From 399f17af57fe3ea23401b461cc269d4e948e9a77 Mon Sep 17 00:00:00 2001 From: Joel Falcou Date: Wed, 17 Sep 2025 09:51:46 +0200 Subject: [PATCH] Fix some ref/map/block non-trivial interactions. --- include/rotgen/common/ref.hpp | 21 ++++---- include/rotgen/common/strides.hpp | 13 +++-- include/rotgen/dynamic/map.hpp | 12 ++++- include/rotgen/fixed/map.hpp | 14 ++++-- include/rotgen/impl/map_model.hpp | 1 + src/map_model.cpp | 5 +- test/integration/outer_stride.cpp | 83 +++++++++++++++++++++++++++++++ 7 files changed, 127 insertions(+), 22 deletions(-) create mode 100644 test/integration/outer_stride.cpp diff --git a/include/rotgen/common/ref.hpp b/include/rotgen/common/ref.hpp index 4d27f5d..33f5ef3 100644 --- a/include/rotgen/common/ref.hpp +++ b/include/rotgen/common/ref.hpp @@ -139,22 +139,21 @@ namespace rotgen template S, int R, int C, int O, int MR, int MC> ref(matrix const& m) + requires((O & 1) == storage_order) : parent(m.data(), m.rows(), m.cols(), strides(m)) - { - static_assert((O & 1) == storage_order, "ref: Incompatible storage layout"); - } + {} template - ref(block const& b) : parent(b.data(), b.rows(), b.cols(), stride_type{b.outerStride(),b.innerStride()}) - { - static_assert((Ref::storage_order & 1) == storage_order, "ref: Incompatible storage layout"); - } + ref ( block const& b ) + requires(std::same_as && (Ref::storage_order & 1) == storage_order) + : parent(b.data(), b.rows(), b.cols(), stride_type{b.outerStride(),b.innerStride()}) + {} template - ref(map const& b) : parent(b.data(), b.rows(), b.cols(), stride_type{b.outerStride(),b.innerStride()}) - { - static_assert((Ref::storage_order & 1) == storage_order, "ref: Incompatible storage layout"); - } + ref ( map const& b ) + requires(std::same_as && (Ref::storage_order & 1) == storage_order) + : parent(b.data(), b.rows(), b.cols(), stride_type{b.outerStride(),b.innerStride()}) + {} ref(parent const& m) : parent(m.data(), m.rows(), m.cols()) {} diff --git a/include/rotgen/common/strides.hpp b/include/rotgen/common/strides.hpp index a437205..5d2779f 100644 --- a/include/rotgen/common/strides.hpp +++ b/include/rotgen/common/strides.hpp @@ -20,6 +20,8 @@ namespace rotgen #else struct stride { + static constexpr bool is_dynamic = true; + stride() : outer_(-1), inner_(1) {} stride(Index s, Index i) : outer_(s), inner_(i) {} @@ -35,6 +37,7 @@ namespace rotgen template struct inner_stride : stride { + static constexpr bool is_dynamic = Value == Dynamic; inner_stride() : stride(-1,Value) {} inner_stride(Index v) : stride(0, v) {} }; @@ -42,6 +45,7 @@ namespace rotgen template struct outer_stride : stride { + static constexpr bool is_dynamic = Value == Dynamic; outer_stride() : stride(Value,0) {} outer_stride(Index v) : stride(v,0) {} }; @@ -57,15 +61,16 @@ namespace rotgen } template - stride strides(stride original) + stride strides(stride const& original,Index, Index) { return original; } - template - stride strides(outer_stride const& original) + template + stride strides(outer_stride const& original,Index r, Index c) { - return {original.outer(),1}; + if constexpr(N==0) return stride{ Order==ColMajor ? r : c, 1}; + else return {original.outer(),1}; } template diff --git a/include/rotgen/dynamic/map.hpp b/include/rotgen/dynamic/map.hpp index 67c4b23..545dfde 100644 --- a/include/rotgen/dynamic/map.hpp +++ b/include/rotgen/dynamic/map.hpp @@ -40,8 +40,16 @@ namespace rotgen static constexpr Index RowsAtCompileTime = Ref::RowsAtCompileTime; static constexpr Index ColsAtCompileTime = Ref::ColsAtCompileTime; - map(ptr_type ptr, Index r, Index c, stride_type s) : parent(ptr, r, c, strides(s)) {} - map(ptr_type ptr, Index r, Index c) : parent(ptr, r, c, strides(r,c)) {} + map(ptr_type ptr, Index r, Index c, stride_type s) : parent(ptr, r, c, strides(s,r,c)) {} + map(ptr_type ptr, Index r, Index c) + : parent( ptr, r, c + , [&]() + { + if constexpr(!std::same_as) return strides(Stride{},r,c); + else return strides(r,c); + }() + ) + {} map(ptr_type ptr, stride_type s) requires(RowsAtCompileTime!=-1 && ColsAtCompileTime!=-1) : parent(ptr,RowsAtCompileTime,ColsAtCompileTime, strides(s)) diff --git a/include/rotgen/fixed/map.hpp b/include/rotgen/fixed/map.hpp index 40772bd..2058c56 100644 --- a/include/rotgen/fixed/map.hpp +++ b/include/rotgen/fixed/map.hpp @@ -58,11 +58,19 @@ namespace rotgen map& operator=(const map&) = default; map& operator=(map&&) = default; - map(ptr_type ptr, Index r, Index c, stride_type s) : parent(ptr, r, c, strides(s)) {} - map(ptr_type ptr, Index r, Index c) : parent(ptr, r, c, strides(r,c)) {} + map(ptr_type ptr, Index r, Index c, stride_type s) : parent(ptr, r, c, strides(s,r,c)) {} + map(ptr_type ptr, Index r, Index c) + : parent( ptr, r, c + , [&]() + { + if constexpr(!std::same_as) return strides(Stride{},r,c); + else return strides(r,c); + }() + ) + {} map(ptr_type ptr, stride_type s) requires(RowsAtCompileTime!=-1 && ColsAtCompileTime!=-1) - : parent(ptr, strides(s)) + : parent(ptr, strides(s,RowsAtCompileTime,ColsAtCompileTime)) {} map(ptr_type ptr, Index sz) requires(RowsAtCompileTime==1 || ColsAtCompileTime==1) diff --git a/include/rotgen/impl/map_model.hpp b/include/rotgen/impl/map_model.hpp index 0820799..11341f3 100644 --- a/include/rotgen/impl/map_model.hpp +++ b/include/rotgen/impl/map_model.hpp @@ -93,6 +93,7 @@ class ROTGEN_EXPORT CLASSNAME const TYPE* data() const; #if !defined(USE_CONST) + TYPE* data(); void setZero(); void setOnes(); void setRandom(); diff --git a/src/map_model.cpp b/src/map_model.cpp index 668f78b..504df59 100644 --- a/src/map_model.cpp +++ b/src/map_model.cpp @@ -51,7 +51,10 @@ rotgen::Index CLASSNAME::innerStride() const { return storage_->data.innerStride(); } rotgen::Index CLASSNAME::outerStride() const { return storage_->data.outerStride(); } + const TYPE* CLASSNAME::data() const { return storage_->data.data(); } + #if !defined(USE_CONST) + TYPE* CLASSNAME::data() { return storage_->data.data(); } TYPE& CLASSNAME::operator()(Index i, Index j) { return storage_->data(i,j); } TYPE& CLASSNAME::operator()(Index i) { return storage_->data.data()[i]; } #endif @@ -59,8 +62,6 @@ TYPE CLASSNAME::operator()(Index i, Index j) const { return storage_->data(i,j); } TYPE CLASSNAME::operator()(Index i) const { return storage_->data.data()[i]; } - const TYPE* CLASSNAME::data() const { return storage_->data.data(); } - SOURCENAME CLASSNAME::transpose() const { SOURCENAME result; diff --git a/test/integration/outer_stride.cpp b/test/integration/outer_stride.cpp new file mode 100644 index 0000000..19db74c --- /dev/null +++ b/test/integration/outer_stride.cpp @@ -0,0 +1,83 @@ +//================================================================================================== +/* + ROTGEN - Runtime Overlay for Eigen + Copyright : CODE RECKONS + SPDX-License-Identifier: BSL-1.0 +*/ +//================================================================================================== +#include "unit/tests.hpp" +#include +#include + +TTS_CASE_TPL("outer_stride<0> interactions", rotgen::tests::types) +( tts::type< tts::types> ) +{ + using mat_t = rotgen::matrix; + + T contiguous[] = {1,2,3, 4,5,6, 7,8,9, 10,11,12}; + rotgen::map> m(&contiguous[0], 4, 3); + + TTS_EQUAL(m.innerStride(), 1); + TTS_EQUAL(m.outerStride(), O::value == rotgen::ColMajor ? 4 : 3); + + if constexpr(O::value == rotgen::ColMajor) + { + T padded[] = {1,2,3,4, 99, 5,6,7,8, 99,9,10,11,12}; + rotgen::map> sp(&padded[0], 4, 3); + TTS_EQUAL(sp.innerStride(), 1); + TTS_EQUAL(sp.outerStride(), 5); + + rotgen::map> dp(&padded[0], 4, 3,rotgen::outer_stride(5)); + TTS_EQUAL(dp.innerStride(), 1); + TTS_EQUAL(dp.outerStride(), 5); + + TTS_EQUAL(m , sp); + TTS_EQUAL(m , dp); + TTS_EQUAL(dp, sp); + } + else + { + T padded[] = {1,2,3, 99, 4,5,6, 99, 7,8,9, 99, 10,11,12}; + rotgen::map> sp(&padded[0], 4, 3); + TTS_EQUAL(sp.innerStride(), 1); + TTS_EQUAL(sp.outerStride(), 4); + + rotgen::map> dp(&padded[0], 4, 3,rotgen::outer_stride(4)); + TTS_EQUAL(dp.innerStride(), 1); + TTS_EQUAL(dp.outerStride(), 4); + + TTS_EQUAL(m , sp); + TTS_EQUAL(m , dp); + TTS_EQUAL(dp, sp); + } +}; + +void process_ref(rotgen::ref> ) {} +void process_ref(rotgen::ref>) {} +void process_ref(rotgen::ref>) {} +void process_ref(rotgen::ref>) {} + +TTS_CASE_TPL("Extraction of outer_stride blocks", rotgen::tests::types) +( tts::type< tts::types> ) +{ + using mat_t = rotgen::matrix; + + if constexpr(O::value == rotgen::ColMajor) + { + T padded[] = {1,2,3,4, 99, 5,6,7,8, 99,9,10,11,12}; + rotgen::map> sp(&padded[0], 4, 3); + rotgen::map> dp(&padded[0], 4, 3,rotgen::outer_stride(5)); + + TTS_EXPECT_COMPILES(sp, { process_ref(extract(sp,0, 0, 3, 2)); } ); + TTS_EXPECT_COMPILES(dp, { process_ref(extract(dp,0, 0, 3, 2)); } ); + } + else + { + T padded[] = {1,2,3, 99, 4,5,6, 99, 7,8,9, 99, 10,11,12}; + rotgen::map> sp(&padded[0], 4, 3); + rotgen::map> dp(&padded[0], 4, 3,rotgen::outer_stride(4)); + + TTS_EXPECT_COMPILES(sp, { process_ref(extract(sp,0, 0, 3, 2)); } ); + TTS_EXPECT_COMPILES(dp, { process_ref(extract(dp,0, 0, 3, 2)); } ); + } +};