Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
117 changes: 39 additions & 78 deletions cscs-checks/apps/python/numpy_check.py
Original file line number Diff line number Diff line change
Expand Up @@ -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<dot>\S+)\s+s',
self.stdout, 'dot', float),
'svd': sn.extractsingle(
r'^SVD of a 2048x1024 matrix in\s+(?P<svd>\S+)\s+s',
self.stdout, 'svd', float),
'cholesky': sn.extractsingle(
r'^Cholesky decomposition of a 2048x2048 matrix in'
r'\s+(?P<cholesky>\S+)\s+s',
self.stdout, 'cholesky', float),
'eigendec': sn.extractsingle(
r'^Eigendecomposition of a 2048x2048 matrix in'
r'\s+(?P<eigendec>\S+)\s+s',
self.stdout, 'eigendec', float),
'inv': sn.extractsingle(
r'^Inversion of a 2048x2048 matrix in\s+(?P<inv>\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']
}
78 changes: 78 additions & 0 deletions hpctestlib/python/numpy/numpy_ops.py
Original file line number Diff line number Diff line change
@@ -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 <https://numpy.org/>`__ 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<dot>\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<svd>\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<cholesky>\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<eigendec>\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<inv>\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)