在上一篇中我们介绍了 mpi4py 中的通用化请求,下面我们将介绍 mpi4py 中的数据类型解析。
通过自定义数据类型,应用程序可任意指定数据在内存中的布局。在 MPI-1 中,一旦确定了数据类型定义,则定义的具体细节将无从获取。某些情况下,在数据类型定义完之后,仍有必要访问其定义流程、数据布局等信息,为此 MPI-2 提供了一些函数来解析定义数据类型过程的信息,如数据类型图,数据类型描述等。
方法接口
MPI.Datatype.Get_envelope(self)
获取创建数据类型的参数数量信息,返回值为一个 (num_integers, num_addresses, num_datatypes, combiner) 的四元 tuple,其中 num_integers 是数据类型创建函数使用整型参数的个数,num_addresses 是数据类型创建函数使用地址型参数的个数,num_datatypes 是数据类型创建函数使用原始数据类型的个数,combiner 是数据创建函数的类型,下表是常用的 combiner 取值和数据类型创建函数的对应关系:
combiner 取值 | 对应的数据类型创建函数 |
---|---|
MPI.COMBINER_NAMED | MPI 预定义数据类型,已命名 |
MPI.COMBINER_DUP | MPI.Datatype.Dup |
MPI.COMBINER_CONTIGUOUS | MPI.Datatype.Create_contiguous |
MPI.COMBINER_VECTOR | MPI.Datatype.Create_vector |
MPI.COMBINER_HVECTOR | MPI.Datatype.Create_hvector |
MPI.COMBINER_INDEXED | MPI.Datatype.Create_indexed |
MPI.COMBINER_INDEXED_BLOCK | MPI.Datatype.Create_indexed_block |
MPI.COMBINER_HINDEXED | MPI.Datatype.Create_hindexed |
MPI.COMBINER_HINDEXED_BLOCK | MPI.Datatype.Create_hindexed_block |
MPI.COMBINER_STRUCT | MPI.Datatype.Create_struct |
MPI.COMBINER_SUBARRAY | MPI.Datatype.Create_subarray |
MPI.COMBINER_DARRAY | MPI.Datatype.Create_darray |
MPI.COMBINER_F90_REAL | MPI.Datatype.Create_f90_real |
MPI.COMBINER_F90_COMPLEX | MPI.Datatype.Create_f90_complex |
MPI.COMBINER_F90_INTEGER | MPI.Datatype.Create_f90_integer |
MPI.COMBINER_RESIZED | MPI.Datatype.Create_resized |
MPI.Datatype.Get_contents(self)
获取创建数据类型的实际参数信息,返回值是一个 (array_of_integers, array_of_addresses, array_of_datatypes) 的三元 tuple,其中 array_of_integers 是一个整数列表,包含创建数据类型所使用的所有整型参数,array_of_addresses 是一个整数列表,包含创建数据类型所使用的所有地址型参数,array_of_datatypes 是一个数据类型列表,包含创建数据类型所使用的所有原始数据类型参数。
注意:该方法只能在未命名的自定义数据类型上调用,否则会抛出 MPI.Exception。
MPI.Datatype.decode(self)
更方便的数据类型解析方法,会根据不同的数据类型返回不同的方便解读的信息。
属性
envelope
结果同 MPI.Datatype.Get_envelope 的返回值。
contents
结果同 MPI.Datatype.Get_contents 的返回值。
combiner
结果同 MPI.Datatype.Get_envelope 的返回值的最后一个元素。
is_named
是否是 MPI 预定义的已命名数据类型。
is_predefined
是否是 MPI 预定义数据类型。对 MPI 预定义的已命名数据类型,以及 MPI_DATATYPE_NULL,MPI_COMBINER_F90_INTEGER,MPI_COMBINER_F90_REAL,MPI_COMBINER_F90_COMPLEX 都返回 True。
name
数据类型的名称。
例程
下面给出使用例程。
# decoding.py
"""
Demonstrates the usage of datatype decoding.
Run this with 1 processes like:
$ mpiexec -n 1 python decoding.py
or
$ python decoding.py
"""
from mpi4py import MPI
comm = MPI.COMM_WORLD
Int = MPI.INT
Ihvec = MPI.INT.Create_hvector(2, 3, 4*4)
Ihvec4 = Ihvec.Create_contiguous(4)
for dtyp, typ_name in [ (Int, 'MPI.INT'), (Ihvec, 'Ihvec'), (Ihvec4, 'Ihvec4') ]:
print '%s.Get_envelope: %s' % (typ_name, dtyp.Get_envelope())
print '%s.envelope: %s' % (typ_name, dtyp.envelope)
print '%s.combiner: %s' % (typ_name, dtyp.combiner)
try:
print '%s.Get_contents: %s' % (typ_name, dtyp.Get_contents())
print '%s.contents: %s' % (typ_name, dtyp.contents)
except MPI.Exception as e:
print e.error_string
print '%s.decode: %s' % (typ_name, dtyp.decode())
print '%s.is_named: %s' % (typ_name, dtyp.is_named)
print '%s.is_predefined: %s' % (typ_name, dtyp.is_predefined)
print '%s.name: %s' % (typ_name, dtyp.name)
print
运行结果如下:
$ python decoding.py
MPI.INT.Get_envelope: (0, 0, 0, 0)
MPI.INT.envelope: (0, 0, 0, 0)
MPI.INT.combiner: 0
MPI_ERR_INTERN: internal error
MPI.INT.decode:
MPI.INT.is_named: True
MPI.INT.is_predefined: True
MPI.INT.name: MPI_INT
Ihvec.Get_envelope: (2, 1, 1, 5)
Ihvec.envelope: (2, 1, 1, 5)
Ihvec.combiner: 5
Ihvec.Get_contents: ([2, 3], [16], [])
Ihvec.contents: ([2, 3], [16], [])
Ihvec.decode: (, 'HVECTOR', {'count': 2, 'blocklength': 3, 'stride': 16})
Ihvec.is_named: False
Ihvec.is_predefined: False
Ihvec.name:
Ihvec4.Get_envelope: (1, 0, 1, 2)
Ihvec4.envelope: (1, 0, 1, 2)
Ihvec4.combiner: 2
Ihvec4.Get_contents: ([4], [], [])
Ihvec4.contents: ([4], [], [])
Ihvec4.decode: (, 'CONTIGUOUS', {'count': 4})
Ihvec4.is_named: False
Ihvec4.is_predefined: False
Ihvec4.name:
以上介绍了 mpi4py 中的数据类型解析,在下一篇中我们将介绍 mpi4py 中的 Op 对象。