Skip to content

Commit 8467774

Browse files
authored
Merge pull request #281 from satishskamath/openfoam_64M
OpenFOAM 64M test case [Ready for testing]
2 parents a2ab832 + 6d3d524 commit 8467774

File tree

1 file changed

+125
-0
lines changed

1 file changed

+125
-0
lines changed

eessi/testsuite/tests/apps/openfoam/openfoam.py

Lines changed: 125 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,17 @@
4141
from eessi.testsuite.utils import find_modules
4242

4343

44+
def filter_scales_64M():
45+
"""
46+
Filtering function for filtering scales for the OpenFOAM 64M mesh test
47+
returns all scales with at least half a node.
48+
"""
49+
return [
50+
k for (k, v) in SCALES.items()
51+
if (v['num_nodes'] >= 4) and (0 < v.get('node_part', 0) <= 2)
52+
]
53+
54+
4455
def filter_scales_8M():
4556
"""
4657
Filtering function for filtering scales for the OpenFOAM 8M mesh test
@@ -64,6 +75,120 @@ def filter_scales_1M():
6475
]
6576

6677

78+
@rfm.simple_test
79+
class EESSI_OPENFOAM_LID_DRIVEN_CAVITY_64M(rfm.RunOnlyRegressionTest, EESSI_Mixin):
80+
"""
81+
This is the main OPENFOAM class for the Lid-driven cavity test. The test consists of many steps which are run as
82+
pre-run commands and the main test with the executable `icoFoam` is measured for performance.
83+
"""
84+
# ldc_64M = fixture(EESSI_OPENFOAM_base, scope='partition')
85+
executable = 'icoFoam'
86+
executable_opts = ['-parallel', '2>&1', '|', 'tee log.icofoam']
87+
time_limit = '120m'
88+
readonly_files = ['']
89+
device_type = parameter([DEVICE_TYPES.CPU])
90+
module_name = parameter(find_modules('OpenFOAM/v', name_only=False))
91+
valid_systems = ['*']
92+
scale = parameter(filter_scales_64M())
93+
94+
@run_after('init')
95+
def set_compute_unit(self):
96+
"""
97+
Set the compute unit to which tasks will be assigned:
98+
one task per CPU core for CPU runs.
99+
"""
100+
if self.device_type == DEVICE_TYPES.CPU:
101+
self.compute_unit = COMPUTE_UNITS.CPU
102+
else:
103+
msg = f"No mapping of device type {self.device_type} to a COMPUTE_UNITS was specified in this test"
104+
raise NotImplementedError(msg)
105+
106+
def required_mem_per_node(self):
107+
return self.num_tasks_per_node * 1700
108+
109+
@run_after('setup')
110+
def check_launcher_options(self):
111+
# We had to get the launcher command and prepend this to the prerun steps (func prepare_environment) because:
112+
# 1. A typical OpenFOAM job would contain multiple mpirun steps working on the same stage directory.
113+
# 2. We had trouble using ReFrame fixtures to separate these over multiple jobs, because we couldn't get it to
114+
# work together with the mixin class.
115+
if (self.job.launcher.command(self.job)[0] == 'mpirun'):
116+
self.launcher_command = self.job.launcher.command(self.job)
117+
self.launcher_command[-1] = str(self.num_tasks_per_node * self.num_nodes)
118+
elif (self.job.launcher.command(self.job)[0] == 'srun'):
119+
self.launcher_command = self.job.launcher.command(self.job)
120+
else:
121+
self.skip(msg="The chosen launcher for this test is different from mpirun or srun which means that the"
122+
"test will definitely fail, therefore skipping this test.")
123+
124+
@run_after('setup')
125+
def check_minimum_cores(self):
126+
# The 64M test case requires minimally 512 cores to run within reasonable time.
127+
if self.num_tasks < 512:
128+
self.skip(msg="The minimum number of cores required by this test is 512. Launch on a scale with higher core"
129+
"count.")
130+
131+
@run_before('run')
132+
def prepare_environment(self):
133+
# fullpath = os.path.join(self.ldc_64M.stagedir, 'fixedTol')
134+
self.prerun_cmds = [
135+
'cd ./cavity3D/64M/fixedTol',
136+
'source $FOAM_BASH',
137+
f"foamDictionary -entry numberOfSubdomains -set {self.num_tasks_per_node * self.num_nodes} "
138+
"system/decomposeParDict",
139+
'blockMesh 2>&1 | tee log.blockMesh',
140+
f"{' '.join(self.launcher_command)} redistributePar -decompose -parallel 2>&1 | tee log.decompose",
141+
f"{' '.join(self.launcher_command)} renumberMesh -parallel -overwrite 2>&1 | tee log.renumberMesh"]
142+
143+
@deferrable
144+
def check_files(self):
145+
''' Check for all the log files present. '''
146+
return (sn.path_isfile("./cavity3D/64M/fixedTol/log.blockMesh")
147+
and sn.path_isfile("./cavity3D/64M/fixedTol/log.decompose")
148+
and sn.path_isfile("./cavity3D/64M/fixedTol/log.renumberMesh")
149+
and sn.path_isfile("./cavity3D/64M/fixedTol/log.icofoam"))
150+
151+
@deferrable
152+
def assert_completion(self):
153+
n_ranks = sn.count(sn.extractall(
154+
'^Processor (?P<rank>[0-9]+)', "./cavity3D/64M/fixedTol/log.decompose", tag='rank'))
155+
return (sn.assert_found("^Writing polyMesh with 0 cellZones", "./cavity3D/64M/fixedTol/log.blockMesh",
156+
msg="BlockMesh failure.")
157+
and sn.assert_found(r"\s+nCells: 64000000", "./cavity3D/64M/fixedTol/log.blockMesh",
158+
msg="BlockMesh failure.")
159+
and sn.assert_eq(n_ranks, self.num_tasks)
160+
and sn.assert_found(r"^Finalising parallel run", "./cavity3D/64M/fixedTol/log.renumberMesh",
161+
msg="Did not reach the end of the renumberMesh run. RenumberMesh failure.")
162+
and sn.assert_found(r"^Time = 0.00375", "./cavity3D/64M/fixedTol/log.icofoam",
163+
msg="Did not reach the last time step. IcoFoam failure.")
164+
and sn.assert_found(r"^Finalising parallel run", "./cavity3D/64M/fixedTol/log.icofoam",
165+
msg="Did not reach the end of the icofoam run. IcoFoam failure."))
166+
167+
@deferrable
168+
def assert_convergence(self):
169+
cumulative_cont_err = sn.extractall(r'cumulative = (?P<cont>\S+)', "./cavity3D/64M/fixedTol/log.icofoam",
170+
'cont', float)
171+
abs_cumulative_cont_err = sn.abs(cumulative_cont_err[-1])
172+
return sn.assert_le(abs_cumulative_cont_err, 1e-15,
173+
msg="The cumulative continuity errors are high. Try varying pressure solver.")
174+
175+
@performance_function('s/timestep')
176+
def perf(self):
177+
perftimes = sn.extractall(r'ClockTime = (?P<perf>\S+)', "./cavity3D/64M/fixedTol/log.icofoam", 'perf',
178+
float)
179+
seconds_per_timestep = perftimes[-1] / 15.0
180+
return seconds_per_timestep
181+
182+
@sanity_function
183+
def assert_sanity(self):
184+
'''Check all sanity criteria'''
185+
return sn.all([
186+
self.check_files(),
187+
self.assert_completion(),
188+
self.assert_convergence(),
189+
])
190+
191+
67192
@rfm.simple_test
68193
class EESSI_OPENFOAM_LID_DRIVEN_CAVITY_8M(rfm.RunOnlyRegressionTest, EESSI_Mixin):
69194
"""

0 commit comments

Comments
 (0)