fork download
  1. #include <mpi.h>
  2. #include <stdio.h>
  3. #include <stdlib.h>
  4. #include <time.h>
  5.  
  6. // Function to print an array along with the process rank
  7. void printArray(double *array, int size, int rank) {
  8. printf("Process %d array: ", rank);
  9. for (int i = 0; i < size; i++) {
  10. printf("%.2f ", array[i]);
  11. }
  12. printf("\n");
  13. }
  14.  
  15. // Function to calculate the local average of an array
  16. double calculateLocalAverage(double *array, int size) {
  17. double sum = 0.0;
  18. for (int i = 0; i < size; i++) {
  19. sum += array[i];
  20. }
  21. return sum / size;
  22. }
  23.  
  24. int main(int argc, char *argv[]) {
  25. // Initialize MPI and variables
  26. MPI_Init(&argc, &argv);
  27.  
  28. int rank, size, N;
  29. MPI_Comm_rank(MPI_COMM_WORLD, &rank);
  30. MPI_Comm_size(MPI_COMM_WORLD, &size);
  31.  
  32. // Read and validate command-line argument
  33. if (argc != 2 || (N = atoi(argv[1])) <= 1) {
  34. if (rank == 0) fprintf(stderr, "Usage: %s N (N > 1)\n", argv[0]);
  35. MPI_Finalize();
  36. return 1;
  37. }
  38.  
  39. // Seed random number generator differently for each process
  40. srand(time(NULL) + rank);
  41.  
  42. // Allocate and initialize the array with random values
  43. double *array = (double *)malloc(N * sizeof(double));
  44. for (int i = 0; i < N; i++) {
  45. array[i] = (double)(rand() % 100) / 10.0;
  46. }
  47.  
  48. // Initial array print by master process in process order
  49. if (rank == 0) {
  50. printf("Initial Arrays:\n");
  51. }
  52. MPI_Barrier(MPI_COMM_WORLD); // Sync for orderly printing
  53. printArray(array, N, rank);
  54. MPI_Barrier(MPI_COMM_WORLD);
  55.  
  56. // Calculate global average
  57. double local_sum = 0.0, global_sum = 0.0;
  58. for (int i = 0; i < N; i++) {
  59. local_sum += array[i];
  60. }
  61. MPI_Allreduce(&local_sum, &global_sum, 1, MPI_DOUBLE, MPI_SUM, MPI_COMM_WORLD);
  62. double global_average = global_sum / (N * size);
  63.  
  64. // Randomly select an "odd-ball" process (other than process 0)
  65. int odd_ball = -1;
  66. if (rank == 0) {
  67. odd_ball = (rand() % (size - 1)) + 1; // Random process excluding 0
  68. printf("Odd-ball process selected: %d\n", odd_ball);
  69. }
  70. MPI_Bcast(&odd_ball, 1, MPI_INT, 0, MPI_COMM_WORLD);
  71.  
  72. // Adjust array elements based on the global average
  73. for (int i = 0; i < N; i++) {
  74. if (rank == odd_ball) {
  75. array[i] += global_average; // Odd-ball adds
  76. } else {
  77. array[i] -= global_average; // Others subtract
  78. }
  79. }
  80.  
  81. // Each process finds its maximum value
  82. double local_max = array[0];
  83. for (int i = 1; i < N; i++) {
  84. if (array[i] > local_max) local_max = array[i];
  85. }
  86.  
  87. // Gather all max values from processes
  88. double *max_values = (double *)malloc(size * sizeof(double));
  89. MPI_Allgather(&local_max, 1, MPI_DOUBLE, max_values, 1, MPI_DOUBLE, MPI_COMM_WORLD);
  90.  
  91. // Add neighbor’s max value, or subtract if the process is the odd-ball
  92. double neighbor_max = (rank == size - 1) ? max_values[0] : max_values[rank + 1];
  93. for (int i = 0; i < N; i++) {
  94. if (rank == odd_ball) {
  95. array[i] -= neighbor_max; // Odd-ball subtracts
  96. } else {
  97. array[i] += neighbor_max; // Others add
  98. }
  99. }
  100.  
  101. // Odd-Even Transposition Sort using MPI
  102. int sorted = 0;
  103. while (!sorted) {
  104. sorted = 1;
  105. for (int phase = 0; phase < size; phase++) {
  106. int partner = (phase % 2 == rank % 2) ? rank + 1 : rank - 1;
  107. if (partner >= 0 && partner < size) {
  108. double *temp_array = (double *)malloc(N * sizeof(double));
  109. MPI_Sendrecv(array, N, MPI_DOUBLE, partner, 0, temp_array, N, MPI_DOUBLE, partner, 0, MPI_COMM_WORLD, MPI_STATUS_IGNORE);
  110. // Local sorting logic here between received and local array for transposition
  111. free(temp_array);
  112. }
  113. }
  114. }
  115.  
  116. // Print final sorted arrays
  117. if (rank == 0) {
  118. printf("Final Sorted Arrays:\n");
  119. }
  120. MPI_Barrier(MPI_COMM_WORLD); // Sync for orderly printing
  121. printArray(array, N, rank);
  122. MPI_Barrier(MPI_COMM_WORLD);
  123.  
  124. // Clean up
  125. free(array);
  126. free(max_values);
  127. MPI_Finalize();
  128. return 0;
  129. }
  130.  
  131.  
Success #stdin #stdout #stderr 0.23s 40464KB
stdin
Standard input is empty
stdout
Standard output is empty
stderr
Error: unexpected '/' in "/"
Execution halted