CUDA Rust — тепер із двома шляхами для нативної розробки GPU-ядер на Rust
Public- 09 Sep, 2026

У вересні 2026 року NVIDIA оголосила, що робить ставку на нативну розробку GPU на Rust. CUDA C++ і CUDA Python — зрілі промислові інструментарії, але системний шар ШІ — рушії інференсу, обслуговувальна інфраструктура, драйвери та рантайми агентів — постійно переписується і дедалі частіше пишеться на Rust, який ловить цілі класи помилок ще на етапі компіляції, не жертвуючи продуктивністю. Сама NVIDIA — частина цього зсуву: драйвер Nova Linux написаний на Rust, NVIDIA Dynamo побудована на Rust-ядрі, а в NVTX є Rust-біндинги. Винятком залишалося GPU-ядро, оскільки ядра можна було запускати з Rust, але зазвичай їх доводилося писати іншою мовою. CUDA Rust закриває цей розрив, дозволяючи писати ядра на Rust і компілювати їх нативно в PTX, а не обгортати код із чужих джерел.

Є два шляхи використання Rust, що відповідають двом шляхам, які вже існують у самому CUDA. SIMT — звична модель із CUDA C++ або numba-cuda: ви описуєте, що робить один потік, і запускаєте їх тисячами. Tile — новіша модель програмування, доступна також у C++ і Python, де ви описуєте, що робить один тайл даних, а всім іншим займається компілятор Tile IR. Керівництво NVIDIA радить насамперед звертатися до Tile, тому що компілятор сам вирішує, як тайли лягають на кожну архітектуру, а ваш вихідний код залишається вільним від архітектурно-специфічних рішень; до SIMT ви опускаєтеся, коли потрібен цей рівень контролю або ви хочете самі керувати пам'яттю та потоками. Вибір мови відділений від вибору моделі, а міжмовна сумісність запланована, тож перехід на Rust не замикає вас від інших фронтендів.

Шлях SIMT — це cuda-oxide, кастомний кодген-бекенд rustc. Він перехоплює компіляцію, проводить функції #[kernel] через Rust MIR, фреймворк Pliron IR та LLVM IR аж до PTX, а все інше передає стандартному бекенду. GPU-діалекти поверх Pliron належать NVIDIA, і кожне перетворення залишається на Rust доти, доки не вступає в дію стандартний LLVM-бекенд. Вимоги включають Linux, GPU з compute capability 8.0 або вище, CUDA toolkit 12.x або новіший, clang з його заголовками libclang і закріплений nightly-тулчейн. Підкоманда Cargo cargo-oxide керує збіркою, а cargo oxide doctor перевіряє тулчейн. Проєкт скаффолдиться через cargo oxide new, а перший cargo oxide run збирає кодген-бекенд, тож наступні запуски використовують кеш.
Шлях Tile — це cutile-rs, який працює на рівень вище: ви виконуєте обчислення над тайлами, а не над скалярами. Кожен тайл-блок виконує тіло ядра один раз як єдиний логічний потік над одним під-тензором даних, а компілятор вирішує, скільки реальних GPU-потоків його підтримують. Макрос #[cutile::module] вбудовує AST ядра в бінарник хоста й JIT-компілює його через CUDA Tile IR при першому зверненні до ядра. Вимоги легші, ніж у шляху SIMT: GPU з compute capability 8.0 або вище, CUDA 13.3, стабільний Rust 1.89 або новіший і Linux, без nightly-тулчейна і без власного LLVM. Оскільки cutile опублікований, ви просто запускаєте cargo add cutile, нічого не клонуючи.

Обидва шляхи наводять один і той самий аргумент про безпеку щодо пам'яті. У прикладі SIMT змінюваний вихідний буфер — це DisjointSlice<f32>, спеціально створений тип, який дає кожному потоку ексклюзивний доступ до свого елемента, тому що &mut [f32] має неправильну форму, коли кожному потоку знадобилося б одне й те саме змінюване запозичення. Запуск перевіряється, а не приймається на віру: оголошення #[launch_contract] перевіряється на відповідність LaunchConfig1D і фактичним лімітам пристрою, а ядра без контракту надають лише сирі unsafe-методи запуску. На боці Tile розділення дає кожному тайл-блоку один записуваний під-тензор, який не може перетинатися з іншими блоками, і ця ексклюзивність — саме те, що вже гарантує &mut. Передача вихідного буфера ядра як одного з його власних входів не компілюється, що відловлює гонки аліасингу, які інакше пройшли б тести, а потім спливли в продакшені.