openpmix-src 0.1.0

Vendored build of OpenPMIx, developed for use by the Lamellar runtime.
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
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
/*
 * Copyright (C) 2014      Artem Polyakov <artpol84@gmail.com>
 * Copyright (c) 2014-2020 Intel, Inc.  All rights reserved.
 * Copyright (c) 2015      Research Organization for Information Science
 *                         and Technology (RIST). All rights reserved.
 * Copyright (c) 2021      Nanook Consulting.  All rights reserved.
 * $COPYRIGHT$
 *
 * Additional copyrights may follow
 *
 * $HEADER$
 */

#ifndef PMIX_UTIL_TIMING_H
#define PMIX_UTIL_TIMING_H

#include "src/include/pmix_config.h"

#include "src/class/pmix_list.h"

#if PMIX_ENABLE_TIMING

#    define PMIX_TIMING_DESCR_MAX   1024
#    define PMIX_TIMING_BUFSIZE     32
#    define PMIX_TIMING_OUTBUF_SIZE (10 * 1024)

typedef enum {
    PMIX_TIMING_TRACE,
    PMIX_TIMING_INTDESCR,
    PMIX_TIMING_INTBEGIN,
    PMIX_TIMING_INTEND
} pmix_event_type_t;

typedef struct {
    pmix_list_item_t super;
    int fib;
    pmix_event_type_t type;
    const char *func;
    const char *file;
    int line;
    double ts, ts_ovh;
    char descr[PMIX_TIMING_DESCR_MAX];
    int id;
} pmix_timing_event_t;

typedef double (*get_ts_t)(void);

typedef struct pmix_timing_t {
    int next_id_cntr;
    // not thread safe!
    // The whole implementation is not thread safe now
    // since it is supposed to be used in service
    // thread only. Fix in the future or now?
    int current_id;
    pmix_list_t *events;
    pmix_timing_event_t *buffer;
    size_t buffer_offset, buffer_size;
    get_ts_t get_ts;
} pmix_timing_t;

typedef struct {
    pmix_timing_t *t;
    pmix_timing_event_t *ev;
    int errcode;
} pmix_timing_prep_t;

/* Pass down our namespace and rank for pretty-print purposes */
PMIX_EXPORT void pmix_init_id(char *nspace, int rank);

/**
 * Initialize timing structure.
 *
 * @param t pointer to the timing handler structure
 */
PMIX_EXPORT void pmix_timing_init(pmix_timing_t *t);

/**
 * Prepare timing event, do all printf-like processing.
 * Should not be directly used - for service purposes only.
 *
 * @param t pointer to the timing handler structure
 * @param fmt printf-like format
 * @param ... other parameters that should be converted to string representation
 *
 * @retval partly filled pmix_timing_prep_t structure
 */
PMIX_EXPORT pmix_timing_prep_t pmix_timing_prep_ev(pmix_timing_t *t, const char *fmt, ...);

/**
 * Prepare timing event, ignore printf-like processing.
 * Should not be directly used - for service purposes only.
 *
 * @param t pointer to the timing handler structure
 * @param fmt printf-like format
 * @param ... other parameters that should be converted to string representation
 *
 * @retval partly filled pmix_timing_prep_t structure
 */
PMIX_EXPORT pmix_timing_prep_t pmix_timing_prep_ev_end(pmix_timing_t *t, const char *fmt, ...);

/**
 * Enqueue timing event into the list of events in handler 't'.
 *
 * @param p result of pmix_timing_prep_ev
 * @param func function name where event occurs
 * @param file file name where event occurs
 * @param line line number in the file
 *
 * @retval
 */
PMIX_EXPORT void pmix_timing_add_step(pmix_timing_prep_t p, const char *func, const char *file,
                                      int line);

/**
 * Enqueue the description of the interval into a list of events
 * in handler 't'.
 *
 * @param p result of pmix_timing_prep_ev
 * @param func function name where event occurs
 * @param file file name where event occurs
 * @param line line number in the file
 *
 * @retval id of event interval
 */
PMIX_EXPORT int pmix_timing_descr(pmix_timing_prep_t p, const char *func, const char *file,
                                  int line);

/**
 * Enqueue the beginning of timing interval that already has the
 * description and assigned id into the list of events
 * in handler 't'.
 *
 * @param p result of pmix_timing_prep_ev
 * @param func function name where event occurs
 * @param file file name where event occurs
 * @param line line number in the file
 *
 * @retval
 */
PMIX_EXPORT void pmix_timing_start_id(pmix_timing_t *t, int id, const char *func, const char *file,
                                      int line);

/**
 * Enqueue the end of timing interval that already has
 * description and assigned id into the list of events
 * in handler 't'.
 *
 * @param p result of pmix_timing_prep_ev
 * @param func function name where event occurs
 * @param file file name where event occurs
 * @param line line number in the file
 *
 * @retval
 */
PMIX_EXPORT void pmix_timing_end(pmix_timing_t *t, int id, const char *func, const char *file,
                                 int line);

/**
 * Enqueue both description and start of timing interval
 * into the list of events and assign its id.
 *
 * @param p result of pmix_timing_prep_ev
 * @param func function name where event occurs
 * @param file file name where event occurs
 * @param line line number in the file
 *
 * @retval interval id
 */
static inline int pmix_timing_start_init(pmix_timing_prep_t p, const char *func, const char *file,
                                         int line)
{
    int id = pmix_timing_descr(p, func, file, line);
    if (id < 0)
        return id;
    pmix_timing_start_id(p.t, id, func, file, line);
    return id;
}

/**
 * The wrapper that is used to stop last measurement in PMIX_TIMING_MNEXT.
 *
 * @param p result of pmix_timing_prep_ev
 * @param func function name where event occurs
 * @param file file name where event occurs
 * @param line line number in the file
 *
 * @retval interval id
 */
PMIX_EXPORT void pmix_timing_end_prep(pmix_timing_prep_t p, const char *func, const char *file,
                                      int line);

/**
 * Report all events that were enqueued in the timing handler 't'.
 * - if fname == NULL the output will be done using pmix_output and
 * each line will be prefixed with "prefix" to ease grep'ing.
 * - otherwise the corresponding file will be used for output in "append" mode
 * WARRNING: not all filesystems provide enough support for that feature, some records may
 * disappear.
 *
 * @param t timing handler
 * @param account_overhead consider malloc overhead introduced by timing code
 * @param prefix prefix to use when no fname was specified to ease grep'ing
 * @param fname name of the output file (may be NULL)
 *
 * @retval PMIX_SUCCESS On success
 * @retval PMIX_ERROR or PMIX_ERR_OUT_OF_RESOURCE On failure
 */
PMIX_EXPORT pmix_status_t pmix_timing_report(pmix_timing_t *t, char *fname);

/**
 * Report all intervals that were enqueued in the timing handler 't'.
 * - if fname == NULL the output will be done using pmix_output and
 * each line will be prefixed with "prefix" to ease grep'ing.
 * - otherwise the corresponding file will be used for output in "append" mode
 * WARRNING: not all filesystems provide enough support for that feature, some records may
 * disappear.
 *
 * @param t timing handler
 * @param account_overhead consider malloc overhead introduced by timing code
 * @param fname name of the output file (may be NULL)
 *
 * @retval PMIX_SUCCESS On success
 * @retval PMIX_ERROR or PMIX_ERR_OUT_OF_RESOURCE On failure
 */
PMIX_EXPORT pmix_status_t pmix_timing_deltas(pmix_timing_t *t, char *fname);

/**
 * Release all memory allocated for the timing handler 't'.
 *
 * @param t timing handler
 *
 * @retval
 */
PMIX_EXPORT void pmix_timing_release(pmix_timing_t *t);

/**
 * Macro for passing down process id - compiled out
 * when configured without --enable-timing
 */
#    define PMIX_TIMING_ID(n, r) pmix_timing_id((n), (r));

/**
 * Main macro for use in declaring pmix timing handler;
 * will be "compiled out" when PMIX is configured without
 * --enable-timing.
 *
 */
#    define PMIX_TIMING_DECLARE(t) \
        pmix_timing_t t; /* need semicolon here to avoid warnings when not enabled */

/**
 * Main macro for use in declaring external pmix timing handler;
 * will be "compiled out" when PMIX is configured without
 * --enable-timing.
 *
 */
#    define PMIX_TIMING_DECLARE_EXT(x, t) \
        x extern pmix_timing_t t; /* need semicolon here to avoid warnings when not enabled */

/**
 * Main macro for use in initializing pmix timing handler;
 * will be "compiled out" when PMIX is configured without
 * --enable-timing.
 *
 * @see pmix_timing_init()
 */
#    define PMIX_TIMING_INIT(t) pmix_timing_init(t)

/**
 * Macro that enqueues event with its description to the specified
 * timing handler;
 * will be "compiled out" when PMIX is configured without
 * --enable-timing.
 *
 * @see pmix_timing_add_step()
 */
#    define PMIX_TIMING_EVENT(x) \
        pmix_timing_add_step(pmix_timing_prep_ev x, __FUNCTION__, __FILE__, __LINE__)

/**
 * MDESCR: Measurement DESCRiption
 * Introduce new timing measurement with string description for the specified
 * timing handler;
 * will be "compiled out" when PMIX is configured without
 * --enable-timing.
 *
 * @see pmix_timing_descr()
 */
#    define PMIX_TIMING_MDESCR(x) \
        pmix_timing_descr(pmix_timing_prep_ev x, __FUNCTION__, __FILE__, __LINE__)

/**
 * MSTART_ID: Measurement START by ID.
 * Marks the beginning of the measurement with ID=id on the
 * specified timing handler;
 * will be "compiled out" when PMIX is configured without
 * --enable-timing.
 *
 * @see pmix_timing_start_id()
 */
#    define PMIX_TIMING_MSTART_ID(t, id) \
        pmix_timing_start_id(t, id, __FUNCTION__, __FILE__, __LINE__)

/**
 * MSTART: Measurement START
 * Introduce new timing measurement conjuncted with its start
 * on the specified timing handler;
 * will be "compiled out" when PMIX is configured without
 * --enable-timing.
 *
 * @see pmix_timing_start_init()
 */
#    define PMIX_TIMING_MSTART(x) \
        pmix_timing_start_init(pmix_timing_prep_ev x, __FUNCTION__, __FILE__, __LINE__)

/**
 * MSTOP: STOP Measurement
 * Finishes the most recent measurement on the specified timing handler;
 * will be "compiled out" when PMIX is configured without
 * --enable-timing.
 *
 * @see pmix_timing_end()
 */
#    define PMIX_TIMING_MSTOP(t) pmix_timing_end(t, -1, __FUNCTION__, __FILE__, __LINE__)

/**
 * MSTOP_ID: STOP Measurement with ID=id.
 * Finishes the measurement with give ID on the specified timing handler;
 * will be "compiled out" when PMIX is configured without
 * --enable-timing.
 *
 * @see pmix_timing_end()
 */
#    define PMIX_TIMING_MSTOP_ID(t, id) pmix_timing_end(t, id, __FUNCTION__, __FILE__, __LINE__)

/**
 * MNEXT: start NEXT Measurement
 * Convenient macro, may be implemented with the sequence of three previously
 * defined macros:
 * - finish current measurement (PMIX_TIMING_MSTOP);
 * - introduce new timing measurement (PMIX_TIMING_MDESCR);
 * - starts next measurement (PMIX_TIMING_MSTART_ID)
 * on the specified timing handler;
 * will be "compiled out" when PMIX is configured without
 * --enable-timing.
 *
 * @see pmix_timing_start_init()
 */
#    define PMIX_TIMING_MNEXT(x)                                                            \
        (pmix_timing_end_prep(pmix_timing_prep_ev_end x, __FUNCTION__, __FILE__, __LINE__), \
         pmix_timing_start_init(pmix_timing_prep_ev x, __FUNCTION__, __FILE__, __LINE__))

/**
 * The macro for use in reporting collected events with absolute values;
 * will be "compiled out" when PMIX is configured without
 * --enable-timing.
 *
 * @param enable flag that enables/disables reporting. Used for fine-grained timing.
 * @see pmix_timing_report()
 */
#    define PMIX_TIMING_REPORT(enable, t)                  \
        {                                                  \
            if (enable) {                                  \
                pmix_timing_report(t, pmix_timing_output); \
            }                                              \
        }

/**
 * The macro for use in reporting collected events with relative times;
 * will be "compiled out" when PMIX is configured without
 * --enable-timing.
 *
 * @param enable flag that enables/disables reporting. Used for fine-grained timing.
 * @see pmix_timing_deltas()
 */
#    define PMIX_TIMING_DELTAS(enable, t)                  \
        {                                                  \
            if (enable) {                                  \
                pmix_timing_deltas(t, pmix_timing_output); \
            }                                              \
        }

/**
 * Main macro for use in releasing allocated resources;
 * will be "compiled out" when PMIX is configured without
 * --enable-timing.
 *
 * @see pmix_timing_release()
 */
#    define PMIX_TIMING_RELEASE(t) pmix_timing_release(t)

#else

#    define PMIX_TIMING_ID(n, r)

#    define PMIX_TIMING_DECLARE(t)

#    define PMIX_TIMING_DECLARE_EXT(x, t)

#    define PMIX_TIMING_INIT(t)

#    define PMIX_TIMING_EVENT(x)

#    define PMIX_TIMING_MDESCR(x)

#    define PMIX_TIMING_MSTART_ID(t, id)

#    define PMIX_TIMING_MSTART(x)

#    define PMIX_TIMING_MSTOP(t)

#    define PMIX_TIMING_MSTOP_ID(t, id)

#    define PMIX_TIMING_MNEXT(x)

#    define PMIX_TIMING_REPORT(enable, t)

#    define PMIX_TIMING_DELTAS(enable, t)

#    define PMIX_TIMING_RELEASE(t)

#endif

#endif