diff --git a/config/config.c b/config/config.c deleted file mode 100644 index 7d1c1b7..0000000 --- a/config/config.c +++ /dev/null @@ -1,58 +0,0 @@ -#include -#include - -typedef struct configuration { - int n; - double north; - double east; - double south; - double west; - double init_value; - double threshold; -} configuration; - -int load_config(configuration *config) { - char property[100]; - char *value; - FILE *fp; - - fp = fopen("jacobi.conf", "r"); - if (fp == NULL) { - perror("Error opening file jacobi.conf"); - return 1; - } - while (fgets(property, 100, fp) != NULL) { - if (property[0] == '\n' || property[0] == '#') { - /* Skip empty lines and comments */ - continue; - } - value = strchr(property, ' '); - if (value == NULL) { - fclose(fp); - perror("Error reading file jacobi.conf"); - return 1; - } - value[0] = '\0'; - value += sizeof(char); - value[strlen(value) - 1] = '\0'; - if (strcmp(property, "N") == 0) { - sscanf(value, "%d", &(config->n)); - } else if (strcmp(property, "NORTH") == 0) { - sscanf(value, "%lf", &(config->north)); - } else if (strcmp(property, "EAST") == 0) { - sscanf(value, "%lf", &(config->east)); - } else if (strcmp(property, "SOUTH") == 0) { - sscanf(value, "%lf", &(config->south)); - } else if (strcmp(property, "WEST") == 0) { - sscanf(value, "%lf", &(config->west)); - } else if (strcmp(property, "INIT_VALUE") == 0) { - sscanf(value, "%lf", &(config->init_value)); - } else if (strcmp(property, "THRESHOLD") == 0) { - sscanf(value, "%lf", &(config->threshold)); - } else { - printf("Unknown property %s\n", property); - } - } - fclose(fp); - return 0; -} diff --git a/config/config.h b/config/config.h deleted file mode 100644 index 32635dd..0000000 --- a/config/config.h +++ /dev/null @@ -1,11 +0,0 @@ -typedef struct configuration { - int n; - double north; - double east; - double south; - double west; - double init_value; - double threshold; -} configuration; - -int load_config(configuration *config); diff --git a/mpi_line/Makefile b/mpi_line/Makefile deleted file mode 100644 index 98d68f4..0000000 --- a/mpi_line/Makefile +++ /dev/null @@ -1,15 +0,0 @@ -CC=mpicc -CFLAGS=-Wall -lm -std=c99 - -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 deleted file mode 100644 index 3e7fd02..0000000 --- a/mpi_line/jacobi.conf +++ /dev/null @@ -1,16 +0,0 @@ -# Configuration file for the Jacobi project. - -# The size of the matrix (borders excluded). -N 5 - -# 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 deleted file mode 100644 index 6946f58..0000000 --- a/mpi_line/jacobi_mpi_line.c +++ /dev/null @@ -1,183 +0,0 @@ -/* - * MPI version with the matrix subdivided by "lines". - */ - -#include -#include -#include -#include -#include "../config/config.h" -#include "../utils/utils.h" - -#define TAG_BORDER 0 -#define TAG_MATRIX 1 - -double *compute_jacobi(int n, double init_value, double threshold, borders b, int *iterations); - -int rank; -int numprocs; - -int main(int argc, char* argv[]) { - 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; - - MPI_Init(&argc, &argv); - - MPI_Comm_rank(MPI_COMM_WORLD, &rank); - MPI_Comm_size(MPI_COMM_WORLD, &numprocs); - - 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 (rank == 0) { - startwtime = MPI_Wtime(); - } - - x = compute_jacobi(n, init_value, threshold, b, &iterations); - - if (rank == 0) { - endwtime = MPI_Wtime(); - printf("Wall clock time: %fs\n", endwtime - startwtime); - printf("Iterations: %d\n", iterations); - print_sa_matrix(x, n + 2, n + 2); - } - - destroy_sa_matrix(x); - - MPI_Finalize(); - - return 0; -} - -double *compute_jacobi(int n, double init_value, double threshold, borders b, int *iterations) { - double *complete_x; - double *x; - double max_diff, global_max_diff, new_x; - int i, j; - int nb = n + 2; // n plus the border - int rows, rows_to_transmit; - int receive_pos; - 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_sa_matrix(rows + 2, nb); - for (i = 0; i < rows + 2; i++) { - for (j = 1; j <= n; j++) { - x[IDX(nb, i, j)] = init_value; - } - } - /* Initialize boundary regions */ - for (i = 0; i < rows + 2; i++) { - x[IDX(nb, i, 0)] = b.west; - x[IDX(nb, i, n + 1)] = b.east; - } - if (rank == 0) { - for (i = 1; i <= n + 1; i++) { - x[IDX(nb, 0, i)] = b.north; - } - } - if (rank == numprocs - 1){ - for (i = 1; i < n + 1; i++) { - x[IDX(nb, 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; - for (i = 1; i <= rows; i++) { - for (j = 1; j <= n; j++) { - new_x = 0.25 * (x[IDX(nb, i - 1, j)] + x[IDX(nb, i, j + 1)] + x[IDX(nb, i + 1, j)] + x[IDX(nb, i, j - 1)]); - max_diff = (double) fmax(max_diff, fabs(new_x - x[IDX(nb, i, j)])); - x[IDX(nb, i, j)] = new_x; - } - } - if (rank % 2 == 0) { - if (rank != numprocs - 1) { - // Send and receive south border - MPI_Send(&x[IDX(nb, rows, 0)], nb, MPI_DOUBLE, rank + 1, TAG_BORDER, MPI_COMM_WORLD); - MPI_Recv(&x[IDX(nb, rows + 1, 0)], nb, MPI_DOUBLE, rank + 1, TAG_BORDER, MPI_COMM_WORLD, &status); - } - if (rank != 0) { - // Send and receive north border - MPI_Send(&x[IDX(nb, 1, 0)], nb, MPI_DOUBLE, rank - 1, TAG_BORDER, MPI_COMM_WORLD); - MPI_Recv(&x[IDX(nb, 0, 0)], nb, MPI_DOUBLE, rank - 1, TAG_BORDER, MPI_COMM_WORLD, &status); - } - } else { - // Receive and send north border - MPI_Recv(&x[IDX(nb, 0, 0)], nb, MPI_DOUBLE, rank - 1, TAG_BORDER, MPI_COMM_WORLD, &status); - MPI_Send(&x[IDX(nb, 1, 0)], nb, MPI_DOUBLE, rank - 1, TAG_BORDER, MPI_COMM_WORLD); - if (rank != numprocs - 1) { - // Receive and send south border - MPI_Recv(&x[IDX(nb, rows + 1, 0)], nb, MPI_DOUBLE, rank + 1, TAG_BORDER, MPI_COMM_WORLD, &status); - MPI_Send(&x[IDX(nb, rows, 0)], nb, 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) { - complete_x = create_sa_matrix(nb, nb); - memcpy(complete_x, x, (rows + ((rank == numprocs - 1) ? 2 : 1)) * (nb) * sizeof(double)); - rows_to_transmit = n / numprocs; - receive_pos = rows + 1; - for (i = 1; i < numprocs; i++) { - if (i == numprocs - 1) { - rows_to_transmit++; - } - MPI_Recv(&complete_x[IDX(nb, receive_pos, 0)], rows_to_transmit * (nb), MPI_DOUBLE, i, TAG_MATRIX, MPI_COMM_WORLD, &status); - receive_pos += n / numprocs; - } - } else { - complete_x = NULL; - rows_to_transmit = rows; - if (rank == numprocs - 1) { - rows_to_transmit++; - } - MPI_Send(&x[IDX(nb, 1, 0)], rows_to_transmit * (nb), MPI_DOUBLE, 0, TAG_MATRIX, MPI_COMM_WORLD); - } - - return complete_x; -} diff --git a/sequential/Makefile b/sequential/Makefile deleted file mode 100644 index acdc915..0000000 --- a/sequential/Makefile +++ /dev/null @@ -1,15 +0,0 @@ -CC=mpicc -CFLAGS=-Wall -lm -std=c99 - -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 deleted file mode 100644 index ce8b562..0000000 --- a/sequential/jacobi.conf +++ /dev/null @@ -1,16 +0,0 @@ -# Configuration file for the Jacobi project. - -# The size of the matrix (borders excluded). -N 3000 - -# 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/sequential/jacobi_sequential.c b/sequential/jacobi_sequential.c deleted file mode 100644 index 1c9c95d..0000000 --- a/sequential/jacobi_sequential.c +++ /dev/null @@ -1,82 +0,0 @@ -/* - * Sequential version. - * No paralleliization used. - */ - -#include -#include -#include -#include "../config/config.h" -#include "../utils/utils.h" - -double **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; - double **x; - - 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) { - return 1; - } - - b.north = config.north; - b.east = config.east; - b.south = config.south; - b.west = config.west; - - startwtime = MPI_Wtime(); - 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; -} - -double **compute_jacobi(int n, double init_value, double threshold, borders b) { - 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; - x[i][0] = b.west; - x[i][n + 1] = b.east; - } - /* Initialize the rest of the matrix */ - for (i = 1; i <= n; i++) { - for (j = 1; j <= n; j++) { - x[i][j] = init_value; - } - } - /* Iterative refinement of x until values converge */ - do { - max_diff = 0; - for (i = 1; i <= n; 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; - } - } - } while (max_diff > threshold); - return x; -} diff --git a/utils/utils.c b/utils/utils.c deleted file mode 100644 index 30fda51..0000000 --- a/utils/utils.c +++ /dev/null @@ -1,56 +0,0 @@ -#include -#include -#include "../utils/utils.h" - -double *create_sa_matrix(int rows, int cols) { - double *x; - - x = (double *) malloc(rows * cols * sizeof(double)); - return x; -} - -void destroy_sa_matrix(double *x) { - free(x); -} - -void print_sa_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[IDX(cols, i, j)]); - } - printf("\n"); - } - fflush(stdout); -} - -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 deleted file mode 100644 index eb0b37c..0000000 --- a/utils/utils.h +++ /dev/null @@ -1,46 +0,0 @@ -#include -#include - -/* #define ENABLE_LOG */ - -#ifdef ENABLE_LOG -# define LOG(x) x -#else -# define LOG(x) (void) 0 -#endif - -/* - * Macro used with single array matrices to - * get the array index given the number of columns, - * the row index and the column index. - */ -#define IDX(cols, r, c) ((r) * (cols) + (c)) - -typedef struct borders { - double north; - double east; - double south; - double west; -} borders; - - -/* - * Create a matrix stored in a single array. - */ -double *create_sa_matrix(int rows, int cols); - -/* - * Destroy a single array matrix. - */ -void destroy_sa_matrix(double *x); - -int sa_index(int cols, int r, int c); - -/* - * Print a single array matrix. - */ -void print_sa_matrix(double *x, int rows, int cols); - -double **create_matrix(int rows, int cols); -void destroy_matrix(double **x, int rows); -void print_matrix(double **x, int rows, int cols);