▶ MPI 中与数据打包传输有关的几个函数

● 函数 MPI_Pack() 与 MPI_Unpack() 的原型

 MPI_METHOD MPI_Pack(
_In_opt_ const void* inbuf, // 指向待打包数据的指针
_In_range_(>= , ) int incount, // 带打包数据元素个数
_In_ MPI_Datatype datatype, // 数据类型
_mpi_writes_bytes_(outsize) void* outbuf, // 指向打包输出缓冲区的指针
_In_range_(>= , ) int outsize, // 缓冲区大小(单位为 Byte)
_mpi_position_(outsize) int* position, // 输出缓冲区中第一个用于打包的位置(地址偏移量)
_In_ MPI_Comm comm // 通信子
); MPI_METHOD MPI_Unpack(
_mpi_reads_bytes_(insize) const void* inbuf,// 指向待解包缓冲区的指针
_In_range_(>= , ) int insize, // 缓冲区大小(单位为 Byte)
_mpi_position_(insize) int* position, // 输出缓冲区中第一个用于打包的位置(地址偏移量)
_When_(insize > , _Out_opt_) void* outbuf, // 指向解包后数据的指针
_In_range_(>= , ) int outcount, // 解包元素个数
_In_ MPI_Datatype datatype, // 数据类型
_In_ MPI_Comm comm // 通信子
);

● 使用范例

 int main(int argc, char *argv[])
{
int rank, size, i, position;
char c[], buffer[];// 缓冲区大小 110,即 110 Byte MPI_Init(&argc, &argv);
MPI_Comm_size(MPI_COMM_WORLD, &size);
MPI_Comm_rank(MPI_COMM_WORLD, &rank); position = ; // position 需要赋值为一个非负数,否则报错(?)
if (rank == ) // 0 号进程打包 1 个整形变量和 1 个字符型数组到同一片内存中,发送给 1 号进程
{
for (i = ; i < ; c[i] = i, i++);
i = ;
MPI_Pack(&i, , MPI_INT, buffer, , &position, MPI_COMM_WORLD);// 打包和解包缓冲区时要注明大小(单位为 Byte)
MPI_Pack(c, , MPI_CHAR, buffer, , &position, MPI_COMM_WORLD);
MPI_Send(buffer, position, MPI_PACKED, , , MPI_COMM_WORLD);
}
if (rank == )
{
MPI_Recv(buffer, , MPI_PACKED, , , MPI_COMM_WORLD, MPI_STATUS_IGNORE);
MPI_Unpack(buffer, , &position, &i, , MPI_INT, MPI_COMM_WORLD);
MPI_Unpack(buffer, , &position, c, , MPI_CHAR, MPI_COMM_WORLD);
printf("i=%d, c[0] = %d, c[99] = %d\n", i, (int)c[], (int)c[]);
fflush(stdout);
} MPI_Finalize();
return ;
}

● 输出结果

D:\Code\MPI\MPIProjectTemp\x64\Debug>mpiexec -n  -l MPIProjectTemp.exe
[]i=, c[] = , c[] =

▶ 函数 MPI_Size(),计算打包所需的缓冲区大小。上面的打包和解包过程中使用的是静态内存空间,对于较为复杂的数据类型,可以用 MPI 内建函数来计算需要的空间大小,防止缓冲区不足或者空间浪费。

● 函数原型

 MPI_METHOD MPI_Pack_size(
_In_range_(>= , ) int incount, // 数据数量
_In_ MPI_Datatype datatype, // 数据类型
_In_ MPI_Comm comm, // 通信子
_mpi_out_(size, MPI_UNDEFINED) int *size// 输出所需尺寸(单位为 Byte)
);

● 使用范例

 {
int size,a[];
char *buffer;
MPI_Datatype col;
MPI_Type_vector(, , , MPI_INT, &col);
MPI_Type_commit(&col); // 声明并提交一个数据类型
MPI_Pack_size(, col, MPI_COMM_WORLD, &size); // 计算打包一个这样的类型需要的空间大小
buffer = (char *)malloc((unsigned)size); // 动态声明一个缓冲区用于打包
MPI_Pack(a, , col, buffer, size, &position, MPI_COMM_WORLD);
}

▶ 函数 MPI_Pack_external(),MPI_Unpack_external(),MPI_Pack_external_size(),与上面的打包、解包、求大小函数类似,将需要打包的数据转换成连续的内存空间进行传递

● 函数原型,相比上面的打包、解包、求空间大小的函数,多了数据描述参数,少了通信子参数

 MPI_METHOD MPI_Pack_external(
_In_z_ const char* datarep, // 数据描述,与保存格式有关,不能随意写
_In_opt_ const void* inbuf,
_In_range_(>= , ) int incount,
_In_ MPI_Datatype datatype,
_mpi_writes_bytes_(outsize) void* outbuf,
_In_range_(>= , ) MPI_Aint outsize,
_mpi_position_(outsize) MPI_Aint* position
); MPI_METHOD MPI_Unpack_external(
_In_z_ const char* datarep,
_In_reads_bytes_opt_(insize) const void* inbuf,
_In_range_(>= , ) MPI_Aint insize,
_mpi_position_(insize) MPI_Aint* position,
_When_(insize > , _Out_opt_) void* outbuf,
_In_range_(>= , ) int outcount,
_In_ MPI_Datatype datatype
); MPI_METHOD MPI_Pack_external_size(
_In_z_ const char* datarep,
_In_range_(>= , ) int incount,
_In_ MPI_Datatype datatype,
_Out_ MPI_Aint* size
);

● 使用范例

 {
int comSize, comRank;
MPI_Aint dataSize, position;
double data[];
char *buf; MPI_Init(&argc, &argv);
MPI_Comm_rank(MPI_COMM_WORLD, &comRank); MPI_Pack_external_size("external32", , MPI_DOUBLE, &dataSize);
buf = (char *)malloc(dataSize); position = ;
if (comRank == )
{
MPI_Pack_external("external32", &data, , MPI_DOUBLE, buf, dataSize, &position);
MPI_Send(buf, position, MPI_PACKED, , , MPI_COMM_WORLD);
}
else
{
MPI_Recv(buf, dataSize, MPI_PACKED, , , MPI_COMM_WORLD, MPI_STATUS_IGNORE);
MPI_Unpack_external("external32", buf, dataSize, &position, &data, , MPI_DOUBLE);
}
MPI_Finalize();
return ;
}

MPI 打包与解包函数 MPI_Pack(),MPI_Unpack()的更多相关文章

  1. lambda表达式,filter,map,reduce,curry,打包与解包和

    当然是函数式那一套黑魔法啦,且听我细细道来. lambda表达式 也就是匿名函数. 用法:lambda 参数列表 : 返回值 例: +1函数 f=lambda x:x+1 max函数(条件语句的写法如 ...

  2. struct:二进制数据结构的打包与解包

    介绍 struct模块包括一些函数,这些函数可以完成字节串与原生Python数据类型(如数字和字符串)之间的转换 函数与Struct类 struct提供了一组处理结构值的模块级函数,另外还有一个Str ...

  3. Lua学习教程之 可变參数数据打包与解包

    利用table的pack与unpack进行数据打包与解包.測试代码例如以下: print("Test table.pack()----------------"); functio ...

  4. web socket RFC6455 frame 打包、解包

    #ifndef __APP_WEBSOCKET_FRAME_H__ #define __APP_WEBSOCKET_FRAME_H__ #include "memory.hpp" ...

  5. dpkg打包与解包

    1.打包 dpkg -b 2.解包 2.1 dpkg -X 解出包内容 2.2 dpkg -e 输出包控制信息

  6. CentOS7 tar打包工具 打包,解包,打包压缩,打包解压缩

    tar命令 選項與參數: -c :建立打包檔案,可搭配 -v 來察看過程中被打包的檔名(filename) -t :察看打包檔案的內容含有哪些檔名,重點在察看『檔名』就是了: -x :解打包或解壓縮的 ...

  7. SummerVocation_Learning--java的自动打包与解包

    Auto Boxing: 自动将基础类型转换成对象(JDK1.5之后支持) Auto UnBoxing:自动将对象转换成基础类型 如 Map中的put方法,如果要传入键值对<a,1>,&l ...

  8. Linux下文件打包与解包

    打包(.tar):  tar -cvf Pro.tar /home/lin/Pro   #将/home/lin/Pro文件夹下的所有文件打包成Pro.tar 打解包(.tar.gz)  tar -cv ...

  9. linux下的打包与解包的简单总结

    .tar 解包:tar xvf FileName.tar 打包:tar cvf FileName.tar DirName (注:tar是打包,不是压缩!) ---------------------- ...

随机推荐

  1. UVA-11613 Acme Corporation (最大费用最大流+拆点)

    题目大意:有一种商品X,其每每单位存放一个月的代价I固定.并且已知其每月的最大生产量.生产每单位的的代价.最大销售量和销售单价,还已知每个月生产的X能最多能存放的时间(以月为单位).问只考虑前m个月, ...

  2. C#中as和is关键字

    一. as 运算符用于在兼容的引用类型之间执行某些类型的转换.例如: static void Main(string[] args) { ]; obj[] = new class1(); obj[] ...

  3. restframework api(基础3CBV)

    一 CBV源码流程 urls.py from django.conf.urls import url from django.contrib import admin from app01 impor ...

  4. 【DEV GridControl】怎样使GridView中满足某个条件的行可编辑,其余行不可编辑?

    DXperience控件包,使用起来非常方便,但有时候某些功能的实现在文档中不太容易找到解决方案,比如下面要提到的这个功能我就在文档中找了很久也没找到,最后还是在官方论坛上找到的. 具体问题是这样的: ...

  5. [批处理]自动修改本机IP地址

    前言 抱着笔记本经常到处跑的人,今天回宿舍上网,明天去机房上网,后面去办公室上网,每到一个地方,都要更换一次IP网关掩码 如果都是DHCP还好,关键是为了组织为了方便管理这些地方都是使用的静态IP,所 ...

  6. Django 之 Ajax

    此次主要是做省市区的三级联动. 环境:django 1.10 1. urls.py # coding:utf-8 from django.conf.urls import url import vie ...

  7. WebGL编程指南案例解析之绘制三个点

    //案例2.绘制3个点,将顶点数据存到缓冲区对象(gl.ARRAY_BUFFER)中,然后顶点着色器从里面读数据(3个顶点) //着色器将对这些顶点进行逐个解析, //第一个顶点给到顶点着色器,赋值给 ...

  8. LambdaMART简介——基于Ranklib源码(二 Regression Tree训练)

    上一节中介绍了 $ \lambda $ 的计算,lambdaMART就以计算的每个doc的 $\lambda$ 值作为label,训练Regression Tree,并在最后对叶子节点上的样本 $la ...

  9. python 类属性初始化

    类的一个属性的多种可能初始化: http://stackoverflow.com/questions/2164258/multiple-constructors-in-python 类多个属性的初始化 ...

  10. HDU1300 Pearls(可斜率优化)

    +)*= +)*= .总共需要的花费是150+=++)*= .在两组数据看来.珍珠都买了高品质的了,而且花费也少了!问题是怎么样能花费最少买珍珠! Add:合并肯定是相邻的合并.比如啊a<b&l ...