集合通信の例: scatter

プログラム: scatter.c

#include "mpi.h"
#define N 64
main( argc, argv )
int argc;
char **argv;
{
    int myrank;

    int a[N], local_a[N];
    int sum, local_sum;
    int i;
    int p;
    MPI_Status status;

    MPI_Init( &argc, &argv );
    MPI_Comm_rank( MPI_COMM_WORLD, &myrank );
    MPI_Comm_size( MPI_COMM_WORLD, &p );

    if (myrank == 0){
      for (i=0; i<N; i++){
        a[i]=(i+1);
      }
    }
    MPI_Scatter(a, N/p, MPI_INT, local_a , N/p, MPI_INT, 0, MPI_COMM_WORLD);

    local_sum = 0;
    for (i=0; i<(N/p); i++){
      local_sum = local_sum + local_a[i];
    }

    if (myrank == 0){
      sum = local_sum;
      for (i=1; i<p; i++){
        MPI_Recv(&local_sum, 1, MPI_INT, i, 99, MPI_COMM_WORLD, &status);
        sum = sum + local_sum;
      }
    }
    else{
      MPI_Send(&local_sum, 1, MPI_INT, 0, 99, MPI_COMM_WORLD);
    }

    if (myrank == 0){
      printf("sum of each local_sum = %d\n", sum);
    }

    MPI_Finalize();
  }

コンパイルと実行

   % cc -64 scatter.c -lmpi
   % mpirun -np 4 ./a.out

scatter

int MPI_Scatter ( 
        void *sendbuf,  // address of send buffer 
                        // (choice, significant only at root) 
        int sendcnt,    // number of elements sent to each process 
                        // (integer, significant only at root) 
        MPI_Datatype sendtype, // data type of send buffer elements 
                               // (significant only at root) (handle) 
        void *recvbuf,  // number of elements in receive buffer (integer) 
        int recvcnt,    // data type of receive buffer elements (handle) 
        MPI_Datatype recvtype, // int root, rank of sending process (integer) 
        MPI_Comm comm   // communicator (handle)  
        )

解説

ルートプロセスでN個分の配列要素を1からNまでの値で最初埋めておく.ついで, (自分を除く)各プロセスに,これを分散送付する.その際,大きさはN/p.また, 最初のブロックlocal_aはルートプロセスに残り,次のブロックはプロセス1に, その次のブロックはプロセス2という風に,分割される.

ついで,ルートプロセスを含む全プロセスでローカルな和を計算.ルートプロセス 以外のプロセスはそれをルートプロセスに送り,ルートプロセスはすべての局所和を 集め,プリントする.