C0/S1/W1/W2/S2 でコスト構造が 5 段変わったことを受け、<code>BackendConfig</code> 全 16 field を機械走査して保持 variant を再判定。実測 9 件のうち <strong>8 件は verdict 維持</strong>、<strong>1 件 (<code>loss_path = "gpu"</code>) が flip</strong> — replay final regime で <strong>-26.5%</strong> (21.210 → 15.591 ms/iter、sync-tax 9.20 → 2.96)、iter5000 で -29.6%。残り 7 件は validate hard error による構造的非互換 / 禁忌リスト / harness 非対応で「判定不能」を理由付きで記録した。副産物として <code>splat bench</code> が <code>BackendConfig::validate</code> を呼んでおらず、<code>forward_submission="chained"</code> + <code>tile_sort="tile_counting"</code> のような無効組合せを <strong>exit 0 で黙って別経路実行</strong>していたことを発見し修正。
BackendConfig 全 16 field を機械走査し、default 以外の variant を全数再判定。実測 9 件のうち 8 件は verdict 維持、1 件 (loss_path) が flip。loss_path = "gpu" は replay final regime 21.210 → 15.591 ms/iter (-26.5%) / iter5000 -29.6%、12.5k full gate (同一 session 交互 A/B、n=3) で 283.00 → 183.00s (-35.3%)・PSNR 36.142 → 36.188 dB (+0.047、guard ±0.1 内)。ただし この flip は公式数値を 1 つも動かさない hygiene — 全 237 config が loss_path を明示指定済みで 12.5k gate 系は例外なく "gpu"、enum default だけが 2026-04-30 以来実運用から取り残されていた。残り 7 件は validate hard error による構造的非互換 (5) / 禁忌リスト (2) / harness 非対応 (1) / 非 perf variant (3) として理由付きで判定不能を記録。副産物として splat bench の validate() 抜け (無効組合せが exit 0 で silent 別経路実行) を発見・修正した。2026-08-16 の 1 日で default スタックのコスト構造は C0 (resident binning) → S1 (pipeline 全域 resident) → W1 (warp sparse skip) → W2 (chained submission) → S2 (forward 1 CB 化) と 5 段変わった。`BackendConfig` の保持 variant はいずれもこれ以前の環境で verdict が付いており、規約 (敗者 variant も enum に残し、コスト構造が変わったら再判定する) に従って全 16 field を機械走査し、default 以外の variant を全数再判定した。判定は `splat bench` の fixed-workload replay (Lego final checkpoint 409,660 splats、warmup 20 / iters 200) で行い、有意閾値は harness calibration の規約どおり max(2σ, 1%)。
実測できた 9 flag のうち 8 flag は verdict 維持、1 flag が flip。flip したのは loss_path で、enum default の Host に対し Gpu が replay final regime 21.210 → 15.591 ms/iter (-26.5%)、iter5000 regime 20.712 → 14.592 (-29.6%)。機構は GPU busy 56.6% → 81.0% / sync-tax 9.20 → 2.96 ms/iter が直接示す — submission = "chained" (W2) の Stage B (loss chain 1 CB 統合) は GPU loss 経路にしか効かない設計なので、loss_path = Host の default は W2 の主要部分を丸ごと取りこぼしていた。残り 7 flag は validate hard error による構造的非互換 (5)・禁忌リスト (2)・harness 非対応 (1)・非 perf variant (3) で判定不能とし、理由を enum doc と下表に記録した。
再判定の非互換確認中に、splat bench が BackendConfig::validate() を一度も呼んでいないことが判明した (呼んでいたのは train 側の FullConfig::validate のみ)。このため forward_submission = "chained" + tile_sort = "tile_counting" のような validate が hard error で禁じている組合せが exit 0 で通り、22.770 ms/iter という「もっともらしい数字」を吐いていた。実体は encode_forward_chained が use_tile_counting_sort を一切参照せず global radix を走らせていただけで、flag が silent に無視された default と同じ測定だった。これは validate が hard error として防ぐことを目的にしていた silent override そのもの。bench.rs の config load と --parity candidate 読み込みの 2 箇所に validate() を追加して塞ぎ、あわせて取り残されていた C3 bench 用 config 4 本 (S2 の default flip 時に train 側 config だけ修復されていた) に当時の実効値 forward_submission = "per_stage" / radix_scan = "cpu" を明示した。
「default 以外の variant を持つか」で機械走査し、持つものは全て下表に載せた。判定 列の 維持 は再判定しても既存 verdict が変わらないこと、flip は default 交代、判定不能 は測定が原理的に取れないことを指す。Δ は replay final regime n=3、baseline は sweep 内 3 点の実行位置線形補間 (§3 参照)。
| field | 再判定した variant | Δ (final, n=3) | σ | 閾値 | 判定 | 根拠 |
|---|---|---|---|---|---|---|
| `loss_path` | `gpu` | **-26.49%** | 2.12% | 1.92% | **flip** | 12.5k gate 済 (§2)。W2 Stage B は GPU loss 経路専用 |
| `emit_pairs` | `stop_the_pop` | -0.05% (n=10) | 1.11% | 2.22% | 維持 (棄却) | n=3 で -1.39% と閾値近傍 → n=10 に escalate して null 確定 |
| `backward` | `original` | +13.26% | 2.33% | 4.66% | 維持 (棄却) | warp_any は Simd 専用のため W1 喪失分を含む合成 Δ |
| `backward` | `tg` | +63.61% | 0.31% | 1.92% | 維持 (棄却) | 同上。禁忌 `!33c` だが依頼の明示指定で 1 判定のみ実施 |
| `raster_backward_sparse` | `off` | +16.21% | 0.17% | 1.92% | 維持 (敗退) | W2/S2 後は busy 律速寄りで W1 の効きは gate 時 (-11.2%) より **拡大** |
| `raster_backward_range` | `full_range` | +5.30% | 0.26% | 1.92% | 維持 (敗退) | W1 が backward 定数コストを先に削ったぶん gate 時 (-14.98%) より縮小 |
| `forward_submission` | `per_stage` | +4.82% | 0.12% | 1.92% | 維持 (敗退) | 両 arm で hierarchical scan 固定 → **1 CB 化単独の寄与 ≈ -4.8%** |
| `submission` | `per_kernel` | +3.59% | 0.54% | 1.92% | 維持 (敗退) | gate 時 -13.7% から 1/4 に縮小 (S2 と回収先が一部重複) |
| `target_cache` | `false` | (-0.70%) | 0.58% | 1.92% | 判定不能 | **harness 非対応** — bench は `train_step` 直叩きで target を事前 upload、flag が no-op |
| `tile_sort` | `tile_counting` | — | — | — | 判定不能 (skip) | validate hard error (S2 は global_radix 必須)。再判定仮説は falsified (§4) |
| `dispatch` | `batched_tail` | — | — | — | 判定不能 (skip) | validate hard error — S2 が A.7 の統合対象を包含し排他化 |
| `radix_scan` | `cpu` | — | — | — | 判定不能 (skip) | validate hard error (S2 は per-pass host 往復を許さない) |
| `radix_scan` | `gpu` (F.3 flat) | — | — | — | 判定不能 (skip) | 同上 |
| `binning` | `per_iter_alloc` | — | — | — | 判定不能 (skip) | validate hard error (chained は resident arena 前提) |
| `emit_pairs` | `simd` | — | — | — | 再判定せず | **禁忌リスト** `!33b` SIMD prefix (禁忌はコスト構造変化の例外) |
| `forward` | `f16` | — | — | — | 再判定せず | **禁忌リスト** feat.G f16 forward |
| `shader_fast_math` | `false` | — | — | — | 対象外 | perf variant ではなく IEEE 準拠 bit-repro 用 (設計上遅い) |
| `queue_reuse` | `false` | — | — | — | 対象外 | documented no-op (M-3 で per-iter queue 経路は消滅) |
| `profile` | `true` | — | — | — | 対象外 | 計測用 instrumentation であって perf variant ではない |
LossPathKind::Gpu の verdict は 2026-04-30 以来「検証中 (30k validation 未確定)」のまま据え置かれており、今日の 5 段のコスト構造変化をどれも通っていない唯一の flag だった。しかも SubmissionKind::Chained (W2、今日 default 化) の doc が明記するとおり Stage B (ssim → loss → backward → adam の 1 CB 連結) は GPU loss 経路にしか効かない。つまり enum default (Host) のままだと W2 の主要部分が無効化される状態が今日ずっと続いていた。
| regime | host (enum default) | gpu (候補) | Δ | σ | 閾値 | 判定 |
|---|---|---|---|---|---|---|
| final (409,660 splats) | 21.210 ms/iter | 15.591 | **-26.49%** | 2.12% | 1.92% | 有意 (13.8x) |
| iter5000 (373,933 splats) | 20.712 ms/iter | 14.592 | **-29.55%** | 2.12% | 4.24% | 有意 (7.0x) |
| GPU busy (final) | 56.6% | 81.0% | +24.4pp | — | — | 機構 |
| sync-tax (final) | 9.204 ms/iter | 2.961 | **-67.8%** | — | — | 機構 |
| GPU busy ms/iter (final) | 12.007 | 12.605 | +0.60 | — | — | GPU 実仕事はほぼ不変 |
sweep の冒頭 / 中間 / 末尾に同一 default baseline を 3 回挟んだところ 15.566 → 15.714 → 15.954 ms/iter と単調増加 (spread 2.46%) の thermal drift が出た。閾値 1.92% と同オーダーなので、pooled mean を基準にすると sweep 後半の arm が一律に不利化する。そこで各 arm の Δ は 実行位置による baseline の線形補間に対して算出した。影響が大きいのは後半に測った 2 件 (submission = per_kernel +3.59%、forward_submission = per_stage +4.82%) で、pooled baseline だと +4.4% / +7.1% と過大評価される。いずれも符号と結論は変わらないが、卒論に載る数字としては補間後を採る。
stop_the_pop のみ n=10 へ escalate した。結果 n=3 の -1.39% は n=10 で -0.05% に収束し、ノイズだったことが確定 (両 arm を隣接実行して drift も抑えた)。splat/crates/splat-train-v1/src/config.rs (各 enum に「2026-08-16 S2 後再判定」行を追記)splat/crates/splat-cli/src/cmd/bench.rs (`BenchTomlConfig::from_path` + `run_parity`)splat/configs/2026-08-16-c3-bench-*-tile_counting.toml / 2026-08-16-c3-parity-candidate.tomldocs/findings/p2-bench-harness-calibration.tomldocs/architecture/backend-and-compiler-conventions.mddocs/strategy/2026-08-msplat-gap-sweep.md 大原則 4| arm | r1 | r2 | r3 | mean | sd | median |
|---|---|---|---|---|---|---|
| host wallclock [s] | 265.0 | 262.0 | 322.0 | **283.00** | 33.81 | 265.0 |
| gpu wallclock [s] | 179.0 | 186.0 | 184.0 | **183.00** | 3.61 | 184.0 |
| host PSNR [dB] | 36.176 | 36.101 | 36.148 | **36.142** | 0.038 | 36.148 |
| gpu PSNR [dB] | 36.114 | 36.240 | 36.211 | **36.188** | 0.066 | 36.211 |
splat/configs/ の 全 237 config が loss_path を明示指定しており、default 依存の config は 0 件。とくに卒論に載る 12.5k gate 系 (C0/S1/W1/W2/S2 の *-12500-*.toml) は例外なく loss_path = "gpu" を書いていた。したがって本 flip で挙動が変わる既存 run は 1 つも無く、公表済み wallclock / PSNR は一切変更されない。変わるのは「config で明示しなかった場合の既定値」だけであり、その意味でこれは性能改善の主張ではなく enum default を実運用の実態に揃える hygiene である。逆に言えば、default が Host のままだと W2 Stage B を取りこぼした構成が「既定」として提示され続けるという実害があった。
C0 / W1 / W2 / S2 の default flip はいずれも bit-exact 主張を伴い、bench --parity や単体 fixture の byte equality で裏付けられていた。loss_path は違う — host と GPU で SSIM の計算経路そのものが異なり、しかも --parity は GPU loss 経路専用なので 構造的に parity 比較ができない。品質証拠は 12.5k の PSNR 対比 (Δ +0.047 dB) のみである。補強として既存の Lego 12.5k / loss_path = Gpu の run 19 本が PSNR 36.183 ± 0.045 dB の帯を成しており、本 gate の host arm (36.142) / gpu arm (36.188) はいずれも帯の内側。なお phase5-step31-x-gpu-loss.md はこの比較で n=1 の PSNR -0.65 dB regression を報告し 4-sample variance test で撤回した経緯がある — 「撤回」は差が無いことの証明ではないので、n=3 の spread (host sd 0.038 / gpu sd 0.066 dB) まで見て guard 内と判断した。
本タスクは GPU 専有条件で実施したが、作業中に 2 回この条件を自分で破った: (1) validate 制約の網羅確認のため committed config を全件 `splat bench` に通したところ、これが実際に bench を実行し 12.5k gate の `gpu-r1` と競合した。(2) `cargo test` を gate 実行中に走らせ `host-r2` と競合した。とくに (2) は host loss 経路が host 側 SSIM で CPU 律速であるため、CPU 競合が host arm の wallclock を膨らませ 「gpu が速い」という自分の仮説に有利な方向にバイアスする。両 run は無効として破棄し、全 job 停止後に単独で取り直した clean run で置き換えた (上表の r1 host 側以外はすべて clean)。以後の validate 網羅確認は GPU を使わない静的 TOML 解析で行い、全 237 config が制約を満たすことを確認した。
この finding が観測された / 言及している実験 run。