diff --git a/bucketsort b/bucketsort index 312e0c6cd112f55f320d962c10984ea65836599b..a9dd48c1944c1c36b1222002c0339ad5f19dbfb2 100755 Binary files a/bucketsort and b/bucketsort differ diff --git a/bucketsort.c b/bucketsort.c index 8db1f9362fee1614598043ed7d01b2937dfd51be..b2f89d6720ced4574267d99f10318938c26d1928 100644 --- a/bucketsort.c +++ b/bucketsort.c @@ -1,93 +1,160 @@ -#include <stdio.h> #include <stdlib.h> -#include <mpi.h> -#include <assert.h> - - -int *create_rand_nums(int num_elements) { - int *rand_nums = (int *)malloc(sizeof(int) * num_elements); - assert(rand_nums != NULL); - int i; - for (i = 0; i < num_elements; i++) { - rand_nums[i] = (int)(rand() / (int)RAND_MAX); - } - return rand_nums; -} - +#include <time.h> +#include <stdio.h> +#include <string.h> +#include "mpi.h" +#ifndef ElmtMaks +#define ElmtMaks 100 +#endif -int *sort(int * array, int n){ +typedef struct Bucket { + int* content; + int n_elmt; +} Bucket; - int c,d,t; - for (c = 1 ; c <= n - 1; c++) { - d = c; - - while ( d > 0 && array[d] < array[d-1]) { - t = array[d]; - array[d] = array[d-1]; - array[d-1] = t; - d--; - } - } - - printf("Sorted list in ascending order:\n"); - - for (c = 0; c <= n - 1; c++) { - printf("%d\n", array[c]); - } - - return array; +int *copyArray(int const * oldArray, size_t size) { + int * newArray = malloc(sizeof(int) * size); + memcpy(newArray, oldArray, sizeof(int) * size); + return newArray; } +int *sort(int *array,int n){ + int d,c,t; + for (c = 1 ; c <= n - 1; c++) { + d = c; + while ( d > 0 && array[d] < array[d-1]) { + t = array[d]; + array[d] = array[d-1]; + array[d-1] = t; + d--; + } + } + return array; +} -int main(int argc, char** argv){ - if(argc != 2){ - fprintf(stderr, "Usage: bucketsort N M\n"); - exit(1); - } - - int num_elmt = atoi(argv[1]); - int m = atoi(argv[2]); - - MPI_Init(NULL, NULL); - - int world_rank; - MPI_Comm_rank(MPI_COMM_WORLD, &world_rank); - int world_size; - MPI_Comm_size(MPI_COMM_WORLD, &world_size); - - int * rand_nums = NULL; - if(world_rank == 0){ - create_rand_nums(num_elmt); - } - - int *sub_rand_nums = (int *) malloc(sizeof(int) * num_elmt); - assert(sub_rand_nums != NULL); - - MPI_Scatter(rand_nums, num_elmt, MPI_INT, sub_rand_nums, num_elmt, MPI_INT, 0, MPI_COMM_WORLD); - - int * sub_sort = sort(sub_rand_nums,num_elmt); - - int * sub_sorts = NULL; - if(world_rank == 0){ - sub_sorts = (int *)malloc(sizeof(int) * world_size); - assert(sub_sorts != NULL); - } - MPI_Gather(&sub_sort, 1, MPI_INT, sub_sorts, 1, MPI_INT, 0, MPI_COMM_WORLD); - - if(world_rank == 0){ - int * sorted = sort(sub_sorts, num_elmt); - printf("Sorted elmt = "); - - } - - if(world_rank == 0){ - free(rand_nums); - free(sub_sorts); - - } - - MPI_Barrier(MPI_COMM_WORLD); - MPI_Finalize(); +void printElmt (int *array, int size) { + int i; + for (i = 0; i < size; i++) { + printf("%d\n", array[i]); + } } + +int main(int argc, char *argv[]) { + if(argc != 3){ + fprintf(stderr, "Usage: bucketsort N(jumlah elemen) M(jumlah bucket)\n"); + exit(1); + } + + /* get input */ + int N = atoi(argv[1]); + int M = atoi(argv[2]); + + /* timer variable */ + double start_time, end_time; + start_time = end_time = 0; + + /* MPI */ + MPI_Init(NULL, NULL); + int world_rank, world_size; + MPI_Comm_rank(MPI_COMM_WORLD, &world_rank); + MPI_Comm_size(MPI_COMM_WORLD, &world_size); + + /* Bucket */ + int *random_numbers = NULL; + Bucket *myBucket = NULL; + + if (world_rank == 0) { + int i; + int *randomNumbers = (int *) malloc(sizeof(int) * N); + srand(time(NULL)); + for (i = 0; i < N; i++ ) { + randomNumbers[i] = (rand() % ElmtMaks) + 1; + } + random_numbers = randomNumbers; + + + myBucket = (Bucket *) malloc(sizeof(Bucket) * M); + + int n = (ElmtMaks / M) + 1; + + int j,k; + for (i = 0; i < M; i++) { + k = 0; + int *t = (int *) malloc(sizeof(int) * N); + for (j = 0; j < N; j++) { + if (( random_numbers[j] >= i * n ) &&( random_numbers[j] < (i * n) + n )){ + t[k] = random_numbers[j]; + k++; + } + } + myBucket[i].n_elmt = k; + myBucket[i].content = copyArray(t, k); + free(t); + } + + i = 0; + + if(M < world_size) + world_size = M; + + int *sorted_nums[world_size]; + int sorted_size[world_size]; + + int *sorted_zero = sort(myBucket[0].content, myBucket[0].n_elmt); + sorted_nums[0] = copyArray(sorted_zero, myBucket[0].n_elmt); + sorted_size[0] = myBucket[0].n_elmt; + + /* start counting time */ + start_time = MPI_Wtime(); + + if(M == 1){ + sorted_nums[0] = sort(random_numbers,N); + } else { + for (i = 1; i < world_size; i++) { + MPI_Send(&myBucket[i].n_elmt, 1, MPI_INT, i, 0, MPI_COMM_WORLD); + MPI_Send(myBucket[i].content, myBucket[i].n_elmt, MPI_INT, i, 1, MPI_COMM_WORLD); + } + for (i = 1; i < world_size; i++) { + int received_elmts = 0; + int *received_array = (int *) malloc(sizeof(int) * N); + + MPI_Recv(&received_elmts, 1, MPI_INT, i, 0, MPI_COMM_WORLD, MPI_STATUS_IGNORE ); + MPI_Recv(received_array, received_elmts, MPI_INT, i, 1, MPI_COMM_WORLD, MPI_STATUS_IGNORE ); + + sorted_nums[i] = copyArray(received_array, received_elmts); + sorted_size[i] = received_elmts; + } + } + + /* End counting time */ + end_time = MPI_Wtime(); + double elapsed_time = end_time-start_time; + + /* Print Sorted */ + for (i = 0; i < world_size; i++) { + //printf("Hasil dari bucket ke-%d",i); + printElmt(sorted_nums[i], sorted_size[i]); + } + + /* Print waktu */ + printf("Total Waktu: %G detik\n", elapsed_time); + //printf("Jumlah Elemen %d, Jumlah Bucket %d", N, M); + } else { + int received_elmts; + int *received_array = (int *) malloc(sizeof(int) * N); + + /* Get partitioned array from root */ + MPI_Recv(&received_elmts, 1, MPI_INT, 0, 0, MPI_COMM_WORLD, MPI_STATUS_IGNORE ); + MPI_Recv(received_array, received_elmts, MPI_INT, 0, 1, MPI_COMM_WORLD, MPI_STATUS_IGNORE ); + + /* Sort Array */ + int *sorted_array = sort(received_array, received_elmts); + + /* Send sorted to root */ + MPI_Send(&received_elmts, 1, MPI_INT, 0, 0, MPI_COMM_WORLD); + MPI_Send(sorted_array, received_elmts, MPI_INT, 0, 1, MPI_COMM_WORLD); + } + MPI_Finalize(); +} diff --git a/mpi_hostfile b/mpi_hostfile new file mode 100644 index 0000000000000000000000000000000000000000..1aab781c29869ebddbe342b46de587fe30d3c24d --- /dev/null +++ b/mpi_hostfile @@ -0,0 +1,7 @@ +#daftar host +localhost +167.205.35.26 +167.205.35.28 +167.205.35.29 +167.205.35.30 +167.205.35.31