2009年5月6日星期三

用MPI_Pack()打包C语言的struct


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

没有评论:

发表评论