Я пытаюсь реализовать простую версию MPI_reduce с подпрограммами точка-точка (MPI_send и MPI_recv). Я просто хочу смоделировать сокращение массива [0,1,2]
до root с помощью операции SUM. Вот мой код:
#include <stdio.h>
#include <stdlib.h>
#include <mpi.h>
void my_reduce(void* send_data,void* recv_data,int count, MPI_Datatype datatype,MPI_Op op,int root,MPI_Comm communicator){
int world_rank;
MPI_Comm_rank(communicator, &world_rank);
int world_size;
MPI_Comm_size(communicator, &world_size);
int tmp=*((int*)recv_data);
printf("current recv_data is %d\n",*(int*)recv_data);
if(world_rank==root){
MPI_Recv(recv_data,count,datatype,root,0,communicator,MPI_STATUS_IGNORE);
tmp+=*((int*)recv_data);
*((int*)recv_data)=tmp;
printf("the value after reduce is now is %d\n",*((int*)recv_data));
}else{
MPI_Send(send_data,count,datatype,root,0,communicator);
printf("now sending %d to root\n",*((int*)send_data));
}
}
int main(int argc, char** argv) {
MPI_Init(NULL, NULL);
int world_rank;
MPI_Comm_rank(MPI_COMM_WORLD, &world_rank);
int data[3]={0,1,2};
int dest;
dest=0;
if(world_rank==1){
my_reduce(&data[1],&dest,1,MPI_INT,MPI_SUM,0,MPI_COMM_WORLD);
}
if(world_rank==0){
my_reduce(&data[0],&dest,1,MPI_INT,MPI_SUM,0,MPI_COMM_WORLD);
}
if(world_rank==2){
my_reduce(&data[2],&dest,1,MPI_INT,MPI_SUM,0,MPI_COMM_WORLD);
}
if(world_rank==0){
my_reduce(&data[0],&dest,1,MPI_INT,MPI_SUM,0,MPI_COMM_WORLD);
}
MPI_Finalize();
printf("value of destination after reduce is %d\n",(dest));
return 0;
}
Я запутался в том, как получать несколько таймов от отправки. В этом примере root получает 2 раза от второго и третьего процесса. Мой код дает неправильный вывод:
current recv_data is 0
now sending 1 to root
current recv_data is 0
current recv_data is 0
now sending 2 to root
Если я добавлю два MPI_recv в одну ветвь, то есть:
if(world_rank==0){
my_reduce(&data[0],&dest,1,MPI_INT,MPI_SUM,0,MPI_COMM_WORLD);
my_reduce(&data[0],&dest,1,MPI_INT,MPI_SUM,0,MPI_COMM_WORLD);
}
Это все еще неправильно. Не могли бы вы дать несколько советов по как это исправить?