MPI中的发送和接收缓冲区相同
Same send and receive buffers in MPI
在我的代码中,每个进程都处理数组的特定部分。我希望每个进程将其处理的部分发送到其他进程,并从其他进程接收其他部分。为此,我使用了MPI_Allgatherv
,但我保持发送和接收缓冲区相同:
MPI_Allgatherv (&vel[0], localSizesFaceV[rank], MPI_DOUBLE, &vel[0], localSizesFaceV, displsFaceV, MPI_DOUBLE, MPI_COMM_WORLD);
我以前在不同的发送和接收缓冲区中将此函数用于其他目的,它起到了作用。这就是为什么我确信其他参数没有问题。
在两个进程的情况下,其中一个进程不会返回。当我将发送缓冲区复制到另一个std::vector
时
vector <double> vel2;
vel2 = vel;
并使用CCD_ 3作为发送缓冲区,然后所有进程返回。为什么?
一般来说,MPI要求参数没有别名。本标准第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
来明确参数被忽略。
来自规范http://www.mpich.org/static/docs/v3.1/www3/MPI_Allgatherv.html
int MPI_Allgatherv(const void *sendbuf, int sendcount, MPI_Datatype sendtype,
void *recvbuf, const int *recvcounts, const int *displs,
MPI_Datatype recvtype, MPI_Comm comm)
sendbuf
是常量,但您也可以通过recvbuf
传递一个允许更改sendbuf
底层内存的指针。这看起来有风险,但我对MPI的了解还不足以确定。
我还假设缓冲区内存上可能存在竞争条件,如果是这样,这就是未定义的行为。
相关文章:
- C++字符*缓冲区的大小
- 为什么msgrcv()将垃圾字符馈送到缓冲区
- 使用动态分配的数组会导致代码分析发出虚假的C6386缓冲区溢出警告
- ostream过载时的缓冲区冲洗
- C++中的高效循环缓冲区,它将被传递给C样式数组函数参数
- 用MacOS Mojave编译C++:致命错误:mpi.h:没有这样的文件或目录
- Xaudio2在更改缓冲区或循环时弹出声音
- 为什么我在leetcode上收到AddressSanitizer:地址0x602000000058上的堆缓冲区溢出错误
- 如何将图像传输到c++(dll)中的缓冲区,然后在c#的缓冲区中读/写
- 如何在cpp.中使用协议缓冲区存储大缓冲区/数组(char/int)
- MPI突然停止了对多个核心的操作
- 多线程双缓冲区
- Android P-9.0.0_r53 Logcat主缓冲区超出定义大小
- 套接字读取后,我在缓冲区中看到意外输入
- std::带有自定义缓冲区的 iostream 不允许我写入
- 从返回的顶点缓冲区查询顶点结构
- Vulkan 中的动态顶点缓冲区格式设置
- MPI:反复并行化缓冲区
- MPI 没有收到我发送的相同缓冲区,阻止发送/接收
- MPI中的发送和接收缓冲区相同