mpi4py|mpi4py 中的 info 和 assertion

在上一篇中我们介绍了 mpi4py 中的错误处理,下面我们将介绍 mpi4py 中的 info 和 assertion。
MPI 允许用户提供两种类型的与应用有关的信息:hints 和 assertions。hints 是应用中所做的有助于提高程序性能的选项,MPI 实现可以忽略用户提供的 hints 而不影响程序的正确性;assertions 是用户(编程者)给 MPI 实现的有关其应用程序行为的保证——如果程序给出的某个 assertion 并不正确,MPI 实现可能会产生错误的结果。在 MPI 中大多数的 hints 都是通过 MPI.Info 对象传递给 MPI 实现的,而 assertions 则是传递给一些 MPI 函数/方法的整数值。用户可以不提供 hints 或 assertions,应用程序可以在不提供它们的情况下正确运行,但是,提供合适的 hints 或正确的 assertions 可以提高应用程序的性能。hints 和 assetions 都是可移植的。除了 MPI 标准提供的 hints 外,不同的 MPI 实现可能会定义额外的不同的 hints,用户应该查看相关的文档以了解可用的 hints 及其作用。
MPI-2 引进了 Info 对象,MPI 中的很多函数都使用了 info 参数,Info 参数以 字符串二元组的形式定义信息。MPI 本身也使用一些预留的关键字来保存环境与外部交互,以及其他一些属性信息。关键字和值分别由 MPI.MAX_INFO_KEY 和 MPI.MAX_INFO_VAL 定义上限。
hints 和 Info 对象 一般接口

MPI.Info.Create(type cls)

【mpi4py|mpi4py 中的 info 和 assertion】创建一个 Info 对象,将其 二元组初始化为空。
MPI.Info.Dup(self)

复制当前 Info 对象,包括其中的 二元组。
MPI.Info.Delete(self, key)

从当前 Info 对象中删除 二元组,如果 key 参数指定的关键字不存在,则会抛出 MPI.Exception 异常。
MPI.Info.Free(self)

删除并释放当前 Info 对象,将其值设置为 MPI.INFO_NULL。
MPI.Info.Set(self, key, value)

为当前 Info 对象设置二元组 ,如果 key 所指定的关键字已经存在,则覆盖其原有的值。如果 keyvalue 参数的字符串长度超过上限,则会抛出 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 对象中定义的关键字总数。
MPI.Info.Get_nthkey(self, int n)

返回当前 Info 对象中第 n 个关键字,关键字编号从 0 开始。
类似与字典的接口
MPI.Info.__len__(self)

使用 len 函数获取当前 Info 对象中定义的关键字总数。
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 对象设置 二元组。
MPI.Info.__delitem__(self, object key)

使用 del info[key] 的方式从当前 Info 对象中删除 二元组。
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 对象的所有 二元组,结果是一个 list,其每一个元素为一个二元 tuple。
MPI.Info.update(self, other=(), **kwds)

otherkwds 中的 key 和 value 来更新当前 Info 对象的关键字和值,类似于 Python 字典的 update 操作。
MPI.Info.copy(self)

复制当前 Info 对象,包括其中的 二元组。同 MPI.Info.Dup。
MPI.Info.clear(self)

删除当前 Info 对象中的所有 二元组。
MPI-3 新方法 因为 Info 对象可以潜在地帮助 MPI 实现提供更高的性能,MPI-3 中新增了若干与 Info 相关的方法,允许设置和获取通信子,窗口以及文件句柄的 Info。另外,MPI-3 中增加一个新的通信子复制方法 MPI.Comm.Dup_with_info,该方法与 MPI.Comm.Dup 的作用类似,不过允许在复制通信子对象的时候为其设置一个新的 Info 对象,而不是将原通信子的 Info 对象也一并复制过来。该方法对 MPI 库的开发非常有用,因为通信子复制方法通常被库的开发者用来在库内部创建一个私有的通信子,以防止库内的通信操作对外部的通信产生干扰,库在复制通信子的过程中可能并不需要将用户设置在原通信子上的某些 info 键值对也一并复制过去,因此可以使用 MPI.Comm.Dup_with_info 在复制的过程中为其设置一个新的库所需要的 Info 对象。下面是这些新方法的使用接口。注意:在 mpi4py 中,MPI.Comm.Dup 方法在传递一个有效的 info 参数时等价于 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 参数的作用和可能取值在单边通信和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 MPIcomm = 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_NULLtry: # 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_stringtry: # 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 对象。

    推荐阅读