10#ifndef EIGEN_CXX11_TENSOR_TENSOR_MORPHING_H
11#define EIGEN_CXX11_TENSOR_TENSOR_MORPHING_H
16template<
typename NewDimensions,
typename XprType>
17struct traits<TensorReshapingOp<NewDimensions, XprType> > :
public traits<XprType>
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 = array_size<NewDimensions>::value;
26 static const int Layout = XprTraits::Layout;
29template<
typename NewDimensions,
typename XprType>
30struct eval<TensorReshapingOp<NewDimensions, XprType>, Eigen::Dense>
32 typedef const TensorReshapingOp<NewDimensions, XprType>& type;
35template<
typename NewDimensions,
typename XprType>
36struct nested<TensorReshapingOp<NewDimensions, XprType>, 1, typename eval<TensorReshapingOp<NewDimensions, XprType> >::type>
38 typedef TensorReshapingOp<NewDimensions, XprType> type;
48template <
typename NewDimensions,
typename XprType>
49class TensorReshapingOp :
public TensorBase<TensorReshapingOp<NewDimensions, XprType>, WriteAccessors>
53 typedef typename Eigen::internal::traits<TensorReshapingOp>::Scalar Scalar;
54 typedef typename internal::remove_const<typename XprType::CoeffReturnType>::type CoeffReturnType;
55 typedef typename Eigen::internal::nested<TensorReshapingOp>::type Nested;
56 typedef typename Eigen::internal::traits<TensorReshapingOp>::StorageKind StorageKind;
57 typedef typename Eigen::internal::traits<TensorReshapingOp>::Index Index;
59 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE TensorReshapingOp(
const XprType& expr,
const NewDimensions& dims)
60 : m_xpr(expr), m_dims(dims) {}
63 const NewDimensions& dimensions()
const {
return m_dims; }
66 const typename internal::remove_all<typename XprType::Nested>::type&
67 expression()
const {
return m_xpr; }
70 EIGEN_STRONG_INLINE TensorReshapingOp& operator = (
const TensorReshapingOp& other)
73 Assign assign(*
this, other);
74 internal::TensorExecutor<const Assign, DefaultDevice>::run(assign, DefaultDevice());
78 template<
typename OtherDerived>
80 EIGEN_STRONG_INLINE TensorReshapingOp& operator = (
const OtherDerived& other)
83 Assign assign(*
this, other);
84 internal::TensorExecutor<const Assign, DefaultDevice>::run(assign, DefaultDevice());
89 typename XprType::Nested m_xpr;
90 const NewDimensions m_dims;
95template<
typename NewDimensions,
typename ArgType,
typename Device>
102 IsAligned = TensorEvaluator<ArgType, Device>::IsAligned,
103 PacketAccess = TensorEvaluator<ArgType, Device>::PacketAccess,
104 Layout = TensorEvaluator<ArgType, Device>::Layout,
109 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE TensorEvaluator(
const XprType& op,
const Device&
device)
110 : m_impl(op.expression(),
device), m_dimensions(op.dimensions())
114 eigen_assert(internal::array_prod(m_impl.dimensions()) == internal::array_prod(op.dimensions()));
117 typedef typename XprType::Index Index;
118 typedef typename XprType::Scalar Scalar;
119 typedef typename XprType::CoeffReturnType CoeffReturnType;
120 typedef typename PacketType<CoeffReturnType, Device>::type PacketReturnType;
122 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
const Dimensions& dimensions()
const {
return m_dimensions; }
124 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
bool evalSubExprsIfNeeded(CoeffReturnType* data) {
125 return m_impl.evalSubExprsIfNeeded(data);
127 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
void cleanup() {
131 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE CoeffReturnType coeff(Index index)
const
133 return m_impl.coeff(index);
136 template<
int LoadMode>
137 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE PacketReturnType packet(Index index)
const
139 return m_impl.template packet<LoadMode>(index);
142 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE TensorOpCost costPerCoeff(
bool vectorized)
const {
143 return m_impl.costPerCoeff(vectorized);
146 EIGEN_DEVICE_FUNC Scalar* data()
const {
return const_cast<Scalar*
>(m_impl.data()); }
148 EIGEN_DEVICE_FUNC
const TensorEvaluator<ArgType, Device>& impl()
const {
return m_impl; }
151 TensorEvaluator<ArgType, Device> m_impl;
152 NewDimensions m_dimensions;
157template<
typename NewDimensions,
typename ArgType,
typename Device>
159 :
public TensorEvaluator<const TensorReshapingOp<NewDimensions, ArgType>, Device>
162 typedef TensorEvaluator<const TensorReshapingOp<NewDimensions, ArgType>, Device> Base;
163 typedef TensorReshapingOp<NewDimensions, ArgType> XprType;
164 typedef NewDimensions Dimensions;
167 IsAligned = TensorEvaluator<ArgType, Device>::IsAligned,
168 PacketAccess = TensorEvaluator<ArgType, Device>::PacketAccess,
169 Layout = TensorEvaluator<ArgType, Device>::Layout,
171 RawAccess = TensorEvaluator<ArgType, Device>::RawAccess
174 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE TensorEvaluator(
const XprType& op,
const Device&
device)
178 typedef typename XprType::Index Index;
179 typedef typename XprType::Scalar Scalar;
180 typedef typename XprType::CoeffReturnType CoeffReturnType;
181 typedef typename PacketType<CoeffReturnType, Device>::type PacketReturnType;
183 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE CoeffReturnType& coeffRef(Index index)
185 return this->m_impl.coeffRef(index);
187 template <
int StoreMode> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
188 void writePacket(Index index,
const PacketReturnType& x)
190 this->m_impl.template writePacket<StoreMode>(index, x);
203template<
typename StartIndices,
typename Sizes,
typename XprType>
204struct traits<TensorSlicingOp<StartIndices, Sizes, XprType> > :
public traits<XprType>
206 typedef typename XprType::Scalar Scalar;
207 typedef traits<XprType> XprTraits;
208 typedef typename XprTraits::StorageKind StorageKind;
209 typedef typename XprTraits::Index Index;
210 typedef typename XprType::Nested Nested;
211 typedef typename remove_reference<Nested>::type _Nested;
212 static const int NumDimensions = array_size<StartIndices>::value;
213 static const int Layout = XprTraits::Layout;
216template<
typename StartIndices,
typename Sizes,
typename XprType>
217struct eval<TensorSlicingOp<StartIndices, Sizes, XprType>,
Eigen::Dense>
219 typedef const TensorSlicingOp<StartIndices, Sizes, XprType>& type;
222template<
typename StartIndices,
typename Sizes,
typename XprType>
223struct nested<TensorSlicingOp<StartIndices, Sizes, XprType>, 1, typename eval<TensorSlicingOp<StartIndices, Sizes, XprType> >::type>
225 typedef TensorSlicingOp<StartIndices, Sizes, XprType> type;
232template<
typename StartIndices,
typename Sizes,
typename XprType>
233class TensorSlicingOp :
public TensorBase<TensorSlicingOp<StartIndices, Sizes, XprType> >
236 typedef typename Eigen::internal::traits<TensorSlicingOp>::Scalar Scalar;
237 typedef typename XprType::CoeffReturnType CoeffReturnType;
238 typedef typename Eigen::internal::nested<TensorSlicingOp>::type Nested;
239 typedef typename Eigen::internal::traits<TensorSlicingOp>::StorageKind StorageKind;
240 typedef typename Eigen::internal::traits<TensorSlicingOp>::Index Index;
242 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE TensorSlicingOp(
const XprType& expr,
const StartIndices& indices,
const Sizes& sizes)
243 : m_xpr(expr), m_indices(indices), m_sizes(sizes) {}
246 const StartIndices& startIndices()
const {
return m_indices; }
248 const Sizes& sizes()
const {
return m_sizes; }
251 const typename internal::remove_all<typename XprType::Nested>::type&
252 expression()
const {
return m_xpr; }
254 template<
typename OtherDerived>
256 EIGEN_STRONG_INLINE TensorSlicingOp& operator = (
const OtherDerived& other)
258 typedef TensorAssignOp<TensorSlicingOp, const OtherDerived> Assign;
259 Assign assign(*
this, other);
260 internal::TensorExecutor<const Assign, DefaultDevice>::run(assign, DefaultDevice());
265 EIGEN_STRONG_INLINE TensorSlicingOp& operator = (
const TensorSlicingOp& other)
267 typedef TensorAssignOp<TensorSlicingOp, const TensorSlicingOp> Assign;
268 Assign assign(*
this, other);
269 internal::TensorExecutor<const Assign, DefaultDevice>::run(assign, DefaultDevice());
275 typename XprType::Nested m_xpr;
276 const StartIndices m_indices;
283template <
typename Index,
typename Device>
struct MemcpyTriggerForSlicing {
284 EIGEN_DEVICE_FUNC MemcpyTriggerForSlicing(
const Device& device) : threshold_(2 * device.numThreads()) { }
285 EIGEN_DEVICE_FUNC
bool operator ()(
Index val)
const {
return val > threshold_; }
294template <
typename Index>
struct MemcpyTriggerForSlicing<
Index, GpuDevice> {
295 EIGEN_DEVICE_FUNC MemcpyTriggerForSlicing(
const GpuDevice&) { }
296 EIGEN_DEVICE_FUNC
bool operator ()(
Index val)
const {
return val > 4*1024*1024; }
302template<
typename StartIndices,
typename Sizes,
typename ArgType,
typename Device>
303struct TensorEvaluator<const TensorSlicingOp<StartIndices, Sizes, ArgType>, Device>
305 typedef TensorSlicingOp<StartIndices, Sizes, ArgType> XprType;
306 static const int NumDims = internal::array_size<Sizes>::value;
312 PacketAccess = TensorEvaluator<ArgType, Device>::PacketAccess,
313 Layout = TensorEvaluator<ArgType, Device>::Layout,
318 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE TensorEvaluator(
const XprType& op,
const Device&
device)
319 : m_impl(op.expression(),
device), m_device(
device), m_dimensions(op.sizes()), m_offsets(op.startIndices())
321 for (std::size_t i = 0; i < internal::array_size<Dimensions>::value; ++i) {
322 eigen_assert(m_impl.dimensions()[i] >= op.sizes()[i] + op.startIndices()[i]);
325 const typename TensorEvaluator<ArgType, Device>::Dimensions& input_dims = m_impl.dimensions();
326 const Sizes& output_dims = op.sizes();
327 if (
static_cast<int>(Layout) ==
static_cast<int>(
ColMajor)) {
328 m_inputStrides[0] = 1;
329 for (
int i = 1; i < NumDims; ++i) {
330 m_inputStrides[i] = m_inputStrides[i-1] * input_dims[i-1];
334 m_outputStrides[0] = 1;
335 for (
int i = 1; i < NumDims; ++i) {
336 m_outputStrides[i] = m_outputStrides[i-1] * output_dims[i-1];
337 m_fastOutputStrides[i] = internal::TensorIntDivisor<Index>(m_outputStrides[i]);
340 m_inputStrides[NumDims-1] = 1;
341 for (
int i = NumDims - 2; i >= 0; --i) {
342 m_inputStrides[i] = m_inputStrides[i+1] * input_dims[i+1];
346 m_outputStrides[NumDims-1] = 1;
347 for (
int i = NumDims - 2; i >= 0; --i) {
348 m_outputStrides[i] = m_outputStrides[i+1] * output_dims[i+1];
349 m_fastOutputStrides[i] = internal::TensorIntDivisor<Index>(m_outputStrides[i]);
354 typedef typename XprType::Index Index;
355 typedef typename XprType::Scalar Scalar;
356 typedef typename XprType::CoeffReturnType CoeffReturnType;
357 typedef typename PacketType<CoeffReturnType, Device>::type PacketReturnType;
358 typedef Sizes Dimensions;
360 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
const Dimensions& dimensions()
const {
return m_dimensions; }
363 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
bool evalSubExprsIfNeeded(CoeffReturnType* data) {
364 m_impl.evalSubExprsIfNeeded(NULL);
365 if (!NumTraits<
typename internal::remove_const<Scalar>::type>::RequireInitialization && data && m_impl.data()) {
366 Index contiguous_values = 1;
367 if (
static_cast<int>(Layout) ==
static_cast<int>(
ColMajor)) {
368 for (
int i = 0; i < NumDims; ++i) {
369 contiguous_values *= dimensions()[i];
370 if (dimensions()[i] != m_impl.dimensions()[i]) {
375 for (
int i = NumDims-1; i >= 0; --i) {
376 contiguous_values *= dimensions()[i];
377 if (dimensions()[i] != m_impl.dimensions()[i]) {
383 const MemcpyTriggerForSlicing<Index, Device> trigger(m_device);
384 if (trigger(contiguous_values)) {
385 Scalar* src = (Scalar*)m_impl.data();
386 for (
int i = 0; i < internal::array_prod(dimensions()); i += contiguous_values) {
387 Index offset = srcCoeff(i);
388 m_device.memcpy((
void*)(data+i), src+offset, contiguous_values *
sizeof(Scalar));
396 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
void cleanup() {
400 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE CoeffReturnType coeff(Index index)
const
402 return m_impl.coeff(srcCoeff(index));
405 template<
int LoadMode>
406 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE PacketReturnType packet(Index index)
const
408 const int packetSize = internal::unpacket_traits<PacketReturnType>::size;
409 EIGEN_STATIC_ASSERT((packetSize > 1), YOU_MADE_A_PROGRAMMING_MISTAKE)
410 eigen_assert(index+packetSize-1 < internal::array_prod(dimensions()));
412 Index inputIndices[] = {0, 0};
413 Index indices[] = {index, index + packetSize - 1};
414 if (
static_cast<int>(Layout) ==
static_cast<int>(
ColMajor)) {
415 for (
int i = NumDims - 1; i > 0; --i) {
416 const Index idx0 = indices[0] / m_fastOutputStrides[i];
417 const Index idx1 = indices[1] / m_fastOutputStrides[i];
418 inputIndices[0] += (idx0 + m_offsets[i]) * m_inputStrides[i];
419 inputIndices[1] += (idx1 + m_offsets[i]) * m_inputStrides[i];
420 indices[0] -= idx0 * m_outputStrides[i];
421 indices[1] -= idx1 * m_outputStrides[i];
423 inputIndices[0] += (indices[0] + m_offsets[0]);
424 inputIndices[1] += (indices[1] + m_offsets[0]);
426 for (
int i = 0; i < NumDims - 1; ++i) {
427 const Index idx0 = indices[0] / m_fastOutputStrides[i];
428 const Index idx1 = indices[1] / m_fastOutputStrides[i];
429 inputIndices[0] += (idx0 + m_offsets[i]) * m_inputStrides[i];
430 inputIndices[1] += (idx1 + m_offsets[i]) * m_inputStrides[i];
431 indices[0] -= idx0 * m_outputStrides[i];
432 indices[1] -= idx1 * m_outputStrides[i];
434 inputIndices[0] += (indices[0] + m_offsets[NumDims-1]);
435 inputIndices[1] += (indices[1] + m_offsets[NumDims-1]);
437 if (inputIndices[1] - inputIndices[0] == packetSize - 1) {
438 PacketReturnType rslt = m_impl.template packet<Unaligned>(inputIndices[0]);
442 EIGEN_ALIGN_MAX
typename internal::remove_const<CoeffReturnType>::type values[packetSize];
443 values[0] = m_impl.coeff(inputIndices[0]);
444 values[packetSize-1] = m_impl.coeff(inputIndices[1]);
445 for (
int i = 1; i < packetSize-1; ++i) {
446 values[i] = coeff(index+i);
448 PacketReturnType rslt = internal::pload<PacketReturnType>(values);
453 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE TensorOpCost costPerCoeff(
bool vectorized)
const {
454 return m_impl.costPerCoeff(vectorized) + TensorOpCost(0, 0, NumDims);
458 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Scalar* data()
const {
459 Scalar* result = m_impl.data();
462 if (
static_cast<int>(Layout) ==
static_cast<int>(
ColMajor)) {
463 for (
int i = 0; i < NumDims; ++i) {
464 if (m_dimensions[i] != m_impl.dimensions()[i]) {
465 offset += m_offsets[i] * m_inputStrides[i];
466 for (
int j = i+1; j < NumDims; ++j) {
467 if (m_dimensions[j] > 1) {
470 offset += m_offsets[j] * m_inputStrides[j];
476 for (
int i = NumDims - 1; i >= 0; --i) {
477 if (m_dimensions[i] != m_impl.dimensions()[i]) {
478 offset += m_offsets[i] * m_inputStrides[i];
479 for (
int j = i-1; j >= 0; --j) {
480 if (m_dimensions[j] > 1) {
483 offset += m_offsets[j] * m_inputStrides[j];
489 return result + offset;
495 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Index srcCoeff(Index index)
const
497 Index inputIndex = 0;
498 if (
static_cast<int>(Layout) ==
static_cast<int>(
ColMajor)) {
499 for (
int i = NumDims - 1; i > 0; --i) {
500 const Index idx = index / m_fastOutputStrides[i];
501 inputIndex += (idx + m_offsets[i]) * m_inputStrides[i];
502 index -= idx * m_outputStrides[i];
504 inputIndex += (index + m_offsets[0]);
506 for (
int i = 0; i < NumDims - 1; ++i) {
507 const Index idx = index / m_fastOutputStrides[i];
508 inputIndex += (idx + m_offsets[i]) * m_inputStrides[i];
509 index -= idx * m_outputStrides[i];
511 inputIndex += (index + m_offsets[NumDims-1]);
516 array<Index, NumDims> m_outputStrides;
517 array<internal::TensorIntDivisor<Index>, NumDims> m_fastOutputStrides;
518 array<Index, NumDims> m_inputStrides;
519 TensorEvaluator<ArgType, Device> m_impl;
520 const Device& m_device;
521 Dimensions m_dimensions;
522 const StartIndices m_offsets;
527template<
typename StartIndices,
typename Sizes,
typename ArgType,
typename Device>
528struct TensorEvaluator<TensorSlicingOp<StartIndices, Sizes, ArgType>, Device>
529 :
public TensorEvaluator<const TensorSlicingOp<StartIndices, Sizes, ArgType>, Device>
531 typedef TensorEvaluator<const TensorSlicingOp<StartIndices, Sizes, ArgType>, Device> Base;
532 typedef TensorSlicingOp<StartIndices, Sizes, ArgType> XprType;
533 static const int NumDims = internal::array_size<Sizes>::value;
537 PacketAccess = TensorEvaluator<ArgType, Device>::PacketAccess,
538 Layout = TensorEvaluator<ArgType, Device>::Layout,
543 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE TensorEvaluator(
const XprType& op,
const Device&
device)
547 typedef typename XprType::Index Index;
548 typedef typename XprType::Scalar Scalar;
549 typedef typename XprType::CoeffReturnType CoeffReturnType;
550 typedef typename PacketType<CoeffReturnType, Device>::type PacketReturnType;
551 typedef Sizes Dimensions;
553 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE CoeffReturnType& coeffRef(Index index)
555 return this->m_impl.coeffRef(this->srcCoeff(index));
558 template <
int StoreMode> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
559 void writePacket(Index index,
const PacketReturnType& x)
561 const int packetSize = internal::unpacket_traits<PacketReturnType>::size;
562 Index inputIndices[] = {0, 0};
563 Index indices[] = {index, index + packetSize - 1};
564 if (
static_cast<int>(Layout) ==
static_cast<int>(
ColMajor)) {
565 for (
int i = NumDims - 1; i > 0; --i) {
566 const Index idx0 = indices[0] / this->m_fastOutputStrides[i];
567 const Index idx1 = indices[1] / this->m_fastOutputStrides[i];
568 inputIndices[0] += (idx0 + this->m_offsets[i]) * this->m_inputStrides[i];
569 inputIndices[1] += (idx1 + this->m_offsets[i]) * this->m_inputStrides[i];
570 indices[0] -= idx0 * this->m_outputStrides[i];
571 indices[1] -= idx1 * this->m_outputStrides[i];
573 inputIndices[0] += (indices[0] + this->m_offsets[0]);
574 inputIndices[1] += (indices[1] + this->m_offsets[0]);
576 for (
int i = 0; i < NumDims - 1; ++i) {
577 const Index idx0 = indices[0] / this->m_fastOutputStrides[i];
578 const Index idx1 = indices[1] / this->m_fastOutputStrides[i];
579 inputIndices[0] += (idx0 + this->m_offsets[i]) * this->m_inputStrides[i];
580 inputIndices[1] += (idx1 + this->m_offsets[i]) * this->m_inputStrides[i];
581 indices[0] -= idx0 * this->m_outputStrides[i];
582 indices[1] -= idx1 * this->m_outputStrides[i];
584 inputIndices[0] += (indices[0] + this->m_offsets[NumDims-1]);
585 inputIndices[1] += (indices[1] + this->m_offsets[NumDims-1]);
587 if (inputIndices[1] - inputIndices[0] == packetSize - 1) {
588 this->m_impl.template writePacket<StoreMode>(inputIndices[0], x);
591 EIGEN_ALIGN_MAX CoeffReturnType values[packetSize];
592 internal::pstore<CoeffReturnType, PacketReturnType>(values, x);
593 this->m_impl.coeffRef(inputIndices[0]) = values[0];
594 this->m_impl.coeffRef(inputIndices[1]) = values[packetSize-1];
595 for (
int i = 1; i < packetSize-1; ++i) {
596 this->coeffRef(index+i) = values[i];
605template<
typename StartIndices,
typename StopIndices,
typename Str
ides,
typename XprType>
606struct traits<TensorStridingSlicingOp<StartIndices, StopIndices, Strides, XprType> > :
public traits<XprType>
608 typedef typename XprType::Scalar Scalar;
609 typedef traits<XprType> XprTraits;
610 typedef typename XprTraits::StorageKind StorageKind;
611 typedef typename XprTraits::Index
Index;
612 typedef typename XprType::Nested Nested;
613 typedef typename remove_reference<Nested>::type _Nested;
614 static const int NumDimensions = array_size<StartIndices>::value;
615 static const int Layout = XprTraits::Layout;
618template<
typename StartIndices,
typename StopIndices,
typename Str
ides,
typename XprType>
619struct eval<TensorStridingSlicingOp<StartIndices, StopIndices, Strides, XprType>, Eigen::Dense>
621 typedef const TensorStridingSlicingOp<StartIndices, StopIndices, Strides, XprType>& type;
624template<
typename StartIndices,
typename StopIndices,
typename Str
ides,
typename XprType>
625struct nested<TensorStridingSlicingOp<StartIndices, StopIndices, Strides, XprType>, 1, typename eval<TensorStridingSlicingOp<StartIndices, StopIndices, Strides, XprType> >::type>
627 typedef TensorStridingSlicingOp<StartIndices, StopIndices, Strides, XprType> type;
633template<
typename StartIndices,
typename StopIndices,
typename Str
ides,
typename XprType>
634class TensorStridingSlicingOp :
public TensorBase<TensorStridingSlicingOp<StartIndices, StopIndices, Strides, XprType> >
637 typedef typename internal::traits<TensorStridingSlicingOp>::Scalar Scalar;
638 typedef typename XprType::CoeffReturnType CoeffReturnType;
639 typedef typename internal::nested<TensorStridingSlicingOp>::type Nested;
640 typedef typename internal::traits<TensorStridingSlicingOp>::StorageKind StorageKind;
641 typedef typename internal::traits<TensorStridingSlicingOp>::Index Index;
643 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE TensorStridingSlicingOp(
644 const XprType& expr,
const StartIndices& startIndices,
645 const StopIndices& stopIndices,
const Strides& strides)
646 : m_xpr(expr), m_startIndices(startIndices), m_stopIndices(stopIndices),
647 m_strides(strides) {}
650 const StartIndices& startIndices()
const {
return m_startIndices; }
652 const StartIndices& stopIndices()
const {
return m_stopIndices; }
654 const StartIndices& strides()
const {
return m_strides; }
657 const typename internal::remove_all<typename XprType::Nested>::type&
658 expression()
const {
return m_xpr; }
661 EIGEN_STRONG_INLINE TensorStridingSlicingOp& operator = (
const TensorStridingSlicingOp& other)
663 typedef TensorAssignOp<TensorStridingSlicingOp, const TensorStridingSlicingOp> Assign;
664 Assign assign(*
this, other);
665 internal::TensorExecutor<const Assign, DefaultDevice>::run(
666 assign, DefaultDevice());
670 template<
typename OtherDerived>
672 EIGEN_STRONG_INLINE TensorStridingSlicingOp& operator = (
const OtherDerived& other)
674 typedef TensorAssignOp<TensorStridingSlicingOp, const OtherDerived> Assign;
675 Assign assign(*
this, other);
676 internal::TensorExecutor<const Assign, DefaultDevice>::run(
677 assign, DefaultDevice());
682 typename XprType::Nested m_xpr;
683 const StartIndices m_startIndices;
684 const StopIndices m_stopIndices;
685 const Strides m_strides;
689template<
typename StartIndices,
typename StopIndices,
typename Str
ides,
typename ArgType,
typename Device>
690struct TensorEvaluator<const TensorStridingSlicingOp<StartIndices, StopIndices, Strides, ArgType>, Device>
692 typedef TensorStridingSlicingOp<StartIndices, StopIndices, Strides, ArgType> XprType;
693 static const int NumDims = internal::array_size<Strides>::value;
699 PacketAccess =
false,
701 Layout = TensorEvaluator<ArgType, Device>::Layout,
705 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE TensorEvaluator(
const XprType& op,
const Device&
device)
706 : m_impl(op.expression(),
device), m_device(
device), m_strides(op.strides())
709 DSizes<Index,NumDims> startIndicesClamped, stopIndicesClamped;
710 for (
size_t i = 0; i < internal::array_size<Dimensions>::value; ++i) {
711 eigen_assert(m_strides[i] != 0 &&
"0 stride is invalid");
713 startIndicesClamped[i] = clamp(op.startIndices()[i], 0, m_impl.dimensions()[i]);
714 stopIndicesClamped[i] = clamp(op.stopIndices()[i], 0, m_impl.dimensions()[i]);
717 startIndicesClamped[i] = clamp(op.startIndices()[i], -1, m_impl.dimensions()[i] - 1);
718 stopIndicesClamped[i] = clamp(op.stopIndices()[i], -1, m_impl.dimensions()[i] - 1);
720 m_startIndices[i] = startIndicesClamped[i];
723 const typename TensorEvaluator<ArgType, Device>::Dimensions& input_dims = m_impl.dimensions();
726 bool degenerate =
false;;
727 for(
int i = 0; i < NumDims; i++){
728 Index interval = stopIndicesClamped[i] - startIndicesClamped[i];
729 if(interval == 0 || ((interval<0) != (m_strides[i]<0))){
733 m_dimensions[i] = interval / m_strides[i]
734 + (interval % m_strides[i] != 0 ? 1 : 0);
735 eigen_assert(m_dimensions[i] >= 0);
738 Strides output_dims = m_dimensions;
740 if (
static_cast<int>(Layout) ==
static_cast<int>(
ColMajor)) {
741 m_inputStrides[0] = m_strides[0];
742 m_offsets[0] = startIndicesClamped[0];
743 Index previousDimProduct = 1;
744 for (
int i = 1; i < NumDims; ++i) {
745 previousDimProduct *= input_dims[i-1];
746 m_inputStrides[i] = previousDimProduct * m_strides[i];
747 m_offsets[i] = startIndicesClamped[i] * previousDimProduct;
751 m_outputStrides[0] = 1;
752 for (
int i = 1; i < NumDims; ++i) {
753 m_outputStrides[i] = m_outputStrides[i-1] * output_dims[i-1];
755 m_fastOutputStrides[i] = internal::TensorIntDivisor<Index>(degenerate ? 1 : m_outputStrides[i]);
758 m_inputStrides[NumDims-1] = m_strides[NumDims-1];
759 m_offsets[NumDims-1] = startIndicesClamped[NumDims-1];
760 Index previousDimProduct = 1;
761 for (
int i = NumDims - 2; i >= 0; --i) {
762 previousDimProduct *= input_dims[i+1];
763 m_inputStrides[i] = previousDimProduct * m_strides[i];
764 m_offsets[i] = startIndicesClamped[i] * previousDimProduct;
767 m_outputStrides[NumDims-1] = 1;
768 for (
int i = NumDims - 2; i >= 0; --i) {
769 m_outputStrides[i] = m_outputStrides[i+1] * output_dims[i+1];
771 m_fastOutputStrides[i] = internal::TensorIntDivisor<Index>(degenerate ? 1 : m_outputStrides[i]);
774 m_block_total_size_max = numext::maxi(
static_cast<std::size_t
>(1),
775 device.lastLevelCacheSize() /
779 typedef typename XprType::Index Index;
780 typedef typename XprType::Scalar Scalar;
781 typedef typename internal::remove_const<Scalar>::type ScalarNonConst;
782 typedef typename XprType::CoeffReturnType CoeffReturnType;
783 typedef typename PacketType<CoeffReturnType, Device>::type PacketReturnType;
784 typedef Strides Dimensions;
786 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
const Dimensions& dimensions()
const {
return m_dimensions; }
789 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
bool evalSubExprsIfNeeded(CoeffReturnType*) {
790 m_impl.evalSubExprsIfNeeded(NULL);
794 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
void cleanup() {
798 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE CoeffReturnType coeff(Index index)
const
800 return m_impl.coeff(srcCoeff(index));
803 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE TensorOpCost costPerCoeff(
bool vectorized)
const {
804 return m_impl.costPerCoeff(vectorized) + TensorOpCost(0, 0, NumDims);
807 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Scalar* data()
const {
812 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Index srcCoeff(Index index)
const
814 Index inputIndex = 0;
815 if (
static_cast<int>(Layout) ==
static_cast<int>(
ColMajor)) {
816 for (
int i = NumDims - 1; i >= 0; --i) {
817 const Index idx = index / m_fastOutputStrides[i];
818 inputIndex += idx * m_inputStrides[i] + m_offsets[i];
819 index -= idx * m_outputStrides[i];
822 for (
int i = 0; i < NumDims; ++i) {
823 const Index idx = index / m_fastOutputStrides[i];
824 inputIndex += idx * m_inputStrides[i] + m_offsets[i];
825 index -= idx * m_outputStrides[i];
831 static EIGEN_STRONG_INLINE Index clamp(Index value, Index min, Index max) {
832 return numext::maxi(min, numext::mini(max,value));
835 array<Index, NumDims> m_outputStrides;
836 array<internal::TensorIntDivisor<Index>, NumDims> m_fastOutputStrides;
837 array<Index, NumDims> m_inputStrides;
838 TensorEvaluator<ArgType, Device> m_impl;
839 const Device& m_device;
840 DSizes<Index, NumDims> m_startIndices;
841 DSizes<Index, NumDims> m_dimensions;
842 DSizes<Index, NumDims> m_offsets;
843 const Strides m_strides;
844 std::size_t m_block_total_size_max;
848template<
typename StartIndices,
typename StopIndices,
typename Str
ides,
typename ArgType,
typename Device>
849struct TensorEvaluator<TensorStridingSlicingOp<StartIndices, StopIndices, Strides, ArgType>, Device>
850 :
public TensorEvaluator<const TensorStridingSlicingOp<StartIndices, StopIndices, Strides, ArgType>, Device>
852 typedef TensorEvaluator<const TensorStridingSlicingOp<StartIndices, StopIndices, Strides, ArgType>, Device> Base;
853 typedef TensorStridingSlicingOp<StartIndices, StopIndices, Strides, ArgType> XprType;
854 static const int NumDims = internal::array_size<Strides>::value;
858 PacketAccess =
false,
860 Layout = TensorEvaluator<ArgType, Device>::Layout,
861 CoordAccess = TensorEvaluator<ArgType, Device>::CoordAccess,
865 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE TensorEvaluator(
const XprType& op,
const Device&
device)
869 typedef typename XprType::Index Index;
870 typedef typename XprType::Scalar Scalar;
871 typedef typename internal::remove_const<Scalar>::type ScalarNonConst;
872 typedef typename XprType::CoeffReturnType CoeffReturnType;
873 typedef typename PacketType<CoeffReturnType, Device>::type PacketReturnType;
874 typedef Strides Dimensions;
876 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE CoeffReturnType& coeffRef(Index index)
878 return this->m_impl.coeffRef(this->srcCoeff(index));
Definition TensorAssign.h:56
The tensor base class.
Definition TensorForwardDeclarations.h:29
Tensor reshaping class.
Definition TensorMorphing.h:50
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