MPI_Allreduce は「各プロセスの持つ同じ長さのデータを何らかの演算をして,その結果をすべてのプロセスに渡す関数」。
※ MPI_Reduce は結果をある一つのプロセスに渡していたことに注意。
【目的】
一次元配列 my の和を求めることで MPI_Allreduce の機能を知る。
【使用するもの】
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"mpi.h"
int main(int argc, char *argv[]){
int my_rank, num_proc;
int i, my[3], sum[3];
int j;
MPI_Init(&argc, &argv);
MPI_Comm_size(MPI_COMM_WORLD, &num_proc);
MPI_Comm_rank(MPI_COMM_WORLD, &my_rank);
for(i=0;i<3;i++) my[i] = i*4 + my_rank;
printf("my_rank=%d, my[0]= %d, my[1]= %d, my[2]= %d\n",my_rank,my[0], my[1],my[2]);
MPI_Allreduce(my, sum, 3, MPI_INT, MPI_SUM, MPI_COMM_WORLD);
printf("my_rank:%d, sum[0]= %d, sum[1]= %d, sum[2]= %d\n",my_rank, sum[0], sum[1],sum[2]);
MPI_Finalize();
return 0;
}
【結果】
mpicc コマンドでコンパイル、mpirun コマンドでプロセス数を2にして実行。
$ mpicc Allreduce.c
$ mpirun -np 2 ./a.out
my_rank=1, my[0]= 1, my[1]= 5, my[2]= 9
my_rank=0, my[0]= 0, my[1]= 4, my[2]= 8
my_rank:1, sum[0]= 1, sum[1]= 9, sum[2]= 17
my_rank:0, sum[0]= 1, sum[1]= 9, sum[2]= 17
【考察(何が起きたのか)】
まずプロセス0と1でそれぞれ my[0]、my[1]、my[2]が生成される。
それぞれのプロセスでのfor文で値が格納される。
at プロセス0 my[0]=04+0=0、my[1]=14+0=4、my[2]=24+0=8
at プロセス1 my[0]=04+1=1、my[1]=14+1=5、my[2]=24+1=9
MPI_Allreduceによって「my」が送信され「sum」が受信される。要素の数は「3」、データの型は整数(int)「MPI_INT」、操作は和を求めること「MPI_SUM」。
sum[0]=(プロセス0でのmy[0])+(プロセス1でのmy[0])
sum[1]=(プロセス0でのmy[1])+(プロセス1でのmy[1])
sum[2]=(プロセス0でのmy[2])+(プロセス1でのmy[2])
結果は全てのプロセスへ送信される。
それぞれのプロセスでsumが表示されて終了。
【参考】
「mpi 並列プログラミング」と検索すると、より正確でより情報量の多い資料が見つかります。