#!/usr/bin/env python3 """Collect final-stamp cave, candidate, proof, and startup counters by stratum.""" from __future__ import annotations import json import re import subprocess import time from collections import defaultdict from pathlib import Path ROOT = Path(__file__).resolve().parents[4] OUT = ROOT / "Saved/Linux/l135" BIN = OUT / "bin/VoxelForgeCoreHeadless-clang-l135" DATA = ROOT / "Standalone/data/owner_world.json" STAMP = "8dc4294ce0250a591ee4515471c3c547e796ffa4346ab44f0ae1740bbc3797f5" CAMERAS = { 0: (8.0, 16.0, -372.2626953125), 1: (25.8369140625, 3.19921875, -737.0), 2: (19.166015625, -14.2001953125, -753.3740234375), 3: (-20.0625, -5.068359375, -900.353515625), } STAMP_RE = re.compile(r"^\[VoxelForgeSourceStamp\] sha256=([0-9a-f]+)$", re.M) PLAN_RE = re.compile(r"^\[WorldAssemblerPlanTiming\] total_ms=([0-9.]+) status=([^ ]+)$", re.M) CAVE_RE = re.compile(r"^\[CavernPlannerV1\].* plan_ms=([0-9.]+) status=([^ ]+)$", re.M) TILE_RE = re.compile(r"^\[WorldAssemblerTilePipeline\] (.*)$", re.M) CLASS_RE = re.compile(r"^\[WorldAssemblerLODClassification\] (.*)$", re.M) COMPOSER_RE = re.compile(r"^\[PassageComposerTile\] (.*)$", re.M) FIELDS_RE = re.compile(r"([a-zA-Z0-9_]+)=([^ ]+)") def fields(line: str) -> dict[str, str]: return dict(FIELDS_RE.findall(line)) def main() -> int: if not BIN.is_file() or not DATA.is_file(): raise SystemExit("missing L135 profile binary or owner fixture") rows = [] for strate, xyz in CAMERAS.items(): camera = ",".join(f"{value:.12f}" for value in xyz) + ",0,0" log = OUT / f"profile-final-speed2-s{strate}.log" command = ["taskset", "-c", "0-11", "prlimit", "--as=6442450944", "--", "timeout", "1740s", str(BIN), str(DATA), "--world-assembler-prototype", "--stream-benchmark", "--stream-pipeline", "--workers=8", "--clip-radius=3", "--max-clip-level=8", "--max-level=8", f"--camera={camera}", "--profile-lod-work", "--profile-passage-composer", "--stream-scheduler-policy=3"] started = time.monotonic() with log.open("w", encoding="utf-8") as output: result = subprocess.run(command, cwd=ROOT, stdout=output, stderr=subprocess.STDOUT, check=False, timeout=1740) content = log.read_text(encoding="utf-8", errors="replace") found_stamp = STAMP_RE.search(content) if result.returncode or found_stamp is None or found_stamp.group(1) != STAMP: raise SystemExit(f"final-stamp profile failed: {log}, exit={result.returncode}") plan, cave = PLAN_RE.search(content), CAVE_RE.search(content) tile = TILE_RE.search(content) if plan is None or cave is None or tile is None: raise SystemExit(f"profile counters missing: {log}") aggregate = defaultdict(lambda: defaultdict(int)) for match in CLASS_RE.finditer(content): v = fields(match.group(1)); lod = int(v["lod"]) for key in ("tiles", "tile_skips", "density_point_calls", "field_eval_sample_points", "proof_air_cells", "proof_solid_cells"): aggregate[lod][key] = int(v.get(key, "0")) aggregate[lod]["field_eval_ms_est"] = float(v.get("field_eval_ms_est", "0")) for match in COMPOSER_RE.finditer(content): v = fields(match.group(1)); lod = int(v["key"].split("lod", 1)[1].rstrip(")")) aggregate[lod]["composer_tiles"] += 1 for key in ("samples", "native_cave_samples", "room_candidates", "edge_candidates", "features", "route_candidates", "passage_iterations"): aggregate[lod][key] += int(v.get(key, "0")) aggregate[lod]["composer_worker_ms"] += float(v.get("worker_ms", "0")) for lod, values in aggregate.items(): calls = values.get("density_point_calls", 0) values["field_eval_ns_per_density_call_est"] = round( values.get("field_eval_ms_est", 0.0) * 1.0e6 / calls, 1) if calls else None composer_tiles = values.get("composer_tiles", 0) values["room_candidates_per_composer_tile"] = round( values.get("room_candidates", 0) / composer_tiles, 3) if composer_tiles else None values["edge_candidates_per_composer_tile"] = round( values.get("edge_candidates", 0) / composer_tiles, 3) if composer_tiles else None tile_fields = fields(tile.group(1)) tile_summary = {} for key, value in tile_fields.items(): try: tile_summary[key] = int(value) except ValueError: try: tile_summary[key] = float(value) except ValueError: continue row = {"strate": strate, "source_stamp": found_stamp.group(1), "world_assembler_plan_ms": float(plan.group(1)), "cavern_planner_ms": float(cave.group(1)), "tile_pipeline": tile_summary, "lod": {str(k): dict(v) for k, v in sorted(aggregate.items())}, "wall_s": round(time.monotonic() - started, 3), "log": str(log.relative_to(ROOT))} rows.append(row) print("[L135ProfileRun] " + json.dumps(row, sort_keys=True), flush=True) summary = {"status": "PASS", "source_stamp": STAMP, "strata": rows, "field_eval_ns_per_density_call_note": "Estimate includes all shape-field density calls at this view, not native-cave-exclusive time.", "tile_skip_note": "tile_pipeline.whole_tile_skips and lod.tile_skips are aggregate classifiers; they are not cave-only attribution."} (OUT / "profile-summary-speed2.json").write_text( json.dumps(summary, indent=2) + "\n", encoding="utf-8") print("[L135ProfileSummary] strata=4 status=PASS") return 0 if __name__ == "__main__": raise SystemExit(main())