Skip to content

Commit

Permalink
This adds a new vector wrapper class that allows for an SoA layout, i…
Browse files Browse the repository at this point in the history
…n particular, for the Vc::Vector type. Also adds benchmarks to compare to the std::array backend
  • Loading branch information
niermann999 committed Mar 16, 2023
1 parent c4e5aa4 commit 709cc16
Show file tree
Hide file tree
Showing 35 changed files with 2,064 additions and 12 deletions.
4 changes: 4 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -30,3 +30,7 @@
*.exe
*.out
*.app

# Local folders
/bin
/build
72 changes: 72 additions & 0 deletions benchmarks/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
# Algebra plugins library, part of the ACTS project (R&D line)
#
# (c) 2023 CERN for the benefit of the ACTS project
#
# Mozilla Public License Version 2.0

# Set the default C++ compiler flags.
include( algebra-plugins-compiler-options-cpp )

# Set up an INTERFACE library for the common header(s).
add_library( algebra_bench_common INTERFACE )
target_include_directories( algebra_bench_common INTERFACE
"${CMAKE_CURRENT_SOURCE_DIR}/common/include" )
if( "${CMAKE_CXX_COMPILER_ID}" MATCHES "MSVC" )
target_compile_definitions( algebra_bench_common INTERFACE
-D_USE_MATH_DEFINES )
endif()
add_library( algebra::bench_common ALIAS algebra_bench_common )

# Set up all of the (available) "host" benchmarks.
add_library( algebra_bench_array INTERFACE )
target_include_directories( algebra_bench_array INTERFACE
"$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/array/include>" )
target_link_libraries(algebra_bench_array INTERFACE algebra::array_cmath
algebra::common_storage)
add_library( algebra::bench_array ALIAS algebra_bench_array )

algebra_add_benchmark( array_getter
"array/array_getter.cpp"
LINK_LIBRARIES benchmark::benchmark algebra::bench_common
algebra::bench_array algebra::array_cmath )
algebra_add_benchmark( array_vector
"array/array_vector.cpp"
LINK_LIBRARIES benchmark::benchmark algebra::bench_common
algebra::bench_array algebra::array_cmath )

if( ALGEBRA_PLUGINS_INCLUDE_EIGEN )
add_library( algebra_bench_eigen INTERFACE )
target_include_directories( algebra_bench_eigen INTERFACE
"$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/eigen/include>" )
target_link_libraries(algebra_bench_eigen INTERFACE algebra::eigen_eigen
algebra::common_storage)
add_library( algebra::bench_eigen ALIAS algebra_bench_eigen )

algebra_add_benchmark( eigen_getter
"eigen/eigen_getter.cpp"
LINK_LIBRARIES benchmark::benchmark algebra::bench_common
algebra::bench_eigen algebra::eigen_eigen )
algebra_add_benchmark( eigen_vector
"eigen/eigen_vector.cpp"
LINK_LIBRARIES benchmark::benchmark algebra::bench_common
algebra::bench_eigen algebra::eigen_eigen )
endif()

if( ALGEBRA_PLUGINS_INCLUDE_VC )
add_library( algebra_bench_vc INTERFACE )
target_include_directories( algebra_bench_vc INTERFACE
"$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/vc/include>" )
target_link_libraries(algebra_bench_vc INTERFACE algebra::vc_vc
algebra::vc_soa
algebra::common_storage)
add_library( algebra::bench_vc ALIAS algebra_bench_vc )

algebra_add_benchmark( vc_getter
"vc/vc_soa_getter.cpp"
LINK_LIBRARIES benchmark::benchmark algebra::bench_common
algebra::bench_vc algebra::vc_vc algebra::vc_soa )
algebra_add_benchmark( vc_vector
"vc/vc_soa_vector.cpp"
LINK_LIBRARIES benchmark::benchmark algebra::bench_common
algebra::bench_vc algebra::vc_vc algebra::vc_soa )
endif()
93 changes: 93 additions & 0 deletions benchmarks/array/array_getter.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
/** Algebra plugins library, part of the ACTS project
*
* (c) 2023 CERN for the benefit of the ACTS project
*
* Mozilla Public License Version 2.0
*/

// Project include(s)
#include "algebra/array_cmath.hpp"
#include "benchmark/array/data_generator.hpp"
#include "benchmark/common/benchmark_getter.hpp"

// Benchmark include
#include <benchmark/benchmark.h>

// System include(s)
#include <string>

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<std::size_t>(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<array::vector3, float, bench_op::phi> v_phi_s{cfg};
vector_unaryOP_bm<array::vector3, float, bench_op::theta> v_theta_s{cfg};
vector_unaryOP_bm<array::vector3, float, bench_op::perp> v_perp_s{cfg};
vector_unaryOP_bm<array::vector3, float, bench_op::norm> v_norm_s{cfg};
vector_unaryOP_bm<array::vector3, float, bench_op::eta> v_eta_s{cfg};

vector_unaryOP_bm<array::vector3, double, bench_op::phi> v_phi_d{cfg};
vector_unaryOP_bm<array::vector3, double, bench_op::theta> v_theta_d{cfg};
vector_unaryOP_bm<array::vector3, double, bench_op::perp> v_perp_d{cfg};
vector_unaryOP_bm<array::vector3, double, bench_op::norm> v_norm_d{cfg};
vector_unaryOP_bm<array::vector3, double, bench_op::eta> v_eta_d{cfg};

std::cout << "Algebra-Plugins 'getter' benchmark (std::array)\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();
}
93 changes: 93 additions & 0 deletions benchmarks/array/array_vector.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
/** Algebra plugins library, part of the ACTS project
*
* (c) 2023 CERN for the benefit of the ACTS project
*
* Mozilla Public License Version 2.0
*/

// Project include(s)
#include "algebra/array_cmath.hpp"
#include "benchmark/array/data_generator.hpp"
#include "benchmark/common/benchmark_vector.hpp"

// Benchmark include
#include <benchmark/benchmark.h>

// System include(s)
#include <string>

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<std::size_t>(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_binaryOP_bm<array::vector3, float, bench_op::add> v_add_s{cfg};
vector_binaryOP_bm<array::vector3, float, bench_op::sub> v_sub_s{cfg};
vector_binaryOP_bm<array::vector3, float, bench_op::dot> v_dot_s{cfg};
vector_binaryOP_bm<array::vector3, float, bench_op::cross> v_cross_s{cfg};
vector_unaryOP_bm<array::vector3, float, bench_op::normalize> v_normalize_s{
cfg};

vector_binaryOP_bm<array::vector3, double, bench_op::add> v_add_d{cfg};
vector_binaryOP_bm<array::vector3, double, bench_op::sub> v_sub_d{cfg};
vector_binaryOP_bm<array::vector3, double, bench_op::dot> v_dot_d{cfg};
vector_binaryOP_bm<array::vector3, double, bench_op::cross> v_cross_d{cfg};
vector_unaryOP_bm<array::vector3, double, bench_op::normalize> v_normalize_d{
cfg};

std::cout << "Algebra-Plugins 'vector' benchmark (std::array)\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();
}
36 changes: 36 additions & 0 deletions benchmarks/array/include/benchmark/array/data_generator.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
/** Algebra plugins library, part of the ACTS project
*
* (c) 2023 CERN for the benefit of the ACTS project
*
* Mozilla Public License Version 2.0
*/

#pragma once

// Project include(s)
#include "algebra/storage/array.hpp"
#include "algebra/storage/vector.hpp"

// System include(s)
#include <algorithm>
#include <random>
#include <vector>

namespace algebra {

/// Fill an @c std::array based vector with random values
template <typename vector_t>
inline void fill_random(std::vector<vector_t> &collection) {

// Generate a vector of the right type with random values
std::random_device rd;
std::mt19937 mt(rd());
std::uniform_real_distribution<typename vector_t::value_type> dist(0.f, 1.f);

auto rand_obj = [&]() { return vector_t{dist(mt), dist(mt), dist(mt)}; };

collection.resize(collection.capacity());
std::generate(collection.begin(), collection.end(), rand_obj);
}

} // namespace algebra
Loading

0 comments on commit 709cc16

Please sign in to comment.