diff --git a/tests/debug/Test_general_coarse_hdcg.cc b/tests/debug/Test_general_coarse_hdcg.cc index 901491d5..c11b19f4 100644 --- a/tests/debug/Test_general_coarse_hdcg.cc +++ b/tests/debug/Test_general_coarse_hdcg.cc @@ -2,11 +2,11 @@ Grid physics library, www.github.com/paboyle/Grid - Source file: ./tests/Test_padded_cell.cc + Source file: ./tests/Test_general_coarse_hdcg.cc Copyright (C) 2023 -Author: Peter Boyle +Author: Peter Boyle This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -29,10 +29,22 @@ Author: Peter Boyle #include #include #include +#include using namespace std; using namespace Grid; +template class TestSolver : public LinearFunction { +public: + TestSolver() {}; + void operator() (const Field &in, Field &out){ out = Zero(); } +}; + + +RealD InverseApproximation(RealD x){ + return 1.0/x; +} + // Want Op in CoarsenOp to call MatPcDagMatPc template class HermOpAdaptor : public LinearOperatorBase @@ -40,20 +52,33 @@ class HermOpAdaptor : public LinearOperatorBase LinearOperatorBase & wrapped; public: HermOpAdaptor(LinearOperatorBase &wrapme) : wrapped(wrapme) {}; - void OpDiag (const Field &in, Field &out) { assert(0); } + void Op (const Field &in, Field &out) { wrapped.HermOp(in,out); } + void HermOp(const Field &in, Field &out) { wrapped.HermOp(in,out); } + void AdjOp (const Field &in, Field &out){ wrapped.HermOp(in,out); } + void OpDiag (const Field &in, Field &out) { assert(0); } void OpDir (const Field &in, Field &out,int dir,int disp) { assert(0); } - void OpDirAll (const Field &in, std::vector &out){ assert(0); }; - void Op (const Field &in, Field &out){ - wrapped.HermOp(in,out); - } - void AdjOp (const Field &in, Field &out){ - wrapped.HermOp(in,out); - } + void OpDirAll (const Field &in, std::vector &out) { assert(0); }; void HermOpAndNorm(const Field &in, Field &out,RealD &n1,RealD &n2){ assert(0); } - void HermOp(const Field &in, Field &out){ - wrapped.HermOp(in,out); +}; +template class ChebyshevSmoother : public LinearFunction +{ +public: + using LinearFunction::operator(); + typedef LinearOperatorBase FineOperator; + FineOperator & _SmootherOperator; + Chebyshev Cheby; + ChebyshevSmoother(RealD _lo,RealD _hi,int _ord, FineOperator &SmootherOperator) : + _SmootherOperator(SmootherOperator), + Cheby(_lo,_hi,_ord,InverseApproximation) + { + std::cout << GridLogMessage<<" Chebyshev smoother order "<<_ord<<" ["<<_lo<<","<<_hi<<"]"< seeds4({1,2,3,4}); std::vector seeds5({5,6,7,8}); std::vector cseeds({5,6,7,8}); + GridParallelRNG RNG5(FGrid); RNG5.SeedFixedIntegers(seeds5); GridParallelRNG RNG4(UGrid); RNG4.SeedFixedIntegers(seeds4); GridParallelRNG CRNG(Coarse5d);CRNG.SeedFixedIntegers(cseeds); + ///////////////////////// Configuration ///////////////////////////////// LatticeGaugeField Umu(UGrid); FieldMetaData header; std::string file("ckpoint_lat.4000"); NerscIO::readConfiguration(Umu,header,file); - + + //////////////////////// Fermion action ////////////////////////////////// RealD mass=0.01; RealD M5=1.8; - RealD b=1.5; RealD c=0.5; MobiusFermionD Ddwf(Umu,*FGrid,*FrbGrid,*UGrid,*UrbGrid,mass,M5,b,c); - MobiusFermionD Dpv(Umu,*FGrid,*FrbGrid,*UGrid,*UrbGrid,1.0,M5,b,c); - const int nbasis = 4; + SchurDiagMooeeOperator HermOpEO(Ddwf); + + typedef HermOpAdaptor HermFineMatrix; + HermFineMatrix FineHermOp(HermOpEO); + + LatticeFermion result(FrbGrid); result=Zero(); + + LatticeFermion src(FrbGrid); random(RNG5,src); + + // Run power method on FineHermOp + PowerMethod PM; PM(HermOpEO,src); + + + //////////////////////////////////////////////////////////// + ///////////// Coarse basis and Little Dirac Operator /////// + //////////////////////////////////////////////////////////// + const int nbasis = 40; const int cb = 0 ; - LatticeFermion prom(FrbGrid); - typedef GeneralCoarsenedMatrix LittleDiracOperator; typedef LittleDiracOperator::CoarseVector CoarseVector; - NextToNextToNextToNearestStencilGeometry5D geom; - - std::cout< HermOpEO(Ddwf); - HermOpAdaptor HOA(HermOpEO); - - // Run power method on HOA?? - LatticeFermion result(FrbGrid); result=Zero(); - LatticeFermion ref(FrbGrid); ref=Zero(); - LatticeFermion tmp(FrbGrid); - LatticeFermion err(FrbGrid); - - { - LatticeFermion src(FrbGrid); random(RNG5,src); - PowerMethod PM; PM(HermOpEO,src); - } - // exit(0); + NextToNextToNextToNearestStencilGeometry5D geom(Coarse5d); // Warning: This routine calls PVdagM.Op, not PVdagM.HermOp typedef Aggregation Subspace; @@ -132,72 +156,117 @@ int main (int argc, char ** argv) Aggregates.CreateSubspaceChebyshev(RNG5, HermOpEO, nbasis, - 90.0, - 0.1, - 500, - 500, - 100, - 0.0); + // 100.0, + // 0.1, // Low pass is pretty high still -- 311 iters + // 250.0, + // 0.01, // subspace too low filter power wrong + // 250.0, + // 0.2, // slower + 95.0, + // 0.05, // nbasis 12 - 311 -- wrong coarse inv + // 0.05, // nbasis 12 - 154 -- right filt + // 0.1, // nbasis 12 - 169 oops + // 0.05, // nbasis 16 -- 127 iters + // 0.03, // nbasis 16 -- 13- + // 0.1, // nbasis 16 -- 142; sloppy solve + 0.1, // nbasis 24 + 300); //////////////////////////////////////////////////////////// // Need to check about red-black grid coarsening //////////////////////////////////////////////////////////// LittleDiracOperator LittleDiracOp(geom,FrbGrid,Coarse5d); - LittleDiracOp.CoarsenOperator(HOA,Aggregates); + LittleDiracOp.CoarsenOperatorColoured(FineHermOp,Aggregates); - std::cout< HermMatrix; + HermMatrix CoarseOp (LittleDiracOp); - std::cout< IRLCheby(0.02,50.0,71); // 1 iter + FunctionHermOp IRLOpCheby(IRLCheby,CoarseOp); + PlainHermOp IRLOp (CoarseOp); + int Nk=64; + int Nm=128; + int Nstop=Nk; + ImplicitlyRestartedLanczos IRL(IRLOpCheby,IRLOp,Nstop,Nk,Nm,1.0e-5,20); + + int Nconv; + std::vector eval(Nm); + std::vector evec(Nm,Coarse5d); + CoarseVector c_src(Coarse5d); c_src=1.0; + IRL.calc(eval,evec,c_src,Nconv); + DeflatedGuesser DeflCoarseGuesser(evec,eval); - CoarseVector c_src (Coarse5d); - CoarseVector c_res (Coarse5d); - CoarseVector c_proj(Coarse5d); - - std::vector subspace(nbasis,FrbGrid); - subspace=Aggregates.subspace; - - Complex one(1.0); - c_src = one; // 1 in every element for vector 1. - blockPromote(c_src,err,subspace); - - prom=Zero(); - for(int b=0;b Guess; - RealD tol = 1.0e-8; - int maxit=2000; - ConjugateGradient CG(tol,maxit,false); - HermitianLinearOperator Hop (LittleDiracOp); - CG(Hop, c_src, c_res); + ////////////////////////////////////////// + int maxit=20000; + ConjugateGradient CG(1.0e-8,maxit,false); + ConjugateGradient CGfine(1.0e-8,10000,false); + ZeroGuesser CoarseZeroGuesser; + + // HPDSolver HPDSolve(CoarseOp,CG,CoarseZeroGuesser); + HPDSolver HPDSolve(CoarseOp,CG,DeflCoarseGuesser); + + ////////////////////////////////////////// + // Build a smoother + ////////////////////////////////////////// + // ChebyshevSmoother Smoother(10.0,100.0,10,FineHermOp); //499 + // ChebyshevSmoother Smoother(3.0,100.0,10,FineHermOp); //383 + // ChebyshevSmoother Smoother(1.0,100.0,10,FineHermOp); //328 + // std::vector los({0.5,1.0,3.0}); // 147/142/146 nbasis 1 + // std::vector los({1.0,2.0}); // Nbasis 24: 88,86 iterations + // std::vector los({2.0,4.0}); // Nbasis 32 == 52, iters + // std::vector los({2.0,4.0}); // Nbasis 40 == 36,36 iters + + // + // Turns approx 2700 iterations into 340 fine multiplies with Nbasis 40 + // Need to measure cost of coarse space. + // + // -- i) Reduce coarse residual -- 0.04 + // -- ii) Lanczos on coarse space -- done + // -- iii) Possible 1 hop project and/or preconditioning it - easy - PrecCG it and + // use a limited stencil. Reread BFM code to check on evecs / deflation strategy with prec + // + std::vector los({3.0}); // Nbasis 40 == 36,36 iters + std::vector ords({7,8,10}); // Nbasis 40 == 40,38,36 iters (320,342,396 mults) + + // Standard CG + // result=Zero(); + // CGfine(HermOpEO, src, result); + + for(int l=0;l CGsloppy(4.0e-2,maxit,false); + HPDSolver HPDSolveSloppy(CoarseOp,CGsloppy,DeflCoarseGuesser); + + // ChebyshevSmoother Smoother(lo,92,10,FineHermOp); // 36 best case + ChebyshevSmoother Smoother(lo,92,ords[o],FineHermOp); // 311 + + ////////////////////////////////////////// + // Build a HDCG solver + ////////////////////////////////////////// + TwoLevelFlexiblePcg + HDCG(1.0e-8, 3000, + FineHermOp, + Smoother, + HPDSolveSloppy, + HPDSolve, + Aggregates); + + // result=Zero(); + // HDCG(src,result); + + result=Zero(); + HDCG.Inflexible(src,result); + } + } + Grid_finalize(); return 0; }