mirror of
https://github.com/boostorg/histogram.git
synced 2025-05-11 05:07:58 +00:00
better test of indexed range adaptor and new benchmark for indexed
This commit is contained in:
parent
ab8201eca1
commit
94a3364c83
@ -18,10 +18,10 @@ if ("$ENV{BOOST_ROOT}" STREQUAL "")
|
||||
endif()
|
||||
|
||||
# setup build
|
||||
option(BUILD_BENCHMARKS "Build benchmarks" ON)
|
||||
option(TEST_SERIALIZATION "Test serialization code (requires boost.serialization)" ON)
|
||||
option(TEST_ACCUMULATORS_SUPPORT "Test support for boost.accumulators" ON)
|
||||
option(TEST_RANGE_SUPPORT "Test support for boost.range" ON)
|
||||
option(BUILD_BENCHMARKS "Build benchmarks" ON)
|
||||
|
||||
# serialization support is optional
|
||||
if (TEST_SERIALIZATION)
|
||||
@ -44,14 +44,14 @@ enable_testing()
|
||||
function(compiled_test SRC)
|
||||
get_filename_component(BASENAME ${SRC} NAME_WE)
|
||||
add_executable(${BASENAME} ${SRC})
|
||||
target_include_directories(${BASENAME} PUBLIC include ${Boost_INCLUDE_DIR})
|
||||
target_include_directories(${BASENAME} PRIVATE include ${Boost_INCLUDE_DIR})
|
||||
|
||||
if(CMAKE_BUILD_TYPE MATCHES coverage)
|
||||
target_compile_options(${BASENAME} PRIVATE --coverage)
|
||||
target_link_libraries(${BASENAME} PRIVATE --coverage)
|
||||
endif()
|
||||
|
||||
# max warnings and activate sanitizers for clang and gcc
|
||||
# max warnings and activate sanitizers for clang
|
||||
if(CMAKE_CXX_COMPILER_ID STREQUAL "MSVC")
|
||||
target_compile_options(${BASENAME} PRIVATE -D_SCL_SECURE_NO_WARNINGS)
|
||||
elseif(CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
|
||||
@ -118,16 +118,16 @@ compiled_test(examples/guide_parallel_filling.cpp)
|
||||
|
||||
if (TEST_SERIALIZATION)
|
||||
compiled_test(examples/guide_histogram_serialization.cpp Boost::serialization)
|
||||
target_link_libraries(guide_histogram_serialization PUBLIC Boost::serialization)
|
||||
target_link_libraries(guide_histogram_serialization PRIVATE Boost::serialization)
|
||||
|
||||
compiled_test(test/adaptive_storage_serialization_test.cpp Boost::serialization)
|
||||
target_link_libraries(adaptive_storage_serialization_test PUBLIC Boost::serialization)
|
||||
target_link_libraries(adaptive_storage_serialization_test PRIVATE Boost::serialization)
|
||||
|
||||
compiled_test(test/storage_adaptor_serialization_test.cpp)
|
||||
target_link_libraries(storage_adaptor_serialization_test PUBLIC Boost::serialization)
|
||||
target_link_libraries(storage_adaptor_serialization_test PRIVATE Boost::serialization)
|
||||
|
||||
compiled_test(test/histogram_serialization_test.cpp Boost::serialization)
|
||||
target_link_libraries(histogram_serialization_test PUBLIC Boost::serialization)
|
||||
target_link_libraries(histogram_serialization_test PRIVATE Boost::serialization)
|
||||
endif()
|
||||
|
||||
if (TEST_ACCUMULATORS_SUPPORT) # test the support for external boost::accumulators
|
||||
@ -139,10 +139,26 @@ if (TEST_RANGE_SUPPORT) # test the support for external boost::range
|
||||
endif()
|
||||
|
||||
if (BUILD_BENCHMARKS)
|
||||
include(ExternalProject)
|
||||
|
||||
find_package(benchmark REQUIRED)
|
||||
|
||||
function(benchmark SRC)
|
||||
get_filename_component(BASENAME ${SRC} NAME_WE)
|
||||
add_executable(${BASENAME} ${SRC})
|
||||
target_include_directories(${BASENAME} PRIVATE include ${Boost_INCLUDE_DIR} benchmark::benchmark)
|
||||
target_compile_definitions(${BASENAME} PRIVATE -DBOOST_DISABLE_ASSERTS)
|
||||
target_compile_options(${BASENAME} PRIVATE -O2)
|
||||
target_link_libraries(${BASENAME} PRIVATE benchmark::benchmark_main)
|
||||
endfunction()
|
||||
|
||||
benchmark(test/iteration_bench.cpp)
|
||||
|
||||
add_executable(speed_cpp test/speed_cpp.cpp)
|
||||
target_include_directories(speed_cpp PRIVATE include ${Boost_INCLUDE_DIR})
|
||||
target_compile_definitions(speed_cpp PRIVATE -DBOOST_DISABLE_ASSERTS)
|
||||
target_compile_options(speed_cpp PRIVATE -O3)
|
||||
|
||||
add_executable(axis_size test/axis_size.cpp)
|
||||
target_include_directories(axis_size PRIVATE include ${Boost_INCLUDE_DIR})
|
||||
target_compile_options(axis_size PRIVATE -O3)
|
||||
|
@ -55,77 +55,34 @@ void run_1d_tests(bool include_extra_bins) {
|
||||
}
|
||||
|
||||
template <typename Tag>
|
||||
void run_2d_tests(bool include_extra_bins) {
|
||||
auto h = make_s(Tag(), std::vector<int>(), axis::integer<>(0, 1),
|
||||
axis::integer<int, axis::null_type, axis::option_type::overflow>(2, 4));
|
||||
h(weight(2), 0, 2);
|
||||
h(-1, 2);
|
||||
h(1, 3);
|
||||
void run_3d_tests(bool b) {
|
||||
auto h = make_s(Tag(), std::vector<int>(),
|
||||
axis::integer<>(0, 2),
|
||||
axis::integer<int, axis::null_type, axis::option_type::none>(0, 3),
|
||||
axis::integer<int, axis::null_type, axis::option_type::overflow>(0, 4));
|
||||
|
||||
BOOST_TEST_EQ(axis::traits::extend(h.axis(0)), 3);
|
||||
BOOST_TEST_EQ(axis::traits::extend(h.axis(1)), 3);
|
||||
for (int i = -1; i < 3; ++i)
|
||||
for (int j = -1; j < 4; ++j)
|
||||
for (int k = -1; k < 5; ++k)
|
||||
h(i, j, k, weight(i * 100 + j * 10 + k));
|
||||
|
||||
auto ind = indexed(h, include_extra_bins);
|
||||
auto ind = indexed(h, b);
|
||||
auto it = ind.begin();
|
||||
BOOST_TEST_EQ(it->size(), 2);
|
||||
BOOST_TEST_EQ(it->size(), 3);
|
||||
|
||||
BOOST_TEST_EQ(it->operator[](0), 0);
|
||||
BOOST_TEST_EQ(it->operator[](1), 0);
|
||||
BOOST_TEST_EQ(it->bin(0_c), h.axis(0_c)[0]);
|
||||
BOOST_TEST_EQ(it->bin(1_c), h.axis(1_c)[0]);
|
||||
BOOST_TEST_EQ(it->value, 2);
|
||||
++it;
|
||||
if (include_extra_bins) {
|
||||
BOOST_TEST_EQ(it->operator[](0), 1);
|
||||
BOOST_TEST_EQ(it->operator[](1), 0);
|
||||
BOOST_TEST_EQ(it->bin(0), h.axis(0)[1]);
|
||||
BOOST_TEST_EQ(it->bin(1), h.axis(1)[0]);
|
||||
BOOST_TEST_EQ(it->value, 0);
|
||||
++it;
|
||||
BOOST_TEST_EQ(it->operator[](0), -1);
|
||||
BOOST_TEST_EQ(it->operator[](1), 0);
|
||||
BOOST_TEST_EQ(it->bin(0_c), h.axis(0_c)[-1]);
|
||||
BOOST_TEST_EQ(it->bin(1_c), h.axis(1_c)[0]);
|
||||
BOOST_TEST_EQ(it->value, 1);
|
||||
++it;
|
||||
}
|
||||
BOOST_TEST_EQ(it->operator[](0), 0);
|
||||
BOOST_TEST_EQ(it->operator[](1), 1);
|
||||
BOOST_TEST_EQ(it->bin(0), h.axis(0)[0]);
|
||||
BOOST_TEST_EQ(it->bin(1), h.axis(1)[1]);
|
||||
BOOST_TEST_EQ(it->value, 0);
|
||||
++it;
|
||||
if (include_extra_bins) {
|
||||
BOOST_TEST_EQ(it->operator[](0), 1);
|
||||
BOOST_TEST_EQ(it->operator[](1), 1);
|
||||
BOOST_TEST_EQ(it->bin(0_c), h.axis(0_c)[1]);
|
||||
BOOST_TEST_EQ(it->bin(1_c), h.axis(1_c)[1]);
|
||||
BOOST_TEST_EQ(it->value, 1);
|
||||
++it;
|
||||
BOOST_TEST_EQ(it->operator[](0), -1);
|
||||
BOOST_TEST_EQ(it->operator[](1), 1);
|
||||
BOOST_TEST_EQ(it->bin(0), h.axis(0)[-1]);
|
||||
BOOST_TEST_EQ(it->bin(1), h.axis(1)[1]);
|
||||
BOOST_TEST_EQ(it->value, 0);
|
||||
++it;
|
||||
BOOST_TEST_EQ(it->operator[](0), 0);
|
||||
BOOST_TEST_EQ(it->operator[](1), 2);
|
||||
BOOST_TEST_EQ(it->bin(0), h.axis(0)[0]);
|
||||
BOOST_TEST_EQ(it->bin(1), h.axis(1)[2]);
|
||||
BOOST_TEST_EQ(it->value, 0);
|
||||
++it;
|
||||
BOOST_TEST_EQ(it->operator[](0), 1);
|
||||
BOOST_TEST_EQ(it->operator[](1), 2);
|
||||
BOOST_TEST_EQ(it->bin(0_c), h.axis(0_c)[1]);
|
||||
BOOST_TEST_EQ(it->bin(1_c), h.axis(1_c)[2]);
|
||||
BOOST_TEST_EQ(it->value, 0);
|
||||
++it;
|
||||
BOOST_TEST_EQ(it->operator[](0), -1);
|
||||
BOOST_TEST_EQ(it->operator[](1), 2);
|
||||
BOOST_TEST_EQ(it->bin(0), h.axis(0)[-1]);
|
||||
BOOST_TEST_EQ(it->bin(1), h.axis(1)[2]);
|
||||
BOOST_TEST_EQ(it->value, 0);
|
||||
++it;
|
||||
// imitate iteration order of indexed loop
|
||||
for (int k = 0; k < 4 + b; ++k)
|
||||
for (int j = 0; j < 3; ++j)
|
||||
for (int i = 0; i < 2 + 2*b; ++i) {
|
||||
const auto i2 = i > 2 ? -1 : i;
|
||||
BOOST_TEST_EQ(it->operator[](0), i2);
|
||||
BOOST_TEST_EQ(it->operator[](1), j);
|
||||
BOOST_TEST_EQ(it->operator[](2), k);
|
||||
BOOST_TEST_EQ(it->bin(0_c), h.axis(0_c)[i2]);
|
||||
BOOST_TEST_EQ(it->bin(1_c), h.axis(1_c)[j]);
|
||||
BOOST_TEST_EQ(it->bin(2_c), h.axis(2_c)[k]);
|
||||
BOOST_TEST_EQ(it->value, i2 * 100 + j * 10 + k);
|
||||
++it;
|
||||
}
|
||||
BOOST_TEST(it == ind.end());
|
||||
}
|
||||
@ -149,8 +106,8 @@ int main() {
|
||||
for (int b = 0; b < 2; ++b) {
|
||||
run_1d_tests<static_tag>(b);
|
||||
run_1d_tests<dynamic_tag>(b);
|
||||
run_2d_tests<static_tag>(b);
|
||||
run_2d_tests<dynamic_tag>(b);
|
||||
run_3d_tests<static_tag>(b);
|
||||
run_3d_tests<dynamic_tag>(b);
|
||||
run_density_tests<static_tag>(b);
|
||||
run_density_tests<dynamic_tag>(b);
|
||||
}
|
||||
|
90
test/iteration_bench.cpp
Normal file
90
test/iteration_bench.cpp
Normal file
@ -0,0 +1,90 @@
|
||||
// Copyright 2018 Hans Dembinski
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// (See accompanying file LICENSE_1_0.txt
|
||||
// or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#include <boost/histogram.hpp>
|
||||
#include <benchmark/benchmark.h>
|
||||
#include <vector>
|
||||
|
||||
struct static_tag {};
|
||||
struct dynamic_tag {};
|
||||
|
||||
auto make_histogram(static_tag) {
|
||||
using namespace boost::histogram;
|
||||
return make_histogram_with(
|
||||
std::vector<unsigned>(),
|
||||
axis::integer<>(0, 10),
|
||||
axis::integer<>(0, 10),
|
||||
axis::integer<>(0, 10)
|
||||
);
|
||||
}
|
||||
|
||||
auto make_histogram(dynamic_tag) {
|
||||
using namespace boost::histogram;
|
||||
std::vector<axis::integer<>> axes = {
|
||||
axis::integer<>(0, 10),
|
||||
axis::integer<>(0, 10),
|
||||
axis::integer<>(0, 10)
|
||||
};
|
||||
return make_histogram_with(
|
||||
std::vector<unsigned>(),
|
||||
axes
|
||||
);
|
||||
}
|
||||
|
||||
template <class Tag>
|
||||
static void NaiveForLoop(benchmark::State& state) {
|
||||
auto h = make_histogram(Tag());
|
||||
for (auto _ : state) {
|
||||
for (int i = 0; i < h.axis(0).size(); ++i)
|
||||
for (int j = 0; j < h.axis(1).size(); ++j)
|
||||
for (int k = 0; k < h.axis(2).size(); ++k)
|
||||
benchmark::DoNotOptimize(h.at(i, j, k));
|
||||
}
|
||||
}
|
||||
|
||||
template <class Tag>
|
||||
static void LessNaiveForLoop(benchmark::State& state) {
|
||||
using namespace boost::histogram::literals;
|
||||
auto h = make_histogram(Tag());
|
||||
for (auto _ : state) {
|
||||
for (int i = 0; i < h.axis(0_c).size(); ++i)
|
||||
for (int j = 0; j < h.axis(1_c).size(); ++j)
|
||||
for (int k = 0; k < h.axis(2_c).size(); ++k)
|
||||
benchmark::DoNotOptimize(h.at(i, j, k));
|
||||
}
|
||||
}
|
||||
|
||||
template <class Tag>
|
||||
static void InsiderForLoop(benchmark::State& state) {
|
||||
using namespace boost::histogram::literals;
|
||||
auto h = make_histogram(Tag());
|
||||
for (auto _ : state) {
|
||||
for (int k = 0; k < h.axis(2_c).size(); ++k)
|
||||
for (int j = 0; j < h.axis(1_c).size(); ++j)
|
||||
for (int i = 0; i < h.axis(0_c).size(); ++i)
|
||||
benchmark::DoNotOptimize(h.at(i, j, k));
|
||||
}
|
||||
}
|
||||
|
||||
template <class Tag, bool include_all>
|
||||
static void IndexedLoop(benchmark::State& state) {
|
||||
auto h = make_histogram(Tag());
|
||||
for (auto _ : state) {
|
||||
for (auto x : boost::histogram::indexed(h, include_all))
|
||||
benchmark::DoNotOptimize(x);
|
||||
}
|
||||
}
|
||||
|
||||
BENCHMARK_TEMPLATE(NaiveForLoop, static_tag);
|
||||
BENCHMARK_TEMPLATE(NaiveForLoop, dynamic_tag);
|
||||
BENCHMARK_TEMPLATE(LessNaiveForLoop, static_tag);
|
||||
BENCHMARK_TEMPLATE(LessNaiveForLoop, dynamic_tag);
|
||||
BENCHMARK_TEMPLATE(InsiderForLoop, static_tag);
|
||||
BENCHMARK_TEMPLATE(InsiderForLoop, dynamic_tag);
|
||||
BENCHMARK_TEMPLATE(IndexedLoop, static_tag, false);
|
||||
BENCHMARK_TEMPLATE(IndexedLoop, dynamic_tag, false);
|
||||
BENCHMARK_TEMPLATE(IndexedLoop, static_tag, true);
|
||||
BENCHMARK_TEMPLATE(IndexedLoop, dynamic_tag, true);
|
Loading…
x
Reference in New Issue
Block a user