MPI:当预期的MPI_Recv数量未知时该怎么办

我有很多从节点可能会也可能不会向主节点发送消息.所以目前主节点无法知道预期的MPI_Recv数量.出于效率原因,从节点必须向主节点发送最少数量的消息.

我设法找到a cool trick,当它不再期望任何消息时,它会发送一条额外的“完成”消息.不幸的是,它似乎不适用于我的情况,那里的发送者数量可变.关于如何解决这个问题的任何想法?谢谢!

if(rank == 0){ //MASTER NODE

    while (1) {

        MPI_Recv(&buffer, 10, MPI_INT, MPI_ANY_SOURCE, MPI_ANY_TAG, MPI_COMM_WORLD, &status);

        if (status.MPI_TAG == DONE) break;


        /* Do stuff */
    }

}else{ //MANY SLAVE NODES

    if(some conditions){
        MPI_Send(&buffer, 64, MPI_INT, root, 1, MPI_COMM_WORLD);
    }

}


MPI_Barrier(MPI_COMM_WORLD);
MPI_Send(NULL, 1, MPI_INT, root, DONE, MPI_COMM_WORLD);

不工作,该程序似乎仍在等待MPI_Recv

最佳答案 更简单,更优雅的选择是使用MPI_IBARRIER.让每个工作人员调用它所需的所有发送,然后在完成后调用MPI_IBARRIER.在主服务器上,您可以在MPI_ANY_SOURCE和MPI_IBARRIER上循环MPI_IRECV.完成MPI_IBARRIER后,您知道每个人都已完成,您可以取消MPI_IRECV并继续前进.伪代码看起来像这样:

if (master) {
  /* Start the barrier. Each process will join when it's done. */
  MPI_Ibarrier(MPI_COMM_WORLD, &requests[0]);

  do {
    /* Do the work */
    MPI_Irecv(..., MPI_ANY_SOURCE, &requests[1]);

    /* If the index that finished is 1, we received a message.
     * Otherwise, we finished the barrier and we're done. */
    MPI_Waitany(2, requests, &index, MPI_STATUSES_IGNORE);
  } while (index == 1);

  /* If we're done, we should cancel the receive request and move on. */
  MPI_Cancel(&requests[1]);
} else {
  /* Keep sending work back to the master until we're done. */
  while( ...work is to be done... ) {
    MPI_Send(...);
  }

  /* When we finish, join the Ibarrier. Note that
   * you can't use an MPI_Barrier here because it
   * has to match with the MPI_Ibarrier above. */
  MPI_Ibarrier(MPI_COMM_WORLD, &request);
  MPI_Wait(&request, MPI_STATUS_IGNORE);
}
点赞