在不同的通信器中收到的MPI消息

时间:2014-05-22 13:16:27

标签: mpi intel-mpi

据我所知,MPI传播者限制了沟通的范围 从一个通信器发送的消息永远不应该在另一个通信器中接收。

但是,下面列出的程序似乎与此相矛盾。

我理解MPI_Send调用在匹配的接收发布之前返回,因为它在内部缓冲(而不是MPI_Ssend)。我也明白MPI_Comm_free不会立即破坏通信器,而只是将其标记为重新分配并等待任何未完成的操作完成。我想我的无法匹配的发送操作将永远悬而未决,但后来我想知道第二个通信器如何重用相同的对象(整数值)?

这是正常行为,MPI库实现中的错误,还是我的程序错误?

非常感谢任何建议!

LATER EDIT:发布了follow-up question


#include "stdio.h"
#include "unistd.h"
#include "mpi.h"

int main(int argc, char* argv[]) {
    int  rank, size;
    MPI_Group group;
    MPI_Comm my_comm;

    MPI_Init(&argc, &argv);

    MPI_Comm_rank(MPI_COMM_WORLD, &rank);
    MPI_Comm_size(MPI_COMM_WORLD, &size);
    MPI_Comm_group(MPI_COMM_WORLD, &group);

    MPI_Comm_create(MPI_COMM_WORLD, group, &my_comm);
    if (rank == 0) printf("created communicator %d\n", my_comm);

    if (rank == 1) {
        int msg = 123;
        MPI_Send(&msg, 1, MPI_INT, 0, 0, my_comm);
        printf("rank 1: message sent\n");
    }

    sleep(1);
    if (rank == 0) printf("freeing communicator %d\n", my_comm);
    MPI_Comm_free(&my_comm);

    sleep(2);

    MPI_Comm_create(MPI_COMM_WORLD, group, &my_comm);
    if (rank == 0) printf("created communicator %d\n", my_comm);

    if (rank == 0) {
        int msg;
        MPI_Recv(&msg, 1, MPI_INT, 1, 0, my_comm, MPI_STATUS_IGNORE);
        printf("rank 0: message received\n");
    }

    sleep(1);
    if (rank == 0) printf("freeing communicator %d\n", my_comm);
    MPI_Comm_free(&my_comm);

    MPI_Finalize();
    return 0;
}

输出:

created communicator -2080374784
rank 1: message sent
freeing communicator -2080374784
created communicator -2080374784
rank 0: message received
freeing communicator -2080374784

1 个答案:

答案 0 :(得分:0)

您看到的号码只是沟通者的句柄。因为您已经释放它,所以重复使用手柄是安全的。至于为什么您能够发送消息,请查看您如何创建通信器。当您使用MPI_Comm_group时,您将获得一个包含与指定通信器关联的排名的组。在这种情况下,您将获得所有等级,因为您获得了MPI_COMM_WORLD的组。然后,您正在使用MPI_Comm_create基于一组排名创建通信器。您正在使用您刚刚获得的同一组,其中包含所有级别。因此,您的新沟通者拥有MPI_COMM_WORLD的所有级别。如果您希望您的通信器仅包含一个列的子集,您将需要使用不同的功能(或多个功能)来创建所需的组。我建议阅读MPI标准的第6章,它包含了您需要的所有功能。选择你需要的东西来建立你想要的沟通者。