此错误的最常见原因是什么
MPI_ERR_BUFFER: invalid buffer pointer
MPI_Bsend() 和 MPI_Rcev() 调用的结果是什么?当并行进程数很少(<14)时,该程序运行良好,但是当我增加进程数时,我得到了这个错误。
此错误的最常见原因是什么
MPI_ERR_BUFFER: invalid buffer pointer
MPI_Bsend() 和 MPI_Rcev() 调用的结果是什么?当并行进程数很少(<14)时,该程序运行良好,但是当我增加进程数时,我得到了这个错误。
扩展我之前的评论:
MPI 中的缓冲可以在各种情况下发生。消息可以由 MPI 库在内部缓冲,以隐藏网络延迟(通常只对达到与实现相关的大小的小消息进行),或者用户可以通过使用任何缓冲的发送操作MPI_Bsend()
和MPI_Ibsend()
. 用户缓冲与内部缓冲不同:
MPI_Bsend()
首先,由或 by发送的消息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);
如果内存不足,那么您应该只使用非阻塞发送。