MPI:当不知道预期 MPI_Recv 的数量时该怎么办

kor*_*esh 5 c mpi

我有许多从节点,它们可能会或可能不会向主节点发送消息。所以目前主节点无法知道有多少 MPI_Recv 期望。出于效率原因,从节点必须向主节点发送最少数量的消息。

我设法找到了一个很酷的技巧,当它不再期待任何消息时,它会发送一个额外的“完成”消息。不幸的是,在我的情况下,它似乎不起作用,因为发件人的数量是可变的。关于如何解决这个问题的任何想法?谢谢!

if(rank == 0){ //MASTER NODE

    while (1) {

        MPI_Recv(&buffer, 10, MPI_INT, MPI_ANY_SOURCE, MPI_ANY_TAG, MPI_COMM_WORLD, &status);

        if (status.MPI_TAG == DONE) break;


        /* Do stuff */
    }

}else{ //MANY SLAVE NODES

    if(some conditions){
        MPI_Send(&buffer, 64, MPI_INT, root, 1, MPI_COMM_WORLD);
    }

}


MPI_Barrier(MPI_COMM_WORLD);
MPI_Send(NULL, 1, MPI_INT, root, DONE, MPI_COMM_WORLD);
Run Code Online (Sandbox Code Playgroud)

不工作,程序似乎仍在等待 MPI_Recv

hou*_*sam 1

1- 你调用MPI_Barrier错地方了,应该在 后调用MPI_Send
2-当根收到DONE来自所有其他等级(大小-1)时,它将退出循环。

修改后的代码:

#include <mpi.h>
#include <stdlib.h>
#include <stdio.h>

int main(int argc, char** argv)
{

    MPI_Init(NULL, NULL);
    int size;
    MPI_Comm_size(MPI_COMM_WORLD, &size);
    int rank;
    MPI_Comm_rank(MPI_COMM_WORLD, &rank);
    MPI_Status status;
    int DONE = 888;
    int buffer = 77;
    int root = 0 ;
    printf("here is rank %d with size=%d\n" , rank , size);fflush(stdout);
    int num_of_DONE = 0 ;
 if(rank == 0){ //MASTER NODE


    while (1) {

        MPI_Recv(&buffer, 1, MPI_INT, MPI_ANY_SOURCE, MPI_ANY_TAG, MPI_COMM_WORLD, &status);
        printf("root recev %d from %d with tag = %d\n" , buffer , status.MPI_SOURCE , status.MPI_TAG );fflush(stdout);

        if (status.MPI_TAG == DONE)
        num_of_DONE++;
    printf("num_of_DONE=%d\n" , num_of_DONE);fflush(stdout);
    if(num_of_DONE == size -1)
        break;



        /* Do stuff */
    }

}else{ //MANY SLAVE NODES

    if(1){
        buffer = 66;
        MPI_Send(&buffer, 1, MPI_INT, root, 1, MPI_COMM_WORLD);
        printf("rank %d sent data.\n" , rank);fflush(stdout);
    }

}

    if(rank != 0)
    {
        buffer = 55;
        MPI_Send(&buffer, 1, MPI_INT, root, DONE, MPI_COMM_WORLD);
    }


    MPI_Barrier(MPI_COMM_WORLD);
    printf("rank %d done.\n" , rank);fflush(stdout);
    MPI_Finalize();
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

输出:

    hosam@hosamPPc:~/Desktop$ mpicc -o aa aa.c
    hosam@hosamPPc:~/Desktop$ mpirun -n 3 ./aa
here is rank 2 with size=3
here is rank 0 with size=3
rank 2 sent data.
here is rank 1 with size=3
rank 1 sent data.
root recev 66 from 1 with tag = 1
num_of_DONE=0
root recev 66 from 2 with tag = 1
num_of_DONE=0
root recev 55 from 2 with tag = 888
num_of_DONE=1
root recev 55 from 1 with tag = 888
num_of_DONE=2
rank 0 done.
rank 1 done.
rank 2 done.
Run Code Online (Sandbox Code Playgroud)