我正在尝试将两个数组(每个长度为n)组合到根进程(rank = 0)上的接收缓冲区中,以形成长度为2 * n的数组,即包含所有值的单个数组。
为简洁起见,我的代码类似于以下内容:
#define ROOT 0
int myFunction(int* rBuf, int n) {
int* sBuf = malloc(n*sizeof(int));
// Do work, calculate offset, count etc.
MPI_Reduce(sBuf, rBuf+offset[rank], counts[rank],
MPI_INT, MPI_SUM, ROOT, MPI_COMM_WORLD);
}
// where offset[rank] is amount to offset where it is to be received
// offset[0] = 0, offset[1] = n
// counts contains the length of arrays on each process
然而,当我检查rBuf时,它被缩减为没有偏移的rBuf,例如:
// Rank 0: sBuf = {3, 2}
// Rank 1: sBuf = {5, 1}
// Should be rBuf = {3, 2, 5, 1}
rBuf = {8, 3, 0, 0}
其他信息:
我查了一些文档,一些教程/指南在线,当然这样,我仍然无法弄清楚我做错了什么。
作为答案,我特意寻找:
由于
答案 0 :(得分:2)
this answer中详细描述了聚集(和分散)。
Reduce和Gather相关但操作不同。当您在这些向量上调用MPI_Reduce
时
// Rank 0: sBuf = {3, 2}
// Rank 1: sBuf = {5, 1}
Reduce完全做对了;它花了各种sBuf
并添加它们(因为你告诉它对数据执行操作MPI_SUM
),给出{8,3} == {3,2} + {5,1}
,并将结果放在根处理器接收缓冲区中。 (如果您希望每个人都获得答案,请改用MPI_Allreduce()
。)但请注意您对Reduce的调用,
MPI_Reduce(sBuf, rBuf+offset[rank], counts[rank],
MPI_INT, MPI_SUM, ROOT, MPI_COMM_WORLD);
实际上并不有效;对于Reduce,每个人都需要使用相同的计数进行呼叫。并且唯一重要的rBuf
是根进程中的那个,在这种情况下是0级。
答案 1 :(得分:0)
所以我尝试了MPI_Gatherv,这似乎解决了这个问题,验证了更大数量和数量的数组。
这就是我的所作所为:
MPI_Gatherv(sBuf, counts[rank], MPI_INT, c, counts, offset, MPI_INT,
ROOT, MPI_COMM_WORLD);
我也尝试过MPI_Gather,但这不起作用(看起来真的以与我的reduce调用类似的方式传递偏移没有实际效果)。
由此,我对我的具体问题的理解如下:
如果有经验的MPI用户想要权衡,那就太棒了。
由于