1. node 1 -> node 0 로 값을 보내는 경우
#include <mpi.h>
#include <stdio.h>
int main(){
int my_rank,p;
int a,b;
MPI_Status status;
int source =1, dest=0,tag=5;
MPI_Init(NULL,NULL);
MPI_Comm_size(MPI_COMM_WORLD,&p);
MPI_Comm_rank(MPI_COMM_WORLD,&my_rank);
if(my_rank==1){
a=10;
MPI_Send(&a,1,MPI_INT,dest,tag,MPI_COMM_WORLD);
}
else if(my_rank==0){
MPI_Recv(&b,1,MPI_INT,source,tag,MPI_COMM_WORLD,&status);
printf("received date=%d",b);
}
MPI_Finalize();
return 0;
}
2. 메세지 받는 순서를 정하는 경우
#include<stdio.h>
#include<mpi.h>
int main(void){
int rank, n;
int a,i;
MPI_Init(NULL,NULL);
MPI_Comm_rank(MPI_COMM_WORLD,&rank);
MPI_Comm_size(MPI_COMM_WORLD,&n);
if(rank!=0){
a=rank*15;
MPI_Send(&a,1,MPI_INT,0,5,MPI_COMM_WORLD);
}
else{
for(i=1;i<n;i++)
{
MPI_Recv(&a,1,MPI_INT,i,5,MPI_COMM_WORLD,MPI_STATUS_IGNORE);
printf("%d\n",a);
}
}
MPI_Finalize();
return 0;
}
순서를 정해준 경우에는 process 1부터 순서대로 출력되는 것을 볼 수 있다.
3. 메세지 받는 순서를 정하지 않고 받는 경우
#include<stdio.h>
#include<mpi.h>
int main(void){
int a,b,i;
int my_rank,p;
MPI_Status status;
int dest=0, tag=5;
MPI_Init(NULL,NULL);
MPI_Comm_rank(MPI_COMM_WORLD,&my_rank);
MPI_Comm_size(MPI_COMM_WORLD,&p);
if(my_rank!=0){
a=10+my_rank;
MPI_Send(&a,1,MPI_INT,dest,tag,MPI_COMM_WORLD);
}
else if(my_rank==0){
for(i=1;i<p;i++){
MPI_Recv(&b,1,MPI_INT,MPI_ANY_SOURCE,tag,MPI_COMM_WORLD,&status);
printf("source=%d data=%d",status.MPI_SOURCE,b);
}
}
MPI_Finalize();
return 0;
}
source부분에 MPI_ANY_SOURCE를 썼기 때문에 source의 순서에 상관없이 먼저온 순서대로 처리하는 것을 볼 수 있다. 또한 출력 부분에서 status.MPI_SOURCE를 이용하여 프로세스의 rank번호를 알아내었다.
4. 메세지를 모두 받은 후에 한꺼번에 출력하는 경우
#include<stdio.h>
#include<mpi.h>
int main(void){
int a, b[10],source[10],i;
int my_rank,p;
MPI_Status status;
int dest=0, tag=5;
MPI_Init(NULL,NULL);
MPI_Comm_rank(MPI_COMM_WORLD,&my_rank);
MPI_Comm_size(MPI_COMM_WORLD,&p);
if(my_rank!=0){
a=10+my_rank;
MPI_Send(&a,1,MPI_INT,dest,tag,MPI_COMM_WORLD);
}
else if(my_rank==0){
for(i=0;i<p-1;i++){
MPI_Recv(b+i,1,MPI_INT,MPI_ANY_SOURCE,tag,MPI_COMM_WORLD,&status);
source[i]=status.MPI_SOURCE;
}
for(i=0;i<p-1;i++){
printf("source=%d data=%d\n",source[i],b[i]);
}
}
MPI_Finalize();
return 0;
}
메세지를 한번에 받아 배열에 저장한 후, 배열에 들어있는 결과값을 출력하는 형태의 프로그램이다. 이 프로그램에서는 순서를 지정하지 않고, 받을 때 status.MPI_SOURCE를 이용하여 프로세스의 번호를 같이 저장하였기 때문에 순서를 지정한 경우보다 더 빠르게 실행될 수 있다.
5. 도착메세지의 길이가 다른경우
#include <stdio.h>
#include<mpi.h>
int main(){
int a[10],b[10],i,j,count,my_rank,size;
MPI_Status status;
MPI_Init(NULL,NULL);
MPI_Comm_rank(MPI_COMM_WORLD,&my_rank);
MPI_Comm_size(MPI_COMM_WORLD,&size);
if(my_rank!=0){
for(i=0;i<my_rank;i++){
a[i]=my_rank+i;
}
MPI_Send(a,my_rank,MPI_INT,0,5,MPI_COMM_WORLD);
}
else if(my_rank==0){
for(i=1;i<size;i++){
MPI_Recv(b,10,MPI_INT,MPI_ANY_SOURCE,MPI_ANY_TAG,MPI_COMM_WORLD,&status);
printf("source=%d tag=%d\n",status.MPI_SOURCE,status.MPI_TAG);
MPI_Get_count(&status,MPI_INT,&count);
for(j=0;j<count;j++)
printf("%d ",b[j]);
printf("\n");
}
}
MPI_Finalize();
return 0;
}
도착메세지의 길이가 다른 경우에는 MPI_Get_count(상태변수,데이터타입,길이저장변수)를 사용하여 도착메세지의 길이를 저장한다음, for문을 이용하여 출력해주면된다. 이 경우에도 MPI_ANY_SOURCE를 이용하여 순서 상관없이 메세지를 전송받고있다.
6. 메세지가 모든 노드들을 돌아서 다시 노드0로 오는 경우
#include<stdio.h>
#include<mpi.h>
int main(void){
int rank,n,token,i,src,dest;
MPI_Init(NULL,NULL);
MPI_Comm_rank(MPI_COMM_WORLD,&rank);
MPI_Comm_size(MPI_COMM_WORLD,&n);
src=(rank+n-1)%n;
dest=(rank+1)%n;
if(rank==0) token=10;
if(rank==0){
MPI_Send(&token,1,MPI_INT,dest,5,MPI_COMM_WORLD);
MPI_Recv(&token,1,MPI_INT,src,5,MPI_COMM_WORLD,MPI_STATUS_IGNORE);
printf("돌아온값=%d",token);
}
else{
MPI_Recv(&token,1,MPI_INT,src,5,MPI_COMM_WORLD,MPI_STATUS_IGNORE);
token++;
MPI_Send(&token,1,MPI_INT,dest,5,MPI_COMM_WORLD);
}
MPI_Finalize();
}
process0에서는 data를 먼저 보내고, 마지막에 받아야하며 나머지 process들은 data를 먼저받고 마지막에 보내야하는 것을 유의해야한다. 모든 노드를 방문하고 마지막에 process0으로 왔을 때, 출력되는 프로그램이다.
7. 모든 노드가 send를 먼저하고 receive를 나중에 하는 경우
#include<stdio.h>
#include<mpi.h>
int main(void){
int rank,n,a,b,i,src,dest;
MPI_Init(NULL,NULL);
MPI_Comm_rank(MPI_COMM_WORLD, &rank);
MPI_Comm_size(MPI_COMM_WORLD,&n);
a=rank*10;
src=(rank+n-1)%n;
dest=(rank+1)%n;
MPI_Send(&a,1,MPI_INT,dest,5,MPI_COMM_WORLD);
MPI_Recv(&b,1,MPI_INT,src,5,MPI_COMM_WORLD,MPI_STATUS_IGNORE);
printf("process=%d result=%d \n",rank,b);
MPI_Finalize();
return 0;
}
프로세스 기준에서 데이터 값을 보내고 데이터를 받기 때문에 정상적ㅇ로 동작한다. 이때 순서를 정해준 것은 아니기 때문에 먼저도착한 순서대로 출력된다.
'Cloud Computing' 카테고리의 다른 글
9. MPI프로그램 집합통신 (Collective Communication) (0) | 2020.10.21 |
---|---|
8. MPI프로그램 1:1 통신모드 (1:1 Communication Modes) (6) | 2020.10.21 |
6. MPI program: Coding, Compile, and Run (0) | 2020.10.21 |
5. 병렬 프로그램의 성능 평가 (Performance) (0) | 2020.10.21 |
4. 인터커넥션 네트워크 (Interconnection Networks) (0) | 2020.10.21 |