mirror of
				https://github.com/paboyle/Grid.git
				synced 2025-11-04 14:04:32 +00:00 
			
		
		
		
	Large scale change to support 5d fermion formulations.
Have 5d replicated wilson with 4d gauge working and matrix regressing to Ls copies of wilson.
This commit is contained in:
		@@ -82,7 +82,7 @@ int main (int argc, char ** argv)
 | 
			
		||||
      double rbytes    = xbytes;
 | 
			
		||||
      double bidibytes = xbytes+rbytes;
 | 
			
		||||
 | 
			
		||||
      double time = stop-start;
 | 
			
		||||
      double time = stop-start; // microseconds
 | 
			
		||||
 | 
			
		||||
      std::cout << lat<<"\t\t"<<Ls<<"\t\t"<<bytes<<"\t\t"<<xbytes/time<<"\t\t"<<bidibytes/time<<std::endl;
 | 
			
		||||
    }
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										145
									
								
								benchmarks/Grid_dwf.cc
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										145
									
								
								benchmarks/Grid_dwf.cc
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,145 @@
 | 
			
		||||
#include <Grid.h>
 | 
			
		||||
 | 
			
		||||
using namespace std;
 | 
			
		||||
using namespace Grid;
 | 
			
		||||
using namespace Grid::QCD;
 | 
			
		||||
 | 
			
		||||
template<class d>
 | 
			
		||||
struct scal {
 | 
			
		||||
  d internal;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
  Gamma::GammaMatrix Gmu [] = {
 | 
			
		||||
    Gamma::GammaX,
 | 
			
		||||
    Gamma::GammaY,
 | 
			
		||||
    Gamma::GammaZ,
 | 
			
		||||
    Gamma::GammaT
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
int main (int argc, char ** argv)
 | 
			
		||||
{
 | 
			
		||||
  Grid_init(&argc,&argv);
 | 
			
		||||
 | 
			
		||||
  int threads = GridThread::GetThreads();
 | 
			
		||||
  std::cout << "Grid is setup to use "<<threads<<" threads"<<std::endl;
 | 
			
		||||
 | 
			
		||||
  std::vector<int> latt4 = GridDefaultLatt();
 | 
			
		||||
  std::vector<int> simd4 = GridDefaultSimd(Nd,vComplexF::Nsimd());
 | 
			
		||||
  std::vector<int> mpi4  = GridDefaultMpi();
 | 
			
		||||
 | 
			
		||||
  assert(latt4.size()==4 ); 
 | 
			
		||||
  assert(simd4.size()==4 );
 | 
			
		||||
  assert(mpi4.size() ==4 );
 | 
			
		||||
 | 
			
		||||
  const int Ls=1;
 | 
			
		||||
  std::vector<int> latt5({Ls,latt4[0],latt4[1],latt4[2],latt4[3]});
 | 
			
		||||
  std::vector<int> simd5({1 ,simd4[0],simd4[1],simd4[2],simd4[3]}); 
 | 
			
		||||
  std::vector<int>  mpi5({1 , mpi4[0], mpi4[1], mpi4[2], mpi4[3]}); 
 | 
			
		||||
  std::vector<int>   cb5({0,1,1,1,1}); // Checkerboard 4d only
 | 
			
		||||
  int                cbd=1;            // use dim-1 to reduce
 | 
			
		||||
 | 
			
		||||
  // Four dim grid for gauge field U
 | 
			
		||||
  GridCartesian               UGrid(latt4,simd4,mpi4); 
 | 
			
		||||
  GridRedBlackCartesian     UrbGrid(&UGrid);
 | 
			
		||||
 | 
			
		||||
  // Five dim grid for fermions F
 | 
			
		||||
  GridCartesian               FGrid(latt5,simd5,mpi5); 
 | 
			
		||||
  GridRedBlackCartesian     FrbGrid(latt5,simd5,mpi5,cb5,cbd); 
 | 
			
		||||
 | 
			
		||||
  std::vector<int> seeds4({1,2,3,4});
 | 
			
		||||
  std::vector<int> seeds5({5,6,7,8});
 | 
			
		||||
 | 
			
		||||
  GridParallelRNG          RNG5(&FGrid);  RNG5.SeedFixedIntegers(seeds5);
 | 
			
		||||
  LatticeFermion src   (&FGrid); random(RNG5,src);
 | 
			
		||||
  LatticeFermion result(&FGrid); result=zero;
 | 
			
		||||
  LatticeFermion    ref(&FGrid);    ref=zero;
 | 
			
		||||
  LatticeFermion    tmp(&FGrid);
 | 
			
		||||
  LatticeFermion    err(&FGrid);
 | 
			
		||||
 | 
			
		||||
  ColourMatrix cm = Complex(1.0,0.0);
 | 
			
		||||
 | 
			
		||||
  GridParallelRNG          RNG4(&UGrid);  RNG4.SeedFixedIntegers(seeds4);
 | 
			
		||||
  LatticeGaugeField Umu(&UGrid); random(RNG4,Umu);
 | 
			
		||||
  LatticeGaugeField Umu5d(&FGrid); 
 | 
			
		||||
 | 
			
		||||
  // replicate across fifth dimension
 | 
			
		||||
  for(int ss=0;ss<Umu._grid->oSites();ss++){
 | 
			
		||||
    for(int s=0;s<Ls;s++){
 | 
			
		||||
      Umu5d._odata[Ls*ss+s] = Umu._odata[ss];
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  ////////////////////////////////////
 | 
			
		||||
  // Naive wilson implementation
 | 
			
		||||
  ////////////////////////////////////
 | 
			
		||||
  std::vector<LatticeColourMatrix> U(4,&FGrid);
 | 
			
		||||
  for(int mu=0;mu<Nd;mu++){
 | 
			
		||||
    U[mu] = peekIndex<LorentzIndex>(Umu5d,mu);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  if (1)
 | 
			
		||||
  {
 | 
			
		||||
    ref = zero;
 | 
			
		||||
    for(int mu=0;mu<Nd;mu++){
 | 
			
		||||
 | 
			
		||||
      tmp = U[mu]*Cshift(src,mu+1,1);
 | 
			
		||||
      ref=ref + tmp + Gamma(Gmu[mu])*tmp;
 | 
			
		||||
 | 
			
		||||
      tmp =adj(U[mu])*src;
 | 
			
		||||
      tmp =Cshift(tmp,mu+1,-1);
 | 
			
		||||
      ref=ref + tmp - Gamma(Gmu[mu])*tmp;
 | 
			
		||||
    }
 | 
			
		||||
    ref = -0.5*ref;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  RealD mass=0.1;
 | 
			
		||||
  FiveDimWilsonFermion Dw(Umu,FGrid,FrbGrid,UGrid,UrbGrid,mass);
 | 
			
		||||
  
 | 
			
		||||
  std::cout << "Calling Dw"<<std::endl;
 | 
			
		||||
  int ncall=1000;
 | 
			
		||||
  double t0=usecond();
 | 
			
		||||
  for(int i=0;i<ncall;i++){
 | 
			
		||||
    Dw.Dhop(src,result,0);
 | 
			
		||||
  }
 | 
			
		||||
  double t1=usecond();
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
  double volume=Ls;  for(int mu=0;mu<Nd;mu++) volume=volume*latt4[mu];
 | 
			
		||||
  double flops=1344*volume*ncall;
 | 
			
		||||
  
 | 
			
		||||
  std::cout << "Called Dw"<<std::endl;
 | 
			
		||||
  std::cout << "norm result "<< norm2(result)<<std::endl;
 | 
			
		||||
  std::cout << "norm ref    "<< norm2(ref)<<std::endl;
 | 
			
		||||
  std::cout << "mflop/s =   "<< flops/(t1-t0)<<std::endl;
 | 
			
		||||
  err = ref-result; 
 | 
			
		||||
  std::cout << "norm diff   "<< norm2(err)<<std::endl;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
  if (1)
 | 
			
		||||
  { // Naive wilson dag implementation
 | 
			
		||||
    ref = zero;
 | 
			
		||||
    for(int mu=0;mu<Nd;mu++){
 | 
			
		||||
 | 
			
		||||
      //    ref =  src - Gamma(Gamma::GammaX)* src ; // 1+gamma_x
 | 
			
		||||
      tmp = U[mu]*Cshift(src,mu+1,1);
 | 
			
		||||
      for(int i=0;i<ref._odata.size();i++){
 | 
			
		||||
	ref._odata[i]+= tmp._odata[i] - Gamma(Gmu[mu])*tmp._odata[i]; ;
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      tmp =adj(U[mu])*src;
 | 
			
		||||
      tmp =Cshift(tmp,mu+1,-1);
 | 
			
		||||
      for(int i=0;i<ref._odata.size();i++){
 | 
			
		||||
	ref._odata[i]+= tmp._odata[i] + Gamma(Gmu[mu])*tmp._odata[i]; ;
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
    ref = -0.5*ref;
 | 
			
		||||
  }
 | 
			
		||||
  Dw.Dhop(src,result,1);
 | 
			
		||||
  std::cout << "Called DwDag"<<std::endl;
 | 
			
		||||
  std::cout << "norm result "<< norm2(result)<<std::endl;
 | 
			
		||||
  std::cout << "norm ref    "<< norm2(ref)<<std::endl;
 | 
			
		||||
  err = ref-result; 
 | 
			
		||||
  std::cout << "norm diff   "<< norm2(err)<<std::endl;
 | 
			
		||||
 | 
			
		||||
  Grid_finalize();
 | 
			
		||||
}
 | 
			
		||||
@@ -49,6 +49,7 @@ int main (int argc, char ** argv)
 | 
			
		||||
  }  
 | 
			
		||||
 | 
			
		||||
  // Only one non-zero (y)
 | 
			
		||||
#if 0
 | 
			
		||||
  Umu=zero;
 | 
			
		||||
  Complex cone(1.0,0.0);
 | 
			
		||||
  for(int nn=0;nn<Nd;nn++){
 | 
			
		||||
@@ -59,6 +60,7 @@ int main (int argc, char ** argv)
 | 
			
		||||
    }
 | 
			
		||||
    pokeIndex<LorentzIndex>(Umu,U[nn],nn);
 | 
			
		||||
  }
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
  for(int mu=0;mu<Nd;mu++){
 | 
			
		||||
    U[mu] = peekIndex<LorentzIndex>(Umu,mu);
 | 
			
		||||
@@ -80,9 +82,9 @@ int main (int argc, char ** argv)
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  ref = -0.5*ref;
 | 
			
		||||
  RealD mass=0.1;
 | 
			
		||||
  WilsonMatrix Dw(Umu,Grid,RBGrid,mass);
 | 
			
		||||
  WilsonFermion Dw(Umu,Grid,RBGrid,mass);
 | 
			
		||||
  
 | 
			
		||||
  std::cout << "Calling Dw"<<std::endl;
 | 
			
		||||
  int ncall=10000;
 | 
			
		||||
@@ -91,7 +93,7 @@ int main (int argc, char ** argv)
 | 
			
		||||
    Dw.Dhop(src,result,0);
 | 
			
		||||
  }
 | 
			
		||||
  double t1=usecond();
 | 
			
		||||
  double flops=1320*volume*ncall;
 | 
			
		||||
  double flops=1344*volume*ncall;
 | 
			
		||||
  
 | 
			
		||||
  std::cout << "Called Dw"<<std::endl;
 | 
			
		||||
  std::cout << "norm result "<< norm2(result)<<std::endl;
 | 
			
		||||
@@ -129,6 +131,7 @@ int main (int argc, char ** argv)
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
  ref = -0.5*ref;
 | 
			
		||||
  Dw.Dhop(src,result,1);
 | 
			
		||||
  std::cout << "Called DwDag"<<std::endl;
 | 
			
		||||
  std::cout << "norm result "<< norm2(result)<<std::endl;
 | 
			
		||||
 
 | 
			
		||||
@@ -42,9 +42,9 @@ int main (int argc, char ** argv)
 | 
			
		||||
  }
 | 
			
		||||
  
 | 
			
		||||
  RealD mass=0.5;
 | 
			
		||||
  WilsonMatrix Dw(Umu,Grid,RBGrid,mass);
 | 
			
		||||
  WilsonFermion Dw(Umu,Grid,RBGrid,mass);
 | 
			
		||||
 | 
			
		||||
  //  HermitianOperator<WilsonMatrix,LatticeFermion> HermOp(Dw);
 | 
			
		||||
  //  HermitianOperator<WilsonFermion,LatticeFermion> HermOp(Dw);
 | 
			
		||||
  //  ConjugateGradient<LatticeFermion> CG(1.0e-8,10000);
 | 
			
		||||
  //  CG(HermOp,src,result);
 | 
			
		||||
  
 | 
			
		||||
@@ -53,7 +53,7 @@ int main (int argc, char ** argv)
 | 
			
		||||
  pickCheckerboard(Odd,src_o,src);
 | 
			
		||||
  result_o=zero;
 | 
			
		||||
 | 
			
		||||
  HermitianCheckerBoardedOperator<WilsonMatrix,LatticeFermion> HermOpEO(Dw);
 | 
			
		||||
  HermitianCheckerBoardedOperator<WilsonFermion,LatticeFermion> HermOpEO(Dw);
 | 
			
		||||
  ConjugateGradient<LatticeFermion> CG(1.0e-8,10000);
 | 
			
		||||
  CG(HermOpEO,src_o,result_o);
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -37,7 +37,7 @@ int main (int argc, char ** argv)
 | 
			
		||||
  LatticeFermion resid(&Grid); 
 | 
			
		||||
 | 
			
		||||
  RealD mass=0.5;
 | 
			
		||||
  WilsonMatrix Dw(Umu,Grid,RBGrid,mass);
 | 
			
		||||
  WilsonFermion Dw(Umu,Grid,RBGrid,mass);
 | 
			
		||||
 | 
			
		||||
  ConjugateGradient<LatticeFermion> CG(1.0e-8,10000);
 | 
			
		||||
  SchurRedBlackSolve<LatticeFermion> SchurSolver(CG);
 | 
			
		||||
 
 | 
			
		||||
@@ -47,9 +47,9 @@ int main (int argc, char ** argv)
 | 
			
		||||
  }
 | 
			
		||||
  
 | 
			
		||||
  RealD mass=0.5;
 | 
			
		||||
  WilsonMatrix Dw(Umu,Grid,RBGrid,mass);
 | 
			
		||||
  WilsonFermion Dw(Umu,Grid,RBGrid,mass);
 | 
			
		||||
 | 
			
		||||
  HermitianOperator<WilsonMatrix,LatticeFermion> HermOp(Dw);
 | 
			
		||||
  HermitianOperator<WilsonFermion,LatticeFermion> HermOp(Dw);
 | 
			
		||||
  ConjugateGradient<LatticeFermion> CG(1.0e-8,10000);
 | 
			
		||||
  CG(HermOp,src,result);
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -60,7 +60,7 @@ int main (int argc, char ** argv)
 | 
			
		||||
 | 
			
		||||
  RealD mass=0.1;
 | 
			
		||||
 | 
			
		||||
  WilsonMatrix Dw(Umu,Grid,RBGrid,mass);
 | 
			
		||||
  WilsonFermion Dw(Umu,Grid,RBGrid,mass);
 | 
			
		||||
 | 
			
		||||
  LatticeFermion src_e   (&RBGrid);
 | 
			
		||||
  LatticeFermion src_o   (&RBGrid);
 | 
			
		||||
 
 | 
			
		||||
@@ -5,11 +5,14 @@ AM_LDFLAGS = -L$(top_builddir)/lib
 | 
			
		||||
#
 | 
			
		||||
# Test code
 | 
			
		||||
#
 | 
			
		||||
bin_PROGRAMS = Grid_wilson Grid_comms Grid_memory_bandwidth Grid_su3 Grid_wilson_cg_unprec Grid_wilson_evenodd  Grid_wilson_cg_prec Grid_wilson_cg_schur
 | 
			
		||||
bin_PROGRAMS = Grid_wilson Grid_comms Grid_memory_bandwidth Grid_su3 Grid_wilson_cg_unprec Grid_wilson_evenodd  Grid_wilson_cg_prec Grid_wilson_cg_schur Grid_dwf
 | 
			
		||||
 | 
			
		||||
Grid_wilson_SOURCES = Grid_wilson.cc
 | 
			
		||||
Grid_wilson_LDADD = -lGrid
 | 
			
		||||
 | 
			
		||||
Grid_dwf_SOURCES = Grid_dwf.cc
 | 
			
		||||
Grid_dwf_LDADD = -lGrid
 | 
			
		||||
 | 
			
		||||
Grid_wilson_evenodd_SOURCES = Grid_wilson_evenodd.cc
 | 
			
		||||
Grid_wilson_evenodd_LDADD = -lGrid
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -60,7 +60,7 @@
 | 
			
		||||
 | 
			
		||||
#include <Grid_algorithms.h>// subdir aggregate
 | 
			
		||||
 | 
			
		||||
#include <qcd/Grid_qcd.h>
 | 
			
		||||
#include <qcd/QCD.h>
 | 
			
		||||
#include <parallelIO/GridNerscIO.h>
 | 
			
		||||
 | 
			
		||||
namespace Grid {
 | 
			
		||||
 
 | 
			
		||||
@@ -142,7 +142,11 @@ void Grid_init(int *argc,char ***argv)
 | 
			
		||||
    Grid_quiesce_nodes();
 | 
			
		||||
  }
 | 
			
		||||
  if( GridCmdOptionExists(*argv,*argv+*argc,"--dslash-opt") ){
 | 
			
		||||
    WilsonMatrix::HandOptDslash=1;
 | 
			
		||||
    WilsonFermion::HandOptDslash=1;
 | 
			
		||||
    FiveDimWilsonFermion::HandOptDslash=1;
 | 
			
		||||
  }
 | 
			
		||||
  if( GridCmdOptionExists(*argv,*argv+*argc,"--lebesgue") ){
 | 
			
		||||
    LebesgueOrder::UseLebesgueOrder=1;
 | 
			
		||||
  }
 | 
			
		||||
  GridParseLayout(*argv,*argc,
 | 
			
		||||
		  Grid_default_latt,
 | 
			
		||||
 
 | 
			
		||||
@@ -1,6 +1,8 @@
 | 
			
		||||
#ifndef GRID_STENCIL_H
 | 
			
		||||
#define GRID_STENCIL_H
 | 
			
		||||
 | 
			
		||||
#include <stencil/Grid_lebesgue.h>   // subdir aggregate
 | 
			
		||||
 | 
			
		||||
//////////////////////////////////////////////////////////////////////////////////////////
 | 
			
		||||
// Must not lose sight that goal is to be able to construct really efficient
 | 
			
		||||
// gather to a point stencil code. CSHIFT is not the best way, so need
 | 
			
		||||
@@ -40,28 +42,11 @@
 | 
			
		||||
namespace Grid {
 | 
			
		||||
  
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
  class CartesianStencil { // Stencil runs along coordinate axes only; NO diagonal fill in.
 | 
			
		||||
  public:
 | 
			
		||||
 | 
			
		||||
      typedef uint32_t StencilInteger;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
      StencilInteger alignup(StencilInteger n){
 | 
			
		||||
	n--;           // 1000 0011 --> 1000 0010
 | 
			
		||||
	n |= n >> 1;   // 1000 0010 | 0100 0001 = 1100 0011
 | 
			
		||||
	n |= n >> 2;   // 1100 0011 | 0011 0000 = 1111 0011
 | 
			
		||||
	n |= n >> 4;   // 1111 0011 | 0000 1111 = 1111 1111
 | 
			
		||||
	n |= n >> 8;   // ... (At this point all bits are 1, so further bitwise-or
 | 
			
		||||
	n |= n >> 16;  //      operations produce no effect.)
 | 
			
		||||
	n++;           // 1111 1111 --> 1 0000 0000
 | 
			
		||||
	return n;
 | 
			
		||||
      };
 | 
			
		||||
      void LebesgueOrder(void);
 | 
			
		||||
 | 
			
		||||
      std::vector<StencilInteger> _LebesgueReorder;
 | 
			
		||||
 | 
			
		||||
      int                               _checkerboard;
 | 
			
		||||
      int                               _npoints; // Move to template param?
 | 
			
		||||
      GridBase *                        _grid;
 | 
			
		||||
@@ -131,8 +116,8 @@ namespace Grid {
 | 
			
		||||
	  // Gather phase
 | 
			
		||||
	  int sshift [2];
 | 
			
		||||
	  if ( comm_dim ) {
 | 
			
		||||
	    sshift[0] = _grid->CheckerBoardShift(_checkerboard,dimension,shift,0);
 | 
			
		||||
	    sshift[1] = _grid->CheckerBoardShift(_checkerboard,dimension,shift,1);
 | 
			
		||||
	    sshift[0] = _grid->CheckerBoardShiftForCB(_checkerboard,dimension,shift,Even);
 | 
			
		||||
	    sshift[1] = _grid->CheckerBoardShiftForCB(_checkerboard,dimension,shift,Odd);
 | 
			
		||||
	    if ( sshift[0] == sshift[1] ) {
 | 
			
		||||
	      if (splice_dim) {
 | 
			
		||||
		GatherStartCommsSimd(source,dimension,shift,0x3,u_comm_buf,u_comm_offset,compress);
 | 
			
		||||
@@ -179,8 +164,8 @@ namespace Grid {
 | 
			
		||||
	  std::vector<cobj,alignedAllocator<cobj> > send_buf(buffer_size); // hmm...
 | 
			
		||||
	  std::vector<cobj,alignedAllocator<cobj> > recv_buf(buffer_size);
 | 
			
		||||
	  
 | 
			
		||||
	  int cb= (cbmask==0x2)? 1 : 0;
 | 
			
		||||
	  int sshift= _grid->CheckerBoardShift(rhs.checkerboard,dimension,shift,cb);
 | 
			
		||||
	  int cb= (cbmask==0x2)? Odd : Even;
 | 
			
		||||
	  int sshift= _grid->CheckerBoardShiftForCB(rhs.checkerboard,dimension,shift,cb);
 | 
			
		||||
	  
 | 
			
		||||
	  for(int x=0;x<rd;x++){       
 | 
			
		||||
	    
 | 
			
		||||
@@ -266,8 +251,8 @@ namespace Grid {
 | 
			
		||||
	  // Work out what to send where
 | 
			
		||||
	  ///////////////////////////////////////////
 | 
			
		||||
 | 
			
		||||
	  int cb    = (cbmask==0x2)? 1 : 0;
 | 
			
		||||
	  int sshift= _grid->CheckerBoardShift(rhs.checkerboard,dimension,shift,cb);
 | 
			
		||||
	  int cb    = (cbmask==0x2)? Odd : Even;
 | 
			
		||||
	  int sshift= _grid->CheckerBoardShiftForCB(rhs.checkerboard,dimension,shift,cb);
 | 
			
		||||
	  
 | 
			
		||||
	  // loop over outer coord planes orthog to dim
 | 
			
		||||
	  for(int x=0;x<rd;x++){       
 | 
			
		||||
 
 | 
			
		||||
@@ -9,7 +9,7 @@
 | 
			
		||||
 | 
			
		||||
#ifdef GRID_OMP
 | 
			
		||||
#include <omp.h>
 | 
			
		||||
#define PARALLEL_FOR_LOOP _Pragma("omp parallel for")
 | 
			
		||||
#define PARALLEL_FOR_LOOP _Pragma("omp parallel for ")
 | 
			
		||||
#define PARALLEL_NESTED_LOOP2 _Pragma("omp parallel for collapse(2)")
 | 
			
		||||
#else
 | 
			
		||||
#define PARALLEL_FOR_LOOP 
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										166
									
								
								lib/Makefile.am
									
									
									
									
									
								
							
							
						
						
									
										166
									
								
								lib/Makefile.am
									
									
									
									
									
								
							@@ -16,87 +16,103 @@ endif
 | 
			
		||||
lib_LIBRARIES = libGrid.a
 | 
			
		||||
libGrid_a_SOURCES =				\
 | 
			
		||||
	Grid_init.cc				\
 | 
			
		||||
	stencil/Grid_lebesgue.cc		\
 | 
			
		||||
	stencil/Grid_stencil_common.cc		\
 | 
			
		||||
	qcd/Grid_qcd_dirac.cc			\
 | 
			
		||||
	qcd/Grid_qcd_dhop.cc			\
 | 
			
		||||
	qcd/Grid_qcd_dhop_hand.cc		\
 | 
			
		||||
	qcd/Grid_qcd_wilson_dop.cc		\
 | 
			
		||||
	algorithms/approx/Zolotarev.cc		\
 | 
			
		||||
	algorithms/approx/Remez.cc		\
 | 
			
		||||
	qcd/action/fermion/FiveDimWilsonFermion.cc\
 | 
			
		||||
	qcd/action/fermion/WilsonFermion.cc\
 | 
			
		||||
	qcd/action/fermion/WilsonKernels.cc\
 | 
			
		||||
	qcd/action/fermion/WilsonKernelsHand.cc\
 | 
			
		||||
	qcd/Dirac.cc\
 | 
			
		||||
	$(extra_sources)
 | 
			
		||||
 | 
			
		||||
#
 | 
			
		||||
# Include files
 | 
			
		||||
#
 | 
			
		||||
nobase_include_HEADERS = algorithms/approx/bigfloat.h		\
 | 
			
		||||
	algorithms/approx/Chebyshev.h				\
 | 
			
		||||
	algorithms/approx/Remez.h				\
 | 
			
		||||
	algorithms/approx/Zolotarev.h				\
 | 
			
		||||
	algorithms/iterative/ConjugateGradient.h		\
 | 
			
		||||
	algorithms/iterative/NormalEquations.h			\
 | 
			
		||||
	algorithms/iterative/SchurRedBlack.h			\
 | 
			
		||||
	algorithms/LinearOperator.h				\
 | 
			
		||||
	algorithms/SparseMatrix.h				\
 | 
			
		||||
	cartesian/Grid_cartesian_base.h				\
 | 
			
		||||
	cartesian/Grid_cartesian_full.h				\
 | 
			
		||||
	cartesian/Grid_cartesian_red_black.h			\
 | 
			
		||||
	communicator/Grid_communicator_base.h			\
 | 
			
		||||
	cshift/Grid_cshift_common.h				\
 | 
			
		||||
	cshift/Grid_cshift_mpi.h				\
 | 
			
		||||
	cshift/Grid_cshift_none.h				\
 | 
			
		||||
	Grid.h							\
 | 
			
		||||
	Grid_algorithms.h					\
 | 
			
		||||
	Grid_aligned_allocator.h				\
 | 
			
		||||
	Grid_cartesian.h					\
 | 
			
		||||
	Grid_communicator.h					\
 | 
			
		||||
	Grid_comparison.h					\
 | 
			
		||||
	Grid_cshift.h						\
 | 
			
		||||
	Grid_extract.h						\
 | 
			
		||||
	Grid_lattice.h						\
 | 
			
		||||
	Grid_math.h						\
 | 
			
		||||
	Grid_simd.h						\
 | 
			
		||||
	Grid_stencil.h						\
 | 
			
		||||
	Grid_threads.h						\
 | 
			
		||||
	lattice/Grid_lattice_arith.h				\
 | 
			
		||||
	lattice/Grid_lattice_base.h				\
 | 
			
		||||
	lattice/Grid_lattice_comparison.h			\
 | 
			
		||||
	lattice/Grid_lattice_conformable.h			\
 | 
			
		||||
	lattice/Grid_lattice_coordinate.h			\
 | 
			
		||||
	lattice/Grid_lattice_ET.h				\
 | 
			
		||||
	lattice/Grid_lattice_local.h				\
 | 
			
		||||
	lattice/Grid_lattice_overload.h				\
 | 
			
		||||
	lattice/Grid_lattice_peekpoke.h				\
 | 
			
		||||
	lattice/Grid_lattice_reality.h				\
 | 
			
		||||
	lattice/Grid_lattice_reduction.h			\
 | 
			
		||||
	lattice/Grid_lattice_rng.h				\
 | 
			
		||||
	lattice/Grid_lattice_trace.h				\
 | 
			
		||||
	lattice/Grid_lattice_transfer.h				\
 | 
			
		||||
	lattice/Grid_lattice_transpose.h			\
 | 
			
		||||
	lattice/Grid_lattice_where.h				\
 | 
			
		||||
	math/Grid_math_arith.h					\
 | 
			
		||||
	math/Grid_math_arith_add.h				\
 | 
			
		||||
	math/Grid_math_arith_mac.h				\
 | 
			
		||||
	math/Grid_math_arith_mul.h				\
 | 
			
		||||
	math/Grid_math_arith_scalar.h				\
 | 
			
		||||
	math/Grid_math_arith_sub.h				\
 | 
			
		||||
	math/Grid_math_inner.h					\
 | 
			
		||||
	math/Grid_math_outer.h					\
 | 
			
		||||
	math/Grid_math_peek.h					\
 | 
			
		||||
	math/Grid_math_poke.h					\
 | 
			
		||||
	math/Grid_math_reality.h				\
 | 
			
		||||
	math/Grid_math_tensors.h				\
 | 
			
		||||
	math/Grid_math_trace.h					\
 | 
			
		||||
	math/Grid_math_traits.h					\
 | 
			
		||||
	math/Grid_math_transpose.h				\
 | 
			
		||||
	parallelIO/GridNerscIO.h				\
 | 
			
		||||
	qcd/Grid_qcd.h						\
 | 
			
		||||
	qcd/Grid_qcd_2spinor.h					\
 | 
			
		||||
	qcd/Grid_qcd_dirac.h					\
 | 
			
		||||
	qcd/Grid_qcd_wilson_dop.h				\
 | 
			
		||||
	simd/Grid_vector_types.h				\
 | 
			
		||||
	simd/Grid_sse4.h					\
 | 
			
		||||
	simd/Grid_avx.h						\
 | 
			
		||||
	simd/Grid_avx512.h					
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
nobase_include_HEADERS=\
 | 
			
		||||
		./algorithms/approx/bigfloat.h\
 | 
			
		||||
		./algorithms/approx/bigfloat_double.h\
 | 
			
		||||
		./algorithms/approx/Chebyshev.h\
 | 
			
		||||
		./algorithms/approx/Remez.h\
 | 
			
		||||
		./algorithms/approx/Zolotarev.h\
 | 
			
		||||
		./algorithms/iterative/ConjugateGradient.h\
 | 
			
		||||
		./algorithms/iterative/NormalEquations.h\
 | 
			
		||||
		./algorithms/iterative/SchurRedBlack.h\
 | 
			
		||||
		./algorithms/LinearOperator.h\
 | 
			
		||||
		./algorithms/SparseMatrix.h\
 | 
			
		||||
		./cartesian/Grid_cartesian_base.h\
 | 
			
		||||
		./cartesian/Grid_cartesian_full.h\
 | 
			
		||||
		./cartesian/Grid_cartesian_red_black.h\
 | 
			
		||||
		./communicator/Grid_communicator_base.h\
 | 
			
		||||
		./cshift/Grid_cshift_common.h\
 | 
			
		||||
		./cshift/Grid_cshift_mpi.h\
 | 
			
		||||
		./cshift/Grid_cshift_none.h\
 | 
			
		||||
		./Grid.h\
 | 
			
		||||
		./Grid_algorithms.h\
 | 
			
		||||
		./Grid_aligned_allocator.h\
 | 
			
		||||
		./Grid_cartesian.h\
 | 
			
		||||
		./Grid_communicator.h\
 | 
			
		||||
		./Grid_comparison.h\
 | 
			
		||||
		./Grid_config.h\
 | 
			
		||||
		./Grid_cshift.h\
 | 
			
		||||
		./Grid_extract.h\
 | 
			
		||||
		./Grid_lattice.h\
 | 
			
		||||
		./Grid_math.h\
 | 
			
		||||
		./Grid_simd.h\
 | 
			
		||||
		./Grid_stencil.h\
 | 
			
		||||
		./Grid_threads.h\
 | 
			
		||||
		./lattice/Grid_lattice_arith.h\
 | 
			
		||||
		./lattice/Grid_lattice_base.h\
 | 
			
		||||
		./lattice/Grid_lattice_comparison.h\
 | 
			
		||||
		./lattice/Grid_lattice_conformable.h\
 | 
			
		||||
		./lattice/Grid_lattice_coordinate.h\
 | 
			
		||||
		./lattice/Grid_lattice_ET.h\
 | 
			
		||||
		./lattice/Grid_lattice_local.h\
 | 
			
		||||
		./lattice/Grid_lattice_overload.h\
 | 
			
		||||
		./lattice/Grid_lattice_peekpoke.h\
 | 
			
		||||
		./lattice/Grid_lattice_reality.h\
 | 
			
		||||
		./lattice/Grid_lattice_reduction.h\
 | 
			
		||||
		./lattice/Grid_lattice_rng.h\
 | 
			
		||||
		./lattice/Grid_lattice_trace.h\
 | 
			
		||||
		./lattice/Grid_lattice_transfer.h\
 | 
			
		||||
		./lattice/Grid_lattice_transpose.h\
 | 
			
		||||
		./lattice/Grid_lattice_where.h\
 | 
			
		||||
		./math/Grid_math_arith.h\
 | 
			
		||||
		./math/Grid_math_arith_add.h\
 | 
			
		||||
		./math/Grid_math_arith_mac.h\
 | 
			
		||||
		./math/Grid_math_arith_mul.h\
 | 
			
		||||
		./math/Grid_math_arith_scalar.h\
 | 
			
		||||
		./math/Grid_math_arith_sub.h\
 | 
			
		||||
		./math/Grid_math_inner.h\
 | 
			
		||||
		./math/Grid_math_outer.h\
 | 
			
		||||
		./math/Grid_math_peek.h\
 | 
			
		||||
		./math/Grid_math_poke.h\
 | 
			
		||||
		./math/Grid_math_reality.h\
 | 
			
		||||
		./math/Grid_math_tensors.h\
 | 
			
		||||
		./math/Grid_math_trace.h\
 | 
			
		||||
		./math/Grid_math_traits.h\
 | 
			
		||||
		./math/Grid_math_transpose.h\
 | 
			
		||||
		./parallelIO/GridNerscIO.h\
 | 
			
		||||
		./qcd/action/Actions.h\
 | 
			
		||||
		./qcd/action/fermion/FermionAction.h\
 | 
			
		||||
		./qcd/action/fermion/FiveDimWilsonFermion.h\
 | 
			
		||||
		./qcd/action/fermion/WilsonCompressor.h\
 | 
			
		||||
		./qcd/action/fermion/WilsonFermion.h\
 | 
			
		||||
		./qcd/action/fermion/WilsonKernels.h\
 | 
			
		||||
		./qcd/Dirac.h\
 | 
			
		||||
		./qcd/QCD.h\
 | 
			
		||||
		./qcd/TwoSpinor.h\
 | 
			
		||||
		./qcd/FermionAction.h\
 | 
			
		||||
		./simd/Grid_avx.h\
 | 
			
		||||
		./simd/Grid_avx512.h\
 | 
			
		||||
		./simd/Grid_qpx.h\
 | 
			
		||||
		./simd/Grid_sse4.h\
 | 
			
		||||
		./simd/Grid_vector_types.h\
 | 
			
		||||
		./simd/Old/Grid_vComplexD.h\
 | 
			
		||||
		./simd/Old/Grid_vComplexF.h\
 | 
			
		||||
		./simd/Old/Grid_vInteger.h\
 | 
			
		||||
		./simd/Old/Grid_vRealD.h\
 | 
			
		||||
		./simd/Old/Grid_vRealF.h\
 | 
			
		||||
		./stencil/Grid_lebesgue.h
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -10,7 +10,7 @@ namespace Grid {
 | 
			
		||||
  /////////////////////////////////////////////////////////////////////////////////////////////
 | 
			
		||||
    template<class Field> class SparseMatrixBase {
 | 
			
		||||
    public:
 | 
			
		||||
      GridBase *_grid;
 | 
			
		||||
      virtual GridBase *Grid(void) =0;
 | 
			
		||||
      // Full checkerboar operations
 | 
			
		||||
      virtual RealD M    (const Field &in, Field &out)=0;
 | 
			
		||||
      virtual RealD Mdag (const Field &in, Field &out)=0;
 | 
			
		||||
@@ -19,7 +19,6 @@ namespace Grid {
 | 
			
		||||
	ni=M(in,tmp);
 | 
			
		||||
	no=Mdag(tmp,out);
 | 
			
		||||
      }
 | 
			
		||||
      SparseMatrixBase(GridBase *grid) : _grid(grid) {};
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
  /////////////////////////////////////////////////////////////////////////////////////////////
 | 
			
		||||
@@ -27,7 +26,7 @@ namespace Grid {
 | 
			
		||||
  /////////////////////////////////////////////////////////////////////////////////////////////
 | 
			
		||||
    template<class Field> class CheckerBoardedSparseMatrixBase : public SparseMatrixBase<Field> {
 | 
			
		||||
    public:
 | 
			
		||||
      GridBase *_cbgrid;
 | 
			
		||||
      virtual GridBase *RedBlackGrid(void)=0;
 | 
			
		||||
      // half checkerboard operaions
 | 
			
		||||
      virtual  void Meooe    (const Field &in, Field &out)=0;
 | 
			
		||||
      virtual  void Mooee    (const Field &in, Field &out)=0;
 | 
			
		||||
@@ -62,9 +61,7 @@ namespace Grid {
 | 
			
		||||
	Field tmp(in._grid);
 | 
			
		||||
	ni=Mpc(in,tmp);
 | 
			
		||||
	no=MpcDag(tmp,out);
 | 
			
		||||
	//	std::cout<<"MpcDagMpc "<<ni<<" "<<no<<std::endl;
 | 
			
		||||
      }
 | 
			
		||||
      CheckerBoardedSparseMatrixBase(GridBase *grid,GridBase *cbgrid) : SparseMatrixBase<Field>(grid), _cbgrid(cbgrid) {};
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -60,8 +60,8 @@ namespace Grid {
 | 
			
		||||
 | 
			
		||||
      // FIXME CGdiagonalMee not implemented virtual function
 | 
			
		||||
      // FIXME use CBfactorise to control schur decomp
 | 
			
		||||
      GridBase *grid = _Matrix._cbgrid;
 | 
			
		||||
      GridBase *fgrid= _Matrix._grid;
 | 
			
		||||
      GridBase *grid = _Matrix.RedBlackGrid();
 | 
			
		||||
      GridBase *fgrid= _Matrix.Grid();
 | 
			
		||||
 
 | 
			
		||||
      Field src_e(grid);
 | 
			
		||||
      Field src_o(grid);
 | 
			
		||||
 
 | 
			
		||||
@@ -52,16 +52,13 @@ public:
 | 
			
		||||
    ////////////////////////////////////////////////////////////////
 | 
			
		||||
    virtual int CheckerBoarded(int dim)=0;
 | 
			
		||||
    virtual int CheckerBoard(std::vector<int> site)=0;
 | 
			
		||||
    virtual int CheckerBoardDestination(int source_cb,int shift)=0;
 | 
			
		||||
    virtual int CheckerBoardDestination(int source_cb,int shift,int dim)=0;
 | 
			
		||||
    virtual int CheckerBoardShift(int source_cb,int dim,int shift,int osite)=0;
 | 
			
		||||
    inline int  CheckerBoardFromOindex (int Oindex){
 | 
			
		||||
    virtual int CheckerBoardShiftForCB(int source_cb,int dim,int shift,int cb)=0;
 | 
			
		||||
    int  CheckerBoardFromOindex (int Oindex){
 | 
			
		||||
      std::vector<int> ocoor;
 | 
			
		||||
      oCoorFromOindex(ocoor,Oindex); 
 | 
			
		||||
      int ss=0;
 | 
			
		||||
      for(int d=0;d<_ndimension;d++){
 | 
			
		||||
	ss=ss+ocoor[d];
 | 
			
		||||
      }      
 | 
			
		||||
      return ss&0x1;
 | 
			
		||||
      return CheckerBoard(ocoor);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    //////////////////////////////////////////////////////////////////////////////////////////////
 | 
			
		||||
 
 | 
			
		||||
@@ -18,9 +18,12 @@ public:
 | 
			
		||||
    virtual int CheckerBoard(std::vector<int> site){
 | 
			
		||||
        return 0;
 | 
			
		||||
    }
 | 
			
		||||
    virtual int CheckerBoardDestination(int cb,int shift){
 | 
			
		||||
    virtual int CheckerBoardDestination(int cb,int shift,int dim){
 | 
			
		||||
        return 0;
 | 
			
		||||
    }
 | 
			
		||||
    virtual int CheckerBoardShiftForCB(int source_cb,int dim,int shift, int ocb){
 | 
			
		||||
      return shift;
 | 
			
		||||
    }
 | 
			
		||||
    virtual int CheckerBoardShift(int source_cb,int dim,int shift, int osite){
 | 
			
		||||
      return shift;
 | 
			
		||||
    }
 | 
			
		||||
 
 | 
			
		||||
@@ -8,6 +8,10 @@ namespace Grid {
 | 
			
		||||
    static const int CbBlack=1;
 | 
			
		||||
    static const int Even   =CbRed;
 | 
			
		||||
    static const int Odd    =CbBlack;
 | 
			
		||||
 | 
			
		||||
    // Perhaps these are misplaced and 
 | 
			
		||||
    // should be in sparse matrix.
 | 
			
		||||
    // Also should make these a named enum type
 | 
			
		||||
    static const int DaggerNo=0;
 | 
			
		||||
    static const int DaggerYes=1;
 | 
			
		||||
 | 
			
		||||
@@ -15,53 +19,101 @@ namespace Grid {
 | 
			
		||||
class GridRedBlackCartesian : public GridBase
 | 
			
		||||
{
 | 
			
		||||
public:
 | 
			
		||||
    std::vector<int> _checker_dim_mask;
 | 
			
		||||
    int              _checker_dim;
 | 
			
		||||
 | 
			
		||||
    virtual int CheckerBoarded(int dim){
 | 
			
		||||
      if( dim==0) return 1;
 | 
			
		||||
      if( dim==_checker_dim) return 1;
 | 
			
		||||
      else return 0;
 | 
			
		||||
    }
 | 
			
		||||
    virtual int CheckerBoard(std::vector<int> site){
 | 
			
		||||
      return (site[0]+site[1]+site[2]+site[3])&0x1;
 | 
			
		||||
      int linear=0;
 | 
			
		||||
      assert(site.size()==_ndimension);
 | 
			
		||||
      for(int d=0;d<_ndimension;d++){ 
 | 
			
		||||
	if(_checker_dim_mask[d])
 | 
			
		||||
	  linear=linear+site[d];
 | 
			
		||||
      }
 | 
			
		||||
      return (linear&0x1);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    // Depending on the cb of site, we toggle source cb.
 | 
			
		||||
    // for block #b, element #e = (b, e)
 | 
			
		||||
    // we need 
 | 
			
		||||
    virtual int CheckerBoardShift(int source_cb,int dim,int shift,int osite){
 | 
			
		||||
    virtual int CheckerBoardShiftForCB(int source_cb,int dim,int shift,int ocb){
 | 
			
		||||
      if(dim != _checker_dim) return shift;
 | 
			
		||||
 | 
			
		||||
      if(dim != 0) return shift;
 | 
			
		||||
 | 
			
		||||
      int fulldim =_fdimensions[0];
 | 
			
		||||
      int fulldim =_fdimensions[dim];
 | 
			
		||||
      shift = (shift+fulldim)%fulldim;
 | 
			
		||||
 | 
			
		||||
      // Probably faster with table lookup;
 | 
			
		||||
      // or by looping over x,y,z and multiply rather than computing checkerboard.
 | 
			
		||||
      int ocb=CheckerBoardFromOindex(osite);
 | 
			
		||||
	  
 | 
			
		||||
      if ( (source_cb+ocb)&1 ) {
 | 
			
		||||
 | 
			
		||||
	return (shift)/2;
 | 
			
		||||
      } else {
 | 
			
		||||
	return (shift+1)/2;
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
    virtual int CheckerBoardShift(int source_cb,int dim,int shift,int osite){
 | 
			
		||||
 | 
			
		||||
    virtual int CheckerBoardDestination(int source_cb,int shift){
 | 
			
		||||
        if ((shift+_fdimensions[0])&0x1) {
 | 
			
		||||
      if(dim != _checker_dim) return shift;
 | 
			
		||||
 | 
			
		||||
      int ocb=CheckerBoardFromOindex(osite);
 | 
			
		||||
      
 | 
			
		||||
      return CheckerBoardShiftForCB(source_cb,dim,shift,ocb);
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    virtual int CheckerBoardDestination(int source_cb,int shift,int dim){
 | 
			
		||||
      if ( _checker_dim_mask[dim]  ) {
 | 
			
		||||
	// If _fdimensions[checker_dim] is odd, then shifting by 1 in other dims
 | 
			
		||||
	// does NOT cause a parity hop.
 | 
			
		||||
	int add=(dim==_checker_dim) ? 0 : _fdimensions[_checker_dim];
 | 
			
		||||
        if ( (shift+add) &0x1) {
 | 
			
		||||
            return 1-source_cb;
 | 
			
		||||
        } else {
 | 
			
		||||
            return source_cb;
 | 
			
		||||
        }
 | 
			
		||||
      } else {
 | 
			
		||||
	return source_cb;
 | 
			
		||||
 | 
			
		||||
      }
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    GridRedBlackCartesian(GridBase *base) : GridRedBlackCartesian(base->_fdimensions,base->_simd_layout,base->_processors)  {};
 | 
			
		||||
 | 
			
		||||
    GridRedBlackCartesian(std::vector<int> &dimensions,
 | 
			
		||||
			  std::vector<int> &simd_layout,
 | 
			
		||||
			  std::vector<int> &processor_grid ) : GridBase(processor_grid)
 | 
			
		||||
			  std::vector<int> &processor_grid,
 | 
			
		||||
			  std::vector<int> &checker_dim_mask,
 | 
			
		||||
			  int checker_dim
 | 
			
		||||
			  ) :  GridBase(processor_grid) 
 | 
			
		||||
    {
 | 
			
		||||
      Init(dimensions,simd_layout,processor_grid,checker_dim_mask,checker_dim);
 | 
			
		||||
    }
 | 
			
		||||
    GridRedBlackCartesian(std::vector<int> &dimensions,
 | 
			
		||||
			  std::vector<int> &simd_layout,
 | 
			
		||||
			  std::vector<int> &processor_grid) : GridBase(processor_grid) 
 | 
			
		||||
    {
 | 
			
		||||
      std::vector<int> checker_dim_mask(dimensions.size(),1);
 | 
			
		||||
      Init(dimensions,simd_layout,processor_grid,checker_dim_mask,0);
 | 
			
		||||
    }
 | 
			
		||||
    void Init(std::vector<int> &dimensions,
 | 
			
		||||
	      std::vector<int> &simd_layout,
 | 
			
		||||
	      std::vector<int> &processor_grid,
 | 
			
		||||
	      std::vector<int> &checker_dim_mask,
 | 
			
		||||
	      int checker_dim)
 | 
			
		||||
    {
 | 
			
		||||
    ///////////////////////
 | 
			
		||||
    // Grid information
 | 
			
		||||
    ///////////////////////
 | 
			
		||||
      _checker_dim = checker_dim;
 | 
			
		||||
      assert(checker_dim_mask[checker_dim]==1);
 | 
			
		||||
      _ndimension = dimensions.size();
 | 
			
		||||
      assert(checker_dim_mask.size()==_ndimension);
 | 
			
		||||
      assert(processor_grid.size()==_ndimension);
 | 
			
		||||
      assert(simd_layout.size()==_ndimension);
 | 
			
		||||
      
 | 
			
		||||
      _fdimensions.resize(_ndimension);
 | 
			
		||||
      _gdimensions.resize(_ndimension);
 | 
			
		||||
@@ -74,13 +126,17 @@ public:
 | 
			
		||||
      
 | 
			
		||||
      _fsites = _gsites = _osites = _isites = 1;
 | 
			
		||||
	
 | 
			
		||||
      _checker_dim_mask=checker_dim_mask;
 | 
			
		||||
 | 
			
		||||
      for(int d=0;d<_ndimension;d++){
 | 
			
		||||
	_fdimensions[d] = dimensions[d];
 | 
			
		||||
	_gdimensions[d] = _fdimensions[d];
 | 
			
		||||
	_fsites = _fsites * _fdimensions[d];
 | 
			
		||||
	_gsites = _gsites * _gdimensions[d];
 | 
			
		||||
        
 | 
			
		||||
            if (d==0) _gdimensions[0] = _gdimensions[0]/2; // Remove a checkerboard
 | 
			
		||||
	if (d==_checker_dim) {
 | 
			
		||||
	  _gdimensions[d] = _gdimensions[d]/2; // Remove a checkerboard
 | 
			
		||||
	}
 | 
			
		||||
	_ldimensions[d] = _gdimensions[d]/_processors[d];
 | 
			
		||||
 | 
			
		||||
	// Use a reduced simd grid
 | 
			
		||||
@@ -123,8 +179,14 @@ public:
 | 
			
		||||
protected:
 | 
			
		||||
    virtual int oIndex(std::vector<int> &coor)
 | 
			
		||||
    {
 | 
			
		||||
        int idx=_ostride[0]*((coor[0]/2)%_rdimensions[0]);
 | 
			
		||||
        for(int d=1;d<_ndimension;d++) idx+=_ostride[d]*(coor[d]%_rdimensions[d]);
 | 
			
		||||
      int idx=0;
 | 
			
		||||
      for(int d=0;d<_ndimension;d++) {
 | 
			
		||||
	if( d==_checker_dim ) {
 | 
			
		||||
	  idx+=_ostride[d]*((coor[d]/2)%_rdimensions[d]);
 | 
			
		||||
	} else {
 | 
			
		||||
	  idx+=_ostride[d]*(coor[d]%_rdimensions[d]);
 | 
			
		||||
	}
 | 
			
		||||
      }
 | 
			
		||||
        return idx;
 | 
			
		||||
    };
 | 
			
		||||
        
 | 
			
		||||
 
 | 
			
		||||
@@ -175,7 +175,6 @@ PARALLEL_NESTED_LOOP2
 | 
			
		||||
      if ( ocb&cbmask ) {
 | 
			
		||||
	//lhs._odata[lo+o]=rhs._odata[ro+o];
 | 
			
		||||
	vstream(lhs._odata[lo+o],rhs._odata[ro+o]);
 | 
			
		||||
	
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
@@ -217,8 +216,8 @@ template<class vobj> void Cshift_local(Lattice<vobj>& ret,Lattice<vobj> &rhs,int
 | 
			
		||||
{
 | 
			
		||||
  int sshift[2];
 | 
			
		||||
 | 
			
		||||
  sshift[0] = rhs._grid->CheckerBoardShift(rhs.checkerboard,dimension,shift,0);
 | 
			
		||||
  sshift[1] = rhs._grid->CheckerBoardShift(rhs.checkerboard,dimension,shift,1);
 | 
			
		||||
  sshift[0] = rhs._grid->CheckerBoardShiftForCB(rhs.checkerboard,dimension,shift,Even);
 | 
			
		||||
  sshift[1] = rhs._grid->CheckerBoardShiftForCB(rhs.checkerboard,dimension,shift,Odd);
 | 
			
		||||
 | 
			
		||||
  if ( sshift[0] == sshift[1] ) {
 | 
			
		||||
    Cshift_local(ret,rhs,dimension,shift,0x3);
 | 
			
		||||
@@ -239,8 +238,7 @@ template<class vobj> Lattice<vobj> Cshift_local(Lattice<vobj> &ret,Lattice<vobj>
 | 
			
		||||
  // Map to always positive shift modulo global full dimension.
 | 
			
		||||
  shift = (shift+fd)%fd;
 | 
			
		||||
 | 
			
		||||
  ret.checkerboard = grid->CheckerBoardDestination(rhs.checkerboard,shift);
 | 
			
		||||
        
 | 
			
		||||
  ret.checkerboard = grid->CheckerBoardDestination(rhs.checkerboard,shift,dimension);
 | 
			
		||||
  // the permute type
 | 
			
		||||
  int permute_dim =grid->PermuteDim(dimension);
 | 
			
		||||
  int permute_type=grid->PermuteType(dimension);
 | 
			
		||||
@@ -250,9 +248,9 @@ template<class vobj> Lattice<vobj> Cshift_local(Lattice<vobj> &ret,Lattice<vobj>
 | 
			
		||||
    int o   = 0;
 | 
			
		||||
    int bo  = x * grid->_ostride[dimension];
 | 
			
		||||
    
 | 
			
		||||
    int cb= (cbmask==0x2)? 1 : 0;
 | 
			
		||||
    int cb= (cbmask==0x2)? Odd : Even;
 | 
			
		||||
 | 
			
		||||
    int sshift = grid->CheckerBoardShift(rhs.checkerboard,dimension,shift,cb);
 | 
			
		||||
    int sshift = grid->CheckerBoardShiftForCB(rhs.checkerboard,dimension,shift,cb);
 | 
			
		||||
    int sx     = (x+sshift)%rd;
 | 
			
		||||
 | 
			
		||||
    int permute_slice=0;
 | 
			
		||||
 
 | 
			
		||||
@@ -39,8 +39,8 @@ template<class vobj> void Cshift_comms(Lattice<vobj>& ret,Lattice<vobj> &rhs,int
 | 
			
		||||
{
 | 
			
		||||
  int sshift[2];
 | 
			
		||||
 | 
			
		||||
  sshift[0] = rhs._grid->CheckerBoardShift(rhs.checkerboard,dimension,shift,0);
 | 
			
		||||
  sshift[1] = rhs._grid->CheckerBoardShift(rhs.checkerboard,dimension,shift,1);
 | 
			
		||||
  sshift[0] = rhs._grid->CheckerBoardShiftForCB(rhs.checkerboard,dimension,shift,Even);
 | 
			
		||||
  sshift[1] = rhs._grid->CheckerBoardShiftForCB(rhs.checkerboard,dimension,shift,Odd);
 | 
			
		||||
 | 
			
		||||
  if ( sshift[0] == sshift[1] ) {
 | 
			
		||||
    Cshift_comms(ret,rhs,dimension,shift,0x3);
 | 
			
		||||
@@ -54,8 +54,8 @@ template<class vobj> void Cshift_comms_simd(Lattice<vobj>& ret,Lattice<vobj> &rh
 | 
			
		||||
{
 | 
			
		||||
  int sshift[2];
 | 
			
		||||
 | 
			
		||||
  sshift[0] = rhs._grid->CheckerBoardShift(rhs.checkerboard,dimension,shift,0);
 | 
			
		||||
  sshift[1] = rhs._grid->CheckerBoardShift(rhs.checkerboard,dimension,shift,1);
 | 
			
		||||
  sshift[0] = rhs._grid->CheckerBoardShiftForCB(rhs.checkerboard,dimension,shift,Even);
 | 
			
		||||
  sshift[1] = rhs._grid->CheckerBoardShiftForCB(rhs.checkerboard,dimension,shift,Odd);
 | 
			
		||||
 | 
			
		||||
  if ( sshift[0] == sshift[1] ) {
 | 
			
		||||
    Cshift_comms_simd(ret,rhs,dimension,shift,0x3);
 | 
			
		||||
@@ -87,8 +87,8 @@ template<class vobj> void Cshift_comms(Lattice<vobj> &ret,Lattice<vobj> &rhs,int
 | 
			
		||||
  std::vector<vobj,alignedAllocator<vobj> > send_buf(buffer_size);
 | 
			
		||||
  std::vector<vobj,alignedAllocator<vobj> > recv_buf(buffer_size);
 | 
			
		||||
 | 
			
		||||
  int cb= (cbmask==0x2)? 1 : 0;
 | 
			
		||||
  int sshift= rhs._grid->CheckerBoardShift(rhs.checkerboard,dimension,shift,cb);
 | 
			
		||||
  int cb= (cbmask==0x2)? Odd : Even;
 | 
			
		||||
  int sshift= rhs._grid->CheckerBoardShiftForCB(rhs.checkerboard,dimension,shift,cb);
 | 
			
		||||
 | 
			
		||||
  for(int x=0;x<rd;x++){       
 | 
			
		||||
 | 
			
		||||
@@ -162,8 +162,8 @@ template<class vobj> void  Cshift_comms_simd(Lattice<vobj> &ret,Lattice<vobj> &r
 | 
			
		||||
  ///////////////////////////////////////////
 | 
			
		||||
  // Work out what to send where
 | 
			
		||||
  ///////////////////////////////////////////
 | 
			
		||||
  int cb    = (cbmask==0x2)? 1 : 0;
 | 
			
		||||
  int sshift= grid->CheckerBoardShift(rhs.checkerboard,dimension,shift,cb);
 | 
			
		||||
  int cb    = (cbmask==0x2)? Odd : Even;
 | 
			
		||||
  int sshift= grid->CheckerBoardShiftForCB(rhs.checkerboard,dimension,shift,cb);
 | 
			
		||||
 | 
			
		||||
  // loop over outer coord planes orthog to dim
 | 
			
		||||
  for(int x=0;x<rd;x++){       
 | 
			
		||||
 
 | 
			
		||||
@@ -4,7 +4,7 @@ namespace Grid {
 | 
			
		||||
template<class vobj> Lattice<vobj> Cshift(Lattice<vobj> &rhs,int dimension,int shift)
 | 
			
		||||
{
 | 
			
		||||
  Lattice<vobj> ret(rhs._grid);
 | 
			
		||||
  ret.checkerboard = rhs._grid->CheckerBoardDestination(rhs.checkerboard,shift);
 | 
			
		||||
  ret.checkerboard = rhs._grid->CheckerBoardDestination(rhs.checkerboard,shift,dimension);
 | 
			
		||||
  Cshift_local(ret,rhs,dimension,shift);
 | 
			
		||||
  return ret;
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -116,7 +116,7 @@ PARALLEL_FOR_LOOP
 | 
			
		||||
 | 
			
		||||
      int Nsimd = grid->Nsimd();
 | 
			
		||||
 | 
			
		||||
      assert( l.checkerboard== l._grid->CheckerBoard(site));
 | 
			
		||||
      assert( l.checkerboard == l._grid->CheckerBoard(site));
 | 
			
		||||
      assert( sizeof(sobj)*Nsimd == sizeof(vobj));
 | 
			
		||||
 | 
			
		||||
      int rank,odx,idx;
 | 
			
		||||
 
 | 
			
		||||
@@ -32,7 +32,6 @@ PARALLEL_FOR_LOOP
 | 
			
		||||
      cbos=half._grid->CheckerBoard(coor);
 | 
			
		||||
      
 | 
			
		||||
      if (cbos==cb) {
 | 
			
		||||
	
 | 
			
		||||
	half._odata[ssh] = full._odata[ss];
 | 
			
		||||
	ssh++;
 | 
			
		||||
      }
 | 
			
		||||
 
 | 
			
		||||
@@ -1,217 +0,0 @@
 | 
			
		||||
#include <Grid.h>
 | 
			
		||||
 | 
			
		||||
namespace Grid {
 | 
			
		||||
namespace QCD {
 | 
			
		||||
 | 
			
		||||
const std::vector<int> WilsonMatrix::directions   ({0,1,2,3, 0, 1, 2, 3});
 | 
			
		||||
const std::vector<int> WilsonMatrix::displacements({1,1,1,1,-1,-1,-1,-1});
 | 
			
		||||
 | 
			
		||||
  int WilsonMatrix::HandOptDslash;
 | 
			
		||||
 | 
			
		||||
  class WilsonCompressor {
 | 
			
		||||
  public:
 | 
			
		||||
    int mu;
 | 
			
		||||
    int dag;
 | 
			
		||||
 | 
			
		||||
    WilsonCompressor(int _dag){
 | 
			
		||||
      mu=0;
 | 
			
		||||
      dag=_dag;
 | 
			
		||||
      assert((dag==0)||(dag==1));
 | 
			
		||||
    }
 | 
			
		||||
    void Point(int p) { 
 | 
			
		||||
      mu=p;
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    vHalfSpinColourVector operator () (const vSpinColourVector &in)
 | 
			
		||||
    {
 | 
			
		||||
      vHalfSpinColourVector ret;
 | 
			
		||||
      int mudag=mu;
 | 
			
		||||
      if (dag) {
 | 
			
		||||
	mudag=(mu+Nd)%(2*Nd);
 | 
			
		||||
      }
 | 
			
		||||
      switch(mudag) {
 | 
			
		||||
      case Xp:
 | 
			
		||||
	spProjXp(ret,in);
 | 
			
		||||
	break;
 | 
			
		||||
      case Yp:
 | 
			
		||||
	spProjYp(ret,in);
 | 
			
		||||
	break;
 | 
			
		||||
      case Zp:
 | 
			
		||||
	spProjZp(ret,in);
 | 
			
		||||
	break;
 | 
			
		||||
      case Tp:
 | 
			
		||||
	spProjTp(ret,in);
 | 
			
		||||
	break;
 | 
			
		||||
      case Xm:
 | 
			
		||||
	spProjXm(ret,in);
 | 
			
		||||
	break;
 | 
			
		||||
      case Ym:
 | 
			
		||||
	spProjYm(ret,in);
 | 
			
		||||
	break;
 | 
			
		||||
      case Zm:
 | 
			
		||||
	spProjZm(ret,in);
 | 
			
		||||
	break;
 | 
			
		||||
      case Tm:
 | 
			
		||||
	spProjTm(ret,in);
 | 
			
		||||
	break;
 | 
			
		||||
      default: 
 | 
			
		||||
	assert(0);
 | 
			
		||||
	break;
 | 
			
		||||
      }
 | 
			
		||||
      return ret;
 | 
			
		||||
    }
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
  WilsonMatrix::WilsonMatrix(LatticeGaugeField &_Umu,GridCartesian &Fgrid,GridRedBlackCartesian &Hgrid, double _mass)  : 
 | 
			
		||||
    CheckerBoardedSparseMatrixBase<LatticeFermion>(&Fgrid,&Hgrid),
 | 
			
		||||
    Stencil    (  _grid,npoint,Even,directions,displacements),
 | 
			
		||||
    StencilEven(_cbgrid,npoint,Even,directions,displacements), // source is Even
 | 
			
		||||
    StencilOdd (_cbgrid,npoint,Odd ,directions,displacements), // source is Odd
 | 
			
		||||
    mass(_mass),
 | 
			
		||||
    Umu(_grid),
 | 
			
		||||
    UmuEven(_cbgrid),
 | 
			
		||||
    UmuOdd (_cbgrid)
 | 
			
		||||
  {
 | 
			
		||||
    // Allocate the required comms buffer
 | 
			
		||||
    comm_buf.resize(Stencil._unified_buffer_size); // this is always big enough to contain EO
 | 
			
		||||
    
 | 
			
		||||
    DoubleStore(Umu,_Umu);
 | 
			
		||||
    pickCheckerboard(Even,UmuEven,Umu);
 | 
			
		||||
    pickCheckerboard(Odd ,UmuOdd,Umu);
 | 
			
		||||
  }
 | 
			
		||||
      
 | 
			
		||||
void WilsonMatrix::DoubleStore(LatticeDoubledGaugeField &Uds,const LatticeGaugeField &Umu)
 | 
			
		||||
{
 | 
			
		||||
  LatticeColourMatrix U(_grid);
 | 
			
		||||
 | 
			
		||||
  for(int mu=0;mu<Nd;mu++){
 | 
			
		||||
    U = peekIndex<LorentzIndex>(Umu,mu);
 | 
			
		||||
    pokeIndex<LorentzIndex>(Uds,U,mu);
 | 
			
		||||
    U = adj(Cshift(U,mu,-1));
 | 
			
		||||
    pokeIndex<LorentzIndex>(Uds,U,mu+4);
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
RealD WilsonMatrix::M(const LatticeFermion &in, LatticeFermion &out)
 | 
			
		||||
{
 | 
			
		||||
  out.checkerboard=in.checkerboard;
 | 
			
		||||
  Dhop(in,out,DaggerNo);
 | 
			
		||||
  out = (4+mass)*in - 0.5*out  ; // FIXME : axpby_norm! fusion fun
 | 
			
		||||
  return norm2(out);
 | 
			
		||||
}
 | 
			
		||||
RealD WilsonMatrix::Mdag(const LatticeFermion &in, LatticeFermion &out)
 | 
			
		||||
{
 | 
			
		||||
  out.checkerboard=in.checkerboard;
 | 
			
		||||
  Dhop(in,out,DaggerYes);
 | 
			
		||||
  out = (4+mass)*in - 0.5*out  ; // FIXME : axpby_norm! fusion fun
 | 
			
		||||
  return norm2(out);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void WilsonMatrix::Meooe(const LatticeFermion &in, LatticeFermion &out)
 | 
			
		||||
{
 | 
			
		||||
  if ( in.checkerboard == Odd ) {
 | 
			
		||||
    DhopEO(in,out,DaggerNo);
 | 
			
		||||
  } else {
 | 
			
		||||
    DhopOE(in,out,DaggerNo);
 | 
			
		||||
  }
 | 
			
		||||
  out = (-0.5)*out; // FIXME : scale factor in Dhop
 | 
			
		||||
}
 | 
			
		||||
void WilsonMatrix::MeooeDag(const LatticeFermion &in, LatticeFermion &out)
 | 
			
		||||
{
 | 
			
		||||
  if ( in.checkerboard == Odd ) {
 | 
			
		||||
    DhopEO(in,out,DaggerYes);
 | 
			
		||||
  } else {
 | 
			
		||||
    DhopOE(in,out,DaggerYes);
 | 
			
		||||
  }
 | 
			
		||||
  out = (-0.5)*out; // FIXME : scale factor in Dhop
 | 
			
		||||
}
 | 
			
		||||
void WilsonMatrix::Mooee(const LatticeFermion &in, LatticeFermion &out)
 | 
			
		||||
{
 | 
			
		||||
  out.checkerboard = in.checkerboard;
 | 
			
		||||
  out = (4.0+mass)*in;
 | 
			
		||||
  return ;
 | 
			
		||||
}
 | 
			
		||||
void WilsonMatrix::MooeeDag(const LatticeFermion &in, LatticeFermion &out)
 | 
			
		||||
{
 | 
			
		||||
  out.checkerboard = in.checkerboard;
 | 
			
		||||
  Mooee(in,out);
 | 
			
		||||
}
 | 
			
		||||
void WilsonMatrix::MooeeInv(const LatticeFermion &in, LatticeFermion &out)
 | 
			
		||||
{
 | 
			
		||||
  out.checkerboard = in.checkerboard;
 | 
			
		||||
  out = (1.0/(4.0+mass))*in;
 | 
			
		||||
  return ;
 | 
			
		||||
}
 | 
			
		||||
void WilsonMatrix::MooeeInvDag(const LatticeFermion &in, LatticeFermion &out)
 | 
			
		||||
{
 | 
			
		||||
  out.checkerboard = in.checkerboard;
 | 
			
		||||
  MooeeInv(in,out);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void WilsonMatrix::DhopInternal(CartesianStencil & st,LatticeDoubledGaugeField & U,
 | 
			
		||||
				const LatticeFermion &in, LatticeFermion &out,int dag)
 | 
			
		||||
{
 | 
			
		||||
  assert((dag==DaggerNo) ||(dag==DaggerYes));
 | 
			
		||||
  WilsonCompressor compressor(dag);
 | 
			
		||||
  st.HaloExchange<vSpinColourVector,vHalfSpinColourVector,WilsonCompressor>(in,comm_buf,compressor);
 | 
			
		||||
 | 
			
		||||
  if ( dag == DaggerYes ) {
 | 
			
		||||
    if( HandOptDslash ) {
 | 
			
		||||
PARALLEL_FOR_LOOP
 | 
			
		||||
      for(int sss=0;sss<in._grid->oSites();sss++){
 | 
			
		||||
        DiracOptHand::DhopSiteDag(st,U,comm_buf,sss,in,out);
 | 
			
		||||
      }
 | 
			
		||||
    } else { 
 | 
			
		||||
PARALLEL_FOR_LOOP
 | 
			
		||||
      for(int sss=0;sss<in._grid->oSites();sss++){
 | 
			
		||||
        DiracOpt::DhopSiteDag(st,U,comm_buf,sss,in,out);
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
  } else {
 | 
			
		||||
    if( HandOptDslash ) {
 | 
			
		||||
PARALLEL_FOR_LOOP
 | 
			
		||||
      for(int sss=0;sss<in._grid->oSites();sss++){
 | 
			
		||||
        DiracOptHand::DhopSite(st,U,comm_buf,sss,in,out);
 | 
			
		||||
      }
 | 
			
		||||
    } else { 
 | 
			
		||||
PARALLEL_FOR_LOOP
 | 
			
		||||
      for(int sss=0;sss<in._grid->oSites();sss++){
 | 
			
		||||
        DiracOpt::DhopSite(st,U,comm_buf,sss,in,out);
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
void WilsonMatrix::DhopOE(const LatticeFermion &in, LatticeFermion &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,UmuOdd,in,out,dag);
 | 
			
		||||
}
 | 
			
		||||
void WilsonMatrix::DhopEO(const LatticeFermion &in, LatticeFermion &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,UmuEven,in,out,dag);
 | 
			
		||||
}
 | 
			
		||||
void WilsonMatrix::Dhop(const LatticeFermion &in, LatticeFermion &out,int dag)
 | 
			
		||||
{
 | 
			
		||||
  conformable(in._grid,_grid); // verifies full grid
 | 
			
		||||
  conformable(in._grid,out._grid);
 | 
			
		||||
 | 
			
		||||
  out.checkerboard = in.checkerboard;
 | 
			
		||||
 | 
			
		||||
  DhopInternal(Stencil,Umu,in,out,dag);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
}}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@@ -1,105 +0,0 @@
 | 
			
		||||
#ifndef  GRID_QCD_WILSON_DOP_H
 | 
			
		||||
#define  GRID_QCD_WILSON_DOP_H
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
namespace Grid {
 | 
			
		||||
 | 
			
		||||
  namespace QCD {
 | 
			
		||||
 | 
			
		||||
  // Should be in header?
 | 
			
		||||
    const int Xp = 0;
 | 
			
		||||
    const int Yp = 1;
 | 
			
		||||
    const int Zp = 2;
 | 
			
		||||
    const int Tp = 3;
 | 
			
		||||
    const int Xm = 4;
 | 
			
		||||
    const int Ym = 5;
 | 
			
		||||
    const int Zm = 6;
 | 
			
		||||
    const int Tm = 7;
 | 
			
		||||
 | 
			
		||||
    class WilsonMatrix : public CheckerBoardedSparseMatrixBase<LatticeFermion>
 | 
			
		||||
    {
 | 
			
		||||
      //NB r=1;
 | 
			
		||||
    public:
 | 
			
		||||
      static int HandOptDslash;
 | 
			
		||||
 | 
			
		||||
      double                        mass;
 | 
			
		||||
      //      GridBase                     *    grid; // Inherited
 | 
			
		||||
      //      GridBase                     *  cbgrid;
 | 
			
		||||
 | 
			
		||||
      //Defines the stencils for even and odd
 | 
			
		||||
      CartesianStencil Stencil; 
 | 
			
		||||
      CartesianStencil StencilEven; 
 | 
			
		||||
      CartesianStencil StencilOdd; 
 | 
			
		||||
 | 
			
		||||
      // Copy of the gauge field , with even and odd subsets
 | 
			
		||||
      LatticeDoubledGaugeField Umu;
 | 
			
		||||
      LatticeDoubledGaugeField UmuEven;
 | 
			
		||||
      LatticeDoubledGaugeField UmuOdd;
 | 
			
		||||
 | 
			
		||||
      static const int npoint=8;
 | 
			
		||||
      static const std::vector<int> directions   ;
 | 
			
		||||
      static const std::vector<int> displacements;
 | 
			
		||||
      static const int Xp,Xm,Yp,Ym,Zp,Zm,Tp,Tm;
 | 
			
		||||
 | 
			
		||||
      // Comms buffer
 | 
			
		||||
      std::vector<vHalfSpinColourVector,alignedAllocator<vHalfSpinColourVector> >  comm_buf;
 | 
			
		||||
 | 
			
		||||
      // Constructor
 | 
			
		||||
      WilsonMatrix(LatticeGaugeField &_Umu,GridCartesian &Fgrid,GridRedBlackCartesian &Hgrid,double _mass);
 | 
			
		||||
 | 
			
		||||
      // DoubleStore
 | 
			
		||||
      void DoubleStore(LatticeDoubledGaugeField &Uds,const LatticeGaugeField &Umu);
 | 
			
		||||
 | 
			
		||||
      // override multiply
 | 
			
		||||
      virtual RealD  M    (const LatticeFermion &in, LatticeFermion &out);
 | 
			
		||||
      virtual RealD  Mdag (const LatticeFermion &in, LatticeFermion &out);
 | 
			
		||||
 | 
			
		||||
      // half checkerboard operaions
 | 
			
		||||
      virtual void   Meooe       (const LatticeFermion &in, LatticeFermion &out);
 | 
			
		||||
      virtual void   MeooeDag    (const LatticeFermion &in, LatticeFermion &out);
 | 
			
		||||
      virtual void   Mooee       (const LatticeFermion &in, LatticeFermion &out);
 | 
			
		||||
      virtual void   MooeeDag    (const LatticeFermion &in, LatticeFermion &out);
 | 
			
		||||
      virtual void   MooeeInv    (const LatticeFermion &in, LatticeFermion &out);
 | 
			
		||||
      virtual void   MooeeInvDag (const LatticeFermion &in, LatticeFermion &out);
 | 
			
		||||
 | 
			
		||||
      // non-hermitian hopping term; half cb or both
 | 
			
		||||
      void Dhop  (const LatticeFermion &in, LatticeFermion &out,int dag);
 | 
			
		||||
      void DhopOE(const LatticeFermion &in, LatticeFermion &out,int dag);
 | 
			
		||||
      void DhopEO(const LatticeFermion &in, LatticeFermion &out,int dag);
 | 
			
		||||
      void DhopInternal(CartesianStencil & st,LatticeDoubledGaugeField &U,
 | 
			
		||||
			const LatticeFermion &in, LatticeFermion &out,int dag);
 | 
			
		||||
 | 
			
		||||
      typedef iScalar<iMatrix<vComplex, Nc> > matrix;
 | 
			
		||||
 | 
			
		||||
      
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    class DiracOpt {
 | 
			
		||||
    public:
 | 
			
		||||
      // These ones will need to be package intelligently. WilsonType base class
 | 
			
		||||
      // for use by DWF etc..
 | 
			
		||||
      static void DhopSite(CartesianStencil &st,LatticeDoubledGaugeField &U,
 | 
			
		||||
		    std::vector<vHalfSpinColourVector,alignedAllocator<vHalfSpinColourVector> >  &buf,
 | 
			
		||||
		    int ss,const LatticeFermion &in, LatticeFermion &out);
 | 
			
		||||
      static void DhopSiteDag(CartesianStencil &st,LatticeDoubledGaugeField &U,
 | 
			
		||||
		       std::vector<vHalfSpinColourVector,alignedAllocator<vHalfSpinColourVector> >  &buf,
 | 
			
		||||
		       int ss,const LatticeFermion &in, LatticeFermion &out);
 | 
			
		||||
 | 
			
		||||
    };
 | 
			
		||||
    class DiracOptHand {
 | 
			
		||||
    public:
 | 
			
		||||
      // These ones will need to be package intelligently. WilsonType base class
 | 
			
		||||
      // for use by DWF etc..
 | 
			
		||||
      static void DhopSite(CartesianStencil &st,LatticeDoubledGaugeField &U,
 | 
			
		||||
		    std::vector<vHalfSpinColourVector,alignedAllocator<vHalfSpinColourVector> >  &buf,
 | 
			
		||||
		    int ss,const LatticeFermion &in, LatticeFermion &out);
 | 
			
		||||
      static void DhopSiteDag(CartesianStencil &st,LatticeDoubledGaugeField &U,
 | 
			
		||||
		       std::vector<vHalfSpinColourVector,alignedAllocator<vHalfSpinColourVector> >  &buf,
 | 
			
		||||
		       int ss,const LatticeFermion &in, LatticeFermion &out);
 | 
			
		||||
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
#endif
 | 
			
		||||
@@ -4,6 +4,16 @@ namespace Grid{
 | 
			
		||||
 | 
			
		||||
namespace QCD {
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    static const int Xp = 0;
 | 
			
		||||
    static const int Yp = 1;
 | 
			
		||||
    static const int Zp = 2;
 | 
			
		||||
    static const int Tp = 3;
 | 
			
		||||
    static const int Xm = 4;
 | 
			
		||||
    static const int Ym = 5;
 | 
			
		||||
    static const int Zm = 6;
 | 
			
		||||
    static const int Tm = 7;
 | 
			
		||||
 | 
			
		||||
    static const int Nc=3;
 | 
			
		||||
    static const int Ns=4;
 | 
			
		||||
    static const int Nd=4;
 | 
			
		||||
@@ -297,9 +307,8 @@ namespace QCD {
 | 
			
		||||
}   //namespace QCD
 | 
			
		||||
} // Grid
 | 
			
		||||
 | 
			
		||||
#include <qcd/Grid_qcd_dirac.h>
 | 
			
		||||
#include <qcd/Grid_qcd_2spinor.h>
 | 
			
		||||
//#include <qcd/Grid_qcd_pauli.h>
 | 
			
		||||
#include <qcd/Grid_qcd_wilson_dop.h>
 | 
			
		||||
#include <qcd/Dirac.h>
 | 
			
		||||
#include <qcd/TwoSpinor.h>
 | 
			
		||||
#include <qcd/action/Actions.h>
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
							
								
								
									
										10
									
								
								lib/qcd/action/Actions.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										10
									
								
								lib/qcd/action/Actions.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,10 @@
 | 
			
		||||
#ifndef GRID_QCD_ACTIONS_H
 | 
			
		||||
#define GRID_QCD_ACTIONS_H
 | 
			
		||||
 | 
			
		||||
#include <qcd/action/fermion/FermionAction.h>
 | 
			
		||||
#include <qcd/action/fermion/WilsonCompressor.h>
 | 
			
		||||
#include <qcd/action/fermion/WilsonKernels.h>
 | 
			
		||||
#include <qcd/action/fermion/WilsonFermion.h>
 | 
			
		||||
#include <qcd/action/fermion/FiveDimWilsonFermion.h>
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
							
								
								
									
										47
									
								
								lib/qcd/action/fermion/FermionAction.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										47
									
								
								lib/qcd/action/fermion/FermionAction.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,47 @@
 | 
			
		||||
#ifndef  GRID_QCD_WILSON_DOP_H
 | 
			
		||||
#define  GRID_QCD_WILSON_DOP_H
 | 
			
		||||
 | 
			
		||||
namespace Grid {
 | 
			
		||||
 | 
			
		||||
  namespace QCD {
 | 
			
		||||
 | 
			
		||||
    //////////////////////////////////////////////////////////////////////////////
 | 
			
		||||
    // Four component fermions
 | 
			
		||||
    // Should type template the vector and gauge types
 | 
			
		||||
    // Think about multiple representations
 | 
			
		||||
    //////////////////////////////////////////////////////////////////////////////
 | 
			
		||||
    template<class FermionField,class GaugeField>
 | 
			
		||||
    class FermionAction : public CheckerBoardedSparseMatrixBase<FermionField>
 | 
			
		||||
    {
 | 
			
		||||
    public:
 | 
			
		||||
 | 
			
		||||
      GridBase * Grid(void)   { return FermionGrid(); };   // this is all the linalg routines need to know
 | 
			
		||||
      GridBase * RedBlackGrid(void) { return FermionRedBlackGrid(); };
 | 
			
		||||
 | 
			
		||||
      virtual GridBase *FermionGrid(void)         =0;
 | 
			
		||||
      virtual GridBase *FermionRedBlackGrid(void) =0;
 | 
			
		||||
      virtual GridBase *GaugeGrid(void)           =0;
 | 
			
		||||
      virtual GridBase *GaugeRedBlackGrid(void)   =0;
 | 
			
		||||
 | 
			
		||||
      // override multiply
 | 
			
		||||
      virtual RealD  M    (const FermionField &in, FermionField &out)=0;
 | 
			
		||||
      virtual RealD  Mdag (const FermionField &in, FermionField &out)=0;
 | 
			
		||||
 | 
			
		||||
      // half checkerboard operaions
 | 
			
		||||
      virtual void   Meooe       (const FermionField &in, FermionField &out)=0;
 | 
			
		||||
      virtual void   MeooeDag    (const FermionField &in, FermionField &out)=0;
 | 
			
		||||
      virtual void   Mooee       (const FermionField &in, FermionField &out)=0;
 | 
			
		||||
      virtual void   MooeeDag    (const FermionField &in, FermionField &out)=0;
 | 
			
		||||
      virtual void   MooeeInv    (const FermionField &in, FermionField &out)=0;
 | 
			
		||||
      virtual void   MooeeInvDag (const FermionField &in, FermionField &out)=0;
 | 
			
		||||
 | 
			
		||||
      // non-hermitian hopping term; half cb or both
 | 
			
		||||
      virtual void Dhop  (const FermionField &in, FermionField &out,int dag)=0;
 | 
			
		||||
      virtual void DhopOE(const FermionField &in, FermionField &out,int dag)=0;
 | 
			
		||||
      virtual void DhopEO(const FermionField &in, FermionField &out,int dag)=0;
 | 
			
		||||
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
#endif
 | 
			
		||||
							
								
								
									
										228
									
								
								lib/qcd/action/fermion/FiveDimWilsonFermion.cc
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										228
									
								
								lib/qcd/action/fermion/FiveDimWilsonFermion.cc
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,228 @@
 | 
			
		||||
#include <Grid.h>
 | 
			
		||||
 | 
			
		||||
namespace Grid {
 | 
			
		||||
namespace QCD {
 | 
			
		||||
  
 | 
			
		||||
  // S-direction is INNERMOST and takes no part in the parity.
 | 
			
		||||
  const std::vector<int> FiveDimWilsonFermion::directions   ({1,2,3,4, 1, 2, 3, 4});
 | 
			
		||||
  const std::vector<int> FiveDimWilsonFermion::displacements({1,1,1,1,-1,-1,-1,-1});
 | 
			
		||||
 | 
			
		||||
  int FiveDimWilsonFermion::HandOptDslash;
 | 
			
		||||
 | 
			
		||||
  // 5d lattice for DWF.
 | 
			
		||||
  FiveDimWilsonFermion::FiveDimWilsonFermion(LatticeGaugeField &_Umu,
 | 
			
		||||
					   GridCartesian         &FiveDimGrid,
 | 
			
		||||
					   GridRedBlackCartesian &FiveDimRedBlackGrid,
 | 
			
		||||
					   GridCartesian         &FourDimGrid,
 | 
			
		||||
					   GridRedBlackCartesian &FourDimRedBlackGrid,
 | 
			
		||||
					   double _mass) :
 | 
			
		||||
  _FiveDimGrid(&FiveDimGrid),
 | 
			
		||||
  _FiveDimRedBlackGrid(&FiveDimRedBlackGrid),
 | 
			
		||||
  _FourDimGrid(&FourDimGrid),
 | 
			
		||||
  _FourDimRedBlackGrid(&FourDimRedBlackGrid),
 | 
			
		||||
  Stencil    (_FiveDimGrid,npoint,Even,directions,displacements),
 | 
			
		||||
  StencilEven(_FiveDimRedBlackGrid,npoint,Even,directions,displacements), // source is Even
 | 
			
		||||
  StencilOdd (_FiveDimRedBlackGrid,npoint,Odd ,directions,displacements), // source is Odd
 | 
			
		||||
  mass(_mass),
 | 
			
		||||
  Umu(_FourDimGrid),
 | 
			
		||||
  UmuEven(_FourDimRedBlackGrid),
 | 
			
		||||
  UmuOdd (_FourDimRedBlackGrid),
 | 
			
		||||
  Lebesgue(_FourDimGrid),
 | 
			
		||||
  LebesgueEvenOdd(_FourDimRedBlackGrid)
 | 
			
		||||
{
 | 
			
		||||
  // some assertions
 | 
			
		||||
  assert(FiveDimGrid._ndimension==5);
 | 
			
		||||
  assert(FourDimGrid._ndimension==4);
 | 
			
		||||
  
 | 
			
		||||
  assert(FiveDimRedBlackGrid._ndimension==5);
 | 
			
		||||
  assert(FourDimRedBlackGrid._ndimension==4);
 | 
			
		||||
 | 
			
		||||
  assert(FiveDimRedBlackGrid._checker_dim==1);
 | 
			
		||||
 | 
			
		||||
  // Dimension zero of the five-d is the Ls direction
 | 
			
		||||
  Ls=FiveDimGrid._fdimensions[0];
 | 
			
		||||
  assert(FiveDimRedBlackGrid._fdimensions[0]==Ls);
 | 
			
		||||
  assert(FiveDimRedBlackGrid._processors[0] ==1);
 | 
			
		||||
  assert(FiveDimRedBlackGrid._simd_layout[0]==1);
 | 
			
		||||
  assert(FiveDimGrid._processors[0]         ==1);
 | 
			
		||||
  assert(FiveDimGrid._simd_layout[0]        ==1);
 | 
			
		||||
 | 
			
		||||
  // Other dimensions must match the decomposition of the four-D fields 
 | 
			
		||||
  for(int d=0;d<4;d++){
 | 
			
		||||
    assert(FourDimRedBlackGrid._fdimensions[d]  ==FourDimGrid._fdimensions[d]);
 | 
			
		||||
    assert(FiveDimRedBlackGrid._fdimensions[d+1]==FourDimGrid._fdimensions[d]);
 | 
			
		||||
 | 
			
		||||
    assert(FourDimRedBlackGrid._processors[d]   ==FourDimGrid._processors[d]);
 | 
			
		||||
    assert(FiveDimRedBlackGrid._processors[d+1] ==FourDimGrid._processors[d]);
 | 
			
		||||
 | 
			
		||||
    assert(FourDimRedBlackGrid._simd_layout[d]  ==FourDimGrid._simd_layout[d]);
 | 
			
		||||
    assert(FiveDimRedBlackGrid._simd_layout[d+1]==FourDimGrid._simd_layout[d]);
 | 
			
		||||
 | 
			
		||||
    assert(FiveDimGrid._fdimensions[d+1]        ==FourDimGrid._fdimensions[d]);
 | 
			
		||||
    assert(FiveDimGrid._processors[d+1]         ==FourDimGrid._processors[d]);
 | 
			
		||||
    assert(FiveDimGrid._simd_layout[d+1]        ==FourDimGrid._simd_layout[d]);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // Allocate the required comms buffer
 | 
			
		||||
  comm_buf.resize(Stencil._unified_buffer_size); // this is always big enough to contain EO
 | 
			
		||||
  
 | 
			
		||||
  DoubleStore(Umu,_Umu);
 | 
			
		||||
  pickCheckerboard(Even,UmuEven,Umu);
 | 
			
		||||
  pickCheckerboard(Odd ,UmuOdd,Umu);
 | 
			
		||||
}
 | 
			
		||||
void FiveDimWilsonFermion::DoubleStore(LatticeDoubledGaugeField &Uds,const LatticeGaugeField &Umu)
 | 
			
		||||
{
 | 
			
		||||
  conformable(Uds._grid,GaugeGrid());
 | 
			
		||||
  conformable(Umu._grid,GaugeGrid());
 | 
			
		||||
  LatticeColourMatrix U(GaugeGrid());
 | 
			
		||||
  for(int mu=0;mu<Nd;mu++){
 | 
			
		||||
    U = peekIndex<LorentzIndex>(Umu,mu);
 | 
			
		||||
    pokeIndex<LorentzIndex>(Uds,U,mu);
 | 
			
		||||
    U = adj(Cshift(U,mu,-1));
 | 
			
		||||
    pokeIndex<LorentzIndex>(Uds,U,mu+4);
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
RealD FiveDimWilsonFermion::M(const LatticeFermion &in, LatticeFermion &out)
 | 
			
		||||
{
 | 
			
		||||
  out.checkerboard=in.checkerboard;
 | 
			
		||||
  Dhop(in,out,DaggerNo);
 | 
			
		||||
  return axpy_norm(out,5.0-M5,in,out);
 | 
			
		||||
}
 | 
			
		||||
RealD FiveDimWilsonFermion::Mdag(const LatticeFermion &in, LatticeFermion &out)
 | 
			
		||||
{
 | 
			
		||||
  out.checkerboard=in.checkerboard;
 | 
			
		||||
  Dhop(in,out,DaggerYes);
 | 
			
		||||
  return axpy_norm(out,5.0-M5,in,out);
 | 
			
		||||
}
 | 
			
		||||
void FiveDimWilsonFermion::Meooe(const LatticeFermion &in, LatticeFermion &out)
 | 
			
		||||
{
 | 
			
		||||
  if ( in.checkerboard == Odd ) {
 | 
			
		||||
    DhopEO(in,out,DaggerNo);
 | 
			
		||||
  } else {
 | 
			
		||||
    DhopOE(in,out,DaggerNo);
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
void FiveDimWilsonFermion::MeooeDag(const LatticeFermion &in, LatticeFermion &out)
 | 
			
		||||
{
 | 
			
		||||
  if ( in.checkerboard == Odd ) {
 | 
			
		||||
    DhopEO(in,out,DaggerYes);
 | 
			
		||||
  } else {
 | 
			
		||||
    DhopOE(in,out,DaggerYes);
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
void FiveDimWilsonFermion::Mooee(const LatticeFermion &in, LatticeFermion &out)
 | 
			
		||||
{
 | 
			
		||||
  out.checkerboard = in.checkerboard;
 | 
			
		||||
  out = (5.0-M5)*in;
 | 
			
		||||
  return ;
 | 
			
		||||
}
 | 
			
		||||
void FiveDimWilsonFermion::MooeeDag(const LatticeFermion &in, LatticeFermion &out)
 | 
			
		||||
{
 | 
			
		||||
  out.checkerboard = in.checkerboard;
 | 
			
		||||
  Mooee(in,out);
 | 
			
		||||
}
 | 
			
		||||
void FiveDimWilsonFermion::MooeeInv(const LatticeFermion &in, LatticeFermion &out)
 | 
			
		||||
{
 | 
			
		||||
  out.checkerboard = in.checkerboard;
 | 
			
		||||
  out = (1.0/(5.0-M5))*in;
 | 
			
		||||
  return ;
 | 
			
		||||
}
 | 
			
		||||
void FiveDimWilsonFermion::MooeeInvDag(const LatticeFermion &in, LatticeFermion &out)
 | 
			
		||||
{
 | 
			
		||||
  out.checkerboard = in.checkerboard;
 | 
			
		||||
  MooeeInv(in,out);
 | 
			
		||||
}
 | 
			
		||||
void FiveDimWilsonFermion::DhopInternal(CartesianStencil & st, LebesgueOrder &lo,
 | 
			
		||||
					LatticeDoubledGaugeField & U,
 | 
			
		||||
					const LatticeFermion &in, LatticeFermion &out,int dag)
 | 
			
		||||
{
 | 
			
		||||
  assert((dag==DaggerNo) ||(dag==DaggerYes));
 | 
			
		||||
 | 
			
		||||
  WilsonCompressor compressor(dag);
 | 
			
		||||
 | 
			
		||||
  st.HaloExchange<vSpinColourVector,vHalfSpinColourVector,WilsonCompressor>(in,comm_buf,compressor);
 | 
			
		||||
  
 | 
			
		||||
  // Dhop takes the 4d grid from U, and makes a 5d index for fermion
 | 
			
		||||
  // Not loop ordering and data layout.
 | 
			
		||||
  // Designed to create 
 | 
			
		||||
  // - per thread reuse in L1 cache for U
 | 
			
		||||
  // - 8 linear access unit stride streams per thread for Fermion for hw prefetchable.
 | 
			
		||||
  if ( dag == DaggerYes ) {
 | 
			
		||||
    if( HandOptDslash ) {
 | 
			
		||||
      for(int ss=0;ss<U._grid->oSites();ss++){
 | 
			
		||||
	int sU=lo.Reorder(ss);
 | 
			
		||||
PARALLEL_FOR_LOOP
 | 
			
		||||
	for(int s=0;s<Ls;s++){
 | 
			
		||||
	  int sF = s+Ls*sU;
 | 
			
		||||
	  DiracOptHand::DhopSiteDag(st,U,comm_buf,sF,sU,in,out);
 | 
			
		||||
	}
 | 
			
		||||
      }
 | 
			
		||||
    } else { 
 | 
			
		||||
      for(int ss=0;ss<U._grid->oSites();ss++){
 | 
			
		||||
	int sU=lo.Reorder(ss);
 | 
			
		||||
PARALLEL_FOR_LOOP
 | 
			
		||||
	for(int s=0;s<Ls;s++){
 | 
			
		||||
	  int sF = s+Ls*sU;
 | 
			
		||||
	  DiracOpt::DhopSiteDag(st,U,comm_buf,sF,sU,in,out);
 | 
			
		||||
	}
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
  } else {
 | 
			
		||||
    if( HandOptDslash ) {
 | 
			
		||||
 | 
			
		||||
PARALLEL_FOR_LOOP
 | 
			
		||||
      for(int ss=0;ss<U._grid->oSites();ss++){
 | 
			
		||||
	int sU=lo.Reorder(ss);
 | 
			
		||||
	for(int s=0;s<Ls;s++){
 | 
			
		||||
	  int sF = s+Ls*sU;
 | 
			
		||||
	  DiracOptHand::DhopSite(st,U,comm_buf,sF,sU,in,out);
 | 
			
		||||
	}
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
    } else { 
 | 
			
		||||
      for(int ss=0;ss<U._grid->oSites();ss++){
 | 
			
		||||
	int sU=lo.Reorder(ss);
 | 
			
		||||
PARALLEL_FOR_LOOP
 | 
			
		||||
	for(int s=0;s<Ls;s++){
 | 
			
		||||
	  int sF = s+Ls*sU; 
 | 
			
		||||
	  DiracOpt::DhopSite(st,U,comm_buf,sF,sU,in,out);
 | 
			
		||||
	}
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
void FiveDimWilsonFermion::DhopOE(const LatticeFermion &in, LatticeFermion &out,int dag)
 | 
			
		||||
{
 | 
			
		||||
  conformable(in._grid,FermionRedBlackGrid());    // 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);
 | 
			
		||||
}
 | 
			
		||||
void FiveDimWilsonFermion::DhopEO(const LatticeFermion &in, LatticeFermion &out,int dag)
 | 
			
		||||
{
 | 
			
		||||
  conformable(in._grid,FermionRedBlackGrid());    // 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);
 | 
			
		||||
}
 | 
			
		||||
void FiveDimWilsonFermion::Dhop(const LatticeFermion &in, LatticeFermion &out,int dag)
 | 
			
		||||
{
 | 
			
		||||
  conformable(in._grid,FermionGrid()); // verifies full grid
 | 
			
		||||
  conformable(in._grid,out._grid);
 | 
			
		||||
 | 
			
		||||
  out.checkerboard = in.checkerboard;
 | 
			
		||||
 | 
			
		||||
  DhopInternal(Stencil,Lebesgue,Umu,in,out,dag);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
}}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										108
									
								
								lib/qcd/action/fermion/FiveDimWilsonFermion.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										108
									
								
								lib/qcd/action/fermion/FiveDimWilsonFermion.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,108 @@
 | 
			
		||||
#ifndef  GRID_QCD_DWF_H
 | 
			
		||||
#define  GRID_QCD_DWF_H
 | 
			
		||||
 | 
			
		||||
namespace Grid {
 | 
			
		||||
 | 
			
		||||
  namespace QCD {
 | 
			
		||||
 | 
			
		||||
    ////////////////////////////////////////////////////////////////////////////////
 | 
			
		||||
    // This is the 4d red black case appropriate to support
 | 
			
		||||
    //
 | 
			
		||||
    // parity = (x+y+z+t)|2;
 | 
			
		||||
    // generalised five dim fermions like mobius, zolotarev etc..	
 | 
			
		||||
    //
 | 
			
		||||
    // i.e. even even contains fifth dim hopping term.
 | 
			
		||||
    //
 | 
			
		||||
    // [DIFFERS from original CPS red black implementation parity = (x+y+z+t+s)|2 ]
 | 
			
		||||
    ////////////////////////////////////////////////////////////////////////////////
 | 
			
		||||
    class FiveDimWilsonFermion : public FermionAction<LatticeFermion,LatticeGaugeField>
 | 
			
		||||
    {
 | 
			
		||||
    public:
 | 
			
		||||
      ///////////////////////////////////////////////////////////////
 | 
			
		||||
      // Implement the abstract base
 | 
			
		||||
      ///////////////////////////////////////////////////////////////
 | 
			
		||||
      GridBase *GaugeGrid(void)              { return _FourDimGrid ;}
 | 
			
		||||
      GridBase *GaugeRedBlackGrid(void)      { return _FourDimRedBlackGrid ;}
 | 
			
		||||
      GridBase *FermionGrid(void)            { return _FiveDimGrid;}
 | 
			
		||||
      GridBase *FermionRedBlackGrid(void)    { return _FiveDimRedBlackGrid;}
 | 
			
		||||
 | 
			
		||||
      // override multiply
 | 
			
		||||
      virtual RealD  M    (const LatticeFermion &in, LatticeFermion &out);
 | 
			
		||||
      virtual RealD  Mdag (const LatticeFermion &in, LatticeFermion &out);
 | 
			
		||||
 | 
			
		||||
      // half checkerboard operaions
 | 
			
		||||
      virtual void   Meooe       (const LatticeFermion &in, LatticeFermion &out);
 | 
			
		||||
      virtual void   MeooeDag    (const LatticeFermion &in, LatticeFermion &out);
 | 
			
		||||
      virtual void   Mooee       (const LatticeFermion &in, LatticeFermion &out);
 | 
			
		||||
      virtual void   MooeeDag    (const LatticeFermion &in, LatticeFermion &out);
 | 
			
		||||
      virtual void   MooeeInv    (const LatticeFermion &in, LatticeFermion &out);
 | 
			
		||||
      virtual void   MooeeInvDag (const LatticeFermion &in, LatticeFermion &out);
 | 
			
		||||
 | 
			
		||||
      // non-hermitian hopping term; half cb or both
 | 
			
		||||
      void Dhop  (const LatticeFermion &in, LatticeFermion &out,int dag);
 | 
			
		||||
      void DhopOE(const LatticeFermion &in, LatticeFermion &out,int dag);
 | 
			
		||||
      void DhopEO(const LatticeFermion &in, LatticeFermion &out,int dag);
 | 
			
		||||
 | 
			
		||||
      ///////////////////////////////////////////////////////////////
 | 
			
		||||
      // New methods added 
 | 
			
		||||
      ///////////////////////////////////////////////////////////////
 | 
			
		||||
      void DhopInternal(CartesianStencil & st,
 | 
			
		||||
			LebesgueOrder &lo,
 | 
			
		||||
			LatticeDoubledGaugeField &U,
 | 
			
		||||
			const LatticeFermion &in, 
 | 
			
		||||
			LatticeFermion &out,
 | 
			
		||||
			int dag);
 | 
			
		||||
 | 
			
		||||
      // Constructors
 | 
			
		||||
      FiveDimWilsonFermion(LatticeGaugeField &_Umu,
 | 
			
		||||
			  GridCartesian         &FiveDimGrid,
 | 
			
		||||
			  GridRedBlackCartesian &FiveDimRedBlackGrid,
 | 
			
		||||
			  GridCartesian         &FourDimGrid,
 | 
			
		||||
			  GridRedBlackCartesian &FourDimRedBlackGrid,
 | 
			
		||||
			  double _mass);
 | 
			
		||||
 | 
			
		||||
      // DoubleStore
 | 
			
		||||
      void DoubleStore(LatticeDoubledGaugeField &Uds,const LatticeGaugeField &Umu);
 | 
			
		||||
 | 
			
		||||
      ///////////////////////////////////////////////////////////////
 | 
			
		||||
      // Data members require to support the functionality
 | 
			
		||||
      ///////////////////////////////////////////////////////////////
 | 
			
		||||
      static int HandOptDslash; // these are a temporary hack
 | 
			
		||||
 | 
			
		||||
    protected:
 | 
			
		||||
 | 
			
		||||
      // Add these to the support from Wilson
 | 
			
		||||
      GridBase *_FourDimGrid;
 | 
			
		||||
      GridBase *_FourDimRedBlackGrid;
 | 
			
		||||
      GridBase *_FiveDimGrid;
 | 
			
		||||
      GridBase *_FiveDimRedBlackGrid;
 | 
			
		||||
 | 
			
		||||
      static const int npoint=8;
 | 
			
		||||
      static const std::vector<int> directions   ;
 | 
			
		||||
      static const std::vector<int> displacements;
 | 
			
		||||
 | 
			
		||||
      double                        M5;
 | 
			
		||||
      double                        mass;
 | 
			
		||||
      int Ls;
 | 
			
		||||
 | 
			
		||||
      //Defines the stencils for even and odd
 | 
			
		||||
      CartesianStencil Stencil; 
 | 
			
		||||
      CartesianStencil StencilEven; 
 | 
			
		||||
      CartesianStencil StencilOdd; 
 | 
			
		||||
 | 
			
		||||
      // Copy of the gauge field , with even and odd subsets
 | 
			
		||||
      LatticeDoubledGaugeField Umu;
 | 
			
		||||
      LatticeDoubledGaugeField UmuEven;
 | 
			
		||||
      LatticeDoubledGaugeField UmuOdd;
 | 
			
		||||
 | 
			
		||||
      LebesgueOrder Lebesgue;
 | 
			
		||||
      LebesgueOrder LebesgueEvenOdd;
 | 
			
		||||
 | 
			
		||||
      // Comms buffer
 | 
			
		||||
      std::vector<vHalfSpinColourVector,alignedAllocator<vHalfSpinColourVector> >  comm_buf;
 | 
			
		||||
      
 | 
			
		||||
    };
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
							
								
								
									
										61
									
								
								lib/qcd/action/fermion/WilsonCompressor.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										61
									
								
								lib/qcd/action/fermion/WilsonCompressor.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,61 @@
 | 
			
		||||
#ifndef  GRID_QCD_WILSON_COMPRESSOR_H
 | 
			
		||||
#define  GRID_QCD_WILSON_COMPRESSOR_H
 | 
			
		||||
 | 
			
		||||
namespace Grid {
 | 
			
		||||
namespace QCD {
 | 
			
		||||
 | 
			
		||||
  class WilsonCompressor {
 | 
			
		||||
  public:
 | 
			
		||||
    int mu;
 | 
			
		||||
    int dag;
 | 
			
		||||
 | 
			
		||||
    WilsonCompressor(int _dag){
 | 
			
		||||
      mu=0;
 | 
			
		||||
      dag=_dag;
 | 
			
		||||
      assert((dag==0)||(dag==1));
 | 
			
		||||
    }
 | 
			
		||||
    void Point(int p) { 
 | 
			
		||||
      mu=p;
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    vHalfSpinColourVector operator () (const vSpinColourVector &in)
 | 
			
		||||
    {
 | 
			
		||||
      vHalfSpinColourVector ret;
 | 
			
		||||
      int mudag=mu;
 | 
			
		||||
      if (dag) {
 | 
			
		||||
	mudag=(mu+Nd)%(2*Nd);
 | 
			
		||||
      }
 | 
			
		||||
      switch(mudag) {
 | 
			
		||||
      case Xp:
 | 
			
		||||
	spProjXp(ret,in);
 | 
			
		||||
	break;
 | 
			
		||||
      case Yp:
 | 
			
		||||
	spProjYp(ret,in);
 | 
			
		||||
	break;
 | 
			
		||||
      case Zp:
 | 
			
		||||
	spProjZp(ret,in);
 | 
			
		||||
	break;
 | 
			
		||||
      case Tp:
 | 
			
		||||
	spProjTp(ret,in);
 | 
			
		||||
	break;
 | 
			
		||||
      case Xm:
 | 
			
		||||
	spProjXm(ret,in);
 | 
			
		||||
	break;
 | 
			
		||||
      case Ym:
 | 
			
		||||
	spProjYm(ret,in);
 | 
			
		||||
	break;
 | 
			
		||||
      case Zm:
 | 
			
		||||
	spProjZm(ret,in);
 | 
			
		||||
	break;
 | 
			
		||||
      case Tm:
 | 
			
		||||
	spProjTm(ret,in);
 | 
			
		||||
	break;
 | 
			
		||||
      default: 
 | 
			
		||||
	assert(0);
 | 
			
		||||
	break;
 | 
			
		||||
      }
 | 
			
		||||
      return ret;
 | 
			
		||||
    }
 | 
			
		||||
  };
 | 
			
		||||
}} // namespace close
 | 
			
		||||
#endif
 | 
			
		||||
							
								
								
									
										163
									
								
								lib/qcd/action/fermion/WilsonFermion.cc
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										163
									
								
								lib/qcd/action/fermion/WilsonFermion.cc
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,163 @@
 | 
			
		||||
#include <Grid.h>
 | 
			
		||||
 | 
			
		||||
namespace Grid {
 | 
			
		||||
namespace QCD {
 | 
			
		||||
 | 
			
		||||
const std::vector<int> WilsonFermion::directions   ({0,1,2,3, 0, 1, 2, 3});
 | 
			
		||||
const std::vector<int> WilsonFermion::displacements({1,1,1,1,-1,-1,-1,-1});
 | 
			
		||||
 | 
			
		||||
int WilsonFermion::HandOptDslash;
 | 
			
		||||
 | 
			
		||||
WilsonFermion::WilsonFermion(LatticeGaugeField &_Umu,
 | 
			
		||||
			   GridCartesian         &Fgrid,
 | 
			
		||||
			   GridRedBlackCartesian &Hgrid, 
 | 
			
		||||
			   double _mass) :
 | 
			
		||||
  _grid(&Fgrid),
 | 
			
		||||
  _cbgrid(&Hgrid),
 | 
			
		||||
  Stencil    (&Fgrid,npoint,Even,directions,displacements),
 | 
			
		||||
  StencilEven(&Hgrid,npoint,Even,directions,displacements), // source is Even
 | 
			
		||||
  StencilOdd (&Hgrid,npoint,Odd ,directions,displacements), // source is Odd
 | 
			
		||||
  mass(_mass),
 | 
			
		||||
  Umu(&Fgrid),
 | 
			
		||||
  UmuEven(&Hgrid),
 | 
			
		||||
  UmuOdd (&Hgrid)
 | 
			
		||||
{
 | 
			
		||||
  // Allocate the required comms buffer
 | 
			
		||||
  comm_buf.resize(Stencil._unified_buffer_size); // this is always big enough to contain EO
 | 
			
		||||
  DoubleStore(Umu,_Umu);
 | 
			
		||||
  pickCheckerboard(Even,UmuEven,Umu);
 | 
			
		||||
  pickCheckerboard(Odd ,UmuOdd,Umu);
 | 
			
		||||
}
 | 
			
		||||
      
 | 
			
		||||
void WilsonFermion::DoubleStore(LatticeDoubledGaugeField &Uds,const LatticeGaugeField &Umu)
 | 
			
		||||
{
 | 
			
		||||
  conformable(Uds._grid,GaugeGrid());
 | 
			
		||||
  conformable(Umu._grid,GaugeGrid());
 | 
			
		||||
  LatticeColourMatrix U(GaugeGrid());
 | 
			
		||||
  for(int mu=0;mu<Nd;mu++){
 | 
			
		||||
    U = peekIndex<LorentzIndex>(Umu,mu);
 | 
			
		||||
    pokeIndex<LorentzIndex>(Uds,U,mu);
 | 
			
		||||
    U = adj(Cshift(U,mu,-1));
 | 
			
		||||
    pokeIndex<LorentzIndex>(Uds,U,mu+4);
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
RealD WilsonFermion::M(const LatticeFermion &in, LatticeFermion &out)
 | 
			
		||||
{
 | 
			
		||||
  out.checkerboard=in.checkerboard;
 | 
			
		||||
  Dhop(in,out,DaggerNo);
 | 
			
		||||
  return axpy_norm(out,4+mass,in,out);
 | 
			
		||||
}
 | 
			
		||||
RealD WilsonFermion::Mdag(const LatticeFermion &in, LatticeFermion &out)
 | 
			
		||||
{
 | 
			
		||||
  out.checkerboard=in.checkerboard;
 | 
			
		||||
  Dhop(in,out,DaggerYes);
 | 
			
		||||
  return axpy_norm(out,4+mass,in,out);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void WilsonFermion::Meooe(const LatticeFermion &in, LatticeFermion &out)
 | 
			
		||||
{
 | 
			
		||||
  if ( in.checkerboard == Odd ) {
 | 
			
		||||
    DhopEO(in,out,DaggerNo);
 | 
			
		||||
  } else {
 | 
			
		||||
    DhopOE(in,out,DaggerNo);
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
void WilsonFermion::MeooeDag(const LatticeFermion &in, LatticeFermion &out)
 | 
			
		||||
{
 | 
			
		||||
  if ( in.checkerboard == Odd ) {
 | 
			
		||||
    DhopEO(in,out,DaggerYes);
 | 
			
		||||
  } else {
 | 
			
		||||
    DhopOE(in,out,DaggerYes);
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
void WilsonFermion::Mooee(const LatticeFermion &in, LatticeFermion &out)
 | 
			
		||||
{
 | 
			
		||||
  out.checkerboard = in.checkerboard;
 | 
			
		||||
  out = (4.0+mass)*in;
 | 
			
		||||
  return ;
 | 
			
		||||
}
 | 
			
		||||
void WilsonFermion::MooeeDag(const LatticeFermion &in, LatticeFermion &out)
 | 
			
		||||
{
 | 
			
		||||
  out.checkerboard = in.checkerboard;
 | 
			
		||||
  Mooee(in,out);
 | 
			
		||||
}
 | 
			
		||||
void WilsonFermion::MooeeInv(const LatticeFermion &in, LatticeFermion &out)
 | 
			
		||||
{
 | 
			
		||||
  out.checkerboard = in.checkerboard;
 | 
			
		||||
  out = (1.0/(4.0+mass))*in;
 | 
			
		||||
  return ;
 | 
			
		||||
}
 | 
			
		||||
void WilsonFermion::MooeeInvDag(const LatticeFermion &in, LatticeFermion &out)
 | 
			
		||||
{
 | 
			
		||||
  out.checkerboard = in.checkerboard;
 | 
			
		||||
  MooeeInv(in,out);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void WilsonFermion::DhopInternal(CartesianStencil & st,LatticeDoubledGaugeField & U,
 | 
			
		||||
				const LatticeFermion &in, LatticeFermion &out,int dag)
 | 
			
		||||
{
 | 
			
		||||
  assert((dag==DaggerNo) ||(dag==DaggerYes));
 | 
			
		||||
  WilsonCompressor compressor(dag);
 | 
			
		||||
  st.HaloExchange<vSpinColourVector,vHalfSpinColourVector,WilsonCompressor>(in,comm_buf,compressor);
 | 
			
		||||
 | 
			
		||||
  if ( dag == DaggerYes ) {
 | 
			
		||||
    if( HandOptDslash ) {
 | 
			
		||||
PARALLEL_FOR_LOOP
 | 
			
		||||
      for(int sss=0;sss<in._grid->oSites();sss++){
 | 
			
		||||
        DiracOptHand::DhopSiteDag(st,U,comm_buf,sss,sss,in,out);
 | 
			
		||||
      }
 | 
			
		||||
    } else { 
 | 
			
		||||
PARALLEL_FOR_LOOP
 | 
			
		||||
      for(int sss=0;sss<in._grid->oSites();sss++){
 | 
			
		||||
        DiracOpt::DhopSiteDag(st,U,comm_buf,sss,sss,in,out);
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
  } else {
 | 
			
		||||
    if( HandOptDslash ) {
 | 
			
		||||
PARALLEL_FOR_LOOP
 | 
			
		||||
      for(int sss=0;sss<in._grid->oSites();sss++){
 | 
			
		||||
        DiracOptHand::DhopSite(st,U,comm_buf,sss,sss,in,out);
 | 
			
		||||
      }
 | 
			
		||||
    } else { 
 | 
			
		||||
PARALLEL_FOR_LOOP
 | 
			
		||||
      for(int sss=0;sss<in._grid->oSites();sss++){
 | 
			
		||||
        DiracOpt::DhopSite(st,U,comm_buf,sss,sss,in,out);
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
void WilsonFermion::DhopOE(const LatticeFermion &in, LatticeFermion &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,UmuOdd,in,out,dag);
 | 
			
		||||
}
 | 
			
		||||
void WilsonFermion::DhopEO(const LatticeFermion &in, LatticeFermion &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,UmuEven,in,out,dag);
 | 
			
		||||
}
 | 
			
		||||
void WilsonFermion::Dhop(const LatticeFermion &in, LatticeFermion &out,int dag)
 | 
			
		||||
{
 | 
			
		||||
  conformable(in._grid,_grid); // verifies full grid
 | 
			
		||||
  conformable(in._grid,out._grid);
 | 
			
		||||
 | 
			
		||||
  out.checkerboard = in.checkerboard;
 | 
			
		||||
 | 
			
		||||
  DhopInternal(Stencil,Umu,in,out,dag);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
}}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										87
									
								
								lib/qcd/action/fermion/WilsonFermion.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										87
									
								
								lib/qcd/action/fermion/WilsonFermion.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,87 @@
 | 
			
		||||
#ifndef  GRID_QCD_WILSON_FERMION_H
 | 
			
		||||
#define  GRID_QCD_WILSON_FERMION_H
 | 
			
		||||
 | 
			
		||||
namespace Grid {
 | 
			
		||||
 | 
			
		||||
  namespace QCD {
 | 
			
		||||
 | 
			
		||||
    class WilsonFermion : public FermionAction<LatticeFermion,LatticeGaugeField>
 | 
			
		||||
    {
 | 
			
		||||
    public:
 | 
			
		||||
 | 
			
		||||
      ///////////////////////////////////////////////////////////////
 | 
			
		||||
      // Implement the abstract base
 | 
			
		||||
      ///////////////////////////////////////////////////////////////
 | 
			
		||||
      GridBase *GaugeGrid(void)              { return _grid ;}
 | 
			
		||||
      GridBase *GaugeRedBlackGrid(void)      { return _cbgrid ;}
 | 
			
		||||
      GridBase *FermionGrid(void)            { return _grid;}
 | 
			
		||||
      GridBase *FermionRedBlackGrid(void)    { return _cbgrid;}
 | 
			
		||||
 | 
			
		||||
      // override multiply
 | 
			
		||||
      virtual RealD  M    (const LatticeFermion &in, LatticeFermion &out);
 | 
			
		||||
      virtual RealD  Mdag (const LatticeFermion &in, LatticeFermion &out);
 | 
			
		||||
 | 
			
		||||
      // half checkerboard operaions
 | 
			
		||||
      void   Meooe       (const LatticeFermion &in, LatticeFermion &out);
 | 
			
		||||
      void   MeooeDag    (const LatticeFermion &in, LatticeFermion &out);
 | 
			
		||||
      virtual void   Mooee       (const LatticeFermion &in, LatticeFermion &out); // remain virtual so we 
 | 
			
		||||
      virtual void   MooeeDag    (const LatticeFermion &in, LatticeFermion &out); // can derive Clover
 | 
			
		||||
      virtual void   MooeeInv    (const LatticeFermion &in, LatticeFermion &out); // from Wilson bas
 | 
			
		||||
      virtual void   MooeeInvDag (const LatticeFermion &in, LatticeFermion &out);
 | 
			
		||||
 | 
			
		||||
      // non-hermitian hopping term; half cb or both
 | 
			
		||||
      void Dhop  (const LatticeFermion &in, LatticeFermion &out,int dag);
 | 
			
		||||
      void DhopOE(const LatticeFermion &in, LatticeFermion &out,int dag);
 | 
			
		||||
      void DhopEO(const LatticeFermion &in, LatticeFermion &out,int dag);
 | 
			
		||||
 | 
			
		||||
      ///////////////////////////////////////////////////////////////
 | 
			
		||||
      // Extra methods added by derived
 | 
			
		||||
      ///////////////////////////////////////////////////////////////
 | 
			
		||||
      void DhopInternal(CartesianStencil & st,
 | 
			
		||||
			LatticeDoubledGaugeField &U,
 | 
			
		||||
			const LatticeFermion &in, 
 | 
			
		||||
			LatticeFermion &out,
 | 
			
		||||
			int dag);
 | 
			
		||||
 | 
			
		||||
      // Constructor
 | 
			
		||||
      WilsonFermion(LatticeGaugeField &_Umu,GridCartesian &Fgrid,GridRedBlackCartesian &Hgrid,double _mass);
 | 
			
		||||
 | 
			
		||||
      // DoubleStore
 | 
			
		||||
      void DoubleStore(LatticeDoubledGaugeField &Uds,const LatticeGaugeField &Umu);
 | 
			
		||||
 | 
			
		||||
      ///////////////////////////////////////////////////////////////
 | 
			
		||||
      // Data members require to support the functionality
 | 
			
		||||
      ///////////////////////////////////////////////////////////////
 | 
			
		||||
      static int HandOptDslash; // these are a temporary hack
 | 
			
		||||
      static int MortonOrder;
 | 
			
		||||
 | 
			
		||||
    protected:
 | 
			
		||||
 | 
			
		||||
      double                        mass;
 | 
			
		||||
 | 
			
		||||
      GridBase                     *    _grid; 
 | 
			
		||||
      GridBase                     *  _cbgrid;
 | 
			
		||||
 | 
			
		||||
      static const int npoint=8;
 | 
			
		||||
      static const std::vector<int> directions   ;
 | 
			
		||||
      static const std::vector<int> displacements;
 | 
			
		||||
 | 
			
		||||
      //Defines the stencils for even and odd
 | 
			
		||||
      CartesianStencil Stencil; 
 | 
			
		||||
      CartesianStencil StencilEven; 
 | 
			
		||||
      CartesianStencil StencilOdd; 
 | 
			
		||||
 | 
			
		||||
      // Copy of the gauge field , with even and odd subsets
 | 
			
		||||
      LatticeDoubledGaugeField Umu;
 | 
			
		||||
      LatticeDoubledGaugeField UmuEven;
 | 
			
		||||
      LatticeDoubledGaugeField UmuOdd;
 | 
			
		||||
 | 
			
		||||
      // Comms buffer
 | 
			
		||||
      std::vector<vHalfSpinColourVector,alignedAllocator<vHalfSpinColourVector> >  comm_buf;
 | 
			
		||||
 | 
			
		||||
      
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
#endif
 | 
			
		||||
@@ -5,7 +5,7 @@ namespace QCD {
 | 
			
		||||
 | 
			
		||||
void DiracOpt::DhopSite(CartesianStencil &st,LatticeDoubledGaugeField &U,
 | 
			
		||||
			std::vector<vHalfSpinColourVector,alignedAllocator<vHalfSpinColourVector> >  &buf,
 | 
			
		||||
			    int ss,const LatticeFermion &in, LatticeFermion &out)
 | 
			
		||||
			int sF,int sU,const LatticeFermion &in, LatticeFermion &out)
 | 
			
		||||
{
 | 
			
		||||
    vHalfSpinColourVector  tmp;    
 | 
			
		||||
    vHalfSpinColourVector  chi;    
 | 
			
		||||
@@ -16,6 +16,7 @@ void DiracOpt::DhopSite(CartesianStencil &st,LatticeDoubledGaugeField &U,
 | 
			
		||||
    //#define VERBOSE( A)  if ( ss<10 ) { std::cout << "site " <<ss << " " #A " neigh " << offset << " perm "<< perm <<std::endl;}    
 | 
			
		||||
 | 
			
		||||
    // Xp
 | 
			
		||||
    int ss = sF;
 | 
			
		||||
    offset = st._offsets [Xp][ss];
 | 
			
		||||
    local  = st._is_local[Xp][ss];
 | 
			
		||||
    perm   = st._permute[Xp][ss];
 | 
			
		||||
@@ -29,7 +30,7 @@ void DiracOpt::DhopSite(CartesianStencil &st,LatticeDoubledGaugeField &U,
 | 
			
		||||
    } else { 
 | 
			
		||||
      chi=buf[offset];
 | 
			
		||||
    }
 | 
			
		||||
    mult(&Uchi(),&U._odata[ss](Xp),&chi());
 | 
			
		||||
    mult(&Uchi(),&U._odata[sU](Xp),&chi());
 | 
			
		||||
    spReconXp(result,Uchi);
 | 
			
		||||
 | 
			
		||||
    //    std::cout << "XP_RECON"<<std::endl;
 | 
			
		||||
@@ -51,7 +52,7 @@ void DiracOpt::DhopSite(CartesianStencil &st,LatticeDoubledGaugeField &U,
 | 
			
		||||
    } else { 
 | 
			
		||||
      chi=buf[offset];
 | 
			
		||||
    }
 | 
			
		||||
    mult(&Uchi(),&U._odata[ss](Yp),&chi());
 | 
			
		||||
    mult(&Uchi(),&U._odata[sU](Yp),&chi());
 | 
			
		||||
    accumReconYp(result,Uchi);
 | 
			
		||||
 | 
			
		||||
    // Zp
 | 
			
		||||
@@ -67,7 +68,7 @@ void DiracOpt::DhopSite(CartesianStencil &st,LatticeDoubledGaugeField &U,
 | 
			
		||||
    } else { 
 | 
			
		||||
      chi=buf[offset];
 | 
			
		||||
    }
 | 
			
		||||
    mult(&Uchi(),&U._odata[ss](Zp),&chi());
 | 
			
		||||
    mult(&Uchi(),&U._odata[sU](Zp),&chi());
 | 
			
		||||
    accumReconZp(result,Uchi);
 | 
			
		||||
 | 
			
		||||
    // Tp
 | 
			
		||||
@@ -83,7 +84,7 @@ void DiracOpt::DhopSite(CartesianStencil &st,LatticeDoubledGaugeField &U,
 | 
			
		||||
    } else { 
 | 
			
		||||
      chi=buf[offset];
 | 
			
		||||
    }
 | 
			
		||||
    mult(&Uchi(),&U._odata[ss](Tp),&chi());
 | 
			
		||||
    mult(&Uchi(),&U._odata[sU](Tp),&chi());
 | 
			
		||||
    accumReconTp(result,Uchi);
 | 
			
		||||
 | 
			
		||||
    // Xm
 | 
			
		||||
@@ -101,7 +102,7 @@ void DiracOpt::DhopSite(CartesianStencil &st,LatticeDoubledGaugeField &U,
 | 
			
		||||
    } else { 
 | 
			
		||||
      chi=buf[offset];
 | 
			
		||||
    }
 | 
			
		||||
    mult(&Uchi(),&U._odata[ss](Xm),&chi());
 | 
			
		||||
    mult(&Uchi(),&U._odata[sU](Xm),&chi());
 | 
			
		||||
    accumReconXm(result,Uchi);
 | 
			
		||||
    //  std::cout << "XM_RECON_ACCUM"<<std::endl;
 | 
			
		||||
    //    std::cout << result()(0)(0) <<" "<<result()(0)(1) <<" "<<result()(0)(2) <<std::endl;
 | 
			
		||||
@@ -124,7 +125,7 @@ void DiracOpt::DhopSite(CartesianStencil &st,LatticeDoubledGaugeField &U,
 | 
			
		||||
    } else { 
 | 
			
		||||
      chi=buf[offset];
 | 
			
		||||
    }
 | 
			
		||||
    mult(&Uchi(),&U._odata[ss](Ym),&chi());
 | 
			
		||||
    mult(&Uchi(),&U._odata[sU](Ym),&chi());
 | 
			
		||||
    accumReconYm(result,Uchi);
 | 
			
		||||
 | 
			
		||||
    // Zm
 | 
			
		||||
@@ -140,7 +141,7 @@ void DiracOpt::DhopSite(CartesianStencil &st,LatticeDoubledGaugeField &U,
 | 
			
		||||
    } else { 
 | 
			
		||||
      chi=buf[offset];
 | 
			
		||||
    }
 | 
			
		||||
    mult(&Uchi(),&U._odata[ss](Zm),&chi());
 | 
			
		||||
    mult(&Uchi(),&U._odata[sU](Zm),&chi());
 | 
			
		||||
    accumReconZm(result,Uchi);
 | 
			
		||||
 | 
			
		||||
    // Tm
 | 
			
		||||
@@ -156,15 +157,15 @@ void DiracOpt::DhopSite(CartesianStencil &st,LatticeDoubledGaugeField &U,
 | 
			
		||||
    } else { 
 | 
			
		||||
      chi=buf[offset];
 | 
			
		||||
    }
 | 
			
		||||
    mult(&Uchi(),&U._odata[ss](Tm),&chi());
 | 
			
		||||
    mult(&Uchi(),&U._odata[sU](Tm),&chi());
 | 
			
		||||
    accumReconTm(result,Uchi);
 | 
			
		||||
 | 
			
		||||
    vstream(out._odata[ss],result);
 | 
			
		||||
    vstream(out._odata[ss],result*(-0.5));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void DiracOpt::DhopSiteDag(CartesianStencil &st,LatticeDoubledGaugeField &U,
 | 
			
		||||
			   std::vector<vHalfSpinColourVector,alignedAllocator<vHalfSpinColourVector> >  &buf,
 | 
			
		||||
			       int ss,const LatticeFermion &in, LatticeFermion &out)
 | 
			
		||||
			   int sF,int sU,const LatticeFermion &in, LatticeFermion &out)
 | 
			
		||||
{
 | 
			
		||||
    vHalfSpinColourVector  tmp;    
 | 
			
		||||
    vHalfSpinColourVector  chi;    
 | 
			
		||||
@@ -173,6 +174,7 @@ void DiracOpt::DhopSiteDag(CartesianStencil &st,LatticeDoubledGaugeField &U,
 | 
			
		||||
    int offset,local,perm, ptype;
 | 
			
		||||
 | 
			
		||||
    // Xp
 | 
			
		||||
    int ss=sF;
 | 
			
		||||
    offset = st._offsets [Xm][ss];
 | 
			
		||||
    local  = st._is_local[Xm][ss];
 | 
			
		||||
    perm   = st._permute[Xm][ss];
 | 
			
		||||
@@ -186,7 +188,7 @@ void DiracOpt::DhopSiteDag(CartesianStencil &st,LatticeDoubledGaugeField &U,
 | 
			
		||||
    } else { 
 | 
			
		||||
      chi=buf[offset];
 | 
			
		||||
    }
 | 
			
		||||
    mult(&Uchi(),&U._odata[ss](Xm),&chi());
 | 
			
		||||
    mult(&Uchi(),&U._odata[sU](Xm),&chi());
 | 
			
		||||
    spReconXp(result,Uchi);
 | 
			
		||||
 | 
			
		||||
    // Yp
 | 
			
		||||
@@ -202,7 +204,7 @@ void DiracOpt::DhopSiteDag(CartesianStencil &st,LatticeDoubledGaugeField &U,
 | 
			
		||||
    } else { 
 | 
			
		||||
      chi=buf[offset];
 | 
			
		||||
    }
 | 
			
		||||
    mult(&Uchi(),&U._odata[ss](Ym),&chi());
 | 
			
		||||
    mult(&Uchi(),&U._odata[sU](Ym),&chi());
 | 
			
		||||
    accumReconYp(result,Uchi);
 | 
			
		||||
 | 
			
		||||
    // Zp
 | 
			
		||||
@@ -218,7 +220,7 @@ void DiracOpt::DhopSiteDag(CartesianStencil &st,LatticeDoubledGaugeField &U,
 | 
			
		||||
    } else { 
 | 
			
		||||
      chi=buf[offset];
 | 
			
		||||
    }
 | 
			
		||||
    mult(&Uchi(),&U._odata[ss](Zm),&chi());
 | 
			
		||||
    mult(&Uchi(),&U._odata[sU](Zm),&chi());
 | 
			
		||||
    accumReconZp(result,Uchi);
 | 
			
		||||
 | 
			
		||||
    // Tp
 | 
			
		||||
@@ -234,7 +236,7 @@ void DiracOpt::DhopSiteDag(CartesianStencil &st,LatticeDoubledGaugeField &U,
 | 
			
		||||
    } else { 
 | 
			
		||||
      chi=buf[offset];
 | 
			
		||||
    }
 | 
			
		||||
    mult(&Uchi(),&U._odata[ss](Tm),&chi());
 | 
			
		||||
    mult(&Uchi(),&U._odata[sU](Tm),&chi());
 | 
			
		||||
    accumReconTp(result,Uchi);
 | 
			
		||||
 | 
			
		||||
    // Xm
 | 
			
		||||
@@ -252,7 +254,7 @@ void DiracOpt::DhopSiteDag(CartesianStencil &st,LatticeDoubledGaugeField &U,
 | 
			
		||||
    } else { 
 | 
			
		||||
      chi=buf[offset];
 | 
			
		||||
    }
 | 
			
		||||
    mult(&Uchi(),&U._odata[ss](Xp),&chi());
 | 
			
		||||
    mult(&Uchi(),&U._odata[sU](Xp),&chi());
 | 
			
		||||
    accumReconXm(result,Uchi);
 | 
			
		||||
 | 
			
		||||
    // Ym
 | 
			
		||||
@@ -269,7 +271,7 @@ void DiracOpt::DhopSiteDag(CartesianStencil &st,LatticeDoubledGaugeField &U,
 | 
			
		||||
    } else { 
 | 
			
		||||
      chi=buf[offset];
 | 
			
		||||
    }
 | 
			
		||||
    mult(&Uchi(),&U._odata[ss](Yp),&chi());
 | 
			
		||||
    mult(&Uchi(),&U._odata[sU](Yp),&chi());
 | 
			
		||||
    accumReconYm(result,Uchi);
 | 
			
		||||
 | 
			
		||||
    // Zm
 | 
			
		||||
@@ -285,7 +287,7 @@ void DiracOpt::DhopSiteDag(CartesianStencil &st,LatticeDoubledGaugeField &U,
 | 
			
		||||
    } else { 
 | 
			
		||||
      chi=buf[offset];
 | 
			
		||||
    }
 | 
			
		||||
    mult(&Uchi(),&U._odata[ss](Zp),&chi());
 | 
			
		||||
    mult(&Uchi(),&U._odata[sU](Zp),&chi());
 | 
			
		||||
    accumReconZm(result,Uchi);
 | 
			
		||||
 | 
			
		||||
    // Tm
 | 
			
		||||
@@ -301,9 +303,9 @@ void DiracOpt::DhopSiteDag(CartesianStencil &st,LatticeDoubledGaugeField &U,
 | 
			
		||||
    } else { 
 | 
			
		||||
      chi=buf[offset];
 | 
			
		||||
    }
 | 
			
		||||
    mult(&Uchi(),&U._odata[ss](Tp),&chi());
 | 
			
		||||
    mult(&Uchi(),&U._odata[sU](Tp),&chi());
 | 
			
		||||
    accumReconTm(result,Uchi);
 | 
			
		||||
 | 
			
		||||
    vstream(out._odata[ss],result);
 | 
			
		||||
    vstream(out._odata[ss],result*(-0.5));
 | 
			
		||||
}
 | 
			
		||||
}}
 | 
			
		||||
							
								
								
									
										42
									
								
								lib/qcd/action/fermion/WilsonKernels.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										42
									
								
								lib/qcd/action/fermion/WilsonKernels.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,42 @@
 | 
			
		||||
#ifndef  GRID_QCD_DHOP_H
 | 
			
		||||
#define  GRID_QCD_DHOP_H
 | 
			
		||||
 | 
			
		||||
namespace Grid {
 | 
			
		||||
 | 
			
		||||
  namespace QCD {
 | 
			
		||||
 | 
			
		||||
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////
 | 
			
		||||
    // Helper classes that implement Wilson stencil for a single site.
 | 
			
		||||
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////
 | 
			
		||||
    
 | 
			
		||||
    // Generic version works for any Nc and with extra flavour indices
 | 
			
		||||
    class DiracOpt {
 | 
			
		||||
    public:
 | 
			
		||||
      // These ones will need to be package intelligently. WilsonType base class
 | 
			
		||||
      // for use by DWF etc..
 | 
			
		||||
      static void DhopSite(CartesianStencil &st,LatticeDoubledGaugeField &U,
 | 
			
		||||
			   std::vector<vHalfSpinColourVector,alignedAllocator<vHalfSpinColourVector> >  &buf,
 | 
			
		||||
			   int sF,int sU,const LatticeFermion &in, LatticeFermion &out);
 | 
			
		||||
      static void DhopSiteDag(CartesianStencil &st,LatticeDoubledGaugeField &U,
 | 
			
		||||
			      std::vector<vHalfSpinColourVector,alignedAllocator<vHalfSpinColourVector> >  &buf,
 | 
			
		||||
			      int sF,int sU,const LatticeFermion &in, LatticeFermion &out);
 | 
			
		||||
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    // Hand unrolled for Nc=3, one flavour
 | 
			
		||||
    class DiracOptHand {
 | 
			
		||||
    public:
 | 
			
		||||
      // These ones will need to be package intelligently. WilsonType base class
 | 
			
		||||
      // for use by DWF etc..
 | 
			
		||||
      static void DhopSite(CartesianStencil &st,LatticeDoubledGaugeField &U,
 | 
			
		||||
			   std::vector<vHalfSpinColourVector,alignedAllocator<vHalfSpinColourVector> >  &buf,
 | 
			
		||||
			   int sF,int sU,const LatticeFermion &in, LatticeFermion &out);
 | 
			
		||||
      static void DhopSiteDag(CartesianStencil &st,LatticeDoubledGaugeField &U,
 | 
			
		||||
			      std::vector<vHalfSpinColourVector,alignedAllocator<vHalfSpinColourVector> >  &buf,
 | 
			
		||||
			      int sF,int sU,const LatticeFermion &in, LatticeFermion &out);
 | 
			
		||||
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
#endif
 | 
			
		||||
@@ -27,7 +27,7 @@
 | 
			
		||||
    Chi_12 = ref()(1)(2);
 | 
			
		||||
 | 
			
		||||
#define MULT_2SPIN(A)\
 | 
			
		||||
   auto & ref(U._odata[ss](A));	\
 | 
			
		||||
   auto & ref(U._odata[sU](A));	\
 | 
			
		||||
    U_00 = ref()(0,0);\
 | 
			
		||||
    U_10 = ref()(1,0);\
 | 
			
		||||
    U_20 = ref()(2,0);\
 | 
			
		||||
@@ -282,7 +282,7 @@ namespace QCD {
 | 
			
		||||
 | 
			
		||||
void DiracOptHand::DhopSite(CartesianStencil &st,LatticeDoubledGaugeField &U,
 | 
			
		||||
			    std::vector<vHalfSpinColourVector,alignedAllocator<vHalfSpinColourVector> >  &buf,
 | 
			
		||||
			    int ss,const LatticeFermion &in, LatticeFermion &out)
 | 
			
		||||
			    int sF,int sU,const LatticeFermion &in, LatticeFermion &out)
 | 
			
		||||
{
 | 
			
		||||
  REGISTER vComplex result_00; // 12 regs on knc
 | 
			
		||||
  REGISTER vComplex result_01;
 | 
			
		||||
@@ -338,6 +338,7 @@ void DiracOptHand::DhopSite(CartesianStencil &st,LatticeDoubledGaugeField &U,
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
  int offset,local,perm, ptype;
 | 
			
		||||
  int ss=sF;
 | 
			
		||||
  
 | 
			
		||||
  // Xp
 | 
			
		||||
  offset = st._offsets [Xp][ss];
 | 
			
		||||
@@ -514,24 +515,24 @@ void DiracOptHand::DhopSite(CartesianStencil &st,LatticeDoubledGaugeField &U,
 | 
			
		||||
 | 
			
		||||
  {
 | 
			
		||||
    vSpinColourVector & ref (out._odata[ss]);
 | 
			
		||||
    vstream(ref()(0)(0),result_00);
 | 
			
		||||
    vstream(ref()(0)(1),result_01);
 | 
			
		||||
    vstream(ref()(0)(2),result_02);
 | 
			
		||||
    vstream(ref()(1)(0),result_10);
 | 
			
		||||
    vstream(ref()(1)(1),result_11);
 | 
			
		||||
    vstream(ref()(1)(2),result_12);
 | 
			
		||||
    vstream(ref()(2)(0),result_20);
 | 
			
		||||
    vstream(ref()(2)(1),result_21);
 | 
			
		||||
    vstream(ref()(2)(2),result_22);
 | 
			
		||||
    vstream(ref()(3)(0),result_30);
 | 
			
		||||
    vstream(ref()(3)(1),result_31);
 | 
			
		||||
    vstream(ref()(3)(2),result_32);
 | 
			
		||||
    vstream(ref()(0)(0),result_00*(-0.5));
 | 
			
		||||
    vstream(ref()(0)(1),result_01*(-0.5));
 | 
			
		||||
    vstream(ref()(0)(2),result_02*(-0.5));
 | 
			
		||||
    vstream(ref()(1)(0),result_10*(-0.5));
 | 
			
		||||
    vstream(ref()(1)(1),result_11*(-0.5));
 | 
			
		||||
    vstream(ref()(1)(2),result_12*(-0.5));
 | 
			
		||||
    vstream(ref()(2)(0),result_20*(-0.5));
 | 
			
		||||
    vstream(ref()(2)(1),result_21*(-0.5));
 | 
			
		||||
    vstream(ref()(2)(2),result_22*(-0.5));
 | 
			
		||||
    vstream(ref()(3)(0),result_30*(-0.5));
 | 
			
		||||
    vstream(ref()(3)(1),result_31*(-0.5));
 | 
			
		||||
    vstream(ref()(3)(2),result_32*(-0.5));
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void DiracOptHand::DhopSiteDag(CartesianStencil &st,LatticeDoubledGaugeField &U,
 | 
			
		||||
			       std::vector<vHalfSpinColourVector,alignedAllocator<vHalfSpinColourVector> >  &buf,
 | 
			
		||||
			       int ss,const LatticeFermion &in, LatticeFermion &out)
 | 
			
		||||
			       int ss,int sU,const LatticeFermion &in, LatticeFermion &out)
 | 
			
		||||
{
 | 
			
		||||
  REGISTER vComplex result_00; // 12 regs on knc
 | 
			
		||||
  REGISTER vComplex result_01;
 | 
			
		||||
@@ -752,18 +753,18 @@ void DiracOptHand::DhopSiteDag(CartesianStencil &st,LatticeDoubledGaugeField &U,
 | 
			
		||||
 | 
			
		||||
  {
 | 
			
		||||
    vSpinColourVector & ref (out._odata[ss]);
 | 
			
		||||
    vstream(ref()(0)(0),result_00);
 | 
			
		||||
    vstream(ref()(0)(1),result_01);
 | 
			
		||||
    vstream(ref()(0)(2),result_02);
 | 
			
		||||
    vstream(ref()(1)(0),result_10);
 | 
			
		||||
    vstream(ref()(1)(1),result_11);
 | 
			
		||||
    vstream(ref()(1)(2),result_12);
 | 
			
		||||
    vstream(ref()(2)(0),result_20);
 | 
			
		||||
    vstream(ref()(2)(1),result_21);
 | 
			
		||||
    vstream(ref()(2)(2),result_22);
 | 
			
		||||
    vstream(ref()(3)(0),result_30);
 | 
			
		||||
    vstream(ref()(3)(1),result_31);
 | 
			
		||||
    vstream(ref()(3)(2),result_32);
 | 
			
		||||
    vstream(ref()(0)(0),result_00*(-0.5));
 | 
			
		||||
    vstream(ref()(0)(1),result_01*(-0.5));
 | 
			
		||||
    vstream(ref()(0)(2),result_02*(-0.5));
 | 
			
		||||
    vstream(ref()(1)(0),result_10*(-0.5));
 | 
			
		||||
    vstream(ref()(1)(1),result_11*(-0.5));
 | 
			
		||||
    vstream(ref()(1)(2),result_12*(-0.5));
 | 
			
		||||
    vstream(ref()(2)(0),result_20*(-0.5));
 | 
			
		||||
    vstream(ref()(2)(1),result_21*(-0.5));
 | 
			
		||||
    vstream(ref()(2)(2),result_22*(-0.5));
 | 
			
		||||
    vstream(ref()(3)(0),result_30*(-0.5));
 | 
			
		||||
    vstream(ref()(3)(1),result_31*(-0.5));
 | 
			
		||||
    vstream(ref()(3)(2),result_32*(-0.5));
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
}}
 | 
			
		||||
							
								
								
									
										103
									
								
								lib/stencil/Grid_lebesgue.cc
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										103
									
								
								lib/stencil/Grid_lebesgue.cc
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,103 @@
 | 
			
		||||
#include <Grid.h>
 | 
			
		||||
 | 
			
		||||
namespace Grid {
 | 
			
		||||
 | 
			
		||||
int LebesgueOrder::UseLebesgueOrder;
 | 
			
		||||
 | 
			
		||||
LebesgueOrder::IndexInteger LebesgueOrder::alignup(IndexInteger n){
 | 
			
		||||
  n--;           // 1000 0011 --> 1000 0010
 | 
			
		||||
  n |= n >> 1;   // 1000 0010 | 0100 0001 = 1100 0011
 | 
			
		||||
  n |= n >> 2;   // 1100 0011 | 0011 0000 = 1111 0011
 | 
			
		||||
  n |= n >> 4;   // 1111 0011 | 0000 1111 = 1111 1111
 | 
			
		||||
  n |= n >> 8;   // ... (At this point all bits are 1, so further bitwise-or
 | 
			
		||||
  n |= n >> 16;  //      operations produce no effect.)
 | 
			
		||||
  n++;           // 1111 1111 --> 1 0000 0000
 | 
			
		||||
  return n;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
LebesgueOrder::LebesgueOrder(GridBase *grid) 
 | 
			
		||||
{
 | 
			
		||||
  _LebesgueReorder.resize(0);
 | 
			
		||||
  
 | 
			
		||||
  // Align up dimensions to power of two.
 | 
			
		||||
  const IndexInteger one=1;
 | 
			
		||||
  IndexInteger ND = grid->_ndimension;
 | 
			
		||||
  std::vector<IndexInteger> dims(ND);
 | 
			
		||||
  std::vector<IndexInteger> adims(ND);
 | 
			
		||||
  std::vector<std::vector<IndexInteger> > bitlist(ND);
 | 
			
		||||
  
 | 
			
		||||
  for(IndexInteger mu=0;mu<ND;mu++){
 | 
			
		||||
    dims[mu] = grid->_rdimensions[mu];
 | 
			
		||||
    assert ( dims[mu] != 0 );
 | 
			
		||||
    adims[mu] = alignup(dims[mu]);
 | 
			
		||||
  }
 | 
			
		||||
  
 | 
			
		||||
  // List which bits of padded volume coordinate contribute; this strategy 
 | 
			
		||||
  // i) avoids recursion 
 | 
			
		||||
  // ii) has loop lengths at most the width of a 32 bit word.
 | 
			
		||||
  int sitebit=0;
 | 
			
		||||
  int split=2;
 | 
			
		||||
  for(int mu=0;mu<ND;mu++){   // mu 0 takes bit 0; mu 1 takes bit 1 etc...
 | 
			
		||||
    for(int bit=0;bit<split;bit++){
 | 
			
		||||
      IndexInteger mask = one<<bit;
 | 
			
		||||
      if ( mask&(adims[mu]-1) ){
 | 
			
		||||
	bitlist[mu].push_back(sitebit);
 | 
			
		||||
	sitebit++;
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
  for(int bit=split;bit<32;bit++){
 | 
			
		||||
    IndexInteger mask = one<<bit;
 | 
			
		||||
    for(int mu=0;mu<ND;mu++){   // mu 0 takes bit 0; mu 1 takes bit 1 etc...
 | 
			
		||||
      if ( mask&(adims[mu]-1) ){
 | 
			
		||||
	bitlist[mu].push_back(sitebit);
 | 
			
		||||
	sitebit++;
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
  
 | 
			
		||||
  // Work out padded and unpadded volumes
 | 
			
		||||
  IndexInteger avol = 1;
 | 
			
		||||
  for(int mu=0;mu<ND;mu++) avol = avol * adims[mu];
 | 
			
		||||
  
 | 
			
		||||
  IndexInteger vol = 1;
 | 
			
		||||
  for(int mu=0;mu<ND;mu++) vol = vol * dims[mu];
 | 
			
		||||
  
 | 
			
		||||
  // Loop over padded volume, following Lebesgue curve
 | 
			
		||||
  // We interleave the bits from sequential "mu".
 | 
			
		||||
  std::vector<IndexInteger> ax(ND);
 | 
			
		||||
  
 | 
			
		||||
  for(IndexInteger asite=0;asite<avol;asite++){
 | 
			
		||||
    
 | 
			
		||||
    // Start with zero and collect bits
 | 
			
		||||
    for(int mu=0;mu<ND;mu++) ax[mu] = 0;
 | 
			
		||||
    
 | 
			
		||||
    int contained = 1;
 | 
			
		||||
    for(int mu=0;mu<ND;mu++){
 | 
			
		||||
      
 | 
			
		||||
      // Build the coordinate on the aligned volume
 | 
			
		||||
      for(int bit=0;bit<bitlist[mu].size();bit++){
 | 
			
		||||
	int sbit=bitlist[mu][bit];
 | 
			
		||||
	
 | 
			
		||||
	if(asite&(one<<sbit)){
 | 
			
		||||
	  ax[mu]|=one<<bit;
 | 
			
		||||
	}
 | 
			
		||||
      }
 | 
			
		||||
      
 | 
			
		||||
      // Is it contained in original box
 | 
			
		||||
      if ( ax[mu]>dims[mu]-1 ) contained = 0;
 | 
			
		||||
      
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    if ( contained ) {
 | 
			
		||||
      int site = ax[0]
 | 
			
		||||
	+        dims[0]*ax[1]
 | 
			
		||||
	+dims[0]*dims[1]*ax[2]
 | 
			
		||||
	+dims[0]*dims[1]*dims[2]*ax[3];
 | 
			
		||||
      
 | 
			
		||||
      _LebesgueReorder.push_back(site);
 | 
			
		||||
    }
 | 
			
		||||
	}
 | 
			
		||||
  assert( _LebesgueReorder.size() == vol );
 | 
			
		||||
}
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										29
									
								
								lib/stencil/Grid_lebesgue.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										29
									
								
								lib/stencil/Grid_lebesgue.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,29 @@
 | 
			
		||||
#ifndef GRID_LEBESGUE_H
 | 
			
		||||
#define GRID_LEBESGUE_H
 | 
			
		||||
 | 
			
		||||
#include<vector>
 | 
			
		||||
 | 
			
		||||
// Lebesgue, Morton, Z-graph ordering assistance
 | 
			
		||||
namespace Grid {
 | 
			
		||||
  
 | 
			
		||||
  class LebesgueOrder { 
 | 
			
		||||
  public:
 | 
			
		||||
 | 
			
		||||
    static int UseLebesgueOrder;
 | 
			
		||||
 | 
			
		||||
    typedef uint32_t IndexInteger;
 | 
			
		||||
 | 
			
		||||
    inline IndexInteger Reorder(IndexInteger ss) { 
 | 
			
		||||
      return UseLebesgueOrder ? _LebesgueReorder[ss] : ss; 
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    IndexInteger alignup(IndexInteger n);
 | 
			
		||||
 | 
			
		||||
    LebesgueOrder(GridBase *grid);
 | 
			
		||||
 | 
			
		||||
  private:
 | 
			
		||||
    std::vector<IndexInteger> _LebesgueReorder;
 | 
			
		||||
 | 
			
		||||
  };    
 | 
			
		||||
}
 | 
			
		||||
#endif
 | 
			
		||||
@@ -3,95 +3,6 @@
 | 
			
		||||
namespace Grid {
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
void CartesianStencil::LebesgueOrder(void) 
 | 
			
		||||
{
 | 
			
		||||
  _LebesgueReorder.resize(0);
 | 
			
		||||
  
 | 
			
		||||
  // Align up dimensions to power of two.
 | 
			
		||||
  const StencilInteger one=1;
 | 
			
		||||
  StencilInteger ND = _grid->_ndimension;
 | 
			
		||||
  std::vector<StencilInteger> dims(ND);
 | 
			
		||||
  std::vector<StencilInteger> adims(ND);
 | 
			
		||||
  std::vector<std::vector<StencilInteger> > bitlist(ND);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
  for(StencilInteger mu=0;mu<ND;mu++){
 | 
			
		||||
    dims[mu] = _grid->_rdimensions[mu];
 | 
			
		||||
    assert ( dims[mu] != 0 );
 | 
			
		||||
    adims[mu] = alignup(dims[mu]);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // List which bits of padded volume coordinate contribute; this strategy 
 | 
			
		||||
  // i) avoids recursion 
 | 
			
		||||
  // ii) has loop lengths at most the width of a 32 bit word.
 | 
			
		||||
  int sitebit=0;
 | 
			
		||||
  int split=24;
 | 
			
		||||
  for(int mu=0;mu<ND;mu++){   // mu 0 takes bit 0; mu 1 takes bit 1 etc...
 | 
			
		||||
    for(int bit=0;bit<split;bit++){
 | 
			
		||||
    StencilInteger mask = one<<bit;
 | 
			
		||||
      if ( mask&(adims[mu]-1) ){
 | 
			
		||||
	bitlist[mu].push_back(sitebit);
 | 
			
		||||
	sitebit++;
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
  for(int bit=split;bit<32;bit++){
 | 
			
		||||
    StencilInteger mask = one<<bit;
 | 
			
		||||
    for(int mu=0;mu<ND;mu++){   // mu 0 takes bit 0; mu 1 takes bit 1 etc...
 | 
			
		||||
      if ( mask&(adims[mu]-1) ){
 | 
			
		||||
	bitlist[mu].push_back(sitebit);
 | 
			
		||||
	sitebit++;
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // Work out padded and unpadded volumes
 | 
			
		||||
  StencilInteger avol = 1;
 | 
			
		||||
  for(int mu=0;mu<ND;mu++) avol = avol * adims[mu];
 | 
			
		||||
 | 
			
		||||
  StencilInteger vol = 1;
 | 
			
		||||
  for(int mu=0;mu<ND;mu++) vol = vol * dims[mu];
 | 
			
		||||
  
 | 
			
		||||
  // Loop over padded volume, following Lebesgue curve
 | 
			
		||||
  // We interleave the bits from sequential "mu".
 | 
			
		||||
  std::vector<StencilInteger> ax(ND);
 | 
			
		||||
  
 | 
			
		||||
  for(StencilInteger asite=0;asite<avol;asite++){
 | 
			
		||||
 | 
			
		||||
    // Start with zero and collect bits
 | 
			
		||||
    for(int mu=0;mu<ND;mu++) ax[mu] = 0;
 | 
			
		||||
 | 
			
		||||
    int contained = 1;
 | 
			
		||||
    for(int mu=0;mu<ND;mu++){
 | 
			
		||||
 | 
			
		||||
      // Build the coordinate on the aligned volume
 | 
			
		||||
      for(int bit=0;bit<bitlist[mu].size();bit++){
 | 
			
		||||
	int sbit=bitlist[mu][bit];
 | 
			
		||||
 | 
			
		||||
	if(asite&(one<<sbit)){
 | 
			
		||||
	  ax[mu]|=one<<bit;
 | 
			
		||||
	}
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      // Is it contained in original box
 | 
			
		||||
      if ( ax[mu]>dims[mu]-1 ) contained = 0;
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if ( contained ) {
 | 
			
		||||
      int site = ax[0]
 | 
			
		||||
	+        dims[0]*ax[1]
 | 
			
		||||
        +dims[0]*dims[1]*ax[2]
 | 
			
		||||
        +dims[0]*dims[1]*dims[2]*ax[3];
 | 
			
		||||
 | 
			
		||||
      _LebesgueReorder.push_back(site);
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  assert( _LebesgueReorder.size() == vol );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
  CartesianStencil::CartesianStencil(GridBase *grid,
 | 
			
		||||
				     int npoints,
 | 
			
		||||
				     int checkerboard,
 | 
			
		||||
@@ -110,8 +21,6 @@ void CartesianStencil::LebesgueOrder(void)
 | 
			
		||||
      _unified_buffer_size=0;
 | 
			
		||||
      _request_count =0;
 | 
			
		||||
 | 
			
		||||
      LebesgueOrder();
 | 
			
		||||
 | 
			
		||||
      int osites  = _grid->oSites();
 | 
			
		||||
 | 
			
		||||
      for(int i=0;i<npoints;i++){
 | 
			
		||||
@@ -143,8 +52,8 @@ void CartesianStencil::LebesgueOrder(void)
 | 
			
		||||
	// up a table containing the npoint "neighbours" and whether they 
 | 
			
		||||
	// live in lattice or a comms buffer.
 | 
			
		||||
	if ( !comm_dim ) {
 | 
			
		||||
	  sshift[0] = _grid->CheckerBoardShift(_checkerboard,dimension,shift,0);
 | 
			
		||||
	  sshift[1] = _grid->CheckerBoardShift(_checkerboard,dimension,shift,1);
 | 
			
		||||
	  sshift[0] = _grid->CheckerBoardShift(_checkerboard,dimension,shift,Even);
 | 
			
		||||
	  sshift[1] = _grid->CheckerBoardShift(_checkerboard,dimension,shift,Odd);
 | 
			
		||||
 | 
			
		||||
	  if ( sshift[0] == sshift[1] ) {
 | 
			
		||||
	    Local(point,dimension,shift,0x3);
 | 
			
		||||
@@ -154,8 +63,8 @@ void CartesianStencil::LebesgueOrder(void)
 | 
			
		||||
	  }
 | 
			
		||||
	} else { // All permute extract done in comms phase prior to Stencil application
 | 
			
		||||
	  //        So tables are the same whether comm_dim or splice_dim
 | 
			
		||||
	  sshift[0] = _grid->CheckerBoardShift(_checkerboard,dimension,shift,0);
 | 
			
		||||
	  sshift[1] = _grid->CheckerBoardShift(_checkerboard,dimension,shift,1);
 | 
			
		||||
	  sshift[0] = _grid->CheckerBoardShift(_checkerboard,dimension,shift,Even);
 | 
			
		||||
	  sshift[1] = _grid->CheckerBoardShift(_checkerboard,dimension,shift,Odd);
 | 
			
		||||
	  if ( sshift[0] == sshift[1] ) {
 | 
			
		||||
	    Comms(point,dimension,shift,0x3);
 | 
			
		||||
	  } else {
 | 
			
		||||
@@ -185,7 +94,7 @@ void CartesianStencil::LebesgueOrder(void)
 | 
			
		||||
	int o   = 0;
 | 
			
		||||
	int bo  = x * _grid->_ostride[dimension];
 | 
			
		||||
	
 | 
			
		||||
	int cb= (cbmask==0x2)? 1 : 0;
 | 
			
		||||
	int cb= (cbmask==0x2)? Odd : Even;
 | 
			
		||||
	  
 | 
			
		||||
	int sshift = _grid->CheckerBoardShift(_checkerboard,dimension,shift,cb);
 | 
			
		||||
	int sx     = (x+sshift)%rd;
 | 
			
		||||
@@ -224,7 +133,7 @@ void CartesianStencil::LebesgueOrder(void)
 | 
			
		||||
      _comm_buf_size[point] = buffer_size; // Size of _one_ plane. Multiple planes may be gathered and
 | 
			
		||||
                                           // send to one or more remote nodes.
 | 
			
		||||
 | 
			
		||||
      int cb= (cbmask==0x2)? 1 : 0;
 | 
			
		||||
      int cb= (cbmask==0x2)? Odd : Even;
 | 
			
		||||
      int sshift= _grid->CheckerBoardShift(_checkerboard,dimension,shift,cb);
 | 
			
		||||
      
 | 
			
		||||
      for(int x=0;x<rd;x++){       
 | 
			
		||||
 
 | 
			
		||||
@@ -1,3 +1,3 @@
 | 
			
		||||
#!/bin/sh 
 | 
			
		||||
 | 
			
		||||
wc -l */*.h */*/*.h */*/*/*.h */*.cc */*/*.cc */*/*/*.cc
 | 
			
		||||
wc -l lib/*.h lib/*/*.h lib/*/*/*.h lib/*.cc lib/*/*.cc lib/*/*/*.cc tests/*.cc benchmarks/*.cc
 | 
			
		||||
							
								
								
									
										165
									
								
								tests/Grid_cshift_red_black.cc
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										165
									
								
								tests/Grid_cshift_red_black.cc
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,165 @@
 | 
			
		||||
#include <Grid.h>
 | 
			
		||||
#include <parallelIO/GridNerscIO.h>
 | 
			
		||||
 | 
			
		||||
using namespace Grid;
 | 
			
		||||
using namespace Grid::QCD;
 | 
			
		||||
 | 
			
		||||
int main (int argc, char ** argv)
 | 
			
		||||
{
 | 
			
		||||
  Grid_init(&argc,&argv);
 | 
			
		||||
 | 
			
		||||
  std::vector<int> latt_size   = GridDefaultLatt();
 | 
			
		||||
  int Nd = latt_size.size();
 | 
			
		||||
  std::vector<int> simd_layout = GridDefaultSimd(Nd,vComplexF::Nsimd());
 | 
			
		||||
  std::vector<int> mpi_layout  = GridDefaultMpi();
 | 
			
		||||
 | 
			
		||||
  std::vector<int> mask(Nd,1);
 | 
			
		||||
  mask[0]=0;
 | 
			
		||||
 | 
			
		||||
  GridCartesian         Fine  (latt_size,simd_layout,mpi_layout);
 | 
			
		||||
  GridRedBlackCartesian RBFine(latt_size,simd_layout,mpi_layout,mask,1);
 | 
			
		||||
 | 
			
		||||
  GridParallelRNG      FineRNG(&Fine);  FineRNG.SeedRandomDevice();
 | 
			
		||||
 | 
			
		||||
  LatticeComplex U(&Fine);
 | 
			
		||||
  LatticeComplex ShiftU(&Fine);
 | 
			
		||||
  LatticeComplex rbShiftU(&Fine);
 | 
			
		||||
  LatticeComplex Ue(&RBFine); 
 | 
			
		||||
  LatticeComplex Uo(&RBFine);
 | 
			
		||||
  LatticeComplex ShiftUe(&RBFine);
 | 
			
		||||
  LatticeComplex ShiftUo(&RBFine);
 | 
			
		||||
  LatticeComplex lex(&Fine);
 | 
			
		||||
  lex=zero;
 | 
			
		||||
  Integer stride =1;
 | 
			
		||||
  {
 | 
			
		||||
    double nrm;
 | 
			
		||||
    LatticeComplex coor(&Fine);
 | 
			
		||||
 | 
			
		||||
    for(int d=0;d<Nd;d++){
 | 
			
		||||
      //      Integer i=10000;
 | 
			
		||||
      Integer i=0;
 | 
			
		||||
      LatticeCoordinate(coor,d);
 | 
			
		||||
      lex = lex + coor*stride+i;
 | 
			
		||||
      stride=stride*latt_size[d];
 | 
			
		||||
    }
 | 
			
		||||
    U=lex;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  pickCheckerboard(Even,Ue,U);
 | 
			
		||||
  pickCheckerboard(Odd,Uo,U);
 | 
			
		||||
 | 
			
		||||
  //  std::cout << U<<std::endl;
 | 
			
		||||
  std::cout << "Ue " <<norm2(Ue)<<std::endl;
 | 
			
		||||
  std::cout << "Uo " <<norm2(Uo)<<std::endl;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
  TComplex cm;
 | 
			
		||||
  for(int dir=0;dir<Nd;dir++){
 | 
			
		||||
    if ( dir!=1 ) continue;
 | 
			
		||||
    for(int shift=0;shift<latt_size[dir];shift++){
 | 
			
		||||
 | 
			
		||||
	std::cout<<"Shifting by "<<shift<<" in direction"<<dir<<std::endl;
 | 
			
		||||
 | 
			
		||||
	//	std::cout<<"Even grid"<<std::endl;
 | 
			
		||||
	ShiftUe = Cshift(Ue,dir,shift);    // Shift everything cb by cb
 | 
			
		||||
	//	std::cout << "\tShiftUe " <<norm2(ShiftUe)<<std::endl;
 | 
			
		||||
 | 
			
		||||
	//	std::cout<<"Odd grid"<<std::endl;
 | 
			
		||||
	ShiftUo = Cshift(Uo,dir,shift);    
 | 
			
		||||
	//	std::cout << "\tShiftUo " <<norm2(ShiftUo)<<std::endl;
 | 
			
		||||
 | 
			
		||||
	//	std::cout<<"Recombined Even/Odd grids"<<std::endl;
 | 
			
		||||
	setCheckerboard(rbShiftU,ShiftUe);
 | 
			
		||||
	setCheckerboard(rbShiftU,ShiftUo);
 | 
			
		||||
	//	std::cout << "\trbShiftU " <<norm2(rbShiftU)<<std::endl;
 | 
			
		||||
 | 
			
		||||
	//	std::cout<<"Full grid shift"<<std::endl;
 | 
			
		||||
	ShiftU  = Cshift(U,dir,shift);    // Shift everything
 | 
			
		||||
	//	std::cout << "\tShiftU " <<norm2(rbShiftU)<<std::endl;
 | 
			
		||||
 | 
			
		||||
	std::vector<int> coor(4);
 | 
			
		||||
 | 
			
		||||
	std::cout << "Checking the non-checkerboard shift"<<std::endl;
 | 
			
		||||
	for(coor[3]=0;coor[3]<latt_size[3];coor[3]++){
 | 
			
		||||
	for(coor[2]=0;coor[2]<latt_size[2];coor[2]++){
 | 
			
		||||
	for(coor[1]=0;coor[1]<latt_size[1];coor[1]++){
 | 
			
		||||
	for(coor[0]=0;coor[0]<latt_size[0];coor[0]++){
 | 
			
		||||
	  
 | 
			
		||||
	  peekSite(cm,ShiftU,coor);
 | 
			
		||||
 | 
			
		||||
	  /////////	  double nrm=norm2(U);
 | 
			
		||||
 | 
			
		||||
	  std::vector<int> scoor(coor);
 | 
			
		||||
	  scoor[dir] = (scoor[dir]+shift)%latt_size[dir];
 | 
			
		||||
	  
 | 
			
		||||
	  Integer slex = scoor[0]
 | 
			
		||||
	    + latt_size[0]*scoor[1]
 | 
			
		||||
	    + latt_size[0]*latt_size[1]*scoor[2]
 | 
			
		||||
	    + latt_size[0]*latt_size[1]*latt_size[2]*scoor[3];
 | 
			
		||||
 | 
			
		||||
	  Complex scm(slex);
 | 
			
		||||
	  
 | 
			
		||||
	  double nrm = abs(scm-cm()()());
 | 
			
		||||
	  std::vector<int> peer(4);
 | 
			
		||||
	  int index=real(cm);
 | 
			
		||||
	  Fine.CoorFromIndex(peer,index,latt_size);
 | 
			
		||||
 | 
			
		||||
	  if (nrm > 0){
 | 
			
		||||
	    std::cerr<<"FAIL shift "<< shift<<" in dir "<< dir
 | 
			
		||||
		     <<" ["<<coor[0]<<","<<coor[1]<<","<<coor[2]<<","<<coor[3]<<"] = "
 | 
			
		||||
		     << cm()()()<<" expect "<<scm<<"  "<<nrm<<std::endl;
 | 
			
		||||
	    std::cerr<<"Got    "<<index<<" " << peer[0]<<","<<peer[1]<<","<<peer[2]<<","<<peer[3]<<std::endl;
 | 
			
		||||
	    index=real(scm);
 | 
			
		||||
	    Fine.CoorFromIndex(peer,index,latt_size);
 | 
			
		||||
	    std::cerr<<"Expect "<<index<<" " << peer[0]<<","<<peer[1]<<","<<peer[2]<<","<<peer[3]<<std::endl;
 | 
			
		||||
	    exit(-1);
 | 
			
		||||
	  }
 | 
			
		||||
	}}}}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
	std::cout << "Checking the checkerboard shift"<<std::endl;
 | 
			
		||||
	for(coor[3]=0;coor[3]<latt_size[3];coor[3]++){
 | 
			
		||||
	for(coor[2]=0;coor[2]<latt_size[2];coor[2]++){
 | 
			
		||||
	for(coor[1]=0;coor[1]<latt_size[1];coor[1]++){
 | 
			
		||||
	for(coor[0]=0;coor[0]<latt_size[0];coor[0]++){
 | 
			
		||||
	  
 | 
			
		||||
	  peekSite(cm,rbShiftU,coor);
 | 
			
		||||
 | 
			
		||||
	  double nrm=norm2(U);
 | 
			
		||||
 | 
			
		||||
	  std::vector<int> scoor(coor);
 | 
			
		||||
	  scoor[dir] = (scoor[dir]+shift)%latt_size[dir];
 | 
			
		||||
	  
 | 
			
		||||
	  Integer slex = scoor[0]
 | 
			
		||||
	    + latt_size[0]*scoor[1]
 | 
			
		||||
	    + latt_size[0]*latt_size[1]*scoor[2]
 | 
			
		||||
	    + latt_size[0]*latt_size[1]*latt_size[2]*scoor[3];
 | 
			
		||||
 | 
			
		||||
	  Complex scm(slex);
 | 
			
		||||
	  
 | 
			
		||||
	  nrm = abs(scm-cm()()());
 | 
			
		||||
	  std::vector<int> peer(4);
 | 
			
		||||
	  int index=real(cm);
 | 
			
		||||
	  Fine.CoorFromIndex(peer,index,latt_size);
 | 
			
		||||
 | 
			
		||||
	  if (nrm > 0){
 | 
			
		||||
	    std::cerr<<"FAIL shift "<< shift<<" in dir "<< dir
 | 
			
		||||
		     <<" ["<<coor[0]<<","<<coor[1]<<","<<coor[2]<<","<<coor[3]<<"] = "
 | 
			
		||||
		     << cm()()()<<" expect "<<scm<<"  "<<nrm<<std::endl;
 | 
			
		||||
	    std::cerr<<"Got    "<<index<<" " << peer[0]<<","<<peer[1]<<","<<peer[2]<<","<<peer[3]<<std::endl;
 | 
			
		||||
	    index=real(scm);
 | 
			
		||||
	    Fine.CoorFromIndex(peer,index,latt_size);
 | 
			
		||||
	    std::cerr<<"Expect "<<index<<" " << peer[0]<<","<<peer[1]<<","<<peer[2]<<","<<peer[3]<<std::endl;
 | 
			
		||||
	    exit(-1);
 | 
			
		||||
	  } else if (0) { 
 | 
			
		||||
	    std::cout<<"PASS shift "<< shift<<" in dir "<< dir
 | 
			
		||||
		     <<" ["<<coor[0]<<","<<coor[1]<<","<<coor[2]<<","<<coor[3]<<"] = "
 | 
			
		||||
		     << cm()()()<<" expect "<<scm<<"  "<<nrm<<std::endl;
 | 
			
		||||
	  }
 | 
			
		||||
	}}}}
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  Grid_finalize();
 | 
			
		||||
}
 | 
			
		||||
@@ -5,7 +5,7 @@ AM_LDFLAGS = -L$(top_builddir)/lib
 | 
			
		||||
#
 | 
			
		||||
# Test code
 | 
			
		||||
#
 | 
			
		||||
bin_PROGRAMS = Grid_main Grid_stencil Grid_nersc_io Grid_cshift Grid_gamma  Grid_simd Grid_rng Grid_remez Grid_rng_fixed 
 | 
			
		||||
bin_PROGRAMS = Grid_main Grid_stencil Grid_nersc_io Grid_cshift Grid_gamma  Grid_simd Grid_rng Grid_remez Grid_rng_fixed Grid_cshift_red_black 
 | 
			
		||||
 | 
			
		||||
Grid_main_SOURCES = Grid_main.cc
 | 
			
		||||
Grid_main_LDADD = -lGrid
 | 
			
		||||
@@ -25,6 +25,9 @@ Grid_nersc_io_LDADD = -lGrid
 | 
			
		||||
Grid_cshift_SOURCES = Grid_cshift.cc
 | 
			
		||||
Grid_cshift_LDADD = -lGrid
 | 
			
		||||
 | 
			
		||||
Grid_cshift_red_black_SOURCES = Grid_cshift_red_black.cc
 | 
			
		||||
Grid_cshift_red_black_LDADD = -lGrid
 | 
			
		||||
 | 
			
		||||
Grid_gamma_SOURCES = Grid_gamma.cc
 | 
			
		||||
Grid_gamma_LDADD = -lGrid
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user