ComPPare 1.0.0
Loading...
Searching...
No Matches
google_benchmark.hpp
Go to the documentation of this file.
1/*
2
3Copyright 2025 | Leong Fan FUNG | funglf | stanleyfunglf@gmail.com
4
5Permission is hereby granted, free of charge, to any person obtaining a copy
6of this software and associated documentation files (the “Software”), to deal
7in the Software without restriction, including without limitation the rights
8to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9copies of the Software, and to permit persons to whom the Software is
10furnished to do so, subject to the following conditions:
11
12The above copyright notice and this permission notice shall be included in
13all copies or substantial portions of the Software.
14
15THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21SOFTWARE.
22
23*/
24
34#pragma once
35#ifdef HAVE_GOOGLE_BENCHMARK
36#include <utility>
37#include <tuple>
38#include <ostream>
39#include <iomanip>
40#include <iostream>
41#include <sstream>
42#include <string>
43#include <algorithm>
44#include <cstring>
45#include <benchmark/benchmark.h>
46
49
51{
59 class state
60 {
61 public:
62 state(const state &) = delete;
63 state &operator=(const state &) = delete;
64 state(state &&) = delete;
65 state &operator=(state &&) = delete;
66
67 static state &instance()
68 {
69 static state inst;
70 return inst;
71 }
72
73 static void set_state(benchmark::State &st)
74 {
75 instance().st_ = &st;
76 }
77
78 static benchmark::State &get_state()
79 {
80 if (!instance().st_)
81 throw std::runtime_error("Benchmark state is not set.");
82 return *instance().st_;
83 }
84
85 private:
86 state() = default;
87 benchmark::State *st_ = nullptr;
88 };
89
98 {
99 public:
102
113 void initialize(int &argc, char **argv)
114 {
115 auto [tmp_argc, tmp_argv] = gbench_parser_.parse(argc, argv);
116 gbench_argc = tmp_argc;
117 gbench_argv = tmp_argv;
119
120 benchmark::Initialize(&gbench_argc, gbench_argv);
121 benchmark::ReportUnrecognizedArguments(gbench_argc, gbench_argv);
122 }
123
157 template <typename Func, typename... Args>
158 benchmark::internal::Benchmark *add_gbench(const char *name, Func f, Args &&...args)
159 {
160 std::tuple<Args...> cargs(std::forward<Args>(args)...);
161
162 auto benchptr = benchmark::RegisterBenchmark(
163 name,
164 [f, cargs = std::move(cargs)](benchmark::State &st) mutable
165 {
167 std::apply([&](auto &&...unpacked)
168 { f(std::forward<decltype(unpacked)>(unpacked)...); }, cargs);
169 benchmark::ClobberMemory();
170 });
171
172 return benchptr;
173 }
174
182 void run()
183 {
184 benchmark::RunSpecifiedBenchmarks();
185 benchmark::Shutdown();
186 }
187
188 private:
193
196 {
197
198 std::cout << "\n"
199 << std::left << comppare::internal::ansi::BOLD
200 << "*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=\n============= "
201 << comppare::internal::ansi::ITALIC("Google Benchmark")
202 << " =============\n=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*"
203 << comppare::internal::ansi::BOLD_OFF << "\n\n";
204
205 std::cout << "Google Benchmark cmdline arguments:\n";
206 for (int i = 0; i < gbench_argc; ++i)
207 {
208 std::cout << std::setw(2) << std::right << " "
209 << " [" << i << "] " << std::quoted(gbench_argv[i]) << "\n";
210 }
211
212 std::cout << std::left
213 << comppare::internal::ansi::BOLD("=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*")
214 << "\n\n";
215 }
216 };
217
229 template <class InTup, class OutTup>
230 class GoogleBenchmarkPlugin final : public Plugin<InTup, OutTup>
231 {
234
235 public:
238
247 static std::shared_ptr<Self> instance()
248 {
249 static std::shared_ptr<Self> inst{new Self};
250 return inst;
251 }
252
268 template <class Func>
269 benchmark::internal::Benchmark *register_impl(const std::string &name,
270 Func &&user_fn,
271 const InTup &inputs,
272 OutTup &outs)
273 {
274 return std::apply([&](auto const &...in_vals)
275 { return std::apply([&](auto &&...outs_vals)
276 { return gb_.add_gbench(name.c_str(),
277 std::forward<Func>(user_fn),
278 in_vals..., outs_vals...); }, outs); }, inputs);
279 }
280
289 void initialize(int &argc, char **argv) override
290 {
291 gb_.initialize(argc, argv);
292 }
293
299 void run() override
300 {
301 gb_.run();
302 }
303
304 private:
306 };
307
320 template <comppare::internal::concepts::FloatingPoint T>
321 inline void SetIterationTime(T time)
322 {
324 st.SetIterationTime(static_cast<double>(time * 1e-6));
325 }
326
340 template <typename Rep, typename Period>
341 inline void SetIterationTime(std::chrono::duration<Rep, Period> time)
342 {
344 double elapsed_seconds = std::chrono::duration_cast<std::chrono::duration<double>>(time).count();
345 st.SetIterationTime(elapsed_seconds);
346 }
347
348}
349
353#define PLUGIN_HOTLOOP_BENCH \
354 benchmark::State &st = comppare::plugin::google_benchmark::state::get_state(); \
355 for (auto _ : st) \
356 { \
357 hotloop_body(); \
358 }
359
360#if defined(__CUDACC__)
361#define GPU_PLUGIN_HOTLOOP_BENCH \
362 cudaEvent_t __LINE__stop; \
363 cudaEventCreate(&__LINE__stop); \
364 benchmark::State &st = comppare::plugin::google_benchmark::state::get_state(); \
365 for (auto _ : st) \
366 { \
367 hotloop_body(); \
368 /* Syncronise every time to record GPU time */ \
369 /* Google Benchmark records extra overhead of EventSynchronization */ \
370 /* Google Benchmark not recommended for GPU code anyways. */ \
371 cudaEventRecord(__LINE__stop); \
372 cudaEventSynchronize(__LINE__stop); \
373 }
374#elif defined(__HIPCC__)
375#define GPU_PLUGIN_HOTLOOP_BENCH \
376 hipEvent_t __LINE__stop; \
377 hipEventCreate(&__LINE__stop); \
378 benchmark::State &st = comppare::plugin::google_benchmark::state::get_state(); \
379 for (auto _ : st) \
380 { \
381 hotloop_body(); \
382 /* Syncronise every time to record GPU time */ \
383 /* Google Benchmark records extra overhead of EventSynchronization */ \
384 /* Google Benchmark not recommended for GPU code anyways. */ \
385 hipEventRecord(__LINE__stop); \
386 hipEventSynchronize(__LINE__stop); \
387 }
388#endif
389
391#define PLUGIN_SET_ITERATION_TIME(TIME) \
392 comppare::plugin::google_benchmark::SetIterationTime(TIME);
393
394#endif // HAVE_GOOGLE_BENCHMARK
This file contains utilities for applying ANSI styles and colors to console output.
Argument parser for plugin command-line arguments.
Definition plugin.hpp:107
std::pair< int, char ** > parse(int argc, char **argv)
Definition plugin.hpp:118
Base class for plugins in the ComPPare framework.
Definition plugin.hpp:60
Google Benchmark plugin for the ComPPare framework.
Definition google_benchmark.hpp:231
static std::shared_ptr< Self > instance()
Get the singleton instance of the GoogleBenchmarkPlugin.
Definition google_benchmark.hpp:247
comppare::plugin::google_benchmark::google_benchmark_manager gb_
Definition google_benchmark.hpp:233
void initialize(int &argc, char **argv) override
Initialize the Google Benchmark plugin.
Definition google_benchmark.hpp:289
benchmark::internal::Benchmark * register_impl(const std::string &name, Func &&user_fn, const InTup &inputs, OutTup &outs)
Register an implementation with the Google Benchmark plugin.
Definition google_benchmark.hpp:269
GoogleBenchmarkPlugin & operator=(const GoogleBenchmarkPlugin &)=delete
void run() override
Run the registered benchmarks.
Definition google_benchmark.hpp:299
GoogleBenchmarkPlugin(const GoogleBenchmarkPlugin &)=delete
Manager class for Google Benchmark integration.
Definition google_benchmark.hpp:98
void run()
Run the registered benchmarks.
Definition google_benchmark.hpp:182
int gbench_argc
Definition google_benchmark.hpp:189
benchmark::internal::Benchmark * add_gbench(const char *name, Func f, Args &&...args)
Register a benchmark function with Google Benchmark.
Definition google_benchmark.hpp:158
char ** gbench_argv
Definition google_benchmark.hpp:190
comppare::plugin::PluginArgParser gbench_parser_
Argument parser for Google Benchmark.
Definition google_benchmark.hpp:192
void initialize(int &argc, char **argv)
Initialize the Google Benchmark library.
Definition google_benchmark.hpp:113
void print_benchmark_header()
Print the benchmark header.
Definition google_benchmark.hpp:195
State class to manage the benchmark state.
Definition google_benchmark.hpp:60
static state & instance()
Definition google_benchmark.hpp:67
benchmark::State * st_
Definition google_benchmark.hpp:87
static void set_state(benchmark::State &st)
Definition google_benchmark.hpp:73
state & operator=(const state &)=delete
static benchmark::State & get_state()
Definition google_benchmark.hpp:78
Definition google_benchmark.hpp:51
void SetIterationTime(T time)
Set the iteration time for the current benchmark.
Definition google_benchmark.hpp:321
This file contains the base Plugin class and concept of a valid Plugin class for the ComPPare framewo...