2017-07-13 6 views
0

私はMPIデカルト・トポロジを持っており、MPI_Neighbor_alltoallですべてのノード・ランクをネイバーに送信します。私はどこでエラーが発生するのかわかりませんし、私自身もMPI_Neighbor_alltoallを実装しています。私は自分のコードを分かりやすく(うまくいけば)分かりやすいコードスニペットにしました。MPIデカルト・トポロジ:MPI_Neighbor_alltoall間違ったデータを受け取りました

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


int main(int argc, char** argv) { 


// MPI_Cart variables 
MPI_Comm cart_comm; 
MPI_Comm mycomm; 
int ndims=2; 
int periods[2]={0,0}; 
int coord[2]; 


    int dims[2]={3,3}; 
    int xdim = dims[0]; 
    int ydim = dims[1]; 
    int comm_size = xdim*ydim; 

    // Initialize the MPI environment and pass the arguments to all the processes. 
    MPI_Init(&argc, &argv); 

    // Get the rank and number of the process 
    int rank, size; 
    MPI_Comm_rank(MPI_COMM_WORLD, &rank); 
    MPI_Comm_size(MPI_COMM_WORLD, &size); 

    // output: dimensions 
    if(rank==0){ 
     printf("dims: [%i] [%i]\n", xdim, ydim); 
    } 

    // enough nodes 
    if(comm_size<=size){ 

     // Communicator count has to match nodecount in dims 
     // so we create a new Communicator with matching nodecount 
     int color; 
     int graphnode; 
     if(rank<comm_size){ 
      //printf("%d<%d\n",rank,comm_size); 
      color=0; 
      graphnode=1; 
     } else { 
      //printf("%d>=%d\n",rank,comm_size); 
      // not used nodes 
      color=1; 
      graphnode=0; 
     } 

     MPI_Comm_split(MPI_COMM_WORLD, color, rank, &mycomm); 
     MPI_Comm_rank(mycomm, &rank); 
     MPI_Comm_size(mycomm, &size); 


     // ***GRAPHNODE-SECTION*** 
     if(graphnode){ 

      // Create Dimensions 
      MPI_Dims_create(size, ndims, dims); 

      // Create Cartesian 
      MPI_Cart_create(mycomm, ndims, dims, periods, 1, &cart_comm); 

      // Get the name of the processor 
      char processor_name[MPI_MAX_PROCESSOR_NAME]; 
      int len; 
      MPI_Get_processor_name(processor_name, &len); 

      // Get coordinates 
      MPI_Cart_coords(cart_comm, rank, ndims, coord); 

      // sending 
      int *sendrank = &rank; 
      int recvrank[4]; 
      MPI_Neighbor_alltoall(sendrank , 1, MPI_INT, recvrank, 1, MPI_INT, cart_comm); 


      printf("my rank: %i, received ranks: %i %i %i %i\n", rank, recvrank[0], recvrank[1], recvrank[2], recvrank[3]); 



     } else { 
      // *** SPARE NODES SECTION *** 

     } 
    } else { 
     // not enough nodes reserved 
     if(rank==0) 
      printf("not enough nodes\n"); 
    } 

    // Finalize the MPI environment. 
    MPI_Finalize(); 

} 

alltoall.c

ので、このコードは、3×3デカルトトポロジを作成します。十分なノードがない場合はファイナライズし、ノードが多すぎる場合はスペアノードに何も行わせません。これは簡単なはずですが、出力にはデータが不足しているため、私はまだ間違っています。あなたが出力で見ることができるように

出力

$ mpicc alltoall.c 
$ mpirun -np 9 a.out 
dims: [3] [3] 
my rank: 2, received ranks: -813779952 5 0 32621 
my rank: 1, received ranks: 1415889936 4 0 21 
my rank: 5, received ranks: 9 8 0 32590 
my rank: 3, received ranks: 9 6 -266534912 21 
my rank: 7, received ranks: 9 32652 0 21 
my rank: 8, received ranks: 9 32635 0 32635 
my rank: 6, received ranks: 9 32520 1372057600 21 
my rank: 0, received ranks: -1815116784 3 -1803923456 21 
my rank: 4, received ranks: 9 7 0 21 

、誰も隣人としてノード1,2を持っていないと21はどこから来るのでしょうか?ランク4は唯一のノードでなければなりません。それは4つのネイバーを持ちますが、それは{1,3,5,7}でしょうか?ここで私の間違いがどこにあるのか分かりません。

座標は次のようになります。

[0,0] [1,0] [2,0] 
[0,1] [1,1] [2,1] 
[0,2] [1,2] [2,2] 

と、次のようにランク:

0 3 6 
1 4 7 
2 5 8 
+0

'MPI_Cart_create'を呼び出すとき、親コミュニケータのランク数がトポロジ内のランク数と厳密に一致する必要はありません。カウントはそれ以上でなければなりません。余分なランクは、出力引数に 'MPI_COMM_NULL'を受け取ります。したがって、 'MPI_Comm_split'への中間呼び出しは冗長です。 –

答えて

0

あなたはここで(両方sendrankとrecvrankに)

を初期化されていない大量のデータにアクセスしているありますあなたのテストプログラムの書き換え版です。

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


int main(int argc, char** argv) { 


// MPI_Cart variables 
MPI_Comm cart_comm; 
MPI_Comm mycomm; 
int ndims=2; 
int periods[2]={0,0}; 
int coord[2]; 


    int dims[2]={3,3}; 
    int xdim = dims[0]; 
    int ydim = dims[1]; 
    int comm_size = xdim*ydim; 

    // Initialize the MPI environment and pass the arguments to all the processes. 
    MPI_Init(&argc, &argv); 

    // Get the rank and number of the process 
    int rank, size; 
    MPI_Comm_rank(MPI_COMM_WORLD, &rank); 
    MPI_Comm_size(MPI_COMM_WORLD, &size); 

    // output: dimensions 
    if(rank==0){ 
     printf("dims: [%i] [%i]\n", xdim, ydim); 
    } 

    // enough nodes 
    if(comm_size<=size){ 

     // Communicator count has to match nodecount in dims 
     // so we create a new Communicator with matching nodecount 
     int color; 
     int graphnode; 
     if(rank<comm_size){ 
      //printf("%d<%d\n",rank,comm_size); 
      color=0; 
      graphnode=1; 
     } else { 
      //printf("%d>=%d\n",rank,comm_size); 
      // not used nodes 
      color=1; 
      graphnode=0; 
     } 

     MPI_Comm_split(MPI_COMM_WORLD, color, rank, &mycomm); 
     MPI_Comm_rank(mycomm, &rank); 
     MPI_Comm_size(mycomm, &size); 


     // ***GRAPHNODE-SECTION*** 
     if(graphnode){ 

      // Create Dimensions 
      MPI_Dims_create(size, ndims, dims); 

      // Create Cartesian 
      MPI_Cart_create(mycomm, ndims, dims, periods, 1, &cart_comm); 

      // Get the name of the processor 
      char processor_name[MPI_MAX_PROCESSOR_NAME]; 
      int len; 
      MPI_Get_processor_name(processor_name, &len); 

      // Get coordinates 
      MPI_Cart_coords(cart_comm, rank, ndims, coord); 

      // sending 
      int sendrank[4]; 
      int recvrank[4]; 
      int i; 
      char * neighbors[4]; 
      for (i=0; i<4; i++) { 
       sendrank[i] = rank; 
       recvrank[i] = -1; 
      } 
      MPI_Neighbor_alltoall(sendrank , 1, MPI_INT, recvrank, 1, MPI_INT, cart_comm); 
      for (i=0; i<4; i++) { 
       if (-1 != recvrank[i]) { 
        asprintf(&neighbors[i], "%d ", recvrank[i]); 
       } else { 
        neighbors[i] = ""; 
       } 
      } 

      printf("my rank: %i, received ranks: %s%s%s%s\n", rank, neighbors[0], neighbors[1], neighbors[2], neighbors[3]); 


     } else { 
      // *** SPARE NODES SECTION *** 

     } 
    } else { 
     // not enough nodes reserved 
     if(rank==0) 
      printf("not enough nodes\n"); 
    } 

    // Finalize the MPI environment. 
    MPI_Finalize(); 

} 
関連する問題