2009年5月5日星期二

用MPI_Pack()打包C语言的结构以实现异构非连续数据的传递(MPI_Send())

http://docs.huihoo.com/npact/3.htm

C 结构

考虑一个图像的应用,它传送8位彩色象素的固定长度扫描线。与象素矩阵一起是扫描线数,一个整数。可以在C中将消息描述成一个结构:

    struct {         int             lineno;         char            pixels[1024];     } scanline; 

除了导出类型,对于发送不连续和/或者异构数据消息打包是一个有用的方法。下面列出包装和发送上面结构的代码段:

#include <mpi.h>  {     unsigned int        membersize, maxsize;     int                 position;     int                 dest, tag;     char                *buffer; /*  * Do this once.  */     MPI_Pack_size(1,            /* 一个元素 */             MPI_INT,            /* 数据类型是整数 */             MPI_COMM_WORLD,     /* 一致的 comm. */             &membersize);       /* 最大包装空间 req'd */      maxsize = membersize;     MPI_Pack_size(1024, MPI_CHAR, MPI_COMM_WORLD, &membersize);     maxsize += membersize;     buffer = malloc(maxsize); /*  * 为每一新消息做此。  */     position = 0;      MPI_Pack(&scanline.lineno,  /* 包装此元素 */             1,                  /* 一个元素 */             MPI_INT,            /* 数据类型 int */             buffer,             /* 打包缓冲区 */             maxsize,            /* 缓冲区大小 */             &position,          /* 下一可用字节的偏移 */             MPI_COMM_WORLD);    /* 一致的 comm. */      MPI_Pack(scanline.pixels, 1024, MPI_CHAR,             buffer, maxsize, &position, MPI_COMM_WORLD);      MPI_Send(buffer, position, MPI_PACKED,             dest, tag, MPI_COMM_WORLD); } 

缓冲区分配一次以包含所打包的结构的大小。由于在消息中依赖于实现的开销,必须计算大小。变长的消息可以通过分配能容纳最大可能的消息的缓冲区来处理。对于MPI_Pack( )的位置参数总是返回当前包装缓冲区的大小。

下面列出解包消息的代码段,假设已分配接受缓冲区。

{     int             src;     int             msgsize;     MPI_Status      status;      MPI_Recv(buffer, maxsize, MPI_PACKED,             src, tag, MPI_COMM_WORLD, &status);      position = 0;     MPI_Get_count(&status, MPI_PACKED, &msgsize);      MPI_Unpack(buffer,          /* 打包缓冲区 */             msgsize,            /* 缓冲区大小 */             &position,          /* 下一元素的字节偏移 */             &scanline.lineno,   /* 解包这个元素 */             1,                  /* 一个元素 */             MPI_INT,            /* 数据类型 int */             MPI_COMM_WORLD);    /* 一致的 comm. */      MPI_Unpack(buffer, msgsize, &position,             scanline.pixels, 1024, MPI_CHAR, MPI_COMM_WORLD); } 

你应该能修改上面的代码以适应任意的结构。完全可能改变要解包元素的个数,这基于同一消息中前面解包的应用信息。


--
snigoal,HUST,Wuhan,China

没有评论:

发表评论

VISIT COUNT