PGIコンパイラによる Open MPI の使い方(Linux only)

対象 Open MPI PGIコンパイラ デバッグ方法 プロファイル Linux

 PGI 16.1 以降に、PGI Compilers for Linux 64bit に付属している Open MPI ライブラリの使用方法を説明します(なお、32bit 環境用は付属しておりません)。この Open MPI は、MPI-3 規格に準拠したライブラリで、CUDA-aware Open MPI として実装しております。ここでは、主に PGIコンパイラをインストールしてある「一つのシステム」上のマルチコアを利用した MPI 並列処理を行う場合の構成の方法を説明します。PGI Professional Node-locked (旧 PGI Workstation/Server) 製品にバンドルされた Open MPI は、コンパイラをインストールしたシステム内のみで MPI 実行ができる構成となっております。PGI Professional Network floating x64 Linux (旧PGI CDK) ライセンスの場合は、クラスタシステム全体で MPI の実行が可能となるように構成されます。
2019年2月8日更新

PGIコンパイラの MPI ライブラリ総括ページはこちらへ

 CUDA-aware Open MPI は、MPIライブラリが直接、GPUバッファへの send / receive を行うことができる機能を有します。CUDA ソフトウェアが実装されていない環境でも動作しますが、この場合はシステム内に Infiniband Verbs のライブラリの実装と実行時に CUDA シェアードライブラリの呼び出し無効化が必要となります。以下は Open MPI ホームページの CUDA-aware に関するページを示します。

PGI 19.1 リリースノート追記
PGI 19.1(64bit)から Open MPI 3.1.3 バージョンをバンドルしました。

PGI 18.1 リリースノート追記
PGI 18.1(64bit)から Open MPI 2.1.2 バージョンをバンドルしました。

PGI 16.5 リリースノート追記
PGI 16.5(64bit)から Open MPI 1.10.2 バージョンをバンドルしました。このバージョンは、NVIDIA GPUDirectをサポートする機能を含みます。GPUDirect は、CUDA 7.0 以降が必要とされます。また、64-bit linux86-64 MPI の各メッセージは2GB 以内のサイズに制約されます。NVIDIA GPUDirect は、InfiniBand ハードウェアのサポートに依存するため、システム上でこれがサポートされている場合、InfiniBand ハードウェアを使用できるように構成しておく必要があります。なお、InfiniBand support は、OFED 3.18 以降のバージョンを必要とします。

提供する CUDA-aware Open MPI を動作させるための必要要件

 Infiniband Verbs のライブラリ(libibverbs)の実装が必須です。以下のコマンドでlibibverbs.soが存在するか確認して下さい。一般的に、このライブラリは InfiniBand 用のミドルウェア(OFED等)や NVIDIA CUDA ソフトウェアをインストールする時に実装されますが、存在しない場合は、明示的にインストールして下さい。

(CentOS/RHEL7.6)
$ ls -l /usr/lib64/*ibverbs*
lrwxrwxrwx 1 root root    15  2月  5 12:44 /usr/lib64/libibverbs.so -> libibverbs.so.1*
lrwxrwxrwx 1 root root    22  2月  5 12:26 /usr/lib64/libibverbs.so.1 -> libibverbs.so.1.1.17.2*
-rwxr-xr-x 1 root root 97200 10月 31 05:10 /usr/lib64/libibverbs.so.1.1.17.2*
あるいは、実装方法の違いにより場所が異なる場合もあります。
$ ls -l /lib64/*ibverbs*
lrwxrwxrwx 1 root root    15  2月  5 16:24 /lib64/libibverbs.so -> libibverbs.so.1*
lrwxrwxrwx 1 root root    22  2月  5 15:56 /lib64/libibverbs.so.1 -> libibverbs.so.1.1.17.2*
-rwxr-xr-x 1 root root 97200 10月 31 05:10 /lib64/libibverbs.so.1.1.17.2*
(Ubuntu18.04)
$ ls -l  /usr/lib/x86_64-linux-gnu/libibverbs*
lrwxrwxrwx 1 root root    15 11月 29 22:08 /usr/lib/x86_64-linux-gnu/libibverbs.so -> libibverbs.so.1
lrwxrwxrwx 1 root root    22 11月 29 22:08 /usr/lib/x86_64-linux-gnu/libibverbs.so.1 -> libibverbs.so.1.1.17.1
-rw-r--r-- 1 root root 88112 11月 29 22:08 /usr/lib/x86_64-linux-gnu/libibverbs.so.1.1.17.1

 libibverbsライブラリは、以下のリソースから rpm ファイルをダウンロードして実装して下さい。libibverbs-1.1 以上が必要です。

 なお、Ubuntu の場合、apt-get install libibverbs-dev でインストールできます。

 # rpm -qpl lib64ibverbs1-1.2.1-3.mga7.x86_64.rpm (ソースパッケージの rpm を使った場合)
/usr/lib64/libibverbs.so.1
/usr/lib64/libibverbs.so.1.0.0
/usr/share/doc/packages/libibverbs1
/usr/share/doc/packages/libibverbs1/AUTHORS
/usr/share/doc/packages/libibverbs1/COPYING
/usr/share/doc/packages/libibverbs1/README

# rpm -ivh libibverbs1-1.1.7-4.1.x86_64.rpm	(インストール)

 さらに、PGI 19.x 以降の Open MPI 3.1.3 では、RDMA 用の librdmacm.so.1ライブラリも必要です。これは CentOS/RHEL 7.6ではデフォルトで実装されているようです。Ubuntu では、明示的にパッケージを以下からダウンロードして、インストールする必要があります。ここでは、librdmacm1_17.1-1_amd64.deb をダウンロードする例を示します。

$ wget http://launchpadlibrarian.net/361664554/librdmacm1_17.1-1_amd64.deb
$ dpkg -i librdmacm1_17.1-1_amd64.deb
以前に未選択のパッケージ librdmacm1:amd64 を選択しています。
(データベースを読み込んでいます ... 現在 321882 個のファイルとディレクトリがインストールされています。)
librdmacm1_17.1-1_amd64.deb を展開する準備をしています ...
librdmacm1:amd64 (17.1-1) を展開しています...
librdmacm1:amd64 (17.1-1) を設定しています ...
libc-bin (2.27-3ubuntu1) のトリガを処理しています ...

 libibverbs ライブラリがシステム内に存在しない場合、Open MPIのコンパイラ(mpif90, mpicc, mpic++)を使用してコンパイルした際に、以下のようなリンクエラーが生じます。

kato@photon33:~/MPI$  mpic++ myname.cpp
/usr/bin/ld: warning: libibverbs.so.1, needed by /opt/pgi/linux86-64/2016/mpi/openmpi-1.10.1/lib/libmpi_cxx.so, not found (try using -rpath or -rpath-link)
/opt/pgi/linux86-64/2016/mpi/openmpi-1.10.1/lib/libmpi.so: `ibv_create_comp_channel@IBVERBS_1.0' に対する定義されていない参照です
/opt/pgi/linux86-64/2016/mpi/openmpi-1.10.1/lib/librdmacm.so.1: `ibv_detach_mcast@IBVERBS_1.1' に対する定義されていない参照です
/opt/pgi/linux86-64/2016/mpi/openmpi-1.10.1/lib/libmpi.so: `ibv_ack_async_event@IBVERBS_1.1' に対する定義されていない参照です
/opt/pgi/linux86-64/2016/mpi/openmpi-1.10.1/lib/libmpi.so: `ibv_get_cq_event@IBVERBS_1.1' に対する定義されていない参照です
/opt/pgi/linux86-64/2016/mpi/openmpi-1.10.1/lib/librdmacm.so.1: `ibv_get_device_guid@IBVERBS_1.1' に対する定義されていない参照です
/opt/pgi/linux86-64/2016/mpi/openmpi-1.10.1/lib/libmpi.so: `ibv_create_cq@IBVERBS_1.1' に対する定義されていない参照です
/opt/pgi/linux86-64/2016/mpi/openmpi-1.10.1/lib/libmpi.so: `ibv_get_sysfs_path@IBVERBS_1.0' に対する定義されていない参照です
/opt/pgi/linux86-64/2016/mpi/openmpi-1.10.1/lib/libmpi.so: `ibv_get_device_list@IBVERBS_1.1' に対する定義されていない参照です
/opt/pgi/linux86-64/2016/mpi/openmpi-1.10.1/lib/librdmacm.so.1: `ibv_copy_qp_attr_from_kern@IBVERBS_1.0' に対する定義されていない参照です(以下、略)

 PGI 19.1以降の Open MPI 3.1.3 では、librdmacm ライブラリがシステム内に存在しない場合、Open MPIのコンパイラ(mpiexec, mpif90, mpicc, mpic++)を使用すると以下のようなエラーが生じます。

kato@photon30:~$ mpiexec
/usr/pgi/linux86-64-llvm/2019/mpi/openmpi-3.1.3/bin/.bin/mpiexec: error while loading shared libraries: librdmacm.so.1: cannot open shared object file: No such file or directory
kato@photon30:~$ mpif90
/usr/pgi/linux86-64-llvm/2019/mpi/openmpi-3.1.3/bin/.bin/mpif90: error while loading shared libraries: librdmacm.so.1: cannot open shared object file: No such file or directory

Linux システム環境での rsh、あるいは ssh 設定時の注意事項

同一システム内のマルチコアを利用して MPI 実行する場合、以下に述べる rsh あるいは ssh の設定は必ずしも必要ありません。PGDBG を使用する場合は、どちらかの通信手段を使用できるように設定してください。

 一般的に MPI 並列処理を行う場合、ノード間でリモートアクセスが可能とする構成が必要となります。リモートアクセスのソフトウェアとしては、rsh あるいは ssh の二つの方法があります。クラスタ構成ではない、「一つのシステム」上のマルチコアを使用して MPI 実行する場合でも、そのシステム内に閉じた中で、以下のどちらかの TCP 通信形式が有効でなければいけません。

① rsh の設定
 rsh 系のソフトウェアは、現在の Linux のデフォルト・インストールにおいては、実装されておりません。従って、明示的に rsh/rlogin系のソフトウェアを Linux上にインストールする必要があります。そのほか、いくつかの Linux 上の設定があります。以下に、rsh 関連の設定に関して参考記事がありますので、そのリンクを記します。

  • http://www.proton.jp/main/unix/rsh.html
  • ルート権限での rsh の利用では、/etc/securetty ファイルに "rsh" 行を追加する必要があります。また、必要に応じて、rexec、rlogin 等も追加してください。

② ssh の設定に関する記事リンク
 ssh は、デフォルトでLinux上にインストールされておりますので、基本的に個人用の「鍵」の設定だけ行うことで使用することができます。以下は、ssh 設定に関して参考となる URL です。あるいは、google 等で「ssh パスワード」のキーワードで検索すると、「ssh でパスワード無し」でアクセスする方法の関連記事が出てきます。

システム上での rsh、ssh のリモート環境の確認

 システムの rsh あるいは、ssh リモートアクセス環境の動作を確認して下さい。

 Open MPI の実行や PGDBG デバッガを使用する場合、リモート環境が設定されていることを確認してください。ユーザの環境において以下のコマンドが動作することで確認できます。例えば node1 と言うホスト上で、以下のコマンドを自システムに対して実行します。これにより、リモートログインが可能であれば、問題ないと言うことになります。なお、rsh、ssh 共に 「パスワード(パスフレーズ)認証無し」 でアクセスできる環境でなければなりません。

【自システム内だけでMPIを使う場合】
 $ rsh node1 date あるいは $ ssh node1 date

 PGI CDK の場合は、クラスタシステム上でのノード間のリモート環境が設定されていることを確認してください。mpirun(mpiexec) 等でデフォルトで使用する通信環境は、ssh です。なお、rsh あるいは ssh 共に 「パスワード(パスフレーズ)認証無し」 でアクセスできる環境でなければなりません。

Open MPI 実行(bin)コマンドの場所を環境変数 PATH に追加する (PGI Workstation 製品)

 この設定は、PGI Node-locked あるいは、Network floating (旧 PGI Workstation/Server) 製品を使用した場合の各自のユーザアカウント上の処理です。シェル初期設定ファイル(bash の場合は HOME 上の .bashrc ファイル)の中に、Open MPI 関係の PATH を設定します。PGIコンパイラに付属している Open MPI のソフトウェアは、以下の場所に実装されています。パスの中の '2019' は、PGI 2019 (19.x) バージョンの場合の総称 directory の数字です。適宜、実装している PGI のバージョンにより、変更して下さい。PGI 17.x(2017) の場合は、 以下の「2018」の部分を「2017」に変更してください。以下の PATH を加えることにより、デフォルトで Open MPI のコマンドが使用できます。

【各自のホームディレクトリ上にある .bashrc ファイルの中】
[kato@photon29]# cd      (ホームディレクトリへ)
[kato@photon29]# vi .bashrc (editor で以下を追加する)

【64bit環境 PGI 19.x の場合】  
   export PATH=$PGI/linux86-64/2019/mpi/openmpi-3.1.3/bin/:$PATH
   export LD_LIBRARY_PATH=$PGI/linux86-64/2019/mpi/openmpi-3.1.3/lib:$PATH
   export MANPATH=$MANPATH:$PGI/linux86-64/2019/mpi/openmpi-3.1.3/share/man
   
【64bit環境 PGI 18.10 以前の場合】  
   export PATH=$PGI/linux86-64/2018/mpi/openmpi/bin/:$PATH
   export LD_LIBRARY_PATH=$PGI/linux86-64/2018/mpi/openmpi/lib:$PATH
   export MANPATH=$MANPATH:$PGI/linux86-64/2018/mpi/openmpi/share/man
   
 PGI 16.5 以降の Open MPI を使用する場合、mpif90(mpicc,mpic++)を実行すると以下のような
 エラーが生じますerror while loading shared libraries: libpgmp.so: cannot open shared object file: 
 No such file or directory
 これを回避するには、以下の環境変数も追加して指定ください。
 
 【PGI 19.x の場合】
  export LD_LIBRARY_PATH=$PGI/linux86-64/2019/lib:$LD_LIBRARY_PATH
 【PGI 18.x の場合】
  export LD_LIBRARY_PATH=$PGI/linux86-64/2018/lib:$LD_LIBRARY_PATH
 【PGI 17.x の場合】
 	export LD_LIBRARY_PATH=$PGI/linux86-64/2017/lib:$LD_LIBRARY_PATH
 【PGI 16.x の場合】
 	export LD_LIBRARY_PATH=$PGI/linux86-64/2016/lib:$LD_LIBRARY_PATH

PGI CDK用のソフトウェア製品(クラスタ用の構築utility を使用した場合)の環境変数の設定 (PGI CDK 16.1以降)

 PGI CDK ソフトウェアを使用して、「PCクラスタ」に実装した場合は、以下の PATH の設定を追加してください。さらに、環境変数 LD_LIBRARY_PATH の指定に関しては、以下のように 2 行必要となります。パス内のバージョンを表す番号が 総称バージョン名 2019 と リビジョン番号名 19.x の二種類あります。以下に例示したとおりに LD_LIBRARY_PATH を指定してください。もし、これに誤りがある場合は、クラスタノード間の mpiexec の実行時にエラーが生じます。なお、以下の例に示した19.x 部分は、例えば、PGI CDK 19.1 の実装であれば、19.1 と指定してください。

【各自のホームディレクトリ上にある .bashrc ファイルの中】
[kato@photon29]# cd      (ホームディレクトリへ)
[kato@photon29]# vi .bashrc (editor で以下を追加する)

【PGI 19.x の 64bit環境】
   export PATH=$PGI/linux86-64/2019/mpi/openmpi-3.1.3/bin/:$PATH
   export LD_LIBRARY_PATH=$PGI/linux86-64/2019/mpi/openmpi-3.1.3/lib:$PATH
   export LD_LIBRARY_PATH=$PGI/linux86-64/19.x/libso:$PATH
   export MANPATH=$MANPATH:$PGI/linux86-64/2019/mpi/openmpi-3.1.3/share/man

【PGI 18.x の 64bit環境】
   export PATH=$PGI/linux86-64/2018/mpi/openmpi/bin/:$PATH
   export LD_LIBRARY_PATH=$PGI/linux86-64/2018/mpi/openmpi/lib:$PATH
   export LD_LIBRARY_PATH=$PGI/linux86-64/18.x/libso:$PATH
   export MANPATH=$MANPATH:$PGI/linux86-64/2018/mpi/openmpi/share/man

【PGI 17.x の 64bit環境】
   export PATH=$PGI/linux86-64/2017/mpi/mpich/bin/:$PATH
   export LD_LIBRARY_PATH=$PGI/linux86-64/2017/mpi/openmpi/lib:$PATH
   export LD_LIBRARY_PATH=$PGI/linux86-64/17.x/libso:$PATH
   export MANPATH=$MANPATH:$PGI/linux86-64/2017/mpi/openmpi/share/man

【PGI 16.x の 64bit環境】
   export PATH=$PGI/linux86-64/2016/mpi/mpich/bin/:$PATH
   export LD_LIBRARY_PATH=$PGI/linux86-64/2016/mpi/openmpi/lib:$PATH
   export LD_LIBRARY_PATH=$PGI/linux86-64/16.x/libso:$PATH
   export MANPATH=$MANPATH:$PGI/linux86-64/2016/mpi/openmpi/share/man

MPI プログラムのコンパイル・リンク方法 (PGI 16.1 以降の Open MPI)

1. メモリ空間 2GB 未満のプログラム

 Fortran/C/C++ プログラムの例は、こちらをご参照下さい

 Open MPI を使用する場合のコンパイラのコマンドは、open MPI パッケージで作成された mpif90 コマンドと mpicc/mpic++ コマンドを使用します。コマンド・オプションには、PGI 用のコンパイル/リンク オプションを適宜指定することができます。

【Fortranのコンパイル mpif90 コマンド】
[kato@photon29 mpihello]$ which mpif90
usr/pgi/linux86-64/2019/mpi/openmpi-3.1.3/bin/mpif90

[kato@photon29 mpihello]$ mpif90 -fastsse -Minfo -o mpihello mpihello.f
------------------------------------------------------------------------------------
【C/C++のコンパイル (mpicc/mpic++ コマンド)】 
[kato@photon29 mpihello]$ which mpicc
/opt/pgi/linux86-64/2019/mpi/openmpi-3.1.3/bin/mpicc

[kato@photon29 mpihello]$ mpicc -fastsse -Minfo -o myname myname.c
[kato@photon29 mpihello]$ mpic++ -fastsse -Minfo -o myname myname.cpp

mpif90, mpicc, mpic++ の wrapper コマンドが実際に行う際の「コマンド列」を確認するには、--showme オプションを添えて下さい。

[kato@photon29 mpihello]$ mpicc -o myname myname.c --showme
pgcc -I/usr/pgi/linux86-64-llvm/2019/mpi/openmpi-3.1.3/include -Wl,-rpath -Wl,$ORIGIN/../lib:$ORIGIN/../../lib:$ORIGIN/../../../lib:$ORIGIN/../../../../lib -Wl,-rpath -Wl,/usr/pgi/linux86-64-llvm/2019/mpi/openmpi-3.1.3/lib -L/usr/pgi/linux86-64-llvm/2019/mpi/openmpi-3.1.3/lib -lmpi

2. メモリ空間 2GB 以上のプログラム

 2GB 以上のメモリ空間を使用するプログラムのコンパイルには、PGI の 64bit 用のオプション -mcmodel=medium を追加指定してください。

【Fortranのコンパイル】
 [kato@photon29 mpihello]$ mpif90 -fastsse -Minfo -mcmodel=medium -o mpihello mpihello.f
【Cのコンパイル】
 [kato@photon29 mpihello]$ mpicc -fastsse -Minfo -mcmodel=medium -o myname myname.c
【C++のコンパイル】
 [kato@photon29 mpihello]$ mpic++ -fastsse -Minfo -mcmodel=medium -o myname myname.cpp

  • 2GB 以上のメモリ(配列)空間を要するプログラムでは、-mcmodel=medium コンパイルオプションを付加します。これで生成された実行モジュールは、シェアード・ライブラリ・リンク形式のものとなります。

その他 Open MPI ホームページの参考となる FAQ

  1. FAQ: Compiling MPI applications
  2. FAQ: Running CUDA-aware Open MPI

MPIプログラムの実行

Open MPIの FAQ / man について

 Open MPI の実行時のコマンドオプション「FAQ: Running MPI jobs 」をご覧下さい。また、man コマンドで、man mpirun 等でお確かめください。ドキュメントは、Open MPI v2.1 documentation をご覧ください。

mpirun(mpiexec)コマンドで並列実行

 Open MPI の実行を行うロウンチャー・コマンドは、mpirun あるいは mpiexec です。コマンド・オプションはこちらをご覧ください

【mpirun のヘルプ】
[kato@photon29 mpihello]$ mpiexec -help
mpirun (Open MPI) 1.10.1

Usage: mpirun [OPTION]...  [PROGRAM]...
Start the given program using Open RTE

   -allow-run-as-root|--allow-run-as-root
                         Allow execution as root (STRONGLY DISCOURAGED)
   -am             Aggregate MCA parameter set file list

(以下略)

【mpihelloプログラムの実行】
[kato@photon29 mpihello]$ mpiexec -np 4 mpihello  (4つのプロセスを起動して実行)
 hello - I am process  0 host photon29
 Hello world!  I'm node            0
 hello - I am process  2 host photon29
 Hello world!  I'm node            2
 hello - I am process  3 host photon29
 Hello world!  I'm node            3
 hello - I am process  1 host photon29
 Hello world!  I'm node            1
 
【mynameプログラムの実行】
[kato@photon29 mpihello]$ mpiexec -np 4 myname
My name is photon29
My name is photon29
My name is photon29
My name is photon29

実行時に /usr/lib64/libcuda.so.1 が存在しないと言うエラーが出た場合

NVIDIA CUDA の toolkit ソフトウェアをインストールしていない場合、mpirun の実行時の最初に以下の「警告メッセージ」が出ます。

--------------------------------------------------------------------------
The library attempted to open the following supporting CUDA libraries,
but each of them failed.  CUDA-aware support is disabled.
libcuda.so.1: cannot open shared object file: No such file or directory
/usr/lib64/libcuda.so.1: cannot open shared object file: No such file or directory
If you are not interested in CUDA-aware support, then run with
--mca mpi_cuda_support 0 to suppress this message.  If you are interested
in CUDA-aware support, then try setting LD_LIBRARY_PATH to the location
of libcuda.so.1 to get passed this issue.
--------------------------------------------------------------------------

あるいは、以下のような単純な「警告メッセージ」が出る場合もあります。

--------------------------------------------------------------------------
Sorry!  You were supposed to get help about:
    dlopen failed
--------------------------------------------------------------------------

このメッセージを出さないようにするには、以下の方法があります。この方法は、 「PGIアクセラレータ」製品以外の場合、必ず行っていただく必要があります。

(1) mpirun の mca パラメータ引数(--mca mpi_cuda_support 0)を指定して実行する
   (参考)http://www.open-mpi.org/faq/?category=running#mpirun-options

$ mpirun -np 6 --mca mpi_cuda_support 0 ./a.out

(2) Linuxの環境変数で予め指定しておく方法(OMPI_MCA_と言うprefixを付けて変数名としてこれに0をセット)
   (参考)http://www.open-mpi.org/faq/?category=tuning#setting-mca-params

$ export OMPI_MCA_mpi_cuda_support=0
$ mpirun -np 6 ./a.out

PGI CDK 製品 ホストファイルの指定方法

 mpirun コマンドで、明示的にホストファイルを指定して実行するには、--hostfile {host_file} オプションを使用します。{host_file} には使用するクラスタ内のノード名を記述しておきます。あるいは、mpirun コマンドオプションに、
--host photon30,photon31,photon32 と言った形でホスト名を列挙します。

(参考)
How do I use the --hostfile option to mpirun?

How do I control how my processes are scheduled across nodes?

host_file名を hosts とします。ノード名を定義しています。

[kato@photon29]# cat hosts
photon29 slots=4
photon32 slots=4
photon30 slots=4

[kato@photon29]# mpirun --hostfile hosts -np 10 ./a.out

MPIに使用する最大プロセス数について

 MPI 実行で使用する「複数のプロセス」数の最大値は、使用システムに実装されている CPU の総コア数と言うことになります。最近のインテル・プロセッサは、「ハイパー・スレッディング」技術で、物理コア数の 2 倍の数を「スレッド・コア数」として表示していますが、HPC の並列計算では、「物理コア数」をそのシステムが並列実行に使用する最大コア数(並列許容プロセス数)として、並列実行を行います。(一般に、HPC 用途の純並列実行計算の場合、BIOS レベルで、Hyper threading を disable にします。なぜなら、Hyper threading とは、一つの物理コア内に、全ての CPU リソース(演算器)をダブルで持っていなため、リソース競合を起こし、並列性能を低下させる要因となります。)