SDDS ToolKit Programs and Libraries for C and Python
Loading...
Searching...
No Matches
benchmark_gate.py
1#!/usr/bin/env python3
2"""Run the representative C/C++ numeric benchmark and enforce the release gate."""
3
4import json
5import statistics
6import subprocess
7import sys
8from pathlib import Path
9
10
11def run(program: Path, mode: str, path: Path) -> dict:
12 completed = subprocess.run(
13 [str(program), mode, str(path)], check=True, capture_output=True, text=True
14 )
15 return json.loads(completed.stdout)
16
17
18def median_result(runs: list[dict]) -> dict:
19 return {
20 "seconds": statistics.median(item["seconds"] for item in runs),
21 "peak_kib": statistics.median(item["peak_kib"] for item in runs),
22 }
23
24
25def main() -> int:
26 if len(sys.argv) != 3:
27 return 2
28 program = Path(sys.argv[1]).resolve()
29 data = Path(sys.argv[2]).resolve()
30 c_runs = []
31 cpp_runs = []
32 for iteration in range(5):
33 if iteration % 2:
34 cpp_runs.append(run(program, "cpp-full", data))
35 c_runs.append(run(program, "c-full", data))
36 else:
37 c_runs.append(run(program, "c-full", data))
38 cpp_runs.append(run(program, "cpp-full", data))
39 c_result = median_result(c_runs)
40 cpp_result = median_result(cpp_runs)
41 c_write_runs = []
42 cpp_write_runs = []
43 for iteration in range(5):
44 if iteration % 2:
45 cpp_write_runs.append(run(program, "cpp-write", data.parent / "gate-cpp-write.sdds"))
46 c_write_runs.append(run(program, "c-write", data.parent / "gate-c-write.sdds"))
47 else:
48 c_write_runs.append(run(program, "c-write", data.parent / "gate-c-write.sdds"))
49 cpp_write_runs.append(run(program, "cpp-write", data.parent / "gate-cpp-write.sdds"))
50 c_write = median_result(c_write_runs)
51 cpp_write = median_result(cpp_write_runs)
52 read_throughput_ratio = c_result["seconds"] / cpp_result["seconds"]
53 read_memory_ratio = cpp_result["peak_kib"] / max(c_result["peak_kib"], 1)
54 write_throughput_ratio = c_write["seconds"] / cpp_write["seconds"]
55 write_memory_ratio = cpp_write["peak_kib"] / max(c_write["peak_kib"], 1)
56 report = {
57 "c": c_result,
58 "cpp": cpp_result,
59 "c_write": c_write,
60 "cpp_write": cpp_write,
61 "cpp_read_throughput_ratio": read_throughput_ratio,
62 "cpp_read_peak_memory_ratio": read_memory_ratio,
63 "cpp_write_throughput_ratio": write_throughput_ratio,
64 "cpp_write_peak_memory_ratio": write_memory_ratio,
65 "throughput_gate": 0.85,
66 "memory_gate": 1.25,
67 }
68 print(json.dumps(report, indent=2, sort_keys=True))
69 return 0 if (read_throughput_ratio >= 0.85 and write_throughput_ratio >= 0.85 and
70 read_memory_ratio <= 1.25 and write_memory_ratio <= 1.25) else 1
71
72
73if __name__ == "__main__":
74 raise SystemExit(main())