MPIには大きく分けて
- 1対1通信
- 集団通信
というものがあります。今回は1対1通信について話をします。
1対1通信はその名の通り、PCとPCの間で簡単な通信をするときに使用します。早速やってみましょう。
#include<stdio.h>
#include"mpi.h"
int main(int argc,char *argv[])
{
int rank,size;
MPI_Init(&argc,&argv);
MPI_Comm_rank(MPI_COMM_WORLD,&rank);
MPI_Comm_size(MPI_COMM_WORLD,&size);
printf("hello world I'm %d of %d my number is %d\n",rank,size,mynum);
MPI_Finalize();
return 0;
}
ここで、
- 0番PCで乱数を生成
- 乱数を0番から1番に送信
- 確認
ということをしてみます。
まずは、乱数の動作確認です。
こんな感じ
#include<stdio.h>
#include"mpi.h"
#include<stdlib.h>
#include<time.h>
#define N 10000000
int main(int argc,char *argv[])
{
int rank,size;
int mynum;★★★
MPI_Init(&argc,&argv);
MPI_Comm_rank(MPI_COMM_WORLD,&rank);
MPI_Comm_size(MPI_COMM_WORLD,&size);
srand(time(NULL)+rank);★★★
mynum = rand();★★★
printf("hello world I'm %d of %d my number is %d\n",rank,size,mynum);★★★
MPI_Finalize();
return 0;
}
実行すると…、
$ mpicc -o 004-2 004-2.c
$ mpirun --machinefile ../machinefile ./004-2
hello world I'm 0 of 3 my number is 1031619866
hello world I'm 1 of 3 my number is 731063600
hello world I'm 2 of 3 my number is 428163429
こんな結果になります(数字は乱数なので結果が違っているはずです)。
では、実際に転送するための関数を埋め込みましょう今回は0番のPCから1番のPCに向かって取得した乱数を転送します。
こんな感じ、
#include<stdio.h>
#include"mpi.h"
#include<stdlib.h>
#include<unistd.h>
#include<time.h>
#define N 10000000
int main(int argc,char *argv[])
{
int rank,size;
int mynum;
int myerr=0;★★★
int yournum=0;★★★
MPI_Status status;★★★
MPI_Init(&argc,&argv);
MPI_Comm_rank(MPI_COMM_WORLD,&rank);
MPI_Comm_size(MPI_COMM_WORLD,&size);
srand(time(NULL)+rank);
mynum = rand();
printf("hello world I'm %d of %d my number is %d your number is %d\n",rank,size,mynum,yournum);★★★
sleep(10);★★★
if(rank == 0)★★★
myerr = MPI_Send(&mynum,1,MPI_INT,1,1,MPI_COMM_WORLD);★★★
if(rank == 1)★★★
myerr = MPI_Recv(&yournum,1,MPI_INT,0,1,MPI_COMM_WORLD,&status);★★★
printf("hello world I'm %d of %d my number is %d your number is %d(err No. is %d)\n",rank,size,mynum,yournum,myerr);★★★
MPI_Finalize();
return 0;
}
$ mpirun --machinefile ../machinefile ./004-3
hello world I'm 0 of 3 my number is 2280995 your number is 0
hello world I'm 1 of 3 my number is 1841806718 your number is 0
hello world I'm 2 of 3 my number is 474026168 your number is 0
hello world I'm 2 of 3 my number is 474026168 your number is 0(err No. is 0)
hello world I'm 0 of 3 my number is 2280995 your number is 0(err No. is 0)
hello world I'm 1 of 3 my number is 1841806718 your number is 2280995(err No. is 0)
きちんと0番から1番にメッセージが送られていることを確認できました。
では応用例として、0→1、1→2、2→0と通信してみましょう。
#include<stdio.h>
#include"mpi.h"
#include<stdlib.h>
#include<unistd.h>
#include<time.h>
#define N 10000000
int main(int argc,char *argv[])
{
int rank,size;
int mynum;
int myerr=0;
int yournum=0;
MPI_Status status;
MPI_Init(&argc,&argv);
MPI_Comm_rank(MPI_COMM_WORLD,&rank);
MPI_Comm_size(MPI_COMM_WORLD,&size);
srand(time(NULL)+rank);
mynum = rand();
printf("hello world I'm %d of %d my number is %d your number is %d\n",rank,size,mynum,yournum);
sleep(10);
myerr = MPI_Send(&mynum ,1,MPI_INT,(rank+1)%size, (rank+1)%size,MPI_COMM_WORLD);★★★
myerr = MPI_Recv(&yournum,1,MPI_INT,(rank+size-1)%size,rank ,MPI_COMM_WORLD,&status);★★★
printf("hello world I'm %d of %d my number is %d your number is %d(err No. is %d)\n",rank,size,mynum,yournum,myerr);
MPI_Finalize();
return 0;
}
結果はこんな感じ、
$ mpicc -o 004-4 004-4.c
$ mpirun --machinefile ../machinefile ./004-4
hello world I'm 0 of 3 my number is 1984022592 your number is 0
hello world I'm 1 of 3 my number is 592282443 your number is 0
hello world I'm 2 of 3 my number is 1368506247 your number is 0
hello world I'm 0 of 3 my number is 1984022592 your number is 1368506247(err No. is 0)
hello world I'm 1 of 3 my number is 592282443 your number is 1984022592(err No. is 0)
hello world I'm 2 of 3 my number is 1368506247 your number is 592282443(err No. is 0)
ね、かんたんでしょ?実はこれをもっと簡単に書く方法があります。一行でSend と Recvを実現している関数を使います。
#include<stdio.h>
#include"mpi.h"
#include<stdlib.h>
#include<unistd.h>
#include<time.h>
#define N 10000000
int main(int argc,char *argv[])
{
int rank,size;
int mynum;
int myerr=0;
int yournum=0;
MPI_Status status;
MPI_Init(&argc,&argv);
MPI_Comm_rank(MPI_COMM_WORLD,&rank);
MPI_Comm_size(MPI_COMM_WORLD,&size);
srand(time(NULL)+rank);
mynum = rand();
printf("hello world I'm %d of %d my number is %d your number is %d\n",rank,size,mynum,yournum);
sleep(10);
myerr = MPI_Sendrecv(&mynum,1,MPI_INT,(rank+1)%size,(rank+1)%size,&yournum,1,MPI_INT,(rank+size-1)%size,rank,MPI_COMM_WORLD,&status);★★★
printf("hello world I'm %d of %d my number is %d your number is %d(err No. is %d)\n",rank,size,mynum,yournum,myerr);
MPI_Finalize();
return 0;
}
結果はこんな感じ、
$ mpicc -o 004-5 004-5.c
$ mpirun --machinefile ../machinefile ./004-5
hello world I'm 0 of 3 my number is 95868441 your number is 0
hello world I'm 1 of 3 my number is 860512961 your number is 0
hello world I'm 2 of 3 my number is 1637154686 your number is 0
hello world I'm 1 of 3 my number is 860512961 your number is 95868441(err No. is 0)
hello world I'm 2 of 3 my number is 1637154686 your number is 860512961(err No. is 0)
hello world I'm 0 of 3 my number is 95868441 your number is 1637154686(err No. is 0)
今回はこれまで。