gpumode · 강의 아카이브
《GPU Mode》 L086 2025 High priority transcript · failed

Getting Started with CuTe DSL — Python 으로 만나는 CuTe

CUTLASS C++ 의 핵심인 CuTe (layout 과 tensor 의 algebra) 를 파이썬에서 직접 다루는 DSL. 같은 shape, stride, layout, tile, copy 의 개념을 C++ 보일러플레이트 없이 만지고, 결국에는 PTX/SASS 까지 — 같은 백엔드로 — 내려간다. NVIDIA 의 Vicki Wang 이 깐 CuTe Python DSL 의 첫 진입점, layout algebra 의 직관, GEMM 작성 시퀀스, 그리고 Triton 과의 경계까지 — slides PDF 와 도메인 지식으로 재구성한 학습 노트.

CuTe Python DSL CUTLASS layout algebra Tensor Core GEMM PTX
V
Speaker
Vicki Wang
NVIDIA · CUTLASS / CuTe DSL 팀
강의 번호
L086
스피커
Vicki Wang
학습 우선순위
High · 정독
자막
failed · slides 있음
§ 01강의가 풀려는 문제· why CuTe DSL

“CUTLASS 한 번이라도 본 사람” 의 진입 장벽을 한 단계 낮춘다

CUTLASS 는 NVIDIA 의 production GEMM/Conv 라이브러리. 그 안의 CuTe 가 layout 과 tile 의 algebra 를 표현하는 핵심 추상이다. 그러나 CuTe 는 C++ template으로 짜여 있고 — 한 번 코드를 펼친 사람이라면 안다 — 진입 장벽이 매우 높다. 이 강의는 CuTe 의 같은 추상을 파이썬으로 직접 만지는 새 DSL 을 깐다.

NVIDIA 가 CuTe Python DSL 을 만든 의도는 — 외부에 공개된 자료 흐름에서 — 세 갈래로 모인다.

  1. CUTLASS 의 표현력은 살리고 진입 장벽은 낮춘다 — 같은 layout algebra 를 Python 에서 만지고, 빠른 iteration 가능.
  2. Triton 이 못 다루는 자리 — Triton 은 사용자에게 layout 을 직접 노출하지 않는다. CuTe DSL 은 layout 의 모든 비트를 노출한다 — Tensor Core 의 mma 명령에 정확히 맞추는 자리에서 가치.
  3. 새 hardware 의 빠른 채택 — Hopper 의 TMA, Blackwell 의 새 tensor memory accelerator 같은 새 명령은 CuTe 차원에서 가장 먼저 노출. DSL 이 같이 빨리 따라가야 산업이 받아쓸 수 있다.
자료 한계 · 확인 필요

강의 자막은 실패. 슬라이드 PDF (lecture_086/cute_dsl_introduce.pdf) 가 repo 에 있어 큰 흐름 재구성 가능. 정확한 API 이름 / 코드 예시는 NVIDIA 의 공식 문서 (CUTLASS Python README, CuTe DSL Programming Guide) 와 도메인 지식 기반.

“CuTe 의 layout algebra 는 강력하다 — 단지 C++ template 안에 있어서 만지기 어려웠을 뿐. Python 표면이 그 거리를 좁힌다.”강의 재구성
§ 02CUTLASS C++ 의 진입 장벽· why Python wrapping

왜 Python DSL 인가

CUTLASS C++ 코드를 한 번이라도 펼친 사람이라면 — 진입의 어려움이 어디서 오는지 안다. 그 어려움을 명시화한다.

deep template
한 GEMM 이 수십 개의 template parameter. 컴파일 에러가 줄줄이. using GemmT = cutlass::gemm::device::Gemm<...10 parameters...>; 같은 식.
긴 컴파일 시간
한 번 코드 바꾸면 nvcc 가 수 분 단위 컴파일. iteration 가 매우 느림.
디버깅 어려움
printf 가 안 되고, 컴파일 타임에 모든 게 결정되어 — 변수의 모양을 사람이 머리에 들어야 함.
학습 곡선
CuTe 의 layout 추상 자체가 새로움 (L103 의 layout algebra). 그 위에 C++ template 의 비용 — 두 번 막힌다.
PyTorch 통합 비용
CUTLASS 커널을 PyTorch 에 통합하려면 pybind / load_inline / setup.py. L001 의 load_inline 이 그 자리.
Triton 의 우회
대부분의 사용자가 “직접 CuTe 짜지 말고 Triton 으로 가자” 의 우회. 그러나 Tensor Core 의 정확한 layout 통제가 필요한 자리에서는 한계.

CuTe Python DSL 의 답 — 같은 추상을 그대로 Python 에 노출. C++ template 의 deep nesting 없이, 같은 layout / tensor / copy / mma 를 Python 객체로 직접 만지고, 컴파일은 즉시 (JIT) 도는 형태.

JIT 의 자리

CuTe DSL 의 lowering 은 Python → MLIR (또는 CuTe IR) → PTX. JIT 라 컴파일 시간이 한 함수당 초 단위. C++ 의 분 단위와 비교 불가. 빠른 iteration 의 가장 큰 가치.

§ 03CuTe Python DSL 의 추상· layout · tensor · copy · MMA

네 가지 핵심 객체

CuTe 의 추상은 — C++ 이든 Python 이든 — 네 가지 객체에 모인다. 이 넷의 의미를 한 번 박아두면 나머지가 펼쳐진다.

Layout
Layout = Shape × Stridetensor 의 인덱스 → 메모리 주소
a Layout 은 단순히 “이 텐서의 어떤 (i,j) 가 메모리의 어느 offset 에 있는가” 의 함수. CuTe 의 모든 magic 은 이 함수 자체를 1급 객체로 다룬다는 데서 옴. 예: Layout(Shape(M,N), Stride(N,1)) 은 row-major M×N 텐서.
Tensor
Tensor = pointer + Layout실제 데이터 + 그 모양
PyTorch tensor 와 같은 의미. Tensor(ptr, layout). 차이는 — CuTe 의 Tensor 는 메모리 위치(GMEM, SMEM, RMEM) 를 type 차원에서 들고 있다. Tensor<float, GMEM, ...> 같이.
Copy / TiledCopy
Copy한 layout → 다른 layout 의 복사
한 텐서를 다른 layout (다른 메모리, 다른 shape) 으로 복사하는 단위. 중요한 점 — 단순 memcpy 가 아니라 “이 thread 가 이 element 를 가져온다” 의 매핑을 layout algebra 로 표현. coalesced load, async copy, TMA 가 모두 이 한 추상 위.
MMA / TiledMMA
MMAmatrix-multiply-accumulate
Tensor Core 의 mma 명령 한 개의 추상. m16n8k16 같은 모양과 그에 맞는 layout 이 함께 정의됨. TiledMMA 는 이 한 명령을 여러 thread / warp 에 분배하는 layout 매핑.

이 네 객체로 한 GEMM 의 추상이 거의 다 표현된다 — “G/S/R memory 의 layout 들이 있고, 그 사이를 copy 가 stage 하고, 마지막에 MMA 가 누적” 의 그림.

“CuTe 는 layout 을 1급 객체로 다루는 첫 시도다. 같은 layout 표현이 source / target / thread 매핑에 다 쓰인다.”CUTLASS 문서 · 재구성
§ 04layout algebra· shape · stride pictogram

(Shape, Stride) 의 그림 — 한 번 보면 다음에 다 펼쳐진다

CuTe 의 가장 큰 진입 장벽이자 가치 — layout algebra. 한 번 직관이 잡히면 같은 표기로 row-major, column-major, transposed, swizzled, blocked 가 모두 표현된다.

FIG · row-major 4×4 텐서Shape=(4,4), Stride=(4,1)
0
1
2
3
4
5
6
7
4
5
6
7
8
9
10
11
8
9
10
11
12
13
14
15
12
13
14
15
왼쪽 4×4 가 텐서. 셀 안의 숫자 = 메모리 offset. (i,j) 의 offset = i·stride[0] + j·stride[1] = i·4 + j·1. row 가 row-major 의 기본.
FIG · column-major 4×4 (transpose 효과)Shape=(4,4), Stride=(1,4)
0
4
8
12
1
5
9
13
2
6
10
14
3
7
11
15
같은 데이터, 다른 stride. Stride=(1,4) 면 (i,j) → i + j·4. 같은 메모리에 다른 layout 을 씌우는 것이 transpose — 데이터 이동 없음. CuTe 의 가장 강력한 추상 중 하나.
FIG · 2×2 block 단위 layout (4×4)Shape=((2,2),(2,2)), Stride=((2,8),(1,4))
0
1
4
5
2
3
6
7
8
9
12
13
10
11
14
15
tile 안에서는 row-major, tile 사이는 row-major-of-tiles. nested Shape 와 Stride 로 hierarchical layout 을 표현 — 이게 CuTe 의 본업이고, Triton 이 안 노출하는 자리.
layout algebra 의 연산

두 layout 의 합성 (composition), 분해 (compose / divide), tile 추출 (logical_divide), thread 분배 (zipped_divide) 등이 모두 정의된 algebra. L103 이 이 algebra 의 category-theoretic 해석을 깐다 — 같은 그림이 더 깊게 펼쳐진다.

§ 05예시: GEMM 작성· end-to-end

한 GEMM 을 CuTe Python DSL 로 짠다

강의의 핵심 데모가 정확히 이 자리. 같은 GEMM 을 — Triton 도 아니고 CUTLASS C++ 도 아니고 — CuTe Python DSL 로 짜는 시퀀스. 외부 자료로 재구성한 개념적 형태.

CUTLASS C++ (개념적 형태)
// 깊은 template 의 한 예
using GemmKernel = cutlass::gemm::collective::CollectiveBuilder<
  cutlass::arch::Sm90,
  cutlass::arch::OpClassTensorOp,
  cutlass::half_t, LayoutA, AlignmentA,
  cutlass::half_t, LayoutB, AlignmentB,
  ElementAccumulator,
  TileShape, ClusterShape,
  cutlass::gemm::collective::StageCountAuto,
  cutlass::gemm::collective::KernelScheduleAuto
>::CollectiveOp;

// 이걸 device::Gemm 에 한 번 더 wrap 하고...
// 메인 함수에서 args, workspace, smem 사이즈 까지 직접 셋업
CuTe Python DSL (개념적 형태 · 확인 필요)
import cutlass.cute as cute

@cute.kernel
def gemm(A, B, C,
         tA: cute.TiledCopy,
         tB: cute.TiledCopy,
         tC: cute.TiledMMA):
    bid_m = cute.block_idx(0)
    bid_n = cute.block_idx(1)

    # tile 추출 — layout algebra 로
    gA = cute.local_tile(A, (BM, BK), (bid_m, _))
    gB = cute.local_tile(B, (BN, BK), (bid_n, _))
    gC = cute.local_tile(C, (BM, BN), (bid_m, bid_n))

    sA = cute.make_smem_tensor(BM, BK)
    sB = cute.make_smem_tensor(BN, BK)
    rC = cute.make_reg_tensor(BM, BN)

    for k in range(K // BK):
        cute.copy(tA, gA[:,:,k], sA)
        cute.copy(tB, gB[:,:,k], sB)
        cute.cp_async_wait()
        cute.gemm(tC, sA, sB, rC)

    cute.copy(tC, rC, gC)

두 코드의 의도는 같다 — Hopper Tensor Core 위에서 fp16 GEMM 을 짜는 일. 차이는 표현의 두께. CuTe Python 은 같은 추상 (TiledCopy, TiledMMA, local_tile, copy) 을 명시적으로 다루지만 — template 의 깊이가 사라지고, JIT 로 빠르게 컴파일된다.

FIG · GEMM 의 tile 분해 그림(BM, BN, BK) 와 메모리 위치
A: GMEM   M × K   ──tA──▶  sA: SMEM    BM × BK
B: GMEM   N × K   ──tB──▶  sB: SMEM    BN × BK
                              │
                              ▼
                         tC (TiledMMA)
                              │
                              ▼
                         rC: RMEM   BM × BN
                              │
                              └──tC──▶ C: GMEM   BM × BN
G(global) → S(shared) → R(register) → S → G 의 표준 GEMM 흐름. tA, tB, tC 가 layout 매핑(어떤 thread 가 어떤 element 를 책임). 이 매핑이 정확하지 않으면 mma 명령이 안 받는다.
§ 06PTX/SASS 까지의 길· lowering

CuTe Python 의 lowering 파이프라인

FIG · CuTe Python DSL lowering4 stages
L0 CuTe Python DSL@cute.kernel · TiledCopy · TiledMMA · layout algebra 사용자가 짜는 자리
L1 CuTe IRlayout algebra 가 1급으로 보존 중간 표현
L2 MLIR / NVGPU dialectlayout 이 thread / warp 매핑으로 lowering 메모리 / 동기화 결정
L3 PTXmma.sync, ldmatrix, cp.async, TMA 명령 virtual ISA
L4 SASSarch 별 머신 코드 — sm_90, sm_100 실제 SM 위에서 도는 명령
L1–L2 의 통과가 가장 비싼 자리 — layout algebra 의 의미를 thread mapping 으로 풀어내는 단계. CUTLASS C++ 와 같은 백엔드(같은 PTX)를 생성하는 게 디자인 원칙.

중요한 사실 한 가지 — CuTe Python DSL 이 만드는 PTX 는 CUTLASS C++ 가 만드는 PTX 와 같은 quality를 목표로 한다. 표면(C++ vs Python) 만 다르고, 깎은 결과는 같다는 게 디자인 의도. 그래서 production 에서 “Python DSL 로 짰는데 더 느리다” 같은 의외 없음.

debugging tools

각 lowering 단계의 IR 을 직접 dump 가능 (확인 필요 — CUTE_LOG_LEVEL 같은 환경변수). 학습 자료로도 가치 — 자기 코드가 어떤 PTX 명령으로 내려가는지 직접 본다.

§ 07Triton 과 비교· where CuTe wins

같은 GEMM, 다른 표현 — 언제 어느 쪽인가

Triton 이 더 적합한 자리
표준 fused 패턴 (attention 변형, RMSNorm fused, elementwise pipeline). 짧고 빠르게 짜는 자리.
CuTe DSL 이 더 적합한 자리
Tensor Core 의 layout 을 직접 깎아야 하는 자리. 새 mma 변형, 새 dtype, swizzle 의 직접 통제.
새 hardware 의 첫 노출
Hopper TMA, Blackwell tensor memory, 새 mma 명령은 보통 CUTLASS / CuTe 에 가장 먼저 노출. Triton 이 따라가는 데 시차.
표현력
CuTe 가 layout algebra 를 직접 노출. Triton 은 layout 을 컴파일러 결정으로 숨김. 통제력 vs 단순성의 trade-off.
학습 곡선
Triton 이 훨씬 쉬움. CuTe 는 layout algebra 자체가 큰 학습 부담.
production 기여
CUTLASS / CuTe 가 NVIDIA production GEMM 의 본가. Triton 은 사용자 측 빠른 prototyping. 두 자리가 다름.
의사결정 사다리 — 갱신

L001 의 사다리에 한 칸이 추가된다 — torch → Triton → CuTe DSL → CUTLASS C++ → 직접 PTX. NCU 가 “이 명령으로 mma 의 layout 이 안 맞는다” 같은 hint 를 주면 Triton 으로 안 잡히는 자리 — CuTe 로 내려간다.

§ 08채택· where it's used

현재 시점 CuTe DSL 이 자리잡은 곳

강의에서 Vicki 가 강조했을 입장 — CuTe DSL 은 Triton 의 대체가 아니라 보완. 두 도구가 사용자 표면 차원에서 같이 산다는 디자인.

“CuTe 의 가치는 일반 사용자가 매일 쓰는 데 있지 않다 — 새 hardware 의 새 명령을 가장 먼저 production 에 풀어내는 자리에 있다.”강의 재구성
§ 09다음· roadmap

CuTe Python DSL 의 다음 라운드

  1. Blackwell 의 새 명령 노출 — tensor memory accelerator, new mma 변형, FP4 mma. CuTe DSL 이 가장 먼저 받는 자리.
  2. autotune 통합 — layout / tile size 의 search 를 자동화. L082 Helion 의 흐름과 합쳐질 가능성.
  3. PyTorch 통합 — torch.compile 과의 자연스러운 결합. 사용자가 PyTorch 안에서 CuTe 커널을 부르고, autograd 가 자동.
  4. 비-NVIDIA backend확인 필요. 현재 NVIDIA only. AMD MI300 등 다른 hardware 로의 확장 가능성.
  5. 학습 자료 — layout algebra 의 진입 장벽을 낮추기 위한 시각화 도구, 인터랙티브 튜토리얼. L103 의 본격 카테고리이론적 해석도 같은 흐름.
§ 10기억할 메모· key takeaways

다시 열었을 때 5분 안에 손에 잡혀야 할 것

CuTe 의 위치
CUTLASS 의 layout / tensor / copy / mma 추상. Python DSL 은 같은 추상을 더 친숙한 표면으로.
Layout = Shape × Stride
tensor 의 인덱스 → 메모리 offset 의 함수. CuTe 의 magic 의 출발점. nested 가능 — hierarchical layout.
4 객체
Layout · Tensor · Copy/TiledCopy · MMA/TiledMMA. 이 넷으로 GEMM 의 추상이 거의 다.
layout algebra
composition, divide, zipped_divide. 같은 표기로 row-major / column-major / blocked / swizzled 다 표현.
GEMM 의 GSR 흐름
G(global) → S(shared) → R(register) → S → G. tA/tB/tC 가 thread → element 매핑.
lowering 5 stages
Python DSL → CuTe IR → MLIR → PTX → SASS. JIT 컴파일 — C++ 의 분 단위가 초 단위로.
Triton 과의 분담
Triton = 표준 fused 패턴. CuTe = layout 을 직접 깎는 자리. 보완 관계.
의사결정 사다리
torch → Triton → CuTe DSL → CUTLASS C++ → PTX. NCU 의 layout-related hint 가 trigger.

손에 새기기 — 실습 시퀀스

  1. layout 의 그림 직접 그리기 — 종이 위에 (Shape=(4,4), Stride=(4,1)) 와 (Shape=(4,4), Stride=(1,4)) 의 메모리 offset 을 모두 그려본다. transpose 가 데이터 이동 없이 가능한 이유 손에.
  2. nested layout — Shape=((2,2),(2,2)) 의 4×4 의 offset 을 그려본다. tile 단위 layout 의 직관.
  3. CUTLASS Python DSL 설치 + first kernel — 공식 README 의 hello world. JIT 컴파일 시간 직접 측정.
  4. simple GEMM — § 05 의 형태로 fp16 GEMM 한 번 짜기. cuBLAS baseline 과 시간 비교.
  5. 같은 GEMM 의 lowering dump — CuTe IR / MLIR / PTX 를 각각 dump 해본다. layout 이 어떻게 thread mapping 으로 lowering 되는지 추적.
§ 11다른 강의로 이어지는 길· connections

CuTe 의 자리에 등장하는 다른 강의들

§ 12열린 질문· open questions

다음에 다시 들었을 때 직접 검증해야 할 것들

검증 메모

이 노트는 슬라이드 PDF + 도메인 지식으로 재구성. 정확한 API, 정확한 lowering 경로, 정확한 사용 예시는 NVIDIA 의 공식 문서 (CUTLASS Python README, CuTe DSL Programming Guide) 에서 직접 확인. § 04 의 layout 그림은 row/column-major 의 일반적 정의로 정확하지만, hierarchical 형태의 정확한 표기는 CuTe 문서의 표기를 따라가야 한다.

← Lecture 085 Factorio Learning Environment Lecture 087 → Low Latency Communication Kernels with NVSHMEM