2012-05-05 8 views
2

C/MPIで分散型Webサーバーを構築していて、コード内の最初のMPI_BARRIERの後にポイントツーポイント通信が完全に停止するようです。標準Cコードはバリアの後ろで動作するので、スレッドのそれぞれがバリアを通過することがわかります。ポイントツーポイント通信は、障壁の前でもうまくいきます。しかし、障壁の前の行に働いたのと同じコードを障壁の後の行にコピー&ペーストすると、それは完全に機能しなくなります。 SENDはちょうど永遠に待つでしょう。代わりにISENDを使ってみると、行を通って行こうとしますが、メッセージは受信されません。私はこの問題をたくさん探していましたが、MPI_BARRIERに問題がある人は誰でも障壁が正しく働き、コードが間違っていると言われていますが、私の人生は自分のコードが間違っている理由を理解できません。この現象の原因は何ですか?MPI_SENDがMPI_BARRIERの後に動作しなくなる

#include <mpi.h> 
#include <stdio.h> 

int main(int argc, char *argv[]) 
{ 
    int procID; 
    int val; 
    MPI_Status status; 

    MPI_Init(&argc, &argv); 
    MPI_Comm_rank(MPI_COMM_WORLD, &procID); 
    MPI_Barrier(MPI_COMM_WORLD); 

    if (procID == 0) 
    { 
    val = 4; 
    printf("Before send\n"); 
    MPI_Send(&val, 1, MPI_INT, 1, 4, MPI_COMM_WORLD); 
    printf("after send\n"); 
    } 

    if (procID == 1) 
    { 
    val = 1; 
    printf("before: val = %d\n", val); 
    MPI_Recv(&val, 1, MPI_INT, MPI_ANY_SOURCE, MPI_ANY_TAG, MPI_COMM_WORLD, &status); 
    printf("after: val = %d\n", val); 
    } 

    MPI_Finalize(); 
    return 0; 
} 

バリアを正しく実行するには、このプログラムの原因となる前に2つのif文の移動:ここ

はこれを説明するサンプルプログラムです。

EDIT - 最初の通信は、種類、動作、および将来のすべての通信に関係なく失敗するようです。これは私が最初に思ったよりはるかに一般的です。最初の通信が障壁またはその他のメッセージであるかどうかは関係ありません。将来の通信は適切に機能しません。

+0

あなたが投稿したコードは私にはうまく見えます。あなたはどのバージョンのMPIを使用していますか? – suszterpatt

+0

openmpi 1.5.5ではうまく動作します。 – chemeng

+0

私はそれがopenmpiだと知っていますが、私はバージョン番号を把握できないようです。あなたに伝えるコマンドはありますか? – TEOUltimus

答えて

5

Open MPIはTCP/IPを通信に使用すると、すべての構成済みのネットワークインターフェイスが「UP」状態になるように試みます。これは、他のノードのいくつかがこれらすべてのインタフェースを通じて到達可能でない場合に問題となる。これはOpen MPIが採用している貪欲なコミュニケーションの最適化の一部であり、場合によってはあなたの問題のように問題につながることもあります。

少なくとも第2のノードが起動し、この事実は、ネゴシエーションフェーズの間に第1のノードに導入されたことがある複数のインターフェースを有すると思わ:

  • 128.2.100.167
  • で構成された一つ192.168.109.1で構成された1(あなたは、トンネルやXenは、マシン上で実行されていますか?)

バリア通信が最初にネットワーク上で発生した後、次のMPI_Send試みは、第2のアドレスOVに送信します明らかにすべてのノードに接続していない第2のネットワーク。

最も簡単な解決策は、ノードを接続するneworkだけを使用するようにOpen MPIに指示することです。あなたはそれが以下のMCAパラメータを使用して、そう言うことができます。

--mca btl_tcp_if_include 128.2.100.0/24 

(またはものは何でもあなたの通信ネットワークである)

を、それはすべてのマシンで同じである場合にも、例えば、ネットワークインターフェイスのリストを指定することができます

--mca btl_tcp_if_include eth0 

か、特に、特定のインターフェイスを除外するためにオープンMPIを伝えることができます(ただし、あなたがそうするならば、あなたは常に「LO」ループバックを除外することを伝える必要があります):

--mca btl_tcp_if_exclude lo,virt0 

希望に役立ちますし、ここではまったく同じ問題を抱えているようだ。最近、ほとんどすべてのLinuxディストリビューションがデフォルトでさまざまなネットワークインターフェイスを起動し始めており、Open MPIに問題が発生する可能性が高いようです。

P.S.これらのノードをファイアウォールの背後に置いてください!

+0

ありがとう!あなたが推奨する2番目の修正(ネットワークインターフェイスの指定)は美しく機能しました。 また、これを実行しているクラスタは、私の学校のファイアウォールの背後にあります。私は彼らが何をしているかを彼らが知っていると確信している。 :D – TEOUltimus

関連する問題