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