【发布时间】:2015-01-08 08:24:27
【问题描述】:
我已经花了三天时间寻找答案,所以如果这个问题已经得到解决,我希望你能容忍我,而我很不幸地找到了解决方案。 我正在使用 Fortran(哎呀!),但这是一个通用的 MPI 查询。
场景(本示例已简化):
- 进程 0 和 1 与进程 2 通信(但彼此不通信)
- 0 和 1 进行大量发送/接收
- 2 执行大量接收/处理/发送(但每对都执行两次,以便 拿起 0 和 1)
- 0 & 1 最终会停止 - 我不知道什么时候! - 所以我在适当的时候使用第三个进程的等级(filter_rank_id = 2)和一个特殊标签(c_tag_open_rcv = 200)从每个执行一个MPI_Send,缓冲区中的逻辑为TRUE(end_of_run)。像这样:
CALL MPI_SEND(end_of_run, 1, MPI_LOGICAL, filter_rank_id, c_tag_open_rcv, mpi_coupling_comms, mpi_err)
问题出现在流程 2 中...它正忙于执行其 MPI_Recv/MPI_Send 对,我无法摆脱它。我已经为其他两个进程中的每一个都设置了一个非阻塞接收并存储了请求句柄:
DO model_rank_id= 0, 1
!Set up a non-blocking receive to get notification of end of model run for each model
end_run = end_model_runs(model_rank_id) !this is an array of booleans initialised to FALSE
CALL MPI_IRECV(end_run, 1, MPI_LOGICAL, model_rank_id, &
c_tag_open_rcv, coupling_comms, mpi_request_handle, mpi_err)
!store the handle in an array
request_handles(model_rank_id) = mpi_request_handle
END DO
其中 model_rank_id 是 MPI 通信器中的进程号,即 0 或 1。
后来,忙于处理所有这些接收/发送对,我总是检查缓冲区是否有任何东西到达:
DO model_rank_id= 0, 1
IF (end_model_runs(model_rank_id) .EQV. .FALSE.) THEN
CALL MPI_TEST(request_handles(model_rank_id), run_complete, mpi_status, mpi_err)
IF (run_complete .eqv. .FALSE.) THEN
!do stuff... receive/process/send
ELSE
!run is complete
!___________removed this as I realised it was incorrect__________
!get the stop flag for the specific process
CALL MPI_RECV(end_run, 1, MPI_LOGICAL, model_rank_id, &
c_tag_open_rcv, coupling_comms, mpi_err)
!____________end_________________________________________________
!store the stop flag so I can do a logical 'AND' on it and break out when
!both processes have sent their message
end_model_runs(model_rank_id) = end_run
END IF
END IF
END DO
请注意,这个 sn-p 包含在一个循环中,该循环一直持续到所有停止标志为 TRUE。
我知道这相当复杂,但这不会那么难吧?如果有人能看到错误,那就太好了,甚至可以提出更好的方法。
提前非常感谢。
【问题讨论】: