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/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
15// all 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#pragma once
27
37
38#include <cassert>
39#include <cstdint>
40#include <functional>
41#include <set>
42#include <string>
43
44//======================================================================================//
45//
46namespace tim
47{
48namespace component
49{
50//
51//--------------------------------------------------------------------------------------//
52//
53namespace factory
54{
55//
56//--------------------------------------------------------------------------------------//
57//
58template <typename Tp, typename... Args,
60static auto
61create_heap_variadic(Args... args)
62{
63 return new Tp{ std::move(args)... };
64}
65//
66//--------------------------------------------------------------------------------------//
67//
68template <typename Tp, typename Label, typename... Args,
70static auto
71create_heap_variadic(Label&& _label, scope::config, Args&&... args)
72{
73 return new Tp{ std::forward<Label>(_label), std::forward<Args>(args)... };
74}
75//
76//--------------------------------------------------------------------------------------//
77//
78namespace hidden
79{
80//
81//--------------------------------------------------------------------------------------//
82//
83// Configure the tool for a specific component
84//
85template <typename Toolset>
87 opaque>
89{
90 opaque _obj = Toolset::get_opaque(_scope);
91
92 // this is not in base-class impl
94
95 return _obj;
96}
97//
98//--------------------------------------------------------------------------------------//
99//
100// Configure the tool for a specific set of tools
101//
102template <typename Toolset, typename... Args>
104get_opaque(scope::config _scope, Args... args)
105{
106 using Toolset_t = Toolset;
107
108 if(Toolset::size() == 0)
109 {
110 DEBUG_PRINT_HERE("returning! %s is empty", demangle<Toolset>().c_str());
111 return opaque{};
112 }
113
114 opaque _obj{};
115
116 _obj.m_valid = true;
117
118 _obj.m_typeid = typeid_hash<Toolset>();
119
120 _obj.m_init = []() {};
121
122 auto _setup = [=](void* v_result, string_view_cref_t _prefix,
123 scope::config _arg_scope) {
124 DEBUG_PRINT_HERE("Setting up %s", demangle<Toolset>().c_str());
125 Toolset_t* _result = static_cast<Toolset_t*>(v_result);
126 if(_result == nullptr)
127 {
128 _result =
129 create_heap_variadic<Toolset_t>(_prefix, _scope + _arg_scope, args...);
130 }
131 else
132 {
133 _result->rekey(_prefix);
134 }
135 return static_cast<void*>(_result);
136 };
137
138 _obj.m_setup = _setup;
139
140 _obj.m_push = [_setup](void*& v_result, string_view_cref_t _prefix,
141 scope::config arg_scope) {
142 v_result = _setup(v_result, _prefix, arg_scope);
143 if(v_result)
144 {
145 DEBUG_PRINT_HERE("Pushing %s", demangle<Toolset>().c_str());
146 Toolset_t* _result = static_cast<Toolset_t*>(v_result);
147 _result->push();
148 }
149 };
150
151 _obj.m_sample = [](void* v_result) {
152 if(v_result)
153 {
154 DEBUG_PRINT_HERE("Sampling %s", demangle<Toolset_t>().c_str());
155 Toolset_t* _result = static_cast<Toolset_t*>(v_result);
156 _result->sample();
157 }
158 };
159
160 _obj.m_start = [](void* v_result) {
161 if(v_result)
162 {
163 DEBUG_PRINT_HERE("Starting %s", demangle<Toolset>().c_str());
164 Toolset_t* _result = static_cast<Toolset_t*>(v_result);
165 _result->start();
166 }
167 };
168
169 _obj.m_stop = [](void* v_result) {
170 if(v_result)
171 {
172 DEBUG_PRINT_HERE("Stopping %s", demangle<Toolset>().c_str());
173 Toolset_t* _result = static_cast<Toolset_t*>(v_result);
174 _result->stop();
175 }
176 };
177
178 _obj.m_pop = [](void* v_result) {
179 if(v_result)
180 {
181 DEBUG_PRINT_HERE("Popping %s", demangle<Toolset>().c_str());
182 Toolset_t* _result = static_cast<Toolset_t*>(v_result);
183 _result->pop();
184 }
185 };
186
187 _obj.m_get = [](void* v_result, void*& ptr, size_t _hash) {
188 if(v_result && !ptr)
189 {
190 DEBUG_PRINT_HERE("Getting %s", demangle<Toolset>().c_str());
191 Toolset_t* _result = static_cast<Toolset_t*>(v_result);
192 _result->get(ptr, _hash);
193 }
194 };
195
196 _obj.m_del = [](void* v_result) {
197 if(v_result)
198 {
199 DEBUG_PRINT_HERE("Deleting %s", demangle<Toolset>().c_str());
200 Toolset_t* _result = static_cast<Toolset_t*>(v_result);
201 delete _result;
202 }
203 };
204
205 return _obj;
206}
207//
208//--------------------------------------------------------------------------------------//
209//
210// If a tool is not avail or has no contents return empty opaque
211//
212template <typename Toolset, typename... Args>
215{
216 return opaque{};
217}
218//
219//--------------------------------------------------------------------------------------//
220//
221template <typename T, bool IsWrapper = concepts::is_wrapper<T>::value>
223//
224//--------------------------------------------------------------------------------------//
225//
226template <typename T>
228{
229 using result_type = std::set<size_t>;
230 static_assert(!concepts::is_wrapper<T>::value,
231 "Internal timemory error! Type should not be a variadic wrapper");
232
233 template <typename U = T>
235 {
236 return result_type({ typeid_hash<U>() });
237 }
238
239 template <typename U = T>
241 {
242 return typeid_hash<U>();
243 }
244
245 template <typename U = T>
247 {
248 return result_type({ 0 });
249 }
250
251 template <typename U = T>
253 {
254 return 0;
255 }
256};
257//
258//--------------------------------------------------------------------------------------//
259//
260template <template <typename...> class TupleT, typename... T>
261struct opaque_typeids<TupleT<T...>, false>
262{
263 using result_type = std::set<size_t>;
264 using this_type = opaque_typeids<TupleT<T...>, false>;
265 static_assert(!concepts::is_wrapper<TupleT<T...>>::value,
266 "Internal timemory error! Type should not be a variadic wrapper");
267
268 template <typename U = TupleT<T...>>
270 {
271 return result_type({ typeid_hash<U>() });
272 }
273
274 template <typename U = TupleT<T...>>
276 {
277 return result_type({ 0 });
278 }
279};
280//
281//--------------------------------------------------------------------------------------//
282//
283template <template <typename...> class TupleT, typename... T>
284struct opaque_typeids<TupleT<T...>, true>
285{
286 using result_type = std::set<size_t>;
287 using this_type = opaque_typeids<TupleT<T...>>;
288 static_assert(concepts::is_wrapper<TupleT<T...>>::value,
289 "Internal timemory error! Type should be a variadic wrapper");
290
291 template <typename U = TupleT<T...>>
293 {
294 auto ret = result_type{ typeid_hash<U>() };
295 TIMEMORY_FOLD_EXPRESSION(get<T>(ret));
296 return ret;
297 }
298
299 template <typename U = TupleT<T...>>
301 {
302 return result_type({ 0 });
303 }
304
305private:
306 template <typename U>
307 static void get(result_type& ret, enable_if_t<trait::is_available<U>::value, int> = 0)
308 {
309 ret.insert(typeid_hash<U>());
310 }
311
312 template <typename U>
313 static void get(result_type&, enable_if_t<!trait::is_available<U>::value, int> = 0)
314 {}
315};
316//
317//--------------------------------------------------------------------------------------//
318//
319} // namespace hidden
320//
321//--------------------------------------------------------------------------------------//
322//
323// Generic handler
324//
325template <typename Toolset, typename Arg, typename... Args>
326opaque
327get_opaque(Arg&& arg, Args&&... args)
328{
329 return hidden::get_opaque<Toolset>(std::forward<Arg>(arg),
330 std::forward<Args>(args)...);
331}
332//
333//--------------------------------------------------------------------------------------//
334//
335// Default with no args
336//
337template <typename Toolset>
338opaque
340{
341 return hidden::get_opaque<Toolset>(tim::scope::get_default());
342}
343//
344//--------------------------------------------------------------------------------------//
345//
346// With scope arguments
347//
348template <typename Toolset>
349opaque
351{
352 return hidden::get_opaque<Toolset>(_scope);
353}
354//
355//--------------------------------------------------------------------------------------//
356//
357// Default with no args
358//
359template <typename Toolset>
360std::set<size_t>
362{
364}
365//
366} // namespace factory
367//
368//--------------------------------------------------------------------------------------//
369//
370} // namespace component
371} // namespace tim
Toolset
Definition: types.hpp:40
enable_if_t<!concepts::is_wrapper< Toolset >::value &&trait::is_available< Toolset >::value, opaque > get_opaque(scope::config _scope)
Definition: definition.hpp:88
opaque get_opaque(Arg &&arg, Args &&... args)
Definition: definition.hpp:327
opaque get_opaque(scope::config _scope)
Definition: definition.hpp:350
std::set< size_t > get_typeids()
Definition: definition.hpp:361
typename std::enable_if< B, T >::type enable_if_t
Definition: types.hpp:58
return false
Definition: definition.hpp:326
Definition: kokkosp.cpp:39
char const std::string & _prefix
Definition: config.cpp:55
const std::string & string_view_cref_t
Definition: language.hpp:103
auto get(const auto_bundle< Tag, Types... > &_obj)
Declare the operations types.
Definition for various functions for sample in operations.
static size_t hash(enable_if_t<!trait::is_available< U >::value, long >=0)
Definition: definition.hpp:252
static auto hash(enable_if_t< trait::is_available< U >::value, int >=0)
Definition: definition.hpp:240
static auto get(enable_if_t< trait::is_available< U >::value, int >=0)
Definition: definition.hpp:234
static result_type get(enable_if_t<!trait::is_available< U >::value, long >=0)
Definition: definition.hpp:246
static result_type get(enable_if_t<!trait::is_available< U >::value, long >=0)
Definition: definition.hpp:275
static result_type get(enable_if_t< trait::is_available< U >::value, int >=0)
Definition: definition.hpp:269
static result_type get(enable_if_t< trait::is_available< U >::value, int >=0)
Definition: definition.hpp:292
static result_type get(enable_if_t<!trait::is_available< U >::value, long >=0)
Definition: definition.hpp:300
init_func_t m_init
Definition: types.hpp:90
concept that specifies that a type is a timemory variadic wrapper
Definition: concepts.hpp:285
this data type encodes the options of storage scope. The default is hierarchical (tree) scope....
Definition: types.hpp:453
trait that signifies that an implementation for the component is available. When this is set to false...
Definition: types.hpp:355
#define DEBUG_PRINT_HERE(...)
Definition: macros.hpp:168
#define TIMEMORY_FOLD_EXPRESSION(...)
Definition: types.hpp:56