Made the index type a template parameter of the tensor class instead of encoding it in the options.

This commit is contained in:
Benoit Steiner 2015-03-30 14:55:54 -07:00
parent 71950f02e5
commit 35722fa022
9 changed files with 66 additions and 104 deletions

View File

@ -296,11 +296,7 @@ enum {
/** Align the matrix itself if it is vectorizable fixed-size */ /** Align the matrix itself if it is vectorizable fixed-size */
AutoAlign = 0, AutoAlign = 0,
/** Don't require alignment for the matrix itself (the array of coefficients, if dynamically allocated, may still be requested to be aligned) */ // FIXME --- clarify the situation /** Don't require alignment for the matrix itself (the array of coefficients, if dynamically allocated, may still be requested to be aligned) */ // FIXME --- clarify the situation
DontAlign = 0x2, DontAlign = 0x2
/** Use the DenseIndex type to index the matrix/array/tensor. Unless otherwise specified by defining EIGEN_DEFAULT_DENSE_INDEX_TYPE, DenseIndex is a ptrdiff_t. */
IndexDefault = 0,
/** Use 32bit signed integers to index the matrix/array/tensor. */
Index32Bit = 0x4
}; };
/** \ingroup enums /** \ingroup enums

View File

@ -59,12 +59,12 @@ namespace Eigen {
* \ref TopicStorageOrders * \ref TopicStorageOrders
*/ */
template<typename Scalar_, std::size_t NumIndices_, int Options_> template<typename Scalar_, std::size_t NumIndices_, int Options_, typename IndexType_>
class Tensor : public TensorBase<Tensor<Scalar_, NumIndices_, Options_> > class Tensor : public TensorBase<Tensor<Scalar_, NumIndices_, Options_, IndexType_> >
{ {
public: public:
typedef Tensor<Scalar_, NumIndices_, Options_> Self; typedef Tensor<Scalar_, NumIndices_, Options_, IndexType_> Self;
typedef TensorBase<Tensor<Scalar_, NumIndices_, Options_> > Base; typedef TensorBase<Tensor<Scalar_, NumIndices_, Options_, IndexType_> > Base;
typedef typename Eigen::internal::nested<Self>::type Nested; typedef typename Eigen::internal::nested<Self>::type Nested;
typedef typename internal::traits<Self>::StorageKind StorageKind; typedef typename internal::traits<Self>::StorageKind StorageKind;
typedef typename internal::traits<Self>::Index Index; typedef typename internal::traits<Self>::Index Index;
@ -86,7 +86,7 @@ class Tensor : public TensorBase<Tensor<Scalar_, NumIndices_, Options_> >
typedef DSizes<Index, NumIndices_> Dimensions; typedef DSizes<Index, NumIndices_> Dimensions;
protected: protected:
TensorStorage<Scalar, NumIndices, Dynamic, Options> m_storage; TensorStorage<Scalar, Dimensions, Options> m_storage;
public: public:
// Metadata // Metadata

View File

@ -460,8 +460,7 @@ class TensorBase<Derived, ReadOnlyAccessors>
} }
protected: protected:
template <typename Scalar, std::size_t NumIndices, int Options> friend class Tensor; template <typename Scalar, std::size_t NumIndices, int Options, typename IndexType> friend class Tensor;
template <typename Scalar, int Options> friend class TensorVarDim;
template <typename OtherDerived, int AccessLevel> friend class TensorBase; template <typename OtherDerived, int AccessLevel> friend class TensorBase;
EIGEN_DEVICE_FUNC EIGEN_DEVICE_FUNC
EIGEN_STRONG_INLINE const Derived& derived() const { return *static_cast<const Derived*>(this); } EIGEN_STRONG_INLINE const Derived& derived() const { return *static_cast<const Derived*>(this); }
@ -477,8 +476,7 @@ class TensorBase<Derived, WriteAccessors> : public TensorBase<Derived, ReadOnlyA
typedef typename internal::packet_traits<Scalar>::type PacketReturnType; typedef typename internal::packet_traits<Scalar>::type PacketReturnType;
static const int NumDimensions = DerivedTraits::NumDimensions; static const int NumDimensions = DerivedTraits::NumDimensions;
template <typename Scalar, std::size_t NumIndices, int Options> friend class Tensor; template <typename Scalar, std::size_t NumIndices, int Options, typename IndexType> friend class Tensor;
template <typename Scalar, int Options> friend class TensorVarDim;
template <typename OtherDerived, int AccessLevel> friend class TensorBase; template <typename OtherDerived, int AccessLevel> friend class TensorBase;
EIGEN_DEVICE_FUNC EIGEN_DEVICE_FUNC

View File

@ -184,7 +184,7 @@ template <std::size_t V1=0, std::size_t V2=0, std::size_t V3=0, std::size_t V4=0
template <std::size_t V1, std::size_t V2, std::size_t V3, std::size_t V4, std::size_t V5> template <std::size_t V1, std::size_t V2, std::size_t V3, std::size_t V4, std::size_t V5>
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE std::size_t array_prod(const Sizes<V1, V2, V3, V4, V5>&) { EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE std::size_t array_prod(const Sizes<V1, V2, V3, V4, V5>&) {
return Sizes<V1, V2, V3, V4, V5>::total_size; return Sizes<V1, V2, V3, V4, V5>::total_size;
}; }
#endif #endif
@ -345,7 +345,7 @@ template <std::size_t V1, std::size_t V2, std::size_t V3, std::size_t V4, std::s
}; };
template <std::size_t n, std::size_t V1, std::size_t V2, std::size_t V3, std::size_t V4, std::size_t V5> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE std::size_t array_get(const Sizes<V1,V2,V3,V4,V5>& a) { template <std::size_t n, std::size_t V1, std::size_t V2, std::size_t V3, std::size_t V4, std::size_t V5> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE std::size_t array_get(const Sizes<V1,V2,V3,V4,V5>& a) {
return get<n, typename Sizes<V1,V2,V3,V4,V5>::Base>::value; return get<n, typename Sizes<V1,V2,V3,V4,V5>::Base>::value;
}; }
#endif #endif

View File

@ -23,12 +23,12 @@ namespace Eigen {
* Eigen::TensorFixedSize<float, Size<3,5,7>> t; * Eigen::TensorFixedSize<float, Size<3,5,7>> t;
*/ */
template<typename Scalar_, typename Dimensions_, int Options_> template<typename Scalar_, typename Dimensions_, int Options_, typename IndexType>
class TensorFixedSize : public TensorBase<TensorFixedSize<Scalar_, Dimensions_, Options_> > class TensorFixedSize : public TensorBase<TensorFixedSize<Scalar_, Dimensions_, Options_, IndexType> >
{ {
public: public:
typedef TensorFixedSize<Scalar_, Dimensions_, Options_> Self; typedef TensorFixedSize<Scalar_, Dimensions_, Options_, IndexType> Self;
typedef TensorBase<TensorFixedSize<Scalar_, Dimensions_, Options_> > Base; typedef TensorBase<TensorFixedSize<Scalar_, Dimensions_, Options_, IndexType> > Base;
typedef typename Eigen::internal::nested<Self>::type Nested; typedef typename Eigen::internal::nested<Self>::type Nested;
typedef typename internal::traits<Self>::StorageKind StorageKind; typedef typename internal::traits<Self>::StorageKind StorageKind;
typedef typename internal::traits<Self>::Index Index; typedef typename internal::traits<Self>::Index Index;
@ -50,7 +50,7 @@ class TensorFixedSize : public TensorBase<TensorFixedSize<Scalar_, Dimensions_,
static const std::size_t NumIndices = Dimensions::count; static const std::size_t NumIndices = Dimensions::count;
protected: protected:
TensorStorage<Scalar, NumIndices, Dimensions::total_size, Options, Dimensions> m_storage; TensorStorage<Scalar, Dimensions, Options> m_storage;
public: public:
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Index rank() const { return NumIndices; } EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Index rank() const { return NumIndices; }

View File

@ -12,8 +12,8 @@
namespace Eigen { namespace Eigen {
template<typename Scalar_, std::size_t NumIndices_, int Options_ = 0> class Tensor; template<typename Scalar_, std::size_t NumIndices_, int Options_ = 0, typename IndexType = DenseIndex> class Tensor;
template<typename Scalar_, typename Dimensions, int Options_ = 0> class TensorFixedSize; template<typename Scalar_, typename Dimensions, int Options_ = 0, typename IndexType = DenseIndex> class TensorFixedSize;
template<typename PlainObjectType, int Options_ = Unaligned> class TensorMap; template<typename PlainObjectType, int Options_ = Unaligned> class TensorMap;
template<typename PlainObjectType> class TensorRef; template<typename PlainObjectType> class TensorRef;
template<typename Derived, int AccessLevel = internal::accessors_level<Derived>::value> class TensorBase; template<typename Derived, int AccessLevel = internal::accessors_level<Derived>::value> class TensorBase;

View File

@ -2,6 +2,7 @@
// for linear algebra. // for linear algebra.
// //
// Copyright (C) 2013 Christian Seiler <christian@iwakd.de> // Copyright (C) 2013 Christian Seiler <christian@iwakd.de>
// Copyright (C) 2014-2015 Benoit Steiner <benoit.steiner.goog@gmail.com>
// //
// This Source Code Form is subject to the terms of the Mozilla // 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 // Public License v. 2.0. If a copy of the MPL was not distributed
@ -30,21 +31,22 @@ namespace Eigen {
* *
* \sa Tensor * \sa Tensor
*/ */
template<typename T, DenseIndex NumIndices_, DenseIndex Size, int Options_, typename Dimensions = void> class TensorStorage; template<typename T, typename Dimensions, int Options_> class TensorStorage;
// Pure fixed-size storage // Pure fixed-size storage
template<typename T, DenseIndex NumIndices_, DenseIndex Size, int Options_, typename FixedDimensions> template<typename T, int Options_, typename FixedDimensions>
class TensorStorage class TensorStorage<T, FixedDimensions, Options_>
{ {
private: private:
static const std::size_t Size = FixedDimensions::total_size;
EIGEN_ALIGN_DEFAULT T m_data[Size]; EIGEN_ALIGN_DEFAULT T m_data[Size];
FixedDimensions m_dimensions; FixedDimensions m_dimensions;
public: public:
EIGEN_DEVICE_FUNC EIGEN_DEVICE_FUNC
EIGEN_STRONG_INLINE TensorStorage() { EIGEN_STRONG_INLINE TensorStorage() {
EIGEN_STATIC_ASSERT(Size == FixedDimensions::total_size, YOU_MADE_A_PROGRAMMING_MISTAKE)
} }
EIGEN_DEVICE_FUNC EIGEN_DEVICE_FUNC
@ -60,35 +62,14 @@ class TensorStorage
}; };
// pure-dynamic, but without specification of all dimensions explicitly
template<typename T, DenseIndex NumIndices_, int Options_>
class TensorStorage<T, NumIndices_, Dynamic, Options_, void>
: public TensorStorage<T, NumIndices_, Dynamic, Options_, typename internal::gen_numeric_list_repeated<typename internal::compute_index_type<static_cast<bool>(Options_ & Index32Bit)>::type, NumIndices_, Dynamic>::type>
{
typedef typename internal::compute_index_type<static_cast<bool>(Options_ & Index32Bit)>::type Index;
typedef DSizes<Index, NumIndices_> Dimensions;
typedef TensorStorage<T, NumIndices_, Dynamic, Options_, typename internal::gen_numeric_list_repeated<Index, NumIndices_, Dynamic>::type> Base_;
public:
EIGEN_DEVICE_FUNC TensorStorage() { }
EIGEN_DEVICE_FUNC TensorStorage(const TensorStorage<T, NumIndices_, Dynamic, Options_, void>& other) : Base_(other) { }
EIGEN_DEVICE_FUNC TensorStorage(internal::constructor_without_unaligned_array_assert) : Base_(internal::constructor_without_unaligned_array_assert()) {}
EIGEN_DEVICE_FUNC TensorStorage(Index size, const array<Index, NumIndices_>& dimensions) : Base_(size, dimensions) {}
// TensorStorage<T, NumIndices_, Dynamic, Options_, void>& operator=(const TensorStorage<T, NumIndices_, Dynamic, Options_, void>&) = default;
};
// pure dynamic // pure dynamic
template<typename T, DenseIndex NumIndices_, int Options_> template<typename T, int Options_, typename IndexType, std::size_t NumIndices_>
class TensorStorage<T, NumIndices_, Dynamic, Options_, typename internal::gen_numeric_list_repeated<typename internal::compute_index_type<static_cast<bool>(Options_ & Index32Bit)>::type, NumIndices_, Dynamic>::type> class TensorStorage<T, DSizes<IndexType, NumIndices_>, Options_>
{ {
public: public:
typedef typename internal::compute_index_type<static_cast<bool>(Options_&Index32Bit)>::type Index; typedef IndexType Index;
typedef DSizes<Index, NumIndices_> Dimensions; typedef DSizes<IndexType, NumIndices_> Dimensions;
typedef TensorStorage<T, DSizes<IndexType, NumIndices_>, Options_> Self;
typedef TensorStorage<T, NumIndices_, Dynamic, Options_, typename internal::gen_numeric_list_repeated<Index, NumIndices_, Dynamic>::type> Self_;
EIGEN_DEVICE_FUNC TensorStorage() : m_data(0), m_dimensions() {} EIGEN_DEVICE_FUNC TensorStorage() : m_data(0), m_dimensions() {}
EIGEN_DEVICE_FUNC TensorStorage(internal::constructor_without_unaligned_array_assert) EIGEN_DEVICE_FUNC TensorStorage(internal::constructor_without_unaligned_array_assert)
@ -97,23 +78,23 @@ class TensorStorage<T, NumIndices_, Dynamic, Options_, typename internal::gen_nu
: m_data(internal::conditional_aligned_new_auto<T,(Options_&DontAlign)==0>(size)), m_dimensions(dimensions) : m_data(internal::conditional_aligned_new_auto<T,(Options_&DontAlign)==0>(size)), m_dimensions(dimensions)
{ EIGEN_INTERNAL_TENSOR_STORAGE_CTOR_PLUGIN } { EIGEN_INTERNAL_TENSOR_STORAGE_CTOR_PLUGIN }
EIGEN_DEVICE_FUNC TensorStorage(const Self_& other) EIGEN_DEVICE_FUNC TensorStorage(const Self& other)
: m_data(internal::conditional_aligned_new_auto<T,(Options_&DontAlign)==0>(internal::array_prod(other.m_dimensions))) : m_data(internal::conditional_aligned_new_auto<T,(Options_&DontAlign)==0>(internal::array_prod(other.m_dimensions)))
, m_dimensions(other.m_dimensions) , m_dimensions(other.m_dimensions)
{ {
internal::smart_copy(other.m_data, other.m_data+internal::array_prod(other.m_dimensions), m_data); internal::smart_copy(other.m_data, other.m_data+internal::array_prod(other.m_dimensions), m_data);
} }
EIGEN_DEVICE_FUNC Self_& operator=(const Self_& other) EIGEN_DEVICE_FUNC Self& operator=(const Self& other)
{ {
if (this != &other) { if (this != &other) {
Self_ tmp(other); Self tmp(other);
this->swap(tmp); this->swap(tmp);
} }
return *this; return *this;
} }
EIGEN_DEVICE_FUNC ~TensorStorage() { internal::conditional_aligned_delete_auto<T,(Options_&DontAlign)==0>(m_data, internal::array_prod(m_dimensions)); } EIGEN_DEVICE_FUNC ~TensorStorage() { internal::conditional_aligned_delete_auto<T,(Options_&DontAlign)==0>(m_data, internal::array_prod(m_dimensions)); }
EIGEN_DEVICE_FUNC void swap(Self_& other) EIGEN_DEVICE_FUNC void swap(Self& other)
{ std::swap(m_data,other.m_data); std::swap(m_dimensions,other.m_dimensions); } { std::swap(m_data,other.m_data); std::swap(m_dimensions,other.m_dimensions); }
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const Dimensions& dimensions() const {return m_dimensions;} EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const Dimensions& dimensions() const {return m_dimensions;}

View File

@ -43,24 +43,13 @@ class compute_tensor_flags
enum { ret = packet_access_bit | aligned_bit}; enum { ret = packet_access_bit | aligned_bit};
}; };
template<bool force32bit>
struct compute_index_type {
typedef DenseIndex type;
};
template<> template<typename Scalar_, std::size_t NumIndices_, int Options_, typename IndexType_>
struct compute_index_type<true> { struct traits<Tensor<Scalar_, NumIndices_, Options_, IndexType_> >
typedef int type;
};
template<typename Scalar_, std::size_t NumIndices_, int Options_>
struct traits<Tensor<Scalar_, NumIndices_, Options_> >
{ {
typedef Scalar_ Scalar; typedef Scalar_ Scalar;
typedef Dense StorageKind; typedef Dense StorageKind;
typedef typename compute_index_type<static_cast<bool>(Options_&Index32Bit)>::type Index; typedef IndexType_ Index;
static const int NumDimensions = NumIndices_; static const int NumDimensions = NumIndices_;
static const int Layout = Options_ & RowMajor ? RowMajor : ColMajor; static const int Layout = Options_ & RowMajor ? RowMajor : ColMajor;
enum { enum {
@ -70,12 +59,12 @@ struct traits<Tensor<Scalar_, NumIndices_, Options_> >
}; };
template<typename Scalar_, typename Dimensions, int Options_> template<typename Scalar_, typename Dimensions, int Options_, typename IndexType_>
struct traits<TensorFixedSize<Scalar_, Dimensions, Options_> > struct traits<TensorFixedSize<Scalar_, Dimensions, Options_, IndexType_> >
{ {
typedef Scalar_ Scalar; typedef Scalar_ Scalar;
typedef Dense StorageKind; typedef Dense StorageKind;
typedef typename compute_index_type<static_cast<bool>(Options_&Index32Bit)>::type Index; typedef IndexType_ Index;
static const int NumDimensions = array_size<Dimensions>::value; static const int NumDimensions = array_size<Dimensions>::value;
static const int Layout = Options_ & RowMajor ? RowMajor : ColMajor; static const int Layout = Options_ & RowMajor ? RowMajor : ColMajor;
enum { enum {
@ -118,28 +107,28 @@ struct traits<TensorRef<PlainObjectType> >
}; };
template<typename _Scalar, std::size_t NumIndices_, int Options> template<typename _Scalar, std::size_t NumIndices_, int Options, typename IndexType_>
struct eval<Tensor<_Scalar, NumIndices_, Options>, Eigen::Dense> struct eval<Tensor<_Scalar, NumIndices_, Options, IndexType_>, Eigen::Dense>
{ {
typedef const Tensor<_Scalar, NumIndices_, Options>& type; typedef const Tensor<_Scalar, NumIndices_, Options, IndexType_>& type;
}; };
template<typename _Scalar, std::size_t NumIndices_, int Options> template<typename _Scalar, std::size_t NumIndices_, int Options, typename IndexType_>
struct eval<const Tensor<_Scalar, NumIndices_, Options>, Eigen::Dense> struct eval<const Tensor<_Scalar, NumIndices_, Options, IndexType_>, Eigen::Dense>
{ {
typedef const Tensor<_Scalar, NumIndices_, Options>& type; typedef const Tensor<_Scalar, NumIndices_, Options, IndexType_>& type;
}; };
template<typename Scalar_, typename Dimensions, int Options> template<typename Scalar_, typename Dimensions, int Options, typename IndexType_>
struct eval<TensorFixedSize<Scalar_, Dimensions, Options>, Eigen::Dense> struct eval<TensorFixedSize<Scalar_, Dimensions, Options, IndexType_>, Eigen::Dense>
{ {
typedef const TensorFixedSize<Scalar_, Dimensions, Options>& type; typedef const TensorFixedSize<Scalar_, Dimensions, Options, IndexType_>& type;
}; };
template<typename Scalar_, typename Dimensions, int Options> template<typename Scalar_, typename Dimensions, int Options, typename IndexType_>
struct eval<const TensorFixedSize<Scalar_, Dimensions, Options>, Eigen::Dense> struct eval<const TensorFixedSize<Scalar_, Dimensions, Options, IndexType_>, Eigen::Dense>
{ {
typedef const TensorFixedSize<Scalar_, Dimensions, Options>& type; typedef const TensorFixedSize<Scalar_, Dimensions, Options, IndexType_>& type;
}; };
template<typename PlainObjectType, int Options> template<typename PlainObjectType, int Options>
@ -167,28 +156,28 @@ struct eval<const TensorRef<PlainObjectType>, Eigen::Dense>
}; };
template <typename Scalar_, std::size_t NumIndices_, int Options_> template <typename Scalar_, std::size_t NumIndices_, int Options_, typename IndexType_>
struct nested<Tensor<Scalar_, NumIndices_, Options_> > struct nested<Tensor<Scalar_, NumIndices_, Options_, IndexType_> >
{ {
typedef const Tensor<Scalar_, NumIndices_, Options_>& type; typedef const Tensor<Scalar_, NumIndices_, Options_, IndexType_>& type;
}; };
template <typename Scalar_, std::size_t NumIndices_, int Options_> template <typename Scalar_, std::size_t NumIndices_, int Options_, typename IndexType_>
struct nested<const Tensor<Scalar_, NumIndices_, Options_> > struct nested<const Tensor<Scalar_, NumIndices_, Options_, IndexType_> >
{ {
typedef const Tensor<Scalar_, NumIndices_, Options_>& type; typedef const Tensor<Scalar_, NumIndices_, Options_, IndexType_>& type;
}; };
template <typename Scalar_, typename Dimensions, int Options> template <typename Scalar_, typename Dimensions, int Options, typename IndexType_>
struct nested<TensorFixedSize<Scalar_, Dimensions, Options> > struct nested<TensorFixedSize<Scalar_, Dimensions, Options, IndexType_> >
{ {
typedef const TensorFixedSize<Scalar_, Dimensions, Options>& type; typedef const TensorFixedSize<Scalar_, Dimensions, Options, IndexType_>& type;
}; };
template <typename Scalar_, typename Dimensions, int Options> template <typename Scalar_, typename Dimensions, int Options, typename IndexType_>
struct nested<const TensorFixedSize<Scalar_, Dimensions, Options> > struct nested<const TensorFixedSize<Scalar_, Dimensions, Options, IndexType_> >
{ {
typedef const TensorFixedSize<Scalar_, Dimensions, Options>& type; typedef const TensorFixedSize<Scalar_, Dimensions, Options, IndexType_>& type;
}; };

View File

@ -11,13 +11,11 @@
#include <Eigen/CXX11/Tensor> #include <Eigen/CXX11/Tensor>
using Eigen::Tensor;
using Eigen::RowMajor;
static void test_simple() static void test_simple()
{ {
Tensor<float, 1> vec1({6}); Tensor<float, 1, ColMajor> vec1({6});
Tensor<float, 1, Index32Bit> vec2({6}); Tensor<float, 1, ColMajor, int> vec2({6});
vec1(0) = 4.0; vec2(0) = 0.0; vec1(0) = 4.0; vec2(0) = 0.0;
vec1(1) = 8.0; vec2(1) = 1.0; vec1(1) = 8.0; vec2(1) = 1.0;
@ -27,10 +25,10 @@ static void test_simple()
vec1(5) = 42.0; vec2(5) = 5.0; vec1(5) = 42.0; vec2(5) = 5.0;
float data3[6]; float data3[6];
TensorMap<Tensor<float, 1>> vec3(data3, 6); TensorMap<Tensor<float, 1, ColMajor>> vec3(data3, 6);
vec3 = vec1.sqrt(); vec3 = vec1.sqrt();
float data4[6]; float data4[6];
TensorMap<Tensor<float, 1, Index32Bit>> vec4(data4, 6); TensorMap<Tensor<float, 1, ColMajor, int>> vec4(data4, 6);
vec4 = vec2.square(); vec4 = vec2.square();
VERIFY_IS_APPROX(vec3(0), sqrtf(4.0)); VERIFY_IS_APPROX(vec3(0), sqrtf(4.0));