Skip to content

Commit 0688653

Browse files
authored
Merge branch 'master' into patch-1
2 parents 9c48ccd + eae908e commit 0688653

File tree

6 files changed

+101
-20
lines changed

6 files changed

+101
-20
lines changed

docs/config_reference.rst

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -323,6 +323,14 @@ System Partition Configuration
323323
- ``upcrun``: Parallel programs will be launched using the `UPC <https://upc.lbl.gov/>`__ ``upcrun`` command.
324324
- ``upcxx-run``: Parallel programs will be launched using the `UPC++ <https://bitbucket.org/berkeleylab/upcxx/wiki/Home>`__ ``upcxx-run`` command.
325325

326+
.. tip::
327+
328+
.. versionadded:: 4.0.0
329+
330+
ReFrame also allows you to register your own custom launchers simply by defining them in the configuration.
331+
You can follow a small tutorial `here <tutorial_advanced.html#adding-a-custom-launcher-to-a-partition>`__.
332+
333+
326334
.. js:attribute:: .systems[].partitions[].access
327335

328336
:required: No
@@ -1180,6 +1188,15 @@ The additional properties for the ``httpjson`` handler are the following:
11801188
A set of optional key/value pairs to be passed with each log record to the server.
11811189
These may depend on the server configuration.
11821190

1191+
.. js:attribute:: .logging[].handlers[].ignore_keys
1192+
1193+
.. object:: .logging[].handlers_perflog[].ignore_keys
1194+
1195+
:required: No
1196+
:default: ``[]``
1197+
1198+
These keys will be excluded from the log record that will be sent to the server.
1199+
11831200

11841201
The ``httpjson`` handler sends log messages in JSON format using an HTTP POST request to the specified URL.
11851202

@@ -1194,7 +1211,8 @@ An example configuration of this handler for performance logging is shown here:
11941211
'extras': {
11951212
'facility': 'reframe',
11961213
'data-version': '1.0'
1197-
}
1214+
},
1215+
'ignore_keys': ['check_perfvalues']
11981216
}
11991217
12001218

docs/tutorial_advanced.rst

Lines changed: 59 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -576,8 +576,6 @@ The trick here is to replace the parallel launcher with the local one, which pra
576576
The :func:`~reframe.core.backends.getlauncher` function takes the `registered <config_reference.html#systems-.partitions-.launcher>`__ name of a launcher and returns the class that implements it.
577577
You then instantiate the launcher and assign to the :attr:`~reframe.core.schedulers.Job.launcher` attribute of the job descriptor.
578578

579-
An alternative to this approach would be to define your own custom parallel launcher and register it with the framework.
580-
You could then use it as the scheduler of a system partition in the configuration, but this approach is less test-specific.
581579

582580
Adding more parallel launch commands
583581
====================================
@@ -628,6 +626,65 @@ Let's see how the generated job script looks like:
628626
The first three ``srun`` commands are emitted through the :attr:`prerun_cmds` whereas the last one comes from the test's :attr:`executable` attribute.
629627

630628

629+
Adding a custom launcher to a partition
630+
=======================================
631+
632+
.. versionadded:: 4.0.0
633+
634+
An alternative to the approaches above would be to define your own custom parallel launcher and register it with the framework.
635+
You could then use it as the launcher of a system partition in the configuration and use it in multiple tests.
636+
637+
Each `launcher <regression_test_api.html#reframe.core.launchers.JobLauncher>`__ 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.
638+
639+
As an example of how easy it is to define a new parallel launcher backend, here is the actual implementation of the ``mpirun`` launcher:
640+
641+
.. code:: python
642+
643+
from reframe.core.backends import register_launcher
644+
from reframe.core.launchers import JobLauncher
645+
646+
647+
@register_launcher('mpirun')
648+
class MpirunLauncher(JobLauncher):
649+
def command(self, job):
650+
return ['mpirun', '-np', str(job.num_tasks)]
651+
652+
653+
The :func:`~reframe.core.launchers.JobLauncher.command` returns a list of command tokens that will be combined with any user-supplied `options <regression_test_api.html#reframe.core.launchers.JobLauncher.options>`__ by the :func:`~reframe.core.launchers.JobLauncher.run_command` method to generate the actual launcher command line.
654+
Notice you can use the ``job`` argument to get job-specific information that will allow you to construct the correct launcher invocation.
655+
656+
If you use a Python-based configuration file, you can define your custom launcher directly inside your config as follows:
657+
658+
.. code:: python
659+
660+
from reframe.core.backends import register_launcher
661+
from reframe.core.launchers import JobLaucher
662+
663+
664+
@register_launcher('slrun')
665+
class MySmartLauncher(JobLauncher):
666+
def command(self, job):
667+
return ['slrun', ...]
668+
669+
site_configuration = {
670+
'systems': [
671+
{
672+
'name': 'my_system',
673+
'partitions': [
674+
{
675+
'name': 'my_partition',
676+
'launcher': 'slrun'
677+
...
678+
}
679+
],
680+
...
681+
},
682+
...
683+
],
684+
...
685+
}
686+
687+
631688
Flexible Regression Tests
632689
-------------------------
633690

reframe/core/launchers/__init__.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,11 +15,11 @@ class JobLauncher(abc.ABC):
1515
A job launcher is the executable that actually launches a distributed
1616
program to multiple nodes, e.g., ``mpirun``, ``srun`` etc.
1717
18-
.. warning::
19-
20-
Users may not create job launchers directly.
2118
2219
.. note::
20+
.. versionchanged:: 4.0.0
21+
Users may create job launchers directly.
22+
2323
.. versionchanged:: 2.8
2424
Job launchers do not get a reference to a job during their
2525
initialization.

reframe/core/logging.py

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -371,7 +371,8 @@ def _create_httpjson_handler(site_config, config_prefix):
371371
return None
372372

373373
extras = site_config.get(f'{config_prefix}/extras')
374-
return HTTPJSONHandler(url, extras)
374+
ignore_keys = site_config.get(f'{config_prefix}/ignore_keys')
375+
return HTTPJSONHandler(url, extras, ignore_keys)
375376

376377

377378
class HTTPJSONHandler(logging.Handler):
@@ -386,20 +387,25 @@ class HTTPJSONHandler(logging.Handler):
386387
'stack_info', 'thread', 'threadName', 'exc_text'
387388
}
388389

389-
def __init__(self, url, extras=None):
390+
def __init__(self, url, extras=None, ignore_keys=None):
390391
super().__init__()
391392
self._url = url
392393
self._extras = extras
394+
self._ignore_keys = ignore_keys
393395

394396
def _record_to_json(self, record):
397+
def _can_send(key):
398+
return not (
399+
key.startswith('_') or key in HTTPJSONHandler.LOG_ATTRS
400+
or (self._ignore_keys and key in self._ignore_keys)
401+
)
402+
395403
json_record = {
396-
k: v for k, v in record.__dict__.items()
397-
if not (k.startswith('_') or k in HTTPJSONHandler.LOG_ATTRS)
404+
k: v for k, v in record.__dict__.items() if _can_send(k)
398405
}
399406
if self._extras:
400407
json_record.update({
401-
k: v for k, v in self._extras.items()
402-
if not (k.startswith('_') or k in HTTPJSONHandler.LOG_ATTRS)
408+
k: v for k, v in self._extras.items() if _can_send(k)
403409
})
404410

405411
return _xfmt(json_record).encode('utf-8')

reframe/frontend/cli.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -600,7 +600,7 @@ def main():
600600
envvar='RFM_IGNORE_REQNODENOTAVAIL',
601601
configvar='schedulers/ignore_reqnodenotavail',
602602
action='store_true',
603-
help='Graylog server address'
603+
help='Ignore ReqNodeNotAvail Slurm error'
604604
)
605605
argparser.add_argument(
606606
dest='dump_pipeline_progress',

reframe/schemas/config.json

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -146,7 +146,11 @@
146146
{
147147
"properties": {
148148
"url": {"type": "string"},
149-
"extras": {"type": "object"}
149+
"extras": {"type": "object"},
150+
"ignore_keys": {
151+
"type": "array",
152+
"items": {"type": "string"}
153+
}
150154
},
151155
"required": ["url"]
152156
}
@@ -251,12 +255,7 @@
251255
]
252256
},
253257
"launcher": {
254-
"type": "string",
255-
"enum": [
256-
"alps", "ibrun", "local", "mpirun",
257-
"mpiexec", "srun", "srunalloc", "ssh",
258-
"upcrun", "upcxx-run", "lrun", "lrun-gpu"
259-
]
258+
"type": "string"
260259
},
261260
"access": {
262261
"type": "array",
@@ -551,6 +550,7 @@
551550
"logging/handlers*/filelog_basedir": "./perflogs",
552551
"logging/handlers*/graylog_extras": {},
553552
"logging/handlers*/httpjson_extras": {},
553+
"logging/handlers*/httpjson_ignore_keys": [],
554554
"logging/handlers*/stream_name": "stdout",
555555
"logging/handlers*/syslog_socktype": "udp",
556556
"logging/handlers*/syslog_facility": "user",

0 commit comments

Comments
 (0)