首页 > 解决方案 > MPI I_Send/MPI_Irecv 问题

问题描述

我正在编写一个 MPI 程序,它的第一个实例作为主机工作,从其工作人员发送和接收结果。

接收函数做这样的事情:

struct result *check_for_message(void) {
...
  static unsigned int message_size;
  static char *buffer;
  static bool started_reception = false;
  static MPI_Request req;

  if (!started_reception) {
    MPI_Irecv(&message_size, 1, MPI_INT, MPI_ANY_SOURCE, SIZE_TAG,
              MPI_COMM_WORLD, &req);
    started_reception = true;
  } else {
    int flag = 0;
    MPI_Status status;

    MPI_Test(&req, &flag, &status);
    if (flag == 1) {
      started_reception = false;
      buffer = calloc(message_size + 1, sizeof(char));
      DIE_IF_NULL(buffer); // printf + MPI_Finalize + exit
      MPI_Request content_req;

      MPI_Irecv(buffer, MAX_MSG_SIZE, MPI_CHAR, status.MPI_SOURCE, CONTENT_TAG,
                MPI_COMM_WORLD, &content_req);
      MPI_Wait(&content_req, MPI_STATUS_IGNORE);

      ret = process_request(buffer);
      free(buffer);
    }
  }

...
}

发送函数做这样的事情:

  MPI_Request size_req;
  MPI_Request content_req;

  MPI_Isend(&size, 1, MPI_INT, dest, SIZE_TAG, MPI_COMM_WORLD, &size_req);
  MPI_Wait(&size_req, MPI_STATUS_IGNORE);
  MPI_Isend(buf, size, MPI_CHAR, dest, CONTENT_TAG, MPI_COMM_WORLD,
            &content_req);
  MPI_Wait(&content_req, MPI_STATUS_IGNORE);

我注意到,如果我在发送函数中删除 MPI_Wait,通常会发生执行块或某种信号停止实例的执行(我可以检查输出,但我认为这是关于免费错误 SIGSEGV 的问题)。

当我添加 MPI_Wait 时,它似乎总是完美运行。这可能与两个发送执行的顺序有关吗?他们不应该是有序的吗?

我使用 -n 16 在本地运行程序,但也使用 -n 128 进行了测试。我发送的消息超过 50 个字符(90% 的时间),有些甚至超过 300 个字符。

标签: cmpi

解决方案


推荐阅读