From 2111bfbadf8f33de027efb1d0fa1e0ae4e5b18e4 Mon Sep 17 00:00:00 2001 From: Fabio Salvini Date: Sat, 12 Nov 2016 18:01:00 +0100 Subject: [PATCH] mpi line with fixed n and p --- mpi_line/Makefile | 12 ++++ mpi_line/jacobi.conf | 16 +++++ mpi_line/jacobi_mpi_line.c | 133 +++++++++++++++++++++++++++++++++++++ 3 files changed, 161 insertions(+) create mode 100644 mpi_line/Makefile create mode 100644 mpi_line/jacobi.conf create mode 100644 mpi_line/jacobi_mpi_line.c diff --git a/mpi_line/Makefile b/mpi_line/Makefile new file mode 100644 index 0000000..7045d0a --- /dev/null +++ b/mpi_line/Makefile @@ -0,0 +1,12 @@ +CC=mpicc +CFLAGS=-Wall -lm -std=c99 + +all: config jacobi_mpi_line.c + ${CC} ${CFLAGS} config.o jacobi_mpi_line.c -o jacobi.out + +config: ../config/config.c + ${CC} -c ${CFLAGS} ../config/config.c + +.PHONY: clean +clean: + rm -f *.out *.o diff --git a/mpi_line/jacobi.conf b/mpi_line/jacobi.conf new file mode 100644 index 0000000..79b1a6b --- /dev/null +++ b/mpi_line/jacobi.conf @@ -0,0 +1,16 @@ +# Configuration file for the Jacobi project. + +# The size of the matrix (borders excluded). +N 4 + +# The value at each border. +NORTH 0.0 +EAST 0.0 +SOUTH 300.0 +WEST 0.0 + +# The initial value to assign at each internal cell. +INIT_VALUE 0.0 + +# The threshold that determines the convergence. +THRESHOLD 1.0 diff --git a/mpi_line/jacobi_mpi_line.c b/mpi_line/jacobi_mpi_line.c new file mode 100644 index 0000000..ad90922 --- /dev/null +++ b/mpi_line/jacobi_mpi_line.c @@ -0,0 +1,133 @@ +/* + * MPI version with the matrix subdivided by "lines". + */ + +#include +#include +#include +#include "../config/config.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; + int n; + double init_value, threshold; + double north, south, east, west; + borders b; + int config_loaded; + configuration config; + + MPI_Init(&argc, &argv); + + MPI_Comm_rank(MPI_COMM_WORLD, &rank); + MPI_Comm_size(MPI_COMM_WORLD, &numprocs); + + if (numprocs != 2) { + MPI_Abort(MPI_COMM_WORLD, 1); + } + + if (rank == 0) { + config_loaded = load_config(&config); + if (config_loaded != 0) { + MPI_Abort(MPI_COMM_WORLD, 1); + } + n = config.n; + threshold = config.threshold; + init_value = config.init_value; + north = config.north; + south = config.south; + east = config.east; + west = config.west; + } + MPI_Bcast(&n, 1, MPI_INT, 0, MPI_COMM_WORLD); + MPI_Bcast(&init_value, 1, MPI_DOUBLE, 0, MPI_COMM_WORLD); + MPI_Bcast(&threshold, 1, MPI_DOUBLE, 0, MPI_COMM_WORLD); + MPI_Bcast(&north, 1, MPI_DOUBLE, 0, MPI_COMM_WORLD); + MPI_Bcast(&south, 1, MPI_DOUBLE, 0, MPI_COMM_WORLD); + MPI_Bcast(&east, 1, MPI_DOUBLE, 0, MPI_COMM_WORLD); + MPI_Bcast(&west, 1, MPI_DOUBLE, 0, MPI_COMM_WORLD); + + b.north = north; + b.south = south; + b.east = east; + b.west = west; + + if (n != 4) { + MPI_Abort(MPI_COMM_WORLD, 1); + } + + int rows = 2; + double x[rows + 2][n + 2]; + double max_diff, global_max_diff, new_x; + int i, j; + MPI_Status status; + + /* Initialize the matrix */ + 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++) { + x[i][0] = b.west; + x[i][n + 1] = b.east; + } + if (rank == 0) { + for (i = 1; i <= n + 1; i++) { + x[0][i] = b.north; + } + } else if (rank == 1){ + for (i = 1; i < n + 1; i++) { + x[rows + 1][i] = b.south; + } + } + /* Iterative refinement of x until values converge */ + do { + max_diff = 0; + global_max_diff = 0; + 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])); + x[i][j] = new_x; + } + } + if (rank == 0) { + MPI_Send(&x[rows][0], n + 2, MPI_DOUBLE, 1, TAG_BORDER, MPI_COMM_WORLD); + MPI_Recv(&x[rows + 1][0], n + 2, MPI_DOUBLE, 1, TAG_BORDER, MPI_COMM_WORLD, &status); + } else { + MPI_Recv(&x[0][0], n + 2, MPI_DOUBLE, 0, TAG_BORDER, MPI_COMM_WORLD, &status); + MPI_Send(&x[1][0], n + 2, MPI_DOUBLE, 0, TAG_BORDER, MPI_COMM_WORLD); + } + MPI_Allreduce(&max_diff, &global_max_diff, 1, MPI_DOUBLE, MPI_MAX, MPI_COMM_WORLD); + } while (global_max_diff > threshold); + + MPI_Finalize(); + + return 0; +} + +void print_matrix(int rows, int cols, double x[rows][cols]) { + int i, j; + printf("---------------------------------\n"); + for (i = 0; i < rows; i++) { + for (j = 0; j < cols; j++) { + printf("%f\t", x[i][j]); + } + printf("\n"); + } + printf("---------------------------------\n"); + fflush(stdout); +}