Skip to content

Commit 92252d8

Browse files
author
Theofilos Manitaras
committed
Modernize GREASY Tests
1 parent 152d697 commit 92252d8

File tree

1 file changed

+80
-66
lines changed

1 file changed

+80
-66
lines changed

cscs-checks/apps/greasy/greasy_check.py

Lines changed: 80 additions & 66 deletions
Original file line numberDiff line numberDiff line change
@@ -16,79 +16,70 @@ def to_seconds(str):
1616
datetime.strptime('00:00:00', '%H:%M:%S')).total_seconds()
1717

1818

19-
@rfm.parameterized_test(
20-
['serial', 'gpu', 24, 12, 1, 1],
21-
['serial', 'mc', 72, 36, 1, 1],
22-
['openmp', 'gpu', 24, 3, 1, 4],
23-
['openmp', 'mc', 72, 9, 1, 4],
24-
['mpi', 'gpu', 24, 4, 3, 1],
25-
['mpi', 'mc', 72, 12, 3, 1],
26-
['mpi+openmp', 'gpu', 24, 3, 2, 2],
27-
['mpi+openmp', 'mc', 72, 6, 3, 2]
28-
)
19+
@rfm.simple_test
2920
class GREASYCheck(rfm.RegressionTest):
30-
def __init__(self, variant, partition, num_greasy_tasks, nworkes_per_node,
31-
nranks_per_worker, ncpus_per_worker):
32-
self.valid_systems = ['daint:' + partition, 'dom:' + partition]
33-
34-
self.valid_prog_environs = ['PrgEnv-gnu']
35-
self.sourcepath = 'tasks_mpi_openmp.c'
36-
self.build_system = 'SingleSource'
37-
38-
# sleep enough time to distinguish if the files are running in parallel
39-
# or not
40-
self.sleep_time = 60
21+
configuration = parameter([('serial', 'gpu', 24, 12, 1, 1),
22+
('serial', 'mc', 72, 36, 1, 1),
23+
('openmp', 'gpu', 24, 3, 1, 4),
24+
('openmp', 'mc', 72, 9, 1, 4),
25+
('mpi', 'gpu', 24, 4, 3, 1),
26+
('mpi', 'mc', 72, 12, 3, 1),
27+
('mpi+openmp', 'gpu', 24, 3, 2, 2),
28+
('mpi+openmp', 'mc', 72, 6, 3, 2)])
29+
valid_prog_environs = ['PrgEnv-gnu']
30+
sourcepath = 'tasks_mpi_openmp.c'
31+
build_system = 'SingleSource'
32+
executable = 'tasks_mpi_openmp.x'
33+
tasks_file = 'tasks.txt'
34+
greasy_logfile = 'greasy.log'
35+
nnodes = 2
36+
37+
# sleep enough time to distinguish if the files are running in parallel
38+
# or not
39+
sleep_time = 60
40+
use_multithreading = False
41+
modules = ['GREASY']
42+
maintainers = ['VH', 'SK']
43+
tags = {'production'}
44+
45+
@run_after('init')
46+
def unpack_configuration_parameter(self):
47+
self.variant, self.partition = self.configuration[0:2]
48+
self.num_greasy_tasks, self.workers_per_node = self.configuration[2:4]
49+
self.ranks_per_worker, self.cpus_per_worker = self.configuration[4:6]
50+
51+
@run_after('init')
52+
def set_valid_systems(self):
53+
self.valid_systems = [f'daint:{self.partition}',
54+
f'dom:{self.partition}']
55+
56+
@run_before('compile')
57+
def setup_build_system(self):
4158
self.build_system.cflags = [f'-DSLEEP_TIME={self.sleep_time:d}']
42-
self.variant = variant
43-
if variant == 'openmp':
59+
if self.variant == 'openmp':
4460
self.build_system.cflags += ['-fopenmp']
45-
elif variant == 'mpi':
61+
elif self.variant == 'mpi':
4662
self.build_system.cflags += ['-D_MPI']
47-
elif variant == 'mpi+openmp':
63+
elif self.variant == 'mpi+openmp':
4864
self.build_system.cflags += ['-fopenmp', '-D_MPI']
4965

50-
self.executable = 'tasks_mpi_openmp.x'
51-
self.tasks_file = 'tasks.txt'
66+
@run_before('run')
67+
def setup_greasy_run(self):
5268
self.executable_opts = [self.tasks_file]
53-
self.greasy_logfile = 'greasy.log'
5469
self.keep_files = [self.tasks_file, self.greasy_logfile]
55-
nnodes = 2
56-
self.use_multithreading = False
57-
self.num_greasy_tasks = num_greasy_tasks
58-
self.nworkes_per_node = nworkes_per_node
59-
self.nranks_per_worker = nranks_per_worker
60-
self.num_tasks_per_node = nranks_per_worker * nworkes_per_node
61-
self.num_tasks = self.num_tasks_per_node * nnodes
62-
self.num_cpus_per_task = ncpus_per_worker
63-
self.sanity_patterns = self.eval_sanity()
70+
self.num_tasks_per_node = self.ranks_per_worker * self.workers_per_node
71+
self.num_tasks = self.num_tasks_per_node * self.nnodes
72+
self.num_cpus_per_task = self.cpus_per_worker
6473

65-
# Reference value is system agnostic
66-
# Adding 10 secs of slowdown per greasy tasks
67-
# this is to compensate for whenever the systems are full and srun gets
68-
# slightly slower
69-
refperf = (
70-
(self.sleep_time+10)*num_greasy_tasks / nworkes_per_node / nnodes
71-
)
72-
self.reference = {
73-
'*': {
74-
'time': (refperf, None, 0.5, 's')
75-
}
76-
}
77-
self.perf_patterns = {
78-
'time': sn.extractsingle(r'Total time: (?P<perf>\S+)',
79-
self.greasy_logfile,
80-
'perf', to_seconds)
81-
}
74+
@run_before('run')
75+
def set_variables(self):
8276
# On SLURM there is no need to set OMP_NUM_THREADS if one defines
8377
# num_cpus_per_task, but adding for completeness and portability
8478
self.variables = {
8579
'OMP_NUM_THREADS': str(self.num_cpus_per_task),
86-
'GREASY_NWORKERS_PER_NODE': str(nworkes_per_node),
80+
'GREASY_NWORKERS_PER_NODE': str(self.workers_per_node),
8781
'GREASY_LOGFILE': self.greasy_logfile
8882
}
89-
self.modules = ['GREASY']
90-
self.maintainers = ['VH', 'SK']
91-
self.tags = {'production'}
9283

9384
@run_before('run')
9485
def generate_tasks_file(self):
@@ -114,7 +105,7 @@ def daint_dom_gpu_specific_workaround(self):
114105
}
115106
}
116107
elif self.current_partition.fullname in ['daint:mc']:
117-
if self.variant != 'serial':
108+
if self.configuration.variant != 'serial':
118109
self.extra_resources = {
119110
'gres': {
120111
'gres': 'craynetwork:72'
@@ -133,17 +124,19 @@ def set_launcher(self):
133124
# make calls to srun
134125
self.job.launcher = getlauncher('local')()
135126

136-
@sn.sanity_function
137-
def eval_sanity(self):
127+
@sanity_function
128+
def assert_success(self):
138129
output_files = []
139130
output_files = [file for file in os.listdir(self.stagedir)
140131
if file.startswith('output-')]
141132
num_greasy_tasks = len(output_files)
142133
failure_msg = (f'Requested {self.num_greasy_tasks} task(s), but '
143134
f'executed only {num_greasy_tasks} tasks(s)')
144-
sn.evaluate(sn.assert_eq(num_greasy_tasks, self.num_greasy_tasks,
145-
msg=failure_msg))
146-
num_tasks = sn.getattr(self, 'nranks_per_worker')
135+
sn.evaluate(
136+
sn.assert_eq(num_greasy_tasks, self.num_greasy_tasks,
137+
msg=failure_msg)
138+
)
139+
num_tasks = sn.getattr(self, 'ranks_per_worker')
147140
num_cpus_per_task = sn.getattr(self, 'num_cpus_per_task')
148141

149142
def tid(match):
@@ -184,7 +177,7 @@ def num_ranks(match):
184177
lambda x: sn.assert_lt(
185178
rank(x), num_ranks(x),
186179
msg=(f'Rank id {rank(x)} is not lower than the '
187-
f'number of ranks {self.nranks_per_worker} '
180+
f'number of ranks {self.ranks_per_worker} '
188181
f'in output file')
189182
), result
190183
),
@@ -217,7 +210,7 @@ def num_ranks(match):
217210
lambda x: sn.assert_eq(
218211
num_ranks(x), num_tasks,
219212
msg=(f'Number of ranks {num_ranks(x)} is not '
220-
f'equal to {self.nranks_per_worker} in '
213+
f'equal to {self.ranks_per_worker} in '
221214
f'output file {output_file}')
222215
), result
223216
)
@@ -234,3 +227,24 @@ def num_ranks(match):
234227
))
235228

236229
return True
230+
231+
@run_before('performance')
232+
def set_perf_patterns(self):
233+
# Reference value is system agnostic
234+
# Adding 10 secs of slowdown per greasy tasks
235+
# this is to compensate for whenever the systems are full and srun gets
236+
# slightly slower
237+
refperf = (
238+
(self.sleep_time + 10) * self.num_greasy_tasks /
239+
self.workers_per_node / self.nnodes
240+
)
241+
self.reference = {
242+
'*': {
243+
'time': (refperf, None, 0.5, 's')
244+
}
245+
}
246+
self.perf_patterns = {
247+
'time': sn.extractsingle(r'Total time: (?P<perf>\S+)',
248+
self.greasy_logfile,
249+
'perf', to_seconds)
250+
}

0 commit comments

Comments
 (0)