From 22aa748a28a58cbf418b70efded3a11dc449de25 Mon Sep 17 00:00:00 2001
From: 13513071 <13513071@hpc.if.itb.ac.id>
Date: Fri, 19 Feb 2016 14:00:27 +0700
Subject: [PATCH] Add bucketsort OpenMP

---
 laporan.txt |  34 ++++++++++++++
 sort.c      | 130 ++++++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 164 insertions(+)
 create mode 100644 laporan.txt
 create mode 100644 sort.c

diff --git a/laporan.txt b/laporan.txt
new file mode 100644
index 0000000..8ea8953
--- /dev/null
+++ b/laporan.txt
@@ -0,0 +1,34 @@
+Alexander Sukono	/ 	13513023
+Wilhelm Andrian 	/ 	13513071
+
+N : 50.000
+	M : 1	: 3.730 s
+		8	: 0.720 s
+		16	: 0.430 s
+		32	: 0.350 s
+		64	: 0.310 s
+		128	: 0.150 s
+
+N : 100.000
+	M : 1	: 15.910 s
+		8	: 2.080 s
+		16	: 1.790 s
+		32	: 1.150 s
+		64	: 0.900 s
+		128	: 0.400 s
+
+N : 200.000
+	M : 1	: 62.380 s
+		8	: 8.130 s
+		16	: 4.480 s
+		32	: 3.520 s
+		64	: 3.200 s
+		128	: 1.560 s
+
+N : 400.000
+	M : 1	: 227.270 s
+		8	: 30.630 s
+		16	: 16.380 s
+		32	: 10.170 s 
+		64	: 9.890 s
+		128	: 5.380 s
diff --git a/sort.c b/sort.c
new file mode 100644
index 0000000..c8151f2
--- /dev/null
+++ b/sort.c
@@ -0,0 +1,130 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <omp.h>
+#include <assert.h>
+#include <time.h>
+
+#define END -99
+
+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() % (num_elements - 1 + 1));
+    }
+  return rand_nums;
+}
+
+int get_sizes(int * array, int N, int M, int bagian){
+  int c;
+    int x = 0;
+    int n_per_bagian = (int)N/M;
+    int start = bagian * n_per_bagian;
+    int end = (bagian + 1) * n_per_bagian - 1;
+    for (c = 0; c < N; c++) {
+      if((array[c] >= start) && (array[c] <= end)){
+        x++;
+      }
+    }
+    return x;
+}
+
+
+int *get_bagian(int * array, int N, int M, int bagian, int *bucket_size){
+  int c;
+    int x = 0;
+    int * new_array = (int *)malloc(sizeof(int) * N);
+    int n_per_bagian = (int)N/M;
+    int start = bagian * n_per_bagian;
+    int end = (bagian + 1) * n_per_bagian - 1;
+    for (c = 0; c < N; c++) {
+        if((array[c] >= start) && (array[c] <= end)){
+          new_array[x] = array[c];
+      x++;
+  }
+    }
+    *bucket_size = x;
+    new_array[x] = END;
+    return new_array;
+}
+
+void InsertionSort(int *array, int num_elements){
+  int i=0;
+  int j;
+  int temp;
+ for(i = 0; i<num_elements;i++){
+    j = i;
+    while(j>0 && array[j] < array[j-1]){
+      temp    = array[j];
+      array[j]  = array[j-1];
+      array[j-1]  = temp;
+      j--;
+    }
+  }
+}
+
+void Sort(int *allnums, int num_element, int * hasil, int *bucket_start);
+
+int main(int argc, char *argv[]) {
+  clock_t start_t, end_t;
+  double total_t;
+
+  int num_element = strtol(argv[1], NULL, 10);
+  int thread_count = strtol(argv[2], NULL, 10);
+
+  int * randomnums  = create_rand_nums(num_element);
+  int * b = (int *)malloc(sizeof(int) *thread_count);
+  int * bucket_start = (int *)malloc(sizeof(int) *thread_count);
+  int i;
+  for (i = 0; i<thread_count;i++){
+    b[i] = get_sizes(randomnums,num_element, thread_count, i);
+  }
+  bucket_start[0] = 0;
+  for (i = 1; i<thread_count;i++){
+    b[i] = b[i-1]+b[i];
+    bucket_start[i] = b[i-1];
+  }
+/*
+  for (i = 0; i<thread_count;i++){
+    printf("%d ",bucket_start[i]);
+  }*/
+
+  int * hasil = (int *)malloc(sizeof(int) *num_element);
+
+  start_t = clock();
+
+  #pragma omp parallel num_threads(thread_count)
+  Sort(randomnums,num_element,hasil,bucket_start);
+
+  end_t = clock();
+
+  total_t = (double)(end_t - start_t) / CLOCKS_PER_SEC;
+  printf("Total time taken by CPU: %.3f\n", total_t  );
+
+  /*for(i = 0; i<num_element;i++){
+    printf("%d ", hasil[i]);
+  }*/
+  return 0;
+}
+
+void Sort(int *allnums, int num_element, int * hasil, int *bucket_start){
+
+  int my_rank = omp_get_thread_num();
+  int thread_count = omp_get_num_threads();
+
+  int bucket_size;
+  int * tmp = get_bagian(allnums, num_element, thread_count, my_rank, &bucket_size);
+  InsertionSort(tmp,bucket_size);
+  int i,count;
+  //printf("Rank = %d \n",my_rank);
+  int j = 0;
+
+  count = bucket_start[my_rank];
+  
+  for(i = count;i <count+bucket_size; i++){
+    hasil[i] = tmp[j];
+    j++;
+  }
+}
+
-- 
GitLab