mirror of
				https://github.com/paboyle/Grid.git
				synced 2025-11-03 21:44:33 +00:00 
			
		
		
		
	Merge branch 'develop' into feature/doxygen
# Conflicts: # configure.ac
This commit is contained in:
		
							
								
								
									
										4
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										4
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							@@ -95,6 +95,10 @@ build.sh
 | 
				
			|||||||
################
 | 
					################
 | 
				
			||||||
lib/Eigen/*
 | 
					lib/Eigen/*
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# FFTW source #
 | 
				
			||||||
 | 
					################
 | 
				
			||||||
 | 
					lib/fftw/*
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# libtool macros #
 | 
					# libtool macros #
 | 
				
			||||||
##################
 | 
					##################
 | 
				
			||||||
m4/lt*
 | 
					m4/lt*
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										16
									
								
								.travis.yml
									
									
									
									
									
								
							
							
						
						
									
										16
									
								
								.travis.yml
									
									
									
									
									
								
							@@ -23,6 +23,8 @@ matrix:
 | 
				
			|||||||
            - libmpfr-dev
 | 
					            - libmpfr-dev
 | 
				
			||||||
            - libgmp-dev
 | 
					            - libgmp-dev
 | 
				
			||||||
            - libmpc-dev
 | 
					            - libmpc-dev
 | 
				
			||||||
 | 
					            - libopenmpi-dev
 | 
				
			||||||
 | 
					            - openmpi-bin
 | 
				
			||||||
            - binutils-dev
 | 
					            - binutils-dev
 | 
				
			||||||
      env: VERSION=-4.9
 | 
					      env: VERSION=-4.9
 | 
				
			||||||
    - compiler: gcc
 | 
					    - compiler: gcc
 | 
				
			||||||
@@ -35,6 +37,8 @@ matrix:
 | 
				
			|||||||
            - libmpfr-dev
 | 
					            - libmpfr-dev
 | 
				
			||||||
            - libgmp-dev
 | 
					            - libgmp-dev
 | 
				
			||||||
            - libmpc-dev
 | 
					            - libmpc-dev
 | 
				
			||||||
 | 
					            - libopenmpi-dev
 | 
				
			||||||
 | 
					            - openmpi-bin
 | 
				
			||||||
            - binutils-dev
 | 
					            - binutils-dev
 | 
				
			||||||
      env: VERSION=-5
 | 
					      env: VERSION=-5
 | 
				
			||||||
    - compiler: clang
 | 
					    - compiler: clang
 | 
				
			||||||
@@ -47,6 +51,8 @@ matrix:
 | 
				
			|||||||
            - libmpfr-dev
 | 
					            - libmpfr-dev
 | 
				
			||||||
            - libgmp-dev
 | 
					            - libgmp-dev
 | 
				
			||||||
            - libmpc-dev
 | 
					            - libmpc-dev
 | 
				
			||||||
 | 
					            - libopenmpi-dev
 | 
				
			||||||
 | 
					            - openmpi-bin
 | 
				
			||||||
            - binutils-dev
 | 
					            - binutils-dev
 | 
				
			||||||
      env: CLANG_LINK=http://llvm.org/releases/3.8.0/clang+llvm-3.8.0-x86_64-linux-gnu-ubuntu-14.04.tar.xz
 | 
					      env: CLANG_LINK=http://llvm.org/releases/3.8.0/clang+llvm-3.8.0-x86_64-linux-gnu-ubuntu-14.04.tar.xz
 | 
				
			||||||
    - compiler: clang
 | 
					    - compiler: clang
 | 
				
			||||||
@@ -59,6 +65,8 @@ matrix:
 | 
				
			|||||||
            - libmpfr-dev
 | 
					            - libmpfr-dev
 | 
				
			||||||
            - libgmp-dev
 | 
					            - libgmp-dev
 | 
				
			||||||
            - libmpc-dev
 | 
					            - libmpc-dev
 | 
				
			||||||
 | 
					            - libopenmpi-dev
 | 
				
			||||||
 | 
					            - openmpi-bin
 | 
				
			||||||
            - binutils-dev
 | 
					            - binutils-dev
 | 
				
			||||||
      env: CLANG_LINK=http://llvm.org/releases/3.7.0/clang+llvm-3.7.0-x86_64-linux-gnu-ubuntu-14.04.tar.xz
 | 
					      env: CLANG_LINK=http://llvm.org/releases/3.7.0/clang+llvm-3.7.0-x86_64-linux-gnu-ubuntu-14.04.tar.xz
 | 
				
			||||||
      
 | 
					      
 | 
				
			||||||
@@ -69,6 +77,7 @@ before_install:
 | 
				
			|||||||
    - if [[ "$TRAVIS_OS_NAME" == "linux" ]] && [[ "$CC" == "clang" ]]; then export LD_LIBRARY_PATH="${GRIDDIR}/clang/lib:${LD_LIBRARY_PATH}"; fi
 | 
					    - if [[ "$TRAVIS_OS_NAME" == "linux" ]] && [[ "$CC" == "clang" ]]; then export LD_LIBRARY_PATH="${GRIDDIR}/clang/lib:${LD_LIBRARY_PATH}"; fi
 | 
				
			||||||
    - if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then brew update; fi
 | 
					    - if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then brew update; fi
 | 
				
			||||||
    - if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then brew install libmpc; fi
 | 
					    - if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then brew install libmpc; fi
 | 
				
			||||||
 | 
					    - if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then brew install openmpi; fi
 | 
				
			||||||
    - if [[ "$TRAVIS_OS_NAME" == "osx" ]] && [[ "$CC" == "gcc" ]]; then brew install gcc5; fi
 | 
					    - if [[ "$TRAVIS_OS_NAME" == "osx" ]] && [[ "$CC" == "gcc" ]]; then brew install gcc5; fi
 | 
				
			||||||
    
 | 
					    
 | 
				
			||||||
install:
 | 
					install:
 | 
				
			||||||
@@ -92,3 +101,10 @@ script:
 | 
				
			|||||||
    - ../configure --enable-precision=double --enable-simd=SSE4 --enable-comms=none
 | 
					    - ../configure --enable-precision=double --enable-simd=SSE4 --enable-comms=none
 | 
				
			||||||
    - make -j4
 | 
					    - make -j4
 | 
				
			||||||
    - ./benchmarks/Benchmark_dwf --threads 1
 | 
					    - ./benchmarks/Benchmark_dwf --threads 1
 | 
				
			||||||
 | 
					    - echo make clean
 | 
				
			||||||
 | 
					    - if [[ "$TRAVIS_OS_NAME" == "linux" ]]; then export CXXFLAGS='-DMPI_UINT32_T=MPI_UNSIGNED -DMPI_UINT64_T=MPI_UNSIGNED_LONG'; fi
 | 
				
			||||||
 | 
					    - ../configure --enable-precision=single --enable-simd=SSE4 --enable-comms=mpi-auto
 | 
				
			||||||
 | 
					    - make -j4
 | 
				
			||||||
 | 
					    - if [[ "$TRAVIS_OS_NAME" == "linux" ]]; then mpirun.openmpi -n 2 ./benchmarks/Benchmark_dwf --threads 1 --mpi 2.1.1.1; fi
 | 
				
			||||||
 | 
					    - if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then mpirun -n 2 ./benchmarks/Benchmark_dwf --threads 1 --mpi 2.1.1.1; fi
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -86,18 +86,6 @@ int main (int argc, char ** argv)
 | 
				
			|||||||
  LatticeFermion    tmp(FGrid);
 | 
					  LatticeFermion    tmp(FGrid);
 | 
				
			||||||
  LatticeFermion    err(FGrid);
 | 
					  LatticeFermion    err(FGrid);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  /*  src=zero;
 | 
					 | 
				
			||||||
  std::vector<int> origin(5,0);
 | 
					 | 
				
			||||||
  SpinColourVector f=zero;
 | 
					 | 
				
			||||||
  for(int sp=0;sp<4;sp++){
 | 
					 | 
				
			||||||
  for(int co=0;co<3;co++){
 | 
					 | 
				
			||||||
    f()(sp)(co)=Complex(1.0,0.0); 
 | 
					 | 
				
			||||||
  }}
 | 
					 | 
				
			||||||
  pokeSite(f,src,origin);
 | 
					 | 
				
			||||||
  */
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  ColourMatrix cm = Complex(1.0,0.0);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  LatticeGaugeField Umu(UGrid); 
 | 
					  LatticeGaugeField Umu(UGrid); 
 | 
				
			||||||
  random(RNG4,Umu);
 | 
					  random(RNG4,Umu);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -144,10 +132,12 @@ int main (int argc, char ** argv)
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
  DomainWallFermionR Dw(Umu,*FGrid,*FrbGrid,*UGrid,*UrbGrid,mass,M5);
 | 
					  DomainWallFermionR Dw(Umu,*FGrid,*FrbGrid,*UGrid,*UrbGrid,mass,M5);
 | 
				
			||||||
  
 | 
					  
 | 
				
			||||||
  std::cout<<GridLogMessage << "Calling Dw"<<std::endl;
 | 
					  std::cout<<GridLogMessage << "Naive wilson implementation "<<std::endl;
 | 
				
			||||||
 | 
					  std::cout << GridLogMessage<< "Calling Dw"<<std::endl;
 | 
				
			||||||
  int ncall =100;
 | 
					  int ncall =100;
 | 
				
			||||||
  if (1) {
 | 
					  if (1) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    Dw.ZeroCounters();
 | 
				
			||||||
    double t0=usecond();
 | 
					    double t0=usecond();
 | 
				
			||||||
    for(int i=0;i<ncall;i++){
 | 
					    for(int i=0;i<ncall;i++){
 | 
				
			||||||
      __SSC_START;
 | 
					      __SSC_START;
 | 
				
			||||||
@@ -166,7 +156,7 @@ int main (int argc, char ** argv)
 | 
				
			|||||||
    std::cout<<GridLogMessage << "mflop/s per node =  "<< flops/(t1-t0)/NP<<std::endl;
 | 
					    std::cout<<GridLogMessage << "mflop/s per node =  "<< flops/(t1-t0)/NP<<std::endl;
 | 
				
			||||||
    err = ref-result; 
 | 
					    err = ref-result; 
 | 
				
			||||||
    std::cout<<GridLogMessage << "norm diff   "<< norm2(err)<<std::endl;
 | 
					    std::cout<<GridLogMessage << "norm diff   "<< norm2(err)<<std::endl;
 | 
				
			||||||
    //    Dw.Report();
 | 
					    Dw.Report();
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  if (1)
 | 
					  if (1)
 | 
				
			||||||
@@ -188,8 +178,9 @@ int main (int argc, char ** argv)
 | 
				
			|||||||
      peekSite(tmp,src,site);
 | 
					      peekSite(tmp,src,site);
 | 
				
			||||||
      pokeSite(tmp,ssrc,site);
 | 
					      pokeSite(tmp,ssrc,site);
 | 
				
			||||||
    }}}}}
 | 
					    }}}}}
 | 
				
			||||||
    std::cout<<"src norms "<< norm2(src)<<" " <<norm2(ssrc)<<std::endl;
 | 
					    std::cout<<GridLogMessage<< "src norms "<< norm2(src)<<" " <<norm2(ssrc)<<std::endl;
 | 
				
			||||||
    double t0=usecond();
 | 
					    double t0=usecond();
 | 
				
			||||||
 | 
					    sDw.ZeroCounters();
 | 
				
			||||||
    for(int i=0;i<ncall;i++){
 | 
					    for(int i=0;i<ncall;i++){
 | 
				
			||||||
      __SSC_START;
 | 
					      __SSC_START;
 | 
				
			||||||
      sDw.Dhop(ssrc,sresult,0);
 | 
					      sDw.Dhop(ssrc,sresult,0);
 | 
				
			||||||
@@ -199,23 +190,23 @@ int main (int argc, char ** argv)
 | 
				
			|||||||
    double volume=Ls;  for(int mu=0;mu<Nd;mu++) volume=volume*latt4[mu];
 | 
					    double volume=Ls;  for(int mu=0;mu<Nd;mu++) volume=volume*latt4[mu];
 | 
				
			||||||
    double flops=1344*volume*ncall;
 | 
					    double flops=1344*volume*ncall;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    std::cout<<GridLogMessage << "Called Dw sinner "<<ncall<<" times in "<<t1-t0<<" us"<<std::endl;
 | 
					    std::cout<<GridLogMessage << "Called Dw s_inner "<<ncall<<" times in "<<t1-t0<<" us"<<std::endl;
 | 
				
			||||||
    std::cout<<GridLogMessage << "mflop/s =   "<< flops/(t1-t0)<<std::endl;
 | 
					    std::cout<<GridLogMessage << "mflop/s =   "<< flops/(t1-t0)<<std::endl;
 | 
				
			||||||
    std::cout<<GridLogMessage << "mflop/s per node =  "<< flops/(t1-t0)/NP<<std::endl;
 | 
					    std::cout<<GridLogMessage << "mflop/s per node =  "<< flops/(t1-t0)/NP<<std::endl;
 | 
				
			||||||
    //  sDw.Report();
 | 
					    sDw.Report();
 | 
				
			||||||
  
 | 
					  
 | 
				
			||||||
    if(0){
 | 
					    if(0){
 | 
				
			||||||
      for(int i=0;i< PerformanceCounter::NumTypes(); i++ ){
 | 
					      for(int i=0;i< PerformanceCounter::NumTypes(); i++ ){
 | 
				
			||||||
	sDw.Dhop(ssrc,sresult,0);
 | 
					  sDw.Dhop(ssrc,sresult,0);
 | 
				
			||||||
	PerformanceCounter Counter(i);
 | 
					  PerformanceCounter Counter(i);
 | 
				
			||||||
	Counter.Start();
 | 
					  Counter.Start();
 | 
				
			||||||
	sDw.Dhop(ssrc,sresult,0);
 | 
					  sDw.Dhop(ssrc,sresult,0);
 | 
				
			||||||
	Counter.Stop();
 | 
					  Counter.Stop();
 | 
				
			||||||
	Counter.Report();
 | 
					  Counter.Report();
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    std::cout<<"res norms "<< norm2(result)<<" " <<norm2(sresult)<<std::endl;
 | 
					    std::cout<<GridLogMessage<< "res norms "<< norm2(result)<<" " <<norm2(sresult)<<std::endl;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    RealF sum=0;
 | 
					    RealF sum=0;
 | 
				
			||||||
@@ -230,12 +221,12 @@ int main (int argc, char ** argv)
 | 
				
			|||||||
      peekSite(simd,sresult,site);
 | 
					      peekSite(simd,sresult,site);
 | 
				
			||||||
      sum=sum+norm2(normal-simd);
 | 
					      sum=sum+norm2(normal-simd);
 | 
				
			||||||
      if (norm2(normal-simd) > 1.0e-6 ) {
 | 
					      if (norm2(normal-simd) > 1.0e-6 ) {
 | 
				
			||||||
	std::cout << "site "<<x<<","<<y<<","<<z<<","<<t<<","<<s<<" "<<norm2(normal-simd)<<std::endl;
 | 
					  std::cout << "site "<<x<<","<<y<<","<<z<<","<<t<<","<<s<<" "<<norm2(normal-simd)<<std::endl;
 | 
				
			||||||
	std::cout << "site "<<x<<","<<y<<","<<z<<","<<t<<","<<s<<" normal "<<normal<<std::endl;
 | 
					  std::cout << "site "<<x<<","<<y<<","<<z<<","<<t<<","<<s<<" normal "<<normal<<std::endl;
 | 
				
			||||||
	std::cout << "site "<<x<<","<<y<<","<<z<<","<<t<<","<<s<<" simd   "<<simd<<std::endl;
 | 
					  std::cout << "site "<<x<<","<<y<<","<<z<<","<<t<<","<<s<<" simd   "<<simd<<std::endl;
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
    }}}}}
 | 
					    }}}}}
 | 
				
			||||||
    std::cout<<" difference between normal and simd is "<<sum<<std::endl;
 | 
					    std::cout<<GridLogMessage<<" difference between normal and simd is "<<sum<<std::endl;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (1) {
 | 
					    if (1) {
 | 
				
			||||||
@@ -259,9 +250,10 @@ int main (int argc, char ** argv)
 | 
				
			|||||||
      sr_e = zero;
 | 
					      sr_e = zero;
 | 
				
			||||||
      sr_o = zero;
 | 
					      sr_o = zero;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      sDw.ZeroCounters();
 | 
				
			||||||
      double t0=usecond();
 | 
					      double t0=usecond();
 | 
				
			||||||
      for(int i=0;i<ncall;i++){
 | 
					      for (int i = 0; i < ncall; i++) {
 | 
				
			||||||
	sDw.DhopEO(ssrc_o,sr_e,DaggerNo);
 | 
					        sDw.DhopEO(ssrc_o, sr_e, DaggerNo);
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
      double t1=usecond();
 | 
					      double t1=usecond();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -270,6 +262,7 @@ int main (int argc, char ** argv)
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
      std::cout<<GridLogMessage << "sDeo mflop/s =   "<< flops/(t1-t0)<<std::endl;
 | 
					      std::cout<<GridLogMessage << "sDeo mflop/s =   "<< flops/(t1-t0)<<std::endl;
 | 
				
			||||||
      std::cout<<GridLogMessage << "sDeo mflop/s per node   "<< flops/(t1-t0)/NP<<std::endl;
 | 
					      std::cout<<GridLogMessage << "sDeo mflop/s per node   "<< flops/(t1-t0)/NP<<std::endl;
 | 
				
			||||||
 | 
					      sDw.Report();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      sDw.DhopEO(ssrc_o,sr_e,DaggerNo);
 | 
					      sDw.DhopEO(ssrc_o,sr_e,DaggerNo);
 | 
				
			||||||
      sDw.DhopOE(ssrc_e,sr_o,DaggerNo);
 | 
					      sDw.DhopOE(ssrc_e,sr_o,DaggerNo);
 | 
				
			||||||
@@ -294,18 +287,19 @@ int main (int argc, char ** argv)
 | 
				
			|||||||
      //    ref =  src - Gamma(Gamma::GammaX)* src ; // 1+gamma_x
 | 
					      //    ref =  src - Gamma(Gamma::GammaX)* src ; // 1+gamma_x
 | 
				
			||||||
      tmp = U[mu]*Cshift(src,mu+1,1);
 | 
					      tmp = U[mu]*Cshift(src,mu+1,1);
 | 
				
			||||||
      for(int i=0;i<ref._odata.size();i++){
 | 
					      for(int i=0;i<ref._odata.size();i++){
 | 
				
			||||||
	ref._odata[i]+= tmp._odata[i] + Gamma(Gmu[mu])*tmp._odata[i]; ;
 | 
					  ref._odata[i]+= tmp._odata[i] + Gamma(Gmu[mu])*tmp._odata[i]; ;
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      tmp =adj(U[mu])*src;
 | 
					      tmp =adj(U[mu])*src;
 | 
				
			||||||
      tmp =Cshift(tmp,mu+1,-1);
 | 
					      tmp =Cshift(tmp,mu+1,-1);
 | 
				
			||||||
      for(int i=0;i<ref._odata.size();i++){
 | 
					      for(int i=0;i<ref._odata.size();i++){
 | 
				
			||||||
	ref._odata[i]+= tmp._odata[i] - Gamma(Gmu[mu])*tmp._odata[i]; ;
 | 
					  ref._odata[i]+= tmp._odata[i] - Gamma(Gmu[mu])*tmp._odata[i]; ;
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    ref = -0.5*ref;
 | 
					    ref = -0.5*ref;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
  Dw.Dhop(src,result,1);
 | 
					  Dw.Dhop(src,result,1);
 | 
				
			||||||
 | 
					  std::cout << GridLogMessage << "Naive wilson implementation Dag" << std::endl;
 | 
				
			||||||
  std::cout<<GridLogMessage << "Called DwDag"<<std::endl;
 | 
					  std::cout<<GridLogMessage << "Called DwDag"<<std::endl;
 | 
				
			||||||
  std::cout<<GridLogMessage << "norm result "<< norm2(result)<<std::endl;
 | 
					  std::cout<<GridLogMessage << "norm result "<< norm2(result)<<std::endl;
 | 
				
			||||||
  std::cout<<GridLogMessage << "norm ref    "<< norm2(ref)<<std::endl;
 | 
					  std::cout<<GridLogMessage << "norm ref    "<< norm2(ref)<<std::endl;
 | 
				
			||||||
@@ -327,6 +321,7 @@ int main (int argc, char ** argv)
 | 
				
			|||||||
  std::cout<<GridLogMessage << "src_o"<<norm2(src_o)<<std::endl;
 | 
					  std::cout<<GridLogMessage << "src_o"<<norm2(src_o)<<std::endl;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  {
 | 
					  {
 | 
				
			||||||
 | 
					    Dw.ZeroCounters();
 | 
				
			||||||
    double t0=usecond();
 | 
					    double t0=usecond();
 | 
				
			||||||
    for(int i=0;i<ncall;i++){
 | 
					    for(int i=0;i<ncall;i++){
 | 
				
			||||||
      Dw.DhopEO(src_o,r_e,DaggerNo);
 | 
					      Dw.DhopEO(src_o,r_e,DaggerNo);
 | 
				
			||||||
@@ -338,6 +333,7 @@ int main (int argc, char ** argv)
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    std::cout<<GridLogMessage << "Deo mflop/s =   "<< flops/(t1-t0)<<std::endl;
 | 
					    std::cout<<GridLogMessage << "Deo mflop/s =   "<< flops/(t1-t0)<<std::endl;
 | 
				
			||||||
    std::cout<<GridLogMessage << "Deo mflop/s per node   "<< flops/(t1-t0)/NP<<std::endl;
 | 
					    std::cout<<GridLogMessage << "Deo mflop/s per node   "<< flops/(t1-t0)/NP<<std::endl;
 | 
				
			||||||
 | 
					    Dw.Report();
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
  Dw.DhopEO(src_o,r_e,DaggerNo);
 | 
					  Dw.DhopEO(src_o,r_e,DaggerNo);
 | 
				
			||||||
  Dw.DhopOE(src_e,r_o,DaggerNo);
 | 
					  Dw.DhopOE(src_e,r_o,DaggerNo);
 | 
				
			||||||
 
 | 
				
			|||||||
										
											Binary file not shown.
										
									
								
							
										
											Binary file not shown.
										
									
								
							@@ -1,11 +1,18 @@
 | 
				
			|||||||
#!/usr/bin/env bash
 | 
					#!/usr/bin/env bash
 | 
				
			||||||
 | 
					
 | 
				
			||||||
EIGEN_URL='http://bitbucket.org/eigen/eigen/get/3.2.9.tar.bz2'
 | 
					EIGEN_URL='http://bitbucket.org/eigen/eigen/get/3.2.9.tar.bz2'
 | 
				
			||||||
 | 
					FFTW_URL=http://www.fftw.org/fftw-3.3.4.tar.gz
 | 
				
			||||||
 | 
					
 | 
				
			||||||
echo "-- deploying Eigen source..."
 | 
					echo "-- deploying Eigen source..."
 | 
				
			||||||
wget ${EIGEN_URL}
 | 
					wget ${EIGEN_URL} --no-check-certificate
 | 
				
			||||||
./scripts/update_eigen.sh `basename ${EIGEN_URL}`
 | 
					./scripts/update_eigen.sh `basename ${EIGEN_URL}`
 | 
				
			||||||
rm `basename ${EIGEN_URL}`
 | 
					rm `basename ${EIGEN_URL}`
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					echo "-- copying fftw prototypes..."
 | 
				
			||||||
 | 
					wget ${FFTW_URL}
 | 
				
			||||||
 | 
					./scripts/update_fftw.sh `basename ${FFTW_URL}`
 | 
				
			||||||
 | 
					rm `basename ${FFTW_URL}`
 | 
				
			||||||
 | 
					
 | 
				
			||||||
echo '-- generating Make.inc files...'
 | 
					echo '-- generating Make.inc files...'
 | 
				
			||||||
./scripts/filelist
 | 
					./scripts/filelist
 | 
				
			||||||
echo '-- generating configure script...'
 | 
					echo '-- generating configure script...'
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										58
									
								
								configure.ac
									
									
									
									
									
								
							
							
						
						
									
										58
									
								
								configure.ac
									
									
									
									
									
								
							@@ -1,18 +1,31 @@
 | 
				
			|||||||
AC_PREREQ([2.63])
 | 
					AC_PREREQ([2.63])
 | 
				
			||||||
AC_INIT([Grid], [0.5.1-dev], [https://github.com/paboyle/Grid], [Grid])
 | 
					AC_INIT([Grid], [0.5.1-dev], [https://github.com/paboyle/Grid], [Grid])
 | 
				
			||||||
 | 
					AC_CANONICAL_BUILD
 | 
				
			||||||
 | 
					AC_CANONICAL_HOST
 | 
				
			||||||
 | 
					AC_CANONICAL_TARGET
 | 
				
			||||||
AM_INIT_AUTOMAKE(subdir-objects)
 | 
					AM_INIT_AUTOMAKE(subdir-objects)
 | 
				
			||||||
AC_CONFIG_MACRO_DIR([m4])
 | 
					AC_CONFIG_MACRO_DIR([m4])
 | 
				
			||||||
AC_CONFIG_SRCDIR([lib/Grid.h])
 | 
					AC_CONFIG_SRCDIR([lib/Grid.h])
 | 
				
			||||||
AC_CONFIG_HEADERS([lib/Config.h])
 | 
					AC_CONFIG_HEADERS([lib/Config.h])
 | 
				
			||||||
m4_ifdef([AM_SILENT_RULES], [AM_SILENT_RULES([yes])])
 | 
					m4_ifdef([AM_SILENT_RULES], [AM_SILENT_RULES([yes])])
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
############### Checks for programs
 | 
					############### Checks for programs
 | 
				
			||||||
AC_LANG(C++)
 | 
					AC_LANG(C++)
 | 
				
			||||||
: ${CXXFLAGS="-O3"}
 | 
					CXXFLAGS="-O3 $CXXFLAGS"
 | 
				
			||||||
AC_PROG_CXX
 | 
					AC_PROG_CXX
 | 
				
			||||||
 | 
					AC_PROG_RANLIB
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					############ openmp  ###############
 | 
				
			||||||
AC_OPENMP
 | 
					AC_OPENMP
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					ac_openmp=no
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					if test "${OPENMP_CXXFLAGS}X" != "X"; then
 | 
				
			||||||
 | 
					ac_openmp=yes
 | 
				
			||||||
AM_CXXFLAGS="$OPENMP_CXXFLAGS $AM_CXXFLAGS"
 | 
					AM_CXXFLAGS="$OPENMP_CXXFLAGS $AM_CXXFLAGS"
 | 
				
			||||||
LT_INIT([disable-shared])
 | 
					AM_LDFLAGS="$OPENMP_CXXFLAGS $AM_LDFLAGS"
 | 
				
			||||||
 | 
					fi
 | 
				
			||||||
 | 
					
 | 
				
			||||||
############### Checks for header files
 | 
					############### Checks for header files
 | 
				
			||||||
AC_CHECK_HEADERS(stdint.h)
 | 
					AC_CHECK_HEADERS(stdint.h)
 | 
				
			||||||
@@ -29,20 +42,23 @@ AC_TYPE_SIZE_T
 | 
				
			|||||||
AC_TYPE_UINT32_T
 | 
					AC_TYPE_UINT32_T
 | 
				
			||||||
AC_TYPE_UINT64_T
 | 
					AC_TYPE_UINT64_T
 | 
				
			||||||
 | 
					
 | 
				
			||||||
############### Options
 | 
					############### GMP and MPFR #################
 | 
				
			||||||
AC_ARG_WITH([gmp],
 | 
					AC_ARG_WITH([gmp],
 | 
				
			||||||
    [AS_HELP_STRING([--with-gmp=prefix],
 | 
					    [AS_HELP_STRING([--with-gmp=prefix],
 | 
				
			||||||
    [try this for a non-standard install prefix of the GMP library])],
 | 
					    [try this for a non-standard install prefix of the GMP library])],
 | 
				
			||||||
    [AM_CXXFLAGS="-I$with_gmp/include $AM_CXXFLAGS"]
 | 
					    [AM_CXXFLAGS="-I$with_gmp/include $AM_CXXFLAGS"]
 | 
				
			||||||
    [AM_LDFLAGS="-L$with_gmp/lib" $AM_LDFLAGS])
 | 
					    [AM_LDFLAGS="-L$with_gmp/lib $AM_LDFLAGS"])
 | 
				
			||||||
AC_ARG_WITH([mpfr],
 | 
					AC_ARG_WITH([mpfr],
 | 
				
			||||||
    [AS_HELP_STRING([--with-mpfr=prefix],
 | 
					    [AS_HELP_STRING([--with-mpfr=prefix],
 | 
				
			||||||
    [try this for a non-standard install prefix of the MPFR library])],
 | 
					    [try this for a non-standard install prefix of the MPFR library])],
 | 
				
			||||||
    [AM_CXXFLAGS="-I$with_mpfr/include $AM_CXXFLAGS"]
 | 
					    [AM_CXXFLAGS="-I$with_mpfr/include $AM_CXXFLAGS"]
 | 
				
			||||||
    [AM_LDFLAGS="-L$with_mpfr/lib $AM_LDFLAGS"])
 | 
					    [AM_LDFLAGS="-L$with_mpfr/lib $AM_LDFLAGS"])
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					################## lapack ####################
 | 
				
			||||||
AC_ARG_ENABLE([lapack],
 | 
					AC_ARG_ENABLE([lapack],
 | 
				
			||||||
    [AC_HELP_STRING([--enable-lapack=yes|no|prefix], [enable LAPACK])], 
 | 
					    [AC_HELP_STRING([--enable-lapack=yes|no|prefix], [enable LAPACK])], 
 | 
				
			||||||
    [ac_LAPACK=${enable_lapack}],[ac_LAPACK=no])
 | 
					    [ac_LAPACK=${enable_lapack}],[ac_LAPACK=no])
 | 
				
			||||||
 | 
					
 | 
				
			||||||
case ${ac_LAPACK} in
 | 
					case ${ac_LAPACK} in
 | 
				
			||||||
    no)
 | 
					    no)
 | 
				
			||||||
        ;;
 | 
					        ;;
 | 
				
			||||||
@@ -54,6 +70,13 @@ case ${ac_LAPACK} in
 | 
				
			|||||||
        AC_DEFINE([USE_LAPACK],[1],[use LAPACK])
 | 
					        AC_DEFINE([USE_LAPACK],[1],[use LAPACK])
 | 
				
			||||||
esac
 | 
					esac
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					################## FFTW3 ####################
 | 
				
			||||||
 | 
					AC_ARG_WITH([fftw],    
 | 
				
			||||||
 | 
					            [AS_HELP_STRING([--with-fftw=prefix],
 | 
				
			||||||
 | 
					            [try this for a non-standard install prefix of the FFTW3 library])],
 | 
				
			||||||
 | 
					            [AM_CXXFLAGS="-I$with_fftw/include $AM_CXXFLAGS"]
 | 
				
			||||||
 | 
					            [AM_LDFLAGS="-L$with_fftw/lib $AM_LDFLAGS"])
 | 
				
			||||||
 | 
					
 | 
				
			||||||
################ Get compiler informations
 | 
					################ Get compiler informations
 | 
				
			||||||
AC_LANG([C++])
 | 
					AC_LANG([C++])
 | 
				
			||||||
AX_CXX_COMPILE_STDCXX_11([noext],[mandatory])
 | 
					AX_CXX_COMPILE_STDCXX_11([noext],[mandatory])
 | 
				
			||||||
@@ -67,7 +90,6 @@ AC_DEFINE_UNQUOTED([GXX_VERSION],["$GXX_VERSION"],
 | 
				
			|||||||
############### Checks for library functions
 | 
					############### Checks for library functions
 | 
				
			||||||
CXXFLAGS_CPY=$CXXFLAGS
 | 
					CXXFLAGS_CPY=$CXXFLAGS
 | 
				
			||||||
LDFLAGS_CPY=$LDFLAGS
 | 
					LDFLAGS_CPY=$LDFLAGS
 | 
				
			||||||
LIBS_CPY=$LIBS
 | 
					 | 
				
			||||||
CXXFLAGS="$AM_CXXFLAGS $CXXFLAGS"
 | 
					CXXFLAGS="$AM_CXXFLAGS $CXXFLAGS"
 | 
				
			||||||
LDFLAGS="$AM_LDFLAGS $LDFLAGS"
 | 
					LDFLAGS="$AM_LDFLAGS $LDFLAGS"
 | 
				
			||||||
AC_CHECK_FUNCS([gettimeofday])
 | 
					AC_CHECK_FUNCS([gettimeofday])
 | 
				
			||||||
@@ -77,7 +99,7 @@ AC_CHECK_LIB([gmp],[__gmpf_init],
 | 
				
			|||||||
                 [have_mpfr=true]
 | 
					                 [have_mpfr=true]
 | 
				
			||||||
                 [LIBS="$LIBS -lmpfr"],
 | 
					                 [LIBS="$LIBS -lmpfr"],
 | 
				
			||||||
                 [AC_MSG_ERROR([MPFR library not found])])]
 | 
					                 [AC_MSG_ERROR([MPFR library not found])])]
 | 
				
			||||||
             [AC_DEFINE([HAVE_LIBGMP], [1], [Define to 1 if you have the `GMP' library (-lgmp).])]
 | 
					   	     [AC_DEFINE([HAVE_LIBGMP], [1], [Define to 1 if you have the `GMP' library (-lgmp).])]
 | 
				
			||||||
             [have_gmp=true]
 | 
					             [have_gmp=true]
 | 
				
			||||||
             [LIBS="$LIBS -lgmp"],
 | 
					             [LIBS="$LIBS -lgmp"],
 | 
				
			||||||
             [AC_MSG_WARN([**** GMP library not found, Grid can still compile but RHMC will not work ****])])
 | 
					             [AC_MSG_WARN([**** GMP library not found, Grid can still compile but RHMC will not work ****])])
 | 
				
			||||||
@@ -86,6 +108,11 @@ if test "${ac_LAPACK}x" != "nox"; then
 | 
				
			|||||||
    AC_CHECK_LIB([lapack],[LAPACKE_sbdsdc],[],
 | 
					    AC_CHECK_LIB([lapack],[LAPACKE_sbdsdc],[],
 | 
				
			||||||
                 [AC_MSG_ERROR("LAPACK enabled but library not found")])
 | 
					                 [AC_MSG_ERROR("LAPACK enabled but library not found")])
 | 
				
			||||||
fi
 | 
					fi
 | 
				
			||||||
 | 
					AC_CHECK_LIB([fftw3],[fftw_execute],
 | 
				
			||||||
 | 
					  [AC_DEFINE([HAVE_FFTW],[1],[Define to 1 if you have the `FFTW' library (-lfftw3).])]
 | 
				
			||||||
 | 
					  [have_fftw=true]
 | 
				
			||||||
 | 
					  [LIBS="$LIBS -lfftw3 -lfftw3f"],
 | 
				
			||||||
 | 
					  [AC_MSG_WARN([**** FFTW library not found, Grid can still compile but FFT-based routines will not work ****])])
 | 
				
			||||||
CXXFLAGS=$CXXFLAGS_CPY
 | 
					CXXFLAGS=$CXXFLAGS_CPY
 | 
				
			||||||
LDFLAGS=$LDFLAGS_CPY
 | 
					LDFLAGS=$LDFLAGS_CPY
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -113,11 +140,14 @@ case ${ax_cv_cxx_compiler_vendor} in
 | 
				
			|||||||
        AC_DEFINE([AVX512],[1],[AVX512 intrinsics])
 | 
					        AC_DEFINE([AVX512],[1],[AVX512 intrinsics])
 | 
				
			||||||
        SIMD_FLAGS='-mavx512f -mavx512pf -mavx512er -mavx512cd';;
 | 
					        SIMD_FLAGS='-mavx512f -mavx512pf -mavx512er -mavx512cd';;
 | 
				
			||||||
      IMCI|KNC)
 | 
					      IMCI|KNC)
 | 
				
			||||||
        AC_DEFINE([IMCI],[1],[IMCI Intrinsics for Knights Corner])
 | 
					        AC_DEFINE([IMCI],[1],[IMCI intrinsics for Knights Corner])
 | 
				
			||||||
        SIMD_FLAGS='';;
 | 
					        SIMD_FLAGS='';;
 | 
				
			||||||
      GEN)
 | 
					      GEN)
 | 
				
			||||||
        AC_DEFINE([GENERIC_VEC],[1],[generic vector code])
 | 
					        AC_DEFINE([GENERIC_VEC],[1],[generic vector code])
 | 
				
			||||||
        SIMD_FLAGS='';;
 | 
					        SIMD_FLAGS='';;
 | 
				
			||||||
 | 
					      QPX|BGQ)
 | 
				
			||||||
 | 
					        AC_DEFINE([QPX],[1],[QPX intrinsics for BG/Q])
 | 
				
			||||||
 | 
					        SIMD_FLAGS='';;
 | 
				
			||||||
      *)
 | 
					      *)
 | 
				
			||||||
        AC_MSG_ERROR(["SIMD option ${ac_SIMD} not supported by the GCC/Clang compiler"]);;
 | 
					        AC_MSG_ERROR(["SIMD option ${ac_SIMD} not supported by the GCC/Clang compiler"]);;
 | 
				
			||||||
    esac;;
 | 
					    esac;;
 | 
				
			||||||
@@ -131,7 +161,7 @@ case ${ax_cv_cxx_compiler_vendor} in
 | 
				
			|||||||
        SIMD_FLAGS='-mavx -xavx';;
 | 
					        SIMD_FLAGS='-mavx -xavx';;
 | 
				
			||||||
      AVXFMA4)
 | 
					      AVXFMA4)
 | 
				
			||||||
        AC_DEFINE([AVXFMA4],[1],[AVX intrinsics with FMA4])
 | 
					        AC_DEFINE([AVXFMA4],[1],[AVX intrinsics with FMA4])
 | 
				
			||||||
        SIMD_FLAGS='-mavx -xavx -mfma';;
 | 
					        SIMD_FLAGS='-mavx -mfma';;
 | 
				
			||||||
      AVX2)
 | 
					      AVX2)
 | 
				
			||||||
        AC_DEFINE([AVX2],[1],[AVX2 intrinsics])
 | 
					        AC_DEFINE([AVX2],[1],[AVX2 intrinsics])
 | 
				
			||||||
        SIMD_FLAGS='-march=core-avx2 -xcore-avx2';;
 | 
					        SIMD_FLAGS='-march=core-avx2 -xcore-avx2';;
 | 
				
			||||||
@@ -297,18 +327,20 @@ Summary of configuration for $PACKAGE v$VERSION
 | 
				
			|||||||
- compiler version              : ${ax_cv_gxx_version}
 | 
					- compiler version              : ${ax_cv_gxx_version}
 | 
				
			||||||
----- BUILD OPTIONS -----------------------------------
 | 
					----- BUILD OPTIONS -----------------------------------
 | 
				
			||||||
- SIMD                          : ${ac_SIMD}
 | 
					- SIMD                          : ${ac_SIMD}
 | 
				
			||||||
- communications type           : ${ac_COMMS}
 | 
					- Threading                     : ${ac_openmp} 
 | 
				
			||||||
- default precision             : ${ac_PRECISION}
 | 
					- Communications type           : ${ac_COMMS}
 | 
				
			||||||
 | 
					- Default precision             : ${ac_PRECISION}
 | 
				
			||||||
- RNG choice                    : ${ac_RNG} 
 | 
					- RNG choice                    : ${ac_RNG} 
 | 
				
			||||||
- GMP                           : `if test "x$have_gmp" = xtrue; then echo yes; else echo no; fi`
 | 
					- GMP                           : `if test "x$have_gmp" = xtrue; then echo yes; else echo no; fi`
 | 
				
			||||||
- LAPACK                        : ${ac_LAPACK}
 | 
					- LAPACK                        : ${ac_LAPACK}
 | 
				
			||||||
 | 
					- FFTW                          : `if test "x$have_fftw" = xtrue; then echo yes; else echo no; fi`
 | 
				
			||||||
- build DOXYGEN documentation   : `if test "$DX_FLAG_doc" = '1'; then echo yes; else echo no; fi`
 | 
					- build DOXYGEN documentation   : `if test "$DX_FLAG_doc" = '1'; then echo yes; else echo no; fi`
 | 
				
			||||||
----- BUILD FLAGS -------------------------------------
 | 
					----- BUILD FLAGS -------------------------------------
 | 
				
			||||||
- CXXFLAGS:
 | 
					- CXXFLAGS:
 | 
				
			||||||
`echo ${AM_CXXFLAGS} ${CXXFLAGS} | sed 's/ -/\n\t-/g' | sed 's/^-/\t-/g'`
 | 
					`echo ${AM_CXXFLAGS} ${CXXFLAGS} | tr ' ' '\n' | sed 's/^-/    -/g'`
 | 
				
			||||||
- LDFLAGS:
 | 
					- LDFLAGS:
 | 
				
			||||||
`echo ${AM_LDFLAGS} ${LDFLAGS} | sed 's/ -/\n\t-/g' | sed 's/^-/\t-/g'`
 | 
					`echo ${AM_LDFLAGS} ${LDFLAGS} | tr ' ' '\n' | sed 's/^-/    -/g'`
 | 
				
			||||||
- LIBS:
 | 
					- LIBS:
 | 
				
			||||||
`echo ${LIBS} | sed 's/ -/\n\t-/g' | sed 's/^-/\t-/g'`
 | 
					`echo ${LIBS} | tr ' ' '\n' | sed 's/^-/    -/g'`
 | 
				
			||||||
-------------------------------------------------------
 | 
					-------------------------------------------------------
 | 
				
			||||||
"
 | 
					"
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										276
									
								
								lib/FFT.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										276
									
								
								lib/FFT.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,276 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
 | 
					    /*************************************************************************************
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    Grid physics library, www.github.com/paboyle/Grid 
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    Source file: ./lib/Cshift.h
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    Copyright (C) 2015
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Author: Peter Boyle <paboyle@ph.ed.ac.uk>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    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
 | 
				
			||||||
 | 
					    the Free Software Foundation; either version 2 of the License, or
 | 
				
			||||||
 | 
					    (at your option) any later version.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    This program is distributed in the hope that it will be useful,
 | 
				
			||||||
 | 
					    but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
				
			||||||
 | 
					    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
				
			||||||
 | 
					    GNU General Public License for more details.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    You should have received a copy of the GNU General Public License along
 | 
				
			||||||
 | 
					    with this program; if not, write to the Free Software Foundation, Inc.,
 | 
				
			||||||
 | 
					    51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    See the full license in the file "LICENSE" in the top level distribution directory
 | 
				
			||||||
 | 
					    *************************************************************************************/
 | 
				
			||||||
 | 
					    /*  END LEGAL */
 | 
				
			||||||
 | 
					#ifndef _GRID_FFT_H_
 | 
				
			||||||
 | 
					#define _GRID_FFT_H_
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifdef HAVE_FFTW	
 | 
				
			||||||
 | 
					#include <fftw3.h>
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					namespace Grid {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  template<class scalar> struct FFTW { };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifdef HAVE_FFTW	
 | 
				
			||||||
 | 
					  template<> struct FFTW<ComplexD> {
 | 
				
			||||||
 | 
					  public:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    typedef fftw_complex FFTW_scalar;
 | 
				
			||||||
 | 
					    typedef fftw_plan    FFTW_plan;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    static FFTW_plan fftw_plan_many_dft(int rank, const int *n,int howmany,
 | 
				
			||||||
 | 
										FFTW_scalar *in, const int *inembed,		
 | 
				
			||||||
 | 
										int istride, int idist,		
 | 
				
			||||||
 | 
										FFTW_scalar *out, const int *onembed,		
 | 
				
			||||||
 | 
										int ostride, int odist,		
 | 
				
			||||||
 | 
										int sign, unsigned flags) {
 | 
				
			||||||
 | 
					      return ::fftw_plan_many_dft(rank,n,howmany,in,inembed,istride,idist,out,onembed,ostride,odist,sign,flags);
 | 
				
			||||||
 | 
					    }	  
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    static void fftw_flops(const FFTW_plan p,double *add, double *mul, double *fmas){
 | 
				
			||||||
 | 
					      ::fftw_flops(p,add,mul,fmas);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    inline static void fftw_execute_dft(const FFTW_plan p,FFTW_scalar *in,FFTW_scalar *out) {
 | 
				
			||||||
 | 
					      ::fftw_execute_dft(p,in,out);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    inline static void fftw_destroy_plan(const FFTW_plan p) {
 | 
				
			||||||
 | 
					      ::fftw_destroy_plan(p);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  template<> struct FFTW<ComplexF> {
 | 
				
			||||||
 | 
					  public:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    typedef fftwf_complex FFTW_scalar;
 | 
				
			||||||
 | 
					    typedef fftwf_plan    FFTW_plan;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    static FFTW_plan fftw_plan_many_dft(int rank, const int *n,int howmany,
 | 
				
			||||||
 | 
										FFTW_scalar *in, const int *inembed,		
 | 
				
			||||||
 | 
										int istride, int idist,		
 | 
				
			||||||
 | 
										FFTW_scalar *out, const int *onembed,		
 | 
				
			||||||
 | 
										int ostride, int odist,		
 | 
				
			||||||
 | 
										int sign, unsigned flags) {
 | 
				
			||||||
 | 
					      return ::fftwf_plan_many_dft(rank,n,howmany,in,inembed,istride,idist,out,onembed,ostride,odist,sign,flags);
 | 
				
			||||||
 | 
					    }	  
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    static void fftw_flops(const FFTW_plan p,double *add, double *mul, double *fmas){
 | 
				
			||||||
 | 
					      ::fftwf_flops(p,add,mul,fmas);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    inline static void fftw_execute_dft(const FFTW_plan p,FFTW_scalar *in,FFTW_scalar *out) {
 | 
				
			||||||
 | 
					      ::fftwf_execute_dft(p,in,out);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    inline static void fftw_destroy_plan(const FFTW_plan p) {
 | 
				
			||||||
 | 
					      ::fftwf_destroy_plan(p);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifndef FFTW_FORWARD
 | 
				
			||||||
 | 
					#define FFTW_FORWARD (-1)
 | 
				
			||||||
 | 
					#define FFTW_BACKWARD (+1)
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  class FFT { 
 | 
				
			||||||
 | 
					  private:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    GridCartesian *vgrid;
 | 
				
			||||||
 | 
					    GridCartesian *sgrid;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    int Nd;
 | 
				
			||||||
 | 
					    double flops;
 | 
				
			||||||
 | 
					    double flops_call;
 | 
				
			||||||
 | 
					    uint64_t usec;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    std::vector<int> dimensions;
 | 
				
			||||||
 | 
					    std::vector<int> processors;
 | 
				
			||||||
 | 
					    std::vector<int> processor_coor;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  public:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    static const int forward=FFTW_FORWARD;
 | 
				
			||||||
 | 
					    static const int backward=FFTW_BACKWARD;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    double Flops(void) {return flops;}
 | 
				
			||||||
 | 
					    double MFlops(void) {return flops/usec;}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    FFT ( GridCartesian * grid ) : 
 | 
				
			||||||
 | 
					      vgrid(grid),
 | 
				
			||||||
 | 
					      Nd(grid->_ndimension),
 | 
				
			||||||
 | 
					      dimensions(grid->_fdimensions),
 | 
				
			||||||
 | 
					      processors(grid->_processors),
 | 
				
			||||||
 | 
					      processor_coor(grid->_processor_coor)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					      flops=0;
 | 
				
			||||||
 | 
					      usec =0;
 | 
				
			||||||
 | 
					      std::vector<int> layout(Nd,1);
 | 
				
			||||||
 | 
					      sgrid = new GridCartesian(dimensions,layout,processors);
 | 
				
			||||||
 | 
					    };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    ~FFT ( void)  { 
 | 
				
			||||||
 | 
					      delete sgrid; 
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    template<class vobj>
 | 
				
			||||||
 | 
					    void FFT_dim(Lattice<vobj> &result,const Lattice<vobj> &source,int dim, int inverse){
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      conformable(result._grid,vgrid);
 | 
				
			||||||
 | 
					      conformable(source._grid,vgrid);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      int L = vgrid->_ldimensions[dim];
 | 
				
			||||||
 | 
					      int G = vgrid->_fdimensions[dim];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      std::vector<int> layout(Nd,1);
 | 
				
			||||||
 | 
					      std::vector<int> pencil_gd(vgrid->_fdimensions);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      pencil_gd[dim] = G*processors[dim];    
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      // Pencil global vol LxLxGxLxL per node
 | 
				
			||||||
 | 
					      GridCartesian pencil_g(pencil_gd,layout,processors);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      // Construct pencils
 | 
				
			||||||
 | 
					      typedef typename vobj::scalar_object sobj;
 | 
				
			||||||
 | 
					      typedef typename sobj::scalar_type   scalar;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      Lattice<vobj> ssource(vgrid); ssource =source;
 | 
				
			||||||
 | 
					      Lattice<sobj> pgsource(&pencil_g);
 | 
				
			||||||
 | 
					      Lattice<sobj> pgresult(&pencil_g); pgresult=zero;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifndef HAVE_FFTW	
 | 
				
			||||||
 | 
					      assert(0);
 | 
				
			||||||
 | 
					#else 
 | 
				
			||||||
 | 
					      typedef typename FFTW<scalar>::FFTW_scalar FFTW_scalar;
 | 
				
			||||||
 | 
					      typedef typename FFTW<scalar>::FFTW_plan   FFTW_plan;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      {
 | 
				
			||||||
 | 
						int Ncomp = sizeof(sobj)/sizeof(scalar);
 | 
				
			||||||
 | 
						int Nlow  = 1;
 | 
				
			||||||
 | 
						for(int d=0;d<dim;d++){
 | 
				
			||||||
 | 
						  Nlow*=vgrid->_ldimensions[d];
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						int rank = 1;  /* 1d transforms */
 | 
				
			||||||
 | 
						int n[] = {G}; /* 1d transforms of length G */
 | 
				
			||||||
 | 
						int howmany = Ncomp;
 | 
				
			||||||
 | 
						int odist,idist,istride,ostride;
 | 
				
			||||||
 | 
						idist   = odist   = 1;          /* Distance between consecutive FT's */
 | 
				
			||||||
 | 
						istride = ostride = Ncomp*Nlow; /* distance between two elements in the same FT */
 | 
				
			||||||
 | 
						int *inembed = n, *onembed = n;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						
 | 
				
			||||||
 | 
						int sign = FFTW_FORWARD;
 | 
				
			||||||
 | 
						if (inverse) sign = FFTW_BACKWARD;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						FFTW_plan p;
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
						  FFTW_scalar *in = (FFTW_scalar *)&pgsource._odata[0];
 | 
				
			||||||
 | 
						  FFTW_scalar *out= (FFTW_scalar *)&pgresult._odata[0];
 | 
				
			||||||
 | 
						  p = FFTW<scalar>::fftw_plan_many_dft(rank,n,howmany,
 | 
				
			||||||
 | 
										       in,inembed,
 | 
				
			||||||
 | 
										       istride,idist,
 | 
				
			||||||
 | 
										       out,onembed,
 | 
				
			||||||
 | 
										       ostride, odist,
 | 
				
			||||||
 | 
										       sign,FFTW_ESTIMATE);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						double add,mul,fma;
 | 
				
			||||||
 | 
						FFTW<scalar>::fftw_flops(p,&add,&mul,&fma);
 | 
				
			||||||
 | 
						flops_call = add+mul+2.0*fma;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						GridStopWatch timer;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// Barrel shift and collect global pencil
 | 
				
			||||||
 | 
						for(int p=0;p<processors[dim];p++) { 
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						  for(int idx=0;idx<sgrid->lSites();idx++) { 
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						    std::vector<int> lcoor(Nd);
 | 
				
			||||||
 | 
					    	    sgrid->LocalIndexToLocalCoor(idx,lcoor);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						    sobj s;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						    peekLocalSite(s,ssource,lcoor);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						    lcoor[dim]+=p*L;
 | 
				
			||||||
 | 
						   
 | 
				
			||||||
 | 
						    pokeLocalSite(s,pgsource,lcoor);
 | 
				
			||||||
 | 
						  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						  ssource = Cshift(ssource,dim,L);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						
 | 
				
			||||||
 | 
						// Loop over orthog coords
 | 
				
			||||||
 | 
						int NN=pencil_g.lSites();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						GridStopWatch Timer;
 | 
				
			||||||
 | 
						Timer.Start();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					PARALLEL_FOR_LOOP
 | 
				
			||||||
 | 
						for(int idx=0;idx<NN;idx++) { 
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						  std::vector<int> lcoor(Nd);
 | 
				
			||||||
 | 
						  pencil_g.LocalIndexToLocalCoor(idx,lcoor);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						  if ( lcoor[dim] == 0 ) {  // restricts loop to plane at lcoor[dim]==0
 | 
				
			||||||
 | 
						    FFTW_scalar *in = (FFTW_scalar *)&pgsource._odata[idx];
 | 
				
			||||||
 | 
						    FFTW_scalar *out= (FFTW_scalar *)&pgresult._odata[idx];
 | 
				
			||||||
 | 
						    FFTW<scalar>::fftw_execute_dft(p,in,out);
 | 
				
			||||||
 | 
						  }
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        Timer.Stop();
 | 
				
			||||||
 | 
						usec += Timer.useconds();
 | 
				
			||||||
 | 
						flops+= flops_call*NN;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        int pc = processor_coor[dim];
 | 
				
			||||||
 | 
					        for(int idx=0;idx<sgrid->lSites();idx++) { 
 | 
				
			||||||
 | 
						  std::vector<int> lcoor(Nd);
 | 
				
			||||||
 | 
						  sgrid->LocalIndexToLocalCoor(idx,lcoor);
 | 
				
			||||||
 | 
						  std::vector<int> gcoor = lcoor;
 | 
				
			||||||
 | 
						  // extract the result
 | 
				
			||||||
 | 
						  sobj s;
 | 
				
			||||||
 | 
						  gcoor[dim] = lcoor[dim]+L*pc;
 | 
				
			||||||
 | 
						  peekLocalSite(s,pgresult,gcoor);
 | 
				
			||||||
 | 
						  pokeLocalSite(s,result,lcoor);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					      	  
 | 
				
			||||||
 | 
						FFTW<scalar>::fftw_destroy_plan(p);
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
@@ -68,6 +68,7 @@ Author: paboyle <paboyle@ph.ed.ac.uk>
 | 
				
			|||||||
#include <Grid/Simd.h>
 | 
					#include <Grid/Simd.h>
 | 
				
			||||||
#include <Grid/Threads.h>
 | 
					#include <Grid/Threads.h>
 | 
				
			||||||
#include <Grid/Lexicographic.h>
 | 
					#include <Grid/Lexicographic.h>
 | 
				
			||||||
 | 
					#include <Grid/Init.h>
 | 
				
			||||||
#include <Grid/Communicator.h> 
 | 
					#include <Grid/Communicator.h> 
 | 
				
			||||||
#include <Grid/Cartesian.h>    
 | 
					#include <Grid/Cartesian.h>    
 | 
				
			||||||
#include <Grid/Tensors.h>      
 | 
					#include <Grid/Tensors.h>      
 | 
				
			||||||
@@ -78,7 +79,8 @@ Author: paboyle <paboyle@ph.ed.ac.uk>
 | 
				
			|||||||
#include <Grid/parallelIO/BinaryIO.h>
 | 
					#include <Grid/parallelIO/BinaryIO.h>
 | 
				
			||||||
#include <Grid/qcd/QCD.h>
 | 
					#include <Grid/qcd/QCD.h>
 | 
				
			||||||
#include <Grid/parallelIO/NerscIO.h>
 | 
					#include <Grid/parallelIO/NerscIO.h>
 | 
				
			||||||
#include <Grid/Init.h>
 | 
					
 | 
				
			||||||
 | 
					#include <Grid/FFT.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include <Grid/qcd/hmc/NerscCheckpointer.h>
 | 
					#include <Grid/qcd/hmc/NerscCheckpointer.h>
 | 
				
			||||||
#include <Grid/qcd/hmc/HmcRunner.h>
 | 
					#include <Grid/qcd/hmc/HmcRunner.h>
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -153,6 +153,7 @@ void GridParseLayout(char **argv,int argc,
 | 
				
			|||||||
    assert(ompthreads.size()==1);
 | 
					    assert(ompthreads.size()==1);
 | 
				
			||||||
    GridThread::SetThreads(ompthreads[0]);
 | 
					    GridThread::SetThreads(ompthreads[0]);
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  if( GridCmdOptionExists(argv,argv+argc,"--cores") ){
 | 
					  if( GridCmdOptionExists(argv,argv+argc,"--cores") ){
 | 
				
			||||||
    std::vector<int> cores(0);
 | 
					    std::vector<int> cores(0);
 | 
				
			||||||
    arg= GridCmdOptionPayload(argv,argv+argc,"--cores");
 | 
					    arg= GridCmdOptionPayload(argv,argv+argc,"--cores");
 | 
				
			||||||
@@ -203,7 +204,6 @@ void Grid_init(int *argc,char ***argv)
 | 
				
			|||||||
    GridLogConfigure(logstreams);
 | 
					    GridLogConfigure(logstreams);
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					 | 
				
			||||||
  if( GridCmdOptionExists(*argv,*argv+*argc,"--debug-signals") ){
 | 
					  if( GridCmdOptionExists(*argv,*argv+*argc,"--debug-signals") ){
 | 
				
			||||||
    Grid_debug_handler_init();
 | 
					    Grid_debug_handler_init();
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -17,8 +17,8 @@ endif
 | 
				
			|||||||
include Make.inc
 | 
					include Make.inc
 | 
				
			||||||
include Eigen.inc
 | 
					include Eigen.inc
 | 
				
			||||||
 | 
					
 | 
				
			||||||
lib_LTLIBRARIES = libGrid.la
 | 
					lib_LIBRARIES = libGrid.a
 | 
				
			||||||
 | 
					
 | 
				
			||||||
libGrid_la_SOURCES             = $(CCFILES) $(extra_sources)
 | 
					libGrid_a_SOURCES              = $(CCFILES) $(extra_sources)
 | 
				
			||||||
libGrid_ladir                  = $(pkgincludedir)
 | 
					libGrid_adir                   = $(pkgincludedir)
 | 
				
			||||||
nobase_dist_pkginclude_HEADERS = $(HFILES) $(eigen_files) Config.h
 | 
					nobase_dist_pkginclude_HEADERS = $(HFILES) $(eigen_files) Config.h
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -106,7 +106,6 @@
 | 
				
			|||||||
 #define SERIAL_SENDS
 | 
					 #define SERIAL_SENDS
 | 
				
			||||||
 | 
					
 | 
				
			||||||
       void AddPacket(void *xmit,void * rcv, Integer to,Integer from,Integer bytes){
 | 
					       void AddPacket(void *xmit,void * rcv, Integer to,Integer from,Integer bytes){
 | 
				
			||||||
	 comms_bytes+=2.0*bytes;
 | 
					 | 
				
			||||||
 #ifdef SEND_IMMEDIATE
 | 
					 #ifdef SEND_IMMEDIATE
 | 
				
			||||||
	 commtime-=usecond();
 | 
						 commtime-=usecond();
 | 
				
			||||||
	 _grid->SendToRecvFrom(xmit,to,rcv,from,bytes);
 | 
						 _grid->SendToRecvFrom(xmit,to,rcv,from,bytes);
 | 
				
			||||||
@@ -265,7 +264,7 @@
 | 
				
			|||||||
	 //	 _mm_prefetch((char *)&_entries[ent],_MM_HINT_T0);
 | 
						 //	 _mm_prefetch((char *)&_entries[ent],_MM_HINT_T0);
 | 
				
			||||||
       }
 | 
					       }
 | 
				
			||||||
       inline uint64_t GetInfo(int &ptype,int &local,int &perm,int point,int ent,uint64_t base) {
 | 
					       inline uint64_t GetInfo(int &ptype,int &local,int &perm,int point,int ent,uint64_t base) {
 | 
				
			||||||
	 _mm_prefetch((char *)&_entries[ent+1],_MM_HINT_T0);
 | 
						 //_mm_prefetch((char *)&_entries[ent+1],_MM_HINT_T0);
 | 
				
			||||||
	 local = _entries[ent]._is_local;
 | 
						 local = _entries[ent]._is_local;
 | 
				
			||||||
	 perm  = _entries[ent]._permute;
 | 
						 perm  = _entries[ent]._permute;
 | 
				
			||||||
	 if (perm)  ptype = _permute_type[point]; 
 | 
						 if (perm)  ptype = _permute_type[point]; 
 | 
				
			||||||
@@ -301,6 +300,39 @@
 | 
				
			|||||||
       double gathermtime;
 | 
					       double gathermtime;
 | 
				
			||||||
       double splicetime;
 | 
					       double splicetime;
 | 
				
			||||||
       double nosplicetime;
 | 
					       double nosplicetime;
 | 
				
			||||||
 | 
					       double calls;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					       void ZeroCounters(void) {
 | 
				
			||||||
 | 
					         gathertime = 0.;
 | 
				
			||||||
 | 
					         jointime = 0.;
 | 
				
			||||||
 | 
					         commtime = 0.;
 | 
				
			||||||
 | 
					         halogtime = 0.;
 | 
				
			||||||
 | 
					         mergetime = 0.;
 | 
				
			||||||
 | 
					         spintime = 0.;
 | 
				
			||||||
 | 
					         gathermtime = 0.;
 | 
				
			||||||
 | 
					         splicetime = 0.;
 | 
				
			||||||
 | 
					         nosplicetime = 0.;
 | 
				
			||||||
 | 
					         comms_bytes = 0.;
 | 
				
			||||||
 | 
					         calls = 0.;
 | 
				
			||||||
 | 
					       };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					       void Report(void) {
 | 
				
			||||||
 | 
					#define PRINTIT(A)	\
 | 
				
			||||||
 | 
					 std::cout << GridLogMessage << " Stencil " << #A << " "<< A/calls<<std::endl;
 | 
				
			||||||
 | 
						 if ( calls > 0. ) {
 | 
				
			||||||
 | 
					 std::cout << GridLogMessage << " Stencil calls "<<calls<<std::endl;
 | 
				
			||||||
 | 
					       PRINTIT(jointime);
 | 
				
			||||||
 | 
					       PRINTIT(gathertime);
 | 
				
			||||||
 | 
					       PRINTIT(commtime);
 | 
				
			||||||
 | 
					       PRINTIT(halogtime);
 | 
				
			||||||
 | 
					       PRINTIT(mergetime);
 | 
				
			||||||
 | 
					       PRINTIT(spintime);
 | 
				
			||||||
 | 
					       PRINTIT(comms_bytes);
 | 
				
			||||||
 | 
					       PRINTIT(gathermtime);
 | 
				
			||||||
 | 
					       PRINTIT(splicetime);
 | 
				
			||||||
 | 
					       PRINTIT(nosplicetime);
 | 
				
			||||||
 | 
						 }
 | 
				
			||||||
 | 
					       };
 | 
				
			||||||
 #endif
 | 
					 #endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
   CartesianStencil(GridBase *grid,
 | 
					   CartesianStencil(GridBase *grid,
 | 
				
			||||||
@@ -310,18 +342,6 @@
 | 
				
			|||||||
				      const std::vector<int> &distances) 
 | 
									      const std::vector<int> &distances) 
 | 
				
			||||||
     :   _permute_type(npoints), _comm_buf_size(npoints)
 | 
					     :   _permute_type(npoints), _comm_buf_size(npoints)
 | 
				
			||||||
     {
 | 
					     {
 | 
				
			||||||
 #ifdef TIMING_HACK
 | 
					 | 
				
			||||||
       gathertime=0;
 | 
					 | 
				
			||||||
       jointime=0;
 | 
					 | 
				
			||||||
       commtime=0;
 | 
					 | 
				
			||||||
       halogtime=0;
 | 
					 | 
				
			||||||
       mergetime=0;
 | 
					 | 
				
			||||||
       spintime=0;
 | 
					 | 
				
			||||||
       gathermtime=0;
 | 
					 | 
				
			||||||
       splicetime=0;
 | 
					 | 
				
			||||||
       nosplicetime=0;
 | 
					 | 
				
			||||||
       comms_bytes=0;
 | 
					 | 
				
			||||||
 #endif
 | 
					 | 
				
			||||||
       _npoints = npoints;
 | 
					       _npoints = npoints;
 | 
				
			||||||
       _grid    = grid;
 | 
					       _grid    = grid;
 | 
				
			||||||
       _directions = directions;
 | 
					       _directions = directions;
 | 
				
			||||||
@@ -623,6 +643,7 @@
 | 
				
			|||||||
       template<class compressor>
 | 
					       template<class compressor>
 | 
				
			||||||
       void HaloExchange(const Lattice<vobj> &source,compressor &compress) 
 | 
					       void HaloExchange(const Lattice<vobj> &source,compressor &compress) 
 | 
				
			||||||
       {
 | 
					       {
 | 
				
			||||||
 | 
						 calls++;
 | 
				
			||||||
	 Mergers.resize(0);
 | 
						 Mergers.resize(0);
 | 
				
			||||||
         Packets.resize(0);
 | 
					         Packets.resize(0);
 | 
				
			||||||
         HaloGather(source,compress);
 | 
					         HaloGather(source,compress);
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,153 +1,168 @@
 | 
				
			|||||||
    /*************************************************************************************
 | 
					/*************************************************************************************
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    Grid physics library, www.github.com/paboyle/Grid 
 | 
					Grid physics library, www.github.com/paboyle/Grid
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    Source file: ./lib/algorithms/iterative/ConjugateGradient.h
 | 
					Source file: ./lib/algorithms/iterative/ConjugateGradient.h
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    Copyright (C) 2015
 | 
					Copyright (C) 2015
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Author: Azusa Yamaguchi <ayamaguc@staffmail.ed.ac.uk>
 | 
					Author: Azusa Yamaguchi <ayamaguc@staffmail.ed.ac.uk>
 | 
				
			||||||
Author: Peter Boyle <paboyle@ph.ed.ac.uk>
 | 
					Author: Peter Boyle <paboyle@ph.ed.ac.uk>
 | 
				
			||||||
Author: paboyle <paboyle@ph.ed.ac.uk>
 | 
					Author: paboyle <paboyle@ph.ed.ac.uk>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    This program is free software; you can redistribute it and/or modify
 | 
					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
 | 
					it under the terms of the GNU General Public License as published by
 | 
				
			||||||
    the Free Software Foundation; either version 2 of the License, or
 | 
					the Free Software Foundation; either version 2 of the License, or
 | 
				
			||||||
    (at your option) any later version.
 | 
					(at your option) any later version.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    This program is distributed in the hope that it will be useful,
 | 
					This program is distributed in the hope that it will be useful,
 | 
				
			||||||
    but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
					but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
				
			||||||
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
					MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
				
			||||||
    GNU General Public License for more details.
 | 
					GNU General Public License for more details.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    You should have received a copy of the GNU General Public License along
 | 
					You should have received a copy of the GNU General Public License along
 | 
				
			||||||
    with this program; if not, write to the Free Software Foundation, Inc.,
 | 
					with this program; if not, write to the Free Software Foundation, Inc.,
 | 
				
			||||||
    51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 | 
					51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    See the full license in the file "LICENSE" in the top level distribution directory
 | 
					See the full license in the file "LICENSE" in the top level distribution
 | 
				
			||||||
    *************************************************************************************/
 | 
					directory
 | 
				
			||||||
    /*  END LEGAL */
 | 
					*************************************************************************************/
 | 
				
			||||||
 | 
					/*  END LEGAL */
 | 
				
			||||||
#ifndef GRID_CONJUGATE_GRADIENT_H
 | 
					#ifndef GRID_CONJUGATE_GRADIENT_H
 | 
				
			||||||
#define GRID_CONJUGATE_GRADIENT_H
 | 
					#define GRID_CONJUGATE_GRADIENT_H
 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace Grid {
 | 
					namespace Grid {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /////////////////////////////////////////////////////////////
 | 
					/////////////////////////////////////////////////////////////
 | 
				
			||||||
    // Base classes for iterative processes based on operators
 | 
					// Base classes for iterative processes based on operators
 | 
				
			||||||
    // single input vec, single output vec.
 | 
					// single input vec, single output vec.
 | 
				
			||||||
    /////////////////////////////////////////////////////////////
 | 
					/////////////////////////////////////////////////////////////
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  template<class Field> 
 | 
					template <class Field>
 | 
				
			||||||
    class ConjugateGradient : public OperatorFunction<Field> {
 | 
					class ConjugateGradient : public OperatorFunction<Field> {
 | 
				
			||||||
public:                                                
 | 
					 public:
 | 
				
			||||||
    bool ErrorOnNoConverge; //throw an assert when the CG fails to converge. Defaults true.
 | 
					  bool ErrorOnNoConverge;  // throw an assert when the CG fails to converge.
 | 
				
			||||||
    RealD   Tolerance;
 | 
					                           // Defaults true.
 | 
				
			||||||
    Integer MaxIterations;
 | 
					  RealD Tolerance;
 | 
				
			||||||
  ConjugateGradient(RealD tol,Integer maxit, bool err_on_no_conv = true) : Tolerance(tol), MaxIterations(maxit), ErrorOnNoConverge(err_on_no_conv){ 
 | 
					  Integer MaxIterations;
 | 
				
			||||||
    };
 | 
					  ConjugateGradient(RealD tol, Integer maxit, bool err_on_no_conv = true)
 | 
				
			||||||
 | 
					      : Tolerance(tol),
 | 
				
			||||||
 | 
					        MaxIterations(maxit),
 | 
				
			||||||
 | 
					        ErrorOnNoConverge(err_on_no_conv){};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  void operator()(LinearOperatorBase<Field> &Linop, const Field &src,
 | 
				
			||||||
 | 
					                  Field &psi) {
 | 
				
			||||||
 | 
					    psi.checkerboard = src.checkerboard;
 | 
				
			||||||
 | 
					    conformable(psi, src);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    RealD cp, c, a, d, b, ssq, qq, b_pred;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    Field p(src);
 | 
				
			||||||
 | 
					    Field mmp(src);
 | 
				
			||||||
 | 
					    Field r(src);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // Initial residual computation & set up
 | 
				
			||||||
 | 
					    RealD guess = norm2(psi);
 | 
				
			||||||
 | 
					    assert(std::isnan(guess) == 0);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    
 | 
					    
 | 
				
			||||||
    void operator() (LinearOperatorBase<Field> &Linop,const Field &src, Field &psi){
 | 
					    Linop.HermOpAndNorm(psi, mmp, d, b);
 | 
				
			||||||
    
 | 
					    
 | 
				
			||||||
      psi.checkerboard = src.checkerboard;
 | 
					 | 
				
			||||||
      conformable(psi,src);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
      RealD cp,c,a,d,b,ssq,qq,b_pred;
 | 
					    r = src - mmp;
 | 
				
			||||||
 | 
					    p = r;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      Field   p(src);
 | 
					    a = norm2(p);
 | 
				
			||||||
      Field mmp(src);
 | 
					    cp = a;
 | 
				
			||||||
      Field   r(src);
 | 
					    ssq = norm2(src);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      //Initial residual computation & set up
 | 
					    std::cout << GridLogIterative << std::setprecision(4)
 | 
				
			||||||
      RealD guess = norm2(psi);
 | 
					              << "ConjugateGradient: guess " << guess << std::endl;
 | 
				
			||||||
      assert(std::isnan(guess)==0);
 | 
					    std::cout << GridLogIterative << std::setprecision(4)
 | 
				
			||||||
 | 
					              << "ConjugateGradient:   src " << ssq << std::endl;
 | 
				
			||||||
 | 
					    std::cout << GridLogIterative << std::setprecision(4)
 | 
				
			||||||
 | 
					              << "ConjugateGradient:    mp " << d << std::endl;
 | 
				
			||||||
 | 
					    std::cout << GridLogIterative << std::setprecision(4)
 | 
				
			||||||
 | 
					              << "ConjugateGradient:   mmp " << b << std::endl;
 | 
				
			||||||
 | 
					    std::cout << GridLogIterative << std::setprecision(4)
 | 
				
			||||||
 | 
					              << "ConjugateGradient:  cp,r " << cp << std::endl;
 | 
				
			||||||
 | 
					    std::cout << GridLogIterative << std::setprecision(4)
 | 
				
			||||||
 | 
					              << "ConjugateGradient:     p " << a << std::endl;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      Linop.HermOpAndNorm(psi,mmp,d,b);
 | 
					    RealD rsq = Tolerance * Tolerance * ssq;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      r= src-mmp;
 | 
					    // Check if guess is really REALLY good :)
 | 
				
			||||||
      p= r;
 | 
					    if (cp <= rsq) {
 | 
				
			||||||
      
 | 
					      return;
 | 
				
			||||||
      a  =norm2(p);
 | 
					 | 
				
			||||||
      cp =a;
 | 
					 | 
				
			||||||
      ssq=norm2(src);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
      std::cout<<GridLogIterative <<std::setprecision(4)<< "ConjugateGradient: guess "<<guess<<std::endl;
 | 
					 | 
				
			||||||
      std::cout<<GridLogIterative <<std::setprecision(4)<< "ConjugateGradient:   src "<<ssq  <<std::endl;
 | 
					 | 
				
			||||||
      std::cout<<GridLogIterative <<std::setprecision(4)<< "ConjugateGradient:    mp "<<d    <<std::endl;
 | 
					 | 
				
			||||||
      std::cout<<GridLogIterative <<std::setprecision(4)<< "ConjugateGradient:   mmp "<<b    <<std::endl;
 | 
					 | 
				
			||||||
      std::cout<<GridLogIterative <<std::setprecision(4)<< "ConjugateGradient:  cp,r "<<cp   <<std::endl;
 | 
					 | 
				
			||||||
      std::cout<<GridLogIterative <<std::setprecision(4)<< "ConjugateGradient:     p "<<a    <<std::endl;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
      RealD rsq =  Tolerance* Tolerance*ssq;
 | 
					 | 
				
			||||||
      
 | 
					 | 
				
			||||||
      //Check if guess is really REALLY good :)
 | 
					 | 
				
			||||||
      if ( cp <= rsq ) {
 | 
					 | 
				
			||||||
	return;
 | 
					 | 
				
			||||||
      }
 | 
					 | 
				
			||||||
      
 | 
					 | 
				
			||||||
      std::cout<<GridLogIterative << std::setprecision(4)<< "ConjugateGradient: k=0 residual "<<cp<<" target "<<rsq<<std::endl;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
      GridStopWatch LinalgTimer;
 | 
					 | 
				
			||||||
      GridStopWatch MatrixTimer;
 | 
					 | 
				
			||||||
      GridStopWatch SolverTimer;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
      SolverTimer.Start();
 | 
					 | 
				
			||||||
      int k;
 | 
					 | 
				
			||||||
      for (k=1;k<=MaxIterations;k++){
 | 
					 | 
				
			||||||
	
 | 
					 | 
				
			||||||
	c=cp;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	MatrixTimer.Start();
 | 
					 | 
				
			||||||
	Linop.HermOpAndNorm(p,mmp,d,qq);
 | 
					 | 
				
			||||||
	MatrixTimer.Stop();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	LinalgTimer.Start();
 | 
					 | 
				
			||||||
	//	RealD    qqck = norm2(mmp);
 | 
					 | 
				
			||||||
	//	ComplexD dck  = innerProduct(p,mmp);
 | 
					 | 
				
			||||||
      
 | 
					 | 
				
			||||||
	a      = c/d;
 | 
					 | 
				
			||||||
	b_pred = a*(a*qq-d)/c;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	cp = axpy_norm(r,-a,mmp,r);
 | 
					 | 
				
			||||||
	b = cp/c;
 | 
					 | 
				
			||||||
	
 | 
					 | 
				
			||||||
	// Fuse these loops ; should be really easy
 | 
					 | 
				
			||||||
	psi= a*p+psi;
 | 
					 | 
				
			||||||
	p  = p*b+r;
 | 
					 | 
				
			||||||
	  
 | 
					 | 
				
			||||||
	LinalgTimer.Stop();
 | 
					 | 
				
			||||||
	std::cout<<GridLogIterative<<"ConjugateGradient: Iteration " <<k<<" residual "<<cp<< " target "<< rsq<<std::endl;
 | 
					 | 
				
			||||||
	
 | 
					 | 
				
			||||||
	// Stopping condition
 | 
					 | 
				
			||||||
	if ( cp <= rsq ) { 
 | 
					 | 
				
			||||||
	  
 | 
					 | 
				
			||||||
	  SolverTimer.Stop();
 | 
					 | 
				
			||||||
	  Linop.HermOpAndNorm(psi,mmp,d,qq);
 | 
					 | 
				
			||||||
	  p=mmp-src;
 | 
					 | 
				
			||||||
	  
 | 
					 | 
				
			||||||
	  RealD mmpnorm = sqrt(norm2(mmp));
 | 
					 | 
				
			||||||
	  RealD psinorm = sqrt(norm2(psi));
 | 
					 | 
				
			||||||
	  RealD srcnorm = sqrt(norm2(src));
 | 
					 | 
				
			||||||
	  RealD resnorm = sqrt(norm2(p));
 | 
					 | 
				
			||||||
	  RealD true_residual = resnorm/srcnorm;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	  std::cout<<GridLogMessage<<"ConjugateGradient: Converged on iteration " <<k
 | 
					 | 
				
			||||||
		   <<" computed residual "<<sqrt(cp/ssq)
 | 
					 | 
				
			||||||
		   <<" true residual "    <<true_residual
 | 
					 | 
				
			||||||
		   <<" target "<<Tolerance<<std::endl;
 | 
					 | 
				
			||||||
	  std::cout<<GridLogMessage<<"Time elapsed: Total "<< SolverTimer.Elapsed() << " Matrix  "<<MatrixTimer.Elapsed() << " Linalg "<<LinalgTimer.Elapsed();
 | 
					 | 
				
			||||||
	  std::cout<<std::endl;
 | 
					 | 
				
			||||||
	  
 | 
					 | 
				
			||||||
	  if(ErrorOnNoConverge)
 | 
					 | 
				
			||||||
	    assert(true_residual/Tolerance < 1000.0);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	  return;
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
      }
 | 
					 | 
				
			||||||
      std::cout<<GridLogMessage<<"ConjugateGradient did NOT converge"<<std::endl;
 | 
					 | 
				
			||||||
      if(ErrorOnNoConverge)	
 | 
					 | 
				
			||||||
	assert(0);
 | 
					 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
  };
 | 
					
 | 
				
			||||||
 | 
					    std::cout << GridLogIterative << std::setprecision(4)
 | 
				
			||||||
 | 
					              << "ConjugateGradient: k=0 residual " << cp << " target " << rsq
 | 
				
			||||||
 | 
					              << std::endl;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    GridStopWatch LinalgTimer;
 | 
				
			||||||
 | 
					    GridStopWatch MatrixTimer;
 | 
				
			||||||
 | 
					    GridStopWatch SolverTimer;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    SolverTimer.Start();
 | 
				
			||||||
 | 
					    int k;
 | 
				
			||||||
 | 
					    for (k = 1; k <= MaxIterations; k++) {
 | 
				
			||||||
 | 
					      c = cp;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      MatrixTimer.Start();
 | 
				
			||||||
 | 
					      Linop.HermOpAndNorm(p, mmp, d, qq);
 | 
				
			||||||
 | 
					      MatrixTimer.Stop();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      LinalgTimer.Start();
 | 
				
			||||||
 | 
					      //  RealD    qqck = norm2(mmp);
 | 
				
			||||||
 | 
					      //  ComplexD dck  = innerProduct(p,mmp);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      a = c / d;
 | 
				
			||||||
 | 
					      b_pred = a * (a * qq - d) / c;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      cp = axpy_norm(r, -a, mmp, r);
 | 
				
			||||||
 | 
					      b = cp / c;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      // Fuse these loops ; should be really easy
 | 
				
			||||||
 | 
					      psi = a * p + psi;
 | 
				
			||||||
 | 
					      p = p * b + r;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      LinalgTimer.Stop();
 | 
				
			||||||
 | 
					      std::cout << GridLogIterative << "ConjugateGradient: Iteration " << k
 | 
				
			||||||
 | 
					                << " residual " << cp << " target " << rsq << std::endl;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      // Stopping condition
 | 
				
			||||||
 | 
					      if (cp <= rsq) {
 | 
				
			||||||
 | 
					        SolverTimer.Stop();
 | 
				
			||||||
 | 
					        Linop.HermOpAndNorm(psi, mmp, d, qq);
 | 
				
			||||||
 | 
					        p = mmp - src;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        RealD mmpnorm = sqrt(norm2(mmp));
 | 
				
			||||||
 | 
					        RealD psinorm = sqrt(norm2(psi));
 | 
				
			||||||
 | 
					        RealD srcnorm = sqrt(norm2(src));
 | 
				
			||||||
 | 
					        RealD resnorm = sqrt(norm2(p));
 | 
				
			||||||
 | 
					        RealD true_residual = resnorm / srcnorm;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        std::cout << GridLogMessage
 | 
				
			||||||
 | 
					                  << "ConjugateGradient: Converged on iteration " << k << std::endl;
 | 
				
			||||||
 | 
					        std::cout << GridLogMessage << "Computed residual " << sqrt(cp / ssq)
 | 
				
			||||||
 | 
					                  << " true residual " << true_residual << " target "
 | 
				
			||||||
 | 
					                  << Tolerance << std::endl;
 | 
				
			||||||
 | 
					        std::cout << GridLogMessage << "Time elapsed: Iterations "
 | 
				
			||||||
 | 
					                  << SolverTimer.Elapsed() << " Matrix  "
 | 
				
			||||||
 | 
					                  << MatrixTimer.Elapsed() << " Linalg "
 | 
				
			||||||
 | 
					                  << LinalgTimer.Elapsed();
 | 
				
			||||||
 | 
					        std::cout << std::endl;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if (ErrorOnNoConverge) assert(true_residual / Tolerance < 1000.0);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        return;
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    std::cout << GridLogMessage << "ConjugateGradient did NOT converge"
 | 
				
			||||||
 | 
					              << std::endl;
 | 
				
			||||||
 | 
					    if (ErrorOnNoConverge) assert(0);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										412
									
								
								lib/fftw/fftw3.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										412
									
								
								lib/fftw/fftw3.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,412 @@
 | 
				
			|||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * Copyright (c) 2003, 2007-14 Matteo Frigo
 | 
				
			||||||
 | 
					 * Copyright (c) 2003, 2007-14 Massachusetts Institute of Technology
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * The following statement of license applies *only* to this header file,
 | 
				
			||||||
 | 
					 * and *not* to the other files distributed with FFTW or derived therefrom:
 | 
				
			||||||
 | 
					 * 
 | 
				
			||||||
 | 
					 * Redistribution and use in source and binary forms, with or without
 | 
				
			||||||
 | 
					 * modification, are permitted provided that the following conditions
 | 
				
			||||||
 | 
					 * are met:
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * 1. Redistributions of source code must retain the above copyright
 | 
				
			||||||
 | 
					 *    notice, this list of conditions and the following disclaimer.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * 2. Redistributions in binary form must reproduce the above copyright
 | 
				
			||||||
 | 
					 *    notice, this list of conditions and the following disclaimer in the
 | 
				
			||||||
 | 
					 *    documentation and/or other materials provided with the distribution.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
 | 
				
			||||||
 | 
					 * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 | 
				
			||||||
 | 
					 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 | 
				
			||||||
 | 
					 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
 | 
				
			||||||
 | 
					 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 | 
				
			||||||
 | 
					 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
 | 
				
			||||||
 | 
					 * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 | 
				
			||||||
 | 
					 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
 | 
				
			||||||
 | 
					 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
 | 
				
			||||||
 | 
					 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 | 
				
			||||||
 | 
					 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/***************************** NOTE TO USERS *********************************
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 *                 THIS IS A HEADER FILE, NOT A MANUAL
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 *    If you want to know how to use FFTW, please read the manual,
 | 
				
			||||||
 | 
					 *    online at http://www.fftw.org/doc/ and also included with FFTW.
 | 
				
			||||||
 | 
					 *    For a quick start, see the manual's tutorial section.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 *   (Reading header files to learn how to use a library is a habit
 | 
				
			||||||
 | 
					 *    stemming from code lacking a proper manual.  Arguably, it's a
 | 
				
			||||||
 | 
					 *    *bad* habit in most cases, because header files can contain
 | 
				
			||||||
 | 
					 *    interfaces that are not part of the public, stable API.)
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 ****************************************************************************/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifndef FFTW3_H
 | 
				
			||||||
 | 
					#define FFTW3_H
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <stdio.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifdef __cplusplus
 | 
				
			||||||
 | 
					extern "C"
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					#endif /* __cplusplus */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* If <complex.h> is included, use the C99 complex type.  Otherwise
 | 
				
			||||||
 | 
					   define a type bit-compatible with C99 complex */
 | 
				
			||||||
 | 
					#if !defined(FFTW_NO_Complex) && defined(_Complex_I) && defined(complex) && defined(I)
 | 
				
			||||||
 | 
					#  define FFTW_DEFINE_COMPLEX(R, C) typedef R _Complex C
 | 
				
			||||||
 | 
					#else
 | 
				
			||||||
 | 
					#  define FFTW_DEFINE_COMPLEX(R, C) typedef R C[2]
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define FFTW_CONCAT(prefix, name) prefix ## name
 | 
				
			||||||
 | 
					#define FFTW_MANGLE_DOUBLE(name) FFTW_CONCAT(fftw_, name)
 | 
				
			||||||
 | 
					#define FFTW_MANGLE_FLOAT(name) FFTW_CONCAT(fftwf_, name)
 | 
				
			||||||
 | 
					#define FFTW_MANGLE_LONG_DOUBLE(name) FFTW_CONCAT(fftwl_, name)
 | 
				
			||||||
 | 
					#define FFTW_MANGLE_QUAD(name) FFTW_CONCAT(fftwq_, name)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* IMPORTANT: for Windows compilers, you should add a line
 | 
				
			||||||
 | 
					        #define FFTW_DLL
 | 
				
			||||||
 | 
					   here and in kernel/ifftw.h if you are compiling/using FFTW as a
 | 
				
			||||||
 | 
					   DLL, in order to do the proper importing/exporting, or
 | 
				
			||||||
 | 
					   alternatively compile with -DFFTW_DLL or the equivalent
 | 
				
			||||||
 | 
					   command-line flag.  This is not necessary under MinGW/Cygwin, where
 | 
				
			||||||
 | 
					   libtool does the imports/exports automatically. */
 | 
				
			||||||
 | 
					#if defined(FFTW_DLL) && (defined(_WIN32) || defined(__WIN32__))
 | 
				
			||||||
 | 
					   /* annoying Windows syntax for shared-library declarations */
 | 
				
			||||||
 | 
					#  if defined(COMPILING_FFTW) /* defined in api.h when compiling FFTW */
 | 
				
			||||||
 | 
					#    define FFTW_EXTERN extern __declspec(dllexport) 
 | 
				
			||||||
 | 
					#  else /* user is calling FFTW; import symbol */
 | 
				
			||||||
 | 
					#    define FFTW_EXTERN extern __declspec(dllimport) 
 | 
				
			||||||
 | 
					#  endif
 | 
				
			||||||
 | 
					#else
 | 
				
			||||||
 | 
					#  define FFTW_EXTERN extern
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					enum fftw_r2r_kind_do_not_use_me {
 | 
				
			||||||
 | 
					     FFTW_R2HC=0, FFTW_HC2R=1, FFTW_DHT=2,
 | 
				
			||||||
 | 
					     FFTW_REDFT00=3, FFTW_REDFT01=4, FFTW_REDFT10=5, FFTW_REDFT11=6,
 | 
				
			||||||
 | 
					     FFTW_RODFT00=7, FFTW_RODFT01=8, FFTW_RODFT10=9, FFTW_RODFT11=10
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct fftw_iodim_do_not_use_me {
 | 
				
			||||||
 | 
					     int n;                     /* dimension size */
 | 
				
			||||||
 | 
					     int is;			/* input stride */
 | 
				
			||||||
 | 
					     int os;			/* output stride */
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <stddef.h> /* for ptrdiff_t */
 | 
				
			||||||
 | 
					struct fftw_iodim64_do_not_use_me {
 | 
				
			||||||
 | 
					     ptrdiff_t n;                     /* dimension size */
 | 
				
			||||||
 | 
					     ptrdiff_t is;			/* input stride */
 | 
				
			||||||
 | 
					     ptrdiff_t os;			/* output stride */
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					typedef void (*fftw_write_char_func_do_not_use_me)(char c, void *);
 | 
				
			||||||
 | 
					typedef int (*fftw_read_char_func_do_not_use_me)(void *);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					  huge second-order macro that defines prototypes for all API
 | 
				
			||||||
 | 
					  functions.  We expand this macro for each supported precision
 | 
				
			||||||
 | 
					 
 | 
				
			||||||
 | 
					  X: name-mangling macro
 | 
				
			||||||
 | 
					  R: real data type
 | 
				
			||||||
 | 
					  C: complex data type
 | 
				
			||||||
 | 
					*/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define FFTW_DEFINE_API(X, R, C)					   \
 | 
				
			||||||
 | 
														   \
 | 
				
			||||||
 | 
					FFTW_DEFINE_COMPLEX(R, C);						   \
 | 
				
			||||||
 | 
														   \
 | 
				
			||||||
 | 
					typedef struct X(plan_s) *X(plan);					   \
 | 
				
			||||||
 | 
														   \
 | 
				
			||||||
 | 
					typedef struct fftw_iodim_do_not_use_me X(iodim);			   \
 | 
				
			||||||
 | 
					typedef struct fftw_iodim64_do_not_use_me X(iodim64);			   \
 | 
				
			||||||
 | 
														   \
 | 
				
			||||||
 | 
					typedef enum fftw_r2r_kind_do_not_use_me X(r2r_kind);			   \
 | 
				
			||||||
 | 
														   \
 | 
				
			||||||
 | 
					typedef fftw_write_char_func_do_not_use_me X(write_char_func);		   \
 | 
				
			||||||
 | 
					typedef fftw_read_char_func_do_not_use_me X(read_char_func);		   \
 | 
				
			||||||
 | 
														   \
 | 
				
			||||||
 | 
					FFTW_EXTERN void X(execute)(const X(plan) p);				   \
 | 
				
			||||||
 | 
														   \
 | 
				
			||||||
 | 
					FFTW_EXTERN X(plan) X(plan_dft)(int rank, const int *n,			   \
 | 
				
			||||||
 | 
							    C *in, C *out, int sign, unsigned flags);		   \
 | 
				
			||||||
 | 
														   \
 | 
				
			||||||
 | 
					FFTW_EXTERN X(plan) X(plan_dft_1d)(int n, C *in, C *out, int sign,	   \
 | 
				
			||||||
 | 
							       unsigned flags);					   \
 | 
				
			||||||
 | 
					FFTW_EXTERN X(plan) X(plan_dft_2d)(int n0, int n1,			   \
 | 
				
			||||||
 | 
							       C *in, C *out, int sign, unsigned flags);	   \
 | 
				
			||||||
 | 
					FFTW_EXTERN X(plan) X(plan_dft_3d)(int n0, int n1, int n2,		   \
 | 
				
			||||||
 | 
							       C *in, C *out, int sign, unsigned flags);	   \
 | 
				
			||||||
 | 
														   \
 | 
				
			||||||
 | 
					FFTW_EXTERN X(plan) X(plan_many_dft)(int rank, const int *n,		   \
 | 
				
			||||||
 | 
					                         int howmany,					   \
 | 
				
			||||||
 | 
					                         C *in, const int *inembed,			   \
 | 
				
			||||||
 | 
					                         int istride, int idist,			   \
 | 
				
			||||||
 | 
					                         C *out, const int *onembed,			   \
 | 
				
			||||||
 | 
					                         int ostride, int odist,			   \
 | 
				
			||||||
 | 
					                         int sign, unsigned flags);			   \
 | 
				
			||||||
 | 
														   \
 | 
				
			||||||
 | 
					FFTW_EXTERN X(plan) X(plan_guru_dft)(int rank, const X(iodim) *dims,	   \
 | 
				
			||||||
 | 
								 int howmany_rank,				   \
 | 
				
			||||||
 | 
								 const X(iodim) *howmany_dims,			   \
 | 
				
			||||||
 | 
								 C *in, C *out,					   \
 | 
				
			||||||
 | 
								 int sign, unsigned flags);			   \
 | 
				
			||||||
 | 
					FFTW_EXTERN X(plan) X(plan_guru_split_dft)(int rank, const X(iodim) *dims, \
 | 
				
			||||||
 | 
								 int howmany_rank,				   \
 | 
				
			||||||
 | 
								 const X(iodim) *howmany_dims,			   \
 | 
				
			||||||
 | 
								 R *ri, R *ii, R *ro, R *io,			   \
 | 
				
			||||||
 | 
								 unsigned flags);				   \
 | 
				
			||||||
 | 
														   \
 | 
				
			||||||
 | 
					FFTW_EXTERN X(plan) X(plan_guru64_dft)(int rank,			   \
 | 
				
			||||||
 | 
					                         const X(iodim64) *dims,			   \
 | 
				
			||||||
 | 
								 int howmany_rank,				   \
 | 
				
			||||||
 | 
								 const X(iodim64) *howmany_dims,		   \
 | 
				
			||||||
 | 
								 C *in, C *out,					   \
 | 
				
			||||||
 | 
								 int sign, unsigned flags);			   \
 | 
				
			||||||
 | 
					FFTW_EXTERN X(plan) X(plan_guru64_split_dft)(int rank,			   \
 | 
				
			||||||
 | 
					                         const X(iodim64) *dims,			   \
 | 
				
			||||||
 | 
								 int howmany_rank,				   \
 | 
				
			||||||
 | 
								 const X(iodim64) *howmany_dims,		   \
 | 
				
			||||||
 | 
								 R *ri, R *ii, R *ro, R *io,			   \
 | 
				
			||||||
 | 
								 unsigned flags);				   \
 | 
				
			||||||
 | 
														   \
 | 
				
			||||||
 | 
					FFTW_EXTERN void X(execute_dft)(const X(plan) p, C *in, C *out);	   \
 | 
				
			||||||
 | 
					FFTW_EXTERN void X(execute_split_dft)(const X(plan) p, R *ri, R *ii,	   \
 | 
				
			||||||
 | 
					                                      R *ro, R *io);			   \
 | 
				
			||||||
 | 
														   \
 | 
				
			||||||
 | 
					FFTW_EXTERN X(plan) X(plan_many_dft_r2c)(int rank, const int *n,	   \
 | 
				
			||||||
 | 
					                             int howmany,				   \
 | 
				
			||||||
 | 
					                             R *in, const int *inembed,			   \
 | 
				
			||||||
 | 
					                             int istride, int idist,			   \
 | 
				
			||||||
 | 
					                             C *out, const int *onembed,		   \
 | 
				
			||||||
 | 
					                             int ostride, int odist,			   \
 | 
				
			||||||
 | 
					                             unsigned flags);				   \
 | 
				
			||||||
 | 
														   \
 | 
				
			||||||
 | 
					FFTW_EXTERN X(plan) X(plan_dft_r2c)(int rank, const int *n,		   \
 | 
				
			||||||
 | 
					                        R *in, C *out, unsigned flags);			   \
 | 
				
			||||||
 | 
														   \
 | 
				
			||||||
 | 
					FFTW_EXTERN X(plan) X(plan_dft_r2c_1d)(int n,R *in,C *out,unsigned flags); \
 | 
				
			||||||
 | 
					FFTW_EXTERN X(plan) X(plan_dft_r2c_2d)(int n0, int n1,			   \
 | 
				
			||||||
 | 
								   R *in, C *out, unsigned flags);		   \
 | 
				
			||||||
 | 
					FFTW_EXTERN X(plan) X(plan_dft_r2c_3d)(int n0, int n1,			   \
 | 
				
			||||||
 | 
								   int n2,					   \
 | 
				
			||||||
 | 
								   R *in, C *out, unsigned flags);		   \
 | 
				
			||||||
 | 
														   \
 | 
				
			||||||
 | 
														   \
 | 
				
			||||||
 | 
					FFTW_EXTERN X(plan) X(plan_many_dft_c2r)(int rank, const int *n,	   \
 | 
				
			||||||
 | 
								     int howmany,				   \
 | 
				
			||||||
 | 
								     C *in, const int *inembed,			   \
 | 
				
			||||||
 | 
								     int istride, int idist,			   \
 | 
				
			||||||
 | 
								     R *out, const int *onembed,		   \
 | 
				
			||||||
 | 
								     int ostride, int odist,			   \
 | 
				
			||||||
 | 
								     unsigned flags);				   \
 | 
				
			||||||
 | 
														   \
 | 
				
			||||||
 | 
					FFTW_EXTERN X(plan) X(plan_dft_c2r)(int rank, const int *n,		   \
 | 
				
			||||||
 | 
					                        C *in, R *out, unsigned flags);			   \
 | 
				
			||||||
 | 
														   \
 | 
				
			||||||
 | 
					FFTW_EXTERN X(plan) X(plan_dft_c2r_1d)(int n,C *in,R *out,unsigned flags); \
 | 
				
			||||||
 | 
					FFTW_EXTERN X(plan) X(plan_dft_c2r_2d)(int n0, int n1,			   \
 | 
				
			||||||
 | 
								   C *in, R *out, unsigned flags);		   \
 | 
				
			||||||
 | 
					FFTW_EXTERN X(plan) X(plan_dft_c2r_3d)(int n0, int n1,			   \
 | 
				
			||||||
 | 
								   int n2,					   \
 | 
				
			||||||
 | 
								   C *in, R *out, unsigned flags);		   \
 | 
				
			||||||
 | 
														   \
 | 
				
			||||||
 | 
					FFTW_EXTERN X(plan) X(plan_guru_dft_r2c)(int rank, const X(iodim) *dims,   \
 | 
				
			||||||
 | 
								     int howmany_rank,				   \
 | 
				
			||||||
 | 
								     const X(iodim) *howmany_dims,		   \
 | 
				
			||||||
 | 
								     R *in, C *out,				   \
 | 
				
			||||||
 | 
								     unsigned flags);				   \
 | 
				
			||||||
 | 
					FFTW_EXTERN X(plan) X(plan_guru_dft_c2r)(int rank, const X(iodim) *dims,   \
 | 
				
			||||||
 | 
								     int howmany_rank,				   \
 | 
				
			||||||
 | 
								     const X(iodim) *howmany_dims,		   \
 | 
				
			||||||
 | 
								     C *in, R *out,				   \
 | 
				
			||||||
 | 
								     unsigned flags);				   \
 | 
				
			||||||
 | 
														   \
 | 
				
			||||||
 | 
					FFTW_EXTERN X(plan) X(plan_guru_split_dft_r2c)(				   \
 | 
				
			||||||
 | 
					                             int rank, const X(iodim) *dims,		   \
 | 
				
			||||||
 | 
								     int howmany_rank,				   \
 | 
				
			||||||
 | 
								     const X(iodim) *howmany_dims,		   \
 | 
				
			||||||
 | 
								     R *in, R *ro, R *io,			   \
 | 
				
			||||||
 | 
								     unsigned flags);				   \
 | 
				
			||||||
 | 
					FFTW_EXTERN X(plan) X(plan_guru_split_dft_c2r)(				   \
 | 
				
			||||||
 | 
					                             int rank, const X(iodim) *dims,		   \
 | 
				
			||||||
 | 
								     int howmany_rank,				   \
 | 
				
			||||||
 | 
								     const X(iodim) *howmany_dims,		   \
 | 
				
			||||||
 | 
								     R *ri, R *ii, R *out,			   \
 | 
				
			||||||
 | 
								     unsigned flags);				   \
 | 
				
			||||||
 | 
														   \
 | 
				
			||||||
 | 
					FFTW_EXTERN X(plan) X(plan_guru64_dft_r2c)(int rank,			   \
 | 
				
			||||||
 | 
					                             const X(iodim64) *dims,			   \
 | 
				
			||||||
 | 
								     int howmany_rank,				   \
 | 
				
			||||||
 | 
								     const X(iodim64) *howmany_dims,		   \
 | 
				
			||||||
 | 
								     R *in, C *out,				   \
 | 
				
			||||||
 | 
								     unsigned flags);				   \
 | 
				
			||||||
 | 
					FFTW_EXTERN X(plan) X(plan_guru64_dft_c2r)(int rank,			   \
 | 
				
			||||||
 | 
					                             const X(iodim64) *dims,			   \
 | 
				
			||||||
 | 
								     int howmany_rank,				   \
 | 
				
			||||||
 | 
								     const X(iodim64) *howmany_dims,		   \
 | 
				
			||||||
 | 
								     C *in, R *out,				   \
 | 
				
			||||||
 | 
								     unsigned flags);				   \
 | 
				
			||||||
 | 
														   \
 | 
				
			||||||
 | 
					FFTW_EXTERN X(plan) X(plan_guru64_split_dft_r2c)(			   \
 | 
				
			||||||
 | 
					                             int rank, const X(iodim64) *dims,		   \
 | 
				
			||||||
 | 
								     int howmany_rank,				   \
 | 
				
			||||||
 | 
								     const X(iodim64) *howmany_dims,		   \
 | 
				
			||||||
 | 
								     R *in, R *ro, R *io,			   \
 | 
				
			||||||
 | 
								     unsigned flags);				   \
 | 
				
			||||||
 | 
					FFTW_EXTERN X(plan) X(plan_guru64_split_dft_c2r)(			   \
 | 
				
			||||||
 | 
					                             int rank, const X(iodim64) *dims,		   \
 | 
				
			||||||
 | 
								     int howmany_rank,				   \
 | 
				
			||||||
 | 
								     const X(iodim64) *howmany_dims,		   \
 | 
				
			||||||
 | 
								     R *ri, R *ii, R *out,			   \
 | 
				
			||||||
 | 
								     unsigned flags);				   \
 | 
				
			||||||
 | 
														   \
 | 
				
			||||||
 | 
					FFTW_EXTERN void X(execute_dft_r2c)(const X(plan) p, R *in, C *out);	   \
 | 
				
			||||||
 | 
					FFTW_EXTERN void X(execute_dft_c2r)(const X(plan) p, C *in, R *out);	   \
 | 
				
			||||||
 | 
														   \
 | 
				
			||||||
 | 
					FFTW_EXTERN void X(execute_split_dft_r2c)(const X(plan) p,		   \
 | 
				
			||||||
 | 
					                                          R *in, R *ro, R *io);		   \
 | 
				
			||||||
 | 
					FFTW_EXTERN void X(execute_split_dft_c2r)(const X(plan) p,		   \
 | 
				
			||||||
 | 
					                                          R *ri, R *ii, R *out);	   \
 | 
				
			||||||
 | 
														   \
 | 
				
			||||||
 | 
					FFTW_EXTERN X(plan) X(plan_many_r2r)(int rank, const int *n,		   \
 | 
				
			||||||
 | 
					                         int howmany,					   \
 | 
				
			||||||
 | 
					                         R *in, const int *inembed,			   \
 | 
				
			||||||
 | 
					                         int istride, int idist,			   \
 | 
				
			||||||
 | 
					                         R *out, const int *onembed,			   \
 | 
				
			||||||
 | 
					                         int ostride, int odist,			   \
 | 
				
			||||||
 | 
					                         const X(r2r_kind) *kind, unsigned flags);	   \
 | 
				
			||||||
 | 
														   \
 | 
				
			||||||
 | 
					FFTW_EXTERN X(plan) X(plan_r2r)(int rank, const int *n, R *in, R *out,	   \
 | 
				
			||||||
 | 
					                    const X(r2r_kind) *kind, unsigned flags);		   \
 | 
				
			||||||
 | 
														   \
 | 
				
			||||||
 | 
					FFTW_EXTERN X(plan) X(plan_r2r_1d)(int n, R *in, R *out,		   \
 | 
				
			||||||
 | 
					                       X(r2r_kind) kind, unsigned flags);		   \
 | 
				
			||||||
 | 
					FFTW_EXTERN X(plan) X(plan_r2r_2d)(int n0, int n1, R *in, R *out,	   \
 | 
				
			||||||
 | 
					                       X(r2r_kind) kind0, X(r2r_kind) kind1,		   \
 | 
				
			||||||
 | 
					                       unsigned flags);					   \
 | 
				
			||||||
 | 
					FFTW_EXTERN X(plan) X(plan_r2r_3d)(int n0, int n1, int n2,		   \
 | 
				
			||||||
 | 
					                       R *in, R *out, X(r2r_kind) kind0,		   \
 | 
				
			||||||
 | 
					                       X(r2r_kind) kind1, X(r2r_kind) kind2,		   \
 | 
				
			||||||
 | 
					                       unsigned flags);					   \
 | 
				
			||||||
 | 
														   \
 | 
				
			||||||
 | 
					FFTW_EXTERN X(plan) X(plan_guru_r2r)(int rank, const X(iodim) *dims,	   \
 | 
				
			||||||
 | 
					                         int howmany_rank,				   \
 | 
				
			||||||
 | 
					                         const X(iodim) *howmany_dims,			   \
 | 
				
			||||||
 | 
					                         R *in, R *out,					   \
 | 
				
			||||||
 | 
					                         const X(r2r_kind) *kind, unsigned flags);	   \
 | 
				
			||||||
 | 
														   \
 | 
				
			||||||
 | 
					FFTW_EXTERN X(plan) X(plan_guru64_r2r)(int rank, const X(iodim64) *dims,   \
 | 
				
			||||||
 | 
					                         int howmany_rank,				   \
 | 
				
			||||||
 | 
					                         const X(iodim64) *howmany_dims,		   \
 | 
				
			||||||
 | 
					                         R *in, R *out,					   \
 | 
				
			||||||
 | 
					                         const X(r2r_kind) *kind, unsigned flags);	   \
 | 
				
			||||||
 | 
														   \
 | 
				
			||||||
 | 
					FFTW_EXTERN void X(execute_r2r)(const X(plan) p, R *in, R *out);	   \
 | 
				
			||||||
 | 
														   \
 | 
				
			||||||
 | 
					FFTW_EXTERN void X(destroy_plan)(X(plan) p);				   \
 | 
				
			||||||
 | 
					FFTW_EXTERN void X(forget_wisdom)(void);				   \
 | 
				
			||||||
 | 
					FFTW_EXTERN void X(cleanup)(void);					   \
 | 
				
			||||||
 | 
														   \
 | 
				
			||||||
 | 
					FFTW_EXTERN void X(set_timelimit)(double t);				   \
 | 
				
			||||||
 | 
														   \
 | 
				
			||||||
 | 
					FFTW_EXTERN void X(plan_with_nthreads)(int nthreads);			   \
 | 
				
			||||||
 | 
					FFTW_EXTERN int X(init_threads)(void);					   \
 | 
				
			||||||
 | 
					FFTW_EXTERN void X(cleanup_threads)(void);				   \
 | 
				
			||||||
 | 
														   \
 | 
				
			||||||
 | 
					FFTW_EXTERN int X(export_wisdom_to_filename)(const char *filename);	   \
 | 
				
			||||||
 | 
					FFTW_EXTERN void X(export_wisdom_to_file)(FILE *output_file);		   \
 | 
				
			||||||
 | 
					FFTW_EXTERN char *X(export_wisdom_to_string)(void);			   \
 | 
				
			||||||
 | 
					FFTW_EXTERN void X(export_wisdom)(X(write_char_func) write_char,   	   \
 | 
				
			||||||
 | 
					                                  void *data);				   \
 | 
				
			||||||
 | 
					FFTW_EXTERN int X(import_system_wisdom)(void);				   \
 | 
				
			||||||
 | 
					FFTW_EXTERN int X(import_wisdom_from_filename)(const char *filename);	   \
 | 
				
			||||||
 | 
					FFTW_EXTERN int X(import_wisdom_from_file)(FILE *input_file);		   \
 | 
				
			||||||
 | 
					FFTW_EXTERN int X(import_wisdom_from_string)(const char *input_string);	   \
 | 
				
			||||||
 | 
					FFTW_EXTERN int X(import_wisdom)(X(read_char_func) read_char, void *data); \
 | 
				
			||||||
 | 
														   \
 | 
				
			||||||
 | 
					FFTW_EXTERN void X(fprint_plan)(const X(plan) p, FILE *output_file);	   \
 | 
				
			||||||
 | 
					FFTW_EXTERN void X(print_plan)(const X(plan) p);			   \
 | 
				
			||||||
 | 
					FFTW_EXTERN char *X(sprint_plan)(const X(plan) p);			   \
 | 
				
			||||||
 | 
														   \
 | 
				
			||||||
 | 
					FFTW_EXTERN void *X(malloc)(size_t n);					   \
 | 
				
			||||||
 | 
					FFTW_EXTERN R *X(alloc_real)(size_t n);					   \
 | 
				
			||||||
 | 
					FFTW_EXTERN C *X(alloc_complex)(size_t n);				   \
 | 
				
			||||||
 | 
					FFTW_EXTERN void X(free)(void *p);					   \
 | 
				
			||||||
 | 
														   \
 | 
				
			||||||
 | 
					FFTW_EXTERN void X(flops)(const X(plan) p,				   \
 | 
				
			||||||
 | 
					                          double *add, double *mul, double *fmas);	   \
 | 
				
			||||||
 | 
					FFTW_EXTERN double X(estimate_cost)(const X(plan) p);			   \
 | 
				
			||||||
 | 
					FFTW_EXTERN double X(cost)(const X(plan) p);				   \
 | 
				
			||||||
 | 
														   \
 | 
				
			||||||
 | 
					FFTW_EXTERN int X(alignment_of)(R *p);                                     \
 | 
				
			||||||
 | 
					FFTW_EXTERN const char X(version)[];                                       \
 | 
				
			||||||
 | 
					FFTW_EXTERN const char X(cc)[];						   \
 | 
				
			||||||
 | 
					FFTW_EXTERN const char X(codelet_optim)[];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* end of FFTW_DEFINE_API macro */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					FFTW_DEFINE_API(FFTW_MANGLE_DOUBLE, double, fftw_complex)
 | 
				
			||||||
 | 
					FFTW_DEFINE_API(FFTW_MANGLE_FLOAT, float, fftwf_complex)
 | 
				
			||||||
 | 
					FFTW_DEFINE_API(FFTW_MANGLE_LONG_DOUBLE, long double, fftwl_complex)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* __float128 (quad precision) is a gcc extension on i386, x86_64, and ia64
 | 
				
			||||||
 | 
					   for gcc >= 4.6 (compiled in FFTW with --enable-quad-precision) */
 | 
				
			||||||
 | 
					#if (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6)) \
 | 
				
			||||||
 | 
					 && !(defined(__ICC) || defined(__INTEL_COMPILER)) \
 | 
				
			||||||
 | 
					 && (defined(__i386__) || defined(__x86_64__) || defined(__ia64__))
 | 
				
			||||||
 | 
					#  if !defined(FFTW_NO_Complex) && defined(_Complex_I) && defined(complex) && defined(I)
 | 
				
			||||||
 | 
					/* note: __float128 is a typedef, which is not supported with the _Complex
 | 
				
			||||||
 | 
					         keyword in gcc, so instead we use this ugly __attribute__ version.
 | 
				
			||||||
 | 
					         However, we can't simply pass the __attribute__ version to
 | 
				
			||||||
 | 
					         FFTW_DEFINE_API because the __attribute__ confuses gcc in pointer
 | 
				
			||||||
 | 
					         types.  Hence redefining FFTW_DEFINE_COMPLEX.  Ugh. */
 | 
				
			||||||
 | 
					#    undef FFTW_DEFINE_COMPLEX
 | 
				
			||||||
 | 
					#    define FFTW_DEFINE_COMPLEX(R, C) typedef _Complex float __attribute__((mode(TC))) C
 | 
				
			||||||
 | 
					#  endif
 | 
				
			||||||
 | 
					FFTW_DEFINE_API(FFTW_MANGLE_QUAD, __float128, fftwq_complex)
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define FFTW_FORWARD (-1)
 | 
				
			||||||
 | 
					#define FFTW_BACKWARD (+1)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define FFTW_NO_TIMELIMIT (-1.0)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* documented flags */
 | 
				
			||||||
 | 
					#define FFTW_MEASURE (0U)
 | 
				
			||||||
 | 
					#define FFTW_DESTROY_INPUT (1U << 0)
 | 
				
			||||||
 | 
					#define FFTW_UNALIGNED (1U << 1)
 | 
				
			||||||
 | 
					#define FFTW_CONSERVE_MEMORY (1U << 2)
 | 
				
			||||||
 | 
					#define FFTW_EXHAUSTIVE (1U << 3) /* NO_EXHAUSTIVE is default */
 | 
				
			||||||
 | 
					#define FFTW_PRESERVE_INPUT (1U << 4) /* cancels FFTW_DESTROY_INPUT */
 | 
				
			||||||
 | 
					#define FFTW_PATIENT (1U << 5) /* IMPATIENT is default */
 | 
				
			||||||
 | 
					#define FFTW_ESTIMATE (1U << 6)
 | 
				
			||||||
 | 
					#define FFTW_WISDOM_ONLY (1U << 21)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* undocumented beyond-guru flags */
 | 
				
			||||||
 | 
					#define FFTW_ESTIMATE_PATIENT (1U << 7)
 | 
				
			||||||
 | 
					#define FFTW_BELIEVE_PCOST (1U << 8)
 | 
				
			||||||
 | 
					#define FFTW_NO_DFT_R2HC (1U << 9)
 | 
				
			||||||
 | 
					#define FFTW_NO_NONTHREADED (1U << 10)
 | 
				
			||||||
 | 
					#define FFTW_NO_BUFFERING (1U << 11)
 | 
				
			||||||
 | 
					#define FFTW_NO_INDIRECT_OP (1U << 12)
 | 
				
			||||||
 | 
					#define FFTW_ALLOW_LARGE_GENERIC (1U << 13) /* NO_LARGE_GENERIC is default */
 | 
				
			||||||
 | 
					#define FFTW_NO_RANK_SPLITS (1U << 14)
 | 
				
			||||||
 | 
					#define FFTW_NO_VRANK_SPLITS (1U << 15)
 | 
				
			||||||
 | 
					#define FFTW_NO_VRECURSE (1U << 16)
 | 
				
			||||||
 | 
					#define FFTW_NO_SIMD (1U << 17)
 | 
				
			||||||
 | 
					#define FFTW_NO_SLOW (1U << 18)
 | 
				
			||||||
 | 
					#define FFTW_NO_FIXED_RADIX_LARGE_N (1U << 19)
 | 
				
			||||||
 | 
					#define FFTW_ALLOW_PRUNING (1U << 20)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifdef __cplusplus
 | 
				
			||||||
 | 
					}  /* extern "C" */
 | 
				
			||||||
 | 
					#endif /* __cplusplus */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#endif /* FFTW3_H */
 | 
				
			||||||
@@ -349,7 +349,7 @@ void localConvert(const Lattice<vobj> &in,Lattice<vvobj> &out)
 | 
				
			|||||||
    assert(ig->_ldimensions[d] == og->_ldimensions[d]);
 | 
					    assert(ig->_ldimensions[d] == og->_ldimensions[d]);
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
PARALLEL_FOR_LOOP
 | 
					  //PARALLEL_FOR_LOOP
 | 
				
			||||||
  for(int idx=0;idx<ig->lSites();idx++){
 | 
					  for(int idx=0;idx<ig->lSites();idx++){
 | 
				
			||||||
    std::vector<int> lcoor(ni);
 | 
					    std::vector<int> lcoor(ni);
 | 
				
			||||||
    ig->LocalIndexToLocalCoor(idx,lcoor);
 | 
					    ig->LocalIndexToLocalCoor(idx,lcoor);
 | 
				
			||||||
@@ -446,6 +446,79 @@ void ExtractSlice(Lattice<vobj> &lowDim, Lattice<vobj> & higherDim,int slice, in
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					template<class vobj>
 | 
				
			||||||
 | 
					void InsertSliceLocal(Lattice<vobj> &lowDim, Lattice<vobj> & higherDim,int slice_lo,int slice_hi, int orthog)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					  typedef typename vobj::scalar_object sobj;
 | 
				
			||||||
 | 
					  sobj s;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  GridBase *lg = lowDim._grid;
 | 
				
			||||||
 | 
					  GridBase *hg = higherDim._grid;
 | 
				
			||||||
 | 
					  int nl = lg->_ndimension;
 | 
				
			||||||
 | 
					  int nh = hg->_ndimension;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  assert(nl == nh);
 | 
				
			||||||
 | 
					  assert(orthog<nh);
 | 
				
			||||||
 | 
					  assert(orthog>=0);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  for(int d=0;d<nh;d++){
 | 
				
			||||||
 | 
					    assert(lg->_processors[d]  == hg->_processors[d]);
 | 
				
			||||||
 | 
					    assert(lg->_ldimensions[d] == hg->_ldimensions[d]);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // the above should guarantee that the operations are local
 | 
				
			||||||
 | 
					  //PARALLEL_FOR_LOOP
 | 
				
			||||||
 | 
					  for(int idx=0;idx<lg->lSites();idx++){
 | 
				
			||||||
 | 
					    std::vector<int> lcoor(nl);
 | 
				
			||||||
 | 
					    std::vector<int> hcoor(nh);
 | 
				
			||||||
 | 
					    lg->LocalIndexToLocalCoor(idx,lcoor);
 | 
				
			||||||
 | 
					    if( lcoor[orthog] == slice_lo ) { 
 | 
				
			||||||
 | 
					      hcoor=lcoor;
 | 
				
			||||||
 | 
					      hcoor[orthog] = slice_hi;
 | 
				
			||||||
 | 
					      peekLocalSite(s,lowDim,lcoor);
 | 
				
			||||||
 | 
					      pokeLocalSite(s,higherDim,hcoor);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					template<class vobj>
 | 
				
			||||||
 | 
					void ExtractSliceLocal(Lattice<vobj> &lowDim, Lattice<vobj> & higherDim,int slice_lo,int slice_hi, int orthog)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					  typedef typename vobj::scalar_object sobj;
 | 
				
			||||||
 | 
					  sobj s;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  GridBase *lg = lowDim._grid;
 | 
				
			||||||
 | 
					  GridBase *hg = higherDim._grid;
 | 
				
			||||||
 | 
					  int nl = lg->_ndimension;
 | 
				
			||||||
 | 
					  int nh = hg->_ndimension;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  assert(nl == nh);
 | 
				
			||||||
 | 
					  assert(orthog<nh);
 | 
				
			||||||
 | 
					  assert(orthog>=0);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  for(int d=0;d<nh;d++){
 | 
				
			||||||
 | 
					    assert(lg->_processors[d]  == hg->_processors[d]);
 | 
				
			||||||
 | 
					    assert(lg->_ldimensions[d] == hg->_ldimensions[d]);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // the above should guarantee that the operations are local
 | 
				
			||||||
 | 
					  //PARALLEL_FOR_LOOP
 | 
				
			||||||
 | 
					  for(int idx=0;idx<lg->lSites();idx++){
 | 
				
			||||||
 | 
					    std::vector<int> lcoor(nl);
 | 
				
			||||||
 | 
					    std::vector<int> hcoor(nh);
 | 
				
			||||||
 | 
					    lg->LocalIndexToLocalCoor(idx,lcoor);
 | 
				
			||||||
 | 
					    if( lcoor[orthog] == slice_lo ) { 
 | 
				
			||||||
 | 
					      hcoor=lcoor;
 | 
				
			||||||
 | 
					      hcoor[orthog] = slice_hi;
 | 
				
			||||||
 | 
					      peekLocalSite(s,higherDim,hcoor);
 | 
				
			||||||
 | 
					      pokeLocalSite(s,lowDim,lcoor);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
template<class vobj>
 | 
					template<class vobj>
 | 
				
			||||||
void Replicate(Lattice<vobj> &coarse,Lattice<vobj> & fine)
 | 
					void Replicate(Lattice<vobj> &coarse,Lattice<vobj> & fine)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -194,22 +194,22 @@ class BinaryIO {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
      std::vector<int> site({x,y,z,t});
 | 
					      std::vector<int> site({x,y,z,t});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      if ( grid->IsBoss() ) {
 | 
					      if (grid->IsBoss()) {
 | 
				
			||||||
	fin.read((char *)&file_object,sizeof(file_object));
 | 
					        fin.read((char *)&file_object, sizeof(file_object));
 | 
				
			||||||
	bytes += sizeof(file_object);
 | 
					        bytes += sizeof(file_object);
 | 
				
			||||||
	if(ieee32big) be32toh_v((void *)&file_object,sizeof(file_object));
 | 
					        if (ieee32big) be32toh_v((void *)&file_object, sizeof(file_object));
 | 
				
			||||||
	if(ieee32)    le32toh_v((void *)&file_object,sizeof(file_object));
 | 
					        if (ieee32) le32toh_v((void *)&file_object, sizeof(file_object));
 | 
				
			||||||
	if(ieee64big) be64toh_v((void *)&file_object,sizeof(file_object));
 | 
					        if (ieee64big) be64toh_v((void *)&file_object, sizeof(file_object));
 | 
				
			||||||
	if(ieee64)    le64toh_v((void *)&file_object,sizeof(file_object));
 | 
					        if (ieee64) le64toh_v((void *)&file_object, sizeof(file_object));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	munge(file_object,munged,csum);
 | 
					        munge(file_object, munged, csum);
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
      // The boss who read the file has their value poked
 | 
					      // The boss who read the file has their value poked
 | 
				
			||||||
      pokeSite(munged,Umu,site);
 | 
					      pokeSite(munged,Umu,site);
 | 
				
			||||||
    }}}}
 | 
					    }}}}
 | 
				
			||||||
    timer.Stop();
 | 
					    timer.Stop();
 | 
				
			||||||
    std::cout<<GridLogPerformance<<"readObjectSerial: read "<< bytes <<" bytes in "<<timer.Elapsed() <<" "
 | 
					    std::cout<<GridLogPerformance<<"readObjectSerial: read "<< bytes <<" bytes in "<<timer.Elapsed() <<" "
 | 
				
			||||||
	     << (double)bytes/ (double)timer.useconds() <<" MB/s "  <<std::endl;
 | 
					       << (double)bytes/ (double)timer.useconds() <<" MB/s "  <<std::endl;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    return csum;
 | 
					    return csum;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
@@ -255,19 +255,19 @@ class BinaryIO {
 | 
				
			|||||||
      
 | 
					      
 | 
				
			||||||
      if ( grid->IsBoss() ) {
 | 
					      if ( grid->IsBoss() ) {
 | 
				
			||||||
  
 | 
					  
 | 
				
			||||||
	if(ieee32big) htobe32_v((void *)&file_object,sizeof(file_object));
 | 
					  if(ieee32big) htobe32_v((void *)&file_object,sizeof(file_object));
 | 
				
			||||||
	if(ieee32)    htole32_v((void *)&file_object,sizeof(file_object));
 | 
					  if(ieee32)    htole32_v((void *)&file_object,sizeof(file_object));
 | 
				
			||||||
	if(ieee64big) htobe64_v((void *)&file_object,sizeof(file_object));
 | 
					  if(ieee64big) htobe64_v((void *)&file_object,sizeof(file_object));
 | 
				
			||||||
	if(ieee64)    htole64_v((void *)&file_object,sizeof(file_object));
 | 
					  if(ieee64)    htole64_v((void *)&file_object,sizeof(file_object));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// NB could gather an xstrip as an optimisation.
 | 
					  // NB could gather an xstrip as an optimisation.
 | 
				
			||||||
	fout.write((char *)&file_object,sizeof(file_object));
 | 
					  fout.write((char *)&file_object,sizeof(file_object));
 | 
				
			||||||
	bytes+=sizeof(file_object);
 | 
					  bytes+=sizeof(file_object);
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
    }}}}
 | 
					    }}}}
 | 
				
			||||||
    timer.Stop();
 | 
					    timer.Stop();
 | 
				
			||||||
    std::cout<<GridLogPerformance<<"writeObjectSerial: wrote "<< bytes <<" bytes in "<<timer.Elapsed() <<" "
 | 
					    std::cout<<GridLogPerformance<<"writeObjectSerial: wrote "<< bytes <<" bytes in "<<timer.Elapsed() <<" "
 | 
				
			||||||
	     << (double)bytes/timer.useconds() <<" MB/s "  <<std::endl;
 | 
					       << (double)bytes/timer.useconds() <<" MB/s "  <<std::endl;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    return csum;
 | 
					    return csum;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
@@ -305,15 +305,15 @@ class BinaryIO {
 | 
				
			|||||||
      int l_idx=parallel.generator_idx(o_idx,i_idx);
 | 
					      int l_idx=parallel.generator_idx(o_idx,i_idx);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      if( rank == grid->ThisRank() ){
 | 
					      if( rank == grid->ThisRank() ){
 | 
				
			||||||
	//	std::cout << "rank" << rank<<" Getting state for index "<<l_idx<<std::endl;
 | 
					  //  std::cout << "rank" << rank<<" Getting state for index "<<l_idx<<std::endl;
 | 
				
			||||||
	parallel.GetState(saved,l_idx);
 | 
					  parallel.GetState(saved,l_idx);
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      grid->Broadcast(rank,(void *)&saved[0],bytes);
 | 
					      grid->Broadcast(rank,(void *)&saved[0],bytes);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      if ( grid->IsBoss() ) {
 | 
					      if ( grid->IsBoss() ) {
 | 
				
			||||||
	Uint32Checksum((uint32_t *)&saved[0],bytes,csum);
 | 
					  Uint32Checksum((uint32_t *)&saved[0],bytes,csum);
 | 
				
			||||||
	fout.write((char *)&saved[0],bytes);
 | 
					  fout.write((char *)&saved[0],bytes);
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
@@ -355,14 +355,14 @@ class BinaryIO {
 | 
				
			|||||||
      int l_idx=parallel.generator_idx(o_idx,i_idx);
 | 
					      int l_idx=parallel.generator_idx(o_idx,i_idx);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      if ( grid->IsBoss() ) {
 | 
					      if ( grid->IsBoss() ) {
 | 
				
			||||||
	fin.read((char *)&saved[0],bytes);
 | 
					  fin.read((char *)&saved[0],bytes);
 | 
				
			||||||
	Uint32Checksum((uint32_t *)&saved[0],bytes,csum);
 | 
					  Uint32Checksum((uint32_t *)&saved[0],bytes,csum);
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      grid->Broadcast(0,(void *)&saved[0],bytes);
 | 
					      grid->Broadcast(0,(void *)&saved[0],bytes);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      if( rank == grid->ThisRank() ){
 | 
					      if( rank == grid->ThisRank() ){
 | 
				
			||||||
	parallel.SetState(saved,l_idx);
 | 
					  parallel.SetState(saved,l_idx);
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
@@ -415,15 +415,15 @@ class BinaryIO {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
      if ( d == 0 ) parallel[d] = 0;
 | 
					      if ( d == 0 ) parallel[d] = 0;
 | 
				
			||||||
      if (parallel[d]) {
 | 
					      if (parallel[d]) {
 | 
				
			||||||
	range[d] = grid->_ldimensions[d];
 | 
					  range[d] = grid->_ldimensions[d];
 | 
				
			||||||
	start[d] = grid->_processor_coor[d]*range[d];
 | 
					  start[d] = grid->_processor_coor[d]*range[d];
 | 
				
			||||||
	ioproc[d]= grid->_processor_coor[d];
 | 
					  ioproc[d]= grid->_processor_coor[d];
 | 
				
			||||||
      } else {
 | 
					      } else {
 | 
				
			||||||
	range[d] = grid->_gdimensions[d];
 | 
					  range[d] = grid->_gdimensions[d];
 | 
				
			||||||
	start[d] = 0;
 | 
					  start[d] = 0;
 | 
				
			||||||
	ioproc[d]= 0;
 | 
					  ioproc[d]= 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if ( grid->_processor_coor[d] != 0 ) IOnode = 0;
 | 
					  if ( grid->_processor_coor[d] != 0 ) IOnode = 0;
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
      slice_vol = slice_vol * range[d];
 | 
					      slice_vol = slice_vol * range[d];
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
@@ -434,9 +434,9 @@ class BinaryIO {
 | 
				
			|||||||
      std::cout<< std::dec ;
 | 
					      std::cout<< std::dec ;
 | 
				
			||||||
      std::cout<< GridLogMessage<< "Parallel read I/O to "<< file << " with " <<tmp<< " IOnodes for subslice ";
 | 
					      std::cout<< GridLogMessage<< "Parallel read I/O to "<< file << " with " <<tmp<< " IOnodes for subslice ";
 | 
				
			||||||
      for(int d=0;d<grid->_ndimension;d++){
 | 
					      for(int d=0;d<grid->_ndimension;d++){
 | 
				
			||||||
	std::cout<< range[d];
 | 
					  std::cout<< range[d];
 | 
				
			||||||
	if( d< grid->_ndimension-1 ) 
 | 
					  if( d< grid->_ndimension-1 ) 
 | 
				
			||||||
	  std::cout<< " x ";
 | 
					    std::cout<< " x ";
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
      std::cout << std::endl;
 | 
					      std::cout << std::endl;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
@@ -472,8 +472,8 @@ class BinaryIO {
 | 
				
			|||||||
      Lexicographic::CoorFromIndex(tsite,tlex,range);
 | 
					      Lexicographic::CoorFromIndex(tsite,tlex,range);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      for(int d=0;d<nd;d++){
 | 
					      for(int d=0;d<nd;d++){
 | 
				
			||||||
	lsite[d] = tsite[d]%grid->_ldimensions[d];  // local site
 | 
					  lsite[d] = tsite[d]%grid->_ldimensions[d];  // local site
 | 
				
			||||||
	gsite[d] = tsite[d]+start[d];               // global site
 | 
					  gsite[d] = tsite[d]+start[d];               // global site
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      /////////////////////////
 | 
					      /////////////////////////
 | 
				
			||||||
@@ -488,28 +488,28 @@ class BinaryIO {
 | 
				
			|||||||
      ////////////////////////////////
 | 
					      ////////////////////////////////
 | 
				
			||||||
      if (myrank == iorank) {
 | 
					      if (myrank == iorank) {
 | 
				
			||||||
  
 | 
					  
 | 
				
			||||||
	fin.seekg(offset+g_idx*sizeof(fileObj));
 | 
					  fin.seekg(offset+g_idx*sizeof(fileObj));
 | 
				
			||||||
	fin.read((char *)&fileObj,sizeof(fileObj));
 | 
					  fin.read((char *)&fileObj,sizeof(fileObj));
 | 
				
			||||||
	bytes+=sizeof(fileObj);
 | 
					  bytes+=sizeof(fileObj);
 | 
				
			||||||
  
 | 
					  
 | 
				
			||||||
	if(ieee32big) be32toh_v((void *)&fileObj,sizeof(fileObj));
 | 
					  if(ieee32big) be32toh_v((void *)&fileObj,sizeof(fileObj));
 | 
				
			||||||
	if(ieee32)    le32toh_v((void *)&fileObj,sizeof(fileObj));
 | 
					  if(ieee32)    le32toh_v((void *)&fileObj,sizeof(fileObj));
 | 
				
			||||||
	if(ieee64big) be64toh_v((void *)&fileObj,sizeof(fileObj));
 | 
					  if(ieee64big) be64toh_v((void *)&fileObj,sizeof(fileObj));
 | 
				
			||||||
	if(ieee64)    le64toh_v((void *)&fileObj,sizeof(fileObj));
 | 
					  if(ieee64)    le64toh_v((void *)&fileObj,sizeof(fileObj));
 | 
				
			||||||
  
 | 
					  
 | 
				
			||||||
	munge(fileObj,siteObj,csum);
 | 
					  munge(fileObj,siteObj,csum);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      } 
 | 
					      } 
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      // Possibly do transport through pt2pt 
 | 
					      // Possibly do transport through pt2pt 
 | 
				
			||||||
      if ( rank != iorank ) { 
 | 
					      if ( rank != iorank ) { 
 | 
				
			||||||
	if ( (myrank == rank) || (myrank==iorank) ) {
 | 
					  if ( (myrank == rank) || (myrank==iorank) ) {
 | 
				
			||||||
	  grid->SendRecvPacket((void *)&siteObj,(void *)&siteObj,iorank,rank,sizeof(siteObj));
 | 
					    grid->SendRecvPacket((void *)&siteObj,(void *)&siteObj,iorank,rank,sizeof(siteObj));
 | 
				
			||||||
	}
 | 
					  }
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
      // Poke at destination
 | 
					      // Poke at destination
 | 
				
			||||||
      if ( myrank == rank ) {
 | 
					      if ( myrank == rank ) {
 | 
				
			||||||
	  pokeLocalSite(siteObj,Umu,lsite);
 | 
					    pokeLocalSite(siteObj,Umu,lsite);
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
      grid->Barrier(); // necessary?
 | 
					      grid->Barrier(); // necessary?
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
@@ -520,7 +520,7 @@ class BinaryIO {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    timer.Stop();
 | 
					    timer.Stop();
 | 
				
			||||||
    std::cout<<GridLogPerformance<<"readObjectParallel: read "<< bytes <<" bytes in "<<timer.Elapsed() <<" "
 | 
					    std::cout<<GridLogPerformance<<"readObjectParallel: read "<< bytes <<" bytes in "<<timer.Elapsed() <<" "
 | 
				
			||||||
	     << (double)bytes/timer.useconds() <<" MB/s "  <<std::endl;
 | 
					       << (double)bytes/timer.useconds() <<" MB/s "  <<std::endl;
 | 
				
			||||||
    
 | 
					    
 | 
				
			||||||
    return csum;
 | 
					    return csum;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
@@ -558,15 +558,15 @@ class BinaryIO {
 | 
				
			|||||||
      if ( d!= grid->_ndimension-1 ) parallel[d] = 0;
 | 
					      if ( d!= grid->_ndimension-1 ) parallel[d] = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      if (parallel[d]) {
 | 
					      if (parallel[d]) {
 | 
				
			||||||
	range[d] = grid->_ldimensions[d];
 | 
					  range[d] = grid->_ldimensions[d];
 | 
				
			||||||
	start[d] = grid->_processor_coor[d]*range[d];
 | 
					  start[d] = grid->_processor_coor[d]*range[d];
 | 
				
			||||||
	ioproc[d]= grid->_processor_coor[d];
 | 
					  ioproc[d]= grid->_processor_coor[d];
 | 
				
			||||||
      } else {
 | 
					      } else {
 | 
				
			||||||
	range[d] = grid->_gdimensions[d];
 | 
					  range[d] = grid->_gdimensions[d];
 | 
				
			||||||
	start[d] = 0;
 | 
					  start[d] = 0;
 | 
				
			||||||
	ioproc[d]= 0;
 | 
					  ioproc[d]= 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if ( grid->_processor_coor[d] != 0 ) IOnode = 0;
 | 
					  if ( grid->_processor_coor[d] != 0 ) IOnode = 0;
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      slice_vol = slice_vol * range[d];
 | 
					      slice_vol = slice_vol * range[d];
 | 
				
			||||||
@@ -577,9 +577,9 @@ class BinaryIO {
 | 
				
			|||||||
      grid->GlobalSum(tmp);
 | 
					      grid->GlobalSum(tmp);
 | 
				
			||||||
      std::cout<< GridLogMessage<< "Parallel write I/O from "<< file << " with " <<tmp<< " IOnodes for subslice ";
 | 
					      std::cout<< GridLogMessage<< "Parallel write I/O from "<< file << " with " <<tmp<< " IOnodes for subslice ";
 | 
				
			||||||
      for(int d=0;d<grid->_ndimension;d++){
 | 
					      for(int d=0;d<grid->_ndimension;d++){
 | 
				
			||||||
	std::cout<< range[d];
 | 
					  std::cout<< range[d];
 | 
				
			||||||
	if( d< grid->_ndimension-1 ) 
 | 
					  if( d< grid->_ndimension-1 ) 
 | 
				
			||||||
	  std::cout<< " x ";
 | 
					    std::cout<< " x ";
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
      std::cout << std::endl;
 | 
					      std::cout << std::endl;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
@@ -619,8 +619,8 @@ class BinaryIO {
 | 
				
			|||||||
      Lexicographic::CoorFromIndex(tsite,tlex,range);
 | 
					      Lexicographic::CoorFromIndex(tsite,tlex,range);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      for(int d=0;d<nd;d++){
 | 
					      for(int d=0;d<nd;d++){
 | 
				
			||||||
	lsite[d] = tsite[d]%grid->_ldimensions[d];  // local site
 | 
					  lsite[d] = tsite[d]%grid->_ldimensions[d];  // local site
 | 
				
			||||||
	gsite[d] = tsite[d]+start[d];               // global site
 | 
					  gsite[d] = tsite[d]+start[d];               // global site
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -640,26 +640,26 @@ class BinaryIO {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
      // Pair of nodes may need to do pt2pt send
 | 
					      // Pair of nodes may need to do pt2pt send
 | 
				
			||||||
      if ( rank != iorank ) { // comms is necessary
 | 
					      if ( rank != iorank ) { // comms is necessary
 | 
				
			||||||
	if ( (myrank == rank) || (myrank==iorank) ) { // and we have to do it
 | 
					  if ( (myrank == rank) || (myrank==iorank) ) { // and we have to do it
 | 
				
			||||||
	  // Send to IOrank 
 | 
					    // Send to IOrank 
 | 
				
			||||||
	  grid->SendRecvPacket((void *)&siteObj,(void *)&siteObj,rank,iorank,sizeof(siteObj));
 | 
					    grid->SendRecvPacket((void *)&siteObj,(void *)&siteObj,rank,iorank,sizeof(siteObj));
 | 
				
			||||||
	}
 | 
					  }
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      grid->Barrier(); // necessary?
 | 
					      grid->Barrier(); // necessary?
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      if (myrank == iorank) {
 | 
					      if (myrank == iorank) {
 | 
				
			||||||
  
 | 
					  
 | 
				
			||||||
	munge(siteObj,fileObj,csum);
 | 
					  munge(siteObj,fileObj,csum);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if(ieee32big) htobe32_v((void *)&fileObj,sizeof(fileObj));
 | 
					  if(ieee32big) htobe32_v((void *)&fileObj,sizeof(fileObj));
 | 
				
			||||||
	if(ieee32)    htole32_v((void *)&fileObj,sizeof(fileObj));
 | 
					  if(ieee32)    htole32_v((void *)&fileObj,sizeof(fileObj));
 | 
				
			||||||
	if(ieee64big) htobe64_v((void *)&fileObj,sizeof(fileObj));
 | 
					  if(ieee64big) htobe64_v((void *)&fileObj,sizeof(fileObj));
 | 
				
			||||||
	if(ieee64)    htole64_v((void *)&fileObj,sizeof(fileObj));
 | 
					  if(ieee64)    htole64_v((void *)&fileObj,sizeof(fileObj));
 | 
				
			||||||
  
 | 
					  
 | 
				
			||||||
	fout.seekp(offset+g_idx*sizeof(fileObj));
 | 
					  fout.seekp(offset+g_idx*sizeof(fileObj));
 | 
				
			||||||
	fout.write((char *)&fileObj,sizeof(fileObj));
 | 
					  fout.write((char *)&fileObj,sizeof(fileObj));
 | 
				
			||||||
	bytes+=sizeof(fileObj);
 | 
					  bytes+=sizeof(fileObj);
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -668,7 +668,7 @@ class BinaryIO {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    timer.Stop();
 | 
					    timer.Stop();
 | 
				
			||||||
    std::cout<<GridLogPerformance<<"writeObjectParallel: wrote "<< bytes <<" bytes in "<<timer.Elapsed() <<" "
 | 
					    std::cout<<GridLogPerformance<<"writeObjectParallel: wrote "<< bytes <<" bytes in "<<timer.Elapsed() <<" "
 | 
				
			||||||
	     << (double)bytes/timer.useconds() <<" MB/s "  <<std::endl;
 | 
					       << (double)bytes/timer.useconds() <<" MB/s "  <<std::endl;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    return csum;
 | 
					    return csum;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -55,10 +55,13 @@ namespace QCD {
 | 
				
			|||||||
    //////////////////////////////////////////////////////////////////////////////
 | 
					    //////////////////////////////////////////////////////////////////////////////
 | 
				
			||||||
    // QCD iMatrix types
 | 
					    // QCD iMatrix types
 | 
				
			||||||
    // Index conventions:                            Lorentz x Spin x Colour
 | 
					    // Index conventions:                            Lorentz x Spin x Colour
 | 
				
			||||||
 | 
					    // note: static const int or constexpr will work for type deductions
 | 
				
			||||||
 | 
					    //       with the intel compiler (up to version 17)
 | 
				
			||||||
    //////////////////////////////////////////////////////////////////////////////
 | 
					    //////////////////////////////////////////////////////////////////////////////
 | 
				
			||||||
    static const int ColourIndex = 2;
 | 
					    #define ColourIndex  2
 | 
				
			||||||
    static const int SpinIndex   = 1;
 | 
					    #define SpinIndex    1
 | 
				
			||||||
    static const int LorentzIndex= 0;
 | 
					    #define LorentzIndex 0
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  
 | 
					  
 | 
				
			||||||
    // Also should make these a named enum type
 | 
					    // Also should make these a named enum type
 | 
				
			||||||
    static const int DaggerNo=0;
 | 
					    static const int DaggerNo=0;
 | 
				
			||||||
@@ -490,16 +493,27 @@ namespace QCD {
 | 
				
			|||||||
}   //namespace QCD
 | 
					}   //namespace QCD
 | 
				
			||||||
} // Grid
 | 
					} // Grid
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include <Grid/qcd/utils/SpaceTimeGrid.h>
 | 
					#include <Grid/qcd/utils/SpaceTimeGrid.h>
 | 
				
			||||||
#include <Grid/qcd/spin/Dirac.h>
 | 
					#include <Grid/qcd/spin/Dirac.h>
 | 
				
			||||||
#include <Grid/qcd/spin/TwoSpinor.h>
 | 
					#include <Grid/qcd/spin/TwoSpinor.h>
 | 
				
			||||||
#include <Grid/qcd/utils/LinalgUtils.h>
 | 
					#include <Grid/qcd/utils/LinalgUtils.h>
 | 
				
			||||||
#include <Grid/qcd/utils/CovariantCshift.h>
 | 
					#include <Grid/qcd/utils/CovariantCshift.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Include representations 	
 | 
				
			||||||
#include <Grid/qcd/utils/SUn.h>
 | 
					#include <Grid/qcd/utils/SUn.h>
 | 
				
			||||||
 | 
					#include <Grid/qcd/utils/SUnAdjoint.h>
 | 
				
			||||||
 | 
					#include <Grid/qcd/utils/SUnTwoIndex.h>
 | 
				
			||||||
 | 
					#include <Grid/qcd/representations/hmc_types.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include <Grid/qcd/action/Actions.h>
 | 
					#include <Grid/qcd/action/Actions.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <Grid/qcd/smearing/Smearing.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include <Grid/qcd/hmc/integrators/Integrator.h>
 | 
					#include <Grid/qcd/hmc/integrators/Integrator.h>
 | 
				
			||||||
#include <Grid/qcd/hmc/integrators/Integrator_algorithm.h>
 | 
					#include <Grid/qcd/hmc/integrators/Integrator_algorithm.h>
 | 
				
			||||||
#include <Grid/qcd/hmc/HMC.h>
 | 
					#include <Grid/qcd/hmc/HMC.h>
 | 
				
			||||||
#include <Grid/qcd/smearing/Smearing.h>
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,87 +1,153 @@
 | 
				
			|||||||
    /*************************************************************************************
 | 
					/*************************************************************************************
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    Grid physics library, www.github.com/paboyle/Grid 
 | 
					Grid physics library, www.github.com/paboyle/Grid
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    Source file: ./lib/qcd/action/ActionBase.h
 | 
					Source file: ./lib/qcd/action/ActionBase.h
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    Copyright (C) 2015
 | 
					Copyright (C) 2015
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Author: Peter Boyle <paboyle@ph.ed.ac.uk>
 | 
					Author: Peter Boyle <paboyle@ph.ed.ac.uk>
 | 
				
			||||||
Author: neo <cossu@post.kek.jp>
 | 
					Author: neo <cossu@post.kek.jp>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    This program is free software; you can redistribute it and/or modify
 | 
					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
 | 
					it under the terms of the GNU General Public License as published by
 | 
				
			||||||
    the Free Software Foundation; either version 2 of the License, or
 | 
					the Free Software Foundation; either version 2 of the License, or
 | 
				
			||||||
    (at your option) any later version.
 | 
					(at your option) any later version.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    This program is distributed in the hope that it will be useful,
 | 
					This program is distributed in the hope that it will be useful,
 | 
				
			||||||
    but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
					but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
				
			||||||
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
					MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
				
			||||||
    GNU General Public License for more details.
 | 
					GNU General Public License for more details.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    You should have received a copy of the GNU General Public License along
 | 
					You should have received a copy of the GNU General Public License along
 | 
				
			||||||
    with this program; if not, write to the Free Software Foundation, Inc.,
 | 
					with this program; if not, write to the Free Software Foundation, Inc.,
 | 
				
			||||||
    51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 | 
					51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    See the full license in the file "LICENSE" in the top level distribution directory
 | 
					See the full license in the file "LICENSE" in the top level distribution
 | 
				
			||||||
    *************************************************************************************/
 | 
					directory
 | 
				
			||||||
    /*  END LEGAL */
 | 
					*************************************************************************************/
 | 
				
			||||||
 | 
					/*  END LEGAL */
 | 
				
			||||||
#ifndef QCD_ACTION_BASE
 | 
					#ifndef QCD_ACTION_BASE
 | 
				
			||||||
#define QCD_ACTION_BASE
 | 
					#define QCD_ACTION_BASE
 | 
				
			||||||
namespace Grid {
 | 
					namespace Grid {
 | 
				
			||||||
namespace QCD{
 | 
					namespace QCD {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
template<class GaugeField>
 | 
					template <class GaugeField>
 | 
				
			||||||
class Action {
 | 
					class Action {
 | 
				
			||||||
 | 
					 | 
				
			||||||
 public:
 | 
					 public:
 | 
				
			||||||
  bool is_smeared = false;
 | 
					  bool is_smeared = false;
 | 
				
			||||||
  // Boundary conditions? // Heatbath?
 | 
					  // Boundary conditions? // Heatbath?
 | 
				
			||||||
  virtual void  refresh(const GaugeField &U, GridParallelRNG& pRNG) = 0;// refresh pseudofermions
 | 
					  virtual void refresh(const GaugeField& U,
 | 
				
			||||||
  virtual RealD S    (const GaugeField &U)                        = 0;  // evaluate the action
 | 
					                       GridParallelRNG& pRNG) = 0;  // refresh pseudofermions
 | 
				
			||||||
  virtual void  deriv(const GaugeField &U,GaugeField & dSdU )     = 0;  // evaluate the action derivative
 | 
					  virtual RealD S(const GaugeField& U) = 0;         // evaluate the action
 | 
				
			||||||
  virtual ~Action() {};
 | 
					  virtual void deriv(const GaugeField& U,
 | 
				
			||||||
 | 
					                     GaugeField& dSdU) = 0;  // evaluate the action derivative
 | 
				
			||||||
 | 
					  virtual ~Action(){};
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Indexing of tuple types
 | 
				
			||||||
 | 
					template <class T, class Tuple>
 | 
				
			||||||
 | 
					struct Index;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					template <class T, class... Types>
 | 
				
			||||||
 | 
					struct Index<T, std::tuple<T, Types...>> {
 | 
				
			||||||
 | 
					  static const std::size_t value = 0;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					template <class T, class U, class... Types>
 | 
				
			||||||
 | 
					struct Index<T, std::tuple<U, Types...>> {
 | 
				
			||||||
 | 
					  static const std::size_t value = 1 + Index<T, std::tuple<Types...>>::value;
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Could derive PseudoFermion action with a PF field, FermionField, and a Grid; implement refresh
 | 
					 | 
				
			||||||
/*
 | 
					/*
 | 
				
			||||||
template<class GaugeField, class FermionField>
 | 
					template <class GaugeField>
 | 
				
			||||||
class PseudoFermionAction : public Action<GaugeField> {
 | 
					struct ActionLevel {
 | 
				
			||||||
 public:
 | 
					 public:
 | 
				
			||||||
  FermionField Phi;
 | 
					  typedef Action<GaugeField>*
 | 
				
			||||||
  GridParallelRNG &pRNG;
 | 
					      ActPtr;  // now force the same colours as the rest of the code
 | 
				
			||||||
  GridBase &Grid;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
  PseudoFermionAction(GridBase &_Grid,GridParallelRNG &_pRNG) : Grid(_Grid), Phi(&_Grid), pRNG(_pRNG) {
 | 
					  //Add supported representations here
 | 
				
			||||||
  };
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
  virtual void refresh(const GaugeField &gauge) {
 | 
					 | 
				
			||||||
    gaussian(Phi,pRNG);
 | 
					 | 
				
			||||||
  };
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
};
 | 
					  unsigned int multiplier;
 | 
				
			||||||
*/
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
template<class GaugeField> struct ActionLevel{
 | 
					 | 
				
			||||||
public:
 | 
					 | 
				
			||||||
   
 | 
					 | 
				
			||||||
  typedef Action<GaugeField>*  ActPtr; // now force the same colours as the rest of the code
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  int multiplier;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
  std::vector<ActPtr> actions;
 | 
					  std::vector<ActPtr> actions;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  ActionLevel(int mul = 1) : multiplier(mul) {
 | 
					  ActionLevel(unsigned int mul = 1) : actions(0), multiplier(mul) {
 | 
				
			||||||
    assert (mul > 0);
 | 
					    assert(mul >= 1);
 | 
				
			||||||
  };
 | 
					  };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  void push_back(ActPtr ptr){
 | 
					  void push_back(ActPtr ptr) { actions.push_back(ptr); }
 | 
				
			||||||
    actions.push_back(ptr);
 | 
					};
 | 
				
			||||||
 | 
					*/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					template <class GaugeField, class Repr = NoHirep >
 | 
				
			||||||
 | 
					struct ActionLevel {
 | 
				
			||||||
 | 
					 public:
 | 
				
			||||||
 | 
					  unsigned int multiplier; 
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // Fundamental repr actions separated because of the smearing
 | 
				
			||||||
 | 
					  typedef Action<GaugeField>* ActPtr;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // construct a tuple of vectors of the actions for the corresponding higher
 | 
				
			||||||
 | 
					  // representation fields
 | 
				
			||||||
 | 
					  typedef typename AccessTypes<Action, Repr>::VectorCollection action_collection;
 | 
				
			||||||
 | 
					  action_collection actions_hirep;
 | 
				
			||||||
 | 
					  typedef typename  AccessTypes<Action, Repr>::FieldTypeCollection action_hirep_types;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  std::vector<ActPtr>& actions;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // Temporary conversion between ActionLevel and ActionLevelHirep
 | 
				
			||||||
 | 
					  //ActionLevelHirep(ActionLevel<GaugeField>& AL ):actions(AL.actions), multiplier(AL.multiplier){}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  ActionLevel(unsigned int mul = 1) : actions(std::get<0>(actions_hirep)), multiplier(mul) {
 | 
				
			||||||
 | 
					    // initialize the hirep vectors to zero.
 | 
				
			||||||
 | 
					    //apply(this->resize, actions_hirep, 0); //need a working resize
 | 
				
			||||||
 | 
					    assert(mul >= 1);
 | 
				
			||||||
 | 
					  };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  //void push_back(ActPtr ptr) { actions.push_back(ptr); }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  template < class Field >
 | 
				
			||||||
 | 
					  void push_back(Action<Field>* ptr) {
 | 
				
			||||||
 | 
					    // insert only in the correct vector
 | 
				
			||||||
 | 
					    std::get< Index < Field, action_hirep_types>::value >(actions_hirep).push_back(ptr);
 | 
				
			||||||
 | 
					  };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					 
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  template < class ActPtr>
 | 
				
			||||||
 | 
					  static void resize(ActPtr ap, unsigned int n){
 | 
				
			||||||
 | 
					    ap->resize(n);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  //template <std::size_t I>
 | 
				
			||||||
 | 
					  //auto getRepresentation(Repr& R)->decltype(std::get<I>(R).U)  {return std::get<I>(R).U;}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // Loop on tuple for a callable function
 | 
				
			||||||
 | 
					  template <std::size_t I = 1, typename Callable, typename ...Args>
 | 
				
			||||||
 | 
					  inline typename std::enable_if<I == std::tuple_size<action_collection>::value, void>::type apply(
 | 
				
			||||||
 | 
					      Callable, Repr& R,Args&...) const {}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  template <std::size_t I = 1, typename Callable, typename ...Args>
 | 
				
			||||||
 | 
					  inline typename std::enable_if<I < std::tuple_size<action_collection>::value, void>::type apply(
 | 
				
			||||||
 | 
					      Callable fn, Repr& R, Args&... arguments) const {
 | 
				
			||||||
 | 
					    fn(std::get<I>(actions_hirep), std::get<I>(R.rep), arguments...);
 | 
				
			||||||
 | 
					    apply<I + 1>(fn, R, arguments...);
 | 
				
			||||||
 | 
					  }  
 | 
				
			||||||
 | 
					
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
template<class GaugeField> using ActionSet = std::vector<ActionLevel< GaugeField > >;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					//template <class GaugeField>
 | 
				
			||||||
 | 
					//using ActionSet = std::vector<ActionLevel<GaugeField> >;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
}}
 | 
					template <class GaugeField, class R>
 | 
				
			||||||
 | 
					using ActionSet = std::vector<ActionLevel<GaugeField, R> >;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -111,17 +111,30 @@ typedef SymanzikGaugeAction<ConjugateGimplD>        ConjugateSymanzikGaugeAction
 | 
				
			|||||||
#define FermOp4dVecTemplateInstantiate(A) \
 | 
					#define FermOp4dVecTemplateInstantiate(A) \
 | 
				
			||||||
  template class A<WilsonImplF>;		\
 | 
					  template class A<WilsonImplF>;		\
 | 
				
			||||||
  template class A<WilsonImplD>;		\
 | 
					  template class A<WilsonImplD>;		\
 | 
				
			||||||
 | 
					  template class A<ZWilsonImplF>;		\
 | 
				
			||||||
 | 
					  template class A<ZWilsonImplD>;		\
 | 
				
			||||||
  template class A<GparityWilsonImplF>;		\
 | 
					  template class A<GparityWilsonImplF>;		\
 | 
				
			||||||
  template class A<GparityWilsonImplD>;		
 | 
					  template class A<GparityWilsonImplD>;		
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define AdjointFermOpTemplateInstantiate(A) \
 | 
				
			||||||
 | 
					  template class A<WilsonAdjImplF>; \
 | 
				
			||||||
 | 
					  template class A<WilsonAdjImplD>; 
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define TwoIndexFermOpTemplateInstantiate(A) \
 | 
				
			||||||
 | 
					  template class A<WilsonTwoIndexSymmetricImplF>; \
 | 
				
			||||||
 | 
					  template class A<WilsonTwoIndexSymmetricImplD>; 
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define FermOp5dVecTemplateInstantiate(A) \
 | 
					#define FermOp5dVecTemplateInstantiate(A) \
 | 
				
			||||||
  template class A<DomainWallVec5dImplF>;	\
 | 
					  template class A<DomainWallVec5dImplF>;	\
 | 
				
			||||||
  template class A<DomainWallVec5dImplD>;	
 | 
					  template class A<DomainWallVec5dImplD>;	\
 | 
				
			||||||
 | 
					  template class A<ZDomainWallVec5dImplF>;	\
 | 
				
			||||||
 | 
					  template class A<ZDomainWallVec5dImplD>;	
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define FermOpTemplateInstantiate(A) \
 | 
					#define FermOpTemplateInstantiate(A) \
 | 
				
			||||||
 FermOp4dVecTemplateInstantiate(A) \
 | 
					 FermOp4dVecTemplateInstantiate(A) \
 | 
				
			||||||
 FermOp5dVecTemplateInstantiate(A) 
 | 
					 FermOp5dVecTemplateInstantiate(A) 
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define GparityFermOpTemplateInstantiate(A) 
 | 
					#define GparityFermOpTemplateInstantiate(A) 
 | 
				
			||||||
 | 
					
 | 
				
			||||||
////////////////////////////////////////////
 | 
					////////////////////////////////////////////
 | 
				
			||||||
@@ -138,6 +151,7 @@ typedef SymanzikGaugeAction<ConjugateGimplD>        ConjugateSymanzikGaugeAction
 | 
				
			|||||||
#include <Grid/qcd/action/fermion/DomainWallFermion.h>
 | 
					#include <Grid/qcd/action/fermion/DomainWallFermion.h>
 | 
				
			||||||
#include <Grid/qcd/action/fermion/DomainWallFermion.h>
 | 
					#include <Grid/qcd/action/fermion/DomainWallFermion.h>
 | 
				
			||||||
#include <Grid/qcd/action/fermion/MobiusFermion.h>
 | 
					#include <Grid/qcd/action/fermion/MobiusFermion.h>
 | 
				
			||||||
 | 
					#include <Grid/qcd/action/fermion/ZMobiusFermion.h>
 | 
				
			||||||
#include <Grid/qcd/action/fermion/ScaledShamirFermion.h>
 | 
					#include <Grid/qcd/action/fermion/ScaledShamirFermion.h>
 | 
				
			||||||
#include <Grid/qcd/action/fermion/MobiusZolotarevFermion.h>
 | 
					#include <Grid/qcd/action/fermion/MobiusZolotarevFermion.h>
 | 
				
			||||||
#include <Grid/qcd/action/fermion/ShamirZolotarevFermion.h>
 | 
					#include <Grid/qcd/action/fermion/ShamirZolotarevFermion.h>
 | 
				
			||||||
@@ -166,6 +180,14 @@ typedef WilsonFermion<WilsonImplR> WilsonFermionR;
 | 
				
			|||||||
typedef WilsonFermion<WilsonImplF> WilsonFermionF;
 | 
					typedef WilsonFermion<WilsonImplF> WilsonFermionF;
 | 
				
			||||||
typedef WilsonFermion<WilsonImplD> WilsonFermionD;
 | 
					typedef WilsonFermion<WilsonImplD> WilsonFermionD;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					typedef WilsonFermion<WilsonAdjImplR> WilsonAdjFermionR;
 | 
				
			||||||
 | 
					typedef WilsonFermion<WilsonAdjImplF> WilsonAdjFermionF;
 | 
				
			||||||
 | 
					typedef WilsonFermion<WilsonAdjImplD> WilsonAdjFermionD;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					typedef WilsonFermion<WilsonTwoIndexSymmetricImplR> WilsonTwoIndexSymmetricFermionR;
 | 
				
			||||||
 | 
					typedef WilsonFermion<WilsonTwoIndexSymmetricImplF> WilsonTwoIndexSymmetricFermionF;
 | 
				
			||||||
 | 
					typedef WilsonFermion<WilsonTwoIndexSymmetricImplD> WilsonTwoIndexSymmetricFermionD;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
typedef WilsonTMFermion<WilsonImplR> WilsonTMFermionR;
 | 
					typedef WilsonTMFermion<WilsonImplR> WilsonTMFermionR;
 | 
				
			||||||
typedef WilsonTMFermion<WilsonImplF> WilsonTMFermionF;
 | 
					typedef WilsonTMFermion<WilsonImplF> WilsonTMFermionF;
 | 
				
			||||||
typedef WilsonTMFermion<WilsonImplD> WilsonTMFermionD;
 | 
					typedef WilsonTMFermion<WilsonImplD> WilsonTMFermionD;
 | 
				
			||||||
@@ -176,6 +198,11 @@ typedef DomainWallFermion<WilsonImplD> DomainWallFermionD;
 | 
				
			|||||||
typedef MobiusFermion<WilsonImplR> MobiusFermionR;
 | 
					typedef MobiusFermion<WilsonImplR> MobiusFermionR;
 | 
				
			||||||
typedef MobiusFermion<WilsonImplF> MobiusFermionF;
 | 
					typedef MobiusFermion<WilsonImplF> MobiusFermionF;
 | 
				
			||||||
typedef MobiusFermion<WilsonImplD> MobiusFermionD;
 | 
					typedef MobiusFermion<WilsonImplD> MobiusFermionD;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					typedef ZMobiusFermion<ZWilsonImplR> ZMobiusFermionR;
 | 
				
			||||||
 | 
					typedef ZMobiusFermion<ZWilsonImplF> ZMobiusFermionF;
 | 
				
			||||||
 | 
					typedef ZMobiusFermion<ZWilsonImplD> ZMobiusFermionD;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
typedef ScaledShamirFermion<WilsonImplR> ScaledShamirFermionR;
 | 
					typedef ScaledShamirFermion<WilsonImplR> ScaledShamirFermionR;
 | 
				
			||||||
typedef ScaledShamirFermion<WilsonImplF> ScaledShamirFermionF;
 | 
					typedef ScaledShamirFermion<WilsonImplF> ScaledShamirFermionF;
 | 
				
			||||||
typedef ScaledShamirFermion<WilsonImplD> ScaledShamirFermionD;
 | 
					typedef ScaledShamirFermion<WilsonImplD> ScaledShamirFermionD;
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -54,18 +54,18 @@ template<class Impl>
 | 
				
			|||||||
void CayleyFermion5D<Impl>::M5D   (const FermionField &psi, FermionField &chi)
 | 
					void CayleyFermion5D<Impl>::M5D   (const FermionField &psi, FermionField &chi)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
  int Ls=this->Ls;
 | 
					  int Ls=this->Ls;
 | 
				
			||||||
  std::vector<RealD> diag (Ls,1.0);
 | 
					  std::vector<Coeff_t> diag (Ls,1.0);
 | 
				
			||||||
  std::vector<RealD> upper(Ls,-1.0); upper[Ls-1]=mass;
 | 
					  std::vector<Coeff_t> upper(Ls,-1.0); upper[Ls-1]=mass;
 | 
				
			||||||
  std::vector<RealD> lower(Ls,-1.0); lower[0]   =mass;
 | 
					  std::vector<Coeff_t> lower(Ls,-1.0); lower[0]   =mass;
 | 
				
			||||||
  M5D(psi,chi,chi,lower,diag,upper);
 | 
					  M5D(psi,chi,chi,lower,diag,upper);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
template<class Impl>
 | 
					template<class Impl>
 | 
				
			||||||
void CayleyFermion5D<Impl>::Meooe5D    (const FermionField &psi, FermionField &Din)
 | 
					void CayleyFermion5D<Impl>::Meooe5D    (const FermionField &psi, FermionField &Din)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
  int Ls=this->Ls;
 | 
					  int Ls=this->Ls;
 | 
				
			||||||
  std::vector<RealD> diag = bs;
 | 
					  std::vector<Coeff_t> diag = bs;
 | 
				
			||||||
  std::vector<RealD> upper= cs;
 | 
					  std::vector<Coeff_t> upper= cs;
 | 
				
			||||||
  std::vector<RealD> lower= cs; 
 | 
					  std::vector<Coeff_t> lower= cs; 
 | 
				
			||||||
  upper[Ls-1]=-mass*upper[Ls-1];
 | 
					  upper[Ls-1]=-mass*upper[Ls-1];
 | 
				
			||||||
  lower[0]   =-mass*lower[0];
 | 
					  lower[0]   =-mass*lower[0];
 | 
				
			||||||
  M5D(psi,psi,Din,lower,diag,upper);
 | 
					  M5D(psi,psi,Din,lower,diag,upper);
 | 
				
			||||||
@@ -73,9 +73,9 @@ void CayleyFermion5D<Impl>::Meooe5D    (const FermionField &psi, FermionField &D
 | 
				
			|||||||
template<class Impl> void CayleyFermion5D<Impl>::Meo5D     (const FermionField &psi, FermionField &chi)
 | 
					template<class Impl> void CayleyFermion5D<Impl>::Meo5D     (const FermionField &psi, FermionField &chi)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
  int Ls=this->Ls;
 | 
					  int Ls=this->Ls;
 | 
				
			||||||
  std::vector<RealD> diag = beo;
 | 
					  std::vector<Coeff_t> diag = beo;
 | 
				
			||||||
  std::vector<RealD> upper(Ls);
 | 
					  std::vector<Coeff_t> upper(Ls);
 | 
				
			||||||
  std::vector<RealD> lower(Ls);
 | 
					  std::vector<Coeff_t> lower(Ls);
 | 
				
			||||||
  for(int i=0;i<Ls;i++) {
 | 
					  for(int i=0;i<Ls;i++) {
 | 
				
			||||||
    upper[i]=-ceo[i];
 | 
					    upper[i]=-ceo[i];
 | 
				
			||||||
    lower[i]=-ceo[i];
 | 
					    lower[i]=-ceo[i];
 | 
				
			||||||
@@ -88,9 +88,9 @@ template<class Impl>
 | 
				
			|||||||
void CayleyFermion5D<Impl>::Mooee       (const FermionField &psi, FermionField &chi)
 | 
					void CayleyFermion5D<Impl>::Mooee       (const FermionField &psi, FermionField &chi)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
  int Ls=this->Ls;
 | 
					  int Ls=this->Ls;
 | 
				
			||||||
  std::vector<RealD> diag = bee;
 | 
					  std::vector<Coeff_t> diag = bee;
 | 
				
			||||||
  std::vector<RealD> upper(Ls);
 | 
					  std::vector<Coeff_t> upper(Ls);
 | 
				
			||||||
  std::vector<RealD> lower(Ls);
 | 
					  std::vector<Coeff_t> lower(Ls);
 | 
				
			||||||
  for(int i=0;i<Ls;i++) {
 | 
					  for(int i=0;i<Ls;i++) {
 | 
				
			||||||
    upper[i]=-cee[i];
 | 
					    upper[i]=-cee[i];
 | 
				
			||||||
    lower[i]=-cee[i];
 | 
					    lower[i]=-cee[i];
 | 
				
			||||||
@@ -104,9 +104,9 @@ template<class Impl>
 | 
				
			|||||||
void CayleyFermion5D<Impl>::MooeeDag    (const FermionField &psi, FermionField &chi)
 | 
					void CayleyFermion5D<Impl>::MooeeDag    (const FermionField &psi, FermionField &chi)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
  int Ls=this->Ls;
 | 
					  int Ls=this->Ls;
 | 
				
			||||||
  std::vector<RealD> diag = bee;
 | 
					  std::vector<Coeff_t> diag = bee;
 | 
				
			||||||
  std::vector<RealD> upper(Ls);
 | 
					  std::vector<Coeff_t> upper(Ls);
 | 
				
			||||||
  std::vector<RealD> lower(Ls);
 | 
					  std::vector<Coeff_t> lower(Ls);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  for (int s=0;s<Ls;s++){
 | 
					  for (int s=0;s<Ls;s++){
 | 
				
			||||||
    // Assemble the 5d matrix
 | 
					    // Assemble the 5d matrix
 | 
				
			||||||
@@ -129,9 +129,9 @@ template<class Impl>
 | 
				
			|||||||
void CayleyFermion5D<Impl>::M5Ddag (const FermionField &psi, FermionField &chi)
 | 
					void CayleyFermion5D<Impl>::M5Ddag (const FermionField &psi, FermionField &chi)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
  int Ls=this->Ls;
 | 
					  int Ls=this->Ls;
 | 
				
			||||||
  std::vector<RealD> diag(Ls,1.0);
 | 
					  std::vector<Coeff_t> diag(Ls,1.0);
 | 
				
			||||||
  std::vector<RealD> upper(Ls,-1.0);
 | 
					  std::vector<Coeff_t> upper(Ls,-1.0);
 | 
				
			||||||
  std::vector<RealD> lower(Ls,-1.0);
 | 
					  std::vector<Coeff_t> lower(Ls,-1.0);
 | 
				
			||||||
  upper[Ls-1]=-mass*upper[Ls-1];
 | 
					  upper[Ls-1]=-mass*upper[Ls-1];
 | 
				
			||||||
  lower[0]   =-mass*lower[0];
 | 
					  lower[0]   =-mass*lower[0];
 | 
				
			||||||
  M5Ddag(psi,chi,chi,lower,diag,upper);
 | 
					  M5Ddag(psi,chi,chi,lower,diag,upper);
 | 
				
			||||||
@@ -141,9 +141,9 @@ template<class Impl>
 | 
				
			|||||||
void CayleyFermion5D<Impl>::MeooeDag5D    (const FermionField &psi, FermionField &Din)
 | 
					void CayleyFermion5D<Impl>::MeooeDag5D    (const FermionField &psi, FermionField &Din)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
  int Ls=this->Ls;
 | 
					  int Ls=this->Ls;
 | 
				
			||||||
  std::vector<RealD> diag =bs;
 | 
					  std::vector<Coeff_t> diag =bs;
 | 
				
			||||||
  std::vector<RealD> upper=cs;
 | 
					  std::vector<Coeff_t> upper=cs;
 | 
				
			||||||
  std::vector<RealD> lower=cs;
 | 
					  std::vector<Coeff_t> lower=cs;
 | 
				
			||||||
  upper[Ls-1]=-mass*upper[Ls-1];
 | 
					  upper[Ls-1]=-mass*upper[Ls-1];
 | 
				
			||||||
  lower[0]   =-mass*lower[0];
 | 
					  lower[0]   =-mass*lower[0];
 | 
				
			||||||
  M5Ddag(psi,psi,Din,lower,diag,upper);
 | 
					  M5Ddag(psi,psi,Din,lower,diag,upper);
 | 
				
			||||||
@@ -273,11 +273,21 @@ void CayleyFermion5D<Impl>::MeoDeriv(GaugeField &mat,const FermionField &U,const
 | 
				
			|||||||
template<class Impl>
 | 
					template<class Impl>
 | 
				
			||||||
void CayleyFermion5D<Impl>::SetCoefficientsTanh(Approx::zolotarev_data *zdata,RealD b,RealD c)
 | 
					void CayleyFermion5D<Impl>::SetCoefficientsTanh(Approx::zolotarev_data *zdata,RealD b,RealD c)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
  SetCoefficientsZolotarev(1.0,zdata,b,c);
 | 
					  std::vector<Coeff_t> gamma(this->Ls);
 | 
				
			||||||
 | 
					  for(int s=0;s<this->Ls;s++) gamma[s] = zdata->gamma[s];
 | 
				
			||||||
 | 
					  SetCoefficientsInternal(1.0,gamma,b,c);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
//Zolo
 | 
					//Zolo
 | 
				
			||||||
template<class Impl>
 | 
					template<class Impl>
 | 
				
			||||||
void CayleyFermion5D<Impl>::SetCoefficientsZolotarev(RealD zolo_hi,Approx::zolotarev_data *zdata,RealD b,RealD c)
 | 
					void CayleyFermion5D<Impl>::SetCoefficientsZolotarev(RealD zolo_hi,Approx::zolotarev_data *zdata,RealD b,RealD c)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					  std::vector<Coeff_t> gamma(this->Ls);
 | 
				
			||||||
 | 
					  for(int s=0;s<this->Ls;s++) gamma[s] = zdata->gamma[s];
 | 
				
			||||||
 | 
					  SetCoefficientsInternal(zolo_hi,gamma,b,c);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					//Zolo
 | 
				
			||||||
 | 
					template<class Impl>
 | 
				
			||||||
 | 
					void CayleyFermion5D<Impl>::SetCoefficientsInternal(RealD zolo_hi,std::vector<Coeff_t> & gamma,RealD b,RealD c)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
  int Ls=this->Ls;
 | 
					  int Ls=this->Ls;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -315,7 +325,7 @@ void CayleyFermion5D<Impl>::SetCoefficientsZolotarev(RealD zolo_hi,Approx::zolot
 | 
				
			|||||||
  double bmc = b-c;
 | 
					  double bmc = b-c;
 | 
				
			||||||
  for(int i=0; i < Ls; i++){
 | 
					  for(int i=0; i < Ls; i++){
 | 
				
			||||||
    as[i] = 1.0;
 | 
					    as[i] = 1.0;
 | 
				
			||||||
    omega[i] = ((double)zdata->gamma[i])*zolo_hi; //NB reciprocal relative to Chroma NEF code
 | 
					    omega[i] = gamma[i]*zolo_hi; //NB reciprocal relative to Chroma NEF code
 | 
				
			||||||
    bs[i] = 0.5*(bpc/omega[i] + bmc);
 | 
					    bs[i] = 0.5*(bpc/omega[i] + bmc);
 | 
				
			||||||
    cs[i] = 0.5*(bpc/omega[i] - bmc);
 | 
					    cs[i] = 0.5*(bpc/omega[i] - bmc);
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
@@ -377,7 +387,7 @@ void CayleyFermion5D<Impl>::SetCoefficientsZolotarev(RealD zolo_hi,Approx::zolot
 | 
				
			|||||||
  }
 | 
					  }
 | 
				
			||||||
	
 | 
						
 | 
				
			||||||
  { 
 | 
					  { 
 | 
				
			||||||
    double delta_d=mass*cee[Ls-1];
 | 
					    Coeff_t delta_d=mass*cee[Ls-1];
 | 
				
			||||||
    for(int j=0;j<Ls-1;j++) delta_d *= cee[j]/bee[j];
 | 
					    for(int j=0;j<Ls-1;j++) delta_d *= cee[j]/bee[j];
 | 
				
			||||||
    dee[Ls-1] += delta_d;
 | 
					    dee[Ls-1] += delta_d;
 | 
				
			||||||
  }  
 | 
					  }  
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -62,16 +62,16 @@ namespace Grid {
 | 
				
			|||||||
      void M5D(const FermionField &psi,
 | 
					      void M5D(const FermionField &psi,
 | 
				
			||||||
	       const FermionField &phi, 
 | 
						       const FermionField &phi, 
 | 
				
			||||||
	       FermionField &chi,
 | 
						       FermionField &chi,
 | 
				
			||||||
	       std::vector<RealD> &lower,
 | 
						       std::vector<Coeff_t> &lower,
 | 
				
			||||||
	       std::vector<RealD> &diag,
 | 
						       std::vector<Coeff_t> &diag,
 | 
				
			||||||
	       std::vector<RealD> &upper);
 | 
						       std::vector<Coeff_t> &upper);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      void M5Ddag(const FermionField &psi,
 | 
					      void M5Ddag(const FermionField &psi,
 | 
				
			||||||
		  const FermionField &phi, 
 | 
							  const FermionField &phi, 
 | 
				
			||||||
		  FermionField &chi,
 | 
							  FermionField &chi,
 | 
				
			||||||
		  std::vector<RealD> &lower,
 | 
							  std::vector<Coeff_t> &lower,
 | 
				
			||||||
		  std::vector<RealD> &diag,
 | 
							  std::vector<Coeff_t> &diag,
 | 
				
			||||||
		  std::vector<RealD> &upper);
 | 
							  std::vector<Coeff_t> &upper);
 | 
				
			||||||
      void MooeeInternal(const FermionField &in, FermionField &out,int dag,int inv);
 | 
					      void MooeeInternal(const FermionField &in, FermionField &out,int dag,int inv);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      virtual void   Instantiatable(void)=0;
 | 
					      virtual void   Instantiatable(void)=0;
 | 
				
			||||||
@@ -91,23 +91,23 @@ namespace Grid {
 | 
				
			|||||||
      RealD mass;
 | 
					      RealD mass;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      // Cayley form Moebius (tanh and zolotarev)
 | 
					      // Cayley form Moebius (tanh and zolotarev)
 | 
				
			||||||
      std::vector<RealD> omega; 
 | 
					      std::vector<Coeff_t> omega; 
 | 
				
			||||||
      std::vector<RealD> bs;    // S dependent coeffs
 | 
					      std::vector<Coeff_t> bs;    // S dependent coeffs
 | 
				
			||||||
      std::vector<RealD> cs;    
 | 
					      std::vector<Coeff_t> cs;    
 | 
				
			||||||
      std::vector<RealD> as;    
 | 
					      std::vector<Coeff_t> as;    
 | 
				
			||||||
      // For preconditioning Cayley form
 | 
					      // For preconditioning Cayley form
 | 
				
			||||||
      std::vector<RealD> bee;    
 | 
					      std::vector<Coeff_t> bee;    
 | 
				
			||||||
      std::vector<RealD> cee;    
 | 
					      std::vector<Coeff_t> cee;    
 | 
				
			||||||
      std::vector<RealD> aee;    
 | 
					      std::vector<Coeff_t> aee;    
 | 
				
			||||||
      std::vector<RealD> beo;    
 | 
					      std::vector<Coeff_t> beo;    
 | 
				
			||||||
      std::vector<RealD> ceo;    
 | 
					      std::vector<Coeff_t> ceo;    
 | 
				
			||||||
      std::vector<RealD> aeo;    
 | 
					      std::vector<Coeff_t> aeo;    
 | 
				
			||||||
      // LDU factorisation of the eeoo matrix
 | 
					      // LDU factorisation of the eeoo matrix
 | 
				
			||||||
      std::vector<RealD> lee;    
 | 
					      std::vector<Coeff_t> lee;    
 | 
				
			||||||
      std::vector<RealD> leem;    
 | 
					      std::vector<Coeff_t> leem;    
 | 
				
			||||||
      std::vector<RealD> uee;    
 | 
					      std::vector<Coeff_t> uee;    
 | 
				
			||||||
      std::vector<RealD> ueem;    
 | 
					      std::vector<Coeff_t> ueem;    
 | 
				
			||||||
      std::vector<RealD> dee;    
 | 
					      std::vector<Coeff_t> dee;    
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      // Constructors
 | 
					      // Constructors
 | 
				
			||||||
      CayleyFermion5D(GaugeField &_Umu,
 | 
					      CayleyFermion5D(GaugeField &_Umu,
 | 
				
			||||||
@@ -117,20 +117,19 @@ namespace Grid {
 | 
				
			|||||||
		      GridRedBlackCartesian &FourDimRedBlackGrid,
 | 
							      GridRedBlackCartesian &FourDimRedBlackGrid,
 | 
				
			||||||
		      RealD _mass,RealD _M5,const ImplParams &p= ImplParams());
 | 
							      RealD _mass,RealD _M5,const ImplParams &p= ImplParams());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    protected:
 | 
					    protected:
 | 
				
			||||||
      void SetCoefficientsZolotarev(RealD zolohi,Approx::zolotarev_data *zdata,RealD b,RealD c);
 | 
					      void SetCoefficientsZolotarev(RealD zolohi,Approx::zolotarev_data *zdata,RealD b,RealD c);
 | 
				
			||||||
      void SetCoefficientsTanh(Approx::zolotarev_data *zdata,RealD b,RealD c);
 | 
					      void SetCoefficientsTanh(Approx::zolotarev_data *zdata,RealD b,RealD c);
 | 
				
			||||||
 | 
					      void SetCoefficientsInternal(RealD zolo_hi,std::vector<Coeff_t> & gamma,RealD b,RealD c);
 | 
				
			||||||
    };
 | 
					    };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
#define INSTANTIATE_DPERP(A)\
 | 
					#define INSTANTIATE_DPERP(A)\
 | 
				
			||||||
template void CayleyFermion5D< A >::M5D(const FermionField &psi,const FermionField &phi,FermionField &chi,\
 | 
					template void CayleyFermion5D< A >::M5D(const FermionField &psi,const FermionField &phi,FermionField &chi,\
 | 
				
			||||||
					std::vector<RealD> &lower,std::vector<RealD> &diag,std::vector<RealD> &upper); \
 | 
										std::vector<Coeff_t> &lower,std::vector<Coeff_t> &diag,std::vector<Coeff_t> &upper); \
 | 
				
			||||||
template void CayleyFermion5D< A >::M5Ddag(const FermionField &psi,const FermionField &phi,FermionField &chi,\
 | 
					template void CayleyFermion5D< A >::M5Ddag(const FermionField &psi,const FermionField &phi,FermionField &chi,\
 | 
				
			||||||
					   std::vector<RealD> &lower,std::vector<RealD> &diag,std::vector<RealD> &upper); \
 | 
										   std::vector<Coeff_t> &lower,std::vector<Coeff_t> &diag,std::vector<Coeff_t> &upper); \
 | 
				
			||||||
template void CayleyFermion5D< A >::MooeeInv    (const FermionField &psi, FermionField &chi); \
 | 
					template void CayleyFermion5D< A >::MooeeInv    (const FermionField &psi, FermionField &chi); \
 | 
				
			||||||
template void CayleyFermion5D< A >::MooeeInvDag (const FermionField &psi, FermionField &chi);
 | 
					template void CayleyFermion5D< A >::MooeeInvDag (const FermionField &psi, FermionField &chi);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -43,9 +43,9 @@ template<class Impl>
 | 
				
			|||||||
void CayleyFermion5D<Impl>::M5D(const FermionField &psi,
 | 
					void CayleyFermion5D<Impl>::M5D(const FermionField &psi,
 | 
				
			||||||
				const FermionField &phi, 
 | 
									const FermionField &phi, 
 | 
				
			||||||
				FermionField &chi,
 | 
									FermionField &chi,
 | 
				
			||||||
				std::vector<RealD> &lower,
 | 
									std::vector<Coeff_t> &lower,
 | 
				
			||||||
				std::vector<RealD> &diag,
 | 
									std::vector<Coeff_t> &diag,
 | 
				
			||||||
				std::vector<RealD> &upper)
 | 
									std::vector<Coeff_t> &upper)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
  int Ls =this->Ls;
 | 
					  int Ls =this->Ls;
 | 
				
			||||||
  GridBase *grid=psi._grid;
 | 
					  GridBase *grid=psi._grid;
 | 
				
			||||||
@@ -82,9 +82,9 @@ template<class Impl>
 | 
				
			|||||||
void CayleyFermion5D<Impl>::M5Ddag(const FermionField &psi,
 | 
					void CayleyFermion5D<Impl>::M5Ddag(const FermionField &psi,
 | 
				
			||||||
				   const FermionField &phi, 
 | 
									   const FermionField &phi, 
 | 
				
			||||||
				   FermionField &chi,
 | 
									   FermionField &chi,
 | 
				
			||||||
				   std::vector<RealD> &lower,
 | 
									   std::vector<Coeff_t> &lower,
 | 
				
			||||||
				   std::vector<RealD> &diag,
 | 
									   std::vector<Coeff_t> &diag,
 | 
				
			||||||
				   std::vector<RealD> &upper)
 | 
									   std::vector<Coeff_t> &upper)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
  int Ls =this->Ls;
 | 
					  int Ls =this->Ls;
 | 
				
			||||||
  GridBase *grid=psi._grid;
 | 
					  GridBase *grid=psi._grid;
 | 
				
			||||||
@@ -204,6 +204,8 @@ PARALLEL_FOR_LOOP
 | 
				
			|||||||
  INSTANTIATE_DPERP(WilsonImplD);
 | 
					  INSTANTIATE_DPERP(WilsonImplD);
 | 
				
			||||||
  INSTANTIATE_DPERP(GparityWilsonImplF);
 | 
					  INSTANTIATE_DPERP(GparityWilsonImplF);
 | 
				
			||||||
  INSTANTIATE_DPERP(GparityWilsonImplD);
 | 
					  INSTANTIATE_DPERP(GparityWilsonImplD);
 | 
				
			||||||
 | 
					  INSTANTIATE_DPERP(ZWilsonImplF);
 | 
				
			||||||
 | 
					  INSTANTIATE_DPERP(ZWilsonImplD);
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
}}
 | 
					}}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -43,9 +43,9 @@ template<class Impl>
 | 
				
			|||||||
void CayleyFermion5D<Impl>::M5D(const FermionField &psi,
 | 
					void CayleyFermion5D<Impl>::M5D(const FermionField &psi,
 | 
				
			||||||
				const FermionField &phi, 
 | 
									const FermionField &phi, 
 | 
				
			||||||
				FermionField &chi,
 | 
									FermionField &chi,
 | 
				
			||||||
				std::vector<RealD> &lower,
 | 
									std::vector<Coeff_t> &lower,
 | 
				
			||||||
				std::vector<RealD> &diag,
 | 
									std::vector<Coeff_t> &diag,
 | 
				
			||||||
				std::vector<RealD> &upper)
 | 
									std::vector<Coeff_t> &upper)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
  int Ls=this->Ls;
 | 
					  int Ls=this->Ls;
 | 
				
			||||||
  for(int s=0;s<Ls;s++){
 | 
					  for(int s=0;s<Ls;s++){
 | 
				
			||||||
@@ -65,9 +65,9 @@ template<class Impl>
 | 
				
			|||||||
void CayleyFermion5D<Impl>::M5Ddag(const FermionField &psi,
 | 
					void CayleyFermion5D<Impl>::M5Ddag(const FermionField &psi,
 | 
				
			||||||
				   const FermionField &phi, 
 | 
									   const FermionField &phi, 
 | 
				
			||||||
				   FermionField &chi,
 | 
									   FermionField &chi,
 | 
				
			||||||
				   std::vector<RealD> &lower,
 | 
									   std::vector<Coeff_t> &lower,
 | 
				
			||||||
				   std::vector<RealD> &diag,
 | 
									   std::vector<Coeff_t> &diag,
 | 
				
			||||||
				   std::vector<RealD> &upper)
 | 
									   std::vector<Coeff_t> &upper)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
  int Ls=this->Ls;
 | 
					  int Ls=this->Ls;
 | 
				
			||||||
  for(int s=0;s<Ls;s++){
 | 
					  for(int s=0;s<Ls;s++){
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -53,9 +53,9 @@ template<class Impl>
 | 
				
			|||||||
void CayleyFermion5D<Impl>::M5D(const FermionField &psi,
 | 
					void CayleyFermion5D<Impl>::M5D(const FermionField &psi,
 | 
				
			||||||
				const FermionField &phi, 
 | 
									const FermionField &phi, 
 | 
				
			||||||
				FermionField &chi,
 | 
									FermionField &chi,
 | 
				
			||||||
				std::vector<RealD> &lower,
 | 
									std::vector<Coeff_t> &lower,
 | 
				
			||||||
				std::vector<RealD> &diag,
 | 
									std::vector<Coeff_t> &diag,
 | 
				
			||||||
				std::vector<RealD> &upper)
 | 
									std::vector<Coeff_t> &upper)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
  GridBase *grid=psi._grid;
 | 
					  GridBase *grid=psi._grid;
 | 
				
			||||||
  int Ls   = this->Ls;
 | 
					  int Ls   = this->Ls;
 | 
				
			||||||
@@ -121,9 +121,9 @@ template<class Impl>
 | 
				
			|||||||
void CayleyFermion5D<Impl>::M5Ddag(const FermionField &psi,
 | 
					void CayleyFermion5D<Impl>::M5Ddag(const FermionField &psi,
 | 
				
			||||||
				   const FermionField &phi, 
 | 
									   const FermionField &phi, 
 | 
				
			||||||
				   FermionField &chi,
 | 
									   FermionField &chi,
 | 
				
			||||||
				   std::vector<RealD> &lower,
 | 
									   std::vector<Coeff_t> &lower,
 | 
				
			||||||
				   std::vector<RealD> &diag,
 | 
									   std::vector<Coeff_t> &diag,
 | 
				
			||||||
				   std::vector<RealD> &upper)
 | 
									   std::vector<Coeff_t> &upper)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
  GridBase *grid=psi._grid;
 | 
					  GridBase *grid=psi._grid;
 | 
				
			||||||
  int Ls   = this->Ls;
 | 
					  int Ls   = this->Ls;
 | 
				
			||||||
@@ -194,8 +194,8 @@ void CayleyFermion5D<Impl>::MooeeInternal(const FermionField &psi, FermionField
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
  chi.checkerboard=psi.checkerboard;
 | 
					  chi.checkerboard=psi.checkerboard;
 | 
				
			||||||
  
 | 
					  
 | 
				
			||||||
  Eigen::MatrixXd Pplus  = Eigen::MatrixXd::Zero(Ls,Ls);
 | 
					  Eigen::MatrixXcd Pplus  = Eigen::MatrixXcd::Zero(Ls,Ls);
 | 
				
			||||||
  Eigen::MatrixXd Pminus = Eigen::MatrixXd::Zero(Ls,Ls);
 | 
					  Eigen::MatrixXcd Pminus = Eigen::MatrixXcd::Zero(Ls,Ls);
 | 
				
			||||||
  
 | 
					  
 | 
				
			||||||
  for(int s=0;s<Ls;s++){
 | 
					  for(int s=0;s<Ls;s++){
 | 
				
			||||||
    Pplus(s,s) = bee[s];
 | 
					    Pplus(s,s) = bee[s];
 | 
				
			||||||
@@ -212,8 +212,8 @@ void CayleyFermion5D<Impl>::MooeeInternal(const FermionField &psi, FermionField
 | 
				
			|||||||
  Pplus (0,Ls-1) = mass*cee[0];
 | 
					  Pplus (0,Ls-1) = mass*cee[0];
 | 
				
			||||||
  Pminus(Ls-1,0) = mass*cee[Ls-1];
 | 
					  Pminus(Ls-1,0) = mass*cee[Ls-1];
 | 
				
			||||||
  
 | 
					  
 | 
				
			||||||
  Eigen::MatrixXd PplusMat ;
 | 
					  Eigen::MatrixXcd PplusMat ;
 | 
				
			||||||
  Eigen::MatrixXd PminusMat;
 | 
					  Eigen::MatrixXcd PminusMat;
 | 
				
			||||||
  
 | 
					  
 | 
				
			||||||
  if ( inv ) {
 | 
					  if ( inv ) {
 | 
				
			||||||
    PplusMat =Pplus.inverse();
 | 
					    PplusMat =Pplus.inverse();
 | 
				
			||||||
@@ -298,8 +298,12 @@ PARALLEL_FOR_LOOP
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
INSTANTIATE_DPERP(DomainWallVec5dImplD);
 | 
					INSTANTIATE_DPERP(DomainWallVec5dImplD);
 | 
				
			||||||
INSTANTIATE_DPERP(DomainWallVec5dImplF);
 | 
					INSTANTIATE_DPERP(DomainWallVec5dImplF);
 | 
				
			||||||
 | 
					INSTANTIATE_DPERP(ZDomainWallVec5dImplD);
 | 
				
			||||||
 | 
					INSTANTIATE_DPERP(ZDomainWallVec5dImplF);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
template void CayleyFermion5D<DomainWallVec5dImplF>::MooeeInternal(const FermionField &psi, FermionField &chi,int dag, int inv);
 | 
					template void CayleyFermion5D<DomainWallVec5dImplF>::MooeeInternal(const FermionField &psi, FermionField &chi,int dag, int inv);
 | 
				
			||||||
template void CayleyFermion5D<DomainWallVec5dImplD>::MooeeInternal(const FermionField &psi, FermionField &chi,int dag, int inv);
 | 
					template void CayleyFermion5D<DomainWallVec5dImplD>::MooeeInternal(const FermionField &psi, FermionField &chi,int dag, int inv);
 | 
				
			||||||
 | 
					template void CayleyFermion5D<ZDomainWallVec5dImplF>::MooeeInternal(const FermionField &psi, FermionField &chi,int dag, int inv);
 | 
				
			||||||
 | 
					template void CayleyFermion5D<ZDomainWallVec5dImplD>::MooeeInternal(const FermionField &psi, FermionField &chi,int dag, int inv);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
}}
 | 
					}}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,35 +1,36 @@
 | 
				
			|||||||
    /*************************************************************************************
 | 
					/*************************************************************************************
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    Grid physics library, www.github.com/paboyle/Grid 
 | 
					Grid physics library, www.github.com/paboyle/Grid
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    Source file: ./lib/qcd/action/fermion/FermionOperatorImpl.h
 | 
					Source file: ./lib/qcd/action/fermion/FermionOperatorImpl.h
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    Copyright (C) 2015
 | 
					Copyright (C) 2015
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Author: Peter Boyle <pabobyle@ph.ed.ac.uk>
 | 
					Author: Peter Boyle <pabobyle@ph.ed.ac.uk>
 | 
				
			||||||
Author: Peter Boyle <paboyle@ph.ed.ac.uk>
 | 
					Author: Peter Boyle <paboyle@ph.ed.ac.uk>
 | 
				
			||||||
Author: Peter Boyle <peterboyle@Peters-MacBook-Pro-2.local>
 | 
					Author: Peter Boyle <peterboyle@Peters-MacBook-Pro-2.local>
 | 
				
			||||||
Author: paboyle <paboyle@ph.ed.ac.uk>
 | 
					Author: paboyle <paboyle@ph.ed.ac.uk>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    This program is free software; you can redistribute it and/or modify
 | 
					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
 | 
					it under the terms of the GNU General Public License as published by
 | 
				
			||||||
    the Free Software Foundation; either version 2 of the License, or
 | 
					the Free Software Foundation; either version 2 of the License, or
 | 
				
			||||||
    (at your option) any later version.
 | 
					(at your option) any later version.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    This program is distributed in the hope that it will be useful,
 | 
					This program is distributed in the hope that it will be useful,
 | 
				
			||||||
    but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
					but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
				
			||||||
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
					MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
				
			||||||
    GNU General Public License for more details.
 | 
					GNU General Public License for more details.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    You should have received a copy of the GNU General Public License along
 | 
					You should have received a copy of the GNU General Public License along
 | 
				
			||||||
    with this program; if not, write to the Free Software Foundation, Inc.,
 | 
					with this program; if not, write to the Free Software Foundation, Inc.,
 | 
				
			||||||
    51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 | 
					51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    See the full license in the file "LICENSE" in the top level distribution directory
 | 
					See the full license in the file "LICENSE" in the top level distribution
 | 
				
			||||||
    *************************************************************************************/
 | 
					directory
 | 
				
			||||||
    /*  END LEGAL */
 | 
					*************************************************************************************/
 | 
				
			||||||
#ifndef  GRID_QCD_FERMION_OPERATOR_IMPL_H
 | 
					/*  END LEGAL */
 | 
				
			||||||
#define  GRID_QCD_FERMION_OPERATOR_IMPL_H
 | 
					#ifndef GRID_QCD_FERMION_OPERATOR_IMPL_H
 | 
				
			||||||
 | 
					#define GRID_QCD_FERMION_OPERATOR_IMPL_H
 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace Grid {
 | 
					namespace Grid {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -99,65 +100,80 @@ namespace Grid {
 | 
				
			|||||||
    typedef typename Impl::SiteSpinor               SiteSpinor;		\
 | 
					    typedef typename Impl::SiteSpinor               SiteSpinor;		\
 | 
				
			||||||
    typedef typename Impl::SiteHalfSpinor       SiteHalfSpinor;		\
 | 
					    typedef typename Impl::SiteHalfSpinor       SiteHalfSpinor;		\
 | 
				
			||||||
    typedef typename Impl::Compressor               Compressor;		\
 | 
					    typedef typename Impl::Compressor               Compressor;		\
 | 
				
			||||||
    typedef typename Impl::StencilImpl             StencilImpl;	  \
 | 
					    typedef typename Impl::StencilImpl             StencilImpl;		\
 | 
				
			||||||
    typedef typename Impl::ImplParams ImplParams;
 | 
					    typedef typename Impl::ImplParams ImplParams;			\
 | 
				
			||||||
 | 
					    typedef typename Impl::Coeff_t       Coeff_t;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define INHERIT_IMPL_TYPES(Base) \
 | 
					#define INHERIT_IMPL_TYPES(Base) \
 | 
				
			||||||
    INHERIT_GIMPL_TYPES(Base)\
 | 
					    INHERIT_GIMPL_TYPES(Base)	 \
 | 
				
			||||||
    INHERIT_FIMPL_TYPES(Base)
 | 
					    INHERIT_FIMPL_TYPES(Base)
 | 
				
			||||||
    
 | 
					    
 | 
				
			||||||
    ///////
 | 
					    ///////
 | 
				
			||||||
    // Single flavour four spinors with colour index
 | 
					    // Single flavour four spinors with colour index
 | 
				
			||||||
    ///////
 | 
					    ///////
 | 
				
			||||||
    template<class S,int Nrepresentation=Nc>
 | 
					    template <class S, class Representation = FundamentalRepresentation,class _Coeff_t = RealD >
 | 
				
			||||||
    class WilsonImpl :  public PeriodicGaugeImpl< GaugeImplTypes< S, Nrepresentation> > { 
 | 
					    class WilsonImpl
 | 
				
			||||||
 | 
					      : public PeriodicGaugeImpl<GaugeImplTypes<S, Representation::Dimension > > {
 | 
				
			||||||
    public:
 | 
					    public:
 | 
				
			||||||
 | 
					      static const int Dimension = Representation::Dimension;
 | 
				
			||||||
 | 
					      typedef PeriodicGaugeImpl<GaugeImplTypes<S, Dimension > > Gimpl;
 | 
				
			||||||
 | 
					      
 | 
				
			||||||
 | 
					      //Necessary?
 | 
				
			||||||
 | 
					      constexpr bool is_fundamental() const{return Dimension == Nc ? 1 : 0;}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      const bool LsVectorised=false;
 | 
					      const bool LsVectorised=false;
 | 
				
			||||||
 | 
					      typedef _Coeff_t Coeff_t;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      typedef PeriodicGaugeImpl< GaugeImplTypes< S,Nrepresentation> > Gimpl;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
      INHERIT_GIMPL_TYPES(Gimpl);
 | 
					      INHERIT_GIMPL_TYPES(Gimpl);
 | 
				
			||||||
      
 | 
					      
 | 
				
			||||||
      template<typename vtype> using iImplSpinor             = iScalar<iVector<iVector<vtype, Nrepresentation>, Ns> >;
 | 
					      template <typename vtype> using iImplSpinor            = iScalar<iVector<iVector<vtype, Dimension>, Ns> >;
 | 
				
			||||||
      template<typename vtype> using iImplHalfSpinor         = iScalar<iVector<iVector<vtype, Nrepresentation>, Nhs> >;
 | 
					      template <typename vtype> using iImplHalfSpinor        = iScalar<iVector<iVector<vtype, Dimension>, Nhs> >;
 | 
				
			||||||
      template<typename vtype> using iImplDoubledGaugeField  = iVector<iScalar<iMatrix<vtype, Nrepresentation> >, Nds >;
 | 
					      template <typename vtype> using iImplDoubledGaugeField = iVector<iScalar<iMatrix<vtype, Dimension> >, Nds>;
 | 
				
			||||||
      
 | 
					      
 | 
				
			||||||
      typedef iImplSpinor    <Simd>           SiteSpinor;
 | 
					      typedef iImplSpinor<Simd>            SiteSpinor;
 | 
				
			||||||
      typedef iImplHalfSpinor<Simd>           SiteHalfSpinor;
 | 
					      typedef iImplHalfSpinor<Simd>        SiteHalfSpinor;
 | 
				
			||||||
      typedef iImplDoubledGaugeField<Simd>    SiteDoubledGaugeField;
 | 
					      typedef iImplDoubledGaugeField<Simd> SiteDoubledGaugeField;
 | 
				
			||||||
      
 | 
					      
 | 
				
			||||||
      typedef Lattice<SiteSpinor>                 FermionField;
 | 
					      typedef Lattice<SiteSpinor>            FermionField;
 | 
				
			||||||
      typedef Lattice<SiteDoubledGaugeField> DoubledGaugeField;
 | 
					      typedef Lattice<SiteDoubledGaugeField> DoubledGaugeField;
 | 
				
			||||||
      
 | 
					      
 | 
				
			||||||
      typedef WilsonCompressor<SiteHalfSpinor,SiteSpinor> Compressor;
 | 
					      typedef WilsonCompressor<SiteHalfSpinor, SiteSpinor> Compressor;
 | 
				
			||||||
      typedef WilsonImplParams ImplParams;
 | 
					      typedef WilsonImplParams ImplParams;
 | 
				
			||||||
      typedef WilsonStencil<SiteSpinor,SiteHalfSpinor> StencilImpl;
 | 
					      typedef WilsonStencil<SiteSpinor, SiteHalfSpinor> StencilImpl;
 | 
				
			||||||
      
 | 
					      
 | 
				
			||||||
      ImplParams Params;
 | 
					      ImplParams Params;
 | 
				
			||||||
      
 | 
					      
 | 
				
			||||||
      WilsonImpl(const ImplParams &p= ImplParams()) : Params(p) {}; 
 | 
					      WilsonImpl(const ImplParams &p = ImplParams()) : Params(p){};
 | 
				
			||||||
      
 | 
					      
 | 
				
			||||||
      bool overlapCommsCompute(void) { return Params.overlapCommsCompute; };
 | 
					      bool overlapCommsCompute(void) { return Params.overlapCommsCompute; };
 | 
				
			||||||
      
 | 
					      
 | 
				
			||||||
      inline void multLink(SiteHalfSpinor &phi,const SiteDoubledGaugeField &U,const SiteHalfSpinor &chi,int mu,StencilEntry *SE,StencilImpl &St){
 | 
					      inline void multLink(SiteHalfSpinor &phi,
 | 
				
			||||||
        mult(&phi(),&U(mu),&chi());
 | 
								   const SiteDoubledGaugeField &U,
 | 
				
			||||||
 | 
								   const SiteHalfSpinor &chi,
 | 
				
			||||||
 | 
								   int mu,
 | 
				
			||||||
 | 
								   StencilEntry *SE,
 | 
				
			||||||
 | 
								   StencilImpl &St) {
 | 
				
			||||||
 | 
						mult(&phi(), &U(mu), &chi());
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
      
 | 
					      
 | 
				
			||||||
      template<class ref>
 | 
					      template <class ref>
 | 
				
			||||||
      inline void loadLinkElement(Simd & reg,ref &memory){
 | 
					      inline void loadLinkElement(Simd ®,
 | 
				
			||||||
 | 
									  ref &memory) {
 | 
				
			||||||
	reg = memory;
 | 
						reg = memory;
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
      inline void DoubleStore(GridBase *GaugeGrid,DoubledGaugeField &Uds,const GaugeField &Umu)
 | 
					      
 | 
				
			||||||
      {
 | 
					      inline void DoubleStore(GridBase *GaugeGrid,
 | 
				
			||||||
        conformable(Uds._grid,GaugeGrid);
 | 
								      DoubledGaugeField &Uds,
 | 
				
			||||||
        conformable(Umu._grid,GaugeGrid);
 | 
								      const GaugeField &Umu) {
 | 
				
			||||||
        GaugeLinkField U(GaugeGrid);
 | 
						conformable(Uds._grid, GaugeGrid);
 | 
				
			||||||
        for(int mu=0;mu<Nd;mu++){
 | 
						conformable(Umu._grid, GaugeGrid);
 | 
				
			||||||
  	  U = PeekIndex<LorentzIndex>(Umu,mu);
 | 
						GaugeLinkField U(GaugeGrid);
 | 
				
			||||||
	  PokeIndex<LorentzIndex>(Uds,U,mu);
 | 
						for (int mu = 0; mu < Nd; mu++) {
 | 
				
			||||||
	  U = adj(Cshift(U,mu,-1));
 | 
						  U = PeekIndex<LorentzIndex>(Umu, mu);
 | 
				
			||||||
	  PokeIndex<LorentzIndex>(Uds,U,mu+4);
 | 
						  PokeIndex<LorentzIndex>(Uds, U, mu);
 | 
				
			||||||
 | 
						  U = adj(Cshift(U, mu, -1));
 | 
				
			||||||
 | 
						  PokeIndex<LorentzIndex>(Uds, U, mu + 4);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -173,155 +189,168 @@ namespace Grid {
 | 
				
			|||||||
	
 | 
						
 | 
				
			||||||
	GaugeLinkField tmp(mat._grid);
 | 
						GaugeLinkField tmp(mat._grid);
 | 
				
			||||||
	tmp = zero;
 | 
						tmp = zero;
 | 
				
			||||||
PARALLEL_FOR_LOOP
 | 
						PARALLEL_FOR_LOOP
 | 
				
			||||||
	for(int sss=0;sss<tmp._grid->oSites();sss++){
 | 
						  for(int sss=0;sss<tmp._grid->oSites();sss++){
 | 
				
			||||||
	  int sU=sss;
 | 
						    int sU=sss;
 | 
				
			||||||
	  for(int s=0;s<Ls;s++){
 | 
						    for(int s=0;s<Ls;s++){
 | 
				
			||||||
	    int sF = s+Ls*sU;
 | 
						      int sF = s+Ls*sU;
 | 
				
			||||||
	    tmp[sU] = tmp[sU]+ traceIndex<SpinIndex>(outerProduct(Btilde[sF],Atilde[sF])); // ordering here
 | 
						      tmp[sU] = tmp[sU]+ traceIndex<SpinIndex>(outerProduct(Btilde[sF],Atilde[sF])); // ordering here
 | 
				
			||||||
 | 
						    }
 | 
				
			||||||
	  }
 | 
						  }
 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	PokeIndex<LorentzIndex>(mat,tmp,mu);
 | 
						PokeIndex<LorentzIndex>(mat,tmp,mu);
 | 
				
			||||||
	
 | 
						
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
 | 
					 | 
				
			||||||
    };
 | 
					    };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    ///////
 | 
					    ///////
 | 
				
			||||||
    // Single flavour four spinors with colour index, 5d redblack
 | 
					    // Single flavour four spinors with colour index, 5d redblack
 | 
				
			||||||
    ///////
 | 
					    ///////
 | 
				
			||||||
    template<class S,int Nrepresentation=Nc>
 | 
					    template<class S,int Nrepresentation=Nc,class _Coeff_t = RealD>
 | 
				
			||||||
    class DomainWallVec5dImpl :  public PeriodicGaugeImpl< GaugeImplTypes< S,Nrepresentation> > { 
 | 
					    class DomainWallVec5dImpl :  public PeriodicGaugeImpl< GaugeImplTypes< S,Nrepresentation> > { 
 | 
				
			||||||
    public:
 | 
					    public:
 | 
				
			||||||
      
 | 
					      
 | 
				
			||||||
 | 
					      static const int Dimension = Nrepresentation;
 | 
				
			||||||
      const bool LsVectorised=true;
 | 
					      const bool LsVectorised=true;
 | 
				
			||||||
 | 
					      typedef _Coeff_t Coeff_t;      
 | 
				
			||||||
      typedef PeriodicGaugeImpl< GaugeImplTypes< S,Nrepresentation> > Gimpl;
 | 
					      typedef PeriodicGaugeImpl<GaugeImplTypes<S, Nrepresentation> > Gimpl;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      INHERIT_GIMPL_TYPES(Gimpl);
 | 
					      INHERIT_GIMPL_TYPES(Gimpl);
 | 
				
			||||||
      
 | 
					      
 | 
				
			||||||
      template<typename vtype> using iImplSpinor             = iScalar<iVector<iVector<vtype, Nrepresentation>, Ns> >;
 | 
					      template <typename vtype> using iImplSpinor            = iScalar<iVector<iVector<vtype, Nrepresentation>, Ns> >;
 | 
				
			||||||
      template<typename vtype> using iImplHalfSpinor         = iScalar<iVector<iVector<vtype, Nrepresentation>, Nhs> >;
 | 
					      template <typename vtype> using iImplHalfSpinor        = iScalar<iVector<iVector<vtype, Nrepresentation>, Nhs> >;
 | 
				
			||||||
      template<typename vtype> using iImplDoubledGaugeField  = iVector<iScalar<iMatrix<vtype, Nrepresentation> >, Nds >;
 | 
					      template <typename vtype> using iImplDoubledGaugeField = iVector<iScalar<iMatrix<vtype, Nrepresentation> >, Nds>;
 | 
				
			||||||
      template<typename vtype> using iImplGaugeField         = iVector<iScalar<iMatrix<vtype, Nrepresentation> >, Nd >;
 | 
					      template <typename vtype> using iImplGaugeField        = iVector<iScalar<iMatrix<vtype, Nrepresentation> >, Nd>;
 | 
				
			||||||
      template<typename vtype> using iImplGaugeLink          = iScalar<iScalar<iMatrix<vtype, Nrepresentation> > >;
 | 
					      template <typename vtype> using iImplGaugeLink         = iScalar<iScalar<iMatrix<vtype, Nrepresentation> > >;
 | 
				
			||||||
      
 | 
					      
 | 
				
			||||||
      typedef iImplSpinor    <Simd>           SiteSpinor;
 | 
					      typedef iImplSpinor<Simd> SiteSpinor;
 | 
				
			||||||
      typedef iImplHalfSpinor<Simd>           SiteHalfSpinor;
 | 
					      typedef iImplHalfSpinor<Simd> SiteHalfSpinor;
 | 
				
			||||||
      typedef Lattice<SiteSpinor>             FermionField;
 | 
					      typedef Lattice<SiteSpinor> FermionField;
 | 
				
			||||||
      
 | 
					      
 | 
				
			||||||
      // Make the doubled gauge field a *scalar*
 | 
					      // Make the doubled gauge field a *scalar*
 | 
				
			||||||
      typedef iImplDoubledGaugeField<typename Simd::scalar_type>    SiteDoubledGaugeField; // This is a scalar
 | 
					      typedef iImplDoubledGaugeField<typename Simd::scalar_type>
 | 
				
			||||||
      typedef iImplGaugeField<typename Simd::scalar_type>           SiteScalarGaugeField;  // scalar
 | 
					      SiteDoubledGaugeField;  // This is a scalar
 | 
				
			||||||
      typedef iImplGaugeLink <typename Simd::scalar_type>           SiteScalarGaugeLink;   // scalar
 | 
					      typedef iImplGaugeField<typename Simd::scalar_type>
 | 
				
			||||||
 | 
					      SiteScalarGaugeField;  // scalar
 | 
				
			||||||
 | 
					      typedef iImplGaugeLink<typename Simd::scalar_type>
 | 
				
			||||||
 | 
					      SiteScalarGaugeLink;  // scalar
 | 
				
			||||||
      
 | 
					      
 | 
				
			||||||
      typedef Lattice<SiteDoubledGaugeField>                  DoubledGaugeField;
 | 
					      typedef Lattice<SiteDoubledGaugeField> DoubledGaugeField;
 | 
				
			||||||
      
 | 
					      
 | 
				
			||||||
      typedef WilsonCompressor<SiteHalfSpinor,SiteSpinor> Compressor;
 | 
					      typedef WilsonCompressor<SiteHalfSpinor, SiteSpinor> Compressor;
 | 
				
			||||||
      typedef WilsonImplParams ImplParams;
 | 
					      typedef WilsonImplParams ImplParams;
 | 
				
			||||||
      typedef WilsonStencil<SiteSpinor,SiteHalfSpinor> StencilImpl;
 | 
					      typedef WilsonStencil<SiteSpinor, SiteHalfSpinor> StencilImpl;
 | 
				
			||||||
      
 | 
					      
 | 
				
			||||||
      ImplParams Params;
 | 
					      ImplParams Params;
 | 
				
			||||||
      
 | 
					      
 | 
				
			||||||
      DomainWallVec5dImpl(const ImplParams &p= ImplParams()) : Params(p) {}; 
 | 
					      DomainWallVec5dImpl(const ImplParams &p = ImplParams()) : Params(p){};
 | 
				
			||||||
      
 | 
					      
 | 
				
			||||||
      bool overlapCommsCompute(void) { return false; };
 | 
					      bool overlapCommsCompute(void) { return false; };
 | 
				
			||||||
      
 | 
					      
 | 
				
			||||||
      template<class ref>
 | 
					      template <class ref>
 | 
				
			||||||
      inline void loadLinkElement(Simd & reg,ref &memory){
 | 
					      inline void loadLinkElement(Simd ®, ref &memory) {
 | 
				
			||||||
	vsplat(reg,memory);
 | 
						vsplat(reg, memory);
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
      inline void multLink(SiteHalfSpinor &phi,const SiteDoubledGaugeField &U,const SiteHalfSpinor &chi,int mu,StencilEntry *SE,StencilImpl &St)
 | 
					      inline void multLink(SiteHalfSpinor &phi, const SiteDoubledGaugeField &U,
 | 
				
			||||||
      {
 | 
								   const SiteHalfSpinor &chi, int mu, StencilEntry *SE,
 | 
				
			||||||
 | 
								   StencilImpl &St) {
 | 
				
			||||||
	SiteGaugeLink UU;
 | 
						SiteGaugeLink UU;
 | 
				
			||||||
	for(int i=0;i<Nrepresentation;i++){
 | 
						for (int i = 0; i < Nrepresentation; i++) {
 | 
				
			||||||
	  for(int j=0;j<Nrepresentation;j++){
 | 
						  for (int j = 0; j < Nrepresentation; j++) {
 | 
				
			||||||
	    vsplat(UU()()(i,j),U(mu)()(i,j));
 | 
						    vsplat(UU()()(i, j), U(mu)()(i, j));
 | 
				
			||||||
	  }
 | 
						  }
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
        mult(&phi(),&UU(),&chi());
 | 
						mult(&phi(), &UU(), &chi());
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
      
 | 
					      
 | 
				
			||||||
      inline void DoubleStore(GridBase *GaugeGrid,DoubledGaugeField &Uds,const GaugeField &Umu)
 | 
					      inline void DoubleStore(GridBase *GaugeGrid, DoubledGaugeField &Uds,
 | 
				
			||||||
      {
 | 
								      const GaugeField &Umu) {
 | 
				
			||||||
	SiteScalarGaugeField  ScalarUmu;
 | 
						SiteScalarGaugeField ScalarUmu;
 | 
				
			||||||
	SiteDoubledGaugeField ScalarUds;
 | 
						SiteDoubledGaugeField ScalarUds;
 | 
				
			||||||
	
 | 
						
 | 
				
			||||||
        GaugeLinkField U   (Umu._grid);
 | 
						GaugeLinkField U(Umu._grid);
 | 
				
			||||||
	GaugeField     Uadj(Umu._grid);
 | 
						GaugeField Uadj(Umu._grid);
 | 
				
			||||||
        for(int mu=0;mu<Nd;mu++){
 | 
						for (int mu = 0; mu < Nd; mu++) {
 | 
				
			||||||
  	  U = PeekIndex<LorentzIndex>(Umu,mu);
 | 
						  U = PeekIndex<LorentzIndex>(Umu, mu);
 | 
				
			||||||
	  U = adj(Cshift(U,mu,-1));
 | 
						  U = adj(Cshift(U, mu, -1));
 | 
				
			||||||
	  PokeIndex<LorentzIndex>(Uadj,U,mu);
 | 
						  PokeIndex<LorentzIndex>(Uadj, U, mu);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	
 | 
						
 | 
				
			||||||
	for(int lidx=0;lidx<GaugeGrid->lSites();lidx++){
 | 
						for (int lidx = 0; lidx < GaugeGrid->lSites(); lidx++) {
 | 
				
			||||||
	  std::vector<int> lcoor;
 | 
						  std::vector<int> lcoor;
 | 
				
			||||||
	  GaugeGrid->LocalIndexToLocalCoor(lidx,lcoor);
 | 
						  GaugeGrid->LocalIndexToLocalCoor(lidx, lcoor);
 | 
				
			||||||
	  
 | 
						  
 | 
				
			||||||
	  peekLocalSite(ScalarUmu,Umu,lcoor);
 | 
						  peekLocalSite(ScalarUmu, Umu, lcoor);
 | 
				
			||||||
	  for(int mu=0;mu<4;mu++) ScalarUds(mu) = ScalarUmu(mu);
 | 
						  for (int mu = 0; mu < 4; mu++) ScalarUds(mu) = ScalarUmu(mu);
 | 
				
			||||||
	  
 | 
						  
 | 
				
			||||||
	  peekLocalSite(ScalarUmu,Uadj,lcoor);
 | 
						  peekLocalSite(ScalarUmu, Uadj, lcoor);
 | 
				
			||||||
	  for(int mu=0;mu<4;mu++) ScalarUds(mu+4) = ScalarUmu(mu);
 | 
						  for (int mu = 0; mu < 4; mu++) ScalarUds(mu + 4) = ScalarUmu(mu);
 | 
				
			||||||
	  
 | 
						  
 | 
				
			||||||
	  pokeLocalSite(ScalarUds,Uds,lcoor);
 | 
						  pokeLocalSite(ScalarUds, Uds, lcoor);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
      
 | 
					      
 | 
				
			||||||
      inline void InsertForce4D(GaugeField &mat, FermionField &Btilde, FermionField &A,int mu){
 | 
					      inline void InsertForce4D(GaugeField &mat, FermionField &Btilde,
 | 
				
			||||||
 | 
									FermionField &A, int mu) {
 | 
				
			||||||
	assert(0);
 | 
						assert(0);
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
      
 | 
					      
 | 
				
			||||||
      inline void InsertForce5D(GaugeField &mat, FermionField &Btilde, FermionField Ã,int mu){
 | 
					      inline void InsertForce5D(GaugeField &mat, FermionField &Btilde,
 | 
				
			||||||
 | 
									FermionField Ã, int mu) {
 | 
				
			||||||
	assert(0);
 | 
						assert(0);
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
 | 
					 | 
				
			||||||
    };
 | 
					    };
 | 
				
			||||||
    
 | 
					    
 | 
				
			||||||
 | 
					 | 
				
			||||||
    ////////////////////////////////////////////////////////////////////////////////////////
 | 
					    ////////////////////////////////////////////////////////////////////////////////////////
 | 
				
			||||||
    // Flavour doubled spinors; is Gparity the only? what about C*?
 | 
					    // Flavour doubled spinors; is Gparity the only? what about C*?
 | 
				
			||||||
    ////////////////////////////////////////////////////////////////////////////////////////
 | 
					    ////////////////////////////////////////////////////////////////////////////////////////
 | 
				
			||||||
    
 | 
					    
 | 
				
			||||||
    template<class S,int Nrepresentation>
 | 
					    template <class S, int Nrepresentation,class _Coeff_t = RealD>
 | 
				
			||||||
    class GparityWilsonImpl : public ConjugateGaugeImpl< GaugeImplTypes<S,Nrepresentation> >{ 
 | 
					    class GparityWilsonImpl
 | 
				
			||||||
 | 
					      : public ConjugateGaugeImpl<GaugeImplTypes<S, Nrepresentation> > {
 | 
				
			||||||
    public:
 | 
					    public:
 | 
				
			||||||
 | 
					      static const int Dimension = Nrepresentation;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      const bool LsVectorised=false;
 | 
					      const bool LsVectorised=false;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      typedef _Coeff_t Coeff_t;
 | 
				
			||||||
      typedef ConjugateGaugeImpl< GaugeImplTypes<S,Nrepresentation> > Gimpl;
 | 
					      typedef ConjugateGaugeImpl< GaugeImplTypes<S,Nrepresentation> > Gimpl;
 | 
				
			||||||
      
 | 
					      
 | 
				
			||||||
      INHERIT_GIMPL_TYPES(Gimpl);
 | 
					      INHERIT_GIMPL_TYPES(Gimpl);
 | 
				
			||||||
      
 | 
					      
 | 
				
			||||||
      template<typename vtype> using iImplSpinor             = iVector<iVector<iVector<vtype, Nrepresentation>, Ns>, Ngp >;
 | 
					      template <typename vtype>
 | 
				
			||||||
      template<typename vtype> using iImplHalfSpinor         = iVector<iVector<iVector<vtype, Nrepresentation>, Nhs>, Ngp >;
 | 
					      using iImplSpinor =
 | 
				
			||||||
      template<typename vtype> using iImplDoubledGaugeField  = iVector<iVector<iScalar<iMatrix<vtype, Nrepresentation> >, Nds >, Ngp >;
 | 
					      iVector<iVector<iVector<vtype, Nrepresentation>, Ns>, Ngp>;
 | 
				
			||||||
 | 
					      template <typename vtype>
 | 
				
			||||||
 | 
					      using iImplHalfSpinor =
 | 
				
			||||||
 | 
						iVector<iVector<iVector<vtype, Nrepresentation>, Nhs>, Ngp>;
 | 
				
			||||||
 | 
					      template <typename vtype>
 | 
				
			||||||
 | 
					      using iImplDoubledGaugeField =
 | 
				
			||||||
 | 
						iVector<iVector<iScalar<iMatrix<vtype, Nrepresentation> >, Nds>, Ngp>;
 | 
				
			||||||
      
 | 
					      
 | 
				
			||||||
      typedef iImplSpinor    <Simd>           SiteSpinor;
 | 
					      typedef iImplSpinor<Simd> SiteSpinor;
 | 
				
			||||||
      typedef iImplHalfSpinor<Simd>           SiteHalfSpinor;
 | 
					      typedef iImplHalfSpinor<Simd> SiteHalfSpinor;
 | 
				
			||||||
      typedef iImplDoubledGaugeField<Simd>    SiteDoubledGaugeField;
 | 
					      typedef iImplDoubledGaugeField<Simd> SiteDoubledGaugeField;
 | 
				
			||||||
      
 | 
					      
 | 
				
			||||||
      typedef Lattice<SiteSpinor>                 FermionField;
 | 
					      typedef Lattice<SiteSpinor> FermionField;
 | 
				
			||||||
      typedef Lattice<SiteDoubledGaugeField> DoubledGaugeField;
 | 
					      typedef Lattice<SiteDoubledGaugeField> DoubledGaugeField;
 | 
				
			||||||
      
 | 
					      
 | 
				
			||||||
      typedef WilsonCompressor<SiteHalfSpinor,SiteSpinor> Compressor;
 | 
					      typedef WilsonCompressor<SiteHalfSpinor, SiteSpinor> Compressor;
 | 
				
			||||||
      typedef WilsonStencil<SiteSpinor,SiteHalfSpinor> StencilImpl;
 | 
					      typedef WilsonStencil<SiteSpinor, SiteHalfSpinor> StencilImpl;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      typedef GparityWilsonImplParams ImplParams;
 | 
					      typedef GparityWilsonImplParams ImplParams;
 | 
				
			||||||
      
 | 
					      
 | 
				
			||||||
      ImplParams Params;
 | 
					      ImplParams Params;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      GparityWilsonImpl(const ImplParams &p= ImplParams()) : Params(p) {}; 
 | 
					
 | 
				
			||||||
 | 
					      GparityWilsonImpl(const ImplParams &p = ImplParams()) : Params(p){};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      bool overlapCommsCompute(void) { return Params.overlapCommsCompute; };
 | 
					      bool overlapCommsCompute(void) { return Params.overlapCommsCompute; };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      // provide the multiply by link that is differentiated between Gparity (with flavour index) and non-Gparity
 | 
					      // provide the multiply by link that is differentiated between Gparity (with
 | 
				
			||||||
      inline void multLink(SiteHalfSpinor &phi,const SiteDoubledGaugeField &U,const SiteHalfSpinor &chi,int mu,StencilEntry *SE,StencilImpl &St){
 | 
					      // flavour index) and non-Gparity
 | 
				
			||||||
 | 
					      inline void multLink(SiteHalfSpinor &phi, const SiteDoubledGaugeField &U,
 | 
				
			||||||
 | 
								   const SiteHalfSpinor &chi, int mu, StencilEntry *SE,
 | 
				
			||||||
 | 
								   StencilImpl &St) {
 | 
				
			||||||
	typedef SiteHalfSpinor vobj;
 | 
						typedef SiteHalfSpinor vobj;
 | 
				
			||||||
	typedef typename SiteHalfSpinor::scalar_object sobj;
 | 
						typedef typename SiteHalfSpinor::scalar_object sobj;
 | 
				
			||||||
	
 | 
						
 | 
				
			||||||
@@ -332,17 +361,17 @@ PARALLEL_FOR_LOOP
 | 
				
			|||||||
	
 | 
						
 | 
				
			||||||
	const int Nsimd = grid->Nsimd();
 | 
						const int Nsimd = grid->Nsimd();
 | 
				
			||||||
	
 | 
						
 | 
				
			||||||
	int direction    = St._directions[mu];
 | 
						int direction = St._directions[mu];
 | 
				
			||||||
	int distance     = St._distances[mu];
 | 
						int distance = St._distances[mu];
 | 
				
			||||||
	int ptype        = St._permute_type[mu]; 
 | 
						int ptype = St._permute_type[mu];
 | 
				
			||||||
	int sl           = St._grid->_simd_layout[direction];
 | 
						int sl = St._grid->_simd_layout[direction];
 | 
				
			||||||
	
 | 
						
 | 
				
			||||||
	// Fixme X.Y.Z.T hardcode in stencil
 | 
						// Fixme X.Y.Z.T hardcode in stencil
 | 
				
			||||||
	int mmu          = mu % Nd;
 | 
						int mmu = mu % Nd;
 | 
				
			||||||
	
 | 
						
 | 
				
			||||||
	// assert our assumptions
 | 
						// assert our assumptions
 | 
				
			||||||
	assert((distance==1)||(distance==-1)); // nearest neighbour stencil hard code
 | 
						assert((distance == 1) || (distance == -1));  // nearest neighbour stencil hard code
 | 
				
			||||||
	assert((sl==1)||(sl==2));
 | 
						assert((sl == 1) || (sl == 2));
 | 
				
			||||||
	
 | 
						
 | 
				
			||||||
	std::vector<int> icoor;
 | 
						std::vector<int> icoor;
 | 
				
			||||||
	
 | 
						
 | 
				
			||||||
@@ -386,7 +415,7 @@ PARALLEL_FOR_LOOP
 | 
				
			|||||||
	  mult(&phi(1),&U(1)(mu),&chi(1));
 | 
						  mult(&phi(1),&U(1)(mu),&chi(1));
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	
 | 
						
 | 
				
			||||||
      }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      inline void DoubleStore(GridBase *GaugeGrid,DoubledGaugeField &Uds,const GaugeField &Umu)
 | 
					      inline void DoubleStore(GridBase *GaugeGrid,DoubledGaugeField &Uds,const GaugeField &Umu)
 | 
				
			||||||
      {
 | 
					      {
 | 
				
			||||||
@@ -415,11 +444,11 @@ PARALLEL_FOR_LOOP
 | 
				
			|||||||
	  }
 | 
						  }
 | 
				
			||||||
	  
 | 
						  
 | 
				
			||||||
	  
 | 
						  
 | 
				
			||||||
PARALLEL_FOR_LOOP
 | 
						  PARALLEL_FOR_LOOP
 | 
				
			||||||
	  for(auto ss=U.begin();ss<U.end();ss++){
 | 
						    for(auto ss=U.begin();ss<U.end();ss++){
 | 
				
			||||||
	    Uds[ss](0)(mu) = U[ss]();
 | 
						      Uds[ss](0)(mu) = U[ss]();
 | 
				
			||||||
	    Uds[ss](1)(mu) = Uconj[ss]();
 | 
						      Uds[ss](1)(mu) = Uconj[ss]();
 | 
				
			||||||
	  }
 | 
						    }
 | 
				
			||||||
	  
 | 
						  
 | 
				
			||||||
	  U     = adj(Cshift(U    ,mu,-1));      // correct except for spanning the boundary
 | 
						  U     = adj(Cshift(U    ,mu,-1));      // correct except for spanning the boundary
 | 
				
			||||||
	  Uconj = adj(Cshift(Uconj,mu,-1));
 | 
						  Uconj = adj(Cshift(Uconj,mu,-1));
 | 
				
			||||||
@@ -429,68 +458,86 @@ PARALLEL_FOR_LOOP
 | 
				
			|||||||
	    Utmp = where(coor==0,Uconj,Utmp);
 | 
						    Utmp = where(coor==0,Uconj,Utmp);
 | 
				
			||||||
	  }
 | 
						  }
 | 
				
			||||||
	  
 | 
						  
 | 
				
			||||||
PARALLEL_FOR_LOOP
 | 
						  PARALLEL_FOR_LOOP
 | 
				
			||||||
	  for(auto ss=U.begin();ss<U.end();ss++){
 | 
						    for(auto ss=U.begin();ss<U.end();ss++){
 | 
				
			||||||
	    Uds[ss](0)(mu+4) = Utmp[ss]();
 | 
						      Uds[ss](0)(mu+4) = Utmp[ss]();
 | 
				
			||||||
	  }
 | 
						    }
 | 
				
			||||||
	  
 | 
						  
 | 
				
			||||||
	  Utmp = Uconj;
 | 
						  Utmp = Uconj;
 | 
				
			||||||
	  if ( Params.twists[mu] ) { 
 | 
						  if ( Params.twists[mu] ) { 
 | 
				
			||||||
	    Utmp = where(coor==0,U,Utmp);
 | 
						    Utmp = where(coor==0,U,Utmp);
 | 
				
			||||||
	  }
 | 
						  }
 | 
				
			||||||
	  
 | 
						  
 | 
				
			||||||
PARALLEL_FOR_LOOP
 | 
						  PARALLEL_FOR_LOOP
 | 
				
			||||||
	  for(auto ss=U.begin();ss<U.end();ss++){
 | 
						    for(auto ss=U.begin();ss<U.end();ss++){
 | 
				
			||||||
	    Uds[ss](1)(mu+4) = Utmp[ss]();
 | 
						      Uds[ss](1)(mu+4) = Utmp[ss]();
 | 
				
			||||||
	  }
 | 
						    }
 | 
				
			||||||
	  
 | 
						  
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
      
 | 
					      
 | 
				
			||||||
      inline void InsertForce4D(GaugeField &mat, FermionField &Btilde, FermionField &A,int mu){
 | 
					 | 
				
			||||||
      
 | 
					      
 | 
				
			||||||
 | 
					      inline void InsertForce4D(GaugeField &mat, FermionField &Btilde,
 | 
				
			||||||
 | 
									FermionField &A, int mu) {
 | 
				
			||||||
	// DhopDir provides U or Uconj depending on coor/flavour.
 | 
						// DhopDir provides U or Uconj depending on coor/flavour.
 | 
				
			||||||
	GaugeLinkField link(mat._grid);
 | 
						GaugeLinkField link(mat._grid);
 | 
				
			||||||
	// use lorentz for flavour as hack.
 | 
						// use lorentz for flavour as hack.
 | 
				
			||||||
PARALLEL_FOR_LOOP
 | 
						auto tmp = TraceIndex<SpinIndex>(outerProduct(Btilde, A));
 | 
				
			||||||
        for(auto ss=link.begin();ss<link.end();ss++){
 | 
						PARALLEL_FOR_LOOP
 | 
				
			||||||
	  auto ttmp = traceIndex<SpinIndex>(outerProduct(Btilde[ss],A[ss]));  
 | 
						  for (auto ss = tmp.begin(); ss < tmp.end(); ss++) {
 | 
				
			||||||
	  link[ss]() = ttmp(0,0) + conjugate(ttmp(1,1)) ; 
 | 
						    link[ss]() = tmp[ss](0, 0) - conjugate(tmp[ss](1, 1));
 | 
				
			||||||
	}
 | 
						  }
 | 
				
			||||||
	PokeIndex<LorentzIndex>(mat,link,mu);
 | 
						PokeIndex<LorentzIndex>(mat, link, mu);
 | 
				
			||||||
	return;
 | 
						return;
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
      inline void InsertForce5D(GaugeField &mat, FermionField &Btilde, FermionField Ã,int mu){
 | 
					 | 
				
			||||||
      
 | 
					      
 | 
				
			||||||
	int Ls=Btilde._grid->_fdimensions[0];
 | 
					      inline void InsertForce5D(GaugeField &mat, FermionField &Btilde,
 | 
				
			||||||
 | 
									FermionField Ã, int mu) {
 | 
				
			||||||
 | 
						int Ls = Btilde._grid->_fdimensions[0];
 | 
				
			||||||
	
 | 
						
 | 
				
			||||||
	GaugeLinkField tmp(mat._grid);
 | 
						GaugeLinkField tmp(mat._grid);
 | 
				
			||||||
	tmp = zero;
 | 
						tmp = zero;
 | 
				
			||||||
PARALLEL_FOR_LOOP
 | 
						PARALLEL_FOR_LOOP
 | 
				
			||||||
	for(int ss=0;ss<tmp._grid->oSites();ss++){
 | 
						  for (int ss = 0; ss < tmp._grid->oSites(); ss++) {
 | 
				
			||||||
	  for(int s=0;s<Ls;s++){
 | 
						    for (int s = 0; s < Ls; s++) {
 | 
				
			||||||
	    int sF = s+Ls*ss;
 | 
						      int sF = s + Ls * ss;
 | 
				
			||||||
	    auto ttmp = traceIndex<SpinIndex>(outerProduct(Btilde[sF],Atilde[sF]));
 | 
						      auto ttmp = traceIndex<SpinIndex>(outerProduct(Btilde[sF], Atilde[sF]));
 | 
				
			||||||
	    tmp[ss]() = tmp[ss]()+ ttmp(0,0) + conjugate(ttmp(1,1));
 | 
						      tmp[ss]() = tmp[ss]() + ttmp(0, 0) + conjugate(ttmp(1, 1));
 | 
				
			||||||
 | 
						    }
 | 
				
			||||||
	  }
 | 
						  }
 | 
				
			||||||
	}
 | 
						PokeIndex<LorentzIndex>(mat, tmp, mu);
 | 
				
			||||||
	PokeIndex<LorentzIndex>(mat,tmp,mu);
 | 
					 | 
				
			||||||
	return;
 | 
						return;
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
    };
 | 
					    };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    typedef WilsonImpl<vComplex ,Nc> WilsonImplR; // Real.. whichever prec
 | 
					    typedef WilsonImpl<vComplex,  FundamentalRepresentation > WilsonImplR;   // Real.. whichever prec
 | 
				
			||||||
    typedef WilsonImpl<vComplexF,Nc> WilsonImplF; // Float
 | 
					    typedef WilsonImpl<vComplexF, FundamentalRepresentation > WilsonImplF;  // Float
 | 
				
			||||||
    typedef WilsonImpl<vComplexD,Nc> WilsonImplD; // Double
 | 
					    typedef WilsonImpl<vComplexD, FundamentalRepresentation > WilsonImplD;  // Double
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    typedef WilsonImpl<vComplex,  FundamentalRepresentation, ComplexD > ZWilsonImplR; // Real.. whichever prec
 | 
				
			||||||
 | 
					    typedef WilsonImpl<vComplexF, FundamentalRepresentation, ComplexD > ZWilsonImplF; // Float
 | 
				
			||||||
 | 
					    typedef WilsonImpl<vComplexD, FundamentalRepresentation, ComplexD > ZWilsonImplD; // Double
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    typedef WilsonImpl<vComplex,  AdjointRepresentation > WilsonAdjImplR;   // Real.. whichever prec
 | 
				
			||||||
 | 
					    typedef WilsonImpl<vComplexF, AdjointRepresentation > WilsonAdjImplF;  // Float
 | 
				
			||||||
 | 
					    typedef WilsonImpl<vComplexD, AdjointRepresentation > WilsonAdjImplD;  // Double
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    typedef WilsonImpl<vComplex,  TwoIndexSymmetricRepresentation > WilsonTwoIndexSymmetricImplR;   // Real.. whichever prec
 | 
				
			||||||
 | 
					    typedef WilsonImpl<vComplexF, TwoIndexSymmetricRepresentation > WilsonTwoIndexSymmetricImplF;  // Float
 | 
				
			||||||
 | 
					    typedef WilsonImpl<vComplexD, TwoIndexSymmetricRepresentation > WilsonTwoIndexSymmetricImplD;  // Double
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    typedef DomainWallVec5dImpl<vComplex ,Nc> DomainWallVec5dImplR; // Real.. whichever prec
 | 
					    typedef DomainWallVec5dImpl<vComplex ,Nc> DomainWallVec5dImplR; // Real.. whichever prec
 | 
				
			||||||
    typedef DomainWallVec5dImpl<vComplexF,Nc> DomainWallVec5dImplF; // Float
 | 
					    typedef DomainWallVec5dImpl<vComplexF,Nc> DomainWallVec5dImplF; // Float
 | 
				
			||||||
    typedef DomainWallVec5dImpl<vComplexD,Nc> DomainWallVec5dImplD; // Double
 | 
					    typedef DomainWallVec5dImpl<vComplexD,Nc> DomainWallVec5dImplD; // Double
 | 
				
			||||||
    
 | 
					    
 | 
				
			||||||
    typedef GparityWilsonImpl<vComplex ,Nc> GparityWilsonImplR; // Real.. whichever prec
 | 
					    typedef DomainWallVec5dImpl<vComplex ,Nc,ComplexD> ZDomainWallVec5dImplR; // Real.. whichever prec
 | 
				
			||||||
    typedef GparityWilsonImpl<vComplexF,Nc> GparityWilsonImplF; // Float
 | 
					    typedef DomainWallVec5dImpl<vComplexF,Nc,ComplexD> ZDomainWallVec5dImplF; // Float
 | 
				
			||||||
    typedef GparityWilsonImpl<vComplexD,Nc> GparityWilsonImplD; // Double
 | 
					    typedef DomainWallVec5dImpl<vComplexD,Nc,ComplexD> ZDomainWallVec5dImplD; // Double
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  }
 | 
					    typedef GparityWilsonImpl<vComplex, Nc>  GparityWilsonImplR;  // Real.. whichever prec
 | 
				
			||||||
 | 
					    typedef GparityWilsonImpl<vComplexF, Nc> GparityWilsonImplF;  // Float
 | 
				
			||||||
 | 
					    typedef GparityWilsonImpl<vComplexD, Nc> GparityWilsonImplD;  // Double
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,319 +1,315 @@
 | 
				
			|||||||
    /*************************************************************************************
 | 
					/*************************************************************************************
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    Grid physics library, www.github.com/paboyle/Grid 
 | 
					Grid physics library, www.github.com/paboyle/Grid
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    Source file: ./lib/qcd/action/fermion/WilsonFermion.cc
 | 
					Source file: ./lib/qcd/action/fermion/WilsonFermion.cc
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    Copyright (C) 2015
 | 
					Copyright (C) 2015
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Author: Peter Boyle <pabobyle@ph.ed.ac.uk>
 | 
					Author: Peter Boyle <pabobyle@ph.ed.ac.uk>
 | 
				
			||||||
Author: Peter Boyle <paboyle@ph.ed.ac.uk>
 | 
					Author: Peter Boyle <paboyle@ph.ed.ac.uk>
 | 
				
			||||||
Author: Peter Boyle <peterboyle@Peters-MacBook-Pro-2.local>
 | 
					Author: Peter Boyle <peterboyle@Peters-MacBook-Pro-2.local>
 | 
				
			||||||
Author: paboyle <paboyle@ph.ed.ac.uk>
 | 
					Author: paboyle <paboyle@ph.ed.ac.uk>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    This program is free software; you can redistribute it and/or modify
 | 
					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
 | 
					it under the terms of the GNU General Public License as published by
 | 
				
			||||||
    the Free Software Foundation; either version 2 of the License, or
 | 
					the Free Software Foundation; either version 2 of the License, or
 | 
				
			||||||
    (at your option) any later version.
 | 
					(at your option) any later version.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    This program is distributed in the hope that it will be useful,
 | 
					This program is distributed in the hope that it will be useful,
 | 
				
			||||||
    but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
					but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
				
			||||||
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
					MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
				
			||||||
    GNU General Public License for more details.
 | 
					GNU General Public License for more details.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    You should have received a copy of the GNU General Public License along
 | 
					You should have received a copy of the GNU General Public License along
 | 
				
			||||||
    with this program; if not, write to the Free Software Foundation, Inc.,
 | 
					with this program; if not, write to the Free Software Foundation, Inc.,
 | 
				
			||||||
    51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 | 
					51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    See the full license in the file "LICENSE" in the top level distribution directory
 | 
					See the full license in the file "LICENSE" in the top level distribution
 | 
				
			||||||
    *************************************************************************************/
 | 
					directory
 | 
				
			||||||
    /*  END LEGAL */
 | 
					*************************************************************************************/
 | 
				
			||||||
 | 
					/*  END LEGAL */
 | 
				
			||||||
#include <Grid.h>
 | 
					#include <Grid.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace Grid {
 | 
					namespace Grid {
 | 
				
			||||||
namespace QCD {
 | 
					namespace QCD {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  const std::vector<int> WilsonFermionStatic::directions   ({0,1,2,3, 0, 1, 2, 3});
 | 
					const std::vector<int> WilsonFermionStatic::directions({0, 1, 2, 3, 0, 1, 2,
 | 
				
			||||||
  const std::vector<int> WilsonFermionStatic::displacements({1,1,1,1,-1,-1,-1,-1});
 | 
					                                                        3});
 | 
				
			||||||
  int WilsonFermionStatic::HandOptDslash;
 | 
					const std::vector<int> WilsonFermionStatic::displacements({1, 1, 1, 1, -1, -1,
 | 
				
			||||||
 | 
					                                                           -1, -1});
 | 
				
			||||||
 | 
					int WilsonFermionStatic::HandOptDslash;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  /////////////////////////////////
 | 
					/////////////////////////////////
 | 
				
			||||||
  // Constructor and gauge import
 | 
					// Constructor and gauge import
 | 
				
			||||||
  /////////////////////////////////
 | 
					/////////////////////////////////
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  template<class Impl>
 | 
					template <class Impl>
 | 
				
			||||||
  WilsonFermion<Impl>::WilsonFermion(GaugeField &_Umu,
 | 
					WilsonFermion<Impl>::WilsonFermion(GaugeField &_Umu, GridCartesian &Fgrid,
 | 
				
			||||||
				     GridCartesian         &Fgrid,
 | 
					                                   GridRedBlackCartesian &Hgrid, RealD _mass,
 | 
				
			||||||
				     GridRedBlackCartesian &Hgrid, 
 | 
					                                   const ImplParams &p)
 | 
				
			||||||
				     RealD _mass,const ImplParams &p) :
 | 
					    : Kernels(p),
 | 
				
			||||||
        Kernels(p),
 | 
					      _grid(&Fgrid),
 | 
				
			||||||
        _grid(&Fgrid),
 | 
					      _cbgrid(&Hgrid),
 | 
				
			||||||
	_cbgrid(&Hgrid),
 | 
					      Stencil(&Fgrid, npoint, Even, directions, displacements),
 | 
				
			||||||
	Stencil    (&Fgrid,npoint,Even,directions,displacements),
 | 
					      StencilEven(&Hgrid, npoint, Even, directions,
 | 
				
			||||||
	StencilEven(&Hgrid,npoint,Even,directions,displacements), // source is Even
 | 
					                  displacements),  // source is Even
 | 
				
			||||||
	StencilOdd (&Hgrid,npoint,Odd ,directions,displacements), // source is Odd
 | 
					      StencilOdd(&Hgrid, npoint, Odd, directions,
 | 
				
			||||||
	mass(_mass),
 | 
					                 displacements),  // source is Odd
 | 
				
			||||||
	Lebesgue(_grid),
 | 
					      mass(_mass),
 | 
				
			||||||
	LebesgueEvenOdd(_cbgrid),
 | 
					      Lebesgue(_grid),
 | 
				
			||||||
	Umu(&Fgrid),
 | 
					      LebesgueEvenOdd(_cbgrid),
 | 
				
			||||||
	UmuEven(&Hgrid),
 | 
					      Umu(&Fgrid),
 | 
				
			||||||
	UmuOdd (&Hgrid) 
 | 
					      UmuEven(&Hgrid),
 | 
				
			||||||
  {
 | 
					      UmuOdd(&Hgrid) {
 | 
				
			||||||
    // Allocate the required comms buffer
 | 
					  // Allocate the required comms buffer
 | 
				
			||||||
    ImportGauge(_Umu);
 | 
					  ImportGauge(_Umu);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					template <class Impl>
 | 
				
			||||||
 | 
					void WilsonFermion<Impl>::ImportGauge(const GaugeField &_Umu) {
 | 
				
			||||||
 | 
					  GaugeField HUmu(_Umu._grid);
 | 
				
			||||||
 | 
					  HUmu = _Umu * (-0.5);
 | 
				
			||||||
 | 
					  Impl::DoubleStore(GaugeGrid(), Umu, HUmu);
 | 
				
			||||||
 | 
					  pickCheckerboard(Even, UmuEven, Umu);
 | 
				
			||||||
 | 
					  pickCheckerboard(Odd, UmuOdd, Umu);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/////////////////////////////
 | 
				
			||||||
 | 
					// Implement the interface
 | 
				
			||||||
 | 
					/////////////////////////////
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					template <class Impl>
 | 
				
			||||||
 | 
					RealD WilsonFermion<Impl>::M(const FermionField &in, FermionField &out) {
 | 
				
			||||||
 | 
					  out.checkerboard = in.checkerboard;
 | 
				
			||||||
 | 
					  Dhop(in, out, DaggerNo);
 | 
				
			||||||
 | 
					  return axpy_norm(out, 4 + mass, in, out);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					template <class Impl>
 | 
				
			||||||
 | 
					RealD WilsonFermion<Impl>::Mdag(const FermionField &in, FermionField &out) {
 | 
				
			||||||
 | 
					  out.checkerboard = in.checkerboard;
 | 
				
			||||||
 | 
					  Dhop(in, out, DaggerYes);
 | 
				
			||||||
 | 
					  return axpy_norm(out, 4 + mass, in, out);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					template <class Impl>
 | 
				
			||||||
 | 
					void WilsonFermion<Impl>::Meooe(const FermionField &in, FermionField &out) {
 | 
				
			||||||
 | 
					  if (in.checkerboard == Odd) {
 | 
				
			||||||
 | 
					    DhopEO(in, out, DaggerNo);
 | 
				
			||||||
 | 
					  } else {
 | 
				
			||||||
 | 
					    DhopOE(in, out, DaggerNo);
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
  template<class Impl>
 | 
					template <class Impl>
 | 
				
			||||||
  void WilsonFermion<Impl>::ImportGauge(const GaugeField &_Umu)
 | 
					void WilsonFermion<Impl>::MeooeDag(const FermionField &in, FermionField &out) {
 | 
				
			||||||
  {
 | 
					  if (in.checkerboard == Odd) {
 | 
				
			||||||
    GaugeField HUmu(_Umu._grid);
 | 
					    DhopEO(in, out, DaggerYes);
 | 
				
			||||||
    HUmu = _Umu*(-0.5);
 | 
					  } else {
 | 
				
			||||||
    Impl::DoubleStore(GaugeGrid(),Umu,HUmu);
 | 
					    DhopOE(in, out, DaggerYes);
 | 
				
			||||||
    pickCheckerboard(Even,UmuEven,Umu);
 | 
					 | 
				
			||||||
    pickCheckerboard(Odd ,UmuOdd,Umu);
 | 
					 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  /////////////////////////////
 | 
					template <class Impl>
 | 
				
			||||||
  // Implement the interface
 | 
					void WilsonFermion<Impl>::Mooee(const FermionField &in, FermionField &out) {
 | 
				
			||||||
  /////////////////////////////
 | 
					  out.checkerboard = in.checkerboard;
 | 
				
			||||||
 | 
					  typename FermionField::scalar_type scal(4.0 + mass);
 | 
				
			||||||
 | 
					  out = scal * in;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  template<class Impl>
 | 
					template <class Impl>
 | 
				
			||||||
  RealD WilsonFermion<Impl>::M(const FermionField &in, FermionField &out) 
 | 
					void WilsonFermion<Impl>::MooeeDag(const FermionField &in, FermionField &out) {
 | 
				
			||||||
  {
 | 
					  out.checkerboard = in.checkerboard;
 | 
				
			||||||
    out.checkerboard=in.checkerboard;
 | 
					  Mooee(in, out);
 | 
				
			||||||
    Dhop(in,out,DaggerNo);
 | 
					}
 | 
				
			||||||
    return axpy_norm(out,4+mass,in,out);
 | 
					
 | 
				
			||||||
 | 
					template <class Impl>
 | 
				
			||||||
 | 
					void WilsonFermion<Impl>::MooeeInv(const FermionField &in, FermionField &out) {
 | 
				
			||||||
 | 
					  out.checkerboard = in.checkerboard;
 | 
				
			||||||
 | 
					  out = (1.0 / (4.0 + mass)) * in;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					template <class Impl>
 | 
				
			||||||
 | 
					void WilsonFermion<Impl>::MooeeInvDag(const FermionField &in,
 | 
				
			||||||
 | 
					                                      FermionField &out) {
 | 
				
			||||||
 | 
					  out.checkerboard = in.checkerboard;
 | 
				
			||||||
 | 
					  MooeeInv(in, out);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					///////////////////////////////////
 | 
				
			||||||
 | 
					// Internal
 | 
				
			||||||
 | 
					///////////////////////////////////
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					template <class Impl>
 | 
				
			||||||
 | 
					void WilsonFermion<Impl>::DerivInternal(StencilImpl &st, DoubledGaugeField &U,
 | 
				
			||||||
 | 
					                                        GaugeField &mat, const FermionField &A,
 | 
				
			||||||
 | 
					                                        const FermionField &B, int dag) {
 | 
				
			||||||
 | 
					  assert((dag == DaggerNo) || (dag == DaggerYes));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  Compressor compressor(dag);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  FermionField Btilde(B._grid);
 | 
				
			||||||
 | 
					  FermionField Atilde(B._grid);
 | 
				
			||||||
 | 
					  Atilde = A;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  st.HaloExchange(B, compressor);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  for (int mu = 0; mu < Nd; mu++) {
 | 
				
			||||||
 | 
					    ////////////////////////////////////////////////////////////////////////
 | 
				
			||||||
 | 
					    // Flip gamma (1+g)<->(1-g) if dag
 | 
				
			||||||
 | 
					    ////////////////////////////////////////////////////////////////////////
 | 
				
			||||||
 | 
					    int gamma = mu;
 | 
				
			||||||
 | 
					    if (!dag) gamma += Nd;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    ////////////////////////
 | 
				
			||||||
 | 
					    // Call the single hop
 | 
				
			||||||
 | 
					    ////////////////////////
 | 
				
			||||||
 | 
					    PARALLEL_FOR_LOOP
 | 
				
			||||||
 | 
					    for (int sss = 0; sss < B._grid->oSites(); sss++) {
 | 
				
			||||||
 | 
					      Kernels::DiracOptDhopDir(st, U, st.comm_buf, sss, sss, B, Btilde, mu,
 | 
				
			||||||
 | 
					                               gamma);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    //////////////////////////////////////////////////
 | 
				
			||||||
 | 
					    // spin trace outer product
 | 
				
			||||||
 | 
					    //////////////////////////////////////////////////
 | 
				
			||||||
 | 
					    Impl::InsertForce4D(mat, Btilde, Atilde, mu);
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  template<class Impl>
 | 
					template <class Impl>
 | 
				
			||||||
  RealD WilsonFermion<Impl>::Mdag(const FermionField &in, FermionField &out) 
 | 
					void WilsonFermion<Impl>::DhopDeriv(GaugeField &mat, const FermionField &U,
 | 
				
			||||||
  {
 | 
					                                    const FermionField &V, int dag) {
 | 
				
			||||||
    out.checkerboard=in.checkerboard;
 | 
					  conformable(U._grid, _grid);
 | 
				
			||||||
    Dhop(in,out,DaggerYes);
 | 
					  conformable(U._grid, V._grid);
 | 
				
			||||||
    return axpy_norm(out,4+mass,in,out);
 | 
					  conformable(U._grid, mat._grid);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  mat.checkerboard = U.checkerboard;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  DerivInternal(Stencil, Umu, mat, U, V, dag);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					template <class Impl>
 | 
				
			||||||
 | 
					void WilsonFermion<Impl>::DhopDerivOE(GaugeField &mat, const FermionField &U,
 | 
				
			||||||
 | 
					                                      const FermionField &V, int dag) {
 | 
				
			||||||
 | 
					  conformable(U._grid, _cbgrid);
 | 
				
			||||||
 | 
					  conformable(U._grid, V._grid);
 | 
				
			||||||
 | 
					  conformable(U._grid, mat._grid);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  assert(V.checkerboard == Even);
 | 
				
			||||||
 | 
					  assert(U.checkerboard == Odd);
 | 
				
			||||||
 | 
					  mat.checkerboard = Odd;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  DerivInternal(StencilEven, UmuOdd, mat, U, V, dag);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					template <class Impl>
 | 
				
			||||||
 | 
					void WilsonFermion<Impl>::DhopDerivEO(GaugeField &mat, const FermionField &U,
 | 
				
			||||||
 | 
					                                      const FermionField &V, int dag) {
 | 
				
			||||||
 | 
					  conformable(U._grid, _cbgrid);
 | 
				
			||||||
 | 
					  conformable(U._grid, V._grid);
 | 
				
			||||||
 | 
					  conformable(U._grid, mat._grid);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  assert(V.checkerboard == Odd);
 | 
				
			||||||
 | 
					  assert(U.checkerboard == Even);
 | 
				
			||||||
 | 
					  mat.checkerboard = Even;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  DerivInternal(StencilOdd, UmuEven, mat, U, V, dag);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					template <class Impl>
 | 
				
			||||||
 | 
					void WilsonFermion<Impl>::Dhop(const FermionField &in, FermionField &out,
 | 
				
			||||||
 | 
					                               int dag) {
 | 
				
			||||||
 | 
					  conformable(in._grid, _grid);  // verifies full grid
 | 
				
			||||||
 | 
					  conformable(in._grid, out._grid);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  out.checkerboard = in.checkerboard;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  DhopInternal(Stencil, Lebesgue, Umu, in, out, dag);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					template <class Impl>
 | 
				
			||||||
 | 
					void WilsonFermion<Impl>::DhopOE(const FermionField &in, FermionField &out,
 | 
				
			||||||
 | 
					                                 int dag) {
 | 
				
			||||||
 | 
					  conformable(in._grid, _cbgrid);    // verifies half grid
 | 
				
			||||||
 | 
					  conformable(in._grid, out._grid);  // drops the cb check
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  assert(in.checkerboard == Even);
 | 
				
			||||||
 | 
					  out.checkerboard = Odd;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  DhopInternal(StencilEven, LebesgueEvenOdd, UmuOdd, in, out, dag);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					template <class Impl>
 | 
				
			||||||
 | 
					void WilsonFermion<Impl>::DhopEO(const FermionField &in, FermionField &out,
 | 
				
			||||||
 | 
					                                 int dag) {
 | 
				
			||||||
 | 
					  conformable(in._grid, _cbgrid);    // verifies half grid
 | 
				
			||||||
 | 
					  conformable(in._grid, out._grid);  // drops the cb check
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  assert(in.checkerboard == Odd);
 | 
				
			||||||
 | 
					  out.checkerboard = Even;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  DhopInternal(StencilOdd, LebesgueEvenOdd, UmuEven, in, out, dag);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					template <class Impl>
 | 
				
			||||||
 | 
					void WilsonFermion<Impl>::Mdir(const FermionField &in, FermionField &out,
 | 
				
			||||||
 | 
					                               int dir, int disp) {
 | 
				
			||||||
 | 
					  DhopDir(in, out, dir, disp);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					template <class Impl>
 | 
				
			||||||
 | 
					void WilsonFermion<Impl>::DhopDir(const FermionField &in, FermionField &out,
 | 
				
			||||||
 | 
					                                  int dir, int disp) {
 | 
				
			||||||
 | 
					  int skip = (disp == 1) ? 0 : 1;
 | 
				
			||||||
 | 
					  int dirdisp = dir + skip * 4;
 | 
				
			||||||
 | 
					  int gamma = dir + (1 - skip) * 4;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  DhopDirDisp(in, out, dirdisp, gamma, DaggerNo);
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					template <class Impl>
 | 
				
			||||||
 | 
					void WilsonFermion<Impl>::DhopDirDisp(const FermionField &in, FermionField &out,
 | 
				
			||||||
 | 
					                                      int dirdisp, int gamma, int dag) {
 | 
				
			||||||
 | 
					  Compressor compressor(dag);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  Stencil.HaloExchange(in, compressor);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  PARALLEL_FOR_LOOP
 | 
				
			||||||
 | 
					  for (int sss = 0; sss < in._grid->oSites(); sss++) {
 | 
				
			||||||
 | 
					    Kernels::DiracOptDhopDir(Stencil, Umu, Stencil.comm_buf, sss, sss, in, out,
 | 
				
			||||||
 | 
					                             dirdisp, gamma);
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  template<class Impl>
 | 
					template <class Impl>
 | 
				
			||||||
  void WilsonFermion<Impl>::Meooe(const FermionField &in, FermionField &out) 
 | 
					void WilsonFermion<Impl>::DhopInternal(StencilImpl &st, LebesgueOrder &lo,
 | 
				
			||||||
  {
 | 
					                                       DoubledGaugeField &U,
 | 
				
			||||||
    if ( in.checkerboard == Odd ) {
 | 
					                                       const FermionField &in,
 | 
				
			||||||
      DhopEO(in,out,DaggerNo);
 | 
					                                       FermionField &out, int dag) {
 | 
				
			||||||
    } else {
 | 
					  assert((dag == DaggerNo) || (dag == DaggerYes));
 | 
				
			||||||
      DhopOE(in,out,DaggerNo);
 | 
					
 | 
				
			||||||
    }
 | 
					  Compressor compressor(dag);
 | 
				
			||||||
  }
 | 
					  st.HaloExchange(in, compressor);
 | 
				
			||||||
  template<class Impl>
 | 
					
 | 
				
			||||||
  void WilsonFermion<Impl>::MeooeDag(const FermionField &in, FermionField &out) 
 | 
					  if (dag == DaggerYes) {
 | 
				
			||||||
  {
 | 
					    PARALLEL_FOR_LOOP
 | 
				
			||||||
    if ( in.checkerboard == Odd ) {
 | 
					    for (int sss = 0; sss < in._grid->oSites(); sss++) {
 | 
				
			||||||
      DhopEO(in,out,DaggerYes);
 | 
					      Kernels::DiracOptDhopSiteDag(st, lo, U, st.comm_buf, sss, sss, 1, 1, in,
 | 
				
			||||||
    } else {
 | 
					                                   out);
 | 
				
			||||||
      DhopOE(in,out,DaggerYes);
 | 
					    }
 | 
				
			||||||
 | 
					  } else {
 | 
				
			||||||
 | 
					    PARALLEL_FOR_LOOP
 | 
				
			||||||
 | 
					    for (int sss = 0; sss < in._grid->oSites(); sss++) {
 | 
				
			||||||
 | 
					      Kernels::DiracOptDhopSite(st, lo, U, st.comm_buf, sss, sss, 1, 1, in,
 | 
				
			||||||
 | 
					                                out);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  template<class Impl>
 | 
					FermOpTemplateInstantiate(WilsonFermion);
 | 
				
			||||||
  void WilsonFermion<Impl>::Mooee(const FermionField &in, FermionField &out) {
 | 
					AdjointFermOpTemplateInstantiate(WilsonFermion);
 | 
				
			||||||
    out.checkerboard = in.checkerboard;
 | 
					TwoIndexFermOpTemplateInstantiate(WilsonFermion);
 | 
				
			||||||
    typename FermionField::scalar_type scal(4.0+mass);
 | 
					GparityFermOpTemplateInstantiate(WilsonFermion);
 | 
				
			||||||
    out = scal*in;
 | 
					}
 | 
				
			||||||
  }
 | 
					}
 | 
				
			||||||
  
 | 
					 | 
				
			||||||
  template<class Impl>
 | 
					 | 
				
			||||||
  void WilsonFermion<Impl>::MooeeDag(const FermionField &in, FermionField &out) {
 | 
					 | 
				
			||||||
    out.checkerboard = in.checkerboard;
 | 
					 | 
				
			||||||
    Mooee(in,out);
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
  
 | 
					 | 
				
			||||||
  template<class Impl>
 | 
					 | 
				
			||||||
  void WilsonFermion<Impl>::MooeeInv(const FermionField &in, FermionField &out) {
 | 
					 | 
				
			||||||
    out.checkerboard = in.checkerboard;
 | 
					 | 
				
			||||||
    out = (1.0/(4.0+mass))*in;
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
  
 | 
					 | 
				
			||||||
  template<class Impl>
 | 
					 | 
				
			||||||
  void WilsonFermion<Impl>::MooeeInvDag(const FermionField &in, FermionField &out) {
 | 
					 | 
				
			||||||
    out.checkerboard = in.checkerboard;
 | 
					 | 
				
			||||||
    MooeeInv(in,out);
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
  
 | 
					 | 
				
			||||||
  ///////////////////////////////////
 | 
					 | 
				
			||||||
  // Internal
 | 
					 | 
				
			||||||
  ///////////////////////////////////
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  template<class Impl>
 | 
					 | 
				
			||||||
  void WilsonFermion<Impl>::DerivInternal(StencilImpl & st,
 | 
					 | 
				
			||||||
					  DoubledGaugeField & U,
 | 
					 | 
				
			||||||
					  GaugeField &mat,
 | 
					 | 
				
			||||||
					  const FermionField &A,
 | 
					 | 
				
			||||||
					  const FermionField &B,int dag) {
 | 
					 | 
				
			||||||
	
 | 
					 | 
				
			||||||
    assert((dag==DaggerNo) ||(dag==DaggerYes));
 | 
					 | 
				
			||||||
    
 | 
					 | 
				
			||||||
    Compressor compressor(dag);
 | 
					 | 
				
			||||||
    
 | 
					 | 
				
			||||||
    FermionField Btilde(B._grid);
 | 
					 | 
				
			||||||
    FermionField Atilde(B._grid);
 | 
					 | 
				
			||||||
    Atilde = A;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    st.HaloExchange(B,compressor);
 | 
					 | 
				
			||||||
    
 | 
					 | 
				
			||||||
    for(int mu=0;mu<Nd;mu++){
 | 
					 | 
				
			||||||
      
 | 
					 | 
				
			||||||
      ////////////////////////////////////////////////////////////////////////
 | 
					 | 
				
			||||||
      // Flip gamma (1+g)<->(1-g) if dag
 | 
					 | 
				
			||||||
      ////////////////////////////////////////////////////////////////////////
 | 
					 | 
				
			||||||
      int gamma = mu;
 | 
					 | 
				
			||||||
      if ( !dag ) gamma+= Nd;
 | 
					 | 
				
			||||||
      
 | 
					 | 
				
			||||||
      ////////////////////////
 | 
					 | 
				
			||||||
      // Call the single hop
 | 
					 | 
				
			||||||
      ////////////////////////
 | 
					 | 
				
			||||||
PARALLEL_FOR_LOOP
 | 
					 | 
				
			||||||
	for(int sss=0;sss<B._grid->oSites();sss++){
 | 
					 | 
				
			||||||
	  Kernels::DiracOptDhopDir(st,U,st.comm_buf,sss,sss,B,Btilde,mu,gamma);
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
      
 | 
					 | 
				
			||||||
      //////////////////////////////////////////////////
 | 
					 | 
				
			||||||
      // spin trace outer product
 | 
					 | 
				
			||||||
      //////////////////////////////////////////////////
 | 
					 | 
				
			||||||
      Impl::InsertForce4D(mat,Btilde,Atilde,mu);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
  
 | 
					 | 
				
			||||||
  template<class Impl>
 | 
					 | 
				
			||||||
  void WilsonFermion<Impl>::DhopDeriv(GaugeField &mat,const FermionField &U,const FermionField &V,int dag)
 | 
					 | 
				
			||||||
  {
 | 
					 | 
				
			||||||
    conformable(U._grid,_grid);  
 | 
					 | 
				
			||||||
    conformable(U._grid,V._grid);
 | 
					 | 
				
			||||||
    conformable(U._grid,mat._grid);
 | 
					 | 
				
			||||||
    
 | 
					 | 
				
			||||||
    mat.checkerboard = U.checkerboard;
 | 
					 | 
				
			||||||
    
 | 
					 | 
				
			||||||
    DerivInternal(Stencil,Umu,mat,U,V,dag);
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
  
 | 
					 | 
				
			||||||
  template<class Impl>
 | 
					 | 
				
			||||||
  void WilsonFermion<Impl>::DhopDerivOE(GaugeField &mat,const FermionField &U,const FermionField &V,int dag)
 | 
					 | 
				
			||||||
  {
 | 
					 | 
				
			||||||
    conformable(U._grid,_cbgrid);  
 | 
					 | 
				
			||||||
    conformable(U._grid,V._grid);
 | 
					 | 
				
			||||||
    conformable(U._grid,mat._grid);
 | 
					 | 
				
			||||||
    
 | 
					 | 
				
			||||||
    assert(V.checkerboard==Even);
 | 
					 | 
				
			||||||
    assert(U.checkerboard==Odd);
 | 
					 | 
				
			||||||
    mat.checkerboard = Odd;
 | 
					 | 
				
			||||||
    
 | 
					 | 
				
			||||||
    DerivInternal(StencilEven,UmuOdd,mat,U,V,dag);
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
  
 | 
					 | 
				
			||||||
  template<class Impl>
 | 
					 | 
				
			||||||
  void WilsonFermion<Impl>::DhopDerivEO(GaugeField &mat,const FermionField &U,const FermionField &V,int dag)
 | 
					 | 
				
			||||||
  {
 | 
					 | 
				
			||||||
    conformable(U._grid,_cbgrid);  
 | 
					 | 
				
			||||||
    conformable(U._grid,V._grid);
 | 
					 | 
				
			||||||
    conformable(U._grid,mat._grid);
 | 
					 | 
				
			||||||
	
 | 
					 | 
				
			||||||
    assert(V.checkerboard==Odd);
 | 
					 | 
				
			||||||
    assert(U.checkerboard==Even);
 | 
					 | 
				
			||||||
    mat.checkerboard = Even;
 | 
					 | 
				
			||||||
	
 | 
					 | 
				
			||||||
    DerivInternal(StencilOdd,UmuEven,mat,U,V,dag);
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
  
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  template<class Impl>
 | 
					 | 
				
			||||||
  void WilsonFermion<Impl>::Dhop(const FermionField &in, FermionField &out,int dag) {
 | 
					 | 
				
			||||||
    conformable(in._grid,_grid); // verifies full grid
 | 
					 | 
				
			||||||
    conformable(in._grid,out._grid);
 | 
					 | 
				
			||||||
    
 | 
					 | 
				
			||||||
    out.checkerboard = in.checkerboard;
 | 
					 | 
				
			||||||
    
 | 
					 | 
				
			||||||
    DhopInternal(Stencil,Lebesgue,Umu,in,out,dag);
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
  
 | 
					 | 
				
			||||||
  template<class Impl>
 | 
					 | 
				
			||||||
  void WilsonFermion<Impl>::DhopOE(const FermionField &in, FermionField &out,int dag) {
 | 
					 | 
				
			||||||
    conformable(in._grid,_cbgrid);    // verifies half grid
 | 
					 | 
				
			||||||
    conformable(in._grid,out._grid); // drops the cb check
 | 
					 | 
				
			||||||
    
 | 
					 | 
				
			||||||
    assert(in.checkerboard==Even);
 | 
					 | 
				
			||||||
    out.checkerboard = Odd;
 | 
					 | 
				
			||||||
    
 | 
					 | 
				
			||||||
    DhopInternal(StencilEven,LebesgueEvenOdd,UmuOdd,in,out,dag);
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
  
 | 
					 | 
				
			||||||
  template<class Impl>
 | 
					 | 
				
			||||||
  void WilsonFermion<Impl>::DhopEO(const FermionField &in, FermionField &out,int dag) {
 | 
					 | 
				
			||||||
    conformable(in._grid,_cbgrid);    // verifies half grid
 | 
					 | 
				
			||||||
    conformable(in._grid,out._grid); // drops the cb check
 | 
					 | 
				
			||||||
    
 | 
					 | 
				
			||||||
    assert(in.checkerboard==Odd);
 | 
					 | 
				
			||||||
    out.checkerboard = Even;
 | 
					 | 
				
			||||||
    
 | 
					 | 
				
			||||||
    DhopInternal(StencilOdd,LebesgueEvenOdd,UmuEven,in,out,dag);
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
  
 | 
					 | 
				
			||||||
  template<class Impl>
 | 
					 | 
				
			||||||
  void WilsonFermion<Impl>::Mdir (const FermionField &in, FermionField &out,int dir,int disp) {
 | 
					 | 
				
			||||||
    DhopDir(in,out,dir,disp);
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
  
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  template<class Impl>
 | 
					 | 
				
			||||||
  void WilsonFermion<Impl>::DhopDir(const FermionField &in, FermionField &out,int dir,int disp){
 | 
					 | 
				
			||||||
    
 | 
					 | 
				
			||||||
    int skip = (disp==1) ? 0 : 1;
 | 
					 | 
				
			||||||
    int dirdisp  = dir+skip*4;
 | 
					 | 
				
			||||||
    int gamma    = dir+(1-skip)*4;
 | 
					 | 
				
			||||||
    
 | 
					 | 
				
			||||||
    DhopDirDisp(in,out,dirdisp,gamma,DaggerNo);
 | 
					 | 
				
			||||||
    
 | 
					 | 
				
			||||||
  };
 | 
					 | 
				
			||||||
  
 | 
					 | 
				
			||||||
  template<class Impl>
 | 
					 | 
				
			||||||
  void WilsonFermion<Impl>::DhopDirDisp(const FermionField &in, FermionField &out,int dirdisp,int gamma,int dag) {
 | 
					 | 
				
			||||||
    
 | 
					 | 
				
			||||||
    Compressor compressor(dag);
 | 
					 | 
				
			||||||
    
 | 
					 | 
				
			||||||
    Stencil.HaloExchange(in,compressor);
 | 
					 | 
				
			||||||
    
 | 
					 | 
				
			||||||
PARALLEL_FOR_LOOP
 | 
					 | 
				
			||||||
      for(int sss=0;sss<in._grid->oSites();sss++){
 | 
					 | 
				
			||||||
	Kernels::DiracOptDhopDir(Stencil,Umu,Stencil.comm_buf,sss,sss,in,out,dirdisp,gamma);
 | 
					 | 
				
			||||||
      }
 | 
					 | 
				
			||||||
    
 | 
					 | 
				
			||||||
  };
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  template<class Impl>
 | 
					 | 
				
			||||||
  void WilsonFermion<Impl>::DhopInternal(StencilImpl & st,LebesgueOrder& lo,DoubledGaugeField & U,
 | 
					 | 
				
			||||||
					 const FermionField &in, FermionField &out,int dag) 
 | 
					 | 
				
			||||||
  {
 | 
					 | 
				
			||||||
    assert((dag==DaggerNo) ||(dag==DaggerYes));
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    Compressor compressor(dag);
 | 
					 | 
				
			||||||
    st.HaloExchange(in,compressor);
 | 
					 | 
				
			||||||
    
 | 
					 | 
				
			||||||
    if ( dag == DaggerYes ) {
 | 
					 | 
				
			||||||
PARALLEL_FOR_LOOP
 | 
					 | 
				
			||||||
      for(int sss=0;sss<in._grid->oSites();sss++){
 | 
					 | 
				
			||||||
	Kernels::DiracOptDhopSiteDag(st,lo,U,st.comm_buf,sss,sss,1,1,in,out);
 | 
					 | 
				
			||||||
      }
 | 
					 | 
				
			||||||
    } else {
 | 
					 | 
				
			||||||
PARALLEL_FOR_LOOP
 | 
					 | 
				
			||||||
      for(int sss=0;sss<in._grid->oSites();sss++){
 | 
					 | 
				
			||||||
	Kernels::DiracOptDhopSite(st,lo,U,st.comm_buf,sss,sss,1,1,in,out);
 | 
					 | 
				
			||||||
      }
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
  };
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 
 | 
					 | 
				
			||||||
  FermOpTemplateInstantiate(WilsonFermion);
 | 
					 | 
				
			||||||
  GparityFermOpTemplateInstantiate(WilsonFermion);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
}}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,161 +1,155 @@
 | 
				
			|||||||
    /*************************************************************************************
 | 
					/*************************************************************************************
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    Grid physics library, www.github.com/paboyle/Grid 
 | 
					Grid physics library, www.github.com/paboyle/Grid
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    Source file: ./lib/qcd/action/fermion/WilsonFermion.h
 | 
					Source file: ./lib/qcd/action/fermion/WilsonFermion.h
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    Copyright (C) 2015
 | 
					Copyright (C) 2015
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Author: Peter Boyle <pabobyle@ph.ed.ac.uk>
 | 
					Author: Peter Boyle <pabobyle@ph.ed.ac.uk>
 | 
				
			||||||
Author: Peter Boyle <paboyle@ph.ed.ac.uk>
 | 
					Author: Peter Boyle <paboyle@ph.ed.ac.uk>
 | 
				
			||||||
Author: paboyle <paboyle@ph.ed.ac.uk>
 | 
					Author: paboyle <paboyle@ph.ed.ac.uk>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    This program is free software; you can redistribute it and/or modify
 | 
					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
 | 
					it under the terms of the GNU General Public License as published by
 | 
				
			||||||
    the Free Software Foundation; either version 2 of the License, or
 | 
					the Free Software Foundation; either version 2 of the License, or
 | 
				
			||||||
    (at your option) any later version.
 | 
					(at your option) any later version.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    This program is distributed in the hope that it will be useful,
 | 
					This program is distributed in the hope that it will be useful,
 | 
				
			||||||
    but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
					but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
				
			||||||
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
					MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
				
			||||||
    GNU General Public License for more details.
 | 
					GNU General Public License for more details.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    You should have received a copy of the GNU General Public License along
 | 
					You should have received a copy of the GNU General Public License along
 | 
				
			||||||
    with this program; if not, write to the Free Software Foundation, Inc.,
 | 
					with this program; if not, write to the Free Software Foundation, Inc.,
 | 
				
			||||||
    51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 | 
					51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    See the full license in the file "LICENSE" in the top level distribution directory
 | 
					See the full license in the file "LICENSE" in the top level distribution
 | 
				
			||||||
    *************************************************************************************/
 | 
					directory
 | 
				
			||||||
    /*  END LEGAL */
 | 
					*************************************************************************************/
 | 
				
			||||||
#ifndef  GRID_QCD_WILSON_FERMION_H
 | 
					/*  END LEGAL */
 | 
				
			||||||
#define  GRID_QCD_WILSON_FERMION_H
 | 
					#ifndef GRID_QCD_WILSON_FERMION_H
 | 
				
			||||||
 | 
					#define GRID_QCD_WILSON_FERMION_H
 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace Grid {
 | 
					namespace Grid {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  namespace QCD {
 | 
					namespace QCD {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    class WilsonFermionStatic {
 | 
					class WilsonFermionStatic {
 | 
				
			||||||
    public:
 | 
					 public:
 | 
				
			||||||
      static int HandOptDslash; // these are a temporary hack
 | 
					  static int HandOptDslash;  // these are a temporary hack
 | 
				
			||||||
      static int MortonOrder;
 | 
					  static int MortonOrder;
 | 
				
			||||||
      static const std::vector<int> directions   ;
 | 
					  static const std::vector<int> directions;
 | 
				
			||||||
      static const std::vector<int> displacements;
 | 
					  static const std::vector<int> displacements;
 | 
				
			||||||
      static const int npoint=8;
 | 
					  static const int npoint = 8;
 | 
				
			||||||
    };
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    template<class Impl>
 | 
					template <class Impl>
 | 
				
			||||||
    class WilsonFermion : public WilsonKernels<Impl>, public WilsonFermionStatic
 | 
					class WilsonFermion : public WilsonKernels<Impl>, public WilsonFermionStatic {
 | 
				
			||||||
    {
 | 
					 public:
 | 
				
			||||||
    public:
 | 
					  INHERIT_IMPL_TYPES(Impl);
 | 
				
			||||||
    INHERIT_IMPL_TYPES(Impl);
 | 
					  typedef WilsonKernels<Impl> Kernels;
 | 
				
			||||||
    typedef WilsonKernels<Impl> Kernels;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
      ///////////////////////////////////////////////////////////////
 | 
					  ///////////////////////////////////////////////////////////////
 | 
				
			||||||
      // Implement the abstract base
 | 
					  // Implement the abstract base
 | 
				
			||||||
      ///////////////////////////////////////////////////////////////
 | 
					  ///////////////////////////////////////////////////////////////
 | 
				
			||||||
      GridBase *GaugeGrid(void)              { return _grid ;}
 | 
					  GridBase *GaugeGrid(void) { return _grid; }
 | 
				
			||||||
      GridBase *GaugeRedBlackGrid(void)      { return _cbgrid ;}
 | 
					  GridBase *GaugeRedBlackGrid(void) { return _cbgrid; }
 | 
				
			||||||
      GridBase *FermionGrid(void)            { return _grid;}
 | 
					  GridBase *FermionGrid(void) { return _grid; }
 | 
				
			||||||
      GridBase *FermionRedBlackGrid(void)    { return _cbgrid;}
 | 
					  GridBase *FermionRedBlackGrid(void) { return _cbgrid; }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      //////////////////////////////////////////////////////////////////
 | 
					  //////////////////////////////////////////////////////////////////
 | 
				
			||||||
      // override multiply; cut number routines if pass dagger argument
 | 
					  // override multiply; cut number routines if pass dagger argument
 | 
				
			||||||
      // and also make interface more uniformly consistent
 | 
					  // and also make interface more uniformly consistent
 | 
				
			||||||
      //////////////////////////////////////////////////////////////////
 | 
					  //////////////////////////////////////////////////////////////////
 | 
				
			||||||
      RealD M(const FermionField &in, FermionField &out);
 | 
					  RealD M(const FermionField &in, FermionField &out);
 | 
				
			||||||
      RealD Mdag(const FermionField &in, FermionField &out);
 | 
					  RealD Mdag(const FermionField &in, FermionField &out);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      /////////////////////////////////////////////////////////
 | 
					  /////////////////////////////////////////////////////////
 | 
				
			||||||
      // half checkerboard operations
 | 
					  // half checkerboard operations
 | 
				
			||||||
      // could remain virtual so we  can derive Clover from Wilson base
 | 
					  // could remain virtual so we  can derive Clover from Wilson base
 | 
				
			||||||
      /////////////////////////////////////////////////////////
 | 
					  /////////////////////////////////////////////////////////
 | 
				
			||||||
      void Meooe(const FermionField &in, FermionField &out) ;
 | 
					  void Meooe(const FermionField &in, FermionField &out);
 | 
				
			||||||
      void MeooeDag(const FermionField &in, FermionField &out) ;
 | 
					  void MeooeDag(const FermionField &in, FermionField &out);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      // allow override for twisted mass and clover
 | 
					  // allow override for twisted mass and clover
 | 
				
			||||||
      virtual void Mooee(const FermionField &in, FermionField &out) ;
 | 
					  virtual void Mooee(const FermionField &in, FermionField &out);
 | 
				
			||||||
      virtual void MooeeDag(const FermionField &in, FermionField &out) ;
 | 
					  virtual void MooeeDag(const FermionField &in, FermionField &out);
 | 
				
			||||||
      virtual void MooeeInv(const FermionField &in, FermionField &out) ;
 | 
					  virtual void MooeeInv(const FermionField &in, FermionField &out);
 | 
				
			||||||
      virtual void MooeeInvDag(const FermionField &in, FermionField &out) ;
 | 
					  virtual void MooeeInvDag(const FermionField &in, FermionField &out);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      ////////////////////////
 | 
					  ////////////////////////
 | 
				
			||||||
      // Derivative interface
 | 
					  // Derivative interface
 | 
				
			||||||
      ////////////////////////
 | 
					  ////////////////////////
 | 
				
			||||||
      // Interface calls an internal routine
 | 
					  // Interface calls an internal routine
 | 
				
			||||||
      void DhopDeriv(GaugeField &mat,const FermionField &U,const FermionField &V,int dag);
 | 
					  void DhopDeriv(GaugeField &mat, const FermionField &U, const FermionField &V,
 | 
				
			||||||
      void DhopDerivOE(GaugeField &mat,const FermionField &U,const FermionField &V,int dag);
 | 
					                 int dag);
 | 
				
			||||||
      void DhopDerivEO(GaugeField &mat,const FermionField &U,const FermionField &V,int dag);
 | 
					  void DhopDerivOE(GaugeField &mat, const FermionField &U,
 | 
				
			||||||
 | 
					                   const FermionField &V, int dag);
 | 
				
			||||||
 | 
					  void DhopDerivEO(GaugeField &mat, const FermionField &U,
 | 
				
			||||||
 | 
					                   const FermionField &V, int dag);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  ///////////////////////////////////////////////////////////////
 | 
				
			||||||
 | 
					  // non-hermitian hopping term; half cb or both
 | 
				
			||||||
 | 
					  ///////////////////////////////////////////////////////////////
 | 
				
			||||||
 | 
					  void Dhop(const FermionField &in, FermionField &out, int dag);
 | 
				
			||||||
 | 
					  void DhopOE(const FermionField &in, FermionField &out, int dag);
 | 
				
			||||||
 | 
					  void DhopEO(const FermionField &in, FermionField &out, int dag);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  ///////////////////////////////////////////////////////////////
 | 
				
			||||||
 | 
					  // Multigrid assistance; force term uses too
 | 
				
			||||||
 | 
					  ///////////////////////////////////////////////////////////////
 | 
				
			||||||
 | 
					  void Mdir(const FermionField &in, FermionField &out, int dir, int disp);
 | 
				
			||||||
 | 
					  void DhopDir(const FermionField &in, FermionField &out, int dir, int disp);
 | 
				
			||||||
 | 
					  void DhopDirDisp(const FermionField &in, FermionField &out, int dirdisp,
 | 
				
			||||||
 | 
					                   int gamma, int dag);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  ///////////////////////////////////////////////////////////////
 | 
				
			||||||
 | 
					  // Extra methods added by derived
 | 
				
			||||||
 | 
					  ///////////////////////////////////////////////////////////////
 | 
				
			||||||
 | 
					  void DerivInternal(StencilImpl &st, DoubledGaugeField &U, GaugeField &mat,
 | 
				
			||||||
 | 
					                     const FermionField &A, const FermionField &B, int dag);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  void DhopInternal(StencilImpl &st, LebesgueOrder &lo, DoubledGaugeField &U,
 | 
				
			||||||
 | 
					                    const FermionField &in, FermionField &out, int dag);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // Constructor
 | 
				
			||||||
 | 
					  WilsonFermion(GaugeField &_Umu, GridCartesian &Fgrid,
 | 
				
			||||||
 | 
					                GridRedBlackCartesian &Hgrid, RealD _mass,
 | 
				
			||||||
 | 
					                const ImplParams &p = ImplParams());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // DoubleStore impl dependent
 | 
				
			||||||
 | 
					  void ImportGauge(const GaugeField &_Umu);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  ///////////////////////////////////////////////////////////////
 | 
				
			||||||
 | 
					  // Data members require to support the functionality
 | 
				
			||||||
 | 
					  ///////////////////////////////////////////////////////////////
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  //    protected:
 | 
				
			||||||
 | 
					 public:
 | 
				
			||||||
 | 
					  RealD mass;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  GridBase *_grid;
 | 
				
			||||||
 | 
					  GridBase *_cbgrid;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // Defines the stencils for even and odd
 | 
				
			||||||
 | 
					  StencilImpl Stencil;
 | 
				
			||||||
 | 
					  StencilImpl StencilEven;
 | 
				
			||||||
 | 
					  StencilImpl StencilOdd;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // Copy of the gauge field , with even and odd subsets
 | 
				
			||||||
 | 
					  DoubledGaugeField Umu;
 | 
				
			||||||
 | 
					  DoubledGaugeField UmuEven;
 | 
				
			||||||
 | 
					  DoubledGaugeField UmuOdd;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  LebesgueOrder Lebesgue;
 | 
				
			||||||
 | 
					  LebesgueOrder LebesgueEvenOdd;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					typedef WilsonFermion<WilsonImplF> WilsonFermionF;
 | 
				
			||||||
 | 
					typedef WilsonFermion<WilsonImplD> WilsonFermionD;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      ///////////////////////////////////////////////////////////////
 | 
					}
 | 
				
			||||||
      // non-hermitian hopping term; half cb or both
 | 
					 | 
				
			||||||
      ///////////////////////////////////////////////////////////////
 | 
					 | 
				
			||||||
      void Dhop(const FermionField &in, FermionField &out,int dag) ;
 | 
					 | 
				
			||||||
      void DhopOE(const FermionField &in, FermionField &out,int dag) ;
 | 
					 | 
				
			||||||
      void DhopEO(const FermionField &in, FermionField &out,int dag) ;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
      ///////////////////////////////////////////////////////////////
 | 
					 | 
				
			||||||
      // Multigrid assistance; force term uses too
 | 
					 | 
				
			||||||
      ///////////////////////////////////////////////////////////////
 | 
					 | 
				
			||||||
      void Mdir (const FermionField &in, FermionField &out,int dir,int disp) ;
 | 
					 | 
				
			||||||
      void DhopDir(const FermionField &in, FermionField &out,int dir,int disp);
 | 
					 | 
				
			||||||
      void DhopDirDisp(const FermionField &in, FermionField &out,int dirdisp,int gamma,int dag) ;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
      ///////////////////////////////////////////////////////////////
 | 
					 | 
				
			||||||
      // Extra methods added by derived
 | 
					 | 
				
			||||||
      ///////////////////////////////////////////////////////////////
 | 
					 | 
				
			||||||
      void DerivInternal(StencilImpl & st,
 | 
					 | 
				
			||||||
			 DoubledGaugeField & U,
 | 
					 | 
				
			||||||
			 GaugeField &mat,
 | 
					 | 
				
			||||||
			 const FermionField &A,
 | 
					 | 
				
			||||||
			 const FermionField &B,
 | 
					 | 
				
			||||||
			 int dag);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
      void DhopInternal(StencilImpl & st,LebesgueOrder & lo,DoubledGaugeField & U,
 | 
					 | 
				
			||||||
			const FermionField &in, FermionField &out,int dag) ;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
      // Constructor
 | 
					 | 
				
			||||||
      WilsonFermion(GaugeField &_Umu,
 | 
					 | 
				
			||||||
		    GridCartesian         &Fgrid,
 | 
					 | 
				
			||||||
		    GridRedBlackCartesian &Hgrid, 
 | 
					 | 
				
			||||||
		    RealD _mass,
 | 
					 | 
				
			||||||
		    const ImplParams &p= ImplParams()
 | 
					 | 
				
			||||||
		    ) ;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
      // DoubleStore impl dependent
 | 
					 | 
				
			||||||
      void ImportGauge(const GaugeField &_Umu);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
      ///////////////////////////////////////////////////////////////
 | 
					 | 
				
			||||||
      // Data members require to support the functionality
 | 
					 | 
				
			||||||
      ///////////////////////////////////////////////////////////////
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
      //    protected:
 | 
					 | 
				
			||||||
    public:
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
      RealD                        mass;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
      GridBase                     *    _grid; 
 | 
					 | 
				
			||||||
      GridBase                     *  _cbgrid;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
      //Defines the stencils for even and odd
 | 
					 | 
				
			||||||
      StencilImpl Stencil; 
 | 
					 | 
				
			||||||
      StencilImpl StencilEven; 
 | 
					 | 
				
			||||||
      StencilImpl StencilOdd; 
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
      // Copy of the gauge field , with even and odd subsets
 | 
					 | 
				
			||||||
      DoubledGaugeField Umu;
 | 
					 | 
				
			||||||
      DoubledGaugeField UmuEven;
 | 
					 | 
				
			||||||
      DoubledGaugeField UmuOdd;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
      LebesgueOrder Lebesgue;
 | 
					 | 
				
			||||||
      LebesgueOrder LebesgueEvenOdd;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
      
 | 
					 | 
				
			||||||
    };
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    typedef WilsonFermion<WilsonImplF> WilsonFermionF;
 | 
					 | 
				
			||||||
    typedef WilsonFermion<WilsonImplD> WilsonFermionD;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -42,11 +42,11 @@ const std::vector<int> WilsonFermion5DStatic::displacements({1,1,1,1,-1,-1,-1,-1
 | 
				
			|||||||
  // 5d lattice for DWF.
 | 
					  // 5d lattice for DWF.
 | 
				
			||||||
template<class Impl>
 | 
					template<class Impl>
 | 
				
			||||||
WilsonFermion5D<Impl>::WilsonFermion5D(GaugeField &_Umu,
 | 
					WilsonFermion5D<Impl>::WilsonFermion5D(GaugeField &_Umu,
 | 
				
			||||||
				       GridCartesian         &FiveDimGrid,
 | 
					               GridCartesian         &FiveDimGrid,
 | 
				
			||||||
				       GridRedBlackCartesian &FiveDimRedBlackGrid,
 | 
					               GridRedBlackCartesian &FiveDimRedBlackGrid,
 | 
				
			||||||
				       GridCartesian         &FourDimGrid,
 | 
					               GridCartesian         &FourDimGrid,
 | 
				
			||||||
				       GridRedBlackCartesian &FourDimRedBlackGrid,
 | 
					               GridRedBlackCartesian &FourDimRedBlackGrid,
 | 
				
			||||||
				       RealD _M5,const ImplParams &p) :
 | 
					               RealD _M5,const ImplParams &p) :
 | 
				
			||||||
  Kernels(p),
 | 
					  Kernels(p),
 | 
				
			||||||
  _FiveDimGrid        (&FiveDimGrid),
 | 
					  _FiveDimGrid        (&FiveDimGrid),
 | 
				
			||||||
  _FiveDimRedBlackGrid(&FiveDimRedBlackGrid),
 | 
					  _FiveDimRedBlackGrid(&FiveDimRedBlackGrid),
 | 
				
			||||||
@@ -135,10 +135,10 @@ WilsonFermion5D<Impl>::WilsonFermion5D(GaugeField &_Umu,
 | 
				
			|||||||
  /*
 | 
					  /*
 | 
				
			||||||
template<class Impl>
 | 
					template<class Impl>
 | 
				
			||||||
WilsonFermion5D<Impl>::WilsonFermion5D(int simd,GaugeField &_Umu,
 | 
					WilsonFermion5D<Impl>::WilsonFermion5D(int simd,GaugeField &_Umu,
 | 
				
			||||||
				       GridCartesian         &FiveDimGrid,
 | 
					               GridCartesian         &FiveDimGrid,
 | 
				
			||||||
				       GridRedBlackCartesian &FiveDimRedBlackGrid,
 | 
					               GridRedBlackCartesian &FiveDimRedBlackGrid,
 | 
				
			||||||
				       GridCartesian         &FourDimGrid,
 | 
					               GridCartesian         &FourDimGrid,
 | 
				
			||||||
				       RealD _M5,const ImplParams &p) :
 | 
					               RealD _M5,const ImplParams &p) :
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
  int nsimd = Simd::Nsimd();
 | 
					  int nsimd = Simd::Nsimd();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -175,6 +175,73 @@ WilsonFermion5D<Impl>::WilsonFermion5D(int simd,GaugeField &_Umu,
 | 
				
			|||||||
}  
 | 
					}  
 | 
				
			||||||
  */
 | 
					  */
 | 
				
			||||||
     
 | 
					     
 | 
				
			||||||
 | 
					template<class Impl>
 | 
				
			||||||
 | 
					void WilsonFermion5D<Impl>::Report(void)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    std::vector<int> latt = GridDefaultLatt();          
 | 
				
			||||||
 | 
					    RealD volume = Ls;  for(int mu=0;mu<Nd;mu++) volume=volume*latt[mu];
 | 
				
			||||||
 | 
					    RealD NP = _FourDimGrid->_Nprocessors;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  if ( DhopCalls > 0 ) {
 | 
				
			||||||
 | 
					    std::cout << GridLogMessage << "#### Dhop calls report " << std::endl;
 | 
				
			||||||
 | 
					    std::cout << GridLogMessage << "WilsonFermion5D Number of Dhop Calls     : " << DhopCalls  << std::endl;
 | 
				
			||||||
 | 
					    std::cout << GridLogMessage << "WilsonFermion5D Total Communication time : " << DhopCommTime
 | 
				
			||||||
 | 
					              << " us" << std::endl;
 | 
				
			||||||
 | 
					    std::cout << GridLogMessage << "WilsonFermion5D CommTime/Calls           : "
 | 
				
			||||||
 | 
					              << DhopCommTime / DhopCalls << " us" << std::endl;
 | 
				
			||||||
 | 
					    std::cout << GridLogMessage << "WilsonFermion5D Total Compute time       : "
 | 
				
			||||||
 | 
					              << DhopComputeTime << " us" << std::endl;
 | 
				
			||||||
 | 
					    std::cout << GridLogMessage << "WilsonFermion5D ComputeTime/Calls        : "
 | 
				
			||||||
 | 
					              << DhopComputeTime / DhopCalls << " us" << std::endl;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    RealD mflops = 1344*volume*DhopCalls/DhopComputeTime;
 | 
				
			||||||
 | 
					    std::cout << GridLogMessage << "Average mflops/s per call                : " << mflops << std::endl;
 | 
				
			||||||
 | 
					    std::cout << GridLogMessage << "Average mflops/s per call per node       : " << mflops/NP << std::endl;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					   }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  if ( DerivCalls > 0 ) {
 | 
				
			||||||
 | 
					  std::cout << GridLogMessage << "#### Deriv calls report "<< std::endl;
 | 
				
			||||||
 | 
					  std::cout << GridLogMessage << "WilsonFermion5D Number of Deriv Calls    : " <<DerivCalls <<std::endl;
 | 
				
			||||||
 | 
					  std::cout << GridLogMessage << "WilsonFermion5D Total Communication time : " <<DerivCommTime <<" us"<<std::endl;
 | 
				
			||||||
 | 
					  std::cout << GridLogMessage << "WilsonFermion5D CommTime/Calls           : " <<DerivCommTime/DerivCalls<<" us" <<std::endl;
 | 
				
			||||||
 | 
					  std::cout << GridLogMessage << "WilsonFermion5D Total Compute time       : " <<DerivComputeTime <<" us"<<std::endl;
 | 
				
			||||||
 | 
					  std::cout << GridLogMessage << "WilsonFermion5D ComputeTime/Calls        : " <<DerivComputeTime/DerivCalls<<" us" <<std::endl;
 | 
				
			||||||
 | 
					  std::cout << GridLogMessage << "WilsonFermion5D Total Dhop Compute time  : " <<DerivDhopComputeTime <<" us"<<std::endl;
 | 
				
			||||||
 | 
					  std::cout << GridLogMessage << "WilsonFermion5D Dhop ComputeTime/Calls   : " <<DerivDhopComputeTime/DerivCalls<<" us" <<std::endl;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  RealD mflops = 144*volume*DerivCalls/DerivDhopComputeTime;
 | 
				
			||||||
 | 
					  std::cout << GridLogMessage << "Average mflops/s per call                : " << mflops << std::endl;
 | 
				
			||||||
 | 
					  std::cout << GridLogMessage << "Average mflops/s per call per node       : " << mflops/NP << std::endl;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  if (DerivCalls > 0 || DhopCalls > 0){
 | 
				
			||||||
 | 
					  std::cout << GridLogMessage << "WilsonFermion5D Stencil"<<std::endl;  Stencil.Report();
 | 
				
			||||||
 | 
					  std::cout << GridLogMessage << "WilsonFermion5D StencilEven"<<std::endl;  StencilEven.Report();
 | 
				
			||||||
 | 
					  std::cout << GridLogMessage << "WilsonFermion5D StencilOdd"<<std::endl;  StencilOdd.Report();
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					template<class Impl>
 | 
				
			||||||
 | 
					void WilsonFermion5D<Impl>::ZeroCounters(void) {
 | 
				
			||||||
 | 
					  DhopCalls       = 0;
 | 
				
			||||||
 | 
					  DhopCommTime    = 0;
 | 
				
			||||||
 | 
					  DhopComputeTime = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  DerivCalls       = 0;
 | 
				
			||||||
 | 
					  DerivCommTime    = 0;
 | 
				
			||||||
 | 
					  DerivComputeTime = 0;
 | 
				
			||||||
 | 
					  DerivDhopComputeTime = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  Stencil.ZeroCounters();
 | 
				
			||||||
 | 
					  StencilEven.ZeroCounters();
 | 
				
			||||||
 | 
					  StencilOdd.ZeroCounters();
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
template<class Impl>
 | 
					template<class Impl>
 | 
				
			||||||
void WilsonFermion5D<Impl>::ImportGauge(const GaugeField &_Umu)
 | 
					void WilsonFermion5D<Impl>::ImportGauge(const GaugeField &_Umu)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
@@ -215,12 +282,13 @@ PARALLEL_FOR_LOOP
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
template<class Impl>
 | 
					template<class Impl>
 | 
				
			||||||
void WilsonFermion5D<Impl>::DerivInternal(StencilImpl & st,
 | 
					void WilsonFermion5D<Impl>::DerivInternal(StencilImpl & st,
 | 
				
			||||||
					  DoubledGaugeField & U,
 | 
					            DoubledGaugeField & U,
 | 
				
			||||||
					  GaugeField &mat,
 | 
					            GaugeField &mat,
 | 
				
			||||||
					  const FermionField &A,
 | 
					            const FermionField &A,
 | 
				
			||||||
					  const FermionField &B,
 | 
					            const FermionField &B,
 | 
				
			||||||
					  int dag)
 | 
					            int dag)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
 | 
					  DerivCalls++;
 | 
				
			||||||
  assert((dag==DaggerNo) ||(dag==DaggerYes));
 | 
					  assert((dag==DaggerNo) ||(dag==DaggerYes));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  conformable(st._grid,A._grid);
 | 
					  conformable(st._grid,A._grid);
 | 
				
			||||||
@@ -231,51 +299,53 @@ void WilsonFermion5D<Impl>::DerivInternal(StencilImpl & st,
 | 
				
			|||||||
  FermionField Btilde(B._grid);
 | 
					  FermionField Btilde(B._grid);
 | 
				
			||||||
  FermionField Atilde(B._grid);
 | 
					  FermionField Atilde(B._grid);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  DerivCommTime-=usecond();
 | 
				
			||||||
  st.HaloExchange(B,compressor);
 | 
					  st.HaloExchange(B,compressor);
 | 
				
			||||||
 | 
					  DerivCommTime+=usecond();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  Atilde=A;
 | 
					  Atilde=A;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  for(int mu=0;mu<Nd;mu++){
 | 
					  DerivComputeTime-=usecond();
 | 
				
			||||||
      
 | 
					  for (int mu = 0; mu < Nd; mu++) {
 | 
				
			||||||
    ////////////////////////////////////////////////////////////////////////
 | 
					    ////////////////////////////////////////////////////////////////////////
 | 
				
			||||||
    // Flip gamma if dag
 | 
					    // Flip gamma if dag
 | 
				
			||||||
    ////////////////////////////////////////////////////////////////////////
 | 
					    ////////////////////////////////////////////////////////////////////////
 | 
				
			||||||
    int gamma = mu;
 | 
					    int gamma = mu;
 | 
				
			||||||
    if ( !dag ) gamma+= Nd;
 | 
					    if (!dag) gamma += Nd;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    ////////////////////////
 | 
					    ////////////////////////
 | 
				
			||||||
    // Call the single hop
 | 
					    // Call the single hop
 | 
				
			||||||
    ////////////////////////
 | 
					    ////////////////////////
 | 
				
			||||||
 | 
					
 | 
				
			||||||
PARALLEL_FOR_LOOP
 | 
					    DerivDhopComputeTime -= usecond();
 | 
				
			||||||
    for(int sss=0;sss<U._grid->oSites();sss++){
 | 
					    PARALLEL_FOR_LOOP
 | 
				
			||||||
      for(int s=0;s<Ls;s++){
 | 
					    for (int sss = 0; sss < U._grid->oSites(); sss++) {
 | 
				
			||||||
	int sU=sss;
 | 
					      for (int s = 0; s < Ls; s++) {
 | 
				
			||||||
	int sF = s+Ls*sU;
 | 
					        int sU = sss;
 | 
				
			||||||
 | 
					        int sF = s + Ls * sU;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	assert ( sF< B._grid->oSites());
 | 
					        assert(sF < B._grid->oSites());
 | 
				
			||||||
	assert ( sU< U._grid->oSites());
 | 
					        assert(sU < U._grid->oSites());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	Kernels::DiracOptDhopDir(st,U,st.comm_buf,sF,sU,B,Btilde,mu,gamma);
 | 
					        Kernels::DiracOptDhopDir(st, U, st.comm_buf, sF, sU, B, Btilde, mu,
 | 
				
			||||||
 | 
					                                 gamma);
 | 
				
			||||||
    ////////////////////////////
 | 
					 | 
				
			||||||
    // spin trace outer product
 | 
					 | 
				
			||||||
    ////////////////////////////
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        ////////////////////////////
 | 
				
			||||||
 | 
					        // spin trace outer product
 | 
				
			||||||
 | 
					        ////////////////////////////
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
 | 
					 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					    DerivDhopComputeTime += usecond();
 | 
				
			||||||
    Impl::InsertForce5D(mat,Btilde,Atilde,mu);
 | 
					    Impl::InsertForce5D(mat, Btilde, Atilde, mu);
 | 
				
			||||||
 | 
					 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					  DerivComputeTime += usecond();
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
template<class Impl>
 | 
					template<class Impl>
 | 
				
			||||||
void WilsonFermion5D<Impl>::DhopDeriv(      GaugeField &mat,
 | 
					void WilsonFermion5D<Impl>::DhopDeriv(      GaugeField &mat,
 | 
				
			||||||
					    const FermionField &A,
 | 
					              const FermionField &A,
 | 
				
			||||||
					    const FermionField &B,
 | 
					              const FermionField &B,
 | 
				
			||||||
					    int dag)
 | 
					              int dag)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
  conformable(A._grid,FermionGrid());  
 | 
					  conformable(A._grid,FermionGrid());  
 | 
				
			||||||
  conformable(A._grid,B._grid);
 | 
					  conformable(A._grid,B._grid);
 | 
				
			||||||
@@ -288,9 +358,9 @@ void WilsonFermion5D<Impl>::DhopDeriv(      GaugeField &mat,
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
template<class Impl>
 | 
					template<class Impl>
 | 
				
			||||||
void WilsonFermion5D<Impl>::DhopDerivEO(GaugeField &mat,
 | 
					void WilsonFermion5D<Impl>::DhopDerivEO(GaugeField &mat,
 | 
				
			||||||
					const FermionField &A,
 | 
					          const FermionField &A,
 | 
				
			||||||
					const FermionField &B,
 | 
					          const FermionField &B,
 | 
				
			||||||
					int dag)
 | 
					          int dag)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
  conformable(A._grid,FermionRedBlackGrid());
 | 
					  conformable(A._grid,FermionRedBlackGrid());
 | 
				
			||||||
  conformable(GaugeRedBlackGrid(),mat._grid);
 | 
					  conformable(GaugeRedBlackGrid(),mat._grid);
 | 
				
			||||||
@@ -306,9 +376,9 @@ void WilsonFermion5D<Impl>::DhopDerivEO(GaugeField &mat,
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
template<class Impl>
 | 
					template<class Impl>
 | 
				
			||||||
void WilsonFermion5D<Impl>::DhopDerivOE(GaugeField &mat,
 | 
					void WilsonFermion5D<Impl>::DhopDerivOE(GaugeField &mat,
 | 
				
			||||||
				  const FermionField &A,
 | 
					          const FermionField &A,
 | 
				
			||||||
				  const FermionField &B,
 | 
					          const FermionField &B,
 | 
				
			||||||
				  int dag)
 | 
					          int dag)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
  conformable(A._grid,FermionRedBlackGrid());
 | 
					  conformable(A._grid,FermionRedBlackGrid());
 | 
				
			||||||
  conformable(GaugeRedBlackGrid(),mat._grid);
 | 
					  conformable(GaugeRedBlackGrid(),mat._grid);
 | 
				
			||||||
@@ -323,32 +393,39 @@ void WilsonFermion5D<Impl>::DhopDerivOE(GaugeField &mat,
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
template<class Impl>
 | 
					template<class Impl>
 | 
				
			||||||
void WilsonFermion5D<Impl>::DhopInternal(StencilImpl & st, LebesgueOrder &lo,
 | 
					void WilsonFermion5D<Impl>::DhopInternal(StencilImpl & st, LebesgueOrder &lo,
 | 
				
			||||||
					 DoubledGaugeField & U,
 | 
					           DoubledGaugeField & U,
 | 
				
			||||||
					 const FermionField &in, FermionField &out,int dag)
 | 
					           const FermionField &in, FermionField &out,int dag)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
 | 
					  DhopCalls++;
 | 
				
			||||||
  //  assert((dag==DaggerNo) ||(dag==DaggerYes));
 | 
					  //  assert((dag==DaggerNo) ||(dag==DaggerYes));
 | 
				
			||||||
  Compressor compressor(dag);
 | 
					  Compressor compressor(dag);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  int LLs = in._grid->_rdimensions[0];
 | 
					  int LLs = in._grid->_rdimensions[0];
 | 
				
			||||||
  
 | 
					  
 | 
				
			||||||
 | 
					  DhopCommTime-=usecond();
 | 
				
			||||||
  st.HaloExchange(in,compressor);
 | 
					  st.HaloExchange(in,compressor);
 | 
				
			||||||
 | 
					  DhopCommTime+=usecond();
 | 
				
			||||||
  
 | 
					  
 | 
				
			||||||
 | 
					  DhopComputeTime-=usecond();
 | 
				
			||||||
  // Dhop takes the 4d grid from U, and makes a 5d index for fermion
 | 
					  // Dhop takes the 4d grid from U, and makes a 5d index for fermion
 | 
				
			||||||
  if ( dag == DaggerYes ) {
 | 
					  if (dag == DaggerYes) {
 | 
				
			||||||
PARALLEL_FOR_LOOP
 | 
					    PARALLEL_FOR_LOOP
 | 
				
			||||||
    for(int ss=0;ss<U._grid->oSites();ss++){
 | 
					    for (int ss = 0; ss < U._grid->oSites(); ss++) {
 | 
				
			||||||
	int sU=ss;
 | 
					      int sU = ss;
 | 
				
			||||||
	int sF=LLs*sU;
 | 
					      int sF = LLs * sU;
 | 
				
			||||||
	Kernels::DiracOptDhopSiteDag(st,lo,U,st.comm_buf,sF,sU,LLs,1,in,out);
 | 
					      Kernels::DiracOptDhopSiteDag(st, lo, U, st.comm_buf, sF, sU, LLs, 1, in,
 | 
				
			||||||
 | 
					                                   out);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
  } else {
 | 
					  } else {
 | 
				
			||||||
PARALLEL_FOR_LOOP
 | 
					    PARALLEL_FOR_LOOP
 | 
				
			||||||
    for(int ss=0;ss<U._grid->oSites();ss++){
 | 
					    for (int ss = 0; ss < U._grid->oSites(); ss++) {
 | 
				
			||||||
      int sU=ss;
 | 
					      int sU = ss;
 | 
				
			||||||
      int sF=LLs*sU;
 | 
					      int sF = LLs * sU;
 | 
				
			||||||
      Kernels::DiracOptDhopSite(st,lo,U,st.comm_buf,sF,sU,LLs,1,in,out);
 | 
					      Kernels::DiracOptDhopSite(st, lo, U, st.comm_buf, sF, sU, LLs, 1, in,
 | 
				
			||||||
 | 
					                                out);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					  DhopComputeTime+=usecond();
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -61,6 +61,17 @@ namespace Grid {
 | 
				
			|||||||
     INHERIT_IMPL_TYPES(Impl);
 | 
					     INHERIT_IMPL_TYPES(Impl);
 | 
				
			||||||
     typedef WilsonKernels<Impl> Kernels;
 | 
					     typedef WilsonKernels<Impl> Kernels;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					     void Report(void);
 | 
				
			||||||
 | 
					     void ZeroCounters(void);
 | 
				
			||||||
 | 
					     double DhopCalls;
 | 
				
			||||||
 | 
					     double DhopCommTime;
 | 
				
			||||||
 | 
					     double DhopComputeTime;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					     double DerivCalls;
 | 
				
			||||||
 | 
					     double DerivCommTime;
 | 
				
			||||||
 | 
					     double DerivComputeTime;
 | 
				
			||||||
 | 
					     double DerivDhopComputeTime;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      ///////////////////////////////////////////////////////////////
 | 
					      ///////////////////////////////////////////////////////////////
 | 
				
			||||||
      // Implement the abstract base
 | 
					      // Implement the abstract base
 | 
				
			||||||
      ///////////////////////////////////////////////////////////////
 | 
					      ///////////////////////////////////////////////////////////////
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,98 +1,54 @@
 | 
				
			|||||||
    /*************************************************************************************
 | 
					/*************************************************************************************
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    Grid physics library, www.github.com/paboyle/Grid 
 | 
					Grid physics library, www.github.com/paboyle/Grid
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    Source file: ./lib/qcd/action/fermion/WilsonKernels.cc
 | 
					Source file: ./lib/qcd/action/fermion/WilsonKernels.cc
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    Copyright (C) 2015
 | 
					Copyright (C) 2015
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Author: Peter Boyle <paboyle@ph.ed.ac.uk>
 | 
					Author: Peter Boyle <paboyle@ph.ed.ac.uk>
 | 
				
			||||||
Author: Peter Boyle <peterboyle@Peters-MacBook-Pro-2.local>
 | 
					Author: Peter Boyle <peterboyle@Peters-MacBook-Pro-2.local>
 | 
				
			||||||
Author: paboyle <paboyle@ph.ed.ac.uk>
 | 
					Author: paboyle <paboyle@ph.ed.ac.uk>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    This program is free software; you can redistribute it and/or modify
 | 
					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
 | 
					it under the terms of the GNU General Public License as published by
 | 
				
			||||||
    the Free Software Foundation; either version 2 of the License, or
 | 
					the Free Software Foundation; either version 2 of the License, or
 | 
				
			||||||
    (at your option) any later version.
 | 
					(at your option) any later version.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    This program is distributed in the hope that it will be useful,
 | 
					This program is distributed in the hope that it will be useful,
 | 
				
			||||||
    but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
					but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
				
			||||||
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
					MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
				
			||||||
    GNU General Public License for more details.
 | 
					GNU General Public License for more details.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    You should have received a copy of the GNU General Public License along
 | 
					You should have received a copy of the GNU General Public License along
 | 
				
			||||||
    with this program; if not, write to the Free Software Foundation, Inc.,
 | 
					with this program; if not, write to the Free Software Foundation, Inc.,
 | 
				
			||||||
    51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 | 
					51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    See the full license in the file "LICENSE" in the top level distribution directory
 | 
					See the full license in the file "LICENSE" in the top level distribution
 | 
				
			||||||
    *************************************************************************************/
 | 
					directory
 | 
				
			||||||
    /*  END LEGAL */
 | 
					*************************************************************************************/
 | 
				
			||||||
 | 
					/*  END LEGAL */
 | 
				
			||||||
#include <Grid.h>
 | 
					#include <Grid.h>
 | 
				
			||||||
namespace Grid {
 | 
					namespace Grid {
 | 
				
			||||||
namespace QCD {
 | 
					namespace QCD {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  int WilsonKernelsStatic::HandOpt;
 | 
					int WilsonKernelsStatic::HandOpt;
 | 
				
			||||||
  int WilsonKernelsStatic::AsmOpt;
 | 
					int WilsonKernelsStatic::AsmOpt;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
template<class Impl> 
 | 
					template <class Impl>
 | 
				
			||||||
WilsonKernels<Impl>::WilsonKernels(const ImplParams &p): Base(p) {};
 | 
					WilsonKernels<Impl>::WilsonKernels(const ImplParams &p) : Base(p){};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
template<class Impl> 
 | 
					////////////////////////////////////////////
 | 
				
			||||||
void WilsonKernels<Impl>::DiracOptDhopSite(StencilImpl &st,LebesgueOrder &lo,DoubledGaugeField &U,
 | 
					// Generic implementation; move to different file?
 | 
				
			||||||
						  std::vector<SiteHalfSpinor,alignedAllocator<SiteHalfSpinor> >  &buf,
 | 
					////////////////////////////////////////////
 | 
				
			||||||
						  int sF,int sU,int Ls, int Ns, const FermionField &in, FermionField &out)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
#ifdef AVX512
 | 
					 | 
				
			||||||
  if ( AsmOpt ) {
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    WilsonKernels<Impl>::DiracOptAsmDhopSite(st,lo,U,buf,sF,sU,Ls,Ns,in,out);
 | 
					template <class Impl>
 | 
				
			||||||
 | 
					void WilsonKernels<Impl>::DiracOptGenericDhopSiteDag(
 | 
				
			||||||
  } else {
 | 
					    StencilImpl &st, LebesgueOrder &lo, DoubledGaugeField &U,
 | 
				
			||||||
#else
 | 
					    std::vector<SiteHalfSpinor, alignedAllocator<SiteHalfSpinor> > &buf, int sF,
 | 
				
			||||||
  {  
 | 
					    int sU, const FermionField &in, FermionField &out) {
 | 
				
			||||||
#endif
 | 
					  SiteHalfSpinor tmp;
 | 
				
			||||||
    for(int site=0;site<Ns;site++) {
 | 
					  SiteHalfSpinor chi;
 | 
				
			||||||
      for(int s=0;s<Ls;s++) {
 | 
					 | 
				
			||||||
	if (HandOpt) WilsonKernels<Impl>::DiracOptHandDhopSite(st,lo,U,buf,sF,sU,in,out);
 | 
					 | 
				
			||||||
	else         WilsonKernels<Impl>::DiracOptGenericDhopSite(st,lo,U,buf,sF,sU,in,out);
 | 
					 | 
				
			||||||
	sF++;
 | 
					 | 
				
			||||||
      }
 | 
					 | 
				
			||||||
      sU++;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
template<class Impl> 
 | 
					 | 
				
			||||||
void WilsonKernels<Impl>::DiracOptDhopSiteDag(StencilImpl &st,LebesgueOrder &lo,DoubledGaugeField &U,
 | 
					 | 
				
			||||||
					   std::vector<SiteHalfSpinor,alignedAllocator<SiteHalfSpinor> >  &buf,
 | 
					 | 
				
			||||||
					   int sF,int sU,int Ls, int Ns, const FermionField &in, FermionField &out)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
  // No asm implementation yet.
 | 
					 | 
				
			||||||
  //  if ( AsmOpt )     WilsonKernels<Impl>::DiracOptAsmDhopSiteDag(st,lo,U,buf,sF,sU,in,out);
 | 
					 | 
				
			||||||
  //  else
 | 
					 | 
				
			||||||
  for(int site=0;site<Ns;site++) {
 | 
					 | 
				
			||||||
    for(int s=0;s<Ls;s++) {
 | 
					 | 
				
			||||||
      if (HandOpt) WilsonKernels<Impl>::DiracOptHandDhopSiteDag(st,lo,U,buf,sF,sU,in,out);
 | 
					 | 
				
			||||||
      else         WilsonKernels<Impl>::DiracOptGenericDhopSiteDag(st,lo,U,buf,sF,sU,in,out);
 | 
					 | 
				
			||||||
      sF++;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    sU++;
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  ////////////////////////////////////////////
 | 
					 | 
				
			||||||
  // Generic implementation; move to different file?
 | 
					 | 
				
			||||||
  ////////////////////////////////////////////
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
template<class Impl> 
 | 
					 | 
				
			||||||
void WilsonKernels<Impl>::DiracOptGenericDhopSiteDag(StencilImpl &st,LebesgueOrder &lo,DoubledGaugeField &U,
 | 
					 | 
				
			||||||
					   std::vector<SiteHalfSpinor,alignedAllocator<SiteHalfSpinor> >  &buf,
 | 
					 | 
				
			||||||
					   int sF,int sU,const FermionField &in, FermionField &out)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
  SiteHalfSpinor  tmp;    
 | 
					 | 
				
			||||||
  SiteHalfSpinor  chi;    
 | 
					 | 
				
			||||||
  SiteHalfSpinor *chi_p;
 | 
					  SiteHalfSpinor *chi_p;
 | 
				
			||||||
  SiteHalfSpinor Uchi;
 | 
					  SiteHalfSpinor Uchi;
 | 
				
			||||||
  SiteSpinor result;
 | 
					  SiteSpinor result;
 | 
				
			||||||
@@ -102,175 +58,174 @@ void WilsonKernels<Impl>::DiracOptGenericDhopSiteDag(StencilImpl &st,LebesgueOrd
 | 
				
			|||||||
  ///////////////////////////
 | 
					  ///////////////////////////
 | 
				
			||||||
  // Xp
 | 
					  // Xp
 | 
				
			||||||
  ///////////////////////////
 | 
					  ///////////////////////////
 | 
				
			||||||
  SE=st.GetEntry(ptype,Xp,sF);
 | 
					  SE = st.GetEntry(ptype, Xp, sF);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  if (SE->_is_local ) { 
 | 
					  if (SE->_is_local) {
 | 
				
			||||||
    chi_p = χ
 | 
					    chi_p = χ
 | 
				
			||||||
    if ( SE->_permute ) {
 | 
					    if (SE->_permute) {
 | 
				
			||||||
      spProjXp(tmp,in._odata[SE->_offset]);
 | 
					      spProjXp(tmp, in._odata[SE->_offset]);
 | 
				
			||||||
      permute(chi,tmp,ptype);
 | 
					      permute(chi, tmp, ptype);
 | 
				
			||||||
    } else {
 | 
					    } else {
 | 
				
			||||||
      spProjXp(chi,in._odata[SE->_offset]);
 | 
					      spProjXp(chi, in._odata[SE->_offset]);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
  } else {
 | 
					  } else {
 | 
				
			||||||
    chi_p=&buf[SE->_offset];
 | 
					    chi_p = &buf[SE->_offset];
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  Impl::multLink(Uchi,U._odata[sU],*chi_p,Xp,SE,st);
 | 
					  Impl::multLink(Uchi, U._odata[sU], *chi_p, Xp, SE, st);
 | 
				
			||||||
  spReconXp(result,Uchi);
 | 
					  spReconXp(result, Uchi);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  ///////////////////////////
 | 
					  ///////////////////////////
 | 
				
			||||||
  // Yp
 | 
					  // Yp
 | 
				
			||||||
  ///////////////////////////
 | 
					  ///////////////////////////
 | 
				
			||||||
  SE=st.GetEntry(ptype,Yp,sF);
 | 
					  SE = st.GetEntry(ptype, Yp, sF);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  if ( SE->_is_local ) { 
 | 
					  if (SE->_is_local) {
 | 
				
			||||||
    chi_p = χ
 | 
					    chi_p = χ
 | 
				
			||||||
    if ( SE->_permute ) {
 | 
					    if (SE->_permute) {
 | 
				
			||||||
      spProjYp(tmp,in._odata[SE->_offset]);
 | 
					      spProjYp(tmp, in._odata[SE->_offset]);
 | 
				
			||||||
      permute(chi,tmp,ptype);
 | 
					      permute(chi, tmp, ptype);
 | 
				
			||||||
    } else {
 | 
					    } else {
 | 
				
			||||||
      spProjYp(chi,in._odata[SE->_offset]);
 | 
					      spProjYp(chi, in._odata[SE->_offset]);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
  } else {
 | 
					  } else {
 | 
				
			||||||
    chi_p=&buf[SE->_offset];
 | 
					    chi_p = &buf[SE->_offset];
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  Impl::multLink(Uchi,U._odata[sU],*chi_p,Yp,SE,st);
 | 
					  Impl::multLink(Uchi, U._odata[sU], *chi_p, Yp, SE, st);
 | 
				
			||||||
  accumReconYp(result,Uchi);
 | 
					  accumReconYp(result, Uchi);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  ///////////////////////////
 | 
					  ///////////////////////////
 | 
				
			||||||
  // Zp
 | 
					  // Zp
 | 
				
			||||||
  ///////////////////////////
 | 
					  ///////////////////////////
 | 
				
			||||||
  SE=st.GetEntry(ptype,Zp,sF);
 | 
					  SE = st.GetEntry(ptype, Zp, sF);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  if ( SE->_is_local ) { 
 | 
					  if (SE->_is_local) {
 | 
				
			||||||
    chi_p = χ
 | 
					    chi_p = χ
 | 
				
			||||||
    if ( SE->_permute ) {
 | 
					    if (SE->_permute) {
 | 
				
			||||||
      spProjZp(tmp,in._odata[SE->_offset]);
 | 
					      spProjZp(tmp, in._odata[SE->_offset]);
 | 
				
			||||||
      permute(chi,tmp,ptype);
 | 
					      permute(chi, tmp, ptype);
 | 
				
			||||||
    } else {
 | 
					    } else {
 | 
				
			||||||
      spProjZp(chi,in._odata[SE->_offset]);
 | 
					      spProjZp(chi, in._odata[SE->_offset]);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
  } else {
 | 
					  } else {
 | 
				
			||||||
    chi_p=&buf[SE->_offset];
 | 
					    chi_p = &buf[SE->_offset];
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  Impl::multLink(Uchi,U._odata[sU],*chi_p,Zp,SE,st);
 | 
					  Impl::multLink(Uchi, U._odata[sU], *chi_p, Zp, SE, st);
 | 
				
			||||||
  accumReconZp(result,Uchi);
 | 
					  accumReconZp(result, Uchi);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  ///////////////////////////
 | 
					  ///////////////////////////
 | 
				
			||||||
  // Tp
 | 
					  // Tp
 | 
				
			||||||
  ///////////////////////////
 | 
					  ///////////////////////////
 | 
				
			||||||
  SE=st.GetEntry(ptype,Tp,sF);
 | 
					  SE = st.GetEntry(ptype, Tp, sF);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  if ( SE->_is_local ) {
 | 
					  if (SE->_is_local) {
 | 
				
			||||||
    chi_p = χ
 | 
					    chi_p = χ
 | 
				
			||||||
    if ( SE->_permute ) {
 | 
					    if (SE->_permute) {
 | 
				
			||||||
      spProjTp(tmp,in._odata[SE->_offset]);
 | 
					      spProjTp(tmp, in._odata[SE->_offset]);
 | 
				
			||||||
      permute(chi,tmp,ptype);
 | 
					      permute(chi, tmp, ptype);
 | 
				
			||||||
    } else {
 | 
					    } else {
 | 
				
			||||||
      spProjTp(chi,in._odata[SE->_offset]);
 | 
					      spProjTp(chi, in._odata[SE->_offset]);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
  } else {
 | 
					  } else {
 | 
				
			||||||
    chi_p=&buf[SE->_offset];
 | 
					    chi_p = &buf[SE->_offset];
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  Impl::multLink(Uchi,U._odata[sU],*chi_p,Tp,SE,st);
 | 
					  Impl::multLink(Uchi, U._odata[sU], *chi_p, Tp, SE, st);
 | 
				
			||||||
  accumReconTp(result,Uchi);
 | 
					  accumReconTp(result, Uchi);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  ///////////////////////////
 | 
					  ///////////////////////////
 | 
				
			||||||
  // Xm
 | 
					  // Xm
 | 
				
			||||||
  ///////////////////////////
 | 
					  ///////////////////////////
 | 
				
			||||||
  SE=st.GetEntry(ptype,Xm,sF);
 | 
					  SE = st.GetEntry(ptype, Xm, sF);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  if ( SE->_is_local ) {
 | 
					  if (SE->_is_local) {
 | 
				
			||||||
    chi_p = χ
 | 
					    chi_p = χ
 | 
				
			||||||
    if ( SE->_permute ) {
 | 
					    if (SE->_permute) {
 | 
				
			||||||
      spProjXm(tmp,in._odata[SE->_offset]);
 | 
					      spProjXm(tmp, in._odata[SE->_offset]);
 | 
				
			||||||
      permute(chi,tmp,ptype);
 | 
					      permute(chi, tmp, ptype);
 | 
				
			||||||
    } else {
 | 
					    } else {
 | 
				
			||||||
      spProjXm(chi,in._odata[SE->_offset]);
 | 
					      spProjXm(chi, in._odata[SE->_offset]);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
  } else {
 | 
					  } else {
 | 
				
			||||||
    chi_p=&buf[SE->_offset];
 | 
					    chi_p = &buf[SE->_offset];
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  Impl::multLink(Uchi,U._odata[sU],*chi_p,Xm,SE,st);
 | 
					  Impl::multLink(Uchi, U._odata[sU], *chi_p, Xm, SE, st);
 | 
				
			||||||
  accumReconXm(result,Uchi);
 | 
					  accumReconXm(result, Uchi);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  ///////////////////////////
 | 
					  ///////////////////////////
 | 
				
			||||||
  // Ym
 | 
					  // Ym
 | 
				
			||||||
  ///////////////////////////
 | 
					  ///////////////////////////
 | 
				
			||||||
  SE=st.GetEntry(ptype,Ym,sF);
 | 
					  SE = st.GetEntry(ptype, Ym, sF);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  if ( SE->_is_local ) {
 | 
					  if (SE->_is_local) {
 | 
				
			||||||
    chi_p = χ
 | 
					    chi_p = χ
 | 
				
			||||||
    if ( SE->_permute ) {
 | 
					    if (SE->_permute) {
 | 
				
			||||||
      spProjYm(tmp,in._odata[SE->_offset]);
 | 
					      spProjYm(tmp, in._odata[SE->_offset]);
 | 
				
			||||||
      permute(chi,tmp,ptype);
 | 
					      permute(chi, tmp, ptype);
 | 
				
			||||||
    } else {
 | 
					    } else {
 | 
				
			||||||
      spProjYm(chi,in._odata[SE->_offset]);
 | 
					      spProjYm(chi, in._odata[SE->_offset]);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
  } else {
 | 
					  } else {
 | 
				
			||||||
    chi_p=&buf[SE->_offset];
 | 
					    chi_p = &buf[SE->_offset];
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  Impl::multLink(Uchi,U._odata[sU],*chi_p,Ym,SE,st);
 | 
					  Impl::multLink(Uchi, U._odata[sU], *chi_p, Ym, SE, st);
 | 
				
			||||||
  accumReconYm(result,Uchi);
 | 
					  accumReconYm(result, Uchi);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  ///////////////////////////
 | 
					  ///////////////////////////
 | 
				
			||||||
  // Zm
 | 
					  // Zm
 | 
				
			||||||
  ///////////////////////////
 | 
					  ///////////////////////////
 | 
				
			||||||
  SE=st.GetEntry(ptype,Zm,sF);
 | 
					  SE = st.GetEntry(ptype, Zm, sF);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  if ( SE->_is_local ) {
 | 
					  if (SE->_is_local) {
 | 
				
			||||||
    chi_p = χ
 | 
					    chi_p = χ
 | 
				
			||||||
    if ( SE->_permute ) {
 | 
					    if (SE->_permute) {
 | 
				
			||||||
      spProjZm(tmp,in._odata[SE->_offset]);
 | 
					      spProjZm(tmp, in._odata[SE->_offset]);
 | 
				
			||||||
      permute(chi,tmp,ptype);
 | 
					      permute(chi, tmp, ptype);
 | 
				
			||||||
    } else {
 | 
					    } else {
 | 
				
			||||||
      spProjZm(chi,in._odata[SE->_offset]);
 | 
					      spProjZm(chi, in._odata[SE->_offset]);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
  } else {
 | 
					  } else {
 | 
				
			||||||
    chi_p=&buf[SE->_offset];
 | 
					    chi_p = &buf[SE->_offset];
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  Impl::multLink(Uchi,U._odata[sU],*chi_p,Zm,SE,st);
 | 
					  Impl::multLink(Uchi, U._odata[sU], *chi_p, Zm, SE, st);
 | 
				
			||||||
  accumReconZm(result,Uchi);
 | 
					  accumReconZm(result, Uchi);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  ///////////////////////////
 | 
					  ///////////////////////////
 | 
				
			||||||
  // Tm
 | 
					  // Tm
 | 
				
			||||||
  ///////////////////////////
 | 
					  ///////////////////////////
 | 
				
			||||||
  SE=st.GetEntry(ptype,Tm,sF);
 | 
					  SE = st.GetEntry(ptype, Tm, sF);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  if ( SE->_is_local ) {
 | 
					  if (SE->_is_local) {
 | 
				
			||||||
    chi_p = χ
 | 
					    chi_p = χ
 | 
				
			||||||
    if ( SE->_permute ) {
 | 
					    if (SE->_permute) {
 | 
				
			||||||
      spProjTm(tmp,in._odata[SE->_offset]);
 | 
					      spProjTm(tmp, in._odata[SE->_offset]);
 | 
				
			||||||
      permute(chi,tmp,ptype);
 | 
					      permute(chi, tmp, ptype);
 | 
				
			||||||
    } else {
 | 
					    } else {
 | 
				
			||||||
      spProjTm(chi,in._odata[SE->_offset]);
 | 
					      spProjTm(chi, in._odata[SE->_offset]);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
  } else {
 | 
					  } else {
 | 
				
			||||||
    chi_p=&buf[SE->_offset];
 | 
					    chi_p = &buf[SE->_offset];
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  Impl::multLink(Uchi,U._odata[sU],*chi_p,Tm,SE,st);
 | 
					  Impl::multLink(Uchi, U._odata[sU], *chi_p, Tm, SE, st);
 | 
				
			||||||
  accumReconTm(result,Uchi);
 | 
					  accumReconTm(result, Uchi);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  vstream(out._odata[sF],result);
 | 
					  vstream(out._odata[sF], result);
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Need controls to do interior, exterior, or both
 | 
				
			||||||
  // Need controls to do interior, exterior, or both
 | 
					template <class Impl>
 | 
				
			||||||
template<class Impl> 
 | 
					void WilsonKernels<Impl>::DiracOptGenericDhopSite(
 | 
				
			||||||
void WilsonKernels<Impl>::DiracOptGenericDhopSite(StencilImpl &st,LebesgueOrder &lo,DoubledGaugeField &U,
 | 
					    StencilImpl &st, LebesgueOrder &lo, DoubledGaugeField &U,
 | 
				
			||||||
						  std::vector<SiteHalfSpinor,alignedAllocator<SiteHalfSpinor> >  &buf,
 | 
					    std::vector<SiteHalfSpinor, alignedAllocator<SiteHalfSpinor> > &buf, int sF,
 | 
				
			||||||
						  int sF,int sU,const FermionField &in, FermionField &out)
 | 
					    int sU, const FermionField &in, FermionField &out) {
 | 
				
			||||||
{
 | 
					  SiteHalfSpinor tmp;
 | 
				
			||||||
  SiteHalfSpinor  tmp;    
 | 
					  SiteHalfSpinor chi;
 | 
				
			||||||
  SiteHalfSpinor  chi;    
 | 
					 | 
				
			||||||
  SiteHalfSpinor *chi_p;
 | 
					  SiteHalfSpinor *chi_p;
 | 
				
			||||||
  SiteHalfSpinor Uchi;
 | 
					  SiteHalfSpinor Uchi;
 | 
				
			||||||
  SiteSpinor result;
 | 
					  SiteSpinor result;
 | 
				
			||||||
@@ -280,296 +235,298 @@ void WilsonKernels<Impl>::DiracOptGenericDhopSite(StencilImpl &st,LebesgueOrder
 | 
				
			|||||||
  ///////////////////////////
 | 
					  ///////////////////////////
 | 
				
			||||||
  // Xp
 | 
					  // Xp
 | 
				
			||||||
  ///////////////////////////
 | 
					  ///////////////////////////
 | 
				
			||||||
  SE=st.GetEntry(ptype,Xm,sF);
 | 
					  SE = st.GetEntry(ptype, Xm, sF);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  if ( SE->_is_local ) { 
 | 
					  if (SE->_is_local) {
 | 
				
			||||||
    chi_p = χ
 | 
					    chi_p = χ
 | 
				
			||||||
    if ( SE->_permute ) {
 | 
					    if (SE->_permute) {
 | 
				
			||||||
      spProjXp(tmp,in._odata[SE->_offset]);
 | 
					      spProjXp(tmp, in._odata[SE->_offset]);
 | 
				
			||||||
      permute(chi,tmp,ptype);
 | 
					      permute(chi, tmp, ptype);
 | 
				
			||||||
    } else {
 | 
					    } else {
 | 
				
			||||||
      spProjXp(chi,in._odata[SE->_offset]);
 | 
					      spProjXp(chi, in._odata[SE->_offset]);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
  } else {
 | 
					  } else {
 | 
				
			||||||
    chi_p=&buf[SE->_offset];
 | 
					    chi_p = &buf[SE->_offset];
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  Impl::multLink(Uchi,U._odata[sU],*chi_p,Xm,SE,st);
 | 
					  Impl::multLink(Uchi, U._odata[sU], *chi_p, Xm, SE, st);
 | 
				
			||||||
  spReconXp(result,Uchi);
 | 
					  spReconXp(result, Uchi);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  ///////////////////////////
 | 
					  ///////////////////////////
 | 
				
			||||||
  // Yp
 | 
					  // Yp
 | 
				
			||||||
  ///////////////////////////
 | 
					  ///////////////////////////
 | 
				
			||||||
  SE=st.GetEntry(ptype,Ym,sF);
 | 
					  SE = st.GetEntry(ptype, Ym, sF);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  if ( SE->_is_local ) { 
 | 
					  if (SE->_is_local) {
 | 
				
			||||||
    chi_p = χ
 | 
					    chi_p = χ
 | 
				
			||||||
    if ( SE->_permute ) {
 | 
					    if (SE->_permute) {
 | 
				
			||||||
      spProjYp(tmp,in._odata[SE->_offset]);
 | 
					      spProjYp(tmp, in._odata[SE->_offset]);
 | 
				
			||||||
      permute(chi,tmp,ptype);
 | 
					      permute(chi, tmp, ptype);
 | 
				
			||||||
    } else {
 | 
					    } else {
 | 
				
			||||||
      spProjYp(chi,in._odata[SE->_offset]);
 | 
					      spProjYp(chi, in._odata[SE->_offset]);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
  } else {
 | 
					  } else {
 | 
				
			||||||
    chi_p=&buf[SE->_offset];
 | 
					    chi_p = &buf[SE->_offset];
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  Impl::multLink(Uchi,U._odata[sU],*chi_p,Ym,SE,st);
 | 
					  Impl::multLink(Uchi, U._odata[sU], *chi_p, Ym, SE, st);
 | 
				
			||||||
  accumReconYp(result,Uchi);
 | 
					  accumReconYp(result, Uchi);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  ///////////////////////////
 | 
					  ///////////////////////////
 | 
				
			||||||
  // Zp
 | 
					  // Zp
 | 
				
			||||||
  ///////////////////////////
 | 
					  ///////////////////////////
 | 
				
			||||||
  SE=st.GetEntry(ptype,Zm,sF);
 | 
					  SE = st.GetEntry(ptype, Zm, sF);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  if ( SE->_is_local ) { 
 | 
					  if (SE->_is_local) {
 | 
				
			||||||
    chi_p = χ
 | 
					    chi_p = χ
 | 
				
			||||||
    if ( SE->_permute ) {
 | 
					    if (SE->_permute) {
 | 
				
			||||||
      spProjZp(tmp,in._odata[SE->_offset]);
 | 
					      spProjZp(tmp, in._odata[SE->_offset]);
 | 
				
			||||||
      permute(chi,tmp,ptype);
 | 
					      permute(chi, tmp, ptype);
 | 
				
			||||||
    } else {
 | 
					    } else {
 | 
				
			||||||
      spProjZp(chi,in._odata[SE->_offset]);
 | 
					      spProjZp(chi, in._odata[SE->_offset]);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
  } else {
 | 
					  } else {
 | 
				
			||||||
    chi_p=&buf[SE->_offset];
 | 
					    chi_p = &buf[SE->_offset];
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  Impl::multLink(Uchi,U._odata[sU],*chi_p,Zm,SE,st);
 | 
					  Impl::multLink(Uchi, U._odata[sU], *chi_p, Zm, SE, st);
 | 
				
			||||||
  accumReconZp(result,Uchi);
 | 
					  accumReconZp(result, Uchi);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  ///////////////////////////
 | 
					  ///////////////////////////
 | 
				
			||||||
  // Tp
 | 
					  // Tp
 | 
				
			||||||
  ///////////////////////////
 | 
					  ///////////////////////////
 | 
				
			||||||
  SE=st.GetEntry(ptype,Tm,sF);
 | 
					  SE = st.GetEntry(ptype, Tm, sF);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  if ( SE->_is_local ) {
 | 
					  if (SE->_is_local) {
 | 
				
			||||||
    chi_p = χ
 | 
					    chi_p = χ
 | 
				
			||||||
    if ( SE->_permute ) {
 | 
					    if (SE->_permute) {
 | 
				
			||||||
      spProjTp(tmp,in._odata[SE->_offset]);
 | 
					      spProjTp(tmp, in._odata[SE->_offset]);
 | 
				
			||||||
      permute(chi,tmp,ptype);
 | 
					      permute(chi, tmp, ptype);
 | 
				
			||||||
    } else {
 | 
					    } else {
 | 
				
			||||||
      spProjTp(chi,in._odata[SE->_offset]);
 | 
					      spProjTp(chi, in._odata[SE->_offset]);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
  } else {
 | 
					  } else {
 | 
				
			||||||
    chi_p=&buf[SE->_offset];
 | 
					    chi_p = &buf[SE->_offset];
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  Impl::multLink(Uchi,U._odata[sU],*chi_p,Tm,SE,st);
 | 
					  Impl::multLink(Uchi, U._odata[sU], *chi_p, Tm, SE, st);
 | 
				
			||||||
  accumReconTp(result,Uchi);
 | 
					  accumReconTp(result, Uchi);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  ///////////////////////////
 | 
					  ///////////////////////////
 | 
				
			||||||
  // Xm
 | 
					  // Xm
 | 
				
			||||||
  ///////////////////////////
 | 
					  ///////////////////////////
 | 
				
			||||||
  SE=st.GetEntry(ptype,Xp,sF);
 | 
					  SE = st.GetEntry(ptype, Xp, sF);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  if ( SE->_is_local ) {
 | 
					  if (SE->_is_local) {
 | 
				
			||||||
    chi_p = χ
 | 
					    chi_p = χ
 | 
				
			||||||
    if ( SE->_permute ) {
 | 
					    if (SE->_permute) {
 | 
				
			||||||
      spProjXm(tmp,in._odata[SE->_offset]);
 | 
					      spProjXm(tmp, in._odata[SE->_offset]);
 | 
				
			||||||
      permute(chi,tmp,ptype);
 | 
					      permute(chi, tmp, ptype);
 | 
				
			||||||
    } else {
 | 
					    } else {
 | 
				
			||||||
      spProjXm(chi,in._odata[SE->_offset]);
 | 
					      spProjXm(chi, in._odata[SE->_offset]);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
  } else {
 | 
					  } else {
 | 
				
			||||||
    chi_p=&buf[SE->_offset];
 | 
					    chi_p = &buf[SE->_offset];
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  Impl::multLink(Uchi,U._odata[sU],*chi_p,Xp,SE,st);
 | 
					  Impl::multLink(Uchi, U._odata[sU], *chi_p, Xp, SE, st);
 | 
				
			||||||
  accumReconXm(result,Uchi);
 | 
					  accumReconXm(result, Uchi);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  ///////////////////////////
 | 
					  ///////////////////////////
 | 
				
			||||||
  // Ym
 | 
					  // Ym
 | 
				
			||||||
  ///////////////////////////
 | 
					  ///////////////////////////
 | 
				
			||||||
  SE=st.GetEntry(ptype,Yp,sF);
 | 
					  SE = st.GetEntry(ptype, Yp, sF);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  if ( SE->_is_local ) {
 | 
					  if (SE->_is_local) {
 | 
				
			||||||
    chi_p = χ
 | 
					    chi_p = χ
 | 
				
			||||||
    if ( SE->_permute ) {
 | 
					    if (SE->_permute) {
 | 
				
			||||||
      spProjYm(tmp,in._odata[SE->_offset]);
 | 
					      spProjYm(tmp, in._odata[SE->_offset]);
 | 
				
			||||||
      permute(chi,tmp,ptype);
 | 
					      permute(chi, tmp, ptype);
 | 
				
			||||||
    } else {
 | 
					    } else {
 | 
				
			||||||
      spProjYm(chi,in._odata[SE->_offset]);
 | 
					      spProjYm(chi, in._odata[SE->_offset]);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
  } else {
 | 
					  } else {
 | 
				
			||||||
    chi_p=&buf[SE->_offset];
 | 
					    chi_p = &buf[SE->_offset];
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  Impl::multLink(Uchi,U._odata[sU],*chi_p,Yp,SE,st);
 | 
					  Impl::multLink(Uchi, U._odata[sU], *chi_p, Yp, SE, st);
 | 
				
			||||||
  accumReconYm(result,Uchi);
 | 
					  accumReconYm(result, Uchi);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  ///////////////////////////
 | 
					  ///////////////////////////
 | 
				
			||||||
  // Zm
 | 
					  // Zm
 | 
				
			||||||
  ///////////////////////////
 | 
					  ///////////////////////////
 | 
				
			||||||
  SE=st.GetEntry(ptype,Zp,sF);
 | 
					  SE = st.GetEntry(ptype, Zp, sF);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  if ( SE->_is_local ) {
 | 
					  if (SE->_is_local) {
 | 
				
			||||||
    chi_p = χ
 | 
					    chi_p = χ
 | 
				
			||||||
    if ( SE->_permute ) {
 | 
					    if (SE->_permute) {
 | 
				
			||||||
      spProjZm(tmp,in._odata[SE->_offset]);
 | 
					      spProjZm(tmp, in._odata[SE->_offset]);
 | 
				
			||||||
      permute(chi,tmp,ptype);
 | 
					      permute(chi, tmp, ptype);
 | 
				
			||||||
    } else {
 | 
					    } else {
 | 
				
			||||||
      spProjZm(chi,in._odata[SE->_offset]);
 | 
					      spProjZm(chi, in._odata[SE->_offset]);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
  } else {
 | 
					  } else {
 | 
				
			||||||
    chi_p=&buf[SE->_offset];
 | 
					    chi_p = &buf[SE->_offset];
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  Impl::multLink(Uchi,U._odata[sU],*chi_p,Zp,SE,st);
 | 
					  Impl::multLink(Uchi, U._odata[sU], *chi_p, Zp, SE, st);
 | 
				
			||||||
  accumReconZm(result,Uchi);
 | 
					  accumReconZm(result, Uchi);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  ///////////////////////////
 | 
					  ///////////////////////////
 | 
				
			||||||
  // Tm
 | 
					  // Tm
 | 
				
			||||||
  ///////////////////////////
 | 
					  ///////////////////////////
 | 
				
			||||||
  SE=st.GetEntry(ptype,Tp,sF);
 | 
					  SE = st.GetEntry(ptype, Tp, sF);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  if ( SE->_is_local ) {
 | 
					  if (SE->_is_local) {
 | 
				
			||||||
    chi_p = χ
 | 
					    chi_p = χ
 | 
				
			||||||
    if ( SE->_permute ) {
 | 
					    if (SE->_permute) {
 | 
				
			||||||
      spProjTm(tmp,in._odata[SE->_offset]);
 | 
					      spProjTm(tmp, in._odata[SE->_offset]);
 | 
				
			||||||
      permute(chi,tmp,ptype);
 | 
					      permute(chi, tmp, ptype);
 | 
				
			||||||
    } else {
 | 
					    } else {
 | 
				
			||||||
      spProjTm(chi,in._odata[SE->_offset]);
 | 
					      spProjTm(chi, in._odata[SE->_offset]);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
  } else {
 | 
					  } else {
 | 
				
			||||||
    chi_p=&buf[SE->_offset];
 | 
					    chi_p = &buf[SE->_offset];
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  Impl::multLink(Uchi,U._odata[sU],*chi_p,Tp,SE,st);
 | 
					  Impl::multLink(Uchi, U._odata[sU], *chi_p, Tp, SE, st);
 | 
				
			||||||
  accumReconTm(result,Uchi);
 | 
					  accumReconTm(result, Uchi);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  vstream(out._odata[sF],result);
 | 
					  vstream(out._odata[sF], result);
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
template<class Impl> 
 | 
					template <class Impl>
 | 
				
			||||||
void WilsonKernels<Impl>::DiracOptDhopDir(StencilImpl &st,DoubledGaugeField &U,
 | 
					void WilsonKernels<Impl>::DiracOptDhopDir(
 | 
				
			||||||
					  std::vector<SiteHalfSpinor,alignedAllocator<SiteHalfSpinor> >  &buf,
 | 
					    StencilImpl &st, DoubledGaugeField &U,
 | 
				
			||||||
					  int sF,int sU,const FermionField &in, FermionField &out,int dir,int gamma)
 | 
					    std::vector<SiteHalfSpinor, alignedAllocator<SiteHalfSpinor> > &buf, int sF,
 | 
				
			||||||
{
 | 
					    int sU, const FermionField &in, FermionField &out, int dir, int gamma) {
 | 
				
			||||||
  SiteHalfSpinor  tmp;    
 | 
					  SiteHalfSpinor tmp;
 | 
				
			||||||
  SiteHalfSpinor  chi;    
 | 
					  SiteHalfSpinor chi;
 | 
				
			||||||
  SiteSpinor   result;
 | 
					  SiteSpinor result;
 | 
				
			||||||
  SiteHalfSpinor Uchi;
 | 
					  SiteHalfSpinor Uchi;
 | 
				
			||||||
  StencilEntry *SE;
 | 
					  StencilEntry *SE;
 | 
				
			||||||
  int ptype;
 | 
					  int ptype;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  SE=st.GetEntry(ptype,dir,sF);
 | 
					  SE = st.GetEntry(ptype, dir, sF);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  // Xp
 | 
					  // Xp
 | 
				
			||||||
  if(gamma==Xp){
 | 
					  if (gamma == Xp) {
 | 
				
			||||||
    if (  SE->_is_local && SE->_permute ) {
 | 
					    if (SE->_is_local && SE->_permute) {
 | 
				
			||||||
      spProjXp(tmp,in._odata[SE->_offset]);
 | 
					      spProjXp(tmp, in._odata[SE->_offset]);
 | 
				
			||||||
      permute(chi,tmp,ptype);
 | 
					      permute(chi, tmp, ptype);
 | 
				
			||||||
    } else if ( SE->_is_local ) {
 | 
					    } else if (SE->_is_local) {
 | 
				
			||||||
      spProjXp(chi,in._odata[SE->_offset]);
 | 
					      spProjXp(chi, in._odata[SE->_offset]);
 | 
				
			||||||
    } else {
 | 
					    } else {
 | 
				
			||||||
      chi=buf[SE->_offset];
 | 
					      chi = buf[SE->_offset];
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    Impl::multLink(Uchi,U._odata[sU],chi,dir,SE,st);
 | 
					    Impl::multLink(Uchi, U._odata[sU], chi, dir, SE, st);
 | 
				
			||||||
    spReconXp(result,Uchi);
 | 
					    spReconXp(result, Uchi);
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  // Yp
 | 
					  // Yp
 | 
				
			||||||
  if ( gamma==Yp ){
 | 
					  if (gamma == Yp) {
 | 
				
			||||||
    if (  SE->_is_local && SE->_permute ) {
 | 
					    if (SE->_is_local && SE->_permute) {
 | 
				
			||||||
      spProjYp(tmp,in._odata[SE->_offset]);
 | 
					      spProjYp(tmp, in._odata[SE->_offset]);
 | 
				
			||||||
      permute(chi,tmp,ptype);
 | 
					      permute(chi, tmp, ptype);
 | 
				
			||||||
    } else if ( SE->_is_local ) {
 | 
					    } else if (SE->_is_local) {
 | 
				
			||||||
      spProjYp(chi,in._odata[SE->_offset]);
 | 
					      spProjYp(chi, in._odata[SE->_offset]);
 | 
				
			||||||
    } else {
 | 
					    } else {
 | 
				
			||||||
      chi=buf[SE->_offset];
 | 
					      chi = buf[SE->_offset];
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    Impl::multLink(Uchi,U._odata[sU],chi,dir,SE,st);
 | 
					    Impl::multLink(Uchi, U._odata[sU], chi, dir, SE, st);
 | 
				
			||||||
    spReconYp(result,Uchi);
 | 
					    spReconYp(result, Uchi);
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  // Zp
 | 
					  // Zp
 | 
				
			||||||
  if ( gamma ==Zp ){
 | 
					  if (gamma == Zp) {
 | 
				
			||||||
    if (  SE->_is_local && SE->_permute ) {
 | 
					    if (SE->_is_local && SE->_permute) {
 | 
				
			||||||
      spProjZp(tmp,in._odata[SE->_offset]);
 | 
					      spProjZp(tmp, in._odata[SE->_offset]);
 | 
				
			||||||
      permute(chi,tmp,ptype);
 | 
					      permute(chi, tmp, ptype);
 | 
				
			||||||
    } else if ( SE->_is_local ) {
 | 
					    } else if (SE->_is_local) {
 | 
				
			||||||
      spProjZp(chi,in._odata[SE->_offset]);
 | 
					      spProjZp(chi, in._odata[SE->_offset]);
 | 
				
			||||||
    } else {
 | 
					    } else {
 | 
				
			||||||
      chi=buf[SE->_offset];
 | 
					      chi = buf[SE->_offset];
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    Impl::multLink(Uchi,U._odata[sU],chi,dir,SE,st);
 | 
					    Impl::multLink(Uchi, U._odata[sU], chi, dir, SE, st);
 | 
				
			||||||
    spReconZp(result,Uchi);
 | 
					    spReconZp(result, Uchi);
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  // Tp
 | 
					  // Tp
 | 
				
			||||||
  if ( gamma ==Tp ){
 | 
					  if (gamma == Tp) {
 | 
				
			||||||
    if (  SE->_is_local && SE->_permute ) {
 | 
					    if (SE->_is_local && SE->_permute) {
 | 
				
			||||||
      spProjTp(tmp,in._odata[SE->_offset]);
 | 
					      spProjTp(tmp, in._odata[SE->_offset]);
 | 
				
			||||||
      permute(chi,tmp,ptype);
 | 
					      permute(chi, tmp, ptype);
 | 
				
			||||||
    } else if ( SE->_is_local ) {
 | 
					    } else if (SE->_is_local) {
 | 
				
			||||||
      spProjTp(chi,in._odata[SE->_offset]);
 | 
					      spProjTp(chi, in._odata[SE->_offset]);
 | 
				
			||||||
    } else {
 | 
					    } else {
 | 
				
			||||||
      chi=buf[SE->_offset];
 | 
					      chi = buf[SE->_offset];
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    Impl::multLink(Uchi,U._odata[sU],chi,dir,SE,st);
 | 
					    Impl::multLink(Uchi, U._odata[sU], chi, dir, SE, st);
 | 
				
			||||||
    spReconTp(result,Uchi);
 | 
					    spReconTp(result, Uchi);
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  // Xm
 | 
					  // Xm
 | 
				
			||||||
  if ( gamma==Xm ){
 | 
					  if (gamma == Xm) {
 | 
				
			||||||
    if (  SE->_is_local && SE->_permute ) {
 | 
					    if (SE->_is_local && SE->_permute) {
 | 
				
			||||||
      spProjXm(tmp,in._odata[SE->_offset]);
 | 
					      spProjXm(tmp, in._odata[SE->_offset]);
 | 
				
			||||||
      permute(chi,tmp,ptype);
 | 
					      permute(chi, tmp, ptype);
 | 
				
			||||||
    } else if ( SE->_is_local ) {
 | 
					    } else if (SE->_is_local) {
 | 
				
			||||||
      spProjXm(chi,in._odata[SE->_offset]);
 | 
					      spProjXm(chi, in._odata[SE->_offset]);
 | 
				
			||||||
    } else {
 | 
					    } else {
 | 
				
			||||||
      chi=buf[SE->_offset];
 | 
					      chi = buf[SE->_offset];
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    Impl::multLink(Uchi,U._odata[sU],chi,dir,SE,st);
 | 
					    Impl::multLink(Uchi, U._odata[sU], chi, dir, SE, st);
 | 
				
			||||||
    spReconXm(result,Uchi);
 | 
					    spReconXm(result, Uchi);
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  // Ym
 | 
					  // Ym
 | 
				
			||||||
  if ( gamma == Ym ){
 | 
					  if (gamma == Ym) {
 | 
				
			||||||
    if (  SE->_is_local && SE->_permute ) {
 | 
					    if (SE->_is_local && SE->_permute) {
 | 
				
			||||||
      spProjYm(tmp,in._odata[SE->_offset]);
 | 
					      spProjYm(tmp, in._odata[SE->_offset]);
 | 
				
			||||||
      permute(chi,tmp,ptype);
 | 
					      permute(chi, tmp, ptype);
 | 
				
			||||||
    } else if ( SE->_is_local ) {
 | 
					    } else if (SE->_is_local) {
 | 
				
			||||||
      spProjYm(chi,in._odata[SE->_offset]);
 | 
					      spProjYm(chi, in._odata[SE->_offset]);
 | 
				
			||||||
    } else {
 | 
					    } else {
 | 
				
			||||||
      chi=buf[SE->_offset];
 | 
					      chi = buf[SE->_offset];
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    Impl::multLink(Uchi,U._odata[sU],chi,dir,SE,st);
 | 
					    Impl::multLink(Uchi, U._odata[sU], chi, dir, SE, st);
 | 
				
			||||||
    spReconYm(result,Uchi);
 | 
					    spReconYm(result, Uchi);
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  // Zm
 | 
					  // Zm
 | 
				
			||||||
  if ( gamma == Zm ){
 | 
					  if (gamma == Zm) {
 | 
				
			||||||
    if (  SE->_is_local && SE->_permute ) {
 | 
					    if (SE->_is_local && SE->_permute) {
 | 
				
			||||||
      spProjZm(tmp,in._odata[SE->_offset]);
 | 
					      spProjZm(tmp, in._odata[SE->_offset]);
 | 
				
			||||||
      permute(chi,tmp,ptype);
 | 
					      permute(chi, tmp, ptype);
 | 
				
			||||||
    } else if ( SE->_is_local ) {
 | 
					    } else if (SE->_is_local) {
 | 
				
			||||||
      spProjZm(chi,in._odata[SE->_offset]);
 | 
					      spProjZm(chi, in._odata[SE->_offset]);
 | 
				
			||||||
    } else {
 | 
					    } else {
 | 
				
			||||||
      chi=buf[SE->_offset];
 | 
					      chi = buf[SE->_offset];
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    Impl::multLink(Uchi,U._odata[sU],chi,dir,SE,st);
 | 
					    Impl::multLink(Uchi, U._odata[sU], chi, dir, SE, st);
 | 
				
			||||||
    spReconZm(result,Uchi);
 | 
					    spReconZm(result, Uchi);
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  // Tm
 | 
					  // Tm
 | 
				
			||||||
  if ( gamma==Tm ) {
 | 
					  if (gamma == Tm) {
 | 
				
			||||||
    if (  SE->_is_local && SE->_permute ) {
 | 
					    if (SE->_is_local && SE->_permute) {
 | 
				
			||||||
      spProjTm(tmp,in._odata[SE->_offset]);
 | 
					      spProjTm(tmp, in._odata[SE->_offset]);
 | 
				
			||||||
      permute(chi,tmp,ptype);
 | 
					      permute(chi, tmp, ptype);
 | 
				
			||||||
    } else if ( SE->_is_local ) {
 | 
					    } else if (SE->_is_local) {
 | 
				
			||||||
      spProjTm(chi,in._odata[SE->_offset]);
 | 
					      spProjTm(chi, in._odata[SE->_offset]);
 | 
				
			||||||
    } else {
 | 
					    } else {
 | 
				
			||||||
      chi=buf[SE->_offset];
 | 
					      chi = buf[SE->_offset];
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    Impl::multLink(Uchi,U._odata[sU],chi,dir,SE,st);
 | 
					    Impl::multLink(Uchi, U._odata[sU], chi, dir, SE, st);
 | 
				
			||||||
    spReconTm(result,Uchi);
 | 
					    spReconTm(result, Uchi);
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  vstream(out._odata[sF],result);
 | 
					  vstream(out._odata[sF], result);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					FermOpTemplateInstantiate(WilsonKernels);
 | 
				
			||||||
  FermOpTemplateInstantiate(WilsonKernels);
 | 
					AdjointFermOpTemplateInstantiate(WilsonKernels);
 | 
				
			||||||
 | 
					TwoIndexFermOpTemplateInstantiate(WilsonKernels);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
}}
 | 
					}}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,34 +1,35 @@
 | 
				
			|||||||
    /*************************************************************************************
 | 
					/*************************************************************************************
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    Grid physics library, www.github.com/paboyle/Grid 
 | 
					Grid physics library, www.github.com/paboyle/Grid
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    Source file: ./lib/qcd/action/fermion/WilsonKernels.h
 | 
					Source file: ./lib/qcd/action/fermion/WilsonKernels.h
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    Copyright (C) 2015
 | 
					Copyright (C) 2015
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Author: Peter Boyle <pabobyle@ph.ed.ac.uk>
 | 
					Author: Peter Boyle <pabobyle@ph.ed.ac.uk>
 | 
				
			||||||
Author: Peter Boyle <paboyle@ph.ed.ac.uk>
 | 
					Author: Peter Boyle <paboyle@ph.ed.ac.uk>
 | 
				
			||||||
Author: paboyle <paboyle@ph.ed.ac.uk>
 | 
					Author: paboyle <paboyle@ph.ed.ac.uk>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    This program is free software; you can redistribute it and/or modify
 | 
					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
 | 
					it under the terms of the GNU General Public License as published by
 | 
				
			||||||
    the Free Software Foundation; either version 2 of the License, or
 | 
					the Free Software Foundation; either version 2 of the License, or
 | 
				
			||||||
    (at your option) any later version.
 | 
					(at your option) any later version.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    This program is distributed in the hope that it will be useful,
 | 
					This program is distributed in the hope that it will be useful,
 | 
				
			||||||
    but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
					but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
				
			||||||
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
					MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
				
			||||||
    GNU General Public License for more details.
 | 
					GNU General Public License for more details.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    You should have received a copy of the GNU General Public License along
 | 
					You should have received a copy of the GNU General Public License along
 | 
				
			||||||
    with this program; if not, write to the Free Software Foundation, Inc.,
 | 
					with this program; if not, write to the Free Software Foundation, Inc.,
 | 
				
			||||||
    51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 | 
					51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    See the full license in the file "LICENSE" in the top level distribution directory
 | 
					See the full license in the file "LICENSE" in the top level distribution
 | 
				
			||||||
    *************************************************************************************/
 | 
					directory
 | 
				
			||||||
    /*  END LEGAL */
 | 
					*************************************************************************************/
 | 
				
			||||||
#ifndef  GRID_QCD_DHOP_H
 | 
					/*  END LEGAL */
 | 
				
			||||||
#define  GRID_QCD_DHOP_H
 | 
					#ifndef GRID_QCD_DHOP_H
 | 
				
			||||||
 | 
					#define GRID_QCD_DHOP_H
 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace Grid {
 | 
					namespace Grid {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -48,51 +49,158 @@ namespace Grid {
 | 
				
			|||||||
    template<class Impl> class WilsonKernels : public FermionOperator<Impl> , public WilsonKernelsStatic { 
 | 
					    template<class Impl> class WilsonKernels : public FermionOperator<Impl> , public WilsonKernelsStatic { 
 | 
				
			||||||
    public:
 | 
					    public:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
     INHERIT_IMPL_TYPES(Impl);
 | 
					      INHERIT_IMPL_TYPES(Impl);
 | 
				
			||||||
     typedef FermionOperator<Impl> Base;
 | 
					      typedef FermionOperator<Impl> Base;
 | 
				
			||||||
     
 | 
					     
 | 
				
			||||||
    public:
 | 
					    public:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
     void DiracOptDhopSite(StencilImpl &st,LebesgueOrder &lo,DoubledGaugeField &U,
 | 
					      template <bool EnableBool = true>
 | 
				
			||||||
			   std::vector<SiteHalfSpinor,alignedAllocator<SiteHalfSpinor> >  &buf,
 | 
					      typename std::enable_if<Impl::Dimension == 3 && Nc == 3 &&EnableBool, void>::type
 | 
				
			||||||
			   int sF, int sU,int Ls, int Ns, const FermionField &in, FermionField &out);
 | 
						DiracOptDhopSite(
 | 
				
			||||||
 | 
								 StencilImpl &st, LebesgueOrder &lo, DoubledGaugeField &U,
 | 
				
			||||||
 | 
								 std::vector<SiteHalfSpinor, alignedAllocator<SiteHalfSpinor> > &buf,
 | 
				
			||||||
 | 
								 int sF, int sU, int Ls, int Ns, const FermionField &in,
 | 
				
			||||||
 | 
								 FermionField &out) {
 | 
				
			||||||
 | 
					#ifdef AVX512
 | 
				
			||||||
 | 
						if (AsmOpt) {
 | 
				
			||||||
 | 
						  WilsonKernels<Impl>::DiracOptAsmDhopSite(st, lo, U, buf, sF, sU, Ls, Ns,
 | 
				
			||||||
 | 
											   in, out);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						} else {
 | 
				
			||||||
 | 
					#else
 | 
				
			||||||
 | 
						  {
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
						    for (int site = 0; site < Ns; site++) {
 | 
				
			||||||
 | 
						      for (int s = 0; s < Ls; s++) {
 | 
				
			||||||
 | 
							if (HandOpt)
 | 
				
			||||||
 | 
							  WilsonKernels<Impl>::DiracOptHandDhopSite(st, lo, U, buf, sF, sU,
 | 
				
			||||||
 | 
												    in, out);
 | 
				
			||||||
 | 
							else
 | 
				
			||||||
 | 
							  WilsonKernels<Impl>::DiracOptGenericDhopSite(st, lo, U, buf, sF, sU,
 | 
				
			||||||
 | 
												       in, out);
 | 
				
			||||||
 | 
							sF++;
 | 
				
			||||||
 | 
						      }
 | 
				
			||||||
 | 
						      sU++;
 | 
				
			||||||
 | 
						    }
 | 
				
			||||||
 | 
						  }
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						template <bool EnableBool = true>
 | 
				
			||||||
 | 
						  typename std::enable_if<(Impl::Dimension != 3 || (Impl::Dimension == 3 && Nc != 3)) && EnableBool, void>::type
 | 
				
			||||||
 | 
						  DiracOptDhopSite(
 | 
				
			||||||
 | 
								   StencilImpl &st, LebesgueOrder &lo, DoubledGaugeField &U,
 | 
				
			||||||
 | 
								   std::vector<SiteHalfSpinor, alignedAllocator<SiteHalfSpinor> > &buf,
 | 
				
			||||||
 | 
								   int sF, int sU, int Ls, int Ns, const FermionField &in,
 | 
				
			||||||
 | 
								   FermionField &out) {
 | 
				
			||||||
 | 
						  for (int site = 0; site < Ns; site++) {
 | 
				
			||||||
 | 
						    for (int s = 0; s < Ls; s++) {
 | 
				
			||||||
 | 
						      WilsonKernels<Impl>::DiracOptGenericDhopSite(st, lo, U, buf, sF, sU, in,
 | 
				
			||||||
 | 
												   out);
 | 
				
			||||||
 | 
						      sF++;
 | 
				
			||||||
 | 
						    }
 | 
				
			||||||
 | 
						    sU++;
 | 
				
			||||||
 | 
						  }
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						template <bool EnableBool = true>
 | 
				
			||||||
 | 
						  typename std::enable_if<Impl::Dimension == 3 && Nc == 3 && EnableBool,
 | 
				
			||||||
 | 
									  void>::type
 | 
				
			||||||
 | 
						  DiracOptDhopSiteDag(
 | 
				
			||||||
 | 
								      StencilImpl &st, LebesgueOrder &lo, DoubledGaugeField &U,
 | 
				
			||||||
 | 
								      std::vector<SiteHalfSpinor, alignedAllocator<SiteHalfSpinor> > &buf,
 | 
				
			||||||
 | 
								      int sF, int sU, int Ls, int Ns, const FermionField &in,
 | 
				
			||||||
 | 
								      FermionField &out) {
 | 
				
			||||||
 | 
					#ifdef AVX512
 | 
				
			||||||
 | 
									    if (AsmOpt) {
 | 
				
			||||||
 | 
									      WilsonKernels<Impl>::DiracOptAsmDhopSiteDag(st, lo, U, buf, sF, sU, Ls,
 | 
				
			||||||
 | 
															  Ns, in, out);
 | 
				
			||||||
 | 
									    } else {
 | 
				
			||||||
 | 
					#else
 | 
				
			||||||
 | 
									      {
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
										for (int site = 0; site < Ns; site++) {
 | 
				
			||||||
 | 
										  for (int s = 0; s < Ls; s++) {
 | 
				
			||||||
 | 
										    if (HandOpt)
 | 
				
			||||||
 | 
										      WilsonKernels<Impl>::DiracOptHandDhopSiteDag(st, lo, U, buf, sF, sU,
 | 
				
			||||||
 | 
																   in, out);
 | 
				
			||||||
 | 
										    else
 | 
				
			||||||
 | 
										      WilsonKernels<Impl>::DiracOptGenericDhopSiteDag(st, lo, U, buf, sF,
 | 
				
			||||||
 | 
																      sU, in, out);
 | 
				
			||||||
 | 
										    sF++;
 | 
				
			||||||
 | 
										  }
 | 
				
			||||||
 | 
										  sU++;
 | 
				
			||||||
 | 
										}
 | 
				
			||||||
 | 
									      }
 | 
				
			||||||
 | 
									    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
									    template <bool EnableBool = true>
 | 
				
			||||||
 | 
									      typename std::enable_if<
 | 
				
			||||||
 | 
									      (Impl::Dimension != 3 || (Impl::Dimension == 3 && Nc != 3)) && EnableBool,
 | 
				
			||||||
 | 
									      void>::type
 | 
				
			||||||
 | 
									      DiracOptDhopSiteDag(
 | 
				
			||||||
 | 
												  StencilImpl &st, LebesgueOrder &lo, DoubledGaugeField &U,
 | 
				
			||||||
 | 
												  std::vector<SiteHalfSpinor, alignedAllocator<SiteHalfSpinor> > &buf,
 | 
				
			||||||
 | 
												  int sF, int sU, int Ls, int Ns, const FermionField &in,
 | 
				
			||||||
 | 
												  FermionField &out) {
 | 
				
			||||||
 | 
										for (int site = 0; site < Ns; site++) {
 | 
				
			||||||
 | 
										  for (int s = 0; s < Ls; s++) {
 | 
				
			||||||
 | 
										    WilsonKernels<Impl>::DiracOptGenericDhopSiteDag(st, lo, U, buf, sF, sU,
 | 
				
			||||||
 | 
																    in, out);
 | 
				
			||||||
 | 
										    sF++;
 | 
				
			||||||
 | 
										  }
 | 
				
			||||||
 | 
										  sU++;
 | 
				
			||||||
 | 
										}
 | 
				
			||||||
 | 
									      }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
									    void DiracOptDhopDir(
 | 
				
			||||||
 | 
												 StencilImpl &st, DoubledGaugeField &U,
 | 
				
			||||||
 | 
												 std::vector<SiteHalfSpinor, alignedAllocator<SiteHalfSpinor> > &buf,
 | 
				
			||||||
 | 
												 int sF, int sU, const FermionField &in, FermionField &out, int dirdisp,
 | 
				
			||||||
 | 
												 int gamma);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						private:
 | 
				
			||||||
 | 
									    // Specialised variants
 | 
				
			||||||
 | 
									    void DiracOptGenericDhopSite(
 | 
				
			||||||
 | 
													 StencilImpl &st, LebesgueOrder &lo, DoubledGaugeField &U,
 | 
				
			||||||
 | 
													 std::vector<SiteHalfSpinor, alignedAllocator<SiteHalfSpinor> > &buf,
 | 
				
			||||||
 | 
													 int sF, int sU, const FermionField &in, FermionField &out);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
									    void DiracOptGenericDhopSiteDag(
 | 
				
			||||||
 | 
													    StencilImpl &st, LebesgueOrder &lo, DoubledGaugeField &U,
 | 
				
			||||||
 | 
													    std::vector<SiteHalfSpinor, alignedAllocator<SiteHalfSpinor> > &buf,
 | 
				
			||||||
 | 
													    int sF, int sU, const FermionField &in, FermionField &out);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
									    void DiracOptAsmDhopSite(
 | 
				
			||||||
 | 
												     StencilImpl &st, LebesgueOrder &lo, DoubledGaugeField &U,
 | 
				
			||||||
 | 
												     std::vector<SiteHalfSpinor, alignedAllocator<SiteHalfSpinor> > &buf,
 | 
				
			||||||
 | 
												     int sF, int sU, int Ls, int Ns, const FermionField &in,
 | 
				
			||||||
 | 
												     FermionField &out);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
									    void DiracOptAsmDhopSiteDag(
 | 
				
			||||||
 | 
													StencilImpl &st, LebesgueOrder &lo, DoubledGaugeField &U,
 | 
				
			||||||
 | 
													std::vector<SiteHalfSpinor, alignedAllocator<SiteHalfSpinor> > &buf,
 | 
				
			||||||
 | 
													int sF, int sU, int Ls, int Ns, const FermionField &in,
 | 
				
			||||||
 | 
													FermionField &out);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
									    void DiracOptHandDhopSite(
 | 
				
			||||||
 | 
												      StencilImpl &st, LebesgueOrder &lo, DoubledGaugeField &U,
 | 
				
			||||||
 | 
												      std::vector<SiteHalfSpinor, alignedAllocator<SiteHalfSpinor> > &buf,
 | 
				
			||||||
 | 
												      int sF, int sU, const FermionField &in, FermionField &out);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
									    void DiracOptHandDhopSiteDag(
 | 
				
			||||||
 | 
													 StencilImpl &st, LebesgueOrder &lo, DoubledGaugeField &U,
 | 
				
			||||||
 | 
													 std::vector<SiteHalfSpinor, alignedAllocator<SiteHalfSpinor> > &buf,
 | 
				
			||||||
 | 
													 int sF, int sU, const FermionField &in, FermionField &out);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						public:
 | 
				
			||||||
 | 
									    WilsonKernels(const ImplParams &p = ImplParams());
 | 
				
			||||||
 | 
									  };
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
     void DiracOptDhopSiteDag(StencilImpl &st,LebesgueOrder &lo,DoubledGaugeField &U,
 | 
					 | 
				
			||||||
			      std::vector<SiteHalfSpinor,alignedAllocator<SiteHalfSpinor> >  &buf,
 | 
					 | 
				
			||||||
			      int sF,int sU,int Ls, int Ns, const FermionField &in,FermionField &out);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
     void DiracOptDhopDir(StencilImpl &st,DoubledGaugeField &U,
 | 
					 | 
				
			||||||
			  std::vector<SiteHalfSpinor,alignedAllocator<SiteHalfSpinor> >  &buf,
 | 
					 | 
				
			||||||
			  int sF,int sU,const FermionField &in, FermionField &out,int dirdisp,int gamma);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    private:
 | 
					 | 
				
			||||||
     // Specialised variants
 | 
					 | 
				
			||||||
     void DiracOptGenericDhopSite(StencilImpl &st,LebesgueOrder &lo,DoubledGaugeField &U,
 | 
					 | 
				
			||||||
			   std::vector<SiteHalfSpinor,alignedAllocator<SiteHalfSpinor> >  &buf,
 | 
					 | 
				
			||||||
			   int sF,int sU, const FermionField &in, FermionField &out);
 | 
					 | 
				
			||||||
      
 | 
					 | 
				
			||||||
     void DiracOptGenericDhopSiteDag(StencilImpl &st,LebesgueOrder &lo,DoubledGaugeField &U,
 | 
					 | 
				
			||||||
			      std::vector<SiteHalfSpinor,alignedAllocator<SiteHalfSpinor> >  &buf,
 | 
					 | 
				
			||||||
			      int sF,int sU,const FermionField &in,FermionField &out);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
     void DiracOptAsmDhopSite(StencilImpl &st,LebesgueOrder &lo,DoubledGaugeField &U,
 | 
					 | 
				
			||||||
			      std::vector<SiteHalfSpinor,alignedAllocator<SiteHalfSpinor> >  &buf,
 | 
					 | 
				
			||||||
			      int sF,int sU,int Ls, int Ns, const FermionField &in, FermionField &out);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
     void DiracOptHandDhopSite(StencilImpl &st,LebesgueOrder &lo,DoubledGaugeField &U,
 | 
					 | 
				
			||||||
			      std::vector<SiteHalfSpinor,alignedAllocator<SiteHalfSpinor> >  &buf,
 | 
					 | 
				
			||||||
			      int sF,int sU,const FermionField &in, FermionField &out);
 | 
					 | 
				
			||||||
     
 | 
					 | 
				
			||||||
     void DiracOptHandDhopSiteDag(StencilImpl &st,LebesgueOrder &lo,DoubledGaugeField &U,
 | 
					 | 
				
			||||||
				 std::vector<SiteHalfSpinor,alignedAllocator<SiteHalfSpinor> >  &buf,
 | 
					 | 
				
			||||||
				 int sF,int sU,const FermionField &in, FermionField &out);
 | 
					 | 
				
			||||||
    public:
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
     WilsonKernels(const ImplParams &p= ImplParams());
 | 
					 | 
				
			||||||
     
 | 
					 | 
				
			||||||
    };
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,4 +1,4 @@
 | 
				
			|||||||
    /*************************************************************************************
 | 
					/*************************************************************************************
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    Grid physics library, www.github.com/paboyle/Grid 
 | 
					    Grid physics library, www.github.com/paboyle/Grid 
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -26,46 +26,55 @@ Author: paboyle <paboyle@ph.ed.ac.uk>
 | 
				
			|||||||
    51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 | 
					    51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    See the full license in the file "LICENSE" in the top level distribution directory
 | 
					    See the full license in the file "LICENSE" in the top level distribution directory
 | 
				
			||||||
    *************************************************************************************/
 | 
					*************************************************************************************/
 | 
				
			||||||
    /*  END LEGAL */
 | 
					/*  END LEGAL */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include <Grid.h>
 | 
					#include <Grid.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace Grid {
 | 
					namespace Grid {
 | 
				
			||||||
namespace QCD {
 | 
					  namespace QCD {
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    ///////////////////////////////////////////////////////////
 | 
				
			||||||
 | 
					    // Default to no assembler implementation
 | 
				
			||||||
 | 
					    ///////////////////////////////////////////////////////////
 | 
				
			||||||
 | 
					    template<class Impl>
 | 
				
			||||||
 | 
					      void WilsonKernels<Impl >::DiracOptAsmDhopSite(StencilImpl &st,LebesgueOrder & lo,DoubledGaugeField &U,
 | 
				
			||||||
 | 
					                             std::vector<SiteHalfSpinor,alignedAllocator<SiteHalfSpinor> >  &buf,
 | 
				
			||||||
 | 
					                             int ss,int ssU,int Ls,int Ns,const FermionField &in, FermionField &out)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					      assert(0);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    template<class Impl>
 | 
				
			||||||
 | 
					      void WilsonKernels<Impl >::DiracOptAsmDhopSiteDag(StencilImpl &st,LebesgueOrder & lo,DoubledGaugeField &U,
 | 
				
			||||||
 | 
					                                std::vector<SiteHalfSpinor,alignedAllocator<SiteHalfSpinor> >  &buf,
 | 
				
			||||||
 | 
					                                int ss,int ssU,int Ls,int Ns,const FermionField &in, FermionField &out)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					      assert(0);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  ///////////////////////////////////////////////////////////
 | 
					 | 
				
			||||||
  // Default to no assembler implementation
 | 
					 | 
				
			||||||
  ///////////////////////////////////////////////////////////
 | 
					 | 
				
			||||||
template<class Impl>
 | 
					 | 
				
			||||||
void WilsonKernels<Impl >::DiracOptAsmDhopSite(StencilImpl &st,LebesgueOrder & lo,DoubledGaugeField &U,
 | 
					 | 
				
			||||||
					       std::vector<SiteHalfSpinor,alignedAllocator<SiteHalfSpinor> >  &buf,
 | 
					 | 
				
			||||||
					       int ss,int ssU,int Ls,int Ns,const FermionField &in, FermionField &out)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
  assert(0);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
#if defined(AVX512) 
 | 
					#if defined(AVX512) 
 | 
				
			||||||
    
 | 
					    
 | 
				
			||||||
    
 | 
					    
 | 
				
			||||||
  ///////////////////////////////////////////////////////////
 | 
					    ///////////////////////////////////////////////////////////
 | 
				
			||||||
  // If we are AVX512 specialise the single precision routine
 | 
					    // If we are AVX512 specialise the single precision routine
 | 
				
			||||||
  ///////////////////////////////////////////////////////////
 | 
					    ///////////////////////////////////////////////////////////
 | 
				
			||||||
    
 | 
					    
 | 
				
			||||||
#include <simd/Intel512wilson.h>
 | 
					#include <simd/Intel512wilson.h>
 | 
				
			||||||
#include <simd/Intel512single.h>
 | 
					#include <simd/Intel512single.h>
 | 
				
			||||||
    
 | 
					    
 | 
				
			||||||
static Vector<vComplexF> signs;
 | 
					    static Vector<vComplexF> signs;
 | 
				
			||||||
    
 | 
					    
 | 
				
			||||||
int setupSigns(void ){
 | 
					    int setupSigns(void ){
 | 
				
			||||||
  Vector<vComplexF> bother(2);
 | 
					      Vector<vComplexF> bother(2);
 | 
				
			||||||
  signs = bother;
 | 
					      signs = bother;
 | 
				
			||||||
  vrsign(signs[0]);
 | 
					      vrsign(signs[0]);
 | 
				
			||||||
  visign(signs[1]);
 | 
					      visign(signs[1]);
 | 
				
			||||||
  return 1;
 | 
					      return 1;
 | 
				
			||||||
}
 | 
					    }
 | 
				
			||||||
static int signInit = setupSigns();
 | 
					    static int signInit = setupSigns();
 | 
				
			||||||
  
 | 
					  
 | 
				
			||||||
#define label(A)  ilabel(A)
 | 
					#define label(A)  ilabel(A)
 | 
				
			||||||
#define ilabel(A) ".globl\n"  #A ":\n" 
 | 
					#define ilabel(A) ".globl\n"  #A ":\n" 
 | 
				
			||||||
@@ -73,10 +82,19 @@ static int signInit = setupSigns();
 | 
				
			|||||||
#define MAYBEPERM(A,perm) if (perm) { A ; }
 | 
					#define MAYBEPERM(A,perm) if (perm) { A ; }
 | 
				
			||||||
#define MULT_2SPIN(ptr,pf) MULT_ADDSUB_2SPIN(ptr,pf)
 | 
					#define MULT_2SPIN(ptr,pf) MULT_ADDSUB_2SPIN(ptr,pf)
 | 
				
			||||||
#define FX(A) WILSONASM_ ##A
 | 
					#define FX(A) WILSONASM_ ##A
 | 
				
			||||||
template<>
 | 
					  
 | 
				
			||||||
void WilsonKernels<WilsonImplF>::DiracOptAsmDhopSite(StencilImpl &st,LebesgueOrder & lo,DoubledGaugeField &U,
 | 
					#undef KERNEL_DAG
 | 
				
			||||||
						     std::vector<SiteHalfSpinor,alignedAllocator<SiteHalfSpinor> >  &buf,
 | 
					    template<>
 | 
				
			||||||
						     int ss,int ssU,int Ls,int Ns,const FermionField &in, FermionField &out)
 | 
					    void WilsonKernels<WilsonImplF>::DiracOptAsmDhopSite(StencilImpl &st,LebesgueOrder & lo,DoubledGaugeField &U,
 | 
				
			||||||
 | 
												 std::vector<SiteHalfSpinor,alignedAllocator<SiteHalfSpinor> >  &buf,
 | 
				
			||||||
 | 
												 int ss,int ssU,int Ls,int Ns,const FermionField &in, FermionField &out)
 | 
				
			||||||
 | 
					#include <qcd/action/fermion/WilsonKernelsAsmBody.h>
 | 
				
			||||||
 | 
					      
 | 
				
			||||||
 | 
					#define KERNEL_DAG
 | 
				
			||||||
 | 
					    template<>
 | 
				
			||||||
 | 
					    void WilsonKernels<WilsonImplF>::DiracOptAsmDhopSiteDag(StencilImpl &st,LebesgueOrder & lo,DoubledGaugeField &U,
 | 
				
			||||||
 | 
												    std::vector<SiteHalfSpinor,alignedAllocator<SiteHalfSpinor> >  &buf,
 | 
				
			||||||
 | 
												    int ss,int ssU,int Ls,int Ns,const FermionField &in, FermionField &out)
 | 
				
			||||||
#include <qcd/action/fermion/WilsonKernelsAsmBody.h>
 | 
					#include <qcd/action/fermion/WilsonKernelsAsmBody.h>
 | 
				
			||||||
				    
 | 
									    
 | 
				
			||||||
#undef VMOVIDUP
 | 
					#undef VMOVIDUP
 | 
				
			||||||
@@ -89,32 +107,43 @@ void WilsonKernels<WilsonImplF>::DiracOptAsmDhopSite(StencilImpl &st,LebesgueOrd
 | 
				
			|||||||
#define VMOVIDUP(A,B,C)                                  VBCASTIDUPf(A,B,C)
 | 
					#define VMOVIDUP(A,B,C)                                  VBCASTIDUPf(A,B,C)
 | 
				
			||||||
#define VMOVRDUP(A,B,C)                                  VBCASTRDUPf(A,B,C)
 | 
					#define VMOVRDUP(A,B,C)                                  VBCASTRDUPf(A,B,C)
 | 
				
			||||||
#define MULT_2SPIN(ptr,pf) MULT_ADDSUB_2SPIN_LS(ptr,pf)
 | 
					#define MULT_2SPIN(ptr,pf) MULT_ADDSUB_2SPIN_LS(ptr,pf)
 | 
				
			||||||
template<>
 | 
									    
 | 
				
			||||||
void WilsonKernels<DomainWallVec5dImplF>::DiracOptAsmDhopSite(StencilImpl &st,LebesgueOrder & lo,DoubledGaugeField &U,
 | 
					#undef KERNEL_DAG
 | 
				
			||||||
								   std::vector<SiteHalfSpinor,alignedAllocator<SiteHalfSpinor> >  &buf,
 | 
					    template<>
 | 
				
			||||||
								   int ss,int ssU,int Ls,int Ns,const FermionField &in, FermionField &out)
 | 
					    void WilsonKernels<DomainWallVec5dImplF>::DiracOptAsmDhopSite(StencilImpl &st,LebesgueOrder & lo,DoubledGaugeField &U,
 | 
				
			||||||
 | 
													  std::vector<SiteHalfSpinor,alignedAllocator<SiteHalfSpinor> >  &buf,
 | 
				
			||||||
 | 
													  int ss,int ssU,int Ls,int Ns,const FermionField &in, FermionField &out)
 | 
				
			||||||
 | 
					#include <qcd/action/fermion/WilsonKernelsAsmBody.h>
 | 
				
			||||||
 | 
									    
 | 
				
			||||||
 | 
					#define KERNEL_DAG
 | 
				
			||||||
 | 
					    template<>
 | 
				
			||||||
 | 
					    void WilsonKernels<DomainWallVec5dImplF>::DiracOptAsmDhopSiteDag(StencilImpl &st,LebesgueOrder & lo,DoubledGaugeField &U,
 | 
				
			||||||
 | 
													     std::vector<SiteHalfSpinor,alignedAllocator<SiteHalfSpinor> >  &buf,
 | 
				
			||||||
 | 
													     int ss,int ssU,int Ls,int Ns,const FermionField &in, FermionField &out)
 | 
				
			||||||
#include <qcd/action/fermion/WilsonKernelsAsmBody.h>
 | 
					#include <qcd/action/fermion/WilsonKernelsAsmBody.h>
 | 
				
			||||||
				    
 | 
									    
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
template void WilsonKernels<WilsonImplF>::DiracOptAsmDhopSite(StencilImpl &st,LebesgueOrder & lo,DoubledGaugeField &U,
 | 
					 | 
				
			||||||
							       std::vector<SiteHalfSpinor,alignedAllocator<SiteHalfSpinor> >  &buf,
 | 
					 | 
				
			||||||
							      int ss,int ssU,int Ls,int Ns,const FermionField &in, FermionField &out);		
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
template void WilsonKernels<WilsonImplD>::DiracOptAsmDhopSite(StencilImpl &st,LebesgueOrder & lo,DoubledGaugeField &U, 
 | 
					#define INSTANTIATE_ASM(A)\
 | 
				
			||||||
							       std::vector<SiteHalfSpinor,alignedAllocator<SiteHalfSpinor> >  &buf,
 | 
					template void WilsonKernels<A>::DiracOptAsmDhopSite(StencilImpl &st,LebesgueOrder & lo,DoubledGaugeField &U,\
 | 
				
			||||||
							       int ss,int ssU,int Ls,int Ns,const FermionField &in, FermionField &out);		
 | 
					                                   std::vector<SiteHalfSpinor,alignedAllocator<SiteHalfSpinor> >  &buf,\
 | 
				
			||||||
template void WilsonKernels<GparityWilsonImplF>::DiracOptAsmDhopSite(StencilImpl &st,LebesgueOrder & lo,DoubledGaugeField &U, 
 | 
					                                  int ss,int ssU,int Ls,int Ns,const FermionField &in, FermionField &out);\
 | 
				
			||||||
							       std::vector<SiteHalfSpinor,alignedAllocator<SiteHalfSpinor> >  &buf,
 | 
					template void WilsonKernels<A>::DiracOptAsmDhopSiteDag(StencilImpl &st,LebesgueOrder & lo,DoubledGaugeField &U,\
 | 
				
			||||||
							       int ss,int ssU,int Ls,int Ns,const FermionField &in, FermionField &out);		
 | 
					                                   std::vector<SiteHalfSpinor,alignedAllocator<SiteHalfSpinor> >  &buf,\
 | 
				
			||||||
template void WilsonKernels<GparityWilsonImplD>::DiracOptAsmDhopSite(StencilImpl &st,LebesgueOrder & lo,DoubledGaugeField &U, 
 | 
					                                  int ss,int ssU,int Ls,int Ns,const FermionField &in, FermionField &out);\
 | 
				
			||||||
							       std::vector<SiteHalfSpinor,alignedAllocator<SiteHalfSpinor> >  &buf,
 | 
					
 | 
				
			||||||
							       int ss,int ssU,int Ls,int Ns,const FermionField &in, FermionField &out);		
 | 
					
 | 
				
			||||||
template void WilsonKernels<DomainWallVec5dImplF>::DiracOptAsmDhopSite(StencilImpl &st,LebesgueOrder & lo,DoubledGaugeField &U, 
 | 
					INSTANTIATE_ASM(WilsonImplF);
 | 
				
			||||||
							       std::vector<SiteHalfSpinor,alignedAllocator<SiteHalfSpinor> >  &buf,
 | 
					INSTANTIATE_ASM(WilsonImplD);
 | 
				
			||||||
							       int ss,int ssU,int Ls,int Ns,const FermionField &in, FermionField &out);		
 | 
					INSTANTIATE_ASM(ZWilsonImplF);
 | 
				
			||||||
template void WilsonKernels<DomainWallVec5dImplD>::DiracOptAsmDhopSite(StencilImpl &st,LebesgueOrder & lo,DoubledGaugeField &U, 
 | 
					INSTANTIATE_ASM(ZWilsonImplD);
 | 
				
			||||||
							       std::vector<SiteHalfSpinor,alignedAllocator<SiteHalfSpinor> >  &buf,
 | 
					INSTANTIATE_ASM(GparityWilsonImplF);
 | 
				
			||||||
							       int ss,int ssU,int Ls,int Ns,const FermionField &in, FermionField &out);		
 | 
					INSTANTIATE_ASM(GparityWilsonImplD);
 | 
				
			||||||
}}
 | 
					INSTANTIATE_ASM(DomainWallVec5dImplF);
 | 
				
			||||||
 | 
					INSTANTIATE_ASM(DomainWallVec5dImplD);
 | 
				
			||||||
 | 
					INSTANTIATE_ASM(ZDomainWallVec5dImplF);
 | 
				
			||||||
 | 
					INSTANTIATE_ASM(ZDomainWallVec5dImplD);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -30,7 +30,11 @@
 | 
				
			|||||||
  basep = st.GetPFInfo(nent,plocal); nent++;
 | 
					  basep = st.GetPFInfo(nent,plocal); nent++;
 | 
				
			||||||
  if ( local ) {
 | 
					  if ( local ) {
 | 
				
			||||||
    LOAD64(%r10,isigns);
 | 
					    LOAD64(%r10,isigns);
 | 
				
			||||||
 | 
					#ifdef KERNEL_DAG
 | 
				
			||||||
 | 
					    XP_PROJMEM(base);
 | 
				
			||||||
 | 
					#else 
 | 
				
			||||||
    XM_PROJMEM(base);
 | 
					    XM_PROJMEM(base);
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
    MAYBEPERM(PERMUTE_DIR3,perm);
 | 
					    MAYBEPERM(PERMUTE_DIR3,perm);
 | 
				
			||||||
  } else { 
 | 
					  } else { 
 | 
				
			||||||
    LOAD_CHI(base);
 | 
					    LOAD_CHI(base);
 | 
				
			||||||
@@ -41,15 +45,22 @@
 | 
				
			|||||||
    MULT_2SPIN_DIR_PFXP(Xp,basep);
 | 
					    MULT_2SPIN_DIR_PFXP(Xp,basep);
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
  LOAD64(%r10,isigns);
 | 
					  LOAD64(%r10,isigns);
 | 
				
			||||||
 | 
					#ifdef KERNEL_DAG
 | 
				
			||||||
 | 
					  XP_RECON;
 | 
				
			||||||
 | 
					#else
 | 
				
			||||||
  XM_RECON;
 | 
					  XM_RECON;
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
  ////////////////////////////////
 | 
					  ////////////////////////////////
 | 
				
			||||||
  // Yp
 | 
					  // Yp
 | 
				
			||||||
  ////////////////////////////////
 | 
					  ////////////////////////////////
 | 
				
			||||||
  basep = st.GetPFInfo(nent,plocal); nent++;
 | 
					  basep = st.GetPFInfo(nent,plocal); nent++;
 | 
				
			||||||
  if ( local ) {
 | 
					  if ( local ) {
 | 
				
			||||||
    LOAD64(%r10,isigns);  // times i => shuffle and xor the real part sign bit
 | 
					    LOAD64(%r10,isigns);  // times i => shuffle and xor the real part sign bit
 | 
				
			||||||
 | 
					#ifdef KERNEL_DAG
 | 
				
			||||||
 | 
					    YP_PROJMEM(base);
 | 
				
			||||||
 | 
					#else
 | 
				
			||||||
    YM_PROJMEM(base);
 | 
					    YM_PROJMEM(base);
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
    MAYBEPERM(PERMUTE_DIR2,perm);
 | 
					    MAYBEPERM(PERMUTE_DIR2,perm);
 | 
				
			||||||
  } else { 
 | 
					  } else { 
 | 
				
			||||||
    LOAD_CHI(base);
 | 
					    LOAD_CHI(base);
 | 
				
			||||||
@@ -60,7 +71,11 @@
 | 
				
			|||||||
    MULT_2SPIN_DIR_PFYP(Yp,basep);
 | 
					    MULT_2SPIN_DIR_PFYP(Yp,basep);
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
  LOAD64(%r10,isigns);  // times i => shuffle and xor the real part sign bit
 | 
					  LOAD64(%r10,isigns);  // times i => shuffle and xor the real part sign bit
 | 
				
			||||||
 | 
					#ifdef KERNEL_DAG
 | 
				
			||||||
 | 
					  YP_RECON_ACCUM;
 | 
				
			||||||
 | 
					#else
 | 
				
			||||||
  YM_RECON_ACCUM;
 | 
					  YM_RECON_ACCUM;
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  ////////////////////////////////
 | 
					  ////////////////////////////////
 | 
				
			||||||
  // Zp
 | 
					  // Zp
 | 
				
			||||||
@@ -68,7 +83,11 @@
 | 
				
			|||||||
  basep = st.GetPFInfo(nent,plocal); nent++;
 | 
					  basep = st.GetPFInfo(nent,plocal); nent++;
 | 
				
			||||||
  if ( local ) {
 | 
					  if ( local ) {
 | 
				
			||||||
    LOAD64(%r10,isigns);  // times i => shuffle and xor the real part sign bit
 | 
					    LOAD64(%r10,isigns);  // times i => shuffle and xor the real part sign bit
 | 
				
			||||||
 | 
					#ifdef KERNEL_DAG
 | 
				
			||||||
 | 
					    ZP_PROJMEM(base);
 | 
				
			||||||
 | 
					#else
 | 
				
			||||||
    ZM_PROJMEM(base);
 | 
					    ZM_PROJMEM(base);
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
    MAYBEPERM(PERMUTE_DIR1,perm);
 | 
					    MAYBEPERM(PERMUTE_DIR1,perm);
 | 
				
			||||||
  } else { 
 | 
					  } else { 
 | 
				
			||||||
    LOAD_CHI(base);
 | 
					    LOAD_CHI(base);
 | 
				
			||||||
@@ -79,7 +98,11 @@
 | 
				
			|||||||
    MULT_2SPIN_DIR_PFZP(Zp,basep);
 | 
					    MULT_2SPIN_DIR_PFZP(Zp,basep);
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
  LOAD64(%r10,isigns);  // times i => shuffle and xor the real part sign bit
 | 
					  LOAD64(%r10,isigns);  // times i => shuffle and xor the real part sign bit
 | 
				
			||||||
 | 
					#ifdef KERNEL_DAG
 | 
				
			||||||
 | 
					  ZP_RECON_ACCUM;
 | 
				
			||||||
 | 
					#else
 | 
				
			||||||
  ZM_RECON_ACCUM;
 | 
					  ZM_RECON_ACCUM;
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  ////////////////////////////////
 | 
					  ////////////////////////////////
 | 
				
			||||||
  // Tp
 | 
					  // Tp
 | 
				
			||||||
@@ -87,7 +110,11 @@
 | 
				
			|||||||
  basep = st.GetPFInfo(nent,plocal); nent++;
 | 
					  basep = st.GetPFInfo(nent,plocal); nent++;
 | 
				
			||||||
  if ( local ) {
 | 
					  if ( local ) {
 | 
				
			||||||
    LOAD64(%r10,isigns);  // times i => shuffle and xor the real part sign bit
 | 
					    LOAD64(%r10,isigns);  // times i => shuffle and xor the real part sign bit
 | 
				
			||||||
 | 
					#ifdef KERNEL_DAG
 | 
				
			||||||
 | 
					    TP_PROJMEM(base);
 | 
				
			||||||
 | 
					#else
 | 
				
			||||||
    TM_PROJMEM(base);
 | 
					    TM_PROJMEM(base);
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
    MAYBEPERM(PERMUTE_DIR0,perm);
 | 
					    MAYBEPERM(PERMUTE_DIR0,perm);
 | 
				
			||||||
  } else { 
 | 
					  } else { 
 | 
				
			||||||
    LOAD_CHI(base);
 | 
					    LOAD_CHI(base);
 | 
				
			||||||
@@ -98,7 +125,11 @@
 | 
				
			|||||||
    MULT_2SPIN_DIR_PFTP(Tp,basep);
 | 
					    MULT_2SPIN_DIR_PFTP(Tp,basep);
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
  LOAD64(%r10,isigns);  // times i => shuffle and xor the real part sign bit
 | 
					  LOAD64(%r10,isigns);  // times i => shuffle and xor the real part sign bit
 | 
				
			||||||
 | 
					#ifdef KERNEL_DAG
 | 
				
			||||||
 | 
					  TP_RECON_ACCUM;
 | 
				
			||||||
 | 
					#else
 | 
				
			||||||
  TM_RECON_ACCUM;
 | 
					  TM_RECON_ACCUM;
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  ////////////////////////////////
 | 
					  ////////////////////////////////
 | 
				
			||||||
  // Xm
 | 
					  // Xm
 | 
				
			||||||
@@ -107,7 +138,11 @@
 | 
				
			|||||||
  //  basep= st.GetPFInfo(nent,plocal); nent++;
 | 
					  //  basep= st.GetPFInfo(nent,plocal); nent++;
 | 
				
			||||||
  if ( local ) {
 | 
					  if ( local ) {
 | 
				
			||||||
    LOAD64(%r10,isigns);  // times i => shuffle and xor the real part sign bit
 | 
					    LOAD64(%r10,isigns);  // times i => shuffle and xor the real part sign bit
 | 
				
			||||||
 | 
					#ifdef KERNEL_DAG
 | 
				
			||||||
 | 
					    XM_PROJMEM(base);
 | 
				
			||||||
 | 
					#else
 | 
				
			||||||
    XP_PROJMEM(base);
 | 
					    XP_PROJMEM(base);
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
    MAYBEPERM(PERMUTE_DIR3,perm);
 | 
					    MAYBEPERM(PERMUTE_DIR3,perm);
 | 
				
			||||||
  } else { 
 | 
					  } else { 
 | 
				
			||||||
    LOAD_CHI(base);
 | 
					    LOAD_CHI(base);
 | 
				
			||||||
@@ -118,7 +153,11 @@
 | 
				
			|||||||
    MULT_2SPIN_DIR_PFXM(Xm,basep);
 | 
					    MULT_2SPIN_DIR_PFXM(Xm,basep);
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
  LOAD64(%r10,isigns);  // times i => shuffle and xor the real part sign bit
 | 
					  LOAD64(%r10,isigns);  // times i => shuffle and xor the real part sign bit
 | 
				
			||||||
 | 
					#ifdef KERNEL_DAG
 | 
				
			||||||
 | 
					  XM_RECON_ACCUM;
 | 
				
			||||||
 | 
					#else
 | 
				
			||||||
  XP_RECON_ACCUM;
 | 
					  XP_RECON_ACCUM;
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  ////////////////////////////////
 | 
					  ////////////////////////////////
 | 
				
			||||||
  // Ym
 | 
					  // Ym
 | 
				
			||||||
@@ -126,7 +165,11 @@
 | 
				
			|||||||
  basep= st.GetPFInfo(nent,plocal); nent++;
 | 
					  basep= st.GetPFInfo(nent,plocal); nent++;
 | 
				
			||||||
  if ( local ) {
 | 
					  if ( local ) {
 | 
				
			||||||
    LOAD64(%r10,isigns);  // times i => shuffle and xor the real part sign bit
 | 
					    LOAD64(%r10,isigns);  // times i => shuffle and xor the real part sign bit
 | 
				
			||||||
 | 
					#ifdef KERNEL_DAG
 | 
				
			||||||
 | 
					    YM_PROJMEM(base);
 | 
				
			||||||
 | 
					#else
 | 
				
			||||||
    YP_PROJMEM(base);
 | 
					    YP_PROJMEM(base);
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
    MAYBEPERM(PERMUTE_DIR2,perm);
 | 
					    MAYBEPERM(PERMUTE_DIR2,perm);
 | 
				
			||||||
  } else { 
 | 
					  } else { 
 | 
				
			||||||
    LOAD_CHI(base);
 | 
					    LOAD_CHI(base);
 | 
				
			||||||
@@ -137,7 +180,11 @@
 | 
				
			|||||||
    MULT_2SPIN_DIR_PFYM(Ym,basep);
 | 
					    MULT_2SPIN_DIR_PFYM(Ym,basep);
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
  LOAD64(%r10,isigns);  // times i => shuffle and xor the real part sign bit
 | 
					  LOAD64(%r10,isigns);  // times i => shuffle and xor the real part sign bit
 | 
				
			||||||
 | 
					#ifdef KERNEL_DAG
 | 
				
			||||||
 | 
					  YM_RECON_ACCUM;
 | 
				
			||||||
 | 
					#else
 | 
				
			||||||
  YP_RECON_ACCUM;
 | 
					  YP_RECON_ACCUM;
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  ////////////////////////////////
 | 
					  ////////////////////////////////
 | 
				
			||||||
  // Zm
 | 
					  // Zm
 | 
				
			||||||
@@ -145,7 +192,11 @@
 | 
				
			|||||||
  basep= st.GetPFInfo(nent,plocal); nent++;
 | 
					  basep= st.GetPFInfo(nent,plocal); nent++;
 | 
				
			||||||
  if ( local ) {
 | 
					  if ( local ) {
 | 
				
			||||||
    LOAD64(%r10,isigns);  // times i => shuffle and xor the real part sign bit
 | 
					    LOAD64(%r10,isigns);  // times i => shuffle and xor the real part sign bit
 | 
				
			||||||
 | 
					#ifdef KERNEL_DAG
 | 
				
			||||||
 | 
					    ZM_PROJMEM(base);
 | 
				
			||||||
 | 
					#else
 | 
				
			||||||
    ZP_PROJMEM(base);
 | 
					    ZP_PROJMEM(base);
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
    MAYBEPERM(PERMUTE_DIR1,perm);
 | 
					    MAYBEPERM(PERMUTE_DIR1,perm);
 | 
				
			||||||
  } else { 
 | 
					  } else { 
 | 
				
			||||||
    LOAD_CHI(base);
 | 
					    LOAD_CHI(base);
 | 
				
			||||||
@@ -156,7 +207,11 @@
 | 
				
			|||||||
    MULT_2SPIN_DIR_PFZM(Zm,basep);
 | 
					    MULT_2SPIN_DIR_PFZM(Zm,basep);
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
  LOAD64(%r10,isigns);  // times i => shuffle and xor the real part sign bit
 | 
					  LOAD64(%r10,isigns);  // times i => shuffle and xor the real part sign bit
 | 
				
			||||||
 | 
					#ifdef KERNEL_DAG
 | 
				
			||||||
 | 
					  ZM_RECON_ACCUM;
 | 
				
			||||||
 | 
					#else
 | 
				
			||||||
  ZP_RECON_ACCUM;
 | 
					  ZP_RECON_ACCUM;
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  ////////////////////////////////
 | 
					  ////////////////////////////////
 | 
				
			||||||
  // Tm
 | 
					  // Tm
 | 
				
			||||||
@@ -164,7 +219,11 @@
 | 
				
			|||||||
  basep= st.GetPFInfo(nent,plocal); nent++;
 | 
					  basep= st.GetPFInfo(nent,plocal); nent++;
 | 
				
			||||||
  if ( local ) {
 | 
					  if ( local ) {
 | 
				
			||||||
    LOAD64(%r10,isigns);  // times i => shuffle and xor the real part sign bit
 | 
					    LOAD64(%r10,isigns);  // times i => shuffle and xor the real part sign bit
 | 
				
			||||||
 | 
					#ifdef KERNEL_DAG
 | 
				
			||||||
 | 
					    TM_PROJMEM(base);
 | 
				
			||||||
 | 
					#else
 | 
				
			||||||
    TP_PROJMEM(base);
 | 
					    TP_PROJMEM(base);
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
    MAYBEPERM(PERMUTE_DIR0,perm);
 | 
					    MAYBEPERM(PERMUTE_DIR0,perm);
 | 
				
			||||||
  } else { 
 | 
					  } else { 
 | 
				
			||||||
    LOAD_CHI(base);
 | 
					    LOAD_CHI(base);
 | 
				
			||||||
@@ -175,7 +234,11 @@
 | 
				
			|||||||
    MULT_2SPIN_DIR_PFTM(Tm,basep);
 | 
					    MULT_2SPIN_DIR_PFTM(Tm,basep);
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
  LOAD64(%r10,isigns);  // times i => shuffle and xor the real part sign bit
 | 
					  LOAD64(%r10,isigns);  // times i => shuffle and xor the real part sign bit
 | 
				
			||||||
 | 
					#ifdef KERNEL_DAG
 | 
				
			||||||
 | 
					  TM_RECON_ACCUM;
 | 
				
			||||||
 | 
					#else
 | 
				
			||||||
  TP_RECON_ACCUM;
 | 
					  TP_RECON_ACCUM;
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  basep= st.GetPFInfo(nent,plocal); nent++;
 | 
					  basep= st.GetPFInfo(nent,plocal); nent++;
 | 
				
			||||||
  SAVE_RESULT(base,basep);
 | 
					  SAVE_RESULT(base,basep);
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -311,8 +311,8 @@ namespace Grid {
 | 
				
			|||||||
namespace QCD {
 | 
					namespace QCD {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
template<class Impl>
 | 
					  template<class Impl>
 | 
				
			||||||
void WilsonKernels<Impl >::DiracOptHandDhopSite(StencilImpl &st,LebesgueOrder &lo,DoubledGaugeField &U,
 | 
					  void WilsonKernels<Impl>::DiracOptHandDhopSite(StencilImpl &st,LebesgueOrder &lo,DoubledGaugeField &U,
 | 
				
			||||||
					       std::vector<SiteHalfSpinor,alignedAllocator<SiteHalfSpinor> >  &buf,
 | 
										       std::vector<SiteHalfSpinor,alignedAllocator<SiteHalfSpinor> >  &buf,
 | 
				
			||||||
					       int ss,int sU,const FermionField &in, FermionField &out)
 | 
										       int ss,int sU,const FermionField &in, FermionField &out)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
@@ -554,8 +554,8 @@ void WilsonKernels<Impl >::DiracOptHandDhopSite(StencilImpl &st,LebesgueOrder &l
 | 
				
			|||||||
  }
 | 
					  }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
template<class Impl>
 | 
					  template<class Impl>
 | 
				
			||||||
void WilsonKernels<Impl >::DiracOptHandDhopSiteDag(StencilImpl &st,LebesgueOrder &lo,DoubledGaugeField &U,
 | 
					  void WilsonKernels<Impl>::DiracOptHandDhopSiteDag(StencilImpl &st,LebesgueOrder &lo,DoubledGaugeField &U,
 | 
				
			||||||
					       std::vector<SiteHalfSpinor,alignedAllocator<SiteHalfSpinor> >  &buf,
 | 
										       std::vector<SiteHalfSpinor,alignedAllocator<SiteHalfSpinor> >  &buf,
 | 
				
			||||||
					       int ss,int sU,const FermionField &in, FermionField &out)
 | 
										       int ss,int sU,const FermionField &in, FermionField &out)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
@@ -839,46 +839,23 @@ void WilsonKernels<GparityWilsonImplD>::DiracOptHandDhopSiteDag(StencilImpl &st,
 | 
				
			|||||||
////////////// Wilson ; uses this implementation /////////////////////
 | 
					////////////// Wilson ; uses this implementation /////////////////////
 | 
				
			||||||
// Need Nc=3 though //
 | 
					// Need Nc=3 though //
 | 
				
			||||||
 | 
					
 | 
				
			||||||
template void WilsonKernels<WilsonImplF>::DiracOptHandDhopSite(StencilImpl &st,LebesgueOrder &lo,DoubledGaugeField &U,
 | 
					#define INSTANTIATE_THEM(A) \
 | 
				
			||||||
							       std::vector<SiteHalfSpinor,alignedAllocator<SiteHalfSpinor> >  &buf,
 | 
					template void WilsonKernels<A>::DiracOptHandDhopSite(StencilImpl &st,LebesgueOrder &lo,DoubledGaugeField &U,\
 | 
				
			||||||
							       int ss,int sU,const FermionField &in, FermionField &out);
 | 
												       std::vector<SiteHalfSpinor,alignedAllocator<SiteHalfSpinor> >  &buf,\
 | 
				
			||||||
template void WilsonKernels<WilsonImplD>::DiracOptHandDhopSite(StencilImpl &st,LebesgueOrder &lo,DoubledGaugeField &U,
 | 
												       int ss,int sU,const FermionField &in, FermionField &out);\
 | 
				
			||||||
							       std::vector<SiteHalfSpinor,alignedAllocator<SiteHalfSpinor> >  &buf,
 | 
					template void WilsonKernels<A>::DiracOptHandDhopSiteDag(StencilImpl &st,LebesgueOrder &lo,DoubledGaugeField &U,\
 | 
				
			||||||
							       int ss,int sU,const FermionField &in, FermionField &out);
 | 
													  std::vector<SiteHalfSpinor,alignedAllocator<SiteHalfSpinor> >  &buf,\
 | 
				
			||||||
template void WilsonKernels<WilsonImplF>::DiracOptHandDhopSiteDag(StencilImpl &st,LebesgueOrder &lo,DoubledGaugeField &U,
 | 
					 | 
				
			||||||
								  std::vector<SiteHalfSpinor,alignedAllocator<SiteHalfSpinor> >  &buf,
 | 
					 | 
				
			||||||
								  int ss,int sU,const FermionField &in, FermionField &out);
 | 
					 | 
				
			||||||
template void WilsonKernels<WilsonImplD>::DiracOptHandDhopSiteDag(StencilImpl &st,LebesgueOrder &lo,DoubledGaugeField &U,
 | 
					 | 
				
			||||||
								  std::vector<SiteHalfSpinor,alignedAllocator<SiteHalfSpinor> >  &buf,
 | 
					 | 
				
			||||||
								  int ss,int sU,const FermionField &in, FermionField &out);
 | 
													  int ss,int sU,const FermionField &in, FermionField &out);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					INSTANTIATE_THEM(WilsonImplF);
 | 
				
			||||||
template void WilsonKernels<GparityWilsonImplF>::DiracOptHandDhopSite(StencilImpl &st,LebesgueOrder &lo,DoubledGaugeField &U,
 | 
					INSTANTIATE_THEM(WilsonImplD);
 | 
				
			||||||
								      std::vector<SiteHalfSpinor,alignedAllocator<SiteHalfSpinor> >  &buf,
 | 
					INSTANTIATE_THEM(ZWilsonImplF);
 | 
				
			||||||
								      int ss,int sU,const FermionField &in, FermionField &out);
 | 
					INSTANTIATE_THEM(ZWilsonImplD);
 | 
				
			||||||
template void WilsonKernels<GparityWilsonImplD>::DiracOptHandDhopSite(StencilImpl &st,LebesgueOrder &lo,DoubledGaugeField &U,
 | 
					INSTANTIATE_THEM(GparityWilsonImplF);
 | 
				
			||||||
								      std::vector<SiteHalfSpinor,alignedAllocator<SiteHalfSpinor> >  &buf,
 | 
					INSTANTIATE_THEM(GparityWilsonImplD);
 | 
				
			||||||
								      int ss,int sU,const FermionField &in, FermionField &out);
 | 
					INSTANTIATE_THEM(DomainWallVec5dImplF);
 | 
				
			||||||
template void WilsonKernels<GparityWilsonImplF>::DiracOptHandDhopSiteDag(StencilImpl &st,LebesgueOrder &lo,DoubledGaugeField &U,
 | 
					INSTANTIATE_THEM(DomainWallVec5dImplD);
 | 
				
			||||||
									 std::vector<SiteHalfSpinor,alignedAllocator<SiteHalfSpinor> >  &buf,
 | 
					INSTANTIATE_THEM(ZDomainWallVec5dImplF);
 | 
				
			||||||
									 int ss,int sU,const FermionField &in, FermionField &out);
 | 
					INSTANTIATE_THEM(ZDomainWallVec5dImplD);
 | 
				
			||||||
template void WilsonKernels<GparityWilsonImplD>::DiracOptHandDhopSiteDag(StencilImpl &st,LebesgueOrder &lo,DoubledGaugeField &U,
 | 
					 | 
				
			||||||
									 std::vector<SiteHalfSpinor,alignedAllocator<SiteHalfSpinor> >  &buf,
 | 
					 | 
				
			||||||
									 int ss,int sU,const FermionField &in, FermionField &out);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
template void WilsonKernels<DomainWallVec5dImplF>::DiracOptHandDhopSite(StencilImpl &st,LebesgueOrder &lo,DoubledGaugeField &U,
 | 
					 | 
				
			||||||
								      std::vector<SiteHalfSpinor,alignedAllocator<SiteHalfSpinor> >  &buf,
 | 
					 | 
				
			||||||
								      int ss,int sU,const FermionField &in, FermionField &out);
 | 
					 | 
				
			||||||
template void WilsonKernels<DomainWallVec5dImplD>::DiracOptHandDhopSite(StencilImpl &st,LebesgueOrder &lo,DoubledGaugeField &U,
 | 
					 | 
				
			||||||
								      std::vector<SiteHalfSpinor,alignedAllocator<SiteHalfSpinor> >  &buf,
 | 
					 | 
				
			||||||
								      int ss,int sU,const FermionField &in, FermionField &out);
 | 
					 | 
				
			||||||
template void WilsonKernels<DomainWallVec5dImplF>::DiracOptHandDhopSiteDag(StencilImpl &st,LebesgueOrder &lo,DoubledGaugeField &U,
 | 
					 | 
				
			||||||
									 std::vector<SiteHalfSpinor,alignedAllocator<SiteHalfSpinor> >  &buf,
 | 
					 | 
				
			||||||
									 int ss,int sU,const FermionField &in, FermionField &out);
 | 
					 | 
				
			||||||
template void WilsonKernels<DomainWallVec5dImplD>::DiracOptHandDhopSiteDag(StencilImpl &st,LebesgueOrder &lo,DoubledGaugeField &U,
 | 
					 | 
				
			||||||
									 std::vector<SiteHalfSpinor,alignedAllocator<SiteHalfSpinor> >  &buf,
 | 
					 | 
				
			||||||
									 int ss,int sU,const FermionField &in, FermionField &out);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
}}
 | 
					}}
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										79
									
								
								lib/qcd/action/fermion/ZMobiusFermion.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										79
									
								
								lib/qcd/action/fermion/ZMobiusFermion.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,79 @@
 | 
				
			|||||||
 | 
					    /*************************************************************************************
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    Grid physics library, www.github.com/paboyle/Grid 
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    Source file: ./lib/qcd/action/fermion/MobiusFermion.h
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    Copyright (C) 2015
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Author: Peter Boyle <pabobyle@ph.ed.ac.uk>
 | 
				
			||||||
 | 
					Author: Peter Boyle <paboyle@ph.ed.ac.uk>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    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
 | 
				
			||||||
 | 
					    the Free Software Foundation; either version 2 of the License, or
 | 
				
			||||||
 | 
					    (at your option) any later version.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    This program is distributed in the hope that it will be useful,
 | 
				
			||||||
 | 
					    but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
				
			||||||
 | 
					    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
				
			||||||
 | 
					    GNU General Public License for more details.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    You should have received a copy of the GNU General Public License along
 | 
				
			||||||
 | 
					    with this program; if not, write to the Free Software Foundation, Inc.,
 | 
				
			||||||
 | 
					    51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    See the full license in the file "LICENSE" in the top level distribution directory
 | 
				
			||||||
 | 
					    *************************************************************************************/
 | 
				
			||||||
 | 
					    /*  END LEGAL */
 | 
				
			||||||
 | 
					#ifndef  GRID_QCD_ZMOBIUS_FERMION_H
 | 
				
			||||||
 | 
					#define  GRID_QCD_ZMOBIUS_FERMION_H
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <Grid/Grid.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace Grid {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  namespace QCD {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    template<class Impl>
 | 
				
			||||||
 | 
					    class ZMobiusFermion : public CayleyFermion5D<Impl>
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					    public:
 | 
				
			||||||
 | 
					     INHERIT_IMPL_TYPES(Impl);
 | 
				
			||||||
 | 
					    public:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      virtual void   Instantiatable(void) {};
 | 
				
			||||||
 | 
					      // Constructors
 | 
				
			||||||
 | 
					      ZMobiusFermion(GaugeField &_Umu,
 | 
				
			||||||
 | 
							     GridCartesian         &FiveDimGrid,
 | 
				
			||||||
 | 
							     GridRedBlackCartesian &FiveDimRedBlackGrid,
 | 
				
			||||||
 | 
							     GridCartesian         &FourDimGrid,
 | 
				
			||||||
 | 
							     GridRedBlackCartesian &FourDimRedBlackGrid,
 | 
				
			||||||
 | 
							     RealD _mass,RealD _M5,
 | 
				
			||||||
 | 
							     std::vector<ComplexD> &gamma, RealD b,RealD c,const ImplParams &p= ImplParams()) : 
 | 
				
			||||||
 | 
					      
 | 
				
			||||||
 | 
					      CayleyFermion5D<Impl>(_Umu,
 | 
				
			||||||
 | 
								    FiveDimGrid,
 | 
				
			||||||
 | 
								    FiveDimRedBlackGrid,
 | 
				
			||||||
 | 
								    FourDimGrid,
 | 
				
			||||||
 | 
								    FourDimRedBlackGrid,_mass,_M5,p)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      {
 | 
				
			||||||
 | 
						RealD eps = 1.0;
 | 
				
			||||||
 | 
						
 | 
				
			||||||
 | 
						std::cout<<GridLogMessage << "ZMobiusFermion (b="<<b<<",c="<<c<<") with Ls= "<<this->Ls<<" gamma passed in"<<std::endl;
 | 
				
			||||||
 | 
						std::vector<Coeff_t> zgamma(this->Ls);
 | 
				
			||||||
 | 
						for(int s=0;s<this->Ls;s++){
 | 
				
			||||||
 | 
						  zgamma[s] = gamma[s];
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// Call base setter
 | 
				
			||||||
 | 
						this->SetCoefficientsInternal(1.0,zgamma,b,c);
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
@@ -30,7 +30,6 @@ directory
 | 
				
			|||||||
#define GRID_QCD_GAUGE_IMPL_H
 | 
					#define GRID_QCD_GAUGE_IMPL_H
 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace Grid {
 | 
					namespace Grid {
 | 
				
			||||||
 | 
					 | 
				
			||||||
namespace QCD {
 | 
					namespace QCD {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
////////////////////////////////////////////////////////////////////////
 | 
					////////////////////////////////////////////////////////////////////////
 | 
				
			||||||
@@ -52,7 +51,7 @@ public:
 | 
				
			|||||||
  typedef S Simd;
 | 
					  typedef S Simd;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  template <typename vtype>
 | 
					  template <typename vtype>
 | 
				
			||||||
  using iImplGaugeLink = iScalar<iScalar<iMatrix<vtype, Nrepresentation>>>;
 | 
					  using iImplGaugeLink  = iScalar<iScalar<iMatrix<vtype, Nrepresentation>>>;
 | 
				
			||||||
  template <typename vtype>
 | 
					  template <typename vtype>
 | 
				
			||||||
  using iImplGaugeField = iVector<iScalar<iMatrix<vtype, Nrepresentation>>, Nd>;
 | 
					  using iImplGaugeField = iVector<iScalar<iMatrix<vtype, Nrepresentation>>, Nd>;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -64,7 +63,7 @@ public:
 | 
				
			|||||||
                                                 // ugly
 | 
					                                                 // ugly
 | 
				
			||||||
  typedef Lattice<SiteGaugeField> GaugeField;
 | 
					  typedef Lattice<SiteGaugeField> GaugeField;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  // Move this elsewhere?
 | 
					  // Move this elsewhere? FIXME
 | 
				
			||||||
  static inline void AddGaugeLink(GaugeField &U, GaugeLinkField &W,
 | 
					  static inline void AddGaugeLink(GaugeField &U, GaugeLinkField &W,
 | 
				
			||||||
                                  int mu) { // U[mu] += W
 | 
					                                  int mu) { // U[mu] += W
 | 
				
			||||||
    PARALLEL_FOR_LOOP
 | 
					    PARALLEL_FOR_LOOP
 | 
				
			||||||
@@ -174,12 +173,19 @@ typedef GaugeImplTypes<vComplex, Nc> GimplTypesR;
 | 
				
			|||||||
typedef GaugeImplTypes<vComplexF, Nc> GimplTypesF;
 | 
					typedef GaugeImplTypes<vComplexF, Nc> GimplTypesF;
 | 
				
			||||||
typedef GaugeImplTypes<vComplexD, Nc> GimplTypesD;
 | 
					typedef GaugeImplTypes<vComplexD, Nc> GimplTypesD;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					typedef GaugeImplTypes<vComplex, SU<Nc>::AdjointDimension> GimplAdjointTypesR;
 | 
				
			||||||
 | 
					typedef GaugeImplTypes<vComplexF, SU<Nc>::AdjointDimension> GimplAdjointTypesF;
 | 
				
			||||||
 | 
					typedef GaugeImplTypes<vComplexD, SU<Nc>::AdjointDimension> GimplAdjointTypesD;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
typedef PeriodicGaugeImpl<GimplTypesR> PeriodicGimplR; // Real.. whichever prec
 | 
					typedef PeriodicGaugeImpl<GimplTypesR> PeriodicGimplR; // Real.. whichever prec
 | 
				
			||||||
typedef PeriodicGaugeImpl<GimplTypesF> PeriodicGimplF; // Float
 | 
					typedef PeriodicGaugeImpl<GimplTypesF> PeriodicGimplF; // Float
 | 
				
			||||||
typedef PeriodicGaugeImpl<GimplTypesD> PeriodicGimplD; // Double
 | 
					typedef PeriodicGaugeImpl<GimplTypesD> PeriodicGimplD; // Double
 | 
				
			||||||
 | 
					
 | 
				
			||||||
typedef ConjugateGaugeImpl<GimplTypesR>
 | 
					typedef PeriodicGaugeImpl<GimplAdjointTypesR> PeriodicGimplAdjR; // Real.. whichever prec
 | 
				
			||||||
    ConjugateGimplR; // Real.. whichever prec
 | 
					typedef PeriodicGaugeImpl<GimplAdjointTypesF> PeriodicGimplAdjF; // Float
 | 
				
			||||||
 | 
					typedef PeriodicGaugeImpl<GimplAdjointTypesD> PeriodicGimplAdjD; // Double
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					typedef ConjugateGaugeImpl<GimplTypesR> ConjugateGimplR; // Real.. whichever prec
 | 
				
			||||||
typedef ConjugateGaugeImpl<GimplTypesF> ConjugateGimplF; // Float
 | 
					typedef ConjugateGaugeImpl<GimplTypesF> ConjugateGimplF; // Float
 | 
				
			||||||
typedef ConjugateGaugeImpl<GimplTypesD> ConjugateGimplD; // Double
 | 
					typedef ConjugateGaugeImpl<GimplTypesD> ConjugateGimplD; // Double
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,149 +1,151 @@
 | 
				
			|||||||
    /*************************************************************************************
 | 
					/*************************************************************************************
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    Grid physics library, www.github.com/paboyle/Grid 
 | 
					Grid physics library, www.github.com/paboyle/Grid
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    Source file: ./lib/qcd/action/pseudofermion/TwoFlavour.h
 | 
					Source file: ./lib/qcd/action/pseudofermion/TwoFlavour.h
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    Copyright (C) 2015
 | 
					Copyright (C) 2015
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Author: Peter Boyle <pabobyle@ph.ed.ac.uk>
 | 
					Author: Peter Boyle <pabobyle@ph.ed.ac.uk>
 | 
				
			||||||
Author: Peter Boyle <paboyle@ph.ed.ac.uk>
 | 
					Author: Peter Boyle <paboyle@ph.ed.ac.uk>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    This program is free software; you can redistribute it and/or modify
 | 
					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
 | 
					it under the terms of the GNU General Public License as published by
 | 
				
			||||||
    the Free Software Foundation; either version 2 of the License, or
 | 
					the Free Software Foundation; either version 2 of the License, or
 | 
				
			||||||
    (at your option) any later version.
 | 
					(at your option) any later version.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    This program is distributed in the hope that it will be useful,
 | 
					This program is distributed in the hope that it will be useful,
 | 
				
			||||||
    but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
					but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
				
			||||||
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
					MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
				
			||||||
    GNU General Public License for more details.
 | 
					GNU General Public License for more details.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    You should have received a copy of the GNU General Public License along
 | 
					You should have received a copy of the GNU General Public License along
 | 
				
			||||||
    with this program; if not, write to the Free Software Foundation, Inc.,
 | 
					with this program; if not, write to the Free Software Foundation, Inc.,
 | 
				
			||||||
    51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 | 
					51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    See the full license in the file "LICENSE" in the top level distribution directory
 | 
					See the full license in the file "LICENSE" in the top level distribution
 | 
				
			||||||
    *************************************************************************************/
 | 
					directory
 | 
				
			||||||
    /*  END LEGAL */
 | 
					*************************************************************************************/
 | 
				
			||||||
 | 
					/*  END LEGAL */
 | 
				
			||||||
#ifndef QCD_PSEUDOFERMION_TWO_FLAVOUR_H
 | 
					#ifndef QCD_PSEUDOFERMION_TWO_FLAVOUR_H
 | 
				
			||||||
#define QCD_PSEUDOFERMION_TWO_FLAVOUR_H
 | 
					#define QCD_PSEUDOFERMION_TWO_FLAVOUR_H
 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace Grid{
 | 
					namespace Grid {
 | 
				
			||||||
  namespace QCD{
 | 
					namespace QCD {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    ////////////////////////////////////////////////////////////////////////
 | 
					////////////////////////////////////////////////////////////////////////
 | 
				
			||||||
    // Two flavour pseudofermion action for any dop
 | 
					// Two flavour pseudofermion action for any dop
 | 
				
			||||||
    ////////////////////////////////////////////////////////////////////////
 | 
					////////////////////////////////////////////////////////////////////////
 | 
				
			||||||
    template<class Impl>
 | 
					template <class Impl>
 | 
				
			||||||
    class TwoFlavourPseudoFermionAction : public Action<typename Impl::GaugeField> {
 | 
					class TwoFlavourPseudoFermionAction : public Action<typename Impl::GaugeField> {
 | 
				
			||||||
    public:
 | 
					 public:
 | 
				
			||||||
      INHERIT_IMPL_TYPES(Impl);
 | 
					  INHERIT_IMPL_TYPES(Impl);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    private:
 | 
					 private:
 | 
				
			||||||
 | 
					  FermionOperator<Impl> &FermOp;  // the basic operator
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      FermionOperator<Impl> & FermOp;// the basic operator
 | 
					  OperatorFunction<FermionField> &DerivativeSolver;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      OperatorFunction<FermionField> &DerivativeSolver;
 | 
					  OperatorFunction<FermionField> &ActionSolver;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      OperatorFunction<FermionField> &ActionSolver;
 | 
					  FermionField Phi;  // the pseudo fermion field for this trajectory
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      FermionField Phi; // the pseudo fermion field for this trajectory
 | 
					 public:
 | 
				
			||||||
 | 
					  /////////////////////////////////////////////////
 | 
				
			||||||
 | 
					  // Pass in required objects.
 | 
				
			||||||
 | 
					  /////////////////////////////////////////////////
 | 
				
			||||||
 | 
					  TwoFlavourPseudoFermionAction(FermionOperator<Impl> &Op,
 | 
				
			||||||
 | 
					                                OperatorFunction<FermionField> &DS,
 | 
				
			||||||
 | 
					                                OperatorFunction<FermionField> &AS)
 | 
				
			||||||
 | 
					      : FermOp(Op),
 | 
				
			||||||
 | 
					        DerivativeSolver(DS),
 | 
				
			||||||
 | 
					        ActionSolver(AS),
 | 
				
			||||||
 | 
					        Phi(Op.FermionGrid()){};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    public:
 | 
					  //////////////////////////////////////////////////////////////////////////////////////
 | 
				
			||||||
      /////////////////////////////////////////////////
 | 
					  // Push the gauge field in to the dops. Assume any BC's and smearing already
 | 
				
			||||||
      // Pass in required objects.
 | 
					  // applied
 | 
				
			||||||
      /////////////////////////////////////////////////
 | 
					  //////////////////////////////////////////////////////////////////////////////////////
 | 
				
			||||||
    TwoFlavourPseudoFermionAction(FermionOperator<Impl>  &Op, 
 | 
					  virtual void refresh(const GaugeField &U, GridParallelRNG &pRNG) {
 | 
				
			||||||
				  OperatorFunction<FermionField> & DS,
 | 
					    // P(phi) = e^{- phi^dag (MdagM)^-1 phi}
 | 
				
			||||||
				  OperatorFunction<FermionField> & AS
 | 
					    // Phi = Mdag eta
 | 
				
			||||||
				  ) : FermOp(Op), DerivativeSolver(DS), ActionSolver(AS), Phi(Op.FermionGrid()) {
 | 
					    // P(eta) = e^{- eta^dag eta}
 | 
				
			||||||
      };
 | 
					    //
 | 
				
			||||||
 | 
					    // e^{x^2/2 sig^2} => sig^2 = 0.5.
 | 
				
			||||||
 | 
					    //
 | 
				
			||||||
 | 
					    // So eta should be of width sig = 1/sqrt(2).
 | 
				
			||||||
 | 
					    // and must multiply by 0.707....
 | 
				
			||||||
 | 
					    //
 | 
				
			||||||
 | 
					    // Chroma has this scale factor: two_flavor_monomial_w.h
 | 
				
			||||||
 | 
					    // IroIro: does not use this scale. It is absorbed by a change of vars
 | 
				
			||||||
 | 
					    //         in the Phi integral, and thus is only an irrelevant prefactor for
 | 
				
			||||||
 | 
					    //         the partition function.
 | 
				
			||||||
 | 
					    //
 | 
				
			||||||
 | 
					    RealD scale = std::sqrt(0.5);
 | 
				
			||||||
 | 
					    FermionField eta(FermOp.FermionGrid());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      //////////////////////////////////////////////////////////////////////////////////////
 | 
					    gaussian(pRNG, eta);
 | 
				
			||||||
      // Push the gauge field in to the dops. Assume any BC's and smearing already applied
 | 
					 | 
				
			||||||
      //////////////////////////////////////////////////////////////////////////////////////
 | 
					 | 
				
			||||||
      virtual void refresh(const GaugeField &U, GridParallelRNG& pRNG) {
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// P(phi) = e^{- phi^dag (MdagM)^-1 phi}
 | 
					    FermOp.ImportGauge(U);
 | 
				
			||||||
	// Phi = Mdag eta 
 | 
					    FermOp.Mdag(eta, Phi);
 | 
				
			||||||
	// P(eta) = e^{- eta^dag eta}
 | 
					 | 
				
			||||||
	//
 | 
					 | 
				
			||||||
	// e^{x^2/2 sig^2} => sig^2 = 0.5.
 | 
					 | 
				
			||||||
	// 
 | 
					 | 
				
			||||||
	// So eta should be of width sig = 1/sqrt(2).
 | 
					 | 
				
			||||||
	// and must multiply by 0.707....
 | 
					 | 
				
			||||||
	//
 | 
					 | 
				
			||||||
	// Chroma has this scale factor: two_flavor_monomial_w.h
 | 
					 | 
				
			||||||
	// IroIro: does not use this scale. It is absorbed by a change of vars
 | 
					 | 
				
			||||||
	//         in the Phi integral, and thus is only an irrelevant prefactor for the partition function.
 | 
					 | 
				
			||||||
	//
 | 
					 | 
				
			||||||
	RealD scale = std::sqrt(0.5);
 | 
					 | 
				
			||||||
	FermionField eta(FermOp.FermionGrid());
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	gaussian(pRNG,eta);
 | 
					    Phi = Phi * scale;
 | 
				
			||||||
 | 
					  };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	FermOp.ImportGauge(U);
 | 
					  //////////////////////////////////////////////////////
 | 
				
			||||||
	FermOp.Mdag(eta,Phi);
 | 
					  // S = phi^dag (Mdag M)^-1 phi
 | 
				
			||||||
 | 
					  //////////////////////////////////////////////////////
 | 
				
			||||||
 | 
					  virtual RealD S(const GaugeField &U) {
 | 
				
			||||||
 | 
					    FermOp.ImportGauge(U);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	Phi=Phi*scale;
 | 
					    FermionField X(FermOp.FermionGrid());
 | 
				
			||||||
 | 
					    FermionField Y(FermOp.FermionGrid());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      };
 | 
					    MdagMLinearOperator<FermionOperator<Impl>, FermionField> MdagMOp(FermOp);
 | 
				
			||||||
 | 
					    X = zero;
 | 
				
			||||||
 | 
					    ActionSolver(MdagMOp, Phi, X);
 | 
				
			||||||
 | 
					    MdagMOp.Op(X, Y);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      //////////////////////////////////////////////////////
 | 
					    RealD action = norm2(Y);
 | 
				
			||||||
      // S = phi^dag (Mdag M)^-1 phi
 | 
					    std::cout << GridLogMessage << "Pseudofermion action " << action
 | 
				
			||||||
      //////////////////////////////////////////////////////
 | 
					              << std::endl;
 | 
				
			||||||
      virtual RealD S(const GaugeField &U) {
 | 
					    return action;
 | 
				
			||||||
 | 
					  };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	FermOp.ImportGauge(U);
 | 
					  //////////////////////////////////////////////////////
 | 
				
			||||||
 | 
					  // dS/du = - phi^dag  (Mdag M)^-1 [ Mdag dM + dMdag M ]  (Mdag M)^-1 phi
 | 
				
			||||||
 | 
					  //       = - phi^dag M^-1 dM (MdagM)^-1 phi -  phi^dag (MdagM)^-1 dMdag dM
 | 
				
			||||||
 | 
					  //       (Mdag)^-1 phi
 | 
				
			||||||
 | 
					  //
 | 
				
			||||||
 | 
					  //       = - Ydag dM X  - Xdag dMdag Y
 | 
				
			||||||
 | 
					  //
 | 
				
			||||||
 | 
					  //////////////////////////////////////////////////////
 | 
				
			||||||
 | 
					  virtual void deriv(const GaugeField &U, GaugeField &dSdU) {
 | 
				
			||||||
 | 
					    FermOp.ImportGauge(U);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	FermionField X(FermOp.FermionGrid());
 | 
					    FermionField X(FermOp.FermionGrid());
 | 
				
			||||||
	FermionField Y(FermOp.FermionGrid());
 | 
					    FermionField Y(FermOp.FermionGrid());
 | 
				
			||||||
 | 
					    GaugeField tmp(FermOp.GaugeGrid());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	MdagMLinearOperator<FermionOperator<Impl> ,FermionField> MdagMOp(FermOp);
 | 
					    MdagMLinearOperator<FermionOperator<Impl>, FermionField> MdagMOp(FermOp);
 | 
				
			||||||
	X=zero;
 | 
					 | 
				
			||||||
	ActionSolver(MdagMOp,Phi,X);
 | 
					 | 
				
			||||||
	MdagMOp.Op(X,Y);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	RealD action = norm2(Y);
 | 
					    X = zero;
 | 
				
			||||||
	std::cout << GridLogMessage << "Pseudofermion action "<<action<<std::endl;
 | 
					    DerivativeSolver(MdagMOp, Phi, X); // X = (MdagM)^-1 phi    
 | 
				
			||||||
	return action;
 | 
					    MdagMOp.Op(X, Y);                  // Y = M X = (Mdag)^-1 phi
 | 
				
			||||||
      };
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
      //////////////////////////////////////////////////////
 | 
					    // Our conventions really make this UdSdU; We do not differentiate wrt Udag
 | 
				
			||||||
      // dS/du = - phi^dag  (Mdag M)^-1 [ Mdag dM + dMdag M ]  (Mdag M)^-1 phi
 | 
					    // here.
 | 
				
			||||||
      //       = - phi^dag M^-1 dM (MdagM)^-1 phi -  phi^dag (MdagM)^-1 dMdag dM (Mdag)^-1 phi 
 | 
					    // So must take dSdU - adj(dSdU) and left multiply by mom to get dS/dt.
 | 
				
			||||||
      //
 | 
					 | 
				
			||||||
      //       = - Ydag dM X  - Xdag dMdag Y
 | 
					 | 
				
			||||||
      //
 | 
					 | 
				
			||||||
      //////////////////////////////////////////////////////
 | 
					 | 
				
			||||||
      virtual void deriv(const GaugeField &U,GaugeField & dSdU) {
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	FermOp.ImportGauge(U);
 | 
					    FermOp.MDeriv(tmp, Y, X, DaggerNo);
 | 
				
			||||||
 | 
					    dSdU = tmp;
 | 
				
			||||||
 | 
					    FermOp.MDeriv(tmp, X, Y, DaggerYes);
 | 
				
			||||||
 | 
					    dSdU = dSdU + tmp;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	FermionField X(FermOp.FermionGrid());
 | 
					    // not taking here the traceless antihermitian component
 | 
				
			||||||
	FermionField Y(FermOp.FermionGrid());
 | 
					  };
 | 
				
			||||||
	GaugeField   tmp(FermOp.GaugeGrid());
 | 
					};
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
	MdagMLinearOperator<FermionOperator<Impl> ,FermionField> MdagMOp(FermOp);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	X=zero;
 | 
					 | 
				
			||||||
	DerivativeSolver(MdagMOp,Phi,X);
 | 
					 | 
				
			||||||
	MdagMOp.Op(X,Y);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	// Our conventions really make this UdSdU; We do not differentiate wrt Udag here.
 | 
					 | 
				
			||||||
	// So must take dSdU - adj(dSdU) and left multiply by mom to get dS/dt.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	FermOp.MDeriv(tmp , Y, X,DaggerNo );  dSdU=tmp;
 | 
					 | 
				
			||||||
	FermOp.MDeriv(tmp , X, Y,DaggerYes);  dSdU=dSdU+tmp;
 | 
					 | 
				
			||||||
	
 | 
					 | 
				
			||||||
	//dSdU = Ta(dSdU);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
      };
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    };
 | 
					 | 
				
			||||||
    
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,70 +1,66 @@
 | 
				
			|||||||
    /*************************************************************************************
 | 
					/*************************************************************************************
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    Grid physics library, www.github.com/paboyle/Grid 
 | 
					Grid physics library, www.github.com/paboyle/Grid
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    Source file: ./lib/qcd/action/pseudofermion/TwoFlavourEvenOdd.h
 | 
					Source file: ./lib/qcd/action/pseudofermion/TwoFlavourEvenOdd.h
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    Copyright (C) 2015
 | 
					Copyright (C) 2015
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Author: Peter Boyle <pabobyle@ph.ed.ac.uk>
 | 
					Author: Peter Boyle <pabobyle@ph.ed.ac.uk>
 | 
				
			||||||
Author: Peter Boyle <paboyle@ph.ed.ac.uk>
 | 
					Author: Peter Boyle <paboyle@ph.ed.ac.uk>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    This program is free software; you can redistribute it and/or modify
 | 
					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
 | 
					it under the terms of the GNU General Public License as published by
 | 
				
			||||||
    the Free Software Foundation; either version 2 of the License, or
 | 
					the Free Software Foundation; either version 2 of the License, or
 | 
				
			||||||
    (at your option) any later version.
 | 
					(at your option) any later version.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    This program is distributed in the hope that it will be useful,
 | 
					This program is distributed in the hope that it will be useful,
 | 
				
			||||||
    but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
					but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
				
			||||||
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
					MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
				
			||||||
    GNU General Public License for more details.
 | 
					GNU General Public License for more details.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    You should have received a copy of the GNU General Public License along
 | 
					You should have received a copy of the GNU General Public License along
 | 
				
			||||||
    with this program; if not, write to the Free Software Foundation, Inc.,
 | 
					with this program; if not, write to the Free Software Foundation, Inc.,
 | 
				
			||||||
    51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 | 
					51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    See the full license in the file "LICENSE" in the top level distribution directory
 | 
					See the full license in the file "LICENSE" in the top level distribution
 | 
				
			||||||
    *************************************************************************************/
 | 
					directory
 | 
				
			||||||
    /*  END LEGAL */
 | 
					*************************************************************************************/
 | 
				
			||||||
 | 
					/*  END LEGAL */
 | 
				
			||||||
#ifndef QCD_PSEUDOFERMION_TWO_FLAVOUR_EVEN_ODD_H
 | 
					#ifndef QCD_PSEUDOFERMION_TWO_FLAVOUR_EVEN_ODD_H
 | 
				
			||||||
#define QCD_PSEUDOFERMION_TWO_FLAVOUR_EVEN_ODD_H
 | 
					#define QCD_PSEUDOFERMION_TWO_FLAVOUR_EVEN_ODD_H
 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace Grid{
 | 
					namespace Grid {
 | 
				
			||||||
  namespace QCD{
 | 
					namespace QCD {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					////////////////////////////////////////////////////////////////////////
 | 
				
			||||||
 | 
					// Two flavour pseudofermion action for any EO prec dop
 | 
				
			||||||
 | 
					////////////////////////////////////////////////////////////////////////
 | 
				
			||||||
 | 
					template <class Impl>
 | 
				
			||||||
 | 
					class TwoFlavourEvenOddPseudoFermionAction
 | 
				
			||||||
 | 
					    : public Action<typename Impl::GaugeField> {
 | 
				
			||||||
 | 
					 public:
 | 
				
			||||||
 | 
					  INHERIT_IMPL_TYPES(Impl);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					 private:
 | 
				
			||||||
 | 
					  FermionOperator<Impl> &FermOp;  // the basic operator
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    ////////////////////////////////////////////////////////////////////////
 | 
					  OperatorFunction<FermionField> &DerivativeSolver;
 | 
				
			||||||
    // Two flavour pseudofermion action for any EO prec dop
 | 
					  OperatorFunction<FermionField> &ActionSolver;
 | 
				
			||||||
    ////////////////////////////////////////////////////////////////////////
 | 
					 | 
				
			||||||
    template<class Impl>
 | 
					 | 
				
			||||||
    class TwoFlavourEvenOddPseudoFermionAction : public Action<typename Impl::GaugeField> {
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    public:
 | 
					  FermionField PhiOdd;   // the pseudo fermion field for this trajectory
 | 
				
			||||||
 | 
					  FermionField PhiEven;  // the pseudo fermion field for this trajectory
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      INHERIT_IMPL_TYPES(Impl);
 | 
					 public:
 | 
				
			||||||
 | 
					  /////////////////////////////////////////////////
 | 
				
			||||||
    private:
 | 
					  // Pass in required objects.
 | 
				
			||||||
      
 | 
					  /////////////////////////////////////////////////
 | 
				
			||||||
      FermionOperator<Impl> & FermOp;// the basic operator
 | 
					  TwoFlavourEvenOddPseudoFermionAction(FermionOperator<Impl> &Op,
 | 
				
			||||||
 | 
					                                       OperatorFunction<FermionField> &DS,
 | 
				
			||||||
      OperatorFunction<FermionField> &DerivativeSolver;
 | 
					                                       OperatorFunction<FermionField> &AS)
 | 
				
			||||||
      OperatorFunction<FermionField> &ActionSolver;
 | 
					      : FermOp(Op),
 | 
				
			||||||
 | 
					        DerivativeSolver(DS),
 | 
				
			||||||
      FermionField PhiOdd;   // the pseudo fermion field for this trajectory
 | 
					        ActionSolver(AS),
 | 
				
			||||||
      FermionField PhiEven;  // the pseudo fermion field for this trajectory
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    public:
 | 
					 | 
				
			||||||
      /////////////////////////////////////////////////
 | 
					 | 
				
			||||||
      // Pass in required objects.
 | 
					 | 
				
			||||||
      /////////////////////////////////////////////////
 | 
					 | 
				
			||||||
      TwoFlavourEvenOddPseudoFermionAction(FermionOperator<Impl>  &Op, 
 | 
					 | 
				
			||||||
					 OperatorFunction<FermionField> & DS,
 | 
					 | 
				
			||||||
					 OperatorFunction<FermionField> & AS
 | 
					 | 
				
			||||||
					   ) : 
 | 
					 | 
				
			||||||
        FermOp(Op), 
 | 
					 | 
				
			||||||
	DerivativeSolver(DS), 
 | 
					 | 
				
			||||||
	ActionSolver(AS), 
 | 
					 | 
				
			||||||
        PhiEven(Op.FermionRedBlackGrid()),
 | 
					        PhiEven(Op.FermionRedBlackGrid()),
 | 
				
			||||||
	PhiOdd(Op.FermionRedBlackGrid())
 | 
						PhiOdd(Op.FermionRedBlackGrid())
 | 
				
			||||||
		  {};
 | 
							  {};
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -131,9 +131,11 @@ namespace Grid{
 | 
				
			|||||||
	Vpc.MpcDag(PhiOdd,Y);           // Y= Vdag phi
 | 
						Vpc.MpcDag(PhiOdd,Y);           // Y= Vdag phi
 | 
				
			||||||
	X=zero;
 | 
						X=zero;
 | 
				
			||||||
	ActionSolver(Mpc,Y,X);          // X= (MdagM)^-1 Vdag phi
 | 
						ActionSolver(Mpc,Y,X);          // X= (MdagM)^-1 Vdag phi
 | 
				
			||||||
	Mpc.Mpc(X,Y);                   // Y=  Mdag^-1 Vdag phi
 | 
						//Mpc.Mpc(X,Y);                   // Y=  Mdag^-1 Vdag phi
 | 
				
			||||||
 | 
						// Multiply by Ydag
 | 
				
			||||||
 | 
						RealD action = real(innerProduct(Y,X));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	RealD action = norm2(Y);
 | 
						//RealD action = norm2(Y);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// The EE factorised block; normally can replace with zero if det is constant (gauge field indept)
 | 
						// The EE factorised block; normally can replace with zero if det is constant (gauge field indept)
 | 
				
			||||||
	// Only really clover term that creates this. Leave the EE portion as a future to do to make most
 | 
						// Only really clover term that creates this. Leave the EE portion as a future to do to make most
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,179 +1,191 @@
 | 
				
			|||||||
    /*************************************************************************************
 | 
					/*************************************************************************************
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    Grid physics library, www.github.com/paboyle/Grid 
 | 
					Grid physics library, www.github.com/paboyle/Grid
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    Source file: ./lib/qcd/hmc/HmcRunner.h
 | 
					Source file: ./lib/qcd/hmc/HmcRunner.h
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    Copyright (C) 2015
 | 
					Copyright (C) 2015
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Author: paboyle <paboyle@ph.ed.ac.uk>
 | 
					Author: paboyle <paboyle@ph.ed.ac.uk>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    This program is free software; you can redistribute it and/or modify
 | 
					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
 | 
					it under the terms of the GNU General Public License as published by
 | 
				
			||||||
    the Free Software Foundation; either version 2 of the License, or
 | 
					the Free Software Foundation; either version 2 of the License, or
 | 
				
			||||||
    (at your option) any later version.
 | 
					(at your option) any later version.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    This program is distributed in the hope that it will be useful,
 | 
					This program is distributed in the hope that it will be useful,
 | 
				
			||||||
    but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
					but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
				
			||||||
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
					MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
				
			||||||
    GNU General Public License for more details.
 | 
					GNU General Public License for more details.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    You should have received a copy of the GNU General Public License along
 | 
					You should have received a copy of the GNU General Public License along
 | 
				
			||||||
    with this program; if not, write to the Free Software Foundation, Inc.,
 | 
					with this program; if not, write to the Free Software Foundation, Inc.,
 | 
				
			||||||
    51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 | 
					51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    See the full license in the file "LICENSE" in the top level distribution directory
 | 
					See the full license in the file "LICENSE" in the top level distribution
 | 
				
			||||||
    *************************************************************************************/
 | 
					directory
 | 
				
			||||||
    /*  END LEGAL */
 | 
					*************************************************************************************/
 | 
				
			||||||
 | 
					/*  END LEGAL */
 | 
				
			||||||
#ifndef HMC_RUNNER
 | 
					#ifndef HMC_RUNNER
 | 
				
			||||||
#define HMC_RUNNER
 | 
					#define HMC_RUNNER
 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace Grid{
 | 
					namespace Grid {
 | 
				
			||||||
  namespace QCD{
 | 
					namespace QCD {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					template <class Gimpl, class RepresentationsPolicy = NoHirep >
 | 
				
			||||||
template<class Gimpl>
 | 
					 | 
				
			||||||
class NerscHmcRunnerTemplate {
 | 
					class NerscHmcRunnerTemplate {
 | 
				
			||||||
public:
 | 
					 public:
 | 
				
			||||||
 | 
					 | 
				
			||||||
  INHERIT_GIMPL_TYPES(Gimpl);
 | 
					  INHERIT_GIMPL_TYPES(Gimpl);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  enum StartType_t { ColdStart, HotStart, TepidStart, CheckpointStart };
 | 
					  enum StartType_t { ColdStart, HotStart, TepidStart, CheckpointStart };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  ActionSet<GaugeField> TheAction;
 | 
					  ActionSet<GaugeField, RepresentationsPolicy> TheAction;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  GridCartesian         * UGrid   ;
 | 
					  GridCartesian *UGrid;
 | 
				
			||||||
  GridCartesian         * FGrid   ;
 | 
					  GridCartesian *FGrid;
 | 
				
			||||||
  GridRedBlackCartesian * UrbGrid ;
 | 
					  GridRedBlackCartesian *UrbGrid;
 | 
				
			||||||
  GridRedBlackCartesian * FrbGrid ;
 | 
					  GridRedBlackCartesian *FrbGrid;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  virtual void BuildTheAction (int argc, char **argv) = 0; // necessary?
 | 
					  virtual void BuildTheAction(int argc, char **argv) = 0;  // necessary?
 | 
				
			||||||
 | 
					 | 
				
			||||||
  
 | 
					 | 
				
			||||||
  void Run (int argc, char  **argv){
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  void Run(int argc, char **argv) {
 | 
				
			||||||
    StartType_t StartType = HotStart;
 | 
					    StartType_t StartType = HotStart;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    std::string arg;
 | 
					    std::string arg;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if( GridCmdOptionExists(argv,argv+argc,"--StartType") ){
 | 
					    if (GridCmdOptionExists(argv, argv + argc, "--StartType")) {
 | 
				
			||||||
      arg = GridCmdOptionPayload(argv,argv+argc,"--StartType");
 | 
					      arg = GridCmdOptionPayload(argv, argv + argc, "--StartType");
 | 
				
			||||||
      if ( arg == "HotStart" ) { StartType = HotStart; }
 | 
					      if (arg == "HotStart") {
 | 
				
			||||||
      else if ( arg == "ColdStart" ) { StartType = ColdStart; }
 | 
					        StartType = HotStart;
 | 
				
			||||||
      else if ( arg == "TepidStart" ) { StartType = TepidStart; }
 | 
					      } else if (arg == "ColdStart") {
 | 
				
			||||||
      else if ( arg == "CheckpointStart" ) { StartType = CheckpointStart; }
 | 
					        StartType = ColdStart;
 | 
				
			||||||
      else assert(0);
 | 
					      } else if (arg == "TepidStart") {
 | 
				
			||||||
 | 
					        StartType = TepidStart;
 | 
				
			||||||
 | 
					      } else if (arg == "CheckpointStart") {
 | 
				
			||||||
 | 
					        StartType = CheckpointStart;
 | 
				
			||||||
 | 
					      } else {
 | 
				
			||||||
 | 
					        std::cout << GridLogError << "Unrecognized option in --StartType\n";
 | 
				
			||||||
 | 
					        std::cout << GridLogError << "Valid [HotStart, ColdStart, TepidStart, CheckpointStart]\n";
 | 
				
			||||||
 | 
					        assert(0);
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    int StartTraj = 0;
 | 
					    int StartTraj = 0;
 | 
				
			||||||
    if( GridCmdOptionExists(argv,argv+argc,"--StartTrajectory") ){
 | 
					    if (GridCmdOptionExists(argv, argv + argc, "--StartTrajectory")) {
 | 
				
			||||||
      arg= GridCmdOptionPayload(argv,argv+argc,"--StartTrajectory");
 | 
					      arg = GridCmdOptionPayload(argv, argv + argc, "--StartTrajectory");
 | 
				
			||||||
      std::vector<int> ivec(0);
 | 
					      std::vector<int> ivec(0);
 | 
				
			||||||
      GridCmdOptionIntVector(arg,ivec);
 | 
					      GridCmdOptionIntVector(arg, ivec);
 | 
				
			||||||
      StartTraj = ivec[0];
 | 
					      StartTraj = ivec[0];
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    int NumTraj = 1;
 | 
					    int NumTraj = 1;
 | 
				
			||||||
    if( GridCmdOptionExists(argv,argv+argc,"--Trajectories") ){
 | 
					    if (GridCmdOptionExists(argv, argv + argc, "--Trajectories")) {
 | 
				
			||||||
      arg= GridCmdOptionPayload(argv,argv+argc,"--Trajectories");
 | 
					      arg = GridCmdOptionPayload(argv, argv + argc, "--Trajectories");
 | 
				
			||||||
      std::vector<int> ivec(0);
 | 
					      std::vector<int> ivec(0);
 | 
				
			||||||
      GridCmdOptionIntVector(arg,ivec);
 | 
					      GridCmdOptionIntVector(arg, ivec);
 | 
				
			||||||
      NumTraj = ivec[0];
 | 
					      NumTraj = ivec[0];
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    int NumThermalizations = 10;
 | 
					    int NumThermalizations = 10;
 | 
				
			||||||
    if( GridCmdOptionExists(argv,argv+argc,"--Thermalizations") ){
 | 
					    if (GridCmdOptionExists(argv, argv + argc, "--Thermalizations")) {
 | 
				
			||||||
      arg= GridCmdOptionPayload(argv,argv+argc,"--Thermalizations");
 | 
					      arg = GridCmdOptionPayload(argv, argv + argc, "--Thermalizations");
 | 
				
			||||||
      std::vector<int> ivec(0);
 | 
					      std::vector<int> ivec(0);
 | 
				
			||||||
      GridCmdOptionIntVector(arg,ivec);
 | 
					      GridCmdOptionIntVector(arg, ivec);
 | 
				
			||||||
      NumThermalizations = ivec[0];
 | 
					      NumThermalizations = ivec[0];
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    GridSerialRNG sRNG;
 | 
				
			||||||
 | 
					    GridParallelRNG pRNG(UGrid);
 | 
				
			||||||
 | 
					    LatticeGaugeField U(UGrid);  // change this to an extended field (smearing class)?
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    GridSerialRNG    sRNG;
 | 
					    std::vector<int> SerSeed({1, 2, 3, 4, 5});
 | 
				
			||||||
    GridParallelRNG  pRNG(UGrid);
 | 
					    std::vector<int> ParSeed({6, 7, 8, 9, 10});
 | 
				
			||||||
    LatticeGaugeField  U(UGrid); // change this to an extended field (smearing class)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    std::vector<int> SerSeed({1,2,3,4,5});
 | 
					 | 
				
			||||||
    std::vector<int> ParSeed({6,7,8,9,10});
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // Create integrator, including the smearing policy
 | 
					    // Create integrator, including the smearing policy
 | 
				
			||||||
    // Smearing policy
 | 
					    // Smearing policy, only defined for Nc=3
 | 
				
			||||||
 | 
					    /*
 | 
				
			||||||
    std::cout << GridLogDebug << " Creating the Stout class\n";
 | 
					    std::cout << GridLogDebug << " Creating the Stout class\n";
 | 
				
			||||||
    double rho = 0.1; // smearing parameter, now hardcoded
 | 
					    double rho = 0.1;  // smearing parameter, now hardcoded
 | 
				
			||||||
    int Nsmear = 1;   // number of smearing levels
 | 
					    int Nsmear = 1;    // number of smearing levels
 | 
				
			||||||
    Smear_Stout<Gimpl> Stout(rho);
 | 
					    Smear_Stout<Gimpl> Stout(rho);
 | 
				
			||||||
    std::cout << GridLogDebug << " Creating the SmearedConfiguration class\n";
 | 
					    std::cout << GridLogDebug << " Creating the SmearedConfiguration class\n";
 | 
				
			||||||
    SmearedConfiguration<Gimpl> SmearingPolicy(UGrid, Nsmear, Stout);
 | 
					    //SmearedConfiguration<Gimpl> SmearingPolicy(UGrid, Nsmear, Stout);
 | 
				
			||||||
    std::cout << GridLogDebug << " done\n";
 | 
					    std::cout << GridLogDebug << " done\n";
 | 
				
			||||||
 | 
					    */
 | 
				
			||||||
    //////////////
 | 
					    //////////////
 | 
				
			||||||
    typedef MinimumNorm2<GaugeField, SmearedConfiguration<Gimpl> >  IntegratorType;// change here to change the algorithm
 | 
					    NoSmearing<Gimpl> SmearingPolicy;
 | 
				
			||||||
    IntegratorParameters MDpar(20);
 | 
					    typedef MinimumNorm2<GaugeField, NoSmearing<Gimpl>, RepresentationsPolicy >
 | 
				
			||||||
 | 
					        IntegratorType;  // change here to change the algorithm
 | 
				
			||||||
 | 
					    IntegratorParameters MDpar(20, 1.0);
 | 
				
			||||||
    IntegratorType MDynamics(UGrid, MDpar, TheAction, SmearingPolicy);
 | 
					    IntegratorType MDynamics(UGrid, MDpar, TheAction, SmearingPolicy);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    
 | 
					 | 
				
			||||||
    // Checkpoint strategy
 | 
					    // Checkpoint strategy
 | 
				
			||||||
    NerscHmcCheckpointer<Gimpl> Checkpoint(std::string("ckpoint_lat"),std::string("ckpoint_rng"),1);
 | 
					    NerscHmcCheckpointer<Gimpl> Checkpoint(std::string("ckpoint_lat"),
 | 
				
			||||||
    PlaquetteLogger<Gimpl>      PlaqLog(std::string("plaq"));
 | 
					                                           std::string("ckpoint_rng"), 1);
 | 
				
			||||||
 | 
					    PlaquetteLogger<Gimpl> PlaqLog(std::string("plaq"));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    HMCparameters HMCpar;
 | 
					    HMCparameters HMCpar;
 | 
				
			||||||
    HMCpar.StartTrajectory   = StartTraj;
 | 
					    HMCpar.StartTrajectory = StartTraj;
 | 
				
			||||||
    HMCpar.Trajectories      = NumTraj;
 | 
					    HMCpar.Trajectories = NumTraj;
 | 
				
			||||||
    HMCpar.NoMetropolisUntil = NumThermalizations;
 | 
					    HMCpar.NoMetropolisUntil = NumThermalizations;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (StartType == HotStart) {
 | 
				
			||||||
    if ( StartType == HotStart ) {
 | 
					 | 
				
			||||||
      // Hot start
 | 
					      // Hot start
 | 
				
			||||||
      HMCpar.MetropolisTest = true;
 | 
					      HMCpar.MetropolisTest = true;
 | 
				
			||||||
      sRNG.SeedFixedIntegers(SerSeed);
 | 
					      sRNG.SeedFixedIntegers(SerSeed);
 | 
				
			||||||
      pRNG.SeedFixedIntegers(ParSeed);
 | 
					      pRNG.SeedFixedIntegers(ParSeed);
 | 
				
			||||||
      SU3::HotConfiguration(pRNG, U);
 | 
					      SU<Nc>::HotConfiguration(pRNG, U);
 | 
				
			||||||
    } else if ( StartType == ColdStart ) { 
 | 
					    } else if (StartType == ColdStart) {
 | 
				
			||||||
      // Cold start
 | 
					      // Cold start
 | 
				
			||||||
      HMCpar.MetropolisTest = true;
 | 
					      HMCpar.MetropolisTest = true;
 | 
				
			||||||
      sRNG.SeedFixedIntegers(SerSeed);
 | 
					      sRNG.SeedFixedIntegers(SerSeed);
 | 
				
			||||||
      pRNG.SeedFixedIntegers(ParSeed);
 | 
					      pRNG.SeedFixedIntegers(ParSeed);
 | 
				
			||||||
      SU3::ColdConfiguration(pRNG, U);
 | 
					      SU<Nc>::ColdConfiguration(pRNG, U);
 | 
				
			||||||
    } else if ( StartType == TepidStart ) {       
 | 
					    } else if (StartType == TepidStart) {
 | 
				
			||||||
      // Tepid start
 | 
					      // Tepid start
 | 
				
			||||||
      HMCpar.MetropolisTest = true;
 | 
					      HMCpar.MetropolisTest = true;
 | 
				
			||||||
      sRNG.SeedFixedIntegers(SerSeed);
 | 
					      sRNG.SeedFixedIntegers(SerSeed);
 | 
				
			||||||
      pRNG.SeedFixedIntegers(ParSeed);
 | 
					      pRNG.SeedFixedIntegers(ParSeed);
 | 
				
			||||||
      SU3::TepidConfiguration(pRNG, U);
 | 
					      SU<Nc>::TepidConfiguration(pRNG, U);
 | 
				
			||||||
    } else if ( StartType == CheckpointStart ) { 
 | 
					    } else if (StartType == CheckpointStart) {
 | 
				
			||||||
      HMCpar.MetropolisTest = true;
 | 
					      HMCpar.MetropolisTest = true;
 | 
				
			||||||
      // CheckpointRestart
 | 
					      // CheckpointRestart
 | 
				
			||||||
      Checkpoint.CheckpointRestore(StartTraj, U, sRNG, pRNG);
 | 
					      Checkpoint.CheckpointRestore(StartTraj, U, sRNG, pRNG);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // Attach the gauge field to the smearing Policy and create the fill the smeared set
 | 
					    // Attach the gauge field to the smearing Policy and create the fill the
 | 
				
			||||||
 | 
					    // smeared set
 | 
				
			||||||
    // notice that the unit configuration is singular in this procedure
 | 
					    // notice that the unit configuration is singular in this procedure
 | 
				
			||||||
    std::cout << GridLogMessage << "Filling the smeared set\n";
 | 
					    std::cout << GridLogMessage << "Filling the smeared set\n";
 | 
				
			||||||
    SmearingPolicy.set_GaugeField(U);
 | 
					    SmearingPolicy.set_GaugeField(U);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    HybridMonteCarlo<GaugeField,IntegratorType>  HMC(HMCpar, MDynamics,sRNG,pRNG,U); 
 | 
					    HybridMonteCarlo<GaugeField, IntegratorType> HMC(HMCpar, MDynamics, sRNG,
 | 
				
			||||||
 | 
					                                                     pRNG, U);
 | 
				
			||||||
    HMC.AddObservable(&Checkpoint);
 | 
					    HMC.AddObservable(&Checkpoint);
 | 
				
			||||||
    HMC.AddObservable(&PlaqLog);
 | 
					    HMC.AddObservable(&PlaqLog);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // Run it
 | 
					    // Run it
 | 
				
			||||||
    HMC.evolve();
 | 
					    HMC.evolve();
 | 
				
			||||||
    
 | 
					 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
  
 | 
					 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 typedef NerscHmcRunnerTemplate<PeriodicGimplR> NerscHmcRunner;
 | 
					typedef NerscHmcRunnerTemplate<PeriodicGimplR> NerscHmcRunner;
 | 
				
			||||||
 typedef NerscHmcRunnerTemplate<PeriodicGimplF> NerscHmcRunnerF;
 | 
					typedef NerscHmcRunnerTemplate<PeriodicGimplF> NerscHmcRunnerF;
 | 
				
			||||||
 typedef NerscHmcRunnerTemplate<PeriodicGimplD> NerscHmcRunnerD;
 | 
					typedef NerscHmcRunnerTemplate<PeriodicGimplD> NerscHmcRunnerD;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 typedef NerscHmcRunnerTemplate<PeriodicGimplR> PeriodicNerscHmcRunner;
 | 
					typedef NerscHmcRunnerTemplate<PeriodicGimplR> PeriodicNerscHmcRunner;
 | 
				
			||||||
 typedef NerscHmcRunnerTemplate<PeriodicGimplF> PeriodicNerscHmcRunnerF;
 | 
					typedef NerscHmcRunnerTemplate<PeriodicGimplF> PeriodicNerscHmcRunnerF;
 | 
				
			||||||
 typedef NerscHmcRunnerTemplate<PeriodicGimplD> PeriodicNerscHmcRunnerD;
 | 
					typedef NerscHmcRunnerTemplate<PeriodicGimplD> PeriodicNerscHmcRunnerD;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 typedef NerscHmcRunnerTemplate<ConjugateGimplR> ConjugateNerscHmcRunner;
 | 
					typedef NerscHmcRunnerTemplate<ConjugateGimplR> ConjugateNerscHmcRunner;
 | 
				
			||||||
 typedef NerscHmcRunnerTemplate<ConjugateGimplF> ConjugateNerscHmcRunnerF;
 | 
					typedef NerscHmcRunnerTemplate<ConjugateGimplF> ConjugateNerscHmcRunnerF;
 | 
				
			||||||
 typedef NerscHmcRunnerTemplate<ConjugateGimplD> ConjugateNerscHmcRunnerD;
 | 
					typedef NerscHmcRunnerTemplate<ConjugateGimplD> ConjugateNerscHmcRunnerD;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
}}
 | 
					template <class RepresentationsPolicy>
 | 
				
			||||||
 | 
					using NerscHmcRunnerHirep = NerscHmcRunnerTemplate<PeriodicGimplR, RepresentationsPolicy>;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,33 +1,34 @@
 | 
				
			|||||||
    /*************************************************************************************
 | 
					/*************************************************************************************
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    Grid physics library, www.github.com/paboyle/Grid 
 | 
					Grid physics library, www.github.com/paboyle/Grid
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    Source file: ./lib/qcd/hmc/integrators/Integrator.h
 | 
					Source file: ./lib/qcd/hmc/integrators/Integrator.h
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    Copyright (C) 2015
 | 
					Copyright (C) 2015
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Author: Azusa Yamaguchi <ayamaguc@staffmail.ed.ac.uk>
 | 
					Author: Azusa Yamaguchi <ayamaguc@staffmail.ed.ac.uk>
 | 
				
			||||||
Author: Peter Boyle <paboyle@ph.ed.ac.uk>
 | 
					Author: Peter Boyle <paboyle@ph.ed.ac.uk>
 | 
				
			||||||
Author: neo <cossu@post.kek.jp>
 | 
					Author: neo <cossu@post.kek.jp>
 | 
				
			||||||
Author: paboyle <paboyle@ph.ed.ac.uk>
 | 
					Author: paboyle <paboyle@ph.ed.ac.uk>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    This program is free software; you can redistribute it and/or modify
 | 
					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
 | 
					it under the terms of the GNU General Public License as published by
 | 
				
			||||||
    the Free Software Foundation; either version 2 of the License, or
 | 
					the Free Software Foundation; either version 2 of the License, or
 | 
				
			||||||
    (at your option) any later version.
 | 
					(at your option) any later version.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    This program is distributed in the hope that it will be useful,
 | 
					This program is distributed in the hope that it will be useful,
 | 
				
			||||||
    but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
					but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
				
			||||||
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
					MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
				
			||||||
    GNU General Public License for more details.
 | 
					GNU General Public License for more details.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    You should have received a copy of the GNU General Public License along
 | 
					You should have received a copy of the GNU General Public License along
 | 
				
			||||||
    with this program; if not, write to the Free Software Foundation, Inc.,
 | 
					with this program; if not, write to the Free Software Foundation, Inc.,
 | 
				
			||||||
    51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 | 
					51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    See the full license in the file "LICENSE" in the top level distribution directory
 | 
					See the full license in the file "LICENSE" in the top level distribution
 | 
				
			||||||
    *************************************************************************************/
 | 
					directory
 | 
				
			||||||
    /*  END LEGAL */
 | 
					*************************************************************************************/
 | 
				
			||||||
 | 
					/*  END LEGAL */
 | 
				
			||||||
//--------------------------------------------------------------------
 | 
					//--------------------------------------------------------------------
 | 
				
			||||||
/*! @file Integrator.h
 | 
					/*! @file Integrator.h
 | 
				
			||||||
 * @brief Classes for the Molecular Dynamics integrator
 | 
					 * @brief Classes for the Molecular Dynamics integrator
 | 
				
			||||||
@@ -40,208 +41,278 @@ Author: paboyle <paboyle@ph.ed.ac.uk>
 | 
				
			|||||||
#ifndef INTEGRATOR_INCLUDED
 | 
					#ifndef INTEGRATOR_INCLUDED
 | 
				
			||||||
#define INTEGRATOR_INCLUDED
 | 
					#define INTEGRATOR_INCLUDED
 | 
				
			||||||
 | 
					
 | 
				
			||||||
//class Observer;
 | 
					// class Observer;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include <memory>
 | 
					#include <memory>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 namespace Grid{
 | 
					namespace Grid {
 | 
				
			||||||
 	namespace QCD{
 | 
					namespace QCD {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 		struct IntegratorParameters{
 | 
					struct IntegratorParameters {
 | 
				
			||||||
 | 
					  int Nexp;
 | 
				
			||||||
 | 
					  int MDsteps;  // number of outer steps
 | 
				
			||||||
 | 
					  RealD trajL;  // trajectory length
 | 
				
			||||||
 | 
					  RealD stepsize;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 			int Nexp;
 | 
					  IntegratorParameters(int MDsteps_, RealD trajL_ = 1.0, int Nexp_ = 12)
 | 
				
			||||||
      int MDsteps;  // number of outer steps
 | 
					      : Nexp(Nexp_),
 | 
				
			||||||
      RealD trajL;  // trajectory length 
 | 
					        MDsteps(MDsteps_),
 | 
				
			||||||
      RealD stepsize;
 | 
					        trajL(trajL_),
 | 
				
			||||||
 | 
					        stepsize(trajL / MDsteps){
 | 
				
			||||||
      IntegratorParameters(int MDsteps_, 
 | 
					            // empty body constructor
 | 
				
			||||||
      	RealD trajL_=1.0,
 | 
					        };
 | 
				
			||||||
      	int Nexp_=12):
 | 
					 | 
				
			||||||
      Nexp(Nexp_),
 | 
					 | 
				
			||||||
      MDsteps(MDsteps_),
 | 
					 | 
				
			||||||
      trajL(trajL_),
 | 
					 | 
				
			||||||
      stepsize(trajL/MDsteps)
 | 
					 | 
				
			||||||
      {
 | 
					 | 
				
			||||||
	  // empty body constructor
 | 
					 | 
				
			||||||
      };
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  };
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    /*! @brief Class for Molecular Dynamics management */   
 | 
					 | 
				
			||||||
    template<class GaugeField, class SmearingPolicy>
 | 
					 | 
				
			||||||
  class Integrator {
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  protected:
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  	typedef IntegratorParameters ParameterType;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  	IntegratorParameters Params;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  	const ActionSet<GaugeField> as;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
      int levels;              //
 | 
					 | 
				
			||||||
      double t_U;              // Track time passing on each level and for U and for P
 | 
					 | 
				
			||||||
      std::vector<double> t_P; //
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
      GaugeField P;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
      SmearingPolicy &Smearer;
 | 
					 | 
				
			||||||
      
 | 
					 | 
				
			||||||
      // Should match any legal (SU(n)) gauge field
 | 
					 | 
				
			||||||
      // Need to use this template to match Ncol to pass to SU<N> class
 | 
					 | 
				
			||||||
      template<int Ncol,class vec> void generate_momenta(Lattice< iVector< iScalar< iMatrix<vec,Ncol> >, Nd> > & P,GridParallelRNG& pRNG){
 | 
					 | 
				
			||||||
      typedef Lattice< iScalar< iScalar< iMatrix<vec,Ncol> > > > GaugeLinkField;
 | 
					 | 
				
			||||||
      GaugeLinkField Pmu(P._grid);
 | 
					 | 
				
			||||||
      Pmu = zero;
 | 
					 | 
				
			||||||
      for(int mu=0;mu<Nd;mu++){
 | 
					 | 
				
			||||||
      	SU<Ncol>::GaussianLieAlgebraMatrix(pRNG, Pmu);
 | 
					 | 
				
			||||||
      	PokeIndex<LorentzIndex>(P, Pmu, mu);
 | 
					 | 
				
			||||||
      }
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
      //ObserverList observers; // not yet
 | 
					 | 
				
			||||||
      //      typedef std::vector<Observer*> ObserverList;
 | 
					 | 
				
			||||||
      //      void register_observers();
 | 
					 | 
				
			||||||
      //      void notify_observers();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  void update_P(GaugeField&U, int level, double ep){
 | 
					 | 
				
			||||||
  	t_P[level]+=ep;
 | 
					 | 
				
			||||||
  	update_P(P,U,level,ep);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  	std::cout<<GridLogIntegrator<<"["<<level<<"] P " << " dt "<< ep <<" : t_P "<< t_P[level] <<std::endl;
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  void update_P(GaugeField &Mom,GaugeField&U, int level,double ep){
 | 
					 | 
				
			||||||
  	// input U actually not used... 
 | 
					 | 
				
			||||||
  	for(int a=0; a<as[level].actions.size(); ++a){
 | 
					 | 
				
			||||||
  		GaugeField force(U._grid);
 | 
					 | 
				
			||||||
  		GaugeField& Us = Smearer.get_U(as[level].actions.at(a)->is_smeared);
 | 
					 | 
				
			||||||
  		as[level].actions.at(a)->deriv(Us,force); // deriv should NOT include Ta
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	  	std::cout<< GridLogIntegrator << "Smearing (on/off): "<<as[level].actions.at(a)->is_smeared <<std::endl;
 | 
					 | 
				
			||||||
	  	if (as[level].actions.at(a)->is_smeared) Smearer.smeared_force(force);
 | 
					 | 
				
			||||||
	  	force = Ta(force);
 | 
					 | 
				
			||||||
	  	std::cout<< GridLogIntegrator << "Force average: "<< norm2(force)/(U._grid->gSites()) <<std::endl;
 | 
					 | 
				
			||||||
	  	Mom -= force*ep;
 | 
					 | 
				
			||||||
	  }
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	void update_U(GaugeField&U, double ep){
 | 
					 | 
				
			||||||
		update_U(P,U,ep);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		t_U+=ep;
 | 
					 | 
				
			||||||
		int fl = levels-1;
 | 
					 | 
				
			||||||
		std::cout<< GridLogIntegrator <<"   "<<"["<<fl<<"] U " << " dt "<< ep <<" : t_U "<< t_U <<std::endl;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	void update_U(GaugeField &Mom, GaugeField&U, double ep){
 | 
					 | 
				
			||||||
	//rewrite exponential to deal automatically  with the lorentz index?
 | 
					 | 
				
			||||||
	//	GaugeLinkField Umu(U._grid);
 | 
					 | 
				
			||||||
	//	GaugeLinkField Pmu(U._grid);
 | 
					 | 
				
			||||||
		for (int mu = 0; mu < Nd; mu++){
 | 
					 | 
				
			||||||
			auto Umu=PeekIndex<LorentzIndex>(U, mu);
 | 
					 | 
				
			||||||
			auto Pmu=PeekIndex<LorentzIndex>(Mom, mu);
 | 
					 | 
				
			||||||
			Umu = expMat(Pmu, ep, Params.Nexp)*Umu;
 | 
					 | 
				
			||||||
			ProjectOnGroup(Umu);
 | 
					 | 
				
			||||||
			PokeIndex<LorentzIndex>(U, Umu, mu);
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	// Update the smeared fields, can be implemented as observer
 | 
					 | 
				
			||||||
		Smearer.set_GaugeField(U);
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	virtual void step (GaugeField& U,int level, int first,int last)=0;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
public:
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	Integrator(GridBase* grid, 
 | 
					 | 
				
			||||||
		IntegratorParameters Par,
 | 
					 | 
				
			||||||
		ActionSet<GaugeField> & Aset,
 | 
					 | 
				
			||||||
		SmearingPolicy &Sm):
 | 
					 | 
				
			||||||
	Params(Par),
 | 
					 | 
				
			||||||
	as(Aset),
 | 
					 | 
				
			||||||
	P(grid),
 | 
					 | 
				
			||||||
	levels(Aset.size()),
 | 
					 | 
				
			||||||
	Smearer(Sm)
 | 
					 | 
				
			||||||
	{
 | 
					 | 
				
			||||||
		t_P.resize(levels,0.0);
 | 
					 | 
				
			||||||
		t_U=0.0;
 | 
					 | 
				
			||||||
	// initialization of smearer delegated outside of Integrator
 | 
					 | 
				
			||||||
	};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	virtual ~Integrator(){}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
      //Initialization of momenta and actions
 | 
					 | 
				
			||||||
	void refresh(GaugeField& U,GridParallelRNG &pRNG){
 | 
					 | 
				
			||||||
		std::cout<<GridLogIntegrator<< "Integrator refresh\n";
 | 
					 | 
				
			||||||
		generate_momenta(P,pRNG);
 | 
					 | 
				
			||||||
		for(int level=0; level< as.size(); ++level){
 | 
					 | 
				
			||||||
			for(int actionID=0; actionID<as[level].actions.size(); ++actionID){
 | 
					 | 
				
			||||||
	    // get gauge field from the SmearingPolicy and
 | 
					 | 
				
			||||||
	    // based on the boolean is_smeared in actionID
 | 
					 | 
				
			||||||
				GaugeField& Us = Smearer.get_U(as[level].actions.at(actionID)->is_smeared);
 | 
					 | 
				
			||||||
				as[level].actions.at(actionID)->refresh(Us, pRNG);
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
      // Calculate action
 | 
					 | 
				
			||||||
	RealD S(GaugeField& U){// here also U not used
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		LatticeComplex Hloc(U._grid);	Hloc = zero;
 | 
					 | 
				
			||||||
	// Momenta
 | 
					 | 
				
			||||||
		for (int mu=0; mu <Nd; mu++){
 | 
					 | 
				
			||||||
			auto Pmu = PeekIndex<LorentzIndex>(P, mu);
 | 
					 | 
				
			||||||
			Hloc -= trace(Pmu*Pmu);
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		Complex Hsum = sum(Hloc);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		RealD H = Hsum.real();
 | 
					 | 
				
			||||||
		RealD Hterm;
 | 
					 | 
				
			||||||
		std::cout<<GridLogMessage << "Momentum action H_p = "<< H << "\n";
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	// Actions
 | 
					 | 
				
			||||||
		for(int level=0; level<as.size(); ++level){
 | 
					 | 
				
			||||||
			for(int actionID=0; actionID<as[level].actions.size(); ++actionID){
 | 
					 | 
				
			||||||
	    // get gauge field from the SmearingPolicy and
 | 
					 | 
				
			||||||
	    // based on the boolean is_smeared in actionID
 | 
					 | 
				
			||||||
				GaugeField& Us = Smearer.get_U(as[level].actions.at(actionID)->is_smeared);
 | 
					 | 
				
			||||||
				Hterm = as[level].actions.at(actionID)->S(Us);
 | 
					 | 
				
			||||||
				std::cout<<GridLogMessage << "S Level "<<level<<" term "<<actionID<<" H = "<<Hterm<<std::endl;
 | 
					 | 
				
			||||||
				H += Hterm;
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		return H;
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	void integrate(GaugeField& U){
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	// reset the clocks
 | 
					 | 
				
			||||||
		t_U=0;
 | 
					 | 
				
			||||||
		for(int level=0; level<as.size(); ++level){
 | 
					 | 
				
			||||||
			t_P[level]=0;
 | 
					 | 
				
			||||||
		}	
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	for(int step=0; step< Params.MDsteps; ++step){   // MD step
 | 
					 | 
				
			||||||
		int first_step = (step==0);
 | 
					 | 
				
			||||||
		int  last_step = (step==Params.MDsteps-1);
 | 
					 | 
				
			||||||
		this->step(U,0,first_step,last_step);
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	// Check the clocks all match on all levels
 | 
					 | 
				
			||||||
	for(int level=0; level<as.size(); ++level){
 | 
					 | 
				
			||||||
	  assert(fabs(t_U - t_P[level])<1.0e-6); // must be the same
 | 
					 | 
				
			||||||
	  std::cout<<GridLogIntegrator<<" times["<<level<<"]= "<<t_P[level]<< " " << t_U <<std::endl;
 | 
					 | 
				
			||||||
	}	
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	// and that we indeed got to the end of the trajectory
 | 
					 | 
				
			||||||
	assert(fabs(t_U-Params.trajL) < 1.0e-6);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*! @brief Class for Molecular Dynamics management */
 | 
				
			||||||
 | 
					template <class GaugeField, class SmearingPolicy, class RepresentationPolicy>
 | 
				
			||||||
 | 
					class Integrator {
 | 
				
			||||||
 | 
					 protected:
 | 
				
			||||||
 | 
					  typedef IntegratorParameters ParameterType;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  IntegratorParameters Params;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  const ActionSet<GaugeField, RepresentationPolicy> as;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  int levels;  //
 | 
				
			||||||
 | 
					  double t_U;  // Track time passing on each level and for U and for P
 | 
				
			||||||
 | 
					  std::vector<double> t_P;  //
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  GaugeField P;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  SmearingPolicy& Smearer;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  RepresentationPolicy Representations;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // Should match any legal (SU(n)) gauge field
 | 
				
			||||||
 | 
					  // Need to use this template to match Ncol to pass to SU<N> class
 | 
				
			||||||
 | 
					  template <int Ncol, class vec>
 | 
				
			||||||
 | 
					  void generate_momenta(Lattice<iVector<iScalar<iMatrix<vec, Ncol> >, Nd> >& P,
 | 
				
			||||||
 | 
					                        GridParallelRNG& pRNG) {
 | 
				
			||||||
 | 
					    typedef Lattice<iScalar<iScalar<iMatrix<vec, Ncol> > > > GaugeLinkField;
 | 
				
			||||||
 | 
					    GaugeLinkField Pmu(P._grid);
 | 
				
			||||||
 | 
					    Pmu = zero;
 | 
				
			||||||
 | 
					    for (int mu = 0; mu < Nd; mu++) {
 | 
				
			||||||
 | 
					      SU<Ncol>::GaussianFundamentalLieAlgebraMatrix(pRNG, Pmu);
 | 
				
			||||||
 | 
					      PokeIndex<LorentzIndex>(P, Pmu, mu);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // ObserverList observers; // not yet
 | 
				
			||||||
 | 
					  //      typedef std::vector<Observer*> ObserverList;
 | 
				
			||||||
 | 
					  //      void register_observers();
 | 
				
			||||||
 | 
					  //      void notify_observers();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  void update_P(GaugeField& U, int level, double ep) {
 | 
				
			||||||
 | 
					    t_P[level] += ep;
 | 
				
			||||||
 | 
					    update_P(P, U, level, ep);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    std::cout << GridLogIntegrator << "[" << level << "] P "
 | 
				
			||||||
 | 
					              << " dt " << ep << " : t_P " << t_P[level] << std::endl;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // to be used by the actionlevel class to iterate
 | 
				
			||||||
 | 
					  // over the representations
 | 
				
			||||||
 | 
					  struct _updateP {
 | 
				
			||||||
 | 
					    template <class FieldType, class GF, class Repr>
 | 
				
			||||||
 | 
					    void operator()(std::vector<Action<FieldType>*> repr_set, Repr& Rep,
 | 
				
			||||||
 | 
					                    GF& Mom, GF& U, double ep) {
 | 
				
			||||||
 | 
					      for (int a = 0; a < repr_set.size(); ++a) {
 | 
				
			||||||
 | 
					        FieldType forceR(U._grid);
 | 
				
			||||||
 | 
					        // Implement smearing only for the fundamental representation now
 | 
				
			||||||
 | 
					        repr_set.at(a)->deriv(Rep.U, forceR);
 | 
				
			||||||
 | 
					        GF force =
 | 
				
			||||||
 | 
					            Rep.RtoFundamentalProject(forceR);  // Ta for the fundamental rep
 | 
				
			||||||
 | 
					        std::cout << GridLogIntegrator << "Hirep Force average: "
 | 
				
			||||||
 | 
					                  << norm2(force) / (U._grid->gSites()) << std::endl;
 | 
				
			||||||
 | 
					        Mom -= force * ep ;
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  } update_P_hireps{};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  void update_P(GaugeField& Mom, GaugeField& U, int level, double ep) {
 | 
				
			||||||
 | 
					    // input U actually not used in the fundamental case
 | 
				
			||||||
 | 
					    // Fundamental updates, include smearing
 | 
				
			||||||
 | 
					    for (int a = 0; a < as[level].actions.size(); ++a) {
 | 
				
			||||||
 | 
					      GaugeField force(U._grid);
 | 
				
			||||||
 | 
					      GaugeField& Us = Smearer.get_U(as[level].actions.at(a)->is_smeared);
 | 
				
			||||||
 | 
					      as[level].actions.at(a)->deriv(Us, force);  // deriv should NOT include Ta
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      std::cout << GridLogIntegrator
 | 
				
			||||||
 | 
					                << "Smearing (on/off): " << as[level].actions.at(a)->is_smeared
 | 
				
			||||||
 | 
					                << std::endl;
 | 
				
			||||||
 | 
					      if (as[level].actions.at(a)->is_smeared) Smearer.smeared_force(force);
 | 
				
			||||||
 | 
					      force = Ta(force);
 | 
				
			||||||
 | 
					      std::cout << GridLogIntegrator
 | 
				
			||||||
 | 
					                << "Force average: " << norm2(force) / (U._grid->gSites())
 | 
				
			||||||
 | 
					                << std::endl;
 | 
				
			||||||
 | 
					      Mom -= force * ep;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // Force from the other representations
 | 
				
			||||||
 | 
					    as[level].apply(update_P_hireps, Representations, Mom, U, ep);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  void update_U(GaugeField& U, double ep) {
 | 
				
			||||||
 | 
					    update_U(P, U, ep);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    t_U += ep;
 | 
				
			||||||
 | 
					    int fl = levels - 1;
 | 
				
			||||||
 | 
					    std::cout << GridLogIntegrator << "   "
 | 
				
			||||||
 | 
					              << "[" << fl << "] U "
 | 
				
			||||||
 | 
					              << " dt " << ep << " : t_U " << t_U << std::endl;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  void update_U(GaugeField& Mom, GaugeField& U, double ep) {
 | 
				
			||||||
 | 
					    // rewrite exponential to deal internally with the lorentz index?
 | 
				
			||||||
 | 
					    for (int mu = 0; mu < Nd; mu++) {
 | 
				
			||||||
 | 
					      auto Umu = PeekIndex<LorentzIndex>(U, mu);
 | 
				
			||||||
 | 
					      auto Pmu = PeekIndex<LorentzIndex>(Mom, mu);
 | 
				
			||||||
 | 
					      Umu = expMat(Pmu, ep, Params.Nexp) * Umu;
 | 
				
			||||||
 | 
					      PokeIndex<LorentzIndex>(U, ProjectOnGroup(Umu), mu);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    // Update the smeared fields, can be implemented as observer
 | 
				
			||||||
 | 
					    Smearer.set_GaugeField(U);
 | 
				
			||||||
 | 
					    // Update the higher representations fields
 | 
				
			||||||
 | 
					    Representations.update(U);  // void functions if fundamental representation
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  virtual void step(GaugeField& U, int level, int first, int last) = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					 public:
 | 
				
			||||||
 | 
					  Integrator(GridBase* grid, IntegratorParameters Par,
 | 
				
			||||||
 | 
					             ActionSet<GaugeField, RepresentationPolicy>& Aset,
 | 
				
			||||||
 | 
					             SmearingPolicy& Sm)
 | 
				
			||||||
 | 
					      : Params(Par),
 | 
				
			||||||
 | 
					        as(Aset),
 | 
				
			||||||
 | 
					        P(grid),
 | 
				
			||||||
 | 
					        levels(Aset.size()),
 | 
				
			||||||
 | 
					        Smearer(Sm),
 | 
				
			||||||
 | 
					        Representations(grid) {
 | 
				
			||||||
 | 
					    t_P.resize(levels, 0.0);
 | 
				
			||||||
 | 
					    t_U = 0.0;
 | 
				
			||||||
 | 
					    // initialization of smearer delegated outside of Integrator
 | 
				
			||||||
 | 
					  };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  virtual ~Integrator() {}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // to be used by the actionlevel class to iterate
 | 
				
			||||||
 | 
					  // over the representations
 | 
				
			||||||
 | 
					  struct _refresh {
 | 
				
			||||||
 | 
					    template <class FieldType, class Repr>
 | 
				
			||||||
 | 
					    void operator()(std::vector<Action<FieldType>*> repr_set, Repr& Rep,
 | 
				
			||||||
 | 
					                    GridParallelRNG& pRNG) {
 | 
				
			||||||
 | 
					      for (int a = 0; a < repr_set.size(); ++a){
 | 
				
			||||||
 | 
					        repr_set.at(a)->refresh(Rep.U, pRNG);
 | 
				
			||||||
 | 
					      
 | 
				
			||||||
 | 
					      std::cout << GridLogDebug << "Hirep refreshing pseudofermions" << std::endl;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  } refresh_hireps{};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // Initialization of momenta and actions
 | 
				
			||||||
 | 
					  void refresh(GaugeField& U, GridParallelRNG& pRNG) {
 | 
				
			||||||
 | 
					    std::cout << GridLogIntegrator << "Integrator refresh\n";
 | 
				
			||||||
 | 
					    generate_momenta(P, pRNG);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // Update the smeared fields, can be implemented as observer
 | 
				
			||||||
 | 
					    // necessary to keep the fields updated even after a reject
 | 
				
			||||||
 | 
					    // of the Metropolis
 | 
				
			||||||
 | 
					    Smearer.set_GaugeField(U);
 | 
				
			||||||
 | 
					    // Set the (eventual) representations gauge fields
 | 
				
			||||||
 | 
					    Representations.update(U);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // The Smearer is attached to a pointer of the gauge field
 | 
				
			||||||
 | 
					    // automatically gets the correct field
 | 
				
			||||||
 | 
					    // whether or not has been accepted in the previous sweep
 | 
				
			||||||
 | 
					    for (int level = 0; level < as.size(); ++level) {
 | 
				
			||||||
 | 
					      for (int actionID = 0; actionID < as[level].actions.size(); ++actionID) {
 | 
				
			||||||
 | 
					        // get gauge field from the SmearingPolicy and
 | 
				
			||||||
 | 
					        // based on the boolean is_smeared in actionID
 | 
				
			||||||
 | 
					        GaugeField& Us =
 | 
				
			||||||
 | 
					            Smearer.get_U(as[level].actions.at(actionID)->is_smeared);
 | 
				
			||||||
 | 
					        as[level].actions.at(actionID)->refresh(Us, pRNG);
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      // Refresh the higher representation actions
 | 
				
			||||||
 | 
					      as[level].apply(refresh_hireps, Representations, pRNG);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // to be used by the actionlevel class to iterate
 | 
				
			||||||
 | 
					  // over the representations
 | 
				
			||||||
 | 
					  struct _S {
 | 
				
			||||||
 | 
					    template <class FieldType, class Repr>
 | 
				
			||||||
 | 
					    void operator()(std::vector<Action<FieldType>*> repr_set, Repr& Rep,
 | 
				
			||||||
 | 
					                    int level, RealD& H) {
 | 
				
			||||||
 | 
					      
 | 
				
			||||||
 | 
					      for (int a = 0; a < repr_set.size(); ++a) {
 | 
				
			||||||
 | 
					        RealD Hterm = repr_set.at(a)->S(Rep.U);
 | 
				
			||||||
 | 
					        std::cout << GridLogMessage << "S Level " << level << " term " << a
 | 
				
			||||||
 | 
					                  << " H Hirep = " << Hterm << std::endl;
 | 
				
			||||||
 | 
					        H += Hterm;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  } S_hireps{};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // Calculate action
 | 
				
			||||||
 | 
					  RealD S(GaugeField& U) {  // here also U not used
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    LatticeComplex Hloc(U._grid);
 | 
				
			||||||
 | 
					    Hloc = zero;
 | 
				
			||||||
 | 
					    // Momenta
 | 
				
			||||||
 | 
					    for (int mu = 0; mu < Nd; mu++) {
 | 
				
			||||||
 | 
					      auto Pmu = PeekIndex<LorentzIndex>(P, mu);
 | 
				
			||||||
 | 
					      Hloc -= trace(Pmu * Pmu);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    Complex Hsum = sum(Hloc);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    RealD H = Hsum.real();
 | 
				
			||||||
 | 
					    RealD Hterm;
 | 
				
			||||||
 | 
					    std::cout << GridLogMessage << "Momentum action H_p = " << H << "\n";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // Actions
 | 
				
			||||||
 | 
					    for (int level = 0; level < as.size(); ++level) {
 | 
				
			||||||
 | 
					      for (int actionID = 0; actionID < as[level].actions.size(); ++actionID) {
 | 
				
			||||||
 | 
					        // get gauge field from the SmearingPolicy and
 | 
				
			||||||
 | 
					        // based on the boolean is_smeared in actionID
 | 
				
			||||||
 | 
					        GaugeField& Us =
 | 
				
			||||||
 | 
					            Smearer.get_U(as[level].actions.at(actionID)->is_smeared);
 | 
				
			||||||
 | 
					        Hterm = as[level].actions.at(actionID)->S(Us);
 | 
				
			||||||
 | 
					        std::cout << GridLogMessage << "S Level " << level << " term "
 | 
				
			||||||
 | 
					                  << actionID << " H = " << Hterm << std::endl;
 | 
				
			||||||
 | 
					        H += Hterm;
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					      as[level].apply(S_hireps, Representations, level, H);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return H;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  void integrate(GaugeField& U) {
 | 
				
			||||||
 | 
					    // reset the clocks
 | 
				
			||||||
 | 
					    t_U = 0;
 | 
				
			||||||
 | 
					    for (int level = 0; level < as.size(); ++level) {
 | 
				
			||||||
 | 
					      t_P[level] = 0;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    for (int step = 0; step < Params.MDsteps; ++step) {  // MD step
 | 
				
			||||||
 | 
					      int first_step = (step == 0);
 | 
				
			||||||
 | 
					      int last_step = (step == Params.MDsteps - 1);
 | 
				
			||||||
 | 
					      this->step(U, 0, first_step, last_step);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // Check the clocks all match on all levels
 | 
				
			||||||
 | 
					    for (int level = 0; level < as.size(); ++level) {
 | 
				
			||||||
 | 
					      assert(fabs(t_U - t_P[level]) < 1.0e-6);  // must be the same
 | 
				
			||||||
 | 
					      std::cout << GridLogIntegrator << " times[" << level
 | 
				
			||||||
 | 
					                << "]= " << t_P[level] << " " << t_U << std::endl;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // and that we indeed got to the end of the trajectory
 | 
				
			||||||
 | 
					    assert(fabs(t_U - Params.trajL) < 1.0e-6);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
#endif//INTEGRATOR_INCLUDED
 | 
					#endif  // INTEGRATOR_INCLUDED
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -91,17 +91,19 @@ namespace Grid{
 | 
				
			|||||||
    *  P 1/2                            P 1/2
 | 
					    *  P 1/2                            P 1/2
 | 
				
			||||||
    */    
 | 
					    */    
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    template<class GaugeField, class SmearingPolicy> class LeapFrog :
 | 
					    template<class GaugeField,
 | 
				
			||||||
      public Integrator<GaugeField, SmearingPolicy> {
 | 
						     class SmearingPolicy,
 | 
				
			||||||
 | 
						     class RepresentationPolicy = Representations< FundamentalRepresentation > > class LeapFrog :
 | 
				
			||||||
 | 
					      public Integrator<GaugeField, SmearingPolicy, RepresentationPolicy> {
 | 
				
			||||||
    public:
 | 
					    public:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      typedef LeapFrog<GaugeField, SmearingPolicy> Algorithm;
 | 
					      typedef LeapFrog<GaugeField, SmearingPolicy, RepresentationPolicy> Algorithm;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      LeapFrog(GridBase* grid, 
 | 
					      LeapFrog(GridBase* grid, 
 | 
				
			||||||
	       IntegratorParameters Par,
 | 
						       IntegratorParameters Par,
 | 
				
			||||||
	       ActionSet<GaugeField> & Aset,
 | 
						       ActionSet<GaugeField, RepresentationPolicy> & Aset,
 | 
				
			||||||
	       SmearingPolicy & Sm):
 | 
						       SmearingPolicy & Sm):
 | 
				
			||||||
	Integrator<GaugeField, SmearingPolicy>(grid,Par,Aset,Sm) {};
 | 
						Integrator<GaugeField, SmearingPolicy, RepresentationPolicy>(grid,Par,Aset,Sm) {};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      void step (GaugeField& U, int level,int _first, int _last){
 | 
					      void step (GaugeField& U, int level,int _first, int _last){
 | 
				
			||||||
@@ -138,8 +140,10 @@ namespace Grid{
 | 
				
			|||||||
      }
 | 
					      }
 | 
				
			||||||
    };
 | 
					    };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    template<class GaugeField, class SmearingPolicy> class MinimumNorm2 :
 | 
					    template<class GaugeField,
 | 
				
			||||||
      public Integrator<GaugeField, SmearingPolicy> {
 | 
						     class SmearingPolicy,
 | 
				
			||||||
 | 
						     class RepresentationPolicy = Representations < FundamentalRepresentation > > class MinimumNorm2 :
 | 
				
			||||||
 | 
					      public Integrator<GaugeField, SmearingPolicy, RepresentationPolicy> {
 | 
				
			||||||
    private:
 | 
					    private:
 | 
				
			||||||
      const RealD lambda = 0.1931833275037836;
 | 
					      const RealD lambda = 0.1931833275037836;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -147,9 +151,9 @@ namespace Grid{
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
      MinimumNorm2(GridBase* grid, 
 | 
					      MinimumNorm2(GridBase* grid, 
 | 
				
			||||||
		   IntegratorParameters Par,
 | 
							   IntegratorParameters Par,
 | 
				
			||||||
		   ActionSet<GaugeField> & Aset,
 | 
							   ActionSet<GaugeField, RepresentationPolicy> & Aset,
 | 
				
			||||||
		   SmearingPolicy& Sm):
 | 
							   SmearingPolicy& Sm):
 | 
				
			||||||
	Integrator<GaugeField, SmearingPolicy>(grid,Par,Aset,Sm) {};
 | 
						Integrator<GaugeField, SmearingPolicy, RepresentationPolicy>(grid,Par,Aset,Sm) {};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      void step (GaugeField& U, int level, int _first,int _last){
 | 
					      void step (GaugeField& U, int level, int _first,int _last){
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -197,8 +201,10 @@ namespace Grid{
 | 
				
			|||||||
    };
 | 
					    };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    template<class GaugeField, class SmearingPolicy> class ForceGradient :
 | 
					    template<class GaugeField,
 | 
				
			||||||
      public Integrator<GaugeField, SmearingPolicy> {
 | 
						     class SmearingPolicy,
 | 
				
			||||||
 | 
						     class RepresentationPolicy = Representations< FundamentalRepresentation > > class ForceGradient :
 | 
				
			||||||
 | 
					      public Integrator<GaugeField, SmearingPolicy, RepresentationPolicy> {
 | 
				
			||||||
    private:
 | 
					    private:
 | 
				
			||||||
      const RealD lambda = 1.0/6.0;;
 | 
					      const RealD lambda = 1.0/6.0;;
 | 
				
			||||||
      const RealD chi    = 1.0/72.0;
 | 
					      const RealD chi    = 1.0/72.0;
 | 
				
			||||||
@@ -209,9 +215,9 @@ namespace Grid{
 | 
				
			|||||||
      // Looks like dH scales as dt^4. tested wilson/wilson 2 level.
 | 
					      // Looks like dH scales as dt^4. tested wilson/wilson 2 level.
 | 
				
			||||||
    ForceGradient(GridBase* grid, 
 | 
					    ForceGradient(GridBase* grid, 
 | 
				
			||||||
		  IntegratorParameters Par,
 | 
							  IntegratorParameters Par,
 | 
				
			||||||
		  ActionSet<GaugeField> & Aset,
 | 
							  ActionSet<GaugeField, RepresentationPolicy> & Aset,
 | 
				
			||||||
		  SmearingPolicy &Sm):
 | 
							  SmearingPolicy &Sm):
 | 
				
			||||||
      Integrator<GaugeField, SmearingPolicy>(grid,Par,Aset, Sm) {};
 | 
					      Integrator<GaugeField, SmearingPolicy, RepresentationPolicy>(grid,Par,Aset, Sm) {};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      void FG_update_P(GaugeField&U, int level,double fg_dt,double ep){
 | 
					      void FG_update_P(GaugeField&U, int level,double fg_dt,double ep){
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										115
									
								
								lib/qcd/representations/adjoint.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										115
									
								
								lib/qcd/representations/adjoint.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,115 @@
 | 
				
			|||||||
 | 
					/*
 | 
				
			||||||
 | 
					 *  Policy classes for the HMC
 | 
				
			||||||
 | 
					 *  Author: Guido Cossu
 | 
				
			||||||
 | 
					*/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifndef ADJOINT_H
 | 
				
			||||||
 | 
					#define ADJOINT_H
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace Grid {
 | 
				
			||||||
 | 
					namespace QCD {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					* This is an helper class for the HMC
 | 
				
			||||||
 | 
					* Should contain only the data for the adjoint representation
 | 
				
			||||||
 | 
					* and the facility to convert from the fundamental -> adjoint
 | 
				
			||||||
 | 
					*/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					template <int ncolour>
 | 
				
			||||||
 | 
					class AdjointRep {
 | 
				
			||||||
 | 
					 public:
 | 
				
			||||||
 | 
					  // typdef to be used by the Representations class in HMC to get the
 | 
				
			||||||
 | 
					  // types for the higher representation fields
 | 
				
			||||||
 | 
					  typedef typename SU_Adjoint<ncolour>::LatticeAdjMatrix LatticeMatrix;
 | 
				
			||||||
 | 
					  typedef typename SU_Adjoint<ncolour>::LatticeAdjField LatticeField;
 | 
				
			||||||
 | 
					  static const int Dimension = ncolour * ncolour - 1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  LatticeField U;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  explicit AdjointRep(GridBase *grid) : U(grid) {}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  void update_representation(const LatticeGaugeField &Uin) {
 | 
				
			||||||
 | 
					    std::cout << GridLogDebug << "Updating adjoint representation\n";
 | 
				
			||||||
 | 
					    // Uin is in the fundamental representation
 | 
				
			||||||
 | 
					    // get the U in AdjointRep
 | 
				
			||||||
 | 
					    // (U_adj)_B = tr[e^a U e^b U^dag]
 | 
				
			||||||
 | 
					    // e^a = t^a/sqrt(T_F)
 | 
				
			||||||
 | 
					    // where t^a is the generator in the fundamental
 | 
				
			||||||
 | 
					    // T_F is 1/2 for the fundamental representation
 | 
				
			||||||
 | 
					    conformable(U, Uin);
 | 
				
			||||||
 | 
					    U = zero;
 | 
				
			||||||
 | 
					    LatticeColourMatrix tmp(Uin._grid);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    Vector<typename SU<ncolour>::Matrix> ta(Dimension);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // Debug lines
 | 
				
			||||||
 | 
					    // LatticeMatrix uno(Uin._grid);
 | 
				
			||||||
 | 
					    // uno = 1.0;
 | 
				
			||||||
 | 
					    ////////////////
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // FIXME probably not very efficient to get all the generators
 | 
				
			||||||
 | 
					    // everytime
 | 
				
			||||||
 | 
					    for (int a = 0; a < Dimension; a++) SU<ncolour>::generator(a, ta[a]);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    for (int mu = 0; mu < Nd; mu++) {
 | 
				
			||||||
 | 
					      auto Uin_mu = peekLorentz(Uin, mu);
 | 
				
			||||||
 | 
					      auto U_mu = peekLorentz(U, mu);
 | 
				
			||||||
 | 
					      for (int a = 0; a < Dimension; a++) {
 | 
				
			||||||
 | 
					        tmp = 2.0 * adj(Uin_mu) * ta[a] * Uin_mu;
 | 
				
			||||||
 | 
					        for (int b = 0; b < Dimension; b++)
 | 
				
			||||||
 | 
					          pokeColour(U_mu, trace(tmp * ta[b]), a, b);
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					      pokeLorentz(U, U_mu, mu);
 | 
				
			||||||
 | 
					      // Check matrix U_mu, must be real orthogonal
 | 
				
			||||||
 | 
					      // reality
 | 
				
			||||||
 | 
					      /*
 | 
				
			||||||
 | 
					      LatticeMatrix Ucheck = U_mu - conjugate(U_mu);
 | 
				
			||||||
 | 
					      std::cout << GridLogMessage << "Reality check: " << norm2(Ucheck) <<
 | 
				
			||||||
 | 
					      std::endl;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      Ucheck = U_mu * adj(U_mu) - uno;
 | 
				
			||||||
 | 
					      std::cout << GridLogMessage << "orthogonality check: " << norm2(Ucheck) <<
 | 
				
			||||||
 | 
					      std::endl;
 | 
				
			||||||
 | 
					      */
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  LatticeGaugeField RtoFundamentalProject(const LatticeField &in,
 | 
				
			||||||
 | 
					                                          Real scale = 1.0) const {
 | 
				
			||||||
 | 
					    LatticeGaugeField out(in._grid);
 | 
				
			||||||
 | 
					    out = zero;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    for (int mu = 0; mu < Nd; mu++) {
 | 
				
			||||||
 | 
					      LatticeColourMatrix out_mu(in._grid);  // fundamental representation
 | 
				
			||||||
 | 
					      LatticeMatrix in_mu = peekLorentz(in, mu);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      out_mu = zero;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      typename SU<ncolour>::LatticeAlgebraVector h(in._grid);
 | 
				
			||||||
 | 
					      projectOnAlgebra(h, in_mu, double(Nc) * 2.0);  // factor C(r)/C(fund)
 | 
				
			||||||
 | 
					      FundamentalLieAlgebraMatrix(h, out_mu);   // apply scale only once
 | 
				
			||||||
 | 
					      pokeLorentz(out, out_mu, mu);
 | 
				
			||||||
 | 
					      // Returns traceless antihermitian matrix Nc * Nc.
 | 
				
			||||||
 | 
					      // Confirmed
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    return out;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					 private:
 | 
				
			||||||
 | 
					  void projectOnAlgebra(typename SU<ncolour>::LatticeAlgebraVector &h_out,
 | 
				
			||||||
 | 
					                        const LatticeMatrix &in, Real scale = 1.0) const {
 | 
				
			||||||
 | 
					    SU_Adjoint<ncolour>::projectOnAlgebra(h_out, in, scale);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  void FundamentalLieAlgebraMatrix(
 | 
				
			||||||
 | 
					      typename SU<ncolour>::LatticeAlgebraVector &h,
 | 
				
			||||||
 | 
					      typename SU<ncolour>::LatticeMatrix &out, Real scale = 1.0) const {
 | 
				
			||||||
 | 
					    SU<ncolour>::FundamentalLieAlgebraMatrix(h, out, scale);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					typedef AdjointRep<Nc> AdjointRepresentation;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
							
								
								
									
										45
									
								
								lib/qcd/representations/fundamental.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										45
									
								
								lib/qcd/representations/fundamental.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,45 @@
 | 
				
			|||||||
 | 
					/*
 | 
				
			||||||
 | 
					 *	Policy classes for the HMC
 | 
				
			||||||
 | 
					 *	Author: Guido Cossu
 | 
				
			||||||
 | 
					*/	
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifndef FUNDAMENTAL_H
 | 
				
			||||||
 | 
					#define FUNDAMENTAL_H
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace Grid {
 | 
				
			||||||
 | 
					namespace QCD {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					* This is an helper class for the HMC
 | 
				
			||||||
 | 
					* Empty since HMC updates already the fundamental representation 
 | 
				
			||||||
 | 
					*/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					template <int ncolour>
 | 
				
			||||||
 | 
					class FundamentalRep {
 | 
				
			||||||
 | 
					 public:
 | 
				
			||||||
 | 
					  static const int Dimension = ncolour;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // typdef to be used by the Representations class in HMC to get the
 | 
				
			||||||
 | 
					  // types for the higher representation fields
 | 
				
			||||||
 | 
					  typedef typename SU<ncolour>::LatticeMatrix LatticeMatrix;
 | 
				
			||||||
 | 
					  typedef LatticeGaugeField LatticeField;
 | 
				
			||||||
 | 
					  
 | 
				
			||||||
 | 
					  explicit FundamentalRep(GridBase* grid) {} //do nothing
 | 
				
			||||||
 | 
					  void update_representation(const LatticeGaugeField& Uin) {} // do nothing
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  LatticeField RtoFundamentalProject(const LatticeField& in, Real scale = 1.0) const{
 | 
				
			||||||
 | 
					    return (scale * in);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					typedef	 FundamentalRep<Nc> FundamentalRepresentation;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
							
								
								
									
										91
									
								
								lib/qcd/representations/hmc_types.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										91
									
								
								lib/qcd/representations/hmc_types.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,91 @@
 | 
				
			|||||||
 | 
					#ifndef HMC_TYPES_H
 | 
				
			||||||
 | 
					#define HMC_TYPES_H
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <Grid/qcd/representations/adjoint.h>
 | 
				
			||||||
 | 
					#include <Grid/qcd/representations/two_index.h>
 | 
				
			||||||
 | 
					#include <Grid/qcd/representations/fundamental.h>
 | 
				
			||||||
 | 
					#include <tuple>
 | 
				
			||||||
 | 
					#include <utility>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace Grid {
 | 
				
			||||||
 | 
					namespace QCD {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Supported types
 | 
				
			||||||
 | 
					// enum {Fundamental, Adjoint} repr_type;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Utility to add support to the HMC for representations other than the
 | 
				
			||||||
 | 
					// fundamental
 | 
				
			||||||
 | 
					template <class... Reptypes>
 | 
				
			||||||
 | 
					class Representations {
 | 
				
			||||||
 | 
					 public:
 | 
				
			||||||
 | 
					  typedef std::tuple<Reptypes...> Representation_type;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // Size of the tuple, known at compile time
 | 
				
			||||||
 | 
					  static const int tuple_size = sizeof...(Reptypes);
 | 
				
			||||||
 | 
					  // The collection of types for the gauge fields
 | 
				
			||||||
 | 
					  typedef std::tuple<typename Reptypes::LatticeField...> Representation_Fields;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // To access the Reptypes (FundamentalRepresentation, AdjointRepresentation)
 | 
				
			||||||
 | 
					  template <std::size_t N>
 | 
				
			||||||
 | 
					  using repr_type = typename std::tuple_element<N, Representation_type>::type;
 | 
				
			||||||
 | 
					  // in order to get the typename of the field use
 | 
				
			||||||
 | 
					  // type repr_type<I>::LatticeField
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  Representation_type rep;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // Multiple types constructor
 | 
				
			||||||
 | 
					  explicit Representations(GridBase* grid) : rep(Reptypes(grid)...){};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  int size() { return tuple_size; }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // update the fields
 | 
				
			||||||
 | 
					  template <std::size_t I = 0>
 | 
				
			||||||
 | 
					  inline typename std::enable_if<(I == tuple_size), void>::type update(
 | 
				
			||||||
 | 
					      LatticeGaugeField& U) {}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  template <std::size_t I = 0>
 | 
				
			||||||
 | 
					  inline typename std::enable_if<(I < tuple_size), void>::type update(
 | 
				
			||||||
 | 
					      LatticeGaugeField& U) {
 | 
				
			||||||
 | 
					    std::get<I>(rep).update_representation(U);
 | 
				
			||||||
 | 
					    update<I + 1>(U);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					typedef Representations<FundamentalRepresentation> NoHirep;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Helper classes to access the elements
 | 
				
			||||||
 | 
					// Strips the first N parameters from the tuple
 | 
				
			||||||
 | 
					// sequence of classes to obtain the S sequence
 | 
				
			||||||
 | 
					// Creates a type that is a tuple of vectors of the template type A
 | 
				
			||||||
 | 
					template <template <typename> class A, class TupleClass,
 | 
				
			||||||
 | 
					          size_t N = TupleClass::tuple_size, size_t... S>
 | 
				
			||||||
 | 
					struct AccessTypes : AccessTypes<A, TupleClass, N - 1, N - 1, S...> {};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					template <template <typename> class A, class TupleClass, size_t... S>
 | 
				
			||||||
 | 
					struct AccessTypes<A, TupleClass, 0, S...> {
 | 
				
			||||||
 | 
					 public:
 | 
				
			||||||
 | 
					  typedef typename TupleClass::Representation_Fields Rfields;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  template <std::size_t N>
 | 
				
			||||||
 | 
					  using elem = typename std::tuple_element<N, Rfields>::type;  // fields types
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  typedef std::tuple<std::vector< A< elem<S> >* > ... > VectorCollection;
 | 
				
			||||||
 | 
					  typedef std::tuple< elem<S> ... > FieldTypeCollection;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // Debug
 | 
				
			||||||
 | 
					  void return_size() {
 | 
				
			||||||
 | 
					    std::cout << GridLogMessage
 | 
				
			||||||
 | 
					              << "Access:" << std::tuple_size<std::tuple<elem<S>...> >::value
 | 
				
			||||||
 | 
					              << "\n";
 | 
				
			||||||
 | 
					    std::cout << GridLogMessage
 | 
				
			||||||
 | 
					              << "Access vectors:" << std::tuple_size<VectorCollection>::value
 | 
				
			||||||
 | 
					              << "\n";
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
							
								
								
									
										99
									
								
								lib/qcd/representations/two_index.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										99
									
								
								lib/qcd/representations/two_index.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,99 @@
 | 
				
			|||||||
 | 
					/*
 | 
				
			||||||
 | 
					 *  Policy classes for the HMC
 | 
				
			||||||
 | 
					 *  Authors: Guido Cossu, David Preti
 | 
				
			||||||
 | 
					*/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifndef SUN2INDEX_H_H
 | 
				
			||||||
 | 
					#define SUN2INDEX_H_H
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace Grid {
 | 
				
			||||||
 | 
					namespace QCD {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * This is an helper class for the HMC
 | 
				
			||||||
 | 
					 * Should contain only the data for the two index representations
 | 
				
			||||||
 | 
					 * and the facility to convert from the fundamental -> two index
 | 
				
			||||||
 | 
					 * The templated parameter TwoIndexSymmetry choses between the 
 | 
				
			||||||
 | 
					 * symmetric and antisymmetric representations
 | 
				
			||||||
 | 
					 * 
 | 
				
			||||||
 | 
					 * There is an 
 | 
				
			||||||
 | 
					 * enum TwoIndexSymmetry { Symmetric = 1, AntiSymmetric = -1 };
 | 
				
			||||||
 | 
					 * in the SUnTwoIndex.h file
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					template <int ncolour, TwoIndexSymmetry S>
 | 
				
			||||||
 | 
					class TwoIndexRep {
 | 
				
			||||||
 | 
					 public:
 | 
				
			||||||
 | 
					  // typdef to be used by the Representations class in HMC to get the
 | 
				
			||||||
 | 
					  // types for the higher representation fields
 | 
				
			||||||
 | 
					  typedef typename SU_TwoIndex<ncolour, S>::LatticeTwoIndexMatrix LatticeMatrix;
 | 
				
			||||||
 | 
					  typedef typename SU_TwoIndex<ncolour, S>::LatticeTwoIndexField LatticeField;
 | 
				
			||||||
 | 
					  static const int Dimension = ncolour * (ncolour + S) / 2;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  LatticeField U;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  explicit TwoIndexRep(GridBase *grid) : U(grid) {}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  void update_representation(const LatticeGaugeField &Uin) {
 | 
				
			||||||
 | 
					    std::cout << GridLogDebug << "Updating TwoIndex representation\n";
 | 
				
			||||||
 | 
					    // Uin is in the fundamental representation
 | 
				
			||||||
 | 
					    // get the U in TwoIndexRep
 | 
				
			||||||
 | 
					    // (U)_{(ij)(lk)} = tr [ adj(e^(ij)) U e^(lk) transpose(U) ]
 | 
				
			||||||
 | 
					    conformable(U, Uin);
 | 
				
			||||||
 | 
					    U = zero;
 | 
				
			||||||
 | 
					    LatticeColourMatrix tmp(Uin._grid);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    Vector<typename SU<ncolour>::Matrix> eij(Dimension);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    for (int a = 0; a < Dimension; a++)
 | 
				
			||||||
 | 
					      SU_TwoIndex<ncolour, S>::base(a, eij[a]);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    for (int mu = 0; mu < Nd; mu++) {
 | 
				
			||||||
 | 
					      auto Uin_mu = peekLorentz(Uin, mu);
 | 
				
			||||||
 | 
					      auto U_mu = peekLorentz(U, mu);
 | 
				
			||||||
 | 
					      for (int a = 0; a < Dimension; a++) {
 | 
				
			||||||
 | 
					        tmp = transpose(Uin_mu) * adj(eij[a]) * Uin_mu;
 | 
				
			||||||
 | 
					        for (int b = 0; b < Dimension; b++)
 | 
				
			||||||
 | 
					          pokeColour(U_mu, trace(tmp * eij[b]), a, b);
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					      pokeLorentz(U, U_mu, mu);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  LatticeGaugeField RtoFundamentalProject(const LatticeField &in,
 | 
				
			||||||
 | 
					                                          Real scale = 1.0) const {
 | 
				
			||||||
 | 
					    LatticeGaugeField out(in._grid);
 | 
				
			||||||
 | 
					    out = zero;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    for (int mu = 0; mu < Nd; mu++) {
 | 
				
			||||||
 | 
					      LatticeColourMatrix out_mu(in._grid);  // fundamental representation
 | 
				
			||||||
 | 
					      LatticeMatrix in_mu = peekLorentz(in, mu);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      out_mu = zero;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      typename SU<ncolour>::LatticeAlgebraVector h(in._grid);
 | 
				
			||||||
 | 
					      projectOnAlgebra(h, in_mu, double(Nc + 2 * S));  // factor T(r)/T(fund)
 | 
				
			||||||
 | 
					      FundamentalLieAlgebraMatrix(h, out_mu);          // apply scale only once
 | 
				
			||||||
 | 
					      pokeLorentz(out, out_mu, mu);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    return out;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					 private:
 | 
				
			||||||
 | 
					  void projectOnAlgebra(typename SU<ncolour>::LatticeAlgebraVector &h_out,
 | 
				
			||||||
 | 
					                        const LatticeMatrix &in, Real scale = 1.0) const {
 | 
				
			||||||
 | 
					    SU_TwoIndex<ncolour, S>::projectOnAlgebra(h_out, in, scale);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  void FundamentalLieAlgebraMatrix(
 | 
				
			||||||
 | 
					      typename SU<ncolour>::LatticeAlgebraVector &h,
 | 
				
			||||||
 | 
					      typename SU<ncolour>::LatticeMatrix &out, Real scale = 1.0) const {
 | 
				
			||||||
 | 
					    SU<ncolour>::FundamentalLieAlgebraMatrix(h, out, scale);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					typedef TwoIndexRep<Nc, Symmetric> TwoIndexSymmetricRepresentation;
 | 
				
			||||||
 | 
					typedef TwoIndexRep<Nc, AntiSymmetric> TwoIndexAntiSymmetricRepresentation;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
@@ -10,6 +10,29 @@ namespace Grid {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
namespace QCD {
 | 
					namespace QCD {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  //trivial class for no smearing
 | 
				
			||||||
 | 
					  template< class Gimpl >
 | 
				
			||||||
 | 
					class NoSmearing {
 | 
				
			||||||
 | 
					public:
 | 
				
			||||||
 | 
					  INHERIT_GIMPL_TYPES(Gimpl);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  GaugeField*
 | 
				
			||||||
 | 
					      ThinLinks;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  NoSmearing(): ThinLinks(NULL) {}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  void set_GaugeField(GaugeField& U) { ThinLinks = &U; }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  void smeared_force(GaugeField& SigmaTilde) const {}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  GaugeField& get_SmearedU() { return *ThinLinks; }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  GaugeField& get_U(bool smeared = false) {
 | 
				
			||||||
 | 
					    return *ThinLinks;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/*!
 | 
					/*!
 | 
				
			||||||
  @brief Smeared configuration container
 | 
					  @brief Smeared configuration container
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -201,6 +224,8 @@ class SmearedConfiguration {
 | 
				
			|||||||
  SmearedConfiguration()
 | 
					  SmearedConfiguration()
 | 
				
			||||||
      : smearingLevels(0), StoutSmearing(), SmearedSet(), ThinLinks(NULL) {}
 | 
					      : smearingLevels(0), StoutSmearing(), SmearedSet(), ThinLinks(NULL) {}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  
 | 
				
			||||||
  // attach the smeared routines to the thin links U and fill the smeared set
 | 
					  // attach the smeared routines to the thin links U and fill the smeared set
 | 
				
			||||||
  void set_GaugeField(GaugeField& U) { fill_smearedSet(U); }
 | 
					  void set_GaugeField(GaugeField& U) { fill_smearedSet(U); }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -18,14 +18,12 @@ class Smear_Stout : public Smear<Gimpl> {
 | 
				
			|||||||
  INHERIT_GIMPL_TYPES(Gimpl)
 | 
					  INHERIT_GIMPL_TYPES(Gimpl)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  Smear_Stout(Smear<Gimpl>* base) : SmearBase(base) {
 | 
					  Smear_Stout(Smear<Gimpl>* base) : SmearBase(base) {
 | 
				
			||||||
    static_assert(Nc == 3,
 | 
					    assert(Nc == 3);//                  "Stout smearing currently implemented only for Nc==3");
 | 
				
			||||||
                  "Stout smearing currently implemented only for Nc==3");
 | 
					 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  /*! Default constructor */
 | 
					  /*! Default constructor */
 | 
				
			||||||
  Smear_Stout(double rho = 1.0) : SmearBase(new Smear_APE<Gimpl>(rho)) {
 | 
					  Smear_Stout(double rho = 1.0) : SmearBase(new Smear_APE<Gimpl>(rho)) {
 | 
				
			||||||
    static_assert(Nc == 3,
 | 
					    assert(Nc == 3);//                  "Stout smearing currently implemented only for Nc==3");
 | 
				
			||||||
                  "Stout smearing currently implemented only for Nc==3");
 | 
					 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  ~Smear_Stout() {}  // delete SmearBase...
 | 
					  ~Smear_Stout() {}  // delete SmearBase...
 | 
				
			||||||
 
 | 
				
			|||||||
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										182
									
								
								lib/qcd/utils/SUnAdjoint.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										182
									
								
								lib/qcd/utils/SUnAdjoint.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,182 @@
 | 
				
			|||||||
 | 
					#ifndef QCD_UTIL_SUNADJOINT_H
 | 
				
			||||||
 | 
					#define QCD_UTIL_SUNADJOINT_H
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					////////////////////////////////////////////////////////////////////////
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					// * Adjoint representation generators
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					// * Normalisation for the fundamental generators: 
 | 
				
			||||||
 | 
					//   trace ta tb = 1/2 delta_ab = T_F delta_ab
 | 
				
			||||||
 | 
					//   T_F = 1/2  for SU(N) groups
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					//   base for NxN hermitian traceless matrices
 | 
				
			||||||
 | 
					//   normalized to 1:
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					//   (e_Adj)^a = t^a / sqrt(T_F)
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					//   then the real, antisymmetric generators for the adjoint representations
 | 
				
			||||||
 | 
					//   are computed ( shortcut: e^a == (e_Adj)^a )
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					//   (iT_adj)^d_ba = i tr[e^a t^d e^b - t^d e^a e^b]
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					////////////////////////////////////////////////////////////////////////
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace Grid {
 | 
				
			||||||
 | 
					namespace QCD {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					template <int ncolour>
 | 
				
			||||||
 | 
					class SU_Adjoint : public SU<ncolour> {
 | 
				
			||||||
 | 
					 public:
 | 
				
			||||||
 | 
					  static const int Dimension = ncolour * ncolour - 1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  template <typename vtype>
 | 
				
			||||||
 | 
					  using iSUnAdjointMatrix =
 | 
				
			||||||
 | 
					      iScalar<iScalar<iMatrix<vtype, Dimension > > >;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // Actually the adjoint matrices are real...
 | 
				
			||||||
 | 
					  // Consider this overhead... FIXME
 | 
				
			||||||
 | 
					  typedef iSUnAdjointMatrix<Complex> AMatrix;
 | 
				
			||||||
 | 
					  typedef iSUnAdjointMatrix<ComplexF> AMatrixF;
 | 
				
			||||||
 | 
					  typedef iSUnAdjointMatrix<ComplexD> AMatrixD;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  typedef iSUnAdjointMatrix<vComplex> vAMatrix;
 | 
				
			||||||
 | 
					  typedef iSUnAdjointMatrix<vComplexF> vAMatrixF;
 | 
				
			||||||
 | 
					  typedef iSUnAdjointMatrix<vComplexD> vAMatrixD;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  typedef Lattice<vAMatrix>  LatticeAdjMatrix;
 | 
				
			||||||
 | 
					  typedef Lattice<vAMatrixF> LatticeAdjMatrixF;
 | 
				
			||||||
 | 
					  typedef Lattice<vAMatrixD> LatticeAdjMatrixD;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  typedef Lattice<iVector<iScalar<iMatrix<vComplex, Dimension> >, Nd> >
 | 
				
			||||||
 | 
					      LatticeAdjField;
 | 
				
			||||||
 | 
					  typedef Lattice<iVector<iScalar<iMatrix<vComplexF, Dimension> >, Nd> >
 | 
				
			||||||
 | 
					      LatticeAdjFieldF;
 | 
				
			||||||
 | 
					  typedef Lattice<iVector<iScalar<iMatrix<vComplexD, Dimension> >, Nd> >
 | 
				
			||||||
 | 
					      LatticeAdjFieldD;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  template <class cplx>
 | 
				
			||||||
 | 
					  static void generator(int Index, iSUnAdjointMatrix<cplx> &iAdjTa) {
 | 
				
			||||||
 | 
					    // returns i(T_Adj)^index necessary for the projectors
 | 
				
			||||||
 | 
					    // see definitions above
 | 
				
			||||||
 | 
					    iAdjTa = zero;
 | 
				
			||||||
 | 
					    Vector<typename SU<ncolour>::template iSUnMatrix<cplx> > ta(ncolour * ncolour - 1);
 | 
				
			||||||
 | 
					    typename SU<ncolour>::template iSUnMatrix<cplx> tmp;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // FIXME not very efficient to get all the generators everytime
 | 
				
			||||||
 | 
					    for (int a = 0; a < Dimension; a++) SU<ncolour>::generator(a, ta[a]);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    for (int a = 0; a < Dimension; a++) {
 | 
				
			||||||
 | 
					      tmp = ta[a] * ta[Index] - ta[Index] * ta[a];
 | 
				
			||||||
 | 
					      for (int b = 0; b < (ncolour * ncolour - 1); b++) {
 | 
				
			||||||
 | 
					        typename SU<ncolour>::template iSUnMatrix<cplx> tmp1 =
 | 
				
			||||||
 | 
					            2.0 * tmp * ta[b];  // 2.0 from the normalization
 | 
				
			||||||
 | 
					        Complex iTr = TensorRemove(timesI(trace(tmp1)));
 | 
				
			||||||
 | 
					        //iAdjTa()()(b, a) = iTr;
 | 
				
			||||||
 | 
					        iAdjTa()()(a, b) = iTr;
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  static void printGenerators(void) {
 | 
				
			||||||
 | 
					    for (int gen = 0; gen < Dimension; gen++) {
 | 
				
			||||||
 | 
					      AMatrix ta;
 | 
				
			||||||
 | 
					      generator(gen, ta);
 | 
				
			||||||
 | 
					      std::cout << GridLogMessage << "Nc = " << ncolour << " t_" << gen
 | 
				
			||||||
 | 
					                << std::endl;
 | 
				
			||||||
 | 
					      std::cout << GridLogMessage << ta << std::endl;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  static void testGenerators(void) {
 | 
				
			||||||
 | 
					    AMatrix adjTa;
 | 
				
			||||||
 | 
					    std::cout << GridLogMessage << "Adjoint - Checking if real" << std::endl;
 | 
				
			||||||
 | 
					    for (int a = 0; a < Dimension; a++) {
 | 
				
			||||||
 | 
					      generator(a, adjTa);
 | 
				
			||||||
 | 
					      std::cout << GridLogMessage << a << std::endl;
 | 
				
			||||||
 | 
					      assert(norm2(adjTa - conjugate(adjTa)) < 1.0e-6);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    std::cout << GridLogMessage << std::endl;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    std::cout << GridLogMessage << "Adjoint - Checking if antisymmetric"
 | 
				
			||||||
 | 
					              << std::endl;
 | 
				
			||||||
 | 
					    for (int a = 0; a < Dimension; a++) {
 | 
				
			||||||
 | 
					      generator(a, adjTa);
 | 
				
			||||||
 | 
					      std::cout << GridLogMessage << a << std::endl;
 | 
				
			||||||
 | 
					      assert(norm2(adjTa + transpose(adjTa)) < 1.0e-6);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    std::cout << GridLogMessage << std::endl;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  static void AdjointLieAlgebraMatrix(
 | 
				
			||||||
 | 
					      const typename SU<ncolour>::LatticeAlgebraVector &h,
 | 
				
			||||||
 | 
					      LatticeAdjMatrix &out, Real scale = 1.0) {
 | 
				
			||||||
 | 
					    conformable(h, out);
 | 
				
			||||||
 | 
					    GridBase *grid = out._grid;
 | 
				
			||||||
 | 
					    LatticeAdjMatrix la(grid);
 | 
				
			||||||
 | 
					    AMatrix iTa;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    out = zero;
 | 
				
			||||||
 | 
					    for (int a = 0; a < Dimension; a++) {
 | 
				
			||||||
 | 
					      generator(a, iTa);
 | 
				
			||||||
 | 
					      la = peekColour(h, a) * iTa;
 | 
				
			||||||
 | 
					      out += la;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    out *= scale;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // Projects the algebra components a lattice matrix (of dimension ncol*ncol -1 )
 | 
				
			||||||
 | 
					  static void projectOnAlgebra(typename SU<ncolour>::LatticeAlgebraVector &h_out, const LatticeAdjMatrix &in, Real scale = 1.0) {
 | 
				
			||||||
 | 
					    conformable(h_out, in);
 | 
				
			||||||
 | 
					    h_out = zero;
 | 
				
			||||||
 | 
					    AMatrix iTa;
 | 
				
			||||||
 | 
					    Real coefficient = - 1.0/(ncolour) * scale;// 1/Nc for the normalization of the trace in the adj rep
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    for (int a = 0; a < Dimension; a++) {
 | 
				
			||||||
 | 
					      generator(a, iTa);
 | 
				
			||||||
 | 
					      auto tmp = real(trace(iTa * in)) * coefficient;
 | 
				
			||||||
 | 
					      pokeColour(h_out, tmp, a);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // a projector that keeps the generators stored to avoid the overhead of recomputing them 
 | 
				
			||||||
 | 
					  static void projector(typename SU<ncolour>::LatticeAlgebraVector &h_out, const LatticeAdjMatrix &in, Real scale = 1.0) {
 | 
				
			||||||
 | 
					    conformable(h_out, in);
 | 
				
			||||||
 | 
					    static std::vector<AMatrix> iTa(Dimension);  // to store the generators
 | 
				
			||||||
 | 
					    h_out = zero;
 | 
				
			||||||
 | 
					    static bool precalculated = false; 
 | 
				
			||||||
 | 
					    if (!precalculated){
 | 
				
			||||||
 | 
					      precalculated = true;
 | 
				
			||||||
 | 
					        for (int a = 0; a < Dimension; a++) generator(a, iTa[a]);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    Real coefficient = -1.0 / (ncolour) * scale;  // 1/Nc for the normalization of
 | 
				
			||||||
 | 
					                                                // the trace in the adj rep
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    for (int a = 0; a < Dimension; a++) {
 | 
				
			||||||
 | 
					      auto tmp = real(trace(iTa[a] * in)) * coefficient; 
 | 
				
			||||||
 | 
					      pokeColour(h_out, tmp, a);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Some useful type names
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					typedef SU_Adjoint<2> SU2Adjoint;
 | 
				
			||||||
 | 
					typedef SU_Adjoint<3> SU3Adjoint;
 | 
				
			||||||
 | 
					typedef SU_Adjoint<4> SU4Adjoint;
 | 
				
			||||||
 | 
					typedef SU_Adjoint<5> SU5Adjoint;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					typedef SU_Adjoint<Nc> AdjointMatrices;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
							
								
								
									
										276
									
								
								lib/qcd/utils/SUnTwoIndex.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										276
									
								
								lib/qcd/utils/SUnTwoIndex.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,276 @@
 | 
				
			|||||||
 | 
					////////////////////////////////////////////////////////////////////////
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					// * Two index representation generators
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					// * Normalisation for the fundamental generators:
 | 
				
			||||||
 | 
					//   trace ta tb = 1/2 delta_ab = T_F delta_ab
 | 
				
			||||||
 | 
					//   T_F = 1/2  for SU(N) groups
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					//   base for NxN two index (anti-symmetric) matrices
 | 
				
			||||||
 | 
					//   normalized to 1 (d_ij is the kroenecker delta)
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					//   (e^(ij)_{kl} = 1 / sqrt(2) (d_ik d_jl +/- d_jk d_il)
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					//   Then the generators are written as
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					//   (iT_a)^(ij)(lk) = i * ( tr[e^(ij)^dag e^(lk) T^trasp_a] +
 | 
				
			||||||
 | 
					//   tr[e^(lk)e^(ij)^dag T_a] )  //
 | 
				
			||||||
 | 
					//   
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					////////////////////////////////////////////////////////////////////////
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Authors: David Preti, Guido Cossu
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifndef QCD_UTIL_SUN2INDEX_H
 | 
				
			||||||
 | 
					#define QCD_UTIL_SUN2INDEX_H
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace Grid {
 | 
				
			||||||
 | 
					namespace QCD {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					enum TwoIndexSymmetry { Symmetric = 1, AntiSymmetric = -1 };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					inline Real delta(int a, int b) { return (a == b) ? 1.0 : 0.0; }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					template <int ncolour, TwoIndexSymmetry S>
 | 
				
			||||||
 | 
					class SU_TwoIndex : public SU<ncolour> {
 | 
				
			||||||
 | 
					 public:
 | 
				
			||||||
 | 
					  static const int Dimension = ncolour * (ncolour + S) / 2;
 | 
				
			||||||
 | 
					  static const int NumGenerators = SU<ncolour>::AdjointDimension;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  template <typename vtype>
 | 
				
			||||||
 | 
					  using iSUnTwoIndexMatrix = iScalar<iScalar<iMatrix<vtype, Dimension> > >;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  typedef iSUnTwoIndexMatrix<Complex> TIMatrix;
 | 
				
			||||||
 | 
					  typedef iSUnTwoIndexMatrix<ComplexF> TIMatrixF;
 | 
				
			||||||
 | 
					  typedef iSUnTwoIndexMatrix<ComplexD> TIMatrixD;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  typedef iSUnTwoIndexMatrix<vComplex> vTIMatrix;
 | 
				
			||||||
 | 
					  typedef iSUnTwoIndexMatrix<vComplexF> vTIMatrixF;
 | 
				
			||||||
 | 
					  typedef iSUnTwoIndexMatrix<vComplexD> vTIMatrixD;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  typedef Lattice<vTIMatrix> LatticeTwoIndexMatrix;
 | 
				
			||||||
 | 
					  typedef Lattice<vTIMatrixF> LatticeTwoIndexMatrixF;
 | 
				
			||||||
 | 
					  typedef Lattice<vTIMatrixD> LatticeTwoIndexMatrixD;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  typedef Lattice<iVector<iScalar<iMatrix<vComplex, Dimension> >, Nd> >
 | 
				
			||||||
 | 
					      LatticeTwoIndexField;
 | 
				
			||||||
 | 
					  typedef Lattice<iVector<iScalar<iMatrix<vComplexF, Dimension> >, Nd> >
 | 
				
			||||||
 | 
					      LatticeTwoIndexFieldF;
 | 
				
			||||||
 | 
					  typedef Lattice<iVector<iScalar<iMatrix<vComplexD, Dimension> >, Nd> >
 | 
				
			||||||
 | 
					      LatticeTwoIndexFieldD;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  template <typename vtype>
 | 
				
			||||||
 | 
					  using iSUnMatrix = iScalar<iScalar<iMatrix<vtype, ncolour> > >;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  typedef iSUnMatrix<Complex> Matrix;
 | 
				
			||||||
 | 
					  typedef iSUnMatrix<ComplexF> MatrixF;
 | 
				
			||||||
 | 
					  typedef iSUnMatrix<ComplexD> MatrixD;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  template <class cplx>
 | 
				
			||||||
 | 
					  static void base(int Index, iSUnMatrix<cplx> &eij) {
 | 
				
			||||||
 | 
					    // returns (e)^(ij)_{kl} necessary for change of base U_F -> U_R
 | 
				
			||||||
 | 
					    assert(Index < NumGenerators);
 | 
				
			||||||
 | 
					    eij = zero;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // for the linearisation of the 2 indexes 
 | 
				
			||||||
 | 
					    static int a[ncolour * (ncolour - 1) / 2][2]; // store the a <-> i,j
 | 
				
			||||||
 | 
					    static bool filled = false;
 | 
				
			||||||
 | 
					    if (!filled) {
 | 
				
			||||||
 | 
					      int counter = 0;
 | 
				
			||||||
 | 
					      for (int i = 1; i < ncolour; i++) {
 | 
				
			||||||
 | 
					        for (int j = 0; j < i; j++) {
 | 
				
			||||||
 | 
					          a[counter][0] = i;
 | 
				
			||||||
 | 
					          a[counter][1] = j;
 | 
				
			||||||
 | 
					          counter++;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					      filled = true;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (Index < ncolour * (ncolour - 1) / 2) {
 | 
				
			||||||
 | 
					      baseOffDiagonal(a[Index][0], a[Index][1], eij);
 | 
				
			||||||
 | 
					    } else {
 | 
				
			||||||
 | 
					      baseDiagonal(Index, eij);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  template <class cplx>
 | 
				
			||||||
 | 
					  static void baseDiagonal(int Index, iSUnMatrix<cplx> &eij) {
 | 
				
			||||||
 | 
					    eij = zero;
 | 
				
			||||||
 | 
					    eij()()(Index - ncolour * (ncolour - 1) / 2,
 | 
				
			||||||
 | 
					            Index - ncolour * (ncolour - 1) / 2) = 1.0;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  template <class cplx>
 | 
				
			||||||
 | 
					  static void baseOffDiagonal(int i, int j, iSUnMatrix<cplx> &eij) {
 | 
				
			||||||
 | 
					    eij = zero;
 | 
				
			||||||
 | 
					    for (int k = 0; k < ncolour; k++)
 | 
				
			||||||
 | 
					      for (int l = 0; l < ncolour; l++)
 | 
				
			||||||
 | 
					        eij()()(l, k) = delta(i, k) * delta(j, l) +
 | 
				
			||||||
 | 
					                        S * delta(j, k) * delta(i, l);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    RealD nrm = 1. / std::sqrt(2.0);
 | 
				
			||||||
 | 
					    eij = eij * nrm;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  static void printBase(void) {
 | 
				
			||||||
 | 
					    for (int gen = 0; gen < Dimension; gen++) {
 | 
				
			||||||
 | 
					      Matrix tmp;
 | 
				
			||||||
 | 
					      base(gen, tmp);
 | 
				
			||||||
 | 
					      std::cout << GridLogMessage << "Nc = " << ncolour << " t_" << gen
 | 
				
			||||||
 | 
					                << std::endl;
 | 
				
			||||||
 | 
					      std::cout << GridLogMessage << tmp << std::endl;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  template <class cplx>
 | 
				
			||||||
 | 
					  static void generator(int Index, iSUnTwoIndexMatrix<cplx> &i2indTa) {
 | 
				
			||||||
 | 
					    Vector<typename SU<ncolour>::template iSUnMatrix<cplx> > ta(
 | 
				
			||||||
 | 
					        ncolour * ncolour - 1);
 | 
				
			||||||
 | 
					    Vector<typename SU<ncolour>::template iSUnMatrix<cplx> > eij(Dimension);
 | 
				
			||||||
 | 
					    typename SU<ncolour>::template iSUnMatrix<cplx> tmp;
 | 
				
			||||||
 | 
					    i2indTa = zero;
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    for (int a = 0; a < ncolour * ncolour - 1; a++)
 | 
				
			||||||
 | 
					      SU<ncolour>::generator(a, ta[a]);
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    for (int a = 0; a < Dimension; a++) base(a, eij[a]);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    for (int a = 0; a < Dimension; a++) {
 | 
				
			||||||
 | 
					      tmp = transpose(ta[Index]) * adj(eij[a]) + adj(eij[a]) * ta[Index];
 | 
				
			||||||
 | 
					      for (int b = 0; b < Dimension; b++) {
 | 
				
			||||||
 | 
					        typename SU<ncolour>::template iSUnMatrix<cplx> tmp1 =
 | 
				
			||||||
 | 
					            tmp * eij[b]; 
 | 
				
			||||||
 | 
					        Complex iTr = TensorRemove(timesI(trace(tmp1)));
 | 
				
			||||||
 | 
					        i2indTa()()(a, b) = iTr;
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  static void printGenerators(void) {
 | 
				
			||||||
 | 
					    for (int gen = 0; gen < ncolour * ncolour - 1; gen++) {
 | 
				
			||||||
 | 
					      TIMatrix i2indTa;
 | 
				
			||||||
 | 
					      generator(gen, i2indTa);
 | 
				
			||||||
 | 
					      std::cout << GridLogMessage << "Nc = " << ncolour << " t_" << gen
 | 
				
			||||||
 | 
					                << std::endl;
 | 
				
			||||||
 | 
					      std::cout << GridLogMessage << i2indTa << std::endl;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  static void testGenerators(void) {
 | 
				
			||||||
 | 
					    TIMatrix i2indTa, i2indTb;
 | 
				
			||||||
 | 
					    std::cout << GridLogMessage << "2IndexRep - Checking if traceless"
 | 
				
			||||||
 | 
					              << std::endl;
 | 
				
			||||||
 | 
					    for (int a = 0; a < ncolour * ncolour - 1; a++) {
 | 
				
			||||||
 | 
					      generator(a, i2indTa);
 | 
				
			||||||
 | 
					      std::cout << GridLogMessage << a << std::endl;
 | 
				
			||||||
 | 
					      assert(norm2(trace(i2indTa)) < 1.0e-6);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    std::cout << GridLogMessage << std::endl;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    std::cout << GridLogMessage << "2IndexRep - Checking if antihermitean"
 | 
				
			||||||
 | 
					              << std::endl;
 | 
				
			||||||
 | 
					    for (int a = 0; a < ncolour * ncolour - 1; a++) {
 | 
				
			||||||
 | 
					      generator(a, i2indTa);
 | 
				
			||||||
 | 
					      std::cout << GridLogMessage << a << std::endl;
 | 
				
			||||||
 | 
					      assert(norm2(adj(i2indTa) + i2indTa) < 1.0e-6);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    std::cout << GridLogMessage << std::endl;
 | 
				
			||||||
 | 
					    std::cout << GridLogMessage
 | 
				
			||||||
 | 
					              << "2IndexRep - Checking Tr[Ta*Tb]=delta(a,b)*(N +- 2)/2"
 | 
				
			||||||
 | 
					              << std::endl;
 | 
				
			||||||
 | 
					    for (int a = 0; a < ncolour * ncolour - 1; a++) {
 | 
				
			||||||
 | 
					      for (int b = 0; b < ncolour * ncolour - 1; b++) {
 | 
				
			||||||
 | 
					        generator(a, i2indTa);
 | 
				
			||||||
 | 
					        generator(b, i2indTb);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        // generator returns iTa, so we need a minus sign here
 | 
				
			||||||
 | 
					        Complex Tr = -TensorRemove(trace(i2indTa * i2indTb));
 | 
				
			||||||
 | 
					        std::cout << GridLogMessage << "a=" << a << "b=" << b << "Tr=" << Tr
 | 
				
			||||||
 | 
					                  << std::endl;
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    std::cout << GridLogMessage << std::endl;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  static void TwoIndexLieAlgebraMatrix(
 | 
				
			||||||
 | 
					      const typename SU<ncolour>::LatticeAlgebraVector &h,
 | 
				
			||||||
 | 
					      LatticeTwoIndexMatrix &out, Real scale = 1.0) {
 | 
				
			||||||
 | 
					    conformable(h, out);
 | 
				
			||||||
 | 
					    GridBase *grid = out._grid;
 | 
				
			||||||
 | 
					    LatticeTwoIndexMatrix la(grid);
 | 
				
			||||||
 | 
					    TIMatrix i2indTa;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    out = zero;
 | 
				
			||||||
 | 
					    for (int a = 0; a < ncolour * ncolour - 1; a++) {
 | 
				
			||||||
 | 
					      generator(a, i2indTa);
 | 
				
			||||||
 | 
					      la = peekColour(h, a) * i2indTa;
 | 
				
			||||||
 | 
					      out += la;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    out *= scale;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // Projects the algebra components 
 | 
				
			||||||
 | 
					  // of a lattice matrix ( of dimension ncol*ncol -1 )
 | 
				
			||||||
 | 
					  static void projectOnAlgebra(
 | 
				
			||||||
 | 
					      typename SU<ncolour>::LatticeAlgebraVector &h_out,
 | 
				
			||||||
 | 
					      const LatticeTwoIndexMatrix &in, Real scale = 1.0) {
 | 
				
			||||||
 | 
					    conformable(h_out, in);
 | 
				
			||||||
 | 
					    h_out = zero;
 | 
				
			||||||
 | 
					    TIMatrix i2indTa;
 | 
				
			||||||
 | 
					    Real coefficient = -2.0 / (ncolour + 2 * S) * scale;
 | 
				
			||||||
 | 
					    // 2/(Nc +/- 2) for the normalization of the trace in the two index rep
 | 
				
			||||||
 | 
					    for (int a = 0; a < ncolour * ncolour - 1; a++) {
 | 
				
			||||||
 | 
					      generator(a, i2indTa);
 | 
				
			||||||
 | 
					      auto tmp = real(trace(i2indTa * in)) * coefficient;
 | 
				
			||||||
 | 
					      pokeColour(h_out, tmp, a);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // a projector that keeps the generators stored to avoid the overhead of
 | 
				
			||||||
 | 
					  // recomputing them
 | 
				
			||||||
 | 
					  static void projector(typename SU<ncolour>::LatticeAlgebraVector &h_out,
 | 
				
			||||||
 | 
					                        const LatticeTwoIndexMatrix &in, Real scale = 1.0) {
 | 
				
			||||||
 | 
					    conformable(h_out, in);
 | 
				
			||||||
 | 
					    // to store the generators
 | 
				
			||||||
 | 
					    static std::vector<TIMatrix> i2indTa(ncolour * ncolour -1); 
 | 
				
			||||||
 | 
					    h_out = zero;
 | 
				
			||||||
 | 
					    static bool precalculated = false;
 | 
				
			||||||
 | 
					    if (!precalculated) {
 | 
				
			||||||
 | 
					      precalculated = true;
 | 
				
			||||||
 | 
					      for (int a = 0; a < ncolour * ncolour - 1; a++) generator(a, i2indTa[a]);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    Real coefficient =
 | 
				
			||||||
 | 
					        -2.0 / (ncolour + 2 * S) * scale;  // 2/(Nc +/- 2) for the normalization
 | 
				
			||||||
 | 
					                                           // of the trace in the two index rep
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    for (int a = 0; a < ncolour * ncolour - 1; a++) {
 | 
				
			||||||
 | 
					      auto tmp = real(trace(i2indTa[a] * in)) * coefficient;
 | 
				
			||||||
 | 
					      pokeColour(h_out, tmp, a);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Some useful type names
 | 
				
			||||||
 | 
					typedef SU_TwoIndex<Nc, Symmetric> TwoIndexSymmMatrices;
 | 
				
			||||||
 | 
					typedef SU_TwoIndex<Nc, AntiSymmetric> TwoIndexAntiSymmMatrices;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					typedef SU_TwoIndex<2, Symmetric> SU2TwoIndexSymm;
 | 
				
			||||||
 | 
					typedef SU_TwoIndex<3, Symmetric> SU3TwoIndexSymm;
 | 
				
			||||||
 | 
					typedef SU_TwoIndex<4, Symmetric> SU4TwoIndexSymm;
 | 
				
			||||||
 | 
					typedef SU_TwoIndex<5, Symmetric> SU5TwoIndexSymm;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					typedef SU_TwoIndex<2, AntiSymmetric> SU2TwoIndexAntiSymm;
 | 
				
			||||||
 | 
					typedef SU_TwoIndex<3, AntiSymmetric> SU3TwoIndexAntiSymm;
 | 
				
			||||||
 | 
					typedef SU_TwoIndex<4, AntiSymmetric> SU4TwoIndexAntiSymm;
 | 
				
			||||||
 | 
					typedef SU_TwoIndex<5, AntiSymmetric> SU5TwoIndexAntiSymm;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
@@ -1,300 +1,421 @@
 | 
				
			|||||||
    /*************************************************************************************
 | 
					/*******************************************************************************
 | 
				
			||||||
 
 | 
					 
 | 
				
			||||||
    Grid physics library, www.github.com/paboyle/Grid 
 | 
					 Grid physics library, www.github.com/paboyle/Grid
 | 
				
			||||||
 
 | 
					 
 | 
				
			||||||
    Source file: ./lib/simd/Grid_qpx.h
 | 
					 Source file: ./lib/simd/Grid_qpx.h
 | 
				
			||||||
 
 | 
					 
 | 
				
			||||||
    Copyright (C) 2015
 | 
					 Copyright (C) 2016
 | 
				
			||||||
 
 | 
					 
 | 
				
			||||||
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
 | 
					 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
 | 
					 it under the terms of the GNU General Public License as published by
 | 
				
			||||||
    the Free Software Foundation; either version 2 of the License, or
 | 
					 the Free Software Foundation; either version 2 of the License, or
 | 
				
			||||||
    (at your option) any later version.
 | 
					 (at your option) any later version.
 | 
				
			||||||
 
 | 
					 
 | 
				
			||||||
    This program is distributed in the hope that it will be useful,
 | 
					 This program is distributed in the hope that it will be useful,
 | 
				
			||||||
    but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
					 but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
				
			||||||
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
					 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
				
			||||||
    GNU General Public License for more details.
 | 
					 GNU General Public License for more details.
 | 
				
			||||||
 
 | 
					 
 | 
				
			||||||
    You should have received a copy of the GNU General Public License along
 | 
					 You should have received a copy of the GNU General Public License along
 | 
				
			||||||
    with this program; if not, write to the Free Software Foundation, Inc.,
 | 
					 with this program; if not, write to the Free Software Foundation, Inc.,
 | 
				
			||||||
    51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 | 
					 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 | 
				
			||||||
 
 | 
					 
 | 
				
			||||||
    See the full license in the file "LICENSE" in the top level distribution directory
 | 
					 See the full license in the file "LICENSE" in the top level distribution directory
 | 
				
			||||||
    *************************************************************************************/
 | 
					 ******************************************************************************/
 | 
				
			||||||
    /*  END LEGAL */
 | 
					 | 
				
			||||||
//----------------------------------------------------------------------
 | 
					 | 
				
			||||||
/*! @file Grid_qpx.h
 | 
					 | 
				
			||||||
  @brief Optimization libraries for QPX instructions set for BG/Q
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  Using intrinsics
 | 
					 | 
				
			||||||
*/
 | 
					 | 
				
			||||||
// Time-stamp: <2015-05-27 11:30:21 neo>
 | 
					 | 
				
			||||||
//----------------------------------------------------------------------
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// lot of undefined functions
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace Grid {
 | 
				
			||||||
namespace Optimization {
 | 
					namespace Optimization {
 | 
				
			||||||
 | 
					  typedef struct 
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					    float v0,v1,v2,v3;
 | 
				
			||||||
 | 
					  } vector4float;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  inline std::ostream & operator<<(std::ostream& stream, const vector4double a)
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					    stream << "{"<<vec_extract(a,0)<<","<<vec_extract(a,1)<<","<<vec_extract(a,2)<<","<<vec_extract(a,3)<<"}";
 | 
				
			||||||
 | 
					    return stream;
 | 
				
			||||||
 | 
					  };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  inline std::ostream & operator<<(std::ostream& stream, const vector4float a)
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					    stream << "{"<< a.v0 <<","<< a.v1 <<","<< a.v2 <<","<< a.v3 <<"}";
 | 
				
			||||||
 | 
					    return stream;
 | 
				
			||||||
 | 
					  };
 | 
				
			||||||
  
 | 
					  
 | 
				
			||||||
  struct Vsplat{
 | 
					  struct Vsplat{
 | 
				
			||||||
    //Complex float
 | 
					    //Complex float
 | 
				
			||||||
    inline float operator()(float a, float b){
 | 
					    inline vector4float operator()(float a, float b){
 | 
				
			||||||
      return {a,b,a,b};
 | 
					      return (vector4float){a, b, a, b};
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    // Real float
 | 
					    // Real float
 | 
				
			||||||
    inline float operator()(float a){
 | 
					    inline vector4float operator()(float a){
 | 
				
			||||||
      return {a,a,a,a};
 | 
					      return (vector4float){a, a, a, a};
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    //Complex double
 | 
					    //Complex double
 | 
				
			||||||
    inline vector4double operator()(double a, double b){
 | 
					    inline vector4double operator()(double a, double b){
 | 
				
			||||||
      return {a,b,a,b};
 | 
					      return (vector4double){a, b, a, b};
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    //Real double
 | 
					    //Real double
 | 
				
			||||||
    inline vector4double operator()(double a){
 | 
					    inline vector4double operator()(double a){
 | 
				
			||||||
      return {a,a,a,a};
 | 
					      return (vector4double){a, a, a, a};
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    //Integer
 | 
					    //Integer
 | 
				
			||||||
    inline int operator()(Integer a){
 | 
					    inline int operator()(Integer a){
 | 
				
			||||||
#error
 | 
					      return a;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
  };
 | 
					  };
 | 
				
			||||||
  
 | 
					  
 | 
				
			||||||
  struct Vstore{
 | 
					  struct Vstore{
 | 
				
			||||||
    //Float
 | 
					    //Float
 | 
				
			||||||
    inline void operator()(float a, float* F){
 | 
					    inline void operator()(vector4double a, float *f){
 | 
				
			||||||
      assert(0);
 | 
					      vec_st(a, 0, f);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    inline void operator()(vector4double a, vector4float &f){
 | 
				
			||||||
 | 
					      vec_st(a, 0, (float *)(&f));
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    inline void operator()(vector4float a, float *f){
 | 
				
			||||||
 | 
					      f[0] = a.v0;
 | 
				
			||||||
 | 
					      f[1] = a.v1;
 | 
				
			||||||
 | 
					      f[2] = a.v2;
 | 
				
			||||||
 | 
					      f[3] = a.v3;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    //Double
 | 
					    //Double
 | 
				
			||||||
    inline void operator()(vector4double a, double* D){
 | 
					    inline void operator()(vector4double a, double *d){
 | 
				
			||||||
      assert(0);
 | 
					      vec_st(a, 0, d);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    //Integer
 | 
					    //Integer
 | 
				
			||||||
    inline void operator()(int a, Integer* I){
 | 
					    inline void operator()(int a, Integer *i){
 | 
				
			||||||
      assert(0);
 | 
					      i[0] = a;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					 | 
				
			||||||
  };
 | 
					  };
 | 
				
			||||||
  
 | 
					  
 | 
				
			||||||
 | 
					 | 
				
			||||||
  struct Vstream{
 | 
					  struct Vstream{
 | 
				
			||||||
    //Float
 | 
					    //Float
 | 
				
			||||||
    inline void operator()(float * a, float b){
 | 
					    inline void operator()(float *f, vector4double a){
 | 
				
			||||||
      assert(0);
 | 
					      vec_st(a, 0, f);
 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    //Double
 | 
					 | 
				
			||||||
    inline void operator()(double * a, vector4double b){
 | 
					 | 
				
			||||||
      assert(0);
 | 
					 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    inline void operator()(vector4float f, vector4double a){
 | 
				
			||||||
 | 
					      vec_st(a, 0, (float *)(&f));
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    inline void operator()(float *f, vector4float a){
 | 
				
			||||||
 | 
					      f[0] = a.v0;
 | 
				
			||||||
 | 
					      f[1] = a.v1;
 | 
				
			||||||
 | 
					      f[2] = a.v2;
 | 
				
			||||||
 | 
					      f[3] = a.v3;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    //Double
 | 
				
			||||||
 | 
					    inline void operator()(double *d, vector4double a){
 | 
				
			||||||
 | 
					      vec_st(a, 0, d);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  };
 | 
					  };
 | 
				
			||||||
  
 | 
					  
 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  struct Vset{
 | 
					  struct Vset{
 | 
				
			||||||
    // Complex float
 | 
					    // Complex float
 | 
				
			||||||
    inline float operator()(Grid::ComplexF *a){
 | 
					    inline vector4float operator()(Grid::ComplexF *a){
 | 
				
			||||||
      return {a[0].real(),a[0].imag(),a[1].real(),a[1].imag(),a[2].real(),a[2].imag(),a[3].real(),a[3].imag()};
 | 
					      return (vector4float){a[0].real(), a[0].imag(), a[1].real(), a[1].imag()};
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    // Complex double
 | 
					    // Complex double
 | 
				
			||||||
    inline vector4double operator()(Grid::ComplexD *a){
 | 
					    inline vector4double operator()(Grid::ComplexD *a){
 | 
				
			||||||
      return {a[0].real(),a[0].imag(),a[1].real(),a[1].imag(),a[2].real(),a[2].imag(),a[3].real(),a[3].imag()};
 | 
					      return vec_ld(0, (double *)a);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // Real float
 | 
					    // Real float
 | 
				
			||||||
    inline float operator()(float *a){
 | 
					    inline vector4float operator()(float *a){
 | 
				
			||||||
      return {a[0],a[1],a[2],a[3],a[4],a[5],a[6],a[7]};
 | 
					      return (vector4float){a[0], a[1], a[2], a[3]};
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    inline vector4double operator()(vector4float a){
 | 
				
			||||||
 | 
					      return vec_ld(0, (float *)(&a));
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // Real double
 | 
					    // Real double
 | 
				
			||||||
    inline vector4double operator()(double *a){
 | 
					    inline vector4double operator()(double *a){
 | 
				
			||||||
      return {a[0],a[1],a[2],a[3],a[4],a[5],a[6],a[7]};
 | 
					      return vec_ld(0, a);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    // Integer
 | 
					    // Integer
 | 
				
			||||||
    inline int operator()(Integer *a){
 | 
					    inline int operator()(Integer *a){
 | 
				
			||||||
#error
 | 
					      return a[0];
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    
 | 
					    
 | 
				
			||||||
    
 | 
					    
 | 
				
			||||||
  };
 | 
					  };
 | 
				
			||||||
  
 | 
					  
 | 
				
			||||||
  template <typename Out_type, typename In_type>
 | 
					  template <typename Out_type, typename In_type>
 | 
				
			||||||
    struct Reduce{
 | 
					  struct Reduce{
 | 
				
			||||||
      //Need templated class to overload output type
 | 
					    //Need templated class to overload output type
 | 
				
			||||||
      //General form must generate error if compiled
 | 
					    //General form must generate error if compiled
 | 
				
			||||||
      inline Out_type operator()(In_type in){
 | 
					    inline Out_type operator()(In_type in){
 | 
				
			||||||
	printf("Error, using wrong Reduce function\n");
 | 
					      printf("Error, using wrong Reduce function\n");
 | 
				
			||||||
	exit(1);
 | 
					      exit(1);
 | 
				
			||||||
	return 0;
 | 
					      return 0;
 | 
				
			||||||
      }
 | 
					    }
 | 
				
			||||||
    };
 | 
					  };
 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 
 | 
					 | 
				
			||||||
  
 | 
					  
 | 
				
			||||||
  /////////////////////////////////////////////////////
 | 
					  /////////////////////////////////////////////////////
 | 
				
			||||||
  // Arithmetic operations
 | 
					  // Arithmetic operations
 | 
				
			||||||
  /////////////////////////////////////////////////////
 | 
					  /////////////////////////////////////////////////////
 | 
				
			||||||
 | 
					  #define FLOAT_WRAP_2(fn, pref)\
 | 
				
			||||||
 | 
					  pref vector4float fn(vector4float a, vector4float b)\
 | 
				
			||||||
 | 
					  {\
 | 
				
			||||||
 | 
					    vector4double ad, bd, rd;\
 | 
				
			||||||
 | 
					    vector4float  r;\
 | 
				
			||||||
 | 
					    \
 | 
				
			||||||
 | 
					    ad = Vset()(a);\
 | 
				
			||||||
 | 
					    bd = Vset()(b);\
 | 
				
			||||||
 | 
					    rd = fn(ad, bd);\
 | 
				
			||||||
 | 
					    Vstore()(rd, r);\
 | 
				
			||||||
 | 
					    \
 | 
				
			||||||
 | 
					    return r;\
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  #define FLOAT_WRAP_1(fn, pref)\
 | 
				
			||||||
 | 
					  pref vector4float fn(vector4float a)\
 | 
				
			||||||
 | 
					  {\
 | 
				
			||||||
 | 
					    vector4double ad, rd;\
 | 
				
			||||||
 | 
					    vector4float  r;\
 | 
				
			||||||
 | 
					    \
 | 
				
			||||||
 | 
					    ad = Vset()(a);\
 | 
				
			||||||
 | 
					    rd = fn(ad);\
 | 
				
			||||||
 | 
					    Vstore()(rd, r);\
 | 
				
			||||||
 | 
					    \
 | 
				
			||||||
 | 
					    return r;\
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  struct Sum{
 | 
					  struct Sum{
 | 
				
			||||||
    //Complex/Real float
 | 
					 | 
				
			||||||
    inline float operator()(float a, float b){
 | 
					 | 
				
			||||||
#error
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    //Complex/Real double
 | 
					    //Complex/Real double
 | 
				
			||||||
    inline vector4double operator()(vector4double a, vector4double b){
 | 
					    inline vector4double operator()(vector4double a, vector4double b){
 | 
				
			||||||
      return vec_add(a,b);
 | 
					      return vec_add(a, b);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    //Complex/Real float
 | 
				
			||||||
 | 
					    FLOAT_WRAP_2(operator(), inline)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    //Integer
 | 
					    //Integer
 | 
				
			||||||
    inline int operator()(int a, int b){
 | 
					    inline int operator()(int a, int b){
 | 
				
			||||||
#error
 | 
					      return a + b;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
  };
 | 
					  };
 | 
				
			||||||
  
 | 
					  
 | 
				
			||||||
  struct Sub{
 | 
					  struct Sub{
 | 
				
			||||||
    //Complex/Real float
 | 
					 | 
				
			||||||
    inline float operator()(float a, float b){
 | 
					 | 
				
			||||||
#error
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    //Complex/Real double
 | 
					    //Complex/Real double
 | 
				
			||||||
    inline vector4double operator()(vector4double a, vector4double b){
 | 
					    inline vector4double operator()(vector4double a, vector4double b){
 | 
				
			||||||
#error
 | 
					      return vec_sub(a, b);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    //Complex/Real float
 | 
				
			||||||
 | 
					    FLOAT_WRAP_2(operator(), inline)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    //Integer
 | 
					    //Integer
 | 
				
			||||||
    inline floati operator()(int a, int b){
 | 
					    inline int operator()(int a, int b){
 | 
				
			||||||
#error
 | 
					      return a - b;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
  };
 | 
					  };
 | 
				
			||||||
  
 | 
					  
 | 
				
			||||||
 | 
					 | 
				
			||||||
  struct MultComplex{
 | 
					  struct MultComplex{
 | 
				
			||||||
    // Complex float
 | 
					 | 
				
			||||||
    inline float operator()(float a, float b){
 | 
					 | 
				
			||||||
#error
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    // Complex double
 | 
					    // Complex double
 | 
				
			||||||
    inline vector4double operator()(vector4double a, vector4double b){
 | 
					    inline vector4double operator()(vector4double a, vector4double b){
 | 
				
			||||||
#error
 | 
					      return vec_xxnpmadd(a, b, vec_xmul(b, a));
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // Complex float
 | 
				
			||||||
 | 
					    FLOAT_WRAP_2(operator(), inline)
 | 
				
			||||||
  };
 | 
					  };
 | 
				
			||||||
  
 | 
					  
 | 
				
			||||||
  struct Mult{
 | 
					  struct Mult{
 | 
				
			||||||
    // Real float
 | 
					 | 
				
			||||||
    inline float operator()(float a, float b){
 | 
					 | 
				
			||||||
#error
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    // Real double
 | 
					    // Real double
 | 
				
			||||||
    inline vector4double operator()(vector4double a, vector4double b){
 | 
					    inline vector4double operator()(vector4double a, vector4double b){
 | 
				
			||||||
#error
 | 
					      return vec_mul(a, b);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // Real float
 | 
				
			||||||
 | 
					    FLOAT_WRAP_2(operator(), inline)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // Integer
 | 
					    // Integer
 | 
				
			||||||
    inline int operator()(int a, int b){
 | 
					    inline int operator()(int a, int b){
 | 
				
			||||||
#error
 | 
					      return a*b;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
  };
 | 
					  };
 | 
				
			||||||
  
 | 
					  
 | 
				
			||||||
 | 
					 | 
				
			||||||
  struct Conj{
 | 
					  struct Conj{
 | 
				
			||||||
    // Complex single
 | 
					 | 
				
			||||||
    inline float operator()(float in){
 | 
					 | 
				
			||||||
      assert(0);
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    // Complex double
 | 
					    // Complex double
 | 
				
			||||||
    inline vector4double operator()(vector4double in){
 | 
					    inline vector4double operator()(vector4double v){
 | 
				
			||||||
      assert(0);
 | 
					      return vec_mul(v, (vector4double){1., -1., 1., -1.});
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    // do not define for integer input
 | 
					
 | 
				
			||||||
 | 
					    // Complex float
 | 
				
			||||||
 | 
					    FLOAT_WRAP_1(operator(), inline)
 | 
				
			||||||
  };
 | 
					  };
 | 
				
			||||||
  
 | 
					  
 | 
				
			||||||
  struct TimesMinusI{
 | 
					  struct TimesMinusI{
 | 
				
			||||||
    //Complex single
 | 
					 | 
				
			||||||
    inline float operator()(float in, float ret){
 | 
					 | 
				
			||||||
      assert(0);
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    //Complex double
 | 
					    //Complex double
 | 
				
			||||||
    inline vector4double operator()(vector4double in, vector4double ret){
 | 
					    inline vector4double operator()(vector4double v, vector4double ret){
 | 
				
			||||||
      assert(0);
 | 
					      return vec_xxcpnmadd(v, (vector4double){1., 1., 1., 1.},
 | 
				
			||||||
 | 
					                               (vector4double){0., 0., 0., 0.});
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // Complex float
 | 
				
			||||||
 | 
					    FLOAT_WRAP_2(operator(), inline)
 | 
				
			||||||
  };
 | 
					  };
 | 
				
			||||||
  
 | 
					  
 | 
				
			||||||
  struct TimesI{
 | 
					  struct TimesI{
 | 
				
			||||||
    //Complex single
 | 
					 | 
				
			||||||
    inline float operator()(float in, float ret){
 | 
					 | 
				
			||||||
  
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    //Complex double
 | 
					    //Complex double
 | 
				
			||||||
    inline vector4double operator()(vector4double in, vector4double ret){
 | 
					    inline vector4double operator()(vector4double v, vector4double ret){
 | 
				
			||||||
  
 | 
					      return vec_xxcpnmadd(v, (vector4double){-1., -1., -1., -1.},
 | 
				
			||||||
 | 
					                              (vector4double){0., 0., 0., 0.});
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // Complex float
 | 
				
			||||||
 | 
					    FLOAT_WRAP_2(operator(), inline)
 | 
				
			||||||
  };
 | 
					  };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  struct Permute{
 | 
				
			||||||
 | 
					    //Complex double
 | 
				
			||||||
 | 
					    static inline vector4double Permute0(vector4double v){ //0123 -> 2301
 | 
				
			||||||
 | 
					      return vec_perm(v, v, vec_gpci(02301));
 | 
				
			||||||
 | 
					    };
 | 
				
			||||||
 | 
					    static inline vector4double Permute1(vector4double v){ //0123 -> 1032
 | 
				
			||||||
 | 
					      return vec_perm(v, v, vec_gpci(01032));
 | 
				
			||||||
 | 
					    };
 | 
				
			||||||
 | 
					    static inline vector4double Permute2(vector4double v){
 | 
				
			||||||
 | 
					      return v;
 | 
				
			||||||
 | 
					    };
 | 
				
			||||||
 | 
					    static inline vector4double Permute3(vector4double v){
 | 
				
			||||||
 | 
					      return v;
 | 
				
			||||||
 | 
					    };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // Complex float
 | 
				
			||||||
 | 
					    FLOAT_WRAP_1(Permute0, static inline)
 | 
				
			||||||
 | 
					    FLOAT_WRAP_1(Permute1, static inline)
 | 
				
			||||||
 | 
					    FLOAT_WRAP_1(Permute2, static inline)
 | 
				
			||||||
 | 
					    FLOAT_WRAP_1(Permute3, static inline)
 | 
				
			||||||
 | 
					  };
 | 
				
			||||||
  
 | 
					  
 | 
				
			||||||
 | 
					  struct Rotate{
 | 
				
			||||||
 | 
					    static inline vector4double rotate(vector4double v, int n){
 | 
				
			||||||
 | 
					      switch(n){
 | 
				
			||||||
 | 
					        case 0:
 | 
				
			||||||
 | 
					          return v;
 | 
				
			||||||
 | 
					          break;
 | 
				
			||||||
 | 
					        case 1:
 | 
				
			||||||
 | 
					          return vec_perm(v, v, vec_gpci(01230));
 | 
				
			||||||
 | 
					          break;
 | 
				
			||||||
 | 
					        case 2:
 | 
				
			||||||
 | 
					          return vec_perm(v, v, vec_gpci(02301));
 | 
				
			||||||
 | 
					          break;
 | 
				
			||||||
 | 
					        case 3:
 | 
				
			||||||
 | 
					          return vec_perm(v, v, vec_gpci(03012));
 | 
				
			||||||
 | 
					          break;
 | 
				
			||||||
 | 
					        default: assert(0);
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    static inline vector4float rotate(vector4float v, int n){
 | 
				
			||||||
 | 
					      vector4double vd, rd;
 | 
				
			||||||
 | 
					      vector4float  r;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  //////////////////////////////////////////////
 | 
					      vd = Vset()(v);
 | 
				
			||||||
  // Some Template specialization
 | 
					      rd = rotate(vd, n);
 | 
				
			||||||
 | 
					      Vstore()(rd, r);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      return r;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  };
 | 
				
			||||||
  
 | 
					  
 | 
				
			||||||
  //Complex float Reduce
 | 
					  //Complex float Reduce
 | 
				
			||||||
  template<>
 | 
					  template<>
 | 
				
			||||||
    inline Grid::ComplexF Reduce<Grid::ComplexF, float>::operator()(float in){
 | 
					  inline Grid::ComplexF
 | 
				
			||||||
    assert(0);
 | 
					  Reduce<Grid::ComplexF, vector4float>::operator()(vector4float v) { //2 complex
 | 
				
			||||||
 | 
					    vector4float v1,v2;
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    v1 = Optimization::Permute::Permute0(v);
 | 
				
			||||||
 | 
					    v1 = Optimization::Sum()(v1, v);
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    return Grid::ComplexF(v1.v0, v1.v1);
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
  //Real float Reduce
 | 
					  //Real float Reduce
 | 
				
			||||||
  template<>
 | 
					  template<>
 | 
				
			||||||
    inline Grid::RealF Reduce<Grid::RealF, float>::operator()(float in){
 | 
					  inline Grid::RealF
 | 
				
			||||||
    assert(0);
 | 
					  Reduce<Grid::RealF, vector4float>::operator()(vector4float v){ //4 floats
 | 
				
			||||||
 | 
					    vector4float v1,v2;
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    v1 = Optimization::Permute::Permute0(v);
 | 
				
			||||||
 | 
					    v1 = Optimization::Sum()(v1, v);
 | 
				
			||||||
 | 
					    v2 = Optimization::Permute::Permute1(v1);
 | 
				
			||||||
 | 
					    v1 = Optimization::Sum()(v1, v2);
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    return v1.v0;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
  
 | 
					  
 | 
				
			||||||
  
 | 
					  
 | 
				
			||||||
  //Complex double Reduce
 | 
					  //Complex double Reduce
 | 
				
			||||||
  template<>
 | 
					  template<>
 | 
				
			||||||
    inline Grid::ComplexD Reduce<Grid::ComplexD, vector4double>::operator()(vector4double in){
 | 
					  inline Grid::ComplexD
 | 
				
			||||||
    assert(0);
 | 
					  Reduce<Grid::ComplexD, vector4double>::operator()(vector4double v){ //2 complex
 | 
				
			||||||
 | 
					    vector4double v1;
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    v1 = Optimization::Permute::Permute0(v);
 | 
				
			||||||
 | 
					    v1 = vec_add(v1, v);
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    return Grid::ComplexD(vec_extract(v1, 0), vec_extract(v1, 1));
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
  
 | 
					  
 | 
				
			||||||
  //Real double Reduce
 | 
					  //Real double Reduce
 | 
				
			||||||
  template<>
 | 
					  template<>
 | 
				
			||||||
    inline Grid::RealD Reduce<Grid::RealD, vector4double>::operator()(vector4double in){
 | 
					  inline Grid::RealD
 | 
				
			||||||
    assert(0);
 | 
					  Reduce<Grid::RealD, vector4double>::operator()(vector4double v){ //4 doubles
 | 
				
			||||||
 | 
					    vector4double v1,v2;
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    v1 = Optimization::Permute::Permute0(v);
 | 
				
			||||||
 | 
					    v1 = vec_add(v1, v);
 | 
				
			||||||
 | 
					    v2 = Optimization::Permute::Permute1(v1);
 | 
				
			||||||
 | 
					    v1 = vec_add(v1, v2);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return vec_extract(v1, 0);
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
  
 | 
					  
 | 
				
			||||||
  //Integer Reduce
 | 
					  //Integer Reduce
 | 
				
			||||||
  template<>
 | 
					  template<>
 | 
				
			||||||
    inline Integer Reduce<Integer, floati>::operator()(float in){
 | 
					  inline Integer Reduce<Integer, int>::operator()(int in){
 | 
				
			||||||
 | 
					    // FIXME unimplemented
 | 
				
			||||||
 | 
					    printf("Reduce : Missing integer implementation -> FIX\n");
 | 
				
			||||||
    assert(0);
 | 
					    assert(0);
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
  
 | 
					 | 
				
			||||||
  
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
//////////////////////////////////////////////////////////////////////////////////////
 | 
					////////////////////////////////////////////////////////////////////////////////
 | 
				
			||||||
// Here assign types
 | 
					// Here assign types
 | 
				
			||||||
namespace Grid {
 | 
					typedef Optimization::vector4float SIMD_Ftype;  // Single precision type
 | 
				
			||||||
  typedef float SIMD_Ftype  __attribute__ ((vector_size (16)));         // Single precision type
 | 
					typedef vector4double              SIMD_Dtype; // Double precision type
 | 
				
			||||||
  typedef vector4double SIMD_Dtype; // Double precision type
 | 
					typedef int                        SIMD_Itype; // Integer type
 | 
				
			||||||
  typedef int SIMD_Itype;           // Integer type
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
  inline void v_prefetch0(int size, const char *ptr){};
 | 
					// prefetch utilities
 | 
				
			||||||
 | 
					inline void v_prefetch0(int size, const char *ptr){};
 | 
				
			||||||
  // Function name aliases
 | 
					inline void prefetch_HINT_T0(const char *ptr){};
 | 
				
			||||||
  typedef Optimization::Vsplat   VsplatSIMD;
 | 
					 | 
				
			||||||
  typedef Optimization::Vstore   VstoreSIMD;
 | 
					 | 
				
			||||||
  typedef Optimization::Vset     VsetSIMD;
 | 
					 | 
				
			||||||
  typedef Optimization::Vstream  VstreamSIMD;
 | 
					 | 
				
			||||||
  template <typename S, typename T> using ReduceSIMD = Optimization::Reduce<S,T>;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  // Arithmetic operations
 | 
					// Function name aliases
 | 
				
			||||||
  typedef Optimization::Sum         SumSIMD;
 | 
					typedef Optimization::Vsplat   VsplatSIMD;
 | 
				
			||||||
  typedef Optimization::Sub         SubSIMD;
 | 
					typedef Optimization::Vstore   VstoreSIMD;
 | 
				
			||||||
  typedef Optimization::Mult        MultSIMD;
 | 
					typedef Optimization::Vset     VsetSIMD;
 | 
				
			||||||
  typedef Optimization::MultComplex MultComplexSIMD;
 | 
					typedef Optimization::Vstream  VstreamSIMD;
 | 
				
			||||||
  typedef Optimization::Conj        ConjSIMD;
 | 
					template <typename S, typename T> using ReduceSIMD = Optimization::Reduce<S,T>;
 | 
				
			||||||
  typedef Optimization::TimesMinusI TimesMinusISIMD;
 | 
					
 | 
				
			||||||
  typedef Optimization::TimesI      TimesISIMD;
 | 
					// Arithmetic operations
 | 
				
			||||||
 | 
					typedef Optimization::Sum         SumSIMD;
 | 
				
			||||||
 | 
					typedef Optimization::Sub         SubSIMD;
 | 
				
			||||||
 | 
					typedef Optimization::Mult        MultSIMD;
 | 
				
			||||||
 | 
					typedef Optimization::MultComplex MultComplexSIMD;
 | 
				
			||||||
 | 
					typedef Optimization::Conj        ConjSIMD;
 | 
				
			||||||
 | 
					typedef Optimization::TimesMinusI TimesMinusISIMD;
 | 
				
			||||||
 | 
					typedef Optimization::TimesI      TimesISIMD;
 | 
				
			||||||
  
 | 
					  
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -388,6 +388,12 @@ class Grid_simd {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
};  // end of Grid_simd class definition
 | 
					};  // end of Grid_simd class definition
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					inline void permute(ComplexD &y,ComplexD b, int perm) {  y=b; }
 | 
				
			||||||
 | 
					inline void permute(ComplexF &y,ComplexF b, int perm) {  y=b; }
 | 
				
			||||||
 | 
					inline void permute(RealD &y,RealD b, int perm) {  y=b; }
 | 
				
			||||||
 | 
					inline void permute(RealF &y,RealF b, int perm) {  y=b; }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
////////////////////////////////////////////////////////////////////
 | 
					////////////////////////////////////////////////////////////////////
 | 
				
			||||||
// General rotate
 | 
					// General rotate
 | 
				
			||||||
////////////////////////////////////////////////////////////////////
 | 
					////////////////////////////////////////////////////////////////////
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -67,15 +67,13 @@ template <class scalar>
 | 
				
			|||||||
struct AsinRealFunctor {
 | 
					struct AsinRealFunctor {
 | 
				
			||||||
  scalar operator()(const scalar &a) const { return asin(real(a)); }
 | 
					  scalar operator()(const scalar &a) const { return asin(real(a)); }
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					 | 
				
			||||||
template <class scalar>
 | 
					template <class scalar>
 | 
				
			||||||
struct LogRealFunctor {
 | 
					struct LogRealFunctor {
 | 
				
			||||||
  scalar operator()(const scalar &a) const { return log(real(a)); }
 | 
					  scalar operator()(const scalar &a) const { return log(real(a)); }
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					 | 
				
			||||||
template <class scalar>
 | 
					template <class scalar>
 | 
				
			||||||
struct ExpRealFunctor {
 | 
					struct ExpFunctor {
 | 
				
			||||||
  scalar operator()(const scalar &a) const { return exp(real(a)); }
 | 
					  scalar operator()(const scalar &a) const { return exp(a); }
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
template <class scalar>
 | 
					template <class scalar>
 | 
				
			||||||
struct NotFunctor {
 | 
					struct NotFunctor {
 | 
				
			||||||
@@ -85,7 +83,6 @@ template <class scalar>
 | 
				
			|||||||
struct AbsRealFunctor {
 | 
					struct AbsRealFunctor {
 | 
				
			||||||
  scalar operator()(const scalar &a) const { return std::abs(real(a)); }
 | 
					  scalar operator()(const scalar &a) const { return std::abs(real(a)); }
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					 | 
				
			||||||
template <class scalar>
 | 
					template <class scalar>
 | 
				
			||||||
struct PowRealFunctor {
 | 
					struct PowRealFunctor {
 | 
				
			||||||
  double y;
 | 
					  double y;
 | 
				
			||||||
@@ -135,7 +132,6 @@ template <class Scalar>
 | 
				
			|||||||
inline Scalar rsqrt(const Scalar &r) {
 | 
					inline Scalar rsqrt(const Scalar &r) {
 | 
				
			||||||
  return (RSqrtRealFunctor<Scalar>(), r);
 | 
					  return (RSqrtRealFunctor<Scalar>(), r);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					 | 
				
			||||||
template <class S, class V>
 | 
					template <class S, class V>
 | 
				
			||||||
inline Grid_simd<S, V> cos(const Grid_simd<S, V> &r) {
 | 
					inline Grid_simd<S, V> cos(const Grid_simd<S, V> &r) {
 | 
				
			||||||
  return SimdApply(CosRealFunctor<S>(), r);
 | 
					  return SimdApply(CosRealFunctor<S>(), r);
 | 
				
			||||||
@@ -162,7 +158,7 @@ inline Grid_simd<S, V> abs(const Grid_simd<S, V> &r) {
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
template <class S, class V>
 | 
					template <class S, class V>
 | 
				
			||||||
inline Grid_simd<S, V> exp(const Grid_simd<S, V> &r) {
 | 
					inline Grid_simd<S, V> exp(const Grid_simd<S, V> &r) {
 | 
				
			||||||
  return SimdApply(ExpRealFunctor<S>(), r);
 | 
					  return SimdApply(ExpFunctor<S>(), r);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
template <class S, class V>
 | 
					template <class S, class V>
 | 
				
			||||||
inline Grid_simd<S, V> Not(const Grid_simd<S, V> &r) {
 | 
					inline Grid_simd<S, V> Not(const Grid_simd<S, V> &r) {
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -56,7 +56,7 @@ namespace Grid {
 | 
				
			|||||||
	temp = unit + temp*arg;
 | 
						temp = unit + temp*arg;
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
      
 | 
					      
 | 
				
			||||||
      return ProjectOnGroup(temp);//maybe not strictly necessary
 | 
					      return temp;
 | 
				
			||||||
      
 | 
					      
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										
											BIN
										
									
								
								prerequisites/fftw-3.3.4.tar.gz
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								prerequisites/fftw-3.3.4.tar.gz
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							@@ -13,21 +13,22 @@ echo CCFILES=$CCFILES >> Make.inc
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
# tests Make.inc
 | 
					# tests Make.inc
 | 
				
			||||||
cd $home/tests
 | 
					cd $home/tests
 | 
				
			||||||
dirs=`find . -type d `
 | 
					dirs=`find . -type d -not -path '*/\.*'`
 | 
				
			||||||
for subdir in $dirs; do
 | 
					for subdir in $dirs; do
 | 
				
			||||||
	cd $home/tests/$subdir
 | 
					    cd $home/tests/$subdir
 | 
				
			||||||
	TESTS=`ls T*.cc`
 | 
					    pwd
 | 
				
			||||||
	TESTLIST=`echo ${TESTS} | sed s/.cc//g `
 | 
					    TESTS=`ls T*.cc`
 | 
				
			||||||
	PREF=`[ $subdir = '.' ] && echo noinst || echo EXTRA`
 | 
					    TESTLIST=`echo ${TESTS} | sed s/.cc//g `
 | 
				
			||||||
	echo "tests: ${TESTLIST}" > Make.inc
 | 
					    PREF=`[ $subdir = '.' ] && echo noinst || echo EXTRA`
 | 
				
			||||||
	echo ${PREF}_PROGRAMS = ${TESTLIST} >> Make.inc
 | 
					    echo "tests: ${TESTLIST}" > Make.inc
 | 
				
			||||||
 | 
					    echo ${PREF}_PROGRAMS = ${TESTLIST} >> Make.inc
 | 
				
			||||||
 | 
					    echo >> Make.inc
 | 
				
			||||||
 | 
					    for f in $TESTS; do
 | 
				
			||||||
 | 
						BNAME=`basename $f .cc`
 | 
				
			||||||
 | 
						echo ${BNAME}_SOURCES=$f  >> Make.inc
 | 
				
			||||||
 | 
						echo ${BNAME}_LDADD=-lGrid>> Make.inc
 | 
				
			||||||
	echo >> Make.inc
 | 
						echo >> Make.inc
 | 
				
			||||||
	for f in $TESTS; do
 | 
					    done
 | 
				
			||||||
		BNAME=`basename $f .cc`
 | 
					 | 
				
			||||||
		echo ${BNAME}_SOURCES=$f  >> Make.inc
 | 
					 | 
				
			||||||
		echo ${BNAME}_LDADD=-lGrid>> Make.inc
 | 
					 | 
				
			||||||
		echo >> Make.inc
 | 
					 | 
				
			||||||
	done
 | 
					 | 
				
			||||||
done
 | 
					done
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# benchmarks Make.inc
 | 
					# benchmarks Make.inc
 | 
				
			||||||
@@ -38,10 +39,10 @@ TESTLIST=`echo ${TESTS} | sed s/.cc//g `
 | 
				
			|||||||
echo bin_PROGRAMS = ${TESTLIST} > Make.inc
 | 
					echo bin_PROGRAMS = ${TESTLIST} > Make.inc
 | 
				
			||||||
echo >> Make.inc
 | 
					echo >> Make.inc
 | 
				
			||||||
for f in $TESTS; do
 | 
					for f in $TESTS; do
 | 
				
			||||||
	BNAME=`basename $f .cc`
 | 
					    BNAME=`basename $f .cc`
 | 
				
			||||||
	echo ${BNAME}_SOURCES=$f  >> Make.inc
 | 
					    echo ${BNAME}_SOURCES=$f  >> Make.inc
 | 
				
			||||||
	echo ${BNAME}_LDADD=-lGrid>> Make.inc
 | 
					    echo ${BNAME}_LDADD=-lGrid>> Make.inc
 | 
				
			||||||
	echo >> Make.inc
 | 
					    echo >> Make.inc
 | 
				
			||||||
done
 | 
					done
 | 
				
			||||||
 | 
					
 | 
				
			||||||
cd ..
 | 
					cd ..
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										4
									
								
								scripts/reconfigure_script
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										4
									
								
								scripts/reconfigure_script
									
									
									
									
									
										Executable file
									
								
							@@ -0,0 +1,4 @@
 | 
				
			|||||||
 | 
					aclocal -I m4
 | 
				
			||||||
 | 
					autoheader -f
 | 
				
			||||||
 | 
					automake -f --add-missing
 | 
				
			||||||
 | 
					autoconf -f
 | 
				
			||||||
							
								
								
									
										18
									
								
								scripts/update_fftw.sh
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										18
									
								
								scripts/update_fftw.sh
									
									
									
									
									
										Executable file
									
								
							@@ -0,0 +1,18 @@
 | 
				
			|||||||
 | 
					#!/usr/bin/env bash
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					if (( $# != 1 )); then
 | 
				
			||||||
 | 
					    echo "usage: `basename $0` <archive>" 1>&2
 | 
				
			||||||
 | 
					    exit 1
 | 
				
			||||||
 | 
					fi
 | 
				
			||||||
 | 
					ARC=$1
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					INITDIR=`pwd`
 | 
				
			||||||
 | 
					rm -rf lib/fftw
 | 
				
			||||||
 | 
					mkdir lib/fftw
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					ARCDIR=`tar -tf ${ARC} | head -n1 | sed -e 's@/.*@@'`
 | 
				
			||||||
 | 
					tar -xf ${ARC}
 | 
				
			||||||
 | 
					cp ${ARCDIR}/api/fftw3.h lib/fftw/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					cd ${INITDIR}
 | 
				
			||||||
 | 
					rm -rf ${ARCDIR}
 | 
				
			||||||
@@ -157,10 +157,9 @@ void Tester(const functor &func)
 | 
				
			|||||||
  std::cout << GridLogMessage << " " << func.name() << std::endl;
 | 
					  std::cout << GridLogMessage << " " << func.name() << std::endl;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  std::cout << GridLogDebug << v_input1 << std::endl;
 | 
					  std::cout << GridLogDebug << v_input1 << std::endl;
 | 
				
			||||||
 | 
					  std::cout << GridLogDebug << v_input2 << std::endl;
 | 
				
			||||||
  std::cout << GridLogDebug << v_result << std::endl;
 | 
					  std::cout << GridLogDebug << v_result << std::endl;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  int ok=0;
 | 
					  int ok=0;
 | 
				
			||||||
  for(int i=0;i<Nsimd;i++){
 | 
					  for(int i=0;i<Nsimd;i++){
 | 
				
			||||||
    if ( abs(reference[i]-result[i])>1.0e-7){
 | 
					    if ( abs(reference[i]-result[i])>1.0e-7){
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										111
									
								
								tests/core/Test_fft.cc
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										111
									
								
								tests/core/Test_fft.cc
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,111 @@
 | 
				
			|||||||
 | 
					    /*************************************************************************************
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    Grid physics library, www.github.com/paboyle/Grid 
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    Source file: ./tests/Test_cshift.cc
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    Copyright (C) 2015
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Author: Azusa Yamaguchi <ayamaguc@staffmail.ed.ac.uk>
 | 
				
			||||||
 | 
					Author: Peter Boyle <paboyle@ph.ed.ac.uk>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    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
 | 
				
			||||||
 | 
					    the Free Software Foundation; either version 2 of the License, or
 | 
				
			||||||
 | 
					    (at your option) any later version.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    This program is distributed in the hope that it will be useful,
 | 
				
			||||||
 | 
					    but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
				
			||||||
 | 
					    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
				
			||||||
 | 
					    GNU General Public License for more details.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    You should have received a copy of the GNU General Public License along
 | 
				
			||||||
 | 
					    with this program; if not, write to the Free Software Foundation, Inc.,
 | 
				
			||||||
 | 
					    51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    See the full license in the file "LICENSE" in the top level distribution directory
 | 
				
			||||||
 | 
					    *************************************************************************************/
 | 
				
			||||||
 | 
					    /*  END LEGAL */
 | 
				
			||||||
 | 
					#include <Grid/Grid.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					using namespace Grid;
 | 
				
			||||||
 | 
					using namespace Grid::QCD;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int main (int argc, char ** argv)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					  Grid_init(&argc,&argv);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  int threads = GridThread::GetThreads();
 | 
				
			||||||
 | 
					  std::cout<<GridLogMessage << "Grid is setup to use "<<threads<<" threads"<<std::endl;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  std::vector<int> latt_size   = GridDefaultLatt();
 | 
				
			||||||
 | 
					  std::vector<int> simd_layout( { vComplexD::Nsimd(),1,1,1});
 | 
				
			||||||
 | 
					  std::vector<int> mpi_layout  = GridDefaultMpi();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  int vol = 1;
 | 
				
			||||||
 | 
					  for(int d=0;d<latt_size.size();d++){
 | 
				
			||||||
 | 
					    vol = vol * latt_size[d];
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  GridCartesian        Fine(latt_size,simd_layout,mpi_layout);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  LatticeComplexD     one(&Fine);
 | 
				
			||||||
 | 
					  LatticeComplexD      zz(&Fine);
 | 
				
			||||||
 | 
					  LatticeComplexD       C(&Fine);
 | 
				
			||||||
 | 
					  LatticeComplexD  Ctilde(&Fine);
 | 
				
			||||||
 | 
					  LatticeComplexD    coor(&Fine);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  LatticeSpinMatrixD    S(&Fine);
 | 
				
			||||||
 | 
					  LatticeSpinMatrixD    Stilde(&Fine);
 | 
				
			||||||
 | 
					  
 | 
				
			||||||
 | 
					  std::vector<int> p({1,2,3,2});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  one = ComplexD(1.0,0.0);
 | 
				
			||||||
 | 
					  zz  = ComplexD(0.0,0.0);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  ComplexD ci(0.0,1.0);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  C=zero;
 | 
				
			||||||
 | 
					  for(int mu=0;mu<4;mu++){
 | 
				
			||||||
 | 
					    RealD TwoPiL =  M_PI * 2.0/ latt_size[mu];
 | 
				
			||||||
 | 
					    LatticeCoordinate(coor,mu);
 | 
				
			||||||
 | 
					    C = C - (TwoPiL * p[mu]) * coor;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  C = exp(C*ci);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  S=zero;
 | 
				
			||||||
 | 
					  S = S+C;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  FFT theFFT(&Fine);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  theFFT.FFT_dim(Ctilde,C,0,FFT::forward);  C=Ctilde; std::cout << theFFT.MFlops()<<std::endl;
 | 
				
			||||||
 | 
					  theFFT.FFT_dim(Ctilde,C,1,FFT::forward);  C=Ctilde; std::cout << theFFT.MFlops()<<std::endl;
 | 
				
			||||||
 | 
					  theFFT.FFT_dim(Ctilde,C,2,FFT::forward);  C=Ctilde; std::cout << theFFT.MFlops()<<std::endl;
 | 
				
			||||||
 | 
					  theFFT.FFT_dim(Ctilde,C,3,FFT::forward);  std::cout << theFFT.MFlops()<<std::endl;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  //  C=zero;
 | 
				
			||||||
 | 
					  //  Ctilde = where(abs(Ctilde)<1.0e-10,C,Ctilde);
 | 
				
			||||||
 | 
					  TComplexD cVol;
 | 
				
			||||||
 | 
					  cVol()()() = vol;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  C=zero;
 | 
				
			||||||
 | 
					  pokeSite(cVol,C,p);
 | 
				
			||||||
 | 
					  C=C-Ctilde;
 | 
				
			||||||
 | 
					  std::cout << "diff scalar "<<norm2(C) << std::endl;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  theFFT.FFT_dim(Stilde,S,0,FFT::forward);  S=Stilde; std::cout << theFFT.MFlops()<<std::endl;
 | 
				
			||||||
 | 
					  theFFT.FFT_dim(Stilde,S,1,FFT::forward);  S=Stilde;std::cout << theFFT.MFlops()<<std::endl;
 | 
				
			||||||
 | 
					  theFFT.FFT_dim(Stilde,S,2,FFT::forward);  S=Stilde;std::cout << theFFT.MFlops()<<std::endl;
 | 
				
			||||||
 | 
					  theFFT.FFT_dim(Stilde,S,3,FFT::forward);std::cout << theFFT.MFlops()<<std::endl;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  SpinMatrixD Sp; 
 | 
				
			||||||
 | 
					  Sp = zero; Sp = Sp+cVol;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  S=zero;
 | 
				
			||||||
 | 
					  pokeSite(Sp,S,p);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  S= S-Stilde;
 | 
				
			||||||
 | 
					  std::cout << "diff FT[SpinMat] "<<norm2(S) << std::endl;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  Grid_finalize();
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										111
									
								
								tests/core/Test_fftf.cc
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										111
									
								
								tests/core/Test_fftf.cc
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,111 @@
 | 
				
			|||||||
 | 
					    /*************************************************************************************
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    Grid physics library, www.github.com/paboyle/Grid 
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    Source file: ./tests/Test_cshift.cc
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    Copyright (C) 2015
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Author: Azusa Yamaguchi <ayamaguc@staffmail.ed.ac.uk>
 | 
				
			||||||
 | 
					Author: Peter Boyle <paboyle@ph.ed.ac.uk>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    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
 | 
				
			||||||
 | 
					    the Free Software Foundation; either version 2 of the License, or
 | 
				
			||||||
 | 
					    (at your option) any later version.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    This program is distributed in the hope that it will be useful,
 | 
				
			||||||
 | 
					    but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
				
			||||||
 | 
					    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
				
			||||||
 | 
					    GNU General Public License for more details.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    You should have received a copy of the GNU General Public License along
 | 
				
			||||||
 | 
					    with this program; if not, write to the Free Software Foundation, Inc.,
 | 
				
			||||||
 | 
					    51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    See the full license in the file "LICENSE" in the top level distribution directory
 | 
				
			||||||
 | 
					    *************************************************************************************/
 | 
				
			||||||
 | 
					    /*  END LEGAL */
 | 
				
			||||||
 | 
					#include <Grid/Grid.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					using namespace Grid;
 | 
				
			||||||
 | 
					using namespace Grid::QCD;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int main (int argc, char ** argv)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					  Grid_init(&argc,&argv);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  int threads = GridThread::GetThreads();
 | 
				
			||||||
 | 
					  std::cout<<GridLogMessage << "Grid is setup to use "<<threads<<" threads"<<std::endl;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  std::vector<int> latt_size   = GridDefaultLatt();
 | 
				
			||||||
 | 
					  std::vector<int> simd_layout( { vComplexF::Nsimd(),1,1,1});
 | 
				
			||||||
 | 
					  std::vector<int> mpi_layout  = GridDefaultMpi();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  int vol = 1;
 | 
				
			||||||
 | 
					  for(int d=0;d<latt_size.size();d++){
 | 
				
			||||||
 | 
					    vol = vol * latt_size[d];
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  GridCartesian        Fine(latt_size,simd_layout,mpi_layout);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  LatticeComplexF     one(&Fine);
 | 
				
			||||||
 | 
					  LatticeComplexF      zz(&Fine);
 | 
				
			||||||
 | 
					  LatticeComplexF       C(&Fine);
 | 
				
			||||||
 | 
					  LatticeComplexF  Ctilde(&Fine);
 | 
				
			||||||
 | 
					  LatticeComplexF    coor(&Fine);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  LatticeSpinMatrixF    S(&Fine);
 | 
				
			||||||
 | 
					  LatticeSpinMatrixF    Stilde(&Fine);
 | 
				
			||||||
 | 
					  
 | 
				
			||||||
 | 
					  std::vector<int> p({1,2,3,2});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  one = ComplexF(1.0,0.0);
 | 
				
			||||||
 | 
					  zz  = ComplexF(0.0,0.0);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  ComplexF ci(0.0,1.0);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  C=zero;
 | 
				
			||||||
 | 
					  for(int mu=0;mu<4;mu++){
 | 
				
			||||||
 | 
					    RealD TwoPiL =  M_PI * 2.0/ latt_size[mu];
 | 
				
			||||||
 | 
					    LatticeCoordinate(coor,mu);
 | 
				
			||||||
 | 
					    C = C - (TwoPiL * p[mu]) * coor;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  C = exp(C*ci);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  S=zero;
 | 
				
			||||||
 | 
					  S = S+C;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  FFT theFFT(&Fine);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  theFFT.FFT_dim(Ctilde,C,0,FFT::forward);  C=Ctilde; std::cout << theFFT.MFlops()<<std::endl;
 | 
				
			||||||
 | 
					  theFFT.FFT_dim(Ctilde,C,1,FFT::forward);  C=Ctilde; std::cout << theFFT.MFlops()<<std::endl;
 | 
				
			||||||
 | 
					  theFFT.FFT_dim(Ctilde,C,2,FFT::forward);  C=Ctilde; std::cout << theFFT.MFlops()<<std::endl;
 | 
				
			||||||
 | 
					  theFFT.FFT_dim(Ctilde,C,3,FFT::forward);  std::cout << theFFT.MFlops()<<std::endl;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  //  C=zero;
 | 
				
			||||||
 | 
					  //  Ctilde = where(abs(Ctilde)<1.0e-10,C,Ctilde);
 | 
				
			||||||
 | 
					  TComplexF cVol;
 | 
				
			||||||
 | 
					  cVol()()() = vol;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  C=zero;
 | 
				
			||||||
 | 
					  pokeSite(cVol,C,p);
 | 
				
			||||||
 | 
					  C=C-Ctilde;
 | 
				
			||||||
 | 
					  std::cout << "diff scalar "<<norm2(C) << std::endl;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  theFFT.FFT_dim(Stilde,S,0,FFT::forward);  S=Stilde; std::cout << theFFT.MFlops()<<std::endl;
 | 
				
			||||||
 | 
					  theFFT.FFT_dim(Stilde,S,1,FFT::forward);  S=Stilde;std::cout << theFFT.MFlops()<<std::endl;
 | 
				
			||||||
 | 
					  theFFT.FFT_dim(Stilde,S,2,FFT::forward);  S=Stilde;std::cout << theFFT.MFlops()<<std::endl;
 | 
				
			||||||
 | 
					  theFFT.FFT_dim(Stilde,S,3,FFT::forward);std::cout << theFFT.MFlops()<<std::endl;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  SpinMatrixF Sp; 
 | 
				
			||||||
 | 
					  Sp = zero; Sp = Sp+cVol;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  S=zero;
 | 
				
			||||||
 | 
					  pokeSite(Sp,S,p);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  S= S-Stilde;
 | 
				
			||||||
 | 
					  std::cout << "diff FT[SpinMat] "<<norm2(S) << std::endl;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  Grid_finalize();
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@@ -1,76 +1,532 @@
 | 
				
			|||||||
    /*************************************************************************************
 | 
					/*************************************************************************************
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    Grid physics library, www.github.com/paboyle/Grid 
 | 
					Grid physics library, www.github.com/paboyle/Grid
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    Source file: ./tests/Test_lie_generators.cc
 | 
					Source file: ./tests/Test_lie_generators.cc
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    Copyright (C) 2015
 | 
					Copyright (C) 2015
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Author: Azusa Yamaguchi <ayamaguc@staffmail.ed.ac.uk>
 | 
					Author: Azusa Yamaguchi <ayamaguc@staffmail.ed.ac.uk>
 | 
				
			||||||
Author: Peter Boyle <paboyle@ph.ed.ac.uk>
 | 
					Author: Peter Boyle <paboyle@ph.ed.ac.uk>
 | 
				
			||||||
 | 
					Author: Guido Cossu <guido.cossu@ed.ac.uk>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    This program is free software; you can redistribute it and/or modify
 | 
					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
 | 
					it under the terms of the GNU General Public License as published by
 | 
				
			||||||
    the Free Software Foundation; either version 2 of the License, or
 | 
					the Free Software Foundation; either version 2 of the License, or
 | 
				
			||||||
    (at your option) any later version.
 | 
					(at your option) any later version.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    This program is distributed in the hope that it will be useful,
 | 
					This program is distributed in the hope that it will be useful,
 | 
				
			||||||
    but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
					but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
				
			||||||
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
					MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
				
			||||||
    GNU General Public License for more details.
 | 
					GNU General Public License for more details.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    You should have received a copy of the GNU General Public License along
 | 
					You should have received a copy of the GNU General Public License along
 | 
				
			||||||
    with this program; if not, write to the Free Software Foundation, Inc.,
 | 
					with this program; if not, write to the Free Software Foundation, Inc.,
 | 
				
			||||||
    51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 | 
					51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    See the full license in the file "LICENSE" in the top level distribution directory
 | 
					See the full license in the file "LICENSE" in the top level distribution
 | 
				
			||||||
    *************************************************************************************/
 | 
					directory
 | 
				
			||||||
    /*  END LEGAL */
 | 
					*************************************************************************************/
 | 
				
			||||||
 | 
					/*  END LEGAL */
 | 
				
			||||||
#include <Grid/Grid.h>
 | 
					#include <Grid/Grid.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <Grid/qcd/utils/CovariantCshift.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <Grid/qcd/utils/SUn.h>
 | 
				
			||||||
 | 
					#include <Grid/qcd/utils/SUnAdjoint.h>
 | 
				
			||||||
 | 
					#include <Grid/qcd/utils/SUnTwoIndex.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <Grid/qcd/representations/adjoint.h>
 | 
				
			||||||
 | 
					#include <Grid/qcd/representations/two_index.h>
 | 
				
			||||||
 | 
					#include <Grid/qcd/utils/WilsonLoops.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
using namespace std;
 | 
					using namespace std;
 | 
				
			||||||
using namespace Grid;
 | 
					using namespace Grid;
 | 
				
			||||||
using namespace Grid::QCD;
 | 
					using namespace Grid::QCD;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int main(int argc, char** argv) {
 | 
				
			||||||
 | 
					  Grid_init(&argc, &argv);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
int main (int argc, char ** argv)
 | 
					  std::vector<int> latt({4, 4, 4, 8});
 | 
				
			||||||
{
 | 
					  GridCartesian* grid = SpaceTimeGrid::makeFourDimGrid(
 | 
				
			||||||
  Grid_init(&argc,&argv);
 | 
					      latt, GridDefaultSimd(Nd, vComplex::Nsimd()), GridDefaultMpi());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  std::vector<int> latt({4,4,4,8});
 | 
					  GridRedBlackCartesian* rbGrid = SpaceTimeGrid::makeFourDimRedBlackGrid(grid);
 | 
				
			||||||
  GridCartesian * grid = SpaceTimeGrid::makeFourDimGrid(latt, 
 | 
					 | 
				
			||||||
							GridDefaultSimd(Nd,vComplex::Nsimd()),
 | 
					 | 
				
			||||||
							GridDefaultMpi());
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
  GridRedBlackCartesian * rbGrid = SpaceTimeGrid::makeFourDimRedBlackGrid(grid);
 | 
					  std::cout << GridLogMessage << "*********************************************"
 | 
				
			||||||
 | 
					            << std::endl;
 | 
				
			||||||
  std::cout<<GridLogMessage<<"*********************************************"<<std::endl;
 | 
					  std::cout << GridLogMessage << "* Generators for SU(2)" << std::endl;
 | 
				
			||||||
  std::cout<<GridLogMessage<<"* Generators for SU(2)"<<std::endl;
 | 
					  std::cout << GridLogMessage << "*********************************************"
 | 
				
			||||||
  std::cout<<GridLogMessage<<"*********************************************"<<std::endl;
 | 
					            << std::endl;
 | 
				
			||||||
  SU2::printGenerators();
 | 
					  SU2::printGenerators();
 | 
				
			||||||
 | 
					  std::cout << "Dimension of adjoint representation: "<< SU2Adjoint::Dimension << std::endl;
 | 
				
			||||||
 | 
					  SU2Adjoint::printGenerators();
 | 
				
			||||||
  SU2::testGenerators();
 | 
					  SU2::testGenerators();
 | 
				
			||||||
 | 
					  SU2Adjoint::testGenerators();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  std::cout<<GridLogMessage<<"*********************************************"<<std::endl;
 | 
					  std::cout << GridLogMessage << "*********************************************"
 | 
				
			||||||
  std::cout<<GridLogMessage<<"* Generators for SU(3)"<<std::endl;
 | 
					            << std::endl;
 | 
				
			||||||
  std::cout<<GridLogMessage<<"*********************************************"<<std::endl;
 | 
					  std::cout << GridLogMessage << "* Generators for SU(3)" << std::endl;
 | 
				
			||||||
 | 
					  std::cout << GridLogMessage << "*********************************************"
 | 
				
			||||||
 | 
					            << std::endl;
 | 
				
			||||||
  SU3::printGenerators();
 | 
					  SU3::printGenerators();
 | 
				
			||||||
 | 
					  std::cout << "Dimension of adjoint representation: "<< SU3Adjoint::Dimension << std::endl;
 | 
				
			||||||
 | 
					  SU3Adjoint::printGenerators();
 | 
				
			||||||
  SU3::testGenerators();
 | 
					  SU3::testGenerators();
 | 
				
			||||||
 | 
					  SU3Adjoint::testGenerators();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  std::cout<<GridLogMessage<<"*********************************************"<<std::endl;
 | 
				
			||||||
 | 
					  std::cout<<GridLogMessage<<"* Generators for SU(4)"<<std::endl;
 | 
				
			||||||
 | 
					  std::cout<<GridLogMessage<<"*********************************************"<<std::endl;
 | 
				
			||||||
 | 
					  SU4::printGenerators();
 | 
				
			||||||
 | 
					  std::cout << "Dimension of adjoint representation: "<< SU4Adjoint::Dimension << std::endl;
 | 
				
			||||||
 | 
					  SU4Adjoint::printGenerators();
 | 
				
			||||||
 | 
					  SU4::testGenerators();
 | 
				
			||||||
 | 
					  SU4Adjoint::testGenerators();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // Projectors 
 | 
				
			||||||
 | 
					  GridParallelRNG gridRNG(grid);
 | 
				
			||||||
 | 
					  gridRNG.SeedRandomDevice();
 | 
				
			||||||
 | 
					  SU3Adjoint::LatticeAdjMatrix Gauss(grid);
 | 
				
			||||||
 | 
					  SU3::LatticeAlgebraVector ha(grid);
 | 
				
			||||||
 | 
					  SU3::LatticeAlgebraVector hb(grid);
 | 
				
			||||||
 | 
					  random(gridRNG,Gauss);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  std::cout << GridLogMessage << "Start projectOnAlgebra" << std::endl;
 | 
				
			||||||
 | 
					  SU3Adjoint::projectOnAlgebra(ha, Gauss);
 | 
				
			||||||
 | 
					  std::cout << GridLogMessage << "end projectOnAlgebra" << std::endl;
 | 
				
			||||||
 | 
					  std::cout << GridLogMessage << "Start projector" << std::endl;
 | 
				
			||||||
 | 
					  SU3Adjoint::projector(hb, Gauss);
 | 
				
			||||||
 | 
					  std::cout << GridLogMessage << "end projector" << std::endl;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  std::cout << GridLogMessage << "ReStart projector" << std::endl;
 | 
				
			||||||
 | 
					  SU3Adjoint::projector(hb, Gauss);
 | 
				
			||||||
 | 
					  std::cout << GridLogMessage << "end projector" << std::endl;
 | 
				
			||||||
 | 
					  SU3::LatticeAlgebraVector diff = ha -hb;
 | 
				
			||||||
 | 
					  std::cout << GridLogMessage << "Difference: " << norm2(diff) << std::endl;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // Testing HMC representation classes
 | 
				
			||||||
 | 
					  AdjointRep<Nc> AdjRep(grid);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // AdjointRepresentation has the predefined number of colours Nc
 | 
				
			||||||
 | 
					  Representations<FundamentalRepresentation, AdjointRepresentation, TwoIndexSymmetricRepresentation> RepresentationTypes(grid);  
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  
 | 
				
			||||||
 | 
					  LatticeGaugeField U(grid), V(grid);
 | 
				
			||||||
 | 
					  SU<Nc>::HotConfiguration<LatticeGaugeField>(gridRNG, U);
 | 
				
			||||||
 | 
					  SU<Nc>::HotConfiguration<LatticeGaugeField>(gridRNG, V);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // Adjoint representation
 | 
				
			||||||
 | 
					  // Test group structure
 | 
				
			||||||
 | 
					  // (U_f * V_f)_r = U_r * V_r
 | 
				
			||||||
 | 
					  LatticeGaugeField UV(grid);
 | 
				
			||||||
 | 
					  UV = zero;
 | 
				
			||||||
 | 
					  for (int mu = 0; mu < Nd; mu++) {
 | 
				
			||||||
 | 
					    SU<Nc>::LatticeMatrix Umu = peekLorentz(U,mu);
 | 
				
			||||||
 | 
					    SU<Nc>::LatticeMatrix Vmu = peekLorentz(V,mu);
 | 
				
			||||||
 | 
					    pokeLorentz(UV,Umu*Vmu, mu);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  AdjRep.update_representation(UV);
 | 
				
			||||||
 | 
					  typename AdjointRep<Nc>::LatticeField UVr = AdjRep.U;  // (U_f * V_f)_r 
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  AdjRep.update_representation(U);
 | 
				
			||||||
 | 
					  typename AdjointRep<Nc>::LatticeField Ur = AdjRep.U;  // U_r
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  AdjRep.update_representation(V);
 | 
				
			||||||
 | 
					  typename AdjointRep<Nc>::LatticeField Vr = AdjRep.U;  // V_r
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  typename AdjointRep<Nc>::LatticeField UrVr(grid);
 | 
				
			||||||
 | 
					  UrVr = zero;
 | 
				
			||||||
 | 
					  for (int mu = 0; mu < Nd; mu++) {
 | 
				
			||||||
 | 
					    typename AdjointRep<Nc>::LatticeMatrix Urmu = peekLorentz(Ur,mu);
 | 
				
			||||||
 | 
					    typename AdjointRep<Nc>::LatticeMatrix Vrmu = peekLorentz(Vr,mu);
 | 
				
			||||||
 | 
					    pokeLorentz(UrVr,Urmu*Vrmu, mu);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  typename AdjointRep<Nc>::LatticeField Diff_check = UVr - UrVr;
 | 
				
			||||||
 | 
					  std::cout << GridLogMessage << "Group structure SU("<<Nc<<") check difference (Adjoint representation) : " << norm2(Diff_check) << std::endl;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // Check correspondence of algebra and group transformations
 | 
				
			||||||
 | 
					  // Create a random vector
 | 
				
			||||||
 | 
					  SU<Nc>::LatticeAlgebraVector h_adj(grid);
 | 
				
			||||||
 | 
					  typename AdjointRep<Nc>::LatticeMatrix Ar(grid);
 | 
				
			||||||
 | 
					  random(gridRNG,h_adj);
 | 
				
			||||||
 | 
					  h_adj = real(h_adj);
 | 
				
			||||||
 | 
					  SU_Adjoint<Nc>::AdjointLieAlgebraMatrix(h_adj,Ar);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // Re-extract h_adj
 | 
				
			||||||
 | 
					  SU<Nc>::LatticeAlgebraVector h_adj2(grid);
 | 
				
			||||||
 | 
					  SU_Adjoint<Nc>::projectOnAlgebra(h_adj2, Ar);
 | 
				
			||||||
 | 
					  SU<Nc>::LatticeAlgebraVector h_diff = h_adj - h_adj2;
 | 
				
			||||||
 | 
					  std::cout << GridLogMessage << "Projections structure check vector difference (Adjoint representation) : " << norm2(h_diff) << std::endl;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // Exponentiate
 | 
				
			||||||
 | 
					  typename AdjointRep<Nc>::LatticeMatrix Uadj(grid);
 | 
				
			||||||
 | 
					  Uadj  = expMat(Ar, 1.0, 16);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  typename AdjointRep<Nc>::LatticeMatrix uno(grid);
 | 
				
			||||||
 | 
					  uno = 1.0;
 | 
				
			||||||
 | 
					  // Check matrix Uadj, must be real orthogonal
 | 
				
			||||||
 | 
					  typename AdjointRep<Nc>::LatticeMatrix Ucheck = Uadj - conjugate(Uadj);
 | 
				
			||||||
 | 
					  std::cout << GridLogMessage << "Reality check: " << norm2(Ucheck)
 | 
				
			||||||
 | 
					            << std::endl;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  Ucheck = Uadj * adj(Uadj) - uno;
 | 
				
			||||||
 | 
					  std::cout << GridLogMessage << "orthogonality check 1: " << norm2(Ucheck)
 | 
				
			||||||
 | 
					            << std::endl;
 | 
				
			||||||
 | 
					  Ucheck = adj(Uadj) * Uadj - uno;
 | 
				
			||||||
 | 
					  std::cout << GridLogMessage << "orthogonality check 2: " << norm2(Ucheck)
 | 
				
			||||||
 | 
					            << std::endl;
 | 
				
			||||||
 | 
					      
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // Construct the fundamental matrix in the group
 | 
				
			||||||
 | 
					  SU<Nc>::LatticeMatrix Af(grid);
 | 
				
			||||||
 | 
					  SU<Nc>::FundamentalLieAlgebraMatrix(h_adj,Af);
 | 
				
			||||||
 | 
					  SU<Nc>::LatticeMatrix Ufund(grid);
 | 
				
			||||||
 | 
					  Ufund  = expMat(Af, 1.0, 16);
 | 
				
			||||||
 | 
					  // Check unitarity
 | 
				
			||||||
 | 
					  SU<Nc>::LatticeMatrix uno_f(grid);
 | 
				
			||||||
 | 
					  uno_f = 1.0;
 | 
				
			||||||
 | 
					  SU<Nc>::LatticeMatrix UnitCheck(grid);
 | 
				
			||||||
 | 
					  UnitCheck = Ufund * adj(Ufund) - uno_f;
 | 
				
			||||||
 | 
					  std::cout << GridLogMessage << "unitarity check 1: " << norm2(UnitCheck)
 | 
				
			||||||
 | 
					            << std::endl;
 | 
				
			||||||
 | 
					  UnitCheck = adj(Ufund) * Ufund - uno_f;
 | 
				
			||||||
 | 
					  std::cout << GridLogMessage << "unitarity check 2: " << norm2(UnitCheck)
 | 
				
			||||||
 | 
					            << std::endl;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // Tranform to the adjoint representation
 | 
				
			||||||
 | 
					  U = zero; // fill this with only one direction
 | 
				
			||||||
 | 
					  pokeLorentz(U,Ufund,0); // the representation transf acts on full gauge fields
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  AdjRep.update_representation(U);
 | 
				
			||||||
 | 
					  Ur = AdjRep.U;  // U_r  
 | 
				
			||||||
 | 
					  typename AdjointRep<Nc>::LatticeMatrix Ur0 = peekLorentz(Ur,0); // this should be the same as Uadj
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  typename AdjointRep<Nc>::LatticeMatrix Diff_check_mat = Ur0 - Uadj;
 | 
				
			||||||
 | 
					  std::cout << GridLogMessage << "Projections structure check group difference : " << norm2(Diff_check_mat) << std::endl;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // TwoIndexRep tests
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  std::cout << GridLogMessage << "*********************************************"
 | 
				
			||||||
 | 
					            << std::endl;
 | 
				
			||||||
 | 
					  std::cout << GridLogMessage << "*********************************************"
 | 
				
			||||||
 | 
					            << std::endl;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  
 | 
				
			||||||
 | 
					  std::cout << GridLogMessage << "* eS^{ij} base for SU(2)" << std::endl;
 | 
				
			||||||
 | 
					  std::cout << GridLogMessage << "*********************************************"
 | 
				
			||||||
 | 
					            << std::endl;
 | 
				
			||||||
 | 
					  std::cout << GridLogMessage << "Dimension of Two Index Symmetric representation: "<< SU2TwoIndexSymm::Dimension << std::endl;
 | 
				
			||||||
 | 
					  SU2TwoIndexSymm::printBase();
 | 
				
			||||||
 | 
					      std::cout << GridLogMessage << "*********************************************"
 | 
				
			||||||
 | 
					            << std::endl;
 | 
				
			||||||
 | 
					        std::cout << GridLogMessage << "Generators of Two Index Symmetric representation: "<< SU2TwoIndexSymm::Dimension << std::endl;
 | 
				
			||||||
 | 
					  SU2TwoIndexSymm::printGenerators();
 | 
				
			||||||
 | 
					        std::cout << GridLogMessage << "Test of Two Index Symmetric Generators: "<< SU2TwoIndexSymm::Dimension << std::endl;
 | 
				
			||||||
 | 
					  SU2TwoIndexSymm::testGenerators();
 | 
				
			||||||
 | 
					  std::cout << GridLogMessage << "*********************************************"
 | 
				
			||||||
 | 
					            << std::endl;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  
 | 
				
			||||||
 | 
					  std::cout << GridLogMessage << "*********************************************"
 | 
				
			||||||
 | 
					            << std::endl;
 | 
				
			||||||
 | 
					  std::cout << GridLogMessage << "* eAS^{ij} base for SU(2)" << std::endl;
 | 
				
			||||||
 | 
					  
 | 
				
			||||||
 | 
					  std::cout << GridLogMessage << "*********************************************"
 | 
				
			||||||
 | 
					            << std::endl;
 | 
				
			||||||
 | 
					  std::cout << GridLogMessage << "Dimension of Two Index anti-Symmetric representation: "<< SU2TwoIndexAntiSymm::Dimension << std::endl;
 | 
				
			||||||
 | 
					  SU2TwoIndexAntiSymm::printBase();
 | 
				
			||||||
 | 
					      std::cout << GridLogMessage << "*********************************************"
 | 
				
			||||||
 | 
					            << std::endl;
 | 
				
			||||||
 | 
					        std::cout << GridLogMessage << "Dimension of Two Index anti-Symmetric representation: "<< SU2TwoIndexAntiSymm::Dimension << std::endl;
 | 
				
			||||||
 | 
					  SU2TwoIndexAntiSymm::printGenerators();
 | 
				
			||||||
 | 
					  std::cout << GridLogMessage << "Test of Two Index anti-Symmetric Generators: "<< SU2TwoIndexAntiSymm::Dimension << std::endl;
 | 
				
			||||||
 | 
					  SU2TwoIndexAntiSymm::testGenerators();
 | 
				
			||||||
 | 
					  
 | 
				
			||||||
 | 
					  
 | 
				
			||||||
 | 
					  
 | 
				
			||||||
 | 
					  std::cout << GridLogMessage << "*********************************************"
 | 
				
			||||||
 | 
					      << std::endl;
 | 
				
			||||||
 | 
					  std::cout << GridLogMessage << "Test for the Two Index Symmetric projectors"
 | 
				
			||||||
 | 
					      << std::endl;
 | 
				
			||||||
 | 
					  // Projectors 
 | 
				
			||||||
 | 
					  SU3TwoIndexSymm::LatticeTwoIndexMatrix Gauss2(grid);
 | 
				
			||||||
 | 
					  random(gridRNG,Gauss2);
 | 
				
			||||||
 | 
					  
 | 
				
			||||||
 | 
					  std::cout << GridLogMessage << "Start projectOnAlgebra" << std::endl;
 | 
				
			||||||
 | 
					  SU3TwoIndexSymm::projectOnAlgebra(ha, Gauss2);
 | 
				
			||||||
 | 
					  std::cout << GridLogMessage << "end projectOnAlgebra" << std::endl;
 | 
				
			||||||
 | 
					  std::cout << GridLogMessage << "Start projector" << std::endl;
 | 
				
			||||||
 | 
					  SU3TwoIndexSymm::projector(hb, Gauss2);
 | 
				
			||||||
 | 
					  std::cout << GridLogMessage << "end projector" << std::endl;
 | 
				
			||||||
 | 
					  
 | 
				
			||||||
 | 
					  std::cout << GridLogMessage << "ReStart projector" << std::endl;
 | 
				
			||||||
 | 
					  SU3TwoIndexSymm::projector(hb, Gauss2);
 | 
				
			||||||
 | 
					  std::cout << GridLogMessage << "end projector" << std::endl;
 | 
				
			||||||
 | 
					  SU3::LatticeAlgebraVector diff2 = ha - hb;
 | 
				
			||||||
 | 
					  std::cout << GridLogMessage << "Difference: " << norm2(diff) << std::endl;
 | 
				
			||||||
 | 
					  std::cout << GridLogMessage << "*********************************************"
 | 
				
			||||||
 | 
					      << std::endl;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  
 | 
				
			||||||
 | 
					    std::cout << GridLogMessage << "*********************************************"
 | 
				
			||||||
 | 
					      << std::endl;
 | 
				
			||||||
 | 
					  std::cout << GridLogMessage << "Test for the Two index anti-Symmetric projectors"
 | 
				
			||||||
 | 
					      << std::endl;
 | 
				
			||||||
 | 
					  // Projectors
 | 
				
			||||||
 | 
					  SU3TwoIndexAntiSymm::LatticeTwoIndexMatrix Gauss2a(grid);
 | 
				
			||||||
 | 
					  random(gridRNG,Gauss2a);
 | 
				
			||||||
 | 
					  
 | 
				
			||||||
 | 
					  std::cout << GridLogMessage << "Start projectOnAlgebra" << std::endl;
 | 
				
			||||||
 | 
					  SU3TwoIndexAntiSymm::projectOnAlgebra(ha, Gauss2a);
 | 
				
			||||||
 | 
					  std::cout << GridLogMessage << "end projectOnAlgebra" << std::endl;
 | 
				
			||||||
 | 
					  std::cout << GridLogMessage << "Start projector" << std::endl;
 | 
				
			||||||
 | 
					  SU3TwoIndexAntiSymm::projector(hb, Gauss2a);
 | 
				
			||||||
 | 
					  std::cout << GridLogMessage << "end projector" << std::endl;
 | 
				
			||||||
 | 
					  
 | 
				
			||||||
 | 
					  std::cout << GridLogMessage << "ReStart projector" << std::endl;
 | 
				
			||||||
 | 
					  SU3TwoIndexAntiSymm::projector(hb, Gauss2a);
 | 
				
			||||||
 | 
					  std::cout << GridLogMessage << "end projector" << std::endl;
 | 
				
			||||||
 | 
					  SU3::LatticeAlgebraVector diff2a = ha - hb;
 | 
				
			||||||
 | 
					  std::cout << GridLogMessage << "Difference: " << norm2(diff2a) << std::endl;
 | 
				
			||||||
 | 
					  std::cout << GridLogMessage << "*********************************************"
 | 
				
			||||||
 | 
					      << std::endl;
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					  
 | 
				
			||||||
 | 
					  std::cout << GridLogMessage << "Two index Symmetric: Checking Group Structure"
 | 
				
			||||||
 | 
					      << std::endl;
 | 
				
			||||||
 | 
					  // Testing HMC representation classes
 | 
				
			||||||
 | 
					  TwoIndexRep< Nc, Symmetric > TIndexRep(grid);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // Test group structure
 | 
				
			||||||
 | 
					  // (U_f * V_f)_r = U_r * V_r
 | 
				
			||||||
 | 
					  LatticeGaugeField U2(grid), V2(grid);
 | 
				
			||||||
 | 
					  SU<Nc>::HotConfiguration<LatticeGaugeField>(gridRNG, U2);
 | 
				
			||||||
 | 
					  SU<Nc>::HotConfiguration<LatticeGaugeField>(gridRNG, V2);
 | 
				
			||||||
 | 
					  
 | 
				
			||||||
 | 
					  LatticeGaugeField UV2(grid);
 | 
				
			||||||
 | 
					  UV2 = zero;
 | 
				
			||||||
 | 
					  for (int mu = 0; mu < Nd; mu++) {
 | 
				
			||||||
 | 
					    SU<Nc>::LatticeMatrix Umu2 = peekLorentz(U2,mu);
 | 
				
			||||||
 | 
					    SU<Nc>::LatticeMatrix Vmu2 = peekLorentz(V2,mu);
 | 
				
			||||||
 | 
					    pokeLorentz(UV2,Umu2*Vmu2, mu);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  
 | 
				
			||||||
 | 
					  TIndexRep.update_representation(UV2);
 | 
				
			||||||
 | 
					  typename TwoIndexRep< Nc, Symmetric >::LatticeField UVr2 = TIndexRep.U;  // (U_f * V_f)_r
 | 
				
			||||||
 | 
					  
 | 
				
			||||||
 | 
					  TIndexRep.update_representation(U2);
 | 
				
			||||||
 | 
					  typename TwoIndexRep< Nc, Symmetric >::LatticeField Ur2 = TIndexRep.U;  // U_r
 | 
				
			||||||
 | 
					  
 | 
				
			||||||
 | 
					  TIndexRep.update_representation(V2);
 | 
				
			||||||
 | 
					  typename TwoIndexRep< Nc, Symmetric >::LatticeField Vr2 = TIndexRep.U;  // V_r
 | 
				
			||||||
 | 
					  
 | 
				
			||||||
 | 
					  typename TwoIndexRep< Nc, Symmetric >::LatticeField Ur2Vr2(grid);
 | 
				
			||||||
 | 
					  Ur2Vr2 = zero;
 | 
				
			||||||
 | 
					  for (int mu = 0; mu < Nd; mu++) {
 | 
				
			||||||
 | 
					    typename TwoIndexRep< Nc, Symmetric >::LatticeMatrix Urmu2 = peekLorentz(Ur2,mu);
 | 
				
			||||||
 | 
					    typename TwoIndexRep< Nc, Symmetric >::LatticeMatrix Vrmu2 = peekLorentz(Vr2,mu);
 | 
				
			||||||
 | 
					    pokeLorentz(Ur2Vr2,Urmu2*Vrmu2, mu);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  
 | 
				
			||||||
 | 
					  typename TwoIndexRep< Nc, Symmetric >::LatticeField Diff_check2 = UVr2 - Ur2Vr2;
 | 
				
			||||||
 | 
					  std::cout << GridLogMessage << "Group structure SU("<<Nc<<") check difference (Two Index Symmetric): " << norm2(Diff_check2) << std::endl;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  
 | 
				
			||||||
 | 
					  // Check correspondence of algebra and group transformations
 | 
				
			||||||
 | 
					  // Create a random vector
 | 
				
			||||||
 | 
					  SU<Nc>::LatticeAlgebraVector h_sym(grid);
 | 
				
			||||||
 | 
					  typename TwoIndexRep< Nc, Symmetric>::LatticeMatrix Ar_sym(grid);
 | 
				
			||||||
 | 
					  random(gridRNG,h_sym);
 | 
				
			||||||
 | 
					  h_sym = real(h_sym);
 | 
				
			||||||
 | 
					  SU_TwoIndex<Nc,Symmetric>::TwoIndexLieAlgebraMatrix(h_sym,Ar_sym);
 | 
				
			||||||
 | 
					  
 | 
				
			||||||
 | 
					  // Re-extract h_sym
 | 
				
			||||||
 | 
					  SU<Nc>::LatticeAlgebraVector h_sym2(grid);
 | 
				
			||||||
 | 
					  SU_TwoIndex< Nc, Symmetric>::projectOnAlgebra(h_sym2, Ar_sym);
 | 
				
			||||||
 | 
					  SU<Nc>::LatticeAlgebraVector h_diff_sym = h_sym - h_sym2;
 | 
				
			||||||
 | 
					  std::cout << GridLogMessage << "Projections structure check vector difference (Two Index Symmetric): " << norm2(h_diff_sym) << std::endl;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  
 | 
				
			||||||
 | 
					  // Exponentiate
 | 
				
			||||||
 | 
					  typename TwoIndexRep< Nc, Symmetric>::LatticeMatrix U2iS(grid);
 | 
				
			||||||
 | 
					  U2iS  = expMat(Ar_sym, 1.0, 16);
 | 
				
			||||||
 | 
					  
 | 
				
			||||||
 | 
					  typename TwoIndexRep< Nc, Symmetric>::LatticeMatrix uno2iS(grid);
 | 
				
			||||||
 | 
					  uno2iS = 1.0;
 | 
				
			||||||
 | 
					  // Check matrix U2iS, must be real orthogonal
 | 
				
			||||||
 | 
					  typename TwoIndexRep< Nc, Symmetric>::LatticeMatrix Ucheck2iS = U2iS - conjugate(U2iS);
 | 
				
			||||||
 | 
					  std::cout << GridLogMessage << "Reality check: " << norm2(Ucheck2iS)
 | 
				
			||||||
 | 
					      << std::endl;
 | 
				
			||||||
 | 
					  
 | 
				
			||||||
 | 
					  Ucheck2iS = U2iS * adj(U2iS) - uno2iS;
 | 
				
			||||||
 | 
					  std::cout << GridLogMessage << "orthogonality check 1: " << norm2(Ucheck2iS)
 | 
				
			||||||
 | 
					      << std::endl;
 | 
				
			||||||
 | 
					  Ucheck2iS = adj(U2iS) * U2iS - uno2iS;
 | 
				
			||||||
 | 
					  std::cout << GridLogMessage << "orthogonality check 2: " << norm2(Ucheck2iS)
 | 
				
			||||||
 | 
					      << std::endl;
 | 
				
			||||||
 | 
					  
 | 
				
			||||||
 | 
					  
 | 
				
			||||||
 | 
					  
 | 
				
			||||||
 | 
					  // Construct the fundamental matrix in the group
 | 
				
			||||||
 | 
					  SU<Nc>::LatticeMatrix Af_sym(grid);
 | 
				
			||||||
 | 
					  SU<Nc>::FundamentalLieAlgebraMatrix(h_sym,Af_sym);
 | 
				
			||||||
 | 
					  SU<Nc>::LatticeMatrix Ufund2(grid);
 | 
				
			||||||
 | 
					  Ufund2  = expMat(Af_sym, 1.0, 16);
 | 
				
			||||||
 | 
					  SU<Nc>::LatticeMatrix UnitCheck2(grid);
 | 
				
			||||||
 | 
					  UnitCheck2 = Ufund2 * adj(Ufund2) - uno_f;
 | 
				
			||||||
 | 
					  std::cout << GridLogMessage << "unitarity check 1: " << norm2(UnitCheck2)
 | 
				
			||||||
 | 
					      << std::endl;
 | 
				
			||||||
 | 
					  UnitCheck2 = adj(Ufund2) * Ufund2 - uno_f;
 | 
				
			||||||
 | 
					  std::cout << GridLogMessage << "unitarity check 2: " << norm2(UnitCheck2)
 | 
				
			||||||
 | 
					      << std::endl;
 | 
				
			||||||
 | 
					  
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // Tranform to the 2Index Sym representation
 | 
				
			||||||
 | 
					  U = zero; // fill this with only one direction
 | 
				
			||||||
 | 
					  pokeLorentz(U,Ufund2,0); // the representation transf acts on full gauge fields
 | 
				
			||||||
 | 
					  
 | 
				
			||||||
 | 
					  TIndexRep.update_representation(U);
 | 
				
			||||||
 | 
					  Ur2 = TIndexRep.U;  // U_r  
 | 
				
			||||||
 | 
					  typename TwoIndexRep< Nc, Symmetric>::LatticeMatrix Ur02 = peekLorentz(Ur2,0); // this should be the same as U2iS
 | 
				
			||||||
 | 
					  
 | 
				
			||||||
 | 
					  typename TwoIndexRep< Nc, Symmetric>::LatticeMatrix Diff_check_mat2 = Ur02 - U2iS;
 | 
				
			||||||
 | 
					  std::cout << GridLogMessage << "Projections structure check group difference (Two Index Symmetric): " << norm2(Diff_check_mat2) << std::endl;
 | 
				
			||||||
 | 
					  
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  if (TwoIndexRep<Nc, AntiSymmetric >::Dimension != 1){
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  std::cout << GridLogMessage << "*********************************************"
 | 
				
			||||||
 | 
					      << std::endl;
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					  
 | 
				
			||||||
 | 
					  std::cout << GridLogMessage << "Two Index anti-Symmetric: Check Group Structure"
 | 
				
			||||||
 | 
					      << std::endl;
 | 
				
			||||||
 | 
					  // Testing HMC representation classes
 | 
				
			||||||
 | 
					  TwoIndexRep< Nc, AntiSymmetric > TIndexRepA(grid);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // Test group structure
 | 
				
			||||||
 | 
					  // (U_f * V_f)_r = U_r * V_r
 | 
				
			||||||
 | 
					  LatticeGaugeField U2A(grid), V2A(grid);
 | 
				
			||||||
 | 
					  SU<Nc>::HotConfiguration<LatticeGaugeField>(gridRNG, U2A);
 | 
				
			||||||
 | 
					  SU<Nc>::HotConfiguration<LatticeGaugeField>(gridRNG, V2A);
 | 
				
			||||||
 | 
					  
 | 
				
			||||||
 | 
					  LatticeGaugeField UV2A(grid);
 | 
				
			||||||
 | 
					  UV2A = zero;
 | 
				
			||||||
 | 
					  for (int mu = 0; mu < Nd; mu++) {
 | 
				
			||||||
 | 
					    SU<Nc>::LatticeMatrix Umu2A = peekLorentz(U2,mu);
 | 
				
			||||||
 | 
					    SU<Nc>::LatticeMatrix Vmu2A = peekLorentz(V2,mu);
 | 
				
			||||||
 | 
					    pokeLorentz(UV2A,Umu2A*Vmu2A, mu);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  
 | 
				
			||||||
 | 
					  TIndexRep.update_representation(UV2A);
 | 
				
			||||||
 | 
					  typename TwoIndexRep< Nc, AntiSymmetric >::LatticeField UVr2A = TIndexRepA.U;  // (U_f * V_f)_r
 | 
				
			||||||
 | 
					  
 | 
				
			||||||
 | 
					  TIndexRep.update_representation(U2A);
 | 
				
			||||||
 | 
					  typename TwoIndexRep< Nc, AntiSymmetric >::LatticeField Ur2A = TIndexRepA.U;  // U_r
 | 
				
			||||||
 | 
					  
 | 
				
			||||||
 | 
					  TIndexRep.update_representation(V2A);
 | 
				
			||||||
 | 
					  typename TwoIndexRep< Nc, AntiSymmetric >::LatticeField Vr2A = TIndexRepA.U;  // V_r
 | 
				
			||||||
 | 
					  
 | 
				
			||||||
 | 
					  typename TwoIndexRep< Nc, AntiSymmetric >::LatticeField Ur2Vr2A(grid);
 | 
				
			||||||
 | 
					  Ur2Vr2A = zero;
 | 
				
			||||||
 | 
					  for (int mu = 0; mu < Nd; mu++) {
 | 
				
			||||||
 | 
					    typename TwoIndexRep< Nc, AntiSymmetric >::LatticeMatrix Urmu2A = peekLorentz(Ur2A,mu);
 | 
				
			||||||
 | 
					    typename TwoIndexRep< Nc, AntiSymmetric >::LatticeMatrix Vrmu2A = peekLorentz(Vr2A,mu);
 | 
				
			||||||
 | 
					    pokeLorentz(Ur2Vr2A,Urmu2A*Vrmu2A, mu);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  
 | 
				
			||||||
 | 
					  typename TwoIndexRep< Nc, AntiSymmetric >::LatticeField Diff_check2A = UVr2A - Ur2Vr2A;
 | 
				
			||||||
 | 
					  std::cout << GridLogMessage << "Group structure SU("<<Nc<<") check difference (Two Index anti-Symmetric): " << norm2(Diff_check2A) << std::endl;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  
 | 
				
			||||||
 | 
					  // Check correspondence of algebra and group transformations
 | 
				
			||||||
 | 
					  // Create a random vector
 | 
				
			||||||
 | 
					  SU<Nc>::LatticeAlgebraVector h_Asym(grid);
 | 
				
			||||||
 | 
					  typename TwoIndexRep< Nc, AntiSymmetric>::LatticeMatrix Ar_Asym(grid);
 | 
				
			||||||
 | 
					  random(gridRNG,h_Asym);
 | 
				
			||||||
 | 
					  h_Asym = real(h_Asym);
 | 
				
			||||||
 | 
					  SU_TwoIndex< Nc, AntiSymmetric>::TwoIndexLieAlgebraMatrix(h_Asym,Ar_Asym);
 | 
				
			||||||
 | 
					  
 | 
				
			||||||
 | 
					  // Re-extract h_sym
 | 
				
			||||||
 | 
					  SU<Nc>::LatticeAlgebraVector h_Asym2(grid);
 | 
				
			||||||
 | 
					  SU_TwoIndex< Nc, AntiSymmetric>::projectOnAlgebra(h_Asym2, Ar_Asym);
 | 
				
			||||||
 | 
					  SU<Nc>::LatticeAlgebraVector h_diff_Asym = h_Asym - h_Asym2;
 | 
				
			||||||
 | 
					  std::cout << GridLogMessage << "Projections structure check vector difference (Two Index anti-Symmetric): " << norm2(h_diff_Asym) << std::endl;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  
 | 
				
			||||||
 | 
					  // Exponentiate
 | 
				
			||||||
 | 
					  typename TwoIndexRep< Nc, AntiSymmetric>::LatticeMatrix U2iAS(grid);
 | 
				
			||||||
 | 
					  U2iAS  = expMat(Ar_Asym, 1.0, 16);
 | 
				
			||||||
 | 
					  
 | 
				
			||||||
 | 
					  typename TwoIndexRep< Nc, AntiSymmetric>::LatticeMatrix uno2iAS(grid);
 | 
				
			||||||
 | 
					  uno2iAS = 1.0;
 | 
				
			||||||
 | 
					  // Check matrix U2iS, must be real orthogonal
 | 
				
			||||||
 | 
					  typename TwoIndexRep< Nc, AntiSymmetric>::LatticeMatrix Ucheck2iAS = U2iAS - conjugate(U2iAS);
 | 
				
			||||||
 | 
					  std::cout << GridLogMessage << "Reality check: " << norm2(Ucheck2iAS)
 | 
				
			||||||
 | 
					      << std::endl;
 | 
				
			||||||
 | 
					  
 | 
				
			||||||
 | 
					  Ucheck2iAS = U2iAS * adj(U2iAS) - uno2iAS;
 | 
				
			||||||
 | 
					  std::cout << GridLogMessage << "orthogonality check 1: " << norm2(Ucheck2iAS)
 | 
				
			||||||
 | 
					      << std::endl;
 | 
				
			||||||
 | 
					  Ucheck2iAS = adj(U2iAS) * U2iAS - uno2iAS;
 | 
				
			||||||
 | 
					  std::cout << GridLogMessage << "orthogonality check 2: " << norm2(Ucheck2iAS)
 | 
				
			||||||
 | 
					      << std::endl;
 | 
				
			||||||
 | 
					  
 | 
				
			||||||
 | 
					  
 | 
				
			||||||
 | 
					  
 | 
				
			||||||
 | 
					  // Construct the fundamental matrix in the group
 | 
				
			||||||
 | 
					  SU<Nc>::LatticeMatrix Af_Asym(grid);
 | 
				
			||||||
 | 
					  SU<Nc>::FundamentalLieAlgebraMatrix(h_Asym,Af_Asym);
 | 
				
			||||||
 | 
					  SU<Nc>::LatticeMatrix Ufund2A(grid);
 | 
				
			||||||
 | 
					  Ufund2A  = expMat(Af_Asym, 1.0, 16);
 | 
				
			||||||
 | 
					  SU<Nc>::LatticeMatrix UnitCheck2A(grid);
 | 
				
			||||||
 | 
					  UnitCheck2A = Ufund2A * adj(Ufund2A) - uno_f;
 | 
				
			||||||
 | 
					  std::cout << GridLogMessage << "unitarity check 1: " << norm2(UnitCheck2A)
 | 
				
			||||||
 | 
					      << std::endl;
 | 
				
			||||||
 | 
					  UnitCheck2A = adj(Ufund2A) * Ufund2A - uno_f;
 | 
				
			||||||
 | 
					  std::cout << GridLogMessage << "unitarity check 2: " << norm2(UnitCheck2A)
 | 
				
			||||||
 | 
					      << std::endl;
 | 
				
			||||||
 | 
					  
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // Tranform to the 2Index Sym representation
 | 
				
			||||||
 | 
					  U = zero; // fill this with only one direction
 | 
				
			||||||
 | 
					  pokeLorentz(U,Ufund2A,0); // the representation transf acts on full gauge fields
 | 
				
			||||||
 | 
					  
 | 
				
			||||||
 | 
					  TIndexRepA.update_representation(U);
 | 
				
			||||||
 | 
					  Ur2A = TIndexRepA.U;  // U_r  
 | 
				
			||||||
 | 
					  typename TwoIndexRep< Nc, AntiSymmetric>::LatticeMatrix Ur02A = peekLorentz(Ur2A,0); // this should be the same as U2iS
 | 
				
			||||||
 | 
					  
 | 
				
			||||||
 | 
					  typename TwoIndexRep< Nc, AntiSymmetric>::LatticeMatrix Diff_check_mat2A = Ur02A - U2iAS;
 | 
				
			||||||
 | 
					  std::cout << GridLogMessage << "Projections structure check group difference (Two Index anti-Symmetric): " << norm2(Diff_check_mat2A) << std::endl;
 | 
				
			||||||
 | 
					  
 | 
				
			||||||
 | 
					} else  {
 | 
				
			||||||
 | 
					  std::cout << GridLogMessage << "Skipping Two Index anti-Symmetric tests "
 | 
				
			||||||
 | 
					                                 "because representation is trivial (dim = 1)"
 | 
				
			||||||
 | 
					            << std::endl;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  //  std::cout<<GridLogMessage<<"*********************************************"<<std::endl;
 | 
					 | 
				
			||||||
  //  std::cout<<GridLogMessage<<"* Generators for SU(4)"<<std::endl;
 | 
					 | 
				
			||||||
  //  std::cout<<GridLogMessage<<"*********************************************"<<std::endl;
 | 
					 | 
				
			||||||
  //  SU4::printGenerators();
 | 
					 | 
				
			||||||
  //  SU4::testGenerators();
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
  //  std::cout<<GridLogMessage<<"*********************************************"<<std::endl;
 | 
					 | 
				
			||||||
  //  std::cout<<GridLogMessage<<"* Generators for SU(5)"<<std::endl;
 | 
					 | 
				
			||||||
  //  std::cout<<GridLogMessage<<"*********************************************"<<std::endl;
 | 
					 | 
				
			||||||
  //  SU5::printGenerators();
 | 
					 | 
				
			||||||
  //  SU5::testGenerators();
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
  
 | 
					  
 | 
				
			||||||
  Grid_finalize();
 | 
					  Grid_finalize();
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 
 | 
				
			|||||||
@@ -44,6 +44,7 @@ struct scal {
 | 
				
			|||||||
  };
 | 
					  };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
typedef DomainWallFermion<DomainWallVec5dImplR>                      DomainWallVecFermionR;
 | 
					typedef DomainWallFermion<DomainWallVec5dImplR>                      DomainWallVecFermionR;
 | 
				
			||||||
 | 
					typedef ZMobiusFermion<ZDomainWallVec5dImplR>                        ZMobiusVecFermionR;
 | 
				
			||||||
typedef MobiusFermion<DomainWallVec5dImplR>                          MobiusVecFermionR;
 | 
					typedef MobiusFermion<DomainWallVec5dImplR>                          MobiusVecFermionR;
 | 
				
			||||||
typedef MobiusZolotarevFermion<DomainWallVec5dImplR>                 MobiusZolotarevVecFermionR;
 | 
					typedef MobiusZolotarevFermion<DomainWallVec5dImplR>                 MobiusZolotarevVecFermionR;
 | 
				
			||||||
typedef ScaledShamirFermion<DomainWallVec5dImplR>                    ScaledShamirVecFermionR;
 | 
					typedef ScaledShamirFermion<DomainWallVec5dImplR>                    ScaledShamirVecFermionR;
 | 
				
			||||||
@@ -117,6 +118,17 @@ int main (int argc, char ** argv)
 | 
				
			|||||||
  TestWhat<MobiusFermionR>(Dmob,FGrid,FrbGrid,UGrid,mass,M5,&RNG4,&RNG5);
 | 
					  TestWhat<MobiusFermionR>(Dmob,FGrid,FrbGrid,UGrid,mass,M5,&RNG4,&RNG5);
 | 
				
			||||||
  TestWhat<MobiusVecFermionR>(sDmob,sFGrid,sFrbGrid,sUGrid,mass,M5,&sRNG4,&sRNG5);
 | 
					  TestWhat<MobiusVecFermionR>(sDmob,sFGrid,sFrbGrid,sUGrid,mass,M5,&sRNG4,&sRNG5);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  std::cout<<GridLogMessage<<"**************************************************************"<<std::endl;
 | 
				
			||||||
 | 
					  std::cout<<GridLogMessage <<"Z-MobiusFermion test"<<std::endl;
 | 
				
			||||||
 | 
					  std::cout<<GridLogMessage<<"**************************************************************"<<std::endl;
 | 
				
			||||||
 | 
					  std::vector<ComplexD> gamma(Ls,std::complex<double>(1.0,0.0));
 | 
				
			||||||
 | 
					  ZMobiusFermionR     zDmob(Umu,*FGrid,*FrbGrid,*UGrid,*UrbGrid,mass,M5,gamma,b,c);
 | 
				
			||||||
 | 
					  ZMobiusVecFermionR szDmob(Umu,*sFGrid,*sFrbGrid,*sUGrid,*sUrbGrid,mass,M5,gamma,b,c);
 | 
				
			||||||
 | 
					  TestMoo(zDmob,szDmob);
 | 
				
			||||||
 | 
					  TestWhat<ZMobiusFermionR>(zDmob,FGrid,FrbGrid,UGrid,mass,M5,&RNG4,&RNG5);
 | 
				
			||||||
 | 
					  TestWhat<ZMobiusVecFermionR>(szDmob,sFGrid,sFrbGrid,sUGrid,mass,M5,&sRNG4,&sRNG5);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  std::cout<<GridLogMessage<<"**************************************************************"<<std::endl;
 | 
					  std::cout<<GridLogMessage<<"**************************************************************"<<std::endl;
 | 
				
			||||||
  std::cout<<GridLogMessage <<"MobiusZolotarevFermion test"<<std::endl;
 | 
					  std::cout<<GridLogMessage <<"MobiusZolotarevFermion test"<<std::endl;
 | 
				
			||||||
  std::cout<<GridLogMessage<<"**************************************************************"<<std::endl;
 | 
					  std::cout<<GridLogMessage<<"**************************************************************"<<std::endl;
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,30 +1,30 @@
 | 
				
			|||||||
    /*************************************************************************************
 | 
					/*************************************************************************************
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    Grid physics library, www.github.com/paboyle/Grid 
 | 
					Grid physics library, www.github.com/paboyle/Grid
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    Source file: ./tests/Test_zmm.cc
 | 
					Source file: ./tests/Test_zmm.cc
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    Copyright (C) 2015
 | 
					Copyright (C) 2015
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Author: paboyle <paboyle@ph.ed.ac.uk>
 | 
					Author: paboyle <paboyle@ph.ed.ac.uk>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    This program is free software; you can redistribute it and/or modify
 | 
					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
 | 
					it under the terms of the GNU General Public License as published by
 | 
				
			||||||
    the Free Software Foundation; either version 2 of the License, or
 | 
					the Free Software Foundation; either version 2 of the License, or
 | 
				
			||||||
    (at your option) any later version.
 | 
					(at your option) any later version.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    This program is distributed in the hope that it will be useful,
 | 
					This program is distributed in the hope that it will be useful,
 | 
				
			||||||
    but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
					but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
				
			||||||
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
					MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
				
			||||||
    GNU General Public License for more details.
 | 
					GNU General Public License for more details.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    You should have received a copy of the GNU General Public License along
 | 
					You should have received a copy of the GNU General Public License along
 | 
				
			||||||
    with this program; if not, write to the Free Software Foundation, Inc.,
 | 
					with this program; if not, write to the Free Software Foundation, Inc.,
 | 
				
			||||||
    51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 | 
					51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    See the full license in the file "LICENSE" in the top level distribution directory
 | 
					See the full license in the file "LICENSE" in the top level distribution directory
 | 
				
			||||||
    *************************************************************************************/
 | 
					*************************************************************************************/
 | 
				
			||||||
    /*  END LEGAL */
 | 
					/*  END LEGAL */
 | 
				
			||||||
#include <Grid/Grid.h>
 | 
					#include <Grid/Grid.h>
 | 
				
			||||||
#include <Grid/PerfCount.h>
 | 
					#include <Grid/PerfCount.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -96,7 +96,7 @@ int main (int argc, char ** argv)
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
  for(int mu=0;mu<Nd;mu++){
 | 
					  for(int mu=0;mu<Nd;mu++){
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    SU3::GaussianLieAlgebraMatrix(RNG4, mommu); // Traceless antihermitian momentum; gaussian in lie alg
 | 
					    SU3::GaussianFundamentalLieAlgebraMatrix(RNG4, mommu); // Traceless antihermitian momentum; gaussian in lie alg
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    PokeIndex<LorentzIndex>(mom,mommu,mu);
 | 
					    PokeIndex<LorentzIndex>(mom,mommu,mu);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -96,7 +96,7 @@ int main (int argc, char ** argv)
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
  for(int mu=0;mu<Nd;mu++){
 | 
					  for(int mu=0;mu<Nd;mu++){
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    SU3::GaussianLieAlgebraMatrix(RNG4, mommu); // Traceless antihermitian momentum; gaussian in lie alg
 | 
					    SU3::GaussianFundamentalLieAlgebraMatrix(RNG4, mommu); // Traceless antihermitian momentum; gaussian in lie alg
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    PokeIndex<LorentzIndex>(mom,mommu,mu);
 | 
					    PokeIndex<LorentzIndex>(mom,mommu,mu);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -113,7 +113,7 @@ int main (int argc, char ** argv)
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
  for(int mu=0;mu<Nd;mu++){
 | 
					  for(int mu=0;mu<Nd;mu++){
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    SU3::GaussianLieAlgebraMatrix(RNG4, mommu); // Traceless antihermitian momentum; gaussian in lie alg
 | 
					    SU3::GaussianFundamentalLieAlgebraMatrix(RNG4, mommu); // Traceless antihermitian momentum; gaussian in lie alg
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    Hmom -= real(sum(trace(mommu*mommu)));
 | 
					    Hmom -= real(sum(trace(mommu*mommu)));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -82,7 +82,7 @@ int main (int argc, char ** argv)
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
  for(int mu=0;mu<Nd;mu++){
 | 
					  for(int mu=0;mu<Nd;mu++){
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    SU3::GaussianLieAlgebraMatrix(pRNG, mommu); // Traceless antihermitian momentum; gaussian in lie alg
 | 
					    SU3::GaussianFundamentalLieAlgebraMatrix(pRNG, mommu); // Traceless antihermitian momentum; gaussian in lie alg
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    PokeIndex<LorentzIndex>(mom,mommu,mu);
 | 
					    PokeIndex<LorentzIndex>(mom,mommu,mu);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -100,7 +100,7 @@ int main (int argc, char ** argv)
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
  for(int mu=0;mu<Nd;mu++){
 | 
					  for(int mu=0;mu<Nd;mu++){
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    SU3::GaussianLieAlgebraMatrix(RNG4, mommu); // Traceless antihermitian momentum; gaussian in lie alg
 | 
					    SU3::GaussianFundamentalLieAlgebraMatrix(RNG4, mommu); // Traceless antihermitian momentum; gaussian in lie alg
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    PokeIndex<LorentzIndex>(mom,mommu,mu);
 | 
					    PokeIndex<LorentzIndex>(mom,mommu,mu);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -169,7 +169,7 @@ int main (int argc, char ** argv)
 | 
				
			|||||||
  //
 | 
					  //
 | 
				
			||||||
  //	Pmu = zero;
 | 
					  //	Pmu = zero;
 | 
				
			||||||
  //	for(int mu=0;mu<Nd;mu++){
 | 
					  //	for(int mu=0;mu<Nd;mu++){
 | 
				
			||||||
  //	  SU<Ncol>::GaussianLieAlgebraMatrix(pRNG, Pmu);
 | 
					  //	  SU<Ncol>::GaussianFundamentalLieAlgebraMatrix(pRNG, Pmu);
 | 
				
			||||||
  //	  PokeIndex<LorentzIndex>(P, Pmu, mu);
 | 
					  //	  PokeIndex<LorentzIndex>(P, Pmu, mu);
 | 
				
			||||||
  //	}
 | 
					  //	}
 | 
				
			||||||
  //
 | 
					  //
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -100,7 +100,7 @@ int main (int argc, char ** argv)
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
  for(int mu=0;mu<Nd;mu++){
 | 
					  for(int mu=0;mu<Nd;mu++){
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    SU3::GaussianLieAlgebraMatrix(RNG4, mommu); // Traceless antihermitian momentum; gaussian in lie alg
 | 
					    SU3::GaussianFundamentalLieAlgebraMatrix(RNG4, mommu); // Traceless antihermitian momentum; gaussian in lie alg
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    PokeIndex<LorentzIndex>(mom,mommu,mu);
 | 
					    PokeIndex<LorentzIndex>(mom,mommu,mu);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -96,7 +96,7 @@ int main (int argc, char ** argv)
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
  for(int mu=0;mu<Nd;mu++){
 | 
					  for(int mu=0;mu<Nd;mu++){
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    SU3::GaussianLieAlgebraMatrix(RNG4, mommu); // Traceless antihermitian momentum; gaussian in lie alg
 | 
					    SU3::GaussianFundamentalLieAlgebraMatrix(RNG4, mommu); // Traceless antihermitian momentum; gaussian in lie alg
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    PokeIndex<LorentzIndex>(mom,mommu,mu);
 | 
					    PokeIndex<LorentzIndex>(mom,mommu,mu);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -81,7 +81,7 @@ int main (int argc, char ** argv)
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
  for(int mu=0;mu<Nd;mu++){
 | 
					  for(int mu=0;mu<Nd;mu++){
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    SU3::GaussianLieAlgebraMatrix(pRNG, mommu); // Traceless antihermitian momentum; gaussian in lie alg
 | 
					    SU3::GaussianFundamentalLieAlgebraMatrix(pRNG, mommu); // Traceless antihermitian momentum; gaussian in lie alg
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    PokeIndex<LorentzIndex>(mom,mommu,mu);
 | 
					    PokeIndex<LorentzIndex>(mom,mommu,mu);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -58,8 +58,8 @@ int main (int argc, char ** argv)
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
  LatticeGaugeField U(&Grid);
 | 
					  LatticeGaugeField U(&Grid);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  SU3::HotConfiguration(pRNG,U);
 | 
					  //SU2::HotConfiguration(pRNG,U);
 | 
				
			||||||
  //  SU3::ColdConfiguration(pRNG,U);
 | 
					  SU3::ColdConfiguration(pRNG,U);
 | 
				
			||||||
  
 | 
					  
 | 
				
			||||||
  ////////////////////////////////////
 | 
					  ////////////////////////////////////
 | 
				
			||||||
  // Unmodified matrix element
 | 
					  // Unmodified matrix element
 | 
				
			||||||
@@ -76,6 +76,8 @@ int main (int argc, char ** argv)
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
  Dw.MDeriv(tmp , Mphi,  phi,DaggerNo );  UdSdU=tmp;
 | 
					  Dw.MDeriv(tmp , Mphi,  phi,DaggerNo );  UdSdU=tmp;
 | 
				
			||||||
  Dw.MDeriv(tmp , phi,  Mphi,DaggerYes ); UdSdU=(UdSdU+tmp);
 | 
					  Dw.MDeriv(tmp , phi,  Mphi,DaggerYes ); UdSdU=(UdSdU+tmp);
 | 
				
			||||||
 | 
					  // Take the trace
 | 
				
			||||||
 | 
					  UdSdU = Ta(UdSdU);
 | 
				
			||||||
  
 | 
					  
 | 
				
			||||||
  LatticeFermion Ftmp      (&Grid);
 | 
					  LatticeFermion Ftmp      (&Grid);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -93,7 +95,7 @@ int main (int argc, char ** argv)
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
  for(int mu=0;mu<Nd;mu++){
 | 
					  for(int mu=0;mu<Nd;mu++){
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    SU3::GaussianLieAlgebraMatrix(pRNG, mommu); // Traceless antihermitian momentum; gaussian in lie alg
 | 
					    SU3::GaussianFundamentalLieAlgebraMatrix(pRNG, mommu); // Traceless antihermitian momentum; gaussian in lie alg
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    Hmom -= real(sum(trace(mommu*mommu)));
 | 
					    Hmom -= real(sum(trace(mommu*mommu)));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -140,12 +142,14 @@ int main (int argc, char ** argv)
 | 
				
			|||||||
  LatticeComplex dS(&Grid); dS = zero;
 | 
					  LatticeComplex dS(&Grid); dS = zero;
 | 
				
			||||||
  LatticeComplex dSmom(&Grid); dSmom = zero;
 | 
					  LatticeComplex dSmom(&Grid); dSmom = zero;
 | 
				
			||||||
  LatticeComplex dSmom2(&Grid); dSmom2 = zero;
 | 
					  LatticeComplex dSmom2(&Grid); dSmom2 = zero;
 | 
				
			||||||
 | 
					  
 | 
				
			||||||
  for(int mu=0;mu<Nd;mu++){
 | 
					  for(int mu=0;mu<Nd;mu++){
 | 
				
			||||||
    mommu   = PeekIndex<LorentzIndex>(UdSdU,mu);
 | 
					    mommu   = PeekIndex<LorentzIndex>(UdSdU,mu);
 | 
				
			||||||
    mommu=Ta(mommu)*2.0;
 | 
					    mommu=Ta(mommu)*2.0;
 | 
				
			||||||
    PokeIndex<LorentzIndex>(UdSdU,mommu,mu);
 | 
					    PokeIndex<LorentzIndex>(UdSdU,mommu,mu);
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
  
 | 
					  
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  for(int mu=0;mu<Nd;mu++){
 | 
					  for(int mu=0;mu<Nd;mu++){
 | 
				
			||||||
    mommu   = PeekIndex<LorentzIndex>(mom,mu);
 | 
					    mommu   = PeekIndex<LorentzIndex>(mom,mu);
 | 
				
			||||||
    std::cout << GridLogMessage<< " Mommu  " << norm2(mommu)<<std::endl;
 | 
					    std::cout << GridLogMessage<< " Mommu  " << norm2(mommu)<<std::endl;
 | 
				
			||||||
@@ -168,7 +172,7 @@ int main (int argc, char ** argv)
 | 
				
			|||||||
    dSmom2 = dSmom2 - trace(forcemu*forcemu) *(0.25* dt*dt);
 | 
					    dSmom2 = dSmom2 - trace(forcemu*forcemu) *(0.25* dt*dt);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // Update mom action density
 | 
					    // Update mom action density
 | 
				
			||||||
    mommu = mommu + forcemu*(dt*0.5);
 | 
					    mommu = mommu + forcemu*(dt * 0.5);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    Hmomprime -= real(sum(trace(mommu*mommu)));
 | 
					    Hmomprime -= real(sum(trace(mommu*mommu)));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -103,7 +103,7 @@ int main (int argc, char ** argv)
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
  for(int mu=0;mu<Nd;mu++){
 | 
					  for(int mu=0;mu<Nd;mu++){
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    SU3::GaussianLieAlgebraMatrix(pRNG, mommu); // Traceless antihermitian momentum; gaussian in lie alg
 | 
					    SU3::GaussianFundamentalLieAlgebraMatrix(pRNG, mommu); // Traceless antihermitian momentum; gaussian in lie alg
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    //    Dw.DoubleStore(Dw.Umu,Uprime); // update U _and_ Udag
 | 
					    //    Dw.DoubleStore(Dw.Umu,Uprime); // update U _and_ Udag
 | 
				
			||||||
    Dw.DhopDirDisp(phi,Ftmp,mu,mu+4,DaggerYes); 
 | 
					    Dw.DhopDirDisp(phi,Ftmp,mu,mu+4,DaggerYes); 
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -86,7 +86,7 @@ int main (int argc, char ** argv)
 | 
				
			|||||||
  LatticeColourMatrix Umu_save(&Grid);
 | 
					  LatticeColourMatrix Umu_save(&Grid);
 | 
				
			||||||
  LatticeColourMatrix dU (&Grid);
 | 
					  LatticeColourMatrix dU (&Grid);
 | 
				
			||||||
  LatticeColourMatrix mom(&Grid); 
 | 
					  LatticeColourMatrix mom(&Grid); 
 | 
				
			||||||
  SU3::GaussianLieAlgebraMatrix(pRNG, mom); // Traceless antihermitian momentum; gaussian in lie alg
 | 
					  SU3::GaussianFundamentalLieAlgebraMatrix(pRNG, mom); // Traceless antihermitian momentum; gaussian in lie alg
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  // check mom is as i expect
 | 
					  // check mom is as i expect
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										63
									
								
								tests/hmc/Make.inc
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										63
									
								
								tests/hmc/Make.inc
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,63 @@
 | 
				
			|||||||
 | 
					tests: Test_hmc_EODWFRatio Test_hmc_EODWFRatio_Gparity Test_hmc_EOWilsonFermionGauge Test_hmc_EOWilsonRatio Test_hmc_GparityIwasakiGauge Test_hmc_GparityWilsonGauge Test_hmc_IwasakiGauge Test_hmc_RectGauge Test_hmc_WilsonAdjointFermionGauge Test_hmc_WilsonFermionGauge Test_hmc_WilsonGauge Test_hmc_WilsonMixedRepresentationsFermionGauge Test_hmc_WilsonRatio Test_hmc_WilsonTwoIndexSymmetricFermionGauge Test_multishift_sqrt Test_remez Test_rhmc_EOWilson1p1 Test_rhmc_EOWilsonRatio Test_rhmc_Wilson1p1 Test_rhmc_WilsonRatio
 | 
				
			||||||
 | 
					EXTRA_PROGRAMS = Test_hmc_EODWFRatio Test_hmc_EODWFRatio_Gparity Test_hmc_EOWilsonFermionGauge Test_hmc_EOWilsonRatio Test_hmc_GparityIwasakiGauge Test_hmc_GparityWilsonGauge Test_hmc_IwasakiGauge Test_hmc_RectGauge Test_hmc_WilsonAdjointFermionGauge Test_hmc_WilsonFermionGauge Test_hmc_WilsonGauge Test_hmc_WilsonMixedRepresentationsFermionGauge Test_hmc_WilsonRatio Test_hmc_WilsonTwoIndexSymmetricFermionGauge Test_multishift_sqrt Test_remez Test_rhmc_EOWilson1p1 Test_rhmc_EOWilsonRatio Test_rhmc_Wilson1p1 Test_rhmc_WilsonRatio
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Test_hmc_EODWFRatio_SOURCES=Test_hmc_EODWFRatio.cc
 | 
				
			||||||
 | 
					Test_hmc_EODWFRatio_LDADD=-lGrid
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Test_hmc_EODWFRatio_Gparity_SOURCES=Test_hmc_EODWFRatio_Gparity.cc
 | 
				
			||||||
 | 
					Test_hmc_EODWFRatio_Gparity_LDADD=-lGrid
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Test_hmc_EOWilsonFermionGauge_SOURCES=Test_hmc_EOWilsonFermionGauge.cc
 | 
				
			||||||
 | 
					Test_hmc_EOWilsonFermionGauge_LDADD=-lGrid
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Test_hmc_EOWilsonRatio_SOURCES=Test_hmc_EOWilsonRatio.cc
 | 
				
			||||||
 | 
					Test_hmc_EOWilsonRatio_LDADD=-lGrid
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Test_hmc_GparityIwasakiGauge_SOURCES=Test_hmc_GparityIwasakiGauge.cc
 | 
				
			||||||
 | 
					Test_hmc_GparityIwasakiGauge_LDADD=-lGrid
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Test_hmc_GparityWilsonGauge_SOURCES=Test_hmc_GparityWilsonGauge.cc
 | 
				
			||||||
 | 
					Test_hmc_GparityWilsonGauge_LDADD=-lGrid
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Test_hmc_IwasakiGauge_SOURCES=Test_hmc_IwasakiGauge.cc
 | 
				
			||||||
 | 
					Test_hmc_IwasakiGauge_LDADD=-lGrid
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Test_hmc_RectGauge_SOURCES=Test_hmc_RectGauge.cc
 | 
				
			||||||
 | 
					Test_hmc_RectGauge_LDADD=-lGrid
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Test_hmc_WilsonAdjointFermionGauge_SOURCES=Test_hmc_WilsonAdjointFermionGauge.cc
 | 
				
			||||||
 | 
					Test_hmc_WilsonAdjointFermionGauge_LDADD=-lGrid
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Test_hmc_WilsonFermionGauge_SOURCES=Test_hmc_WilsonFermionGauge.cc
 | 
				
			||||||
 | 
					Test_hmc_WilsonFermionGauge_LDADD=-lGrid
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Test_hmc_WilsonGauge_SOURCES=Test_hmc_WilsonGauge.cc
 | 
				
			||||||
 | 
					Test_hmc_WilsonGauge_LDADD=-lGrid
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Test_hmc_WilsonMixedRepresentationsFermionGauge_SOURCES=Test_hmc_WilsonMixedRepresentationsFermionGauge.cc
 | 
				
			||||||
 | 
					Test_hmc_WilsonMixedRepresentationsFermionGauge_LDADD=-lGrid
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Test_hmc_WilsonRatio_SOURCES=Test_hmc_WilsonRatio.cc
 | 
				
			||||||
 | 
					Test_hmc_WilsonRatio_LDADD=-lGrid
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Test_hmc_WilsonTwoIndexSymmetricFermionGauge_SOURCES=Test_hmc_WilsonTwoIndexSymmetricFermionGauge.cc
 | 
				
			||||||
 | 
					Test_hmc_WilsonTwoIndexSymmetricFermionGauge_LDADD=-lGrid
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Test_multishift_sqrt_SOURCES=Test_multishift_sqrt.cc
 | 
				
			||||||
 | 
					Test_multishift_sqrt_LDADD=-lGrid
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Test_remez_SOURCES=Test_remez.cc
 | 
				
			||||||
 | 
					Test_remez_LDADD=-lGrid
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Test_rhmc_EOWilson1p1_SOURCES=Test_rhmc_EOWilson1p1.cc
 | 
				
			||||||
 | 
					Test_rhmc_EOWilson1p1_LDADD=-lGrid
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Test_rhmc_EOWilsonRatio_SOURCES=Test_rhmc_EOWilsonRatio.cc
 | 
				
			||||||
 | 
					Test_rhmc_EOWilsonRatio_LDADD=-lGrid
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Test_rhmc_Wilson1p1_SOURCES=Test_rhmc_Wilson1p1.cc
 | 
				
			||||||
 | 
					Test_rhmc_Wilson1p1_LDADD=-lGrid
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Test_rhmc_WilsonRatio_SOURCES=Test_rhmc_WilsonRatio.cc
 | 
				
			||||||
 | 
					Test_rhmc_WilsonRatio_LDADD=-lGrid
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -76,6 +76,12 @@ public:
 | 
				
			|||||||
    TheAction.push_back(Level1);
 | 
					    TheAction.push_back(Level1);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    Run(argc,argv);
 | 
					    Run(argc,argv);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    std::cout << GridLogMessage << "Numerator report, Pauli-Villars term         : " << std::endl;
 | 
				
			||||||
 | 
					    NumOp.Report();
 | 
				
			||||||
 | 
					    std::cout << GridLogMessage << "Denominator report, Dw(m) term (includes CG) : " << std::endl;
 | 
				
			||||||
 | 
					    DenOp.Report();
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
  };
 | 
					  };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -67,7 +67,7 @@ public:
 | 
				
			|||||||
    TwoFlavourEvenOddPseudoFermionAction<ImplPolicy> Nf2(FermOp,CG,CG);
 | 
					    TwoFlavourEvenOddPseudoFermionAction<ImplPolicy> Nf2(FermOp,CG,CG);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    //Set smearing (true/false), default: false
 | 
					    //Set smearing (true/false), default: false
 | 
				
			||||||
    Nf2.is_smeared=false;
 | 
					    Nf2.is_smeared=true;
 | 
				
			||||||
    
 | 
					    
 | 
				
			||||||
    //Collect actions
 | 
					    //Collect actions
 | 
				
			||||||
    ActionLevel<LatticeGaugeField> Level1(1);
 | 
					    ActionLevel<LatticeGaugeField> Level1(1);
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										107
									
								
								tests/hmc/Test_hmc_WilsonAdjointFermionGauge.cc
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										107
									
								
								tests/hmc/Test_hmc_WilsonAdjointFermionGauge.cc
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,107 @@
 | 
				
			|||||||
 | 
					/*************************************************************************************
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Grid physics library, www.github.com/paboyle/Grid
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Source file: ./tests/Test_hmc_WilsonAdjointFermionGauge.cc
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Copyright (C) 2015
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Author: Peter Boyle <pabobyle@ph.ed.ac.uk>
 | 
				
			||||||
 | 
					Author: Peter Boyle <paboyle@ph.ed.ac.uk>
 | 
				
			||||||
 | 
					Author: neo <cossu@post.kek.jp>
 | 
				
			||||||
 | 
					Author: paboyle <paboyle@ph.ed.ac.uk>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					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
 | 
				
			||||||
 | 
					the Free Software Foundation; either version 2 of the License, or
 | 
				
			||||||
 | 
					(at your option) any later version.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					This program is distributed in the hope that it will be useful,
 | 
				
			||||||
 | 
					but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
				
			||||||
 | 
					MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
				
			||||||
 | 
					GNU General Public License for more details.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					You should have received a copy of the GNU General Public License along
 | 
				
			||||||
 | 
					with this program; if not, write to the Free Software Foundation, Inc.,
 | 
				
			||||||
 | 
					51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					See the full license in the file "LICENSE" in the top level distribution
 | 
				
			||||||
 | 
					directory
 | 
				
			||||||
 | 
					*************************************************************************************/
 | 
				
			||||||
 | 
					/*  END LEGAL */
 | 
				
			||||||
 | 
					#include "Grid/Grid.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					using namespace std;
 | 
				
			||||||
 | 
					using namespace Grid;
 | 
				
			||||||
 | 
					using namespace Grid::QCD;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace Grid {
 | 
				
			||||||
 | 
					namespace QCD {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Here change the allowed (higher) representations
 | 
				
			||||||
 | 
					typedef Representations< FundamentalRepresentation, AdjointRepresentation > TheRepresentations;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class HmcRunner : public NerscHmcRunnerHirep< TheRepresentations > {
 | 
				
			||||||
 | 
					 public:
 | 
				
			||||||
 | 
					  void BuildTheAction(int argc, char **argv)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					    typedef WilsonAdjImplR ImplPolicy; // gauge field implemetation for the pseudofermions
 | 
				
			||||||
 | 
					    typedef WilsonAdjFermionR FermionAction; // type of lattice fermions (Wilson, DW, ...)
 | 
				
			||||||
 | 
					    typedef typename FermionAction::FermionField FermionField;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    UGrid = SpaceTimeGrid::makeFourDimGrid(
 | 
				
			||||||
 | 
					        GridDefaultLatt(), GridDefaultSimd(Nd, vComplex::Nsimd()),
 | 
				
			||||||
 | 
					        GridDefaultMpi());
 | 
				
			||||||
 | 
					    UrbGrid = SpaceTimeGrid::makeFourDimRedBlackGrid(UGrid);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    FGrid = UGrid;
 | 
				
			||||||
 | 
					    FrbGrid = UrbGrid;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // temporarily need a gauge field
 | 
				
			||||||
 | 
					    //LatticeGaugeField U(UGrid);
 | 
				
			||||||
 | 
					    AdjointRepresentation::LatticeField U(UGrid);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // Gauge action
 | 
				
			||||||
 | 
					    WilsonGaugeActionR Waction(2.25);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    Real mass = -0.95;
 | 
				
			||||||
 | 
					    FermionAction FermOp(U, *FGrid, *FrbGrid, mass);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    ConjugateGradient<FermionField> CG(1.0e-8, 10000, false);
 | 
				
			||||||
 | 
					    ConjugateResidual<FermionField> CR(1.0e-8, 10000);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // Pass two solvers: one for the force computation and one for the action
 | 
				
			||||||
 | 
					    TwoFlavourPseudoFermionAction<ImplPolicy> Nf2(FermOp, CG, CG);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // Set smearing (true/false), default: false
 | 
				
			||||||
 | 
					    Nf2.is_smeared = false;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // Collect actions
 | 
				
			||||||
 | 
					    ActionLevel<LatticeGaugeField, TheRepresentations > Level1(1);
 | 
				
			||||||
 | 
					    Level1.push_back(&Nf2);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    ActionLevel<LatticeGaugeField, TheRepresentations > Level2(4);
 | 
				
			||||||
 | 
					    Level2.push_back(&Waction);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    TheAction.push_back(Level1);
 | 
				
			||||||
 | 
					    TheAction.push_back(Level2);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    Run(argc, argv);
 | 
				
			||||||
 | 
					  };
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int main(int argc, char **argv) {
 | 
				
			||||||
 | 
					  Grid_init(&argc, &argv);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  int threads = GridThread::GetThreads();
 | 
				
			||||||
 | 
					  std::cout << GridLogMessage << "Grid is setup to use " << threads
 | 
				
			||||||
 | 
					            << " threads" << std::endl;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  HmcRunner TheHMC;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  TheHMC.BuildTheAction(argc, argv);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@@ -1,33 +1,33 @@
 | 
				
			|||||||
    /*************************************************************************************
 | 
					/*************************************************************************************
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    Grid physics library, www.github.com/paboyle/Grid 
 | 
					Grid physics library, www.github.com/paboyle/Grid
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    Source file: ./tests/Test_hmc_WilsonFermionGauge.cc
 | 
					Source file: ./tests/Test_hmc_WilsonFermionGauge.cc
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    Copyright (C) 2015
 | 
					Copyright (C) 2015
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Author: Peter Boyle <pabobyle@ph.ed.ac.uk>
 | 
					Author: Peter Boyle <pabobyle@ph.ed.ac.uk>
 | 
				
			||||||
Author: Peter Boyle <paboyle@ph.ed.ac.uk>
 | 
					Author: Peter Boyle <paboyle@ph.ed.ac.uk>
 | 
				
			||||||
Author: neo <cossu@post.kek.jp>
 | 
					Author: neo <cossu@post.kek.jp>
 | 
				
			||||||
Author: paboyle <paboyle@ph.ed.ac.uk>
 | 
					Author: paboyle <paboyle@ph.ed.ac.uk>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    This program is free software; you can redistribute it and/or modify
 | 
					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
 | 
					it under the terms of the GNU General Public License as published by
 | 
				
			||||||
    the Free Software Foundation; either version 2 of the License, or
 | 
					the Free Software Foundation; either version 2 of the License, or
 | 
				
			||||||
    (at your option) any later version.
 | 
					(at your option) any later version.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    This program is distributed in the hope that it will be useful,
 | 
					This program is distributed in the hope that it will be useful,
 | 
				
			||||||
    but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
					but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
				
			||||||
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
					MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
				
			||||||
    GNU General Public License for more details.
 | 
					GNU General Public License for more details.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    You should have received a copy of the GNU General Public License along
 | 
					You should have received a copy of the GNU General Public License along
 | 
				
			||||||
    with this program; if not, write to the Free Software Foundation, Inc.,
 | 
					with this program; if not, write to the Free Software Foundation, Inc.,
 | 
				
			||||||
    51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 | 
					51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    See the full license in the file "LICENSE" in the top level distribution directory
 | 
					See the full license in the file "LICENSE" in the top level distribution directory
 | 
				
			||||||
    *************************************************************************************/
 | 
					*************************************************************************************/
 | 
				
			||||||
    /*  END LEGAL */
 | 
					/*  END LEGAL */
 | 
				
			||||||
#include <Grid/Grid.h>
 | 
					#include <Grid/Grid.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
using namespace std;
 | 
					using namespace std;
 | 
				
			||||||
@@ -35,43 +35,42 @@ using namespace Grid;
 | 
				
			|||||||
using namespace Grid::QCD;
 | 
					using namespace Grid::QCD;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace Grid {
 | 
					namespace Grid {
 | 
				
			||||||
  namespace QCD { 
 | 
					namespace QCD {
 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
class HmcRunner : public NerscHmcRunner {
 | 
					class HmcRunner : public NerscHmcRunner {
 | 
				
			||||||
public:
 | 
					 public:
 | 
				
			||||||
 | 
					  void BuildTheAction(int argc, char **argv)
 | 
				
			||||||
  void BuildTheAction (int argc, char **argv)
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
  {
 | 
					  {
 | 
				
			||||||
    typedef WilsonImplR ImplPolicy;
 | 
					    typedef WilsonImplR ImplPolicy;
 | 
				
			||||||
    typedef WilsonFermionR FermionAction;
 | 
					    typedef WilsonFermionR FermionAction;
 | 
				
			||||||
    typedef typename FermionAction::FermionField FermionField;
 | 
					    typedef typename FermionAction::FermionField FermionField;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    UGrid   = SpaceTimeGrid::makeFourDimGrid(GridDefaultLatt(), GridDefaultSimd(Nd,vComplex::Nsimd()),GridDefaultMpi());
 | 
					    UGrid = SpaceTimeGrid::makeFourDimGrid(
 | 
				
			||||||
 | 
					        GridDefaultLatt(), GridDefaultSimd(Nd, vComplex::Nsimd()),
 | 
				
			||||||
 | 
					        GridDefaultMpi());
 | 
				
			||||||
    UrbGrid = SpaceTimeGrid::makeFourDimRedBlackGrid(UGrid);
 | 
					    UrbGrid = SpaceTimeGrid::makeFourDimRedBlackGrid(UGrid);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    FGrid   = UGrid;
 | 
					    FGrid = UGrid;
 | 
				
			||||||
    FrbGrid = UrbGrid;
 | 
					    FrbGrid = UrbGrid;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // temporarily need a gauge field
 | 
					    // temporarily need a gauge field
 | 
				
			||||||
    LatticeGaugeField  U(UGrid);
 | 
					    LatticeGaugeField U(UGrid);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // Gauge action
 | 
					    // Gauge action
 | 
				
			||||||
    WilsonGaugeActionR Waction(5.6);
 | 
					    WilsonGaugeActionR Waction(5.6);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    Real mass=-0.77;
 | 
					    Real mass = -0.77;
 | 
				
			||||||
    FermionAction FermOp(U,*FGrid,*FrbGrid,mass);
 | 
					    FermionAction FermOp(U, *FGrid, *FrbGrid, mass);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    ConjugateGradient<FermionField>  CG(1.0e-8,10000);
 | 
					    ConjugateGradient<FermionField> CG(1.0e-8, 10000);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    TwoFlavourPseudoFermionAction<ImplPolicy> Nf2(FermOp,CG,CG);
 | 
					    TwoFlavourPseudoFermionAction<ImplPolicy> Nf2(FermOp, CG, CG);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    //Set smearing (true/false), default: false
 | 
					    // Set smearing (true/false), default: false
 | 
				
			||||||
    Nf2.is_smeared = true;
 | 
					    Nf2.is_smeared = true;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // Collect actions
 | 
				
			||||||
    //Collect actions
 | 
					 | 
				
			||||||
    ActionLevel<LatticeGaugeField> Level1(1);
 | 
					    ActionLevel<LatticeGaugeField> Level1(1);
 | 
				
			||||||
    Level1.push_back(&Nf2);
 | 
					    Level1.push_back(&Nf2);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -81,24 +80,20 @@ public:
 | 
				
			|||||||
    TheAction.push_back(Level1);
 | 
					    TheAction.push_back(Level1);
 | 
				
			||||||
    TheAction.push_back(Level2);
 | 
					    TheAction.push_back(Level2);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    Run(argc,argv);
 | 
					    Run(argc, argv);
 | 
				
			||||||
  };
 | 
					  };
 | 
				
			||||||
 | 
					 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
}}
 | 
					int main(int argc, char **argv) {
 | 
				
			||||||
 | 
					  Grid_init(&argc, &argv);
 | 
				
			||||||
int main (int argc, char ** argv)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
  Grid_init(&argc,&argv);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
  int threads = GridThread::GetThreads();
 | 
					  int threads = GridThread::GetThreads();
 | 
				
			||||||
  std::cout<<GridLogMessage << "Grid is setup to use "<<threads<<" threads"<<std::endl;
 | 
					  std::cout << GridLogMessage << "Grid is setup to use " << threads
 | 
				
			||||||
 | 
					            << " threads" << std::endl;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  HmcRunner TheHMC;
 | 
					  HmcRunner TheHMC;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  TheHMC.BuildTheAction(argc,argv);
 | 
					  TheHMC.BuildTheAction(argc, argv);
 | 
				
			||||||
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										113
									
								
								tests/hmc/Test_hmc_WilsonMixedRepresentationsFermionGauge.cc
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										113
									
								
								tests/hmc/Test_hmc_WilsonMixedRepresentationsFermionGauge.cc
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,113 @@
 | 
				
			|||||||
 | 
					/*************************************************************************************
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Grid physics library, www.github.com/paboyle/Grid
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Source file: ./tests/Test_hmc_WilsonAdjointFermionGauge.cc
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Copyright (C) 2015
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Author: Peter Boyle <pabobyle@ph.ed.ac.uk>
 | 
				
			||||||
 | 
					Author: Peter Boyle <paboyle@ph.ed.ac.uk>
 | 
				
			||||||
 | 
					Author: neo <cossu@post.kek.jp>
 | 
				
			||||||
 | 
					Author: paboyle <paboyle@ph.ed.ac.uk>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					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
 | 
				
			||||||
 | 
					the Free Software Foundation; either version 2 of the License, or
 | 
				
			||||||
 | 
					(at your option) any later version.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					This program is distributed in the hope that it will be useful,
 | 
				
			||||||
 | 
					but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
				
			||||||
 | 
					MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
				
			||||||
 | 
					GNU General Public License for more details.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					You should have received a copy of the GNU General Public License along
 | 
				
			||||||
 | 
					with this program; if not, write to the Free Software Foundation, Inc.,
 | 
				
			||||||
 | 
					51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					See the full license in the file "LICENSE" in the top level distribution
 | 
				
			||||||
 | 
					directory
 | 
				
			||||||
 | 
					*************************************************************************************/
 | 
				
			||||||
 | 
					/*  END LEGAL */
 | 
				
			||||||
 | 
					#include "Grid/Grid.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					using namespace std;
 | 
				
			||||||
 | 
					using namespace Grid;
 | 
				
			||||||
 | 
					using namespace Grid::QCD;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace Grid {
 | 
				
			||||||
 | 
					namespace QCD {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Here change the allowed (higher) representations
 | 
				
			||||||
 | 
					typedef Representations< FundamentalRepresentation, AdjointRepresentation , TwoIndexSymmetricRepresentation> TheRepresentations;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class HmcRunner : public NerscHmcRunnerHirep< TheRepresentations > {
 | 
				
			||||||
 | 
					 public:
 | 
				
			||||||
 | 
					  void BuildTheAction(int argc, char **argv)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					    typedef WilsonAdjImplR AdjImplPolicy; // gauge field implemetation for the pseudofermions
 | 
				
			||||||
 | 
					    typedef WilsonAdjFermionR AdjFermionAction; // type of lattice fermions (Wilson, DW, ...)
 | 
				
			||||||
 | 
					    typedef WilsonTwoIndexSymmetricImplR SymmImplPolicy; 
 | 
				
			||||||
 | 
					    typedef WilsonTwoIndexSymmetricFermionR SymmFermionAction; 
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					 
 | 
				
			||||||
 | 
					    typedef typename AdjFermionAction::FermionField AdjFermionField;
 | 
				
			||||||
 | 
					    typedef typename SymmFermionAction::FermionField SymmFermionField;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    UGrid = SpaceTimeGrid::makeFourDimGrid(
 | 
				
			||||||
 | 
					        GridDefaultLatt(), GridDefaultSimd(Nd, vComplex::Nsimd()),
 | 
				
			||||||
 | 
					        GridDefaultMpi());
 | 
				
			||||||
 | 
					    UrbGrid = SpaceTimeGrid::makeFourDimRedBlackGrid(UGrid);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    FGrid = UGrid;
 | 
				
			||||||
 | 
					    FrbGrid = UrbGrid;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // temporarily need a gauge field
 | 
				
			||||||
 | 
					    //LatticeGaugeField U(UGrid);
 | 
				
			||||||
 | 
					    AdjointRepresentation::LatticeField UA(UGrid);
 | 
				
			||||||
 | 
					    TwoIndexSymmetricRepresentation::LatticeField US(UGrid);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // Gauge action
 | 
				
			||||||
 | 
					    WilsonGaugeActionR Waction(5.6);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    Real adjoint_mass = -0.1;
 | 
				
			||||||
 | 
					    Real symm_mass = -0.5;
 | 
				
			||||||
 | 
					    AdjFermionAction AdjFermOp(UA, *FGrid, *FrbGrid, adjoint_mass);
 | 
				
			||||||
 | 
					    SymmFermionAction SymmFermOp(US, *FGrid, *FrbGrid, symm_mass);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    ConjugateGradient<AdjFermionField> CG_adj(1.0e-8, 10000, false);
 | 
				
			||||||
 | 
					    ConjugateGradient<SymmFermionField> CG_symm(1.0e-8, 10000, false);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // Pass two solvers: one for the force computation and one for the action
 | 
				
			||||||
 | 
					    TwoFlavourPseudoFermionAction<AdjImplPolicy> Nf2_Adj(AdjFermOp, CG_adj, CG_adj);
 | 
				
			||||||
 | 
					    TwoFlavourPseudoFermionAction<SymmImplPolicy> Nf2_Symm(SymmFermOp, CG_symm, CG_symm);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // Collect actions
 | 
				
			||||||
 | 
					    ActionLevel<LatticeGaugeField, TheRepresentations > Level1(1);
 | 
				
			||||||
 | 
					    Level1.push_back(&Nf2_Adj);
 | 
				
			||||||
 | 
					    Level1.push_back(&Nf2_Symm);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    ActionLevel<LatticeGaugeField, TheRepresentations > Level2(4);
 | 
				
			||||||
 | 
					    Level2.push_back(&Waction);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    TheAction.push_back(Level1);
 | 
				
			||||||
 | 
					    TheAction.push_back(Level2);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    Run(argc, argv);
 | 
				
			||||||
 | 
					  };
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int main(int argc, char **argv) {
 | 
				
			||||||
 | 
					  Grid_init(&argc, &argv);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  int threads = GridThread::GetThreads();
 | 
				
			||||||
 | 
					  std::cout << GridLogMessage << "Grid is setup to use " << threads
 | 
				
			||||||
 | 
					            << " threads" << std::endl;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  HmcRunner TheHMC;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  TheHMC.BuildTheAction(argc, argv);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										103
									
								
								tests/hmc/Test_hmc_WilsonTwoIndexSymmetricFermionGauge.cc
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										103
									
								
								tests/hmc/Test_hmc_WilsonTwoIndexSymmetricFermionGauge.cc
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,103 @@
 | 
				
			|||||||
 | 
					/*************************************************************************************
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Grid physics library, www.github.com/paboyle/Grid
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Source file: ./tests/Test_hmc_WilsonAdjointFermionGauge.cc
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Copyright (C) 2015
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Author: Peter Boyle <paboyle@ph.ed.ac.uk>
 | 
				
			||||||
 | 
					Author: neo <cossu@post.kek.jp>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					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
 | 
				
			||||||
 | 
					the Free Software Foundation; either version 2 of the License, or
 | 
				
			||||||
 | 
					(at your option) any later version.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					This program is distributed in the hope that it will be useful,
 | 
				
			||||||
 | 
					but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
				
			||||||
 | 
					MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
				
			||||||
 | 
					GNU General Public License for more details.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					You should have received a copy of the GNU General Public License along
 | 
				
			||||||
 | 
					with this program; if not, write to the Free Software Foundation, Inc.,
 | 
				
			||||||
 | 
					51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					See the full license in the file "LICENSE" in the top level distribution
 | 
				
			||||||
 | 
					directory
 | 
				
			||||||
 | 
					*************************************************************************************/
 | 
				
			||||||
 | 
					/*  END LEGAL */
 | 
				
			||||||
 | 
					#include "Grid/Grid.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					using namespace std;
 | 
				
			||||||
 | 
					using namespace Grid;
 | 
				
			||||||
 | 
					using namespace Grid::QCD;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace Grid {
 | 
				
			||||||
 | 
					namespace QCD {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Here change the allowed (higher) representations
 | 
				
			||||||
 | 
					typedef Representations< FundamentalRepresentation, TwoIndexSymmetricRepresentation > TheRepresentations;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class HmcRunner : public NerscHmcRunnerHirep< TheRepresentations > {
 | 
				
			||||||
 | 
					 public:
 | 
				
			||||||
 | 
					  void BuildTheAction(int argc, char **argv)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					    typedef WilsonTwoIndexSymmetricImplR ImplPolicy; // gauge field implemetation for the pseudofermions
 | 
				
			||||||
 | 
					    typedef WilsonTwoIndexSymmetricFermionR FermionAction; // type of lattice fermions (Wilson, DW, ...)
 | 
				
			||||||
 | 
					    typedef typename FermionAction::FermionField FermionField;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    UGrid = SpaceTimeGrid::makeFourDimGrid(
 | 
				
			||||||
 | 
					        GridDefaultLatt(), GridDefaultSimd(Nd, vComplex::Nsimd()),
 | 
				
			||||||
 | 
					        GridDefaultMpi());
 | 
				
			||||||
 | 
					    UrbGrid = SpaceTimeGrid::makeFourDimRedBlackGrid(UGrid);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    FGrid = UGrid;
 | 
				
			||||||
 | 
					    FrbGrid = UrbGrid;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // temporarily need a gauge field
 | 
				
			||||||
 | 
					    TwoIndexSymmetricRepresentation::LatticeField U(UGrid);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // Gauge action
 | 
				
			||||||
 | 
					    WilsonGaugeActionR Waction(2.0);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    Real mass = -0.0;
 | 
				
			||||||
 | 
					    FermionAction FermOp(U, *FGrid, *FrbGrid, mass);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    ConjugateGradient<FermionField> CG(1.0e-8, 10000, false);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // Pass two solvers: one for the force computation and one for the action
 | 
				
			||||||
 | 
					    TwoFlavourPseudoFermionAction<ImplPolicy> Nf2(FermOp, CG, CG);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // Set smearing (true/false), default: false
 | 
				
			||||||
 | 
					    Nf2.is_smeared = false;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // Collect actions
 | 
				
			||||||
 | 
					    ActionLevel<LatticeGaugeField, TheRepresentations > Level1(1);
 | 
				
			||||||
 | 
					    Level1.push_back(&Nf2);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    ActionLevel<LatticeGaugeField, TheRepresentations > Level2(4);
 | 
				
			||||||
 | 
					    Level2.push_back(&Waction);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    TheAction.push_back(Level1);
 | 
				
			||||||
 | 
					    TheAction.push_back(Level2);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    Run(argc, argv);
 | 
				
			||||||
 | 
					  };
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int main(int argc, char **argv) {
 | 
				
			||||||
 | 
					  Grid_init(&argc, &argv);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  int threads = GridThread::GetThreads();
 | 
				
			||||||
 | 
					  std::cout << GridLogMessage << "Grid is setup to use " << threads
 | 
				
			||||||
 | 
					            << " threads" << std::endl;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  HmcRunner TheHMC;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  TheHMC.BuildTheAction(argc, argv);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										0
									
								
								tests/qdpxx/Test_qdpxx_loops_staples.cc
									
									
									
									
									
										
										
										Executable file → Normal file
									
								
							
							
						
						
									
										0
									
								
								tests/qdpxx/Test_qdpxx_loops_staples.cc
									
									
									
									
									
										
										
										Executable file → Normal file
									
								
							
							
								
								
									
										0
									
								
								tests/qdpxx/Test_qdpxx_munprec.cc
									
									
									
									
									
										
										
										Executable file → Normal file
									
								
							
							
						
						
									
										0
									
								
								tests/qdpxx/Test_qdpxx_munprec.cc
									
									
									
									
									
										
										
										Executable file → Normal file
									
								
							@@ -1,87 +1,105 @@
 | 
				
			|||||||
    /*************************************************************************************
 | 
					/*************************************************************************************
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    Grid physics library, www.github.com/paboyle/Grid 
 | 
					Grid physics library, www.github.com/paboyle/Grid
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    Source file: ./tests/Test_dwf_cg_prec.cc
 | 
					Source file: ./tests/Test_dwf_cg_prec.cc
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    Copyright (C) 2015
 | 
					Copyright (C) 2015
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Author: Peter Boyle <paboyle@ph.ed.ac.uk>
 | 
					Author: Peter Boyle <paboyle@ph.ed.ac.uk>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    This program is free software; you can redistribute it and/or modify
 | 
					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
 | 
					it under the terms of the GNU General Public License as published by
 | 
				
			||||||
    the Free Software Foundation; either version 2 of the License, or
 | 
					the Free Software Foundation; either version 2 of the License, or
 | 
				
			||||||
    (at your option) any later version.
 | 
					(at your option) any later version.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    This program is distributed in the hope that it will be useful,
 | 
					This program is distributed in the hope that it will be useful,
 | 
				
			||||||
    but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
					but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
				
			||||||
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
					MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
				
			||||||
    GNU General Public License for more details.
 | 
					GNU General Public License for more details.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    You should have received a copy of the GNU General Public License along
 | 
					You should have received a copy of the GNU General Public License along
 | 
				
			||||||
    with this program; if not, write to the Free Software Foundation, Inc.,
 | 
					with this program; if not, write to the Free Software Foundation, Inc.,
 | 
				
			||||||
    51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 | 
					51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    See the full license in the file "LICENSE" in the top level distribution directory
 | 
					See the full license in the file "LICENSE" in the top level distribution
 | 
				
			||||||
    *************************************************************************************/
 | 
					directory
 | 
				
			||||||
    /*  END LEGAL */
 | 
					*************************************************************************************/
 | 
				
			||||||
 | 
					/*  END LEGAL */
 | 
				
			||||||
#include <Grid/Grid.h>
 | 
					#include <Grid/Grid.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
using namespace std;
 | 
					using namespace std;
 | 
				
			||||||
using namespace Grid;
 | 
					using namespace Grid;
 | 
				
			||||||
using namespace Grid::QCD;
 | 
					using namespace Grid::QCD;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
template<class d>
 | 
					template <class d>
 | 
				
			||||||
struct scal {
 | 
					struct scal {
 | 
				
			||||||
  d internal;
 | 
					  d internal;
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  Gamma::GammaMatrix Gmu [] = {
 | 
					Gamma::GammaMatrix Gmu[] = {Gamma::GammaX, Gamma::GammaY, Gamma::GammaZ,
 | 
				
			||||||
    Gamma::GammaX,
 | 
					                            Gamma::GammaT};
 | 
				
			||||||
    Gamma::GammaY,
 | 
					 | 
				
			||||||
    Gamma::GammaZ,
 | 
					 | 
				
			||||||
    Gamma::GammaT
 | 
					 | 
				
			||||||
  };
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
int main (int argc, char ** argv)
 | 
					int main(int argc, char** argv) {
 | 
				
			||||||
{
 | 
					  Grid_init(&argc, &argv);
 | 
				
			||||||
  Grid_init(&argc,&argv);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
  const int Ls=8;
 | 
					  const int Ls = 16;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  GridCartesian         * UGrid   = SpaceTimeGrid::makeFourDimGrid(GridDefaultLatt(), GridDefaultSimd(Nd,vComplex::Nsimd()),GridDefaultMpi());
 | 
					  GridCartesian* UGrid = SpaceTimeGrid::makeFourDimGrid(
 | 
				
			||||||
  GridRedBlackCartesian * UrbGrid = SpaceTimeGrid::makeFourDimRedBlackGrid(UGrid);
 | 
					      GridDefaultLatt(), GridDefaultSimd(Nd, vComplex::Nsimd()),
 | 
				
			||||||
  GridCartesian         * FGrid   = SpaceTimeGrid::makeFiveDimGrid(Ls,UGrid);
 | 
					      GridDefaultMpi());
 | 
				
			||||||
  GridRedBlackCartesian * FrbGrid = SpaceTimeGrid::makeFiveDimRedBlackGrid(Ls,UGrid);
 | 
					  GridRedBlackCartesian* UrbGrid =
 | 
				
			||||||
 | 
					      SpaceTimeGrid::makeFourDimRedBlackGrid(UGrid);
 | 
				
			||||||
 | 
					  GridCartesian* FGrid = SpaceTimeGrid::makeFiveDimGrid(Ls, UGrid);
 | 
				
			||||||
 | 
					  GridRedBlackCartesian* FrbGrid =
 | 
				
			||||||
 | 
					      SpaceTimeGrid::makeFiveDimRedBlackGrid(Ls, UGrid);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  std::vector<int> seeds4({1,2,3,4});
 | 
					  std::vector<int> seeds4({1, 2, 3, 4});
 | 
				
			||||||
  std::vector<int> seeds5({5,6,7,8});
 | 
					  std::vector<int> seeds5({5, 6, 7, 8});
 | 
				
			||||||
  GridParallelRNG          RNG5(FGrid);  RNG5.SeedFixedIntegers(seeds5);
 | 
					  GridParallelRNG RNG5(FGrid);
 | 
				
			||||||
  GridParallelRNG          RNG4(UGrid);  RNG4.SeedFixedIntegers(seeds4);
 | 
					  RNG5.SeedFixedIntegers(seeds5);
 | 
				
			||||||
 | 
					  GridParallelRNG RNG4(UGrid);
 | 
				
			||||||
 | 
					  RNG4.SeedFixedIntegers(seeds4);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  LatticeFermion    src(FGrid); random(RNG5,src);
 | 
					  LatticeFermion src(FGrid);
 | 
				
			||||||
  LatticeFermion result(FGrid); result=zero;
 | 
					  random(RNG5, src);
 | 
				
			||||||
 | 
					  LatticeFermion result(FGrid);
 | 
				
			||||||
 | 
					  result = zero;
 | 
				
			||||||
  LatticeGaugeField Umu(UGrid);
 | 
					  LatticeGaugeField Umu(UGrid);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  SU3::HotConfiguration(RNG4,Umu);
 | 
					  SU3::HotConfiguration(RNG4, Umu);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  std::vector<LatticeColourMatrix> U(4,UGrid);
 | 
					  std::cout << GridLogMessage << "Lattice dimensions: " << GridDefaultLatt()
 | 
				
			||||||
  for(int mu=0;mu<Nd;mu++){
 | 
					            << "   Ls: " << Ls << std::endl;
 | 
				
			||||||
    U[mu] = PeekIndex<LorentzIndex>(Umu,mu);
 | 
					
 | 
				
			||||||
 | 
					  std::vector<LatticeColourMatrix> U(4, UGrid);
 | 
				
			||||||
 | 
					  for (int mu = 0; mu < Nd; mu++) {
 | 
				
			||||||
 | 
					    U[mu] = PeekIndex<LorentzIndex>(Umu, mu);
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  RealD mass=0.1;
 | 
					  RealD mass = 0.01;
 | 
				
			||||||
  RealD M5=1.8;
 | 
					  RealD M5 = 1.8;
 | 
				
			||||||
  DomainWallFermionR Ddwf(Umu,*FGrid,*FrbGrid,*UGrid,*UrbGrid,mass,M5);
 | 
					  DomainWallFermionR Ddwf(Umu, *FGrid, *FrbGrid, *UGrid, *UrbGrid, mass, M5);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  LatticeFermion    src_o(FrbGrid);
 | 
					  LatticeFermion src_o(FrbGrid);
 | 
				
			||||||
  LatticeFermion result_o(FrbGrid);
 | 
					  LatticeFermion result_o(FrbGrid);
 | 
				
			||||||
  pickCheckerboard(Odd,src_o,src);
 | 
					  pickCheckerboard(Odd, src_o, src);
 | 
				
			||||||
  result_o=zero;
 | 
					  result_o = zero;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  SchurDiagMooeeOperator<DomainWallFermionR,LatticeFermion> HermOpEO(Ddwf);
 | 
					  GridStopWatch CGTimer;
 | 
				
			||||||
  ConjugateGradient<LatticeFermion> CG(1.0e-8,10000);
 | 
					
 | 
				
			||||||
  CG(HermOpEO,src_o,result_o);
 | 
					  SchurDiagMooeeOperator<DomainWallFermionR, LatticeFermion> HermOpEO(Ddwf);
 | 
				
			||||||
 | 
					  ConjugateGradient<LatticeFermion> CG(1.0e-8, 10000, 0);// switch off the assert
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  CGTimer.Start();
 | 
				
			||||||
 | 
					  CG(HermOpEO, src_o, result_o);
 | 
				
			||||||
 | 
					  CGTimer.Stop();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  std::cout << GridLogMessage << "Total CG time : " << CGTimer.Elapsed()
 | 
				
			||||||
 | 
					            << std::endl;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  std::cout << GridLogMessage << "######## Dhop calls summary" << std::endl;
 | 
				
			||||||
 | 
					  Ddwf.Report();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  Grid_finalize();
 | 
					  Grid_finalize();
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -84,5 +84,6 @@ int main (int argc, char ** argv)
 | 
				
			|||||||
  ConjugateGradient<LatticeFermion> CG(1.0e-8,10000);
 | 
					  ConjugateGradient<LatticeFermion> CG(1.0e-8,10000);
 | 
				
			||||||
  CG(HermOpEO,src_o,result_o);
 | 
					  CG(HermOpEO,src_o,result_o);
 | 
				
			||||||
  
 | 
					  
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  Grid_finalize();
 | 
					  Grid_finalize();
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user