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.
policy.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/or sell
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#pragma once
26
29#include "timemory/tpls/cereal/archives.hpp"
30
31#include <atomic>
32#include <iosfwd>
33#include <memory>
34#include <tuple>
35
36namespace tim
37{
38//
39template <typename Tp>
40struct statistics;
41//
42namespace policy
43{
44//======================================================================================//
45
46template <typename CompT, typename Tp>
48{
49 using type = Tp;
53
54 void operator()(statistics<type>&, const CompT&, bool _accum = true);
55 void operator()(type&, const CompT&) {}
56};
57
58//--------------------------------------------------------------------------------------//
59//
60template <typename CompT>
61struct record_statistics<CompT, void>
62{
63 using type = void;
67
68 template <typename... ArgsT>
69 void operator()(ArgsT&&...)
70 {}
71};
72
73//--------------------------------------------------------------------------------------//
74//
75template <typename CompT>
76struct record_statistics<CompT, std::tuple<>>
77{
78 using type = std::tuple<>;
79 using this_type = record_statistics<CompT, type>;
80 using policy_type = this_type;
82
83 template <typename... ArgsT>
84 void operator()(ArgsT&&...)
85 {}
86};
87
88//======================================================================================//
89
90template <typename Archive, typename Api>
92{
93 using type = Archive;
94 using pointer = std::shared_ptr<type>;
95
96 static pointer get(std::istream& is) { return std::make_shared<type>(is); }
97};
98
99//--------------------------------------------------------------------------------------//
100
101template <typename Api>
102struct input_archive<cereal::JSONInputArchive, Api>
103{
104 using type = cereal::JSONInputArchive;
105 using pointer = std::shared_ptr<type>;
106
107 static pointer get(std::istream& is) { return std::make_shared<type>(is); }
108};
109
110//--------------------------------------------------------------------------------------//
111
112template <typename Api>
113struct input_archive<cereal::PrettyJSONOutputArchive, Api>
114{
115 using type = cereal::JSONInputArchive;
116 using pointer = std::shared_ptr<type>;
117
118 static pointer get(std::istream& is) { return std::make_shared<type>(is); }
119};
120
121//--------------------------------------------------------------------------------------//
122
123template <typename Api>
124struct input_archive<cereal::MinimalJSONOutputArchive, Api>
125{
126 using type = cereal::JSONInputArchive;
127 using pointer = std::shared_ptr<type>;
128
129 static pointer get(std::istream& is) { return std::make_shared<type>(is); }
130};
131
132//======================================================================================//
133
134template <typename Archive, typename Api>
136{
137 using type = Archive;
138 using pointer = std::shared_ptr<type>;
139
140 static pointer get(std::ostream& os) { return std::make_shared<type>(os); }
141};
142
143//--------------------------------------------------------------------------------------//
144
145template <typename Api>
146struct output_archive<cereal::PrettyJSONOutputArchive, Api>
147{
148 using type = cereal::PrettyJSONOutputArchive;
149 using pointer = std::shared_ptr<type>;
150 using option_type = typename type::Options;
151 using indent_type = typename option_type::IndentChar;
152
153 static unsigned int& precision()
154 {
155 static unsigned int value = 16;
156 return value;
157 }
158
159 static unsigned int& indent_length()
160 {
161 static unsigned int value = 1;
162 return value;
163 }
164
166 {
167 static indent_type value = indent_type::space;
168 return value;
169 }
170
171 static pointer get(std::ostream& os)
172 {
173 // Option args: precision, spacing, indent size
174 option_type opts(precision(), indent_char(), indent_length());
175 return std::make_shared<type>(os, opts);
176 }
177};
178
179//--------------------------------------------------------------------------------------//
180///
181/// partial specialization for MinimalJSONOutputArchive
182///
183template <typename Api>
184struct output_archive<cereal::MinimalJSONOutputArchive, Api>
185{
186 using type = cereal::MinimalJSONOutputArchive;
187 using pointer = std::shared_ptr<type>;
188 using option_type = typename type::Options;
189 using indent_type = typename option_type::IndentChar;
190
191 static unsigned int& precision()
192 {
193 static unsigned int value = 16;
194 return value;
195 }
196 static unsigned int& indent_length()
197 {
198 static unsigned int value = 0;
199 return value;
200 }
202 {
203 static indent_type value = indent_type::space;
204 return value;
205 }
206
207 static pointer get(std::ostream& os)
208 {
209 // Option args: precision, spacing, indent size
210 // The last two options are meaningless for the minimal writer
211 option_type opts(precision(), indent_char(), indent_length());
212 return std::make_shared<type>(os, opts);
213 }
214};
215
216//--------------------------------------------------------------------------------------//
217#if defined(TIMEMORY_USE_XML)
218///
219/// partial specialization for XMLOutputArchive
220///
221template <typename Api>
222struct output_archive<cereal::XMLOutputArchive, Api>
223{
224 using type = cereal::XMLOutputArchive;
225 using pointer = std::shared_ptr<type>;
226 using option_type = typename type::Options;
227 using indent_type = bool;
228 using output_type = bool;
229
230 static unsigned int& precision()
231 {
232 static unsigned int value = 16;
233 return value;
234 }
235
236 // indent the output
237 static indent_type& indent()
238 {
239 static indent_type value =
240 trait::pretty_archive<Api>::value || trait::pretty_archive<void>::value;
241 return value;
242 }
243
244 // output the type as an attribute
245 static output_type& type_attribute()
246 {
247 static output_type value = false;
248 return value;
249 }
250
251 // Whether dynamically sized containers output the size=dynamic attribute
252 static output_type& size_attribute()
253 {
254 static output_type value = false;
255 return value;
256 }
257
258 static pointer get(std::ostream& os)
259 {
260 // Option args: precision, spacing, indent size
261 // The last two options are meaningless for the minimal writer
262 option_type opts(precision(), indent(), type_attribute(), size_attribute());
263 return std::make_shared<type>(os, opts);
264 }
265};
266#endif
267//======================================================================================//
268
269template <typename Tp>
271{
272public:
273 using type = Tp;
274 using int_type = int64_t;
275 using pair_type = std::pair<int_type, int_type>;
276 static constexpr bool thread_support = true;
277
278 TIMEMORY_DEFAULT_OBJECT(instance_tracker)
279
280 enum
281 {
282 global_count = 0,
283 thread_count
284 };
285
286public:
287 //----------------------------------------------------------------------------------//
288 //
289 static int_type get_started_count() { return get_started().load(); }
290
291 //----------------------------------------------------------------------------------//
292 //
293 static int_type get_thread_started_count() { return get_thread_started(); }
294
295protected:
296 //----------------------------------------------------------------------------------//
297 //
298 static std::atomic<int_type>& get_started()
299 {
300 static std::atomic<int_type> _instance(0);
301 return _instance;
302 }
303
304 //----------------------------------------------------------------------------------//
305 //
307 {
308 static thread_local int_type _instance = 0;
309 return _instance;
310 }
311
312 //----------------------------------------------------------------------------------//
313 //
314 auto start()
315 {
316 m_tot = get_started()++;
317 m_thr = get_thread_started()++;
318 return pair_type{ m_tot, m_thr };
319 }
320
321 auto stop()
322 {
323 m_tot = --get_started();
324 m_thr = --get_thread_started();
325 return pair_type{ m_tot, m_thr };
326 }
327
328 //----------------------------------------------------------------------------------//
329 // increment/decrement global and thread counts and return global count
330 template <size_t Idx>
332 {
333 m_tot = get_started()++;
334 m_thr = get_thread_started()++;
335 return m_tot;
336 }
337
338 template <size_t Idx>
340 {
341 m_tot = --get_started();
342 m_thr = --get_thread_started();
343 return m_tot;
344 }
345
346 //----------------------------------------------------------------------------------//
347 // increment/decrement global and thread counts and return thread count
348 template <size_t Idx>
350 {
351 m_tot = get_started()++;
352 m_thr = get_thread_started()++;
353 return m_thr;
354 }
355
356 template <size_t Idx>
358 {
359 m_tot = --get_started();
360 m_thr = --get_thread_started();
361 return m_thr;
362 }
363
364 auto get_global_count() { return m_tot; }
365 auto get_thread_count() { return m_tot; }
366
367 auto global_tracker_start() { return (start(), m_tot); }
368 auto global_tracker_stop() { return (stop(), m_tot); }
369 auto thread_tracker_start() { return (start(), m_thr); }
370 auto thread_tracker_stop() { return (stop(), m_thr); }
371
372protected:
373 int_type m_tot = get_started_count();
374 int_type m_thr = get_thread_started_count();
375};
376
377//======================================================================================//
378
379template <typename Tp>
381{
382public:
383 using type = Tp;
384 using int_type = int64_t;
385 static constexpr bool thread_support = false;
386
387 instance_tracker() = default;
388 ~instance_tracker() = default;
390 instance_tracker(instance_tracker&&) noexcept = default;
391 instance_tracker& operator=(const instance_tracker&) = default;
392 instance_tracker& operator=(instance_tracker&&) noexcept = default;
393
394public:
395 //----------------------------------------------------------------------------------//
396 //
397 static int_type get_started_count() { return get_started().load(); }
398
399protected:
400 //----------------------------------------------------------------------------------//
401 //
402 static std::atomic<int_type>& get_started()
403 {
404 static std::atomic<int_type> _instance(0);
405 return _instance;
406 }
407
408 //----------------------------------------------------------------------------------//
409 //
410 auto start()
411 {
412 m_tot = get_started()++;
413 return m_tot;
414 }
415
416 //----------------------------------------------------------------------------------//
417 //
418 auto stop()
419 {
420 m_tot = --get_started();
421 return m_tot;
422 }
423
424 auto get_global_count() { return m_tot; }
425 auto global_tracker_start() { return (start(), m_tot); }
426 auto global_tracker_stop() { return (stop(), m_tot); }
427
428protected:
429 int_type m_tot = get_started_count();
430};
431
432//======================================================================================//
433
434} // namespace policy
435} // namespace tim
STL namespace.
return false
Definition: definition.hpp:326
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
typename std::enable_if< B, T >::type enable_if_t
Alias template for enable_if.
Definition: types.hpp:190
const std::string std::ostream * os
precision
Definition: settings.cpp:1643
Provides a static get() function which returns a shared pointer to an instance of the given archive f...
Definition: policy.hpp:92
static pointer get(std::istream &is)
Definition: policy.hpp:96
std::shared_ptr< type > pointer
Definition: policy.hpp:94
instance_tracker(const instance_tracker &)=default
static std::atomic< int_type > & get_started()
Definition: policy.hpp:402
instance_tracker(instance_tracker &&) noexcept=default
static int_type get_thread_started_count()
Definition: policy.hpp:293
static int_type & get_thread_started()
Definition: policy.hpp:306
static std::atomic< int_type > & get_started()
Definition: policy.hpp:298
enable_if_t< Idx==thread_count, int_type > start()
Definition: policy.hpp:349
enable_if_t< Idx==thread_count, int_type > stop()
Definition: policy.hpp:357
std::pair< int_type, int_type > pair_type
Definition: policy.hpp:275
enable_if_t< Idx==global_count, int_type > start()
Definition: policy.hpp:331
enable_if_t< Idx==global_count, int_type > stop()
Definition: policy.hpp:339
Provides a static get() function which return a shared pointer to an instance of the given archive fo...
Definition: policy.hpp:136
std::shared_ptr< type > pointer
Definition: policy.hpp:138
static pointer get(std::ostream &os)
Definition: policy.hpp:140
Specification of how to accumulate statistics. This will not be used unless tim::trait::statistics ha...
Definition: policy.hpp:48
void operator()(statistics< type > &, const CompT &, bool _accum=true)
statistics< type > statistics_type
Definition: policy.hpp:52
void operator()(type &, const CompT &)
Definition: policy.hpp:55
record_statistics< CompT, type > this_type
Definition: policy.hpp:50
A generic class for statistical accumulation. It uses the timemory math overloads to enable statistic...
Definition: statistics.hpp:83