diff --git a/Makefile b/Makefile new file mode 100644 index 0000000000000000000000000000000000000000..1777811cd4b25c410e7c2eab1208bcfab384fd82 --- /dev/null +++ b/Makefile @@ -0,0 +1,13 @@ +all : mpi_dijkstra + +mpi_dijkstra: src/mpi_dijkstra.o src/func.o + mpicc src/mpi_dijkstra.o src/func.o -o mpi_dijkstra + +mpi_dijkstra.o: src/mpi_dijkstra.c + mpicc -c src/mpi_dijkstra.c -o src/mpi_dijkstra.o + +func.o: src/func.c + mpicc -c src/func.c -o src/func.o + +clean: + rm -f src/mpi_dijkstra.o src/func.o mpi_dijkstra core *~ \ No newline at end of file diff --git a/README.md b/README.md index f77e0e810edfc34916acba1e68f804cc665adacd..70cf99978f23747e7ff23e423bd0c646101f7dd2 100644 --- a/README.md +++ b/README.md @@ -1,11 +1,33 @@ -# Announcement - -Beberapa file yang harus ada dalam repositori tersebut diantaranya: -* Direktori src yang berisi source code yang anda buat. -* File output yang berisi hasil uji dijkstra algorithm pada data uji. -* Makefile. Buatlah sehingga kompilasi program dapat dilakukan hanya dengan pemanggilan command ’make’ saja. -* File README.md yang berisi: - * Petunjuk penggunaan program. - * Pembagian tugas. Sampaikan dalam list pengerjaan untuk setiap mahasiswa. Sebagai contoh: XXXX mengerjakan fungsi YYYY, ZZZZ, dan YYZZ. - * Laporan pengerjaan, dengan struktur laporan sesuai dengan deskripsi pada bagian sebelumnya. +# OpenMPI + +## Nama - NIM : +- Paulus H.D. Siahaan - 13517111 +- Harry Rahmadi Munly - 13517033 + +## Petunjuk penggunaan program +1. Install library openmpi pada komputer +2. Ketik "make" tanpa tanda kutip pada direktori penyimpanan program untuk kompilasi program +3. Ketik "mpiexec -n <<jumlah node>> mpi_dijkstra" tanpa tanda kutip dan ubah <<jumlah node>> dengan jumlah node yang diinginkan. +4. Masukkan nilai n dengan syarat n>jumlah node dan n<=3000 +5. Program akan mengeluarkan runtime dari setiap node dan hasil jarak terpendek ada pada out.txt + +## Pembagian tugas +- Paulus : Membantu fungsi yang berhubungan dengan openmpi, Inisialisasi matriks, Percobaan pada server +- Harry : Membuat fungsi dijkstra, Membuat dijkstra serial + +## Jawaban Pertanyaan +### Solusi paralel +Solusi paralel pada program ini adalah program ini membagikan data menjadi beberapa bagian lalu, pada setiap node dijalankan djikstra untuk data yang diterima. Setelah itu setiap solusi lokal dari simpul digabung untuk dicari solusi globalnya yang menjadi jalur terpendek. + +### Analisis solusi +Solusi ini mungkin tidak terlalu baik dikarenakan memakan waktu juga pada saat mencari solusi global. Mungkin ada solusi yang lebih baik dimana proses mencari solusi globalnya bisa dipersingkat. + +### Jumlah thread +Jumlah thread yang digunakan adalah 2. Karena dari hasil percobaan, semakin sedikit thread, maka semakin cepat waktu kinerjanya Dikarenakan jika menggunakan 1 thread menyebabkan segmentation fault pada kasus n = 3000, maka kami menggunakan 2 thread. + +### Perbandingan dengan serial +Pada dijkstra serial, semuanya membutuhkan waktu yang lebih sedikit dibandingkan dijkstra paralel. Bisa dilihat dari folder img, foto trial_serial menunjukkan hasil percobaan data serial dan foto trial_100, trial_500, dll menunjukkan hasil foto paralel dengan np = 2. + +### Analisis perbandingan +Kemungkinan dijkstra paralel lebih lambat dikarenakan dijkstra paralel membutuhkan waktu yang sedikit lama untuk saling mengirim data antar thread, tetapi memiliki keuntungan dimana dijkstra paralel dapat mengerjakan kasus dengan jumlah n yang besar tanpa masalah. diff --git a/img/trial1.png b/img/trial1.png new file mode 100644 index 0000000000000000000000000000000000000000..af68afde69a571710dd7eaa6d0d7cd4ea2c3cb72 Binary files /dev/null and b/img/trial1.png differ diff --git a/img/trial3.png b/img/trial3.png new file mode 100644 index 0000000000000000000000000000000000000000..c38a2e266eba2c25ed40c78f00dd796ebd328489 Binary files /dev/null and b/img/trial3.png differ diff --git a/img/trial4.png b/img/trial4.png new file mode 100644 index 0000000000000000000000000000000000000000..22593f5aa953e0c094e4c08eff3d7925c507dafd Binary files /dev/null and b/img/trial4.png differ diff --git a/img/trial5.png b/img/trial5.png new file mode 100644 index 0000000000000000000000000000000000000000..def7b4fefd17ddd1c0991bbc98875fd30565a183 Binary files /dev/null and b/img/trial5.png differ diff --git a/img/trial6.png b/img/trial6.png new file mode 100644 index 0000000000000000000000000000000000000000..c99fe3b2a353e45b48560c9d10c75d63d5f100ca Binary files /dev/null and b/img/trial6.png differ diff --git a/img/trial_1000.png b/img/trial_1000.png new file mode 100644 index 0000000000000000000000000000000000000000..0fc637abb90da63ae525c45b9936c08f36ebe0dc Binary files /dev/null and b/img/trial_1000.png differ diff --git a/img/trial_100_1.png b/img/trial_100_1.png new file mode 100644 index 0000000000000000000000000000000000000000..64c23ed16d938bc58dd02ad8a58f48d6ed471210 Binary files /dev/null and b/img/trial_100_1.png differ diff --git a/img/trial_100_2.png b/img/trial_100_2.png new file mode 100644 index 0000000000000000000000000000000000000000..ae622770c4d483a2dbe403b80adac60775634d3d Binary files /dev/null and b/img/trial_100_2.png differ diff --git a/img/trial_100_3.png b/img/trial_100_3.png new file mode 100644 index 0000000000000000000000000000000000000000..1593f73be4808828cf86ee8e8b9e6b3aaa89f3a2 Binary files /dev/null and b/img/trial_100_3.png differ diff --git a/img/trial_3000.png b/img/trial_3000.png new file mode 100644 index 0000000000000000000000000000000000000000..0783b575e7c9d82626c4542a6d1d7d3b61021528 Binary files /dev/null and b/img/trial_3000.png differ diff --git a/img/trial_500.png b/img/trial_500.png new file mode 100644 index 0000000000000000000000000000000000000000..222d93864267476b51e874a6173026675a428ef3 Binary files /dev/null and b/img/trial_500.png differ diff --git a/img/trial_serial.png b/img/trial_serial.png new file mode 100644 index 0000000000000000000000000000000000000000..83c7456d754d46c6bd7024213186c89813117848 Binary files /dev/null and b/img/trial_serial.png differ diff --git a/mpi_dijkstra b/mpi_dijkstra new file mode 100755 index 0000000000000000000000000000000000000000..51f58458382ef380535e7d4cbd36bf87ab4f49d3 Binary files /dev/null and b/mpi_dijkstra differ diff --git a/out.txt b/out.txt new file mode 100644 index 0000000000000000000000000000000000000000..e5b1a83512c3c4a0951945d00ee50f2a2d68f215 --- /dev/null +++ b/out.txt @@ -0,0 +1,102 @@ + v dist 0->v +---- --------- + 1 23 + 2 20 + 3 20 + 4 44 + 5 5 + 6 18 + 7 27 + 8 18 + 9 4 + 10 51 + 11 23 + 12 34 + 13 55 + 14 23 + 15 19 + 16 15 + 17 21 + 18 28 + 19 16 + 20 10 + 21 13 + 22 23 + 23 33 + 24 32 + 25 31 + 26 10 + 27 31 + 28 21 + 29 45 + 30 45 + 31 48 + 32 28 + 33 25 + 34 20 + 35 39 + 36 13 + 37 24 + 38 11 + 39 46 + 40 37 + 41 22 + 42 14 + 43 29 + 44 40 + 45 29 + 46 30 + 47 28 + 48 20 + 49 65 + 50 12 + 51 16 + 52 57 + 53 87 + 54 18 + 55 51 + 56 40 + 57 21 + 58 2 + 59 22 + 60 21 + 61 69 + 62 23 + 63 23 + 64 7 + 65 47 + 66 54 + 67 29 + 68 42 + 69 19 + 70 33 + 71 39 + 72 41 + 73 26 + 74 68 + 75 8 + 76 35 + 77 25 + 78 3 + 79 28 + 80 29 + 81 45 + 82 16 + 83 20 + 84 36 + 85 45 + 86 12 + 87 24 + 88 73 + 89 23 + 90 29 + 91 39 + 92 21 + 93 8 + 94 44 + 95 61 + 96 55 + 97 20 + 98 52 + 99 41 + diff --git a/serial_dijkstra b/serial_dijkstra new file mode 100755 index 0000000000000000000000000000000000000000..bc47803ca296a41ad34058e0d1863fdc1a745609 Binary files /dev/null and b/serial_dijkstra differ diff --git a/src/func.c b/src/func.c index e2aa5e5ff85893016961ea4b55c570c989a6fe36..4ba3aa3e6daa869a30c2345a9f97481df0917a6c 100644 --- a/src/func.c +++ b/src/func.c @@ -1,206 +1,206 @@ -#include <stdio.h> -#include <stdlib.h> -#include </usr/include/mpi/mpi.h> -#include <time.h> -#include "func.h" -#define INFINITY 1000000 - -/* - Fungsi untuk membaca n (jumlah node yang akan digunakan) - */ -int Read_n(int rank, MPI_Comm com) { - int n; - if (rank == 0){ - scanf("%d", &n); - } - - MPI_Bcast(&n, 1, MPI_INT, 0, com); - return n; -} - -/* - Membuat MPI_Datatype yang merepresentasikan matriks - */ -MPI_Datatype Build_blk_col_type(int n_local, int n) { - MPI_Datatype first_bc_mpi_t; - MPI_Datatype block_mpi_t; - MPI_Datatype blk_col_mpi_t; - MPI_Aint lb, extent; - - MPI_Type_contiguous(n_local, MPI_INT, &block_mpi_t); - MPI_Type_get_extent(block_mpi_t, &lb, &extent); - - MPI_Type_vector(n, n_local, n, MPI_INT, &first_bc_mpi_t); - - MPI_Type_create_resized(first_bc_mpi_t, lb, extent, &blk_col_mpi_t); - - MPI_Type_commit(&blk_col_mpi_t); - - MPI_Type_free(&block_mpi_t); - MPI_Type_free(&first_bc_mpi_t); - - return blk_col_mpi_t; -} - -/* - Membuat sebuah matriks nxn yang mewakili graf. - Nilai M[i][j] = jarak dari node i ke j. - Jarak diinisialisasi dengan nilai random yang memiliki seed = 13517111. - */ -void Make_matrix(int tab_local[], int n_local, int n, - MPI_Datatype blk_col_mpi_t, int rank, MPI_Comm com) { - int upper = 1000; - int lower = 0; - int *mat = NULL, i, j; - - srand(13517111); - - if (rank == 0) { - mat = malloc(n * n * sizeof(int)); - for (i = 0; i < n; i++) { - for (j = 0; j < n; j++) { - if(j==i) { - mat[i * n + j] = 0; - } - else if (j>i){ - int x = (rand() % (upper - lower + 1)) + lower; - mat[i * n + j] = x; - mat[i + j * n] = x; - } - } - } - } - - MPI_Scatter(mat, 1, blk_col_mpi_t, tab_local, n * n_local, MPI_INT, 0, com); - - if (rank == 0) free(mat); -} - -/* - Mencari jarak minimum lokal dari titik 0 ke sebuah simpul - */ -int Find_jarak_min(int jarak_local[], int known_local[], int n_local) { - int jarak_terpendek = INFINITY; - int v_local; - int u_local = -1; - - for (v_local = 0; v_local < n_local; v_local++) { - if (!known_local[v_local]) { - if (jarak_local[v_local] < jarak_terpendek) { - jarak_terpendek = jarak_local[v_local]; - u_local = v_local; - } - } - } - return u_local; -} - -/* - Menuliskan setiap jarak dari titik 0 ke setiap simpul ke out.txt - */ -void Print_jarak(int jarak_global[], int n) { - int v; - FILE *fptr; - fptr = fopen("out.txt","w"); - if(fptr == NULL){ - printf("Error!"); - exit(1); - } - - fprintf(fptr," v dist 0->v\n"); - fprintf(fptr,"---- ---------\n"); - - for (v = 1; v < n; v++) { - if (jarak_global[v] != INFINITY) { - fprintf(fptr,"%3d %4d\n", v, jarak_global[v]); - } - else - fprintf(fptr,"%3d %5s\n", v, "inf"); - } - fprintf(fptr,"\n"); - fclose(fptr); -} - - -/* - Menginisialisasi setiap matriks yang ada pada nodes agar algoritmanya bisa berjalan. - */ -void Dijkstra_Init(int tab_local[], int pred_local[], int jarak_local[], int known_local[], - int rank, int n_local) { - int loc_v; - - if (rank == 0) - known_local[0] = 1; - else - known_local[0] = 0; - - for (loc_v = 1; loc_v < n_local; loc_v++) - known_local[loc_v] = 0; - - for (loc_v = 0; loc_v < n_local; loc_v++) { - jarak_local[loc_v] = tab_local[0 * n_local + loc_v]; - pred_local[loc_v] = 0; - } -} - -/* - Algoritma dijkstra untuk menghitung jarak terpendek dari simpul 0 ke setiap simpul lainnya. - */ -void Dijkstra(int tab_local[], int jarak_local[], int pred_local[], int n_local, int n, - MPI_Comm com) { - - int i, jarak_baru, rank, v_local, u_local, global_u, jarak_global_u; - int *known_local; - int min_global[2]; - int min[2]; - - MPI_Comm_rank(com, &rank); - known_local = malloc(n_local * sizeof(int)); - - Dijkstra_Init(tab_local, pred_local, jarak_local, known_local, rank, n_local); - - /* - Membuat loop sebanyak n-1 kali karena jarak terpendek node 0 ke 0 adalah 0 - */ - for (i = 0; i < n - 1; i++) { - u_local = Find_jarak_min(jarak_local, known_local, n_local); - - if (u_local == -1) { - min[0] = INFINITY; - min[1] = -1; - } - else { - min[0] = jarak_local[u_local]; - min[1] = u_local + rank * n_local; - } - - /* - Menyimpan jarak terpendek global dan nodenya dalam min_global - */ - MPI_Allreduce(min, min_global, 1, MPI_2INT, MPI_MINLOC, com); - - jarak_global_u = min_global[0]; - global_u = min_global[1]; - - if (global_u == -1) - break; - - if ((global_u / n_local) == rank) { - u_local = global_u % n_local; - known_local[u_local] = 1; - } - - for (v_local = 0; v_local < n_local; v_local++) { - if (!known_local[v_local]) { - jarak_baru = jarak_global_u + tab_local[global_u * n_local + v_local]; - if (jarak_baru < jarak_local[v_local]) { - pred_local[v_local] = global_u; - jarak_local[v_local] = jarak_baru; - } - } - } - } - free(known_local); -} - - +#include <stdio.h> +#include <stdlib.h> +#include </usr/include/mpi/mpi.h> +#include <time.h> +#include "func.h" +#define INFINITY 1000000 + +/* + Fungsi untuk membaca n (jumlah node yang akan digunakan) + */ +int Read_n(int rank, MPI_Comm com) { + int n; + if (rank == 0){ + scanf("%d", &n); + } + + MPI_Bcast(&n, 1, MPI_INT, 0, com); + return n; +} + +/* + Membuat MPI_Datatype yang merepresentasikan matriks + */ +MPI_Datatype Build_blk_col_type(int n_local, int n) { + MPI_Datatype first_bc_mpi_t; + MPI_Datatype block_mpi_t; + MPI_Datatype blk_col_mpi_t; + MPI_Aint lb, extent; + + MPI_Type_contiguous(n_local, MPI_INT, &block_mpi_t); + MPI_Type_get_extent(block_mpi_t, &lb, &extent); + + MPI_Type_vector(n, n_local, n, MPI_INT, &first_bc_mpi_t); + + MPI_Type_create_resized(first_bc_mpi_t, lb, extent, &blk_col_mpi_t); + + MPI_Type_commit(&blk_col_mpi_t); + + MPI_Type_free(&block_mpi_t); + MPI_Type_free(&first_bc_mpi_t); + + return blk_col_mpi_t; +} + +/* + Membuat sebuah matriks nxn yang mewakili graf. + Nilai M[i][j] = jarak dari node i ke j. + Jarak diinisialisasi dengan nilai random yang memiliki seed = 13517111. + */ +void Make_matrix(int tab_local[], int n_local, int n, + MPI_Datatype blk_col_mpi_t, int rank, MPI_Comm com) { + int upper = 1000; + int lower = 0; + int *mat = NULL, i, j; + + srand(13517111); + + if (rank == 0) { + mat = malloc(n * n * sizeof(int)); + for (i = 0; i < n; i++) { + for (j = 0; j < n; j++) { + if(j==i) { + mat[i * n + j] = 0; + } + else if (j>i){ + int x = (rand() % (upper - lower + 1)) + lower; + mat[i * n + j] = x; + mat[i + j * n] = x; + } + } + } + } + + MPI_Scatter(mat, 1, blk_col_mpi_t, tab_local, n * n_local, MPI_INT, 0, com); + + if (rank == 0) free(mat); +} + +/* + Mencari jarak minimum lokal dari titik 0 ke sebuah simpul + */ +int Find_jarak_min(int jarak_local[], int known_local[], int n_local) { + int jarak_terpendek = INFINITY; + int v_local; + int u_local = -1; + + for (v_local = 0; v_local < n_local; v_local++) { + if (!known_local[v_local]) { + if (jarak_local[v_local] < jarak_terpendek) { + jarak_terpendek = jarak_local[v_local]; + u_local = v_local; + } + } + } + return u_local; +} + +/* + Menuliskan setiap jarak dari titik 0 ke setiap simpul ke out.txt + */ +void Print_jarak(int n, int jarak_global[]) { + int v; + FILE *fptr; + fptr = fopen("out.txt","w"); + if(fptr == NULL){ + printf("Error!"); + exit(1); + } + + fprintf(fptr," v dist 0->v\n"); + fprintf(fptr,"---- ---------\n"); + + for (v = 1; v < n; v++) { + if (jarak_global[v] != INFINITY) { + fprintf(fptr,"%3d %4d\n", v, jarak_global[v]); + } + else + fprintf(fptr,"%3d %5s\n", v, "inf"); + } + fprintf(fptr,"\n"); + fclose(fptr); +} + + +/* + Menginisialisasi setiap matriks yang ada pada nodes agar algoritmanya bisa berjalan. + */ +void Dijkstra_Init(int tab_local[], int pred_local[], int jarak_local[], int known_local[], + int rank, int n_local) { + int loc_v; + + if (rank == 0) + known_local[0] = 1; + else + known_local[0] = 0; + + for (loc_v = 1; loc_v < n_local; loc_v++) + known_local[loc_v] = 0; + + for (loc_v = 0; loc_v < n_local; loc_v++) { + jarak_local[loc_v] = tab_local[0 * n_local + loc_v]; + pred_local[loc_v] = 0; + } +} + +/* + Algoritma dijkstra untuk menghitung jarak terpendek dari simpul 0 ke setiap simpul lainnya. + */ +void Dijkstra(int tab_local[], int jarak_local[], int pred_local[], int n_local, int n, + MPI_Comm com) { + + int i, jarak_baru, rank, v_local, u_local, global_u, jarak_global_u; + int *known_local; + int min_global[2]; + int min[2]; + + MPI_Comm_rank(com, &rank); + known_local = malloc(n_local * sizeof(int)); + + Dijkstra_Init(tab_local, pred_local, jarak_local, known_local, rank, n_local); + + /* + Membuat loop sebanyak n-1 kali karena jarak terpendek node 0 ke 0 adalah 0 + */ + for (i = 0; i < n - 1; i++) { + u_local = Find_jarak_min(jarak_local, known_local, n_local); + + if (u_local == -1) { + min[0] = INFINITY; + min[1] = -1; + } + else { + min[0] = jarak_local[u_local]; + min[1] = u_local + rank * n_local; + } + + /* + Menyimpan jarak terpendek global dan nodenya dalam min_global + */ + MPI_Allreduce(min, min_global, 1, MPI_2INT, MPI_MINLOC, com); + + jarak_global_u = min_global[0]; + global_u = min_global[1]; + + if (global_u == -1) + break; + + if ((global_u / n_local) == rank) { + u_local = global_u % n_local; + known_local[u_local] = 1; + } + + for (v_local = 0; v_local < n_local; v_local++) { + if (!known_local[v_local]) { + jarak_baru = jarak_global_u + tab_local[global_u * n_local + v_local]; + if (jarak_baru < jarak_local[v_local]) { + pred_local[v_local] = global_u; + jarak_local[v_local] = jarak_baru; + } + } + } + } + free(known_local); +} + + diff --git a/src/func.h b/src/func.h index b049ea796685d2298ebd1752ae45dbf02f6751cb..cf865724ac34887236e815c67c9c4f2cfa24c154 100644 --- a/src/func.h +++ b/src/func.h @@ -1,20 +1,20 @@ -#include <stdio.h> -#include <stdlib.h> -#include </usr/include/mpi/mpi.h> -#include <time.h> - -#ifndef FUNC_H -#define FUNC_H - -int Read_n(int rank, MPI_Comm com); -MPI_Datatype Build_blk_col_type(int n_local, int n); -void Make_matrix(int tab_local[], int n_local, int n, MPI_Datatype blk_col_mpi_t, - int rank, MPI_Comm com); -int Find_jarak_min(int jarak_local[], int known_local[], int n_local); -void Print_jarak(int n, int jarak_global[]); -void Dijkstra_Init(int tab_local[], int pred_local[], int jarak_local[], int known_local[], - int rank, int n_local); -void Dijkstra(int tab_local[], int jarak_local[], int pred_local[], int n_local, int n, - MPI_Comm com); - +#include <stdio.h> +#include <stdlib.h> +#include </usr/include/mpi/mpi.h> +#include <time.h> + +#ifndef FUNC_H +#define FUNC_H + +int Read_n(int rank, MPI_Comm com); +MPI_Datatype Build_blk_col_type(int n_local, int n); +void Make_matrix(int tab_local[], int n_local, int n, MPI_Datatype blk_col_mpi_t, + int rank, MPI_Comm com); +int Find_jarak_min(int jarak_local[], int known_local[], int n_local); +void Print_jarak(int n, int jarak_global[]); +void Dijkstra_Init(int tab_local[], int pred_local[], int jarak_local[], int known_local[], + int rank, int n_local); +void Dijkstra(int tab_local[], int jarak_local[], int pred_local[], int n_local, int n, + MPI_Comm com); + #endif \ No newline at end of file diff --git a/src/func.o b/src/func.o new file mode 100644 index 0000000000000000000000000000000000000000..51b0198a050ce4b4e69ca4d4a873f8f411141c63 Binary files /dev/null and b/src/func.o differ diff --git a/src/mpi_dijkstra.c b/src/mpi_dijkstra.c new file mode 100644 index 0000000000000000000000000000000000000000..e309a17939d0bf8749716ac5f0c33b22c5cdcaf7 --- /dev/null +++ b/src/mpi_dijkstra.c @@ -0,0 +1,60 @@ +#include <stdio.h> +#include <stdlib.h> +#include </usr/include/mpi/mpi.h> +#include <time.h> +#include "func.h" +#define INFINITY 1000000 + +int main(int argc, char **argv) { + // Inisialisasi setiap variabel yang digunakan + int n_local, n, my_rank, p; + int *mat_local, *pred_local, *jarak_local, *jarak_global = NULL, *global_pred = NULL; + double *time_mat; + MPI_Comm comm; + MPI_Datatype blk_col_mpi_t; + clock_t start, end; + double cpu_time_used; + // Inisiasi openmpi dan size dari variabel yang digunakan + MPI_Init(NULL, NULL); + comm = MPI_COMM_WORLD; + MPI_Comm_rank(comm, &my_rank); + MPI_Comm_size(comm, &p); + n = Read_n(my_rank, comm); + n_local = n / p; + mat_local = malloc(n * n_local * sizeof(int)); + pred_local = malloc(n_local * sizeof(int)); + jarak_local = malloc(n_local * sizeof(int)); + blk_col_mpi_t = Build_blk_col_type(n_local, n); + + if (my_rank == 0) { + jarak_global = malloc(n * sizeof(int)); + global_pred = malloc(n * sizeof(int)); + } + + // Membuat graf dalam bentuk matriks + Make_matrix(mat_local, n_local, n, blk_col_mpi_t, my_rank, comm); + // Memulai menghitung waktu + start = clock(); + // Memulai dijkstra untuk setiap node + Dijkstra(mat_local, jarak_local, pred_local, n_local, n, comm); + + /* Mengumpulkan hasil dari setiap node */ + MPI_Gather(jarak_local, n_local, MPI_INT, jarak_global, n_local, MPI_INT, 0, comm); + MPI_Gather(pred_local, n_local, MPI_INT, global_pred, n_local, MPI_INT, 0, comm); + + /* Menuliskan hasil ke dalam file out.txt */ + if (my_rank == 0) { + Print_jarak(n, jarak_global); + free(jarak_global); + free(global_pred); + } + free(mat_local); + free(pred_local); + free(jarak_local); + MPI_Type_free(&blk_col_mpi_t); + MPI_Finalize(); + end = clock(); + cpu_time_used = ((double) (end - start)) / CLOCKS_PER_SEC; + printf("Process in node %d use time : %f\n",my_rank,cpu_time_used); + return 0; +} \ No newline at end of file diff --git a/src/mpi_dijkstra.o b/src/mpi_dijkstra.o new file mode 100644 index 0000000000000000000000000000000000000000..73f8ba92e74b69f8bd68c8df6b857cbfd939f9e0 Binary files /dev/null and b/src/mpi_dijkstra.o differ diff --git a/src/serial_dijkstra.c b/src/serial_dijkstra.c new file mode 100644 index 0000000000000000000000000000000000000000..9eb6e9e772b4b6d92dc14ad2a7c3d3d3d283e76f --- /dev/null +++ b/src/serial_dijkstra.c @@ -0,0 +1,85 @@ +#include <stdio.h> +#include <time.h> +#include <stdlib.h> +#define INFINITY 9999 + +int main() +{ + int i,j,n,startnode; + clock_t start, end; + double cpu_time_used; + int upper = 1000; + int lower = 0; + scanf("%d",&n); + int **G = (int **)malloc(n * sizeof(int *)); + for (i=0; i<n; i++) + G[i] = (int *)malloc(n * sizeof(int)); + srand(13517111); + for (i = 0; i < n; i++) { + for (j = 0; j < n; j++) { + if(j>i) { + int x = (rand() % (upper - lower + 1)) + lower; + G[i][j] = x; + G[j][i] = x; + } + else if (i==j){ + G[i][j] = 0; + } + } + } + startnode = 0; + start = clock(); + int cost[n][n],distance[n],pred[n]; + int visited[n],count,mindistance,nextnode; + + //pred[] stores the predecessor of each node + //count gives the number of nodes seen so far + //create the cost matrix + for(i=0;i<n;i++) + for(j=0;j<n;j++) + if(G[i][j]==0) + cost[i][j]=INFINITY; + else + cost[i][j]=G[i][j]; + + //initialize pred[],distance[] and visited[] + for(i=0;i<n;i++) + { + distance[i]=cost[startnode][i]; + pred[i]=startnode; + visited[i]=0; + } + + distance[startnode]=0; + visited[startnode]=1; + count=1; + + while(count<n-1) + { + mindistance=INFINITY; + + //nextnode gives the node at minimum distance + for(i=0;i<n;i++) + if(distance[i]<mindistance&&!visited[i]) + { + mindistance=distance[i]; + nextnode=i; + } + + //check if a better path exists through nextnode + visited[nextnode]=1; + for(i=0;i<n;i++) + if(!visited[i]) + if(mindistance+cost[nextnode][i]<distance[i]) + { + distance[i]=mindistance+cost[nextnode][i]; + pred[i]=nextnode; + } + count++; + } + end = clock(); + cpu_time_used = ((double) (end - start)) / CLOCKS_PER_SEC; + printf("Time used : %f\n",cpu_time_used); + free(G); + return 0; +}