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.
statistics.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
15// all 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
32#include "timemory/math/stl.hpp"
33#include "timemory/tpls/cereal/cereal.hpp"
35
36#include <cmath>
37#include <cstdint>
38#include <fstream>
39#include <functional>
40#include <iomanip>
41#include <iostream>
42#include <limits>
43
44namespace tim
45{
46template <typename Tp>
47struct statistics;
48}
49
50namespace tim
51{
52namespace cereal
53{
54namespace detail
55{
56template <typename Tp>
58
59template <typename Tp>
61{
62 static constexpr uint32_t version = 0;
63};
64} // namespace detail
65} // namespace cereal
66namespace math
67{
68template <typename Tp, typename Up>
69struct compute;
70}
71} // namespace tim
72
73namespace tim
74{
75/// \struct tim::statistics
76/// \tparam Tp data type for statistical accumulation
77///
78/// \brief A generic class for statistical accumulation. It uses the timemory math
79/// overloads to enable statistics for containers such as `std::vector<double>`, etc.
80///
81template <typename Tp>
83{
84public:
85 using value_type = Tp;
88 template <typename Vp>
90
91public:
92 inline statistics() = default;
93 inline ~statistics() = default;
94 inline statistics(const statistics&) = default;
95 inline statistics(statistics&&) noexcept = default;
96 inline statistics& operator=(const statistics&) = default;
97 inline statistics& operator=(statistics&&) noexcept = default;
98
99 inline explicit statistics(const value_type& val)
100 : m_cnt(1)
101 , m_sum(val)
102 , m_sqr(compute_type::sqr(val))
103 , m_min(val)
104 , m_max(val)
105 {}
106
107 inline explicit statistics(value_type&& val)
108 : m_cnt(1)
109 , m_sum(std::move(val))
110 , m_sqr(compute_type::sqr(m_sum))
111 , m_min(m_sum)
112 , m_max(m_sum)
113 {}
114
116 {
117 m_cnt = 1;
118 m_sum = val;
119 m_min = val;
120 m_max = val;
121 m_sqr = compute_type::sqr(val);
122 return *this;
123 }
124
125public:
126 // Accumulated values
127 inline int64_t get_count() const { return m_cnt; }
128 inline const value_type& get_min() const { return m_min; }
129 inline const value_type& get_max() const { return m_max; }
130 inline const value_type& get_sum() const { return m_sum; }
131 inline const value_type& get_sqr() const { return m_sqr; }
132 inline value_type get_mean() const { return m_sum / m_cnt; }
134 {
135 if(m_cnt < 2)
136 {
137 auto ret = m_sum;
138 compute_type::minus(ret, m_sum);
139 return ret;
140 }
141
142 auto _sum = m_sum;
143 auto _sqr = m_sqr;
144
145 // lambda for equation clarity (will be inlined)
146 auto compute_variance = [&]() {
147 compute_type::multiply(_sum, m_sum);
148 _sum /= m_cnt;
149 compute_type::minus(_sqr, _sum);
150 _sqr /= (m_cnt - 1);
151 return _sqr;
152 };
153 return compute_variance();
154 }
155
156 inline value_type get_stddev() const
157 {
159 }
160
161 // Modifications
162 inline void reset()
163 {
164 m_cnt = 0;
165 m_sum = value_type{};
166 m_sqr = value_type{};
167 m_min = value_type{};
168 m_max = value_type{};
169 }
170
171public:
172 // Operators (value_type)
173 inline statistics& operator+=(const value_type& val)
174 {
175 if(m_cnt == 0)
176 {
177 m_sum = val;
178 m_sqr = compute_type::sqr(val);
179 m_min = val;
180 m_max = val;
181 }
182 else
183 {
184 compute_type::plus(m_sum, val);
186 m_min = compute_type::min(m_min, val);
187 m_max = compute_type::max(m_max, val);
188 }
189 ++m_cnt;
190
191 return *this;
192 }
193
194 inline statistics& operator-=(const value_type& val)
195 {
196 if(m_cnt > 1)
197 --m_cnt;
198 compute_type::minus(m_sum, val);
200 compute_type::minus(m_min, val);
201 compute_type::minus(m_max, val);
202 return *this;
203 }
204
205 inline statistics& operator*=(const value_type& val)
206 {
207 compute_type::multiply(m_sum, val);
209 compute_type::multiply(m_min, val);
210 compute_type::multiply(m_max, val);
211 return *this;
212 }
213
214 inline statistics& operator/=(const value_type& val)
215 {
216 compute_type::divide(m_sum, val);
218 compute_type::divide(m_min, val);
219 compute_type::divide(m_max, val);
220 return *this;
221 }
222
223public:
224 // Operators (this_type)
225 inline statistics& operator+=(const statistics& rhs)
226 {
227 if(m_cnt == 0)
228 {
229 m_sum = rhs.m_sum;
230 m_sqr = rhs.m_sqr;
231 m_min = rhs.m_min;
232 m_max = rhs.m_max;
233 }
234 else
235 {
236 compute_type::plus(m_sum, rhs.m_sum);
237 compute_type::plus(m_sqr, rhs.m_sqr);
238 m_min = compute_type::min(m_min, rhs.m_min);
239 m_max = compute_type::max(m_max, rhs.m_max);
240 }
241 m_cnt += rhs.m_cnt;
242 return *this;
243 }
244
245 // Operators (this_type)
246 inline statistics& operator-=(const statistics& rhs)
247 {
248 if(m_cnt > 0)
249 {
250 compute_type::minus(m_sum, rhs.m_sum);
251 compute_type::minus(m_sqr, rhs.m_sqr);
252 m_min = compute_type::min(m_min, rhs.m_min);
253 m_max = compute_type::max(m_max, rhs.m_max);
254 // m_cnt += std::abs(m_cnt - rhs.m_cnt);
255 }
256 return *this;
257 }
258
259private:
260 // summation of each history^1
261 int64_t m_cnt = 0;
262 value_type m_sum = value_type{};
263 value_type m_sqr = value_type{};
264 value_type m_min = value_type{};
265 value_type m_max = value_type{};
266
267public:
268 // friend operator for output
269 friend std::ostream& operator<<(std::ostream& os, const statistics& obj)
270 {
271 using namespace tim::stl::ostream;
272 auto _mean = (obj.get_count() > 0) ? obj.get_mean() : value_type{};
273 os << "[sum: " << obj.get_sum() << "] [mean: " << _mean
274 << "] [min: " << obj.get_min() << "] [max: " << obj.get_max()
275 << "] [var: " << obj.get_variance() << "] [stddev: " << obj.get_stddev()
276 << "] [count: " << obj.get_count() << "]";
277 return os;
278 }
279
280 // friend operator for addition
281 friend statistics operator+(const statistics& lhs, const statistics& rhs)
282 {
283 return statistics(lhs) += rhs;
284 }
285
286 friend statistics operator-(const statistics& lhs, const statistics& rhs)
287 {
288 return statistics(lhs) -= rhs;
289 }
290
291 template <typename Archive>
292 void save(Archive& ar, const unsigned int) const
293 {
294 auto _mean = (m_cnt > 0) ? get_mean() : value_type{};
295 ar(cereal::make_nvp("sum", m_sum), cereal::make_nvp("count", m_cnt),
296 cereal::make_nvp("min", m_min), cereal::make_nvp("max", m_max),
297 cereal::make_nvp("sqr", m_sqr), cereal::make_nvp("mean", _mean),
298 cereal::make_nvp("stddev", get_stddev()));
299 }
300
301 template <typename Archive>
302 void load(Archive& ar, const unsigned int)
303 {
304 ar(cereal::make_nvp("sum", m_sum), cereal::make_nvp("min", m_min),
305 cereal::make_nvp("max", m_max), cereal::make_nvp("sqr", m_sqr),
306 cereal::make_nvp("count", m_cnt));
307 }
308};
309
310//======================================================================================//
311
312} // namespace tim
313
314namespace std
315{
316//--------------------------------------------------------------------------------------//
317
318template <typename Tp>
320max(::tim::statistics<Tp> lhs, const Tp& rhs)
321{
322 return lhs.get_max(rhs);
323}
324
325//--------------------------------------------------------------------------------------//
326
327template <typename Tp>
329min(::tim::statistics<Tp> lhs, const Tp& rhs)
330{
331 return lhs.get_min(rhs);
332}
333
334//--------------------------------------------------------------------------------------//
335
336template <typename Tp>
338operator+=(::tim::statistics<tuple<>>& _lhs, const Tp&)
339{
340 return _lhs;
341}
342
343//--------------------------------------------------------------------------------------//
344} // namespace std
STL namespace.
::tim::statistics< Tp > max(::tim::statistics< Tp > lhs, const Tp &rhs)
Definition: statistics.hpp:320
::tim::statistics< Tp > min(::tim::statistics< Tp > lhs, const Tp &rhs)
Definition: statistics.hpp:329
::tim::statistics< tuple<> > & operator+=(::tim::statistics< tuple<> > &_lhs, const Tp &)
Definition: statistics.hpp:338
type_list sqr(type_list<>)
Definition: fwd.hpp:405
the namespace provides overloads to output complex data types w/ streams
Definition: kokkosp.cpp:39
const std::string std::ostream * os
Struct for performing math operations on complex data structures without using globally overload oper...
Definition: compute.hpp:53
static decltype(auto) sqr(const type &_v)
Definition: compute.hpp:63
static decltype(auto) abs(const type &_v)
Definition: compute.hpp:58
static decltype(auto) sqrt(const type &_v)
Definition: compute.hpp:68
static decltype(auto) max(const type &_l, const V &_r)
Definition: compute.hpp:80
static decltype(auto) min(const type &_l, const V &_r)
Definition: compute.hpp:74
static decltype(auto) minus(type &_l, const V &_r)
Definition: compute.hpp:99
static decltype(auto) plus(type &_l, const V &_r)
Definition: compute.hpp:93
static decltype(auto) multiply(type &_l, const V &_r)
Definition: compute.hpp:105
static decltype(auto) divide(type &_l, const V &_r)
Definition: compute.hpp:111
A generic class for statistical accumulation. It uses the timemory math overloads to enable statistic...
Definition: statistics.hpp:83
statistics(const statistics &)=default
const value_type & get_sqr() const
Definition: statistics.hpp:131
statistics & operator-=(const value_type &val)
Definition: statistics.hpp:194
const value_type & get_sum() const
Definition: statistics.hpp:130
friend std::ostream & operator<<(std::ostream &os, const statistics &obj)
Definition: statistics.hpp:269
statistics(statistics &&) noexcept=default
~statistics()=default
void load(Archive &ar, const unsigned int)
Definition: statistics.hpp:302
statistics & operator-=(const statistics &rhs)
Definition: statistics.hpp:246
statistics()=default
statistics(value_type &&val)
Definition: statistics.hpp:107
statistics & operator+=(const statistics &rhs)
Definition: statistics.hpp:225
void save(Archive &ar, const unsigned int) const
Definition: statistics.hpp:292
value_type get_variance() const
Definition: statistics.hpp:133
statistics & operator/=(const value_type &val)
Definition: statistics.hpp:214
friend statistics operator+(const statistics &lhs, const statistics &rhs)
Definition: statistics.hpp:281
const value_type & get_max() const
Definition: statistics.hpp:129
const value_type & get_min() const
Definition: statistics.hpp:128
statistics & operator=(const value_type &val)
Definition: statistics.hpp:115
statistics & operator+=(const value_type &val)
Definition: statistics.hpp:173
int64_t get_count() const
Definition: statistics.hpp:127
statistics & operator*=(const value_type &val)
Definition: statistics.hpp:205
value_type get_mean() const
Definition: statistics.hpp:132
friend statistics operator-(const statistics &lhs, const statistics &rhs)
Definition: statistics.hpp:286
value_type get_stddev() const
Definition: statistics.hpp:156