| 333 | |
| 334 | |
| 335 | def main(): |
| 336 | parser = argparse.ArgumentParser() |
| 337 | parser.add_argument("--binary", action="append", required=True, help="MODE=/absolute/path/to/release/atomic") |
| 338 | parser.add_argument("--output", type=pathlib.Path, required=True) |
| 339 | parser.add_argument("--repeats", type=int, default=5) |
| 340 | parser.add_argument("--payload-bytes", type=int, default=1024) |
| 341 | parser.add_argument("--scenarios", nargs="+", choices=SCENARIOS, default=[s for s in SCENARIOS if s != "frame-boundary"]) |
| 342 | args = parser.parse_args() |
| 343 | assert hasattr(socket, "AF_UNIX"), "this driver currently supports Unix sockets" |
| 344 | binaries = dict(pair.split("=", 1) for pair in args.binary) |
| 345 | binaries = {mode: pathlib.Path(path).resolve() for mode, path in binaries.items()} |
| 346 | assert args.repeats > 0 and args.payload_bytes > 0 |
| 347 | metadata = {"platform": platform.platform(), "python": platform.python_version(), |
| 348 | "started_at": time.strftime("%Y-%m-%dT%H:%M:%S%z"), |
| 349 | "payload_output_bytes": args.payload_bytes, "repeats": args.repeats, |
| 350 | "blake3_version": blake3.__version__, |
| 351 | "binaries": {m: {"path": str(p), "sha256": hashlib.sha256(p.read_bytes()).hexdigest()} for m, p in binaries.items()}} |
| 352 | if platform.system() == "Darwin": |
| 353 | metadata["hardware"] = subprocess.check_output(["sysctl", "machdep.cpu.brand_string", "hw.logicalcpu", "hw.memsize"], text=True) |
| 354 | result = {"metadata": metadata, "measurements": []} |
| 355 | args.output.parent.mkdir(parents=True, exist_ok=True) |
| 356 | for repeat in range(args.repeats): |
| 357 | modes = list(binaries) |
| 358 | modes = modes[repeat % len(modes):] + modes[:repeat % len(modes)] |
| 359 | for name in args.scenarios: |
| 360 | for mode in modes: |
| 361 | case = measure_case(binaries[mode], name, SCENARIOS[name], args.payload_bytes) |
| 362 | case.update(mode=mode, repeat=repeat) |
| 363 | result["measurements"].append(case) |
| 364 | result["summary"] = summarize(result["measurements"]) |
| 365 | args.output.write_text(json.dumps(result, indent=2) + "\n") |
| 366 | print(json.dumps({"repeat": repeat, "mode": mode, "scenario": name, |
| 367 | "events_s": [round(t["events_s"], 1) for t in case["turns"]], |
| 368 | "checkpoint_ms": [round(t["checkpoint_ms"], 1) for t in case["turns"]], |
| 369 | "checkpoint_ok": [t["checkpoint_ok"] for t in case["turns"]]}), flush=True) |
| 370 | |
| 371 | |
| 372 | if __name__ == "__main__": |