在上一篇中我们介绍了 mpi4py 中组与通信子的基本概念,下面我们将介绍 mpi4py 中的组管理 API。
组的构建和取消 API
MPI.Comm.Get_group(self)
返回与通信子 comm 相关的组。
MPI.Group.Dup(self)
复制当前组而产生一个新的组。
MPI.Group.Free(self)
释放组对象。
MPI.Group.Union(type cls, Group group1, Group group2)
返回 group1
和 group2
的并集,得到一个新的组 newgroup
,进程的 rank 序号为 group1
先,group2
后。
MPI.Group.Intersect(type cls, Group group1, Group group2)
MPI.Group.Intersection(type cls, Group group1, Group group2)
返回 group1
和 group2
的交集所形成的新的组 newgroup
,进程的 rank 顺序同 group1
。
MPI.Group.Difference(type cls, Group group1, Group group2)
返回一个新的组 newgroup
, 包含在 group1
中出现但不在 group2
中出现的进程。进程的 rank 顺序同 group1
。
MPI.Group.Incl(self, ranks)
由当前组中所列出的一组进程 ranks
而产生一个新的组 newgroup
,这些进程在 newgroup
中将重新编号。如果 ranks
是一个空的列表,则返回的 newgroup
是 MPI.GROUP_EMPTY。
MPI.Group.Excl(self, ranks)
由当前组中不包含在 ranks
中的一组进程产生一个新的组 newgroup
, 这些进程在 newgroup
中将重新编号。ranks
中的每一个元素都必须是当前组中的有效的 rank 号。 如果 ranks
是一个空的列表,则返回的 newgroup
与原组相同。
MPI.Group.Range_incl(self, ranks)
将当前组中的 n 个 range 三元组所组成的列表 ranks
所包含的进程形成一个 newgroup
,并返回这个 newgroup
。 其中每一个 range三元组为下列形式 (first, last, stride)。例如,如果 ranks = [(1, 9, 2), (15, 20, 3), (21, 30, 2)],则结果将包含如下进程 [1, 3, 5, 7, 9, 15, 18, 21, 23, 25, 27, 29]。
MPI.Group.Range_excl(self, ranks)
从当前组中除去n 个 range 三元组所组成的列表 ranks
所包含的进程后形成一个 newgroup
,并返回这个 newgroup
。
访问组的相关信息和属性
MPI.Group.Get_rank(self)
返回调用进程在给定组内的 rank,进程如果不在该组内则返回 MPI.UNDEFINED。注意:此信息也可以通过属性 rank
获取。
MPI.Group.Get_size(self)
返回指定组所包含的进程数。注意:此信息也可以通过属性 size
获取。
MPI.Group.Translate_ranks(type cls, Group group1, ranks1, Group group2=None)
返回进程组 group1
中的 n 个进程(由 ranks1
指定)在进程组 group2
中的编号。如果 group2
中不包含 group1
所指定的进程,则对应的返回值为 MPI.UNDEFINED。
MPI.Group.Compare(type cls, Group group1, Group group2)
如果 group1
和 group2
中所含进程以及相同进程的编号相同则返回 MPI.IDENT,如果二者所含进程完全相同但相同进程在二者中的编号不同则返回 MPI.SIMILAR,否则返回 MPI.UNEQUAL。
下面给出这些与组相关的 API 的使用例程。
# comm_group.py
import numpy as np
from mpi4py import MPI
comm = MPI.COMM_WORLD
rank = comm.Get_rank()
size = comm.Get_size()
# get the group associated with comm
grp = comm.Get_group()
print 'Group rank %d, group size: %d' % (grp.rank, grp.size)
# create a new group by duplicate `grp`
grp_new = grp.Dup()
print 'The duplicated new group:', grp_new
grp_new.Free()
print 'MPI.UNDEFINED:', MPI.UNDEFINED
# produce a group by include ranks 0, 1, 3 in `grp`
grp_incl = grp.Incl([0, 1, 3])
print 'rank %d in grp -> rank %d in grp_incl' % (rank, grp_incl.rank)
# produce a group by exclude ranks 1, 2 in `grp`
grp_excl = grp.Excl([1, 2])
print 'rank %d in grp -> rank %d in grp_excl' % (rank, grp_excl.rank)
grp_range_incl = grp.Range_incl([(0, 3, 2), (1, 2, 2)])
print 'rank %d in grp -> rank %d in grp_range_incl' % (rank, grp_range_incl.rank)
grp_range_excl = grp.Range_excl([(0, 3, 2), (1, 2, 2)])
print 'rank %d in grp -> rank %d in grp_range_excl' % (rank, grp_range_excl.rank)
# produce a group by combining `grp_incl` and `grp_excl`
grp_union = MPI.Group.Union(grp_incl, grp_excl)
print 'Size of grp_union: %d' % grp_union.size
# produce a group as the intersection of `grp_incl` and `grp_excl`
grp_intersect = MPI.Group.Intersect(grp_incl, grp_excl)
print 'Size of grp_intersect: %d' % grp_intersect.size
# grp_intersection = MPI.Group.Intersection(grp_incl, grp_excl)
# print 'Size of grp_intersection: %d' % grp_intersection.size
# produce a group from the difference of `grp_incl` and `grp_excl`
grp_diff = MPI.Group.Difference(grp_incl, grp_excl)
print 'Size of grp_diff: %d' % grp_diff.size
# translate the ranks of processes in `grp_incl` to those in `grp_excl`
print 'translate:', MPI.Group.Translate_ranks(grp_incl, [0, 1, 3], grp_excl)
print 'MPI.IDENT:', MPI.IDENT
print 'MPI.SIMILAR:', MPI.SIMILAR
print 'MPI.UNEQUAL:', MPI.UNEQUAL
# compare `grp_incl` and `grp_incl`
print MPI.Group.Compare(grp_incl, grp_incl)
# compare `grp_incl` and `grp_excl`
print MPI.Group.Compare(grp_incl, grp_excl)
运行结果如下:
$ mpiexec -n 4 python comm_group.py
Group rank 2, group size: 4
The duplicated new group:
MPI.UNDEFINED: -32766
rank 2 in grp -> rank -32766 in grp_incl
rank 2 in grp -> rank -32766 in grp_excl
rank 2 in grp -> rank 1 in grp_range_incl
rank 2 in grp -> rank -32766 in grp_range_excl
Size of grp_union: 3
Size of grp_intersect: 2
Size of grp_diff: 1
translate: array('i', [0, -32766, -32766])
MPI.IDENT: 0
MPI.SIMILAR: 2
MPI.UNEQUAL: 3
0
3
Group rank 3, group size: 4
The duplicated new group:
MPI.UNDEFINED: -32766
rank 3 in grp -> rank 2 in grp_incl
rank 3 in grp -> rank 1 in grp_excl
rank 3 in grp -> rank -32766 in grp_range_incl
rank 3 in grp -> rank 0 in grp_range_excl
Size of grp_union: 3
Size of grp_intersect: 2
Size of grp_diff: 1
translate: array('i', [0, -32766, -32766])
MPI.IDENT: 0
MPI.SIMILAR: 2
MPI.UNEQUAL: 3
0
3
Group rank 0, group size: 4
The duplicated new group:
MPI.UNDEFINED: -32766
rank 0 in grp -> rank 0 in grp_incl
rank 0 in grp -> rank 0 in grp_excl
rank 0 in grp -> rank 0 in grp_range_incl
rank 0 in grp -> rank -32766 in grp_range_excl
Size of grp_union: 3
Size of grp_intersect: 2
Size of grp_diff: 1
translate: array('i', [0, -32766, -32766])
MPI.IDENT: 0
MPI.SIMILAR: 2
MPI.UNEQUAL: 3
0
3
Group rank 1, group size: 4
The duplicated new group:
MPI.UNDEFINED: -32766
rank 1 in grp -> rank 1 in grp_incl
rank 1 in grp -> rank -32766 in grp_excl
rank 1 in grp -> rank 2 in grp_range_incl
rank 1 in grp -> rank -32766 in grp_range_excl
Size of grp_union: 3
Size of grp_intersect: 2
Size of grp_diff: 1
translate: array('i', [0, -32766, -32766])
MPI.IDENT: 0
MPI.SIMILAR: 2
MPI.UNEQUAL: 3
0
3
上面我们介绍了 mpi4py 中的组管理 API, 在下一篇中我们将介绍通信子管理 API。