使用具有2D连续数组的MPI_Sendrecv进行分段错误

时间:2013-01-02 21:16:27

标签: c multidimensional-array segmentation-fault mpi

我的问题很简单。使用MPI_Sendrecv时,它会系统地生成段错误。我之前使用2D数组和基本的MPI_Send遇到了同样的问题,但最终解决了它。当我尝试在最后一种情况下工作的相同解决方案时,这并没有改变任何东西。因此,我在寻求帮助!

所以基本上,我通过这段代码分配我的所有矩阵:

    double**
    allocateMatrix(int rows, int cols)
    {
        double **M; // Row pointer
        double *Mdata; // Where data will be actually storde

        M = calloc(rows, sizeof *M);
        Mdata = calloc(rows*cols, sizeof(double));

        int i;
        for (i = 0; i < rows; ++i) 
            M[i] = Mdata+ i*rows;

        return M;
    }

我这样做是因为我读到MPI_Sendrecv不适用于非连续数据......

这是我收到错误的地方:

    double **submtx;
    submtx = allocateMatrix(submtx_dim, submtx_dim);

    /* 
    ...
    */

    MPI_Sendrecv(&(submtx[0][0]), 1, left_col, neighbours[0], LEFT_COL,
                 &tmp_rcol, SUB_MTX_SIZE, MPI_DOUBLE, neighbours[0], RIGHT_COL,
                 my_grid, MPI_STATUS_IGNORE);

我知道测试它的错误来自给MPI_Sendrecv的第一个参数的语法。我使用MPI子阵列和一个网格加一个移位来让我的邻居在网格上,但是这段代码已经使用了发送/接收的基本版本。唯一的变化就是用MPI_Sendrecv调用替换Send / recv调用以简化代码......所以我不认为整个代码是必要的。

有什么想法吗?

我试过了:

    MPI_Sendrecv(&submtx, ...
    MPI_Sendrecv(submtx, ...

没有一个工作,我仍然在这一行得到分段错误。

2 个答案:

答案 0 :(得分:0)

MPI_Sendrecv期望指向数据缓冲区的指针作为第一个参数(void *)

http://www.mcs.anl.gov/research/projects/mpi/www/www3/MPI_Sendrecv.html

所以,试试这个

double* // pointer to double (not pointer to pointer)
    allocateMatrix(int rows, int cols)
    {
        return calloc(rows * cols, sizeof(double));
    }

然后再

double *submtx;
submtx = allocateMatrix(submtx_dim, submtx_dim);

/* 
...
*/

MPI_Sendrecv(submtx,....

我认为评论区域会在矩阵中写入内容......

要访问 r 行和 c 列中的值,请执行此操作

smbmtx[c + r * submtx_dim] = 1.234;

答案 1 :(得分:0)

事实证明,我摆脱了我的分段错误。在我的问题中写的语法实际上是好的,&amp;(submtx [0] [0])不是问题...也正如本文所指出的,submtx [0]也在工作(MPI_Type_create_subarray and MPI_Send

这实际上有点棘手,因为除了我必须在真正的东西之前做一些愚蠢的事情之外,根本没有真正的问题:

没有正常工作的代码:

    MPI_Barrier(my_grid);

    do {

        MPI_Sendrecv(&(submtx[0][0], ...)

        /*
        ...
        */

    } while (cond);

和工作代码:

    MPI_Barrier(my_grid);

    double *stupid_allocation;
    stupid_allocation = calloc(submtx_dim*submtx_dim, sizeof(double));

    do {

        MPI_Sendrecv(&(submtx[0][0]), ...)

        /*
        ...
        */

    } while (cond);

虽然我很高兴我的问题终于得到了解决,但我还是希望得到问题的答案,这意味着&#34;为什么在删除分配时(或者我认为的任何其他内容)它不起作用那不会有任何用处吗?