cuda-oxide 中文文档#
cuda-oxide 是一个实验性的 Rust 到 CUDA 编译器,让你能够用安全(近乎安全)、地道的 Rust 编写(SIMT)GPU 内核。它将标准 Rust 代码直接编译为 PTX——无需 DSL,无需外部语言绑定,只需 Rust。
备注
本书假定读者熟悉 Rust 编程语言,包括所有权、trait 和泛型。后续关于异步 GPU 编程的章节还假定读者了解 async/.await 以及 tokio 等运行时。
如需复习,请参阅 Rust 程序设计语言、Rust 示例 或 异步编程指南。
项目状态#
v0.1.0 版本是一个早期 alpha 阶段:预期会遇到 bug、不完整的功能和 API 变更,我们正在努力改进。我们希望你能试用它,并通过分享使用体验来帮助塑造其发展方向。
🚀 快速开始#
use cuda_device::{cuda_module, kernel, thread, DisjointSlice};
use cuda_core::{CudaContext, DeviceBuffer, LaunchConfig};
#[cuda_module]
mod kernels {
use super::*;
#[kernel]
fn vecadd(a: &[f32], b: &[f32], mut c: DisjointSlice<f32>) {
let idx = thread::index_1d();
let i = idx.get();
if let Some(c_elem) = c.get_mut(idx) {
*c_elem = a[i] + b[i];
}
}
}
fn main() {
let ctx = CudaContext::new(0).unwrap();
let stream = ctx.default_stream();
let module = kernels::load(&ctx).unwrap();
let a = DeviceBuffer::from_host(&stream, &[1.0f32; 1024]).unwrap();
let b = DeviceBuffer::from_host(&stream, &[2.0f32; 1024]).unwrap();
let mut c = DeviceBuffer::<f32>::zeroed(&stream, 1024).unwrap();
module
.vecadd(&stream, LaunchConfig::for_num_elems(1024), &a, &b, &mut c)
.unwrap();
let result = c.to_host_vec(&stream).unwrap();
assert_eq!(result[0], 3.0);
}
安装好前提条件后,使用 cargo oxide run vecadd 构建并运行。
备注
#[cuda_module] 将生成的设备工件嵌入到宿主二进制文件中,并生成一个类型化的 kernels::load 函数以及每个内核一个启动方法。当你需要加载特定的 sidecar 工件或构建自定义启动代码时,仍可使用更低层的 load_kernel_module 和 cuda_launch! API。
为什么选择 cuda-oxide?#
使用 Rust 的类型系统和所有权模型编写 GPU 内核。安全性是首要目标,但 GPU 有其微妙之处——请阅读安全模型。
这不是 DSL。它是一个自定义的 rustc 代码生成后端,将纯 Rust 编译为 PTX。
将 GPU 工作组合为惰性的 DeviceOperation 图。跨流池调度。使用 .await 等待结果。