本当は怖いHPC

HPC屋の趣味&実益ブログ

UCXを試す日記(10):バグ報告をした

自分でプログラムを書いていてハマったのでTwitterに(日本語で)グチグチ書いていたところ、中の人(たぶんORNL)の人から「バグ報告しなよ」と背中を押してもらいました。

ということで、Issueを作成。

github.com

中の人が修正するPRを作ってくれたのだが…いまいち会話が噛み合っていないので、自分で直したほうが良さげな感じもしつつ…

github.com

引き続きコードを読んでいきます

続報:直してもらいました

UCXを試す日記(9):allreduceを実装する上での予備調査

とりあえず、UCXで実用(?)コードを書いてみようということで、Allreduceを書いてみようと思っています。Allreduceは、ディープラーニングにおいては重要な通信パターンで、業務においても研究したことがあるので経験があります(これについては、近々会社のブログの方で発表できると思います)。

Allreduceを実装するにはいくつかのポイントがあることがわかっていますので、これを先に調査しておきます。

send/recv通信として, bcopyzcopy のどちらを使うか

いわゆる普通のsend/recvを実現する手段としては、bcopyzcopyがあります。bcopyzcopyの違いはわかりにくいですが、このページによると、

  • bcopy:転送を直ちに開始するか、失敗かの2通りの結果しかない。失敗とは、sendするローカル側のリソースが不足している場合で、UCS_ERR_WOULD_BLOCKが返される。この場合、Endpointの作成時にUCT_FLAG_PENDINGとコールバックを設定しておくと、リソースが利用可能になった時点でこのコールバックが呼ばれる
  • zcopybcopyの動作に加えて、 UCS_INPROGRESS を返すことがある。この場合、通信は非同期に行われ、完了時に uct_ep_am_zcopyの引数に指定したコールバックが呼ばれる。

ということで、非同期通信モデルである zcopy が良さそうです。気になるのは、bcopyのメモリコピーに関する動作がはっきり書いていないところです(bが何を意味するのかよくわからない)。zcopyzはZeroだろうと思われるので、逆に考えるとbcopyはゼロコピー性は保証されていないのかな…?ソースを読む必要がありそう

通信の順序が保証されるか?

MPIおよびInfinibandでは、通信の到着順は保証されています。これが入れ替わってしまうと、Ring-Allreduceが成り立たないので注意が必要です。下のレイヤがInfinibandであれば自動的に(事実上)保証されることになるでしょうが、APIとしての保証がない場合、例えば下のレイヤをTCPに変えたら動作が変わって動かなくなる、みたいなことになりそうなので注意が必要ですね。

UCTとUCPのどちらを使うか?

UCXには、通信を実現するAPIのレイヤとして UCPUCTがあります。UCTは、固有のAPIに近い、薄いレイヤを提供するので、特定の機能がサポートされているかどうか、などのフラグによる分岐をユーザーが書く必要があります。一方でUCPは上位の機能を実現するレイヤでタグマッチングなどが実装されています。インターフェースがサポートしない機能はエミュレーションするように実装されているようなので、便利そうではあります。

その場合、 * UCPのオーバーヘッドはどれくらいか? * UCPのエミュレーション機能は、現段階でどれくらい実装されているのか * UCPのみで実現されている機能が必要か?

ということだけど…

以上の点を調査する必要がありそうですが、とりあえずInfinibandを前提にした高速な実装を目指そうと思うので、これらの調査は先送りしようと思います。

Travis CI上で、g++とclang++の複数バージョンでビルドする

C++でライブラリを作っていて、それをTravisCI上でテストします。そのとき、GCCとClangの両方でテストしたっかったのですが、いろいろ面倒だったのでメモです。

基本的には、Travis CIのmatrixという機能を使って様々なバージョンのコンパイラを使ったテストを独立・並行に立ち上げることができます(GCCとClangの複数バージョンをテストしたいので、単にcompiler を設定するだけでは不足です)。

以下が面倒なポイントです

  • GCC, Clangのそれぞれについて、バージョンに応じたリポジトリを追加・パッケージを入れる必要がある
    • GCC: apt / source に、 ubuntu-toolchain-r-test を加える
    • Clang: それに加え、3.8 までと 3.9 以降で追加リポジトリが違う。Clangのバージョンに応じて llvm-toolchain-precise-X.Yもしくは llvm-toolchain-trusty-X.Yを加える
  • Clangの注意:
    • C++11/14以降を使うためにはlibc++が必要なので、 libc++-dev, libc++abi-dev をインストールする
    • C++で書かれた依存ライブラリが必要な場合は、それも libc++ でビルドする必要がある。(C++ のABIが違うので)。aptパッケージなどのビルド済みバイナリは使えない
    • -stdlib=libc++CMAKE_CXX_FLAGS に加えた状態でビルド

といったあたりがややこしいポイントです。

自分が現在開発しているucx-playgroundというライブラリでは、以上の試行錯誤を全部詰め込んだ結果、無事に動きました(ライブラリというよりは実験コード置き場ですが)

GitHub - keisukefukuda/ucx-playground

Travis CI - Test and Deploy Your Code with Confidence

そのときに使った .travis.yml は、

ucx-playground/.travis.yml at d4102355079e3998e16977369076166afa5526cf · keisukefukuda/ucx-playground · GitHub

これです。リポジトリ内にある travis/gen_yaml.py というPythonスクリプトで自動生成しています。

【広告】