[英]MPI_Recv and timeout
我有个问题 。 假设我有np个进程,对于每个进程,我都会根据输入文件计算需要发送给其他每个进程的消息数量(从0到...),我想向其发送此编号。 问题是我只能从通过直接连接的节点创建的拓扑中发送。 所以基本上我希望每个进程将一个int发送给所有其他进程,我有以下算法(将使用伪代码):
for(i=1,np){
if(i!=rankID){
MPI_Send(&nr,1,MPI_INT,topology[i][nexthop],DATA,MPI_COMM_WORLD);
MPI_SEND(&i,1,MPI_INT,topology[i][nexthop],DATA,MPI_COMM,WORLD); //i send the destination along with the int
}
}
while(1){
MPI_Recv(&recvInt,1,MPI_INT,MPI_ANY_SOURCE,DATA,MPI_COMM,WORLD);
MPI_Recv(&destination,MPI_INT,MPI_ANY_SOURCE,DATA,MPI_COMM,WORLD);
if(destination == rankID){
ireceive+=recvInt;
receivedFrom++;
//normally i would break if i received all np-1 messages but what if someone sends a message through me for another process ?
}
else{
MPI_Send(&recvInt,1,MPI_INT,topology[destination][nexthop],DATA,MPI_COMM_WORLD);
MPI_Send(&destination,1,MPI_INT,topology[destination][nexthop],DATA,MPI_COMM_WORLD);
}
}
现在进一步解释一下。在这个小算法的结尾,我希望每个进程都知道下一步将收到多少消息。
为了将消息从每个节点发送到每个节点,我使用了我创建的上一个路由表。基本上每个节点都有一个包含所有节点的矩阵,并且topology [node] [1] =下一跳(这就是为什么我在上面输入了nexthop的原因)代码)。
每个节点都知道有np个进程,因此每个节点将必须接收np-1条消息(他是目的地)。
我遇到的问题是,在收到np-1消息后,我无法中断,因为我可能是其他进程的next_hop,并且该消息将不会发送。 所以我想做这样的事情,使用MPI_TEST或另一条指令来查看我的Recv是否正在实际接收东西,或者它只是坐在那里,因为如果程序阻塞1-2秒,很明显它不会接收任何更多(因为我没有一个大的拓扑,最多20-30个进程)。
问题是我从来没有使用过MPI_Test或其他语法,而且我不确定该怎么做。有人可以帮我为Recv创建超时,或者是否有其他解决方案? 谢谢你,很抱歉长文本
可能不是最高效的代码,但是它应该可以工作(我没有机会对其进行测试)
MPI_Request request;
MPI_Status status;
for(i=1,np){
if(i!=rankID){
MPI_ISend(&nr,1,MPI_INT,topology[i][nexthop],DATA,MPI_COMM_WORLD);
MPI_ISend(&i,1,MPI_INT,topology[i][nexthop],DATA,MPI_COMM,WORLD); //i send the destination along with the int
}
}
while(1){
bool over = false;
if(over == true)
break;
if(recievedFrom < np){
MPI_Recv(&recvInt,1,MPI_INT,MPI_ANY_SOURCE,DATA,MPI_COMM,WORLD);
MPI_Recv(&destination,MPI_INT,MPI_ANY_SOURCE,DATA,MPI_COMM,WORLD);
if(destination == rankID){
ireceive+=recvInt;
receivedFrom++;
//normally i would break if i received all np-1 messages but what if someone sends a message through me for another process ?
}
else{
MPI_Send(&recvInt,1,MPI_INT,topology[destination][nexthop],DATA,MPI_COMM_WORLD);
MPI_Send(&destination,1,MPI_INT,topology[destination][nexthop],DATA,MPI_COMM_WORLD);
}
}
else {
MPI_Irecv(&recvInt,1,MPI_INT,MPI_ANY_SOURCE,DATA,MPI_COMM,WORLD, request); // non blocking recieve call after you finished receiving everything addressed to you
time_t now = time(NULL);
while(time(NULL) < now + time_you_set_until_timeout){
over = true;
int flag = 0;
MPI_Test(req, flag, status);
if(flag){
over = false;
break; //exit timeout loop if something was received
}
}
}
if(!over){
MPI_Recv(&destination,MPI_INT,MPI_ANY_SOURCE,DATA,MPI_COMM,WORLD);
//route the message and continue
}
}
无论如何,由于您不知道消息在拓扑中通过之前会经过多少时间,因此应谨慎选择超时时间。 您可以尝试实现某种其他类型的信令机制,例如广播一条消息,告知该节点已收到发给该节点的所有消息。 可以增加发送的消息数量,但可以确保每个人都能得到所有信息。 另外,您可以尝试打包或序列化要发送的数据,以便只有一个Send / Recv调用,这将使您的代码更易于使用(我认为)。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.