2014-04-28 10:32:27 -07:00
// This file is part of Eigen, a lightweight C++ template library
// for linear algebra.
//
// Copyright (C) 2014 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
// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
# ifndef EIGEN_CXX11_TENSOR_TENSOR_MAP_H
# define EIGEN_CXX11_TENSOR_TENSOR_MAP_H
2021-09-10 19:12:26 +00:00
# include "./InternalHeaderCheck.h"
2014-04-28 10:32:27 -07:00
namespace Eigen {
2018-10-19 21:10:28 +02:00
// FIXME use proper doxygen documentation (e.g. \tparam MakePointer_)
2014-04-28 10:32:27 -07:00
/** \class TensorMap
* \ ingroup CXX11_Tensor_Module
*
* \ brief A tensor expression mapping an existing array of data .
*
*/
2018-10-19 21:10:28 +02:00
/// `template <class> class MakePointer_` is added to convert the host pointer to the device pointer.
/// It is added due to the fact that for our device compiler `T*` is not allowed.
/// If we wanted to use the same Evaluator functions we have to convert that type to our pointer `T`.
/// This is done through our `MakePointer_` class. By default the Type in the `MakePointer_<T>` is `T*` .
2016-09-19 12:44:13 +01:00
/// Therefore, by adding the default value, we managed to convert the type and it does not break any
2018-10-19 21:10:28 +02:00
/// existing code as its default value is `T*`.
2016-09-19 12:44:13 +01:00
template < typename PlainObjectType , int Options_ , template < class > class MakePointer_ > class TensorMap : public TensorBase < TensorMap < PlainObjectType , Options_ , MakePointer_ > >
2014-04-28 10:32:27 -07:00
{
public :
2016-09-19 12:44:13 +01:00
typedef TensorMap < PlainObjectType , Options_ , MakePointer_ > Self ;
2020-11-12 15:59:29 -08:00
typedef TensorBase < TensorMap < PlainObjectType , Options_ , MakePointer_ > > Base ;
2019-06-28 10:08:23 +01:00
# ifdef EIGEN_USE_SYCL
2022-03-16 16:43:40 +00:00
typedef std : : remove_reference_t < typename Eigen : : internal : : nested < Self > : : type > Nested ;
2019-06-28 10:08:23 +01:00
# else
typedef typename Eigen : : internal : : nested < Self > : : type Nested ;
# endif
typedef typename internal : : traits < PlainObjectType > : : StorageKind StorageKind ;
2014-04-28 10:32:27 -07:00
typedef typename internal : : traits < PlainObjectType > : : Index Index ;
typedef typename internal : : traits < PlainObjectType > : : Scalar Scalar ;
typedef typename NumTraits < Scalar > : : Real RealScalar ;
2020-11-12 15:59:29 -08:00
typedef typename PlainObjectType : : Base : : CoeffReturnType CoeffReturnType ;
2014-04-28 10:32:27 -07:00
2016-09-19 12:44:13 +01:00
typedef typename MakePointer_ < Scalar > : : Type PointerType ;
2019-08-28 17:46:05 -07:00
typedef typename MakePointer_ < Scalar > : : ConstType PointerConstType ;
// WARN: PointerType still can be a pointer to const (const Scalar*), for
// example in TensorMap<Tensor<const Scalar, ...>> expression. This type of
// expression should be illegal, but adding this restriction is not possible
// in practice (see https://bitbucket.org/eigen/eigen/pull-requests/488).
2022-03-16 16:43:40 +00:00
typedef std : : conditional_t <
2019-08-28 17:46:05 -07:00
bool ( internal : : is_lvalue < PlainObjectType > : : value ) ,
PointerType , // use simple pointer in lvalue expressions
PointerConstType // use const pointer in rvalue expressions
2022-03-16 16:43:40 +00:00
> StoragePointerType ;
2019-08-28 17:46:05 -07:00
// If TensorMap was constructed over rvalue expression (e.g. const Tensor),
// we should return a reference to const from operator() (and others), even
// if TensorMap itself is not const.
2022-03-16 16:43:40 +00:00
typedef std : : conditional_t <
2019-08-28 17:46:05 -07:00
bool ( internal : : is_lvalue < PlainObjectType > : : value ) ,
Scalar & ,
const Scalar &
2022-03-16 16:43:40 +00:00
> StorageRefType ;
2014-04-28 10:32:27 -07:00
2022-04-04 17:33:33 +00:00
static constexpr int Options = Options_ ;
2014-05-16 15:08:05 -07:00
2022-04-04 17:33:33 +00:00
static constexpr Index NumIndices = PlainObjectType : : NumIndices ;
2014-05-22 16:22:35 -07:00
typedef typename PlainObjectType : : Dimensions Dimensions ;
2022-03-16 16:43:40 +00:00
static constexpr int Layout = PlainObjectType : : Layout ;
2014-05-16 15:08:05 -07:00
enum {
2014-10-13 17:02:09 -07:00
IsAligned = ( ( int ( Options_ ) & Aligned ) = = Aligned ) ,
2016-01-19 17:05:10 -08:00
CoordAccess = true ,
RawAccess = true
2014-05-16 15:08:05 -07:00
} ;
2014-05-06 11:18:37 -07:00
2015-10-29 17:49:04 -07:00
EIGEN_DEVICE_FUNC
2019-08-28 17:46:05 -07:00
EIGEN_STRONG_INLINE TensorMap ( StoragePointerType dataPtr ) : m_data ( dataPtr ) , m_dimensions ( ) {
2015-10-29 17:49:04 -07:00
// The number of dimensions used to construct a tensor must be equal to the rank of the tensor.
EIGEN_STATIC_ASSERT ( ( 0 = = NumIndices | | NumIndices = = Dynamic ) , YOU_MADE_A_PROGRAMMING_MISTAKE )
}
2014-04-28 10:32:27 -07:00
template < typename . . . IndexTypes > EIGEN_DEVICE_FUNC
2019-08-28 17:46:05 -07:00
EIGEN_STRONG_INLINE TensorMap ( StoragePointerType dataPtr , Index firstDimension , IndexTypes . . . otherDimensions ) : m_data ( dataPtr ) , m_dimensions ( firstDimension , otherDimensions . . . ) {
2014-04-28 10:32:27 -07:00
// The number of dimensions used to construct a tensor must be equal to the rank of the tensor.
2014-10-13 17:02:09 -07:00
EIGEN_STATIC_ASSERT ( ( sizeof . . . ( otherDimensions ) + 1 = = NumIndices | | NumIndices = = Dynamic ) , YOU_MADE_A_PROGRAMMING_MISTAKE )
2014-04-28 10:32:27 -07:00
}
2019-08-28 17:46:05 -07:00
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE TensorMap ( StoragePointerType dataPtr , const array < Index , NumIndices > & dimensions )
2015-01-14 12:45:20 -08:00
: m_data ( dataPtr ) , m_dimensions ( dimensions )
{ }
2014-10-16 14:52:50 -07:00
template < typename Dimensions >
2019-08-28 17:46:05 -07:00
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE TensorMap ( StoragePointerType dataPtr , const Dimensions & dimensions )
2014-05-06 11:18:37 -07:00
: m_data ( dataPtr ) , m_dimensions ( dimensions )
{ }
2015-10-22 11:48:02 -07:00
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE TensorMap ( PlainObjectType & tensor )
: m_data ( tensor . data ( ) ) , m_dimensions ( tensor . dimensions ( ) )
{ }
2015-01-14 12:45:20 -08:00
EIGEN_DEVICE_FUNC
EIGEN_STRONG_INLINE Index rank ( ) const { return m_dimensions . rank ( ) ; }
2014-04-28 10:32:27 -07:00
EIGEN_DEVICE_FUNC
EIGEN_STRONG_INLINE Index dimension ( Index n ) const { return m_dimensions [ n ] ; }
EIGEN_DEVICE_FUNC
2014-05-22 16:22:35 -07:00
EIGEN_STRONG_INLINE const Dimensions & dimensions ( ) const { return m_dimensions ; }
2014-05-06 11:18:37 -07:00
EIGEN_DEVICE_FUNC
EIGEN_STRONG_INLINE Index size ( ) const { return m_dimensions . TotalSize ( ) ; }
2014-04-28 10:32:27 -07:00
EIGEN_DEVICE_FUNC
2019-08-28 17:46:05 -07:00
EIGEN_STRONG_INLINE StoragePointerType data ( ) { return m_data ; }
2014-04-28 10:32:27 -07:00
EIGEN_DEVICE_FUNC
2019-09-03 11:08:09 -07:00
EIGEN_STRONG_INLINE StoragePointerType data ( ) const { return m_data ; }
2014-04-28 10:32:27 -07:00
2014-05-16 15:08:05 -07:00
EIGEN_DEVICE_FUNC
2019-09-03 11:08:09 -07:00
EIGEN_STRONG_INLINE StorageRefType operator ( ) ( const array < Index , NumIndices > & indices ) const
2014-05-16 15:08:05 -07:00
{
// eigen_assert(checkIndexRange(indices));
if ( PlainObjectType : : Options & RowMajor ) {
const Index index = m_dimensions . IndexOfRowMajor ( indices ) ;
return m_data [ index ] ;
} else {
const Index index = m_dimensions . IndexOfColMajor ( indices ) ;
return m_data [ index ] ;
}
}
2015-10-29 17:49:04 -07:00
EIGEN_DEVICE_FUNC
2019-09-03 11:08:09 -07:00
EIGEN_STRONG_INLINE StorageRefType operator ( ) ( ) const
2015-10-29 17:49:04 -07:00
{
EIGEN_STATIC_ASSERT ( NumIndices = = 0 , YOU_MADE_A_PROGRAMMING_MISTAKE )
return m_data [ 0 ] ;
}
2016-02-10 08:02:04 -08:00
EIGEN_DEVICE_FUNC
2019-09-03 11:08:09 -07:00
EIGEN_STRONG_INLINE StorageRefType operator ( ) ( Index index ) const
2016-02-10 08:02:04 -08:00
{
eigen_internal_assert ( index > = 0 & & index < size ( ) ) ;
return m_data [ index ] ;
}
2014-05-16 15:08:05 -07:00
template < typename . . . IndexTypes > EIGEN_DEVICE_FUNC
2019-09-03 11:08:09 -07:00
EIGEN_STRONG_INLINE StorageRefType operator ( ) ( Index firstIndex , Index secondIndex , IndexTypes . . . otherIndices ) const
2014-05-16 15:08:05 -07:00
{
2016-02-10 08:02:04 -08:00
EIGEN_STATIC_ASSERT ( sizeof . . . ( otherIndices ) + 2 = = NumIndices , YOU_MADE_A_PROGRAMMING_MISTAKE )
2018-08-01 16:04:44 +01:00
eigen_assert ( internal : : all ( ( Eigen : : NumTraits < Index > : : highest ( ) > = otherIndices ) . . . ) ) ;
2014-05-16 15:08:05 -07:00
if ( PlainObjectType : : Options & RowMajor ) {
2016-02-10 08:02:04 -08:00
const Index index = m_dimensions . IndexOfRowMajor ( array < Index , NumIndices > { { firstIndex , secondIndex , otherIndices . . . } } ) ;
2014-05-16 15:08:05 -07:00
return m_data [ index ] ;
} else {
2016-02-10 08:02:04 -08:00
const Index index = m_dimensions . IndexOfColMajor ( array < Index , NumIndices > { { firstIndex , secondIndex , otherIndices . . . } } ) ;
2014-05-16 15:08:05 -07:00
return m_data [ index ] ;
}
}
EIGEN_DEVICE_FUNC
2019-08-28 17:46:05 -07:00
EIGEN_STRONG_INLINE StorageRefType operator ( ) ( const array < Index , NumIndices > & indices )
2014-05-16 15:08:05 -07:00
{
// eigen_assert(checkIndexRange(indices));
if ( PlainObjectType : : Options & RowMajor ) {
const Index index = m_dimensions . IndexOfRowMajor ( indices ) ;
return m_data [ index ] ;
} else {
const Index index = m_dimensions . IndexOfColMajor ( indices ) ;
return m_data [ index ] ;
}
}
2014-04-28 10:32:27 -07:00
2015-10-29 17:49:04 -07:00
EIGEN_DEVICE_FUNC
2019-08-28 17:46:05 -07:00
EIGEN_STRONG_INLINE StorageRefType operator ( ) ( )
2015-10-29 17:49:04 -07:00
{
EIGEN_STATIC_ASSERT ( NumIndices = = 0 , YOU_MADE_A_PROGRAMMING_MISTAKE )
return m_data [ 0 ] ;
}
2016-02-10 08:02:04 -08:00
EIGEN_DEVICE_FUNC
2019-08-28 17:46:05 -07:00
EIGEN_STRONG_INLINE StorageRefType operator ( ) ( Index index )
2016-02-10 08:02:04 -08:00
{
eigen_internal_assert ( index > = 0 & & index < size ( ) ) ;
return m_data [ index ] ;
}
2014-04-28 10:32:27 -07:00
template < typename . . . IndexTypes > EIGEN_DEVICE_FUNC
2019-08-28 17:46:05 -07:00
EIGEN_STRONG_INLINE StorageRefType operator ( ) ( Index firstIndex , Index secondIndex , IndexTypes . . . otherIndices )
2014-04-28 10:32:27 -07:00
{
2016-02-10 08:02:04 -08:00
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. " ) ;
2018-08-01 16:04:44 +01:00
eigen_assert ( internal : : all ( ( Eigen : : NumTraits < Index > : : highest ( ) > = otherIndices ) . . . ) ) ;
2016-02-10 08:02:04 -08:00
const std : : size_t NumDims = sizeof . . . ( otherIndices ) + 2 ;
2014-05-06 11:18:37 -07:00
if ( PlainObjectType : : Options & RowMajor ) {
2016-02-10 08:02:04 -08:00
const Index index = m_dimensions . IndexOfRowMajor ( array < Index , NumDims > { { firstIndex , secondIndex , otherIndices . . . } } ) ;
2014-05-06 11:18:37 -07:00
return m_data [ index ] ;
} else {
2016-02-10 08:02:04 -08:00
const Index index = m_dimensions . IndexOfColMajor ( array < Index , NumDims > { { firstIndex , secondIndex , otherIndices . . . } } ) ;
2014-05-06 11:18:37 -07:00
return m_data [ index ] ;
}
2014-04-28 10:32:27 -07:00
}
2020-11-12 15:59:29 -08:00
EIGEN_TENSOR_INHERIT_ASSIGNMENT_OPERATORS ( TensorMap )
2014-04-28 10:32:27 -07:00
private :
2019-08-28 17:46:05 -07:00
StoragePointerType m_data ;
2014-05-22 16:22:35 -07:00
Dimensions m_dimensions ;
2014-04-28 10:32:27 -07:00
} ;
} // end namespace Eigen
# endif // EIGEN_CXX11_TENSOR_TENSOR_MAP_H