SSブログ

MPIのコンパイルについて [MPI]

MPIのコンパイルではまったことがあった。
ちょっと1年ほど前のバージョンのMPICH2で別のマシンでビルドした最新のMPICH2のバイナリを実行させようとしたら、ライブラリ(このときはglibc)の互換性でエラーが出た。仕方がないので、何とかやっているうちに古いマシンの方のMPIを更新することにした。このときはまってしまった。なんとコンパイルが安定せず、コンパイルがうまくいっても実行ができない(サンプルのcpiすら)状態になってしまった。
原因をいろいろと調査して、コンパイラのバージョンを変えてみる、glibcのバージョンを変えてみるなど、
ありとあらゆる方法をトライしたが、結局解決しない。古いマシンはちょっと特殊なハードで借り物なので、
再インストールとかができない。困り果てた時にMPIのDocumentを読んでいたら、

「-jオプションをつけると、正しくコンパイルできないかもしれない」

と書いてあった。まさかと思い実行してみると、ビンゴ
あっさりうまくいってしまった。
こんなので夜中の3時までかかってしまった。

Fedora11 rshの設定 [MPI]

RSH関連のインストール

まず、必要ファイルのインストール
[user@host ~]$ yum install xinetd rsh rsh-server

下記のスクリプトを編集する。
[user@host ~]$ vim /etc/xinetd.d/rsh
[user@host ~]$ vim /etc/xinetd.d/rlogin

編集すべき内容
service shell
{
        socket_type             = stream
        wait                    = no
        user                    = root
        log_on_success          += USERID
        log_on_failure          += USERID
        server                  = /usr/sbin/in.rshd
        disable                 = no <-ここをyesからnoへ変更
}

このServiceに関しては、
/etc/servicesで定義されている名前を設定してあげる必要がある。
基本はすべて決まっているので、変更する必要はない。

つづいて、/etc/hosts.allowを設定するが、セキュリティを気にしなければ、

ALL:ALL

でOK。

さらに、記述されているホストのユーザーに対してrshログインを許可する。
まずは/etc/hosts.equivに許可するIPアドレスを追加する。

192.168.1.33
192.168.1.34
192.168.1.35

これらはTCP_Wrapperを介しているので、これをやりたくない場合はソースレベルでコンパイルし直さないといけない。

SSHのパスワードレス [MPI]

sshのパスワードレス

以前sshのパスワードレスの記事を書いたが、その後ちょっと訂正が必要だった。
結構はまったので、やり方を書いておく。
SSHをパスワードなしでログインするためのは鍵の設定が必要
わかりやすいようにHOSTAとHOSTB間をパスワードレスにする。

1)鍵の設定
.sshフォルダをいったん削除
[user@HOSTA ~]$ rm -rf ~/.ssh

HOSTAのRSA鍵の作成
[user@HOSTA ~]$ ssh-keygen
Generating public/private rsa key pair.
Enter file in which to save the key (/home/user/.ssh/id_rsa):
Created directory '/home/user/.ssh'.
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in /home/user/.ssh/id_rsa.
Your public key has been saved in /home/user/.ssh/id_rsa.pub.
The key fingerprint is:
3d:43:ee:8d:0d:5e:09:07:d8:78:4d:23:ab:4c:19:4b user@sonyOSD
The key's randomart image is:
+--[ RSA 2048]----+
|        E+ooo    |
|       .o+o+..   |
|        +.+ .    |
|       o = o .   |
|        S * o    |
|         o O     |
|          + o    |
|                 |
|                 |
+-----------------+

[user@HOSTA ~]$ cd .ssh/
[user@HOSTA .ssh]$ ls
id_rsa  id_rsa.pub

ここで、id_rsaは私有鍵、id_rsa.pubは公開鍵。まず自分の私有鍵を登録
[user@HOSTA .ssh]$ eval `ssh-agent`
[user@HOSTA .ssh]$ ssh-add
[user@HOSTA .ssh]$ ssh-agent -k

2)公開鍵の設定。
まず自分の公開鍵のファイルを他のホストに渡していいように名前を変更する。
[user@HOSTA .ssh]$ cp id_rsa.pub id_rsa.hosta
[user@HOSTA .ssh]$ cat id_rsa.hosta >> authorized_keys
[user@HOSTA .ssh]$ chmod 644 authorized_keys
最後のパーミッションの設定が重要で、これをやらないとパスワードを聞かれてしまう。

ここまでの作業をHOSTBでも行う。

3)公開鍵のコピー
HOSTA側
[user@HOSTA .ssh]$ scp id_rsa.hosta user@HOSTB:/home/user/.ssh/
HOSTAの公開鍵をHOSTBにコピー

HOSTB側
[user@HOSTB .ssh]$ cat id_rsa.hosta >> authorized_keys

これで、HOSTB側にHOSTA側の情報が記録されたので、HOSTAからHOSTBにSSHでログインしたときにパスワードを聞かれなくなる。










MPICH2 vs OpenMPI 通信パフォーマンス [MPI]

前回、MPICH2とOpenMPIの通信パフォーマンスを載せたが、
データが送信側の時間を測定していたので、バッファに書き込んだ時点で、
転送が終了してしまうのでバラツキが大きかった。
そこで、今回から受信側の測定結果を載せることにした。

<Bitrate>
SendRecv_MPICH2_vs_OpenMPI_bitrate.jpg

<Latency>
SendRecv_MPICH2_vs_OpenMPI_latency.jpg

結果を見ると、大きいサイズの転送はあまり差はないが、小さいサイズになると、
OpenMPIの方がバラツキが大きいように思える。
レイテンシに関しても同様のことがいえるが、大きな差はないといえる。
基本的にMPIを使う場合は、ノード間の通信は極力少なくする方がよいので、
大きいサイズの転送はあまり気にしなくてよく、小さい方のレイテンシを気にした方がよい。
いずれにしてもMPICH2とOpenMPIはパフォーマンスの差はそれほど気にしなくてもいいのかもしれない。余計な設計がいらない分、OpenMPIの方が使いやすいかも。

OpemMPIとMPICH2のベンチマーク [MPI]

OpenMPIとMPICH2との比較を行ってみた。
条件は前回と同様

1)同じホスト間(つまり同じマシン内でのスレッド間通信)

SendRecv_between_same_MPICH2.jpg

2)異なるホスト間

SendRecv_between_other_node_MPICH2.jpg

<考察>

1)同じノード内ではMPICH2の方が小さいサイズでもパフォーマンスがよいが、パケットサイズが1M程度で一度大きな落ち込みがある。それに対してOpenMPIは安定しているようだ。

2)異なるノードの結果ではほぼ特性は変わらずだが、若干MPICH2の方がよいみたい。

OpenMPIはMPICH2よりも安定していると聞いていた。実際測定してみた限りでは、OpenMPIとMPICH2はいずれも多きサイズの転送には差はないが、同じノード内では小さいサイズでMPICH2の方がばらつきが大きい。最近はマルチコア化してきているので、MPIを使ってスレッドを沢山生成することも多いので、同じノード内での運用においてMPICH2が不安定になるのかもしれない。
その場合はOpenMPなりPthreadを使うのがよいのかも。
もちょっと検討が必要だ。

OpemMPIのベンチマーク1 [MPI]

OpenMPIのベンチマークをとってみる。

構成
Node0) Indel Core2Quad Q9550/8G DDR2 800 RAM/Fedora 11
Node1) Indel Core2Quad Q9450/8G DDR2 800 RAM/Ubuntu 9.04

2つのノードは1Gbbs対応のHUB(D-link/DGS-2208)で接続。

1)同じホスト間(つまり同じマシン内でのスレッド間通信)

SendRecv_between_same_node.jpg


2)異なるホスト間

SendRecv_between_other_node.jpg


<考察>
1)は基本的にスレッド間通信なので、単純なメモリコピー。
測定マシンがHost1で、DDR2 800、デュアルチャンネルを使っているので、メモリ帯域は最大12.8G/s。TCPの通信によるオーバーヘッドやら何やらで、1/12位に落ちるようだ。
真ん中あたりは、CPUIキャッシュでうまくヒットしているのかもしれない。

2)パケットサイズが大きくなると、シーケンシャルになるので、概ね1GEtherの理論値の90%位出ている。小さいサイズになるとOS側のメモリキャッシュの影響か、1Gbpsを超える物がある。このあたりは測定プログラムを検討する必要がある。

以上ざっくりだが、TCPの通信のためか、CPU使用率が非常に高くなる。
現状ブロッキング通信なので、単純にビジーウェイトで待っているだけなのかもしれない。
HUBの影響を排除使用と思って、ピアツーピアで接続しようとしたら、ゲートウェイの設定を変更しなければならないので、今は面倒だからやっていない。そのうちやろう。
非ブロッキング通信Isend/Irecvの場合も検証していく予定

OpenMPIのインストール2 [MPI]

OpenMPIのインストール方法が間違っていた。

1)MPIの設定
OpenMPIはMPICH2の様に事前にデーモンを起動する必要がないため、
下記の部分は設定不要だった。
MPIの設定 [user@host: ~]$ touch ~/.mpd.conf [user@host: ~]$ chmod 600 ~/.mpd.conf

その代わり下記の設定が必要

~/hostsを作成する。記載方法は

[user@host: ~]$ vi ~/hosts
~/hostsファイルの中身

host0 cpu=4
host1 cpu=4



<ホスト名> CPU=<ホストのcpu coreの数>

2)PATHの設定
基本的にMPICH2と同じ。

[user@host: ~]$ vim ~/.bash_profile
以下PATHの追加

PATH=/home/you/openmpi-install/bin:$PATH
LD_LIBRARY_PATH=/home/you/openmpi-install/lib:$LD_LIBRARY_PATH

[user@host: ~]$ source ~/.bash_profile

これをやっても実行時に他のhost側が使えない場合がある。
その場合は、

[user@host:0 ~]$ mpirun --prefix /home/you/openmpi-install/ -np 2 --host host0,host1 ./cpi

とするとよい。

OpenMPIのインストール [MPI]

openmpi install

下記から最新のOpenMPIをダウンロード
http://www.open-mpi.org/

OpenMPIのソースはrpm形式なので、適当なツールを使ってソースファイルを解凍する。
Fedora11では書庫マネージャを使用

今回もrootではなくuserとしてインストールする。
以下、openmpi-1.3.3にソールファイルを展開している。
基本的にMPICH2の場合と同様。

[user@host: ~]$ ./configure --prefix=/home/you/mpich2-install 2>&1 | tee c.txt
->[user@host: ~]$ ./configure --prefix=/home/you/openmpi-install 2>&1 | tee c.txt

注)--prefixでインストールするフォルダを指定
上記youの部分を自分の環境に合わせる。

[user@host: ~]$ make
[user@host: ~]$ makeinstall

MPIの設定
[user@host: ~]$ touch ~/.mpd.conf
[user@host: ~]$ chmod 600 ~/.mpd.conf

MPIのPATHの設定
[user@host: ~]$ vim ~/.bash_profile
以下PATHの追加

PATH=/home/you/openmpi-install/bin:$PATH
LD_LIBRARY_PATH=/home/you/openmpi-install/lib:$LD_LIBRARY_PATH

[user@host: ~]$ source ~/.bash_profile

以下の設定は同じ。

参考)
MPICH2を最適化オプションーO3でコンパイルして実行してみると、
大きいサイズのデータを転送するとパフォーマンスが落ちることがあるようだ。
最適化オプションはそのままの方がよさそう。

MPICH2のインストール [MPI]

mpich2 install

下記から最新のMPICH2をダウンロード
http://www.mcs.anl.gov/research/projects/mpich2/

今回はrootではなくuserとしてインストールする。

[user@host: ~]$ tar xvf mpich2-1.1.1p1.tar.gz
[user@host: ~]$ cd mpich2-1.1.1p1
[user@host: ~]$ ./configure --prefix=/home/you/mpich2-install 2>&1 | tee c.txt
注)--prefixでインストールするフォルダを指定
上記youの部分を自分の環境に合わせる。

[user@host: ~]$ make
[user@host: ~]$ makeinstall

MPIの設定
[user@host: ~]$ touch ~/.mpd.conf
[user@host: ~]$ chmod 600 ~/.mpd.conf

secretword=xxxxxx

<-適当な単語で、各ホストに置く

MPIのPATHの設定
[user@host: ~]$ vim ~/.bash_profile
以下PATHの追加

PATH=/home/you/mpich2-install/bin:$PATH
LD_LIBRARY_PATH=/home/you/mpich2-install/lib:$LD_LIBRARY_PATH

[user@host: ~]$ source ~/.bash_profile

1)スタンドアローンで使う場合
mpdを起動
[user@host: ~]$ mpd &

2)クラスターとして使う場合
sshを使えるようにしておく。(sshデーモンを起動)
パスワードレスにするために、下記を行う。

[user@host: ~]$ ssh-keygen -t dsa
パスフレーズとかを聞かれるが、ここではEnterで進む。

[user@host: ~]$ ssh-copy-id user@hostname
ここではsshでログインするアカウント@ホストを追加する。

[user@host: ~]$ ssh-add
これでパスワードなしで接続ができるようになる。
確認のためにsshで接続するとよい。

mpd.hostsの設定
~/mpd.hostsを作成する。
ファイルは下記のように単純にホスト名を追加していく

host0
host1
host2
.
.
.

[user@host: ~]$ mpdboot -n 3 -f ~/mpd.conf

<参考>
Ubuntuの場合はFireWallがデフォルトで動いているので、
uwfを使って設定する。GUI版のguwfもあるのでそれを使うのがよい。
[user@host: ~]$ apt-get install guwf
でインストールできる。ただし、メニューにはインストールされないので、
ターミナルで起動する
[user@host: ~]$ guwf &

3)動作確認

MPICH2のインストール元のフォルダにはexampelフォルダがあるので、
その中のcpiを実行するとよい。
[user@host: ~]$ mpirun -n 3 ./cpi

結果が下記のようになれば成功
[user@host0: ~]$ mpiexec -n 4 ./cpi
Process 0 of 4 is on host0
Process 1 of 4 is on host1
Process 3 of 4 is on host2
Process 2 of 4 is on host3
pi is approximately 3.1415926535981162, Error is 0.0000000000083231
wall clock time = 0.017468

注)当然各ホストに同じバイナリファイルを入れておく必要があるので、
NFS等で共有フォルダをベースに使うのがよいと思う。






この広告は前回の更新から一定期間経過したブログに表示されています。更新すると自動で解除されます。