派生数据类型
原理
目的
- 传递含有不同数据类型值的信息(例如:int-float)
- 传递非连续数据的用户(例如:矩阵的一个子块)
方法
- 在发送端将非连续的数据打包到一个连续的缓冲区,在接收端再解包(缺点:接收端和发送端都需要额外的内存和内存拷贝操作)
类型图——通用的数据类型表述方法
- 类型图:是一系列二元数组的集合,两个数据类型是否相同,取决于它们的类型图是否相同。将类型图和一个数据缓冲区的基地值结合起来,可以说明一个通信缓冲区的数据分布情况。
类型图={<基类型0, 偏移0>, <基类型1, 偏移1>, <基类型2, 偏移2>,…,<基类型n-1, 偏移n-1>}
基类型:指出该类型图中包含哪些基本的数据类型
偏移:指该基类型在整个类型图中的起始位置
例子:MPI_INT := {(int, 0)}
- 类型图的相关量:
类型图:
typemap={( t y p e 0 type_0 type0, d i s p 0 disp_0 disp0),…,( t y p e n − 1 type_{n-1} typen−1, d i s p n − 1 disp_{n-1} dispn−1)}
类型图下界:
lb(typemap)=min{ d i s p j disp_j dispj}, 0 ≤ \leq ≤ j ≤ \leq ≤ n-1
类型图上界:
ub(typemap)=max{ d i s p j disp_j dispj+sizeof( t y p e j type_j typej)}, 0 ≤ \leq ≤ j ≤ \leq ≤ n-1
类型图的跨度:
extent(typemap)=ub(typemap)-lb(typemap)+ ϵ \epsilon ϵ
ϵ \epsilon ϵ: 由于不同的类型有不同的对其位置要求,是能够使类型图的跨度,满足类型图中所有的类型能达到下一个对齐要求,所需要的最小非负整数值
例子:
type={(double,0),(char,8)};假设double型的值必须严格分配到地址为8的倍数的存储空间,则该数据类型的extent是16
新数据类型的定义
连续复制的类型生成
- 数据类型生成器:
int MPI_Type_contiguous(int count,MPI_Datatype oldtype,MPI_Datatype *newtype)
IN count:复制个数(非负整数)
IN oldtype:旧数据类型(句柄)
OUT newtype:新数据类型(句柄)
RETURN int:返回1,0标志操作是否成功的
- 例子:
设
oldtype={(double,0),(char,8)}
extent=16
count=3
则MPI_TYPE_CONTIGUOUS
返回的新的数据类型为:
newtype={(double,0),(char,8),(double,16),(char,24),(double,32),(char,40)}
- 更通用的表达:
设旧类型oldtype的类型图为
oldtype={( t y p e 0 type_0 type0, d i s p 0 disp_0 disp0),…,( t y p e n − 1 type_{n-1} typen−1, d i s p n − 1 disp_{n-1} dispn−1)},其跨度为extent=ex.
新类型newtype将oldtype连续复制count次,则新类型newtype的类型图为
newtype={( t y p e 0 type_0 type0, d i s p 0 disp_0 disp0),…,( t y p e n − 1 type_{n-1} type