fork download
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <mpi.h>
  4.  
  5. #define N 1000000 // Number of random numbers in total
  6.  
  7. int compare(const void *a, const void *b) {
  8. return (*(double*)a > *(double*)b) - (*(double*)a < *(double*)b);
  9. }
  10.  
  11. int main(int argc, char *argv[]) {
  12. int rank, size;
  13. double *global_data = NULL;
  14. double *local_data;
  15. int local_n;
  16. double start_time, end_time;
  17.  
  18. MPI_Init(&argc, &argv);
  19. MPI_Comm_rank(MPI_COMM_WORLD, &rank);
  20. MPI_Comm_size(MPI_COMM_WORLD, &size);
  21.  
  22. local_n = N / size; // Number of elements per process
  23. if (N % size > rank) {
  24. local_n++;
  25. }
  26.  
  27. local_data = (double *)malloc(local_n * sizeof(double));
  28.  
  29. // Root process generates the full data set
  30. if (rank == 0) {
  31. global_data = (double *)malloc(N * sizeof(double));
  32. srand(0); // Use a fixed seed for reproducibility
  33. for (int i = 0; i < N; i++) {
  34. global_data[i] = (double)rand() / RAND_MAX;
  35. }
  36. }
  37.  
  38. // Distribute portions of the array to all processes
  39. if (rank == 0) {
  40. // Calculate displacements and counts for distribution
  41. int *displs = malloc(size * sizeof(int));
  42. int *sendcounts = malloc(size * sizeof(int));
  43. int disp = 0;
  44. for (int i = 0; i < size; i++) {
  45. sendcounts[i] = N / size;
  46. if (i < N % size) sendcounts[i]++;
  47. displs[i] = disp;
  48. disp += sendcounts[i];
  49. }
  50.  
  51. MPI_Scatterv(global_data, sendcounts, displs, MPI_DOUBLE, local_data, local_n, MPI_DOUBLE, 0, MPI_COMM_WORLD);
  52.  
  53. free(displs);
  54. free(sendcounts);
  55. } else {
  56. MPI_Scatterv(NULL, NULL, NULL, MPI_DOUBLE, local_data, local_n, MPI_DOUBLE, 0, MPI_COMM_WORLD);
  57. }
  58.  
  59. // Sort local data
  60. qsort(local_data, local_n, sizeof(double), compare);
  61.  
  62. // Gather sorted data back at root
  63. if (rank == 0) {
  64. int *recvcounts = malloc(size * sizeof(int));
  65. int *displs = malloc(size * sizeof(int));
  66. int disp = 0;
  67. for (int i = 0; i < size; i++) {
  68. recvcounts[i] = N / size;
  69. if (i < N % size) recvcounts[i]++;
  70. displs[i] = disp;
  71. disp += recvcounts[i];
  72. }
  73.  
  74. MPI_Gatherv(local_data, local_n, MPI_DOUBLE, global_data, recvcounts, displs, MPI_DOUBLE, 0, MPI_COMM_WORLD);
  75.  
  76. // Sort the entire array at root
  77. qsort(global_data, N, sizeof(double), compare);
  78.  
  79. free(recvcounts);
  80. free(displs);
  81. } else {
  82. MPI_Gatherv(local_data, local_n, MPI_DOUBLE, NULL, NULL, NULL, MPI_DOUBLE, 0, MPI_COMM_WORLD);
  83. }
  84.  
  85. // Print results if needed
  86. if (rank == 0) {
  87. for (int i = 0; i < N; i++) {
  88. printf("%f ", global_data[i]);
  89. }
  90. printf("\n");
  91. free(global_data);
  92. }
  93.  
  94. free(local_data);
  95. MPI_Finalize();
  96. return 0;
  97. }
  98.  
Success #stdin #stdout #stderr 0.36s 40448KB
stdin
Standard input is empty
stdout
Standard output is empty
stderr
Error: unexpected symbol in "int compare"
Execution halted