MPI_Gather は「各プロセスの持つ同じ長さのデータを結合して,あるプロセスに渡す関数」。
【目的】
各プロセスの一次元配列 div を結合した配列 cmb を作り、プロセス0へ送信することで MPI_Gather の機能を知る。
【使用するもの】
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
【方法】
#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_Gather(div, N, MPI_INT, cmb, N, MPI_INT, 0, 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 Gather.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:1, cmb[0] = -1
my_rank:1, cmb[1] = -1
my_rank:1, cmb[2] = -1
my_rank:1, cmb[3] = -1
my_rank:1, cmb[4] = -1
my_rank:1, cmb[5] = -1
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
【考察(何が起きたのか)】
まずプロセス0と1でそれぞれ div[0]、div[1]、div[2]が生成される。それぞれのプロセスで値が格納される。
at プロセス0 div[0]=04+0=0、div[1]=14+0=4、div[2]=24+0=8
at プロセス1 div[0]=04+1=1、div[1]=14+1=5、div[2]=24+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_Gatherによって各々のプロセスの「div」から、「N」個ずつデータが送信される。データの型は整数(int)「MPI_INT」である。「cmb」がその「N」個ずつの整数型(int)「MPI_INT」のデータを受信して結合する。送信先はプロセス「0」である。プロセス1のcmbの要素は変化なし。
つまり
at プロセス0 cmb[0]=-1、cmb[1]=-1、・・・、cmb[5]=-1
at プロセス1 cmb[0]=0、cmb[1]=4、cmb[0]=8、cmb[3]=1、cmb[4]=5、cmb[5]=9
となる。
それぞれのプロセスで cmbが表示されて終了。free(cmb)で各プロセスのメモリを解放。
【参考】
「mpi 並列プログラミング」と検索すると、より正確でより情報量の多い資料が見つかります。