As described in the API, the
sim_f is called by a
libEnsemble worker via a similar interface to the
out = sim_f(H[sim_specs['in']][sim_ids_from_allocf], persis_info, sim_specs, libE_info)
In practice, most
sim_f function definitions written by users resemble:
def my_simulator(H, persis_info, sim_specs, libE_info):
Where sim_specs is a
dictionary containing pre-defined parameters for the
sim_f, and the other
parameters serve similar purposes to those in the
The pattern of setting up a local
H, parsing out parameters from
sim_specs, performing calculations, and returning the local
persis_info should be familiar:
batch_size = sim_specs['user']['batch_size'] local_H_out = np.zeros(batch_size, dtype=sim_specs['out']) ... # Perform simulation calculations return local_H_out, persis_info
Between the output array definition and the function returning, any level and complexity of computation can be performed. Users are encouraged to use the executor to submit applications to parallel resources if necessary, or plug in components from other libraries to serve their needs.
Simulator functions can also return a calc_status
integer attribute from the
libensemble.message_numbers module to be logged.
Descriptions of included simulator functions can be found here.
The Simple Sine tutorial is an excellent introduction for writing simple user functions and using them with libEnsemble.