passages: prepared per-segment data + per-column XY projection cache (L98, exact)

Per-world prepared chord/length/radius/Catmull-Rom/floor-profile data (310 segments, ~66 KB,
<0.04 ms); same expression grouping, divisions and square roots, so output is bit-identical
(zero density/tile mismatches, Clang vs GCC equal). No measurable readiness gain - the cost is
the number of samples running passage work, not per-sample arithmetic. Note: the report's
world labels are shifted by one row (the 2,850-tile row is SurfaceWorld). Fast tier PASS;
Linux UE host builds.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016dhxM43dnWvUu2B5Ph1iG1
This commit is contained in:
Fr0zkaandClaude Opus 5.5 committed 2026-10-28 12:50:19 +01:00
1 parent 9d9504ae4e
commit 36140b573f
7 files changed
+1087 -180

No files matched your search

@@ -0,0 +1,61 @@
# L98 — exact passage building blocks
## Changes and work counts
Passage setup now prepares per-segment chord endpoints/deltas, squared lengths, radii, Catmull–Rom inputs, and floor-profile samples once per world. Capsule-route and mouth-support callbacks also use prepared segment endpoints and deltas. The scalar expression grouping, divisions, and square roots remain in the same order. Relief interpolation sharing was not added.
Measured preparation per world: 310 passage segments, 313 floor samples, and 32 capsule-route segments; the trace reports 66,296 bytes. The 32 mouth-route segments report another 4,608 bytes. Preparation measured 0.025–0.040 ms in the whole-view hash runs (mouth preparation rounded to 0.000 ms).
The streamed-view counters below are prepared-data reads/uses, not baseline arithmetic counts. They directly confirm the prepared paths were exercised. Avoided recomputations are inferred from the replaced per-sample expressions; the old arithmetic was not separately instrumented.
| World | Floor-profile reads | Carve uses | Support/tread uses | Capsule uses | Mouth-support uses |
|---|---:|---:|---:|---:|---:|
| FI | 129,382,181 | 8,255,393 | 5,131,690 | 2,693,464 | 14,773,980 |
| TN | 396,540,009 | 50,346,149 | 19,176,668 | 11,657,176 | 63,632,356 |
| SW | 318,412,931 | 50,093,885 | 17,065,041 | 10,323,467 | 60,102,531 |
| VS | 99,874,533 | 5,141,277 | 3,142,836 | 662,072 | 8,984,390 |
The XY cache keeps the scalar numerator grouping `(qx-ax)*dx + (qy-ay)*dy`; clamp, winner, reach, and composition remain per lane. A direct probe exercised 310 z-runs × 8 samples in each world: 2,558 numerator computations and 31,085 cache hits, with zero density mismatches against scalar evaluation. The measured hit fraction was 92.4% of numerator requests. The ordinary streamed view does not call the z-run API, so these XY reuse counts come from the opt-in direct probe, not natural view traffic.
## Exactness
Compared rebuilt committed-HEAD baseline to L98 Clang, then L98 Clang to L98 GCC. Density tile hashes aggregate the density sample bit patterns. All comparisons had zero tile-hash mismatches at every LOD, zero LOD0–2 density-tile mismatches, and identical whole-view density, mesh, payload, and topology hashes.
| World | Whole-view tiles | LOD0–2 density mismatches | Whole-view density | Mesh | Payload | Topology |
|---|---:|---:|---|---|---|---|
| FI | 2,850 | 0 | `40b76d0072a2adcd` | `8559df0850d4d7f1` | `7700965ff31ac702` | `0e7f2a16b4cc71a9` |
| TN | 2,249 | 0 | `99ca213b21ce86e4` | `2977525405b79fff` | `3d7d2efb581710bd` | `af1916c949224871` |
| SW | 2,233 | 0 | `8d23c26f5c092be1` | `15c3aad2e29d9ea0` | `3d48f68d511c21df` | `5b1584676884edd8` |
| VS | 2,329 | 0 | `876b44981d106be3` | `aaef57cb08bd6845` | `b19617df9f4acbb1` | `e8eee991260adff4` |
The direct XY probe also reported 2,480 sample comparisons and zero mismatches for each world. Hash runs and probe logs are under `Saved/Linux/l98/hashes/` and `Saved/Linux/l98/reuse-counts/`.
## L77 passage-share census
Mean near-LOD0–2 passage share, three profile runs per world and binary:
| World | HEAD before | L98 after | Change |
|---|---:|---:|---:|
| FI | 57.82% | 56.74% | −1.08 pp |
| TN | 55.94% | 55.70% | −0.24 pp |
This is a census comparison, not evidence of a timing gain. Logs and raw run values are in `Saved/Linux/l98/census/`.
## Cold readiness
Median seconds from three interleaved HEAD/L98 pairs per cell. Each binary/stratum/worker-count cell had a warmup. Cold timing includes world/layout setup and passage preparation. The LOD0–2 and whole-view tile counts are included below.
| World | LOD0–2 / whole tiles | W8 HEAD → L98 (LOD0–2 / whole s) | W12 HEAD → L98 (LOD0–2 / whole s) |
|---|---:|---:|---:|
| FI | 1,408 / 2,850 | 1.070 / 2.341 → 1.099 / 2.369 | 1.029 / 2.147 → 1.005 / 2.123 |
| TN | 1,216 / 2,249 | 2.672 / 4.034 → 2.680 / 4.059 | 2.211 / 3.357 → 2.207 / 3.357 |
| SW | 1,344 / 2,233 | 2.713 / 3.929 → 2.496 / 3.623 | 2.255 / 3.313 → 2.176 / 3.183 |
| VS | 1,344 / 2,329 | 1.292 / 2.315 → 1.264 / 2.257 | 1.094 / 2.015 → 1.107 / 2.041 |
All 48 measured readiness runs completed. Results are close and mixed across worlds; they do not show a broad readiness speedup. Full results and logs are in `Saved/Linux/l98/readiness/`.
## Verification and failed attempts
- Fast tier: PASS (269 pass checks, 5 diagnostic checks), 80 runs, 303.5 s. The first invocation stopped before checks because its output directory had no built headless executable; building it and rerunning passed. Summary: `Saved/Linux/l98/verify-fast/fast-summary.json`.
- Linux UE build: `VFHostEditor Linux Development`, `-NoUBA -MaxParallelActions=4`, succeeded in 36.60 s after timing. The first attempt stopped before compilation when UBT could not rotate its default log in the read-only user config directory. Retry used an explicit log at `Saved/Linux/l98/unreal-build-ubt.log`; no `--as` limit was used.
- No measured run exceeded the 30-minute limit. All experiment processes used `taskset -c 0-11`; headless runs also used the 6 GiB address-space limit.
@@ -0,0 +1,91 @@
#!/usr/bin/env python3
"""Three interleaved L77 passage-share censuses for pre-L98 and L98 Core."""
from __future__ import annotations
import json
import re
import subprocess
import time
from pathlib import Path
ROOT = Path(__file__).resolve().parents[4]
OUT = ROOT / "Saved/Linux/l98/census"
DATA = ROOT / "Standalone/data/owner_world.json"
BINARIES = {
"pre": ROOT / "Saved/Linux/l98/profile-pre-bin/VoxelForgeCoreHeadless-l98-pre-profile",
"post": ROOT / "Saved/Linux/l98/profile-post-bin/VoxelForgeCoreHeadless-l98-post-profile",
}
CAMERAS = {
"FI": (25.8369140625, 3.19921875, -737.0),
"TN": (19.166015625, -14.2001953125, -753.3740234375),
}
SAMPLE = re.compile(r"^\[L77Sample\] pc=(0x\w+) lod=(\d+) .*?phase=(\S+) .*?weight=(\d+)$", re.M)
SAMPLER = re.compile(r"^\[L77Sampler\] action=stop .*?samples=(\d+).*?status=PASS$", re.M)
def run(world: str, label: str, rep: int) -> dict:
OUT.mkdir(parents=True, exist_ok=True)
log = OUT / f"{label}-{world.lower()}-r{rep}.log"
camera = ",".join(f"{value:.12f}" for value in CAMERAS[world]) + ",0,0"
command = [
"taskset", "-c", "0-11", "prlimit", "--as=6442450944", "--",
"env", "timeout", "1740s", str(BINARIES[label]), 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", "--linux77-profile",
]
start = time.monotonic()
with log.open("w", encoding="utf-8") as stream:
result = subprocess.run(command, cwd=ROOT, stdout=stream,
stderr=subprocess.STDOUT, check=False, timeout=1740)
output = log.read_text(encoding="utf-8", errors="replace")
samples = [(int(lod), phase, int(weight))
for _pc, lod, phase, weight in SAMPLE.findall(output)]
sampler = SAMPLER.search(output)
if result.returncode or not samples or sampler is None:
raise RuntimeError(f"census failed: exit={result.returncode} {log}")
near = [row for row in samples if row[0] <= 2]
passage = sum(weight for _, phase, weight in near if phase == "passages")
total = sum(weight for _, _, weight in near)
row = {
"world": world, "binary": label, "replicate": rep,
"exit_code": result.returncode, "wall_s": round(time.monotonic() - start, 3),
"sampler_samples": int(sampler.group(1)), "near_lod_samples": len(near),
"near_lod_weighted_ticks": total,
"near_lod_passage_weighted_ticks": passage,
"near_lod_passage_share_pct": 100.0 * passage / total,
"log": str(log.relative_to(ROOT)),
}
print("[L98CensusRun] " + json.dumps(row, sort_keys=True), flush=True)
return row
def main() -> int:
for binary in (*BINARIES.values(), DATA):
if not binary.is_file():
raise SystemExit(f"missing input: {binary}")
rows = []
orders = (("pre", "post"), ("post", "pre"), ("pre", "post"))
for rep, order in enumerate(orders, 1):
for label in order:
for world in CAMERAS:
rows.append(run(world, label, rep))
(OUT / "runs-partial.json").write_text(json.dumps(rows, indent=2) + "\n",
encoding="utf-8")
summary = {}
for world in CAMERAS:
summary[world] = {}
for label in BINARIES:
values = [row["near_lod_passage_share_pct"] for row in rows
if row["world"] == world and row["binary"] == label]
summary[world][label] = {
"runs_pct": values, "mean_pct": sum(values) / len(values),
}
(OUT / "summary.json").write_text(json.dumps(
{"runs": rows, "near_lod_passage_share": summary}, indent=2) + "\n",
encoding="utf-8")
return 0
if __name__ == "__main__":
raise SystemExit(main())
@@ -0,0 +1,126 @@
#!/usr/bin/env python3
"""Compare L97 baseline and L98 Clang/GCC whole-view tile hashes at LOD0-2."""
from __future__ import annotations
import json
import re
import subprocess
import time
from pathlib import Path
ROOT = Path(__file__).resolve().parents[4]
OUT = ROOT / "Saved/Linux/l98/hashes"
DATA = ROOT / "Standalone/data/owner_world.json"
BINARIES = {
"HEAD": ROOT / "Saved/Linux/l98/pre-bin/VoxelForgeCoreHeadless-l98-pre-clang",
"L98-Clang": ROOT / "Saved/Linux/l98/bin/VoxelForgeCoreHeadless-l98-clang19",
"L98-GCC": ROOT / "Saved/Linux/l98/bin/VoxelForgeCoreHeadless-l98-gcc",
}
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),
}
TILE_HASH = re.compile(
r"^\[PipelineTileHash\] lod=(-?\d+) x=(-?\d+) y=(-?\d+) z=(-?\d+) "
r"density=(0x[0-9a-f]+) mesh=(0x[0-9a-f]+) payload=(0x[0-9a-f]+) "
r"topology=(0x[0-9a-f]+)$", re.M)
WHOLE_HASH = 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]+)$", re.M)
FIELDS = ("density", "mesh", "payload", "topology")
def run(strate: int, label: str) -> dict:
OUT.mkdir(parents=True, exist_ok=True)
log = OUT / f"{label.lower()}-s{strate}.log"
camera = ",".join(f"{v:.12f}" for v in CAMERAS[strate]) + ",0,0"
command = [
"taskset", "-c", "0-11", "prlimit", "--as=6442450944", "--",
"env", "VOXELFORGE_L98_PASSAGE_PREP_TRACE=1", "timeout", "1740s",
str(BINARIES[label]), str(DATA), "--world-assembler-prototype",
"--stream-benchmark", "--stream-pipeline", "--workers=8", "--clip-radius=3",
"--max-clip-level=8", "--max-level=8", f"--camera={camera}",
"--stream-hash-tiles",
]
start = time.monotonic()
with log.open("w", encoding="utf-8") as stream:
result = subprocess.run(command, cwd=ROOT, stdout=stream,
stderr=subprocess.STDOUT, check=False, timeout=1740)
output = log.read_text(encoding="utf-8", errors="replace")
hashes = {
(int(m.group(1)), int(m.group(2)), int(m.group(3)), int(m.group(4))):
m.group(5, 6, 7, 8) for m in TILE_HASH.finditer(output)
}
whole = WHOLE_HASH.search(output)
if result.returncode or whole is None or len(hashes) != int(whole.group(1)):
raise RuntimeError(f"hash run failed or incomplete: exit={result.returncode} {log}")
prep = re.findall(r"^\[L98PassagePrepare\] (.*)$", output, re.M)
mouth_prep = re.findall(r"^\[L98PassageMouthPrepare\] (.*)$", output, re.M)
row = {
"binary": label, "strate": strate, "exit_code": result.returncode,
"wall_s": round(time.monotonic() - start, 3), "tile_hash_count": len(hashes),
"tile_hashes_by_lod": {str(lod): sum(1 for key in hashes if key[0] == lod)
for lod in sorted({key[0] for key in hashes})},
"whole_hash": whole.group(1, 2, 3, 4, 5), "hashes": hashes,
"prepare_traces": prep, "mouth_prepare_traces": mouth_prep,
"log": str(log.relative_to(ROOT)),
}
print("[L98HashRun] " + json.dumps(
{k: v for k, v in row.items() if k != "hashes"},
sort_keys=True), flush=True)
return row
def compare(strate: int, left_label: str, right_label: str,
left: dict, right: dict) -> dict:
mismatch_keys = sorted(key for key in set(left["hashes"]) | set(right["hashes"])
if left["hashes"].get(key) != right["hashes"].get(key))
component_mismatches = {}
for component_index, component in enumerate(FIELDS):
component_mismatches[component] = sum(
left["hashes"].get(key, (None,) * 4)[component_index]
!= right["hashes"].get(key, (None,) * 4)[component_index]
for key in set(left["hashes"]) | set(right["hashes"]))
near_density_mismatches = sum(
key[0] <= 2 and left["hashes"].get(key, (None,) * 4)[0]
!= right["hashes"].get(key, (None,) * 4)[0]
for key in set(left["hashes"]) | set(right["hashes"]))
item = {
"strate": strate, "left": left_label, "right": right_label,
"tiles_left": len(left["hashes"]), "tiles_right": len(right["hashes"]),
"whole_hash_identical": left["whole_hash"] == right["whole_hash"],
"tile_hashes_identical": not mismatch_keys,
"mismatch_tile_count": len(mismatch_keys),
"component_mismatch_tile_counts": component_mismatches,
"lod0_2_density_mismatch_tile_count": near_density_mismatches,
"first_mismatches": mismatch_keys[:8],
"left_whole_hash": left["whole_hash"], "right_whole_hash": right["whole_hash"],
}
print("[L98HashComparison] " + json.dumps(item, sort_keys=True), flush=True)
return item
def main() -> int:
for binary in (*BINARIES.values(), DATA):
if not binary.is_file():
raise SystemExit(f"missing input: {binary}")
runs, comparisons = [], []
for strate in CAMERAS:
by_binary = {label: run(strate, label) for label in BINARIES}
comparisons.append(compare(strate, "HEAD", "L98-Clang",
by_binary["HEAD"], by_binary["L98-Clang"]))
comparisons.append(compare(strate, "L98-Clang", "L98-GCC",
by_binary["L98-Clang"], by_binary["L98-GCC"]))
runs.extend({key: value for key, value in row.items() if key != "hashes"}
for row in by_binary.values())
summary = {"comparisons": comparisons, "runs": runs}
(OUT / "summary.json").write_text(json.dumps(summary, indent=2) + "\n",
encoding="utf-8")
return 0 if all(item["tile_hashes_identical"] and item["whole_hash_identical"]
for item in comparisons) else 1
if __name__ == "__main__":
raise SystemExit(main())
@@ -0,0 +1,102 @@
#!/usr/bin/env python3
"""L80 cold-readiness protocol: three interleaved L97/L98 pairs at W8 and W12."""
from __future__ import annotations
import json
import re
import statistics
import subprocess
import time
from pathlib import Path
ROOT = Path(__file__).resolve().parents[4]
OUT = ROOT / "Saved/Linux/l98/readiness"
DATA = ROOT / "Standalone/data/owner_world.json"
BINARIES = {
"HEAD": ROOT / "Saved/Linux/l98/pre-bin/VoxelForgeCoreHeadless-l98-pre-clang",
"L98": ROOT / "Saved/Linux/l98/bin/VoxelForgeCoreHeadless-l98-clang19",
}
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),
}
PIPELINE = re.compile(r"^\[StreamPipeline\] (.*)$", re.M)
FIELDS = re.compile(r"([a-zA-Z0-9_]+)=([^ ]+)")
NEAR = re.compile(r"^\[WorldAssemblerNearLODReady\] lods=0-2 tiles=(\d+)/(\d+) "
r"cold_ready_s=([0-9.]+)$", re.M)
def run(strate: int, workers: int, label: str, phase: str, rep: int) -> dict:
OUT.mkdir(parents=True, exist_ok=True)
log = OUT / f"w{workers}-s{strate}-{label.lower()}-{phase}{rep}.log"
camera = ",".join(f"{v:.12f}" for v in CAMERAS[strate]) + ",0,0"
command = [
"taskset", "-c", "0-11", "prlimit", "--as=6442450944", "--",
"env", "timeout", "1740s", str(BINARIES[label]), str(DATA),
"--world-assembler-prototype", "--stream-benchmark", "--stream-pipeline",
f"--workers={workers}", "--clip-radius=3", "--max-clip-level=8",
"--max-level=8", f"--camera={camera}", "--profile-lod-work",
"--stream-scheduler-policy=3",
]
start = time.monotonic()
with log.open("w", encoding="utf-8") as stream:
result = subprocess.run(command, cwd=ROOT, stdout=stream,
stderr=subprocess.STDOUT, check=False, timeout=1740)
output = log.read_text(encoding="utf-8", errors="replace")
pipeline_match, near_match = PIPELINE.search(output), NEAR.search(output)
if result.returncode or pipeline_match is None or near_match is None:
raise RuntimeError(f"readiness run failed: exit={result.returncode} {log}")
pipeline = dict(FIELDS.findall(pipeline_match.group(1)))
row = {
"strate": strate, "workers": workers, "binary": label, "phase": phase,
"replicate": rep, "exit_code": result.returncode,
"wall_s": round(time.monotonic() - start, 3),
"lod02_tiles": f"{near_match.group(1)}/{near_match.group(2)}",
"lod02_ready_s": float(near_match.group(3)),
"whole_view_ready_s": float(pipeline["whole_view_ready"].removesuffix("s")),
"whole_tiles": pipeline["whole_tiles"].split("/")[0],
"log": str(log.relative_to(ROOT)),
}
print("[L98ReadinessRun] " + json.dumps(row, sort_keys=True), flush=True)
return row
def main() -> int:
for binary in (*BINARIES.values(), DATA):
if not binary.is_file():
raise SystemExit(f"missing input: {binary}")
rows = []
orders = (("HEAD", "L98"), ("L98", "HEAD"), ("HEAD", "L98"))
for workers in (8, 12):
for strate in CAMERAS:
for label in BINARIES:
run(strate, workers, label, "warmup", 0)
for strate in CAMERAS:
for rep, order in enumerate(orders, 1):
for label in order:
rows.append(run(strate, workers, label, "measured", rep))
(OUT / "runs-partial.json").write_text(json.dumps(rows, indent=2) + "\n",
encoding="utf-8")
summary = []
for workers in (8, 12):
for strate in CAMERAS:
group = [row for row in rows
if row["workers"] == workers and row["strate"] == strate]
item = {"workers": workers, "strate": strate, "measured_pairs": 3}
for label in BINARIES:
subset = [row for row in group if row["binary"] == label]
for metric in ("lod02_ready_s", "whole_view_ready_s"):
values = [row[metric] for row in subset]
item[f"{label}_{metric}_runs"] = values
item[f"{label}_{metric}_median"] = statistics.median(values)
item[f"{label}_process_wall_s_runs"] = [row["wall_s"] for row in subset]
summary.append(item)
(OUT / "summary.json").write_text(json.dumps(
{"runs": rows, "summary": summary}, indent=2) + "\n", encoding="utf-8")
return 0
if __name__ == "__main__":
raise SystemExit(main())
@@ -0,0 +1,105 @@
#!/usr/bin/env python3
"""Count prepared-segment use and XY projection reuse in LOD0-2 world views."""
from __future__ import annotations
import json
import re
import subprocess
import time
from pathlib import Path
ROOT = Path(__file__).resolve().parents[4]
OUT = ROOT / "Saved/Linux/l98/reuse-counts"
DATA = ROOT / "Standalone/data/owner_world.json"
BINARY = ROOT / "Saved/Linux/l98/bin/VoxelForgeCoreHeadless-l98-clang19"
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),
}
REUSE = re.compile(
r"^\[L98PassageReuseTile\] lod=(-?\d+) projection_columns=(\d+) "
r"projection_computes=(\d+) projection_hits=(\d+) floor_profile_reads=(\d+) "
r"carve_prepared=(\d+) support_prepared=(\d+) capsule_prepared=(\d+) "
r"mouth_prepared=(\d+)$", re.M)
PREP = re.compile(r"^\[L98PassagePrepare\] (.*)$", re.M)
MOUTH_PREP = re.compile(r"^\[L98PassageMouthPrepare\] (.*)$", re.M)
PIPELINE = re.compile(r"^\[StreamPipeline\] (.*)$", re.M)
PROBE = re.compile(r"^\[L98PassageReuseProbe\] z_runs=(\d+) samples=(\d+) "
r"scalar_mismatches=(\d+) status=(\S+)$", re.M)
def run(strate: int) -> dict:
OUT.mkdir(parents=True, exist_ok=True)
log = OUT / f"s{strate}.log"
camera = ",".join(f"{v:.12f}" for v in CAMERAS[strate]) + ",0,0"
command = [
"taskset", "-c", "0-11", "prlimit", "--as=6442450944", "--",
"env", "VOXELFORGE_L98_PASSAGE_REUSE_COUNTS=1",
"VOXELFORGE_L98_PASSAGE_PREP_TRACE=1",
"VOXELFORGE_L98_PASSAGE_REUSE_PROBE=1", "timeout", "1740s", str(BINARY),
str(DATA), "--world-assembler-prototype", "--stream-benchmark",
"--stream-pipeline", "--workers=8", "--clip-radius=3", "--max-clip-level=8",
"--max-level=8", f"--camera={camera}",
]
start = time.monotonic()
with log.open("w", encoding="utf-8") as stream:
result = subprocess.run(command, cwd=ROOT, stdout=stream,
stderr=subprocess.STDOUT, check=False, timeout=1740)
output = log.read_text(encoding="utf-8", errors="replace")
tile_rows = [tuple(map(int, match.groups())) for match in REUSE.finditer(output)]
prep = PREP.findall(output)
mouth_prep = MOUTH_PREP.findall(output)
pipeline = PIPELINE.search(output)
probe = PROBE.search(output)
if (result.returncode or not tile_rows or not prep or pipeline is None or probe is None
or probe.group(4) != "PASS"):
raise RuntimeError(f"reuse-count run failed or incomplete: exit={result.returncode} {log}")
totals = [sum(row[index] for row in tile_rows) for index in range(1, 9)]
lod_totals = {}
for lod in sorted({row[0] for row in tile_rows}):
lod_rows = [row for row in tile_rows if row[0] == lod]
lod_totals[str(lod)] = {
"tile_scope_rows": len(lod_rows),
"projection_columns": sum(row[1] for row in lod_rows),
"projection_computes": sum(row[2] for row in lod_rows),
"projection_hits": sum(row[3] for row in lod_rows),
"floor_profile_reads": sum(row[4] for row in lod_rows),
"carve_prepared_uses": sum(row[5] for row in lod_rows),
"support_prepared_uses": sum(row[6] for row in lod_rows),
"capsule_prepared_uses": sum(row[7] for row in lod_rows),
"mouth_prepared_uses": sum(row[8] for row in lod_rows),
}
row = {
"strate": strate, "exit_code": result.returncode,
"wall_s": round(time.monotonic() - start, 3), "tile_scope_rows": len(tile_rows),
"lod_scope_rows": {str(lod): sum(1 for row in tile_rows if row[0] == lod)
for lod in sorted({row[0] for row in tile_rows})},
"lod_totals": lod_totals,
"projection_columns": totals[0], "projection_computes": totals[1],
"projection_hits": totals[2], "floor_profile_reads": totals[3],
"carve_prepared_uses": totals[4], "support_prepared_uses": totals[5],
"capsule_prepared_uses": totals[6], "mouth_prepared_uses": totals[7],
"projection_probe": {
"z_runs": int(probe.group(1)), "samples": int(probe.group(2)),
"scalar_mismatches": int(probe.group(3)), "status": probe.group(4),
},
"prepare_traces": prep, "mouth_prepare_traces": mouth_prep,
"stream_pipeline": pipeline.group(1), "log": str(log.relative_to(ROOT)),
}
print("[L98ReuseCountRun] " + json.dumps(row, sort_keys=True), flush=True)
return row
def main() -> int:
if not BINARY.is_file() or not DATA.is_file():
raise SystemExit(f"missing input: {BINARY} or {DATA}")
rows = [run(strate) for strate in CAMERAS]
(OUT / "summary.json").write_text(json.dumps({"runs": rows}, indent=2) + "\n",
encoding="utf-8")
return 0
if __name__ == "__main__":
raise SystemExit(main())