diff --git a/extras/Hadrons/Global.cc b/extras/Hadrons/Global.cc index 9a90a08c..b121434f 100644 --- a/extras/Hadrons/Global.cc +++ b/extras/Hadrons/Global.cc @@ -37,6 +37,7 @@ HadronsLogger Hadrons::HadronsLogWarning(1,"Warning"); HadronsLogger Hadrons::HadronsLogMessage(1,"Message"); HadronsLogger Hadrons::HadronsLogIterative(1,"Iterative"); HadronsLogger Hadrons::HadronsLogDebug(1,"Debug"); +HadronsLogger Hadrons::HadronsLogIRL(1,"IRL"); void Hadrons::initLogger(void) { @@ -46,11 +47,13 @@ void Hadrons::initLogger(void) GridLogMessage.setTopWidth(w); GridLogIterative.setTopWidth(w); GridLogDebug.setTopWidth(w); + GridLogIRL.setTopWidth(w); HadronsLogError.Active(GridLogError.isActive()); HadronsLogWarning.Active(GridLogWarning.isActive()); HadronsLogMessage.Active(GridLogMessage.isActive()); HadronsLogIterative.Active(GridLogIterative.isActive()); HadronsLogDebug.Active(GridLogDebug.isActive()); + HadronsLogIRL.Active(GridLogIRL.isActive()); } // type utilities ////////////////////////////////////////////////////////////// diff --git a/extras/Hadrons/Global.hpp b/extras/Hadrons/Global.hpp index fc069ed6..7f60ebcb 100644 --- a/extras/Hadrons/Global.hpp +++ b/extras/Hadrons/Global.hpp @@ -111,6 +111,7 @@ extern HadronsLogger HadronsLogWarning; extern HadronsLogger HadronsLogMessage; extern HadronsLogger HadronsLogIterative; extern HadronsLogger HadronsLogDebug; +extern HadronsLogger HadronsLogIRL; void initLogger(void); diff --git a/extras/Hadrons/LanczosUtils.hpp b/extras/Hadrons/LanczosUtils.hpp new file mode 100644 index 00000000..e6a78753 --- /dev/null +++ b/extras/Hadrons/LanczosUtils.hpp @@ -0,0 +1,88 @@ +#ifndef Hadrons_LanczosUtils_hpp_ +#define Hadrons_LanczosUtils_hpp_ + +#include +#include + +BEGIN_HADRONS_NAMESPACE + +// Lanczos type +#ifndef HADRONS_DEFAULT_LANCZOS_NBASIS +#define HADRONS_DEFAULT_LANCZOS_NBASIS 60 +#endif + +template +using LCL = LocalCoherenceLanczos; + +template +struct EigenPack +{ + std::vector eval; + std::vector evec; + + EigenPack(void) = default; + + EigenPack(const size_t size, GridBase *grid) + { + resize(size, grid); + } + + void resize(const size_t size, GridBase *grid) + { + eval.resize(size); + evec.resize(size, grid); + } + + void read(const std::string fileStem) + { + std::string evecFilename = fileStem + "_evec.bin"; + std::string evalFilename = fileStem + "_eval.xml"; + emptyUserRecord record; + ScidacReader binReader; + XmlReader xmlReader(evalFilename); + + LOG(Message) << "Reading " << evec.size() << " eigenvectors from '" + << evecFilename << "'" << std::endl; + binReader.open(evecFilename); + for(int k = 0; k < evec.size(); ++k) + { + binReader.readScidacFieldRecord(evec[k], record); + } + binReader.close(); + LOG(Message) << "Reading " << eval.size() << " eigenvalues from '" + << evalFilename << "'" << std::endl; + Grid::read(xmlReader, "evals", eval); + } + + void write(const std::string fileStem) + { + std::string evecFilename = fileStem + "_evec.bin"; + std::string evalFilename = fileStem + "_eval.xml"; + emptyUserRecord record; + ScidacWriter binWriter; + XmlWriter xmlWriter(evalFilename); + + LOG(Message) << "Writing " << evec.size() << " eigenvectors to '" + << evecFilename << "'" << std::endl; + binWriter.open(fileStem + "_evec.bin"); + for(int k = 0; k < evec.size(); ++k) + { + binWriter.writeScidacFieldRecord(evec[k], record); + } + binWriter.close(); + LOG(Message) << "Writing " << eval.size() << " eigenvalues to '" + << evalFilename << "'" << std::endl; + Grid::write(xmlWriter, "evals", eval); + } +}; + +template +using FineEigenPack = EigenPack; + +template +using CoarseEigenPack = EigenPack::CoarseField>; + +END_HADRONS_NAMESPACE + +#endif // Hadrons_LanczosUtils_hpp_ \ No newline at end of file diff --git a/extras/Hadrons/Makefile.am b/extras/Hadrons/Makefile.am index 3d07679a..477b93e4 100644 --- a/extras/Hadrons/Makefile.am +++ b/extras/Hadrons/Makefile.am @@ -21,6 +21,7 @@ nobase_libHadrons_a_HEADERS = \ GeneticScheduler.hpp \ Global.hpp \ Graph.hpp \ + LanczosUtils.hpp \ Module.hpp \ Modules.hpp \ ModuleFactory.hpp \ diff --git a/extras/Hadrons/Modules/MSolver/LocalCoherenceLanczos.hpp b/extras/Hadrons/Modules/MSolver/LocalCoherenceLanczos.hpp index 5fd486fd..a41a7839 100644 --- a/extras/Hadrons/Modules/MSolver/LocalCoherenceLanczos.hpp +++ b/extras/Hadrons/Modules/MSolver/LocalCoherenceLanczos.hpp @@ -31,11 +31,7 @@ See the full license in the file "LICENSE" in the top level distribution directo #include #include #include -#include - -#ifndef DEFAULT_LANCZOS_NBASIS -#define DEFAULT_LANCZOS_NBASIS 60 -#endif +#include BEGIN_HADRONS_NAMESPACE @@ -55,7 +51,8 @@ public: LanczosParams, coarseParams, ChebyParams, smoother, RealD, coarseRelaxTol, - std::string, blockSize); + std::string, blockSize, + std::string, output); }; template @@ -63,9 +60,9 @@ class TLocalCoherenceLanczos: public Module { public: FERM_TYPE_ALIASES(FImpl,); - typedef LocalCoherenceLanczos LCL; - typedef typename LCL::FineField FineField; - typedef typename LCL::CoarseField CoarseField; + typedef LCL LCL; + typedef FineEigenPack FineEigenPack; + typedef CoarseEigenPack CoarseEigenPack; typedef SchurDiagMooeeOperator SchurFMat; public: // constructor @@ -88,12 +85,12 @@ private: std::unique_ptr coarseGrid_{nullptr}; std::unique_ptr coarseGrid4Rb_{nullptr}; std::unique_ptr coarseGridRb_{nullptr}; - std::string fevecName_, cevecName_, fevalName_, cevalName_; + std::string fineName_, coarseName_; }; MODULE_REGISTER_NS(LocalCoherenceLanczos, - ARG(TLocalCoherenceLanczos), - MSolver); + ARG(TLocalCoherenceLanczos), + MSolver); /****************************************************************************** * TLocalCoherenceLanczos implementation * @@ -103,10 +100,8 @@ template TLocalCoherenceLanczos::TLocalCoherenceLanczos(const std::string name) : Module(name) { - fevecName_ = getName() + "_fineEvec"; - cevecName_ = getName() + "_coarseEvec"; - fevalName_ = getName() + "_fineEval"; - cevalName_ = getName() + "_coarseEval"; + fineName_ = getName() + "_fine"; + coarseName_ = getName() + "_coarse"; } // dependencies/products /////////////////////////////////////////////////////// @@ -121,7 +116,7 @@ std::vector TLocalCoherenceLanczos::getInput(void) template std::vector TLocalCoherenceLanczos::getOutput(void) { - std::vector out = {fevecName_, cevecName_, fevalName_, cevalName_}; + std::vector out = {fineName_, coarseName_}; return out; } @@ -187,47 +182,56 @@ void TLocalCoherenceLanczos::setup(void) { makeCoarseGrid(); } - envCreate(std::vector, fevecName_, Ls_, par().fineParams.Nm, + envCreate(FineEigenPack, fineName_, Ls_, par().fineParams.Nm, env().getRbGrid(Ls_)); - envCreate(std::vector, cevecName_, Ls_, par().coarseParams.Nm, + envCreate(CoarseEigenPack, coarseName_, Ls_, par().coarseParams.Nm, coarseGridRb_.get()); - envCreate(std::vector, fevalName_, Ls_, par().fineParams.Nm); - envCreate(std::vector, cevalName_, Ls_, par().coarseParams.Nm); + auto &fine = envGet(FineEigenPack, fineName_); + auto &coarse = envGet(CoarseEigenPack, coarseName_); envTmp(SchurFMat, "mat", Ls_, envGet(FMat, par().action)); envGetTmp(SchurFMat, mat); - envTmp(LCL, "solver", Ls_, env().getRbGrid(Ls_), coarseGridRb_.get(), mat, Odd, - envGet(std::vector, fevecName_), - envGet(std::vector, cevecName_), - envGet(std::vector, fevalName_), - envGet(std::vector, cevalName_)); + envTmp(LCL, "solver", Ls_, env().getRbGrid(Ls_), coarseGridRb_.get(), mat, + Odd, fine.evec, coarse.evec, fine.eval, coarse.eval); } // execution /////////////////////////////////////////////////////////////////// template void TLocalCoherenceLanczos::execute(void) { - auto &fine = par().fineParams; - auto &coarse = par().coarseParams; - + auto &finePar = par().fineParams; + auto &coarsePar = par().coarseParams; + auto &fine = envGet(FineEigenPack, fineName_); + auto &coarse = envGet(CoarseEigenPack, coarseName_); + envGetTmp(LCL, solver); if (par().doFine) { LOG(Message) << "Performing fine grid IRL -- Nstop= " - << fine.Nstop << ", Nk= " << fine.Nk << ", Nm= " - << fine.Nm << std::endl; - solver.calcFine(fine.Cheby, fine.Nstop, fine.Nk, fine.Nm, fine.resid, - fine.MaxIt, fine.betastp, fine.MinRes); + << finePar.Nstop << ", Nk= " << finePar.Nk << ", Nm= " + << finePar.Nm << std::endl; + solver.calcFine(finePar.Cheby, finePar.Nstop, finePar.Nk, finePar.Nm, + finePar.resid,finePar.MaxIt, finePar.betastp, + finePar.MinRes); LOG(Message) << "Orthogonalising" << std::endl; solver.Orthogonalise(); + if (!par().output.empty()) + { + fine.write(par().output + "_fine"); + } } if (par().doCoarse) { LOG(Message) << "Performing coarse grid IRL -- Nstop= " - << fine.Nstop << ", Nk= " << fine.Nk << ", Nm= " - << fine.Nm << std::endl; - solver.calcCoarse(coarse.Cheby, par().smoother, par().coarseRelaxTol, - coarse.Nstop, coarse.Nk, coarse.Nm, coarse.resid, - coarse.MaxIt, coarse.betastp, coarse.MinRes); + << coarsePar.Nstop << ", Nk= " << coarsePar.Nk << ", Nm= " + << coarsePar.Nm << std::endl; + solver.calcCoarse(coarsePar.Cheby, par().smoother, par().coarseRelaxTol, + coarsePar.Nstop, coarsePar.Nk, coarsePar.Nm, + coarsePar.resid, coarsePar.MaxIt, coarsePar.betastp, + coarsePar.MinRes); + if (!par().output.empty()) + { + coarse.write(par().output + "_coarse"); + } } }