LCOV - code coverage report
Current view: top level - Src/SCALAR - InaVecSCALARFloat.hpp (source / functions) Hit Total Coverage
Test: Coverage inastemp Lines: 74 74 100.0 %
Date: 2022-03-17 09:48:28 Functions: 6 6 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 INAVECSCALARFLOAT_HPP
       6             : #define INAVECSCALARFLOAT_HPP
       7             : 
       8             : #include "InastempGlobal.h"
       9             : #include "Common/InaUtils.hpp"
      10             : #include "Common/InaIfElse.hpp"
      11             : 
      12             : #include <cmath>
      13             : #include <initializer_list>
      14             : 
      15             : template <class RealType>
      16             : class InaVecMaskSCALAR;
      17             : 
      18             : template <class RealType>
      19             : class InaVecSCALAR;
      20             : 
      21             : // Mask type
      22             : template <>
      23             : class InaVecMaskSCALAR<float> {
      24             :     bool mask;
      25             : public:
      26             :     // Classic constructors
      27             :     inline InaVecMaskSCALAR(){}
      28             : 
      29             :     inline InaVecMaskSCALAR(const InaVecMaskSCALAR&) = default;
      30             :     inline InaVecMaskSCALAR& operator=(const InaVecMaskSCALAR&) = default;
      31             : 
      32             :     // Native data type compatibility
      33             :     inline /*not explicit*/ InaVecMaskSCALAR(const bool inMask)
      34          20 :         : mask(inMask){}
      35             : 
      36             :     inline InaVecMaskSCALAR& operator=(const bool inMask){
      37             :         mask = inMask;
      38             :         return (*this);
      39             :     }
      40             : 
      41             :     inline explicit operator bool() const{
      42             :         return mask;
      43             :     }
      44             : 
      45             :     inline bool getMask() const{
      46             :         return mask;
      47             :     }
      48             : 
      49             :     // Binary methods
      50             :     inline InaVecMaskSCALAR Not() const{
      51             :         return InaVecMaskSCALAR(!mask);
      52             :     }
      53             : 
      54             :     inline bool isAllTrue() const{
      55             :         // true if all FF
      56             :         return mask;
      57             :     }
      58             : 
      59             :     inline bool isAllFalse() const{
      60             :         // true if all zero
      61             :         return !mask;
      62             :     }
      63             : 
      64             :     // Double args methods
      65             :     inline static InaVecMaskSCALAR And(const InaVecMaskSCALAR& inMask1, const InaVecMaskSCALAR& inMask2){
      66             :         return InaVecMaskSCALAR(inMask1.mask & inMask2.mask);
      67             :     }
      68             : 
      69             :     inline static InaVecMaskSCALAR NotAnd(const InaVecMaskSCALAR& inMask1, const InaVecMaskSCALAR& inMask2){
      70             :         return InaVecMaskSCALAR((!inMask1.mask) & inMask2.mask);
      71             :     }
      72             : 
      73             :     inline static InaVecMaskSCALAR Or(const InaVecMaskSCALAR& inMask1, const InaVecMaskSCALAR& inMask2){
      74             :         return InaVecMaskSCALAR(inMask1.mask | inMask2.mask);
      75             :     }
      76             : 
      77             :     inline static InaVecMaskSCALAR Xor(const InaVecMaskSCALAR& inMask1, const InaVecMaskSCALAR& inMask2){
      78             :         return InaVecMaskSCALAR(inMask1.mask ^ inMask2.mask);
      79             :     }
      80             : 
      81             :     inline static bool IsEqual(const InaVecMaskSCALAR& inMask1, const InaVecMaskSCALAR& inMask2){
      82             :         return inMask1.mask == inMask2.mask;
      83             :     }
      84             : 
      85             :     inline static bool IsNotEqual(const InaVecMaskSCALAR& inMask1, const InaVecMaskSCALAR& inMask2){
      86           1 :         return inMask1.mask != inMask2.mask;
      87             :     }
      88             : };
      89             : 
      90             : // Mask must have operators
      91             : inline InaVecMaskSCALAR<float> operator&(const InaVecMaskSCALAR<float>& inMask1, const InaVecMaskSCALAR<float>& inMask2){
      92             :     return InaVecMaskSCALAR<float>::And(inMask1, inMask2);
      93             : }
      94             : 
      95             : inline InaVecMaskSCALAR<float> operator|(const InaVecMaskSCALAR<float>& inMask1, const InaVecMaskSCALAR<float>& inMask2){
      96             :     return InaVecMaskSCALAR<float>::Or(inMask1, inMask2);
      97             : }
      98             : 
      99             : inline InaVecMaskSCALAR<float> operator^(const InaVecMaskSCALAR<float>& inMask1, const InaVecMaskSCALAR<float>& inMask2){
     100             :     return InaVecMaskSCALAR<float>::Xor(inMask1, inMask2);
     101             : }
     102             : 
     103             : inline bool operator==(const InaVecMaskSCALAR<float>& inMask1, const InaVecMaskSCALAR<float>& inMask2){
     104           4 :     return InaVecMaskSCALAR<float>::IsEqual(inMask1, inMask2);
     105             : }
     106             : 
     107             : inline bool operator!=(const InaVecMaskSCALAR<float>& inMask1, const InaVecMaskSCALAR<float>& inMask2){
     108           2 :     return InaVecMaskSCALAR<float>::IsNotEqual(inMask1, inMask2);
     109             : }
     110             : 
     111             : // Vec type
     112             : template <>
     113             : class InaVecSCALAR<float> {
     114             : protected:
     115             :     float vec;
     116             : 
     117             : public:
     118             :     using VecRawType           = float;
     119             :     using MaskType             = InaVecMaskSCALAR<float>;
     120             :     using RealType             = float;
     121             :     [[deprecated("Please use the method instead")]]
     122             :     static const int VecLength = 1;
     123             :     static const int Alignement= 1;
     124             :     static const bool IsOfFixedSize = true;
     125             : 
     126             :     static constexpr int GetVecLength(){
     127             :         return 1;
     128             :     }
     129             : 
     130             :     static constexpr bool IsRealFma(){
     131             :         return false;
     132             :     }
     133             : 
     134          32 :     inline InaVecSCALAR(){}
     135             :     inline InaVecSCALAR(const InaVecSCALAR&) = default;
     136             :     inline InaVecSCALAR& operator = (const InaVecSCALAR&) = default;
     137             : 
     138             :     // Constructor from raw type
     139             :     inline /*not explicit*/ InaVecSCALAR(const float inVec)
     140         258 :         : vec(inVec){
     141             :     }
     142             : 
     143             :     inline InaVecSCALAR& operator=(const float inVec){
     144             :         vec = inVec;
     145             :         return *this;
     146             :     }
     147             : 
     148             :     inline InaVecSCALAR& setFromRawType(const float inVec){
     149             :         vec = inVec;
     150             :         return *this;
     151             :     }
     152             : 
     153             :     inline explicit operator float() const{
     154             :         return vec;
     155             :     }
     156             : 
     157             :     inline float getVec() const{
     158             :         return vec;
     159             :     }
     160             : 
     161             :     // Constructor from scalar
     162             : 
     163             :     // Constructor from vec
     164             :     inline InaVecSCALAR(const std::initializer_list<float> lst)
     165          10 :         : InaVecSCALAR(lst.begin()){
     166             :     }
     167             : 
     168             :     inline explicit InaVecSCALAR(const float ptr[])
     169         903 :         : vec(*ptr){
     170             :     }
     171             : 
     172             :     inline InaVecSCALAR& setFromArray(const float ptr[]){
     173          30 :         vec = *ptr;
     174             :         return *this;
     175             :     }
     176             : 
     177             :     inline InaVecSCALAR& setFromAlignedArray(const float ptr[]){
     178           5 :         vec = *ptr;
     179             :         return *this;
     180             :     }
     181             : 
     182             :     inline InaVecSCALAR& setFromIndirectArray(const float values[], const int inIndirection[]) {
     183          12 :         vec = values[inIndirection[0]];
     184             :         return *this;
     185             :     }
     186             : 
     187             :     inline InaVecSCALAR& setFromIndirect2DArray(const float inArray[], const int inIndirection1[],
     188             :                                  const int inLeadingDimension, const int inIndirection2[]){
     189          15 :         vec = inArray[inIndirection1[0] * inLeadingDimension + inIndirection2[0]];
     190             :         return *this;
     191             :     }
     192             : 
     193             :     // Move back to array
     194             :     inline void storeInArray(float ptr[]) const {
     195         218 :         ptr[0] = vec;
     196             :     }
     197             : 
     198             :     inline void storeInAlignedArray(float ptr[]) const {
     199             :         ptr[0] = vec;
     200             :     }
     201             : 
     202             :     // Acce to individual values
     203             :     inline float at(const int /*index*/) const {
     204             :         return vec;
     205             :     }
     206             : 
     207             :     // Horizontal operation
     208             :     inline float horizontalSum() const {
     209             :         return vec;
     210             :     }
     211             : 
     212             :     inline float horizontalMul() const {
     213             :         return vec;
     214             :     }
     215             : 
     216             :     inline float minInVec() const {
     217             :         return vec;
     218             :     }
     219             : 
     220             :     inline float maxInVec() const {
     221             :         return vec;
     222             :     }
     223             : 
     224             :     inline InaVecSCALAR sqrt() const {
     225          20 :         return std::sqrt(vec);
     226             :     }
     227             : 
     228             :     inline InaVecSCALAR exp() const {
     229          27 :          return std::exp(vec);
     230             :     }
     231             : 
     232             :     inline InaVecSCALAR expLowAcc() const {
     233          20 :         return std::exp(vec);
     234             :     }
     235             : 
     236             :     inline InaVecSCALAR rsqrt() const {
     237          20 :         return 1/std::sqrt(vec);
     238             :     }
     239             : 
     240             :     inline InaVecSCALAR abs() const {
     241          15 :         return vec<0?-vec:vec;
     242             :     }
     243             : 
     244             :     inline InaVecSCALAR floor() const {
     245          25 :         return std::floor(vec);
     246             :     }
     247             : 
     248             :     inline InaVecSCALAR signOf() const {
     249          25 :         return vec < 0.f ? -1 : vec > 0.f ? 1.f : 0.f;
     250             :     }
     251             : 
     252             :     inline InaVecSCALAR isPositive() const {
     253          25 :         return vec >= 0.f ? 1.f : 0.f;
     254             :     }
     255             : 
     256             :     inline InaVecSCALAR isNegative() const {
     257          25 :         return vec <= 0.f ? 1.f : 0.f;
     258             :     }
     259             : 
     260             :     inline InaVecSCALAR isPositiveStrict() const {
     261          25 :         return vec > 0.f ? 1.f : 0.f;
     262             :     }
     263             : 
     264             :     inline InaVecSCALAR isNegativeStrict() const {
     265          25 :         return vec < 0.f ? 1.f : 0.f;
     266             :     }
     267             : 
     268             :     inline InaVecSCALAR isZero() const {
     269          15 :         return vec == 0.f ? 1.f : 0.f;
     270             :     }
     271             : 
     272             :     inline InaVecSCALAR isNotZero() const {
     273          15 :         return vec == 0.f ? 0.f : 1.f;
     274             :     }
     275             : 
     276             :     inline InaVecMaskSCALAR<float> isPositiveMask() const {
     277          25 :         return vec >= 0.f ? true : false;
     278             :     }
     279             : 
     280             :     inline InaVecMaskSCALAR<float> isNegativeMask() const {
     281          25 :         return vec <= 0.f ? true : false;
     282             :     }
     283             : 
     284             :     inline InaVecMaskSCALAR<float> isPositiveStrictMask() const {
     285          25 :         return vec > 0.f ? true : false;
     286             :     }
     287             : 
     288             :     inline InaVecMaskSCALAR<float> isNegativeStrictMask() const {
     289          25 :         return vec < 0.f ? true : false;
     290             :     }
     291             : 
     292             :     inline InaVecMaskSCALAR<float> isZeroMask() const {
     293          20 :         return vec == 0.f ? true : false;
     294             :     }
     295             : 
     296             :     inline InaVecMaskSCALAR<float> isNotZeroMask() const {
     297          18 :         return vec == 0.f ? false : true;
     298             :     }
     299             : 
     300             :     // Static basic methods
     301             :     inline static InaVecSCALAR GetZero() {
     302          20 :         return 0.f;
     303             :     }
     304             : 
     305             :     inline static InaVecSCALAR GetOne() {
     306           5 :         return 1.f;
     307             :     }
     308             : 
     309             :     inline static InaVecSCALAR Min(const InaVecSCALAR& inVec1, const InaVecSCALAR& inVec2) {
     310             :         return (inVec1.vec <= inVec2.vec ? inVec1 : inVec2);
     311             :     }
     312             : 
     313             :     inline static InaVecSCALAR Max(const InaVecSCALAR& inVec1, const InaVecSCALAR& inVec2) {
     314             :         return (inVec1.vec >= inVec2.vec ? inVec1 : inVec2);
     315             :     }
     316             : 
     317             :     inline static InaVecSCALAR IsLowerOrEqual(const InaVecSCALAR& inVec1, const InaVecSCALAR& inVec2) {
     318          20 :         return inVec1.vec <= inVec2.vec ? 1.f : 0.f;
     319             :     }
     320             : 
     321             :     inline static InaVecSCALAR IsLower(const InaVecSCALAR& inVec1, const InaVecSCALAR& inVec2) {
     322          20 :         return inVec1.vec < inVec2.vec ? 1.f : 0.f;
     323             :     }
     324             : 
     325             :     inline static InaVecSCALAR IsGreaterOrEqual(const InaVecSCALAR& inVec1, const InaVecSCALAR& inVec2) {
     326          20 :         return inVec1.vec >= inVec2.vec ? 1.f : 0.f;
     327             :     }
     328             : 
     329             :     inline static InaVecSCALAR IsGreater(const InaVecSCALAR& inVec1, const InaVecSCALAR& inVec2) {
     330          20 :         return inVec1.vec > inVec2.vec ? 1.f : 0.f;
     331             :     }
     332             : 
     333             :     inline static InaVecSCALAR IsEqual(const InaVecSCALAR& inVec1, const InaVecSCALAR& inVec2) {
     334          20 :         return inVec1.vec == inVec2.vec ? 1.f : 0.f;
     335             :     }
     336             : 
     337             :     inline static InaVecSCALAR IsNotEqual(const InaVecSCALAR& inVec1, const InaVecSCALAR& inVec2) {
     338          20 :         return inVec1.vec != inVec2.vec ? 1.f : 0.f;
     339             :     }
     340             : 
     341             :     inline static InaVecMaskSCALAR<float> IsLowerOrEqualMask(const InaVecSCALAR& inVec1, const InaVecSCALAR& inVec2) {
     342          25 :         return inVec1.vec <= inVec2.vec ? true : false;
     343             :     }
     344             : 
     345             :     inline static InaVecMaskSCALAR<float> IsLowerMask(const InaVecSCALAR& inVec1, const InaVecSCALAR& inVec2) {
     346          21 :         return inVec1.vec < inVec2.vec ? true : false;
     347             :     }
     348             : 
     349             :     inline static InaVecMaskSCALAR<float> IsGreaterOrEqualMask(const InaVecSCALAR& inVec1, const InaVecSCALAR& inVec2) {
     350          24 :         return inVec1.vec >= inVec2.vec ? true : false;
     351             :     }
     352             : 
     353             :     inline static InaVecMaskSCALAR<float> IsGreaterMask(const InaVecSCALAR& inVec1, const InaVecSCALAR& inVec2) {
     354          20 :         return inVec1.vec > inVec2.vec ? true : false;
     355             :     }
     356             : 
     357             :     inline static InaVecMaskSCALAR<float> IsEqualMask(const InaVecSCALAR& inVec1, const InaVecSCALAR& inVec2) {
     358          46 :         return inVec1.vec == inVec2.vec ? true : false;
     359             :     }
     360             : 
     361             :     inline static InaVecMaskSCALAR<float> IsNotEqualMask(const InaVecSCALAR& inVec1, const InaVecSCALAR& inVec2) {
     362          31 :         return inVec1.vec != inVec2.vec ? true : false;
     363             :     }
     364             : 
     365             :     inline static InaVecSCALAR BitsAnd(const InaVecSCALAR& inVec1, const InaVecSCALAR& inVec2) {
     366          60 :         return InaUtils::ConvertBits< int, float >(InaUtils::ConvertBits< float, int >(inVec1.vec) & InaUtils::ConvertBits< float, int >(inVec2.vec));
     367             :     }
     368             : 
     369             :     inline static InaVecSCALAR BitsNotAnd(const InaVecSCALAR& inVec1, const InaVecSCALAR& inVec2) {
     370          80 :         return InaUtils::ConvertBits< int, float >((~InaUtils::ConvertBits< float, int >(inVec1.vec)) & InaUtils::ConvertBits< float, int >(inVec2.vec));
     371             :     }
     372             : 
     373             :     inline static InaVecSCALAR BitsOr(const InaVecSCALAR& inVec1, const InaVecSCALAR& inVec2) {
     374         204 :         return InaUtils::ConvertBits< int, float >(InaUtils::ConvertBits< float, int >(inVec1.vec) | InaUtils::ConvertBits< float, int >(inVec2.vec));
     375             :     }
     376             : 
     377             :     inline static InaVecSCALAR BitsXor(const InaVecSCALAR& inVec1, const InaVecSCALAR& inVec2) {
     378          60 :         return InaUtils::ConvertBits< int, float >(InaUtils::ConvertBits< float, int >(inVec1.vec) ^ InaUtils::ConvertBits< float, int >(inVec2.vec));
     379             :     }
     380             : 
     381             :     inline static  const char* GetName() {
     382             :         return "InaVecSCALAR<float>";
     383             :     }
     384             : 
     385             :     inline static  InaIfElse< InaVecSCALAR<float> >::ThenClass If(const InaVecMaskSCALAR<float>& inTest) {
     386          30 :         return InaIfElse< InaVecSCALAR<float> >::IfClass().If(inTest);
     387             :     }
     388             : 
     389             :     inline static InaVecSCALAR IfElse(const InaVecMaskSCALAR<float>& inMask, const InaVecSCALAR& inIfTrue, const InaVecSCALAR& inIfFalse) {
     390           4 :         return inMask?inIfTrue:inIfFalse;
     391             :     }
     392             : 
     393             :     inline static InaVecSCALAR IfTrue(const InaVecMaskSCALAR<float>& inMask, const InaVecSCALAR& inIfTrue) {
     394         528 :         return inMask?inIfTrue:0.f;
     395             :     }
     396             : 
     397             :     inline static InaVecSCALAR IfFalse(const InaVecMaskSCALAR<float>& inMask, const InaVecSCALAR& inIfFalse) {
     398          36 :         return inMask?0:inIfFalse;
     399             :     }
     400             : 
     401             :     // Inner operators
     402             :     inline InaVecSCALAR<float>& operator+=(const InaVecSCALAR<float>& inVec){
     403           6 :         vec += inVec.vec;
     404             :         return *this;
     405             :     }
     406             : 
     407             :     inline InaVecSCALAR<float>& operator-=(const InaVecSCALAR<float>& inVec){
     408           1 :         vec -= inVec.vec;
     409             :         return *this;
     410             :     }
     411             : 
     412             :     inline InaVecSCALAR<float>& operator/=(const InaVecSCALAR<float>& inVec){
     413           1 :         vec /= inVec.vec;
     414             :         return *this;
     415             :     }
     416             : 
     417             :     inline InaVecSCALAR<float>& operator*=(const InaVecSCALAR<float>& inVec){
     418          36 :         vec *= inVec.vec;
     419             :         return *this;
     420             :     }
     421             : 
     422             :     inline InaVecSCALAR<float> operator-() const {
     423          20 :         return -vec;
     424             :     }
     425             : 
     426             :     inline InaVecSCALAR<float> pow(size_t power) const{
     427          50 :         return InaUtils::FastPow<InaVecSCALAR<float>>(vec, power);
     428             :     }
     429             : 
     430             :     // Multiple sum
     431             :     template <class ... Args>
     432          20 :     inline static void MultiHorizontalSum(float sumRes[], const InaVecSCALAR<float>& inVec, Args ...args){
     433         915 :         sumRes[0] += inVec.vec;
     434         920 :         MultiHorizontalSum(&sumRes[1], args...);
     435          20 :     }
     436             : 
     437             :     inline static void MultiHorizontalSum(float /*sumRes*/[]){
     438             :     }    
     439             : 
     440             :     inline static InaVecSCALAR<float> Fma(const InaVecSCALAR<float>& inValAdd, const InaVecSCALAR<float>& inValMul1, const InaVecSCALAR<float>& inValMul2){
     441          27 :         return inValAdd.vec + (inValMul1.vec * inValMul2.vec);
     442             :     }
     443             : };
     444             : 
     445             : // Bits operators
     446             : inline InaVecSCALAR<float> operator&(const InaVecSCALAR<float>& inVec1, const InaVecSCALAR<float>& inVec2){
     447             :     return InaVecSCALAR<float>::BitsAnd(inVec1, inVec2);
     448             : }
     449             : 
     450             : inline InaVecSCALAR<float> operator|(const InaVecSCALAR<float>& inVec1, const InaVecSCALAR<float>& inVec2){
     451             :     return InaVecSCALAR<float>::BitsOr(inVec1, inVec2);
     452             : }
     453             : 
     454             : inline InaVecSCALAR<float> operator^(const InaVecSCALAR<float>& inVec1, const InaVecSCALAR<float>& inVec2){
     455             :     return InaVecSCALAR<float>::BitsXor(inVec1, inVec2);
     456             : }
     457             : 
     458             : // Dual operators
     459             : inline InaVecSCALAR<float> operator+(const InaVecSCALAR<float>& inVec1, const InaVecSCALAR<float>& inVec2){
     460          23 :     return inVec1.getVec() + inVec2.getVec();
     461             : }
     462             : 
     463             : inline InaVecSCALAR<float> operator-(const InaVecSCALAR<float>& inVec1, const InaVecSCALAR<float>& inVec2){
     464          23 :     return inVec1.getVec() - inVec2.getVec();
     465             : }
     466             : 
     467             : inline InaVecSCALAR<float> operator/(const InaVecSCALAR<float>& inVec1, const InaVecSCALAR<float>& inVec2){
     468          13 :     return inVec1.getVec() / inVec2.getVec();
     469             : }
     470             : 
     471             : inline InaVecSCALAR<float> operator*(const InaVecSCALAR<float>& inVec1, const InaVecSCALAR<float>& inVec2){
     472          38 :     return inVec1.getVec() * inVec2.getVec();
     473             : }
     474             : 
     475             : // Tests and comparions
     476             : inline InaVecMaskSCALAR<float> operator<(const InaVecSCALAR<float>& inVec1, const InaVecSCALAR<float>& inVec2){
     477           1 :     return InaVecSCALAR<float>::IsLowerMask(inVec1,inVec2);
     478             : }
     479             : 
     480             : inline InaVecMaskSCALAR<float> operator<=(const InaVecSCALAR<float>& inVec1, const InaVecSCALAR<float>& inVec2){
     481           4 :     return InaVecSCALAR<float>::IsLowerOrEqualMask(inVec1,inVec2);
     482             : }
     483             : 
     484             : inline InaVecMaskSCALAR<float> operator>(const InaVecSCALAR<float>& inVec1, const InaVecSCALAR<float>& inVec2){
     485             :     return InaVecSCALAR<float>::IsGreaterMask(inVec1,inVec2);
     486             : }
     487             : 
     488             : inline InaVecMaskSCALAR<float> operator>=(const InaVecSCALAR<float>& inVec1, const InaVecSCALAR<float>& inVec2){
     489           2 :     return InaVecSCALAR<float>::IsGreaterOrEqualMask(inVec1,inVec2);
     490             : }
     491             : 
     492             : inline InaVecMaskSCALAR<float> operator==(const InaVecSCALAR<float>& inVec1, const InaVecSCALAR<float>& inVec2){
     493          25 :     return InaVecSCALAR<float>::IsEqualMask(inVec1,inVec2);
     494             : }
     495             : 
     496             : inline InaVecMaskSCALAR<float> operator!=(const InaVecSCALAR<float>& inVec1, const InaVecSCALAR<float>& inVec2){
     497          11 :     return InaVecSCALAR<float>::IsNotEqualMask(inVec1,inVec2);
     498             : }
     499             : 
     500             : 
     501             : 
     502             : 
     503             : #endif // INAVECFLOAT_HPP

Generated by: LCOV version 1.13