Three root causes of CUDA_ERROR_INVALID_PTX on H100 addressed:
1. TMA busy-wait label: cooperative_load_tile_tma used a named PTX label
(TMA_WAIT:) in a __forceinline__ function inlined at ~28 call sites,
producing duplicate labels in the same PTX function. Replaced with a
C while loop + selp.b32 to extract the try_wait predicate — no PTX
labels emitted.
2. mbarrier wait scope: only thread 0 waited for TMA completion while
lanes 1-31 skipped the entire function body. Now all 32 lanes
participate in mbarrier.try_wait.parity.acquire, with __syncwarp()
fences before and after to handle Hopper independent thread scheduling.
3. Dead per-thread functions: q_forward_dueling, q_forward_branching,
q_forward_distributional, q_forward_dueling_noisy, and their _shmem
variants were compiled into sm_90 PTX despite never being called by
the warp kernel. q_forward_distributional alone allocates 600 floats
(2.4KB) per thread. Guarded all three groups with
#if __CUDA_ARCH__ < 900 to eliminate ~7KB dead stack from PTX.
Also: removed NUM_ATOMS_MAX=51 cap (no longer needed since distributional
per-thread function is excluded), moved dim_overrides before common_src
to avoid NVRTC macro redefinition warnings.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>