zoukankan      html  css  js  c++  java
  • MPI自定义数据类型

    自定义数据类型

    1.数据类型辅助函数
    • MPI_Type_commit
    int MPI_Type_commit(
      MPI_Datatype *datatype
    );
    

    在通信中使用数据类型对象之前,必须提交数据类型对象。提交的数据类型仍可用作数据类型构造函数中的参数。无需提交基本数据类型。它们是"预先承诺的"。

    • MPI_Type_free
    int MPI_Type_free(
      MPI_Datatype *datatype
    );
    

    标记与处理数据的数据类型关联的数据类型对象,并将数据类型设置到MPI_DATATYPE_NULL。当前使用此数据类型的任何通信都将正常完成。从释放的数据类型定义的派生数据类型不受影响。

    • MPI_Type_extent(已弃用,由替换MPI_Type_get_extent)
    int MPI_Type_extent(
      MPI_Datatype datatype,
      MPI_Aint *extent
    );
    

    此例程既具有线程安全,也具有中断安全。这意味着此例程可能安全地由多个线程使用,也可以在信号处理程序中使用。

    • MPI_Address
    int MPI_Address(
      void *location,
      MPI_Aint *address
    );
    

    获取内存中的某位置的地址,返回指定变量内存中的“绝对”地址。

    2.Contiguous数据类型
    • MPI_Type_contiguous
    int MPI_Type_contiguous(
      int count,
      MPI_Datatype old_type,
      MPI_Datatype *new_type_p
    );
    

    连续复制:将原数据类型oldtype按顺序依次连续复制后,得到一个新的数据类型。比如定义连续的2个实数为一个新的数据类型。

     MPI_Type_contiguous( 2, MPI_CHAR, &type );
    
    3.Vector数据类型
    • MPI_Type_vector
    int MPI_Type_vector(
      int count,
      int blocklength,
      int stride,
      MPI_Datatype old_type,
      MPI_Datatype *newtype_p
    );
    

    创建向量(步幅)数据类型。先连续复制blocklength个oldtype类型的数据,形成一个数据块;再通过等间隔的复制count个该数据块形成新的数据类型;相邻两个数据的的起始位置的位移相差stride乘extent(oldtype)个字节。
    例如有oldtype数据
    1,2,3,4,5,6,7,8
    现在要求新的数据类型3个,每连续2个作为一个新的数据类型,间隔为1.

    MPI_Type_vector(3,2,1,old,new)
    
    • MPI_Type_hvector
    int MPI_Type_hvector(
      int count,
      int blocklen,
      MPI_Aint stride,
      MPI_Datatype old_type,
      MPI_Datatype *newtype_p
    );
    

    功能同MPI_Type_vector相同,唯一区别就是stride的单位是字节。

    4.Index数据类型
    • MPI_Type_indexed
    int MPI_Type_indexed(
      int count,
      int blocklens[],
      int indices[],//位移,和首地址的位移
      MPI_Datatype old_type,
      MPI_Datatype *newtype
    );
    

    创建索引数据类型:该函数生成的新数据类型有count个数据块构成,第i个数据块包含blocklens[i]个连续存放的oldtype,第i个数据块与首地址的偏移量(字节数)为indices[i]乘extent(oldtype)。
    可以看作是MPI_Type_vector的扩展,区别是买个数据块的长度可以不同,数据块之间的间隔也可以不同。

    • MPI_Type_hindexed
    int MPI_Type_hindexed(
      int count,
      int blocklens[],
      MPI_Aint indices[],
      MPI_Datatype old_type,
      MPI_Datatype *newtype
    );
    

    功能同MPI_Type_vector相同,唯一区别就是indices数组存放的数据单位是字节。

    • MPI_Type_struct
    int MPI_Type_struct(
      int count,
      int blocklens[],
      MPI_Aint indices[],
      MPI_Datatype old_types[],
      MPI_Datatype *newtype
    );
    

    创建结构数据类型:与MPI_Type_indexed的区别在于每个数据块的数据类型可以不同,这里的indices数组存访的单位是字节。
    该函数时最一般的新数据类型的构造函数,也是最广泛的一个。

    MPI的数据打包与拆包

    打包(Pack)和解包(Unpack)操作是为了发送不连续的数据, 在发送前显示地把数据包装大一个连续的缓冲区, 在接收之后从连续的缓冲区中解包。

    • MPI_Pack
    int MPI_Pack(
      void *inbuf,
      int incount,
      MPI_Datatype datatype,
      void *outbuf,
      int outcount,
      int *position,
      MPI_Comm comm
    );
    

    MPI_PACK把由inbuf,incount, datatype指定的发送缓冲区中的incount个datatype类型的消息放到起始为 outbuf 的连续空间,该空间共有 outcount 个字节。 输入缓冲区可以是 MPI_Send 允许的任何通信缓冲区。入口参数 position 的值是输出缓冲区中用于打包的起始地址,打包后它的值根据打包消息的大小来增加,出口参数 position 的值是被打包的消息占用的输出缓冲区后面的第一个地址。通过连续几次对不同位置的消息调用打包操作, 就将不连续的消息放到了一个连续的空间。comm参数是将在后面用于发送打包的消息时用的通信域。 (NOTE:这里要连续多次调用打包操作)

    • MPI_Unpack
    int MPI_Unpack(
      void *inbuf,
      int insize,
      int *position,
      void *outbuf,
      int outcount,
      MPI_Datatype datatype,
      MPI_Comm comm
    );
    

    MPI_UNPACK 和 MPI_PACK 对应, 它从 inbuf 和 insize 指定的缓冲区空间将不连续的消息解开,放到 outbuf, outcount, datatype 指定的缓冲区中。 输出缓冲区可以是 MPI_RECV 允许的任何通信缓冲区。 输入缓冲区是一个连续的存储空间,大小为insize字节, 开始地址为 inbuf。入口参数 position的初始值是输出缓冲区中被打包消息占用的起始地址, 解包后它的值根据打包消息的大小来增加,因此出口参数 position的值是输出缓冲区中被解包的消息占用空间后面的第一个地址。 通过连续几次对已打包的消息调用与打包时相应的解包操作,就可以将连续的消息解开放到一个不连续的空间。comm参数是用于接收消息的通信域。

    • MPI_Pack_size
    int MPI_Pack_size(
      int incount,
      MPI_Datatype datatype,
      MPI_Comm comm,
      int *size
    );
    

    描述MPI_Pack和MPI_Unpack的最大值。

  • 相关阅读:
    [sql]在case语句中不同情况下then的数据的数据类型不一致ORA-00932: inconsistent datatypes: expected NUMBER got CHAR
    环境迁移 小记
    linux下安装oracle遇到的问题
    正向代理与反向代理
    文件夹与SVN脱离关系
    shell 脚本中$$,$#,$?
    在MySQL中单列索引和联合索引的区别
    Java中Map、HashMap、LinkedHashMap、TreeMap的区别
    Error、Exception与RuntimeException的区别
    设计模式--单例模式
  • 原文地址:https://www.cnblogs.com/zhangyazhou/p/13376284.html
Copyright © 2011-2022 走看看