This source file includes following definitions.
- SET_SPC_BIT
- IS_SPC_BIT_SET
- CLEAR_SPC_BIT
- ompi_spc_notify
- ompi_spc_get_count
- ompi_spc_events_init
- ompi_spc_init
- ompi_spc_dump
- ompi_spc_fini
- ompi_spc_record
- ompi_spc_timer_start
- ompi_spc_timer_stop
- ompi_spc_user_or_mpi
- ompi_spc_update_watermark
- ompi_spc_cycles_to_usecs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 #include "ompi_spc.h"
17
18 opal_timer_t sys_clock_freq_mhz = 0;
19
20 static void ompi_spc_dump(void);
21
22
23 OMPI_DECLSPEC int mpi_t_offset = -1;
24 OMPI_DECLSPEC bool mpi_t_enabled = false;
25
26 OPAL_DECLSPEC ompi_communicator_t *ompi_spc_comm = NULL;
27
28 typedef struct ompi_spc_event_t {
29 const char* counter_name;
30 const char* counter_description;
31 } ompi_spc_event_t;
32
33 #define SET_COUNTER_ARRAY(NAME, DESC) [NAME] = { .counter_name = #NAME, .counter_description = DESC }
34
35 static ompi_spc_event_t ompi_spc_events_names[OMPI_SPC_NUM_COUNTERS] = {
36 SET_COUNTER_ARRAY(OMPI_SPC_SEND, "The number of times MPI_Send was called."),
37 SET_COUNTER_ARRAY(OMPI_SPC_BSEND, "The number of times MPI_Bsend was called."),
38 SET_COUNTER_ARRAY(OMPI_SPC_RSEND, "The number of times MPI_Rsend was called."),
39 SET_COUNTER_ARRAY(OMPI_SPC_SSEND, "The number of times MPI_Ssend was called."),
40 SET_COUNTER_ARRAY(OMPI_SPC_RECV, "The number of times MPI_Recv was called."),
41 SET_COUNTER_ARRAY(OMPI_SPC_MRECV, "The number of times MPI_Mrecv was called."),
42 SET_COUNTER_ARRAY(OMPI_SPC_ISEND, "The number of times MPI_Isend was called."),
43 SET_COUNTER_ARRAY(OMPI_SPC_IBSEND, "The number of times MPI_Ibsend was called."),
44 SET_COUNTER_ARRAY(OMPI_SPC_IRSEND, "The number of times MPI_Irsend was called."),
45 SET_COUNTER_ARRAY(OMPI_SPC_ISSEND, "The number of times MPI_Issend was called."),
46 SET_COUNTER_ARRAY(OMPI_SPC_IRECV, "The number of times MPI_Irecv was called."),
47 SET_COUNTER_ARRAY(OMPI_SPC_SENDRECV, "The number of times MPI_Sendrecv was called."),
48 SET_COUNTER_ARRAY(OMPI_SPC_SENDRECV_REPLACE, "The number of times MPI_Sendrecv_replace was called."),
49 SET_COUNTER_ARRAY(OMPI_SPC_PUT, "The number of times MPI_Put was called."),
50 SET_COUNTER_ARRAY(OMPI_SPC_RPUT, "The number of times MPI_Rput was called."),
51 SET_COUNTER_ARRAY(OMPI_SPC_GET, "The number of times MPI_Get was called."),
52 SET_COUNTER_ARRAY(OMPI_SPC_RGET, "The number of times MPI_Rget was called."),
53 SET_COUNTER_ARRAY(OMPI_SPC_PROBE, "The number of times MPI_Probe was called."),
54 SET_COUNTER_ARRAY(OMPI_SPC_IPROBE, "The number of times MPI_Iprobe was called."),
55 SET_COUNTER_ARRAY(OMPI_SPC_BCAST, "The number of times MPI_Bcast was called."),
56 SET_COUNTER_ARRAY(OMPI_SPC_IBCAST, "The number of times MPI_Ibcast was called."),
57 SET_COUNTER_ARRAY(OMPI_SPC_BCAST_INIT, "The number of times MPIX_Bcast_init was called."),
58 SET_COUNTER_ARRAY(OMPI_SPC_REDUCE, "The number of times MPI_Reduce was called."),
59 SET_COUNTER_ARRAY(OMPI_SPC_REDUCE_SCATTER, "The number of times MPI_Reduce_scatter was called."),
60 SET_COUNTER_ARRAY(OMPI_SPC_REDUCE_SCATTER_BLOCK, "The number of times MPI_Reduce_scatter_block was called."),
61 SET_COUNTER_ARRAY(OMPI_SPC_IREDUCE, "The number of times MPI_Ireduce was called."),
62 SET_COUNTER_ARRAY(OMPI_SPC_IREDUCE_SCATTER, "The number of times MPI_Ireduce_scatter was called."),
63 SET_COUNTER_ARRAY(OMPI_SPC_IREDUCE_SCATTER_BLOCK, "The number of times MPI_Ireduce_scatter_block was called."),
64 SET_COUNTER_ARRAY(OMPI_SPC_REDUCE_INIT, "The number of times MPIX_Reduce_init was called."),
65 SET_COUNTER_ARRAY(OMPI_SPC_REDUCE_SCATTER_INIT, "The number of times MPIX_Reduce_scatter_init was called."),
66 SET_COUNTER_ARRAY(OMPI_SPC_REDUCE_SCATTER_BLOCK_INIT, "The number of times MPIX_Reduce_scatter_block_init was called."),
67 SET_COUNTER_ARRAY(OMPI_SPC_ALLREDUCE, "The number of times MPI_Allreduce was called."),
68 SET_COUNTER_ARRAY(OMPI_SPC_IALLREDUCE, "The number of times MPI_Iallreduce was called."),
69 SET_COUNTER_ARRAY(OMPI_SPC_ALLREDUCE_INIT, "The number of times MPIX_Allreduce_init was called."),
70 SET_COUNTER_ARRAY(OMPI_SPC_SCAN, "The number of times MPI_Scan was called."),
71 SET_COUNTER_ARRAY(OMPI_SPC_EXSCAN, "The number of times MPI_Exscan was called."),
72 SET_COUNTER_ARRAY(OMPI_SPC_ISCAN, "The number of times MPI_Iscan was called."),
73 SET_COUNTER_ARRAY(OMPI_SPC_IEXSCAN, "The number of times MPI_Iexscan was called."),
74 SET_COUNTER_ARRAY(OMPI_SPC_SCAN_INIT, "The number of times MPIX_Scan_init was called."),
75 SET_COUNTER_ARRAY(OMPI_SPC_EXSCAN_INIT, "The number of times MPIX_Exscan_init was called."),
76 SET_COUNTER_ARRAY(OMPI_SPC_SCATTER, "The number of times MPI_Scatter was called."),
77 SET_COUNTER_ARRAY(OMPI_SPC_SCATTERV, "The number of times MPI_Scatterv was called."),
78 SET_COUNTER_ARRAY(OMPI_SPC_ISCATTER, "The number of times MPI_Iscatter was called."),
79 SET_COUNTER_ARRAY(OMPI_SPC_ISCATTERV, "The number of times MPI_Iscatterv was called."),
80 SET_COUNTER_ARRAY(OMPI_SPC_SCATTER_INIT, "The number of times MPIX_Scatter_init was called."),
81 SET_COUNTER_ARRAY(OMPI_SPC_SCATTERV_INIT, "The number of times MPIX_Scatterv_init was called."),
82 SET_COUNTER_ARRAY(OMPI_SPC_GATHER, "The number of times MPI_Gather was called."),
83 SET_COUNTER_ARRAY(OMPI_SPC_GATHERV, "The number of times MPI_Gatherv was called."),
84 SET_COUNTER_ARRAY(OMPI_SPC_IGATHER, "The number of times MPI_Igather was called."),
85 SET_COUNTER_ARRAY(OMPI_SPC_IGATHERV, "The number of times MPI_Igatherv was called."),
86 SET_COUNTER_ARRAY(OMPI_SPC_GATHER_INIT, "The number of times MPIX_Gather_init was called."),
87 SET_COUNTER_ARRAY(OMPI_SPC_GATHERV_INIT, "The number of times MPIX_Gatherv_init was called."),
88 SET_COUNTER_ARRAY(OMPI_SPC_ALLTOALL, "The number of times MPI_Alltoall was called."),
89 SET_COUNTER_ARRAY(OMPI_SPC_ALLTOALLV, "The number of times MPI_Alltoallv was called."),
90 SET_COUNTER_ARRAY(OMPI_SPC_ALLTOALLW, "The number of times MPI_Alltoallw was called."),
91 SET_COUNTER_ARRAY(OMPI_SPC_IALLTOALL, "The number of times MPI_Ialltoall was called."),
92 SET_COUNTER_ARRAY(OMPI_SPC_IALLTOALLV, "The number of times MPI_Ialltoallv was called."),
93 SET_COUNTER_ARRAY(OMPI_SPC_IALLTOALLW, "The number of times MPI_Ialltoallw was called."),
94 SET_COUNTER_ARRAY(OMPI_SPC_ALLTOALL_INIT, "The number of times MPIX_Alltoall_init was called."),
95 SET_COUNTER_ARRAY(OMPI_SPC_ALLTOALLV_INIT, "The number of times MPIX_Alltoallv_init was called."),
96 SET_COUNTER_ARRAY(OMPI_SPC_ALLTOALLW_INIT, "The number of times MPIX_Alltoallw_init was called."),
97 SET_COUNTER_ARRAY(OMPI_SPC_NEIGHBOR_ALLTOALL, "The number of times MPI_Neighbor_alltoall was called."),
98 SET_COUNTER_ARRAY(OMPI_SPC_NEIGHBOR_ALLTOALLV, "The number of times MPI_Neighbor_alltoallv was called."),
99 SET_COUNTER_ARRAY(OMPI_SPC_NEIGHBOR_ALLTOALLW, "The number of times MPI_Neighbor_alltoallw was called."),
100 SET_COUNTER_ARRAY(OMPI_SPC_INEIGHBOR_ALLTOALL, "The number of times MPI_Ineighbor_alltoall was called."),
101 SET_COUNTER_ARRAY(OMPI_SPC_INEIGHBOR_ALLTOALLV, "The number of times MPI_Ineighbor_alltoallv was called."),
102 SET_COUNTER_ARRAY(OMPI_SPC_INEIGHBOR_ALLTOALLW, "The number of times MPI_Ineighbor_alltoallw was called."),
103 SET_COUNTER_ARRAY(OMPI_SPC_NEIGHBOR_ALLTOALL_INIT, "The number of times MPIX_Neighbor_alltoall_init was called."),
104 SET_COUNTER_ARRAY(OMPI_SPC_NEIGHBOR_ALLTOALLV_INIT, "The number of times MPIX_Neighbor_alltoallv_init was called."),
105 SET_COUNTER_ARRAY(OMPI_SPC_NEIGHBOR_ALLTOALLW_INIT, "The number of times MPIX_Neighbor_alltoallw_init was called."),
106 SET_COUNTER_ARRAY(OMPI_SPC_ALLGATHER, "The number of times MPI_Allgather was called."),
107 SET_COUNTER_ARRAY(OMPI_SPC_ALLGATHERV, "The number of times MPI_Allgatherv was called."),
108 SET_COUNTER_ARRAY(OMPI_SPC_IALLGATHER, "The number of times MPI_Iallgather was called."),
109 SET_COUNTER_ARRAY(OMPI_SPC_IALLGATHERV, "The number of times MPI_Iallgatherv was called."),
110 SET_COUNTER_ARRAY(OMPI_SPC_ALLGATHER_INIT, "The number of times MPIX_Allgather_init was called."),
111 SET_COUNTER_ARRAY(OMPI_SPC_ALLGATHERV_INIT, "The number of times MPIX_Allgatherv_init was called."),
112 SET_COUNTER_ARRAY(OMPI_SPC_NEIGHBOR_ALLGATHER, "The number of times MPI_Neighbor_allgather was called."),
113 SET_COUNTER_ARRAY(OMPI_SPC_NEIGHBOR_ALLGATHERV, "The number of times MPI_Neighbor_allgatherv was called."),
114 SET_COUNTER_ARRAY(OMPI_SPC_INEIGHBOR_ALLGATHER, "The number of times MPI_Ineighbor_allgather was called."),
115 SET_COUNTER_ARRAY(OMPI_SPC_INEIGHBOR_ALLGATHERV, "The number of times MPI_Ineighbor_allgatherv was called."),
116 SET_COUNTER_ARRAY(OMPI_SPC_NEIGHBOR_ALLGATHER_INIT, "The number of times MPIX_Neighbor_allgather_init was called."),
117 SET_COUNTER_ARRAY(OMPI_SPC_NEIGHBOR_ALLGATHERV_INIT, "The number of times MPIX_Neighbor_allgatherv_init was called."),
118 SET_COUNTER_ARRAY(OMPI_SPC_TEST, "The number of times MPI_Test was called."),
119 SET_COUNTER_ARRAY(OMPI_SPC_TESTALL, "The number of times MPI_Testall was called."),
120 SET_COUNTER_ARRAY(OMPI_SPC_TESTANY, "The number of times MPI_Testany was called."),
121 SET_COUNTER_ARRAY(OMPI_SPC_TESTSOME, "The number of times MPI_Testsome was called."),
122 SET_COUNTER_ARRAY(OMPI_SPC_WAIT, "The number of times MPI_Wait was called."),
123 SET_COUNTER_ARRAY(OMPI_SPC_WAITALL, "The number of times MPI_Waitall was called."),
124 SET_COUNTER_ARRAY(OMPI_SPC_WAITANY, "The number of times MPI_Waitany was called."),
125 SET_COUNTER_ARRAY(OMPI_SPC_WAITSOME, "The number of times MPI_Waitsome was called."),
126 SET_COUNTER_ARRAY(OMPI_SPC_BARRIER, "The number of times MPI_Barrier was called."),
127 SET_COUNTER_ARRAY(OMPI_SPC_IBARRIER, "The number of times MPI_Ibarrier was called."),
128 SET_COUNTER_ARRAY(OMPI_SPC_BARRIER_INIT, "The number of times MPIX_Barrier_init was called."),
129 SET_COUNTER_ARRAY(OMPI_SPC_WTIME, "The number of times MPI_Wtime was called."),
130 SET_COUNTER_ARRAY(OMPI_SPC_CANCEL, "The number of times MPI_Cancel was called."),
131 SET_COUNTER_ARRAY(OMPI_SPC_BYTES_RECEIVED_USER, "The number of bytes received by the user through point-to-point communications. Note: Includes bytes transferred using internal RMA operations."),
132 SET_COUNTER_ARRAY(OMPI_SPC_BYTES_RECEIVED_MPI, "The number of bytes received by MPI through collective, control, or other internal communications."),
133 SET_COUNTER_ARRAY(OMPI_SPC_BYTES_SENT_USER, "The number of bytes sent by the user through point-to-point communications. Note: Includes bytes transferred using internal RMA operations."),
134 SET_COUNTER_ARRAY(OMPI_SPC_BYTES_SENT_MPI, "The number of bytes sent by MPI through collective, control, or other internal communications."),
135 SET_COUNTER_ARRAY(OMPI_SPC_BYTES_PUT, "The number of bytes sent/received using RMA Put operations both through user-level Put functions and internal Put functions."),
136 SET_COUNTER_ARRAY(OMPI_SPC_BYTES_GET, "The number of bytes sent/received using RMA Get operations both through user-level Get functions and internal Get functions."),
137 SET_COUNTER_ARRAY(OMPI_SPC_UNEXPECTED, "The number of messages that arrived as unexpected messages."),
138 SET_COUNTER_ARRAY(OMPI_SPC_OUT_OF_SEQUENCE, "The number of messages that arrived out of the proper sequence."),
139 SET_COUNTER_ARRAY(OMPI_SPC_MATCH_TIME, "The number of microseconds spent matching unexpected messages. Note: The timer used on the back end is in cycles, which could potentially be problematic on a system where the clock frequency can change. On such a system, this counter could be inaccurate since we assume a fixed clock rate."),
140 SET_COUNTER_ARRAY(OMPI_SPC_UNEXPECTED_IN_QUEUE, "The number of messages that are currently in the unexpected message queue(s) of an MPI process."),
141 SET_COUNTER_ARRAY(OMPI_SPC_OOS_IN_QUEUE, "The number of messages that are currently in the out of sequence message queue(s) of an MPI process."),
142 SET_COUNTER_ARRAY(OMPI_SPC_MAX_UNEXPECTED_IN_QUEUE, "The maximum number of messages that the unexpected message queue(s) within an MPI process "
143 "contained at once since the last reset of this counter. Note: This counter is reset each time it is read."),
144 SET_COUNTER_ARRAY(OMPI_SPC_MAX_OOS_IN_QUEUE, "The maximum number of messages that the out of sequence message queue(s) within an MPI process "
145 "contained at once since the last reset of this counter. Note: This counter is reset each time it is read.")
146 };
147
148
149 static uint32_t ompi_spc_attached_event[OMPI_SPC_NUM_COUNTERS / sizeof(uint32_t)] = { 0 };
150
151 static uint32_t ompi_spc_timer_event[OMPI_SPC_NUM_COUNTERS / sizeof(uint32_t)] = { 0 };
152
153 static ompi_spc_t *ompi_spc_events = NULL;
154
155 static inline void SET_SPC_BIT(uint32_t* array, int32_t pos)
156 {
157 assert(pos < OMPI_SPC_NUM_COUNTERS);
158 array[pos / (8 * sizeof(uint32_t))] |= (1U << (pos % (8 * sizeof(uint32_t))));
159 }
160
161 static inline bool IS_SPC_BIT_SET(uint32_t* array, int32_t pos)
162 {
163 assert(pos < OMPI_SPC_NUM_COUNTERS);
164 return !!(array[pos / (8 * sizeof(uint32_t))] & (1U << (pos % (8 * sizeof(uint32_t)))));
165 }
166
167 static inline void CLEAR_SPC_BIT(uint32_t* array, int32_t pos)
168 {
169 assert(pos < OMPI_SPC_NUM_COUNTERS);
170 array[pos / (8 * sizeof(uint32_t))] &= ~(1U << (pos % (8 * sizeof(uint32_t))));
171 }
172
173
174
175
176
177 static int ompi_spc_notify(mca_base_pvar_t *pvar, mca_base_pvar_event_t event, void *obj_handle, int *count)
178 __opal_attribute_unused__;
179
180 static int ompi_spc_notify(mca_base_pvar_t *pvar, mca_base_pvar_event_t event, void *obj_handle, int *count)
181 {
182 int index;
183
184 if(OPAL_LIKELY(!mpi_t_enabled)) {
185 return MPI_SUCCESS;
186 }
187
188
189
190
191
192 if(MCA_BASE_PVAR_HANDLE_BIND == event) {
193 *count = 1;
194 }
195
196 else if(MCA_BASE_PVAR_HANDLE_START == event) {
197
198 index = pvar->pvar_index - mpi_t_offset;
199 SET_SPC_BIT(ompi_spc_attached_event, index);
200 }
201
202 else if(MCA_BASE_PVAR_HANDLE_STOP == event) {
203
204 index = pvar->pvar_index - mpi_t_offset;
205 CLEAR_SPC_BIT(ompi_spc_attached_event, index);
206 }
207
208 return MPI_SUCCESS;
209 }
210
211
212
213
214
215
216
217
218
219
220
221 static int ompi_spc_get_count(const struct mca_base_pvar_t *pvar, void *value, void *obj_handle)
222 __opal_attribute_unused__;
223
224 static int ompi_spc_get_count(const struct mca_base_pvar_t *pvar, void *value, void *obj_handle)
225 {
226 long long *counter_value = (long long*)value;
227
228 if(OPAL_LIKELY(!mpi_t_enabled)) {
229 *counter_value = 0;
230 return MPI_SUCCESS;
231 }
232
233
234 int index = pvar->pvar_index - mpi_t_offset;
235
236 *counter_value = (long long)ompi_spc_events[index].value;
237
238 if( IS_SPC_BIT_SET(ompi_spc_timer_event, index) ) {
239 *counter_value /= sys_clock_freq_mhz;
240 }
241
242 if(index == OMPI_SPC_MAX_UNEXPECTED_IN_QUEUE || index == OMPI_SPC_MAX_OOS_IN_QUEUE) {
243 ompi_spc_events[index].value = 0;
244 }
245
246 return MPI_SUCCESS;
247 }
248
249
250 void ompi_spc_events_init(void)
251 {
252 int i;
253
254
255 if(NULL == ompi_spc_events) {
256 ompi_spc_events = (ompi_spc_t*)malloc(OMPI_SPC_NUM_COUNTERS * sizeof(ompi_spc_t));
257 if(ompi_spc_events == NULL) {
258 opal_show_help("help-mpi-runtime.txt", "lib-call-fail", true,
259 "malloc", __FILE__, __LINE__);
260 return;
261 }
262 }
263
264
265
266 for(i = 0; i < OMPI_SPC_NUM_COUNTERS; i++) {
267 ompi_spc_events[i].name = (char*)ompi_spc_events_names[i].counter_name;
268 ompi_spc_events[i].value = 0;
269 }
270
271 ompi_comm_dup(&ompi_mpi_comm_world.comm, &ompi_spc_comm);
272 }
273
274
275
276
277 void ompi_spc_init(void)
278 {
279 int i, j, ret, found = 0, all_on = 0;
280
281
282 sys_clock_freq_mhz = opal_timer_base_get_freq() / 1000000;
283
284 ompi_spc_events_init();
285
286
287 char **arg_strings = opal_argv_split(ompi_mpi_spc_attach_string, ',');
288 int num_args = opal_argv_count(arg_strings);
289
290
291
292
293 if(1 == num_args) {
294 if(strcmp(arg_strings[0], "all") == 0) {
295 all_on = 1;
296 }
297 }
298
299
300 for(i = 0; i < OMPI_SPC_NUM_COUNTERS; i++) {
301 if(all_on) {
302 SET_SPC_BIT(ompi_spc_attached_event, i);
303 mpi_t_enabled = true;
304 found++;
305 } else {
306
307 for(j = 0; j < num_args; j++) {
308 if( 0 == strcmp(ompi_spc_events_names[i].counter_name, arg_strings[j]) ) {
309 SET_SPC_BIT(ompi_spc_attached_event, i);
310 mpi_t_enabled = true;
311 found++;
312 break;
313 }
314 }
315 }
316
317
318
319
320
321 CLEAR_SPC_BIT(ompi_spc_timer_event, i);
322
323
324 ret = mca_base_pvar_register("ompi", "runtime", "spc", ompi_spc_events_names[i].counter_name, ompi_spc_events_names[i].counter_description,
325 OPAL_INFO_LVL_4, MPI_T_PVAR_CLASS_SIZE,
326 MCA_BASE_VAR_TYPE_UNSIGNED_LONG_LONG, NULL, MPI_T_BIND_NO_OBJECT,
327 MCA_BASE_PVAR_FLAG_READONLY | MCA_BASE_PVAR_FLAG_CONTINUOUS,
328 ompi_spc_get_count, NULL, ompi_spc_notify, NULL);
329
330
331
332 if( ret >= 0 ) {
333 if( mpi_t_offset == -1 ) {
334 mpi_t_offset = ret;
335 }
336 }
337 if( (ret < 0) || (ret != (mpi_t_offset + found - 1)) ) {
338 mpi_t_enabled = false;
339 opal_show_help("help-mpi-runtime.txt", "spc: MPI_T disabled", true);
340 break;
341 }
342 }
343
344 SET_SPC_BIT(ompi_spc_timer_event, OMPI_SPC_MATCH_TIME);
345 opal_argv_free(arg_strings);
346 }
347
348
349
350
351 static void ompi_spc_dump(void)
352 {
353 int i, j, world_size, offset;
354 long long *recv_buffer = NULL, *send_buffer;
355
356 int rank = ompi_comm_rank(ompi_spc_comm);
357 world_size = ompi_comm_size(ompi_spc_comm);
358
359
360 for(i = 0; i < OMPI_SPC_NUM_COUNTERS; i++) {
361 if( IS_SPC_BIT_SET(ompi_spc_timer_event, i) ) {
362 SPC_CYCLES_TO_USECS(&ompi_spc_events[i].value);
363 }
364 }
365
366
367 send_buffer = (long long*)malloc(OMPI_SPC_NUM_COUNTERS * sizeof(long long));
368 if (NULL == send_buffer) {
369 opal_show_help("help-mpi-runtime.txt", "lib-call-fail", true,
370 "malloc", __FILE__, __LINE__);
371 return;
372 }
373 for(i = 0; i < OMPI_SPC_NUM_COUNTERS; i++) {
374 send_buffer[i] = (long long)ompi_spc_events[i].value;
375 }
376 if( 0 == rank ) {
377 recv_buffer = (long long*)malloc(world_size * OMPI_SPC_NUM_COUNTERS * sizeof(long long));
378 if (NULL == recv_buffer) {
379 opal_show_help("help-mpi-runtime.txt", "lib-call-fail", true,
380 "malloc", __FILE__, __LINE__);
381 return;
382 }
383 }
384 (void)ompi_spc_comm->c_coll->coll_gather(send_buffer, OMPI_SPC_NUM_COUNTERS, MPI_LONG_LONG,
385 recv_buffer, OMPI_SPC_NUM_COUNTERS, MPI_LONG_LONG,
386 0, ompi_spc_comm,
387 ompi_spc_comm->c_coll->coll_gather_module);
388
389
390 if(rank == 0) {
391 opal_output(0, "Open MPI Software-based Performance Counters:\n");
392 offset = 0;
393 for(j = 0; j < world_size; j++) {
394 opal_output(0, "MPI_COMM_WORLD Rank %d:\n", j);
395 for(i = 0; i < OMPI_SPC_NUM_COUNTERS; i++) {
396
397 if( 0 == recv_buffer[offset+i] ) {
398 continue;
399 }
400 opal_output(0, "%s -> %lld\n", ompi_spc_events[i].name, recv_buffer[offset+i]);
401 }
402 opal_output(0, "\n");
403 offset += OMPI_SPC_NUM_COUNTERS;
404 }
405 printf("###########################################################################\n");
406 printf("NOTE: Any counters not shown here were either disabled or had a value of 0.\n");
407 printf("###########################################################################\n");
408
409 free(recv_buffer);
410 }
411 free(send_buffer);
412
413 ompi_spc_comm->c_coll->coll_barrier(ompi_spc_comm, ompi_spc_comm->c_coll->coll_barrier_module);
414 }
415
416
417 void ompi_spc_fini(void)
418 {
419 if (SPC_ENABLE == 1 && ompi_mpi_spc_dump_enabled) {
420 ompi_spc_dump();
421 }
422
423 free(ompi_spc_events); ompi_spc_events = NULL;
424 ompi_comm_free(&ompi_spc_comm);
425 }
426
427
428 void ompi_spc_record(unsigned int event_id, ompi_spc_value_t value)
429 {
430
431 if( OPAL_UNLIKELY(IS_SPC_BIT_SET(ompi_spc_attached_event, event_id)) ) {
432 OPAL_THREAD_ADD_FETCH_SIZE_T(&(ompi_spc_events[event_id].value), value);
433 }
434 }
435
436
437
438
439
440 void ompi_spc_timer_start(unsigned int event_id, opal_timer_t *cycles)
441 {
442
443
444
445 if( OPAL_UNLIKELY(IS_SPC_BIT_SET(ompi_spc_attached_event, event_id) && *cycles == 0) ) {
446 *cycles = opal_timer_base_get_cycles();
447 }
448 }
449
450
451
452
453
454 void ompi_spc_timer_stop(unsigned int event_id, opal_timer_t *cycles)
455 {
456
457 if( OPAL_UNLIKELY(IS_SPC_BIT_SET(ompi_spc_attached_event, event_id)) ) {
458 *cycles = opal_timer_base_get_cycles() - *cycles;
459 OPAL_THREAD_ADD_FETCH_SIZE_T(&ompi_spc_events[event_id].value, (size_t) *cycles);
460 }
461 }
462
463
464
465
466 void ompi_spc_user_or_mpi(int tag, ompi_spc_value_t value, unsigned int user_enum, unsigned int mpi_enum)
467 {
468 SPC_RECORD( (tag >= 0 ? user_enum : mpi_enum), value);
469 }
470
471
472
473
474
475 void ompi_spc_update_watermark(unsigned int watermark_enum, unsigned int value_enum)
476 {
477
478 if( OPAL_UNLIKELY(IS_SPC_BIT_SET(ompi_spc_attached_event, watermark_enum) &&
479 IS_SPC_BIT_SET(ompi_spc_attached_event, value_enum)) ) {
480
481
482
483 if(ompi_spc_events[value_enum].value > ompi_spc_events[watermark_enum].value) {
484 ompi_spc_events[watermark_enum].value = ompi_spc_events[value_enum].value;
485 }
486 }
487 }
488
489
490
491 void ompi_spc_cycles_to_usecs(ompi_spc_value_t *cycles)
492 {
493 *cycles = *cycles / sys_clock_freq_mhz;
494 }