ProductEvaluators.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) 2006-2008 Benoit Jacob <jacob.benoit.1@gmail.com>
5 // Copyright (C) 2008-2010 Gael Guennebaud <gael.guennebaud@inria.fr>
6 // Copyright (C) 2011 Jitse Niesen <jitse@maths.leeds.ac.uk>
7 //
8 // This Source Code Form is subject to the terms of the Mozilla
9 // Public License v. 2.0. If a copy of the MPL was not distributed
10 // with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
11 
12 #ifndef EIGEN_PRODUCTEVALUATORS_H
13 #define EIGEN_PRODUCTEVALUATORS_H
14 
15 // IWYU pragma: private
16 #include "./InternalHeaderCheck.h"
17 
18 namespace Eigen {
19 
20 namespace internal {
21 
30 template <typename Lhs, typename Rhs, int Options>
31 struct evaluator<Product<Lhs, Rhs, Options>> : public product_evaluator<Product<Lhs, Rhs, Options>> {
34 
36 };
37 
38 // Catch "scalar * ( A * B )" and transform it to "(A*scalar) * B"
39 // TODO we should apply that rule only if that's really helpful
40 template <typename Lhs, typename Rhs, typename Scalar1, typename Scalar2, typename Plain1>
42  const CwiseNullaryOp<internal::scalar_constant_op<Scalar1>, Plain1>,
43  const Product<Lhs, Rhs, DefaultProduct>>> {
44  static const bool value = true;
45 };
46 template <typename Lhs, typename Rhs, typename Scalar1, typename Scalar2, typename Plain1>
48  const CwiseNullaryOp<internal::scalar_constant_op<Scalar1>, Plain1>,
49  const Product<Lhs, Rhs, DefaultProduct>>>
50  : public evaluator<Product<EIGEN_SCALAR_BINARYOP_EXPR_RETURN_TYPE(Scalar1, Lhs, product), Rhs, DefaultProduct>> {
55  typedef evaluator<Product<EIGEN_SCALAR_BINARYOP_EXPR_RETURN_TYPE(Scalar1, Lhs, product), Rhs, DefaultProduct>> Base;
56 
58  : Base(xpr.lhs().functor().m_other * xpr.rhs().lhs() * xpr.rhs().rhs()) {}
59 };
60 
61 template <typename Lhs, typename Rhs, int DiagIndex>
62 struct evaluator<Diagonal<const Product<Lhs, Rhs, DefaultProduct>, DiagIndex>>
63  : public evaluator<Diagonal<const Product<Lhs, Rhs, LazyProduct>, DiagIndex>> {
66 
68  : Base(Diagonal<const Product<Lhs, Rhs, LazyProduct>, DiagIndex>(
69  Product<Lhs, Rhs, LazyProduct>(xpr.nestedExpression().lhs(), xpr.nestedExpression().rhs()), xpr.index())) {}
70 };
71 
72 // Helper class to perform a matrix product with the destination at hand.
73 // Depending on the sizes of the factors, there are different evaluation strategies
74 // as controlled by internal::product_type.
75 template <typename Lhs, typename Rhs, typename LhsShape = typename evaluator_traits<Lhs>::Shape,
76  typename RhsShape = typename evaluator_traits<Rhs>::Shape,
79 
80 template <typename Lhs, typename Rhs>
82  static const bool value = true;
83 };
84 
85 // This is the default evaluator implementation for products:
86 // It creates a temporary and call generic_product_impl
87 template <typename Lhs, typename Rhs, int Options, int ProductTag, typename LhsShape, typename RhsShape>
88 struct product_evaluator<Product<Lhs, Rhs, Options>, ProductTag, LhsShape, RhsShape>
89  : public evaluator<typename Product<Lhs, Rhs, Options>::PlainObject> {
91  typedef typename XprType::PlainObject PlainObject;
93  enum { Flags = Base::Flags | EvalBeforeNestingBit };
94 
96  : m_result(xpr.rows(), xpr.cols()) {
97  internal::construct_at<Base>(this, m_result);
98 
99  // FIXME shall we handle nested_eval here?,
100  // if so, then we must take care at removing the call to nested_eval in the specializations (e.g., in
101  // permutation_matrix_product, transposition_matrix_product, etc.)
102  // typedef typename internal::nested_eval<Lhs,Rhs::ColsAtCompileTime>::type LhsNested;
103  // typedef typename internal::nested_eval<Rhs,Lhs::RowsAtCompileTime>::type RhsNested;
104  // typedef internal::remove_all_t<LhsNested> LhsNestedCleaned;
105  // typedef internal::remove_all_t<RhsNested> RhsNestedCleaned;
106  //
107  // const LhsNested lhs(xpr.lhs());
108  // const RhsNested rhs(xpr.rhs());
109  //
110  // generic_product_impl<LhsNestedCleaned, RhsNestedCleaned>::evalTo(m_result, lhs, rhs);
111 
113  }
114 
115  protected:
117 };
118 
119 // The following three shortcuts are enabled only if the scalar types match exactly.
120 // TODO: we could enable them for different scalar types when the product is not vectorized.
121 
122 // Dense = Product
123 template <typename DstXprType, typename Lhs, typename Rhs, int Options, typename Scalar>
124 struct Assignment<DstXprType, Product<Lhs, Rhs, Options>, internal::assign_op<Scalar, Scalar>, Dense2Dense,
125  std::enable_if_t<(Options == DefaultProduct || Options == AliasFreeProduct)>> {
127  static EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE void run(DstXprType& dst, const SrcXprType& src,
129  Index dstRows = src.rows();
130  Index dstCols = src.cols();
131  if ((dst.rows() != dstRows) || (dst.cols() != dstCols)) dst.resize(dstRows, dstCols);
132  // FIXME shall we handle nested_eval here?
134  }
135 };
136 
137 // Dense += Product
138 template <typename DstXprType, typename Lhs, typename Rhs, int Options, typename Scalar>
139 struct Assignment<DstXprType, Product<Lhs, Rhs, Options>, internal::add_assign_op<Scalar, Scalar>, Dense2Dense,
140  std::enable_if_t<(Options == DefaultProduct || Options == AliasFreeProduct)>> {
142  static EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE void run(DstXprType& dst, const SrcXprType& src,
144  eigen_assert(dst.rows() == src.rows() && dst.cols() == src.cols());
145  // FIXME shall we handle nested_eval here?
146  generic_product_impl<Lhs, Rhs>::addTo(dst, src.lhs(), src.rhs());
147  }
148 };
149 
150 // Dense -= Product
151 template <typename DstXprType, typename Lhs, typename Rhs, int Options, typename Scalar>
152 struct Assignment<DstXprType, Product<Lhs, Rhs, Options>, internal::sub_assign_op<Scalar, Scalar>, Dense2Dense,
153  std::enable_if_t<(Options == DefaultProduct || Options == AliasFreeProduct)>> {
155  static EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE void run(DstXprType& dst, const SrcXprType& src,
157  eigen_assert(dst.rows() == src.rows() && dst.cols() == src.cols());
158  // FIXME shall we handle nested_eval here?
159  generic_product_impl<Lhs, Rhs>::subTo(dst, src.lhs(), src.rhs());
160  }
161 };
162 
163 // Dense ?= scalar * Product
164 // TODO we should apply that rule if that's really helpful
165 // for instance, this is not good for inner products
166 template <typename DstXprType, typename Lhs, typename Rhs, typename AssignFunc, typename Scalar, typename ScalarBis,
167  typename Plain>
168 struct Assignment<DstXprType,
169  CwiseBinaryOp<internal::scalar_product_op<ScalarBis, Scalar>,
170  const CwiseNullaryOp<internal::scalar_constant_op<ScalarBis>, Plain>,
171  const Product<Lhs, Rhs, DefaultProduct>>,
172  AssignFunc, Dense2Dense> {
177  static EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE void run(DstXprType& dst, const SrcXprType& src,
178  const AssignFunc& func) {
179  call_assignment_no_alias(dst, (src.lhs().functor().m_other * src.rhs().lhs()) * src.rhs().rhs(), func);
180  }
181 };
182 
183 //----------------------------------------
184 // Catch "Dense ?= xpr + Product<>" expression to save one temporary
185 // FIXME we could probably enable these rules for any product, i.e., not only Dense and DefaultProduct
186 
187 template <typename OtherXpr, typename Lhs, typename Rhs>
190  internal::scalar_sum_op<typename OtherXpr::Scalar, typename Product<Lhs, Rhs, DefaultProduct>::Scalar>,
191  const OtherXpr, const Product<Lhs, Rhs, DefaultProduct>>,
192  DenseShape> {
193  static const bool value = true;
194 };
195 
196 template <typename OtherXpr, typename Lhs, typename Rhs>
199  internal::scalar_difference_op<typename OtherXpr::Scalar, typename Product<Lhs, Rhs, DefaultProduct>::Scalar>,
200  const OtherXpr, const Product<Lhs, Rhs, DefaultProduct>>,
201  DenseShape> {
202  static const bool value = true;
203 };
204 
205 template <typename DstXprType, typename OtherXpr, typename ProductType, typename Func1, typename Func2>
207  template <typename SrcXprType, typename InitialFunc>
208  static EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE void run(DstXprType& dst, const SrcXprType& src,
209  const InitialFunc& /*func*/) {
210  call_assignment_no_alias(dst, src.lhs(), Func1());
211  call_assignment_no_alias(dst, src.rhs(), Func2());
212  }
213 };
214 
215 #define EIGEN_CATCH_ASSIGN_XPR_OP_PRODUCT(ASSIGN_OP, BINOP, ASSIGN_OP2) \
216  template <typename DstXprType, typename OtherXpr, typename Lhs, typename Rhs, typename DstScalar, \
217  typename SrcScalar, typename OtherScalar, typename ProdScalar> \
218  struct Assignment<DstXprType, \
219  CwiseBinaryOp<internal::BINOP<OtherScalar, ProdScalar>, const OtherXpr, \
220  const Product<Lhs, Rhs, DefaultProduct>>, \
221  internal::ASSIGN_OP<DstScalar, SrcScalar>, Dense2Dense> \
222  : assignment_from_xpr_op_product<DstXprType, OtherXpr, Product<Lhs, Rhs, DefaultProduct>, \
223  internal::ASSIGN_OP<DstScalar, OtherScalar>, \
224  internal::ASSIGN_OP2<DstScalar, ProdScalar>> {}
225 
229 
233 
234 //----------------------------------------
235 
236 template <typename Lhs, typename Rhs>
239  template <typename Dst>
240  static EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE void evalTo(Dst& dst, const Lhs& lhs, const Rhs& rhs) {
241  dst.coeffRef(0, 0) = impl::run(lhs, rhs);
242  }
243 
244  template <typename Dst>
245  static EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE void addTo(Dst& dst, const Lhs& lhs, const Rhs& rhs) {
246  dst.coeffRef(0, 0) += impl::run(lhs, rhs);
247  }
248 
249  template <typename Dst>
250  static EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE void subTo(Dst& dst, const Lhs& lhs, const Rhs& rhs) {
251  dst.coeffRef(0, 0) -= impl::run(lhs, rhs);
252  }
253 };
254 
255 /***********************************************************************
256  * Implementation of outer dense * dense vector product
257  ***********************************************************************/
258 
259 // Column major result
260 template <typename Dst, typename Lhs, typename Rhs, typename Func>
261 void EIGEN_DEVICE_FUNC outer_product_selector_run(Dst& dst, const Lhs& lhs, const Rhs& rhs, const Func& func,
262  const false_type&) {
263  evaluator<Rhs> rhsEval(rhs);
264  ei_declare_local_nested_eval(Lhs, lhs, Rhs::SizeAtCompileTime, actual_lhs);
265  // FIXME if cols is large enough, then it might be useful to make sure that lhs is sequentially stored
266  // FIXME not very good if rhs is real and lhs complex while alpha is real too
267  const Index cols = dst.cols();
268  for (Index j = 0; j < cols; ++j) func(dst.col(j), rhsEval.coeff(Index(0), j) * actual_lhs);
269 }
270 
271 // Row major result
272 template <typename Dst, typename Lhs, typename Rhs, typename Func>
273 void EIGEN_DEVICE_FUNC outer_product_selector_run(Dst& dst, const Lhs& lhs, const Rhs& rhs, const Func& func,
274  const true_type&) {
275  evaluator<Lhs> lhsEval(lhs);
276  ei_declare_local_nested_eval(Rhs, rhs, Lhs::SizeAtCompileTime, actual_rhs);
277  // FIXME if rows is large enough, then it might be useful to make sure that rhs is sequentially stored
278  // FIXME not very good if lhs is real and rhs complex while alpha is real too
279  const Index rows = dst.rows();
280  for (Index i = 0; i < rows; ++i) func(dst.row(i), lhsEval.coeff(i, Index(0)) * actual_rhs);
281 }
282 
283 template <typename Lhs, typename Rhs>
285  template <typename T>
286  struct is_row_major : std::conditional_t<(int(T::Flags) & RowMajorBit), internal::true_type, internal::false_type> {};
288 
289  // TODO it would be nice to be able to exploit our *_assign_op functors for that purpose
290  struct set {
291  template <typename Dst, typename Src>
292  EIGEN_DEVICE_FUNC void operator()(const Dst& dst, const Src& src) const {
293  dst.const_cast_derived() = src;
294  }
295  };
296  struct add {
297  template <typename Dst, typename Src>
298  EIGEN_DEVICE_FUNC void operator()(const Dst& dst, const Src& src) const {
299  dst.const_cast_derived() += src;
300  }
301  };
302  struct sub {
303  template <typename Dst, typename Src>
304  EIGEN_DEVICE_FUNC void operator()(const Dst& dst, const Src& src) const {
305  dst.const_cast_derived() -= src;
306  }
307  };
308  struct adds {
310  explicit adds(const Scalar& s) : m_scale(s) {}
311  template <typename Dst, typename Src>
312  void EIGEN_DEVICE_FUNC operator()(const Dst& dst, const Src& src) const {
313  dst.const_cast_derived() += m_scale * src;
314  }
315  };
316 
317  template <typename Dst>
318  static EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE void evalTo(Dst& dst, const Lhs& lhs, const Rhs& rhs) {
319  internal::outer_product_selector_run(dst, lhs, rhs, set(), is_row_major<Dst>());
320  }
321 
322  template <typename Dst>
323  static EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE void addTo(Dst& dst, const Lhs& lhs, const Rhs& rhs) {
324  internal::outer_product_selector_run(dst, lhs, rhs, add(), is_row_major<Dst>());
325  }
326 
327  template <typename Dst>
328  static EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE void subTo(Dst& dst, const Lhs& lhs, const Rhs& rhs) {
329  internal::outer_product_selector_run(dst, lhs, rhs, sub(), is_row_major<Dst>());
330  }
331 
332  template <typename Dst>
333  static EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE void scaleAndAddTo(Dst& dst, const Lhs& lhs, const Rhs& rhs,
334  const Scalar& alpha) {
335  internal::outer_product_selector_run(dst, lhs, rhs, adds(alpha), is_row_major<Dst>());
336  }
337 };
338 
339 // This base class provides default implementations for evalTo, addTo, subTo, in terms of scaleAndAddTo
340 template <typename Lhs, typename Rhs, typename Derived>
343 
344  template <typename Dst>
345  static EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE void evalTo(Dst& dst, const Lhs& lhs, const Rhs& rhs) {
346  dst.setZero();
347  scaleAndAddTo(dst, lhs, rhs, Scalar(1));
348  }
349 
350  template <typename Dst>
351  static EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE void addTo(Dst& dst, const Lhs& lhs, const Rhs& rhs) {
352  scaleAndAddTo(dst, lhs, rhs, Scalar(1));
353  }
354 
355  template <typename Dst>
356  static EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE void subTo(Dst& dst, const Lhs& lhs, const Rhs& rhs) {
357  scaleAndAddTo(dst, lhs, rhs, Scalar(-1));
358  }
359 
360  template <typename Dst>
361  static EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE void scaleAndAddTo(Dst& dst, const Lhs& lhs, const Rhs& rhs,
362  const Scalar& alpha) {
363  Derived::scaleAndAddTo(dst, lhs, rhs, alpha);
364  }
365 };
366 
367 template <typename Lhs, typename Rhs>
369  : generic_product_impl_base<Lhs, Rhs, generic_product_impl<Lhs, Rhs, DenseShape, DenseShape, GemvProduct>> {
373  enum { Side = Lhs::IsVectorAtCompileTime ? OnTheLeft : OnTheRight };
375 
376  template <typename Dest>
377  static EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE void scaleAndAddTo(Dest& dst, const Lhs& lhs, const Rhs& rhs,
378  const Scalar& alpha) {
379  // Fallback to inner product if both the lhs and rhs is a runtime vector.
380  if (lhs.rows() == 1 && rhs.cols() == 1) {
381  dst.coeffRef(0, 0) += alpha * lhs.row(0).conjugate().dot(rhs.col(0));
382  return;
383  }
384  LhsNested actual_lhs(lhs);
385  RhsNested actual_rhs(rhs);
388  actual_rhs, dst,
389  alpha);
390  }
391 };
392 
393 template <typename Lhs, typename Rhs>
396 
397  template <typename Dst>
398  static EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE void evalTo(Dst& dst, const Lhs& lhs, const Rhs& rhs) {
399  // Same as: dst.noalias() = lhs.lazyProduct(rhs);
400  // but easier on the compiler side
402  }
403 
404  template <typename Dst>
405  static EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE void addTo(Dst& dst, const Lhs& lhs, const Rhs& rhs) {
406  // dst.noalias() += lhs.lazyProduct(rhs);
408  }
409 
410  template <typename Dst>
411  static EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE void subTo(Dst& dst, const Lhs& lhs, const Rhs& rhs) {
412  // dst.noalias() -= lhs.lazyProduct(rhs);
414  }
415 
416  // This is a special evaluation path called from generic_product_impl<...,GemmProduct> in file GeneralMatrixMatrix.h
417  // This variant tries to extract scalar multiples from both the LHS and RHS and factor them out. For instance:
418  // dst {,+,-}= (s1*A)*(B*s2)
419  // will be rewritten as:
420  // dst {,+,-}= (s1*s2) * (A.lazyProduct(B))
421  // There are at least four benefits of doing so:
422  // 1 - huge performance gain for heap-allocated matrix types as it save costly allocations.
423  // 2 - it is faster than simply by-passing the heap allocation through stack allocation.
424  // 3 - it makes this fallback consistent with the heavy GEMM routine.
425  // 4 - it fully by-passes huge stack allocation attempts when multiplying huge fixed-size matrices.
426  // (see https://stackoverflow.com/questions/54738495)
427  // For small fixed sizes matrices, however, the gains are less obvious, it is sometimes x2 faster, but sometimes x3
428  // slower, and the behavior depends also a lot on the compiler... This is why this re-writing strategy is currently
429  // enabled only when falling back from the main GEMM.
430  template <typename Dst, typename Func>
431  static EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE void eval_dynamic(Dst& dst, const Lhs& lhs, const Rhs& rhs,
432  const Func& func) {
433  enum {
437  };
438  // FIXME: in c++11 this should be auto, and extractScalarFactor should also return auto
439  // this is important for real*complex_mat
440  Scalar actualAlpha = combine_scalar_factors<Scalar>(lhs, rhs);
441 
442  eval_dynamic_impl(dst, blas_traits<Lhs>::extract(lhs).template conjugateIf<ConjLhs>(),
443  blas_traits<Rhs>::extract(rhs).template conjugateIf<ConjRhs>(), func, actualAlpha,
444  std::conditional_t<HasScalarFactor, true_type, false_type>());
445  }
446 
447  protected:
448  template <typename Dst, typename LhsT, typename RhsT, typename Func, typename Scalar>
449  static EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE void eval_dynamic_impl(Dst& dst, const LhsT& lhs, const RhsT& rhs,
450  const Func& func, const Scalar& s /* == 1 */,
451  false_type) {
454  call_restricted_packet_assignment_no_alias(dst, lhs.lazyProduct(rhs), func);
455  }
456 
457  template <typename Dst, typename LhsT, typename RhsT, typename Func, typename Scalar>
458  static EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE void eval_dynamic_impl(Dst& dst, const LhsT& lhs, const RhsT& rhs,
459  const Func& func, const Scalar& s, true_type) {
460  call_restricted_packet_assignment_no_alias(dst, s * lhs.lazyProduct(rhs), func);
461  }
462 };
463 
464 // This specialization enforces the use of a coefficient-based evaluation strategy
465 template <typename Lhs, typename Rhs>
467  : generic_product_impl<Lhs, Rhs, DenseShape, DenseShape, CoeffBasedProductMode> {};
468 
469 // Case 2: Evaluate coeff by coeff
470 //
471 // This is mostly taken from CoeffBasedProduct.h
472 // The main difference is that we add an extra argument to the etor_product_*_impl::run() function
473 // for the inner dimension of the product, because evaluator object do not know their size.
474 
475 template <int Traversal, int UnrollingIndex, typename Lhs, typename Rhs, typename RetScalar>
477 
478 template <int StorageOrder, int UnrollingIndex, typename Lhs, typename Rhs, typename Packet, int LoadMode>
480 
481 template <typename Lhs, typename Rhs, int ProductTag>
483  : evaluator_base<Product<Lhs, Rhs, LazyProduct>> {
485  typedef typename XprType::Scalar Scalar;
486  typedef typename XprType::CoeffReturnType CoeffReturnType;
487 
489  : m_lhs(xpr.lhs()),
490  m_rhs(xpr.rhs()),
491  m_lhsImpl(m_lhs), // FIXME the creation of the evaluator objects should result in a no-op, but check that!
492  m_rhsImpl(m_rhs), // Moreover, they are only useful for the packet path, so we could completely disable
493  // them when not needed, or perhaps declare them on the fly on the packet method... We
494  // have experiment to check what's best.
495  m_innerDim(xpr.lhs().cols()) {
498  EIGEN_INTERNAL_CHECK_COST_VALUE(CoeffReadCost);
499 #if 0
500  std::cerr << "LhsOuterStrideBytes= " << LhsOuterStrideBytes << "\n";
501  std::cerr << "RhsOuterStrideBytes= " << RhsOuterStrideBytes << "\n";
502  std::cerr << "LhsAlignment= " << LhsAlignment << "\n";
503  std::cerr << "RhsAlignment= " << RhsAlignment << "\n";
504  std::cerr << "CanVectorizeLhs= " << CanVectorizeLhs << "\n";
505  std::cerr << "CanVectorizeRhs= " << CanVectorizeRhs << "\n";
506  std::cerr << "CanVectorizeInner= " << CanVectorizeInner << "\n";
507  std::cerr << "EvalToRowMajor= " << EvalToRowMajor << "\n";
508  std::cerr << "Alignment= " << Alignment << "\n";
509  std::cerr << "Flags= " << Flags << "\n";
510 #endif
511  }
512 
513  // Everything below here is taken from CoeffBasedProduct.h
514 
517 
520 
523 
524  enum {
525  RowsAtCompileTime = LhsNestedCleaned::RowsAtCompileTime,
526  ColsAtCompileTime = RhsNestedCleaned::ColsAtCompileTime,
527  InnerSize = min_size_prefer_fixed(LhsNestedCleaned::ColsAtCompileTime, RhsNestedCleaned::RowsAtCompileTime),
528  MaxRowsAtCompileTime = LhsNestedCleaned::MaxRowsAtCompileTime,
529  MaxColsAtCompileTime = RhsNestedCleaned::MaxColsAtCompileTime
530  };
531 
534 
535  enum {
536 
537  LhsCoeffReadCost = LhsEtorType::CoeffReadCost,
538  RhsCoeffReadCost = RhsEtorType::CoeffReadCost,
539  CoeffReadCost = InnerSize == 0 ? NumTraits<Scalar>::ReadCost
540  : InnerSize == Dynamic
541  ? HugeCost
542  : InnerSize * (NumTraits<Scalar>::MulCost + int(LhsCoeffReadCost) + int(RhsCoeffReadCost)) +
543  (InnerSize - 1) * NumTraits<Scalar>::AddCost,
544 
545  Unroll = CoeffReadCost <= EIGEN_UNROLLING_LIMIT,
546 
547  LhsFlags = LhsEtorType::Flags,
548  RhsFlags = RhsEtorType::Flags,
549 
550  LhsRowMajor = LhsFlags & RowMajorBit,
551  RhsRowMajor = RhsFlags & RowMajorBit,
552 
553  LhsVecPacketSize = unpacket_traits<LhsVecPacketType>::size,
554  RhsVecPacketSize = unpacket_traits<RhsVecPacketType>::size,
555 
556  // Here, we don't care about alignment larger than the usable packet size.
557  LhsAlignment =
558  plain_enum_min(LhsEtorType::Alignment, LhsVecPacketSize* int(sizeof(typename LhsNestedCleaned::Scalar))),
559  RhsAlignment =
560  plain_enum_min(RhsEtorType::Alignment, RhsVecPacketSize* int(sizeof(typename RhsNestedCleaned::Scalar))),
561 
563 
564  CanVectorizeRhs = bool(RhsRowMajor) && (RhsFlags & PacketAccessBit) && (ColsAtCompileTime != 1),
565  CanVectorizeLhs = (!LhsRowMajor) && (LhsFlags & PacketAccessBit) && (RowsAtCompileTime != 1),
566 
567  EvalToRowMajor = (MaxRowsAtCompileTime == 1 && MaxColsAtCompileTime != 1) ? 1
568  : (MaxColsAtCompileTime == 1 && MaxRowsAtCompileTime != 1)
569  ? 0
570  : (bool(RhsRowMajor) && !CanVectorizeLhs),
571 
572  Flags = ((int(LhsFlags) | int(RhsFlags)) & HereditaryBits & ~RowMajorBit) |
573  (EvalToRowMajor ? RowMajorBit : 0)
574  // TODO enable vectorization for mixed types
575  | (SameType && (CanVectorizeLhs || CanVectorizeRhs) ? PacketAccessBit : 0) |
576  (XprType::IsVectorAtCompileTime ? LinearAccessBit : 0),
577 
578  LhsOuterStrideBytes =
579  int(LhsNestedCleaned::OuterStrideAtCompileTime) * int(sizeof(typename LhsNestedCleaned::Scalar)),
580  RhsOuterStrideBytes =
581  int(RhsNestedCleaned::OuterStrideAtCompileTime) * int(sizeof(typename RhsNestedCleaned::Scalar)),
582 
583  Alignment = bool(CanVectorizeLhs)
584  ? (LhsOuterStrideBytes <= 0 || (int(LhsOuterStrideBytes) % plain_enum_max(1, LhsAlignment)) != 0
585  ? 0
586  : LhsAlignment)
587  : bool(CanVectorizeRhs)
588  ? (RhsOuterStrideBytes <= 0 || (int(RhsOuterStrideBytes) % plain_enum_max(1, RhsAlignment)) != 0
589  ? 0
590  : RhsAlignment)
591  : 0,
592 
593  /* CanVectorizeInner deserves special explanation. It does not affect the product flags. It is not used outside
594  * of Product. If the Product itself is not a packet-access expression, there is still a chance that the inner
595  * loop of the product might be vectorized. This is the meaning of CanVectorizeInner. Since it doesn't affect
596  * the Flags, it is safe to make this value depend on ActualPacketAccessBit, that doesn't affect the ABI.
597  */
598  CanVectorizeInner = SameType && LhsRowMajor && (!RhsRowMajor) &&
599  (int(LhsFlags) & int(RhsFlags) & ActualPacketAccessBit) &&
600  (int(InnerSize) % packet_traits<Scalar>::size == 0)
601  };
602 
604  return (m_lhs.row(row).transpose().cwiseProduct(m_rhs.col(col))).sum();
605  }
606 
607  /* Allow index-based non-packet access. It is impossible though to allow index-based packed access,
608  * which is why we don't set the LinearAccessBit.
609  * TODO: this seems possible when the result is a vector
610  */
612  const Index row = (RowsAtCompileTime == 1 || MaxRowsAtCompileTime == 1) ? 0 : index;
613  const Index col = (RowsAtCompileTime == 1 || MaxRowsAtCompileTime == 1) ? index : 0;
614  return (m_lhs.row(row).transpose().cwiseProduct(m_rhs.col(col))).sum();
615  }
616 
617  template <int LoadMode, typename PacketType>
619  PacketType res;
621  Unroll ? int(InnerSize) : Dynamic, LhsEtorType, RhsEtorType, PacketType, LoadMode>
622  PacketImpl;
623  PacketImpl::run(row, col, m_lhsImpl, m_rhsImpl, m_innerDim, res);
624  return res;
625  }
626 
627  template <int LoadMode, typename PacketType>
629  const Index row = (RowsAtCompileTime == 1 || MaxRowsAtCompileTime == 1) ? 0 : index;
630  const Index col = (RowsAtCompileTime == 1 || MaxRowsAtCompileTime == 1) ? index : 0;
631  return packet<LoadMode, PacketType>(row, col);
632  }
633 
634  protected:
637 
640 
641  // TODO: Get rid of m_innerDim if known at compile time
643 };
644 
645 template <typename Lhs, typename Rhs>
647  : product_evaluator<Product<Lhs, Rhs, LazyProduct>, CoeffBasedProductMode, DenseShape, DenseShape> {
651  enum { Flags = Base::Flags | EvalBeforeNestingBit };
653  : Base(BaseProduct(xpr.lhs(), xpr.rhs())) {}
654 };
655 
656 /****************************************
657 *** Coeff based product, Packet path ***
658 ****************************************/
659 
660 template <int UnrollingIndex, typename Lhs, typename Rhs, typename Packet, int LoadMode>
661 struct etor_product_packet_impl<RowMajor, UnrollingIndex, Lhs, Rhs, Packet, LoadMode> {
662  static EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE void run(Index row, Index col, const Lhs& lhs, const Rhs& rhs,
663  Index innerDim, Packet& res) {
665  innerDim, res);
666  res = pmadd(pset1<Packet>(lhs.coeff(row, Index(UnrollingIndex - 1))),
667  rhs.template packet<LoadMode, Packet>(Index(UnrollingIndex - 1), col), res);
668  }
669 };
670 
671 template <int UnrollingIndex, typename Lhs, typename Rhs, typename Packet, int LoadMode>
672 struct etor_product_packet_impl<ColMajor, UnrollingIndex, Lhs, Rhs, Packet, LoadMode> {
673  static EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE void run(Index row, Index col, const Lhs& lhs, const Rhs& rhs,
674  Index innerDim, Packet& res) {
676  innerDim, res);
677  res = pmadd(lhs.template packet<LoadMode, Packet>(row, Index(UnrollingIndex - 1)),
678  pset1<Packet>(rhs.coeff(Index(UnrollingIndex - 1), col)), res);
679  }
680 };
681 
682 template <typename Lhs, typename Rhs, typename Packet, int LoadMode>
683 struct etor_product_packet_impl<RowMajor, 1, Lhs, Rhs, Packet, LoadMode> {
684  static EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE void run(Index row, Index col, const Lhs& lhs, const Rhs& rhs,
685  Index /*innerDim*/, Packet& res) {
686  res = pmul(pset1<Packet>(lhs.coeff(row, Index(0))), rhs.template packet<LoadMode, Packet>(Index(0), col));
687  }
688 };
689 
690 template <typename Lhs, typename Rhs, typename Packet, int LoadMode>
691 struct etor_product_packet_impl<ColMajor, 1, Lhs, Rhs, Packet, LoadMode> {
692  static EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE void run(Index row, Index col, const Lhs& lhs, const Rhs& rhs,
693  Index /*innerDim*/, Packet& res) {
694  res = pmul(lhs.template packet<LoadMode, Packet>(row, Index(0)), pset1<Packet>(rhs.coeff(Index(0), col)));
695  }
696 };
697 
698 template <typename Lhs, typename Rhs, typename Packet, int LoadMode>
699 struct etor_product_packet_impl<RowMajor, 0, Lhs, Rhs, Packet, LoadMode> {
700  static EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE void run(Index /*row*/, Index /*col*/, const Lhs& /*lhs*/,
701  const Rhs& /*rhs*/, Index /*innerDim*/, Packet& res) {
702  res = pset1<Packet>(typename unpacket_traits<Packet>::type(0));
703  }
704 };
705 
706 template <typename Lhs, typename Rhs, typename Packet, int LoadMode>
707 struct etor_product_packet_impl<ColMajor, 0, Lhs, Rhs, Packet, LoadMode> {
708  static EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE void run(Index /*row*/, Index /*col*/, const Lhs& /*lhs*/,
709  const Rhs& /*rhs*/, Index /*innerDim*/, Packet& res) {
710  res = pset1<Packet>(typename unpacket_traits<Packet>::type(0));
711  }
712 };
713 
714 template <typename Lhs, typename Rhs, typename Packet, int LoadMode>
716  static EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE void run(Index row, Index col, const Lhs& lhs, const Rhs& rhs,
717  Index innerDim, Packet& res) {
718  res = pset1<Packet>(typename unpacket_traits<Packet>::type(0));
719  for (Index i = 0; i < innerDim; ++i)
720  res = pmadd(pset1<Packet>(lhs.coeff(row, i)), rhs.template packet<LoadMode, Packet>(i, col), res);
721  }
722 };
723 
724 template <typename Lhs, typename Rhs, typename Packet, int LoadMode>
726  static EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE void run(Index row, Index col, const Lhs& lhs, const Rhs& rhs,
727  Index innerDim, Packet& res) {
728  res = pset1<Packet>(typename unpacket_traits<Packet>::type(0));
729  for (Index i = 0; i < innerDim; ++i)
730  res = pmadd(lhs.template packet<LoadMode, Packet>(row, i), pset1<Packet>(rhs.coeff(i, col)), res);
731  }
732 };
733 
734 /***************************************************************************
735  * Triangular products
736  ***************************************************************************/
737 template <int Mode, bool LhsIsTriangular, typename Lhs, bool LhsIsVector, typename Rhs, bool RhsIsVector>
739 
740 template <typename Lhs, typename Rhs, int ProductTag>
742  : generic_product_impl_base<Lhs, Rhs, generic_product_impl<Lhs, Rhs, TriangularShape, DenseShape, ProductTag>> {
744 
745  template <typename Dest>
746  static void scaleAndAddTo(Dest& dst, const Lhs& lhs, const Rhs& rhs, const Scalar& alpha) {
748  dst, lhs.nestedExpression(), rhs, alpha);
749  }
750 };
751 
752 template <typename Lhs, typename Rhs, int ProductTag>
754  : generic_product_impl_base<Lhs, Rhs, generic_product_impl<Lhs, Rhs, DenseShape, TriangularShape, ProductTag>> {
756 
757  template <typename Dest>
758  static void scaleAndAddTo(Dest& dst, const Lhs& lhs, const Rhs& rhs, const Scalar& alpha) {
760  dst, lhs, rhs.nestedExpression(), alpha);
761  }
762 };
763 
764 /***************************************************************************
765  * SelfAdjoint products
766  ***************************************************************************/
767 template <typename Lhs, int LhsMode, bool LhsIsVector, typename Rhs, int RhsMode, bool RhsIsVector>
769 
770 template <typename Lhs, typename Rhs, int ProductTag>
772  : generic_product_impl_base<Lhs, Rhs, generic_product_impl<Lhs, Rhs, SelfAdjointShape, DenseShape, ProductTag>> {
774 
775  template <typename Dest>
776  static EIGEN_DEVICE_FUNC void scaleAndAddTo(Dest& dst, const Lhs& lhs, const Rhs& rhs, const Scalar& alpha) {
778  dst, lhs.nestedExpression(), rhs, alpha);
779  }
780 };
781 
782 template <typename Lhs, typename Rhs, int ProductTag>
784  : generic_product_impl_base<Lhs, Rhs, generic_product_impl<Lhs, Rhs, DenseShape, SelfAdjointShape, ProductTag>> {
786 
787  template <typename Dest>
788  static void scaleAndAddTo(Dest& dst, const Lhs& lhs, const Rhs& rhs, const Scalar& alpha) {
790  dst, lhs, rhs.nestedExpression(), alpha);
791  }
792 };
793 
794 /***************************************************************************
795  * Diagonal products
796  ***************************************************************************/
797 
798 template <typename MatrixType, typename DiagonalType, typename Derived, int ProductOrder>
801 
802  public:
803  enum {
806 
809 
810  StorageOrder_ = (Derived::MaxRowsAtCompileTime == 1 && Derived::MaxColsAtCompileTime != 1) ? RowMajor
811  : (Derived::MaxColsAtCompileTime == 1 && Derived::MaxRowsAtCompileTime != 1) ? ColMajor
815 
816  ScalarAccessOnDiag_ = !((int(StorageOrder_) == ColMajor && int(ProductOrder) == OnTheLeft) ||
817  (int(StorageOrder_) == RowMajor && int(ProductOrder) == OnTheRight)),
819  // FIXME currently we need same types, but in the future the next rule should be the one
820  // Vectorizable_ = bool(int(MatrixFlags)&PacketAccessBit) && ((!_PacketOnDiag) || (SameTypes_ &&
821  // bool(int(DiagFlags)&PacketAccessBit))),
826  (MatrixType::RowsAtCompileTime == 1 || MatrixType::ColsAtCompileTime == 1) ? LinearAccessBit : 0,
827  Flags =
830 
832  (DiagonalType::SizeAtCompileTime == 1) ||
833  (DiagonalType::SizeAtCompileTime == Dynamic && MatrixType::RowsAtCompileTime == 1 &&
834  ProductOrder == OnTheLeft) ||
835  (DiagonalType::SizeAtCompileTime == Dynamic && MatrixType::ColsAtCompileTime == 1 && ProductOrder == OnTheRight)
836  };
837 
842  }
843 
845  if (AsScalarProduct)
846  return m_diagImpl.coeff(0) * m_matImpl.coeff(idx);
847  else
848  return m_diagImpl.coeff(idx) * m_matImpl.coeff(idx);
849  }
850 
851  protected:
852  template <int LoadMode, typename PacketType>
854  return internal::pmul(m_matImpl.template packet<LoadMode, PacketType>(row, col),
855  internal::pset1<PacketType>(m_diagImpl.coeff(id)));
856  }
857 
858  template <int LoadMode, typename PacketType>
860  enum {
861  InnerSize = (MatrixType::Flags & RowMajorBit) ? MatrixType::ColsAtCompileTime : MatrixType::RowsAtCompileTime,
862  DiagonalPacketLoadMode = plain_enum_min(
863  LoadMode,
864  ((InnerSize % 16) == 0) ? int(Aligned16) : int(evaluator<DiagonalType>::Alignment)) // FIXME hardcoded 16!!
865  };
866  return internal::pmul(m_matImpl.template packet<LoadMode, PacketType>(row, col),
867  m_diagImpl.template packet<DiagonalPacketLoadMode, PacketType>(id));
868  }
869 
872 };
873 
874 // diagonal * dense
875 template <typename Lhs, typename Rhs, int ProductKind, int ProductTag>
876 struct product_evaluator<Product<Lhs, Rhs, ProductKind>, ProductTag, DiagonalShape, DenseShape>
877  : diagonal_product_evaluator_base<Rhs, typename Lhs::DiagonalVectorType, Product<Lhs, Rhs, LazyProduct>,
878  OnTheLeft> {
880  OnTheLeft>
882  using Base::coeff;
883  using Base::m_diagImpl;
884  using Base::m_matImpl;
885  typedef typename Base::Scalar Scalar;
886 
888  typedef typename XprType::PlainObject PlainObject;
889  typedef typename Lhs::DiagonalVectorType DiagonalType;
890 
891  enum { StorageOrder = Base::StorageOrder_ };
892 
893  EIGEN_DEVICE_FUNC explicit product_evaluator(const XprType& xpr) : Base(xpr.rhs(), xpr.lhs().diagonal()) {}
894 
896  return m_diagImpl.coeff(row) * m_matImpl.coeff(row, col);
897  }
898 
899 #ifndef EIGEN_GPUCC
900  template <int LoadMode, typename PacketType>
902  // FIXME: NVCC used to complain about the template keyword, but we have to check whether this is still the case.
903  // See also similar calls below.
904  return this->template packet_impl<LoadMode, PacketType>(
905  row, col, row, std::conditional_t<int(StorageOrder) == RowMajor, internal::true_type, internal::false_type>());
906  }
907 
908  template <int LoadMode, typename PacketType>
910  return packet<LoadMode, PacketType>(int(StorageOrder) == ColMajor ? idx : 0,
911  int(StorageOrder) == ColMajor ? 0 : idx);
912  }
913 #endif
914 };
915 
916 // dense * diagonal
917 template <typename Lhs, typename Rhs, int ProductKind, int ProductTag>
920  OnTheRight> {
922  OnTheRight>
924  using Base::coeff;
925  using Base::m_diagImpl;
926  using Base::m_matImpl;
927  typedef typename Base::Scalar Scalar;
928 
930  typedef typename XprType::PlainObject PlainObject;
931 
932  enum { StorageOrder = Base::StorageOrder_ };
933 
934  EIGEN_DEVICE_FUNC explicit product_evaluator(const XprType& xpr) : Base(xpr.lhs(), xpr.rhs().diagonal()) {}
935 
937  return m_matImpl.coeff(row, col) * m_diagImpl.coeff(col);
938  }
939 
940 #ifndef EIGEN_GPUCC
941  template <int LoadMode, typename PacketType>
943  return this->template packet_impl<LoadMode, PacketType>(
944  row, col, col, std::conditional_t<int(StorageOrder) == ColMajor, internal::true_type, internal::false_type>());
945  }
946 
947  template <int LoadMode, typename PacketType>
949  return packet<LoadMode, PacketType>(int(StorageOrder) == ColMajor ? idx : 0,
950  int(StorageOrder) == ColMajor ? 0 : idx);
951  }
952 #endif
953 };
954 
955 /***************************************************************************
956  * Products with permutation matrices
957  ***************************************************************************/
958 
964 template <typename ExpressionType, int Side, bool Transposed, typename ExpressionShape>
966 
967 template <typename ExpressionType, int Side, bool Transposed>
971 
972  template <typename Dest, typename PermutationType>
973  static EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE void run(Dest& dst, const PermutationType& perm,
974  const ExpressionType& xpr) {
975  MatrixType mat(xpr);
976  const Index n = Side == OnTheLeft ? mat.rows() : mat.cols();
977  // FIXME we need an is_same for expression that is not sensitive to constness. For instance
978  // is_same_xpr<Block<const Matrix>, Block<Matrix> >::value should be true.
979  // if(is_same<MatrixTypeCleaned,Dest>::value && extract_data(dst) == extract_data(mat))
980  if (is_same_dense(dst, mat)) {
981  // apply the permutation inplace
983  mask.fill(false);
984  Index r = 0;
985  while (r < perm.size()) {
986  // search for the next seed
987  while (r < perm.size() && mask[r]) r++;
988  if (r >= perm.size()) break;
989  // we got one, let's follow it until we are back to the seed
990  Index k0 = r++;
991  Index kPrev = k0;
992  mask.coeffRef(k0) = true;
993  for (Index k = perm.indices().coeff(k0); k != k0; k = perm.indices().coeff(k)) {
994  Block<Dest, Side == OnTheLeft ? 1 : Dest::RowsAtCompileTime,
995  Side == OnTheRight ? 1 : Dest::ColsAtCompileTime>(dst, k)
996  .swap(Block < Dest, Side == OnTheLeft ? 1 : Dest::RowsAtCompileTime,
997  Side == OnTheRight
998  ? 1
999  : Dest::ColsAtCompileTime > (dst, ((Side == OnTheLeft) ^ Transposed) ? k0 : kPrev));
1000 
1001  mask.coeffRef(k) = true;
1002  kPrev = k;
1003  }
1004  }
1005  } else {
1006  for (Index i = 0; i < n; ++i) {
1008  dst, ((Side == OnTheLeft) ^ Transposed) ? perm.indices().coeff(i) : i)
1009 
1010  =
1011 
1012  Block < const MatrixTypeCleaned,
1013  Side == OnTheLeft ? 1 : MatrixTypeCleaned::RowsAtCompileTime,
1014  Side == OnTheRight ? 1
1015  : MatrixTypeCleaned::ColsAtCompileTime >
1016  (mat, ((Side == OnTheRight) ^ Transposed) ? perm.indices().coeff(i) : i);
1017  }
1018  }
1019  }
1020 };
1021 
1022 template <typename Lhs, typename Rhs, int ProductTag, typename MatrixShape>
1023 struct generic_product_impl<Lhs, Rhs, PermutationShape, MatrixShape, ProductTag> {
1024  template <typename Dest>
1025  static EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE void evalTo(Dest& dst, const Lhs& lhs, const Rhs& rhs) {
1027  }
1028 };
1029 
1030 template <typename Lhs, typename Rhs, int ProductTag, typename MatrixShape>
1031 struct generic_product_impl<Lhs, Rhs, MatrixShape, PermutationShape, ProductTag> {
1032  template <typename Dest>
1033  static EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE void evalTo(Dest& dst, const Lhs& lhs, const Rhs& rhs) {
1035  }
1036 };
1037 
1038 template <typename Lhs, typename Rhs, int ProductTag, typename MatrixShape>
1039 struct generic_product_impl<Inverse<Lhs>, Rhs, PermutationShape, MatrixShape, ProductTag> {
1040  template <typename Dest>
1041  static EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE void evalTo(Dest& dst, const Inverse<Lhs>& lhs, const Rhs& rhs) {
1043  }
1044 };
1045 
1046 template <typename Lhs, typename Rhs, int ProductTag, typename MatrixShape>
1047 struct generic_product_impl<Lhs, Inverse<Rhs>, MatrixShape, PermutationShape, ProductTag> {
1048  template <typename Dest>
1049  static EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE void evalTo(Dest& dst, const Lhs& lhs, const Inverse<Rhs>& rhs) {
1051  }
1052 };
1053 
1054 /***************************************************************************
1055  * Products with transpositions matrices
1056  ***************************************************************************/
1057 
1058 // FIXME could we unify Transpositions and Permutation into a single "shape"??
1059 
1064 template <typename ExpressionType, int Side, bool Transposed, typename ExpressionShape>
1068 
1069  template <typename Dest, typename TranspositionType>
1070  static EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE void run(Dest& dst, const TranspositionType& tr,
1071  const ExpressionType& xpr) {
1072  MatrixType mat(xpr);
1073  typedef typename TranspositionType::StorageIndex StorageIndex;
1074  const Index size = tr.size();
1075  StorageIndex j = 0;
1076 
1077  if (!is_same_dense(dst, mat)) dst = mat;
1078 
1079  for (Index k = (Transposed ? size - 1 : 0); Transposed ? k >= 0 : k < size; Transposed ? --k : ++k)
1080  if (Index(j = tr.coeff(k)) != k) {
1081  if (Side == OnTheLeft)
1082  dst.row(k).swap(dst.row(j));
1083  else if (Side == OnTheRight)
1084  dst.col(k).swap(dst.col(j));
1085  }
1086  }
1087 };
1088 
1089 template <typename Lhs, typename Rhs, int ProductTag, typename MatrixShape>
1090 struct generic_product_impl<Lhs, Rhs, TranspositionsShape, MatrixShape, ProductTag> {
1091  template <typename Dest>
1092  static EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE void evalTo(Dest& dst, const Lhs& lhs, const Rhs& rhs) {
1094  }
1095 };
1096 
1097 template <typename Lhs, typename Rhs, int ProductTag, typename MatrixShape>
1098 struct generic_product_impl<Lhs, Rhs, MatrixShape, TranspositionsShape, ProductTag> {
1099  template <typename Dest>
1100  static EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE void evalTo(Dest& dst, const Lhs& lhs, const Rhs& rhs) {
1102  }
1103 };
1104 
1105 template <typename Lhs, typename Rhs, int ProductTag, typename MatrixShape>
1106 struct generic_product_impl<Transpose<Lhs>, Rhs, TranspositionsShape, MatrixShape, ProductTag> {
1107  template <typename Dest>
1108  static EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE void evalTo(Dest& dst, const Transpose<Lhs>& lhs, const Rhs& rhs) {
1110  }
1111 };
1112 
1113 template <typename Lhs, typename Rhs, int ProductTag, typename MatrixShape>
1114 struct generic_product_impl<Lhs, Transpose<Rhs>, MatrixShape, TranspositionsShape, ProductTag> {
1115  template <typename Dest>
1116  static EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE void evalTo(Dest& dst, const Lhs& lhs, const Transpose<Rhs>& rhs) {
1118  }
1119 };
1120 
1121 /***************************************************************************
1122  * skew symmetric products
1123  * for now we just call the generic implementation
1124  ***************************************************************************/
1125 template <typename Lhs, typename Rhs, int ProductTag, typename MatrixShape>
1126 struct generic_product_impl<Lhs, Rhs, SkewSymmetricShape, MatrixShape, ProductTag> {
1127  template <typename Dest>
1128  static EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE void evalTo(Dest& dst, const Lhs& lhs, const Rhs& rhs) {
1130  rhs);
1131  }
1132 };
1133 
1134 template <typename Lhs, typename Rhs, int ProductTag, typename MatrixShape>
1135 struct generic_product_impl<Lhs, Rhs, MatrixShape, SkewSymmetricShape, ProductTag> {
1136  template <typename Dest>
1137  static EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE void evalTo(Dest& dst, const Lhs& lhs, const Rhs& rhs) {
1139  rhs);
1140  }
1141 };
1142 
1143 template <typename Lhs, typename Rhs, int ProductTag>
1145  template <typename Dest>
1146  static EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE void evalTo(Dest& dst, const Lhs& lhs, const Rhs& rhs) {
1147  generic_product_impl<typename Lhs::DenseMatrixType, typename Rhs::DenseMatrixType, DenseShape, DenseShape,
1148  ProductTag>::evalTo(dst, lhs, rhs);
1149  }
1150 };
1151 
1152 } // end namespace internal
1153 
1154 } // end namespace Eigen
1155 
1156 #endif // EIGEN_PRODUCT_EVALUATORS_H
int i
Definition: BiCGSTAB_step_by_step.cpp:9
const unsigned n
Definition: CG3DPackingUnitTest.cpp:11
Eigen::SparseMatrix< double > mat
Definition: EigenUnitTest.cpp:10
#define eigen_internal_assert(x)
Definition: Macros.h:916
#define EIGEN_UNUSED_VARIABLE(var)
Definition: Macros.h:966
#define EIGEN_DEVICE_FUNC
Definition: Macros.h:892
#define eigen_assert(x)
Definition: Macros.h:910
#define EIGEN_STRONG_INLINE
Definition: Macros.h:834
m col(1)
m row(1)
#define ei_declare_local_nested_eval(XPR_T, XPR, N, NAME)
Definition: Memory.h:812
cout<< "Here is the matrix m:"<< endl<< m<< endl;Matrix< ptrdiff_t, 3, 1 > res
Definition: PartialRedux_count.cpp:3
#define EIGEN_UNROLLING_LIMIT
Definition: Settings.h:23
Side
Definition: Side.h:9
#define EIGEN_INTERNAL_CHECK_COST_VALUE(C)
Definition: StaticAssert.h:101
int rows
Definition: Tutorial_commainit_02.cpp:1
int cols
Definition: Tutorial_commainit_02.cpp:1
Scalar Scalar int size
Definition: benchVecAdd.cpp:17
SCALAR Scalar
Definition: bench_gemm.cpp:45
MatrixXf MatrixType
Definition: benchmark-blocking-sizes.cpp:52
Expression of a fixed-size or dynamic-size block.
Definition: Block.h:110
Generic expression where a coefficient-wise binary operator is applied to two expressions.
Definition: CwiseBinaryOp.h:79
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const RhsNested_ & rhs() const
Definition: CwiseBinaryOp.h:125
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const LhsNested_ & lhs() const
Definition: CwiseBinaryOp.h:123
Generic expression of a matrix where all coefficients are defined by a functor.
Definition: CwiseNullaryOp.h:64
Expression of a diagonal/subdiagonal/superdiagonal in a matrix.
Definition: Diagonal.h:68
Expression of the inverse of another expression.
Definition: Inverse.h:43
EIGEN_DEVICE_FUNC const XprTypeNestedCleaned & nestedExpression() const
Definition: Inverse.h:57
The matrix class, also used for vectors and row-vectors.
Definition: Eigen/Eigen/src/Core/Matrix.h:186
EIGEN_DEVICE_FUNC constexpr EIGEN_STRONG_INLINE Scalar & coeffRef(Index rowId, Index colId)
Definition: PlainObjectBase.h:217
Expression of the product of two arbitrary matrices or vectors.
Definition: Product.h:202
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE EIGEN_CONSTEXPR Index rows() const EIGEN_NOEXCEPT
Definition: Product.h:227
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const LhsNestedCleaned & lhs() const
Definition: Product.h:230
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const RhsNestedCleaned & rhs() const
Definition: Product.h:231
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE EIGEN_CONSTEXPR Index cols() const EIGEN_NOEXCEPT
Definition: Product.h:228
Scalar coeff(Index row, Index col) const
Definition: SparseMatrix.h:211
void swap(SparseMatrix &other)
Definition: SparseMatrix.h:829
Index cols() const
Definition: SparseMatrix.h:161
Index rows() const
Definition: SparseMatrix.h:159
Expression of the transpose of a matrix.
Definition: Transpose.h:56
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const internal::remove_all_t< MatrixTypeNested > & nestedExpression() const
Definition: Transpose.h:72
void diagonal(const MatrixType &m)
Definition: diagonal.cpp:13
@ GemvProduct
Definition: Constants.h:510
@ LazyProduct
Definition: Constants.h:504
@ InnerProduct
Definition: Constants.h:509
@ DefaultProduct
Definition: Constants.h:503
@ CoeffBasedProductMode
Definition: Constants.h:506
@ OuterProduct
Definition: Constants.h:508
@ LazyCoeffBasedProductMode
Definition: Constants.h:507
@ Aligned16
Definition: Constants.h:237
@ ColMajor
Definition: Constants.h:318
@ RowMajor
Definition: Constants.h:320
@ OnTheLeft
Definition: Constants.h:331
@ OnTheRight
Definition: Constants.h:333
const unsigned int PacketAccessBit
Definition: Constants.h:97
const unsigned int LinearAccessBit
Definition: Constants.h:133
const unsigned int EvalBeforeNestingBit
Definition: Constants.h:74
const unsigned int RowMajorBit
Definition: Constants.h:70
RealScalar s
Definition: level1_cplx_impl.h:130
return int(ret)+1
RealScalar alpha
Definition: level1_cplx_impl.h:151
func(actual_m, actual_n, a, *lda, actual_b, 1, actual_c, 1, alpha)
const char const char const char * diag
Definition: level2_impl.h:86
char char char int int * k
Definition: level2_impl.h:374
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE void call_restricted_packet_assignment_no_alias(Dst &dst, const Src &src, const Func &func)
Definition: AssignEvaluator.h:833
constexpr int plain_enum_min(A a, B b)
Definition: Meta.h:649
@ Lhs
Definition: TensorContractionMapper.h:20
@ Rhs
Definition: TensorContractionMapper.h:20
constexpr int plain_enum_max(A a, B b)
Definition: Meta.h:656
EIGEN_CATCH_ASSIGN_XPR_OP_PRODUCT(assign_op, scalar_sum_op, add_assign_op)
constexpr int min_size_prefer_fixed(A a, B b)
Definition: Meta.h:683
EIGEN_STRONG_INLINE Packet4f pmadd(const Packet4f &a, const Packet4f &b, const Packet4f &c)
Definition: AltiVec/PacketMath.h:1218
EIGEN_STRONG_INLINE Packet4cf pmul(const Packet4cf &a, const Packet4cf &b)
Definition: AVX/Complex.h:88
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE EIGEN_CONSTEXPR void call_assignment_no_alias(Dst &dst, const Src &src, const Func &func)
Definition: AssignEvaluator.h:812
void EIGEN_DEVICE_FUNC outer_product_selector_run(Dst &dst, const Lhs &lhs, const Rhs &rhs, const Func &func, const false_type &)
Definition: ProductEvaluators.h:261
typename remove_all< T >::type remove_all_t
Definition: Meta.h:142
EIGEN_DEVICE_FUNC bool is_same_dense(const T1 &mat1, const T2 &mat2, std::enable_if_t< possibly_same_dense< T1, T2 >::value > *=0)
Definition: XprHelper.h:869
void swap(scoped_array< T > &a, scoped_array< T > &b)
Definition: Memory.h:734
typename add_const_on_value_type< T >::type add_const_on_value_type_t
Definition: Meta.h:274
EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC bool is_exactly_one(const X &x)
Definition: Meta.h:601
Namespace containing all symbols from the Eigen library.
Definition: bench_norm.cpp:70
const unsigned int ActualPacketAccessBit
Definition: Constants.h:110
auto run(Kernel kernel, Args &&... args) -> decltype(kernel(args...))
Definition: gpu_test_helper.h:414
const unsigned int HereditaryBits
Definition: Constants.h:198
const int HugeCost
Definition: Constants.h:48
EIGEN_DEFAULT_DENSE_INDEX_TYPE Index
The Index type as used for the API.
Definition: Meta.h:83
const int Dynamic
Definition: Constants.h:25
Extend namespace for flags.
Definition: fsi_chan_precond_driver.cc:56
r
Definition: UniformPSDSelfTest.py:20
Definition: Eigen_Colamd.h:49
void product(const MatrixType &m)
Definition: product.h:42
void set(Container &c, Position position, const Value &value)
Definition: stdlist_overload.cpp:36
Definition: Constants.h:540
Definition: Constants.h:549
Holds information about the various numeric (i.e. scalar) types allowed by Eigen.
Definition: NumTraits.h:217
Definition: TensorMeta.h:47
Definition: Constants.h:564
Determines whether the given binary operation of two numeric types is allowed and what the scalar ret...
Definition: XprHelper.h:1043
Definition: Constants.h:561
Definition: Constants.h:552
Definition: Constants.h:567
Definition: Constants.h:558
CwiseBinaryOp< internal::scalar_product_op< ScalarBis, Scalar >, const CwiseNullaryOp< internal::scalar_constant_op< ScalarBis >, Plain >, const Product< Lhs, Rhs, DefaultProduct > > SrcXprType
Definition: ProductEvaluators.h:176
static EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE void run(DstXprType &dst, const SrcXprType &src, const internal::assign_op< Scalar, Scalar > &)
Definition: ProductEvaluators.h:127
static EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE void run(DstXprType &dst, const SrcXprType &src, const internal::add_assign_op< Scalar, Scalar > &)
Definition: ProductEvaluators.h:142
static EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE void run(DstXprType &dst, const SrcXprType &src, const internal::sub_assign_op< Scalar, Scalar > &)
Definition: ProductEvaluators.h:155
Definition: AssignEvaluator.h:773
Definition: AssignEvaluator.h:756
Template functor for scalar/packet assignment with addition.
Definition: AssignmentFunctors.h:52
Template functor for scalar/packet assignment.
Definition: AssignmentFunctors.h:25
Definition: ProductEvaluators.h:206
static EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE void run(DstXprType &dst, const SrcXprType &src, const InitialFunc &)
Definition: ProductEvaluators.h:208
Definition: BlasUtil.h:459
Definition: InnerProduct.h:232
Definition: ProductEvaluators.h:799
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const Scalar coeff(Index idx) const
Definition: ProductEvaluators.h:844
EIGEN_STRONG_INLINE PacketType packet_impl(Index row, Index col, Index id, internal::true_type) const
Definition: ProductEvaluators.h:853
@ DiagFlags
Definition: ProductEvaluators.h:808
@ CoeffReadCost
Definition: ProductEvaluators.h:804
@ SameTypes_
Definition: ProductEvaluators.h:818
@ StorageOrder_
Definition: ProductEvaluators.h:810
@ SameStorageOrder_
Definition: ProductEvaluators.h:814
@ AsScalarProduct
Definition: ProductEvaluators.h:831
@ ScalarAccessOnDiag_
Definition: ProductEvaluators.h:816
@ LinearAccessMask_
Definition: ProductEvaluators.h:825
@ Vectorizable_
Definition: ProductEvaluators.h:822
@ Alignment
Definition: ProductEvaluators.h:829
@ MatrixFlags
Definition: ProductEvaluators.h:807
evaluator< DiagonalType > m_diagImpl
Definition: ProductEvaluators.h:870
evaluator< MatrixType > m_matImpl
Definition: ProductEvaluators.h:871
EIGEN_STRONG_INLINE PacketType packet_impl(Index row, Index col, Index id, internal::false_type) const
Definition: ProductEvaluators.h:859
ScalarBinaryOpTraits< typename MatrixType::Scalar, typename DiagonalType::Scalar >::ReturnType Scalar
Definition: ProductEvaluators.h:800
EIGEN_DEVICE_FUNC diagonal_product_evaluator_base(const MatrixType &mat, const DiagonalType &diag)
Definition: ProductEvaluators.h:838
Definition: ProductEvaluators.h:476
static EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE void run(Index, Index, const Lhs &, const Rhs &, Index, Packet &res)
Definition: ProductEvaluators.h:708
static EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE void run(Index row, Index col, const Lhs &lhs, const Rhs &rhs, Index, Packet &res)
Definition: ProductEvaluators.h:692
static EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE void run(Index row, Index col, const Lhs &lhs, const Rhs &rhs, Index innerDim, Packet &res)
Definition: ProductEvaluators.h:726
static EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE void run(Index row, Index col, const Lhs &lhs, const Rhs &rhs, Index innerDim, Packet &res)
Definition: ProductEvaluators.h:673
static EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE void run(Index, Index, const Lhs &, const Rhs &, Index, Packet &res)
Definition: ProductEvaluators.h:700
static EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE void run(Index row, Index col, const Lhs &lhs, const Rhs &rhs, Index, Packet &res)
Definition: ProductEvaluators.h:684
static EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE void run(Index row, Index col, const Lhs &lhs, const Rhs &rhs, Index innerDim, Packet &res)
Definition: ProductEvaluators.h:716
static EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE void run(Index row, Index col, const Lhs &lhs, const Rhs &rhs, Index innerDim, Packet &res)
Definition: ProductEvaluators.h:662
Definition: ProductEvaluators.h:479
CwiseBinaryOp< internal::scalar_product_op< Scalar1, Scalar2 >, const CwiseNullaryOp< internal::scalar_constant_op< Scalar1 >, Plain1 >, const Product< Lhs, Rhs, DefaultProduct > > XprType
Definition: ProductEvaluators.h:54
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE evaluator(const XprType &xpr)
Definition: ProductEvaluators.h:67
Diagonal< const Product< Lhs, Rhs, DefaultProduct >, DiagIndex > XprType
Definition: ProductEvaluators.h:64
evaluator< Diagonal< const Product< Lhs, Rhs, LazyProduct >, DiagIndex > > Base
Definition: ProductEvaluators.h:65
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE evaluator(const XprType &xpr)
Definition: ProductEvaluators.h:35
product_evaluator< XprType > Base
Definition: ProductEvaluators.h:33
Product< Lhs, Rhs, Options > XprType
Definition: ProductEvaluators.h:32
Definition: CoreEvaluators.h:98
static const bool value
Definition: CoreEvaluators.h:99
Definition: CoreEvaluators.h:118
storage_kind_to_shape< typename traits< T >::StorageKind >::Shape Shape
Definition: CoreEvaluators.h:90
Definition: CoreEvaluators.h:104
unary_evaluator< T > Base
Definition: CoreEvaluators.h:105
Definition: Meta.h:97
find_best_packet_helper< Size, typename packet_traits< T >::type >::type type
Definition: XprHelper.h:290
Definition: GeneralProduct.h:221
static EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE void evalTo(Dest &dst, const Inverse< Lhs > &lhs, const Rhs &rhs)
Definition: ProductEvaluators.h:1041
static EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE void evalTo(Dest &dst, const Lhs &lhs, const Inverse< Rhs > &rhs)
Definition: ProductEvaluators.h:1049
static EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE void eval_dynamic(Dst &dst, const Lhs &lhs, const Rhs &rhs, const Func &func)
Definition: ProductEvaluators.h:431
static EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE void eval_dynamic_impl(Dst &dst, const LhsT &lhs, const RhsT &rhs, const Func &func, const Scalar &s, false_type)
Definition: ProductEvaluators.h:449
static EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE void eval_dynamic_impl(Dst &dst, const LhsT &lhs, const RhsT &rhs, const Func &func, const Scalar &s, true_type)
Definition: ProductEvaluators.h:458
static EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE void evalTo(Dst &dst, const Lhs &lhs, const Rhs &rhs)
Definition: ProductEvaluators.h:398
static EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE void addTo(Dst &dst, const Lhs &lhs, const Rhs &rhs)
Definition: ProductEvaluators.h:405
static EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE void subTo(Dst &dst, const Lhs &lhs, const Rhs &rhs)
Definition: ProductEvaluators.h:411
EIGEN_DEVICE_FUNC void operator()(const Dst &dst, const Src &src) const
Definition: ProductEvaluators.h:304
EIGEN_DEVICE_FUNC void operator()(const Dst &dst, const Src &src) const
Definition: ProductEvaluators.h:298
EIGEN_DEVICE_FUNC void operator()(const Dst &dst, const Src &src) const
Definition: ProductEvaluators.h:292
void EIGEN_DEVICE_FUNC operator()(const Dst &dst, const Src &src) const
Definition: ProductEvaluators.h:312
nested_eval< Lhs, 1 >::type LhsNested
Definition: ProductEvaluators.h:370
nested_eval< Rhs, 1 >::type RhsNested
Definition: ProductEvaluators.h:371
static EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE void scaleAndAddTo(Dest &dst, const Lhs &lhs, const Rhs &rhs, const Scalar &alpha)
Definition: ProductEvaluators.h:377
Product< Lhs, Rhs >::Scalar Scalar
Definition: ProductEvaluators.h:372
internal::remove_all_t< std::conditional_t< int(Side)==OnTheRight, LhsNested, RhsNested > > MatrixType
Definition: ProductEvaluators.h:374
static EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE void subTo(Dst &dst, const Lhs &lhs, const Rhs &rhs)
Definition: ProductEvaluators.h:250
static EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE void evalTo(Dst &dst, const Lhs &lhs, const Rhs &rhs)
Definition: ProductEvaluators.h:240
static EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE void addTo(Dst &dst, const Lhs &lhs, const Rhs &rhs)
Definition: ProductEvaluators.h:245
static EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE void evalTo(Dst &dst, const Lhs &lhs, const Rhs &rhs)
Definition: ProductEvaluators.h:318
static EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE void subTo(Dst &dst, const Lhs &lhs, const Rhs &rhs)
Definition: ProductEvaluators.h:328
static EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE void scaleAndAddTo(Dst &dst, const Lhs &lhs, const Rhs &rhs, const Scalar &alpha)
Definition: ProductEvaluators.h:333
static EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE void addTo(Dst &dst, const Lhs &lhs, const Rhs &rhs)
Definition: ProductEvaluators.h:323
Product< Lhs, Rhs >::Scalar Scalar
Definition: ProductEvaluators.h:287
Product< Lhs, Rhs >::Scalar Scalar
Definition: ProductEvaluators.h:785
static void scaleAndAddTo(Dest &dst, const Lhs &lhs, const Rhs &rhs, const Scalar &alpha)
Definition: ProductEvaluators.h:788
static void scaleAndAddTo(Dest &dst, const Lhs &lhs, const Rhs &rhs, const Scalar &alpha)
Definition: ProductEvaluators.h:758
Product< Lhs, Rhs >::Scalar Scalar
Definition: ProductEvaluators.h:755
static EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE void evalTo(Dest &dst, const Lhs &lhs, const Rhs &rhs)
Definition: ProductEvaluators.h:1033
static EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE void evalTo(Dest &dst, const Lhs &lhs, const Rhs &rhs)
Definition: ProductEvaluators.h:1137
static EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE void evalTo(Dest &dst, const Lhs &lhs, const Rhs &rhs)
Definition: ProductEvaluators.h:1100
static EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE void evalTo(Dest &dst, const Lhs &lhs, const Rhs &rhs)
Definition: ProductEvaluators.h:1025
Product< Lhs, Rhs >::Scalar Scalar
Definition: ProductEvaluators.h:773
static EIGEN_DEVICE_FUNC void scaleAndAddTo(Dest &dst, const Lhs &lhs, const Rhs &rhs, const Scalar &alpha)
Definition: ProductEvaluators.h:776
static EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE void evalTo(Dest &dst, const Lhs &lhs, const Rhs &rhs)
Definition: ProductEvaluators.h:1146
static EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE void evalTo(Dest &dst, const Lhs &lhs, const Rhs &rhs)
Definition: ProductEvaluators.h:1128
static EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE void evalTo(Dest &dst, const Lhs &lhs, const Rhs &rhs)
Definition: ProductEvaluators.h:1092
Product< Lhs, Rhs >::Scalar Scalar
Definition: ProductEvaluators.h:743
static void scaleAndAddTo(Dest &dst, const Lhs &lhs, const Rhs &rhs, const Scalar &alpha)
Definition: ProductEvaluators.h:746
static EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE void evalTo(Dest &dst, const Lhs &lhs, const Transpose< Rhs > &rhs)
Definition: ProductEvaluators.h:1116
static EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE void evalTo(Dest &dst, const Transpose< Lhs > &lhs, const Rhs &rhs)
Definition: ProductEvaluators.h:1108
Definition: ProductEvaluators.h:341
static EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE void scaleAndAddTo(Dst &dst, const Lhs &lhs, const Rhs &rhs, const Scalar &alpha)
Definition: ProductEvaluators.h:361
static EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE void addTo(Dst &dst, const Lhs &lhs, const Rhs &rhs)
Definition: ProductEvaluators.h:351
static EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE void subTo(Dst &dst, const Lhs &lhs, const Rhs &rhs)
Definition: ProductEvaluators.h:356
static EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE void evalTo(Dst &dst, const Lhs &lhs, const Rhs &rhs)
Definition: ProductEvaluators.h:345
Product< Lhs, Rhs >::Scalar Scalar
Definition: ProductEvaluators.h:342
Definition: ProductEvaluators.h:78
Definition: Meta.h:205
std::conditional_t< Evaluate, PlainObject, typename ref_selector< T >::type > type
Definition: XprHelper.h:549
Definition: GenericPacketMath.h:108
remove_all_t< MatrixType > MatrixTypeCleaned
Definition: ProductEvaluators.h:970
static EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE void run(Dest &dst, const PermutationType &perm, const ExpressionType &xpr)
Definition: ProductEvaluators.h:973
nested_eval< ExpressionType, 1 >::type MatrixType
Definition: ProductEvaluators.h:969
Definition: ProductEvaluators.h:965
product_evaluator< BaseProduct, CoeffBasedProductMode, DenseShape, DenseShape > Base
Definition: ProductEvaluators.h:650
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE product_evaluator(const XprType &xpr)
Definition: ProductEvaluators.h:652
find_best_packet< Scalar, ColsAtCompileTime >::type RhsVecPacketType
Definition: ProductEvaluators.h:533
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const CoeffReturnType coeff(Index index) const
Definition: ProductEvaluators.h:611
internal::remove_all_t< RhsNested > RhsNestedCleaned
Definition: ProductEvaluators.h:519
internal::nested_eval< Lhs, Rhs::ColsAtCompileTime >::type LhsNested
Definition: ProductEvaluators.h:515
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const PacketType packet(Index index) const
Definition: ProductEvaluators.h:628
internal::remove_all_t< LhsNested > LhsNestedCleaned
Definition: ProductEvaluators.h:518
find_best_packet< Scalar, RowsAtCompileTime >::type LhsVecPacketType
Definition: ProductEvaluators.h:532
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE product_evaluator(const XprType &xpr)
Definition: ProductEvaluators.h:488
add_const_on_value_type_t< LhsNested > m_lhs
Definition: ProductEvaluators.h:635
internal::nested_eval< Rhs, Lhs::RowsAtCompileTime >::type RhsNested
Definition: ProductEvaluators.h:516
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const PacketType packet(Index row, Index col) const
Definition: ProductEvaluators.h:618
add_const_on_value_type_t< RhsNested > m_rhs
Definition: ProductEvaluators.h:636
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const CoeffReturnType coeff(Index row, Index col) const
Definition: ProductEvaluators.h:603
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE product_evaluator(const XprType &xpr)
Definition: ProductEvaluators.h:95
EIGEN_DEVICE_FUNC product_evaluator(const XprType &xpr)
Definition: ProductEvaluators.h:934
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const Scalar coeff(Index row, Index col) const
Definition: ProductEvaluators.h:936
diagonal_product_evaluator_base< Lhs, typename Rhs::DiagonalVectorType, Product< Lhs, Rhs, LazyProduct >, OnTheRight > Base
Definition: ProductEvaluators.h:923
EIGEN_STRONG_INLINE PacketType packet(Index idx) const
Definition: ProductEvaluators.h:948
EIGEN_STRONG_INLINE PacketType packet(Index row, Index col) const
Definition: ProductEvaluators.h:942
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const Scalar coeff(Index row, Index col) const
Definition: ProductEvaluators.h:895
EIGEN_STRONG_INLINE PacketType packet(Index row, Index col) const
Definition: ProductEvaluators.h:901
diagonal_product_evaluator_base< Rhs, typename Lhs::DiagonalVectorType, Product< Lhs, Rhs, LazyProduct >, OnTheLeft > Base
Definition: ProductEvaluators.h:881
EIGEN_DEVICE_FUNC product_evaluator(const XprType &xpr)
Definition: ProductEvaluators.h:893
EIGEN_STRONG_INLINE PacketType packet(Index idx) const
Definition: ProductEvaluators.h:909
Definition: ForwardDeclarations.h:221
Definition: GeneralProduct.h:52
Template functor to compute the difference of two scalars.
Definition: BinaryFunctors.h:381
Template functor to compute the product of two scalars.
Definition: BinaryFunctors.h:73
Template functor to compute the sum of two scalars.
Definition: BinaryFunctors.h:34
Definition: ProductEvaluators.h:768
Template functor for scalar/packet assignment with subtraction.
Definition: AssignmentFunctors.h:73
Definition: ProductEvaluators.h:1065
static EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE void run(Dest &dst, const TranspositionType &tr, const ExpressionType &xpr)
Definition: ProductEvaluators.h:1070
nested_eval< ExpressionType, 1 >::type MatrixType
Definition: ProductEvaluators.h:1066
remove_all_t< MatrixType > MatrixTypeCleaned
Definition: ProductEvaluators.h:1067
Definition: ProductEvaluators.h:738
Definition: Meta.h:94
Definition: GenericPacketMath.h:134
Definition: benchGeometry.cpp:21
EIGEN_DONT_INLINE T sub(T a, T b)
Definition: svd_common.h:238
std::ptrdiff_t j
Definition: tut_arithmetic_redux_minmax.cpp:2
void run(const string &dir_name, LinearSolver *linear_solver_pt, const unsigned nel_1d, bool mess_up_order)
Definition: two_d_poisson_compare_solvers.cc:317
Definition: ZVector/PacketMath.h:50