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 }