NVIDIA Announced Native Rust GPU Kernels. The Two-Track Design Is the Most Honest Thing They Could Have Done.
NVIDIA published the CUDA Rust announcement on September 8, 2026, and the Hacker News thread hit 800 points before most people had finished reading the blog post. The reaction was predictable: a mix of genuine excitement about memory safety on GPUs and the usual skepticism about whether a vendor-backed Rust project would ever reach the quality of the C++ toolchain it sits beside. Both reactions are partially right and missing the more interesting question, which is why NVIDIA chose two separate projects instead of one.
I have been writing GPU kernels since 2017, first in CUDA C++ for computer vision pipelines, then in Triton for attention variants, and most recently evaluating whether any of the Rust GPU tooling was production-ready for inference serving infrastructure. The short answer until this week was no. The longer answer is that the two-track design NVIDIA announced changes the calculation in ways that are not obvious from the blog post alone.
This piece is about the engineering decisions behind the design, not the syntax. The syntax is in the announcement. The decisions are not.
What the Two Tracks Actually Are
The announcement describes cuda-oxide and cutile-rs as two separate projects, one for SIMT programming and one for Tile programming. The framing in the blog post is that they “match the two tracks CUDA itself has.” That is true but underspecifies what is going on.
SIMT (Single Instruction, Multiple Threads) is the original CUDA programming model. You write what one thread does. You launch thousands of threads. The GPU schedules them. You manage your own shared memory, your own thread indexing, your own synchronization. Everything fast in CUDA C++ is fast because a skilled programmer made explicit decisions about all of those things.
Tile programming is different in kind, not just in syntax. The CUDA Tile IR compiler, which NVIDIA has been developing since roughly 2024, takes a kernel written at the tile level and decides how it maps onto the actual hardware. You say what one tile of data does. The compiler decides how many threads back that tile, how they access memory, and what the launch geometry is. You give up control. The compiler takes responsibility.
These are not two styles of the same thing. They are two different contracts about who owns the hardware decisions. A two-track design is not a compromise. It is the correct response to the fact that the two use cases have genuinely different requirements.
The Memory Safety Argument Is Stronger Than It Looks
The announcement makes a safety argument for both tracks using the same example: aliasing a buffer as both input and output. In cuda-oxide, this fails to compile because you cannot borrow c_dev as both &DeviceBuffer and &mut DeviceBuffer in the same call. In cutile-rs, it fails because the first argument takes ownership of the tensor and the second argument cannot use a moved value.
That example is chosen because it is easy to explain. The actual safety surface is larger, and I want to be precise about where it holds and where it does not.
In cuda-oxide, the ownership model prevents aliasing between kernel arguments. That is meaningful. Data races on GPU are exactly the kind of bug that does not reproduce in testing and appears in production under specific occupancy conditions. I have debugged two of them personally. Both took more than a week. The first was a subtle shared memory race in a softmax kernel that only triggered when block size hit a specific warp boundary. The second was a reduction kernel that assumed a particular execution order that held on Ampere but not on Hopper under different scheduling pressure. Static aliasing prevention would have caught neither of those directly, but the forced explicitness about ownership would have made the shared memory path require unsafe, which would have flagged it for review.
In cutile-rs, the safety argument is stronger by construction. If the compiler owns the thread indexing and the shared memory layout, you cannot race on things you cannot touch. The blog post says “a tile block is a single logical thread, so there are no threads for you to race.” That is accurate. The tradeoff is that you lose the ability to write kernels that require fine-grained thread cooperation, which includes most of the fastest CUDA kernels in production today. Flash attention requires explicit control of shared memory staging across warp groups. Speculative decoding with continuous batching requires manual thread block communication patterns. Cutile-rs cannot express those yet, and the blog post is honest that shared memory in cuda-oxide currently requires unsafe.
The safety story is real. It is not complete. That is the right thing to say about it in September 2026.
Why Not One Project
This is the question the blog post does not answer directly. The obvious path for a vendor-backed project would have been one unified interface: a single crate, a single abstraction, SIMT as the escape hatch when you need it. That is how most other GPU Rust projects have worked. Rust-GPU does this. CubeCL does this. You pick an entry point and drop down when you need control.
NVIDIA chose two separate projects, two separate teams, and two separate codegen backends. cuda-oxide goes through Rust MIR into Pliron IR and then into LLVM IR and down to PTX. cutile-rs captures the kernel’s AST in the host binary and JIT-compiles it through CUDA Tile IR at runtime. These are fundamentally different compilation pipelines that share almost nothing except the Rust surface syntax.
The reason is that the Tile IR compiler is the strategic bet. CUDA Tile IR is NVIDIA’s attempt to define a hardware-agnostic kernel representation that can target future architectures without recompilation. The “compiler decides how tiles map onto each architecture” line in the announcement is not a feature description. It is a portability claim. If you write a kernel in cutile-rs today, NVIDIA is claiming that it will run efficiently on whatever they ship in 2028 without you touching it.
That claim only holds if the Tile IR compiler is the authoritative path. If NVIDIA put the SIMT and Tile tracks in the same crate and let you mix them freely, the Tile IR optimization passes would have to contend with SIMT assumptions baked into the IR. That is a compilation correctness problem that would either limit the optimizer or require constant annotations to resolve. Separate projects means separate IRs, separate optimizers, and the ability to evolve the Tile track without being constrained by SIMT compatibility.
This is also why cutile-rs uses JIT compilation and cuda-oxide uses AOT. Tile IR optimization is architecture-specific in ways that you do not know at compile time. JIT lets the compiler see the actual device it is running on and make optimal decisions. AOT through PTX gives you a portable binary but locks in some decisions early. For the SIMT track, where you are already making explicit hardware decisions, AOT is fine. For the Tile track, where the compiler is supposed to own those decisions, JIT is the honest choice.
Where This Sits in the Existing Ecosystem
The announcement includes an appendix about the existing Rust GPU ecosystem, which is unusually careful for a vendor launch post. It acknowledges Rust-GPU, rust-cuda, and CubeCL explicitly, and says NVIDIA has been working with the rust-cuda maintainers.
The relationship between these projects is worth being precise about.
| Project | Maintainer | Codegen | Programming Model | Production Status |
|---|---|---|---|---|
| rust-gpu | Embark Studios / community | SPIR-V | SIMT | Graphics workloads, limited compute |
| rust-cuda | Community (Rust CUDA project) | PTX via LLVM | SIMT | Research, not production-ready |
| CubeCL | tracel-ai | CUDA C++ codegen + WGPU | Tile-like abstraction | Used in Burn ML framework |
| cudarc | Imbue / community | PTX bindings | Host-side only | Production, widely used |
| cuda-oxide (NVIDIA) | NVIDIA | MIR → Pliron → LLVM → PTX | SIMT | Early alpha, not production-ready |
| cutile-rs (NVIDIA) | NVIDIA | JIT via CUDA Tile IR | Tile | Used in HuggingFace Grout and mistral.rs |
The meaningful difference between cuda-oxide and rust-cuda is that cuda-oxide goes through NVIDIA’s own Pliron IR framework rather than through LLVM directly. Pliron is NVIDIA’s dialect-based IR, and it gives them control over the GPU-specific optimization passes in a way that upstream LLVM does not. The rust-cuda project has been limited partly by the fact that LLVM’s NVPTX backend is not owned or controlled by NVIDIA and has historically been conservative about adopting features from newer CUDA releases.
The meaningful difference between cutile-rs and CubeCL is the IR. CubeCL generates CUDA C++ source and relies on nvcc to handle the final compilation. That works and is the reason Burn can use it, but it means the optimizer is constrained by what nvcc can see. cutile-rs feeds directly into CUDA Tile IR, which is the same IR that the CUDA C++ Tile track uses, which means NVIDIA’s full optimization budget applies to Rust kernels the same way it applies to C++ kernels. That is a real difference.
The cutile-rs adoption in HuggingFace Grout and mistral.rs is the most important sentence in the blog post and gets the least emphasis. Grout is HuggingFace’s new inference engine, begun after their acquisition of VectorWare in early 2026, targeting the H200 and B200 series specifically. Mistral.rs is one of the more widely deployed open inference stacks. Both chose cutile-rs before the public announcement, which means the Tile track has already survived contact with production workloads at real scale.
The Nightly Toolchain Problem
cuda-oxide requires a pinned nightly Rust toolchain. The announcement acknowledges this and calls it “exactly the kind of thing we would like to stop asking you for.” The blog post treats this as a known friction point that will eventually be resolved.
I want to be more specific about why it matters, because “requires nightly” is not a minor ergonomic complaint when you are talking about production infrastructure.
A pinned nightly toolchain means that your kernel code is coupled to a specific compiler version in a way that stable Rust is not. When NVIDIA pins to nightly-2026-04-03, they are telling you that this is the compiler that their codegen backend was tested against. Using a different nightly is not supported. Upgrading to a newer nightly requires NVIDIA to validate and update cuda-oxide.
For a research project or a personal project, this is annoying. For production infrastructure at a company that audits its dependencies, pins its toolchains, and has a security team that reviews compiler provenance, this is a blocker. NVIDIA knows this. The language in the announcement suggests they know this and are working on it, but they shipped without solving it because the alternative was not shipping until it was solved, and the community feedback loop they need to solve it requires shipping first.
cutile-rs does not have this problem. It requires stable Rust 1.89 or newer. That is a pinnable, auditable, reproducible toolchain requirement. This is not an accident. It is one of the reasons to reach for the Tile track first, as the announcement explicitly recommends.
What the Fearless Concurrency Claim Actually Means on a GPU
The paper the announcement links is titled “Fearless Concurrency on the GPU,” and the RustConf 2026 talk by Melih Elibol has the same name. Rust’s “fearless concurrency” story on the CPU is well understood: the ownership system prevents data races at compile time by ensuring that mutable references are exclusive. The question is how much of that story transfers to GPU execution, where “threads” means something different than it does on a CPU.
On a CPU, threads are OS-managed units of execution that can be preempted and scheduled in arbitrary orders. Rust’s Send and Sync traits reason about which data can be safely shared across those scheduling boundaries. The model is well-defined and the compiler guarantees are precise.
On a GPU, threads are lightweight execution units grouped into warps, and warps are grouped into thread blocks, and thread blocks share resources within a streaming multiprocessor. The ordering guarantees within a warp are strong: threads in a warp execute in lockstep. The ordering guarantees between warps in the same block are weaker: you need explicit barriers. The ordering guarantees between blocks are almost nonexistent: the only cross-block communication primitive is global memory with explicit atomics, or NVSHMEM for multi-GPU.
The fearless concurrency guarantee that cuda-oxide provides is at the argument level: you cannot alias input and output buffers. It does not prevent races within a kernel that writes to global memory using multiple threads without synchronization. Shared memory access, as the announcement notes, currently requires unsafe. Warp-level primitives require unsafe. Any kernel that does something more interesting than elementwise operations will touch unsafe code.
Cutile-rs provides a stronger guarantee: by abstracting threads away entirely, the races you could have introduced do not exist because you cannot write the code that would cause them. The cost is that you cannot write the code at all, which means you cannot write certain fast kernels.
My prediction: within eighteen months, the “fearless concurrency on the GPU” framing will be refined. The community will establish that the Tile track provides the strong version of the guarantee and that the SIMT track provides a weaker but still meaningful version. The distinction will become important when these tools are being evaluated for safety-critical inference workloads, which is exactly the direction the industry is moving as AI systems take on more consequential decisions.
The Architecture Decision That Makes cutile-rs Different from Everything Before It
The most interesting line in the cutile-rs code example is .sync_on(&stream)?;. Everything before it in the code is lazy. The ones, the zeros, the kernel launch, and even the copy back to the host are described but not executed until that single synchronization point.
This is not just an ergonomic choice. It is a statement about the execution model. Lazy evaluation means that the runtime has visibility into the entire computation graph before any of it executes. A runtime with that visibility can reorder operations to maximize overlap between compute and memory transfer, can detect redundant copies, and can make decisions about when to actually allocate device memory based on observed access patterns.
CUDA streams already allow overlap between compute and transfer, but using them correctly requires explicit management by the programmer. You have to know when to submit operations to which stream, when to synchronize, and what the overlap opportunities are. Most CUDA code in production uses the default stream for everything because managing multiple streams is difficult and error-prone. The result is serialized execution that leaves significant GPU utilization on the table.
Lazy evaluation by default inverts that default. The common case gets overlap for free. The uncommon case where you need explicit control still has access to streams, but the optimizer can do the right thing without programmer intervention. This is the same design choice that JAX made with its tracing model and that XLA exploits for fusion and layout optimization. NVIDIA is making it for GPU kernels in Rust, and the fact that it requires no nightly toolchain means it could realistically be adopted in production inference stacks within the next year.
What This Means for Inference Infrastructure
I want to make a specific claim about where this goes, because the blog post is careful to avoid making strong predictions and I think that leaves the most important implication unstated.
The inference serving stack in 2026 is written mostly in C++ and CUDA, with Python at the edges for orchestration. The fast paths through vLLM, TensorRT-LLM, and the NVIDIA NIM stack are C++ with CUDA kernels. The maintenance burden of those kernels is high, the onboarding time for new engineers is measured in months, and the bugs that make it to production are disproportionately the kinds of bugs that memory safety would have caught: aliasing errors, race conditions on shared state, and incorrect assumptions about execution order.
Cutile-rs is already in HuggingFace Grout and mistral.rs. Those are not toy projects. Grout was specifically designed to replace the fragile Python wrapper layers in the HuggingFace inference stack with something that could run closer to the metal. Mistral.rs targets performance-sensitive deployment with a lean binary that avoids the Python interpreter overhead entirely. Both chose cutile-rs before the public announcement, which means the evaluation was based on actual engineering requirements rather than brand or novelty.
My prediction: by the end of 2027, at least one major inference framework will have its attention kernel path written primarily in cutile-rs, and the benchmark numbers will be within five percent of the equivalent CUDA C++ implementation. The productivity gain will be significant enough that new kernel development defaults to cutile-rs for any operation that can be expressed at the Tile level, and drops to cuda-oxide SIMT only for operations that require explicit shared memory management.
The reason I am confident about the five percent gap rather than parity is that the Tile IR compiler will have been running in production for over a year by then, and NVIDIA’s compiler team has a strong incentive to close performance gaps when they can measure them against C++. The reason I am confident about the remaining gap is that shared memory management in SIMT is still manually optimal in ways the Tile compiler cannot fully match, and the operations that need it are also the ones most people care most about.
What the SIMT Track Is Actually For
The blog post recommends reaching for the Tile track first, and the recommendation is correct for most use cases. But it undersells what the SIMT track is for, which is kernel development where you need to understand exactly what the GPU is doing and why.
The ownership model in cuda-oxide does something valuable beyond safety: it makes the memory access pattern explicit in the type signature. When you look at a cuda-oxide kernel, you know from the types which buffers are inputs and which are outputs, and you know that no aliasing is possible. That information is not in a CUDA C++ kernel signature without reading the implementation.
For debugging and profiling, that explicitness matters. When you are running nsight-compute and trying to understand why your cache hit rate is lower than expected, having the memory access structure visible in types rather than inferred from the implementation is genuinely useful. The cognitive overhead of reasoning about ownership goes down when the ownership is encoded in the type system rather than in comments or conventions.
I expect the SIMT track to be most useful for people writing new kernels from scratch who want the safety guarantees during development, even if they know they will need unsafe for the final shared memory optimization pass. The ownership model catches aliasing bugs before you hit the profiler, which means you spend more of your profiling time on actual performance problems rather than on correctness issues that happen to look like performance problems.
The Nightly Stabilization Timeline
The nightly requirement for cuda-oxide is a real problem and NVIDIA knows it. The reason it exists is that cuda-oxide uses a custom rustc codegen backend, which requires nightly features that have not yet been stabilized. The specific feature is the ability to register a custom codegen backend, tracked in the Rust repository under an open RFC that has been in progress since 2023.
The stabilization timeline for custom codegen backends is not controlled by NVIDIA. It is controlled by the Rust compiler team, which moves carefully and has legitimate concerns about the API surface. The current estimate from Rust internals discussions is stabilization in 2027 if the design is agreed upon, but that timeline has slipped before.
Until it stabilizes, cuda-oxide will require nightly, and that will limit its adoption in organizations with strict toolchain requirements. The phrase “exactly the kind of thing we would like to stop asking you for” is accurate and honest, but it does not tell you when you can stop being asked. The answer is probably late 2027, and it is not within NVIDIA’s control.
Why This Matters Beyond NVIDIA Hardware
The announcement targets NVIDIA GPUs. But the architecture decisions in cutile-rs have implications beyond CUDA.
The Tile IR is designed to be architecture-portable within the NVIDIA lineup, meaning it can target H100, H200, B200, and future architectures from the same source. But the JIT compilation model and the lazy evaluation semantics are not inherently NVIDIA-specific. If the Tile programming model proves successful, it will create pressure on other hardware vendors to expose similar compiler interfaces, because the alternative is that software written for cutile-rs requires full reimplementation to run on their hardware.
AMD has ROCm and HIP, which provide CUDA compatibility at the API level. They do not have a Tile IR equivalent. Intel has oneAPI, which has its own tile-level abstractions in SYCL, but the ecosystem is smaller and the tooling is less mature. The vendor that ships a Rust-native Tile programming model that targets multiple backends will capture the kernel development community that cutile-rs is building right now.
Whether NVIDIA keeps cutile-rs NVIDIA-only or opens the Tile IR to non-NVIDIA targets is a strategic decision they have not made public. My prediction is that they will keep it NVIDIA-only for at least two years, and that this will become a competitive argument for AMD and Intel to accelerate their own Rust GPU efforts. The community that rust-gpu and CubeCL built will continue to grow, and the existence of NVIDIA’s projects will increase investment in portable alternatives rather than reducing it.
The Honest Assessment
NVIDIA shipping two early-alpha Rust GPU projects with clear documentation of what they can and cannot do is the right approach. The blog post says “neither is production-ready.” That is true. It says “coverage is incomplete and APIs will move.” That is true. It says “shared memory in SIMT currently requires unsafe.” That is true and important.
The two-track design is not a lack of focus. It is the correct response to the fact that SIMT and Tile are different programming models with different safety properties and different compilation requirements. A single interface over both would have produced a leaky abstraction that satisfied neither use case. Two separate projects with clear boundaries let each evolve toward its natural endpoint without compromising the other.
The cutile-rs adoption in Grout and mistral.rs is the strongest evidence that the Tile track is heading somewhere real. Those teams made engineering decisions based on actual performance data, not on the promise of a future announcement. The fact that they chose cutile-rs before the public launch means the tool was already good enough for production work, which is more than can be said for most pre-announcement GPU tooling.
The cuda-oxide SIMT track is earlier and more constrained by the nightly requirement. But it is also doing something that no other project has done: bringing Rust’s ownership model directly to the GPU kernel level with NVIDIA’s compiler infrastructure behind it. That matters for the kernel development workflow even before it is production-ready, because the static feedback shortens the correctness loop in ways that affect real engineering time.
I plan to evaluate cutile-rs against our current Triton kernels for the attention path in our inference stack over the next quarter. My expectation is that the stable Rust requirement, the lazy evaluation model, and the tile-level safety guarantees will make it the right choice for new kernel development even before the performance fully matches C++. If I am wrong about the five percent gap, I will say so publicly. The Triton comparison numbers will be honest either way.
The Right Lesson from the HN Thread
The Hacker News discussion predictably split into two camps. One camp spent most of its energy arguing about whether NVIDIA will maintain these projects long-term, citing historical examples of GPU vendor tooling that was announced with fanfare and quietly deprecated two years later. The other camp got lost in comparisons between Rust ownership semantics and C++ const correctness, which is technically interesting but misses the point of why you want memory safety in kernel code specifically.
The right lesson is narrower than either camp landed on. NVIDIA shipped two tools that solve a real problem: kernel correctness is hard, and the feedback loop for finding correctness errors in CUDA C++ is slow because the errors surface at runtime under specific hardware conditions rather than at compile time under any conditions. Both cuda-oxide and cutile-rs shorten that feedback loop in different ways and for different audiences.
Whether NVIDIA maintains them long-term depends entirely on whether the projects attract enough external use to justify the investment. Cutile-rs being in Grout and mistral.rs before the public announcement is the strongest indicator that the Tile track will survive. Kernel developers at HuggingFace and Mistral are not sentimental about tooling choices. They use what works and drop what does not. The fact that they chose cutile-rs and are now public about it creates the kind of community investment that outlasts any individual vendor decision. That is the number to watch, not the launch blog post.




Discussion