Loading...
Searching...
No Matches
TensorGenerator.h
1// This file is part of Eigen, a lightweight C++ template library
2// for linear algebra.
3//
4// Copyright (C) 2015 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_GENERATOR_H
11#define EIGEN_CXX11_TENSOR_TENSOR_GENERATOR_H
12
13namespace Eigen {
14
15namespace internal {
16template<typename Generator, typename XprType>
17struct traits<TensorGeneratorOp<Generator, XprType> > : public traits<XprType>
18{
19 typedef typename XprType::Scalar Scalar;
20 typedef traits<XprType> XprTraits;
21 typedef typename XprTraits::StorageKind StorageKind;
22 typedef typename XprTraits::Index Index;
23 typedef typename XprType::Nested Nested;
24 typedef typename remove_reference<Nested>::type _Nested;
25 static const int NumDimensions = XprTraits::NumDimensions;
26 static const int Layout = XprTraits::Layout;
27};
28
29template<typename Generator, typename XprType>
30struct eval<TensorGeneratorOp<Generator, XprType>, Eigen::Dense>
31{
32 typedef const TensorGeneratorOp<Generator, XprType>& type;
33};
34
35template<typename Generator, typename XprType>
36struct nested<TensorGeneratorOp<Generator, XprType>, 1, typename eval<TensorGeneratorOp<Generator, XprType> >::type>
37{
38 typedef TensorGeneratorOp<Generator, XprType> type;
39};
40
41} // end namespace internal
42
48template <typename Generator, typename XprType>
49class TensorGeneratorOp : public TensorBase<TensorGeneratorOp<Generator, XprType>, ReadOnlyAccessors> {
50 public:
51 typedef typename Eigen::internal::traits<TensorGeneratorOp>::Scalar Scalar;
52 typedef typename Eigen::NumTraits<Scalar>::Real RealScalar;
53 typedef typename XprType::CoeffReturnType CoeffReturnType;
54 typedef typename Eigen::internal::nested<TensorGeneratorOp>::type Nested;
55 typedef typename Eigen::internal::traits<TensorGeneratorOp>::StorageKind StorageKind;
56 typedef typename Eigen::internal::traits<TensorGeneratorOp>::Index Index;
57
58 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE TensorGeneratorOp(const XprType& expr, const Generator& generator)
59 : m_xpr(expr), m_generator(generator) {}
60
61 EIGEN_DEVICE_FUNC
62 const Generator& generator() const { return m_generator; }
63
64 EIGEN_DEVICE_FUNC
65 const typename internal::remove_all<typename XprType::Nested>::type&
66 expression() const { return m_xpr; }
67
68 protected:
69 typename XprType::Nested m_xpr;
70 const Generator m_generator;
71};
72
73
74// Eval as rvalue
75template<typename Generator, typename ArgType, typename Device>
76struct TensorEvaluator<const TensorGeneratorOp<Generator, ArgType>, Device>
77{
79 typedef typename XprType::Index Index;
80 typedef typename TensorEvaluator<ArgType, Device>::Dimensions Dimensions;
81 static const int NumDims = internal::array_size<Dimensions>::value;
82 typedef typename XprType::Scalar Scalar;
83 typedef typename XprType::CoeffReturnType CoeffReturnType;
84 typedef typename PacketType<CoeffReturnType, Device>::type PacketReturnType;
85 enum {
86 IsAligned = false,
87 PacketAccess = (internal::unpacket_traits<PacketReturnType>::size > 1),
88 BlockAccess = false,
89 Layout = TensorEvaluator<ArgType, Device>::Layout,
90 CoordAccess = false, // to be implemented
91 RawAccess = false
92 };
93
94 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE TensorEvaluator(const XprType& op, const Device& device)
95 : m_generator(op.generator())
96 {
97 TensorEvaluator<ArgType, Device> impl(op.expression(), device);
98 m_dimensions = impl.dimensions();
99
100 if (static_cast<int>(Layout) == static_cast<int>(ColMajor)) {
101 m_strides[0] = 1;
102 for (int i = 1; i < NumDims; ++i) {
103 m_strides[i] = m_strides[i - 1] * m_dimensions[i - 1];
104 }
105 } else {
106 m_strides[NumDims - 1] = 1;
107 for (int i = NumDims - 2; i >= 0; --i) {
108 m_strides[i] = m_strides[i + 1] * m_dimensions[i + 1];
109 }
110 }
111 }
112
113 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const Dimensions& dimensions() const { return m_dimensions; }
114
115 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE bool evalSubExprsIfNeeded(Scalar* /*data*/) {
116 return true;
117 }
118 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE void cleanup() {
119 }
120
121 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE CoeffReturnType coeff(Index index) const
122 {
123 array<Index, NumDims> coords;
124 extract_coordinates(index, coords);
125 return m_generator(coords);
126 }
127
128 template<int LoadMode>
129 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE PacketReturnType packet(Index index) const
130 {
131 const int packetSize = internal::unpacket_traits<PacketReturnType>::size;
132 EIGEN_STATIC_ASSERT((packetSize > 1), YOU_MADE_A_PROGRAMMING_MISTAKE)
133 eigen_assert(index+packetSize-1 < dimensions().TotalSize());
134
135 EIGEN_ALIGN_MAX typename internal::remove_const<CoeffReturnType>::type values[packetSize];
136 for (int i = 0; i < packetSize; ++i) {
137 values[i] = coeff(index+i);
138 }
139 PacketReturnType rslt = internal::pload<PacketReturnType>(values);
140 return rslt;
141 }
142
143 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE TensorOpCost
144 costPerCoeff(bool) const {
145 // TODO(rmlarsen): This is just a placeholder. Define interface to make
146 // generators return their cost.
147 return TensorOpCost(0, 0, TensorOpCost::AddCost<Scalar>() +
148 TensorOpCost::MulCost<Scalar>());
149 }
150
151 EIGEN_DEVICE_FUNC Scalar* data() const { return NULL; }
152
153 protected:
154 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
155 void extract_coordinates(Index index, array<Index, NumDims>& coords) const {
156 if (static_cast<int>(Layout) == static_cast<int>(ColMajor)) {
157 for (int i = NumDims - 1; i > 0; --i) {
158 const Index idx = index / m_strides[i];
159 index -= idx * m_strides[i];
160 coords[i] = idx;
161 }
162 coords[0] = index;
163 } else {
164 for (int i = 0; i < NumDims - 1; ++i) {
165 const Index idx = index / m_strides[i];
166 index -= idx * m_strides[i];
167 coords[i] = idx;
168 }
169 coords[NumDims-1] = index;
170 }
171 }
172
173 Dimensions m_dimensions;
174 array<Index, NumDims> m_strides;
175 Generator m_generator;
176};
177
178} // end namespace Eigen
179
180#endif // EIGEN_CXX11_TENSOR_TENSOR_GENERATOR_H
The tensor base class.
Definition TensorForwardDeclarations.h:29
Tensor generator class.
Definition TensorGenerator.h:49
Namespace containing all symbols from the Eigen library.
EIGEN_DEFAULT_DENSE_INDEX_TYPE Index
The tensor evaluator class.
Definition TensorEvaluator.h:27
const Device & device() const
required by sycl in order to construct sycl buffer from raw pointer
Definition TensorEvaluator.h:112