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

のようにした。

参考

Tags of current page

,