プログラミング
Vx – 1つの言語で、あらゆるチップに対応
Vx – One Language, Every Chip (vxlang.org)
要約
Vxは、CPU、GPU、NPUなどの異種コンピューティング向けシステムプログラミング言語です。メモリの場所を型システムに組み込むことで、コンパイル時に多くのランタイムエラーを防ぎます。明示的なデータ転送とハードウェア定義に基づいたコンパイルにより、パフォーマンスと正確性を重視したコード開発を可能にします。
全文翻訳
1つの言語で、あらゆるチップに対応
Vxは、異種コンピューティングのためのシステムプログラミング言語です。CPU、GPU、NPU、アクセラレータのメモリは型システムの一部であるため、ホストスレッドがデバイスポインタを逆参照すると、深夜のセグメンテーション違反ではなく、コンパイルエラーになります。
はじめに
マニフェストを読む
GitHubでソースを見る
curl -fsSL https://vxlang.org/install.sh | sh
インストール
macOS on Apple Silicon および Linux x86_64。
その他のインストールオプション。
異種性はランタイムではなく、型システムに属します。
データの場所はその型の1部です
ほとんどの言語では、アクセラレータをインフラストラクチャとして扱います。つまり、数式を記述し、不透明な大規模ランタイムがそれをどのように配布するかを決定します。Vxでは、それをセマンティクスとして扱います。NPUの高帯域幅メモリに固定されたテンソルは、ホストDRAMにあるテンソルとは異なる型を持ち、それらの間を移動するには明示的なtransfer()が必要になります。ハードウェア境界が無料であってもです。Appleのユニファイドメモリでは、その転送はほとんど何もコンパイルされません。それでも書き留められるのは、データ局所性はバイナリをプロファイリングするのではなく、ソースを読むことで証明可能であるべきだからです。
// 既にNPUメモリに常駐している2つの行列。
fn custom_matmul(
a: Pinned<Tensor<f32, [4, 4]>, Topology::NPU[0]>,
b: Pinned<Tensor<f32, [4, 4]>, Topology::NPU[0]>)
-> Verified<Tensor<f32, [4, 4], Memory::NPU_HBM>> {
let mut result = Tensor<f32, [4, 4], Memory::NPU_HBM>::uninit();
// 計算をアクセラレータにディスパッチします。
spawn on(Topology::NPU[0]) {
for i in 0..4 {
for j in 0..4 {
result[i][j] = 0.0;
for k in 0..4 {
result[i][j] += a[i][k] * b[k][j];
}
}
}
}
return Verified(result);
}
コンパイラが除外するもの
Vxは、通常、ランタイムクラッシュ、サイレント破損、またはトレーニングステップ1200でのメモリ不足として現れるバグのクラスを型チェックに前もって組み込みます。
アドレス空間タイピング
デバイスポインタをホストから逆参照する。
Pinned<T, NPU_SRAM> がホスト式にエスケープする。
容量アドミッション
作業セットがターゲットメモリ空間に収まらない配置 — バイナリが存在する前に、宣言されたマシンに対してチェックされます。
シーム契約
非同期転送が可視化されていないバッファの読み取り。
SMTプロバーによって解決されます。
線形型
消費されたバッファの使用後移動、および分散と領域追跡を備えた借用チェッカー。
トポロジー到達可能性
宣言されたパスのない2つのメモリ空間間の転送。
自動微分
隣接が定義されていない領域での微分。
マシンは仮定されるのではなく、宣言されます。
ほとんどのコンパイラはコストモデルをハードコードしています。Vxはそれを読み取ります。マシンファイルは、実際のパーツのメモリ階層と相互接続を記述し、コンパイラはそれに対して配置を許可または拒否します。単位は正確な整数変換であり、浮動小数点数ではありません。SIプレフィックスは10進数(GB = 10^9)、IECは2進数(GiB = 2^30)です。ベンダーシートからコピーされた図は、シートが意味したことを意味します。リポジトリには、H100、H200、B200、A100、MI300X、Apple M4、およびマルチGPUノードのマシンファイルが含まれています。それぞれがソースを引用し、検証されていない図を検証されていないとマークしています。
Memory HBM {
capacity: 80 GiB,
bandwidth: 3.35 TB/s,
managed: explicit,
scope: device
}
Memory L2 {
within: Memory::HBM,
capacity: 50 MiB,
bandwidth: 12 TB/s,
managed: cached
}
Memory SMEM {
within: Memory::L2,
capacity: 228 KiB,
bandwidth: 128 B/cyc,
clock: 1.98 GHz,
replicas: 132,
granule: 1 KiB,
scope: sm
}
Topology Device {
arch: nvptx64,
memory: Memory::HBM,
transfer Memory::CPU_DRAM -> Memory::HBM : 63 GB/s,
}
コンパイル方法
データ指向の並列フロントエンド
すべてのシンボル、名前付き型、およびモノモル化されたバリアントは、フラットな256ビット識別子です。名前付き型システムと再帰型に対する必須のボクシングはモジュールを分離するため、パイプラインはクエリエンジンやロック競合なしにコア間で並列に実行されます。コンパイルは、ポインタをたどるツリーではなく、フラットな配列をウォークします。同じソースは、シリアルにビルドされても並列にビルドされても、バイト単位で同一のMLIRにコンパイルされます。これは、テストスイートで希望するのではなくアサートされます。ベンチマークスケールで、1スレッドで、4スレッドで、スレッドプールが完全にパスから外された状態で、さらにコーパスが新しいプロセスで再コンパイルされ、各実行が独自のハッシュシードを取得します。主張は、フロントエンドが発行するMLIRに関するものです。それ以降のすべてはLLVMに属します。
バックエンド
CPU (x86-64, arm64) MLIR → LLVM IR → ネイティブ、AOTまたはJIT
NVIDIA GPU MLIR → NVVM → PTX → SASS
Apple AMX / ANECoreML プライグイン経由のプリミティブディスパッチ
分散 マニフェスト駆動のリモート領域をワイヤプロトコル経由で
ベンダーは、Vxをパッチするのではなく、MLIRパスプラグインを通じてコンパイラを拡張します。
Vxが不適切なツールである場合
PyTorchユーザーはループ中にアーキテクチャを変更し、テンソルの形状を出力し、それに基づいて分岐し、続行します。Vxでは、事前にコンパイルされ、データ指向で、静的に領域化されているため、同じ動的性は実際の作業を必要とします。Vxは、10種類のシリコンで正確かつ高速でなければならないものに適した言語です。まだ検討中のものには適した言語ではありません。
ここから始める
開始方法
ツールチェーンをインストールし、最初のプログラムを実行します。
Vxツアー
1回のセッションで言語を理解する: 型、ジェネリクス、所有権。
トポロジーとメモリ
配置、転送、およびチェッカーが強制するもの。
マシンファイル
実際のパーツを記述します。その制限に対してコンパイルします。