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.
lightweight_tuple.cpp
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#ifndef TIMEMORY_VARIADIC_LIGHTWEIGHT_TUPLE_CPP_
26#define TIMEMORY_VARIADIC_LIGHTWEIGHT_TUPLE_CPP_ 1
27
29
34
35//======================================================================================//
36//
37// tim::get functions
38//
39namespace tim
40{
41//--------------------------------------------------------------------------------------//
42//
43template <typename... Types>
44template <typename... T>
46 quirk::config<T...> _config,
47 transient_func_t _init_func)
48: bundle_type(bundle_type::handle(type_list_type{}, _key, false_type{}, _config))
49, m_data(invoke::construct<data_type>(_key, _config))
50{
51 bundle_type::init(type_list_type{}, *this, m_data, std::move(_init_func), _config);
52}
53
54//--------------------------------------------------------------------------------------//
55//
56template <typename... Types>
57template <typename... T>
59 quirk::config<T...> _config,
60 transient_func_t _init_func)
61: bundle_type(bundle_type::handle(type_list_type{}, _loc, false_type{}, _config))
62, m_data(invoke::construct<data_type>(_loc, _config))
63{
64 bundle_type::init(type_list_type{}, *this, m_data, std::move(_init_func), _config);
65}
66
67//--------------------------------------------------------------------------------------//
68//
69template <typename... Types>
70template <typename... T>
72 transient_func_t _init_func)
73: bundle_type(bundle_type::handle(type_list_type{}, _hash, false_type{}, _config))
74, m_data(invoke::construct<data_type>(_hash, _config))
75{
76 bundle_type::init(type_list_type{}, *this, m_data, std::move(_init_func), _config);
77}
78
79//--------------------------------------------------------------------------------------//
80//
81template <typename... Types>
83 transient_func_t _init_func)
84: bundle_type(bundle_type::handle(type_list_type{}, _hash, false_type{}, _scope))
85, m_data(invoke::construct<data_type>(_hash, m_scope))
86{
87 bundle_type::init(type_list_type{}, *this, m_data, std::move(_init_func));
88}
89
90//--------------------------------------------------------------------------------------//
91//
92template <typename... Types>
94 transient_func_t _init_func)
95: bundle_type(bundle_type::handle(type_list_type{}, _key, false_type{}, _scope))
96{
97 bundle_type::init(type_list_type{}, *this, m_data, std::move(_init_func));
98}
99
100//--------------------------------------------------------------------------------------//
101//
102template <typename... Types>
104 scope::config _scope,
105 transient_func_t _init_func)
106: lightweight_tuple(loc.get_hash(), _scope, std::move(_init_func))
107{}
108
109//--------------------------------------------------------------------------------------//
110//
111template <typename... Types>
113{
115 {
116 if(m_is_active())
117 stop();
118 }
119}
120
121//--------------------------------------------------------------------------------------//
122//
123template <typename... Types>
124lightweight_tuple<Types...>
126{
127 lightweight_tuple tmp(*this);
128 tmp.m_store(_store);
129 tmp.m_scope = _scope;
130 return tmp;
131}
132
133//--------------------------------------------------------------------------------------//
134// insert into graph
135//
136template <typename... Types>
137lightweight_tuple<Types...>&
139{
140 if(!m_is_pushed())
141 {
142 // reset the data
143 invoke::reset(m_data);
144 // avoid pushing/popping when already pushed/popped
145 m_is_pushed(true);
146 // insert node or find existing node
147 invoke::push(m_data, m_scope, m_hash);
148 }
149 return get_this_type();
150}
151
152//--------------------------------------------------------------------------------------//
153// insert into graph
154//
155template <typename... Types>
156template <typename... Tp>
159{
160 using pw_type = mpl::implemented_t<Tp...>;
161 // reset the data
162 invoke_piecewise<operation::reset>(pw_type{});
163 // insert node or find existing node
164 invoke_piecewise<operation::push_node>(pw_type{}, m_scope, m_hash);
165 return get_this_type();
166}
167
168//--------------------------------------------------------------------------------------//
169// insert into graph
170//
171template <typename... Types>
172template <typename... Tp>
175{
177 // reset the data
178 invoke_piecewise<operation::reset>(pw_type{});
179 // insert node or find existing node
180 invoke_piecewise<operation::push_node>(pw_type{}, m_scope, m_hash);
181 return get_this_type();
182}
183
184//--------------------------------------------------------------------------------------//
185// pop out of graph
186//
187template <typename... Types>
188lightweight_tuple<Types...>&
190{
191 if(m_is_pushed())
192 {
193 // set the current node to the parent node
194 invoke::pop(m_data);
195 // avoid pushing/popping when already pushed/popped
196 m_is_pushed(false);
197 }
198 return get_this_type();
199}
200
201//--------------------------------------------------------------------------------------//
202// pop out of graph
203//
204template <typename... Types>
205template <typename... Tp>
208{
209 using pw_type = mpl::implemented_t<Tp...>;
210 // set the current node to the parent node
211 invoke_piecewise<operation::pop_node>(pw_type{});
212 return get_this_type();
213}
214
215//--------------------------------------------------------------------------------------//
216// pop out of graph
217//
218template <typename... Types>
219template <typename... Tp>
222{
224 // set the current node to the parent node
225 invoke_piecewise<operation::pop_node>(pw_type{});
226 return get_this_type();
227}
228
229//--------------------------------------------------------------------------------------//
230// measure functions
231//
232template <typename... Types>
233template <typename... Args>
234lightweight_tuple<Types...>&
236{
237 invoke::measure(m_data, std::forward<Args>(args)...);
238 return get_this_type();
239}
240
241//--------------------------------------------------------------------------------------//
242// sample functions
243//
244template <typename... Types>
245template <typename... Args>
246lightweight_tuple<Types...>&
248{
249 invoke::invoke<operation::sample, TIMEMORY_API>(m_data, std::forward<Args>(args)...);
250 return get_this_type();
251}
252
253//--------------------------------------------------------------------------------------//
254// start/stop functions with no push/pop or assemble/derive
255//
256template <typename... Types>
257template <typename... Args>
258lightweight_tuple<Types...>&
260{
261 invoke::start(m_data, std::forward<Args>(args)...);
262 m_is_active(true);
263 return get_this_type();
264}
265
266//--------------------------------------------------------------------------------------//
267// start/stop functions with no push/pop or assemble/derive
268//
269template <typename... Types>
270template <typename... Tp, typename... Args>
271lightweight_tuple<Types...>&
273{
274 auto&& _data = mpl::get_reference_tuple<mpl::available_t<std::tuple<Tp...>>>(m_data);
275 invoke::start(_data, std::forward<Args>(args)...);
276 return get_this_type();
277}
278
279//--------------------------------------------------------------------------------------//
280// start/stop functions with no push/pop or assemble/derive
281//
282template <typename... Types>
283template <typename... Tp, typename... Args>
284lightweight_tuple<Types...>&
286{
287 using selected_t =
289 std::tuple<>>;
290 auto&& _data = mpl::get_reference_tuple<selected_t>(m_data);
291 invoke::start(_data, std::forward<Args>(args)...);
292 return get_this_type();
293}
294
295//--------------------------------------------------------------------------------------//
296//
297template <typename... Types>
298template <typename... Args>
299lightweight_tuple<Types...>&
301{
302 invoke::stop(m_data, std::forward<Args>(args)...);
303 ++m_laps;
304 m_is_active(false);
305 return get_this_type();
306}
307
308//--------------------------------------------------------------------------------------//
309// start/stop functions with no push/pop or assemble/derive
310//
311template <typename... Types>
312template <typename... Tp, typename... Args>
313lightweight_tuple<Types...>&
315{
316 auto&& _data = mpl::get_reference_tuple<mpl::available_t<std::tuple<Tp...>>>(m_data);
317 invoke::stop(_data, std::forward<Args>(args)...);
318 return get_this_type();
319}
320
321//--------------------------------------------------------------------------------------//
322// start/stop functions with no push/pop or assemble/derive
323//
324template <typename... Types>
325template <typename... Tp, typename... Args>
326lightweight_tuple<Types...>&
328{
329 using selected_t =
331 std::tuple<>>;
332 auto&& _data = mpl::get_reference_tuple<selected_t>(m_data);
333 invoke::stop(_data, std::forward<Args>(args)...);
334 return get_this_type();
335}
336
337//--------------------------------------------------------------------------------------//
338// recording
339//
340template <typename... Types>
341template <typename... Args>
342lightweight_tuple<Types...>&
344{
345 ++m_laps;
346 invoke::record(m_data, std::forward<Args>(args)...);
347 return get_this_type();
348}
349
350//--------------------------------------------------------------------------------------//
351// reset data
352//
353template <typename... Types>
354template <typename... Args>
355lightweight_tuple<Types...>&
357{
358 invoke::reset(m_data, std::forward<Args>(args)...);
359 m_laps = 0;
360 return get_this_type();
361}
362
363//--------------------------------------------------------------------------------------//
364// get data
365//
366template <typename... Types>
367template <typename... Args>
368auto
370{
371 return invoke::get(m_data, std::forward<Args>(args)...);
372}
373
374//--------------------------------------------------------------------------------------//
375// reset data
376//
377template <typename... Types>
378template <typename... Args>
379auto
381{
382 return invoke::get_labeled(m_data, std::forward<Args>(args)...);
383}
384
385//--------------------------------------------------------------------------------------//
386// this_type operators
387//
388template <typename... Types>
389lightweight_tuple<Types...>&
391{
392 invoke::invoke_impl::invoke_data<operation::minus, TIMEMORY_API>(m_data, rhs.m_data);
393 m_laps -= rhs.m_laps;
394 return get_this_type();
395}
396
397//--------------------------------------------------------------------------------------//
398//
399template <typename... Types>
400lightweight_tuple<Types...>&
402{
403 invoke::invoke_impl::invoke_data<operation::minus, TIMEMORY_API>(m_data, rhs.m_data);
404 m_laps -= rhs.m_laps;
405 return get_this_type();
406}
407
408//--------------------------------------------------------------------------------------//
409//
410template <typename... Types>
411lightweight_tuple<Types...>&
413{
414 invoke::invoke_impl::invoke_data<operation::plus, TIMEMORY_API>(m_data, rhs.m_data);
415 m_laps += rhs.m_laps;
416 return get_this_type();
417}
418
419//--------------------------------------------------------------------------------------//
420//
421template <typename... Types>
422lightweight_tuple<Types...>&
424{
425 invoke::invoke_impl::invoke_data<operation::plus, TIMEMORY_API>(m_data, rhs.m_data);
426 m_laps += rhs.m_laps;
427 return get_this_type();
428}
429
430//--------------------------------------------------------------------------------------//
431//
432template <typename... Types>
433typename lightweight_tuple<Types...>::data_type&
435{
436 return m_data;
437}
438
439//--------------------------------------------------------------------------------------//
440//
441template <typename... Types>
442const typename lightweight_tuple<Types...>::data_type&
444{
445 return m_data;
446}
447
448//--------------------------------------------------------------------------------------//
449//
450template <typename... Types>
451void
453{
454 invoke::set_prefix(m_data, m_hash, _key);
455}
456
457//--------------------------------------------------------------------------------------//
458//
459template <typename... Types>
460void
462{
463 auto itr = get_hash_ids()->find(_hash);
464 if(itr != get_hash_ids()->end())
465 invoke::set_prefix(m_data, _hash, itr->second);
466}
467
468//--------------------------------------------------------------------------------------//
469//
470template <typename... Types>
471lightweight_tuple<Types...>&
473{
474 m_scope = val;
475 invoke::set_scope(m_data, m_scope);
476 return get_this_type();
477}
478
479//--------------------------------------------------------------------------------------//
480//
481template <typename... Types>
482void
484{
485 static thread_local bool _once = []() {
486 apply_v::type_access<operation::init_storage, data_type>();
487 return true;
488 }();
489 consume_parameters(_once);
490}
491
492//--------------------------------------------------------------------------------------//
493
494} // namespace tim
495
496#endif
This is a variadic component wrapper which provides the least amount of runtime and compilation overh...
lightweight_tuple clone(bool store, scope::config _scope=scope::get_default())
this_type & measure(Args &&...)
generic
void set_prefix(const string_t &) const
this_type & reset(Args &&...)
generic
this_type & operator-=(const this_type &rhs)
this_type & pop()
generic pop out of storage
typename bundle_type::data_type data_type
tim::variadic::impl::quirk_config< T, type_list< Types... >, U... > quirk_config
this_type & operator+=(const this_type &rhs)
this_type & push()
generic push into storage
static void init_storage()
requests the component initialize their storage
auto get_labeled(Args &&...) const
generic
this_type & stop(Args &&...)
stop all applicable components
typename bundle_type::string_t string_t
this_type & set_scope(scope::config)
set scope configuration
T * get()
get member functions taking either a type
data_type & data()
get tuple
this_type & record(Args &&...)
generic
this_type & sample(Args &&...)
generic
this_type & start(Args &&...)
start all applicable components
#define IF_CONSTEXPR(...)
Definition: language.hpp:72
STL namespace.
return _hash_map end()
size_t get_hash(T &&obj)
Definition: utility.hpp:206
hash_map_ptr_t & get_hash_ids()
void set_scope(TupleT< Tp... > &obj, Args &&... args)
Definition: functional.cpp:810
void set_prefix(TupleT< Tp... > &obj, Args &&... args)
Definition: functional.cpp:774
void record(TupleT< Tp... > &obj, Args &&... args)
Definition: functional.cpp:634
void pop(TupleT< Tp... > &obj, Args &&... args)
Definition: functional.cpp:739
auto get(TupleT< Tp... > &obj, Args &&... args)
void stop(TupleT< Tp... > &obj, Args &&... args)
Definition: functional.cpp:386
void measure(TupleT< Tp... > &obj, Args &&... args)
Definition: functional.cpp:669
void push(TupleT< Tp... > &obj, Args &&... args)
Definition: functional.cpp:704
auto get_labeled(TupleT< Tp... > &obj, Args &&... args)
void reset(TupleT< Tp... > &obj, Args &&... args)
Definition: functional.cpp:599
void start(TupleT< Tp... > &obj, Args &&... args)
Definition: functional.cpp:316
impl::filter_false_after_decay_t< trait::is_available, type_list< Types... > > implemented_t
filter out any types that are not available
Definition: available.hpp:318
decltype(auto) get_reference_tuple(Tp &&_tuple)
Definition: types.hpp:1075
impl::filter_false< trait::is_available, T > available_t
Definition: available.hpp:324
typename impl::subtract< LhsT, RhsT >::type subtract_t
Definition: filters.hpp:426
Ret invoke(string_view_t &&label, Func &&func, Args &&... args)
Definition: invoker.hpp:39
std::bitset< scope_count > data_type
Definition: types.hpp:399
A light-weight alternative to std::function. Pass any callback - including capturing lambdas - cheapl...
Definition: kokkosp.cpp:39
void init(Args &&... args)
Definition: types.hpp:111
typename impl::convert< T, U >::type convert_t
Definition: types.hpp:855
void consume_parameters(ArgsT &&...)
Definition: types.hpp:285
lightweight tuple-alternative for meta-programming logic
Definition: types.hpp:233
a variadic type which holds zero or more quirks that are passed to the constructor of a component bun...
Definition: quirks.hpp:39
this data type encodes the options of storage scope. The default is hierarchical (tree) scope....
Definition: types.hpp:453