Top-Level Scripts¶
Many other examples of top-level scripts can be found in libEnsemble’s regression tests.
Local Sine Tutorial¶
This example is from the Local Sine Tutorial,
meant to run with Python’s multiprocessing as the primary comms method.
1import numpy as np
2from gest_api.vocs import VOCS
3from sine_gen_std import RandomSample
4from sine_sim import sim_find_sine
5
6from libensemble import Ensemble
7from libensemble.specs import ExitCriteria, GenSpecs, LibeSpecs, SimSpecs
8
9if __name__ == "__main__": # Python-quirk required on macOS and windows
10 libE_specs = LibeSpecs(nworkers=4, comms="local")
11
12 vocs = VOCS(variables={"x": [-3, 3]}, objectives={"y": "EXPLORE"}) # Configure our generator with this object
13
14 generator = RandomSample(vocs) # Instantiate our generator
15
16 gen_specs = GenSpecs(
17 generator=generator, # Pass our generator and config to libEnsemble
18 vocs=vocs,
19 batch_size=4,
20 )
21
22 sim_specs = SimSpecs(
23 sim_f=sim_find_sine, # Our simulator function
24 inputs=["x"], # InputArray field names. "x" from gen_f output
25 out=[("y", float)], # sim_f output. "y" = sine("x")
26 ) # sim_specs_end_tag
27
28 exit_criteria = ExitCriteria(sim_max=80) # Stop libEnsemble after 80 simulations
29
30 ensemble = Ensemble(sim_specs, gen_specs, exit_criteria, libE_specs)
31 ensemble.run() # start the ensemble. Blocks until completion.
32
33 history = ensemble.H # start visualizing our results
34
35 print([i for i in history.dtype.fields]) # (optional) to visualize our history array
36 print(history)
37
38 import matplotlib.pyplot as plt
39
40 colors = ["b", "g", "r", "y", "m", "c", "k", "w"]
41
42 for i in range(1, libE_specs.nworkers + 1): # type: ignore
43 worker_xy = np.extract(history["sim_worker"] == i, history)
44 x = [entry.tolist() for entry in worker_xy["x"]]
45 y = [entry for entry in worker_xy["y"]]
46 plt.scatter(x, y, label="Worker {}".format(i), c=colors[i - 1])
47
48 plt.title("Sine calculations for a uniformly sampled random distribution")
49 plt.xlabel("x")
50 plt.ylabel("sine(x)")
51 plt.legend(loc="lower right")
52 plt.savefig("tutorial_sines.png")
Electrostatic Forces with Executor¶
These examples are from a test for evaluating the scaling capabilities of libEnsemble
by calculating particle electrostatic forces through a user application. This
application is registered with the MPIExecutor, then submitted
for execution in the sim_f. Note the use of the parse_args=True which allows
reading arguments such as the number of workers from the command line.
Traditional Version¶
Run using five workers with:
python run_libe_forces.py -n 5
1#!/usr/bin/env python
2import os
3import sys
4from pathlib import Path
5
6import numpy as np
7from forces_simf import run_forces # Sim func from current dir
8
9from libensemble import Ensemble
10from libensemble.executors import MPIExecutor
11from libensemble.gen_funcs.persistent_sampling import persistent_uniform as gen_f
12from libensemble.specs import ExitCriteria, GenSpecs, LibeSpecs, SimSpecs
13
14if __name__ == "__main__":
15 # Initialize MPI Executor
16 exctr = MPIExecutor()
17
18 # Register simulation executable with executor
19 sim_app = Path.cwd() / "../forces_app/forces.x"
20
21 if not os.path.isfile(sim_app):
22 sys.exit("forces.x not found - please build first in ../forces_app dir")
23
24 exctr.register_app(full_path=sim_app, app_name="forces")
25
26 # Parse number of workers, comms type, etc. from arguments
27 ensemble = Ensemble(parse_args=True, executor=exctr)
28 nsim_workers = ensemble.nworkers - 1 # One worker is for persistent generator
29
30 # Persistent gen does not need resources
31 ensemble.libE_specs = LibeSpecs(
32 num_resource_sets=nsim_workers,
33 sim_dirs_make=True,
34 )
35
36 ensemble.sim_specs = SimSpecs(
37 sim_f=run_forces,
38 inputs=["x"],
39 outputs=[("energy", float)],
40 )
41
42 ensemble.gen_specs = GenSpecs(
43 gen_f=gen_f,
44 inputs=[], # No input when start persistent generator
45 persis_in=["sim_id"], # Return sim_ids of evaluated points to generator
46 outputs=[("x", float, (1,))],
47 initial_batch_size=nsim_workers,
48 async_return=False,
49 user={
50 "lb": np.array([1000]), # min particles
51 "ub": np.array([3000]), # max particles
52 },
53 )
54
55 # Starts one persistent generator. Simulated values are returned in batch.
56
57 # Instruct libEnsemble to exit after this many simulations
58 ensemble.exit_criteria = ExitCriteria(sim_max=8)
59
60 # Run ensemble
61 ensemble.run()
62
63 if ensemble.is_manager:
64 # Note, this will change if changing sim_max, nworkers, lb, ub, etc.
65 print(f'Final energy checksum: {np.sum(ensemble.H["energy"])}')
gest-api APOSMM¶
This example from the regression tests demonstrates the gest-api interface with a
standardized APOSMM generator class parameterized by a VOCS object, and
paired with a gest-api simulator callable.