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.
auto_list.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
26#pragma once
27
30
31#include <cstddef>
32#include <tuple>
33#include <type_traits>
34#include <utility>
35
36namespace tim
37{
38//--------------------------------------------------------------------------------------//
39/// \class tim::auto_list
40/// \tparam Types Specification of the component types to bundle together
41///
42/// \brief This is a variadic component wrapper where all components are optional
43/// at runtime. Accept unlimited number of parameters. The constructor starts the
44/// components, the destructor stops the components. The default behavior is
45/// to query the TIMEMORY_AUTO_LIST_INIT environment variable once (the first
46/// time the bundle is used) and use that list of components (if any) to
47/// initialize the components which are part of it's template parameters.
48/// This behavior can be modified by assigning a new lambda/functor to the
49/// reference which is returned from \ref tim::auto_list<Types...>::get_initializer().
50/// Assignment is not thread-safe since this is relatively unnecessary... if a different
51/// set of components are required on a particular thread, just create a different
52/// type with those particular components or pass the initialization functor to the
53/// constructor.
54///
55/// \code{.cpp}
56/// using bundle_t = tim::auto_list<wall_clock, cpu_clock, peak_rss>;
57///
58/// void foo()
59/// {
60/// setenv("TIMEMORY_AUTO_LIST_COMPONENTS", "wall_clock", 0);
61///
62/// auto bar = bundle_t("bar");
63///
64/// bundle_t::get_initializer() = [](bundle_t& b)
65/// {
66/// b.initialize<cpu_clock, peak_rss>();
67/// };
68///
69/// auto qix = bundle_t("qix");
70///
71/// auto local_init = [](bundle_t& b)
72/// {
73/// b.initialize<thread_cpu_clock, peak_rss>();
74/// };
75///
76/// auto spam = bundle_t("spam", ..., local_init);
77///
78/// }
79/// \endcode
80///
81/// The above code will record wall-clock timer on first use of "bar", and
82/// will record cpu-clock, peak-rss at "qix", and peak-rss at "spam". If foo()
83/// is called a second time, "bar" will record cpu-clock and peak-rss. "spam" will
84/// always use the local initialized. If none of these initializers are set, wall-clock
85/// will be recorded for all of them. The intermediate storage will happen on the heap and
86/// when the destructor is called, it will add itself to the call-graph
87template <typename... Types>
89: public auto_base_bundle<TIMEMORY_API, component_list<>, auto_list<Types...>>
91{
92 using poly_base =
94
95public:
96 using this_type = auto_list<Types...>;
97 using base_type = component_list<Types...>;
101
102 template <typename... Args>
103 explicit auto_list(Args&&... args);
104
105 // copy and move
106 ~auto_list() = default;
107 auto_list(const auto_list&) = default;
108 auto_list(auto_list&&) = default;
109 auto_list& operator=(const auto_list&) = default;
111
112 static constexpr std::size_t size() { return poly_base::size(); }
113
114public:
115 this_type& print(std::ostream& os, bool _endl = false) const;
116 friend std::ostream& operator<<(std::ostream& os, const this_type& obj)
117 {
118 obj.print(os, false);
119 return os;
120 }
121};
122//
123template <typename... Types>
124template <typename... Args>
126: poly_base{ std::forward<Args>(args)... }
127{}
128//
129template <typename... Types>
130auto_list<Types...>&
131auto_list<Types...>::print(std::ostream& os, bool _endl) const
132{
133 os << poly_base::m_temporary;
134 if(_endl)
135 os << '\n';
136 return const_cast<this_type&>(*this);
137}
138//
139//======================================================================================//
140//
141template <typename... Types>
142auto
144{
145 return get(_obj.get_component());
146}
147//
148template <typename... Types>
149auto
151{
152 return get_labeled(_obj.get_component());
153}
154//
155} // namespace tim
156
157//--------------------------------------------------------------------------------------//
158// variadic versions
159//
160#if !defined(TIMEMORY_VARIADIC_BLANK_AUTO_LIST)
161# define TIMEMORY_VARIADIC_BLANK_AUTO_LIST(tag, ...) \
162 using _TIM_TYPEDEF(__LINE__) = ::tim::auto_list<__VA_ARGS__>; \
163 TIMEMORY_BLANK_MARKER(_TIM_TYPEDEF(__LINE__), tag);
164#endif
165
166#if !defined(TIMEMORY_VARIADIC_BASIC_AUTO_LIST)
167# define TIMEMORY_VARIADIC_BASIC_AUTO_LIST(tag, ...) \
168 using _TIM_TYPEDEF(__LINE__) = ::tim::auto_list<__VA_ARGS__>; \
169 TIMEMORY_BASIC_MARKER(_TIM_TYPEDEF(__LINE__), tag);
170#endif
171
172#if !defined(TIMEMORY_VARIADIC_AUTO_LIST)
173# define TIMEMORY_VARIADIC_AUTO_LIST(tag, ...) \
174 using _TIM_TYPEDEF(__LINE__) = ::tim::auto_list<__VA_ARGS__>; \
175 TIMEMORY_MARKER(_TIM_TYPEDEF(__LINE__), tag);
176#endif
177
178//======================================================================================//
179//
180// std::get operator
181//
182namespace std
183{
184//--------------------------------------------------------------------------------------//
185
186template <std::size_t N, typename... Types>
187auto
188get(tim::auto_list<Types...>& obj) -> decltype(get<N>(obj.data()))
189{
190 return get<N>(obj.data());
191}
192
193//--------------------------------------------------------------------------------------//
194
195template <std::size_t N, typename... Types>
196auto
197get(const tim::auto_list<Types...>& obj) -> decltype(get<N>(obj.data()))
198{
199 return get<N>(obj.data());
200}
201
202//--------------------------------------------------------------------------------------//
203
204template <std::size_t N, typename... Types>
205auto
207 -> decltype(get<N>(std::forward<tim::auto_list<Types...>>(obj).data()))
208{
209 using obj_type = tim::auto_list<Types...>;
210 return get<N>(std::forward<obj_type>(obj).data());
211}
212
213//======================================================================================//
214
215} // namespace std
216
217//======================================================================================//
This is a variadic component wrapper where all components are optional at runtime....
Definition: auto_list.hpp:91
typename base_type::component_type component_type
Definition: auto_list.hpp:99
auto_list(const auto_list &)=default
auto_list< Types... > this_type
Definition: auto_list.hpp:96
auto_list & operator=(const auto_list &)=default
convert_t< typename component_type::type, auto_list<> > type
Definition: auto_list.hpp:100
friend std::ostream & operator<<(std::ostream &os, const this_type &obj)
Definition: auto_list.hpp:116
static constexpr std::size_t size()
Definition: auto_list.hpp:112
auto_list(Args &&... args)
Definition: auto_list.hpp:125
auto_list(auto_list &&)=default
auto_list & operator=(auto_list &&)=default
this_type & print(std::ostream &os, bool _endl=false) const
Definition: auto_list.hpp:131
~auto_list()=default
This is a variadic component wrapper where all components are optional at runtime....
component_list< Types... > component_type
STL namespace.
std::tuple_element< N, std::tuple< Types... > >::type & get(tim::auto_bundle< Tag, Types... > &obj)
Definition: kokkosp.cpp:39
auto get_labeled(const auto_bundle< Tag, Types... > &_obj)
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
Static polymorphic base class for automatic start/stop bundlers.
Definition: types.hpp:72