fork download
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <string.h>
  4. #include <limits.h>
  5. #include <mpi.h>
  6. #include "fileio.h"
  7.  
  8. const int ROOT = 0;
  9. const int TAG = 0;
  10.  
  11. void ptp_ring_sum(int size, char *input_file, int my_rank, int comm_sz);
  12. double array_sum(int *array, int size);
  13.  
  14. int main(int argc, char* argv[]) {
  15. int comm_sz, my_rank;
  16.  
  17. MPI_Init(NULL, NULL);
  18. MPI_Comm_size(MPI_COMM_WORLD, &comm_sz);
  19. MPI_Comm_rank(MPI_COMM_WORLD, &my_rank);
  20.  
  21. if (argc < (comm_sz + 2)) {
  22. if (my_rank == ROOT) {
  23. fprintf(stderr, "Usage: mpirun -np <p> %s <size> <file for rank 0> ... <file for rank p-1>\n", argv[0]);
  24. }
  25. } else {
  26. ptp_ring_sum(atoi(argv[1]), argv[2 + my_rank], my_rank, comm_sz);
  27. }
  28.  
  29. MPI_Finalize();
  30.  
  31. return EXIT_SUCCESS;
  32. }
  33.  
  34. /**
  35.  * This function will be called by all the processes in the communicator
  36.  * TODO: Calculate the total sum of all the local array sums using point to point communication as follows:
  37.  * - process 0 should send its sum to process 1, and receive the total sum from the process with the highest rank
  38.  * - process 1 should receive the sum from process 0, add its local_sum to it, and send the result to process 2
  39.  * - ...
  40.  * - the last process should receive the sum from the second-last process, add its local_sum to it, and send the result to process 0
  41.  */
  42. void ptp_ring_sum(int size, char *input_file, int my_rank, int comm_sz) {
  43. // Allocate memory for the local array
  44. int *local_array = NULL;
  45. local_array = read_array(input_file, &size);
  46. if (!local_array) {
  47. fprintf(stderr, "Error: Unable to allocate memory for local array.\n");
  48. MPI_Abort(MPI_COMM_WORLD, EXIT_FAILURE);
  49. return;
  50. }
  51.  
  52. // Print the local array
  53. print_array(local_array, size, "Array");
  54.  
  55. // Calculate the sum of the local array
  56. double local_sum = array_sum(local_array, size);
  57. print_double(local_sum, "The local sum");
  58.  
  59. // Free the local array
  60. free(local_array);
  61.  
  62. // Determine the destination and source for sending/receiving sums
  63. int dest = (my_rank + 1) % comm_sz; // Destination is the next process in the ring
  64. int source = (my_rank - 1 + comm_sz) % comm_sz; // Source is the previous process in the ring
  65.  
  66. if (my_rank == 0) {
  67. // Process 0 starts the chain by sending its sum to process 1
  68. MPI_Send(&local_sum, 1, MPI_DOUBLE, dest, 0, MPI_COMM_WORLD);
  69. printf("Process 0 sent its partial sum to process 1.\n");
  70. // Then it receives the final total sum from the last process
  71. MPI_Recv(&local_sum, 1, MPI_DOUBLE, source, 0, MPI_COMM_WORLD, MPI_STATUS_IGNORE);
  72. printf("Process 0 received the total sum from the last process: %.1f\n", local_sum);
  73. } else {
  74. // All other processes receive sum from the previous process, add to it, and send it to the next
  75. double received_sum = 0.0;
  76. MPI_Recv(&received_sum, 1, MPI_DOUBLE, source, 0, MPI_COMM_WORLD, MPI_STATUS_IGNORE);
  77. printf("Process %d received a partial sum from process %d: %.1f\n", my_rank, source, received_sum);
  78.  
  79. received_sum += local_sum;
  80. MPI_Send(&received_sum, 1, MPI_DOUBLE, dest, 0, MPI_COMM_WORLD);
  81. printf("Process %d sent its partial sum to process %d.\n", my_rank, dest);
  82. }
  83. }
  84.  
  85. /** Calculate the sum of the values in the provided array */
  86. double array_sum(int *arr, int sz) {
  87. double sum = 0;
  88. for (int i = 0; i < sz; i++) {
  89. sum += (double) arr[i];
  90. }
  91.  
  92. return sum;
  93. }
  94.  
Success #stdin #stdout #stderr 0.26s 40604KB
stdin
Standard input is empty
stdout
Standard output is empty
stderr
Error: unexpected symbol in "const int"
Execution halted