1

我的问题很简单。当使用 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 子数组和一个网格加上一个 shift 来让我的邻居在网格上,但是这段代码已经在一个基本版本中使用了单独的 Send/Recv。唯一的变化是用 MPI_Sendrecv 调用替换 Send/recv 调用以简化代码......所以我认为整个代码都不是必需的。

有任何想法吗 ?

我试过了 :

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

它都不起作用,我仍然在这条线上遇到分段错误。

4

2 回答 2

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;
于 2013-01-02T22:58:17.373 回答
0

事实证明,我摆脱了分段错误。我的问题中写的语法实际上很好, &(submtx[0][0]) 不是问题......也正如这篇文章中指出的那样, submtx[0] 也在工作(MPI_Type_create_subarray 和 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);

虽然我很高兴我的问题终于得到解决,但我真的很想得到这个问题的答案,这意味着“为什么在删除不会有任何用途的分配(或我认为的其他任何东西)时它不起作用??

于 2013-01-03T10:36:19.850 回答