diff --git a/libensemble/executors/mpi_executor.py b/libensemble/executors/mpi_executor.py index 96c4d0d09..28d1fb6f9 100644 --- a/libensemble/executors/mpi_executor.py +++ b/libensemble/executors/mpi_executor.py @@ -47,29 +47,32 @@ class MPIExecutor(Executor): information using the ``custom_info`` argument. This takes a dictionary of values. - The allowable fields are:: + The allowable fields are: - 'mpi_runner' [string]: - Select runner: 'mpich', 'openmpi', 'aprun', 'srun', 'jsrun', 'custom' - All except 'custom' relate to runner classes in libEnsemble. + .. parsed-literal:: + + **'mpi_runner'** [string]: + Select runner: `'mpich'`, `'openmpi'`, `'aprun'`, `'srun'`, `'jsrun'`, `'custom'` + All except `'custom'` relate to runner classes in libEnsemble. Custom allows user to define their own run-lines but without parsing arguments or making use of auto-resources. - 'runner_name' [string]: - Runner name: Replaces run command if present. All runners have a default - except for 'custom'. - 'subgroup_launch' [bool]: + **'runner_name'** [string]: + The literal string that appears at the front of the run command. + This is typically 'mpirun', 'srun', etc., and can be a full path. + Defaults exist for all runners except 'custom'. + **'subgroup_launch'** [bool]: Whether MPI runs should be initiated in a new process group. This needs to be correct for kills to work correctly. Use the standalone test at - libensemble/tests/standalone_tests/kill_test to determine correct value + `libensemble/tests/standalone_tests/kill_test` to determine correct value for a system. - For example:: + For example:: - customizer = {'mpi_runner': 'mpich', - 'runner_name': 'wrapper -x mpich'} + customizer = {'mpi_runner': 'mpich', + 'runner_name': 'wrapper -x mpich'} - from libensemble.executors.mpi_executor import MPIExecutor - exctr = MPIExecutor(custom_info=customizer) + from libensemble.executors.mpi_executor import MPIExecutor + exctr = MPIExecutor(custom_info=customizer) """ @@ -336,6 +339,9 @@ def submit( else: mpi_runner_obj = self.mpi_runner_obj or self._create_mpi_runner_from_attr() + if env_script is None and mpi_runner_obj is None: + raise ExecutorException("No valid MPI runner was found") + mpi_specs = mpi_runner_obj.get_mpi_specs( task, num_procs, diff --git a/libensemble/executors/mpi_runner.py b/libensemble/executors/mpi_runner.py index eb002d14b..48953cc3c 100644 --- a/libensemble/executors/mpi_runner.py +++ b/libensemble/executors/mpi_runner.py @@ -21,11 +21,13 @@ def get_runner(mpi_runner_type, runner_name=None, platform_info=None): "msmpi": MSMPI_MPIRunner, "custom": MPIRunner, } - mpi_runner = mpi_runners[mpi_runner_type] - if runner_name is not None: - runner = mpi_runner(run_command=runner_name, platform_info=platform_info) - else: - runner = mpi_runner(platform_info=platform_info) + runner = None + if mpi_runner_type is not None: + mpi_runner = mpi_runners[mpi_runner_type] + if runner_name is not None: + runner = mpi_runner(run_command=runner_name, platform_info=platform_info) + else: + runner = mpi_runner(platform_info=platform_info) return runner def __init__(self, run_command="mpiexec", platform_info=None):