T1 shipped without a design doc; capture the Rust↔CUDA build chain (build.rs+nvcc, no_cuda cfg pattern, RAII GpuBuffer, gitea↔dash5 flow). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
3.2 KiB
3.2 KiB
Phase T1: Rust↔CUDA Build Chain — Design Document
回填文档:T1 随 commit
92acf9f落地(scaffold + 构建链路 + vecadd 冒烟测试), 当时未写文档,此处补记,供后续 Phase 回溯。
Goal
打通「Rust 调 CUDA」的最小闭环:用 build.rs 调 nvcc 编 csrc/*.cu,
经手写 extern "C" FFI 链入 Rust;本地无 GPU/nvcc 时仍能 cargo check。
验收以一个 vector-add kernel 冒烟通过为准。
Module Layout
xtrain/
├── Cargo.toml # workspace
├── csrc/
│ └── test/vecadd.cu # 冒烟用 c[i]=a[i]+b[i]
└── crates/xtrain-cuda/
├── build.rs # 检测 nvcc → 编 .cu / 链 cudart,否则发 no_cuda cfg
└── src/
├── ffi.rs # extern "C" 绑定(cudaMalloc/Memcpy/Free…+ kernel launch)
├── error.rs # CudaError + check(code)
├── device.rs # device_count / set_device / synchronize
└── memory.rs # RAII GpuBuffer(alloc/H2D/D2H/Drop)
Key Design Decisions
build.rs 检测 nvcc,缺失则发 no_cuda cfg
if !nvcc_available(&cuda_path) {
println!("cargo:warning=nvcc not found — skipping CUDA compilation (host-only build).");
println!("cargo:rustc-cfg=no_cuda");
return; // 不编 .cu、不链 cudart
}
// 否则:cc::Build::new().cuda(true)…-gencode=arch=compute_120,code=sm_120
- 本地机无 GPU/nvcc → 跳过 CUDA 编译,host 侧 Rust 照常
cargo check。 - dash5 有 nvcc 12.9 → 实编
.cu,目标sm_120(RTX 5090)。 - 必须配
println!("cargo:rustc-check-cfg=cfg(no_cuda)")声明自定义 cfg, 否则新版 rustc 报unexpected_cfgswarning。
no_cuda cfg 门控 GPU-only 代码
GPU 专属的 kernel-launch FFI 与集成测试用 #[cfg(not(no_cuda))] 包起来:
#[cfg(not(no_cuda))]
unsafe extern "C" {
pub fn launch_vecadd_f32(a: *const f32, b: *const f32, c: *mut f32, n: i32, stream: CudaStream);
}
测试文件顶用 #![cfg(not(no_cuda))] 整体门控。注意:cudaMalloc 等
runtime 符号在 ffi.rs 里不门控(恒声明),本地只 cargo check(不链接)所以无碍;
真正链接发生在 dash5(cudart 在)。约定:本地只 check/fmt,链接+测试都在 dash5。
RAII GpuBuffer
alloc/copy_from_host(H2D)/copy_to_host(D2H),Drop 调 cudaFree,
unsafe impl Send。后续张量层在其上搭 device 存储(见 docs/01-tensor.md)。
验证方法
ssh dash5
export PATH=/usr/local/cuda/bin:/opt/wjh/.cargo/bin:$PATH
cd ~/projects/xtrain && cargo test -p xtrain-cuda -- --nocapture
# vecadd OK: a[i]+b[i],c[i]=3i 通过
本地(无 GPU):cargo check 绿(build.rs 发 no_cuda,GPU 测试编译出局)。
gitea ↔ dash5 同步流
origin = git@gitea:gahow/xtrain.git,分支main;git 身份用~/.gitconfig(不-c覆盖)。- 本地
git push origin main→ dash5cd ~/projects/xtrain && git pull→ export PATH 后构建/测试。 - 连 gitea 会打印无害的
Welcome to VyOSbanner,可忽略。