diff --git a/src/Coba.c b/src/Coba.c deleted file mode 100644 index 3a98195636abc7846703dfeae6c84e819b317312..0000000000000000000000000000000000000000 --- a/src/Coba.c +++ /dev/null @@ -1,95 +0,0 @@ -#include <mpi.h> -#include <stdio.h> -#include <string.h> -#include <time.h> - -// Menuliskan array ke layar -void PrintArray(int T[], int a, int b) -{ - for (int i = a; i <= b - 1; i++) - { - printf("%d ", T[i - 1]); - } - printf("%d\n", T[b - 1]); -} - -// Melakukan partisi sembari menukar value dengan pivot ke-i -void Partisi(int T[], int i, int j, int *k) -{ - int pivot = T[i - 1]; - int p = i; - int q = j; - while (p <= q) - { - while (T[p - 1] < pivot) - { - p++; - } - while (T[q - 1] > pivot) - { - q--; - } - if (p < q) - { - int temp = T[p - 1]; - T[p - 1] = T[q - 1]; - T[q - 1] = temp; - p++; - q--; - } - else if (p == q) - { - p++; - } - } - *k = q; -} - -// Mengurutkan array dengan menggunakan Quick Sort -void SequentialQuickSort(int T[], int i, int j) -{ - int k; - if (i < j) - { - Partisi(T, i, j, &k); - SequentialQuickSort(T, i, k); - SequentialQuickSort(T, k + 1, j); - } -} - -int main() -{ - int my_rank, comm_sz, n; - int T[5000]; - int N; - - MPI_Init(NULL, NULL); - MPI_Comm_rank(MPI_COMM_WORLD, &my_rank); - MPI_Comm_size(MPI_COMM_WORLD, &comm_sz); - - if (my_rank == 0){ - scanf("%d", &N); - for (int i = 0; i < N; i++) - { - scanf("%d", &T[i]); - } - printf("Hello World"); - double t = MPI_Wtime(); - // QuickSort(T, 1, N); - // MPI_Bcast(&N, 1, MPI_INT, 0, MPI_COMM_WORLD); - // MPI_Bcast(&T, 5000, MPI_INT, 0, MPI_COMM_WORLD); - MPI_Send(&T, 5000, MPI_INT, 0, 0, MPI_COMM_WORLD); - printf("Hello World"); - t = MPI_Wtime() - t; - printf("Waktu Eksekusi: %.4f ms\n", t / CLOCKS_PER_SEC * 1000); - - } else { - // MPI_Bcast(&N, 1, MPI_INT, 0, MPI_COMM_WORLD); - // MPI_Bcast(&T, 5000, MPI_INT, 0, MPI_COMM_WORLD); - MPI_Recv(&T, 5000, MPI_INT, 0, 0, MPI_COMM_WORLD, MPI_STATUS_IGNORE); - // printf("Process %d: After MPI_Bcast, value is %d\n", my_rank, N); - } - - PrintArray(T, 1, N); - return 0; -} \ No newline at end of file diff --git a/src/Graph_Generator.c b/src/Graph_Generator.c index d9916904861c277f62f55e84bd51ce194977cf81..4b38cb20a5acd2cd687505ccc0e51828ad37d553 100644 --- a/src/Graph_Generator.c +++ b/src/Graph_Generator.c @@ -28,7 +28,7 @@ int main(){ } else{ - int r = rand() % 20; + int r = rand() % (2*N); int val = (r == 5) || (r == 0) || (r < 3) ? -1: r; edge[i][j] = val; edge[j][i] = val; diff --git a/src/Hello b/src/Hello new file mode 100755 index 0000000000000000000000000000000000000000..db07b316b3fa565c722217df5f338b3cfef62373 Binary files /dev/null and b/src/Hello differ diff --git a/src/MPI_Communication.c b/src/MPI_Communication.c deleted file mode 100644 index 70dc805455f1901f9aa25133fd66326a73c97e4c..0000000000000000000000000000000000000000 --- a/src/MPI_Communication.c +++ /dev/null @@ -1,25 +0,0 @@ -#include <mpi.h> -#include <stdio.h> - -int main() -{ - int id, size, x; - - MPI_Init(NULL, NULL); - MPI_Comm_size(MPI_COMM_WORLD, &size); - MPI_Comm_rank(MPI_COMM_WORLD, &id); - - // P0 mengirim pesan x ke P1 - // P1 menerima pesan dari P0, disimpan ke x - if (id == 0) { - x = 6; - MPI_Send(&x, 1, MPI_INT, 1, 0, MPI_COMM_WORLD); - } - if (id == 1) - MPI_Recv(&x, 1, MPI_INT, 0, 0, MPI_COMM_WORLD, NULL); - - printf("P[%d] x: %d\n", id, x); - - MPI_Finalize(); - return 0; -} \ No newline at end of file diff --git a/src/MST_OpenMPI b/src/MST_OpenMPI index b930a6e530331da0962716a45935f44a7cc369b1..28e6b1e49e20808b13c387ea4ea2a9e1fed5fb50 100755 Binary files a/src/MST_OpenMPI and b/src/MST_OpenMPI differ diff --git a/src/MST_OpenMPI.c b/src/MST_OpenMPI.c index 1fe81b8b60fb46c107cb71ac094e85ef3bc79adc..e1883e5df04236dbe4c8c7a28b020ee026a638c9 100644 --- a/src/MST_OpenMPI.c +++ b/src/MST_OpenMPI.c @@ -7,6 +7,7 @@ #include <string.h> #include <time.h> #include <mpi.h> +#include <stddef.h> // Edge structure typedef struct @@ -31,7 +32,6 @@ void makeStruct(MPI_Datatype *mpi_edge_type) //Inisialisasi MPI_Datatype types[3] = {MPI_INT, MPI_INT, MPI_INT}; - MPI_Datatype mpi_edge_type; MPI_Aint offset[3]; int block[3] = {1,1,1}; @@ -200,6 +200,96 @@ void bubbleSort(Edge arr[], int n, int type) } } +int pow2(int x){ + return 2 << x; +} + +// Menuliskan array ke layar +void PrintArray(Edge arr[], int a, int b) +{ + for (int i = a; i <= b - 1; i++) + { + printf("%d ", arr[i - 1].weight); + } + printf("%d\n", arr[b - 1].weight); +} + +// Melakukan partisi sembari menukar value dengan pivot ke-i +void Partisi(Edge arr[], int i, int j, int *k) +{ + int pivot = arr[i - 1].weight; + int p = i; + int q = j; + while (p <= q) + { + while (arr[p - 1].weight < pivot) + { + p++; + } + while (arr[q - 1].weight > pivot) + { + q--; + } + if (p < q) + { + Edge temp = arr[p - 1]; + arr[p - 1] = arr[q - 1]; + arr[q - 1] = temp; + p++; + q--; + } + else if (p == q) + { + p++; + } + } + *k = q; +} + +// Mengurutkan array dengan menggunakan Quick Sort versi Sequential +void SequentialQuickSort(Edge arr[], int i, int j) +{ + int k; + if (i < j) + { + Partisi(arr, i, j, &k); + SequentialQuickSort(arr, i, k); + SequentialQuickSort(arr, k + 1, j); + } +} + +// Mengurutkan array dengan metode Quick Sort Parallel +void QuickSort(Edge arr[], int i, int j, int rank, int max_rank, int rank_index){ + MPI_Datatype mpi_edge_type; + makeStruct(&mpi_edge_type); + + int distributed_process = rank + pow2(rank_index); + rank_index++; + + // If the rank of distributed process is higher than max rank + if (distributed_process > max_rank) { + SequentialQuickSort(arr, i, j); + } + else { + int pivot; + Partisi(arr, i, j, &pivot); + + // Upper half of array is larger than lower half of array + if (pivot-i > j-pivot-1){ + MPI_Send(&arr[pivot + 1], j - pivot - 1, mpi_edge_type, distributed_process, 1, MPI_COMM_WORLD); + QuickSort(arr, i, pivot, rank, max_rank, rank_index + 1); + MPI_Recv(&arr[pivot + 1], j - pivot - 1, mpi_edge_type, distributed_process, 1, MPI_COMM_WORLD, MPI_STATUS_IGNORE); + printf("rank x : %d\n", rank); + } else { + MPI_Send(&arr[i], pivot - i, mpi_edge_type, distributed_process, 1, MPI_COMM_WORLD); + QuickSort(arr, pivot + 1, j, rank, max_rank, rank_index + 1); + MPI_Recv(&arr[i], pivot - i, mpi_edge_type, distributed_process, 1, MPI_COMM_WORLD, MPI_STATUS_IGNORE); + printf("rank y : %d\n", rank); + } + } +} + + /// Create graph based from the adjacency matrix in file Graph *ReadArguments() { @@ -207,6 +297,7 @@ Graph *ReadArguments() int V, weight; scanf("%d", &V); + // V = 5; graph->V = V; graph->edge = (Edge *)(malloc(((V * V - V) / 2) * sizeof(Edge))); @@ -217,6 +308,8 @@ Graph *ReadArguments() for (int j = 0; j < V; j++) { scanf("%d", &weight); + // int r = rand() % (2* V); + // int weight = (r < 0.2 * V) ? -1: r; if ((weight != -1) && (i <= j)) { graph->edge[E].src = i; @@ -298,31 +391,32 @@ int compare_src(const void *a, const void *b) -void PreQuickSort (Edge result[], int size, int rank) { - if (rank==0) { +void PreQuickSort (Edge result[], int resultLength, int size, int rank) { + // if (rank==0) { //Implementasi quicksort disini + QuickSort(result, 1, resultLength, rank, size, 0); - } else { - MPI_Datatype mpi_edge_type; - makeStruct(&mpi_edge_type); + // } else { + // MPI_Datatype mpi_edge_type; + // makeStruct(&mpi_edge_type); - int idxcnt = 0; - Edge arr; - MPI_Status status; - while (rank >= pow(2, idxcnt)) { - idxcnt = idxcnt+1; - } - - int source = MPI_Probe(MPI_ANY_SOURCE, MPI_ANY_TAG, MPI_COMM_WORLD, &status); - source = MPI_Get_count(&status, mpi_edge_type, &arr); - int src = status.MPI_SOURCE; - - Edge * temp = (Edge *) malloc (sizeof(Edge) *arr); - source = MPI_Recv(temp, arr, mpi_edge_type, src, 1, MPI_COMM_WORLD, MPI_STATUS_IGNORE); - //Impementasiquicksort disini - source = MPI_Send(temp, arr, mpi_edge_type, src, 1, MPI_COMM_WORLD); - free(temp); - } + // int idxcnt = 0; + // int arrLength; + // MPI_Status status; + // while (rank >= pow2(idxcnt)) { + // idxcnt = idxcnt+1; + // } + + // int source = MPI_Probe(MPI_ANY_SOURCE, MPI_ANY_TAG, MPI_COMM_WORLD, &status); + // source = MPI_Get_count(&status, mpi_edge_type, &arrLength); + // int src = status.MPI_SOURCE; + + // Edge* temp = (Edge *) malloc (sizeof(Edge) *arrLength); + // source = MPI_Recv(temp, arrLength, mpi_edge_type, src, 1, MPI_COMM_WORLD, MPI_STATUS_IGNORE); + // QuickSort(temp, 0, arrLength, rank, size, idxcnt); + // source = MPI_Send(temp, arrLength, mpi_edge_type, src, 1, MPI_COMM_WORLD); + // free(temp); + // } } @@ -337,9 +431,9 @@ void KruskalMST(Graph *graph, Edge result[], int *e, int size, int rank) // Step 1: Sort all the edges into correspendent sorted edges // bubbleSort(graph->edge, graph->E, 1); // QuickSortWeight(graph->edge, 0, graph->E, size, rank); - - - + // printf("Process %d\n", rank); + PreQuickSort(graph->edge, graph->E, size, rank); + // PrintArray(graph->edge, 0, graph->E-1); // Step 2: Allocate memory for creating V subsets Subset *subsets = CreateSubset(V); @@ -357,6 +451,8 @@ void KruskalMST(Graph *graph, Edge result[], int *e, int size, int rank) } // QuickSortSrc(graph->edge, 0, graph->E, size, rank); + // QuickSortSrc(result, 1, (*e)); + qsort(result, *e, sizeof(result[0]), compare_src); return; } @@ -391,15 +487,43 @@ int main() int rank; MPI_Comm_rank(MPI_COMM_WORLD, &rank); + if (rank == 0){ + Graph *graph= ReadArguments(); + Edge result[graph->V]; + int e = 0; + double t = MPI_Wtime(); + KruskalMST(graph, result, &e, size, rank); + t = MPI_Wtime() - t; + printResult(result, e); + printf("Waktu Eksekusi: %f ms \n", (t * 1000)); + MPI_Abort(MPI_COMM_WORLD, EXIT_FAILURE); + + + } else { + // printf("Process %d\n", rank); + MPI_Datatype mpi_edge_type; + makeStruct(&mpi_edge_type); + + int idxcnt = 0; + int arrLength; + MPI_Status status; + while (rank >= pow2(idxcnt)) { + idxcnt = idxcnt+1; + } + + int source = MPI_Probe(MPI_ANY_SOURCE, MPI_ANY_TAG, MPI_COMM_WORLD, &status); + source = MPI_Get_count(&status, mpi_edge_type, &arrLength); + int src = status.MPI_SOURCE; + // arrLength = 100; - Graph *graph= ReadArguments(); - Edge result[graph->V]; - int e = 0; - int t = clock(); - KruskalMST(graph, result, &e, size, rank); - t = clock() - t; - printResult(result, e); - printf("Waktu Eksekusi: %f ms \n", ((double)t) / CLOCKS_PER_SEC * 1000); + Edge* temp = (Edge *) malloc (sizeof(Edge) *arrLength); + source = MPI_Recv(temp, arrLength, mpi_edge_type, src, 1, MPI_COMM_WORLD, MPI_STATUS_IGNORE); + QuickSort(temp, 0, arrLength, rank, size, idxcnt); + source = MPI_Send(temp, arrLength, mpi_edge_type, src, 1, MPI_COMM_WORLD); + // printf("Process %d\n", rank); + free(temp); + } MPI_Finalize(); + return 0; } \ No newline at end of file diff --git a/src/QuickSort b/src/QuickSort deleted file mode 100755 index 6fbff9dbcbc9d1eb9659fdac8069c2176f7e8825..0000000000000000000000000000000000000000 Binary files a/src/QuickSort and /dev/null differ diff --git a/src/QuickSort_MPI b/src/QuickSort_MPI new file mode 100755 index 0000000000000000000000000000000000000000..503e03f92f00f3015ebb70649b3c5dde037d456a Binary files /dev/null and b/src/QuickSort_MPI differ diff --git a/src/QuickSort_MPI.c b/src/QuickSort_MPI.c new file mode 100644 index 0000000000000000000000000000000000000000..a61d268f3470969986c99eefaf9f37e2ce21725a --- /dev/null +++ b/src/QuickSort_MPI.c @@ -0,0 +1,145 @@ +#include <mpi.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <time.h> +#include <math.h> + +int pow2(int x){ + return 2 << x; +} + +// Menuliskan array ke layar +void PrintArray(int T[], int a, int b) +{ + for (int i = a; i <= b - 1; i++) + { + printf("%d ", T[i - 1]); + } + printf("%d\n", T[b - 1]); +} + +// Melakukan partisi sembari menukar value dengan pivot ke-i +void Partisi(int T[], int i, int j, int *k) +{ + int pivot = T[i - 1]; + int p = i; + int q = j; + while (p <= q) + { + while (T[p - 1] < pivot) + { + p++; + } + while (T[q - 1] > pivot) + { + q--; + } + if (p < q) + { + int temp = T[p - 1]; + T[p - 1] = T[q - 1]; + T[q - 1] = temp; + p++; + q--; + } + else if (p == q) + { + p++; + } + } + *k = q; +} + +// Mengurutkan array dengan menggunakan Quick Sort versi Sequential +void SequentialQuickSort(int T[], int i, int j) +{ + int k; + if (i < j) + { + Partisi(T, i, j, &k); + SequentialQuickSort(T, i, k); + SequentialQuickSort(T, k + 1, j); + } +} + +// Mengurutkan array dengan metode Quick Sort Parallel +void QuickSort(int T[], int i, int j, int rank, int max_rank, int rank_index){ + int distributed_process = rank + pow2(rank_index); + rank_index++; + + // If the rank of distributed process is higher than max rank + if (distributed_process > max_rank) { + SequentialQuickSort(T, i, j); + } + else { + int pivot; + Partisi(T, i, j, &pivot); + + // Upper half of array is larger than lower half of array + if (pivot-i > j-pivot-1){ + MPI_Send(&T[pivot + 1], j - pivot - 1, MPI_INT, distributed_process, 1, MPI_COMM_WORLD); + QuickSort(T, i, pivot, rank, max_rank, rank_index + 1); + MPI_Recv(&T[pivot + 1], j - pivot - 1, MPI_INT, distributed_process, 1, MPI_COMM_WORLD, MPI_STATUS_IGNORE); + } else { + MPI_Send(&T[i], pivot - i, MPI_INT, distributed_process, 1, MPI_COMM_WORLD); + QuickSort(T, pivot + 1, j, rank, max_rank, rank_index + 1); + MPI_Recv(&T[i], pivot - i, MPI_INT, distributed_process, 1, MPI_COMM_WORLD, MPI_STATUS_IGNORE); + } + } +} + +int main() +{ + int rank, size, n; + int T[5000]; + int N; + + // OpenMPI Environment Initialization + MPI_Init(NULL, NULL); + MPI_Comm_rank(MPI_COMM_WORLD, &rank); + MPI_Comm_size(MPI_COMM_WORLD, &size); + + // If the root process is in charge + if (rank == 0){ + + // Get adjacency matrix input from user + scanf("%d", &N); + for (int i = 0; i < N; i++) + { + scanf("%d", &T[i]); + } + + // Calculate execution time + double t = MPI_Wtime(); + QuickSort(T, 1, N, rank, size, 0); + t = MPI_Wtime() - t; + printf("Waktu Eksekusi: %.4f ms\n", t / CLOCKS_PER_SEC * 1000); + PrintArray(T, 1, N); + + // Process with rank > 0 + } else { + int idxcnt = 0; + int N; + MPI_Status status; + while (rank >= pow2(idxcnt)) { + idxcnt = idxcnt+1; + } + + int source = MPI_Probe(MPI_ANY_SOURCE, MPI_ANY_TAG, MPI_COMM_WORLD, &status); + source = MPI_Get_count(&status, MPI_INT, &N); + int src = status.MPI_SOURCE; + + int* temp = (int*) malloc (sizeof(int) * N); + source = MPI_Recv(temp, N, MPI_INT, src, 1, MPI_COMM_WORLD, MPI_STATUS_IGNORE); + QuickSort(temp, 0, N, rank, size, idxcnt); + source = MPI_Send(temp, N, MPI_INT, src, 1, MPI_COMM_WORLD); + free(temp); + } + + MPI_Barrier(MPI_COMM_WORLD); + printf("Hello World %d\n\n", rank); + MPI_Finalize(); + + return 0; +} \ No newline at end of file diff --git a/src/QuickSort_Serial b/src/QuickSort_Serial new file mode 100755 index 0000000000000000000000000000000000000000..284c1c2d1e324723214f69f9732fd39956c0fba6 Binary files /dev/null and b/src/QuickSort_Serial differ diff --git a/src/QuickSort_Serial.c b/src/QuickSort_Serial.c new file mode 100644 index 0000000000000000000000000000000000000000..b9ff71ae339759f0a1aa533789f64b58eeb8c87b --- /dev/null +++ b/src/QuickSort_Serial.c @@ -0,0 +1,77 @@ +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <time.h> + +// Menuliskan array ke layar +void PrintArray(int T[], int a, int b) +{ + for (int i = a; i <= b - 1; i++) + { + printf("%d ", T[i - 1]); + } + printf("%d\n", T[b - 1]); +} + +// Melakukan partisi sembari menukar value dengan pivot ke-i +void Partisi(int T[], int i, int j, int *k) +{ + int pivot = T[i - 1]; + int p = i; + int q = j; + while (p <= q) + { + while (T[p - 1] < pivot) + { + p++; + } + while (T[q - 1] > pivot) + { + q--; + } + if (p < q) + { + int temp = T[p - 1]; + T[p - 1] = T[q - 1]; + T[q - 1] = temp; + p++; + q--; + } + else if (p == q) + { + p++; + } + } + *k = q; +} + +// Mengurutkan array dengan menggunakan Quick Sort +void QuickSort(int T[], int i, int j) +{ + + int k; + if (i < j) + { + Partisi(T, i, j, &k); + QuickSort(T, i, k); + QuickSort(T, k + 1, j); + } +} + +int main() +{ + int T[5000]; + int N; + scanf("%d", &N); + for (int i = 0; i < N; i++) + { + scanf("%d", &T[i]); + } + + PrintArray(T, 1, N); + float t = clock(); + QuickSort(T, 1, N); + t = clock() - t; + printf("Waktu Eksekusi: %f ms\n", (t / CLOCKS_PER_SEC) * 1000); + return 0; +} \ No newline at end of file diff --git a/src/a.out b/src/a.out new file mode 100755 index 0000000000000000000000000000000000000000..c025e37d329922d797f1eb508f8b6361f8e36884 Binary files /dev/null and b/src/a.out differ diff --git a/src/b.out b/src/b.out new file mode 100755 index 0000000000000000000000000000000000000000..242962d277a94b229fa5945ad3f7db3743b75f51 Binary files /dev/null and b/src/b.out differ diff --git a/src/c.out b/src/c.out new file mode 100755 index 0000000000000000000000000000000000000000..fe49bd9526854d08142ec62c9dc90cdb8d94b197 Binary files /dev/null and b/src/c.out differ diff --git a/src/log b/src/log new file mode 100644 index 0000000000000000000000000000000000000000..b20862adaba836b0e0e52e8f5b4aab971e28b9da Binary files /dev/null and b/src/log differ