Files
VoxelForge/Standalone/Research/WorldAssemblerM3/Linux37/RunDeterminismL37.py
T
Fr0zkaandClaude Opus 5.5 5e2fc53d39 planner: four-strate owner plan spawns (L66); pinned 2-strate regression fixture
- Core caps each passage mouth reach to its own strate's usable content band (owner
  DA_Strate1 exports ReachMax=5000 owner voxels, which put the SW->FI lower mouth 79.5 m
  below FI, inside TN).
- Unreal adapter: SW route search keeps the old 64 m candidates first, then a bounded
  single-mouth search with shorter lengths; logs candidate/rejection counts.
- Internal-chain passage floor/support tweaks (only with >2 strates): ripple 1-2 4.78->2.90 cm,
  2-3 3.57->0.10 cm. Interfaces still 0/3 walkable (59/3/2 unsupported).
- verify.py: legacy tiers use Standalone/data/regression/owner_world_2strate_l61.json; new
  four-strate stage reads its expectations from owner_world.json (currently red on interfaces).
- Unreal trace L14 vs HEAD, same assets (16-chunk FlatPlain): 12.20 vs 12.56 worker-s; no x2.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016dhxM43dnWvUu2B5Ph1iG1
2026-10-26 22:13:22 +01:00

122 lines
5.3 KiB
Python

#!/usr/bin/env python3
"""Check L25, 24 m crossing and upper-SW fixture determinism for L37."""
import csv
import os
import re
import subprocess
import time
from pathlib import Path
ROOT = Path(__file__).resolve().parents[4]
OUT = ROOT / "Saved/Linux/l37"
OWNER = Path(os.environ.get("VOXELFORGE_OWNER_DATA",
ROOT / "Standalone/data/owner_world.json"))
FIXTURE = ROOT / "Saved/Linux/l33/fixtures/sw-upper-tunnel-network-style0.json"
BINARIES = {
"clang": OUT / "bin/VoxelForgeCoreHeadless-l37-final-clang",
"gcc": OUT / "bin/VoxelForgeCoreHeadless-l37-final-gcc",
}
HASH = re.compile(r"^\[Pipeline(?:FullDetailHash|WholeViewHash|LODHash|ExactQueryHash)\].*$", re.M)
STAMP = re.compile(
r"^\[WorldAssemblerRecipeAudit\] requested=([^ ]+) actual=([^ ]+).*status=([^ ]+)$", re.M)
LAYOUT = re.compile(
r"^\[ResolvedLayoutSnapshot\] schema=\d+ stable_identity=([^ ]+) strata=\d+ bytes=\d+ round_trip=PASS$",
re.M)
PLAN = re.compile(
r"^\[WorldAssemblerPlanSerialization\].*canonical_round_trip=true .*"
r"plan_hash=([0-9a-f]+) manifest_hash=([0-9a-f]+) status=PASS$", re.M)
ROUTE = re.compile(
r"^\[WorldAssemblerRouteAccepted\] arrival_xy_m=\([^)]*\) "
r"departure_xy_m=\([^)]*\) endpoint_proximity_cost=\d+ average_grade_q16=\d+$", re.M)
rows = []
failed = False
references = {}
def run(kind, recipe, compiler, workers, data, passage_audit=False, crossing=False):
global failed
binary = BINARIES[compiler]
name = f"determinism-{kind}-{compiler}-{recipe}-w{workers}"
if kind == "upper-fixture":
name = f"determinism-upper-fixture-{compiler}-w{workers}"
log = OUT / f"{name}.log"
command = [
"taskset", "-c", "0-11", "prlimit", "--as=6442450944", "--",
"timeout", "1800s", str(binary), str(data), f"--workers={workers}",
"--world-assembler-prototype", "--stream-benchmark", "--stream-pipeline",
"--force-generate", "--clip-radius=3", "--max-clip-level=8", "--max-level=-1",
f"--recipe={recipe}",
]
if passage_audit:
command.append("--audit-resolved-layout-passages")
else:
command.append("--stream-hash")
if crossing:
command.extend(("--camera-step=24,0,0", "--region-crossing"))
started = time.monotonic()
try:
with log.open("w", encoding="utf-8") as stream:
result = subprocess.run(command, cwd=ROOT, stdout=stream,
stderr=subprocess.STDOUT, timeout=1800, check=False)
except subprocess.TimeoutExpired:
result = None
elapsed = time.monotonic() - started
output = log.read_text(encoding="utf-8", errors="replace")
stamps = STAMP.findall(output)
stamp_ok = stamps == [(recipe, recipe, "PASS")]
if passage_audit:
signature = (tuple(LAYOUT.findall(output)), tuple(PLAN.findall(output)),
tuple(ROUTE.findall(output)))
expected = references.get((kind, recipe))
stable = expected is None or signature == expected
if expected is None and all(signature):
references[(kind, recipe)] = signature
valid = (result is not None and result.returncode == 0 and stamp_ok
and len(signature[0]) == len(signature[1]) == len(signature[2]) == 1
and re.search(r"^\[ResolvedPassageAuditSummary\].*status=PASS$", output, re.M)
and re.search(r"^\[PassageRippleAuditSummary\].*status=PASS$", output, re.M)
and stable)
hashes = ()
detail = f"layout={signature[0][0] if signature[0] else 'MISSING'} stable={stable}"
else:
hashes = tuple(HASH.findall(output))
key = (kind, recipe)
expected = references.get(key)
stable = expected is None or hashes == expected
if expected is None and hashes:
references[key] = hashes
valid = (result is not None and result.returncode == 0 and stamp_ok
and "hash=on" in output and len(hashes) == 12 and stable)
detail = f"hashes={len(hashes)}/12 stable={stable}"
code = result.returncode if result is not None else "TIMEOUT"
rows.append((kind, recipe, compiler, workers, elapsed, code, valid))
failed |= not valid
print(f"[L37DeterminismRun] kind={kind} recipe={recipe} compiler={compiler} "
f"workers={workers} elapsed={elapsed:.1f}s {detail} "
f"{'PASS' if valid else 'FAIL'} log={log}", flush=True)
for kind in ("l25", "crossing24"):
for recipe in ("surface-world", "floating-islands"):
for compiler in BINARIES:
for workers in (1, 8, 12):
run(kind, recipe, compiler, workers, OWNER,
crossing=(kind == "crossing24"))
for compiler in BINARIES:
for workers in (1, 8, 12):
run("upper-fixture", "floating-islands", compiler, workers, FIXTURE,
passage_audit=True)
summary = OUT / "determinism-l37.csv"
with summary.open("w", newline="", encoding="utf-8") as stream:
writer = csv.writer(stream)
writer.writerow(("kind", "recipe", "compiler", "workers", "elapsed_seconds",
"exit_code", "status"))
for row in rows:
writer.writerow((*row[:-1], "PASS" if row[-1] else "FAIL"))
print(f"[L37DeterminismSummary] runs={len(rows)} pass={sum(row[-1] for row in rows)} "
f"fail={sum(not row[-1] for row in rows)} summary={summary}", flush=True)
raise SystemExit(1 if failed or len(rows) != 30 else 0)