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.
papi_rate_tuple.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#pragma once
26
28#include "timemory/components/papi/backends.hpp"
35#include "timemory/units.hpp"
36
37#include <array>
38#include <functional>
39#include <memory>
40#include <sstream>
41#include <string>
42#include <vector>
43
44namespace tim
45{
46namespace component
47{
48/// \struct tim::component::papi_rate_tuple
49/// \tparam RateT Component whose value will be the divisor for all the hardware counters
50/// \tparam EventTypes Compile-time constant list of PAPI event identifiers
51///
52/// \brief This component pairs a \ref tim::component::papi_tuple with a component which
53/// will provide an interval over which the hardware counters will be reported, e.g. if
54/// `RateT` is \ref tim::component::wall_clock, the reported values will be the
55/// hardware-counters w.r.t. the wall-clock time. If `RateT` is \ref
56/// tim::component::cpu_clock, the reported values will be the hardware counters w.r.t.
57/// the cpu time.
58///
59/// \code{.cpp}
60/// // the "Instructions" alias below explicitly collects the total instructions per
61/// second,
62/// // the number of load instructions per second, the number of store instructions per
63/// second using Instructions = papi_rate_tuple<wall_clock, PAPI_TOT_INS, PAPI_LD_INS,
64/// PAPI_SR_INS>;
65///
66/// Instructions inst{};
67/// inst.start();
68/// ...
69/// inst.stop();
70/// std::vector<double> data = inst.get();
71///
72/// \endcode
73template <typename RateT, int... EventTypes>
75: public base<papi_rate_tuple<RateT, EventTypes...>,
76 std::pair<papi_tuple<EventTypes...>, RateT>>
77, private papi_common
78{
80 "Error! rate_type must be a component");
81
82 using size_type = std::size_t;
83 static const size_type num_events = sizeof...(EventTypes);
84
85 using tuple_type = papi_tuple<EventTypes...>;
87 using value_type = std::pair<tuple_type, rate_type>;
88 using this_type = papi_rate_tuple<RateT, EventTypes...>;
92
93 template <typename Tp>
94 using array_t = std::array<Tp, num_events>;
95
96 friend struct operation::record<common_type>;
97 friend struct operation::start<this_type>;
98 friend struct operation::stop<this_type>;
99 friend struct operation::set_started<this_type>;
100 friend struct operation::set_stopped<this_type>;
101
102public:
103 static void configure() { tuple_type::configure(); }
105 static void finalize() { tuple_type::finalize(); }
106
107 static void global_init()
108 {
113 }
114 static void global_finalize()
115 {
116 /*operation::fini<tuple_type>{}(
117 operation::mode_constant<operation::fini_mode::global>{});
118 operation::fini<rate_type>{}(
119 operation::mode_constant<operation::fini_mode::global>{});*/
120 }
121
122 static void thread_init()
123 {
128 }
129 static void thread_finalize()
130 {
131 /*operation::fini<tuple_type>{}(
132 operation::mode_constant<operation::fini_mode::thread>{});
133 operation::fini<rate_type>{}(
134 operation::mode_constant<operation::fini_mode::thread>{});*/
135 }
136
138 {
139 return tuple_type::label() + "_" + properties<rate_type>::id() + "_rate";
140 }
142 {
143 return std::string(
144 "Reports the rate of the given set of HW counters w.r.t. the ") +
145 rate_type::label() + " component";
146 }
147
148public:
149 TIMEMORY_DEFAULT_OBJECT(papi_rate_tuple)
150
151 using base_type::load;
152
153 void start()
154 {
155 value.first.start();
156 value.second.start();
157 }
158
159 void stop()
160 {
161 value.second.stop();
162 value.first.stop();
163 }
164
166 {
167 value.first += rhs.value.first;
168 value.second += rhs.value.second;
169 return *this;
170 }
171
173 {
174 value.first -= rhs.value.first;
175 value.second -= rhs.value.second;
176 return *this;
177 }
178
179 template <typename Tp = double>
180 auto get() const
181 {
182 auto _val = value.first.template get<Tp>();
183 for(auto& itr : _val)
184 itr /= value.second.get();
185 return _val;
186 }
187
188 static auto label_array()
189 {
190 auto arr = tuple_type::label_array();
191 for(auto& itr : arr)
192 itr += " per " + rate_type::get_display_unit();
193 return arr;
194 }
195
196 static auto description_array()
197 {
199 for(auto& itr : arr)
200 itr += " Rate";
201 return arr;
202 }
203
204 static auto display_unit_array()
205 {
206 auto arr = tuple_type::label_array();
207 for(auto& itr : arr)
208 {
209 if(itr.empty())
210 itr = "1";
211 itr += "/" + rate_type::display_unit();
212 }
213 return arr;
214 }
215
216 static auto unit_array()
217 {
218 std::array<double, num_events> arr;
219 auto _units = tuple_type::unit_array();
220 for(size_t i = 0; i < _units.size(); ++i)
221 arr.at(i) = _units.at(i);
222 for(auto& itr : _units)
223 itr /= rate_type::unit();
224 return arr;
225 }
226
227 friend std::ostream& operator<<(std::ostream& os, const this_type& obj)
228 {
229 // output the metrics
230 auto _value = obj.get();
231 auto _label = this_type::label_array();
232 auto _disp = this_type::display_unit_array();
233 auto _prec = this_type::get_precision();
234 auto _width = this_type::get_width();
235 auto _flags = this_type::get_format_flags();
236
237 for(size_t i = 0; i < _value.size(); ++i)
238 {
239 std::stringstream ss_value;
240 std::stringstream ss_extra;
241 ss_value.setf(_flags);
242 ss_value << std::setw(_width) << std::setprecision(_prec) << _value.at(i);
243 if(!_disp.at(i).empty())
244 {
245 ss_extra << " " << _disp.at(i);
246 }
247 else if(!_label.at(i).empty())
248 {
249 ss_extra << " " << _label.at(i);
250 }
251 os << ss_value.str() << ss_extra.str();
252 if(i + 1 < _value.size())
253 os << ", ";
254 }
255 return os;
256 }
257
258protected:
259 using base_type::accum;
260 using base_type::laps;
263 using base_type::value;
264
265 friend struct base<this_type, value_type>;
266 friend class impl::storage<this_type,
267 trait::uses_value_storage<this_type, value_type>::value>;
268};
269} // namespace component
270} // namespace tim
Declare the papi component types.
int EventTypes RateT
Definition: types.hpp:46
Definition for global and thread-local finalization functions for a component.
Definition for global and thread-local initialzation functions for a component.
std::integral_constant< int, ModeV > mode_constant
Definition: types.hpp:240
Definition: kokkosp.cpp:39
tim::mpl::apply< std::string > string
Definition: macros.hpp:53
const std::string std::ostream * os
decltype(auto) load()
void set_stopped()
store that stop has been called
storage< Tp, Value > storage_type
void set_started()
store that start has been called
A very lightweight storage class which provides nothing.
Definition: declaration.hpp:51
std::array< Tp, N > array_t
Definition: papi_common.hpp:60
vector_t< long long > value_type
Definition: papi_common.hpp:64
This component pairs a tim::component::papi_tuple with a component which will provide an interval ove...
papi_tuple< EventTypes... > tuple_type
friend std::ostream & operator<<(std::ostream &os, const this_type &obj)
std::pair< tuple_type, rate_type > value_type
this_type & operator+=(const this_type &rhs)
this_type & operator-=(const this_type &rhs)
static const size_type num_events
papi_rate_tuple< RateT, EventTypes... > this_type
This component is useful for bundling together a fixed set of hardware counter identifiers which requ...
Definition: papi_tuple.hpp:69
static std::string label()
Definition: papi_tuple.hpp:225
static array_t< std::string > description_array()
Definition: papi_tuple.hpp:323
static array_t< std::string > label_array()
Definition: papi_tuple.hpp:312
static array_t< int64_t > unit_array()
Definition: papi_tuple.hpp:345
static constexpr const char * id()
Definition: properties.hpp:221
concept that specifies that a type is a component. Components are used to perform some measurement,...
Definition: concepts.hpp:226
This operation class is used for invoking the static initializer and thread-local initializer of a co...
Definition: init.hpp:51
This operation attempts to call a member function which the component provides to internally store wh...
Definition: types.hpp:469
This operation attempts to call a member function which the component provides to internally store wh...
Definition: types.hpp:502