mirror of
				https://github.com/paboyle/Grid.git
				synced 2025-11-04 05:54:32 +00:00 
			
		
		
		
	Binop assist and real/complex improvements
This commit is contained in:
		@@ -28,7 +28,9 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
namespace Grid {
 | 
					namespace Grid {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  //////////////////////////////////////
 | 
				
			||||||
  // To take the floating point type of real/complex type
 | 
					  // To take the floating point type of real/complex type
 | 
				
			||||||
 | 
					  //////////////////////////////////////
 | 
				
			||||||
  template <typename T> struct RealPart {
 | 
					  template <typename T> struct RealPart {
 | 
				
			||||||
    typedef T type;
 | 
					    typedef T type;
 | 
				
			||||||
  };
 | 
					  };
 | 
				
			||||||
@@ -36,6 +38,10 @@ namespace Grid {
 | 
				
			|||||||
    typedef T type;
 | 
					    typedef T type;
 | 
				
			||||||
  };
 | 
					  };
 | 
				
			||||||
  
 | 
					  
 | 
				
			||||||
 | 
					  //////////////////////////////////////
 | 
				
			||||||
 | 
					  // demote a vector to real type
 | 
				
			||||||
 | 
					  //////////////////////////////////////
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  // type alias used to simplify the syntax of std::enable_if
 | 
					  // type alias used to simplify the syntax of std::enable_if
 | 
				
			||||||
  template <typename T> using Invoke                                  =  typename T::type;
 | 
					  template <typename T> using Invoke                                  =  typename T::type;
 | 
				
			||||||
  template <typename Condition, typename ReturnType> using EnableIf   =  Invoke<std::enable_if<Condition::value, ReturnType> >;
 | 
					  template <typename Condition, typename ReturnType> using EnableIf   =  Invoke<std::enable_if<Condition::value, ReturnType> >;
 | 
				
			||||||
@@ -205,7 +211,6 @@ namespace Grid {
 | 
				
			|||||||
      return *this;
 | 
					      return *this;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					 | 
				
			||||||
    ///////////////////////////////////////
 | 
					    ///////////////////////////////////////
 | 
				
			||||||
    // Not all functions are supported
 | 
					    // Not all functions are supported
 | 
				
			||||||
    // through SIMD and must breakout to 
 | 
					    // through SIMD and must breakout to 
 | 
				
			||||||
@@ -214,7 +219,6 @@ namespace Grid {
 | 
				
			|||||||
    ///////////////////////////////////////
 | 
					    ///////////////////////////////////////
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    template<class functor> friend inline Grid_simd SimdApply (const functor &func,const Grid_simd &v) {
 | 
					    template<class functor> friend inline Grid_simd SimdApply (const functor &func,const Grid_simd &v) {
 | 
				
			||||||
 | 
					 | 
				
			||||||
      Grid_simd ret;
 | 
					      Grid_simd ret;
 | 
				
			||||||
      Grid_simd::conv_t conv;
 | 
					      Grid_simd::conv_t conv;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -225,6 +229,19 @@ namespace Grid {
 | 
				
			|||||||
      ret.v = conv.v;
 | 
					      ret.v = conv.v;
 | 
				
			||||||
      return ret;
 | 
					      return ret;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					    template<class functor> friend inline Grid_simd SimdApplyBinop (const functor &func,const Grid_simd &x,const Grid_simd &y) {
 | 
				
			||||||
 | 
					      Grid_simd ret;
 | 
				
			||||||
 | 
					      Grid_simd::conv_t cx;
 | 
				
			||||||
 | 
					      Grid_simd::conv_t cy;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      cx.v = x.v;
 | 
				
			||||||
 | 
					      cy.v = y.v;
 | 
				
			||||||
 | 
					      for(int i=0;i<Nsimd();i++){
 | 
				
			||||||
 | 
						cx.s[i]=func(cx.s[i],cy.s[i]);
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					      ret.v = cx.v;
 | 
				
			||||||
 | 
					      return ret;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    ////////////////////////////////////////////////////////////////////
 | 
					    ////////////////////////////////////////////////////////////////////
 | 
				
			||||||
    // General permute; assumes vector length is same across 
 | 
					    // General permute; assumes vector length is same across 
 | 
				
			||||||
@@ -236,6 +253,7 @@ namespace Grid {
 | 
				
			|||||||
      Gpermute<Grid_simd>(y,b,perm);
 | 
					      Gpermute<Grid_simd>(y,b,perm);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
  };// end of Grid_simd class definition 
 | 
					  };// end of Grid_simd class definition 
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -383,7 +401,6 @@ namespace Grid {
 | 
				
			|||||||
    return in;
 | 
					    return in;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					 | 
				
			||||||
  /////////////////////
 | 
					  /////////////////////
 | 
				
			||||||
  // Inner, outer
 | 
					  // Inner, outer
 | 
				
			||||||
  /////////////////////
 | 
					  /////////////////////
 | 
				
			||||||
@@ -405,6 +422,46 @@ namespace Grid {
 | 
				
			|||||||
    return arg;
 | 
					    return arg;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  ////////////////////////////////////////////////////////////
 | 
				
			||||||
 | 
					  // copy/splat complex real parts into real;
 | 
				
			||||||
 | 
					  // insert real into complex and zero imag;
 | 
				
			||||||
 | 
					  ////////////////////////////////////////////////////////////
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  //real = toReal( complex )
 | 
				
			||||||
 | 
					  template<class S,class V,IfReal<S>  = 0>	
 | 
				
			||||||
 | 
					  inline Grid_simd<S,V> toReal(const Grid_simd<std::complex<S>,V> &in)
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					    typedef Grid_simd<S,V> simd;
 | 
				
			||||||
 | 
					    simd ret;
 | 
				
			||||||
 | 
					    typename simd::conv_t conv;
 | 
				
			||||||
 | 
					    conv.v = in.v;
 | 
				
			||||||
 | 
					    for(int i=0;i<simd::Nsimd();i+=2){
 | 
				
			||||||
 | 
					      conv.s[i+1]=conv.s[i];    // duplicate (r,r);(r,r);(r,r); etc...
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    ret.v = conv.v;
 | 
				
			||||||
 | 
					    return ret;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  
 | 
				
			||||||
 | 
					  //complex = toComplex( real )
 | 
				
			||||||
 | 
					  template<class R,class V,IfReal<R> = 0 >	// must be a real arg
 | 
				
			||||||
 | 
					  inline Grid_simd<std::complex<R>,V> toComplex (const Grid_simd<R,V> &in)
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					    typedef Grid_simd<R,V> Rsimd;
 | 
				
			||||||
 | 
					    typedef Grid_simd<std::complex<R>,V> Csimd;
 | 
				
			||||||
 | 
					    typename Rsimd::conv_t conv;// address as real
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    conv.v = in.v;
 | 
				
			||||||
 | 
					    for(int i=0;i<Rsimd::Nsimd();i+=2){
 | 
				
			||||||
 | 
					      assert(conv.s[i+1]==conv.s[i]); // trap any cases where real was not duplicated 
 | 
				
			||||||
 | 
					      // indicating the SIMD grids of real and imag assignment did not correctly match
 | 
				
			||||||
 | 
					      conv.s[i+1]=0.0;                // zero imaginary parts
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    Csimd ret;
 | 
				
			||||||
 | 
					    ret.v = conv.v;
 | 
				
			||||||
 | 
					    return ret;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  ///////////////////////////////
 | 
					  ///////////////////////////////
 | 
				
			||||||
  // Define available types
 | 
					  // Define available types
 | 
				
			||||||
  ///////////////////////////////
 | 
					  ///////////////////////////////
 | 
				
			||||||
@@ -413,6 +470,20 @@ namespace Grid {
 | 
				
			|||||||
  typedef Grid_simd< std::complex< float > , SIMD_Ftype > vComplexF;
 | 
					  typedef Grid_simd< std::complex< float > , SIMD_Ftype > vComplexF;
 | 
				
			||||||
  typedef Grid_simd< std::complex< double >, SIMD_Dtype > vComplexD;
 | 
					  typedef Grid_simd< std::complex< double >, SIMD_Dtype > vComplexD;
 | 
				
			||||||
  typedef Grid_simd< Integer               , SIMD_Itype > vInteger;
 | 
					  typedef Grid_simd< Integer               , SIMD_Itype > vInteger;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  /////////////////////////////////////////
 | 
				
			||||||
 | 
					  // Some traits to recognise the types
 | 
				
			||||||
 | 
					  /////////////////////////////////////////
 | 
				
			||||||
 | 
					  template <typename T> struct is_simd : public std::false_type{};
 | 
				
			||||||
 | 
					  template <> struct is_simd<vRealF>   : public std::true_type {};
 | 
				
			||||||
 | 
					  template <> struct is_simd<vRealD>   : public std::true_type {};
 | 
				
			||||||
 | 
					  template <> struct is_simd<vComplexF>: public std::true_type {};
 | 
				
			||||||
 | 
					  template <> struct is_simd<vComplexD>: public std::true_type {};
 | 
				
			||||||
 | 
					  template <> struct is_simd<vInteger> : public std::true_type {};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  template <typename T> using IfSimd     = Invoke<std::enable_if< is_simd<T>::value,int> > ;
 | 
				
			||||||
 | 
					  template <typename T> using IfNotSimd  = Invoke<std::enable_if<!is_simd<T>::value,unsigned> > ;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user