/************************************************************************************* Grid physics library, www.github.com/paboyle/Grid Source file: ./tests/qdpxx/Test_qdpxx_munprec.cc Copyright (C) 2015 Author: Azusa Yamaguchi Author: paboyle This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. See the full license in the file "LICENSE" in the top level distribution directory *************************************************************************************/ /* END LEGAL */ #include int Ls=8; double M5=1.6; double mq=0.01; double zolo_lo = 0.1; double zolo_hi = 2.0; double mobius_scale=2.0; enum ChromaAction { DWF, // CPS style preconditioning WilsonFermion, // Wilson HwPartFracZolo, // KEK's approach HwContFracZolo, // Edwards, Kennedy et al prefer this HwPartFracTanh, // HwContFracTanh, // HwCayleyZolo, // Chiu Optimal HtCayleyZolo, // HmCayleyZolo, // Scaled shamir 13 HwCayleyTanh, // Scaled shamir HtCayleyTanh, // Plain old DWF. HmCayleyTanh, // Scaled shamir 13 HtContFracTanh, HtContFracZolo }; void calc_grid (ChromaAction action,Grid::QCD::LatticeGaugeField & lat, Grid::QCD::LatticeFermion &src, Grid::QCD::LatticeFermion &res,int dag); void calc_chroma (ChromaAction action,Grid::QCD::LatticeGaugeField & lat, Grid::QCD::LatticeFermion &src, Grid::QCD::LatticeFermion &res,int dag); #include #include #include namespace Chroma { class ChromaWrapper { public: typedef multi1d U; typedef LatticeFermion T4; typedef multi1d T5; static void ImportGauge(Grid::QCD::LatticeGaugeField & gr, QDP::multi1d & ch) { Grid::QCD::LorentzColourMatrix LCM; Grid::Complex cc; QDP::ColorMatrix cm; QDP::Complex c; std::vector x(4); QDP::multi1d cx(4); std::vector gd= gr._grid->GlobalDimensions(); for (x[0]=0;x[0] & ch ) { Grid::QCD::SpinColourVector F; Grid::Complex c; QDP::Fermion cF; QDP::SpinVector cS; QDP::Complex cc; std::vector x(5); QDP::multi1d cx(4); std::vector gd= gr._grid->GlobalDimensions(); for (x[0]=0;x[0] & ch ) { Grid::QCD::SpinColourVector F; Grid::Complex c; QDP::Fermion cF; QDP::SpinVector cS; QDP::Complex cc; std::vector x(5); QDP::multi1d cx(4); std::vector gd= gr._grid->GlobalDimensions(); for (x[0]=0;x[0] > GetLinOp (U &u, ChromaAction parms) { QDP::Real _mq(mq); QDP::Real eps_lo(zolo_lo); QDP::Real eps_hi(zolo_hi); QDP::Real scale(mobius_scale); QDP::multi1d bcs(QDP::Nd); bcs[0] = bcs[1] = bcs[2] = bcs[3] = 1; Chroma::Handle > fbc(new Chroma::SimpleFermBC< T4, U, U >(bcs)); Chroma::Handle > cfs( new Chroma::CreateSimpleFermState(fbc)); Chroma::GroupXML_t invparm; invparm.xml=std::string( " \n" " CG_INVERTER\n" " 1.0e-9\n" " 3000\n" " " ); invparm.id=std::string("CG_INVERTER"); invparm.path=std::string("/InvertParam"); if ( (parms == HtCayleyTanh)|| (parms==DWF) ) { Chroma::UnprecDWFermActArray S_f(cfs, M5, _mq, Ls); Chroma::Handle< Chroma::FermState > fs( S_f.createState(u) ); Chroma::Handle< Chroma::LinearOperatorArray > M(S_f.unprecLinOp(fs,_mq)); return M; } if ( parms == HwCayleyTanh ) { QDP::Real b5 = 0.5; QDP::Real c5 = 0.5; Chroma::UnprecNEFFermActArray S_f(cfs, M5,b5,c5, _mq, Ls); Chroma::Handle< Chroma::FermState > fs( S_f.createState(u) ); Chroma::Handle< Chroma::LinearOperatorArray > M(S_f.unprecLinOp(fs,_mq)); return M; } if ( parms == HmCayleyTanh ) { Real b5 = 0.5*(scale +1.0); Real c5 = 0.5*(scale -1.0); UnprecNEFFermActArray S_f(cfs, M5,b5,c5, _mq, Ls); Handle< FermState > fs( S_f.createState(u) ); Handle< LinearOperatorArray > M(S_f.unprecLinOp(fs,_mq)); return M; } if ( parms == HwCayleyZolo ) { UnprecZoloNEFFermActArrayParams params; params.OverMass=M5; params.Mass=_mq; params.b5=0.5; params.c5=0.5; params.N5=Ls; params.approximation_type = COEFF_TYPE_ZOLOTAREV; params.ApproxMin=eps_lo; params.ApproxMax=eps_hi; UnprecZoloNEFFermActArray S_f(cfs, params); Handle< FermState > fs( S_f.createState(u) ); Handle< LinearOperatorArray > M(S_f.unprecLinOp(fs,_mq)); return M; } if ( parms == HtCayleyZolo ) { UnprecZoloNEFFermActArrayParams params; params.OverMass=M5; params.Mass=_mq; params.b5=1.0; params.c5=0.0; params.N5=Ls; params.approximation_type = COEFF_TYPE_ZOLOTAREV; params.ApproxMin=eps_lo; params.ApproxMax=eps_hi; UnprecZoloNEFFermActArray S_f(cfs, params); Handle< FermState > fs( S_f.createState(u) ); Handle< LinearOperatorArray > M(S_f.unprecLinOp(fs,_mq)); return M; } if ( parms == HmCayleyZolo ) { UnprecZoloNEFFermActArrayParams params; params.OverMass=M5; params.Mass=_mq; params.b5= 0.5*(mobius_scale +1.0); params.c5= 0.5*(mobius_scale -1.0); params.N5=Ls; params.approximation_type = COEFF_TYPE_ZOLOTAREV; params.ApproxMin=eps_lo; params.ApproxMax=eps_hi; UnprecZoloNEFFermActArray S_f(cfs, params); Handle< FermState > fs( S_f.createState(u) ); Handle< LinearOperatorArray > M(S_f.unprecLinOp(fs,_mq)); return M; } if ( parms == HwPartFracZolo ) { if ( Ls%2 == 0 ) { printf("Ls is not odd\n"); exit(-1); } UnprecOvExtFermActArrayParams param; param.OverMass=M5; param.Mass=_mq; param.RatPolyDeg = Ls; param.ApproxMin =eps_lo; param.ApproxMax =eps_hi; param.b5 =1.0; param.c5 =1.0; param.approximation_type=COEFF_TYPE_ZOLOTAREV; // param.approximation_type=COEFF_TYPE_TANH_UNSCALED; // param.approximation_type=COEFF_TYPE_TANH; param.tuning_strategy_xml= "OVEXT_CONSTANT_STRATEGY\n"; UnprecOvExtFermActArray S_f(cfs,param); Handle< FermState > fs( S_f.createState(u) ); Handle< LinearOperatorArray > M(S_f.linOp(fs)); return M; } if ( parms == HwContFracZolo ) { UnprecOvlapContFrac5DFermActParams param; param.Mass=_mq; // How is M5 set? Wilson mass In AuxFermAct param.ApproxMin=eps_lo; param.ApproxMax=eps_hi; param.approximation_type=COEFF_TYPE_ZOLOTAREV; param.RatPolyDeg=Ls; // The following is why I think Chroma made some directional errors: param.AuxFermAct= std::string( "\n" " UNPRECONDITIONED_WILSON\n" " -1.8\n" " 1\n" " 0\n" " 1000\n" " 1.0e-9\n" " \n" " SIMPLE_FERMBC\n" " 1 1 1 1\n" " \n" "" ); param.AuxFermActGrp= std::string(""); UnprecOvlapContFrac5DFermActArray S_f(fbc,param); Handle< FermState > fs( S_f.createState(u) ); Handle< LinearOperatorArray > M(S_f.linOp(fs)); return M; } assert(0); } static Chroma::Handle< Chroma::SystemSolver > GetSolver(QDP::multi1d &u, ChromaAction parms) { QDP::multi1d bcs(Nd); bcs[0] = bcs[1] = bcs[2] = bcs[3] = 1; Chroma::Handle > fbc(new Chroma::SimpleFermBC< T4, U, U >(bcs)); Chroma::Handle > cfs( new Chroma::CreateSimpleFermState(fbc)); Chroma::GroupXML_t invparm; invparm.xml=std::string( " \n" " CG_INVERTER\n" " 1.0e-10\n" " 3000\n" " " ); invparm.id=std::string("CG_INVERTER"); invparm.path=std::string("/InvertParam"); Chroma::UnprecDWFermActArray S_f(cfs, M5, mq, Ls); std::cout << "GetSolver: DWF 4d prec "< > fs( S_f.createState(u) ); Chroma::Handle< LinearOperatorArray > M(S_f.unprecLinOp(fs,mq)); return S_f.qprop(fs,invparm); } }; } int main (int argc,char **argv ) { /******************************************************** * Setup QDP *********************************************************/ Chroma::initialize(&argc,&argv); Chroma::WilsonTypeFermActs4DEnv::registerAll(); /******************************************************** * Setup Grid *********************************************************/ Grid::Grid_init(&argc,&argv); Grid::GridCartesian * UGrid = Grid::QCD::SpaceTimeGrid::makeFourDimGrid(Grid::GridDefaultLatt(), Grid::GridDefaultSimd(Grid::QCD::Nd,Grid::vComplex::Nsimd()), Grid::GridDefaultMpi()); std::vector gd = UGrid->GlobalDimensions(); QDP::multi1d nrow(QDP::Nd); for(int mu=0;mu<4;mu++) nrow[mu] = gd[mu]; QDP::Layout::setLattSize(nrow); QDP::Layout::create(); Grid::GridCartesian * FGrid = Grid::QCD::SpaceTimeGrid::makeFiveDimGrid(Ls,UGrid); Grid::QCD::LatticeGaugeField lat(UGrid); Grid::QCD::LatticeFermion src(FGrid); Grid::QCD::LatticeFermion res_chroma(FGrid); Grid::QCD::LatticeFermion res_grid (FGrid); std::vector ActionList({ HtCayleyTanh, // Plain old DWF. HmCayleyTanh, HwCayleyTanh, HtCayleyZolo, // Plain old DWF. HmCayleyZolo, HwCayleyZolo }); std::vector ActionName({ "HtCayleyTanh", "HmCayleyTanh", "HwCayleyTanh", "HtCayleyZolo", "HmCayleyZolo", "HwCayleyZolo" }); for(int i=0;i u(4); // Chroma::HotSt(u); Chroma::ChromaWrapper::ImportGauge(lat,u) ; QDP::multi1d check(Ls); QDP::multi1d result(Ls); QDP::multi1d psi(Ls); Chroma::ChromaWrapper::ImportFermion(src,psi); for(int mu=0;mu<4;mu++){ std::cout <<"Imported Gauge norm ["< U; auto linop =Chroma::ChromaWrapper::GetLinOp(u, action); printf("Calling Chroma Linop\n"); fflush(stdout); if ( dag ) (*linop)(check,psi,Chroma::MINUS); else (*linop)(check,psi,Chroma::PLUS); printf("Called Chroma Linop\n"); fflush(stdout); Chroma::ChromaWrapper::ExportFermion(res,check) ; } void calc_grid(ChromaAction action,Grid::QCD::LatticeGaugeField & Umu, Grid::QCD::LatticeFermion &src, Grid::QCD::LatticeFermion &res,int dag) { using namespace Grid; ; std::vector seeds4({1,2,3,4}); std::vector seeds5({5,6,7,8}); Grid::GridCartesian * UGrid = (Grid::GridCartesian *) Umu._grid; Grid::GridCartesian * FGrid = (Grid::GridCartesian *) src._grid; Grid::GridRedBlackCartesian * UrbGrid = Grid::QCD::SpaceTimeGrid::makeFourDimRedBlackGrid(UGrid); Grid::GridRedBlackCartesian * FrbGrid = Grid::QCD::SpaceTimeGrid::makeFiveDimRedBlackGrid(Ls,UGrid); Grid::GridParallelRNG RNG4(UGrid); RNG4.SeedFixedIntegers(seeds4); Grid::GridParallelRNG RNG5(FGrid); RNG5.SeedFixedIntegers(seeds5); Grid::gaussian(RNG5,src); Grid::gaussian(RNG5,res); Grid::QCD::SU3::HotConfiguration(RNG4,Umu); /* Grid::QCD::LatticeColourMatrix U(UGrid); U=Grid::zero; for(int nn=0;nn=4 ) { Grid::PokeIndex(Umu,U,nn); } } */ Grid::RealD _mass=mq; Grid::RealD _M5 =M5; if ( action == HtCayleyTanh ) { Grid::QCD::DomainWallFermionR Ddwf(Umu,*FGrid,*FrbGrid,*UGrid,*UrbGrid,_mass,_M5); std::cout << Grid::GridLogMessage <<" Calling domain wall multiply "<