From 7b235c152464d5ba1ac4d52d29020ce02c6a14fb Mon Sep 17 00:00:00 2001 From: Eirini Koutsaniti Date: Mon, 26 Sep 2022 17:16:34 +0200 Subject: [PATCH 1/4] Relax configuration schema for launcher --- docs/config_reference.rst | 33 +++++++++++++++++++++++++++++++++ reframe/schemas/config.json | 7 +------ 2 files changed, 34 insertions(+), 6 deletions(-) diff --git a/docs/config_reference.rst b/docs/config_reference.rst index b6e156ae0b..44944bdc35 100644 --- a/docs/config_reference.rst +++ b/docs/config_reference.rst @@ -322,6 +322,39 @@ System Partition Configuration - ``upcrun``: Parallel programs will be launched using the `UPC `__ ``upcrun`` command. - ``upcxx-run``: Parallel programs will be launched using the `UPC++ `__ ``upcxx-run`` command. + .. tip:: + + ReFrame also allows you to register your own custom launchers simply by defining them in the configuration. + Here is an example: + + .. code:: python + + import reframe.core.launchers.mpi as mpi + + @mpi.register_launcher('custom_launcher') + class MyLauncher(mpi.SrunLauncher): + def command(self, job): + return super().command(job) + [...] + + site_configuration = { + 'systems': [ + { + 'name': 'my_system', + 'partitions': [ + { + 'name': 'my_partition', + 'launcher': 'custom_launcher' + ... + } + ], + ... + }, + ... + ], + ... + } + + .. js:attribute:: .systems[].partitions[].access :required: No diff --git a/reframe/schemas/config.json b/reframe/schemas/config.json index f643002f7e..7867b28fc0 100644 --- a/reframe/schemas/config.json +++ b/reframe/schemas/config.json @@ -251,12 +251,7 @@ ] }, "launcher": { - "type": "string", - "enum": [ - "alps", "ibrun", "local", "mpirun", - "mpiexec", "srun", "srunalloc", "ssh", - "upcrun", "upcxx-run", "lrun", "lrun-gpu" - ] + "type": "string" }, "access": { "type": "array", From f5a609c514e98a457eeeea3fbf528f18119d46c0 Mon Sep 17 00:00:00 2001 From: Eirini Koutsaniti Date: Thu, 29 Sep 2022 11:15:20 +0200 Subject: [PATCH 2/4] Update the tutorial --- docs/config_reference.rst | 31 ++------------------ docs/tutorial_advanced.rst | 58 ++++++++++++++++++++++++++++++++++++-- 2 files changed, 59 insertions(+), 30 deletions(-) diff --git a/docs/config_reference.rst b/docs/config_reference.rst index 44944bdc35..430083cf90 100644 --- a/docs/config_reference.rst +++ b/docs/config_reference.rst @@ -324,35 +324,10 @@ System Partition Configuration .. tip:: - ReFrame also allows you to register your own custom launchers simply by defining them in the configuration. - Here is an example: + .. versionadded:: 4.0.0 - .. code:: python - - import reframe.core.launchers.mpi as mpi - - @mpi.register_launcher('custom_launcher') - class MyLauncher(mpi.SrunLauncher): - def command(self, job): - return super().command(job) + [...] - - site_configuration = { - 'systems': [ - { - 'name': 'my_system', - 'partitions': [ - { - 'name': 'my_partition', - 'launcher': 'custom_launcher' - ... - } - ], - ... - }, - ... - ], - ... - } + ReFrame also allows you to register your own custom launchers simply by defining them in the configuration. + You can follow a small tutorial `here `__. .. js:attribute:: .systems[].partitions[].access diff --git a/docs/tutorial_advanced.rst b/docs/tutorial_advanced.rst index f23c7fd143..43f42df007 100644 --- a/docs/tutorial_advanced.rst +++ b/docs/tutorial_advanced.rst @@ -576,8 +576,6 @@ The trick here is to replace the parallel launcher with the local one, which pra The :func:`~reframe.core.backends.getlauncher` function takes the `registered `__ name of a launcher and returns the class that implements it. You then instantiate the launcher and assign to the :attr:`~reframe.core.schedulers.Job.launcher` attribute of the job descriptor. -An alternative to this approach would be to define your own custom parallel launcher and register it with the framework. -You could then use it as the scheduler of a system partition in the configuration, but this approach is less test-specific. Adding more parallel launch commands ==================================== @@ -628,6 +626,62 @@ Let's see how the generated job script looks like: The first three ``srun`` commands are emitted through the :attr:`prerun_cmds` whereas the last one comes from the test's :attr:`executable` attribute. +Adding a custom launcher to a partition +======================================= + +.. versionadded:: 4.0.0 + +An alternative to the approaches above would be to define your own custom parallel launcher and register it with the framework. +You could then use it as the launcher of a system partition in the configuration and use it in multiple tests. + +Each `launcher `__ needs to implement the ``command`` method and can optionally change the default ``run_command`` method. + +Here is an example of the srun implementation to get an idea and change according to your needs: + +.. code:: python + + from reframe.core.backends import register_launcher + from reframe.core.launchers import JobLauncher + + + @register_launcher('my_srun') + class SrunLauncher(JobLauncher): + def command(self, job): + return ['srun'] + + +For more advanced cases you may also want to inherit from an `already implemented launcher `__ and extend it. This would look like: + +.. code:: python + + import reframe.core.launchers.mpi as mpi + from reframe.core.backends import register_launcher + + + @register_launcher('custom_launcher') + class MyLauncher(mpi.SrunLauncher): + def command(self, job): + return super().command(job) + [...] + + site_configuration = { + 'systems': [ + { + 'name': 'my_system', + 'partitions': [ + { + 'name': 'my_partition', + 'launcher': 'custom_launcher' + ... + } + ], + ... + }, + ... + ], + ... + } + + Flexible Regression Tests ------------------------- From 5a1ff9f1442f39f5a95b8b684c40430190518ecc Mon Sep 17 00:00:00 2001 From: Eirini Koutsaniti Date: Thu, 29 Sep 2022 14:49:31 +0200 Subject: [PATCH 3/4] Update JobLauncher docs --- reframe/core/launchers/__init__.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/reframe/core/launchers/__init__.py b/reframe/core/launchers/__init__.py index d187c9a74f..f59a1ed362 100644 --- a/reframe/core/launchers/__init__.py +++ b/reframe/core/launchers/__init__.py @@ -15,11 +15,11 @@ class JobLauncher(abc.ABC): A job launcher is the executable that actually launches a distributed program to multiple nodes, e.g., ``mpirun``, ``srun`` etc. - .. warning:: - - Users may not create job launchers directly. .. note:: + .. versionchanged:: 4.0.0 + Users may create job launchers directly. + .. versionchanged:: 2.8 Job launchers do not get a reference to a job during their initialization. From a1bfb16a1a816b9dd0117c2eeb439d1e407cd4af Mon Sep 17 00:00:00 2001 From: Vasileios Karakasis Date: Mon, 3 Oct 2022 23:59:39 +0200 Subject: [PATCH 4/4] Improve docs for custom launcher --- docs/tutorial_advanced.rst | 25 ++++++++++++++----------- 1 file changed, 14 insertions(+), 11 deletions(-) diff --git a/docs/tutorial_advanced.rst b/docs/tutorial_advanced.rst index 43f42df007..f56e5cacc9 100644 --- a/docs/tutorial_advanced.rst +++ b/docs/tutorial_advanced.rst @@ -634,9 +634,9 @@ Adding a custom launcher to a partition An alternative to the approaches above would be to define your own custom parallel launcher and register it with the framework. You could then use it as the launcher of a system partition in the configuration and use it in multiple tests. -Each `launcher `__ needs to implement the ``command`` method and can optionally change the default ``run_command`` method. +Each `launcher `__ needs to implement the :func:`~reframe.core.launchers.JobLauncher.command` method and can optionally change the default :func:`~reframe.core.launchers.JobLauncher.run_command` method. -Here is an example of the srun implementation to get an idea and change according to your needs: +As an example of how easy it is to define a new parallel launcher backend, here is the actual implementation of the ``mpirun`` launcher: .. code:: python @@ -644,24 +644,27 @@ Here is an example of the srun implementation to get an idea and change accordin from reframe.core.launchers import JobLauncher - @register_launcher('my_srun') - class SrunLauncher(JobLauncher): + @register_launcher('mpirun') + class MpirunLauncher(JobLauncher): def command(self, job): - return ['srun'] + return ['mpirun', '-np', str(job.num_tasks)] -For more advanced cases you may also want to inherit from an `already implemented launcher `__ and extend it. This would look like: +The :func:`~reframe.core.launchers.JobLauncher.command` returns a list of command tokens that will be combined with any user-supplied `options `__ by the :func:`~reframe.core.launchers.JobLauncher.run_command` method to generate the actual launcher command line. +Notice you can use the ``job`` argument to get job-specific information that will allow you to construct the correct launcher invocation. + +If you use a Python-based configuration file, you can define your custom launcher directly inside your config as follows: .. code:: python - import reframe.core.launchers.mpi as mpi from reframe.core.backends import register_launcher + from reframe.core.launchers import JobLaucher - @register_launcher('custom_launcher') - class MyLauncher(mpi.SrunLauncher): + @register_launcher('slrun') + class MySmartLauncher(JobLauncher): def command(self, job): - return super().command(job) + [...] + return ['slrun', ...] site_configuration = { 'systems': [ @@ -670,7 +673,7 @@ For more advanced cases you may also want to inherit from an `already implemente 'partitions': [ { 'name': 'my_partition', - 'launcher': 'custom_launcher' + 'launcher': 'slrun' ... } ],