问题
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