From 0cbe2859e00be33adeef5a979ad36e916357573c Mon Sep 17 00:00:00 2001 From: Peter Boyle Date: Tue, 30 Jun 2020 14:17:20 -0400 Subject: [PATCH] Making progress on Hw based 5d coarse matrix --- tests/solver/Test_hw_multigrid.cc | 496 +++++++++++++++++++++++++++--- 1 file changed, 451 insertions(+), 45 deletions(-) diff --git a/tests/solver/Test_hw_multigrid.cc b/tests/solver/Test_hw_multigrid.cc index b728faa7..9864c8e1 100644 --- a/tests/solver/Test_hw_multigrid.cc +++ b/tests/solver/Test_hw_multigrid.cc @@ -32,22 +32,457 @@ Author: Peter Boyle using namespace std; using namespace Grid; -/* Params - * Grid: - * block1(4) - * block2(4) - * - * Subspace - * * Fine : Subspace(nbasis,hi,lo,order,first,step) -- 32, 60,0.02,500,100,100 - * * Coarse: Subspace(nbasis,hi,lo,order,first,step) -- 32, 18,0.02,500,100,100 - * Smoother: - * * Fine: Cheby(hi, lo, order) -- 60,0.5,10 - * * Coarse: Cheby(hi, lo, order) -- 12,0.1,4 +// TODO +// +// Coarse Grid axpby_ssp_pminus // Inherit from spProj5pm +// Coarse Grid axpby_ssp_pplus - * Lanczos: - * CoarseCoarse IRL( Nk, Nm, Nstop, poly(lo,hi,order)) 24,36,24,0.002,4.0,61 - */ +template +class CayleyBase +{ +public: + int Ls; + // protected: + RealD mass; + // Save arguments to SetCoefficientsInternal + Vector _gamma; + RealD _zolo_hi; + RealD _b; + RealD _c; + + // Cayley form Moebius (tanh and zolotarev) + Vector omega; + Vector bs; // S dependent coeffs + Vector cs; + Vector as; + // For preconditioning Cayley form + Vector bee; + Vector cee; + Vector aee; + Vector beo; + Vector ceo; + Vector aeo; + // LDU factorisation of the eeoo matrix + Vector lee; + Vector leem; + Vector uee; + Vector ueem; + Vector dee; +public: + ///////////////////////////////////////////////////////// + // Replicates functionality + // Use a common base class approach + ///////////////////////////////////////////////////////// + // Tanh + void SetCoefficientsTanh(Approx::zolotarev_data *zdata,RealD b,RealD c) + { + Vector gamma(this->Ls); + for(int s=0;sLs;s++) gamma[s] = zdata->gamma[s]; + SetCoefficientsInternal(1.0,gamma,b,c); + } + //Zolo + void SetCoefficientsZolotarev(RealD zolo_hi,Approx::zolotarev_data *zdata,RealD b,RealD c) + { + Vector gamma(this->Ls); + for(int s=0;sLs;s++) gamma[s] = zdata->gamma[s]; + SetCoefficientsInternal(zolo_hi,gamma,b,c); + } + //Zolo + void SetCoefficientsInternal(RealD zolo_hi,Vector & gamma,RealD b,RealD c) + { + int Ls=this->Ls; + + /////////////////////////////////////////////////////////// + // The Cayley coeffs (unprec) + /////////////////////////////////////////////////////////// + assert(gamma.size()==Ls); + + omega.resize(Ls); + bs.resize(Ls); + cs.resize(Ls); + as.resize(Ls); + + double bpc = b+c; + double bmc = b-c; + _b = b; + _c = c; + _gamma = gamma; // Save the parameters so we can change mass later. + _zolo_hi= zolo_hi; + for(int i=0; i < Ls; i++){ + as[i] = 1.0; + omega[i] = _gamma[i]*_zolo_hi; //NB reciprocal relative to Chroma NEF code + assert(omega[i]!=Coeff_t(0.0)); + bs[i] = 0.5*(bpc/omega[i] + bmc); + cs[i] = 0.5*(bpc/omega[i] - bmc); + } + + //////////////////////////////////////////////////////// + // Constants for the preconditioned matrix Cayley form + //////////////////////////////////////////////////////// + bee.resize(Ls); + cee.resize(Ls); + beo.resize(Ls); + ceo.resize(Ls); + + for(int i=0;iM5) +1.0); + assert(bee[i]!=Coeff_t(0.0)); + cee[i]=as[i]*(1.0-cs[i]*(4.0-this->M5)); + beo[i]=as[i]*bs[i]; + ceo[i]=-as[i]*cs[i]; + } + aee.resize(Ls); + aeo.resize(Ls); + for(int i=0;iLs; + chi=Zero(); + for(int s=0;sLs; + chi=Zero(); + for(int s=0;sLs; + Vector diag (Ls,1.0); + Vector upper(Ls,-1.0); upper[Ls-1]=mass; + Vector lower(Ls,-1.0); lower[0] =mass; + M5D(psi,chi,chi,lower,diag,upper); + } + void M5Ddag (const Field &psi, Field &chi) + { + int Ls=this->Ls; + Vector diag(Ls,1.0); + Vector upper(Ls,-1.0); + Vector lower(Ls,-1.0); + upper[Ls-1]=-mass*upper[Ls-1]; + lower[0] =-mass*lower[0]; + M5Ddag(psi,chi,chi,lower,diag,upper); + } + void Meooe5D (const Field &psi, Field &Din) + { + int Ls=this->Ls; + Vector diag = bs; + Vector upper= cs; + Vector lower= cs; + upper[Ls-1]=-mass*upper[Ls-1]; + lower[0] =-mass*lower[0]; + M5D(psi,psi,Din,lower,diag,upper); + } + void MeooeDag5D (const Field &psi, Field &Din) + { + int Ls=this->Ls; + Vector diag =bs; + Vector upper=cs; + Vector lower=cs; + + for (int s=0;s &lower, + Vector &diag, + Vector &upper); + virtual void M5Ddag(const Field &psi_i, + const Field &phi_i, + Field &chi_i, + Vector &lower, + Vector &diag, + Vector &upper); + +}; + +template +class CoarseCayleyFermion + : public CayleyBase< Lattice >, + public SparseMatrixBase > > +{ +public: + typedef iVector siteVector; + typedef Lattice CoarseComplexField; + typedef Lattice CoarseVector; + typedef Lattice > CoarseMatrix; + typedef iMatrix Cobj; + typedef Lattice< CComplex > CoarseScalar; // used for inner products on fine field + typedef Lattice FineField; + + // Similar to the CoarseOperator but add 5D support. + Geometry geom; + GridBase *Coarse5D; + GridBase *Coarse4D; + CartesianStencil Stencil; + CoarsenedMatrix &Dw; + + GridBase * Grid(void) { return Coarse5D; }; // this is all the linalg routines need to know + + CoarseCayleyFermion(GridCartesian &CoarseGrid4, + GridCartesian &CoarseGrid5 + CoarsenedMatrix &_Dw ): + Coarse4D(&CoarseGrid4), + Coarse5D(&CoarseGrid5), + Dw(_Dw), + geom(CoarseGrid4._ndimension), + Stencil( &CoarseGrid4,geom.npoint,Even,geom.directions,geom.displacements,0), + A(2*Nd+1,&CoarseGrid4) + { + Ls=Coarse5D->_fdimensions[0]; + RealD eps = 1.0; + Approx::zolotarev_data *zdata = Approx::higham(eps,Ls);// eps is ignored for higham + SetCoefficientsTanh(zdata,1.0,0.0); + Approx::zolotarev_free(zdata); + }; + +public: + + //////////////////////////////////////////////// + // This is specific to Coarse Grid Cayley + //////////////////////////////////////////////// + void DW (const CoarseVector &in, CoarseVector &out) + { + conformable(Coarse5D,in.Grid()); + conformable(in.Grid(),out.Grid()); + + SimpleCompressor compressor; + + Stencil.HaloExchange(in,compressor); + autoView( in_v , in, AcceleratorRead); + autoView( out_v , out, AcceleratorWrite); + typedef LatticeView Aview; + + Vector AcceleratorViewContainer; + + for(int p=0;poSites(); + + // Ls loop for2D + int Ls=this->Ls; + accelerator_for2d(sF, oSites*Ls, b, nbasis, Nsimd, { + + int sU = sF/Ls; + int s = sF%Ls; + calcComplex res = Zero(); + calcVector nbr; + int ptype; + StencilEntry *SE; + + for(int point=0;point_is_local) { + nbr = coalescedReadPermute(in_v[SE->_offset],ptype,SE->_permute); + } else { + nbr = coalescedRead(Stencil.CommBuf()[SE->_offset]); + } + acceleratorSynchronise(); + + for(int bb=0;bb &lower, + Vector &diag, + Vector &upper) + { + + chi_i.Checkerboard()=psi_i.Checkerboard(); + GridBase *grid=psi_i.Grid(); + autoView(psi , psi_i,AcceleratorRead); + autoView(phi , phi_i,AcceleratorRead); + autoView(chi , chi_i,AcceleratorWrite); + assert(phi.Checkerboard() == psi.Checkerboard()); + + auto pdiag = &diag[0]; + auto pupper = &upper[0]; + auto plower = &lower[0]; + + int Ls =this->Ls; + + // 10 = 3 complex mult + 2 complex add + // Flops = 10.0*(Nc*Ns) *Ls*vol (/2 for red black counting) + uint64_t nloop = grid->oSites()/Ls; + accelerator_for(sss,nloop,Simd::Nsimd(),{ + uint64_t ss= sss*Ls; + typedef decltype(coalescedRead(psi[0])) spinor; + spinor tmp1, tmp2; + for(int s=0;s &lower, + Vector &diag, + Vector &upper) + { + chi_i.Checkerboard()=psi_i.Checkerboard(); + GridBase *grid=psi_i.Grid(); + autoView(psi , psi_i,AcceleratorRead); + autoView(phi , phi_i,AcceleratorRead); + autoView(chi , chi_i,AcceleratorWrite); + assert(phi.Checkerboard() == psi.Checkerboard()); + + auto pdiag = &diag[0]; + auto pupper = &upper[0]; + auto plower = &lower[0]; + + int Ls=this->Ls; + + uint64_t nloop = grid->oSites()/Ls; + accelerator_for(sss,nloop,Simd::Nsimd(),{ + uint64_t ss=sss*Ls; + typedef decltype(coalescedRead(psi[0])) spinor; + spinor tmp1,tmp2; + for(int s=0;s class SolverWrapper : public LinearFunction { private: @@ -319,15 +754,6 @@ int main (int argc, char ** argv) Aggregates4D.subspace[n] = Aggregates4D.subspace[n] + g5 * Aggregates4D.subspace[n]; } - std::cout< LinOpDwf(Ddwf); - Level1Op LDOp (*Coarse5d,0); + Level1Op c_Dw (*Coarse4d,0); std::cout< CoarseMdagM(LDOp); - BiCGSTAB CoarseBiCGSTAB(tol,MaxIt); - ConjugateGradient CoarseCG(tol,MaxIt); - - c_res=Zero(); - CoarseCG(CoarseMdagM,c_src,c_res); + LDOp.CoarsenOperator(FGrid,LinOpDwf,Aggregates4D); std::cout<