c - MPI 减少到特定的接收缓冲区地址

标签 c parallel-processing mpi

我试图将两个数组(每个长度为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}

其他信息:

  • rBuf 在reduce 之前初始化为正确的大小,其中值中包含0
  • 所有进程都有偏移量数组
  • 当时使用 MPI_Reduce 的原因是,如果 rBuf 设置为 0,那么使用 MPI_SUM 进行归约将给出所需的答案

我已经在线查找了文档、一些教程/指南,当然,我仍然无法弄清楚我做错了什么。

为了得到答案,我专门寻找:

  1. 使用 MPI_Reduce 这在技术上可行吗?
  2. 我的 MPI_Reduce 调用正确吗? (指针运算错误?)
  3. 使用 MPI 的做法是否可行/正确,还是更好的方法?

谢谢

最佳答案

this answer 中详细描述了聚集(和分散) .

ReduceGather是相关但不同的操作。当您对这些 vector 调用 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 是根进程上的 rBuf,在本例中为 0 级。

另一方面,Gather 也收集所有数据,但它不是用求和、乘积、异或等运算来折叠数据,而是连接结果。

关于c - MPI 减少到特定的接收缓冲区地址,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15965508/

相关文章:

python - 如何在 python + linux 中监听端口并行

c - 使用 MPI IO 读取文件时出现错误值

c++ - 在 Windows 上使用 MPI 时在进程之间共享数据

c - 在 C 中,解析由多个空格分隔的整数组成的字符串

c - 断点在带有 QEMU 模拟 cortex-a8 的 gdb 中不起作用

c - Bash 扩展在 popen 中不起作用

c - MPI_Reduce 和 MPI_MIN 如何工作?

c - 如何从文本文件的每一行中查找数字

c# - 使用并行复制表会导致 MySQL 死锁

c++ - 包含后增量的表达式能否与 C++ 中该表达式的其他部分并行执行?