persis_info
Holds persistent information that can be updated during the ensemble.
An initialized persis_info
dictionary can be provided to the libE()
call
or as an attribute of the Ensemble
class.
Dictionary keys that have an integer value contain entries that are passed to
and from the corresponding workers. These are received in the persis_info
argument of user functions, and returned as the optional second return value.
A typical example is a random number generator stream to be used in consecutive
calls to a generator (see
add_unique_random_streams()
)
All other entries persist on the manager and can be updated in the calling script between ensemble invocations, or in the allocation function.
Examples:
1def uniform_random_sample(_, persis_info, gen_specs):
2 """
3 Generates ``gen_specs["user"]["gen_batch_size"]`` points uniformly over the domain
4 defined by ``gen_specs["user"]["ub"]`` and ``gen_specs["user"]["lb"]``.
5
6 .. seealso::
7 `test_uniform_sampling.py <https://github.com/Libensemble/libensemble/blob/develop/libensemble/tests/functionality_tests/test_uniform_sampling.py>`_ # noqa
8 """
9 ub = gen_specs["user"]["ub"]
10 lb = gen_specs["user"]["lb"]
11
12 n = len(lb)
13 b = gen_specs["user"]["gen_batch_size"]
14
15 H_o = np.zeros(b, dtype=gen_specs["out"])
16
17 H_o["x"] = persis_info["rand_stream"].uniform(lb, ub, (b, n))
18
19 return H_o, persis_info
20
21
1 for wid in support.avail_worker_ids(gen_workers=False):
2 persis_info = support.skip_canceled_points(H, persis_info)
3 if persis_info["next_to_give"] < len(H):
4 try:
5 Work[wid] = support.sim_work(wid, H, sim_specs["in"], [persis_info["next_to_give"]], [])
6 except InsufficientFreeResources:
7 break
8 persis_info["next_to_give"] += 1
9
1 avail_workers = support.avail_worker_ids(persistent=False, zero_resource_workers=True, gen_workers=True)
2
3 for wid in avail_workers:
4 if gen_count < user.get("num_active_gens", 1):
5 # Finally, start a persistent generator as there is nothing else to do.
6 try:
7 Work[wid] = support.gen_work(
8 wid,
9 gen_specs.get("in", []),
10 range(len(H)),
11 persis_info.get(wid),
12 persistent=True,
13 active_recv=active_recv_gen,
14 )
15 except InsufficientFreeResources:
16 break
17
18 persis_info["num_gens_started"] = persis_info.get("num_gens_started", 0) + 1
19 gen_count += 1
20
1 if gen_count < persis_info.get("num_gens_started", 0):
2 # When a persistent worker is done, trigger a shutdown (returning exit condition of 1)
3 return Work, persis_info, 1
4
When there are repeated calls to libE()
or ensemble.run()
, users may
need to modify or reset the contents of persis_info
in some cases.
See also
From: support.py
persis_info_1 = {
"total_gen_calls": 0, # Counts gen calls in alloc_f
"last_worker": 0, # Remembers last gen worker in alloc_f
"next_to_give": 0, # Remembers next H row to give in alloc_f
}
persis_info_1[0] = {
"run_order": {}, # Used by manager to remember run order
"total_runs": 0, # Used by manager to count total runs
"rand_stream": np.random.default_rng(1),
}