]> git.proxmox.com Git - ceph.git/blob - ceph/src/boost/libs/math/reporting/performance/performance.hpp
add subtree-ish sources for 12.0.3
[ceph.git] / ceph / src / boost / libs / math / reporting / performance / performance.hpp
1 // Copyright John Maddock 2015.
2 // Use, modification and distribution are subject to the
3 // Boost Software License, Version 1.0. (See accompanying file
4 // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
5
6 #ifndef PERFORMANCE_HPP
7 #define PERFORMANCE_HPP
8
9 #include <boost/math/special_functions/relative_difference.hpp>
10 #include <boost/array.hpp>
11 #include <boost/chrono.hpp>
12 #include <boost/regex.hpp>
13
14 template <class Array>
15 void add_data(const Array& a)
16 {
17 //
18 // This function is called multiple times to merge multiple data sets into one big table:
19 //
20 for(typename Array::const_iterator i = a.begin(); i != a.end(); ++i)
21 {
22 data.push_back(std::vector<double>());
23 for(typename Array::value_type::const_iterator j = i->begin(); j != i->end(); ++j)
24 {
25 data.back().push_back(*j);
26 }
27 }
28 }
29
30 template <class Func, class Result>
31 void screen_data(Func f, Result r)
32 {
33 //
34 // If any of the implementations being tested produces garbage for one of our
35 // test cases (or else if we test a domain they don't support), then we remove that
36 // row from the table. This allows us to only test a common supported sub-set for performance:
37 //
38 for(std::vector<std::vector<double> >::size_type row = 0; row < data.size(); ++row)
39 {
40 try
41 {
42 double computed = f(data[row]);
43 double expected = r(data[row]);
44 double err = boost::math::relative_difference(computed, expected);
45 if(err > 1e-7)
46 {
47 std::cout << "Erasing row: ";
48 for(unsigned i = 0; i < data[row].size(); ++i)
49 {
50 std::cout << data[row][i] << " ";
51 }
52 std::cout << "Error was " << err << std::endl;
53 data.erase(data.begin() + row);
54 --row;
55 }
56 }
57 catch(const std::exception& e)
58 {
59 std::cout << "Erasing row: ";
60 for(unsigned i = 0; i < data[row].size(); ++i)
61 {
62 std::cout << data[row][i] << " ";
63 }
64 std::cout << "due to thrown exception: " << e.what() << std::endl;
65 data.erase(data.begin() + row);
66 --row;
67 }
68 }
69 }
70
71 template <class Clock>
72 struct stopwatch
73 {
74 typedef typename Clock::duration duration;
75 stopwatch()
76 {
77 m_start = Clock::now();
78 }
79 duration elapsed()
80 {
81 return Clock::now() - m_start;
82 }
83 void reset()
84 {
85 m_start = Clock::now();
86 }
87
88 private:
89 typename Clock::time_point m_start;
90 };
91
92 double sum = 0;
93
94 template <class Func>
95 double exec_timed_test(Func f)
96 {
97 double t = 0;
98 unsigned repeats = 1;
99 do{
100 stopwatch<boost::chrono::high_resolution_clock> w;
101
102 for(unsigned count = 0; count < repeats; ++count)
103 {
104 for(std::vector<std::vector<double> >::const_iterator i = data.begin(); i != data.end(); ++i)
105 sum += f(*i);
106 }
107
108 t = boost::chrono::duration_cast<boost::chrono::duration<double>>(w.elapsed()).count();
109 if(t < 0.5)
110 repeats *= 2;
111 } while(t < 0.5);
112 return t / (repeats * data.size());
113 }
114
115 #endif // PERFORMANCE_HPP