如何安全地切换到MPI中的另一个通信器

时间:2017-06-26 11:34:36

标签: mpi mpi4py

我正在使用MPI编写应用程序(实际上是mpi4py)。应用程序可能会使用MPI_Comm_spawn()(统称在所有当前进程上)生成一些新进程,并且来自父组/通信器某些节点可能将数据发送到子组/通信器中的一些节点,反之亦然。 (注意MPI_Comm_spawn()和数据发送/接收正在不同的线程中发生功能[有其他功能与这个问题没有直接关系,因此我没有描述]和性能。)

因为可能会多次调用MPI_Comm_spawn()函数,并且我希望所有节点可以相互通信,所以我目前计划使用{{1将两个组(父和子)合并为一个内部通信器,然后通过新的内部通信器发送数据(下一个MPI_Intercomm_merge()将在新的内部通信器上发生。)

但是,由于生成和合并过程在程序运行期间发生,因此将会有一些数据通过旧的通信器发送(但可能尚未被dest接收)。我怎样才能安全地从旧的通信器切换到新的通信器(例如,能够在某些时候删除旧的通信器),同时失去最低的性能? MPI_Comm_spawn()是我知道保证所有进程可以相互发送数据的唯一方法(因为如果我们不合并,下次我们调用MPI_Comm_merge()时,某些进程无法直接发送数据彼此),我不介意只要它运作良好就把它改成另一种方法。

例如,在下图中,流程A,B,C是初始流程(MPI_Comm_merge()),D是生成流程:

Chart 1

A和B将连续数据发送给C;在发送期间,D产生;然后C将数据发送给D.假设旧的通信器A,B和C使用的是mpiexec -np 3,并且合并的内部通信器是comm1

我想要实现的是最初通过comm2发送数据,并且在生成D之后(所有进程)切换到comm1。缺少的是一种机制,可以知道何时C可以安全地从comm2切换到comm1以从A和/或B接收数据,然后我可以安全地呼叫comm2。 简单地在切换时通过MPI_Comm_free(comm1)发送特殊标签将是最后一个选项,因为C不知道有多少进程将数据发送给它。它确实知道有多少进程会向其发送数据,因此可以通过引入当地领导来实现(但我想了解其他选项)。
由于comm1AB正在处理parellel而C / sendrecv正在不同的主题中发生,我们不能当我们致电spawn时,保证没有待处理的数据。例如。如果我们想象MPI_Comm_spawn()A处理Bsend处理C的费率相同,那么当他们调用recv时,{{1}我只收到了来自comm_spawnC的一半数据,因此我们无法将A放在B,但必须等到comm1已收到C的所有待处理数据(这是一个未知数量的消息)。

MPI或mpi4py是否提供了任何机制(例如错误代码或例外)来实现此目的?

顺便说一句,如果我的做法显然不好或者我误解了C的做法,请指出。
(我的理解是comm1不是集体电话;在致电MPI_Comm_free()后,相同节点上不再允许向MPI_Comm_free()发送/接听电话它调用MPI_Comm_free(comm1)

1 个答案:

答案 0 :(得分:0)

基本上,C会调用MPI_Comm_spawn(..., MPI_COMM_SELF, ...)

为什么不让{A,B,C}调用MPI_Comm_spawn(..., comm1, ...)

MPI_Intercomm_merge()是一个集体操作,因此您需要以某种方式“同步”您的任务,那么为什么不在MPI_Comm_spawn()之前“同步”它们呢?

然后切换到新的通信器是微不足道的