NVIDIA has announced CUDA Rust, a development that finally allows developers to write GPU kernels directly in Rust without needing a separate C++ or CUDA file. The initiative relies on two open-source projects: cuda-oxide for the Single Instruction, Multiple Thread (SIMT) model and cutile-rs for the newer Tile model. Both tools compile Rust code natively into GPU instructions and use the language’s ownership system to catch aliasing errors before the program runs.
In this article
Deployment status
Availability is mixed. cutile-rs is published on crates.io, runs on stable Rust 1.89 or later, and is currently used in Hugging Face’s Grout inference engine and the mistral.rs project. cuda-oxide is in early alpha. Neither project is confirmed for production use yet.
Rust for the GPU kernel
The systems layer of artificial intelligence is increasingly written in Rust. NVIDIA’s Nova Linux driver, the core of NVIDIA Dynamo, and the NVTX bindings all use Rust. The GPU kernel was the missing piece.
The two tracks mirror the two programming models CUDA already supports. SIMT is the standard used in CUDA C++ and numba-cuda; it requires the developer to define the logic for a single thread and launch thousands of them. Tile is the newer model, available in C++ and Python. It lets developers define what one block of data does, while the Tile IR compiler handles thread mapping and memory layout. NVIDIA recommends starting with Tile, reserving SIMT for cases requiring explicit thread and memory control. Planned interoperability means choosing Rust will not lock developers out of C++ or Python.
The SIMT track: cuda-oxide
cuda-oxide is a custom rustc codegen backend. It routes #[kernel] functions through Rust MIR, the community Pliron IR framework, and LLVM IR down to PTX, then hands everything else to the standard backend. NVIDIA wrote the GPU dialects on top of Pliron.
Requirements include Linux, a GPU with compute capability 8.0 or later, CUDA 12.x or newer, clang with libclang, and a pinned nightly toolchain (nightly-2026-04-03). The command cargo oxide doctor checks the setup, while cargo oxide new scaffolds a vector addition program containing both host and device code in one file.
The safety argument rests in the kernel signature. Inputs a and b are ordinary shared slices. The output c is a DisjointSlice<f32>, a type that gives each thread exclusive access to its own element. A plain &mut [f32] would require every thread to hold the same mutable borrow, which Rust refuses. Calling c.get_mut(idx) returns an Option, turning out-of-bounds access into a handled branch. A #[launch_contract] attribute declares the block shape, and the generated prepare_vecadd method validates the launch configuration against it before the safe launch runs.
The Tile track: cutile-rs
cutile-rs works one level higher. Each tile block runs the kernel body once as a single logical thread over one sub-tensor, and the compiler decides how many real GPU threads back it. The #[cutile::module] macro embeds the kernel’s AST in the host binary and JIT-compiles it through CUDA Tile IR when the kernel is first launched.
Requirements are lighter: compute capability 8.0 or later, CUDA 13.3, stable Rust 1.89 or newer, and Linux, with no nightly and no custom LLVM. Setup involves cargo new, then cargo add cutile.
The host-side .partition([128]) call performs three tasks. It gives each tile exclusive ownership of its 128-element chunk, fixes the grid at 1,024 / 128 = 8 tiles, and supplies the const tile width B. Input tensors use -1 as a dynamic dimension resolved at launch. The generated launcher takes ownership of all tensors and returns them when the GPU finishes. Nothing executes until .sync_on(&stream); everything before it is a lazy description recorded in one chain.
What the compiler catches
Passing the SIMT kernel’s output buffer as one of its own inputs fails with error[E0502]: cannot borrow c_dev as mutable because it is also borrowed as immutable. The same aliasing on the Tile side fails with error[E0382]: use of moved value: z. cuda-oxide checks each launch call; cutile-rs‘s ownership follows tensors across the launch boundary, which NVIDIA calls the stronger guarantee.
Tile exposes no shared memory or thread indexing to misuse. SIMT keeps that control, but shared memory in cuda-oxide currently requires unsafe.
What it means
For people writing high-performance code, this removes the need to maintain parallel C++ and Rust files for GPU workloads. It also reduces the risk of runtime crashes caused by memory aliasing, as the compiler prevents these errors during development. However, users should expect instability with cuda-oxide until it moves past alpha.




