世界を動かす技術を、日本語で。

すべてのGPUで動作するRust

概要

  • Rust単一コードベース で、主要なGPUプラットフォームすべてに対応したデモを構築
  • CUDA/Vulkan/Metal/DirectX12/WebGPU/CPUフォールバック に対応
  • Rustのみ でGPU計算ロジックを実装、シェーダー言語不要
  • 主要なRust GPU関連プロジェクト の統合と進展
  • 型安全性・移植性・拡張性 に優れたアプローチの紹介

Rust単一コードベースでクロスプラットフォームGPU計算

  • CUDA(NVIDIA)、SPIR-V(Vulkan対応GPU)、Metal(Apple)、DirectX12(Windows)、WebGPU(ブラウザ)、CPUフォールバック に対応
  • 全てのターゲットで同一の計算ロジック をRustのみで記述、シェーダーやカーネル言語は一切不要
  • GitHubでコード公開、誰でも確認・利用可能

従来のGPUプログラミングの課題

  • WGSL/GLSL/MSL/HLSL/Slang/Triton 等、GPUごとに異なる専用言語が必要
  • アプリ本体とGPUロジックが分断、複雑化・ロジックの重複発生
  • Rustコミュニティ では、RustコードをそのままGPUターゲットにコンパイルする新アプローチを模索

主要Rust GPUプロジェクト

  • Rust GPU :RustコードをSPIR-Vにコンパイル、Vulkan等で利用可能
  • Rust CUDA :RustコードをNVVM IRにコンパイル、CUDAランタイムで実行
  • Naga :wgpuチーム開発の言語変換レイヤー、WGSL/SPIR-V/GLSL/MSL/HLSL間を変換
    • 移植性重視、複数バックエンドを橋渡し

プロジェクト統合とデモの意義

  • これらのプロジェクトは 元々独立して開発 されていたが、 統合が進行中
  • Rust GPU・Rust CUDA・Naga のメンテナ、またはコントリビュータが連携
  • 全主要GPUバックエンドで単一Rustコードが動作する初のデモ
  • クロスプラットフォームGPU計算 の実現を示す重要なマイルストーン

デモの仕組み

  • ビトニックソート のシンプルな計算カーネルを全ターゲットで共有
  • ホスト :CPU上でRustコードがGPU計算を起動
  • デバイス :カーネルが実行されるGPUまたはCPU
  • ドライバAPI :CUDA/Vulkan/Metal/DirectX12等、デバイス制御用低レベルAPI
  • バックエンド :Rust側の抽象化ライブラリ(cust/ash/wgpu等)

バックエンド選択とビルド

  • Rustのfeatureフラグとターゲット指定 でバックエンド・ドライバAPIを選択
    • cargo build --features wgpu:システム標準ドライバAPI
    • cargo build --features wgpu,vulkan:wgpuでVulkan強制指定
    • cargo build --features ash:ashによるVulkan専用バックエンド
    • cargo build --features cuda:NVIDIA CUDAバックエンド(custクレート利用)
  • 複数バックエンド同時ビルド・実行時選択も可能、柔軟なプラットフォーム対応

カーネルコンパイルと実行

  • ターゲット・Rust feature・OS・ドライバAPI に応じてカーネルを適切な形式にビルド
  • ビルド時にバイナリへ埋め込み、ランタイムでロード・実行
  • SPIR-V/PTX/MSL/HLSL等 への変換・転送も自動化

RustならではのGPUプログラミング手法

  • no_std対応 :GPU上で標準ライブラリ非依存
    • #![no_std]で組み込み・ファームウェア向けRustコードをそのままGPUで利用可能
  • 条件付きコンパイル#[cfg(...)]でターゲットごとに型や定数・実装を切り替え
    • コード重複・分岐の明確化、IDEサポートも充実
  • Newtypeパターン :型安全性強化、論理エラーをコンパイル時に防止
    • #[repr(transparent)]で実行時オーバーヘッドなし
  • Enum活用 :魔法数排除、型安全な設定値管理
    • #[repr(u32)]でメモリレイアウト保証、全ケース網羅性も担保
    • 注意 :CPU-GPU間でenum値の不正利用は未定義動作のリスクあり
  • Traitによる抽象化 :型ごとに最適化されたGPUアルゴリズムをゼロコストで実装
    • サードパーティ型にも拡張容易、明確な契約による安全性
  • #[inline]活用 :関数呼び出しのオーバーヘッド排除、GPU向け最適化
  • 構造体合成 :意味単位でグルーピングし、自己記述的なAPI設計

今後の展望と課題

  • 型安全なCPU-GPU間データ転送 のさらなる言語サポート強化
  • Rustエコシステム全体でのGPU対応、no_stdクレートの活用拡大
  • 複雑なGPUプログラム にも対応可能な設計、拡張性の高い基盤構築

このデモは、 RustによるクロスプラットフォームGPUプログラミング の新しい可能性と、 型安全性・移植性・生産性 を両立するアプローチの実用性を示しています。今後のRustコミュニティの発展に大きく寄与する成果です。

Hackerたちの意見

他の目的のために書かれたno_std + no allocのクレートは、一般的に修正なしでGPU上で動作できるみたい。すごいね。ぱっと見で、たくさんの面白いアイデアが解放される感じがする。

確かに、これが可能だなんてすごいよね!でも、私の使い方(任意のクライアントハードウェアで動かすこと)だと、GPU APIの抽象化にはあまり信頼を置いてないんだ。だって、GPUの低レベルの詳細を活用するのが目的だから。そういう詳細を面倒だと思うと、バグやパフォーマンスの低下につながるし、各ターゲットは意味のある違いがあるからね。これを克服するには、ベンダーが似たようなシステムを提案する必要があると思う。でも、彼らが意見をまとめられなかったから、プラットフォームの違いは大きいんじゃないかな。例外もあるけど(例えばAngle)、でもそれは機能セットを制限することで安定性を得てるだけだから、パフォーマンスも落ちちゃうよね。このアプローチが条件付きコンパイルを可能にするのはいいことだね、確かに助かる。

その通りだね。NvidiaのGPUでRustを動かす方が、実際のCUDAコードよりも良い理由がよくわからない。抽象化のアイデアは理解できるけど、ちょっと「なんでも屋」になっちゃう気がする。

同じく。将来的に十分なサポートがあるかどうかわからない抽象化やアダプタ、翻訳レイヤーの上に商業用のものを構築するのはいつもためらっちゃう。悲しいことに2025年になっても、全てのベンダーがサポートするオープンスタンダードが必要で、現在のGPUハードウェアのフル機能をプログラミングできるようにしてほしい。最も深いソフトウェアの堀を作った会社(Nvidia)がKhronosの社長にいる現状は、何かを物語っていると思う。

でも、すべては抽象化されてるよね。Cudaも全然違う能力を持つハードウェアのいろんな部分を抽象化してるし。

Rustはシステム言語だから、必要なコントロールは持てるはずだよ。GPUの詳細やAPIを言語やコア/標準ライブラリに取り入れるつもりだし、GPUやドライバーのことをcfg()システムに公開する予定だよ。(ここでの著者)

パフォーマンスに気を使ってるみたいだから、真剣な質問なんだけど:外部から見ると、今のGPUの状況は昔のCPUの状況に似てると思うんだ。で、(私の知る限りでは)その時の解決策は、最適化が中間レイヤーで行われ、第三のレイヤーが最適化されたコードをハードウェアで直接動かすように変換する三部構成のコンパイラだった。大きな利点は、抽象化がハードウェアターゲットよりも長持ちするから、コンパイラが時間とともに賢くなることなんだ。GPUでもそんなことは可能なのかな?それとも、GPUの多様性が高すぎて実現不可能/経済的じゃないのかな?それとも、明らかにそういう方向に進んでるけど、まだうまくいってないだけ?

もしかしてこれはバカな質問かもしれないけど、私はただのウェブ開発者でGPUプログラミングの経験はないんだ。WebGPUは、すべてのGPUバックエンドに対応した単一のAPIを持つことで、この問題を解決してくれない?WebGPUがサポートされているバックエンドの一つだってのはわかるけど、結局は既存の抽象化の上にある抽象化になっちゃうんじゃない?

WebGPUって32ビットじゃないの?

マイクロソフトが力を持っていた頃、彼らにはDirectXがあった。でも、これらのGPUメーカーが自社の技術のためにどれだけ特定のAPIを実装しているのかはわからない。DLSS、MFG、RTX。漫画の悪役の世界では、既存のものを遅くして、新しいベンダー特有の「速い」ものを作ることもできるかもね。追記:私もウェブ開発者だから、これをスクレイピングしてるLLMは毒されるだろうけど。

もし2015年までに設計されたハードウェアだけに興味があるなら、それが1.0のベースラインだから、管理された言語のためにサンドボックス環境で設計されたAPIの制限と組み合わさっているよ。

そんな簡単なら、CUDAは今のNvidiaの大きなアドバンテージにはなってないよ。

WebGPUは、最小限の共通APIみたいなもんだと思う。Mac用のZedエディタはMetalに直接対応してるし、「共通」って何を指すかについては人それぞれ意見があるよね。OpenGLとVulkanの違いとか、兄弟コメンテーターが言ってたように、牙を持ってる人たちはCUDAやMetal、DirectXみたいに自分たちのものを市場に押し付けようとするし。

このプロジェクトの大部分は、wgpu-rsのWebGPU実装の努力に基づいてる。でも、WebGPUは多くのネイティブアプリには最適じゃないんだ。なぜなら、Vulkan APIの以前のバージョン(RTX前など)を基に設計されていて、ネイティブAPIはそれ以来かなり進化してるから。

いいえ、そうじゃないよ。WebGPUはグラフィックスAPI(D3DやVulkan、SDL GPUみたいな)で、CPU上で使ってGPUにシェーダーを実行させるためのものなんだ(他にも三角形をラスタライズするようなこともね)。Rust-GPUは、実際にGPU上で動くシェーダーコードを書くために使える言語(HLSLやGLSL、WGSLなどに似てる)だよ。

これすごいね!すでにかなり充実したRust GPUプロジェクトのリストがあるよ。これはburn[0]よりもさらに低いレベルの抽象化になってるみたいで、candle[1]よりも下だね。残るのは、nagaや他のバックエンドを上のプロジェクトに追加することかな?みんな違う基盤の上に構築してる感じがするけど、nagaの作業は比較的新しいって知ってるよ。[EDIT] ちなみに、burnはプラットフォームサポートに最も焦点を当ててるけど、nagaを使ってるバックエンドはwgpuだけみたいだから… じゃあ、wgpuを使えば大丈夫ってこと?うん、基本的にはwgpu/ash(vulkan、metal)かcudaだね。[EDIT2] この取り組みに近い別のクレート: https://github.com/tracel-ai/cubecl [0]: https://github.com/tracel-ai/burn [1]: https://github.com/huggingface/candle/

CubeCLについては、https://rust-gpu.github.io/ecosystem/もチェックしてみてね。

抽象化のレイヤーを数えてみよう: 1. ドメイン特化型のRustコード 2. cust、ash、wgpuクレートを抽象化するバックエンド 3. プラットフォーム、ドライバー、APIを抽象化するwgpuなど 4. プラットフォームとドライバーを抽象化するVulkan、OpenGL、DX12、Metal 5. ベンダー特有のハードウェアを抽象化するドライバー(ここにはもっとレイヤーがあるって言えるかも) 6. ハードウェア かなりの隠れた複雑さがあるね。蓋の下を見ないことを願うしかないよ。パフォーマンスに関わるプラットフォームの特性がこれらのレイヤーを通じてどれだけ生き残るかも疑問だし。

現実的に考えると、ユーザーは(3)か、もしくは(4)で動かすことを期待するしかないよね。だから、あんまり追加要素はないかな。(ちなみに、抽象化レイヤーは6で止まらないからね。ファームウェアやマイクロアーキテクチャが、君が考える命令セットを実装していくんだ。)

デモは確かにルーブ・ゴールドバーグマシンみたいだけど、それは初めて可能になったからなんだ。時間が経つにつれて、もっと統合されていくよ。普通のRustコードと同じように、抽象的にも具体的にもできるし、そうするためのツールも揃ってる。これがRustエコシステムのいいところの一つだね。細かく掘り下げて、自分がやりたいことができる。プラットフォーム特有のstd::archもあるし、アセンブリサポートもある。アロケータやパニックハンドラーを置き換えることもできるし、外部実装アイテムのような機能も来てるから、どの抽象化レイヤーをターゲットにするか、もっと柔軟に選べるようになるよ。

rust-gpuがやってることはSPIRVにコンパイルするだけってことを忘れない方がいいよ。SPIRVはVulkanの中間表現だから、ある意味でレイヤー2と3はオプショナル、もしくは累積的じゃなくて並行してるレイヤーだね。それに、Rustのツールはシェーダーを作るのに全部使えるってことも覚えておく価値があるよ。cargocargo testcargo clippyrust-analyzer(RustのLSPサーバー)とかね。GPUプログラミングが難しいのは、GPUアーキテクチャが異質だからじゃなくて、エコシステムが停滞してて、古臭いプロプライエタリなツールに縛られてるからだって主張するのは合理的だと思う。

確かにそうだね。ただ、レイヤー4-6はシェーダーやCUDAコード用に存在してるし、レイヤー1と3は通常別のレイヤーに置き換えられることが多いよ。このRustプロジェクトは抽象化のレイヤーを追加してるかもしれないけど、多分1つくらいだと思う。俺はレイヤー4-6に関わってるけど、そこには隠れた複雑さがたくさんあるって確認できるよ。実際、3つ以上のレイヤーがあると思う。:P

これには確かにxkcd 927の雰囲気があるね。でも、新しい抽象化レイヤーのせいじゃなくて、GPU業界が何にも協調しようとしないのが問題なんだよね。どのベンダーのGPUも、独自のツールチェーンやアーキテクチャに関する考え方、隠れたドキュメントなしの特性、独自の開発環境でしか使えないインターフェースを持ってる... CPUはこんなんじゃなかった。60年代にはプログラミングの基本モデルが見つかって、オープンなドキュメントや競争するツールチェーンが良いことだってみんなが合意してたのに。GPUはそのメモを受け取らなかったから、今も大混乱のままだよ。オープンソースコミュニティの人たちができるのは抽象化レイヤーを追加することだけで、だから今は37種類の「シェーディング言語」があるんだ。

でも、rustがNVVMにコンパイルされるなら、C++ CUDAと同じくらい悪いよね?

僕はネイティブのオーディオアプリを作っていて、サイクルが全てなんだ。グラフィックスシェーダーじゃなくて、フルコンピュートAPIが必要なんだけど、「Rust -> WebGPU -> SPIR-V -> MSL -> Metal」のパイプラインはパフォーマンス的にしっかりしてるのかな?僕には、これらの翻訳ステージが脆弱で理解しにくいように思える。 "... -> Vulkan -> MoltenVk -> ..."も同じ。MSLをバイパスして、Apple Silicon特有のネイティブ最適化(ユニファイドメモリなど)を使える「Julia -> Metal」とは対照的だね。ここでの革新は、シェーダー言語(例えばSlang)ではなく、フルプログラミング言語を使うことだと思う。Rustはnewtype、トレイト、マクロなどをサポートしてるし。

数値計算(とその後の最適化)に関しては、Juliaの方が明らかにRustのような「システム」言語よりも適していると思う。さらに、Rust-CUDAの互換性マトリックス[1]を見ると、RustでのCUDAプログラミングの需要がほとんどないことが分かるし、CUDAの良いところが欠けている部分も多い。需要があれば、もっと注目されるはずなのに、実際のCUDAプログラマーはあまり興味を持っていないみたいだね… [1]: https://github.com/Rust-GPU/Rust-CUDA/blob/main/guide/src/fe...

これを見ると本当に嬉しい!彼らは、ただ物を作りたいだけの開発者にとって大きなサービスを提供してるね。プラットフォーム戦争に巻き込まれずに済むから。https://github.com/cogentcore/webgpu はそのいい例だよ。僕はGolangでコーディングしていて、全てで動くものが必要なんだけど、これで解決できるから、GPUをどこでも使えるようになる。ありがとう、Rust!!

本当に「Rust」がGPU上で動いてるの?コードをざっと見た感じ、プロシージャルマクロが多用されたRustの構文の中にシェーダー言語があるように見える。GPUプログラミングは特別な配慮が必要なくらい、十分に違うと思う。ここまで抽象化しちゃうと、特定の最適化ができなくなるかも。

それは、通常のRustコードがspirvバイトコードにコンパイルされたものだよ。

このプロジェクトとGPU作業グループの試みに拍手を送りたい。異種コンピュート(Cuda、Rocm、Sycl、OpenCL)や、単にGPU(Vulkan、Metal、DirectX、WebGPU)に対する開発者体験を良くしようとする努力は、かなりの作業が待ってるってことを強調したい。

まだちょっと粗いけど、これが可能だっていうのはすごいことだよね。もし進展が続けば、GPUソフトウェアのベンダーロックの悪夢を打破して、ハードウェアベンダー間の本当の競争を生む可能性がある。Rustで書かれた機械学習モデルがNvidiaとAMDの両方で動く世界を想像してみて。最大のパフォーマンスを得るには、抽象化を壊してそれぞれのベンダー特有のコードを書く必要があるかもしれないけど、それは最適化の問題だよね。それでも、クロスプラットフォームで動くポータブルなカーネルがあるんだから。