読者です 読者をやめる 読者になる 読者になる

その手の平は尻もつかめるさ

ギジュツ的な事をメーンで書く予定です

CUDAで特定の条件に合致したGPUのIDを持ってきたい

CUDA

CUDAで,特にマルチGPUプログラミングなどをやっておりますと,特定の条件に合致したGPUのIDを持ってきたいという要求に高確率でぶち当たる事となると存じます.俺はぶち当たる.


GPUマザーボードに5枚刺さっていて,そのうち4枚は映像のアウトプット端子がないGPGPU専用の板で,残る1枚は映像を出力するためだけの貧弱なボード,という構成のサーバはこの世の中少なくありません *1
そうした構成の時に,不慮の事故によりcudaSetDevice()によってGPGPU専用のグラボではなく映像出力専用の貧弱な板がアサインされてしまったばかりにパフォーマンスが死ぬほど落ちて死ぬ,というのは割とよくある事例であります.そうした事故は未然に防がなくてはなりません.


原因を考えてみましょう.
なぜこういう悲しい事故が起こるかと言うと,cudaSetDevice()に食べさせるGPU IDをハードコードしているからこういう事が起こるわけです.
GPUのIDはハードウェアの構成が変わるとそれと共に変化します (あと良くわからんけどこの前マシンをリブートしたらIDが変わってハマった,ふざけんな).
つまり,書いたプログラムを違う環境に持って行くと動かなくなったりパフォーマンスが下がる可能性が出てくるわけですね.
GPU IDをハードコードしてはならない.


で,どうするかと言うと,

こういう感じのプログラムを書くことで解決を試みています.
cudaGetDeviceCount()GPUボードの数を持ってきて,それをもとに全部のGPUボードを舐めつつcudaGetDeviceProperties()GPUのプロパティを引き出し,そのプロパティのデータを使って条件と一致するボードかどうか (今回はボードの名前) を見てやるという感じですね.
基本的にcudaGetDeviceProperties()で取れるcudaDeviceProp構造体はボードのほとんどの情報を持ってるので,これを使えば大体なんとかなります.


こういう感じで持ってきたIDをcudaSetDevice()に渡してやると事故が起きなくて便利.

追記

つらい

*1:とは言え,「GPUなのに映像出力できないとはけしからん!!」と怒る怖い人がいるので,最近ではGPGPU専用の板でも映像を出力できたりします