mpi4py 中的進(jìn)程拓?fù)浞椒?/h2>

上一篇中我們簡(jiǎn)要介紹了進(jìn)程拓?fù)涞幕靖拍?,下面我們將介紹與進(jìn)程拓?fù)湎嚓P(guān)的一些方法。

創(chuàng)建方法

注意:只能在組內(nèi)通信子(Intracomm)或 Intracomm 類子類通信子上創(chuàng)建拓?fù)渫ㄐ抛印?chuàng)建拓?fù)渫ㄐ抛拥南嚓P(guān)方法(MPI.Intracomm 類的方法)接口如下:

Create_cart(self, dims, periods=None, bool reorder=False)

創(chuàng)建并返回一個(gè)新的通信子,在這個(gè)新通信子上附加與笛卡爾拓?fù)涔芾碛嘘P(guān)的數(shù)據(jù)結(jié)構(gòu)及相應(yīng)的操作信息。dims 是長(zhǎng)度為維數(shù) ndims 的整型數(shù)組,指出各維的進(jìn)程數(shù),periods 可取值 None,True,F(xiàn)alse 或長(zhǎng)度為 ndims 的布爾數(shù)組,指出各維是否周期性循環(huán),默認(rèn)值 None 表示各維都不循環(huán),True/False 表示各維都循環(huán)/都不循環(huán)。布爾型的 reorder 指出進(jìn)程在新創(chuàng)建的通信子組內(nèi)是否進(jìn)行重排序,默認(rèn)值為 False,此時(shí)進(jìn)程在新創(chuàng)建的通信子組內(nèi)的順序與在原通信子組內(nèi)的順序相同。在創(chuàng)建過(guò)程中,允許新通信子中包含的進(jìn)程數(shù)少于原通信子中的進(jìn)程數(shù),此時(shí)多余的進(jìn)程將返回 MPI.COMM_NULL,但不允許多于原通信子中的進(jìn)程數(shù)。

Create_graph(self, index, edges, bool reorder=False)

創(chuàng)建并返回一個(gè)新的通信子,在這個(gè)新通信子上附加與圖結(jié)構(gòu)的拓?fù)涔芾碛嘘P(guān)的數(shù)據(jù)結(jié)構(gòu)及相應(yīng)的操作信息。通過(guò) indexedges 兩個(gè)整數(shù)序列參數(shù)來(lái)描述整個(gè)圖的結(jié)構(gòu),假設(shè)生成的圖拓?fù)涞墓?jié)點(diǎn)個(gè)數(shù)為 nnodes,各節(jié)點(diǎn)按照從 0 到 nnodes - 1 編號(hào),其鄰居節(jié)點(diǎn)都順序、連續(xù)地放在 edges 序列中,通過(guò) index 序列分別指定各編號(hào)節(jié)點(diǎn)的鄰居節(jié)點(diǎn)列表在 edges 序列中的起始位置,index 的第 i 個(gè)元素保存圖中前 i 個(gè)節(jié)點(diǎn)的鄰居總數(shù),而各節(jié)點(diǎn)的鄰居順序地排成一個(gè)一維序列存放在 edges 中。因此,index[0] 為節(jié)點(diǎn) 0 的鄰居個(gè)數(shù),index[i] - index[i - 1] 為節(jié)點(diǎn) i > 0 的鄰居個(gè)數(shù),而節(jié)點(diǎn) 0 的鄰居保存在 edges[0:(index[0] - 1)] 范圍內(nèi),節(jié)點(diǎn) i > 0 的鄰居保存在 edges[index[i-1]:(index[i] - 1)] 范圍內(nèi)。布爾型的 reorder 指出進(jìn)程在新創(chuàng)建的通信子組內(nèi)是否進(jìn)行重排序,默認(rèn)值為 False,此時(shí)進(jìn)程在新創(chuàng)建的通信子組內(nèi)的順序與在原通信子組內(nèi)的順序相同。在創(chuàng)建過(guò)程中,允許新通信子中包含的進(jìn)程數(shù)少于原通信子中的進(jìn)程數(shù),此時(shí)多余的進(jìn)程將返回 MPI.COMM_NULL,但不允許多于原通信子中的進(jìn)程數(shù)。

下面舉個(gè)簡(jiǎn)單的例子來(lái)說(shuō)明如何設(shè)置以上參數(shù),比如創(chuàng)建一個(gè)含有 4 個(gè)節(jié)點(diǎn)的圖拓?fù)?,各個(gè)節(jié)點(diǎn)的鄰居節(jié)點(diǎn)如下表所示:

Node Neighbors
0 1, 3
1 0
2 3
3 0, 2

則相應(yīng)的參數(shù)可以如下設(shè)置:

Argument Input
nnodes 4
index 2, 3, 4, 6
edges 1, 3, 0, 3, 0, 2
Create_dist_graph_adjacent(self, sources, destinations, sourceweights=None, destweights=None, Info info=INFO_NULL, bool reorder=False)

創(chuàng)建一個(gè)分布式的圖拓?fù)渫ㄐ抛?。MPI-3 中引進(jìn)的新方法,暫不作介紹。

Create_dist_graph(self, sources, degrees, destinations, weights=None, Info info=INFO_NULL, bool reorder=False)

創(chuàng)建一個(gè)分布式的圖拓?fù)渫ㄐ抛?。MPI-3 中引進(jìn)的新方法,暫不作介紹。

笛卡爾拓?fù)渫ㄐ抛樱–artcomm)

方法

繼承自拓?fù)渫ㄐ抛樱═opocomm),其特有的一些方法有:

Get_topo(self)

獲取當(dāng)前拓?fù)渫ㄐ抛拥脑敿?xì)信息。也可以通過(guò)屬性 topo 獲取。

Get_cart_rank(self, coords)

返回根據(jù)笛卡爾拓?fù)涞淖鴺?biāo) coords 得到的進(jìn)程編號(hào)。

Get_coords(self, int rank)

返回根據(jù)進(jìn)程編號(hào) rank 得到的笛卡爾拓?fù)渥鴺?biāo)。

Get_dim(self)

返回笛卡爾拓?fù)涞木S數(shù)。也可以通過(guò)屬性 dimndim 獲取。

Shift(self, int direction, int disp)

給定一個(gè)笛卡爾坐標(biāo)平移的維度 direction 和步長(zhǎng) disp(大于 0 表示正方向,小于 0 表示負(fù)方向),返回平移的源進(jìn)程號(hào)和目的進(jìn)程號(hào)。對(duì)無(wú)周期的維,平移到末端后再平移將得到 MPI.PROC_NULL。

Sub(self, remain_dims)

將當(dāng)前的笛卡爾拓?fù)渫ㄐ抛咏M劃分成若干子組,每個(gè)子組對(duì)應(yīng)原笛卡爾拓?fù)渚W(wǎng)格的子網(wǎng)格,返回由這些子組創(chuàng)建成的子笛卡爾拓?fù)渫ㄐ抛?。由參?shù) remain_dims 決定如何進(jìn)行劃分:如果 remain_dims[i] 為 True 表示在新坐標(biāo)中保留第 i 維,否則去掉第 i 維。該方法與 MPI.Comm.Split 方法的功能類似。

例如,如果當(dāng)前笛卡爾拓?fù)涠x了一個(gè) 2 × 3 × 4 的網(wǎng)格,當(dāng) remain_dims = [True, False, True] 時(shí)會(huì)創(chuàng)建 3 個(gè)子笛卡爾拓?fù)渫ㄐ抛?,每一個(gè)包含 8 個(gè)進(jìn)程構(gòu)成一個(gè) 2 × 4 網(wǎng)格。當(dāng) remain_dims = [False, False, True] 時(shí)會(huì)創(chuàng)建 6 個(gè)子笛卡爾拓?fù)渫ㄐ抛?,每一個(gè)包含 4 個(gè)進(jìn)程構(gòu)成一個(gè)一維網(wǎng)格。

屬性

coords

笛卡爾拓?fù)渥鴺?biāo)。

dim

笛卡爾拓?fù)渚S數(shù)。

dims

笛卡爾拓?fù)涓骶S的進(jìn)程數(shù)。

ndim

笛卡爾拓?fù)渚S數(shù)。

periods

笛卡爾拓?fù)涓骶S的周期性。

topo

拓?fù)湫畔ⅰ?/p>

圖拓?fù)渫ㄐ抛樱℅raphcomm)

方法

繼承自拓?fù)渫ㄐ抛樱═opocomm),其特有的一些方法有:

Get_topo(self)

獲取當(dāng)前拓?fù)渫ㄐ抛拥脑敿?xì)信息。也可以通過(guò)屬性 topo 獲取。

Get_dims(self)

返回當(dāng)前圖拓?fù)涞墓?jié)點(diǎn)數(shù)和邊數(shù)。也可以通過(guò)屬性 dims 獲取。

Get_neighbors(self, int rank)

返回進(jìn)程 rank 的所有鄰居節(jié)點(diǎn)。

Get_neighbors_count(self, int rank)

返回進(jìn)程 rank 的鄰居節(jié)點(diǎn)的個(gè)數(shù)。

屬性

dims

圖的節(jié)點(diǎn)數(shù)和邊數(shù)。

edges

圖的邊。

index

圖的 index。

nedges

圖的邊數(shù)。

neighbors

所有鄰居節(jié)點(diǎn)。

nneighbors

鄰居節(jié)點(diǎn)的數(shù)目。

nnodes

節(jié)點(diǎn)數(shù)。

topo

拓?fù)湫畔ⅰ?/p>

分布式圖拓?fù)洌―istgraphcomm)

繼承自拓?fù)渫ㄐ抛樱═opocomm),其特有的一些方法有:

方法

Get_dist_neighbors(self)

獲取分布式圖拓?fù)涞泥従庸?jié)點(diǎn)。

Get_dist_neighbors_count(self)

獲取分布式圖拓?fù)涞泥従庸?jié)點(diǎn)數(shù)目。

例程

下面給出部分進(jìn)程拓?fù)洳僮飨嚓P(guān)方法的使用例程。

# topo.py

"""
Demonstrates the usage of Create_cart, Get_coords, Get_cart_rank, Shift, Sub.

Run this with 6 processes like:
$ mpiexec -n 6 python topo.py
"""

import numpy as np
from mpi4py import MPI


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

# create a 3 x 2 Cartesian topocomm
#      period = True  period = True
#       |   (4)     |   (5)     |
# ------+-----------+-----------+--------
# (-2)  |  0,0 (0)  |  0,1 (1)  |  (-2)     period = False
# ------+-----------+-----------+--------
# (-2)  |  1,0 (2)  |  1,1 (3)  |  (-2)     period = False
# ------+-----------+-----------+--------
# (-2)  |  2,0 (4)  |  2,1 (5)  |  (-2)     period = False
# ------+-----------+-----------+--------
#       |   (0)     |   (1)     |
dims = [3, 2]
periods = [True, False]
cart_comm = comm.Create_cart(dims, periods)
print 'rank %d has topo:' % rank, cart_comm.topo
print 'rank %d has coords:' % rank, cart_comm.coords
print 'rank %d has dims:' % rank, cart_comm.dims
print 'rank %d has periods:' % rank, cart_comm.periods

print 'rank 3 has coords:', cart_comm.Get_coords(3)
print 'coords [1, 1] is rank:', cart_comm.Get_cart_rank([1, 1])

# shift
sd = cart_comm.Shift(0, 1)
print 'shift 1 for row: rank %d has (source, dest) = (%d, %d)' % (rank, sd[0], sd[1])
sd = cart_comm.Shift(1, 1)
print 'shift 1 for column: rank %d has (source, dest) = (%d, %d)' % (rank, sd[0], sd[1])
print 'MPI.PROC_NULL =', MPI.PROC_NULL

# sub
remain_dims = [True, False]
sub_comm = cart_comm.Sub(remain_dims)
# sub_comm1  sub_comm2
# 0 <-> 0  |  1 <-> 0
# 2 <-> 1  |  3 <-> 1
# 4 <-> 2  |  5 <-> 2
print 'rank %d has topo (sub_comm):' % rank, sub_comm.topo

運(yùn)行結(jié)果如下:

$ mpiexec -n 6 python topo.py
rank 0 has topo: ([3, 2], [1, 0], [0, 0])
rank 0 has coords: [0, 0]
rank 0 has dims: [3, 2]
rank 0 has periods: [1, 0]
rank 3 has coords: array('i', [1, 1])
coords [1, 1] is rank: 3
shift 1 for row: rank 0 has (source, dest) = (4, 2)
shift 1 for column: rank 0 has (source, dest) = (-2, 1)
MPI.PROC_NULL = -2
rank 0 has topo (sub_comm): ([3], [1], [0])
rank 1 has topo: ([3, 2], [1, 0], [0, 1])
rank 1 has coords: [0, 1]
rank 1 has dims: [3, 2]
rank 1 has periods: [1, 0]
rank 3 has coords: array('i', [1, 1])
coords [1, 1] is rank: 3
shift 1 for row: rank 1 has (source, dest) = (5, 3)
shift 1 for column: rank 1 has (source, dest) = (0, -2)
MPI.PROC_NULL = -2
rank 1 has topo (sub_comm): ([3], [1], [0])
rank 2 has topo: ([3, 2], [1, 0], [1, 0])
rank 2 has coords: [1, 0]
rank 2 has dims: [3, 2]
rank 2 has periods: [1, 0]
rank 3 has coords: array('i', [1, 1])
coords [1, 1] is rank: 3
shift 1 for row: rank 2 has (source, dest) = (0, 4)
shift 1 for column: rank 2 has (source, dest) = (-2, 3)
MPI.PROC_NULL = -2
rank 2 has topo (sub_comm): ([3], [1], [1])
rank 3 has topo: ([3, 2], [1, 0], [1, 1])
rank 3 has coords: [1, 1]
rank 3 has dims: [3, 2]
rank 3 has periods: [1, 0]
rank 3 has coords: array('i', [1, 1])
coords [1, 1] is rank: 3
shift 1 for row: rank 3 has (source, dest) = (1, 5)
shift 1 for column: rank 3 has (source, dest) = (2, -2)
MPI.PROC_NULL = -2
rank 3 has topo (sub_comm): ([3], [1], [1])
rank 4 has topo: ([3, 2], [1, 0], [2, 0])
rank 4 has coords: [2, 0]
rank 4 has dims: [3, 2]
rank 4 has periods: [1, 0]
rank 3 has coords: array('i', [1, 1])
coords [1, 1] is rank: 3
shift 1 for row: rank 4 has (source, dest) = (2, 0)
shift 1 for column: rank 4 has (source, dest) = (-2, 5)
MPI.PROC_NULL = -2
rank 4 has topo (sub_comm): ([3], [1], [2])
rank 5 has topo: ([3, 2], [1, 0], [2, 1])
rank 5 has coords: [2, 1]
rank 5 has dims: [3, 2]
rank 5 has periods: [1, 0]
rank 3 has coords: array('i', [1, 1])
coords [1, 1] is rank: 3
shift 1 for row: rank 5 has (source, dest) = (3, 1)
shift 1 for column: rank 5 has (source, dest) = (4, -2)
MPI.PROC_NULL = -2
rank 5 has topo (sub_comm): ([3], [1], [2])

以上我們介紹了 mpi4py 中的進(jìn)程拓?fù)洳僮?,?a href="http://www.itdecent.cn/p/fcf31970f038" target="_blank">下一篇中我們將介紹動(dòng)態(tài)進(jìn)程管理。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容