diff --git a/cscs-checks/apps/python/numpy_check.py b/cscs-checks/apps/python/numpy_check.py index 260d5f4f51..31abb53272 100644 --- a/cscs-checks/apps/python/numpy_check.py +++ b/cscs-checks/apps/python/numpy_check.py @@ -4,87 +4,48 @@ # SPDX-License-Identifier: BSD-3-Clause import reframe as rfm -import reframe.utility.sanity as sn - -class NumpyBaseTest(rfm.RunOnlyRegressionTest): - def __init__(self): - self.descr = 'Test a few typical numpy operations' - self.valid_prog_environs = ['builtin'] - self.modules = ['numpy'] - self.reference = { - 'daint:gpu': { - 'dot': (0.4, None, 0.05, 'seconds'), - 'svd': (0.37, None, 0.05, 'seconds'), - 'cholesky': (0.12, None, 0.05, 'seconds'), - 'eigendec': (3.5, None, 0.05, 'seconds'), - 'inv': (0.21, None, 0.05, 'seconds'), - }, - 'daint:mc': { - 'dot': (0.3, None, 0.05, 'seconds'), - 'svd': (0.35, None, 0.05, 'seconds'), - 'cholesky': (0.1, None, 0.05, 'seconds'), - 'eigendec': (4.14, None, 0.05, 'seconds'), - 'inv': (0.16, None, 0.05, 'seconds'), - }, - 'dom:gpu': { - 'dot': (0.4, None, 0.05, 'seconds'), - 'svd': (0.37, None, 0.05, 'seconds'), - 'cholesky': (0.12, None, 0.05, 'seconds'), - 'eigendec': (3.5, None, 0.05, 'seconds'), - 'inv': (0.21, None, 0.05, 'seconds'), - }, - 'dom:mc': { - 'dot': (0.3, None, 0.05, 'seconds'), - 'svd': (0.35, None, 0.05, 'seconds'), - 'cholesky': (0.1, None, 0.05, 'seconds'), - 'eigendec': (4.14, None, 0.05, 'seconds'), - 'inv': (0.16, None, 0.05, 'seconds'), - }, - } - self.perf_patterns = { - 'dot': sn.extractsingle( - r'^Dotted two 4096x4096 matrices in\s+(?P\S+)\s+s', - self.stdout, 'dot', float), - 'svd': sn.extractsingle( - r'^SVD of a 2048x1024 matrix in\s+(?P\S+)\s+s', - self.stdout, 'svd', float), - 'cholesky': sn.extractsingle( - r'^Cholesky decomposition of a 2048x2048 matrix in' - r'\s+(?P\S+)\s+s', - self.stdout, 'cholesky', float), - 'eigendec': sn.extractsingle( - r'^Eigendecomposition of a 2048x2048 matrix in' - r'\s+(?P\S+)\s+s', - self.stdout, 'eigendec', float), - 'inv': sn.extractsingle( - r'^Inversion of a 2048x2048 matrix in\s+(?P\S+)\s+s', - self.stdout, 'inv', float) - } - self.sanity_patterns = sn.assert_found(r'Numpy version:\s+\S+', - self.stdout) - self.variables = { - 'OMP_NUM_THREADS': '$SLURM_CPUS_PER_TASK', - } - self.executable = 'python' - self.executable_opts = ['np_ops.py'] - self.num_tasks_per_node = 1 - self.use_multithreading = False - self.tags = {'production'} - self.maintainers = ['RS', 'TR'] +from hpctestlib.python.numpy.numpy_ops import numpy_ops_check @rfm.simple_test -class NumpyHaswellTest(NumpyBaseTest): - def __init__(self): - super().__init__() - self.valid_systems = ['daint:gpu', 'dom:gpu'] - self.num_cpus_per_task = 12 +class cscs_numpy_test(numpy_ops_check): + valid_prog_environs = ['builtin'] + valid_systems = ['daint:gpu', 'daint:mc', 'dom:gpu', 'dom:mc'] + modules = ['numpy'] + num_tasks_per_node = 1 + use_multithreading = False + all_ref = { + 'haswell@12c': { + 'dot': (0.4, None, 0.05, 's'), + 'svd': (0.37, None, 0.05, 's'), + 'cholesky': (0.12, None, 0.05, 's'), + 'eigendec': (3.5, None, 0.05, 's'), + 'inv': (0.21, None, 0.05, 's'), + }, + 'broadwell@36c': { + 'dot': (0.3, None, 0.05, 's'), + 'svd': (0.35, None, 0.05, 's'), + 'cholesky': (0.1, None, 0.05, 's'), + 'eigendec': (4.14, None, 0.05, 's'), + 'inv': (0.16, None, 0.05, 's'), + } + } + tags = {'production'} + maintainers = ['RS', 'TR'] + @run_after('setup') + def set_num_cpus_per_task(self): + self.num_cpus_per_task = self.current_partition.processor.num_cores + variables = { + 'OMP_NUM_THREADS': self.num_cpus_per_task + } -@rfm.simple_test -class NumpyBroadwellTest(NumpyBaseTest): - def __init__(self): - super().__init__() - self.valid_systems = ['daint:mc', 'dom:mc'] - self.num_cpus_per_task = 36 + @run_before('performance') + def set_perf_ref(self): + arch = self.current_partition.processor.arch + pname = self.current_partition.fullname + num_cores = self.current_partition.processor.num_cores + self.reference = { + pname: self.all_ref[f'{arch}@{num_cores}c'] + } diff --git a/hpctestlib/python/numpy/numpy_ops.py b/hpctestlib/python/numpy/numpy_ops.py new file mode 100644 index 0000000000..5e438b9017 --- /dev/null +++ b/hpctestlib/python/numpy/numpy_ops.py @@ -0,0 +1,78 @@ +# 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 + + +@rfm.simple_test +class numpy_ops_check(rfm.RunOnlyRegressionTest, pin_prefix=True): + '''NumPy basic operations test. + + `NumPy `__ is the fundamental package for scientific + computing in Python. + It provides a multidimensional array object, various derived objects + (such as masked arrays and matrices), and an assortment of routines + for fast operations on arrays, including mathematical, logical, shape + manipulation, sorting, selecting, I/O, discrete Fourier transforms, + basic linear algebra, basic statistical operations, random simulation + and much more. + + This test test performs some fundamental NumPy linear algebra operations + (matrix product, SVD, Cholesky decomposition, eigendecomposition, and + inverse matrix calculation) and users the execution time as a performance + metric. The default assumption is that NumPy is already installed on the + currest system. + ''' + + executable = 'python' + executable_opts = ['np_ops.py'] + descr = 'Test NumPy operations: dot, svd, cholesky, eigen and inv' + + @performance_function('s', perf_key='dot') + def time_dot(self): + '''Time of the ``dot`` kernel in seconds.''' + + return sn.extractsingle( + r'^Dotted two 4096x4096 matrices in\s+(?P\S+)\s+s', + self.stdout, 'dot', float) + + @performance_function('s', perf_key='svd') + def time_svd(self): + '''Time of the ``svd`` kernel in seconds.''' + + return sn.extractsingle( + r'^SVD of a 2048x1024 matrix in\s+(?P\S+)\s+s', + self.stdout, 'svd', float) + + @performance_function('s', perf_key='cholesky') + def time_cholesky(self): + '''Time of the ``cholesky`` kernel in seconds.''' + + return sn.extractsingle( + r'^Cholesky decomposition of a 2048x2048 matrix in' + r'\s+(?P\S+)\s+s', + self.stdout, 'cholesky', float) + + @performance_function('s', perf_key='eigendec') + def time_eigendec(self): + '''Time of the ``eigendec`` kernel in seconds.''' + + return sn.extractsingle( + r'^Eigendecomposition of a 2048x2048 matrix in' + r'\s+(?P\S+)\s+s', + self.stdout, 'eigendec', float) + + @performance_function('s', perf_key='inv') + def time_inv(self): + '''Time of the ``inv`` kernel in seconds.''' + + return sn.extractsingle( + r'^Inversion of a 2048x2048 matrix in\s+(?P\S+)\s+s', + self.stdout, 'inv', float) + + @sanity_function + def assert_numpy_version(self): + return sn.assert_found(r'Numpy version:\s+\S+', self.stdout) diff --git a/cscs-checks/apps/python/src/np_ops.py b/hpctestlib/python/numpy/src/np_ops.py similarity index 100% rename from cscs-checks/apps/python/src/np_ops.py rename to hpctestlib/python/numpy/src/np_ops.py