c - MPI Scatter/Gather scope of variables -
i'm dealing mpi version of bml automaton mpi_scatter() won't work expected. read here collective communication functions every process needs copy of array, allocated space without initialization. in code there subgrid local_grid
every process manipulates, , starting big grid
root manipulate. mean use scatter-gather communication mpi datatype. allocate space grid , sub-grid every one, , initialize grid root. wrong?
unsigned char*** local_grid; unsigned char** grid; mpi_status stat; mpi_datatype rowtype; mpi_init(&argc, &argv); mpi_comm_rank(mpi_comm_world, &rank); mpi_comm_size(mpi_comm_world, &nproc); local_n = n / nproc; mpi_type_contiguous(n + 2, /* count */ mpi_unsigned_char, /* oldtype */ &rowtype /* newtype */ ); mpi_type_commit(&rowtype); /* allocate space 3d local grids*/ local_grid = (unsigned char***)malloc(2 * sizeof(unsigned char**)); for(i = 0; < 2; i++) { local_grid[i] = (unsigned char**)malloc((local_n + 2) * sizeof(unsigned char*)); for(j = 0; j < local_n + 2; j++) { local_grid[i][j] = (unsigned char*)malloc((n + 2) * sizeof(unsigned char)); } } /* initialize local grids*/ for(i = 0; < local_n + 2; i++) { for(j = 0; j < n + 2; j++) { local_grid[0][i][j] = 0; local_grid[1][i][j] = 0; } } /* allocate 2d starting grid */ grid = (unsigned char**)malloc(n * sizeof(unsigned char*)); for(i = 0; < n + 2; i++) { grid[i] = (unsigned char*)malloc((n + 2) * sizeof(unsigned char)); } /* root */ if(rank == 0) { /* initialize 2d starting grid */ for(i = 0; < n; i++) { for(j = 0; j < n + 2; j++) { grid[i][j] = (((float)rand())/rand_max) > rho ? 0 : rand()%2 + 1; grid[i][0] = grid[i][n+1] = 0; printf("%2d ", grid[i][j]); } printf("\n"); } } /* */ mpi_scatter(grid[0], local_n, rowtype, local_grid[cur][1], local_n, rowtype, source, mpi_comm_world); ...
program terminates correctly, 1 single rowtype row passed scatter() root process, nothing other process despite of number.
an issue comes way declare/allocate 2d arrays.
you declared 2d arrays arrays of pointers arrays (e.g. matrix rows), mpi expects contiguous layout.
for example, can replace
grid = (unsigned char**)malloc(n * sizeof(unsigned char*)); for(i = 0; < n; i++) { grid[i] = (unsigned char*)malloc((n + 2) * sizeof(unsigned char)); }
with
grid = (unsigned char**)malloc(n * sizeof(unsigned char*)); grid[0] = (unsigned char*)malloc(n*(n+2)*sizeof(unsigned char)); for(i = 1; < n; i++) { grid[i] = grid[i-1] + n + 2; }
and use grid[0]
buffer argument mpi_scatter()
or mpi_gather()
same thing must applied local_grid[0]
, local_grid[1]
when need free grid, can simply
free(grid[0]); free(grid);
note not think program can work correctly if n
not multiple of nproc
wiki
Comments
Post a Comment