本文共 9421 字,大约阅读时间需要 31 分钟。
类型图={<基类型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标志操作是否成功的
MPI_TYPE_CONTIGUOUS
返回的新的数据类型为: newtype={(double,0),(char,8),(double,16),(char,24),(double,32),(char,40)}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} typen−1, d i s p n − 1 disp_{n-1} dispn−1),
( t y p e 0 type_0 type0, d i s p 0 + e x disp_0+ex disp0+ex),…,( t y p e n − 1 type_{n-1} typen−1, d i s p n − 1 + e x disp_{n-1}+ex dispn−1+ex), …, ( t y p e 0 type_0 type0, d i s p 0 + e x ( c o u n t − 1 ) disp_0+ex(count-1) disp0+ex(count−1)),…,( t y p e n − 1 type_{n-1} typen−1, d i s p n − 1 + e x ( c o u n t − 1 ) disp_{n-1}+ex(count-1) dispn−1+ex(count−1))} 其类型的跨度为 c o u n t × e x count \times ex count×ex
int MPI_Type_vector(int count,int blocklength,int stride,MPI_Datatype oldtype,MPI_Datatype *newtype)
IN count:块的数目(非负整数)
IN blocklength:每个块中所含元素的个数(非负整数) IN stride:各块第一个元素之间相隔的元素个数(整数) IN oldtype:旧数据类型(句柄) OUT newtype:新数据类型(句柄)
int MPI_Type_hvector(int count,int blocklength,int stride,MPI_Datatype oldtype,MPI_Datatype *newtype)
IN count:块的数目(非负整数)
IN blocklength:每个块中所含元素的个数(非负整数) IN stride:各块第一个元素之间相隔的字节数(整数) IN oldtype:旧数据类型(句柄) OUT newtype:新数据类型(句柄)
MPI_TYPE_VECTOR(2,3,4,oldtype,newtype)
生成的数据类型的类型图为: newtype={(double,0),(char,8),(double,16),(char,24),(double,32),(char,40),(double,64),(char 72),(double,80),(char,88),(double,96),(char,104)}MPI_TYPE_VECTOR(3,1,-2,oldtype,newtype)
生成的数据类型的类型图为: newtype={(double,0),(char,8),(double,-32),(char,-24),(double,-64),(char,-56)}block(offset)= { ( t y p e 0 , d i s p 0 + o f f s e t ) , . . . , ( t y p e n − 1 , d i s p n − 1 + o f f s e t ) , \{(type_0,disp_0+offset),...,(type_{n-1},disp_{n-1}+offset), { (type0,disp0+offset),...,(typen−1,dispn−1+offset),
( t y p e 0 , d i s p 0 + e x + o f f s e t ) , . . . , ( t y p e n − 1 , d i s p n − 1 + e x + o f f s e t ) , (type_0,disp_0+ex+offset),...,(type_{n-1},disp_{n-1}+ex+offset), (type0,disp0+ex+offset),...,(typen−1,dispn−1+ex+offset), . . . , ..., ..., ( t y p e 0 , d i s p 0 + e x ( b l − 1 ) + o f f s e t ) , . . . , ( t y p e n − 1 , d i s p n − 1 + e x ( b l − 1 ) + o f f s e t ) } (type_0,disp_0+ex(bl-1)+offset),...,(type_{n-1},disp_{n-1}+ex(bl-1)+offset)\} (type0,disp0+ex(bl−1)+offset),...,(typen−1,dispn−1+ex(bl−1)+offset)} newtype= { b l o c k ( 0 ) , b l o c k ( s t r i d e ) , . . . , b l o c k ( s t r i d e ∗ ( c o u n t − 1 ) ) } \{block(0),block(stride),...,block(stride*(count-1))\} { block(0),block(stride),...,block(stride∗(count−1))}
MPI_TYPE_CONTIGUOUS(count,oldtype,newtype)
等价于MPI_TYPE_VECTOR(count,1,1,oldtype,newtype)
或MPI_TYPE_VECTOR(1,count,n,oldtype,newtype)
(n为升序)int MPI_Type_indexed(int count, int *array_of_blocklengths, MPI_Aint *array_of_displacements, MPI_Datatype_oldtype, MPI_Datatype *newtype)
IN count:块的数量(整型)
IN array_of_blocklengths:每个块中所含的元素个数(非负整数数组) IN array_of_displacements:各块偏移的元素个数(整数数组) IN oldtype:旧数据类型 OUT newtype:新数据类型
int MPI_Type_hindexed(int count, int *array_of_blocklengths, int *array_of_displacements, MPI_Datatype_oldtype, MPI_Datatype *newtype)
IN count:块的数量(整型)
IN array_of_blocklengths:每个块中所含的元素个数(非负整数数组) IN array_of_displacements:各块偏移的字节数(整数数组) IN oldtype:旧数据类型 OUT newtype:新数据类型
MPI_TYPE_INDEXED(2,B,D,oldtype,newtype)
调用生成的数据类型图为: newtype={(double,64),(char,72),(double,80),(char,88),(double,96),(char,104),(double,0),(char,8)}int MPI_Type_struct(int count, int *array_of_blocklengths, MPI_Aint *array_of_displacements, MPI_Datatype array_of_types, MPI_Datatype *newtype)
IN count:块的数目(整数)
IN array_of_blocklengths:每个块中所含元素个数(非负整数数组) IN array_of_displacements:各块偏移字节数(整数数组) IN array_of_types:每个块中元素的类型(句柄) OUT newtype:新数据类型(句柄)
MPI_TYPE_STRUCT(3,B,D,T,newtype)
返回的新数据类型为: newtype={(float,0),(float,4),(double,16),(char,24),(char,26),(char,27),(char,28)}MPI_TYPE_HINDEXED(count,B,D,oldtype,newtype)
等价于MPI_TYPE_STRUCT(count,B,D,T,newtype)
,其中T的每一项都是oldtype新定义的数据类型在使用之前,必须先递交给MPI系统.递交之后的数据类型可以作为一个基本数据类型,用在数据类型生成器中产生新的数据类型.
int MPI_Type_commit(MPI_Datatype *datatype)
递交作用用于定义新的数据类型
int MPI_Type_free(MPI_Datatype *datatype)
释放操作用于释放已提交的数据类型,并且将该数据类型的指针或句柄设为空MPI_DATATYPE_NULL.由该派生类型定义的新派生类型不受当前派生类型释放的影响.
int MPI_Type_extent(MPI_Datatype datatype, int *extent)
IN datatype:数据类型(句柄)
OUT extent:数据类型的extent(整型) 作用:MPI_TYPE_EXTENT
以字节为单位返回一个数据类型的跨度extent
int MPI_Type_size(MPI_Datatype datatype, int *size)
IN datatype:数据类型(句柄)
OUT size:数据类型的大小(整型) 作用:MPI_TYPE_SIZE
以字节为单位,返回一个数据类型有用部分所占空间的大小,即跨度减去类型中空隙后的空间的大小.
int MPI_Get_elements(MPI_Status status, MPI_Datatype datatype, int *count)
IN status:接受操作后返回的状态(状态类型)
IN datatype:接受操作后使用的数据类型(句柄) OUT count:接收到的基本元素个数 作用:MPI_GET_ELEMENTS
返回以基本数据类型为单位的个数
int MPI_Get_count(MPI_Status *status, MPI_Datatype datatype, int *int)
IN status:接受操作后返回的状态(状态类型)
IN datatype:接受操作后使用的数据类型(句柄) OUT count:接受到的以指定的数据类型为单位的数据个数(整型)MPI_GET_COUNT
返回的是以指定的数据类型为单位,接受操作接收到的数据个数.
MPI提供两个特殊的数据类型,称为伪数据类型,上界标记类型MPI_UB
和下界标记类型MPI_LB
.这两个数据类型不占空间,即extent(MPI_LB)=extent(MPI_UB)=0
.
typemap的下界: l b ( T y p e m a p ) = { m i n j d i s p j 不 包 含 l b 类 型 m i n j { d i s p j ∣ t y p e j = l b } 若 含 有 l b 类 型 lb(Typemap) = \begin{cases} min_j disp_j \quad不包含lb类型 \\ min_j \{disp_j | type_j=lb\} \quad 若含有lb类型 \end{cases} lb(Typemap)={ minjdispj不包含lb类型minj{ dispj∣typej=lb}若含有lb类型
typemap的上界: u b ( T y p e m a p ) = { m a x j d i s p j + s i z e o f ( t y p e j ) + ϵ 不 包 含 u b 类 型 m a x j { d i s p j ∣ t y p e j = u b } 若 含 有 u b 类 型 ub(Typemap) = \begin{cases} max_j disp_j+sizeof(type_j)+\epsilon \quad不包含ub类型 \\ max_j \{disp_j | type_j=ub\} \quad 若含有ub类型 \end{cases} ub(Typemap)={ maxjdispj+sizeof(typej)+ϵ不包含ub类型maxj{ dispj∣typej=ub}若含有ub类型
数据类型typemap的跨度:
e x t e n t ( t y p e m a p ) = u b ( t y p e m a p ) − l b ( t y p e m a p ) extent(typemap)=ub(typemap)-lb(typemap) extent(typemap)=ub(typemap)−lb(typemap)int MPI_Type_lb(MPI_Datatype datatype, int *displacement)
IN datatype:数据类型(句柄)
OUT displacement:下界的偏移(整数)
int MPI_Type_ub(MPI_Datatype datatype, int *displacement)
IN datatype:数据类型(句柄)
OUT displacement:上界的位移(整数)
MPI_TYPE_STRUCT(3,B,D,T,type1)
产生了一个extent=9的数据类型 type1={(lb,-3),(int,0),(ub,6)}.如果该数据类型被MPI_TYPE_COUNTIGUOUS(2,type1,type2)
复制两次,则新生成的序列为 type2={(lb,3),(int,0),(int,9),(ub,15)} (如果lb或者ub出现在数据类型两端以外的位置,则它们可以被忽略)打包和解包操作是为了发送不连续的数据,在发送前显式地把数据包装到一个连续的缓冲区,在接收之后从连续缓冲区中解包.
int MPI_Pack(void *inbuf, int incount, MPI_Datatype datatype, void *outbuf, int outcount, int *position, MPI_Comm comm)
IN inbuf:输入缓冲区起始地址
IN incount:输入数据项个数 IN datatype:每个输入数据项的类型 OUT outbuf:输出缓冲区开始地址 IN outcount:输出缓冲区的大小 INOUT position:缓冲区当前位置 IN comm:通信域
int MPI_Unpack(void *inbuf, int insize, int *position, void *outbuf, int outcount, MPI_Datatype datatype, MPI_Comm comm)
IN inbuf:输入缓冲区起始
IN insize:输入数据项数目 INOUT position:缓冲区当前位置 OUT outbuf:输出缓冲区起始 IN outcount:输出缓冲区大小 IN datatype:每个输入数据项的类型 IN comm:打包的信息的通信域
int MPI_Pack_size(int incount, MPI_Datatype datatype, MPI_Comm comm, int *size)
IN incount:指定数据类型的个数
IN datatype:数据类型 IN comm:通信域 OUT size:以字节为单位,incount个datatype数据类型打包需要的空间
int position, i, j, a[2];char buff[1000];MPI_Comm_rank(MPI_COMM_WORLD, &myrank);// 进程0发送信息if(myrank==0){ position=0; // 打包的起始位置 MPI_Pack(&i, 1, MPI_INT, buff, 1000, &position, MPI_COMM_WORLD);// 将整数i打包 MPI_Pack(&j, 1, MPI_INT, buff, 1000, &position, MPI_COMM_WORLD); // 将整数j打包 MPI_Send(buff, position, MPI_PACKED, 1, 0, MPI_COMM_WORLD); // 将打包后的数据发送出去}else if(myrank==1){ MPI_Recv(a, 2, MPI_INT, 0, 0, MPI_COMM_WORLD); // 以整型从进程0接收消息}
参考文献:《MPI并行程序设计》链接: https://pan.baidu.com/s/1mVKWmzc8AHT1Crxa5ZWArQ 密码: c49v
转载地址:http://hvxvi.baihongyu.com/