diff --git a/.DS_Store b/.DS_Store
index ea1d8fcae3082442de5386a3a8dd2fa5cbd0955a..707c39b8ba9621345fc9797d7071c7eea90abfc7 100644
Binary files a/.DS_Store and b/.DS_Store differ
diff --git a/doc/README.md b/doc/README.md
new file mode 100644
index 0000000000000000000000000000000000000000..10acabed211b8da80e076e428023014ef500f139
--- /dev/null
+++ b/doc/README.md
@@ -0,0 +1,62 @@
+## Praktikum 02
+# OpenMPI - Radix Sort
+
+# How To
+Run `make` then open `sort` using `mpirun`
+
+# Pembagian Tugas
+13516100 - Putu Gery Wahyu Nugraha
+* Counting Sort
+* Radix Sort
+* All realted with MPIs
+* Doc and README
+
+13516091 - Yasya Rusyda Aslina
+* Desain solusi paralel
+* Testing
+
+# Deskripsi Solusi Paralel
+OpenMPI merupakan sebuah message passing interface, oleh karena itu kemampuan terbesarnya adalah mengirimkan pesan antar proses.
+
+Perlu dibuat sebuah solusi radix sort yang menggunakan sistem pengiriman pesan antar proses. Salah satu cara termudahnya adalah
+
+1. Bagi data yang akan di sort kepada setiap proses secara adil (data lokal)
+2. Hitung nilai count dari setiap data yang akan di sort
+3. Sort data lokal pada tiap-tiap proses
+4. Gabungkan semua data lokal yang ada dari proses
+5. Gabungkan nilai count dari tiap proses
+6. Lakukan sort secara global
+7. Ulangi langkah 1 
+
+Dari langkah-langkah tersebut
+
+* Langkah 1 bisa kita selesaikan dengan menggunakan `MPI_Scatter`
+* Langkah 4 bisa kita selesaikan dengan menggunakan `MPI_Gather`
+* Langkah 5 bisa kita selesaikan dengan menggunakan `MPI_Reduce` dan `MPI_SUM`
+
+# Analisis Solusi
+Setelah penulis menulis kode diatas, penulis menemukan banyak hal yang dapat diefektifkan. Salah satunya adalah bagaimana program ini melakukan sorting. Jika kita melihat langkah yang telah dideskripsikan diatas, maka kita menemukan bahwa: 
+* Sort dilakukan dua kali, dalam scope lokal dan scope global. Tidak efektif, kemungkinan besar bisa dilakukan sekali saja
+
+# Jumlah Thread yang Digunakan
+## 2
+Ketika melakukan pengerjaan melalui komputer pribadi, kami menemukan bahwa jika nilai thread lebih dari 2, ada kemungkinan program MPI tersebut stuck. Walaupun hal ini tidak pernah kami temukan di komputer remote. Maka dari itu untuk mendapatkan data yang konsisten kami memutuskan untuk menggunakan 2 thread saja
+
+# Pengukuran Kinerja
+| N | Size | 1     | 2 | 3 | avg |
+|---|------|-------|---|---|-----|
+| 1 | 5000 | 15145 | 15131 | 15273 | 15183 | 
+| 2 | 5000 | 40787 | 11316 | 5893  | 19332 |
+| 1 | 50000| 187103| 148275| 105336 | 146904 |
+| 2 | 50000| 89551 | 130345| 119153 | 113016 |
+| 1 |100000| 224312|154683 |154609 |177868 | 
+| 2 |100000| 217054|197716|150975|188581 |
+| 1 |200000|621111|629161|706030|652100 |
+| 2 |200000|304229|358362|302638|321743 |
+| 1 |400000|1142259|728879|1230207|1033781 |
+| 2 |400000|1339009|1217159|1199709|1251959 |
+
+# Analisis Pengukuran Kinerja
+Dari data kinerja diatas, sebenarnya kami lebih cenderung merasa bahwa faktor terbesar berkurangnya waktu bukanlah jumlah thread yang digunakan, tapi bagaimana kondisi cache dari prosesor. Walaupun dari data diatas dapat kita temukan perbedaan, tapi perbedaan tersebut sifatnya random dan tidak memiliki arah yang jelas. Oleh karena itu setiap pengurangan waktu yang terjadi ketika jumlah thread ditambahkan (atau penambahan waktu) lebih cenderung disebabkan oleh kondisi cache pada saat itu.
+
+Tapi karena radix sort parallel jauh lebih unggul ketika jumlah data banyak maka mungkin saja penurunan drastis yang terjadi ketika menggunakan dua thread ketika size = 200000 disebabkan oleh penggunaan parallel programming dan bukan kondisi cache saja.
diff --git a/src/.DS_Store b/src/.DS_Store
index 8d1c6ed5fdc8f98ecae7e03285b3580fa78ccedd..4912157825bb3ffe363aeada5f93b27d3b9d50db 100644
Binary files a/src/.DS_Store and b/src/.DS_Store differ
diff --git a/src/Makefile b/src/Makefile
index 544e8c26fc65071f1dd73af69516a4d916b9f3ae..1eff687026c9735f6c9e6554462c3dd01ab15663 100644
--- a/src/Makefile
+++ b/src/Makefile
@@ -1,2 +1,6 @@
-build:
-	gcc-8 -g -Wall -o radix_sort radix_sort.c -fopenmp -lm 
+all:
+	nvcc radix_sort_cuda.cu -o radix_sort_cuda
+
+clean:
+	rm -rf radix_sort_cuda
+	rm -rf radix_sort_cuda.exe
\ No newline at end of file
diff --git a/src/radix_par2.cpp b/src/radix_par2.cpp
deleted file mode 100644
index eae49a3713dec42e968c6d4cea75d8dcc9499f6f..0000000000000000000000000000000000000000
--- a/src/radix_par2.cpp
+++ /dev/null
@@ -1,118 +0,0 @@
-// C++ implementation of Radix Sort 
-#include <iostream> 
-#include <cstdlib>
-#include <time.h>
-using namespace std; 
-  
-// A utility function to get maximum value in arr[] 
-int getMax(int arr[], int n) 
-{ 
-    int mx = arr[0]; 
-    for (int i = 1; i < n; i++) 
-        if (arr[i] > mx) 
-            mx = arr[i]; 
-    return mx; 
-} 
-  
-// A function to do counting sort of arr[] according to 
-// the digit represented by exp. 
-__global__ void countSort(int arr[], int n, int exp) 
-{ 
-    int output[n]; // output array 
-    int i, count[10] = {0}; 
-  
-    // Store count of occurrences in count[] 
-    for (i = 0; i < n; i++) 
-        count[ (arr[i]/exp)%10 ]++; 
-  
-    // Change count[i] so that count[i] now contains actual 
-    //  position of this digit in output[] 
-    for (i = 1; i < 10; i++) 
-        count[i] += count[i - 1]; 
-  
-    // Build the output array 
-    for (i = n - 1; i >= 0; i--) 
-    { 
-        output[count[ (arr[i]/exp)%10 ] - 1] = arr[i]; 
-        count[ (arr[i]/exp)%10 ]--; 
-    } 
-  
-    // Copy the output array to arr[], so that arr[] now 
-    // contains sorted numbers according to current digit 
-    for (i = 0; i < n; i++) 
-        arr[i] = output[i]; 
-} 
-  
-// The main function to that sorts arr[] of size n using  
-// Radix Sort 
-void radixsort(int arr[], int n) 
-{ 
-    int *d_arr;
-    // Find the maximum number to know number of digits 
-    int m = getMax(arr, n); 
-  
-    // Do counting sort for every digit. Note that instead 
-    // of passing digit number, exp is passed. exp is 10^i 
-    // where i is current digit number 
-
-    cudaMalloc((void**)&d_arr,sizeof(int)*n);
-    cudaMemcpy(d_arr, arr, sizeof(int)*n,cudaMemcpyHostToDevice);
- 
-    for (int exp = 1; m/exp > 0; exp *= 10) {
-        countSort<<<1,32>>>(arr, n, exp);
-        cudaMemcpy(arr, d_arr, sizeof(int)*n, cudaMemcpyDeviceToHost);
-    }
-
-    cudaFree(d_arr); 
-} 
-  
-// A utility function to print an array 
-void print(int arr[], int n) 
-{ 
-    for (int i = 0; i < n; i++) 
-        cout << arr[i] << "\n"; 
-} 
-  
-void rng(int* arr,int n){
-    int seed = 13516067;
-    srand(seed);
-    for (long i=0; i<n; i++){
-        arr[i] = (int) rand();
-    }
-}
-
- 
-timespec diff(timespec start, timespec end)
-{
-    timespec temp;
-    if ((end.tv_nsec - start.tv_nsec) < 0) {
-        temp.tv_sec = end.tv_sec - start.tv_sec - 1;
-        temp.tv_nsec = 1000000000 + end.tv_nsec - start.tv_nsec;
-    } else {
-        temp.tv_sec = end.tv_sec - start.tv_sec;
-        temp.tv_nsec = end.tv_nsec - start.tv_nsec;
-    }
-    return temp;
-}
-
-// Driver program to test above functions 
-int main() 
-{ 
-    timespec start, stop;
-    
-    int n;
-    cout<<"Masukkan nilai N\n";
-    cin>>n;
-    int arr[n];
-    rng(arr,n);
-    clock_gettime(CLOCK_REALTIME, &start);
-    radixsort(arr,n);
-    clock_gettime(CLOCK_REALTIME, &stop);
-    print(arr,n);
-    
-    timespec duration = diff(start, stop);
-    long time = duration.tv_sec * 1000000 + duration.tv_nsec/1000;
-    printf("\n%d.%09d s\n", duration.tv_sec, duration.tv_nsec);
-    
-    return 0; 
-} 
\ No newline at end of file
diff --git a/src/radix_par2.cu b/src/radix_sort_cuda.cu
similarity index 100%
rename from src/radix_par2.cu
rename to src/radix_sort_cuda.cu