• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // This file is part of Eigen, a lightweight C++ template library
2 // for linear algebra.
3 //
4 // Copyright (C) 2013 Christian Seiler <christian@iwakd.de>
5 // Copyright (C) 2014-2015 Benoit Steiner <benoit.steiner.goog@gmail.com>
6 //
7 // This Source Code Form is subject to the terms of the Mozilla
8 // Public License v. 2.0. If a copy of the MPL was not distributed
9 // with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
10 
11 #ifndef EIGEN_CXX11_TENSOR_TENSORSTORAGE_H
12 #define EIGEN_CXX11_TENSOR_TENSORSTORAGE_H
13 
14 #ifdef EIGEN_TENSOR_STORAGE_CTOR_PLUGIN
15   #define EIGEN_INTERNAL_TENSOR_STORAGE_CTOR_PLUGIN EIGEN_TENSOR_STORAGE_CTOR_PLUGIN;
16 #else
17   #define EIGEN_INTERNAL_TENSOR_STORAGE_CTOR_PLUGIN
18 #endif
19 
20 namespace Eigen {
21 
22 /** \internal
23   *
24   * \class TensorStorage
25   * \ingroup CXX11_Tensor_Module
26   *
27   * \brief Stores the data of a tensor
28   *
29   * This class stores the data of fixed-size, dynamic-size or mixed tensors
30   * in a way as compact as possible.
31   *
32   * \sa Tensor
33   */
34 template<typename T, typename Dimensions, int Options> class TensorStorage;
35 
36 
37 // Pure fixed-size storage
38 template<typename T, typename FixedDimensions, int Options_>
39 class TensorStorage
40 {
41  private:
42   static const std::size_t Size = FixedDimensions::total_size;
43 
44   // Allocate an array of size at least one to prevent compiler warnings.
45   static const std::size_t MinSize = max_n_1<Size>::size;
46   EIGEN_ALIGN_MAX T m_data[MinSize];
47 
48  public:
49   EIGEN_DEVICE_FUNC
TensorStorage()50   EIGEN_STRONG_INLINE TensorStorage() {
51   }
52 
53   EIGEN_DEVICE_FUNC
data()54   EIGEN_STRONG_INLINE T *data() { return m_data; }
55   EIGEN_DEVICE_FUNC
data()56   EIGEN_STRONG_INLINE const T *data() const { return m_data; }
57 
58   static EIGEN_DEVICE_FUNC
dimensions()59   EIGEN_STRONG_INLINE const FixedDimensions& dimensions()
60   {
61     static const FixedDimensions* singleton_dimensions = new FixedDimensions();
62     return *singleton_dimensions;
63   }
64 
65   EIGEN_DEVICE_FUNC
size()66   EIGEN_STRONG_INLINE DenseIndex size() const { return Size; }
67 };
68 
69 // pure dynamic
70 template<typename T, typename IndexType, int NumIndices_, int Options_>
71 class TensorStorage<T, DSizes<IndexType, NumIndices_>, Options_>
72 {
73   public:
74     typedef IndexType Index;
75     typedef DSizes<IndexType, NumIndices_> Dimensions;
76     typedef TensorStorage<T, DSizes<IndexType, NumIndices_>, Options_> Self;
77 
TensorStorage()78     EIGEN_DEVICE_FUNC TensorStorage() : m_data(0), m_dimensions() {
79       if (NumIndices_ == 0) {
80 	m_data = internal::conditional_aligned_new_auto<T,(Options_&DontAlign)==0>(1);
81       }
82     }
TensorStorage(internal::constructor_without_unaligned_array_assert)83     EIGEN_DEVICE_FUNC TensorStorage(internal::constructor_without_unaligned_array_assert)
84       : m_data(0), m_dimensions(internal::template repeat<NumIndices_, Index>(0)) {}
TensorStorage(Index size,const array<Index,NumIndices_> & dimensions)85     EIGEN_DEVICE_FUNC TensorStorage(Index size, const array<Index, NumIndices_>& dimensions)
86         : m_data(internal::conditional_aligned_new_auto<T,(Options_&DontAlign)==0>(size)), m_dimensions(dimensions)
87       { EIGEN_INTERNAL_TENSOR_STORAGE_CTOR_PLUGIN }
88 
89 #if EIGEN_HAS_VARIADIC_TEMPLATES
90     template <typename... DenseIndex>
TensorStorage(DenseIndex...indices)91     EIGEN_DEVICE_FUNC TensorStorage(DenseIndex... indices) : m_dimensions(indices...) {
92       m_data = internal::conditional_aligned_new_auto<T,(Options_&DontAlign)==0>(internal::array_prod(m_dimensions));
93     }
94 #endif
95 
TensorStorage(const Self & other)96     EIGEN_DEVICE_FUNC TensorStorage(const Self& other)
97       : m_data(internal::conditional_aligned_new_auto<T,(Options_&DontAlign)==0>(internal::array_prod(other.m_dimensions)))
98       , m_dimensions(other.m_dimensions)
99     {
100       internal::smart_copy(other.m_data, other.m_data+internal::array_prod(other.m_dimensions), m_data);
101     }
102     EIGEN_DEVICE_FUNC Self& operator=(const Self& other)
103     {
104       if (this != &other) {
105         Self tmp(other);
106         this->swap(tmp);
107       }
108       return *this;
109     }
110 
111 #if EIGEN_HAS_RVALUE_REFERENCES
TensorStorage(Self && other)112     EIGEN_DEVICE_FUNC TensorStorage(Self&& other) : TensorStorage()
113     {
114       *this = std::move(other);
115     }
116 
117     EIGEN_DEVICE_FUNC Self& operator=(Self&& other)
118     {
119       numext::swap(m_data, other.m_data);
120       numext::swap(m_dimensions, other.m_dimensions);
121       return *this;
122     }
123 #endif
124 
~TensorStorage()125     EIGEN_DEVICE_FUNC  ~TensorStorage() { internal::conditional_aligned_delete_auto<T,(Options_&DontAlign)==0>(m_data, internal::array_prod(m_dimensions)); }
swap(Self & other)126     EIGEN_DEVICE_FUNC  void swap(Self& other)
127     { numext::swap(m_data,other.m_data); numext::swap(m_dimensions,other.m_dimensions); }
128 
dimensions()129     EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const Dimensions& dimensions() const {return m_dimensions;}
130 
resize(Index size,const array<Index,NumIndices_> & nbDimensions)131     EIGEN_DEVICE_FUNC void resize(Index size, const array<Index, NumIndices_>& nbDimensions)
132     {
133       const Index currentSz = internal::array_prod(m_dimensions);
134       if(size != currentSz)
135       {
136         internal::conditional_aligned_delete_auto<T,(Options_&DontAlign)==0>(m_data, currentSz);
137         if (size)
138           m_data = internal::conditional_aligned_new_auto<T,(Options_&DontAlign)==0>(size);
139         else if (NumIndices_ == 0) {
140 	  m_data = internal::conditional_aligned_new_auto<T,(Options_&DontAlign)==0>(1);
141 	}
142 	else
143           m_data = 0;
144         EIGEN_INTERNAL_DENSE_STORAGE_CTOR_PLUGIN({})
145       }
146       m_dimensions = nbDimensions;
147     }
148 
data()149     EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE T *data() { return m_data; }
data()150     EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const T *data() const { return m_data; }
151 
size()152     EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Index size() const { return m_dimensions.TotalSize(); }
153 
154  private:
155   T *m_data;
156   Dimensions m_dimensions;
157 };
158 
159 } // end namespace Eigen
160 
161 #endif // EIGEN_CXX11_TENSOR_TENSORSTORAGE_H
162