TensorChipping.h
Go to the documentation of this file.
1 // This file is part of Eigen, a lightweight C++ template library
2 // for linear algebra.
3 //
4 // Copyright (C) 2014 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_CHIPPING_H
11 #define EIGEN_CXX11_TENSOR_TENSOR_CHIPPING_H
12 
13 namespace Eigen {
14 
23 namespace internal {
24 template<DenseIndex DimId, typename XprType>
25 struct traits<TensorChippingOp<DimId, XprType> > : public traits<XprType>
26 {
27  typedef typename XprType::Scalar Scalar;
29  typedef typename XprTraits::StorageKind StorageKind;
30  typedef typename XprTraits::Index Index;
31  typedef typename XprType::Nested Nested;
33  static const int NumDimensions = XprTraits::NumDimensions - 1;
34  static const int Layout = XprTraits::Layout;
35 };
36 
37 template<DenseIndex DimId, typename XprType>
38 struct eval<TensorChippingOp<DimId, XprType>, Eigen::Dense>
39 {
41 };
42 
43 template<DenseIndex DimId, typename XprType>
44 struct nested<TensorChippingOp<DimId, XprType>, 1, typename eval<TensorChippingOp<DimId, XprType> >::type>
45 {
47 };
48 
49 template <DenseIndex DimId>
51 {
53  eigen_assert(dim == DimId);
54  }
55  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE DenseIndex actualDim() const {
56  return DimId;
57  }
58 };
59 template <>
61 {
62  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE DimensionId(DenseIndex dim) : actual_dim(dim) {
63  eigen_assert(dim >= 0);
64  }
65  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE DenseIndex actualDim() const {
66  return actual_dim;
67  }
68  private:
70 };
71 
72 
73 } // end namespace internal
74 
75 
76 
77 template<DenseIndex DimId, typename XprType>
78 class TensorChippingOp : public TensorBase<TensorChippingOp<DimId, XprType> >
79 {
80  public:
83  typedef typename XprType::CoeffReturnType CoeffReturnType;
87 
88  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE TensorChippingOp(const XprType& expr, const Index offset, const Index dim)
89  : m_xpr(expr), m_offset(offset), m_dim(dim) {
90  }
91 
92  EIGEN_DEVICE_FUNC
93  const Index offset() const { return m_offset; }
94  EIGEN_DEVICE_FUNC
95  const Index dim() const { return m_dim.actualDim(); }
96 
97  EIGEN_DEVICE_FUNC
99  expression() const { return m_xpr; }
100 
101  EIGEN_DEVICE_FUNC
103  {
105  Assign assign(*this, other);
107  return *this;
108  }
109 
110  template<typename OtherDerived>
111  EIGEN_DEVICE_FUNC
112  EIGEN_STRONG_INLINE TensorChippingOp& operator = (const OtherDerived& other)
113  {
115  Assign assign(*this, other);
117  return *this;
118  }
119 
120  protected:
121  typename XprType::Nested m_xpr;
122  const Index m_offset;
124 };
125 
126 
127 // Eval as rvalue
128 template<DenseIndex DimId, typename ArgType, typename Device>
129 struct TensorEvaluator<const TensorChippingOp<DimId, ArgType>, Device>
130 {
133  static const int NumDims = NumInputDims-1;
134  typedef typename XprType::Index Index;
136  typedef typename XprType::Scalar Scalar;
140 
141 
142  enum {
143  // Alignment can't be guaranteed at compile time since it depends on the
144  // slice offsets.
145  IsAligned = false,
148  CoordAccess = false, // to be implemented
149  RawAccess = false
150  };
151 
152  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE TensorEvaluator(const XprType& op, const Device& device)
153  : m_impl(op.expression(), device), m_dim(op.dim()), m_device(device)
154  {
155  EIGEN_STATIC_ASSERT((NumInputDims >= 1), YOU_MADE_A_PROGRAMMING_MISTAKE);
156  eigen_assert(NumInputDims > m_dim.actualDim());
157 
158  const typename TensorEvaluator<ArgType, Device>::Dimensions& input_dims = m_impl.dimensions();
159  eigen_assert(op.offset() < input_dims[m_dim.actualDim()]);
160 
161  int j = 0;
162  for (int i = 0; i < NumInputDims; ++i) {
163  if (i != m_dim.actualDim()) {
164  m_dimensions[j] = input_dims[i];
165  ++j;
166  }
167  }
168 
169  m_stride = 1;
170  m_inputStride = 1;
171  if (static_cast<int>(Layout) == static_cast<int>(ColMajor)) {
172  for (int i = 0; i < m_dim.actualDim(); ++i) {
173  m_stride *= input_dims[i];
174  m_inputStride *= input_dims[i];
175  }
176  } else {
177  for (int i = NumInputDims-1; i > m_dim.actualDim(); --i) {
178  m_stride *= input_dims[i];
179  m_inputStride *= input_dims[i];
180  }
181  }
182  m_inputStride *= input_dims[m_dim.actualDim()];
183  m_inputOffset = m_stride * op.offset();
184  }
185 
186  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const Dimensions& dimensions() const { return m_dimensions; }
187 
188  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE bool evalSubExprsIfNeeded(Scalar* /*data*/) {
189  m_impl.evalSubExprsIfNeeded(NULL);
190  return true;
191  }
192 
193  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE void cleanup() {
194  m_impl.cleanup();
195  }
196 
197  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE CoeffReturnType coeff(Index index) const
198  {
199  return m_impl.coeff(srcCoeff(index));
200  }
201 
202  template<int LoadMode>
203  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE PacketReturnType packet(Index index) const
204  {
205  EIGEN_STATIC_ASSERT((PacketSize > 1), YOU_MADE_A_PROGRAMMING_MISTAKE)
206  eigen_assert(index+PacketSize-1 < dimensions().TotalSize());
207 
208  if ((static_cast<int>(Layout) == static_cast<int>(ColMajor) && m_dim.actualDim() == 0) ||
209  (static_cast<int>(Layout) == static_cast<int>(RowMajor) && m_dim.actualDim() == NumInputDims-1)) {
210  // m_stride is equal to 1, so let's avoid the integer division.
211  eigen_assert(m_stride == 1);
212  Index inputIndex = index * m_inputStride + m_inputOffset;
214  for (int i = 0; i < PacketSize; ++i) {
215  values[i] = m_impl.coeff(inputIndex);
216  inputIndex += m_inputStride;
217  }
218  PacketReturnType rslt = internal::pload<PacketReturnType>(values);
219  return rslt;
220  } else if ((static_cast<int>(Layout) == static_cast<int>(ColMajor) && m_dim.actualDim() == NumInputDims - 1) ||
221  (static_cast<int>(Layout) == static_cast<int>(RowMajor) && m_dim.actualDim() == 0)) {
222  // m_stride is aways greater than index, so let's avoid the integer division.
223  eigen_assert(m_stride > index);
224  return m_impl.template packet<LoadMode>(index + m_inputOffset);
225  } else {
226  const Index idx = index / m_stride;
227  const Index rem = index - idx * m_stride;
228  if (rem + PacketSize <= m_stride) {
229  Index inputIndex = idx * m_inputStride + m_inputOffset + rem;
230  return m_impl.template packet<LoadMode>(inputIndex);
231  } else {
232  // Cross the stride boundary. Fallback to slow path.
234  for (int i = 0; i < PacketSize; ++i) {
235  values[i] = coeff(index);
236  ++index;
237  }
238  PacketReturnType rslt = internal::pload<PacketReturnType>(values);
239  return rslt;
240  }
241  }
242  }
243 
244  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE TensorOpCost
245  costPerCoeff(bool vectorized) const {
246  double cost = 0;
247  if ((static_cast<int>(Layout) == static_cast<int>(ColMajor) &&
248  m_dim.actualDim() == 0) ||
249  (static_cast<int>(Layout) == static_cast<int>(RowMajor) &&
250  m_dim.actualDim() == NumInputDims - 1)) {
251  cost += TensorOpCost::MulCost<Index>() + TensorOpCost::AddCost<Index>();
252  } else if ((static_cast<int>(Layout) == static_cast<int>(ColMajor) &&
253  m_dim.actualDim() == NumInputDims - 1) ||
254  (static_cast<int>(Layout) == static_cast<int>(RowMajor) &&
255  m_dim.actualDim() == 0)) {
256  cost += TensorOpCost::AddCost<Index>();
257  } else {
258  cost += 3 * TensorOpCost::MulCost<Index>() + TensorOpCost::DivCost<Index>() +
259  3 * TensorOpCost::AddCost<Index>();
260  }
261 
262  return m_impl.costPerCoeff(vectorized) +
263  TensorOpCost(0, 0, cost, vectorized, PacketSize);
264  }
265 
266  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE CoeffReturnType* data() const {
267  CoeffReturnType* result = const_cast<CoeffReturnType*>(m_impl.data());
268  if (((static_cast<int>(Layout) == static_cast<int>(ColMajor) && m_dim.actualDim() == NumDims) ||
269  (static_cast<int>(Layout) == static_cast<int>(RowMajor) && m_dim.actualDim() == 0)) &&
270  result) {
271  return result + m_inputOffset;
272  } else {
273  return NULL;
274  }
275  }
276 
277  protected:
278  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Index srcCoeff(Index index) const
279  {
280  Index inputIndex;
281  if ((static_cast<int>(Layout) == static_cast<int>(ColMajor) && m_dim.actualDim() == 0) ||
282  (static_cast<int>(Layout) == static_cast<int>(RowMajor) && m_dim.actualDim() == NumInputDims-1)) {
283  // m_stride is equal to 1, so let's avoid the integer division.
284  eigen_assert(m_stride == 1);
285  inputIndex = index * m_inputStride + m_inputOffset;
286  } else if ((static_cast<int>(Layout) == static_cast<int>(ColMajor) && m_dim.actualDim() == NumInputDims-1) ||
287  (static_cast<int>(Layout) == static_cast<int>(RowMajor) && m_dim.actualDim() == 0)) {
288  // m_stride is aways greater than index, so let's avoid the integer division.
289  eigen_assert(m_stride > index);
290  inputIndex = index + m_inputOffset;
291  } else {
292  const Index idx = index / m_stride;
293  inputIndex = idx * m_inputStride + m_inputOffset;
294  index -= idx * m_stride;
295  inputIndex += index;
296  }
297  return inputIndex;
298  }
299 
300  Dimensions m_dimensions;
301  Index m_stride;
306  const Device& m_device;
307 };
308 
309 
310 // Eval as lvalue
311 template<DenseIndex DimId, typename ArgType, typename Device>
312 struct TensorEvaluator<TensorChippingOp<DimId, ArgType>, Device>
313  : public TensorEvaluator<const TensorChippingOp<DimId, ArgType>, Device>
314 {
318  static const int NumDims = NumInputDims-1;
319  typedef typename XprType::Index Index;
321  typedef typename XprType::Scalar Scalar;
325 
326  enum {
327  IsAligned = false,
329  RawAccess = false
330  };
331 
332  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE TensorEvaluator(const XprType& op, const Device& device)
333  : Base(op, device)
334  { }
335 
336  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE CoeffReturnType& coeffRef(Index index)
337  {
338  return this->m_impl.coeffRef(this->srcCoeff(index));
339  }
340 
341  template <int StoreMode> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
342  void writePacket(Index index, const PacketReturnType& x)
343  {
344  EIGEN_STATIC_ASSERT((PacketSize > 1), YOU_MADE_A_PROGRAMMING_MISTAKE)
345 
346  if ((static_cast<int>(this->Layout) == static_cast<int>(ColMajor) && this->m_dim.actualDim() == 0) ||
347  (static_cast<int>(this->Layout) == static_cast<int>(RowMajor) && this->m_dim.actualDim() == NumInputDims-1)) {
348  // m_stride is equal to 1, so let's avoid the integer division.
349  eigen_assert(this->m_stride == 1);
351  internal::pstore<CoeffReturnType, PacketReturnType>(values, x);
352  Index inputIndex = index * this->m_inputStride + this->m_inputOffset;
353  for (int i = 0; i < PacketSize; ++i) {
354  this->m_impl.coeffRef(inputIndex) = values[i];
355  inputIndex += this->m_inputStride;
356  }
357  } else if ((static_cast<int>(this->Layout) == static_cast<int>(ColMajor) && this->m_dim.actualDim() == NumInputDims-1) ||
358  (static_cast<int>(this->Layout) == static_cast<int>(RowMajor) && this->m_dim.actualDim() == 0)) {
359  // m_stride is aways greater than index, so let's avoid the integer division.
360  eigen_assert(this->m_stride > index);
361  this->m_impl.template writePacket<StoreMode>(index + this->m_inputOffset, x);
362  } else {
363  const Index idx = index / this->m_stride;
364  const Index rem = index - idx * this->m_stride;
365  if (rem + PacketSize <= this->m_stride) {
366  const Index inputIndex = idx * this->m_inputStride + this->m_inputOffset + rem;
367  this->m_impl.template writePacket<StoreMode>(inputIndex, x);
368  } else {
369  // Cross stride boundary. Fallback to slow path.
371  internal::pstore<CoeffReturnType, PacketReturnType>(values, x);
372  for (int i = 0; i < PacketSize; ++i) {
373  this->coeffRef(index) = values[i];
374  ++index;
375  }
376  }
377  }
378  }
379 };
380 
381 
382 } // end namespace Eigen
383 
384 #endif // EIGEN_CXX11_TENSOR_TENSOR_CHIPPING_H
SCALAR Scalar
Definition: bench_gemm.cpp:33
#define EIGEN_STRONG_INLINE
Definition: Macros.h:494
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const Dimensions & dimensions() const
Eigen::NumTraits< Scalar >::Real RealScalar
XprType::CoeffReturnType CoeffReturnType
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE DimensionId(DenseIndex dim)
Eigen::internal::traits< TensorChippingOp >::StorageKind StorageKind
leaf::MyValues values
set noclip points set clip one set noclip two set bar set border lt lw set xdata set ydata set zdata set x2data set y2data set boxwidth set dummy y set format x g set format y g set format x2 g set format y2 g set format z g set angles radians set nogrid set key title set key left top Right noreverse box linetype linewidth samplen spacing width set nolabel set noarrow set nologscale set logscale x set set pointsize set encoding default set nopolar set noparametric set set set set surface set nocontour set clabel set mapping cartesian set nohidden3d set cntrparam order set cntrparam linear set cntrparam levels auto set cntrparam points set size set set xzeroaxis lt lw set x2zeroaxis lt lw set yzeroaxis lt lw set y2zeroaxis lt lw set tics in set ticslevel set tics set mxtics default set mytics default set mx2tics default set my2tics default set xtics border mirror norotate autofreq set ytics border mirror norotate autofreq set ztics border nomirror norotate autofreq set nox2tics set noy2tics set timestamp bottom norotate offset
Namespace containing all symbols from the Eigen library.
Definition: jet.h:637
A cost model used to limit the number of threads used for evaluating tensor expression.
const mpreal rem(const mpreal &x, const mpreal &y, mp_rnd_t rnd_mode=mpreal::get_default_rnd())
Definition: mpreal.h:2409
#define EIGEN_STATIC_ASSERT(CONDITION, MSG)
Definition: StaticAssert.h:124
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE TensorEvaluator(const XprType &op, const Device &device)
vector< size_t > dimensions(L.begin(), L.end())
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE DenseIndex actualDim() const
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE PacketReturnType packet(Index index) const
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE TensorOpCost costPerCoeff(bool vectorized) const
const internal::DimensionId< DimId > m_dim
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE TensorEvaluator(const XprType &op, const Device &device)
Values result
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE CoeffReturnType coeff(Index index) const
EIGEN_DEFAULT_DENSE_INDEX_TYPE Index
The Index type as used for the API.
Definition: Meta.h:33
#define eigen_assert(x)
Definition: Macros.h:579
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE DenseIndex actualDim() const
Eigen::internal::traits< TensorChippingOp >::Index Index
static EIGEN_DEVICE_FUNC void run(const Expression &expr, const Device &device=Device())
TensorEvaluator< const TensorChippingOp< DimId, ArgType >, Device > Base
#define NULL
Definition: ccolamd.c:609
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE void writePacket(Index index, const PacketReturnType &x)
PacketType< CoeffReturnType, Device >::type PacketReturnType
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE CoeffReturnType * data() const
const mpreal dim(const mpreal &a, const mpreal &b, mp_rnd_t r=mpreal::get_default_rnd())
Definition: mpreal.h:2201
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Index srcCoeff(Index index) const
The tensor base class.
Definition: TensorBase.h:829
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE TensorChippingOp(const XprType &expr, const Index offset, const Index dim)
EIGEN_DEFAULT_DENSE_INDEX_TYPE DenseIndex
Definition: Meta.h:25
Eigen::internal::nested< TensorChippingOp >::type Nested
EIGEN_DEVICE_FUNC const Index dim() const
EIGEN_DEVICE_FUNC const Index offset() const
#define EIGEN_ALIGN_MAX
Definition: Macros.h:757
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE DimensionId(DenseIndex dim)
Eigen::internal::traits< TensorChippingOp >::Scalar Scalar
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE CoeffReturnType & coeffRef(Index index)
EIGEN_DEVICE_FUNC const internal::remove_all< typename XprType::Nested >::type & expression() const
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE bool evalSubExprsIfNeeded(Scalar *)
const int Dynamic
Definition: Constants.h:21
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const Dimensions & dimensions() const
set noclip points set clip one set noclip two set bar set border lt lw set xdata set ydata set zdata set x2data set y2data set boxwidth set dummy x
std::ptrdiff_t j


gtsam
Author(s):
autogenerated on Sat May 8 2021 02:45:15