在上一篇中我們介紹了 mpi4py 中的近鄰集合通信方法,下面我們將介紹 mpi4py 中的非阻塞通信子復(fù)制和組集合通信子創(chuàng)建方法。
非阻塞通信子復(fù)制方法 MPI.Comm.Idup 和組集合通信子創(chuàng)建方法 MPI.Comm.Create_group 都是 MPI-3 中新增的通信子創(chuàng)建方法匙睹。
在前面已經(jīng)介紹了 MPI-1 和 MPI-2 中的通信子創(chuàng)建方法听诸,其中 MPI.Comm.Dup 是一個(gè)阻塞的通信子復(fù)制方法,MPI.Comm.Create 是一個(gè)集合通信子創(chuàng)建方法讼载,即處于調(diào)用該方法的通信子內(nèi)的所有進(jìn)程必須共同參與才能完成一個(gè)新的通信子的創(chuàng)建工作,即使所創(chuàng)建的新通信子只包含原通信子里面的部分進(jìn)程中跌。MPI.Comm.Create 的集合操作性在某些情況下可能會(huì)遇到問(wèn)題咨堤,比如說(shuō)只要一個(gè)通信子內(nèi)的某一個(gè)或幾個(gè)進(jìn)程因出錯(cuò)誤而死掉后,所有這個(gè)通信子上的集合操作都無(wú)法進(jìn)行了漩符,因?yàn)榧喜僮饕笸ㄐ抛由系乃羞M(jìn)程共同參與一喘。我們可以考慮將該通信子中正常的進(jìn)程創(chuàng)建成一個(gè)新的通信子,并進(jìn)行后續(xù)的計(jì)算工作嗜暴。一種自然的想法是調(diào)用該通信子的 MPI.Comm.Create 方法凸克,但是因?yàn)槠浼喜僮餍月燎郑覀儫o(wú)法在該通信子的某些進(jìn)程死掉的情況下使用 MPI.Comm.Create 創(chuàng)建一個(gè)新的通信子,而且其它的集合通信子創(chuàng)建方法如 MPI.Comm.Dup触徐,MPI.Comm.Split 等也都無(wú)法使用咪鲜。MPI-1 和 MPI-2 中沒(méi)有提供非集合的通信子創(chuàng)建方法,此限制可能會(huì)導(dǎo)致直到程序退出該通信子上的所有集合操作都無(wú)法進(jìn)行撞鹉。
MPI-3 引進(jìn)的 MPI.Comm.Idup 是 MPI.Comm.Dup 的非阻塞版本疟丙,可以通過(guò)將通信子創(chuàng)建和其它計(jì)算重疊而提高程序的運(yùn)行效率。
MPI-3 引進(jìn)的 MPI.Comm.Create_group 是一個(gè)非集合操作鸟雏,改進(jìn)了 MPI.Comm.Create 的缺陷享郊,它可以在某個(gè)通信子上的部分進(jìn)程參與的情況下下創(chuàng)建一個(gè)新的通信子。
方法接口
下面給出這兩個(gè)新的通信子創(chuàng)建方法的使用接口孝鹊。
MPI.Comm.Idup(self)
非阻塞地復(fù)制當(dāng)前通信子炊琉,返回一個(gè)由新創(chuàng)建的通信子 comm_new
和一個(gè) MPI.Request 對(duì)象 req
組成的二元 tuple。注意:在沒(méi)有調(diào)用 req
的 Wait又活,Test 等方法以等待或測(cè)試該非阻塞調(diào)用完成之前苔咪,新通信子 comm_new
并未真正創(chuàng)建成功,不能進(jìn)行通信工作柳骄。
MPI.Comm.Create_group(self, Group group, int tag=0)
在已有通信子 comm 環(huán)境下团赏,利用 group
組創(chuàng)建新的通信子 newcomm
,但不會(huì)復(fù)制原通信子中添加的屬性信息耐薯。是一個(gè)非集合操作方法舔清,只要求處于 group
中的所有進(jìn)程執(zhí)行這個(gè)調(diào)用,對(duì)那些不在組 group
中的進(jìn)程曲初,返回的 newcomm
值為 MPI.COMM_NULL体谒。group
參數(shù)可以為 MPI.GROUP_NULL。注意:如果 group 不是 comm 所關(guān)聯(lián)組的子集或者不同進(jìn)程中變量 group 所包含的組內(nèi)容不同臼婆,則會(huì)發(fā)生錯(cuò)誤抒痒。tag
參數(shù)用來(lái)區(qū)分對(duì)該方法的多次調(diào)用。
例程
下面給出這兩個(gè)新方法的使用例程目锭。
# Idup.py
"""
Demonstrates the usage of Idup and Create_group.
Run this with 4 processes like:
$ mpiexec -n 4 python Idup.py
"""
import numpy as np
from mpi4py import MPI
comm = MPI.COMM_WORLD
rank = comm.Get_rank()
# Idup
comm_dup, req = comm.Idup()
req.Wait()
recv_obj = comm_dup.scatter([1, 2, 3, 4], root=0)
print 'rank %d has %d' % (rank, recv_obj)
# make one process die
if rank == 0:
# process 0 dies
exit()
# other processes can still work
# Create_group
# sub_comm = comm.Create(comm.group.Excl([0])) # dead lock for Create
sub_comm1 = comm.Create_group(comm.group.Excl([0])) # OK for Create_group
print 'sub_comm1.rank %d <-> comm.rank %d' % (sub_comm1.rank, rank)
sub_comm2 = comm.Create_group(comm.group.Excl([0, 1])) # OK for Create_group
if rank >=2:
print 'sub_comm2.rank %d <-> comm.rank %d' % (sub_comm2.rank, rank)
else:
print sub_comm2 == MPI.COMM_NULL
sub_comm3 = comm.Create_group(MPI.GROUP_NULL) # OK for Create_group
print sub_comm3 == MPI.COMM_NULL
運(yùn)行結(jié)果如下:
$ mpiexec -n 4 python Idup.py
rank 1 has 2
sub_comm1.rank 0 <-> comm.rank 1
True
True
rank 2 has 3
sub_comm1.rank 1 <-> comm.rank 2
sub_comm2.rank 0 <-> comm.rank 2
True
rank 3 has 4
sub_comm1.rank 2 <-> comm.rank 3
sub_comm2.rank 1 <-> comm.rank 3
True
rank 0 has 1
以上介紹了 MPI-3 中引進(jìn)的非阻塞通信子復(fù)制和組集合通信子創(chuàng)建方法评汰,在下一篇中我們將介紹 MPI-3 中增強(qiáng)的單邊通信方法纷捞。