【问题标题】:MPI_ERR_BUFFER: invalid buffer pointerMPI_ERR_BUFFER:无效的缓冲区指针
【发布时间】:2012-06-09 19:51:02
【问题描述】:

这个错误最常见的原因是什么

 MPI_ERR_BUFFER: invalid buffer pointer

哪个是 MPI_Bsend() 和 MPI_Rcev() 调用的结果? 当并行进程数很少(

【问题讨论】:

  • 缓冲区参数有问题。你在用MPI_Buffer_attach吗?我认为您必须发布一些代码才能获得更多帮助。
  • 缓冲区有最大大小吗?
  • 我认为MPI_Buffer_attach 没有大小限制(int 的大小除外)。 MPI_Buffer_attach page 说:“给定的大小应该是您打算拥有的所有未完成 Bsend 的大小之和,加上您执行的每个 Bsend 的 MPI_BSEND_OVERHEAD。为了计算大小,您应该使用 MPI_Pack_size。”你符合这些要求吗?
  • 随着更多进程要发送给您,最终会在发送之前缓冲更多数据,并且您的缓冲区太小。增加其大小或更好地使用非阻塞标准发送MPI_Isend()
  • @HristoIliev 我使用了 MPI_Isend() 并解决了问题。您可以将其发布为anwer,我会接受它。

标签: c++ parallel-processing mpi


【解决方案1】:

扩展我之前的评论:

MPI 中的缓冲可以在多种情况下发生。消息可以由 MPI 库在内部缓冲,以隐藏网络延迟(通常只对达到依赖于实现的大小的小消息进行),或者用户可以通过使用任何缓冲的发送操作MPI_Bsend() 来强制执行缓冲和MPI_Ibsend()。用户缓冲与内部缓冲不同:

  • 首先,MPI_Bsend()MPI_Ibsend() 发送的消息始终被缓冲,而内部缓冲消息则不是这种情况。后者可以缓冲或不缓冲,具体取决于它们的大小和内部缓冲空间的可用性;
  • 其次,由于“始终缓冲区”方面,如果用户附加缓冲区中没有可用的缓冲区空间,则会出现MPI_ERR_BUFFER 错误。

发送的消息使用缓冲区空间,直到它们被目标进程确定接收。由于 MPI 不提供任何内置机制来确认消息的接收,因此必须设计另一种方法来完成它,例如通过从目标进程向源进程发送回确认消息。

因此,必须考虑所有未明确确认为正在传输的消息,并且必须在缓冲区中分配足够的内存。通常这意味着缓冲区应该至少与您愿意传输的数据总量加上等于number_of_sends * MPI_BSEND_OVERHEAD 的消息信封开销一样大。这会给大型 MPI 作业带来很大的内存压力。必须牢记这一点,并在进程数量发生变化时相应地调整缓冲区空间。

请注意,提供缓冲发送只是为了方便。它可以很容易地实现为内存复制和非阻塞发送操作的组合,例如缓冲发送使您无需编写如下代码:

int data[];
int *shadow_data;
MPI_Request req;

...
<populate data>
...
shadow_data = (int *)malloc(sizeof(data));
memcpy(shadow_data, data, sizeof(data));
MPI_Isend(shadow_data, count, MPI_INT, destination, tag, MPI_COMM_WORLD, &req);
...
<reuse data as it is not used by MPI>
...
MPI_Wait(&req);
free(shadow_data);

如果内存不足,那么你应该只使用非阻塞发送。

【讨论】:

  • 谢谢赫斯托。现在将 MPI_Isend 与 MPI_Recv 和 MPI_Waitall 结合使用,程序会在处理更多进程时停止(不产生错误消息),同时增加缓冲区大小。不同进程发送的缓冲区大小有很大差异。对于较少数量的进程,它仍然可以正常工作。你有什么建议吗?
  • 这可能是您的 MPI 实现的一些特殊行为吗?您正在使用什么 MPI 库以及什么硬件(主要是什么互连?)。会不会是你的算法出了问题?如果您可以访问 DDT 或 TotalView 等并行调试器,这可能会有所帮助。
  • 问题出在其他地方。谢谢!
猜你喜欢
  • 2015-04-04
  • 2013-06-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-01-31
  • 1970-01-01
相关资源
最近更新 更多