InfiniBandカードを使って分子動力学計算エンジンnamdを動かしてみる
手元にMHGH28-XTC (現物はHP「HP IB 4X DDR PCI-e DUAL PORT HCA」なOEM製品)がある。ConnectX系でDDR(20Gbps)な製品。
このInfiniBandカードを2台のマシンの載せて、ノード間通信を高めての並列計算を行ってみた。
過去記事 ib160820
ib/OpenSM ib/IPoIB ib/NFS
ib/ubuntu
まず、InfiniBandカードを計算マシンに刺し込み認識させる。
InfiniBandカード †
InfiniBandカードを差し込んで起動すると lspci にて下記のように認識される(下記はCentOS 7の場合)
[root@e ~]# yum install pciutils
[root@e ~]# lspci -vv
:
05:00.0 InfiniBand: Mellanox Technologies MT25418 [ConnectX VPI PCIe 2.0 2.5GT/s - IB DDR / 10GigE] (rev a0)
:
LnkCap: Port #8, Speed 2.5GT/s, Width x8, ASPM L0s, Exit Latency L0s unlimited, L1 unlimited
:
LnkSta: Speed 2.5GT/s, Width x4, TrErr- Train- SlotClk- DLActive- BWMgmt- ABWMgmt-
:
[root@e ~]#
2.5GT/sのGen1で繋がって、x8で行けるのに、、2.5GT/s x4に減ってる....
カーネルモジュールは
[root@e ~]# lsmod |egrep "^ib_|_ib$|mlx"
mlx4_core 293672 0
[root@e ~]#
mlx4_coreのみロードされている。そしてもう一台のマシンにもカードを刺し込み認識させる
通信方法 †
InfiniBandカードを使う際、「InfiniBandプロトコルを使う」と「IPoIBかmlx4_enでTCPプロトコルを使う」があるそうな。
後者は既存のTCPに対応したアプリがそのまま使える。
前者はそれ向けのアプリを別途用意する必要がある。ここではInfiniBandで通信させて計算を行ってみる。
っが、いきなり計算させるのでは良くないので、段階的に進める。
まずは、InfiniBandによる簡単な通信テストを行ってみる。「libibverbs-utils」パッケージを使います。
準備:infinibandパッケージをインストール †
CentOS6の時は「yum groupinstall "Infiniband Support"」で必要なパッケージがインストールされたが、
CentOS 7ではそのパッケージグループが見当たらない。
だが、よく調べると"Infrastructure Server"パッケージグループの中に含まれているようだ
[root@e ~]# yum groupinfo "Infrastructure Server"
読み込んだプラグイン:fastestmirror
Loading mirror speeds from cached hostfile
* base: ftp.riken.jp
* extras: ftp.riken.jp
* updates: ftp.riken.jp
Environment Group: インフラストラクチャサーバー
Environment-Id: infrastructure-server-environment
説明: ネットワークインフラストラクチャのサービスを動作させるサーバーです。
Mandatory Groups:
+base
+core
Optional Groups:
(略
+infiniband <-------------- これ
(略
[root@e ~]#
なので
[root@e ~]# yum groupinstall infiniband
[root@e ~]# reboot
としてパッケージをインストール。もう一台のマシンにもインストールします。
opensm †
InfiniBand通信においてたとえ二点間通信であっても「OpenSM」は必要で、
片方のマシンにopensmをインストールして、自動起動させて起きます。
[root@e ~]# yum install opensm
[root@e ~]# systemctl enable opensm
[root@e ~]# systemctl start opensm
デバイス確認 †
「yum groupinstall infiniband」でインストールされた「libibverbs-utils」パッケージのプログラムで再度物理デバイス確認を行う
[root@e ~]# ibv_devices
device node GUID
------ ----------------
mlx4_0 001a4bffff0c52d8
[root@e ~]#
[root@e ~]# ibv_devinfo
hca_id: mlx4_0
transport: InfiniBand (0)
fw_ver: 2.9.1000
node_guid: 001a:4bff:ff0c:52d8
sys_image_guid: 001a:4bff:ff0c:52db
vendor_id: 0x02c9
vendor_part_id: 25418
hw_ver: 0xA0
board_id: HP_09D0000001
phys_port_cnt: 2
port: 1
state: PORT_ACTIVE (4)
max_mtu: 4096 (5)
active_mtu: 4096 (5)
sm_lid: 1
port_lid: 1
port_lmc: 0x00
link_layer: InfiniBand
port: 2
state: PORT_DOWN (1)
max_mtu: 4096 (5)
active_mtu: 4096 (5)
sm_lid: 0
port_lid: 0
port_lmc: 0x00
link_layer: InfiniBand
[root@e ~]#
ここではInfiniBandカードの1ポート目で互いをDDRケーブルで繋げている。一応「PORT_ACTIVE」なので相互には繋がっているみたい。
通信テスト †
簡単な通信テストです。
2台のどちらかをサーバと見立て
[root@s ~]# ibv_rc_pingpong -d mlx4_0 -i 1
と待ち受けモードにする。「-d」はデバイスで「mlx4_0」、「-i」はポート番号を示す。
もう片方のクライアントとなるマシンにて
[root@e ~]# ibv_rc_pingpong -d mlx4_0 -i 1 192.168.0.7
と相手方を指定すると
1
2
3
4
5
6
| [root@e ~]# ibv_rc_pingpong -d mlx4_0 -i 1 192.168.0.7
local address: LID 0x0001, QPN 0x00020b, PSN 0x6fd472, GID ::
remote address: LID 0x0002, QPN 0x00020d, PSN 0xc64b6e, GID ::
8192000 bytes in 0.02 seconds = 2988.83 Mbit/sec
1000 iters in 0.02 seconds = 21.93 usec/iter
[root@e ~]#
|
と値が帰ってくる。
値が気になりますが、ここはInfiniBandで通信ができたとだけ認識すればいい。ただ相手先指定にIPを使っているのが気に食わないかもしれない。その際は、infiniband-diags パッケージにある ibping を使って確認すれば宜しいかと。
[root@e ~]# yum install infiniband-diags
2台に共に「infiniband-diags」をインストールします。
サーバ側で「Port GUID」を確認して ibping 待ち受けモードで起動します。
[root@s ~]# ibstat
CA 'mlx4_0'
CA type: MT25418
Number of ports: 2
Firmware version: 2.9.1000
Hardware version: a0
Node GUID: 0x001a4bffff0c625c
System image GUID: 0x001a4bffff0c625f
Port 1:
State: Active
Physical state: LinkUp
Rate: 20
Base lid: 2
LMC: 0
SM lid: 1
Capability mask: 0x02590868
Port GUID: 0x001a4bffff0c625d
Link layer: InfiniBand
Port 2:
State: Down
Physical state: Polling
Rate: 10
Base lid: 0
LMC: 0
SM lid: 0
Capability mask: 0x02590868
Port GUID: 0x001a4bffff0c625e
Link layer: InfiniBand
[root@s ~]#
[root@s ~]# ibping -S
そして、サーバ側でクライアントと繋がっている「Port GUID」は「0x001a4bffff0c625e」なので
クライアント側で
[root@e ~]# ibping -G 0x001a4bffff0c625d
とします。すると
Pong from s.sybyl.local.(none) (Lid 2): time 0.238 ms
Pong from s.sybyl.local.(none) (Lid 2): time 0.270 ms
Pong from s.sybyl.local.(none) (Lid 2): time 0.270 ms
Pong from s.sybyl.local.(none) (Lid 2): time 0.269 ms
Pong from s.sybyl.local.(none) (Lid 2): time 0.271 ms
^C
--- s.sybyl.local.(none) (Lid 2) ibping statistics ---
5 packets transmitted, 5 received, 0% packet loss, time 4203 ms
rtt min/avg/max = 0.238/0.263/0.271 ms
[root@e ~]#
:
なpingと同じ感じでinfinibandの通信確認が取れます。
openmpiのインストール †
*当初 infiniband向けに新たにopenmpiを拵える必要があると思っていたが、OS提供のopenmpiで大丈夫みたい
2台共にopenmpiをインストールします
[root@e ~]# yum -y install openmpi
[root@s ~]# yum -y install openmpi
片方だけで十分なのだが、プログラムをコンパイルするために開発環境とopenmpi-develをインストールします。
[root@e ~]# yum groupinstall "Development Tools"
[root@e ~]# yum -y install openmpi-devel
2点間の通信速度ベンチマーク †
OSU Micro-Benchmarks
を使って openmpi による2点間の速度を計測してみた。
まずはベンチマークソフトの調理
[illya@e ~]$ curl -O http://mvapich.cse.ohio-state.edu/download/mvapich/osu-micro-benchmarks-5.3.1.tar.gz
[illya@e ~]$ gzip -cd osu-micro-benchmarks-5.3.1.tar.gz | tar xf - && cd osu-micro-benchmarks-5.3.1/
[illya@e osu-micro-benchmarks-5.3.1]$ export PATH=/usr/lib64/openmpi/bin:$PATH
[illya@e osu-micro-benchmarks-5.3.1]$ export LD_LIBRARY_PATH=/usr/lib64/openmpi/lib:$LD_LIBRARY_PATH
[illya@e osu-micro-benchmarks-5.3.1]$ ./configure CC=mpicc CXX=mpicxx && make
完成したら、インストールせずそのまま使います。
注意
実行者のリソース制限を解除する必要があるかもしれません。下記のようにlimits.confを修正する必要があるかも。
関連するサイトに実施します
[root@e ~]# vi /etc/security/limits.conf
(略
* hard memlock unlimited
* soft memlock unlimited
[root@e ~]#
その後で、この設定を反映させるためにログアウトして、ログインしなおします。
[illya@e ~]$ ulimit -l
unlimited
[illya@e ~]$
[illya@e ~]$ cd osu-micro-benchmarks-5.3.1/mpi/pt2pt
[illya@e pt2pt]$ mpirun -np 2 -H s,e -mca btl openib,sm,self osu_bw
# OSU MPI Bandwidth Test v5.3.1
# Size Bandwidth (MB/s)
1 3.54
2 6.90
4 13.22
8 27.42
16 56.11
32 87.07
64 190.69
128 238.28
256 366.12
512 497.99
1024 607.38
2048 672.99
4096 727.61
8192 756.79
16384 804.46
32768 816.01
65536 821.30
131072 823.61
262144 824.87
524288 825.65
1048576 825.94
2097152 826.11
4194304 826.20
[illya@e pt2pt]$
[illya@e pt2pt]$ mpirun -np 2 -H s,e -mca btl tcp,self osu_bw
# OSU MPI Bandwidth Test v5.3.1
# Size Bandwidth (MB/s)
1 0.39
2 0.78
4 1.55
8 3.08
16 5.02
32 12.51
64 21.95
128 40.84
256 65.16
512 91.80
1024 24.57
2048 107.78
4096 31.44
8192 114.92
16384 116.38
32768 117.19
65536 116.20
131072 117.07
262144 117.43
524288 117.55
1048576 117.59
2097152 116.63
4194304 117.67
[illya@e pt2pt]$
後者は一般的なGiga通信でのBandwidthで1000Mbps(125MB/sec)の上限だろうか、
前者は 826.20MB/sec = 6609.6Mbps で 6.6Gbps 。DDRの20Gbps(実際には16Gbps)には程遠い。InfiniBandカードの認識が「x4」だからかも。
perftest †
別に openmpi を持ち出さなくてももっと簡便なベンチ測定もできる。
いずれInfiniBand経由のopenmpiを実施する予定だったから用いただけである
IB Performance Testsなる「perftest」を使う。InfiniBandで繋がった2つのマシンにこれをインストールして
サーバ側と看做す側で
[illya@s ~]$ ib_read_bw
************************************
* Waiting for client to connect... *
************************************
と待ち受け状態にして、クライアント側でサーバ側を目掛けて要求を出す。
[illya@e ~]$ ib_read_bw s -F --report_gbits
(略
#bytes #iterations BW peak[Gb/sec] BW average[Gb/sec] MsgRate[Mpps]
65536 1000 787.30 782.17 0.012515
[illya@e ~]$
Bit表記(--report_gbits)にしても
#bytes #iterations BW peak[Gb/sec] BW average[Gb/sec] MsgRate[Mpps]
65536 1000 6.54 6.54 0.012481
と以前の半分である。参照ib160820/IPoIB/Performance。恐らくPCIeとの接続が「x4」であるからだろう。
qperf †
こちらもベンチマークアプリ。
サーバ側と看做す側で
と待ち受け状態にして、クライアント側から
[root@e ~]# qperf s rc_rdma_read_bw
rc_rdma_read_bw:
bw = 818 MB/sec
[root@e ~]# qperf s rc_rdma_write_bw
rc_rdma_write_bw:
bw = 821 MB/sec
[root@e ~]#
と実施する。実施可能な項目は「qperf --help tests」で参照
NAMD計算 †
っで、目的であったInfiniBandを使ったNAMD計算。
NAMDのバイナリはnamdに記載されているダウンロード場所でLinux-x86_64-ibverbs-smpを入手します。
それを計算機から共通に参照できる場所に配置して(例:/Appl)、PATH環境変数に加えます。
使用した計算機は4core/8threadsマシンが2台。っで、4threads/1rankで、合計16threadsで計算させた
[illya@c apoa1]$ charmrun ++ppn 4 ++p 16 ++nodelist list `which namd2` apoa1.namd
NAMD-CUDA計算 †
欲をだしてCUDAで計算を行わせてみた。NAMDの配布元のLinux-x86_64-ibverbs-smp-CUDAにバイナリを交換した。
CUDAを手持ちのQuadro K600とGeForce GT 710でしたら、
[illya@c apoa1]$ charmrun ++ppn 4 ++p 16 ++nodelist list `which namd2` apoa1.namd
Charmrun> scalable start enabled.
Charmrun> IBVERBS version of charmrun
Charmrun> started all node programs in 1.316 seconds.
Converse/Charm++ Commit ID: v6.7.0-0-g46f867c-namd-charm-6.7.0-build-2015-Dec-21-45876
Warning> Randomization of stack pointer is turned on in kernel, thread migration may not work! Run
'echo 0 > /proc/sys/kernel/randomize_va_space' as root to disable it, or try run with '+isomalloc_sync'.
Charm++> scheduler running in netpoll mode.
CharmLB> Load balancer assumes all CPUs are same.
Charm++> Running on 2 unique compute nodes (8-way SMP).
Charm++> cpu topology info is gathered in 0.010 seconds.
Info: Built with CUDA version 6000
Did not find +devices i,j,k,... argument, using all
FATAL ERROR: CUDA error All CUDA devices are in prohibited mode, of compute capability 1.0,
unable to map host memory, too small, or otherwise unusable. on Pe 2 (e.sybyl.local device 0)
------------- Processor 2 Exiting: Called CmiAbort ------------
Reason: FATAL ERROR: CUDA error All CUDA devices are in prohibited mode, of compute capability 1.0,
unable to map host memory, too small, or otherwise unusable. on Pe 2 (e.sybyl.local device 0)
FATAL ERROR: CUDA error All CUDA devices are in prohibited mode, of compute capability 1.0,
unable to map host memory, too small, or otherwise unusable. on Pe 1 (e.sybyl.local device 0)
FATAL ERROR: CUDA error All CUDA devices are in prohibited mode, of compute capability 1.0,
unable to map host memory, too small, or otherwise unusable. on Pe 5 (e.sybyl.local device 0)
FATAL ERROR: CUDA error All CUDA devices are in prohibited mode, of compute capability 1.0,
unable to map host memory, too small, or otherwise unusable. on Pe 7 (e.sybyl.local device 0)
Charmrun> error on request socket to node 'e'--
Socket closed before recv.
[illya@c apoa1]$
とだめでした
あっ、単に「++device」の指定忘れかな...