松田研究室
FindingID: a-6-feat-g-packed-investigation
Status: stable / task A.6
← Findings Index
Investigation · feat.G f16 packed

A.6 #feat.G f16 packed Splat ROI 再評価 — kernel pair は完成、trainer integration は未着手で close

Splat2DPacked kernel pair (project / rasterize forward + backward) と Rust glue は cherry-pick で main 取り込み可能な状態にしたが trainer の forward path で packed kernel を活性化する route が未実装。ROI ~1% 既知で integration 余地ナシ、close。

negativerank: lowinvestigative第 3 軸phase-5feat-gf16packedsplat2dinvestigationdeferredmetal
Δ Wallclock
~1% (既知、bench 不実施)
Impact
Splat2DPacked kernel pair は完成 (cargo test 73/73 pass) だが、trainer forward path は fp32 path のみで packed kernel を呼ぶ route がない。理論上 -39% memory traffic / splat だが kernel pair 単独 bench で wallclock 効果 ~1% と既知。close。
01

本文

feat.G branch (claude/musing-mendeleev-579d41) から Splat2DPacked kernel pair (project / rasterize forward + backward) と Rust glue を cherry-pick で main 取り込み可能な状態にしたが、trainer の forward path で packed kernel を活性化する route が実装されていない。30k bench 不可、ROI ~1% (memory より既知) で時間 budget 内では integration 余地ナシ、close。

実装日
2026-05-23 (subagent worktree feat-g-f16-packed-takeup、commit 416a2b9 まで)
ユーザー判断
A.6 は documented investigation で close、bench は実施せず (2026-05-23)

取り込み済みの内容

subagent worktree agent-ad177df468acfb25a (branch feat-g-f16-packed-takeup、cargo test 73/73 pass):

  1. splat-core/types.rs::Splat2DPacked (struct + round-trip helpers、half = "2.4" 依存追加)
  2. shaders/forward/project.metal の Splat2DPacked emit path
  3. shaders/forward/rasterize.metal の Splat2DPacked forward kernel
  4. shaders/backward/rasterize_backwards.metal の Splat2DPacked backward kernel
  5. splat-metal/kernels/project.rs の packed entry method
  6. splat-metal/kernels/rasterize.rsforward_packed + backward_buf_packed (テスト用 entry、trainer から呼ばれない)
  7. test: forward_packed_matches_forward_fp32, backward_packed_matches_backward_simd_fp32

なぜ bench 不可

splat-train-v1/src/trainer.rsforward_with_state / backward_rasterize_buffp32 Splat2D path のみ を呼ぶ。packed kernel は test 経由でのみ実行され、env / config / build flag で switch する route が無い。

実 trainer に packed path を組み込むには:

  1. Param に packed buffer pool を追加 (現状 splat3d_buf / splat2d_buf は fp32)
  2. Trainer::forward_with_state を switch 化 (config flag で fp32 / packed select)
  3. backward chain (project_backwards) も packed entry を呼ぶよう改修
  4. adam の SH coeffs update が fp16 を経由する場合の精度確保

これは feat.G の Phase 4 integration に相当し、feat.G branch にも未実装 (stage 1-3a までしか cherry-pick されていない)。

ROI ~1% 既知 — bench する価値が低い

memory [[feat_g_f16_packed_roi]] より、kernel pair 単独 bench で trainer 統合相当の wallclock 効果は ~1% と既知 (feat.G branch 内の独自 bench から)。

期待効果 (theoretic):

  • Splat2D = 9 floats × 4 bytes = 36 bytes
  • Splat2DPacked = (xy: 2 f32) + (conic: 3 f16) + (rgba: 4 f16) ≈ 8 + 6 + 8 = 22 bytes → -39% memory traffic per splat
  • ただし rasterize は per-tile に 256 splat を threadgroup memory に load して再利用、bandwidth が律速かは疑問
  • bench 実測 ~1% は「bandwidth bound でなかった」を示唆

卒論への含意

第 3 軸 (Apple Silicon 固有最適化) の Negative finding (微改善): f16 packed 表現は理論上 -39% memory traffic だが、実際の wallclock 効果は ~1% に留まる。Lego (~80k splats) で memory bound でなく compute bound (Shading + alpha 合成)。bandwidth 削減は より大規模シーン (200k+ splats) で効果出る可能性、卒研範囲外。

A.7 / A.9 との関係

  • A.7 simpler batching: commit overhead 削減、scope 別 (今 30k bench 中)
  • A.9 f16 forward: accumulator のみ f16 化、storage は f32 のまま、scope 別 (今 30k bench 中)
  • A.6 は storage 全体を f16 化 する path、kernel pair は完成しているが trainer 統合に手間がかかる

残作業 (defer, 卒研後)

  1. Param packed buffer pool 追加
  2. trainer dispatch switch (config flag [backend] dtype = "fp32" | "packed")
  3. 30k bench で wallclock / PSNR drift 計測 → ROI 再確認
  4. memory bandwidth profiling (Instruments Metal Trace) で「実際に bandwidth bound だったか」を確認

関連

  • memory: [[feat_g_f16_packed_roi]] (ROI ~1% の元情報), [[feat_g_branch_state]] (branch 状態)
  • A.9 f16 forward (accumulator only): bench 進行中
  • A.5 final ablation 表 第 3 軸: final-ablation-table.md
© 2026 大竹律輝 — 松田研究室