mirror of
				https://github.com/paboyle/Grid.git
				synced 2025-11-02 21:14:32 +00:00 
			
		
		
		
	Merge branch 'feature/fft-opt' into feature/hadrons
This commit is contained in:
		@@ -244,7 +244,10 @@ namespace Grid {
 | 
			
		||||
            pokeLocalSite(s,pgbuf,cbuf);
 | 
			
		||||
          }
 | 
			
		||||
        }
 | 
			
		||||
        result = Cshift(result,dim,L);
 | 
			
		||||
        if (p != processors[dim] - 1)
 | 
			
		||||
        {
 | 
			
		||||
          result = Cshift(result,dim,L);
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
      
 | 
			
		||||
      // Loop over orthog coords
 | 
			
		||||
@@ -287,10 +290,10 @@ namespace Grid {
 | 
			
		||||
          cgbuf = clbuf;
 | 
			
		||||
          cgbuf[dim] = clbuf[dim]+L*pc;
 | 
			
		||||
          peekLocalSite(s,pgbuf,cgbuf);
 | 
			
		||||
          s = s * div;
 | 
			
		||||
          pokeLocalSite(s,result,clbuf);
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
      result = result*div;
 | 
			
		||||
      
 | 
			
		||||
      // destroying plan
 | 
			
		||||
      FFTW<scalar>::fftw_destroy_plan(p);
 | 
			
		||||
 
 | 
			
		||||
@@ -369,7 +369,7 @@ void Grid_init(int *argc,char ***argv)
 | 
			
		||||
  
 | 
			
		||||
void Grid_finalize(void)
 | 
			
		||||
{
 | 
			
		||||
#if defined (GRID_COMMS_MPI) || defined (GRID_COMMS_MPI3)
 | 
			
		||||
#if defined (GRID_COMMS_MPI) || defined (GRID_COMMS_MPI3) 
 | 
			
		||||
  MPI_Finalize();
 | 
			
		||||
  Grid_unquiesce_nodes();
 | 
			
		||||
#endif
 | 
			
		||||
 
 | 
			
		||||
@@ -93,7 +93,7 @@ void GridLogConfigure(std::vector<std::string> &logstreams) {
 | 
			
		||||
////////////////////////////////////////////////////////////
 | 
			
		||||
void Grid_quiesce_nodes(void) {
 | 
			
		||||
  int me = 0;
 | 
			
		||||
#if defined(GRID_COMMS_MPI) || defined(GRID_COMMS_MPI3)
 | 
			
		||||
#if defined(GRID_COMMS_MPI) || defined(GRID_COMMS_MPI3) || defined(GRID_COMMS_MPI3L)
 | 
			
		||||
  MPI_Comm_rank(MPI_COMM_WORLD, &me);
 | 
			
		||||
#endif
 | 
			
		||||
#ifdef GRID_COMMS_SHMEM
 | 
			
		||||
 
 | 
			
		||||
@@ -154,7 +154,7 @@ class ConjugateGradient : public OperatorFunction<Field> {
 | 
			
		||||
                  << LinalgTimer.Elapsed();
 | 
			
		||||
        std::cout << std::endl;
 | 
			
		||||
 | 
			
		||||
        if (ErrorOnNoConverge) assert(true_residual / Tolerance < 1000.0);
 | 
			
		||||
        if (ErrorOnNoConverge) assert(true_residual / Tolerance < 10000.0);
 | 
			
		||||
 | 
			
		||||
        return;
 | 
			
		||||
      }
 | 
			
		||||
 
 | 
			
		||||
@@ -1080,10 +1080,10 @@ say con = 2
 | 
			
		||||
**/
 | 
			
		||||
 | 
			
		||||
template<class T>
 | 
			
		||||
static void Lock(DenseMatrix<T> &H, 	///Hess mtx	
 | 
			
		||||
		 DenseMatrix<T> &Q, 	///Lock Transform
 | 
			
		||||
		 T val, 		///value to be locked
 | 
			
		||||
		 int con, 	///number already locked
 | 
			
		||||
static void Lock(DenseMatrix<T> &H, 	// Hess mtx	
 | 
			
		||||
		 DenseMatrix<T> &Q, 	// Lock Transform
 | 
			
		||||
		 T val, 		// value to be locked
 | 
			
		||||
		 int con, 	// number already locked
 | 
			
		||||
		 RealD small,
 | 
			
		||||
		 int dfg,
 | 
			
		||||
		 bool herm)
 | 
			
		||||
 
 | 
			
		||||
@@ -116,7 +116,7 @@ class NerscHmcRunnerTemplate {
 | 
			
		||||
    NoSmearing<Gimpl> SmearingPolicy;
 | 
			
		||||
    typedef MinimumNorm2<GaugeField, NoSmearing<Gimpl>, RepresentationsPolicy >
 | 
			
		||||
        IntegratorType;  // change here to change the algorithm
 | 
			
		||||
    IntegratorParameters MDpar(20, 1.0);
 | 
			
		||||
    IntegratorParameters MDpar(40, 1.0);
 | 
			
		||||
    IntegratorType MDynamics(UGrid, MDpar, TheAction, SmearingPolicy);
 | 
			
		||||
 | 
			
		||||
    // Checkpoint strategy
 | 
			
		||||
 
 | 
			
		||||
@@ -167,7 +167,7 @@ namespace Optimization {
 | 
			
		||||
    }
 | 
			
		||||
    //Integer
 | 
			
		||||
    inline __m256i operator()(__m256i a, __m256i b){
 | 
			
		||||
#if defined (AVX1) || defined (AVXFMA4)
 | 
			
		||||
#if defined (AVX1) || defined (AVXFMA) || defined (AVXFMA4)
 | 
			
		||||
          __m128i a0,a1;
 | 
			
		||||
          __m128i b0,b1;
 | 
			
		||||
          a0 = _mm256_extractf128_si256(a,0);
 | 
			
		||||
@@ -195,7 +195,7 @@ namespace Optimization {
 | 
			
		||||
    }
 | 
			
		||||
    //Integer
 | 
			
		||||
    inline __m256i operator()(__m256i a, __m256i b){
 | 
			
		||||
#if defined (AVX1) || defined (AVXFMA4)
 | 
			
		||||
#if defined (AVX1) || defined (AVXFMA) || defined (AVXFMA4)
 | 
			
		||||
          __m128i a0,a1;
 | 
			
		||||
          __m128i b0,b1;
 | 
			
		||||
          a0 = _mm256_extractf128_si256(a,0);
 | 
			
		||||
@@ -216,7 +216,7 @@ namespace Optimization {
 | 
			
		||||
  struct MultComplex{
 | 
			
		||||
    // Complex float
 | 
			
		||||
    inline __m256 operator()(__m256 a, __m256 b){
 | 
			
		||||
#if defined (AVX1) 
 | 
			
		||||
#if defined (AVX1)
 | 
			
		||||
      __m256 ymm0,ymm1,ymm2;
 | 
			
		||||
      ymm0 = _mm256_shuffle_ps(a,a,_MM_SELECT_FOUR_FOUR(2,2,0,0)); // ymm0 <- ar ar,
 | 
			
		||||
      ymm0 = _mm256_mul_ps(ymm0,b);                       // ymm0 <- ar bi, ar br
 | 
			
		||||
@@ -233,7 +233,7 @@ namespace Optimization {
 | 
			
		||||
      a_imag = _mm256_mul_ps( a_imag,tmp  );  // (Ai, Ai) * (Bi, Br) = Ai Bi, Ai Br
 | 
			
		||||
      return _mm256_maddsub_ps( a_real, b, a_imag ); // Ar Br , Ar Bi   +- Ai Bi             = ArBr-AiBi , ArBi+AiBr
 | 
			
		||||
#endif
 | 
			
		||||
#if defined (AVX2)
 | 
			
		||||
#if defined (AVX2)  || defined (AVXFMA)
 | 
			
		||||
      __m256 a_real = _mm256_moveldup_ps( a ); // Ar Ar
 | 
			
		||||
      __m256 a_imag = _mm256_movehdup_ps( a ); // Ai Ai
 | 
			
		||||
      a_imag = _mm256_mul_ps( a_imag, _mm256_shuffle_ps( b,b, _MM_SELECT_FOUR_FOUR(2,3,0,1) ));  // (Ai, Ai) * (Bi, Br) = Ai Bi, Ai Br
 | 
			
		||||
@@ -264,7 +264,7 @@ namespace Optimization {
 | 
			
		||||
	IF IMM0[3] = 0
 | 
			
		||||
	THEN DEST[255:192]=SRC2[191:128] ELSE DEST[255:192]=SRC2[255:192] FI; // Ox5 r<->i   ; 0xC unchanged
 | 
			
		||||
      */
 | 
			
		||||
#if defined (AVX1) 
 | 
			
		||||
#if defined (AVX1)
 | 
			
		||||
      __m256d ymm0,ymm1,ymm2;
 | 
			
		||||
      ymm0 = _mm256_shuffle_pd(a,a,0x0); // ymm0 <- ar ar, ar,ar b'00,00
 | 
			
		||||
      ymm0 = _mm256_mul_pd(ymm0,b);      // ymm0 <- ar bi, ar br
 | 
			
		||||
@@ -279,7 +279,7 @@ namespace Optimization {
 | 
			
		||||
      a_imag = _mm256_mul_pd( a_imag, _mm256_permute_pd( b, 0x5 ) );  // (Ai, Ai) * (Bi, Br) = Ai Bi, Ai Br
 | 
			
		||||
      return _mm256_maddsub_pd( a_real, b, a_imag ); // Ar Br , Ar Bi   +- Ai Bi             = ArBr-AiBi , ArBi+AiBr
 | 
			
		||||
#endif
 | 
			
		||||
#if defined (AVX2)
 | 
			
		||||
#if defined (AVX2) || defined (AVXFMA)
 | 
			
		||||
      __m256d a_real = _mm256_movedup_pd( a ); // Ar Ar
 | 
			
		||||
      __m256d a_imag = _mm256_shuffle_pd(a,a,0xF);//aiai
 | 
			
		||||
      a_imag = _mm256_mul_pd( a_imag, _mm256_permute_pd( b, 0x5 ) );  // (Ai, Ai) * (Bi, Br) = Ai Bi, Ai Br
 | 
			
		||||
@@ -320,7 +320,7 @@ namespace Optimization {
 | 
			
		||||
#if defined (AVXFMA4)
 | 
			
		||||
      a= _mm256_macc_ps(b,c,a);
 | 
			
		||||
#endif
 | 
			
		||||
#if defined (AVX2)
 | 
			
		||||
#if defined (AVX2) || defined (AVXFMA)
 | 
			
		||||
      a= _mm256_fmadd_ps( b, c, a);
 | 
			
		||||
#endif
 | 
			
		||||
    }
 | 
			
		||||
@@ -332,7 +332,7 @@ namespace Optimization {
 | 
			
		||||
#if defined (AVXFMA4)
 | 
			
		||||
      a= _mm256_macc_pd(b,c,a);
 | 
			
		||||
#endif
 | 
			
		||||
#if defined (AVX2)
 | 
			
		||||
#if defined (AVX2) || defined (AVXFMA)
 | 
			
		||||
      a= _mm256_fmadd_pd( b, c, a);
 | 
			
		||||
#endif
 | 
			
		||||
    }
 | 
			
		||||
@@ -347,7 +347,7 @@ namespace Optimization {
 | 
			
		||||
    }
 | 
			
		||||
    // Integer
 | 
			
		||||
    inline __m256i operator()(__m256i a, __m256i b){
 | 
			
		||||
#if defined (AVX1) 
 | 
			
		||||
#if defined (AVX1) || defined (AVXFMA)
 | 
			
		||||
      __m128i a0,a1;
 | 
			
		||||
      __m128i b0,b1;
 | 
			
		||||
      a0 = _mm256_extractf128_si256(a,0);
 | 
			
		||||
 
 | 
			
		||||
@@ -27,15 +27,6 @@ Author: paboyle <paboyle@ph.ed.ac.uk>
 | 
			
		||||
    See the full license in the file "LICENSE" in the top level distribution directory
 | 
			
		||||
    *************************************************************************************/
 | 
			
		||||
    /*  END LEGAL */
 | 
			
		||||
//----------------------------------------------------------------------
 | 
			
		||||
/*! @file Grid_knc.h
 | 
			
		||||
  @brief Optimization libraries for AVX512 instructions set for KNC
 | 
			
		||||
 | 
			
		||||
  Using intrinsics
 | 
			
		||||
*/
 | 
			
		||||
// Time-stamp: <2015-06-09 14:27:28 neo>
 | 
			
		||||
//----------------------------------------------------------------------
 | 
			
		||||
 | 
			
		||||
#include <immintrin.h>
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -6,8 +6,7 @@
 | 
			
		||||
 | 
			
		||||
    Copyright (C) 2015
 | 
			
		||||
 | 
			
		||||
Author: Peter Boyle <paboyle@ph.ed.ac.uk>
 | 
			
		||||
Author: neo <cossu@post.kek.jp>
 | 
			
		||||
Author: Antonin Portelli <antonin.portelli@me.com>
 | 
			
		||||
 | 
			
		||||
    This program is free software; you can redistribute it and/or modify
 | 
			
		||||
    it under the terms of the GNU General Public License as published by
 | 
			
		||||
@@ -27,133 +26,352 @@ Author: neo <cossu@post.kek.jp>
 | 
			
		||||
    *************************************************************************************/
 | 
			
		||||
    /*  END LEGAL */
 | 
			
		||||
 | 
			
		||||
static_assert(GEN_SIMD_WIDTH % 16u == 0, "SIMD vector size is not an integer multiple of 16 bytes");
 | 
			
		||||
 | 
			
		||||
//#define VECTOR_LOOPS
 | 
			
		||||
 | 
			
		||||
// playing with compiler pragmas
 | 
			
		||||
#ifdef VECTOR_LOOPS
 | 
			
		||||
#ifdef __clang__
 | 
			
		||||
#define VECTOR_FOR(i, w, inc)\
 | 
			
		||||
_Pragma("clang loop unroll(full) vectorize(enable) interleave(enable) vectorize_width(w)")\
 | 
			
		||||
for (unsigned int i = 0; i < w; i += inc)
 | 
			
		||||
#elif defined __INTEL_COMPILER
 | 
			
		||||
#define VECTOR_FOR(i, w, inc)\
 | 
			
		||||
_Pragma("simd vectorlength(w*8)")\
 | 
			
		||||
for (unsigned int i = 0; i < w; i += inc)
 | 
			
		||||
#else
 | 
			
		||||
#define VECTOR_FOR(i, w, inc)\
 | 
			
		||||
for (unsigned int i = 0; i < w; i += inc)
 | 
			
		||||
#endif
 | 
			
		||||
#else
 | 
			
		||||
#define VECTOR_FOR(i, w, inc)\
 | 
			
		||||
for (unsigned int i = 0; i < w; i += inc)
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
namespace Grid {
 | 
			
		||||
namespace Optimization {
 | 
			
		||||
 | 
			
		||||
  template<class vtype>
 | 
			
		||||
  union uconv {
 | 
			
		||||
    float f;
 | 
			
		||||
    vtype v;
 | 
			
		||||
  // type traits giving the number of elements for each vector type
 | 
			
		||||
  template <typename T> struct W;
 | 
			
		||||
  template <> struct W<double> {
 | 
			
		||||
    constexpr static unsigned int c = GEN_SIMD_WIDTH/16u;
 | 
			
		||||
    constexpr static unsigned int r = GEN_SIMD_WIDTH/8u;
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
  union u128f {
 | 
			
		||||
    float v;
 | 
			
		||||
    float f[4];
 | 
			
		||||
  };
 | 
			
		||||
  union u128d {
 | 
			
		||||
    double v;
 | 
			
		||||
    double f[2];
 | 
			
		||||
  template <> struct W<float> {
 | 
			
		||||
    constexpr static unsigned int c = GEN_SIMD_WIDTH/8u;
 | 
			
		||||
    constexpr static unsigned int r = GEN_SIMD_WIDTH/4u;
 | 
			
		||||
  };
 | 
			
		||||
  
 | 
			
		||||
  // SIMD vector types
 | 
			
		||||
  template <typename T>
 | 
			
		||||
  struct vec {
 | 
			
		||||
    alignas(GEN_SIMD_WIDTH) T v[W<T>::r];
 | 
			
		||||
  };
 | 
			
		||||
  
 | 
			
		||||
  typedef vec<float>   vecf;
 | 
			
		||||
  typedef vec<double>  vecd;
 | 
			
		||||
  
 | 
			
		||||
  struct Vsplat{
 | 
			
		||||
    //Complex float
 | 
			
		||||
    inline u128f operator()(float a, float b){
 | 
			
		||||
      u128f out; 
 | 
			
		||||
      out.f[0] = a;
 | 
			
		||||
      out.f[1] = b;
 | 
			
		||||
      out.f[2] = a;
 | 
			
		||||
      out.f[3] = b;
 | 
			
		||||
    // Complex
 | 
			
		||||
    template <typename T>
 | 
			
		||||
    inline vec<T> operator()(T a, T b){
 | 
			
		||||
      vec<T> out;
 | 
			
		||||
      
 | 
			
		||||
      VECTOR_FOR(i, W<T>::r, 2)
 | 
			
		||||
      {
 | 
			
		||||
        out.v[i]   = a;
 | 
			
		||||
        out.v[i+1] = b;
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      return out;
 | 
			
		||||
    }
 | 
			
		||||
    // Real float
 | 
			
		||||
    inline u128f operator()(float a){
 | 
			
		||||
      u128f out; 
 | 
			
		||||
      out.f[0] = a;
 | 
			
		||||
      out.f[1] = a;
 | 
			
		||||
      out.f[2] = a;
 | 
			
		||||
      out.f[3] = a;
 | 
			
		||||
    
 | 
			
		||||
    // Real
 | 
			
		||||
    template <typename T>
 | 
			
		||||
    inline vec<T> operator()(T a){
 | 
			
		||||
      vec<T> out;
 | 
			
		||||
      
 | 
			
		||||
      VECTOR_FOR(i, W<T>::r, 1)
 | 
			
		||||
      {
 | 
			
		||||
        out.v[i] = a;
 | 
			
		||||
      }
 | 
			
		||||
      
 | 
			
		||||
      return out;
 | 
			
		||||
    }
 | 
			
		||||
    //Complex double
 | 
			
		||||
    inline u128d operator()(double a, double b){
 | 
			
		||||
      u128d out; 
 | 
			
		||||
      out.f[0] = a;
 | 
			
		||||
      out.f[1] = b;
 | 
			
		||||
      return out;
 | 
			
		||||
    }
 | 
			
		||||
    //Real double
 | 
			
		||||
    inline u128d operator()(double a){
 | 
			
		||||
      u128d out; 
 | 
			
		||||
      out.f[0] = a;
 | 
			
		||||
      out.f[1] = a;
 | 
			
		||||
      return out;
 | 
			
		||||
    }
 | 
			
		||||
    //Integer
 | 
			
		||||
    
 | 
			
		||||
    // Integer
 | 
			
		||||
    inline int operator()(Integer a){
 | 
			
		||||
      return a;
 | 
			
		||||
    }
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
  struct Vstore{
 | 
			
		||||
    //Float 
 | 
			
		||||
    inline void operator()(u128f a, float* F){
 | 
			
		||||
      memcpy(F,a.f,4*sizeof(float));
 | 
			
		||||
    }
 | 
			
		||||
    //Double
 | 
			
		||||
    inline void operator()(u128d a, double* D){
 | 
			
		||||
      memcpy(D,a.f,2*sizeof(double));
 | 
			
		||||
    // Real
 | 
			
		||||
    template <typename T>
 | 
			
		||||
    inline void operator()(vec<T> a, T *D){
 | 
			
		||||
      *((vec<T> *)D) = a;
 | 
			
		||||
    }
 | 
			
		||||
    //Integer
 | 
			
		||||
    inline void operator()(int a, Integer* I){
 | 
			
		||||
      I[0] = a;
 | 
			
		||||
    inline void operator()(int a, Integer *I){
 | 
			
		||||
      *I = a;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
  struct Vstream{
 | 
			
		||||
    //Float
 | 
			
		||||
    inline void operator()(float * a, u128f b){
 | 
			
		||||
      memcpy(a,b.f,4*sizeof(float));
 | 
			
		||||
    // Real
 | 
			
		||||
    template <typename T>
 | 
			
		||||
    inline void operator()(T * a, vec<T> b){
 | 
			
		||||
      *((vec<T> *)a) = b;
 | 
			
		||||
    }
 | 
			
		||||
    //Double
 | 
			
		||||
    inline void operator()(double * a, u128d b){
 | 
			
		||||
      memcpy(a,b.f,2*sizeof(double));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
  struct Vset{
 | 
			
		||||
    // Complex float 
 | 
			
		||||
    inline u128f operator()(Grid::ComplexF *a){
 | 
			
		||||
      u128f out; 
 | 
			
		||||
      out.f[0] = a[0].real();
 | 
			
		||||
      out.f[1] = a[0].imag();
 | 
			
		||||
      out.f[2] = a[1].real();
 | 
			
		||||
      out.f[3] = a[1].imag();
 | 
			
		||||
    // Complex
 | 
			
		||||
    template <typename T>
 | 
			
		||||
    inline vec<T> operator()(std::complex<T> *a){
 | 
			
		||||
      vec<T> out;
 | 
			
		||||
      
 | 
			
		||||
      VECTOR_FOR(i, W<T>::c, 1)
 | 
			
		||||
      {
 | 
			
		||||
        out.v[2*i]   = a[i].real();
 | 
			
		||||
        out.v[2*i+1] = a[i].imag();
 | 
			
		||||
      }
 | 
			
		||||
      
 | 
			
		||||
      return out;
 | 
			
		||||
    }
 | 
			
		||||
    // Complex double 
 | 
			
		||||
    inline u128d operator()(Grid::ComplexD *a){
 | 
			
		||||
      u128d out; 
 | 
			
		||||
      out.f[0] = a[0].real();
 | 
			
		||||
      out.f[1] = a[0].imag();
 | 
			
		||||
      return out;
 | 
			
		||||
    }
 | 
			
		||||
    // Real float 
 | 
			
		||||
    inline u128f operator()(float *a){
 | 
			
		||||
      u128f out; 
 | 
			
		||||
      out.f[0] = a[0];
 | 
			
		||||
      out.f[1] = a[1];
 | 
			
		||||
      out.f[2] = a[2];
 | 
			
		||||
      out.f[3] = a[3];
 | 
			
		||||
      return out;
 | 
			
		||||
    }
 | 
			
		||||
    // Real double
 | 
			
		||||
    inline u128d operator()(double *a){
 | 
			
		||||
      u128d out; 
 | 
			
		||||
      out.f[0] = a[0];
 | 
			
		||||
      out.f[1] = a[1];
 | 
			
		||||
    
 | 
			
		||||
    // Real
 | 
			
		||||
    template <typename T>
 | 
			
		||||
    inline vec<T> operator()(T *a){
 | 
			
		||||
      vec<T> out;
 | 
			
		||||
      
 | 
			
		||||
      out = *((vec<T> *)a);
 | 
			
		||||
      
 | 
			
		||||
      return out;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // Integer
 | 
			
		||||
    inline int operator()(Integer *a){
 | 
			
		||||
      return a[0];
 | 
			
		||||
      return *a;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
  /////////////////////////////////////////////////////
 | 
			
		||||
  // Arithmetic operations
 | 
			
		||||
  /////////////////////////////////////////////////////
 | 
			
		||||
  struct Sum{
 | 
			
		||||
    // Complex/Real
 | 
			
		||||
    template <typename T>
 | 
			
		||||
    inline vec<T> operator()(vec<T> a, vec<T> b){
 | 
			
		||||
      vec<T> out;
 | 
			
		||||
      
 | 
			
		||||
      VECTOR_FOR(i, W<T>::r, 1)
 | 
			
		||||
      {
 | 
			
		||||
        out.v[i] = a.v[i] + b.v[i];
 | 
			
		||||
      }
 | 
			
		||||
      
 | 
			
		||||
      return out;
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    //I nteger
 | 
			
		||||
    inline int operator()(int a, int b){
 | 
			
		||||
      return a + b;
 | 
			
		||||
    }
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
  struct Sub{
 | 
			
		||||
    // Complex/Real
 | 
			
		||||
    template <typename T>
 | 
			
		||||
    inline vec<T> operator()(vec<T> a, vec<T> b){
 | 
			
		||||
      vec<T> out;
 | 
			
		||||
      
 | 
			
		||||
      VECTOR_FOR(i, W<T>::r, 1)
 | 
			
		||||
      {
 | 
			
		||||
        out.v[i] = a.v[i] - b.v[i];
 | 
			
		||||
      }
 | 
			
		||||
      
 | 
			
		||||
      return out;
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    //Integer
 | 
			
		||||
    inline int operator()(int a, int b){
 | 
			
		||||
      return a-b;
 | 
			
		||||
    }
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
  struct Mult{
 | 
			
		||||
    // Real
 | 
			
		||||
    template <typename T>
 | 
			
		||||
    inline vec<T> operator()(vec<T> a, vec<T> b){
 | 
			
		||||
      vec<T> out;
 | 
			
		||||
      
 | 
			
		||||
      VECTOR_FOR(i, W<T>::r, 1)
 | 
			
		||||
      {
 | 
			
		||||
        out.v[i] = a.v[i]*b.v[i];
 | 
			
		||||
      }
 | 
			
		||||
      
 | 
			
		||||
      return out;
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    // Integer
 | 
			
		||||
    inline int operator()(int a, int b){
 | 
			
		||||
      return a*b;
 | 
			
		||||
    }
 | 
			
		||||
  };
 | 
			
		||||
  
 | 
			
		||||
  #define cmul(a, b, c, i)\
 | 
			
		||||
  c[i]   = a[i]*b[i]   - a[i+1]*b[i+1];\
 | 
			
		||||
  c[i+1] = a[i]*b[i+1] + a[i+1]*b[i];
 | 
			
		||||
  
 | 
			
		||||
  struct MultComplex{
 | 
			
		||||
    // Complex
 | 
			
		||||
    template <typename T>
 | 
			
		||||
    inline vec<T> operator()(vec<T> a, vec<T> b){
 | 
			
		||||
      vec<T> out;
 | 
			
		||||
      
 | 
			
		||||
      VECTOR_FOR(i, W<T>::c, 1)
 | 
			
		||||
      {
 | 
			
		||||
        cmul(a.v, b.v, out.v, 2*i);
 | 
			
		||||
      }      
 | 
			
		||||
      
 | 
			
		||||
      return out;
 | 
			
		||||
    }
 | 
			
		||||
  };
 | 
			
		||||
  
 | 
			
		||||
  #undef cmul
 | 
			
		||||
 | 
			
		||||
  struct Div{
 | 
			
		||||
    // Real
 | 
			
		||||
    template <typename T>
 | 
			
		||||
    inline vec<T> operator()(vec<T> a, vec<T> b){
 | 
			
		||||
      vec<T> out;
 | 
			
		||||
      
 | 
			
		||||
      VECTOR_FOR(i, W<T>::r, 1)
 | 
			
		||||
      {
 | 
			
		||||
        out.v[i] = a.v[i]/b.v[i];
 | 
			
		||||
      }
 | 
			
		||||
      
 | 
			
		||||
      return out;
 | 
			
		||||
    }
 | 
			
		||||
  };
 | 
			
		||||
  
 | 
			
		||||
  #define conj(a, b, i)\
 | 
			
		||||
  b[i]   = a[i];\
 | 
			
		||||
  b[i+1] = -a[i+1];
 | 
			
		||||
  
 | 
			
		||||
  struct Conj{
 | 
			
		||||
    // Complex
 | 
			
		||||
    template <typename T>
 | 
			
		||||
    inline vec<T> operator()(vec<T> a){
 | 
			
		||||
      vec<T> out;
 | 
			
		||||
      
 | 
			
		||||
      VECTOR_FOR(i, W<T>::c, 1)
 | 
			
		||||
      {
 | 
			
		||||
        conj(a.v, out.v, 2*i);
 | 
			
		||||
      }
 | 
			
		||||
      
 | 
			
		||||
      return out;
 | 
			
		||||
    }
 | 
			
		||||
  };
 | 
			
		||||
  
 | 
			
		||||
  #undef conj
 | 
			
		||||
 | 
			
		||||
  #define timesmi(a, b, i)\
 | 
			
		||||
  b[i]   = a[i+1];\
 | 
			
		||||
  b[i+1] = -a[i];
 | 
			
		||||
  
 | 
			
		||||
  struct TimesMinusI{
 | 
			
		||||
    // Complex
 | 
			
		||||
    template <typename T>
 | 
			
		||||
    inline vec<T> operator()(vec<T> a, vec<T> b){
 | 
			
		||||
      vec<T> out;
 | 
			
		||||
      
 | 
			
		||||
      VECTOR_FOR(i, W<T>::c, 1)
 | 
			
		||||
      {
 | 
			
		||||
        timesmi(a.v, out.v, 2*i);
 | 
			
		||||
      }
 | 
			
		||||
      
 | 
			
		||||
      return out;
 | 
			
		||||
    }
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
  #undef timesmi
 | 
			
		||||
  
 | 
			
		||||
  #define timesi(a, b, i)\
 | 
			
		||||
  b[i]   = -a[i+1];\
 | 
			
		||||
  b[i+1] = a[i];
 | 
			
		||||
  
 | 
			
		||||
  struct TimesI{
 | 
			
		||||
    // Complex
 | 
			
		||||
    template <typename T>
 | 
			
		||||
    inline vec<T> operator()(vec<T> a, vec<T> b){
 | 
			
		||||
      vec<T> out;
 | 
			
		||||
      
 | 
			
		||||
      VECTOR_FOR(i, W<T>::c, 1)
 | 
			
		||||
      {
 | 
			
		||||
        timesi(a.v, out.v, 2*i);
 | 
			
		||||
      }
 | 
			
		||||
      
 | 
			
		||||
      return out;
 | 
			
		||||
    }
 | 
			
		||||
  };
 | 
			
		||||
  
 | 
			
		||||
  #undef timesi
 | 
			
		||||
 | 
			
		||||
  //////////////////////////////////////////////
 | 
			
		||||
  // Some Template specialization
 | 
			
		||||
  #define perm(a, b, n, w)\
 | 
			
		||||
  unsigned int _mask = w >> (n + 1);\
 | 
			
		||||
  VECTOR_FOR(i, w, 1)\
 | 
			
		||||
  {\
 | 
			
		||||
    b[i] = a[i^_mask];\
 | 
			
		||||
  }
 | 
			
		||||
  
 | 
			
		||||
  #define DECL_PERMUTE_N(n)\
 | 
			
		||||
  template <typename T>\
 | 
			
		||||
  static inline vec<T> Permute##n(vec<T> in) {\
 | 
			
		||||
    vec<T> out;\
 | 
			
		||||
    perm(in.v, out.v, n, W<T>::r);\
 | 
			
		||||
    return out;\
 | 
			
		||||
  }
 | 
			
		||||
  
 | 
			
		||||
  struct Permute{
 | 
			
		||||
    DECL_PERMUTE_N(0);
 | 
			
		||||
    DECL_PERMUTE_N(1);
 | 
			
		||||
    DECL_PERMUTE_N(2);
 | 
			
		||||
    DECL_PERMUTE_N(3);
 | 
			
		||||
  };
 | 
			
		||||
  
 | 
			
		||||
  #undef perm
 | 
			
		||||
  #undef DECL_PERMUTE_N
 | 
			
		||||
  
 | 
			
		||||
  #define rot(a, b, n, w)\
 | 
			
		||||
  VECTOR_FOR(i, w, 1)\
 | 
			
		||||
  {\
 | 
			
		||||
    b[i] = a[(i + n)%w];\
 | 
			
		||||
  }
 | 
			
		||||
  
 | 
			
		||||
  struct Rotate{
 | 
			
		||||
    template <typename T>
 | 
			
		||||
    static inline vec<T> rotate(vec<T> in, int n){
 | 
			
		||||
      vec<T> out;
 | 
			
		||||
      
 | 
			
		||||
      rot(in.v, out.v, n, W<T>::r);
 | 
			
		||||
      
 | 
			
		||||
      return out;
 | 
			
		||||
    }
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
  #undef rot
 | 
			
		||||
  
 | 
			
		||||
  #define acc(v, a, off, step, n)\
 | 
			
		||||
  for (unsigned int i = off; i < n; i += step)\
 | 
			
		||||
  {\
 | 
			
		||||
    a += v[i];\
 | 
			
		||||
  }
 | 
			
		||||
  
 | 
			
		||||
  template <typename Out_type, typename In_type>
 | 
			
		||||
  struct Reduce{
 | 
			
		||||
    //Need templated class to overload output type
 | 
			
		||||
@@ -164,316 +382,67 @@ namespace Optimization {
 | 
			
		||||
      return 0;
 | 
			
		||||
    }
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
  /////////////////////////////////////////////////////
 | 
			
		||||
  // Arithmetic operations
 | 
			
		||||
  /////////////////////////////////////////////////////
 | 
			
		||||
  struct Sum{
 | 
			
		||||
    //Complex/Real float
 | 
			
		||||
    inline u128f operator()(u128f a, u128f b){
 | 
			
		||||
      u128f out;
 | 
			
		||||
      out.f[0] = a.f[0] + b.f[0];
 | 
			
		||||
      out.f[1] = a.f[1] + b.f[1];
 | 
			
		||||
      out.f[2] = a.f[2] + b.f[2];
 | 
			
		||||
      out.f[3] = a.f[3] + b.f[3];
 | 
			
		||||
      return out;
 | 
			
		||||
    }
 | 
			
		||||
    //Complex/Real double
 | 
			
		||||
    inline u128d operator()(u128d a, u128d b){
 | 
			
		||||
      u128d out;
 | 
			
		||||
      out.f[0] = a.f[0] + b.f[0];
 | 
			
		||||
      out.f[1] = a.f[1] + b.f[1];
 | 
			
		||||
      return out;
 | 
			
		||||
    }
 | 
			
		||||
    //Integer
 | 
			
		||||
    inline int operator()(int a, int b){
 | 
			
		||||
      return a + b;
 | 
			
		||||
    }
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
  struct Sub{
 | 
			
		||||
    //Complex/Real float
 | 
			
		||||
    inline u128f operator()(u128f a, u128f b){
 | 
			
		||||
      u128f out;
 | 
			
		||||
      out.f[0] = a.f[0] - b.f[0];
 | 
			
		||||
      out.f[1] = a.f[1] - b.f[1];
 | 
			
		||||
      out.f[2] = a.f[2] - b.f[2];
 | 
			
		||||
      out.f[3] = a.f[3] - b.f[3];
 | 
			
		||||
      return out;
 | 
			
		||||
    }
 | 
			
		||||
    //Complex/Real double
 | 
			
		||||
    inline u128d operator()(u128d a, u128d b){
 | 
			
		||||
      u128d out;
 | 
			
		||||
      out.f[0] = a.f[0] - b.f[0];
 | 
			
		||||
      out.f[1] = a.f[1] - b.f[1];
 | 
			
		||||
      return out;
 | 
			
		||||
    }
 | 
			
		||||
    //Integer
 | 
			
		||||
    inline int operator()(int a, int b){
 | 
			
		||||
      return a-b;
 | 
			
		||||
    }
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
  struct MultComplex{
 | 
			
		||||
    // Complex float
 | 
			
		||||
    inline u128f operator()(u128f a, u128f b){
 | 
			
		||||
      u128f out;
 | 
			
		||||
      out.f[0] = a.f[0]*b.f[0] - a.f[1]*b.f[1];
 | 
			
		||||
      out.f[1] = a.f[0]*b.f[1] + a.f[1]*b.f[0];
 | 
			
		||||
      out.f[2] = a.f[2]*b.f[2] - a.f[3]*b.f[3];
 | 
			
		||||
      out.f[3] = a.f[2]*b.f[3] + a.f[3]*b.f[2];
 | 
			
		||||
      return out;
 | 
			
		||||
    }
 | 
			
		||||
    // Complex double
 | 
			
		||||
    inline u128d operator()(u128d a, u128d b){
 | 
			
		||||
      u128d out;
 | 
			
		||||
      out.f[0] = a.f[0]*b.f[0] - a.f[1]*b.f[1];
 | 
			
		||||
      out.f[1] = a.f[0]*b.f[1] + a.f[1]*b.f[0];
 | 
			
		||||
      return out;
 | 
			
		||||
    }
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
  struct Mult{
 | 
			
		||||
    //CK: Appear unneeded
 | 
			
		||||
    // inline float  mac(float a, float b,double c){
 | 
			
		||||
    //   return 0;
 | 
			
		||||
    // }
 | 
			
		||||
    // inline double mac(double a, double b,double c){
 | 
			
		||||
    //   return 0;
 | 
			
		||||
    // }
 | 
			
		||||
 | 
			
		||||
    // Real float
 | 
			
		||||
    inline u128f operator()(u128f a, u128f b){
 | 
			
		||||
      u128f out;
 | 
			
		||||
      out.f[0] = a.f[0]*b.f[0];
 | 
			
		||||
      out.f[1] = a.f[1]*b.f[1];
 | 
			
		||||
      out.f[2] = a.f[2]*b.f[2];
 | 
			
		||||
      out.f[3] = a.f[3]*b.f[3];
 | 
			
		||||
      return out;
 | 
			
		||||
    }
 | 
			
		||||
    // Real double
 | 
			
		||||
    inline u128d operator()(u128d a, u128d b){
 | 
			
		||||
      u128d out;
 | 
			
		||||
      out.f[0] = a.f[0]*b.f[0];
 | 
			
		||||
      out.f[1] = a.f[1]*b.f[1];
 | 
			
		||||
      return out;
 | 
			
		||||
    }
 | 
			
		||||
    // Integer
 | 
			
		||||
    inline int operator()(int a, int b){
 | 
			
		||||
      return a*b;
 | 
			
		||||
    }
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
  struct Conj{
 | 
			
		||||
    // Complex single
 | 
			
		||||
    inline u128f operator()(u128f in){
 | 
			
		||||
      u128f out;
 | 
			
		||||
      out.f[0] = in.f[0];
 | 
			
		||||
      out.f[1] = -in.f[1];
 | 
			
		||||
      out.f[2] = in.f[2];
 | 
			
		||||
      out.f[3] = -in.f[3];
 | 
			
		||||
      return out;
 | 
			
		||||
    }
 | 
			
		||||
    // Complex double
 | 
			
		||||
    inline u128d operator()(u128d in){
 | 
			
		||||
      u128d out;
 | 
			
		||||
      out.f[0] = in.f[0];
 | 
			
		||||
      out.f[1] = -in.f[1];
 | 
			
		||||
      return out;
 | 
			
		||||
    }
 | 
			
		||||
    // do not define for integer input
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
  struct TimesMinusI{
 | 
			
		||||
    //Complex single
 | 
			
		||||
    inline u128f operator()(u128f in, u128f ret){ //note ret is ignored
 | 
			
		||||
      u128f out;
 | 
			
		||||
      out.f[0] = in.f[1];
 | 
			
		||||
      out.f[1] = -in.f[0];
 | 
			
		||||
      out.f[2] = in.f[3];
 | 
			
		||||
      out.f[3] = -in.f[2];
 | 
			
		||||
      return out;
 | 
			
		||||
    }
 | 
			
		||||
    //Complex double
 | 
			
		||||
    inline u128d operator()(u128d in, u128d ret){
 | 
			
		||||
      u128d out;
 | 
			
		||||
      out.f[0] = in.f[1];
 | 
			
		||||
      out.f[1] = -in.f[0];
 | 
			
		||||
      return out;
 | 
			
		||||
    }
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
  struct TimesI{
 | 
			
		||||
    //Complex single
 | 
			
		||||
    inline u128f operator()(u128f in, u128f ret){ //note ret is ignored
 | 
			
		||||
      u128f out;
 | 
			
		||||
      out.f[0] = -in.f[1];
 | 
			
		||||
      out.f[1] = in.f[0];
 | 
			
		||||
      out.f[2] = -in.f[3];
 | 
			
		||||
      out.f[3] = in.f[2];
 | 
			
		||||
      return out;
 | 
			
		||||
    }
 | 
			
		||||
    //Complex double
 | 
			
		||||
    inline u128d operator()(u128d in, u128d ret){
 | 
			
		||||
      u128d out;
 | 
			
		||||
      out.f[0] = -in.f[1];
 | 
			
		||||
      out.f[1] = in.f[0];
 | 
			
		||||
      return out;
 | 
			
		||||
    }
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
  //////////////////////////////////////////////
 | 
			
		||||
  // Some Template specialization
 | 
			
		||||
  struct Permute{
 | 
			
		||||
    //We just have to mirror the permutes of Grid_sse4.h
 | 
			
		||||
    static inline u128f Permute0(u128f in){ //AB CD -> CD AB
 | 
			
		||||
      u128f out;
 | 
			
		||||
      out.f[0] = in.f[2];
 | 
			
		||||
      out.f[1] = in.f[3];
 | 
			
		||||
      out.f[2] = in.f[0];
 | 
			
		||||
      out.f[3] = in.f[1];
 | 
			
		||||
      return out;
 | 
			
		||||
    };
 | 
			
		||||
    static inline u128f Permute1(u128f in){ //AB CD -> BA DC
 | 
			
		||||
      u128f out;
 | 
			
		||||
      out.f[0] = in.f[1];
 | 
			
		||||
      out.f[1] = in.f[0];
 | 
			
		||||
      out.f[2] = in.f[3];
 | 
			
		||||
      out.f[3] = in.f[2];
 | 
			
		||||
      return out;
 | 
			
		||||
    };
 | 
			
		||||
    static inline u128f Permute2(u128f in){
 | 
			
		||||
      return in;
 | 
			
		||||
    };
 | 
			
		||||
    static inline u128f Permute3(u128f in){
 | 
			
		||||
      return in;
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    static inline u128d Permute0(u128d in){ //AB -> BA
 | 
			
		||||
      u128d out;
 | 
			
		||||
      out.f[0] = in.f[1];
 | 
			
		||||
      out.f[1] = in.f[0];
 | 
			
		||||
      return out;      
 | 
			
		||||
    };
 | 
			
		||||
    static inline u128d Permute1(u128d in){
 | 
			
		||||
      return in;
 | 
			
		||||
    };
 | 
			
		||||
    static inline u128d Permute2(u128d in){
 | 
			
		||||
      return in;
 | 
			
		||||
    };
 | 
			
		||||
    static inline u128d Permute3(u128d in){
 | 
			
		||||
      return in;
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
  };
 | 
			
		||||
  
 | 
			
		||||
  template < typename vtype > 
 | 
			
		||||
    void permute(vtype &a, vtype b, int perm) {
 | 
			
		||||
   };
 | 
			
		||||
    
 | 
			
		||||
  struct Rotate{
 | 
			
		||||
 | 
			
		||||
    static inline u128f rotate(u128f in,int n){
 | 
			
		||||
      u128f out;
 | 
			
		||||
      switch(n){
 | 
			
		||||
      case 0:
 | 
			
		||||
        out.f[0] = in.f[0];
 | 
			
		||||
        out.f[1] = in.f[1];
 | 
			
		||||
        out.f[2] = in.f[2];
 | 
			
		||||
        out.f[3] = in.f[3];
 | 
			
		||||
        break;
 | 
			
		||||
      case 1:
 | 
			
		||||
        out.f[0] = in.f[1];
 | 
			
		||||
        out.f[1] = in.f[2];
 | 
			
		||||
        out.f[2] = in.f[3];
 | 
			
		||||
        out.f[3] = in.f[0];
 | 
			
		||||
        break;
 | 
			
		||||
      case 2:
 | 
			
		||||
        out.f[0] = in.f[2];
 | 
			
		||||
        out.f[1] = in.f[3];
 | 
			
		||||
        out.f[2] = in.f[0];
 | 
			
		||||
        out.f[3] = in.f[1];
 | 
			
		||||
        break;
 | 
			
		||||
      case 3:
 | 
			
		||||
        out.f[0] = in.f[3];
 | 
			
		||||
        out.f[1] = in.f[0];
 | 
			
		||||
        out.f[2] = in.f[1];
 | 
			
		||||
        out.f[3] = in.f[2];
 | 
			
		||||
        break;
 | 
			
		||||
      default: assert(0);
 | 
			
		||||
      }
 | 
			
		||||
      return out;
 | 
			
		||||
    }
 | 
			
		||||
    static inline u128d rotate(u128d in,int n){
 | 
			
		||||
      u128d out;
 | 
			
		||||
      switch(n){
 | 
			
		||||
      case 0:
 | 
			
		||||
        out.f[0] = in.f[0];
 | 
			
		||||
        out.f[1] = in.f[1];
 | 
			
		||||
        break;
 | 
			
		||||
      case 1:
 | 
			
		||||
        out.f[0] = in.f[1];
 | 
			
		||||
        out.f[1] = in.f[0];
 | 
			
		||||
        break;
 | 
			
		||||
      default: assert(0);
 | 
			
		||||
      }
 | 
			
		||||
      return out;
 | 
			
		||||
    }
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
  //Complex float Reduce
 | 
			
		||||
  template<>
 | 
			
		||||
  inline Grid::ComplexF Reduce<Grid::ComplexF, u128f>::operator()(u128f in){ //2 complex
 | 
			
		||||
    return Grid::ComplexF(in.f[0] + in.f[2], in.f[1] + in.f[3]);
 | 
			
		||||
  template <>
 | 
			
		||||
  inline Grid::ComplexF Reduce<Grid::ComplexF, vecf>::operator()(vecf in){
 | 
			
		||||
    float a = 0.f, b = 0.f;
 | 
			
		||||
    
 | 
			
		||||
    acc(in.v, a, 0, 2, W<float>::r);
 | 
			
		||||
    acc(in.v, b, 1, 2, W<float>::r);
 | 
			
		||||
    
 | 
			
		||||
    return Grid::ComplexF(a, b);
 | 
			
		||||
  }
 | 
			
		||||
  
 | 
			
		||||
  //Real float Reduce
 | 
			
		||||
  template<>
 | 
			
		||||
  inline Grid::RealF Reduce<Grid::RealF, u128f>::operator()(u128f in){ //4 floats
 | 
			
		||||
    return in.f[0] + in.f[1] + in.f[2] + in.f[3];
 | 
			
		||||
  inline Grid::RealF Reduce<Grid::RealF, vecf>::operator()(vecf in){
 | 
			
		||||
    float a = 0.;
 | 
			
		||||
    
 | 
			
		||||
    acc(in.v, a, 0, 1, W<float>::r);
 | 
			
		||||
    
 | 
			
		||||
    return a;
 | 
			
		||||
  }
 | 
			
		||||
  
 | 
			
		||||
  
 | 
			
		||||
  //Complex double Reduce
 | 
			
		||||
  template<>
 | 
			
		||||
  inline Grid::ComplexD Reduce<Grid::ComplexD, u128d>::operator()(u128d in){ //1 complex
 | 
			
		||||
    return Grid::ComplexD(in.f[0],in.f[1]);
 | 
			
		||||
  inline Grid::ComplexD Reduce<Grid::ComplexD, vecd>::operator()(vecd in){
 | 
			
		||||
    double a = 0., b = 0.;
 | 
			
		||||
    
 | 
			
		||||
    acc(in.v, a, 0, 2, W<double>::r);
 | 
			
		||||
    acc(in.v, b, 1, 2, W<double>::r);
 | 
			
		||||
    
 | 
			
		||||
    return Grid::ComplexD(a, b);
 | 
			
		||||
  }
 | 
			
		||||
  
 | 
			
		||||
  //Real double Reduce
 | 
			
		||||
  template<>
 | 
			
		||||
  inline Grid::RealD Reduce<Grid::RealD, u128d>::operator()(u128d in){ //2 doubles
 | 
			
		||||
    return in.f[0] + in.f[1];
 | 
			
		||||
  inline Grid::RealD Reduce<Grid::RealD, vecd>::operator()(vecd in){
 | 
			
		||||
    double a = 0.f;
 | 
			
		||||
    
 | 
			
		||||
    acc(in.v, a, 0, 1, W<double>::r);
 | 
			
		||||
    
 | 
			
		||||
    return a;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  //Integer Reduce
 | 
			
		||||
  template<>
 | 
			
		||||
  inline Integer Reduce<Integer, int>::operator()(int in){
 | 
			
		||||
    // FIXME unimplemented
 | 
			
		||||
   printf("Reduce : Missing integer implementation -> FIX\n");
 | 
			
		||||
    assert(0);
 | 
			
		||||
    return in;
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
//////////////////////////////////////////////////////////////////////////////////////
 | 
			
		||||
// Here assign types 
 | 
			
		||||
 | 
			
		||||
  typedef Optimization::u128f SIMD_Ftype;  // Single precision type
 | 
			
		||||
  typedef Optimization::u128d SIMD_Dtype; // Double precision type
 | 
			
		||||
  typedef Optimization::vecf SIMD_Ftype; // Single precision type
 | 
			
		||||
  typedef Optimization::vecd SIMD_Dtype; // Double precision type
 | 
			
		||||
  typedef int SIMD_Itype; // Integer type
 | 
			
		||||
 | 
			
		||||
  // prefetch utilities
 | 
			
		||||
  inline void v_prefetch0(int size, const char *ptr){};
 | 
			
		||||
  inline void prefetch_HINT_T0(const char *ptr){};
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
  // Gpermute function
 | 
			
		||||
  template < typename VectorSIMD > 
 | 
			
		||||
    inline void Gpermute(VectorSIMD &y,const VectorSIMD &b, int perm ) {
 | 
			
		||||
    Optimization::permute(y.v,b.v,perm);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
  // Function name aliases
 | 
			
		||||
  typedef Optimization::Vsplat   VsplatSIMD;
 | 
			
		||||
  typedef Optimization::Vstore   VstoreSIMD;
 | 
			
		||||
@@ -481,16 +450,13 @@ namespace Optimization {
 | 
			
		||||
  typedef Optimization::Vstream  VstreamSIMD;
 | 
			
		||||
  template <typename S, typename T> using ReduceSIMD = Optimization::Reduce<S,T>;
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
  // Arithmetic operations
 | 
			
		||||
  typedef Optimization::Sum         SumSIMD;
 | 
			
		||||
  typedef Optimization::Sub         SubSIMD;
 | 
			
		||||
  typedef Optimization::Div         DivSIMD;
 | 
			
		||||
  typedef Optimization::Mult        MultSIMD;
 | 
			
		||||
  typedef Optimization::MultComplex MultComplexSIMD;
 | 
			
		||||
  typedef Optimization::Conj        ConjSIMD;
 | 
			
		||||
  typedef Optimization::TimesMinusI TimesMinusISIMD;
 | 
			
		||||
  typedef Optimization::TimesI      TimesISIMD;
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -26,14 +26,6 @@ Author: paboyle <paboyle@ph.ed.ac.uk>
 | 
			
		||||
    See the full license in the file "LICENSE" in the top level distribution directory
 | 
			
		||||
    *************************************************************************************/
 | 
			
		||||
    /*  END LEGAL */
 | 
			
		||||
//----------------------------------------------------------------------
 | 
			
		||||
/*! @file Grid_knc.h
 | 
			
		||||
  @brief Optimization libraries for AVX512 instructions set for KNC
 | 
			
		||||
 | 
			
		||||
  Using intrinsics
 | 
			
		||||
*/
 | 
			
		||||
// Time-stamp: <2015-06-09 14:27:28 neo>
 | 
			
		||||
//----------------------------------------------------------------------
 | 
			
		||||
 | 
			
		||||
#include <immintrin.h>
 | 
			
		||||
#include <zmmintrin.h>
 | 
			
		||||
 
 | 
			
		||||
@@ -38,13 +38,13 @@ directory
 | 
			
		||||
#ifndef GRID_VECTOR_TYPES
 | 
			
		||||
#define GRID_VECTOR_TYPES
 | 
			
		||||
 | 
			
		||||
#ifdef GENERIC_VEC
 | 
			
		||||
#ifdef GEN
 | 
			
		||||
#include "Grid_generic.h"
 | 
			
		||||
#endif
 | 
			
		||||
#ifdef SSE4
 | 
			
		||||
#include "Grid_sse4.h"
 | 
			
		||||
#endif
 | 
			
		||||
#if defined(AVX1) || defined(AVX2) || defined(AVXFMA4)
 | 
			
		||||
#if defined(AVX1) || defined (AVXFMA) || defined(AVX2) || defined(AVXFMA4)
 | 
			
		||||
#include "Grid_avx.h"
 | 
			
		||||
#endif
 | 
			
		||||
#if defined AVX512
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user