mpi4py 點到點通信之緩沖阻塞通信模式

上一篇中我們介紹了 mpi4py 中標(biāo)準(zhǔn)阻塞通信模式,下面我們將介紹緩沖阻塞通信模式紧憾。

緩沖通信模式主要用于解開阻塞通信的發(fā)送和接收之間的耦合。有了緩沖機(jī)制昆码,即使在接受端沒有啟動相應(yīng)的接收的情況下顷歌,在完成其消息數(shù)據(jù)到緩沖區(qū)的轉(zhuǎn)移后發(fā)送端的阻塞發(fā)送函數(shù)也可返回锰蓬。其實標(biāo)準(zhǔn)通信模式中也存在緩沖機(jī)制,它使用的是 MPI 環(huán)境所提供的數(shù)據(jù)緩沖區(qū)眯漩,是有一定大小的芹扭。使用緩沖通信模式,我們可以自己分配和組裝一塊內(nèi)存區(qū)域用作緩沖區(qū)坤塞,緩沖區(qū)的大小可以根據(jù)需要進(jìn)行控制冯勉。但需要注意的是,當(dāng)消息大小超過緩沖區(qū)容量時摹芙,程序會出錯灼狰。

下面是 mpi4py 中用于緩沖阻塞點到點通信的方法接口(MPI.Comm 類的方法):

bsend(self, obj, int dest, int tag=0)
recv(self, buf=None, int source=ANY_SOURCE, int tag=ANY_TAG, Status status=None)

Bsend(self, buf, int dest, int tag=0)
Recv(self, buf, int source=ANY_SOURCE, int tag=ANY_TAG, Status status=None)

這些方法調(diào)用中的參數(shù)是與標(biāo)準(zhǔn)通信模式的方法調(diào)用參數(shù)一樣的。

另外我們會用到的裝配和卸載用于通信的緩沖區(qū)的函數(shù)如下:

MPI.Attach_buffer(buf)
MPI.Detach_buffer()

下面分別給出 bsend/recv 和 Bsend/Recv 的使用例程浮禾。

# bsend_recv.py

from mpi4py import MPI


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

# MPI.BSEND_OVERHEAD gives the extra overhead in buffered mode
BUFSISE = 2000 + MPI.BSEND_OVERHEAD
buf = bytearray(BUFSISE)

# Attach a user-provided buffer for sending in buffered mode
MPI.Attach_buffer(buf)

send_obj = {'a': [1, 2.4, 'abc', -2.3+3.4J],
            'b': {2, 3, 4}}

if rank == 0:
    comm.bsend(send_obj, dest=1, tag=11)
    recv_obj = comm.recv(source=1, tag=22)
elif rank == 1:
    recv_obj = comm.recv(source=0, tag=11)
    comm.bsend(send_obj, dest=0, tag=22)

print 'process %d receives %s' % (rank, recv_obj)

# Remove an existing attached buffer
MPI.Detach_buffer()

運行結(jié)果如下:

$ mpiexec -n 2 python bsend_recv.py
process 0 receives {'a': [1, 2.4, 'abc', (-2.3+3.4j)], 'b': set([2, 3, 4])}
process 1 receives {'a': [1, 2.4, 'abc', (-2.3+3.4j)], 'b': set([2, 3, 4])}
# Bsend_recv.py

import numpy as np
from mpi4py import MPI


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

# MPI.BSEND_OVERHEAD gives the extra overhead in buffered mode
BUFSISE = 2000 + MPI.BSEND_OVERHEAD
buf = bytearray(BUFSISE)

# Attach a user-provided buffer for sending in buffered mode
MPI.Attach_buffer(buf)

count = 10
send_buf = np.arange(count, dtype='i')
recv_buf = np.empty(count, dtype='i')

if rank == 0:
    comm.Bsend(send_buf, dest=1, tag=11)
    comm.Recv(recv_buf, source=1, tag=22)
elif rank == 1:
    comm.Recv(recv_buf, source=0, tag=11)
    comm.Bsend(send_buf, dest=0, tag=22)

print 'process %d receives %s' % (rank, recv_buf)

# Remove an existing attached buffer
MPI.Detach_buffer()

運行結(jié)果如下:

$ mpiexec -n 2 python Bsend_recv.py
process 0 receives [0 1 2 3 4 5 6 7 8 9]
process 1 receives [0 1 2 3 4 5 6 7 8 9]

在以上兩個例程中交胚,因為發(fā)送的數(shù)據(jù)量很小,即使不裝配一個用于通信的緩沖區(qū)盈电,程序一樣可以工作(讀者可以試一試)蝴簇,這時將使用 MPI 環(huán)境提供的緩沖區(qū)。但是當(dāng)通信的數(shù)據(jù)量很大超過 MPI 環(huán)境提供的緩沖區(qū)容量時匆帚,就必須提供一個足夠大的緩沖區(qū)以使程序能夠正常工作熬词。

可以用下面這個例程測試一下 MPI 環(huán)境提供的緩沖區(qū)大小。

# attach_detach_buf.py

import numpy as np
from mpi4py import MPI


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

max_msg_size = 2**10
BUFSISE = 32 * max_msg_size
mpi_buf = bytearray(BUFSISE)

# Attach a big user-provided buffer for sending in buffered mode
MPI.Attach_buffer(mpi_buf)

recv_buf = np.empty((max_msg_size,), np.float64)

if rank == 0:
    print '-' * 80
    print 'With an attached big buffer:'
    print

msg_size = 1
tag = 0
while msg_size <= max_msg_size:
    msg = np.random.random((msg_size,))
    if rank == 0:
        print 'Trying with size: ', msg_size

    comm.Bsend(msg, (rank+1)%2, tag)
    comm.Recv(recv_buf, (rank+1)%2, tag)

    if rank == 0:
        print 'Completed with size: ', msg_size

    msg_size *= 2
    tag += 1

# Remove an existing attached buffer
MPI.Detach_buffer()

if rank == 0:
    print
    print '-' * 80
    print 'Without an attached big buffer:'
    print

msg_size = 1
tag = 0
while msg_size <= max_msg_size:
    msg = np.random.random((msg_size,))
    if rank == 0:
        print 'Trying with size: ', msg_size

    comm.Bsend(msg, (rank+1)%2, tag)
    comm.Recv(recv_buf, (rank+1)%2, tag)

    if rank == 0:
        print 'Completed with size: ', msg_size

    msg_size *= 2
    tag += 1

運行結(jié)果如下:

$ mpiexec -n 2 python attach_detach_buf.py
--------------------------------------------------------------------------------
With an attached big buffer:

Trying with size:  1
Completed with size:  1
Trying with size:  2
Completed with size:  2
Trying with size:  4
Completed with size:  4
Trying with size:  8
Completed with size:  8
Trying with size:  16
Completed with size:  16
Trying with size:  32
Completed with size:  32
Trying with size:  64
Completed with size:  64
Trying with size:  128
Completed with size:  128
Trying with size:  256
Completed with size:  256
Trying with size:  512
Completed with size:  512
Trying with size:  1024
Completed with size:  1024

--------------------------------------------------------------------------------
Without an attached big buffer:

Trying with size:  1
Completed with size:  1
Trying with size:  2
Completed with size:  2
Trying with size:  4
Completed with size:  4
Trying with size:  8
Traceback (most recent call last):
Completed with size:  8
Trying with size:  16
Completed with size:  16
Trying with size:  32
Completed with size:  32
Trying with size:  64
Completed with size:  64
Trying with size:  128
Completed with size:  128
Trying with size:  256
Completed with size:  256
Trying with size:  512
Traceback (most recent call last):
File "attach_detach_buf.py", line 56, in <module>
File "attach_detach_buf.py", line 56, in <module>
        comm.Bsend(msg, (rank+1)%2, tag)
File "Comm.pyx", line 286, in mpi4py.MPI.Comm.Bsend (src/mpi4py.MPI.c:64922)
comm.Bsend(msg, (rank+1)%2, tag)
mpi4py.MPI.Exception: MPI_ERR_BUFFER: invalid buffer pointer
File "Comm.pyx", line 286, in mpi4py.MPI.Comm.Bsend (src/mpi4py.MPI.c:64922)
mpi4py.MPI.Exception: MPI_ERR_BUFFER: invalid buffer pointer
-------------------------------------------------------
Primary job  terminated normally, but 1 process returned
a non-zero exit code.. Per user-direction, the job has been aborted.
-------------------------------------------------------
--------------------------------------------------------------------------
mpiexec detected that one or more processes exited with non-zero status, thus causing
the job to be terminated. The first process to do so was:

Process name: [[45613,1],0]
Exit code:    1
--------------------------------------------------------------------------

可以看出吸重,當(dāng)我們提供一個大的緩沖區(qū)時就能夠成功地收發(fā)大的消息互拾,但是當(dāng)我們卸載掉這個緩沖區(qū)后,再發(fā)送大的消息時就出錯了嚎幸。

上面我們介紹 mpi4py 中緩沖阻塞通信模式颜矿,在下一篇中我們將介紹就緒阻塞通信模式。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末嫉晶,一起剝皮案震驚了整個濱河市骑疆,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌替废,老刑警劉巖箍铭,帶你破解...
    沈念sama閱讀 222,729評論 6 517
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異椎镣,居然都是意外死亡坡疼,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 95,226評論 3 399
  • 文/潘曉璐 我一進(jìn)店門衣陶,熙熙樓的掌柜王于貴愁眉苦臉地迎上來柄瑰,“玉大人,你說我怎么就攤上這事剪况〗陶矗” “怎么了?”我有些...
    開封第一講書人閱讀 169,461評論 0 362
  • 文/不壞的土叔 我叫張陵译断,是天一觀的道長授翻。 經(jīng)常有香客問我,道長孙咪,這世上最難降的妖魔是什么堪唐? 我笑而不...
    開封第一講書人閱讀 60,135評論 1 300
  • 正文 為了忘掉前任,我火速辦了婚禮翎蹈,結(jié)果婚禮上淮菠,老公的妹妹穿的比我還像新娘。我一直安慰自己荤堪,他們只是感情好合陵,可當(dāng)我...
    茶點故事閱讀 69,130評論 6 398
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著澄阳,像睡著了一般拥知。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上碎赢,一...
    開封第一講書人閱讀 52,736評論 1 312
  • 那天低剔,我揣著相機(jī)與錄音,去河邊找鬼肮塞。 笑死襟齿,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的峦嗤。 我是一名探鬼主播蕊唐,決...
    沈念sama閱讀 41,179評論 3 422
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼烁设!你這毒婦竟也來了替梨?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 40,124評論 0 277
  • 序言:老撾萬榮一對情侶失蹤装黑,失蹤者是張志新(化名)和其女友劉穎副瀑,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體恋谭,經(jīng)...
    沈念sama閱讀 46,657評論 1 320
  • 正文 獨居荒郊野嶺守林人離奇死亡糠睡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,723評論 3 342
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了疚颊。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片狈孔。...
    茶點故事閱讀 40,872評論 1 353
  • 序言:一個原本活蹦亂跳的男人離奇死亡信认,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出均抽,到底是詐尸還是另有隱情嫁赏,我是刑警寧澤,帶...
    沈念sama閱讀 36,533評論 5 351
  • 正文 年R本政府宣布油挥,位于F島的核電站潦蝇,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏深寥。R本人自食惡果不足惜攘乒,卻給世界環(huán)境...
    茶點故事閱讀 42,213評論 3 336
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望惋鹅。 院中可真熱鬧则酝,春花似錦、人聲如沸负饲。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,700評論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽返十。三九已至妥泉,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間洞坑,已是汗流浹背盲链。 一陣腳步聲響...
    開封第一講書人閱讀 33,819評論 1 274
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點兒被人妖公主榨干…… 1. 我叫王不留迟杂,地道東北人刽沾。 一個月前我還...
    沈念sama閱讀 49,304評論 3 379
  • 正文 我出身青樓,卻偏偏與公主長得像排拷,于是被迫代替她去往敵國和親侧漓。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 45,876評論 2 361

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

  • Android 自定義View的各種姿勢1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 172,332評論 25 707
  • 轉(zhuǎn)自: http://www.reibang.com/p/486b0965c296 http://www.jia...
    demop閱讀 3,899評論 1 21
  • “噼里啪啦……噼里啪啦……”聲聲鞭炮湊響了新年的樂章。 新年第一天浪腐,你在干啥纵揍?拜年、送祝福议街、發(fā)紅包泽谨、曬幸福、展望未...
    牧羊人的天空閱讀 489評論 0 6
  • 我 的夢想一名畫家,可以畫畫吧雹,也可以學(xué)到很多知識骨杂,可以畫出很大的畫面,來展示雄卷,
    慧妮子閱讀 215評論 0 0
  • 第一次聽我的同事跟我說腊脱,他和夫人在大學(xué)時候就說好不要小孩,然后我當(dāng)時覺得很瘋狂龙亲。后來身邊開始出現(xiàn)了決定不結(jié)婚的好朋...
    WEI_曹蕾閱讀 299評論 0 1