UbuntuでInfinibandクラスタを作る

今までRedHatLinux + OFEDパッケージでInfinibandを使うことが多かったが、Ubuntu 12.04 + 基本パッケージでどこまでできるかやってみた。InfiniBand HCAはMellanoxのConnectX-3。カーネルは3.5.0-23-genericで、ドライバ類はカーネル標準の物を利用する*1

結論から言えば、基本的に基本パッケージだけでInfinibandが動く環境を作ることができる。ただし、Ubuntu 12.04に含まれるlibmlx4パッケージはConnectX-3に対応していないので、ここだけは12.10のパッケージを持ってきてしのいだ*2。したがって、12.04でも新しめのHCAを使わない場合や、12.10では何の問題もなく動くだろう。

まず、/etc/modulesにとりあえず必要そうなモジュールを追加して、それぞれをmodprobeしておく。

# For Infiniband
mlx4_ib
rdma_ucm
ib_umad
ib_uverbs
ib_ipoib

基本的な動作確認とMPI実行環境が必要であれば、ibverbs-utils、infiniband-diags、perftest、openmpi1.5-binあたりをインストールする。コンパイル環境が必要なノードには、これらに加えてopenmpi1.5-dev、gcc、gfortran、g++あたりをインストールする。

冒頭に書いた通り、12.10のlibmlx4をダウンロードして、インストールする。

$ curl -O http://us.archive.ubuntu.com/ubuntu/ubuntu/pool/universe/libm/libmlx4/libmlx4-1_1.0.4-1_amd64.deb
$ sudo dpkg -i libmlx4-1_1.0.4-1_amd64.deb

ibv_devinfoやibstatでHCAが見えているか確認する。

OpenSMをどこか最低1台のノードで起動する。おそらく自動起動になっているので、一度Infinibandの設定が済めば、後はこの作業は不要。

/etc/init.d/opensm start

OpenSMとのネゴシエーションに成功すれば、ibv_devinfoでポートの状態がPORT_ACTIVEになるはず。あとはibpingやib_write_bw、ib_read_bwあたりでノード間の疎通や性能を確認する。

node1 $ sudo ibping -S

node2 $ sudo ibping <node1のLID>

必要ならIPoIBの設定もやっておく。/etc/network/interfacesにib0の設定を加える。デフォルトではdatagramモードで動くが、connectedモードにしてもよいかも。

# IPoIB network interface
auto ib0
iface ib0 inet static
address 192.168.250.1
network 192.168.250.0
netmask 255.255.255.0
broadcast 192.168.250.255

最後にOpen MPIの動作を確認する。まず、FAQだけど、memlockの制限をunlimitedにしないと動かない。安直には/etc/security/limits.confに次の行を追加すればよい。SSHがPAMの設定を参照してくれるので、SSH経由でプロセスを起動してもちゃんとmemlockがunlimitedに設定される。Ubuntu 12.04は大丈夫だったけど、これだけでダメな場合は、/etc/ssh/sshd_configのUsePAMの設定を確認すること。

* soft memlock unlimited
* hard memlock unlimited

あとは、適当なMPIプログラムを動かしてみる。

$ mpirun --mca btl openib,self -np 20 -hostfile hostlist ./a.out

*1:ちなみに、最近のOFED 3.x系ではOFED 1.5.x系とは異なりドライバは含まれない。

*2:詳細はここを参照。ibv_devinfoを実行すると「libibverbs: Warning: no userspace device-specific driver found for /sys/class/infiniband_verbs/uverbs0」というメッセージが出て動かない。