Skip to content

Commit

Permalink
Intorduce concepts (#132)
Browse files Browse the repository at this point in the history
This PR adds concepts for the main linear algebra types and constrains as many template parameters as possible. Also switches out the std::enable_if instances against requires clauses
  • Loading branch information
niermann999 authored Nov 25, 2024
1 parent 254ea58 commit bf37559
Show file tree
Hide file tree
Showing 70 changed files with 1,271 additions and 1,075 deletions.
7 changes: 4 additions & 3 deletions benchmarks/array/include/benchmark/array/data_generator.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@

// Project include(s)
#include "algebra/array_cmath.hpp"
#include "algebra/concepts.hpp"

// System include(s)
#include <algorithm>
Expand All @@ -18,7 +19,7 @@
namespace algebra {

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

// Generate a vector of the right type with random values
Expand All @@ -33,7 +34,7 @@ inline void fill_random_vec(std::vector<vector_t> &collection) {
}

/// Fill a @c std::array based transform3 with random values
template <typename transform3_t>
template <concepts::transform3D transform3_t>
inline void fill_random_trf(std::vector<transform3_t> &collection) {

using vector_t = typename transform3_t::vector3;
Expand Down Expand Up @@ -64,7 +65,7 @@ inline void fill_random_trf(std::vector<transform3_t> &collection) {
}

/// Fill a @c std::array based matrix with random values
template <typename matrix_t>
template <concepts::matrix matrix_t>
inline void fill_random_matrix(std::vector<matrix_t> &collection) {

using scalar_t = typename matrix_t::value_type::value_type;
Expand Down
26 changes: 14 additions & 12 deletions benchmarks/common/include/benchmark/common/benchmark_matrix.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,14 +17,14 @@

namespace algebra {

template <typename matrix_t>
template <concepts::matrix matrix_t>
void fill_random_matrix(std::vector<matrix_t>&);

template <typename vector_t>
template <concepts::vector vector_t>
void fill_random_vec(std::vector<vector_t>&);

/// Benchmark for matrix operations
template <typename matrix_t>
template <concepts::matrix matrix_t>
struct matrix_bm : public benchmark_base {

/// Prefix for the benchmark name
Expand Down Expand Up @@ -59,8 +59,9 @@ struct matrix_bm : public benchmark_base {
};

/// Benchmark operations on a single matrix (transpose, inverse etc)
template <typename matrix_t, typename unaryOP>
struct matrix_unaryOP_bm : public matrix_bm<matrix_t> {
template <concepts::matrix matrix_t, typename unaryOP>
requires std::invocable<unaryOP, matrix_t> struct matrix_unaryOP_bm
: public matrix_bm<matrix_t> {
using base_type = matrix_bm<matrix_t>;

matrix_unaryOP_bm() = delete;
Expand Down Expand Up @@ -90,8 +91,9 @@ struct matrix_unaryOP_bm : public matrix_bm<matrix_t> {
};

/// Benchmark elementwise addition/subtraction/multiplication of matrices
template <typename matrix_t, typename binaryOP>
struct matrix_binaryOP_bm : public matrix_bm<matrix_t> {
template <concepts::matrix matrix_t, typename binaryOP>
requires std::invocable<binaryOP, matrix_t, matrix_t> struct matrix_binaryOP_bm
: public matrix_bm<matrix_t> {
using base_type = matrix_bm<matrix_t>;

matrix_binaryOP_bm() = delete;
Expand Down Expand Up @@ -121,7 +123,7 @@ struct matrix_binaryOP_bm : public matrix_bm<matrix_t> {
};

/// Benchmark matrix vector multiplication
template <typename matrix_t, typename vector_t>
template <concepts::matrix matrix_t, concepts::vector vector_t>
struct matrix_vector_bm : public matrix_bm<matrix_t> {
using base_type = matrix_bm<matrix_t>;

Expand Down Expand Up @@ -162,29 +164,29 @@ namespace bench_op {

struct add {
inline static const std::string name{"add"};
template <typename matrix_t>
template <concepts::matrix matrix_t>
matrix_t operator()(const matrix_t& a, const matrix_t& b) const {
return a + b;
}
};
struct sub {
inline static const std::string name{"sub"};
template <typename matrix_t>
template <concepts::matrix matrix_t>
matrix_t operator()(const matrix_t& a, const matrix_t& b) const {
return a - b;
}
};
struct mul {
inline static const std::string name{"mul"};
template <typename matrix_t>
template <concepts::matrix matrix_t>
matrix_t operator()(const matrix_t& a, const matrix_t& b) const {
return a * b;
}
};

struct transpose {
inline static const std::string name{"transpose"};
template <typename matrix_t>
template <concepts::matrix matrix_t>
auto operator()(const matrix_t& a) const {
return algebra::matrix::transpose(a);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,11 +19,11 @@

namespace algebra {

template <typename transform3_t>
template <concepts::transform3D transform3_t>
void fill_random_trf(std::vector<transform3_t>&);

/// Benchmark for vector operations
template <typename transform3_t>
template <concepts::transform3D transform3_t>
struct transform3_bm : public vector_bm<typename transform3_t::vector3> {
private:
using base_type = vector_bm<typename transform3_t::vector3>;
Expand Down
25 changes: 14 additions & 11 deletions benchmarks/common/include/benchmark/common/benchmark_vector.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,11 +20,11 @@

namespace algebra {

template <typename vector_t>
template <concepts::vector vector_t>
void fill_random_vec(std::vector<vector_t> &);

/// Benchmark for vector operations
template <typename vector_t>
template <concepts::vector vector_t>
struct vector_bm : public benchmark_base {

/// Prefix for the benchmark name
Expand Down Expand Up @@ -57,9 +57,10 @@ struct vector_bm : public benchmark_base {
};

/// Benchmark elementwise addition of vectors
template <template <typename> class vector_t, typename scalar_t,
template <template <typename> class vector_t, concepts::scalar scalar_t,
typename unaryOP>
struct vector_unaryOP_bm : public vector_bm<vector_t<scalar_t>> {
requires std::invocable<unaryOP, vector_t<scalar_t>> struct vector_unaryOP_bm
: public vector_bm<vector_t<scalar_t>> {
using base_type = vector_bm<vector_t<scalar_t>>;

vector_unaryOP_bm() = delete;
Expand Down Expand Up @@ -89,9 +90,11 @@ struct vector_unaryOP_bm : public vector_bm<vector_t<scalar_t>> {
};

/// Benchmark elementwise addition of vectors
template <template <typename> class vector_t, typename scalar_t,
template <template <typename> class vector_t, concepts::scalar scalar_t,
typename binaryOP>
struct vector_binaryOP_bm : public vector_bm<vector_t<scalar_t>> {
requires std::invocable<binaryOP, vector_t<scalar_t>,
vector_t<scalar_t>> struct vector_binaryOP_bm
: public vector_bm<vector_t<scalar_t>> {
using base_type = vector_bm<vector_t<scalar_t>>;

vector_binaryOP_bm() = delete;
Expand Down Expand Up @@ -126,28 +129,28 @@ namespace bench_op {

struct add {
inline static const std::string name{"add"};
template <typename vector_t>
template <concepts::vector vector_t>
auto operator()(const vector_t &a, const vector_t &b) const {
return a + b;
}
};
struct sub {
inline static const std::string name{"sub"};
template <typename vector_t>
template <concepts::vector vector_t>
auto operator()(const vector_t &a, const vector_t &b) const {
return a - b;
}
};
struct dot {
inline static const std::string name{"dot"};
template <typename vector_t>
template <concepts::vector vector_t>
auto operator()(const vector_t &a, const vector_t &b) const {
return algebra::vector::dot(a, b);
}
};
struct cross {
inline static const std::string name{"cross"};
template <typename vector_t>
template <concepts::vector vector_t>
auto operator()(const vector_t &a, const vector_t &b) const {
return algebra::vector::cross(a, b);
}
Expand All @@ -157,7 +160,7 @@ struct cross {
#define ALGEBRA_PLUGINS_BENCH_VECTOR(OP) \
struct OP { \
inline static const std::string name{#OP}; \
template <typename vector_t> \
template <concepts::vector vector_t> \
auto operator()(const vector_t &a) const { \
return algebra::vector::OP(a); \
} \
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,9 @@

#pragma once

// Project include(s)
#include "benchmark_base.hpp"

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

Expand All @@ -15,8 +18,9 @@

namespace algebra {

template <typename benchmark_t, typename config_t>
void register_benchmark(const config_t& cfg, const std::string& suffix) {
template <typename benchmark_t>
requires std::derived_from<benchmark_t, benchmark_base> void register_benchmark(
const benchmark_base::configuration& cfg, const std::string& suffix) {
benchmark_t bench{cfg};

::benchmark::RegisterBenchmark((bench.name() + suffix).c_str(), bench)
Expand Down
6 changes: 3 additions & 3 deletions benchmarks/eigen/include/benchmark/eigen/data_generator.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
namespace algebra {

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

auto rand_obj = []() { return vector_t::Random(); };
Expand All @@ -27,7 +27,7 @@ inline void fill_random_vec(std::vector<vector_t> &collection) {
}

/// Fill a @c Eigen3 based transform3 with random values
template <typename transform3_t>
template <concepts::transform3D transform3_t>
inline void fill_random_trf(std::vector<transform3_t> &collection) {

using vector_t = typename transform3_t::vector3;
Expand All @@ -52,7 +52,7 @@ inline void fill_random_trf(std::vector<transform3_t> &collection) {
}

/// Fill a @c Eigen3 based matrix with random values
template <typename matrix_t>
template <concepts::matrix matrix_t>
inline void fill_random_matrix(std::vector<matrix_t> &collection) {

auto rand_obj = []() { return matrix_t::Random(); };
Expand Down
6 changes: 3 additions & 3 deletions benchmarks/vc_aos/include/benchmark/vc_aos/data_generator.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
namespace algebra {

/// Fill a @c Vc::SimdArray based vector with random values
template <typename vector_aos_t>
template <concepts::vector vector_aos_t>
inline void fill_random_vec(std::vector<vector_aos_t> &collection) {

// Generate a vector of the right type with random values
Expand All @@ -30,7 +30,7 @@ inline void fill_random_vec(std::vector<vector_aos_t> &collection) {
}

/// Fill a @c Vc::SimdArray based transform3 with random values
template <typename transform3_t>
template <concepts::transform3D transform3_t>
inline void fill_random_trf(std::vector<transform3_t> &collection) {
// Generate a random, but valid affine transformation
auto rand_obj = []() {
Expand Down Expand Up @@ -59,7 +59,7 @@ inline void fill_random_trf(std::vector<transform3_t> &collection) {
}

/// Fill a @c Vc::SimdArray based matrix with random values
template <typename matrix_t>
template <concepts::matrix matrix_t>
inline void fill_random_matrix(std::vector<matrix_t> &collection) {
// Generate a random, but valid affine transformation
auto rand_obj = []() {
Expand Down
15 changes: 8 additions & 7 deletions benchmarks/vc_soa/include/benchmark/vc_soa/data_generator.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,11 @@
namespace algebra {

/// Fill a @c Vc::Vector based vector with random values
template <typename vector_soa_t>
template <concepts::vector vector_soa_t>
inline void fill_random_vec(std::vector<vector_soa_t> &collection) {
// Generate a vector of the right type with random values
auto rand_obj = []() {
using simd_vector_t = typename vector_soa_t::value_type;
using simd_vector_t = typename vector_soa_t::scalar_type;
vector_soa_t tmp{};
tmp[0] = simd_vector_t::Random();
tmp[1] = simd_vector_t::Random();
Expand All @@ -34,11 +34,11 @@ inline void fill_random_vec(std::vector<vector_soa_t> &collection) {
}

/// Fill a @c Vc::Vector based transform3 with random values
template <typename transform3_t>
template <concepts::transform3D transform3_t>
inline void fill_random_trf(std::vector<transform3_t> &collection) {
// Generate a random, but valid affine transformation
auto rand_obj = []() {
using simd_vector_t = typename transform3_t::value_type;
using simd_vector_t = typename transform3_t::scalar_type;
typename transform3_t::vector3 x_axis, z_axis, t;
x_axis[0] = simd_vector_t::Random();
x_axis[1] = simd_vector_t::Random();
Expand Down Expand Up @@ -66,11 +66,11 @@ inline void fill_random_trf(std::vector<transform3_t> &collection) {
}

/// Fill a @c Vc::Vector based matrix with random values
template <typename matrix_t>
template <concepts::matrix matrix_t>
inline void fill_random_matrix(std::vector<matrix_t> &collection) {
// Generate a random, but valid affine transformation
auto rand_obj = []() {
using simd_vector_t = typename matrix_t::value_type;
using simd_vector_t = typename matrix_t::scalar_type;

matrix_t m;

Expand All @@ -80,8 +80,9 @@ inline void fill_random_matrix(std::vector<matrix_t> &collection) {

for (std::size_t i = 0u; i < matrix_t::rows(); ++i) {
v[i] = simd_vector_t::Random();
m[j] = v;
}

m[j] = v;
}

return m;
Expand Down
Loading

0 comments on commit bf37559

Please sign in to comment.