// This file is part of Eigen, a lightweight C++ template library // for linear algebra. // // Copyright (C) 2017 Gagan Goel <gagan.nith@gmail.com> // Copyright (C) 2017 Benoit Steiner <benoit.steiner.goog@gmail.com> // // This Source Code Form is subject to the terms of the Mozilla // Public License v. 2.0. If a copy of the MPL was not distributed // with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
for (int i = 0; i < NumInputDims; ++i) {
m_reduced[i] = false;
}
const Dims& op_dims = op.dims(); for (int i = 0; i < NumReducedDims; ++i) {
eigen_assert(op_dims[i] >= 0);
eigen_assert(op_dims[i] < NumInputDims);
m_reduced[op_dims[i]] = true;
}
// All the dimensions should be distinct to compute the trace int num_distinct_reduce_dims = 0; for (int i = 0; i < NumInputDims; ++i) { if (m_reduced[i]) {
++num_distinct_reduce_dims;
}
}
// Compute the dimensions of the result. consttypename TensorEvaluator<ArgType, Device>::Dimensions& input_dims = m_impl.dimensions();
int output_index = 0; int reduced_index = 0; for (int i = 0; i < NumInputDims; ++i) { if (m_reduced[i]) {
m_reducedDims[reduced_index] = input_dims[i]; if (reduced_index > 0) { // All the trace dimensions must have the same size
eigen_assert(m_reducedDims[0] == m_reducedDims[reduced_index]);
}
++reduced_index;
} else {
m_dimensions[output_index] = input_dims[i];
++output_index;
}
}
if (NumReducedDims != 0) {
m_traceDim = m_reducedDims[0];
}
// Compute the output strides if (NumOutputDims > 0) { if (static_cast<int>(Layout) == static_cast<int>(ColMajor)) {
m_outputStrides[0] = 1; for (int i = 1; i < NumOutputDims; ++i) {
m_outputStrides[i] = m_outputStrides[i - 1] * m_dimensions[i - 1];
}
} else {
m_outputStrides.back() = 1; for (int i = NumOutputDims - 2; i >= 0; --i) {
m_outputStrides[i] = m_outputStrides[i + 1] * m_dimensions[i + 1];
}
}
}
// Compute the input strides if (NumInputDims > 0) {
array<Index, NumInputDims> input_strides; if (static_cast<int>(Layout) == static_cast<int>(ColMajor)) {
input_strides[0] = 1; for (int i = 1; i < NumInputDims; ++i) {
input_strides[i] = input_strides[i - 1] * input_dims[i - 1];
}
} else {
input_strides.back() = 1; for (int i = NumInputDims - 2; i >= 0; --i) {
input_strides[i] = input_strides[i + 1] * input_dims[i + 1];
}
}
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE CoeffReturnType coeff(Index index) const
{ // Initialize the result
CoeffReturnType result = internal::cast<int, CoeffReturnType>(0);
Index index_stride = 0; for (int i = 0; i < NumReducedDims; ++i) {
index_stride += m_reducedStrides[i];
}
// If trace is requested along all dimensions, starting index would be 0
Index cur_index = 0; if (NumOutputDims != 0)
cur_index = firstInput(index); for (Index i = 0; i < m_traceDim; ++i) {
result += m_impl.coeff(cur_index);
cur_index += index_stride;
}
EIGEN_ALIGN_MAX typename internal::remove_const<CoeffReturnType>::type values[PacketSize]; for (int i = 0; i < PacketSize; ++i) {
values[i] = coeff(index + i);
}
PacketReturnType result = internal::ploadt<PacketReturnType, LoadMode>(values); return result;
}
#ifdef EIGEN_USE_SYCL // binding placeholder accessors to a command group handler for SYCL
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE void bind(cl::sycl::handler &cgh) const {
m_impl.bind(cgh);
} #endif
protected: // Given the output index, finds the first index in the input tensor used to compute the trace
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Index firstInput(Index index) const {
Index startInput = 0; if (static_cast<int>(Layout) == static_cast<int>(ColMajor)) { for (int i = NumOutputDims - 1; i > 0; --i) { const Index idx = index / m_outputStrides[i];
startInput += idx * m_preservedStrides[i];
index -= idx * m_outputStrides[i];
}
startInput += index * m_preservedStrides[0];
} else { for (int i = 0; i < NumOutputDims - 1; ++i) { const Index idx = index / m_outputStrides[i];
startInput += idx * m_preservedStrides[i];
index -= idx * m_outputStrides[i];
}
startInput += index * m_preservedStrides[NumOutputDims - 1];
} return startInput;
}
Dimensions m_dimensions;
TensorEvaluator<ArgType, Device> m_impl; // Initialize the size of the trace dimension
Index m_traceDim; const Device EIGEN_DEVICE_REF m_device;
array<bool, NumInputDims> m_reduced;
array<Index, NumReducedDims> m_reducedDims;
array<Index, NumOutputDims> m_outputStrides;
array<Index, NumReducedDims> m_reducedStrides;
array<Index, NumOutputDims> m_preservedStrides;
};
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.