Nvidia announces native GPU programming in Rust
NVIDIA, Rust로 GPU 커널을 직접 작성하는 CUDA Rust 공개 — SIMT와 Tile 두 트랙
NVIDIA가 Rust로 GPU 커널을 네이티브하게 작성해 PTX로 컴파일하는 CUDA Rust를 발표했습니다. SIMT 모델의 cuda-oxide와 Tile 모델의 cutile-rs 두 트랙으로 제공되며, Rust의 소유권·빌림 검사로 GPU 커널의 메모리 안전성을 컴파일 타임에 보장하는 것이 핵심입니다.
- 주제
본문
NVIDIA가 Rust로 GPU 커널을 직접 작성할 수 있는 CUDA Rust를 발표했습니다. 지금까지 Rust에서 커널을 '실행'하는 것은 가능했지만 커널 자체는 다른 언어로 작성해야 했는데, 이번 발표는 그 간극을 메우는 것을 목표로 합니다. CUDA C++와 CUDA Python은 성숙한 엔터프라이즈급 툴체인으로 유지되고, CUDA Rust는 2027년 이후까지 성장·성숙시켜 나간다는 방향입니다.
배경에는 AI 시스템 계층의 Rust 전환이 있습니다. 추론 엔진, 서빙 인프라, 드라이버, 에이전트 런타임 등은 모델과 기법 변화에 따라 끊임없이 바뀌는데, Rust는 성능 손실 없이 컴파일 타임에 버그 계열을 걸러내기 때문에 이 계층에서 채택이 늘고 있습니다. NVIDIA 자신도 Linux 드라이버 Nova를 Rust로 작성했고, NVIDIA Dynamo는 Rust 코어 위에 구축됐으며 NVTX도 Rust 바인딩을 제공합니다.
두 가지 트랙: SIMT와 Tile
CUDA Rust는 CUDA 자체의 두 프로그래밍 모델에 대응하는 두 트랙을 제공합니다. 첫째는 SIMT 트랙으로, CUDA C++나 numba-cuda에서 쓰는 기존 모델입니다. 한 스레드가 무엇을 하는지 기술하고 수천 개를 실행하는 방식입니다. 둘째는 Tile 트랙으로, C++와 Python에서도 제공되는 새로운 프로그래밍 모델입니다. 데이터 타일 하나가 무엇을 하는지 기술하면 Tile IR 컴파일러가 나머지를 결정합니다. NVIDIA는 기본적으로 Tile을 먼저 선택하고, 메모리와 스레드를 직접 제어해야 할 때 SIMT로 내려가라고 권합니다. 타일이 각 아키텍처에 어떻게 매핑될지를 컴파일러가 결정하므로 소스에 아키텍처 종속 선택이 새겨지지 않기 때문입니다. 언어 선택과 모델 선택은 별개의 문제이며, 언어 간 상호운용도 지원할 계획이라고 밝혔습니다.
cuda-oxide: SIMT 트랙
cuda-oxide는 커스텀 rustc 코드젠 백엔드입니다. 컴파일을 가로채 #[kernel] 함수를 Rust MIR, 커뮤니티의 Pliron IR 프레임워크, LLVM IR을 거쳐 PTX로 내리고, 나머지는 표준 백엔드에 넘깁니다. Pliron 위의 GPU dialect는 NVIDIA가 만들었고, 표준 LLVM 백엔드가 인계받기 전까지 모든 dialect와 변환이 Rust 안에 머뭅니다. Linux, compute capability 8.0 이상 GPU, CUDA toolkit 12.x 이상, clang과 libclang 헤더, 고정된 nightly 툴체인이 필요하며 cargo oxide doctor가 환경을 점검합니다. cargo +nightly-2026-04-03 install로 cargo-oxide를 설치한 뒤 cargo oxide new로 프로젝트를 생성하고 cargo oxide run으로 실행할 수 있습니다.
예제 커널은 1,024개 float에 대한 elementwise 덧셈입니다. 안전성 논증은 커널 시그니처에 담겨 있습니다. 입력 a와 b는 모든 스레드가 읽을 수 있는 공유 슬라이스이고, 출력 c는 DisjointSlice<f32>라는 특수 타입입니다. 모든 스레드가 동일한 &mut을 필요로 하면 Rust가 거부하므로, DisjointSlice가 하나의 가변 빌림을 스레드별 조각으로 분할해 각 스레드에 자기 원소에 대한 배타적 접근만 줍니다. thread::index_1d()는 벌거숭이 정수가 아닌 인덱스 타입을 반환하고, c.get_mut(idx)는 그 타입만 받아 Option을 반환하므로 경계 초과는 나중에 발견하는 메모리 오류가 아니라 처리해야 하는 분기가 됩니다. #[launch_contract]가 1차원 인덱싱과 256 스레드 블록을 선언하면 prepare_vecadd가 LaunchConfig1D를 선언 및 실제 디바이스 한계와 대조해 검증하고, 안전한 vecadd 메서드가 요구하는 증명 토큰을 돌려줍니다. 계약이 없는 커널은 unsafe한 raw 런치 메서드만 노출됩니다.
cutile-rs: Tile 트랙
cutile-rs는 한 수준 위에서 동작합니다. 스칼라가 아닌 타일 단위로 연산하며, 각 타일 블록은 하나의 서브 텐서 위에서 커널 본문을 단일 논리 스레드로 한 번 실행하고 실제 GPU 스레드 수는 컴파일러가 정합니다. #[cutile::module] 매크로가 커널 AST를 호스트 바이너리에 내장하고, 처음 필요할 때 CUDA Tile IR을 통해 JIT 컴파일합니다. 요구사항도 가볍습니다. compute capability 8.0 이상, CUDA 13.3, stable Rust 1.89 이상, Linux면 되고 nightly나 자체 LLVM이 필요 없습니다. crates.io에 공개돼 있어 cargo add cutile로 바로 쓸 수 있습니다.
Tile 예제의 흥미로운 지점은 호스트 측 .partition([128])입니다. 이 호출 하나가 세 가지 일을 합니다. 각 타일에 128개 원소 청크에 대한 배타적 소유권을 부여하고, 1,024/128로 그리드 8개를 고정하며, 호출부에 쓰지 않아도 되는 타일 폭 B를 공급합니다. 그래서 &mut 출력은 partition을 거치지 않으면 아예 전달할 수 없습니다. 커널의 -1 차원은 크기가 아닌 센티널로, 런치 시 텐서에서 읽히므로 재컴파일 없이 shape를 바꿀 수 있습니다. 런처는 세 텐서의 소유권을 받아 GPU 작업이 끝나면 튜플로 돌려주며, .first()로 출력을 꺼냅니다. .sync_on(&stream)까지는 커널 호출과 호스트 복사를 포함해 전부 지연된 기술(description)일 뿐 실제로는 아무것도 실행되지 않습니다.
컴파일 타임 안전성과 한계
두 트랙 모두 고전적인 에일리어싱 실수를 컴파일 타임에 잡습니다. SIMT에서 출력 버퍼를 입력으로 넘기면 E0502(가변·불변 빌림 충돌)가, Tile에서 같은 텐서를 두 번 쓰면 E0382(이동된 값 사용)가 발생합니다. 수천 스레드가 순서 보장 없이 같은 버퍼에 접근할 때 발생하는 데이터 레이스는 재현이 어렵고 테스트를 통과한 뒤 프로덕션에서 터지는데, 이를 타입으로 차단하는 것이 핵심 가치입니다. Tile은 공유 메모리와 스레드 인덱싱 자체가 없어 구조적으로 안전하지만 그만큼 제어권을 잃습니다. SIMT는 제어를 유지하되 현재 공유 메모리 사용에는 unsafe가 필요하며, 빠른 SIMT 커널의 근간인 공유 메모리 경로를 안전하게 만드는 것이 진행 중인 과제입니다.
두 프로젝트 모두 초기 단계로 프로덕션 준비는 안 됐습니다. cuda-oxide는 얼리 알파이고, cutile-rs는 더 진행돼 crates.io에 공개됐으며 HuggingFace의 Grout 추론 엔진과 mistral.rs에서 이미 사용 중입니다. NVIDIA는 rust-cuda, Rust-GPU, cudarc, CubeCL 등 선행 작업과 VectorWare 팀을 명시적으로 언급하며, rust-cuda 메인테이너들과 협력 중이라고 밝혔습니다. RustConf 2026(9월 8~11일, 몬트리올)에서 Melih Elibol이 'Fearless Concurrency on the GPU'를 발표할 예정입니다.
Hacker News 반응
- @the__alchemist — 안정화되면 써보고 싶습니다. 현재 그래픽스에는 WGPU, CUDA에는 cudarc를 쓰고 있습니다. cuda-oxide는 cudarc의 호스트 구성 요소와 비슷하지만 Rust 스타일 커널 dialect를 씁니다. 장점은 호스트와 디바이스가 구조체를 공유한다는 것이고, 단점은 표준 CUDA 커널 대신 새로운 WIP dialect와 맞바꾼다는 점입니다. 마지막으로 확인했을 때 cuda-oxide는 Linux 전용이고 Async가 필요했는데, 이것들이 아직 안 써본 이유입니다.
- @embedding-shape — cudarc는 기존 예제와 레퍼런스를 찾기 쉽고 1대1로 매핑돼서 좋았습니다. 이미 CUDA 자체만으로도 힘든데 dialect가 얹히면 기존 작업에 의존하기가 조금 더 어려워집니다. 다만 두 접근 모두 cudarc보다 인체공학적이고 빌드 인프라와 환경 설정이 적다는 점은 좋아 보입니다.
- @dllu — NVIDIA가 HuggingFace를 소유하게 됐고 HuggingFace에는 Rust 추론용으로 훌륭한 Candle 크레이트가 있으니, 이건 네이티브 Rust 커널을 향한 좋은 진전으로 보입니다.
- @jacobgorm — 커널이 Rust로 작성되는지는 아무도 신경 쓰지 않습니다. 커널은 원래 C로 쓰는 것이고, 더 고수준을 원하면 타일 크기 등을 깔끔하게 추상화하는 Triton 같은 DSL을 쓰면 됩니다.
- @cpill — 이러다가 AI와 게임 개발에서 C++의 지배가 무너지겠네요.
원문: NVIDIA Developer Blog / 번역·요약: Trawling