fork download
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <mpi.h>
  4.  
  5. #define ARRAY_SIZE 1000008 // Define the maximum array size statically
  6.  
  7. void prefix_sum(int* local_data, int local_size, int* result) {
  8. int rank, size;
  9. MPI_Comm_rank(MPI_COMM_WORLD, &rank);
  10. MPI_Comm_size(MPI_COMM_WORLD, &size);
  11.  
  12. // Compute local prefix sum
  13. result[0] = local_data[0];
  14. for (int i = 1; i < local_size; i++) {
  15. result[i] = result[i - 1] + local_data[i];
  16. }
  17.  
  18. // Compute offset from previous ranks
  19. int offset = 0;
  20. if (rank != 0) {
  21. int previous_sum;
  22. MPI_Recv(&previous_sum, 1, MPI_INT, rank - 1, 0, MPI_COMM_WORLD, MPI_STATUS_IGNORE);
  23. offset = previous_sum;
  24. // Adjust the last element of the local prefix sum with the received offset
  25. result[local_size - 1] += offset;
  26. // Send the total sum of the current process to the next process
  27. int total_sum = result[local_size - 1];
  28. if (rank != size - 1) {
  29. MPI_Send(&total_sum, 1, MPI_INT, rank + 1, 0, MPI_COMM_WORLD);
  30. }
  31. // Adjust all local results based on the offset
  32. for (int i = 0; i < local_size - 1; i++) {
  33. result[i] += offset;
  34. }
  35. }
  36. // Send the total sum to the next rank
  37. int total_sum = result[local_size - 1];
  38. if (rank == 0) {
  39. MPI_Send(&total_sum, 1, MPI_INT, rank + 1, 0, MPI_COMM_WORLD);
  40. }
  41. }
  42.  
  43. int main(int argc, char** argv) {
  44. MPI_Init(&argc, &argv);
  45.  
  46. int rank, size;
  47. MPI_Comm_rank(MPI_COMM_WORLD, &rank);
  48. MPI_Comm_size(MPI_COMM_WORLD, &size);
  49.  
  50. // Ensure ARRAY_SIZE is divisible by size
  51. if (ARRAY_SIZE % size != 0) {
  52. if (rank == 0) {
  53. fprintf(stderr, "Array size must be divisible by the number of processes.\n");
  54. }
  55. MPI_Finalize();
  56. return EXIT_FAILURE;
  57. }
  58.  
  59. int total_size = ARRAY_SIZE;
  60. int data[ARRAY_SIZE]; // Static allocation for the entire array
  61.  
  62. if (rank == 0) {
  63. // Initialize array with ones
  64. for (int i = 0; i < total_size; i++) {
  65. data[i] = 1;
  66. }
  67. }
  68.  
  69. // Compute local size for each process
  70. int local_size = total_size / size;
  71. int local_data[local_size]; // Static allocation for local data
  72.  
  73. // Distribute data among processes
  74. MPI_Scatter(data, local_size, MPI_INT, local_data, local_size, MPI_INT, 0, MPI_COMM_WORLD);
  75.  
  76. // Measure computation time
  77. double start_time = MPI_Wtime();
  78.  
  79. // Compute prefix sum locally and adjust with offsets
  80. int local_result[local_size]; // Static allocation for local result
  81. prefix_sum(local_data, local_size, local_result);
  82.  
  83. // Gather the results back
  84. static int result[ARRAY_SIZE]; // Static allocation for the final result
  85. MPI_Gather(local_result, local_size, MPI_INT, result, local_size, MPI_INT, 0, MPI_COMM_WORLD);
  86.  
  87. double end_time = MPI_Wtime();
  88.  
  89. // Print the result and computation time
  90. if (rank == 0) {
  91. printf("Prefix Sum: ");
  92. printf("%d ", result[1000007]);
  93. printf("\n");
  94. printf("Computation Time: %f seconds\n", end_time - start_time);
  95. }
  96.  
  97. MPI_Finalize();
  98. return 0;
  99. }
  100.  
Success #stdin #stdout #stderr 0.25s 40764KB
stdin
Standard input is empty
stdout
Standard output is empty
stderr
Error: unexpected symbol in "void prefix_sum"
Execution halted