PartialReduxEvaluator.h
Go to the documentation of this file.
1 // This file is part of Eigen, a lightweight C++ template library
2 // for linear algebra.
3 //
4 // Copyright (C) 2011-2018 Gael Guennebaud <gael.guennebaud@inria.fr>
5 //
6 // This Source Code Form is subject to the terms of the Mozilla
7 // Public License v. 2.0. If a copy of the MPL was not distributed
8 // with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 
10 #ifndef EIGEN_PARTIALREDUX_H
11 #define EIGEN_PARTIALREDUX_H
12 
13 namespace Eigen {
14 
15 namespace internal {
16 
17 
18 /***************************************************************************
19 *
20 * This file provides evaluators for partial reductions.
21 * There are two modes:
22 *
23 * - scalar path: simply calls the respective function on the column or row.
24 * -> nothing special here, all the tricky part is handled by the return
25 * types of VectorwiseOp's members. They embed the functor calling the
26 * respective DenseBase's member function.
27 *
28 * - vectorized path: implements a packet-wise reductions followed by
29 * some (optional) processing of the outcome, e.g., division by n for mean.
30 *
31 * For the vectorized path let's observe that the packet-size and outer-unrolling
32 * are both decided by the assignement logic. So all we have to do is to decide
33 * on the inner unrolling.
34 *
35 * For the unrolling, we can reuse "internal::redux_vec_unroller" from Redux.h,
36 * but be need to be careful to specify correct increment.
37 *
38 ***************************************************************************/
39 
40 
41 /* logic deciding a strategy for unrolling of vectorized paths */
42 template<typename Func, typename Evaluator>
44 {
45  enum {
46  OuterSize = int(Evaluator::IsRowMajor) ? Evaluator::RowsAtCompileTime : Evaluator::ColsAtCompileTime,
48  : OuterSize * Evaluator::CoeffReadCost + (OuterSize-1) * functor_traits<Func>::Cost,
50  };
51 
52 };
53 
54 /* Value to be returned when size==0 , by default let's return 0 */
55 template<typename PacketType,typename Func>
57 PacketType packetwise_redux_empty_value(const Func& ) { return pset1<PacketType>(0); }
58 
59 /* For products the default is 1 */
60 template<typename PacketType,typename Scalar>
63 
64 /* Perform the actual reduction */
65 template<typename Func, typename Evaluator,
66  int Unrolling = packetwise_redux_traits<Func, Evaluator>::Unrolling
67 >
69 
70 /* Perform the actual reduction with unrolling */
71 template<typename Func, typename Evaluator>
72 struct packetwise_redux_impl<Func, Evaluator, CompleteUnrolling>
73 {
75  typedef typename Evaluator::Scalar Scalar;
76 
77  template<typename PacketType>
79  PacketType run(const Evaluator &eval, const Func& func, Index /*size*/)
80  {
82  }
83 };
84 
85 /* Add a specialization of redux_vec_unroller for size==0 at compiletime.
86  * This specialization is not required for general reductions, which is
87  * why it is defined here.
88  */
89 template<typename Func, typename Evaluator, int Start>
90 struct redux_vec_unroller<Func, Evaluator, Start, 0>
91 {
92  template<typename PacketType>
94  static EIGEN_STRONG_INLINE PacketType run(const Evaluator &, const Func& f)
95  {
96  return packetwise_redux_empty_value<PacketType>(f);
97  }
98 };
99 
100 /* Perform the actual reduction for dynamic sizes */
101 template<typename Func, typename Evaluator>
102 struct packetwise_redux_impl<Func, Evaluator, NoUnrolling>
103 {
104  typedef typename Evaluator::Scalar Scalar;
106 
107  template<typename PacketType>
109  static PacketType run(const Evaluator &eval, const Func& func, Index size)
110  {
111  if(size==0)
112  return packetwise_redux_empty_value<PacketType>(func);
113 
114  const Index size4 = (size-1)&(~3);
115  PacketType p = eval.template packetByOuterInner<Unaligned,PacketType>(0,0);
116  Index i = 1;
117  // This loop is optimized for instruction pipelining:
118  // - each iteration generates two independent instructions
119  // - thanks to branch prediction and out-of-order execution we have independent instructions across loops
120  for(; i<size4; i+=4)
121  p = func.packetOp(p,
122  func.packetOp(
123  func.packetOp(eval.template packetByOuterInner<Unaligned,PacketType>(i+0,0),eval.template packetByOuterInner<Unaligned,PacketType>(i+1,0)),
124  func.packetOp(eval.template packetByOuterInner<Unaligned,PacketType>(i+2,0),eval.template packetByOuterInner<Unaligned,PacketType>(i+3,0))));
125  for(; i<size; ++i)
126  p = func.packetOp(p, eval.template packetByOuterInner<Unaligned,PacketType>(i,0));
127  return p;
128  }
129 };
130 
131 template< typename ArgType, typename MemberOp, int Direction>
132 struct evaluator<PartialReduxExpr<ArgType, MemberOp, Direction> >
133  : evaluator_base<PartialReduxExpr<ArgType, MemberOp, Direction> >
134 {
139  typedef typename ArgType::Scalar InputScalar;
140  typedef typename XprType::Scalar Scalar;
141  enum {
142  TraversalSize = Direction==int(Vertical) ? int(ArgType::RowsAtCompileTime) : int(ArgType::ColsAtCompileTime)
143  };
144  typedef typename MemberOp::template Cost<int(TraversalSize)> CostOpType;
145  enum {
146  CoeffReadCost = TraversalSize==Dynamic ? HugeCost
147  : TraversalSize==0 ? 1
149 
151 
152  _Vectorizable = bool(int(_ArgFlags)&PacketAccessBit)
153  && bool(MemberOp::Vectorizable)
154  && (Direction==int(Vertical) ? bool(_ArgFlags&RowMajorBit) : (_ArgFlags&RowMajorBit)==0)
155  && (TraversalSize!=0),
156 
157  Flags = (traits<XprType>::Flags&RowMajorBit)
158  | (evaluator<ArgType>::Flags&(HereditaryBits&(~RowMajorBit)))
159  | (_Vectorizable ? PacketAccessBit : 0)
160  | LinearAccessBit,
161 
162  Alignment = 0 // FIXME this will need to be improved once PartialReduxExpr is vectorized
163  };
164 
165  EIGEN_DEVICE_FUNC explicit evaluator(const XprType xpr)
166  : m_arg(xpr.nestedExpression()), m_functor(xpr.functor())
167  {
168  EIGEN_INTERNAL_CHECK_COST_VALUE(TraversalSize==Dynamic ? HugeCost : (TraversalSize==0 ? 1 : int(CostOpType::value)));
169  EIGEN_INTERNAL_CHECK_COST_VALUE(CoeffReadCost);
170  }
171 
172  typedef typename XprType::CoeffReturnType CoeffReturnType;
173 
175  const Scalar coeff(Index i, Index j) const
176  {
177  return coeff(Direction==Vertical ? j : i);
178  }
179 
181  const Scalar coeff(Index index) const
182  {
183  return m_functor(m_arg.template subVector<DirectionType(Direction)>(index));
184  }
185 
186  template<int LoadMode,typename PacketType>
189  {
190  return packet<LoadMode,PacketType>(Direction==Vertical ? j : i);
191  }
192 
193  template<int LoadMode,typename PacketType>
196  {
197  enum { PacketSize = internal::unpacket_traits<PacketType>::size };
198  typedef Block<const ArgTypeNestedCleaned,
199  Direction==Vertical ? int(ArgType::RowsAtCompileTime) : int(PacketSize),
200  Direction==Vertical ? int(PacketSize) : int(ArgType::ColsAtCompileTime),
201  true /* InnerPanel */> PanelType;
202 
203  PanelType panel(m_arg,
204  Direction==Vertical ? 0 : idx,
205  Direction==Vertical ? idx : 0,
206  Direction==Vertical ? m_arg.rows() : Index(PacketSize),
207  Direction==Vertical ? Index(PacketSize) : m_arg.cols());
208 
209  // FIXME
210  // See bug 1612, currently if PacketSize==1 (i.e. complex<double> with 128bits registers) then the storage-order of panel get reversed
211  // and methods like packetByOuterInner do not make sense anymore in this context.
212  // So let's just by pass "vectorization" in this case:
213  if(PacketSize==1)
214  return internal::pset1<PacketType>(coeff(idx));
215 
216  typedef typename internal::redux_evaluator<PanelType> PanelEvaluator;
217  PanelEvaluator panel_eval(panel);
218  typedef typename MemberOp::BinaryOp BinaryOp;
219  PacketType p = internal::packetwise_redux_impl<BinaryOp,PanelEvaluator>::template run<PacketType>(panel_eval,m_functor.binaryFunc(),m_arg.outerSize());
220  return p;
221  }
222 
223 protected:
225  const MemberOp m_functor;
226 };
227 
228 } // end namespace internal
229 
230 } // end namespace Eigen
231 
232 #endif // EIGEN_PARTIALREDUX_H
gtsam.examples.DogLegOptimizerExample.int
int
Definition: DogLegOptimizerExample.py:111
Eigen::internal::packetwise_redux_traits
Definition: PartialReduxEvaluator.h:43
Eigen::internal::redux_novec_unroller< Func, Evaluator, 0, Evaluator::SizeAtCompileTime >
Eigen::HugeCost
const int HugeCost
Definition: Constants.h:44
EIGEN_DEVICE_FUNC
#define EIGEN_DEVICE_FUNC
Definition: Macros.h:976
Eigen
Namespace containing all symbols from the Eigen library.
Definition: jet.h:637
Eigen::internal::redux_evaluator
Definition: Redux.h:357
EIGEN_UNROLLING_LIMIT
#define EIGEN_UNROLLING_LIMIT
Definition: Settings.h:24
Eigen::Block
Expression of a fixed-size or dynamic-size block.
Definition: Block.h:103
Eigen::internal::redux_traits::PacketType
find_best_packet< typename Evaluator::Scalar, Evaluator::SizeAtCompileTime >::type PacketType
Definition: Redux.h:32
Eigen::internal::packetwise_redux_traits::Cost
@ Cost
Definition: PartialReduxEvaluator.h:87
Eigen::internal::evaluator< PartialReduxExpr< ArgType, MemberOp, Direction > >::Scalar
XprType::Scalar Scalar
Definition: PartialReduxEvaluator.h:140
Eigen::internal::evaluator< PartialReduxExpr< ArgType, MemberOp, Direction > >::ArgTypeNested
internal::nested_eval< ArgType, 1 >::type ArgTypeNested
Definition: PartialReduxEvaluator.h:136
Eigen::internal::evaluator< PartialReduxExpr< ArgType, MemberOp, Direction > >::m_functor
const MemberOp m_functor
Definition: PartialReduxEvaluator.h:225
Eigen::RowMajorBit
const unsigned int RowMajorBit
Definition: Constants.h:66
Eigen::internal::packetwise_redux_impl< Func, Evaluator, NoUnrolling >::Scalar
Evaluator::Scalar Scalar
Definition: PartialReduxEvaluator.h:104
Eigen::DirectionType
DirectionType
Definition: Constants.h:261
Eigen::CompleteUnrolling
@ CompleteUnrolling
Definition: Constants.h:304
Eigen::internal::evaluator_base
Definition: CoreEvaluators.h:110
Eigen::internal::evaluator< PartialReduxExpr< ArgType, MemberOp, Direction > >::packet
EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC PacketType packet(Index idx) const
Definition: PartialReduxEvaluator.h:195
Eigen::internal::packetwise_redux_impl< Func, Evaluator, NoUnrolling >::run
static EIGEN_DEVICE_FUNC PacketType run(const Evaluator &eval, const Func &func, Index size)
Definition: PartialReduxEvaluator.h:109
Eigen::internal::scalar_product_op
Definition: BinaryFunctors.h:70
Eigen::NoUnrolling
@ NoUnrolling
Definition: Constants.h:299
Eigen::PacketAccessBit
const unsigned int PacketAccessBit
Definition: Constants.h:94
Eigen::PacketType
Definition: TensorMeta.h:50
Eigen::internal::true_type
Definition: Meta.h:96
Eigen::internal::evaluator< PartialReduxExpr< ArgType, MemberOp, Direction > >::ConstArgTypeNested
internal::add_const_on_value_type< ArgTypeNested >::type ConstArgTypeNested
Definition: PartialReduxEvaluator.h:137
Eigen::internal::evaluator< PartialReduxExpr< ArgType, MemberOp, Direction > >::packet
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE PacketType packet(Index i, Index j) const
Definition: PartialReduxEvaluator.h:188
j
std::ptrdiff_t j
Definition: tut_arithmetic_redux_minmax.cpp:2
Eigen::internal::packetwise_redux_traits::OuterSize
@ OuterSize
Definition: PartialReduxEvaluator.h:86
Eigen::Dynamic
const int Dynamic
Definition: Constants.h:22
Eigen::internal::unpacket_traits
Definition: GenericPacketMath.h:132
Eigen::internal::redux_vec_unroller
Definition: Redux.h:146
EIGEN_STRONG_INLINE
#define EIGEN_STRONG_INLINE
Definition: Macros.h:917
Eigen::internal::evaluator< PartialReduxExpr< ArgType, MemberOp, Direction > >::CoeffReturnType
XprType::CoeffReturnType CoeffReturnType
Definition: PartialReduxEvaluator.h:172
Eigen::internal::packetwise_redux_impl< Func, Evaluator, CompleteUnrolling >::Base
redux_novec_unroller< Func, Evaluator, 0, Evaluator::SizeAtCompileTime > Base
Definition: PartialReduxEvaluator.h:74
Eigen::Triplet< double >
Eigen::internal::evaluator
Definition: CoreEvaluators.h:90
Eigen::Vertical
@ Vertical
Definition: Constants.h:264
Eigen::internal::packetwise_redux_impl
Definition: PartialReduxEvaluator.h:68
tree::f
Point2(* f)(const Point3 &, OptionalJacobian< 2, 3 >)
Definition: testExpression.cpp:218
Eigen::internal::evaluator< PartialReduxExpr< ArgType, MemberOp, Direction > >::InputScalar
ArgType::Scalar InputScalar
Definition: PartialReduxEvaluator.h:139
Eigen::LinearAccessBit
const unsigned int LinearAccessBit
Definition: Constants.h:130
Eigen::internal::evaluator< PartialReduxExpr< ArgType, MemberOp, Direction > >::ArgTypeNestedCleaned
internal::remove_all< ArgTypeNested >::type ArgTypeNestedCleaned
Definition: PartialReduxEvaluator.h:138
Eigen::internal::packetwise_redux_impl< Func, Evaluator, NoUnrolling >::PacketScalar
redux_traits< Func, Evaluator >::PacketType PacketScalar
Definition: PartialReduxEvaluator.h:105
Eigen::internal::traits
Definition: ForwardDeclarations.h:17
Eigen::internal::evaluator< PartialReduxExpr< ArgType, MemberOp, Direction > >::CostOpType
MemberOp::template Cost< int(TraversalSize)> CostOpType
Definition: PartialReduxEvaluator.h:144
Eigen::internal::packetwise_redux_impl< Func, Evaluator, CompleteUnrolling >::run
static EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE PacketType run(const Evaluator &eval, const Func &func, Index)
Definition: PartialReduxEvaluator.h:79
Eigen::internal::evaluator< PartialReduxExpr< ArgType, MemberOp, Direction > >::coeff
EIGEN_DEVICE_FUNC const EIGEN_STRONG_INLINE Scalar coeff(Index i, Index j) const
Definition: PartialReduxEvaluator.h:175
subVector
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE internal::conditional< Direction==Vertical, ColXpr, RowXpr >::type subVector(Index i)
Definition: BlockMethods.h:1422
p
float * p
Definition: Tutorial_Map_using.cpp:9
Eigen::internal::redux_vec_unroller< Func, Evaluator, Start, 0 >::run
static EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE PacketType run(const Evaluator &, const Func &f)
Definition: PartialReduxEvaluator.h:94
Eigen::internal::evaluator< PartialReduxExpr< ArgType, MemberOp, Direction > >::XprType
PartialReduxExpr< ArgType, MemberOp, Direction > XprType
Definition: PartialReduxEvaluator.h:135
Eigen::internal::evaluator< PartialReduxExpr< ArgType, MemberOp, Direction > >::m_arg
ConstArgTypeNested m_arg
Definition: PartialReduxEvaluator.h:224
Eigen::internal::packetwise_redux_empty_value
EIGEN_DEVICE_FUNC PacketType packetwise_redux_empty_value(const Func &)
Definition: PartialReduxEvaluator.h:57
Eigen::internal::functor_traits
Definition: XprHelper.h:175
internal
Definition: BandTriangularSolver.h:13
Eigen::internal::size
EIGEN_CONSTEXPR Index size(const T &x)
Definition: Meta.h:479
EIGEN_INTERNAL_CHECK_COST_VALUE
#define EIGEN_INTERNAL_CHECK_COST_VALUE(C)
Definition: StaticAssert.h:218
func
Definition: benchGeometry.cpp:23
Eigen::PartialReduxExpr
Generic expression of a partially reduxed matrix.
Definition: ForwardDeclarations.h:263
Eigen::HereditaryBits
const unsigned int HereditaryBits
Definition: Constants.h:195
Eigen::internal::evaluator< PartialReduxExpr< ArgType, MemberOp, Direction > >::coeff
EIGEN_DEVICE_FUNC const EIGEN_STRONG_INLINE Scalar coeff(Index index) const
Definition: PartialReduxEvaluator.h:181
Eigen::internal::eval
Definition: XprHelper.h:332
Eigen::internal::evaluator< PartialReduxExpr< ArgType, MemberOp, Direction > >::evaluator
EIGEN_DEVICE_FUNC evaluator(const XprType xpr)
Definition: PartialReduxEvaluator.h:165
test_callbacks.value
value
Definition: test_callbacks.py:160
i
int i
Definition: BiCGSTAB_step_by_step.cpp:9
Eigen::internal::packetwise_redux_impl< Func, Evaluator, CompleteUnrolling >::Scalar
Evaluator::Scalar Scalar
Definition: PartialReduxEvaluator.h:75
Scalar
SCALAR Scalar
Definition: bench_gemm.cpp:46
Eigen::Index
EIGEN_DEFAULT_DENSE_INDEX_TYPE Index
The Index type as used for the API.
Definition: Meta.h:74
Eigen::internal::add_const_on_value_type
Definition: Meta.h:214


gtsam
Author(s):
autogenerated on Sat Nov 16 2024 04:03:31