From 2084874b1b4d7a13a5b391928ad0c89ef4aded17 Mon Sep 17 00:00:00 2001 From: Joel Falcou Date: Sun, 20 Jul 2025 20:23:51 +0200 Subject: [PATCH] Implement fixed size options for rotgen containers See merge request oss/rotgen!11 --- .gitlab-ci.yml | 82 +++--- CMakeLists.txt | 26 +- CMakePresets.json | 56 ++++ cmake/options.cmake | 106 ++++++++ include/rotgen/concepts.hpp | 18 ++ include/rotgen/config.hpp | 62 +++++ include/rotgen/detail/static_info.hpp | 2 +- include/rotgen/{ => dynamic}/block.hpp | 10 +- include/rotgen/{ => dynamic}/matrix.hpp | 16 +- include/rotgen/extract.hpp | 3 - include/rotgen/fixed/block.hpp | 224 ++++++++++++++++ include/rotgen/fixed/common.hpp | 86 ++++++ include/rotgen/fixed/matrix.hpp | 246 ++++++++++++++++++ include/rotgen/functions.hpp | 4 +- include/rotgen/impl/block_model.hpp | 6 +- include/rotgen/impl/matrix.hpp | 1 + include/rotgen/impl/matrix_model.hpp | 6 +- include/rotgen/rotgen.hpp | 14 +- src/block_model.cpp | 6 +- src/info.cpp | 30 +++ src/matrix.cpp | 1 + src/matrix_model.cpp | 6 +- test/CMakeLists.txt | 6 +- test/unit/block/arithmetic_functions.cpp | 38 +-- test/unit/block/extract.cpp | 63 +++-- test/unit/block/norms.cpp | 25 +- test/unit/block/operators.cpp | 86 +++--- test/unit/block/static_functions.cpp | 26 +- .../free_functions/arithmetic_functions.cpp | 10 +- test/unit/free_functions/functions.cpp | 8 +- test/unit/free_functions/norms.cpp | 6 +- test/unit/matrix/arithmetic_functions.cpp | 6 +- test/unit/matrix/constructors.cpp | 89 ++++--- test/unit/matrix/functions.cpp | 80 +++--- test/unit/matrix/io.cpp | 4 +- test/unit/matrix/norms.cpp | 12 +- test/unit/matrix/operators.cpp | 47 ++-- test/unit/matrix/static_functions.cpp | 5 +- test/unit/tests.hpp | 48 +++- 39 files changed, 1247 insertions(+), 323 deletions(-) create mode 100644 cmake/options.cmake create mode 100644 include/rotgen/concepts.hpp create mode 100644 include/rotgen/config.hpp rename include/rotgen/{ => dynamic}/block.hpp (96%) rename include/rotgen/{ => dynamic}/matrix.hpp (94%) create mode 100644 include/rotgen/fixed/block.hpp create mode 100644 include/rotgen/fixed/common.hpp create mode 100644 include/rotgen/fixed/matrix.hpp create mode 100644 src/info.cpp diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index d9d615b..656ec43 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -1,57 +1,61 @@ # https://docs.gitlab.com/ee/ci/yaml/ -# Job templates - -.docker-job: &docker-job - tags: [docker] - cache: - paths: [/var/cache/pacman, build/] - image: archlinux/archlinux:base-devel - before_script: [./ci-cd/environment-setup.sh] - .native-job: &native-job tags: ["shell"] - cache: - paths: [build/] stages: - - build - test -# Native stuff - -build-debug-native: +test-debug: <<: *native-job - stage: build - artifacts: - paths: - - build/debug/ + stage: test script: - cmake --preset debug -DCMAKE_CXX_COMPILER=clang++ - cmake --build --preset debug + - cmake --build --preset debug --target rotgen-test + - cd build/debug && ctest --output-on-failure --verbose -build-release-native: +test-debug-static: <<: *native-job - stage: build - artifacts: - paths: - - build/release/ + stage: test + script: + - cmake --preset debug-static -DCMAKE_CXX_COMPILER=clang++ + - cmake --build --preset debug-static + - cmake --build --preset debug-static --target rotgen-test + - cd build/debug-static && ctest --output-on-failure --verbose + +test-debug-et: + <<: *native-job + stage: test + script: + - cmake --preset debug-et -DCMAKE_CXX_COMPILER=clang++ + - cmake --build --preset debug-et + - cmake --build --preset debug-et --target rotgen-test + - cd build/debug-et && ctest --output-on-failure --verbose + +test-release: + <<: *native-job + stage: test script: - cmake --preset release -DCMAKE_CXX_COMPILER=clang++ - cmake --build --preset release - -test-debug-native: - <<: *native-job - needs: ["build-debug-native"] - stage: test - script: - - cmake --build --preset debug --target rotgen-test - - cd build/debug && ctest --output-on-failure - -test-release-native: - <<: *native-job - needs: ["build-release-native"] - stage: test - script: - cmake --build --preset release --target rotgen-test - - cd build/release && ctest --output-on-failure + - cd build/release && ctest --output-on-failure --verbose + +test-release-static: + <<: *native-job + stage: test + script: + - cmake --preset release-static -DCMAKE_CXX_COMPILER=clang++ + - cmake --build --preset release-static + - cmake --build --preset release-static --target rotgen-test + - cd build/release-static && ctest --output-on-failure --verbose + +test-release-et: + <<: *native-job + stage: test + script: + - cmake --preset release-et -DCMAKE_CXX_COMPILER=clang++ + - cmake --build --preset release-et + - cmake --build --preset release-et --target rotgen-test + - cd build/release-et && ctest --output-on-failure --verbose diff --git a/CMakeLists.txt b/CMakeLists.txt index 7d121d3..ad9bac1 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -25,13 +25,30 @@ if (${PROJECT_SOURCE_DIR} STREQUAL ${PROJECT_BINARY_DIR}) message(FATAL_ERROR "[${PROJECT_NAME}]: In-source build is not supported") endif() +##====================================================================================================================== +## Handle options +##====================================================================================================================== +option(ROTGEN_FORCE_DYNAMIC "Force dynamic configuration for rotgen" OFF) +option(ROTGEN_DISABLE_EXPRESSION_TEMPLATES "Disable expression templates" OFF) +set(ROTGEN_MAX_SIZE "" CACHE STRING "Max matrix number of elements for rotgen (integer)") + +include(${ROTGEN_SOURCE_DIR}/cmake/options.cmake) +handle_option(ROTGEN_COMPILE_DEFS) + ##====================================================================================================================== ## Sources & Public Headers lists ##====================================================================================================================== -set ( SOURCES - src/matrix.cpp - src/block.cpp - ) +if(ROTGEN_FORCE_DYNAMIC) + set ( SOURCES + src/matrix.cpp + src/block.cpp + src/info.cpp + ) +else() + set ( SOURCES + src/info.cpp + ) +endif() ##====================================================================================================================== ## Setup the library's dependencies @@ -46,6 +63,7 @@ set_target_properties(rotgen PROPERTIES VERSION ${PROJECT_VERSION}) set_target_properties(rotgen PROPERTIES SOVERSION ${PROJECT_VERSION_MAJOR}) target_compile_options(rotgen PUBLIC -std=c++20 -Werror -Wall -Wextra -Wshadow -Wunused-variable) +target_compile_definitions(rotgen PUBLIC ${ROTGEN_COMPILE_DEFS}) set_target_properties(rotgen PROPERTIES EXPORT_NAME rotgen) add_library(rotgen::rotgen ALIAS rotgen) diff --git a/CMakePresets.json b/CMakePresets.json index 041ad83..4759685 100644 --- a/CMakePresets.json +++ b/CMakePresets.json @@ -40,6 +40,46 @@ "cacheVariables": { "CMAKE_BUILD_TYPE": "Debug" } + }, + { + "name": "release-static", + "displayName": "Release (Static size)", + "description": "Release (Static size) build", + "generator": "Ninja", + "binaryDir": "${sourceDir}/build/release-static", + "cacheVariables": { + "ROTGEN_MAX_SIZE": "4" + } + }, + { + "name": "debug-static", + "displayName": "Debug (Static size)", + "description": "Debug (Static size) build", + "generator": "Ninja", + "binaryDir": "${sourceDir}/build/debug-static", + "cacheVariables": { + "ROTGEN_MAX_SIZE": "4" + } + }, + { + "name": "release-et", + "displayName": "Release (No Expr. Temp.)", + "description": "Release (No Expr. Temp.) build", + "generator": "Ninja", + "binaryDir": "${sourceDir}/build/release-et", + "cacheVariables": { + "ROTGEN_DISABLE_EXPRESSION_TEMPLATES": "ON" + } + }, + { + "name": "debug-et", + "displayName": "Debug (No Expr. Temp.)", + "description": "Debug (No Expr. Temp.) build", + "generator": "Ninja", + "binaryDir": "${sourceDir}/build/debug-et", + "cacheVariables": { + "ROTGEN_DISABLE_EXPRESSION_TEMPLATES": "ON" + } } ], "buildPresets": [ @@ -47,9 +87,25 @@ "name": "release", "configurePreset": "release" }, + { + "name": "release-static", + "configurePreset": "release-static" + }, + { + "name": "release-et", + "configurePreset": "release-et" + }, { "name": "debug", "configurePreset": "debug" + }, + { + "name": "debug-static", + "configurePreset": "debug-static" + }, + { + "name": "debug-et", + "configurePreset": "debug-et" } ] } diff --git a/cmake/options.cmake b/cmake/options.cmake new file mode 100644 index 0000000..202586d --- /dev/null +++ b/cmake/options.cmake @@ -0,0 +1,106 @@ +##====================================================================================================================== +## ROTGEN - Runtime Overlay for Eigen +## Copyright : CODE RECKONS +## SPDX-License-Identifier: BSL-1.0 +##====================================================================================================================== + +function(assert_integer VAR_NAME) + if(DEFINED ${VAR_NAME} AND NOT ${${VAR_NAME}} STREQUAL "") + if(NOT ${${VAR_NAME}} MATCHES "^[0-9]+$") + message(FATAL_ERROR "[ROTGEN] - ${VAR_NAME} must be a non-negative integer, got '${${VAR_NAME}}'}") + endif() + endif() +endfunction() + +function(check_force_dynamic_and_sizes FORCE_DYNAMIC_VAR MAX_SIZE_VAR) + if(${FORCE_DYNAMIC_VAR}) + if(NOT ${MAX_SIZE_VAR} STREQUAL "") + message(FATAL_ERROR "[ROTGEN] - ROTGEN_FORCE_DYNAMIC is set, so ROTGEN_MAX_SIZE must not be defined.") + endif() + endif() +endfunction() + +function(infer_force_dynamic FORCE_DYNAMIC_VAR MAX_SIZE_VAR OUT_FORCE_DYNAMIC_INFERRED) + set(${OUT_FORCE_DYNAMIC_INFERRED} OFF PARENT_SCOPE) + + if(${FORCE_DYNAMIC_VAR}) + if(NOT ${MAX_SIZE_VAR} STREQUAL "") + message(FATAL_ERROR "ROTGEN_FORCE_DYNAMIC cannot be used together with MAX_SIZE.") + endif() + elseif(${MAX_SIZE_VAR} STREQUAL "") + # None set, enable force_dynamic + set(${OUT_FORCE_DYNAMIC_INFERRED} ON PARENT_SCOPE) + set(${FORCE_DYNAMIC_VAR} ON PARENT_SCOPE) # update caller variable! + endif() +endfunction() + +function(build_compile_definitions FORCE_DYNAMIC_VAR MAX_SIZE_VAR OUT_DEFS) + set(defs "") + if(${FORCE_DYNAMIC_VAR}) + list(APPEND defs "ROTGEN_FORCE_DYNAMIC") + else() + if(NOT ${MAX_SIZE_VAR} STREQUAL "") + list(APPEND defs "ROTGEN_MAX_SIZE=${${MAX_SIZE_VAR}}") + endif() + endif() + set(${OUT_DEFS} "${defs}" PARENT_SCOPE) +endfunction() + +function(print_configuration_summary FORCE_DYNAMIC_VAR FORCE_CONFIG_REASON MAX_SIZE_VAR COMPILE_DEFS) + message(STATUS "==================== Rotgen Configuration Summary ====================") + + if(DEFINED ROTGEN_DISABLE_EXPRESSION_TEMPLATES AND ROTGEN_DISABLE_EXPRESSION_TEMPLATES) + message(STATUS " Configuration mode: DISABLE_EXPRESSION_TEMPLATES (overrides other settings)") + elseif(${FORCE_DYNAMIC_VAR}) + message(STATUS " Configuration mode: DYNAMIC") + if(${FORCE_CONFIG_REASON}) + message(STATUS " Reason : No static size options were provided") + endif() + else() + message(STATUS " Configuration mode: STATIC") + endif() + + set(PREPROCESSOR_FLAGS "") + foreach(def IN LISTS COMPILE_DEFS) + string(APPEND PREPROCESSOR_FLAGS " -D${def}") + endforeach() + message(STATUS " Preprocessor flags: ${PREPROCESSOR_FLAGS}") + message(STATUS "======================================================================") +endfunction() + +function(handle_option OUT_DEFS) + # Early-out if disabling expression templates + if(NOT DEFINED ROTGEN_DISABLE_EXPRESSION_TEMPLATES) + set(ROTGEN_DISABLE_EXPRESSION_TEMPLATES OFF) + endif() + if(ROTGEN_DISABLE_EXPRESSION_TEMPLATES) + # Pass only the disable flag + set(${OUT_DEFS} "ROTGEN_DISABLE_EXPRESSION_TEMPLATES" PARENT_SCOPE) + message(STATUS "==================== Rotgen Configuration Summary ====================") + message(STATUS " Configuration mode: DISABLE_EXPRESSION_TEMPLATES (overrides other settings)") + message(STATUS " Preprocessor flags: -DROTGEN_DISABLE_EXPRESSION_TEMPLATES") + message(STATUS "======================================================================") + # Propagate to parent + set(ROTGEN_DISABLE_EXPRESSION_TEMPLATES ${ROTGEN_DISABLE_EXPRESSION_TEMPLATES} PARENT_SCOPE) + return() + endif() + + # Defaults for other options + if(NOT DEFINED ROTGEN_FORCE_DYNAMIC) + set(ROTGEN_FORCE_DYNAMIC OFF) + endif() + if(NOT DEFINED ROTGEN_MAX_SIZE) + set(ROTGEN_MAX_SIZE "") + endif() + + assert_integer("ROTGEN_MAX_SIZE") + check_force_dynamic_and_sizes("ROTGEN_FORCE_DYNAMIC" "ROTGEN_MAX_SIZE") + infer_force_dynamic("ROTGEN_FORCE_DYNAMIC" "ROTGEN_MAX_SIZE" _force_dynamic_inferred) + + build_compile_definitions("ROTGEN_FORCE_DYNAMIC" "ROTGEN_MAX_SIZE" defs) + print_configuration_summary("ROTGEN_FORCE_DYNAMIC" "_force_dynamic_inferred" "ROTGEN_MAX_SIZE" "${defs}") + + set(${OUT_DEFS} "${defs}" PARENT_SCOPE) + set(ROTGEN_FORCE_DYNAMIC ${ROTGEN_FORCE_DYNAMIC} PARENT_SCOPE) + set(ROTGEN_MAX_SIZE ${ROTGEN_MAX_SIZE} PARENT_SCOPE) +endfunction() diff --git a/include/rotgen/concepts.hpp b/include/rotgen/concepts.hpp new file mode 100644 index 0000000..98539a7 --- /dev/null +++ b/include/rotgen/concepts.hpp @@ -0,0 +1,18 @@ +//================================================================================================== +/* + ROTGEN - Runtime Overlay for Eigen + Copyright : CODE RECKONS + SPDX-License-Identifier: BSL-1.0 +*/ +//================================================================================================== +#pragma once + +namespace rotgen::concepts +{ + template + concept entity = requires(T const&) + { + typename T::rotgen_tag; + typename T::parent; + }; +} \ No newline at end of file diff --git a/include/rotgen/config.hpp b/include/rotgen/config.hpp new file mode 100644 index 0000000..de708f0 --- /dev/null +++ b/include/rotgen/config.hpp @@ -0,0 +1,62 @@ +//================================================================================================== +/* + ROTGEN - Runtime Overlay for Eigen + Copyright : CODE RECKONS + SPDX-License-Identifier: BSL-1.0 +*/ +//================================================================================================== +#pragma once + +#include +#include + +namespace rotgen +{ + using Index = std::ptrdiff_t; +} + +#if defined(ROTGEN_DISABLE_EXPRESSION_TEMPLATES) + #define ROTGEN_MAX_SIZE 0 +#endif + +#if !defined(ROTGEN_FORCE_DYNAMIC) + #if !defined(ROTGEN_MAX_SIZE) + #define ROTGEN_FORCE_DYNAMIC + #endif +#endif + +#if defined(ROTGEN_FORCE_DYNAMIC) +#define ROTGEN_HAS_STATIC_LIMIT false +#else +#define ROTGEN_HAS_STATIC_LIMIT true +#endif + +namespace rotgen +{ + inline constexpr bool has_static_limit = ROTGEN_HAS_STATIC_LIMIT; + inline constexpr bool is_forcing_dynamic_status = !has_static_limit; + + std::ostream& setup_summary(std::ostream& os); +} + +#if defined(ROTGEN_FORCE_DYNAMIC) +namespace rotgen +{ + inline constexpr Index max_static_size = -1; + + template + inline constexpr bool storage_status = false; +} +#else +namespace rotgen +{ + inline constexpr Index max_static_size = ROTGEN_MAX_SIZE; + template + inline constexpr bool storage_status = (Rows > 0 && Cols > 0) && ((Rows*Cols) <= max_static_size); +} +#endif + +namespace rotgen +{ + inline constexpr bool use_expression_templates = max_static_size > 0; +} \ No newline at end of file diff --git a/include/rotgen/detail/static_info.hpp b/include/rotgen/detail/static_info.hpp index 39fc391..2915195 100644 --- a/include/rotgen/detail/static_info.hpp +++ b/include/rotgen/detail/static_info.hpp @@ -23,5 +23,5 @@ namespace rotgen inline constexpr int AutoAlign = 0; inline constexpr int ColMajor = 0; inline constexpr int RowMajor = 1; - inline constexpr int DotnAlgin = 2; + inline constexpr int DontAlign = 2; } \ No newline at end of file diff --git a/include/rotgen/block.hpp b/include/rotgen/dynamic/block.hpp similarity index 96% rename from include/rotgen/block.hpp rename to include/rotgen/dynamic/block.hpp index e082471..009eba3 100644 --- a/include/rotgen/block.hpp +++ b/include/rotgen/dynamic/block.hpp @@ -7,8 +7,9 @@ //================================================================================================== #pragma once +#include #include -#include +#include #include #include @@ -17,8 +18,13 @@ namespace rotgen template class block : public find_block { - using parent = find_block; public: + static_assert ( concepts::entity + , "[ROTGEN][CRITICAL] - Block of non-rotgen type instanciated" + ); + + using parent = find_block; + using rotgen_tag = void; using scalar_type = typename Ref::scalar_type; static constexpr int storage_order = (ForceStorageOrder == -1) ? Ref::storage_order : ForceStorageOrder; using concrete_type = matrix; diff --git a/include/rotgen/matrix.hpp b/include/rotgen/dynamic/matrix.hpp similarity index 94% rename from include/rotgen/matrix.hpp rename to include/rotgen/dynamic/matrix.hpp index 12e8b68..65669c9 100644 --- a/include/rotgen/matrix.hpp +++ b/include/rotgen/dynamic/matrix.hpp @@ -20,12 +20,16 @@ namespace rotgen > class matrix : public find_matrix { - using parent = find_matrix; - public: - using scalar_type = Scalar; + using parent = find_matrix; + using rotgen_tag = void; + using concrete_type = matrix; + using scalar_type = Scalar; static constexpr auto storage_order = Options & 1; + static constexpr int RowsAtCompileTime = Rows; + static constexpr int ColsAtCompileTime = Cols; + matrix() : parent(Rows==-1?0:Rows,Cols==-1?0:Cols) {} matrix(int r, int c) : parent(r, c) @@ -36,7 +40,7 @@ namespace rotgen matrix(parent const& base) : parent(base) {} - matrix(std::initializer_list> init) : parent(init) + explicit matrix(std::initializer_list> init) : parent(init) { if constexpr(Rows != -1) assert(init.size() == Rows && "Mismatched between dynamic and static row size"); if constexpr(Cols != -1) @@ -48,7 +52,7 @@ namespace rotgen } template... S> - matrix(Scalar s0,S... init) + explicit matrix(Scalar s0,S... init) requires((Rows == 1 && Cols == (1+sizeof...(S))) || (Cols == 1 && Rows == (1+sizeof...(S)))) : parent(Rows, Cols, {s0,static_cast(init)...}) {} @@ -170,7 +174,7 @@ namespace rotgen } template - Scalar lp_norm() const + Scalar lpNorm() const { static_assert(P == 1 || P == 2 || P == Infinity); return parent::lp_norm(P); diff --git a/include/rotgen/extract.hpp b/include/rotgen/extract.hpp index dd88510..8cf77b5 100644 --- a/include/rotgen/extract.hpp +++ b/include/rotgen/extract.hpp @@ -7,9 +7,6 @@ //================================================================================================== #pragma once -#include -#include - namespace rotgen { template< typename S, int R , int C diff --git a/include/rotgen/fixed/block.hpp b/include/rotgen/fixed/block.hpp new file mode 100644 index 0000000..b8ea489 --- /dev/null +++ b/include/rotgen/fixed/block.hpp @@ -0,0 +1,224 @@ +//================================================================================================== +/* + ROTGEN - Runtime Overlay for Eigen + Copyright : CODE RECKONS + SPDX-License-Identifier: BSL-1.0 +*/ +//================================================================================================== +#pragma once + +#include +#include +#include +#include + +namespace rotgen +{ + namespace detail + { + template + using block_type = std::conditional_t < storage_status + , Eigen::Block + , Eigen::Block + >; + } + + template< typename Ref + , int Rows = Dynamic, int Cols = Dynamic + , bool Inner = false, int ForceStorageOrder = -1 + > + class block : private detail::block_type + { + static_assert ( concepts::entity + , "[ROTGEN][CRITICAL] - Block of non-rotgen type instanciated" + ); + + public: + using rotgen_tag = void; + using parent = detail::block_type; + using value_type = typename parent::value_type; + using scalar_type = typename parent::value_type; + using Index = typename parent::Index; + + static constexpr int storage_order = (ForceStorageOrder == -1) ? Ref::storage_order : ForceStorageOrder; + using concrete_type = matrix; + using concrete_dynamic_type = matrix; + + template + using as_concrete_type = as_concrete_t; + + static constexpr int RowsAtCompileTime = Rows; + static constexpr int ColsAtCompileTime = Cols; + + private: + static constexpr bool has_static_storage = storage_status; + + public: + + block(const block& other) = default; + block(block&& other) = default; + block& operator=(const block&) = default; + block& operator=(block&&) = default; + + block(Ref& r, std::size_t i0, std::size_t j0, std::size_t ni, std::size_t nj) : parent(r.base(),i0,j0,ni,nj) + {} + + block(Ref& r, std::size_t i0, std::size_t j0) requires(Rows != -1 && Cols != -1) + : parent(r.base(),i0,j0,Rows,Cols) + {} + + template + block(const Eigen::MatrixBase& other) : parent(other) {} + + template + block(const Eigen::EigenBase& other) : parent(other) {} + + template + block& operator=(const Eigen::MatrixBase& other) + { + parent::operator=(other); + return *this; + } + + template + block& operator=(const Eigen::EigenBase& other) + { + parent::operator=(other); + return *this; + } + + parent& base() { return static_cast(*this); } + parent const& base() const { return static_cast(*this); } + + concrete_type transpose() const + { + return concrete_type(static_cast(*this).transpose()); + } + + concrete_type conjugate() const + { + return concrete_type(static_cast(*this).conjugate()); + } + + concrete_type adjoint() const + { + return concrete_type(static_cast(*this).adjoint()); + } + + void transposeInPlace() { parent::transposeInPlace(); } + void adjointInPlace() { parent::adjointInPlace(); } + + static concrete_type Constant(scalar_type value) requires (Rows != -1 && Cols != -1) + { + return parent::Constant(Rows, Cols, static_cast(value)); + } + + static concrete_type Constant(int rows, int cols, scalar_type value) + { + if constexpr(Rows != -1) assert(rows == Rows && "Mismatched between dynamic and static row size"); + if constexpr(Cols != -1) assert(cols == Cols && "Mismatched between dynamic and static column size"); + return parent::Constant(rows, cols, static_cast(value)); + } + + static concrete_type Identity() requires (Rows != -1 && Cols != -1) + { + return parent::Identity(Rows, Cols); + } + + static concrete_type Identity(int rows, int cols) + { + if constexpr(Rows != -1) assert(rows == Rows && "Mismatched between dynamic and static row size"); + if constexpr(Cols != -1) assert(cols == Cols && "Mismatched between dynamic and static column size"); + return parent::Identity(rows, cols); + } + + static concrete_type Zero() requires (Rows != -1 && Cols != -1) + { + return parent::Zero(Rows, Cols); + } + + static concrete_type Zero(int rows, int cols) + { + if constexpr(Rows != -1) assert(rows == Rows && "Mismatched between dynamic and static row size"); + if constexpr(Cols != -1) assert(cols == Cols && "Mismatched between dynamic and static column size"); + return parent::Zero(rows, cols); + } + + static concrete_type Random() requires (Rows != -1 && Cols != -1) + { + return parent::Random(Rows, Cols); + } + + static concrete_type Random(int rows, int cols) + { + if constexpr(Rows != -1) assert(rows == Rows && "Mismatched between dynamic and static row size"); + if constexpr(Cols != -1) assert(cols == Cols && "Mismatched between dynamic and static column size"); + return parent::Random(rows, cols); + } + + template + scalar_type lpNorm() const + { + static_assert(P == 1 || P == 2 || P == Infinity); + return parent::template lpNorm

(); + } + + using parent::operator(); + using parent::rows; + using parent::cols; + using parent::size; + using parent::prod; + using parent::mean; + using parent::trace; + using parent::maxCoeff; + using parent::minCoeff; + using parent::squaredNorm; + using parent::norm; + using parent::sum; + using parent::data; + + block& operator+=(block const& rhs) + { + static_cast(*this) += static_cast(rhs); + return *this; + } + + block& operator-=(block const& rhs) + { + static_cast(*this) -= static_cast(rhs); + return *this; + } + + concrete_type operator-() const + { + return concrete_type(static_cast(*this).operator-()); + } + + block& operator*=(block const& rhs) + { + static_cast(*this) *= static_cast(rhs); + return *this; + } + + block& operator*=(scalar_type rhs) + { + static_cast(*this) *= rhs; + return *this; + } + + block& operator/=(scalar_type rhs) + { + static_cast(*this) /= rhs; + return *this; + } + + static void print_storage_info() + { + std::cout << "Block " << Rows << "x" << Cols + << " - Storage: " << (has_static_storage ? "Static" : "Dynamic") + << " (from: "; + Ref::print_storage_info(); + std::cout << ")" << std::endl; + } + }; +} \ No newline at end of file diff --git a/include/rotgen/fixed/common.hpp b/include/rotgen/fixed/common.hpp new file mode 100644 index 0000000..7c741f0 --- /dev/null +++ b/include/rotgen/fixed/common.hpp @@ -0,0 +1,86 @@ +//================================================================================================== +/* + ROTGEN - Runtime Overlay for Eigen + Copyright : CODE RECKONS + SPDX-License-Identifier: BSL-1.0 +*/ +//================================================================================================== +#pragma once + +#include +#include +#include + +namespace rotgen +{ + template typename Wrapper + > + struct as_concrete + { + using type = Wrapper< typename EigenType::value_type + , EigenType::RowsAtCompileTime, EigenType::ColsAtCompileTime + , EigenType::Flags + , EigenType::MaxRowsAtCompileTime, EigenType::MaxColsAtCompileTime + >; + }; + + template typename Wrapper + > + using as_concrete_t = typename as_concrete::type; + + template + bool operator==(E1 const& lhs, E2 const& rhs) + { + return lhs.base() == rhs.base(); + } + + template + std::ostream& operator<<(std::ostream& os, E const& arg) + { + return os << arg.base(); + } + + template + auto operator+(E1 const& lhs, E2 const& rhs) + { + using type = E1::template as_concrete_type; + return type(lhs.base() + rhs.base()); + } + + template + auto operator-(E1 const& lhs, E2 const& rhs) + { + using type = E1::template as_concrete_type; + return type(lhs.base() - rhs.base()); + } + + template + auto operator*(E1 const& lhs, E2 const& rhs) + { + using type = typename E1::concrete_dynamic_type; + return type(lhs.base() * rhs.base()); + } + + template S> + auto operator*(E const& lhs, S rhs) + { + using type = E::template as_concrete_type; + return type(lhs.base() * rhs); + } + + template S> + auto operator*(S lhs, E const& rhs ) + { + using type = E::template as_concrete_type; + return type(lhs * rhs.base()); + } + + template S> + auto operator/(E const& lhs, S rhs) + { + using type = E::template as_concrete_type; + return type(lhs.base() / rhs); + } +} \ No newline at end of file diff --git a/include/rotgen/fixed/matrix.hpp b/include/rotgen/fixed/matrix.hpp new file mode 100644 index 0000000..f130842 --- /dev/null +++ b/include/rotgen/fixed/matrix.hpp @@ -0,0 +1,246 @@ +//================================================================================================== +/* + ROTGEN - Runtime Overlay for Eigen + Copyright : CODE RECKONS + SPDX-License-Identifier: BSL-1.0 +*/ +//================================================================================================== +#pragma once + +#include +#include +#include +#include + +namespace rotgen +{ + namespace detail + { + template + using storage_type = std::conditional_t < storage_status + , Eigen::Matrix + , Eigen::Matrix + >; + } + + template< typename Scalar + , int Rows = Dynamic , int Cols = Dynamic + , int Options = ColMajor + , int MaxRows = Rows , int MaxCols = Cols + > + class matrix : private detail::storage_type + { + public: + using rotgen_tag = void; + using parent = detail::storage_type; + using value_type = Scalar; + using scalar_type = Scalar; + using Index = typename parent::Index; + + static constexpr auto storage_order = Options & 1; + using concrete_type = matrix; + using concrete_dynamic_type = matrix; + + template + using as_concrete_type = as_concrete_t; + + private: + static constexpr bool has_static_storage = storage_status; + + public: + + matrix() requires(has_static_storage) {} + matrix() requires(!has_static_storage) : parent(Rows > 0 ? Rows : 0, Cols > 0 ? Cols : 0){} + matrix(Index r, Index c) requires(!has_static_storage) : parent(r, c) {} + + matrix(const matrix& other) = default; + matrix(matrix&& other) = default; + matrix& operator=(const matrix&) = default; + matrix& operator=(matrix&&) = default; + + + matrix(std::initializer_list> init) : parent(init) + {} + + template... S> + requires((Rows == 1 && Cols == (1+sizeof...(S))) || (Cols == 1 && Rows == (1+sizeof...(S)))) + matrix(Scalar s0,S... init) + : parent ( [&]() + { + if constexpr(has_static_storage) + return parent{static_cast(s0),static_cast(init)...}; + else return parent{Rows,Cols}; + }() + ) + { + if constexpr(!has_static_storage) + { + auto raw = {static_cast(s0),static_cast(init)...}; + auto first = raw.begin(); + for(rotgen::Index i=0; i < parent::size(); i++) + (*this)(i) = first[i]; + } + } + + template + matrix(const Eigen::MatrixBase& other) : parent(other) + {} + + template + matrix& operator=(const Eigen::MatrixBase& other) + { + parent::operator=(other); + return *this; + } + + template + matrix& operator=(const Eigen::EigenBase& other) + { + parent::operator=(other); + return *this; + } + + parent& base() { return static_cast(*this); } + parent const& base() const { return static_cast(*this); } + + concrete_type transpose() const + { + return concrete_type(static_cast(*this).transpose()); + } + + concrete_type conjugate() const + { + return concrete_type(static_cast(*this).conjugate()); + } + + concrete_type adjoint() const + { + return concrete_type(static_cast(*this).adjoint()); + } + + void transposeInPlace() { parent::transposeInPlace(); } + void adjointInPlace() { parent::adjointInPlace(); } + + void resize(int new_rows, int new_cols) requires(Rows == -1 && Cols == -1) + { + parent::resize(new_rows, new_cols); + } + + void conservativeResize(int new_rows, int new_cols) requires(Rows == -1 && Cols == -1) + { + parent::conservativeResize(new_rows, new_cols); + } + + static matrix Constant(Scalar value) requires (Rows != -1 && Cols != -1) + { + return parent::Constant(Rows, Cols, static_cast(value)); + } + + static matrix Constant(int rows, int cols, Scalar value) + { + if constexpr(Rows != -1) assert(rows == Rows && "Mismatched between dynamic and static row size"); + if constexpr(Cols != -1) assert(cols == Cols && "Mismatched between dynamic and static column size"); + return parent::Constant(rows, cols, static_cast(value)); + } + + static matrix Identity() requires (Rows != -1 && Cols != -1) + { + return parent::Identity(Rows, Cols); + } + + static matrix Identity(int rows, int cols) + { + if constexpr(Rows != -1) assert(rows == Rows && "Mismatched between dynamic and static row size"); + if constexpr(Cols != -1) assert(cols == Cols && "Mismatched between dynamic and static column size"); + return parent::Identity(rows, cols); + } + + static matrix Zero() requires (Rows != -1 && Cols != -1) + { + return parent::Zero(Rows, Cols); + } + + static matrix Zero(int rows, int cols) + { + if constexpr(Rows != -1) assert(rows == Rows && "Mismatched between dynamic and static row size"); + if constexpr(Cols != -1) assert(cols == Cols && "Mismatched between dynamic and static column size"); + return parent::Zero(rows, cols); + } + + static matrix Random() requires (Rows != -1 && Cols != -1) + { + return parent::Random(Rows, Cols); + } + + static matrix Random(int rows, int cols) + { + if constexpr(Rows != -1) assert(rows == Rows && "Mismatched between dynamic and static row size"); + if constexpr(Cols != -1) assert(cols == Cols && "Mismatched between dynamic and static column size"); + return parent::Random(rows, cols); + } + + template + scalar_type lpNorm() const + { + static_assert(P == 1 || P == 2 || P == Infinity); + return parent::template lpNorm

(); + } + + using parent::operator(); + using parent::rows; + using parent::cols; + using parent::size; + using parent::prod; + using parent::mean; + using parent::trace; + using parent::maxCoeff; + using parent::minCoeff; + using parent::squaredNorm; + using parent::norm; + using parent::sum; + using parent::data; + + matrix& operator+=(matrix const& rhs) + { + static_cast(*this) += static_cast(rhs); + return *this; + } + + matrix& operator-=(matrix const& rhs) + { + static_cast(*this) -= static_cast(rhs); + return *this; + } + + matrix operator-() const + { + return matrix(static_cast(*this).operator-()); + } + + matrix& operator*=(matrix const& rhs) + { + static_cast(*this) *= static_cast(rhs); + return *this; + } + + matrix& operator*=(Scalar rhs) + { + static_cast(*this) *= rhs; + return *this; + } + + matrix& operator/=(Scalar rhs) + { + static_cast(*this) /= rhs; + return *this; + } + + static void print_storage_info() + { + std::cout << "Matrix " << Rows << "x" << Cols + << " - Storage: " << (has_static_storage ? "Static" : "Dynamic") + << " (Max. size=" << max_static_size << ")" + << std::endl; + } + }; +} \ No newline at end of file diff --git a/include/rotgen/functions.hpp b/include/rotgen/functions.hpp index 4a6384b..565cbdf 100644 --- a/include/rotgen/functions.hpp +++ b/include/rotgen/functions.hpp @@ -6,7 +6,6 @@ */ //================================================================================================== #pragma once -#include namespace rotgen { @@ -88,7 +87,8 @@ namespace rotgen double lpNorm(const rotgen::matrix &matrix) { static_assert(P == 1 || P == 2 || P == Infinity); - return matrix.template lp_norm

(); + + return matrix.template lpNorm

(); } template< typename Scalar, int Rows = -1, int Cols = 1, int Options = 0, int MaxRows = Rows, int MaxCols = Cols > diff --git a/include/rotgen/impl/block_model.hpp b/include/rotgen/impl/block_model.hpp index 52ecb99..1dcbf5f 100644 --- a/include/rotgen/impl/block_model.hpp +++ b/include/rotgen/impl/block_model.hpp @@ -24,9 +24,9 @@ class CLASSNAME ~CLASSNAME(); - std::size_t rows() const; - std::size_t cols() const; - std::size_t size() const; + Index rows() const; + Index cols() const; + Index size() const; SOURCENAME transpose() const; SOURCENAME conjugate() const; diff --git a/include/rotgen/impl/matrix.hpp b/include/rotgen/impl/matrix.hpp index 7969b1c..84b61dc 100644 --- a/include/rotgen/impl/matrix.hpp +++ b/include/rotgen/impl/matrix.hpp @@ -9,6 +9,7 @@ #include #include +#include #include #include #include diff --git a/include/rotgen/impl/matrix_model.hpp b/include/rotgen/impl/matrix_model.hpp index a4da96b..94d2004 100644 --- a/include/rotgen/impl/matrix_model.hpp +++ b/include/rotgen/impl/matrix_model.hpp @@ -27,10 +27,10 @@ class CLASSNAME ~CLASSNAME(); - std::size_t rows() const; - std::size_t cols() const; + Index rows() const; + Index cols() const; + Index size() const; - std::size_t size() const; void resize(std::size_t new_rows, std::size_t new_cols); void conservativeResize(std::size_t new_rows, std::size_t new_cols); diff --git a/include/rotgen/rotgen.hpp b/include/rotgen/rotgen.hpp index 0726f3e..f489060 100644 --- a/include/rotgen/rotgen.hpp +++ b/include/rotgen/rotgen.hpp @@ -7,6 +7,16 @@ //================================================================================================== #pragma once -#include -#include +#include +#include + +#if defined(ROTGEN_FORCE_DYNAMIC) +#include +#include +#else +#include +#include +#endif + #include +#include diff --git a/src/block_model.cpp b/src/block_model.cpp index 79a907c..91a8bc7 100644 --- a/src/block_model.cpp +++ b/src/block_model.cpp @@ -53,9 +53,9 @@ struct CLASSNAME::payload //================================================================================================== // Matrix API //================================================================================================== - std::size_t CLASSNAME::rows() const { return static_cast(storage_->data.rows()); } - std::size_t CLASSNAME::cols() const { return static_cast(storage_->data.cols()); } - std::size_t CLASSNAME::size() const { return static_cast(storage_->data.size()); } + rotgen::Index CLASSNAME::rows() const { return storage_->data.rows(); } + rotgen::Index CLASSNAME::cols() const { return storage_->data.cols(); } + rotgen::Index CLASSNAME::size() const { return storage_->data.size(); } TYPE& CLASSNAME::operator()(std::size_t i, std::size_t j) { return storage_->data(i,j); } TYPE const& CLASSNAME::operator()(std::size_t i, std::size_t j) const { return storage_->data(i,j); } diff --git a/src/info.cpp b/src/info.cpp new file mode 100644 index 0000000..0291e93 --- /dev/null +++ b/src/info.cpp @@ -0,0 +1,30 @@ + +//================================================================================================== +/* + ROTGEN - Runtime Overlay for Eigen + Copyright : CODE RECKONS + SPDX-License-Identifier: BSL-1.0 +*/ +//================================================================================================== +#include +#include + +namespace rotgen +{ + std::ostream& setup_summary(std::ostream& os) + { + if constexpr(rotgen::is_forcing_dynamic_status) + { + os << "[ROTGEN] - Fully Dynamic mode" << std::endl; + } + else + { + if constexpr(use_expression_templates) + os << "[ROTGEN] - Expression templates : Disabled." << std::endl; + else + os << "[ROTGEN] - Static/Dynamic mode with maximum size: " << rotgen::max_static_size << std::endl; + } + + return os; + } +} \ No newline at end of file diff --git a/src/matrix.cpp b/src/matrix.cpp index 3d467cd..c29dbc1 100644 --- a/src/matrix.cpp +++ b/src/matrix.cpp @@ -8,6 +8,7 @@ #include #include #include +#include #include namespace rotgen diff --git a/src/matrix_model.cpp b/src/matrix_model.cpp index 9b0fb50..419eded 100644 --- a/src/matrix_model.cpp +++ b/src/matrix_model.cpp @@ -51,9 +51,9 @@ CLASSNAME::~CLASSNAME() = default; //================================================================================================== // Matrix API //================================================================================================== -std::size_t CLASSNAME::rows() const { return static_cast(storage_->data.rows()); } -std::size_t CLASSNAME::cols() const { return static_cast(storage_->data.cols()); } -std::size_t CLASSNAME::size() const { return static_cast(storage_->data.size()); } +rotgen::Index CLASSNAME::rows() const { return storage_->data.rows(); } +rotgen::Index CLASSNAME::cols() const { return storage_->data.cols(); } +rotgen::Index CLASSNAME::size() const { return storage_->data.size(); } void CLASSNAME::resize(std::size_t new_rows, std::size_t new_cols) { diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index 301f714..18eab67 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -7,7 +7,7 @@ include(${ROTGEN_SOURCE_DIR}/cmake/unit.cmake) rotgen_setup_test_targets() ##====================================================================================================================== -## Compiler options for Unit Tests +## Compiler options for Unit Tests in dynamci and static mode ##====================================================================================================================== add_library(rotgen_test INTERFACE) target_compile_options(rotgen_test INTERFACE -std=c++20 -Werror -Wall -Wextra -Wshadow -Wunused-variable) @@ -18,5 +18,5 @@ target_link_libraries(rotgen_test INTERFACE rotgen Eigen3::Eigen) ## Unit Tests registration ##====================================================================================================================== rotgen_glob_unit(PATTERN "unit/free_functions/*.cpp" INTERFACE rotgen_test) -rotgen_glob_unit(PATTERN "unit/matrix/*.cpp" INTERFACE rotgen_test) -rotgen_glob_unit(PATTERN "unit/block/*.cpp" INTERFACE rotgen_test) +rotgen_glob_unit(PATTERN "unit/matrix/*.cpp" INTERFACE rotgen_test) +rotgen_glob_unit(PATTERN "unit/block/*.cpp" INTERFACE rotgen_test) diff --git a/test/unit/block/arithmetic_functions.cpp b/test/unit/block/arithmetic_functions.cpp index 02e4f27..618305f 100644 --- a/test/unit/block/arithmetic_functions.cpp +++ b/test/unit/block/arithmetic_functions.cpp @@ -6,9 +6,7 @@ */ //================================================================================================== #include "unit/tests.hpp" -#include -#include -#include +#include #include template @@ -16,8 +14,8 @@ void test_comparison(const Type1& t1, const Type2& t2) { TTS_EQUAL(static_cast(t1.rows()), static_cast(t2.rows())); TTS_EQUAL(static_cast(t1.cols()), static_cast(t2.cols())); - for (std::size_t r = 0; r < static_cast(t1.rows()); ++r) - for (std::size_t c = 0; c < static_cast(t1.cols()); ++c) + for (rotgen::Index r = 0; r < static_cast(t1.rows()); ++r) + for (rotgen::Index c = 0; c < static_cast(t1.cols()); ++c) TTS_EQUAL(t1(r, c), t2(r, c)); } @@ -25,6 +23,10 @@ template void test_block_unary_ops(const Matrix1& original_matrix, const Matrix2& ref_matrix, Block1 original_block, Block2 ref_block) { + TTS_EXPECT(verify_rotgen_reentrance(original_block.transpose())); + TTS_EXPECT(verify_rotgen_reentrance(original_block.conjugate())); + TTS_EXPECT(verify_rotgen_reentrance(original_block.adjoint())); + test_comparison(original_block.transpose(), ref_block.transpose()); test_comparison(original_block.conjugate(), ref_block.conjugate()); test_comparison(original_block.adjoint(), ref_block.adjoint()); @@ -72,8 +74,8 @@ void test_dynamic_block_reductions(rotgen::tests::matrix_block_test_case(matrix_construct.init_fn(r, c)); std::vector, Eigen::Block>> test_cases { @@ -113,17 +115,17 @@ TTS_CASE_TPL("Test dynamic block reductions", rotgen::tests::types) std::vector> test_cases = { - {6, 5, [](auto r, auto c) { return T(r + c); }, 1, 2, 3, 2}, - {9, 11, [](auto r, auto c) {return T(r + c); }, 0, 1, 4, 9}, - {3, 3, [](auto , auto ) {return T(0.0); }, 1, 1, 1, 1}, - {1, 4, [](auto r, auto c) {return T(-r -c*c - 1234); }, 0, 0, 1, 1}, - {9, 9, [](auto r, auto c) {return T(-r + 2*c); }, 0, 1, 3, 3}, - {11, 13, [](auto r, auto c) {return T(std::tan(r+c)); }, 1, 1, 2, 2}, - {4, 1, [](auto , auto ) {return T(7.0); }, 2, 0, 2, 1}, - {1, 1, [](auto , auto ) {return T(42.0); }, 0, 0, 1, 1}, - {12, 13, [](auto r, auto c) {return T(std::sin(r + c)); }, 2, 3, 4, 5 }, - {4, 9, [](auto r, auto c) {return T(-1.5 * r + 2.56 * c); }, 0, 1, 2, 3 }, - {2, 5, [](auto r, auto c) {return T(r == c ? 1.0 : 0.0); }, 1, 1, 1, 1}, + {6, 5, [](rotgen::Index r, rotgen::Index c) { return T(r + c); }, 1, 2, 3, 2}, + {9, 11, [](rotgen::Index r, rotgen::Index c) {return T(r + c); }, 0, 1, 4, 9}, + {3, 3, [](rotgen::Index , rotgen::Index ) {return T(0.0); }, 1, 1, 1, 1}, + {1, 4, [](rotgen::Index r, rotgen::Index c) {return T(-r -c*c - 1234); }, 0, 0, 1, 1}, + {9, 9, [](rotgen::Index r, rotgen::Index c) {return T(-r + 2*c); }, 0, 1, 3, 3}, + {11, 13, [](rotgen::Index r, rotgen::Index c) {return T(std::tan(r+c)); }, 1, 1, 2, 2}, + {4, 1, [](rotgen::Index , rotgen::Index ) {return T(7.0); }, 2, 0, 2, 1}, + {1, 1, [](rotgen::Index , rotgen::Index ) {return T(42.0); }, 0, 0, 1, 1}, + {12, 13, [](rotgen::Index r, rotgen::Index c) {return T(std::sin(r + c)); }, 2, 3, 4, 5 }, + {4, 9, [](rotgen::Index r, rotgen::Index c) {return T(-1.5 * r + 2.56 * c); }, 0, 1, 2, 3 }, + {2, 5, [](rotgen::Index r, rotgen::Index c) {return T(r == c ? 1.0 : 0.0); }, 1, 1, 1, 1}, }; for (const auto& test_case : test_cases) diff --git a/test/unit/block/extract.cpp b/test/unit/block/extract.cpp index 0b20451..506edbe 100644 --- a/test/unit/block/extract.cpp +++ b/test/unit/block/extract.cpp @@ -6,22 +6,21 @@ */ //================================================================================================== #include "unit/tests.hpp" -#include -#include +#include template void for_each_element(EigenType const& m, F&& f) { - for(std::size_t i = 0; i < m.rows(); ++i) - for(std::size_t j = 0; j < m.cols(); ++j) + for(rotgen::Index i = 0; i < m.rows(); ++i) + for(rotgen::Index j = 0; j < m.cols(); ++j) f(i, j, m(i,j)); } template void for_each_element(EigenType& m, F&& f) { - for(std::size_t i = 0; i < m.rows(); ++i) - for(std::size_t j = 0; j < m.cols(); ++j) + for(rotgen::Index i = 0; i < m.rows(); ++i) + for(rotgen::Index j = 0; j < m.cols(); ++j) f(i, j, m(i,j)); } @@ -30,8 +29,8 @@ MatrixType make_initialized_matrix(rotgen::tests::matrix_block_test_case(matrix_construct.init_fn(i, j)); return matrix; @@ -39,8 +38,8 @@ MatrixType make_initialized_matrix(rotgen::tests::matrix_block_test_case void validate_block_behavior(MatrixType& matrix, BlockType& block, - std::size_t i0, std::size_t j0, - std::size_t ni, std::size_t nj) + rotgen::Index i0, rotgen::Index j0, + rotgen::Index ni, rotgen::Index nj) { TTS_EQUAL(block.rows(), ni); TTS_EQUAL(block.cols(), nj); @@ -125,13 +124,13 @@ void test_dynamic_block_extraction(rotgen::tests::matrix_block_test_case +template void test_static_block_extraction(rotgen::tests::static_matrix_block_test_case const& matrix_construct) { MatrixType matrix(matrix_construct.rows, matrix_construct.cols); - for (std::size_t i = 0; i < matrix_construct.rows; ++i) - for (std::size_t j = 0; j < matrix_construct.cols; ++j) + for (rotgen::Index i = 0; i < matrix_construct.rows; ++i) + for (rotgen::Index j = 0; j < matrix_construct.cols; ++j) matrix(i, j) = static_cast(matrix_construct.init_fn(i, j)); auto block_main = rotgen::extract(matrix, matrix_construct.i0, matrix_construct.j0); @@ -206,10 +205,10 @@ TTS_CASE_TPL("Check all dynamic block extractions on a dynamic row-major matrix" using mat_t = rotgen::matrix; std::vector> cases = { - { 6, 11, [](std::size_t i, std::size_t j) { return T(i * 10 + j); }, 1, 2, 3, 2 }, - { 7, 10, [](std::size_t i, std::size_t j) { return T(std::sin(i + j)); }, 4, 4, 3, 3 }, - { 5, 5, [](std::size_t i, std::size_t j) { return T((i + j) % 7); }, 0, 0, 5, 5 }, - { 9, 14, [](std::size_t i, std::size_t j) { return T(i+j + 3*j); }, 3, 7, 1, 1 } + { 6, 11, [](rotgen::Index i, rotgen::Index j) { return T(i * 10 + j); }, 1, 2, 3, 2 }, + { 7, 10, [](rotgen::Index i, rotgen::Index j) { return T(std::sin(i + j)); }, 4, 4, 3, 3 }, + { 5, 5, [](rotgen::Index i, rotgen::Index j) { return T((i + j) % 7); }, 0, 0, 5, 5 }, + { 9, 14, [](rotgen::Index i, rotgen::Index j) { return T(i+j + 3*j); }, 3, 7, 1, 1 } }; for (auto const& matrix_case : cases) { @@ -224,9 +223,9 @@ TTS_CASE_TPL("Check all dynamic block extractions on a static column-major matri using mat_t = rotgen::matrix; std::vector> cases = { - { 4, 5, [](std::size_t i, std::size_t j) { return T(2*i + j*j*j - 42); }, 1, 2, 3, 2 }, - { 4, 5, [](std::size_t i, std::size_t j) { return T(std::tan(i*i*j)); }, 0, 1, 2, 1 }, - { 4, 5, [](std::size_t i, std::size_t j) { return T((i*i + j*j) / 6); }, 2, 0, 0, 0 } + { 4, 5, [](auto i, auto j) { return T(2*i + j*j*j - 42); }, 1, 2, 3, 2 }, + { 4, 5, [](auto i, auto j) { return T(std::tan(i*i*j)); }, 0, 1, 2, 1 }, + { 4, 5, [](auto i, auto j) { return T((i*i + j*j) / 6); }, 2, 0, 0, 0 } }; for (auto const& matrix_case : cases) { @@ -241,26 +240,26 @@ TTS_CASE_TPL("Check all static block extractions", rotgen::tests::types) using mat_t = rotgen::matrix; test_static_block_extraction( - rotgen::tests::static_matrix_block_test_case{ - 11, 11, - [](std::size_t i, std::size_t j) { return T(i*i*i + 3*j - 127); }, - 3, 2 + rotgen::tests::static_matrix_block_test_case{ + 11, 11, + [](rotgen::Index i, rotgen::Index j) { return T(i*i*i + 3*j - 127); }, + 3, 2 } ); test_static_block_extraction( - rotgen::tests::static_matrix_block_test_case{ - 14, 15, - [](std::size_t i, std::size_t j) { return T(std::cos(i * j * 2)); }, - 5, 1 + rotgen::tests::static_matrix_block_test_case{ + 14, 15, + [](rotgen::Index i, rotgen::Index j) { return T(std::cos(i * j * 2)); }, + 5, 1 } ); test_static_block_extraction( - rotgen::tests::static_matrix_block_test_case{ - 5, 5, - [](std::size_t i, std::size_t j) { return T((i + j) % 9); }, - 0, 0 + rotgen::tests::static_matrix_block_test_case{ + 5, 5, + [](rotgen::Index i, rotgen::Index j) { return T((i + j) % 9); }, + 0, 0 } ); }; \ No newline at end of file diff --git a/test/unit/block/norms.cpp b/test/unit/block/norms.cpp index 7a30347..f0e466b 100644 --- a/test/unit/block/norms.cpp +++ b/test/unit/block/norms.cpp @@ -6,8 +6,7 @@ */ //================================================================================================== #include "unit/tests.hpp" -#include -#include +#include #include TTS_CASE_TPL("Matrix norm-related operations", rotgen::tests::types) @@ -17,15 +16,15 @@ TTS_CASE_TPL("Matrix norm-related operations", rotgen::tests::types) std::vector> test_cases = { - {6, 5, [](auto r, auto c) {return r + c; }, 1, 2, 3, 2}, - {9, 11, [](auto r, auto c) {return r + c; }, 0, 1, 4, 9}, - {3, 3, [](auto , auto ) {return 0.0; }, 1, 1, 1, 1}, - {1, 4, [](auto r, auto c) {return -r -c*c - 1234; }, 0, 0, 1, 1}, - {4, 1, [](auto , auto ) {return 7.0; }, 2, 0, 2, 1}, - {1, 1, [](auto , auto ) {return 42.0; }, 0, 0, 1, 1}, - {12, 13, [](auto r, auto c) {return std::sin(r + c); }, 2, 3, 4, 5 }, - {4, 9, [](auto r, auto c) {return -1.5 * r + 2.56 * c; }, 0, 1, 2, 3 }, - {2, 5, [](auto r, auto c) {return (r == c ? 1.0 : 0.0); }, 1, 1, 1, 1}, + {6, 5, [](rotgen::Index r, rotgen::Index c) {return r + c; }, 1, 2, 3, 2}, + {9, 11, [](rotgen::Index r, rotgen::Index c) {return r + c; }, 0, 1, 4, 9}, + {3, 3, [](rotgen::Index , rotgen::Index ) {return 0.0; }, 1, 1, 1, 1}, + {1, 4, [](rotgen::Index r, rotgen::Index c) {return -r -c*c - 1234; }, 0, 0, 1, 1}, + {4, 1, [](rotgen::Index , rotgen::Index ) {return 7.0; }, 2, 0, 2, 1}, + {1, 1, [](rotgen::Index , rotgen::Index ) {return 42.0; }, 0, 0, 1, 1}, + {12, 13, [](rotgen::Index r, rotgen::Index c) {return std::sin(r + c); }, 2, 3, 4, 5 }, + {4, 9, [](rotgen::Index r, rotgen::Index c) {return -1.5 * r + 2.56 * c; }, 0, 1, 2, 3 }, + {2, 5, [](rotgen::Index r, rotgen::Index c) {return (r == c ? 1.0 : 0.0); }, 1, 1, 1, 1}, }; for (const auto& [rows, cols, fn, i0, j0, ni, nj] : test_cases) @@ -33,8 +32,8 @@ TTS_CASE_TPL("Matrix norm-related operations", rotgen::tests::types) rotgen::matrix original_matrix(rows, cols); Eigen::Matrix ref_matrix(rows, cols); - for (std::size_t r = 0; r < rows; ++r) - for (std::size_t c = 0; c < cols; ++c) + for (rotgen::Index r = 0; r < rows; ++r) + for (rotgen::Index c = 0; c < cols; ++c) ref_matrix(r, c) = original_matrix(r, c) = fn(r,c); auto original_block = rotgen::extract(original_matrix, i0, j0, ni, nj); diff --git a/test/unit/block/operators.cpp b/test/unit/block/operators.cpp index 64b91a5..f135e59 100644 --- a/test/unit/block/operators.cpp +++ b/test/unit/block/operators.cpp @@ -6,8 +6,7 @@ */ //================================================================================================== #include "unit/tests.hpp" -#include -#include +#include #include template @@ -21,9 +20,11 @@ void test_block_matrix_operations(rotgen::tests::matrix_block_test_case(matrix_construct.init_fn(r, c)); ref_b(r,c) = b(r,c) = static_cast(b_init_fn(r, c)); @@ -42,20 +43,20 @@ void test_block_matrix_operations(rotgen::tests::matrix_block_test_case(matrix_construct.init_fn(r, c)); auto a_block = rotgen::extract(a, matrix_construct.i0, matrix_construct.j0, @@ -84,19 +87,19 @@ void test_block_scalar_operations(rotgen::tests::matrix_block_test_case(matrix_construct.init_fn(r, c)); auto a_block = rotgen::extract(a, matrix_construct.i0, matrix_construct.j0, @@ -123,9 +129,9 @@ void test_scalar_block_multiplications(rotgen::tests::matrix_block_test_case EigenMatrix ref_a(a_matrix_construct.rows, a_matrix_construct.cols); EigenMatrix ref_b(b_matrix_construct.rows, b_matrix_construct.cols); - for (std::size_t r = 0; r < a_matrix_construct.rows; ++r) - for (std::size_t c = 0; c < a_matrix_construct.cols; ++c) + for (rotgen::Index r = 0; r < a_matrix_construct.rows; ++r) + for (rotgen::Index c = 0; c < a_matrix_construct.cols; ++c) ref_a(r,c) = a(r,c) = static_cast(a_matrix_construct.init_fn(r, c)); - for (std::size_t r = 0; r < b_matrix_construct.rows; ++r) - for (std::size_t c = 0; c < b_matrix_construct.cols; ++c) + for (rotgen::Index r = 0; r < b_matrix_construct.rows; ++r) + for (rotgen::Index c = 0; c < b_matrix_construct.cols; ++c) ref_b(r,c) = b(r,c) = static_cast(b_matrix_construct.init_fn(r, c)); @@ -173,26 +179,28 @@ void test_block_multiplication(rotgen::tests::matrix_block_test_case auto ref_b_block = ref_b.block(b_matrix_construct.i0, b_matrix_construct.j0, b_matrix_construct.ni, b_matrix_construct.nj); + TTS_EXPECT(verify_rotgen_reentrance(a_block * b_block)); + auto a_b_product_original = a_block * b_block; auto a_b_product_ref = ref_a_block * ref_b_block; - for (std::size_t r = 0; r < a_matrix_construct.ni; ++r) - for (std::size_t c = 0; c < a_matrix_construct.nj; ++c) + for (rotgen::Index r = 0; r < a_matrix_construct.ni; ++r) + for (rotgen::Index c = 0; c < a_matrix_construct.nj; ++c) TTS_EQUAL(a_b_product_original (r, c), a_b_product_ref(r, c)); a_block *= b_block; ref_a_block *= ref_b_block; - for (std::size_t r = 0; r < a_matrix_construct.ni; ++r) - for (std::size_t c = 0; c < a_matrix_construct.nj; ++c) + for (rotgen::Index r = 0; r < a_matrix_construct.ni; ++r) + for (rotgen::Index c = 0; c < a_matrix_construct.nj; ++c) TTS_EQUAL(a_block(r, c), ref_a_block(r, c)); - for (std::size_t r = 0; r < a_matrix_construct.rows; ++r) - for (std::size_t c = 0; c < a_matrix_construct.cols; ++c) + for (rotgen::Index r = 0; r < a_matrix_construct.rows; ++r) + for (rotgen::Index c = 0; c < a_matrix_construct.cols; ++c) TTS_EQUAL(a(r, c), ref_a(r, c)); - for (std::size_t r = 0; r < b_matrix_construct.rows; ++r) - for (std::size_t c = 0; c < b_matrix_construct.cols; ++c) + for (rotgen::Index r = 0; r < b_matrix_construct.rows; ++r) + for (rotgen::Index c = 0; c < b_matrix_construct.cols; ++c) TTS_EQUAL(b(r, c), ref_b(r, c)); } @@ -244,7 +252,7 @@ TTS_CASE_TPL("Check block multiplications", rotgen::tests::types) ( tts::type< tts::types> ) { using mat_t = rotgen::matrix; - auto init_id = [](auto r, auto c) { return r == c ? 1 : 0; }; + auto init_id = [](rotgen::Index r, rotgen::Index c) { return r == c ? 1 : 0; }; test_block_multiplication({1 , 1, init_a, 0, 0, 1, 1}, {1 , 1, init_b, 0, 0, 1, 1}); test_block_multiplication({13 , 15, init_b, 1, 2, 4, 4}, {13 , 15, init_b, 0, 1, 4, 4}); diff --git a/test/unit/block/static_functions.cpp b/test/unit/block/static_functions.cpp index 7b210ab..44e6efa 100644 --- a/test/unit/block/static_functions.cpp +++ b/test/unit/block/static_functions.cpp @@ -6,40 +6,42 @@ */ //================================================================================================== #include "unit/tests.hpp" -#include -#include +#include -void test_size(const auto& matrix, std::size_t rows, std::size_t cols) +void test_size(const auto& matrix, rotgen::Index rows, rotgen::Index cols) { TTS_EQUAL(matrix.rows(), rows); TTS_EQUAL(matrix.cols(), cols); TTS_EQUAL(matrix.size(), rows*cols); } -void test_value(const auto& matrix, std::size_t rows, std::size_t cols, auto constant) +void test_value(const auto& matrix, rotgen::Index rows, rotgen::Index cols, auto constant) { + TTS_EXPECT(verify_rotgen_reentrance(matrix)); test_size(matrix, rows, cols); - for(std::size_t r=0;r -#include "tts.hpp" +#include "unit/tests.hpp" +#include #include -#include "rotgen/functions.hpp" template struct MatrixDescriptor @@ -38,6 +36,10 @@ void test_matrix_unary_ops(std::size_t rows, std::size_t cols, TTS_EQUAL(rotgen::conjugate(original), original); TTS_EQUAL(rotgen::adjoint(original), transposed_matrix); + TTS_EXPECT(verify_rotgen_reentrance(rotgen::transpose(original))); + TTS_EXPECT(verify_rotgen_reentrance(rotgen::conjugate(original))); + TTS_EXPECT(verify_rotgen_reentrance(rotgen::adjoint(original))); + rotgen::transposeInPlace(original); TTS_EQUAL(original, transposed_matrix); diff --git a/test/unit/free_functions/functions.cpp b/test/unit/free_functions/functions.cpp index f807b40..8490d38 100644 --- a/test/unit/free_functions/functions.cpp +++ b/test/unit/free_functions/functions.cpp @@ -5,15 +5,11 @@ SPDX-License-Identifier: BSL-1.0 */ //================================================================================================== -#define TTS_MAIN -#include -#include -#include "tts.hpp" +#include "unit/tests.hpp" +#include #include #include - - template struct MatrixDescriptor { diff --git a/test/unit/free_functions/norms.cpp b/test/unit/free_functions/norms.cpp index 084e42e..832952e 100644 --- a/test/unit/free_functions/norms.cpp +++ b/test/unit/free_functions/norms.cpp @@ -5,10 +5,8 @@ SPDX-License-Identifier: BSL-1.0 */ //================================================================================================== -#define TTS_MAIN -#include -#include -#include "tts.hpp" +#include "unit/tests.hpp" +#include #include template diff --git a/test/unit/matrix/arithmetic_functions.cpp b/test/unit/matrix/arithmetic_functions.cpp index b51e47e..c2ad1a9 100644 --- a/test/unit/matrix/arithmetic_functions.cpp +++ b/test/unit/matrix/arithmetic_functions.cpp @@ -6,7 +6,7 @@ */ //================================================================================================== #include "unit/tests.hpp" -#include +#include #include template @@ -27,6 +27,10 @@ void test_matrix_unary_ops(std::size_t rows, std::size_t cols, auto const &init_ TTS_EQUAL(original.conjugate(), original); TTS_EQUAL(original.adjoint(), transposed_matrix); + TTS_EXPECT(verify_rotgen_reentrance(original.transpose())); + TTS_EXPECT(verify_rotgen_reentrance(original.conjugate())); + TTS_EXPECT(verify_rotgen_reentrance(original.adjoint())); + original.transposeInPlace(); TTS_EQUAL(original, transposed_matrix); diff --git a/test/unit/matrix/constructors.cpp b/test/unit/matrix/constructors.cpp index 5506c34..993ccea 100644 --- a/test/unit/matrix/constructors.cpp +++ b/test/unit/matrix/constructors.cpp @@ -6,15 +6,15 @@ */ //================================================================================================== #include "unit/tests.hpp" -#include +#include TTS_CASE_TPL("Default matrix dynamic constructor", rotgen::tests::types) ( tts::type< tts::types> ) { rotgen::matrix matrix; - TTS_EQUAL(matrix.rows(), 0ULL); - TTS_EQUAL(matrix.cols(), 0ULL); + TTS_EQUAL(matrix.rows(), rotgen::Index{0}); + TTS_EQUAL(matrix.cols(), rotgen::Index{0}); }; TTS_CASE_TPL("Default matrix static constructor", rotgen::tests::types) @@ -22,8 +22,8 @@ TTS_CASE_TPL("Default matrix static constructor", rotgen::tests::types) { rotgen::matrix matrix; - TTS_EQUAL(matrix.rows(), 4ULL); - TTS_EQUAL(matrix.cols(), 9ULL); + TTS_EQUAL(matrix.rows(), rotgen::Index{4}); + TTS_EQUAL(matrix.cols(), rotgen::Index{9}); }; TTS_CASE_TPL("Dynamic matrix constructor with row and columns", rotgen::tests::types) @@ -31,8 +31,8 @@ TTS_CASE_TPL("Dynamic matrix constructor with row and columns", rotgen::tests::t { rotgen::matrix matrix(10, 5); - TTS_EQUAL(matrix.rows(), 10ULL); - TTS_EQUAL(matrix.cols(), 5ULL); + TTS_EQUAL(matrix.rows(), rotgen::Index{10}); + TTS_EQUAL(matrix.cols(), rotgen::Index{5}); }; TTS_CASE_TPL("Static matrix constructor with row and columns", rotgen::tests::types) @@ -40,8 +40,8 @@ TTS_CASE_TPL("Static matrix constructor with row and columns", rotgen::tests::ty { rotgen::matrix matrix(6, 11); - TTS_EQUAL(matrix.rows(), 6ULL); - TTS_EQUAL(matrix.cols(), 11ULL); + TTS_EQUAL(matrix.rows(), rotgen::Index{6}); + TTS_EQUAL(matrix.cols(), rotgen::Index{11}); }; TTS_CASE_TPL("Copy constructor produces identical but independent matrix", rotgen::tests::types) @@ -49,8 +49,8 @@ TTS_CASE_TPL("Copy constructor produces identical but independent matrix", rotge { rotgen::matrix a(3, 3); - for(std::size_t r=0;r b = a; @@ -58,8 +58,8 @@ TTS_CASE_TPL("Copy constructor produces identical but independent matrix", rotge TTS_EQUAL(b.rows(), a.rows()); TTS_EQUAL(b.cols(), a.cols()); - for(std::size_t r=0;r a; rotgen::matrix b = a; - TTS_EQUAL(b.rows(), 0ULL); - TTS_EQUAL(b.cols(), 0ULL); + TTS_EQUAL(b.rows(), rotgen::Index{0}); + TTS_EQUAL(b.cols(), rotgen::Index{0}); }; TTS_CASE_TPL("Copy constructor from const matrix", rotgen::tests::types) @@ -84,17 +84,17 @@ TTS_CASE_TPL("Copy constructor from const matrix", rotgen::tests::types) { const rotgen::matrix a(2, 2); auto b = a; - TTS_EQUAL(b.rows(), 2ULL); - TTS_EQUAL(b.cols(), 2ULL); + TTS_EQUAL(b.rows(), rotgen::Index{2}); + TTS_EQUAL(b.cols(), rotgen::Index{2}); }; TTS_CASE_TPL("Copy constructor on static matrix", rotgen::tests::types) ( tts::type< tts::types> ) { - rotgen::matrix a; - rotgen::matrix b = a; - TTS_EQUAL(b.rows(), 2ULL); - TTS_EQUAL(b.cols(), 5ULL); + rotgen::matrix a; + rotgen::matrix b = a; + TTS_EQUAL(b.rows(), rotgen::Index{2}); + TTS_EQUAL(b.cols(), rotgen::Index{5}); }; /* @@ -126,8 +126,8 @@ TTS_CASE_TPL("Move constructor transfers contents", rotgen::tests::types) rotgen::matrix b = std::move(a); TTS_EQUAL(b(1,1), 7); - TTS_EQUAL(b.rows(), 3ULL); - TTS_EQUAL(b.cols(), 3ULL); + TTS_EQUAL(b.rows(), rotgen::Index{3}); + TTS_EQUAL(b.cols(), rotgen::Index{3}); TTS_EXPECT(b.data() == ptr); }; @@ -135,31 +135,32 @@ TTS_CASE_TPL("Move constructor from Rvalue", rotgen::tests::types) ( tts::type< tts::types> ) { rotgen::matrix b = rotgen::matrix(2, 2); - TTS_EQUAL(b.rows(), 2ULL); - TTS_EQUAL(b.cols(), 2ULL); + TTS_EQUAL(b.rows(), rotgen::Index{2}); + TTS_EQUAL(b.cols(), rotgen::Index{2}); }; TTS_CASE_TPL("Constructor from Initializer list", rotgen::tests::types) ( tts::type< tts::types> ) { - rotgen::matrix b1 = {3.5}; - TTS_EQUAL(b1.rows(), 1ULL); - TTS_EQUAL(b1.cols(), 1ULL); + rotgen::matrix b1{3.5}; + TTS_EQUAL(b1.rows(), rotgen::Index{1}); + TTS_EQUAL(b1.cols(), rotgen::Index{1}); TTS_EQUAL(b1(0) , 3.5); - rotgen::matrix b9 = {0.25, 0.5, 1, 2, 4}; - TTS_EQUAL(b9.rows(), 5ULL); - TTS_EQUAL(b9.cols(), 1ULL); + rotgen::matrix b9{0.25, 0.5, 1, 2, 4}; + TTS_EQUAL(b9.rows(), rotgen::Index{5}); + TTS_EQUAL(b9.cols(), rotgen::Index{1}); T i = 0.25; - for(std::size_t r=0;r b13 = {1.2,2.3,3.4}; - TTS_EQUAL(b13.rows(), 1ULL); - TTS_EQUAL(b13.cols(), 3ULL); + rotgen::matrix b13{1.2,2.3,3.4}; + TTS_EQUAL(b13.rows(), rotgen::Index{1}); + TTS_EQUAL(b13.cols(), rotgen::Index{3}); TTS_EQUAL(b13(0) , T(1.2)); TTS_EQUAL(b13(1) , T(2.3)); TTS_EQUAL(b13(2) , T(3.4)); @@ -168,16 +169,18 @@ TTS_CASE_TPL("Constructor from Initializer list", rotgen::tests::types) TTS_CASE_TPL("Constructor from Initializer list of rows", rotgen::tests::types) ( tts::type< tts::types> ) { - rotgen::matrix b1 = {{3.5}}; - TTS_EQUAL(b1.rows(), 1ULL); - TTS_EQUAL(b1.cols(), 1ULL); + rotgen::matrix b1{{3.5}}; + TTS_EQUAL(b1.rows(), rotgen::Index{1}); + TTS_EQUAL(b1.cols(), rotgen::Index{1}); TTS_EQUAL(b1(0,0) , T(3.5)); - rotgen::matrix b23 = { {1.2,2.3,3.4} - , {10,200,3000} - }; - TTS_EQUAL(b23.rows(), 2ULL); - TTS_EQUAL(b23.cols(), 3ULL); + rotgen::matrix + b23 { {1.2,2.3,3.4} + , {10,200,3000} + }; + + TTS_EQUAL(b23.rows(), rotgen::Index{2}); + TTS_EQUAL(b23.cols(), rotgen::Index{3}); TTS_EQUAL(b23(0,0) , T(1.2)); TTS_EQUAL(b23(0,1) , T(2.3)); TTS_EQUAL(b23(0,2) , T(3.4)); diff --git a/test/unit/matrix/functions.cpp b/test/unit/matrix/functions.cpp index 5de37fa..82c26e0 100644 --- a/test/unit/matrix/functions.cpp +++ b/test/unit/matrix/functions.cpp @@ -6,7 +6,7 @@ */ //================================================================================================== #include "unit/tests.hpp" -#include +#include TTS_CASE_TPL("Function size", rotgen::tests::types) ( tts::type< tts::types> ) @@ -16,10 +16,10 @@ TTS_CASE_TPL("Function size", rotgen::tests::types) rotgen::matrix row_vector(9,1); rotgen::matrix column_vector(1,5); - TTS_EQUAL(empty_matrix.size(), 0ULL); - TTS_EQUAL(matrix.size(), 12ULL); - TTS_EQUAL(row_vector.size(), 9ULL); - TTS_EQUAL(column_vector.size(), 5ULL); + TTS_EQUAL(empty_matrix.size(), rotgen::Index{0}); + TTS_EQUAL(matrix.size(), rotgen::Index{12}); + TTS_EQUAL(row_vector.size(), rotgen::Index{9}); + TTS_EQUAL(column_vector.size(), rotgen::Index{5}); }; TTS_CASE_TPL("Resizing dynamic matrix", rotgen::tests::types) @@ -27,21 +27,21 @@ TTS_CASE_TPL("Resizing dynamic matrix", rotgen::tests::types) { rotgen::matrix a(2, 3); - for(std::size_t r=0;r a(2, 3); int i = 1; - for(std::size_t r=0;r a(3, 5); - for(std::size_t r=0;r +#include #include TTS_CASE_TPL("Sample test", rotgen::tests::types) @@ -17,4 +17,4 @@ TTS_CASE_TPL("Sample test", rotgen::tests::types) os << x; TTS_EQUAL(os.str(), std::string{"1 2\n3 4"}); -}; \ No newline at end of file +}; diff --git a/test/unit/matrix/norms.cpp b/test/unit/matrix/norms.cpp index 52d4a9e..8b4819b 100644 --- a/test/unit/matrix/norms.cpp +++ b/test/unit/matrix/norms.cpp @@ -6,7 +6,7 @@ */ //================================================================================================== #include "unit/tests.hpp" -#include +#include #include TTS_CASE_TPL("Matrix norm-related operations", rotgen::tests::types) @@ -30,9 +30,9 @@ TTS_CASE_TPL("Matrix norm-related operations", rotgen::tests::types) rotgen::matrix matrix(rows, cols); Eigen::Matrix ref(rows, cols); - for (std::size_t r = 0; r < rows; ++r) + for (rotgen::Index r = 0; r < rows; ++r) { - for (std::size_t c = 0; c < cols; ++c) + for (rotgen::Index c = 0; c < cols; ++c) { ref(r, c) = matrix(r, c) = fn(r,c); } @@ -40,8 +40,8 @@ TTS_CASE_TPL("Matrix norm-related operations", rotgen::tests::types) TTS_EQUAL(matrix.norm(), ref.norm()); TTS_EQUAL(matrix.squaredNorm(), ref.squaredNorm()); - TTS_EQUAL(matrix.template lp_norm<1>() , ref.template lpNorm<1>()); - TTS_EQUAL(matrix.template lp_norm<2>() , ref.template lpNorm<2>()); - TTS_EQUAL(matrix.template lp_norm(), ref.template lpNorm()); + TTS_EQUAL(matrix.template lpNorm<1>() , ref.template lpNorm<1>()); + TTS_EQUAL(matrix.template lpNorm<2>() , ref.template lpNorm<2>()); + TTS_EQUAL(matrix.template lpNorm(), ref.template lpNorm()); } }; \ No newline at end of file diff --git a/test/unit/matrix/operators.cpp b/test/unit/matrix/operators.cpp index fd1930e..0f207ac 100644 --- a/test/unit/matrix/operators.cpp +++ b/test/unit/matrix/operators.cpp @@ -6,18 +6,18 @@ */ //================================================================================================== #include "unit/tests.hpp" -#include +#include template -void test_matrix_operations(std::size_t rows, std::size_t cols, auto a_init_fn, auto b_init_fn, auto ops, auto self_ops) +void test_matrix_operations(rotgen::Index rows, rotgen::Index cols, auto a_init_fn, auto b_init_fn, auto ops, auto self_ops) { MatrixType a(rows, cols); MatrixType b(rows, cols); MatrixType ref(rows, cols); - for (std::size_t r = 0; r < rows; ++r) + for (rotgen::Index r = 0; r < rows; ++r) { - for (std::size_t c = 0; c < cols; ++c) + for (rotgen::Index c = 0; c < cols; ++c) { a(r,c) = a_init_fn(r, c); b(r,c) = b_init_fn(r, c); @@ -28,17 +28,20 @@ void test_matrix_operations(std::size_t rows, std::size_t cols, auto a_init_fn, TTS_EQUAL(ops(a, b), ref); self_ops(a,b); TTS_EQUAL(a, ref); + + TTS_EXPECT(verify_rotgen_reentrance(ops(a, b))); + TTS_EXPECT(verify_rotgen_reentrance(self_ops(a, b))); } template -void test_scalar_operations(std::size_t rows, std::size_t cols, auto a_init_fn, auto s, auto ops, auto self_ops) +void test_scalar_operations(rotgen::Index rows, rotgen::Index cols, auto a_init_fn, auto s, auto ops, auto self_ops) { MatrixType a(rows, cols); MatrixType ref(rows, cols); - for (std::size_t r = 0; r < rows; ++r) + for (rotgen::Index r = 0; r < rows; ++r) { - for (std::size_t c = 0; c < cols; ++c) + for (rotgen::Index c = 0; c < cols; ++c) { a(r,c) = a_init_fn(r, c); ref(r, c) = ops(a(r,c),s); @@ -48,17 +51,20 @@ void test_scalar_operations(std::size_t rows, std::size_t cols, auto a_init_fn, TTS_EQUAL(ops(a, s), ref); self_ops(a,s); TTS_EQUAL(a, ref); + + TTS_EXPECT(verify_rotgen_reentrance(ops(a, s))); + TTS_EXPECT(verify_rotgen_reentrance(self_ops(a, s))); } template -void test_scalar_multiplications(std::size_t rows, std::size_t cols, auto fn, auto s) +void test_scalar_multiplications(rotgen::Index rows, rotgen::Index cols, auto fn, auto s) { MatrixType a(rows, cols); MatrixType ref(rows, cols); - for (std::size_t r = 0; r < rows; ++r) + for (rotgen::Index r = 0; r < rows; ++r) { - for (std::size_t c = 0; c < cols; ++c) + for (rotgen::Index c = 0; c < cols; ++c) { a(r,c) = fn(r, c); ref(r, c) = a(r,c) * s; @@ -69,34 +75,39 @@ void test_scalar_multiplications(std::size_t rows, std::size_t cols, auto fn, au TTS_EQUAL(s * a, ref); a *= s; TTS_EQUAL(a, ref); + + TTS_EXPECT(verify_rotgen_reentrance(a*s)); + TTS_EXPECT(verify_rotgen_reentrance(s*a)); + TTS_EXPECT(verify_rotgen_reentrance(a*=s)); } template -void test_matrix_multiplication(std::size_t rows, std::size_t cols, auto a_init_fn, auto b_init_fn) +void test_matrix_multiplication(rotgen::Index rows, rotgen::Index cols, auto a_init_fn, auto b_init_fn) { MatrixType a(rows, cols); MatrixType b(cols, rows); MatrixType ref(rows, rows); - for (std::size_t r = 0; r < a.rows(); ++r) - for (std::size_t c = 0; c < a.cols(); ++c) + for (rotgen::Index r = 0; r < a.rows(); ++r) + for (rotgen::Index c = 0; c < a.cols(); ++c) a(r,c) = a_init_fn(r, c); - for (std::size_t r = 0; r < b.rows(); ++r) - for (std::size_t c = 0; c < b.cols(); ++c) + for (rotgen::Index r = 0; r < b.rows(); ++r) + for (rotgen::Index c = 0; c < b.cols(); ++c) b(r,c) = b_init_fn(r, c); - for (std::size_t i = 0; i < a.rows(); ++i) + for (rotgen::Index i = 0; i < a.rows(); ++i) { - for (std::size_t j = 0; j < b.cols(); ++j) + for (rotgen::Index j = 0; j < b.cols(); ++j) { ref(i, j) = 0; - for (std::size_t k = 0; k < a.cols(); ++k) + for (rotgen::Index k = 0; k < a.cols(); ++k) ref(i, j) += a(i, k) * b(k, j); } } TTS_EQUAL(a * b, ref); + TTS_EXPECT(verify_rotgen_reentrance(a*b)); } // Basic initializers diff --git a/test/unit/matrix/static_functions.cpp b/test/unit/matrix/static_functions.cpp index deb95e4..48d98ef 100644 --- a/test/unit/matrix/static_functions.cpp +++ b/test/unit/matrix/static_functions.cpp @@ -6,10 +6,11 @@ */ //================================================================================================== #include "unit/tests.hpp" -#include +#include void test_value(const auto& matrix, std::size_t rows, std::size_t cols, auto constant) { + TTS_EXPECT(verify_rotgen_reentrance(matrix)); for(std::size_t r=0;r +#include +#include #include namespace rotgen::tests @@ -25,25 +28,50 @@ namespace rotgen::tests struct matrix_descriptor { - std::size_t rows, cols; + rotgen::Index rows, cols; std::function init_fn; }; template struct matrix_block_test_case { - std::size_t rows, cols; - std::function init_fn; - std::size_t i0, j0, ni, nj; + rotgen::Index rows, cols; + std::function init_fn; + rotgen::Index i0, j0, ni, nj; }; - template + template struct static_matrix_block_test_case { - std::size_t rows, cols; - std::function init_fn; - static constexpr std::size_t ni = NI; - static constexpr std::size_t nj = NJ; - std::size_t i0, j0; + rotgen::Index rows, cols; + std::function init_fn; + static constexpr rotgen::Index ni = NI; + static constexpr rotgen::Index nj = NJ; + rotgen::Index i0, j0; }; +} + +#include + +template +constexpr bool verify_rotgen_reentrance(T const&) +{ + return rotgen::concepts::entity; +} + +int main(int argc, char const **argv) +{ + ::tts::initialize(argc,argv); +#ifdef NDEBUG + constexpr auto assert_status = "Disabled"; +#else + constexpr auto assert_status = "Enabled"; +#endif + + std::cout << "[ROTGEN] - Assertions: " << assert_status << std::endl; + + rotgen::setup_summary(std::cout); + + rotgen_main(argc, argv); + return tts::report(0,0); } \ No newline at end of file