The IQN backward kernel now computes dL/d(h_s2) = dL/d(combined) ⊙ embed
and outputs it to d_h_s2_buf [B, hidden_dim]. Previously this was
explicitly NOT computed (comment: "trunk trained by C51").
Now the shared trunk receives BOTH gradient signals:
C51: dense cross-entropy gradient (can be noisy/steep)
IQN: bounded Huber quantile gradient (always stable)
The IQN gradient stabilizes trunk training when C51's gradient is steep.
With both signals, the trunk learns from C51's distributional knowledge
AND IQN's risk-aware quantile knowledge simultaneously.
New: d_h_s2_buf allocated in GpuIqnHead, zeroed before backward,
accumulated via atomicAdd across all quantiles per sample.
Accessors added: GpuDqnTrainer::bw_d_h_s2_buf(), shared_h2()
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>