NVIDIA brengt CUDA naar Rust om GPU-kernels te schrijven zonder de taal te verlaten

NVIDIA heeft een belangrijke stap gezet om Rust een first-class taal te maken binnen CUDA. Het bedrijf presenteerde twee projecten waarmee kernels rechtstreeks in Rust geschreven en gecompileerd kunnen worden naar PTX: cuda-oxide, gericht op het traditionele SIMT-model, en cutile-rs, gebaseerd op de nieuwe CUDA Tile-benadering. Beide bevinden zich nog in ontwikkeling en NVIDIA waarschuwt dat ze nog niet klaar zijn voor productiegebruik, maar verwacht dat CUDA Rust verder zal rijpen gedurende 2027 en de daaropvolgende jaren.

De kernpunten van CUDA Rust in 30 seconden

  • NVIDIA maakt het mogelijk om GPU-kernels rechtstreeks in Rust te schrijven en te compileren naar PTX, zonder het kernel in CUDA C++ te hoeven behouden.
  • Er zijn twee benaderingen: cuda-oxide voor lage-level SIMT-programmering en cutile-rs voor werken met blokken of tiles.
  • NVIDIA adviseert te beginnen met Tile als het niet nodig is om direct threads en geheugen te controleren.
  • Rust biedt de mogelijkheid om enkele van zijn eigenschappen rondom eigendom en aliasing toe te passen op GPU-parallelle programmering.
  • Beide projecten zijn experimenteel; cuda-oxide bevindt zich in een early alpha-fase.

Deze ontwikkeling verhelpt een opvallende situatie voor diegenen die al infrastructuur voor kunstmatige intelligentie in Rust aan het bouwen waren. De taal wint al geruime tijd terrein in systeemcomponenten, inferentiemotoren en infrastructuurhulpmiddelen, maar wanneer het aankomt op de kernel die uiteindelijk binnen de GPU wordt uitgevoerd, was het gebruikelijk om van taal te wisselen.

Met CUDA Rust wil NVIDIA die barrière wegnemen.

De kernel kan in Rust geschreven worden en wordt direct geconverteerd naar PTX (Parallel Thread Execution), de tussenrepresentatie die door CUDA wordt gebruikt voor code op NVIDIA GPU’s.

Dit maakt Rust niet meteen een vervanger voor CUDA C++, maar het verbindt de talenpotentie. NVIDIA omschrijft CUDA C++ en CUDA Python als volwassen tools voor zakelijke omgevingen, terwijl hun twee Rust-alternatieven nog in een vroege fase zitten.

Twee verschillende manieren om GPU te programmeren met Rust

NVIDIA brengt de twee programmeermodellen die momenteel binnen CUDA ontwikkeld worden over naar Rust.

De eerste is SIMT (Single Instruction, Multiple Threads), het klassieke model dat geassocieerd wordt met CUDA. De ontwikkelaar beschrijft wat één thread moet doen en runt vervolgens duizenden threads parallel.

Voor deze aanpak komt cuda-oxide.

De tweede optie is Tile, een hogere abstractielaag waarin de programmeur operaties op blokken data beschrijft, en de compiler beslist hoe de taak wordt verdeeld over de fysieke threads van de architectuur.

Hier komt cutile-rs in beeld.

Kenmerkcuda-oxidecutile-rs
ModelSIMTTile
Controle-niveauLaagMeer abstract
CompilatieRust → MIR → Pliron → LLVM → PTXRust → CUDA Tile IR
RustNightly vastgesteldStabiel 1.89 of hoger
CUDA12.x of laterCUDA 13.3
Minimale GPUCompute Capability 8.0Compute Capability 8.0
Eigen LLVMJa / bijbehorende omgevingNee
StatusEarly alphaGeavanceerder, maar experimenteel
Waardering NVIDIAWanneer controle nodigAlgemene eerste keuze

De aanbeveling van NVIDIA is veelzeggend: Begin met Tile en ga pas terug naar SIMT als je echt controle over threads, geheugen of hardware-details nodig hebt.

Dit wijkt af van de traditionele CUDA-programmering, waarbij veel performance afhing van het handmatig verdelen van blokken, threads en gedeeld geheugen.

CUDA Tile probeert meer van die beslissingen naar de compiler te verplaatsen.

Het potentieel voordeel is de portabiliteit tussen GPU-generaties. Als de code een operatie op een tile data uitdrukt in plaats van de specifieke manier waarop threads werken, heeft de compiler meer ruimte om het kernel aan te passen aan een ander architectuur.

cuda-oxide behoudt het klassieke CUDA-model

Voor ontwikkelaars die dat controle-niveau nodig hebben, verschijnt cuda-oxide als een aangepaste backend voor de rustc compiler.

Wanneer een functie gemarkeerd is als kernel, leidt deze door de tussenrepresentaties van Rust, het Pliron-framework en LLVM om PTX te genereren. De rest van de applicatie gebruikt de reguliere compilatieprocedure.

Een belangrijke eigenschap is dat host-code en GPU-code in hetzelfde Rust-bestand kunnen bestaan. Een apart project voor kernels is niet nodig.

Het model blijft herkenbaar voor iedereen die eerder met CUDA gewerkt heeft:

#[kernel]
#[launch_bounds(256)]
pub fn vecadd(...) {
    let idx = thread::index_1d();
    // thread-operatie
}

Elke thread berekent zijn index en werkt aan een deel van de data.

De verschillen liggen in hoe Rust zijn type- en eigendomsprincipes toepast op mogelijke fouten die in traditioneel CUDA pas tijdens runtime zichtbaar zouden zijn.

Een voorbeeld dat NVIDIA noemt, is DisjointSlice.

Een normale &mut [f32] zou een enige mutable toegang tot de gehele slice betekenen, wat niet geschikt is voor duizenden threads die gelijktijdig op verschillende posities willen schrijven.

DisjointSlice verdeelt dat conceptueel zodat elke thread exclusieve toegang krijgt tot zijn eigen positie.

De thread-index wordt niet meer simpelweg als een integer behandeld. thread::index_1d() geeft een specifiek type dat kan gebruikt worden met get_mut, en het resultaat wordt als Option teruggegeven.

Hiermee kunnen out-of-range accesses expliciet worden afgehandeld binnen het programma, in plaats van als een geheugenfout te worden genegeerd.

cuda-oxide introduceert ook launch contracts.

Met een annotatie kan een kernel bijvoorbeeld aangeven dat het verwacht dat blokken uit 256 threads bestaan en dat het binnen een eendimensionale domein werkt. Vooraf wordt de configuratie gevalideerd op basis van dat contract en de werkelijke capaciteiten van het apparaat.

Wanneer een kernel geen contract heeft, wordt de launch als unsafe gemarkeerd.

Dit illustreert goed hoe NVIDIA de ideeën van Rust qua veiligheid verder wil integreren in CUDA, zonder het hardware-aspect volledig te verbergen.

cutile-rs laat de compiler de threads beheren

cutile-rs hanteert een totaal andere filosofie.

De programmeur denkt niet meer vooral in individuele threads, maar werkt met tiles van data.

Bijvoorbeeld, een vector van 1.024 elementen gedeeld in blokken van 128, creëert acht tiles. Elk vormt een logische eenheid waarop het kernel wordt uitgevoerd.

Een operatie als:

let z = api::zeros::(&[1024]).partition([128]);

gaat niet alleen over dataverdeling.

De partitionering bepaalt welke regio door elk tile wordt gemodificeerd, hoe de uitvoering wordt georganiseerd en geeft informatie over de grootte aan de kernel.

Daarna kiest de compiler het aantal fysieke threads dat gebruikt wordt om deze operatie op de GPU uit te voeren.

Ook verandert de manier waarop mutabele geheugen toegang wordt afgehandeld.

Elke tile krijgt een exclusieve geheugenregio, waarop het schrijven plaatsvindt. Twee tiles zouden niet gelijktijdig referenties mutabel op hetzelfde fragment moeten hebben.

Hiermee wil NVIDIA een van de centrale principes van Rust toepassen: als er een mutable referentie bestaat, mag er geen onverenigbare referentie over diezelfde data bestaan gelijktijdig.

Dit is vooral relevant op GPU, waar gelijktijdigheid fouten erg moeilijk kunnen maken en sommige problemen alleen onder bepaalde hardwarecondities zichtbaar worden.

Het eigendomssysteem van Rust kan sommige van deze gevallen ontdekken voordat het programma uitgevoerd wordt.

Dit betekent niet dat Rust automatisch alle GPU-kernels veilig maakt. In cuda-oxide is het gebruik van gedeeld geheugen nog steeds unsafe, wat een gebied is dat NVIDIA erkent dat nog verbetering behoeft.

Rust begint ook dichterbij de GPU te komen

Deze ontwikkeling maakt deel uit van een bredere strategie.

NVIDIA benadrukt dat verschillende componenten van haar infrastructuur al in Rust geschreven zijn. NVIDIA Dynamo, het platform voor gedistribueerde inferentie, heeft een kern geschreven in Rust, net als bindings voor NVTX. Ook het werk rond Linux-drivermateriaal zoals Nova wordt genoemd.

Het programmeren van kernels was een van de onderdelen die altijd een overstap naar een andere taal vereiste.

CUDA Rust probeert beide werelden te verbinden:

Rust-application → CUDA-runtime → Rust-kernel → PTX → NVIDIA GPU

Dit kan bijzonder interessant zijn voor inferentiemotoren, versneld databasebeheer, wetenschappelijk onderzoek of AI-toepassingen die al Rust gebruiken voor de rest van hun infrastructuur.

Het zou ook een deel van de complexiteit verminderen die ontstaat bij het mixen van Rust-code en kernels die los van elkaar in CUDA C++ zijn geschreven.

NVIDIA beschouwt CUDA Rust nog niet als productieklaar

De aankondiging heeft een duidelijke beperking: Deze projecten vervangen CUDA C++ nog niet in kritieke toepassingen.

NVIDIA bestempelt cuda-oxide als early alpha. Het vereist Linux, een GPU met Compute Capability 8.0 of later, CUDA 12.x, Clang, en een specifieke versie van Rust Nightly.

De installatie weerspiegelt deze status:

cargo +nightly-2026-04-03 install --git https://github.com/NVlabs/cuda-oxide.git cargo-oxide

Daarna kan een project worden aangemaakt met:

cargo oxide new vecadd_demo
cargo oxide doctor
cargo oxide run

cutile-rs is iets verder ontwikkeld qua distributie. Het is beschikbaar als package en werkt met stabiele Rust-versies, maar vereist CUDA 13.3.

cargo new vecadd_demo
cd vecadd_demo
cargo add cutile

NVIDIA geeft daarnaast aan dat cutile-rs al buiten het bedrijf wordt gebruikt, onder andere door Grout, een inferentiemotor van Hugging Face, en het project mistral.rs.

Toch blijft CUDA-ondersteuning voorlopig beperkt en kunnen de interfaces nog veranderen.

Het werk dat besproken wordt in Fearless Concurrency on the GPU biedt enkele indicaties over de prestatiedoelen. In publicaties van de auteurs bereikte cuTile Rust op een NVIDIA B200 ongeveer 7 TB/s in elementaire operaties en 2 PFLOPS in GEMM, ongeveer 96% van de prestaties van cuBLAS in die specifieke test. Dit zijn experimentele resultaten op bepaalde workloads, geen garantie dat elk Rust-kernel automatisch nabij de prestaties van geoptimaliseerde CUDA-bibliotheken komt.

NVIDIA wil ook interoperabiliteit toevoegen tussen CUDA Rust, CUDA C++ en CUDA Python. Het doel is dat het kiezen van Rust voor een kernel niet betekent dat de rest van de applicatie moet worden gemigreerd.

De strategie is dus veelomvattender dan het uitbrengen van twee nieuwe bibliotheken. NVIDIA probeert ervoor te zorgen dat Rust de hele stack kan doorlopen, van systeeminfrastructuur tot de uiteindelijke code die door de GPU-kernen wordt uitgevoerd.

CUDA C++ blijft lange tijd de referentie voor veel ontwikkelaars die het hardware optimaal willen benutten. Maar als cuda-oxide en cutile-rs zich verder ontwikkelen zoals gepland, zou Rust niet alleen het taal kunnen worden dat het werk naar de GPU stuurt, maar ook dat waarin de kernel zelf wordt geschreven.

via: developer.nvidia

Scroll naar boven