问题
I am trying to implement a MPI of the filter code below, but I'm facing difficulties doing it. How should it be done?:
Filter code:
int A[100000][100000];
int B[100000][100000];
for (int i=1; i<(100000 - 1); i++)
for (int i=1; j<(100000 - 1); j++)
B[i][j] = A[i-1][j] + A[i+1][j] + A[i][j-1] + A[i][j+1] - 4*A[i][j];
This is what I have tried while following the six functions of MPI:
int myrank; /* Rank of process */
int numprocs; /* Number of processes */
int source; /* Rank of sender */
int dest; /* Rank of receiver */
char message[100]; /* Storage for the message */
MPI_Status status; /* Return status for receive */
MPI_Init( & argc, & argv);
MPI_Comm_size(MPI_COMM_WORLD, & numprocs);
MPI_Comm_rank(MPI_COMM_WORLD, & myrank);
if (myrank != 0)
{
dest = 0;
MPI_Send(message, strlen(message) + 1,
MPI_CHAR, dest, 15, MPI_COMM_WORLD);
} else {
for (source = 1; source < numprocs; source++) {
MPI_Recv(message, 100, MPI_CHAR, source,
15, MPI_COMM_WORLD, & status);
}
}
MPI_Finalize();
回答1:
I'd go like this. First of all, I'd have this code
int A[100000][100000];
int B[100000][100000];
replaced with dynamic allocations. You don't need all that memory for each and every process.
Then, I'd send array A to different processes. By rows.
What is the "height" of data frame (number of rows):
delta = (100000 - 2) / (numprocs-1); // we don't count first and last row
reminder = (100000 - 2) % (numprocs-1); // it might be that we need to give
// little bit more to calculate
// to one of the processes
// we are starting from row with idx=1 (second row) and we want to finish when
// we hit last row
if(myrank == 0) {
for( int i=1; i < numprocs; i++ ) {
// +100000 - we need two more rows to calculate data
int how_many_bytes = delta * 100000 + 200000;
if(reminder != 0 && i == (numprocs-1)) {
how_many_bytes += reminder * 100000;
}
MPI_Send(&(A[(i-1)*delta][0]), how_many_bytes, MPI_INT, i, 0,
MPI_COMM_WORLD);
}
} else {
// allocate memory for bytes
int *local_array = NULL;
int how_many_bytes = delta * 100000 + 200000;
if(reminder != 0 && i == (numprocs-1)) {
how_many_bytes += reminder * 100000;
}
local_array = malloc(how_many_bytes * sizeof(int));
MPI_Status status;
MPI_Recv(
local_array,
how_many_bytes,
MPI_INT,
0,
0,
MPI_COMM_WORLD,
&status);
}
// perform calculations for each and every slice
// remembering that we always have on extra row on
// top and one at the bottom
// send data back to master (as above, but vice versa).
来源:https://stackoverflow.com/questions/45677220/how-to-implement-a-mpi-filter-on-c-code