在我的代码中,每个进程都作用于数组的特定部分。我希望每个进程将其处理的部分发送到其他进程,并从其他进程接收其他部分。为此我使用了MPI_Allgatherv
但我保持发送和接收缓冲区相同:
MPI_Allgatherv (&vel[0], localSizesFaceV[rank], MPI_DOUBLE, &vel[0], localSizesFaceV, displsFaceV, MPI_DOUBLE, MPI_COMM_WORLD);
我之前使用此函数用于具有不同发送和接收缓冲区的其他目的,并且它有效。所以我确信其他参数没有问题。
2个进程的情况下,其中一个进程不返回。当我将发送缓冲区复制到另一个时std::vector
vector <double> vel2;
vel2 = vel;
并使用vel2
作为发送缓冲区,然后所有进程都返回。为什么?
一般来说,MPI 要求参数没有别名。这是明确提到的本标准第2.3章 http://www.mpi-forum.org/docs/mpi-3.1/mpi31-report.pdf#section.2.3.
除非另有指定,否则为 OUT 或 INOUT 类型的参数
不能使用传递给 MPI 过程的任何其他参数作为别名。
这解释了为什么您的代码有问题。但是,可以非常轻松地解决您的问题,而无需显式复制缓冲区:MPI_IN_PLACE
关键词。它指定通信将在相关的地方使用输出缓冲区作为输入缓冲区“就地”完成。
你的代码将变成:
MPI_Allgatherv( MPI_IN_PLACE, 0, MPI_DATATYPE_NULL, &vel[0], localSizesFaceV, displsFaceV, MPI_DOUBLE, MPI_COMM_WORLD);
注意:发送缓冲区使用的实际类型是无关的。你可以保留MPI_DOUBLE
如果你愿意,但我更喜欢使用MPI_DATATYPE_NULL
明确该参数被忽略。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)