11 #ifndef EIGEN_CXX11_TENSOR_TENSOR_TRACE_H
12 #define EIGEN_CXX11_TENSOR_TENSOR_TRACE_H
14 #include "./InternalHeaderCheck.h"
27 template<
typename Dims,
typename XprType>
28 struct traits<TensorTraceOp<Dims, XprType> > :
public traits<XprType>
30 typedef typename XprType::Scalar Scalar;
31 typedef traits<XprType> XprTraits;
32 typedef typename XprTraits::StorageKind StorageKind;
33 typedef typename XprTraits::Index
Index;
34 typedef typename XprType::Nested Nested;
35 typedef std::remove_reference_t<Nested> Nested_;
36 static constexpr
int NumDimensions = XprTraits::NumDimensions - array_size<Dims>::value;
37 static constexpr
int Layout = XprTraits::Layout;
40 template<
typename Dims,
typename XprType>
41 struct eval<TensorTraceOp<Dims, XprType>,
Eigen::Dense>
43 typedef const TensorTraceOp<Dims, XprType>& type;
46 template<
typename Dims,
typename XprType>
47 struct nested<TensorTraceOp<Dims, XprType>, 1, typename eval<TensorTraceOp<Dims, XprType> >::type>
49 typedef TensorTraceOp<Dims, XprType> type;
55 template<
typename Dims,
typename XprType>
56 class TensorTraceOp :
public TensorBase<TensorTraceOp<Dims, XprType> >
59 typedef typename Eigen::internal::traits<TensorTraceOp>::Scalar Scalar;
61 typedef typename XprType::CoeffReturnType CoeffReturnType;
62 typedef typename Eigen::internal::nested<TensorTraceOp>::type Nested;
63 typedef typename Eigen::internal::traits<TensorTraceOp>::StorageKind StorageKind;
64 typedef typename Eigen::internal::traits<TensorTraceOp>::Index
Index;
66 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE TensorTraceOp(
const XprType& expr,
const Dims& dims)
67 : m_xpr(expr), m_dims(dims) {
70 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
71 const Dims& dims()
const {
return m_dims; }
73 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
74 const internal::remove_all_t<typename XprType::Nested>& expression()
const {
return m_xpr; }
77 typename XprType::Nested m_xpr;
83 template<
typename Dims,
typename ArgType,
typename Device>
84 struct TensorEvaluator<const TensorTraceOp<Dims, ArgType>, Device>
86 typedef TensorTraceOp<Dims, ArgType> XprType;
87 static constexpr
int NumInputDims = internal::array_size<typename TensorEvaluator<ArgType, Device>::Dimensions>::value;
88 static constexpr
int NumReducedDims = internal::array_size<Dims>::value;
89 static constexpr
int NumOutputDims = NumInputDims - NumReducedDims;
90 typedef typename XprType::Index Index;
91 typedef DSizes<Index, NumOutputDims> Dimensions;
92 typedef typename XprType::Scalar Scalar;
93 typedef typename XprType::CoeffReturnType CoeffReturnType;
94 typedef typename PacketType<CoeffReturnType, Device>::type PacketReturnType;
95 static constexpr
int PacketSize = internal::unpacket_traits<PacketReturnType>::size;
96 typedef StorageMemory<CoeffReturnType, Device> Storage;
97 typedef typename Storage::Type EvaluatorPointerType;
99 static constexpr
int Layout = TensorEvaluator<ArgType, Device>::Layout;
102 PacketAccess = TensorEvaluator<ArgType, Device>::PacketAccess,
104 PreferBlockAccess = TensorEvaluator<ArgType, Device>::PreferBlockAccess,
110 typedef internal::TensorBlockNotImplemented TensorBlock;
113 EIGEN_STRONG_INLINE TensorEvaluator(
const XprType& op,
const Device& device)
114 : m_impl(op.expression(), device), m_traceDim(1), m_device(device)
117 EIGEN_STATIC_ASSERT((NumOutputDims >= 0), YOU_MADE_A_PROGRAMMING_MISTAKE);
118 EIGEN_STATIC_ASSERT((NumReducedDims >= 2) || ((NumReducedDims == 0) && (NumInputDims == 0)), YOU_MADE_A_PROGRAMMING_MISTAKE);
120 for (
int i = 0; i < NumInputDims; ++i) {
121 m_reduced[i] =
false;
124 const Dims& op_dims = op.dims();
125 for (
int i = 0; i < NumReducedDims; ++i) {
126 eigen_assert(op_dims[i] >= 0);
127 eigen_assert(op_dims[i] < NumInputDims);
128 m_reduced[op_dims[i]] =
true;
132 int num_distinct_reduce_dims = 0;
133 for (
int i = 0; i < NumInputDims; ++i) {
135 ++num_distinct_reduce_dims;
139 EIGEN_ONLY_USED_FOR_DEBUG(num_distinct_reduce_dims);
140 eigen_assert(num_distinct_reduce_dims == NumReducedDims);
143 const typename TensorEvaluator<ArgType, Device>::Dimensions& input_dims = m_impl.dimensions();
145 int output_index = 0;
146 int reduced_index = 0;
147 for (
int i = 0; i < NumInputDims; ++i) {
149 m_reducedDims[reduced_index] = input_dims[i];
150 if (reduced_index > 0) {
152 eigen_assert(m_reducedDims[0] == m_reducedDims[reduced_index]);
157 m_dimensions[output_index] = input_dims[i];
162 if (NumReducedDims != 0) {
163 m_traceDim = m_reducedDims[0];
167 if (NumOutputDims > 0) {
168 if (
static_cast<int>(Layout) ==
static_cast<int>(
ColMajor)) {
169 m_outputStrides[0] = 1;
170 for (
int i = 1; i < NumOutputDims; ++i) {
171 m_outputStrides[i] = m_outputStrides[i - 1] * m_dimensions[i - 1];
175 m_outputStrides.back() = 1;
176 for (
int i = NumOutputDims - 2; i >= 0; --i) {
177 m_outputStrides[i] = m_outputStrides[i + 1] * m_dimensions[i + 1];
183 if (NumInputDims > 0) {
184 array<Index, NumInputDims> input_strides;
185 if (
static_cast<int>(Layout) ==
static_cast<int>(
ColMajor)) {
186 input_strides[0] = 1;
187 for (
int i = 1; i < NumInputDims; ++i) {
188 input_strides[i] = input_strides[i - 1] * input_dims[i - 1];
192 input_strides.back() = 1;
193 for (
int i = NumInputDims - 2; i >= 0; --i) {
194 input_strides[i] = input_strides[i + 1] * input_dims[i + 1];
200 for (
int i = 0; i < NumInputDims; ++i) {
202 m_reducedStrides[reduced_index] = input_strides[i];
206 m_preservedStrides[output_index] = input_strides[i];
213 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
const Dimensions& dimensions()
const {
217 EIGEN_STRONG_INLINE
bool evalSubExprsIfNeeded(EvaluatorPointerType ) {
218 m_impl.evalSubExprsIfNeeded(NULL);
222 EIGEN_STRONG_INLINE
void cleanup() {
226 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE CoeffReturnType coeff(Index index)
const
229 CoeffReturnType result = internal::cast<int, CoeffReturnType>(0);
230 Index index_stride = 0;
231 for (
int i = 0; i < NumReducedDims; ++i) {
232 index_stride += m_reducedStrides[i];
237 if (NumOutputDims != 0)
238 cur_index = firstInput(index);
239 for (Index i = 0; i < m_traceDim; ++i) {
240 result += m_impl.coeff(cur_index);
241 cur_index += index_stride;
247 template<
int LoadMode>
248 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE PacketReturnType packet(Index index)
const {
249 eigen_assert(index + PacketSize - 1 < dimensions().TotalSize());
251 EIGEN_ALIGN_MAX std::remove_const_t<CoeffReturnType> values[PacketSize];
252 for (
int i = 0; i < PacketSize; ++i) {
253 values[i] = coeff(index + i);
255 PacketReturnType result = internal::ploadt<PacketReturnType, LoadMode>(values);
259 #ifdef EIGEN_USE_SYCL
261 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
void bind(cl::sycl::handler &cgh)
const {
268 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
Index firstInput(Index index)
const {
269 Index startInput = 0;
270 if (
static_cast<int>(Layout) ==
static_cast<int>(
ColMajor)) {
271 for (
int i = NumOutputDims - 1; i > 0; --i) {
272 const Index idx = index / m_outputStrides[i];
273 startInput += idx * m_preservedStrides[i];
274 index -= idx * m_outputStrides[i];
276 startInput += index * m_preservedStrides[0];
279 for (
int i = 0; i < NumOutputDims - 1; ++i) {
280 const Index idx = index / m_outputStrides[i];
281 startInput += idx * m_preservedStrides[i];
282 index -= idx * m_outputStrides[i];
284 startInput += index * m_preservedStrides[NumOutputDims - 1];
289 Dimensions m_dimensions;
290 TensorEvaluator<ArgType, Device> m_impl;
293 const Device EIGEN_DEVICE_REF m_device;
294 array<bool, NumInputDims> m_reduced;
295 array<Index, NumReducedDims> m_reducedDims;
296 array<Index, NumOutputDims> m_outputStrides;
297 array<Index, NumReducedDims> m_reducedStrides;
298 array<Index, NumOutputDims> m_preservedStrides;
Namespace containing all symbols from the Eigen library.
EIGEN_DEFAULT_DENSE_INDEX_TYPE Index