Skip to content
Merged
Show file tree
Hide file tree
Changes from 39 commits
Commits
Show all changes
43 commits
Select commit Hold shift + click to select a range
c92b8b8
add BLAS test
Jun 18, 2025
a0c85d6
update Makefile to not include common.mk
Jun 18, 2025
7caae27
add MKL; add more tags
Jun 18, 2025
328741c
add 2023b
Jun 19, 2025
df66259
add test docstring
Jun 19, 2025
3ea8724
add BLIS tests
Jun 19, 2025
5a12683
simplify perf variables
Jun 19, 2025
c7dcd98
add more docstrings
Jun 19, 2025
869a747
typos in docstring
Jun 19, 2025
d2baddf
various improvements
Jun 19, 2025
5ffa89c
docstring
Jun 19, 2025
489ce3f
module_name(s) fixes
Jun 19, 2025
d172ee0
update variable name
Jun 19, 2025
581c552
add sanitycheck to ensure BLAS backend is found
Jun 19, 2025
d7d9c0b
Merge branch 'main' into blas
Jun 19, 2025
92585e1
add __init__.py files + minor style changes
Jun 27, 2025
cb44619
don't use predefined module lists
Jul 5, 2025
89a44b7
update docstring
Jul 5, 2025
8995cb2
various small code improvements
Jul 6, 2025
c34f1d9
refactor
Jul 6, 2025
97e096c
add type check for module_name
Jul 7, 2025
47a8540
Merge branch 'main' into blas
Jul 8, 2025
57c46f8
also load matching buildenv module (required for EESSI)
Aug 3, 2025
c6288bf
merge main
Aug 3, 2025
d4bc0b5
fix?
Aug 3, 2025
d14dbfc
minor order change
Aug 3, 2025
cc51207
don't fail, just skip
Aug 8, 2025
a803d02
use generic select_matching_modules function
Aug 16, 2025
92c9e09
remove unused import
Aug 16, 2025
9089a16
fix type hints
Aug 16, 2025
3bbd80e
prepend global vars with underscore
Aug 16, 2025
4c92d69
update get_blas_modules
Aug 18, 2025
d07ca75
update get_blas_modules again
Aug 18, 2025
a5b4e97
fix split_module function
Oct 4, 2025
c1df749
add index parameter to add_buildenv_module function
Oct 4, 2025
cf39ca1
set compact thread binding
Oct 4, 2025
e603086
reorder list of modules to have BLIS always last
Oct 4, 2025
56aeed7
merge main
Oct 4, 2025
feea17e
add thread binding variables to eessi_mixin
Oct 5, 2025
bb06255
fix hooks order in metalwalls test
Oct 21, 2025
8a948e4
use a single thread_binding variable
Oct 21, 2025
8c234f2
remove single-threaded tests
Oct 21, 2025
4618d49
remove old line
Oct 21, 2025
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
4 changes: 2 additions & 2 deletions eessi/testsuite/common_config.py
Original file line number Diff line number Diff line change
Expand Up @@ -100,8 +100,8 @@ def common_eessi_init(eessi_version=None):
if eessi_cvmfs_repo is None:
rflog.getlogger().warning(' '.join([
"Environment variable 'EESSI_CVMFS_REPO' is not defined.",
"If you do not intend to use the EESSI software stack, this is perfectly fine.",
"To use EESSI, initialize the EESSI environment before running the test suite.",
"If you plan to use the EESSI software stack,",
"make sure to initialize the EESSI environment before running the test suite.",
]))
return ''

Expand Down
1 change: 1 addition & 0 deletions eessi/testsuite/constants.py
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@ class _GPUVendors(NamedTuple):
'1_core': {'num_nodes': 1, 'num_cpus_per_node': 1, 'num_gpus_per_node': 1},
'2_cores': {'num_nodes': 1, 'num_cpus_per_node': 2, 'num_gpus_per_node': 1},
'4_cores': {'num_nodes': 1, 'num_cpus_per_node': 4, 'num_gpus_per_node': 1},
'8_cores': {'num_nodes': 1, 'num_cpus_per_node': 8, 'num_gpus_per_node': 1},
# renamed after v0.2.0 from 1_cpn_2_nodes to make more unique
'1cpn_2nodes': {'num_nodes': 2, 'num_cpus_per_node': 1, 'num_gpus_per_node': 1},
# renamed after v0.2.0 from 1_cpn_4_nodes to make more unique
Expand Down
27 changes: 20 additions & 7 deletions eessi/testsuite/eessi_mixin.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,17 +38,22 @@ class EESSI_Mixin(RegressionMixin):
- Init phase: time_limit, measure_memory_usage, bench_name_ci
"""

# Set defaults for these class variables, can be overwritten by child class if desired
# Defaults for ReFrame variables that can be overwritten on the cmd line
measure_memory_usage = variable(bool, value=False)
exact_memory = variable(bool, value=False)
user_executable_opts = variable(str, value='')
thread_binding = variable(str, value='None') # takes priority over compact_thread_binding
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I might be missing something, but why do we need both this and compact_thread_binding?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i was under the impression that you can't override the thread_binding variable in a test class, but that's actually not true. you can override it, but not in a base class.

fixed in 8a948e4


# Set defaults for these class variables, can be overwritten by child class if desired
scale = parameter(SCALES.keys())
bench_name = None
bench_name_ci = None
is_ci_test = False
num_tasks_per_compute_unit = 1
always_request_gpus = None
require_buildenv_module = False
require_internet = False
compact_thread_binding = False

# Create ReFrame variables for logging runtime environment information
cvmfs_repo_name = variable(str, value='None')
Expand Down Expand Up @@ -126,10 +131,17 @@ def EESSI_mixin_run_after_init(self):
# Filter on which scales are supported by the partitions defined in the ReFrame configuration
hooks.filter_supported_scales(self)

hooks.filter_valid_systems_by_device_type(self, required_device_type=self.device_type)

hooks.set_modules(self)

if self.require_buildenv_module:
hooks.add_buildenv_module(self)

thread_binding = self.thread_binding.lower()
if thread_binding == 'true' or (thread_binding == 'none' and self.compact_thread_binding):
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If thread_binding is a variable, what if it's not True or False, but someone set it to compact? Or made a type Ture?. I think we should catch all cases we know (true / compact => do compact binding, false => do nothing, anything else => do nothing and warn the user that an invalid value was set for thread_binding).

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i opted for a hard error in case an invalid value was set

fixed in 8a948e4

hooks.set_compact_thread_binding(self)

hooks.filter_valid_systems_by_device_type(self, required_device_type=self.device_type)

# Set scales as tags
hooks.set_tag_scale(self)

Expand Down Expand Up @@ -210,10 +222,11 @@ def EESSI_mixin_log_runtime_info(self):
path to the modulefile, EESSI software subdir, EESSI testsuite version"""
self.postrun_cmds.append('echo "EESSI_CVMFS_REPO: $EESSI_CVMFS_REPO"')
self.postrun_cmds.append('echo "EESSI_SOFTWARE_SUBDIR: $EESSI_SOFTWARE_SUBDIR"')
if self.module_name:
# Get full modulepath
get_full_modpath = f'echo "FULL_MODULEPATH: $(module --location show {self.module_name} 2>&1)"'
self.postrun_cmds.append(get_full_modpath)
if self.module_names:
for mod in self.module_names:
# Get full modulepath
get_full_modpath = f'echo "FULL_MODULEPATH: $(module --location show {mod} 2>&1)"'
self.postrun_cmds.append(get_full_modpath)

@run_before('run', always_last=True)
def EESSI_mixin_set_user_executable_opts(self):
Expand Down
92 changes: 83 additions & 9 deletions eessi/testsuite/hooks.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,12 @@

from eessi.testsuite.constants import (COMPUTE_UNITS, DEVICE_TYPES, EXTRAS, FEATURES,
GPU_VENDORS, INVALID_SYSTEM, SCALES)
from eessi.testsuite.utils import (get_max_avail_gpus_per_node, is_cuda_required_module, log,
check_proc_attribute_defined, check_extras_key_defined)
from eessi.testsuite.utils import (check_extras_key_defined, check_proc_attribute_defined, find_modules,
get_max_avail_gpus_per_node, is_cuda_required_module, log, split_module,
select_matching_modules)

# global variables
_buildenv_modules = []


def _assign_default_num_cpus_per_node(test: rfm.RegressionTest):
Expand Down Expand Up @@ -463,7 +467,7 @@ def filter_valid_systems_by_device_type(test: rfm.RegressionTest, required_devic
cause the valid_systems to be set to an empty string, and consequently the
test.valid_systems to an invalid system name (eessi.testsuite.constants.INVALID_SYSTEM).
"""
is_cuda_module = is_cuda_required_module(test.module_name)
is_cuda_module = is_cuda_required_module(test.module_names)

if is_cuda_module and required_device_type == DEVICE_TYPES.GPU:
# CUDA modules and when using a GPU require partitions with FEATURES.GPU feature and
Expand Down Expand Up @@ -613,14 +617,25 @@ def req_memory_per_node(test: rfm.RegressionTest, app_mem_req: float):

def set_modules(test: rfm.RegressionTest):
"""
Skip current test if module_name is not among a list of modules,
Set modules test parameter via module_name, which can be a string or a list of strings
Skip current test if any of the module names is not present in the list of modules,
specified with --setvar modules=<comma-separated-list>.
"""
if test.modules and test.module_name not in test.modules:
test.valid_systems = []
log(f'valid_systems set to {test.valid_systems}')

test.modules = [test.module_name]
if not test.module_name:
return
if isinstance(test.module_name, str):
test.module_names = [test.module_name]
elif isinstance(test.module_name, (list, tuple)):
test.module_names = test.module_name
else:
raise TypeError(f'module_name is a {type(test.module_name).__name__}, should be string, list, or tuple')
if test.modules:
for name in test.module_names:
if name not in test.modules:
test.valid_systems = []
log(f'module {name} not in {test.modules}, valid_systems set to {test.valid_systems}')

test.modules = test.module_names
log(f'modules set to {test.modules}')


Expand Down Expand Up @@ -765,3 +780,62 @@ def extract_memory_usage(self):
return hooks.extract_memory_usage(self)
"""
return sn.extractsingle(r'^MAX_MEM_IN_MIB=(?P<memory>\S+)', test.stdout, 'memory', int)


def add_buildenv_module(test: rfm.RegressionTest, index=-1):
"""
Add a buildenv module that matches the reference module to the list of modules


Arguments:
- test: ReFrame test to which this hook should apply
- index: module index in test.modules to take as the reference (default is last);
note that the reference module’s toolchain should not be at the system
level: otherwise only buildenv modules at the system level can be added

Requirements:
- recent enough easybuild python package
- a matching default buildenv module (e.g. buildenv/default-foss-2024a) available on the system
"""
for mod in test.modules:
if mod.split('/')[0] == 'buildenv':
# buildenv module already in the list
return

# get list of buildenv modules on the system
# make global to avoid calculating _buildenv_modules multiple times
global _buildenv_modules
if not _buildenv_modules:
_buildenv_modules = set(find_modules('buildenv'))
to_remove = []
for mod in _buildenv_modules:
mod_parts = split_module(mod)
if mod_parts[4] or mod_parts[1] != 'default':
# only consider default buildenv modules without versionsuffixes
to_remove.append(mod)

_buildenv_modules = [x for x in _buildenv_modules if x not in to_remove]

if not _buildenv_modules:
msg = 'No default buildenv modules without versionsuffixes found on the system.'
log(msg)
test.valid_systems = [INVALID_SYSTEM]
return

ref_module = test.modules[index]
matching_modules = select_matching_modules(list(_buildenv_modules), ref_module)

if not matching_modules:
msg = f'No matching buildenv module for {ref_module} found on the system.'
log(msg)
test.valid_systems = [INVALID_SYSTEM]
return

if len(matching_modules) > 1:
msg = f'Multiple matching buildenv modules found, will use the first one: {_buildenv_modules}.'
log(msg)

buildenv_mod = matching_modules[0]
# insert to keep the most important module last
test.modules.insert(0, buildenv_mod)
log(f'Module {buildenv_mod} added to list of modules')
2 changes: 2 additions & 0 deletions eessi/testsuite/tests/libs/blas/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
# WARNING: do not remove this file.
# It is needed to autogenerate documentation from this repo.
Loading