This source file includes following definitions.
- mpigclock_sync_linear
- mpigclock_sync_log
- mpigclock_measure_offset_adaptive
   1 
   2 
   3 
   4 
   5 
   6 
   7 
   8 
   9 
  10 
  11 
  12 
  13 
  14 
  15 
  16 
  17 
  18 
  19 
  20 
  21 
  22 
  23 
  24 
  25 
  26 
  27 
  28 
  29 
  30 
  31 
  32 
  33 
  34 
  35 
  36 
  37 
  38 
  39 
  40 
  41 
  42 
  43 #include <stdio.h>
  44 #include <stdlib.h>
  45 
  46 #include <mpi.h>
  47 
  48 #include "mpigclock.h"
  49 #include "hpctimer.h"
  50 
  51 #define INVALIDTIME -1.0
  52 #define MPIGCLOCK_RTTMIN_NOTCHANGED_MAX 100
  53 #define MPIGCLOCK_MSGTAG 128
  54 
  55 static double mpigclock_measure_offset_adaptive(MPI_Comm comm, int root, int peer, double *min_rtt, double root_offset);
  56 
  57 
  58 
  59 
  60 
  61 double mpigclock_sync_linear(MPI_Comm comm, int root, double *rtt)
  62 {
  63     int peer, rank, commsize;
  64     double ret = 0;
  65 
  66     MPI_Comm_rank(comm, &rank);
  67     MPI_Comm_size(comm, &commsize);
  68 
  69     for (peer = 1; peer < commsize; peer++) {
  70         MPI_Barrier(comm);
  71         if (rank == root || rank == peer) {
  72             ret = mpigclock_measure_offset_adaptive(comm, root, peer, rtt, 0.0);
  73         }
  74     }
  75     return ret;
  76 }
  77 
  78 
  79 
  80 
  81 
  82 double mpigclock_sync_log(MPI_Comm comm, int root, double *rtt)
  83 {
  84     int peer, rank, commsize;
  85     double root_offset = 0;
  86     double ret = 0;
  87 
  88     MPI_Comm_rank(comm, &rank);
  89     MPI_Comm_size(comm, &commsize);
  90 
  91     
  92     if (rank != root) {
  93         root = (rank - 1) / 2;
  94         MPI_Recv(&root_offset, 1, MPI_DOUBLE, root, MPIGCLOCK_MSGTAG, comm, MPI_STATUS_IGNORE);
  95         ret = mpigclock_measure_offset_adaptive(comm, root, rank, rtt, root_offset);
  96     }
  97 
  98     root_offset = ret;
  99 
 100     
 101     *rtt = 0;
 102     peer = 2 * rank + 1;
 103     if (peer < commsize) {
 104         MPI_Send(&root_offset, 1, MPI_DOUBLE, peer, MPIGCLOCK_MSGTAG, comm);
 105         mpigclock_measure_offset_adaptive(comm, rank, peer, rtt, root_offset);
 106     }
 107 
 108     *rtt = 0;
 109     peer = 2 * rank + 2;
 110     if (peer < commsize) {
 111         MPI_Send(&root_offset, 1, MPI_DOUBLE, peer, MPIGCLOCK_MSGTAG, comm);
 112         mpigclock_measure_offset_adaptive(comm, rank, peer, rtt, root_offset);
 113     }
 114 
 115     return ret;
 116 }
 117 
 118 
 119 static double mpigclock_measure_offset_adaptive(MPI_Comm comm, int root, int peer, double *min_rtt, double root_offset)
 120 {
 121     int rank, commsize, rttmin_notchanged = 0;
 122     double starttime, stoptime, peertime, rtt, rttmin = 1E12,
 123            invalidtime = INVALIDTIME, offset;
 124 
 125     MPI_Comm_rank(comm, &rank);
 126     MPI_Comm_size(comm, &commsize);
 127 
 128     offset = 0.0;
 129     for (;;) {
 130         if (rank != root) {
 131             
 132             starttime = hpctimer_wtime();
 133             MPI_Send(&starttime, 1, MPI_DOUBLE, root, MPIGCLOCK_MSGTAG, comm);
 134             MPI_Recv(&peertime, 1, MPI_DOUBLE, root, MPIGCLOCK_MSGTAG, comm,
 135                      MPI_STATUS_IGNORE);
 136             stoptime = hpctimer_wtime();
 137             rtt = stoptime - starttime;
 138 
 139             if (rtt < rttmin) {
 140                 rttmin = rtt;
 141                 rttmin_notchanged = 0;
 142                 offset =  peertime - rtt / 2.0 - starttime;
 143             } else {
 144                 if (++rttmin_notchanged == MPIGCLOCK_RTTMIN_NOTCHANGED_MAX) {
 145                     MPI_Send(&invalidtime, 1, MPI_DOUBLE, root, MPIGCLOCK_MSGTAG,
 146                              comm);
 147                     break;
 148                 }
 149             }
 150         } else {
 151             
 152             MPI_Recv(&starttime, 1, MPI_DOUBLE, peer, MPIGCLOCK_MSGTAG, comm,
 153                      MPI_STATUS_IGNORE);
 154             peertime = hpctimer_wtime() + root_offset;
 155             if (starttime < 0.0) {
 156                 break;
 157             }
 158             MPI_Send(&peertime, 1, MPI_DOUBLE, peer, MPIGCLOCK_MSGTAG, comm);
 159         }
 160     } 
 161 
 162     if( rank != root ){
 163         *min_rtt = rttmin;
 164     } else {
 165         rtt = 0.0;
 166     }
 167     return offset;
 168 }