C   132
broadcast
Guest on 14th March 2023 12:16:39 AM


  1. #include <stdio.h>
  2. #include <string.h>
  3. #include <stdlib.h>
  4. #include <mpi.h>
  5.  
  6. #define TAG_BCAST 123
  7.  
  8. void my_broadcast(int rank, int size, double *message);
  9.  
  10. int main(int argc, char *argv[])
  11. {
  12.         int rank, size;
  13.         double message;
  14.  
  15.         MPI_Init(&argc, &argv);
  16.         MPI_Comm_rank(MPI_COMM_WORLD, &rank);
  17.         MPI_Comm_size(MPI_COMM_WORLD, &size);
  18.  
  19.         /* an arbitrary message */
  20.         message = 0.0;
  21.         if (rank == 0)
  22.                 message = 5.6789;
  23.  
  24.         /* local broadcast */
  25.         my_broadcast(rank, size, &message);
  26.  
  27.         /* check that nodes received message */
  28.         printf("after broadcast -- node %d -- message %f\n", rank, message);
  29.  
  30.         /* end of code */
  31.         MPI_Finalize();
  32.         return EXIT_SUCCESS;
  33. }
  34.  
  35. void my_broadcast(int rank, int size, double *message)
  36. {
  37.         int level, maxlevel;
  38.         int shift_ip, n_target;
  39.         int *target_process;
  40.         int from_process, target;
  41.         MPI_Status recv_status;
  42.  
  43.         /* build transmission tree */
  44.  
  45.         /* size of binary tree */
  46.         maxlevel = 0;
  47.         while (1 << maxlevel + 1 < size)
  48.                 maxlevel++;
  49.         /* '<<' is a bitwise shift left, so  1 << b == pow(2, b) */
  50.  
  51.         /* make space for local branch of tree */
  52.         target_process = (int *)malloc((unsigned)(size * sizeof(int)));
  53.  
  54.         /* build the branches */
  55.         n_target = 0;
  56.         from_process = -1;
  57.         n_target = 0;
  58.         for (level = 0; level <= maxlevel; level++) {
  59.                 shift_ip = 1 << level;
  60.                 if (rank >= shift_ip)
  61.                         from_process = rank - shift_ip;
  62.                 if (rank < shift_ip) {
  63.                         target = rank + shift_ip;
  64.                         if (target < size) {
  65.                                 target_process[n_target] = target;
  66.                                 n_target++;
  67.                         }
  68.                 }
  69.         }
  70.  
  71.         /* debugging output */
  72.         fprintf(stderr, "process %d -- from_process %d -- %d targets\n",
  73.                 rank, from_process, n_target);
  74.         if (n_target > 0) {
  75.                 for (target = 0; target < n_target; target++)
  76.                         fprintf(stderr, "process %d -- target %d\n",
  77.                                 rank, target_process[target]);
  78.         }
  79.  
  80.         /* message transmission */
  81.  
  82.         /* receive message */
  83.         if (rank > 0) {
  84.                 fprintf(stderr, "--- receiving %d %d \n", rank, from_process);
  85.                 fflush(stderr);
  86.                 MPI_Recv(message, 1, MPI_DOUBLE, from_process, TAG_BCAST,
  87.                          MPI_COMM_WORLD, &recv_status);
  88.         }
  89.  
  90.         /* send message to all target processes */
  91.         if (n_target > 0) {
  92.                 fprintf(stderr, "--- sending %d %d \n", rank, n_target);
  93.                 for (target = 0; target < n_target; target++)
  94.                         MPI_Ssend(message, 1, MPI_DOUBLE,
  95.                                   target_process[target], TAG_BCAST,
  96.                                   MPI_COMM_WORLD);
  97.         }
  98.  
  99.         /* free up space */
  100.         free(target_process);
  101. }

Raw Paste

Login or Register to edit or fork this paste. It's free.