GTC2017 - 個人的トピック

個人的トピックまとめ。

ポスター発表

今回、急遽渡米することを決めた理由がこのポスター発表。

セッションやトレーニングと並行して、GTCではGPUを用いた研究開発ネタのポスター展示が行われており、今年は約140件のポスター展示が採択されている。
このうち、プログラム委員の評価が高い20件が、S7480 - Fast Forward Poster Program for the Top 20 Posters のセッションで各々4minづつの発表を行う。さらに Top-20 の中からプログラム委員が事前に選定した5件が "Top-5 Poster Finalist" という扱いで、コンベンションセンターの正面、最も目立つ場所に掲載され、参加者がモバイルアプリ経由でどのポスターが気に入ったかを投票する。
最も票を集めたポスターには GTC2017 Poster Winner Award と副賞$5,000が贈られることになる。

今年は旅費の関係もあって元々渡米する予定はなかったので、セッション発表には申し込まず、ポスターを2枚投稿しただけだった。

このうち、SSD-to-GPUダイレクトSQL実行機能を紹介した P7130 - An intelligent storage for PostgreSQL database がTop-5に選定されたという連絡が来たのが4月29日(土)。Top-20の4分発表だけならちょっと考えたが、Poster Winner Awardの可能性があるならという事で急遽渡米準備。フライトとホテルを抑えてサンノゼに向かったワケである。

ただ、残念ながら結果は及ばず。
NVIDIA-JPの皆様からも他のゲストにご紹介頂いたり、偶然その場にいたNECのメンバに応援してもらったものの、7000人のGTC参加者の投票の結果*1、台湾の学生さんのMACHINE LEARNING領域の研究がPoster Winner Awardに選ばれた。おめでとうございます。
最終選考は一般からの投票だった訳だが、やはり応援してもらったのに結果につながらなかったというのは申し訳ない。次に機会があれば、今度はきちんとTop-1を取れるようにしたいものである。

ただ、今回ポスター発表という事で気付いた事も。GTC16, GTC15と過去2回の参加はいずれもセッション発表のみの参加で、これはある種一発勝負の要素がある。つまり、同じ時間帯に注目度の高いセッションが入っていたり、講演タイトルの"引き"がいま一つだと、わざわざ米国まで出かけて聴衆が10人くらいだとか、そういう悲しい事になる可能性も多いにある。

一方で、空き時間に人がぶらぶら眺めに来るポスターであれば、ちょっと熱心に読んでいる人がいたら『Hello, I'm author of the poster. Let me introduce our research briefly.』なんて声をかければ*2何回でもディスカッションのチャンスはあるし、場合によっては、セッションにただ参加して聞いているだけの人よりも高いレベルの認知/関心を得られるかもしれない。

来年以降、研究開発の発表を行う時には、単にセッションにプロポーザルを出すだけじゃなく、これまでリーチできなかった人の認知/関心を得るためにどういった発表の仕方がベストかもう少し考えてみた方がよさげ。例えば、ピュアな技術の部分はポスターとして、製品や事例に関してはセッションでというやり方があり得るかもしれない。

ちなみに、ポスターに申し込む時には一つ注意があり、プロポーザルを出す段階で既にポスターを作成していなければならないという事。
確か1月下旬が〆切だったが、担当のKaraさんから『ポスターのPDFが添付されてないですよ』と突っ込みがあり、ポスター2枚を大慌てで仕上げる羽目になった*3。ただ、これもちょっと考え物で、1月以降の進捗が発表に反映されないというデメリットはあるとは思う。

[idea] Visual Profiler

その他、参加したセッションの中でPG-Stromに応用が利きそうなものが二つ。
一つは Visual Profiler で、不勉強にして今まで知らなかったのだが、あるマシンでCUDAプログラムを実行し、そこでプロファイラが生成したログファイルを、別のマシンにインポートして可視化するという機能があるらしい。

確かに、CUDA Driver APIを見てみると、以下のようにプロファイラを初期化する関数の中に、出力ファイルを指定するオプションがある。

CUresult
cuProfilerInitialize(const char* configFile,
                     const char* outputFile,
                     CUoutput_mode outputMode);

今まで、PostgreSQL v9.5ベースの実装(つまりCPUパラレルなし)では、例えばデータ転送時間にしてもDMAの開始時刻/終了時刻を記録して、総転送データサイズを時間で割ってやれば、プロファイリングとして比較的直観に一致する結果が得られていた。
しかし、CPU+GPUハイブリッド並列に対応するPostgreSQL v9.6以降では、他のバックエンドとDMA転送がかち合った結果、PCIeバス使用率は高い(= 実際には10GB/sとか出る)一方で、処理時間が間延びした分転送レートが非常に低く見えてしまうという問題があった。
EXPLAIN ANALYZEで手軽に性能情報を確認できるというメリットがある一方で、CPU並列と相性が悪いというのは未解決問題であった。
であれば、細かい事は全部CUDAの実行系に任せて、PG-Stromの側でプロファイリングを頑張らないのも一つの選択肢ではないのかとも思えてきた。

実際、GPU kernel実行時間やDMA Send/Recvといった定量指標だけでなく、GPUタスクがうまい具合にキューに突っ込まれてSSDGPUを遊ばせていないかというのも非常に重要なチューニングポイントではあるが、現状のPG-Stromのプロファイラはこれをきちんと取る事ができない。

[idea] GDF(GPU Data Flame) プロジェクト

MAP-DやH2Oといった、データ解析分野でGPUを使っている人たちが始めたプロジェクトで、要は、GPU上のグローバルメモリに配置したデータをGDFに対応したアプリケーション間で交換するという規格らしい。
確かに、cuMemAlloc()で獲得したメモリ領域は、cuIpcGetMemHandle()を使って識別キーをエクスポートする事が可能で、識別キーを受け取った他のプロセスはcuIpcOpenMemHandle()を呼び出す事でその領域を自分のプロセスでも利用する事ができるようになる。
彼らのアイデアとしては、GPU上の統計解析・機械学習アプリケーションを連携させるために、毎度毎度GPU RAM⇔CPU RAM間のデータ交換は避けたいというもの。GDFの仕様に従ってデータ領域をエクスポートすれば、連携対象のアプリケーションも同じようにその領域を参照できるはずだというもの。

海外としては二つ狙いがある。
一つは、やはり開発リソース・得意分野の関係で自分たちが統計解析・機械学習のエンジンを全て自作するか??というもので、サードパーティと連携できる芽があり、さらにNVIDIAもこれを推しているなら悪くはないだろうという判断。
もう一つは、PL/CUDA関数で1GBを越えるデータサイズを扱う時に問題となっている、PostgreSQL可変長データサイズの問題を実質的にクリアできる可能性があること。

例えば、10GB程度の行列をGPUにロードすることを考える。Tesla P40であれば24GBのデバイスメモリを搭載しており、メモリの割り当て自体はそれほど大変な話ではない。しかし、PostgreSQL可変長データのサイズ制限により、これをPL/CUDAの引数として渡そうとすると、実質的には1個の行列であるにも関わらず複数の2次元配列に分割しなければならないなどの制約が生じる。
では考え方を変えて、GPUバイスメモリ上に確保したメモリ領域を、PostgreSQLからForeign Tableとして読み書きできるようにしてはどうか?
この方法であれば、一度に受け渡すデータサイズが1GBを越える必然性はないし、FDWドライバが内部的に管理するデータ構造であれば(varlena型ではないので)1GBの壁は生じない。

GPU RAM上にデータを保持するForeign Tableを使用する場合、おそらく、PL/CUDA関数への引数はregclass型を用いてForeign TableのOIDが渡るようにすべきだろう。元々データはGPU RAM上に存在していることが前提なので、これらのデータは毎回RAM⇔GPU間を転送する必要がなくなる。
残念ながらTop-20に残らなかった方のポスター(P7129)では、PL/CUDAを用いた類似化合物検索を行っているが、1GB制約に合わせるため化合物データ1000万件(1.5GB)を4分割してPL/CUDA関数に与えている。しかし、予め化合物データがGPU側にロードされていれば、呼び出しのたびに2次元配列をセットアップする必要はなくなり、大幅に統計解析処理の効率が上がるだろう。

ここ最近の一連の開発で学んだのは、統計解析・機械学習のワークロードにおいては何がしかの前処理は必ず必要になるため、GPU RAMと関連付けられたForeign Tableに対して SELECT ... INTO fdw_table FROM transaction_table するというのは、どうやらユーザの負担を大きく増やすという性質のものではなさそうだという点。
生データからサマリを作ったり、前処理を行うというのはPG-Stromの得意とするところなので、これをPL/CUDAと組み合わせるための良い閃きが得られたと思っている。

[idea] 機械学習でのSSD-to-GPUダイレクトの利用

ポスターの発表に関連して、『これは機械学習のデータロードに使えませんかね?』と、以前にSSD-to-GPUダイレクトをブログで書いた時に頂いたのと全く同じ反応を、しかも複数の方から頂いた。
時間が取れないこともありペンディングになっているが、それほど難しい話ではないので、もう一度真面目に検討してみないと…。

[idea] CUDA MPSの利用

Tesla V100とCUDA9.0の発表に関連して、MPSの機能拡張によって、SMに空きがあるときはどんどんGPU kernelを放り込んでいけるようになるという説明があった。
現状、PostgreSQL v9.6に対応したバージョンはMPSと同じような機能を実現するバックグラウンドワーカを使っているが、こういった機能強化を取り込むためにも、できるだけ標準的なソフトウェアスタックの上に構築したいという思いはある。
現状、MPSだとストリームにコールバックを突っ込む事ができない。ここを何とかカバーする方法があれば、、、、という事で要検討。

*1:投票率は知らないがw

*2:なお、話しかけた相手が日本人だと若干気まずい。

*3:自業自得である