10 #ifndef EIGEN_CXX11_TENSOR_TENSOR_PATCH_H 11 #define EIGEN_CXX11_TENSOR_TENSOR_PATCH_H 23 template<
typename PatchDim,
typename XprType>
30 typedef typename XprType::Nested
Nested;
32 static const int NumDimensions = XprTraits::NumDimensions + 1;
33 static const int Layout = XprTraits::Layout;
36 template<
typename PatchDim,
typename XprType>
42 template<
typename PatchDim,
typename XprType>
52 template<
typename PatchDim,
typename XprType>
64 : m_xpr(expr), m_patch_dims(patch_dims) {}
67 const PatchDim&
patch_dims()
const {
return m_patch_dims; }
80 template<
typename PatchDim,
typename ArgType,
typename Device>
102 : m_impl(op.expression(), device)
104 Index num_patches = 1;
107 if (static_cast<int>(Layout) == static_cast<int>(
ColMajor)) {
108 for (
int i = 0;
i < NumDims-1; ++
i) {
109 m_dimensions[
i] = patch_dims[
i];
110 num_patches *= (input_dims[
i] - patch_dims[
i] + 1);
112 m_dimensions[NumDims-1] = num_patches;
114 m_inputStrides[0] = 1;
115 m_patchStrides[0] = 1;
116 for (
int i = 1;
i < NumDims-1; ++
i) {
117 m_inputStrides[
i] = m_inputStrides[
i-1] * input_dims[
i-1];
118 m_patchStrides[
i] = m_patchStrides[
i-1] * (input_dims[
i-1] - patch_dims[
i-1] + 1);
120 m_outputStrides[0] = 1;
121 for (
int i = 1;
i < NumDims; ++
i) {
122 m_outputStrides[
i] = m_outputStrides[
i-1] * m_dimensions[
i-1];
125 for (
int i = 0;
i < NumDims-1; ++
i) {
126 m_dimensions[
i+1] = patch_dims[
i];
127 num_patches *= (input_dims[
i] - patch_dims[
i] + 1);
129 m_dimensions[0] = num_patches;
131 m_inputStrides[NumDims-2] = 1;
132 m_patchStrides[NumDims-2] = 1;
133 for (
int i = NumDims-3;
i >= 0; --
i) {
134 m_inputStrides[
i] = m_inputStrides[
i+1] * input_dims[
i+1];
135 m_patchStrides[
i] = m_patchStrides[
i+1] * (input_dims[
i+1] - patch_dims[
i+1] + 1);
137 m_outputStrides[NumDims-1] = 1;
138 for (
int i = NumDims-2;
i >= 0; --
i) {
139 m_outputStrides[
i] = m_outputStrides[
i+1] * m_dimensions[
i+1];
147 m_impl.evalSubExprsIfNeeded(
NULL);
157 Index output_stride_index = (
static_cast<int>(Layout) == static_cast<int>(
ColMajor)) ? NumDims - 1 : 0;
159 Index patchIndex = index / m_outputStrides[output_stride_index];
161 Index patchOffset = index - patchIndex * m_outputStrides[output_stride_index];
162 Index inputIndex = 0;
163 if (static_cast<int>(Layout) ==
static_cast<int>(
ColMajor)) {
164 for (
int i = NumDims - 2;
i > 0; --
i) {
165 const Index patchIdx = patchIndex / m_patchStrides[
i];
166 patchIndex -= patchIdx * m_patchStrides[
i];
167 const Index offsetIdx = patchOffset / m_outputStrides[
i];
168 patchOffset -= offsetIdx * m_outputStrides[
i];
169 inputIndex += (patchIdx + offsetIdx) * m_inputStrides[
i];
172 for (
int i = 0;
i < NumDims - 2; ++
i) {
173 const Index patchIdx = patchIndex / m_patchStrides[
i];
174 patchIndex -= patchIdx * m_patchStrides[
i];
175 const Index offsetIdx = patchOffset / m_outputStrides[
i+1];
176 patchOffset -= offsetIdx * m_outputStrides[
i+1];
177 inputIndex += (patchIdx + offsetIdx) * m_inputStrides[
i];
180 inputIndex += (patchIndex + patchOffset);
181 return m_impl.coeff(inputIndex);
184 template<
int LoadMode>
190 Index output_stride_index = (
static_cast<int>(Layout) == static_cast<int>(
ColMajor)) ? NumDims - 1 : 0;
191 Index indices[2] = {index, index + PacketSize - 1};
192 Index patchIndices[2] = {indices[0] / m_outputStrides[output_stride_index],
193 indices[1] / m_outputStrides[output_stride_index]};
194 Index patchOffsets[2] = {indices[0] - patchIndices[0] * m_outputStrides[output_stride_index],
195 indices[1] - patchIndices[1] * m_outputStrides[output_stride_index]};
197 Index inputIndices[2] = {0, 0};
198 if (static_cast<int>(Layout) ==
static_cast<int>(
ColMajor)) {
199 for (
int i = NumDims - 2;
i > 0; --
i) {
200 const Index patchIdx[2] = {patchIndices[0] / m_patchStrides[
i],
201 patchIndices[1] / m_patchStrides[
i]};
202 patchIndices[0] -= patchIdx[0] * m_patchStrides[
i];
203 patchIndices[1] -= patchIdx[1] * m_patchStrides[
i];
205 const Index offsetIdx[2] = {patchOffsets[0] / m_outputStrides[
i],
206 patchOffsets[1] / m_outputStrides[
i]};
207 patchOffsets[0] -= offsetIdx[0] * m_outputStrides[
i];
208 patchOffsets[1] -= offsetIdx[1] * m_outputStrides[
i];
210 inputIndices[0] += (patchIdx[0] + offsetIdx[0]) * m_inputStrides[
i];
211 inputIndices[1] += (patchIdx[1] + offsetIdx[1]) * m_inputStrides[
i];
214 for (
int i = 0;
i < NumDims - 2; ++
i) {
215 const Index patchIdx[2] = {patchIndices[0] / m_patchStrides[
i],
216 patchIndices[1] / m_patchStrides[
i]};
217 patchIndices[0] -= patchIdx[0] * m_patchStrides[
i];
218 patchIndices[1] -= patchIdx[1] * m_patchStrides[
i];
220 const Index offsetIdx[2] = {patchOffsets[0] / m_outputStrides[
i+1],
221 patchOffsets[1] / m_outputStrides[
i+1]};
222 patchOffsets[0] -= offsetIdx[0] * m_outputStrides[
i+1];
223 patchOffsets[1] -= offsetIdx[1] * m_outputStrides[
i+1];
225 inputIndices[0] += (patchIdx[0] + offsetIdx[0]) * m_inputStrides[
i];
226 inputIndices[1] += (patchIdx[1] + offsetIdx[1]) * m_inputStrides[
i];
229 inputIndices[0] += (patchIndices[0] + patchOffsets[0]);
230 inputIndices[1] += (patchIndices[1] + patchOffsets[1]);
232 if (inputIndices[1] - inputIndices[0] == PacketSize - 1) {
233 PacketReturnType rslt = m_impl.template packet<Unaligned>(inputIndices[0]);
238 values[0] = m_impl.coeff(inputIndices[0]);
239 values[PacketSize-1] = m_impl.coeff(inputIndices[1]);
240 for (
int i = 1;
i < PacketSize-1; ++
i) {
241 values[
i] = coeff(index+
i);
243 PacketReturnType rslt = internal::pload<PacketReturnType>(
values);
249 const double compute_cost = NumDims * (TensorOpCost::DivCost<Index>() +
250 TensorOpCost::MulCost<Index>() +
251 2 * TensorOpCost::AddCost<Index>());
252 return m_impl.costPerCoeff(vectorized) +
253 TensorOpCost(0, 0, compute_cost, vectorized, PacketSize);
256 EIGEN_DEVICE_FUNC Scalar*
data()
const {
return NULL; }
269 #endif // EIGEN_CXX11_TENSOR_TENSOR_PATCH_H array< Index, NumDims > m_outputStrides
Eigen::internal::nested< TensorPatchOp >::type Nested
#define EIGEN_STRONG_INLINE
remove_reference< Nested >::type _Nested
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const Dimensions & dimensions() const
XprType::CoeffReturnType CoeffReturnType
array< Index, NumDims-1 > m_inputStrides
EIGEN_DEVICE_FUNC const PatchDim & patch_dims() const
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE TensorEvaluator(const XprType &op, const Device &device)
Namespace containing all symbols from the Eigen library.
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE bool evalSubExprsIfNeeded(Scalar *)
A cost model used to limit the number of threads used for evaluating tensor expression.
#define EIGEN_STATIC_ASSERT(CONDITION, MSG)
XprTraits::StorageKind StorageKind
vector< size_t > dimensions(L.begin(), L.end())
XprType::CoeffReturnType CoeffReturnType
EIGEN_DEVICE_FUNC Scalar * data() const
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE CoeffReturnType coeff(Index index) const
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE void cleanup()
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE TensorPatchOp(const XprType &expr, const PatchDim &patch_dims)
EIGEN_DEFAULT_DENSE_INDEX_TYPE Index
The Index type as used for the API.
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE PacketReturnType packet(Index index) const
Eigen::internal::traits< TensorPatchOp >::StorageKind StorageKind
TensorPatchOp< PatchDim, ArgType > XprType
DSizes< Index, NumDims > Dimensions
EIGEN_DEVICE_FUNC const internal::remove_all< typename XprType::Nested >::type & expression() const
TensorEvaluator< ArgType, Device > m_impl
Eigen::internal::traits< TensorPatchOp >::Scalar Scalar
const TensorPatchOp< PatchDim, XprType > & type
const PatchDim m_patch_dims
Eigen::internal::traits< TensorPatchOp >::Index Index
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const Dimensions & dimensions() const
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE TensorOpCost costPerCoeff(bool vectorized) const
TensorPatchOp< PatchDim, XprType > type
array< Index, NumDims-1 > m_patchStrides
traits< XprType > XprTraits
Eigen::NumTraits< Scalar >::Real RealScalar
PacketType< CoeffReturnType, Device >::type PacketReturnType