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.
properties.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
32#include "timemory/enum.h"
36
37#include <set>
38#include <string>
39#include <type_traits>
40#include <unordered_map>
41
42namespace tim
43{
44//
45//--------------------------------------------------------------------------------------//
46//
47namespace runtime
48{
49//
50//--------------------------------------------------------------------------------------//
51//
52template <int I>
53using make_int_sequence = std::make_integer_sequence<int, I>;
54template <int... Ints>
55using int_sequence = std::integer_sequence<int, Ints...>;
56using component_match_set_t = std::set<std::string>;
57using component_match_vector_t = std::vector<bool (*)(const char*)>;
58using component_match_index_t = std::vector<TIMEMORY_COMPONENT>;
59using opaque_pair_t = std::pair<component::opaque, std::set<size_t>>;
60//
61//--------------------------------------------------------------------------------------//
62//
63static inline size_t
64get_hash(std::string&& key)
65{
66 return ::tim::get_hash(std::forward<std::string>(key));
67}
68//
69//--------------------------------------------------------------------------------------//
70//
71template <int I, int V, typename... Args>
73do_enumerator_generate(std::vector<opaque_pair_t>& opaque_array, int idx, Args&&... args)
74{
75 using type = component::enumerator_t<I>;
77 {
78 if(idx == I)
79 {
80 opaque_array.push_back(
81 { component::factory::get_opaque<type>(std::forward<Args>(args)...),
82 component::factory::get_typeids<type>() });
83 }
84 }
85}
86//
87//--------------------------------------------------------------------------------------//
88//
89template <int I, int V, typename... Args>
91do_enumerator_generate(std::vector<opaque_pair_t>&, int, Args&&...)
92{}
93//
94//--------------------------------------------------------------------------------------//
95//
96// The actual implementation of the function calls
97//
98//--------------------------------------------------------------------------------------//
99//
100template <int I, typename Tp, typename... Args>
102do_enumerator_init(Tp& obj, int idx, Args&&... args)
103{
104 using type = component::enumerator_t<I>;
106 !std::is_same<decay_t<Tp>, type>::value)
107 {
108 if(idx == I)
109 obj.template initialize<type>(std::forward<Args>(args)...);
110 }
111}
112//
113//--------------------------------------------------------------------------------------//
114//
115template <int I, typename Tp, typename... Args>
117do_enumerator_init(Tp&, int, Args&&...)
118{}
119//
120//--------------------------------------------------------------------------------------//
121//
122template <int I>
123inline void
126{
127 using type = component::enumerator_t<I>;
128 constexpr auto _is_ph = concepts::is_placeholder<type>::value;
129 IF_CONSTEXPR(!_is_ph)
130 {
132 if(_id != "TIMEMORY_COMPONENTS_END")
133 {
134 using match_func_t = bool (*)(const char*);
135 match_func_t _func = &component::properties<type>::matches;
136 _vec.emplace_back(_func);
137 _idx.emplace_back(I);
138 _set.insert(_id);
139 for(const auto& itr : component::properties<type>::ids())
140 _set.insert(itr);
141 }
142 }
143}
144//
145//--------------------------------------------------------------------------------------//
146//
147// The fold expressions to call the actual functions
148//
149//--------------------------------------------------------------------------------------//
150//
151template <typename Tp, int... Ints, typename... Args>
152void
153enumerator_init(Tp& obj, int idx, int_sequence<Ints...>, Args&&... args)
154{
156 do_enumerator_init<Ints>(obj, idx, std::forward<Args>(args)...));
157}
158//
159//--------------------------------------------------------------------------------------//
160//
161template <typename Tp, int... Ints, typename... Args>
162void
163enumerator_insert(Tp& obj, int idx, int_sequence<Ints...>, Args&&... args)
164{
165 constexpr int TpV = component::properties<Tp>::value;
166 std::vector<opaque_pair_t> opaque_array{};
167 TIMEMORY_FOLD_EXPRESSION(do_enumerator_generate<Ints, TpV>(
168 opaque_array, idx, std::forward<Args>(args)...));
169 for(auto&& itr : opaque_array)
170 obj.insert(std::move(itr.first), std::move(itr.second));
171}
172//
173//--------------------------------------------------------------------------------------//
174//
175template <typename Tp, int... Ints, typename... Args>
176void
178{
179 constexpr int TpV = component::properties<Tp>::value;
180 std::vector<opaque_pair_t> opaque_array{};
181 TIMEMORY_FOLD_EXPRESSION(do_enumerator_generate<Ints, TpV>(
182 opaque_array, idx, std::forward<Args>(args)...));
183 for(auto&& itr : opaque_array)
184 Tp::configure(std::move(itr.first), std::move(itr.second));
185}
186//
187//--------------------------------------------------------------------------------------//
188//
189template <typename Tp, int... Ints, typename... Args>
190void
191enumerator_configure(Tp& obj, int idx, int_sequence<Ints...>, Args&&... args)
192{
193 constexpr int TpV = component::properties<Tp>::value;
194 std::vector<opaque_pair_t> opaque_array{};
195 TIMEMORY_FOLD_EXPRESSION(do_enumerator_generate<Ints, TpV>(
196 opaque_array, idx, std::forward<Args>(args)...));
197 for(auto&& itr : opaque_array)
198 obj.configure(std::move(itr.first), std::move(itr.second));
199}
200//
201//--------------------------------------------------------------------------------------//
202//
203template <int... Ints>
204void
207{
208 TIMEMORY_FOLD_EXPRESSION(do_enumerator_enumerate<Ints>(_vec, _idx, _set));
209}
210//
211//--------------------------------------------------------------------------------------//
212//
213// The forward declared functions
214//
215//--------------------------------------------------------------------------------------//
216//
217template <typename Tp, typename Arg, typename... Args>
218void
219initialize(Tp& obj, int idx, Arg&& arg, Args&&... args)
220{
222 std::forward<Arg>(arg), std::forward<Args>(args)...);
223}
224//
225//--------------------------------------------------------------------------------------//
226//
227template <typename Tp, typename Arg, typename... Args>
228void
229insert(Tp& obj, int idx, Arg&& arg, Args&&... args)
230{
232 std::forward<Arg>(arg), std::forward<Args>(args)...);
233}
234//
235//--------------------------------------------------------------------------------------//
236//
237template <typename Tp, typename Arg, typename... Args>
238void
239configure(int idx, Arg&& arg, Args&&... args)
240{
241 enumerator_configure<Tp>(idx, make_int_sequence<TIMEMORY_COMPONENTS_END>{},
242 std::forward<Arg>(arg), std::forward<Args>(args)...);
243}
244//
245//--------------------------------------------------------------------------------------//
246//
247template <typename Tp, typename Arg, typename... Args>
248void
249configure(Tp& obj, int idx, Arg&& arg, Args&&... args)
250{
252 std::forward<Arg>(arg), std::forward<Args>(args)...);
253}
254//
255//--------------------------------------------------------------------------------------//
256//
257inline int
259{
261 std::function<void(const char*)>>;
262 static auto _data = []() {
266 enumerator_enumerate(_vec, _idx, _set,
268 std::stringstream ss;
269 ss << "Valid choices are: [";
270 for(auto itr = _set.begin(); itr != _set.end(); ++itr)
271 {
272 ss << "'" << (*itr) << "'";
273 size_t _dist = std::distance(_set.begin(), itr);
274 if(_dist + 1 < _set.size())
275 ss << ", ";
276 }
277 ss << ']';
278 auto _choices = ss.str();
279 auto _msg = [_choices](const char* itr) {
280 fprintf(stderr, "Unknown component: '%s'. %s\n", itr, _choices.c_str());
281 };
282 return data_t(_vec, _idx, _msg);
283 }();
284
285 auto& _vec = std::get<0>(_data);
286 auto& _enum = std::get<1>(_data);
287 auto _key = settings::tolower(key);
288 for(size_t i = 0; i < _vec.size(); ++i)
289 {
290 if(_vec[i](_key.c_str()))
291 return _enum[i];
292 }
293
294 std::get<2>(_data)(key.c_str());
296}
297//
298//--------------------------------------------------------------------------------------//
299//
300inline int
301enumerate(const char* key)
302{
303 return enumerate(std::string(key));
304}
305//
306//--------------------------------------------------------------------------------------//
307//
308// Non-variadic specializations
309//
310//--------------------------------------------------------------------------------------//
311//
312template <typename Tp>
313void
314initialize(Tp& obj, int idx)
315{
317}
318//
319//--------------------------------------------------------------------------------------//
320//
321template <typename Tp>
322void
323insert(Tp& obj, int idx)
324{
326}
327//
328//--------------------------------------------------------------------------------------//
329//
330template <typename Tp>
331void
332configure(int idx)
333{
334 enumerator_configure<Tp>(idx, make_int_sequence<TIMEMORY_COMPONENTS_END>{});
335}
336//
337//--------------------------------------------------------------------------------------//
338//
339template <typename Tp>
340void
341configure(Tp& obj, int idx)
342{
344}
345//
346//--------------------------------------------------------------------------------------//
347//
348template <typename Tp>
349void
350insert(Tp& obj, int idx, scope::config _scope)
351{
353}
354//
355//--------------------------------------------------------------------------------------//
356//
357template <typename Tp>
358void
359configure(int idx, scope::config _scope)
360{
361 enumerator_configure<Tp>(idx, make_int_sequence<TIMEMORY_COMPONENTS_END>{}, _scope);
362}
363//
364//--------------------------------------------------------------------------------------//
365//
366template <typename Tp>
367void
368configure(Tp& obj, int idx, scope::config _scope)
369{
371}
372//
373//--------------------------------------------------------------------------------------//
374//
375} // namespace runtime
376} // namespace tim
#define TIMEMORY_COMPONENTS_END
Definition: enum.h:155
#define IF_CONSTEXPR(...)
Definition: language.hpp:72
typename enumerator< Idx >::type enumerator_t
Definition: properties.hpp:273
void configure(Tp &obj, int idx, scope::config _scope)
Definition: properties.hpp:368
int enumerate(const std::string &key)
Definition: properties.hpp:258
std::make_integer_sequence< int, I > make_int_sequence
Definition: properties.hpp:53
void enumerator_enumerate(component_match_vector_t &_vec, component_match_index_t &_idx, component_match_set_t &_set, int_sequence< Ints... >)
Definition: properties.hpp:205
void do_enumerator_enumerate(component_match_vector_t &_vec, component_match_index_t &_idx, component_match_set_t &_set)
Definition: properties.hpp:124
std::pair< component::opaque, std::set< size_t > > opaque_pair_t
Definition: properties.hpp:59
std::set< std::string > component_match_set_t
Definition: properties.hpp:56
std::integer_sequence< int, Ints... > int_sequence
Definition: properties.hpp:55
void insert(Tp &obj, int idx, Arg &&arg, Args &&... args)
Definition: properties.hpp:229
enable_if_t< component::enumerator< I >::value, void > do_enumerator_init(Tp &obj, int idx, Args &&... args)
Definition: properties.hpp:102
enable_if_t< component::enumerator< I >::value &&I !=V, void > do_enumerator_generate(std::vector< opaque_pair_t > &opaque_array, int idx, Args &&... args)
Definition: properties.hpp:73
std::vector< TIMEMORY_COMPONENT > component_match_index_t
Definition: properties.hpp:58
void enumerator_insert(Tp &obj, int idx, int_sequence< Ints... >, Args &&... args)
Definition: properties.hpp:163
void initialize(Tp &obj, int idx, Arg &&arg, Args &&... args)
Definition: properties.hpp:219
std::vector< bool(*)(const char *)> component_match_vector_t
Definition: properties.hpp:57
void configure(int idx, Arg &&arg, Args &&... args)
Definition: properties.hpp:239
void enumerator_init(Tp &obj, int idx, int_sequence< Ints... >, Args &&... args)
Definition: properties.hpp:153
void enumerator_configure(int idx, int_sequence< Ints... >, Args &&... args)
Definition: properties.hpp:177
typename data< Tp >::type data_t
Definition: types.hpp:50
Definition: kokkosp.cpp:39
typename std::decay< T >::type decay_t
Alias template for decay.
Definition: types.hpp:194
typename std::enable_if< B, T >::type enable_if_t
Alias template for enable_if.
Definition: types.hpp:190
tim::mpl::apply< std::string > string
Definition: macros.hpp:53
This is a critical specialization for mapping string and integers to component types at runtime....
Definition: properties.hpp:214
static constexpr const char * id()
Definition: properties.hpp:221
concept that specifies that a type is not necessarily marked as not available but is still a dummy ty...
Definition: concepts.hpp:198
this data type encodes the options of storage scope. The default is hierarchical (tree) scope....
Definition: types.hpp:453
static string_t tolower(string_t str)
Definition: settings.cpp:135
#define TIMEMORY_FOLD_EXPRESSION(...)
Definition: types.hpp:56