在我的代码中,每个进程都在数组的某个部分上工作.我希望每个进程将其处理的部分发送到其他进程,并从其他进程接收其他部分.为此,我使用MPI_Allgatherv
但我保持发送和接收缓冲区相同:
MPI_Allgatherv (&vel[0], localSizesFaceV[rank], MPI_DOUBLE, &vel[0], localSizesFaceV, displsFaceV, MPI_DOUBLE, MPI_COMM_WORLD);
之前我使用此函数用于其他目的,具有不同的发送和接收缓冲区并且它有效.这就是为什么我确信其他参数没有问题.
在2个进程的情况下,其中一个进程不返回.当我将发送缓冲区复制到另一个时std::vector
vectorvel2; vel2 = vel;
并用作vel2
发送缓冲区,然后返回所有进程.为什么?
一般来说,MPI要求参数不带别名.这明确提到了当前标准的第2.3章.
除非另有说明,否则OUT类型或INOUT类型的参数不能与传递给MPI过程的任何其他参数别名.
这解释了为什么您的代码有问题.但是,有可能非常轻松地解决您的问题,而无需显式复制缓冲区:MPI_IN_PLACE
关键字.它指定在相关的任何地方使用输出缓冲区作为输入缓冲区"就地"完成通信.
您的代码将变为:
MPI_Allgatherv( MPI_IN_PLACE, 0, MPI_TYPE_NULL, &vel[0], localSizesFaceV, displsFaceV, MPI_DOUBLE, MPI_COMM_WORLD);
注意:用于发送缓冲区的实际类型是无关紧要的.MPI_DOUBLE
如果您愿意,可以保留,但我倾向于使用MPI_TYPE_NULL
以明确该参数被忽略.