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