diff --git a/mergesort.c b/mergesort.c index 1185267936d027adfd879e9b911594de9b576f6f..aa92d02bf52c65240e7af8209e4d772acb6500a1 100644 --- a/mergesort.c +++ b/mergesort.c @@ -1,91 +1,104 @@ #include <stdlib.h> +#include <string.h> #include <mpi.h> #include <stdio.h> -void merge(int* arr, int l, int m, int r, int* tmp) +void merge(int* arr1, int* arr2, int size1, int size2) { - int last = l; + int *tmp = (int*) malloc(sizeof(int) * (size1 + size2)); + int last = 0; // merge to tmp - int i = l, j = m; - for (; i < m && j < r;) + int i = 0, j = 0; + for (; i < size1 && j < size2;) { - if (arr[i] > arr[j]) - tmp[last++] = arr[j++]; + if (arr1[i] > arr2[j]) + tmp[last++] = arr2[j++]; else - tmp[last++] = arr[i++]; + tmp[last++] = arr1[i++]; } - while (i < m) tmp[last++] = arr[i++]; - while (j < r) tmp[last++] = arr[j++]; + while (i < size1) tmp[last++] = arr1[i++]; + while (j < size2) tmp[last++] = arr2[j++]; // move to origin - while (last > l) + for(int i = 0; i < last; ++i) { - --last; - arr[last] = tmp[last]; + arr1[i] = tmp[i]; } + + free(tmp); } -void mergesort(int* arr, int l, int r, int* tmp) +void mergesort(int* arr, int l, int r) { if (l + 2 > r) return; // base int m = (l + r) >> 1; - mergesort(arr, l, m, tmp); - mergesort(arr, m, r, tmp); - merge(arr, l, m, r, tmp); + mergesort(arr, l, m); + mergesort(arr, m, r); + merge(arr+l, arr+m, m-l, r-m); } int main(int argc, char *argv[]) { - int n, i; - scanf("%d", &n); - - int *arr = (int*) malloc(sizeof(int) * (n + 1)); - for (i = 0; i < n; ++i) - { - scanf("%d", &arr[i]); - } - + int n = 0, i; + int world_rank; int world_size; - + MPI_Init(&argc, &argv); MPI_Comm_rank(MPI_COMM_WORLD, &world_rank); MPI_Comm_size(MPI_COMM_WORLD, &world_size); - int size = n / world_size; // equally distributed - - int *arr_part = (int*) malloc(sizeof(int) * size); - MPI_Scatter(arr, size, MPI_INT, arr_part, size, MPI_INT, 0, MPI_COMM_WORLD); // scatter to buckets - - int *tmp = (int*) malloc(sizeof(int) * size); - mergesort(arr_part, 0, size, tmp); - - int *sorted = NULL; - if(world_rank == 0) { - sorted = malloc(n * sizeof(int)); + if (!world_rank) scanf("%d", &n); + int size = (n + world_size - 1) / world_size; // equally distributed + int N = size * world_size; + + int *arr = (int*) malloc(sizeof(int) * N); + memset(arr, 127, sizeof(int) * N); + if (!world_rank) { + for (i = 0; i < n; ++i) scanf("%d", &arr[i]); + } + + world_rank++; // 1-based + MPI_Bcast(&size, 1, MPI_INT, 0, MPI_COMM_WORLD); + MPI_Scatter(arr, size, MPI_INT, + arr, size, MPI_INT, + 0, MPI_COMM_WORLD); // scatter to buckets + + mergesort(arr, 0, size); + + int x = 1; + MPI_Status stat; + char isSend = 0; + while (x < world_size) + { + if (world_rank & x == x) + { + MPI_Send(arr, size, MPI_INT, world_rank + x, world_rank + x, MPI_COMM_WORLD); + isSend = 1; + } else + { + if (isSend) continue; + + MPI_Recv(arr, size, MPI_INT, world_rank + x, world_rank + x, MPI_COMM_WORLD, &stat); + merge(arr, arr+size, size, size); + size <<= 1; + } + + x <<= 1; } - MPI_Gather(arr_part, size, MPI_INT, sorted, size, MPI_INT, 0, MPI_COMM_WORLD); // gather result - - if(world_rank == 0) + if (world_rank == world_size) { - int *tmp2 = (int*) malloc(sizeof(int) * n); - mergesort(sorted, 0, n, tmp2); - for(i = 0; i < n; i++) { - printf("%d ", sorted[i]); - } + printf("%d ", arr[i]); + } + puts(""); - free(sorted); - free(tmp2); } - free(arr); - free(arr_part); - free(tmp); MPI_Barrier(MPI_COMM_WORLD); MPI_Finalize(); diff --git a/mpi_hostfile b/mpi_hostfile index 2441373bc37c202811a0d4e4ba0d6124963703a6..068dea3a6b768e124ad7389e57cb1e45f1724cc7 100644 --- a/mpi_hostfile +++ b/mpi_hostfile @@ -1,9 +1,9 @@ #daftar host localhost #167.205.35.26 -167.205.35.28 -167.205.35.29 -167.205.35.30 +#167.205.35.28 +#167.205.35.29 +#167.205.35.30 #167.205.35.31 #167.205.35.32 #167.205.35.33 diff --git a/sort b/sort index 21dd03803e7224f096748d72f4f26a482cdc5cd7..65828fb6fe8ce8d368ef1f1eb2c57df82c1ced10 100755 Binary files a/sort and b/sort differ