Skip to content

Commit 0bcfc79

Browse files
committed
refactor give_sim_work_first for running on gen_workers if no points_to_evaluate. add test for mixed existing sample plus calling a gen
1 parent 13fecde commit 0bcfc79

2 files changed

Lines changed: 77 additions & 3 deletions

File tree

libensemble/alloc_funcs/give_sim_work_first.py

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -64,15 +64,19 @@ def give_sim_work_first(
6464
Work = {}
6565

6666
points_to_evaluate = ~H["sim_started"] & ~H["cancel_requested"]
67-
for wid in support.avail_worker_ids():
68-
if np.any(points_to_evaluate):
67+
68+
if np.any(points_to_evaluate):
69+
for wid in support.avail_worker_ids(gen_workers=False):
6970
sim_ids_to_send = support.points_by_priority(H, points_avail=points_to_evaluate, batch=batch_give)
7071
try:
7172
Work[wid] = support.sim_work(wid, H, sim_specs["in"], sim_ids_to_send, persis_info.get(wid))
7273
except InsufficientFreeResources:
7374
break
7475
points_to_evaluate[sim_ids_to_send] = False
75-
else:
76+
if not np.any(points_to_evaluate):
77+
break
78+
else:
79+
for wid in support.avail_worker_ids(gen_workers=True):
7680
# Allow at most num_active_gens active generator instances
7781
if gen_count >= user.get("num_active_gens", gen_count + 1):
7882
break
Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
"""
2+
Test libEnsemble's capability to evalute existing points and then generate
3+
new samples via gen_on_manager.
4+
5+
Execute via one of the following commands (e.g. 3 workers):
6+
mpiexec -np 4 python test_evaluate_existing_sample.py
7+
python test_evaluate_existing_sample.py --nworkers 3 --comms local
8+
python test_evaluate_existing_sample.py --nworkers 3 --comms tcp
9+
10+
The number of concurrent evaluations of the objective function will be 4-1=3.
11+
"""
12+
13+
# Do not change these lines - they are parsed by run-tests.sh
14+
# TESTSUITE_COMMS: mpi local tcp
15+
# TESTSUITE_NPROCS: 2 4
16+
17+
import numpy as np
18+
19+
# Import libEnsemble items for this test
20+
from libensemble import Ensemble
21+
from libensemble.gen_funcs.sampling import latin_hypercube_sample as gen_f
22+
from libensemble.sim_funcs.six_hump_camel import six_hump_camel as sim_f
23+
from libensemble.specs import ExitCriteria, GenSpecs, SimSpecs
24+
from libensemble.tools import add_unique_random_streams
25+
26+
27+
def create_H0(persis_info, gen_specs, H0_size):
28+
"""Create an H0 for give_pregenerated_sim_work"""
29+
# Manually creating H0
30+
ub = gen_specs["user"]["ub"]
31+
lb = gen_specs["user"]["lb"]
32+
n = len(lb)
33+
b = H0_size
34+
35+
H0 = np.zeros(b, dtype=[("x", float, 2), ("sim_id", int), ("sim_started", bool)])
36+
H0["x"] = persis_info[0]["rand_stream"].uniform(lb, ub, (b, n))
37+
H0["sim_id"] = range(b)
38+
H0["sim_started"] = False
39+
return H0
40+
41+
42+
# Main block is necessary only when using local comms with spawn start method (default on macOS and Windows).
43+
if __name__ == "__main__":
44+
45+
sampling = Ensemble(parse_args=True)
46+
sampling.libE_specs.gen_on_manager = True
47+
sampling.sim_specs = SimSpecs(sim_f=sim_f, inputs=["x"], out=[("f", float)])
48+
49+
gen_specs = {
50+
"gen_f": gen_f,
51+
"outputs": [("x", float, (2,))],
52+
"user": {
53+
"gen_batch_size": 50,
54+
"lb": np.array([-3, -3]),
55+
"ub": np.array([3, 3]),
56+
},
57+
}
58+
sampling.gen_specs = GenSpecs(**gen_specs)
59+
sampling.exit_criteria = ExitCriteria(sim_max=100)
60+
sampling.persis_info = add_unique_random_streams({}, sampling.nworkers + 1)
61+
sampling.H0 = create_H0(sampling.persis_info, gen_specs, 50)
62+
sampling.run()
63+
64+
if sampling.is_manager:
65+
assert len(sampling.H) == 2 * len(sampling.H0)
66+
assert np.array_equal(sampling.H0["x"][:50], sampling.H["x"][:50])
67+
assert np.all(sampling.H["sim_ended"])
68+
assert np.all(sampling.H["gen_worker"] == 0)
69+
print("\nlibEnsemble correctly didn't add anything to initial sample")
70+
sampling.save_output(__file__)

0 commit comments

Comments
 (0)