1919#include < TAU.h>
2020#endif
2121
22+ #if defined(LIKWID_PERFMON)
23+ #include < likwid.h>
24+ #endif
25+
2226namespace coreneuron {
2327
2428namespace detail {
2529
30+ /* ! \class Instrumentor
31+ * \brief Instrumentation infrastructure for benchmarking and profiling.
32+ *
33+ * The Instrumentor class exposes static methods that can be used to
34+ * toggle with fine-grained resolution the profiling of specific
35+ * areas within the code.
36+ */
2637template <class ... TProfilerImpl>
2738struct Instrumentor {
39+ /* ! \fn phase_begin
40+ * \brief Activate the collection of profiling data within a code region.
41+ *
42+ * This function semantically defines the beginning of a region
43+ * of code that the user wishes to profile.
44+ * Loops through all enabled profilers and calls the relevant
45+ * `phase_begin` function.
46+ * This function should have a non-empty implementation only for
47+ * profilers that allow multiple code regions with different names
48+ * to be profiled concurrently.
49+ *
50+ * @param name the (unique) identifier of the code region to be profiled
51+ */
2852 inline static void phase_begin (const char * name) {
2953 std::initializer_list<int >{(TProfilerImpl::phase_begin (name), 0 )...};
3054 }
55+
56+ /* ! \fn phase_end
57+ * \brief Deactivate the collection of profiling data within a code region.
58+ *
59+ * This function semantically defines the end of a region
60+ * of code that the user wishes to profile.
61+ * Loops through all enabled profilers and calls the relevant
62+ * `phase_end` function.
63+ * This function should have a non-empty implementation only for
64+ * profilers that allow multiple code regions with different names
65+ * to be profiled concurrently.
66+ *
67+ * @param name the (unique) identifier of the code region to be profiled
68+ */
3169 inline static void phase_end (const char * name) {
3270 std::initializer_list<int >{(TProfilerImpl::phase_end (name), 0 )...};
3371 }
72+
73+ /* ! \fn start_profile
74+ * \brief Globally activate the collection of profiling data.
75+ *
76+ * Activate the collection of profiler data without defining
77+ * a region of interest with a given name, as opposed to `phase_begin`.
78+ * Loops through all enabled profilers and calls the relevant
79+ * `start_profile` function.
80+ * This function should have a non-empty implementation only for
81+ * profilers that expose simply a global begin/end interface, without
82+ * named regions.
83+ */
3484 inline static void start_profile () {
3585 std::initializer_list<int >{(TProfilerImpl::start_profile (), 0 )...};
3686 }
87+
88+ /* ! \fn stop_profile
89+ * \brief Globally deactivate the collection of profiling data.
90+ *
91+ * Deactivate the collection of profiler data without defining
92+ * a region of interest with a given name, as opposed to `phase_end`.
93+ * Loops through all enabled profilers and calls the relevant
94+ * `stop_profile` function.
95+ * This function should have a non-empty implementation only for
96+ * profilers that expose simply a global begin/end interface, without
97+ * named regions.
98+ */
3799 inline static void stop_profile () {
38100 std::initializer_list<int >{(TProfilerImpl::stop_profile (), 0 )...};
39101 }
102+
103+ /* ! \fn init_profile
104+ * \brief Initialize the profiler.
105+ *
106+ * Initialize a profiler's internal structure, without activating yet
107+ * any data collection, similar in concept to MPI_Init.
108+ * Loops through all enabled profilers and calls the relevant
109+ * `init_profile` function.
110+ * This function should have a non-empty implementation only for
111+ * profilers that require special initialization, typically before
112+ * any memory allocation is done.
113+ */
114+ inline static void init_profile () {
115+ std::initializer_list<int >{(TProfilerImpl::init_profile (), 0 )...};
116+ }
117+
118+ /* ! \fn finalize_profile
119+ * \brief Finalize the profiler.
120+ *
121+ * Finalize a profiler's internal structure, without activating yet
122+ * any data collection, similar in concept to MPI_Finalize.
123+ * Loops through all enabled profilers and calls the relevant
124+ * `finalize_profile` function.
125+ * This function should have a non-empty implementation only for
126+ * profilers that require special finalization.
127+ */
128+ inline static void finalize_profile () {
129+ std::initializer_list<int >{(TProfilerImpl::finalize_profile (), 0 )...};
130+ }
40131};
41132
42133#if defined(CORENEURON_CALIPER)
@@ -53,6 +144,10 @@ struct Caliper {
53144 inline static void start_profile (){};
54145
55146 inline static void stop_profile (){};
147+
148+ inline static void init_profile (){};
149+
150+ inline static void finalize_profile (){};
56151};
57152
58153#endif
@@ -71,6 +166,10 @@ struct CudaProfiling {
71166 inline static void stop_profile () {
72167 cudaProfilerStop ();
73168 };
169+
170+ inline static void init_profile (){};
171+
172+ inline static void finalize_profile (){};
74173};
75174
76175#endif
@@ -89,6 +188,10 @@ struct CrayPat {
89188 inline static void stop_profile () {
90189 PAT_record (PAT_STATE_OFF);
91190 };
191+
192+ inline static void init_profile (){};
193+
194+ inline static void finalize_profile (){};
92195};
93196#endif
94197
@@ -106,6 +209,42 @@ struct Tau {
106209 inline static void stop_profile () {
107210 TAU_DISABLE_INSTRUMENTATION ();
108211 };
212+
213+ inline static void init_profile (){};
214+
215+ inline static void finalize_profile (){};
216+ };
217+
218+ #endif
219+
220+ #if defined(LIKWID_PERFMON)
221+
222+ struct Likwid {
223+ inline static void phase_begin (const char * name){
224+ LIKWID_MARKER_START (name);
225+ };
226+
227+ inline static void phase_end (const char * name){
228+ LIKWID_MARKER_STOP (name);
229+ };
230+
231+ inline static void start_profile () {};
232+
233+ inline static void stop_profile () {};
234+
235+ inline static void init_profile (){
236+ LIKWID_MARKER_INIT;
237+
238+ #pragma omp parallel
239+ {
240+ LIKWID_MARKER_THREADINIT;
241+ }
242+
243+ };
244+
245+ inline static void finalize_profile (){
246+ LIKWID_MARKER_CLOSE;
247+ };
109248};
110249
111250#endif
@@ -115,6 +254,8 @@ struct NullInstrumentor {
115254 inline static void phase_end (const char * name){};
116255 inline static void start_profile (){};
117256 inline static void stop_profile (){};
257+ inline static void init_profile (){};
258+ inline static void finalize_profile (){};
118259};
119260
120261} // namespace detail
@@ -131,6 +272,9 @@ using Instrumentor = detail::Instrumentor<
131272#endif
132273#if defined(TAU)
133274 detail::Tau,
275+ #endif
276+ #if defined(LIKWID_PERFMON)
277+ detail::Likwid,
134278#endif
135279 detail::NullInstrumentor>;
136280
0 commit comments