propulate

Subpackages

Submodules

Package Contents

Classes

Islands

Initialize an island model with the given parameters.

Migrator

Initialize Migrator with given parameters.

Pollinator

Initialize Pollinator with given parameters.

Individual

Initialize an individual with given parameters.

Propulator

Initialize Propulator with given parameters.

Surrogate

Initialize a new surrogate model.

Functions

get_default_propagator(→ propulate.propagators.Propagator)

Get Propulate's default evolutionary optimization propagator.

set_logger_config(→ None)

Set up the logger. Should only need to be done once. Generally, logging should only be done on the master rank.

class propulate.Islands(loss_fn: Callable | Generator[float, None, None], propagator: propulate.propagators.Propagator, rng: random.Random, generations: int = 0, num_islands: int = 1, island_sizes: numpy.ndarray | None = None, migration_topology: numpy.ndarray | None = None, migration_probability: float = 0.0, emigration_propagator: Type[propulate.propagators.Propagator] = SelectMin, immigration_propagator: Type[propulate.propagators.Propagator] = SelectMax, pollination: bool = True, checkpoint_path: str | pathlib.Path = Path('./'), ranks_per_worker: int = 1, surrogate_factory: Callable[[], propulate.surrogate.Surrogate] | None = None)

Initialize an island model with the given parameters.

Parameters:
  • loss_fn (Union[Callable, Generator[float, None, None]]) – The loss function to be minimized.

  • propagator (propulate.propagators.Propagator) – The propagator, i.e., evolutionary operator, to apply for breeding.

  • rng (random.Random) – The separate random number generator for the Propulate optimization.

  • generations (int, optional) – The number of generations. Default is 0.

  • num_islands (int, optional) – The number of separate equally sized evolutionary islands. Ignored if island_sizes is not None. Differences of +-1 are possible due to load balancing. Default is 1.

  • island_sizes (numpy.ndarray[int], optional) – An array with numbers of workers for each island (heterogeneous case).

  • migration_topology (numpy.ndarray[int], optional) – A two-dimensional matrix where entry (i,j) specifies how many individuals are sent by island i to island j

  • migration_probability (float, optional) – The probability of migration after each generation.

  • emigration_propagator (Type[propulate.propagators.Propagator], optional) – The emigration propagator, i.e., how to choose individuals for emigration that are sent to the destination island. Should be some kind of selection operator. Default is SelectMin.

  • immigration_propagator (Type[propulate.propagators.Propagator], optional) – The immigration propagator, i.e., how to choose individuals on the target island to be replaced by the immigrants. Should be some kind of selection operator. Default is SelectMax.

  • pollination (bool, optional) – If True, copies of emigrants are sent; otherwise, emigrants are removed from the original island. Default is True.

  • checkpoint_path (pathlib.Path | str, optional) – The path where checkpoints are loaded from and stored to. Default is the current working directory.

  • ranks_per_worker (int, optional) – The number of ranks per worker. Default is 1.

  • surrogate_factory (Callable[[], propulate.surrogate.Surrogate], optional) – Function that returns a new instance of a Surrogate model. Only used when loss_fn is a generator function.

Raises:

ValueError – If the overall number of ranks is not evenly divisible by the requested number of ranks per worker. If the specified number of islands is smaller than 1. If the number of workers in the custom worker distribution does not equal overall number of ranks. If a custom migration topology has the wrong shape. If the migration probability is not within [0, 1].

propulate(logging_interval: int = 10, debug: int = 1) None

Run Propulate optimization.

Parameters:
  • logging_interval (int) – The logging interval.

  • debug (int) – The debug level.

Returns:

The top-n best individuals on each island.

Return type:

List[List[propulate.population.Individual] | propulate.population.Individual]

summarize(top_n: int = 3, debug: int = 1) List[List[propulate.population.Individual] | propulate.population.Individual] | None

Summarize optimization results.

Parameters:
  • top_n (int) – The number of best results to report. Default is 3.

  • debug (int) – The debug level; 0 - silent; 1 - moderate, 2 - noisy (debug mode). Default is 1.

Returns:

The top-n best individuals on each island.

Return type:

List[List[propulate.population.Individual] | propulate.population.Individual]

class propulate.Migrator(loss_fn: Callable | Generator[float, None, None], propagator: propulate.propagators.Propagator, rng: random.Random, island_idx: int = 0, island_comm: mpi4py.MPI.Comm = MPI.COMM_WORLD, propulate_comm: mpi4py.MPI.Comm = MPI.COMM_WORLD, worker_sub_comm: mpi4py.MPI.Comm = MPI.COMM_SELF, generations: int = -1, checkpoint_path: str | pathlib.Path = Path('./'), migration_topology: numpy.ndarray | None = None, migration_prob: float = 0.0, emigration_propagator: Type[propulate.propagators.Propagator] = SelectMin, island_displs: numpy.ndarray | None = None, island_counts: numpy.ndarray | None = None, surrogate_factory: Callable[[], propulate.surrogate.Surrogate] | None = None)

Bases: propulate.propulator.Propulator

Initialize Migrator with given parameters.

Parameters:
  • loss_fn (Union[Callable, Generator[float, None, None]]) – The loss function to be minimized.

  • propagator (propulate.propagators.Propagator) – The propagator to apply for breeding.

  • rng (random.Random) – The separate random number generator for the Propulate optimization.

  • island_idx (int, optional) – The island’s index. Default is 0.

  • island_comm (MPI.Comm, optional) – The intra-island communicator for communication within that island. Default is MPI.COMM_WORLD.

  • propulate_comm (MPI.Comm, optional) – The Propulate world communicator, consisting of rank 0 of each worker’s sub communicator. Default is MPI.COMM_WORLD.

  • worker_sub_comm (MPI.Comm, optional) – The sub communicator for each (multi rank) worker. Default is MPI.COMM_SELF.

  • generations (int, optional) – The number of generations to run. Default is -1, i.e., run into wall-clock time limit.

  • checkpoint_path (pathlib.Path | str, optional) – The path where the checkpoints are loaded from and stored. Default is current working directory.

  • migration_topology (numpy.ndarray, optional) – The migration topology, i.e., a 2D matrix where entry (i,j) specifies how many individuals are sent by island i to island j.

  • migration_prob (float, optional) – The per-worker migration probability. Default is 0.0.

  • emigration_propagator (Type[propulate.propagators.Propagator]) – The emigration propagator, i.e., how to choose individuals for emigration that are sent to the destination island. Should be some kind of selection operator. Default is SelectMin.

  • island_displs (numpy.ndarray, optional) – An array with propulate_comm rank of each island’s worker 0. Element i specifies the rank of worker 0 on island with index i in the Propulate communicator.

  • island_counts (numpy.ndarray, optional) – An array with the number of workers per island. Element i specifies the number of workers on island i.

  • surrogate_factory (Callable[[], propulate.surrogate.Surrogate], optional) – Function that returns a new instance of a Surrogate model. Only used when loss_fn is a generator function.

_send_emigrants() None

Perform migration, i.e. island sends individuals out to other islands.

_receive_immigrants() None

Check for and possibly receive immigrants send by other islands.

Raises:

RuntimeError – If identical immigrant is already active on target island for real migration.

_check_emigrants_to_deactivate() bool

Redundant safety check for existence of emigrants that could not be deactivated in population.

Returns:

True if emigrants to be deactivated exist in population, False if not.

Return type:

bool

_deactivate_emigrants() None

Check for and possibly receive emigrants from other intra-island workers to be deactivated.

propulate(logging_interval: int = 10, debug: int = 1) None

Execute evolutionary algorithm using island model with real migration in parallel.

Parameters:
  • logging_interval (int, optional) – The logging interval. Default is 10.

  • debug (int) – The debug level; 0 - silent; 1 - moderate, 2 - noisy (debug mode). Default is 1.

Raises:

ValueError – If any individuals are left that should have been deactivated before (only for debug > 0).

class propulate.Pollinator(loss_fn: Callable | Generator[float, None, None], propagator: propulate.propagators.Propagator, rng: random.Random, island_idx: int = 0, island_comm: mpi4py.MPI.Comm = MPI.COMM_WORLD, propulate_comm: mpi4py.MPI.Comm = MPI.COMM_WORLD, worker_sub_comm: mpi4py.MPI.Comm = MPI.COMM_SELF, generations: int = 0, checkpoint_path: pathlib.Path | str = Path('./'), migration_topology: numpy.ndarray | None = None, migration_prob: float = 0.0, emigration_propagator: Type[propulate.propagators.Propagator] = SelectMin, immigration_propagator: Type[propulate.propagators.Propagator] = SelectMax, island_displs: numpy.ndarray | None = None, island_counts: numpy.ndarray | None = None, surrogate_factory: Callable[[], propulate.surrogate.Surrogate] | None = None)

Bases: propulate.propulator.Propulator

Initialize Pollinator with given parameters.

Parameters:
  • loss_fn (Union[Callable, Generator[float, None, None]]) – The loss function to be minimized.

  • propagator (propulate.propagators.Propagator) – The propagator to apply for breeding.

  • rng (random.Random) – The separate random number generator for the Propulate optimization.

  • island_idx (int, optional) – The island index. Default is 0.

  • island_comm (MPI.Comm, optional) – The intra-island communicator for communication within this island. Default is MPI.COMM_WORLD.

  • propulate_comm (MPI.Comm, optional) – The Propulate world communicator, consisting of rank 0 of each worker’s sub communicator. Default is MPI.COMM_WORLD.

  • worker_sub_comm (MPI.Comm, optional) – The sub communicator for each (multi rank) worker. Default is MPI.COMM_SELF.

  • generations (int, optional) – The number of generations to run. Default is -1, i.e., run into wall-clock time limit.

  • checkpoint_path (pathlib.Path, optional) – The path where checkpoints are loaded from and stored. Default is current working directory.

  • migration_topology (numpy.ndarray, optional) – The 2D matrix where entry (i,j) specifies how many individuals are sent by island i to island j.

  • migration_prob (float, optional) – The per-worker migration probability. Default is 0.0.

  • emigration_propagator (Type[propulate.propagators.Propagator], optional) – The emigration propagator, i.e., how to choose individuals for emigration that are sent to the destination island. Should be some kind of selection operator. Default is SelectMin.

  • immigration_propagator (Type[propulate.propagators.Propagator], optional) – The immigration propagator, i.e., how to choose individuals to be replaced by immigrants on a target island. Should be some kind of selection operator. Default is SelectMax.

  • island_displs (numpy.ndarray, optional) – An array with propulate_comm rank of each island’s worker 0. Element i specifies the rank of worker 0 on island with index i in the Propulate communicator.

  • island_counts (numpy.ndarray, optional) – An array with the number of workers per island. Element i specifies the number of workers on island i.

  • surrogate_factory (Callable[[], propulate.surrogate.Surrogate], optional) – Function that returns a new instance of a Surrogate model. Only used when loss_fn is a generator function.

_send_emigrants() None

Perform migration, i.e. island sends individuals out to other islands.

_receive_immigrants() None

Check for and possibly receive immigrants send by other islands.

_deactivate_replaced_individuals() None

Check for and receive individuals from other intra-island workers to be deactivated due to immigration.

_check_for_duplicates(active: bool, debug: int = 1) Tuple[List[List[propulate.population.Individual | int]], List[propulate.population.Individual]]

Check for duplicates in current population.

For pollination, duplicates are allowed as emigrants are sent as copies and not deactivated on sending island.

Parameters:
  • active (bool) – Whether to consider active individuals (True) or all individuals (False).

  • debug (int, optional) – The debug level; 0 - silent; 1 - moderate, 2 - noisy (debug mode). Default is 1.

Returns:

  • List[List[propulate.population.Individual | int]] – The individuals and their occurrences.

  • List[propulate.population.Individual] – All unique individuals in the population.

propulate(logging_interval: int = 10, debug: int = 1) None

Execute evolutionary algorithm using island model with pollination in parallel.

Parameters:
  • logging_interval (int, optional) – The logging interval. Default is 10.

  • debug (int, optional) – The debug level; 0 - silent; 1 - moderate, 2 - noisy (debug mode). Default is 1.

class propulate.Individual(position: MutableMapping[str, str | int | float | Any] | numpy.ndarray, limits: Mapping[str, Tuple[float, float] | Tuple[int, int] | Tuple[str, Ellipsis]], velocity: numpy.ndarray | None = None, generation: int = -1, rank: int = -1)

Initialize an individual with given parameters.

Parameters:
  • generation (int) – The current generation (-1 if unset).

  • rank (int) – The rank (-1 if unset).

__getitem__(key: str) float | int | str

Return decoded value for input key.

__setitem__(key: str, newvalue: float | int | str | Any) None

Encode and set value for given key.

__delitem__(key: str) None

Do not implement deleting items.

__len__() int

Give number of genes, i.e., parameter space dimension. Each categorical variable adds only one dimension.

__contains__(key: str) bool

Check if individual contains key.

values() ValuesView

Return dict values view.

items() ItemsView

Return dict items view.

keys() KeysView

Return dict keys view.

abstract clear() None

Not implemented.

abstract update(*args: Any, **kwargs: Any) None

Not implemented.

__repr__() str

Return string representation of an Individual instance.

__iter__() Generator[str, None, None]

Return standard iterator.

__eq__(other: object) bool

Define equality operator == for class Individual.

Checks for equality of traits, loss, generation, worker rank, birth island, and active status. Other attributes, like migration steps, are not considered.

Parameters:

other (Individual) – Other individual to compare individual under consideration to.

Returns:

True if individuals are the same, false if not.

Return type:

bool

Raises:

TypeError – If other is not an instance or subclass of Individual.

equals(other: object) bool

Define alternative equality check for class Individual.

Checks for equality of traits and loss. Other attributes, like birth island or generation, are not considered.

Parameters:

other (Individual) – The other individual to compare the individual under consideration to.

Returns:

True if individuals are the same, false if not.

Return type:

bool

Raises:

TypeError – If other is not an instance or subclass of Individual.

class propulate.Propulator(loss_fn: Callable | Generator[float, None, None], propagator: propulate.propagators.Propagator, rng: random.Random, island_idx: int = 0, island_comm: mpi4py.MPI.Comm = MPI.COMM_WORLD, propulate_comm: mpi4py.MPI.Comm = MPI.COMM_WORLD, worker_sub_comm: mpi4py.MPI.Comm = MPI.COMM_SELF, generations: int = -1, checkpoint_path: str | pathlib.Path = Path('./'), migration_topology: numpy.ndarray | None = None, migration_prob: float = 0.0, emigration_propagator: Type[propulate.propagators.Propagator] = SelectMin, island_displs: numpy.ndarray | None = None, island_counts: numpy.ndarray | None = None, surrogate_factory: Callable[[], propulate.surrogate.Surrogate] | None = None)

Initialize Propulator with given parameters.

Parameters:
  • loss_fn (Union[Callable, Generator[float, None, None]]) – The loss function to be minimized.

  • propagator (propulate.propagators.Propagator) – The propagator to apply for breeding.

  • rng (random.Random) – The separate random number generator for the Propulate optimization.

  • island_idx (int, optional) – The island’s index. Default is 0.

  • island_comm (MPI.Comm, optional) – The intra-island communicator. Default is MPI.COMM_WORLD.

  • propulate_comm (MPI.Comm, optional) – The Propulate world communicator, consisting of rank 0 of each worker’s sub communicator. Default is MPI.COMM_WORLD.

  • worker_sub_comm (MPI.Comm, optional) – The sub communicator for each (multi rank) worker. Default is MPI.COMM_SELF.

  • generations (int, optional) – The number of generations to run. Default is -1, i.e., run into wall-clock time limit.

  • checkpoint_path (pathlib.Path | str, optional) – The path where checkpoints are loaded from and stored. Default is current working directory.

  • migration_topology (numpy.ndarray, optional) – The migration topology, i.e., a 2D matrix where entry (i,j) specifies how many individuals are sent by island i to island j.

  • migration_prob (float, optional) – The per-worker migration probability. Default is 0.0.

  • emigration_propagator (Type[propulate.propagators.Propagator], optional) – The emigration propagator, i.e., how to choose individuals for emigration that are sent to destination island. Should be some kind of selection operator. Default is SelectMin.

  • island_displs (numpy.ndarray, optional) – An array with propulate_comm rank of each island’s worker 0. Element i specifies the rank of worker 0 on island with index i in the Propulate communicator.

  • island_counts (numpy.ndarray, optional) – An array with the number of workers per island. Element i specifies the number of workers on island with index i.

  • surrogate_factory (Callable[[], propulate.surrogate.Surrogate], optional) – Function that returns a new instance of a Surrogate model. Only used when loss_fn is a generator function.

_get_active_individuals() Tuple[List[propulate.population.Individual], int]

Get active individuals in current population list.

Returns:

  • List[propulate.population.Individual] – All active individuals in the current population.

  • int – The number of currently active individuals.

_breed() propulate.population.Individual

Apply propagator to current population of active individuals to breed new individual.

Returns:

The newly bred individual.

Return type:

propulate.population.Individual

_evaluate_individual() None

Breed and evaluate individual.

_receive_intra_island_individuals() None

Check for and possibly receive incoming individuals evaluated by other workers within own island.

abstract _send_emigrants() None

Perform migration, i.e., island sends individuals out to other islands.

Raises:

NotImplementedError – Not implemented in Propulator base class. Exact migration and pollination behavior is defined in the Migrator and Pollinator classes, respectively.

abstract _receive_immigrants() None

Check for and possibly receive immigrants send by other islands.

Raises:

NotImplementedError – Not implemented in Propulator base class. Exact migration and pollination behavior is defined in the Migrator and Pollinator classes, respectively.

_get_unique_individuals() List[propulate.population.Individual]

Get unique individuals in terms of traits and loss in current population.

Returns:

All unique individuals in the current population.

Return type:

List[propulate.population.Individual]

_check_intra_island_synchronization(populations: List[List[propulate.population.Individual]]) bool

Check synchronization of populations of workers within one island.

Parameters:

populations (List[List[propulate.population.Individual]]) – A list of all islands’ sorted population lists.

Returns:

True if populations are synchronized, False if not.

Return type:

bool

propulate(logging_interval: int = 10, debug: int = -1) None

Execute evolutionary algorithm in parallel.

Parameters:
  • logging_interval (int, optional) – Print each worker’s progress every logging_interval-th generation. Default is 10.

  • debug (int, optional) – The debug level; 0 - silent; 1 - moderate, 2 - noisy (debug mode). Default is 1.

Raises:

ValueError – If any individuals are left that should have been deactivated before (only for debug > 0).

_dump_checkpoint() None

Dump checkpoint to file.

_determine_worker_dumping_next() bool

Determine the worker who dumps the checkpoint in the next generation.

_dump_final_checkpoint() None

Dump final checkpoint.

_check_for_duplicates(active: bool, debug: int = 1) Tuple[List[List[propulate.population.Individual | int]], List[propulate.population.Individual]]

Check for duplicates in current population.

For pollination, duplicates are allowed as emigrants are sent as copies and not deactivated on sending island.

Parameters:
  • active (bool) – Whether to consider active individuals (True) or all individuals (False).

  • debug (int, optional) – The debug level; 0 - silent; 1 - moderate, 2 - noisy (debug mode). Default is 1.

Returns:

  • List[List[propulate.population.Individual | int]] – The individuals and their occurrences.

  • List[propulate.population.Individual] – The unique individuals in the population.

summarize(top_n: int = 1, debug: int = 1) List[List[propulate.population.Individual] | propulate.population.Individual] | None

Get top-n results from Propulate optimization.

Parameters:
  • top_n (int, optional) – The number of best results to report. Default is 1.

  • debug (int, optional) – The debug level; 0 - silent; 1 - moderate, 2 - noisy (debug mode). Default is 1.

Returns:

The top-n best individuals on each island.

Return type:

List[List[propulate.population.Individual] | propulate.population.Individual]

class propulate.Surrogate

Initialize a new surrogate model.

Propulate passes down a surrogate factory, as defined by the user, to each Propulator instance. That means __init__ can be overwritten to take additional arguments.

Raises:

NotImplementedError – Not implemented (abstract base class method needs to be overridden).

abstract start_run(ind: propulate.population.Individual) None

Signal that a new run is about to start.

This is called before the first yield from the loss_fn. It is assumed that the individual is freshly created. Keep in mind that there might be (private) keys that are not related to limits, like the surrogate key _s; key names related to limits could be provided to the Surrogate constructor if necessary.

Parameters:

ind (propulate.population.Individual) – The individual to be evaluated.

Raises:

NotImplementedError – Not implemented (abstract base class method needs to be overridden).

abstract update(loss: float) None

Update the surrogate model with the final loss.

Indicative that the current run has finished.

Parameters:

loss (float) – The final loss of the current run.

Raises:

NotImplementedError – Not implemented (abstract base class method needs to be overridden).

abstract cancel(loss: float) bool

Evaluate surrogate to check if the current run should be cancelled.

This will be called after every yield from the loss_fn.

Parameters:

loss (float) – The loss of the most recent step.

Returns:

If the surrogate model determines that the current run will not result in a lower loss than previous runs.

Return type:

bool

Raises:

NotImplementedError – Not implemented (abstract base class method needs to be overridden).

abstract merge(data: Any) None

Merge the results of another surrogate model into itself.

Used to synchronize surrogate models from different Propulators.

Implementation of merge has to be commutative! Otherwise, the different surrogate models will diverge.

Parameters:

data (Any) – All relevant information to update its model to the same state as the origin of the data.

Raises:

NotImplementedError – Not implemented (abstract base class method needs to be overridden).

abstract data() Any

Return all relevant information about the surrogate model for merging with another surrogate.

It most likely only needs to return the most recent loss from update().

Returns:

All relevant information to convey the current state of the surrogate model.

Return type:

T

Raises:

NotImplementedError – Not implemented (abstract base class method needs to be overridden).

propulate.get_default_propagator(pop_size: int, limits: Mapping[str, Tuple[float, float] | Tuple[int, int] | Tuple[str, Ellipsis]], crossover_prob: float = 0.7, mutation_prob: float = 0.4, random_init_prob: float = 0.1, sigma_factor: float = 0.05, rng: random.Random | None = None) propulate.propagators.Propagator

Get Propulate’s default evolutionary optimization propagator.

Parameters:
  • pop_size (int) – The number of individuals in the breeding population.

  • limits (Dict[str, Tuple[float, float]] | Dict[str, Tuple[int, int]] | Dict[str, Tuple[str, ...]]) – The (hyper-)parameters to be optimized, i.e., the search space.

  • crossover_prob (float, optional) – The uniform-crossover probability. Default is 0.7.

  • mutation_prob (float, optional) – The point-mutation probability. Default is 0.4.

  • random_init_prob (float, optional) – The random-initialization probability. Default is 0.1.

  • sigma_factor (float) – The scaling factor for obtaining the standard deviation from the search-space boundaries for interval mutation. Default is 0.05.

  • rng (random.Random, optional) – The separate random number generator for the Propulate optimization.

Returns:

A basic evolutionary optimization propagator.

Return type:

propagators.Propagator

propulate.set_logger_config(level: int = logging.INFO, log_file: str | pathlib.Path | None = None, log_to_stdout: bool = True, log_rank: bool = False, colors: bool = True) None

Set up the logger. Should only need to be done once. Generally, logging should only be done on the master rank.

Parameters:
  • level (int) – The default level for logging. Default is logging.INFO.

  • log_file (str | Path, optional) – The file to save the log to.

  • log_to_stdout (bool) – A flag indicating if the log should be printed on stdout. Default is True.

  • log_rank (bool) – A flag for prepending the MPI rank to the logging message. Default is False.

  • colors (bool) – A flag for using colored logs. Default is True.