10 #ifndef EIGEN_CXX11_TENSOR_TENSOR_SCAN_H 11 #define EIGEN_CXX11_TENSOR_TENSOR_SCAN_H 17 template <
typename Op,
typename XprType>
20 typedef typename XprType::Scalar Scalar;
22 typedef typename XprTraits::StorageKind StorageKind;
23 typedef typename XprType::Nested Nested;
25 static const int NumDimensions = XprTraits::NumDimensions;
26 static const int Layout = XprTraits::Layout;
29 template<
typename Op,
typename XprType>
35 template<
typename Op,
typename XprType>
48 template <
typename Op,
typename XprType>
50 :
public TensorBase<TensorScanOp<Op, XprType>, ReadOnlyAccessors> {
54 typedef typename XprType::CoeffReturnType CoeffReturnType;
60 const XprType& expr,
const Index& axis,
bool exclusive =
false,
const Op& op = Op())
61 : m_expr(expr), m_axis(axis), m_accumulator(op), m_exclusive(exclusive) {}
63 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
64 const Index axis()
const {
return m_axis; }
65 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
66 const XprType& expression()
const {
return m_expr; }
67 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
68 const Op accumulator()
const {
return m_accumulator; }
69 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
70 bool exclusive()
const {
return m_exclusive; }
73 typename XprType::Nested m_expr;
75 const Op m_accumulator;
76 const bool m_exclusive;
79 template <
typename Self,
typename Reducer,
typename Device>
83 template <
typename Op,
typename ArgType,
typename Device>
87 typedef typename XprType::Index
Index;
91 typedef typename XprType::CoeffReturnType CoeffReturnType;
104 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
TensorEvaluator(
const XprType& op,
105 const Device& device)
106 : m_impl(op.expression(), device),
108 m_exclusive(op.exclusive()),
109 m_accumulator(op.accumulator()),
110 m_size(m_impl.dimensions()[op.axis()]),
115 EIGEN_STATIC_ASSERT((NumDims > 0), YOU_MADE_A_PROGRAMMING_MISTAKE);
116 eigen_assert(op.axis() >= 0 && op.axis() < NumDims);
119 const Dimensions& dims = m_impl.dimensions();
120 if (static_cast<int>(Layout) == static_cast<int>(
ColMajor)) {
121 for (
int i = 0; i < op.axis(); ++i) {
122 m_stride = m_stride * dims[i];
125 for (
int i = NumDims - 1; i > op.axis(); --i) {
126 m_stride = m_stride * dims[i];
131 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
const Dimensions& dimensions()
const {
132 return m_impl.dimensions();
135 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
const Index& stride()
const {
139 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
const Index& size()
const {
143 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
const Op& accumulator()
const {
144 return m_accumulator;
147 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
bool exclusive()
const {
155 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
const Device& device()
const {
159 EIGEN_STRONG_INLINE
bool evalSubExprsIfNeeded(Scalar* data) {
160 m_impl.evalSubExprsIfNeeded(NULL);
163 launcher(*
this, data);
167 const Index total_size = internal::array_prod(dimensions());
168 m_output =
static_cast<CoeffReturnType*
>(m_device.allocate(total_size *
sizeof(Scalar)));
169 launcher(*
this, m_output);
173 template<
int LoadMode>
174 EIGEN_DEVICE_FUNC PacketReturnType packet(Index index)
const {
175 return internal::ploadt<PacketReturnType, LoadMode>(m_output + index);
178 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE CoeffReturnType* data()
const 183 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE CoeffReturnType coeff(Index index)
const 185 return m_output[index];
188 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
TensorOpCost costPerCoeff(
bool)
const {
192 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
void cleanup() {
193 if (m_output != NULL) {
194 m_device.deallocate(m_output);
202 const Device& m_device;
203 const bool m_exclusive;
207 CoeffReturnType* m_output;
213 template <
typename Self,
typename Reducer,
typename Device>
215 void operator()(
Self&
self,
typename Self::CoeffReturnType *data) {
216 Index total_size = internal::array_prod(
self.dimensions());
221 for (Index idx1 = 0; idx1 < total_size; idx1 +=
self.stride() *
self.size()) {
222 for (Index idx2 = 0; idx2 <
self.stride(); idx2++) {
224 Index offset = idx1 + idx2;
227 typename Self::CoeffReturnType accum =
self.accumulator().initialize();
228 for (Index idx3 = 0; idx3 <
self.size(); idx3++) {
229 Index curr = offset + idx3 *
self.stride();
231 if (
self.exclusive()) {
232 data[curr] =
self.accumulator().finalize(accum);
233 self.accumulator().reduce(
self.inner().coeff(curr), &accum);
235 self.accumulator().reduce(
self.inner().coeff(curr), &accum);
236 data[curr] =
self.accumulator().finalize(accum);
244 #if defined(EIGEN_USE_GPU) && defined(__CUDACC__) 250 template <
typename Self,
typename Reducer>
251 __global__
void ScanKernel(
Self self, Index total_size,
typename Self::CoeffReturnType* data) {
253 Index val = threadIdx.x + blockIdx.x * blockDim.x;
254 Index offset = (val /
self.stride()) *
self.stride() *
self.size() + val %
self.stride();
256 if (offset + (
self.size() - 1) *
self.stride() < total_size) {
258 typename Self::CoeffReturnType accum =
self.accumulator().initialize();
259 for (Index idx = 0; idx <
self.size(); idx++) {
260 Index curr = offset + idx *
self.stride();
261 if (
self.exclusive()) {
262 data[curr] =
self.accumulator().finalize(accum);
263 self.accumulator().reduce(
self.inner().coeff(curr), &accum);
265 self.accumulator().reduce(
self.inner().coeff(curr), &accum);
266 data[curr] =
self.accumulator().finalize(accum);
274 template <
typename Self,
typename Reducer>
276 void operator()(
const Self&
self,
typename Self::CoeffReturnType* data) {
277 Index total_size = internal::array_prod(
self.dimensions());
278 Index num_blocks = (total_size /
self.size() + 63) / 64;
279 Index block_size = 64;
280 LAUNCH_CUDA_KERNEL((ScanKernel<Self, Reducer>), num_blocks, block_size, 0,
self.device(),
self, total_size, data);
283 #endif // EIGEN_USE_GPU && __CUDACC__ 287 #endif // EIGEN_CXX11_TENSOR_TENSOR_SCAN_H Definition: TensorForwardDeclarations.h:60
Definition: TensorCostModel.h:25
Storage order is column major (see TopicStorageOrders).
Definition: Constants.h:320
Definition: XprHelper.h:158
Namespace containing all symbols from the Eigen library.
Definition: bench_norm.cpp:85
A cost model used to limit the number of threads used for evaluating tensor expression.
Definition: TensorEvaluator.h:28
Definition: TensorScan.h:80
EIGEN_DEFAULT_DENSE_INDEX_TYPE Index
The Index type as used for the API.
Definition: Meta.h:33
The tensor base class.
Definition: TensorBase.h:827
Definition: BandTriangularSolver.h:13
Definition: TensorScan.h:84
Definition: TensorTraits.h:170
The type used to identify a dense storage.
Definition: Constants.h:491
Generic expression where a coefficient-wise unary operator is applied to an expression.
Definition: CwiseUnaryOp.h:55
Definition: ForwardDeclarations.h:17
Definition: XprHelper.h:312
Definition: EmulateArray.h:203