From 6edae2d30d5a74a3234f6a91adb5ffdb1b86bbfc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gabriel=20N=C3=BCtzi?= Date: Fri, 9 Oct 2015 18:52:48 +0200 Subject: [PATCH 1/5] added CustomIndex capability only to Tensor and not yet to TensorBase. using Sfinae and is_base_of to select correct template which converts to array MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit user: Gabriel Nützi branch 'default' added unsupported/Eigen/CXX11/src/Tensor/TensorMetaMacros.h added unsupported/test/cxx11_tensor_customIndex.cpp changed unsupported/Eigen/CXX11/Tensor changed unsupported/Eigen/CXX11/src/Tensor/Tensor.h changed unsupported/Eigen/CXX11/src/Tensor/TensorMeta.h changed unsupported/test/CMakeLists.txt --- unsupported/Eigen/CXX11/Tensor | 1 + unsupported/Eigen/CXX11/src/Tensor/Tensor.h | 81 ++++++++++++++++++- .../Eigen/CXX11/src/Tensor/TensorMeta.h | 51 ++++++++++++ .../Eigen/CXX11/src/Tensor/TensorMetaMacros.h | 33 ++++++++ unsupported/test/CMakeLists.txt | 1 + unsupported/test/cxx11_tensor_customIndex.cpp | 41 ++++++++++ 6 files changed, 205 insertions(+), 3 deletions(-) create mode 100644 unsupported/Eigen/CXX11/src/Tensor/TensorMetaMacros.h create mode 100644 unsupported/test/cxx11_tensor_customIndex.cpp diff --git a/unsupported/Eigen/CXX11/Tensor b/unsupported/Eigen/CXX11/Tensor index cbe416602..ee3a1cdb6 100644 --- a/unsupported/Eigen/CXX11/Tensor +++ b/unsupported/Eigen/CXX11/Tensor @@ -59,6 +59,7 @@ #include "src/Tensor/TensorForwardDeclarations.h" #include "src/Tensor/TensorMeta.h" +#include "src/Tensor/TensorMetaMacros.h" #include "src/Tensor/TensorDeviceType.h" #include "src/Tensor/TensorIndexList.h" #include "src/Tensor/TensorDimensionList.h" diff --git a/unsupported/Eigen/CXX11/src/Tensor/Tensor.h b/unsupported/Eigen/CXX11/src/Tensor/Tensor.h index 6c16e0faa..f9d367e0e 100644 --- a/unsupported/Eigen/CXX11/src/Tensor/Tensor.h +++ b/unsupported/Eigen/CXX11/src/Tensor/Tensor.h @@ -88,6 +88,11 @@ class Tensor : public TensorBase m_storage; + template + struct isOfNormalIndex{ + static const bool value = internal::is_base_of< array, CustomIndex >::value; + }; + public: // Metadata EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Index rank() const { return NumIndices; } @@ -111,14 +116,29 @@ class Tensor : public TensorBase{{firstIndex, secondIndex, otherIndices...}}); } + + #endif + + /** Normal Index */ EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const Scalar& coeff(const array& indices) const { eigen_internal_assert(checkIndexRange(indices)); return m_storage.data()[linearizedIndex(indices)]; } + /** Custom Index */ + template::value) ) + > + EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const Scalar& coeff(const CustomIndex & indices) const + { + return coeff(internal::customIndex2Array(indices)); + } + + + EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const Scalar& coeff(Index index) const { eigen_internal_assert(index >= 0 && index < size()); @@ -135,12 +155,23 @@ class Tensor : public TensorBase& indices) { eigen_internal_assert(checkIndexRange(indices)); return m_storage.data()[linearizedIndex(indices)]; } + /** Custom Index */ + template::value) ) + > + EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Scalar& coeffRef(const CustomIndex & indices) + { + return coeffRef(internal::customIndex2Array(indices)); + } + + EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Scalar& coeffRef(Index index) { eigen_internal_assert(index >= 0 && index < size()); @@ -178,9 +209,20 @@ class Tensor : public TensorBase::value) ) + > + EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const Scalar& operator()(const CustomIndex & indices) const + { + //eigen_assert(checkIndexRange(indices)); /* already in coeff */ + return coeff(internal::customIndex2Array(indices)); + } + + /** Normal Index */ EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const Scalar& operator()(const array& indices) const { - eigen_assert(checkIndexRange(indices)); + //eigen_assert(checkIndexRange(indices)); /* already in coeff */ return coeff(indices); } @@ -228,12 +270,23 @@ class Tensor : public TensorBase& indices) { - eigen_assert(checkIndexRange(indices)); + //eigen_assert(checkIndexRange(indices)); /* already in coeff */ return coeffRef(indices); } + /** Custom Index */ + template::value) ) + > + EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Scalar& operator()(const CustomIndex & indices) + { + //eigen_assert(checkIndexRange(indices)); /* already in coeff */ + return coeffRef(internal::customIndex2Array(indices)); + } + EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Scalar& operator()(Index index) { eigen_assert(index >= 0 && index < size()); @@ -295,12 +348,20 @@ class Tensor : public TensorBase& dimensions) : m_storage(internal::array_prod(dimensions), dimensions) { EIGEN_INITIALIZE_COEFFS_IF_THAT_OPTION_IS_ENABLED } + /** Custom Dimension (delegating constructor c++11) */ + template::value) ) + > + inline explicit Tensor(const CustomDimension & dimensions) : Tensor(internal::customIndex2Array(dimensions)) + {} + template EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Tensor(const TensorBase& other) @@ -341,7 +402,7 @@ class Tensor : public TensorBase EIGEN_DEVICE_FUNC + template EIGEN_DEVICE_FUNC void resize(Index firstDimension, IndexTypes... otherDimensions) { // The number of dimensions used to resize a tensor must be equal to the rank of the tensor. @@ -350,6 +411,7 @@ class Tensor : public TensorBase& dimensions) { std::size_t i; @@ -367,6 +429,8 @@ class Tensor : public TensorBase& dimensions) { array dims; for (std::size_t i = 0; i < NumIndices; ++i) { @@ -375,6 +439,17 @@ class Tensor : public TensorBase::value) ) + > + EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE void resize(const CustomDimension & dimensions) + { + //eigen_assert(checkIndexRange(indices)); /* already in coeff */ + return coeffRef(internal::customIndex2Array(dimensions)); + } + + #ifndef EIGEN_EMULATE_CXX11_META_H template EIGEN_DEVICE_FUNC diff --git a/unsupported/Eigen/CXX11/src/Tensor/TensorMeta.h b/unsupported/Eigen/CXX11/src/Tensor/TensorMeta.h index 7dfa04760..60a6c1469 100644 --- a/unsupported/Eigen/CXX11/src/Tensor/TensorMeta.h +++ b/unsupported/Eigen/CXX11/src/Tensor/TensorMeta.h @@ -34,6 +34,9 @@ template <> struct max_n_1<0> { + + + #if defined(EIGEN_HAS_CONSTEXPR) #define EIGEN_CONSTEXPR constexpr #else @@ -83,6 +86,54 @@ bool operator!=(const Tuple& x, const Tuple& y) { return !(x == y); } + + + +namespace internal{ + + template + EIGEN_CONSTEXPR EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE + array customIndex2Array(const IndexType & idx, numeric_list) { + return { idx(Is)... }; + } + + /** Make an array (for index/dimensions) out of a custom index */ + template + EIGEN_CONSTEXPR EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE + array customIndex2Array(const IndexType & idx) { + return customIndex2Array(idx, typename gen_numeric_list::type{}); + } + + + template + struct is_base_of + { + + typedef char (&yes)[1]; + typedef char (&no)[2]; + + template + struct Host + { + operator BB*() const; + operator DD*(); + }; + + template + static yes check(D*, T); + static no check(B*, int); + + static const bool value = sizeof(check(Host(), int())) == sizeof(yes); + }; + +} + + + + + + + #undef EIGEN_CONSTEXPR } // namespace Eigen diff --git a/unsupported/Eigen/CXX11/src/Tensor/TensorMetaMacros.h b/unsupported/Eigen/CXX11/src/Tensor/TensorMetaMacros.h new file mode 100644 index 000000000..8cb46e703 --- /dev/null +++ b/unsupported/Eigen/CXX11/src/Tensor/TensorMetaMacros.h @@ -0,0 +1,33 @@ +// This file is part of Eigen, a lightweight C++ template library +// for linear algebra. +// +// Copyright (C) 2015 Benoit Steiner +// +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#ifndef EIGEN_CXX11_TENSOR_TENSOR_META_MACROS_H +#define EIGEN_CXX11_TENSOR_TENSOR_META_MACROS_H + + +/** use this macro in sfinae selection in templated functions + * + * template::value , int >::type = 0 + * > + * void foo(){} + * + * becomes => + * + * template::value ) + * > + * void foo(){} + */ + +#define EIGEN_SFINAE_ENABLE_IF( __condition__ ) \ + typename internal::enable_if< ( __condition__ ) , int >::type = 0 + + +#endif diff --git a/unsupported/test/CMakeLists.txt b/unsupported/test/CMakeLists.txt index 7a1737edd..e9656f404 100644 --- a/unsupported/test/CMakeLists.txt +++ b/unsupported/test/CMakeLists.txt @@ -142,6 +142,7 @@ if(EIGEN_TEST_CXX11) ei_add_test(cxx11_tensor_io "-std=c++0x") ei_add_test(cxx11_tensor_generator "-std=c++0x") ei_add_test(cxx11_tensor_custom_op "-std=c++0x") + ei_add_test(cxx11_tensor_customIndex "-std=c++0x") # These tests needs nvcc # ei_add_test(cxx11_tensor_device "-std=c++0x") diff --git a/unsupported/test/cxx11_tensor_customIndex.cpp b/unsupported/test/cxx11_tensor_customIndex.cpp new file mode 100644 index 000000000..6ec809890 --- /dev/null +++ b/unsupported/test/cxx11_tensor_customIndex.cpp @@ -0,0 +1,41 @@ +// This file is part of Eigen, a lightweight C++ template library +// for linear algebra. +// +// Copyright (C) 2014 Benoit Steiner +// +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#include "main.h" +#include + +#include +#include + +using Eigen::Tensor; + + +template +static void test_customIndex() { + + Tensor tensor(2, 3, 5, 7); + + using NormalIndex = DSizes; + using CustomIndex = Matrix; + + tensor.setRandom(); + + CustomIndex coeffC(1,2,4,1); + NormalIndex coeff(1,2,4,1); + + VERIFY_IS_EQUAL(tensor.coeff( coeffC ), tensor.coeff( coeff )); + VERIFY_IS_EQUAL(tensor.coeffRef( coeffC ), tensor.coeffRef( coeff )); + +} + + +void test_cxx11_tensor_customIndex() { + CALL_SUBTEST(test_customIndex()); + CALL_SUBTEST(test_customIndex()); +} From 7b34834f64aa03731dfb5bb01efc005820753932 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gabriel=20N=C3=BCtzi?= Date: Fri, 9 Oct 2015 19:08:14 +0200 Subject: [PATCH 2/5] name changes MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit user: Gabriel Nützi branch 'default' changed unsupported/Eigen/CXX11/src/Tensor/Tensor.h --- unsupported/Eigen/CXX11/src/Tensor/Tensor.h | 56 ++++++++++----------- 1 file changed, 28 insertions(+), 28 deletions(-) diff --git a/unsupported/Eigen/CXX11/src/Tensor/Tensor.h b/unsupported/Eigen/CXX11/src/Tensor/Tensor.h index f9d367e0e..2b892571e 100644 --- a/unsupported/Eigen/CXX11/src/Tensor/Tensor.h +++ b/unsupported/Eigen/CXX11/src/Tensor/Tensor.h @@ -88,9 +88,9 @@ class Tensor : public TensorBase m_storage; - template + template struct isOfNormalIndex{ - static const bool value = internal::is_base_of< array, CustomIndex >::value; + static const bool value = internal::is_base_of< array, CustomIndices >::value; }; public: @@ -121,20 +121,20 @@ class Tensor : public TensorBase& indices) const { eigen_internal_assert(checkIndexRange(indices)); return m_storage.data()[linearizedIndex(indices)]; } - /** Custom Index */ - template::value) ) + // custom indices + template::value) ) > - EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const Scalar& coeff(const CustomIndex & indices) const + EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const Scalar& coeff(const CustomIndices & indices) const { - return coeff(internal::customIndex2Array(indices)); + return coeff(internal::CustomIndices2Array(indices)); } @@ -155,20 +155,20 @@ class Tensor : public TensorBase& indices) { eigen_internal_assert(checkIndexRange(indices)); return m_storage.data()[linearizedIndex(indices)]; } - /** Custom Index */ - template::value) ) + // custom indices + template::value) ) > - EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Scalar& coeffRef(const CustomIndex & indices) + EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Scalar& coeffRef(const CustomIndices & indices) { - return coeffRef(internal::customIndex2Array(indices)); + return coeffRef(internal::CustomIndices2Array(indices)); } @@ -209,17 +209,17 @@ class Tensor : public TensorBase::value) ) + // custom indices + template::value) ) > - EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const Scalar& operator()(const CustomIndex & indices) const + EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const Scalar& operator()(const CustomIndices & indices) const { //eigen_assert(checkIndexRange(indices)); /* already in coeff */ - return coeff(internal::customIndex2Array(indices)); + return coeff(internal::CustomIndices2Array(indices)); } - /** Normal Index */ + // normal indices EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const Scalar& operator()(const array& indices) const { //eigen_assert(checkIndexRange(indices)); /* already in coeff */ @@ -270,21 +270,21 @@ class Tensor : public TensorBase& indices) { //eigen_assert(checkIndexRange(indices)); /* already in coeff */ return coeffRef(indices); } - /** Custom Index */ - template::value) ) + // custom indices + template::value) ) > - EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Scalar& operator()(const CustomIndex & indices) + EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Scalar& operator()(const CustomIndices & indices) { //eigen_assert(checkIndexRange(indices)); /* already in coeff */ - return coeffRef(internal::customIndex2Array(indices)); + return coeffRef(internal::CustomIndices2Array(indices)); } EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Scalar& operator()(Index index) @@ -359,7 +359,7 @@ class Tensor : public TensorBase::value) ) > - inline explicit Tensor(const CustomDimension & dimensions) : Tensor(internal::customIndex2Array(dimensions)) + inline explicit Tensor(const CustomDimension & dimensions) : Tensor(internal::CustomIndices2Array(dimensions)) {} template @@ -446,7 +446,7 @@ class Tensor : public TensorBase(dimensions)); + return coeffRef(internal::CustomIndices2Array(dimensions)); } From fc7478c04d16b8585d6eaff1ae2f473e247aaf2e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gabriel=20N=C3=BCtzi?= Date: Fri, 9 Oct 2015 19:10:08 +0200 Subject: [PATCH 3/5] =?UTF-8?q?name=20changes=202=20user:=20Gabriel=20N?= =?UTF-8?q?=C3=BCtzi=20=20branch=20'default'=20changed=20u?= =?UTF-8?q?nsupported/Eigen/CXX11/src/Tensor/Tensor.h=20changed=20unsuppor?= =?UTF-8?q?ted/Eigen/CXX11/src/Tensor/TensorMeta.h?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- unsupported/Eigen/CXX11/src/Tensor/Tensor.h | 12 ++++++------ unsupported/Eigen/CXX11/src/Tensor/TensorMeta.h | 6 +++--- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/unsupported/Eigen/CXX11/src/Tensor/Tensor.h b/unsupported/Eigen/CXX11/src/Tensor/Tensor.h index 2b892571e..d59fd21dc 100644 --- a/unsupported/Eigen/CXX11/src/Tensor/Tensor.h +++ b/unsupported/Eigen/CXX11/src/Tensor/Tensor.h @@ -134,7 +134,7 @@ class Tensor : public TensorBase EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const Scalar& coeff(const CustomIndices & indices) const { - return coeff(internal::CustomIndices2Array(indices)); + return coeff(internal::customIndices2Array(indices)); } @@ -168,7 +168,7 @@ class Tensor : public TensorBase EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Scalar& coeffRef(const CustomIndices & indices) { - return coeffRef(internal::CustomIndices2Array(indices)); + return coeffRef(internal::customIndices2Array(indices)); } @@ -216,7 +216,7 @@ class Tensor : public TensorBase(indices)); + return coeff(internal::customIndices2Array(indices)); } // normal indices @@ -284,7 +284,7 @@ class Tensor : public TensorBase(indices)); + return coeffRef(internal::customIndices2Array(indices)); } EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Scalar& operator()(Index index) @@ -359,7 +359,7 @@ class Tensor : public TensorBase::value) ) > - inline explicit Tensor(const CustomDimension & dimensions) : Tensor(internal::CustomIndices2Array(dimensions)) + inline explicit Tensor(const CustomDimension & dimensions) : Tensor(internal::customIndices2Array(dimensions)) {} template @@ -446,7 +446,7 @@ class Tensor : public TensorBase(dimensions)); + return coeffRef(internal::customIndices2Array(dimensions)); } diff --git a/unsupported/Eigen/CXX11/src/Tensor/TensorMeta.h b/unsupported/Eigen/CXX11/src/Tensor/TensorMeta.h index 60a6c1469..01aedd3c9 100644 --- a/unsupported/Eigen/CXX11/src/Tensor/TensorMeta.h +++ b/unsupported/Eigen/CXX11/src/Tensor/TensorMeta.h @@ -93,15 +93,15 @@ namespace internal{ template EIGEN_CONSTEXPR EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE - array customIndex2Array(const IndexType & idx, numeric_list) { + array customIndices2Array(const IndexType & idx, numeric_list) { return { idx(Is)... }; } /** Make an array (for index/dimensions) out of a custom index */ template EIGEN_CONSTEXPR EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE - array customIndex2Array(const IndexType & idx) { - return customIndex2Array(idx, typename gen_numeric_list::type{}); + array customIndices2Array(const IndexType & idx) { + return customIndices2Array(idx, typename gen_numeric_list::type{}); } From 6585efc55354b38c65de8c23599e99f3caaca843 Mon Sep 17 00:00:00 2001 From: Benoit Steiner Date: Wed, 14 Oct 2015 09:31:37 -0700 Subject: [PATCH 4/5] Tightened the definition of isOfNormalIndex to take into account integer types in addition to arrays of indices Only compile the custom index code when EIGEN_HAS_SFINAE is defined. For the time beeing, EIGEN_HAS_SFINAE is a synonym for EIGEN_HAS_VARIADIC_TEMPLATES, but this might evolve in the future. Moved some code around. --- unsupported/Eigen/CXX11/Tensor | 2 +- unsupported/Eigen/CXX11/src/Tensor/Tensor.h | 33 +++++++++---------- .../{TensorMetaMacros.h => TensorMacros.h} | 11 +++++++ .../Eigen/CXX11/src/Tensor/TensorMeta.h | 20 ++--------- unsupported/test/CMakeLists.txt | 2 +- ...ndex.cpp => cxx11_tensor_custom_index.cpp} | 25 +++++++------- 6 files changed, 41 insertions(+), 52 deletions(-) rename unsupported/Eigen/CXX11/src/Tensor/{TensorMetaMacros.h => TensorMacros.h} (84%) rename unsupported/test/{cxx11_tensor_customIndex.cpp => cxx11_tensor_custom_index.cpp} (64%) diff --git a/unsupported/Eigen/CXX11/Tensor b/unsupported/Eigen/CXX11/Tensor index ee3a1cdb6..3331ccb55 100644 --- a/unsupported/Eigen/CXX11/Tensor +++ b/unsupported/Eigen/CXX11/Tensor @@ -57,9 +57,9 @@ #endif +#include "src/Tensor/TensorMacros.h" #include "src/Tensor/TensorForwardDeclarations.h" #include "src/Tensor/TensorMeta.h" -#include "src/Tensor/TensorMetaMacros.h" #include "src/Tensor/TensorDeviceType.h" #include "src/Tensor/TensorIndexList.h" #include "src/Tensor/TensorDimensionList.h" diff --git a/unsupported/Eigen/CXX11/src/Tensor/Tensor.h b/unsupported/Eigen/CXX11/src/Tensor/Tensor.h index d59fd21dc..57d44baf9 100644 --- a/unsupported/Eigen/CXX11/src/Tensor/Tensor.h +++ b/unsupported/Eigen/CXX11/src/Tensor/Tensor.h @@ -88,10 +88,14 @@ class Tensor : public TensorBase m_storage; +#ifdef EIGEN_HAS_SFINAE template struct isOfNormalIndex{ - static const bool value = internal::is_base_of< array, CustomIndices >::value; + static const bool is_array = internal::is_base_of, CustomIndices >::value; + static const bool is_int = NumTraits::IsInteger; + static const bool value = is_array | is_int; }; +#endif public: // Metadata @@ -129,6 +133,7 @@ class Tensor : public TensorBase::value) ) > @@ -136,8 +141,7 @@ class Tensor : public TensorBase(indices)); } - - +#endif EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const Scalar& coeff(Index index) const { @@ -163,6 +167,7 @@ class Tensor : public TensorBase::value) ) > @@ -170,7 +175,7 @@ class Tensor : public TensorBase(indices)); } - +#endif EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Scalar& coeffRef(Index index) { @@ -210,19 +215,19 @@ class Tensor : public TensorBase::value) ) > EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const Scalar& operator()(const CustomIndices & indices) const { - //eigen_assert(checkIndexRange(indices)); /* already in coeff */ return coeff(internal::customIndices2Array(indices)); } +#endif // normal indices EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const Scalar& operator()(const array& indices) const { - //eigen_assert(checkIndexRange(indices)); /* already in coeff */ return coeff(indices); } @@ -273,19 +278,19 @@ class Tensor : public TensorBase& indices) { - //eigen_assert(checkIndexRange(indices)); /* already in coeff */ return coeffRef(indices); } // custom indices +#ifdef EIGEN_HAS_SFINAE template::value) ) > EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Scalar& operator()(const CustomIndices & indices) { - //eigen_assert(checkIndexRange(indices)); /* already in coeff */ return coeffRef(internal::customIndices2Array(indices)); } +#endif EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Scalar& operator()(Index index) { @@ -355,13 +360,6 @@ class Tensor : public TensorBase::value) ) - > - inline explicit Tensor(const CustomDimension & dimensions) : Tensor(internal::customIndices2Array(dimensions)) - {} - template EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Tensor(const TensorBase& other) @@ -429,7 +427,6 @@ class Tensor : public TensorBase& dimensions) { array dims; @@ -440,15 +437,15 @@ class Tensor : public TensorBase::value) ) > EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE void resize(const CustomDimension & dimensions) { - //eigen_assert(checkIndexRange(indices)); /* already in coeff */ return coeffRef(internal::customIndices2Array(dimensions)); } - +#endif #ifndef EIGEN_EMULATE_CXX11_META_H template diff --git a/unsupported/Eigen/CXX11/src/Tensor/TensorMetaMacros.h b/unsupported/Eigen/CXX11/src/Tensor/TensorMacros.h similarity index 84% rename from unsupported/Eigen/CXX11/src/Tensor/TensorMetaMacros.h rename to unsupported/Eigen/CXX11/src/Tensor/TensorMacros.h index 8cb46e703..6d9cc4f38 100644 --- a/unsupported/Eigen/CXX11/src/Tensor/TensorMetaMacros.h +++ b/unsupported/Eigen/CXX11/src/Tensor/TensorMacros.h @@ -26,8 +26,19 @@ * void foo(){} */ +#ifdef EIGEN_HAS_VARIADIC_TEMPLATES +#define EIGEN_HAS_SFINAE +#endif + #define EIGEN_SFINAE_ENABLE_IF( __condition__ ) \ typename internal::enable_if< ( __condition__ ) , int >::type = 0 +#if defined(EIGEN_HAS_CONSTEXPR) +#define EIGEN_CONSTEXPR constexpr +#else +#define EIGEN_CONSTEXPR +#endif + + #endif diff --git a/unsupported/Eigen/CXX11/src/Tensor/TensorMeta.h b/unsupported/Eigen/CXX11/src/Tensor/TensorMeta.h index 01aedd3c9..d1efc1a87 100644 --- a/unsupported/Eigen/CXX11/src/Tensor/TensorMeta.h +++ b/unsupported/Eigen/CXX11/src/Tensor/TensorMeta.h @@ -32,17 +32,6 @@ template <> struct max_n_1<0> { }; - - - - - -#if defined(EIGEN_HAS_CONSTEXPR) -#define EIGEN_CONSTEXPR constexpr -#else -#define EIGEN_CONSTEXPR -#endif - // Tuple mimics std::pair but works on e.g. nvcc. template struct Tuple { public: @@ -88,7 +77,7 @@ bool operator!=(const Tuple& x, const Tuple& y) { - +#ifdef EIGEN_HAS_SFINAE namespace internal{ template @@ -127,15 +116,10 @@ namespace internal{ }; } +#endif - - - - -#undef EIGEN_CONSTEXPR - } // namespace Eigen #endif // EIGEN_CXX11_TENSOR_TENSOR_META_H diff --git a/unsupported/test/CMakeLists.txt b/unsupported/test/CMakeLists.txt index e9656f404..8865892e6 100644 --- a/unsupported/test/CMakeLists.txt +++ b/unsupported/test/CMakeLists.txt @@ -142,7 +142,7 @@ if(EIGEN_TEST_CXX11) ei_add_test(cxx11_tensor_io "-std=c++0x") ei_add_test(cxx11_tensor_generator "-std=c++0x") ei_add_test(cxx11_tensor_custom_op "-std=c++0x") - ei_add_test(cxx11_tensor_customIndex "-std=c++0x") + ei_add_test(cxx11_tensor_custom_index "-std=c++0x") # These tests needs nvcc # ei_add_test(cxx11_tensor_device "-std=c++0x") diff --git a/unsupported/test/cxx11_tensor_customIndex.cpp b/unsupported/test/cxx11_tensor_custom_index.cpp similarity index 64% rename from unsupported/test/cxx11_tensor_customIndex.cpp rename to unsupported/test/cxx11_tensor_custom_index.cpp index 6ec809890..ff9545a7a 100644 --- a/unsupported/test/cxx11_tensor_customIndex.cpp +++ b/unsupported/test/cxx11_tensor_custom_index.cpp @@ -1,7 +1,7 @@ // This file is part of Eigen, a lightweight C++ template library // for linear algebra. // -// Copyright (C) 2014 Benoit Steiner +// Copyright (C) 2015 Benoit Steiner // // This Source Code Form is subject to the terms of the Mozilla // Public License v. 2.0. If a copy of the MPL was not distributed @@ -17,25 +17,22 @@ using Eigen::Tensor; template -static void test_customIndex() { - +static void test_custom_index() { + Tensor tensor(2, 3, 5, 7); - - using NormalIndex = DSizes; - using CustomIndex = Matrix; - tensor.setRandom(); + using NormalIndex = DSizes; + using CustomIndex = Matrix; CustomIndex coeffC(1,2,4,1); NormalIndex coeff(1,2,4,1); - - VERIFY_IS_EQUAL(tensor.coeff( coeffC ), tensor.coeff( coeff )); - VERIFY_IS_EQUAL(tensor.coeffRef( coeffC ), tensor.coeffRef( coeff )); - + + VERIFY_IS_EQUAL(tensor.coeff(coeffC), tensor.coeff(coeff)); + VERIFY_IS_EQUAL(tensor.coeffRef(coeffC), tensor.coeffRef(coeff)); } -void test_cxx11_tensor_customIndex() { - CALL_SUBTEST(test_customIndex()); - CALL_SUBTEST(test_customIndex()); +void test_cxx11_tensor_custom_index() { + test_custom_index(); + test_custom_index(); } From de1e9f29f4db2c837ffb354c90f9e9fb7df05e85 Mon Sep 17 00:00:00 2001 From: Benoit Steiner Date: Thu, 15 Oct 2015 14:58:49 -0700 Subject: [PATCH 5/5] Updated the custom indexing code: we can now use any container that provides the [] operator to index a tensor. Added unit tests to validate the use of std::map and a few more types as valid custom index containers --- unsupported/Eigen/CXX11/src/Tensor/Tensor.h | 17 ++--- .../Eigen/CXX11/src/Tensor/TensorMeta.h | 8 +-- .../test/cxx11_tensor_custom_index.cpp | 72 +++++++++++++++++-- unsupported/test/cxx11_tensor_simple.cpp | 4 -- 4 files changed, 78 insertions(+), 23 deletions(-) diff --git a/unsupported/Eigen/CXX11/src/Tensor/Tensor.h b/unsupported/Eigen/CXX11/src/Tensor/Tensor.h index 57d44baf9..3ac465d24 100644 --- a/unsupported/Eigen/CXX11/src/Tensor/Tensor.h +++ b/unsupported/Eigen/CXX11/src/Tensor/Tensor.h @@ -91,7 +91,7 @@ class Tensor : public TensorBase struct isOfNormalIndex{ - static const bool is_array = internal::is_base_of, CustomIndices >::value; + static const bool is_array = internal::is_base_of, CustomIndices>::value; static const bool is_int = NumTraits::IsInteger; static const bool value = is_array | is_int; }; @@ -120,11 +120,8 @@ class Tensor : public TensorBase{{firstIndex, secondIndex, otherIndices...}}); } - - #endif - // normal indices EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const Scalar& coeff(const array& indices) const { @@ -137,7 +134,7 @@ class Tensor : public TensorBase::value) ) > - EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const Scalar& coeff(const CustomIndices & indices) const + EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const Scalar& coeff(CustomIndices& indices) const { return coeff(internal::customIndices2Array(indices)); } @@ -171,7 +168,7 @@ class Tensor : public TensorBase::value) ) > - EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Scalar& coeffRef(const CustomIndices & indices) + EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Scalar& coeffRef(CustomIndices& indices) { return coeffRef(internal::customIndices2Array(indices)); } @@ -219,7 +216,7 @@ class Tensor : public TensorBase::value) ) > - EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const Scalar& operator()(const CustomIndices & indices) const + EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const Scalar& operator()(CustomIndices& indices) const { return coeff(internal::customIndices2Array(indices)); } @@ -286,7 +283,7 @@ class Tensor : public TensorBase::value) ) > - EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Scalar& operator()(const CustomIndices & indices) + EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Scalar& operator()(CustomIndices& indices) { return coeffRef(internal::customIndices2Array(indices)); } @@ -441,9 +438,9 @@ class Tensor : public TensorBase::value) ) > - EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE void resize(const CustomDimension & dimensions) + EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE void resize(CustomDimension& dimensions) { - return coeffRef(internal::customIndices2Array(dimensions)); + resize(internal::customIndices2Array(dimensions)); } #endif diff --git a/unsupported/Eigen/CXX11/src/Tensor/TensorMeta.h b/unsupported/Eigen/CXX11/src/Tensor/TensorMeta.h index d1efc1a87..07735fa5f 100644 --- a/unsupported/Eigen/CXX11/src/Tensor/TensorMeta.h +++ b/unsupported/Eigen/CXX11/src/Tensor/TensorMeta.h @@ -82,15 +82,15 @@ namespace internal{ template EIGEN_CONSTEXPR EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE - array customIndices2Array(const IndexType & idx, numeric_list) { - return { idx(Is)... }; + array customIndices2Array(IndexType& idx, numeric_list) { + return { idx[Is]... }; } /** Make an array (for index/dimensions) out of a custom index */ template EIGEN_CONSTEXPR EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE - array customIndices2Array(const IndexType & idx) { - return customIndices2Array(idx, typename gen_numeric_list::type{}); + array customIndices2Array(IndexType& idx) { + return customIndices2Array(idx, typename gen_numeric_list::type{}); } diff --git a/unsupported/test/cxx11_tensor_custom_index.cpp b/unsupported/test/cxx11_tensor_custom_index.cpp index ff9545a7a..4528cc176 100644 --- a/unsupported/test/cxx11_tensor_custom_index.cpp +++ b/unsupported/test/cxx11_tensor_custom_index.cpp @@ -9,6 +9,7 @@ #include "main.h" #include +#include #include #include @@ -17,22 +18,83 @@ using Eigen::Tensor; template -static void test_custom_index() { - +static void test_map_as_index() +{ +#ifdef EIGEN_HAS_SFINAE Tensor tensor(2, 3, 5, 7); tensor.setRandom(); using NormalIndex = DSizes; - using CustomIndex = Matrix; + using CustomIndex = std::map; + CustomIndex coeffC; + coeffC[0] = 1; + coeffC[1] = 2; + coeffC[2] = 4; + coeffC[3] = 1; + NormalIndex coeff(1,2,4,1); + + VERIFY_IS_EQUAL(tensor.coeff(coeffC), tensor.coeff(coeff)); + VERIFY_IS_EQUAL(tensor.coeffRef(coeffC), tensor.coeffRef(coeff)); +#endif +} + + +template +static void test_matrix_as_index() +{ +#ifdef EIGEN_HAS_SFINAE + Tensor tensor(2, 3, 5, 7); + tensor.setRandom(); + + using NormalIndex = DSizes; + using CustomIndex = Matrix; CustomIndex coeffC(1,2,4,1); NormalIndex coeff(1,2,4,1); VERIFY_IS_EQUAL(tensor.coeff(coeffC), tensor.coeff(coeff)); VERIFY_IS_EQUAL(tensor.coeffRef(coeffC), tensor.coeffRef(coeff)); +#endif +} + + +template +static void test_varlist_as_index() +{ +#ifdef EIGEN_HAS_SFINAE + Tensor tensor(2, 3, 5, 7); + tensor.setRandom(); + + DSizes coeff(1,2,4,1); + + VERIFY_IS_EQUAL(tensor.coeff({1,2,4,1}), tensor.coeff(coeff)); + VERIFY_IS_EQUAL(tensor.coeffRef({1,2,4,1}), tensor.coeffRef(coeff)); +#endif +} + + +template +static void test_sizes_as_index() +{ +#ifdef EIGEN_HAS_SFINAE + Tensor tensor(2, 3, 5, 7); + tensor.setRandom(); + + DSizes coeff(1,2,4,1); + Sizes<1,2,4,1> coeffC; + + VERIFY_IS_EQUAL(tensor.coeff(coeffC), tensor.coeff(coeff)); + VERIFY_IS_EQUAL(tensor.coeffRef(coeffC), tensor.coeffRef(coeff)); +#endif } void test_cxx11_tensor_custom_index() { - test_custom_index(); - test_custom_index(); + test_map_as_index(); + test_map_as_index(); + test_matrix_as_index(); + test_matrix_as_index(); + test_varlist_as_index(); + test_varlist_as_index(); + test_sizes_as_index(); + test_sizes_as_index(); } diff --git a/unsupported/test/cxx11_tensor_simple.cpp b/unsupported/test/cxx11_tensor_simple.cpp index 8cd2ab7fd..0ce92eed9 100644 --- a/unsupported/test/cxx11_tensor_simple.cpp +++ b/unsupported/test/cxx11_tensor_simple.cpp @@ -293,7 +293,3 @@ void test_cxx11_tensor_simple() CALL_SUBTEST(test_simple_assign()); CALL_SUBTEST(test_resize()); } - -/* - * kate: space-indent on; indent-width 2; mixedindent off; indent-mode cstyle; - */