Skip to content
This repository was archived by the owner on Mar 20, 2023. It is now read-only.

Commit 5af3a6f

Browse files
sharkovskypramodk
authored andcommitted
Added Likwid instrumentor (#174)
* CMake infrastructure for likwid profiler * Likwid Instrumentor - support for Likwid Marker instrumentation - contextually added init_profile and finalize_profile to handle cases (such as Likwid) where the profiler requires an initialization to be called before any memory allocation happens. * Added docs for Instrumentor methods
1 parent 408115e commit 5af3a6f

File tree

5 files changed

+217
-2
lines changed

5 files changed

+217
-2
lines changed

CMake/packages/Findlikwid.cmake

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
# Copyright (c) 2016, Blue Brain Project
2+
# All rights reserved.
3+
4+
# Redistribution and use in source and binary forms, with or without modification,
5+
# are permitted provided that the following conditions are met:
6+
# 1. Redistributions of source code must retain the above copyright notice,
7+
# this list of conditions and the following disclaimer.
8+
# 2. Redistributions in binary form must reproduce the above copyright notice,
9+
# this list of conditions and the following disclaimer in the documentation
10+
# and/or other materials provided with the distribution.
11+
# 3. Neither the name of the copyright holder nor the names of its contributors
12+
# may be used to endorse or promote products derived from this software
13+
# without specific prior written permission.
14+
15+
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
16+
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17+
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18+
# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
19+
# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
20+
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
21+
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
22+
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
23+
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
24+
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
25+
# THE POSSIBILITY OF SUCH DAMAGE.
26+
27+
28+
# Findlikwid
29+
# -------------
30+
#
31+
# Find likwid
32+
#
33+
# Find the likwid RRZE Performance Monitoring and Benchmarking Suite
34+
#
35+
# Using likwid:
36+
#
37+
# ::
38+
# set(LIKWID_ROOT "" CACHE PATH "Path likwid performance monitoring and benchmarking suite")
39+
# find_package(likwid REQUIRED)
40+
# include_directories(${likwid_INCLUDE_DIRS})
41+
# target_link_libraries(foo ${likwid_LIBRARIES})
42+
#
43+
# This module sets the following variables:
44+
#
45+
# ::
46+
#
47+
# likwid_FOUND - set to true if the library is found
48+
# likwid_INCLUDE - list of required include directories
49+
# likwid_LIBRARIES - list of required library directories
50+
51+
find_path(likwid_INCLUDE_DIRS "likwid.h" HINTS "${LIKWID_ROOT}/include")
52+
find_library(likwid_LIBRARIES likwid HINTS "${LIKWID_ROOT}/lib")
53+
54+
# Checks 'REQUIRED', 'QUIET' and versions.
55+
include(FindPackageHandleStandardArgs)
56+
57+
find_package_handle_standard_args(likwid
58+
REQUIRED_VARS likwid_INCLUDE_DIRS likwid_LIBRARIES)

CMakeLists.txt

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,7 @@ option(ENABLE_OMP_RUNTIME_SCHEDULE "Use runtime schedule for OpenMP" OFF)
6262
option(ENABLE_ISPC_TARGET "Enable ispc interoperability structs and data" OFF)
6363
option(ENABLE_NMODL "Enable external nmodl source-to-source compiler" OFF)
6464
option(ENABLE_CALIPER "Enable Caliper instrumentation" OFF)
65+
option(CORENEURON_ENABLE_LIKWID "Enable LIKWID instrumentation" OFF)
6566

6667
## set C++11 standard to be default
6768
set(CMAKE_CXX_STANDARD 11)
@@ -195,6 +196,14 @@ if(ENABLE_CALIPER)
195196
endif()
196197
endif(ENABLE_CALIPER)
197198

199+
# Code instrumentation
200+
set(LIKWID_ROOT "" CACHE PATH "Path likwid performance monitoring and benchmarking suite")
201+
if(CORENEURON_ENABLE_LIKWID)
202+
find_package(likwid REQUIRED)
203+
include_directories(${likwid_INCLUDE_DIRS})
204+
add_definitions("-DLIKWID_PERFMON")
205+
endif(CORENEURON_ENABLE_LIKWID)
206+
198207
CHECK_INCLUDE_FILES (malloc.h have_malloc_h)
199208
if(have_malloc_h)
200209
add_definitions("-DHAVE_MALLOC_H")

apps/coreneuron.cpp

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,11 @@ THE POSSIBILITY OF SUCH DAMAGE.
2727
*/
2828

2929
#include <coreneuron/enginemech.h>
30+
#include "coreneuron/nrniv/profiler_interface.h"
3031

3132
int main(int argc, char** argv) {
32-
return solve_core(argc, argv);
33+
coreneuron::Instrumentor::init_profile();
34+
auto solve_core_result = solve_core(argc, argv);
35+
coreneuron::Instrumentor::finalize_profile();
36+
return solve_core_result;
3337
}

coreneuron/CMakeLists.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -384,7 +384,7 @@ add_library(coreneuron ${COMPILE_LIBRARY_TYPE} ${coreneuron_all_headers} ${coren
384384
add_dependencies(coreneuron kinderiv)
385385

386386
target_link_libraries(coreneuron ${MPI_CXX_LIBRARIES}
387-
${link_reportinglib} ${link_cudacoreneuron} ${CUDA_LIBRARIES} ${CALIPER_LIB} ${CALIPER_MPI_LIB})
387+
${link_reportinglib} ${link_cudacoreneuron} ${CUDA_LIBRARIES} ${CALIPER_LIB} ${CALIPER_MPI_LIB} ${likwid_LIBRARIES})
388388

389389
set_target_properties(coreneuron PROPERTIES
390390
VERSION ${VERSION_MAJOR}.${VERSION_MINOR}.${VERSION_PATCH}

coreneuron/nrniv/profiler_interface.h

Lines changed: 144 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,24 +19,115 @@
1919
#include <TAU.h>
2020
#endif
2121

22+
#if defined(LIKWID_PERFMON)
23+
#include <likwid.h>
24+
#endif
25+
2226
namespace coreneuron {
2327

2428
namespace 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+
*/
2637
template <class... TProfilerImpl>
2738
struct 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

Comments
 (0)