【问题标题】:Addressing Memory in MPI_Gather C在 MPI_Gather C 中寻址内存
【发布时间】:2017-02-01 17:17:52
【问题描述】:

我正在尝试将数据传递给MPI_Gather。我分配内存如下:

float *phie, *phitemp;
MPI_Comm_size(MPI_COMM_WORLD, &size);
MPI_Comm_rank(MPI_COMM_WORLD, &rank);

phitemp=(float *) malloc(20*sizeof(float));
if (rank==1) phie=(float *) malloc(itermax*20*size*sizeof(float));

然后让所有进程使用MPI_Gather() 将数据发送到排名 1,如下所示:

for (iter=0;iter<itermax;iter++) {    
   MPI_Gather((float *) phitemp, 20, MPI_FLOAT, (float *) (phie+iter*20*size*sizeof(float)), 20, MPI_FLOAT, 1, MPI_COMM_WORLD);
   iter=0;

}

我收到错误消息,提示我没有正确分配内存。

【问题讨论】:

  • 补充我的问题。我使用变量 iter 在 MPI_Gather() 中移动接收缓冲区的地址。 iter 在不同的处理器中可能有不同的值。 MPI_Gather 函数中使用了哪一个?用于接收数据的处理器?如果是这样,我如何确保不同的处理器都在等待它?
  • 请在您的问题中添加具体错误消息的准确措辞!
  • 如果您添加更多问题,请使用编辑功能并将添加的问题放在问题正文中。

标签: c malloc mpi pointer-arithmetic


【解决方案1】:

指针运算是根据指针指向的字的大小进行的。由于phiefloat *,因此phie+iter*20*size*sizeof(float) 中的sizeof(float) 是多余的,您将超出有效内存。

删除sizeof(float),或者更好地将其更改为更清晰的数组索引:&amp;(phie[iter * 20 * size])

您还应该删除所有指针强制转换,它们都是多余的并且可以隐藏问题。只有在知道自己需要时才应该施放。

关于您的附加问题:MPI_Gatherrecvbuf 参数仅在根进程中有意义。因此,只有根进程的iter 很重要。尽管如此,由于您的所有进程都通过相同的循环运行MPI_Gather,并且它们不能相互超越,因此在匹配聚集期间它们将始终具有相同的iter

【讨论】:

  • 谢谢。我已经解决了这个问题,但错误仍然存​​在。
  • 如果 MPI_Gather 不允许进程相互超越,如何在 MPI_Gather 命令之前插入输出行 printf("iter: %d, processor: %d before MPI_Gather.\n", iter , 排名);给这个输出?迭代器:0,处理器:MPI_Gather 之前的 0。迭代器:0,处理器:MPI_Gather 之前的 1。迭代器:0,处理器:MPI_Gather 之前的 2。迭代器:0,处理器:MPI_Gather 之前的 3。迭代器:1,处理器:MPI_Gather 之前的 0。迭代器:1,处理器:MPI_Gather 之前的 1。迭代器:2,处理器:MPI_Gather 之前的 1。迭代器:3,处理器:MPI_Gather 之前的 1。迭代器:4,处理器:MPI_Gathe 之前的 1 个
  • 请将固定的minimal reproducible example(仔细阅读该页面)编辑到您的问题中,以便进行进一步的调试尝试。
  • 操作不能互相超越,只表示它们会按顺序匹配。但是队列上的控制流不一定是同步的——MPI_Gather 并不意味着有障碍。此外,对于如何合并来自不同等级的标准输出也没有任何保证。
  • 这是一个我已经修复的小错误。感谢您之前的澄清:这是我面临的主要问题。
猜你喜欢
  • 2011-03-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-06-02
  • 2012-07-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多