feat(sp14-β): pre-load SP14 EGF kernel handles in experience collector (Option B)

Step 1 of β migration — Option B (collector-native): collector
loads its own CudaFunction handles for the 3 SP14 producer kernels
plus their sub-kernels (4 total: aux_dir_acc_reduce,
aux_pred_to_isv_tanh, q_disagreement_update, alpha_grad_compute).
Mirrors SP13 hold_rate pattern at gpu_experience_collector.rs:1820.
Cleaner than cross-component launcher calls (avoids trainer-stream /
collector-stream race; no signature surgery on the existing trainer
launchers).

Cubin static decls flipped to pub(crate) so the collector can
re-load on its own stream. Compile clean; sp14_oracle_tests pass
(2/2 non-GPU; GPU-gated 7 ignored on RTX 3050 Ti host).

No launches yet — additive infrastructure commit.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
jgrusewski
2026-05-07 21:43:56 +02:00
parent 9d0c124cee
commit 09202aa991
3 changed files with 114 additions and 4 deletions

View File

@@ -625,7 +625,7 @@ pub(crate) static SP13_HOLD_RATE_OBSERVER_CUBIN: &[u8] =
/// the SP13 EMAs at ISV[373..375) (short/long EMAs, sentinel 0.5 per
/// `pearl_first_observation_bootstrap`). See
/// `aux_dir_acc_reduce_kernel.cu` for kernel contract details.
static SP13_AUX_DIR_ACC_REDUCE_CUBIN: &[u8] =
pub(crate) static SP13_AUX_DIR_ACC_REDUCE_CUBIN: &[u8] =
include_bytes!(concat!(env!("OUT_DIR"), "/aux_dir_acc_reduce_kernel.cubin"));
/// SP13 Phase 0a P0a.T4 (2026-05-04): fixed-α EMA applicator. Sibling
@@ -652,14 +652,14 @@ pub(crate) static SP13_APPLY_FIXED_ALPHA_EMA_CUBIN: &[u8] =
/// preserved for layout stability. Consumed by
/// `GpuDqnTrainer::launch_aux_pred_to_isv_tanh`. See
/// `aux_pred_to_isv_tanh_kernel.cu` for kernel contract details.
static SP13_AUX_PRED_TO_ISV_TANH_CUBIN: &[u8] =
pub(crate) static SP13_AUX_PRED_TO_ISV_TANH_CUBIN: &[u8] =
include_bytes!(concat!(env!("OUT_DIR"), "/aux_pred_to_isv_tanh_kernel.cubin"));
/// SP14 B.3 (2026-05-05): per-step Q-head ↔ aux argmax disagreement EMA
/// producer. Reads online Q logits + aux softmax outputs; computes per-step
/// argmax-disagreement bool; updates a Wiener-optimal EMA into ISV[388].
/// Loaded from `q_disagreement_update_kernel.cubin`.
static SP14_Q_DISAGREEMENT_CUBIN: &[u8] =
pub(crate) static SP14_Q_DISAGREEMENT_CUBIN: &[u8] =
include_bytes!(concat!(env!("OUT_DIR"), "/q_disagreement_update_kernel.cubin"));
/// SP14 B.4 (2026-05-05): α_grad compute kernel (Schmitt + adaptive k +
@@ -667,7 +667,7 @@ static SP14_Q_DISAGREEMENT_CUBIN: &[u8] =
/// gate), ISV[390] (hack-rate EMA); computes α_grad ∈ [0, 1] and writes to
/// ISV[387]. Consumed downstream by the direction Q-head SGEMM weight as an
/// input-gate scalar. Loaded from `alpha_grad_compute_kernel.cubin`.
static SP14_ALPHA_GRAD_CUBIN: &[u8] =
pub(crate) static SP14_ALPHA_GRAD_CUBIN: &[u8] =
include_bytes!(concat!(env!("OUT_DIR"), "/alpha_grad_compute_kernel.cubin"));
/// SP14 B.5 (2026-05-05): anti-gradient-hacking circuit breaker. Compares

View File

@@ -902,6 +902,43 @@ pub struct GpuExperienceCollector {
/// the kernel overwrites it on every launch.
sp13_hold_rate_buf: MappedF32Buffer,
// ── SP14 β-migration (Option B, 2026-05-07): collector-native EGF
// producer chain. The trainer's `submit_aux_ops` path only fires once
// per epoch with batches drawn from the replay buffer where Q has
// converged on Hold/Flat (total_cnt=0 → EMA decays toward zero). The
// rollout path on this collector's stream sees Thompson-forced
// Short/Long picks which is where genuine aux↔Q disagreement signal
// lives. Same cubin handles as the trainer's, loaded on this stream
// for same-stream producer→consumer ordering. Mirrors the SP13
// hold-rate observer's collector-native pattern (loaded above).
/// SP14 β-migration (2026-05-07): SP13 dir-acc reduce kernel handle
/// on the collector's stream. Reads `exp_aux_nb_softmax_buf [N, 2]` +
/// `exp_aux_nb_label_buf [N]` and writes 6 floats to
/// `exp_aux_dir_acc_buf` (mapped-pinned). Same cubin as the trainer's
/// `aux_dir_acc_reduce` (`SP13_AUX_DIR_ACC_REDUCE_CUBIN`).
exp_sp13_aux_dir_acc_reduce_kernel: CudaFunction,
/// SP14 β-migration (2026-05-07): aux-pred → ISV[375] tanh producer
/// kernel handle on the collector's stream. Reads
/// `exp_aux_nb_softmax_buf [N, 2]` and writes
/// `mean(softmax[:,1] - softmax[:,0])` to ISV[AUX_DIR_PREDICTION_INDEX=375].
/// Same cubin as the trainer's `aux_pred_to_isv_tanh_kernel`
/// (`SP13_AUX_PRED_TO_ISV_TANH_CUBIN`).
exp_sp13_aux_pred_to_isv_tanh_kernel: CudaFunction,
/// SP14 β-migration (2026-05-07): SP14 q-disagreement EMA producer
/// kernel handle on the collector's stream. Reads
/// `exp_aux_nb_softmax_buf [N, K=2]` + collector's `q_values [N, q_stride]`
/// (post-`expected_q_kernel`) and updates ISV[388] +
/// ISV[Q_DISAGREEMENT_VAR_INDEX=389]. Same cubin as the trainer's
/// `sp14_q_disagreement_update_kernel` (`SP14_Q_DISAGREEMENT_CUBIN`).
exp_sp14_q_disagreement_update_kernel: CudaFunction,
/// SP14 β-migration (2026-05-07): SP14 α_grad compute kernel handle
/// on the collector's stream. Pure ISV-state kernel — reads
/// ISV[372..395) drivers and writes ISV[392] / ISV[393] (raw and
/// smoothed α_grad) plus the Schmitt-trigger / k_q / k_aux state
/// machine bookkeeping. Same cubin as the trainer's
/// `sp14_alpha_grad_compute_kernel` (`SP14_ALPHA_GRAD_CUBIN`).
exp_sp14_alpha_grad_compute_kernel: CudaFunction,
/// B.2 Plan 3 Task 3: trade_attempt_rate_ema_update GPU kernel.
/// Single-block (1 thread) reduction + adaptive EMA of Flat→Positioned
/// transition rate into ISV[71]. Launched alongside reward_component_ema
@@ -1801,6 +1838,69 @@ impl GpuExperienceCollector {
format!("SP13 v3 sp13_hold_rate_buf alloc (1 f32, collector): {e}")
))?;
// SP14 β-migration (Option B, 2026-05-07): pre-load the 4 SP14/SP13
// EGF kernel handles on the collector's stream. The diagnostic
// motivation lives in commit 9d0c124ce (kernel-gate fix) — even
// with that gate, the trainer-time `submit_aux_ops` chain feeds
// the EGF producers a Q-head that has converged to Hold/Flat on
// replayed batches (total_cnt=0 every batch → EMAs decay to
// zero). The rollout path with Thompson-forced Short/Long picks
// is where the genuine aux↔Q disagreement signal lives. Each
// load mirrors the SP13 hold-rate pattern at line 1820 — same
// cubin as the trainer, loaded once on this stream so the
// chained launches submit on `self.stream` and producer→consumer
// ordering is stream-implicit (no cross-stream race, no host
// sync). Per `feedback_no_partial_refactor.md`: handles allocate
// here in step 1 of the β migration, launches wire in step 4.
let exp_sp13_aux_dir_acc_reduce_kernel = {
use super::gpu_dqn_trainer::SP13_AUX_DIR_ACC_REDUCE_CUBIN;
let m = stream.context()
.load_cubin(SP13_AUX_DIR_ACC_REDUCE_CUBIN.to_vec())
.map_err(|e| MLError::ModelError(format!(
"sp14-β: aux_dir_acc_reduce cubin (collector): {e}"
)))?;
m.load_function("aux_dir_acc_reduce_kernel")
.map_err(|e| MLError::ModelError(format!(
"sp14-β: aux_dir_acc_reduce_kernel load (collector): {e}"
)))?
};
let exp_sp13_aux_pred_to_isv_tanh_kernel = {
use super::gpu_dqn_trainer::SP13_AUX_PRED_TO_ISV_TANH_CUBIN;
let m = stream.context()
.load_cubin(SP13_AUX_PRED_TO_ISV_TANH_CUBIN.to_vec())
.map_err(|e| MLError::ModelError(format!(
"sp14-β: aux_pred_to_isv_tanh cubin (collector): {e}"
)))?;
m.load_function("aux_pred_to_isv_tanh_kernel")
.map_err(|e| MLError::ModelError(format!(
"sp14-β: aux_pred_to_isv_tanh_kernel load (collector): {e}"
)))?
};
let exp_sp14_q_disagreement_update_kernel = {
use super::gpu_dqn_trainer::SP14_Q_DISAGREEMENT_CUBIN;
let m = stream.context()
.load_cubin(SP14_Q_DISAGREEMENT_CUBIN.to_vec())
.map_err(|e| MLError::ModelError(format!(
"sp14-β: q_disagreement cubin (collector): {e}"
)))?;
m.load_function("q_disagreement_update_kernel")
.map_err(|e| MLError::ModelError(format!(
"sp14-β: q_disagreement_update_kernel load (collector): {e}"
)))?
};
let exp_sp14_alpha_grad_compute_kernel = {
use super::gpu_dqn_trainer::SP14_ALPHA_GRAD_CUBIN;
let m = stream.context()
.load_cubin(SP14_ALPHA_GRAD_CUBIN.to_vec())
.map_err(|e| MLError::ModelError(format!(
"sp14-β: alpha_grad cubin (collector): {e}"
)))?;
m.load_function("alpha_grad_compute_kernel")
.map_err(|e| MLError::ModelError(format!(
"sp14-β: alpha_grad_compute_kernel load (collector): {e}"
)))?
};
// SP15 Phase 1.3.b-followup (2026-05-07): per-env DD state tile
// sized `[alloc_episodes * 6]`. The redesigned `dd_state_kernel`
// writes 6 stats per env to this tile (Path A → Path B
@@ -2156,6 +2256,14 @@ impl GpuExperienceCollector {
sp13_hold_rate_observer_kernel,
sp13_apply_fixed_alpha_ema_kernel,
sp13_hold_rate_buf,
// SP14 β-migration (Option B, 2026-05-07): kernel handles for
// the collector-native EGF producer chain. Wired in step 4 of
// the β migration; this commit just allocates the handles
// (additive, no behavior change).
exp_sp13_aux_dir_acc_reduce_kernel,
exp_sp13_aux_pred_to_isv_tanh_kernel,
exp_sp14_q_disagreement_update_kernel,
exp_sp14_alpha_grad_compute_kernel,
trade_attempt_rate_ema_kernel,
plan_threshold_update_kernel,
state_kl_kernel,