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.
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"
39
40#include <cstdint>
41#include <cstdio>
42#include <string>
43
44namespace 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
93template <typename... Types>
95: public bundle<TIMEMORY_API, component_list<>,
96 tim::variadic::heap_wrapper_types<concat<Types...>>>
98{
99public:
101
104 using this_type = component_list<Types...>;
106 using auto_type = auto_list<Types...>;
107
108public:
109 template <typename... Args>
110 component_list(Args&&...);
111
112 ~component_list() = default;
115
118};
119
120template <typename... Types>
121template <typename... Args>
123: bundle_type{ std::forward<Args>(args)... }
124{}
125
126//--------------------------------------------------------------------------------------//
127
128template <typename... Types>
129auto
131 -> decltype(std::declval<component_list<Types...>>().get())
132{
133 return _obj.get();
134}
135
136//--------------------------------------------------------------------------------------//
137
138template <typename... Types>
139auto
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//
154namespace std
155{
156//--------------------------------------------------------------------------------------//
157
158template <std::size_t N, typename... Types>
159typename std::tuple_element<N, std::tuple<Types...>>::type&
161{
162 return get<N>(obj.data());
163}
164
165//--------------------------------------------------------------------------------------//
166
167template <std::size_t N, typename... Types>
168const typename std::tuple_element<N, std::tuple<Types...>>::type&
170{
171 return get<N>(obj.data());
172}
173
174//--------------------------------------------------------------------------------------//
175
176template <std::size_t N, typename... Types>
177auto
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()=default
component_list(const component_list &)=default
component_list & operator=(component_list &&)=default
component_list(component_list &&)=default
component_list & operator=(const component_list &rhs)=default
component_list(Args &&...)
STL namespace.
std::tuple_element< N, std::tuple< Types... > >::type & get(tim::auto_bundle< Tag, Types... > &obj)
Definition: kokkosp.cpp:39
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.