I have written a program for the famous game of life problem. The program is running perfectly for the sequential version. Now I am trying to implement it in parallel with MPI.
I am just sending the main function where I am calling two functions. Calculate is updating the array after the calculation on each and every cell and init is just assigning some values to the elements of the array. allocarray is allocating the arrays.
int main(int argc, char *argv[]) {
int generation = 0;
int i, myN, above =0, below=0 ,startrow, endrow, *counts, *offset;
double starttime, time;
int height,width;
//int flag = 0;
int **array1, **array2, **myarray=NULL;
int rank, size;
MPI_Status status;
MPI_Init(&argc, &argv);
MPI_Comm_rank(MPI_COMM_WORLD, &rank);
MPI_Comm_size(MPI_COMM_WORLD, &size);
if (argc!=3) {
printf("You need to enter the size of the matrix and the number of generations in the comment line argument\n");
MPI_Abort(MPI_COMM_WORLD,-1);
}
height = atoi(argv[1])+2;
width = height;
//allocate required arrays in all processes
counts = (int *)malloc(sizeof(int)*size);
offset = (int *)malloc(sizeof(int)*size);
// compute counts and offsets for the scatter operation
for (i=0; i<size; i++)
counts[i] = height/size + ((i<height%size)?1:0);
for (offset[0]=0, i=1; i<size; i++)
offset[i] = offset[i-1] + counts[i-1];
myN = counts[rank]; // obtain count for current process
if (rank == 0) { // allocate and initialize vector in master process
array1=allocarray(height,width);
initarray(array1,height,width);
}
// allocate receive buffer in all processes
myarray = allocarray(myN,width);
array2 = allocarray(myN,width);
// distribute data equally among other processes
MPI_Scatterv(array1, counts, offset, MPI_INT, myarray, myN, MPI_INT, 0, MPI_COMM_WORLD);
printf("My rank is %d, size is %d, myN is %d\n", rank, size, myN);
fflush(stdout);
MPI_Barrier(MPI_COMM_WORLD);
starttime = MPI_Wtime();
for (rank=1; rank<=size;rank++)
{
if (rank > 1)
above = (rank-2)%size + 1;
if (rank < size)
below = rank%size + 1;
startrow = (rank-1)*size +1;
endrow = startrow + size -1;
if (below != 0)
MPI_Send(&array1[0][endrow], width, MPI_INT, below, 0, MPI_COMM_WORLD);
if (above != 0)
MPI_Send(&array1[0][startrow], width, MPI_INT, above, 0, MPI_COMM_WORLD);
if (above != 0)
MPI_Recv(&myarray[0][0], width, MPI_INT, above, 0, MPI_COMM_WORLD, &status);
if (below != 0)
MPI_Recv(&myarray[0][endrow+1], width, MPI_INT, below, 0, MPI_COMM_WORLD, &status);
calculate(myarray, array2, myN, width);
}
MPI_Gatherv(array2, myN, MPI_INT, array1, counts, offset, MPI_INT, 0, MPI_COMM_WORLD);
//temparray = array1;
//array1 = array2;
//array2 = temparray;
printTable(array1, height, width);
time= MPI_Wtime()-starttime;
printf("Time taken= %f\n", time);
MPI_Finalize();
return 0;
}