Launcher

aimmd.Launcher orchestrates one or more runs. It normalizes inputs, computes worker counts and CPU/GPU allocations, builds the on-disk directory layout, and then either launches workers locally (via spawned processes) or emits a SLURM job script that starts them with srun.

class aimmd.Launcher(params, directories, termination_timeout=60.0, save_params=True)[source]

Bases: LauncherHelpers, LauncherMagic, LauncherProperties, LauncherMethods, LauncherBuild, LauncherRun

Orchestrate one or more AIMMD runs and spawn/manage worker processes.

A Launcher groups together runs, where each run is defined by:

  • a Params instance (or a path to a saved Params file),

  • a working directory where trajectories, caches, and logs are created.

The launcher turns this declarative configuration into an execution plan (via _build()) and then executes it either:

  • locally, by spawning processes and monitoring them (run()), or

  • on a cluster, by emitting an srun-based SLURM script that launches the same workers (create_job()).

The launcher also computes derived values that are needed to run reliably:

  • how many worker processes should be launched for each run and role,

  • per-task CPU/GPU allocations (shared, all, explicit, or skipped binding),

  • stop-condition budgets to pass to workers.

Notes

  • This class is built from mixins. The public methods users typically call are:

  • A launcher installs SIGINT/SIGTERM handlers (via LauncherHelpers._init()) that clear managed processes. This behavior assumes the launcher runs in a main thread in an interactive/script context.

  • The launcher uses a fail-fast supervision policy: during local runs, it stops all workers when any worker exits; non-zero exit codes are treated as failure.

Initialize a launcher instance.

Parameters:

params – Parameter specification(s) for the run(s). Each element may be:

  • a path to a saved Params file (string), loaded via

aimmd.params.Params.load(), or

  • an already instantiated Params.

If a single string/Params is given, it is treated as a one-element list (one run). :type params: str or aimmd.params.Params or iterable of these :param directories: Working directory (or directories) in which to run simulations. Each directory is stored as a string and is interpreted relative to the current working directory by higher-level launcher logic.

If a single string is given, it is treated as a one-element list. :type directories: str or iterable of str :param termination_timeout: Grace period (seconds) for terminating worker processes, after which they may be killed by the executor. Stored as termination_timeout. Default is 60.. :type termination_timeout: float, optional :param save_params: If True: save params to file. Default is True. :type save_params: bool, optional

Return type:

None

Raises:

TypeError – If a params entry cannot be loaded, if any params object has no initial paths, or if directories cannot be converted into a list of strings.

Notes

  • All Params are forced to have a saved file on disk: if params[i].path is not a file, params[i].save() is called.

  • If the number of params and directories differs, the shorter list is extended by repeating its last element so that the lengths match.

  • Signal handlers for SIGTERM and SIGINT are installed at initialization.

add(params, directories)

Append one or more runs to the launcher.

Parameters:

params – Params specification(s) for the run(s). See

LauncherHelpers._init() for accepted forms. :type params: str or aimmd.params.Params or iterable :param directories: Working directory (or directories) for the new run(s). :type directories: str or iterable of str

Return type:

None

Raises:

TypeError – If, after appending, directories are not unique.

Notes

The launcher is updated in place and _update() is called to refresh derived fields (process counts, resource allocation, etc.).

create_job(filename, n=1, n1=0, n2=0, reactive_region_mode='chain', state1_mode='free', state2_mode='free', nsteps=inf, nframes=inf, nrounds=inf, walltime=86400, cpus_per_task=1, gpus_per_task=0, ntasks_per_node=1, skip_binding=True, nchains_per_worker=1)

Create a SLURM job script that launches AIMMD workers via srun.

The script produced by this method:

  • writes the SLURM header derived from params.slurm_header and from the provided defaults (if missing),

  • sets shell job control (set -m),

  • launches each planned worker as a background process using srun --exclusive ... &,

  • stops the full job allocation as soon as the first worker exits.

Parameters:
  • filename (str) – Destination path of the job script.

  • n – Number of replicas dedicated to reactive-region sampling. The exact

meaning depends on reactive_region_mode:

  • 'chain': committor-guided shooting chain (TPS/RFPS-like),

  • 'sweep': sweep shooting for committor validation,

  • 'free': free simulations instead of shooting.

Default is 1. :type n: int or iterable of int, optional :param n1: Number of replicas dedicated to sampling around the initial end state (params.states[0]). Default is 0. :type n1: int or iterable of int, optional :param n2: Number of replicas dedicated to sampling around the final end state (params.states[2]). Default is 0. :type n2: int or iterable of int, optional :param reactive_region_mode: Mode for reactive-region replicas. Default is 'chain'. :type reactive_region_mode: {‘chain’, ‘free’, ‘sweep’} or iterable, optional :param state1_mode: Mode for state-1 replicas. Default is 'free'. :type state1_mode: {‘free’, ‘shoot’} or iterable, optional :param state2_mode: Mode for state-2 replicas. Default is 'free'. :type state2_mode: {‘free’, ‘shoot’} or iterable, optional :param nchains_per_worker: If > 1, the worker will manage more than one chain. A higher value of nchains_per_worker tends to regularize the training set and thus improve performance. If running only one shooting worker, nchains_per_worker=10 is recommended. :type nchains_per_worker: int, optional, default = 1 :param nsteps: Maximum number of simulated independent trajectories (worker stop condition). Default is inf. Attention! If “train” runs, then nsteps refers to the total number of steps across the shooting simulations only. Otherwise, it refers to the number of steps of each single worker in the launcher run. The first worker reaching nsteps stops all the others. Exception – reactive_region_mode='sweep': nsteps is each sweep worker’s share of a global target, so the campaign runs until the combined committed-shot count over all n sweep workers reaches n * nsteps (the per-worker step/frame caps are disabled and the job waits for all workers rather than scancel-ing on the first to finish). This keeps the intended total exact even when workers are uneven, and lets a finished campaign be extended by raising nsteps and resubmitting. :type nsteps: float or iterable of float, optional :param nframes: Maximum number of simulated frames (worker stop condition). Default is inf. Attention! If “train” runs, then nframes refers to the total number of frames across all workers. Otherwise, it refers to the number of nframes of each single worker in the launcher run. The first worker reaching nsteps stops all the others. :type nframes: float or iterable of float, optional :param nrounds: If None and new simulations are requested, add a new process that trains the model and computes selection bins and densities indefinitely. If None and no new simulations are requested, just does one round before exiting. If != 0, the process does training rounds up until reaching nrounds, from that point on it just updates selection bins and densities. Forced to zero when reactive_region_mode = ‘sweep’. :type nrounds: float or iterable of float, optional :param walltime: Job walltime in seconds, written as #SBATCH --time=HH:MM:SS. Default is 24*3600 (24 hours). :type walltime: float, optional :param cpus_per_task: CPUs per worker task. May be overridden by an SBATCH directive present in params.slurm_header. Default is 1. :type cpus_per_task: int, optional :param gpus_per_task: GPUs per worker task. May be overridden by an SBATCH directive present in params.slurm_header. Default is 0. :type gpus_per_task: int, optional :param ntasks_per_node: Tasks per node. May be overridden by an SBATCH directive present in params.slurm_header. Default is 1. :type ntasks_per_node: int, optional :param skip_binding: If True, pass 'skip' to the worker for CPU/GPU binding so that workers do not explicitly bind resources. Default is True. :type skip_binding: bool, optional

Return type:

None

Raises:
  • OSError – If filename cannot be written.

  • TypeError – If the launcher cannot be configured with the requested modes.

Notes

  • The effective number of nodes is computed as:

    ceil(total_processes / ntasks_per_node)

    and written as #SBATCH --nodes=....

  • The script uses srun --exclusive --nodes=1 --ntasks=1 for each worker to ensure processes do not share a task allocation.

property directories

Run directories managed by this launcher.

Returns:

Copy of the internal directory list.

Return type:

list[str]

property params

Parameter sets managed by this launcher.

Returns:

Copy of the internal Params list.

Return type:

list[aimmd.params.Params]

property paths

Parameter file paths for each managed run.

Returns:

List of params.path for each run.

Return type:

list[pathlib.Path]

pop(i)

Remove the i-th run from the launcher.

Parameters:

i (int) – Index of the run to remove.

Return type:

None

Notes

This method mutates internal lists but does not call _update(). Callers that rely on derived fields should call _update() afterwards.

property processes

Process executor used to spawn and track worker processes.

Returns:

The process executor instance stored in _processes.

Return type:

aimmd.execute.processes.ProcessExecutor

run(n=1, n1=0, n2=0, reactive_region_mode='chain', state1_mode='free', state2_mode='free', nsteps=inf, nframes=inf, nrounds=None, walltime=inf, cpus_per_task='share', gpus_per_task='share', nchains_per_worker=1)

Launch AIMMD runs locally by spawning multiple worker processes.

Parameters:

n – Number of replicas dedicated to reactive-region sampling for each

run. Default is 1. :type n: int or iterable of int, optional :param n1: Number of replicas dedicated to sampling in/around the initial end state (params.states[0]). Default is 0. :type n1: int or iterable of int, optional :param n2: Number of replicas dedicated to sampling in/around the final end state (params.states[2]). Default is 0. :type n2: int or iterable of int, optional :param reactive_region_mode: Mode for reactive-region replicas:

  • 'chain': committor-guided shooting chain (TPS/RFPS-like),

  • 'sweep': sweep shooting for brute-force committor validation,

  • 'free': free simulations in place of shooting.

Default is 'chain'. :type reactive_region_mode: {‘chain’, ‘free’, ‘sweep’} or iterable, optional :param state1_mode: Mode for state-1 replicas. Default is 'free'. :type state1_mode: {‘free’, ‘shoot’} or iterable, optional :param state2_mode: Mode for state-2 replicas. Default is 'free'. :type state2_mode: {‘free’, ‘shoot’} or iterable, optional :param nsteps: Maximum number of simulated independent trajectories (worker stop condition). Default is inf. Attention! If “train” runs, then nsteps refers to the total number of steps across the shooting simulations only. Otherwise, it refers to the number of steps of each single worker in the launcher run. The first worker reaching nsteps stops all the others. :type nsteps: float or iterable of float, optional :param nchains_per_worker: If > 1, the worker will manage more than one chain. A higher value of nchains_per_worker tends to regularize the training set and thus improve performance. If running only one shooting worker, nchains_per_worker=10 is recommended. :type nchains_per_worker: int, optional, default = 1 :param nframes: Maximum number of simulated frames (worker stop condition). Default is inf. Attention! If “train” runs, then nframes refers to the total number of frames across all workers. Otherwise, it refers to the number of nframes of each single worker in the launcher run. The first worker reaching nsteps stops all the others. :type nframes: float or iterable of float, optional :param nrounds: If None and new simulations are requested, add a new process that trains the model and computes selection bins and densities indefinitely. If None and no new simulations are requested, just does one round before exiting. If != 0, the process does training rounds up until reaching nrounds, from that point on it just updates selection bins and densities. Forced to zero when reactive_region_mode = ‘sweep’. :type nrounds: float or iterable of float, optional :param walltime: Maximum walltime for the launcher monitoring loop (seconds). Also passed to workers as a stop condition when training is not enabled. Default is inf. :type walltime: float, optional :param cpus_per_task: CPU allocation policy per worker. Default is 'share'. :type cpus_per_task: {‘share’, ‘all’, ‘skip’} or int, optional :param gpus_per_task: GPU allocation policy per worker. Default is 'share'. :type gpus_per_task: {‘share’, ‘all’, ‘skip’} or int, optional

Return type:

None

Raises:
  • RuntimeError – If any worker exits with a non-zero exit code.

  • Exception – Re-raises unexpected exceptions that occur during process startup or monitoring.

Notes

The monitoring policy is “stop all as soon as any other stops”. This is consistent with AIMMD workflows where workers share on-disk state and should not keep running after another worker has stopped or failed.