Segmentation Fault using MPI_Sendrecv with a 2D contiguous array

六月ゝ 毕业季﹏ 提交于 2021-01-28 12:23:12

问题


my problem is quite simple. When using MPI_Sendrecv, its generates systematically a segfault. I had the same problem earlier with the use of 2D array and a basic MPI_Send but finally solved it. As I tried the same solution that work in the last case, this did not change anything. Thus I'm asking help !

So basically, I allocate all my matrix by this code :

    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;
    }

I did it because I read that MPI_Sendrecv should not work with non contiguous data...

Here is where I get my error:

    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);

I know for having it tested that the error is from the syntax of the first argument given to MPI_Sendrecv. I use MPI subarray and a grid plus a shift to get my neighbours on the grid, but this code has been already working with a basic version using Send/Recv separately. The only change in it has been the replacement of Send/recv calls by MPI_Sendrecv calls in order to simplify the code ... so I don't think the whole code should be necessary.

Any ideas ?

I tried :

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

None of it worked and I still get a segmentation fault at this line.


回答1:


MPI_Sendrecv expects a pointer to a buffer of data as first parameter (void *)

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

so, try this

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

then later

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

/* 
...
*/

MPI_Sendrecv(submtx,....

I suppose the commented area writes something into the matrix...

To access the value in the row r and column c do this

smbmtx[c + r * submtx_dim] = 1.234;



回答2:


As it turns out, I got rid of my segmentation fault. The syntax written in my question was actually good, &(submtx[0][0]) was not the problem... also as pointed out in this post, submtx[0] is also working (MPI_Type_create_subarray and MPI_Send).

This is actually a bit tricky, because there is no real problem at all except that I have to do some stupid stuff before the real one :

not working code:

    MPI_Barrier(my_grid);

    do {

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

        /*
        ...
        */

    } while (cond);

and working code:

    MPI_Barrier(my_grid);

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

    do {

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

        /*
        ...
        */

    } while (cond);

While I'm happy my problem is finally fixed, I would really like to get an answer to the problem anyway, meaning "why does it not work when removing an allocation (or anything else I presume) that won't be of any use ??



来源:https://stackoverflow.com/questions/14129297/segmentation-fault-using-mpi-sendrecv-with-a-2d-contiguous-array

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!