mpi4py 中的單邊通信相關(guān)操作

上一篇中我們簡要地介紹了 mpi4py 中的單邊通信概念,下面我們將介紹單邊通信的相關(guān)操作隙姿。

創(chuàng)建/釋放窗口對象

注意:在使用單邊通信操作之前,所有進程都須通過共同參與的創(chuàng)建窗口操作公開聲明自己可供訪問的內(nèi)存空間。

創(chuàng)建和釋放窗口對象的方法(MPI.Win 類方法)接口如下:

Create(type cls, memory, int disp_unit=1, Info info=INFO_NULL, Intracomm comm=COMM_SELF)

創(chuàng)建并返回用于單邊通信的窗口對象兄朋。在組內(nèi)通信子 comm 所指定的通信子范圍內(nèi)所有進程上執(zhí)行集合操作常拓,每個進程通過一塊內(nèi)存緩沖區(qū) memory 指定要創(chuàng)建的窗口渐溶,可以為 None(或 MPI.BOTTOM),此時不提供可供其它進程訪問的窗口弄抬。disp_unit 指定在遠端內(nèi)存訪問操作中的地址單位茎辐,即 origin 所指定的位置在 target 一側(cè)要以 target 進程所指定的 diap_unit 為單位計算。通常如果采用相同類型創(chuàng)建窗口掂恕,則統(tǒng)一將 disp_unit 設(shè)置成 1 即可拖陆。如果有的進程需要以組合數(shù)據(jù)類型(type)給出緩沖區(qū),則可能需要指定 disp_unit 為 sizeof(type)懊亡。info 對象用于為 MPI 環(huán)境提供優(yōu)化所需的輔助信息依啰,目前可用的 key 為 no_lock,如果該值設(shè)置為 True店枣,則指示 MPI 環(huán)境不對進程的本地窗口加鎖速警,也就是說此時表示應(yīng)用程序可以確信相應(yīng)窗口不會作為第三方參與通信叹誉,這樣就可減少相應(yīng)進程異步代理機制上的一些額外操作。參與創(chuàng)建窗口的進程可分別指定不同的 memory闷旧,disp_unitinfo 參數(shù)长豁,內(nèi)存中的同一塊區(qū)域也可同時存在于多個窗口中,只要應(yīng)用程序能確保并發(fā)訪問這塊區(qū)域所需的安全語義鸠匀。

Free(self)

釋放當(dāng)前窗口對象蕉斜。會在所有進程間實施 barrier 同步操作,直至所有進程都執(zhí)行完畢才返回缀棍。所有進程都必須在其遠端內(nèi)存訪問結(jié)束后才可調(diào)用此操作宅此。

通信操作

單邊通信的 3 種操作方法(MPI.Win 類方法)接口如下:

Put(self, origin, int target_rank, target=None)

該操作把當(dāng)前進程 origin 中的數(shù)據(jù)傳輸?shù)竭M程 target_ranktarget 位置。參數(shù) origin 應(yīng)該是一個長度為2或3的 list 或 tuple爬范,類似于 [data, MPI.DOUBLE]父腕,或者 [data, count, MPI.DOUBLE],以指明發(fā)送數(shù)據(jù)緩沖區(qū)青瀑,數(shù)據(jù)計數(shù)以及數(shù)據(jù)類型璧亮。當(dāng) count 省略時會利用 data 的字節(jié)長度和數(shù)據(jù)類型計算出對應(yīng)的 count。對 numpy 數(shù)組斥难,其計數(shù)和數(shù)據(jù)類型可以自動推斷出來枝嘶,因此可以直接以 data 作為第一個參數(shù)傳給 origintarget 可以是 None哑诊,一個整數(shù)或是一個長度為3的 list 或 tuple群扶,類似于 [target_disp, target_count, target_datatype],分別指定接收到的數(shù)據(jù)寫入 target_rank 進程相對于窗口內(nèi)存緩沖區(qū)的起始位置的偏移镀裤,數(shù)據(jù)量和數(shù)據(jù)類型竞阐,當(dāng)為 None 或一個整數(shù)時,會設(shè)置 target_disp 為 0 或該整數(shù)暑劝,而 target_counttarget_datatype 會設(shè)置成目標(biāo)窗口緩沖區(qū)的大小和數(shù)據(jù)類型骆莹。與點到點通信類似,target 進程緩沖區(qū)的大小也需要有足夠的空間以容納要傳輸?shù)臄?shù)據(jù)担猛。如果 target_datatype 是自定義數(shù)據(jù)類型幕垦,則必須僅包含相對偏移,而不能使用絕對地址毁习,這一限制對后面的 Get 和 Accumulate 方法同樣適用智嚷。

此操作的實際效果相當(dāng)于執(zhí)行一次點到點通信,在源進程執(zhí)行 Send(origin, dest=target_rank, tag=tag)纺且,在目標(biāo)進程執(zhí)行 Recv(buf, source=source, tag=tag),不同的是稍浆,Put 操作的源進程指定所有通信參數(shù)载碌,而不需要在目標(biāo)進程里啟動與之匹配的接收操作猜嘱。

Get(self, origin, int target_rank, target=None)

該操作從 target_rank 的窗口緩沖區(qū)讀取數(shù)據(jù),各參數(shù)的含義及限制與 Put 基本相同嫁艇,只是數(shù)據(jù)傳輸?shù)姆较蚋臑橛赡繕?biāo)流向源朗伶。

Accumulate(self, origin, int target_rank, target=None, Op op=SUM)

該操作將 origin 中的數(shù)據(jù)用 Reduce 中所定義的操作 op 更新 target_rank 的窗口緩沖區(qū)中由 target 所指定位置處的數(shù)據(jù)。各參數(shù)的含義及限制與 Put 基本相同, op 指定操作的規(guī)約算符步咪。該操作只能使用 Reduce 內(nèi)置定義的操作和 Accumulate 增加的一個操作——MPI.REPLACE论皆。Put 是 Accumulate 執(zhí)行 MPI.REPLACE 的特殊情形』可以使用預(yù)定義數(shù)據(jù)類型和用戶自定義數(shù)據(jù)類型点晴,但 target_datatype 不能指定重疊的區(qū)域,且目標(biāo)進程中緩沖區(qū)不能超過目標(biāo)進程所聲明窗口的范圍悯周。

以上介紹的 Put粒督,Get,Accumulate 均為非阻塞操作禽翼,僅當(dāng)操作發(fā)起者對相同的窗口對象調(diào)用同步函數(shù)(在下一篇中將會介紹)后才能確保實際數(shù)據(jù)傳輸完畢屠橄。從啟動遠端內(nèi)存訪問操作起,到通過同步函數(shù)確認操作完成之間闰挡,不能更新本地進程為實現(xiàn)該次通信所使用的數(shù)據(jù)緩沖區(qū)锐墙,即使是 Get 操作,在此期間也不能更新其所使用的本地通信緩沖區(qū)长酗。

例程

下面給出單邊通信操作相關(guān)方法的使用例程溪北。

# win.py

"""
Demonstrates the usage of Create, Free, Put, Get, Accumulate.

Run this with 4 processes like:
$ mpiexec -n 4 python win.py
"""

import numpy as np
from mpi4py import MPI


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

# Create and Put
if rank == 0:
    mem = np.array([1, 2], dtype='i')
    # create a window object with no accessable memory, used to communicate with other only
    win =  MPI.Win.Create(None, comm=comm)
    # synchronize
    win.Fence()
    # put data into a memory window of rank 1
    print 'rank 0 puts %s to rank 1' % mem
    win.Put(mem, target_rank=1)
    # synchronize
    win.Fence()
else:
    # initialize a memory of [0, 0]
    mem = np.array([0, 0], dtype='i')
    # use mem to create a window for receiving data
    win =  MPI.Win.Create(mem, comm=comm)
    # synchronize
    win.Fence()
    # synchronize
    win.Fence()
    print 'rank %d has %s after put' % (rank, mem)


# Get and Accumulate
if rank == 0:
    a = np.array(0.5, dtype='d')
    # initialize acc with 0.0
    acc = np.array(0.0, dtype='d')
    # create window objects
    win_a =  MPI.Win.Create(a, comm=comm)
    win_acc =  MPI.Win.Create(acc, comm=comm)
    # synchronize for win_a
    win_a.Fence()
    # synchronize for win_a
    win_a.Fence()
    # synchronize for win_acc
    win_acc.Fence()
    # synchronize for win_acc
    win_acc.Fence()
    # after accumulate, print the value of acc = 0.5 + 0.5 + 0.5
    print 'rank 0 has acc = %s' % acc
else:
    # initialize a with 0.0
    a = np.array(0.0, dtype='d')
    win_a =  MPI.Win.Create(None, comm=comm)
    win_acc =  MPI.Win.Create(None, comm=comm)
    # synchronize for win_a
    win_a.Fence()
    # get data from a memory window of rank 0
    win_a.Get(a, target_rank=0)
    # synchronize for win_a
    win_a.Fence()
    print 'rank %d has a = %s' % (rank, a)
    # synchronize for win_acc
    win_acc.Fence()
    # each rank except 0 accumulates a to the memory window of rank 0
    win_acc.Accumulate(a, target_rank=0, op=MPI.SUM)
    # synchronize for win_acc
    win_acc.Fence()

# free the window object
win.Free()
win_a.Free()
win_acc.Free()

運行結(jié)果如下:

$ mpiexec -n 4 python win.py 
rank 0 puts [1 2] to rank 1
rank 3 has [0 0] after put
rank 2 has [0 0] after put
rank 1 has [1 2] after put
rank 1 has a = 0.5
rank 3 has a = 0.5
rank 2 has a = 0.5
rank 0 has acc = 1.5

以上我們介紹了 mpi4py 中的單邊通信相關(guān)操作,在下一篇中我們將介紹單邊通信的同步操作花枫。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末刻盐,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子劳翰,更是在濱河造成了極大的恐慌敦锌,老刑警劉巖,帶你破解...
    沈念sama閱讀 217,657評論 6 505
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件佳簸,死亡現(xiàn)場離奇詭異乙墙,居然都是意外死亡,警方通過查閱死者的電腦和手機生均,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,889評論 3 394
  • 文/潘曉璐 我一進店門听想,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人马胧,你說我怎么就攤上這事汉买。” “怎么了佩脊?”我有些...
    開封第一講書人閱讀 164,057評論 0 354
  • 文/不壞的土叔 我叫張陵蛙粘,是天一觀的道長垫卤。 經(jīng)常有香客問我,道長出牧,這世上最難降的妖魔是什么穴肘? 我笑而不...
    開封第一講書人閱讀 58,509評論 1 293
  • 正文 為了忘掉前任,我火速辦了婚禮舔痕,結(jié)果婚禮上评抚,老公的妹妹穿的比我還像新娘。我一直安慰自己伯复,他們只是感情好慨代,可當(dāng)我...
    茶點故事閱讀 67,562評論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著边翼,像睡著了一般鱼响。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上组底,一...
    開封第一講書人閱讀 51,443評論 1 302
  • 那天丈积,我揣著相機與錄音,去河邊找鬼债鸡。 笑死江滨,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的厌均。 我是一名探鬼主播唬滑,決...
    沈念sama閱讀 40,251評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼棺弊!你這毒婦竟也來了晶密?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,129評論 0 276
  • 序言:老撾萬榮一對情侶失蹤模她,失蹤者是張志新(化名)和其女友劉穎稻艰,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體侈净,經(jīng)...
    沈念sama閱讀 45,561評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡尊勿,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,779評論 3 335
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了畜侦。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片元扔。...
    茶點故事閱讀 39,902評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖旋膳,靈堂內(nèi)的尸體忽然破棺而出澎语,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 35,621評論 5 345
  • 正文 年R本政府宣布咏连,位于F島的核電站盯孙,受9級特大地震影響鲁森,放射性物質(zhì)發(fā)生泄漏祟滴。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,220評論 3 328
  • 文/蒙蒙 一歌溉、第九天 我趴在偏房一處隱蔽的房頂上張望垄懂。 院中可真熱鬧,春花似錦痛垛、人聲如沸草慧。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,838評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽漫谷。三九已至,卻和暖如春蹂析,著一層夾襖步出監(jiān)牢的瞬間舔示,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,971評論 1 269
  • 我被黑心中介騙來泰國打工电抚, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留惕稻,地道東北人。 一個月前我還...
    沈念sama閱讀 48,025評論 2 370
  • 正文 我出身青樓蝙叛,卻偏偏與公主長得像俺祠,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子借帘,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,843評論 2 354

推薦閱讀更多精彩內(nèi)容