1- # Copyright 2016-2024 Swiss National Supercomputing Centre (CSCS/ETH Zurich)
1+ # Copyright Swiss National Supercomputing Centre (CSCS/ETH Zurich)
22# ReFrame Project Developers. See the top-level LICENSE file for details.
33#
44# SPDX-License-Identifier: BSD-3-Clause
55
66import os
77import shutil
8+ from packaging .version import Version
9+ import re
810
911import reframe as rfm
1012import reframe .utility .sanity as sn
1315
1416cp2k_references = {
1517 'md' : {
16- 'gh200' : {'time_run' : (52 , None , 0.05 , 's' )},
18+ 'gh200' : {'time_run' : (69 , None , 0.05 , 's' )},
1719 'zen2' : {'time_run' : (91 , None , 0.05 , 's' )}
1820 },
1921 'pbe' : {
20- 'gh200' : {'time_run' : (44 , None , 0.05 , 's' )},
21- 'zen2' : {'time_run' : (53 , None , 0.05 , 's' )}
22+ 'gh200' : {'time_run' : (67 , None , 0.05 , 's' )},
23+ 'zen2' : {'time_run' : (68 , None , 0.05 , 's' )}
2224 },
2325 'rpa' : {
2426 'gh200' : {'time_run' : (575 , None , 0.05 , 's' )}
7173}
7274
7375
74- class cp2k_download (rfm .RunOnlyRegressionTest ):
75- '''
76- Download CP2K source code.
77- '''
76+ def version_from_uenv ():
77+ uenv_var = os .environ ['UENV' ]
78+ match = re .search (r'/(\d+\.\d+)' , uenv_var )
79+ if match : # Return version (YYYY.VV)
80+ return match .group (1 )
81+ else :
82+ return None
7883
84+ @rfm .xfail (
85+ 'CP2K 2025.1 issues with libxc linking.' ,
86+ lambda test : test .version == "2025.1"
87+ )
88+ class cp2k_download (rfm .RunOnlyRegressionTest ):
7989 version = variable (str , value = '' )
80- descr = 'Fetch CP2K source code'
90+ descr = 'Download CP2K source code'
8191 sourcesdir = None
8292 executable = 'wget'
83- local = True
93+ local = False
8494
8595 @run_before ('run' )
8696 def set_version (self ):
87- uenv_version = os .environ ['UENV' ].split ('/' )[1 ].split ('.' )[0 ]
88- uenv_src_d = {'2024' : 'v2024.3' , '2025' : 'v2025.1' }
89- self .version = uenv_src_d [uenv_version ] if self .version == '' else self .version
97+ try :
98+ uenv_version = self .current_environ .extras ['version' ][1 :]
99+ except (KeyError , AttributeError ):
100+ uenv_version = version_from_uenv ()
101+
102+ self .version = uenv_version if self .version == '' else self .version
90103
91104 url = 'https://jfrog.svc.cscs.ch/artifactory/cscs-reframe-tests'
92105
93106 self .executable_opts = [
94107 '--quiet' ,
95- f'{ url } /cp2k/{ self .version } .tar.gz'
108+ f'{ url } /cp2k/v { self .version } .tar.gz'
96109 ]
97110
98111 @sanity_function
99112 def validate_download (self ):
100- return sn .assert_eq (self .job .exitcode , 0 )
113+ # Manual compilation of v2025.1 with CMake is known to fail at link
114+ # time, because of issues with the libxc integration.
115+ return sn .and_ (sn .assert_eq (self .job .exitcode , 0 ),
116+ sn .assert_ne (self .version , '2025.1' ))
101117
102118
103119@rfm .simple_test
104120class Cp2kBuildTestUENV (rfm .CompileOnlyRegressionTest ):
105- '''
106- Test CP2K build from source.
107- '''
108-
109121 descr = 'CP2K Build Test'
110122 valid_prog_environs = ['+cp2k-dev -dlaf' ]
111123 valid_systems = ['+uenv' ]
112124 build_system = 'CMake'
113125 sourcesdir = None
114- maintainers = ['tmathieu' , 'romeli' , 'abussy' , 'simbergm' , 'SSA' ]
115- cp2k_sources = fixture (cp2k_download , scope = 'session ' )
126+ maintainers = ['tmathieu' , 'romeli' , 'abussy' , 'simbergm' , 'SSA' ]
127+ cp2k_sources = fixture (cp2k_download , scope = 'test ' )
116128 build_locally = False
117129 tags = {'uenv' }
118130
@@ -124,54 +136,65 @@ def prepare_build(self):
124136 cpu = self .current_partition .processor
125137 self .build_system .max_concurrency = cpu .info ['num_cpus_per_socket' ]
126138
139+ self .time_limit = '0d0h30m0s'
140+
127141 tarsource = os .path .join (
128- self .cp2k_sources .stagedir , f'{ self .cp2k_sources .version } .tar.gz'
142+ self .cp2k_sources .stagedir , f'v { self .cp2k_sources .version } .tar.gz'
129143 )
130144
131145 # Extract source code
132146 self .prebuild_cmds = [
133147 f'tar --strip-components=1 -xzf { tarsource } -C { self .stagedir } '
134148 ]
135149
136- # TODO: Use Ninja generator
137- self .build_system .config_opts = [
138- # Puts executables under exe/local_cuda/
139- '-DCP2K_ENABLE_REGTESTS=ON' ,
140- '-DCP2K_USE_LIBXC=ON' ,
141- '-DCP2K_USE_LIBINT2=ON' ,
142- '-DCP2K_USE_SPGLIB=ON' ,
143- '-DCP2K_USE_ELPA=ON' ,
144- '-DCP2K_USE_SPLA=ON' ,
145- '-DCP2K_USE_SIRIUS=ON' ,
146- '-DCP2K_USE_COSMA=ON' ,
147- '-DCP2K_USE_PLUMED=ON' ,
148- ]
149-
150- if self .uarch == 'gh200' :
151- self .build_system .config_opts += [
152- '-DCP2K_USE_ACCEL=CUDA' ,
153- '-DCP2K_WITH_GPU=H100' ,
154- ]
150+ try :
151+ self .build_system .config_opts = self .current_environ .extras ['cmake' ].split ()
152+ except (KeyError , AttributeError ):
153+ self .build_system .config_opts = [
154+ '-DCMAKE_BUILD_TYPE=Release' ,
155+ '-DCP2K_USE_LIBXC=ON' ,
156+ '-DCP2K_USE_LIBINT2=ON' ,
157+ '-DCP2K_USE_FFTW3=ON' ,
158+ '-DCP2K_USE_SPGLIB=ON' ,
159+ '-DCP2K_USE_ELPA=ON' ,
160+ '-DCP2K_USE_SPLA=ON' ,
161+ '-DCP2K_USE_SIRIUS=ON' ,
162+ '-DCP2K_USE_COSMA=ON' ,
163+ '-DCP2K_USE_PLUMED=ON' ,
164+ ]
165+
166+ if self .uarch == 'gh200' :
167+ self .build_system .config_opts += [
168+ '-DCP2K_USE_ACCEL=CUDA' ,
169+ '-DCP2K_USE_SPLA_GEMM_OFFLOADING=ON' ,
170+ '-DCMAKE_CUDA_HOST_COMPILER=mpicc' ,
171+ '-DCP2K_WITH_GPU=H100' ,
172+ ]
155173
156174 @sanity_function
157175 def validate_test (self ):
158176 # INFO: Executables are in exe/FOLDER because -DCP2K_ENABLE_REGTEST=ON
159177 # INFO: With -DCP2K_ENABLE_REGTEST=OFF, executables are in build/bin/
160- folder = 'local_cuda' if self .uarch == 'gh200' else 'local'
161- self .cp2k_executable = os .path .join (self .stagedir , 'exe' , folder ,
178+ # folder = 'local_cuda' if self.uarch == 'gh200' else 'local'
179+ # self.cp2k_executable = os.path.join(self.stagedir, 'exe', folder,
180+ # 'cp2k.psmp')
181+ self .cp2k_executable = os .path .join (self .stagedir , 'build' , 'bin' ,
162182 'cp2k.psmp' )
163183 return os .path .isfile (self .cp2k_executable )
164184
165185
166186class Cp2kCheck_UENV (rfm .RunOnlyRegressionTest ):
167- executable = './pika-bind.sh cp2k.psmp'
168187 maintainers = ['SSA' ]
169188 valid_systems = ['+uenv' ]
170189 valid_prog_environs = ['+cp2k -dlaf' ]
171190
191+ @run_after ('setup' )
192+ def setup_wrapper (self ):
193+ self .uarch = uarch (self .current_partition )
194+ self .wrapper = './mps-wrapper.sh' if self .uarch == 'gh200' else ''
195+
172196 @run_before ('run' )
173197 def prepare_run (self ):
174- self .uarch = uarch (self .current_partition )
175198 config = slurm_config [self .test_name ][self .uarch ]
176199 # sbatch options
177200 self .job .options = [
@@ -183,9 +206,6 @@ def prepare_run(self):
183206 self .ntasks_per_core = 1
184207 self .time_limit = config ['walltime' ]
185208
186- # wrapper script
187- self .wrapper = './mps-wrapper.sh' if self .uarch == 'gh200' else ''
188-
189209 # srun options
190210 self .job .launcher .options = ['--cpu-bind=cores' ]
191211
@@ -196,20 +216,21 @@ def prepare_run(self):
196216 self .env_vars ['OMP_PLACES' ] = 'cores'
197217 self .env_vars ['OMP_PROC_BIND' ] = 'close'
198218
199- self .env_vars [" MIMALLOC_ALLOW_LARGE_OS_PAGES" ] = "1"
200- self .env_vars [" MIMALLOC_EAGER_COMMIT_DELAY" ] = "0"
219+ self .env_vars [' MIMALLOC_ALLOW_LARGE_OS_PAGES' ] = '1'
220+ self .env_vars [' MIMALLOC_EAGER_COMMIT_DELAY' ] = '0'
201221
202- if self .uarch == "zen2" :
203- self .env_vars ["PIKA_THREADS" ] = str ((self .num_cpus_per_task // 2 ) - 1 )
222+ if self .uarch == 'zen2' :
223+ self .env_vars ['PIKA_THREADS' ] = \
224+ str ((self .num_cpus_per_task // 2 ) - 1 )
204225 else :
205- self .env_vars [" PIKA_THREADS" ] = str (self .num_cpus_per_task - 1 )
226+ self .env_vars [' PIKA_THREADS' ] = str (self .num_cpus_per_task - 1 )
206227
207228 if self .uarch == 'gh200' :
208229 self .env_vars ['MPICH_GPU_SUPPORT_ENABLED' ] = '1'
209230 self .env_vars ['CUDA_CACHE_DISABLE' ] = '1'
210- self .env_vars [" DLAF_BT_BAND_TO_TRIDIAG_HH_APPLY_GROUP_SIZE" ] = \
211- " 128"
212- self .env_vars [" DLAF_UMPIRE_DEVICE_MEMORY_POOL_ALIGNMENT_BYTES" ] = \
231+ self .env_vars [' DLAF_BT_BAND_TO_TRIDIAG_HH_APPLY_GROUP_SIZE' ] = \
232+ ' 128'
233+ self .env_vars [' DLAF_UMPIRE_DEVICE_MEMORY_POOL_ALIGNMENT_BYTES' ] = \
213234 str (2 ** 21 )
214235
215236 # set reference
@@ -220,6 +241,10 @@ def prepare_run(self):
220241 cp2k_references [self .test_name ][self .uarch ]
221242 }
222243
244+ @run_before ('run' )
245+ def setup_executable (self ):
246+ self .executable = f'{ self .wrapper } ./pika-bind.sh cp2k.psmp'
247+
223248 @sanity_function
224249 def assert_energy_diff (self ):
225250 regex = (
@@ -255,7 +280,7 @@ class Cp2kCheckMD_UENV(Cp2kCheck_UENV):
255280@rfm .simple_test
256281class Cp2kCheckMD_UENVExec (Cp2kCheckMD_UENV ):
257282 valid_prog_environs = ['+cp2k -dlaf' ]
258- tags = {'uenv' , 'production' }
283+ tags = {'uenv' , 'production' , 'maintenance' , 'bencher' }
259284
260285
261286@rfm .simple_test
@@ -271,30 +296,46 @@ class Cp2kCheckMD_UENVCustomExec(Cp2kCheckMD_UENV):
271296 def setup_dependency (self ):
272297 self .depends_on ('Cp2kBuildTestUENV' , udeps .fully )
273298
274- @run_after ( 'setup ' )
299+ @run_before ( 'run ' )
275300 def setup_executable (self ):
276301 parent = self .getdep ('Cp2kBuildTestUENV' )
277- self .executable = f'{ self .wrapper } ./pika-bind.sh { parent .cp2k_executable } '
302+ self .executable = (
303+ f'{ self .wrapper } ./pika-bind.sh { parent .cp2k_executable } ' )
278304
279305
280306# }}}
281307# {{{ PBE
282308class Cp2kCheckPBE_UENV (Cp2kCheck_UENV ):
283309 test_name = 'pbe'
284310 valid_prog_environs = ['+cp2k -dlaf' ]
285- tags = {'uenv' , 'production' }
286- executable_opts = ['-i' , 'H2O-128-PBE-TZ.inp' ]
287311 energy_reference = - 2206.2426491358
288312
289313 @run_after ('init' )
290- def set_wfn (self ):
314+ def setup_input_and_wf (self ):
315+ # Define input file depending on version
316+ # CP2K 2025.2 counts SCF steps differently
317+ # Since this first inner SCF step does converge
318+ # a different count means a different runtime with the same input file
319+ # See https://github.com/cp2k/cp2k/pull/4141
320+ try :
321+ uenv_version = self .current_environ .extras ['version' ][1 :]
322+ except (KeyError , AttributeError ):
323+ uenv_version = version_from_uenv ()
324+
325+ if Version (uenv_version ) > Version ('2025.1' ):
326+ # Reduce max_scf to 16 to reproduce previous behaviour
327+ self .executable_opts = ['-i' , 'H2O-128-PBE-TZ-max_scf_16.inp' ]
328+ else :
329+ self .executable_opts = ['-i' , 'H2O-128-PBE-TZ.inp' ]
330+
331+ # Define WF file for restart (needed by RPA test)
291332 self .wfn_file = 'H2O-128-PBE-TZ-RESTART.wfn'
292333
293334
294335@rfm .simple_test
295336class Cp2kCheckPBE_UENVExec (Cp2kCheckPBE_UENV ):
296337 valid_prog_environs = ['+cp2k -dlaf' ]
297- tags = {'uenv' , 'production' }
338+ tags = {'uenv' , 'production' , 'maintenance' , 'bencher' }
298339
299340
300341@rfm .simple_test
@@ -310,10 +351,11 @@ class Cp2kCheckPBE_UENVCustomExec(Cp2kCheckPBE_UENV):
310351 def setup_dependency (self ):
311352 self .depends_on ('Cp2kBuildTestUENV' , udeps .fully )
312353
313- @run_after ( 'setup ' )
354+ @run_before ( 'run ' )
314355 def setup_executable (self ):
315356 parent = self .getdep ('Cp2kBuildTestUENV' )
316- self .executable = f'{ self .wrapper } ./pika-bind.sh { parent .cp2k_executable } '
357+ self .executable = (
358+ f'{ self .wrapper } ./pika-bind.sh { parent .cp2k_executable } ' )
317359
318360
319361# }}}
0 commit comments