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_bundle.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_bundle
40/// \tparam Tag unique identifying type for the bundle which when \ref
41/// tim::trait::is_available<Tag> is false at compile-time or \ref
42/// tim::trait::runtime_enabled<Tag>() is false at runtime, then none of the components
43/// will be collected
44/// \tparam Types Specification of the component types to bundle together
45///
46/// \brief This is a variadic component wrapper which combines the features of \ref
47/// tim::auto_tuple<T...> and \ref tim::auto_list<U..>. The "T" types (compile-time fixed,
48/// allocated on stack) should be specified as usual, the "U" types (runtime-time
49/// optional, allocated on the heap) should be specified as a pointer. Initialization
50/// of the optional types is similar to \ref tim::auto_list<U...> but no environment
51/// variable is built-in since, ideally, this environment variable should be customized
52/// based on the \ref Tag template parameter.
53///
54/// \code{.cpp}
55///
56/// // dummy type identifying the context
57/// struct FooApi {};
58///
59/// using bundle_t = tim::auto_bundle<FooApi, wall_clock, cpu_clock*>;
60///
61/// void foo_init() // user initialization routine
62/// {
63/// bundle_t::get_initializer() = [](bundle_t& b)
64/// {
65/// static auto env_enum = tim::enumerate_components(
66/// tim::delimit(tim::get_env<string_t>("FOO_COMPONENTS", "wall_clock")));
67///
68/// :im::initialize(b, env_enum);
69/// };
70/// }
71/// void bar()
72/// {
73/// // will record whichever components are specified by "FOO_COMPONENT" in
74/// // environment, which "wall_clock" as the default
75///
76/// auto bar = bundle_t("foo");
77/// // ...
78/// }
79///
80/// int main(int argc, char** argv)
81/// {
82/// tim::timemory_init(argc, argv);
83///
84/// foo_init();
85///
86/// bar();
87///
88/// tim::timemory_finalize();
89/// }
90/// \endcode
91///
92/// The above code will record wall-clock, cpu-clock, and peak-rss. The intermediate
93/// storage will happen on the stack and when the destructor is called, it will add itself
94/// to the call-graph
95///
96template <typename Tag, typename... Types>
97class auto_bundle<Tag, Types...>
98: public auto_base_bundle<Tag, component_bundle<Tag>, auto_bundle<Tag, Types...>>
100{
101 using poly_base =
103
104public:
105 using this_type = auto_bundle<Tag, Types...>;
106 using base_type = component_bundle<Tag, Types...>;
110
111 template <typename... Args>
112 explicit auto_bundle(Args&&... args);
113
114 // copy and move
115 ~auto_bundle() = default;
116 auto_bundle(const auto_bundle&) = default;
120
121 static constexpr std::size_t size() { return poly_base::size(); }
122
123public:
124 this_type& print(std::ostream& os, bool _endl = false) const;
125 friend std::ostream& operator<<(std::ostream& os, const this_type& obj)
126 {
127 obj.print(os, false);
128 return os;
129 }
130};
131//
132template <typename Tag, typename... Types>
133template <typename... Args>
135: poly_base{ std::forward<Args>(args)... }
136{}
137//
138template <typename Tag, typename... Types>
139auto_bundle<Tag, Types...>&
140auto_bundle<Tag, Types...>::print(std::ostream& os, bool _endl) const
141{
142 os << poly_base::m_temporary;
143 if(_endl)
144 os << '\n';
145 return const_cast<this_type&>(*this);
146}
147//
148//======================================================================================//
149//
150template <typename Tag, typename... Types>
151auto
153{
154 return get(_obj.get_component());
155}
156
157//--------------------------------------------------------------------------------------//
158
159template <typename Tag, typename... Types>
160auto
162{
163 return get_labeled(_obj.get_component());
164}
165//
166} // namespace tim
167
168//======================================================================================//
169//
170// variadic versions
171//
172#if !defined(TIMEMORY_VARIADIC_BLANK_AUTO_BUNDLE)
173# define TIMEMORY_VARIADIC_BLANK_AUTO_BUNDLE(tag, ...) \
174 using _TIM_TYPEDEF(__LINE__) = ::tim::auto_bundle<__VA_ARGS__>; \
175 TIMEMORY_BLANK_MARKER(_TIM_TYPEDEF(__LINE__), tag);
176#endif
177
178#if !defined(TIMEMORY_VARIADIC_BASIC_AUTO_BUNDLE)
179# define TIMEMORY_VARIADIC_BASIC_AUTO_BUNDLE(tag, ...) \
180 using _TIM_TYPEDEF(__LINE__) = ::tim::auto_bundle<__VA_ARGS__>; \
181 TIMEMORY_BASIC_MARKER(_TIM_TYPEDEF(__LINE__), tag);
182#endif
183
184#if !defined(TIMEMORY_VARIADIC_AUTO_BUNDLE)
185# define TIMEMORY_VARIADIC_AUTO_BUNDLE(tag, ...) \
186 using _TIM_TYPEDEF(__LINE__) = ::tim::auto_bundle<__VA_ARGS__>; \
187 TIMEMORY_MARKER(_TIM_TYPEDEF(__LINE__), tag);
188#endif
189
190//======================================================================================//
191//
192// std::get operator
193//
194//======================================================================================//
195//
196namespace std
197{
198//
199//--------------------------------------------------------------------------------------//
200//
201template <std::size_t N, typename Tag, typename... Types>
202typename std::tuple_element<N, std::tuple<Types...>>::type&
204{
205 return get<N>(obj.data());
206}
207//
208//--------------------------------------------------------------------------------------//
209//
210template <std::size_t N, typename Tag, typename... Types>
211const typename std::tuple_element<N, std::tuple<Types...>>::type&
213{
214 return get<N>(obj.data());
215}
216//
217//--------------------------------------------------------------------------------------//
218//
219template <std::size_t N, typename Tag, typename... Types>
220auto
222 -> decltype(get<N>(std::forward<tim::auto_bundle<Tag, Types...>>(obj).data()))
223{
224 using obj_type = tim::auto_bundle<Tag, Types...>;
225 return get<N>(std::forward<obj_type>(obj).data());
226}
227//
228//--------------------------------------------------------------------------------------//
229//
230} // namespace std
auto_bundle & operator=(const auto_bundle &)=default
friend std::ostream & operator<<(std::ostream &os, const this_type &obj)
typename base_type::component_type component_type
convert_t< typename component_type::type, auto_bundle< Tag > > type
this_type & print(std::ostream &os, bool _endl=false) const
auto_bundle(const auto_bundle &)=default
static constexpr std::size_t size()
auto_bundle(auto_bundle &&)=default
auto_bundle & operator=(auto_bundle &&)=default
STL namespace.
std::tuple_element< N, std::tuple< Types... > >::type & get(tim::auto_bundle< Tag, Types... > &obj)
void print(std::ostream &os, Args &&... args)
Definition: functional.cpp:159
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
This is a variadic component wrapper which combines the features of tim::component_tuple<T....
Definition: types.hpp:63
This is a variadic component wrapper which combines the features of tim::auto_tuple<T....
Definition: types.hpp:75