2

据我了解,MPI 通信器限制了通信范围,因此从一个通信器发送的消息永远不会在另一个通信器中接收。

然而,下面内联的程序似乎与此相矛盾。

我知道MPI_Send调用在发布匹配接收之前返回,因为它在引擎盖下进行了内部缓冲(而不是MPI_Ssend)。我也明白这MPI_Comm_free不会立即破坏通信器,而只是将其标记为释放并等待任何挂起的操作完成。我想我不匹配的发送操作将永远挂起,但是我想知道为什么同一个对象(整数值)会被第二个通信器重用!?

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

任何建议都非常感谢!

后期编辑:发布后续问题


#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
4

1 回答 1

0

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

于 2014-05-22T14:13:09.490 回答