MPI_ERR_BUFFER:缓冲区指针无效

Tar*_*rek 5 c++ parallel-processing mpi

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

 MPI_ERR_BUFFER: invalid buffer pointer
Run Code Online (Sandbox Code Playgroud)

这是由MPI_Bsend()和MPI_Rcev()调用产生的?当并行进程的数量很少(<14)时,程序工作正常,但是当我增加进程数时,我得到了这个错误.

Hri*_*iev 8

扩展我之前的评论:

MPI中的缓冲可以在各种场合发生.消息可在内部由MPI库以隐藏网络延迟进行缓冲(通常只用于小消息进行长达一个实现相关的大小)或缓冲可以由用户通过使用任何缓冲的发送操作的强制执行MPI_Bsend()MPI_Ibsend().用户缓冲与内部缓冲不同:

  • 首先,发送MPI_Bsend()或发送的消息MPI_Ibsend()总是被缓冲,而内部缓冲的消息则不是这种情况.后者可以是缓冲的,也可以不缓存,具体取决于它们的大小和内部缓冲空间的可用性;
  • 第二,由于"始终缓冲"方面,如果用户连接缓冲区中没有可用的缓冲区空间,MPI_ERR_BUFFER则会发生错误.

发送的消息使用缓冲区空间,直到它们被destionation过程收到.由于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);
Run Code Online (Sandbox Code Playgroud)

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