You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
causal_conv1d_fwd and causal_conv1d_update produce numerically incorrect output on B300 (SM103, "Blackwell-Ultra") when built from source with CUDA 13.x and the SM103 gencode that setup.py enables for bare_metal_version >= 13.0. Forward output drifts by max_abs_diff ≈ 0.4–0.6 on BF16 (well above any reasonable tolerance), and causal_conv1d_update loses its in-place conv_state update entirely (state error ≈ 0.98). Same source compiled for sm_100 only is bit-exact correct on the same hardware (max_abs_diff = 0).
Wheel causal-conv1d==1.6.1 (no sm_103 cubin, falls back to sm_100 on B300)
0.0e+00
✅ correct
Source build, CUDA 13.2, default arch list (incl. compute_103,sm_103)
~6.0e-01
❌ wrong
Source build, CUDA 13.2, arch list with onlycompute_100,sm_100
0.0e+00
✅ correct
Source build, CUDA 13.2, arch list with onlycompute_103,sm_103
~6.0e-01
❌ wrong
So when both cubins are present in the fatbin, the CUDA loader picks sm_103 on B300 (exact major.minor match), and that cubin produces wrong output. The sm_100 cubin is forward-compatible to sm_103 within the Blackwell family and is correct.
Environment
GPU: NVIDIA B300 SXM6 AC (compute capability 10.3, "Blackwell-Ultra")
update_bf16_width4's state_err ≈ 0.98 is particularly damning — conv_state gets shifted left by one and the new token appended, but with sm_103 it looks like the in-place store is being dropped or scrambled.
Workarounds
The simplest workaround is to drop the arch=compute_103,code=sm_103 gencode from setup.py and let the sm_100 cubin handle B300 via Blackwell forward-compatibility. Patch:
Verified that this restores correctness on B300 in our full test matrix (fwd_bf16_*, update_bf16_*, causal_conv1d_varlen_*).
Hypothesis
Either nvcc 13.2's SM103 codegen has a bug for this specific kernel (the warp-shuffle / cub::BlockLoad<..., BLOCK_LOAD_WARP_TRANSPOSE> exchange pattern is the most subtle thing in the kernel), or the CUB version shipped with CUDA 13.2 has an SM103 path that miscompiles the WARP_TRANSPOSE algorithm. We didn't dig into PTX/SASS to pin it down — happy to do so if useful.
Next steps
Will open a PR that applies the diff above and adds a B300 test job to CI if you have B300 capacity.
Summary
causal_conv1d_fwdandcausal_conv1d_updateproduce numerically incorrect output on B300 (SM103, "Blackwell-Ultra") when built from source with CUDA 13.x and the SM103 gencode thatsetup.pyenables forbare_metal_version >= 13.0. Forward output drifts bymax_abs_diff ≈ 0.4–0.6on BF16 (well above any reasonable tolerance), andcausal_conv1d_updateloses its in-placeconv_stateupdate entirely (state error≈ 0.98). Same source compiled forsm_100only is bit-exact correct on the same hardware (max_abs_diff = 0).Repro
causal-conv1d==1.6.1(no sm_103 cubin, falls back to sm_100 on B300)0.0e+00compute_103,sm_103)~6.0e-01compute_100,sm_1000.0e+00compute_103,sm_103~6.0e-01So when both cubins are present in the fatbin, the CUDA loader picks
sm_103on B300 (exact major.minor match), and that cubin produces wrong output. Thesm_100cubin is forward-compatible tosm_103within the Blackwell family and is correct.Environment
cuda_13.2.r13.2/compiler.37434383_00d2252d(currentmain, includes [NVIDIA] Add support Thor, Spark and GB300 #71's SM103 gencode)cuobjdump --list-elfon the locally-built.so:Failing test cases
In our test suite (which mirrors the upstream
tests/test_causal_conv1d.pyat smaller shapes):update_bf16_width4'sstate_err ≈ 0.98is particularly damning —conv_stategets shifted left by one and the new token appended, but with sm_103 it looks like the in-place store is being dropped or scrambled.Workarounds
The simplest workaround is to drop the
arch=compute_103,code=sm_103gencode fromsetup.pyand let thesm_100cubin handle B300 via Blackwell forward-compatibility. Patch:Verified that this restores correctness on B300 in our full test matrix (
fwd_bf16_*,update_bf16_*,causal_conv1d_varlen_*).Hypothesis
Either nvcc 13.2's SM103 codegen has a bug for this specific kernel (the warp-shuffle /
cub::BlockLoad<..., BLOCK_LOAD_WARP_TRANSPOSE>exchange pattern is the most subtle thing in the kernel), or the CUB version shipped with CUDA 13.2 has an SM103 path that miscompiles the WARP_TRANSPOSE algorithm. We didn't dig into PTX/SASS to pin it down — happy to do so if useful.Next steps
Will open a PR that applies the diff above and adds a B300 test job to CI if you have B300 capacity.