Skip to content

Updating for libEnsemble v0.8.0

Stephen Hudson edited this page Dec 21, 2021 · 14 revisions

libEnsemble v0.8 API changes

The following is a summary of breaking changes for libEnsemble v0.8.

These should be minor changes for most users.

Version 0.8.0 sees a major enhancement of resource management in order to support variable size resource assignment to workers. User functions have improved support classes and there has been an effort to remove duplicated code in the example allocation functions.

Resources to be separated from Executor.

Resource management happens independently of the libEnsemble Executor and thus will be configured by libE_specs options instead of executor arguments. Also, a few option names have changed (see below). The executor will still have access to resource information, but the user can also access resource information independently.

The MPIExecutor constructor arguments that become libE_specs options are: central_mode, zero_resource_workers, auto_resources, and allow_oversubscribe. Also the custom_info dictionary argument to the MPIExecutor will be split. The sub-options mpi_runner,runner_name and subgroup_launch will stay put. The other options that specify resource information will move to the libE_specs option resource_info

The name changes are as follows::

MPIExecutor option New libE_specs option Flip True/False Comments
central_mode dedicated_mode No libEnsmble nodes are not used for task resources
auto_resources disable_resource_manager Yes Default is still to have resource management
allow_oversubscribe enforce_worker_core_bounds Yes Default is still to allow workers to oversubscribe on node
custom_info resource_info No Some sub-options moved as detailed above

Use of 'persis_in' field in gen_specs and sim_specs

In addition to 'in', 'out', and 'user', there is now a 'persis_in' field to gen_specs and sim_specs. This determines which history (H) fields should be given back to the persistent generator while it is running (while 'in' is the fields given to the persistent generator when it is first called). This was previously hard-coded in some of the persistent allocation functions.

For example, the allocation function start_only_persistent, previously used sim_specs['in'] + [n[0] for n in sim_specs['out']] + [('sim_id')]. See other examples here.

For generators, the 'in' field may be empty or only used if passing previous points (from an H0) that you want to give when starting up a persistent generator. In some cases you might be able to give different (perhaps fewer) fields in 'persis_in'; you may not need to give x for example, as the persistent generator already has it.

Both of these simply tell the allocation function what to pass, so it would be possible to still have defaults in the allocation function. However, the example functions have removed defaults, to help transparency to the user.

User function support modules to use a class.

The allocation functions use the class AllocSupport, while the gen_support module is replaced with persistent_support, which contains the class PersistentSupport.

Allocation function support class

This enables some temporary information to be re-used while running the allocation function, helping simplicity and performance. In particular, this helps with keeping a cache of assigned resources during the function call (as the actual resource assignment is only updated when the manager gives out work to workers). Example usage: start_only_persistent.py

Persistent support class

This class can be used for persistent sim and gen functions to communicate with the manager. It includes the functions send(), recv(), and send_recv(), replacing the old functions send_mgr_worker_msg, get_mgr_worker_msg and sendrecv_mgr_worker_msg. Example usage: persistent_uniform_sampling.py

The allocation function will be called until sim_max evaluations have returned.

Note: This will not require script changes for most users.

Previously, when sim_max was set as an exit criteria, the allocation function was only called until sim_max points had been given to sims. At which point, the main loop exited and waited for the results to return. Instead, the allocation function now continues to be called until sim_max points have returned. However, as detailed below, the user can determine what happens in the allocation function after sim_max points are given out. Most supplied allocation functions default to returning without packing up any work.

libE_info to be passed to allocation functions

As with sim and gen functions, the argument libE_info will be passed to allocation functions. In this case it contains some useful libEnsemble metrics. These include the boolean sim_max_given, which returns True if sim_max was set as an exit criteria, and this many simulations have been issued. In most supplied examples, the allocation function will just return once sim_max_given is True, but the user could choose to do something different, such as cancel points or keep returning completed points to the generator. For more details the allocation function guide.

Also note that generally options that are intended for allocation functions in the examples will be alloc_specs['user'] options rather than gen_specs['user'] options, including the option give_all_with_same_priority However, gen_specs is still passed to allocation functions.

History array changes

'given_back' is now a protected libEnsemble field in the history array (H). This field was previously used as a user field in some examples.

Final return to persistent gen

The final exit can include sending evaluated points to a persistent worker (e.g., to perform some final update before exiting) so a final status can be sent to the manager. Set 'final_fields' in libE_specs.

Minor API changes

Function:

  • Executor.register_calc() -> Executor.register_app()

executor.submit() Arguments:

  • ranks_per_node -> procs_per_node

  • wait_on_run - wait_on_start (possible add a wait_on_finish)

  • libE_specs option use_persis_return is replaced by two options: use_persis_return_sim and use_persis_return_gen As you may want to use only the return from a sim or a gen.

Imports:

  • liBE_logger to become logger. E.g. libensemble import logger