From fb9b62a1f96597d8641f095fa68d0fa9c1ef0f0b Mon Sep 17 00:00:00 2001 From: jgrusewski Date: Thu, 14 May 2026 12:35:48 +0200 Subject: [PATCH] fix(plan-head): trainer trade plan forward reads from wrong param indices MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit `launch_trade_plan_forward` read `w_fc/b_fc/w_out/b_out` from `padded_byte_offset(¶m_sizes, [82..86))` — i.e., the ISV-conditioning + recursive-confidence tensors (`b_isv_gate`, `w_isv_gamma`, `b_isv_gamma`, `w_conf_fc`). The actual plan tensors live at `[91..95)` per `compute_param_sizes` and the matching Xavier init block. No backward exists for the plan head, so the plan tensors at `[91..94]` sat at cold-start Xavier values forever while `plan_params` was being driven by whichever ISV/conf weights happened to occupy the wrong offsets. Every downstream consumer (`backtest_plan_kernel`, `plan_isv` slots in `experience_kernels`, `compute_plan_params` in `q_value_provider`, regime gating, and the SP22 H6 vNext B5b concat path) was therefore conditioning on noise correlated with ISV optimisation, not on a learned plan. Discovered while preparing Phase B5b-2 (collector trade plan launch). Two-line index fix + diagnostic comment + audit doc entry. Co-Authored-By: Claude Opus 4.7 (1M context) --- .../ml/src/cuda_pipeline/gpu_dqn_trainer.rs | 18 +++++++++--- docs/dqn-wire-up-audit.md | 29 +++++++++++++++++++ 2 files changed, 43 insertions(+), 4 deletions(-) diff --git a/crates/ml/src/cuda_pipeline/gpu_dqn_trainer.rs b/crates/ml/src/cuda_pipeline/gpu_dqn_trainer.rs index a8064fafa..86b441d41 100644 --- a/crates/ml/src/cuda_pipeline/gpu_dqn_trainer.rs +++ b/crates/ml/src/cuda_pipeline/gpu_dqn_trainer.rs @@ -10843,10 +10843,20 @@ impl GpuDqnTrainer { /// 4. Elementwise: bias + sigmoid/scaling activations → plan_params pub(crate) fn launch_trade_plan_forward(&self, batch_size: usize) -> Result<(), MLError> { let param_sizes = compute_param_sizes(&self.config); - let w_fc = self.ptrs.params_ptr + padded_byte_offset(¶m_sizes, 82); - let b_fc = self.ptrs.params_ptr + padded_byte_offset(¶m_sizes, 83); - let w_out = self.ptrs.params_ptr + padded_byte_offset(¶m_sizes, 84); - let b_out = self.ptrs.params_ptr + padded_byte_offset(¶m_sizes, 85); + // SP22 H6 vNext Phase B5b-2 (2026-05-14): trade plan weights live at + // [91..95) per `compute_param_sizes` + param-init (`(cfg.adv_h, + // cfg.shared_h2)` Xavier at [91] etc.). Pre-fix this function read + // from [82..86) — `b_isv_gate / w_isv_gamma / b_isv_gamma / w_conf_fc` + // — i.e., ISV-conditioning + recursive-confidence tensors. The plan + // tensors at [91..94] sat at cold-start Xavier values, never updated + // (no backward exists for plan head), while `plan_params` was driven + // by whatever ISV/conf weights happened to be at the wrong offsets. + // Every downstream consumer (backtest_plan_kernel, plan_isv slots, + // compute_plan_params, regime gating) was conditioning on noise. + let w_fc = self.ptrs.params_ptr + padded_byte_offset(¶m_sizes, 91); + let b_fc = self.ptrs.params_ptr + padded_byte_offset(¶m_sizes, 92); + let w_out = self.ptrs.params_ptr + padded_byte_offset(¶m_sizes, 93); + let b_out = self.ptrs.params_ptr + padded_byte_offset(¶m_sizes, 94); let ah = self.config.adv_h; let sh2 = self.config.shared_h2; let save_h_s2_ptr = self.save_h_s2.raw_ptr(); diff --git a/docs/dqn-wire-up-audit.md b/docs/dqn-wire-up-audit.md index 4e2b15427..04e3f0166 100644 --- a/docs/dqn-wire-up-audit.md +++ b/docs/dqn-wire-up-audit.md @@ -2,6 +2,35 @@ **Status:** Populated during Plan 1 Task 6 (A.5 orphan audit). Updated on every commit per Invariant 7. +## 2026-05-14 — fix(plan-head): trainer trade plan forward reads from wrong param indices + +**Branch:** `sp20-aux-h-fixed`. **Discovered during SP22 H6 vNext Phase B5b-2.** + +`launch_trade_plan_forward` in `gpu_dqn_trainer.rs` read +`w_fc/b_fc/w_out/b_out` from `padded_byte_offset(¶m_sizes, [82..86))` +— `b_isv_gate / w_isv_gamma / b_isv_gamma / w_conf_fc`, i.e., the +ISV-conditioning + recursive-confidence tensors. The actual plan-head +tensors live at `[91..95)` per `compute_param_sizes` (line 4682) and +the matching Xavier init block (line 33779). + +**Net effect across all prior SP runs that touched plan-conditioning:** +`plan_params` was the cuBLAS output of `(h_s2 @ b_isv_gate^T) → bias-relu +→ (• @ b_isv_gamma^T) → activate`. No backward exists for the plan head, +so the plan tensors at `[91..94]` sat at their cold-start Xavier values +forever. The downstream consumers — `backtest_plan_kernel` (PLAN_ISV +slots), `experience_kernels` (`PLAN_ISV_CONVICTION_DRIFT`, `plan_isv` → +regime gate), `compute_plan_params` in `q_value_provider`, plan-noise +injection — were all conditioning on ISV-optimisation noise, not on a +learned trade plan. + +**Fix:** two-line index update (82,83,84,85 → 91,92,93,94) + +diagnostic doc-comment at the launch fn. Compile-clean under +`SQLX_OFFLINE=true cargo check -p ml --lib`. Adding a real plan-head +backward is a follow-up project — out of scope for this commit. + +**Touched:** `crates/ml/src/cuda_pipeline/gpu_dqn_trainer.rs` +(launch_trade_plan_forward only). + ## 2026-05-10 — SP21 T2.2 Phase 1 Step B: per-trade tape buffers + readback (atomic) **Branch:** `sp20-aux-h-fixed` (off `5d01190e1`).