Skip to content

Commit 8851447

Browse files
committed
Fixed user in alloc_fs to be the combination of gen_specs and alloc_specs["user"]. Updated alloc_f docstrings to reflect where the options can be. Other docstring updates. Adjust tests to have the relevant alloc options in gen_specs instead. some mypy adjusts.
1 parent 0c972d3 commit 8851447

67 files changed

Lines changed: 128 additions & 158 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.pre-commit-config.yaml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,3 +37,4 @@ repos:
3737
rev: v1.19.1
3838
hooks:
3939
- id: mypy
40+
exclude: ^libensemble/utils/(launcher|loc_stack|runners|pydantic|output_directory)\.py$|^libensemble/tests/regression_tests/support\.py$|^libensemble/tests/functionality_tests/

docs/tutorials/calib_cancel_tutorial.rst

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -151,11 +151,9 @@ The allocation function used in this example is the *only_persistent_gens* funct
151151
152152
alloc_specs = {
153153
"alloc_f": alloc_f,
154-
"user": {
155-
"init_sample_size": init_sample_size,
156-
"async_return": True,
157-
"active_recv_gen": True,
158-
},
154+
"initial_batch_size": init_sample_size,
155+
"async_return": True,
156+
"active_recv_gen": True,
159157
}
160158
161159
**async_return** tells the allocation function to return results to the generator as soon

libensemble/alloc_funcs/fast_alloc.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ def give_sim_work_first(W, H, sim_specs, gen_specs, alloc_specs, persis_info, li
77
to evaluate in the simulation function. The fields in ``sim_specs["in"]``
88
are given. If all entries in `H` have been given a be evaluated, a worker
99
is told to call the generator function, provided this wouldn't result in
10-
more than ``alloc_specs["user"]["num_active_gen"]`` active generators.
10+
more than ``gen_specs["num_active_gens"]`` or ``alloc_specs["user"]["num_active_gens"]`` active generators.
1111
1212
This fast_alloc variation of give_sim_work_first is useful for cases that
1313
simply iterate through H, issuing evaluations in order and, in particular,
@@ -23,7 +23,8 @@ def give_sim_work_first(W, H, sim_specs, gen_specs, alloc_specs, persis_info, li
2323
if libE_info["sim_max_given"] or not libE_info["any_idle_workers"]:
2424
return {}, persis_info
2525

26-
user = alloc_specs.get("user", {})
26+
user = {**gen_specs, **alloc_specs.get("user", {})}
27+
2728
manage_resources = libE_info["use_resource_sets"]
2829

2930
support = AllocSupport(W, manage_resources, persis_info, libE_info)

libensemble/alloc_funcs/fast_alloc_and_pausing.py

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -28,13 +28,16 @@ def give_sim_work_first(W, H, sim_specs, gen_specs, alloc_specs, persis_info, li
2828
if libE_info["sim_max_given"] or not libE_info["any_idle_workers"]:
2929
return {}, persis_info
3030

31+
user = {**gen_specs, **alloc_specs.get("user", {})}
3132
manage_resources = libE_info["use_resource_sets"]
3233
support = AllocSupport(W, manage_resources, persis_info, libE_info)
3334
Work = {}
3435
gen_count = support.count_gens()
3536

3637
if gen_specs["user"].get("single_component_at_a_time"):
37-
assert alloc_specs["user"]["batch_mode"], "Must be in batch mode when using 'single_component_at_a_time'"
38+
assert (
39+
alloc_specs["user"]["batch_mode"] or gen_specs["batch_mode"]
40+
), "Must be in batch mode when using 'single_component_at_a_time'"
3841
if len(H) != persis_info["H_len"]:
3942
# Something new is in the history.
4043
persis_info["need_to_give"].update(H["sim_id"][persis_info["H_len"] :].tolist())
@@ -119,13 +122,13 @@ def give_sim_work_first(W, H, sim_specs, gen_specs, alloc_specs, persis_info, li
119122
break
120123

121124
while len(idle_gen_workers):
122-
if gen_count < alloc_specs["user"].get("num_active_gens", gen_count + 1):
125+
if gen_count < user.get("num_active_gens", gen_count + 1):
123126
lw = persis_info["last_worker"]
124127

125128
last_size = persis_info.get("last_size")
126129
if len(H):
127130
# Don't give gen instances in batch mode if points are unfinished
128-
if alloc_specs["user"].get("batch_mode") and not all(
131+
if (alloc_specs["user"].get("batch_mode") or gen_specs.get("batch_mode")) and not all(
129132
np.logical_or(H["sim_ended"][last_size:], H["paused"][last_size:])
130133
):
131134
break
@@ -142,7 +145,7 @@ def give_sim_work_first(W, H, sim_specs, gen_specs, alloc_specs, persis_info, li
142145
persis_info["last_worker"] = i
143146
persis_info["last_size"] = len(H)
144147

145-
elif gen_count >= alloc_specs["user"].get("num_active_gens", gen_count + 1):
148+
elif gen_count >= user.get("num_active_gens", gen_count + 1):
146149
idle_gen_workers = []
147150

148151
return Work, persis_info

libensemble/alloc_funcs/give_sim_work_first.py

Lines changed: 9 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -18,14 +18,14 @@ def give_sim_work_first(
1818
"""
1919
Decide what should be given to workers. This allocation function gives any
2020
available simulation work first, and only when all simulations are
21-
completed or running does it start (at most ``alloc_specs["user"]["num_active_gens"]``)
21+
completed or running does it start (at most ``gen_specs["num_active_gens"]`` or ``alloc_specs["user"]["num_active_gens"]``)
2222
generator instances.
2323
24-
Allows for a ``alloc_specs["user"]["batch_mode"]`` where no generation
24+
Allows for a ``gen_specs["batch_mode"]`` or ``alloc_specs["user"]["batch_mode"]`` where no generation
2525
work is given out unless all entries in ``H`` are returned.
2626
2727
Can give points in highest priority, if ``"priority"`` is a field in ``H``.
28-
If ``alloc_specs["user"]["give_all_with_same_priority"]`` is set to True, then
28+
If ``gen_specs["give_all_with_same_priority"]`` or ``alloc_specs["user"]["give_all_with_same_priority"]`` is set to True, then
2929
all points with the same priority value are given as a batch to the sim.
3030
3131
Workers performing sims will be assigned resources given in H["resource_sets"]
@@ -40,7 +40,8 @@ def give_sim_work_first(
4040
`test_uniform_sampling.py <https://github.com/Libensemble/libensemble/blob/develop/libensemble/tests/functionality_tests/test_uniform_sampling.py>`_ # noqa
4141
"""
4242

43-
user = alloc_specs.get("user", {})
43+
user = {**gen_specs, **alloc_specs.get("user", {})}
44+
4445
if "cancel_sims_time" in user:
4546
# Cancel simulations that are taking too long
4647
rows = np.where(np.logical_and.reduce((H["sim_started"], ~H["sim_ended"], ~H["cancel_requested"])))[0]
@@ -52,11 +53,8 @@ def give_sim_work_first(
5253
if libE_info["sim_max_given"] or not libE_info["any_idle_workers"]:
5354
return {}, persis_info
5455

55-
# Initialize options - check gen_specs first
56-
batch_give = gen_specs.get("give_all_with_same_priority", user.get("give_all_with_same_priority", False))
57-
num_active_gens = gen_specs.get("num_active_gens", user.get("num_active_gens", 1))
58-
batch_mode = gen_specs.get("batch_mode", user.get("batch_mode", False))
59-
56+
# Initialize alloc_specs["user"] as user.
57+
batch_give = user.get("give_all_with_same_priority", False)
6058
gen_in = gen_specs.get("in", [])
6159

6260
manage_resources = libE_info["use_resource_sets"]
@@ -79,11 +77,11 @@ def give_sim_work_first(
7977
else:
8078
for wid in support.avail_worker_ids(gen_workers=True):
8179
# Allow at most num_active_gens active generator instances
82-
if gen_count >= num_active_gens:
80+
if gen_count >= user.get("num_active_gens", gen_count + 1):
8381
break
8482

8583
# Do not start gen instances in batch mode if workers still working
86-
if batch_mode and not support.all_sim_ended(H):
84+
if user.get("batch_mode") and not support.all_sim_ended(H):
8785
break
8886

8987
# Give gen work

libensemble/alloc_funcs/persistent_aposmm_alloc.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,8 @@ def persistent_aposmm_alloc(W, H, sim_specs, gen_specs, alloc_specs, persis_info
2121
if libE_info["sim_max_given"] or not libE_info["any_idle_workers"]:
2222
return {}, persis_info
2323

24-
init_sample_size = gen_specs["user"]["initial_sample_size"]
24+
user = {**gen_specs, **alloc_specs.get("user", {})}
25+
init_sample_size = user["initial_batch_size"]
2526
manage_resources = libE_info["use_resource_sets"]
2627
support = AllocSupport(W, manage_resources, persis_info, libE_info)
2728
gen_count = support.count_persis_gens()

libensemble/alloc_funcs/start_only_persistent.py

Lines changed: 12 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -7,12 +7,12 @@
77
def only_persistent_gens(W, H, sim_specs, gen_specs, alloc_specs, persis_info, libE_info):
88
"""
99
This allocation function will give simulation work if possible, but
10-
otherwise start up to ``alloc_specs["user"]["num_active_gens"]``
10+
otherwise start up to ``gen_specs["num_active_gens"]`` or ``alloc_specs["user"]["num_active_gens"]``
1111
persistent generators (defaulting to one).
1212
1313
By default, evaluation results are given back to the generator once
1414
all generated points have been returned from the simulation evaluation.
15-
If ``alloc_specs["user"]["async_return"]`` is set to True, then any
15+
If ``gen_specs["async_return"]`` or ``alloc_specs["user"]["async_return"]`` is set to True, then any
1616
returned points are given back to the generator.
1717
1818
If any workers are marked as zero_resource_workers, then these will only
@@ -25,7 +25,7 @@ def only_persistent_gens(W, H, sim_specs, gen_specs, alloc_specs, persis_info, l
2525
2626
To be provided in calling script: E.g., ``alloc_specs["user"]["async_return"] = True``
2727
28-
initial_batch_size: int, optional
28+
init_sample_size: int, optional
2929
Initial sample size - always return in batch. Default: 0
3030
3131
num_active_gens: int, optional
@@ -56,21 +56,20 @@ def only_persistent_gens(W, H, sim_specs, gen_specs, alloc_specs, persis_info, l
5656
return {}, persis_info
5757

5858
# Initialize alloc_specs["user"] as user.
59-
user = alloc_specs.get("user", {})
59+
user = {**gen_specs, **alloc_specs.get("user", {})}
60+
6061
manage_resources = libE_info["use_resource_sets"]
6162

62-
active_recv_gen = gen_specs.get("active_recv_gen", user.get("active_recv_gen", False))
63-
initial_batch_size = gen_specs.get("initial_batch_size", user.get("initial_batch_size", 0))
64-
batch_give = gen_specs.get("give_all_with_same_priority", user.get("give_all_with_same_priority", False))
63+
active_recv_gen = user.get("active_recv_gen", False) # Persistent gen can handle irregular communications
64+
initial_batch_size = user.get("initial_batch_size", 0) # Always batch return until this many evals complete
65+
batch_give = user.get("give_all_with_same_priority", False)
6566

6667
support = AllocSupport(W, manage_resources, persis_info, libE_info)
6768
gen_count = support.count_persis_gens()
6869
Work = {}
6970

7071
# Asynchronous return to generator
71-
async_return = (
72-
gen_specs.get("async_return", user.get("async_return", False)) and sum(H["sim_ended"]) >= initial_batch_size
73-
)
72+
async_return = user.get("async_return", False) and sum(H["sim_ended"]) >= initial_batch_size
7473

7574
if gen_count < persis_info.get("num_gens_started", 0):
7675
# When a persistent worker is done, trigger a shutdown (returning exit condition of 1)
@@ -96,7 +95,7 @@ def only_persistent_gens(W, H, sim_specs, gen_specs, alloc_specs, persis_info, l
9695
# Now the give_sim_work_first part
9796
points_to_evaluate = ~H["sim_started"] & ~H["cancel_requested"]
9897
avail_workers = support.avail_worker_ids(persistent=False, zero_resource_workers=False, gen_workers=False)
99-
if gen_specs.get("alt_type", user.get("alt_type")):
98+
if user.get("alt_type"):
10099
avail_workers = list(
101100
set(support.avail_worker_ids(persistent=False, zero_resource_workers=False))
102101
| set(support.avail_worker_ids(persistent=EVAL_SIM_TAG, zero_resource_workers=False))
@@ -108,7 +107,7 @@ def only_persistent_gens(W, H, sim_specs, gen_specs, alloc_specs, persis_info, l
108107
sim_ids_to_send = support.points_by_priority(H, points_avail=points_to_evaluate, batch=batch_give)
109108

110109
try:
111-
if gen_specs.get("alt_type", user.get("alt_type")):
110+
if user.get("alt_type"):
112111
Work[wid] = support.sim_work(
113112
wid, H, sim_specs["in"], sim_ids_to_send, persis_info.get(wid), persistent=True
114113
)
@@ -124,7 +123,7 @@ def only_persistent_gens(W, H, sim_specs, gen_specs, alloc_specs, persis_info, l
124123
avail_workers = support.avail_worker_ids(persistent=False, zero_resource_workers=True, gen_workers=True)
125124

126125
for wid in avail_workers:
127-
if gen_count < gen_specs.get("num_active_gens", user.get("num_active_gens", 1)):
126+
if gen_count < user.get("num_active_gens", 1):
128127
# Finally, start a persistent generator as there is nothing else to do.
129128
try:
130129
Work[wid] = support.gen_work(

libensemble/gen_funcs/persistent_sampling_var_resources.py

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -25,11 +25,11 @@
2525
]
2626

2727

28-
def _get_user_params(user_specs):
28+
def _get_user_params(gen_specs):
2929
"""Extract user params"""
30-
b = user_specs["initial_batch_size"]
31-
ub = user_specs["ub"]
32-
lb = user_specs["lb"]
30+
b = gen_specs["initial_batch_size"]
31+
ub = gen_specs["user"]["ub"]
32+
lb = gen_specs["user"]["lb"]
3333
n = len(lb) # dimension
3434
return b, n, lb, ub
3535

@@ -43,7 +43,7 @@ def uniform_sample(_, persis_info, gen_specs, libE_info):
4343
`test_uniform_sampling_with_variable_resources.py <https://github.com/Libensemble/libensemble/blob/develop/libensemble/tests/functionality_tests/test_uniform_sampling_with_variable_resources.py>`_
4444
""" # noqa
4545

46-
b, n, lb, ub = _get_user_params(gen_specs["user"])
46+
b, n, lb, ub = _get_user_params(gen_specs)
4747
rng = persis_info["rand_stream"]
4848
ps = PersistentSupport(libE_info, EVAL_GEN_TAG)
4949
tag = None
@@ -76,7 +76,7 @@ def uniform_sample_with_var_gpus(_, persis_info, gen_specs, libE_info):
7676
`test_GPU_variable_resources.py <https://github.com/Libensemble/libensemble/blob/develop/libensemble/tests/regression_tests/test_GPU_variable_resources.py>`_
7777
""" # noqa
7878

79-
b, n, lb, ub = _get_user_params(gen_specs["user"])
79+
b, n, lb, ub = _get_user_params(gen_specs)
8080
rng = persis_info["rand_stream"]
8181
ps = PersistentSupport(libE_info, EVAL_GEN_TAG)
8282
tag = None
@@ -111,7 +111,7 @@ def uniform_sample_with_procs_gpus(_, persis_info, gen_specs, libE_info):
111111
`test_GPU_variable_resources.py <https://github.com/Libensemble/libensemble/blob/develop/libensemble/tests/regression_tests/test_GPU_variable_resources.py>`_
112112
""" # noqa
113113

114-
b, n, lb, ub = _get_user_params(gen_specs["user"])
114+
b, n, lb, ub = _get_user_params(gen_specs)
115115
rng = persis_info["rand_stream"]
116116
ps = PersistentSupport(libE_info, EVAL_GEN_TAG)
117117
tag = None
@@ -137,7 +137,7 @@ def uniform_sample_with_var_priorities(_, persis_info, gen_specs, libE_info):
137137
resource sets and priorities are requested for each point.
138138
"""
139139

140-
b, n, lb, ub = _get_user_params(gen_specs["user"])
140+
b, n, lb, ub = _get_user_params(gen_specs)
141141
rng = persis_info["rand_stream"]
142142
ps = PersistentSupport(libE_info, EVAL_GEN_TAG)
143143

@@ -175,7 +175,7 @@ def uniform_sample_diff_simulations(_, persis_info, gen_specs, libE_info):
175175
`test_GPU_variable_resources_multi_task.py <https://github.com/Libensemble/libensemble/blob/develop/libensemble/tests/regression_tests/test_GPU_variable_resources_multi_task.py>`_
176176
""" # noqa
177177

178-
b, n, lb, ub = _get_user_params(gen_specs["user"])
178+
b, n, lb, ub = _get_user_params(gen_specs)
179179
rng = persis_info["rand_stream"]
180180
ps = PersistentSupport(libE_info, EVAL_GEN_TAG)
181181
tag = None
@@ -209,7 +209,7 @@ def uniform_sample_with_sim_gen_resources(_, persis_info, gen_specs, libE_info):
209209
`test_GPU_variable_resources.py <https://github.com/Libensemble/libensemble/blob/develop/libensemble/tests/regression_tests/test_GPU_variable_resources.py>`_
210210
""" # noqa
211211

212-
b, n, lb, ub = _get_user_params(gen_specs["user"])
212+
b, n, lb, ub = _get_user_params(gen_specs)
213213
rng = persis_info["rand_stream"]
214214
ps = PersistentSupport(libE_info, EVAL_GEN_TAG)
215215
tag = None

libensemble/gen_funcs/sampling.py

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@
1919
@output_data([("x", float, 2)]) # default: can be overwritten in gen_specs
2020
def uniform_random_sample(_, persis_info, gen_specs):
2121
"""
22-
Generates ``gen_specs["user"]["gen_batch_size"]`` points uniformly over the domain
22+
Generates ``gen_specs["batch_size"]`` points uniformly over the domain
2323
defined by ``gen_specs["user"]["ub"]`` and ``gen_specs["user"]["lb"]``.
2424
2525
.. seealso::
@@ -29,7 +29,7 @@ def uniform_random_sample(_, persis_info, gen_specs):
2929
lb = gen_specs["user"]["lb"]
3030

3131
n = len(lb)
32-
b = gen_specs["user"]["gen_batch_size"]
32+
b = gen_specs["batch_size"]
3333

3434
H_o = np.zeros(b, dtype=gen_specs["out"])
3535

@@ -40,7 +40,7 @@ def uniform_random_sample(_, persis_info, gen_specs):
4040

4141
def uniform_random_sample_with_variable_resources(_, persis_info, gen_specs):
4242
"""
43-
Generates ``gen_specs["user"]["gen_batch_size"]`` points uniformly over the domain
43+
Generates ``gen_specs["batch_size"]`` points uniformly over the domain
4444
defined by ``gen_specs["user"]["ub"]`` and ``gen_specs["user"]["lb"]``.
4545
4646
Also randomly requests a different number of resource sets to be used in each evaluation.
@@ -56,7 +56,7 @@ def uniform_random_sample_with_variable_resources(_, persis_info, gen_specs):
5656
max_rsets = gen_specs["user"]["max_resource_sets"]
5757

5858
n = len(lb)
59-
b = gen_specs["user"]["gen_batch_size"]
59+
b = gen_specs["batch_size"]
6060

6161
H_o = np.zeros(b, dtype=gen_specs["out"])
6262

@@ -84,7 +84,7 @@ def uniform_random_sample_with_var_priorities_and_resources(H, persis_info, gen_
8484
n = len(lb)
8585

8686
if len(H) == 0:
87-
b = gen_specs["user"]["initial_batch_size"]
87+
b = gen_specs["batch_size"]
8888

8989
H_o = np.zeros(b, dtype=gen_specs["out"])
9090
for i in range(0, b):
@@ -119,7 +119,7 @@ def uniform_random_sample_obj_components(H, persis_info, gen_specs):
119119

120120
n = len(lb)
121121
m = gen_specs["user"]["components"]
122-
b = gen_specs["user"]["gen_batch_size"]
122+
b = gen_specs["batch_size"]
123123

124124
H_o = np.zeros(b * m, dtype=gen_specs["out"])
125125
for i in range(0, b):
@@ -143,7 +143,7 @@ def uniform_random_sample_cancel(_, persis_info, gen_specs):
143143
lb = gen_specs["user"]["lb"]
144144

145145
n = len(lb)
146-
b = gen_specs["user"]["gen_batch_size"]
146+
b = gen_specs["batch_size"]
147147

148148
H_o = np.zeros(b, dtype=gen_specs["out"])
149149
for i in range(b):
@@ -158,7 +158,7 @@ def uniform_random_sample_cancel(_, persis_info, gen_specs):
158158
@output_data([("x", float, (1,))])
159159
def latin_hypercube_sample(_, persis_info, gen_specs):
160160
"""
161-
Generates ``gen_specs["user"]["gen_batch_size"]`` points in a Latin
161+
Generates ``gen_specs["batch_size"]`` points in a Latin
162162
hypercube sample over the domain defined by ``gen_specs["user"]["ub"]`` and
163163
``gen_specs["user"]["lb"]``.
164164
@@ -170,7 +170,7 @@ def latin_hypercube_sample(_, persis_info, gen_specs):
170170
lb = gen_specs["user"]["lb"]
171171

172172
n = len(lb)
173-
b = gen_specs["user"]["gen_batch_size"]
173+
b = gen_specs["batch_size"]
174174

175175
H_o = np.zeros(b, dtype=gen_specs["out"])
176176

libensemble/gen_funcs/uniform_or_localopt.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515

1616
def uniform_or_localopt(H, persis_info, gen_specs, libE_info):
1717
"""
18-
This generation function returns ``gen_specs["user"]["gen_batch_size"]`` uniformly
18+
This generation function returns ``gen_specs["batch_size"]`` uniformly
1919
sampled points when called in nonpersistent mode (i.e., when
2020
``libE_info["persistent"]`` isn't ``True``). Otherwise, the generation
2121
function starts a persistent nlopt local optimization run.
@@ -31,7 +31,7 @@ def uniform_or_localopt(H, persis_info, gen_specs, libE_info):
3131
ub = gen_specs["user"]["ub"]
3232
lb = gen_specs["user"]["lb"]
3333
n = len(lb)
34-
b = gen_specs["user"]["gen_batch_size"]
34+
b = gen_specs["batch_size"]
3535

3636
H_o = np.zeros(b, dtype=gen_specs["out"])
3737
for i in range(0, b):

0 commit comments

Comments
 (0)