Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Revert "Use Catch2 for benchmarks" #5582

Merged
merged 1 commit into from
Oct 23, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .github/workflows/Tests.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -701,6 +701,11 @@ ${{ matrix.build_type }}-pch-${{ matrix.use_pch || 'ON' }}"
working-directory: build
run: |
make test-executables
- name: Build Benchmark executable
if: matrix.build_type == 'Release'
working-directory: build
run: |
make -j2 Benchmark
# Delete unused cache entries before uploading the cache
- name: Clean up ccache
if: github.ref == 'refs/heads/develop'
Expand Down
1 change: 1 addition & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,7 @@ include(SetupLIBXSMM)
include(SetupBlaze)
include(SetupBrigand)
include(SetupFuka)
include(SetupGoogleBenchmark)
include(SetupGsl)
include(SetupHdf5)
include(SetupAllocator)
Expand Down
25 changes: 25 additions & 0 deletions cmake/SetupGoogleBenchmark.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
# Distributed under the MIT License.
# See LICENSE.txt for details.

find_package(GoogleBenchmark QUIET)


if (${GoogleBenchmark_FOUND})
message(STATUS "Google Benchmark libs: " ${GoogleBenchmark_LIBRARIES})
message(STATUS "Google Benchmark incl: " ${GoogleBenchmark_INCLUDE_DIRS})

file(APPEND
"${CMAKE_BINARY_DIR}/BuildInfo.txt"
"Google Benchmark found\n"
)

add_library(GoogleBenchmark INTERFACE IMPORTED)
set_property(TARGET GoogleBenchmark PROPERTY
INTERFACE_INCLUDE_DIRECTORIES ${GoogleBenchmark_INCLUDE_DIRS})
set_property(TARGET GoogleBenchmark PROPERTY
INTERFACE_LINK_LIBRARIES ${GoogleBenchmark_LIBRARIES})
set_property(
GLOBAL APPEND PROPERTY SPECTRE_THIRD_PARTY_LIBS
GoogleBenchmark
)
endif()
3 changes: 2 additions & 1 deletion containers/Dockerfile.buildenv
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,8 @@ RUN apt-get update -y \
libboost-thread-dev libboost-tools-dev libssl-dev \
libhdf5-dev hdf5-tools \
libarpack2-dev \
libyaml-cpp-dev
libyaml-cpp-dev \
libbenchmark-dev

# Install Python packages
# We only install packages that are needed by the build system (e.g. to compile
Expand Down
5 changes: 5 additions & 0 deletions docs/DevGuide/PerformanceGuidelines.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,11 @@ Below are some general guidelines for achieving decent performance.
specific machine or architecture). You can keep track of the benchmark results
you ran on specific machines in a comment in the test case (until we have a
better way of keeping track of benchmark results).

Catch2's benchmarking is not as feature-rich as Google Benchmark. We have a
`Benchmark` executable that uses Google Benchmark so one can compare
different implementations and see how they perform. This executable is only
available in release builds.
- Reduce memory allocations. On all modern hardware (many core CPUs, GPUs, and
FPGAs), memory is almost always the bottleneck. Memory allocations are
especially expensive since this is a quasi-serial process: the OS has to
Expand Down
2 changes: 2 additions & 0 deletions docs/Installation/Installation.md
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,8 @@ apt), or AppleClang 13.0.0 or later
<details>
\include support/Python/dev_requirements.txt
</details>
* [Google Benchmark](https://github.com/google/benchmark) - to do
microbenchmarking inside the SpECTRE framework. v1.2 or newer is required
* [LCOV](http://ltp.sourceforge.net/coverage/lcov.php) and
[gcov](https://gcc.gnu.org/onlinedocs/gcc/Gcov.html) — to check code test
coverage
Expand Down
116 changes: 116 additions & 0 deletions src/Executables/Benchmark/Benchmark.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@
// Distributed under the MIT License.
// See LICENSE.txt for details.

#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wredundant-decls"
#include <benchmark/benchmark.h>
#pragma GCC diagnostic pop
#include <charm++.h>
#include <string>
#include <vector>

#include "DataStructures/DataBox/Tag.hpp"
#include "DataStructures/DataVector.hpp"
#include "DataStructures/Tensor/Tensor.hpp"
#include "DataStructures/Variables.hpp"
#include "Domain/CoordinateMaps/Affine.hpp"
#include "Domain/CoordinateMaps/CoordinateMap.hpp"
#include "Domain/CoordinateMaps/CoordinateMap.tpp"
#include "Domain/CoordinateMaps/ProductMaps.hpp"
#include "Domain/CoordinateMaps/ProductMaps.tpp"
#include "Domain/Structure/Element.hpp"
#include "NumericalAlgorithms/LinearOperators/PartialDerivatives.tpp"
#include "NumericalAlgorithms/Spectral/LogicalCoordinates.hpp"
#include "NumericalAlgorithms/Spectral/Mesh.hpp"
#include "NumericalAlgorithms/Spectral/Spectral.hpp"
#include "PointwiseFunctions/MathFunctions/PowX.hpp"

// Charm looks for this function but since we build without a main function or
// main module we just have it be empty
extern "C" void CkRegisterMainModule(void) {}

// This file is an example of how to do microbenchmark with Google Benchmark
// https://github.com/google/benchmark
// For two examples in different anonymous namespaces

namespace {
// Benchmark of push_back() in std::vector, following Chandler Carruth's talk
// at CppCon in 2015,
// https://www.youtube.com/watch?v=nXaxk27zwlk

// void bench_create(benchmark::State &state) {
// while (state.KeepRunning()) {
// std::vector<int> v;
// benchmark::DoNotOptimize(&v);
// static_cast<void>(v);
// }
// }
// BENCHMARK(bench_create);

// void bench_reserve(benchmark::State &state) {
// while (state.KeepRunning()) {
// std::vector<int> v;
// v.reserve(1);
// benchmark::DoNotOptimize(v.data());
// }
// }
// BENCHMARK(bench_reserve);

// void bench_push_back(benchmark::State &state) {
// while (state.KeepRunning()) {
// std::vector<int> v;
// v.reserve(1);
// benchmark::DoNotOptimize(v.data());
// v.push_back(42);
// benchmark::ClobberMemory();
// }
// }
// BENCHMARK(bench_push_back);
} // namespace

namespace {
// In this anonymous namespace is an example of microbenchmarking the
// all_gradient routine for the GH system

template <size_t Dim>
struct Kappa : db::SimpleTag {
using type = tnsr::abb<DataVector, Dim, Frame::Grid>;
};
template <size_t Dim>
struct Psi : db::SimpleTag {
using type = tnsr::aa<DataVector, Dim, Frame::Grid>;
};

// clang-tidy: don't pass be non-const reference
void bench_all_gradient(benchmark::State& state) { // NOLINT
constexpr const size_t pts_1d = 4;
constexpr const size_t Dim = 3;
const Mesh<Dim> mesh{pts_1d, Spectral::Basis::Legendre,
Spectral::Quadrature::GaussLobatto};
domain::CoordinateMaps::Affine map1d(-1.0, 1.0, -1.0, 1.0);
using Map3d =
domain::CoordinateMaps::ProductOf3Maps<domain::CoordinateMaps::Affine,
domain::CoordinateMaps::Affine,
domain::CoordinateMaps::Affine>;
domain::CoordinateMap<Frame::ElementLogical, Frame::Grid, Map3d> map(
Map3d{map1d, map1d, map1d});

using VarTags = tmpl::list<Kappa<Dim>, Psi<Dim>>;
const InverseJacobian<DataVector, Dim, Frame::ElementLogical, Frame::Grid>
inv_jac = map.inv_jacobian(logical_coordinates(mesh));
const auto grid_coords = map(logical_coordinates(mesh));
Variables<VarTags> vars(mesh.number_of_grid_points(), 0.0);

while (state.KeepRunning()) {
benchmark::DoNotOptimize(partial_derivatives<VarTags>(vars, mesh, inv_jac));
}
}
BENCHMARK(bench_all_gradient); // NOLINT
} // namespace

// Ignore the warning about an extra ';' because some versions of benchmark
// require it
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wpedantic"
BENCHMARK_MAIN();
#pragma GCC diagnostic pop
27 changes: 27 additions & 0 deletions src/Executables/Benchmark/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
# Distributed under the MIT License.
# See LICENSE.txt for details.

# Since benchmarking is only interesting in release mode the executable isn't
# added for Debug builds. Charm++'s main function is overridden with the main
# from the Google Benchmark library. The executable is not added to the `all` make
# target since it is only interesting in specific circumstances.
if("${GoogleBenchmark_FOUND}" AND NOT "${CMAKE_BUILD_TYPE}" STREQUAL "Debug")
set(executable Benchmark)

add_spectre_executable(
${executable}
EXCLUDE_FROM_ALL
Benchmark.cpp
)

# Add specific libraries needed for the benchmark you are interested in.
target_link_libraries(
${executable}
PRIVATE
CoordinateMaps
Domain
Informer
GoogleBenchmark
Spectral
)
endif()
1 change: 1 addition & 0 deletions src/Executables/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
# Distributed under the MIT License.
# See LICENSE.txt for details.

add_subdirectory(Benchmark)
add_subdirectory(ConvertComposeTable)
add_subdirectory(DebugPreprocessor)
add_subdirectory(ExportEquationOfStateForRotNS)
Expand Down