在上一篇中我們介紹了 mpi4py 中的錯誤處理,下面我們將介紹 mpi4py 中的 info 和 assertion。
MPI 允許用戶提供兩種類型的與應用有關的信息:hints 和 assertions。hints 是應用中所做的有助于提高程序性能的選項,MPI 實現(xiàn)可以忽略用戶提供的 hints 而不影響程序的正確性;assertions 是用戶(編程者)給 MPI 實現(xiàn)的有關其應用程序行為的保證——如果程序給出的某個 assertion 并不正確,MPI 實現(xiàn)可能會產生錯誤的結果。在 MPI 中大多數(shù)的 hints 都是通過 MPI.Info 對象傳遞給 MPI 實現(xiàn)的,而 assertions 則是傳遞給一些 MPI 函數(shù)/方法的整數(shù)值。用戶可以不提供 hints 或 assertions,應用程序可以在不提供它們的情況下正確運行,但是,提供合適的 hints 或正確的 assertions 可以提高應用程序的性能。hints 和 assetions 都是可移植的。除了 MPI 標準提供的 hints 外,不同的 MPI 實現(xiàn)可能會定義額外的不同的 hints,用戶應該查看相關的文檔以了解可用的 hints 及其作用。
MPI-2 引進了 Info 對象,MPI 中的很多函數(shù)都使用了 info 參數(shù),Info 參數(shù)以 <key,value> 字符串二元組的形式定義信息。MPI 本身也使用一些預留的關鍵字來保存環(huán)境與外部交互,以及其他一些屬性信息。關鍵字和值分別由 MPI.MAX_INFO_KEY 和 MPI.MAX_INFO_VAL 定義上限。
hints 和 Info 對象
一般接口
MPI.Info.Create(type cls)
創(chuàng)建一個 Info 對象,將其 <key,value> 二元組初始化為空。
MPI.Info.Dup(self)
復制當前 Info 對象,包括其中的 <key,value> 二元組。
MPI.Info.Delete(self, key)
從當前 Info 對象中刪除 <key,value> 二元組,如果 key 參數(shù)指定的關鍵字不存在,則會拋出 MPI.Exception 異常。
MPI.Info.Free(self)
刪除并釋放當前 Info 對象,將其值設置為 MPI.INFO_NULL。
MPI.Info.Set(self, key, value)
為當前 Info 對象設置二元組 <key,value>,如果 key 所指定的關鍵字已經存在,則覆蓋其原有的值。如果 key 或 value 參數(shù)的字符串長度超過上限,則會拋出 MPI.Exception 異常。
MPI.Info.Get(self, key, int maxlen=-1)
從當前 Info 對象中獲取關鍵字 key 的值,如果該關鍵字不存在,則返回 None。maxlen 是獲取的值的最大長度,如果該長度小于值的實際長度,則返回的是被截斷的值,maxlen 如果為小于 0 或大于 MPI.MAX_INFO_VAL,則會使用 MPI.MAX_INFO_VAL。
MPI.Info.Get_nkeys(self)
返回當前 Info 對象中定義的關鍵字總數(shù)。
MPI.Info.Get_nthkey(self, int n)
返回當前 Info 對象中第 n 個關鍵字,關鍵字編號從 0 開始。
類似與字典的接口
MPI.Info.__len__(self)
使用 len 函數(shù)獲取當前 Info 對象中定義的關鍵字總數(shù)。
MPI.Info.__contains__(self, object key)
使用 in 來測試當前 Info 對象中是否包含 key 關鍵字。
MPI.Info.__iter__(self)
迭代器接口。
MPI.Info.__getitem__(self, object key)
使用 info[key] 獲取 key 對應的值。
MPI.Info.__setitem__(self, object key, object value)
使用 info[key] = value 的方式為當前 Info 對象設置 <key,value> 二元組。
MPI.Info.__delitem__(self, object key)
使用 del info[key] 的方式從當前 Info 對象中刪除 <key,value> 二元組。
MPI.Info.get(self, object key, object default=None)
獲取當前 Info 對象的 key 關鍵字對應的值,如果 key 不存在,則返回 default。
MPI.Info.keys(self)
返回當前 Info 對象的所有關鍵字,結果是一個 list。
MPI.Info.values(self)
返回當前 Info 對象的所有值,結果是一個 list。
MPI.Info.items(self)
返回當前 Info 對象的所有 <key,value> 二元組,結果是一個 list,其每一個元素為一個二元 tuple。
MPI.Info.update(self, other=(), **kwds)
以 other 和 kwds 中的 key 和 value 來更新當前 Info 對象的關鍵字和值,類似于 Python 字典的 update 操作。
MPI.Info.copy(self)
復制當前 Info 對象,包括其中的 <key,value> 二元組。同 MPI.Info.Dup。
MPI.Info.clear(self)
刪除當前 Info 對象中的所有 <key,value> 二元組。
MPI-3 新方法
因為 Info 對象可以潛在地幫助 MPI 實現(xiàn)提供更高的性能,MPI-3 中新增了若干與 Info 相關的方法,允許設置和獲取通信子,窗口以及文件句柄的 Info。另外,MPI-3 中增加一個新的通信子復制方法 MPI.Comm.Dup_with_info,該方法與 MPI.Comm.Dup 的作用類似,不過允許在復制通信子對象的時候為其設置一個新的 Info 對象,而不是將原通信子的 Info 對象也一并復制過來。該方法對 MPI 庫的開發(fā)非常有用,因為通信子復制方法通常被庫的開發(fā)者用來在庫內部創(chuàng)建一個私有的通信子,以防止庫內的通信操作對外部的通信產生干擾,庫在復制通信子的過程中可能并不需要將用戶設置在原通信子上的某些 info 鍵值對也一并復制過去,因此可以使用 MPI.Comm.Dup_with_info 在復制的過程中為其設置一個新的庫所需要的 Info 對象。下面是這些新方法的使用接口。注意:在 mpi4py 中,MPI.Comm.Dup 方法在傳遞一個有效的 info 參數(shù)時等價于 MPI.Comm.Dup_with_info。
通信子
MPI.Comm.Dup(self, Info info=None)
MPI.Comm.Dup_with_info(self, Info info)
MPI.Comm.Set_info(self, Info info)
MPI.Comm.Get_info(self)
窗口
MPI.Win.Set_info(self, Info info)
MPI.Win.Get_info(self)
文件
MPI.File.Set_info(self, Info info)
MPI.File.Get_info(self)
assertions
MPI 中,assertions 主要使用在單邊通信的相關操作中,比如下面的一些方法接口:
MPI.Win.Fence(self, int assertion=0)
MPI.Win.Lock(self, int rank, int lock_type=LOCK_EXCLUSIVE, int assertion=0)
MPI.Win.Lock_all(self, int assertion=0)
MPI.Win.Post(self, Group group, int assertion=0)
MPI.Win.Start(self, Group group, int assertion=0)
這些方法及其 assertion 參數(shù)的作用和可能取值在單邊通信和MPI-3 中增強的單邊通信中作過相應的介紹。
例程
下面給出使用例程。
# info.py
"""
Demonstrates the usage of info and assertion.
Run this with 1 processes like:
$ mpiexec -n 1 python info.py
or
$ python info.py
"""
import numpy as np
from mpi4py import MPI
comm = MPI.COMM_WORLD
# create an info object
info = MPI.Info.Create()
# dupicate the info
info1 = info.Dup()
# free the duplicated info
info1.Free()
# becomes MPI.INFO_NULL after the free op
assert info1 == MPI.INFO_NULL
try:
# try to delete a non-existed key from info
info.Delete('a')
except MPI.Exception as e:
print e.error_string
# set key and value
info.Set('k1', 'v1')
info.Set('k2', 'v2')
info.Set('k3', 'v3')
print 'k1:', info.Get('k1')
print 'nkeys:', info.Get_nkeys()
print 'the second key:', info.Get_nthkey(1)
try:
# try to set a key with length > MPI.MAX_INFO_KEY
info.Set('k' * (MPI.MAX_INFO_KEY + 1), 'v')
except MPI.Exception as e:
print e.error_string
try:
# try to set a value with length > MPI.MAX_INFO_VAL
info.Set('k', 'v' * (MPI.MAX_INFO_VAL + 1))
except MPI.Exception as e:
print e.error_string
# dict interface
print 'len(info):', len(info)
print 'k1 in info:', 'k1' in info
# __iter__ method
for k in info:
print k
info['k4'] = 'v4'
print 'k4:', info['k4']
del info['k4']
print 'k4:', info.get('k4', 'v4_new')
print 'keys:', info.keys()
print 'values:', info.values()
print 'items:', info.items()
info.update({'k1': 'v1_new', 'k5': 'k5_new'})
print 'items after update:', info.items()
info.clear()
print 'items after clea:', info.items()
# info with comm
comm_info = MPI.Info.Create()
comm.Set_info(comm_info)
comm.Get_info()
info_dup = MPI.Info.Create()
comm.Dup_with_info(info_dup)
運行結果如下:
$ python info.py
MPI_ERR_INFO_NOKEY: unknown key for given info object
k1: v1
nkeys: 3
the second key: k2
MPI_ERR_INFO_KEY: invalid key argument for info object
MPI_ERR_INFO_VALUE: invalid value argument for info object
len(info): 3
k1 in info: True
k1
k2
k3
k4: v4
k4: v4_new
keys: ['k1', 'k2', 'k3']
values: ['v1', 'v2', 'v3']
items: [('k1', 'v1'), ('k2', 'v2'), ('k3', 'v3')]
items after update: [('k1', 'v1_new'), ('k2', 'v2'), ('k3', 'v3'), ('k5', 'k5_new')]
items after clea: []
以上介紹了 mpi4py 中的 info 和 assertion,在下一篇中我們將介紹 mpi4py 中的 Status 對象。