2018年2月3日土曜日

PythonとGPGPUで地獄めぐり

 結論だけ書くと、
・NVIDIA Performance Primitives (NPP) 9.1は、cannyがとてつもなく遅い。OpenCVが6msの条件で、NPPは86ms。もちろんデバイスメモリにコピーする時間は含まない。おそらくバグなので、そのうち速くなるかもしれない。
・OpenCVのUMat(OpenCL)は、モルフォロジー変換(erode / dilate)がとてつもなく遅い。OpenCLを使わないほうが倍くらい速い。
・もちろん両者をつなぎ合わせる方法はない。デバイス→ホスト→デバイスのコピーは気が遠くなるほど遅い。
・OpenCVのUMatのUMatを使いながら、モルフォロジー変換だけ自分でカーネルを書くには、C++のビルド環境が必要。
・必要なカーネルを全部自分で書くのでなければ、何をどうやってもC++のビルド環境が必要なので、Pythonで書く意味がそもそもない。
PythonでGPGPUが流行らないわけがよくわかった。NVIDIAは昔はNPPでPythonをサポートしていたらしいが、今はやめている。地獄めぐりがお好きな向きはどうぞ。

追記:まったく同じ引数(元画像の中身は異なる)で連続して2度呼び出すと、2度目は1msを切ってくる。スクラッチバッファをmallocした直後の1回だけ遅いらしい。キャッシュの関係か。

追記:CUDAを使うコードのプロファイリングにはcudaDeviceSynchronize()が必要。CUDAは(見た目はそうは見えないが)非同期で動く。

2018年2月1日木曜日

Windows上のPyCUDAのC4819を黙らせる方法

 Windowsの日本語環境でPyCUDAを使うと、cl.exeが大量にwarning C4819を吐いて鬱陶しい。そこで初期化時に以下のようにして黙らせる。

 import os  
 os.environ["CL"] = r'-Xcompiler "/wd 4819"'  

ちなみに同じ手口でcl.exe用の環境変数を設定すると便利だ。

 os.environ["INCLUDE"] = r"C:\Program Files (x86)\Windows Kits\10\include\10.0.10240.0\ucrt"  
 os.environ["Path"] += r"C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\BIN\amd64"