超音波流体屋のプログラム備忘録
MPICH2 (mpd, hydra)
最終更新:
usapfrog
-
view
代表的なMPIソフト、MPICH2での並列計算方法の構築手順など。
CentOS Linux 6.5, mpich2 1.2.1。
ネットワークで繋がった複数の独立マシン間を通信する場合について扱う。
主にmpdの場合について扱うけど、バージョンが新しいhydra使うタイプのがずっと楽なので、
yumが対応してない場合は自分でビルドしたほうが良いかも。
CentOS Linux 6.5, mpich2 1.2.1。
ネットワークで繋がった複数の独立マシン間を通信する場合について扱う。
主にmpdの場合について扱うけど、バージョンが新しいhydra使うタイプのがずっと楽なので、
yumが対応してない場合は自分でビルドしたほうが良いかも。
1.双子マシンを準備する
最低限、Linuxのディストリビューションは揃える。
(CentOSとFedraで試したら、MPIライブラリの関係で駄目だった。)
ユーザー名も共通の物を準備しておく。
(CentOSとFedraで試したら、MPIライブラリの関係で駄目だった。)
ユーザー名も共通の物を準備しておく。
2.MPICH2のインストール
全マシンに。バージョンも揃えたほうがよい。
gcc, gfortranで良いなら、yumで mpich2とmpich2-develを取ってくる。
インテルやPGIのコンパイラを使いたければ、
環境変数CC, F77などを指定した後に自分でビルドする。
自分でビルドしたときは、/usr/local/mpich2以下のbinをPATHに、libをLD_LIBRARY_PATHに忘れずに追加する。
(参考)
MPICH2 : downloads
PGIコンパイラによる MPICH2 ライブラリ環境の構築(Linux)プロセス管理として MPD を使用
Intel CompilerとMPICH2のインストールメモ
gcc, gfortranで良いなら、yumで mpich2とmpich2-develを取ってくる。
インテルやPGIのコンパイラを使いたければ、
環境変数CC, F77などを指定した後に自分でビルドする。
自分でビルドしたときは、/usr/local/mpich2以下のbinをPATHに、libをLD_LIBRARY_PATHに忘れずに追加する。
(参考)
MPICH2 : downloads
PGIコンパイラによる MPICH2 ライブラリ環境の構築(Linux)プロセス管理として MPD を使用
Intel CompilerとMPICH2のインストールメモ
3./etc/hostsの整備
これも全マシンで共通のほうがよい。例えば以下のとおり。
# vi /etc/hosts 127.0.0.1 localhost 192.168.1.2 server 192.168.1.3 client1 192.168.1.4 client2
server1などがhostnameをと違う場合はhostnameも登録しておくこと。
hostnameの調べ方はそのまま。
hostnameの調べ方はそのまま。
$ hostname
きちんとserver-clientマシン間でpingが通るかも確認する。
4.パスなしでssh通信の確立
RSA鍵認証でパスを打たなくてもseverからclientにsshできるようにしておく。
serverでssh-keygenをして、改行を連打(パスフレーズはいれない)
serverでssh-keygenをして、改行を連打(パスフレーズはいれない)
[server] $ ssh-keygen
公開鍵をclient全員に送る
[server] $ cd ~/.ssh $ scp id_rsa.pub client1:
client側で公開鍵を登録する。パーミッションに注意する。
[client] $ cd $ cat id_rsa.pub >> .ssh/authorized_keys $ rm id_rsa.pub $ chmod 700 .ssh $ chmod 600 .ssh/authorized_keys
(rootの場合)クライアント側でSELinuxを無効にする。
# setenforce 0 # vi /etc/sysconfig/selinux SELINUX=disabled に変更
server側でパス無しでsshが動作するか確認する。
[server] $ ssh client1 date
5..mpd.confの準備、mpdの動作チェック
hydraを使う場合は飛ばしてよい。
全マシンでsercretwordは共通とする。スペースや改行、形式も厳格に同じで。
後述するmpdboot時のエラー(handle_mpd_output 407)(handle_mpd_output 420)は主に.mpd.conf関連で発生するらしい。
全マシンでsercretwordは共通とする。スペースや改行、形式も厳格に同じで。
後述するmpdboot時のエラー(handle_mpd_output 407)(handle_mpd_output 420)は主に.mpd.conf関連で発生するらしい。
$ vi .mpd.conf secretword=hoge $ chmod 600 .mpd.conf
mpdが正常に動作するか確認する。
$ mpd & $ mpdallexit
6.シングルプロセスおよびサーバのみでの実行テスト
以下のようなプログラム。
[~/mpitest.c]
[~/mpitest.c]
- #include <unistd.h>
- #include "mpi.h"
- int main(int argc, char **argv)
- {
- int len,ierr;
- int my_rank;
- char hname[32];
- len = 32;
- MPI_Init( &argc, &argv );
- MPI_Comm_rank(MPI_COMM_WORLD, &my_rank);
- gethostname(hname,len);
- MPI_Finalize( );
- return 0;
- }
-
コンパイルして、単純実行する、単マシンでのmpiexecを試す。
$ mpicc mpitest.c $ ./a.out [server, mpd] $ mpd & $ mpiexec -n 4 ./a.out $ mpdallexit
[server, hydra] $ mpiexec -n 4 ./a.out
以降しばらくmpdの場合。hydraを使う場合は、9-hydraまで飛ばしてよい。
7.ファイアウォールを切るかポート開放する
mpich2はssh22番以外のポートも経由して通信する。
支障がなければファイアウォールを切ってしまうのが早い。
CentOSは以下のコマンド。
支障がなければファイアウォールを切ってしまうのが早い。
CentOSは以下のコマンド。
[全マシン] # /etc/init.d/iptables stop
(Fedra Coreは # systemctl stop iptables.service だった。)
ファイアウォールを維持して、計算したい場合はMPICHの使用するポートを環境変数で指定する。
(1プロセス1ポート使うので、ある程度の範囲は確保すること。狭すぎるとmpiexecで実行時にエラーが出る。)
(1プロセス1ポート使うので、ある程度の範囲は確保すること。狭すぎるとmpiexecで実行時にエラーが出る。)
[全マシン] $ vi .bashrc $ export MPICH_PORT_RANGE=57700:57800
その後、OS付属のファイアウォールツールや手動iptableなどで該当ポートを開放する。
CentOSなら、
CentOSなら、
# system-config-firewall のその他から、57700-57800 TCPを指定し、iptableの再起動をする。 # /etc/init.d/iptables restart
8.mpdcheckでの相互通信の確認
[server] $ mpdcheck -s
で出てくるホスト、ポートをクライアント側で下記入力する。
[client] $ mpdcheck -c [server] [port]
無事通信できると以下のメッセージが出力される。
[server] server successfully recvd msg from client: hello_from_client_to_server [client] client successfully recvd ack from server: ack_from_server_to_client
9.mpd.hostsの準備、mpdbootで手をつなぐ
mpd.hostsに計算に使用するサーバ、使用可能プロセス数を指定する。
[server] $ vi mpd.hosts server:2 client1:2 client2:4
mpdbootでclientマシンと連結する。ファイル名がmpd.hostsなら-f以下は省略可能。-n以降はマシン数を指定する。
[server] $ mpdboot -n 3 -f mpd.hosts
エラーが出たら、--debugオプションを付けると詳細な原因を出力してくれる。
$ mpdboot -n 3 --debug
ファイアーウォールで引っかかると、(handle_mpd_output 407)エラーがでるので、上の設定を見直す。
/usr/bin/mpd.py以外にmpd.pyがあるためエラー(handle_mpd_output 420)となる場合は
clientの該当箇所にシンボリックリンクを貼るなどして対応する。
/usr/bin/mpd.py以外にmpd.pyがあるためエラー(handle_mpd_output 420)となる場合は
clientの該当箇所にシンボリックリンクを貼るなどして対応する。
無事起動し、クライアントを認識しているかはmpdtraceで確認できる。
$ mpdtrace
10.実行(mpiexec, mpd)
mpdboot後、mpiexecで実行する。-nはプロセス数を指定する。
[server] $ mpiexec -n 6 ./a.out
結果。通常順番はバラバラである。
My name is server, Rank = 0 My name is server, Rank = 1 My name is client1, Rank = 2 My name is client1, Rank = 3 My name is client2, Rank = 4 My name is client2, Rank = 5
MPI系の実行エラーが出た場合は上記の使用ポート範囲が狭過ぎないか確認すること。
mpdを終了する。
[server] $ mpdallexit
9-hydra.ホストの準備・実行ファイルの転送
適当なファイルmpi.hostsに計算に使用するサーバ、使用可能プロセス数を指定する。
[server] $ vi mpi.hosts server:2 client1:2 client2:4
NFSなどでストレージを共有してない場合、各マシンの同階層にプログラムを転送する必要がある。
[server] $ scp a.out client1: $ scp a.out client2:
mpi.hostsを使った全送信スクリプトなんかを組んでしまうと楽。
[bcast.sh (転送ファイル)] 現在ディレクトリを全クライアントノードに作成し、scpでファイルを転送する。
[bcast.sh (転送ファイル)] 現在ディレクトリを全クライアントノードに作成し、scpでファイルを転送する。
- #!/bin/bash
- CWD=`pwd`
- NUL=/dev/null
-
- if [ $# -eq 0 ] ; then
- echo "no file specified."
- exit 1
- fi
-
- for h in `cat mpi.hosts`; do
- host=${h%%:*}
- if [ $host != `hostname` ]; then
- echo $host
- ssh $host ls $CWD 1>$NUL 2>$NUL
- if [ $? -ne 0 ]; then
- fi
- ls $FILE 1>$NUL 2>$NUL
- if [ $? -eq 0 ]; then
- scp $FILE $host:$CWD
- fi
- fi
- done
-
$1=引数, $#=引数の数, $?=前コマンドの戻り値,
%%=最大マッチの後方置換,ワイルドカード'*'つき
%%=最大マッチの後方置換,ワイルドカード'*'つき
10-hydra.実行(mpiexec,hydra)
mpiexecで実行する。-nはプロセス数, -fはホストファイルを指定する。結果は上記と同じ。
[server] $ mpiexec -n 6 -f mpi.hosts ./a.out
びっくりするほど楽です。hydra版はドキュメントの少なさがネックかな。
参考
MPICH2
UIKYO.NET MPICHインストール
CentOS 6.2 に mpich2 をインストール
PGIコンパイラによる MPICH2 ライブラリ環境の構築2(Linux)プロセス管理としてデフォルトの Hydra を使用
UIKYO.NET MPICHインストール
CentOS 6.2 に mpich2 をインストール
PGIコンパイラによる MPICH2 ライブラリ環境の構築2(Linux)プロセス管理としてデフォルトの Hydra を使用