C MPI_Iprobe未正确设置标志
我最近在使用MPI_Iprobe时遇到了麻烦。我在下面附上了一些代码来尝试和演示这个问题(注意:我使用的代码是不同的,这些代码纯粹是为了创建我的问题的最小可复制示例) 我要做的是使秩为0的进程向秩为1的进程发送请求消息。秩0可以在循环中的任意点发送此消息(因此我使用if语句-C MPI_Iprobe未正确设置标志,c,parallel-processing,mpi,C,Parallel Processing,Mpi,我最近在使用MPI_Iprobe时遇到了麻烦。我在下面附上了一些代码来尝试和演示这个问题(注意:我使用的代码是不同的,这些代码纯粹是为了创建我的问题的最小可复制示例) 我要做的是使秩为0的进程向秩为1的进程发送请求消息。秩0可以在循环中的任意点发送此消息(因此我使用if语句-if(I==1))。可能秩0从未发送此消息,这就是我在handleReplies()中使用Iprobe的原因。在循环中完成秩1后(这几乎是立即的,因为它在循环中没有功要做),我希望它在五秒钟后调用handleReplies(
if(I==1)
)。可能秩0从未发送此消息,这就是我在handleReplies()
中使用Iprobe的原因。在循环中完成秩1后(这几乎是立即的,因为它在循环中没有功要做),我希望它在五秒钟后调用handleReplies()
。这是为了确保在调用handleReplies()时进程0已经使用了send()
问题是,当调用handleReplies()
时,它应该使用MPI\u Iprobe将标志
变量设置为true(即:1),因为秩0进程发送了一条TAG\u REQ消息。但是,由于某些原因,该标志从未设置为1
,而是保持为0
。因此,我的排名0中的MPI_Recv仍然被阻止
int main(int argc, char *argv[]) {
int rank, size;
// Call MPI_init, MPI_Comm_rank, MPI_Comm_size...
int i = 0;
while(i <= 3) {
if(rank == 0) {
int fav;
int linked = 1; // the rank send/recv messages from
if(i == 1) { // at some point in the loop, send a request to the linked process
printf("Sending msg request to %d\n", linked);
MPI_Send(&rank, 0, MPI_INT, linked, TAG_REQ, MPI_COMM_WORLD);
printf("waiting for receieve\n");
MPI_Recv(&fav, 1, MPI_INT, linked, TAG_REP, MPI_COMM_WORLD, MPI_STATUS_IGNORE);
printf("%d's favourite number is %d\n", linked, fav);
}
}
i++;
}
sleep(5); // sleep 5 secs to ensure that the other node is waiting for a reply
handleReplies(MPI_COMM_WORLD, 1); // before we quit, handle any replies which may be waiting still
printf("[%d] Finished...\n", rank);
MPI_Finalize();
return 0;
};
void handleReplies(MPI_Comm comm, int debug) {
int linked = 0;
int flag = 0; // gets set to 1 if message received
MPI_Iprobe(linked, TAG_REQ, comm, &flag, MPI_STATUS_IGNORE);
printf("Is there a requesting message: %s\n", flag ? "yes" : "no");
if(flag) {
int recvVal;
int fav = 11;
MPI_Recv(&recvVal, 0, MPI_INT, linked, TAG_REQ, comm, MPI_STATUS_IGNORE);
MPI_Send(&fav, 1, MPI_INT, linked, TAG_REP, comm);
}
}
[1]完成后…
它继续挂起,作为MPI\u发送(&fav,1,MPI\u INT,linked,TAG\u REP,comm)代码>因为标志
从未设置为true
为什么MPI_Iprobe五秒钟前没有收到排名0的邮件
我也看过了,但问题似乎是他们使用的是MPI Isend而不是MPI Isend。否,链接问题中的问题与您正在处理的问题相同,+anMPI Isend
,没有等待。您必须在循环中调用MPI_Iprobe
,直到它将标志设置为true为止。@hristoilev感谢您的评论。我会再读一遍你对那个问题的回答。在循环内部使用MPI_Iprobe直到它将标志设置为true,是否与使用阻塞MPI_Probe方法相同?此外,秩0可能并不总是发送消息,在这种情况下,使用handleReplies()
loop()中的while循环进行循环不是吗,然而,如果是这样的话,我希望它只是简单地结束。MPI\u探测
正在阻塞-它将在出现消息之前不会返回MPI_Iprobe
不会阻塞,因此允许您在循环中运行它,在等待消息到达时执行其他操作。但您必须继续调用它,否则MPI操作将无法进行(除非存在异步进程线程,但您不能依赖它)。如果您不希望循环永远循环,只需发送一条带有特殊标记的消息,并在接收到循环后终止循环。顺便说一下,这里提供的代码是有缺陷的,因为秩0和秩1都将运行handleReplies()
,并且由于秩0从不向自身发送,因此它将保持在handleReplies()内
@hristoilev我明白了,谢谢你的建议。我已经实现了终止消息技术来退出似乎正在工作的循环。再次感谢你的帮助
Sending msg request to 1 // shows that message has been sent
waiting for receive // left hanging as no reply ever sent
Is there a requesting message: no // 5 seconds after above line (expected "yes" instead of "no")
[1] Finished...