From 49f5ef4c6d1f8be1756926df606e1b16e0488ed7 Mon Sep 17 00:00:00 2001 From: Joana Niermann Date: Fri, 12 Apr 2024 13:27:07 +0200 Subject: [PATCH 1/4] Restore Vc types in vc_aos plugin and add it to benchmarks --- benchmarks/CMakeLists.txt | 21 ++ .../benchmark/vc_aos/data_generator.hpp | 61 +++++ benchmarks/vc_aos/vc_aos_getter.cpp | 93 ++++++++ benchmarks/vc_aos/vc_aos_transform3.cpp | 51 ++++ benchmarks/vc_aos/vc_aos_vector.cpp | 89 +++++++ .../benchmark/vc_soa/data_generator.hpp | 17 +- frontend/vc_vc/include/algebra/vc_vc.hpp | 25 +- math/vc/CMakeLists.txt | 2 +- .../include/algebra/math/impl/vc_getter.hpp | 83 ++++--- .../algebra/math/impl/vc_transform3.hpp | 218 ++++++++---------- .../include/algebra/math/impl/vc_vector.hpp | 80 ++++--- .../common/include/algebra/storage/vector.hpp | 123 ++++++---- .../algebra/storage/impl/vc_array4.hpp | 190 --------------- storage/vc/include/algebra/storage/vc.hpp | 38 +-- tests/common/test_host_basics.hpp | 14 +- tests/vc/vc_cmath.cpp | 8 +- tests/vc/vc_vc.cpp | 20 +- 17 files changed, 633 insertions(+), 500 deletions(-) create mode 100644 benchmarks/vc_aos/include/benchmark/vc_aos/data_generator.hpp create mode 100644 benchmarks/vc_aos/vc_aos_getter.cpp create mode 100644 benchmarks/vc_aos/vc_aos_transform3.cpp create mode 100644 benchmarks/vc_aos/vc_aos_vector.cpp delete mode 100644 storage/vc/include/algebra/storage/impl/vc_array4.hpp diff --git a/benchmarks/CMakeLists.txt b/benchmarks/CMakeLists.txt index 950d8b71..f742a5c9 100644 --- a/benchmarks/CMakeLists.txt +++ b/benchmarks/CMakeLists.txt @@ -61,6 +61,27 @@ if( ALGEBRA_PLUGINS_INCLUDE_EIGEN ) endif() if( ALGEBRA_PLUGINS_INCLUDE_VC ) + add_library( algebra_bench_vc_aos INTERFACE ) + target_include_directories( algebra_bench_vc_aos INTERFACE + "$" ) + target_link_libraries(algebra_bench_vc_aos INTERFACE + algebra::vc_vc + algebra::common_storage) + add_library( algebra::bench_vc_aos ALIAS algebra_bench_vc_aos ) + + algebra_add_benchmark( vc_aos_getter + "vc_aos/vc_aos_getter.cpp" + LINK_LIBRARIES benchmark::benchmark algebra::bench_common + algebra::bench_vc_aos algebra::vc_vc ) + algebra_add_benchmark( vc_aos_vector + "vc_aos/vc_aos_vector.cpp" + LINK_LIBRARIES benchmark::benchmark algebra::bench_common + algebra::bench_vc_aos algebra::vc_vc ) + algebra_add_benchmark( vc_aos_transform3 + "vc_aos/vc_aos_transform3.cpp" + LINK_LIBRARIES benchmark::benchmark algebra::bench_common + algebra::bench_vc_aos algebra::vc_vc ) + if( NOT "${CMAKE_CXX_COMPILER_ID}" MATCHES "AppleClang" ) add_library( algebra_bench_vc_soa INTERFACE ) target_include_directories( algebra_bench_vc_soa INTERFACE diff --git a/benchmarks/vc_aos/include/benchmark/vc_aos/data_generator.hpp b/benchmarks/vc_aos/include/benchmark/vc_aos/data_generator.hpp new file mode 100644 index 00000000..6ec3e753 --- /dev/null +++ b/benchmarks/vc_aos/include/benchmark/vc_aos/data_generator.hpp @@ -0,0 +1,61 @@ +/** Algebra plugins library, part of the ACTS project + * + * (c) 2024 CERN for the benefit of the ACTS project + * + * Mozilla Public License Version 2.0 + */ + +#pragma once + +// Project include(s) +#include "algebra/vc_vc.hpp" + +// System include(s) +#include +#include + +namespace algebra { + +/// Fill a @c Vc::SimdArray based vector with random values +template +inline void fill_random_vec(std::vector &collection) { + + // Generate a vector of the right type with random values + auto rand_obj = [&]() { + return vector_aos_t{vector_aos_t::array_type::Random()}; + }; + + collection.resize(collection.capacity()); + std::generate(collection.begin(), collection.end(), rand_obj); +} + +/// Fill a @c Vc::SimdArray based transform3 with random values +template +inline void fill_random_trf(std::vector &collection) { + // Generate a random, but valid affine transformation + auto rand_obj = []() { + using vector_t = typename transform3_t::vector3; + vector_t x_axis, z_axis, t; + + x_axis = vector_t{vector_t::array_type::Random()}; + x_axis = vector::normalize(x_axis); + + z_axis = vector_t{vector_t::array_type::Random()}; + z_axis = vector::normalize(z_axis); + + t = vector_t{vector_t::array_type::Random()}; + t = vector::normalize(t); + + // Gram-Schmidt projection + typename transform3_t::scalar_type coeff = + vector::dot(x_axis, z_axis) / getter::norm(x_axis); + z_axis = x_axis - coeff * z_axis; + + return transform3_t{t, x_axis, vector::normalize(z_axis)}; + }; + + collection.resize(collection.capacity()); + std::generate(collection.begin(), collection.end(), rand_obj); +} + +} // namespace algebra diff --git a/benchmarks/vc_aos/vc_aos_getter.cpp b/benchmarks/vc_aos/vc_aos_getter.cpp new file mode 100644 index 00000000..35a4624f --- /dev/null +++ b/benchmarks/vc_aos/vc_aos_getter.cpp @@ -0,0 +1,93 @@ +/** Algebra plugins library, part of the ACTS project + * + * (c) 2024 CERN for the benefit of the ACTS project + * + * Mozilla Public License Version 2.0 + */ + +// Project include(s) +#include "algebra/vc_vc.hpp" +#include "benchmark/common/benchmark_getter.hpp" +#include "benchmark/vc_aos/data_generator.hpp" + +// Benchmark include +#include + +// System include(s) +#include + +using namespace algebra; + +/// Run vector benchmarks +int main(int argc, char** argv) { + + constexpr std::size_t n_samples{160000}; + constexpr std::size_t n_warmup{static_cast(0.1 * n_samples)}; + + // + // Prepare benchmarks + // + algebra::benchmark_base::configuration cfg{}; + cfg.n_samples(n_samples).n_warmup(n_warmup); + cfg.do_sleep(false); + + vector_unaryOP_bm v_phi_s{cfg}; + vector_unaryOP_bm v_theta_s{cfg}; + vector_unaryOP_bm v_perp_s{cfg}; + vector_unaryOP_bm v_norm_s{cfg}; + vector_unaryOP_bm v_eta_s{cfg}; + + vector_unaryOP_bm v_phi_d{cfg}; + vector_unaryOP_bm v_theta_d{cfg}; + vector_unaryOP_bm v_perp_d{cfg}; + vector_unaryOP_bm v_norm_d{cfg}; + vector_unaryOP_bm v_eta_d{cfg}; + + std::cout << "Algebra-Plugins 'getter' benchmark (Vc AoS)\n" + << "-------------------------------------------\n\n" + << cfg; + + // + // Register all benchmarks + // + ::benchmark::RegisterBenchmark((v_phi_s.name() + "_single").c_str(), v_phi_s) + ->MeasureProcessCPUTime() + ->ThreadPerCpu(); + ::benchmark::RegisterBenchmark((v_phi_d.name() + "_double").c_str(), v_phi_d) + ->MeasureProcessCPUTime() + ->ThreadPerCpu(); + ::benchmark::RegisterBenchmark((v_theta_s.name() + "_single").c_str(), + v_theta_s) + ->MeasureProcessCPUTime() + ->ThreadPerCpu(); + ::benchmark::RegisterBenchmark((v_theta_d.name() + "_double").c_str(), + v_theta_d) + ->MeasureProcessCPUTime() + ->ThreadPerCpu(); + ::benchmark::RegisterBenchmark((v_perp_s.name() + "_single").c_str(), + v_perp_s) + ->MeasureProcessCPUTime() + ->ThreadPerCpu(); + ::benchmark::RegisterBenchmark((v_perp_d.name() + "_double").c_str(), + v_perp_d) + ->MeasureProcessCPUTime() + ->ThreadPerCpu(); + ::benchmark::RegisterBenchmark((v_norm_s.name() + "_single").c_str(), + v_norm_s) + ->MeasureProcessCPUTime() + ->ThreadPerCpu(); + ::benchmark::RegisterBenchmark((v_norm_d.name() + "_double").c_str(), + v_norm_d) + ->MeasureProcessCPUTime() + ->ThreadPerCpu(); + ::benchmark::RegisterBenchmark((v_eta_s.name() + "_single").c_str(), v_eta_s) + ->MeasureProcessCPUTime() + ->ThreadPerCpu(); + ::benchmark::RegisterBenchmark((v_eta_d.name() + "_double").c_str(), v_eta_d) + ->MeasureProcessCPUTime() + ->ThreadPerCpu(); + + ::benchmark::Initialize(&argc, argv); + ::benchmark::RunSpecifiedBenchmarks(); + ::benchmark::Shutdown(); +} diff --git a/benchmarks/vc_aos/vc_aos_transform3.cpp b/benchmarks/vc_aos/vc_aos_transform3.cpp new file mode 100644 index 00000000..d7a2bcee --- /dev/null +++ b/benchmarks/vc_aos/vc_aos_transform3.cpp @@ -0,0 +1,51 @@ +/** Algebra plugins library, part of the ACTS project + * + * (c) 2024 CERN for the benefit of the ACTS project + * + * Mozilla Public License Version 2.0 + */ + +// Project include(s) +#include "algebra/vc_vc.hpp" +#include "benchmark/common/benchmark_transform3.hpp" +#include "benchmark/vc_aos/data_generator.hpp" + +// Benchmark include +#include + +using namespace algebra; + +/// Run vector benchmarks +int main(int argc, char** argv) { + + constexpr std::size_t n_samples{160000}; + + // + // Prepare benchmarks + // + algebra::benchmark_base::configuration cfg{}; + cfg.n_samples(n_samples).n_warmup( + static_cast(0.1 * cfg.n_samples())); + cfg.do_sleep(false); + + transform3_bm> v_trf_s{cfg}; + transform3_bm> v_trf_d{cfg}; + + std::cout << "Algebra-Plugins 'transform3' benchmark (Vc AoS)\n" + << "-------------------------------------------\n\n" + << cfg; + + // + // Register all benchmarks + // + ::benchmark::RegisterBenchmark((v_trf_s.name() + "_single").c_str(), v_trf_s) + ->MeasureProcessCPUTime() + ->ThreadPerCpu(); + ::benchmark::RegisterBenchmark((v_trf_d.name() + "_double").c_str(), v_trf_d) + ->MeasureProcessCPUTime() + ->ThreadPerCpu(); + + ::benchmark::Initialize(&argc, argv); + ::benchmark::RunSpecifiedBenchmarks(); + ::benchmark::Shutdown(); +} diff --git a/benchmarks/vc_aos/vc_aos_vector.cpp b/benchmarks/vc_aos/vc_aos_vector.cpp new file mode 100644 index 00000000..92b78b99 --- /dev/null +++ b/benchmarks/vc_aos/vc_aos_vector.cpp @@ -0,0 +1,89 @@ +/** Algebra plugins library, part of the ACTS project + * + * (c) 2024 CERN for the benefit of the ACTS project + * + * Mozilla Public License Version 2.0 + */ + +// Project include(s) +#include "algebra/vc_vc.hpp" +#include "benchmark/common/benchmark_vector.hpp" +#include "benchmark/vc_aos/data_generator.hpp" + +// Benchmark include +#include + +using namespace algebra; + +/// Run vector benchmarks +int main(int argc, char** argv) { + + constexpr std::size_t n_samples{160000}; + + // + // Prepare benchmarks + // + algebra::benchmark_base::configuration cfg{}; + cfg.n_samples(n_samples).n_warmup( + static_cast(0.1 * cfg.n_samples())); + cfg.do_sleep(false); + + vector_binaryOP_bm v_add_s{cfg}; + vector_binaryOP_bm v_sub_s{cfg}; + vector_binaryOP_bm v_dot_s{cfg}; + vector_binaryOP_bm v_cross_s{cfg}; + vector_unaryOP_bm v_normalize_s{cfg}; + + vector_binaryOP_bm v_add_d{cfg}; + vector_binaryOP_bm v_sub_d{cfg}; + vector_binaryOP_bm v_dot_d{cfg}; + vector_binaryOP_bm v_cross_d{cfg}; + vector_unaryOP_bm v_normalize_d{ + cfg}; + + std::cout << "Algebra-Plugins 'vector' benchmark (Vc SoA)\n" + << "-------------------------------------------\n\n" + << cfg; + + // + // Register all benchmarks + // + ::benchmark::RegisterBenchmark((v_add_s.name() + "_single").c_str(), v_add_s) + ->MeasureProcessCPUTime() + ->ThreadPerCpu(); + ::benchmark::RegisterBenchmark((v_add_d.name() + "_double").c_str(), v_add_d) + ->MeasureProcessCPUTime() + ->ThreadPerCpu(); + ::benchmark::RegisterBenchmark((v_sub_s.name() + "_single").c_str(), v_sub_s) + ->MeasureProcessCPUTime() + ->ThreadPerCpu(); + ::benchmark::RegisterBenchmark((v_sub_d.name() + "_double").c_str(), v_sub_d) + ->MeasureProcessCPUTime() + ->ThreadPerCpu(); + ::benchmark::RegisterBenchmark((v_dot_s.name() + "_single").c_str(), v_dot_s) + ->MeasureProcessCPUTime() + ->ThreadPerCpu(); + ::benchmark::RegisterBenchmark((v_dot_d.name() + "_double").c_str(), v_dot_d) + ->MeasureProcessCPUTime() + ->ThreadPerCpu(); + ::benchmark::RegisterBenchmark((v_cross_s.name() + "_single").c_str(), + v_cross_s) + ->MeasureProcessCPUTime() + ->ThreadPerCpu(); + ::benchmark::RegisterBenchmark((v_cross_d.name() + "_double").c_str(), + v_cross_d) + ->MeasureProcessCPUTime() + ->ThreadPerCpu(); + ::benchmark::RegisterBenchmark((v_normalize_s.name() + "_single").c_str(), + v_normalize_s) + ->MeasureProcessCPUTime() + ->ThreadPerCpu(); + ::benchmark::RegisterBenchmark((v_normalize_d.name() + "_double").c_str(), + v_normalize_d) + ->MeasureProcessCPUTime() + ->ThreadPerCpu(); + + ::benchmark::Initialize(&argc, argv); + ::benchmark::RunSpecifiedBenchmarks(); + ::benchmark::Shutdown(); +} diff --git a/benchmarks/vc_soa/include/benchmark/vc_soa/data_generator.hpp b/benchmarks/vc_soa/include/benchmark/vc_soa/data_generator.hpp index e0fdd4fe..b519a795 100644 --- a/benchmarks/vc_soa/include/benchmark/vc_soa/data_generator.hpp +++ b/benchmarks/vc_soa/include/benchmark/vc_soa/data_generator.hpp @@ -16,21 +16,6 @@ namespace algebra { -// @todo Leave for later - -/// Fill a @c Vc::SimdArray based vector with random values -/*template -inline void fill_random_vec( - std::vector, allocator_t>> - &collection) { - - using vector_t = vector3_s; - // Generate a vector of the right type with random values - auto rand_obj = [&]() { return vector_t{vector_t::array_type::Random()}; }; - - std::generate(collection.begin(), collection.end(), rand_obj); -}*/ - /// Fill a @c Vc::Vector based vector with random values template inline void fill_random_vec(std::vector &collection) { @@ -80,4 +65,4 @@ inline void fill_random_trf(std::vector &collection) { std::generate(collection.begin(), collection.end(), rand_obj); } -} // namespace algebra \ No newline at end of file +} // namespace algebra diff --git a/frontend/vc_vc/include/algebra/vc_vc.hpp b/frontend/vc_vc/include/algebra/vc_vc.hpp index d5d258b7..f044e3ef 100644 --- a/frontend/vc_vc/include/algebra/vc_vc.hpp +++ b/frontend/vc_vc/include/algebra/vc_vc.hpp @@ -64,14 +64,13 @@ using vc::math::theta; /// Function extracting a slice from the matrix used by /// @c algebra::vc::transform3 template = true> -ALGEBRA_HOST_DEVICE inline Vc::array vector( - const vc::transform3::matrix44& m, - std::size_t +ALGEBRA_HOST_DEVICE inline auto vector(const vc::transform3::matrix44& m, + std::size_t #ifndef NDEBUG - row + row #endif // not NDEBUG - , - std::size_t col) { + , + std::size_t col) { assert(row == 0); assert(col < 4); @@ -92,7 +91,7 @@ ALGEBRA_HOST_DEVICE inline Vc::array vector( /// Function extracting a slice from the matrix used by /// @c algebra::vc::transform3 template = true> -ALGEBRA_HOST_DEVICE inline Vc::array vector( +ALGEBRA_HOST_DEVICE inline auto vector( const vc::transform3::matrix44& m, std::size_t #ifndef NDEBUG @@ -151,7 +150,7 @@ using array_type = vc::storage_type; template using matrix_type = vc::matrix_type; -template +/*template using element_getter = cmath::element_getter; template @@ -163,12 +162,12 @@ template , block_getter>; + element_getter, block_getter>;*/ namespace determinant { // determinant aggregation -template +/*template using actor = cmath::matrix::determinant::actor; @@ -224,9 +223,9 @@ using hard_coded = // preset(s) as standard option(s) for user's convenience template using preset0 = - actor, hard_coded>; + actor, hard_coded>;*/ -} // namespace inverse +} // namespace determinant } // namespace matrix -} // namespace algebra \ No newline at end of file +} // namespace algebra diff --git a/math/vc/CMakeLists.txt b/math/vc/CMakeLists.txt index 5b5b6a6a..20ab90e8 100644 --- a/math/vc/CMakeLists.txt +++ b/math/vc/CMakeLists.txt @@ -11,7 +11,7 @@ algebra_add_library( algebra_vc_math vc_math "include/algebra/math/impl/vc_transform3.hpp" "include/algebra/math/impl/vc_vector.hpp" ) target_link_libraries( algebra_vc_math - INTERFACE Vc::Vc algebra::common algebra::common_math + INTERFACE Vc::Vc algebra::common algebra::common_math algebra::vc_storage algebra::cmath_math ) algebra_test_public_headers( algebra_vc_math "algebra/math/vc.hpp" ) diff --git a/math/vc/include/algebra/math/impl/vc_getter.hpp b/math/vc/include/algebra/math/impl/vc_getter.hpp index 0063d225..ac28f527 100644 --- a/math/vc/include/algebra/math/impl/vc_getter.hpp +++ b/math/vc/include/algebra/math/impl/vc_getter.hpp @@ -1,6 +1,6 @@ /** Algebra plugins library, part of the ACTS project * - * (c) 2020-2022 CERN for the benefit of the ACTS project + * (c) 2020-2024 CERN for the benefit of the ACTS project * * Mozilla Public License Version 2.0 */ @@ -11,56 +11,75 @@ #include "algebra/math/common.hpp" #include "algebra/math/impl/vc_vector.hpp" #include "algebra/qualifiers.hpp" +#include "algebra/storage/vector.hpp" + +// Vc include(s). +#ifdef _MSC_VER +#pragma warning(push, 0) +#endif // MSVC +#include +#ifdef _MSC_VER +#pragma warning(pop) +#endif // MSVC namespace algebra::vc::math { -/** This method retrieves phi from a vector, vector base with rows >= 2 - * - * @param v the input vector - **/ -template +/// This method retrieves phi from a vector, vector base with rows >= 2 +/// +/// @param v the input vector +template ::value || + algebra::detail::is_storage_vector_v), + bool> = true> ALGEBRA_HOST_DEVICE inline auto phi(const vector_type &v) noexcept { return algebra::math::atan2(v[1], v[0]); } -/** This method retrieves theta from a vector, vector base with rows >= 3 - * - * @param v the input vector - **/ -template -ALGEBRA_HOST_DEVICE inline auto theta(const vector_type &v) noexcept { +/// This method retrieves the perpendicular magnitude of a vector with rows >= 2 +/// +/// @param v the input vector +template ::value || + algebra::detail::is_storage_vector_v), + bool> = true> +ALGEBRA_HOST_DEVICE inline auto perp(const vector_type &v) noexcept { - return algebra::math::atan2(algebra::math::sqrt(v[0] * v[0] + v[1] * v[1]), - v[2]); + return algebra::math::sqrt(v[0] * v[0] + v[1] * v[1]); } -/** This method retrieves the perpendicular magnitude of a vector with rows >= 2 - * - * @param v the input vector - **/ -template -ALGEBRA_HOST_DEVICE inline auto perp(const vector_type &v) noexcept { +/// This method retrieves theta from a vector, vector base with rows >= 3 +/// +/// @param v the input vector +template ::value || + algebra::detail::is_storage_vector_v), + bool> = true> +ALGEBRA_HOST_DEVICE inline auto theta(const vector_type &v) noexcept { - return algebra::math::sqrt(v[0] * v[0] + v[1] * v[1]); + return algebra::math::atan2(perp(v), v[2]); } -/** This method retrieves the norm of a vector, no dimension restriction - * - * @param v the input vector - **/ -template +/// This method retrieves the norm of a vector, no dimension restriction +/// +/// @param v the input vector +template ::value || + algebra::detail::is_storage_vector_v), + bool> = true> ALGEBRA_HOST_DEVICE inline auto norm(const vector_type &v) { return algebra::math::sqrt(dot(v, v)); } -/** This method retrieves the pseudo-rapidity from a vector or vector base with - * rows >= 3 - * - * @param v the input vector - **/ -template +/// This method retrieves the pseudo-rapidity from a vector or vector base with +/// rows >= 3 +/// +/// @param v the input vector +template ::value || + algebra::detail::is_storage_vector_v), + bool> = true> ALGEBRA_HOST_DEVICE inline auto eta(const vector_type &v) noexcept { return algebra::math::atanh(v[2] / norm(v)); diff --git a/math/vc/include/algebra/math/impl/vc_transform3.hpp b/math/vc/include/algebra/math/impl/vc_transform3.hpp index eeb34a24..8fcb99d7 100644 --- a/math/vc/include/algebra/math/impl/vc_transform3.hpp +++ b/math/vc/include/algebra/math/impl/vc_transform3.hpp @@ -1,6 +1,6 @@ /** Algebra plugins library, part of the ACTS project * - * (c) 2020-2022 CERN for the benefit of the ACTS project + * (c) 2020-2024 CERN for the benefit of the ACTS project * * Mozilla Public License Version 2.0 */ @@ -26,8 +26,6 @@ namespace algebra::vc::math { -using cmath::cross; - namespace internal { /// 4x4 matrix type used by @c algebra::vc::math::transform3 @@ -90,8 +88,7 @@ struct element_getter { } // namespace internal -/** Transform wrapper class to ensure standard API within differnt plugins - **/ +/// Transform wrapper class to ensure standard API within differnt plugins template