MPI发送结构体与字节数组和整数



我想发送图像数据(无符号字符数组),宽度和高度从排名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;
}

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

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

  • 一个具有图像大小,以便接收器可以准备适当大小的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);
    ...
}

相关内容

  • 没有找到相关文章

最新更新