diff --git a/src/10nodes_output.txt b/src/10nodes_output.txt new file mode 100644 index 0000000000000000000000000000000000000000..aaf259b44650d1717045055729d09ebee289a0af --- /dev/null +++ b/src/10nodes_output.txt @@ -0,0 +1,10 @@ +0 8 9 7 1 1 5 9 8 3 +8 0 10 7 7 9 3 1 6 9 +9 10 0 11 9 10 12 11 9 11 +7 7 11 0 6 8 4 8 7 6 +1 7 9 6 0 2 4 8 7 2 +1 9 10 8 2 0 6 10 9 4 +5 3 12 4 4 6 0 4 3 6 +9 1 11 8 8 10 4 0 7 10 +8 6 9 7 7 9 3 7 0 9 +3 9 11 6 2 4 6 10 9 0 diff --git a/src/4nodes_output.txt b/src/4nodes_output.txt new file mode 100644 index 0000000000000000000000000000000000000000..6a5c68bff01488b31ac6b58e064366b45cc91583 --- /dev/null +++ b/src/4nodes_output.txt @@ -0,0 +1,4 @@ +0 10 9 11 +10 0 1 1 +9 1 0 2 +11 1 2 0 diff --git a/src/Makefile b/src/Makefile new file mode 100644 index 0000000000000000000000000000000000000000..6396eab27480e8b1e2ad3dc41264ab5e22fedde9 --- /dev/null +++ b/src/Makefile @@ -0,0 +1,2 @@ +main_omp_v1: main_omp_v1.c + gcc main_omp_v1.c data_structure.c -lm -o main_omp_v1 -fopenmp diff --git a/src/data_structure.c b/src/data_structure.c new file mode 100644 index 0000000000000000000000000000000000000000..903a15016d5ece26ced69b1e7ef0c15ebef09668 --- /dev/null +++ b/src/data_structure.c @@ -0,0 +1,105 @@ +#include "data_structure.h" +#include <stdio.h> +#include <stdlib.h> + +void createMatrix(int r, int c, matrix* M){ + mem(*M) =(int*) malloc(((r * c) + 2) * sizeof(int)); + row(*M) = r; + column(*M) = c; +} + +void resetMatrix(matrix *M, int value){ + for (int i = 0; i < row(*M); i++){ + for (int j = 0; j < row(*M); j++){ + if (i == j){ + setValue(M, i, j, ZERO); + } + else{ + setValue(M, i, j, value); + } + } + } +} + +void printMatrix(matrix M){ + for (int i = 0; i < row(M); i++){ + for (int j = 0; j < column(M); j++){ + printf("%d\t", value(M, i, j)); + } + printf("\n"); + } +} + +void setValue(matrix *M, int i, int j, int value){ + value(*M, i, j) = value; +} + +void updateMatrix(matrix *M, int* distance){ + int src = distance[0]; + for (int dest = 0; dest < row(*M); dest++){ + if (distance[3 + dest] < value(*M, src, dest) && src != dest){ + value(*M, src, dest) = distance[3 + dest]; + value(*M, dest, src) = distance[3 + dest]; + } + } +} + +// void updateDistance(matrix *M, int* distance){ + +// } + +int* serializeMatrix(matrix M){ + return mem(M); +} + +void printSerializedMatrix(int* SM){ + for (int i = 0; i < SM[0]; i++){ + for (int j = 0; j < SM[1]; j++){ + printf("%d ", SM[2 + (i * SM[0]) + j]); + } + printf("\n"); + } +} + +void setMatrix(matrix *M){ + setValue(M, 0, 1, 4); + setValue(M, 0, 7, 8); + + setValue(M, 1, 0, 4); + setValue(M, 1, 2, 8); + setValue(M, 1, 7, 11); + + setValue(M, 2, 1, 8); + setValue(M, 2, 3, 7); + setValue(M, 2, 5, 4); + setValue(M, 2, 8, 2); + + setValue(M, 3, 2, 7); + setValue(M, 3, 4, 9); + setValue(M, 3, 5, 14); + + setValue(M, 4, 3, 9); + setValue(M, 4, 5, 10); + + setValue(M, 5, 2, 4); + setValue(M, 5, 3, 14); + setValue(M, 5, 4, 10); + setValue(M, 5, 6, 2); + + setValue(M, 6, 5, 2); + setValue(M, 6, 7, 1); + setValue(M, 6, 8, 6); + + setValue(M, 7, 0, 8); + setValue(M, 7, 1, 11); + setValue(M, 7, 6, 1); + setValue(M, 7, 8, 7); + + setValue(M, 8, 2, 2); + setValue(M, 8, 6, 6); + setValue(M, 8, 7, 7); +} + +void destroyMatrix(matrix *M){ + free(mem(*M)); +} \ No newline at end of file diff --git a/src/data_structure.h b/src/data_structure.h new file mode 100644 index 0000000000000000000000000000000000000000..deef19bb2f6e575df5b34178d6b3979a4599f791 --- /dev/null +++ b/src/data_structure.h @@ -0,0 +1,29 @@ +#ifndef DATA_STRUCTURE_H +#define DATA_STRUCTURE_H + + +typedef struct { + int* mem; +} matrix; + +// Selektor +#define mem(M) (M).mem +// Ukuran +#define row(M) (M).mem[0] +#define column(M) (M).mem[1] +#define value(M, i, j) (M).mem[2 + (i*row(M)) + (j)] +#define INF 99999 +#define ZERO 0 + +void createMatrix(int r, int c, matrix* M); +void printMatrix(matrix M); +void resetMatrix(matrix *M, int value); +void setValue(matrix *M, int i, int j, int value); +void updateMatrix(matrix *M, int* distance); +void setMatrix(matrix *M); + +int* serializeMatrix(matrix M); +void printSerializedMatrix(int* SM); +void destroyMatrix(matrix *M); + +#endif \ No newline at end of file diff --git a/src/data_structure_serial.c b/src/data_structure_serial.c new file mode 100644 index 0000000000000000000000000000000000000000..999b9265e76e6e2a256991ac3d0461b7a6cd2fa7 --- /dev/null +++ b/src/data_structure_serial.c @@ -0,0 +1,79 @@ +#include "data_structure_serial.h" +#include <stdio.h> +#include <stdlib.h> + +void createMatrix(int r, int c, matrix *M) +{ + row(*M) = r; + column(*M) = c; + Mem(*M) = (int **)malloc(row(*M) * sizeof(int *)); + + for (int i = 0; i < row(*M); i++) + { + M->mem[i] = (int *)malloc(column(*M) * sizeof(int)); + } +} + +void destroyMatrix(matrix *M) +{ + for (int i = 0; i < row(*M); i++) + { + free(M->mem[i]); + } + free(M->mem); +} + +void resetMatrix(matrix *M, int value) +{ + for (int i = 0; i < row(*M); i++) + { + for (int j = 0; j < column(*M); j++) + { + if (i == j) + { + setValue(M, i, j, ZERO); + } + else + { + setValue(M, i, j, value); + } + } + } +} + +void printMatrix(matrix M) +{ + for (int i = 0; i < row(M); i++) + { + for (int j = 0; j < column(M); j++) + { + + printf("%d ", value(M, i, j)); + // printf("Ngeprint col %d\n", j); + // printf("Ngeprint row %d\n", i); + // printf("%d ", M.mem[i][j]); + } + printf("\n"); + } +} + +void setValue(matrix *M, int i, int j, int value) +{ + value(*M, i, j) = value; +} + +void updateMatrix(matrix *M, matrix m, int src) +{ + for (int dest = 0; dest < row(m); dest++) + { + // printf("VALUE DISTANCE %d %d \n", dest, (value(m, dest, 0))); + // printf("MATRIX SOLU %d %d %d \n", src, dest, (value(*M, src, dest))); + if ((value(m, dest, 0) < value(*M, src, dest)) && (src != dest)) + { + setValue(M, src, dest, value(m, dest, 0)); + setValue(M, dest, src, value(m, dest, 0)); + // value(*M, src, dest) = value(m, dest, 0); + // value(*M, dest, src) = value(m, dest, 0); + } + } +} diff --git a/src/data_structure_serial.h b/src/data_structure_serial.h new file mode 100644 index 0000000000000000000000000000000000000000..da637cee0c6f7d882a7579f82596ae4db9e769e4 --- /dev/null +++ b/src/data_structure_serial.h @@ -0,0 +1,28 @@ +#ifndef DATA_STRUCTURE_SERIAL_H +#define DATA_STRUCTURE_SERIAL_H + +typedef struct +{ + int **mem; + int row; + int column; +} matrix; + +// Selektor +#define Mem(M) (M).mem +// Ukuran +#define row(M) (M).row +#define column(M) (M).column +#define value(M, i, j) (M).mem[(i)][(j)] +#define INF 99999 +#define ZERO 0 + +void createMatrix(int r, int c, matrix *M); +void destroyMatrix(matrix *M); +void printMatrix(matrix M); +void resetMatrix(matrix *M, int value); +void setValue(matrix *M, int i, int j, int value); + +void updateMatrix(matrix *M, matrix m, int src); + +#endif diff --git a/src/main_omp_v1 b/src/main_omp_v1 new file mode 100755 index 0000000000000000000000000000000000000000..bfc79f91db7a7a60d8fbe5ee1cadd22b91f14f1d Binary files /dev/null and b/src/main_omp_v1 differ diff --git a/src/main_omp_v1.c b/src/main_omp_v1.c new file mode 100644 index 0000000000000000000000000000000000000000..88a95cf76b8c0594c8e06556208900ccb19a296b --- /dev/null +++ b/src/main_omp_v1.c @@ -0,0 +1,156 @@ +#include "data_structure.h" +#include <omp.h> +#include <math.h> +#include <stdlib.h> +#include <stdio.h> +#include <string.h> + +int minDistance(int* distance, int visitedNodes[], int sz){ + int min_value = INF; + int min_index = 0; + for (int i = 0; i < sz; i++){ + if ((distance[3 + i] <= min_value) && (visitedNodes[i] != 1)){ + min_index = i; + min_value = distance[3 + i]; + } + } + return min_index; +} + +int normalize(int rand){ + + rand = (rand % (20 - 1)) + 1; + + return rand; +} + +void randomize(matrix *M, int NIM){ + srand(NIM); + + for (int row = 0; row < row(*M); row++){ + for (int column = 0; column < column(*M); column++){ + if (column > row){ + int temp = normalize(rand()); + + value(*M, row, column) = temp; + value(*M, column, row) = temp; + } + } + } +} + +void dijsktra(matrix graph, int* distance, int src){ + + int nNodes = row(graph); + // Current Node with minimum distance to SRC + int currentNode; + int visitedNodes[nNodes]; + + + // Init distance to INFINITY + for (int j = 0; j < nNodes; j++){ + distance[3 + j] = INF; + visitedNodes[j] = 0; + } + + // Distance to itself is 0 + distance[3 + src] = 0; + + for (int n = 0; n < nNodes - 1; n++){ + // Pick the minimum distance from current nodes + currentNode = minDistance(distance, visitedNodes, nNodes); + + visitedNodes[currentNode] = 1; + + for (int v = 0; v < nNodes; v++){ + if (visitedNodes[v] == 0 && + value(graph, currentNode, v) != INF && + distance[3 + currentNode] != INF && + distance[3 + currentNode]+ value(graph, currentNode, v) < distance[3 + v] + ){ + distance[3 + v] = distance[3 + currentNode] + value(graph, currentNode, v); + } + } + } + distance[2] = 1; +} + +void filewrite(matrix *M, int nNodes){ + FILE * fp; + int i; + /* open the file for writing*/ + char strint[10]; + sprintf(strint, "%d", nNodes); + fp = fopen (strcat(strint,"nodes_output.txt"),"w"); + + for (int i = 0; i < row(*M); i++){ + for (int j = 0; j < column(*M); j++){ + fprintf (fp, "%d\t", value(*M, i, j)); + } + fprintf(fp, "\n"); + } + /* close the file*/ + fclose (fp); + +} + + +void parallelDijsktra(int nNodes, int NUM_THREADS){ + + double startTime = 0.0, totalTime = 0.0; + int buff, temp; + + matrix M; + matrix Solu; + createMatrix(nNodes, nNodes, &M); + resetMatrix(&M, INF); + + createMatrix(nNodes, nNodes, &Solu); + resetMatrix(&Solu, INF); + randomize(&M, 13517124); + + startTime = omp_get_wtime(); + int factor = ceil((double) nNodes/(NUM_THREADS)); + +# pragma omp parallel num_threads(NUM_THREADS) shared(Solu, M, factor, startTime, nNodes) +{ + int i = 0; + + int currentNode = (omp_get_thread_num() * factor); + + int* distance; + distance = (int *) malloc((3 + nNodes) * sizeof(int)); + distance[1] = nNodes; + distance[2] = 0; + + //printf("Thread #%d ngurus node: ", omp_get_thread_num()); + while (i < factor && currentNode < nNodes){ + distance[0] = currentNode; + dijsktra(M, distance, currentNode); + updateMatrix(&Solu, distance); + i += 1; + currentNode = i + (omp_get_thread_num() * factor); + } + + //printf("thread #%d finished\n", omp_get_thread_num()); + free(distance); +} +# pragma omp barrier + totalTime = omp_get_wtime() - startTime; + printf("PEPEG\n"); + // printMatrix(Solu); + printf("Process completed in %f microseconds\n", totalTime*1000); + filewrite(&Solu, nNodes); + destroyMatrix(&Solu); +} + +int main(){ + // Banyak Nodes, Banyak Threads + int N, NUM_THREADS; + printf("Banyak Node: "); + scanf("%d", &N); + printf("Banyak Threads: "); + scanf("%d", &NUM_THREADS); + parallelDijsktra(N, NUM_THREADS); + return 0; +} \ No newline at end of file diff --git a/src/mainserial b/src/mainserial new file mode 100755 index 0000000000000000000000000000000000000000..2816c63d8ce344ee776ff3d0ccc7e9f8b2f4809c Binary files /dev/null and b/src/mainserial differ diff --git a/src/mainserial.c b/src/mainserial.c new file mode 100644 index 0000000000000000000000000000000000000000..cbe7333efb4ef919123adedf7836763cc7b182ae --- /dev/null +++ b/src/mainserial.c @@ -0,0 +1,159 @@ +#include "data_structure_serial.h" +#include <stdio.h> +#include <stdlib.h> +#include <time.h> +// #include "mpi.h" +int normalize(int rand){ + + rand = (rand % (20 - 1)) + 1; + + return rand; +} + +void randomize(matrix *M, int NIM){ + srand(NIM); + + for (int row = 0; row < row(*M); row++){ + for (int column = 0; column < column(*M); column++){ + if (column > row){ + int temp = normalize(rand()); + + value(*M, row, column) = temp; + value(*M, column, row) = temp; + } + } + } +} +void printSolution(matrix distance, int src) +{ + printf("Node Src: %d\n", src); + printf("Node Dest Distance from\n"); + for (int i = 0; i < row(distance); i++) + { + printf("%d %d %d\n", i, value(distance, i, 0), value(distance, i, 1)); + } +} +int minDistance(matrix distance, int visitedNodes[], int sz) +{ + int min_value = INF; + int min_index = 0; + for (int i = 0; i < sz; i++) + { + if (value(distance, i, 0) <= min_value && visitedNodes[i] != 1) + { + min_index = i; + min_value = value(distance, i, 0); + } + } + // printf("MINDEX %d\n", min_index); + // printf("MINVAL %d\n", min_value); + return min_index; +} +matrix dijsktra(matrix graph, int src) +{ + int nNodes = row(graph); + // Current Node with minimum distance to SRC + int currentNode; + matrix distance; + int visitedNodes[nNodes]; + createMatrix(nNodes, 2, &distance); + // Init distance to INFINITY + for (int i = 0; i < nNodes; i++) + { + value(distance, i, 0) = INF; + value(distance, i, 1) = -1; + visitedNodes[i] = 0; + } + // Distance to itself is 0 + value(distance, src, 0) = 0; + for (int n = 0; n < nNodes - 1; n++) + { + // Pick the minimum distance from current nodes + currentNode = minDistance(distance, visitedNodes, nNodes); + visitedNodes[currentNode] = 1; + for (int v = 0; v < nNodes; v++) + { + /* printf("[%d, %d]\n", n, v); + printf("current Nodes: %d\n", currentNode); */ + if (visitedNodes[v] == 0 && + value(graph, currentNode, v) != INF && + value(distance, currentNode, 0) != INF && + value(distance, currentNode, 0) + value(graph, currentNode, v) < value(distance, v, 0)) + { + value(distance, v, 0) = value(distance, currentNode, 0) + value(graph, currentNode, v); + value(distance, v, 1) = currentNode; + } + } + } + // printSolution(distance, src); + return distance; +} +void generateSolutions(matrix graph) +{ + int currentNode; + matrix solutions; + matrix tempSingleSolution; + createMatrix(row(graph), 2, &tempSingleSolution); + createMatrix(row(graph), column(graph), &solutions); + + resetMatrix(&solutions, INF); + + for (currentNode = 0; currentNode < row(graph); currentNode++) + { + tempSingleSolution = dijsktra(graph, currentNode); + updateMatrix(&solutions, tempSingleSolution, currentNode); + + } + destroyMatrix(&tempSingleSolution); + // printMatrix(solutions); + destroyMatrix(&solutions); +} + +void filewrite(matrix *M){ + FILE * fp; + int i; + /* open the file for writing*/ + fp = fopen ("outputserial.txt","w"); + + for (int i = 0; i < row(*M); i++){ + for (int j = 0; j < column(*M); j++){ + fprintf (fp, "%d\t", value(*M, i, j)); + } + fprintf(fp, "\n"); + } + /* close the file*/ + fclose (fp); + +} + +int main(int argc, char* argv[]) +{ + clock_t start, end; + double cpu_time_used; + + matrix M; + int nNodes; + nNodes = atoi(argv[1]); + + + createMatrix(nNodes, nNodes, &M); + resetMatrix(&M, INF); + + randomize(&M, 13517073); + // printMatrix(M); + + start = clock(); + + generateSolutions(M); + + destroyMatrix(&M); + + end = clock(); + cpu_time_used = ((double) (end - start)) / CLOCKS_PER_SEC; + + printf("\nSerial time Elapsed: %f\n", cpu_time_used * 1000000); + + // filewrite(&M); + + return 0; +}