背景
CUDA Driver API を python からぺろっと叩きたい.
pybind11 とか cfffi だとネイティブコードのビルドが必要になりめんどい. pure python(標準 python 機能)でやりたい(CI ビルドとかだと CUDA SDK インストールとかめんどい)
ctypes を使います.
CUDA Driver API(ドライバが入っていれば使える API)を想定します.
CUDA Runtime API(CUDA SDK or ランタイムのインストールが必要になる)は扱いません(API 面倒いし)
動かす Kernel は PTX 形式で生成されているものとします.
python で CUDA を叩くことで, たとえば PTX コードをテンプレートにしておいて, python 側で動的に書き換えてコンパイル(ターゲット GPU に合わせて最適なパラメータを設定)するとかができるようになります.
Clang で CUDA コードを NVPTX に変換するメモ
https://qiita.com/syoyo/items/4e60543aded0210fde49
dll/so のありか
Windows
C:\Windows\System32\nvcuda.dll
通常は nvcuda.dll
だけで良い
(CUDA は NVIDIA driver インストールすれば自動で入っているので, ロードできなかったら NV GPU が挿さっていない PC(e.g. Intel 内臓/Xe or AMD GPU) であろう)
Linux(Ubuntu)
Ubuntu ですと /usr/lib/x86_64-linux-gnu/
あたりにあります.
さわりだけ
from ctypes import *
cu = cdll.LoadLibrary("/usr/lib/x86_64-linux-gnu/libcuda.so")
print(cu)
ret = cu.cuInit(0)
assert ret == 0 # CUDA_SUCCESS
ver = c_int()
ret = cu.cuDriverGetVersion(byref(ver))
assert ret == 0 # CUDA_SUCCESS
print("CUDA version", ver)
CUDA version c_int(11020)
Voila!
ポインタのところは byref
を使うといいようです.
あとはいろいろ API 呼び出していけば OK のはずです!
その他
PTX Compiler API
PTX Compiler API のメモ
https://qiita.com/syoyo/items/cfaf0f7dd20b67cc734e
static lib しか提供されていないので, 一旦なんらかの dll を作る必要がありますが, これによりドライバにある PTX compile では満足できない場合, クライアントサイドでの PTX compile も pure Python でできるようになります!
Runtime API
cuSparse など, runtime API の上に作られたライブラリを使いたいときもあります.
一応だいたいの dll/so は再配布可能なので,
必要であれば自身のアプリに同梱するなどして対応しましょう
(e.g. CI 環境で毎回 CUDA SDK インストールとかめんどい)
TODO
- numpy との連携を考える(Python buffer protocol で連携になるかしらん)