#!/usr/bin/env python3 """Run the L17 deterministic W1/W8/W12 x5 matrix on both supported Linux builds.""" import os import re import signal import subprocess import sys import time from pathlib import Path ROOT = Path(__file__).resolve().parents[4] OUT = ROOT / "Saved/Linux/l17-matrix" OUT.mkdir(parents=True, exist_ok=True) if not os.sched_getaffinity(0).issubset(set(range(12))): raise SystemExit("run under taskset -c 0-11") BINARIES = { "clang-off": ROOT / "Standalone/bin/linux/VoxelForgeCoreHeadless-linux17-final-clang", "gcc-default": ROOT / "Standalone/bin/linux/VoxelForgeCoreHeadless-linux17-final-gcc", } RECIPES = { "floating-islands": "-10,-31,-22,0,-8", "surface-world": "0,-35,-75,0,0", } HASH_PATTERNS = { "full": re.compile(r"^\[PipelineFullDetailHash\].*$", re.M), "whole": re.compile(r"^\[PipelineWholeViewHash\].*$", re.M), "lod": re.compile(r"^\[PipelineLODHash\].*$", re.M), "exact": re.compile(r"^\[PipelineExactQueryHash\].*$", re.M), } rows = [] all_pass = True for recipe, camera in RECIPES.items(): for compiler, binary in BINARIES.items(): if not binary.exists(): raise SystemExit(f"missing binary: {binary}") for workers, repeat in [(1, 1), (8, 1), (12, 1), (12, 2), (12, 3), (12, 4), (12, 5)]: name = f"{recipe}-{compiler}-w{workers}-r{repeat}" logfile = OUT / f"{name}.log" command = ["prlimit", "--as=6442450944", "--", str(binary), str(ROOT / "Standalone/data/owner_world.json"), "--world-assembler-prototype", "--stream-benchmark", "--stream-pipeline", "--stream-hash", "--force-generate", "--clip-radius=3", "--max-clip-level=8", f"--workers={workers}", f"--camera={camera}", f"--recipe={recipe}"] started = time.monotonic() peak_rss_kib = 0 with logfile.open("w", encoding="utf-8") as stream: process = subprocess.Popen(command, stdout=stream, stderr=subprocess.STDOUT, start_new_session=True) while process.poll() is None: pending = [process.pid] seen = set() while pending: pid = pending.pop() if pid in seen: continue seen.add(pid) try: children = Path(f"/proc/{pid}/task/{pid}/children").read_text().split() pending.extend(int(value) for value in children) for line in Path(f"/proc/{pid}/status").read_text().splitlines(): if line.startswith("VmRSS:"): peak_rss_kib = max(peak_rss_kib, int(line.split()[1])) break except (FileNotFoundError, PermissionError, ProcessLookupError, ValueError): pass if time.monotonic() - started > 900: os.killpg(process.pid, signal.SIGTERM) try: process.wait(timeout=5) except subprocess.TimeoutExpired: os.killpg(process.pid, signal.SIGKILL) process.wait() all_pass = False break time.sleep(0.1) code = process.wait() elapsed = time.monotonic() - started output = logfile.read_text(encoding="utf-8", errors="replace") matched = {key: pattern.findall(output) for key, pattern in HASH_PATTERNS.items()} ok = code == 0 and all(matched.values()) and len(matched["lod"]) == 9 if not ok: all_pass = False row = {"recipe": recipe, "compiler": compiler, "workers": workers, "repeat": repeat, "exit": code, "seconds": elapsed, "peak_rss_kib": peak_rss_kib, "ok": ok, "full": matched["full"][-1] if matched["full"] else "", "whole": matched["whole"][-1] if matched["whole"] else "", "lod": " || ".join(matched["lod"]), "exact": matched["exact"][-1] if matched["exact"] else ""} rows.append(row) print(f"[MatrixRun] {name} exit={code} seconds={elapsed:.3f} " f"peak_rss_kib={peak_rss_kib} hash_rows={sum(map(len,matched.values()))} " f"status={'PASS' if ok else 'FAIL'}", flush=True) summary = OUT / "summary.tsv" columns = ["recipe", "compiler", "workers", "repeat", "exit", "seconds", "peak_rss_kib", "ok", "full", "whole", "lod", "exact"] with summary.open("w", encoding="utf-8") as f: f.write("\t".join(columns) + "\n") for row in rows: f.write("\t".join(str(row[key]) for key in columns) + "\n") for recipe in RECIPES: reference = None for row in rows: if row["recipe"] != recipe: continue signature = (row["full"], row["whole"], row["lod"], row["exact"]) if reference is None: reference = signature elif signature != reference: print(f"[MatrixMismatch] recipe={recipe} workers={row['workers']} " f"compiler={row['compiler']} repeat={row['repeat']}", flush=True) all_pass = False print(f"[MatrixSummary] rows={len(rows)} expected=28 result={'PASS' if all_pass else 'FAIL'} " f"path={summary}", flush=True) raise SystemExit(0 if all_pass and len(rows) == 28 else 1)