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.
component_list.hpp
Go to the documentation of this file.
1 
2 // MIT License
3 //
4 // Copyright (c) 2020, The Regents of the University of California,
5 // through Lawrence Berkeley National Laboratory (subject to receipt of any
6 // required approvals from the U.S. Dept. of Energy). All rights reserved.
7 //
8 // Permission is hereby granted, free of charge, to any person obtaining a copy
9 // of this software and associated documentation files (the "Software"), to deal
10 // in the Software without restriction, including without limitation the rights
11 // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
12 // copies of the Software, and to permit persons to whom the Software is
13 // furnished to do so, subject to the following conditions:
14 //
15 // The above copyright notice and this permission notice shall be included in
16 // all copies or substantial portions of the Software.
17 //
18 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
21 // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
23 // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
24 // SOFTWARE.
25 //
26 
27 #pragma once
28 
29 #include "timemory/backends/dmp.hpp"
31 #include "timemory/mpl/apply.hpp"
32 #include "timemory/mpl/filters.hpp"
39 
40 #include <cstdint>
41 #include <cstdio>
42 #include <string>
43 
44 namespace tim
45 {
46 /// \class tim::component_list
47 /// \tparam Types Specification of the component types to bundle together
48 ///
49 /// \brief This is a variadic component wrapper where all components are optional
50 /// at runtime. Accept unlimited number of parameters. The default behavior is
51 /// to query the TIMEMORY_COMPONENT_LIST_INIT environment variable once (the first
52 /// time the bundle is used) and use that list of components (if any) to
53 /// initialize the components which are part of it's template parameters.
54 /// This behavior can be modified by assigning a new lambda/functor to the
55 /// reference which is returned from \ref
56 /// tim::component_list<Types...>::get_initializer(). Assignment is not thread-safe since
57 /// this is relatively unnecessary... if a different set of components are required on a
58 /// particular thread, just create a different type with those particular components or
59 /// pass the initialization functor to the constructor.
60 ///
61 /// \code{.cpp}
62 /// using bundle_t = tim::component_list<wall_clock, cpu_clock, peak_rss>;
63 ///
64 /// void foo()
65 /// {
66 /// setenv("TIMEMORY_COMPONENT_LIST_INIT", "wall_clock", 0);
67 ///
68 /// auto bar = bundle_t("bar");
69 ///
70 /// bundle_t::get_initializer() = [](bundle_t& b)
71 /// {
72 /// b.initialize<cpu_clock, peak_rss>();
73 /// };
74 ///
75 /// auto qix = bundle_t("qix");
76 ///
77 /// auto local_init = [](bundle_t& b)
78 /// {
79 /// b.initialize<thread_cpu_clock, peak_rss>();
80 /// };
81 ///
82 /// auto spam = bundle_t("spam", ..., local_init);
83 ///
84 /// }
85 /// \endcode
86 ///
87 /// The above code will record wall-clock timer on first use of "bar", and
88 /// will record cpu-clock, peak-rss at "qix", and peak-rss at "spam". If foo()
89 /// is called a second time, "bar" will record cpu-clock and peak-rss. "spam" will
90 /// always use the local initialized. If none of these initializers are set, wall-clock
91 /// will be recorded for all of them. The intermediate storage will happen on the heap and
92 /// when the destructor is called, it will add itself to the call-graph
93 template <typename... Types>
95 : public bundle<TIMEMORY_API, component_list<>,
96  tim::variadic::heap_wrapper_types<concat<Types...>>>
98 {
99 public:
101 
104  using this_type = component_list<Types...>;
105  using component_type = component_list<Types...>;
106  using auto_type = auto_list<Types...>;
107 
108 public:
109  template <typename... Args>
110  component_list(Args&&...);
111 
112  ~component_list() = default;
113  component_list(const component_list&) = default;
114  component_list(component_list&&) noexcept = default;
115 
116  component_list& operator=(const component_list& rhs) = default;
117  component_list& operator=(component_list&&) noexcept = default;
118 };
119 
120 template <typename... Types>
121 template <typename... Args>
122 component_list<Types...>::component_list(Args&&... args)
123 : bundle_type{ std::forward<Args>(args)... }
124 {}
125 
126 //--------------------------------------------------------------------------------------//
127 
128 template <typename... Types>
129 auto
131  -> decltype(std::declval<component_list<Types...>>().get())
132 {
133  return _obj.get();
134 }
135 
136 //--------------------------------------------------------------------------------------//
137 
138 template <typename... Types>
139 auto
141  -> decltype(std::declval<component_list<Types...>>().get_labeled())
142 {
143  return _obj.get_labeled();
144 }
145 
146 //--------------------------------------------------------------------------------------//
147 
148 } // namespace tim
149 
150 //======================================================================================//
151 //
152 // std::get operator
153 //
154 namespace std
155 {
156 //--------------------------------------------------------------------------------------//
157 
158 template <std::size_t N, typename... Types>
159 typename std::tuple_element<N, std::tuple<Types...>>::type&
161 {
162  return get<N>(obj.data());
163 }
164 
165 //--------------------------------------------------------------------------------------//
166 
167 template <std::size_t N, typename... Types>
168 const typename std::tuple_element<N, std::tuple<Types...>>::type&
170 {
171  return get<N>(obj.data());
172 }
173 
174 //--------------------------------------------------------------------------------------//
175 
176 template <std::size_t N, typename... Types>
177 auto
179  -> decltype(get<N>(std::forward<tim::component_list<Types...>>(obj).data()))
180 {
181  using obj_type = tim::component_list<Types...>;
182  return get<N>(std::forward<obj_type>(obj).data());
183 }
184 
185 //======================================================================================//
186 } // namespace std
This is a variadic component wrapper where all components are optional at runtime....
Definition: auto_list.hpp:91
This is a variadic component wrapper where all components are optional at runtime....
component_list(component_list &&) noexcept=default
~component_list()=default
component_list(const component_list &)=default
component_list(Args &&...)
Definition: kokkosp.cpp:38
typename impl::concat< Types... >::type concat
Definition: types.hpp:707
auto get_labeled(const auto_bundle< Tag, Types... > &_obj)
auto get(const auto_bundle< Tag, Types... > &_obj)
Static polymorphic base class for component bundlers.
Definition: bundle.hpp:51
Declare the operations types.
The declaration for the types for settings without definitions.
typename typename typename
Definition: types.hpp:226