fix(plan-head): trainer trade plan forward reads from wrong param indices

`launch_trade_plan_forward` read `w_fc/b_fc/w_out/b_out` from
`padded_byte_offset(&param_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) <noreply@anthropic.com>
This commit is contained in:
jgrusewski
2026-05-14 12:35:48 +02:00
parent cdd3dc6edb
commit fb9b62a1f9
2 changed files with 43 additions and 4 deletions

View File

@@ -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(&param_sizes, 82);
let b_fc = self.ptrs.params_ptr + padded_byte_offset(&param_sizes, 83);
let w_out = self.ptrs.params_ptr + padded_byte_offset(&param_sizes, 84);
let b_out = self.ptrs.params_ptr + padded_byte_offset(&param_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(&param_sizes, 91);
let b_fc = self.ptrs.params_ptr + padded_byte_offset(&param_sizes, 92);
let w_out = self.ptrs.params_ptr + padded_byte_offset(&param_sizes, 93);
let b_out = self.ptrs.params_ptr + padded_byte_offset(&param_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();

View File

@@ -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(&param_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`).