diff --git a/tests/apps/castep/castep_check.py b/tests/apps/castep/castep_check.py index 2fc24c13..298fd11c 100644 --- a/tests/apps/castep/castep_check.py +++ b/tests/apps/castep/castep_check.py @@ -52,7 +52,7 @@ def extract_calctime(self): class CASTEPCPUCheck(CASTEPBaseCheck): """CASTEP Check for CPU""" - valid_systems = ["archer2:compute", "cirrus:compute"] + valid_systems = ["archer2:compute", "cirrus:compute", "cirrus-ex:compute"] descr = "CASTEP corrctness and performance test" executable_opts = ["al3x3"] @@ -64,10 +64,13 @@ class CASTEPCPUCheck(CASTEPBaseCheck): reference["archer2:compute"]["runtime"] = (132, -0.1, 0.1, "s") reference["cirrus:compute"] = {} - reference["cirrus:compute"]["calctime"] = (325.9, -0.1, 0.1, "s") reference["cirrus:compute"]["runtime"] = (328.2, -0.1, 0.1, "s") + reference["cirrus-ex:compute"] = {} + reference["cirrus-ex:compute"]["runtime"] = (82, -0.1, 0.1, "s") + reference["cirrus-ex:compute"]["calctime"] = (74, -0.1, 0.1, "s") + @run_after("init") def setup_environment(self): """Setup environment""" @@ -76,6 +79,11 @@ def setup_environment(self): self.num_tasks = 512 self.num_tasks_per_node = 128 + if self.current_system.name in ["cirrus-ex"]: + self.modules = ["castep"] + self.num_tasks = 288 * 2 + self.num_tasks_per_node = 288 + if self.current_system.name in ["cirrus"]: self.modules = ["castep/22.1.1"] self.num_tasks = 216 diff --git a/tests/apps/cp2k/cp2k_check.py b/tests/apps/cp2k/cp2k_check.py index 00737b9b..6f572703 100644 --- a/tests/apps/cp2k/cp2k_check.py +++ b/tests/apps/cp2k/cp2k_check.py @@ -1,6 +1,6 @@ #!/usr/bin/env python3 -"""ReFrame test for cp2k""" +"""ReFrame tests for cp2k""" import reframe as rfm import reframe.utility.sanity as sn @@ -15,62 +15,20 @@ class CP2KBaseCheck(rfm.RunOnlyRegressionTest): executable = "cp2k.psmp" # Additional Slurm parameters. Requires adding to config file first. extra_resources = {"qos": {"qos": "standard"}} - # Output files to be retained - keep_files = ["cp2k.out"] - - # Set time limit - - time_limit = "20m" maintainers = ["j.richings@epcc.ed.ac.uk"] use_multithreading = False - tags = {"applications", "performance"} - - # Reference value to validate run with - energy_reference = -870.934788 - - reference = { - "*": {"energy": (energy_reference, -0.01, 0.01, "a.u.")}, - "cirrus:compute": {"performance": (1300, -0.05, 0.05, "seconds")}, - } - - reference_performance = { - "2000000": (350, -0.1, 0.1, "seconds"), - "2250000": (250, -0.1, 0.1, "seconds"), - } - - @sanity_function - def assert_finished(self): - """Sanity check that simulation finished successfully""" - return sn.assert_found("CP2K ", self.keep_files[0]) - - @performance_function("a.u.", perf_key="energy") - def extract_energy(self): - """Extract value of system energy for performance check""" - return sn.extractsingle( - r"ENERGY\| Total FORCE_EVAL \( QS \) energy \[a.u.\]:\s+(?P\S+)", - self.keep_files[0], - "energy", - float, - ) - - @performance_function("seconds", perf_key="performance") - def extract_perf(self): - """Extract performance value to compare with reference value""" - return sn.extractsingle( - r"\s+CP2K(?:\s+\d+\.?\d*){5}\s+(?P\S+)", - self.keep_files[0], - "perf", - float, - ) + tags = {"applications"} @rfm.simple_test -class CP2KARCHER2(CP2KBaseCheck): - """CP2K test""" +class CP2KARCHER2HFX(CP2KBaseCheck): + """CP2K performance test""" # Select system to use valid_systems = ["archer2:compute"] + # Output files to be retained + keep_files = ["cp2k.out"] # Set Programming Environment valid_prog_environs = ["PrgEnv-gnu", "PrgEnv-gnu-hf"] # Description of test @@ -84,12 +42,19 @@ class CP2KARCHER2(CP2KBaseCheck): num_tasks_per_node = 16 num_cpus_per_task = 8 time_limit = "10m" - + # Reference value to validate run with + energy_reference = -870.934788 + tags = CP2KBaseCheck.tags.union({"performance"}) reference_performance = { "2000000": (350, -0.1, 0.1, "seconds"), "2250000": (250, -0.1, 0.1, "seconds"), } + @sanity_function + def assert_finished(self): + """Sanity check that simulation finished successfully""" + return sn.assert_found("CP2K ", self.keep_files[0]) + @run_after("init") def setup_params(self): """sets up extra parameters""" @@ -97,9 +62,6 @@ def setup_params(self): if self.current_system.name in ["archer2"]: self.env_vars = {"OMP_NUM_THREADS": str(self.num_cpus_per_task), "OMP_PLACES": "cores"} - # "SLURM_CPU_FREQ_REQ": self.freq, - # } - @run_before("performance") def set_reference(self): """Changes reference values""" @@ -109,26 +71,120 @@ def set_reference(self): "2250000" if self.current_environ.name[-3:] == "-hf" else "2000000" ] + reference = {"*": {"energy": (energy_reference, -0.01, 0.01, "a.u.")}} + + reference_performance = { + "2000000": (350, -0.1, 0.1, "seconds"), + "2250000": (250, -0.1, 0.1, "seconds"), + } + + @performance_function("a.u.", perf_key="energy") + def extract_energy(self): + """Extract value of system energy for performance check""" + return sn.extractsingle( + r"ENERGY\| Total FORCE_EVAL \( QS \) energy \[a.u.\]:\s+(?P\S+)", + self.keep_files[0], + "energy", + float, + ) + + @performance_function("seconds", perf_key="performance") + def extract_perf(self): + """Extract performance value to compare with reference value""" + return sn.extractsingle( + r"\s+CP2K(?:\s+\d+\.?\d*){5}\s+(?P\S+)", + self.keep_files[0], + "perf", + float, + ) + + +@rfm.simple_test +class FetchCP2K(rfm.RunOnlyRegressionTest): + """ + Fetch CP2K source code, which contains the regression tests and benchmarks. + """ + + descr = "Fetch cp2k code" + version = variable(str, value="2025.2") + executable = "wget" + executable_opts = [f"https://github.com/cp2k/cp2k/archive/refs/tags/v{version}.tar.gz"] + local = True + valid_systems = ["cirrus-ex:login"] + valid_prog_environs = ["PgEnv-gnu"] + + @sanity_function + def validate_download(self): + """Validate the download was successful""" + return sn.assert_eq(self.job.exitcode, 0) + @rfm.simple_test -class CP2KCPUCirrus(CP2KBaseCheck): - """CP2K test for Cirrus""" +class CP2KCPUCirrusExRegressionTests(CP2KBaseCheck): + """ + CP2K regression tests for cirrus-ex + + This runs the CP2K tests from the CP2K regression test suite. + They are good functionality tests but not very useful for performance. + + """ # Select system to use - valid_systems = ["cirrus:compute"] + valid_systems = ["cirrus-ex:compute"] # Set Programming Environment - valid_prog_environs = ["gcc"] + valid_prog_environs = ["PrgEnv-gnu"] # Description of test - descr = "CP2K test" + descr = "CP2K regression tests" + launcher = "cp2k_reg_tests" + # Command line options for executable - executable_opts = ("-i input_bulk_HFX_3.inp -o cp2k.out ").split() - # slurm parameters - num_tasks = 360 - num_tasks_per_node = 18 - num_cpus_per_task = 2 - time_limit = "1h" - - env_vars = { - "OMP_NUM_THREADS": str(num_cpus_per_task), - "OMP_PLACES": "cores", - } + + executable = "cp2k.psmp" + + executable_opts = ["-v"] + + cp2k_src = fixture(FetchCP2K, scope="environment") + + env_vars = {"OMP_PLACES": "cores", "CP2K_APP": "$(which cp2k.psmp)", "CP2K_DIR": "${CP2K_APP::-10}"} + + @sanity_function + def assert_all_tests_completed(self): + """Sanity check that simulation finished successfully""" + return sn.assert_found("Status: OK", self.stdout) + + @run_before("run") + def set_resources(self): + """Sets up slurm parameters""" + # slurm parameters + self.num_tasks = self.current_partition.processor.num_cpus // 2 + self.num_tasks_per_node = self.current_partition.processor.num_cpus // 2 + self.num_cpus_per_task = 2 + self.time_limit = "20m" + self.env_vars["OMP_NUM_THREADS"] = str(self.num_cpus_per_task) + + @run_before("run") + def launch_reg_tests(self): + """ + The command to launch the regression tests is a python script executed serially ( not in parallel). + + In this implementation we use pre-run commands. + An alternative is to use a custom launcher. + However this needs to be specified in the config, + in a custom programming environment. + I think that solution is worse , because it pollutes a configuration file with test specific logic. + + """ + + source_tar_file = f"v{self.cp2k_src.version}.tar.gz" + + self.prerun_cmds = [ + f"cp {self.cp2k_src.stagedir}/{source_tar_file} .", + f"tar -zxf {source_tar_file}", + f'cp2k-{self.cp2k_src.version}/tests/do_regtest.py \ + --workbasedir=$(pwd) \ + --maxtasks=72 \ + --mpiranks=2 \ + --ompthreads=${{OMP_NUM_THREADS}} \ + --mpiexec="srun --ntasks=2 --cpus-per-task=${{OMP_NUM_THREADS}}" \ + $CP2K_DIR psmp', + ] diff --git a/tests/apps/lammps/ethanol.py b/tests/apps/lammps/ethanol.py index 0e718926..1d6a673c 100644 --- a/tests/apps/lammps/ethanol.py +++ b/tests/apps/lammps/ethanol.py @@ -34,6 +34,7 @@ class LAMMPSBaseEthanol(LAMMPSBase): reference = { "cirrus:compute-gpu": {"energy": (ethanol_energy_reference, -0.01, 0.01, "kJ/mol")}, "archer2:compute": {"energy": (ethanol_energy_reference, -0.01, 0.01, "kJ/mol")}, + "cirrus-ex:compute": {"energy": (ethanol_energy_reference, -0.01, 0.01, "kJ/mol")}, "archer2-tds:compute": {"energy": (ethanol_energy_reference, -0.01, 0.01, "kJ/mol")}, } @@ -49,18 +50,18 @@ def extract_energy(self): ) -@rfm.simple_test class LAMMPSEthanolCPU(LAMMPSBaseEthanol): """ReFrame LAMMPS Ethanol test for performance checks""" - valid_systems = ["archer2:compute"] descr = LAMMPSBaseEthanol.descr + " -- CPU" - stream_binary = fixture(BuildLAMMPS, scope="environment") reference["archer2-tds:compute"] = {} reference["archer2:compute"] = {} + reference["cirrus-ex:compute"] = {} reference["archer2:compute"]["performance"] = (11.250, -0.05, None, "ns/day") + reference["cirrus-ex:compute"]["performance"] = (27.56, -0.05, None, "ns/day") + reference["archer2-tds:compute"]["performance"] = (11.250, -0.05, None, "ns/day") @run_after("init") @@ -68,6 +69,9 @@ def setup_nnodes(self): """sets up number of tasks per node""" if self.current_system.name in ["archer2"]: self.num_tasks_per_node = 128 + else: + if self.current_system.name in ["cirrus-ex"]: + self.num_tasks_per_node = 288 @run_after("setup") def set_executable(self): @@ -77,7 +81,34 @@ def set_executable(self): @run_before("run") def setup_resources(self): """sets up number of tasks""" - self.num_tasks = self.n_nodes * self.cores.get(self.current_partition.fullname, 1) + self.num_tasks = self.n_nodes * self.num_tasks_per_node + + +@rfm.simple_test +class LAMMPSEthanolCPURunReframeBuild(LAMMPSEthanolCPU): + """ReFrame LAMMPS Ethanol test for performance checks of the reframe-built executable""" + + valid_systems = ["archer2:compute"] + descr = LAMMPSEthanolCPU.descr + ", reframe-bult-executable -- CPU" + stream_binary = fixture(BuildLAMMPS, scope="environment") + + @run_after("setup") + def set_executable(self): + """sets up executable""" + self.executable = os.path.join(self.stream_binary.build_system.builddir, "lmp") + + +@rfm.simple_test +class LAMMPSEthanolCPURunModule(LAMMPSEthanolCPU): + """ReFrame LAMMPS Ethanol test for performance checks of the default lammps module""" + + valid_systems = ["archer2:compute", "cirrus-ex:compute"] + descr = LAMMPSEthanolCPU.descr + ", default lammps module -- CPU" + + @run_after("setup") + def set_executable(self): + """sets up executable""" + self.executable = "lmp" @rfm.simple_test diff --git a/tests/apps/openfoam/openfoam_org_base.py b/tests/apps/openfoam/openfoam_org_base.py index 8a5b062c..7675a3b7 100644 --- a/tests/apps/openfoam/openfoam_org_base.py +++ b/tests/apps/openfoam/openfoam_org_base.py @@ -1,33 +1,33 @@ """Base class for OpenFoam.org tests""" import reframe as rfm -import reframe.utility.sanity as sn class OpenFOAMBase(rfm.RunOnlyRegressionTest): """ReFrame OpenFOAM test base class""" - v_major = "10" - v_patch = "20230119" - version = f"{v_major}.{v_patch}" - valid_systems = ["archer2:compute"] valid_prog_environs = ["PrgEnv-gnu"] maintainers = ["e.broadway@epcc.ed.ac.uk", "j.richings@epcc.ed.ac.uk"] use_multithreading = False tags = {"applications", "performance"} - @sanity_function - def assert_finished(self): - """Sanity check that simulation finished successfully""" - return sn.assert_found("End", self.stdout) - - @performance_function("seconds", perf_key="performance") - def extract_perf(self): - """Extract performance value to compare with reference value""" - return sn.extractsingle( - r"ExecutionTime\s+=\s+(?P