#include <stdio.h>
#include <stdlib.h>
#include <mpi.h>
#define N 1000000 // Number of random numbers in total
int compare(const void *a, const void *b) {
return (*(double*)a > *(double*)b) - (*(double*)a < *(double*)b);
}
int main(int argc, char *argv[]) {
int rank, size;
double *global_data = NULL;
double *local_data;
int local_n;
double start_time, end_time;
MPI_Init(&argc, &argv);
MPI_Comm_rank(MPI_COMM_WORLD, &rank);
MPI_Comm_size(MPI_COMM_WORLD, &size);
local_n = N / size; // Number of elements per process
if (N % size > rank) {
local_n++;
}
local_data = (double *)malloc(local_n * sizeof(double));
// Root process generates the full data set
if (rank == 0) {
global_data = (double *)malloc(N * sizeof(double));
srand(0); // Use a fixed seed for reproducibility
for (int i = 0; i < N; i++) {
global_data[i] = (double)rand() / RAND_MAX;
}
}
// Distribute portions of the array to all processes
if (rank == 0) {
// Calculate displacements and counts for distribution
int *displs = malloc(size * sizeof(int));
int *sendcounts = malloc(size * sizeof(int));
int disp = 0;
for (int i = 0; i < size; i++) {
sendcounts[i] = N / size;
if (i < N % size) sendcounts[i]++;
displs[i] = disp;
disp += sendcounts[i];
}
MPI_Scatterv(global_data, sendcounts, displs, MPI_DOUBLE, local_data, local_n, MPI_DOUBLE, 0, MPI_COMM_WORLD);
free(displs);
free(sendcounts);
} else {
MPI_Scatterv(NULL, NULL, NULL, MPI_DOUBLE, local_data, local_n, MPI_DOUBLE, 0, MPI_COMM_WORLD);
}
// Sort local data
qsort(local_data, local_n, sizeof(double), compare);
// Gather sorted data back at root
if (rank == 0) {
int *recvcounts = malloc(size * sizeof(int));
int *displs = malloc(size * sizeof(int));
int disp = 0;
for (int i = 0; i < size; i++) {
recvcounts[i] = N / size;
if (i < N % size) recvcounts[i]++;
displs[i] = disp;
disp += recvcounts[i];
}
MPI_Gatherv(local_data, local_n, MPI_DOUBLE, global_data, recvcounts, displs, MPI_DOUBLE, 0, MPI_COMM_WORLD);
// Sort the entire array at root
qsort(global_data, N, sizeof(double), compare);
free(recvcounts);
free(displs);
} else {
MPI_Gatherv(local_data, local_n, MPI_DOUBLE, NULL, NULL, NULL, MPI_DOUBLE, 0, MPI_COMM_WORLD);
}
// Print results if needed
if (rank == 0) {
for (int i = 0; i < N; i++) {
printf("%f ", global_data[i]);
}
printf("\n");
free(global_data);
}
free(local_data);
MPI_Finalize();
return 0;
}