GCC Code Coverage Report


Directory: ./
File: benchmarks/bench.h
Date: 2023-04-27 00:55:30
Exec Total Coverage
Lines: 0 48 0.0%
Functions: 0 19 0.0%
Branches: 0 50 0.0%

Line Branch Exec Source
1 #pragma once
2
3 #include "dtypes.h"
4 #include "utilities/stopwatch.h"
5
6 #include <cmath>
7 #include <tuple>
8
9 namespace lython {
10
11 template <typename T = double>
12 struct ValueStream {
13
14 void add(T value) {
15 sum += value;
16 count += 1;
17 sum_squared += value * value;
18 }
19
20 double mean() const { return sum / double(count); }
21
22 double var() const {
23 double m = mean();
24 return sum_squared / double(count) - m * m;
25 }
26
27 double total() const { return sum; }
28
29 double std() const { return sqrt(var()); }
30
31 T sum = 0;
32 T sum_squared = 0;
33 int count = 0;
34 };
35
36 template <class T>
37 void fakeuse(T&& datum) {
38 #ifdef __linux__
39 asm volatile("" : "+r"(datum));
40 #endif
41 }
42
43 template <typename... Args>
44 struct Benchmark {
45 Benchmark(std::string const& name,
46 std::function<void(Args...)> function,
47 int count = 100,
48 int repeat = 100000):
49 name(name),
50 function(function), count(count), repeat(repeat) {}
51
52 void run(Args... args) {
53 val = ValueStream<double>();
54
55 for (int i = 0; i < count; i++) {
56 StopWatch<double, std::chrono::milliseconds> time;
57
58 for (int j = 0; j < repeat; j++) {
59 function(args...);
60 }
61 val.add(time.stop());
62 }
63 }
64
65 void report(std::ostream& out) {
66 out << fmt::format(
67 "{:>30} | {:10.3f} | {:10.3f} | {:10.3f} \n", name, val.mean(), val.std(), val.total());
68 }
69
70 std::string name;
71 std::function<void(Args...)> function;
72 ValueStream<double> val;
73 int count;
74 int repeat;
75 };
76
77 template <typename... Args>
78 std::ostream& print(std::ostream& out, Args... args) {
79 print(out, args...);
80 return out;
81 }
82
83 template <typename... Args, typename T, typename V>
84 std::ostream& print(std::ostream& out, T val, V v, Args... args) {
85 print(out, v, args...);
86 out << val << "-";
87 return out;
88 }
89
90 template <typename... Args, typename T>
91 std::ostream& print(std::ostream& out, T val, Args... args) {
92 print(out, args...);
93 out << val;
94 return out;
95 }
96
97 template <>
98 std::ostream& print(std::ostream& out) {
99 return out;
100 }
101
102 template <typename... Args>
103 struct Compare {
104 Compare(std::vector<Benchmark<Args...>> const& benchs, int count = 100, int repeat = 100000):
105 benchmarks(benchs), count(count), repeat(repeat) {}
106
107 void run(std::ostream& out) {
108 int i = 0;
109
110 for (std::tuple<Args...>& args: setups) {
111 for (Benchmark<Args...>& bench: benchmarks) {
112 progress(out, i);
113
114 bench.count = count;
115 bench.repeat = repeat;
116
117 std::apply([&bench](auto&&... args) { bench.run(args...); }, args);
118
119 std::stringstream ss;
120 ss << bench.name << " (";
121 std::apply([&ss](auto&&... args) { print(ss, args...); }, args);
122 ss << ")";
123
124 results.emplace_back(ss.str(), bench.val);
125 i += 1;
126 }
127 }
128
129 progress(out, i);
130 }
131
132 void add_setup(Args... args) { setups.push_back(std::make_tuple(args...)); }
133
134 void progress(std::ostream& out, int i) {
135 float n = total();
136
137 out << fmt::format("{:6.2f} % {}/{}\n", float(i) * 100.0 / n, i, n);
138 }
139
140 float total() { return float(benchmarks.size()) * float(setups.size()); }
141
142 void report(std::ostream& out) {
143 out << fmt::format(
144 "{:>30} | {:>10} | {:>10} | {:>10} \n", "bench", "mean (ms)", "std (ms)", "total (ms)");
145 out << "---------------------------------------------------------------------\n";
146
147 for (auto const& bench: results) {
148 report(out, bench);
149 }
150 }
151
152 void as_csv(std::ostream& out) {
153 out << "bench,mean (ms),std (ms),total (ms)";
154 for (auto const& bench: results) {
155 as_csv(out, bench);
156 }
157 }
158
159 private:
160 void report(std::ostream& out, std::tuple<String, ValueStream<double>> const& result) {
161 String name = std::get<0>(result);
162 ValueStream<double> val = std::get<1>(result);
163 out << fmt::format(
164 "{:>30} | {:10.3f} | {:10.3f} | {:10.3f} \n", name, val.mean(), val.std(), val.total());
165 }
166
167 void as_csv(std::ostream& out, std::tuple<String, ValueStream<double>> const& result) {
168 String name = std::get<0>(result);
169 ValueStream<double> val = std::get<1>(result);
170 out << fmt::format("{},{},{},{}\n", name, val.mean(), val.std(), val.total());
171 }
172
173 std::vector<std::tuple<String, ValueStream<double>>> results;
174 std::vector<std::tuple<Args...>> setups;
175 std::vector<Benchmark<Args...>> benchmarks;
176 int count;
177 int repeat;
178 int col_size = 0;
179 };
180
181 } // namespace lython
182