Ubuntu 13.04 で OpenMPI を使ってみる
Ubuntu 13.04 で openmpi を使用してみた。 インストールと Hello World を表示するプログラムを実行したときのメモ。
インストール
とりあえず
apt-get install openmpi-bin libopenmpi-dev
でインストールする。
1台で実行
http://www.open-mpi.org/papers/workshop-2006/hello.c に次のような Hello World のサンプルがあったので実行してみる。
#include <mpi.h>
#include <stdio.h>
int
main(int argc, char *argv[])
{
int rank, size;
MPI_Init(&argc, &argv);
MPI_Comm_rank(MPI_COMM_WORLD, &rank);
MPI_Comm_size(MPI_COMM_WORLD, &size);
printf("Hello, World. I am %d of %d\n", rank, size);
MPI_Finalize();
return 0;
}
作業用のディレクトリを作成して hello.c を mpicc でコンパイルする。
mkdir hello
cd hello
wget http://www.open-mpi.org/papers/workshop-2006/hello.c
mpicc hello.c -o hello
実行は mpirun を使う。
mpirun -np 4 ./hello
各プロセス毎に Hello World が 4 回表示される。
複数のマシンで実行
あらかじめ、すべてのマシンに openmpi をインストールし、 各マシン間で SSH でパスフレーズなしでログインできるようにしておく。
hello.c を変更してホスト名を表示するようにする。
#include <mpi.h>
#include <stdio.h>
#include <glib.h>
int
main(int argc, char *argv[])
{
char *hostname, *command;
int rank, size;
MPI_Init(&argc, &argv);
MPI_Comm_rank(MPI_COMM_WORLD, &rank);
MPI_Comm_size(MPI_COMM_WORLD, &size);
command = "hostname";
g_spawn_command_line_sync(command, &hostname, NULL, NULL, NULL);
printf("Hello, World. I am %d of %d at %s", rank, size, hostname);
g_free(hostname);
MPI_Finalize();
return 0;
}
のように変更して(glib が必要)
mpicc hello.c `pkg-config --cflags --libs glib-2.0` -o hello
でコンパイルする。NFS で共有してあるディレクトリで
mpirun -np 4 -H host1,host2 ./hello
のようにホスト名を指定して実行する。 NFS でない場合は各マシンの同じディレクトリにファイルをコピーすることで実行できる。
SSH でパスフレーズなしでログイン
openmpi を複数のマシンで実行するときに必要なパスフレーズなしの SSH ログインについてメモしておく。 ssh-keygen の man page はいろいろとオプションが書いてあって、すべて把握できなかった。 何も設定していない状態でパスフレーズなしで SSH のログインを実行できるように、以下のように鍵を作成した。 もちろん、パスフレーズなしでログインできるようにするとセキュリティ的にはよくないので注意。
鍵を作って各マシンの ~/.ssh に置く。
ssh-keygen -t rsa
としてパスフレーズなしの鍵を作成する。鍵のファイルは今回は指示にしたがって ~/.ssh/id_rsa にした。 他に鍵はない状態なので
mv .ssh/id_rsa.pub .ssh/authorized_keys
とする。
scp .ssh/authorized_keys .ssh/id_rsa USER@HOST:.ssh
として両方ともコピーすればお互いにパスフレーズなしでログインできるようになる。
オプション –preload-binary
NFS でない場合でもオプションの –preload-binary をつけると自動でファイルをマシン間でコピーして実行する。 ただ、これには SSH のホスト名の設定をしておかないと scp の実行で失敗する。 ~/.ssh/config にホスト名だけで SSH 接続できるように
Host HOSTNAME
HostName HOSTNAME.example.com
User USERNAME
のような設定を書いておく。これで NFS でなくても
mpirun -np 4 -H HOSTNAME --preload-binary ./hello
で実行できる。
gdb でデバッグする
xterm で実行
参考にしたサイトでは端末として xterm を使用していた。 openmpi を使用したプログラムを gdb でデバッグするには次のようにする。
mpirun -np 2 xterm -e gdb --args path/to/program_with_mpi --some-program-options arguments
2つ xterm が起動して、各プロセスごとにデバックできる。それぞれの xterm で
b main
run
とするとそれぞれ main で止まる。
roxterm で実行
単に
mpirun -np 2 roxterm -e gdb --args path/to/program_with_mpi --some-program-options arguments
とうまくいかない。roxterm は複数のウィンドウでプロセスを共有しているためのようだ。 roxterm の –separate オプションをつけて roxterm のプロセスを別々にする。
mpirun -np 2 roxterm --separate -e gdb --args path/to/program_with_mpi --some-program-options arguments
valgrind でメモリリークを探す
valgrind は mpirun で実行すれば良いようだ。 glib を使用しているため、それの環境変数を設定して
G_SLICE=always-malloc G_DEBUG=gc-friendly mpirun -np 2 valgrind -v --leak-check=full --show-reachable=yes --log-file=valgrind.%p.log path/to/program_with_mpi --options arguments
のようにした。
参考
- http://d.hatena.ne.jp/cmphys/20120628/1340900709
- http://www.open-mpi.org/papers/workshop-2006/prerequisites.php
- http://stackoverflow.com/questions/3968656/how-to-compile-mpi-and-non-mpi-version-of-the-same-program-with-automake
- http://tech.ckme.co.jp/mpi.shtml
- http://e-days.info/2011/05/ssh-keygen/
- http://d.hatena.ne.jp/sankumee/20120404/1333500988
- http://todo.issp.u-tokyo.ac.jp/ja/members/halm/test
- http://margaret-sdpara.blogspot.jp/2011/07/openmpi-libtool.html