MPI_Pack:无效的缓冲区指针

时间:2015-10-04 09:27:16

标签: c++ mpi

所以,这是我的任务。我应该在主过程中读取K - 1三元组(K - 是进程数)。三元组由两个整数数字和一个 double 组成。我必须使用 MPI_Pack 和集体操作将此三元组发送到其他进程。但是当使用 MPI_Pack 时,我收到一个错误:无效的缓冲区指针。 这是我的代码:

int flag;
    MPI_Initialized(&flag);
    if (flag == 0)
        return;
    int rank, size;
    MPI_Comm_size(MPI_COMM_WORLD, &size);
    MPI_Comm_rank(MPI_COMM_WORLD, &rank);

    int* intbuf = new int[2];
    double doublebuf;
    byte* rbuf = new byte[(size - 1)*(2 * sizeof(int)+sizeof(double))];
    if (rank == 0) {
        int pos = 0;
        for (int i = 0; i < size - 1; ++i){
            pt >> intbuf[1] >> intbuf[2] >> doublebuf; //pt is from the special library and it's okay
            MPI_Pack(intbuf, 2, MPI_INT, rbuf, sizeof(int)* 2, &pos, MPI_COMM_WORLD);
            MPI_Pack(&doublebuf, 1, MPI_DOUBLE, rbuf, sizeof(double), &pos, MPI_COMM_WORLD);
        }
    }

    MPI_Bcast(rbuf, sizeof(rbuf), MPI_PACKED, 0, MPI_COMM_WORLD);

    if (rank != 0){
        int pos = 0;
        for (int i = 0; i < size - 1; ++i){
            MPI_Unpack(rbuf, sizeof(int)* 2, &pos, intbuf, 2, MPI_INT, MPI_COMM_WORLD);
            MPI_Unpack(rbuf, sizeof(double), &pos, &doublebuf, 1, MPI_DOUBLE, MPI_COMM_WORLD);
            pt << intbuf[1] << intbuf[2] << doublebuf;
        }

    }

我在做什么?

2 个答案:

答案 0 :(得分:3)

主要问题来自这一行:

MPI_Bcast(rbuf, sizeof(rbuf), MPI_PACKED, 0, MPI_COMM_WORLD);

更具体地说,它来自sizeof(rdbuf),应由pos替换。实际上,sizeof(rdbuf)是一个sizeof(byte*),根据您的操作系统可能是4或8,但这与您尝试传输的数据大小无关...这已修复,你的代码可能“有效”。

然而,这仍有很多问题:

  1. 你的包装缓冲区分配了某种任意大小,这没什么意义。通常,要知道打包一些数据需要多少内存,您应该使用MPI_Pack_size()
  2. 为什么你首先要使用MPI_Pack()?此功能是PVM(即并行虚拟机)的一种遗留物,它是消息传递库预先存在的MPI。该功能的目的是简化从PVM到MPI的过渡,但肯定不能用于从头开发。
  3. 为了解决您的问题,我建议您拨打2个不同的MPI_Bcast(),一个使用2个整数,另一个使用双倍。这非常简单明了。

    另一个(更好,如果可伸缩性很重要)可能性是创建一个包含你的int和double的结构,并使用MPI_Type_create_struct()创建匹配的MPI结构类型。

    无论如何,祝你的代码好运。

答案 1 :(得分:0)

所以我只是修复了我的错误。打包数据时发生了错误: MPI_Pack 的第5个分区并不意味着您打包了多少数据,这意味着您的缓冲区大小(在我的情况下,缓冲区是 rbuf < / em>), MPI_Unpack 的第二个参数具有相同的语义。 这是固定代码。它有效。

int* intbuf = new int[2];
    double doublebuf;
    int N = (size - 1)*(2 * sizeof(int)+sizeof(double));
    byte* rbuf = new byte[N];
    int pos = 0;
    if (rank == 0) {
        for (int i = 0; i < size - 1; ++i){
            pt >> intbuf[0] >> intbuf[1] >> doublebuf;
            MPI_Pack(intbuf, 2, MPI_INT, rbuf, N, &pos, MPI_COMM_WORLD);
            MPI_Pack(&doublebuf, 1, MPI_DOUBLE, rbuf, N, &pos, MPI_COMM_WORLD);
        }
    }
    MPI_Bcast(rbuf, N, MPI_PACKED, 0, MPI_COMM_WORLD);

    if (rank != 0){
        int pos = 0;
        for (int i = 0; i < size - 1; ++i){
            int* intbuf_out = new int[2];
            double doublebuf_out;
            MPI_Unpack(rbuf, N, &pos, intbuf_out, 2, MPI_INT, MPI_COMM_WORLD);
            MPI_Unpack(rbuf, N, &pos, &doublebuf_out, 1, MPI_DOUBLE, MPI_COMM_WORLD);
            pt << intbuf_out[0] << intbuf_out[1] << doublebuf_out;
            delete(intbuf_out);
        }

    }