在上一篇中我們介紹了 mpi4py 中的通用化請求,下面我們將介紹 mpi4py 中的數(shù)據(jù)類型解析。
通過自定義數(shù)據(jù)類型,應(yīng)用程序可任意指定數(shù)據(jù)在內(nèi)存中的布局。在 MPI-1 中,一旦確定了數(shù)據(jù)類型定義,則定義的具體細節(jié)將無從獲取。某些情況下,在數(shù)據(jù)類型定義完之后,仍有必要訪問其定義流程、數(shù)據(jù)布局等信息,為此 MPI-2 提供了一些函數(shù)來解析定義數(shù)據(jù)類型過程的信息,如數(shù)據(jù)類型圖,數(shù)據(jù)類型描述等。
方法接口
MPI.Datatype.Get_envelope(self)
獲取創(chuàng)建數(shù)據(jù)類型的參數(shù)數(shù)量信息,返回值為一個 (num_integers, num_addresses, num_datatypes, combiner) 的四元 tuple,其中 num_integers 是數(shù)據(jù)類型創(chuàng)建函數(shù)使用整型參數(shù)的個數(shù),num_addresses 是數(shù)據(jù)類型創(chuàng)建函數(shù)使用地址型參數(shù)的個數(shù),num_datatypes 是數(shù)據(jù)類型創(chuàng)建函數(shù)使用原始數(shù)據(jù)類型的個數(shù),combiner 是數(shù)據(jù)創(chuàng)建函數(shù)的類型,下表是常用的 combiner 取值和數(shù)據(jù)類型創(chuàng)建函數(shù)的對應(yīng)關(guān)系:
| combiner 取值 | 對應(yīng)的數(shù)據(jù)類型創(chuàng)建函數(shù) |
|---|---|
| MPI.COMBINER_NAMED | MPI 預(yù)定義數(shù)據(jù)類型,已命名 |
| 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)
獲取創(chuàng)建數(shù)據(jù)類型的實際參數(shù)信息,返回值是一個 (array_of_integers, array_of_addresses, array_of_datatypes) 的三元 tuple,其中 array_of_integers 是一個整數(shù)列表,包含創(chuàng)建數(shù)據(jù)類型所使用的所有整型參數(shù),array_of_addresses 是一個整數(shù)列表,包含創(chuàng)建數(shù)據(jù)類型所使用的所有地址型參數(shù),array_of_datatypes 是一個數(shù)據(jù)類型列表,包含創(chuàng)建數(shù)據(jù)類型所使用的所有原始數(shù)據(jù)類型參數(shù)。
注意:該方法只能在未命名的自定義數(shù)據(jù)類型上調(diào)用,否則會拋出 MPI.Exception。
MPI.Datatype.decode(self)
更方便的數(shù)據(jù)類型解析方法,會根據(jù)不同的數(shù)據(jù)類型返回不同的方便解讀的信息。
屬性
envelope
結(jié)果同 MPI.Datatype.Get_envelope 的返回值。
contents
結(jié)果同 MPI.Datatype.Get_contents 的返回值。
combiner
結(jié)果同 MPI.Datatype.Get_envelope 的返回值的最后一個元素。
is_named
是否是 MPI 預(yù)定義的已命名數(shù)據(jù)類型。
is_predefined
是否是 MPI 預(yù)定義數(shù)據(jù)類型。對 MPI 預(yù)定義的已命名數(shù)據(jù)類型,以及 MPI_DATATYPE_NULL,MPI_COMBINER_F90_INTEGER,MPI_COMBINER_F90_REAL,MPI_COMBINER_F90_COMPLEX 都返回 True。
name
數(shù)據(jù)類型的名稱。
例程
下面給出使用例程。
# 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
運行結(jié)果如下:
$ 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: <mpi4py.MPI.Datatype object at 0x7f6d3fd5b2f0>
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], [<mpi4py.MPI.Datatype object at 0x7f6d3fd5bb90>])
Ihvec.contents: ([2, 3], [16], [<mpi4py.MPI.Datatype object at 0x7f6d3fd5bb90>])
Ihvec.decode: (<mpi4py.MPI.Datatype object at 0x7f6d3fd5bb90>, '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], [], [<mpi4py.MPI.Datatype object at 0x7f6d3fd5bb90>])
Ihvec4.contents: ([4], [], [<mpi4py.MPI.Datatype object at 0x7f6d3fd5bb90>])
Ihvec4.decode: (<mpi4py.MPI.Datatype object at 0x7f6d3fd5bb90>, 'CONTIGUOUS', {'count': 4})
Ihvec4.is_named: False
Ihvec4.is_predefined: False
Ihvec4.name:
以上介紹了 mpi4py 中的數(shù)據(jù)類型解析,在下一篇中我們將介紹 mpi4py 中的 Op 對象。