diff --git a/bucketsort.c b/bucketsort.c index 6efa026044025b5be61b0cf517a60f406549f828..da4a7bcb31e6fa31524bd341775c79b0b281924d 100644 --- a/bucketsort.c +++ b/bucketsort.c @@ -10,93 +10,123 @@ int *create_rand_nums(int num_elements) { int i; for (i = 0; i < num_elements; i++) { - rand_nums[i] = (rand() / (int)RAND_MAX); + rand_nums[i] = (rand() % num_elements); } return rand_nums; } -void sort(int n, int* array[]) { +int* sort(int n, int* ar) { int c, d, t; + int* array = ar; 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; + t = array[d]; + array[d] = array[d-1]; + array[d-1] = t; d--; } } + + return array; } int main(int argc, char** argv) { MPI_Status stat; - int* bucky; - - if (argc != 2) { - fprintf(stderr, "Usage: avg num_elements_per_proc\n"); + int num_elements = atoi(argv[1]); + int* bucky = (int *)malloc(sizeof(int) * num_elements); + int bucky_count = 0; + double starttime, endtime; + int* results = (int *)malloc(sizeof(int) * num_elements); + + if (argc != 2) { exit(1); } - int num_elements = atoi(argv[1]); srand(time(NULL)); 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; int range = 0; int bucket_loc = 0; int rand_num = 0; - int buckets[world_size][num_elements]; - int bucket_count[world_size]; - - if (world_rank == 0) { - rand_nums = create_rand_nums(num_elements-1); - - range = num_elements/world_size; + int buckets[world_size-1][num_elements]; + int bucket_count[world_size-1]; + + rand_nums = create_rand_nums(num_elements); + if (world_size == 1) { + starttime = MPI_Wtime(); + results = sort(num_elements, rand_nums); + } else { + if (world_rank == 0) { + + range = (num_elements+world_size-1-1)/(world_size-1); - for (int i=0; i < world_size; i++) { - bucket_count[i] = 0; - } + for (int i=0; i < world_size-1; i++) { + bucket_count[i] = 0; + } - for (int i=0; i < sizeof(rand_nums); i++) { - rand_num = rand_nums[i]; - bucket_loc = rand_num/range; - buckets[bucket_loc][bucket_count[bucket_loc]] = rand_num; - bucket_count[bucket_loc]++; - } + for (int i=0; i < num_elements; i++) { + rand_num = rand_nums[i]; + bucket_loc = rand_num/range; + buckets[bucket_loc][bucket_count[bucket_loc]] = rand_num; + bucket_count[bucket_loc]++; + } - for (int i=1; i < world_size; i++) { - MPI_Send(&buckets[i],bucket_count[i],MPI_INT, i, 1, MPI_COMM_WORLD); + starttime = MPI_Wtime(); + + for (int i=1; i < world_size; i++) { + MPI_Send(&bucket_count[i-1],1,MPI_INT, i, 1, MPI_COMM_WORLD); + MPI_Send(buckets[i-1],bucket_count[i-1],MPI_INT, i, 2, MPI_COMM_WORLD); + } + } + + int* new_bucky; + if (world_rank != 0) { + MPI_Recv(&bucky_count,1,MPI_INT,0,1,MPI_COMM_WORLD, &stat); + MPI_Recv(bucky, bucky_count, MPI_INT, 0, 2, MPI_COMM_WORLD, &stat); + + new_bucky = sort(bucky_count, bucky); } - } else { - MPI_Recv(&bucky, bucket_count[world_rank], MPI_INT, 0, 1, MPI_COMM_WORLD, &stat); - - sort(sizeof(bucky), &bucky); - - } - - MPI_Gather(&bucky, sizeof(bucky), MPI_INT, buckets[world_rank], sizeof(bucky), MPI_INT, 0, MPI_COMM_WORLD); - printf("Sorted list in ascending order:\n"); - - for (int c = 0; c < world_size; c++) { - for (int d = 0; d < bucket_count[c]; d++) { - printf("%d\n", buckets[c][d]); + + int count[world_size]; + count[0] = 0; + for(int i=1; i < world_size; i++) { + count[i] = bucket_count[i-1]; + } + + int dspls[world_size]; + dspls[0] = 0; + dspls[1] = 0; + for(int i=2; i<world_size; i++) { + dspls[i] = dspls[i-1]+bucket_count[i-2]; } + + MPI_Gatherv(new_bucky, bucky_count, MPI_INT, results, count, dspls, MPI_INT, 0, MPI_COMM_WORLD); + } + + if (world_rank ==0) { + printf("Sorted list in ascending order:\n"); + for (int d = 0; d < num_elements; d++) { + printf("%d \n", results[d]); + } + endtime = MPI_Wtime(); + double time = endtime - starttime; + printf("Running time: %.5f\n", time); } MPI_Finalize(); - }