LoginSignup
0
0

More than 3 years have passed since last update.

C言語+MPIのtips(MPI_Gather)

Last updated at Posted at 2020-10-24

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

【方法】

Gather.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_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]=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_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 並列プログラミング」と検索すると、より正確でより情報量の多い資料が見つかります。

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