timemory  3.2.1
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 #include "timemory/mpl/filters.hpp"
33 
34 //======================================================================================//
35 //
36 // tim::get functions
37 //
38 namespace tim
39 {
40 //--------------------------------------------------------------------------------------//
41 //
42 template <typename... Types>
43 template <typename... T>
45  quirk::config<T...> _config,
46  transient_func_t _init_func)
47 : bundle_type(bundle_type::handle(type_list_type{}, _key, false_type{}, _config))
48 , m_data(invoke::construct<data_type>(_key, _config))
49 {
50  bundle_type::init(type_list_type{}, *this, m_data, std::move(_init_func), _config);
51 }
52 
53 //--------------------------------------------------------------------------------------//
54 //
55 template <typename... Types>
56 template <typename... T>
58  quirk::config<T...> _config,
59  transient_func_t _init_func)
60 : bundle_type(bundle_type::handle(type_list_type{}, _loc, false_type{}, _config))
61 , m_data(invoke::construct<data_type>(_loc, _config))
62 {
63  bundle_type::init(type_list_type{}, *this, m_data, std::move(_init_func), _config);
64 }
65 
66 //--------------------------------------------------------------------------------------//
67 //
68 template <typename... Types>
69 template <typename... T>
71  transient_func_t _init_func)
72 : bundle_type(bundle_type::handle(type_list_type{}, _hash, false_type{}, _config))
73 , m_data(invoke::construct<data_type>(_hash, _config))
74 {
75  bundle_type::init(type_list_type{}, *this, m_data, std::move(_init_func), _config);
76 }
77 
78 //--------------------------------------------------------------------------------------//
79 //
80 template <typename... Types>
82  transient_func_t _init_func)
83 : bundle_type(bundle_type::handle(type_list_type{}, _hash, false_type{}, _scope))
84 , m_data(invoke::construct<data_type>(_hash, m_scope))
85 {
86  bundle_type::init(type_list_type{}, *this, m_data, std::move(_init_func));
87 }
88 
89 //--------------------------------------------------------------------------------------//
90 //
91 template <typename... Types>
93  transient_func_t _init_func)
94 : bundle_type(bundle_type::handle(type_list_type{}, _key, false_type{}, _scope))
95 {
96  bundle_type::init(type_list_type{}, *this, m_data, std::move(_init_func));
97 }
98 
99 //--------------------------------------------------------------------------------------//
100 //
101 template <typename... Types>
103  scope::config _scope,
104  transient_func_t _init_func)
105 : lightweight_tuple(loc.get_hash(), _scope, std::move(_init_func))
106 {}
107 
108 //--------------------------------------------------------------------------------------//
109 //
110 template <typename... Types>
112 {
114  {
115  if(m_is_active())
116  stop();
117  }
118 }
119 
120 //--------------------------------------------------------------------------------------//
121 //
122 template <typename... Types>
123 lightweight_tuple<Types...>
125 {
126  lightweight_tuple tmp(*this);
127  tmp.m_store(_store);
128  tmp.m_scope = _scope;
129  return tmp;
130 }
131 
132 //--------------------------------------------------------------------------------------//
133 // insert into graph
134 //
135 template <typename... Types>
136 lightweight_tuple<Types...>&
138 {
139  if(!m_is_pushed())
140  {
141  // reset the data
142  invoke::reset(m_data);
143  // avoid pushing/popping when already pushed/popped
144  m_is_pushed(true);
145  // insert node or find existing node
146  invoke::push(m_data, m_scope, m_hash);
147  }
148  return *this;
149 }
150 
151 //--------------------------------------------------------------------------------------//
152 // pop out of graph
153 //
154 template <typename... Types>
155 lightweight_tuple<Types...>&
157 {
158  if(m_is_pushed())
159  {
160  // set the current node to the parent node
161  invoke::pop(m_data);
162  // avoid pushing/popping when already pushed/popped
163  m_is_pushed(false);
164  }
165  return *this;
166 }
167 
168 //--------------------------------------------------------------------------------------//
169 // measure functions
170 //
171 template <typename... Types>
172 template <typename... Args>
173 lightweight_tuple<Types...>&
175 {
176  invoke::measure(m_data, std::forward<Args>(args)...);
177  return *this;
178 }
179 
180 //--------------------------------------------------------------------------------------//
181 // sample functions
182 //
183 template <typename... Types>
184 template <typename... Args>
185 lightweight_tuple<Types...>&
187 {
188  invoke::invoke<operation::sample, TIMEMORY_API>(m_data, std::forward<Args>(args)...);
189  return *this;
190 }
191 
192 //--------------------------------------------------------------------------------------//
193 // start/stop functions with no push/pop or assemble/derive
194 //
195 template <typename... Types>
196 template <typename... Args>
197 lightweight_tuple<Types...>&
199 {
200  invoke::start(m_data, std::forward<Args>(args)...);
201  m_is_active(true);
202  return *this;
203 }
204 
205 //--------------------------------------------------------------------------------------//
206 //
207 template <typename... Types>
208 template <typename... Args>
209 lightweight_tuple<Types...>&
211 {
212  invoke::stop(m_data, std::forward<Args>(args)...);
213  ++m_laps;
214  m_is_active(false);
215  return *this;
216 }
217 
218 //--------------------------------------------------------------------------------------//
219 // recording
220 //
221 template <typename... Types>
222 template <typename... Args>
223 lightweight_tuple<Types...>&
225 {
226  ++m_laps;
227  invoke::record(m_data, std::forward<Args>(args)...);
228  return *this;
229 }
230 
231 //--------------------------------------------------------------------------------------//
232 // reset data
233 //
234 template <typename... Types>
235 template <typename... Args>
236 lightweight_tuple<Types...>&
238 {
239  invoke::reset(m_data, std::forward<Args>(args)...);
240  m_laps = 0;
241  return *this;
242 }
243 
244 //--------------------------------------------------------------------------------------//
245 // get data
246 //
247 template <typename... Types>
248 template <typename... Args>
249 auto
250 lightweight_tuple<Types...>::get(Args&&... args) const
251 {
252  return invoke::get(m_data, std::forward<Args>(args)...);
253 }
254 
255 //--------------------------------------------------------------------------------------//
256 // reset data
257 //
258 template <typename... Types>
259 template <typename... Args>
260 auto
262 {
263  return invoke::get_labeled(m_data, std::forward<Args>(args)...);
264 }
265 
266 //--------------------------------------------------------------------------------------//
267 // this_type operators
268 //
269 template <typename... Types>
270 lightweight_tuple<Types...>&
272 {
273  invoke::invoke_impl::invoke_data<operation::minus, TIMEMORY_API>(m_data, rhs.m_data);
274  m_laps -= rhs.m_laps;
275  return *this;
276 }
277 
278 //--------------------------------------------------------------------------------------//
279 //
280 template <typename... Types>
281 lightweight_tuple<Types...>&
283 {
284  invoke::invoke_impl::invoke_data<operation::minus, TIMEMORY_API>(m_data, rhs.m_data);
285  m_laps -= rhs.m_laps;
286  return *this;
287 }
288 
289 //--------------------------------------------------------------------------------------//
290 //
291 template <typename... Types>
292 lightweight_tuple<Types...>&
294 {
295  invoke::invoke_impl::invoke_data<operation::plus, TIMEMORY_API>(m_data, rhs.m_data);
296  m_laps += rhs.m_laps;
297  return *this;
298 }
299 
300 //--------------------------------------------------------------------------------------//
301 //
302 template <typename... Types>
303 lightweight_tuple<Types...>&
305 {
306  invoke::invoke_impl::invoke_data<operation::plus, TIMEMORY_API>(m_data, rhs.m_data);
307  m_laps += rhs.m_laps;
308  return *this;
309 }
310 
311 //--------------------------------------------------------------------------------------//
312 //
313 template <typename... Types>
314 typename lightweight_tuple<Types...>::data_type&
316 {
317  return m_data;
318 }
319 
320 //--------------------------------------------------------------------------------------//
321 //
322 template <typename... Types>
323 const typename lightweight_tuple<Types...>::data_type&
325 {
326  return m_data;
327 }
328 
329 //--------------------------------------------------------------------------------------//
330 //
331 template <typename... Types>
332 void
334 {
335  invoke::set_prefix(m_data, m_hash, _key);
336 }
337 
338 //--------------------------------------------------------------------------------------//
339 //
340 template <typename... Types>
341 void
343 {
344  auto itr = get_hash_ids()->find(_hash);
345  if(itr != get_hash_ids()->end())
346  invoke::set_prefix(m_data, _hash, itr->second);
347 }
348 
349 //--------------------------------------------------------------------------------------//
350 //
351 template <typename... Types>
352 lightweight_tuple<Types...>&
354 {
355  m_scope = val;
356  invoke::set_scope(m_data, m_scope);
357  return *this;
358 }
359 
360 //--------------------------------------------------------------------------------------//
361 //
362 template <typename... Types>
363 void
365 {
366  static thread_local bool _once = []() {
367  apply_v::type_access<operation::init_storage, data_type>();
368  return true;
369  }();
370  consume_parameters(_once);
371 }
372 
373 //--------------------------------------------------------------------------------------//
374 
375 } // namespace tim
376 
377 #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())
void set_prefix(const string_t &) const
this_type & operator-=(const this_type &rhs)
T * get()
get member functions taking either a type
this_type & stop(Args &&...)
this_type & measure(Args &&...)
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 & reset(Args &&...)
this_type & sample(Args &&...)
this_type & start(Args &&...)
static void init_storage()
requests the component initialize their storage
auto get_labeled(Args &&...) const
this_type & record(Args &&...)
typename bundle_type::string_t string_t
this_type & set_scope(scope::config)
#define IF_CONSTEXPR(...)
Definition: language.hpp:72
void set_scope(TupleT< Tp... > &obj, Args &&... args)
Definition: functional.cpp:792
void set_prefix(TupleT< Tp... > &obj, Args &&... args)
Definition: functional.cpp:756
void record(TupleT< Tp... > &obj, Args &&... args)
Definition: functional.cpp:616
void pop(TupleT< Tp... > &obj, Args &&... args)
Definition: functional.cpp:721
auto get(TupleT< Tp... > &obj, Args &&... args)
Definition: functional.cpp:992
void stop(TupleT< Tp... > &obj, Args &&... args)
Definition: functional.cpp:368
void measure(TupleT< Tp... > &obj, Args &&... args)
Definition: functional.cpp:651
void push(TupleT< Tp... > &obj, Args &&... args)
Definition: functional.cpp:686
auto get_labeled(TupleT< Tp... > &obj, Args &&... args)
void reset(TupleT< Tp... > &obj, Args &&... args)
Definition: functional.cpp:581
void start(TupleT< Tp... > &obj, Args &&... args)
Definition: functional.cpp:298
Ret invoke(string_view_t &&label, Func &&func, Args &&... args)
Definition: invoker.hpp:39
std::bitset< scope_count > data_type
Definition: types.hpp:395
A light-weight alternative to std::function. Pass any callback - including capturing lambdas - cheapl...
Definition: kokkosp.cpp:38
size_t get_hash(T &&obj)
Definition: utility.hpp:793
void consume_parameters(ArgsT &&...) TIMEMORY_HIDDEN
Definition: types.hpp:285
void init(Args &&... args)
Definition: types.hpp:111
hash_map_ptr_t & get_hash_ids()
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:446