NVIDIA 在 2026 年 9 月发布 CUDA Rust,让 GPU 内核可以直接用 Rust 编写并原生编译到 PTX。它给出两条路线,cuda-oxide 面向线程级并行,cutile-rs 面向数据块级并行,后者已经发布到 crates.io,被 HuggingFace 的推理引擎和 mistral.rs 采用。官方明确说明两个项目都处于早期阶段,还没有达到生产可用,API 会继续变化。写 GPU 算子的团队现在值得跟踪,暂时别放进生产计划。
CUDA Rust 是什么
过去在 Rust 里调用 GPU,内核通常用另一种语言写,Rust 侧通过 FFI 启动。CUDA Rust 要补上的是这段缺口,内核用 Rust 写,编译链直接产出 PTX,中间没有包装层。
两个项目的分工不同。cuda-oxide 的编译链先把 Rust MIR 转进 Pliron 这个 IR 框架,再走 LLVM 生成 PTX,每个线程处理标量数据。cutile-rs 把数据块当作计算单位,一个 tile block 对应一个逻辑线程,线程映射和内存布局交给编译器,首次使用时通过 CUDA Tile IR 做即时编译。
Rust 写内核的好处落在编译期
数据竞争和越界是 GPU 编程最常见的两类错误,往往在运行很久之后才暴露。Rust 的类型系统把这两类问题前移。cuda-oxide 用 DisjointSlice 把一次可变借用拆成每线程一份,启动配置还要通过 launch contract 校验,配置与设备实际限制不符时会被拦下。cutile-rs 让所有权跟着张量跨过启动边界,编译器保证每个分区的独占访问。
演示代码能看出机制的实际效果。SIMT 版本故意制造借用冲突,编译器直接报 E0502。Tile 版本重复使用已移动的值,报 E0382。同类错误写在 C++ 内核里,通常要等运行时才以未定义行为的形式出现。
两条路线怎么选
官方建议先看 Tile 路线。满足这几个条件就用它。
- 算子可以按数据块表达,比如矩阵乘、归一化、逐元素运算。
- 希望线程映射和内存布局由编译器管理。
- 环境是稳定版 Rust 1.89 以上,CUDA 13.3。
需要手动管理线程和共享内存时,再换到 SIMT 路线。它的门槛更高,要用固定版本的 nightly 工具链,共享内存访问目前仍要写 unsafe。
最小例子与运行门槛
两条路线的入门示例是同一道题,1024 个 float 逐元素相加。SIMT 版本启动 4 个 block、每个 256 线程,不使用动态共享内存。Tile 版本把数据切成 128 元素的块,共 8 个 tile,内核执行是惰性的,调用 sync_on 之后才开始跑。
SIMT 路线把设备端和主机端分成三个 crate,设备侧代码和启动逻辑分开写,线程编号通过 index_1d 取,缓冲区在主机与设备之间搬运有对应的方法。启动配置除了算 block 和线程数,还要过一遍启动契约校验,把配置和设备实时限制对一遍,不匹配就直接失败,不会带着错误配置跑出一堆难查的结果。
Tile 路线用宏把内核代码嵌进宿主二进制,库里现成的 ones、zeros 这类初始化接口可以直接用,张量形状里的负一是占位符,实际维度在启动时决定。写完不用手动同步,所有计算挂在流上,直到调用同步方法才执行。
工具链方面,Tile 路线用稳定版 Rust 1.89 以上加 CUDA 13.3 就行,不需要 nightly。SIMT 路线绑定一个固定日期的 nightly 工具链,官方在文档里也提到这是希望能省掉的约束。命令行工具提供新建项目、环境自检、运行三个子命令,环境自检会把工具链和驱动问题先找出来。
硬件门槛两边一致,GPU 计算能力 8.0 以上。
现阶段的限制
两个项目都不适合放进生产计划。cuda-oxide 还是早期 alpha,覆盖范围不完整,共享内存的安全化仍在开发中。cutile-rs 成熟一些,功能覆盖面同样会变。SIMT 项目第一次运行时先编译 codegen 后端,构建耗时明显更长。跨语言互操作,也就是 CUDA Rust 与 CUDA C++、CUDA Python 混编的能力,还在规划里。
常见问题
- 现在能把 CUDA C++ 内核迁到 Rust 吗。小算子可以试,大型内核库建议等 API 稳定,两个项目都会做破坏性变更。
- 不写 CUDA 的团队需要关注吗。做推理、训练框架和算子库的团队值得跟踪,应用层开发短期不受影响。
- 两个项目选哪个起步。跟着官方建议,先 Tile 再 SIMT,写起来省事的程度差别很大。