关于 cute-dsl-ref
cute-dsl-ref 是面向使用 NVIDIA CuTe Python DSL 编写 GPU 内核的开发者的参考技能,涵盖主机与设备执行模型、API、常见模式及架构约束,包括 SM100 与 SM120 的差异。
主要功能
- 01说明主机与设备内核的职责
- 02汇总布局、张量和 MMA API
- 03介绍 TMA、共享内存与同步
- 04说明 JIT 编译与缓存
- 05列出架构约束和常见模式
适用场景
- 01构建 CuTe DSL GPU 内核
- 02选择布局和 MMA 操作
- 03实现 TMA 流水线与屏障
- 04运行前核对 GPU 架构约束
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ pepperu96/ hyper-mla --skill cute-dsl-ref安装后在 Claude Code 中输入/cute-dsl-ref确认已加载。
附带文件references/architecture-ops.mdreferences/docs-index.md
详细介绍
CuTe Python DSL 参考
执行模型
CuTe Python DSL 是 NVIDIA CuTe 布局代数的 Python 接口。与 cuTile 的块级抽象不同,CuTe DSL 可显式控制线程、warp 和 warpgroup,并提供 TMA 流水线、屏障编排和共享内存管理。
两级主机/设备模式
每个 CuTe DSL 内核都包含两个函数:
@cute.jit主机函数 — 在 CPU 上运行,设置 TMA 描述符、计算网格、分配共享内存并启动内核@cute.kernel设备函数 — 在 GPU 上运行,包含实际计算
import cutlass
import cutlass.cute as cute
@cute.kernel
def my_kernel(tiled_mma: cute.TiledMma, ...):
tidx, _, _ = cute.arch.thread_idx()
bidx, bidy, _ = cute.arch.block_idx()
# ... GPU code
@cute.jit
def host_fn(a: cute.Tensor, b: cute.Tensor, c: cute.Tensor):
# Setup TMA descriptors, compute grid, allocate SMEM
my_kernel(...).launch(grid=grid_shape, block=block_shape, smem=smem_bytes)
编译流水线
三阶段 JIT 编译:
- 预暂存阶段:Python AST 重写
- 元阶段:Python 解释器执行元程序(解析编译时常量)
- 对象阶段:编译器后端生成 PTX → SASS
JIT 产物会自动缓存。使用 CUTE_DSL_CACHE_DIR 和 CUTE_DSL_DISABLE_FILE_CACHING 控制缓存。
与 cuTile 的主要区别
| 方面 | cuTile | CuTe DSL |
|---|---|---|
| 抽象级别 | 块级(无线程标识) | 线程、warp、warpgroup 级 |
| TMA | 隐式(allow_tma=True) | 在主机端显式设置描述符 |
| 共享内存 | 编译器管理 | 显式分配和布局 |
| 同步 | 不提供 | 屏障、到达/等待、命名屏障 |
| 流水线 | 不提供 | 显式多阶段异步流水线 |
| MMA | 对 tile 使用 ct.mma(A, B, C) | 对分区片段使用 cute.gemm(tiled_mma, d, a, b, c) |
| 编译 | cuTile 字节码 → MLIR | CuTe DSL JIT → PTX → SASS |
核心 API 表
装饰器和编译
| API | 用途 | 关键参数 |
|---|---|---|
@cute.kernel | 设备内核装饰器 | 函数名必须与模块文件名一致 |
@cute.jit | 主机 JIT 函数装饰器 | — |
kernel(...).launch(grid, block, smem, cluster) | 启动内核 | grid=(x,y,z)、block=(threads,1,1)、smem=bytes、cluster=(cx,cy,cz) |
cute.compile(fn, *args, options="...") | 提前编译 | "opt-level=3"、"keep-ptx" 等 |
线程/块/网格索引
| API | 用途 |
|---|---|
cute.arch.thread_idx() | 返回 (tidx, tidy, tidz) |
cute.arch.block_idx() | 返回 (bidx, bidy, bidz) |
cute.arch.block_dim() | 块维度 |
cute.arch.grid_dim() | 网格维度 |
cute.arch.warp_idx() | 块内的 warp 索引 |
cute.arch.block_idx_in_cluster() | 集群内的块索引(Hopper+) |
布局和张量构造
| API | 用途 | 说明 |
|---|---|---|
cute.make_layout(shape, stride) | 创建布局 | 核心抽象:将坐标映射为索引 |
cute.make_ordered_layout(shape, order) | 按步幅顺序创建布局 | 例如,列优先布局使用 order=(1,0) |
cute.make_identity_layout(shape) | 创建恒等布局 | 用于谓词处理 |
cute.make_tensor(ptr, layout) | 创建张量视图 | 将指针与布局配对 |
cute.make_fragment(layout, dtype) | 分配寄存器张量 | 用于累加器 |
cute.make_fragment_like(src, dtype) | 创建与源匹配的寄存器张量 | — |
cute.make_ptr(dtype, addr, memspace) | 创建带地址空间标记的指针 | cute.AddressSpace.smem/gmem |
cute.from_dlpack(tensor) | 转换 PyTorch/JAX 张量 | 返回带有 .mark_layout_dynamic() 的 cute.Tensor |
布局代数
| API | 用途 |
|---|---|
cute.size(t, mode=None) | 总大小或指定模式的大小 |
cute.shape(t) | 获取形状元组 |
cute.stride(t) | 获取步幅元组 |
cute.rank(t) | 模式数量 |
cute.local_tile(tensor, tiler, coord, proj) | 提取块的分块 |
cute.logical_divide(tensor, divisor) | 划分为分块和剩余部分 |
cute.composition(layout1, layout2) | 组合布局 |
cute.complement(layout) | 求布局的补布局 |
cute.coalesce(layout) | 简化布局 |
cute.flatten(t) | 展平张量/布局 |
cute.group_modes(layout, start, end) | 将多个模式组合在一起 |
cute.tile_to_shape(tile, shape) | 将分块扩展到目标形状 |
cute.ceil_div(a, b) | 向上取整除法 |
MMA 操作
| API | 用途 | 备注 |
|---|---|---|
cute.make_tiled_mma(op) | 根据操作创建分块 MMA | 例如,tcgen05.MmaF16BF16Op(...) |
tiled_mma.get_slice(thread_idx) | 获取线程的分区 | 返回 ThrMma |
thr_mma.partition_A(tensor) | 对 A 操作数进行分区 | 线程级视图 |
thr_mma.partition_B(tensor) | 对 B 操作数进行分区 | 线程级视图 |
thr_mma.partition_C(tensor) | 对 C 操作数进行分区 | 线程级视图 |
tiled_mma.partition_shape_C(shape) | 获取 C 分区的形状 | 用于片段分配 |
tiled_mma.make_fragment_A(tensor) | 创建 A 片段 | 寄存器分配 |
tiled_mma.make_fragment_B(tensor) | 创建 B 片段 | 寄存器分配 |
tiled_mma.make_fragment_C(shape) | 创建 C 片段 | 寄存器分配 |
cute.gemm(tiled_mma, d, a, b, c) | 执行 MMA:d = a @ b + c | 分派到硬件 MMA |
复制和 TMA 操作
| API | 用途 | 备注 |
|---|---|---|
cute.make_tiled_copy(atom) | 创建分块复制 | 用于批量数据移动 |
cute.copy(atom, src, dst, **kw) | 执行复制 | tma_bar_ptr=、mcast_mask= |
cute.basic_copy(src, dst) | 逐元素复制 | 无需 atom |
cute.prefetch(atom, src) | 预取 TMA 描述符 | — |
cute.nvgpu.make_tiled_tma_atom_A(op, tensor, smem_layout, tile, mma) | 为 A 创建 TMA atom | 仅主机端 |
cute.nvgpu.make_tiled_tma_atom_B(op, tensor, smem_layout, tile, mma) | 为 B 创建 TMA atom | 仅主机端 |
共享内存
| API | 用途 |
|---|---|
cutlass.utils.SmemAllocator() | 创建 SMEM 分配器 |
smem.allocate_tensor(dtype, layout, align, swizzle) | 在 SMEM 中分配张量 |
smem.allocate(struct_type) | 在 SMEM 中分配结构体 |
张量内存(仅限 SM100)
| API | 用途 |
|---|---|
cutlass.utils.TmemAllocator(...) | 创建 TMEM 分配器 |
tmem.allocate(num_cols) | 分配列 |
tmem.wait_for_alloc() | 等待分配完成 |
tmem.retrieve_ptr(dtype) | 获取指针 |
tmem.free(ptr) | 释放内存 |
同步
| API | 用途 |
|---|---|
cute.arch.mbar.init(barrier_ptr, count) | 初始化屏障 |
cute.arch.mbar.arrive(barrier_ptr) | 到达屏障 |
cute.arch.mbar.wait(barrier_ptr, phase) | 等待屏障 |
cute.arch.mbar.arrive_and_expect_tx(barrier_ptr, bytes) | 到达屏障并指定预期的 TX 字节数 |
cute.arch.mbar.try_wait(barrier_ptr, phase) | 非阻塞等待 |
| Pipeline classes (see references) | 多阶段异步流水线 |
数学函数(对 TensorSSA 逐元素运算)
| API | 用途 | API | 用途 |
|---|---|---|---|
cute.exp(x) | e^x | cute.exp2(x) | 2^x |
cute.log(x) | ln(x) | cute.log2(x) | log2(x) |
cute.sqrt(x) | sqrt | cute.rsqrt(x) | 1/sqrt(x) |
cute.sin(x) | sin | cute.cos(x) | cos |
cute.tanh(x) | tanh | cute.erf(x) | erf |
所有数学函数都支持 fastmath=True,以使用近似硬件内建函数。
Tensor Operations
| API | 用途 |
|---|---|
cute.full(shape, val, dtype) | 填充指定值 |
cute.zeros_like(tensor) | 创建与张量形状相同的零张量 |
cute.where(cond, x, y) | 条件选择 |
cute.any_(tensor) | 逻辑任一 |
cute.all_(tensor) | 逻辑全部 |
调试
| API | 用途 |
|---|---|
cute.printf(fmt, ...) | 设备端 printf |
cute.print_tensor(tensor) | 打印张量内容 |
print(...) | 编译时打印(仅限元阶段) |
关键约束
-
@cute.kernel函数名必须与模块文件名一致——与 cuTile 的规则相同 -
TMA 描述符仅限主机端使用——在
@cute.jit中创建,并传递给@cute.kernel -
寄存器预算:每线程最多 255 个——根据
docs/devices/规格进行验证 -
SMEM 限制因设备和 SM 版本而异——SM100(B200/B300):228 KB/SM,227 KB/块(选择启用);SM120(RTX 5090):96 KB
-
流水线阶段会占用 SMEM——每个阶段都需要自己的缓冲区;请验证总量
-
屏障同步错误不会显式报错——会导致结果错误,而非程序崩溃;务必使用
--check进行测试 -
集群维度必须与网格兼容——集群形状必须能整除网格
-
print()仅用于编译时打印——设备端输出请使用cute.printf() -
循环中不支持提前退出——请改用谓词控制
-
32 位布局代数——形状/步长限制为 32 位整数
-
架构支持:Ampere(SM80)及以上;SM100(B200/B300)支持包括
tcgen05和 TMEM 在内的全部功能 -
特定架构的内核:部分内核面向特定 SM 版本(例如,
tcgen05MMA 操作要求 SM100,而非笼统的“Blackwell”)。Blackwell 这一营销名称涵盖多个 SM 版本,它们具有不同的指令集:- SM100(B200、B300)——数据中心 GPU,支持
tcgen05MMA、TMEM 和完整的集群功能 - SM120(GeForce RTX 5090、RTX 5080)——消费级 Blackwell,使用
sm_120a,不支持tcgen05操作
运行、编译或分析性能前,务必检查设备:
nvidia-smi --query-gpu=name --format=csv,noheader。然后与内核的目标 SM 版本进行匹配——仅凭 GPU 名称并不足够;你必须了解它对应的 SM 版本。如果 SM 版本不匹配,请跳过运行/性能分析步骤,不要尝试执行,以免失败或产生误导性结果。 - SM100(B200、B300)——数据中心 GPU,支持
控制流
| 构造 | 行为 | 备注 |
|---|---|---|
for i in range(N) | 如果 N 是静态值,则展开循环 | 标准 Python range |
for i in cutlass.range(N) | 运行时循环 | 生成 MLIR 循环 |
for i in cutlass.range_constexpr(N) | 编译时展开循环 | N 必须是静态值 |
if cutlass.const_expr(cond) | 编译时分支 | 在编译时消除 |
if cond | 运行时分支 | 两个分支都必须通过类型检查 |
Blackwell 数据中心 MMA 操作(tcgen05)——仅限 SM100
需要 SM100。
tcgen05操作仅适用于 B200/B300(SM100)。消费级 Blackwell GPU(如 RTX 5090(SM120/sm_120a))不支持这些操作。
from cutlass.cute.nvgpu import tcgen05
# Create MMA operation for SM100 (B200/B300) tensor cores
op = tcgen05.MmaF16BF16Op(
dtype=cutlass.Float16, # Input type
acc_dtype=cutlass.Float32, # Accumulator type
shape=(128, 128, 64), # M x N x K tile shape
cta_group=tcgen05.CtaGroup.ONE, # ONE or TWO CTAs
)
tiled_mma = cute.make_tiled_mma(op)
| 操作 | 输入类型 | 形状 |
|---|---|---|
MmaF16BF16Op | FP16/BF16 → FP32 | 各种 M×N×K |
MmaF8F6F4Op | FP8/FP6/FP4 → FP32 | 窄精度 |
| 分块缩放变体 | 使用缩放因子 | 参见示例 |
常见模式
使用 TMA 流水线的 GEMM(简化版)
@cute.kernel
def gemm_kernel(tiled_mma, tma_a, tma_b, smem_a, smem_b, gmem_c, ...):
tidx, _, _ = cute.arch.thread_idx()
bidx, bidy, _ = cute.arch.block_idx()
# Get thread's MMA partition
thr_mma = tiled_mma.get_slice(tidx)
# Allocate accumulator in registers
acc = tiled_mma.partition_shape_C(tile_shape)
tCrC = cute.make_fragment(acc, cutlass.Float32)
# K-loop with TMA pipeline
for k_tile in range(num_k_tiles):
# TMA copy: global → shared (async)
cute.copy(tma_a, gA_tile, sA_tile, tma_bar_ptr=barrier)
cute.copy(tma_b, gB_tile, sB_tile, tma_bar_ptr=barrier)
# Wait for TMA to complete
cute.arch.mbar.wait(barrier, phase)
# Partition shared memory for this thread
tCsA = thr_mma.partition_A(sA)
tCsB = thr_mma.partition_B(sB)
# MMA: accumulate into registers
cute.gemm(tiled_mma, tCrC, tCsA, tCsB, tCrC)
# Epilogue: write back to global memory
cute.basic_copy(tCrC, gC_partition)
Warpgroup 专项化(生产者/消费者)
warp_idx = cute.arch.warp_idx()
is_producer = warp_idx < num_producer_warps
if is_producer:
# Issue TMA copies for upcoming pipeline stages
for stage in range(num_stages):
cute.copy(tma_atom, src, dst, tma_bar_ptr=barriers[stage])
cute.arch.mbar.arrive_and_expect_tx(barriers[stage], bytes_per_stage)
else:
# Consume data from shared memory, execute MMA
for stage in range(num_stages):
cute.arch.mbar.wait(barriers[stage], phase)
cute.gemm(tiled_mma, acc, sA_stage, sB_stage, acc)
持久化内核循环
@cute.kernel
def persistent_kernel(tiled_mma, num_tiles, ...):
bidx, _, _ = cute.arch.block_idx()
num_blocks = cute.arch.grid_dim()[0]
tile_id = bidx
while tile_id < num_tiles:
# Process tile
# ... TMA copy, MMA, epilogue ...
tile_id += num_blocks
详细参考
- 架构操作(线程索引、TMA、MMA 原子操作、屏障、SMEM/TMEM):参见 references/architecture-ops.md
- 官方文档索引:参见 references/docs-index.md
- 示例内核:参见
/learn-cute-dsl技能,查看按类别整理的示例源码索引