MPI 发送带有字节数组和整数的结构

Posted

技术标签:

【中文标题】MPI 发送带有字节数组和整数的结构【英文标题】:MPI send struct with bytes array and integers 【发布时间】:2015-08-20 02:45:26 【问题描述】:

我想将图像数据(无符号字符数组)、宽度和高度从 0 级发送到 1 级。最好的方法是什么?我已经读过要在 MPI 中发送复杂的数据结构,我们可以使用打包数据或创建自己的数据类型。在我的情况下什么更好?

我试图通过创建一个新的数据类型来做到这一点。但我错了:Segmentation fault (signal 11)。当我从我的结构中删除数组时,它是有效的。那么发送这个数组有什么问题呢?

我的结构:

typedef struct MyImage 
    int w;
    int h;
    unsigned char *data;
 image;

主要:

int main(int argc, char **argv) 

    int size, rank;
    MPI_Init(&argc, &argv);
    MPI_Comm_size(MPI_COMM_WORLD, &size);

    int blocksCount = 3;
    int blocksLength[3] = 1, 1, 512 * 512 * 3;

    //   I also tried MPI_BYTE
    MPI_Datatype types[3] = MPI_INT, MPI_INT, MPI_UNSIGNED_CHAR;
    MPI_Aint offsets[3];
    MPI_Datatype custom_type;
    offsets[0] = offsetof(image, w);
    offsets[1] = offsetof(image, h);
    offsets[3] = offsetof(image, data);

    MPI_Type_create_struct(blocksCount, blocksLength, offsets, types, &custom_type);
    MPI_Type_commit(&custom_type);

    MPI_Comm_rank(MPI_COMM_WORLD, &rank);
    if (rank == 0) 

    Mat mat = imread("/home/user/image.jpg", CV_LOAD_IMAGE_COLOR);
        image send;
        send.w = mat.size().width;
        send.h = mat.size().height;
        send.data = mat.data;
        MPI_Send(&send, 1, custom_type, 1, 0, MPI_COMM_WORLD);
    
    if (rank == 1) 
        image recv;
        MPI_Status status;
        MPI_Recv(&recv, 1, custom_type, 0, MPI_ANY_TAG, MPI_COMM_WORLD, &status);
    
    MPI_Type_free(&custom_type);
    MPI_Finalize();

    return 0;

【问题讨论】:

是不是多了一个MPI_INT,这里是MPI_Datatype types[3] = MPI_INT, MPI_INT, MPI_INT, MPI_UNSIGNED_CHAR; @gurka,谢谢我编辑了这个。但这没问题。只是我创建此示例时的错误。 【参考方案1】:

发送方出现段错误是因为您试图从Mat.data 指针本身的位置开始发送数据,而不是从它指向的内存位置开始发送数据。接收器出现段错误,因为没有空间来存储 768 KiB 的数据(如果有任何数据到达)。

您可以先打包数据,但这需要额外的缓冲区。您最好的选择是简单地发送两条消息:

与图像大小的一个,以便接收者可以准备一个适当大小的Mat 对象; 图像数据本身。

有时发送两条消息比将所有消息都打包成一条更好。

typedef struct MyImage 
   int w;
   int h;
 image;

int blocksCount = 2;
int blocksLength[2] = 1, 1;

MPI_Datatype types[2] = MPI_INT, MPI_INT;
MPI_Aint offsets[2];
MPI_Datatype custom_type;
offsets[0] = offsetof(image, w);
offsets[1] = offsetof(image, h);

MPI_Type_create_struct(blocksCount, blocksLength, offsets, types, &custom_type);
MPI_Type_commit(&custom_type);

if (rank == 0) 
    Mat mat = imread("/home/user/image.jpg", CV_LOAD_IMAGE_COLOR);
    image send;
    send.w = mat.size().width;
    send.h = mat.size().height;
    // Send image dimensions
    MPI_Send(&send, 1, custom_type, 1, 0, MPI_COMM_WORLD);
    // Send image data
    MPI_Send(mat.data, send.w*send.h*3, MPI_UNSIGNED_CHAR, 1, 0, MPI_COMM_WORLD);

if (rank == 1) 
    image recv;
    MPI_Status status;
    // Receive image dimensions
    MPI_Recv(&recv, 1, custom_type, 0, 0, MPI_COMM_WORLD, &status);
    // Allocate image matrix
    Mat mat(Size(recv.w, recv.h), CV_8UC3);
    // Receive image data
    MPI_Recv(mat.data, recv.w*recv.h*3, MPI_UNSIGNED_CHAR, 0, 0, MPI_COMM_WORLD, &status);
    ...

【讨论】:

非常感谢,这正是我想要的。 MPI_Send 只是 1 个 custom_type 不是很贵吗? @KcFnMi,这取决于。在这种特殊情况下,发送所需时间只是传输图像所需时间的一小部分,因此不会那么昂贵。

以上是关于MPI 发送带有字节数组和整数的结构的主要内容,如果未能解决你的问题,请参考以下文章

C-MPI 发送创建的带有字符数组的 typedef 结构

如何使用 MPI 传输带有动态数组的自定义结构?

在C#中获取整数的上下字节并将其作为char数组发送到com端口,如何?

如何将带有字节数组的 json 发送到 web api / postman

如何将带有图像的字节数组从 AS3 发送到 PHP?

Boost Beast 将带有字节数组的 json 发送到客户端抛出 websocket