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.
definition.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#pragma once
26
30#include "timemory/mpl/math.hpp"
34#include "timemory/units.hpp"
35
36namespace tim
37{
38namespace component
39{
40//
41//======================================================================================//
42//
43// NON-VOID BASE
44//
45//======================================================================================//
46//
47template <typename Tp, typename Value>
48void
50{
51 laps = 0;
54}
55//
56//--------------------------------------------------------------------------------------//
57//
58template <typename Tp, typename Value>
59void
60base<Tp, Value>::get(void*& ptr, size_t _typeid_hash) const
61{
62 if(!ptr && _typeid_hash == typeid_hash<Tp>())
63 ptr = reinterpret_cast<void*>(const_cast<base_type*>(this));
64}
65//
66//--------------------------------------------------------------------------------------//
67//
68template <typename Tp, typename Value>
69void
71{
72 set_is_running(true);
73}
74//
75//--------------------------------------------------------------------------------------//
76//
77template <typename Tp, typename Value>
78void
80{
81 if(get_is_running())
82 {
83 ++laps;
84 set_is_transient(true);
85 set_is_running(false);
86 }
87}
88//
89//--------------------------------------------------------------------------------------//
90//
91template <typename Tp, typename Value>
92typename base<Tp, Value>::base_storage_type*
94{
95 return tim::base::storage::template base_instance<Tp, Value>();
96}
97//
98//--------------------------------------------------------------------------------------//
99//
100template <typename Tp, typename Value>
101short
103{
104 static short _instance = Type::width;
105 if(settings::width() >= 0)
106 _instance = settings::width();
107
108 if(timing_category_v && settings::timing_width() >= 0)
109 {
110 _instance = settings::timing_width();
111 }
112 else if(memory_category_v && settings::memory_width() >= 0)
113 {
114 _instance = settings::memory_width();
115 }
116
117 return _instance;
118}
119//
120//--------------------------------------------------------------------------------------//
121//
122template <typename Tp, typename Value>
123short
125{
126 static short _instance = Type::precision;
127 if(settings::precision() >= 0)
128 _instance = settings::precision();
129
130 if(timing_category_v && settings::timing_precision() >= 0)
131 {
132 _instance = settings::timing_precision();
133 }
134 else if(memory_category_v && settings::memory_precision() >= 0)
135 {
136 _instance = settings::memory_precision();
137 }
138
139 return _instance;
140}
141//
142//--------------------------------------------------------------------------------------//
143//
144template <typename Tp, typename Value>
145std::ios_base::fmtflags
147{
148 static std::ios_base::fmtflags _instance = Type::format_flags;
149
150 auto _set_scientific = []() {
151 _instance &= (std::ios_base::fixed & std::ios_base::scientific);
152 _instance |= (std::ios_base::scientific);
153 };
154
155 if(!percent_units_v &&
156 (settings::scientific() || (timing_category_v && settings::timing_scientific()) ||
157 (memory_category_v && settings::memory_scientific())))
158 _set_scientific();
159
160 return _instance;
161}
162//
163//--------------------------------------------------------------------------------------//
164//
165template <typename Tp, typename Value>
168{
169 return metadata<Tp>::label();
170}
171//
172//--------------------------------------------------------------------------------------//
173//
174template <typename Tp, typename Value>
177{
179}
180//
181//--------------------------------------------------------------------------------------//
182//
183template <typename Tp, typename Value>
186{
187 static std::string _instance = Type::label();
188 return _instance;
189}
190//
191//--------------------------------------------------------------------------------------//
192//
193template <typename Tp, typename Value>
196{
197 static std::string _instance = Type::description();
198 return _instance;
199}
200//
201//--------------------------------------------------------------------------------------//
202//
203// operator + - * / (Type)
204//
205//--------------------------------------------------------------------------------------//
206//
207template <typename Tp, typename Value>
208Tp&
209base<Tp, Value>::plus_oper(const Tp& rhs)
210{
211 data_type::plus(rhs);
212 return static_cast<Type&>(*this);
213}
214//
215//--------------------------------------------------------------------------------------//
216//
217template <typename Tp, typename Value>
218Tp&
219base<Tp, Value>::minus_oper(const Tp& rhs)
220{
221 data_type::minus(rhs);
222 return static_cast<Type&>(*this);
223}
224//
225//--------------------------------------------------------------------------------------//
226//
227template <typename Tp, typename Value>
228Tp&
230{
232 return static_cast<Type&>(*this);
233}
234//
235//--------------------------------------------------------------------------------------//
236//
237template <typename Tp, typename Value>
238Tp&
239base<Tp, Value>::divide_oper(const Tp& rhs)
240{
242 return static_cast<Type&>(*this);
243}
244//
245//--------------------------------------------------------------------------------------//
246//
247// operator + - * / (Value)
248//
249//--------------------------------------------------------------------------------------//
250//
251template <typename Tp, typename Value>
252Tp&
253base<Tp, Value>::plus_oper(const Value& rhs)
254{
255 data_type::plus(rhs);
256 return static_cast<Type&>(*this);
257}
258//
259//--------------------------------------------------------------------------------------//
260//
261template <typename Tp, typename Value>
262Tp&
263base<Tp, Value>::minus_oper(const Value& rhs)
264{
265 data_type::minus(rhs);
266 return static_cast<Type&>(*this);
267}
268//
269//--------------------------------------------------------------------------------------//
270//
271template <typename Tp, typename Value>
272Tp&
273base<Tp, Value>::multiply_oper(const Value& rhs)
274{
275 data_type::minus(rhs);
276 return static_cast<Type&>(*this);
277}
278//
279//--------------------------------------------------------------------------------------//
280//
281template <typename Tp, typename Value>
282Tp&
283base<Tp, Value>::divide_oper(const Value& rhs)
284{
286 return static_cast<Type&>(*this);
287}
288//
289//--------------------------------------------------------------------------------------//
290//
291// operator + - * / <<
292//
293//--------------------------------------------------------------------------------------//
294//
295template <typename Tp, typename Value>
296Tp
298{
299 return Tp(static_cast<const Tp&>(lhs)) += static_cast<const Tp&>(rhs);
300}
301//
302//--------------------------------------------------------------------------------------//
303//
304template <typename Tp, typename Value>
305Tp
307{
308 return Tp(static_cast<const Tp&>(lhs)) -= static_cast<const Tp&>(rhs);
309}
310//
311//--------------------------------------------------------------------------------------//
312//
313template <typename Tp, typename Value>
314Tp operator*(const base<Tp, Value>& lhs, const base<Tp, Value>& rhs)
315{
316 return Tp(static_cast<const Tp&>(lhs)) *= static_cast<const Tp&>(rhs);
317}
318//
319//--------------------------------------------------------------------------------------//
320//
321template <typename Tp, typename Value>
322Tp
324{
325 return Tp(static_cast<const Tp&>(lhs)) /= static_cast<const Tp&>(rhs);
326}
327//
328//======================================================================================//
329//
330// VOID BASE
331//
332//======================================================================================//
333//
334template <typename Tp>
335void
337{
339}
340//
341//--------------------------------------------------------------------------------------//
342//
343template <typename Tp>
344void
346{
347 set_is_running(true);
348}
349//
350//--------------------------------------------------------------------------------------//
351//
352template <typename Tp>
353void
355{
356 if(get_is_running())
357 set_is_transient(true);
358 set_is_running(false);
359}
360//
361//--------------------------------------------------------------------------------------//
362//
363template <typename Tp>
364void
365base<Tp, void>::get(void*& ptr, size_t _typeid_hash) const
366{
367 if(!ptr && _typeid_hash == typeid_hash<Tp>())
368 ptr = reinterpret_cast<void*>(const_cast<base_type*>(this));
369}
370//
371//--------------------------------------------------------------------------------------//
372//
373template <typename Tp>
376{
377 return metadata<Tp>::label();
378}
379//
380//--------------------------------------------------------------------------------------//
381//
382template <typename Tp>
385{
387}
388//
389//--------------------------------------------------------------------------------------//
390//
391template <typename Tp>
394{
395 static std::string _instance = Type::label();
396 return _instance;
397}
398//
399//--------------------------------------------------------------------------------------//
400//
401template <typename Tp>
404{
405 static std::string _instance = Type::description();
406 return _instance;
407}
408//
409//--------------------------------------------------------------------------------------//
410//
411} // namespace component
412} // namespace tim
413
419
420namespace tim
421{
422namespace component
423{
424//
425template <typename Tp, typename Value>
426opaque
427base<Tp, Value>::get_opaque(scope::config _scope)
428{
429 auto _typeid_hash = typeid_hash<Tp>();
430
431 opaque _obj{};
432
433 _obj.m_valid = true;
434
435 _obj.m_typeid = _typeid_hash;
436
437 _obj.m_setup = [](void* v_result, string_view_cref_t _prefix,
438 scope::config arg_scope) {
439 DEBUG_PRINT_HERE("Setting up %s", demangle<Tp>().c_str());
440 Tp* _result = static_cast<Tp*>(v_result);
441 if(!_result)
442 _result = new Tp{};
443 invoke::set_prefix<TIMEMORY_API>(std::tie(*_result), _prefix);
444 invoke::set_scope<TIMEMORY_API>(std::tie(*_result), arg_scope);
445 return (void*) _result;
446 };
447
448 _obj.m_push = [_scope](void*& v_result, string_view_cref_t _prefix,
449 scope::config arg_scope) {
450 if(v_result)
451 {
452 DEBUG_PRINT_HERE("Pushing %s", demangle<Tp>().c_str());
453 auto _hash = add_hash_id(_prefix);
454 Tp* _result = static_cast<Tp*>(v_result);
455 invoke::push<TIMEMORY_API>(std::tie(*_result), _scope + arg_scope, _hash);
456 }
457 };
458
459 _obj.m_sample = [](void* v_result) {
460 if(v_result)
461 {
462 DEBUG_PRINT_HERE("Sampling %s", demangle<Tp>().c_str());
463 Tp* _result = static_cast<Tp*>(v_result);
464 invoke::invoke<operation::sample, TIMEMORY_API>(std::tie(*_result));
465 }
466 };
467
468 _obj.m_start = [](void* v_result) {
469 if(v_result)
470 {
471 DEBUG_PRINT_HERE("Starting %s", demangle<Tp>().c_str());
472 Tp* _result = static_cast<Tp*>(v_result);
473 invoke::start<TIMEMORY_API>(std::tie(*_result));
474 }
475 };
476
477 _obj.m_stop = [](void* v_result) {
478 if(v_result)
479 {
480 DEBUG_PRINT_HERE("Stopping %s", demangle<Tp>().c_str());
481 Tp* _result = static_cast<Tp*>(v_result);
482 invoke::stop<TIMEMORY_API>(std::tie(*_result));
483 }
484 };
485
486 _obj.m_pop = [](void* v_result) {
487 if(v_result)
488 {
489 DEBUG_PRINT_HERE("Popping %s", demangle<Tp>().c_str());
490 Tp* _result = static_cast<Tp*>(v_result);
491 invoke::pop<TIMEMORY_API>(std::tie(*_result));
492 }
493 };
494
495 _obj.m_get = [_typeid_hash](void* v_result, void*& _ptr, size_t _hash) {
496 if(_hash == _typeid_hash && v_result && !_ptr)
497 {
498 DEBUG_PRINT_HERE("Getting %s", demangle<Tp>().c_str());
499 Tp* _result = static_cast<Tp*>(v_result);
500 // invoke::get<TIMEMORY_API>(std::tie(*_result), _ptr, _hash);
501 // operation::get<Tp>{ *_result, _ptr, _hash };
502 invoke::invoke<operation::get, TIMEMORY_API>(std::tie(*_result), _ptr, _hash);
503 }
504 };
505
506 _obj.m_del = [](void* v_result) {
507 if(v_result)
508 {
509 DEBUG_PRINT_HERE("Deleting %s", demangle<Tp>().c_str());
510 Tp* _result = static_cast<Tp*>(v_result);
511 delete _result;
512 }
513 };
514
515 _obj.m_update_stats = [](void* v_result, bool _v) {
516 if(v_result)
517 {
518 DEBUG_PRINT_HERE("Updating statistics %s", demangle<Tp>().c_str());
519 Tp* _result = static_cast<Tp*>(v_result);
520 invoke::invoke<operation::add_statistics, TIMEMORY_API>(std::tie(*_result),
521 _v);
522 }
523 };
524
525 return _obj;
526}
527//
528template <typename Tp>
529opaque
530base<Tp, void>::get_opaque(scope::config _scope)
531{
532 auto _typeid_hash = typeid_hash<Tp>();
533
534 opaque _obj{};
535
536 _obj.m_valid = true;
537
538 _obj.m_typeid = _typeid_hash;
539
540 _obj.m_setup = [](void* v_result, string_view_cref_t _prefix,
541 scope::config arg_scope) {
542 DEBUG_PRINT_HERE("Setting up %s", demangle<Tp>().c_str());
543 Tp* _result = static_cast<Tp*>(v_result);
544 if(!_result)
545 _result = new Tp{};
546 invoke::set_prefix<TIMEMORY_API>(std::tie(*_result), _prefix);
547 invoke::set_scope<TIMEMORY_API>(std::tie(*_result), arg_scope);
548 return (void*) _result;
549 };
550
551 _obj.m_push = [_scope](void*& v_result, string_view_cref_t _prefix,
552 scope::config arg_scope) {
553 if(v_result)
554 {
555 DEBUG_PRINT_HERE("Pushing %s", demangle<Tp>().c_str());
556 auto _hash = add_hash_id(_prefix);
557 Tp* _result = static_cast<Tp*>(v_result);
558 invoke::push<TIMEMORY_API>(std::tie(*_result), _scope + arg_scope, _hash);
559 }
560 };
561
562 _obj.m_sample = [](void* v_result) {
563 if(v_result)
564 {
565 DEBUG_PRINT_HERE("Sampling %s", demangle<Tp>().c_str());
566 Tp* _result = static_cast<Tp*>(v_result);
567 invoke::invoke<operation::sample, TIMEMORY_API>(std::tie(*_result));
568 }
569 };
570
571 _obj.m_start = [](void* v_result) {
572 if(v_result)
573 {
574 DEBUG_PRINT_HERE("Starting %s", demangle<Tp>().c_str());
575 Tp* _result = static_cast<Tp*>(v_result);
576 invoke::start<TIMEMORY_API>(std::tie(*_result));
577 }
578 };
579
580 _obj.m_stop = [](void* v_result) {
581 if(v_result)
582 {
583 DEBUG_PRINT_HERE("Stopping %s", demangle<Tp>().c_str());
584 Tp* _result = static_cast<Tp*>(v_result);
585 invoke::stop<TIMEMORY_API>(std::tie(*_result));
586 }
587 };
588
589 _obj.m_pop = [](void* v_result) {
590 if(v_result)
591 {
592 DEBUG_PRINT_HERE("Popping %s", demangle<Tp>().c_str());
593 Tp* _result = static_cast<Tp*>(v_result);
594 invoke::pop<TIMEMORY_API>(std::tie(*_result));
595 }
596 };
597
598 _obj.m_get = [_typeid_hash](void* v_result, void*& _ptr, size_t _hash) {
599 if(_hash == _typeid_hash && v_result && !_ptr)
600 {
601 DEBUG_PRINT_HERE("Getting %s", demangle<Tp>().c_str());
602 Tp* _result = static_cast<Tp*>(v_result);
603 invoke::invoke<operation::get, TIMEMORY_API>(std::tie(*_result), _ptr, _hash);
604 }
605 };
606
607 _obj.m_del = [](void* v_result) {
608 if(v_result)
609 {
610 DEBUG_PRINT_HERE("Deleting %s", demangle<Tp>().c_str());
611 Tp* _result = static_cast<Tp*>(v_result);
612 delete _result;
613 }
614 };
615
616 _obj.m_update_stats = [](void* v_result, bool _v) {
617 if(v_result)
618 {
619 DEBUG_PRINT_HERE("Updating statistics %s", demangle<Tp>().c_str());
620 Tp* _result = static_cast<Tp*>(v_result);
621 invoke::invoke<operation::add_statistics, TIMEMORY_API>(std::tie(*_result),
622 _v);
623 }
624 };
625
626 return _obj;
627}
628//
629} // namespace component
630} // namespace tim
Declare the base component types.
Definition for various functions for get in operations.
Tp operator*(const base< Tp, Value > &lhs, const base< Tp, Value > &rhs)
Definition: definition.hpp:314
Tp operator+(const base< Tp, Value > &lhs, const base< Tp, Value > &rhs)
Definition: definition.hpp:297
Tp operator/(const base< Tp, Value > &lhs, const base< Tp, Value > &rhs)
Definition: definition.hpp:323
Tp operator-(const base< Tp, Value > &lhs, const base< Tp, Value > &rhs)
Definition: definition.hpp:306
hash_value_t add_hash_id(hash_map_ptr_t &_hash_map, string_view_cref_t _prefix)
add an string to the given hash-map (if it doesn't already exist) and return the hash
Definition: types.hpp:190
void reset(TupleT< Tp... > &obj, Args &&... args)
Definition: functional.cpp:599
Tp & plus(Tp &, const Up &)
Definition: plus.hpp:106
auto divide(Tp &_lhs, Up _rhs, type_list<>,...) -> decltype(_lhs/=_rhs, void())
Definition: divide.hpp:43
Tp & minus(Tp &, const Up &)
Definition: minus.hpp:98
Tp & multiply(Tp &, const Up &)
Definition: multiply.hpp:140
Definition: kokkosp.cpp:39
timing_precision
Definition: settings.cpp:1647
char const std::string & _prefix
Definition: config.cpp:55
memory_scientific
Definition: settings.cpp:1659
const std::string & string_view_cref_t
Definition: language.hpp:103
timing_width
Definition: settings.cpp:1649
scientific
Definition: settings.cpp:1646
tim::mpl::apply< std::string > string
Definition: macros.hpp:53
precision
Definition: settings.cpp:1643
memory_precision
Definition: settings.cpp:1654
memory_width
Definition: settings.cpp:1656
description("A generic option for any setting. Each argument MUST be passed in " "form: 'NAME=VALUE'. E.g. --timemory-args " "\"papi_events=PAPI_TOT_INS,PAPI_TOT_CYC\" text_output=off") .action([&](parser_t &p)
Definition: config.cpp:312
timing_scientific
Definition: settings.cpp:1652
Declare the operations types.
Definition for various functions for sample in operations.
Declare the storage types.
static short get_precision()
Type & multiply_oper(const Type &rhs)
static base_storage_type * get_storage()
void reset()
reset the values
Type & minus_oper(const Type &rhs)
static std::string get_label()
Type & plus_oper(const Type &rhs)
void set_stopped()
store that stop has been called
static short get_width()
static fmtflags get_format_flags()
static opaque get_opaque(scope::config)
get the opaque binding for user-bundle
static std::string label()
Type & divide_oper(const Type &rhs)
auto get() const
retrieve the current measurement value in the units for the type
void set_started()
store that start has been called
static std::string get_description()
static std::string description()
static std::string label()
Definition: metadata.hpp:68
static std::string description()
Definition: metadata.hpp:77
#define DEBUG_PRINT_HERE(...)
Definition: macros.hpp:168