# Nvidia announces native GPU programming in Rust

> 来源：[HackerNews](https://developer.nvidia.com/blog/introducing-cuda-rust-two-tracks-for-writing-gpu-kernels/)

# Nvidia 宣布原生支持 Rust 编写 GPU 内核：CUDA Rust 的两条技术路线

## 背景与概述

长期以来，GPU 编程几乎等同于 CUDA C/C++。尽管 CUDA 生态在性能与工具链上极为成熟，但其语言绑定始终局限于 C、C++ 以及 Fortran 等传统系统语言。随着 Rust 在系统编程领域的快速崛起——尤其是在操作系统、嵌入式和高性能计算场景中的广泛应用——开发者社区对“用 Rust 写 GPU 内核”的呼声日益高涨。

过去，社区曾通过 `rust-cuda`、`cust`、`accel` 等第三方项目尝试打通 Rust 与 CUDA 之间的壁垒，但这些方案大多依赖非官方的 LLVM 后端或手写绑定，存在维护成本高、版本滞后、与官方工具链脱节等问题。Nvidia 此次在官方开发者博客上发布《Introducing CUDA Rust: Two Tracks for Writing GPU Kernels》，标志着 GPU 巨头正式将 Rust 纳入其原生编程语言版图。

这一动作的意义不仅在于多了一种语言选择，更在于它释放出一个明确信号：Rust 正在从“系统层”向“加速计算层”渗透，而 Nvidia 愿意为此提供官方支持。对于中国开发者而言，这意味着未来在 AI 基础设施、自动驾驶、科学计算等领域，可以用更安全、更现代的语言栈来编写高性能 GPU 代码。

## 核心内容

根据 Nvidia 官方博客的表述，CUDA Rust 并非单一方案，而是提供了两条并行的技术路线，分别面向不同的使用场景与成熟度需求。

### 路线一：`cuda-oxide`——基于 rustc 代码生成后端的原生集成

第一条路线名为 `cuda-oxide`，其核心思路是将 CUDA 的代码生成能力直接接入 Rust 编译器 `rustc` 的后端。开发者可以用纯 Rust 编写 GPU 内核，编译器在编译阶段将 Rust 的 MIR（中级中间表示）或 LLVM IR 转换为 PTX（Parallel Thread Execution）或 SASS，从而生成可在 Nvidia GPU 上执行的二进制代码。

这条路线追求的是“原生体验”：无需手写 C++ 胶水代码，类型系统、所有权模型和生命周期检查都能在内核代码中延续。它更适合追求长期可维护性和安全性的项目。

### 路线二：`cuda-bindings`——面向现有 CUDA 生态的 Rust 绑定

第二条路线是 `cuda-bindings`，它并不试图重新实现代码生成，而是为现有的 CUDA Runtime API、Driver API 以及部分库（如 cuBLAS、cuDNN）提供高质量的 Rust FFI 绑定。开发者仍然用 CUDA C++ 编写内核，但主机端（host）的调度、��存管理和错误处理可以用 Rust 完成。

这条路线成熟度更高、落地更快，适合那些已有大量 CUDA C++ 内核资产、但希望用 Rust 重构主机端逻辑的团队。

### 两条路线的定位差异

| 维度 | cuda-oxide | cuda-bindings |
|------|------------|---------------|
| 内核语言 | 纯 Rust | CUDA C++ |
| 成熟度 | 实验性/早期 | 相对成熟 |
| 迁移成本 | 需重写内核 | 仅重写主机端 |
| 安全性 | 全栈 Rust 安全保障 | 主机端安全，内核端仍依赖 C++ |
| 适用场景 | 新项目、长期演进 | 存量项目、渐进式改造 |

### 与社区方案的对比

与 `rust-cuda` 等社区项目相比，官方方案的最大优势在于工具链一致性和版本同步。社区项目往往需要锁定特定的 nightly Rust 版本，且难以跟上 CUDA 新特性的发布节奏。官方介入后，开发者可以期待更稳定的 ABI、更完善的文档以及更及时的 bug 修复。

### 对中国开发者的现实意义

在国内，AI 芯片与 GPU 加速计算正处于高速发展期，但底层软件栈长期依赖 C/C++，人才门槛高、内存安全问题频发。CUDA Rust 的出现，为国内团队提供了一条“用 Rust 写加速计算”的官方路径，尤其适合对可靠性和安全性要求极高的自动驾驶、金融风控和科学计算场景。

## 技术分析

从技术实现角度看，`cuda-oxide` 的关键挑战在于如何将 Rust 的所有权与借用检查语义映射到 GPU 的 SIMT（单指令多线程）执行模型上。GPU 内核中常见的共享内存、线程束同步、原子操作等概念，在 Rust 中并没有直接对应物。因此，Nvidia 很可能通过提供一组 `#[kernel]` 属性宏和 `unsafe` 边界来桥接两种语义。

一个典型的 Rust GPU 内核可能长这样：

```rust
use cuda_rust::prelude::*;

#[kernel]
fn vector_add(a: &[f32], b: &[f32], c: &mut [f32]) {
    let idx = thread_idx_x() + block_idx_x() * block_dim_x();
    if idx < a.len() as u32 {
        c[idx] = a[idx] + b[idx];
    }
}
```

主机端则通过 Rust 的异步运行时或 `cuda-bindings` 来调度：

```rust
let a = DeviceBuffer::from_slice(&host_a)?;
let b = DeviceBuffer::from_slice(&host_b)?;
let mut c = DeviceBuffer::zeros(host_a.len())?;
vector_add::launch(&a, &b, &mut c, grid, block)?;
```

而 `cuda-bindings` 则更接近传统 FFI 风格，通过 `unsafe` 块调用 `cuLaunchKernel` 等 API，同时用 Rust 的 `Result` 类型封装 CUDA 错误码，避免 C 风格错误处理带来的隐患。

从架构上看，两条路线并非互斥，而是可以混合使用：用 `cuda-bindings` 管理主机端资源，用 `cuda-oxide` 编写新内核，逐步替换旧有 C++ 内核。这种渐进式策略，正是 Nvidia 降低迁移门槛的巧妙之处。

## 实践建议

对于想要尝鲜的开发者，建议按以下步骤上手：

1. **评估现有资产**：如果项目已有大量 CUDA C++ 内核，优先选择 `cuda-bindings`，先重构主机端逻辑，验证 Rust 与 CUDA 的互操作性。
2. **从 `cuda-bindings` 起步**：安装官方提供的 crate，编写一个简单的向量加法示例，熟悉 `DeviceBuffer`、`Stream` 等抽象。
3. **小范围试点 `cuda-oxide`**：选择计算密集但逻辑简单的内核（如逐元素运算、归约）用 Rust 重写，对比性能与开发体验。
4. **关注工具链版本**：由于 `cuda-oxide` 仍处于早期阶段，建议锁定官方推荐的 Rust 版本，避免 nightly 特性带来的不稳定性。
5. **参与社区反馈**：Nvidia 开发者论坛和 GitHub 仓库是获取最新进展和提交 issue 的主要渠道，国内开发者可积极反馈中文场景下的需求。

## 总结

Nvidia 官方支持 Rust 编写 GPU 内核，是 Rust 生态向加速计算领域迈出的标志性一步。`cuda-oxide` 与 `cuda-bindings` 两条路线分别代表了“原生重构”与“渐进绑定”两种哲学，既照顾了存量项目的迁移现实，也为新项目提供了全栈安全的可能。尽管当前成熟度仍有待提升，但官方背书本身已足以让这一方向值得持续关注。对于中国开发者而言，尽早熟悉 CUDA Rust，或许就是抢占下一代高性能计算语言红利的关键一步。