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 */
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
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
DontAlign = 0x2
};
/** \ingroup enums

View File

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

View File

@ -460,8 +460,7 @@ class TensorBase<Derived, ReadOnlyAccessors>
}
protected:
template <typename Scalar, std::size_t NumIndices, int Options> friend class Tensor;
template <typename Scalar, int Options> friend class TensorVarDim;
template <typename Scalar, std::size_t NumIndices, int Options, typename IndexType> friend class Tensor;
template <typename OtherDerived, int AccessLevel> friend class TensorBase;
EIGEN_DEVICE_FUNC
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;
static const int NumDimensions = DerivedTraits::NumDimensions;
template <typename Scalar, std::size_t NumIndices, int Options> friend class Tensor;
template <typename Scalar, int Options> friend class TensorVarDim;
template <typename Scalar, std::size_t NumIndices, int Options, typename IndexType> friend class Tensor;
template <typename OtherDerived, int AccessLevel> friend class TensorBase;
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>
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;
};
}
#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) {
return get<n, typename Sizes<V1,V2,V3,V4,V5>::Base>::value;
};
}
#endif

View File

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

View File

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

View File

@ -2,6 +2,7 @@
// for linear algebra.
//
// 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
// Public License v. 2.0. If a copy of the MPL was not distributed
@ -30,21 +31,22 @@ namespace Eigen {
*
* \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
template<typename T, DenseIndex NumIndices_, DenseIndex Size, int Options_, typename FixedDimensions>
class TensorStorage
template<typename T, int Options_, typename FixedDimensions>
class TensorStorage<T, FixedDimensions, Options_>
{
private:
static const std::size_t Size = FixedDimensions::total_size;
EIGEN_ALIGN_DEFAULT T m_data[Size];
FixedDimensions m_dimensions;
public:
EIGEN_DEVICE_FUNC
EIGEN_STRONG_INLINE TensorStorage() {
EIGEN_STATIC_ASSERT(Size == FixedDimensions::total_size, YOU_MADE_A_PROGRAMMING_MISTAKE)
}
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
template<typename T, DenseIndex NumIndices_, int Options_>
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>
template<typename T, int Options_, typename IndexType, std::size_t NumIndices_>
class TensorStorage<T, DSizes<IndexType, NumIndices_>, Options_>
{
public:
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> Self_;
typedef IndexType Index;
typedef DSizes<IndexType, NumIndices_> Dimensions;
typedef TensorStorage<T, DSizes<IndexType, NumIndices_>, Options_> Self;
EIGEN_DEVICE_FUNC TensorStorage() : m_data(0), m_dimensions() {}
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)
{ 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_dimensions(other.m_dimensions)
{
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) {
Self_ tmp(other);
Self tmp(other);
this->swap(tmp);
}
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 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); }
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};
};
template<bool force32bit>
struct compute_index_type {
typedef DenseIndex type;
};
template<>
struct compute_index_type<true> {
typedef int type;
};
template<typename Scalar_, std::size_t NumIndices_, int Options_>
struct traits<Tensor<Scalar_, NumIndices_, Options_> >
template<typename Scalar_, std::size_t NumIndices_, int Options_, typename IndexType_>
struct traits<Tensor<Scalar_, NumIndices_, Options_, IndexType_> >
{
typedef Scalar_ Scalar;
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 Layout = Options_ & RowMajor ? RowMajor : ColMajor;
enum {
@ -70,12 +59,12 @@ struct traits<Tensor<Scalar_, NumIndices_, Options_> >
};
template<typename Scalar_, typename Dimensions, int Options_>
struct traits<TensorFixedSize<Scalar_, Dimensions, Options_> >
template<typename Scalar_, typename Dimensions, int Options_, typename IndexType_>
struct traits<TensorFixedSize<Scalar_, Dimensions, Options_, IndexType_> >
{
typedef Scalar_ Scalar;
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 Layout = Options_ & RowMajor ? RowMajor : ColMajor;
enum {
@ -118,28 +107,28 @@ struct traits<TensorRef<PlainObjectType> >
};
template<typename _Scalar, std::size_t NumIndices_, int Options>
struct eval<Tensor<_Scalar, NumIndices_, Options>, Eigen::Dense>
template<typename _Scalar, std::size_t NumIndices_, int Options, typename IndexType_>
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>
struct eval<const Tensor<_Scalar, NumIndices_, Options>, Eigen::Dense>
template<typename _Scalar, std::size_t NumIndices_, int Options, typename IndexType_>
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>
struct eval<TensorFixedSize<Scalar_, Dimensions, Options>, Eigen::Dense>
template<typename Scalar_, typename Dimensions, int Options, typename IndexType_>
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>
struct eval<const TensorFixedSize<Scalar_, Dimensions, Options>, Eigen::Dense>
template<typename Scalar_, typename Dimensions, int Options, typename IndexType_>
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>
@ -167,28 +156,28 @@ struct eval<const TensorRef<PlainObjectType>, Eigen::Dense>
};
template <typename Scalar_, std::size_t NumIndices_, int Options_>
struct nested<Tensor<Scalar_, NumIndices_, Options_> >
template <typename Scalar_, std::size_t NumIndices_, int Options_, typename IndexType_>
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_>
struct nested<const Tensor<Scalar_, NumIndices_, Options_> >
template <typename Scalar_, std::size_t NumIndices_, int Options_, typename IndexType_>
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>
struct nested<TensorFixedSize<Scalar_, Dimensions, Options> >
template <typename Scalar_, typename Dimensions, int Options, typename IndexType_>
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>
struct nested<const TensorFixedSize<Scalar_, Dimensions, Options> >
template <typename Scalar_, typename Dimensions, int Options, typename IndexType_>
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>
using Eigen::Tensor;
using Eigen::RowMajor;
static void test_simple()
{
Tensor<float, 1> vec1({6});
Tensor<float, 1, Index32Bit> vec2({6});
Tensor<float, 1, ColMajor> vec1({6});
Tensor<float, 1, ColMajor, int> vec2({6});
vec1(0) = 4.0; vec2(0) = 0.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;
float data3[6];
TensorMap<Tensor<float, 1>> vec3(data3, 6);
TensorMap<Tensor<float, 1, ColMajor>> vec3(data3, 6);
vec3 = vec1.sqrt();
float data4[6];
TensorMap<Tensor<float, 1, Index32Bit>> vec4(data4, 6);
TensorMap<Tensor<float, 1, ColMajor, int>> vec4(data4, 6);
vec4 = vec2.square();
VERIFY_IS_APPROX(vec3(0), sqrtf(4.0));