From 852fc1b00174b255e41d00591363ce494de8b8f1 Mon Sep 17 00:00:00 2001 From: Peter Boyle Date: Mon, 27 Jan 2020 13:45:10 -0500 Subject: [PATCH] True Hierachical multigrid for DWF --- tests/solver/Test_dwf_hdcr.cc | 715 +++++++++++----------------------- 1 file changed, 224 insertions(+), 491 deletions(-) diff --git a/tests/solver/Test_dwf_hdcr.cc b/tests/solver/Test_dwf_hdcr.cc index 5a131a57..873530ff 100644 --- a/tests/solver/Test_dwf_hdcr.cc +++ b/tests/solver/Test_dwf_hdcr.cc @@ -1,3 +1,5 @@ + + /************************************************************************************* Grid physics library, www.github.com/paboyle/Grid @@ -29,357 +31,174 @@ Author: paboyle /* END LEGAL */ #include #include -//#include 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 -class myclass: Serializable { -public: - - GRID_SERIALIZABLE_CLASS_MEMBERS(myclass, - int, domaindecompose, - int, domainsize, - int, order, - int, Ls, - double, mq, - double, lo, - double, hi, - int, steps); - - myclass(){}; - -}; + * Smoother: + * * Fine: Cheby(hi, lo, order) -- 60,0.5,10 + * * Coarse: Cheby(hi, lo, order) -- 12,0.1,4 + * Lanczos: + * CoarseCoarse IRL( Nk, Nm, Nstop, poly(lo,hi,order)) 24,36,24,0.002,4.0,61 + */ RealD InverseApproximation(RealD x){ return 1.0/x; } -template +template class ChebyshevSmoother : public LinearFunction +{ +public: + typedef LinearOperatorBase FineOperator; + Matrix & _SmootherMatrix; + FineOperator & _SmootherOperator; + + Chebyshev Cheby; + + ChebyshevSmoother(RealD _lo,RealD _hi,int _ord, FineOperator &SmootherOperator,Matrix &SmootherMatrix) : + _SmootherOperator(SmootherOperator), + _SmootherMatrix(SmootherMatrix), + Cheby(_lo,_hi,_ord,InverseApproximation) + {}; + + void operator() (const Field &in, Field &out) + { + Field tmp(in.Grid()); + MdagMLinearOperator MdagMOp(_SmootherMatrix); + _SmootherOperator.AdjOp(in,tmp); + Cheby(MdagMOp,tmp,out); + } +}; +template class MirsSmoother : public LinearFunction +{ +public: + typedef LinearOperatorBase FineOperator; + Matrix & SmootherMatrix; + FineOperator & SmootherOperator; + RealD tol; + RealD shift; + int maxit; + + MirsSmoother(RealD _shift,RealD _tol,int _maxit,FineOperator &_SmootherOperator,Matrix &_SmootherMatrix) : + shift(_shift),tol(_tol),maxit(_maxit), + SmootherOperator(_SmootherOperator), + SmootherMatrix(_SmootherMatrix) + {}; + + void operator() (const Field &in, Field &out) + { + ZeroGuesser Guess; + ConjugateGradient CG(tol,maxit,false); + + Field src(in.Grid()); + + ShiftedMdagMLinearOperator,Field> MdagMOp(SmootherMatrix,shift); + SmootherOperator.AdjOp(in,src); + Guess(src,out); + CG(MdagMOp,src,out); + } +}; + +template class MultiGridPreconditioner : public LinearFunction< Lattice > { public: typedef Aggregation Aggregates; typedef CoarsenedMatrix CoarseOperator; - - typedef typename Aggregation::siteVector siteVector; - typedef typename Aggregation::CoarseScalar CoarseScalar; typedef typename Aggregation::CoarseVector CoarseVector; typedef typename Aggregation::CoarseMatrix CoarseMatrix; typedef typename Aggregation::FineField FineField; typedef LinearOperatorBase FineOperator; + typedef LinearFunction FineSmoother; Aggregates & _Aggregates; CoarseOperator & _CoarseOperator; Matrix & _FineMatrix; FineOperator & _FineOperator; - Matrix & _SmootherMatrix; - FineOperator & _SmootherOperator; Guesser & _Guess; + FineSmoother & _Smoother; + CoarseSolver & _CoarseSolve; - double cheby_hi; - double cheby_lo; - int cheby_ord; + int level; void Level(int lv) {level = lv; }; - myclass _params; +#define GridLogLevel std::cout << GridLogMessage < fMdagMOp(_FineMatrix); - - p1=in; - for(int i=0;i<50;i++){ - RealD absp1=std::sqrt(norm2(p1)); - fMdagMOp.HermOp(p1,p2);// this is the G5 herm bit - // _FineOperator.Op(p1,p2);// this is the G5 herm bit - RealD absp2=std::sqrt(norm2(p2)); - if(i%10==9) - std::cout< CG(1.0e-3,100,false); - ConjugateGradient fCG(1.0e-3,10,false); - - HermitianLinearOperator HermOp(_CoarseOperator); - MdagMLinearOperator MdagMOp(_CoarseOperator); - MdagMLinearOperator fMdagMOp(_FineMatrix); - - FineField tmp(in.Grid()); - FineField res(in.Grid()); - FineField Min(in.Grid()); - - // Monitor completeness of low mode space - _Aggregates.ProjectToSubspace (Csrc,in); - _Aggregates.PromoteFromSubspace(Csrc,out); - std::cout< CG(1.0e-10,100000); - ConjugateGradient fCG(1.0e-3,1000); - - HermitianLinearOperator HermOp(_CoarseOperator); - MdagMLinearOperator MdagMOp(_CoarseOperator); - ShiftedMdagMLinearOperator fMdagMOp(_FineMatrix,0.1); - - FineField tmp(in.Grid()); - FineField res(in.Grid()); - FineField Qin(in.Grid()); - - // Monitor completeness of low mode space - // _Aggregates.ProjectToSubspace (Csrc,in); - // _Aggregates.PromoteFromSubspace(Csrc,out); - // std::cout< fMdagMOp(_FineMatrix); - ShiftedMdagMLinearOperator fMdagMOp(_SmootherMatrix,0.0); - - RealD Ni,r; - - Ni = norm2(in); - - for(int ilo=0;ilo<3;ilo++){ - for(int ord=5;ord<50;ord*=2){ - - std::cout << " lo "< Cheby (lo[ilo],70.0,ord,InverseApproximation); - Cheby(fMdagMOp,vec1,vec2); // solves MdagM = g5 M g5M - - _FineOperator.Op(vec2,vec1);// this is the G5 herm bit - vec1 = in - vec1; // tmp = in - A Min - r=norm2(vec1); - std::cout< CG(5.0e-2,100000); - - HermitianLinearOperator HermOp(_CoarseOperator); - MdagMLinearOperator MdagMOp(_CoarseOperator); - // MdagMLinearOperator fMdagMOp(_FineMatrix); - ShiftedMdagMLinearOperator fMdagMOp(_SmootherMatrix,0.0); - FineField vec1(in.Grid()); FineField vec2(in.Grid()); - Chebyshev Cheby (_params.lo,_params.hi,_params.order,InverseApproximation); - Chebyshev ChebyAccu(_params.lo,_params.hi,_params.order,InverseApproximation); + double t; + // Fine Smoother + t=-usecond(); + _Smoother(in,out); + t+=usecond(); + GridLogLevel << "Smoother took "<< t/1000.0<< "ms" < block ({2,2,2,2}); + std::vector blockc ({2,2,2,2}); const int nbasis= 32; + const int nbasisc= 32; auto clatt = GridDefaultLatt(); for(int d=0;d seeds4({1,2,3,4}); std::vector seeds5({5,6,7,8}); @@ -407,49 +233,20 @@ int main (int argc, char ** argv) GridParallelRNG RNG5(FGrid); RNG5.SeedFixedIntegers(seeds5); GridParallelRNG RNG4(UGrid); RNG4.SeedFixedIntegers(seeds4); GridParallelRNG CRNG(Coarse5d);CRNG.SeedFixedIntegers(cseeds); - - Gamma g5(Gamma::Algebra::Gamma5); - LatticeFermion src(FGrid); gaussian(RNG5,src);// src=src+g5*src; - LatticeFermion result(FGrid); result=Zero(); - LatticeFermion ref(FGrid); ref=Zero(); - LatticeFermion tmp(FGrid); - LatticeFermion err(FGrid); + LatticeFermion result(FGrid); LatticeGaugeField Umu(UGrid); - LatticeGaugeField UmuDD(UGrid); - LatticeColourMatrix U(UGrid); - LatticeColourMatrix zz(UGrid); FieldMetaData header; std::string file("./ckpoint_lat.4000"); NerscIO::readConfiguration(Umu,header,file); - - if ( params.domaindecompose ) { - Lattice > coor(UGrid); - zz=Zero(); - for(int mu=0;mu(Umu,mu); - U = where(mod(coor,params.domainsize)==(Integer)0,zz,U); - PokeIndex(UmuDD,U,mu); - } - } else { - UmuDD = Umu; - } - // SU3::ColdConfiguration(RNG4,Umu); - // SU3::TepidConfiguration(RNG4,Umu); - // SU3::HotConfiguration(RNG4,Umu); - // Umu=Zero(); - - RealD mass=params.mq; - RealD M5=1.8; - std::cout< Subspace; typedef CoarsenedMatrix CoarseOperator; @@ -463,204 +260,140 @@ int main (int argc, char ** argv) Subspace Aggregates(Coarse5d,FGrid,0); assert ( (nbasis & 0x1)==0); - { int nb=nbasis/2; - std::cout< HermIndefOp(Ddwf); - Gamma5R5HermitianLinearOperator HermIndefOpDD(DdwfDD); - CoarsenedMatrix LDOp(*Coarse5d,1); // Hermitian matrix - LDOp.CoarsenOperator(FGrid,HermIndefOp,Aggregates); - exit(0); + typedef CoarsenedMatrix Level1Op; + typedef CoarsenedMatrix,nbasisc> Level2Op; + + Gamma5R5HermitianLinearOperator HermIndefOp(Ddwf); + + Level1Op LDOp(*Coarse5d,1); LDOp.CoarsenOperator(FGrid,HermIndefOp,Aggregates); - CoarseVector c_src (Coarse5d); - CoarseVector c_res (Coarse5d); - gaussian(CRNG,c_src); - result=Zero(); - c_res=Zero(); ////////////////////////////////////////////////// // Deflate the course space. Recursive multigrid? ////////////////////////////////////////////////// - - typedef CoarsenedMatrix Level1Op; - typedef CoarsenedMatrix,nbasis> Level2Op; - - auto cclatt = clatt; - for(int d=0;d,nbasis> CoarseSubspace; + typedef Aggregation,nbasisc> CoarseSubspace; CoarseSubspace CoarseAggregates(CoarseCoarse5d,Coarse5d,0); - double c_first = 0.2; - double c_div = 1.2; - std::vector c_lo(nbasis/2); - c_lo[0] = c_first; - for(int b=1;b c_ord(nbasis/2,200); - c_ord[0]=500; - -#define RECURSIVE_MULTIGRID -#ifdef RECURSIVE_MULTIGRID std::cout< PosdefLdop(LDOp); - // CoarseAggregates.CreateSubspaceChebyshev(CRNG,PosdefLdop,nbasis,14.0,c_lo,c_ord); - // CoarseAggregates.CreateSubspaceRandom(CRNG); + { + int nb=nbasisc/2; + CoarseAggregates.CreateSubspaceChebyshev(CRNG,PosdefLdop,nb,12.0,0.02,500,100,100,0.0); + for(int n=0;noSites();site++){ + subspace_g5[site](nn) = subspace[site](nn); + subspace_g5[site](nn+nb)=-subspace[site](nn+nb); + } + } + } + } - // Level2Op L2Op(*CoarseCoarse5d,1); // Hermitian matrix - // HermitianLinearOperator L1LinOp(LDOp); - // L2Op.CoarsenOperator(Coarse5d,L1LinOp,CoarseAggregates); -#endif + Level2Op L2Op(*CoarseCoarse5d,1); // Hermitian matrix + typedef Level2Op::CoarseVector CoarseCoarseVector; + HermitianLinearOperator L1LinOp(LDOp); + L2Op.CoarsenOperator(Coarse5d,L1LinOp,CoarseAggregates); - // std::cout< simple; - // ConjugateGradient fCG(1.0e-8,100000); - // fCG(HermDefOp,src,result); + MdagMLinearOperator IRLHermOpL2(L2Op); + Chebyshev IRLChebyL2(0.001,4.2,71); + FunctionHermOp IRLOpChebyL2(IRLChebyL2,IRLHermOpL2); + PlainHermOp IRLOpL2 (IRLHermOpL2); + int cNk=24; + int cNm=36; + int cNstop=24; + ImplicitlyRestartedLanczos IRLL2(IRLOpChebyL2,IRLOpL2,cNstop,cNk,cNm,1.0e-3,20); - std::cout< HermOpEO(Ddwf); - ConjugateGradient pCG(1.0e-8,10000); - // pCG(HermOpEO,src_o,result_o); + int cNconv; + std::vector eval2(cNm); + std::vector evec2(cNm,CoarseCoarse5d); + CoarseCoarseVector cc_src(CoarseCoarse5d); cc_src=1.0; + IRLL2.calc(eval2,evec2,cc_src,cNconv); + + ConjugateGradient CoarseCoarseCG(0.1,1000); + DeflatedGuesser DeflCoarseCoarseGuesser(evec2,eval2); + NormalEquations DeflCoarseCoarseCGNE(L2Op,CoarseCoarseCG,DeflCoarseCoarseGuesser); + + std::cout< , NormalEquations > TwoLevelMG; + typedef MultiGridPreconditioner,nbasisc,Level1Op, DeflatedGuesser, NormalEquations > CoarseMG; + typedef MultiGridPreconditioner, LinearFunction > ThreeLevelMG; + + // MultiGrid preconditioner acting on the coarse space <-> coarsecoarse space + ChebyshevSmoother CoarseSmoother(0.1,12.0,3,L1LinOp,LDOp); + ChebyshevSmoother FineSmoother(0.5,60.0,10,HermIndefOp,Ddwf); + + // MirsSmoother CoarseCGSmoother(0.1,0.1,4,L1LinOp,LDOp); + // MirsSmoother FineCGSmoother(0.0,0.01,8,HermIndefOp,Ddwf); + + CoarseMG Level2Precon (CoarseAggregates, L2Op, + L1LinOp,LDOp, + CoarseSmoother, + DeflCoarseCoarseGuesser, + DeflCoarseCoarseCGNE); + Level2Precon.Level(2); + + // PGCR Applying this solver to solve the coarse space problem + PrecGeneralisedConjugateResidual l2PGCR(0.1, 100, L1LinOp,Level2Precon,16,16); + l2PGCR.Level(2); - std::cout< IRLHermOp(LDOp); - Chebyshev IRLCheby(0.005,16.0,51); - // IRLCheby.InitLowPass(0.01,18.0,51); - FunctionHermOp IRLOpCheby(IRLCheby,IRLHermOp); - PlainHermOp IRLOp (IRLHermOp); - - int Nstop=24; - int Nk=24; - int Nm=48; - ImplicitlyRestartedLanczos IRL(IRLOpCheby,IRLOp,Nstop,Nk,Nm,1.0e-3,20); - int Nconv; - std::vector eval(Nm); - std::vector evec(Nm,Coarse5d); - IRL.calc(eval,evec,c_src,Nconv); - - - std::cout< CG(3.0e-3,100000); - // CG(PosdefLdop,c_src,c_res); - - std::cout< DeflCoarseGuesser(evec,eval); - DeflCoarseGuesser(c_src,c_res); - // CG(PosdefLdop,c_src,c_res); - - std::cout< CoarseZeroGuesser; + ThreeLevelMG ThreeLevelPrecon(Aggregates, LDOp, + HermIndefOp,Ddwf, + FineSmoother, + CoarseZeroGuesser, + l2PGCR); + ThreeLevelPrecon.Level(1); - MultiGridPreconditioner > - Precon (Aggregates, LDOp, - HermIndefOp,Ddwf, - HermIndefOp,Ddwf, - CoarseZeroGuesser, - params); + // Apply the fine-coarse-coarsecoarse 2 deep MG preconditioner in an outer PGCR on the fine fgrid + PrecGeneralisedConjugateResidual l1PGCR(1.0e-8,1000,HermIndefOp,ThreeLevelPrecon,16,16); + l1PGCR.Level(1); - // Precon.PowerMethod(src); - - /* std::cout<,nbasis,Level1Op,ZeroGuesser > - CoarsePrecon (CoarseAggregates, - L2Op, - L1LinOp,LDOp, - L1LinOp,LDOp, - CoarseZeroGuesser, - cparams); - - CoarsePrecon.PowerMethod(c_src); - */ - - /* - std::cout< PGCR(1.0e-8,100000,Precon,8,8); - std::cout< > - DeflatedPrecon (Aggregates, LDOp, - HermIndefOp,Ddwf, - HermIndefOp,Ddwf, - DeflCoarseGuesser, - params); - - PrecGeneralisedConjugateResidual deflPGCR(1.0e-8,100000,DeflatedPrecon,16,16); - - std::cout< CPGCR(1.0e-3,10000,CoarsePrecon,8,8); - std::cout< PM; PM(HermDefOp,src); + std::cout< cPM; cPM(PosdefLdop,c_src); + std::cout< ccPM; ccPM(IRLHermOpL2,cc_src); std::cout<