11 #ifndef EIGEN_CXX11_TENSOR_TENSOR_REVERSE_H 12 #define EIGEN_CXX11_TENSOR_TENSOR_REVERSE_H 22 template<
typename ReverseDimensions,
typename XprType>
30 typedef typename XprType::Nested
Nested;
32 static const int NumDimensions = XprTraits::NumDimensions;
33 static const int Layout = XprTraits::Layout;
37 template<
typename ReverseDimensions,
typename XprType>
43 template<
typename ReverseDimensions,
typename XprType>
52 template<
typename ReverseDimensions,
typename XprType>
54 XprType>, WriteAccessors>
67 const XprType& expr,
const ReverseDimensions& reverse_dims)
68 : m_xpr(expr), m_reverse_dims(reverse_dims) { }
71 const ReverseDimensions&
reverse()
const {
return m_reverse_dims; }
86 template<
typename ReverseDimensions,
typename ArgType,
typename Device>
103 BlockAccess = NumDims > 0,
104 PreferBlockAccess =
true,
125 : m_impl(op.expression(), device),
133 m_dimensions = m_impl.dimensions();
134 if (static_cast<int>(Layout) == static_cast<int>(
ColMajor)) {
136 for (
int i = 1;
i < NumDims; ++
i) {
137 m_strides[
i] = m_strides[
i-1] * m_dimensions[
i-1];
138 if (m_strides[
i] > 0) m_fastStrides[
i] = IndexDivisor(m_strides[
i]);
141 m_strides[NumDims-1] = 1;
142 for (
int i = NumDims - 2;
i >= 0; --
i) {
143 m_strides[
i] = m_strides[
i+1] * m_dimensions[
i+1];
144 if (m_strides[
i] > 0) m_fastStrides[
i] = IndexDivisor(m_strides[
i]);
150 const Dimensions&
dimensions()
const {
return m_dimensions; }
153 m_impl.evalSubExprsIfNeeded(
NULL);
157 #ifdef EIGEN_USE_THREADS 158 template <
typename EvalSubExprsCallback>
160 EvaluatorPointerType, EvalSubExprsCallback done) {
161 m_impl.evalSubExprsIfNeededAsync(
nullptr, [done](
bool) { done(
true); });
163 #endif // EIGEN_USE_THREADS 172 Index inputIndex = 0;
173 if (static_cast<int>(Layout) == static_cast<int>(
ColMajor)) {
175 for (
int i = NumDims - 1;
i > 0; --
i) {
176 Index idx = index / m_fastStrides[
i];
177 index -= idx * m_strides[
i];
179 idx = m_dimensions[
i] - idx - 1;
181 inputIndex += idx * m_strides[
i] ;
184 inputIndex += (m_dimensions[0] - index - 1);
190 for (
int i = 0;
i < NumDims - 1; ++
i) {
191 Index idx = index / m_fastStrides[
i];
192 index -= idx * m_strides[
i];
194 idx = m_dimensions[
i] - idx - 1;
196 inputIndex += idx * m_strides[
i] ;
198 if (m_reverse[NumDims-1]) {
199 inputIndex += (m_dimensions[NumDims-1] - index - 1);
209 return m_impl.coeff(reverseIndex(index));
212 template<
int LoadMode>
214 PacketReturnType
packet(Index index)
const 224 for (
int i = 0;
i < PacketSize; ++
i) {
225 values[
i] = coeff(index+
i);
227 PacketReturnType rslt = internal::pload<PacketReturnType>(
values);
233 const size_t target_size = m_device.lastLevelCacheSize();
236 return internal::TensorBlockResourceRequirements::skewed<Scalar>(
238 .addCostPerCoeff({0, 0, 24});
242 block(TensorBlockDesc& desc, TensorBlockScratch& scratch,
243 bool =
false)
const {
251 static const bool isColMajor =
252 static_cast<int>(Layout) == static_cast<int>(
ColMajor);
254 static const Index inner_dim_idx = isColMajor ? 0 : NumDims - 1;
255 const bool inner_dim_reversed = m_reverse[inner_dim_idx];
258 Index block_offset = 0;
261 Index input_offset = reverseIndex(desc.
offset());
266 for (
int i = 0;
i < NumDims; ++
i) {
267 const int dim = isColMajor ?
i : NumDims - 1 -
i;
270 it[
i].reverse = m_reverse[dim];
273 i == 0 ? 1 : (it[i - 1].size * it[i - 1].block_stride);
274 it[
i].block_span = it[
i].block_stride * (it[
i].size - 1);
276 it[
i].input_stride = m_strides[dim];
277 it[
i].input_span = it[
i].input_stride * (it[
i].size - 1);
280 it[
i].input_stride = -1 * it[
i].input_stride;
281 it[
i].input_span = -1 * it[
i].input_span;
287 int effective_inner_dim = 0;
288 for (
int i = 1;
i < NumDims; ++
i) {
290 if (it[
i].block_stride != it[effective_inner_dim].
size)
break;
291 if (it[
i].block_stride !=
numext::abs(it[
i].input_stride))
break;
293 it[
i].size = it[effective_inner_dim].size * it[
i].size;
295 it[
i].block_stride = 1;
296 it[
i].input_stride = (inner_dim_reversed ? -1 : 1);
298 it[
i].block_span = it[
i].block_stride * (it[
i].size - 1);
299 it[
i].input_span = it[
i].input_stride * (it[
i].size - 1);
301 effective_inner_dim =
i;
304 eigen_assert(it[effective_inner_dim].block_stride == 1);
306 (inner_dim_reversed ? -1 : 1));
308 const Index inner_dim_size = it[effective_inner_dim].size;
312 TensorBlock::prepareStorage(desc, scratch);
313 CoeffReturnType* block_buffer = block_storage.
data();
315 while (it[NumDims - 1].count < it[NumDims - 1].
size) {
317 Index dst = block_offset;
318 Index src = input_offset;
322 if (inner_dim_reversed) {
323 for (Index
i = 0;
i < inner_dim_size; ++
i) {
324 block_buffer[dst] = m_impl.coeff(src);
329 for (Index
i = 0;
i < inner_dim_size; ++
i) {
330 block_buffer[dst] = m_impl.coeff(src);
337 if ((NumDims - effective_inner_dim) == 1)
break;
340 for (Index
i = effective_inner_dim + 1;
i < NumDims; ++
i) {
341 if (++it[
i].count < it[
i].
size) {
342 block_offset += it[
i].block_stride;
343 input_offset += it[
i].input_stride;
346 if (
i != NumDims - 1) it[
i].count = 0;
347 block_offset -= it[
i].block_span;
348 input_offset -= it[
i].input_span;
356 double compute_cost = NumDims * (2 * TensorOpCost::AddCost<Index>() +
357 2 * TensorOpCost::MulCost<Index>() +
358 TensorOpCost::DivCost<Index>());
359 for (
int i = 0;
i < NumDims; ++
i) {
361 compute_cost += 2 * TensorOpCost::AddCost<Index>();
364 return m_impl.costPerCoeff(vectorized) +
370 #ifdef EIGEN_USE_SYCL 386 struct BlockIteratorState {
408 template <
typename ReverseDimensions,
typename ArgType,
typename Device>
410 :
public TensorEvaluator<const TensorReverseOp<ReverseDimensions, ArgType>,
423 PreferBlockAccess =
false,
429 : Base(op, device) {}
441 const Dimensions&
dimensions()
const {
return this->m_dimensions; }
444 return this->m_impl.coeffRef(this->reverseIndex(index));
454 internal::pstore<CoeffReturnType, PacketReturnType>(
values,
x);
456 for (
int i = 0;
i < PacketSize; ++
i) {
457 this->coeffRef(index+
i) = values[
i];
465 #endif // EIGEN_CXX11_TENSOR_TENSOR_REVERSE_H TensorEvaluator< const ArgType, Device >::TensorBlock ArgTensorBlock
Storage::Type EvaluatorPointerType
const Device EIGEN_DEVICE_REF m_device
#define EIGEN_STRONG_INLINE
XprType::CoeffReturnType CoeffReturnType
PacketType< CoeffReturnType, Device >::type PacketReturnType
EIGEN_STRONG_INLINE void cleanup()
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE TensorBlock block(TensorBlockDesc &desc, TensorBlockScratch &scratch, bool=false) const
EIGEN_DEVICE_FUNC const internal::remove_all< typename XprType::Nested >::type & expression() const
TensorReverseOp< ReverseDimensions, ArgType > XprType
EIGEN_DEVICE_FUNC Storage::Type data() const
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Index reverseIndex(Index index) const
Namespace containing all symbols from the Eigen library.
const ReverseDimensions m_reverse_dims
A cost model used to limit the number of threads used for evaluating tensor expression.
TensorMaterializedBlock AsTensorMaterializedBlock() const
internal::TensorBlockScratchAllocator< Device > TensorBlockScratch
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE PacketReturnType packet(Index index) const
#define EIGEN_STATIC_ASSERT(CONDITION, MSG)
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE TensorOpCost costPerCoeff(bool vectorized) const
traits< XprType > XprTraits
IndexType dimension(int index) const
const TensorReverseOp< ReverseDimensions, XprType > & type
Eigen::internal::traits< TensorReverseOp >::StorageKind StorageKind
TensorBase< TensorReverseOp< ReverseDimensions, XprType >, WriteAccessors > Base
PacketType< CoeffReturnType, Device >::type PacketReturnType
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const Dimensions & dimensions() const
TensorReverseOp< ReverseDimensions, ArgType > XprType
EIGEN_STRONG_INLINE TensorEvaluator(const XprType &op, const Device &device)
XprTraits::PointerType PointerType
Generic expression where a coefficient-wise binary operator is applied to two expressions.
EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE internal::enable_if< NumTraits< T >::IsSigned||NumTraits< T >::IsComplex, typename NumTraits< T >::Real >::type abs(const T &x)
EIGEN_STRONG_INLINE bool evalSubExprsIfNeeded(EvaluatorPointerType)
internal::TensorMaterializedBlock< CoeffReturnType, NumDims, Layout, Index > TensorBlock
array< Index, NumDims > m_strides
Eigen::NumTraits< Scalar >::Real RealScalar
EIGEN_DEFAULT_DENSE_INDEX_TYPE Index
The Index type as used for the API.
DSizes< Index, NumDims > Dimensions
DSizes< Index, NumDims > Dimensions
array< IndexDivisor, NumDims > m_fastStrides
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const Dimensions & dimensions() const
Eigen::internal::traits< TensorReverseOp >::Index Index
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE CoeffReturnType coeff(Index index) const
TensorEvaluator< const TensorReverseOp< ReverseDimensions, ArgType >, Device > Base
StorageMemory< CoeffReturnType, Device > Storage
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE internal::TensorBlockResourceRequirements getResourceRequirements() const
XprType::CoeffReturnType CoeffReturnType
XprType::CoeffReturnType CoeffReturnType
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE TensorReverseOp(const XprType &expr, const ReverseDimensions &reverse_dims)
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE void writePacket(Index index, const PacketReturnType &x)
EIGEN_CONSTEXPR Index size(const T &x)
#define EIGEN_DEVICE_FUNC
internal::TensorBlockNotImplemented TensorBlock
Eigen::internal::traits< TensorReverseOp >::Scalar Scalar
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Scalar & coeffRef(Index index)
void reverse(const MatrixType &m)
TensorEvaluator< ArgType, Device > m_impl
#define EIGEN_TENSOR_INHERIT_ASSIGNMENT_OPERATORS(Derived)
ReverseDimensions m_reverse
EIGEN_STRONG_INLINE TensorEvaluator(const XprType &op, const Device &device)
Eigen::internal::nested< TensorReverseOp >::type Nested
remove_reference< Nested >::type _Nested
Generic expression where a coefficient-wise unary operator is applied to an expression.
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
const std::vector< size_t > dimensions
XprTraits::StorageKind StorageKind
TensorReverseOp< ReverseDimensions, XprType > type
internal::TensorIntDivisor< Index > IndexDivisor
EIGEN_DEVICE_FUNC const ReverseDimensions & reverse() const
#define EIGEN_UNROLL_LOOP
internal::TensorBlockDescriptor< NumDims, Index > TensorBlockDesc