Files
Fr0zkaandClaude Opus 5.5 046f2af495 wip(assembler): round L3 -- Core forces FP contraction off and refuses to generate if it can't
CoreNamespacePreamble.h applies per-compiler contraction-off pragmas (Clang, MSVC, GCC; unknown
compiler = #error) and a fused-multiply-add self-test that World::compile runs before building.
Clang -ffp-contract=on and GCC's default (fast) now reproduce the L1/Windows hashes (they diverged
in L2); Clang -ffp-contract=fast ignores the pragma and is refused at startup (negative control).
Seed sweep with every cube on real terrain: 48 seeds x 2 recipes x 3 builds x W1/W12, 576 runs,
0 mismatches, 0 empty meshes. Cost +0.5% (2.326 -> 2.337 s, interleaved). World unchanged.
MSVC/UBT not compiled here: Windows to-do list in Linux3/REPORT.md.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-19 18:51:07 +02:00

176 lines
9.5 KiB
Python

#!/usr/bin/env python3
"""Run the corrected L3 seed/compiler/worker matrix with per-seed mesh coverage."""
import csv
import re
import subprocess
import sys
import time
from pathlib import Path
ROOT = Path.cwd()
ROUND = ROOT / "Standalone/Research/WorldAssemblerM3/Linux3"
SEEDS = ROOT / "Standalone/Research/WorldAssemblerM3/Linux2/seeds.txt"
LOG_DIR = ROOT / "Saved/Linux"
MEASURE = ROOT / "Standalone/Research/WorldAssemblerM3/Linux2/MeasureProcess.py"
DATA = ROOT / "Standalone/data/owner_world.json"
BINARIES = {
"clang19-off": ROOT / "Standalone/bin/linux/VoxelForgeCoreHeadless-clang19-l3-off",
"clang19-on": ROOT / "Standalone/bin/linux/VoxelForgeCoreHeadless-clang19-l3-on",
"gcc14-default": ROOT / "Standalone/bin/linux/VoxelForgeCoreHeadless-gcc14-l3-default",
}
CAMERAS = {
"surface-world": "0,-35,-487.94,0,-22",
"floating-islands": "0,0,-32,0,-22",
}
HASH_RE = re.compile(
r"\[PipelineWholeViewHash\] tiles=(\d+) density=0x([0-9a-f]+) "
r"mesh=0x([0-9a-f]+) payload=0x([0-9a-f]+) topology=0x([0-9a-f]+)"
)
MESH_RE = re.compile(
r"\[PipelineMeshCoverage\] tiles=(\d+) nonempty_mesh_tiles=(\d+) indexed_triangles=(\d+)"
)
PLACEMENT_RE = re.compile(
r"\[SeedSurfacePlacement\].*camera_voxel=\(([-0-9.]+),([-0-9.]+),([-0-9.]+)\) status=PASS"
)
READY_RE = re.compile(r"\[StreamPipeline\].*whole_view_ready=([0-9.]+)s")
RESOURCE_RE = re.compile(
r"\[ProcessResources\] exit_code=(-?\d+) wall_s=([0-9.]+) peak_rss_kib=(\d+)"
)
def main() -> int:
if len(sys.argv) > 2:
raise SystemExit("usage: RunSeedSweep.py [budget-seconds; default 1800]")
budget = int(sys.argv[1]) if len(sys.argv) == 2 else 1800
seeds = [int(line.strip()) for line in SEEDS.read_text().splitlines() if line.strip()]
if len(seeds) != 48 or len(set(seeds)) != 48:
raise SystemExit("expected the 48 unique signed int32 L2 seeds")
missing = [str(path) for path in [MEASURE, DATA, *BINARIES.values()] if not path.is_file()]
if missing:
raise SystemExit("missing sweep input/build: " + ", ".join(missing))
LOG_DIR.mkdir(parents=True, exist_ok=True)
output_path = ROUND / "seed_mesh_coverage.csv"
fields = [
"seed", "recipe", "compiler_setting", "workers", "tiles",
"nonempty_mesh_tiles", "indexed_triangles", "camera_x_vox", "camera_y_vox", "camera_z_vox",
"density_hash", "mesh_hash", "payload_hash", "topology_hash",
"whole_view_ready_s", "wall_s", "peak_rss_kib", "exit_code", "status",
]
started = time.monotonic()
total = len(seeds) * len(CAMERAS) * len(BINARIES) * 2
print(f"L3 sweep: {len(seeds)} seeds x 2 recipes x 3 builds x W1/W12 = {total}; budget={budget}s", flush=True)
with output_path.open("w", newline="") as csv_file:
writer = csv.DictWriter(csv_file, fieldnames=fields)
writer.writeheader()
completed = 0
for seed in seeds:
for recipe, camera in CAMERAS.items():
for compiler, binary in BINARIES.items():
for workers in (1, 12):
remaining = budget - (time.monotonic() - started)
if remaining <= 0:
print("L3 sweep exceeded its 30-minute budget; stopping.", file=sys.stderr, flush=True)
return 124
stem = f"linux3-seed-{seed}-{recipe}-{compiler}-w{workers}"
log_path = LOG_DIR / f"{stem}.log"
args = [
str(binary), str(DATA), f"--seed={seed}", f"--recipe={recipe}",
"--render-distance-chunks=0", f"--workers={workers}",
"--world-assembler-prototype", "--stream-benchmark", "--stream-pipeline",
"--stream-hash", "--mesh-coverage", "--auto-surface-camera", "--force-generate",
"--clip-radius=1", "--max-clip-level=0", f"--camera={camera}",
"--far-horizon-lod8-step=0",
]
command = [
"taskset", "-c", "0-11", "prlimit", "--as=6442450944", "--",
"python3", str(MEASURE), *args,
]
with log_path.open("w") as log_file:
log_file.write("[SweepCommand] " + " ".join(command) + "\n")
log_file.flush()
try:
result = subprocess.run(
command, cwd=ROOT, stdout=log_file, stderr=subprocess.STDOUT,
timeout=min(900, max(1, remaining)), check=False,
)
exit_code = result.returncode
except subprocess.TimeoutExpired:
exit_code = 124
log_file.write("\n[SweepTimeout] row reached its allotted limit\n")
output = log_path.read_text(errors="replace")
hashes = HASH_RE.search(output)
mesh = MESH_RE.search(output)
placement = PLACEMENT_RE.search(output)
ready = READY_RE.search(output)
resources = RESOURCE_RE.search(output)
passed = bool(
exit_code == 0 and hashes and mesh and placement and ready and resources
and int(hashes.group(1)) == 27 and int(mesh.group(1)) == 27
and int(mesh.group(2)) > 0 and int(mesh.group(3)) > 0
and int(resources.group(1)) == 0
)
row = {
"seed": seed, "recipe": recipe, "compiler_setting": compiler, "workers": workers,
"tiles": mesh.group(1) if mesh else "",
"nonempty_mesh_tiles": mesh.group(2) if mesh else "",
"indexed_triangles": mesh.group(3) if mesh else "",
"camera_x_vox": placement.group(1) if placement else "",
"camera_y_vox": placement.group(2) if placement else "",
"camera_z_vox": placement.group(3) if placement else "",
"density_hash": "0x" + hashes.group(2) if hashes else "",
"mesh_hash": "0x" + hashes.group(3) if hashes else "",
"payload_hash": "0x" + hashes.group(4) if hashes else "",
"topology_hash": "0x" + hashes.group(5) if hashes else "",
"whole_view_ready_s": ready.group(1) if ready else "",
"wall_s": resources.group(2) if resources else "",
"peak_rss_kib": resources.group(3) if resources else "",
"exit_code": exit_code, "status": "PASS" if passed else "FAIL",
}
writer.writerow(row)
csv_file.flush()
completed += 1
print(
f"[{completed}/{total}] seed={seed} recipe={recipe} build={compiler} W{workers} "
f"nonempty={row['nonempty_mesh_tiles']}/27 triangles={row['indexed_triangles']} "
f"wall={row['wall_s']}s status={row['status']} elapsed={time.monotonic()-started:.1f}s",
flush=True,
)
if not passed:
print(f"Failed row log: {log_path}", file=sys.stderr, flush=True)
return exit_code or 1
rows = list(csv.DictReader(output_path.open(newline="")))
hash_columns = ("density_hash", "mesh_hash", "payload_hash", "topology_hash")
compiler_checks = []
worker_checks = []
for seed in seeds:
for recipe in CAMERAS:
for workers in (1, 12):
pair = [r for r in rows if int(r["seed"]) == seed and r["recipe"] == recipe
and int(r["workers"]) == workers]
compiler_checks.append(len(pair) == len(BINARIES)
and all(all(row[key] == pair[0][key] for key in hash_columns) for row in pair))
for compiler in BINARIES:
pair = [r for r in rows if int(r["seed"]) == seed and r["recipe"] == recipe
and r["compiler_setting"] == compiler]
worker_checks.append(len(pair) == 2
and all(all(row[key] == pair[0][key] for key in hash_columns) for row in pair))
elapsed = time.monotonic() - started
maximum_rss = max(int(row["peak_rss_kib"]) for row in rows)
empty_rows = sum(int(row["nonempty_mesh_tiles"]) == 0 or int(row["indexed_triangles"]) == 0 for row in rows)
summary = (
f"runs={len(rows)} seeds={len(seeds)} recipes={len(CAMERAS)} builds={len(BINARIES)} workers=1,12 "
f"cross_build_checks={len(compiler_checks)} cross_build_mismatches={sum(not x for x in compiler_checks)} "
f"worker_checks={len(worker_checks)} worker_mismatches={sum(not x for x in worker_checks)} "
f"empty_mesh_rows={empty_rows} max_peak_rss_kib={maximum_rss} elapsed_s={elapsed:.3f}\n"
)
(ROUND / "seed_mesh_coverage_summary.txt").write_text(summary)
print(summary, end="", flush=True)
return 0 if all(compiler_checks) and all(worker_checks) and empty_rows == 0 and elapsed <= budget else 3
if __name__ == "__main__":
raise SystemExit(main())