Expand description
The lane’s kernel library: one CUDA kernel per kind of op a step runs, each templated over the forms the fusion rules ask of it (a residual added before a norm, an activation quantized in a producer’s epilogue, a result written into the row of a cache a position names). The planner instantiates them; no kernel here knows a model.
Every kernel computes what the language’s sugar means, the formula the VM runs: an RMSNorm divides by
sqrt(mean + 1e-6) then scales, an attention scores (q·k)/√hd and normalizes by a max-subtracted softmax, an
arg-max keeps the first of equal maxima. Accumulation is f32 in a fixed order (the same inputs give the same
bits on every run); the projections are the one place the numerics are a choice — Q8MatKind picks the
activation precision of every Q8_0 GEMV:
• Dequant — the activation stays f32, the int8 weight is scaled in the kernel, the dot accumulates in f64:
the precise lane, logits a hair from the f64 reference;
• Int8Act — the activation quantized to int8 per 32-block and multiplied by __dp4a against the weight
(llama.cpp’s MMVQ shape): the fast lane;
• TwoPassInt8 — the activation split into a high and a low int8 word, two __dp4a per block: ~14-bit
activations at the fast lane’s memory cost.
A quantized activation is a group of 32 values sharing one scale s = max|v| / 127; the high word is
round(v / s), the low word round((v − hi·s) / (s/128)) with v − hi·s one fused multiply-add, as the f64
reference computes it.
A Q8_0 matrix is uploaded split, its int8 values in one array and its block scales in another, so the GEMV reads
16-byte words. A matrix in any other GGUF format keeps its blocks as the checkpoint stores them, and BLOCKS
decodes a 32-weight sub-block of a row into int8 levels with a scale and an offset per 16 — weight = scale·level + offset, exactly the CPU dequantizer’s arithmetic — so one row dot serves every format under every numerics: the
offset term multiplies the activation’s sum, which the int8 lanes take with a __dp4a against ones.
Enums§
- Kernel
- One library kernel: its name and its source.
Constants§
- ATTN_
BLOCK_ VALUES - The key and value elements an attention block reads a position, across its heads: four latent-attention heads’
worth (
(576 + 512) · 4), which scored best from a thousand positions on (the 3060’s attention measurements), against two heads’ at a hundred. - ATTN_
FOLD_ PAIRS - The value pairs a block of
lk_attention_foldfolds, a thread each. - ATTN_
HELD_ BYTES - The most shared memory an attention block (
lk_attention) keeps its chunks’ partials in, so a row it takes whole (a batch’s sequence, a chunk’s row) weighs each chunk once: a block of 256 threads keeps three to a streaming multiprocessor. - ATTN_
I8_ QUERIES - The query vectors a block of the two-word attention (
lk_attention_i8) takes, a warp 16 of them. - ATTN_
MIN_ SPLIT - The fewest positions a split of an attention’s span takes: below it a split’s partial costs more than its scores.
- ATTN_
MMA_ QUERIES - The query vectors a block of the f16 tensor-core attention (
lk_attention_mma) takes, a warp 16 of them. - ATTN_
SHARED_ HEADS - The most query heads
lk_attention_sharedtakes in its one block: four warps of four heads. - ATTN_
SHARED_ STEP - The cached rows
lk_attention_sharedstages a step (LK_STin its source). - ATTN_
TILE - The positions the attention scores at a time (
LK_TILEin its source). - ATTN_
TILE_ Q - The query vectors a block of the tiled attention takes: heads of one key/value group over consecutive rows.
- AXPY_R
- AXPY_
SUMS - The bytes of the staged per-head matmul’s own sums in shared memory (
red): anf32for each lane of each of itsAXPY_R · AXPY_Wwarps — it stages only under the quantized numerics, which sum inf32. - AXPY_W
- The sub-blocks of outputs and the row groups a block of the staged per-head matmul takes.
- BLOCKS
- A weight matrix as the kernels read it, and the sub-block decoders of every format besides Q8_0 (template argument
F, the GGUF type id): a Q8_0 matrix is its int8 valuesqand block scaless; any other is its blocksb, a row everyrbbytes.lk_sub<F>decodes sub-blocksb(weights32·sb …) of a row into 32 int8 levels and, per half, a scale and an offset; a weight isscale·level + offsetrounded as the CPU dequantizer rounds it (a product, then a sum);lk_level<F>decodes one element of a sub-block alike.lk_row_dot<F, Q, M>is a row’s dot withMactivation rows (ldapart) under numericsQ, one warp;lk_dot<F, Q, M>the same for any format, a Q8_0 matrix’s split arrays included;lk_gemv_dot<F, Q, M>a row’s dot withMactivation rows of its length as the plain GEMV of its format takes it, the one dot of a format every kernel shares so a fused launch computes what its parts computed. - DELTA_
CHUNK - The rows of a chunk of the chunked delta rule (
LK_DCin its source), the rows of a value head’s memory a block of its walk takes, and the threads of that block: two warps. - DELTA_
PREP_ SMEM - The dynamic shared memory of
lk_delta_prep: a run of 32 of a chunk’s keys’ and queries’ values (thenT),A, and the sumsT’s lower blocks take — rows padded a value. - DELTA_
STATE_ ROWS - DELTA_
STATE_ THREADS - GEMM_
BLK_ TILE_ M - The activation rows of a dense block-format tensor-core GEMM block’s tile (its outputs:
GEMM_TILE_N). - GEMM_
PARTS - The matrices a launch in parts (
lk_parts:lk_gemv_parts,lk_gemv_mma,lk_gemm_blk‘sG4) multiplies one activation by at most — the kernels’LK_PARTS: six, so a recurrent layer’s query, key, value, output gate and two gates project its activation in one launch, the gates no launch of their own (at Qwen3.5-0.8B’s batch of 64 a single block on the 3060, 16.8 µs a layer). - GEMM_
TILE_ N - The outputs a block of the tensor-core block GEMM computes (
lk_gemm_blk’s tile). - GEMV_
F32_ ROWS - The activation rows a block of
lk_gemv_f32takes, together (itsLK_F32_ROWS): few enough that a wide chunk’s rows spread over the chip, every row’s dots summed as one row’s are. - GEMV_
MMA_ MIN_ ROWS - The fewest rows a batch’s Q8_0 projection takes to the tensor cores (
lk_gemv_mma); fewer run on the GEMV. - GEMV_
MMA_ ROWS - The most rows
lk_gemv_mmatakes in one launch: four m-tiles of 16. - HEAD_
TILE_ M - The rows of a tiled per-head matmul block (
lk_head_tiled), each block 64 of a head’s outputs. - PRELUDE
- The helpers every kernel shares: the storage types, row addressing, warp and block reductions, the activation quantizer.
- ROPE_
HEAD - The widest head a rotation turns: its block holds the head’s values in shared memory (
lk_rope_head’shv). - STALL
- A stream held back for a span of the global timer. Under
--stagger <seed>one runs before each launch of a step, its span drawn from the seed, the form and the launch, so launches its streams leave unordered run in another order under each seed.
Functions§
- accumulator
- The bytes of the lane’s sums under the numerics of kernel mode
mode(mode), and their CUDA type:f64for the precise numerics (mode 0) — every sum of every kernel, a norm’s, a convolution’s, the delta rule’s, the router’s softmax and the experts’ —f32for the others. - argmax_
blocks - The blocks an arg-max over
nvalues spreads across: a run of at least 2048 values a block, at most 64 blocks. - attn_
blocks_ a_ multiprocessor - The blocks of an attention (
lk_attention‘sMB) a multiprocessor holds at once, by the registers it leaves them: three for a launch of more blocks than the chip holds at two (blocksoversms), which come in waves, so occupancy bounds them — on the 3060, 5.7% faster for Llama-3.2-1B’s batch of 64 and 3.4% for Gemma-3-1B’s; two for a launch under one wave, whose blocks’ latency bounds it, and for thef64sums (acc8 bytes), which need the registers. - attn_
flash_ queries - The query vectors a block of the flash attention (
lk_attention_flash) takes: 64 for heads and values to 128 wide, 32 past them, so a thread’s outputs stay 64 registers and the block’s shared memory within a block’s. - attn_
flash_ smem_ bytes - The flash attention block’s dynamic shared memory: its queries, two stages of a tile’s keys 32 values of the head at a time and of its values 16 keys at a time, and the tile’s weights — rows padded four values.
- attn_
flash_ threads - The threads of a flash attention block: 256 over 64 queries (a thread 4 queries by 4 keys), 128 over 32 — where the 3060 measured each fastest.
- attn_
heads_ per_ block - The query heads an attention block takes together: the largest divisor of
group, at most 16, whose keys and values a position stay withinATTN_BLOCK_VALUES(one head whatever its width), whose accumulators (gheads’ value pairs a thread, twice over in a block that takes every chunk) stay within 32 registers, and whose queries, scores and chunk sums fitsmembytes —Nonewhen not even one head fits. - attn_
held_ bytes - The bytes of a block’s
gheads’ partials oversplitschunks — each chunk’s maximum, sum andvdweighed values, in the accumulator’saccbytes — and whether the block holds them (held): a row cut into chunks, the partials withinATTN_HELD_BYTES. - attn_
holds - attn_
i8_ keys - The keys a tile of the two-word attention takes: 64, or 32 where heads or values pass 128 wide.
- attn_
i8_ rows - The key rows a key/value group’s two words take for a cache of
lenpositions: whole tiles of 64. - attn_
i8_ scratch - The two-word attention’s scratch for a cache of
lenpositions overgroupskey/value groups: the keys’ high and low words, the values’, and each row’s two scales — in bytes. - attn_
i8_ smem_ bytes - The two-word attention block’s dynamic shared memory: a tile’s keys’ and values’ two words, rows padded 16 bytes, and both its scales in two buffers.
- attn_
mma_ keys - The keys a tile of the f16 tensor-core attention takes: 64, or 32 where heads or values pass 192 wide.
- attn_
mma_ smem_ bytes - The f16 tensor-core attention block’s dynamic shared memory: a tile’s keys (
attn_mma_keys) and their values as f16, rows padded eight values. - attn_
path - The path an attention launch takes past a row of one chunk (
lk_attention‘sPATH,lk_attn_path), fixed where it launches so its kernel compiles that path alone and ptxas allots its registers to it: the chunks’ partials of a grid ofzsplit blocks a row folded by the last to arrive, held side by side by the row’s one block (sidechunks at a time), weighed one at a time by it, or none where a row is one chunk (splits1). - attn_
run_ width - The lanes a key’s dot takes in an attention of heads
hdwide (lk_attn_run_width,lk_attention’sRW): a half warp for a head of 9 to 16 fours, the whole warp otherwise. - attn_
shared_ padded_ heads - The heads
lk_attention_sharedpads itsgheads to: whole warps of four. - attn_
shared_ smem_ bytes - The dynamic shared memory of a block of
lk_attention_sharedovergheads ofhd: two steps’ rows, and a step’s scores of every padded head. - attn_
shared_ splits - The most chunks
lk_attention_sharedcuts a row’s span ofspanpositions into, the decode step’s in every form: one block a streaming multiprocessor (sms), its shared memory a block’s, and no more than give each chunkATTN_MIN_SPLITpositions. - attn_
side_ bytes - The shared memory a block weighing
sidechunks side by side takes pastattn_smem_bytes’ one tile of scores: a tile of itsgheads’ scores for each other chunk. - attn_
side_ chunks - The chunks of its row a block that holds them weighs side by side (
lk_attn_side): as many as its threads’ value slots hold — each chunkvd / 2pairs a head, a threadattn_values_per_threada head — and no more than the row’ssplits; one where a chunk fills them. - attn_
smem_ bytes - The dynamic shared memory an attention block takes: its
gquery heads ofhd(f32), then — in accumulators ofaccbytes — their scores over a tile and each head’s maximum, sum and fold factor over each ofsplitschunks. - attn_
splits - The most chunks an attention cuts a row’s span into: enough blocks for two a streaming multiprocessor (
sms) over theblocksthe head blocks of one row give, and no more than give each chunkATTN_MIN_SPLITpositions ofspan. - attn_
tile_ heads - The heads of one group a tiled attention block takes: the largest power of two dividing
group, at most 32 — the block’s rowsATTN_TILE_Qover it. - attn_
tile_ smem_ bytes - The tiled attention block’s dynamic shared memory: a 32-wide chunk of its queries and of a tile’s 64 keys, the tile’s scores, and eight keys’ values.
- attn_
tile_ values - The groups of four values, 128 apart, a thread of the tiled attention accumulates for each of its queries.
- attn_
values_ per_ thread - The pairs of each head’s values a thread of an attention block (256 threads) accumulates:
lk_attentionweighs at mostgtimes as many of its block’sgheads’ value slots a thread. - axpy_
pitch - The bytes of a row the staged per-head matmul holds in shared memory (
lk_axpy_pitch): the units ofAXPY_Wsub-blocks and one more, 15 bytes of alignment slack, rounded to an odd number of words. - axpy_
staged - Whether a per-head matmul whose rows are its inputs stages them (
lk_head_axpy_staged,AXPY_Wsub-blocks andAXPY_Rrow groups a block): under the quantized numerics in every block format but Q6_K and Q8_0 — 1.7–2.8 times the per-lane kernel on the 3060 there (19.9 µs to 9.7 for DeepSeek-V2-Lite’s Q4_K absorption); the per-lane kernel keeps the precise numerics’f64sums, Q6_K’s heavier decode and Q8_0’s one activation row. The choice reads no count of activation rows: a prompt’s chunk and a decode step sum alike, so a prompt continues alike in chunks or a token at a time. - block_
holds_ its_ norm - Whether a block of
threadsruns a norm of a row ofcolsas the norm’s own block does, each of its threads one of the norm’s (norm_threads). A narrower block plays several of the norm’s warps a warp, one after another, and the row’s norm runs on that one block alone: DeepSeek-V2-Lite’s 320-thread down blocks playing the norm’s 1024 decoded at 142.0 tokens a second on the 3060, 146.7 with the norm’s tail cut and 146.3 with the norm its own launch. - decodes
- Whether the block library decodes
ty: the formats with a sub-block decoder below. - delta_
chunk_ scratch - The floats of the chunked delta rule’s scratch over
chunkschunks ofhvvalue headsdwide: each chunk’s decayed keys and queries (a value of the width at a time), itsT·diag(β)and masked scores, and its rows’ decays to its end with its own. - delta_
chunks_ take - Whether the chunked delta rule takes heads
dwide: at most 128, in whole runs of 32 (a lane of the walk’s warpd / 32values of the width, the preparation’s runs of 32). - format_
arg - The template argument that names a weight format in the block library: its GGUF type id.
- gemm_
blk_ expert_ rows - The activation rows of a grouped GEMM block over an expert mixture’s choices: 128 when the average expert has more
than 64 rows to multiply (
choices / experts), 64 otherwise — a taller tile reads each expert’s decoded weights for more rows, a shorter one leaves fewer of its rows empty. - gemm_
blk_ launch_ smem - The dynamic shared memory one launch of the block-format tensor-core GEMM over
ktakes: a Q8_0 matrix’s streamed path over akof whole 128-value scale groups, the block path otherwise — so the streamed path’s blocks are not held to the block path’s larger stages, and two of them share a multiprocessor where its registers allow. - gemm_
blk_ launch_ threads - The threads one launch of the block-format tensor-core GEMM over
ktakes: a Q8_0 matrix’s streamed path over 128 rows, eight warps of 64 rows by 32 outputs — two blocks of them, their registers and stages, share a multiprocessor — and a warp each 32 × 32 of the tile otherwise (gemm_blk_threads). - gemm_
blk_ rows - The activation rows a dense tensor-core GEMM of a matrix in format
f(its GGUF type id) takes a block: 64 for a Q8_0 matrix under two words, so two blocks of its streamed path, both words of each stage, share a multiprocessor;GEMM_BLK_TILE_Motherwise. - gemm_
blk_ smem_ bytes - The dynamic shared memory a block-format tensor-core GEMM block in format
f(its GGUF type id) overbmactivation rows may take, whichever path a launch takes (gemm_blk_launch_smemover everyk): what its kernel is allowed. - gemm_
blk_ tail - How a dense block GEMM of
tilestiles andstagesstages ofkfills its last wave ofworkersblocks:(whole, split)— the firstwholetiles a block each, every later tile cut intosplitparts of its stages, as many as fill the wave.split1 when the tiles fill whole waves, or a wave’s blocks cannot cut a remaining tile in two. - gemm_
blk_ threads - The threads of a block-format tensor-core GEMM block over
bmactivation rows: a warp each 32 × 32 of the tile. - gemm_
f32_ splits - The parts an
f32router GEMM (lk_gemm_f32) oftiles64 × 64 tiles cuts each tile’schunksruns of 32kinto: as many as give the chip’ssmstwo blocks each, whole runs of chunks every one. - gemv_
blk_ norm_ threads - The threads of a block-format projection that norms its row in its last block (
lk_gemv_blk_norm): eight warps, four where a warp takesper_warprows past one. - gemv_
f32_ parts - The warps an
f32GEMV (lk_gemv_f32) cuts each output row’skinto: the most, to eight, that keep 128 values a warp and give itsnoutputs no more than 16 warps a streaming multiprocessor of the chip’ssms. - gemv_
mma_ launch lk_gemv_mma’s launch overmrows (at mostGEMV_MMA_ROWS) of a projection ofnoutputs andkon a chip ofsmsmultiprocessors,(mt, nt, mw, nw): the widest tile its rows fill (gemv_mma_shape), except that a narrow projection of long rows over four m-tiles — its blocks of 128 outputs leaving more than half the chip idle, each running long (kat least 2048) — takes blocks of 64 outputs, twice as many. On the 3060 at 64 rows: Gemma-3-1B’s down projection (6912 by 1152) 94 µs to 54 (62 as the 32-row tile in two slabs of grid layers), Qwen3.5-0.8B’s (3584 by 1024) 54 to 31 (35) and its output projection (2048 by 1024) 33 to 20 (22); wider or shorter projections are faster in blocks of 128.- gemv_
mma_ shape lk_gemv_mma’s shape overmtm-tiles,(nt, mw, nw): four n-tiles of 8 outputs a block over one m-tile, a warp each; eight over two, a warp each n-tile over both; sixteen over four, a warp each two n-tiles over two m-tiles — so a block stages its activation rows once for32·mtoutputs, and over four m-tiles each fragment a warp loads feeds two products. On the 3060 at 64 rows the two-by-two warps beat a warp each n-tile over all four m-tiles on Llama-3.2-1B’s down projection (8192 by 2048) 117 µs to 102, its output projection 33.8 to 30.9, its query, key and value 35.6 to 32.9 and its gate and up 171.6 to 168.8; at 16 and 32 rows two n-tiles a warp gain nothing.- gemv_
mma_ smem_ bytes lk_gemv_mma‘s shared memory (lk_mma_smem): its stages (three, two under the two-word numerics), a stage four blocks of each of its8·ntmatrix rows and16·mtactivation rows (both words’ under two words), rows 144 bytes apart, and the stage’s scales.- gemv_
mma_ threads lk_gemv_mma’s threads: a warp eachnwn-tiles over eachmwof itsmtm-tiles.- gemv_
mma_ tiles lk_gemv_mma’s m-tiles formrows (at mostGEMV_MMA_ROWS): 1, 2 or 4.- head_
mode - The numerics a per-head matmul — a latent’s expansion half — runs under: its activation
f32under every numerics, withf64sums under the precise one (0) andf32sums under the quantized ones (3), so the absorbed latent attention computes what the expanded one does. - mode
- The template argument that names a numerics mode in the library: 0
f32activations, 1 int8, 2 two-pass int8. - moe_
down_ launch - The blocks and threads of a decode step’s down projection (
lk_moe_down,lk_moe_down_norm) over a row ofd:moe_down_rowsoutputs a block, a warp each of thekkept experts and the shared expert’s warps where its intermediatesdffis not 0. - moe_
down_ rows - The outputs a block of the decode step’s expert down projection takes (
Woflk_moe_down), and the warps its shared expert’s rows take (SW): four outputs whereddivides by four, so each kept expert’s warp has four rows’ weight loads in flight over one load of the hidden row — and a warp a row of the shared expert’s where its rows are wider than an expert’s, so no warp holds the block back. Against a block of one output on the 3060, DeepSeek-V2-Lite’s down projections (Q8_0 beside a shared Q6_K, Q5_0 beside a shared Q4_K) drop 13–31%, gpt-oss-20b’s (MXFP4) 23–36% and Qwen3-30B-A3B’s shape (Q4_K, Q6_K) 16–33%; eight outputs lost but in MXFP4. - moe_
group_ smem_ bytes - The shared memory of
lk_moe_groupatthreads: the running offsets and each warp’s counts. - moe_
group_ threads - The threads of the block that groups a block’s expert choices (
lk_moe_group): a warp a 32 choices, as many warps as 32 and as each warp’s count of every one ofexpertsexperts, beside the running offsets, fits 48 KB. - norm_
threads - The threads of a block that norms a row of
cols(lk_rmsnorm, and the norm inside a rotation): the row’s width in whole warps, at most 1024 — each thread then holds at mostcols / 1024values. - route_
warps - The warps an expert router’s row takes (
WPEoflk_moe_route): four for anf32router whose row splits into four parts of whole 16-byte words, so its experts fill four times the blocks; one for a quantized router, whose row is its format’s one dot. - rows_
a_ warp - The output rows a warp of a GEMV takes (
Woflk_row_dot): four in a block format when one activation row meets a matrix of at least 2048 rows of at least 64 sub-blocks — four rows’ weight loads in flight over one load of the activation outran one row a warp by 12–20% on the 3060 there, and lost where fewer warps would cover the chip or a row leaves lanes idle — one otherwise. A Q8_0 row already moves sixteen bytes a lane at a time.