0
0

More than 3 years have passed since last update.

C言語+MPIのtips(MPI_Allgather)

Last updated at Posted at 2020-10-24

MPI_Allgatherは「各プロセスの持つ同じ長さのデータを結合して,全てのプロセスに渡す関数」。
※MPI_Gatherはある一つのプロセスに渡すことに注意。

【目的】

各プロセスの一次元配列 div を結合した配列 cmb を作り、全てのプロセスへ送信することで MPI_Allgather の機能を知る。

【使用するもの】


open-mpi

【環境】


$ mpicc —version


Apple clang version 11.0.3 (clang-1103.0.32.29) 


Target: x86_64-apple-darwin19.6.0 


Thread model: posix 


InstalledDir: /Library/Developer/CommandLineTools/usr/bin

【方法】

Allgather.c
#include<stdio.h>
#include<stdlib.h>
#include<mpi.h>

#define N 3

int main(int argc, char **argv){
        int my_rank, num_proc;
        int i,j, div[N];
        int *cmb;

        MPI_Init(&argc, &argv);
        MPI_Comm_size(MPI_COMM_WORLD, &num_proc);
        MPI_Comm_rank(MPI_COMM_WORLD, &my_rank);

        for(i=0;i<N;i++) div[i] = i*4+my_rank;
        printf("myrank:%d, div[0]=%d, div[1]=%d, div[2]=%d\n",my_rank,div[0],div[1],div[2]);

        cmb=(int *)malloc(N*num_proc*sizeof(int));
        if (cmb==NULL){
            printf("arr\n");
            return 1;
        }

        for(j=0;j<N*num_proc;j++) cmb[j]=-1;

        MPI_Allgather(div, N, MPI_INT, cmb, N, MPI_INT, MPI_COMM_WORLD);

        for(j=0;j<N*num_proc;j++) printf("my_rank:%d, cmb[%d] = %d\n",my_rank,j,cmb[j]);
        free(cmb);

MPI_Finalize();
return 0;
}

【結果】
mpicc コマンドでコンパイル、mpirun コマンドでプロセス数を2にして実行。

$ mpicc Allgather.c
$ mpirun -np 2 ./a.out
myrank:0, div[0]=0, div[1]=4, div[2]=8
myrank:1, div[0]=1, div[1]=5, div[2]=9
my_rank:0, cmb[0] = 0
my_rank:0, cmb[1] = 4
my_rank:0, cmb[2] = 8
my_rank:0, cmb[3] = 1
my_rank:0, cmb[4] = 5
my_rank:0, cmb[5] = 9
my_rank:1, cmb[0] = 0
my_rank:1, cmb[1] = 4
my_rank:1, cmb[2] = 8
my_rank:1, cmb[3] = 1
my_rank:1, cmb[4] = 5
my_rank:1, cmb[5] = 9

【考察(何が起きたのか)】



まずプロセス0と1でそれぞれ div[0]、div[1]、div[2]が生成される。それぞれのプロセスで値が格納される。

at プロセス0 div[0]=0*4+0=0、div[1]=1*4+0=4、div[2]=2*4+0=8


at プロセス1 div[0]=0*4+1=1、div[1]=1*4+1=5、div[2]=2*4+1=9

次にプロセス0と1でそれぞれ cmb[0]から cmb[5]までがメモリ割り当てされる。それぞれのプロセスで値が格納される。

at プロセス0 cmb[0]=-1、cmb[1]=-1、・・・、cmb[5]=-1



at プロセス1 cmb[0]=-1、cmb[1]=-1、・・・、cmb[5]=-1

MPI_Allgatherによって各々のプロセスの「div」から、「N」個ずつデータが送信される。データの型は整数(int)「MPI_INT」である。「cmb」がその「N」個ずつの整数型(int)「MPI_INT」のデータを受信して結合する。送信先は全てのプロセスである。
つまり


at プロセス0 cmb[0]=0、cmb[1]=4、cmb[0]=8、cmb[3]=1、cmb[4]=5、cmb[5]=9

at プロセス1 cmb[0]=0、cmb[1]=4、cmb[0]=8、cmb[3]=1、cmb[4]=5、cmb[5]=9

となる。


それぞれのプロセスで cmbが表示されて終了。free(cmb) で各プロセスのメモリを解放。

【参考】
「mpi 並列プログラミング」と検索すると、より正確でより情報量の多い資料が見つかります。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0