这是this previous question of mine的后续行动,其结论是程序错误,因此预期行为未定义。
我在这里尝试创建的是一个简单的错误处理机制,为此我使用Irecv请求将空消息作为“中止句柄”,将其附加到我的普通{ {1}}调用(并将其转换为MPI_Wait
),以便允许我在进程0发生错误的情况下取消阻止进程1,并且它无法再到达应该发布匹配的点{ {1}}。
由于内部消息缓冲,MPI_WaitAny
可能会立即成功,而其他进程无法发布匹配的MPI_Recv
。因此,再也无法取消它了。
我希望一旦所有进程调用MPI_Isend
,我就可以一劳永逸地忘记这条消息,但事实证明,情况并非如此。相反,它将被传递到以下通信器中的MPI_Recv
。
所以我的问题是:
MPI_Comm_free
来电转为MPI_Recv
,该程序会按预期运行 - 至少在这种情况下,我是否可以放心,该程序是否正确?再次,非常感谢任何反馈!
MPI_Isend
输出:
MPI_Issend
答案 0 :(得分:2)
如@kraffenetti的上述评论之一所述,这是一个错误的程序,因为发送的消息未被接收匹配。即使消息被取消,它们仍然需要在远程端具有匹配的接收,因为由于在取消之前它们已经被发送,所以取消对于已发送的消息可能不成功是可能的。完成(这是这里的情况)。
这个问题在MPICH的故障单上开了一个帖子,你可以找到here有更多细节。
答案 1 :(得分:0)
我尝试使用open mpi构建你的代码,但它没有用。 mpicc抱怨status.cancelled
error: ‘MPI_Status’ has no member named ‘cancelled’
我想这是intel mpi的一个特色。切换到以下内容会发生什么:
...
int flag;
MPI_Test_cancelled(&status, &flag);
if (flag) {
...
这使用open mpi给出了预期的输出(并且它使您的代码更少依赖)。是使用intel mpi的情况吗?
我们需要一位专家告诉我们英特尔的status.cancelled
是什么,因为我对此一无所知!
编辑:我多次测试我的答案,我发现输出是随机的,有时是正确的,有时不是。对不起...好像status
中的某些内容未设置。部分答案可能在MPI_Wait()
,http://www.mpich.org/static/docs/v3.1/www3/MPI_Wait.html,
"仅当MPI例程的返回值为MPI_ERR_IN_STATUS时,才会设置状态返回的MPI_ERROR字段。该错误类仅由采用状态参数数组的例程返回(MPI_Testall,MPI_Testsome,MPI_Waitall和MPI_Waitsome)。在所有其他情况下,状态中MPI_ERROR字段的值不变。有关确切文本,请参阅MPI-1.1规范中的第3.2.5节。 "如果MPI_Test_cancelled()使用MPI_ERROR,事情可能会变坏。
所以这就是诀窍:使用MPI_Waitall(1,&req, &status)
!输出最后是正确的!