From fec15c487014ed4a3e1f49c281a8048fb78c4200 Mon Sep 17 00:00:00 2001 From: Sergei Kliavinek Date: Thu, 9 Sep 2021 16:11:09 +0300 Subject: [PATCH] add redesigned cpmd tests --- cscs-checks/apps/cpmd/cpmd_check.py | 94 ++++++++-------- hpctestlib/apps/cpmd/nve.py | 102 ++++++++++++++++++ .../apps/cpmd/src/C_MT_BLYP | 0 .../apps/cpmd/src/H_MT_BLYP | 0 .../apps/cpmd/src/ana_c4h6.in | 0 5 files changed, 148 insertions(+), 48 deletions(-) create mode 100644 hpctestlib/apps/cpmd/nve.py rename {cscs-checks => hpctestlib}/apps/cpmd/src/C_MT_BLYP (100%) rename {cscs-checks => hpctestlib}/apps/cpmd/src/H_MT_BLYP (100%) rename {cscs-checks => hpctestlib}/apps/cpmd/src/ana_c4h6.in (100%) diff --git a/cscs-checks/apps/cpmd/cpmd_check.py b/cscs-checks/apps/cpmd/cpmd_check.py index 32434202fd..03257aed54 100644 --- a/cscs-checks/apps/cpmd/cpmd_check.py +++ b/cscs-checks/apps/cpmd/cpmd_check.py @@ -5,60 +5,58 @@ import reframe as rfm import reframe.utility.sanity as sn +from hpctestlib.apps.cpmd.nve import Cpmd_NVE +REFERENCE_PERFORMANCE_SMALL = { + 'dom:mc': { + 'prod': (285.5, None, 0.20, 's') + }, + 'daint:mc': { + 'prod': (285.5, None, 0.20, 's') + }, +} -@rfm.parameterized_test(['small'], ['large']) -class CPMDCheck(rfm.RunOnlyRegressionTest): - def __init__(self, scale): - self.descr = 'CPMD check (C4H6 metadynamics)' - self.maintainers = ['AJ', 'LM'] - self.tags = {'production'} +REFERENCE_PERFORMANCE_LARGE = { + 'daint:mc': { + 'prod': (245.0, None, 0.59, 's') + }, +} - self.valid_systems = ['daint:gpu'] - if scale == 'small': +REFERENCE_PERFORMANCE = { + 'small': REFERENCE_PERFORMANCE_SMALL, + 'large': REFERENCE_PERFORMANCE_LARGE, +} + + +@rfm.simple_test +class cpmd_check(Cpmd_NVE): + scale = parameter(['small', 'large']) + mode = parameter(['prod']) + valid_systems = ['daint:gpu'] + modules = ['CPMD'] + valid_prog_environs = ['builtin'] + num_tasks_per_node = 1 + maintainers = ['AJ', 'LM'] + tags = {'production'} + use_multithreading = True + strict_check = False + descr = 'CPMD check (C4H6 metadynamics)' + extra_resources = { + 'switches': { + 'num_switches': 1 + } + } + + @run_after('init') + def set_num_tasks(self): + if self.scale == 'small': self.num_tasks = 9 self.valid_systems += ['dom:gpu'] else: self.num_tasks = 16 - - self.num_tasks_per_node = 1 - self.valid_prog_environs = ['builtin'] - self.modules = ['CPMD'] - self.executable = 'cpmd.x' - self.executable_opts = ['ana_c4h6.in > stdout.txt'] - self.readonly_files = ['ana_c4h6.in', 'C_MT_BLYP', 'H_MT_BLYP'] - self.use_multithreading = True - self.strict_check = False - self.extra_resources = { - 'switches': { - 'num_switches': 1 - } - } - # OpenMP version of CPMD segfaults # self.variables = { 'OMP_NUM_THREADS' : '8' } - energy = sn.extractsingle( - r'CLASSICAL ENERGY\s+-(?P\S+)', - 'stdout.txt', 'result', float) - energy_reference = 25.81 - energy_diff = sn.abs(energy - energy_reference) - self.sanity_patterns = sn.assert_lt(energy_diff, 0.26) - self.perf_patterns = { - 'time': sn.extractsingle(r'^ cpmd(\s+[\d\.]+){3}\s+(?P\S+)', - 'stdout.txt', 'perf', float) - } - if scale == 'small': - self.reference = { - 'daint:gpu': { - 'time': (285.5, None, 0.20, 's') - }, - 'dom:gpu': { - 'time': (332.0, None, 0.15, 's') - } - } - else: - self.reference = { - 'daint:gpu': { - 'time': (245.0, None, 0.59, 's') - } - } + + @run_after('setup') + def set_reference(self): + self.reference = REFERENCE_PERFORMANCE[self.scale] diff --git a/hpctestlib/apps/cpmd/nve.py b/hpctestlib/apps/cpmd/nve.py new file mode 100644 index 0000000000..27ba856f6c --- /dev/null +++ b/hpctestlib/apps/cpmd/nve.py @@ -0,0 +1,102 @@ +# Copyright 2016-2021 Swiss National Supercomputing Centre (CSCS/ETH Zurich) +# ReFrame Project Developers. See the top-level LICENSE file for details. +# +# SPDX-License-Identifier: BSD-3-Clause + +import reframe as rfm +import reframe.utility.sanity as sn +import reframe.utility.typecheck as typ + + +class Cpmd_NVE(rfm.RunOnlyRegressionTest, pin_prefix=True): + '''Base class for the CPMD NVE Test. + + The CPMD code is a plane wave/pseudopotential implementation + of Density Functional Theory, particularly designed + for ab-initio molecular dynamics. Its first version was + developed by Jürg Hutter at IBM Zurich Research + Laboratory starting from the original Car-Parrinello + codes. + + The presented abstract run-only class checks the perfomance of CPMD. + To do this, it is necessary to define in tests the name + of executable file (executable), the running script + (input file), the output file, as well as set the reference + values of energy and possible deviations from this value. + This data is used to check if the task is being executed + correctly, that is, the final energy is correct + (approximately the reference). The default assumption is that + CPMD is already installed on the device under test. + ''' + + #: CPMD input file. This file is set by the post-init hook + #: :func:`set_executable_opts`. + #: + #: :default: :class:`required` + input_file = variable(str) + + #: CPMD output file. This file is set by the post-init hook + #: :func:`set_executable_opts`. + #: + #: :default: : 'stdout.txt' + output_file = variable(str, value='stdout.txt') + + #: Reference value of energy, that is used for the comparison + #: with the execution ouput on the sanity step. The absolute + #: difference between final energy value and reference value + #: should be smaller than energy_tolerance + #: + #: :type: float + #: :default: :class:`required` + energy_value = variable(float) + + #: Maximum deviation from the reference value of energy, + #: that is acceptable. + #: + #: :type: float + #: :default: :class:`required` + energy_tolerance = variable(float) + + #: :default: :class:`required` + num_tasks_per_node = required + + #: :default: :class:`required` + executable = required + + executable = 'cpmd.x' + input_file = 'ana_c4h6.in' + energy_value = 25.81 + energy_tolerance = 0.26 + readonly_files = ['ana_c4h6.in', 'C_MT_BLYP', 'H_MT_BLYP'] + + @performance_function('s', perf_key='time') + def set_perf_patterns(self): + return sn.extractsingle(r'^ cpmd(\s+[\d\.]+){3}\s+(?P\S+)', + 'stdout.txt', 'perf', float) + + @run_before('performance') + def set_the_performance_dict(self): + self.perf_variables = {self.mode: + sn.make_performance_function( + sn.extractsingle( + r'^ cpmd(\s+[\d\.]+){3}\s+(?P' + r'\S+)', 'stdout.txt', 'perf', + float), 's')} + + @run_after('setup') + def set_executable_opts(self): + '''Set the executable options for the CPMD. Determine the + using of input and ouput files. + ''' + self.executable_opts = [f'{self.input_file} > {self.output_file}'] + + @sanity_function + def set_sanity_patterns(self): + '''Assert the obtained energy meets the specified tolerances.''' + + energy = sn.extractsingle( + r'CLASSICAL ENERGY\s+-(?P\S+)', + 'stdout.txt', 'result', float) + energy_diff = sn.abs(energy - self.energy_value) + ref_ener_diff = sn.abs(self.energy_tolerance) + return sn.assert_lt(energy_diff, ref_ener_diff) diff --git a/cscs-checks/apps/cpmd/src/C_MT_BLYP b/hpctestlib/apps/cpmd/src/C_MT_BLYP similarity index 100% rename from cscs-checks/apps/cpmd/src/C_MT_BLYP rename to hpctestlib/apps/cpmd/src/C_MT_BLYP diff --git a/cscs-checks/apps/cpmd/src/H_MT_BLYP b/hpctestlib/apps/cpmd/src/H_MT_BLYP similarity index 100% rename from cscs-checks/apps/cpmd/src/H_MT_BLYP rename to hpctestlib/apps/cpmd/src/H_MT_BLYP diff --git a/cscs-checks/apps/cpmd/src/ana_c4h6.in b/hpctestlib/apps/cpmd/src/ana_c4h6.in similarity index 100% rename from cscs-checks/apps/cpmd/src/ana_c4h6.in rename to hpctestlib/apps/cpmd/src/ana_c4h6.in