124def build(name, configuration, arguments, directory):
125 """! Generate and compile one configuration. Returns the wall time or None if it failed."""
127 [
"python3", os.path.join(HERE,
"single-black-hole.py")]
128 + shlex.split(configuration)
130 "--variant", arguments.variant,
131 "--verbosity",
"text",
132 "--output-directory", directory,
133 "--peano-directory", arguments.peano_directory,
135 + shlex.split(arguments.extra_arguments)
138 with open(os.path.join(directory,
"build.log"),
"w")
as log:
139 result = subprocess.run(command, stdout=log, stderr=subprocess.STDOUT)
140 return time.time() - start
if result.returncode == 0
else None
143def run(arguments, directory, threads, repetition):
144 """! Run the executable once. Returns (exit code, wall time)."""
145 environment = dict(os.environ)
147 environment[
"OMP_NUM_THREADS"] = str(threads)
148 log_name = f
"run-{threads}-threads-{repetition}.log"
150 with open(os.path.join(directory, log_name),
"w")
as log:
152 result = subprocess.run(
153 [
"./single-black-hole"],
157 stderr=subprocess.STDOUT,
158 timeout=arguments.timeout,
160 exit_code = result.returncode
161 except subprocess.TimeoutExpired:
162 exit_code =
"timeout"
163 return exit_code, time.time() - start, log_name
167 """! Metrics Peano's step report writes at the end of a run
169 Returns the seconds of the setup, the seconds spent in all time stepping
170 sweeps, the number of sweeps, and the final time stamp. Entries are None
171 if the run did not get that far.
173 setup = sweeps = sweep_seconds = final_time =
None
174 with open(path, errors=
"replace")
as log:
176 match = re.search(
r"reportFinalResults\(\)\s+info\s+(\w+): ([0-9.e+-]+)s\s+\(avg=([0-9.e+-]+),#measurements=(\d+)", line)
178 if match.group(1) ==
"SetupSimulation":
179 setup = float(match.group(2))
180 elif match.group(1) ==
"TimeStep":
181 sweeps = int(match.group(4))
182 sweep_seconds = float(match.group(3)) * sweeps
183 match = re.search(
r"t=([0-9.e+-]+), new dt=", line)
185 final_time = float(match.group(1))
186 return setup, sweep_seconds, sweeps, final_time
191 study = SchemeStudy
if arguments.study ==
"schemes" else PerformanceStudy
192 if arguments.only
is not None:
193 unknown = set(arguments.only) - set(study)
195 raise SystemExit(f
"Unknown configurations {sorted(unknown)}, available: {sorted(study)}")
196 study = {name: study[name]
for name
in arguments.only}
198 if arguments.dry_run:
199 for name, configuration
in study.items():
200 print(f
"{name}: single-black-hole.py {configuration} --variant {arguments.variant}")
203 os.makedirs(arguments.work_directory, exist_ok=
True)
204 result_file = os.path.join(arguments.work_directory, f
"results-{arguments.study}.csv")
205 with open(result_file,
"w", newline=
"")
as handle:
206 writer = csv.writer(handle)
208 [
"name",
"arguments",
"threads",
"repetition",
"build_seconds",
"exit_code",
"run_seconds",
209 "setup_seconds",
"time_stepping_seconds",
"sweeps",
"final_time",
"log"]
211 for name, configuration
in study.items():
212 directory = os.path.abspath(os.path.join(arguments.work_directory, name))
213 os.makedirs(directory, exist_ok=
True)
215 if arguments.skip_build:
218 print(f
"Build {name}")
219 build_seconds =
build(name, configuration, arguments, directory)
220 if build_seconds
is None:
221 print(f
" build failed, see {directory}/build.log")
222 writer.writerow([name, configuration,
"",
"",
"",
"build failed",
"",
"",
"",
"",
"",
"build.log"])
225 for threads
in arguments.threads:
226 for repetition
in range(arguments.repetitions):
227 print(f
"Run {name}, {threads} threads, repetition {repetition}")
228 exit_code, run_seconds, log_name =
run(arguments, directory, threads, repetition)
229 print(f
" exit code {exit_code}, {run_seconds:.1f}s")
230 metrics =
parse_log(os.path.join(directory, log_name))
232 [name, configuration, threads, repetition, f
"{build_seconds:.1f}",
233 exit_code, f
"{run_seconds:.1f}", *metrics, log_name]
236 print(f
"Wrote {result_file}")