Aleph-w 3.0
A C++ Library for Data Structures and Algorithms
Loading...
Searching...
No Matches
bench_support.H
Go to the documentation of this file.
1/*
2 Aleph_w
3
4 Data structures & Algorithms
5 version 2.0.0b
6 https://github.com/lrleon/Aleph-w
7
8 This file is part of Aleph-w library
9
10 Copyright (c) 2002-2026 Leandro Rabindranath Leon
11
12 Permission is hereby granted, free of charge, to any person obtaining a copy
13 of this software and associated documentation files (the "Software"), to deal
14 in the Software without restriction, including without limitation the rights
15 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
16 copies of the Software, and to permit persons to whom the Software is
17 furnished to do so, subject to the following conditions:
18
19 The above copyright notice and this permission notice shall be included in all
20 copies or substantial portions of the Software.
21
22 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
23 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
24 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
25 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
26 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
27 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
28 SOFTWARE.
29*/
30
50#ifndef CA_BENCH_SUPPORT_H
51#define CA_BENCH_SUPPORT_H
52
53#include <algorithm>
54#include <chrono>
55#include <cstddef>
56#include <cstdint>
57#include <cstdio>
58#include <cstdlib>
59#include <fstream>
60#include <iostream>
61#include <string>
62#include <utility>
63#include <vector>
64
65namespace Aleph {
66namespace CA {
67namespace Bench {
68
71{
72 std::string name;
73 std::uint64_t wall_ns = 0;
74 double cells_per_sec = 0.0;
75};
76
80inline std::string compiler_string()
81{
82#if defined(__clang__)
83 return std::string("clang ") + __clang_version__;
84#elif defined(__GNUC__)
85 return std::string("gcc ") + std::to_string(__GNUC__) + '.'
86 + std::to_string(__GNUC_MINOR__) + '.' + std::to_string(__GNUC_PATCHLEVEL__);
87#else
88 return "unknown";
89#endif
90}
91
100inline std::string cpu_string()
101{
102 std::string model = "unknown";
103 std::ifstream cpuinfo("/proc/cpuinfo");
104 std::string line;
105 while (std::getline(cpuinfo, line))
106 if (line.rfind("model name", 0) == 0)
107 {
108 const std::size_t colon = line.find(':');
109 if (colon != std::string::npos and colon + 2 <= line.size())
110 model = line.substr(colon + 2);
111 break;
112 }
113 for (char &c : model)
114 if (c == '"' or c == ',' or c == '\\')
115 c = ' ';
116 return model;
117}
118
128inline std::size_t resolve_repeats(const std::size_t fallback)
129{
130 if (const char *env = std::getenv("CA_BENCH_REPEATS"))
131 {
132 const long parsed = std::strtol(env, nullptr, 10);
133 if (parsed > 0)
134 return static_cast<std::size_t>(parsed);
135 }
136 return fallback == 0 ? 1 : fallback;
137}
138
155template <typename Work>
156[[nodiscard]] Bench_Result measure(std::string name,
157 const double processed_cells,
158 std::size_t repeats,
159 Work &&work)
160{
161 using clock = std::chrono::steady_clock;
162 if (repeats == 0)
163 repeats = 1;
164
165 work(); // untimed warmup.
166
167 std::vector<std::uint64_t> samples;
168 samples.reserve(repeats);
169 for (std::size_t i = 0; i < repeats; ++i)
170 {
171 const auto start = clock::now();
172 work();
173 const auto elapsed = clock::now() - start;
174 samples.push_back(static_cast<std::uint64_t>(
175 std::chrono::duration_cast<std::chrono::nanoseconds>(elapsed).count()));
176 }
177
178 std::sort(samples.begin(), samples.end());
179 const std::uint64_t median = samples[samples.size() / 2];
180
181 Bench_Result result;
182 result.name = std::move(name);
183 result.wall_ns = median;
184 result.cells_per_sec
185 = median == 0 ? 0.0 : processed_cells / (static_cast<double>(median) * 1e-9);
186 return result;
187}
188
199inline void emit_json(const Bench_Result &result, std::ostream &out = std::cout)
200{
201 char throughput[64];
202 std::snprintf(throughput, sizeof throughput, "%.3f", result.cells_per_sec);
203 out << "{\"name\":\"" << result.name << "\","
204 << "\"wall_ns\":" << result.wall_ns << ','
205 << "\"cells_per_sec\":" << throughput << ','
206 << "\"compiler\":\"" << compiler_string() << "\","
207 << "\"cpu\":\"" << cpu_string() << "\"}" << std::endl;
208}
209
210} // namespace Bench
211} // namespace CA
212} // namespace Aleph
213
214#endif // CA_BENCH_SUPPORT_H
size_t size_t int32_t * out
Definition ca-c-api.h:120
size_t blossom_maximum_cardinality_matching(const GT &g, DynDlist< typename GT::Arc * > &matching, SA sa=SA())
Alias of compute_maximum_cardinality_general_matching().
Definition Blossom.H:466
std::size_t resolve_repeats(const std::size_t fallback)
Resolve the number of timed repetitions for one anchor.
void emit_json(const Bench_Result &result, std::ostream &out=std::cout)
Print one benchmark result as a single structured JSON object.
std::string cpu_string()
Read the CPU model name advertised by the host.
Bench_Result measure(std::string name, const double processed_cells, std::size_t repeats, Work &&work)
Time a kernel with one warmup pass plus a median of timed passes.
std::string compiler_string()
Describe the compiler that produced the running binary.
Main namespace for Aleph-w library functions.
Definition ah-arena.H:89
const T * median(const T &a, const T &b, const T &c, const Compare &cmp=Compare())
Return a pointer to the median value among three elements.
Definition ahUtils.H:84
and
Check uniqueness with explicit hash + equality functors.
Itor::difference_type count(const Itor &beg, const Itor &end, const T &value)
Count elements equal to a value.
Definition ahAlgo.H:127
Outcome of one measured anchor benchmark.
std::string name
stable benchmark identifier.
double cells_per_sec
processed cells divided by the median run time.
std::uint64_t wall_ns
median wall-clock time of one run, nanoseconds.