blob: 48de4903a572b604b86a1733648548ed56de4853 [file] [log] [blame]
// This file is part of Eigen, a lightweight C++ template library
// for linear algebra.
//
// Copyright (C) 2013 Christian Seiler <christian@iwakd.de>
//
// 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
// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
#ifndef EIGEN_CXX11_TENSOR_TENSORSTORAGE_H
#define EIGEN_CXX11_TENSOR_TENSORSTORAGE_H
#ifdef EIGEN_TENSOR_STORAGE_CTOR_PLUGIN
#define EIGEN_INTERNAL_TENSOR_STORAGE_CTOR_PLUGIN EIGEN_TENSOR_STORAGE_CTOR_PLUGIN;
#else
#define EIGEN_INTERNAL_TENSOR_STORAGE_CTOR_PLUGIN
#endif
namespace Eigen {
/** \internal
*
* \class TensorStorage
* \ingroup CXX11_Tensor_Module
*
* \brief Stores the data of a tensor
*
* This class stores the data of fixed-size, dynamic-size or mixed tensors
* in a way as compact as possible.
*
* \sa Tensor
*/
template<typename T, typename Dimensions, int Options_> class TensorStorage;
// Pure fixed-size storage
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
EIGEN_STRONG_INLINE T *data() { return m_data; }
EIGEN_DEVICE_FUNC
EIGEN_STRONG_INLINE const T *data() const { return m_data; }
EIGEN_DEVICE_FUNC
EIGEN_STRONG_INLINE const FixedDimensions& dimensions() const { return m_dimensions; }
EIGEN_DEVICE_FUNC
EIGEN_STRONG_INLINE DenseIndex size() const { return m_dimensions.TotalSize(); }
};
// pure dynamic
template<typename T, int Options_, typename IndexType, int NumIndices_>
class TensorStorage<T, DSizes<IndexType, NumIndices_>, Options_>
{
public:
typedef IndexType Index;
typedef DSizes<IndexType, NumIndices_> Dimensions;
typedef TensorStorage<T, DSizes<IndexType, NumIndices_>, Options_> Self;
EIGEN_DEVICE_FUNC TensorStorage()
: m_data(NumIndices_ ? 0 : internal::conditional_aligned_new_auto<T,(Options_&DontAlign)==0>(1))
, m_dimensions() {}
EIGEN_DEVICE_FUNC TensorStorage(internal::constructor_without_unaligned_array_assert)
: m_data(NumIndices_ ? 0 : internal::conditional_aligned_new_auto<T,(Options_&DontAlign)==0>(1))
, m_dimensions(internal::template repeat<NumIndices_, Index>(0)) {}
EIGEN_DEVICE_FUNC TensorStorage(Index size, const array<Index, NumIndices_>& dimensions)
: 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)
: 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)
{
if (this != &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)
{ numext::swap(m_data,other.m_data); numext::swap(m_dimensions,other.m_dimensions); }
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const Dimensions& dimensions() const {return m_dimensions;}
EIGEN_DEVICE_FUNC void resize(Index size, const array<Index, NumIndices_>& nbDimensions)
{
const Index currentSz = internal::array_prod(m_dimensions);
if(size != currentSz)
{
internal::conditional_aligned_delete_auto<T,(Options_&DontAlign)==0>(m_data, currentSz);
if (size)
m_data = internal::conditional_aligned_new_auto<T,(Options_&DontAlign)==0>(size);
else
m_data = 0;
EIGEN_INTERNAL_DENSE_STORAGE_CTOR_PLUGIN
}
m_dimensions = nbDimensions;
}
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE T *data() { return m_data; }
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const T *data() const { return m_data; }
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Index size() const { return m_dimensions.TotalSize(); }
private:
T *m_data;
Dimensions m_dimensions;
};
// pure dynamic
template<typename T, int Options_>
class TensorStorage<T, VSizes<DenseIndex>, Options_>
{
T* m_data;
VSizes<DenseIndex> m_dimensions;
typedef TensorStorage<T, VSizes<DenseIndex>, Options_> Self_;
public:
EIGEN_DEVICE_FUNC TensorStorage() : m_data(0), m_dimensions() {}
template <DenseIndex NumDims>
EIGEN_DEVICE_FUNC TensorStorage(const array<DenseIndex, NumDims>& dimensions)
{
m_dimensions.resize(NumDims);
for (int i = 0; i < NumDims; ++i) {
m_dimensions[i] = dimensions[i];
}
const DenseIndex size = array_prod(dimensions);
m_data = internal::conditional_managed_new_auto<T,(Options_&DontAlign)==0,(Options_&AllocateUVM)>(size);
EIGEN_INTERNAL_TENSOR_STORAGE_CTOR_PLUGIN
}
EIGEN_DEVICE_FUNC TensorStorage(const std::vector<DenseIndex>& dimensions)
: m_dimensions(dimensions)
{
const DenseIndex size = internal::array_prod(dimensions);
m_data = internal::conditional_managed_new_auto<T,(Options_&DontAlign)==0,(Options_&AllocateUVM)>(size);
EIGEN_INTERNAL_TENSOR_STORAGE_CTOR_PLUGIN
}
#ifdef EIGEN_HAS_VARIADIC_TEMPLATES
template<typename... IndexTypes> EIGEN_DEVICE_FUNC
TensorStorage(IndexTypes... dimensions) {
const int NumDims = sizeof...(dimensions);
m_dimensions.resize(NumDims);
const array<DenseIndex, NumDims> dim{{dimensions...}};
DenseIndex size = 1;
for (int i = 0; i < NumDims; ++i) {
size *= dim[i];
m_dimensions[i] = dim[i];
}
m_data = internal::conditional_managed_new_auto<T,(Options_&DontAlign)==0,(Options_&AllocateUVM)>(size);
EIGEN_INTERNAL_TENSOR_STORAGE_CTOR_PLUGIN
}
#endif
EIGEN_DEVICE_FUNC TensorStorage(const Self_& other)
: m_data(internal::conditional_managed_new_auto<T,(Options_&DontAlign)==0,(Options_&AllocateUVM)>(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)
{
if (this != &other) {
Self_ tmp(other);
this->swap(tmp);
}
return *this;
}
EIGEN_DEVICE_FUNC ~TensorStorage()
{
internal::conditional_managed_delete_auto<T,(Options_&DontAlign)==0,(Options_&AllocateUVM)>(m_data, internal::array_prod(m_dimensions));
}
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 VSizes<DenseIndex>& dimensions() const { return m_dimensions; }
template <typename NewDimensions> EIGEN_DEVICE_FUNC
void resize(DenseIndex size, const NewDimensions& nbDimensions)
{
const DenseIndex currentSz = internal::array_prod(m_dimensions);
if(size != currentSz)
{
internal::conditional_managed_delete_auto<T,(Options_&DontAlign)==0,(Options_&AllocateUVM)>(m_data, currentSz);
if (size)
m_data = internal::conditional_managed_new_auto<T,(Options_&DontAlign)==0,(Options_&AllocateUVM)>(size);
else
m_data = 0;
EIGEN_INTERNAL_DENSE_STORAGE_CTOR_PLUGIN
}
m_dimensions.resize(internal::array_size<NewDimensions>::value);
for (int i = 0; i < internal::array_size<NewDimensions>::value; ++i) {
m_dimensions[i] = nbDimensions[i];
}
}
EIGEN_DEVICE_FUNC void resize(DenseIndex size, const std::vector<DenseIndex>& nbDimensions)
{
const DenseIndex currentSz = internal::array_prod(m_dimensions);
if(size != currentSz)
{
internal::conditional_managed_delete_auto<T,(Options_&DontAlign)==0,(Options_&AllocateUVM)>(m_data, currentSz);
if (size)
m_data = internal::conditional_managed_new_auto<T,(Options_&DontAlign)==0,(Options_&AllocateUVM)>(size);
else
m_data = 0;
EIGEN_INTERNAL_DENSE_STORAGE_CTOR_PLUGIN
}
m_dimensions = nbDimensions;
}
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE T *data() { return m_data; }
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const T *data() const { return m_data; }
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE DenseIndex size() const { return m_dimensions.TotalSize(); }
};
} // end namespace Eigen
#endif // EIGEN_CXX11_TENSOR_TENSORSTORAGE_H