diff --git a/mpi_line/Makefile b/mpi_line/Makefile index 7045d0a..98d68f4 100644 --- a/mpi_line/Makefile +++ b/mpi_line/Makefile @@ -1,12 +1,15 @@ CC=mpicc CFLAGS=-Wall -lm -std=c99 -all: config jacobi_mpi_line.c - ${CC} ${CFLAGS} config.o jacobi_mpi_line.c -o jacobi.out +all: config utils jacobi_mpi_line.c + ${CC} ${CFLAGS} config.o utils.o jacobi_mpi_line.c -o jacobi.out config: ../config/config.c ${CC} -c ${CFLAGS} ../config/config.c +utils: ../utils/utils.c + ${CC} -c ${CFLAGS} ../utils/utils.c + .PHONY: clean clean: rm -f *.out *.o diff --git a/mpi_line/jacobi.conf b/mpi_line/jacobi.conf index 79b1a6b..f1121d4 100644 --- a/mpi_line/jacobi.conf +++ b/mpi_line/jacobi.conf @@ -1,7 +1,7 @@ # Configuration file for the Jacobi project. # The size of the matrix (borders excluded). -N 4 +N 5000 # The value at each border. NORTH 0.0 diff --git a/mpi_line/jacobi_mpi_line.c b/mpi_line/jacobi_mpi_line.c index 43e99ea..85e4651 100644 --- a/mpi_line/jacobi_mpi_line.c +++ b/mpi_line/jacobi_mpi_line.c @@ -6,18 +6,11 @@ #include #include #include "../config/config.h" +#include "../utils/utils.h" #define TAG_BORDER 0 -typedef struct borders { - double north; - double east; - double south; - double west; -} borders; - void compute_jacobi(int n, double init_value, double threshold, borders b); -void print_matrix(int rows, int cols, double x[rows][cols]); int main(int argc, char* argv[]) { int rank, numprocs; @@ -65,13 +58,22 @@ int main(int argc, char* argv[]) { } else { rows = n / numprocs; } + LOG(printf("[Process %d/%d] rows: %d\n", rank, numprocs, rows)); - double x[rows + 2][n + 2]; + double **x; double max_diff, global_max_diff, new_x; - int i, j; + int i, j, iterations; MPI_Status status; + double startwtime = 0.0, endwtime; + if (rank == 0) { + startwtime = MPI_Wtime(); + } + + /* 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++) { for (j = 1; j <= n; j++) { x[i][j] = init_value; @@ -86,12 +88,15 @@ int main(int argc, char* argv[]) { for (i = 1; i <= n + 1; i++) { x[0][i] = b.north; } - } else if (rank == numprocs - 1){ + } + if (rank == numprocs - 1){ for (i = 1; i < n + 1; i++) { 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; do { max_diff = 0; global_max_diff = 0; @@ -123,21 +128,19 @@ int main(int argc, char* argv[]) { 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++; } 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; } - -void print_matrix(int rows, int cols, double x[rows][cols]) { - int i, j; - for (i = 0; i < rows; i++) { - for (j = 0; j < cols; j++) { - printf("%f\t", x[i][j]); - } - printf("\n"); - } - fflush(stdout); -} diff --git a/sequential/Makefile b/sequential/Makefile index aacf23e..acdc915 100644 --- a/sequential/Makefile +++ b/sequential/Makefile @@ -1,12 +1,15 @@ -CC=gcc +CC=mpicc CFLAGS=-Wall -lm -std=c99 -all: config jacobi_sequential.c - ${CC} ${CFLAGS} config.o jacobi_sequential.c -o jacobi.out +all: config utils jacobi_sequential.c + ${CC} ${CFLAGS} config.o utils.o jacobi_sequential.c -o jacobi.out config: ../config/config.c ${CC} -c ${CFLAGS} ../config/config.c +utils: ../utils/utils.c + ${CC} -c ${CFLAGS} ../utils/utils.c + .PHONY: clean clean: rm -f *.out *.o diff --git a/sequential/jacobi.conf b/sequential/jacobi.conf index 95ce868..f1121d4 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 10 +N 5000 # The value at each border. NORTH 0.0 diff --git a/sequential/jacobi_sequential.c b/sequential/jacobi_sequential.c index 6061dce..3111199 100644 --- a/sequential/jacobi_sequential.c +++ b/sequential/jacobi_sequential.c @@ -5,21 +5,25 @@ #include #include +#include #include "../config/config.h" - -typedef struct borders { - double north; - double east; - double south; - double west; -} borders; +#include "../utils/utils.h" void compute_jacobi(int n, double init_value, double threshold, borders b); int main(int argc, char* argv[]) { + int numprocs; int config_loaded; configuration config; borders b; + double startwtime = 0.0, endwtime; + + MPI_Init(&argc, &argv); + MPI_Comm_size(MPI_COMM_WORLD, &numprocs); + + if (numprocs != 1) { + MPI_Abort(MPI_COMM_WORLD, 1); + } config_loaded = load_config(&config); if (config_loaded != 0) { @@ -31,17 +35,24 @@ int main(int argc, char* argv[]) { b.south = config.south; b.west = config.west; + startwtime = MPI_Wtime(); compute_jacobi(config.n, config.init_value, config.threshold, b); + endwtime = MPI_Wtime(); + printf("Wall clock time: %fs\n", endwtime - startwtime); + + MPI_Finalize(); + return 0; } void compute_jacobi(int n, double init_value, double threshold, borders b) { - double x[n + 2][n + 2]; + double **x; double max_diff, new_x; int i, j; /* Initialize boundary regions */ + x = create_matrix(n + 2, n + 2); for (i = 1; i <= n; i++) { x[0][i] = b.north; x[n + 1][i] = b.south; @@ -65,4 +76,6 @@ void compute_jacobi(int n, double init_value, double threshold, borders b) { } } } while (max_diff > threshold); + + destroy_matrix(x, n + 2); } diff --git a/utils/utils.c b/utils/utils.c new file mode 100644 index 0000000..5891256 --- /dev/null +++ b/utils/utils.c @@ -0,0 +1,34 @@ +#include +#include + + +double **create_matrix(int rows, int cols) { + int i; + double **x; + + x = (double **) malloc(rows * sizeof(double)); + for (i = 0; i < rows; i++) { + x[i] = (double *) malloc(cols * sizeof(double)); + } + return x; +} + +void destroy_matrix(double **x, int rows) { + int i; + + for (i = 0; i < rows; i++) { + free(x[i]); + } + free(x); +} + +void print_matrix(double **x, int rows, int cols) { + int i, j; + for (i = 0; i < rows; i++) { + for (j = 0; j < cols; j++) { + printf("%f\t", x[i][j]); + } + printf("\n"); + } + fflush(stdout); +} diff --git a/utils/utils.h b/utils/utils.h new file mode 100644 index 0000000..d6c875a --- /dev/null +++ b/utils/utils.h @@ -0,0 +1,22 @@ +#include +#include + +/* #define ENABLE_LOG */ + +#ifdef ENABLE_LOG +# define LOG(x) x +#else +# define LOG(x) (void) 0 +#endif + +typedef struct borders { + double north; + double east; + double south; + double west; +} borders; + +double **create_matrix(int rows, int cols); + +void print_matrix(double **x, int rows, int cols); +void destroy_matrix(double **x, int rows);