Linear Attention
Chunked linear-attention and state-space layers with a recurrent matrix state S per (sequence, head), served by the
open-source FROST kernels (CuTe DSL, nvidia-cutlass-dsl) through the Python frontend. There is no C++ API for these
operations. Every variant has a forward, a full backward, and a pair of summary operations for context parallelism.
The ops live in cudnn.linear_attention.ops and are PyTorch custom operators with autograd formulas; the summary ops
are <op>_summary and <op>_summary_bwd. The same node types are available on the Python graph API.
Support Matrix
Requires an SM100 / SM103 / SM107 GPU (Blackwell data center) and the CuTe DSL runtime the package depends on
(nvidia-cutlass-dsl, a required dependency except on Windows ARM64; these kernels need 4.7.0 or newer and the engines
decline with an error that names the installed version otherwise). On Windows ARM64, the CuTe DSL and TVM-FFI runtime
dependencies are excluded from the base installation, so the base install does not enable these kernels there.
One linear-attention node per graph.
T is the total token count of the packed batch, N the number of sequences. Dtypes are kernel-native and strict:
callers convert, and every gradient comes back in its input’s dtype. cu_seqlens is int32 or int64.
Layout
All operands use the packed THD layout: tokens of every sequence concatenated along the first axis, with
cu_seqlens ([N + 1]) giving the sequence boundaries. A dense batch of N equal-length sequences is
cu_seqlens = [0, T, 2T, ...] over the flattened tokens; no copy is needed.
Operands may be strided views: the engines build their TMA descriptors from the buffer strides, and the only
requirement is a contiguous innermost (head-dim) axis. A column slice of a wider per-token buffer (for example the
q, k, v pieces of one fused projection) is accepted directly, forward and backward, without .contiguous().
Tensors are rank 3 ([T, heads, dim]); a hidden-fused [T, heads * dim] slice needs a .view to rank 3, which is
free when heads * dim is contiguous.
GDP runs on two timelines: q and g have one row per real token, while k, v and beta have n rows per token.
They come either expanded ([T * n, ...], update-major: the n updates of token t are rows t * n to t * n + n - 1)
or token-major (k [T, n, HK, K], v [T, n, HV, V], beta [T, n, HO], with the caller’s token stride), so the
per-token column slices of a joint [V | K | Q] projection ([T, n * H * D] viewed as [T, n, H, D]) are consumed in
place; dk, dv and dbeta come back in the input’s shape. num_householder == 1 is exactly GDN.
Mamba-2 uses the SSD vocabulary: x plays v, B plays k, C plays q, dt is the gate. The output is
y = C^T S + D x, gated by z sigmoid(z) when z is given.
Semantics worth knowing
- States and checkpoints.
output_final_state=Truereturns the per-sequence state after the last token.checkpoint_every_n_tokens > 0also returns the state series, one entry everyntokens strictly before each sequence end, as a non-differentiable dump that the backward reuses instead of recomputing. The rows are io dtype by default; every variant also takescheckpoint_dtype=torch.float32for fp32 rows (the backward reuses io rows at the chunk cadence and regenerates the dense series from any other rows).state_indicesturnsinitial_stateinto a pool[N_pool, ...]addressed per sequence, written back in place; forward only and exclusive with checkpoints. - Summaries.
<op>_summaryreturns the end state of each sequence from a given start state together with the span’s state-transition operatortransition: for the delta-rule variants a[N, HO, K, K]fp32 matrix (the product of the span’s decayed erase steps, in the backward’s stored orientation), for Mamba-2 a[N, H]fp32 scalar per head (the log2 of the decay product), so that across spansS_final = S_init * transition + S_H.<op>_summary_bwdis the mirror for the state gradient. Together they implement context parallelism over sequence spans. Both are non-differentiable. - batch_invariant. Each sequence’s results are bitwise independent of the batch composition (whole-sequence scheduling; split-K load balancing is disabled).
- Clamps and guards. Mamba-2’s
dtclamp zeroes the gate gradient where active. GDN-2’sbeta_guardis recomputed, not differentiated, in the backward. - Engines. The FROST engines are the only engines for these nodes and are pure pass-through:
check_supportverifies the kernel-native dtypes and head dims listed above and declines everything else. A plan can be pinned by name throughplan_name(for examplegdn_frost,mamba2_frost,mamba2_summary_frost).
Example
Benchmarks against the reference implementations are in benchmark/linear_attention/.