Skip to content

Commit b4ce920

Browse files
committed
Use Google Benchmark for performance tables
1 parent c358e80 commit b4ce920

15 files changed

Lines changed: 987 additions & 342 deletions

.gitmodules

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,3 +13,6 @@
1313
[submodule "3rdparty/libenvpp"]
1414
path = 3rdparty/libenvpp
1515
url = https://github.com/ph3at/libenvpp
16+
[submodule "3rdparty/benchmark"]
17+
path = 3rdparty/benchmark
18+
url = https://github.com/google/benchmark

3rdparty/benchmark

Submodule benchmark added at a846068

CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@ endforeach()
4444

4545
message( STATUS "PPC step: Setup external projects" )
4646
include(cmake/gtest.cmake)
47+
include(cmake/benchmark.cmake)
4748

4849
############################## Modules ##############################
4950

cmake/benchmark.cmake

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
include_guard()
2+
3+
include(ExternalProject)
4+
5+
ExternalProject_Add(
6+
ppc_benchmark
7+
SOURCE_DIR "${CMAKE_SOURCE_DIR}/3rdparty/benchmark"
8+
PREFIX "${CMAKE_CURRENT_BINARY_DIR}/ppc_benchmark"
9+
BINARY_DIR "${CMAKE_CURRENT_BINARY_DIR}/ppc_benchmark/build"
10+
INSTALL_DIR "${CMAKE_CURRENT_BINARY_DIR}/ppc_benchmark/install"
11+
EXCLUDE_FROM_ALL TRUE
12+
CMAKE_ARGS -DCMAKE_C_COMPILER=${CMAKE_C_COMPILER}
13+
-DCMAKE_CXX_COMPILER=${CMAKE_CXX_COMPILER}
14+
-DCMAKE_C_COMPILER_LAUNCHER=${CMAKE_C_COMPILER_LAUNCHER}
15+
-DCMAKE_CXX_COMPILER_LAUNCHER=${CMAKE_CXX_COMPILER_LAUNCHER}
16+
-DCMAKE_CXX_STANDARD=${CMAKE_CXX_STANDARD}
17+
-DCMAKE_CXX_STANDARD_REQUIRED=${CMAKE_CXX_STANDARD_REQUIRED}
18+
-DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE}
19+
${PPC_EXTERNAL_PROJECT_CMAKE_ARGS}
20+
-DCMAKE_C_FLAGS=-w
21+
-DCMAKE_CXX_FLAGS=-w
22+
-DBENCHMARK_ENABLE_TESTING=OFF
23+
-DBENCHMARK_ENABLE_GTEST_TESTS=OFF
24+
-DBENCHMARK_ENABLE_WERROR=OFF
25+
-DBENCHMARK_ENABLE_INSTALL=ON
26+
-DBENCHMARK_ENABLE_LIBPFM=OFF
27+
BUILD_COMMAND
28+
"${CMAKE_COMMAND}" --build "${CMAKE_CURRENT_BINARY_DIR}/ppc_benchmark/build"
29+
--config $<CONFIG> --parallel
30+
INSTALL_COMMAND
31+
"${CMAKE_COMMAND}" --install
32+
"${CMAKE_CURRENT_BINARY_DIR}/ppc_benchmark/build" --config $<CONFIG>
33+
--prefix "${CMAKE_CURRENT_BINARY_DIR}/ppc_benchmark/install"
34+
${PPC_EXTERNAL_PROJECT_LOG_ARGS})
35+
36+
function(ppc_link_benchmark target_name)
37+
target_include_directories(
38+
${target_name} PUBLIC ${CMAKE_SOURCE_DIR}/3rdparty/benchmark/include)
39+
40+
add_dependencies(${target_name} ppc_benchmark)
41+
target_link_directories(${target_name} PUBLIC
42+
"${CMAKE_BINARY_DIR}/ppc_benchmark/install/lib")
43+
target_link_libraries(${target_name} PUBLIC benchmark Threads::Threads)
44+
endfunction()

modules/util/include/perf_test_util.hpp

Lines changed: 82 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,13 @@
11
#pragma once
22

3+
#include <benchmark/benchmark.h>
34
#include <gtest/gtest.h>
45
#include <omp.h>
56
#include <tbb/tick_count.h>
67

78
#include <chrono>
89
#include <cstddef>
10+
#include <cstdlib>
911
#include <functional>
1012
#include <sstream>
1113
#include <stdexcept>
@@ -21,8 +23,64 @@
2123

2224
namespace ppc::util {
2325

24-
double GetTimeMPI();
25-
int GetMPIRank();
26+
namespace detail {
27+
28+
inline bool ContainsFilterToken(std::string_view value, const char *filter_env) {
29+
if (filter_env == nullptr || std::string_view(filter_env).empty()) {
30+
return true;
31+
}
32+
return value.find(filter_env) != std::string_view::npos;
33+
}
34+
35+
inline bool ShouldRunBenchmark(std::string_view test_name) {
36+
return ContainsFilterToken(test_name, std::getenv("PPC_PERF_IMPL_FILTER")) &&
37+
ContainsFilterToken(test_name, std::getenv("PPC_PERF_CATEGORY_FILTER"));
38+
}
39+
40+
inline void CheckPerfMode(ppc::performance::PerfResults::TypeOfRunning mode) {
41+
if (mode == ppc::performance::PerfResults::TypeOfRunning::kPipeline ||
42+
mode == ppc::performance::PerfResults::TypeOfRunning::kTaskRun) {
43+
return;
44+
}
45+
std::stringstream err_msg;
46+
err_msg << '\n' << "The type of performance check for the task was not selected.\n";
47+
throw std::runtime_error(err_msg.str().c_str());
48+
}
49+
50+
template <typename InType, typename OutType>
51+
void RunTaskPipeline(const ppc::task::TaskPtr<InType, OutType> &task) {
52+
task->Validation();
53+
task->PreProcessing();
54+
task->Run();
55+
task->PostProcessing();
56+
}
57+
58+
template <typename InType, typename OutType>
59+
void RunTaskForBenchmark(const ppc::task::TaskPtr<InType, OutType> &task,
60+
ppc::performance::PerfResults::TypeOfRunning mode, benchmark::State &state) {
61+
task->GetStateOfTesting() = ppc::task::StateOfTesting::kPerf;
62+
if (mode == ppc::performance::PerfResults::TypeOfRunning::kPipeline) {
63+
SynchronizeMpiRanks();
64+
state.ResumeTiming();
65+
RunTaskPipeline(task);
66+
state.PauseTiming();
67+
return;
68+
}
69+
70+
task->Validation();
71+
task->PreProcessing();
72+
SynchronizeMpiRanks();
73+
state.ResumeTiming();
74+
task->Run();
75+
state.PauseTiming();
76+
task->PostProcessing();
77+
}
78+
79+
inline std::string MakeBenchmarkName(const std::string &test_name, ppc::performance::PerfResults::TypeOfRunning mode) {
80+
return test_name + "/" + ppc::performance::GetStringParamName(mode);
81+
}
82+
83+
} // namespace detail
2684

2785
template <typename InType, typename OutType>
2886
using PerfTestParam = std::tuple<std::function<ppc::task::TaskPtr<InType, OutType>(InType)>, std::string,
@@ -80,31 +138,35 @@ class BaseRunPerfTests : public ::testing::TestWithParam<PerfTestParam<InType, O
80138
// A single perf test body may execute several implementations; do not abort the enabled ones.
81139
return;
82140
}
141+
if (!detail::ShouldRunBenchmark(test_name)) {
142+
return;
143+
}
144+
detail::CheckPerfMode(mode);
83145

84146
const auto test_env_scope = ppc::util::test::MakePerTestEnvForCurrentGTest(test_name);
85147

86-
task_ = task_getter(GetTestInputData());
87-
ppc::performance::Perf perf(task_);
88-
ppc::performance::PerfAttr perf_attr;
148+
const auto input_data = GetTestInputData();
149+
task_ = task_getter(input_data);
89150
SynchronizeMpiRanks();
90-
SetPerfAttributes(perf_attr);
91-
92-
if (mode == ppc::performance::PerfResults::TypeOfRunning::kPipeline) {
93-
perf.PipelineRun(perf_attr);
94-
} else if (mode == ppc::performance::PerfResults::TypeOfRunning::kTaskRun) {
95-
perf.TaskRun(perf_attr);
96-
} else {
97-
std::stringstream err_msg;
98-
err_msg << '\n' << "The type of performance check for the task was not selected.\n";
99-
throw std::runtime_error(err_msg.str().c_str());
100-
}
101-
102-
if (GetMPIRank() == 0) {
103-
perf.PrintPerfStatistic(test_name);
104-
}
151+
detail::RunTaskPipeline(task_);
105152

106153
OutType output_data = task_->GetOutput();
107154
ASSERT_TRUE(CheckTestOutputData(output_data));
155+
156+
const auto benchmark_name = detail::MakeBenchmarkName(test_name, mode);
157+
benchmark::RegisterBenchmark(benchmark_name,
158+
[task_getter, input_data, mode](benchmark::State &state) {
159+
for (auto _ : state) {
160+
state.PauseTiming();
161+
auto task = task_getter(input_data);
162+
detail::RunTaskForBenchmark(task, mode, state);
163+
benchmark::DoNotOptimize(task->GetOutput());
164+
state.ResumeTiming();
165+
}
166+
})
167+
->UseRealTime()
168+
->Unit(benchmark::kMillisecond)
169+
->MinTime(0.01);
108170
}
109171

110172
private:

modules/util/include/util.hpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,8 @@ int GetNumThreads();
7575
int GetNumProc();
7676
double GetTaskMaxTime();
7777
double GetPerfMaxTime();
78+
double GetTimeMPI();
79+
int GetMPIRank();
7880
void SynchronizeMpiRanks();
7981

8082
template <typename T>

modules/util/src/func_test_util.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
#include <mpi.h>
22

3-
#include "util/include/perf_test_util.hpp"
3+
#include "util/include/util.hpp"
44

55
double ppc::util::GetTimeMPI() {
66
return MPI_Wtime();

0 commit comments

Comments
 (0)