An Illustrated Guide to GPU Kernels for ML
From what is a warp to why FlashAttention-4 changes the Blackwell schedule. Every mechanism is drawn, most are interactive, and key claims link to their sources. Written for people who train or serve models and want to stop treating the kernel layer as a black box.
There is a particular kind of frustration in reading GPU kernel code. Every line is simple — an index computation, a load, a barrier — and yet the whole is opaque, because the reasons live in hardware behaviour that nobody writes down next to the code. Why 128×128 tiles? Why is the shared-memory array indexed with an XOR? Why does the fast attention kernel have two warpgroups doing different things?
This series answers those questions in order, from the bottom. It is built the way the MMA swizzle-layout post that inspired it is built: numbered sections, a diagram for every mechanism, and a refusal to hand-wave past the confusing part.
§ The parts
§ Conventions used throughout
Every diagram in the series is drawn from one small palette, and colour always means the same thing. There are only two hues. Blue is the execution side of the machine — lanes, warps, warpgroups, blocks. Amber is the storage side — registers, shared memory, L2, HBM. Within each, darker means further out: a darker blue is a wider scope, a darker amber is further from the ALU and slower to reach.
That leaves pink for the one thing that is neither, the tensor core, and grey for anything idle, masked or wasted. Green and red are held back for verdicts — conflict-free versus serialised, above the ridge versus below it — and never used to name a component.
- interactive in a caption means the figure has controls. Drag them; the readout under the chart updates. Nothing is a video — every figure is live SVG.
- Code appears in tabs. CUDA is the ground truth, Triton is what most people write, and PyTorch is the reference semantics you are trying to match. Not every block has all three.
- Key numbers are sourced inline. Where NVIDIA quotes a figure "with sparsity", the dense number is shown for an apples-to-apples roofline. The higher sparse peak is real when operands satisfy NVIDIA's supported 2:4 structured-sparsity pattern; an ordinary dense LLM kernel does not receive it automatically.
- Solid fills are measurements — a bar's length or a cell's value. Pale washes with a coloured outline are containers — a box in a floorplan or a dataflow. If a shape is pale, its size means nothing.
- The dark button in the top bar switches themes; the diagrams recolour with it.
§ The numbers worth memorising
Almost every design decision in the series is downstream of one of these. If you only take one thing from Parts 1–3, take this table.
| A100 80GB | H100 SXM5 | H200 SXM | B200 (HGX) | |
|---|---|---|---|---|
| SMs | 108 | 132 | 132 | 148* |
| Warps / registers / SM | 64 · 64K | 64 · 64K | 64 · 64K | 64 · 64K |
| Max shared memory / SM | 164 KB | 228 KB | 228 KB | 228 KB |
| L2 cache | 40 MB | 50 MB | 50 MB | 126 MB |
| HBM bandwidth | 2.04 TB/s | 3.35 TB/s | 4.8 TB/s | 7.7 TB/s |
| BF16 tensor, dense | 312 TF | 989 TF | 989 TF | 2,250 TF |
| FP8 tensor, dense | — | 1,979 TF | 1,979 TF | 4,500 TF |
| FP4 tensor, dense | — | — | — | 9,000 TF |
| FP32 (non-tensor) | 19.5 TF | 67 TF | 67 TF | 75 TF |
| BF16 roofline ridge | 153 FLOP/B | 295 FLOP/B | 206 FLOP/B | 292 FLOP/B |
* NVIDIA does not publish B200's SM count; 148 is a third-party measurement. NVIDIA's Blackwell Tuning Guide publishes the 126 MB L2 capacity. Tensor figures here are dense; NVIDIA's 2:4 sparse figures are twice the dense peak and require compatible structured operands. Ridge point = dense peak ÷ HBM bandwidth: the arithmetic intensity above which a kernel becomes compute-bound.
An H100 can do 295 BF16 tensor-core FLOPs in the time it takes to read one byte from HBM. Nearly every kernel technique in this series — tiling, fusion, low precision, KV-cache layout — exists to move a workload across that line, or to accept that it cannot and go as fast as memory allows.
§ Prerequisites and sources
You need to be able to read C and Python. You do not need prior CUDA. If you have written a Triton kernel and want to know what it compiles into, or you have read the FlashAttention paper and want to know what "warp specialization" physically means, this is aimed at you.
The series leans on primary documentation throughout — the CUDA Programming Guide, PTX ISA, CUTLASS/CuTe source, and NVIDIA's architecture tuning guides — plus the following, which are worth reading in full:
- Yifan Yang, Tensor Core MMA Swizzle Layout — the post that prompted this series.
- Simon Boehm, How to Optimize a CUDA Matmul Kernel — the canonical optimization ladder.
- Horace He, Making Deep Learning Go Brrrr From First Principles — the compute / bandwidth / overhead taxonomy.
- Vasily Volkov, Better Performance at Lower Occupancy (GTC 2010) — still the correct framing of occupancy.
- Dao et al., FlashAttention-2, FlashAttention-3, and FlashAttention-4.
- Colfax Research's CUTLASS tutorials — the best writing on Hopper-era kernel structure.
Marosi, Mark. An Illustrated Guide to GPU Kernels for ML. 2026. gpu-kernels.pages.dev.
@misc{mapika2026gpukernels,
author = {Marosi, Mark},
title = {An Illustrated Guide to GPU Kernels for ML},
year = {2026},
url = {https://gpu-kernels.pages.dev/}
}
§ Read it offline
Every page here is self-contained — no build step, no CDN, nothing fetched at runtime — so the whole series works from a local folder or a USB stick.
Complete edition
All nine parts in a single scrolling document with a series sidebar. Good for reading straight through, or for printing.
Download · ZIPZIP of the whole site
The nine parts plus the contents page as separate linked HTML files, and the single-file edition. Open index.html and it works offline.