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.
bundle.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_BUNDLE_CPP_
26#define TIMEMORY_VARIADIC_BUNDLE_CPP_
27
29
30#include "timemory/backends/dmp.hpp"
34#include "timemory/tpls/cereal/cereal.hpp"
39
40namespace tim
41{
42//--------------------------------------------------------------------------------------//
43//
44template <typename Tag, typename BundleT, typename TupleT>
47{
48 static initializer_type _instance = [](this_type&) {};
49 return _instance;
50}
51
52//--------------------------------------------------------------------------------------//
53//
54template <typename Tag, typename BundleT, typename TupleT>
56{
57 update_last_instance(&get_this_type(), get_last_instance(),
59 IF_CONSTEXPR(optional_count() > 0) { apply_v::set_value(m_data, nullptr); }
60 bundle_type::init(type_list_type{}, get_this_type(), m_data, get_initializer());
61}
62
63//--------------------------------------------------------------------------------------//
64//
65template <typename Tag, typename BundleT, typename TupleT>
66template <typename... T>
68 transient_func_t _init_func)
69: bundle_type(bundle_type::handle(type_list_type{}, _key, true_type{}, _config))
70, m_data(invoke::construct<data_type, Tag>(_key, _config))
71{
72 update_last_instance(&get_this_type(), get_last_instance(),
74 IF_CONSTEXPR(optional_count() > 0) { apply_v::set_value(m_data, nullptr); }
75 bundle_type::init(type_list_type{}, get_this_type(), m_data, std::move(_init_func),
76 _config);
77}
78
79//--------------------------------------------------------------------------------------//
80//
81template <typename Tag, typename BundleT, typename TupleT>
82template <typename... T>
84 transient_func_t _init_func)
85: bundle_type(bundle_type::handle(type_list_type{}, _hash, true_type{}, _config))
86, m_data(invoke::construct<data_type, Tag>(_hash, _config))
87{
88 update_last_instance(&get_this_type(), get_last_instance(),
90 IF_CONSTEXPR(optional_count() > 0) { apply_v::set_value(m_data, nullptr); }
91 bundle_type::init(type_list_type{}, get_this_type(), m_data, std::move(_init_func),
92 _config);
93}
94
95//--------------------------------------------------------------------------------------//
96//
97template <typename Tag, typename BundleT, typename TupleT>
98template <typename... T>
100 quirk::config<T...> _config,
101 transient_func_t _init_func)
102: bundle_type(bundle_type::handle(type_list_type{}, _loc, true_type{}, _config))
103, m_data(invoke::construct<data_type, Tag>(_loc, _config))
104{
105 update_last_instance(&get_this_type(), get_last_instance(),
107 IF_CONSTEXPR(optional_count() > 0) { apply_v::set_value(m_data, nullptr); }
108 bundle_type::init(type_list_type{}, get_this_type(), m_data, std::move(_init_func),
109 _config);
110}
111
112//--------------------------------------------------------------------------------------//
113//
114template <typename Tag, typename BundleT, typename TupleT>
115template <typename... T>
117 quirk::config<T...> _config,
118 transient_func_t _init_func)
119: bundle_type(bundle_type::handle(type_list_type{}, _key, _store, _config))
120, m_data(invoke::construct<data_type, Tag>(_key, _config))
121{
122 update_last_instance(&get_this_type(), get_last_instance(),
124 IF_CONSTEXPR(optional_count() > 0) { apply_v::set_value(m_data, nullptr); }
125 bundle_type::init(type_list_type{}, get_this_type(), m_data, std::move(_init_func),
126 _config);
127}
128
129//--------------------------------------------------------------------------------------//
130//
131template <typename Tag, typename BundleT, typename TupleT>
132template <typename... T>
134 quirk::config<T...> _config,
135 transient_func_t _init_func)
136: bundle_type(bundle_type::handle(type_list_type{}, _loc, _store, _config))
137, m_data(invoke::construct<data_type, Tag>(_loc, _config))
138{
139 update_last_instance(&get_this_type(), get_last_instance(),
141 IF_CONSTEXPR(optional_count() > 0) { apply_v::set_value(m_data, nullptr); }
142 bundle_type::init(type_list_type{}, get_this_type(), m_data, std::move(_init_func),
143 _config);
144}
145
146//--------------------------------------------------------------------------------------//
147//
148template <typename Tag, typename BundleT, typename TupleT>
150 scope::config _scope, transient_func_t _init_func)
151: bundle_type(bundle_type::handle(type_list_type{}, _hash, _store, _scope))
152, m_data(invoke::construct<data_type, Tag>(_hash, m_scope))
153{
154 update_last_instance(&get_this_type(), get_last_instance(),
156 IF_CONSTEXPR(optional_count() > 0) { apply_v::set_value(m_data, nullptr); }
157 bundle_type::init(type_list_type{}, get_this_type(), m_data, std::move(_init_func));
158}
159
160//--------------------------------------------------------------------------------------//
161//
162template <typename Tag, typename BundleT, typename TupleT>
164 scope::config _scope, transient_func_t _init_func)
165: bundle_type(bundle_type::handle(type_list_type{}, _key, _store, _scope))
166{
167 update_last_instance(&get_this_type(), get_last_instance(),
169 IF_CONSTEXPR(optional_count() > 0) { apply_v::set_value(m_data, nullptr); }
170 bundle_type::init(type_list_type{}, get_this_type(), m_data, std::move(_init_func));
171}
172
173//--------------------------------------------------------------------------------------//
174//
175template <typename Tag, typename BundleT, typename TupleT>
177 scope::config _scope, transient_func_t _init_func)
178: bundle_type(bundle_type::handle(type_list_type{}, _loc, _store, _scope))
179{
180 update_last_instance(&get_this_type(), get_last_instance(),
182 IF_CONSTEXPR(optional_count() > 0) { apply_v::set_value(m_data, nullptr); }
183 bundle_type::init(type_list_type{}, get_this_type(), m_data, std::move(_init_func));
184}
185
186//--------------------------------------------------------------------------------------//
187//
188template <typename Tag, typename BundleT, typename TupleT>
190 transient_func_t _init_func)
191: bundle_type(bundle_type::handle(type_list_type{}, _hash, true_type{}, _scope))
192{
193 update_last_instance(&get_this_type(), get_last_instance(),
195 IF_CONSTEXPR(optional_count() > 0) { apply_v::set_value(m_data, nullptr); }
196 bundle_type::init(type_list_type{}, get_this_type(), m_data, std::move(_init_func));
197}
198
199//--------------------------------------------------------------------------------------//
200//
201template <typename Tag, typename BundleT, typename TupleT>
203 transient_func_t _init_func)
204: bundle_type(bundle_type::handle(type_list_type{}, _key, true_type{}, _scope))
205{
206 update_last_instance(&get_this_type(), get_last_instance(),
208 IF_CONSTEXPR(optional_count() > 0) { apply_v::set_value(m_data, nullptr); }
209 bundle_type::init(type_list_type{}, get_this_type(), m_data, std::move(_init_func));
210}
211
212//--------------------------------------------------------------------------------------//
213//
214template <typename Tag, typename BundleT, typename TupleT>
216 scope::config _scope, transient_func_t _init_func)
217: bundle_type(bundle_type::handle(type_list_type{}, _loc, true_type{}, _scope))
218{
219 update_last_instance(&get_this_type(), get_last_instance(),
221 IF_CONSTEXPR(optional_count() > 0) { apply_v::set_value(m_data, nullptr); }
222 bundle_type::init(type_list_type{}, get_this_type(), m_data, std::move(_init_func));
223}
224
225//--------------------------------------------------------------------------------------//
226//
227template <typename Tag, typename BundleT, typename TupleT>
229{
230 if(get_last_instance() == &get_this_type())
231 update_last_instance(nullptr, get_last_instance(), false);
232
234 {
235 if(m_is_active())
236 stop();
237 }
238
239 IF_CONSTEXPR(optional_count() > 0)
240 {
241#if defined(DEBUG) && !defined(NDEBUG)
243 {
244 PRINT_HERE("%s", "deleting components");
245 }
246#endif
247 invoke::destroy<Tag>(m_data);
248 }
249}
250
251//--------------------------------------------------------------------------------------//
252//
253template <typename Tag, typename BundleT, typename TupleT>
255: bundle_type(rhs)
256{
258 IF_CONSTEXPR(optional_count() > 0) { apply_v::set_value(m_data, nullptr); }
259 apply_v::access2<copy_oper_t>(m_data, rhs.m_data);
260}
261
262//--------------------------------------------------------------------------------------//
263//
264template <typename Tag, typename BundleT, typename TupleT>
267{
268 if(this != &rhs)
269 {
270 bundle_type::operator=(rhs);
271 invoke::destroy<Tag>(m_data);
272 invoke::invoke_impl::invoke_data<operation::copy, Tag>(m_data, rhs.m_data);
273 // apply_v::access<operation_t<operation::copy>>(m_data);
274 }
275 return get_this_type();
276}
277
278//--------------------------------------------------------------------------------------//
279// this_type operators
280//
281template <typename Tag, typename BundleT, typename TupleT>
284{
285 bundle_type::operator-=(static_cast<const bundle_type&>(rhs));
286 invoke::invoke_impl::invoke_data<operation::minus, Tag>(m_data, rhs.m_data);
287 return get_this_type();
288}
289
290//--------------------------------------------------------------------------------------//
291//
292template <typename Tag, typename BundleT, typename TupleT>
295{
296 bundle_type::operator+=(static_cast<const bundle_type&>(rhs));
297 invoke::invoke_impl::invoke_data<operation::plus, Tag>(m_data, rhs.m_data);
298 return get_this_type();
299}
300
301//--------------------------------------------------------------------------------------//
302//
303template <typename Tag, typename BundleT, typename TupleT>
306{
307 bundle tmp(*this);
308 tmp.m_store(_store);
309 tmp.m_scope = _scope;
310 return tmp;
311}
312
313//--------------------------------------------------------------------------------------//
314//
315template <typename Tag, typename BundleT, typename TupleT>
316void
318{
319 static thread_local bool _once = []() {
320 apply_v::type_access<operation::init_storage, mpl::non_quirk_t<reference_type>>();
321 return true;
322 }();
323 consume_parameters(_once);
324}
325
326//--------------------------------------------------------------------------------------//
327// insert into graph
328//
329template <typename Tag, typename BundleT, typename TupleT>
332{
333 if(!m_enabled())
334 return get_this_type();
335
336 if(!m_is_pushed())
337 {
338 // reset the data
339 invoke::reset<Tag>(m_data);
340 // avoid pushing/popping when already pushed/popped
341 m_is_pushed(true);
342 // insert node or find existing node
343 invoke::push<Tag>(m_data, m_scope, m_hash);
344 }
345 return get_this_type();
346}
347
348//--------------------------------------------------------------------------------------//
349// insert into graph
350//
351template <typename Tag, typename BundleT, typename TupleT>
352template <typename... Tp>
355{
356 if(!m_enabled())
357 return get_this_type();
358
360 // reset the data
361 invoke::invoke<operation::reset, Tag>(pw_type{}, m_data);
362 // insert node or find existing node
363 invoke::invoke<operation::push_node, Tag>(pw_type{}, m_data, m_scope, m_hash);
364 return get_this_type();
365}
366
367//--------------------------------------------------------------------------------------//
368// insert into graph
369//
370template <typename Tag, typename BundleT, typename TupleT>
371template <typename... Tp>
374{
375 if(!m_enabled())
376 return get_this_type();
377
379 // reset the data
380 invoke_piecewise<operation::reset>(pw_type{});
381 // insert node or find existing node
382 invoke_piecewise<operation::push_node>(pw_type{}, m_scope, m_hash);
383 return get_this_type();
384}
385
386//--------------------------------------------------------------------------------------//
387// insert into graph
388//
389template <typename Tag, typename BundleT, typename TupleT>
390template <typename... Tp>
393{
394 if(!m_enabled())
395 return get_this_type();
396
398 // reset the data
399 invoke::invoke<operation::reset, Tag>(pw_type{}, m_data);
400 // insert node or find existing node
401 invoke::invoke<operation::push_node, Tag>(pw_type{}, m_data, _scope, m_hash);
402 return get_this_type();
403}
404
405//--------------------------------------------------------------------------------------//
406// insert into graph
407//
408template <typename Tag, typename BundleT, typename TupleT>
409template <typename... Tp>
412{
413 if(!m_enabled())
414 return get_this_type();
415
417 // reset the data
418 invoke_piecewise<operation::reset>(pw_type{});
419 // insert node or find existing node
420 invoke_piecewise<operation::push_node>(pw_type{}, _scope, m_hash);
421 return get_this_type();
422}
423
424//--------------------------------------------------------------------------------------//
425// pop out of graph
426//
427template <typename Tag, typename BundleT, typename TupleT>
430{
431 if(!m_enabled())
432 return get_this_type();
433
434 if(m_is_pushed())
435 {
436 // set the current node to the parent node
437 invoke::pop<Tag>(m_data);
438 // avoid pushing/popping when already pushed/popped
439 m_is_pushed(false);
440 }
441 return get_this_type();
442}
443
444//--------------------------------------------------------------------------------------//
445// pop out of graph
446//
447template <typename Tag, typename BundleT, typename TupleT>
448template <typename... Tp>
451{
452 if(!m_enabled())
453 return get_this_type();
454
456 // set the current node to the parent node
457 invoke::invoke<operation::pop_node, Tag>(pw_type{}, m_data);
458 return get_this_type();
459}
460
461//--------------------------------------------------------------------------------------//
462// pop out of graph
463//
464template <typename Tag, typename BundleT, typename TupleT>
465template <typename... Tp>
468{
469 if(!m_enabled())
470 return get_this_type();
471
473 // set the current node to the parent node
474 invoke_piecewise<operation::pop_node>(pw_type{});
475 return get_this_type();
476}
477
478//--------------------------------------------------------------------------------------//
479// measure functions
480//
481template <typename Tag, typename BundleT, typename TupleT>
482template <typename... Args>
485{
486 return invoke<operation::measure>(std::forward<Args>(args)...);
487}
488
489//--------------------------------------------------------------------------------------//
490// sample functions
491//
492template <typename Tag, typename BundleT, typename TupleT>
493template <typename... Args>
496{
497 return invoke<operation::sample>(std::forward<Args>(args)...);
498}
499
500//--------------------------------------------------------------------------------------//
501// start/stop functions with no push/pop or assemble/derive
502//
503template <typename Tag, typename BundleT, typename TupleT>
504template <typename... Args>
507{
508 if(!m_enabled())
509 return get_this_type();
510
511 assemble(*this);
512 invoke::start<Tag>(m_data, std::forward<Args>(args)...);
513 m_is_active(true);
514 return get_this_type();
515}
516
517//--------------------------------------------------------------------------------------//
518//
519template <typename Tag, typename BundleT, typename TupleT>
520template <typename... Args>
523{
524 if(!m_enabled())
525 return get_this_type();
526
527 invoke::stop<Tag>(m_data, std::forward<Args>(args)...);
528 if(m_is_active())
529 ++m_laps;
530 derive(*this);
531 m_is_active(false);
532 return get_this_type();
533}
534
535//--------------------------------------------------------------------------------------//
536// start/stop functions with no push/pop or assemble/derive
537//
538template <typename Tag, typename BundleT, typename TupleT>
539template <typename... Tp, typename... Args>
542{
543 if(!m_enabled())
544 return get_this_type();
545
546 using select_tuple_t = mpl::sort<trait::start_priority, std::tuple<Tp...>>;
547
548 invoke_piecewise<operation::reset>(type_list<Tp...>{});
551 {
552 if(m_store() && !bundle_type::m_explicit_push())
553 {
554 invoke_piecewise<operation::push_node>(type_list<Tp...>{}, m_scope, m_hash);
555 }
556 }
557
558 // start components
559 auto&& _data = mpl::get_reference_tuple<select_tuple_t>(m_data);
560 invoke::invoke<operation::standard_start, Tag>(_data, std::forward<Args>(args)...);
561 return get_this_type();
562}
563
564//--------------------------------------------------------------------------------------//
565// start/stop functions with no push/pop or assemble/derive
566//
567template <typename Tag, typename BundleT, typename TupleT>
568template <typename... Tp, typename... Args>
571{
572 using selected_t =
574 return start(convert_t<selected_t, mpl::piecewise_select<>>{},
575 std::forward<Args>(args)...);
576}
577
578//--------------------------------------------------------------------------------------//
579//
580template <typename Tag, typename BundleT, typename TupleT>
581template <typename... Tp, typename... Args>
584{
585 if(!m_enabled())
586 return get_this_type();
587
588 using select_tuple_t = mpl::sort<trait::stop_priority, std::tuple<Tp...>>;
589
590 // stop components
591 auto&& _data = mpl::get_reference_tuple<select_tuple_t>(m_data);
592 invoke::invoke<operation::standard_stop, Tag>(_data, std::forward<Args>(args)...);
593
596 {
597 if(m_store() && !bundle_type::m_explicit_pop())
598 {
599 invoke_piecewise<operation::pop_node>(type_list<Tp...>{});
600 }
601 }
602 return get_this_type();
603}
604
605//--------------------------------------------------------------------------------------//
606//
607template <typename Tag, typename BundleT, typename TupleT>
608template <typename... Tp, typename... Args>
611{
612 using selected_t =
614 return stop(convert_t<selected_t, mpl::piecewise_select<>>{},
615 std::forward<Args>(args)...);
616}
617
618//--------------------------------------------------------------------------------------//
619// start/stop functions
620//
621template <typename Tag, typename BundleT, typename TupleT>
622template <typename... Args>
625{
626 if(!m_enabled())
627 return get_this_type();
628
629 // push components into the call-stack
632 {
633 if(m_store() && !bundle_type::m_explicit_push())
634 push();
635 }
636
637 // start components
638 start(mpl::lightweight{}, std::forward<Args>(args)...);
639 return get_this_type();
640}
641
642//--------------------------------------------------------------------------------------//
643//
644template <typename Tag, typename BundleT, typename TupleT>
645template <typename... Args>
648{
649 if(!m_enabled())
650 return get_this_type();
651
652 // stop components
653 stop(mpl::lightweight{}, std::forward<Args>(args)...);
654
655 // pop components off of the call-stack stack
658 {
659 if(m_store() && !bundle_type::m_explicit_pop())
660 pop();
661 }
662 return get_this_type();
663}
664
665//--------------------------------------------------------------------------------------//
666// recording
667//
668template <typename Tag, typename BundleT, typename TupleT>
669template <typename... Args>
672{
673 if(!m_enabled())
674 return get_this_type();
675
676 ++m_laps;
677 return invoke<operation::record>(std::forward<Args>(args)...);
678}
679
680//--------------------------------------------------------------------------------------//
681// reset data
682//
683template <typename Tag, typename BundleT, typename TupleT>
684template <typename... Args>
687{
688 m_laps = 0;
689 return invoke<operation::reset>(std::forward<Args>(args)...);
690}
691
692//--------------------------------------------------------------------------------------//
693//
694//
695template <typename Tag, typename BundleT, typename TupleT>
696uint64_t
698{
699 uint64_t _count = 0;
700 invoke::invoke<operation::generic_counter>(m_data, std::ref(_count));
701 return _count;
702}
703
704//--------------------------------------------------------------------------------------//
705//
706//
707template <typename Tag, typename BundleT, typename TupleT>
708template <typename... Args>
711{
712 // using construct_t = operation_t<operation::construct>;
713 // apply_v::access<construct_t>(m_data, std::forward<Args>(_args)...);
714 return invoke<operation::construct>(std::forward<Args>(_args)...);
715}
716
717//--------------------------------------------------------------------------------------//
718//
719//
720template <typename Tag, typename BundleT, typename TupleT>
721template <typename... Args>
724{
725 return invoke<operation::assemble>(std::forward<Args>(_args)...);
726}
727
728//--------------------------------------------------------------------------------------//
729//
730//
731template <typename Tag, typename BundleT, typename TupleT>
732template <typename... Args>
735{
736 return invoke<operation::derive>(std::forward<Args>(_args)...);
737}
738
739//--------------------------------------------------------------------------------------//
740//
741//
742template <typename Tag, typename BundleT, typename TupleT>
743template <typename... Args>
746{
747 return invoke<operation::mark>(std::forward<Args>(_args)...);
748}
749
750//--------------------------------------------------------------------------------------//
751//
752//
753template <typename Tag, typename BundleT, typename TupleT>
754template <typename... Args>
757{
758 return invoke<operation::mark_begin>(std::forward<Args>(_args)...);
759}
760
761//--------------------------------------------------------------------------------------//
762//
763//
764template <typename Tag, typename BundleT, typename TupleT>
765template <typename... Args>
768{
769 return invoke<operation::mark_end>(std::forward<Args>(_args)...);
770}
771
772//--------------------------------------------------------------------------------------//
773//
774//
775template <typename Tag, typename BundleT, typename TupleT>
776template <typename... Args>
779{
780 if(!m_enabled())
781 return get_this_type();
782
783 m_is_active(true);
784 invoke<operation::store>(std::forward<Args>(_args)...);
785 m_is_active(false);
786 return get_this_type();
787}
788
789//--------------------------------------------------------------------------------------//
790//
791//
792template <typename Tag, typename BundleT, typename TupleT>
793template <typename... Args>
796{
797 return invoke<operation::audit>(std::forward<Args>(_args)...);
798}
799
800//--------------------------------------------------------------------------------------//
801//
802//
803template <typename Tag, typename BundleT, typename TupleT>
804template <typename... Args>
807{
808 return invoke<operation::add_secondary>(std::forward<Args>(_args)...);
809}
810
811//--------------------------------------------------------------------------------------//
812//
813//
814template <typename Tag, typename BundleT, typename TupleT>
815template <typename... Args>
818{
819 return invoke<operation::add_statistics>(std::forward<Args>(_args)...);
820}
821
822//--------------------------------------------------------------------------------------//
823//
824//
825template <typename Tag, typename BundleT, typename TupleT>
826template <template <typename> class OpT, typename... Args>
829{
830 if(!m_enabled())
831 return get_this_type();
832
833 invoke::invoke<OpT, Tag>(m_data, std::forward<Args>(_args)...);
834 return get_this_type();
835}
836
837//--------------------------------------------------------------------------------------//
838//
839//
840template <typename Tag, typename BundleT, typename TupleT>
841template <template <typename> class OpT, typename... Tp, typename... Args>
844{
845 if(!m_enabled())
846 return get_this_type();
847 invoke_piecewise<OpT>(mpl::available_t<type_list<Tp...>>{},
848 std::forward<Args>(_args)...);
849 return get_this_type();
850}
851
852//--------------------------------------------------------------------------------------//
853//
854//
855template <typename Tag, typename BundleT, typename TupleT>
856template <template <typename> class OpT, typename... Tp, typename... Args>
859{
860 if(!m_enabled())
861 return get_this_type();
862 invoke_piecewise<OpT>(
864 std::forward<Args>(_args)...);
865 return get_this_type();
866}
867
868//--------------------------------------------------------------------------------------//
869//
870//
871template <typename Tag, typename BundleT, typename TupleT>
872template <template <typename> class OpT, typename... Tp, typename... Args>
873void
875{
877 this->get<Tp>(), std::forward<Args>(_args)...));
878}
879
880//--------------------------------------------------------------------------------------//
881// get data
882//
883template <typename Tag, typename BundleT, typename TupleT>
884template <typename... Args>
885auto
887{
888 return invoke::get<Tag>(m_data, std::forward<Args>(args)...);
889}
890
891//--------------------------------------------------------------------------------------//
892// get labeled data
893//
894template <typename Tag, typename BundleT, typename TupleT>
895template <typename... Args>
896auto
898{
899 return invoke::get_labeled<Tag>(m_data, std::forward<Args>(args)...);
900}
901
902//--------------------------------------------------------------------------------------//
903//
904template <typename Tag, typename BundleT, typename TupleT>
907{
908 return m_data;
909}
910
911//--------------------------------------------------------------------------------------//
912//
913template <typename Tag, typename BundleT, typename TupleT>
916{
917 return m_data;
918}
919
920//--------------------------------------------------------------------------------------//
921//
922//
923template <typename Tag, typename BundleT, typename TupleT>
925bundle<Tag, BundleT, TupleT>::get(void*& ptr, size_t _hash) const
926{
927 if(!m_enabled())
928 return get_this_type();
929
930 tim::variadic::impl::get<Tag>(m_data, ptr, _hash);
931 return get_this_type();
932}
933
934//--------------------------------------------------------------------------------------//
935//
936//
937template <typename Tag, typename BundleT, typename TupleT>
938template <typename... Tail>
941{
943 this->get_reference<Tail>() });
944 return get_this_type();
945}
946
947//--------------------------------------------------------------------------------------//
948//
949//
950template <typename Tag, typename BundleT, typename TupleT>
951template <typename... T, typename... Args>
952std::array<bool, sizeof...(T)>
954{
955 if(!m_enabled())
956 return std::array<bool, sizeof...(T)>{};
957
958 constexpr auto N = sizeof...(T);
959 return TIMEMORY_FOLD_EXPANSION(bool, N, init<T>(std::forward<Args>(args)...));
960}
961
962//--------------------------------------------------------------------------------------//
963//
964template <typename Tag, typename BundleT, typename TupleT>
965template <typename T, typename Func, typename... Args,
969{
970 if(!m_enabled())
971 return get_this_type();
972
973 auto* _obj = get<T>();
974 if(_obj)
975 ((*_obj).*(_func))(std::forward<Args>(_args)...);
976 return get_this_type();
977}
978
979//--------------------------------------------------------------------------------------//
980//
981template <typename Tag, typename BundleT, typename TupleT>
982template <typename T, typename Func, typename... Args,
986{
987 return get_this_type();
988}
989
990//--------------------------------------------------------------------------------------//
991//
992template <typename Tag, typename BundleT, typename TupleT>
993void
995{
996 if(!m_enabled())
997 return;
998
999 invoke::set_prefix<Tag>(m_data, m_hash, _key);
1000}
1001
1002//--------------------------------------------------------------------------------------//
1003//
1004template <typename Tag, typename BundleT, typename TupleT>
1007{
1008 if(!m_enabled())
1009 return get_this_type();
1010
1011 const auto& _hash_ids = hash::get_hash_ids();
1012 auto itr = hash::find_hash_identifier(_hash_ids, hash::get_hash_aliases(), _hash);
1013 if(itr != _hash_ids->end())
1014 {
1015 invoke::set_prefix<Tag>(m_data, _hash, itr->second);
1016 }
1017 else
1018 {
1019 const char* _prefix = nullptr;
1021 invoke::set_prefix<Tag>(m_data, _hash, _prefix);
1022 }
1023 return get_this_type();
1024}
1025
1026//--------------------------------------------------------------------------------------//
1027//
1028template <typename Tag, typename BundleT, typename TupleT>
1031{
1032 return set_prefix(_loc.get_hash());
1033}
1034
1035//--------------------------------------------------------------------------------------//
1036//
1037template <typename Tag, typename BundleT, typename TupleT>
1040{
1041 if(!m_enabled())
1042 return get_this_type();
1043
1044 m_scope = val;
1045 invoke::set_scope<Tag>(m_data, m_scope);
1046 return get_this_type();
1047}
1048
1049//--------------------------------------------------------------------------------------//
1050//
1051template <typename Tag, typename BundleT, typename TupleT>
1054{
1055 return scope::transient_destructor{ [&]() { this->stop(); } };
1056}
1057
1058//--------------------------------------------------------------------------------------//
1059//
1060template <typename Tag, typename BundleT, typename TupleT>
1064{
1065 return scope::transient_destructor{ [&, _func]() { _func(get_this_type()); } };
1066}
1067
1068//--------------------------------------------------------------------------------------//
1069//
1070template <typename Tag, typename BundleT, typename TupleT>
1071template <typename T>
1072void
1074{
1075 if(!m_enabled())
1076 return;
1077
1079 std::string* _key = nullptr;
1080 if(get_hash_identifier_fast(m_hash, _key))
1081 PrefixOpT{ obj, m_hash, *_key };
1082}
1083
1084//--------------------------------------------------------------------------------------//
1085//
1086template <typename Tag, typename BundleT, typename TupleT>
1087template <typename T>
1088void
1090{
1091 if(!m_enabled())
1092 return;
1093
1095 PrefixOpT(obj, m_scope);
1096}
1097
1098//----------------------------------------------------------------------------------//
1099//
1100template <typename Tag, typename BundleT, typename TupleT>
1101template <bool PrintPrefix, bool PrintLaps>
1103bundle<Tag, BundleT, TupleT>::print(std::ostream& os, bool _endl) const
1104{
1105 using printer_t = typename bundle_type::print_type;
1106 if(size() == 0 || m_hash == 0)
1107 return get_this_type();
1108 std::stringstream ss_data;
1109 apply_v::access_with_indices<printer_t>(m_data, std::ref(ss_data), false);
1110 if(PrintPrefix)
1111 {
1112 bundle_type::update_width();
1113 std::stringstream ss_prefix;
1114 std::stringstream ss_id;
1115 ss_id << get_prefix() << " " << std::left << key();
1116 ss_prefix << std::setw(bundle_type::output_width()) << std::left << ss_id.str()
1117 << " : ";
1118 os << ss_prefix.str();
1119 }
1120 std::string _s = ss_data.str();
1121 if(_s.empty())
1122 return get_this_type();
1123 while(_s.find_last_of(", ") == _s.length() - 1)
1124 _s = _s.substr(0, _s.length() - 1);
1125 if(_s.empty())
1126 return get_this_type();
1127 os << _s;
1128 if(m_laps > 0 && PrintLaps)
1129 os << " [laps: " << m_laps << "]";
1130 if(_endl)
1131 os << '\n';
1132 return get_this_type();
1133}
1134
1135//----------------------------------------------------------------------------------//
1136//
1137template <typename Tag, typename BundleT, typename TupleT>
1138template <typename Archive>
1139void
1140bundle<Tag, BundleT, TupleT>::serialize(Archive& ar, const unsigned int)
1141{
1142 std::string _key = {};
1143 auto keyitr = get_hash_ids()->find(m_hash);
1144 if(keyitr != get_hash_ids()->end())
1145 _key = keyitr->second;
1146
1147 ar(cereal::make_nvp("hash", m_hash), cereal::make_nvp("key", _key),
1148 cereal::make_nvp("laps", m_laps));
1149
1150 if(keyitr == get_hash_ids()->end())
1151 {
1152 auto _hash = add_hash_id(_key);
1153 if(_hash != m_hash)
1154 {
1155 PRINT_HERE("Warning! Hash for '%s' (%llu) != %llu", _key.c_str(),
1156 (unsigned long long) _hash, (unsigned long long) m_hash);
1157 }
1158 }
1159
1160 ar.setNextName("data");
1161 ar.startNode();
1162 invoke::serialize(ar, m_data);
1163 ar.finishNode();
1164 // ar(cereal::make_nvp("data", m_data));
1165}
1166
1167//--------------------------------------------------------------------------------------//
1168
1169} // namespace tim
1170
1171#endif
Example: bundle<Tag, component_bundle<Foo>, mixed_wrapper_types<concat<Bar, Baz>>> will use Tag + tra...
Definition: bundle.hpp:113
typename TupleT::template data_type< Tag > data_type
Definition: bundle.hpp:153
typename TupleT::type_list_type type_list_type
Definition: bundle.hpp:154
tim::variadic::impl::quirk_config< T, reference_type, U... > quirk_config
Definition: bundle.hpp:164
typename bundle_type::string_t string_t
Definition: bundle.hpp:145
typename TupleT::template this_type< BundleT > this_type
Definition: bundle.hpp:150
std::function< void(this_type &)> initializer_type
Definition: bundle.hpp:157
#define IF_CONSTEXPR(...)
Definition: language.hpp:72
::tim::statistics< tuple<> > & operator+=(::tim::statistics< tuple<> > &_lhs, const Tp &)
Definition: statistics.hpp:338
void serialize(std::string fname, exec_data< Counter > &obj)
Definition: counter.hpp:325
return _hash_map end()
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
hash_alias_ptr_t & get_hash_aliases()
bool get_hash_identifier(const hash_map_ptr_t &_hash_map, const hash_alias_ptr_t &_hash_alias, hash_value_t _hash_id, std::string *&_ret)
string_view_t get_hash_identifier_fast(hash_value_t _hash)
this does not check other threads or aliases. Only call this function when you know that the hash exi...
Definition: types.hpp:252
hash_map_t::const_iterator find_hash_identifier(const hash_map_ptr_t &_hash_map, const hash_alias_ptr_t &_hash_alias, hash_value_t _hash_id)
hash_map_ptr_t & get_hash_ids()
size_t hash_value_t
Definition: types.hpp:84
void set_scope(TupleT< Tp... > &obj, Args &&... args)
Definition: functional.cpp:810
void assemble(TupleT< Tp... > &obj, Args &&... args)
Definition: functional.cpp:868
void mark_begin(TupleT< Tp... > &obj, Args &&... args)
Definition: functional.cpp:492
void set_prefix(TupleT< Tp... > &obj, Args &&... args)
Definition: functional.cpp:774
void audit(TupleT< Tp... > &obj, Args &&... args)
Definition: functional.cpp:939
void store(TupleT< Tp... > &obj, Args &&... args)
Definition: functional.cpp:564
auto serialize(ArchiveT &ar, TupleT< Tp... > &obj)
void record(TupleT< Tp... > &obj, Args &&... args)
Definition: functional.cpp:634
void derive(TupleT< Tp... > &obj, Args &&... args)
Definition: functional.cpp:904
void pop(TupleT< Tp... > &obj, Args &&... args)
Definition: functional.cpp:739
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
void mark_end(TupleT< Tp... > &obj, Args &&... args)
Definition: functional.cpp:528
void mark(TupleT< Tp... > &obj, Args &&... args)
Definition: functional.cpp:457
void reset(TupleT< Tp... > &obj, Args &&... args)
Definition: functional.cpp:599
void print(std::ostream &os, Args &&... args)
Definition: functional.cpp:159
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
convert_t< typename ::tim::mpl::impl::sortT< PrioT, convert_t< Tuple, type_list<> >, convert_t< BegT, type_list<> >, convert_t< EndT, type_list<> > >::type, std::tuple<> > sort
Definition: filters.hpp:478
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
a generic type for indicating that function call or constructor should be as lightweight as possible.
Definition: types.hpp:328
Ret invoke(string_view_t &&label, Func &&func, Args &&... args)
Definition: invoker.hpp:39
std::array< Tp, N > & operator-=(std::array< Tp, N > &, const std::array< Tp, N > &)
Definition: stl.hpp:96
A light-weight alternative to std::function. Pass any callback - including capturing lambdas - cheapl...
Definition: kokkosp.cpp:39
std::array< char *, 4 > _args
char const std::string & _prefix
Definition: config.cpp:55
typename impl::convert_each< T, U... >::type convert_each_t
Definition: types.hpp:858
add_secondary
Definition: settings.cpp:1677
typename std::remove_pointer< U >::type remove_pointer_t
Definition: types.hpp:569
typename std::enable_if< B, T >::type enable_if_t
Alias template for enable_if.
Definition: types.hpp:190
auto get_labeled(const auto_bundle< Tag, Types... > &_obj)
void init(Args &&... args)
Definition: types.hpp:111
tim::mpl::apply< std::string > string
Definition: macros.hpp:53
const std::string std::ostream * os
auto get(const auto_bundle< Tag, Types... > &_obj)
typename impl::convert< T, U >::type convert_t
Definition: types.hpp:855
void consume_parameters(ArgsT &&...)
Definition: types.hpp:285
Static polymorphic base class for component bundlers.
Definition: bundle.hpp:51
lightweight tuple-alternative for meta-programming logic
Definition: types.hpp:233
This operation class is similar to pointer_operator but can handle non-pointer types.
Definition: generic.hpp:55
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
const hash_value_t & get_hash() const
trait that designates whether there is a priority when starting the type w.r.t. other types....
trait that designates whether there is a priority when stopping the type w.r.t. other types....
#define PRINT_HERE(...)
Definition: macros.hpp:152
#define TIMEMORY_FOLD_EXPRESSION(...)
Definition: types.hpp:56
#define TIMEMORY_FOLD_EXPANSION(TYPE, SIZE,...)
Definition: types.hpp:64