diag: bounded passage carve reach rejected (L93); R43 Unreal SW startup notes

Explicit carve reach R (diagnostic, default unbounded): R=2.5 m -> 1.56 cm max displacement,
106 deg max normal change; R=4 m -> 0.63 cm but 53 deg normals. Fails the bar; readiness gain
small and inconsistent (TN -5%, VS +6-7%). No world change (v214). Fast tier PASS.
R43: Unreal SW bReady 2.16 s = serial sign-edge repair (1.94 s, 10.9M corrections;
parallelSignEdgeRepair exists but off); ~0.45 s of SerializeResolvedWorld = adapter SW route search.

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 07:33:53 +01:00
1 parent 70c37aaab3
commit 1e111cc042
9 files changed
+545 -55

No files matched your search

@@ -0,0 +1,68 @@
## Ranked findings
1. **[TRACE] The extra ~2 seconds are inside Core’s shape build.** Across the three final runs, SW’s `core_compile_start → core_bready` interval is **2.171, 2.157, and 2.038 s**; FI’s is **0.173, 0.184, and 0.187 s**. The median gap is **1.973 s**. [SW traces](</home/jahni/VoxelM/Plugins/VoxelForge/Saved/Linux/l92/unreal-arrival/after-direct-json-sw-on-1.trace.jsonl:24>), [FI traces](</home/jahni/VoxelM/Plugins/VoxelForge/Saved/Linux/l92/unreal-arrival/after-direct-json-fi-on-1.trace.jsonl:24>)
**[TRACE]** The SW `ShapeStage`’s median `sign_edge_distances` time is **1.942 s**, versus **8.8 ms** for FI. SW repairs **10,864,702** endpoint proxies, with **10,864,427** occupancy corrections; FI records zero endpoint proxies. Both compile **138,188,413 nodes** and use the same assembly, recipe, and plan hashes. [SW shape log](</home/jahni/VoxelM/Plugins/VoxelForge/Saved/Linux/l92/unreal-arrival/after-direct-json-sw-on-1.stdout.log:1376>), [FI shape log](</home/jahni/VoxelM/Plugins/VoxelForge/Saved/Linux/l92/unreal-arrival/after-direct-json-fi-on-1.stdout.log:1132>), [L92 hashes](</home/jahni/VoxelM/Plugins/VoxelForge/Standalone/Research/WorldAssemblerM3/Linux92/REPORT.md:26>)
**[CODE]** `FStandaloneShapeWorld::Build` runs `ApplyDetailBand`, then `CompleteSignEdgeDistances`; the latter calls `AnalyticDensityAt` for missing edge samples. The parallel repair branch exists, but `parallelSignEdgeRepair` defaults to `false` and Unreal does not set it on this request. [Shape build](</home/jahni/VoxelM/Plugins/VoxelForge/Standalone/Core/src/ShapeWorldInternal.h:3331>), [serial repair](</home/jahni/VoxelM/Plugins/VoxelForge/Standalone/Core/src/ShapeWorldInternal.h:12000>), [request default](</home/jahni/VoxelM/Plugins/VoxelForge/Standalone/Core/include/VoxelForgeCore/VoxelForgeCore.h:1592>), [Unreal request](</home/jahni/VoxelM/Plugins/VoxelForge/Private/VoxelWorld.cpp:7807>)
**[INFERENCE]** The dominant delay is serial sign-edge repair over the SW-start shape region. The different spawn heights support that explanation: SW starts at −200 m, within the SurfaceWorld stratum; FI starts at −737 m. **Falsifier:** an identical SW run showing sign-edge repair below roughly 100 ms, or showing that the repair is not part of `World::compile`, would overturn this attribution. [SW spawn](</home/jahni/VoxelM/Plugins/VoxelForge/Saved/Linux/l92/unreal-arrival/after-direct-json-sw-on-1.trace.jsonl:27>), [FI spawn](</home/jahni/VoxelM/Plugins/VoxelForge/Saved/Linux/l92/unreal-arrival/after-direct-json-fi-on-1.trace.jsonl:27>)
2. **[TRACE] The adapter’s route search is a separate ~0.45 s cost before compile launch.** In the measured SW run, serialization takes **466.957 ms**. The corresponding route logs span about **452 ms** from the failed legacy candidate set to the bounded-mouth candidate result; that fallback visits 78,408 candidates and ends with only three sweep attempts. [SW trace](</home/jahni/VoxelM/Plugins/VoxelForge/Saved/Linux/l92/unreal-arrival/after-direct-json-sw-on-3.trace.jsonl:17>), [SW route logs](</home/jahni/VoxelM/Plugins/VoxelForge/Saved/Linux/l92/unreal-arrival/after-direct-json-sw-on-3.log:928>)
**[CODE]** This runs in `BuildFiniteSurfaceRoute`, called while `BuildSurfaceStratumPlan` assembles the manifest inside `SerializeResolvedWorld`. It finishes before `core_compile_launch`; it cannot explain the launch-to-`bReady` interval. [Route search](</home/jahni/VoxelM/Plugins/VoxelForge/Source/VoxelForge/Private/VoxelForgeCoreAdapter.cpp:445>), [plan call](</home/jahni/VoxelM/Plugins/VoxelForge/Source/VoxelForge/Private/VoxelForgeCoreAdapter.cpp:839>), [manifest build](</home/jahni/VoxelM/Plugins/VoxelForge/Source/VoxelForge/Private/VoxelForgeCoreAdapter.cpp:1635>), [compile launch](</home/jahni/VoxelM/Plugins/VoxelForge/Saved/Linux/l92/unreal-arrival/after-direct-json-sw-on-3.trace.jsonl:23>)
**[INFERENCE]** The route search explains much of the **shared** ~466–468 ms serialization cost in both FI and SW, but not why SW takes longer than FI after compile starts. The log span is strong attribution, though it is not a per-function timer. **Falsifier:** a direct timer showing the candidate loops take far less than 400 ms, or showing they fall outside the measured exporter interval.
3. **[CODE][TRACE] The “radius 6 / max clip 6” values are the Settings asset values, not the Core compile settings in these traces.** Core uses `CoreClipRadius=3` and `CoreMaxClipLevel=8`; the adapter writes those values into the snapshot, and the runtime log says `clip_radius=3 max_level=8`. The trace’s `settings_resolved` event reports the separate Settings values 6/6. [Core defaults](</home/jahni/VoxelM/Plugins/VoxelForge/Source/VoxelForge/Public/VoxelWorld.h:310>), [snapshot override](</home/jahni/VoxelM/Plugins/VoxelForge/Source/VoxelForge/Private/VoxelForgeCoreAdapter.cpp:2104>), [trace Settings values](</home/jahni/VoxelM/Plugins/VoxelForge/Saved/Linux/l92/unreal-arrival/after-direct-json-sw-on-3.trace.jsonl:3>), [runtime Core values](</home/jahni/VoxelM/Plugins/VoxelForge/Saved/Linux/l92/unreal-arrival/after-direct-json-sw-on-3.log:932>)
**[INFERENCE]** Changing the legacy Settings radius to 3 would not fix this Core compile; it already uses 3. **Falsifier:** inspecting the Core snapshot actually consumed by `World` and finding radius 6 / max level 6.
4. **[CODE][TRACE] Far parents, recipe differences, and long validation do not explain this gap.** Unreal sets `Request.includeFarWorld=false`, and the SW logs report `far_parents=0.000 ms`; FI and SW also log the same assembly/recipe/plan hashes. Passage validation is about 1.2–1.7 ms. [Request](</home/jahni/VoxelM/Plugins/VoxelForge/Source/VoxelForge/Private/VoxelWorld.cpp:7807>), [far build condition](</home/jahni/VoxelM/Plugins/VoxelForge/Standalone/Core/src/ShapeWorldInternal.h:3339>), [SW shape stages](</home/jahni/VoxelM/Plugins/VoxelForge/Saved/Linux/l92/unreal-arrival/after-direct-json-sw-on-1.stdout.log:1379>)
**[INFERENCE]** Neither another plan path nor a debug/validation pass accounts for the 1.97 s FI/SW gap. **Falsifier:** a run with different plan hashes, nonzero far-parent time, or an unmeasured validation stage above hundreds of milliseconds.
## Trace arithmetic
**[TRACE]** These are direct subtractions of `core_compile_start.t_s` from `core_bready.t_s`:
| Arrival | Repeat 1 | Repeat 2 | Repeat 3 | Median |
|---|---:|---:|---:|---:|
| FI | `.742608 − .569354 = .173254 s` | `.749704 − .565919 = .183785 s` | `.796746 − .609896 = .186850 s` | `.183785 s` |
| SW | `2.780194 − .608768 = 2.171426 s` | `2.737530 − .580978 = 2.156552 s` | `2.616805 − .578886 = 2.037919 s` | `2.156552 s` |
[FI trace 1](</home/jahni/VoxelM/Plugins/VoxelForge/Saved/Linux/l92/unreal-arrival/after-direct-json-fi-on-1.trace.jsonl:24>), [FI trace 2](</home/jahni/VoxelM/Plugins/VoxelForge/Saved/Linux/l92/unreal-arrival/after-direct-json-fi-on-2.trace.jsonl:24>), [FI trace 3](</home/jahni/VoxelM/Plugins/VoxelForge/Saved/Linux/l92/unreal-arrival/after-direct-json-fi-on-3.trace.jsonl:24>), [SW trace 1](</home/jahni/VoxelM/Plugins/VoxelForge/Saved/Linux/l92/unreal-arrival/after-direct-json-sw-on-1.trace.jsonl:24>), [SW trace 2](</home/jahni/VoxelM/Plugins/VoxelForge/Saved/Linux/l92/unreal-arrival/after-direct-json-sw-on-2.trace.jsonl:24>), [SW trace 3](</home/jahni/VoxelM/Plugins/VoxelForge/Saved/Linux/l92/unreal-arrival/after-direct-json-sw-on-3.trace.jsonl:24>)
**[TRACE]** The reported `compile_s` values differ by at most about 26 μs because the code samples the duration just before recording the event timestamp. The SW run 1 trace then shows `bReady` at **2.780194 s**, first tile `request` at **2.794163 s**, and scheduler admission at **2.794603 s**. So the ~2.75 s table value is almost entirely the wait for `bReady`; the first per-tile request is about **14 ms** after readiness. [Ready sample](</home/jahni/VoxelM/Plugins/VoxelForge/Source/VoxelForge/Private/VoxelWorld.cpp:7886>), [SW events](</home/jahni/VoxelM/Plugins/VoxelForge/Saved/Linux/l92/unreal-arrival/after-direct-json-sw-on-1.trace.jsonl:422>)
**[TRACE]** The detailed logs match the Core trace: median FI `ShapeStage` is **183.527 ms**, median SW is **2,156.283 ms**; SW’s median sign-edge substage alone is **1,942.160 ms**. **Falsifier:** a trace/log pair with the same run identifiers but materially different `ShapeStage` and `core_bready` durations would break this mapping. [FI stage](</home/jahni/VoxelM/Plugins/VoxelForge/Saved/Linux/l92/unreal-arrival/after-direct-json-fi-on-2.stdout.log:1137>), [SW stage](</home/jahni/VoxelM/Plugins/VoxelForge/Saved/Linux/l92/unreal-arrival/after-direct-json-sw-on-2.stdout.log:1377>)
## What `SerializeResolvedWorld` does
**[CODE]** `BeginPlay` calls `InitializeVoxelForgeCoreWorld` synchronously; that function calls `SerializeResolvedWorld` before converting the result to UTF-8 and calling Core’s `ResolvedWorldSnapshot::FromJson`. [BeginPlay](</home/jahni/VoxelM/Plugins/VoxelForge/Source/VoxelForge/Private/VoxelWorld.cpp:2720>), [export and parse](</home/jahni/VoxelM/Plugins/VoxelForge/Source/VoxelForge/Private/VoxelWorld.cpp:7658>)
**[CODE]** The exporter reflects over Settings and nested Voxel objects with `TFieldIterator<FProperty>`, handles arrays/maps/sets/structs, serializes resolved strata and passages, and synchronously loads terrain-operation assets. It then builds or imports a world assembly, rebuilds the resolved layout, writes canonical manifest JSON, parses that manifest back into an Unreal JSON object, and writes the full snapshot JSON. [Reflection](</home/jahni/VoxelM/Plugins/VoxelForge/Source/VoxelForge/Private/VoxelForgeCoreAdapter.cpp:966>), [asset load](</home/jahni/VoxelM/Plugins/VoxelForge/Source/VoxelForge/Private/VoxelForgeCoreAdapter.cpp:2172>), [manifest build](</home/jahni/VoxelM/Plugins/VoxelForge/Source/VoxelForge/Private/VoxelForgeCoreAdapter.cpp:1565>), [JSON embed/write](</home/jahni/VoxelM/Plugins/VoxelForge/Source/VoxelForge/Private/VoxelForgeCoreAdapter.cpp:2036>)
**[TRACE]** L92 measures the whole exporter at **465.6 ms FI / 468.0 ms SW** and `FromJson` at **18.9 / 19.3 ms**. The route-search logs align with about **452 ms** inside the SW exporter window, so generic asset reflection and JSON handling are not supported as the main cause of the 466 ms. Their individual shares were not timed. [L92 timing and attribution note](</home/jahni/VoxelM/Plugins/VoxelForge/Standalone/Research/WorldAssemblerM3/Linux92/REPORT.md:9>), [SW route logs](</home/jahni/VoxelM/Plugins/VoxelForge/Saved/Linux/l92/unreal-arrival/after-direct-json-sw-on-3.log:928>)
**[CODE]** Core’s public snapshot API currently exposes `FromJson`, getters, and layout helpers; the snapshot’s data constructor is private. A direct handoff is possible with a new typed Core builder, but the adapter would still need to map the resolved Unreal assets into Core-owned data. [Snapshot API](</home/jahni/VoxelM/Plugins/VoxelForge/Standalone/Core/include/VoxelForgeCore/VoxelForgeCore.h:1546>)
**[INFERENCE]** Direct typed construction could remove JSON encode/decode work, but it would not remove the route search. The measured ceiling for the parser plus the exporter’s non-route remainder is roughly **35 ms gross**; actual net savings may be smaller because a typed builder must still resolve and validate the owner data. **Falsifier:** a typed A/B that saves substantially more than that while generating the same plan would show unmeasured JSON work is larger than the current timing decomposition suggests.
**[CODE]** Running the existing exporter unchanged off-thread is unsafe: it reads Unreal `UObject` properties and calls `LoadSynchronous`. A split is possible: snapshot UObject-backed values on the game thread, then build the route/manifest from immutable Core inputs on a worker. **[INFERENCE]** That would reduce the game-thread hitch, but it will not reduce first-request wall time unless the work can overlap independent startup or use a precomputed manifest. **Falsifier:** a worker-thread run of the unchanged exporter that is shown safe for all UObject access and measurably reduces first admission without overlap.
## Smallest changes and measurements
1. **[INFERENCE] First SW experiment: enable the existing deterministic parallel sign-edge repair.** Set `Request.parallelSignEdgeRepair=true`; Core already has a parallel density evaluation path with sorted, deterministic publication. The current sign-edge stage is **1.94 s**, so that is the hard upper bound. L55 measured a different headless FI workload falling from **535 ms to 47 ms** with the same approach; using that ratio gives a rough SW estimate of **about 1.77 s saved**, not a result for this Unreal case. [Parallel implementation](</home/jahni/VoxelM/Plugins/VoxelForge/Standalone/Core/src/ShapeWorldInternal.h:12103>), [prior L55 result](</home/jahni/VoxelM/Plugins/VoxelForge/Standalone/Research/WorldAssemblerM3/Linux55/REPORT.md:56>)
**[INFERENCE]** Cheapest confirmation: A/B that one request flag at the same SW spawn and worker count; compare existing `sign_edge_distances`, `ShapeStage`, `core_bready`, and output hashes. Keep the serial path if the SW hashes differ or the stage barely moves. **Falsifier:** the paired run saves under roughly 100 ms, or changes the exact SW outputs.
2. **[INFERENCE] For the separate ~0.45 s exporter cost, use an already generated manifest through the existing override path when a seed/layout-matched artifact is available.** `AttachValidatedWorldAssembly` parses and validates an imported manifest instead of building `BuildSurfaceStratumPlan` and searching candidates; preserving the existing manifest hash preserves the route plan and does not change the passage composer. Expected saving is **about 0.4–0.45 s**, subject to the artifact matching the resolved seed and strata. [Override branch](</home/jahni/VoxelM/Plugins/VoxelForge/Source/VoxelForge/Private/VoxelForgeCoreAdapter.cpp:1577>)
**[INFERENCE]** Cheapest confirmation: one fixed-seed trace using the identical manifest; check that route-candidate logs disappear, hashes remain identical, and `SerializeResolvedWorld` falls by roughly the route-search span. **Falsifier:** the route search still runs, hashes change, or the exporter falls by much less than 0.4 s.
3. **[INFERENCE] Treat direct typed handoff as a small cleanup, not the startup fix.** It can target the roughly **19 ms** parse and some residual JSON work, but not the sign-edge repair or route search. **Falsifier:** a direct-builder A/B removes hundreds of milliseconds without changing route planning; that would show the current residual estimate is wrong.
4. **[TRACE][INFERENCE] Do not tune the legacy 6/6 clip values or raise the compile task priority as the first fix.** Core already runs 3/8, and launch-to-start queue delay is only **0.05–1.59 ms**; priority could still affect CPU progress, but the trace isolates a much larger serial substage. **Falsifier:** a same-input priority A/B materially reduces `sign_edge_distances` or the shape-stage wall time. [Task priority and queue delay](</home/jahni/VoxelM/Plugins/VoxelForge/Saved/Linux/l92/unreal-arrival/after-direct-json-sw-on-2.trace.jsonl:23>)
**[TRACE]** The headless L84/L86/L87 shape timings show that the compiler can finish in roughly **0.25–0.4 s** for those runs, but they do not falsify the R43 finding: R43’s SW camera hits the SurfaceWorld region and triggers the measured 10.9M serial sign corrections. **[INFERENCE]** A headless trace with the same request bounds, spawn, and repair mode would be the clean comparison. **Falsifier:** that matched headless run also takes about 2 s in `sign_edge_distances`. [L84](</home/jahni/VoxelM/Plugins/VoxelForge/Standalone/Research/WorldAssemblerM3/Linux84/REPORT.md>), [L86](</home/jahni/VoxelM/Plugins/VoxelForge/Standalone/Research/WorldAssemblerM3/Linux86/REPORT.md>), [L87](</home/jahni/VoxelM/Plugins/VoxelForge/Standalone/Research/WorldAssemblerM3/Linux87/REPORT.md>)
@@ -0,0 +1,66 @@
# Linux93 — explicit passage carve reach
## R and acceptance bar
Before measurement, the bar was: **zero sign flips, maximum surface displacement ≤1 cm, maximum normal change ≤2°, and all passage audits pass.**
I chose **R = 2.5 m beyond the tube surface**, with the final 0.5 m smoothly fading to identity. The code’s local terms are a 2.25 m positive-source reach floor and a 0.24 m wall-relief/source allowance (0.21 m relief plus 0.03 m margin); mouth-floor relief is separately capped at 0.20 m. Wider short-span decks and mouth/transition envelopes are separate paths, retained behind their existing feature guards. R is an experiment, not a proof that those separate envelopes fit inside the carve radius. I also measured R=1.5, 2.0 and 4.0 m.
The instrument reported `GenerateTile -> ApplyResolvedStrateComposition -> ApplyResolvedStratePassageCarves`, comparing density, mesh-edge crossings and normals. It did not use the L91 source-gradient probe. Each reach covered the full desired LOD0–2 set in S0/FI/TN/S3: 5,312 tiles and 174,736,448 samples per reach. Source stamp: `938a849b053aa7e5bc9bf5fcaf51a73590d408c15bc9d8f0564fec685e68921d`.
## Effect
Worst displacement and normal change are across all four strata; moved crossings and pairing failures are totals. Every row had zero sign flips and zero edge-crossing mismatches.
| R (m) | Moved crossings | Max displacement (cm) | Max normal change | Normal pairing failures | Bar |
|---:|---:|---:|---:|---:|---|
| 1.5 | 4,303 | 85.136 | 144.823° | 65 | Fail |
| 2.0 | 1,910 | 41.106 | 118.485° | 57 | Fail |
| 2.5 | 922 | 1.555 | 106.628° | 57 | Fail |
| 4.0 | 916 | 0.632 | 53.193° | 57 | Fail |
R=2.5 exceeds the displacement limit and misses the normal limit by a wide margin. R=4 meets the displacement limit but still fails normals. The effect audits completed with zero generation failures and zero invalid comparisons; full same-world passage audits were not run after this gate failed.
## Census and prototype
The L90 census was not rerun because the effect bar failed. The requested active-p90 (about 4–6) and fallback (<10%) stops therefore have no L93 measurements; the previous 10 m baseline was p90=13 and 18.28% fallback. The compiled evaluator prototype on `passage/1-2/0` was not started because it depends on a passing census.
## Bounded-only readiness
Cold headless runs compared default reach with R=2.5 m, L81 padding 0, and passage-composer profiling. Each mode had one warmup and three alternating measured pairs. Counts below are complete LOD0–2 near sets; times are medians in seconds.
| Stratum | W8 default → R=2.5 | W12 default → R=2.5 |
|---|---:|---:|
| S0 | 0.975 → 0.897 | 0.976 → 0.929 |
| FI | 2.354 → 2.307 | 2.181 → 2.158 |
| TN | 2.356 → 2.229 | 2.156 → 2.032 |
| S3 | 1.276 → 1.371 | 1.100 → 1.169 |
All runs completed their near sets: S0 1,408, FI 1,216, TN 1,344, S3 1,344 tiles. The work table sums the four per-stratum median counters. Positive deltas mean more counted work with bounded reach.
| Work counter | W8 default → R=2.5 (Δ) | W12 default → R=2.5 (Δ) |
|---|---:|---:|
| Tile-bound checks | 21,697,558 → 15,820,579 (−27.1%) | 23,141,444 → 15,820,579 (−31.6%) |
| Tile-bound rejects | 15,393,408 → 15,702,098 (+2.0%) | 16,114,028 → 15,702,098 (−2.6%) |
| Passage iterations skipped by tile bound | 46,180,224 → 47,106,294 (+2.0%) | 48,342,084 → 47,106,294 (−2.6%) |
| Negative-bound checks / rejects | 5,506,163 / 2,500,536 → 3,461,477 / 3,286,103 (checks −37.1%, rejects +31.4%) | 5,705,127 / 2,699,500 → 3,767,727 / 3,592,353 (checks −34.0%, rejects +33.1%) |
| Passage iterations | 33,137,208 → 32,209,659 (−2.8%) | 38,207,001 → 39,438,384 (+3.2%) |
| Carve segment visits | 78,166,733 → 77,908,735 (−0.3%) | 101,322,676 → 106,806,150 (+5.4%) |
| Support segment visits | 31,466,498 → 30,406,353 (−3.4%) | 37,630,363 → 38,810,022 (+3.1%) |
| Mouth route checks | 38,701,878 → 37,198,938 (−3.9%) | 47,097,975 → 47,996,583 (+1.9%) |
| Relief field calls | 56,100,413 → 51,745,464 (−7.8%) | 66,227,624 → 64,386,389 (−2.8%) |
The skip counters do not show a consistent work reduction: several active-loop counters rise at W12, and S3 readiness regresses at both worker counts. This is not a readiness win.
## Same-world evidence and disposition
The bounded candidate is rejected. No candidate peer-hash comparison at W1/W8/W12 or across Clang/GCC, bounded passage-audit suite, mouth/mid-tunnel captures, version bump, or hash repin was done. The evaluator remains version 214 and the default reach remains unbounded. The Clang fast tier on the default path passed: 274 checks, 269 PASS and 5 expected diagnostics, in 285.9 s; its W1/W8/W12 checks matched. Standalone diagnostic builds took 65.49 s (Clang) and 89.39 s (GCC). No Unreal source changed, so no Unreal build was run.
## Failed and superseded runs
- The first fast-tier launch stopped before tests because its expected binary did not exist. After building the stamped binaries, the fast tier passed.
- An early readiness parser incorrectly required a composer-profile row for every near tile; the profiler emits rows only for active tiles. The parser was corrected and the final matrix validated complete near-tile coverage. Earlier fixed-5 m support-floor readiness data is superseded and excluded.
- Final effect runs completed but intentionally reported FAIL against the stated effect bar. No run exceeded 30 minutes.
- Build, headless measurement and verifier processes were pinned to CPUs 0–11; headless runs also had the 6 GiB address-space limit. A few read-only status/source/JSON inspection commands during consolidation were not pinned. No measurement or build ran in those commands.
Logs and machine-readable summaries are under `Saved/Linux/l93/`.
@@ -0,0 +1,139 @@
#!/usr/bin/env python3
"""L80-style cold near-readiness A/B for the bounded carve and L81 reach skip."""
from __future__ import annotations
import argparse
import json
import re
import statistics
import subprocess
import time
from pathlib import Path
ROOT = Path(__file__).resolve().parents[4]
OUT = ROOT / "Saved/Linux/l93/readiness"
DATA = ROOT / "Standalone/data/owner_world.json"
BINARY = ROOT / "Saved/Linux/l93/bin/VoxelForgeCoreHeadless-clang19"
STRATA = {
"S0": {"id": 0, "camera": (8.0, 16.0, -372.2626953125), "near": 1408},
"FI": {"id": 1, "camera": (25.8369140625, 3.19921875, -737.0), "near": 1216},
"TN": {"id": 2, "camera": (19.166015625, -14.2001953125, -753.3740234375), "near": 1344},
"S3": {"id": 3, "camera": (-20.0625, -5.068359375, -900.353515625), "near": 1344},
}
MODES = {"unbounded": "0", "bounded": "2.5"}
PIPELINE = re.compile(r"^\[StreamPipeline\] (.*)$", re.M)
NEAR = re.compile(r"^\[WorldAssemblerNearLODReady\] lods=0-2 tiles=(\d+)/(\d+) "
r"cold_ready_s=([0-9.]+)$", re.M)
PROFILE = re.compile(r"^\[PassageComposerTile\] key=\((-?\d+),(-?\d+),(-?\d+),lod(\d+)\) (.*)$", re.M)
FIELDS = re.compile(r"([a-zA-Z0-9_]+)=([^ ]+)")
WORK_FIELDS = (
"samples", "queries", "passage_iterations", "tile_bound_checks",
"tile_bound_rejects", "tile_bound_skipped_iterations", "negative_bounds",
"negative_rejects", "positive_bounds", "positive_rejects",
"carve_segment_visits", "support_segment_visits", "support_capsule_checks",
"later_bore_checks", "other_capsule_checks", "mouth_route_segment_checks",
"relief_field_calls", "smoothstep_evaluations",
)
def parse_fields(line: str) -> dict[str, str]:
return dict(FIELDS.findall(line))
def run(stratum: str, workers: int, mode: str, phase: str, replicate: int) -> dict:
OUT.mkdir(parents=True, exist_ok=True)
spec = STRATA[stratum]
label = f"{stratum.lower()}-w{workers}-{mode}-{phase}{replicate}"
log = OUT / f"{label}.log"
camera = ",".join(f"{value:.12f}" for value in spec["camera"]) + ",0,0"
command = [
"taskset", "-c", "0-11", "prlimit", "--as=6442450944", "--", "env",
f"VOXELFORGE_L93_PASSAGE_CARVE_REACH_METRES={MODES[mode]}",
"VOXELFORGE_L81_PASSAGE_BOUND_PADDING_VOXELS=0", "timeout", "1740s",
str(BINARY), 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", "--profile-passage-composer",
"--stream-scheduler-policy=3",
]
start = time.monotonic()
try:
with log.open("w", encoding="utf-8") as stream:
proc = subprocess.run(command, cwd=ROOT, stdout=stream,
stderr=subprocess.STDOUT, check=False, timeout=1750)
except subprocess.TimeoutExpired as exc:
raise RuntimeError(f"readiness run exceeded 1,750 seconds: {log}") from exc
output = log.read_text(encoding="utf-8", errors="replace")
near = NEAR.search(output)
pipeline = PIPELINE.search(output)
if proc.returncode or near is None or pipeline is None:
raise RuntimeError(f"readiness run failed or required output missing: {log}; exit={proc.returncode}")
pipeline_fields = parse_fields(pipeline.group(1))
by_key: dict[tuple[int, int, int, int], dict[str, int]] = {}
for match in PROFILE.finditer(output):
key = tuple(int(value) for value in match.groups()[:4])
if key[3] > 2:
continue
fields = parse_fields(match.group(5))
by_key[key] = {name: int(fields.get(name, "0")) for name in WORK_FIELDS}
work = {name: sum(values[name] for values in by_key.values()) for name in WORK_FIELDS}
expected = spec["near"]
row = {
"stratum": stratum, "workers": workers, "mode": mode,
"phase": phase, "replicate": replicate, "exit_code": proc.returncode,
"wall_s": round(time.monotonic() - start, 3),
"lod02_ready_s": float(near.group(3)),
"near_tiles": f"{near.group(1)}/{near.group(2)}",
"expected_near_tiles": expected,
"profiled_near_tiles": len(by_key),
"unprofiled_near_tiles": max(0, expected - len(by_key)),
"whole_view_ready_s": float(pipeline_fields["whole_view_ready"].removesuffix("s")),
"whole_tiles": int(pipeline_fields["whole_tiles"].split("/")[0]),
"work": work,
"log": str(log.relative_to(ROOT)),
}
print("[L93BoundedReadinessRun] " + json.dumps(row, sort_keys=True), flush=True)
return row
def main() -> int:
parser = argparse.ArgumentParser()
parser.add_argument("--stratum", choices=tuple(STRATA), required=True)
parser.add_argument("--workers", choices=(8, 12), type=int, required=True)
args = parser.parse_args()
if not BINARY.is_file() or not DATA.is_file():
raise SystemExit(f"missing input: {BINARY} or {DATA}")
rows = []
for mode in MODES:
run(args.stratum, args.workers, mode, "warmup", 0)
orders = (("unbounded", "bounded"), ("bounded", "unbounded"),
("unbounded", "bounded"))
for replicate, order in enumerate(orders, 1):
for mode in order:
rows.append(run(args.stratum, args.workers, mode, "measured", replicate))
(OUT / f"runs-partial-{args.stratum.lower()}-w{args.workers}.json").write_text(
json.dumps(rows, indent=2) + "\n", encoding="utf-8")
summary = {"stratum": args.stratum, "workers": args.workers,
"measured_pairs": 3, "runs": rows}
for mode in MODES:
subset = [row for row in rows if row["mode"] == mode]
summary[f"{mode}_lod02_ready_s"] = [row["lod02_ready_s"] for row in subset]
summary[f"{mode}_lod02_ready_median_s"] = statistics.median(
row["lod02_ready_s"] for row in subset)
summary[f"{mode}_whole_ready_s"] = [row["whole_view_ready_s"] for row in subset]
summary[f"{mode}_whole_ready_median_s"] = statistics.median(
row["whole_view_ready_s"] for row in subset)
summary[f"{mode}_work_median"] = {
name: statistics.median(row["work"][name] for row in subset)
for name in WORK_FIELDS}
path = OUT / f"summary-{args.stratum.lower()}-w{args.workers}.json"
path.write_text(json.dumps(summary, indent=2) + "\n", encoding="utf-8")
print("[L93BoundedReadinessSummary] " + json.dumps(summary, sort_keys=True), flush=True)
valid = all(row["near_tiles"].split("/") == [str(row["expected_near_tiles"])] * 2
and 0 < row["profiled_near_tiles"] <= row["expected_near_tiles"]
for row in rows)
return 0 if valid else 14
if __name__ == "__main__":
raise SystemExit(main())
@@ -0,0 +1,135 @@
#!/usr/bin/env python3
"""Compare bounded passage-carve reaches over each owner's complete near view."""
from __future__ import annotations
import json
import argparse
import re
import subprocess
import time
from pathlib import Path
ROOT = Path(__file__).resolve().parents[4]
OUT = ROOT / "Saved/Linux/l93/effects"
DATA = ROOT / "Standalone/data/owner_world.json"
BINARY = ROOT / "Saved/Linux/l93/bin/VoxelForgeCoreHeadless-clang19"
STRATA = {
"S0": {"camera": (8.0, 16.0, -372.2626953125), "near": 1408},
"FI": {"camera": (25.8369140625, 3.19921875, -737.0), "near": 1216},
"TN": {"camera": (19.166015625, -14.2001953125, -753.3740234375), "near": 1344},
"S3": {"camera": (-20.0625, -5.068359375, -900.353515625), "near": 1344},
}
REACHES = (1.5, 2.0, 2.5, 4.0)
STAMP = re.compile(r"^\[VoxelForgeSourceStamp\] sha256=(\S+)$", re.M)
COVERAGE = re.compile(r"^\[L93PassageReachCoverage\] (.*)$", re.M)
SUMMARY = re.compile(r"^\[L93PassageReachSummary\] (.*)$", re.M)
AUDIT = re.compile(r"^\[L93PassageReachAudit\] (.*)$", re.M)
FIELDS = re.compile(r"([a-zA-Z0-9_]+)=([^ ]+)")
def parse_fields(line: str) -> dict[str, str]:
return dict(FIELDS.findall(line))
def run(stratum: str) -> dict:
OUT.mkdir(parents=True, exist_ok=True)
spec = STRATA[stratum]
camera = ",".join(f"{value:.12f}" for value in spec["camera"]) + ",0,0"
log = OUT / f"{stratum.lower()}-reach-effects.log"
command = [
"taskset", "-c", "0-11", "prlimit", "--as=6442450944", "--", "env",
"VOXELFORGE_L81_PASSAGE_BOUND_PADDING_VOXELS=0", "timeout", "1740s",
str(BINARY), str(DATA), "--world-assembler-prototype", "--stream-benchmark",
"--stream-pipeline", "--workers=8", "--clip-radius=3", "--max-clip-level=8",
"--max-level=2", f"--camera={camera}", "--audit-passage-carve-reach",
]
started = time.monotonic()
try:
with log.open("w", encoding="utf-8") as stream:
proc = subprocess.run(command, cwd=ROOT, stdout=stream,
stderr=subprocess.STDOUT, check=False, timeout=1750)
except subprocess.TimeoutExpired as exc:
raise RuntimeError(f"reach effect audit exceeded 1,750 seconds: {log}") from exc
output = log.read_text(encoding="utf-8", errors="replace")
coverage = COVERAGE.search(output)
summaries = [parse_fields(match.group(1)) for match in SUMMARY.finditer(output)]
audit = AUDIT.search(output)
stamp = STAMP.search(output)
expected = spec["near"]
coverage_fields = parse_fields(coverage.group(1)) if coverage else {}
coverage_ok = (int(coverage_fields.get("tiles", "0")) == expected
and int(coverage_fields.get("lod0", "0"))
+ int(coverage_fields.get("lod1", "0"))
+ int(coverage_fields.get("lod2", "0")) == expected)
rows = []
for summary in summaries:
reach = float(summary["reach_m"])
tile_counts = summary["tiles"].split("/")
passed = (len(tile_counts) == 2 and int(tile_counts[0]) == expected
and int(tile_counts[1]) == expected
and summary["status"] == "PASS")
rows.append({
"reach_m": reach,
"tiles": summary["tiles"],
"samples": int(summary["samples"]),
"changed_samples": int(summary["changed_samples"]),
"sign_flips": int(summary["sign_flips"]),
"edge_crossing_mismatches": int(summary["edge_crossing_mismatches"]),
"moved_crossings": int(summary["moved_crossings"]),
"max_displacement_cm": float(summary["max_displacement_cm"]),
"max_normal_degrees": float(summary["max_normal_degrees"]),
"normal_pairing_failures": int(summary["normal_pairing_failures"]),
"status": "PASS" if passed else "FAIL",
})
row = {
"stratum": stratum,
"exit_code": proc.returncode,
"wall_s": round(time.monotonic() - started, 3),
"expected_near_tiles": expected,
"coverage": coverage_fields or None,
"coverage_ok": coverage_ok,
"reaches": rows,
"audit": parse_fields(audit.group(1)) if audit else None,
"source_stamp": stamp.group(1) if stamp else None,
"log": str(log.relative_to(ROOT)),
}
(OUT / f"{stratum.lower()}-reach-effects.json").write_text(
json.dumps(row, indent=2) + "\n", encoding="utf-8")
print("[L93CarveReachRun] " + json.dumps(row, sort_keys=True), flush=True)
return row
def main() -> int:
parser = argparse.ArgumentParser()
parser.add_argument("--stratum", choices=tuple(STRATA), required=True)
args = parser.parse_args()
if not BINARY.is_file() or not DATA.is_file():
raise SystemExit(f"missing input: {BINARY} or {DATA}")
rows = [run(args.stratum)]
summaries: dict[str, dict] = {}
for reach in REACHES:
samples = [row for run_row in rows for row in run_row["reaches"]
if row["reach_m"] == reach]
summaries[f"{reach:g}"] = {
"strata": len(samples),
"sign_flips": sum(row["sign_flips"] for row in samples),
"edge_crossing_mismatches": sum(row["edge_crossing_mismatches"] for row in samples),
"max_displacement_cm": max((row["max_displacement_cm"] for row in samples), default=0.0),
"max_normal_degrees": max((row["max_normal_degrees"] for row in samples), default=0.0),
"normal_pairing_failures": sum(row["normal_pairing_failures"] for row in samples),
"changed_samples": sum(row["changed_samples"] for row in samples),
"status": "PASS" if len(samples) == len(rows)
and all(row["status"] == "PASS" for row in samples) else "FAIL",
}
result = {"runs": rows, "reach_summary": summaries}
(OUT / f"summary-{args.stratum.lower()}.json").write_text(
json.dumps(result, indent=2) + "\n", encoding="utf-8")
print("[L93CarveReachSummary] " + json.dumps(result, sort_keys=True), flush=True)
return 0 if all(row["coverage_ok"] and row["source_stamp"]
and row["audit"] and row["audit"].get("status") == "PASS"
for row in rows) and all(item["status"] == "PASS"
for item in summaries.values()) else 14
if __name__ == "__main__":
raise SystemExit(main())