我正在尝试测试MPI_Send
没有MPI_Recv
的效果。我有以下程序,我使用openmpi-1.4.5和mvapich2-1.9编译和运行。我知道这些实现适用于MPI标准的2个不同版本,但我认为MPI_Send
和MPI_Recv
在这些标准中是相同的:
#include <mpi.h>
#include <iostream>
#include <assert.h>
using namespace std;
MPI_Comm ping_world;
int mpi_size, mpi_rank;
void* ping(void* args)
{
int ctr = 0;
while(1)
{
char buff[6] = "PING";
++ctr;
for(int i=0; i<mpi_size; ++i)
{
cout << "[" << ctr << "] Rank " << mpi_rank << " sending " << buff << " to rank " << i << endl;
MPI_Send(buff, 6, MPI_CHAR, i, 0, ping_world);
}
}
}
int main(int argc, char *argv[])
{
int provided;
MPI_Init_thread(&argc, &argv, MPI_THREAD_MULTIPLE, &provided);
assert(provided == MPI_THREAD_MULTIPLE);
MPI_Comm_rank (MPI_COMM_WORLD, &mpi_rank);
MPI_Comm_size (MPI_COMM_WORLD, &mpi_size);
{
MPI_Group orig_group;
MPI_Comm_group(MPI_COMM_WORLD, &orig_group);
int ranks[mpi_size];
for(int i=0; i<mpi_size; ++i)
ranks[i] = i;
MPI_Group new_group;
MPI_Group_incl(orig_group, mpi_size, ranks, &new_group);
MPI_Comm_create(MPI_COMM_WORLD, new_group, &ping_world);
}
pthread_t th_ping;
pthread_create(&th_ping, NULL, ping, (void *) NULL);
pthread_join(th_ping, NULL);
return 0;
}
使用mvapich2,我总是得到以下输出(仅此而已)。基本上,该计划似乎在3行之后被绞死:
[1] Rank 0 sending PING to rank 0
[1] Rank 1 sending PING to rank 0
[1] Rank 1 sending PING to rank 1
使用openmpi,我得到以下输出(无休止):
[1] Rank 1 sending PING to rank 0
[1] Rank 1 sending PING to rank 1
[1] Rank 0 sending PING to rank 0
[1] Rank 0 sending PING to rank 1
[2] Rank 0 sending PING to rank 0
[2] Rank 0 sending PING to rank 1
[3] Rank 0 sending PING to rank 0
[3] Rank 0 sending PING to rank 1
[4] Rank 0 sending PING to rank 0
[4] Rank 0 sending PING to rank 1
[5] Rank 0 sending PING to rank 0
[2] Rank 1 sending PING to rank 0
[2] Rank 1 sending PING to rank 1
[3] Rank 1 sending PING to rank 0
[3] Rank 1 sending PING to rank 1
[4] Rank 1 sending PING to rank 0
[4] Rank 1 sending PING to rank 1
[5] Rank 1 sending PING to rank 0
[5] Rank 1 sending PING to rank 1
[6] Rank 1 sending PING to rank 0
问题:
答案 0 :(得分:1)
当调用程序可以安全地重用缓冲区时,MPI_Send可以返回。没有其他保证,但有许多不同的实现依赖行为。不同的实现可以不同地处理消息的缓冲。急切协议还允许将一些短(呃)消息传输到接收等级,而不需要发布匹配的MPI_Recv。
如果您需要MPI在阻止发送返回之前强制执行收到的消息,请查看MPI_Ssend。
答案 1 :(得分:0)
发送数据而不接收数据是一个不正确的MPI程序。您看到的问题是您的发送与任何接收都不匹配。根据实现,MPI_SEND
可能会阻塞,直到在另一端实际收到消息。实际上,我所知道的所有实现都会针对足够大的消息执行此操作(尽管您的6字节消息可能无法在任何地方达到该阈值)。
如果您想在不阻止的情况下发送邮件,则需要使用MPI_ISEND
。但是,即使这样,您最终还是需要调用MPI_TEST
或MPI_WAIT
以确保数据实际发送,而不是仅在本地进行缓冲。
我不确定MVAPICH2挂起的原因,而Open MPI没有,但最终它并不重要。您需要修改您的程序,或者您只是测试不应该真正使用的案例。
答案 2 :(得分:0)
在MVAPICH2(和MPICH)实现中,阻塞(不缓冲)自阻塞发送,直到找到相应的MPI_Recv。这就是它没有挂在“Rank 1发送PING到0级”的原因。这只是一个实现选择。