LCOV - code coverage report
Current view: top level - Src/FLOPS - InaVecFLOPS.hpp (source / functions) Hit Total Coverage
Test: Coverage inastemp Lines: 111 111 100.0 %
Date: 2022-03-17 09:48:28 Functions: 50 50 100.0 %

          Line data    Source code
       1             : ///////////////////////////////////////////////////////////////////////////
       2             : // Inastemp - Berenger Bramas MPCDF - 2016
       3             : // Under MIT Licence, please you must read the LICENCE file.
       4             : ///////////////////////////////////////////////////////////////////////////
       5             : #ifndef INAVECFLOPS_HPP
       6             : #define INAVECFLOPS_HPP
       7             : 
       8             : #include <type_traits>
       9             : 
      10             : #include "Common/InaUtils.hpp"
      11             : 
      12             : class InaVecFLOPSStats {
      13             :     size_t mulop;
      14             :     size_t divop;
      15             :     size_t addop;
      16             :     size_t subop;
      17             :     size_t rsqrt;
      18             :     size_t sqrt;
      19             : 
      20             : public:
      21             :     InaVecFLOPSStats()
      22          42 :         : mulop(0), divop(0), addop(0),
      23          42 :           subop(0), rsqrt(0), sqrt(0){
      24             :     }
      25             : 
      26             :     void incMulOp(const size_t inNbEvents = 1){
      27         828 :         mulop += inNbEvents;
      28             :     }
      29             :     void incDivOp(const size_t inNbEvents = 1){
      30         154 :         divop += inNbEvents;
      31             :     }
      32             :     void incAddOp(const size_t inNbEvents = 1){
      33        5604 :         addop += inNbEvents;
      34             :     }
      35             :     void incSubOp(const size_t inNbEvents = 1){
      36         350 :         subop += inNbEvents;
      37             :     }
      38             :     void incRsqrt(const size_t inNbEvents = 1){
      39          28 :         rsqrt += inNbEvents;
      40             :     }
      41             :     void incSqrt(const size_t inNbEvents = 1){
      42          28 :         sqrt += inNbEvents;
      43             :     }
      44             : 
      45             :     size_t getMulOp() const {
      46             :         return mulop;
      47             :     }
      48             :     size_t getDivOp() const {
      49             :         return divop;
      50             :     }
      51             :     size_t getAddOp() const {
      52             :         return addop;
      53             :     }
      54             :     size_t getSubOp() const {
      55             :         return subop;
      56             :     }
      57             :     size_t getRsqrt() const {
      58             :         return rsqrt;
      59             :     }
      60             :     size_t getSqrt() const {
      61             :         return sqrt;
      62             :     }
      63             : };
      64             : 
      65             : 
      66             : /**
      67             :  * This class defines the interface that each vector
      68             :  * type must provide.
      69             :  * It is not made to be use as an abstract data type
      70             :  * by having for example a pointer on InaVecFLOPS.
      71             :  * It simply help to implement each type.
      72             :  */
      73             : template < class VecType >
      74             : class InaVecFLOPS : public VecType {
      75             :     static InaVecFLOPSStats FlopsStats;
      76             : 
      77             : public:
      78             :     static const InaVecFLOPSStats& GetFlopsStats(){
      79             :         return FlopsStats;
      80             :     }
      81             : 
      82             :     static void ResetFlopsStats(){
      83          70 :         FlopsStats = InaVecFLOPSStats();
      84             :     }
      85             : 
      86             :     using Parent               = VecType;
      87             :     using VecRawType           = typename VecType::VecRawType;
      88             :     using MaskType             = typename VecType::MaskType;
      89             :     using RealType             = typename VecType::RealType;
      90             :     static const int Alignement= VecType::Alignement;
      91             :     static const bool IsOfFixedSize = VecType::IsOfFixedSize;
      92             : 
      93             :     using VecType::GetVecLength;
      94             : 
      95       19556 :     using VecType::VecType;
      96             : 
      97             :     using VecType::IsRealFma;
      98             : 
      99         702 :     inline InaVecFLOPS(){}
     100             :     inline InaVecFLOPS(const InaVecFLOPS&) = default;
     101             :     inline InaVecFLOPS& operator = (const InaVecFLOPS&) = default;
     102             : 
     103        6300 :     inline InaVecFLOPS(const VecType& inVec) : Parent(inVec){};
     104             :     inline InaVecFLOPS& operator = (const VecType& inVec){
     105          14 :         this->Parent::operator=(inVec);
     106             :         return *this;
     107             :     }
     108             : 
     109             :     inline InaVecFLOPS(const std::initializer_list<RealType> lst)
     110         164 :         : Parent(lst.begin()){
     111             :     }
     112             : 
     113             :     /** Load and store */
     114             : 
     115             :     inline /*not explicit*/ InaVecFLOPS(const VecRawType inVec)
     116        1682 :         : Parent(inVec){
     117             :     }
     118             : 
     119             :     inline VecType& operator=(const VecRawType inVec){
     120             :         this->Parent::operator =(inVec);
     121             :         return *this;
     122             :     }
     123             : 
     124             :     //! Convert inValue into a VecType by duplicating it and
     125             :     //! setting all the values of the array equal to inValue
     126             :     //! @code VecType[0:last-val-idx] = inValue
     127             :     inline VecType setFromRawType(const VecRawType inValue) const {
     128             :         return Parent::setFromRawType(inValue);
     129             :     }
     130             : 
     131             :     inline explicit operator VecRawType() const{
     132             :         return this->Parent::operator VecRawType();
     133             :     }
     134             : 
     135             :     inline VecRawType getVec() const{
     136             :         return Parent::getVec();
     137             :     }
     138             : 
     139             : //    inline /*not explicit*/ InaVecFLOPS(const RealType inVal)
     140             : //        : Parent(inVal){
     141             : //    }
     142             : 
     143             : //    inline VecType& operator=(const RealType inVal){
     144             : //        this->Parent::operator =(inVal);
     145             : //        return *this;
     146             : //    }
     147             : 
     148             :     inline void setFromScalar(const RealType inVal){
     149             :         this->Parent::setFromScalar(inVal);
     150             :     }
     151             : 
     152             :     // Constructor from vec
     153             :     inline explicit InaVecFLOPS(const RealType ptr[])
     154       11524 :         : Parent(ptr){
     155             :     }
     156             : 
     157             :     //! Convert values from inArray into a VecType
     158             :     //! inArray might not be aligned
     159             :     //! @code idx in [0:last-val-idx] => VecType[idx] = inArray[idx]
     160             :     inline VecType& setFromArray(const RealType ptr[]){
     161        1184 :         Parent::setFromArray(ptr);
     162             :         return *this;
     163             :     }
     164             : 
     165             :     //! Convert values from inArray into a VecType
     166             :     //! inArray must be aligned
     167             :     //! @code idx in [0:last-val-idx] => VecType[idx] = inArray[idx]
     168             :     inline VecType& setFromAlignedArray(const RealType ptr[]){
     169         264 :         Parent::setFromAlignedArray(ptr);
     170             :         return *this;
     171             :     }
     172             : 
     173             :     //! Convert values at position inIndirection from inArray into a VecType
     174             :     //! inArray might not be aligned
     175             :     //! @code idx in [0:last-val-idx] => VecType[idx] = inArray[inIndirection[idx]]
     176             :     inline VecType& setFromIndirectArray(const RealType values[], const int inIndirection[]) {
     177         156 :         Parent::setFromIndirectArray(values, inIndirection);
     178             :         return *this;
     179             :     }
     180             : 
     181             :     //! Convert values at position inIndirection from inArray into a VecType
     182             :     //! inArray might not be aligned
     183             :     //! @code idx in [0:last-val-idx] => VecType[idx] = inArray[inIndirection1[idx]*inLeadingDimension
     184             :     //! @code                                                                         + inIndirection2[idx]]
     185             :     inline VecType& setFromIndirect2DArray(const RealType inArray[], const int inIndirection1[],
     186             :                                  const int inLeadingDimension, const int inIndirection2[]){
     187         120 :         Parent::setFromIndirect2DArray(inArray, inIndirection1, inLeadingDimension, inIndirection2);
     188             :         return *this;
     189             :     }
     190             : 
     191             :     //! inArray
     192             :     //! @code idx in [0:last-val-idx] => outArray[idx] = inVec[idx]
     193             :     inline void storeInArray(RealType ptr[]) const {
     194       46872 :         Parent::storeInArray(ptr);
     195             :     }
     196             : 
     197             :     //! inArray might must be aligned
     198             :     //! @code idx in [0:last-val-idx] => outArray[idx] = inVec[idx]
     199             :     inline void storeInAlignedArray(RealType ptr[]) const {
     200       12944 :         Parent::storeInAlignedArray(ptr);
     201             :     }
     202             : 
     203             :     // Acce to individual values
     204             :     //! Return the value at position inIdx in inVec
     205             :     //! @code return inVec[inIdx]
     206             :     inline RealType at(const int index) const {
     207       67984 :         return Parent::at(index);
     208             :     }
     209             : 
     210             :     // Horizontal operation
     211             :     //! Sum all the values from inVec
     212             :     //! @code return inVec[0] + ... + inVec[last-val-idx]
     213             :     inline RealType horizontalSum() const {
     214        9724 :         FlopsStats.incAddOp(size_t(GetVecLength())-1);
     215        9724 :         return Parent::horizontalSum();
     216             :     }
     217             : 
     218             :     //! Multiply all the values from inVec
     219             :     //! @code return inVec[0] * ... * inVec[last-val-idx]
     220             :     inline RealType horizontalMul() const {
     221         156 :         FlopsStats.incMulOp(size_t(GetVecLength())-1);
     222         156 :         return Parent::horizontalMul();
     223             :     }
     224             : 
     225             :     //! Return the smallest value in the vector
     226             :     inline RealType minInVec() const {
     227         392 :         return Parent::minInVec();
     228             :     }
     229             : 
     230             :     //! Return the greatest value in the vector
     231             :     inline RealType maxInVec() const {
     232         392 :         return Parent::maxInVec();
     233             :     }
     234             : 
     235             :     //! Apply Sqrt to all values from inVec
     236             :     //! @code idx in [0:last-val-idx] => resVec[idx] = Sqrt(inVec[idx])
     237             :     inline VecType sqrt() const {
     238          56 :         FlopsStats.incSqrt((1)*size_t(GetVecLength()));
     239          64 :         return Parent::sqrt();
     240             :     }
     241             : 
     242             :     //! Apply exponential to all values from inVec
     243             :     //! @code idx in [0:last-val-idx] => resVec[idx] = Exp(inVec[idx])
     244          56 :     inline VecType exp() const {
     245         112 :         FlopsStats.incAddOp((1+5)*size_t(GetVecLength()));
     246         112 :         FlopsStats.incMulOp((1+1+5)*size_t(GetVecLength()));
     247         112 :         FlopsStats.incSubOp((1+1)*size_t(GetVecLength()));
     248             :         if(std::is_same<double,typename VecType::RealType>::value){
     249          56 :             FlopsStats.incAddOp((3)*size_t(GetVecLength()));
     250          56 :             FlopsStats.incMulOp((3)*size_t(GetVecLength()));
     251             :         }
     252          88 :         return Parent::exp();
     253             :     }
     254             : 
     255             :     //! Apply exponential to all values from inVec with low accuracy
     256             :     //! @code idx in [0:last-val-idx] => resVec[idx] = ExpLowExp(inVec[idx])
     257          28 :     inline VecType expLowAcc() const {
     258          56 :         FlopsStats.incAddOp((1+2)*size_t(GetVecLength()));
     259          56 :         FlopsStats.incMulOp((1+1+2)*size_t(GetVecLength()));
     260          56 :         FlopsStats.incSubOp((1+1)*size_t(GetVecLength()));
     261             :         if(std::is_same<double,typename VecType::RealType>::value){
     262          28 :             FlopsStats.incAddOp((1)*size_t(GetVecLength()));
     263          28 :             FlopsStats.incMulOp((1)*size_t(GetVecLength()));
     264             :         }
     265          50 :         return Parent::expLowAcc();
     266             :     }
     267             : 
     268             :     //! Apply 1/Sqrt to all values from inVec
     269             :     //! @code idx in [0:last-val-idx] => resVec[idx] = 1/Sqrt(inVec[idx])
     270             :     inline VecType rsqrt() const {
     271          56 :         FlopsStats.incRsqrt((1)*size_t(GetVecLength()));
     272          64 :         return Parent::rsqrt();
     273             :     }
     274             : 
     275             :     //! Return the abs value of inVec
     276             :     //! @code idx in [0:last-val-idx] => resVec[idx] = abs(inVec[idx])
     277             :     inline VecType abs() const {
     278         192 :         return Parent::abs();
     279             :     }
     280             : 
     281             :     //! Convert inVal in integer and then to real
     282             :     //! @code idx in [0:last-val-idx] => floor(inVal[idx])
     283             :     inline VecType floor() const {
     284         260 :         return Parent::floor();
     285             :     }
     286             : 
     287             :     //! Return 1 or -1 for each value in inVec
     288             :     //! @code idx in [0:last-val-idx] => resVec[idx] = (inVec[idx]<0?-1:1)
     289             :     inline VecType signOf() const {
     290         320 :         return Parent::signOf();
     291             :     }
     292             : 
     293             :     //! Return 1 if positive or zero, else 0 for each value
     294             :     //! @code idx in [0:last-val-idx] => resVec[idx] = inVec[idx]>=0?1:0
     295             :     inline VecType isPositive() const {
     296         320 :         return Parent::isPositive();
     297             :     }
     298             : 
     299             :     //! Return 1 if negative or zero, else 0 for each value
     300             :     //! @code idx in [0:last-val-idx] => resVec[idx] = inVec[idx]<=0?1:0
     301             :     inline VecType isNegative() const {
     302         320 :         return Parent::isNegative();
     303             :     }
     304             : 
     305             :     //! Return 1 if positive, else 0 for each value
     306             :     //! @code idx in [0:last-val-idx] => resVec[idx] = inVec[idx]>0?1:0
     307             :     inline VecType isPositiveStrict() const {
     308         320 :         return Parent::isPositiveStrict();
     309             :     }
     310             : 
     311             :     //! Return 1 if negative, else 0 for each value
     312             :     //! @code idx in [0:last-val-idx] => resVec[idx] = inVec[idx]<0?1:0
     313             :     inline VecType isNegativeStrict() const {
     314         320 :         return Parent::isNegativeStrict();
     315             :     }
     316             : 
     317             :     //! Return 1 if equal to, else 0 for each value
     318             :     //! @code idx in [0:last-val-idx] => resVec[idx] = inVec[idx]==0?1:0
     319             :     inline VecType isZero() const {
     320         192 :         return Parent::isZero();
     321             :     }
     322             : 
     323             :     //! Return 1 if not equal to, else 0 for each value
     324             :     //! @code idx in [0:last-val-idx] => resVec[idx] = inVec[idx]!=0?1:0
     325             :     inline VecType isNotZero() const {
     326         192 :         return Parent::isNotZero();
     327             :     }
     328             : 
     329             :     //! Return ~0 if positive or zero, else 0 for each value
     330             :     //! @code idx in [0:last-val-idx] => resVec[idx] = inVec[idx]>=0?~0:0
     331             :     inline MaskType isPositiveMask() const {
     332         280 :         return Parent::isPositiveMask();
     333             :     }
     334             : 
     335             :     //! Return ~0 if negative or zero, else 0 for each value
     336             :     //! @code idx in [0:last-val-idx] => resVec[idx] = inVec[idx]<=0?~0:0
     337             :     inline MaskType isNegativeMask() const {
     338         280 :         return Parent::isNegativeMask();
     339             :     }
     340             : 
     341             :     //! Return ~0 if positive, else 0 for each value
     342             :     //! @code idx in [0:last-val-idx] => resVec[idx] = inVec[idx]>0?~0:0
     343             :     inline MaskType isPositiveStrictMask() const {
     344         280 :         return Parent::isPositiveStrictMask();
     345             :     }
     346             : 
     347             :     //! Return ~0 if negative, else 0 for each value
     348             :     //! @code idx in [0:last-val-idx] => resVec[idx] = inVec[idx]<0?~0:0
     349             :     inline MaskType isNegativeStrictMask() const {
     350         280 :         return Parent::isNegativeStrictMask();
     351             :     }
     352             : 
     353             :     //! Return ~0 if equal to, else 0 for each value
     354             :     //! @code idx in [0:last-val-idx] => resVec[idx] = inVec[idx]==0?~0:0
     355             :     inline MaskType isZeroMask() const {
     356         168 :         return Parent::isZeroMask();
     357             :     }
     358             : 
     359             :     //! Return ~0 if not equal to, else 0 for each value
     360             :     //! @code idx in [0:last-val-idx] => resVec[idx] = inVec[idx]!=0?~0:0
     361             :     inline MaskType isNotZeroMask() const {
     362         168 :         return Parent::isNotZeroMask();
     363             :     }
     364             : 
     365             :     // Static basic methods
     366             :     //! Return a vector where all values are 1
     367             :     //! @code VecType[0:last-val-idx] = 1
     368             :     //! Might be implemtented as ScalarToSimd(1)
     369             :     inline static VecType GetZero() {
     370          24 :         return Parent::GetZero();
     371             :     }
     372             : 
     373             :     //! Return a vector where all values are 0
     374             :     //! @code VecType[0:last-val-idx] = 0
     375             :     //! Might be implemtented as ScalarToSimd(0)
     376             :     inline static VecType GetOne() {
     377          24 :         return Parent::GetOne();
     378             :     }
     379             : 
     380             :     //! Return the minimum value between inVec1 and inVec2
     381             :     //! @code idx in [0:last-val-idx] => resVec[idx] = inVec1[idx]<=inVec2[idx]?inVec1[idx]:inVec2[idx]
     382             :     inline static VecType Min(const VecType& inVec1, const VecType& inVec2) {
     383         156 :         return Parent::Min(inVec1, inVec2);
     384             :     }
     385             : 
     386             :     //! Return the maximum value between inVec1 and inVec2
     387             :     //! @code idx in [0:last-val-idx] => resVec[idx] = inVec1[idx]>=inVec2[idx]?inVec1[idx]:inVec2[idx]
     388             :     inline static VecType Max(const VecType& inVec1, const VecType& inVec2) {
     389         156 :         return Parent::Max(inVec1, inVec2);
     390             :     }
     391             : 
     392             :     //! Return 1 if inVec1 <= inVec2, else 0 for each value
     393             :     //! @code idx in [0:last-val-idx] => resVec[idx] = inVec1[idx]<=inVec2[idx]?1:0
     394             :     inline static VecType IsLowerOrEqual(const VecType& inVec1, const VecType& inVec2) {
     395         208 :         return Parent::IsLowerOrEqual(inVec1, inVec2);
     396             :     }
     397             : 
     398             :     //! Return 1 if inVec1 < inVec2, else 0 for each value
     399             :     //! @code idx in [0:last-val-idx] => resVec[idx] = inVec1[idx]<inVec2[idx]?1:0
     400             :     inline static VecType IsLower(const VecType& inVec1, const VecType& inVec2) {
     401         208 :         return Parent::IsLower(inVec1, inVec2);
     402             :     }
     403             : 
     404             :     //! Return 1 if inVec1 >= inVec2, else 0 for each value
     405             :     //! @code idx in [0:last-val-idx] => resVec[idx] = inVec1[idx]>=inVec2[idx]?1:0
     406             :     inline static VecType IsGreaterOrEqual(const VecType& inVec1, const VecType& inVec2) {
     407         208 :         return Parent::IsGreaterOrEqual(inVec1, inVec2);
     408             :     }
     409             : 
     410             :     //! Return 1 if inVec1 > inVec2, else 0 for each value
     411             :     //! @code idx in [0:last-val-idx] => resVec[idx] = inVec1[idx]>inVec2[idx]?1:0
     412             :     inline static VecType IsGreater(const VecType& inVec1, const VecType& inVec2) {
     413         208 :         return Parent::IsGreater(inVec1, inVec2);
     414             :     }
     415             : 
     416             :     //! Return 1 if inVec1 == inVec2, else 0 for each value
     417             :     //! @code idx in [0:last-val-idx] => resVec[idx] = inVec1[idx]==inVec2[idx]?1:0
     418             :     inline static VecType IsEqual(const VecType& inVec1, const VecType& inVec2) {
     419         208 :         return Parent::IsEqual(inVec1, inVec2);
     420             :     }
     421             : 
     422             :     //! Return 1 if inVec1 == inVec2, else 0 for each value
     423             :     //! @code idx in [0:last-val-idx] => resVec[idx] = inVec1[idx]!=inVec2[idx]?1:0
     424             :     inline static VecType IsNotEqual(const VecType& inVec1, const VecType& inVec2) {
     425         208 :         return Parent::IsNotEqual(inVec1, inVec2);
     426             :     }
     427             : 
     428             :     //! Return ~0 if inVec1 <= inVec2, else 0 for each value
     429             :     //! @code idx in [0:last-val-idx] => resVec[idx] = inVec1[idx]<=inVec2[idx]?~0:0
     430             :     inline static MaskType IsLowerOrEqualMask(const VecType& inVec1, const VecType& inVec2) {
     431         176 :         return Parent::IsLowerOrEqualMask(inVec1, inVec2);
     432             :     }
     433             : 
     434             :     //! Return ~0 if inVec1 < inVec2, else 0 for each value
     435             :     //! @code idx in [0:last-val-idx] => resVec[idx] = inVec1[idx]<inVec2[idx]?~0:0
     436             :     inline static MaskType IsLowerMask(const VecType& inVec1, const VecType& inVec2) {
     437         176 :         return Parent::IsLowerMask(inVec1, inVec2);
     438             :     }
     439             : 
     440             :     //! Return ~0 if inVec1 >= inVec2, else 0 for each value
     441             :     //! @code idx in [0:last-val-idx] => resVec[idx] = inVec1[idx]>=inVec2[idx]?~0:0
     442             :     inline static MaskType IsGreaterOrEqualMask(const VecType& inVec1, const VecType& inVec2) {
     443         176 :         return Parent::IsGreaterOrEqualMask(inVec1, inVec2);
     444             :     }
     445             : 
     446             :     //! Return ~0 if inVec1 > inVec2, else 0 for each value
     447             :     //! @code idx in [0:last-val-idx] => resVec[idx] = inVec1[idx]>inVec2[idx]?~0:0
     448             :     inline static MaskType IsGreaterMask(const VecType& inVec1, const VecType& inVec2) {
     449         176 :         return Parent::IsGreaterMask(inVec1, inVec2);
     450             :     }
     451             : 
     452             :     //! Return ~0 if inVec1 == inVec2, else 0 for each value
     453             :     //! @code idx in [0:last-val-idx] => resVec[idx] = inVec1[idx]==inVec2[idx]?~0:0
     454             :     inline static MaskType IsEqualMask(const VecType& inVec1, const VecType& inVec2) {
     455         176 :         return Parent::IsEqualMask(inVec1, inVec2);
     456             :     }
     457             : 
     458             :     //! Return ~0 if inVec1 == inVec2, else 0 for each value
     459             :     //! @code idx in [0:last-val-idx] => resVec[idx] = inVec1[idx]!=inVec2[idx]?~0:0
     460             :     inline static MaskType IsNotEqualMask(const VecType& inVec1, const VecType& inVec2) {
     461         176 :         return Parent::IsNotEqualMask(inVec1, inVec2);
     462             :     }
     463             : 
     464             :     /** Bits operations */
     465             :     //! Return inVec1 AND inVec2, for each value
     466             :     //! @code idx in [0:last-val-idx] => resVec[idx] = inVec1[idx]&inVec2[idx]
     467             :     inline static VecType BitsAnd(const VecType& inVec1, const VecType& inVec2) {
     468         156 :         return Parent::BitsAnd(inVec1, inVec2);
     469             :     }
     470             : 
     471             :     //! Return NOT inVec1 AND inVec2, for each value
     472             :     //! @code idx in [0:last-val-idx] => resVec[idx] = (~inVec1[idx])&inVec2[idx]
     473             :     inline static VecType BitsNotAnd(const VecType& inVec1, const VecType& inVec2) {
     474         208 :         return Parent::BitsNotAnd(inVec1, inVec2);
     475             :     }
     476             : 
     477             :     //! Return inVec1 OR inVec2, for each value
     478             :     //! @code idx in [0:last-val-idx] => resVec[idx] = inVec1[idx]|inVec2[idx]
     479             :     inline static VecType BitsOr(const VecType& inVec1, const VecType& inVec2) {
     480         156 :         return Parent::BitsOr(inVec1, inVec2);
     481             :     }
     482             : 
     483             :     //! Return inVec1 XOR inVec2, for each value
     484             :     //! @code idx in [0:last-val-idx] => resVec[idx] = inVec1[idx] ^ inVec2[idx]
     485             :     inline static VecType BitsXor(const VecType& inVec1, const VecType& inVec2) {
     486         156 :         return Parent::BitsXor(inVec1, inVec2);
     487             :     }
     488             : 
     489             :     //! Return the name identifier of the vectorizer
     490             :     inline static  const char* GetName() {
     491             :         return Parent::GetName();
     492             :     }
     493             : 
     494             :     //! The method cannot be because the return type is unknown
     495             :     inline static  typename InaIfElse< VecType >::ThenClass If(const MaskType& inTest) {
     496             :         return Parent::If(inTest);
     497             :     }
     498             : 
     499             :     //! This is a ternary if/else test
     500             :     //! It can be implemented as : return (inMask & inIfTrue) | (~inMask & inIfFalse)
     501             :     //! @code idx in [0:last-val-idx] => resVec[idx] = inMask ? inIfTrue[idx] : inIfFalse[idx]
     502             :     inline static VecType IfElse(const MaskType& inMask, const VecType& inIfTrue, const VecType& inIfFalse) {
     503             :         return Parent::IfElse(inMask, inIfTrue, inIfFalse);
     504             :     }
     505             : 
     506             :     //! This is a ternary if/else test with 0 as else case
     507             :     //! It can be implemented as : return (inMask & inIfTrue)
     508             :     //! @code idx in [0:last-val-idx] => resVec[idx] = inMask ? inIfTrue[idx] : 0
     509             :     inline static VecType IfTrue(const MaskType& inMask, const VecType& inIfTrue) {
     510        5200 :         return Parent::IfTrue(inMask, inIfTrue);
     511             :     }
     512             : 
     513             :     //! This is a ternary if/else test with 0 as if case
     514             :     //! It can be implemented as : return (!inMask & inIfFalse)
     515             :     //! @code idx in [0:last-val-idx] => resVec[idx] = inMask ? 0 : inIfFalse[idx]
     516             :     inline static VecType IfFalse(const MaskType& inMask, const VecType& inIfFalse) {
     517             :         return Parent::IfFalse(inMask, inIfFalse);
     518             :     }
     519             : 
     520             :     // Inner operators
     521             :     inline VecType& operator+=(const VecType& inVec){
     522         308 :         FlopsStats.incAddOp(size_t(GetVecLength()));
     523         292 :         this->Parent::operator +=(inVec);
     524             :         return *this;
     525             :     }
     526             : 
     527             :     inline VecType& operator-=(const VecType& inVec){
     528         252 :         FlopsStats.incSubOp(size_t(GetVecLength()));
     529         236 :         this->Parent::operator -=(inVec);
     530             :         return *this;
     531             :     }
     532             : 
     533             :     inline VecType& operator/=(const VecType& inVec){
     534         140 :         FlopsStats.incDivOp(size_t(GetVecLength()));
     535         132 :         this->Parent::operator /=(inVec);
     536             :         return *this;
     537             :     }
     538             : 
     539             :     inline VecType& operator*=(const VecType& inVec){
     540         252 :         FlopsStats.incMulOp(size_t(GetVecLength()));
     541         236 :         this->Parent::operator *=(inVec);
     542             :         return *this;
     543             :     }
     544             : 
     545             : 
     546         168 :     inline VecType pow(size_t power) const{
     547         336 :         FlopsStats.incMulOp(InaUtils::FastPowNbMul(power)*size_t(GetVecLength()));
     548         384 :         return this->Parent::pow(power);
     549             :     }
     550             : 
     551             : 
     552             :     template <class VecType2>
     553             :     friend InaVecFLOPS<VecType2> operator+(const InaVecFLOPS<VecType2>& inVec1, const InaVecFLOPS<VecType2>& inVec2);
     554             : 
     555             :     template <class VecType2>
     556             :     friend InaVecFLOPS<VecType2> operator-(const InaVecFLOPS<VecType2>& inVec1, const InaVecFLOPS<VecType2>& inVec2);
     557             : 
     558             :     template <class VecType2>
     559             :     friend InaVecFLOPS<VecType2> operator/(const InaVecFLOPS<VecType2>& inVec1, const InaVecFLOPS<VecType2>& inVec2);
     560             : 
     561             :     template <class VecType2>
     562             :     friend InaVecFLOPS<VecType2> operator*(const InaVecFLOPS<VecType2>& inVec1, const InaVecFLOPS<VecType2>& inVec2);
     563             : 
     564             : 
     565             :     // Multiple sum
     566             :     template <class ... Args>
     567          16 :     inline static void MultiHorizontalSum(RealType sumRes[], Args ...args){
     568         644 :         const size_t nbVecs = sizeof...(args);
     569        1172 :         FlopsStats.incAddOp((size_t(GetVecLength())-1)*nbVecs);
     570         644 :         Parent::MultiHorizontalSum(sumRes, args...);
     571          16 :     }
     572             : 
     573             :     inline static VecType Fma(const VecType& inValAdd, const VecType& inValMul1, const VecType& inValMul2){
     574         336 :         FlopsStats.incAddOp(size_t(GetVecLength()));
     575         336 :         FlopsStats.incMulOp(size_t(GetVecLength()));
     576         312 :         return Parent::Fma(inValAdd, inValMul1, inValMul2);
     577             :     }
     578             : };
     579             : 
     580             : // Bits operators
     581             : template <class VecType>
     582             : inline InaVecFLOPS<VecType> operator&(const InaVecFLOPS<VecType>& inVec1, const InaVecFLOPS<VecType>& inVec2){
     583             :     return InaVecFLOPS<VecType>::BitsAnd(inVec1, inVec2);
     584             : }
     585             : 
     586             : template <class VecType>
     587             : inline InaVecFLOPS<VecType> operator|(const InaVecFLOPS<VecType>& inVec1, const InaVecFLOPS<VecType>& inVec2){
     588             :     return InaVecFLOPS<VecType>::BitsOr(inVec1, inVec2);
     589             : }
     590             : 
     591             : template <class VecType>
     592             : inline InaVecFLOPS<VecType> operator^(const InaVecFLOPS<VecType>& inVec1, const InaVecFLOPS<VecType>& inVec2){
     593             :     return InaVecFLOPS<VecType>::BitsXor(inVec1, inVec2);
     594             : }
     595             : 
     596             : // Dual operators
     597             : template <class VecType>
     598             : inline InaVecFLOPS<VecType> operator+(const InaVecFLOPS<VecType>& inVec1, const InaVecFLOPS<VecType>& inVec2){
     599         294 :     InaVecFLOPS<VecType>::FlopsStats.incAddOp(size_t(InaVecFLOPS<VecType>::GetVecLength()));
     600         396 :     return static_cast<const VecType&>(inVec1) + static_cast<const VecType&>(inVec2);
     601             : }
     602             : 
     603             : template <class VecType>
     604             : inline InaVecFLOPS<VecType> operator-(const InaVecFLOPS<VecType>& inVec1, const InaVecFLOPS<VecType>& inVec2){
     605         294 :     InaVecFLOPS<VecType>::FlopsStats.incSubOp(size_t(InaVecFLOPS<VecType>::GetVecLength()));
     606         396 :     return static_cast<const VecType&>(inVec1) - static_cast<const VecType&>(inVec2);
     607             : }
     608             : 
     609             : template <class VecType>
     610             : inline InaVecFLOPS<VecType> operator/(const InaVecFLOPS<VecType>& inVec1, const InaVecFLOPS<VecType>& inVec2){
     611         182 :     InaVecFLOPS<VecType>::FlopsStats.incDivOp(size_t(InaVecFLOPS<VecType>::GetVecLength()));
     612         252 :     return static_cast<const VecType&>(inVec1) / static_cast<const VecType&>(inVec2);
     613             : }
     614             : 
     615             : template <class VecType>
     616             : inline InaVecFLOPS<VecType> operator*(const InaVecFLOPS<VecType>& inVec1, const InaVecFLOPS<VecType>& inVec2){
     617         350 :     InaVecFLOPS<VecType>::FlopsStats.incMulOp(size_t(InaVecFLOPS<VecType>::GetVecLength()));
     618         468 :     return static_cast<const VecType&>(inVec1) * static_cast<const VecType&>(inVec2);
     619             : }
     620             : 
     621             : // Tests and comparions
     622             : template <class VecType>
     623             : inline typename InaVecFLOPS<VecType>::MaskType operator<(const InaVecFLOPS<VecType>& inVec1, const InaVecFLOPS<VecType>& inVec2){
     624             :     return InaVecFLOPS<VecType>::IsLowerMask(inVec1,inVec2);
     625             : }
     626             : 
     627             : template <class VecType>
     628             : inline typename InaVecFLOPS<VecType>::MaskType operator<=(const InaVecFLOPS<VecType>& inVec1, const InaVecFLOPS<VecType>& inVec2){
     629             :     return InaVecFLOPS<VecType>::IsLowerOrEqualMask(inVec1,inVec2);
     630             : }
     631             : 
     632             : template <class VecType>
     633             : inline typename InaVecFLOPS<VecType>::MaskType operator>(const InaVecFLOPS<VecType>& inVec1, const InaVecFLOPS<VecType>& inVec2){
     634             :     return InaVecFLOPS<VecType>::IsGreaterMask(inVec1,inVec2);
     635             : }
     636             : 
     637             : template <class VecType>
     638             : inline typename InaVecFLOPS<VecType>::MaskType operator>=(const InaVecFLOPS<VecType>& inVec1, const InaVecFLOPS<VecType>& inVec2){
     639             :     return InaVecFLOPS<VecType>::IsGreaterOrEqualMask(inVec1,inVec2);
     640             : }
     641             : 
     642             : template <class VecType>
     643             : inline typename InaVecFLOPS<VecType>::MaskType operator==(const InaVecFLOPS<VecType>& inVec1, const InaVecFLOPS<VecType>& inVec2){
     644             :     return InaVecFLOPS<VecType>::IsEqualMask(inVec1,inVec2);
     645             : }
     646             : 
     647             : template <class VecType>
     648             : inline typename InaVecFLOPS<VecType>::MaskType operator!=(const InaVecFLOPS<VecType>& inVec1, const InaVecFLOPS<VecType>& inVec2){
     649             :     return InaVecFLOPS<VecType>::IsNotEqualMask(inVec1,inVec2);
     650             : }
     651             : 
     652             : 
     653             : template < class VecType >
     654          42 : InaVecFLOPSStats InaVecFLOPS<VecType>::FlopsStats;
     655             : 
     656             : #endif // INAVECFLOPS_HPP

Generated by: LCOV version 1.13