diff --git a/LaporanPraktikum2SisterTerintegrasi.pdf b/LaporanPraktikum2SisterTerintegrasi.pdf new file mode 100644 index 0000000000000000000000000000000000000000..dfe171a84041f8b17c5194ae0c77449e479ccec5 Binary files /dev/null and b/LaporanPraktikum2SisterTerintegrasi.pdf differ diff --git a/mpi_hostfile b/mpi_hostfile new file mode 100644 index 0000000000000000000000000000000000000000..0939f2a584be71b5cff495c488f03671a8582391 --- /dev/null +++ b/mpi_hostfile @@ -0,0 +1,8 @@ +#daftar host +localhost +167.205.35.26 +167.205.35.28 +167.205.35.29 +167.205.35.30 +167.205.35.31 + diff --git a/solution b/solution new file mode 100644 index 0000000000000000000000000000000000000000..babae7f03bb7d006e930247ffef35303be5a8f32 Binary files /dev/null and b/solution differ diff --git a/solution.c b/solution.c new file mode 100644 index 0000000000000000000000000000000000000000..ad9e314362c4f92add64b8319f2358e32b3f4011 --- /dev/null +++ b/solution.c @@ -0,0 +1,123 @@ +#include <stdio.h> +#include <stdlib.h> +#include <mpi.h> +#include <assert.h> +#include <unistd.h> +#include <time.h> + +int* create_random(int num) { + int* ret = (int*) malloc(sizeof(int) * num); + int i; + for(i = 0; i < num; i++) { + ret[i] = rand() % 100000; + } + return ret; +} + +void merge_sort(int* a, int n) { + if(n <= 1) return; + int mid = (n - 1) / 2; + merge_sort(a, mid + 1); + merge_sort(a + mid + 1, n - mid - 1); + int l = 0, r = mid + 1, pt = 0; + int* temp = (int*) malloc(sizeof(int) * n); + while(l <= mid && r < n) { + if(a[l] < a[r]) temp[pt++] = a[l++]; + else temp[pt++] = a[r++]; + } + while(l <= mid) temp[pt++] = a[l++]; + while(r < n) temp[pt++] = a[r++]; + for(l = 0; l < n; l++) a[l] = temp[l]; + free(temp); +} + +void sort(int* a, int n) { + int i, j, t; + for(i = 0; i < n; i++) { + for(j = i + 1; j < n; j++) { + if(a[i] > a[j]) { + t = a[i]; + a[i] = a[j]; + a[j] = t; + } + } + } +} + +int main(int argc, char** argv) { + if(argc != 2) { + fprintf(stderr, "Usage: num_elements"); + return 0; + } + int n = atoi(argv[1]); + + int world_size, world_rank; + MPI_Status Stat; + MPI_Init(&argc, &argv); + MPI_Comm_size(MPI_COMM_WORLD, &world_size); + MPI_Comm_rank(MPI_COMM_WORLD, &world_rank); + + printf("Hello from rank %d\n", world_rank); + + int* num_bucket = (int*) malloc(sizeof(int) * world_size); + int i, j; + if(world_rank == 0) { + clock_t begin = clock(); + int* a = create_random(n); + printf("Done randomized\n"); + printf("Raw : "); + for(i = 0; i < n; i++) printf("%d ", a[i]); + printf("\n"); + int mn = 2000000000; + int mk = -2000000000; + for(i = 0; i < n; i++) { + if(a[i] > mk) mk = a[i]; + if(a[i] < mn) mn = a[i]; + } + int range = mk - mn; + int leap = range / world_size + 1; + int* this = (int*) malloc(sizeof(int) * n); + int* cur = (int*) malloc(sizeof(int) * n); + for(i = 0; i < world_size; i++) num_bucket[i] = 0; + for(j = 0; j < world_size; j++) { + for(i = 0; i < n; i++) { + if(mn + j*leap <= a[i] && a[i] < mn + (j + 1)*leap) { + cur[num_bucket[j]++] = a[i]; + //printf("%d (%d) belong to %d\n", a[i], i, j); + } + } + if(j == 0) { + for(i = 0; i < num_bucket[j]; i++) this[i] = cur[i]; + } else { + MPI_Send(num_bucket + j, 1, MPI_INT, j, 1000 + j, MPI_COMM_WORLD); + MPI_Send(cur, num_bucket[j], MPI_INT, j, j, MPI_COMM_WORLD); + } + } + merge_sort(this, num_bucket[0]); + int cnt = 0; + int all = 0; + for(i = 0; i < world_size; i++) { + all += num_bucket[i]; + if(i) MPI_Recv(this, num_bucket[i], MPI_INT, i, n + i, MPI_COMM_WORLD, &Stat); + for(j = 0; j < num_bucket[i]; j++) { + a[cnt++] = this[j]; + } + } + assert(all == n); + printf("Sorted: "); + for(i = 0; i < n; i++) printf("%d ", a[i]); + printf("\n"); + clock_t end = clock(); + printf("Running time (ms) : %lf\n", (double)(end - begin) *1000 / CLOCKS_PER_SEC); + } else { + int size_bucket; + MPI_Recv(&size_bucket, 1, MPI_INT, 0, 1000 + world_rank, MPI_COMM_WORLD, &Stat); + int* a = (int*) malloc(sizeof(int) * size_bucket); + MPI_Recv(a, size_bucket, MPI_INT, 0, world_rank, MPI_COMM_WORLD, &Stat); + merge_sort(a, size_bucket); + MPI_Send(a, size_bucket, MPI_INT, 0, n + world_rank, MPI_COMM_WORLD); + } + MPI_Finalize(); + return 0; +} +