timemory 3.3.0
Modular C++ Toolkit for Performance Analysis and Logging. Profiling API and Tools for C, C++, CUDA, Fortran, and Python. The C++ template API is essentially a framework to creating tools: it is designed to provide a unifying interface for recording various performance measurements alongside data logging and interfaces to other tools.
components.hpp
Go to the documentation of this file.
1// MIT License
2//
3// Copyright (c) 2020, The Regents of the University of California,
4// through Lawrence Berkeley National Laboratory (subject to receipt of any
5// required approvals from the U.S. Dept. of Energy). All rights reserved.
6//
7// Permission is hereby granted, free of charge, to any person obtaining a copy
8// of this software and associated documentation files (the "Software"), to deal
9// in the Software without restriction, including without limitation the rights
10// to use, copy, modify, merge, publish, distribute, sublicense, and
11// copies of the Software, and to permit persons to whom the Software is
12// furnished to do so, subject to the following conditions:
13//
14// The above copyright notice and this permission notice shall be included in all
15// copies or substantial portions of the Software.
16//
17// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
23// SOFTWARE.
24
25/**
26 * \file timemory/components/craypat/components.hpp
27 * \brief Implementation of the craypat component(s)
28 */
29
30#pragma once
31
33//
34#include "timemory/components/craypat/backends.hpp"
36
37//======================================================================================//
38//
39namespace tim
40{
41namespace component
42{
43//
44//--------------------------------------------------------------------------------------//
45//
46/// \struct tim::component::craypat_record
47/// \brief Provides scoping the CrayPAT profiler. Global initialization stops
48/// the profiler, the first call to `start()` starts the profiler again on the
49/// calling thread. Instance counting is enabled per-thread and each call to start
50/// increments the counter. All calls to `stop()` have no effect until the counter reaches
51/// zero, at which point the compiler is turned off again.
52///
54: base<craypat_record, void>
55, private policy::instance_tracker<craypat_record>
56{
58 using value_type = void;
61
62 static std::string label() { return "craypat_record"; }
64 {
65 return "Toggles CrayPAT recording on calling thread";
66 }
67
68 static void global_init() { backend::craypat::record(PAT_STATE_OFF); }
69
70 static void global_finalize() { backend::craypat::record(PAT_STATE_OFF); }
71
72 void start()
73 {
75 if(tracker_type::m_thr == 0)
76 backend::craypat::record(PAT_STATE_ON);
77 }
78
79 void stop()
80 {
82 if(tracker_type::m_thr == 0)
83 backend::craypat::record(PAT_STATE_OFF);
84 }
85};
86//
87//--------------------------------------------------------------------------------------//
88//
89/// \struct tim::component::craypat_region
90/// \brief Adds a region label to the CrayPAT profiling output
91///
93: base<craypat_region, void>
94, private policy::instance_tracker<craypat_region, false>
95{
97
98 static std::string label() { return "craypat_region"; }
99 static std::string description() { return "Adds region labels to CrayPAT output"; }
100
101 void start()
102 {
104 backend::craypat::region_begin(tracker_type::m_tot, m_label.c_str());
105 }
106
107 void stop()
108 {
109 backend::craypat::region_end(tracker_type::m_tot);
111 }
112
113 void set_prefix(const std::string& _label) { m_label = _label; }
114
115private:
116 std::string m_label = {};
117};
118//
119//--------------------------------------------------------------------------------------//
120//
121/// \struct tim::component::craypat_region
122/// \brief Retrieves the names and value of any counter events that have been set to count
123/// on the hardware category
124///
125struct craypat_counters : base<craypat_counters, std::vector<unsigned long>>
126{
127 using value_type = std::vector<unsigned long>;
131 using strvector_t = std::vector<std::string>;
132
133 static std::string label() { return "craypat_counters"; }
134
136 {
137 return "Names and value of any counter events that have been set to count on the "
138 "hardware category";
139 }
140
141 static void configure()
142 {
143 std::set<int> _empty;
144 int _idx = 0;
145 for(auto& citr : get_persistent_data().m_categories)
146 {
147 int _category = std::get<0>(citr);
148 // temporary data
149 const char** _names = nullptr;
150 unsigned long* _values = nullptr;
151 int* _nevents = nullptr;
152 // get data from craypat
153 backend::craypat::counters(_category, _names, _values, _nevents);
154 if(_names && _values && _nevents)
155 {
156 std::get<1>(citr) = *_nevents;
157 for(int i = 0; i < *_nevents; ++i)
158 {
159 std::get<2>(citr).push_back(_names[i]);
160 get_persistent_data().m_labels.push_back(_names[i]);
161 }
162 }
163 else
164 {
165 _empty.insert(_idx);
166 }
167 ++_idx;
168 }
169
170 get_persistent_data().m_events = get_persistent_data().m_labels.size();
171
172 // erase the unused categories
173 for(auto ritr = _empty.rbegin(); ritr != _empty.rend(); ++ritr)
174 {
175 auto itr = get_persistent_data().m_categories.begin();
176 std::advance(itr, *ritr);
177 get_persistent_data().m_categories.erase(itr);
178 }
179 }
180
181 static void global_init() { configure(); }
182
184 {
185 value_type _data;
186 for(const auto& citr : get_persistent_data().m_categories)
187 {
188 int _category = std::get<0>(citr);
189 // temporary data
190 const char** _names = nullptr;
191 unsigned long* _values = nullptr;
192 int* _nevents = nullptr;
193 // get data from craypat
194 backend::craypat::counters(_category, _names, _values, _nevents);
195 if(_names && _values && _nevents)
196 {
197 // current beginning index
198 auto _off = _data.size();
199 // make sure data size is consistent
200 _data.resize(_off + std::get<1>(citr), 0);
201 // compute the size of loop
202 int _n = std::min(std::get<1>(citr), *_nevents);
203 for(int i = 0; i < _n; ++i)
204 _data[_off + i] = _values[i];
205 }
206 }
207 return _data;
208 }
209
210 static strvector_t label_array() { return get_persistent_data().m_labels; }
211
213 {
214 return strvector_t(get_persistent_data().m_events, "");
215 }
216
217 static std::vector<unsigned long> unit_array()
218 {
219 return std::vector<unsigned long>(get_persistent_data().m_events, 1);
220 }
221
223 {
224 return strvector_t(get_persistent_data().m_events, "");
225 }
226
227 TIMEMORY_NODISCARD value_type get() const { return base_type::load(); }
228 TIMEMORY_NODISCARD value_type get_display() const { return base_type::load(); }
229
230 void start() { value = record(); }
231
232 void stop()
233 {
234 using namespace tim::component::operators;
235 value = (record() - value);
236 accum += value;
237 }
238
239private:
240 struct persistent_data
241 {
242 using category_tuple_t = std::tuple<int, int, strvector_t>;
243 using category_vector_t = std::vector<category_tuple_t>;
244 category_vector_t m_categories =
245 category_vector_t({ category_tuple_t{ PAT_CTRS_CPU, 0, strvector_t{} },
246 category_tuple_t{ PAT_CTRS_NETWORK, 0, strvector_t{} },
247 category_tuple_t{ PAT_CTRS_ACCEL, 0, strvector_t{} },
248 category_tuple_t{ PAT_CTRS_RAPL, 0, strvector_t{} },
249 category_tuple_t{ PAT_CTRS_PM, 0, strvector_t{} },
250 category_tuple_t{ PAT_CTRS_UNCORE, 0, strvector_t{} } });
251 strvector_t m_labels = {};
252 size_t m_events = 0;
253 };
254
255 static persistent_data& get_persistent_data()
256 {
257 static persistent_data _instance;
258 return _instance;
259 }
260};
261//
262//--------------------------------------------------------------------------------------//
263//
264/// \struct tim::component::craypat_heap_stats
265/// \brief Dumps the craypat heap statistics
266///
267struct craypat_heap_stats : base<craypat_heap_stats, void>
268{
269 static std::string label() { return "craypat_heap_stats"; }
270 static std::string description() { return "Undocumented by 'pat_api.h'"; }
271
272 void start() {}
273 static void stop() { backend::craypat::heap_stats(); }
274};
275//
276//--------------------------------------------------------------------------------------//
277//
278/// \struct tim::component::craypat_flush_buffer
279/// \brief Writes all the recorded contents in the data buffer. Returns the number of
280/// bytes flushed
281///
282struct craypat_flush_buffer : base<craypat_flush_buffer, unsigned long>
283{
284 using value_type = unsigned long;
287
288 static std::string label() { return "craypat_flush_buffer"; }
290 {
291 return "Writes all the recorded contents in the data buffer. Returns the number "
292 "of bytes flushed";
293 }
294
296 {
297 unsigned long _nbytes;
298 backend::craypat::flush_buffer(&_nbytes);
299 return _nbytes;
300 }
301
302 TIMEMORY_NODISCARD double get() const { return m_nbytes; }
303 TIMEMORY_NODISCARD auto get_display() const { return get(); }
304 void start() {}
305 void stop()
306 {
307 value = record();
308 accum += record();
309 }
310
311private:
312 unsigned long m_nbytes = 0;
313};
314//
315} // namespace component
316} // namespace tim
317//
318//======================================================================================//
Declare the craypat component types.
::tim::statistics< Tp > min(::tim::statistics< Tp > lhs, const Tp &rhs)
Definition: statistics.hpp:329
void record(TupleT< Tp... > &obj, Args &&... args)
Definition: functional.cpp:634
void stop(TupleT< Tp... > &obj, Args &&... args)
Definition: functional.cpp:386
void start(TupleT< Tp... > &obj, Args &&... args)
Definition: functional.cpp:316
Inherit from this policy to add reference counting support. Useful if you want to turn a global setti...
Definition: types.hpp:406
Definition: kokkosp.cpp:39
tim::mpl::apply< std::string > string
Definition: macros.hpp:53
decltype(auto) load()
storage< Tp, Value > storage_type
std::vector< unsigned long > value_type
Definition: components.hpp:127
static strvector_t display_unit_array()
Definition: components.hpp:222
value_type get_display() const
Definition: components.hpp:228
static std::vector< unsigned long > unit_array()
Definition: components.hpp:217
static strvector_t label_array()
Definition: components.hpp:210
static std::string description()
Definition: components.hpp:135
std::vector< std::string > strvector_t
Definition: components.hpp:131
static strvector_t description_array()
Definition: components.hpp:212
static std::string label()
Definition: components.hpp:133
Writes all the recorded contents in the data buffer. Returns the number of bytes flushed.
Definition: components.hpp:283
Dumps the craypat heap statistics.
Definition: components.hpp:268
static std::string description()
Definition: components.hpp:270
Provides scoping the CrayPAT profiler. Global initialization stops the profiler, the first call to st...
Definition: components.hpp:56
static std::string description()
Definition: components.hpp:63
static std::string label()
Definition: components.hpp:62
Adds a region label to the CrayPAT profiling output.
Definition: components.hpp:95
void set_prefix(const std::string &_label)
Definition: components.hpp:113
static std::string description()
Definition: components.hpp:99
static std::string label()
Definition: components.hpp:98
A very lightweight storage class which provides nothing.
Definition: declaration.hpp:51