Repository navigation
[Fix] Fold chunk state launch grids to fit the 65535-block limit - #1239
Conversation
The state kernels launch a (NK, NV, N*H) grid. N is the number of packed documents for varlen, so a packed batch with more than 65535/H documents overflows CUDA's per-axis grid cap and the launch fails with 'invalid argument'. GDN's chunk_delta_h was fixed this way in fla-org#1077; the same kernels were missed.
|
The failing smoke test is pre-existing on
https://github.com/fla-org/flash-linear-attention/actions/runs/34407286027 The dependent-test list is run in order and stops at the first failing file, so the smoke job For reference, the changed paths were verified locally on RTX 5090 D (sm_120, torch 2.8.0+cu128, Update: the base branch has since been updated and now includes |
|
pytest tests/ops/test_simple_gla.py tests/ops/test_linear_attn.py tests/ops/utils/test_cumsum.py -q |
|
The Smoke job is red from the 2-hour job cap, not from a test failure.
Touching Two things worth noting for whoever picks this up:
I could not get H100 coverage for the changed files through the |
|
For anyone looking at the red The run I inspected (job
The reason the fanout is this wide is that Two other data points that point the same way:
Net: the code in this PR has not been shown to fail any test; the smoke tier just no longer fits the suite it now selects. Closing this out needs a |
Summary
Avoid invalid CUDA launches when packing many short sequences. Several chunk-state kernels put
N * Hon grid axis z, and vector global cumsum puts it on axis y. Both CUDA axes are limited to 65535 blocks, whereN = len(cu_seqlens) - 1is the number of packed sequences.For example, 2050 sequences of 16 tokens with 32 heads require 65600 blocks and fail at launch with only 32800 input tokens. The trigger is the number of sequences times heads, independent of dtype; a large token count alone does not trigger it.
Flatten these grids onto CUDA's x axis and recover the logical 2D/3D indices through a shared
unflatten_program_id(X, Y)Triton helper. This covers the shared chunk-state kernels used by simple GLA, GLA, GSA, RWKV6 and MesaNet, the separate IPLR/DPLR state kernels, and vector global cumsum used by normalized linear attention and other callers. Per-block computations, dtypes and public APIs are unchanged.Test plan
FLA_CI_ENV=0, default Triton implementations and normal NaN memory poisoning: 259 selected tests passed across simple GLA (32), GLA (30), linear attention (54), RWKV6 (13), IPLR (14), DPLR (35), cumsum (33), GSA (33) and MesaNet (15). All listed test files pass in full except simple GLA, which selects-k 'test_chunk or test_fused_recurrent'. DPLR uses Triton 3.6.0; the other suites use 3.5.1. MesaNet's reference required loading the image's BLAS/LAPACK libraries.fused_chunkfailure on this environment. Independent base/head runs load the correct worktrees, have identicalfused_chunksource hashes, and produce the sameo diff=60.875, ratio=0.999282. This path does not use the changed helper. Triton 3.5.1 also fails to compile an unchanged DPLRwy_fast_bwd.pykernel at D=100 on both base and head; the DPLR suite passes with 3.6.0.Benchmark / NCU (kernel changes only)
Each before/after pair runs on the same GB200, comparing
e27e1aaf→8e8024fc. The grid implementation is unchanged in final head3c94fc43; linear attention was revalidated and remeasured against its updated base (d07d7ad8→3c94fc43). PyTorch 2.11.0.post1+cu132.msh / Triton 3.5.1, BF16, H=8, D=64. Dense: B=2, T=2048. Varlen: B=1, T=4096, 32 sequences of 128 tokens. Values are median before → after, µs.Registry-generated inputs and
benchmarks.ops.run.benchmark_op, with 6 warmup iterations, 40 ms timing warmup and 200 ms repetitions (100/500 ms for the final linear-attention rerun):IPLR and DPLR additionally use
triton.testing.do_bench_cudagraphwith 500 ms repetitions to isolate GPU execution. Eager DPLR timings varied substantially between repeated processes, so those timings do not support a stable regression conclusion. IPLR has no implemented backward API.NCU
--set full/--set sourceon the shared state-forward kernel: duration 12.99 → 12.99 µs, 32 → 32 registers/thread, memory throughput 646.21 → 646.60 GB/s. The profiled state kernel has unchanged latency; IPLR/DPLR graph timings vary by at most 3% on these workloads.Breaking changes
None.
Checklist