cart-elc

Source code for CART-ELC
git clone git://git.laack.co/cart-elc.git
Log | Files | Refs | README | LICENSE

TensorMap.h (14191B)


      1 // This file is part of Eigen, a lightweight C++ template library
      2 // for linear algebra.
      3 //
      4 // Copyright (C) 2014 Benoit Steiner <benoit.steiner.goog@gmail.com>
      5 //
      6 // This Source Code Form is subject to the terms of the Mozilla
      7 // Public License v. 2.0. If a copy of the MPL was not distributed
      8 // with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
      9 
     10 #ifndef EIGEN_CXX11_TENSOR_TENSOR_MAP_H
     11 #define EIGEN_CXX11_TENSOR_TENSOR_MAP_H
     12 
     13 namespace Eigen {
     14 
     15 // FIXME use proper doxygen documentation (e.g. \tparam MakePointer_)
     16 
     17 /** \class TensorMap
     18   * \ingroup CXX11_Tensor_Module
     19   *
     20   * \brief A tensor expression mapping an existing array of data.
     21   *
     22   */
     23 /// `template <class> class MakePointer_` is added to convert the host pointer to the device pointer.
     24 /// It is added due to the fact that for our device compiler `T*` is not allowed.
     25 /// If we wanted to use the same Evaluator functions we have to convert that type to our pointer `T`.
     26 /// This is done through our `MakePointer_` class. By default the Type in the `MakePointer_<T>` is `T*` .
     27 /// Therefore, by adding the default value, we managed to convert the type and it does not break any
     28 /// existing code as its default value is `T*`.
     29 template<typename PlainObjectType, int Options_, template <class> class MakePointer_> class TensorMap : public TensorBase<TensorMap<PlainObjectType, Options_, MakePointer_> >
     30 {
     31   public:
     32     typedef TensorMap<PlainObjectType, Options_, MakePointer_> Self;
     33     typedef TensorBase<TensorMap<PlainObjectType, Options_, MakePointer_> > Base;
     34   #ifdef EIGEN_USE_SYCL
     35     typedef  typename Eigen::internal::remove_reference<typename Eigen::internal::nested<Self>::type>::type Nested;
     36   #else
     37      typedef typename Eigen::internal::nested<Self>::type Nested;
     38   #endif
     39    typedef typename internal::traits<PlainObjectType>::StorageKind StorageKind;
     40     typedef typename internal::traits<PlainObjectType>::Index Index;
     41     typedef typename internal::traits<PlainObjectType>::Scalar Scalar;
     42     typedef typename NumTraits<Scalar>::Real RealScalar;
     43     typedef typename PlainObjectType::Base::CoeffReturnType CoeffReturnType;
     44 
     45     typedef typename MakePointer_<Scalar>::Type PointerType;
     46     typedef typename MakePointer_<Scalar>::ConstType PointerConstType;
     47 
     48     // WARN: PointerType still can be a pointer to const (const Scalar*), for
     49     // example in TensorMap<Tensor<const Scalar, ...>> expression. This type of
     50     // expression should be illegal, but adding this restriction is not possible
     51     // in practice (see https://bitbucket.org/eigen/eigen/pull-requests/488).
     52     typedef typename internal::conditional<
     53         bool(internal::is_lvalue<PlainObjectType>::value),
     54         PointerType,      // use simple pointer in lvalue expressions
     55         PointerConstType  // use const pointer in rvalue expressions
     56         >::type StoragePointerType;
     57 
     58     // If TensorMap was constructed over rvalue expression (e.g. const Tensor),
     59     // we should return a reference to const from operator() (and others), even
     60     // if TensorMap itself is not const.
     61     typedef typename internal::conditional<
     62         bool(internal::is_lvalue<PlainObjectType>::value),
     63         Scalar&,
     64         const Scalar&
     65         >::type StorageRefType;
     66 
     67     static const int Options = Options_;
     68 
     69     static const Index NumIndices = PlainObjectType::NumIndices;
     70     typedef typename PlainObjectType::Dimensions Dimensions;
     71 
     72     enum {
     73       IsAligned = ((int(Options_)&Aligned)==Aligned),
     74       Layout = PlainObjectType::Layout,
     75       CoordAccess = true,
     76       RawAccess = true
     77     };
     78 
     79     EIGEN_DEVICE_FUNC
     80     EIGEN_STRONG_INLINE TensorMap(StoragePointerType dataPtr) : m_data(dataPtr), m_dimensions() {
     81       // The number of dimensions used to construct a tensor must be equal to the rank of the tensor.
     82       EIGEN_STATIC_ASSERT((0 == NumIndices || NumIndices == Dynamic), YOU_MADE_A_PROGRAMMING_MISTAKE)
     83     }
     84 
     85 #if EIGEN_HAS_VARIADIC_TEMPLATES
     86     template<typename... IndexTypes> EIGEN_DEVICE_FUNC
     87     EIGEN_STRONG_INLINE TensorMap(StoragePointerType dataPtr, Index firstDimension, IndexTypes... otherDimensions) : m_data(dataPtr), m_dimensions(firstDimension, otherDimensions...) {
     88       // The number of dimensions used to construct a tensor must be equal to the rank of the tensor.
     89       EIGEN_STATIC_ASSERT((sizeof...(otherDimensions) + 1 == NumIndices || NumIndices == Dynamic), YOU_MADE_A_PROGRAMMING_MISTAKE)
     90     }
     91 #else
     92     EIGEN_DEVICE_FUNC
     93     EIGEN_STRONG_INLINE TensorMap(StoragePointerType dataPtr, Index firstDimension) : m_data(dataPtr), m_dimensions(firstDimension) {
     94       // The number of dimensions used to construct a tensor must be equal to the rank of the tensor.
     95       EIGEN_STATIC_ASSERT((1 == NumIndices || NumIndices == Dynamic), YOU_MADE_A_PROGRAMMING_MISTAKE)
     96     }
     97     EIGEN_DEVICE_FUNC
     98     EIGEN_STRONG_INLINE TensorMap(StoragePointerType dataPtr, Index dim1, Index dim2) : m_data(dataPtr), m_dimensions(dim1, dim2) {
     99       EIGEN_STATIC_ASSERT(2 == NumIndices || NumIndices == Dynamic, YOU_MADE_A_PROGRAMMING_MISTAKE)
    100     }
    101     EIGEN_DEVICE_FUNC
    102     EIGEN_STRONG_INLINE TensorMap(StoragePointerType dataPtr, Index dim1, Index dim2, Index dim3) : m_data(dataPtr), m_dimensions(dim1, dim2, dim3) {
    103       EIGEN_STATIC_ASSERT(3 == NumIndices || NumIndices == Dynamic, YOU_MADE_A_PROGRAMMING_MISTAKE)
    104     }
    105     EIGEN_DEVICE_FUNC
    106     EIGEN_STRONG_INLINE TensorMap(StoragePointerType dataPtr, Index dim1, Index dim2, Index dim3, Index dim4) : m_data(dataPtr), m_dimensions(dim1, dim2, dim3, dim4) {
    107       EIGEN_STATIC_ASSERT(4 == NumIndices || NumIndices == Dynamic, YOU_MADE_A_PROGRAMMING_MISTAKE)
    108     }
    109     EIGEN_DEVICE_FUNC
    110     EIGEN_STRONG_INLINE TensorMap(StoragePointerType dataPtr, Index dim1, Index dim2, Index dim3, Index dim4, Index dim5) : m_data(dataPtr), m_dimensions(dim1, dim2, dim3, dim4, dim5) {
    111       EIGEN_STATIC_ASSERT(5 == NumIndices || NumIndices == Dynamic, YOU_MADE_A_PROGRAMMING_MISTAKE)
    112     }
    113 #endif
    114 
    115    EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE TensorMap(StoragePointerType dataPtr, const array<Index, NumIndices>& dimensions)
    116       : m_data(dataPtr), m_dimensions(dimensions)
    117     { }
    118 
    119     template <typename Dimensions>
    120     EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE TensorMap(StoragePointerType dataPtr, const Dimensions& dimensions)
    121       : m_data(dataPtr), m_dimensions(dimensions)
    122     { }
    123 
    124     EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE TensorMap(PlainObjectType& tensor)
    125       : m_data(tensor.data()), m_dimensions(tensor.dimensions())
    126     { }
    127 
    128     EIGEN_DEVICE_FUNC
    129     EIGEN_STRONG_INLINE Index rank() const { return m_dimensions.rank(); }
    130     EIGEN_DEVICE_FUNC
    131     EIGEN_STRONG_INLINE Index dimension(Index n) const { return m_dimensions[n]; }
    132     EIGEN_DEVICE_FUNC
    133     EIGEN_STRONG_INLINE const Dimensions& dimensions() const { return m_dimensions; }
    134     EIGEN_DEVICE_FUNC
    135     EIGEN_STRONG_INLINE Index size() const { return m_dimensions.TotalSize(); }
    136     EIGEN_DEVICE_FUNC
    137     EIGEN_STRONG_INLINE StoragePointerType data() { return m_data; }
    138     EIGEN_DEVICE_FUNC
    139     EIGEN_STRONG_INLINE StoragePointerType data() const { return m_data; }
    140 
    141     EIGEN_DEVICE_FUNC
    142     EIGEN_STRONG_INLINE StorageRefType operator()(const array<Index, NumIndices>& indices) const
    143     {
    144       //      eigen_assert(checkIndexRange(indices));
    145       if (PlainObjectType::Options&RowMajor) {
    146         const Index index = m_dimensions.IndexOfRowMajor(indices);
    147         return m_data[index];
    148       } else {
    149         const Index index = m_dimensions.IndexOfColMajor(indices);
    150         return m_data[index];
    151       }
    152     }
    153 
    154     EIGEN_DEVICE_FUNC
    155     EIGEN_STRONG_INLINE StorageRefType operator()() const
    156     {
    157       EIGEN_STATIC_ASSERT(NumIndices == 0, YOU_MADE_A_PROGRAMMING_MISTAKE)
    158       return m_data[0];
    159     }
    160 
    161     EIGEN_DEVICE_FUNC
    162     EIGEN_STRONG_INLINE StorageRefType operator()(Index index) const
    163     {
    164       eigen_internal_assert(index >= 0 && index < size());
    165       return m_data[index];
    166     }
    167 
    168 #if EIGEN_HAS_VARIADIC_TEMPLATES
    169     template<typename... IndexTypes> EIGEN_DEVICE_FUNC
    170     EIGEN_STRONG_INLINE StorageRefType operator()(Index firstIndex, Index secondIndex, IndexTypes... otherIndices) const
    171     {
    172       EIGEN_STATIC_ASSERT(sizeof...(otherIndices) + 2 == NumIndices, YOU_MADE_A_PROGRAMMING_MISTAKE)
    173       eigen_assert(internal::all((Eigen::NumTraits<Index>::highest() >= otherIndices)...));
    174       if (PlainObjectType::Options&RowMajor) {
    175         const Index index = m_dimensions.IndexOfRowMajor(array<Index, NumIndices>{{firstIndex, secondIndex, otherIndices...}});
    176         return m_data[index];
    177       } else {
    178         const Index index = m_dimensions.IndexOfColMajor(array<Index, NumIndices>{{firstIndex, secondIndex, otherIndices...}});
    179         return m_data[index];
    180       }
    181     }
    182 #else
    183     EIGEN_DEVICE_FUNC
    184     EIGEN_STRONG_INLINE StorageRefType operator()(Index i0, Index i1) const
    185     {
    186       if (PlainObjectType::Options&RowMajor) {
    187         const Index index = i1 + i0 * m_dimensions[1];
    188         return m_data[index];
    189       } else {
    190         const Index index = i0 + i1 * m_dimensions[0];
    191         return m_data[index];
    192       }
    193     }
    194     EIGEN_DEVICE_FUNC
    195     EIGEN_STRONG_INLINE StorageRefType operator()(Index i0, Index i1, Index i2) const
    196     {
    197       if (PlainObjectType::Options&RowMajor) {
    198          const Index index = i2 + m_dimensions[2] * (i1 + m_dimensions[1] * i0);
    199          return m_data[index];
    200       } else {
    201          const Index index = i0 + m_dimensions[0] * (i1 + m_dimensions[1] * i2);
    202         return m_data[index];
    203       }
    204     }
    205     EIGEN_DEVICE_FUNC
    206     EIGEN_STRONG_INLINE StorageRefType operator()(Index i0, Index i1, Index i2, Index i3) const
    207     {
    208       if (PlainObjectType::Options&RowMajor) {
    209         const Index index = i3 + m_dimensions[3] * (i2 + m_dimensions[2] * (i1 + m_dimensions[1] * i0));
    210         return m_data[index];
    211       } else {
    212         const Index index = i0 + m_dimensions[0] * (i1 + m_dimensions[1] * (i2 + m_dimensions[2] * i3));
    213         return m_data[index];
    214       }
    215     }
    216     EIGEN_DEVICE_FUNC
    217     EIGEN_STRONG_INLINE StorageRefType operator()(Index i0, Index i1, Index i2, Index i3, Index i4) const
    218     {
    219       if (PlainObjectType::Options&RowMajor) {
    220         const Index index = i4 + m_dimensions[4] * (i3 + m_dimensions[3] * (i2 + m_dimensions[2] * (i1 + m_dimensions[1] * i0)));
    221         return m_data[index];
    222       } else {
    223         const Index index = i0 + m_dimensions[0] * (i1 + m_dimensions[1] * (i2 + m_dimensions[2] * (i3 + m_dimensions[3] * i4)));
    224         return m_data[index];
    225       }
    226     }
    227 #endif
    228 
    229     EIGEN_DEVICE_FUNC
    230     EIGEN_STRONG_INLINE StorageRefType operator()(const array<Index, NumIndices>& indices)
    231     {
    232       //      eigen_assert(checkIndexRange(indices));
    233       if (PlainObjectType::Options&RowMajor) {
    234         const Index index = m_dimensions.IndexOfRowMajor(indices);
    235         return m_data[index];
    236       } else {
    237         const Index index = m_dimensions.IndexOfColMajor(indices);
    238         return m_data[index];
    239       }
    240     }
    241 
    242     EIGEN_DEVICE_FUNC
    243     EIGEN_STRONG_INLINE StorageRefType operator()()
    244     {
    245       EIGEN_STATIC_ASSERT(NumIndices == 0, YOU_MADE_A_PROGRAMMING_MISTAKE)
    246       return m_data[0];
    247     }
    248 
    249     EIGEN_DEVICE_FUNC
    250     EIGEN_STRONG_INLINE StorageRefType operator()(Index index)
    251     {
    252       eigen_internal_assert(index >= 0 && index < size());
    253       return m_data[index];
    254     }
    255 
    256 #if EIGEN_HAS_VARIADIC_TEMPLATES
    257     template<typename... IndexTypes> EIGEN_DEVICE_FUNC
    258     EIGEN_STRONG_INLINE StorageRefType operator()(Index firstIndex, Index secondIndex, IndexTypes... otherIndices)
    259     {
    260       static_assert(sizeof...(otherIndices) + 2 == NumIndices || NumIndices == Dynamic, "Number of indices used to access a tensor coefficient must be equal to the rank of the tensor.");
    261        eigen_assert(internal::all((Eigen::NumTraits<Index>::highest() >= otherIndices)...));
    262       const std::size_t NumDims = sizeof...(otherIndices) + 2;
    263       if (PlainObjectType::Options&RowMajor) {
    264         const Index index = m_dimensions.IndexOfRowMajor(array<Index, NumDims>{{firstIndex, secondIndex, otherIndices...}});
    265         return m_data[index];
    266       } else {
    267         const Index index = m_dimensions.IndexOfColMajor(array<Index, NumDims>{{firstIndex, secondIndex, otherIndices...}});
    268         return m_data[index];
    269       }
    270     }
    271 #else
    272     EIGEN_DEVICE_FUNC
    273     EIGEN_STRONG_INLINE StorageRefType operator()(Index i0, Index i1)
    274     {
    275        if (PlainObjectType::Options&RowMajor) {
    276          const Index index = i1 + i0 * m_dimensions[1];
    277         return m_data[index];
    278       } else {
    279         const Index index = i0 + i1 * m_dimensions[0];
    280         return m_data[index];
    281       }
    282     }
    283     EIGEN_DEVICE_FUNC
    284     EIGEN_STRONG_INLINE StorageRefType operator()(Index i0, Index i1, Index i2)
    285     {
    286        if (PlainObjectType::Options&RowMajor) {
    287          const Index index = i2 + m_dimensions[2] * (i1 + m_dimensions[1] * i0);
    288         return m_data[index];
    289       } else {
    290          const Index index = i0 + m_dimensions[0] * (i1 + m_dimensions[1] * i2);
    291         return m_data[index];
    292       }
    293     }
    294     EIGEN_DEVICE_FUNC
    295     EIGEN_STRONG_INLINE StorageRefType operator()(Index i0, Index i1, Index i2, Index i3)
    296     {
    297       if (PlainObjectType::Options&RowMajor) {
    298         const Index index = i3 + m_dimensions[3] * (i2 + m_dimensions[2] * (i1 + m_dimensions[1] * i0));
    299         return m_data[index];
    300       } else {
    301         const Index index = i0 + m_dimensions[0] * (i1 + m_dimensions[1] * (i2 + m_dimensions[2] * i3));
    302         return m_data[index];
    303       }
    304     }
    305     EIGEN_DEVICE_FUNC
    306     EIGEN_STRONG_INLINE StorageRefType operator()(Index i0, Index i1, Index i2, Index i3, Index i4)
    307     {
    308       if (PlainObjectType::Options&RowMajor) {
    309         const Index index = i4 + m_dimensions[4] * (i3 + m_dimensions[3] * (i2 + m_dimensions[2] * (i1 + m_dimensions[1] * i0)));
    310         return m_data[index];
    311       } else {
    312         const Index index = i0 + m_dimensions[0] * (i1 + m_dimensions[1] * (i2 + m_dimensions[2] * (i3 + m_dimensions[3] * i4)));
    313         return m_data[index];
    314       }
    315     }
    316 #endif
    317 
    318     EIGEN_TENSOR_INHERIT_ASSIGNMENT_OPERATORS(TensorMap)
    319 
    320   private:
    321     StoragePointerType m_data;
    322     Dimensions m_dimensions;
    323 };
    324 
    325 } // end namespace Eigen
    326 
    327 #endif // EIGEN_CXX11_TENSOR_TENSOR_MAP_H