Main libE Module - Calling Script
The libE module is the outer libEnsemble routine.
This module sets up the manager and the team of workers, configured according
to the contents of the libE_specs
dictionary. The manager/worker
communications scheme used in libEnsemble is parsed from the comms
key
if present, with valid values being mpi
, local
(for multiprocessing), or
tcp
. MPI is the default; if a communicator is specified, each call to this
module will initiate manager/worker communications on a duplicate of that
communicator. Otherwise, a duplicate of COMM_WORLD will be used.
In the vast majority of cases, programming with libEnsemble involves the creation
of a calling script, a Python file where libEnsemble is parameterized via
the various specification dictionaries (e.g. libE_specs,
sim_specs, and gen_specs). The
outer libEnsemble routine libE()
is imported and called with such dictionaries to initiate
libEnsemble. A simple calling script (from the first tutorial)
may resemble:
1import numpy as np
2from libensemble.libE import libE
3from generator import gen_random_sample
4from simulator import sim_find_sine
5from libensemble.tools import add_unique_random_streams
6
7nworkers, is_manager, libE_specs, _ = parse_args()
8
9libE_specs["save_every_k_gens"] = 20
10
11gen_specs = {"gen_f": gen_random_sample,
12 "out": [("x", float, (1,))],
13 "user": {
14 "lower": np.array([-3]),
15 "upper": np.array([3]),
16 "gen_batch_size": 5
17 }
18 }
19
20sim_specs = {"sim_f": sim_find_sine,
21 "in": ["x"],
22 "out": [("y", float)]}
23
24persis_info = add_unique_random_streams({}, nworkers+1)
25
26exit_criteria = {"sim_max": 80}
27
28H, persis_info, flag = libE(sim_specs, gen_specs, exit_criteria, persis_info,
29 libE_specs=libE_specs)
This will initiate libEnsemble with a Manager and nworkers
workers (parsed from
the command line), and runs on laptops or supercomputers. If an exception is
encountered by the manager or workers, the history array is dumped to file, and
MPI abort is called.
An alternative approach to parameterizing and interacting with libEnsemble via
Ensemble
objects and yaml
files is available, but requires pyyaml
to be installed. The equivalent of above resembles:
1import numpy as np
2from libensemble import Ensemble
3
4my_experiment = Ensemble()
5my_experiment.from_yaml("my_parameters.yaml")
6
7my_experiment.gen_specs["user"]["lower"] = np.array([-3])
8my_experiment.gen_specs["user"]["upper"] = np.array([3])
9
10H, persis_info, flag = my_experiment.run()
The remaining parameters may be found in a yaml
file that resembles:
1libE_specs:
2 save_every_k_gens: 20
3 exit_criteria:
4 sim_max: 80
5
6gen_specs:
7 function: generator.gen_random_sample
8 outputs:
9 x:
10 type: float
11 size: 1
12 user:
13 gen_batch_size: 5
14
15sim_specs:
16 function: simulator.sim_find_sine
17 inputs:
18 - x
19 outputs:
20 y:
21 type: float
See below for the complete traditional libE()
API.
- libE.libE(sim_specs, gen_specs, exit_criteria, persis_info=None, alloc_specs=None, libE_specs=None, H0=None)
- Parameters
sim_specs (
dict
) – Specifications for the simulation function (example)gen_specs (
dict
) – Specifications for the generator function (example)exit_criteria (
dict
) – Tell libEnsemble when to stop a run (example)persis_info (
dict
, optional) – Persistent information to be passed between user functions (example)alloc_specs (
dict
, optional) – Specifications for the allocation function (example)libE_specs (
dict
, optional) – Specifications for libEnsemble (example)H0 (NumPy structured array, optional) – A previous libEnsemble history to be prepended to the history in the current libEnsemble run (example)
- Returns
H (NumPy structured array) – History array storing rows for each point. (example)
persis_info (
dict
) – Final state of persistent information (example)exit_flag (
int
) – Flag containing final task status0 = No errors 1 = Exception occurred 2 = Manager timed out and ended simulation 3 = Current process is not in libEnsemble MPI communicator