【发布时间】:2026-02-16 07:25:03
【问题描述】:
我有两个具有不同算法的函数。在第一个函数中,我实现了非阻塞通信(MPI_Irecv、MPI_Isend)并且程序运行没有任何错误。即使我将非阻塞更改为阻塞通信,一切都很好。没有僵局。 但是,如果我用这样的基本阻塞通信实现第二个功能(将算法简化为问题):
if( my_rank == 0)
{
a = 3 ;
MPI_Send(&a,1,MPI_DOUBLE,1,0,MPI_COMM_WORLD) ;
}
else if( my_rank == 1 )
{
MPI_Recv(&a,1,MPI_DOUBLE,0,0,MPI_COMM_WORLD, &status ) ;
}
所以,进程 1 应该从进程 0 接收值 a。但是我收到了这个错误:
MPI_Recv 中的致命错误:消息 截断,错误堆栈: MPI_Recv(187).......................: MPI_Recv(buf=0xbfbef2a8, count=1, MPI_DOUBLE,src=0,标签=0, MPI_COMM_WORLD,状态=0xbfbef294) 失败的 MPIDI_CH3U_Request_unpack_uebuf(600): 消息被截断;收到 32 个字节 但缓冲区大小为 8 排名 2 在作业 39 布拉布拉引起集体 中止所有等级的退出状态 等级2:被信号9杀死
如果我只使用这两个函数之一来运行程序,那么它们会按预期工作。但两者一起导致上面的错误消息。我确实理解错误消息,但我不知道我能做些什么来防止它。有人可以向我解释我必须在哪里寻找错误吗?由于我没有在第一个函数中遇到死锁,因此我假设第一个函数不会有未收到的发送,这会导致第二个函数出错。
【问题讨论】:
-
问题不在于 Recv 与 Irecv,当然也不是任何死锁。问题是来自任务 0 的 Rank 2 的 Recv(),它接收单个 MPI_DOUBLE,正在与来自大小为 32 字节的 rank 0 的 SEND 匹配(可能是 4 个双精度数?)。因此消息被截断错误。所以我们需要查看更多代码来了解发生了什么。
-
我知道。第二个功能仅包含发送/接收操作。它肯定位于第一个函数中,因为(取决于用户输入)这正是通信数组的大小。但那怎么可能呢?所有发送/接收操作必须完成,否则会导致死锁。还是我完全错了?整个代码大约有六百行。必须简化它...可能需要一段时间。