NVIDIA CUTLASS Review: CUDA Templates for GEMM Kernels Behind Modern LLMs
NVIDIA CUTLASS provides CUDA C++ templates and Python DSLs for building custom GEMM kernels. We examine where it fits versus cuBLAS, what the abstraction costs you, and when to reach for it.
If you have ever profiled an LLM inference path and watched 90 percent of the time evaporate inside a single matrix multiply, you already know why CUTLASS exists. General matrix-matrix multiplication (GEMM) is the hot loop of nearly every transformer, every diffusion model, and every classical training step. cuBLAS handles the common cases well, but the moment you need a non-standard data type, a fused epilogue, or a tile shape the vendor library does not ship, you fall off a cliff. CUTLASS is NVIDIA’s open-source answer to that cliff: a hierarchy of CUDA C++ templates (and now Python DSLs) that exposes the same primitives the cuBLAS team uses internally, so you can assemble custom kernels without rewriting warp-level matrix instructions from scratch.
We spent time reading the CUTLASS source tree on GitHub and tracing how it is consumed by projects like FlashAttention, vLLM, and TensorRT-LLM. This review is for developers building inference engines, training frameworks, or fused kernels — not for application engineers who can stay on PyTorch.
What CUTLASS Actually Gives You
CUTLASS decomposes a GEMM into a stack of abstractions: thread-block tile, warp tile, instruction tile, and the data movement required to feed each level. You compose a kernel by picking template parameters at each layer — tile shapes, swizzling patterns, pipelining stages, epilogue functors — and the compiler emits a specialized kernel for that exact configuration. The library ships reference kernels for FP32, FP16, BF16, TF32, INT8, FP8 (E4M3 and E5M2), and the newer narrow-precision formats on Hopper and Blackwell.
The practical upshot is that you get three things you cannot easily build yourself:
- Tensor Core access without inline PTX. The
mmaandwgmmainstructions are wrapped in C++ types you can compose, instead of assembly you have to maintain across architectures. - Asynchronous data movement primitives. TMA (Tensor Memory Accelerator) on Hopper and the older
cp.asyncfamily are exposed through the CuTe layer, so you can build software pipelines without hand-rolling barriers. - Fused epilogues. Bias add, ReLU, GELU, residual add, dequantize — all of these can be chained into the GEMM tail so you avoid a separate kernel launch and the extra round-trip to global memory.
The trade-off is that template error messages are notorious. A single wrong tile shape produces hundreds of lines of substitution-failure noise, and the iteration loop (edit, nvcc, wait) is slow on a cold cache.
CuTe DSL and the Python On-Ramp
The biggest recent shift in CUTLASS is the introduction of CuTe — a layout algebra that describes how logical tensor coordinates map to physical memory — and a Python DSL on top of it. CuTe gives you a uniform vocabulary for tiles, shapes, strides, and partitioning across threads. The Python DSL lets you author kernels with the same semantics as the C++ templates, then JIT-compile them. For prototyping a custom attention variant or a quantization scheme, this collapses the edit-compile-test loop from minutes to seconds.
This matters because the audience for low-level GPU work has widened. Five years ago, the people writing custom GEMMs were a small group of HPC and graphics veterans. Today, a researcher at a six-person startup might need a fused FP8 GEMM with a custom dequantization epilogue to ship their inference path. The Python DSL is NVIDIA’s bet that you should not need to learn 4,000 lines of template metaprogramming to get there.
That said, the Python DSL is newer and the documentation surface is thinner. Expect to read C++ examples and translate. If you are exploring kernels interactively, an AI-aware editor that can keep both languages in context shortens the loop considerably.
Cursor
AI code editor that handles cross-language refactors well — useful when you are reading CUTLASS C++ examples and translating patterns into the Python DSL.
Free tier; Pro $20/month
Affiliate link · We earn a commission at no cost to you.
When to Reach for CUTLASS — and When Not To
The honest answer is that most teams should not write CUTLASS kernels. If cuBLAS, cuBLASLt, or PyTorch’s native operators cover your shapes and data types, use them. NVIDIA ships hand-tuned heuristics that select kernels at runtime, and you will rarely beat them on the standard cases.
CUTLASS earns its place when one of these conditions holds:
- You need a data type or layout the vendor library does not ship — for example, an INT4 weight-only GEMM, a grouped GEMM for mixture-of-experts routing, or a sparse format with a specific compression scheme.
- You need to fuse a non-trivial epilogue that cannot be expressed as a simple bias-and-activation, such as a per-channel quantization scale fused with a residual add.
- You are building a kernel library that will outlive cuBLAS releases, and you need control over the exact instructions emitted so you can profile and tune deterministically.
- You are doing research on new tile schedules, pipelining strategies, or async patterns and need primitives at the warp and thread-block level.
Projects like FlashAttention-3, vLLM’s CUTLASS-backed FP8 path, and several open-source MoE inference stacks fall into the first two buckets. They use CUTLASS because cuBLAS does not, and would not, ship the exact kernel shape they need.
| Use Case | cuBLAS / cuBLASLt | CUTLASS |
|---|---|---|
| Standard FP16/BF16 GEMM | Yes — use this | Overkill |
| FP8 with custom epilogue | Limited | Designed for it |
| Grouped GEMM for MoE | Partial coverage | First-class support |
| Research on tile scheduling | Opaque | Full control |
| Compile time budget | Zero — pre-built | Significant |
A reasonable adoption path is to start with cuBLASLt’s epilogue fusion API for any custom-tail work, fall back to CUTLASS only when you hit a wall, and treat the Python DSL as your prototyping surface before committing to C++ templates in production.
The Maintenance Question
One underdiscussed cost is architectural drift. CUTLASS kernels written for Ampere often need rework for Hopper (TMA, wgmma) and again for Blackwell. The library tracks each architecture with separate examples and template specializations, so a kernel you ship today may require a parallel implementation for the next generation. If you adopt CUTLASS, plan for one engineer to own kernel maintenance across the architectures you support — this is not a fire-and-forget dependency.
The payoff, when it lands, is real. Teams that have built custom CUTLASS kernels for FP8 inference report end-to-end throughput improvements that would be impossible to achieve by composing existing PyTorch ops. The question is whether your workload, team, and roadmap justify owning a kernel.
FAQ
Is CUTLASS a replacement for cuBLAS?
Do I need to write C++ templates, or can I stay in Python?
How portable is a CUTLASS kernel across GPU generations?
Related reading
2026-06-10
How Our OG Image Generation Pipeline Works (Satori, resvg, and a Cloudflare Worker)
A look inside the pipeline that renders a unique social preview image for every article on pickuma.com — the components, the failure modes, and what we'd skip.
2026-06-08
What Our llms.txt Is, and Why We Publish It
Pickuma ships two machine-readable files for AI crawlers: an index and a full corpus. Here's what's in them, how they're generated, and why a review site publishes its own content to language models.
2026-05-28
AI-Assisted Writing Disclosure: Where We Draw the Line
Most 'AI-assisted' badges are vague. Here's the binary threshold we use for flagging articles, why FTC and E-E-A-T guidance pushed us there, and the edge cases that still leak.
2026-05-26
AI Agent Pipelines for Developer Productivity: What Actually Saves Hours
We tested a four-stage AI agent pipeline for code review, test generation, and deployment over two weeks. Here's where the gains are real and where the failure modes hide.
2026-05-26
GPT-5.5 Instant vs GPT-5.3 Instant: Testing OpenAI's Three Claims
OpenAI silently swapped ChatGPT's default from GPT-5.3 Instant to GPT-5.5 Instant. We break down which of the three official claims — speed, reasoning, accuracy — hold up in independent testing, and what to do if you ship on the API.
Get the best tools, weekly
One email every Friday. No spam, unsubscribe anytime.