Replace all Candle tensor operations in the fused training loop with
pure cudarc CudaSlice operations to prevent Candle tensor Drops from
recording events on the default stream (which conflicts with our forked
training stream via cudarc event tracking).
Key changes:
- Re-enable disable_event_tracking() in GpuDqnTrainer::new() — safe now
that no Candle tensors are created during training
- Rewrite upload_batch_gpu(): BF16 states/next_states use DtoD + bf16→f32
kernel instead of Candle to_dtype(F32); F32 rewards/dones/weights use
direct DtoD copy with layout offset handling
- Load bf16_to_f32_kernel from training module (was defined in CUH but
not loaded)
- Add train_value_step_raw() to GpuIqlTrainer that takes CudaSlice<f32>
directly, bypassing Candle tensor manipulation
- IQL in fused training now reuses DQN trainer's already-converted F32
states_buf/rewards_buf instead of creating Candle temporaries
- Fix dtod_from_candle_f32/u32 to respect Candle layout start_offset
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>