2017-02-26 4 views
1

私はMPI_Ibcastの仕組みを理解しようとしています。 私は何が必要なのかを示す1つのテストを考え出しました。私はIbcastの右の使い方を理解しないかもしれないように、それは、正しくない可能性があり :MPI_Ibcastは、最初の反復で関数内で呼び出すことができる場合MPI-Ibcastの使用

#include <iostream> 
#include <mpi.h> 
#include <string> 
#include <vector> 


using namespace std; 

class A { 
public: 
     int a[3]; 
     MPI_Request request; 
     int tag; 
     A() {} 
     int foo() { 
       int rank; 
       MPI_Comm_rank(MPI_COMM_WORLD, &rank); 
       cout<<rank<<endl; 
       if (rank == 0) 
         tag = 5; 
       MPI_Ibcast(&tag, 1, MPI_INT, 0, MPI_COMM_WORLD, &request); 
     } 
}; 

int main(int argc, char* argv[]) { 
     MPI_Init(&argc, &argv); 
     int rank; 
     MPI_Comm_rank(MPI_COMM_WORLD, &rank); 
     MPI_Status* status = new MPI_Status[2]; 
     MPI_Request* request = new MPI_Request[2]; 
     A* a = new A[2]; 
     for (int i = 0; i < 2; i++) { 
       a[i].request = request[i]; 
     } 

     for (int i = 0; i < 2; i++) { 
       if (i == 0 && rank == 0) { 
         a[0].foo(); 
       }else if (i == 1 && rank == 1) { 
         a[1].foo(); 
       } 
       int a; 
       for (int i = 0; i < 1000; i++) 
         a+=i; 
     } 
     MPI_Waitall(2, request, status); 
     cout <<a[1].tag<<" "<<a[1].tag<<" "<<a[1].tag<<endl; 
     MPI_Finalize(); 
} 

私は、見たいと思って、この関数は返し、別にMPI_Ibcastを呼び出して、すべて終了します(タグはブロードキャストされ、2つのプロセスすべてで5に設定されます)。私がここでクラスを使う理由は、それらを元のプログラムの中に入れて、小さな問題をモデル化しようとしているからです。

タスクは次のとおりです。別々のサイクルでは、別々のプロセス上の別個のインスタンスが関数を呼び出します。それらのいくつかはグループで編成され、このグループの中でIbcastはタグをブロードキャストします。ここで私は2つのクラスを持つ1つのグループを持っています。たぶん私はこの例をどうにかして修正すべきでしょうか?

答えて

0

あなたのやりたいことは完全にはわかりませんが、ここでは例の固定バージョンです。あなたは正しいものを待っていなかったとして、私は修正の主なものは、要求の使用である...ここで

#include <iostream> 
#include <mpi.h> 

using namespace std; 

class A { 
    public: 
     MPI_Request request; 
     int tag; 
     A() : request(MPI_REQUEST_NULL), tag(-1){} 
     int foo() { 
      int rank; 
      MPI_Comm_rank(MPI_COMM_WORLD, &rank); 
      cout<<rank<<endl; 
      if (rank == 0) 
       tag = 5; 
      MPI_Ibcast(&tag, 1, MPI_INT, 0, MPI_COMM_WORLD, &request); 
     } 
}; 

int main(int argc, char* argv[]) { 
    MPI_Init(&argc, &argv); 
    int rank; 
    MPI_Comm_rank(MPI_COMM_WORLD, &rank); 
    A a[2]; 

    for (int i = 0; i < 2; i++) { 
     if (i == 0 && rank == 0) { 
      a[0].foo(); 
     }else if (i == 1 && rank == 1) { 
      a[1].foo(); 
     } 
     int b = 0; 
     for (int i = 0; i < 1000; i++) 
      b+=i; 
    } 
    MPI_Wait(&a[rank].request, MPI_STATUS_IGNORE); 
    cout <<a[1].tag<<" "<<a[1].tag<<" "<<a[1].tag<<endl; 
    MPI_Finalize(); 
} 

は、私はコンパイルと私のマシン上に2つのプロセスでそれを実行すると、それが与えるものである。

~/tmp$ mpiicpc -O0 ibcst.cc 
~/tmp$ mpirun -n 2 ./a.out 
1 
0 
5 5 5 
-1 -1 -1 

これはうまくいけばうまくいけば、あなたが期待したことをします。しかし、プロセスのグループについてのあなたの説明は、例えば、MPI_Comm_split()を使用して複数のサブコミュニケータを作成して、グループ内で一斉呼び出しを使用できるようにすると信じさせています。