删除以下print语句后MPI_Bsend中的MPI_ERR_BUFFER?

时间:2017-05-20 14:54:38

标签: c mpi

我有以下代码可以使用:

#include <mpi.h>
#include <stdio.h>

int main(int argc, char** argv) {

  int world_rank, world_size;
  MPI_Init(NULL, NULL);
  MPI_Comm_rank(MPI_COMM_WORLD, &world_rank);
  MPI_Comm_size(MPI_COMM_WORLD, &world_size);

  int n = 10000;
  int ni, i;

  double t[n];
  int x[n];

  int buf[n];
  int buf_size = n*sizeof(int);
  MPI_Buffer_attach(buf, buf_size);

  if (world_rank == 0) {
    for (ni = 0; ni < n; ++ni) {
      int msg_size = ni;
      int msg[msg_size];
      for (i = 0; i < msg_size; ++i) {
        msg[i] = rand();
      }

      double time0 = MPI_Wtime();
      MPI_Bsend(&msg, msg_size, MPI_INT, 1, 0, MPI_COMM_WORLD);
      t[ni] = MPI_Wtime() - time0;
      x[ni] = msg_size;
      MPI_Barrier(MPI_COMM_WORLD);
      printf("P0 sent msg with size %d\n", msg_size);
    }
  }

  else if (world_rank == 1) {
    for (ni = 0; ni < n; ++ni) {
      int msg_size = ni;
      int msg[msg_size];
      MPI_Request request;
      MPI_Barrier(MPI_COMM_WORLD);
      MPI_Irecv(&msg, msg_size, MPI_INT, 0, 0, MPI_COMM_WORLD, &request);
      MPI_Wait(&request, MPI_STATUS_IGNORE);
      printf("P1 received msg with size %d\n", msg_size);
    }
  }
  MPI_Buffer_detach(&buf, &buf_size);
  MPI_Finalize();
}

一旦我删除了打印语句,程序就会崩溃,告诉我有一个MPI_ERR_BUFFER: invalid buffer pointer。如果我只删除其中一个打印语句,则其他打印语句仍然执行,所以我认为它在程序结束时崩溃了。我不明白它崩溃的原因以及当我使用print语句时它没有崩溃的事实超出了我的逻辑......

有人知道这里发生了什么吗?

1 个答案:

答案 0 :(得分:0)

您根本没有为MPI提供足够的缓冲区空间。在缓冲模式下,所有正在进行的消息都存储在缓冲区空间中,缓冲区空间用作环形缓冲区。在您的代码中,无论printf如何,都可能有多条消息需要缓冲。请注意,即使2*n*sizeof(int)也没有足够的缓冲区空间 - 即使相应的接收完成,这些障碍也不能保证缓冲区在本地被释放。你必须提供(n*(n-1)/2)*sizeof(int)记忆以确保,或介于两者之间并希望。

底线:不要使用缓冲模式。

通常,使用标准阻止发送调用并编写应用程序,使其不会死锁。调整MPI实现,使得无论接收器如何都是小消息 - 以避免在后期接收器上等待。

如果您想重叠通信和计算,请使用非阻塞消息 - 为每次通信提供适当的内存。