NEURON
profiler_interface.h
Go to the documentation of this file.
1 /*
2 # =============================================================================
3 # Copyright (c) 2016 - 2021 Blue Brain Project/EPFL
4 #
5 # See top-level LICENSE file for details.
6 # =============================================================================
7 */
8 
9 #pragma once
10 
11 #include <initializer_list>
12 #include <type_traits>
13 
14 #if defined(NRN_CALIPER)
15 #include <caliper/cali.h>
16 #endif
17 
18 #if defined(CRAYPAT)
19 #include <pat_api.h>
20 #endif
21 
22 #if defined(TAU)
23 #include <TAU.h>
24 #endif
25 
26 #if defined(LIKWID_PERFMON)
27 #include <likwid.h>
28 #endif
29 
30 namespace nrn {
31 
32 namespace detail {
33 
34 /*! \class Instrumentor
35  * \brief Instrumentation infrastructure for benchmarking and profiling.
36  *
37  * The Instrumentor class exposes static methods that can be used to
38  * toggle with fine-grained resolution the profiling of specific
39  * areas within the code.
40  */
41 template <class... TProfilerImpl>
42 struct Instrumentor {
43 #pragma clang diagnostic push
44 #pragma clang diagnostic ignored "-Wunused-value"
45  /*! \fn phase_begin
46  * \brief Activate the collection of profiling data within a code region.
47  *
48  * This function semantically defines the beginning of a region
49  * of code that the user wishes to profile.
50  * Loops through all enabled profilers and calls the relevant
51  * `phase_begin` function.
52  * This function should have a non-empty implementation only for
53  * profilers that allow multiple code regions with different names
54  * to be profiled concurrently.
55  *
56  * @param name the (unique) identifier of the code region to be profiled
57  */
58  inline static void phase_begin(const char* name) {
59  std::initializer_list<int>{(TProfilerImpl::phase_begin(name), 0)...};
60  }
61 
62  /*! \fn phase_end
63  * \brief Deactivate the collection of profiling data within a code region.
64  *
65  * This function semantically defines the end of a region
66  * of code that the user wishes to profile.
67  * Loops through all enabled profilers and calls the relevant
68  * `phase_end` function.
69  * This function should have a non-empty implementation only for
70  * profilers that allow multiple code regions with different names
71  * to be profiled concurrently.
72  *
73  * @param name the (unique) identifier of the code region to be profiled
74  */
75  inline static void phase_end(const char* name) {
76  std::initializer_list<int>{(TProfilerImpl::phase_end(name), 0)...};
77  }
78 
79  /*! \fn start_profile
80  * \brief Globally activate the collection of profiling data.
81  *
82  * Activate the collection of profiler data without defining
83  * a region of interest with a given name, as opposed to `phase_begin`.
84  * Loops through all enabled profilers and calls the relevant
85  * `start_profile` function.
86  * This function should have a non-empty implementation only for
87  * profilers that expose simply a global begin/end interface, without
88  * named regions.
89  */
90  inline static void start_profile() {
91  std::initializer_list<int>{(TProfilerImpl::start_profile(), 0)...};
92  }
93 
94  /*! \fn stop_profile
95  * \brief Globally deactivate the collection of profiling data.
96  *
97  * Deactivate the collection of profiler data without defining
98  * a region of interest with a given name, as opposed to `phase_end`.
99  * Loops through all enabled profilers and calls the relevant
100  * `stop_profile` function.
101  * This function should have a non-empty implementation only for
102  * profilers that expose simply a global begin/end interface, without
103  * named regions.
104  */
105  inline static void stop_profile() {
106  std::initializer_list<int>{(TProfilerImpl::stop_profile(), 0)...};
107  }
108 
109  /*! \fn init_profile
110  * \brief Initialize the profiler.
111  *
112  * Initialize a profiler's internal structure, without activating yet
113  * any data collection, similar in concept to MPI_Init.
114  * Loops through all enabled profilers and calls the relevant
115  * `init_profile` function.
116  * This function should have a non-empty implementation only for
117  * profilers that require special initialization, typically before
118  * any memory allocation is done.
119  */
120  inline static void init_profile() {
121  std::initializer_list<int>{(TProfilerImpl::init_profile(), 0)...};
122  }
123 
124  /*! \fn finalize_profile
125  * \brief Finalize the profiler.
126  *
127  * Finalize a profiler's internal structure, without activating yet
128  * any data collection, similar in concept to MPI_Finalize.
129  * Loops through all enabled profilers and calls the relevant
130  * `finalize_profile` function.
131  * This function should have a non-empty implementation only for
132  * profilers that require special finalization.
133  */
134  inline static void finalize_profile() {
135  std::initializer_list<int>{(TProfilerImpl::finalize_profile(), 0)...};
136  }
137 #pragma clang diagnostic pop
138 };
139 
140 #if defined(NRN_CALIPER)
141 
142 struct Caliper {
143  inline static void phase_begin(const char* name) {
144  CALI_MARK_BEGIN(name);
145  };
146 
147  inline static void phase_end(const char* name) {
148  CALI_MARK_END(name);
149  };
150 
151  inline static void start_profile(){};
152 
153  inline static void stop_profile(){};
154 
155  inline static void init_profile(){};
156 
157  inline static void finalize_profile(){};
158 };
159 
160 #endif
161 
162 #if defined(CRAYPAT)
163 
164 struct CrayPat {
165  inline static void phase_begin(const char* name){};
166 
167  inline static void phase_end(const char* name){};
168 
169  inline static void start_profile() {
170  PAT_record(PAT_STATE_ON);
171  };
172 
173  inline static void stop_profile() {
174  PAT_record(PAT_STATE_OFF);
175  };
176 
177  inline static void init_profile(){};
178 
179  inline static void finalize_profile(){};
180 };
181 #endif
182 
183 #if defined(TAU)
184 
185 struct Tau {
186  inline static void phase_begin(const char* name){};
187 
188  inline static void phase_end(const char* name){};
189 
190  inline static void start_profile() {
191  TAU_ENABLE_INSTRUMENTATION();
192  };
193 
194  inline static void stop_profile() {
195  TAU_DISABLE_INSTRUMENTATION();
196  };
197 
198  inline static void init_profile(){};
199 
200  inline static void finalize_profile(){};
201 };
202 
203 #endif
204 
205 #if defined(LIKWID_PERFMON)
206 
207 struct Likwid {
208  inline static void phase_begin(const char* name) {
209  LIKWID_MARKER_START(name);
210  };
211 
212  inline static void phase_end(const char* name) {
213  LIKWID_MARKER_STOP(name);
214  };
215 
216  inline static void start_profile(){};
217 
218  inline static void stop_profile(){};
219 
220  inline static void init_profile() {
221  LIKWID_MARKER_INIT;
222 
223 #pragma omp parallel
224  { LIKWID_MARKER_THREADINIT; }
225  };
226 
227  inline static void finalize_profile() {
228  LIKWID_MARKER_CLOSE;
229  };
230 };
231 
232 #endif
233 
235  inline static void phase_begin(const char* name){};
236  inline static void phase_end(const char* name){};
237  inline static void start_profile(){};
238  inline static void stop_profile(){};
239  inline static void init_profile(){};
240  inline static void finalize_profile(){};
241 };
242 
244 #if defined NRN_CALIPER
245  detail::Caliper,
246 #endif
247 #if defined(CRAYPAT)
248  detail::CrayPat,
249 #endif
250 #if defined(TAU)
251  detail::Tau,
252 #endif
253 #if defined(LIKWID_PERFMON)
254  detail::Likwid,
255 #endif
257 } // namespace detail
258 
259 namespace Instrumentor {
260 struct phase {
261  const char* phase_name;
262  phase(const char* name)
263  : phase_name(name) {
265  }
266  ~phase() {
268  }
269 };
270 
271 inline static void start_profile() {
273 }
274 
275 inline static void stop_profile() {
277 }
278 
279 inline static void phase_begin(const char* name) {
281 }
282 
283 inline static void phase_end(const char* name) {
285 }
286 
287 inline static void init_profile() {
289 }
290 
291 inline static void finalize_profile() {
293 }
294 } // namespace Instrumentor
295 
296 } // namespace nrn
char * name
Definition: init.cpp:16
static void phase_begin(const char *name)
static void stop_profile()
static void start_profile()
static void phase_end(const char *name)
static void finalize_profile()
static void init_profile()
Definition: bimap.hpp:13
Instrumentation infrastructure for benchmarking and profiling.
static void finalize_profile()
Finalize the profiler.
static void init_profile()
Initialize the profiler.
static void phase_begin(const char *name)
Activate the collection of profiling data within a code region.
static void start_profile()
Globally activate the collection of profiling data.
static void phase_end(const char *name)
Deactivate the collection of profiling data within a code region.
static void stop_profile()
Globally deactivate the collection of profiling data.
static void phase_end(const char *name)
static void phase_begin(const char *name)