diff --git a/mpi_line/jacobi_mpi_line.c b/mpi_line/jacobi_mpi_line.c index 85e4651..9bc0984 100644 --- a/mpi_line/jacobi_mpi_line.c +++ b/mpi_line/jacobi_mpi_line.c @@ -10,16 +10,22 @@ #define TAG_BORDER 0 -void compute_jacobi(int n, double init_value, double threshold, borders b); +double **compute_jacobi(int n, double init_value, double threshold, borders b, int *rows, int *iterations); + +int rank; +int numprocs; int main(int argc, char* argv[]) { - int rank, numprocs; int n; double init_value, threshold; double north, south, east, west; borders b; int config_loaded; configuration config; + double **x; + double startwtime = 0.0, endwtime; + int iterations; + int rows; MPI_Init(&argc, &argv); @@ -51,36 +57,48 @@ int main(int argc, char* argv[]) { b.south = south; b.east = east; b.west = west; - - int rows; - if (rank == 0) { - rows = n - (n / numprocs) * (numprocs - 1); - } else { - rows = n / numprocs; - } - LOG(printf("[Process %d/%d] rows: %d\n", rank, numprocs, rows)); - - double **x; - double max_diff, global_max_diff, new_x; - int i, j, iterations; - MPI_Status status; - double startwtime = 0.0, endwtime; if (rank == 0) { startwtime = MPI_Wtime(); } + + x = compute_jacobi(n, init_value, threshold, b, &rows, &iterations); + if (rank == 0) { + endwtime = MPI_Wtime(); + printf("Wall clock time: %fs\n", endwtime - startwtime); + printf("Iterations: %d\n", iterations); + } + + destroy_matrix(x, rows); + + MPI_Finalize(); + + return 0; +} + +double **compute_jacobi(int n, double init_value, double threshold, borders b, int *rows, int *iterations) { + double **x; + double max_diff, global_max_diff, new_x; + int i, j; + MPI_Status status; + + if (rank == 0) { + *rows = n - (n / numprocs) * (numprocs - 1); + } else { + *rows = n / numprocs; + } + LOG(printf("[Process %d/%d] rows: %d\n", rank, numprocs, *rows)); /* LOG(printf("[Process %d/%d] initializing matrix\n", rank, numprocs)); */ - /* Initialize the matrix */ - x = create_matrix(rows + 2, n + 2); - for (i = 0; i < rows + 2; i++) { + x = create_matrix(*rows + 2, n + 2); + for (i = 0; i < *rows + 2; i++) { for (j = 1; j <= n; j++) { x[i][j] = init_value; } } /* Initialize boundary regions */ - for (i = 0; i < rows + 2; i++) { + for (i = 0; i < *rows + 2; i++) { x[i][0] = b.west; x[i][n + 1] = b.east; } @@ -91,16 +109,16 @@ int main(int argc, char* argv[]) { } if (rank == numprocs - 1){ for (i = 1; i < n + 1; i++) { - x[rows + 1][i] = b.south; + x[*rows + 1][i] = b.south; } } /* LOG(printf("[Process %d/%d] matrix initialized\n", rank, numprocs)); */ /* Iterative refinement of x until values converge */ - iterations = 0; + *iterations = 0; do { max_diff = 0; global_max_diff = 0; - for (i = 1; i <= rows; i++) { + for (i = 1; i <= *rows; i++) { for (j = 1; j <= n; j++) { new_x = 0.25 * (x[i - 1][j] + x[i][j + 1] + x[i + 1][j] + x[i][j - 1]); max_diff = (double) fmax(max_diff, fabs(new_x - x[i][j])); @@ -110,8 +128,8 @@ int main(int argc, char* argv[]) { if (rank % 2 == 0) { if (rank != numprocs - 1) { // Send and receive south border - MPI_Send(&x[rows][0], n + 2, MPI_DOUBLE, rank + 1, TAG_BORDER, MPI_COMM_WORLD); - MPI_Recv(&x[rows + 1][0], n + 2, MPI_DOUBLE, rank + 1, TAG_BORDER, MPI_COMM_WORLD, &status); + MPI_Send(&x[*rows][0], n + 2, MPI_DOUBLE, rank + 1, TAG_BORDER, MPI_COMM_WORLD); + MPI_Recv(&x[*rows + 1][0], n + 2, MPI_DOUBLE, rank + 1, TAG_BORDER, MPI_COMM_WORLD, &status); } if (rank != 0) { // Send and receive north border @@ -124,23 +142,14 @@ int main(int argc, char* argv[]) { MPI_Send(&x[1][0], n + 2, MPI_DOUBLE, rank - 1, TAG_BORDER, MPI_COMM_WORLD); if (rank != numprocs - 1) { // Receive and send south border - MPI_Recv(&x[rows + 1][0], n + 2, MPI_DOUBLE, rank + 1, TAG_BORDER, MPI_COMM_WORLD, &status); - MPI_Send(&x[rows][0], n + 2, MPI_DOUBLE, rank + 1, TAG_BORDER, MPI_COMM_WORLD); + MPI_Recv(&x[*rows + 1][0], n + 2, MPI_DOUBLE, rank + 1, TAG_BORDER, MPI_COMM_WORLD, &status); + MPI_Send(&x[*rows][0], n + 2, MPI_DOUBLE, rank + 1, TAG_BORDER, MPI_COMM_WORLD); } } /* LOG(printf("[Process %d/%d] max_diff: %f\n", rank, numprocs, max_diff)); */ MPI_Allreduce(&max_diff, &global_max_diff, 1, MPI_DOUBLE, MPI_MAX, MPI_COMM_WORLD); /* LOG(printf("[Process %d/%d] global_max_diff: %f\n", rank, numprocs, global_max_diff)); */ - iterations++; + (*iterations)++; } while (global_max_diff > threshold); - - if (rank == 0) { - endwtime = MPI_Wtime(); - printf("Wall clock time: %fs\n", endwtime - startwtime); - printf("Iterations: %d\n", iterations); - } - - MPI_Finalize(); - - return 0; + return x; } diff --git a/sequential/jacobi.conf b/sequential/jacobi.conf index f1121d4..ce8b562 100644 --- a/sequential/jacobi.conf +++ b/sequential/jacobi.conf @@ -1,7 +1,7 @@ # Configuration file for the Jacobi project. # The size of the matrix (borders excluded). -N 5000 +N 3000 # The value at each border. NORTH 0.0 diff --git a/sequential/jacobi_sequential.c b/sequential/jacobi_sequential.c index 3111199..1c9c95d 100644 --- a/sequential/jacobi_sequential.c +++ b/sequential/jacobi_sequential.c @@ -9,7 +9,7 @@ #include "../config/config.h" #include "../utils/utils.h" -void compute_jacobi(int n, double init_value, double threshold, borders b); +double **compute_jacobi(int n, double init_value, double threshold, borders b); int main(int argc, char* argv[]) { int numprocs; @@ -17,6 +17,7 @@ int main(int argc, char* argv[]) { configuration config; borders b; double startwtime = 0.0, endwtime; + double **x; MPI_Init(&argc, &argv); MPI_Comm_size(MPI_COMM_WORLD, &numprocs); @@ -36,17 +37,18 @@ int main(int argc, char* argv[]) { b.west = config.west; startwtime = MPI_Wtime(); - compute_jacobi(config.n, config.init_value, config.threshold, b); + x = compute_jacobi(config.n, config.init_value, config.threshold, b); endwtime = MPI_Wtime(); printf("Wall clock time: %fs\n", endwtime - startwtime); + destroy_matrix(x, config.n + 2); MPI_Finalize(); return 0; } -void compute_jacobi(int n, double init_value, double threshold, borders b) { +double **compute_jacobi(int n, double init_value, double threshold, borders b) { double **x; double max_diff, new_x; int i, j; @@ -76,6 +78,5 @@ void compute_jacobi(int n, double init_value, double threshold, borders b) { } } } while (max_diff > threshold); - - destroy_matrix(x, n + 2); + return x; }