better test of indexed range adaptor and new benchmark for indexed

This commit is contained in:
Hans Dembinski 2018-12-04 11:11:26 +01:00
parent ab8201eca1
commit 94a3364c83
3 changed files with 139 additions and 76 deletions

View File

@ -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)

View File

@ -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
View 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);