Skip to content

Commit 0c06675

Browse files
authored
Merge branch 'master' into enhancement/assert_reference_restriction
2 parents 2c4484e + 3a8f945 commit 0c06675

File tree

9 files changed

+272
-65
lines changed

9 files changed

+272
-65
lines changed

Jenkinsfile

Lines changed: 1 addition & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -83,29 +83,14 @@ stage('Unittest') {
8383
echo \$SCRATCH""").trim()
8484
def reframeDir = "${scratch}/${dirPrefix}-${machineName}-${uniqueID}"
8585
def moduleDefinition = ''
86-
def gitClone = ''
8786
if (machineName == 'leone') {
8887
moduleDefinition = '''module() { eval `/usr/bin/modulecmd bash $*`; }
8988
export -f module'''
90-
gitClone = """module use /apps/common/UES/RHAT6/easybuild/modules/all/
91-
module load git
92-
git init .
93-
git fetch --tags --quiet https://github.com/eth-cscs/reframe.git +refs/heads/*:refs/remotes/origin/*
94-
git config remote.origin.url https://github.com/eth-cscs/reframe.git
95-
git config --add remote.origin.fetch +refs/heads/*:refs/remotes/origin/*
96-
git config remote.origin.url https://github.com/eth-cscs/reframe.git
97-
git fetch --tags --quiet https://github.com/eth-cscs/reframe.git +refs/pull/*:refs/remotes/origin/pr/* +refs/heads/master:refs/remotes/origin/master
98-
git rev-parse ${env.ghprbActualCommit}^{commit}
99-
git config core.sparsecheckout
100-
git checkout -f ${env.ghprbActualCommit}"""
10189
}
10290
dir(reframeDir) {
103-
if (machineName != 'leone') {
104-
checkout scm
105-
}
91+
checkout scm
10692
sh("""${loginBash}
10793
${moduleDefinition}
108-
${gitClone}
10994
ln -sf ../${cscsSettings} reframe/settings.py
11095
bash ${reframeDir}/${bashScript} -f ${reframeDir} -i ''""")
11196
}

cscs-checks/apps/espresso/espresso_check.py

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,9 +15,11 @@ def __init__(self, variant, **kwargs):
1515
'Espresso')
1616
self.executable = 'pw.x'
1717
self.executable_opts = '-in ausurf.in'.split()
18-
19-
self.sanity_patterns = sn.assert_found(
20-
r'convergence has been achieved', self.stdout)
18+
energy = sn.extractsingle(r'!\s+total energy\s+=\s+(?P<energy>\S+) Ry',
19+
self.stdout, 'energy', float)
20+
self.sanity_patterns = sn.all([
21+
sn.assert_found(r'convergence has been achieved', self.stdout),
22+
sn.assert_reference(energy, -11427.08612278, -1e-10, 1e-10)])
2123
self.perf_patterns = {
2224
'sec': sn.extractsingle(r'electrons :\s+(?P<sec>\S+)s CPU ',
2325
self.stdout, 'sec', float)

docs/running.rst

Lines changed: 119 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -412,30 +412,37 @@ By default, the output in ``reframe.log`` looks like the following:
412412

413413
.. code-block:: none
414414
415-
[2017-10-24T21:19:04] info: reframe: [----------] started processing example7_check (Matrix-vector mult
416-
iplication example with Cuda)
417-
[2017-10-24T21:19:04] info: reframe: [ SKIP ] skipping daint:mc
418-
[2017-10-24T21:19:04] info: reframe: [ RUN ] example7_check on daint:gpu using PrgEnv-cray
419-
[2017-10-24T21:19:04] debug: example7_check: setting up the environment
420-
[2017-10-24T21:19:04] debug: example7_check: loading environment for partition daint:gpu
421-
[2017-10-24T21:19:05] debug: example7_check: loading environment PrgEnv-cray
422-
[2017-10-24T21:19:05] debug: example7_check: setting up paths
423-
[2017-10-24T21:19:05] debug: example7_check: setting up the job descriptor
424-
[2017-10-24T21:19:05] debug: example7_check: job scheduler backend: nativeslurm
425-
[2017-10-24T21:19:05] debug: example7_check: setting up performance logging
426-
[2017-10-24T21:19:05] debug: example7_check: compilation started
427-
[2017-10-24T21:19:06] debug: example7_check: compilation stdout:
428-
429-
[2017-10-24T21:19:06] debug: example7_check: compilation stderr:
430-
nvcc warning : The 'compute_20', 'sm_20', and 'sm_21' architectures are deprecated, and may be removed
431-
in a future release (Use -Wno-deprecated-gpu-targets to suppress warning).
432-
433-
[2017-10-24T21:19:06] debug: example7_check: compilation finished
434-
[2017-10-24T21:19:09] debug: example7_check: spawned job (jobid=4163846)
435-
[2017-10-24T21:19:21] debug: example7_check: spawned job finished
436-
[2017-10-24T21:19:21] debug: example7_check: copying interesting files to output directory
437-
[2017-10-24T21:19:21] debug: example7_check: removing stage directory
438-
[2017-10-24T21:19:21] info: reframe: [ OK ] example7_check on daint:gpu using PrgEnv-cray
415+
[2018-03-01T20:03:13] info: reframe: [ RUN ] example7_check on daint:gpu using PrgEnv-cray
416+
[2018-03-01T20:03:13] debug: example7_check: entering stage: setup
417+
[2018-03-01T20:03:13] debug: example7_check on daint:gpu using PrgEnv-cray: loading environment for the current partition
418+
[2018-03-01T20:03:13] debug: example7_check on daint:gpu using PrgEnv-cray: executing OS command: modulecmd python show daint-gpu
419+
[2018-03-01T20:03:13] debug: example7_check on daint:gpu using PrgEnv-cray: executing OS command: modulecmd python load daint-gpu
420+
[2018-03-01T20:03:13] debug: example7_check on daint:gpu using PrgEnv-cray: loading test's environment
421+
[2018-03-01T20:03:13] debug: example7_check on daint:gpu using PrgEnv-cray: executing OS command: modulecmd python show cudatoolkit
422+
[2018-03-01T20:03:13] debug: example7_check on daint:gpu using PrgEnv-cray: executing OS command: modulecmd python load cudatoolkit
423+
[2018-03-01T20:03:13] debug: example7_check on daint:gpu using PrgEnv-cray: setting up paths
424+
[2018-03-01T20:03:13] debug: example7_check on daint:gpu using PrgEnv-cray: setting up the job descriptor
425+
[2018-03-01T20:03:13] debug: example7_check on daint:gpu using PrgEnv-cray: job scheduler backend: local
426+
[2018-03-01T20:03:13] debug: example7_check on daint:gpu using PrgEnv-cray: setting up performance logging
427+
[2018-03-01T20:03:13] debug: example7_check on daint:gpu using PrgEnv-cray: entering stage: compile
428+
[2018-03-01T20:03:13] debug: example7_check on daint:gpu using PrgEnv-cray: copying /users/karakasv/Devel/reframe/tutorial/src to stage directory (/users/karakasv/Devel/reframe/stage/gpu/example7_check/PrgEnv
429+
-cray)
430+
[2018-03-01T20:03:13] debug: example7_check on daint:gpu using PrgEnv-cray: symlinking files: []
431+
[2018-03-01T20:03:13] debug: example7_check on daint:gpu using PrgEnv-cray: Staged sourcepath: /users/karakasv/Devel/reframe/stage/gpu/example7_check/PrgEnv-cray/example_matrix_vector_multiplication_cuda.cu
432+
[2018-03-01T20:03:13] debug: example7_check on daint:gpu using PrgEnv-cray: executing OS command: nvcc -O3 -I/users/karakasv/Devel/reframe/stage/gpu/example7_check/PrgEnv-cray /users/karakasv/Devel/reframe/s
433+
tage/gpu/example7_check/PrgEnv-cray/example_matrix_vector_multiplication_cuda.cu -o /users/karakasv/Devel/reframe/stage/gpu/example7_check/PrgEnv-cray/./example7_check
434+
[2018-03-01T20:03:14] debug: example7_check on daint:gpu using PrgEnv-cray: compilation stdout:
435+
436+
[2018-03-01T20:03:14] debug: example7_check on daint:gpu using PrgEnv-cray: compilation stderr:
437+
nvcc warning : The 'compute_20', 'sm_20', and 'sm_21' architectures are deprecated, and may be removed in a future release (Use -Wno-deprecated-gpu-targets to suppress warning).
438+
439+
[2018-03-01T20:03:14] debug: example7_check on daint:gpu using PrgEnv-cray: compilation finished
440+
[2018-03-01T20:03:14] debug: example7_check on daint:gpu using PrgEnv-cray: entering stage: run
441+
[2018-03-01T20:03:14] debug: example7_check on daint:gpu using PrgEnv-cray: executing OS command: sbatch /users/karakasv/Devel/reframe/stage/gpu/example7_check/PrgEnv-cray/example7_check_daint_gpu_PrgEnv-cray
442+
.sh
443+
[2018-03-01T20:03:14] debug: example7_check on daint:gpu using PrgEnv-cray: spawned job (jobid=6224537)
444+
[2018-03-01T20:03:14] debug: example7_check on daint:gpu using PrgEnv-cray: entering stage: wait
445+
439446
440447
Each line starts with a timestamp, the level of the message (``info``, ``debug`` etc.), the context in which the framework is currently executing (either ``reframe`` or the name of the current test and, finally, the actual message.
441448

@@ -459,7 +466,7 @@ The default configuration looks as follows:
459466
'reframe.log' : {
460467
'level' : 'DEBUG',
461468
'format' : '[%(asctime)s] %(levelname)s: '
462-
'%(testcase_name)s: %(message)s',
469+
'%(check_info)s: %(message)s',
463470
'append' : False,
464471
},
465472
@@ -500,9 +507,9 @@ The configurable properties of a log record handler are the following:
500507
If ReFrame is not in the context of regression test, ``reframe`` will be printed.
501508
* ``check_jobid``: Prints the job or process id of the job or process associated with currently executing regression test.
502509
If a job or process is not yet created, ``-1`` will be printed.
503-
* ``testcase_name``: Print the name of the test case that is currently executing.
504-
Test case is essentially a tuple consisting of the test name, the current system and partition and the current programming environment.
505-
This format string prints out like ``<test-name>@<partition> using <environ>``.
510+
* ``check_info``: Print live information of the currently executing check.
511+
By default this field has the form ``<check_name> on <current_partition> using <current_environment>``.
512+
It can be configured on a per test basis by overriding the :func:`info <reframe.core.pipeline.RegressionTest.info>` method in your regression test.
506513

507514
* ``datefmt`` (default: ``'%FT%T'``) The format that will be used for outputting timestamps (i.e., the ``%(asctime)s`` field).
508515
Acceptable formats must conform to standard library's `time.strftime() <https://docs.python.org/3.6/library/time.html#time.strftime>`__ function.
@@ -513,21 +520,26 @@ The configurable properties of a log record handler are the following:
513520
If set for a ``filename.log`` handler entry, the resulting log file name will be ``filename_<timestamp>.log``.
514521
This property is ignored for the standard output/error handlers.
515522

523+
.. note::
524+
.. versionchanged:: 2.10
525+
The ``testcase_name`` logging attribute was replaced with the ``check_info``, which is now also configurable
526+
527+
516528
Performance Logging
517529
^^^^^^^^^^^^^^^^^^^
518530

519531
ReFrame supports additional logging for performance tests specifically, in order to record historical performance data.
520532
For each performance test, a log file of the form ``<test-name>.log`` is created under the ReFrame's `log directory <#configuring-reframe-directories>`__ where the test's performance is recorded.
521-
The default format used for this file is ``'[%(asctime)s] %(testcase_name)s (jobid=%(check_jobid)s): %(message)s'`` and ReFrame always appends to this file.
533+
The default format used for this file is ``'[%(asctime)s] %(check_info)s (jobid=%(check_jobid)s): %(message)s'`` and ReFrame always appends to this file.
522534
Currently, it is not possible for users to configure performance logging.
523535

524536
The resulting log file looks like the following:
525537

526538
.. code-block:: none
527539
528-
[2017-12-01T15:31:20] example7_check@daint:gpu using PrgEnv-cray (jobid=649790): value: 47.797996, reference: (50.0, -0.1, 0.1)
529-
[2017-12-01T15:31:24] example7_check@daint:gpu using PrgEnv-gnu (jobid=649791): value: 49.048228, reference: (50.0, -0.1, 0.1)
530-
[2017-12-01T15:31:24] example7_check@daint:gpu using PrgEnv-pgi (jobid=649792): value: 48.575334, reference: (50.0, -0.1, 0.1)
540+
[2018-03-01T20:01:20] reframe 2.10: example7_check on daint:gpu using PrgEnv-pgi (jobid=6224525): value: 49.637615, reference: (50.0, -0.1, 0.1)
541+
[2018-03-01T20:01:20] reframe 2.10: example7_check on daint:gpu using PrgEnv-cray (jobid=6224523): value: 49.931819, reference: (50.0, -0.1, 0.1)
542+
[2018-03-01T20:01:21] reframe 2.10: example7_check on daint:gpu using PrgEnv-gnu (jobid=6224524): value: 49.428855, reference: (50.0, -0.1, 0.1)
531543
532544
The interpretation of the performance values depends on the individual tests.
533545
The above output is from the CUDA performance test we presented in the `tutorial <tutorial.html#writing-a-performance-test>`__, so the value refers to the achieved Gflop/s.
@@ -617,3 +629,78 @@ Here is an example output of ReFrame using asynchronous execution policy:
617629
618630
The asynchronous execution policy may provide significant overall performance benefits for run-only regression tests.
619631
For compile-only and normal tests that require a compilation, the execution time will be bound by the total compilation time of the test.
632+
633+
634+
Manipulating modules
635+
--------------------
636+
637+
.. versionadded:: 2.11
638+
639+
ReFrame allows you to change the modules loaded by a regression test on-the-fly without having to edit the regression test file.
640+
This feature is extremely useful when you need to quickly test a newer version of a module, but it also allows you to completely decouple the module names used in your regression tests from the real module names in a system, thus making your test even more portable.
641+
This is achieved by defining *module mappings*.
642+
643+
There are two ways to pass module mappings to ReFrame.
644+
The first is to use the ``--map-module`` command-line option, which accepts a module mapping.
645+
For example, the following line maps the module ``test_module`` to the module ``real_module``:
646+
647+
.. code-block:: none
648+
649+
--map-module='test_module: real_module'
650+
651+
In this case, whenever ReFrame is asked to load ``test_module``, it will load ``real_module``.
652+
Any string without spaces may be accepted in place of ``test_module`` and ``real_module``.
653+
You can also define multiple module mappings at once by repeating the ``--map-module``.
654+
If more than one mapping is specified for the same module, then the last mapping will take precedence.
655+
It is also possible to map a single module to more than one target.
656+
This can be done by listing the target modules separated by spaces in the order that they should be loaded.
657+
In the following example, ReFrame will load ``real_module0`` and ``real_module1`` whenever the ``test_module`` is encountered:
658+
659+
.. code-block:: none
660+
661+
--map-module 'test_module: real_module0 real_module1'
662+
663+
The second way of defining mappings is by listing them on a file, which you can then pass to ReFrame through the command-line option ``--module-mappings``.
664+
Each line on the file corresponds to the definition of a mapping for a single module.
665+
The syntax of the individual mappings in the file is the same as with the option ``--map-module`` and the same rules apply regarding repeated definitions.
666+
Text starting with ``#`` is considered a comment and is ignored until the end of line is encountered.
667+
Empty lines are ignored.
668+
The following block shows an example of module mapping file:
669+
670+
.. code-block:: none
671+
672+
module-1: module-1a # an inline comment
673+
module-2: module-2a module-2b module-2c
674+
675+
# This is a full line comment
676+
module-4: module-4a module-4b
677+
678+
If both ``--map-module`` and ``--module-mappings`` are passed, ReFrame will first create a mapping from the definitions on the file and it will then process the definitions passed with the ``--map-module`` options.
679+
As usual, later definitions will override the former.
680+
681+
A final note on module mappings.
682+
Module mappings can be arbitrarily deep as long as they do not form a cycle.
683+
In this case, ReFrame will issue an error (denoting the offending cyclic dependency).
684+
For example, suppose having the following mapping file:
685+
686+
.. code-block:: none
687+
688+
cudatoolkit: foo
689+
foo: bar
690+
bar: foobar
691+
foobar: cudatoolkit
692+
693+
If you now try to run a test that loads the module `cudatoolkit`, the following error will be yielded:
694+
695+
.. code-block:: none
696+
697+
------------------------------------------------------------------------------
698+
FAILURE INFO for example7_check
699+
* System partition: daint:gpu
700+
* Environment: PrgEnv-gnu
701+
* Stage directory: None
702+
* Job type: batch job (id=-1)
703+
* Maintainers: ['you-can-type-your-email-here']
704+
* Failing phase: setup
705+
* Reason: caught framework exception: module cyclic dependency: cudatoolkit->foo->bar->foobar->cudatoolkit
706+
------------------------------------------------------------------------------

reframe/__init__.py

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,7 @@
1-
#
2-
# Sanity checks and modules environment setup
3-
#
4-
51
import sys
62

73

8-
VERSION = '2.10'
4+
VERSION = '2.11'
95
_required_pyver = (3, 5, 0)
106

117
# Check python version

reframe/core/modules.py

Lines changed: 31 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
import abc
66
import os
77
import re
8+
from collections import OrderedDict
89

910
import reframe.core.fields as fields
1011
import reframe.utility.os as os_ext
@@ -203,6 +204,35 @@ def is_module_loaded(self, name):
203204
def _is_module_loaded(self, name):
204205
return self._backend.is_module_loaded(Module(name))
205206

207+
def load_mapping(self, mapping):
208+
"""Updates the internal module mapping with a single mapping"""
209+
key, *rest = mapping.split(':')
210+
if len(rest) != 1:
211+
raise ConfigError('invalid mapping syntax: %s' % mapping)
212+
213+
key = key.strip()
214+
values = rest[0].split()
215+
if not key:
216+
raise ConfigError('no key found in mapping: %s' % mapping)
217+
218+
if not values:
219+
raise ConfigError('no mapping defined for module: %s' % key)
220+
221+
self.module_map[key] = list(OrderedDict.fromkeys(values))
222+
223+
def load_mapping_from_file(self, filename):
224+
"""Update the internal module mapping from mappings in a file."""
225+
with open(filename) as fp:
226+
for lineno, line in enumerate(fp, start=1):
227+
line = line.strip().split('#')[0]
228+
if not line:
229+
continue
230+
231+
try:
232+
self.load_mapping(line)
233+
except ConfigError as e:
234+
raise ConfigError('%s:%s' % (filename, lineno)) from e
235+
206236
@property
207237
def name(self):
208238
"""Return the name of this module system."""
@@ -513,7 +543,7 @@ def init_modules_system(modules_kind=None):
513543
elif modules_kind == 'lmod':
514544
_modules_system = ModulesSystem(LModImpl())
515545
else:
516-
raise ConfigError('unknown module system')
546+
raise ConfigError('unknown module system: %s' % modules_kind)
517547

518548

519549
def get_modules_system():

reframe/core/pipeline.py

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -636,10 +636,21 @@ def info(self):
636636
637637
This method is used by the front-end to print the status message during
638638
the test's execution.
639+
This function is also called to provide the message for the
640+
``check_info`` `logging attribute <running.html#logging>`__.
641+
By default, it returns a message reporting the test name, the current
642+
partition and the current programming environment that the test is
643+
currently executing on.
644+
645+
:returns: a string with an informational message about this test
646+
647+
.. note ::
648+
When overriding this method, you should pay extra attention on how
649+
you use the :class:`RegressionTest`'s attributes, because this
650+
method may be called at any point of the test's lifetime.
651+
652+
.. versionadded:: 2.10
639653
640-
:returns: a string with an informational message containing the test
641-
name, the current partition and the current programming environment
642-
that the test is currently executing on.
643654
"""
644655
ret = self.name
645656
if self.current_partition:

0 commit comments

Comments
 (0)