CUDA, C++ AMP and ROCm

Neural Networks の実装はなぜか軒並み CUDA を使っている。自分も数日前から CUDA の入門書を読みはじめた。以前 OpenCL の入門書を読んだことがあるのだけれど、GPGPU へのアプローチにどんな違いがあるのか興味が湧いたため。

そんな矢先、AMD が GPGPU 用のカード Radeon Instinct をリリースしたというニュースがあった。彼らが提供するプログラマ向けのプラットホームは Radeon Open Compute Platform (ROCm) と銘打たれ GitHub に置かれている。色々なツールがあるけれど、主要なコンポーネントは HCC というコンパイラらしい。このコンパイラから使える API は数年前に Microsoft が発表した C++ AMP と互換だそうな。

C++AMP や HPP のサンプルコードを眺めてみると、ホストのコードと GPU でうごくカーネルのコードがわかれていない。これは CUDA も同じ。OpenCL ではカーネルを別のファイルに定義し、そのカーネルからコンパイルしたバイナリを OpenCL のホスト API でロードし GPU に送る、みたいな荒々しい API だった。C++ AMP だと C++ の lambda を専用のアルゴリズム関数(並列 for みたいなやつら)に渡すだけ。あとはツールチェインがよろしくやってくれる。こりゃいいわ。

CUDA は C++ ではなく C なので若干切り口は違うけれども、やはりホストとカーネルが混在できる。このアプローチだと GPU 業者はコンパイラをまるごと提供する必要がある。ROCm は Clang を使っている。ROCm にしろ CUDA の NVCC にしろ、基本的には ホスト/カーネル混在のコードをCPU 用のコンパイラに渡す前で前処理し、カーネル部分だけ自分でコンパイルするかんじらしい。これは OpenCL よりだいぶいい。特に C++AMP の lambda を使えるところ。未来っぽい。

CUDA は今の所 lambda は使えないけれど、対応は時間の問題に見える。CUDA 自体は C API ながら NVCC は C++ も扱え、NVIDIA 自身 Thrust という CUDA 向け C++ ライブラリを提供している。

なお NN まわりでの CUDA の普及は CUDA それ自体の良さだけでなく、NVIDIA 謹製の cuDNN なるライブラリが職人的チューニングですごい速く、みなこれを使っているからという面もあるそうな。NVIDIA がんばった。積み重ねを感じる。OpenCL を勉強している場合じゃなかった。