feat(rl): Phase 3 noisy linear layers — state-dependent exploration
Factored noisy nets (Fortunato et al. 2017) for state-dependent
exploration. Replaces brute-force P_MIN probability floor.
- rl_noisy_linear_forward.cu: y = (μ_w + σ_w ⊙ ε_w)x + (μ_b + σ_b ⊙ ε_b)
Factored noise: ε_w[i,j] = f(ε_i)×f(ε_j), f(x) = sign(x)√|x|
Only p+q noise samples needed (not p×q). Per-thread, no atomicAdd.
- rl_noisy_linear_backward.cu: per-batch scratch gradients for all 4
weight tensors. Caller reduces across batches.
- rl/noisy.rs: NoisyLinear struct with Fortunato init (σ = 0.5/√in),
resample_noise() via mapped-pinned host→device, forward/backward.
ISV slot 547 (RL_NOISY_SIGMA_INIT_INDEX, default 0.5).
Not yet wired into DQN/IQN/policy heads — module compiles and is
ready for integration. Will replace P_MIN floor once wired.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>