#include #include #include #include #include "mpi.h" void High(int bit); void Low(int bit); int Comparison(const void * x, const void * y); #define MASTER 0 #define NUMBER 10 int * array; int array_size; int process_rank; int num_processes; double start_time; double end_time; int main(int argc, char * argv[]) { MPI_Init(&argc, &argv); MPI_Comm_size(MPI_COMM_WORLD, &num_processes); MPI_Comm_rank(MPI_COMM_WORLD, &process_rank); array_size = atoi(argv[1]) / num_processes; array = (int *)malloc(array_size * sizeof(int)); srand(time(NULL)); int i, j; for (i = 0; i < array_size; i++) { array[i] = rand() % (atoi(argv[1])); } MPI_Barrier(MPI_COMM_WORLD); int stages = (int)(log2(num_processes)); if (process_rank == MASTER) { printf("Number of Processes is: %d\n", num_processes); timer_start = MPI_Wtime(); } qsort(array, array_size, sizeof(int), Comparison); for (i = 0; i < stages; i++) { for (j = i; j >= 0; j--) { printf("%d ",process_rank>>(i+1)); if (((process_rank >> (i + 1)) % 2 == 0 && (process_rank >> j) % 2 == 0) || ((process_rank >> (i + 1)) % 2 != 0 && (process_rank >> j) % 2 != 0)) { Low(j); } else { High(j); } } } MPI_Barrier(MPI_COMM_WORLD); if (process_rank == MASTER) { end_time = MPI_Wtime(); printf("Sample sorted array for verification(10 elements)\n"); for (i = 0; i < array_size; i++) { if ((i % (array_size / NUMBER)) == 0) { printf("%d ", array[i]); } } printf("Time in seconds : %f\n", end_time - start_time); } free(array); MPI_Finalize(); return 0; } void High(int j) { int i, max; int counter_receive; int * buffer_recieve = (int *)malloc((array_size + 1) * sizeof(int)); MPI_Recv(&max, 1, MPI_INT, process_rank ^ (1 << j), 0, MPI_COMM_WORLD, MPI_STATUS_IGNORE ); int counter_send = 0; int * buffer_send = (int *)malloc((array_size + 1) * sizeof(int)); MPI_Send(&array[0], 1, MPI_INT, process_rank ^ (1 << j), 0, MPI_COMM_WORLD); for (i = 0; i < array_size; i++) { if (array[i] < max) { buffer_send[counter_send + 1] = array[i]; counter_send++; } else { break; } } MPI_Recv(buffer_recieve, array_size, MPI_INT, process_rank ^ (1 << j), 0, MPI_COMM_WORLD, MPI_STATUS_IGNORE ); counter_receive = buffer_recieve[0]; buffer_send[0] = counter_send; MPI_Send(buffer_send, counter_send, MPI_INT, process_rank ^ (1 << j), 0, MPI_COMM_WORLD); for (i = 1; i < counter_receive + 1; i++) { if (buffer_recieve[i] > array[0]) { array[0] = buffer_recieve[i]; } else { break; } } qsort(array, array_size, sizeof(int), ComparisonFunc); free(buffer_send); free(buffer_recieve); } void Low(int j) { int i, min; int counter_send = 0; int * buffer_send = (int *)malloc((array_size + 1) * sizeof(int)); MPI_Send(&array[array_size - 1],1,MPI_INT,process_rank ^ (1 << j),0,MPI_COMM_WORLD); int counter_receive; int * buffer_recieve = (int *)malloc((array_size + 1) * sizeof(int)); MPI_Recv(&min,1,MPI_INT,process_rank ^ (1 << j),0,MPI_COMM_WORLD,MPI_STATUS_IGNORE); for (i = 0; i < array_size; i++) { if (array[i] > min) { buffer_send[counter_send + 1] = array[i]; counter_send++; } else { break; } } buffer_send[0] = counter_send; MPI_Send(buffer_send,counter_send,MPI_INT,process_rank ^ (1 << j),0,MPI_COMM_WORLD); MPI_Recv(buffer_recieve,array_size,MPI_INT,process_rank ^ (1 << j),0,MPI_COMM_WORLD,MPI_STATUS_IGNORE); for (i = 1; i < buffer_recieve[0] + 1; i++) { if (array[array_size - 1] < buffer_recieve[i]) { array[array_size - 1] = buffer_recieve[i]; } else { break; } } qsort(array, array_size, sizeof(int), ComparisonFunc); free(buffer_send); free(buffer_recieve); } int Comparison(const void * x, const void * y) { return (*(int *)x - *(int *)y); }