Mpi4py mpi_test 总是 returns 错误

Mpi4py mpi_test always returns false

我在这里找不到类似的问题,所以这里是: 为什么下面的代码总是输出(False, None)?如果在进程 0 发送消息后 3 秒调用 test(),它不应该是 (True, None) 吗?另外,如果我在 test() 之前调用 req.wait() 我得到了我需要的输出,但是它不是不可阻塞的,所以 test() 失去了它的目的(我想能够告诉进程 1 在它休眠的那 3 秒内收到了来自任何来源的消息)

代码:

import time
from mpi4py import MPI

comm = MPI.COMM_WORLD
rank = comm.Get_rank()    

if rank == 0:
    req = comm.isend(0, 1, tag=0);
    req.wait();
elif rank == 1:
    req = comm.irecv();
    time.sleep(3);
    print req.test();

我不是 mpi4py 方面的专家,但假设它的行为类似于它的 MPI C 对应物(这似乎是一个合理的假设)那么确实,这里没有什么惊喜。

嗯,公平地说,MPI 标准并未规定您的代码输出。保证的是,在 次调用 MPI_Test() 函数后,它将 return true。这个数字可以是任何东西,因此它 return true 在第一次调用时,或者在第二次调用时,或者仅在十亿次调用之后......因此, usual/recommended 使用 MPI_Test() 函数是在这里和那里使用它,并以它的无限循环(基于其输出的退出条件)结束,或者使用 MPI_Wait() 调用。

现在,原因如下:MPI 库通常不执行显式 MPI 调用之外的任何操作。因此,为了看到非阻塞通信的进展,您必须执行 some MPI 调用。这些调用不需要与常设通信相关(通常任何 MPI 调用都会在内部触发消息队列的某种程度的进度)但您需要将手交给 MPI 库才能获得它。这就是对 MPI_Test() 的调用所做的。这也解释了为什么这不是真正与时间相关的:您对 sleep() 函数的调用确实为通信的发生提供了时间,但是由于 MPI 库没有在两者之间得到帮助,所以什么也没有真的发生了。

最后,对我的上述解释进行一些调整:

  1. 以上假定没有外部 机制来处理传输中的消息。然而,(远程)直接内存访问引擎,例如 InfiniBand 卡上可用的引擎,确实可以处理消息而无需进行额外的 MPI 调用。但是,这通常只会发生在节点间通信时,并且高度依赖于您的硬件和软件。
  2. 一些 MPI 库作为扩展提供了一种可能性,即专用于 CPU 线程以在 MPI 调用之外进行 MPI 通信。一些基于 MPICH 的 MPI 库,例如 Intel MPI,建议 MPICH_ASYNC_PROGRESS 环境变量,一旦设置为 1,将触发创建此 MPI 通信线程以进行非阻塞通信现场。不确定 OpenMPI 是否也提供此功能...

也许这只是因为您通过编辑一个更大的程序创建了这个示例,但我只是想检查一下它们是不是对非阻塞 MPI 通信存在一些潜在的误解...

我不明白你为什么有:

req = comm.isend(0, 1, tag=0);
req.wait();

因为这在功能上与阻塞调用相同

comm.send(0, 1, tag=0);

当然,非阻塞形式意味着您稍后可以在 isend 和 wait 之间插入更多代码,这也许正是您想要做的。