LCOV - code coverage report
Current view: top level - Core/functors - AssignmentFunctors.h (source / functions) Hit Total Coverage
Test: coverage.info.cleaned Lines: 16 16 100.0 %
Date: 1980-01-01 00:00:00 Functions: 14 14 100.0 %
Branches: 0 0 -

           Branch data     Line data    Source code
       1                 :            : // This file is part of Eigen, a lightweight C++ template library
       2                 :            : // for linear algebra.
       3                 :            : //
       4                 :            : // Copyright (C) 2008-2010 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_ASSIGNMENT_FUNCTORS_H
      11                 :            : #define EIGEN_ASSIGNMENT_FUNCTORS_H
      12                 :            : 
      13                 :            : namespace Eigen {
      14                 :            : 
      15                 :            : namespace internal {
      16                 :            :   
      17                 :            : /** \internal
      18                 :            :   * \brief Template functor for scalar/packet assignment
      19                 :            :   *
      20                 :            :   */
      21                 :            : template<typename DstScalar,typename SrcScalar> struct assign_op {
      22                 :            : 
      23                 :      81448 :   EIGEN_EMPTY_STRUCT_CTOR(assign_op)
      24                 :     111174 :   EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE void assignCoeff(DstScalar& a, const SrcScalar& b) const { a = b; }
      25                 :            :   
      26                 :            :   template<int Alignment, typename Packet>
      27                 :      66865 :   EIGEN_STRONG_INLINE void assignPacket(DstScalar* a, const Packet& b) const
      28                 :      66865 :   { internal::pstoret<DstScalar,Packet,Alignment>(a,b); }
      29                 :            : };
      30                 :            : 
      31                 :            : // Empty overload for void type (used by PermutationMatrix)
      32                 :            : template<typename DstScalar> struct assign_op<DstScalar,void> {};
      33                 :            : 
      34                 :            : template<typename DstScalar,typename SrcScalar>
      35                 :            : struct functor_traits<assign_op<DstScalar,SrcScalar> > {
      36                 :            :   enum {
      37                 :            :     Cost = NumTraits<DstScalar>::ReadCost,
      38                 :            :     PacketAccess = is_same<DstScalar,SrcScalar>::value && packet_traits<DstScalar>::Vectorizable && packet_traits<SrcScalar>::Vectorizable
      39                 :            :   };
      40                 :            : };
      41                 :            : 
      42                 :            : /** \internal
      43                 :            :   * \brief Template functor for scalar/packet assignment with addition
      44                 :            :   *
      45                 :            :   */
      46                 :            : template<typename DstScalar,typename SrcScalar> struct add_assign_op {
      47                 :            : 
      48                 :       1000 :   EIGEN_EMPTY_STRUCT_CTOR(add_assign_op)
      49                 :       1000 :   EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE void assignCoeff(DstScalar& a, const SrcScalar& b) const { a += b; }
      50                 :            :   
      51                 :            :   template<int Alignment, typename Packet>
      52                 :       1000 :   EIGEN_STRONG_INLINE void assignPacket(DstScalar* a, const Packet& b) const
      53                 :       1000 :   { internal::pstoret<DstScalar,Packet,Alignment>(a,internal::padd(internal::ploadt<Packet,Alignment>(a),b)); }
      54                 :            : };
      55                 :            : template<typename DstScalar,typename SrcScalar>
      56                 :            : struct functor_traits<add_assign_op<DstScalar,SrcScalar> > {
      57                 :            :   enum {
      58                 :            :     Cost = NumTraits<DstScalar>::ReadCost + NumTraits<DstScalar>::AddCost,
      59                 :            :     PacketAccess = is_same<DstScalar,SrcScalar>::value && packet_traits<DstScalar>::HasAdd
      60                 :            :   };
      61                 :            : };
      62                 :            : 
      63                 :            : /** \internal
      64                 :            :   * \brief Template functor for scalar/packet assignment with subtraction
      65                 :            :   *
      66                 :            :   */
      67                 :            : template<typename DstScalar,typename SrcScalar> struct sub_assign_op {
      68                 :            : 
      69                 :            :   EIGEN_EMPTY_STRUCT_CTOR(sub_assign_op)
      70                 :            :   EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE void assignCoeff(DstScalar& a, const SrcScalar& b) const { a -= b; }
      71                 :            :   
      72                 :            :   template<int Alignment, typename Packet>
      73                 :            :   EIGEN_STRONG_INLINE void assignPacket(DstScalar* a, const Packet& b) const
      74                 :            :   { internal::pstoret<DstScalar,Packet,Alignment>(a,internal::psub(internal::ploadt<Packet,Alignment>(a),b)); }
      75                 :            : };
      76                 :            : template<typename DstScalar,typename SrcScalar>
      77                 :            : struct functor_traits<sub_assign_op<DstScalar,SrcScalar> > {
      78                 :            :   enum {
      79                 :            :     Cost = NumTraits<DstScalar>::ReadCost + NumTraits<DstScalar>::AddCost,
      80                 :            :     PacketAccess = is_same<DstScalar,SrcScalar>::value && packet_traits<DstScalar>::HasSub
      81                 :            :   };
      82                 :            : };
      83                 :            : 
      84                 :            : /** \internal
      85                 :            :   * \brief Template functor for scalar/packet assignment with multiplication
      86                 :            :   *
      87                 :            :   */
      88                 :            : template<typename DstScalar, typename SrcScalar=DstScalar>
      89                 :            : struct mul_assign_op {
      90                 :            : 
      91                 :       3271 :   EIGEN_EMPTY_STRUCT_CTOR(mul_assign_op)
      92                 :        100 :   EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE void assignCoeff(DstScalar& a, const SrcScalar& b) const { a *= b; }
      93                 :            :   
      94                 :            :   template<int Alignment, typename Packet>
      95                 :       6392 :   EIGEN_STRONG_INLINE void assignPacket(DstScalar* a, const Packet& b) const
      96                 :       6392 :   { internal::pstoret<DstScalar,Packet,Alignment>(a,internal::pmul(internal::ploadt<Packet,Alignment>(a),b)); }
      97                 :            : };
      98                 :            : template<typename DstScalar, typename SrcScalar>
      99                 :            : struct functor_traits<mul_assign_op<DstScalar,SrcScalar> > {
     100                 :            :   enum {
     101                 :            :     Cost = NumTraits<DstScalar>::ReadCost + NumTraits<DstScalar>::MulCost,
     102                 :            :     PacketAccess = is_same<DstScalar,SrcScalar>::value && packet_traits<DstScalar>::HasMul
     103                 :            :   };
     104                 :            : };
     105                 :            : 
     106                 :            : /** \internal
     107                 :            :   * \brief Template functor for scalar/packet assignment with diviving
     108                 :            :   *
     109                 :            :   */
     110                 :            : template<typename DstScalar, typename SrcScalar=DstScalar> struct div_assign_op {
     111                 :            : 
     112                 :      16812 :   EIGEN_EMPTY_STRUCT_CTOR(div_assign_op)
     113                 :          2 :   EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE void assignCoeff(DstScalar& a, const SrcScalar& b) const { a /= b; }
     114                 :            :   
     115                 :            :   template<int Alignment, typename Packet>
     116                 :      27418 :   EIGEN_STRONG_INLINE void assignPacket(DstScalar* a, const Packet& b) const
     117                 :      27418 :   { internal::pstoret<DstScalar,Packet,Alignment>(a,internal::pdiv(internal::ploadt<Packet,Alignment>(a),b)); }
     118                 :            : };
     119                 :            : template<typename DstScalar, typename SrcScalar>
     120                 :            : struct functor_traits<div_assign_op<DstScalar,SrcScalar> > {
     121                 :            :   enum {
     122                 :            :     Cost = NumTraits<DstScalar>::ReadCost + NumTraits<DstScalar>::MulCost,
     123                 :            :     PacketAccess = is_same<DstScalar,SrcScalar>::value && packet_traits<DstScalar>::HasDiv
     124                 :            :   };
     125                 :            : };
     126                 :            : 
     127                 :            : /** \internal
     128                 :            :   * \brief Template functor for scalar/packet assignment with swapping
     129                 :            :   *
     130                 :            :   * It works as follow. For a non-vectorized evaluation loop, we have:
     131                 :            :   *   for(i) func(A.coeffRef(i), B.coeff(i));
     132                 :            :   * where B is a SwapWrapper expression. The trick is to make SwapWrapper::coeff behaves like a non-const coeffRef.
     133                 :            :   * Actually, SwapWrapper might not even be needed since even if B is a plain expression, since it has to be writable
     134                 :            :   * B.coeff already returns a const reference to the underlying scalar value.
     135                 :            :   * 
     136                 :            :   * The case of a vectorized loop is more tricky:
     137                 :            :   *   for(i,j) func.assignPacket<A_Align>(&A.coeffRef(i,j), B.packet<B_Align>(i,j));
     138                 :            :   * Here, B must be a SwapWrapper whose packet function actually returns a proxy object holding a Scalar*,
     139                 :            :   * the actual alignment and Packet type.
     140                 :            :   *
     141                 :            :   */
     142                 :            : template<typename Scalar> struct swap_assign_op {
     143                 :            : 
     144                 :            :   EIGEN_EMPTY_STRUCT_CTOR(swap_assign_op)
     145                 :            :   EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE void assignCoeff(Scalar& a, const Scalar& b) const
     146                 :            :   {
     147                 :            : #ifdef EIGEN_GPUCC
     148                 :            :     // FIXME is there some kind of cuda::swap?
     149                 :            :     Scalar t=b; const_cast<Scalar&>(b)=a; a=t;
     150                 :            : #else
     151                 :            :     using std::swap;
     152                 :            :     swap(a,const_cast<Scalar&>(b));
     153                 :            : #endif
     154                 :            :   }
     155                 :            : };
     156                 :            : template<typename Scalar>
     157                 :            : struct functor_traits<swap_assign_op<Scalar> > {
     158                 :            :   enum {
     159                 :            :     Cost = 3 * NumTraits<Scalar>::ReadCost,
     160                 :            :     PacketAccess = 
     161                 :            :     #if defined(EIGEN_VECTORIZE_AVX) && EIGEN_COMP_CLANG && (EIGEN_COMP_CLANG<800 || defined(__apple_build_version__))
     162                 :            :     // This is a partial workaround for a bug in clang generating bad code
     163                 :            :     // when mixing 256/512 bits loads and 128 bits moves.
     164                 :            :     // See http://eigen.tuxfamily.org/bz/show_bug.cgi?id=1684
     165                 :            :     //     https://bugs.llvm.org/show_bug.cgi?id=40815
     166                 :            :     0
     167                 :            :     #else
     168                 :            :     packet_traits<Scalar>::Vectorizable
     169                 :            :     #endif
     170                 :            :   };
     171                 :            : };
     172                 :            : 
     173                 :            : } // namespace internal
     174                 :            : 
     175                 :            : } // namespace Eigen
     176                 :            : 
     177                 :            : #endif // EIGEN_ASSIGNMENT_FUNCTORS_H

Generated by: LCOV version 1.0