在上一篇中我們介紹了 mpi4py 中的 info 和 assertion轻纪,下面我們將介紹 mpi4py 中的 Status 對象轰驳。
在 MPI-1 中应役,Status 對象僅用于點到點通信,而 MPI-2 則在通用化請求以及并行 I/O 中使用 Status 對象显沈。因此新的 MPI.Status 對象在不同上下文環(huán)境下刁卜,可能存在有效域或無效域志电,特別是在通用化請求操作中,應(yīng)用程序需要在回調(diào)函數(shù)中設(shè)置某些狀態(tài)信息蛔趴。為管理泛化后的 MPI.Status 對象挑辆,MPI-2 新增加了下列函數(shù):MPI.Status.Set_elements 和 MPI.Status.Set_cancelled。
需要注意的是夺脾,Status 對象最好對應(yīng)每個操作單獨使用,而不推薦復(fù)用的方式茉继。此外咧叭,如果在通用化請求中需要傳遞額外信息,則不應(yīng)修改 Status 對象中各域的語義烁竭,而推薦借助 extra_status 參數(shù)傳遞信息菲茬。通用化請求將在下一篇中介紹。
下面給出 MPI.Status 對象的方法接口派撕。
MPI.Status.Get_source(self)
獲得并返回接收消息的源婉弹。也可以通過屬性 source 獲取。
MPI.Status.Set_source(self, int source)
設(shè)置接收消息的源终吼。也可以通過屬性 source 設(shè)置镀赌。
MPI.Status.Get_tag(self)
獲得并返回接收消息的 tag。也可以通過屬性 tag 獲取际跪。
MPI.Status.Set_tag(self, int tag)
設(shè)置接收消息的tag商佛。也可以通過屬性 tag 設(shè)置喉钢。
MPI.Status.Get_error(self)
獲得接收消息的錯誤。也可以通過屬性 error 獲取良姆。
MPI.Status.Set_error(self, int error)
設(shè)置接收消息的錯誤肠虽。也可以通過屬性 error 設(shè)置。
MPI.Status.Get_count(self, Datatype datatype=BYTE)
返回接收到的元素個數(shù)(以 datatype
為單位計算)玛追。如果 datatype
的 size 為 0税课,該方法也會返回 0;如果接收到的數(shù)據(jù)不是 datatype
的整數(shù)倍痊剖,則會返回 MPI.UNDEFINED韩玩。也可以通過屬性 count 獲取以 MPI.BYTE 為單位的計數(shù)。
MPI.Status.Get_elements(self, Datatype datatype)
返回 datatype
中的基本數(shù)據(jù)類型的個數(shù)邢笙。如果支持 MPI-3啸如,mpi4py 實際調(diào)用的是 MPI_Get_elements_x 以支持大的計數(shù)。
MPI.Status.Set_elements(self, Datatype datatype, Count count)
設(shè)置 datatype
中的基本數(shù)據(jù)類型的個數(shù)氮惯。如果支持 MPI-3叮雳,mpi4py 實際調(diào)用的是 MPI_Status_set_elements_x 以支持大的計數(shù)。
MPI.Status.Is_cancelled(self)
檢測某個通信請求是否被取消妇汗。也可用通過屬性 cancelled 來查詢帘不。
MPI.Status.Set_cancelled(self, bool flag)
將取消狀態(tài)設(shè)置為 flag
。注意:該方法只能用于通用化請求的回調(diào)函數(shù)中杨箭。
例程
下面給出使用例程寞焙。
# status.py
"""
Demonstrates the usage of MPI.Status.
Run this with 2 processes like:
$ mpiexec -n 2 python status.py
"""
import numpy as np
from mpi4py import MPI
comm = MPI.COMM_WORLD
rank = comm.rank
status = MPI.Status()
print 'status.source == MPI.ANY_SOURCE:', status.source == MPI.ANY_SOURCE
print 'status.tag == MPI.ANY_TAG:', status.tag == MPI.ANY_TAG
print 'status.error == MPI.SUCCESS:', status.error == MPI.SUCCESS
print 'MPI.UNDEFINED = %d' % MPI.UNDEFINED
comm.Barrier()
if rank == 0:
send_buf = np.arange(10, dtype='i')
# send 10 MPI.INTs, 40 MPI.BYTEs
comm.Send(send_buf, dest=1, tag=0)
# create a datatype and send it (multiple of sizeof(int))
send_type = MPI.Datatype.Create_struct([1, 16], [0, 4], [MPI.INT, MPI.CHAR])
send_type.Commit()
# send 1 MPI.INT, 16 MPI.CHARs (= 4 MPI.INTs), 1 + 16 basic elements
comm.Send([send_buf, 1, send_type], dest=1, tag=1)
send_type.Free()
# create a datatype and send it (not a multiple of sizeof(int))
send_type = MPI.Datatype.Create_struct([1, 17], [0, 4], [MPI.INT, MPI.CHAR])
send_type.Commit()
# send 1 MPI.INT, 17 MPI.CHARs (not a multiple of MPI.INT), 1 + 17 basic elements
comm.Send([send_buf, 1, send_type], dest=1, tag=2)
send_type.Free()
elif rank == 1:
recv_buf = np.full(10, -1, dtype='i')
# receive 10 ints
status = MPI.Status()
comm.Recv(recv_buf, source=0, tag=0, status=status)
print
print 'Get count with MPI.INT:', status.Get_count(MPI.INT)
print 'Get elements with MPI.INT:', status.Get_elements(MPI.INT)
print 'Get count with MPI.BYTE:', status.Get_count(MPI.BYTE)
print 'Get elements with MPI.BYTE:', status.Get_elements(MPI.BYTE)
print
# create a datatype and receive it
recv_type = MPI.Datatype.Create_struct([1, 36], [0, 4], [MPI.INT, MPI.CHAR])
recv_type.Commit()
status = MPI.Status()
comm.Recv([recv_buf, 1, recv_type], source=0, tag=1, status=status)
print 'Get count with MPI.INT:', status.Get_count(MPI.INT)
print 'Get elements with MPI.INT:', status.Get_elements(MPI.INT)
print 'Get count with recv_type:', status.Get_count(recv_type)
print 'Get elements with recv_type:', status.Get_elements(recv_type)
print
status = MPI.Status()
comm.Recv([recv_buf, 1, recv_type], source=0, tag=2, status=status)
print 'Get count with MPI.INT:', status.Get_count(MPI.INT)
print 'Get elements with MPI.INT:', status.Get_elements(MPI.INT)
print 'Get count with recv_type:', status.Get_count(recv_type)
print 'Get elements with recv_type:', status.Get_elements(recv_type)
recv_type.Free()
運行結(jié)果如下:
$ mpiexec -n 2 python status.py
status.source == MPI.ANY_SOURCE: True
status.tag == MPI.ANY_TAG: True
status.error == MPI.SUCCESS: True
MPI.UNDEFINED = -32766
status.source == MPI.ANY_SOURCE: True
status.tag == MPI.ANY_TAG: True
status.error == MPI.SUCCESS: True
MPI.UNDEFINED = -32766
Get count with MPI.INT: 10
Get elements with MPI.INT: 10
Get count with MPI.BYTE: 40
Get elements with MPI.BYTE: 40
Get count with MPI.INT: 5
Get elements with MPI.INT: 5
Get count with recv_type: -32766
Get elements with recv_type: 17
Get count with MPI.INT: -32766
Get elements with MPI.INT: -32766
Get count with recv_type: -32766
Get elements with recv_type: 18
以上介紹了 mpi4py 中的 Status 對象,在下一篇中我們將介紹 mpi4py 中的通用化請求互婿。