Split graph_forward into graph_forward_main (Pass 1+2+loss+backward
on main stream) and graph_forward_ddqn (Pass 3 on double_dqn_stream).
Event synchronization happens in ungraphed replay_forward() code,
not inside captured functions. Each graph uses its own CublasForward
handle — no set_stream() during capture.
Fixes: H100 training hang with gpu_n_episodes=4096.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>