你已经派生过 gprMax
镜像自地址
https://gitee.com/sunhf/gprMax.git
已同步 2025-08-07 15:10:13 +08:00
Split up reframe tests and pytest unit tests
这个提交包含在:
8
tests/.gitignore
vendored
8
tests/.gitignore
vendored
@@ -1,8 +0,0 @@
|
||||
output/
|
||||
perflogs/
|
||||
stage/
|
||||
reframe.log
|
||||
reframe.out
|
||||
reframe_perf.out
|
||||
|
||||
configuration/user_config.py
|
@@ -1,169 +0,0 @@
|
||||
"""ReFrame base classes for GprMax tests"""
|
||||
import os
|
||||
from pathlib import Path
|
||||
from shutil import copyfile
|
||||
|
||||
import reframe as rfm
|
||||
import reframe.utility.sanity as sn
|
||||
from reframe.core.builtins import performance_function, require_deps, run_after, run_before, sanity_function, variable
|
||||
from reframe.utility import udeps
|
||||
|
||||
from tests.utilities.deferrable import path_join
|
||||
|
||||
GPRMAX_ROOT_DIR = Path(__file__).parent.parent.resolve()
|
||||
PATH_TO_PYENV = os.path.join(".venv", "bin", "activate")
|
||||
|
||||
|
||||
@rfm.simple_test
|
||||
class CreatePyenvTest(rfm.RunOnlyRegressionTest):
|
||||
valid_systems = ["generic", "archer2:login"]
|
||||
valid_prog_environs = ["builtin", "PrgEnv-cray"]
|
||||
modules = ["cray-python"]
|
||||
|
||||
prerun_cmds = [
|
||||
"python -m venv --system-site-packages --prompt gprMax .venv",
|
||||
f"source {PATH_TO_PYENV}",
|
||||
f"pip install -r {os.path.join(GPRMAX_ROOT_DIR, 'requirements.txt')}",
|
||||
]
|
||||
executable = f"pip install -e {GPRMAX_ROOT_DIR}"
|
||||
|
||||
@sanity_function
|
||||
def check_requirements_installed(self):
|
||||
"""
|
||||
Check packages successfully installed from requirements.txt
|
||||
Check gprMax installed successfully and no other errors thrown
|
||||
"""
|
||||
return (
|
||||
sn.assert_found(r"Successfully installed (?!gprMax)", self.stdout, "Failed to install requirements")
|
||||
and sn.assert_found(r"Successfully installed gprMax", self.stdout, "Failed to install gprMax")
|
||||
and sn.assert_not_found(r"finished with status 'error'", self.stdout)
|
||||
and sn.assert_not_found(r"ERROR:", self.stderr)
|
||||
)
|
||||
|
||||
|
||||
class GprMaxBaseTest(rfm.RunOnlyRegressionTest):
|
||||
valid_systems = ["archer2:compute"]
|
||||
valid_prog_environs = ["PrgEnv-cray"]
|
||||
executable = "time -p python -m gprMax --log-level 25"
|
||||
exclusive_access = True
|
||||
|
||||
@run_after("init")
|
||||
def setup_env_vars(self):
|
||||
"""Set OMP_NUM_THREADS environment variable from num_cpus_per_task"""
|
||||
self.env_vars["OMP_NUM_THREADS"] = self.num_cpus_per_task
|
||||
|
||||
if self.current_system.name == "archer2":
|
||||
# Avoid inheriting slurm memory environment variables from any previous slurm job (i.e. the reframe job)
|
||||
self.prerun_cmds.append("unset SLURM_MEM_PER_NODE")
|
||||
self.prerun_cmds.append("unset SLURM_MEM_PER_CPU")
|
||||
|
||||
# Set HOME environment variable to the work filesystem
|
||||
self.env_vars["HOME"] = "${HOME/home/work}"
|
||||
|
||||
# TODO: Change CreatePyenvTest to a fixture instead of a test dependency
|
||||
@run_after("init")
|
||||
def inject_dependencies(self):
|
||||
"""Test depends on the Python virtual environment building correctly"""
|
||||
self.depends_on("CreatePyenvTest", udeps.by_env)
|
||||
|
||||
@require_deps
|
||||
def get_pyenv_path(self, CreatePyenvTest):
|
||||
"""Add prerun command to load the built Python environment"""
|
||||
path_to_pyenv = os.path.join(CreatePyenvTest(part="login").stagedir, PATH_TO_PYENV)
|
||||
self.prerun_cmds.append(f"source {path_to_pyenv}")
|
||||
|
||||
@sanity_function
|
||||
def test_simulation_complete(self):
|
||||
"""Check simulation completed successfully"""
|
||||
# TODO: Check for correctness/regression rather than just completing
|
||||
return sn.assert_not_found(
|
||||
r"(?i)error", self.stderr, f"An error occured. See '{path_join(self.stagedir, self.stderr)}' for details."
|
||||
) and sn.assert_found(r"=== Simulation completed in ", self.stdout, "Simulation did not complete")
|
||||
|
||||
@performance_function("s", perf_key="run_time")
|
||||
def extract_run_time(self):
|
||||
"""Extract total runtime from the last task to complete"""
|
||||
return sn.extractsingle(r"real\s+(?P<run_time>\S+)", self.stderr, "run_time", float, self.num_tasks - 1)
|
||||
|
||||
@performance_function("s", perf_key="simulation_time")
|
||||
def extract_simulation_time(self):
|
||||
"""Extract simulation time reported by gprMax"""
|
||||
|
||||
# sn.extractall throws an error if a group has value None.
|
||||
# Therefore have to handle the < 1 min, >= 1 min and >= 1 hour cases separately.
|
||||
timeframe = sn.extractsingle(
|
||||
r"=== Simulation completed in \S+ (?P<timeframe>hour|minute|second)", self.stdout, "timeframe"
|
||||
)
|
||||
if timeframe == "hour":
|
||||
simulation_time = sn.extractall(
|
||||
r"=== Simulation completed in (?P<hours>\S+) hours?, (?P<minutes>\S+) minutes? and (?P<seconds>\S+) seconds? =*",
|
||||
self.stdout,
|
||||
["hours", "minutes", "seconds"],
|
||||
float,
|
||||
)
|
||||
hours = simulation_time[0][0]
|
||||
minutes = simulation_time[0][1]
|
||||
seconds = simulation_time[0][2]
|
||||
elif timeframe == "minute":
|
||||
hours = 0
|
||||
simulation_time = sn.extractall(
|
||||
r"=== Simulation completed in (?P<minutes>\S+) minutes? and (?P<seconds>\S+) seconds? =*",
|
||||
self.stdout,
|
||||
["minutes", "seconds"],
|
||||
float,
|
||||
)
|
||||
minutes = simulation_time[0][0]
|
||||
seconds = simulation_time[0][1]
|
||||
else:
|
||||
hours = 0
|
||||
minutes = 0
|
||||
seconds = sn.extractsingle(
|
||||
r"=== Simulation completed in (?P<seconds>\S+) seconds? =*", self.stdout, "seconds", float
|
||||
)
|
||||
return hours * 3600 + minutes * 60 + seconds
|
||||
|
||||
|
||||
class GprMaxRegressionTest(GprMaxBaseTest):
|
||||
modules = ["cray-hdf5"]
|
||||
|
||||
input_file = variable(str)
|
||||
output_file = variable(str)
|
||||
|
||||
h5diff_header = f"{'=' * 10} h5diff output {'=' * 10}"
|
||||
|
||||
@run_before("run", always_last=True)
|
||||
def setup_regression_check(self):
|
||||
"""Build reference file path and add h5diff command to run after the test"""
|
||||
self.reference_file = Path("regression_checks", self.unique_name).with_suffix(".h5")
|
||||
self.reference_file = os.path.abspath(self.reference_file)
|
||||
if os.path.exists(self.reference_file):
|
||||
self.postrun_cmds.append(f"echo {self.h5diff_header}")
|
||||
self.postrun_cmds.append(f"h5diff {self.output_file} {self.reference_file}")
|
||||
|
||||
@sanity_function
|
||||
def regression_check(self):
|
||||
"""
|
||||
Perform regression check by checking for the h5diff output.
|
||||
Create reference file from the test output if it does not exist.
|
||||
"""
|
||||
if sn.path_exists(self.reference_file):
|
||||
h5diff_output = sn.extractsingle(f"{self.h5diff_header}\n(?P<h5diff>[\S\s]*)", self.stdout, "h5diff")
|
||||
return (
|
||||
self.test_simulation_complete()
|
||||
and sn.assert_found(self.h5diff_header, self.stdout, "Failed to find h5diff header")
|
||||
and sn.assert_false(
|
||||
h5diff_output,
|
||||
(
|
||||
f"Found h5diff output (see '{path_join(self.stagedir, self.stdout)}')\n"
|
||||
f"For more details run: 'h5diff {os.path.abspath(self.output_file)} {self.reference_file}'\n"
|
||||
f"To re-create regression file, delete '{self.reference_file}' and rerun the test."
|
||||
),
|
||||
)
|
||||
)
|
||||
else:
|
||||
copyfile(self.output_file, self.reference_file)
|
||||
return sn.assert_true(False, f"No reference file exists. Creating... '{self.reference_file}'")
|
||||
|
||||
|
||||
class GprMaxMpiTest(GprMaxBaseTest):
|
||||
pass
|
@@ -1,145 +0,0 @@
|
||||
cpu_freq,domain,num_cpus_per_task,num_tasks,num_tasks_per_node,omp_threads,run_time,simulation_time
|
||||
2000000,0.1,1,1,,1,66.38,56.22
|
||||
2000000,0.1,2,1,,2,37.98,30.32
|
||||
2000000,0.1,4,1,,4,22.77,17.18
|
||||
2000000,0.1,8,1,,8,16.18,10.51
|
||||
2000000,0.1,16,1,,16,14.27,8.09
|
||||
2000000,0.1,32,1,,32,17.05,10.1
|
||||
2000000,0.1,64,1,,64,28.35,19.12
|
||||
2000000,0.1,128,1,,128,85.27,65.33
|
||||
2000000,0.15,1,1,,1,182.5,174.22
|
||||
2000000,0.15,2,1,,2,102.11,92.21
|
||||
2000000,0.15,4,1,,4,55.17,49.58
|
||||
2000000,0.15,8,1,,8,37.08,31.39
|
||||
2000000,0.15,16,1,,16,33.61,25.55
|
||||
2000000,0.15,32,1,,32,26.1,19.07
|
||||
2000000,0.15,64,1,,64,33.14,23.48
|
||||
2000000,0.15,128,1,,128,78.14,59.57
|
||||
2000000,0.2,1,1,,1,386.67,374.75
|
||||
2000000,0.2,2,1,,2,206.99,197.88
|
||||
2000000,0.2,4,1,,4,109.97,104.41
|
||||
2000000,0.2,8,1,,8,73.19,64.43
|
||||
2000000,0.2,16,1,,16,62.07,54.08
|
||||
2000000,0.2,32,1,,32,48.24,40.67
|
||||
2000000,0.2,64,1,,64,55.74,44.6
|
||||
2000000,0.2,128,1,,128,101.74,83.55
|
||||
2000000,0.3,1,1,,1,1151.43,1140.37
|
||||
2000000,0.3,2,1,,2,611.66,602.01
|
||||
2000000,0.3,4,1,,4,321.48,310.84
|
||||
2000000,0.3,8,1,,8,204.9,196.05
|
||||
2000000,0.3,16,1,,16,174.01,167.72
|
||||
2000000,0.3,32,1,,32,128.94,116.76
|
||||
2000000,0.3,64,1,,64,121.17,108.21
|
||||
2000000,0.3,128,1,,128,198.33,174.66
|
||||
2000000,0.4,1,1,,1,2610.57,2598.76
|
||||
2000000,0.4,2,1,,2,1371.05,1359.44
|
||||
2000000,0.4,4,1,,4,706.84,699.5
|
||||
2000000,0.4,8,1,,8,466.36,459.21
|
||||
2000000,0.4,16,1,,16,401.64,393.83
|
||||
2000000,0.4,32,1,,32,279.96,267.74
|
||||
2000000,0.4,64,1,,64,271.98,247.58
|
||||
2000000,0.4,128,1,,128,374.76,314.99
|
||||
2000000,0.5,1,1,,1,4818.72,4806.97
|
||||
2000000,0.5,2,1,,2,2549.42,2540.13
|
||||
2000000,0.5,4,1,,4,1315.68,1306.77
|
||||
2000000,0.5,8,1,,8,864.02,855.79
|
||||
2000000,0.5,16,1,,16,755.09,748.3
|
||||
2000000,0.5,32,1,,32,548.72,527.04
|
||||
2000000,0.5,64,1,,64,473.02,414.43
|
||||
2000000,0.5,128,1,,128,594.65,443.44
|
||||
2000000,0.6,1,1,,1,8219.78,8149.55
|
||||
2000000,0.6,2,1,,2,4277.96,4266.5
|
||||
2000000,0.6,4,1,,4,2199.55,2190.22
|
||||
2000000,0.6,8,1,,8,1445.58,1438.02
|
||||
2000000,0.6,16,1,,16,1319.07,1312.13
|
||||
2000000,0.6,32,1,,32,877.47,818.48
|
||||
2000000,0.6,64,1,,64,741.43,649.31
|
||||
2000000,0.6,128,1,,128,821.9,554.22
|
||||
2000000,0.7,1,1,,1,12964.86,12949.06
|
||||
2000000,0.7,2,1,,2,6769.45,6762.25
|
||||
2000000,0.7,4,1,,4,3471.68,3465.48
|
||||
2000000,0.7,8,1,,8,2270.26,2263.86
|
||||
2000000,0.7,16,1,,16,2040.48,2033.68
|
||||
2000000,0.7,32,1,,32,1364.91,1274.35
|
||||
2000000,0.7,64,1,,64,1094.98,936.72
|
||||
2000000,0.7,128,1,,128,1163.05,775.27
|
||||
2000000,0.8,1,1,,1,19115.24,18963.06
|
||||
2000000,0.8,2,1,,2,9894.57,9868.57
|
||||
2000000,0.8,4,1,,4,5021.3,5011.79
|
||||
2000000,0.8,8,1,,8,3285.76,3272.44
|
||||
2000000,0.8,16,1,,16,3010.09,3003.21
|
||||
2000000,0.8,32,1,,32,1961.83,1789.48
|
||||
2000000,0.8,64,1,,64,1528.58,1304.87
|
||||
2000000,0.8,128,1,,128,1671.89,1115.37
|
||||
2250000,0.1,1,1,,1,46.42,38.46
|
||||
2250000,0.1,2,1,,2,27.41,19.9
|
||||
2250000,0.1,4,1,,4,15.61,11.83
|
||||
2250000,0.1,8,1,,8,13.1,9.04
|
||||
2250000,0.1,16,1,,16,11.33,5.89
|
||||
2250000,0.1,32,1,,32,13.28,6.98
|
||||
2250000,0.1,64,1,,64,22.95,14.36
|
||||
2250000,0.1,128,1,,128,63.82,47.17
|
||||
2250000,0.15,1,1,,1,122.83,114.3
|
||||
2250000,0.15,2,1,,2,67.81,58.22
|
||||
2250000,0.15,4,1,,4,37.45,33.57
|
||||
2250000,0.15,8,1,,8,32.12,28.33
|
||||
2250000,0.15,16,1,,16,28.47,23.02
|
||||
2250000,0.15,32,1,,32,21.8,15.31
|
||||
2250000,0.15,64,1,,64,26.29,17.85
|
||||
2250000,0.15,128,1,,128,67.36,50.01
|
||||
2250000,0.2,1,1,,1,249.09,240.5
|
||||
2250000,0.2,2,1,,2,131.92,122.94
|
||||
2250000,0.2,4,1,,4,73.47,69.44
|
||||
2250000,0.2,8,1,,8,68.64,59.68
|
||||
2250000,0.2,16,1,,16,58.96,50.94
|
||||
2250000,0.2,32,1,,32,42.94,35.78
|
||||
2250000,0.2,64,1,,64,44.52,36.89
|
||||
2250000,0.2,128,1,,128,84.06,68.65
|
||||
2250000,0.3,1,1,,1,713.41,703.34
|
||||
2250000,0.3,2,1,,2,369.84,363.33
|
||||
2250000,0.3,4,1,,4,211.28,203.39
|
||||
2250000,0.3,8,1,,8,190.98,186.1
|
||||
2250000,0.3,16,1,,16,169.92,163.23
|
||||
2250000,0.3,32,1,,32,117.74,109.5
|
||||
2250000,0.3,64,1,,64,116.59,101.76
|
||||
2250000,0.3,128,1,,128,162.47,134.58
|
||||
2250000,0.4,1,1,,1,1593.84,1584.41
|
||||
2250000,0.4,2,1,,2,821.79,813.12
|
||||
2250000,0.4,4,1,,4,476.39,468.35
|
||||
2250000,0.4,8,1,,8,445.69,437.75
|
||||
2250000,0.4,16,1,,16,392.55,385.05
|
||||
2250000,0.4,32,1,,32,280.65,265.65
|
||||
2250000,0.4,64,1,,64,249.73,221.02
|
||||
2250000,0.4,128,1,,128,312.19,240.34
|
||||
2250000,0.5,1,1,,1,2917.2,2908.0
|
||||
2250000,0.5,2,1,,2,1501.78,1493.7
|
||||
2250000,0.5,4,1,,4,868.33,859.61
|
||||
2250000,0.5,8,1,,8,831.58,827.08
|
||||
2250000,0.5,16,1,,16,734.53,729.57
|
||||
2250000,0.5,32,1,,32,520.43,486.83
|
||||
2250000,0.5,64,1,,64,431.9,373.89
|
||||
2250000,0.5,128,1,,128,523.72,368.59
|
||||
2250000,0.6,1,1,,1,4930.04,4918.3
|
||||
2250000,0.6,2,1,,2,2513.92,2508.71
|
||||
2250000,0.6,4,1,,4,1437.79,1433.86
|
||||
2250000,0.6,8,1,,8,1385.16,1380.08
|
||||
2250000,0.6,16,1,,16,1278.64,1274.32
|
||||
2250000,0.6,32,1,,32,843.05,800.03
|
||||
2250000,0.6,64,1,,64,683.45,575.28
|
||||
2250000,0.6,128,1,,128,736.02,466.24
|
||||
2250000,0.7,1,1,,1,7778.74,7766.64
|
||||
2250000,0.7,2,1,,2,3979.22,3973.14
|
||||
2250000,0.7,4,1,,4,2290.33,2285.86
|
||||
2250000,0.7,8,1,,8,2193.65,2185.43
|
||||
2250000,0.7,16,1,,16,1984.77,1980.02
|
||||
2250000,0.7,32,1,,32,1302.34,1186.39
|
||||
2250000,0.7,64,1,,64,1011.7,830.39
|
||||
2250000,0.7,128,1,,128,1077.62,685.29
|
||||
2250000,0.8,1,1,,1,11319.94,11306.89
|
||||
2250000,0.8,2,1,,2,5715.39,5709.03
|
||||
2250000,0.8,4,1,,4,3279.14,3260.67
|
||||
2250000,0.8,8,1,,8,3194.27,3174.3
|
||||
2250000,0.8,16,1,,16,2923.77,2918.94
|
||||
2250000,0.8,32,1,,32,1871.78,1736.6
|
||||
2250000,0.8,64,1,,64,1424.7,1179.98
|
||||
2250000,0.8,128,1,,128,1530.45,930.84
|
|
@@ -1,131 +0,0 @@
|
||||
site_configuration = {
|
||||
"general": [
|
||||
{
|
||||
# Necessary if using the --restore-session flag
|
||||
"keep_stage_files": True
|
||||
}
|
||||
],
|
||||
"systems": [
|
||||
{
|
||||
"name": "archer2",
|
||||
"descr": "ARCHER2",
|
||||
"hostnames": ["uan", "ln", "dvn"],
|
||||
"modules_system": "lmod",
|
||||
"partitions": [
|
||||
{
|
||||
"name": "login",
|
||||
"descr": "Login nodes",
|
||||
"scheduler": "local",
|
||||
"launcher": "local",
|
||||
"environs": ["PrgEnv-gnu", "PrgEnv-cray", "PrgEnv-aocc"],
|
||||
},
|
||||
{
|
||||
"name": "compute",
|
||||
"descr": "Compute nodes",
|
||||
"scheduler": "slurm",
|
||||
"launcher": "srun",
|
||||
"access": [
|
||||
"--hint=nomultithread",
|
||||
"--distribution=block:block",
|
||||
"--partition=standard",
|
||||
"--qos=standard",
|
||||
],
|
||||
"environs": ["PrgEnv-gnu", "PrgEnv-cray", "PrgEnv-aocc"],
|
||||
"max_jobs": 16,
|
||||
},
|
||||
],
|
||||
}
|
||||
],
|
||||
"environments": [
|
||||
{
|
||||
"name": "PrgEnv-gnu",
|
||||
"modules": ["PrgEnv-gnu"],
|
||||
"cc": "cc",
|
||||
"cxx": "CC",
|
||||
"ftn": "ftn",
|
||||
"target_systems": ["archer2"],
|
||||
},
|
||||
{
|
||||
"name": "PrgEnv-cray",
|
||||
"modules": ["PrgEnv-cray"],
|
||||
"cc": "cc",
|
||||
"cxx": "CC",
|
||||
"ftn": "ftn",
|
||||
"target_systems": ["archer2"],
|
||||
},
|
||||
{
|
||||
"name": "PrgEnv-aocc",
|
||||
"modules": ["PrgEnv-aocc"],
|
||||
"cc": "cc",
|
||||
"cxx": "CC",
|
||||
"ftn": "ftn",
|
||||
"target_systems": ["archer2"],
|
||||
},
|
||||
],
|
||||
"logging": [
|
||||
{
|
||||
"level": "debug",
|
||||
"handlers": [
|
||||
{"type": "stream", "name": "stdout", "level": "info", "format": "%(message)s"},
|
||||
{
|
||||
"type": "file",
|
||||
"name": "reframe.out",
|
||||
"level": "info",
|
||||
"format": "[%(asctime)s] %(check_info)s: %(message)s",
|
||||
"append": True,
|
||||
},
|
||||
{
|
||||
"type": "file",
|
||||
"name": "reframe.log",
|
||||
"level": "debug",
|
||||
"format": "[%(asctime)s] %(levelname)s %(levelno)s: %(check_info)s: %(message)s", # noqa: E501
|
||||
"append": False,
|
||||
},
|
||||
],
|
||||
"handlers_perflog": [
|
||||
{
|
||||
"type": "file",
|
||||
"name": "reframe_perf.out",
|
||||
"level": "info",
|
||||
"format": "[%(asctime)s] %(check_info)s job_id=%(check_jobid)s %(check_perfvalues)s",
|
||||
"format_perfvars": "| %(check_perf_var)s: %(check_perf_value)s %(check_perf_unit)s (r: %(check_perf_ref)s l: %(check_perf_lower_thres)s u: %(check_perf_upper_thres)s) ",
|
||||
"append": True,
|
||||
},
|
||||
{
|
||||
"type": "filelog",
|
||||
"prefix": "%(check_system)s/%(check_partition)s",
|
||||
"level": "info",
|
||||
"format": (
|
||||
"%(check_result)s,%(check_job_completion_time)s,"
|
||||
"%(check_info)s,%(check_jobid)s,"
|
||||
"%(check_num_tasks)s,%(check_num_cpus_per_task)s,%(check_num_tasks_per_node)s,"
|
||||
"%(check_perfvalues)s"
|
||||
),
|
||||
"format_perfvars": (
|
||||
"%(check_perf_value)s,%(check_perf_unit)s,"
|
||||
"%(check_perf_ref)s,%(check_perf_lower_thres)s,"
|
||||
"%(check_perf_upper_thres)s,"
|
||||
),
|
||||
"append": True,
|
||||
},
|
||||
{
|
||||
"type": "filelog",
|
||||
"prefix": "%(check_system)s/%(check_partition)s/latest",
|
||||
"level": "info",
|
||||
"format": (
|
||||
"%(check_result)s,%(check_job_completion_time)s,"
|
||||
"%(check_info)s,%(check_jobid)s,"
|
||||
"%(check_num_tasks)s,%(check_num_cpus_per_task)s,%(check_num_tasks_per_node)s,"
|
||||
"%(check_perfvalues)s"
|
||||
),
|
||||
"format_perfvars": (
|
||||
"%(check_perf_value)s,%(check_perf_unit)s,"
|
||||
"%(check_perf_ref)s,%(check_perf_lower_thres)s,"
|
||||
"%(check_perf_upper_thres)s,"
|
||||
),
|
||||
"append": False,
|
||||
},
|
||||
],
|
||||
}
|
||||
],
|
||||
}
|
@@ -1,19 +0,0 @@
|
||||
#!/bin/bash
|
||||
#SBATCH --job-name=gprMax-benchmarks
|
||||
#SBATCH --time=24:0:0
|
||||
#SBATCH --ntasks=1
|
||||
#SBATCH --partition=serial
|
||||
#SBATCH --qos=serial
|
||||
#SBATCH --output=output/archer2/rfm_bench_%J.out
|
||||
|
||||
# Set the number of threads to 1
|
||||
# This prevents any threaded system libraries from automatically
|
||||
# using threading.
|
||||
export OMP_NUM_THREADS=1
|
||||
|
||||
source ../.venv/bin/activate
|
||||
|
||||
# Any commandline arguments provided will be passed to reframe
|
||||
reframe -C configuration/archer2_settings.py -c reframe_benchmarks.py -c base_tests.py -r --performance-report "$@"
|
||||
|
||||
sacct --format=JobID,State,Submit,Start,End,Elapsed,NodeList,ReqMem --units=M -j $SLURM_JOBID
|
@@ -1,24 +0,0 @@
|
||||
#!/bin/bash
|
||||
#SBATCH --job-name=gprMax-map
|
||||
#SBATCH --time=00:20:0
|
||||
#SBATCH --partition=standard
|
||||
#SBATCH --qos=short
|
||||
#SBATCH --nodes=1
|
||||
#SBATCH --ntasks=1
|
||||
#SBATCH --cpus-per-task=1
|
||||
#SBATCH --output=output/archer2/map_%J.out
|
||||
|
||||
# USAGE: sbatch -c [ompthreads] job_scripts/archer2_map_single_node.slurm [domain]
|
||||
|
||||
export OMP_NUM_THREADS=$SLURM_CPUS_PER_TASK
|
||||
export SRUN_CPUS_PER_TASK=$SLURM_CPUS_PER_TASK
|
||||
|
||||
module load arm/forge
|
||||
|
||||
source ../.venv/bin/activate
|
||||
|
||||
mkdir -p profile/archer2/
|
||||
|
||||
map -o="profile/archer2/gprMax_${1}d_${SLURM_CPUS_PER_TASK}t_$(date +%F_%H-%M)" --mpi=slurm --mpiargs="--hint=nomultithread --distribution=block:block" --profile python -m gprMax --log-level 25 src/benchmark_model_$1.in
|
||||
|
||||
sacct --format=JobID,State,Submit,Start,End,Elapsed,NodeList --units=M -j $SLURM_JOBID
|
@@ -1,18 +0,0 @@
|
||||
#!/bin/bash
|
||||
#SBATCH --job-name=gprMax-tests
|
||||
#SBATCH --time=24:0:0
|
||||
#SBATCH --ntasks=1
|
||||
#SBATCH --partition=serial
|
||||
#SBATCH --qos=serial
|
||||
#SBATCH --output=output/archer2/rfm_tests_%J.out
|
||||
|
||||
# Set the number of threads to 1
|
||||
# This prevents any threaded system libraries from automatically
|
||||
# using threading.
|
||||
export OMP_NUM_THREADS=1
|
||||
|
||||
source ../.venv/bin/activate
|
||||
|
||||
reframe -C configuration/archer2_settings.py -c reframe_tests.py -c base_tests.py -r "$@"
|
||||
|
||||
sacct --format=JobID,State,Submit,Start,End,Elapsed,NodeList --units=M -j $SLURM_JOBID
|
@@ -1,33 +0,0 @@
|
||||
import reframe as rfm
|
||||
from base_tests import GprMaxBaseTest
|
||||
from reframe.core.builtins import parameter, run_after
|
||||
|
||||
"""ReFrame tests for performance benchmarking
|
||||
|
||||
Usage:
|
||||
cd gprMax/tests
|
||||
reframe -C configuraiton/{CONFIG_FILE} -c reframe_benchmarks.py -c base_tests.py -r
|
||||
"""
|
||||
|
||||
|
||||
@rfm.simple_test
|
||||
class SingleNodeBenchmark(GprMaxBaseTest):
|
||||
tags = {"benchmark", "single node", "openmp"}
|
||||
|
||||
num_tasks = 1
|
||||
omp_threads = parameter([1, 2, 4, 8, 16, 32, 64, 128])
|
||||
domain = parameter([0.1, 0.15, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8])
|
||||
cpu_freq = parameter([2000000, 2250000])
|
||||
time_limit = "8h"
|
||||
|
||||
@run_after("init")
|
||||
def setup_env_vars(self):
|
||||
self.num_cpus_per_task = self.omp_threads
|
||||
self.env_vars["SLURM_CPU_FREQ_REQ"] = self.cpu_freq
|
||||
super().setup_env_vars()
|
||||
|
||||
@run_after("init")
|
||||
def set_model_file(self):
|
||||
input_file = f"benchmark_model_{self.domain}.in"
|
||||
self.executable_opts = [input_file]
|
||||
self.keep_files = [input_file]
|
@@ -1,64 +0,0 @@
|
||||
import reframe as rfm
|
||||
from base_tests import GprMaxRegressionTest
|
||||
from reframe.core.builtins import parameter, run_after
|
||||
|
||||
"""ReFrame tests for basic functionality
|
||||
|
||||
Usage:
|
||||
cd gprMax/tests
|
||||
reframe -C configuraiton/{CONFIG_FILE} -c reframe_tests.py -c base_tests.py -r
|
||||
"""
|
||||
|
||||
|
||||
@rfm.simple_test
|
||||
class TaskfarmTest(GprMaxRegressionTest):
|
||||
tags = {"test", "mpi", "taskfarm"}
|
||||
|
||||
model = parameter(["cylinder_Bscan_2D"])
|
||||
|
||||
num_mpi_tasks = parameter([8, 16])
|
||||
num_cpus_per_task = 16
|
||||
|
||||
@run_after("init")
|
||||
def setup_env_vars(self):
|
||||
self.num_tasks = self.num_mpi_tasks
|
||||
super().setup_env_vars()
|
||||
|
||||
@run_after("init")
|
||||
def set_filenames(self):
|
||||
self.input_file = f"{self.model}.in"
|
||||
self.output_file = f"{self.model}_merged.h5"
|
||||
self.executable_opts = [self.input_file, "-n", "64", "-taskfarm"]
|
||||
self.postrun_cmds = [
|
||||
f"python -m toolboxes.Utilities.outputfiles_merge {self.model}",
|
||||
f"python -m toolboxes.Plotting.plot_Bscan -save {self.output_file} Ez",
|
||||
]
|
||||
self.keep_files = [self.input_file, self.output_file, "{self.model}_merged.pdf"]
|
||||
|
||||
|
||||
@rfm.simple_test
|
||||
class BasicModelsTest(GprMaxRegressionTest):
|
||||
tags = {"test", "serial", "regression"}
|
||||
|
||||
# List of available basic test models
|
||||
model = parameter(
|
||||
[
|
||||
"2D_ExHyHz",
|
||||
"2D_EyHxHz",
|
||||
"2D_EzHxHy",
|
||||
"cylinder_Ascan_2D",
|
||||
"hertzian_dipole_fs",
|
||||
"hertzian_dipole_hs",
|
||||
"hertzian_dipole_dispersive",
|
||||
"magnetic_dipole_fs",
|
||||
]
|
||||
)
|
||||
num_cpus_per_task = 16
|
||||
|
||||
@run_after("init")
|
||||
def set_filenames(self):
|
||||
self.input_file = f"{self.model}.in"
|
||||
self.output_file = f"{self.model}.h5"
|
||||
self.executable_opts = [self.input_file, "-o", self.output_file]
|
||||
self.postrun_cmds = [f"python -m toolboxes.Plotting.plot_Ascan -save {self.output_file}"]
|
||||
self.keep_files = [self.input_file, self.output_file, f"{self.model}.pdf"]
|
二进制文件未显示。
二进制文件未显示。
二进制文件未显示。
二进制文件未显示。
二进制文件未显示。
二进制文件未显示。
二进制文件未显示。
二进制文件未显示。
二进制文件未显示。
二进制文件未显示。
@@ -1,8 +0,0 @@
|
||||
#title: 2D test Ex, Hy, Hz components
|
||||
#domain: 0.001 0.100 0.100
|
||||
#dx_dy_dz: 0.001 0.001 0.001
|
||||
#time_window: 3e-9
|
||||
|
||||
#waveform: gaussiandot 1 1e9 myWave
|
||||
#hertzian_dipole: x 0 0.050 0.050 myWave
|
||||
#rx: 0 0.070 0.070
|
@@ -1,8 +0,0 @@
|
||||
#title: 2D test Ey, Hx, Hz components
|
||||
#domain: 0.100 0.001 0.100
|
||||
#dx_dy_dz: 0.001 0.001 0.001
|
||||
#time_window: 3e-9
|
||||
|
||||
#waveform: gaussiandot 1 1e9 myWave
|
||||
#hertzian_dipole: y 0.050 0 0.050 myWave
|
||||
#rx: 0.070 0 0.070
|
@@ -1,8 +0,0 @@
|
||||
#title: 2D test Ez, Hx, Hy components
|
||||
#domain: 0.100 0.100 0.001
|
||||
#dx_dy_dz: 0.001 0.001 0.001
|
||||
#time_window: 3e-9
|
||||
|
||||
#waveform: gaussiandot 1 1e9 myWave
|
||||
#hertzian_dipole: z 0.050 0.050 0 myWave
|
||||
#rx: 0.070 0.070 0
|
@@ -1,7 +0,0 @@
|
||||
#title: Benchmark model
|
||||
#domain: 0.1 0.1 0.1
|
||||
#dx_dy_dz: 0.001 0.001 0.001
|
||||
#time_window: 3e-9
|
||||
|
||||
#waveform: gaussiandotnorm 1 900e6 myWave
|
||||
#hertzian_dipole: x 0.05 0.05 0.05 myWave
|
@@ -1,7 +0,0 @@
|
||||
#title: Benchmark model
|
||||
#domain: 0.15 0.15 0.15
|
||||
#dx_dy_dz: 0.001 0.001 0.001
|
||||
#time_window: 3e-9
|
||||
|
||||
#waveform: gaussiandotnorm 1 900e6 myWave
|
||||
#hertzian_dipole: x 0.075 0.075 0.075 myWave
|
@@ -1,7 +0,0 @@
|
||||
#title: Benchmark model
|
||||
#domain: 0.2 0.2 0.2
|
||||
#dx_dy_dz: 0.001 0.001 0.001
|
||||
#time_window: 3e-9
|
||||
|
||||
#waveform: gaussiandotnorm 1 900e6 myWave
|
||||
#hertzian_dipole: x 0.1 0.1 0.1 myWave
|
@@ -1,7 +0,0 @@
|
||||
#title: Benchmark model
|
||||
#domain: 0.3 0.3 0.3
|
||||
#dx_dy_dz: 0.001 0.001 0.001
|
||||
#time_window: 3e-9
|
||||
|
||||
#waveform: gaussiandotnorm 1 900e6 myWave
|
||||
#hertzian_dipole: x 0.15 0.15 0.15 myWave
|
@@ -1,7 +0,0 @@
|
||||
#title: Benchmark model
|
||||
#domain: 0.4 0.4 0.4
|
||||
#dx_dy_dz: 0.001 0.001 0.001
|
||||
#time_window: 3e-9
|
||||
|
||||
#waveform: gaussiandotnorm 1 900e6 myWave
|
||||
#hertzian_dipole: x 0.2 0.2 0.2 myWave
|
@@ -1,7 +0,0 @@
|
||||
#title: Benchmark model
|
||||
#domain: 0.5 0.5 0.5
|
||||
#dx_dy_dz: 0.001 0.001 0.001
|
||||
#time_window: 3e-9
|
||||
|
||||
#waveform: gaussiandotnorm 1 900e6 myWave
|
||||
#hertzian_dipole: x 0.25 0.25 0.25 myWave
|
@@ -1,7 +0,0 @@
|
||||
#title: Benchmark model
|
||||
#domain: 0.6 0.6 0.6
|
||||
#dx_dy_dz: 0.001 0.001 0.001
|
||||
#time_window: 3e-9
|
||||
|
||||
#waveform: gaussiandotnorm 1 900e6 myWave
|
||||
#hertzian_dipole: x 0.3 0.3 0.3 myWave
|
@@ -1,7 +0,0 @@
|
||||
#title: Benchmark model
|
||||
#domain: 0.7 0.7 0.7
|
||||
#dx_dy_dz: 0.001 0.001 0.001
|
||||
#time_window: 3e-9
|
||||
|
||||
#waveform: gaussiandotnorm 1 900e6 myWave
|
||||
#hertzian_dipole: x 0.35 0.35 0.35 myWave
|
@@ -1,7 +0,0 @@
|
||||
#title: Benchmark model
|
||||
#domain: 0.8 0.8 0.8
|
||||
#dx_dy_dz: 0.001 0.001 0.001
|
||||
#time_window: 3e-9
|
||||
|
||||
#waveform: gaussiandotnorm 1 900e6 myWave
|
||||
#hertzian_dipole: x 0.4 0.4 0.4 myWave
|
@@ -1,13 +0,0 @@
|
||||
#title: A-scan from a metal cylinder buried in a dielectric half-space
|
||||
#domain: 0.240 0.210 0.002
|
||||
#dx_dy_dz: 0.002 0.002 0.002
|
||||
#time_window: 3e-9
|
||||
|
||||
#material: 6 0 1 0 half_space
|
||||
|
||||
#waveform: ricker 1 1.5e9 my_ricker
|
||||
#hertzian_dipole: z 0.100 0.170 0 my_ricker
|
||||
#rx: 0.140 0.170 0
|
||||
|
||||
#box: 0 0 0 0.240 0.170 0.002 half_space
|
||||
#cylinder: 0.120 0.080 0 0.120 0.080 0.002 0.010 pec
|
@@ -1,15 +0,0 @@
|
||||
#title: B-scan from a metal cylinder buried in a dielectric half-space
|
||||
#domain: 0.240 0.210 0.002
|
||||
#dx_dy_dz: 0.002 0.002 0.002
|
||||
#time_window: 3e-9
|
||||
|
||||
#material: 6 0 1 0 half_space
|
||||
|
||||
#waveform: ricker 1 1.5e9 my_ricker
|
||||
#hertzian_dipole: z 0.040 0.170 0 my_ricker
|
||||
#rx: 0.080 0.170 0
|
||||
#src_steps: 0.002 0 0
|
||||
#rx_steps: 0.002 0 0
|
||||
|
||||
#box: 0 0 0 0.240 0.170 0.002 half_space
|
||||
#cylinder: 0.120 0.080 0 0.120 0.080 0.002 0.010 pec
|
@@ -1,12 +0,0 @@
|
||||
#title: Hertzian dipole in water
|
||||
#domain: 0.100 0.100 0.100
|
||||
#dx_dy_dz: 0.001 0.001 0.001
|
||||
#time_window: 3e-9
|
||||
|
||||
#waveform: gaussiandot 1 1e9 myWave
|
||||
#hertzian_dipole: z 0.050 0.050 0.050 myWave
|
||||
#rx: 0.070 0.070 0.070
|
||||
|
||||
#material: 4.9 0 1 0 myWater
|
||||
#add_dispersion_debye: 1 75.2 9.231e-12 myWater
|
||||
#box: 0 0 0 0.100 0.100 0.100 myWater
|
@@ -1,8 +0,0 @@
|
||||
#title: Hertzian dipole in free-space
|
||||
#domain: 0.100 0.100 0.100
|
||||
#dx_dy_dz: 0.001 0.001 0.001
|
||||
#time_window: 3e-9
|
||||
|
||||
#waveform: gaussiandot 1 1e9 myWave
|
||||
#hertzian_dipole: z 0.050 0.050 0.050 myWave
|
||||
#rx: 0.070 0.070 0.070
|
@@ -1,11 +0,0 @@
|
||||
#title: Hertzian dipole over a half-space
|
||||
#domain: 0.100 0.100 0.100
|
||||
#dx_dy_dz: 0.001 0.001 0.001
|
||||
#time_window: 3e-9
|
||||
|
||||
#waveform: gaussiandot 1 1e9 myWave
|
||||
#hertzian_dipole: z 0.050 0.050 0.050 myWave
|
||||
#rx: 0.070 0.070 0.070
|
||||
|
||||
#material: 8 0 1 0 half_space
|
||||
#box: 0 0 0 0.100 0.100 0.050 half_space
|
@@ -1,8 +0,0 @@
|
||||
#title: Magnetic dipole in free-space
|
||||
#domain: 0.100 0.100 0.100
|
||||
#dx_dy_dz: 0.001 0.001 0.001
|
||||
#time_window: 3e-9
|
||||
|
||||
#waveform: gaussiandot 1 1e9 myWave
|
||||
#magnetic_dipole: z 0.050 0.050 0.050 myWave
|
||||
#rx: 0.070 0.070 0.070
|
@@ -1,53 +0,0 @@
|
||||
import logging
|
||||
|
||||
import h5py
|
||||
import numpy as np
|
||||
|
||||
from gprMax.utilities.logging import logging_config
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
logging_config(name=__name__)
|
||||
|
||||
|
||||
FIELD_COMPONENTS_BASE_PATH = "/rxs/rx1/"
|
||||
|
||||
|
||||
def get_data_from_h5_file(h5_filepath):
|
||||
with h5py.File(h5_filepath, "r") as h5_file:
|
||||
# Get available field output component names and datatype
|
||||
field_components = list(h5_file[FIELD_COMPONENTS_BASE_PATH].keys())
|
||||
dtype = h5_file[FIELD_COMPONENTS_BASE_PATH + field_components[0]].dtype
|
||||
shape = h5_file[FIELD_COMPONENTS_BASE_PATH + str(field_components[0])].shape
|
||||
|
||||
# Arrays for storing field data
|
||||
if len(shape) == 1:
|
||||
data = np.zeros((h5_file.attrs["Iterations"], len(field_components)), dtype=dtype)
|
||||
else: # Merged B-scan data
|
||||
data = np.zeros((h5_file.attrs["Iterations"], len(field_components), shape[1]), dtype=dtype)
|
||||
for index, field_component in enumerate(field_components):
|
||||
data[:, index] = h5_file[FIELD_COMPONENTS_BASE_PATH + str(field_component)]
|
||||
if np.any(np.isnan(data[:, index])):
|
||||
logger.exception("Data contains NaNs")
|
||||
raise ValueError
|
||||
|
||||
max_time = (h5_file.attrs["Iterations"] - 1) * h5_file.attrs["dt"] / 1e-9
|
||||
time = np.linspace(0, max_time, num=h5_file.attrs["Iterations"])
|
||||
|
||||
return time, data
|
||||
|
||||
|
||||
def calculate_diffs(test_data, ref_data):
|
||||
diffs = np.zeros(test_data.shape, dtype=np.float64)
|
||||
for i in range(test_data.shape[1]):
|
||||
maxi = np.amax(np.abs(ref_data[:, i]))
|
||||
diffs[:, i] = np.divide(
|
||||
np.abs(ref_data[:, i] - test_data[:, i]), maxi, out=np.zeros_like(ref_data[:, i]), where=maxi != 0
|
||||
) # Replace any division by zero with zero
|
||||
|
||||
# Calculate power (ignore warning from taking a log of any zero values)
|
||||
with np.errstate(divide="ignore"):
|
||||
diffs[:, i] = 20 * np.log10(diffs[:, i])
|
||||
# Replace any NaNs or Infs from zero division
|
||||
diffs[:, i][np.invert(np.isfinite(diffs[:, i]))] = 0
|
||||
|
||||
return diffs
|
@@ -1,9 +0,0 @@
|
||||
import os
|
||||
|
||||
import reframe.utility.sanity as sn
|
||||
|
||||
|
||||
@sn.deferrable
|
||||
def path_join(*path):
|
||||
"""Deferable version of os.path.join"""
|
||||
return os.path.join(*path)
|
@@ -1,85 +0,0 @@
|
||||
import numpy as np
|
||||
from matplotlib import pyplot as plt
|
||||
|
||||
|
||||
def _plot_data(subplots, time, data, label=None, colour="r", line_style="-"):
|
||||
for i in range(data.shape[1]):
|
||||
subplots[i].plot(time, data[:, i], colour, lw=2, ls=line_style, label=label)
|
||||
|
||||
|
||||
def plot_dataset_comparison(test_time, test_data, ref_time, ref_data, model_name):
|
||||
fig, ((ex, hx), (ey, hy), (ez, hz)) = plt.subplots(
|
||||
nrows=3,
|
||||
ncols=2,
|
||||
sharex=False,
|
||||
sharey="col",
|
||||
subplot_kw=dict(xlabel="Time [ns]"),
|
||||
figsize=(20, 10),
|
||||
facecolor="w",
|
||||
edgecolor="w",
|
||||
)
|
||||
|
||||
subplots = [ex, ey, ez, hx, hy, hz]
|
||||
_plot_data(subplots, test_time, test_data, model_name)
|
||||
_plot_data(subplots, ref_time, ref_data, f"{model_name} (Ref)", "g", "--")
|
||||
|
||||
ylabels = [
|
||||
"$E_x$, field strength [V/m]",
|
||||
"$H_x$, field strength [A/m]",
|
||||
"$E_y$, field strength [V/m]",
|
||||
"$H_y$, field strength [A/m]",
|
||||
"$E_z$, field strength [V/m]",
|
||||
"$H_z$, field strength [A/m]",
|
||||
]
|
||||
|
||||
x_max = max(np.max(test_time), np.max(ref_time))
|
||||
for i, ax in enumerate(fig.axes):
|
||||
ax.set_ylabel(ylabels[i])
|
||||
ax.set_xlim(0, x_max)
|
||||
ax.grid()
|
||||
ax.legend()
|
||||
|
||||
return fig
|
||||
|
||||
|
||||
def plot_diffs(time, diffs, plot_min=-160):
|
||||
"""Plots ...
|
||||
|
||||
Args:
|
||||
time:
|
||||
diffs:
|
||||
plot_min: minimum value of difference to plot (dB). Default: -160
|
||||
|
||||
Returns:
|
||||
plt: matplotlib plot object.
|
||||
"""
|
||||
fig, ((ex, hx), (ey, hy), (ez, hz)) = plt.subplots(
|
||||
nrows=3,
|
||||
ncols=2,
|
||||
sharex=False,
|
||||
sharey="col",
|
||||
subplot_kw=dict(xlabel="Time [ns]"),
|
||||
figsize=(20, 10),
|
||||
facecolor="w",
|
||||
edgecolor="w",
|
||||
)
|
||||
_plot_data([ex, ey, ez, hx, hy, hz], time, diffs)
|
||||
|
||||
ylabels = [
|
||||
"$E_x$, difference [dB]",
|
||||
"$H_x$, difference [dB]",
|
||||
"$E_y$, difference [dB]",
|
||||
"$H_y$, difference [dB]",
|
||||
"$E_z$, difference [dB]",
|
||||
"$H_z$, difference [dB]",
|
||||
]
|
||||
|
||||
x_max = np.max(time)
|
||||
y_max = np.max(diffs)
|
||||
for i, ax in enumerate(fig.axes):
|
||||
ax.set_ylabel(ylabels[i])
|
||||
ax.set_xlim(0, x_max)
|
||||
ax.set_ylim(plot_min, y_max)
|
||||
ax.grid()
|
||||
|
||||
return fig
|
@@ -1,53 +0,0 @@
|
||||
import argparse
|
||||
import re
|
||||
from datetime import datetime
|
||||
from pathlib import Path
|
||||
|
||||
import matplotlib.pyplot as plt
|
||||
import pandas as pd
|
||||
|
||||
|
||||
def get_parameter(row, parameter):
|
||||
value = re.search(f"\s%{parameter}=(?P<value>\S+)\s", row["info"])["value"]
|
||||
return value
|
||||
|
||||
|
||||
def get_parameter_names(item):
|
||||
return re.findall(f"\s%(?P<name>\S+)=\S+", item)
|
||||
|
||||
|
||||
columns_to_keep = ["num_tasks", "num_cpus_per_task", "num_tasks_per_node", "run_time_value", "simulation_time_value"]
|
||||
|
||||
if __name__ == "__main__":
|
||||
# Parse command line arguments
|
||||
parser = argparse.ArgumentParser(
|
||||
usage="cd gprMax/tests; python -m utilities.process_perflog inputfile [-o OUTPUT]",
|
||||
description="Extract perfvars from reframe perflog file.",
|
||||
)
|
||||
parser.add_argument("inputfile", help="name of input file including path")
|
||||
parser.add_argument("--output", "-o", help="name of output file including path", required=False)
|
||||
|
||||
args = parser.parse_args()
|
||||
|
||||
perflog = pd.read_csv(args.inputfile, index_col=False)
|
||||
|
||||
# Extract recorded parameters and create a new column for them in the dataframe
|
||||
parameters = perflog["info"].agg(get_parameter_names).explode().unique()
|
||||
for parameter in parameters:
|
||||
perflog[parameter] = perflog.apply(get_parameter, args=[parameter], axis=1)
|
||||
|
||||
# Organise dataframe
|
||||
columns_to_keep += parameters.tolist()
|
||||
columns_to_keep.sort()
|
||||
perflog = perflog[columns_to_keep].sort_values(columns_to_keep)
|
||||
perflog["simulation_time_value"] = perflog["simulation_time_value"].apply(round, args=[2])
|
||||
perflog = perflog.rename(columns={"simulation_time_value": "simulation_time", "run_time_value": "run_time"})
|
||||
|
||||
# Save output to file
|
||||
if args.output:
|
||||
outputfile = args.output
|
||||
else:
|
||||
stem = f"{Path(args.inputfile).stem}_{datetime.today().strftime('%Y-%m-%d_%H-%M-%S')}"
|
||||
outputfile = Path("benchmarks", stem).with_suffix(".csv")
|
||||
perflog.to_csv(outputfile, index=False)
|
||||
print(f"Saved benchmark: '{outputfile}'")
|
在新工单中引用
屏蔽一个用户