root/opal/util/timings.h

/* [<][>][^][v][top][bottom][index][help] */

INCLUDED FROM


   1 /*
   2  * Copyright (C) 2014      Artem Polyakov <artpol84@gmail.com>
   3  * Copyright (c) 2014-2017 Intel, Inc. All rights reserved.
   4  * Copyright (c) 2017-2018 Mellanox Technologies Ltd. All rights reserved.
   5  * $COPYRIGHT$
   6  *
   7  * Additional copyrights may follow
   8  *
   9  * $HEADER$
  10  */
  11 
  12 #ifndef OPAL_UTIL_TIMING_H
  13 #define OPAL_UTIL_TIMING_H
  14 
  15 #include "opal_config.h"
  16 
  17 #include "opal/class/opal_list.h"
  18 #include "opal/runtime/opal_params.h"
  19 
  20 typedef enum {
  21     OPAL_TIMING_AUTOMATIC_TIMER,
  22     OPAL_TIMING_GET_TIME_OF_DAY,
  23     OPAL_TIMING_CYCLE_NATIVE,
  24     OPAL_TIMING_USEC_NATIVE
  25 } opal_timer_type_t;
  26 
  27 #if OPAL_ENABLE_TIMING
  28 
  29 typedef double (*opal_timing_ts_func_t)(void);
  30 
  31 #define OPAL_TIMING_STR_LEN 256
  32 
  33 typedef struct {
  34     char id[OPAL_TIMING_STR_LEN], cntr_env[OPAL_TIMING_STR_LEN];
  35     int enabled, error;
  36     int cntr;
  37     double ts;
  38     opal_timing_ts_func_t get_ts;
  39 } opal_timing_env_t;
  40 
  41 opal_timing_ts_func_t opal_timing_ts_func(opal_timer_type_t type);
  42 
  43 #define OPAL_TIMING_ENV_START_TYPE(func, _nm, type, prefix)                       \
  44     do {                                                                          \
  45         char *ptr = NULL;                                                         \
  46         char *_prefix = prefix;                                                   \
  47         int n;                                                                    \
  48         if( NULL == prefix ){                                                     \
  49             _prefix = "";                                                         \
  50         }                                                                         \
  51         (_nm)->error = 0;                                                         \
  52         n = snprintf((_nm)->id, OPAL_TIMING_STR_LEN, "%s%s", _prefix, func);      \
  53         if( n > OPAL_TIMING_STR_LEN ){                                            \
  54              (_nm)->error = 1;                                                    \
  55         }                                                                         \
  56         n = sprintf((_nm)->cntr_env,"OMPI_TIMING_%s%s_CNT", prefix, (_nm)->id);   \
  57         if( n > OPAL_TIMING_STR_LEN ){                                            \
  58             (_nm)->error = 1;                                                     \
  59         }                                                                         \
  60         ptr = getenv((_nm)->id);                                                  \
  61         if( NULL == ptr || strcmp(ptr, "1")){                                     \
  62             (_nm)->enabled = 0;                                                   \
  63         }                                                                         \
  64         (_nm)->get_ts = opal_timing_ts_func(type);                                \
  65         ptr = getenv("OPAL_TIMING_ENABLE");                                       \
  66         if (NULL != ptr) {                                                        \
  67             (_nm)->enabled = atoi(ptr);                                           \
  68         }                                                                         \
  69         (_nm)->cntr = 0;                                                          \
  70         ptr = getenv((_nm)->id);                                                  \
  71         if( NULL != ptr ){                                                        \
  72             (_nm)->cntr = atoi(ptr);                                              \
  73         }                                                                         \
  74         (_nm)->ts = (_nm)->get_ts();                                              \
  75         if ( 0 != (_nm)->error ){                                                 \
  76             (_nm)->enabled = 0;                                                   \
  77         }                                                                         \
  78     } while(0)
  79 
  80 #define OPAL_TIMING_ENV_INIT(name)                                                \
  81     opal_timing_env_t name ## _val, *name = &(name ## _val);                      \
  82     OPAL_TIMING_ENV_START_TYPE(__func__, name, OPAL_TIMING_AUTOMATIC_TIMER, "");
  83 
  84 
  85 /* We use function names for identification
  86  * however this might be a problem for the private
  87  * functions declared as static as their names may
  88  * conflict.
  89  * Use prefix to do a finer-grained identification if needed
  90  */
  91 #define OPAL_TIMING_ENV_INIT_PREFIX(prefix, name)                                 \
  92     do {                                                                          \
  93         opal_timing_env_t name ## _val, *name = &(name ## _val);                  \
  94         *name = OPAL_TIMING_ENV_START_TYPE(__func__, name, OPAL_TIMING_AUTOMATIC_TIMER, prefix); \
  95     } while(0)
  96 
  97 #define OPAL_TIMING_ENV_NEXT(h, ...)                                              \
  98     do {                                                                          \
  99         int n;                                                                    \
 100         char buf1[OPAL_TIMING_STR_LEN], buf2[OPAL_TIMING_STR_LEN];                \
 101         double time;                                                              \
 102         char *filename;                                                           \
 103         if( h->enabled ){                                                         \
 104             /* enabled codepath */                                                \
 105             time = h->get_ts() - h->ts;                                           \
 106             n = snprintf(buf1, OPAL_TIMING_STR_LEN, "OMPI_TIMING_%s_DESC_%d", h->id, h->cntr); \
 107             if ( n > OPAL_TIMING_STR_LEN ){                                       \
 108                 h->error = 1;                                                     \
 109             }                                                                     \
 110             n = snprintf(buf2, OPAL_TIMING_STR_LEN, __VA_ARGS__ );                \
 111             if ( n > OPAL_TIMING_STR_LEN ){                                       \
 112                 h->error = 1;                                                     \
 113             }                                                                     \
 114             setenv(buf1, buf2, 1);                                                \
 115             n = snprintf(buf1, OPAL_TIMING_STR_LEN, "OMPI_TIMING_%s_VAL_%d", h->id, h->cntr);  \
 116             if ( n > OPAL_TIMING_STR_LEN ){                                       \
 117                 h->error = 1;                                                     \
 118             }                                                                     \
 119             n = snprintf(buf2, OPAL_TIMING_STR_LEN, "%lf", time);                 \
 120             if ( n > OPAL_TIMING_STR_LEN ){                                       \
 121                 h->error = 1;                                                     \
 122             }                                                                     \
 123             setenv(buf1, buf2, 1);                                                \
 124             filename = strrchr(__FILE__, '/');                                    \
 125             filename = (filename == NULL) ? strdup(__FILE__) : filename+1;        \
 126             n = snprintf(buf1, OPAL_TIMING_STR_LEN, "OMPI_TIMING_%s_FILE_%d", h->id, h->cntr); \
 127             if ( n > OPAL_TIMING_STR_LEN ){                                       \
 128                 h->error = 1;                                                     \
 129             }                                                                     \
 130             n = snprintf(buf2, OPAL_TIMING_STR_LEN, "%s", filename);              \
 131             if ( n > OPAL_TIMING_STR_LEN ){                                       \
 132                 h->error = 1;                                                     \
 133             }                                                                     \
 134             setenv(buf1, buf2, 1);                                                \
 135             h->cntr++;                                                            \
 136             sprintf(buf1, "%d", h->cntr);                                         \
 137             setenv(h->cntr_env, buf1, 1);                                         \
 138             /* We don't include env operations into the consideration.
 139              * Hopefully this will help to make measurements more accurate.
 140              */                                                                   \
 141             h->ts = h->get_ts();                                                  \
 142         }                                                                         \
 143         if (h->error) {                                                           \
 144             n = snprintf(buf1, OPAL_TIMING_STR_LEN, "OMPI_TIMING_%s_ERROR", h->id);\
 145             if ( n > OPAL_TIMING_STR_LEN ){                                       \
 146                 h->error = 1;                                                     \
 147             }                                                                     \
 148             n = snprintf(buf2, OPAL_TIMING_STR_LEN, "%d", h->error);              \
 149             if ( n > OPAL_TIMING_STR_LEN ){                                       \
 150                 h->error = 1;                                                     \
 151             }                                                                     \
 152             setenv(buf1, buf2, 1);                                                \
 153         }                                                                         \
 154     } while(0)
 155 
 156 /* This function supposed to be called from the code that will
 157  * do the postprocessing, i.e. OMPI timing portion that will
 158  * do the reduction of accumulated values
 159  */
 160 #define OPAL_TIMING_ENV_CNT_PREFIX(prefix, func, _cnt)                            \
 161     do {                                                                          \
 162         char ename[OPAL_TIMING_STR_LEN];                                          \
 163         char *ptr = NULL;                                                         \
 164         int n = snprintf(ename, OPAL_TIMING_STR_LEN, "OMPI_TIMING_%s%s_CNT", prefix, func);    \
 165         (_cnt) = 0;                                                               \
 166         if ( n <= OPAL_TIMING_STR_LEN ){                                          \
 167             ptr = getenv(ename);                                                  \
 168             if( NULL != ptr ){ (_cnt) = atoi(ptr); };                             \
 169         }                                                                         \
 170     } while(0)
 171 
 172 #define OPAL_TIMING_ENV_ERROR_PREFIX(prefix, func, _err)                          \
 173     do {                                                                          \
 174         char ename[OPAL_TIMING_STR_LEN];                                          \
 175         (_err) = 0;                                                               \
 176         char *ptr = NULL;                                                         \
 177         int n = snprintf(ename, OPAL_TIMING_STR_LEN, "OMPI_TIMING_%s%s_ERROR", prefix, func);    \
 178         if ( n <= OPAL_TIMING_STR_LEN ){                                          \
 179             ptr = getenv(ename);                                                  \
 180             if( NULL != ptr ){ (_err) = atoi(ptr); };                             \
 181         }                                                                         \
 182     } while(0)
 183 
 184 #define OPAL_TIMING_ENV_CNT(func, _cnt)                                           \
 185     OPAL_TIMING_ENV_CNT_PREFIX("", func, _cnt)
 186 
 187 #define OPAL_TIMING_ENV_GETDESC_PREFIX(prefix, filename, func, i, desc, _t)       \
 188     do {                                                                          \
 189         char vname[OPAL_TIMING_STR_LEN];                                          \
 190         (_t) = 0.0;                                                               \
 191         sprintf(vname, "OMPI_TIMING_%s%s_FILE_%d", prefix, func, i);              \
 192         *filename = getenv(vname);                                                \
 193         sprintf(vname, "OMPI_TIMING_%s%s_DESC_%d", prefix, func, i);              \
 194         *desc = getenv(vname);                                                    \
 195         sprintf(vname, "OMPI_TIMING_%s%s_VAL_%d", prefix, func, i);               \
 196         char *ptr = getenv(vname);                                                \
 197         if ( NULL != ptr ) {                                                      \
 198             sscanf(ptr,"%lf", &(_t));                                             \
 199         }                                                                         \
 200     } while(0)
 201 
 202 #define OPAL_TIMING_ENV_GETDESC(file, func, index, desc)                          \
 203     OPAL_TIMING_ENV_GETDESC_PREFIX("", file, func, index, desc)
 204 
 205 #else
 206 
 207 #define OPAL_TIMING_ENV_START_TYPE(func, type, prefix)
 208 
 209 #define OPAL_TIMING_ENV_INIT(name)
 210 
 211 #define OPAL_TIMING_ENV_INIT_PREFIX(prefix, name)
 212 
 213 #define OPAL_TIMING_ENV_NEXT(h, ... )
 214 
 215 #define OPAL_TIMING_ENV_CNT_PREFIX(prefix, func)
 216 
 217 #define OPAL_TIMING_ENV_CNT(func)
 218 
 219 #define OPAL_TIMING_ENV_GETDESC_PREFIX(prefix, func, i, desc)
 220 
 221 #define OPAL_TIMING_ENV_GETDESC(func, index, desc)
 222 
 223 #define OPAL_TIMING_ENV_ERROR_PREFIX(prefix, func)
 224 
 225 #endif
 226 
 227 #endif

/* [<][>][^][v][top][bottom][index][help] */