|
| 1 | +""" |
| 2 | +Tests libEnsemble with Xopt ExpectedImprovementGenerator using a |
| 3 | +pre-constructed sampler instance for ``initial_sample_method``. |
| 4 | +
|
| 5 | +Companion to ``test_xopt_EI_initial_sample.py``, which uses the string form |
| 6 | +(``initial_sample_method="uniform"``). This test instead passes a pre-configured |
| 7 | +``LatinHypercubeSample`` instance — exercising the path that lets the user |
| 8 | +supply constructor kwargs (here, ``random_seed``) and choose any sampler from |
| 9 | +``gen_classes.sampling`` (or a custom one) without going through the string |
| 10 | +registry in ``runners.py``. |
| 11 | +
|
| 12 | +Execute via one of the following commands (e.g. 4 workers): |
| 13 | + mpiexec -np 5 python test_xopt_EI_initial_sample_instance.py |
| 14 | + python test_xopt_EI_initial_sample_instance.py -n 4 |
| 15 | +""" |
| 16 | + |
| 17 | +# Do not change these lines - they are parsed by run-tests.sh |
| 18 | +# TESTSUITE_COMMS: local |
| 19 | +# TESTSUITE_NPROCS: 4 |
| 20 | +# TESTSUITE_EXTRA: true |
| 21 | +# TESTSUITE_EXCLUDE: true |
| 22 | + |
| 23 | +import numpy as np |
| 24 | +from gest_api.vocs import VOCS |
| 25 | +from xopt.generators.bayesian.expected_improvement import ExpectedImprovementGenerator |
| 26 | + |
| 27 | +from libensemble import Ensemble |
| 28 | +from libensemble.alloc_funcs.start_only_persistent import only_persistent_gens as alloc_f |
| 29 | +from libensemble.gen_classes.sampling import LatinHypercubeSample |
| 30 | +from libensemble.specs import AllocSpecs, ExitCriteria, GenSpecs, LibeSpecs, SimSpecs |
| 31 | + |
| 32 | + |
| 33 | +def xtest_sim(H, persis_info, sim_specs, _): |
| 34 | + """y1 = x2, c1 = x1""" |
| 35 | + batch = len(H) |
| 36 | + H_o = np.zeros(batch, dtype=sim_specs["out"]) |
| 37 | + for i in range(batch): |
| 38 | + H_o["y1"][i] = H["x2"][i] |
| 39 | + H_o["c1"][i] = H["x1"][i] |
| 40 | + return H_o, persis_info |
| 41 | + |
| 42 | + |
| 43 | +if __name__ == "__main__": |
| 44 | + |
| 45 | + batch_size = 4 |
| 46 | + |
| 47 | + libE_specs = LibeSpecs(gen_on_manager=True, nworkers=batch_size) |
| 48 | + libE_specs.reuse_output_dir = True |
| 49 | + |
| 50 | + vocs = VOCS( |
| 51 | + variables={"x1": [0, 1.0], "x2": [0, 10.0]}, |
| 52 | + objectives={"y1": "MINIMIZE"}, |
| 53 | + constraints={"c1": ["GREATER_THAN", 0.5]}, |
| 54 | + constants={"constant1": 1.0}, |
| 55 | + ) |
| 56 | + |
| 57 | + gen = ExpectedImprovementGenerator(vocs=vocs) |
| 58 | + |
| 59 | + # Pre-constructed sampler with a custom random_seed — not reachable via the |
| 60 | + # string form, which always instantiates with sampler defaults. |
| 61 | + initial_sampler = LatinHypercubeSample(vocs=vocs, random_seed=42) |
| 62 | + |
| 63 | + gen_specs = GenSpecs( |
| 64 | + generator=gen, |
| 65 | + initial_batch_size=batch_size, |
| 66 | + initial_sample_method=initial_sampler, |
| 67 | + batch_size=batch_size, |
| 68 | + vocs=vocs, |
| 69 | + ) |
| 70 | + |
| 71 | + sim_specs = SimSpecs( |
| 72 | + sim_f=xtest_sim, |
| 73 | + vocs=vocs, |
| 74 | + ) |
| 75 | + |
| 76 | + alloc_specs = AllocSpecs(alloc_f=alloc_f) |
| 77 | + exit_criteria = ExitCriteria(sim_max=20) |
| 78 | + |
| 79 | + workflow = Ensemble( |
| 80 | + libE_specs=libE_specs, |
| 81 | + sim_specs=sim_specs, |
| 82 | + alloc_specs=alloc_specs, |
| 83 | + gen_specs=gen_specs, |
| 84 | + exit_criteria=exit_criteria, |
| 85 | + ) |
| 86 | + |
| 87 | + H, _, _ = workflow.run() |
| 88 | + |
| 89 | + if workflow.is_manager: |
| 90 | + print(f"Completed {len(H)} simulations") |
| 91 | + assert len(H) >= 8, f"Expected at least 8 sims, got {len(H)}" |
| 92 | + print("Test passed") |
0 commit comments