[{"data":1,"prerenderedAt":385},["ShallowReactive",2],{"finding:p3-s4b-ssim-reduce":3,"finding-runs:p3-s4b-ssim-reduce":280,"finding-related:p3-s4b-ssim-reduce":281},{"meta":4,"sections":47},{"id":5,"title":6,"subtitle":7,"eyebrow":8,"date":9,"status":10,"category":11,"polarity":12,"axes":13,"tags":16,"task_code":25,"commit":26,"branch":27,"config_paths":28,"related_runs":35,"related_findings":42},"p3-s4b-ssim-reduce","S4b — read_mean_ssim を gpu に移す ssim_reduce flag、採用確定 (2026-08-30 gate)","`p3-s4-host-shadow` §7 follow-up の実装。`[backend] ssim_reduce = \"host\" | \"host_lagged\" | \"gpu\"` を追加した。\u003Cstrong>gpu\u003C\u002Fstrong> は `loss.metal` の `loss_l1_only` と同型の 1 dispatch reduction (`ssim_sum_reduce`、warp `simd_sum` → lane 0 `atomic_fetch_add`) に置き換え、host 仕事を 4 byte readback まで削る — pipelining \u002F host_schedule に依存せず全 iteration で効くが bit-exact ではない (atomic 加算順非決定性、`loss_path = \"gpu\"` の L1 項がすでに持つ性質と同種)。gradient (`ssim_backward*`) には一切触れないため \u003Cstrong>PSNR には構造的に影響しない\u003C\u002Fstrong> (§5 参照)。\u003Cstrong>host_lagged\u003C\u002Fstrong> は `host_schedule = \"backward_shadow\"` の 6.38ms shadow に `read_mean_ssim` 自体を 1 iteration 遅らせて重ねる設計 (値は同一 buffer に対する読みなので bit-exact) だが、`p3-s4-host-shadow` 本体の 12.5k gate が backward_shadow を棄却した (+1〜5% 遅い) ため実用価値が下がり、**gate 対象から外したまま実装・test のみ完了させて残した**。\u003Cstrong>12.5k n=3 交互 A\u002FB gate (2026-08-30 実施) で Δ \u003Cstrong>-1.4347%\u003C\u002Fstrong> (閾値 max(2σ_off,1%)=1.0%)、PSNR +0.053dB (guard -0.05dB 内)、3\u002F3 pair 一貫 (on&lt;off) — 採用確定、`BackendConfig::default()` の `ssim_reduce` を `Gpu` に flip した\u003C\u002Fstrong>。事前見積り (-2〜-4%、§2b) より実測は小さかった (host 仕事 13.66s 削減のうち wallclock 回収は 1.79s = 変換効率 13%、§7 で機構解釈)。`cargo test --workspace --release` 全 pass。","2026-09 ゼミ milestones · S4b 採用 · C2\u002FS4 follow-up","2026-08-30","stable","implementation","positive",[14,15],1,3,[17,18,19,20,21,22,23,24],"s4b","c2","ssim-reduce","gpu-reduction","host-lagged","pipelining","gate-adopted","default-flip","S4b: read_mean_ssim を gpu\u002Fhost_lagged で移動する ssim_reduce flag 実装 + 12.5k gate","9daa57978c9b (実装) \u002F gate + default flip は main HEAD 1c54a0b 上で実施 (binary sha256 a4317ea72e8b35e259075859c3e312fac2930a28f7d92db7849894087ccfef4e、series 中に main HEAD が docs-only commit b88e4dcb86c3 [re200 finding] へ移動したが binary は再ビルドしておらず sha256 は series 通じて不変、gate 結果に影響なし)、後続 commit","worktree-agent-a9945be09639eb3a5 (実装、main merge 済み) \u002F main (gate + flip)",[29,30,31,32,33,34],"splat\u002Fconfigs\u002F2026-08-30-s4b-12500-off-r1.toml","splat\u002Fconfigs\u002F2026-08-30-s4b-12500-off-r2.toml","splat\u002Fconfigs\u002F2026-08-30-s4b-12500-off-r3.toml","splat\u002Fconfigs\u002F2026-08-30-s4b-12500-on-r1.toml","splat\u002Fconfigs\u002F2026-08-30-s4b-12500-on-r2.toml","splat\u002Fconfigs\u002F2026-08-30-s4b-12500-on-r3.toml",[36,37,38,39,40,41],"splat\u002Fruns-logs\u002Fs4b-12500-off-r1.log","splat\u002Fruns-logs\u002Fs4b-12500-on-r1.log","splat\u002Fruns-logs\u002Fs4b-12500-off-r2.log","splat\u002Fruns-logs\u002Fs4b-12500-on-r2.log","splat\u002Fruns-logs\u002Fs4b-12500-off-r3.log","splat\u002Fruns-logs\u002Fs4b-12500-on-r3.log",[43,44,45,46],"p3-s4-host-shadow","p3-c2-bubble-attribution","p2-s3-iteration-pipelining","p3-final-stack",[48,51,54,75,87,89,94,105,107,118,120,129,131,158,160,167,169,186,262,266,268,271,273],{"type":49,"text":50},"lead","`p3-s4-host-shadow` §7 は「`read_mean_ssim` (1.92M 要素の CPU 総和、`loss = \"l1_ssim\"` の host 仕事 1.871ms\u002Fiter で最大の未着手候補) を動かせば、S4 の実測見積り (-1.5〜-3%) を元の -3〜-5% レンジに近づけられる可能性が高い」と申し送っていた。本 finding はその follow-up 実装 — `[backend] ssim_reduce` flag に `host` (default) \u002F `host_lagged` \u002F `gpu` の 3 variant を追加し、消費箇所の分類・2 案の比較・test・gate config 準備までを行う。",{"type":52,"text":53},"heading","1. `read_mean_ssim` の呼び出し経路と消費箇所の分類",{"type":55,"columns":56,"align":60,"rows":62},"table",[57,58,59],"呼び出し元","経路","消費先",[61,61,61],"left",[63,67,71],[64,65,66],"`train_loop.rs` L266 (train_step、`pipelining = \"off\"`)","`wait(B_it)` 直後に同期呼び出し","`total_loss` → `StepOutcome` 相当の戻り値 → `history.push`",[68,69,70],"`pipeline.rs` `Depth2Pipeline::step` (`pipelining = \"depth2\"`)","同上 (S4 以前は常に同期)","`loss_value` → `StepOutcome.loss` → `train_loop` の `history.push`",[72,73,74],"`loss_and_backward` 系 legacy host path (`forward_and_grad_buf` \u002F `forward_and_grad`)","CB 内で完結、host が commit+wait 後に自前で総和","parity test \u002F host fallback 専用、production では不使用",{"type":76,"items":77},"kv",[78,81,84],{"key":79,"value":80},"`loss_history` (`TrainOutcome.loss_history`)","`train_loop` が毎 iteration 1 個 push する `Vec\u003Cf32>`。**唯一の実質的な消費者はさらに 2 段先**: (1) `outcome.loss_history.last()` → CLI の `final_loss_value` (stderr 表示 + `result.toml` `metrics.final_loss`)、(2) `snapshots` (`log_every` ヒット時の `TrainSnapshot { iter, loss, splats }`) → `result.toml` `[curve.loss]` (web の run summary グラフ)。**refine tick \u002F 早期停止判定 \u002F eval は loss を一切参照しない** (`splat-train-v1\u002Fsrc\u002Frefine.rs` に `loss` という識別子は 0 件、grep で確認済み) — refine は `it % every` のみで駆動する純粋な iteration counter 駆動",{"key":82,"value":83},"1 iteration 遅延しても意味論が変わらないもの","`loss_history` の**中間**エントリ (`i` 番目の値が eventually 正しい iteration `i` の値になっていれば、host が『いつ』計算するかは result.toml\u002Fstderr の見た目に一切影響しない) — 唯一の制約は『配列の長さと各要素の帰属を保つ』こと",{"key":85,"value":86},"1 iteration 遅延すると意味論が変わるもの","(1) **最終 iteration (`it == max_steps`) の loss** — `loss_history.last()` が `result.toml` の `final_loss` として報告される実質的な成果指標なので、1-step stale になると『学習が実際にどこで終わったか』とズレた値を報告してしまう。(2) **`snapshots` (`log_every` ヒット時)** — `curve.loss` は『iteration `it` 時点の loss』として web に描画されるグラフなので、defer されたまま古い値が入ると per-iteration 帰属が壊れる (advisor 指摘)。(3) **refine tick 直前の値** — 本実装には該当する消費者が無い (refine は loss を見ない) ので理論的な懸念に留まる、念のため §3 の設計はこの経路も汚さないよう `is_snapshot_iter` 相当のガードを refine tick には不要と判断した (refine tick 自身の iteration は `param_mutated_after_step` により `prefetched=false` になるため、defer 条件が構造的に成立せず自動的に安全)",{"type":52,"text":88},"2. 案 (a) GPU reduction と (b) 1 iteration lag の比較 — 選定は「両方実装」",{"type":90,"label":91,"variant":92,"text":93},"callout","禁忌リストとの関係 — #5.33c \u002F #5.34.a とは別物","info","`docs\u002Fstrategy\u002F2026-08-msplat-gap-sweep.md` の禁忌リスト「reduction (`!33c`)」「SSIM threadgroup 単独 (`#5.34.a`)」を実読して確認した。**`!33c` は rasterize backward の `backward = \"tg\"` (threadgroup-memory 版 atomic emit 分散) の話** (`config::BackwardKind::Tg` doc、`docs\u002Ffindings\u002Fp2-w1-warp-sparse-skip.toml` 参照) で、SSIM とは無関係。**`#5.34.a` は SSIM forward\u002Fbackward 本体を threadgroup-mem 化する試み** (`docs\u002Ffindings\u002Ffeat-bundle-musing-mendeleev-inventory.md`、gate 不通過で REJECT) であり、こちらも今回の対象 (SSIM forward が**すでに計算し終えた**per-window 値の総和のみを行う 1 dispatch kernel) とは別物。よって `ssim_sum_reduce` kernel は禁忌に抵触しない。",{"type":76,"items":95},[96,99,102],{"key":97,"value":98},"(a) GPU reduction (`ssim_sum_reduce`)","実装してみると想定より工数が低かった — `loss.metal` の `loss_l1_only` (`splat-metal\u002Fsrc\u002Fkernels\u002Floss.rs` の `LossEvaluator`) が**すでに同型の kernel** (`atomic\u003Cfloat>` + `simd_sum`、`loss_sum_buf` の zero-clear→dispatch→4 byte readback) を実装・本番稼働させていたため、そのパターンを丸ごと再利用するだけで済んだ。**利点**: pipelining\u002Fhost_schedule に一切依存せず、`prefetched == false` の iteration (refine tick・grad RMW・MCMC noise・最終 iteration) でも効く — host 仕事を『どかす』のではなく『消す』。**欠点**: bit-exact ではない (atomic 加算順が dispatch ごとに非決定的)。ただし `loss = \"l1_ssim\"` の L1 項はすでに `loss_l1_combine_ssim` の atomic 加算で同じ性質の ULP 揺れを持っており (`loss.metal` 冒頭コメントで既存文書化済み)、**新しい種類の非決定性を持ち込むわけではない**。gradient (`ssim_backward*`) には一切触れないので学習結果 (PSNR) への影響は理論上ゼロ",{"key":100,"value":101},"(b) 1 iteration lag (`host_lagged`)","`host_schedule = \"backward_shadow\"` が既に実装した『grad readback を 1 iteration 遅らせて次の backward CB shadow で flush する』パターンをそのまま SSIM 総和に適用。`work_ssim` は `Rasterize::work_grad` と同じ `GenScratch` 2 世代 ping-pong に乗っているため (`ssim.rs` の既存コメントがこれを明記していた)、grad buffer と全く同じ安全性論証が成り立つ。**利点**: アルゴリズム自体は `Host` と完全同一 (CPU `f64` 逐次総和) なので、同一 buffer に対しては値が bit-exact (`read_mean_ssim_from_buf_matches_synchronous_read` test で pin)。**欠点**: `host_schedule = \"backward_shadow\"` かつ『この iteration が次を prefetch した』ときにしか効かない — refine tick 直前 \u002F RMW \u002F 最終 iteration では構造的に no-op。実装コストは (a) より高い: `loss_history` の bit-exact 性を保ったまま `history.push` 自体を 1 slot 遅らせる設計 (`StepOutcome.loss: Option\u003Cf32>` + `StepOutcome.deferred_loss: Option\u003Cf32>` の 2 本立て、`StepCtx.is_snapshot_iter` で snapshot\u002Flog 消費点だけ defer を止める) が必要だった",{"key":103,"value":104},"選定","**advisor レビューでの結論に従い、両方を `ssim_reduce` の 3 variant (`host`\u002F`host_lagged`\u002F`gpu`) として実装した**。「工数と bit-exact 性で有利な方」を単独で選ぶなら bit-exact 性は (b)、実測工数は (a) の方が僅かに低かった (loss.metal の precedent を丸ごと再利用できたため) — 実装時点では甲乙つけがたく、かつ (a) は (b) が構造的にカバーできない iteration (refine tick 等) もカバーするため両方を実装した。**その後判明した追加情報 (`p3-s4-host-shadow` 本体の 12.5k gate 結果) が選定を確定させた**: `host_schedule = \"backward_shadow\"` が gate で棄却された (+1〜5% 遅い、期待符号と逆) ため、それに依存する (b) `host_lagged` は現状の production スタックでは**発火する場面が無い** (`backward_shadow` を有効にしないなら `host_lagged` は常に no-op)。よって **(a) gpu を唯一の gate 対象 (on arm)** とし、(b) host_lagged は実装・test のみ完了させた代替 flag として残す (追加工数はかけない、`p3-s4-host-shadow` の verdict が将来覆った場合の再利用候補)",{"type":52,"text":106},"2b. gate 前の Δ 予測と PSNR guard の位置づけ (advisor 指摘、gate 実施前に明記)",{"type":76,"items":108},[109,112,115],{"key":110,"value":111},"Δ 予測 (wallclock、`ts_ssim_host_sum` 実測後の確定版)","計装 (§4) の結果、1000 iter smoke (800×800、splats ~6.8k) で `ts_ssim_host_sum` (host 経路の同期 CPU 総和) = **1.093ms\u002Fiter** (TOTAL[sum] の 31.0%) — `p3-c2-bubble-attribution` §4 の事前見積り (grad copy 150µs + accumulate 407µs を引いた残り ≈1.3ms) とほぼ整合。SSIM 総和は **`W*H*3` の image-size-bound コストで splat 数に依存しない** (forward\u002Fbackward\u002Fbinning は splat 数に比例) ため、この 1.093ms\u002Fiter という絶対値は 12.5k 本番 regime (400k splats) でもほぼ同じ値で持ち越せると見積る。base の forward shadow (2.00ms) に対し host 仕事 1.871ms\u002Fiter (fill 93.6%、`p3-c2-bubble-attribution` §4) のうち SSIM 総和が 1.093\u002F1.871=**58%** を占める計算になる。`gpu` はこれを ~0 (実測 `ts_ssim_host_sum`=29.6µs + `ts_ssim_sum_reduce` encode 326ns、合計 \u003C0.04ms) まで削るので、fill 率は 93.6% → 93.6%×(1-0.58)=**39%程度**まで下がる。残差 7.2〜8.1s (wall比 5.8〜6.5%、`p3-c2-bubble-attribution` §5) が host-late にほぼ 1:1 対応するという機構仮説のもとでは、回収量は概ね『動かした割合』(58%) に比例: 残差の 58% ≈ **4.2〜4.7s (wall 124.75s 比 3.4〜3.8%)**。ceiling ではなく比例見積りであり、fill 率が 100% を割った時点で理論上は頭打ちになるはずなので実際の回収はこれより小さく出る可能性がある一方、fill 率が 39% まで下がれば host-late 自体がほぼ消える可能性もある。**レンジとして -2〜-4% と見積る**",{"key":113,"value":114},"smoke 規模での実測 (参考、production 規模への外挿には注意)","1000 iter smoke (splats ~6.8k) では **wall 3.427s (host) → 2.927s (gpu)、busy 76.0% → 91.4%** という大きな差が観測できた (Δ -14.6%)。これは `p3-s4-host-shadow` の smoke が『grad copy\u002Faccumulate は splat 数に比例するコストなので splats ~6.9k では小さすぎて run-to-run noise に埋もれる』と結論づけたのと対照的 — **SSIM 総和は image-size-bound なので splat 数が少ない smoke 規模でも絶対値 (1.093ms\u002Fiter) がほぼ変わらず、むしろ per-iteration budget が小さい smoke ではその『相対的な重さ』が大きくなる**。この smoke の -14.6% という数字自体は 12.5k 本番の Δ (-2〜-4% と見積り) には直接外挿できない (400k splats では forward\u002Fbackward\u002Fbinning の絶対コストが増え、SSIM 総和 1ms が相対的に薄まる) が、**instrumentation が正しく効いていること・機構仮説 (host 仕事の削減が busy% を直接押し上げる) 自体は smoke でも定性的に確認できた** という点で価値がある",{"key":116,"value":117},"PSNR guard の位置づけ (advisor 指摘 — 誤読すると誤った verdict を出す)","`work_ssim` は `read_mean_ssim`\u002F`ssim_sum_reduce` からしか読まれず、そのまま `mean_ssim` → `total_loss` → `history` に流れるだけで、**gradient には一切合流しない** (gradient は別経路: `encode_forward_and_grad` が書く `work_grad` → `encode_l1_combine_ssim` の `dldr` → backward)。refine\u002FLR schedule\u002Fcheckpoint も loss を参照しない (§1 で確認済み)。**したがって `ssim_reduce` は構造的に学習された param を一切変えられない** — off\u002Fon で PSNR に系統的な差が出ることは原理的にありえない。gate で観測される off-vs-on の PSNR 差は **すべて backward atomic の run-to-run noise** (`per_kernel_single_texel_run_to_run_deterministic_1iter` と同型) であり、`p3-s4-host-shadow` の smoke が使った比較基準 (off-vs-off の splats 数ばらつき 6886 vs 6896 等) と同じ土俵で見るべきもの。**`±0.1 dB` の PSNR guard を『抵触したら NO-GO』の基準として使うのは誤り** — off-vs-off の repeat 内ばらつきと同程度の差なら『guard 抵触』ではなく『ノイズ』と正しく判定すること。次段が gate 結果を読むときにこの一段落を必ず参照すること",{"type":52,"text":119},"3. flag 配線と依存関係",{"type":121,"items":122},"list",[123,124,125,126,127,128],"`splat\u002Fcrates\u002Fsplat-train-v1\u002Fsrc\u002Fconfig.rs`: `SsimReduceKind { Host (#[default]), HostLagged, Gpu }`、`BackendConfig::ssim_reduce` field。`validate()` に `ssim_reduce = \"host_lagged\"` かつ `host_schedule != \"backward_shadow\"` の **warning** (host_schedule 自身の hard error とは非対称 — defer 条件が `self.backward_shadow && self.ssim_lagged && ...` の AND で構造的に false に落ちて `Host` と完全に同じ挙動になる『効かないだけで安全』なケースなので、config を reject するのではなく警告に留めた、advisor 指摘どおり fallback を doc に明記)","`splat\u002Fcrates\u002Fsplat-metal\u002Fsrc\u002Fkernels\u002Fssim.rs`: kernel-level mirror `SsimReduceKind { Host, Gpu }` (2 variant のみ — `HostLagged` は算法的に `Host` と同一なので mirror が要らない)。新規: `pso_sum_reduce` PSO、`sum_buf: GenValue\u003CBuffer>` (`loss.metal` の `loss_sum_buf` と同型)、`encode_sum_reduce()`、`read_mean_ssim(img_size, reduce)` (旧 API に reduce 引数を追加)、`read_mean_ssim_from_buf()` (deferred flush 専用、生 Buffer から直接総和)、`ssim_buf_handle()` (deferred flush 用に現在の `work_ssim` handle を clone)","`splat\u002Fshaders\u002Floss\u002Fssim.metal`: `ssim_sum_reduce` kernel を追加 (`loss.metal` の `loss_l1_only` と同一パターン、warp `simd_sum` → lane0 `atomic_fetch_add`)","`splat\u002Fcrates\u002Fsplat-train-v1\u002Fsrc\u002Fpipeline.rs`: `Depth2Pipeline` に `ssim_lagged: bool` \u002F `deferred_ssim: Option\u003CDeferredSsim>` を追加。`DeferredSsim { ssim_buf: Buffer, l1: f32, lambda: f32, img_size }`。`flush_deferred_ssim()` を新設し `flush_deferred_accumulate()` と同じ flush point (手順 4 の直後) で常時呼ぶ。`StepOutcome` を `{ loss: Option\u003Cf32>, deferred_loss: Option\u003Cf32>, prefetched_forward: bool }` に変更 — defer した iteration では `loss = None`、次の呼び出しの flush で確定した値が `deferred_loss` に載る。`StepCtx` に `is_snapshot_iter: bool` を追加 (snapshot\u002Flog 消費点では defer しない)。`encode_loss_backward_chain` に `trainer.ssim_reduce.get() == Gpu` のときだけ `encode_sum_reduce` を追加 encoder として積む処理を追加","`splat\u002Fcrates\u002Fsplat-train-v1\u002Fsrc\u002Ftrain_loop.rs`: `is_snapshot_iter` を `log_every` の条件式から計算し `StepCtx` に渡す。`let loss: Option\u003Cf32> = match {...}` に変更、`Some(p)` 枝で `out.deferred_loss` を先に `history.push`、その後 `out.loss` があれば push (`loss: Option\u003Cf32>` → `if let Some(l) = loss { history.push(l); }`)。snapshot\u002Flog ブロックは `is_snapshot_iter` をガードにし、`loss.expect(...)` で defer されていないことを pin する。`ssim_lagged` bool を `backend.ssim_reduce == HostLagged` から計算し `Depth2Pipeline::new` の第 4 引数に渡す (`host_schedule` と同じ配線パターン — `Trainer::Cell` を経由せず `backend: &BackendConfig` から直接)","`splat\u002Fcrates\u002Fsplat-train-v1\u002Fsrc\u002Ftrainer.rs` \u002F `splat\u002Fcrates\u002Fsplat-cli\u002Fsrc\u002Futil.rs`: `Trainer::ssim_reduce: Cell\u003CMetalSsimReduceKind>` を追加、`apply_backend_config` の exhaustive destructure に `ssim_reduce` を追加し `Host|HostLagged → Host`、`Gpu → Gpu` で配線 (host_lagged の defer タイミングは `train_loop` が直接読む別経路)",{"type":52,"text":130},"4. 検証結果",{"type":55,"columns":132,"align":135,"rows":136},[133,134],"検証","結果",[61,61],[137,140,143,146,149,152,155],[138,139],"`cargo test --workspace --release`","全 pass (splat-metal 95 [新規 2 本含む]、splat-train-v1 90 [新規 2 本含む]、他クレート含め failure 0)。`cargo test -p splat-train-v1` (debug profile) も全 pass",[141,142],"新規 test (`splat-metal\u002Fsrc\u002Fkernels\u002Fssim.rs`)","`ssim_sum_reduce_matches_host_within_tolerance` (128×128 fixture、複数 simdgroup にまたがる規模で `Gpu` vs `Host` の相対誤差 \u003C1e-4 を確認 — `new_single_texel` 級の 3 要素 1 warp では non-determinism 自体が発現せず識別力ゼロになる、advisor 指摘を踏まえた規模選定)。`read_mean_ssim_from_buf_matches_synchronous_read` (24×24、同一 command buffer 内で同期 read と deferred read が **bit-exact** — `HostLagged` の中核主張を直接 pin)",[144,145],"新規 test (`splat-train-v1\u002Fsrc\u002Ftrain_loop.rs`)","`ssim_reduce_host_lagged_matches_host_loss_history_bit_exact` (`loss_history` が `assert_history_matches` 基準で一致、`host.len()==lagged.len()==3` で末尾 slot 欠落なしを確認)。`ssim_reduce_host_lagged_without_backward_shadow_matches_host` (`host_schedule` 未設定でも `host_lagged` が no-op で `host` と一致することを実行時 pin、validate warning の主張の裏取り)",[147,148],"**発見 1**: `train_loop` レベルでは `Host` vs `HostLagged` の全要素 bit-exact 比較は誤って fail する","初版 test は全要素 `to_bits()` 一致を要求し、3 iteration 目 (最終 iteration、defer なし) で ULP 差により fail した。原因調査の結果、`loss = \"l1_ssim\"` の **L1 項自体** (`loss.metal` の `loss_l1_combine_ssim`、`atomic\u003Cfloat>` 加算) が `host_lagged` と無関係に run-to-run で非決定的であることが判明 (`per_kernel_single_texel_run_to_run_deterministic_1iter` の doc がすでに文書化していた性質と同型)。SSIM 総和自体の bit-exactness は低レベル test (`read_mean_ssim_from_buf_matches_synchronous_read`、L1 confound を排除した同一 CB 内比較) に切り出して pin し直し、`train_loop` レベルの test は既存規約 (`assert_history_matches`、iter1 は byte 一致・以降は rel tolerance) に合わせた",[150,151],"**発見 2**: `assert_params_close` にも host_lagged 非固有の低頻度 flakiness (~1\u002F30) が残る","`cargo test --workspace --release` を繰り返した際、新規 test (`ssim_reduce_host_lagged_matches_host_loss_history_bit_exact`) がまれに `rot_quats[2]` の rel tolerance (1e-4) をわずかに超えて fail した (rel≈1.14e-4)。30 回 stress run で 1\u002F30。**同じ 30 回 stress run を、host_lagged と無関係な既存 test `pipelining_depth2_backward_shadow_matches_off_steady_state_chain` (同じ 3-iteration 構成) にも実施したところ、こちらも 1\u002F30 で同じ signature (`rot_quats[2]`, rel≈1.13e-4) で fail した** — rasterize backward の per-splat grad atomic accumulate が run ごとに加算順が変わりうるという、fixture が既に持っていた性質であって S4b 固有の regression ではないことを確認。閾値は変更せず (緩めると real regression を見逃すリスクが増す)、doc に測定値を明記するに留めた",[153,154],"1000 iter smoke #1 (Lego、`loss=l1_ssim`、`refine.every=100 start=500` → 6 tick、`host_schedule=backward_shadow` 固定 [初版、後に base 変更で非該当]、`ssim_reduce={host,host_lagged,gpu}` 3 arm)","3 arm とも `peak_in_flight=2` \u002F `sync_iters=6` \u002F crash なし。`host`: wall 3.46s、final loss 6.674047e-2、splats 6809、PSNR 19.565 dB。`host_lagged`: wall 3.00s、final loss 6.542842e-2、splats 6861、PSNR 19.560 dB。`gpu`: wall 3.01s、final loss 6.622096e-2、splats 6889、PSNR 19.653 dB。loss\u002FPSNR\u002Fsplats は 3 arm とも n=1 の atomic 非決定性の範囲で近い値",[156,157],"1000 iter smoke #2 (base 修正版、`host_schedule` は default=forward_shadow、`ssim_reduce={host,gpu}` 2 arm、`ts_ssim_host_sum` 計装後)","両 arm とも `peak_in_flight=2` \u002F `sync_iters=6` \u002F crash なし、final loss\u002Fsplats\u002FPSNR は近い値 (host: 6.572725e-2 \u002F 6843 \u002F 19.606dB、gpu: 6.568488e-2 \u002F 6781 \u002F 19.593dB)。**`ts_ssim_host_sum` 実測: host = 1.093ms\u002Fiter (TOTAL[sum] の 31.0%)、gpu = 0.030ms\u002Fiter (+ `ts_ssim_sum_reduce` encode 0.326µs、合計 \u003C0.04ms)** — §2b の事前見積り (≈1.3ms) とほぼ整合。**busy%\u002Fwall にも明確な差が出た: host busy 76.0% \u002F wall 3.427s → gpu busy 91.4% \u002F wall 2.927s (Δ -14.6%)** — `p3-s4-host-shadow` の smoke (splat 数に比例するコストは splats~6.9k で不可視) と異なり、SSIM 総和は image-size-bound (`W*H*3`) で splat 数に依存しないため smoke 規模でも絶対値が変わらず可視化できた。ただしこの -14.6% は smoke 固有の per-iteration budget の小ささゆえで、12.5k 本番規模にそのまま外挿できない (§2b 参照)",{"type":52,"text":159},"5. 未解決点 \u002F 次段への申し送り",{"type":121,"items":161},[162,163,164,165,166],"~~**12.5k A\u002FB gate (n=3) 未実施**~~ → **2026-08-30 実施済み、採用確定**。§6\u002F§7 参照","**`host_lagged` は gate 対象外のまま (実装のみ、追加工数なし)** — `p3-s4-host-shadow` (backward_shadow) が棄却されたため現状の production スタックでは発火しない。`p3-s4-host-shadow` の verdict が将来覆るか、backward_shadow に依存しない別の defer 機構が生まれた場合の再利用候補として残す (verdict は §5 のまま変更なし、コードの enum doc にも同旨を追記済み)","**GPU reduction の regime 依存性が未検証のまま採用** — 128×128 (49,152 要素) の unit test では `Gpu` vs `Host` の相対誤差 \u003C1e-4 だったが、12.5k 本番 regime (800×800×3 = 1.92M 要素、K=7 window) では atomic 競合の規模が 2 桁近く大きい。gate 自体は wallclock\u002FPSNR の両方で pass しており (§6)、PSNR guard は「gradient 非変更のため理論上ノイズ」という設計上の主張どおりの挙動 (§7) だったため、この不確実性は採否判断をブロックしなかった","~~gate run 後は本 finding に verdict を追記~~ → **完了 (§6\u002F§7)**。§2b の Δ 予測 (-2〜-4%) は実測 (-1.4347%) より過大だったため、§7 で機構解釈を追記した","**`ssim_reduce_host_lagged_matches_host_loss_history_bit_exact` は ~1\u002F30 の確率で `assert_params_close` の rel tolerance をわずかに超えて fail しうる** (§4 発見 2 参照)。既存 sibling test も同水準の flake rate を持つ pre-existing な fixture 性質であり S4b 固有のバグではないため対処不要と判断したが、CI で偶発的に赤くなった場合はこの finding を参照して再実行で切り分けること (real regression なら閾値を大きく超える・再現性がある、のいずれかで区別できるはず)",{"type":52,"text":168},"6. 12.5k n=3 gate (2026-08-30、s4b-12500 series) — 採用根拠",{"type":76,"items":170},[171,174,177,180,183],{"key":172,"value":173},"前提","build: `cargo build --release`、HEAD `1c54a0b6a064` 上でビルド (binary sha256 `a4317ea72e8b35e259075859c3e312fac2930a28f7d92db7849894087ccfef4e`)。起動直前に `pgrep -fl \"target\u002Frelease\u002Fsplat\"` を確認したところ直前の re200 gate (別 finding `p3-refine-every-200`) の r2 pair retry がまだ稼働中だったため、その完了 (pgrep 空) を待ってから series を開始した。config 6 本は事前に `splat check` で ok を確認済み。AC 接続を series 通じて維持 (`pmset -g batt` で `AC Power` を都度確認、driver 自身も check_ac で監視)",{"key":175,"value":176},"driver","`splat\u002Fscripts\u002Fgate-ab-n.sh configs\u002F2026-08-30-s4b-12500-off configs\u002F2026-08-30-s4b-12500-on s4b-12500 3` (nohup+disown で detach、`s4b-12500-gate.DONE` sentinel で完了検出)。**1 回目起動は prefix に `configs\u002F` を付け忘れて off-r1 が `config IO error` で即時 rc=1 終了 (GPU work 無し、0.018s) — ログは `s4b-12500-*-BADPREFIX-attempt1.*` として保存し、prefix を修正して再起動した (2 回目が本 gate の実測)**",{"key":178,"value":179},"binary\u002FHEAD provenance","series 開始時 binary sha256 `a4317ea7…` \u002F HEAD `1c54a0b`。**series 完了時、driver が記録した binary sha256 は開始時と同一 (`a4317ea7…`、不変)**、一方 `git rev (post-series)` は `b88e4dcb86c3` に変わっていた — 別 finding (`p3-refine-every-200`、re200 gate の結果) の docs-only commit が series 実行中に main へ入ったため。code 変更を含まないコミット (`git show --stat` で確認、変更は `docs\u002Ffindings\u002F*` と `splat\u002Fconfigs\u002F2026-08-30-re200-*` と `splat\u002Fruns-logs\u002Fre200-*` のみ) であり、かつ binary は series 中一度も再ビルドしていないため、**6 run はすべて単一 binary (`a4317ea7…`) 上で実行されており gate 結果への影響はない**",{"key":181,"value":182},"flag 実測確認 (6\u002F6)","全 6 run の `[backend] BackendConfig { … }` から他の全 flag が off\u002Fon 間で完全に同一であることを確認 (`backward=Simd, loss_path=Gpu, binning=Resident, pipelining=Depth2, host_schedule=ForwardShadow, refine_scratch_persist=true, refine_direct_write=true` 等)、差分は `ssim_reduce: Host` (off 3\u002F3) \u002F `ssim_reduce: Gpu` (on 3\u002F3) のみ",{"key":184,"value":185},"汚染 \u002F retry 判定","事前登録条件 (`p3-tier1-bit-exact.toml` §5 の教訓どおり (i) load 証拠 AND (ii) 自 arm 内 3σ 超 の **AND**) を両 arm 全 6 run に適用。off (125.094, 124.605, 123.966, mean 124.555, sample σ 0.566s=0.454%) — 最大偏差は off-r1 の 0.95σ、off-r1 の run 窓内 load1 (mean 3.99, max 5.12) は他の run より高いが (i) のみで (ii) 不成立。on (123.987, 122.062, 122.254, mean 122.768, sample σ 1.060s=0.864%) — 最大偏差は on-r1 の 1.15σ。**いずれの run も条件 (ii) の 3σ を大きく下回るため retry 対象なし、6 run すべてそのまま採用**",{"type":55,"columns":187,"align":196,"rows":198},[188,189,190,191,192,193,194,195],"実行順","arm","run","train elapsed (s)","PSNR (dB)","final_loss","run 窓内 load1 mean\u002Fmax","備考",[61,61,61,197,197,197,197,61],"right",[199,208,216,223,230,237,244,251,256],[200,201,202,203,204,205,206,207],"1","off (A)","s4b-12500-off-r1","125.094","36.125","5.6347e-3","3.99 \u002F 5.12","採用",[209,210,211,212,213,214,215,207],"2","on (B)","s4b-12500-on-r1","123.987","36.209","5.5052e-3","1.62 \u002F 2.37",[217,201,218,219,220,221,222,207],"3","s4b-12500-off-r2","124.605","36.154","5.3727e-3","1.01 \u002F 1.45",[224,210,225,226,227,228,229,207],"4","s4b-12500-on-r2","122.062","36.183","5.4684e-3","2.67 \u002F 5.24",[231,201,232,233,234,235,236,207],"5","s4b-12500-off-r3","123.966","36.099","5.4520e-3","1.53 \u002F 2.38",[238,210,239,240,241,242,243,207],"6","s4b-12500-on-r3","122.254","36.145","5.5190e-3","1.10 \u002F 1.50",[245,246,247,248,249,250,247,247],"**mean (n=3)**","**off**","—","**124.5549** (σ 0.4541%)","**36.1260**","5.35e-3 台",[245,252,247,253,254,255,247,247],"**on**","**122.7680** (σ 0.8637%)","**36.1790**","5.49e-3 台",[257,247,247,258,259,260,247,261],"**Δ**","**-1.4347%**","**+0.0530**","同じ桁で一致 (5.3〜5.6e-3、GPU 加算順で末尾桁のみ揺れる、§8 参照)","閾値 max(2σ_off,1%)=1.0% を有意にクリア",{"type":90,"label":263,"variant":264,"text":265},"判定 — wallclock \u002F PSNR guard とも pass、3\u002F3 pair 一貫、除外感度分析でも頑健","success","wallclock: Δ **-1.4347%** ≤ -閾値 1.0% で pass。3\u002F3 pair とも on&lt;off で一貫 (r1: 123.987&lt;125.094、r2: 122.062&lt;124.605、r3: 122.254&lt;123.966)。**除外感度分析** (`p3-tier1-bit-exact.toml` §5 が「1 点の去就で判定が反転する」脆さを指摘したのを踏まえた事前チェック): off-r1 のみ除外 (off n=2, mean 124.286) でも Δ -1.221%、r1 pair を丸ごと除外 (n=2 vs n=2) でも Δ -1.712% — **3 通りいずれの扱いでも閾値 1.0% を超えて pass**、tier1 v2 のような脆い形式通過ではない。PSNR: Δ **+0.0530dB** ≥ -0.05dB guard で pass。§2b が明記したとおり `ssim_reduce` は gradient に一切触れないため、この +0.053dB は「改善した証拠」ではなく**背景の atomic 加算順 run-to-run noise** として読むべき値 (off 側レンジ 36.099-36.154 = 0.055dB、on 側レンジ 36.145-36.209 = 0.064dB で同程度の散らばり、系統的分離なし) — guard pass は「壊れていないことの確認」であり品質向上の主張ではない。final_loss は 6 run とも 5.3〜5.6e-3 の同じ桁に収まっており (off\u002Fon で系統的な水準差なし)、GPU 加算順の違いによる末尾桁の揺れの範囲内。**以上により採用確定**、`BackendConfig::default()` の `ssim_reduce` を `Gpu` に flip、`cargo test --workspace --release` 全 pass。",{"type":52,"text":267},"7. Δ 実測 (-1.4347%) が §2b 予測 (-2〜-4%) より小さかったことの機構解釈",{"type":90,"label":269,"variant":92,"text":270},"host 仕事の削減量と wallclock 回収量は 1:1 でない — 変換効率 ~13%","§2b は `ts_ssim_host_sum` 実測 (host 1.093ms\u002Fiter vs gpu \u003C0.04ms\u002Fiter) から『host 仕事 1.093ms\u002Fiter × 12500 iter ≈ 13.66s の host 仕事削減のうち、forward shadow の fill 率低下に比例する分 (58%) が残差 bubble から回収される』という比例モデルで -2〜-4% (4.2〜4.7s) を見積もった。実測の wallclock 回収量は off mean 124.5549s → on mean 122.7680s = **1.787s**、host 仕事削減量 13.66s に対する**変換効率は 13.08%** — §2b の比例モデル (58%) の 1\u002F4 程度に留まった。読み: `p3-c2-bubble-attribution` の残差 bubble 帰属モデルは『host-late (host 仕事が forward shadow からはみ出す分) が概ね 1:1 で wallclock に乗る』ことを前提にしていたが、実際には SSIM 総和 (1.093ms) の**大部分はもともと forward shadow (2.00ms) の中に収まっており** (fill 率 93.6% は 100% 未満、shadow に空きがあった)、`gpu`化で削減されるのは主に『shadow の中で消費されていた時間』であって『shadow からはみ出して直接 wallclock に乗っていた時間』ではない — 後者 (host-late overflow) はごく一部だったため、比例モデルが想定した回収量よりかなり小さい実測になったと解釈するのが整合的。この解釈が正しければ、§2b の『回収量 ∝ 動かした割合 (58%)』という比例仮定は楽観的すぎた、というのが今回のずれの説明になる (次に同種の host-shadow 系施策を見積もる際は、shadow 内 fill 率が 100% 未満である限り比例モデルは上振れしやすい点に注意すること)。ただしこの解釈は事後的な推測であり追加計装による検証はしていない — 採否判定 (採用) 自体はこの解釈の正否に依存しない (gate 自体は閾値を明確にクリアしているため)。",{"type":52,"text":272},"8. default flip の実装詳細 — `p3-s4-host-shadow.toml` §10 の罠の回避",{"type":121,"items":274},[275,276,277,278,279],"`p3-s4-host-shadow.toml` §10 が指摘した罠 (field-level `#[serde(default)]` を付けた enum field は、TOML 省略時に `BackendConfig::default()` の literal ではなく enum 自身の `#[default]` 属性 [`SsimReduceKind::default()`] から解決される — bool field の `bool::default()`=false 罠と同型) を踏まえ、**4 箇所を一括で変更した**: (1) `SsimReduceKind` enum の `#[default]` 属性を `Host` から `Gpu` に移動、(2) `BackendConfig::default()` の `ssim_reduce: SsimReduceKind::Host` を `SsimReduceKind::Gpu` に変更、(3) `BackendConfig::ssim_reduce` field の doc comment (旧: `default = Host (従来動作)。gate 待ち。`) を gate 結果込みで更新、(4) `SsimReduceKind` の 3 variant doc (`Host` から「現行」を外す、`HostLagged` に「gate 対象外のまま」の明示 verdict を追加、`Gpu` に `#[default]` と gate 実測を追記)","**実装後に実機で検証**: `ssim_reduce` を省略した config (12.5k gate の off-r1 config から `ssim_reduce = \"host\"` 行を削除、`max_steps = 1` にした 1-iter smoke) を実行し、`splat check`\u002F`splat train` が出力する `[backend] BackendConfig { …, ssim_reduce: Gpu, … }` を目視確認した — TOML 省略時の解決先が期待どおり `Gpu` になっていることを Rust の型システムの推論だけでなく実行時出力で pin した (A7 の default flip 前検証と同型の手順)","kernel-level mirror (`splat_metal::kernels::ssim::SsimReduceKind`、2 variant のみ) 側の `#[default] Host` 属性は**変更していない** — この mirror の default 値は `Trainer::new` が `Cell::new(SsimReduceKind::default())` で初期化する一時値に過ぎず、`apply_backend_config` (`splat-cli\u002Fsrc\u002Futil.rs`、`train.rs`\u002F`bench.rs` の両方の config load 経路から無条件で呼ばれることを確認済み) が config 側の値で必ず上書きするため、mirror 側 default の値自体は実行結果に影響しない。config 側 (`splat-train-v1::config::SsimReduceKind`) と mirror 側の 2 つの enum が別物であることに注意 (mirror 側は変更不要、と結論)","`config_paths` にある gate config family (`2026-08-30-final-12500-r{1,2,3}.toml` 等、ヘッダに『全 [backend] flag は default に任せる』と明記されたもの) は、本 flip 後は `ssim_reduce` を明示していない限り**黙って `Gpu` 経路になる** — 意図した挙動 (default 追従) だが、これらの config が過去に生成した『baseline』wallclock 数値は host 経路のものであり、本 flip 後に同じ config を再実行すると異なる (gpu 経路の) 数値になる点に注意。既存の gate config はすべて `ssim_reduce` を明示済み (off\u002Fon とも) なので、本 flip によって過去の gate 結果自体が無効になることはない","`cargo test --workspace --release` を計 4 回連続実行し、うち 2 回で `train_loop::tests::ssim_reduce_host_lagged_matches_host_loss_history_bit_exact` \u002F `ssim_reduce_host_lagged_without_backward_shadow_matches_host` が低頻度で fail した (`rot_quats[2]` rel≈1.0e-4、§4 発見 2 が既に文書化した ~1\u002F30 pre-existing flake と同一 signature)。両 test は `ssim_reduce` を fixture 内で明示的に `Host`\u002F`HostLagged` に設定しており default 値には依存しないため、**本 flip が原因ではない** (flip 前から存在する rasterize backward atomic 非決定性、既知の flake)。最終確認の連続実行では全 pass (splat-metal 95、splat-train-v1 90、他クレート含め failure 0) を得た",[],[282,307,332,354],{"id":44,"title":283,"date":9,"status":10,"polarity":284,"category":285,"axes":286,"tags":287,"task_code":298,"related_runs":299,"delta_psnr":301,"delta_wallclock":302,"rank":303,"verdict":304,"impact_summary":305,"detail_path":306},"C2 実測 — 残差 bubble は host-late 支配 (7.2〜8.1s)、refine tick drain は A7 で半減済み (3.0〜3.8s)。handoff は定常帯で headroom ほぼ無し","mixed","measurement",[14,15],[18,288,289,290,291,292,293,294,295,296,297],"gap-report","cb-gap","host-lead","drvproc","handoff","residual-bubble","refine-drain","post-m4-a7","lego","measurement-only","C2: 12.5k の残差 bubble 帰属計測と分析",[300],"c2-12500-depth2-prof","n=1 self-eval: 36.068 dB (100 views)。C2 は測定目的の run で PSNR gate 対象ではないが、p3-final-stack の n=3 mean (36.219 dB) からの乖離は n=1 ノイズ帯として妥当な範囲","train elapsed 124.75s (n=1)。p3-final-stack n=3 mean 124.393s (σ0.756%) の guard 内 — profile=true + gap report 計装のオーバーヘッドは計測可能な歪みを生んでいない、と読める","high","residual-is-host-late-dominated \u002F handoff-headroom-thin \u002F refine-drain-already-halved-by-a7","`p3-kernel-share-post-s3.toml` §4\u002F§8 の宿題 (「残差は既存計装では分解不能、実装後も 12.5k 実測がまだ無い」) を、`2026-08-30-c2-12500-depth2-prof.toml` (M4+A7 default 込み、S3 gate arm B と [backend] bit-exact) の 1 run で埋めた。\u003Cstrong>reliable=true \u002F dropped=0 \u002F kernel_invalid=0 \u002F sum\u002Funion=1.000000x\u003C\u002Fstrong> — 信頼性ゲート健全、全列使用可。wall 124.75s \u002F busy 113.627s (91.1%) \u002F sync-tax 11.126〜11.129s は `p3-final-stack` の n=3 mean (124.393s, σ0.756%) の guard 内 (n=1 の点推定として妥当)。\u003Cstrong>Σcb_gap=11.085s が sync-tax 全量の 99.6% を説明\u003C\u002Fstrong>し、`p50×n` (band 別合計 7.244s) と `mean×n` (11.081s) の差 3.837s を refine tick 由来の外れ値と読むと、\u003Cstrong>残差 (通常境界) 7.2〜8.1s (5.8〜6.5%) \u002F refine tick drain 3.0〜3.8s (2.4〜3.1%)\u003C\u002Fstrong> にブラケットできる。refine 側は `ts_refine`(2.869s)+`ts_opacity_decay`(0.185s)=3.054s の独立 host 実測が下限とほぼ一致し、クロスチェックが成立した。\u003Cstrong>旧 3 分解 (refine 6.26s \u002F encode(B) 3.41s \u002F 残差 4.54s、旧 sync-tax 全量 14.206s) との整合\u003C\u002Fstrong>: 旧「残差」+「encode(B)」= 4.54+3.41=7.95s ≈ 新「通常境界」7.24s (wall が 151.70→124.75s に縮んだ分を割り引けば近い) — \u003Cstrong>旧 encode(B) バケツは独立した加算成分ではなく、非重複だった encode コストが host-late として `cb_gap` に同じ形で現れていた\u003C\u002Fstrong>と判明し、旧 3 分解を「refine drain \u002F それ以外 (通常境界)」の 2 分解へ訂正する形になった。\u003Cstrong>帰属の結論: 通常境界の bubble は host-late が支配的、driver 処理 (`drvproc`) と GPU キュー待ち (`handoff`) は定常帯で中央値がほぼゼロ (headroom 薄い)\u003C\u002Fstrong> — task が例示した「handoff → CB 統合」は主因ではないと実測が明示的に否定した。","\u002Ffindings\u002Fp3-c2-bubble-attribution\u002F",{"id":46,"title":308,"date":9,"status":10,"polarity":12,"category":309,"axes":310,"tags":311,"task_code":320,"related_runs":321,"delta_psnr":327,"delta_wallclock":328,"rank":303,"verdict":329,"impact_summary":330,"detail_path":331},"M7 最終スタック確定 — 12.5k 124.39s (独立 n=3)、msplat 等価 gap 0.927×→0.755×、throughput 1.135×負け→0.926× (msplat 側 avg splats 借用値 ±8% 未満なら逆転)","experiment",[14,15],[312,313,314,315,316,317,296,318,319],"m7","seminar05-milestones","final-stack","msplat-parity","pareto-v3","throughput-parity","gpu-gate","independent-remeasurement","2026-09-seminar05-milestones M7 (最終スタック確定 + msplat 等価再比較 + Pareto v3)",[322,323,324,325,326],"final-12500-r1","final-12500-r2","final-12500-r3","final-12500-r4","c1v2-12500-off-prof","12.5k self-eval (r2-r4 n=3 mean): **36.219 dB** (σ 0.046%)、baseline guard 36.202±0.1dB 内。brush cross-eval q8 (r2-r4 mean): **36.249 dB** (msplat 30K 保守値 34.243 比 **+2.006dB**、旧 +1.97dB とほぼ不変)。white cross-eval (r2-r4 mean): **35.147 dB** (msplat 30K cross-eval 最小 36.252 比 **-1.105dB**、旧 -1.10dB とほぼ不変)","12.5k train elapsed 独立 n=3 (r2\u002Fr3\u002Fr4、clean set): **124.393s (σ 0.756%)**。A7 gate on-arm mean (124.807s) を **-0.33%** で再現。msplat 等価 gap (block1 n=2 分母 164.69s): **0.755×** (旧 0.927×)。per-splat·iter throughput: 本実装 **30.94ns** vs msplat 33.4ns = **0.926×** (旧 1.135×負けから逆転)","final-stack-confirmed-msplat-gap-0.755x-throughput-parity-crossed-pending-msplat-avg-splats-recheck","2026-09-seminar05-milestones M7 を実施した。(1) **12.5k full run 独立 n=3**: `2026-08-30-final-12500-r{1,2,3}.toml` を単純 3 repeat (off arm なし、全 [backend] flag は default 任せ = M4 radix_scatter=SimdBallot + A7 refine_scratch_persist\u002Frefine_direct_write=true 込み) で実行。r1 (131.84s) が r2\u002Fr3\u002Fr4 (123.34\u002F124.69\u002F125.15s) から外れて見えたため、advisor レビューを経て診断用の r4 を追加実行した結果、**r1 は script 再起動時に load sampler window ログが truncate され窓内記録が皆無**という house 規約 (p2-msplat-parity-final §7「事前 gate だけでは不十分、窓内記録が必須」) 上の欠陥を抱えていたことが判明し、r2\u002Fr3\u002Fr4 (全 run とも window 記録あり、load 正常) を正式な n=3 として採用した。**mean 124.393s (σ 0.756%)** — A7 gate on-arm mean 124.807s を -0.33% で独立再現しており、この近さ自体が両 session の健全性証拠になる。r1 込みの参考値 (n=3 リテラル\u002Fn=4 全部) も §1 に残す。(2) **per-kernel share v2**: `2026-08-30-c1v2-12500-off-prof.toml` (submission=per_kernel\u002Fforward_submission=per_stage\u002Fpipelining=off、M4\u002FA7 default 込み) を 1 run。leaf gpu_ms 合計 114.508s は busy union と exact 一致。radix share 26.40%→12.01% (絶対 -63.25%、M4 gate の per_stage 補助計測 -63.7% と独立一致)、backward_raster が単独最大ブロックとしてさらに優位 (33.86%→40.07%)。詳細は `p3-kernel-share-post-s3.toml` §6 に追記。(3) **累計 ablation**: p2 の 8 段 (Phase0 766.07s → S3 151.70s) に M4 (127.53s、-14.9%) \u002F A7 (124.81s、-2.15%) \u002F M7 独立再計測 (124.39s、-0.33%、ほぼ noise level) を継ぎ足し、Phase 0 比 **-83.76%**。(4) **msplat 等価再比較**: p2-msplat-parity-final の計算手順を最終値で再計算。gap 分母は継続性のため block1 n=2 mean (164.69s) を維持 (msplat 側は再実行していない)。**wallclock gap 0.927×→0.755×**。throughput は avg splats を新 4 run の trapezoid 積分から自前算出 (321,637、旧値 322k とほぼ一致し手法の妥当性を裏づける) して **1.135×負け→0.926×勝ち** (ただし msplat 側 avg splats ~165k は p2 からの借用値で本 session では再導出できておらず、逆転が成立するのはこの借用値の誤差が +8.0% 未満の場合に限る、§4 callout 参照)。brush\u002Fwhite PSNR は既存 final.ply に対し `splat eval` を回して再計測し (新規 GPU 学習 run は不要)、両 convention とも旧値からほぼ不変 (brush +2.01dB \u002F white -1.11dB) — M4\u002FA7 は PSNR trajectory に理論上影響しない施策なので想定どおり。matched-iteration (30K vs 30K) \u002F matched-wallclock (旧 13.3k 点) \u002F matched-PSNR(brush) の旧 6.0k 点 \u002F energy は**新規 GPU run が必要なため本 session では再計測せず**、旧スタック値を明示ラベルで carry forward するに留めた (外挿スケーリングによる偽の精度を避ける、advisor レビュー指摘)。(5) **Pareto v3**: `make_msplat_pareto.py` の入力を msplat 等価比較 4 点 Pareto curve (p2-msplat-parity-final §10 の未実施項目) に更新し `docs\u002Ffigures\u002Fpareto-v3-msplat-lego-final-stack.png` を生成。12.5k 点のみ最終スタック値、他 3 点 (6.0k\u002F13.3k\u002F30k) と msplat は旧スタック値のまま明示ラベル。","\u002Ffindings\u002Fp3-final-stack\u002F",{"id":43,"title":333,"date":9,"status":10,"polarity":334,"category":309,"axes":335,"tags":336,"task_code":343,"related_runs":344,"delta_psnr":348,"delta_wallclock":349,"rank":350,"verdict":351,"impact_summary":352,"detail_path":353},"S4 — post-backward accumulate を backward CB shadow に配置する host_schedule flag — 棄却確定 (2026-08-30 gate)","negative",[14,15],[337,18,338,22,339,340,341,342],"s4","host-schedule","depth2","refine-accumulate","gate-rejected","contaminated-pair-retry","S4: C2 施策 #1 (post-backward host 仕事の backward shadow 配置) 実装 + gate",[345,346,347],"splat\u002Fruns-logs\u002Fs4-12500-*.log (n=3 主系列、r1 pair は汚染で破棄・保存)","splat\u002Fruns-logs\u002Fs4-12500-retry4-*.log (r1 pair retry、r4 として採用)","splat\u002Fruns-logs\u002Fs4-12500-predecision.log (事前登録判定規則)","+0.027 dB (guard 内、ただし wallclock 不通過のため判定は変わらない)","**逆符号 (on が遅い) — どの扱いでも正符号、代表値は使わないこと**。採用条件 Δ ≤ -1% に対し: r1→r4 置換 n=3 で **+5.63%** (on-r4 の大外れ値 141.77s が支配)、on-r4 を外れ値として除外した n=2 相当で **+1.8%**、r1 込み (retry 前) n=3 で **+1.02%**。σ_on 6.36% という広い散らばりに対し +5.63% は解像できる効果量ではなく、**真の効果量は ~1〜2% (harness 分解能付近) で null〜わずかな悪化、`p3-tier1-bit-exact` v1→v2 と同種の『単一外れ値が代表値を膨らませる』パターン**とみるのが妥当。どの扱いでも符号は一貫して不通過 (on≥off) なので棄却の結論自体は変わらない","low","rejected","C2 施策 #1 (post-backward host 仕事を backward CB shadow に配置) を `[backend] host_schedule` flag として実装し、12.5k n=3 交互 A\u002FB gate を実施した。**棄却 — ただしどの尺度で見ても符号は on≥off で一貫**: 採用セット (r1→r4 置換) の点推定は +5.63% だが、これは on-r4=141.77s という単一の大外れ値に支配された数字であり (on-r4 を除くと +1.8%、r1 込みの retry 前でも +1.02%)、σ_on 6.36% の広さを踏まえると真の効果量は ~1〜2% (harness 分解能付近) で null〜わずかな悪化とみるのが妥当 (`p3-tier1-bit-exact` v1 が経験した「単一の汚染値が代表値を膨らませる」パターンの符号違い版)。r1 pair は series 独立 load sampler で load1 max 7.91\u002F8.90 (LOAD_LIMIT 6.0 超) を検知し事前登録条件 (i)(ii) を満たしたため 1 回だけ retry (r4) に置換 — ただし (i) の判定は max ベースで行っており、mean ベースでは off-r1 (mean 2.72) は 1.5×中央値 (3.765) 未満で非該当になる (次回の predecision には mean\u002Fmax のどちらで評価するか明記すべき教訓、§8 参照)。retry 後の on-r4 (141.77s) はさらに大きな外れ値だが、走行中 load1 は終始 clean (mean 1.64 \u002F max 3.19) — 事前登録条件 (i) load 証拠が不成立のため追加 retry はせず (`p3-tier1-bit-exact` §5 の教訓通り、条件 (ii) 単独での retry 連鎖を回避)。discarded r1 pair 自体は on\u003Coff (on が速かった) — 「3\u002F3 一貫」は採用セットに限った話で、破棄分含む 4 pair 全体では 3\u002F4 が on>off。ms\u002Fiter trace は on-r4 で iter 2000 以降一貫して高い (discrete spike ではなく持続的) — A7 §7 off-r3 と同型の GPU thermal 蓄積の可能性はあるが host_schedule 由来と特定する根拠はない。全 pair とも off→on の順で実行 (ABAB、ABBA 均衡化なし) — on arm は常に「温まった後」の機体条件で走っており、末尾の on-r4 が最遅であることと整合するが、同構造の A7 gate では on 側が一貫して速かったこともあり主要因とは考えにくい。棄却により `.rs` は一切変更していない。","\u002Ffindings\u002Fp3-s4-host-shadow\u002F",{"id":45,"title":355,"date":356,"status":10,"polarity":12,"category":309,"axes":357,"tags":358,"task_code":368,"related_runs":369,"delta_psnr":380,"delta_wallclock":381,"rank":303,"verdict":382,"impact_summary":383,"detail_path":384},"S3 iteration pipelining depth 2 — 12.5k -18.1% \u002F busy 78 → 91% (default flip)","2026-08-17",[14,15],[359,360,361,362,363,364,365,366,296,367],"1x-roadmap-v2","s3","iteration-pipelining","command-buffer","gpu-busy","sync-tax","double-buffering","scratch-generation","unified-memory","2026-08 1× 工程表 v2 — AC 復帰後 計測 queue #2' (S3 gate)",[370,371,372,373,374,375,376,377,378,379],"s3-smoke-1000-off","s3-smoke-1000-depth2","s3-12500-off-prof","s3-12500-depth2-prof","s3-12500-off-r1","s3-12500-off-r2","s3-12500-off-r3","s3-12500-depth2-r1","s3-12500-depth2-r2","s3-12500-depth2-r3","12.5k **同一 session 交互 A\u002FB** n=3 mean: depth2 **36.202 dB** (36.195 \u002F 36.179 \u002F 36.231) vs off **36.185 dB** (36.178 \u002F 36.192 \u002F 36.186) = **+0.016 dB** (guard 36.167 ± 0.1 の内側、n=3 mean 判定 — n=1 判定なし)。final splats は depth2 406,439 \u002F off 408,874 で **depth2 のほうが 0.6% 少ない** (前段の profile pair では逆に +0.6% で、方向が一致しない = 既存 atomic 非決定性の chaos 増幅の範囲)","12.5k full run **同一 session 交互 A\u002FB n=3 mean: 185.21 → 151.70s = -18.1%** (train elapsed)。process wallclock では **188.33 → 154.00s = -18.2%**。σ は off 3.33% \u002F depth2 1.18% なので有意閾値 max(2σ,1%) = 6.7%、実測 Δ は**その 2.7 倍**。同一 session の off arm は S2 gate 当日の S2 arm (train 184.61s \u002F process 187.65s) を **+0.3% で再現**しており、session の健全性が確認できている。参考: profile=true の 1 対 1 比較では 180.49 → 162.72s = -9.85% (計装自体が host 側 critical path に乗るため S3 の効果を過小評価する)","s3-adopted-default-flip-pipelining-depth2","1× 工程表 v2 が「S2 後の単独本命」に指定していた S3 を gate し、採用した。S2 までの施策が \u003Cstrong>CB の数\u003C\u002Fstrong>を減らすものだったのに対し、S3 は \u003Cstrong>CB の並び方\u003C\u002Fstrong>を変える — iteration N の loss\u002Fbackward CB (B\u003Csub>N\u003C\u002Fsub>) を commit したら wait せずに iteration N+1 の forward CB (F\u003Csub>N+1\u003C\u002Fsub>) を組んで commit し、\u003Ccode>wait(B\u003Csub>N\u003C\u002Fsub>)\u003C\u002Fcode> の後の host readback \u002F \u003Ccode>accumulate\u003C\u002Fcode> を F\u003Csub>N+1\u003C\u002Fsub> の GPU 実行の影に置く。\u003Cstrong>12.5k 同一 session 交互 A\u002FB n=3 で 185.21 → 151.70s = -18.1%\u003C\u002Fstrong> (閾値 max(2σ,1%) = 6.7% の 2.7 倍)。\u003Cstrong>GPU busy 77.5 → 91.3% \u002F sync-tax 3.244 → 1.136 ms\u002Fiter (-65%)\u003C\u002Fstrong> で counter session が置いた「busy 100% = 理論上限」への距離は 22.5 pt → 8.7 pt に縮んだ。\u003Cstrong>1k smoke では busy 65.8 → 72.0% にしか上がらず判定不能だった\u003C\u002Fstrong> — smoke の splat 数 6.8k では forward の GPU 影 (1.06 ms\u002Fiter) が image size 固定の host 仕事 (~1.7 ms\u002Fiter) を隠しきれないためで、これは \u003Cstrong>「pipelining の gate は smoke では代替できない」という harness 上の教訓\u003C\u002Fstrong>として残す。残 bubble の内訳も確定した: \u003Cstrong>refine tick の drain 6.04s (43%) &gt; encode(B) 4.66s (33%) &gt; 残差 3.28s (23%)\u003C\u002Fstrong> — 次の一手が roadmap の「即効ペア (refine capacity スコープバグ修正)」であることが実測で決まった。msplat 同日等価 gap \u003Cstrong>1.105× → 0.907×\u003C\u002Fstrong>、Phase 0 からの累計 766.07 → 154.0s = \u003Cstrong>-79.9%\u003C\u002Fstrong> (全て数学的同値の施策のみ)。","\u002Ffindings\u002Fp2-s3-iteration-pipelining\u002F",1790227327661]