Generator Specs

Used to specify the generator function, its inputs and outputs, and user data.

Can be constructed and passed to libEnsemble as a Python class or a dictionary. When provided as a Python class, all data is validated immediately on instantiation.

 2import numpy as np
 3from libensemble import GenSpecs
 4from generator import gen_random_sample
 8gen_specs = GenSpecs(
 9    gen_f=gen_random_sample,
10    out=[("x", float, (1,))],
11    user={
12        "lower": np.array([-3]),
13        "upper": np.array([3]),
14        "gen_batch_size": 5,
15    },
pydantic model libensemble.specs.GenSpecs

Specifications for configuring a Generator Function. Equivalent to a gen_specs dictionary.

field funcx_endpoint: str | None = ''

A funcX ( ID corresponding to an active endpoint on a remote system. libEnsemble’s workers will submit generator function instances to this endpoint to be executed, instead of being called in-place

field gen_f: Callable | None = <function latin_hypercube_sample>

Python function that matches the gen_f api. e.g. libensemble.gen_funcs.sampling. Produces parameters for evaluation by a simulator function, and makes decisions based on simulator function output

field inputs: List[str] | None = [] (alias 'in')

List of field names out of the complete history to pass into the simulation function on initialization. Can use in or inputs as keyword

field out: List[Tuple[str, Any] | Tuple[str, Any, int | Tuple]] = []

List of tuples corresponding to NumPy dtypes. e.g. ("dim", int, (3,)), or ("path", str). Typically used to initialize an output array within the generator function: out = np.zeros(100, dtype=gen_specs["out"]). Also used to construct the complete dtype for libEnsemble’s history array

field persis_in: List[str] | None = []

List of field names that will be passed to a persistent generator function throughout runtime, following initialization

field user: dict | None = {}

A user-data dictionary to place bounds, constants, settings, or other parameters for customizing the generator function

1gen_specs = {
2    "gen_f": gen_random_sample,
3    "out": [("x", float, (1,))],
4    "user": {
5        "lower": np.array([-3]),
6        "upper": np.array([3]),
7        "gen_batch_size": 5,
8    },

See also

  • the generator function uniform_random_sample in will generate 500 random points uniformly over the 2D domain defined by gen_specs["ub"] and gen_specs["lb"].

    gen_specs = {
        "gen_f": uniform_random_sample,  # Function generating sim_f input
        "out": [("x", float, (2,))],  # Tell libE gen_f output, type, size
        "user": {
            "gen_batch_size": 500,  # Used by this specific gen_f
            "lb": np.array([-3, -2]),  # Used by this specific gen_f
            "ub": np.array([3, 2]),  # Used by this specific gen_f

See also

  • shows an example where gen_specs["in"] is empty, but gen_specs["persis_in"] specifies values to return to the persistent generator.

  • shows a similar example where an H0 is used to provide points from a previous run. In this case, gen_specs["in"] is populated to provide the generator with data for the initial points.

  • In some cases you might be able to give different (perhaps fewer) fields in "persis_in" than "in"; you may not need to give x for example, as the persistent generator already has x for those points. See more example uses of persis_in.


  • In all interfaces, custom fields should only be placed in "user"

  • Generator "out" fields typically match Simulation "in" fields, and vice-versa.