NVIDIA anunció CUDA Rust, una apuesta por convertir a Rust en un lenguaje de primera clase para escribir kernels de GPU. El código Rust ya podía lanzar kernels CUDA, pero el cuerpo del kernel había que escribirlo en otra parte. CUDA Rust cierra esa brecha con dos proyectos de código abierto de NVlabs: cuda-oxide para el modelo SIMT y cutile-rs para el modelo Tile, más reciente. Ambos compilan kernels de Rust de forma nativa y usan las reglas de propiedad del lenguaje para rechazar errores de aliasing en tiempo de compilación.
¿Se puede usar hoy en producción?
Parcialmente. cutile-rs está publicado en crates.io, corre sobre Rust estable 1.89 o superior y ya se usa en el motor de inferencia Grout de Hugging Face y en mistral.rs. cuda-oxide, en cambio, está en alfa temprana. Los dos proyectos siguen en fase alfa y ninguno está confirmado para producción.
Por qué Rust en el kernel de la GPU
La capa de sistemas de la inteligencia artificial, desde los motores de inferencia hasta los controladores y los entornos de ejecución de agentes, se escribe cada vez más en Rust. El controlador Nova para Linux de NVIDIA está en Rust, NVIDIA Dynamo tiene un núcleo en Rust y NVTX cuenta con enlaces para el lenguaje. El kernel de GPU era la excepción.
Los dos caminos reflejan los dos modelos de programación que CUDA ya ofrece. SIMT es el modelo que usan CUDA C++ y numba-cuda: se describe lo que hace un hilo y se lanzan miles. Tile es el modelo más nuevo, también disponible en C++ y Python: se describe lo que hace un bloque de datos y el compilador de Tile IR resuelve el mapeo de hilos y la disposición en memoria. NVIDIA recomienda partir por Tile y dejar SIMT para cuando se necesita control explícito de hilos y memoria. La interoperabilidad entre lenguajes que la empresa tiene planificada implica que elegir Rust no dejará al desarrollador fuera de C++ o Python.
El camino SIMT: cuda-oxide
cuda-oxide es un backend de generación de código propio para rustc. Enruta las funciones marcadas con #[kernel] a través del MIR de Rust, el entorno de representación intermedia comunitario Pliron y LLVM IR hasta llegar a PTX, y deja todo lo demás en manos del backend estándar. Los dialectos de GPU sobre Pliron los escribió NVIDIA.
Los requisitos son exigentes: Linux, una GPU con capacidad de cómputo 8.0 o superior, CUDA 12.x o más nuevo, clang con libclang y una versión nightly fijada del conjunto de herramientas (nightly-2026-04-03). El comando cargo oxide doctor revisa la instalación y cargo oxide new genera un programa de suma de vectores con el código del anfitrión y el del dispositivo en un mismo archivo.
El argumento de seguridad está en la firma del kernel. Las entradas a y b son porciones compartidas corrientes. La salida c es un DisjointSlice<f32>, un tipo que le da a cada hilo acceso exclusivo a su propio elemento. Un &mut [f32] común obligaría a que todos los hilos tomaran el mismo préstamo mutable, algo que Rust rechaza. La llamada c.get_mut(idx) devuelve un Option, así que un acceso fuera de rango se convierte en una rama manejada. El atributo #[launch_contract] declara la forma del bloque, y el método generado prepare_vecadd valida la configuración de lanzamiento contra ese contrato antes de ejecutar el lanzamiento seguro.
El camino Tile: cutile-rs
cutile-rs trabaja un nivel más arriba. Cada bloque de tile ejecuta el cuerpo del kernel una sola vez, como un hilo lógico único sobre un subtensor, y el compilador decide cuántos hilos reales de GPU lo respaldan. La macro #[cutile::module] incrusta el árbol sintáctico del kernel en el binario del anfitrión y lo compila al vuelo mediante CUDA Tile IR la primera vez que se lanza.
Los requisitos son más livianos: capacidad de cómputo 8.0 o superior, CUDA 13.3, Rust estable 1.89 o más nuevo y Linux, sin nightly y sin un LLVM a medida. La instalación se reduce a cargo new y luego cargo add cutile.
La llamada .partition([128]) del lado del anfitrión hace tres cosas: le entrega a cada tile la propiedad exclusiva de su bloque de 128 elementos, fija la grilla en 1.024 dividido en 128, es decir 8 tiles, y provee el ancho constante B del tile. Los tensores de entrada usan -1 como dimensión dinámica que se resuelve al momento del lanzamiento. El lanzador generado toma la propiedad de todos los tensores y los devuelve cuando la GPU termina. Nada se ejecuta hasta el .sync_on(&stream): todo lo anterior es una descripción perezosa registrada en una sola cadena.
Qué alcanza a atrapar el compilador
Pasar el búfer de salida del kernel SIMT como una de sus propias entradas falla con error[E0502]: cannot borrow c_dev as mutable because it is also borrowed as immutable. El mismo aliasing del lado Tile falla con error[E0382]: use of moved value: z. cuda-oxide revisa cada llamada de lanzamiento, mientras que la propiedad en cutile-rs sigue a los tensores más allá del límite del lanzamiento, lo que NVIDIA considera la garantía más fuerte.
Tile no expone memoria compartida ni indexación de hilos, así que no hay nada que usar mal. SIMT conserva ese control, pero la memoria compartida en cuda-oxide todavía exige bloques unsafe.
Lo esencial
- CUDA Rust suma dos caminos nativos para escribir kernels de GPU en Rust: cuda-oxide para SIMT y cutile-rs para Tile.
- cuda-oxide compila el MIR de Rust a través de Pliron y LLVM hasta PTX, y necesita una versión nightly fijada.
- cutile-rs corre sobre Rust estable 1.89 o superior con CUDA 13.3 y compila al vuelo por medio de CUDA Tile IR.
- Ambos rechazan el aliasing de búferes en tiempo de compilación usando el verificador de préstamos y la propiedad de Rust.
- cutile-rs ya mueve a Grout y a mistral.rs, aunque ninguno de los dos proyectos está listo para producción.
Los detalles técnicos están acá.
¿Qué implica para quien programa GPU en la región?
El requisito de capacidad de cómputo 8.0 marca el piso real de entrada: deja fuera a las tarjetas anteriores a la arquitectura Ampere, que siguen siendo la base del parque instalado en laboratorios universitarios y pequeños proveedores de cómputo en LatAm. Quien quiera probar cutile-rs necesita además CUDA 13.3, una versión bastante por delante del 12.x que aún se ve en muchos servidores en producción. La ruta más corta hoy pasa por instancias en la nube antes que por hardware propio.




