From e415260961104e3f1bbde929130686a6f60d90f7 Mon Sep 17 00:00:00 2001 From: Guido Cossu Date: Mon, 3 Oct 2016 15:28:00 +0100 Subject: [PATCH 001/214] First cut on generalised HMC Backward compatibility OK --- lib/qcd/action/gauge/GaugeImpl.h | 54 +- lib/qcd/hmc/HMC.h | 38 +- lib/qcd/hmc/HmcRunner.h | 8 +- lib/qcd/hmc/NerscCheckpointer.h | 2 +- lib/qcd/hmc/integrators/Integrator.h | 107 ++-- .../hmc/integrators/Integrator_algorithm.h | 508 +++++++++--------- lib/qcd/smearing/GaugeConfiguration.h | 4 +- 7 files changed, 376 insertions(+), 345 deletions(-) diff --git a/lib/qcd/action/gauge/GaugeImpl.h b/lib/qcd/action/gauge/GaugeImpl.h index 400381bb..8e9ad36f 100644 --- a/lib/qcd/action/gauge/GaugeImpl.h +++ b/lib/qcd/action/gauge/GaugeImpl.h @@ -38,15 +38,19 @@ namespace QCD { template class WilsonLoops; -#define INHERIT_GIMPL_TYPES(GImpl) \ - typedef typename GImpl::Simd Simd; \ - typedef typename GImpl::GaugeLinkField GaugeLinkField; \ - typedef typename GImpl::GaugeField GaugeField; \ - typedef typename GImpl::SiteGaugeField SiteGaugeField; \ - typedef typename GImpl::SiteGaugeLink SiteGaugeLink; +// +#define INHERIT_GIMPL_TYPES(GImpl) \ + typedef typename GImpl::Simd Simd; \ + typedef typename GImpl::LinkField GaugeLinkField; \ + typedef typename GImpl::Field GaugeField; \ + typedef typename GImpl::SiteField SiteGaugeField; \ + typedef typename GImpl::SiteLink SiteGaugeLink; -// -template class GaugeImplTypes { +#define INHERIT_FIELD_TYPES(Impl) \ + typedef typename Impl::Field Field; + + +template class GaugeImplTypes { public: typedef S Simd; @@ -55,16 +59,14 @@ public: template using iImplGaugeField = iVector>, Nd>; - typedef iImplGaugeLink SiteGaugeLink; - typedef iImplGaugeField SiteGaugeField; + typedef iImplGaugeLink SiteLink; + typedef iImplGaugeField SiteField; - typedef Lattice GaugeLinkField; // bit ugly naming; polarised - // gauge field, lorentz... all - // ugly - typedef Lattice GaugeField; + typedef Lattice LinkField; + typedef Lattice Field; // Move this elsewhere? FIXME - static inline void AddGaugeLink(GaugeField &U, GaugeLinkField &W, + static inline void AddLink(Field &U, LinkField &W, int mu) { // U[mu] += W PARALLEL_FOR_LOOP for (auto ss = 0; ss < U._grid->oSites(); ss++) { @@ -72,6 +74,28 @@ public: U._odata[ss]._internal[mu] + W._odata[ss]._internal; } } + + static inline void generate_momenta(Field& P, GridParallelRNG& pRNG){ + // specific for SU gauge fields + LinkField Pmu(P._grid); + Pmu = zero; + for (int mu = 0; mu < Nd; mu++) { + SU::GaussianFundamentalLieAlgebraMatrix(pRNG, Pmu); + PokeIndex(P, Pmu, mu); + } + } + + static inline void update_field(Field& P, Field& U, double ep, unsigned int Nexp){ + + for (int mu = 0; mu < Nd; mu++) { + auto Umu = PeekIndex(U, mu); + auto Pmu = PeekIndex(P, mu); + Umu = expMat(Pmu, ep, Nexp) * Umu; + PokeIndex(U, ProjectOnGroup(Umu), mu); + } + + } + }; // Composition with smeared link, bc's etc.. probably need multiple inheritance diff --git a/lib/qcd/hmc/HMC.h b/lib/qcd/hmc/HMC.h index 05838349..a30242d3 100644 --- a/lib/qcd/hmc/HMC.h +++ b/lib/qcd/hmc/HMC.h @@ -60,24 +60,25 @@ struct HMCparameters { ///////////////////////////////// } - void print() const { - std::cout << GridLogMessage << "[HMC parameter] Trajectories : " << Trajectories << "\n"; - std::cout << GridLogMessage << "[HMC parameter] Start trajectory : " << StartTrajectory << "\n"; - std::cout << GridLogMessage << "[HMC parameter] Metropolis test (on/off): " << MetropolisTest << "\n"; - std::cout << GridLogMessage << "[HMC parameter] Thermalization trajs : " << NoMetropolisUntil << "\n"; + void print_parameters() const { + std::cout << GridLogMessage << "[HMC parameters] Trajectories : " << Trajectories << "\n"; + std::cout << GridLogMessage << "[HMC parameters] Start trajectory : " << StartTrajectory << "\n"; + std::cout << GridLogMessage << "[HMC parameters] Metropolis test (on/off): " << MetropolisTest << "\n"; + std::cout << GridLogMessage << "[HMC parameters] Thermalization trajs : " << NoMetropolisUntil << "\n"; } }; -template +template class HmcObservable { public: - virtual void TrajectoryComplete(int traj, GaugeField &U, GridSerialRNG &sRNG, + virtual void TrajectoryComplete(int traj, Field &U, GridSerialRNG &sRNG, GridParallelRNG &pRNG) = 0; }; + // this is only defined for a gauge theory template -class PlaquetteLogger : public HmcObservable { +class PlaquetteLogger : public HmcObservable { private: std::string Stem; @@ -117,19 +118,19 @@ class PlaquetteLogger : public HmcObservable { } }; -// template -template +template class HybridMonteCarlo { private: const HMCparameters Params; + typedef typename IntegratorType::Field Field; + GridSerialRNG &sRNG; // Fixme: need a RNG management strategy. GridParallelRNG &pRNG; // Fixme: need a RNG management strategy. - GaugeField &Ucur; + Field &Ucur; IntegratorType &TheIntegrator; - std::vector *> Observables; + std::vector *> Observables; ///////////////////////////////////////////////////////// // Metropolis step @@ -164,7 +165,7 @@ class HybridMonteCarlo { ///////////////////////////////////////////////////////// // Evolution ///////////////////////////////////////////////////////// - RealD evolve_step(GaugeField &U) { + RealD evolve_step(Field &U) { TheIntegrator.refresh(U, pRNG); // set U and initialize P and phi's RealD H0 = TheIntegrator.S(U); // initial state action @@ -191,20 +192,21 @@ class HybridMonteCarlo { // Constructor ///////////////////////////////////////// HybridMonteCarlo(HMCparameters Pams, IntegratorType &_Int, - GridSerialRNG &_sRNG, GridParallelRNG &_pRNG, GaugeField &_U) + GridSerialRNG &_sRNG, GridParallelRNG &_pRNG, Field &_U) : Params(Pams), TheIntegrator(_Int), sRNG(_sRNG), pRNG(_pRNG), Ucur(_U) {} ~HybridMonteCarlo(){}; - void AddObservable(HmcObservable *obs) { + void AddObservable(HmcObservable *obs) { Observables.push_back(obs); } void evolve(void) { Real DeltaH; - GaugeField Ucopy(Ucur._grid); + Field Ucopy(Ucur._grid); - Params.print(); + Params.print_parameters(); + TheIntegrator.print_parameters(); // Actual updates (evolve a copy Ucopy then copy back eventually) for (int traj = Params.StartTrajectory; diff --git a/lib/qcd/hmc/HmcRunner.h b/lib/qcd/hmc/HmcRunner.h index a31ba784..9ca4be01 100644 --- a/lib/qcd/hmc/HmcRunner.h +++ b/lib/qcd/hmc/HmcRunner.h @@ -32,6 +32,7 @@ directory namespace Grid { namespace QCD { +// Class for HMC specific for gauge theories template class NerscHmcRunnerTemplate { public: @@ -114,7 +115,7 @@ class NerscHmcRunnerTemplate { */ ////////////// NoSmearing SmearingPolicy; - typedef MinimumNorm2, RepresentationsPolicy > + typedef MinimumNorm2, RepresentationsPolicy > IntegratorType; // change here to change the algorithm IntegratorParameters MDpar(20, 1.0); IntegratorType MDynamics(UGrid, MDpar, TheAction, SmearingPolicy); @@ -157,10 +158,9 @@ class NerscHmcRunnerTemplate { // smeared set // notice that the unit configuration is singular in this procedure std::cout << GridLogMessage << "Filling the smeared set\n"; - SmearingPolicy.set_GaugeField(U); + SmearingPolicy.set_Field(U); - HybridMonteCarlo HMC(HMCpar, MDynamics, sRNG, - pRNG, U); + HybridMonteCarlo HMC(HMCpar, MDynamics, sRNG, pRNG, U); HMC.AddObservable(&Checkpoint); HMC.AddObservable(&PlaqLog); diff --git a/lib/qcd/hmc/NerscCheckpointer.h b/lib/qcd/hmc/NerscCheckpointer.h index 2e368b2a..6701740b 100644 --- a/lib/qcd/hmc/NerscCheckpointer.h +++ b/lib/qcd/hmc/NerscCheckpointer.h @@ -36,7 +36,7 @@ Author: paboyle namespace Grid{ namespace QCD{ - + // Only for gauge fields template class NerscHmcCheckpointer : public HmcObservable { private: diff --git a/lib/qcd/hmc/integrators/Integrator.h b/lib/qcd/hmc/integrators/Integrator.h index f89b7959..09e1c275 100644 --- a/lib/qcd/hmc/integrators/Integrator.h +++ b/lib/qcd/hmc/integrators/Integrator.h @@ -49,60 +49,53 @@ namespace Grid { namespace QCD { struct IntegratorParameters { - int Nexp; - int MDsteps; // number of outer steps - RealD trajL; // trajectory length - RealD stepsize; + unsigned int + Nexp; // number of terms in the Taylor expansion of the exponential + unsigned int MDsteps; // number of outer steps + RealD trajL; // trajectory length + RealD stepsize; // trajectory stepsize - IntegratorParameters(int MDsteps_, RealD trajL_ = 1.0, int Nexp_ = 12) + IntegratorParameters(int MDsteps_, RealD trajL_ = 1.0, + unsigned int Nexp_ = 12) : Nexp(Nexp_), MDsteps(MDsteps_), trajL(trajL_), stepsize(trajL / MDsteps){ // empty body constructor - }; + }; + + void print_parameters() { + std::cout << GridLogMessage << "[Integrator] Trajectory length : " << trajL << std::endl; + std::cout << GridLogMessage << "[Integrator] Number of MD steps : " << MDsteps << std::endl; + std::cout << GridLogMessage << "[Integrator] Step size : " << stepsize << std::endl; + std::cout << GridLogMessage << "[Integrator] Exponential approx.: " << Nexp << std::endl; + + } }; /*! @brief Class for Molecular Dynamics management */ -template +template class Integrator { protected: typedef IntegratorParameters ParameterType; + typedef typename FieldImplementation::Field MomentaField; //for readability + typedef typename FieldImplementation::Field Field; IntegratorParameters Params; - const ActionSet as; + const ActionSet as; int levels; // double t_U; // Track time passing on each level and for U and for P std::vector t_P; // - GaugeField P; + MomentaField P; SmearingPolicy& Smearer; RepresentationPolicy Representations; - // Should match any legal (SU(n)) gauge field - // Need to use this template to match Ncol to pass to SU class - template - void generate_momenta(Lattice >, Nd> >& P, - GridParallelRNG& pRNG) { - typedef Lattice > > > GaugeLinkField; - GaugeLinkField Pmu(P._grid); - Pmu = zero; - for (int mu = 0; mu < Nd; mu++) { - SU::GaussianFundamentalLieAlgebraMatrix(pRNG, Pmu); - PokeIndex(P, Pmu, mu); - } - } - - // ObserverList observers; // not yet - // typedef std::vector ObserverList; - // void register_observers(); - // void notify_observers(); - - void update_P(GaugeField& U, int level, double ep) { + void update_P(Field& U, int level, double ep) { t_P[level] += ep; update_P(P, U, level, ep); @@ -129,12 +122,12 @@ class Integrator { } } update_P_hireps{}; - void update_P(GaugeField& Mom, GaugeField& U, int level, double ep) { + void update_P(MomentaField& Mom, Field& U, int level, double ep) { // input U actually not used in the fundamental case // Fundamental updates, include smearing for (int a = 0; a < as[level].actions.size(); ++a) { - GaugeField force(U._grid); - GaugeField& Us = Smearer.get_U(as[level].actions.at(a)->is_smeared); + Field force(U._grid); + Field& Us = Smearer.get_U(as[level].actions.at(a)->is_smeared); as[level].actions.at(a)->deriv(Us, force); // deriv should NOT include Ta std::cout << GridLogIntegrator @@ -152,7 +145,7 @@ class Integrator { as[level].apply(update_P_hireps, Representations, Mom, U, ep); } - void update_U(GaugeField& U, double ep) { + void update_U(Field& U, double ep) { update_U(P, U, ep); t_U += ep; @@ -161,26 +154,21 @@ class Integrator { << "[" << fl << "] U " << " dt " << ep << " : t_U " << t_U << std::endl; } - void update_U(GaugeField& Mom, GaugeField& U, double ep) { - // rewrite exponential to deal internally with the lorentz index? - for (int mu = 0; mu < Nd; mu++) { - auto Umu = PeekIndex(U, mu); - auto Pmu = PeekIndex(Mom, mu); - Umu = expMat(Pmu, ep, Params.Nexp) * Umu; - PokeIndex(U, ProjectOnGroup(Umu), mu); - } - + void update_U(MomentaField& Mom, Field& U, double ep) { + FieldImplementation::update_field(Mom, U, ep, Params.Nexp); + // Update the smeared fields, can be implemented as observer - Smearer.set_GaugeField(U); + Smearer.set_Field(U); + // Update the higher representations fields Representations.update(U); // void functions if fundamental representation } - virtual void step(GaugeField& U, int level, int first, int last) = 0; + virtual void step(Field& U, int level, int first, int last) = 0; public: Integrator(GridBase* grid, IntegratorParameters Par, - ActionSet& Aset, + ActionSet& Aset, SmearingPolicy& Sm) : Params(Par), as(Aset), @@ -195,6 +183,13 @@ class Integrator { virtual ~Integrator() {} + virtual std::string integrator_name() = 0; + + void print_parameters(){ + std::cout << GridLogMessage << "[Integrator] Name : "<< integrator_name() << std::endl; + Params.print_parameters(); + } + // to be used by the actionlevel class to iterate // over the representations struct _refresh { @@ -210,14 +205,14 @@ class Integrator { } refresh_hireps{}; // Initialization of momenta and actions - void refresh(GaugeField& U, GridParallelRNG& pRNG) { + void refresh(Field& U, GridParallelRNG& pRNG) { std::cout << GridLogIntegrator << "Integrator refresh\n"; - generate_momenta(P, pRNG); + FieldImplementation::generate_momenta(P, pRNG); // Update the smeared fields, can be implemented as observer // necessary to keep the fields updated even after a reject // of the Metropolis - Smearer.set_GaugeField(U); + Smearer.set_Field(U); // Set the (eventual) representations gauge fields Representations.update(U); @@ -228,7 +223,7 @@ class Integrator { for (int actionID = 0; actionID < as[level].actions.size(); ++actionID) { // get gauge field from the SmearingPolicy and // based on the boolean is_smeared in actionID - GaugeField& Us = + Field& Us = Smearer.get_U(as[level].actions.at(actionID)->is_smeared); as[level].actions.at(actionID)->refresh(Us, pRNG); } @@ -256,11 +251,12 @@ class Integrator { } S_hireps{}; // Calculate action - RealD S(GaugeField& U) { // here also U not used + RealD S(Field& U) { // here also U not used LatticeComplex Hloc(U._grid); Hloc = zero; - // Momenta + // Momenta --- modify this (take the trace of field) + // momenta_action() for (int mu = 0; mu < Nd; mu++) { auto Pmu = PeekIndex(P, mu); Hloc -= trace(Pmu * Pmu); @@ -276,7 +272,7 @@ class Integrator { for (int actionID = 0; actionID < as[level].actions.size(); ++actionID) { // get gauge field from the SmearingPolicy and // based on the boolean is_smeared in actionID - GaugeField& Us = + Field& Us = Smearer.get_U(as[level].actions.at(actionID)->is_smeared); Hterm = as[level].actions.at(actionID)->S(Us); std::cout << GridLogMessage << "S Level " << level << " term " @@ -289,7 +285,7 @@ class Integrator { return H; } - void integrate(GaugeField& U) { + void integrate(Field& U) { // reset the clocks t_U = 0; for (int level = 0; level < as.size(); ++level) { @@ -312,7 +308,12 @@ class Integrator { // and that we indeed got to the end of the trajectory assert(fabs(t_U - Params.trajL) < 1.0e-6); } + + + + }; } } #endif // INTEGRATOR_INCLUDED + diff --git a/lib/qcd/hmc/integrators/Integrator_algorithm.h b/lib/qcd/hmc/integrators/Integrator_algorithm.h index cd289b08..67144912 100644 --- a/lib/qcd/hmc/integrators/Integrator_algorithm.h +++ b/lib/qcd/hmc/integrators/Integrator_algorithm.h @@ -1,287 +1,291 @@ - /************************************************************************************* +/************************************************************************************* - Grid physics library, www.github.com/paboyle/Grid +Grid physics library, www.github.com/paboyle/Grid - Source file: ./lib/qcd/hmc/integrators/Integrator_algorithm.h +Source file: ./lib/qcd/hmc/integrators/Integrator_algorithm.h - Copyright (C) 2015 +Copyright (C) 2015 Author: Peter Boyle Author: neo - 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 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. +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. +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 */ +See the full license in the file "LICENSE" in the top level distribution +directory +*************************************************************************************/ +/* END LEGAL */ //-------------------------------------------------------------------- + + /*! @file Integrator_algorithm.h * @brief Declaration of classes for the Molecular Dynamics algorithms * - * @author Guido Cossu */ //-------------------------------------------------------------------- #ifndef INTEGRATOR_ALG_INCLUDED #define INTEGRATOR_ALG_INCLUDED -namespace Grid{ - namespace QCD{ +namespace Grid { +namespace QCD { - /* PAB: - * - * Recursive leapfrog; explanation of nested stepping - * - * Nested 1:4; units in dt for top level integrator - * - * CHROMA IroIro - * 0 1 0 - * P 1/2 P 1/2 - * P 1/16 P1/16 - * U 1/8 U1/8 - * P 1/8 P1/8 - * U 1/8 U1/8 - * P 1/8 P1/8 - * U 1/8 U1/8 - * P 1/8 P1/8 - * U 1/8 U1/8 - * P 1/16 P1/8 - * P 1 P 1 - * P 1/16 * skipped --- avoids revaluating force - * U 1/8 U1/8 - * P 1/8 P1/8 - * U 1/8 U1/8 - * P 1/8 P1/8 - * U 1/8 U1/8 - * P 1/8 P1/8 - * U 1/8 U1/8 - * P 1/16 P1/8 - * P 1 P 1 - * P 1/16 * skipped - * U 1/8 U1/8 - * P 1/8 P1/8 - * U 1/8 U1/8 - * P 1/8 P1/8 - * U 1/8 U1/8 - * P 1/8 P1/8 - * U 1/8 U1/8 - * P 1/16 * skipped - * P 1 P 1 - * P 1/16 P1/8 - * U 1/8 U1/8 - * P 1/8 P1/8 - * U 1/8 U1/8 - * P 1/8 P1/8 - * U 1/8 U1/8 - * P 1/8 P1/8 - * U 1/8 U1/8 - * P 1/16 P1/16 - * P 1/2 P 1/2 - */ +/* PAB: + * + * Recursive leapfrog; explanation of nested stepping + * + * Nested 1:4; units in dt for top level integrator + * + * CHROMA IroIro + * 0 1 0 + * P 1/2 P 1/2 + * P 1/16 P1/16 + * U 1/8 U1/8 + * P 1/8 P1/8 + * U 1/8 U1/8 + * P 1/8 P1/8 + * U 1/8 U1/8 + * P 1/8 P1/8 + * U 1/8 U1/8 + * P 1/16 P1/8 + * P 1 P 1 + * P 1/16 * skipped --- avoids revaluating force + * U 1/8 U1/8 + * P 1/8 P1/8 + * U 1/8 U1/8 + * P 1/8 P1/8 + * U 1/8 U1/8 + * P 1/8 P1/8 + * U 1/8 U1/8 + * P 1/16 P1/8 + * P 1 P 1 + * P 1/16 * skipped + * U 1/8 U1/8 + * P 1/8 P1/8 + * U 1/8 U1/8 + * P 1/8 P1/8 + * U 1/8 U1/8 + * P 1/8 P1/8 + * U 1/8 U1/8 + * P 1/16 * skipped + * P 1 P 1 + * P 1/16 P1/8 + * U 1/8 U1/8 + * P 1/8 P1/8 + * U 1/8 U1/8 + * P 1/8 P1/8 + * U 1/8 U1/8 + * P 1/8 P1/8 + * U 1/8 U1/8 + * P 1/16 P1/16 + * P 1/2 P 1/2 + */ - template > class LeapFrog : - public Integrator { - public: +template > +class LeapFrog : public Integrator { + public: + typedef LeapFrog + Algorithm; + INHERIT_FIELD_TYPES(FieldImplementation); - typedef LeapFrog Algorithm; + std::string integrator_name(){return "LeapFrog";} - LeapFrog(GridBase* grid, - IntegratorParameters Par, - ActionSet & Aset, - SmearingPolicy & Sm): - Integrator(grid,Par,Aset,Sm) {}; + LeapFrog(GridBase* grid, IntegratorParameters Par, + ActionSet& Aset, SmearingPolicy& Sm) + : Integrator( + grid, Par, Aset, Sm){}; + void step(Field& U, int level, int _first, int _last) { + int fl = this->as.size() - 1; + // level : current level + // fl : final level + // eps : current step size - void step (GaugeField& U, int level,int _first, int _last){ + // Get current level step size + RealD eps = this->Params.stepsize; + for (int l = 0; l <= level; ++l) eps /= this->as[l].multiplier; - int fl = this->as.size() -1; - // level : current level - // fl : final level - // eps : current step size - - // Get current level step size - RealD eps = this->Params.stepsize; - for(int l=0; l<=level; ++l) eps/= this->as[l].multiplier; - - int multiplier = this->as[level].multiplier; - for(int e=0; eas[level].multiplier; + for (int e = 0; e < multiplier; ++e) { + int first_step = _first && (e == 0); + int last_step = _last && (e == multiplier - 1); - int first_step = _first && (e==0); - int last_step = _last && (e==multiplier-1); - - if(first_step){ // initial half step - this->update_P(U, level,eps/2.0); - } - - if(level == fl){ // lowest level - this->update_U(U, eps); - }else{ // recursive function call - this->step(U, level+1,first_step,last_step); - } - - int mm = last_step ? 1 : 2; - this->update_P(U, level,mm*eps/2.0); - - } - } - }; - - template > class MinimumNorm2 : - public Integrator { - private: - const RealD lambda = 0.1931833275037836; - - public: - - MinimumNorm2(GridBase* grid, - IntegratorParameters Par, - ActionSet & Aset, - SmearingPolicy& Sm): - Integrator(grid,Par,Aset,Sm) {}; - - void step (GaugeField& U, int level, int _first,int _last){ - - // level : current level - // fl : final level - // eps : current step size - - int fl = this->as.size() -1; - - RealD eps = this->Params.stepsize*2.0; - for(int l=0; l<=level; ++l) eps/= 2.0*this->as[l].multiplier; - - // Nesting: 2xupdate_U of size eps/2 - // Next level is eps/2/multiplier - - int multiplier = this->as[level].multiplier; - for(int e=0; eupdate_P(U,level,lambda*eps); - } - - if(level == fl){ // lowest level - this->update_U(U,0.5*eps); - }else{ // recursive function call - this->step(U,level+1,first_step,0); - } - - this->update_P(U,level,(1.0-2.0*lambda)*eps); - - if(level == fl){ // lowest level - this->update_U(U,0.5*eps); - }else{ // recursive function call - this->step(U,level+1,0,last_step); - } - - int mm = (last_step) ? 1 : 2; - this->update_P(U,level,lambda*eps*mm); - - } - } - }; - - - template > class ForceGradient : - public Integrator { - private: - const RealD lambda = 1.0/6.0;; - const RealD chi = 1.0/72.0; - const RealD xi = 0.0; - const RealD theta = 0.0; - public: - - // Looks like dH scales as dt^4. tested wilson/wilson 2 level. - ForceGradient(GridBase* grid, - IntegratorParameters Par, - ActionSet & Aset, - SmearingPolicy &Sm): - Integrator(grid,Par,Aset, Sm) {}; - - - void FG_update_P(GaugeField&U, int level,double fg_dt,double ep){ - GaugeField Ufg(U._grid); - GaugeField Pfg(U._grid); - Ufg = U; - Pfg = zero; - std::cout << GridLogMessage << "FG update "<update_P(Pfg,Ufg,level,1.0); - this->update_U(Pfg,Ufg,fg_dt); - this->update_P(Ufg,level,ep); + if (first_step) { // initial half step + this->update_P(U, level, eps / 2.0); } - void step (GaugeField& U, int level, int _first,int _last){ - - RealD eps = this->Params.stepsize*2.0; - for(int l=0; l<=level; ++l) eps/= 2.0*this->as[l].multiplier; - - RealD Chi = chi*eps*eps*eps; - - int fl = this->as.size() -1; - - int multiplier = this->as[level].multiplier; - - for(int e=0; eupdate_P(U,level,lambda*eps); - } - - if(level == fl){ // lowest level - this->update_U(U,0.5*eps); - }else{ // recursive function call - this->step(U,level+1,first_step,0); - } - - this->FG_update_P(U,level,2*Chi/((1.0-2.0*lambda)*eps),(1.0-2.0*lambda)*eps); - - if(level == fl){ // lowest level - this->update_U(U,0.5*eps); - }else{ // recursive function call - this->step(U,level+1,0,last_step); - } - - int mm = (last_step) ? 1 : 2; - this->update_P(U,level,lambda*eps*mm); - - } + if (level == fl) { // lowest level + this->update_U(U, eps); + } else { // recursive function call + this->step(U, level + 1, first_step, last_step); } - }; + int mm = last_step ? 1 : 2; + this->update_P(U, level, mm * eps / 2.0); + } } +}; + +template > +class MinimumNorm2 : public Integrator { + private: + const RealD lambda = 0.1931833275037836; + + public: + INHERIT_FIELD_TYPES(FieldImplementation); + + MinimumNorm2(GridBase* grid, IntegratorParameters Par, + ActionSet& Aset, SmearingPolicy& Sm) + : Integrator( + grid, Par, Aset, Sm){}; + + std::string integrator_name(){return "MininumNorm2";} + + void step(Field& U, int level, int _first, int _last) { + // level : current level + // fl : final level + // eps : current step size + + int fl = this->as.size() - 1; + + RealD eps = this->Params.stepsize * 2.0; + for (int l = 0; l <= level; ++l) eps /= 2.0 * this->as[l].multiplier; + + // Nesting: 2xupdate_U of size eps/2 + // Next level is eps/2/multiplier + + int multiplier = this->as[level].multiplier; + for (int e = 0; e < multiplier; ++e) { // steps per step + + int first_step = _first && (e == 0); + int last_step = _last && (e == multiplier - 1); + + if (first_step) { // initial half step + this->update_P(U, level, lambda * eps); + } + + if (level == fl) { // lowest level + this->update_U(U, 0.5 * eps); + } else { // recursive function call + this->step(U, level + 1, first_step, 0); + } + + this->update_P(U, level, (1.0 - 2.0 * lambda) * eps); + + if (level == fl) { // lowest level + this->update_U(U, 0.5 * eps); + } else { // recursive function call + this->step(U, level + 1, 0, last_step); + } + + int mm = (last_step) ? 1 : 2; + this->update_P(U, level, lambda * eps * mm); + } + } +}; + +template > +class ForceGradient : public Integrator { + private: + const RealD lambda = 1.0 / 6.0; + ; + const RealD chi = 1.0 / 72.0; + const RealD xi = 0.0; + const RealD theta = 0.0; + + public: + INHERIT_FIELD_TYPES(FieldImplementation); + + // Looks like dH scales as dt^4. tested wilson/wilson 2 level. + ForceGradient(GridBase* grid, IntegratorParameters Par, + ActionSet& Aset, + SmearingPolicy& Sm) + : Integrator( + grid, Par, Aset, Sm){}; + + std::string integrator_name(){return "ForceGradient";} + + void FG_update_P(Field& U, int level, double fg_dt, double ep) { + Field Ufg(U._grid); + Field Pfg(U._grid); + Ufg = U; + Pfg = zero; + std::cout << GridLogMessage << "FG update " << fg_dt << " " << ep + << std::endl; + // prepare_fg; no prediction/result cache for now + // could relax CG stopping conditions for the + // derivatives in the small step since the force gets multiplied by + // a tiny dt^2 term relative to main force. + // + // Presently 4 force evals, and should have 3, so 1.33x too expensive. + // could reduce this with sloppy CG to perhaps 1.15x too expensive + // even without prediction. + this->update_P(Pfg, Ufg, level, 1.0); + this->update_U(Pfg, Ufg, fg_dt); + this->update_P(Ufg, level, ep); + } + + void step(Field& U, int level, int _first, int _last) { + RealD eps = this->Params.stepsize * 2.0; + for (int l = 0; l <= level; ++l) eps /= 2.0 * this->as[l].multiplier; + + RealD Chi = chi * eps * eps * eps; + + int fl = this->as.size() - 1; + + int multiplier = this->as[level].multiplier; + + for (int e = 0; e < multiplier; ++e) { // steps per step + + int first_step = _first && (e == 0); + int last_step = _last && (e == multiplier - 1); + + if (first_step) { // initial half step + this->update_P(U, level, lambda * eps); + } + + if (level == fl) { // lowest level + this->update_U(U, 0.5 * eps); + } else { // recursive function call + this->step(U, level + 1, first_step, 0); + } + + this->FG_update_P(U, level, 2 * Chi / ((1.0 - 2.0 * lambda) * eps), + (1.0 - 2.0 * lambda) * eps); + + if (level == fl) { // lowest level + this->update_U(U, 0.5 * eps); + } else { // recursive function call + this->step(U, level + 1, 0, last_step); + } + + int mm = (last_step) ? 1 : 2; + this->update_P(U, level, lambda * eps * mm); + } + } +}; +} } -#endif//INTEGRATOR_INCLUDED +#endif // INTEGRATOR_INCLUDED diff --git a/lib/qcd/smearing/GaugeConfiguration.h b/lib/qcd/smearing/GaugeConfiguration.h index 57cccb0a..803f3566 100644 --- a/lib/qcd/smearing/GaugeConfiguration.h +++ b/lib/qcd/smearing/GaugeConfiguration.h @@ -21,7 +21,7 @@ public: NoSmearing(): ThinLinks(NULL) {} - void set_GaugeField(GaugeField& U) { ThinLinks = &U; } + void set_Field(GaugeField& U) { ThinLinks = &U; } void smeared_force(GaugeField& SigmaTilde) const {} @@ -227,7 +227,7 @@ class SmearedConfiguration { // attach the smeared routines to the thin links U and fill the smeared set - void set_GaugeField(GaugeField& U) { fill_smearedSet(U); } + void set_Field(GaugeField& U) { fill_smearedSet(U); } //==================================================================== void smeared_force(GaugeField& SigmaTilde) const { From 257f69f931d9d6f0e6e627001d76f6efd64e6bbf Mon Sep 17 00:00:00 2001 From: Guido Cossu Date: Mon, 3 Oct 2016 15:50:04 +0100 Subject: [PATCH 002/214] One more function to generalise the HMC integrator --- lib/qcd/action/gauge/GaugeImpl.h | 11 +++++++++++ lib/qcd/hmc/integrators/Integrator.h | 12 +----------- 2 files changed, 12 insertions(+), 11 deletions(-) diff --git a/lib/qcd/action/gauge/GaugeImpl.h b/lib/qcd/action/gauge/GaugeImpl.h index 8e9ad36f..fd3bf55a 100644 --- a/lib/qcd/action/gauge/GaugeImpl.h +++ b/lib/qcd/action/gauge/GaugeImpl.h @@ -96,6 +96,17 @@ public: } + static inline RealD FieldSquareNorm(Field& U){ + LatticeComplex Hloc(U._grid); + Hloc = zero; + for (int mu = 0; mu < Nd; mu++) { + auto Umu = PeekIndex(U, mu); + Hloc += trace(Umu * Umu); + } + Complex Hsum = sum(Hloc); + return Hsum.real(); + } + }; // Composition with smeared link, bc's etc.. probably need multiple inheritance diff --git a/lib/qcd/hmc/integrators/Integrator.h b/lib/qcd/hmc/integrators/Integrator.h index 09e1c275..d2c1aef1 100644 --- a/lib/qcd/hmc/integrators/Integrator.h +++ b/lib/qcd/hmc/integrators/Integrator.h @@ -253,17 +253,7 @@ class Integrator { // Calculate action RealD S(Field& U) { // here also U not used - LatticeComplex Hloc(U._grid); - Hloc = zero; - // Momenta --- modify this (take the trace of field) - // momenta_action() - for (int mu = 0; mu < Nd; mu++) { - auto Pmu = PeekIndex(P, mu); - Hloc -= trace(Pmu * Pmu); - } - Complex Hsum = sum(Hloc); - - RealD H = Hsum.real(); + RealD H = - FieldImplementation::FieldSquareNorm(P); // - trace (P*P) RealD Hterm; std::cout << GridLogMessage << "Momentum action H_p = " << H << "\n"; From cfbc1a26b8667f95a6fe4c2aff4baeacfad5c21b Mon Sep 17 00:00:00 2001 From: Guido Cossu Date: Mon, 3 Oct 2016 16:20:06 +0100 Subject: [PATCH 003/214] Now the gauge implementation has to take care of the Nexp --- lib/qcd/action/gauge/GaugeImpl.h | 11 ++++++----- lib/qcd/hmc/integrators/Integrator.h | 3 ++- 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/lib/qcd/action/gauge/GaugeImpl.h b/lib/qcd/action/gauge/GaugeImpl.h index fd3bf55a..5ef9f107 100644 --- a/lib/qcd/action/gauge/GaugeImpl.h +++ b/lib/qcd/action/gauge/GaugeImpl.h @@ -49,8 +49,8 @@ template class WilsonLoops; #define INHERIT_FIELD_TYPES(Impl) \ typedef typename Impl::Field Field; - -template class GaugeImplTypes { +// hard codes the exponential approximation in the template +template class GaugeImplTypes { public: typedef S Simd; @@ -75,6 +75,7 @@ public: } } + // HMC auxiliary functions static inline void generate_momenta(Field& P, GridParallelRNG& pRNG){ // specific for SU gauge fields LinkField Pmu(P._grid); @@ -85,15 +86,15 @@ public: } } - static inline void update_field(Field& P, Field& U, double ep, unsigned int Nexp){ - + + + static inline void update_field(Field& P, Field& U, double ep){ for (int mu = 0; mu < Nd; mu++) { auto Umu = PeekIndex(U, mu); auto Pmu = PeekIndex(P, mu); Umu = expMat(Pmu, ep, Nexp) * Umu; PokeIndex(U, ProjectOnGroup(Umu), mu); } - } static inline RealD FieldSquareNorm(Field& U){ diff --git a/lib/qcd/hmc/integrators/Integrator.h b/lib/qcd/hmc/integrators/Integrator.h index d2c1aef1..f5e5a37c 100644 --- a/lib/qcd/hmc/integrators/Integrator.h +++ b/lib/qcd/hmc/integrators/Integrator.h @@ -155,7 +155,8 @@ class Integrator { << " dt " << ep << " : t_U " << t_U << std::endl; } void update_U(MomentaField& Mom, Field& U, double ep) { - FieldImplementation::update_field(Mom, U, ep, Params.Nexp); + // exponential of Mom*U in the gauge fields case + FieldImplementation::update_field(Mom, U, ep); // Update the smeared fields, can be implemented as observer Smearer.set_Field(U); From d9b5fbd374fa08d700d52a054786d6ecd70b4e9d Mon Sep 17 00:00:00 2001 From: Guido Cossu Date: Tue, 4 Oct 2016 11:24:08 +0100 Subject: [PATCH 004/214] In the middle of adding a general binary writer --- lib/parallelIO/BinaryIO.h | 6 ++ lib/parallelIO/NerscIO.h | 86 +++++++++++----------- lib/qcd/hmc/BinaryCheckpointer.h | 106 +++++++++++++++++++++++++++ lib/qcd/hmc/integrators/Integrator.h | 20 ++--- 4 files changed, 163 insertions(+), 55 deletions(-) create mode 100644 lib/qcd/hmc/BinaryCheckpointer.h diff --git a/lib/parallelIO/BinaryIO.h b/lib/parallelIO/BinaryIO.h index 5eddb57d..6e2bbb67 100644 --- a/lib/parallelIO/BinaryIO.h +++ b/lib/parallelIO/BinaryIO.h @@ -539,6 +539,12 @@ class BinaryIO { int ieee64big = (format == std::string("IEEE64BIG")); int ieee64 = (format == std::string("IEEE64")); + if(!(ieee32big || ieee32 || ieee64big || ieee64)){ + std::cout << GridLogError << "Unrecognized file format " << format << std::endl; + std::cout << GridLogError << "Allowed: IEEE32BIG | IEEE32 | IEEE64BIG | IEEE64" << std::endl; + exit(0); + } + int nd = grid->_ndimension; for(int d=0;dCheckerBoarded(d) == 0); diff --git a/lib/parallelIO/NerscIO.h b/lib/parallelIO/NerscIO.h index 79572539..945c6571 100644 --- a/lib/parallelIO/NerscIO.h +++ b/lib/parallelIO/NerscIO.h @@ -137,51 +137,53 @@ inline void NerscMachineCharacteristics(NerscField &header) const int y=1; const int z=2; for(int mu=0;mu<4;mu++){ - cm(mu)()(2,x) = adj(cm(mu)()(0,y)*cm(mu)()(1,z)-cm(mu)()(0,z)*cm(mu)()(1,y)); //x= yz-zy - cm(mu)()(2,y) = adj(cm(mu)()(0,z)*cm(mu)()(1,x)-cm(mu)()(0,x)*cm(mu)()(1,z)); //y= zx-xz - cm(mu)()(2,z) = adj(cm(mu)()(0,x)*cm(mu)()(1,y)-cm(mu)()(0,y)*cm(mu)()(1,x)); //z= xy-yx + cm(mu)()(2,x) = adj(cm(mu)()(0,y)*cm(mu)()(1,z)-cm(mu)()(0,z)*cm(mu)()(1,y)); //x= yz-zy + cm(mu)()(2,y) = adj(cm(mu)()(0,z)*cm(mu)()(1,x)-cm(mu)()(0,x)*cm(mu)()(1,z)); //y= zx-xz + cm(mu)()(2,z) = adj(cm(mu)()(0,x)*cm(mu)()(1,y)-cm(mu)()(0,y)*cm(mu)()(1,x)); //z= xy-yx } } template struct NerscSimpleMunger{ - - void operator() (fobj &in,sobj &out,uint32_t &csum){ - - for(int mu=0;mu<4;mu++){ - for(int i=0;i<3;i++){ - for(int j=0;j<3;j++){ - out(mu)()(i,j) = in(mu)()(i,j); - }}} - NerscChecksum((uint32_t *)&in,sizeof(in),csum); + void operator()(fobj &in, sobj &out, uint32_t &csum) { + for (int mu = 0; mu < Nd; mu++) { + for (int i = 0; i < Nc; i++) { + for (int j = 0; j < Nc; j++) { + out(mu)()(i, j) = in(mu)()(i, j); + } + } + } + NerscChecksum((uint32_t *)&in, sizeof(in), csum); }; }; - template - struct NerscSimpleUnmunger{ - void operator() (sobj &in,fobj &out,uint32_t &csum){ - for(int mu=0;mu + struct NerscSimpleUnmunger { + void operator()(sobj &in, fobj &out, uint32_t &csum) { + for (int mu = 0; mu < Nd; mu++) { + for (int i = 0; i < Nc; i++) { + for (int j = 0; j < Nc; j++) { + out(mu)()(i, j) = in(mu)()(i, j); + } + } + } + NerscChecksum((uint32_t *)&out, sizeof(out), csum); }; }; - + template struct Nersc3x2munger{ void operator() (fobj &in,sobj &out,uint32_t &csum){ - NerscChecksum((uint32_t *)&in,sizeof(in),csum); + NerscChecksum((uint32_t *)&in,sizeof(in),csum); - for(int mu=0;mu<4;mu++){ - for(int i=0;i<2;i++){ - for(int j=0;j<3;j++){ - out(mu)()(i,j) = in(mu)(i)(j); - }} - } - reconstruct3(out); + for(int mu=0;mu<4;mu++){ + for(int i=0;i<2;i++){ + for(int j=0;j<3;j++){ + out(mu)()(i,j) = in(mu)(i)(j); + }} + } + reconstruct3(out); } }; @@ -191,14 +193,14 @@ inline void NerscMachineCharacteristics(NerscField &header) void operator() (sobj &in,fobj &out,uint32_t &csum){ - for(int mu=0;mu<4;mu++){ - for(int i=0;i<2;i++){ - for(int j=0;j<3;j++){ - out(mu)(i)(j) = in(mu)()(i,j); - }} - } + for(int mu=0;mu<4;mu++){ + for(int i=0;i<2;i++){ + for(int j=0;j<3;j++){ + out(mu)(i)(j) = in(mu)()(i,j); + }} + } - NerscChecksum((uint32_t *)&out,sizeof(out),csum); + NerscChecksum((uint32_t *)&out,sizeof(out),csum); } }; @@ -346,24 +348,24 @@ static inline void readConfiguration(Lattice > &Umu, if ( header.data_type == std::string("4D_SU3_GAUGE") ) { if ( ieee32 || ieee32big ) { // csum=BinaryIO::readObjectSerial, LorentzColour2x3F> - csum=BinaryIO::readObjectParallel, LorentzColour2x3F> - (Umu,file,Nersc3x2munger(), offset,format); + csum=BinaryIO::readObjectParallel, LorentzColour2x3F> + (Umu,file,Nersc3x2munger(), offset,format); } if ( ieee64 || ieee64big ) { //csum=BinaryIO::readObjectSerial, LorentzColour2x3D> csum=BinaryIO::readObjectParallel, LorentzColour2x3D> - (Umu,file,Nersc3x2munger(),offset,format); + (Umu,file,Nersc3x2munger(),offset,format); } } else if ( header.data_type == std::string("4D_SU3_GAUGE_3x3") ) { if ( ieee32 || ieee32big ) { //csum=BinaryIO::readObjectSerial,LorentzColourMatrixF> csum=BinaryIO::readObjectParallel,LorentzColourMatrixF> - (Umu,file,NerscSimpleMunger(),offset,format); + (Umu,file,NerscSimpleMunger(),offset,format); } if ( ieee64 || ieee64big ) { // csum=BinaryIO::readObjectSerial,LorentzColourMatrixD> csum=BinaryIO::readObjectParallel,LorentzColourMatrixD> - (Umu,file,NerscSimpleMunger(),offset,format); + (Umu,file,NerscSimpleMunger(),offset,format); } } else { assert(0); diff --git a/lib/qcd/hmc/BinaryCheckpointer.h b/lib/qcd/hmc/BinaryCheckpointer.h new file mode 100644 index 00000000..fb48201c --- /dev/null +++ b/lib/qcd/hmc/BinaryCheckpointer.h @@ -0,0 +1,106 @@ + /************************************************************************************* + + Grid physics library, www.github.com/paboyle/Grid + + Source file: ./lib/qcd/hmc/NerscCheckpointer.h + + Copyright (C) 2015 + +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 */ +#ifndef NERSC_CHECKPOINTER +#define NERSC_CHECKPOINTER + +#include +#include +#include + + +namespace Grid{ + namespace QCD{ + + template + struct BinarySimpleUnmunger{ + void operator() (sobj &in,fobj &out,uint32_t &csum){ + fobj = sobj; + csum =0; + }; + + + // Only for gauge fields + template + class BinaryHmcCheckpointer : public HmcObservable { + private: + std::string configStem; + std::string rngStem; + int SaveInterval; + public: + INHERIT_FIELD_TYPES(Impl); // The Field is a Lattice object + + typedef typename Field::vector_object vobj; + typedef typename vobj::scalar_object sobj; + + + BinaryHmcCheckpointer(std::string cf, std::string rn,int savemodulo) { + configStem = cf; + rngStem = rn; + SaveInterval= savemodulo; + }; + + void TrajectoryComplete(int traj, Field &U, GridSerialRNG &sRNG, + GridParallelRNG &pRNG) { + if ((traj % SaveInterval) == 0) { + std::string rng; + { + std::ostringstream os; + os << rngStem << "." << traj; + rng = os.str(); + } + std::string config; + { + std::ostringstream os; + os << configStem << "." << traj; + config = os.str(); + } + + int prec = getPrecision::value; //get precision of oject + std::string floating_point = "IEEE64BIG"; //default precision + if (prec == 1) + floating_point = "IEEE32BIG" + + BinarySimpleUnmunger munge; + BinaryIO::writeRNGSerial(sRNG, pRNG, rng, 0); + BinaryIO::writeObjectParallel(U, config, munge, 0 ,floating_point); + } + }; + + void CheckpointRestore(int traj, GaugeField &U, GridSerialRNG &sRNG, GridParallelRNG & pRNG ){ + + std::string rng; { std::ostringstream os; os << rngStem <<"."<< traj; rng = os.str(); } + std::string config;{ std::ostringstream os; os << configStem <<"."<< traj; config = os.str();} + + NerscField header; + NerscIO::readRNGState(sRNG,pRNG,header,rng); + NerscIO::readConfiguration(U,header,config); + }; + + }; +}} +#endif diff --git a/lib/qcd/hmc/integrators/Integrator.h b/lib/qcd/hmc/integrators/Integrator.h index f5e5a37c..735863a0 100644 --- a/lib/qcd/hmc/integrators/Integrator.h +++ b/lib/qcd/hmc/integrators/Integrator.h @@ -41,8 +41,6 @@ directory #ifndef INTEGRATOR_INCLUDED #define INTEGRATOR_INCLUDED -// class Observer; - #include namespace Grid { @@ -77,24 +75,20 @@ struct IntegratorParameters { template class Integrator { protected: - typedef IntegratorParameters ParameterType; typedef typename FieldImplementation::Field MomentaField; //for readability typedef typename FieldImplementation::Field Field; + int levels; // number of integration levels + double t_U; // Track time passing on each level and for U and for P + std::vector t_P; + + MomentaField P; + SmearingPolicy& Smearer; + RepresentationPolicy Representations; IntegratorParameters Params; const ActionSet as; - int levels; // - double t_U; // Track time passing on each level and for U and for P - std::vector t_P; // - - MomentaField P; - - SmearingPolicy& Smearer; - - RepresentationPolicy Representations; - void update_P(Field& U, int level, double ep) { t_P[level] += ep; update_P(P, U, level, ep); From c065e454c392dda361eaa0d9f8172ac7b2c09a7e Mon Sep 17 00:00:00 2001 From: Guido Cossu Date: Thu, 6 Oct 2016 10:12:11 +0100 Subject: [PATCH 005/214] Adding Binrary IO, untested --- lib/algorithms/approx/Chebyshev.h | 5 +- lib/parallelIO/NerscIO.h | 4 +- lib/qcd/hmc/BinaryCheckpointer.h | 202 +++++++++++++++++----------- lib/tensors/Tensor_class.h | 13 +- lib/tensors/Tensor_traits.h | 13 +- tests/solver/Test_wilson_lanczos.cc | 108 +++++++++++++++ 6 files changed, 258 insertions(+), 87 deletions(-) create mode 100644 tests/solver/Test_wilson_lanczos.cc diff --git a/lib/algorithms/approx/Chebyshev.h b/lib/algorithms/approx/Chebyshev.h index 6837ae99..2793f138 100644 --- a/lib/algorithms/approx/Chebyshev.h +++ b/lib/algorithms/approx/Chebyshev.h @@ -197,8 +197,9 @@ namespace Grid { void operator() (LinearOperatorBase &Linop, const Field &in, Field &out) { GridBase *grid=in._grid; -//std::cout << "Chevyshef(): in._grid="< #include #include +#include +namespace Grid { +namespace QCD { -namespace Grid{ - namespace QCD{ +template +struct BinarySimpleUnmunger { + typedef typename getPrecision::real_scalar_type fobj_stype; + typedef typename getPrecision::real_scalar_type sobj_stype; + + void operator()(sobj &in, fobj &out, uint32_t &csum) { + // take word by word and transform accoding to the status + fobj_stype* out_buffer = (fobj_stype*)&out; + sobj_stype* in_buffer = (sobj_stype*)∈ + size_t fobj_words = sizeof(out)/sizeof(fobj_stype); + size_t sobj_words = sizeof(in)/sizeof(sobj_stype); + assert(fobj_words == sobj_words); + + for (unsigned int word = 0; word < sobj_words; word++) + out_buffer[word] = in_buffer[word]; // type conversion on the fly + + BinaryIO::Uint32Checksum((uint32_t*)&out,sizeof(out),csum); - template - struct BinarySimpleUnmunger{ - void operator() (sobj &in,fobj &out,uint32_t &csum){ - fobj = sobj; - csum =0; - }; + }; + +template +struct BinarySimpleMunger { + typedef typename getPrecision::real_scalar_type fobj_stype; + typedef typename getPrecision::real_scalar_type sobj_stype; + + void operator()(sobj &out, fobj &in, uint32_t &csum) { + // take word by word and transform accoding to the status + fobj_stype* in_buffer = (fobj_stype*)∈ + sobj_stype* out_buffer = (sobj_stype*)&out; + size_t fobj_words = sizeof(in)/sizeof(fobj_stype); + size_t sobj_words = sizeof(out)/sizeof(sobj_stype); + assert(fobj_words == sobj_words); + + for (unsigned int word = 0; word < sobj_words; word++) + out_buffer[word] = in_buffer[word]; // type conversion on the fly + + BinaryIO::Uint32Checksum((uint32_t*)&in,sizeof(in),csum); + + }; - // Only for gauge fields - template - class BinaryHmcCheckpointer : public HmcObservable { - private: - std::string configStem; - std::string rngStem; - int SaveInterval; - public: - INHERIT_FIELD_TYPES(Impl); // The Field is a Lattice object + // Only for the main field in the hmc + template + class BinaryHmcCheckpointer : public HmcObservable { + private: + std::string configStem; + std::string rngStem; + int SaveInterval; - typedef typename Field::vector_object vobj; - typedef typename vobj::scalar_object sobj; - + public: + INHERIT_FIELD_TYPES(Impl); // The Field is a Lattice object - BinaryHmcCheckpointer(std::string cf, std::string rn,int savemodulo) { - configStem = cf; - rngStem = rn; - SaveInterval= savemodulo; - }; + typedef typename Field::vector_object vobj; + typedef typename vobj::scalar_object sobj; + typedef typename getPrecision::real_scalar_type sobj_stype; + typedef typename sobj::DoublePrecision sobj_double; - void TrajectoryComplete(int traj, Field &U, GridSerialRNG &sRNG, - GridParallelRNG &pRNG) { - if ((traj % SaveInterval) == 0) { - std::string rng; - { - std::ostringstream os; - os << rngStem << "." << traj; - rng = os.str(); - } - std::string config; - { - std::ostringstream os; - os << configStem << "." << traj; - config = os.str(); - } + BinaryHmcCheckpointer(std::string cf, std::string rn, int savemodulo, const std::string &format) + : configStem(cf), + rngStem(rn), + SaveInterval(savemodulo){}; - int prec = getPrecision::value; //get precision of oject - std::string floating_point = "IEEE64BIG"; //default precision - if (prec == 1) - floating_point = "IEEE32BIG" - - BinarySimpleUnmunger munge; - BinaryIO::writeRNGSerial(sRNG, pRNG, rng, 0); - BinaryIO::writeObjectParallel(U, config, munge, 0 ,floating_point); + void TrajectoryComplete(int traj, Field &U, GridSerialRNG &sRNG, + GridParallelRNG &pRNG) { + if ((traj % SaveInterval) == 0) { + std::string rng; + { + std::ostringstream os; + os << rngStem << "." << traj; + rng = os.str(); + } + std::string config; + { + std::ostringstream os; + os << configStem << "." << traj; + config = os.str(); } - }; - - void CheckpointRestore(int traj, GaugeField &U, GridSerialRNG &sRNG, GridParallelRNG & pRNG ){ - - std::string rng; { std::ostringstream os; os << rngStem <<"."<< traj; rng = os.str(); } - std::string config;{ std::ostringstream os; os << configStem <<"."<< traj; config = os.str();} - - NerscField header; - NerscIO::readRNGState(sRNG,pRNG,header,rng); - NerscIO::readConfiguration(U,header,config); - }; + // Save always in double precision + BinarySimpleUnmunger munge; + BinaryIO::writeRNGSerial(sRNG, pRNG, rng, 0); + BinaryIO::writeObjectParallel(U, config, munge, 0, format); + } }; -}} + + void CheckpointRestore(int traj, Field &U, GridSerialRNG &sRNG, + GridParallelRNG &pRNG) { + std::string rng; + { + std::ostringstream os; + os << rngStem << "." << traj; + rng = os.str(); + } + std::string config; + { + std::ostringstream os; + os << configStem << "." << traj; + config = os.str(); + } + + BinarySimpleMunger munge; + BinaryIO::readRNGSerial(sRNG, pRNG, rng, header); + BinaryIO::readObjectParallel(U, config, munge, 0, format); + }; + }; +} +} #endif diff --git a/lib/tensors/Tensor_class.h b/lib/tensors/Tensor_class.h index 473dd6b1..916fc09c 100644 --- a/lib/tensors/Tensor_class.h +++ b/lib/tensors/Tensor_class.h @@ -65,6 +65,9 @@ class iScalar { typedef iScalar::Complexified> Complexified; typedef iScalar::Realified> Realified; + // get double precision version + typedef iScalar::DoublePrecision> DoublePrecision; + enum { TensorLevel = GridTypeMapper::TensorLevel + 1 }; // Scalar no action @@ -197,6 +200,10 @@ class iVector { typedef iVector::Complexified, N> Complexified; typedef iVector::Realified, N> Realified; + // get double precision version + typedef iVector::DoublePrecision, N> DoublePrecision; + + template ::value, T>::type * = nullptr> strong_inline auto operator=(T arg) -> iVector { @@ -300,7 +307,11 @@ class iMatrix { typedef iMatrix::Complexified, N> Complexified; typedef iMatrix::Realified, N> Realified; - // Tensure removal + // get double precision version + typedef iMatrix::DoublePrecision, N> DoublePrecision; + + + // Tensor removal typedef iScalar tensor_reduced; typedef iMatrix scalar_object; diff --git a/lib/tensors/Tensor_traits.h b/lib/tensors/Tensor_traits.h index 777b398d..5191f190 100644 --- a/lib/tensors/Tensor_traits.h +++ b/lib/tensors/Tensor_traits.h @@ -57,6 +57,7 @@ namespace Grid { typedef typename T::scalar_object scalar_object; typedef typename T::Complexified Complexified; typedef typename T::Realified Realified; + typedef typename T::DoublePrecision DoublePrecision; enum { TensorLevel = T::TensorLevel }; }; @@ -71,6 +72,7 @@ namespace Grid { typedef RealF scalar_object; typedef ComplexF Complexified; typedef RealF Realified; + typedef RealD DoublePrecision; enum { TensorLevel = 0 }; }; template<> class GridTypeMapper { @@ -81,6 +83,7 @@ namespace Grid { typedef RealD scalar_object; typedef ComplexD Complexified; typedef RealD Realified; + typedef RealD DoublePrecision; enum { TensorLevel = 0 }; }; template<> class GridTypeMapper { @@ -91,6 +94,7 @@ namespace Grid { typedef ComplexF scalar_object; typedef ComplexF Complexified; typedef RealF Realified; + typedef ComplexD DoublePrecision; enum { TensorLevel = 0 }; }; template<> class GridTypeMapper { @@ -101,6 +105,7 @@ namespace Grid { typedef ComplexD scalar_object; typedef ComplexD Complexified; typedef RealD Realified; + typedef ComplexD DoublePrecision; enum { TensorLevel = 0 }; }; template<> class GridTypeMapper { @@ -111,6 +116,7 @@ namespace Grid { typedef Integer scalar_object; typedef void Complexified; typedef void Realified; + typedef void DoublePrecision; enum { TensorLevel = 0 }; }; @@ -122,6 +128,7 @@ namespace Grid { typedef RealF scalar_object; typedef vComplexF Complexified; typedef vRealF Realified; + typedef vRealD DoublePrecision; enum { TensorLevel = 0 }; }; template<> class GridTypeMapper { @@ -132,6 +139,7 @@ namespace Grid { typedef RealD scalar_object; typedef vComplexD Complexified; typedef vRealD Realified; + typedef vRealD DoublePrecision; enum { TensorLevel = 0 }; }; template<> class GridTypeMapper { @@ -142,6 +150,7 @@ namespace Grid { typedef ComplexF scalar_object; typedef vComplexF Complexified; typedef vRealF Realified; + typedef vComplexD DoublePrecision; enum { TensorLevel = 0 }; }; template<> class GridTypeMapper { @@ -152,6 +161,7 @@ namespace Grid { typedef ComplexD scalar_object; typedef vComplexD Complexified; typedef vRealD Realified; + typedef vComplexD DoublePrecision; enum { TensorLevel = 0 }; }; template<> class GridTypeMapper { @@ -162,6 +172,7 @@ namespace Grid { typedef Integer scalar_object; typedef void Complexified; typedef void Realified; + typedef void DoublePrecision; enum { TensorLevel = 0 }; }; @@ -256,8 +267,8 @@ namespace Grid { typedef typename getVectorType::type vector_obj; //get the vector_obj (i.e. a grid Tensor) if its a Lattice, do nothing otherwise (i.e. if fundamental or grid Tensor) typedef typename GridTypeMapper::scalar_type scalar_type; //get the associated scalar type. Works on fundamental and tensor types - typedef typename GridTypeMapper::Realified real_scalar_type; //remove any std::complex wrapper, should get us to the fundamental type public: + typedef typename GridTypeMapper::Realified real_scalar_type; //remove any std::complex wrapper, should get us to the fundamental type enum { value = sizeof(real_scalar_type)/sizeof(float) }; }; } diff --git a/tests/solver/Test_wilson_lanczos.cc b/tests/solver/Test_wilson_lanczos.cc new file mode 100644 index 00000000..e8549234 --- /dev/null +++ b/tests/solver/Test_wilson_lanczos.cc @@ -0,0 +1,108 @@ +/************************************************************************************* + +Grid physics library, www.github.com/paboyle/Grid + +Source file: ./tests/Test_dwf_lanczos.cc + +Copyright (C) 2015 + +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 +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 + +using namespace std; +using namespace Grid; +using namespace Grid::QCD; + +typedef WilsonFermionR FermionOp; +typedef typename WilsonFermionR::FermionField FermionField; + + +RealD AllZero(RealD x) { return 0.; } + +int main(int argc, char** argv) { + Grid_init(&argc, &argv); + + GridCartesian* UGrid = SpaceTimeGrid::makeFourDimGrid( + GridDefaultLatt(), GridDefaultSimd(Nd, vComplex::Nsimd()), + GridDefaultMpi()); + GridRedBlackCartesian* UrbGrid = + SpaceTimeGrid::makeFourDimRedBlackGrid(UGrid); + GridCartesian* FGrid = UGrid; + GridRedBlackCartesian* FrbGrid = UrbGrid; + printf("UGrid=%p UrbGrid=%p FGrid=%p FrbGrid=%p\n", UGrid, UrbGrid, FGrid, + FrbGrid); + + std::vector seeds4({1, 2, 3, 4}); + std::vector seeds5({5, 6, 7, 8}); + GridParallelRNG RNG5(FGrid); + RNG5.SeedFixedIntegers(seeds5); + GridParallelRNG RNG4(UGrid); + RNG4.SeedFixedIntegers(seeds4); + GridParallelRNG RNG5rb(FrbGrid); + RNG5.SeedFixedIntegers(seeds5); + + LatticeGaugeField Umu(UGrid); + SU3::HotConfiguration(RNG4, Umu); + +/* + std::vector U(4, UGrid); + for (int mu = 0; mu < Nd; mu++) { + U[mu] = PeekIndex(Umu, mu); + } +*/ + + RealD mass = -0.1; + RealD M5 = 1.8; + RealD mob_b = 1.5; + FermionOp WilsonOperator(Umu,*FGrid,*FrbGrid,mass); + MdagMLinearOperator HermOp(WilsonOperator); /// <----- + //SchurDiagTwoOperator HermOp(WilsonOperator); + + const int Nstop = 20; + const int Nk = 60; + const int Np = 60; + const int Nm = Nk + Np; + const int MaxIt = 10000; + RealD resid = 1.0e-6; + + std::vector Coeffs{0, 1.}; + Polynomial PolyX(Coeffs); + Chebyshev Cheb(0.0, 10., 12); + ImplicitlyRestartedLanczos IRL(HermOp, PolyX, Nstop, Nk, Nm, + resid, MaxIt); + + std::vector eval(Nm); + FermionField src(FGrid); + gaussian(RNG5, src); + std::vector evec(Nm, FGrid); + for (int i = 0; i < 1; i++) { + std::cout << i << " / " << Nm << " grid pointer " << evec[i]._grid + << std::endl; + }; + + int Nconv; + IRL.calc(eval, evec, src, Nconv); + + std::cout << eval << std::endl; + + Grid_finalize(); +} From 11b4c80b2778b7f7fc0ad4c9aced2f32cf5ae89c Mon Sep 17 00:00:00 2001 From: Guido Cossu Date: Fri, 7 Oct 2016 13:37:29 +0100 Subject: [PATCH 006/214] Added support for hmc and binary IO for a general field --- lib/Grid.h | 2 + lib/parallelIO/BinaryIO.h | 260 +++++++++++------- lib/qcd/QCD.h | 2 +- lib/qcd/action/gauge/GaugeImpl.h | 13 + lib/qcd/hmc/BinaryCheckpointer.h | 148 ++++------ lib/qcd/hmc/GenericHMCrunner.h | 173 ++++++++++++ tests/hmc/Make.inc | 7 +- .../hmc/Test_hmc_WilsonFermionGauge_Binary.cc | 99 +++++++ 8 files changed, 517 insertions(+), 187 deletions(-) create mode 100644 lib/qcd/hmc/GenericHMCrunner.h create mode 100644 tests/hmc/Test_hmc_WilsonFermionGauge_Binary.cc diff --git a/lib/Grid.h b/lib/Grid.h index 486ee4d3..d2e12d29 100644 --- a/lib/Grid.h +++ b/lib/Grid.h @@ -83,7 +83,9 @@ Author: paboyle #include #include +#include #include +#include diff --git a/lib/parallelIO/BinaryIO.h b/lib/parallelIO/BinaryIO.h index 6e2bbb67..f9a8ae3c 100644 --- a/lib/parallelIO/BinaryIO.h +++ b/lib/parallelIO/BinaryIO.h @@ -159,7 +159,48 @@ class BinaryIO { csum=csum+buf[i]; } } - + + // Simple classes for precision conversion + template + struct BinarySimpleUnmunger { + typedef typename getPrecision::real_scalar_type fobj_stype; + typedef typename getPrecision::real_scalar_type sobj_stype; + + void operator()(sobj &in, fobj &out, uint32_t &csum) { + // take word by word and transform accoding to the status + fobj_stype *out_buffer = (fobj_stype *)&out; + sobj_stype *in_buffer = (sobj_stype *)∈ + size_t fobj_words = sizeof(out) / sizeof(fobj_stype); + size_t sobj_words = sizeof(in) / sizeof(sobj_stype); + assert(fobj_words == sobj_words); + + for (unsigned int word = 0; word < sobj_words; word++) + out_buffer[word] = in_buffer[word]; // type conversion on the fly + + BinaryIO::Uint32Checksum((uint32_t *)&out, sizeof(out), csum); + } + }; + + template + struct BinarySimpleMunger { + typedef typename getPrecision::real_scalar_type fobj_stype; + typedef typename getPrecision::real_scalar_type sobj_stype; + + void operator()(fobj &in, sobj &out, uint32_t &csum) { + // take word by word and transform accoding to the status + fobj_stype *in_buffer = (fobj_stype *)∈ + sobj_stype *out_buffer = (sobj_stype *)&out; + size_t fobj_words = sizeof(in) / sizeof(fobj_stype); + size_t sobj_words = sizeof(out) / sizeof(sobj_stype); + assert(fobj_words == sobj_words); + + for (unsigned int word = 0; word < sobj_words; word++) + out_buffer[word] = in_buffer[word]; // type conversion on the fly + + BinaryIO::Uint32Checksum((uint32_t *)&in, sizeof(in), csum); + } + }; + template static inline uint32_t readObjectSerial(Lattice &Umu,std::string file,munger munge,int offset,const std::string &format) { @@ -272,58 +313,65 @@ class BinaryIO { return csum; } - static inline uint32_t writeRNGSerial(GridSerialRNG &serial,GridParallelRNG ¶llel,std::string file,int offset) - { + static inline uint32_t writeRNGSerial(GridSerialRNG &serial, + GridParallelRNG ¶llel, + std::string file, int offset) { typedef typename GridSerialRNG::RngStateType RngStateType; const int RngStateCount = GridSerialRNG::RngStateCount; - GridBase *grid = parallel._grid; int gsites = grid->_gsites; ////////////////////////////////////////////////// // Serialise through node zero ////////////////////////////////////////////////// - std::cout<< GridLogMessage<< "Serial RNG write I/O "<< file<IsBoss() ) { - fout.open(file,std::ios::binary|std::ios::out|std::ios::in); + if (grid->IsBoss()) { + fout.open(file, std::ios::binary | std::ios::out | std::ios::in); + if (!fout.is_open()) { + std::cout << GridLogMessage << "writeRNGSerial: Error opening file " + << file << std::endl; + exit(0); + } fout.seekp(offset); } - - uint32_t csum=0; + + std::cout << GridLogMessage << "Serial RNG write I/O " << file << std::endl; + uint32_t csum = 0; std::vector saved(RngStateCount); - int bytes = sizeof(RngStateType)*saved.size(); + int bytes = sizeof(RngStateType) * saved.size(); std::vector gcoor; - for(int gidx=0;gidxGlobalIndexToGlobalCoor(gidx, gcoor); + grid->GlobalCoorToRankIndex(rank, o_idx, i_idx, gcoor); + int l_idx = parallel.generator_idx(o_idx, i_idx); - int rank,o_idx,i_idx; - grid->GlobalIndexToGlobalCoor(gidx,gcoor); - grid->GlobalCoorToRankIndex(rank,o_idx,i_idx,gcoor); - int l_idx=parallel.generator_idx(o_idx,i_idx); - - if( rank == grid->ThisRank() ){ - // std::cout << "rank" << rank<<" Getting state for index "<ThisRank()) { + // std::cout << "rank" << rank<<" Getting state for index + // "<Broadcast(rank,(void *)&saved[0],bytes); + grid->Broadcast(rank, (void *)&saved[0], bytes); - if ( grid->IsBoss() ) { - Uint32Checksum((uint32_t *)&saved[0],bytes,csum); - fout.write((char *)&saved[0],bytes); + if (grid->IsBoss()) { + Uint32Checksum((uint32_t *)&saved[0], bytes, csum); + fout.write((char *)&saved[0], bytes); } - } - if ( grid->IsBoss() ) { - serial.GetState(saved,0); - Uint32Checksum((uint32_t *)&saved[0],bytes,csum); - fout.write((char *)&saved[0],bytes); + if (grid->IsBoss()) { + serial.GetState(saved, 0); + Uint32Checksum((uint32_t *)&saved[0], bytes, csum); + fout.write((char *)&saved[0], bytes); } - grid->Broadcast(0,(void *)&csum,sizeof(csum)); + grid->Broadcast(0, (void *)&csum, sizeof(csum)); + + if (grid->IsBoss()) + fout.close(); + return csum; } static inline uint32_t readRNGSerial(GridSerialRNG &serial,GridParallelRNG ¶llel,std::string file,int offset) @@ -528,30 +576,35 @@ class BinaryIO { ////////////////////////////////////////////////////////// // Parallel writer ////////////////////////////////////////////////////////// - template - static inline uint32_t writeObjectParallel(Lattice &Umu,std::string file,munger munge,int offset,const std::string & format) - { + template + static inline uint32_t writeObjectParallel(Lattice &Umu, + std::string file, munger munge, + int offset, + const std::string &format) { typedef typename vobj::scalar_object sobj; GridBase *grid = Umu._grid; int ieee32big = (format == std::string("IEEE32BIG")); - int ieee32 = (format == std::string("IEEE32")); + int ieee32 = (format == std::string("IEEE32")); int ieee64big = (format == std::string("IEEE64BIG")); - int ieee64 = (format == std::string("IEEE64")); + int ieee64 = (format == std::string("IEEE64")); - if(!(ieee32big || ieee32 || ieee64big || ieee64)){ - std::cout << GridLogError << "Unrecognized file format " << format << std::endl; - std::cout << GridLogError << "Allowed: IEEE32BIG | IEEE32 | IEEE64BIG | IEEE64" << std::endl; + if (!(ieee32big || ieee32 || ieee64big || ieee64)) { + std::cout << GridLogError << "Unrecognized file format " << format + << std::endl; + std::cout << GridLogError + << "Allowed: IEEE32BIG | IEEE32 | IEEE64BIG | IEEE64" + << std::endl; exit(0); } int nd = grid->_ndimension; - for(int d=0;dCheckerBoarded(d) == 0); } - std::vector parallel(nd,1); - std::vector ioproc (nd); + std::vector parallel(nd, 1); + std::vector ioproc(nd); std::vector start(nd); std::vector range(nd); @@ -559,39 +612,39 @@ class BinaryIO { int IOnode = 1; - for(int d=0;d_ndimension;d++) { - - if ( d!= grid->_ndimension-1 ) parallel[d] = 0; + for (int d = 0; d < grid->_ndimension; d++) { + if (d != grid->_ndimension - 1) parallel[d] = 0; if (parallel[d]) { - range[d] = grid->_ldimensions[d]; - start[d] = grid->_processor_coor[d]*range[d]; - ioproc[d]= grid->_processor_coor[d]; + range[d] = grid->_ldimensions[d]; + start[d] = grid->_processor_coor[d] * range[d]; + ioproc[d] = grid->_processor_coor[d]; } else { - range[d] = grid->_gdimensions[d]; - start[d] = 0; - ioproc[d]= 0; + range[d] = grid->_gdimensions[d]; + start[d] = 0; + ioproc[d] = 0; - if ( grid->_processor_coor[d] != 0 ) IOnode = 0; + if (grid->_processor_coor[d] != 0) IOnode = 0; } slice_vol = slice_vol * range[d]; } - + { uint32_t tmp = IOnode; grid->GlobalSum(tmp); - std::cout<< GridLogMessage<< "Parallel write I/O from "<< file << " with " <_ndimension;d++){ - std::cout<< range[d]; - if( d< grid->_ndimension-1 ) - std::cout<< " x "; + std::cout << GridLogMessage << "Parallel write I/O from " << file + << " with " << tmp << " IOnodes for subslice "; + for (int d = 0; d < grid->_ndimension; d++) { + std::cout << range[d]; + if (d < grid->_ndimension - 1) std::cout << " x "; } std::cout << std::endl; } - GridStopWatch timer; timer.Start(); - uint64_t bytes=0; + GridStopWatch timer; + timer.Start(); + uint64_t bytes = 0; int myrank = grid->ThisRank(); int iorank = grid->RankFromProcessorCoor(ioproc); @@ -601,71 +654,79 @@ class BinaryIO { // Ideally one reader/writer per xy plane and read these contiguously // with comms from nominated I/O nodes. std::ofstream fout; - if ( IOnode ) fout.open(file,std::ios::binary|std::ios::in|std::ios::out); + if (IOnode){ + fout.open(file, std::ios::binary | std::ios::in | std::ios::out); + if (!fout.is_open()) { + std::cout << GridLogMessage << "writeObjectParallel: Error opening file " << file + << std::endl; + exit(0); + } + } ////////////////////////////////////////////////////////// // Find the location of each site and send to primary node - // Take loop order from Chroma; defines loop order now that NERSC doc no longer + // Take loop order from Chroma; defines loop order now that NERSC doc no + // longer // available (how short sighted is that?) ////////////////////////////////////////////////////////// - uint32_t csum=0; + uint32_t csum = 0; fobj fileObj; - static sobj siteObj; // static for SHMEM target; otherwise dynamic allocate with AlignedAllocator + static sobj siteObj; // static for SHMEM target; otherwise dynamic allocate + // with AlignedAllocator // should aggregate a whole chunk and then write. - // need to implement these loops in Nd independent way with a lexico conversion - for(int tlex=0;tlex tsite(nd); // temporary mixed up site + // need to implement these loops in Nd independent way with a lexico + // conversion + for (int tlex = 0; tlex < slice_vol; tlex++) { + std::vector tsite(nd); // temporary mixed up site std::vector gsite(nd); std::vector lsite(nd); std::vector iosite(nd); - Lexicographic::CoorFromIndex(tsite,tlex,range); + Lexicographic::CoorFromIndex(tsite, tlex, range); - for(int d=0;d_ldimensions[d]; // local site - gsite[d] = tsite[d]+start[d]; // global site + for (int d = 0; d < nd; d++) { + lsite[d] = tsite[d] % grid->_ldimensions[d]; // local site + gsite[d] = tsite[d] + start[d]; // global site } - ///////////////////////// // Get the rank of owner of data ///////////////////////// - int rank, o_idx,i_idx, g_idx; - grid->GlobalCoorToRankIndex(rank,o_idx,i_idx,gsite); - grid->GlobalCoorToGlobalIndex(gsite,g_idx); + int rank, o_idx, i_idx, g_idx; + grid->GlobalCoorToRankIndex(rank, o_idx, i_idx, gsite); + grid->GlobalCoorToGlobalIndex(gsite, g_idx); //////////////////////////////// // iorank writes from the seek //////////////////////////////// - + // Owner of data peeks it - peekLocalSite(siteObj,Umu,lsite); + peekLocalSite(siteObj, Umu, lsite); // Pair of nodes may need to do pt2pt send - if ( rank != iorank ) { // comms is necessary - if ( (myrank == rank) || (myrank==iorank) ) { // and we have to do it - // Send to IOrank - grid->SendRecvPacket((void *)&siteObj,(void *)&siteObj,rank,iorank,sizeof(siteObj)); - } + if (rank != iorank) { // comms is necessary + if ((myrank == rank) || (myrank == iorank)) { // and we have to do it + // Send to IOrank + grid->SendRecvPacket((void *)&siteObj, (void *)&siteObj, rank, iorank, + sizeof(siteObj)); + } } - grid->Barrier(); // necessary? + grid->Barrier(); // necessary? if (myrank == iorank) { - - munge(siteObj,fileObj,csum); + munge(siteObj, fileObj, csum); - if(ieee32big) htobe32_v((void *)&fileObj,sizeof(fileObj)); - if(ieee32) htole32_v((void *)&fileObj,sizeof(fileObj)); - if(ieee64big) htobe64_v((void *)&fileObj,sizeof(fileObj)); - if(ieee64) htole64_v((void *)&fileObj,sizeof(fileObj)); - - fout.seekp(offset+g_idx*sizeof(fileObj)); - fout.write((char *)&fileObj,sizeof(fileObj)); - bytes+=sizeof(fileObj); + if (ieee32big) htobe32_v((void *)&fileObj, sizeof(fileObj)); + if (ieee32) htole32_v((void *)&fileObj, sizeof(fileObj)); + if (ieee64big) htobe64_v((void *)&fileObj, sizeof(fileObj)); + if (ieee64) htole64_v((void *)&fileObj, sizeof(fileObj)); + + fout.seekp(offset + g_idx * sizeof(fileObj)); + fout.write((char *)&fileObj, sizeof(fileObj)); + bytes += sizeof(fileObj); } } @@ -673,14 +734,19 @@ class BinaryIO { grid->GlobalSum(bytes); timer.Stop(); - std::cout<Barrier(); // necessary? + if (IOnode) + fout.close(); return csum; } - }; - } #endif diff --git a/lib/qcd/QCD.h b/lib/qcd/QCD.h index f434bdd9..829752c7 100644 --- a/lib/qcd/QCD.h +++ b/lib/qcd/QCD.h @@ -45,7 +45,7 @@ namespace QCD { static const int Zm = 6; static const int Tm = 7; - static const int Nc=3; + static const int Nc=2; static const int Ns=4; static const int Nd=4; static const int Nhs=2; // half spinor diff --git a/lib/qcd/action/gauge/GaugeImpl.h b/lib/qcd/action/gauge/GaugeImpl.h index 5ef9f107..5423dcbb 100644 --- a/lib/qcd/action/gauge/GaugeImpl.h +++ b/lib/qcd/action/gauge/GaugeImpl.h @@ -75,6 +75,8 @@ public: } } + /////////////////////////////////////////////////////////// + // Move these to another class // HMC auxiliary functions static inline void generate_momenta(Field& P, GridParallelRNG& pRNG){ // specific for SU gauge fields @@ -108,6 +110,17 @@ public: return Hsum.real(); } + static inline void HotConfiguration(GridParallelRNG &pRNG, Field &U) { + SU::HotConfiguration(pRNG, U); + } + + static inline void TepidConfiguration(GridParallelRNG &pRNG, Field &U) { + SU::TepidConfiguration(pRNG, U); + } + + static inline void ColdConfiguration(GridParallelRNG &pRNG, Field &U) { + SU::ColdConfiguration(pRNG, U); + } }; // Composition with smeared link, bc's etc.. probably need multiple inheritance diff --git a/lib/qcd/hmc/BinaryCheckpointer.h b/lib/qcd/hmc/BinaryCheckpointer.h index 1e992dec..8c96f85b 100644 --- a/lib/qcd/hmc/BinaryCheckpointer.h +++ b/lib/qcd/hmc/BinaryCheckpointer.h @@ -36,93 +36,36 @@ directory namespace Grid { namespace QCD { -template -struct BinarySimpleUnmunger { - typedef typename getPrecision::real_scalar_type fobj_stype; +// Simple checkpointer, only binary file +template +class BinaryHmcCheckpointer : public HmcObservable { + private: + std::string configStem; + std::string rngStem; + int SaveInterval; + std::string format; + + public: + INHERIT_FIELD_TYPES(Impl); // Gets the Field type, a Lattice object + + // Extract types from the Field + typedef typename Field::vector_object vobj; + typedef typename vobj::scalar_object sobj; typedef typename getPrecision::real_scalar_type sobj_stype; + typedef typename sobj::DoublePrecision sobj_double; - void operator()(sobj &in, fobj &out, uint32_t &csum) { - // take word by word and transform accoding to the status - fobj_stype* out_buffer = (fobj_stype*)&out; - sobj_stype* in_buffer = (sobj_stype*)∈ - size_t fobj_words = sizeof(out)/sizeof(fobj_stype); - size_t sobj_words = sizeof(in)/sizeof(sobj_stype); - assert(fobj_words == sobj_words); + BinaryHmcCheckpointer(std::string cf, std::string rn, int savemodulo, + const std::string &f) + : configStem(cf), rngStem(rn), SaveInterval(savemodulo), format(f){}; - for (unsigned int word = 0; word < sobj_words; word++) - out_buffer[word] = in_buffer[word]; // type conversion on the fly + void truncate(std::string file) { + std::ofstream fout(file, std::ios::out); + fout.close(); + } - BinaryIO::Uint32Checksum((uint32_t*)&out,sizeof(out),csum); - - }; - -template -struct BinarySimpleMunger { - typedef typename getPrecision::real_scalar_type fobj_stype; - typedef typename getPrecision::real_scalar_type sobj_stype; - - void operator()(sobj &out, fobj &in, uint32_t &csum) { - // take word by word and transform accoding to the status - fobj_stype* in_buffer = (fobj_stype*)∈ - sobj_stype* out_buffer = (sobj_stype*)&out; - size_t fobj_words = sizeof(in)/sizeof(fobj_stype); - size_t sobj_words = sizeof(out)/sizeof(sobj_stype); - assert(fobj_words == sobj_words); - - for (unsigned int word = 0; word < sobj_words; word++) - out_buffer[word] = in_buffer[word]; // type conversion on the fly - - BinaryIO::Uint32Checksum((uint32_t*)&in,sizeof(in),csum); - - }; - - - // Only for the main field in the hmc - template - class BinaryHmcCheckpointer : public HmcObservable { - private: - std::string configStem; - std::string rngStem; - int SaveInterval; - - public: - INHERIT_FIELD_TYPES(Impl); // The Field is a Lattice object - - typedef typename Field::vector_object vobj; - typedef typename vobj::scalar_object sobj; - typedef typename getPrecision::real_scalar_type sobj_stype; - typedef typename sobj::DoublePrecision sobj_double; - - BinaryHmcCheckpointer(std::string cf, std::string rn, int savemodulo, const std::string &format) - : configStem(cf), - rngStem(rn), - SaveInterval(savemodulo){}; - - void TrajectoryComplete(int traj, Field &U, GridSerialRNG &sRNG, - GridParallelRNG &pRNG) { - if ((traj % SaveInterval) == 0) { - std::string rng; - { - std::ostringstream os; - os << rngStem << "." << traj; - rng = os.str(); - } - std::string config; - { - std::ostringstream os; - os << configStem << "." << traj; - config = os.str(); - } - - // Save always in double precision - BinarySimpleUnmunger munge; - BinaryIO::writeRNGSerial(sRNG, pRNG, rng, 0); - BinaryIO::writeObjectParallel(U, config, munge, 0, format); - } - }; - - void CheckpointRestore(int traj, Field &U, GridSerialRNG &sRNG, - GridParallelRNG &pRNG) { + void TrajectoryComplete(int traj, Field &U, GridSerialRNG &sRNG, + GridParallelRNG &pRNG) { + if ((traj % SaveInterval) == 0) { std::string rng; { std::ostringstream os; @@ -136,11 +79,42 @@ struct BinarySimpleMunger { config = os.str(); } - BinarySimpleMunger munge; - BinaryIO::readRNGSerial(sRNG, pRNG, rng, header); - BinaryIO::readObjectParallel(U, config, munge, 0, format); - }; + BinaryIO::BinarySimpleUnmunger munge; + truncate(rng); + BinaryIO::writeRNGSerial(sRNG, pRNG, rng, 0); + truncate(config); + uint32_t csum = BinaryIO::writeObjectParallel( + U, config, munge, 0, format); + + std::cout << GridLogMessage << "Written Binary Configuration " << config + << " checksum " << std::hex << csum << std::dec << std::endl; + } }; + + void CheckpointRestore(int traj, Field &U, GridSerialRNG &sRNG, + GridParallelRNG &pRNG) { + std::string rng; + { + std::ostringstream os; + os << rngStem << "." << traj; + rng = os.str(); + } + std::string config; + { + std::ostringstream os; + os << configStem << "." << traj; + config = os.str(); + } + + BinaryIO::BinarySimpleMunger munge; + BinaryIO::readRNGSerial(sRNG, pRNG, rng, 0); + uint32_t csum = BinaryIO::readObjectParallel( + U, config, munge, 0, format); + + std::cout << GridLogMessage << "Read Binary Configuration " << config + << " checksum " << std::hex << csum << std::dec << std::endl; + }; +}; } } #endif diff --git a/lib/qcd/hmc/GenericHMCrunner.h b/lib/qcd/hmc/GenericHMCrunner.h new file mode 100644 index 00000000..299bff37 --- /dev/null +++ b/lib/qcd/hmc/GenericHMCrunner.h @@ -0,0 +1,173 @@ +/************************************************************************************* + +Grid physics library, www.github.com/paboyle/Grid + +Source file: ./lib/qcd/hmc/GenericHmcRunner.h + +Copyright (C) 2015 + +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 */ +#ifndef GENERIC_HMC_RUNNER +#define GENERIC_HMC_RUNNER + +namespace Grid { +namespace QCD { + +// Virtual Class for HMC specific for gauge theories +// implement a specific theory by defining the BuildTheAction +template +class BinaryHmcRunnerTemplate { + public: + INHERIT_FIELD_TYPES(Implementation); + + enum StartType_t { ColdStart, HotStart, TepidStart, CheckpointStart }; + + ActionSet TheAction; + // Add here a vector of HmcObservable + // that can be injected from outside + + GridCartesian *UGrid; + GridCartesian *FGrid; + GridRedBlackCartesian *UrbGrid; + GridRedBlackCartesian *FrbGrid; + + virtual void BuildTheAction(int argc, char **argv) = 0; // necessary? + + void Run(int argc, char **argv) { + StartType_t StartType = HotStart; + + std::string arg; + + if (GridCmdOptionExists(argv, argv + argc, "--StartType")) { + arg = GridCmdOptionPayload(argv, argv + argc, "--StartType"); + if (arg == "HotStart") { + StartType = HotStart; + } else if (arg == "ColdStart") { + StartType = ColdStart; + } else if (arg == "TepidStart") { + StartType = TepidStart; + } else if (arg == "CheckpointStart") { + StartType = CheckpointStart; + } else { + std::cout << GridLogError << "Unrecognized option in --StartType\n"; + std::cout + << GridLogError + << "Valid [HotStart, ColdStart, TepidStart, CheckpointStart]\n"; + assert(0); + } + } + + int StartTraj = 0; + if (GridCmdOptionExists(argv, argv + argc, "--StartTrajectory")) { + arg = GridCmdOptionPayload(argv, argv + argc, "--StartTrajectory"); + std::vector ivec(0); + GridCmdOptionIntVector(arg, ivec); + StartTraj = ivec[0]; + } + + int NumTraj = 1; + if (GridCmdOptionExists(argv, argv + argc, "--Trajectories")) { + arg = GridCmdOptionPayload(argv, argv + argc, "--Trajectories"); + std::vector ivec(0); + GridCmdOptionIntVector(arg, ivec); + NumTraj = ivec[0]; + } + + int NumThermalizations = 10; + if (GridCmdOptionExists(argv, argv + argc, "--Thermalizations")) { + arg = GridCmdOptionPayload(argv, argv + argc, "--Thermalizations"); + std::vector ivec(0); + GridCmdOptionIntVector(arg, ivec); + NumThermalizations = ivec[0]; + } + + GridSerialRNG sRNG; + GridParallelRNG pRNG(UGrid); + Field U(UGrid); + + std::vector SerSeed({1, 2, 3, 4, 5}); + std::vector ParSeed({6, 7, 8, 9, 10}); + + NoSmearing SmearingPolicy; + typedef MinimumNorm2, + RepresentationsPolicy> + IntegratorType; // change here to change the algorithm + IntegratorParameters MDpar(20, 1.0); + IntegratorType MDynamics(UGrid, MDpar, TheAction, SmearingPolicy); + + // Checkpoint strategy + int SaveInterval = 1; + std::string format = std::string("IEEE64BIG"); + std::string conf_prefix = std::string("ckpoint_lat"); + std::string rng_prefix = std::string("ckpoint_rng"); + BinaryHmcCheckpointer Checkpoint(conf_prefix, rng_prefix, + SaveInterval, format); + + HMCparameters HMCpar; + HMCpar.StartTrajectory = StartTraj; + HMCpar.Trajectories = NumTraj; + HMCpar.NoMetropolisUntil = NumThermalizations; + + if (StartType == HotStart) { + // Hot start + HMCpar.MetropolisTest = true; + sRNG.SeedFixedIntegers(SerSeed); + pRNG.SeedFixedIntegers(ParSeed); + Implementation::HotConfiguration(pRNG, U); + } else if (StartType == ColdStart) { + // Cold start + HMCpar.MetropolisTest = true; + sRNG.SeedFixedIntegers(SerSeed); + pRNG.SeedFixedIntegers(ParSeed); + Implementation::ColdConfiguration(pRNG, U); + } else if (StartType == TepidStart) { + // Tepid start + HMCpar.MetropolisTest = true; + sRNG.SeedFixedIntegers(SerSeed); + pRNG.SeedFixedIntegers(ParSeed); + Implementation::TepidConfiguration(pRNG, U); + } else if (StartType == CheckpointStart) { + HMCpar.MetropolisTest = true; + // CheckpointRestart + Checkpoint.CheckpointRestore(StartTraj, U, sRNG, pRNG); + } + + SmearingPolicy.set_Field(U); + + HybridMonteCarlo HMC(HMCpar, MDynamics, sRNG, pRNG, U); + HMC.AddObservable(&Checkpoint); + + // Run it + HMC.evolve(); + } +}; + +typedef BinaryHmcRunnerTemplate BinaryHmcRunner; +typedef BinaryHmcRunnerTemplate BinaryHmcRunnerF; +typedef BinaryHmcRunnerTemplate BinaryHmcRunnerD; + +template +using BinaryHmcRunnerTemplateHirep = + BinaryHmcRunnerTemplate; +} +} +#endif diff --git a/tests/hmc/Make.inc b/tests/hmc/Make.inc index f6f9c6b5..4fa49710 100644 --- a/tests/hmc/Make.inc +++ b/tests/hmc/Make.inc @@ -1,5 +1,5 @@ -tests: Test_hmc_EODWFRatio Test_hmc_EODWFRatio_Gparity Test_hmc_EOWilsonFermionGauge Test_hmc_EOWilsonRatio Test_hmc_GparityIwasakiGauge Test_hmc_GparityWilsonGauge Test_hmc_IwasakiGauge Test_hmc_RectGauge Test_hmc_WilsonAdjointFermionGauge Test_hmc_WilsonFermionGauge Test_hmc_WilsonGauge Test_hmc_WilsonMixedRepresentationsFermionGauge Test_hmc_WilsonRatio Test_hmc_WilsonTwoIndexSymmetricFermionGauge Test_multishift_sqrt Test_remez Test_rhmc_EOWilson1p1 Test_rhmc_EOWilsonRatio Test_rhmc_Wilson1p1 Test_rhmc_WilsonRatio -EXTRA_PROGRAMS = Test_hmc_EODWFRatio Test_hmc_EODWFRatio_Gparity Test_hmc_EOWilsonFermionGauge Test_hmc_EOWilsonRatio Test_hmc_GparityIwasakiGauge Test_hmc_GparityWilsonGauge Test_hmc_IwasakiGauge Test_hmc_RectGauge Test_hmc_WilsonAdjointFermionGauge Test_hmc_WilsonFermionGauge Test_hmc_WilsonGauge Test_hmc_WilsonMixedRepresentationsFermionGauge Test_hmc_WilsonRatio Test_hmc_WilsonTwoIndexSymmetricFermionGauge Test_multishift_sqrt Test_remez Test_rhmc_EOWilson1p1 Test_rhmc_EOWilsonRatio Test_rhmc_Wilson1p1 Test_rhmc_WilsonRatio +tests: Test_hmc_EODWFRatio Test_hmc_EODWFRatio_Gparity Test_hmc_EOWilsonFermionGauge Test_hmc_EOWilsonRatio Test_hmc_GparityIwasakiGauge Test_hmc_GparityWilsonGauge Test_hmc_IwasakiGauge Test_hmc_RectGauge Test_hmc_WilsonAdjointFermionGauge Test_hmc_WilsonFermionGauge_Binary Test_hmc_WilsonFermionGauge Test_hmc_WilsonGauge Test_hmc_WilsonMixedRepresentationsFermionGauge Test_hmc_WilsonRatio Test_hmc_WilsonTwoIndexSymmetricFermionGauge Test_multishift_sqrt Test_remez Test_rhmc_EOWilson1p1 Test_rhmc_EOWilsonRatio Test_rhmc_Wilson1p1 Test_rhmc_WilsonRatio +EXTRA_PROGRAMS = Test_hmc_EODWFRatio Test_hmc_EODWFRatio_Gparity Test_hmc_EOWilsonFermionGauge Test_hmc_EOWilsonRatio Test_hmc_GparityIwasakiGauge Test_hmc_GparityWilsonGauge Test_hmc_IwasakiGauge Test_hmc_RectGauge Test_hmc_WilsonAdjointFermionGauge Test_hmc_WilsonFermionGauge_Binary Test_hmc_WilsonFermionGauge Test_hmc_WilsonGauge Test_hmc_WilsonMixedRepresentationsFermionGauge Test_hmc_WilsonRatio Test_hmc_WilsonTwoIndexSymmetricFermionGauge Test_multishift_sqrt Test_remez Test_rhmc_EOWilson1p1 Test_rhmc_EOWilsonRatio Test_rhmc_Wilson1p1 Test_rhmc_WilsonRatio Test_hmc_EODWFRatio_SOURCES=Test_hmc_EODWFRatio.cc Test_hmc_EODWFRatio_LDADD=-lGrid @@ -28,6 +28,9 @@ Test_hmc_RectGauge_LDADD=-lGrid Test_hmc_WilsonAdjointFermionGauge_SOURCES=Test_hmc_WilsonAdjointFermionGauge.cc Test_hmc_WilsonAdjointFermionGauge_LDADD=-lGrid +Test_hmc_WilsonFermionGauge_Binary_SOURCES=Test_hmc_WilsonFermionGauge_Binary.cc +Test_hmc_WilsonFermionGauge_Binary_LDADD=-lGrid + Test_hmc_WilsonFermionGauge_SOURCES=Test_hmc_WilsonFermionGauge.cc Test_hmc_WilsonFermionGauge_LDADD=-lGrid diff --git a/tests/hmc/Test_hmc_WilsonFermionGauge_Binary.cc b/tests/hmc/Test_hmc_WilsonFermionGauge_Binary.cc new file mode 100644 index 00000000..5161617c --- /dev/null +++ b/tests/hmc/Test_hmc_WilsonFermionGauge_Binary.cc @@ -0,0 +1,99 @@ +/************************************************************************************* + +Grid physics library, www.github.com/paboyle/Grid + +Source file: ./tests/Test_hmc_WilsonFermionGauge.cc + +Copyright (C) 2015 + +Author: Peter Boyle +Author: Peter Boyle +Author: neo +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 + +using namespace std; +using namespace Grid; +using namespace Grid::QCD; + +namespace Grid { +namespace QCD { + +class HmcRunner : public BinaryHmcRunner { + public: + void BuildTheAction(int argc, char **argv) + + { + typedef WilsonImplR ImplPolicy; + typedef WilsonFermionR FermionAction; + typedef typename FermionAction::FermionField FermionField; + + UGrid = SpaceTimeGrid::makeFourDimGrid( + GridDefaultLatt(), GridDefaultSimd(Nd, vComplex::Nsimd()), + GridDefaultMpi()); + UrbGrid = SpaceTimeGrid::makeFourDimRedBlackGrid(UGrid); + + FGrid = UGrid; + FrbGrid = UrbGrid; + + // temporarily need a gauge field + LatticeGaugeField U(UGrid); + + // Gauge action + WilsonGaugeActionR Waction(5.6); + + Real mass = -0.77; + FermionAction FermOp(U, *FGrid, *FrbGrid, mass); + + ConjugateGradient CG(1.0e-8, 10000); + + TwoFlavourPseudoFermionAction Nf2(FermOp, CG, CG); + + // Set smearing (true/false), default: false + Nf2.is_smeared = true; + + // Collect actions + ActionLevel Level1(1); + Level1.push_back(&Nf2); + + ActionLevel Level2(4); + Level2.push_back(&Waction); + + TheAction.push_back(Level1); + TheAction.push_back(Level2); + + Run(argc, argv); + }; +}; +} +} + +int main(int argc, char **argv) { + Grid_init(&argc, &argv); + + int threads = GridThread::GetThreads(); + std::cout << GridLogMessage << "Grid is setup to use " << threads + << " threads" << std::endl; + + HmcRunner TheHMC; + + TheHMC.BuildTheAction(argc, argv); +} From 6eb873dd96b8b4fe3d00191282309148108a5fe8 Mon Sep 17 00:00:00 2001 From: Guido Cossu Date: Fri, 7 Oct 2016 17:28:46 +0100 Subject: [PATCH 007/214] Added scalar action phi^4 Check Norm2 output (Complex type assumption) --- lib/qcd/QCD.h | 3 + lib/qcd/action/ActionBase.h | 16 +--- lib/qcd/action/Actions.h | 12 +++ lib/qcd/action/gauge/GaugeImpl.h | 8 +- lib/qcd/action/scalar/ScalarAction.h | 77 +++++++++++++++ lib/qcd/action/scalar/scalarImpl.h | 56 +++++++++++ lib/qcd/hmc/GenericHMCrunner.h | 23 ++++- lib/qcd/hmc/NerscCheckpointer.h | 7 +- lib/qcd/hmc/integrators/Integrator.h | 5 +- lib/qcd/representations/fundamental.h | 13 +++ lib/qcd/representations/hmc_types.h | 11 ++- lib/qcd/smearing/GaugeConfiguration.h | 19 ++-- lib/qcd/utils/ScalarObjs.h | 96 +++++++++++++++++++ tests/hmc/Make.inc | 7 +- tests/hmc/Test_hmc_ScalarAction.cc | 77 +++++++++++++++ .../hmc/Test_hmc_WilsonFermionGauge_Binary.cc | 9 +- 16 files changed, 401 insertions(+), 38 deletions(-) create mode 100644 lib/qcd/action/scalar/ScalarAction.h create mode 100644 lib/qcd/action/scalar/scalarImpl.h create mode 100644 lib/qcd/utils/ScalarObjs.h create mode 100644 tests/hmc/Test_hmc_ScalarAction.cc diff --git a/lib/qcd/QCD.h b/lib/qcd/QCD.h index 829752c7..fc95490a 100644 --- a/lib/qcd/QCD.h +++ b/lib/qcd/QCD.h @@ -506,6 +506,9 @@ namespace QCD { #include #include +// Scalar field +#include + #include #include diff --git a/lib/qcd/action/ActionBase.h b/lib/qcd/action/ActionBase.h index 56d6b8e0..7911462e 100644 --- a/lib/qcd/action/ActionBase.h +++ b/lib/qcd/action/ActionBase.h @@ -81,13 +81,13 @@ struct ActionLevel { }; */ -template +template struct ActionLevel { public: unsigned int multiplier; // Fundamental repr actions separated because of the smearing - typedef Action* ActPtr; + typedef Action* ActPtr; // construct a tuple of vectors of the actions for the corresponding higher // representation fields @@ -97,9 +97,6 @@ struct ActionLevel { std::vector& actions; - // Temporary conversion between ActionLevel and ActionLevelHirep - //ActionLevelHirep(ActionLevel& AL ):actions(AL.actions), multiplier(AL.multiplier){} - ActionLevel(unsigned int mul = 1) : actions(std::get<0>(actions_hirep)), multiplier(mul) { // initialize the hirep vectors to zero. //apply(this->resize, actions_hirep, 0); //need a working resize @@ -110,10 +107,10 @@ struct ActionLevel { - template < class Field > - void push_back(Action* ptr) { + template < class GenField > + void push_back(Action* ptr) { // insert only in the correct vector - std::get< Index < Field, action_hirep_types>::value >(actions_hirep).push_back(ptr); + std::get< Index < GenField, action_hirep_types>::value >(actions_hirep).push_back(ptr); }; @@ -142,9 +139,6 @@ struct ActionLevel { }; -//template -//using ActionSet = std::vector >; - template using ActionSet = std::vector >; diff --git a/lib/qcd/action/Actions.h b/lib/qcd/action/Actions.h index ba6e577d..e45f2e0c 100644 --- a/lib/qcd/action/Actions.h +++ b/lib/qcd/action/Actions.h @@ -60,6 +60,12 @@ Author: paboyle #include #include +//////////////////////////////////////////// +// Scalar Actions +//////////////////////////////////////////// +#include +#include + namespace Grid { namespace QCD { @@ -90,6 +96,12 @@ typedef SymanzikGaugeAction ConjugateSymanzikGaugeAction typedef SymanzikGaugeAction ConjugateSymanzikGaugeActionF; typedef SymanzikGaugeAction ConjugateSymanzikGaugeActionD; + + typedef ScalarAction ScalarActionR; + typedef ScalarAction ScalarActionF; + typedef ScalarAction ScalarActionD; + + }} //////////////////////////////////////////////////////////////////////////////////////////////////// diff --git a/lib/qcd/action/gauge/GaugeImpl.h b/lib/qcd/action/gauge/GaugeImpl.h index 5423dcbb..08fbfa68 100644 --- a/lib/qcd/action/gauge/GaugeImpl.h +++ b/lib/qcd/action/gauge/GaugeImpl.h @@ -47,6 +47,8 @@ template class WilsonLoops; typedef typename GImpl::SiteLink SiteGaugeLink; #define INHERIT_FIELD_TYPES(Impl) \ + typedef typename Impl::Simd Simd; \ + typedef typename Impl::SiteField SiteField; \ typedef typename Impl::Field Field; // hard codes the exponential approximation in the template @@ -88,7 +90,9 @@ public: } } - + static inline Field projectForce(Field& P){ + return Ta(P); + } static inline void update_field(Field& P, Field& U, double ep){ for (int mu = 0; mu < Nd; mu++) { @@ -117,7 +121,7 @@ public: static inline void TepidConfiguration(GridParallelRNG &pRNG, Field &U) { SU::TepidConfiguration(pRNG, U); } - + static inline void ColdConfiguration(GridParallelRNG &pRNG, Field &U) { SU::ColdConfiguration(pRNG, U); } diff --git a/lib/qcd/action/scalar/ScalarAction.h b/lib/qcd/action/scalar/ScalarAction.h new file mode 100644 index 00000000..048cde8d --- /dev/null +++ b/lib/qcd/action/scalar/ScalarAction.h @@ -0,0 +1,77 @@ +/************************************************************************************* + + Grid physics library, www.github.com/paboyle/Grid + + Source file: ./lib/qcd/action/gauge/WilsonGaugeAction.h + + Copyright (C) 2015 + +Author: Azusa Yamaguchi +Author: Peter Boyle +Author: neo +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 */ +#ifndef SCALAR_ACTION_H +#define SCALAR_ACTION_H + +namespace Grid { +namespace QCD { + +//////////////////////////////////////////////////////////////////////// +// Wilson Gauge Action .. should I template the Nc etc.. +//////////////////////////////////////////////////////////////////////// + +template +class ScalarAction : public Action { + public: + INHERIT_FIELD_TYPES(Impl); + + private: + RealD mass_square; + RealD lambda; + + public: + ScalarAction(RealD ms, RealD l) : mass_square(ms), lambda(l){}; + + virtual void refresh(const Field &U, + GridParallelRNG &pRNG){}; // noop as no pseudoferms + + virtual RealD S(const Field &p) { + return (mass_square * 0.5 + Nd) * ScalarObs::sumphisquared(p) + + (lambda / 24.) * ScalarObs::sumphifourth(p) + + ScalarObs::sumphider(p); + }; + + virtual void deriv(const Field &p, + Field &force) { + Field tmp(p._grid); + Field p2(p._grid); + ScalarObs::phisquared(p2, p); + tmp = -(Cshift(p, 0, -1) + Cshift(p, 0, 1)); + for (int mu = 1; mu < Nd; mu++) tmp -= Cshift(p, mu, -1) + Cshift(p, mu, 1); + + force=+(mass_square + 2. * Nd) * p + (lambda / 6.) * p2 * p + tmp; + }; +}; +} +} + +#endif \ No newline at end of file diff --git a/lib/qcd/action/scalar/scalarImpl.h b/lib/qcd/action/scalar/scalarImpl.h new file mode 100644 index 00000000..f3a7932d --- /dev/null +++ b/lib/qcd/action/scalar/scalarImpl.h @@ -0,0 +1,56 @@ +#ifndef SCALAR_IMPL +#define SCALAR_IMPL + + +namespace Grid { +namespace QCD { + +template +class ScalarImplTypes { + public: + typedef S Simd; + + template + using iImplField = iScalar > >; + + typedef iImplField SiteField; + + + typedef Lattice Field; + + static inline void generate_momenta(Field& P, GridParallelRNG& pRNG){ + gaussian(pRNG, P); + } + + static inline Field projectForce(Field& P){return P;} + + static inline void update_field(Field& P, Field& U, double ep){ + U += P*ep; + } + + static inline RealD FieldSquareNorm(Field& U){ + return (- sum(trace(U*U))/2.0); + } + + static inline void HotConfiguration(GridParallelRNG &pRNG, Field &U) { + gaussian(pRNG, U); + } + + static inline void TepidConfiguration(GridParallelRNG &pRNG, Field &U) { + gaussian(pRNG, U); + } + + static inline void ColdConfiguration(GridParallelRNG &pRNG, Field &U) { + U = 1.0; + } + +}; + + +typedef ScalarImplTypes ScalarImplR; +typedef ScalarImplTypes ScalarImplF; +typedef ScalarImplTypes ScalarImplD; + +}} + +#endif \ No newline at end of file diff --git a/lib/qcd/hmc/GenericHMCrunner.h b/lib/qcd/hmc/GenericHMCrunner.h index 299bff37..a7eb8016 100644 --- a/lib/qcd/hmc/GenericHMCrunner.h +++ b/lib/qcd/hmc/GenericHMCrunner.h @@ -34,16 +34,21 @@ namespace QCD { // Virtual Class for HMC specific for gauge theories // implement a specific theory by defining the BuildTheAction -template +template , + class RepresentationsPolicy = NoHirep> class BinaryHmcRunnerTemplate { public: INHERIT_FIELD_TYPES(Implementation); + typedef Implementation ImplPolicy; enum StartType_t { ColdStart, HotStart, TepidStart, CheckpointStart }; ActionSet TheAction; // Add here a vector of HmcObservable // that can be injected from outside + std::vector< HmcObservable > ObservablesList; + GridCartesian *UGrid; GridCartesian *FGrid; @@ -119,8 +124,7 @@ class BinaryHmcRunnerTemplate { std::string format = std::string("IEEE64BIG"); std::string conf_prefix = std::string("ckpoint_lat"); std::string rng_prefix = std::string("ckpoint_rng"); - BinaryHmcCheckpointer Checkpoint(conf_prefix, rng_prefix, - SaveInterval, format); + IOCheckpointer Checkpoint(conf_prefix, rng_prefix, SaveInterval, format); HMCparameters HMCpar; HMCpar.StartTrajectory = StartTraj; @@ -154,20 +158,31 @@ class BinaryHmcRunnerTemplate { SmearingPolicy.set_Field(U); HybridMonteCarlo HMC(HMCpar, MDynamics, sRNG, pRNG, U); - HMC.AddObservable(&Checkpoint); + //HMC.AddObservable(&Checkpoint); + + for (int obs = 0; obs < ObservablesList.size(); obs++) + HMC.AddObservable(&ObservablesList[obs]); // Run it HMC.evolve(); } }; +// These are for gauge fields typedef BinaryHmcRunnerTemplate BinaryHmcRunner; typedef BinaryHmcRunnerTemplate BinaryHmcRunnerF; typedef BinaryHmcRunnerTemplate BinaryHmcRunnerD; +typedef BinaryHmcRunnerTemplate > NerscTestHmcRunner; + + template using BinaryHmcRunnerTemplateHirep = BinaryHmcRunnerTemplate; + + + +typedef BinaryHmcRunnerTemplate, ScalarFields> ScalarBinaryHmcRunner; } } #endif diff --git a/lib/qcd/hmc/NerscCheckpointer.h b/lib/qcd/hmc/NerscCheckpointer.h index 6701740b..fca4cd47 100644 --- a/lib/qcd/hmc/NerscCheckpointer.h +++ b/lib/qcd/hmc/NerscCheckpointer.h @@ -36,7 +36,7 @@ Author: paboyle namespace Grid{ namespace QCD{ - // Only for gauge fields + // Only for Gauge fields template class NerscHmcCheckpointer : public HmcObservable { private: @@ -44,12 +44,13 @@ namespace Grid{ std::string rngStem; int SaveInterval; public: - INHERIT_GIMPL_TYPES(Gimpl); + INHERIT_GIMPL_TYPES(Gimpl);// - NerscHmcCheckpointer(std::string cf, std::string rn,int savemodulo) { + NerscHmcCheckpointer(std::string cf, std::string rn,int savemodulo, std::string format = "") { configStem = cf; rngStem = rn; SaveInterval= savemodulo; + // format is fixed to IEEE64BIG for NERSC }; void TrajectoryComplete(int traj, GaugeField &U, GridSerialRNG &sRNG, GridParallelRNG & pRNG ) diff --git a/lib/qcd/hmc/integrators/Integrator.h b/lib/qcd/hmc/integrators/Integrator.h index 735863a0..d37d9271 100644 --- a/lib/qcd/hmc/integrators/Integrator.h +++ b/lib/qcd/hmc/integrators/Integrator.h @@ -128,7 +128,7 @@ class Integrator { << "Smearing (on/off): " << as[level].actions.at(a)->is_smeared << std::endl; if (as[level].actions.at(a)->is_smeared) Smearer.smeared_force(force); - force = Ta(force); + force = FieldImplementation::projectForce(force); // Ta for gauge fields std::cout << GridLogIntegrator << "Force average: " << norm2(force) / (U._grid->gSites()) << std::endl; @@ -201,9 +201,10 @@ class Integrator { // Initialization of momenta and actions void refresh(Field& U, GridParallelRNG& pRNG) { + assert(P._grid == U._grid); std::cout << GridLogIntegrator << "Integrator refresh\n"; FieldImplementation::generate_momenta(P, pRNG); - + // Update the smeared fields, can be implemented as observer // necessary to keep the fields updated even after a reject // of the Metropolis diff --git a/lib/qcd/representations/fundamental.h b/lib/qcd/representations/fundamental.h index 7d85d357..db52d893 100644 --- a/lib/qcd/representations/fundamental.h +++ b/lib/qcd/representations/fundamental.h @@ -34,8 +34,21 @@ class FundamentalRep { }; + template + class EmptyRep { + public: + typedef Field LatticeField; + + explicit EmptyRep(GridBase* grid) {} //do nothing + void update_representation(const LatticeField& Uin) {} // do nothing + LatticeField RtoFundamentalProject(const LatticeField& in, Real scale = 1.0) const{}// do nothing + }; + + + typedef FundamentalRep FundamentalRepresentation; + } } diff --git a/lib/qcd/representations/hmc_types.h b/lib/qcd/representations/hmc_types.h index 7ab15e9b..65ba7062 100644 --- a/lib/qcd/representations/hmc_types.h +++ b/lib/qcd/representations/hmc_types.h @@ -4,6 +4,8 @@ #include #include #include +#include + #include #include @@ -39,13 +41,17 @@ class Representations { int size() { return tuple_size; } // update the fields + // fields in the main representation always the first in the list + // get the field type + typedef typename std::tuple_element<0,Representation_Fields>::type LatticeSourceField; + template inline typename std::enable_if<(I == tuple_size), void>::type update( - LatticeGaugeField& U) {} + LatticeSourceField& U) {} template inline typename std::enable_if<(I < tuple_size), void>::type update( - LatticeGaugeField& U) { + LatticeSourceField& U) { std::get(rep).update_representation(U); update(U); } @@ -55,6 +61,7 @@ class Representations { }; typedef Representations NoHirep; +typedef Representations > ScalarFields; // Helper classes to access the elements // Strips the first N parameters from the tuple diff --git a/lib/qcd/smearing/GaugeConfiguration.h b/lib/qcd/smearing/GaugeConfiguration.h index 803f3566..fc045ba2 100644 --- a/lib/qcd/smearing/GaugeConfiguration.h +++ b/lib/qcd/smearing/GaugeConfiguration.h @@ -11,24 +11,23 @@ namespace Grid { namespace QCD { //trivial class for no smearing - template< class Gimpl > + template< class Impl > class NoSmearing { public: - INHERIT_GIMPL_TYPES(Gimpl); + INHERIT_FIELD_TYPES(Impl); - GaugeField* - ThinLinks; + Field* ThinField; - NoSmearing(): ThinLinks(NULL) {} + NoSmearing(): ThinField(NULL) {} - void set_Field(GaugeField& U) { ThinLinks = &U; } + void set_Field(Field& U) { ThinField = &U; } - void smeared_force(GaugeField& SigmaTilde) const {} + void smeared_force(Field&) const {} - GaugeField& get_SmearedU() { return *ThinLinks; } + Field& get_SmearedU() { return *ThinField; } - GaugeField& get_U(bool smeared = false) { - return *ThinLinks; + Field& get_U(bool smeared = false) { + return *ThinField; } }; diff --git a/lib/qcd/utils/ScalarObjs.h b/lib/qcd/utils/ScalarObjs.h new file mode 100644 index 00000000..9915a89b --- /dev/null +++ b/lib/qcd/utils/ScalarObjs.h @@ -0,0 +1,96 @@ +/************************************************************************************* + + Grid physics library, www.github.com/paboyle/Grid + + Source file: ./lib/qcd/utils/WilsonLoops.h + + Copyright (C) 2015 + +Author: Azusa Yamaguchi +Author: Peter Boyle +Author: neo +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 */ +#ifndef SCALAR_OBJS_H +#define SCALAR_OBJS_H +namespace Grid { +namespace QCD { + +// Scalar field obs +template +class ScalarObs { + public: + ////////////////////////////////////////////////// + // squared field + ////////////////////////////////////////////////// + + static void phisquared(typename Impl::Field &fsq, + const typename Impl::Field &f) { + fsq = f * f; + } + ////////////////////////////////////////////////// + // phi^4 interaction term + ////////////////////////////////////////////////// + + static void phifourth(typename Impl::Field &fsq, + const typename Impl::Field &f) { + fsq = f * f * f * f; + } + + ////////////////////////////////////////////////// + // phi(x)phi(x+mu) + ////////////////////////////////////////////////// + + static void phider(typename Impl::Field &fsq, + const typename Impl::Field &f) { + fsq = Cshift(f, 0, -1) * f; + for (int mu = 1; mu < Nd; mu++) fsq += Cshift(f, mu, -1) * f; + } + + ////////////////////////////////////////////////// + // Vol sum of the previous obs. + ////////////////////////////////////////////////// + + static RealD sumphider(const typename Impl::Field &f) { + typename Impl::Field tmp(f._grid); + tmp = Cshift(f, 0, -1) * f; + for (int mu = 1; mu < Nd; mu++) { + tmp += Cshift(f, mu, -1) * f; + } + return -sum(trace(tmp)); + } + + static RealD sumphisquared(const typename Impl::Field &f) { + typename Impl::Field tmp(f._grid); + tmp = f * f; + return sum(trace(tmp)); + } + + static RealD sumphifourth(const typename Impl::Field &f) { + typename Impl::Field tmp(f._grid); + phifourth(tmp, f); + return sum(trace(tmp)); + } +}; +} +} + +#endif \ No newline at end of file diff --git a/tests/hmc/Make.inc b/tests/hmc/Make.inc index 4fa49710..e39fb40b 100644 --- a/tests/hmc/Make.inc +++ b/tests/hmc/Make.inc @@ -1,5 +1,5 @@ -tests: Test_hmc_EODWFRatio Test_hmc_EODWFRatio_Gparity Test_hmc_EOWilsonFermionGauge Test_hmc_EOWilsonRatio Test_hmc_GparityIwasakiGauge Test_hmc_GparityWilsonGauge Test_hmc_IwasakiGauge Test_hmc_RectGauge Test_hmc_WilsonAdjointFermionGauge Test_hmc_WilsonFermionGauge_Binary Test_hmc_WilsonFermionGauge Test_hmc_WilsonGauge Test_hmc_WilsonMixedRepresentationsFermionGauge Test_hmc_WilsonRatio Test_hmc_WilsonTwoIndexSymmetricFermionGauge Test_multishift_sqrt Test_remez Test_rhmc_EOWilson1p1 Test_rhmc_EOWilsonRatio Test_rhmc_Wilson1p1 Test_rhmc_WilsonRatio -EXTRA_PROGRAMS = Test_hmc_EODWFRatio Test_hmc_EODWFRatio_Gparity Test_hmc_EOWilsonFermionGauge Test_hmc_EOWilsonRatio Test_hmc_GparityIwasakiGauge Test_hmc_GparityWilsonGauge Test_hmc_IwasakiGauge Test_hmc_RectGauge Test_hmc_WilsonAdjointFermionGauge Test_hmc_WilsonFermionGauge_Binary Test_hmc_WilsonFermionGauge Test_hmc_WilsonGauge Test_hmc_WilsonMixedRepresentationsFermionGauge Test_hmc_WilsonRatio Test_hmc_WilsonTwoIndexSymmetricFermionGauge Test_multishift_sqrt Test_remez Test_rhmc_EOWilson1p1 Test_rhmc_EOWilsonRatio Test_rhmc_Wilson1p1 Test_rhmc_WilsonRatio +tests: Test_hmc_EODWFRatio Test_hmc_EODWFRatio_Gparity Test_hmc_EOWilsonFermionGauge Test_hmc_EOWilsonRatio Test_hmc_GparityIwasakiGauge Test_hmc_GparityWilsonGauge Test_hmc_IwasakiGauge Test_hmc_RectGauge Test_hmc_ScalarAction Test_hmc_WilsonAdjointFermionGauge Test_hmc_WilsonFermionGauge_Binary Test_hmc_WilsonFermionGauge Test_hmc_WilsonGauge Test_hmc_WilsonMixedRepresentationsFermionGauge Test_hmc_WilsonRatio Test_hmc_WilsonTwoIndexSymmetricFermionGauge Test_multishift_sqrt Test_remez Test_rhmc_EOWilson1p1 Test_rhmc_EOWilsonRatio Test_rhmc_Wilson1p1 Test_rhmc_WilsonRatio +EXTRA_PROGRAMS = Test_hmc_EODWFRatio Test_hmc_EODWFRatio_Gparity Test_hmc_EOWilsonFermionGauge Test_hmc_EOWilsonRatio Test_hmc_GparityIwasakiGauge Test_hmc_GparityWilsonGauge Test_hmc_IwasakiGauge Test_hmc_RectGauge Test_hmc_ScalarAction Test_hmc_WilsonAdjointFermionGauge Test_hmc_WilsonFermionGauge_Binary Test_hmc_WilsonFermionGauge Test_hmc_WilsonGauge Test_hmc_WilsonMixedRepresentationsFermionGauge Test_hmc_WilsonRatio Test_hmc_WilsonTwoIndexSymmetricFermionGauge Test_multishift_sqrt Test_remez Test_rhmc_EOWilson1p1 Test_rhmc_EOWilsonRatio Test_rhmc_Wilson1p1 Test_rhmc_WilsonRatio Test_hmc_EODWFRatio_SOURCES=Test_hmc_EODWFRatio.cc Test_hmc_EODWFRatio_LDADD=-lGrid @@ -25,6 +25,9 @@ Test_hmc_IwasakiGauge_LDADD=-lGrid Test_hmc_RectGauge_SOURCES=Test_hmc_RectGauge.cc Test_hmc_RectGauge_LDADD=-lGrid +Test_hmc_ScalarAction_SOURCES=Test_hmc_ScalarAction.cc +Test_hmc_ScalarAction_LDADD=-lGrid + Test_hmc_WilsonAdjointFermionGauge_SOURCES=Test_hmc_WilsonAdjointFermionGauge.cc Test_hmc_WilsonAdjointFermionGauge_LDADD=-lGrid diff --git a/tests/hmc/Test_hmc_ScalarAction.cc b/tests/hmc/Test_hmc_ScalarAction.cc new file mode 100644 index 00000000..e0798c2b --- /dev/null +++ b/tests/hmc/Test_hmc_ScalarAction.cc @@ -0,0 +1,77 @@ +/************************************************************************************* + +Grid physics library, www.github.com/paboyle/Grid + +Source file: ./tests/Test_hmc_WilsonFermionGauge.cc + +Copyright (C) 2015 + +Author: Peter Boyle +Author: Peter Boyle +Author: neo +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 + +using namespace std; +using namespace Grid; +using namespace Grid::QCD; + +namespace Grid { +namespace QCD { + +// Derive from the BinaryHmcRunner (templated for gauge fields) +class HmcRunner : public ScalarBinaryHmcRunner { + public: + void BuildTheAction(int argc, char **argv) + + { + UGrid = SpaceTimeGrid::makeFourDimGrid( + GridDefaultLatt(), GridDefaultSimd(Nd, vComplex::Nsimd()), + GridDefaultMpi()); + UrbGrid = SpaceTimeGrid::makeFourDimRedBlackGrid(UGrid); + + // Scalar action + ScalarActionR Saction(0.11,0.); + + // Collect actions + ActionLevel Level1(1); + Level1.push_back(&Saction); + + TheAction.push_back(Level1); + + + Run(argc, argv); + }; +}; +} +} + +int main(int argc, char **argv) { + Grid_init(&argc, &argv); + + int threads = GridThread::GetThreads(); + std::cout << GridLogMessage << "Grid is setup to use " << threads + << " threads" << std::endl; + + HmcRunner TheHMC; + + TheHMC.BuildTheAction(argc, argv); +} diff --git a/tests/hmc/Test_hmc_WilsonFermionGauge_Binary.cc b/tests/hmc/Test_hmc_WilsonFermionGauge_Binary.cc index 5161617c..8d8543f2 100644 --- a/tests/hmc/Test_hmc_WilsonFermionGauge_Binary.cc +++ b/tests/hmc/Test_hmc_WilsonFermionGauge_Binary.cc @@ -37,6 +37,7 @@ using namespace Grid::QCD; namespace Grid { namespace QCD { +// Derive from the BinaryHmcRunner (templated for gauge fields) class HmcRunner : public BinaryHmcRunner { public: void BuildTheAction(int argc, char **argv) @@ -71,15 +72,19 @@ class HmcRunner : public BinaryHmcRunner { Nf2.is_smeared = true; // Collect actions - ActionLevel Level1(1); + ActionLevel Level1(1); Level1.push_back(&Nf2); - ActionLevel Level2(4); + ActionLevel Level2(4); Level2.push_back(&Waction); TheAction.push_back(Level1); TheAction.push_back(Level2); + // Add observables + //PlaquetteLogger PlaqLog(std::string("plaq")); + //ObservablesList.push_back(PlaqLog); + Run(argc, argv); }; }; From 26b9740d533aa3de155cfe0219af6f39a5867348 Mon Sep 17 00:00:00 2001 From: Guido Cossu Date: Mon, 10 Oct 2016 09:43:05 +0100 Subject: [PATCH 008/214] Some fix for the GenericHMCrunner --- lib/lattice/Lattice_reduction.h | 107 +++++++++--------- lib/qcd/hmc/GenericHMCrunner.h | 9 +- tests/core/Test_main.cc | 13 +++ tests/hmc/Test_hmc_ScalarAction.cc | 7 +- .../hmc/Test_hmc_WilsonFermionGauge_Binary.cc | 4 +- 5 files changed, 80 insertions(+), 60 deletions(-) diff --git a/lib/lattice/Lattice_reduction.h b/lib/lattice/Lattice_reduction.h index 2615af48..488229f5 100644 --- a/lib/lattice/Lattice_reduction.h +++ b/lib/lattice/Lattice_reduction.h @@ -38,51 +38,56 @@ namespace Grid { //////////////////////////////////////////////////////////////////////////////////////////////////// // Deterministic Reduction operations //////////////////////////////////////////////////////////////////////////////////////////////////// - template inline RealD norm2(const Lattice &arg){ - ComplexD nrm = innerProduct(arg,arg); - return std::real(nrm); +template +inline RealD norm2(const Lattice &arg) { + ComplexD nrm = innerProduct(arg, arg); + return std::real(nrm); +} + +template +inline ComplexD innerProduct(const Lattice &left, + const Lattice &right) { + typedef typename vobj::scalar_type scalar_type; + typedef typename vobj::vector_type vector_type; + scalar_type nrm; + + GridBase *grid = left._grid; + + std::vector > sumarray( + grid->SumArraySize()); + for (int i = 0; i < grid->SumArraySize(); i++) { + sumarray[i] = zero; } - template - inline ComplexD innerProduct(const Lattice &left,const Lattice &right) - { - typedef typename vobj::scalar_type scalar_type; - typedef typename vobj::vector_type vector_type; - scalar_type nrm; + PARALLEL_FOR_LOOP + for (int thr = 0; thr < grid->SumArraySize(); thr++) { + int nwork, mywork, myoff; + GridThread::GetWork(left._grid->oSites(), thr, mywork, myoff); - GridBase *grid = left._grid; - - std::vector > sumarray(grid->SumArraySize()); - for(int i=0;iSumArraySize();i++){ - sumarray[i]=zero; - } - -PARALLEL_FOR_LOOP - for(int thr=0;thrSumArraySize();thr++){ - int nwork, mywork, myoff; - GridThread::GetWork(left._grid->oSites(),thr,mywork,myoff); - - decltype(innerProduct(left._odata[0],right._odata[0])) vnrm=zero; // private to thread; sub summation - for(int ss=myoff;ssSumArraySize();i++){ - vvnrm = vvnrm+sumarray[i]; - } - nrm = Reduce(vvnrm);// sum across simd - right._grid->GlobalSum(nrm); - return nrm; + decltype(innerProduct(left._odata[0], right._odata[0])) vnrm = + zero; // private to thread; sub summation + for (int ss = myoff; ss < mywork + myoff; ss++) { + vnrm = vnrm + innerProduct(left._odata[ss], right._odata[ss]); } + sumarray[thr] = TensorRemove(vnrm); + } + - template - inline auto sum(const LatticeUnaryExpression & expr) - ->typename decltype(expr.first.func(eval(0,std::get<0>(expr.second))))::scalar_object - { - return sum(closure(expr)); + vector_type vvnrm; + vvnrm = zero; // sum across threads + for (int i = 0; i < grid->SumArraySize(); i++) { + vvnrm = vvnrm + sumarray[i]; + } + nrm = Reduce(vvnrm); // sum across simd + right._grid->GlobalSum(nrm); + return nrm; +} + +template +inline auto sum(const LatticeUnaryExpression &expr) -> + typename decltype( + expr.first.func(eval(0, std::get<0>(expr.second))))::scalar_object { + return sum(closure(expr)); } template @@ -96,9 +101,9 @@ PARALLEL_FOR_LOOP template inline auto sum(const LatticeTrinaryExpression & expr) ->typename decltype(expr.first.func(eval(0,std::get<0>(expr.second)), - eval(0,std::get<1>(expr.second)), - eval(0,std::get<2>(expr.second)) - ))::scalar_object + eval(0,std::get<1>(expr.second)), + eval(0,std::get<2>(expr.second)) + ))::scalar_object { return sum(closure(expr)); } @@ -111,24 +116,24 @@ PARALLEL_FOR_LOOP std::vector > sumarray(grid->SumArraySize()); for(int i=0;iSumArraySize();i++){ - sumarray[i]=zero; + sumarray[i]=zero; } PARALLEL_FOR_LOOP for(int thr=0;thrSumArraySize();thr++){ - int nwork, mywork, myoff; - GridThread::GetWork(grid->oSites(),thr,mywork,myoff); + int nwork, mywork, myoff; + GridThread::GetWork(grid->oSites(),thr,mywork,myoff); - vobj vvsum=zero; + vobj vvsum=zero; for(int ss=myoff;ssSumArraySize();i++){ - vsum = vsum+sumarray[i]; + vsum = vsum+sumarray[i]; } typedef typename vobj::scalar_object sobj; diff --git a/lib/qcd/hmc/GenericHMCrunner.h b/lib/qcd/hmc/GenericHMCrunner.h index a7eb8016..5df3f393 100644 --- a/lib/qcd/hmc/GenericHMCrunner.h +++ b/lib/qcd/hmc/GenericHMCrunner.h @@ -47,7 +47,7 @@ class BinaryHmcRunnerTemplate { ActionSet TheAction; // Add here a vector of HmcObservable // that can be injected from outside - std::vector< HmcObservable > ObservablesList; + std::vector< HmcObservable* > ObservablesList; GridCartesian *UGrid; @@ -119,12 +119,13 @@ class BinaryHmcRunnerTemplate { IntegratorParameters MDpar(20, 1.0); IntegratorType MDynamics(UGrid, MDpar, TheAction, SmearingPolicy); - // Checkpoint strategy + // Checkpoint strategy int SaveInterval = 1; std::string format = std::string("IEEE64BIG"); std::string conf_prefix = std::string("ckpoint_lat"); std::string rng_prefix = std::string("ckpoint_rng"); IOCheckpointer Checkpoint(conf_prefix, rng_prefix, SaveInterval, format); + HMCparameters HMCpar; HMCpar.StartTrajectory = StartTraj; @@ -158,10 +159,10 @@ class BinaryHmcRunnerTemplate { SmearingPolicy.set_Field(U); HybridMonteCarlo HMC(HMCpar, MDynamics, sRNG, pRNG, U); - //HMC.AddObservable(&Checkpoint); + HMC.AddObservable(&Checkpoint); for (int obs = 0; obs < ObservablesList.size(); obs++) - HMC.AddObservable(&ObservablesList[obs]); + HMC.AddObservable(ObservablesList[obs]); // Run it HMC.evolve(); diff --git a/tests/core/Test_main.cc b/tests/core/Test_main.cc index 78c28539..7bef5d4e 100644 --- a/tests/core/Test_main.cc +++ b/tests/core/Test_main.cc @@ -143,6 +143,7 @@ int main(int argc, char **argv) { random(FineRNG, Foo); gaussian(FineRNG, Bar); + random(FineRNG, scFoo); random(FineRNG, scBar); @@ -169,6 +170,18 @@ int main(int argc, char **argv) { abort(); } + // Norm2 check + LatticeReal BarReal(&Fine); + LatticeComplex BarComplex(&Fine); + BarReal = 1.0; + BarComplex = 1.0; + + + std::cout << "Norm2 LatticeReal : "<< norm2(BarReal) << std::endl; + std::cout << "Norm2 LatticeComplex : "<< norm2(BarComplex) << std::endl; + + exit(0); + TComplex tr = trace(cmat); cVec = cMat * cVec; // LatticeColourVector = LatticeColourMatrix diff --git a/tests/hmc/Test_hmc_ScalarAction.cc b/tests/hmc/Test_hmc_ScalarAction.cc index e0798c2b..8565d001 100644 --- a/tests/hmc/Test_hmc_ScalarAction.cc +++ b/tests/hmc/Test_hmc_ScalarAction.cc @@ -43,12 +43,13 @@ class HmcRunner : public ScalarBinaryHmcRunner { void BuildTheAction(int argc, char **argv) { + // Notice that the Grid is for reals now UGrid = SpaceTimeGrid::makeFourDimGrid( - GridDefaultLatt(), GridDefaultSimd(Nd, vComplex::Nsimd()), + GridDefaultLatt(), GridDefaultSimd(Nd, vReal::Nsimd()), GridDefaultMpi()); UrbGrid = SpaceTimeGrid::makeFourDimRedBlackGrid(UGrid); - // Scalar action + // Real Scalar action ScalarActionR Saction(0.11,0.); // Collect actions @@ -59,7 +60,7 @@ class HmcRunner : public ScalarBinaryHmcRunner { Run(argc, argv); - }; + }; }; } } diff --git a/tests/hmc/Test_hmc_WilsonFermionGauge_Binary.cc b/tests/hmc/Test_hmc_WilsonFermionGauge_Binary.cc index 8d8543f2..e0227b14 100644 --- a/tests/hmc/Test_hmc_WilsonFermionGauge_Binary.cc +++ b/tests/hmc/Test_hmc_WilsonFermionGauge_Binary.cc @@ -82,8 +82,8 @@ class HmcRunner : public BinaryHmcRunner { TheAction.push_back(Level2); // Add observables - //PlaquetteLogger PlaqLog(std::string("plaq")); - //ObservablesList.push_back(PlaqLog); + PlaquetteLogger PlaqLog(std::string("plaq")); + ObservablesList.push_back(&PlaqLog); Run(argc, argv); }; From 65f61bb3bfa6e4457b653296d7607aa9176d3882 Mon Sep 17 00:00:00 2001 From: Guido Cossu Date: Mon, 10 Oct 2016 09:46:17 +0100 Subject: [PATCH 009/214] Reset QCD colours to 3 --- lib/qcd/QCD.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/qcd/QCD.h b/lib/qcd/QCD.h index fc95490a..74107a3e 100644 --- a/lib/qcd/QCD.h +++ b/lib/qcd/QCD.h @@ -45,7 +45,7 @@ namespace QCD { static const int Zm = 6; static const int Tm = 7; - static const int Nc=2; + static const int Nc=3; static const int Ns=4; static const int Nd=4; static const int Nhs=2; // half spinor From 293df6cd20b36f3bbacb190593a9b2228e07b064 Mon Sep 17 00:00:00 2001 From: Guido Cossu Date: Mon, 10 Oct 2016 11:49:55 +0100 Subject: [PATCH 010/214] Generalising the HMCRunner and moving parameters to the user level --- lib/qcd/hmc/GenericHMCrunner.h | 20 ++++---- tests/hmc/Test_hmc_ScalarAction.cc | 10 +++- .../hmc/Test_hmc_WilsonFermionGauge_Binary.cc | 46 ++++++++++++++++--- 3 files changed, 61 insertions(+), 15 deletions(-) diff --git a/lib/qcd/hmc/GenericHMCrunner.h b/lib/qcd/hmc/GenericHMCrunner.h index 5df3f393..8500cfb4 100644 --- a/lib/qcd/hmc/GenericHMCrunner.h +++ b/lib/qcd/hmc/GenericHMCrunner.h @@ -35,7 +35,6 @@ namespace QCD { // Virtual Class for HMC specific for gauge theories // implement a specific theory by defining the BuildTheAction template , class RepresentationsPolicy = NoHirep> class BinaryHmcRunnerTemplate { public: @@ -45,7 +44,8 @@ class BinaryHmcRunnerTemplate { enum StartType_t { ColdStart, HotStart, TepidStart, CheckpointStart }; ActionSet TheAction; - // Add here a vector of HmcObservable + + // A vector of HmcObservable // that can be injected from outside std::vector< HmcObservable* > ObservablesList; @@ -57,7 +57,9 @@ class BinaryHmcRunnerTemplate { virtual void BuildTheAction(int argc, char **argv) = 0; // necessary? - void Run(int argc, char **argv) { +// add here the smearing implementation? +template > + void Run(int argc, char **argv, IOCheckpointer &Checkpoint) { StartType_t StartType = HotStart; std::string arg; @@ -119,13 +121,14 @@ class BinaryHmcRunnerTemplate { IntegratorParameters MDpar(20, 1.0); IntegratorType MDynamics(UGrid, MDpar, TheAction, SmearingPolicy); - // Checkpoint strategy + // Checkpoint strategy + /* int SaveInterval = 1; std::string format = std::string("IEEE64BIG"); std::string conf_prefix = std::string("ckpoint_lat"); std::string rng_prefix = std::string("ckpoint_rng"); IOCheckpointer Checkpoint(conf_prefix, rng_prefix, SaveInterval, format); - + */ HMCparameters HMCpar; HMCpar.StartTrajectory = StartTraj; @@ -159,7 +162,7 @@ class BinaryHmcRunnerTemplate { SmearingPolicy.set_Field(U); HybridMonteCarlo HMC(HMCpar, MDynamics, sRNG, pRNG, U); - HMC.AddObservable(&Checkpoint); + //HMC.AddObservable(&Checkpoint); for (int obs = 0; obs < ObservablesList.size(); obs++) HMC.AddObservable(ObservablesList[obs]); @@ -174,7 +177,7 @@ typedef BinaryHmcRunnerTemplate BinaryHmcRunner; typedef BinaryHmcRunnerTemplate BinaryHmcRunnerF; typedef BinaryHmcRunnerTemplate BinaryHmcRunnerD; -typedef BinaryHmcRunnerTemplate > NerscTestHmcRunner; +//typedef BinaryHmcRunnerTemplate > NerscTestHmcRunner; template @@ -183,7 +186,8 @@ using BinaryHmcRunnerTemplateHirep = -typedef BinaryHmcRunnerTemplate, ScalarFields> ScalarBinaryHmcRunner; +//typedef BinaryHmcRunnerTemplate, ScalarFields> ScalarBinaryHmcRunner; + typedef BinaryHmcRunnerTemplate ScalarBinaryHmcRunner; } } #endif diff --git a/tests/hmc/Test_hmc_ScalarAction.cc b/tests/hmc/Test_hmc_ScalarAction.cc index 8565d001..8a2ff036 100644 --- a/tests/hmc/Test_hmc_ScalarAction.cc +++ b/tests/hmc/Test_hmc_ScalarAction.cc @@ -59,7 +59,15 @@ class HmcRunner : public ScalarBinaryHmcRunner { TheAction.push_back(Level1); - Run(argc, argv); + // Add observables and checkpointers + int SaveInterval = 1; + std::string format = std::string("IEEE64BIG"); + std::string conf_prefix = std::string("ckpoint_scalar_lat"); + std::string rng_prefix = std::string("ckpoint_scalar_rng"); + BinaryHmcCheckpointer Checkpoint(conf_prefix, rng_prefix, SaveInterval, format); + ObservablesList.push_back(&Checkpoint); + + Run(argc, argv, Checkpoint); }; }; } diff --git a/tests/hmc/Test_hmc_WilsonFermionGauge_Binary.cc b/tests/hmc/Test_hmc_WilsonFermionGauge_Binary.cc index e0227b14..3e76c015 100644 --- a/tests/hmc/Test_hmc_WilsonFermionGauge_Binary.cc +++ b/tests/hmc/Test_hmc_WilsonFermionGauge_Binary.cc @@ -7,9 +7,8 @@ Source file: ./tests/Test_hmc_WilsonFermionGauge.cc Copyright (C) 2015 Author: Peter Boyle -Author: Peter Boyle Author: neo -Author: paboyle +Author: Guido Cossu 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 @@ -25,7 +24,8 @@ 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 +See the full license in the file "LICENSE" in the top level distribution +directory *************************************************************************************/ /* END LEGAL */ #include @@ -37,6 +37,23 @@ using namespace Grid::QCD; namespace Grid { namespace QCD { +class HMCRunnerParameters : Serializable { + public: + GRID_SERIALIZABLE_CLASS_MEMBERS(HMCRunnerParameters, + double, beta, + double, mass, + int, MaxCGIterations, + double, StoppingCondition, + bool, smearedAction, + int, SaveInterval, + std::string, format, + std::string, conf_prefix, + std::string, rng_prefix, + ); + + HMCRunnerParameters() {} +}; + // Derive from the BinaryHmcRunner (templated for gauge fields) class HmcRunner : public BinaryHmcRunner { public: @@ -62,6 +79,9 @@ class HmcRunner : public BinaryHmcRunner { WilsonGaugeActionR Waction(5.6); Real mass = -0.77; + + // Can we define an overloaded operator that does not need U and initialises + // it with zeroes? FermionAction FermOp(U, *FGrid, *FrbGrid, mass); ConjugateGradient CG(1.0e-8, 10000); @@ -82,10 +102,24 @@ class HmcRunner : public BinaryHmcRunner { TheAction.push_back(Level2); // Add observables - PlaquetteLogger PlaqLog(std::string("plaq")); - ObservablesList.push_back(&PlaqLog); + int SaveInterval = 2; + std::string format = std::string("IEEE64BIG"); + std::string conf_prefix = std::string("ckpoint_lat"); + std::string rng_prefix = std::string("ckpoint_rng"); + BinaryHmcCheckpointer Checkpoint( + conf_prefix, rng_prefix, SaveInterval, format); + // Can implement also a specific function in the hmcrunner + // AddCheckpoint (...) that takes the same parameters + a string/tag + // defining the type of the checkpointer + // with tags can be implemented by overloading and no ifs + // Then force all checkpoint to have few common functions + // return an object that is then passed to the Run function - Run(argc, argv); + PlaquetteLogger PlaqLog(std::string("Plaquette")); + ObservablesList.push_back(&PlaqLog); + ObservablesList.push_back(&Checkpoint); + + Run(argc, argv, Checkpoint); }; }; } From c68a2b9637995072670d4eb667406669b3b7baf1 Mon Sep 17 00:00:00 2001 From: Guido Cossu Date: Mon, 10 Oct 2016 11:54:58 +0100 Subject: [PATCH 011/214] Minor fix --- lib/qcd/hmc/integrators/Integrator.h | 3 +-- tests/hmc/Test_hmc_WilsonFermionGauge_Binary.cc | 2 +- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/lib/qcd/hmc/integrators/Integrator.h b/lib/qcd/hmc/integrators/Integrator.h index d37d9271..29c1912d 100644 --- a/lib/qcd/hmc/integrators/Integrator.h +++ b/lib/qcd/hmc/integrators/Integrator.h @@ -8,8 +8,7 @@ Copyright (C) 2015 Author: Azusa Yamaguchi Author: Peter Boyle -Author: neo -Author: paboyle +Author: Guido Cossu 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 diff --git a/tests/hmc/Test_hmc_WilsonFermionGauge_Binary.cc b/tests/hmc/Test_hmc_WilsonFermionGauge_Binary.cc index 3e76c015..6a5b6f52 100644 --- a/tests/hmc/Test_hmc_WilsonFermionGauge_Binary.cc +++ b/tests/hmc/Test_hmc_WilsonFermionGauge_Binary.cc @@ -102,7 +102,7 @@ class HmcRunner : public BinaryHmcRunner { TheAction.push_back(Level2); // Add observables - int SaveInterval = 2; + int SaveInterval = 1; std::string format = std::string("IEEE64BIG"); std::string conf_prefix = std::string("ckpoint_lat"); std::string rng_prefix = std::string("ckpoint_rng"); From eda4dd622e6470af3ee260a2d8568f8a2f40e985 Mon Sep 17 00:00:00 2001 From: Guido Cossu Date: Tue, 11 Oct 2016 15:45:20 +0100 Subject: [PATCH 012/214] Some more edit --- lib/parallelIO/BinaryIO.h | 2 +- lib/qcd/QCD.h | 87 +++++++++++++++++++++++++++++----- lib/qcd/hmc/GenericHMCrunner.h | 11 +---- lib/tensors/Tensor_outer.h | 3 ++ 4 files changed, 82 insertions(+), 21 deletions(-) diff --git a/lib/parallelIO/BinaryIO.h b/lib/parallelIO/BinaryIO.h index f9a8ae3c..3265ba54 100644 --- a/lib/parallelIO/BinaryIO.h +++ b/lib/parallelIO/BinaryIO.h @@ -505,7 +505,7 @@ class BinaryIO { // available (how short sighted is that?) ////////////////////////////////////////////////////////// Umu = zero; - static uint32_t csum=0; + static uint32_t csum; csum=0;//static for SHMEM fobj fileObj; static sobj siteObj; // Static to place in symmetric region for SHMEM diff --git a/lib/qcd/QCD.h b/lib/qcd/QCD.h index 74107a3e..61313f33 100644 --- a/lib/qcd/QCD.h +++ b/lib/qcd/QCD.h @@ -33,6 +33,71 @@ Author: paboyle #define GRID_QCD_H namespace Grid{ +// First steps in the complete generalization of the Physics part +namespace LatticeTheories { + +template +struct LatticeTheory { + static const int Nd = Dimensions; + static const int Nds = Dimensions * 2; // double stored field + template + using iSinglet = iScalar > >; +}; + +template +struct LatticeGaugeTheory : public LatticeTheory { + static const int Nds = Dimensions * 2; + static const int Nd = Dimensions; + static const int Nc = Colours; + + template + using iColourMatrix = iScalar > >; + template + using iLorentzColourMatrix = iVector >, Nd>; + template + using iDoubleStoredColourMatrix = iVector >, Nds>; + template + using iColourVector = iScalar > >; +}; + +template +struct FermionicLatticeGaugeTheory + : public LatticeGaugeTheory { + static const int Nd = Dimensions; + static const int Nds = Dimensions * 2; + static const int Nc = Colours; + static const int Ns = Spin; + + template + using iSpinMatrix = iScalar, Ns> >; + template + using iSpinColourMatrix = iScalar, Ns> >; + template + using iSpinVector = iScalar, Ns> >; + template + using iSpinColourVector = iScalar, Ns> >; + // These 2 only is Spin is a multiple of 2 + static const int Nhs = Spin / 2; + template + using iHalfSpinVector = iScalar, Nhs> >; + template + using iHalfSpinColourVector = iScalar, Nhs> >; +}; + +struct QCD : public FermionicLatticeGaugeTheory<4, 3, 4> { + typedef FermionicLatticeGaugeTheory FLGT; + typedef FLGT::iSpinMatrix SpinMatrix; + typedef FLGT::iSpinMatrix SpinMatrixF; + typedef FLGT::iSpinMatrix SpinMatrixD; + +}; +struct QED : public FermionicLatticeGaugeTheory<4, 1, 4> {}; + +template +struct Scalar : public LatticeTheory {}; + +} // LatticeTheories + namespace QCD { @@ -355,36 +420,36 @@ namespace QCD { ////////////////////////////////////////////// template void pokeColour(Lattice &lhs, - const Lattice(lhs._odata[0],0))> & rhs, - int i) + const Lattice(lhs._odata[0],0))> & rhs, + int i) { PokeIndex(lhs,rhs,i); } template void pokeColour(Lattice &lhs, - const Lattice(lhs._odata[0],0,0))> & rhs, - int i,int j) + const Lattice(lhs._odata[0],0,0))> & rhs, + int i,int j) { PokeIndex(lhs,rhs,i,j); } template void pokeSpin(Lattice &lhs, - const Lattice(lhs._odata[0],0))> & rhs, - int i) + const Lattice(lhs._odata[0],0))> & rhs, + int i) { PokeIndex(lhs,rhs,i); } template void pokeSpin(Lattice &lhs, - const Lattice(lhs._odata[0],0,0))> & rhs, - int i,int j) + const Lattice(lhs._odata[0],0,0))> & rhs, + int i,int j) { PokeIndex(lhs,rhs,i,j); } template void pokeLorentz(Lattice &lhs, - const Lattice(lhs._odata[0],0))> & rhs, - int i) + const Lattice(lhs._odata[0],0))> & rhs, + int i) { PokeIndex(lhs,rhs,i); } @@ -500,7 +565,7 @@ namespace QCD { #include #include -// Include representations +// Include representations #include #include #include diff --git a/lib/qcd/hmc/GenericHMCrunner.h b/lib/qcd/hmc/GenericHMCrunner.h index 8500cfb4..d627c47b 100644 --- a/lib/qcd/hmc/GenericHMCrunner.h +++ b/lib/qcd/hmc/GenericHMCrunner.h @@ -111,9 +111,11 @@ template > GridParallelRNG pRNG(UGrid); Field U(UGrid); + // This outside std::vector SerSeed({1, 2, 3, 4, 5}); std::vector ParSeed({6, 7, 8, 9, 10}); + // these decisions outside NoSmearing SmearingPolicy; typedef MinimumNorm2, RepresentationsPolicy> @@ -121,15 +123,6 @@ template > IntegratorParameters MDpar(20, 1.0); IntegratorType MDynamics(UGrid, MDpar, TheAction, SmearingPolicy); - // Checkpoint strategy - /* - int SaveInterval = 1; - std::string format = std::string("IEEE64BIG"); - std::string conf_prefix = std::string("ckpoint_lat"); - std::string rng_prefix = std::string("ckpoint_rng"); - IOCheckpointer Checkpoint(conf_prefix, rng_prefix, SaveInterval, format); - */ - HMCparameters HMCpar; HMCpar.StartTrajectory = StartTraj; HMCpar.Trajectories = NumTraj; diff --git a/lib/tensors/Tensor_outer.h b/lib/tensors/Tensor_outer.h index 896fb8ed..6429a190 100644 --- a/lib/tensors/Tensor_outer.h +++ b/lib/tensors/Tensor_outer.h @@ -44,6 +44,8 @@ auto outerProduct (const iVector& lhs,const iVector& rhs) -> iMatrix inline auto outerProduct (const iScalar& lhs,const iScalar& rhs) -> iScalar { @@ -53,6 +55,7 @@ auto outerProduct (const iScalar& lhs,const iScalar& rhs) -> iScalar Date: Thu, 13 Oct 2016 11:51:25 +0100 Subject: [PATCH 013/214] Adding gh-pages --- .gitignore | 6 +++++- gh-pages | 1 + 2 files changed, 6 insertions(+), 1 deletion(-) create mode 120000 gh-pages diff --git a/.gitignore b/.gitignore index e82ecf9c..384f49d9 100644 --- a/.gitignore +++ b/.gitignore @@ -101,4 +101,8 @@ lib/fftw/* # libtool macros # ################## m4/lt* -m4/libtool.m4 \ No newline at end of file +m4/libtool.m4 + +# github pages # +################ +gh-pages/ \ No newline at end of file diff --git a/gh-pages b/gh-pages new file mode 120000 index 00000000..0f895714 --- /dev/null +++ b/gh-pages @@ -0,0 +1 @@ +../Grid_gh-pages/Grid/ \ No newline at end of file From e250e6b7bbd82abf196952f966235e6bbf17130e Mon Sep 17 00:00:00 2001 From: Guido Cossu Date: Fri, 14 Oct 2016 17:22:32 +0100 Subject: [PATCH 014/214] Moving parameters outside of the HMCrunner --- lib/qcd/hmc/GenericHMCrunner.h | 57 +++++++++++-------- lib/qcd/hmc/integrators/Integrator.h | 17 +++--- lib/qcd/smearing/APEsmearing.h | 8 +-- .../hmc/Test_hmc_WilsonFermionGauge_Binary.cc | 23 +++++++- 4 files changed, 68 insertions(+), 37 deletions(-) diff --git a/lib/qcd/hmc/GenericHMCrunner.h b/lib/qcd/hmc/GenericHMCrunner.h index d627c47b..bad3b9cf 100644 --- a/lib/qcd/hmc/GenericHMCrunner.h +++ b/lib/qcd/hmc/GenericHMCrunner.h @@ -7,6 +7,7 @@ Source file: ./lib/qcd/hmc/GenericHmcRunner.h Copyright (C) 2015 Author: paboyle +Author: Guido Cossu 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 @@ -49,17 +50,39 @@ class BinaryHmcRunnerTemplate { // that can be injected from outside std::vector< HmcObservable* > ObservablesList; + IntegratorParameters MDparameters; GridCartesian *UGrid; GridCartesian *FGrid; GridRedBlackCartesian *UrbGrid; GridRedBlackCartesian *FrbGrid; + std::vector SerialSeed; + std::vector ParallelSeed; + + void RNGSeeds(std::vector S, std::vector P){ + SerialSeed = S; + ParallelSeed = P; + } + virtual void BuildTheAction(int argc, char **argv) = 0; // necessary? -// add here the smearing implementation? -template > + // A couple of wrapper classes + template void Run(int argc, char **argv, IOCheckpointer &Checkpoint) { + NoSmearing S; + Runner(argc, argv, Checkpoint, S); + } + + template + void Run(int argc, char **argv, IOCheckpointer &CP, SmearingPolicy &S) { + Runner(argc, argv, CP, S); + } + ////////////////////////////// + + template + void Runner(int argc, char **argv, IOCheckpointer &Checkpoint, + SmearingPolicy &Smearing) { StartType_t StartType = HotStart; std::string arg; @@ -111,17 +134,10 @@ template > GridParallelRNG pRNG(UGrid); Field U(UGrid); - // This outside - std::vector SerSeed({1, 2, 3, 4, 5}); - std::vector ParSeed({6, 7, 8, 9, 10}); - - // these decisions outside - NoSmearing SmearingPolicy; - typedef MinimumNorm2, + typedef MinimumNorm2 IntegratorType; // change here to change the algorithm - IntegratorParameters MDpar(20, 1.0); - IntegratorType MDynamics(UGrid, MDpar, TheAction, SmearingPolicy); + IntegratorType MDynamics(UGrid, MDparameters, TheAction, Smearing); HMCparameters HMCpar; HMCpar.StartTrajectory = StartTraj; @@ -131,20 +147,20 @@ template > if (StartType == HotStart) { // Hot start HMCpar.MetropolisTest = true; - sRNG.SeedFixedIntegers(SerSeed); - pRNG.SeedFixedIntegers(ParSeed); + sRNG.SeedFixedIntegers(SerialSeed); + pRNG.SeedFixedIntegers(ParallelSeed); Implementation::HotConfiguration(pRNG, U); } else if (StartType == ColdStart) { // Cold start HMCpar.MetropolisTest = true; - sRNG.SeedFixedIntegers(SerSeed); - pRNG.SeedFixedIntegers(ParSeed); + sRNG.SeedFixedIntegers(SerialSeed); + pRNG.SeedFixedIntegers(ParallelSeed); Implementation::ColdConfiguration(pRNG, U); } else if (StartType == TepidStart) { // Tepid start HMCpar.MetropolisTest = true; - sRNG.SeedFixedIntegers(SerSeed); - pRNG.SeedFixedIntegers(ParSeed); + sRNG.SeedFixedIntegers(SerialSeed); + pRNG.SeedFixedIntegers(ParallelSeed); Implementation::TepidConfiguration(pRNG, U); } else if (StartType == CheckpointStart) { HMCpar.MetropolisTest = true; @@ -152,10 +168,9 @@ template > Checkpoint.CheckpointRestore(StartTraj, U, sRNG, pRNG); } - SmearingPolicy.set_Field(U); + Smearing.set_Field(U); HybridMonteCarlo HMC(HMCpar, MDynamics, sRNG, pRNG, U); - //HMC.AddObservable(&Checkpoint); for (int obs = 0; obs < ObservablesList.size(); obs++) HMC.AddObservable(ObservablesList[obs]); @@ -170,16 +185,12 @@ typedef BinaryHmcRunnerTemplate BinaryHmcRunner; typedef BinaryHmcRunnerTemplate BinaryHmcRunnerF; typedef BinaryHmcRunnerTemplate BinaryHmcRunnerD; -//typedef BinaryHmcRunnerTemplate > NerscTestHmcRunner; - - template using BinaryHmcRunnerTemplateHirep = BinaryHmcRunnerTemplate; -//typedef BinaryHmcRunnerTemplate, ScalarFields> ScalarBinaryHmcRunner; typedef BinaryHmcRunnerTemplate ScalarBinaryHmcRunner; } } diff --git a/lib/qcd/hmc/integrators/Integrator.h b/lib/qcd/hmc/integrators/Integrator.h index 29c1912d..43974f48 100644 --- a/lib/qcd/hmc/integrators/Integrator.h +++ b/lib/qcd/hmc/integrators/Integrator.h @@ -46,27 +46,28 @@ namespace Grid { namespace QCD { struct IntegratorParameters { - unsigned int - Nexp; // number of terms in the Taylor expansion of the exponential unsigned int MDsteps; // number of outer steps RealD trajL; // trajectory length RealD stepsize; // trajectory stepsize - IntegratorParameters(int MDsteps_, RealD trajL_ = 1.0, - unsigned int Nexp_ = 12) - : Nexp(Nexp_), - MDsteps(MDsteps_), + IntegratorParameters(int MDsteps_ = 10, RealD trajL_ = 1.0) + : MDsteps(MDsteps_), trajL(trajL_), stepsize(trajL / MDsteps){ // empty body constructor }; + void set(int MDsteps_, RealD trajL_){ + MDsteps = MDsteps_; + trajL = trajL_; + stepsize = trajL/MDsteps; + } + + void print_parameters() { std::cout << GridLogMessage << "[Integrator] Trajectory length : " << trajL << std::endl; std::cout << GridLogMessage << "[Integrator] Number of MD steps : " << MDsteps << std::endl; std::cout << GridLogMessage << "[Integrator] Step size : " << stepsize << std::endl; - std::cout << GridLogMessage << "[Integrator] Exponential approx.: " << Nexp << std::endl; - } }; diff --git a/lib/qcd/smearing/APEsmearing.h b/lib/qcd/smearing/APEsmearing.h index 4db11338..467bf2c6 100644 --- a/lib/qcd/smearing/APEsmearing.h +++ b/lib/qcd/smearing/APEsmearing.h @@ -92,19 +92,19 @@ temp_Sigma = -rho_numu*staple*iLambda_nu; //ok //-r_numu*U_nu(x+mu)*Udag_mu(x+nu)*Udag_nu(x)*Lambda_nu(x) - Gimpl::AddGaugeLink(SigmaTerm, temp_Sigma, mu); + Gimpl::AddLink(SigmaTerm, temp_Sigma, mu); sh_field = Cshift(iLambda_nu, mu, 1);// general also for Gparity? temp_Sigma = rho_numu*sh_field*staple; //ok //r_numu*Lambda_nu(mu)*U_nu(x+mu)*Udag_mu(x+nu)*Udag_nu(x) - Gimpl::AddGaugeLink(SigmaTerm, temp_Sigma, mu); + Gimpl::AddLink(SigmaTerm, temp_Sigma, mu); sh_field = Cshift(iLambda_mu, nu, 1); temp_Sigma = -rho_munu*staple*U_nu*sh_field*adj(U_nu); //ok //-r_munu*U_nu(x+mu)*Udag_mu(x+nu)*Lambda_mu(x+nu)*Udag_nu(x) - Gimpl::AddGaugeLink(SigmaTerm, temp_Sigma, mu); + Gimpl::AddLink(SigmaTerm, temp_Sigma, mu); staple = zero; sh_field = Cshift(U_nu, mu, 1); @@ -116,7 +116,7 @@ sh_field = Cshift(u_tmp, mu, 1); temp_Sigma += -rho_numu*sh_field*adj(U_mu)*U_nu; sh_field = Cshift(temp_Sigma, nu, -1); - Gimpl::AddGaugeLink(SigmaTerm, sh_field, mu); + Gimpl::AddLink(SigmaTerm, sh_field, mu); } } diff --git a/tests/hmc/Test_hmc_WilsonFermionGauge_Binary.cc b/tests/hmc/Test_hmc_WilsonFermionGauge_Binary.cc index 6a5b6f52..9024b4e2 100644 --- a/tests/hmc/Test_hmc_WilsonFermionGauge_Binary.cc +++ b/tests/hmc/Test_hmc_WilsonFermionGauge_Binary.cc @@ -49,6 +49,8 @@ class HMCRunnerParameters : Serializable { std::string, format, std::string, conf_prefix, std::string, rng_prefix, + double, rho, + int, SmearingLevels, ); HMCRunnerParameters() {} @@ -115,11 +117,21 @@ class HmcRunner : public BinaryHmcRunner { // Then force all checkpoint to have few common functions // return an object that is then passed to the Run function - PlaquetteLogger PlaqLog(std::string("Plaquette")); + PlaquetteLogger PlaqLog( + std::string("Plaquette")); ObservablesList.push_back(&PlaqLog); ObservablesList.push_back(&Checkpoint); - Run(argc, argv, Checkpoint); + // Smearing section, omit if not needed + double rho = 0.1; // smearing parameter + int Nsmear = 2; // number of smearing levels + Smear_Stout Stout(rho); + SmearedConfiguration SmearingPolicy( + UGrid, Nsmear, Stout); + /////////////////// + + // Run(argc, argv, Checkpoint, SmearingPolicy); + Run(argc, argv, Checkpoint); // no smearing }; }; } @@ -134,5 +146,12 @@ int main(int argc, char **argv) { HmcRunner TheHMC; + // Seeds for the random number generators + std::vector SerSeed({1, 2, 3, 4, 5}); + std::vector ParSeed({6, 7, 8, 9, 10}); + TheHMC.RNGSeeds(SerSeed, ParSeed); + + TheHMC.MDparameters.set(20, 1.0);// MDsteps, traj length + TheHMC.BuildTheAction(argc, argv); } From 79270ef510d3d090ac0a3775d28528f23906f845 Mon Sep 17 00:00:00 2001 From: Guido Cossu Date: Fri, 14 Oct 2016 17:34:26 +0100 Subject: [PATCH 015/214] Added a test for EODWF Scaled Shamir with general HMC --- tests/hmc/Make.inc | 7 +- tests/hmc/Test_hmc_EODWFRatio_Binary.cc | 158 ++++++++++++++++++++++++ 2 files changed, 163 insertions(+), 2 deletions(-) create mode 100644 tests/hmc/Test_hmc_EODWFRatio_Binary.cc diff --git a/tests/hmc/Make.inc b/tests/hmc/Make.inc index e39fb40b..b37d797e 100644 --- a/tests/hmc/Make.inc +++ b/tests/hmc/Make.inc @@ -1,5 +1,8 @@ -tests: Test_hmc_EODWFRatio Test_hmc_EODWFRatio_Gparity Test_hmc_EOWilsonFermionGauge Test_hmc_EOWilsonRatio Test_hmc_GparityIwasakiGauge Test_hmc_GparityWilsonGauge Test_hmc_IwasakiGauge Test_hmc_RectGauge Test_hmc_ScalarAction Test_hmc_WilsonAdjointFermionGauge Test_hmc_WilsonFermionGauge_Binary Test_hmc_WilsonFermionGauge Test_hmc_WilsonGauge Test_hmc_WilsonMixedRepresentationsFermionGauge Test_hmc_WilsonRatio Test_hmc_WilsonTwoIndexSymmetricFermionGauge Test_multishift_sqrt Test_remez Test_rhmc_EOWilson1p1 Test_rhmc_EOWilsonRatio Test_rhmc_Wilson1p1 Test_rhmc_WilsonRatio -EXTRA_PROGRAMS = Test_hmc_EODWFRatio Test_hmc_EODWFRatio_Gparity Test_hmc_EOWilsonFermionGauge Test_hmc_EOWilsonRatio Test_hmc_GparityIwasakiGauge Test_hmc_GparityWilsonGauge Test_hmc_IwasakiGauge Test_hmc_RectGauge Test_hmc_ScalarAction Test_hmc_WilsonAdjointFermionGauge Test_hmc_WilsonFermionGauge_Binary Test_hmc_WilsonFermionGauge Test_hmc_WilsonGauge Test_hmc_WilsonMixedRepresentationsFermionGauge Test_hmc_WilsonRatio Test_hmc_WilsonTwoIndexSymmetricFermionGauge Test_multishift_sqrt Test_remez Test_rhmc_EOWilson1p1 Test_rhmc_EOWilsonRatio Test_rhmc_Wilson1p1 Test_rhmc_WilsonRatio +tests: Test_hmc_EODWFRatio_Binary Test_hmc_EODWFRatio Test_hmc_EODWFRatio_Gparity Test_hmc_EOWilsonFermionGauge Test_hmc_EOWilsonRatio Test_hmc_GparityIwasakiGauge Test_hmc_GparityWilsonGauge Test_hmc_IwasakiGauge Test_hmc_RectGauge Test_hmc_ScalarAction Test_hmc_WilsonAdjointFermionGauge Test_hmc_WilsonFermionGauge_Binary Test_hmc_WilsonFermionGauge Test_hmc_WilsonGauge Test_hmc_WilsonMixedRepresentationsFermionGauge Test_hmc_WilsonRatio Test_hmc_WilsonTwoIndexSymmetricFermionGauge Test_multishift_sqrt Test_remez Test_rhmc_EOWilson1p1 Test_rhmc_EOWilsonRatio Test_rhmc_Wilson1p1 Test_rhmc_WilsonRatio +EXTRA_PROGRAMS = Test_hmc_EODWFRatio_Binary Test_hmc_EODWFRatio Test_hmc_EODWFRatio_Gparity Test_hmc_EOWilsonFermionGauge Test_hmc_EOWilsonRatio Test_hmc_GparityIwasakiGauge Test_hmc_GparityWilsonGauge Test_hmc_IwasakiGauge Test_hmc_RectGauge Test_hmc_ScalarAction Test_hmc_WilsonAdjointFermionGauge Test_hmc_WilsonFermionGauge_Binary Test_hmc_WilsonFermionGauge Test_hmc_WilsonGauge Test_hmc_WilsonMixedRepresentationsFermionGauge Test_hmc_WilsonRatio Test_hmc_WilsonTwoIndexSymmetricFermionGauge Test_multishift_sqrt Test_remez Test_rhmc_EOWilson1p1 Test_rhmc_EOWilsonRatio Test_rhmc_Wilson1p1 Test_rhmc_WilsonRatio + +Test_hmc_EODWFRatio_Binary_SOURCES=Test_hmc_EODWFRatio_Binary.cc +Test_hmc_EODWFRatio_Binary_LDADD=-lGrid Test_hmc_EODWFRatio_SOURCES=Test_hmc_EODWFRatio.cc Test_hmc_EODWFRatio_LDADD=-lGrid diff --git a/tests/hmc/Test_hmc_EODWFRatio_Binary.cc b/tests/hmc/Test_hmc_EODWFRatio_Binary.cc new file mode 100644 index 00000000..cd35968a --- /dev/null +++ b/tests/hmc/Test_hmc_EODWFRatio_Binary.cc @@ -0,0 +1,158 @@ +/************************************************************************************* + +Grid physics library, www.github.com/paboyle/Grid + +Source file: ./tests/Test_hmc_WilsonFermionGauge.cc + +Copyright (C) 2015 + +Author: Peter Boyle +Author: neo +Author: Guido Cossu + +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 + +using namespace std; +using namespace Grid; +using namespace Grid::QCD; + +namespace Grid { +namespace QCD { + +class HMCRunnerParameters : Serializable { + public: + GRID_SERIALIZABLE_CLASS_MEMBERS(HMCRunnerParameters, + double, beta, + double, mass, + int, MaxCGIterations, + double, StoppingCondition, + bool, smearedAction, + int, SaveInterval, + std::string, format, + std::string, conf_prefix, + std::string, rng_prefix, + double, rho, + int, SmearingLevels, + ); + + HMCRunnerParameters() {} +}; + +// Derive from the BinaryHmcRunner (templated for gauge fields) +class HmcRunner : public BinaryHmcRunner { + public: + void BuildTheAction(int argc, char **argv) + + { + typedef WilsonImplR ImplPolicy; + typedef ScaledShamirFermionR FermionAction; + typedef typename FermionAction::FermionField FermionField; + + const int Ls = 12; + + UGrid = SpaceTimeGrid::makeFourDimGrid(GridDefaultLatt(), GridDefaultSimd(Nd,vComplex::Nsimd()),GridDefaultMpi()); + UrbGrid = SpaceTimeGrid::makeFourDimRedBlackGrid(UGrid); + + FGrid = SpaceTimeGrid::makeFiveDimGrid(Ls,UGrid); + FrbGrid = SpaceTimeGrid::makeFiveDimRedBlackGrid(Ls,UGrid); + + // temporarily need a gauge field + LatticeGaugeField U(UGrid); + + // Gauge action + IwasakiGaugeActionR Iaction(4.0); + + Real mass = 0.04; + Real pv = 1.0; + RealD M5 = 1.5; + RealD scale = 2.0; + FermionAction DenOp(U,*FGrid,*FrbGrid,*UGrid,*UrbGrid,mass,M5,scale); + FermionAction NumOp(U,*FGrid,*FrbGrid,*UGrid,*UrbGrid,pv,M5,scale); + + ConjugateGradient CG(1.0e-8,10000); + TwoFlavourEvenOddRatioPseudoFermionAction Nf2(NumOp, DenOp,CG,CG); + + // Set smearing (true/false), default: false + Nf2.is_smeared = true; + + // Collect actions + // here an example of 2 level integration + ActionLevel Level1(1); + Level1.push_back(&Nf2); + + ActionLevel Level2(4); + Level2.push_back(&Iaction); + + TheAction.push_back(Level1); + TheAction.push_back(Level2); + + // Add observables + int SaveInterval = 1; + std::string format = std::string("IEEE64BIG"); + std::string conf_prefix = std::string("DWF_ckpoint_lat"); + std::string rng_prefix = std::string("DWF_ckpoint_rng"); + BinaryHmcCheckpointer Checkpoint( + conf_prefix, rng_prefix, SaveInterval, format); + // Can implement also a specific function in the hmcrunner + // AddCheckpoint (...) that takes the same parameters + a string/tag + // defining the type of the checkpointer + // with tags can be implemented by overloading and no ifs + // Then force all checkpoint to have few common functions + // return an object that is then passed to the Run function + + PlaquetteLogger PlaqLog( + std::string("Plaquette")); + ObservablesList.push_back(&PlaqLog); + ObservablesList.push_back(&Checkpoint); + + // Smearing section, omit if not needed + double rho = 0.1; // smearing parameter + int Nsmear = 2; // number of smearing levels + Smear_Stout Stout(rho); + SmearedConfiguration SmearingPolicy( + UGrid, Nsmear, Stout); + /////////////////// + + Run(argc, argv, Checkpoint, SmearingPolicy); + //Run(argc, argv, Checkpoint); // no smearing + }; +}; +} +} + +int main(int argc, char **argv) { + Grid_init(&argc, &argv); + + int threads = GridThread::GetThreads(); + std::cout << GridLogMessage << "Grid is setup to use " << threads + << " threads" << std::endl; + + HmcRunner TheHMC; + + // Seeds for the random number generators + std::vector SerSeed({1, 2, 3, 4, 5}); + std::vector ParSeed({6, 7, 8, 9, 10}); + TheHMC.RNGSeeds(SerSeed, ParSeed); + + TheHMC.MDparameters.set(20, 1.0);// MDsteps, traj length + + TheHMC.BuildTheAction(argc, argv); +} From 74f1ed3bc5a051255793c9e0f2c7bff6e2c85db1 Mon Sep 17 00:00:00 2001 From: Guido Cossu Date: Wed, 19 Oct 2016 10:51:13 +0100 Subject: [PATCH 016/214] Adding some documentation for HMC --- lib/qcd/action/Actions.h | 4 + lib/qcd/action/gauge/WilsonGaugeAction.h | 290 ++++++++++++++++++----- lib/qcd/hmc/UsingHMC.md | 107 +++++++++ lib/qcd/utils/WilsonLoops.h | 47 +++- tests/hmc/Make.inc | 7 +- tests/hmc/Test_hmc_EODWFRatio_Binary.cc | 10 +- tests/hmc/Test_hmc_WilsonGauge_Binary.cc | 136 +++++++++++ 7 files changed, 531 insertions(+), 70 deletions(-) create mode 100644 lib/qcd/hmc/UsingHMC.md create mode 100644 tests/hmc/Test_hmc_WilsonGauge_Binary.cc diff --git a/lib/qcd/action/Actions.h b/lib/qcd/action/Actions.h index e45f2e0c..ef2edc97 100644 --- a/lib/qcd/action/Actions.h +++ b/lib/qcd/action/Actions.h @@ -72,6 +72,10 @@ namespace QCD { typedef WilsonGaugeAction WilsonGaugeActionR; typedef WilsonGaugeAction WilsonGaugeActionF; typedef WilsonGaugeAction WilsonGaugeActionD; +typedef VariableWilsonGaugeAction VariableWilsonGaugeActionR; +typedef VariableWilsonGaugeAction VariableWilsonGaugeActionF; +typedef VariableWilsonGaugeAction VariableWilsonGaugeActionD; + typedef PlaqPlusRectangleAction PlaqPlusRectangleActionR; typedef PlaqPlusRectangleAction PlaqPlusRectangleActionF; typedef PlaqPlusRectangleAction PlaqPlusRectangleActionD; diff --git a/lib/qcd/action/gauge/WilsonGaugeAction.h b/lib/qcd/action/gauge/WilsonGaugeAction.h index aff67c67..686c5470 100644 --- a/lib/qcd/action/gauge/WilsonGaugeAction.h +++ b/lib/qcd/action/gauge/WilsonGaugeAction.h @@ -1,86 +1,260 @@ - /************************************************************************************* +/************************************************************************************* - Grid physics library, www.github.com/paboyle/Grid +Grid physics library, www.github.com/paboyle/Grid - Source file: ./lib/qcd/action/gauge/WilsonGaugeAction.h +Source file: ./lib/qcd/action/gauge/WilsonGaugeAction.h - Copyright (C) 2015 +Copyright (C) 2015 Author: Azusa Yamaguchi Author: Peter Boyle Author: neo 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 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. +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. +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 */ +See the full license in the file "LICENSE" in the top level distribution +directory +*************************************************************************************/ +/* END LEGAL */ #ifndef QCD_WILSON_GAUGE_ACTION_H #define QCD_WILSON_GAUGE_ACTION_H -namespace Grid{ - namespace QCD{ - - //////////////////////////////////////////////////////////////////////// - // Wilson Gauge Action .. should I template the Nc etc.. - //////////////////////////////////////////////////////////////////////// - template - class WilsonGaugeAction : public Action { - public: +namespace Grid { +namespace QCD { - INHERIT_GIMPL_TYPES(Gimpl); +//////////////////////////////////////////////////////////////////////// +// Wilson Gauge Action .. should I template the Nc etc.. +//////////////////////////////////////////////////////////////////////// +template +class WilsonGaugeAction : public Action { + public: + INHERIT_GIMPL_TYPES(Gimpl); - // typedef LorentzScalar GaugeLinkField; + // typedef LorentzScalar GaugeLinkField; - private: - RealD beta; - public: - WilsonGaugeAction(RealD b):beta(b){}; + private: + RealD beta; + + public: + WilsonGaugeAction(RealD b) : beta(b){}; + + virtual void refresh(const GaugeField &U, + GridParallelRNG &pRNG){}; // noop as no pseudoferms + + virtual RealD S(const GaugeField &U) { + RealD plaq = WilsonLoops::avgPlaquette(U); + RealD vol = U._grid->gSites(); + RealD action = beta * (1.0 - plaq) * (Nd * (Nd - 1.0)) * vol * 0.5; + return action; + }; + + virtual void deriv(const GaugeField &U, GaugeField &dSdU) { + // not optimal implementation FIXME + // extend Ta to include Lorentz indexes + + // RealD factor = 0.5*beta/RealD(Nc); + RealD factor = 0.5 * beta / RealD(Nc); + + GaugeLinkField Umu(U._grid); + GaugeLinkField dSdU_mu(U._grid); + for (int mu = 0; mu < Nd; mu++) { + Umu = PeekIndex(U, mu); + + // Staple in direction mu + WilsonLoops::Staple(dSdU_mu, U, mu); + dSdU_mu = Ta(Umu * dSdU_mu) * factor; - virtual void refresh(const GaugeField &U, GridParallelRNG& pRNG) {}; // noop as no pseudoferms - - virtual RealD S(const GaugeField &U) { - RealD plaq = WilsonLoops::avgPlaquette(U); - RealD vol = U._grid->gSites(); - RealD action=beta*(1.0 -plaq)*(Nd*(Nd-1.0))*vol*0.5; - return action; - }; + PokeIndex(dSdU, dSdU_mu, mu); + } + }; +}; - virtual void deriv(const GaugeField &U,GaugeField & dSdU) { - //not optimal implementation FIXME - //extend Ta to include Lorentz indexes +template +class VariableWilsonGaugeAction : public Action { + public: + INHERIT_GIMPL_TYPES(Gimpl); - //RealD factor = 0.5*beta/RealD(Nc); - RealD factor = 0.5*beta/RealD(Nc); + private: + std::vector b_bulk;// bulk couplings + std::vector b_xdim;//extra dimension couplings + GridBase *grid; + LatticeComplex beta_xdim; + LatticeComplex beta_xdim_shifted; + LatticeComplex beta_bulk; - GaugeLinkField Umu(U._grid); - GaugeLinkField dSdU_mu(U._grid); - for (int mu=0; mu < Nd; mu++){ + public: + VariableWilsonGaugeAction(std::vector bulk, std::vector xdim, + GridBase *_grid) + : b_bulk(bulk), + b_xdim(xdim), + grid(_grid), + beta_xdim(grid), + beta_xdim_shifted(grid), + beta_bulk(grid) + { + //check that the grid is ok + //todo + int Ndim = Nd;//change later - Umu = PeekIndex(U,mu); + LatticeComplex temp(grid); - // Staple in direction mu - WilsonLoops::Staple(dSdU_mu,U,mu); - dSdU_mu = Ta(Umu*dSdU_mu)*factor; - PokeIndex(dSdU, dSdU_mu, mu); - } - }; - }; - + Lattice > coor(grid); + + LatticeCoordinate(coor, Ndim - 1); + + int Nex = grid->_fdimensions[Ndim - 1]; + assert(b_bulk.size() == Nex); + assert(b_xdim.size() == Nex); + + beta_xdim = zero; + for (int tau = 0; tau < Nex; tau++) { + temp = b_xdim[tau]; + beta_xdim = where(coor == tau, temp, beta_xdim); + } + + beta_xdim_shifted = Cshift(beta_xdim, Ndim - 1, -1); + + beta_bulk = zero; + for (int tau = 0; tau < Nex; tau++) { + temp = b_bulk[tau]; + beta_bulk = where(coor == tau, temp, beta_bulk); + } + }; + + virtual void refresh(const GaugeField &U, + GridParallelRNG &pRNG){}; // noop as no pseudoferms + + virtual RealD S(const GaugeField &Umu) { + int Ndim = Nd; // change later for generality + conformable(grid, Umu._grid); + + std::vector U(Ndim, grid); + + for (int mu = 0; mu < Ndim; mu++) { + U[mu] = PeekIndex(Umu, mu); + } + + LatticeComplex dirPlaq(grid); + LatticeComplex Plaq(grid); + + RealD OneOnNc = 1.0 / Real(Nc); + + ///////////// + // Lower dim plaquettes + ///////////// + Plaq = zero; + for (int mu = 1; mu < Ndim - 1; mu++) { + for (int nu = 0; nu < mu; nu++) { + WilsonLoops::traceDirPlaquette(dirPlaq, U, mu, nu); + Plaq = Plaq + (1.0 - dirPlaq * OneOnNc) * beta_bulk; + } + } + + ///////////// + // Extra dimension + ///////////// + { + int mu = Ndim - 1; + for (int nu = 0; nu < mu; nu++) { + WilsonLoops::traceDirPlaquette(dirPlaq, U, mu, nu); + Plaq = Plaq + (1.0 - dirPlaq * OneOnNc) * beta_xdim; + } + } + + TComplex Tp = sum(Plaq); + Complex p = TensorRemove(Tp); + RealD action = p.real(); + return action; + }; + + virtual void deriv(const GaugeField &U, GaugeField &dSdU) { + // not optimal implementation FIXME + // extend Ta to include Lorentz indexes + + // for the higher dimension plaquettes take the upper plaq of the + // 4d slice and multiply by beta[s] and the lower and multiply by beta[s-1] + // todo + // derivative of links mu = 0, ... Nd-1 inside plaq (mu,5) + // for these I need upper and lower staples separated + // each multiplied with their own beta + // derivative of links mu = 5 + // living on the same slice, share the same beta + + +conformable(grid,U._grid); +int Ndim = Nd; // change later +RealD factor = 0.5 / RealD(Nc); + +GaugeLinkField Umu(grid); +GaugeLinkField dSdU_mu(grid); +GaugeLinkField staple(grid); + +for (int mu = 0; mu < Ndim; mu++) { + Umu = PeekIndex(U, mu); + dSdU_mu = zero; + + for (int nu = 0; nu < Ndim; nu++) { + if (nu != mu) { + if ((mu < (Ndim - 1)) && (nu < (Ndim - 1))) { + // Spacelike case apply beta space + WilsonLoops::Staple(staple, U, mu, nu); + staple = staple * beta_bulk; + dSdU_mu += staple; + + } else if (mu == (Ndim - 1)) { + // nu space; mu time link + assert(nu < (Ndim - 1)); + assert(mu == (Ndim - 1)); + + // mu==tau dir link deriv, nu spatial + WilsonLoops::Staple(staple, U, mu, nu); + staple = staple * beta_xdim; + dSdU_mu += staple; + + } else { + assert(mu < (Ndim - 1)); + assert(nu == (Ndim - 1)); + + // nu time; mu space link + + // staple forwards in tau + WilsonLoops::StapleUpper(staple, U, mu, nu); + staple = staple * beta_xdim; + dSdU_mu += staple; + + // staple backwards in tau + WilsonLoops::StapleLower(staple, U, mu, nu); + staple = staple * beta_xdim_shifted; + dSdU_mu += staple; + } + } } + + dSdU_mu = Ta(Umu * dSdU_mu) * factor; + PokeIndex(dSdU, dSdU_mu, mu); + } + + + + }; +}; + + + +} } #endif diff --git a/lib/qcd/hmc/UsingHMC.md b/lib/qcd/hmc/UsingHMC.md new file mode 100644 index 00000000..da3c3c00 --- /dev/null +++ b/lib/qcd/hmc/UsingHMC.md @@ -0,0 +1,107 @@ +Using HMC in Grid version 0.5.1 + +These are the instructions to use the Generalised HMC on Grid version 0.5.1. +Disclaimer: GRID is still under active development so any information here can be changed in future releases. + + +Command line options +=================== +(relevant file GenericHMCrunner.h) +The initial configuration can be changed at the command line using +--StartType +valid choices, one among these +HotStart, ColdStart, TepidStart, CheckpointStart +default: HotStart + +example +./My_hmc_exec --StartType HotStart + +The CheckpointStart option uses the prefix for the configurations and rng seed files defined in your executable and the initial configuration is specified by +--StartTrajectory +default: 0 + +The number of trajectories for a specific run are specified at command line by +--Trajectories +default: 1 + +The number of thermalization steps (i.e. steps when the Metropolis acceptance check is turned off) is specified by +--Thermalizations +default: 10 + + +Any other parameter is defined in the source for the executable. + +HMC controls +=========== + +The lines + + std::vector SerSeed({1, 2, 3, 4, 5}); + std::vector ParSeed({6, 7, 8, 9, 10}); + +define the seeds for the serial and the parallel RNG. + +The line + + TheHMC.MDparameters.set(20, 1.0);// MDsteps, traj length + +declares the number of molecular dynamics steps and the total trajectory length. + + +Actions +====== + +Action names are defined in the file +lib/qcd/Actions.h + +Gauge actions list: + +WilsonGaugeActionR; +WilsonGaugeActionF; +WilsonGaugeActionD; +PlaqPlusRectangleActionR; +PlaqPlusRectangleActionF; +PlaqPlusRectangleActionD; +IwasakiGaugeActionR; +IwasakiGaugeActionF; +IwasakiGaugeActionD; +SymanzikGaugeActionR; +SymanzikGaugeActionF; +SymanzikGaugeActionD; + + +ConjugateWilsonGaugeActionR; +ConjugateWilsonGaugeActionF; +ConjugateWilsonGaugeActionD; +ConjugatePlaqPlusRectangleActionR; +ConjugatePlaqPlusRectangleActionF; +ConjugatePlaqPlusRectangleActionD; +ConjugateIwasakiGaugeActionR; +ConjugateIwasakiGaugeActionF; +ConjugateIwasakiGaugeActionD; +ConjugateSymanzikGaugeActionR; +ConjugateSymanzikGaugeActionF; +ConjugateSymanzikGaugeActionD; + + +ScalarActionR; +ScalarActionF; +ScalarActionD; + + +each of these action accept one single parameter at creation time (beta). +Example for creating a Symanzik action with beta=4.0 + + SymanzikGaugeActionR(4.0) + +The suffixes R,F,D in the action names refer to the Real +(the precision is defined at compile time by the --enable-precision flag in the configure), +Float and Double, that force the precision of the action to be 32, 64 bit respectively. + + + + + + + + diff --git a/lib/qcd/utils/WilsonLoops.h b/lib/qcd/utils/WilsonLoops.h index 10022f50..3051f830 100644 --- a/lib/qcd/utils/WilsonLoops.h +++ b/lib/qcd/utils/WilsonLoops.h @@ -86,8 +86,7 @@ public: // sum over all x,y,z,t and over all planes of plaquette ////////////////////////////////////////////////// static RealD sumPlaquette(const GaugeLorentz &Umu) { - std::vector U(4, Umu._grid); - + std::vector U(Nd, Umu._grid); for (int mu = 0; mu < Nd; mu++) { U[mu] = PeekIndex(Umu, mu); } @@ -95,11 +94,12 @@ public: LatticeComplex Plaq(Umu._grid); sitePlaquette(Plaq, U); - TComplex Tp = sum(Plaq); Complex p = TensorRemove(Tp); return p.real(); } + + ////////////////////////////////////////////////// // average over all x,y,z,t and over all planes of plaquette ////////////////////////////////////////////////// @@ -114,7 +114,7 @@ public: // average over traced single links ////////////////////////////////////////////////// static RealD linkTrace(const GaugeLorentz &Umu) { - std::vector U(4, Umu._grid); + std::vector U(Nd, Umu._grid); LatticeComplex Tr(Umu._grid); Tr = zero; @@ -139,7 +139,7 @@ public: GridBase *grid = Umu._grid; - std::vector U(4, grid); + std::vector U(Nd, grid); for (int d = 0; d < Nd; d++) { U[d] = PeekIndex(Umu, d); } @@ -233,7 +233,7 @@ public: if (nu != mu) { GridBase *grid = Umu._grid; - std::vector U(4, grid); + std::vector U(Nd, grid); for (int d = 0; d < Nd; d++) { U[d] = PeekIndex(Umu, d); } @@ -256,6 +256,37 @@ public: } } + ////////////////////////////////////////////////// + // the sum over all staples on each site in direction mu,nu, lower part + ////////////////////////////////////////////////// + static void StapleLower(GaugeMat &staple, const GaugeLorentz &Umu, int mu, + int nu) { + staple = zero; + + if (nu != mu) { + GridBase *grid = Umu._grid; + + std::vector U(Nd, grid); + for (int d = 0; d < Nd; d++) { + U[d] = PeekIndex(Umu, d); + } + + // mu + // ^ + // |__> nu + + // __ + // | + // |__ + // + // + staple += Gimpl::ShiftStaple( + Gimpl::CovShiftBackward(U[nu], nu, + Gimpl::CovShiftBackward(U[mu], mu, U[nu])), + mu); + } + } + ////////////////////////////////////////////////////// // Similar to above for rectangle is required ////////////////////////////////////////////////////// @@ -375,8 +406,8 @@ public: // |___ ___| // - // tmp= Staple2x1* Cshift(U[mu],mu,-2); - // Stap+= Cshift(tmp,mu,1) ; + // tmp= Staple2x1* Cshift(U[mu],mu,-2); + // Stap+= Cshift(tmp,mu,1) ; Stap += Cshift(Staple2x1, mu, 1) * Cshift(U[mu], mu, -1); ; diff --git a/tests/hmc/Make.inc b/tests/hmc/Make.inc index b37d797e..f4a3603f 100644 --- a/tests/hmc/Make.inc +++ b/tests/hmc/Make.inc @@ -1,5 +1,5 @@ -tests: Test_hmc_EODWFRatio_Binary Test_hmc_EODWFRatio Test_hmc_EODWFRatio_Gparity Test_hmc_EOWilsonFermionGauge Test_hmc_EOWilsonRatio Test_hmc_GparityIwasakiGauge Test_hmc_GparityWilsonGauge Test_hmc_IwasakiGauge Test_hmc_RectGauge Test_hmc_ScalarAction Test_hmc_WilsonAdjointFermionGauge Test_hmc_WilsonFermionGauge_Binary Test_hmc_WilsonFermionGauge Test_hmc_WilsonGauge Test_hmc_WilsonMixedRepresentationsFermionGauge Test_hmc_WilsonRatio Test_hmc_WilsonTwoIndexSymmetricFermionGauge Test_multishift_sqrt Test_remez Test_rhmc_EOWilson1p1 Test_rhmc_EOWilsonRatio Test_rhmc_Wilson1p1 Test_rhmc_WilsonRatio -EXTRA_PROGRAMS = Test_hmc_EODWFRatio_Binary Test_hmc_EODWFRatio Test_hmc_EODWFRatio_Gparity Test_hmc_EOWilsonFermionGauge Test_hmc_EOWilsonRatio Test_hmc_GparityIwasakiGauge Test_hmc_GparityWilsonGauge Test_hmc_IwasakiGauge Test_hmc_RectGauge Test_hmc_ScalarAction Test_hmc_WilsonAdjointFermionGauge Test_hmc_WilsonFermionGauge_Binary Test_hmc_WilsonFermionGauge Test_hmc_WilsonGauge Test_hmc_WilsonMixedRepresentationsFermionGauge Test_hmc_WilsonRatio Test_hmc_WilsonTwoIndexSymmetricFermionGauge Test_multishift_sqrt Test_remez Test_rhmc_EOWilson1p1 Test_rhmc_EOWilsonRatio Test_rhmc_Wilson1p1 Test_rhmc_WilsonRatio +tests: Test_hmc_EODWFRatio_Binary Test_hmc_EODWFRatio Test_hmc_EODWFRatio_Gparity Test_hmc_EOWilsonFermionGauge Test_hmc_EOWilsonRatio Test_hmc_GparityIwasakiGauge Test_hmc_GparityWilsonGauge Test_hmc_IwasakiGauge Test_hmc_RectGauge Test_hmc_ScalarAction Test_hmc_WilsonAdjointFermionGauge Test_hmc_WilsonFermionGauge_Binary Test_hmc_WilsonFermionGauge Test_hmc_WilsonGauge_Binary Test_hmc_WilsonGauge Test_hmc_WilsonMixedRepresentationsFermionGauge Test_hmc_WilsonRatio Test_hmc_WilsonTwoIndexSymmetricFermionGauge Test_multishift_sqrt Test_remez Test_rhmc_EOWilson1p1 Test_rhmc_EOWilsonRatio Test_rhmc_Wilson1p1 Test_rhmc_WilsonRatio +EXTRA_PROGRAMS = Test_hmc_EODWFRatio_Binary Test_hmc_EODWFRatio Test_hmc_EODWFRatio_Gparity Test_hmc_EOWilsonFermionGauge Test_hmc_EOWilsonRatio Test_hmc_GparityIwasakiGauge Test_hmc_GparityWilsonGauge Test_hmc_IwasakiGauge Test_hmc_RectGauge Test_hmc_ScalarAction Test_hmc_WilsonAdjointFermionGauge Test_hmc_WilsonFermionGauge_Binary Test_hmc_WilsonFermionGauge Test_hmc_WilsonGauge_Binary Test_hmc_WilsonGauge Test_hmc_WilsonMixedRepresentationsFermionGauge Test_hmc_WilsonRatio Test_hmc_WilsonTwoIndexSymmetricFermionGauge Test_multishift_sqrt Test_remez Test_rhmc_EOWilson1p1 Test_rhmc_EOWilsonRatio Test_rhmc_Wilson1p1 Test_rhmc_WilsonRatio Test_hmc_EODWFRatio_Binary_SOURCES=Test_hmc_EODWFRatio_Binary.cc Test_hmc_EODWFRatio_Binary_LDADD=-lGrid @@ -40,6 +40,9 @@ Test_hmc_WilsonFermionGauge_Binary_LDADD=-lGrid Test_hmc_WilsonFermionGauge_SOURCES=Test_hmc_WilsonFermionGauge.cc Test_hmc_WilsonFermionGauge_LDADD=-lGrid +Test_hmc_WilsonGauge_Binary_SOURCES=Test_hmc_WilsonGauge_Binary.cc +Test_hmc_WilsonGauge_Binary_LDADD=-lGrid + Test_hmc_WilsonGauge_SOURCES=Test_hmc_WilsonGauge.cc Test_hmc_WilsonGauge_LDADD=-lGrid diff --git a/tests/hmc/Test_hmc_EODWFRatio_Binary.cc b/tests/hmc/Test_hmc_EODWFRatio_Binary.cc index cd35968a..a7fb4db1 100644 --- a/tests/hmc/Test_hmc_EODWFRatio_Binary.cc +++ b/tests/hmc/Test_hmc_EODWFRatio_Binary.cc @@ -78,7 +78,8 @@ class HmcRunner : public BinaryHmcRunner { LatticeGaugeField U(UGrid); // Gauge action - IwasakiGaugeActionR Iaction(4.0); + double beta = 4.0; + IwasakiGaugeActionR Iaction(beta); Real mass = 0.04; Real pv = 1.0; @@ -87,7 +88,9 @@ class HmcRunner : public BinaryHmcRunner { FermionAction DenOp(U,*FGrid,*FrbGrid,*UGrid,*UrbGrid,mass,M5,scale); FermionAction NumOp(U,*FGrid,*FrbGrid,*UGrid,*UrbGrid,pv,M5,scale); - ConjugateGradient CG(1.0e-8,10000); + double StoppingCondition = 1.0e-8; + double MaxCGIterations = 10000; + ConjugateGradient CG(StoppingCondition,MaxCGIterations); TwoFlavourEvenOddRatioPseudoFermionAction Nf2(NumOp, DenOp,CG,CG); // Set smearing (true/false), default: false @@ -98,6 +101,9 @@ class HmcRunner : public BinaryHmcRunner { ActionLevel Level1(1); Level1.push_back(&Nf2); + // this level will integrate with a + // step that is 4 times finer + // than the previous level ActionLevel Level2(4); Level2.push_back(&Iaction); diff --git a/tests/hmc/Test_hmc_WilsonGauge_Binary.cc b/tests/hmc/Test_hmc_WilsonGauge_Binary.cc new file mode 100644 index 00000000..d6041679 --- /dev/null +++ b/tests/hmc/Test_hmc_WilsonGauge_Binary.cc @@ -0,0 +1,136 @@ +/************************************************************************************* + +Grid physics library, www.github.com/paboyle/Grid + +Source file: ./tests/Test_hmc_WilsonFermionGauge.cc + +Copyright (C) 2015 + +Author: Peter Boyle +Author: neo +Author: Guido Cossu + +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 + +using namespace std; +using namespace Grid; +using namespace Grid::QCD; + +namespace Grid { +namespace QCD { + +class HMCRunnerParameters : Serializable { + public: + GRID_SERIALIZABLE_CLASS_MEMBERS(HMCRunnerParameters, + double, beta, + double, mass, + int, MaxCGIterations, + double, StoppingCondition, + bool, smearedAction, + int, SaveInterval, + std::string, format, + std::string, conf_prefix, + std::string, rng_prefix, + double, rho, + int, SmearingLevels, + ); + + HMCRunnerParameters() {} +}; + +// Derive from the BinaryHmcRunner (templated for gauge fields) +class HmcRunner : public BinaryHmcRunner { + public: + void BuildTheAction(int argc, char **argv) + + { + typedef WilsonImplR ImplPolicy; + typedef WilsonFermionR FermionAction; + typedef typename FermionAction::FermionField FermionField; + + UGrid = SpaceTimeGrid::makeFourDimGrid( + GridDefaultLatt(), GridDefaultSimd(Nd, vComplex::Nsimd()), + GridDefaultMpi()); + UrbGrid = SpaceTimeGrid::makeFourDimRedBlackGrid(UGrid); + + FGrid = UGrid; + FrbGrid = UrbGrid; + + // temporarily need a gauge field + LatticeGaugeField U(UGrid); + + // Gauge action + int Ls = UGrid->_gdimensions[Nd - 1]; + std::vector betat(Ls,5); + std::vector betas(Ls); + betas={5,6,6,5}; + std:cout << "Betas:" << betas << std::endl; + VariableWilsonGaugeActionR Waction(betas, betat, UGrid); + //WilsonGaugeActionR Waction(5.6); + + // Collect actions + ActionLevel Level1(1); + Level1.push_back(&Waction); + TheAction.push_back(Level1); + + // Add observables + int SaveInterval = 1; + std::string format = std::string("IEEE64BIG"); + std::string conf_prefix = std::string("ckpoint_lat"); + std::string rng_prefix = std::string("ckpoint_rng"); + BinaryHmcCheckpointer Checkpoint( + conf_prefix, rng_prefix, SaveInterval, format); + // Can implement also a specific function in the hmcrunner + // AddCheckpoint (...) that takes the same parameters + a string/tag + // defining the type of the checkpointer + // with tags can be implemented by overloading and no ifs + // Then force all checkpoint to have few common functions + // return an object that is then passed to the Run function + + PlaquetteLogger PlaqLog( + std::string("Plaquette")); + ObservablesList.push_back(&PlaqLog); + ObservablesList.push_back(&Checkpoint); + + Run(argc, argv, Checkpoint); // no smearing + }; +}; +} +} + +int main(int argc, char **argv) { + Grid_init(&argc, &argv); + + int threads = GridThread::GetThreads(); + std::cout << GridLogMessage << "Grid is setup to use " << threads + << " threads" << std::endl; + + HmcRunner TheHMC; + + // Seeds for the random number generators + std::vector SerSeed({1, 2, 3, 4, 5}); + std::vector ParSeed({6, 7, 8, 9, 10}); + TheHMC.RNGSeeds(SerSeed, ParSeed); + + TheHMC.MDparameters.set(20, 1.0);// MDsteps, traj length + + TheHMC.BuildTheAction(argc, argv); +} From 8c65bdf6d345314cb4ce2bcb9ac81667cd944299 Mon Sep 17 00:00:00 2001 From: Guido Cossu Date: Wed, 19 Oct 2016 16:56:11 +0100 Subject: [PATCH 017/214] Printing checksum for the RNG file --- lib/parallelIO/BinaryIO.h | 4 ++++ lib/qcd/action/gauge/GaugeImpl.h | 1 + tests/hmc/Test_hmc_EODWFRatio_Binary.cc | 2 ++ tests/hmc/Test_hmc_WilsonGauge_Binary.cc | 2 ++ 4 files changed, 9 insertions(+) diff --git a/lib/parallelIO/BinaryIO.h b/lib/parallelIO/BinaryIO.h index 3265ba54..9dab4d24 100644 --- a/lib/parallelIO/BinaryIO.h +++ b/lib/parallelIO/BinaryIO.h @@ -372,6 +372,8 @@ class BinaryIO { if (grid->IsBoss()) fout.close(); + std::cout << GridLogMessage << "RNG file checksum " << csum << std::endl; + return csum; } static inline uint32_t readRNGSerial(GridSerialRNG &serial,GridParallelRNG ¶llel,std::string file,int offset) @@ -421,6 +423,8 @@ class BinaryIO { Uint32Checksum((uint32_t *)&saved[0],bytes,csum); } + std::cout << GridLogMessage << "RNG file checksum " << csum << std::endl; + grid->Broadcast(0,(void *)&csum,sizeof(csum)); return csum; diff --git a/lib/qcd/action/gauge/GaugeImpl.h b/lib/qcd/action/gauge/GaugeImpl.h index 08fbfa68..3448062b 100644 --- a/lib/qcd/action/gauge/GaugeImpl.h +++ b/lib/qcd/action/gauge/GaugeImpl.h @@ -85,6 +85,7 @@ public: LinkField Pmu(P._grid); Pmu = zero; for (int mu = 0; mu < Nd; mu++) { + std::cout << "generating momenta " << mu << "\n"; SU::GaussianFundamentalLieAlgebraMatrix(pRNG, Pmu); PokeIndex(P, Pmu, mu); } diff --git a/tests/hmc/Test_hmc_EODWFRatio_Binary.cc b/tests/hmc/Test_hmc_EODWFRatio_Binary.cc index a7fb4db1..0b912c66 100644 --- a/tests/hmc/Test_hmc_EODWFRatio_Binary.cc +++ b/tests/hmc/Test_hmc_EODWFRatio_Binary.cc @@ -161,4 +161,6 @@ int main(int argc, char **argv) { TheHMC.MDparameters.set(20, 1.0);// MDsteps, traj length TheHMC.BuildTheAction(argc, argv); + + Grid_finalize(); } diff --git a/tests/hmc/Test_hmc_WilsonGauge_Binary.cc b/tests/hmc/Test_hmc_WilsonGauge_Binary.cc index d6041679..e1f1e8df 100644 --- a/tests/hmc/Test_hmc_WilsonGauge_Binary.cc +++ b/tests/hmc/Test_hmc_WilsonGauge_Binary.cc @@ -133,4 +133,6 @@ int main(int argc, char **argv) { TheHMC.MDparameters.set(20, 1.0);// MDsteps, traj length TheHMC.BuildTheAction(argc, argv); + + Grid_finalize(); } From 590675e2ca765f56478a75c7d6a3f9997852ea87 Mon Sep 17 00:00:00 2001 From: Guido Cossu Date: Wed, 19 Oct 2016 17:26:25 +0100 Subject: [PATCH 018/214] Csum in hex format --- lib/lattice/Lattice_rng.h | 98 ++++++++++++++++++++------------------- lib/parallelIO/BinaryIO.h | 6 +-- 2 files changed, 53 insertions(+), 51 deletions(-) diff --git a/lib/lattice/Lattice_rng.h b/lib/lattice/Lattice_rng.h index 3254af30..ae61224a 100644 --- a/lib/lattice/Lattice_rng.h +++ b/lib/lattice/Lattice_rng.h @@ -130,14 +130,14 @@ namespace Grid { ss<<_generators[gen]; ss.seekg(0,ss.beg); for(int i=0;i>saved[i]; + ss>>saved[i]; } } void SetState(std::vector & saved,int gen){ assert(saved.size()==RngStateCount); std::stringstream ss; for(int i=0;i>_generators[gen]; @@ -178,7 +178,7 @@ namespace Grid { dist[0].reset(); for(int idx=0;idxGlobalIndexToGlobalCoor(gidx,gcoor); - _grid->GlobalCoorToRankIndex(rank,o_idx,i_idx,gcoor); + int rank,o_idx,i_idx; + _grid->GlobalIndexToGlobalCoor(gidx,gcoor); + _grid->GlobalCoorToRankIndex(rank,o_idx,i_idx,gcoor); - int l_idx=generator_idx(o_idx,i_idx); - - std::vector site_seeds(4); - for(int i=0;i<4;i++){ - site_seeds[i]= ui(pseeder); - } + int l_idx=generator_idx(o_idx,i_idx); + + std::vector site_seeds(4); + for(int i=0;i<4;i++){ + site_seeds[i]= ui(pseeder); + } - _grid->Broadcast(0,(void *)&site_seeds[0],sizeof(int)*site_seeds.size()); + _grid->Broadcast(0,(void *)&site_seeds[0],sizeof(int)*site_seeds.size()); - if( rank == _grid->ThisRank() ){ - fixedSeed ssrc(site_seeds); - typename source::result_type sinit = ssrc(); - _generators[l_idx] = RngEngine(sinit); - } + if( rank == _grid->ThisRank() ){ + fixedSeed ssrc(site_seeds); + typename source::result_type sinit = ssrc(); + _generators[l_idx] = RngEngine(sinit); + } } _seeded=1; } @@ -317,51 +317,53 @@ namespace Grid { //void SaveState(const std::string &file); //void LoadState(const std::string &file); - template inline void fill(Lattice &l,std::vector &dist){ - + template + inline void fill(Lattice &l, std::vector &dist) { typedef typename vobj::scalar_object scalar_object; typedef typename vobj::scalar_type scalar_type; typedef typename vobj::vector_type vector_type; - - int multiplicity = RNGfillable(_grid,l._grid); - int Nsimd =_grid->Nsimd(); - int osites=_grid->oSites(); - int words=sizeof(scalar_object)/sizeof(scalar_type); + int multiplicity = RNGfillable(_grid, l._grid); + int Nsimd = _grid->Nsimd(); + int osites = _grid->oSites(); + int words = sizeof(scalar_object) / sizeof(scalar_type); -PARALLEL_FOR_LOOP - for(int ss=0;ss buf(Nsimd); - for(int m=0;m buf(Nsimd); + for (int m = 0; m < multiplicity; + m++) { // Draw from same generator multiplicity times - int sm=multiplicity*ss+m; // Maps the generator site to the fine site + int sm = multiplicity * ss + + m; // Maps the generator site to the fine site - for(int si=0;si &seeds){ + void SeedFixedIntegers(const std::vector &seeds) { fixedSeed src(seeds); Seed(src); } - }; template inline void random(GridParallelRNG &rng,Lattice &l){ diff --git a/lib/parallelIO/BinaryIO.h b/lib/parallelIO/BinaryIO.h index 9dab4d24..cdcb1989 100644 --- a/lib/parallelIO/BinaryIO.h +++ b/lib/parallelIO/BinaryIO.h @@ -372,8 +372,8 @@ class BinaryIO { if (grid->IsBoss()) fout.close(); - std::cout << GridLogMessage << "RNG file checksum " << csum << std::endl; - + std::cout << GridLogMessage << "RNG file checksum " << std::hex << csum << std::dec << std::endl; + return csum; } static inline uint32_t readRNGSerial(GridSerialRNG &serial,GridParallelRNG ¶llel,std::string file,int offset) @@ -423,7 +423,7 @@ class BinaryIO { Uint32Checksum((uint32_t *)&saved[0],bytes,csum); } - std::cout << GridLogMessage << "RNG file checksum " << csum << std::endl; + std::cout << GridLogMessage << "RNG file checksum " << std::hex << csum << std::dec << std::endl; grid->Broadcast(0,(void *)&csum,sizeof(csum)); From 977d8443946a868360902c367d9488f41ce4533b Mon Sep 17 00:00:00 2001 From: Guido Cossu Date: Thu, 20 Oct 2016 17:01:59 +0100 Subject: [PATCH 019/214] Few modifications on stdout messages --- lib/parallelIO/NerscIO.h | 2 -- lib/qcd/action/gauge/GaugeImpl.h | 1 - tests/IO/Test_nersc_io.cc | 3 ++- tests/hmc/Test_hmc_WilsonFermionGauge.cc | 2 +- tests/hmc/Test_hmc_WilsonFermionGauge_Binary.cc | 2 +- tests/hmc/Test_hmc_WilsonGauge_Binary.cc | 6 +++--- 6 files changed, 7 insertions(+), 9 deletions(-) diff --git a/lib/parallelIO/NerscIO.h b/lib/parallelIO/NerscIO.h index ecd7527a..6fdf83ef 100644 --- a/lib/parallelIO/NerscIO.h +++ b/lib/parallelIO/NerscIO.h @@ -513,8 +513,6 @@ static inline void readRNGState(GridSerialRNG &serial,GridParallelRNG & parallel // munger is a function of uint32_t csum=BinaryIO::readRNGSerial(serial,parallel,file,offset); - std::cerr<<" Csum "<< csum << " "<< header.checksum <::GaussianFundamentalLieAlgebraMatrix(pRNG, Pmu); PokeIndex(P, Pmu, mu); } diff --git a/tests/IO/Test_nersc_io.cc b/tests/IO/Test_nersc_io.cc index 0273d02a..16514d9e 100644 --- a/tests/IO/Test_nersc_io.cc +++ b/tests/IO/Test_nersc_io.cc @@ -41,7 +41,7 @@ int main (int argc, char ** argv) std::vector simd_layout = GridDefaultSimd(4,vComplex::Nsimd()); std::vector mpi_layout = GridDefaultMpi(); - std::vector latt_size ({16,16,16,32}); + std::vector latt_size ({32,32,32,32}); std::vector clatt_size ({4,4,4,8}); int orthodir=3; int orthosz =latt_size[orthodir]; @@ -73,6 +73,7 @@ int main (int argc, char ** argv) random(sRNGb,b); std::cout << " serial RNG numbers "< Nf2(FermOp, CG, CG); // Set smearing (true/false), default: false - Nf2.is_smeared = true; + Nf2.is_smeared = false; // Collect actions ActionLevel Level1(1); diff --git a/tests/hmc/Test_hmc_WilsonFermionGauge_Binary.cc b/tests/hmc/Test_hmc_WilsonFermionGauge_Binary.cc index 9024b4e2..e81c212d 100644 --- a/tests/hmc/Test_hmc_WilsonFermionGauge_Binary.cc +++ b/tests/hmc/Test_hmc_WilsonFermionGauge_Binary.cc @@ -151,7 +151,7 @@ int main(int argc, char **argv) { std::vector ParSeed({6, 7, 8, 9, 10}); TheHMC.RNGSeeds(SerSeed, ParSeed); - TheHMC.MDparameters.set(20, 1.0);// MDsteps, traj length + TheHMC.MDparameters.set(5, 1.0);// MDsteps, traj length TheHMC.BuildTheAction(argc, argv); } diff --git a/tests/hmc/Test_hmc_WilsonGauge_Binary.cc b/tests/hmc/Test_hmc_WilsonGauge_Binary.cc index e1f1e8df..098e23e4 100644 --- a/tests/hmc/Test_hmc_WilsonGauge_Binary.cc +++ b/tests/hmc/Test_hmc_WilsonGauge_Binary.cc @@ -82,9 +82,9 @@ class HmcRunner : public BinaryHmcRunner { std::vector betat(Ls,5); std::vector betas(Ls); betas={5,6,6,5}; - std:cout << "Betas:" << betas << std::endl; - VariableWilsonGaugeActionR Waction(betas, betat, UGrid); - //WilsonGaugeActionR Waction(5.6); + //std:cout << "Betas:" << betas << std::endl; + //VariableWilsonGaugeActionR Waction(betas, betat, UGrid); + WilsonGaugeActionR Waction(5.6); // Collect actions ActionLevel Level1(1); From deef2673b2d13de0308724db7733f61e236268f7 Mon Sep 17 00:00:00 2001 From: Guido Cossu Date: Thu, 20 Oct 2016 17:24:08 +0100 Subject: [PATCH 020/214] Separating the Lattice theories stub from the QCD.h file --- lib/qcd/LatticeTheories.h | 119 ++++++++++++++++++++++++++++++++++++++ lib/qcd/QCD.h | 66 --------------------- 2 files changed, 119 insertions(+), 66 deletions(-) create mode 100644 lib/qcd/LatticeTheories.h diff --git a/lib/qcd/LatticeTheories.h b/lib/qcd/LatticeTheories.h new file mode 100644 index 00000000..981c7577 --- /dev/null +++ b/lib/qcd/LatticeTheories.h @@ -0,0 +1,119 @@ + /************************************************************************************* + + Grid physics library, www.github.com/paboyle/Grid + + Source file: ./lib/qcd/QCD.h + + Copyright (C) 2015 + +Author: Azusa Yamaguchi +Author: Peter Boyle +Author: Peter Boyle +Author: neo +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 */ +#ifndef GRID_LT_H +#define GRID_LT_H +namespace Grid{ + +// First steps in the complete generalization of the Physics part +namespace LatticeTheories { + +template +struct LatticeTheory { + static const int Nd = Dimensions; + static const int Nds = Dimensions * 2; // double stored field + template + using iSinglet = iScalar > >; +}; + +template +struct LatticeGaugeTheory : public LatticeTheory { + static const int Nds = Dimensions * 2; + static const int Nd = Dimensions; + static const int Nc = Colours; + + template + using iColourMatrix = iScalar > >; + template + using iLorentzColourMatrix = iVector >, Nd>; + template + using iDoubleStoredColourMatrix = iVector >, Nds>; + template + using iColourVector = iScalar > >; +}; + +template +struct FermionicLatticeGaugeTheory + : public LatticeGaugeTheory { + static const int Nd = Dimensions; + static const int Nds = Dimensions * 2; + static const int Nc = Colours; + static const int Ns = Spin; + + template + using iSpinMatrix = iScalar, Ns> >; + template + using iSpinColourMatrix = iScalar, Ns> >; + template + using iSpinVector = iScalar, Ns> >; + template + using iSpinColourVector = iScalar, Ns> >; + // These 2 only if Spin is a multiple of 2 + static const int Nhs = Spin / 2; + template + using iHalfSpinVector = iScalar, Nhs> >; + template + using iHalfSpinColourVector = iScalar, Nhs> >; +}; + +// Examples, not complete now. +struct QCD : public FermionicLatticeGaugeTheory<4, 3, 4> { + static const int Xp = 0; + static const int Yp = 1; + static const int Zp = 2; + static const int Tp = 3; + static const int Xm = 4; + static const int Ym = 5; + static const int Zm = 6; + static const int Tm = 7; + + typedef FermionicLatticeGaugeTheory FLGT; + + typedef FLGT::iColourMatrix ColourMatrix; + typedef FLGT::iColourMatrix ColourMatrixF; + typedef FLGT::iColourMatrix ColourMatrixD; + + typedef FLGT::iSpinMatrix SpinMatrix; + typedef FLGT::iSpinMatrix SpinMatrixF; + typedef FLGT::iSpinMatrix SpinMatrixD; + +}; +struct QED : public FermionicLatticeGaugeTheory<4, 1, 4> {//fill +}; + +template +struct Scalar : public LatticeTheory {}; + +}; // LatticeTheories + +} // Grid + +#endif diff --git a/lib/qcd/QCD.h b/lib/qcd/QCD.h index 61313f33..e08c3dc8 100644 --- a/lib/qcd/QCD.h +++ b/lib/qcd/QCD.h @@ -32,72 +32,6 @@ Author: paboyle #ifndef GRID_QCD_H #define GRID_QCD_H namespace Grid{ - -// First steps in the complete generalization of the Physics part -namespace LatticeTheories { - -template -struct LatticeTheory { - static const int Nd = Dimensions; - static const int Nds = Dimensions * 2; // double stored field - template - using iSinglet = iScalar > >; -}; - -template -struct LatticeGaugeTheory : public LatticeTheory { - static const int Nds = Dimensions * 2; - static const int Nd = Dimensions; - static const int Nc = Colours; - - template - using iColourMatrix = iScalar > >; - template - using iLorentzColourMatrix = iVector >, Nd>; - template - using iDoubleStoredColourMatrix = iVector >, Nds>; - template - using iColourVector = iScalar > >; -}; - -template -struct FermionicLatticeGaugeTheory - : public LatticeGaugeTheory { - static const int Nd = Dimensions; - static const int Nds = Dimensions * 2; - static const int Nc = Colours; - static const int Ns = Spin; - - template - using iSpinMatrix = iScalar, Ns> >; - template - using iSpinColourMatrix = iScalar, Ns> >; - template - using iSpinVector = iScalar, Ns> >; - template - using iSpinColourVector = iScalar, Ns> >; - // These 2 only is Spin is a multiple of 2 - static const int Nhs = Spin / 2; - template - using iHalfSpinVector = iScalar, Nhs> >; - template - using iHalfSpinColourVector = iScalar, Nhs> >; -}; - -struct QCD : public FermionicLatticeGaugeTheory<4, 3, 4> { - typedef FermionicLatticeGaugeTheory FLGT; - typedef FLGT::iSpinMatrix SpinMatrix; - typedef FLGT::iSpinMatrix SpinMatrixF; - typedef FLGT::iSpinMatrix SpinMatrixD; - -}; -struct QED : public FermionicLatticeGaugeTheory<4, 1, 4> {}; - -template -struct Scalar : public LatticeTheory {}; - -} // LatticeTheories - namespace QCD { From 392130a53738b8dda3c5cbb046f70f23b3ed2b91 Mon Sep 17 00:00:00 2001 From: Guido Cossu Date: Fri, 21 Oct 2016 14:22:25 +0100 Subject: [PATCH 021/214] Working on the 5d --- lib/qcd/LatticeTheories.h | 51 ++-- lib/qcd/QCD.h | 2 +- lib/qcd/action/gauge/WilsonGaugeAction.h | 174 ++++++++------ lib/qcd/hmc/GenericHMCrunner.h | 294 ++++++++++++----------- lib/qcd/hmc/HMC.h | 1 - lib/qcd/hmc/integrators/Integrator.h | 8 - lib/qcd/utils/WilsonLoops.h | 4 +- tests/hmc/Test_hmc_WilsonGauge_Binary.cc | 14 +- 8 files changed, 286 insertions(+), 262 deletions(-) diff --git a/lib/qcd/LatticeTheories.h b/lib/qcd/LatticeTheories.h index 981c7577..74c68d83 100644 --- a/lib/qcd/LatticeTheories.h +++ b/lib/qcd/LatticeTheories.h @@ -1,10 +1,10 @@ - /************************************************************************************* +/************************************************************************************* - Grid physics library, www.github.com/paboyle/Grid +Grid physics library, www.github.com/paboyle/Grid - Source file: ./lib/qcd/QCD.h +Source file: ./lib/qcd/QCD.h - Copyright (C) 2015 +Copyright (C) 2015 Author: Azusa Yamaguchi Author: Peter Boyle @@ -12,28 +12,30 @@ Author: Peter Boyle Author: neo 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 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. +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. +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 */ +See the full license in the file "LICENSE" in the top level distribution +directory +*************************************************************************************/ +/* END LEGAL */ #ifndef GRID_LT_H #define GRID_LT_H namespace Grid{ // First steps in the complete generalization of the Physics part +// Design not final namespace LatticeTheories { template @@ -50,7 +52,7 @@ struct LatticeGaugeTheory : public LatticeTheory { static const int Nd = Dimensions; static const int Nc = Colours; - template + template using iColourMatrix = iScalar > >; template using iLorentzColourMatrix = iVector >, Nd>; @@ -82,6 +84,13 @@ struct FermionicLatticeGaugeTheory using iHalfSpinVector = iScalar, Nhs> >; template using iHalfSpinColourVector = iScalar, Nhs> >; + + //tests + typedef iColourMatrix ColourMatrix; + typedef iColourMatrix ColourMatrixF; + typedef iColourMatrix ColourMatrixD; + + }; // Examples, not complete now. @@ -97,10 +106,6 @@ struct QCD : public FermionicLatticeGaugeTheory<4, 3, 4> { typedef FermionicLatticeGaugeTheory FLGT; - typedef FLGT::iColourMatrix ColourMatrix; - typedef FLGT::iColourMatrix ColourMatrixF; - typedef FLGT::iColourMatrix ColourMatrixD; - typedef FLGT::iSpinMatrix SpinMatrix; typedef FLGT::iSpinMatrix SpinMatrixF; typedef FLGT::iSpinMatrix SpinMatrixD; diff --git a/lib/qcd/QCD.h b/lib/qcd/QCD.h index e08c3dc8..0d8c28bc 100644 --- a/lib/qcd/QCD.h +++ b/lib/qcd/QCD.h @@ -46,7 +46,7 @@ namespace QCD { static const int Nc=3; static const int Ns=4; - static const int Nd=4; + static const int Nd=5; static const int Nhs=2; // half spinor static const int Nds=8; // double stored gauge field static const int Ngp=2; // gparity index range diff --git a/lib/qcd/action/gauge/WilsonGaugeAction.h b/lib/qcd/action/gauge/WilsonGaugeAction.h index 686c5470..059fcc58 100644 --- a/lib/qcd/action/gauge/WilsonGaugeAction.h +++ b/lib/qcd/action/gauge/WilsonGaugeAction.h @@ -76,7 +76,7 @@ class WilsonGaugeAction : public Action { // Staple in direction mu WilsonLoops::Staple(dSdU_mu, U, mu); dSdU_mu = Ta(Umu * dSdU_mu) * factor; - + PokeIndex(dSdU, dSdU_mu, mu); } }; @@ -88,57 +88,70 @@ class VariableWilsonGaugeAction : public Action { INHERIT_GIMPL_TYPES(Gimpl); private: - std::vector b_bulk;// bulk couplings - std::vector b_xdim;//extra dimension couplings + std::vector b_bulk; // bulk couplings + std::vector b_xdim; // extra dimension couplings GridBase *grid; LatticeComplex beta_xdim; LatticeComplex beta_xdim_shifted; LatticeComplex beta_bulk; + int bulk_volume; + public: VariableWilsonGaugeAction(std::vector bulk, std::vector xdim, - GridBase *_grid) + GridBase *_grid, bool openBC = false) : b_bulk(bulk), b_xdim(xdim), grid(_grid), beta_xdim(grid), beta_xdim_shifted(grid), - beta_bulk(grid) - { - //check that the grid is ok - //todo - int Ndim = Nd;//change later + beta_bulk(grid) { + // check that the grid is ok + // todo + int Ndim = Nd; // change later - LatticeComplex temp(grid); + std::vector FullDim = grid->GlobalDimensions(); + bulk_volume = 1; + for (int s = 0; s < Ndim - 1; s++) bulk_volume *= FullDim[s]; - Lattice > coor(grid); + LatticeComplex temp(grid); - LatticeCoordinate(coor, Ndim - 1); + Lattice > coor(grid); - int Nex = grid->_fdimensions[Ndim - 1]; - assert(b_bulk.size() == Nex); - assert(b_xdim.size() == Nex); + LatticeCoordinate(coor, Ndim - 1); - beta_xdim = zero; - for (int tau = 0; tau < Nex; tau++) { - temp = b_xdim[tau]; - beta_xdim = where(coor == tau, temp, beta_xdim); - } + int Nex = FullDim[Ndim - 1]; + assert(b_bulk.size() == Nex); + assert(b_xdim.size() == Nex); - beta_xdim_shifted = Cshift(beta_xdim, Ndim - 1, -1); + beta_xdim = zero; + for (int tau = 0; tau < Nex - 1; tau++) { + temp = b_xdim[tau]; + beta_xdim = where(coor == tau, temp, beta_xdim); + } - beta_bulk = zero; - for (int tau = 0; tau < Nex; tau++) { - temp = b_bulk[tau]; - beta_bulk = where(coor == tau, temp, beta_bulk); - } - }; + if (!openBC) { + temp = b_xdim[Nex - 1]; + beta_xdim = where(coor == Nex - 1, temp, beta_xdim); + } + + beta_xdim_shifted = Cshift(beta_xdim, Ndim - 1, -1); + + beta_bulk = zero; + for (int tau = 0; tau < Nex; tau++) { + temp = b_bulk[tau]; + beta_bulk = where(coor == tau, temp, beta_bulk); + } + + std::cout << beta_xdim << std::endl; + std::cout << beta_xdim_shifted << std::endl; + }; virtual void refresh(const GaugeField &U, GridParallelRNG &pRNG){}; // noop as no pseudoferms virtual RealD S(const GaugeField &Umu) { - int Ndim = Nd; // change later for generality + int Ndim = Nd; // change later for generality conformable(grid, Umu._grid); std::vector U(Ndim, grid); @@ -150,19 +163,34 @@ class VariableWilsonGaugeAction : public Action { LatticeComplex dirPlaq(grid); LatticeComplex Plaq(grid); + LatticeComplex SumdirPlaq(grid); + RealD OneOnNc = 1.0 / Real(Nc); ///////////// // Lower dim plaquettes ///////////// Plaq = zero; + SumdirPlaq = zero; for (int mu = 1; mu < Ndim - 1; mu++) { for (int nu = 0; nu < mu; nu++) { WilsonLoops::traceDirPlaquette(dirPlaq, U, mu, nu); + SumdirPlaq += dirPlaq; Plaq = Plaq + (1.0 - dirPlaq * OneOnNc) * beta_bulk; } } + double faces = (1.0 * (Nd - 1) * (Nd - 2)) / 2.0; + SumdirPlaq *= OneOnNc / (RealD(bulk_volume) * faces); + + // print slices in the extra dimension + int Nex = grid->_fdimensions[Ndim - 1]; + std::vector plaq_ex(Nex); + sliceSum(SumdirPlaq, plaq_ex, Ndim - 1); + for (int ex = 0; ex < Nex; ex++) + std::cout << GridLogMessage << "Bulk plaq[" << ex + << "] = " << TensorRemove(plaq_ex[ex]).real() << std::endl; + ///////////// // Extra dimension ///////////// @@ -186,74 +214,66 @@ class VariableWilsonGaugeAction : public Action { // for the higher dimension plaquettes take the upper plaq of the // 4d slice and multiply by beta[s] and the lower and multiply by beta[s-1] - // todo // derivative of links mu = 0, ... Nd-1 inside plaq (mu,5) // for these I need upper and lower staples separated // each multiplied with their own beta // derivative of links mu = 5 // living on the same slice, share the same beta + conformable(grid, U._grid); + int Ndim = Nd; // change later + RealD factor = 0.5 / RealD(Nc); -conformable(grid,U._grid); -int Ndim = Nd; // change later -RealD factor = 0.5 / RealD(Nc); + GaugeLinkField Umu(grid); + GaugeLinkField dSdU_mu(grid); + GaugeLinkField staple(grid); -GaugeLinkField Umu(grid); -GaugeLinkField dSdU_mu(grid); -GaugeLinkField staple(grid); + for (int mu = 0; mu < Ndim; mu++) { + Umu = PeekIndex(U, mu); + dSdU_mu = zero; -for (int mu = 0; mu < Ndim; mu++) { - Umu = PeekIndex(U, mu); - dSdU_mu = zero; + for (int nu = 0; nu < Ndim; nu++) { + if (nu != mu) { + if ((mu < (Ndim - 1)) && (nu < (Ndim - 1))) { + // Spacelike case apply beta space + WilsonLoops::Staple(staple, U, mu, nu); + staple = staple * beta_bulk; + dSdU_mu += staple; - for (int nu = 0; nu < Ndim; nu++) { - if (nu != mu) { - if ((mu < (Ndim - 1)) && (nu < (Ndim - 1))) { - // Spacelike case apply beta space - WilsonLoops::Staple(staple, U, mu, nu); - staple = staple * beta_bulk; - dSdU_mu += staple; + } else if (mu == (Ndim - 1)) { + // nu space; mu time link + assert(nu < (Ndim - 1)); + assert(mu == (Ndim - 1)); - } else if (mu == (Ndim - 1)) { - // nu space; mu time link - assert(nu < (Ndim - 1)); - assert(mu == (Ndim - 1)); + // mu==tau dir link deriv, nu spatial + WilsonLoops::Staple(staple, U, mu, nu); + staple = staple * beta_xdim; + dSdU_mu += staple; - // mu==tau dir link deriv, nu spatial - WilsonLoops::Staple(staple, U, mu, nu); - staple = staple * beta_xdim; - dSdU_mu += staple; + } else { + assert(mu < (Ndim - 1)); + assert(nu == (Ndim - 1)); - } else { - assert(mu < (Ndim - 1)); - assert(nu == (Ndim - 1)); + // nu time; mu space link - // nu time; mu space link + // staple forwards in tau + WilsonLoops::StapleUpper(staple, U, mu, nu); + staple = staple * beta_xdim; + dSdU_mu += staple; - // staple forwards in tau - WilsonLoops::StapleUpper(staple, U, mu, nu); - staple = staple * beta_xdim; - dSdU_mu += staple; - - // staple backwards in tau - WilsonLoops::StapleLower(staple, U, mu, nu); - staple = staple * beta_xdim_shifted; - dSdU_mu += staple; + // staple backwards in tau + WilsonLoops::StapleLower(staple, U, mu, nu); + staple = staple * beta_xdim_shifted; + dSdU_mu += staple; + } + } } + + dSdU_mu = Ta(Umu * dSdU_mu) * factor; + PokeIndex(dSdU, dSdU_mu, mu); } - } - - dSdU_mu = Ta(Umu * dSdU_mu) * factor; - PokeIndex(dSdU, dSdU_mu, mu); - } - - - }; }; - - - } } diff --git a/lib/qcd/hmc/GenericHMCrunner.h b/lib/qcd/hmc/GenericHMCrunner.h index bad3b9cf..047b9c9e 100644 --- a/lib/qcd/hmc/GenericHMCrunner.h +++ b/lib/qcd/hmc/GenericHMCrunner.h @@ -23,9 +23,9 @@ 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 -*************************************************************************************/ + See the full license in the file "LICENSE" in the top level distribution + directory + *************************************************************************************/ /* END LEGAL */ #ifndef GENERIC_HMC_RUNNER #define GENERIC_HMC_RUNNER @@ -33,165 +33,169 @@ directory namespace Grid { namespace QCD { -// Virtual Class for HMC specific for gauge theories -// implement a specific theory by defining the BuildTheAction -template -class BinaryHmcRunnerTemplate { - public: - INHERIT_FIELD_TYPES(Implementation); - typedef Implementation ImplPolicy; + // Virtual Class for HMC specific for gauge theories + // implement a specific theory by defining the BuildTheAction + template + class BinaryHmcRunnerTemplate { + public: + INHERIT_FIELD_TYPES(Implementation); + typedef Implementation ImplPolicy; - enum StartType_t { ColdStart, HotStart, TepidStart, CheckpointStart }; + enum StartType_t { ColdStart, + HotStart, + TepidStart, + CheckpointStart }; - ActionSet TheAction; - - // A vector of HmcObservable - // that can be injected from outside - std::vector< HmcObservable* > ObservablesList; + ActionSet TheAction; - IntegratorParameters MDparameters; + // A vector of HmcObservable + // that can be injected from outside + std::vector *> + ObservablesList; - GridCartesian *UGrid; - GridCartesian *FGrid; - GridRedBlackCartesian *UrbGrid; - GridRedBlackCartesian *FrbGrid; + IntegratorParameters MDparameters; - std::vector SerialSeed; - std::vector ParallelSeed; + GridCartesian * UGrid; + GridCartesian * FGrid; + GridRedBlackCartesian *UrbGrid; + GridRedBlackCartesian *FrbGrid; - void RNGSeeds(std::vector S, std::vector P){ - SerialSeed = S; - ParallelSeed = P; - } + std::vector SerialSeed; + std::vector ParallelSeed; - virtual void BuildTheAction(int argc, char **argv) = 0; // necessary? + void RNGSeeds(std::vector S, std::vector P) { + SerialSeed = S; + ParallelSeed = P; + } - // A couple of wrapper classes - template - void Run(int argc, char **argv, IOCheckpointer &Checkpoint) { - NoSmearing S; - Runner(argc, argv, Checkpoint, S); - } + virtual void BuildTheAction(int argc, char **argv) = 0; // necessary? - template - void Run(int argc, char **argv, IOCheckpointer &CP, SmearingPolicy &S) { - Runner(argc, argv, CP, S); - } - ////////////////////////////// + // A couple of wrapper classes + template + void Run(int argc, char **argv, IOCheckpointer &Checkpoint) { + NoSmearing S; + Runner(argc, argv, Checkpoint, S); + } - template - void Runner(int argc, char **argv, IOCheckpointer &Checkpoint, - SmearingPolicy &Smearing) { - StartType_t StartType = HotStart; + template + void Run(int argc, char **argv, IOCheckpointer &CP, SmearingPolicy &S) { + Runner(argc, argv, CP, S); + } + ////////////////////////////// - std::string arg; + template + void Runner(int argc, + char ** argv, + IOCheckpointer &Checkpoint, + SmearingPolicy &Smearing) { + StartType_t StartType = HotStart; - if (GridCmdOptionExists(argv, argv + argc, "--StartType")) { - arg = GridCmdOptionPayload(argv, argv + argc, "--StartType"); - if (arg == "HotStart") { - StartType = HotStart; - } else if (arg == "ColdStart") { - StartType = ColdStart; - } else if (arg == "TepidStart") { - StartType = TepidStart; - } else if (arg == "CheckpointStart") { - StartType = CheckpointStart; - } else { - std::cout << GridLogError << "Unrecognized option in --StartType\n"; - std::cout - << GridLogError - << "Valid [HotStart, ColdStart, TepidStart, CheckpointStart]\n"; - assert(0); + std::string arg; + + if (GridCmdOptionExists(argv, argv + argc, "--StartType")) { + arg = GridCmdOptionPayload(argv, argv + argc, "--StartType"); + if (arg == "HotStart") { + StartType = HotStart; + } else if (arg == "ColdStart") { + StartType = ColdStart; + } else if (arg == "TepidStart") { + StartType = TepidStart; + } else if (arg == "CheckpointStart") { + StartType = CheckpointStart; + } else { + std::cout << GridLogError << "Unrecognized option in --StartType\n"; + std::cout + << GridLogError + << "Valid [HotStart, ColdStart, TepidStart, CheckpointStart]\n"; + assert(0); + } } + + int StartTraj = 0; + if (GridCmdOptionExists(argv, argv + argc, "--StartTrajectory")) { + arg = GridCmdOptionPayload(argv, argv + argc, "--StartTrajectory"); + std::vector ivec(0); + GridCmdOptionIntVector(arg, ivec); + StartTraj = ivec[0]; + } + + int NumTraj = 1; + if (GridCmdOptionExists(argv, argv + argc, "--Trajectories")) { + arg = GridCmdOptionPayload(argv, argv + argc, "--Trajectories"); + std::vector ivec(0); + GridCmdOptionIntVector(arg, ivec); + NumTraj = ivec[0]; + } + + int NumThermalizations = 10; + if (GridCmdOptionExists(argv, argv + argc, "--Thermalizations")) { + arg = GridCmdOptionPayload(argv, argv + argc, "--Thermalizations"); + std::vector ivec(0); + GridCmdOptionIntVector(arg, ivec); + NumThermalizations = ivec[0]; + } + + GridSerialRNG sRNG; + GridParallelRNG pRNG(UGrid); + Field U(UGrid); + + typedef MinimumNorm2 + IntegratorType; // change here to change the algorithm + IntegratorType MDynamics(UGrid, MDparameters, TheAction, Smearing); + + HMCparameters HMCpar; + HMCpar.StartTrajectory = StartTraj; + HMCpar.Trajectories = NumTraj; + HMCpar.NoMetropolisUntil = NumThermalizations; + + if (StartType == HotStart) { + // Hot start + HMCpar.MetropolisTest = true; + sRNG.SeedFixedIntegers(SerialSeed); + pRNG.SeedFixedIntegers(ParallelSeed); + Implementation::HotConfiguration(pRNG, U); + } else if (StartType == ColdStart) { + // Cold start + HMCpar.MetropolisTest = true; + sRNG.SeedFixedIntegers(SerialSeed); + pRNG.SeedFixedIntegers(ParallelSeed); + Implementation::ColdConfiguration(pRNG, U); + } else if (StartType == TepidStart) { + // Tepid start + HMCpar.MetropolisTest = true; + sRNG.SeedFixedIntegers(SerialSeed); + pRNG.SeedFixedIntegers(ParallelSeed); + Implementation::TepidConfiguration(pRNG, U); + } else if (StartType == CheckpointStart) { + HMCpar.MetropolisTest = true; + // CheckpointRestart + Checkpoint.CheckpointRestore(StartTraj, U, sRNG, pRNG); + } + + Smearing.set_Field(U); + + HybridMonteCarlo HMC(HMCpar, MDynamics, sRNG, pRNG, U); + + for (int obs = 0; obs < ObservablesList.size(); obs++) + HMC.AddObservable(ObservablesList[obs]); + + // Run it + HMC.evolve(); } + }; - int StartTraj = 0; - if (GridCmdOptionExists(argv, argv + argc, "--StartTrajectory")) { - arg = GridCmdOptionPayload(argv, argv + argc, "--StartTrajectory"); - std::vector ivec(0); - GridCmdOptionIntVector(arg, ivec); - StartTraj = ivec[0]; - } + // These are for gauge fields + typedef BinaryHmcRunnerTemplate BinaryHmcRunner; + typedef BinaryHmcRunnerTemplate BinaryHmcRunnerF; + typedef BinaryHmcRunnerTemplate BinaryHmcRunnerD; - int NumTraj = 1; - if (GridCmdOptionExists(argv, argv + argc, "--Trajectories")) { - arg = GridCmdOptionPayload(argv, argv + argc, "--Trajectories"); - std::vector ivec(0); - GridCmdOptionIntVector(arg, ivec); - NumTraj = ivec[0]; - } + template + using BinaryHmcRunnerTemplateHirep = BinaryHmcRunnerTemplate; - int NumThermalizations = 10; - if (GridCmdOptionExists(argv, argv + argc, "--Thermalizations")) { - arg = GridCmdOptionPayload(argv, argv + argc, "--Thermalizations"); - std::vector ivec(0); - GridCmdOptionIntVector(arg, ivec); - NumThermalizations = ivec[0]; - } - - GridSerialRNG sRNG; - GridParallelRNG pRNG(UGrid); - Field U(UGrid); - - typedef MinimumNorm2 - IntegratorType; // change here to change the algorithm - IntegratorType MDynamics(UGrid, MDparameters, TheAction, Smearing); - - HMCparameters HMCpar; - HMCpar.StartTrajectory = StartTraj; - HMCpar.Trajectories = NumTraj; - HMCpar.NoMetropolisUntil = NumThermalizations; - - if (StartType == HotStart) { - // Hot start - HMCpar.MetropolisTest = true; - sRNG.SeedFixedIntegers(SerialSeed); - pRNG.SeedFixedIntegers(ParallelSeed); - Implementation::HotConfiguration(pRNG, U); - } else if (StartType == ColdStart) { - // Cold start - HMCpar.MetropolisTest = true; - sRNG.SeedFixedIntegers(SerialSeed); - pRNG.SeedFixedIntegers(ParallelSeed); - Implementation::ColdConfiguration(pRNG, U); - } else if (StartType == TepidStart) { - // Tepid start - HMCpar.MetropolisTest = true; - sRNG.SeedFixedIntegers(SerialSeed); - pRNG.SeedFixedIntegers(ParallelSeed); - Implementation::TepidConfiguration(pRNG, U); - } else if (StartType == CheckpointStart) { - HMCpar.MetropolisTest = true; - // CheckpointRestart - Checkpoint.CheckpointRestore(StartTraj, U, sRNG, pRNG); - } - - Smearing.set_Field(U); - - HybridMonteCarlo HMC(HMCpar, MDynamics, sRNG, pRNG, U); - - for (int obs = 0; obs < ObservablesList.size(); obs++) - HMC.AddObservable(ObservablesList[obs]); - - // Run it - HMC.evolve(); - } -}; - -// These are for gauge fields -typedef BinaryHmcRunnerTemplate BinaryHmcRunner; -typedef BinaryHmcRunnerTemplate BinaryHmcRunnerF; -typedef BinaryHmcRunnerTemplate BinaryHmcRunnerD; - -template -using BinaryHmcRunnerTemplateHirep = - BinaryHmcRunnerTemplate; - - - - typedef BinaryHmcRunnerTemplate ScalarBinaryHmcRunner; + typedef BinaryHmcRunnerTemplate + ScalarBinaryHmcRunner; } } #endif diff --git a/lib/qcd/hmc/HMC.h b/lib/qcd/hmc/HMC.h index a30242d3..e39faae0 100644 --- a/lib/qcd/hmc/HMC.h +++ b/lib/qcd/hmc/HMC.h @@ -34,7 +34,6 @@ directory * @brief Classes for Hybrid Monte Carlo update * * @author Guido Cossu - * Time-stamp: <2015-07-30 16:58:26 neo> */ //-------------------------------------------------------------------- #ifndef HMC_INCLUDED diff --git a/lib/qcd/hmc/integrators/Integrator.h b/lib/qcd/hmc/integrators/Integrator.h index 43974f48..ec3d31fe 100644 --- a/lib/qcd/hmc/integrators/Integrator.h +++ b/lib/qcd/hmc/integrators/Integrator.h @@ -29,14 +29,6 @@ directory *************************************************************************************/ /* END LEGAL */ //-------------------------------------------------------------------- -/*! @file Integrator.h - * @brief Classes for the Molecular Dynamics integrator - * - * @author Guido Cossu - * Time-stamp: <2015-07-30 16:21:29 neo> - */ -//-------------------------------------------------------------------- - #ifndef INTEGRATOR_INCLUDED #define INTEGRATOR_INCLUDED diff --git a/lib/qcd/utils/WilsonLoops.h b/lib/qcd/utils/WilsonLoops.h index 3051f830..e47040ee 100644 --- a/lib/qcd/utils/WilsonLoops.h +++ b/lib/qcd/utils/WilsonLoops.h @@ -235,7 +235,7 @@ public: std::vector U(Nd, grid); for (int d = 0; d < Nd; d++) { - U[d] = PeekIndex(Umu, d); + U[d] = PeekIndex(Umu, d);// some redundant copies } // mu @@ -268,7 +268,7 @@ public: std::vector U(Nd, grid); for (int d = 0; d < Nd; d++) { - U[d] = PeekIndex(Umu, d); + U[d] = PeekIndex(Umu, d);// some redundant copies } // mu diff --git a/tests/hmc/Test_hmc_WilsonGauge_Binary.cc b/tests/hmc/Test_hmc_WilsonGauge_Binary.cc index 098e23e4..9a9c3e8e 100644 --- a/tests/hmc/Test_hmc_WilsonGauge_Binary.cc +++ b/tests/hmc/Test_hmc_WilsonGauge_Binary.cc @@ -79,12 +79,16 @@ class HmcRunner : public BinaryHmcRunner { // Gauge action int Ls = UGrid->_gdimensions[Nd - 1]; - std::vector betat(Ls,5); + std::vector betat(Ls); std::vector betas(Ls); - betas={5,6,6,5}; - //std:cout << "Betas:" << betas << std::endl; - //VariableWilsonGaugeActionR Waction(betas, betat, UGrid); - WilsonGaugeActionR Waction(5.6); + //betat={5,6,6,6,6,6,6,5}; + betat={1,1,1,0,1,1,1,1}; + //betas={5.2,5.5,5.8,6,6,5.8,5.5,5.2}; + betas={0,0,0,0,0,0,0,0}; + bool openBC = false; + std:cout << GridLogMessage << "Betas: " << betas << std::endl; + VariableWilsonGaugeActionR Waction(betas, betat, UGrid, openBC); + //WilsonGaugeActionR Waction(5.6); // Collect actions ActionLevel Level1(1); From e6acffdfc21c5e02ac3836abc43ad7324aa534b0 Mon Sep 17 00:00:00 2001 From: Guido Cossu Date: Fri, 21 Oct 2016 16:06:34 +0100 Subject: [PATCH 022/214] Fixing the plaquette computation --- lib/qcd/action/gauge/WilsonGaugeAction.h | 11 +++------- lib/qcd/utils/SUn.h | 3 +++ lib/qcd/utils/WilsonLoops.h | 12 ++++++++++ tests/hmc/Test_hmc_WilsonGauge_Binary.cc | 28 ++++++++++-------------- 4 files changed, 29 insertions(+), 25 deletions(-) diff --git a/lib/qcd/action/gauge/WilsonGaugeAction.h b/lib/qcd/action/gauge/WilsonGaugeAction.h index 059fcc58..8ac1df74 100644 --- a/lib/qcd/action/gauge/WilsonGaugeAction.h +++ b/lib/qcd/action/gauge/WilsonGaugeAction.h @@ -99,7 +99,7 @@ class VariableWilsonGaugeAction : public Action { public: VariableWilsonGaugeAction(std::vector bulk, std::vector xdim, - GridBase *_grid, bool openBC = false) + GridBase *_grid) : b_bulk(bulk), b_xdim(xdim), grid(_grid), @@ -130,11 +130,6 @@ class VariableWilsonGaugeAction : public Action { beta_xdim = where(coor == tau, temp, beta_xdim); } - if (!openBC) { - temp = b_xdim[Nex - 1]; - beta_xdim = where(coor == Nex - 1, temp, beta_xdim); - } - beta_xdim_shifted = Cshift(beta_xdim, Ndim - 1, -1); beta_bulk = zero; @@ -143,8 +138,7 @@ class VariableWilsonGaugeAction : public Action { beta_bulk = where(coor == tau, temp, beta_bulk); } - std::cout << beta_xdim << std::endl; - std::cout << beta_xdim_shifted << std::endl; + }; virtual void refresh(const GaugeField &U, @@ -180,6 +174,7 @@ class VariableWilsonGaugeAction : public Action { } } + double faces = (1.0 * (Nd - 1) * (Nd - 2)) / 2.0; SumdirPlaq *= OneOnNc / (RealD(bulk_volume) * faces); diff --git a/lib/qcd/utils/SUn.h b/lib/qcd/utils/SUn.h index 20cd1889..9ad3ca18 100644 --- a/lib/qcd/utils/SUn.h +++ b/lib/qcd/utils/SUn.h @@ -170,6 +170,7 @@ class SU { ta()()(i2, i1) = 1.0; ta = ta * 0.5; } + template static void generatorSigmaX(int su2Index, iSUnMatrix &ta) { ta = zero; @@ -194,6 +195,8 @@ class SU { ta = ta * nrm; } + + //////////////////////////////////////////////////////////////////////// // Map a su2 subgroup number to the pair of rows that are non zero //////////////////////////////////////////////////////////////////////// diff --git a/lib/qcd/utils/WilsonLoops.h b/lib/qcd/utils/WilsonLoops.h index e47040ee..19de7ab0 100644 --- a/lib/qcd/utils/WilsonLoops.h +++ b/lib/qcd/utils/WilsonLoops.h @@ -54,9 +54,21 @@ public: // resolution throughout the usage in this file, and rather defeats the // purpose of deriving // from Gimpl. + /* plaq = Gimpl::CovShiftBackward( U[mu], mu, Gimpl::CovShiftBackward( U[nu], nu, Gimpl::CovShiftForward(U[mu], mu, U[nu]))); + */ + // _ + //|< _| + plaq = Gimpl::CovShiftForward(U[mu],mu, + Gimpl::CovShiftForward(U[nu],nu, + Gimpl::CovShiftBackward(U[mu],mu, + Gimpl::CovShiftIdentityBackward(U[nu], nu)))); + + + + } ////////////////////////////////////////////////// // trace of directed plaquette oriented in mu,nu plane diff --git a/tests/hmc/Test_hmc_WilsonGauge_Binary.cc b/tests/hmc/Test_hmc_WilsonGauge_Binary.cc index 9a9c3e8e..a3bdbe4f 100644 --- a/tests/hmc/Test_hmc_WilsonGauge_Binary.cc +++ b/tests/hmc/Test_hmc_WilsonGauge_Binary.cc @@ -62,32 +62,26 @@ class HmcRunner : public BinaryHmcRunner { void BuildTheAction(int argc, char **argv) { + int Ndim=5; typedef WilsonImplR ImplPolicy; typedef WilsonFermionR FermionAction; typedef typename FermionAction::FermionField FermionField; - UGrid = SpaceTimeGrid::makeFourDimGrid( - GridDefaultLatt(), GridDefaultSimd(Nd, vComplex::Nsimd()), - GridDefaultMpi()); - UrbGrid = SpaceTimeGrid::makeFourDimRedBlackGrid(UGrid); + std::vector simd = GridDefaultSimd(Ndim-1,vComplex::Nsimd()); + simd.push_back(1); - FGrid = UGrid; - FrbGrid = UrbGrid; - // temporarily need a gauge field - LatticeGaugeField U(UGrid); + //UGrid = SpaceTimeGrid::makeFourDimGrid(GridDefaultLatt(), simd, GridDefaultMpi()); + UGrid = new GridCartesian(GridDefaultLatt(),simd,GridDefaultMpi()); // Gauge action - int Ls = UGrid->_gdimensions[Nd - 1]; - std::vector betat(Ls); - std::vector betas(Ls); - //betat={5,6,6,6,6,6,6,5}; - betat={1,1,1,0,1,1,1,1}; - //betas={5.2,5.5,5.8,6,6,5.8,5.5,5.2}; - betas={0,0,0,0,0,0,0,0}; - bool openBC = false; + int Ls = UGrid->_fdimensions[Nd - 1]; + std::vector betat(Ls,6.0); + std::vector betas(Ls,5.6); + betat[Ls-1]= 0.0; + betas={5.2,5.5,5.8,6,6,5.8,5.5,5.2}; std:cout << GridLogMessage << "Betas: " << betas << std::endl; - VariableWilsonGaugeActionR Waction(betas, betat, UGrid, openBC); + VariableWilsonGaugeActionR Waction(betas, betat, UGrid); //WilsonGaugeActionR Waction(5.6); // Collect actions From cccd14b09edae68bf4cf7489ecf374fc53c200bd Mon Sep 17 00:00:00 2001 From: Guido Cossu Date: Fri, 21 Oct 2016 17:20:54 +0100 Subject: [PATCH 023/214] Small cleanup --- lib/qcd/action/Actions.h | 3 - lib/qcd/action/gauge/WilsonGaugeAction.h | 186 ----------------------- tests/hmc/Test_hmc_WilsonGauge_Binary.cc | 18 +-- 3 files changed, 3 insertions(+), 204 deletions(-) diff --git a/lib/qcd/action/Actions.h b/lib/qcd/action/Actions.h index ef2edc97..20023455 100644 --- a/lib/qcd/action/Actions.h +++ b/lib/qcd/action/Actions.h @@ -72,9 +72,6 @@ namespace QCD { typedef WilsonGaugeAction WilsonGaugeActionR; typedef WilsonGaugeAction WilsonGaugeActionF; typedef WilsonGaugeAction WilsonGaugeActionD; -typedef VariableWilsonGaugeAction VariableWilsonGaugeActionR; -typedef VariableWilsonGaugeAction VariableWilsonGaugeActionF; -typedef VariableWilsonGaugeAction VariableWilsonGaugeActionD; typedef PlaqPlusRectangleAction PlaqPlusRectangleActionR; typedef PlaqPlusRectangleAction PlaqPlusRectangleActionF; diff --git a/lib/qcd/action/gauge/WilsonGaugeAction.h b/lib/qcd/action/gauge/WilsonGaugeAction.h index 8ac1df74..b9216d78 100644 --- a/lib/qcd/action/gauge/WilsonGaugeAction.h +++ b/lib/qcd/action/gauge/WilsonGaugeAction.h @@ -82,193 +82,7 @@ class WilsonGaugeAction : public Action { }; }; -template -class VariableWilsonGaugeAction : public Action { - public: - INHERIT_GIMPL_TYPES(Gimpl); - private: - std::vector b_bulk; // bulk couplings - std::vector b_xdim; // extra dimension couplings - GridBase *grid; - LatticeComplex beta_xdim; - LatticeComplex beta_xdim_shifted; - LatticeComplex beta_bulk; - - int bulk_volume; - - public: - VariableWilsonGaugeAction(std::vector bulk, std::vector xdim, - GridBase *_grid) - : b_bulk(bulk), - b_xdim(xdim), - grid(_grid), - beta_xdim(grid), - beta_xdim_shifted(grid), - beta_bulk(grid) { - // check that the grid is ok - // todo - int Ndim = Nd; // change later - - std::vector FullDim = grid->GlobalDimensions(); - bulk_volume = 1; - for (int s = 0; s < Ndim - 1; s++) bulk_volume *= FullDim[s]; - - LatticeComplex temp(grid); - - Lattice > coor(grid); - - LatticeCoordinate(coor, Ndim - 1); - - int Nex = FullDim[Ndim - 1]; - assert(b_bulk.size() == Nex); - assert(b_xdim.size() == Nex); - - beta_xdim = zero; - for (int tau = 0; tau < Nex - 1; tau++) { - temp = b_xdim[tau]; - beta_xdim = where(coor == tau, temp, beta_xdim); - } - - beta_xdim_shifted = Cshift(beta_xdim, Ndim - 1, -1); - - beta_bulk = zero; - for (int tau = 0; tau < Nex; tau++) { - temp = b_bulk[tau]; - beta_bulk = where(coor == tau, temp, beta_bulk); - } - - - }; - - virtual void refresh(const GaugeField &U, - GridParallelRNG &pRNG){}; // noop as no pseudoferms - - virtual RealD S(const GaugeField &Umu) { - int Ndim = Nd; // change later for generality - conformable(grid, Umu._grid); - - std::vector U(Ndim, grid); - - for (int mu = 0; mu < Ndim; mu++) { - U[mu] = PeekIndex(Umu, mu); - } - - LatticeComplex dirPlaq(grid); - LatticeComplex Plaq(grid); - - LatticeComplex SumdirPlaq(grid); - - RealD OneOnNc = 1.0 / Real(Nc); - - ///////////// - // Lower dim plaquettes - ///////////// - Plaq = zero; - SumdirPlaq = zero; - for (int mu = 1; mu < Ndim - 1; mu++) { - for (int nu = 0; nu < mu; nu++) { - WilsonLoops::traceDirPlaquette(dirPlaq, U, mu, nu); - SumdirPlaq += dirPlaq; - Plaq = Plaq + (1.0 - dirPlaq * OneOnNc) * beta_bulk; - } - } - - - double faces = (1.0 * (Nd - 1) * (Nd - 2)) / 2.0; - SumdirPlaq *= OneOnNc / (RealD(bulk_volume) * faces); - - // print slices in the extra dimension - int Nex = grid->_fdimensions[Ndim - 1]; - std::vector plaq_ex(Nex); - sliceSum(SumdirPlaq, plaq_ex, Ndim - 1); - for (int ex = 0; ex < Nex; ex++) - std::cout << GridLogMessage << "Bulk plaq[" << ex - << "] = " << TensorRemove(plaq_ex[ex]).real() << std::endl; - - ///////////// - // Extra dimension - ///////////// - { - int mu = Ndim - 1; - for (int nu = 0; nu < mu; nu++) { - WilsonLoops::traceDirPlaquette(dirPlaq, U, mu, nu); - Plaq = Plaq + (1.0 - dirPlaq * OneOnNc) * beta_xdim; - } - } - - TComplex Tp = sum(Plaq); - Complex p = TensorRemove(Tp); - RealD action = p.real(); - return action; - }; - - virtual void deriv(const GaugeField &U, GaugeField &dSdU) { - // not optimal implementation FIXME - // extend Ta to include Lorentz indexes - - // for the higher dimension plaquettes take the upper plaq of the - // 4d slice and multiply by beta[s] and the lower and multiply by beta[s-1] - // derivative of links mu = 0, ... Nd-1 inside plaq (mu,5) - // for these I need upper and lower staples separated - // each multiplied with their own beta - // derivative of links mu = 5 - // living on the same slice, share the same beta - - conformable(grid, U._grid); - int Ndim = Nd; // change later - RealD factor = 0.5 / RealD(Nc); - - GaugeLinkField Umu(grid); - GaugeLinkField dSdU_mu(grid); - GaugeLinkField staple(grid); - - for (int mu = 0; mu < Ndim; mu++) { - Umu = PeekIndex(U, mu); - dSdU_mu = zero; - - for (int nu = 0; nu < Ndim; nu++) { - if (nu != mu) { - if ((mu < (Ndim - 1)) && (nu < (Ndim - 1))) { - // Spacelike case apply beta space - WilsonLoops::Staple(staple, U, mu, nu); - staple = staple * beta_bulk; - dSdU_mu += staple; - - } else if (mu == (Ndim - 1)) { - // nu space; mu time link - assert(nu < (Ndim - 1)); - assert(mu == (Ndim - 1)); - - // mu==tau dir link deriv, nu spatial - WilsonLoops::Staple(staple, U, mu, nu); - staple = staple * beta_xdim; - dSdU_mu += staple; - - } else { - assert(mu < (Ndim - 1)); - assert(nu == (Ndim - 1)); - - // nu time; mu space link - - // staple forwards in tau - WilsonLoops::StapleUpper(staple, U, mu, nu); - staple = staple * beta_xdim; - dSdU_mu += staple; - - // staple backwards in tau - WilsonLoops::StapleLower(staple, U, mu, nu); - staple = staple * beta_xdim_shifted; - dSdU_mu += staple; - } - } - } - - dSdU_mu = Ta(Umu * dSdU_mu) * factor; - PokeIndex(dSdU, dSdU_mu, mu); - } - }; -}; } } diff --git a/tests/hmc/Test_hmc_WilsonGauge_Binary.cc b/tests/hmc/Test_hmc_WilsonGauge_Binary.cc index a3bdbe4f..977ca1c8 100644 --- a/tests/hmc/Test_hmc_WilsonGauge_Binary.cc +++ b/tests/hmc/Test_hmc_WilsonGauge_Binary.cc @@ -62,27 +62,15 @@ class HmcRunner : public BinaryHmcRunner { void BuildTheAction(int argc, char **argv) { - int Ndim=5; typedef WilsonImplR ImplPolicy; typedef WilsonFermionR FermionAction; typedef typename FermionAction::FermionField FermionField; - std::vector simd = GridDefaultSimd(Ndim-1,vComplex::Nsimd()); - simd.push_back(1); - - - //UGrid = SpaceTimeGrid::makeFourDimGrid(GridDefaultLatt(), simd, GridDefaultMpi()); - UGrid = new GridCartesian(GridDefaultLatt(),simd,GridDefaultMpi()); + UGrid = SpaceTimeGrid::makeFourDimGrid(GridDefaultLatt(), GridDefaultSimd(Nd, vComplex::Nsimd()), GridDefaultMpi()); + // Gauge action - int Ls = UGrid->_fdimensions[Nd - 1]; - std::vector betat(Ls,6.0); - std::vector betas(Ls,5.6); - betat[Ls-1]= 0.0; - betas={5.2,5.5,5.8,6,6,5.8,5.5,5.2}; - std:cout << GridLogMessage << "Betas: " << betas << std::endl; - VariableWilsonGaugeActionR Waction(betas, betat, UGrid); - //WilsonGaugeActionR Waction(5.6); + WilsonGaugeActionR Waction(5.6); // Collect actions ActionLevel Level1(1); From 4b740fc8fd8b01206f1c90d12af2b005f163afc9 Mon Sep 17 00:00:00 2001 From: Guido Cossu Date: Sat, 22 Oct 2016 13:06:00 +0100 Subject: [PATCH 024/214] Debugging the RNG state save --- lib/parallelIO/BinaryIO.h | 153 +++++++++++++++++++++----------------- lib/qcd/QCD.h | 2 +- 2 files changed, 87 insertions(+), 68 deletions(-) diff --git a/lib/parallelIO/BinaryIO.h b/lib/parallelIO/BinaryIO.h index cdcb1989..8b2d9223 100644 --- a/lib/parallelIO/BinaryIO.h +++ b/lib/parallelIO/BinaryIO.h @@ -6,8 +6,8 @@ Copyright (C) 2015 -Author: Peter Boyle -Author: paboyle + Author: Peter Boyle + Author: Guido Cossu 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 @@ -239,9 +239,9 @@ class BinaryIO { fin.read((char *)&file_object, sizeof(file_object)); bytes += sizeof(file_object); if (ieee32big) be32toh_v((void *)&file_object, sizeof(file_object)); - if (ieee32) le32toh_v((void *)&file_object, sizeof(file_object)); + if (ieee32) le32toh_v((void *)&file_object, sizeof(file_object)); if (ieee64big) be64toh_v((void *)&file_object, sizeof(file_object)); - if (ieee64) le64toh_v((void *)&file_object, sizeof(file_object)); + if (ieee64) le64toh_v((void *)&file_object, sizeof(file_object)); munge(file_object, munged, csum); } @@ -258,7 +258,7 @@ class BinaryIO { template static inline uint32_t writeObjectSerial(Lattice &Umu,std::string file,munger munge,int offset,const std::string & format) { - typedef typename vobj::scalar_object sobj; + typedef typename vobj::scalar_object sobj; GridBase *grid = Umu._grid; @@ -295,15 +295,15 @@ class BinaryIO { if ( grid->IsBoss() ) { - - if(ieee32big) htobe32_v((void *)&file_object,sizeof(file_object)); - if(ieee32) htole32_v((void *)&file_object,sizeof(file_object)); - if(ieee64big) htobe64_v((void *)&file_object,sizeof(file_object)); - if(ieee64) htole64_v((void *)&file_object,sizeof(file_object)); - // NB could gather an xstrip as an optimisation. - fout.write((char *)&file_object,sizeof(file_object)); - bytes+=sizeof(file_object); + if(ieee32big) htobe32_v((void *)&file_object,sizeof(file_object)); + if(ieee32) htole32_v((void *)&file_object,sizeof(file_object)); + if(ieee64big) htobe64_v((void *)&file_object,sizeof(file_object)); + if(ieee64) htole64_v((void *)&file_object,sizeof(file_object)); + + // NB could gather an xstrip as an optimisation. + fout.write((char *)&file_object,sizeof(file_object)); + bytes+=sizeof(file_object); } }}}} timer.Stop(); @@ -313,15 +313,14 @@ class BinaryIO { return csum; } - static inline uint32_t writeRNGSerial(GridSerialRNG &serial, - GridParallelRNG ¶llel, - std::string file, int offset) { + static inline uint32_t writeRNGSerial(GridSerialRNG &serial, GridParallelRNG ¶llel, std::string file, int offset) { typedef typename GridSerialRNG::RngStateType RngStateType; const int RngStateCount = GridSerialRNG::RngStateCount; GridBase *grid = parallel._grid; int gsites = grid->_gsites; + GridStopWatch timer; timer.Start(); ////////////////////////////////////////////////// // Serialise through node zero ////////////////////////////////////////////////// @@ -329,19 +328,21 @@ class BinaryIO { if (grid->IsBoss()) { fout.open(file, std::ios::binary | std::ios::out | std::ios::in); if (!fout.is_open()) { - std::cout << GridLogMessage << "writeRNGSerial: Error opening file " - << file << std::endl; - exit(0); + std::cout << GridLogMessage << "writeRNGSerial: Error opening file " << file << std::endl; + exit(0);// write better error handling } fout.seekp(offset); } - std::cout << GridLogMessage << "Serial RNG write I/O " << file << std::endl; + std::cout << GridLogMessage << "Serial RNG write I/O on file " << file << std::endl; uint32_t csum = 0; std::vector saved(RngStateCount); int bytes = sizeof(RngStateType) * saved.size(); + std::cout << GridLogDebug << "RngStateCount: " << RngStateCount << std::endl; + std::cout << GridLogDebug << "Type has " << bytes << " bytes" << std::endl; std::vector gcoor; + std::cout << GridLogDebug << "gsites: " << gsites << " loop" << std::endl; for (int gidx = 0; gidx < gsites; gidx++) { int rank, o_idx, i_idx; grid->GlobalIndexToGlobalCoor(gidx, gcoor); @@ -349,12 +350,10 @@ class BinaryIO { int l_idx = parallel.generator_idx(o_idx, i_idx); if (rank == grid->ThisRank()) { - // std::cout << "rank" << rank<<" Getting state for index - // "<Broadcast(rank, (void *)&saved[0], bytes); + grid->Broadcast(rank, (void *)&saved[0], bytes); + } if (grid->IsBoss()) { Uint32Checksum((uint32_t *)&saved[0], bytes, csum); @@ -367,15 +366,21 @@ class BinaryIO { Uint32Checksum((uint32_t *)&saved[0], bytes, csum); fout.write((char *)&saved[0], bytes); } + grid->Broadcast(0, (void *)&csum, sizeof(csum)); if (grid->IsBoss()) fout.close(); - std::cout << GridLogMessage << "RNG file checksum " << std::hex << csum << std::dec << std::endl; - + timer.Stop(); + + std::cout << GridLogMessage << "RNG file checksum " << std::hex << csum << std::dec << std::endl; + std::cout << GridLogMessage << "RNG state saved in " << timer.Elapsed() << " " + << timer.useconds() <<" us" <IsBoss()) { + fin.open(file, std::ios::binary | std::ios::in); + if (!fin.is_open()) { + std::cout << GridLogMessage << "readRNGSerial: Error opening file " << file << std::endl; + exit(0);// write better error handling + } + fin.seekg(offset); + } - std::ifstream fin(file,std::ios::binary|std::ios::in); - fin.seekg(offset); uint32_t csum=0; std::vector saved(RngStateCount); int bytes = sizeof(RngStateType)*saved.size(); + std::cout << GridLogDebug << "RngStateCount: " << RngStateCount << std::endl; + std::cout << GridLogDebug << "Type has " << bytes << " bytes" << std::endl; std::vector gcoor; + std::cout << GridLogDebug << "gsites: " << gsites << " loop" << std::endl; for(int gidx=0;gidxIsBoss() ) { - fin.read((char *)&saved[0],bytes); - Uint32Checksum((uint32_t *)&saved[0],bytes,csum); - } + fin.read((char *)&saved[0],bytes); + Uint32Checksum((uint32_t *)&saved[0],bytes,csum); - grid->Broadcast(0,(void *)&saved[0],bytes); + + grid->Broadcast(0,(void *)&saved[0],bytes); + } if( rank == grid->ThisRank() ){ - parallel.SetState(saved,l_idx); + parallel.SetState(saved,l_idx); } - } if ( grid->IsBoss() ) { @@ -467,15 +483,15 @@ class BinaryIO { if ( d == 0 ) parallel[d] = 0; if (parallel[d]) { - range[d] = grid->_ldimensions[d]; - start[d] = grid->_processor_coor[d]*range[d]; - ioproc[d]= grid->_processor_coor[d]; + range[d] = grid->_ldimensions[d]; + start[d] = grid->_processor_coor[d]*range[d]; + ioproc[d]= grid->_processor_coor[d]; } else { - range[d] = grid->_gdimensions[d]; - start[d] = 0; - ioproc[d]= 0; + range[d] = grid->_gdimensions[d]; + start[d] = 0; + ioproc[d]= 0; - if ( grid->_processor_coor[d] != 0 ) IOnode = 0; + if ( grid->_processor_coor[d] != 0 ) IOnode = 0; } slice_vol = slice_vol * range[d]; } @@ -486,9 +502,9 @@ class BinaryIO { std::cout<< std::dec ; std::cout<< GridLogMessage<< "Parallel read I/O to "<< file << " with " <_ndimension;d++){ - std::cout<< range[d]; - if( d< grid->_ndimension-1 ) - std::cout<< " x "; + std::cout<< range[d]; + if( d< grid->_ndimension-1 ) + std::cout<< " x "; } std::cout << std::endl; } @@ -515,7 +531,7 @@ class BinaryIO { // need to implement these loops in Nd independent way with a lexico conversion for(int tlex=0;tlex tsite(nd); // temporary mixed up site std::vector gsite(nd); std::vector lsite(nd); @@ -523,11 +539,14 @@ class BinaryIO { Lexicographic::CoorFromIndex(tsite,tlex,range); - for(int d=0;d_ldimensions[d]; // local site - gsite[d] = tsite[d]+start[d]; // global site + for(int d=0; d_ldimensions[d]; // local site + gsite[d] = tsite[d]+start[d]; // global site } + ///////////////////////// // Get the rank of owner of data ///////////////////////// @@ -539,29 +558,29 @@ class BinaryIO { // iorank reads from the seek //////////////////////////////// if (myrank == iorank) { - - fin.seekg(offset+g_idx*sizeof(fileObj)); - fin.read((char *)&fileObj,sizeof(fileObj)); - bytes+=sizeof(fileObj); - - if(ieee32big) be32toh_v((void *)&fileObj,sizeof(fileObj)); - if(ieee32) le32toh_v((void *)&fileObj,sizeof(fileObj)); - if(ieee64big) be64toh_v((void *)&fileObj,sizeof(fileObj)); - if(ieee64) le64toh_v((void *)&fileObj,sizeof(fileObj)); - - munge(fileObj,siteObj,csum); + + fin.seekg(offset+g_idx*sizeof(fileObj)); + fin.read((char *)&fileObj,sizeof(fileObj)); + bytes+=sizeof(fileObj); + + if(ieee32big) be32toh_v((void *)&fileObj,sizeof(fileObj)); + if(ieee32) le32toh_v((void *)&fileObj,sizeof(fileObj)); + if(ieee64big) be64toh_v((void *)&fileObj,sizeof(fileObj)); + if(ieee64) le64toh_v((void *)&fileObj,sizeof(fileObj)); + + munge(fileObj,siteObj,csum); } // Possibly do transport through pt2pt if ( rank != iorank ) { - if ( (myrank == rank) || (myrank==iorank) ) { - grid->SendRecvPacket((void *)&siteObj,(void *)&siteObj,iorank,rank,sizeof(siteObj)); - } + if ( (myrank == rank) || (myrank==iorank) ) { + grid->SendRecvPacket((void *)&siteObj,(void *)&siteObj,iorank,rank,sizeof(siteObj)); + } } // Poke at destination if ( myrank == rank ) { - pokeLocalSite(siteObj,Umu,lsite); + pokeLocalSite(siteObj,Umu,lsite); } grid->Barrier(); // necessary? } @@ -571,8 +590,8 @@ class BinaryIO { grid->Barrier(); timer.Stop(); - std::cout<Barrier(); // necessary? - if (IOnode) + if (IOnode) fout.close(); return csum; diff --git a/lib/qcd/QCD.h b/lib/qcd/QCD.h index 0d8c28bc..e08c3dc8 100644 --- a/lib/qcd/QCD.h +++ b/lib/qcd/QCD.h @@ -46,7 +46,7 @@ namespace QCD { static const int Nc=3; static const int Ns=4; - static const int Nd=5; + static const int Nd=4; static const int Nhs=2; // half spinor static const int Nds=8; // double stored gauge field static const int Ngp=2; // gparity index range From 3e990c9d0ac1d0546126140a798391e65d6e1cad Mon Sep 17 00:00:00 2001 From: Guido Cossu Date: Sat, 22 Oct 2016 13:26:43 +0100 Subject: [PATCH 025/214] Reverting the broadcast change --- lib/lattice/Lattice_rng.h | 4 ++-- lib/parallelIO/BinaryIO.h | 9 ++++----- 2 files changed, 6 insertions(+), 7 deletions(-) diff --git a/lib/lattice/Lattice_rng.h b/lib/lattice/Lattice_rng.h index ae61224a..52dd627f 100644 --- a/lib/lattice/Lattice_rng.h +++ b/lib/lattice/Lattice_rng.h @@ -130,14 +130,14 @@ namespace Grid { ss<<_generators[gen]; ss.seekg(0,ss.beg); for(int i=0;i>saved[i]; + ss>>saved[i]; } } void SetState(std::vector & saved,int gen){ assert(saved.size()==RngStateCount); std::stringstream ss; for(int i=0;i>_generators[gen]; diff --git a/lib/parallelIO/BinaryIO.h b/lib/parallelIO/BinaryIO.h index 8b2d9223..75e732ad 100644 --- a/lib/parallelIO/BinaryIO.h +++ b/lib/parallelIO/BinaryIO.h @@ -348,12 +348,12 @@ class BinaryIO { grid->GlobalIndexToGlobalCoor(gidx, gcoor); grid->GlobalCoorToRankIndex(rank, o_idx, i_idx, gcoor); int l_idx = parallel.generator_idx(o_idx, i_idx); + std::cout << GridLogDebug << "l_idx "<< l_idx << " o_idx " << o_idx << " i_idx " << i_idx << std::endl; if (rank == grid->ThisRank()) { parallel.GetState(saved, l_idx); - - grid->Broadcast(rank, (void *)&saved[0], bytes); } + grid->Broadcast(rank, (void *)&saved[0], bytes); if (grid->IsBoss()) { Uint32Checksum((uint32_t *)&saved[0], bytes, csum); @@ -419,14 +419,13 @@ class BinaryIO { grid->GlobalIndexToGlobalCoor(gidx,gcoor); grid->GlobalCoorToRankIndex(rank,o_idx,i_idx,gcoor); int l_idx=parallel.generator_idx(o_idx,i_idx); + std::cout << GridLogDebug << "l_idx "<< l_idx << " o_idx " << o_idx << " i_idx " << i_idx << std::endl; if ( grid->IsBoss() ) { fin.read((char *)&saved[0],bytes); Uint32Checksum((uint32_t *)&saved[0],bytes,csum); - - - grid->Broadcast(0,(void *)&saved[0],bytes); } + grid->Broadcast(0,(void *)&saved[0],bytes); if( rank == grid->ThisRank() ){ parallel.SetState(saved,l_idx); From df67e013ca66267dc0acc0ef93af63717cea68fd Mon Sep 17 00:00:00 2001 From: Guido Cossu Date: Sat, 22 Oct 2016 13:34:17 +0100 Subject: [PATCH 026/214] More debug output for the RNG --- lib/parallelIO/BinaryIO.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/lib/parallelIO/BinaryIO.h b/lib/parallelIO/BinaryIO.h index 75e732ad..5410f5c9 100644 --- a/lib/parallelIO/BinaryIO.h +++ b/lib/parallelIO/BinaryIO.h @@ -356,6 +356,7 @@ class BinaryIO { grid->Broadcast(rank, (void *)&saved[0], bytes); if (grid->IsBoss()) { + std::cout << "Saved: " << saved << std::endl; Uint32Checksum((uint32_t *)&saved[0], bytes, csum); fout.write((char *)&saved[0], bytes); } @@ -429,6 +430,7 @@ class BinaryIO { if( rank == grid->ThisRank() ){ parallel.SetState(saved,l_idx); + std::cout << "Saved: " << saved << std::endl; } } From f55c16f9846f70808597bfff3792396957619c3f Mon Sep 17 00:00:00 2001 From: Guido Cossu Date: Mon, 24 Oct 2016 11:02:14 +0100 Subject: [PATCH 027/214] Adding a barrier in the RNG save --- configure.ac | 3 +- lib/lattice/Lattice_rng.h | 30 +++++++------- lib/parallelIO/BinaryIO.h | 34 +++++++++------- lib/qcd/hmc/GenericHMCrunner.h | 2 + lib/serialisation/TextIO.cc | 20 ++++++---- tests/hmc/Test_hmc_EODWFRatio_Binary.cc | 51 ++++++++++++------------ tests/hmc/Test_hmc_WilsonGauge_Binary.cc | 36 +++++++++-------- 7 files changed, 96 insertions(+), 80 deletions(-) diff --git a/configure.ac b/configure.ac index 7bcdc49f..0f3a3018 100644 --- a/configure.ac +++ b/configure.ac @@ -359,4 +359,5 @@ Summary of configuration for $PACKAGE v$VERSION - LIBS: `echo ${LIBS} | tr ' ' '\n' | sed 's/^-/ -/g'` ------------------------------------------------------- -" +" > grid.configure.summary +cat grid.configure.summary diff --git a/lib/lattice/Lattice_rng.h b/lib/lattice/Lattice_rng.h index 52dd627f..10c21d4a 100644 --- a/lib/lattice/Lattice_rng.h +++ b/lib/lattice/Lattice_rng.h @@ -291,24 +291,24 @@ namespace Grid { for(int gidx=0;gidxGlobalIndexToGlobalCoor(gidx,gcoor); - _grid->GlobalCoorToRankIndex(rank,o_idx,i_idx,gcoor); + int rank,o_idx,i_idx; + _grid->GlobalIndexToGlobalCoor(gidx,gcoor); + _grid->GlobalCoorToRankIndex(rank,o_idx,i_idx,gcoor); - int l_idx=generator_idx(o_idx,i_idx); - - std::vector site_seeds(4); - for(int i=0;i<4;i++){ - site_seeds[i]= ui(pseeder); - } + int l_idx=generator_idx(o_idx,i_idx); + + std::vector site_seeds(4); + for(int i=0;i<4;i++){ + site_seeds[i]= ui(pseeder); + } - _grid->Broadcast(0,(void *)&site_seeds[0],sizeof(int)*site_seeds.size()); + _grid->Broadcast(0,(void *)&site_seeds[0],sizeof(int)*site_seeds.size()); - if( rank == _grid->ThisRank() ){ - fixedSeed ssrc(site_seeds); - typename source::result_type sinit = ssrc(); - _generators[l_idx] = RngEngine(sinit); - } + if( rank == _grid->ThisRank() ){ + fixedSeed ssrc(site_seeds); + typename source::result_type sinit = ssrc(); + _generators[l_idx] = RngEngine(sinit); + } } _seeded=1; } diff --git a/lib/parallelIO/BinaryIO.h b/lib/parallelIO/BinaryIO.h index 5410f5c9..abba1880 100644 --- a/lib/parallelIO/BinaryIO.h +++ b/lib/parallelIO/BinaryIO.h @@ -258,7 +258,7 @@ class BinaryIO { template static inline uint32_t writeObjectSerial(Lattice &Umu,std::string file,munger munge,int offset,const std::string & format) { - typedef typename vobj::scalar_object sobj; + typedef typename vobj::scalar_object sobj; GridBase *grid = Umu._grid; @@ -296,14 +296,14 @@ class BinaryIO { if ( grid->IsBoss() ) { - if(ieee32big) htobe32_v((void *)&file_object,sizeof(file_object)); - if(ieee32) htole32_v((void *)&file_object,sizeof(file_object)); - if(ieee64big) htobe64_v((void *)&file_object,sizeof(file_object)); - if(ieee64) htole64_v((void *)&file_object,sizeof(file_object)); + if(ieee32big) htobe32_v((void *)&file_object,sizeof(file_object)); + if(ieee32) htole32_v((void *)&file_object,sizeof(file_object)); + if(ieee64big) htobe64_v((void *)&file_object,sizeof(file_object)); + if(ieee64) htole64_v((void *)&file_object,sizeof(file_object)); - // NB could gather an xstrip as an optimisation. - fout.write((char *)&file_object,sizeof(file_object)); - bytes+=sizeof(file_object); + // NB could gather an xstrip as an optimisation. + fout.write((char *)&file_object,sizeof(file_object)); + bytes+=sizeof(file_object); } }}}} timer.Stop(); @@ -326,7 +326,7 @@ class BinaryIO { ////////////////////////////////////////////////// std::ofstream fout; if (grid->IsBoss()) { - fout.open(file, std::ios::binary | std::ios::out | std::ios::in); + fout.open(file, std::ios::binary | std::ios::out); if (!fout.is_open()) { std::cout << GridLogMessage << "writeRNGSerial: Error opening file " << file << std::endl; exit(0);// write better error handling @@ -348,20 +348,23 @@ class BinaryIO { grid->GlobalIndexToGlobalCoor(gidx, gcoor); grid->GlobalCoorToRankIndex(rank, o_idx, i_idx, gcoor); int l_idx = parallel.generator_idx(o_idx, i_idx); - std::cout << GridLogDebug << "l_idx "<< l_idx << " o_idx " << o_idx << " i_idx " << i_idx << std::endl; - + std::cout << GridLogDebug << "l_idx " << l_idx << " o_idx " << o_idx + << " i_idx " << i_idx << " rank " << rank << std::endl; if (rank == grid->ThisRank()) { parallel.GetState(saved, l_idx); } grid->Broadcast(rank, (void *)&saved[0], bytes); + grid->Barrier(); // necessary? if (grid->IsBoss()) { std::cout << "Saved: " << saved << std::endl; Uint32Checksum((uint32_t *)&saved[0], bytes, csum); fout.write((char *)&saved[0], bytes); } + grid->Barrier(); // this can be necessary } + if (grid->IsBoss()) { serial.GetState(saved, 0); Uint32Checksum((uint32_t *)&saved[0], bytes, csum); @@ -376,8 +379,7 @@ class BinaryIO { timer.Stop(); std::cout << GridLogMessage << "RNG file checksum " << std::hex << csum << std::dec << std::endl; - std::cout << GridLogMessage << "RNG state saved in " << timer.Elapsed() << " " - << timer.useconds() <<" us" <GlobalIndexToGlobalCoor(gidx,gcoor); grid->GlobalCoorToRankIndex(rank,o_idx,i_idx,gcoor); int l_idx=parallel.generator_idx(o_idx,i_idx); - std::cout << GridLogDebug << "l_idx "<< l_idx << " o_idx " << o_idx << " i_idx " << i_idx << std::endl; + std::cout << GridLogDebug << "l_idx " << l_idx << " o_idx " << o_idx + << " i_idx " << i_idx << " rank " << rank << std::endl; if ( grid->IsBoss() ) { fin.read((char *)&saved[0],bytes); + std::cout << "Saved: " << saved << std::endl; Uint32Checksum((uint32_t *)&saved[0],bytes,csum); } + grid->Broadcast(0,(void *)&saved[0],bytes); if( rank == grid->ThisRank() ){ parallel.SetState(saved,l_idx); - std::cout << "Saved: " << saved << std::endl; } } diff --git a/lib/qcd/hmc/GenericHMCrunner.h b/lib/qcd/hmc/GenericHMCrunner.h index 047b9c9e..fbf26156 100644 --- a/lib/qcd/hmc/GenericHMCrunner.h +++ b/lib/qcd/hmc/GenericHMCrunner.h @@ -139,10 +139,12 @@ namespace QCD { GridParallelRNG pRNG(UGrid); Field U(UGrid); + typedef MinimumNorm2 IntegratorType; // change here to change the algorithm + IntegratorType MDynamics(UGrid, MDparameters, TheAction, Smearing); HMCparameters HMCpar; diff --git a/lib/serialisation/TextIO.cc b/lib/serialisation/TextIO.cc index 39b987d0..9d733099 100644 --- a/lib/serialisation/TextIO.cc +++ b/lib/serialisation/TextIO.cc @@ -6,8 +6,9 @@ Copyright (C) 2015 -Author: Antonin Portelli -Author: paboyle + Author: Antonin Portelli + Author: paboyle + Author: Guido Cossu 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 @@ -50,14 +51,19 @@ void TextWriter::indent(void) { for (int i = 0; i < level_; ++i) { - file_ << '\t'; + file_ << '\t';//is this portable? } }; // Reader implementation /////////////////////////////////////////////////////// -TextReader::TextReader(const string &fileName) -: file_(fileName, ios::in) -{} +TextReader::TextReader(const string &fileName) +{ + file_.open(fileName, ios::in); + if (!file_.is_open()) { + std::cout << GridLogMessage << "TextReader: Error opening file " << fileName << std::endl; + exit(0);// write better error handling + } +} void TextReader::push(const string &s) { @@ -78,7 +84,7 @@ void TextReader::checkIndent(void) file_.get(c); if (c != '\t') { - cerr << "mismatch on tab " << c << " level " << level_; + cerr << "TextReader: mismatch on tab " << c << " level " << level_; cerr << " i "<< i << endl; abort(); } diff --git a/tests/hmc/Test_hmc_EODWFRatio_Binary.cc b/tests/hmc/Test_hmc_EODWFRatio_Binary.cc index 0b912c66..44d4f44b 100644 --- a/tests/hmc/Test_hmc_EODWFRatio_Binary.cc +++ b/tests/hmc/Test_hmc_EODWFRatio_Binary.cc @@ -37,28 +37,28 @@ using namespace Grid::QCD; namespace Grid { namespace QCD { -class HMCRunnerParameters : Serializable { - public: - GRID_SERIALIZABLE_CLASS_MEMBERS(HMCRunnerParameters, - double, beta, - double, mass, - int, MaxCGIterations, - double, StoppingCondition, - bool, smearedAction, - int, SaveInterval, - std::string, format, - std::string, conf_prefix, - std::string, rng_prefix, - double, rho, - int, SmearingLevels, - ); + class HMCRunnerParameters : Serializable { + public: + GRID_SERIALIZABLE_CLASS_MEMBERS(HMCRunnerParameters, + double, beta, + double, mass, + int, MaxCGIterations, + double, StoppingCondition, + bool, smearedAction, + int, SaveInterval, + std::string, format, + std::string, conf_prefix, + std::string, rng_prefix, + double, rho, + int, SmearingLevels, + ); - HMCRunnerParameters() {} -}; + HMCRunnerParameters() {} + }; // Derive from the BinaryHmcRunner (templated for gauge fields) class HmcRunner : public BinaryHmcRunner { - public: +public: void BuildTheAction(int argc, char **argv) { @@ -70,7 +70,7 @@ class HmcRunner : public BinaryHmcRunner { UGrid = SpaceTimeGrid::makeFourDimGrid(GridDefaultLatt(), GridDefaultSimd(Nd,vComplex::Nsimd()),GridDefaultMpi()); UrbGrid = SpaceTimeGrid::makeFourDimRedBlackGrid(UGrid); - + FGrid = SpaceTimeGrid::makeFiveDimGrid(Ls,UGrid); FrbGrid = SpaceTimeGrid::makeFiveDimRedBlackGrid(Ls,UGrid); @@ -87,12 +87,12 @@ class HmcRunner : public BinaryHmcRunner { RealD scale = 2.0; FermionAction DenOp(U,*FGrid,*FrbGrid,*UGrid,*UrbGrid,mass,M5,scale); FermionAction NumOp(U,*FGrid,*FrbGrid,*UGrid,*UrbGrid,pv,M5,scale); - + double StoppingCondition = 1.0e-8; double MaxCGIterations = 10000; ConjugateGradient CG(StoppingCondition,MaxCGIterations); TwoFlavourEvenOddRatioPseudoFermionAction Nf2(NumOp, DenOp,CG,CG); - + // Set smearing (true/false), default: false Nf2.is_smeared = true; @@ -115,8 +115,7 @@ class HmcRunner : public BinaryHmcRunner { std::string format = std::string("IEEE64BIG"); std::string conf_prefix = std::string("DWF_ckpoint_lat"); std::string rng_prefix = std::string("DWF_ckpoint_rng"); - BinaryHmcCheckpointer Checkpoint( - conf_prefix, rng_prefix, SaveInterval, format); + BinaryHmcCheckpointer Checkpoint(conf_prefix, rng_prefix, SaveInterval, format); // Can implement also a specific function in the hmcrunner // AddCheckpoint (...) that takes the same parameters + a string/tag // defining the type of the checkpointer @@ -124,8 +123,7 @@ class HmcRunner : public BinaryHmcRunner { // Then force all checkpoint to have few common functions // return an object that is then passed to the Run function - PlaquetteLogger PlaqLog( - std::string("Plaquette")); + PlaquetteLogger PlaqLog(std::string("Plaquette")); ObservablesList.push_back(&PlaqLog); ObservablesList.push_back(&Checkpoint); @@ -139,7 +137,7 @@ class HmcRunner : public BinaryHmcRunner { Run(argc, argv, Checkpoint, SmearingPolicy); //Run(argc, argv, Checkpoint); // no smearing - }; +}; }; } } @@ -153,6 +151,7 @@ int main(int argc, char **argv) { HmcRunner TheHMC; + // Seeds for the random number generators std::vector SerSeed({1, 2, 3, 4, 5}); std::vector ParSeed({6, 7, 8, 9, 10}); diff --git a/tests/hmc/Test_hmc_WilsonGauge_Binary.cc b/tests/hmc/Test_hmc_WilsonGauge_Binary.cc index 977ca1c8..aed66d20 100644 --- a/tests/hmc/Test_hmc_WilsonGauge_Binary.cc +++ b/tests/hmc/Test_hmc_WilsonGauge_Binary.cc @@ -37,20 +37,22 @@ using namespace Grid::QCD; namespace Grid { namespace QCD { +//Change here the type of reader +typedef Grid::TextReader InputFileReader; + + class HMCRunnerParameters : Serializable { public: GRID_SERIALIZABLE_CLASS_MEMBERS(HMCRunnerParameters, double, beta, - double, mass, - int, MaxCGIterations, - double, StoppingCondition, - bool, smearedAction, + int, MDsteps, + double, TrajectorLength, int, SaveInterval, std::string, format, std::string, conf_prefix, std::string, rng_prefix, - double, rho, - int, SmearingLevels, + std::string, serial_seeds, + std::string, parallel_seeds, ); HMCRunnerParameters() {} @@ -59,7 +61,8 @@ class HMCRunnerParameters : Serializable { // Derive from the BinaryHmcRunner (templated for gauge fields) class HmcRunner : public BinaryHmcRunner { public: - void BuildTheAction(int argc, char **argv) + HMCRunnerParameters HMCPar; + void BuildTheAction(int argc, char **argv) { typedef WilsonImplR ImplPolicy; @@ -70,7 +73,7 @@ class HmcRunner : public BinaryHmcRunner { // Gauge action - WilsonGaugeActionR Waction(5.6); + WilsonGaugeActionR Waction(HMCPar.beta); // Collect actions ActionLevel Level1(1); @@ -78,12 +81,8 @@ class HmcRunner : public BinaryHmcRunner { TheAction.push_back(Level1); // Add observables - int SaveInterval = 1; - std::string format = std::string("IEEE64BIG"); - std::string conf_prefix = std::string("ckpoint_lat"); - std::string rng_prefix = std::string("ckpoint_rng"); BinaryHmcCheckpointer Checkpoint( - conf_prefix, rng_prefix, SaveInterval, format); + HMCPar.conf_prefix, HMCPar.rng_prefix, HMCPar.SaveInterval, HMCPar.format); // Can implement also a specific function in the hmcrunner // AddCheckpoint (...) that takes the same parameters + a string/tag // defining the type of the checkpointer @@ -110,13 +109,18 @@ int main(int argc, char **argv) { << " threads" << std::endl; HmcRunner TheHMC; + InputFileReader Reader("input.wilson_gauge.params"); + read(Reader, "HMC", TheHMC.HMCPar); + + std::cout << GridLogMessage << TheHMC.HMCPar << std::endl; // Seeds for the random number generators - std::vector SerSeed({1, 2, 3, 4, 5}); - std::vector ParSeed({6, 7, 8, 9, 10}); + std::vector SerSeed = strToVec(TheHMC.HMCPar.serial_seeds); + std::vector ParSeed = strToVec(TheHMC.HMCPar.parallel_seeds); + TheHMC.RNGSeeds(SerSeed, ParSeed); - TheHMC.MDparameters.set(20, 1.0);// MDsteps, traj length + TheHMC.MDparameters.set(TheHMC.HMCPar.MDsteps, TheHMC.HMCPar.TrajectorLength); TheHMC.BuildTheAction(argc, argv); From f415db583a701297dcddb789933928f000dff945 Mon Sep 17 00:00:00 2001 From: Guido Cossu Date: Mon, 24 Oct 2016 15:48:22 +0100 Subject: [PATCH 028/214] Adding ILDG format --- configure.ac | 7 ++ lib/Grid.h | 5 +- lib/parallelIO/BinaryIO.h | 38 ++++--- lib/parallelIO/IldgIO.h | 194 +++++++++++++++++++++++++++++++++++ lib/parallelIO/IldgIOtypes.h | 74 +++++++++++++ lib/parallelIO/NerscIO.h | 4 +- 6 files changed, 302 insertions(+), 20 deletions(-) create mode 100644 lib/parallelIO/IldgIO.h create mode 100644 lib/parallelIO/IldgIOtypes.h diff --git a/configure.ac b/configure.ac index 0f3a3018..33a94004 100644 --- a/configure.ac +++ b/configure.ac @@ -130,6 +130,13 @@ AC_CHECK_LIB([fftw3],[fftw_execute], CXXFLAGS=$CXXFLAGS_CPY LDFLAGS=$LDFLAGS_CPY +AC_CHECK_LIB([lime],[limeCreateReader], + [LIBS="$LIBS -llime"], + [AC_MSG_ERROR(C-LIME library was not found in your system. +Please install or provide the correct path to your installation [default search path ~/lime/] +Info at: http://usqcd.jlab.org/usqcd-docs/c-lime/)]) + + ############### SIMD instruction selection AC_ARG_ENABLE([simd],[AC_HELP_STRING([--enable-simd=SSE4|AVX|AVXFMA4|AVXFMA|AVX2|AVX512|AVX512MIC|IMCI|KNL|KNC],\ [Select instructions to be SSE4.0, AVX 1.0, AVX 2.0+FMA, AVX 512, IMCI])],\ diff --git a/lib/Grid.h b/lib/Grid.h index d2e12d29..5db4a0d2 100644 --- a/lib/Grid.h +++ b/lib/Grid.h @@ -76,10 +76,13 @@ Author: paboyle #include #include #include -#include #include +#include +#include +#include #include + #include #include diff --git a/lib/parallelIO/BinaryIO.h b/lib/parallelIO/BinaryIO.h index abba1880..3b2a8912 100644 --- a/lib/parallelIO/BinaryIO.h +++ b/lib/parallelIO/BinaryIO.h @@ -348,8 +348,8 @@ class BinaryIO { grid->GlobalIndexToGlobalCoor(gidx, gcoor); grid->GlobalCoorToRankIndex(rank, o_idx, i_idx, gcoor); int l_idx = parallel.generator_idx(o_idx, i_idx); - std::cout << GridLogDebug << "l_idx " << l_idx << " o_idx " << o_idx - << " i_idx " << i_idx << " rank " << rank << std::endl; + //std::cout << GridLogDebug << "l_idx " << l_idx << " o_idx " << o_idx + // << " i_idx " << i_idx << " rank " << rank << std::endl; if (rank == grid->ThisRank()) { parallel.GetState(saved, l_idx); } @@ -357,7 +357,6 @@ class BinaryIO { grid->Barrier(); // necessary? if (grid->IsBoss()) { - std::cout << "Saved: " << saved << std::endl; Uint32Checksum((uint32_t *)&saved[0], bytes, csum); fout.write((char *)&saved[0], bytes); } @@ -422,12 +421,11 @@ class BinaryIO { grid->GlobalIndexToGlobalCoor(gidx,gcoor); grid->GlobalCoorToRankIndex(rank,o_idx,i_idx,gcoor); int l_idx=parallel.generator_idx(o_idx,i_idx); - std::cout << GridLogDebug << "l_idx " << l_idx << " o_idx " << o_idx - << " i_idx " << i_idx << " rank " << rank << std::endl; + //std::cout << GridLogDebug << "l_idx " << l_idx << " o_idx " << o_idx + // << " i_idx " << i_idx << " rank " << rank << std::endl; if ( grid->IsBoss() ) { fin.read((char *)&saved[0],bytes); - std::cout << "Saved: " << saved << std::endl; Uint32Checksum((uint32_t *)&saved[0],bytes,csum); } @@ -608,7 +606,8 @@ class BinaryIO { static inline uint32_t writeObjectParallel(Lattice &Umu, std::string file, munger munge, int offset, - const std::string &format) { + const std::string &format, + ILDGtype ILDG = ILDGtype()) { typedef typename vobj::scalar_object sobj; GridBase *grid = Umu._grid; @@ -682,13 +681,15 @@ class BinaryIO { // Ideally one reader/writer per xy plane and read these contiguously // with comms from nominated I/O nodes. std::ofstream fout; - if (IOnode){ - fout.open(file, std::ios::binary | std::ios::in | std::ios::out); - if (!fout.is_open()) { - std::cout << GridLogMessage << "writeObjectParallel: Error opening file " << file - << std::endl; - exit(0); - } + if (!ILDG.is_ILDG){ + if (IOnode){ + fout.open(file, std::ios::binary | std::ios::in | std::ios::out); + if (!fout.is_open()) { + std::cout << GridLogMessage << "writeObjectParallel: Error opening file " << file + << std::endl; + exit(0); + } + } } ////////////////////////////////////////////////////////// @@ -752,8 +753,13 @@ class BinaryIO { if (ieee64big) htobe64_v((void *)&fileObj, sizeof(fileObj)); if (ieee64) htole64_v((void *)&fileObj, sizeof(fileObj)); - fout.seekp(offset + g_idx * sizeof(fileObj)); - fout.write((char *)&fileObj, sizeof(fileObj)); + if (ILDG.is_ILDG){ + size_t sizeFO = sizeof(fileObj); + int status = limeWriteRecordData((char*)&fileObj, &sizeFO, ILDG.LW); + } else{ + fout.seekp(offset + g_idx * sizeof(fileObj)); + fout.write((char *)&fileObj, sizeof(fileObj)); + } bytes += sizeof(fileObj); } } diff --git a/lib/parallelIO/IldgIO.h b/lib/parallelIO/IldgIO.h new file mode 100644 index 00000000..e723d3f8 --- /dev/null +++ b/lib/parallelIO/IldgIO.h @@ -0,0 +1,194 @@ +/************************************************************************************* + +Grid physics library, www.github.com/paboyle/Grid + +Source file: ./lib/parallelIO/IldgIO.h + +Copyright (C) 2015 + +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 */ +#ifndef GRID_ILDG_IO_H +#define GRID_ILDG_IO_H + +#include +#include +#include +#include +#include + +#include +#include +#include + +extern "C" { // for linkage +#include "lime.h" +} + +namespace Grid { +namespace QCD { + +inline void ILDGGrid(GridBase *grid, ILDGField &header) { + assert(grid->_ndimension == 4); // emit error if not + header.dimension.resize(4); + header.boundary.resize(4); + for (int d = 0; d < 4; d++) { + header.dimension[d] = grid->_fdimensions[d]; + // Read boundary conditions from ... ? + header.boundary[d] = std::string("periodic"); + } +} + +inline void ILDGChecksum(uint32_t *buf, uint32_t buf_size_bytes, + uint32_t &csum) { + BinaryIO::Uint32Checksum(buf, buf_size_bytes, csum); +} + +////////////////////////////////////////////////////////////////////// +// Utilities ; these are QCD aware +////////////////////////////////////////////////////////////////////// +template +inline void ILDGStatistics(GaugeField &data, ILDGField &header) { + // How to convert data precision etc... + header.link_trace = Grid::QCD::WilsonLoops::linkTrace(data); + header.plaquette = Grid::QCD::WilsonLoops::avgPlaquette(data); + // header.polyakov = +} + +// Forcing QCD here +template +struct ILDGMunger { + void operator()(fobj &in, sobj &out, uint32_t &csum) { + for (int mu = 0; mu < 4; mu++) { + for (int i = 0; i < 3; i++) { + for (int j = 0; j < 3; j++) { + out(mu)()(i, j) = in(mu)()(i, j); + } + } + } + ILDGChecksum((uint32_t *)&in, sizeof(in), csum); + }; +}; + +template +struct ILDGSimpleUnmunger { + void operator()(sobj &in, fobj &out, uint32_t &csum) { + for (int mu = 0; mu < 4; mu++) { + for (int i = 0; i < 3; i++) { + for (int j = 0; j < 3; j++) { + out(mu)()(i, j) = in(mu)()(i, j); + } + } + } + ILDGChecksum((uint32_t *)&out, sizeof(out), csum); + }; +}; + +//////////////////////////////////////////////////////////////////////////////// +// Write and read from fstream; compute header offset for payload +//////////////////////////////////////////////////////////////////////////////// +class ILDGIO : public BinaryIO { + FILE *outFile; + LimeWriter *LimeW; + LimeRecordHeader *LimeHeader; + + public: + ILDGIO(std::string file) { + outFile = fopen(file.c_str(), "w"); + // check if opened correctly + + LimeW = limeCreateWriter(outFile); + } + + ~ILDGIO() { fclose(outFile); } + + unsigned int writeHeader(ILDGField &header) { + // write header in LIME + n_uint64_t nbytes; + int MB_flag = 1, ME_flag = 0; + + char message[] = "ildg-format"; + nbytes = strlen(message); + LimeHeader = limeCreateHeader(MB_flag, ME_flag, message, nbytes); + limeWriteRecordHeader(LimeHeader, LimeW); + limeDestroyHeader(LimeHeader); + // save the xml header here + // use the xml_writer to c++ streams in pugixml + // and convert to char message + // limeWriteRecordData(message, &nbytes, LimeW); + limeWriterCloseRecord(LimeW); + + return 0; + } + + unsigned int readHeader(std::string file, GridBase *grid, ILDGField &field) { + return 0; + } + + template + int readConfiguration(Lattice > &Umu, + ILDGField &header, std::string file) { + typedef Lattice > GaugeField; + + return 0; + } + + template + int writeConfiguration(Lattice > &Umu, + ILDGField &header, std::string file) { + typedef Lattice > GaugeField; + typedef iLorentzColourMatrix vobj; + typedef typename vobj::scalar_object sobj; + typedef LorentzColourMatrixD fobj; + + ILDGSimpleUnmunger munge; + unsigned int offset = writeHeader(header); + + BinaryIO::Uint32Checksum(Umu, munge, header.checksum); + + // Write record header + LimeRecordHeader *h; + std::cout << GridLogDebug << "ILDG Creating Header" << std::endl; + char message[] = "ildg-binary-data"; + h = limeCreateHeader(1, 1, message, strlen(message)); + + std::cout << GridLogDebug << "ILDG Writing Header" << std::endl; + int status = limeWriteRecordHeader(h, LimeW); + + if (status < 0) { + std::cerr << "ILDG Header error\n"; + return 1; + } + + limeDestroyHeader(h); + + ILDGtype ILDGt(true, LimeW); + uint32_t csum = BinaryIO::writeObjectParallel( + Umu, file, munge, offset, header.floating_point, ILDGt); + + limeWriterCloseRecord(LimeW); + + return 0; + } + + // format for RNG? +}; +} +} +#endif diff --git a/lib/parallelIO/IldgIOtypes.h b/lib/parallelIO/IldgIOtypes.h new file mode 100644 index 00000000..bbee2a53 --- /dev/null +++ b/lib/parallelIO/IldgIOtypes.h @@ -0,0 +1,74 @@ +/************************************************************************************* + +Grid physics library, www.github.com/paboyle/Grid + +Source file: ./lib/parallelIO/IldgIO.h + +Copyright (C) 2015 + +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 */ +#ifndef GRID_ILDGTYPES_IO_H +#define GRID_ILDGTYPES_IO_H + +extern "C" { // for linkage +#include "lime.h" +} + +namespace Grid { + + struct ILDGtype{ + bool is_ILDG; + LimeWriter* LW; + + ILDGtype(bool is, LimeWriter* L):is_ILDG(is),LW(L){} + ILDGtype():is_ILDG(false),LW(NULL){} + }; + + + + + class ILDGField { + public: + // header strings (not in order) + std::vector dimension; + std::vector boundary; + int data_start; + std::string hdr_version; + std::string storage_format; + // Checks on data + double link_trace; + double plaquette; + uint32_t checksum; + unsigned int sequence_number; + std::string data_type; + std::string ensemble_id ; + std::string ensemble_label ; + std::string creator ; + std::string creator_hardware ; + std::string creation_date ; + std::string archive_date ; + std::string floating_point; + }; + + + + +} +#endif diff --git a/lib/parallelIO/NerscIO.h b/lib/parallelIO/NerscIO.h index 6fdf83ef..91e622db 100644 --- a/lib/parallelIO/NerscIO.h +++ b/lib/parallelIO/NerscIO.h @@ -397,9 +397,7 @@ static inline void writeConfiguration(Lattice > &Umu typedef LorentzColourMatrixD fobj3D; typedef LorentzColour2x3D fobj2D; - //typedef LorentzColourMatrixF fobj3f; - //typedef LorentzColour2x3F fobj2f; - + GridBase *grid = Umu._grid; NerscGrid(grid,header); From 47c7159177a6a341bcd273d592e0b0c75346ffb9 Mon Sep 17 00:00:00 2001 From: Guido Cossu Date: Mon, 24 Oct 2016 21:57:54 +0100 Subject: [PATCH 029/214] ILDG reader/writer works Fill the xml header with the required information, todo. --- lib/Grid.h | 1 + lib/parallelIO/BinaryIO.h | 46 +++++---- lib/parallelIO/IldgIO.h | 115 +++++++++++++++------ lib/parallelIO/IldgIOtypes.h | 18 ++-- lib/parallelIO/NerscIO.h | 7 +- lib/qcd/hmc/ILDGCheckpointer.h | 121 +++++++++++++++++++++++ tests/hmc/Test_hmc_WilsonGauge_Binary.cc | 2 +- 7 files changed, 248 insertions(+), 62 deletions(-) create mode 100644 lib/qcd/hmc/ILDGCheckpointer.h diff --git a/lib/Grid.h b/lib/Grid.h index 5db4a0d2..03921400 100644 --- a/lib/Grid.h +++ b/lib/Grid.h @@ -87,6 +87,7 @@ Author: paboyle #include #include +#include #include #include diff --git a/lib/parallelIO/BinaryIO.h b/lib/parallelIO/BinaryIO.h index 3b2a8912..2b7747ba 100644 --- a/lib/parallelIO/BinaryIO.h +++ b/lib/parallelIO/BinaryIO.h @@ -449,10 +449,13 @@ class BinaryIO { return csum; } - - template - static inline uint32_t readObjectParallel(Lattice &Umu,std::string file,munger munge,int offset,const std::string &format) - { + template + static inline uint32_t readObjectParallel(Lattice &Umu, + std::string file, + munger munge, + int offset, + const std::string &format, + ILDGtype ILDG = ILDGtype()) { typedef typename vobj::scalar_object sobj; GridBase *grid = Umu._grid; @@ -518,9 +521,10 @@ class BinaryIO { int myrank = grid->ThisRank(); int iorank = grid->RankFromProcessorCoor(ioproc); - if ( IOnode ) { - fin.open(file,std::ios::binary|std::ios::in); - } + if (!ILDG.is_ILDG) + if ( IOnode ) { + fin.open(file,std::ios::binary|std::ios::in); + } ////////////////////////////////////////////////////////// // Find the location of each site and send to primary node @@ -562,8 +566,15 @@ class BinaryIO { //////////////////////////////// if (myrank == iorank) { - fin.seekg(offset+g_idx*sizeof(fileObj)); - fin.read((char *)&fileObj,sizeof(fileObj)); + if (ILDG.is_ILDG){ + // use C-LIME to populate the record + size_t sizeFO = sizeof(fileObj); + limeReaderSeek(ILDG.LR, g_idx*sizeFO, SEEK_SET); + int status = limeReaderReadData((void *)&fileObj, &sizeFO, ILDG.LR); + } else{ + fin.seekg(offset+g_idx*sizeof(fileObj)); + fin.read((char *)&fileObj,sizeof(fileObj)); + } bytes+=sizeof(fileObj); if(ieee32big) be32toh_v((void *)&fileObj,sizeof(fileObj)); @@ -681,7 +692,7 @@ class BinaryIO { // Ideally one reader/writer per xy plane and read these contiguously // with comms from nominated I/O nodes. std::ofstream fout; - if (!ILDG.is_ILDG){ + if (!ILDG.is_ILDG) if (IOnode){ fout.open(file, std::ios::binary | std::ios::in | std::ios::out); if (!fout.is_open()) { @@ -690,7 +701,7 @@ class BinaryIO { exit(0); } } - } + ////////////////////////////////////////////////////////// // Find the location of each site and send to primary node @@ -753,12 +764,13 @@ class BinaryIO { if (ieee64big) htobe64_v((void *)&fileObj, sizeof(fileObj)); if (ieee64) htole64_v((void *)&fileObj, sizeof(fileObj)); - if (ILDG.is_ILDG){ - size_t sizeFO = sizeof(fileObj); - int status = limeWriteRecordData((char*)&fileObj, &sizeFO, ILDG.LW); - } else{ - fout.seekp(offset + g_idx * sizeof(fileObj)); - fout.write((char *)&fileObj, sizeof(fileObj)); + if (ILDG.is_ILDG) { + size_t sizeFO = sizeof(fileObj); + limeWriterSeek(ILDG.LW, g_idx*sizeFO, SEEK_SET); + int status = limeWriteRecordData((void *)&fileObj, &sizeFO, ILDG.LW); + } else { + fout.seekp(offset + g_idx * sizeof(fileObj)); + fout.write((char *)&fileObj, sizeof(fileObj)); } bytes += sizeof(fileObj); } diff --git a/lib/parallelIO/IldgIO.h b/lib/parallelIO/IldgIO.h index e723d3f8..ad8fcfd3 100644 --- a/lib/parallelIO/IldgIO.h +++ b/lib/parallelIO/IldgIO.h @@ -87,7 +87,7 @@ struct ILDGMunger { }; template -struct ILDGSimpleUnmunger { +struct ILDGUnmunger { void operator()(sobj &in, fobj &out, uint32_t &csum) { for (int mu = 0; mu < 4; mu++) { for (int i = 0; i < 3; i++) { @@ -103,20 +103,45 @@ struct ILDGSimpleUnmunger { //////////////////////////////////////////////////////////////////////////////// // Write and read from fstream; compute header offset for payload //////////////////////////////////////////////////////////////////////////////// +enum ILDGstate {ILDGread, ILDGwrite}; + class ILDGIO : public BinaryIO { - FILE *outFile; + FILE *File; LimeWriter *LimeW; LimeRecordHeader *LimeHeader; + LimeReader *LimeR; + std::string filename; + public: - ILDGIO(std::string file) { - outFile = fopen(file.c_str(), "w"); - // check if opened correctly + ILDGIO(std::string file, ILDGstate RW) { + filename = file; + if (RW == ILDGwrite){ + File = fopen(file.c_str(), "w"); + // check if opened correctly - LimeW = limeCreateWriter(outFile); + LimeW = limeCreateWriter(File); + } else { + File = fopen(file.c_str(), "r"); + // check if opened correctly + + LimeR = limeCreateReader(File); + } } - ~ILDGIO() { fclose(outFile); } + ~ILDGIO() { fclose(File); } + + int createHeader(std::string message, int MB, int ME, size_t PayloadSize, LimeWriter* L){ + LimeRecordHeader *h; + h = limeCreateHeader(MB, ME, const_cast(message.c_str()), PayloadSize); + int status = limeWriteRecordHeader(h, L); + if (status < 0) { + std::cerr << "ILDG Header error\n"; + return status; + } + limeDestroyHeader(h); + return LIME_SUCCESS; + } unsigned int writeHeader(ILDGField &header) { // write header in LIME @@ -131,60 +156,86 @@ class ILDGIO : public BinaryIO { // save the xml header here // use the xml_writer to c++ streams in pugixml // and convert to char message - // limeWriteRecordData(message, &nbytes, LimeW); + limeWriteRecordData(message, &nbytes, LimeW); limeWriterCloseRecord(LimeW); return 0; } - unsigned int readHeader(std::string file, GridBase *grid, ILDGField &field) { + unsigned int readHeader(ILDGField &header) { return 0; } template - int readConfiguration(Lattice > &Umu, - ILDGField &header, std::string file) { + uint32_t readConfiguration(Lattice > &Umu) { typedef Lattice > GaugeField; + typedef LorentzColourMatrixD sobjd; + typedef LorentzColourMatrixF sobjf; + typedef iLorentzColourMatrix itype; + typedef LorentzColourMatrix sobj; + GridBase *grid = Umu._grid; - return 0; + ILDGField header; + readHeader(header); + + // now just the conf, ignore the header + std::string format = std::string("IEEE64BIG"); + do {limeReaderNextRecord(LimeR);} + while (strncmp(limeReaderType(LimeR), "ildg-binary-data",16)); + + n_uint64_t nbytes = limeReaderBytes(LimeR);//size of this record (configuration) + + + ILDGtype ILDGt(true, LimeR); + // this is special for double prec data, just for the moment + uint32_t csum = BinaryIO::readObjectParallel< itype, sobjd >( + Umu, filename, ILDGMunger(), 0, format, ILDGt); + + // Check configuration + // todo + + return csum; } template - int writeConfiguration(Lattice > &Umu, - ILDGField &header, std::string file) { + uint32_t writeConfiguration(Lattice > &Umu, std::string format) { typedef Lattice > GaugeField; typedef iLorentzColourMatrix vobj; typedef typename vobj::scalar_object sobj; typedef LorentzColourMatrixD fobj; - ILDGSimpleUnmunger munge; + ILDGField header; + // fill the header + header.floating_point = format; + + ILDGUnmunger munge; unsigned int offset = writeHeader(header); BinaryIO::Uint32Checksum(Umu, munge, header.checksum); - // Write record header - LimeRecordHeader *h; - std::cout << GridLogDebug << "ILDG Creating Header" << std::endl; - char message[] = "ildg-binary-data"; - h = limeCreateHeader(1, 1, message, strlen(message)); - - std::cout << GridLogDebug << "ILDG Writing Header" << std::endl; - int status = limeWriteRecordHeader(h, LimeW); - - if (status < 0) { - std::cerr << "ILDG Header error\n"; - return 1; - } - - limeDestroyHeader(h); + // Write data record header + n_uint64_t PayloadSize = sizeof(fobj) * Umu._grid->_gsites; + createHeader("ildg-binary-data", 0, 1, PayloadSize, LimeW); ILDGtype ILDGt(true, LimeW); uint32_t csum = BinaryIO::writeObjectParallel( - Umu, file, munge, offset, header.floating_point, ILDGt); + Umu, filename, munge, 0, header.floating_point, ILDGt); limeWriterCloseRecord(LimeW); - return 0; + // Last record + // the logical file name LNF + // look into documentation on how to generate this string + std::string LNF = "empty"; + + + PayloadSize = sizeof(LNF); + createHeader("ildg-binary-lfn", 1 , 1, PayloadSize, LimeW); + limeWriteRecordData(const_cast(LNF.c_str()), &PayloadSize, LimeW); + + limeWriterCloseRecord(LimeW); + + return csum; } // format for RNG? diff --git a/lib/parallelIO/IldgIOtypes.h b/lib/parallelIO/IldgIOtypes.h index bbee2a53..455fef41 100644 --- a/lib/parallelIO/IldgIOtypes.h +++ b/lib/parallelIO/IldgIOtypes.h @@ -33,14 +33,16 @@ extern "C" { // for linkage namespace Grid { - struct ILDGtype{ - bool is_ILDG; - LimeWriter* LW; - - ILDGtype(bool is, LimeWriter* L):is_ILDG(is),LW(L){} - ILDGtype():is_ILDG(false),LW(NULL){} - }; - + struct ILDGtype{ + bool is_ILDG; + LimeWriter* LW; + LimeReader* LR; + + ILDGtype(bool is, LimeWriter* L):is_ILDG(is),LW(L),LR(NULL){} + ILDGtype(bool is, LimeReader* L):is_ILDG(is),LW(NULL),LR(L){} + ILDGtype():is_ILDG(false),LW(NULL),LR(NULL){} + }; + diff --git a/lib/parallelIO/NerscIO.h b/lib/parallelIO/NerscIO.h index 91e622db..0c64f414 100644 --- a/lib/parallelIO/NerscIO.h +++ b/lib/parallelIO/NerscIO.h @@ -424,8 +424,8 @@ static inline void writeConfiguration(Lattice > &Umu //int csum1=BinaryIO::writeObjectSerial(Umu,file1,munge,offset,header.floating_point); - std::cout << GridLogMessage << " TESTING PARALLEL WRITE offsets " << offset1 << " "<< offset << std::endl; - std::cout << GridLogMessage << " TESTING PARALLEL WRITE csums " << csum1 << " "< > &Umu NerscSimpleUnmunger munge; BinaryIO::Uint32Checksum(Umu, munge,header.checksum); offset = writeHeader(header,file); - // csum=BinaryIO::writeObjectSerial(Umu,file,munge,offset,header.floating_point); csum=BinaryIO::writeObjectParallel(Umu,file,munge,offset,header.floating_point); } - std::cout< +#include +#include + +namespace Grid { +namespace QCD { + +// Only for Gauge fields +template +class ILDGHmcCheckpointer + : public HmcObservable { + private: + std::string configStem; + std::string rngStem; + int SaveInterval; + std::string format; + + public: + INHERIT_GIMPL_TYPES(Implementation); // + + ILDGHmcCheckpointer(std::string cf, std::string rn, int savemodulo, + std::string form = "IEEE64BIG") { + configStem = cf; + rngStem = rn; + SaveInterval = savemodulo; + format = form; + + // check here that the format is valid + int ieee32big = (format == std::string("IEEE32BIG")); + int ieee32 = (format == std::string("IEEE32")); + int ieee64big = (format == std::string("IEEE64BIG")); + int ieee64 = (format == std::string("IEEE64")); + + if (!(ieee64big ^ ieee32 ^ ieee32big ^ ieee64)) { + std::cout << GridLogMessage << "Invalid format: " << format << std::endl; + exit(0); + } + }; + + void TrajectoryComplete(int traj, GaugeField &U, GridSerialRNG &sRNG, + GridParallelRNG &pRNG) { + if ((traj % SaveInterval) == 0) { + std::string rng; + { + std::ostringstream os; + os << rngStem << "." << traj; + rng = os.str(); + } + std::string config; + { + std::ostringstream os; + os << configStem << "." << traj; + config = os.str(); + } + + ILDGIO IO(config, ILDGwrite); + BinaryIO::writeRNGSerial(sRNG, pRNG, rng, 0); + uint32_t csum = IO.writeConfiguration(U, format); + + std::cout << GridLogMessage << "Written ILDG Configuration on " << config + << " checksum " << std::hex << csum << std::dec << std::endl; + } + }; + + void CheckpointRestore(int traj, GaugeField &U, GridSerialRNG &sRNG, + GridParallelRNG &pRNG) { + std::string rng; + { + std::ostringstream os; + os << rngStem << "." << traj; + rng = os.str(); + } + std::string config; + { + std::ostringstream os; + os << configStem << "." << traj; + config = os.str(); + } + + ILDGIO IO(config, ILDGread); + BinaryIO::readRNGSerial(sRNG, pRNG, rng, 0); + uint32_t csum = IO.readConfiguration(U);// format from the header + + std::cout << GridLogMessage << "Read ILDG Configuration from " << config + << " checksum " << std::hex << csum << std::dec << std::endl; + }; +}; +} +} +#endif diff --git a/tests/hmc/Test_hmc_WilsonGauge_Binary.cc b/tests/hmc/Test_hmc_WilsonGauge_Binary.cc index aed66d20..65b055ef 100644 --- a/tests/hmc/Test_hmc_WilsonGauge_Binary.cc +++ b/tests/hmc/Test_hmc_WilsonGauge_Binary.cc @@ -81,7 +81,7 @@ class HmcRunner : public BinaryHmcRunner { TheAction.push_back(Level1); // Add observables - BinaryHmcCheckpointer Checkpoint( + ILDGHmcCheckpointer Checkpoint( HMCPar.conf_prefix, HMCPar.rng_prefix, HMCPar.SaveInterval, HMCPar.format); // Can implement also a specific function in the hmcrunner // AddCheckpoint (...) that takes the same parameters + a string/tag From d50055cd96dac81ab5364ebb33a210dd67d34e98 Mon Sep 17 00:00:00 2001 From: Guido Cossu Date: Wed, 26 Oct 2016 09:48:01 +0100 Subject: [PATCH 030/214] Making the ILDG support optional --- configure.ac | 7 ++- lib/parallelIO/BinaryIO.h | 9 ++- lib/parallelIO/IldgIO.h | 8 ++- lib/parallelIO/IldgIOtypes.h | 78 +++++++++++++----------- lib/qcd/hmc/GenericHMCrunner.h | 1 + lib/qcd/hmc/ILDGCheckpointer.h | 15 ++++- tests/hmc/Test_hmc_WilsonGauge_Binary.cc | 4 ++ 7 files changed, 78 insertions(+), 44 deletions(-) diff --git a/configure.ac b/configure.ac index 33a94004..5d5c60f1 100644 --- a/configure.ac +++ b/configure.ac @@ -131,9 +131,11 @@ CXXFLAGS=$CXXFLAGS_CPY LDFLAGS=$LDFLAGS_CPY AC_CHECK_LIB([lime],[limeCreateReader], + [AC_DEFINE([HAVE_LIME],[1],[Define to 1 if you have the `LIME' library (-llime).])] + [have_lime=true] [LIBS="$LIBS -llime"], - [AC_MSG_ERROR(C-LIME library was not found in your system. -Please install or provide the correct path to your installation [default search path ~/lime/] + [AC_MSG_WARN(C-LIME library was not found in your system. +In order to use ILGG file format please install or provide the correct path to your installation [default search path ~/lime/] Info at: http://usqcd.jlab.org/usqcd-docs/c-lime/)]) @@ -355,6 +357,7 @@ Summary of configuration for $PACKAGE v$VERSION - RNG choice : ${ac_RNG} - GMP : `if test "x$have_gmp" = xtrue; then echo yes; else echo no; fi` - LAPACK : ${ac_LAPACK} +- ILDG support (LIME) : `if test "x$have_lime" = xtrue; then echo yes; else echo no; fi` - FFTW : `if test "x$have_fftw" = xtrue; then echo yes; else echo no; fi` - build DOXYGEN documentation : `if test "x$enable_doc" = xyes; then echo yes; else echo no; fi` - graphs and diagrams : `if test "x$enable_dot" = xyes; then echo yes; else echo no; fi` diff --git a/lib/parallelIO/BinaryIO.h b/lib/parallelIO/BinaryIO.h index 2b7747ba..b5b684f6 100644 --- a/lib/parallelIO/BinaryIO.h +++ b/lib/parallelIO/BinaryIO.h @@ -568,9 +568,11 @@ class BinaryIO { if (ILDG.is_ILDG){ // use C-LIME to populate the record + #ifdef HAVE_LIME size_t sizeFO = sizeof(fileObj); limeReaderSeek(ILDG.LR, g_idx*sizeFO, SEEK_SET); int status = limeReaderReadData((void *)&fileObj, &sizeFO, ILDG.LR); + #endif } else{ fin.seekg(offset+g_idx*sizeof(fileObj)); fin.read((char *)&fileObj,sizeof(fileObj)); @@ -764,11 +766,16 @@ class BinaryIO { if (ieee64big) htobe64_v((void *)&fileObj, sizeof(fileObj)); if (ieee64) htole64_v((void *)&fileObj, sizeof(fileObj)); + if (ILDG.is_ILDG) { + #ifdef HAVE_LIME size_t sizeFO = sizeof(fileObj); limeWriterSeek(ILDG.LW, g_idx*sizeFO, SEEK_SET); int status = limeWriteRecordData((void *)&fileObj, &sizeFO, ILDG.LW); - } else { + #endif + } + + else { fout.seekp(offset + g_idx * sizeof(fileObj)); fout.write((char *)&fileObj, sizeof(fileObj)); } diff --git a/lib/parallelIO/IldgIO.h b/lib/parallelIO/IldgIO.h index ad8fcfd3..0912e2f6 100644 --- a/lib/parallelIO/IldgIO.h +++ b/lib/parallelIO/IldgIO.h @@ -37,6 +37,8 @@ directory #include #include +#ifdef HAVE_LIME + extern "C" { // for linkage #include "lime.h" } @@ -238,8 +240,12 @@ class ILDGIO : public BinaryIO { return csum; } - // format for RNG? + // format for RNG? Now just binary out }; } } + +//HAVE_LIME +#endif + #endif diff --git a/lib/parallelIO/IldgIOtypes.h b/lib/parallelIO/IldgIOtypes.h index 455fef41..4c7a1edd 100644 --- a/lib/parallelIO/IldgIOtypes.h +++ b/lib/parallelIO/IldgIOtypes.h @@ -27,50 +27,54 @@ directory #ifndef GRID_ILDGTYPES_IO_H #define GRID_ILDGTYPES_IO_H +#ifdef HAVE_LIME extern "C" { // for linkage #include "lime.h" } namespace Grid { - struct ILDGtype{ - bool is_ILDG; - LimeWriter* LW; - LimeReader* LR; - - ILDGtype(bool is, LimeWriter* L):is_ILDG(is),LW(L),LR(NULL){} - ILDGtype(bool is, LimeReader* L):is_ILDG(is),LW(NULL),LR(L){} - ILDGtype():is_ILDG(false),LW(NULL),LR(NULL){} - }; - - - - - class ILDGField { - public: - // header strings (not in order) - std::vector dimension; - std::vector boundary; - int data_start; - std::string hdr_version; - std::string storage_format; - // Checks on data - double link_trace; - double plaquette; - uint32_t checksum; - unsigned int sequence_number; - std::string data_type; - std::string ensemble_id ; - std::string ensemble_label ; - std::string creator ; - std::string creator_hardware ; - std::string creation_date ; - std::string archive_date ; - std::string floating_point; - }; - - +struct ILDGtype { + bool is_ILDG; + LimeWriter* LW; + LimeReader* LR; + ILDGtype(bool is, LimeWriter* L) : is_ILDG(is), LW(L), LR(NULL) {} + ILDGtype(bool is, LimeReader* L) : is_ILDG(is), LW(NULL), LR(L) {} + ILDGtype() : is_ILDG(false), LW(NULL), LR(NULL) {} +}; +class ILDGField { + public: + // header strings (not in order) + std::vector dimension; + std::vector boundary; + int data_start; + std::string hdr_version; + std::string storage_format; + // Checks on data + double link_trace; + double plaquette; + uint32_t checksum; + unsigned int sequence_number; + std::string data_type; + std::string ensemble_id; + std::string ensemble_label; + std::string creator; + std::string creator_hardware; + std::string creation_date; + std::string archive_date; + std::string floating_point; +}; } +#else +namespace Grid { + +struct ILDGtype { + bool is_ILDG; + ILDGtype() : is_ILDG(false) {} +}; +} + +#endif #endif diff --git a/lib/qcd/hmc/GenericHMCrunner.h b/lib/qcd/hmc/GenericHMCrunner.h index fbf26156..114595b1 100644 --- a/lib/qcd/hmc/GenericHMCrunner.h +++ b/lib/qcd/hmc/GenericHMCrunner.h @@ -83,6 +83,7 @@ namespace QCD { } ////////////////////////////// + template void Runner(int argc, char ** argv, diff --git a/lib/qcd/hmc/ILDGCheckpointer.h b/lib/qcd/hmc/ILDGCheckpointer.h index 9c65bef2..5dd3120f 100644 --- a/lib/qcd/hmc/ILDGCheckpointer.h +++ b/lib/qcd/hmc/ILDGCheckpointer.h @@ -29,6 +29,8 @@ directory #ifndef ILDG_CHECKPOINTER #define ILDG_CHECKPOINTER +#ifdef HAVE_LIME + #include #include #include @@ -47,7 +49,7 @@ class ILDGHmcCheckpointer std::string format; public: - INHERIT_GIMPL_TYPES(Implementation); // + INHERIT_GIMPL_TYPES(Implementation); ILDGHmcCheckpointer(std::string cf, std::string rn, int savemodulo, std::string form = "IEEE64BIG") { @@ -62,8 +64,13 @@ class ILDGHmcCheckpointer int ieee64big = (format == std::string("IEEE64BIG")); int ieee64 = (format == std::string("IEEE64")); - if (!(ieee64big ^ ieee32 ^ ieee32big ^ ieee64)) { - std::cout << GridLogMessage << "Invalid format: " << format << std::endl; + if (!(ieee64big || ieee32 || ieee32big || ieee64)) { + std::cout << GridLogError << "Unrecognized file format " << format + << std::endl; + std::cout << GridLogError + << "Allowed: IEEE32BIG | IEEE32 | IEEE64BIG | IEEE64" + << std::endl; + exit(0); } }; @@ -118,4 +125,6 @@ class ILDGHmcCheckpointer }; } } + +#endif #endif diff --git a/tests/hmc/Test_hmc_WilsonGauge_Binary.cc b/tests/hmc/Test_hmc_WilsonGauge_Binary.cc index 65b055ef..01a6a0e9 100644 --- a/tests/hmc/Test_hmc_WilsonGauge_Binary.cc +++ b/tests/hmc/Test_hmc_WilsonGauge_Binary.cc @@ -81,6 +81,10 @@ class HmcRunner : public BinaryHmcRunner { TheAction.push_back(Level1); // Add observables + // options for checkpointers + //BinaryHmcCheckpointer + //ILDGHmcCheckpointer + //NerscHmcCheckpointer ILDGHmcCheckpointer Checkpoint( HMCPar.conf_prefix, HMCPar.rng_prefix, HMCPar.SaveInterval, HMCPar.format); // Can implement also a specific function in the hmcrunner From 1d666771f9c7c2e6d41622ffdcea4d4d92acafde Mon Sep 17 00:00:00 2001 From: Guido Cossu Date: Wed, 26 Oct 2016 16:08:23 +0100 Subject: [PATCH 031/214] Debugging the RNG, eliminate the barrier after broadcast --- lib/parallelIO/BinaryIO.h | 2 +- tests/hmc/Test_hmc_WilsonGauge_Binary.cc | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/parallelIO/BinaryIO.h b/lib/parallelIO/BinaryIO.h index b5b684f6..83b183c6 100644 --- a/lib/parallelIO/BinaryIO.h +++ b/lib/parallelIO/BinaryIO.h @@ -355,7 +355,7 @@ class BinaryIO { } grid->Broadcast(rank, (void *)&saved[0], bytes); - grid->Barrier(); // necessary? + //grid->Barrier(); // necessary? if (grid->IsBoss()) { Uint32Checksum((uint32_t *)&saved[0], bytes, csum); fout.write((char *)&saved[0], bytes); diff --git a/tests/hmc/Test_hmc_WilsonGauge_Binary.cc b/tests/hmc/Test_hmc_WilsonGauge_Binary.cc index 01a6a0e9..60035135 100644 --- a/tests/hmc/Test_hmc_WilsonGauge_Binary.cc +++ b/tests/hmc/Test_hmc_WilsonGauge_Binary.cc @@ -85,7 +85,7 @@ class HmcRunner : public BinaryHmcRunner { //BinaryHmcCheckpointer //ILDGHmcCheckpointer //NerscHmcCheckpointer - ILDGHmcCheckpointer Checkpoint( + NerscHmcCheckpointer Checkpoint( HMCPar.conf_prefix, HMCPar.rng_prefix, HMCPar.SaveInterval, HMCPar.format); // Can implement also a specific function in the hmcrunner // AddCheckpoint (...) that takes the same parameters + a string/tag From 19b85d84862df3fb39a81446ce8e0e216e7c759c Mon Sep 17 00:00:00 2001 From: Guido Cossu Date: Thu, 10 Nov 2016 17:55:58 +0000 Subject: [PATCH 032/214] Some comments in the hmc files --- tests/hmc/Test_hmc_WilsonGauge_Binary.cc | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/tests/hmc/Test_hmc_WilsonGauge_Binary.cc b/tests/hmc/Test_hmc_WilsonGauge_Binary.cc index 60035135..2becb37c 100644 --- a/tests/hmc/Test_hmc_WilsonGauge_Binary.cc +++ b/tests/hmc/Test_hmc_WilsonGauge_Binary.cc @@ -58,6 +58,7 @@ class HMCRunnerParameters : Serializable { HMCRunnerParameters() {} }; + // Derive from the BinaryHmcRunner (templated for gauge fields) class HmcRunner : public BinaryHmcRunner { public: @@ -65,15 +66,21 @@ class HmcRunner : public BinaryHmcRunner { void BuildTheAction(int argc, char **argv) { + // Typedefs to simplify notation + typedef WilsonGaugeActionR GaugeAction; typedef WilsonImplR ImplPolicy; typedef WilsonFermionR FermionAction; typedef typename FermionAction::FermionField FermionField; - UGrid = SpaceTimeGrid::makeFourDimGrid(GridDefaultLatt(), GridDefaultSimd(Nd, vComplex::Nsimd()), GridDefaultMpi()); + // this can be simplified too. MakeDefaultGrid(Nd) + UGrid = SpaceTimeGrid::makeFourDimGrid( + GridDefaultLatt(), + GridDefaultSimd(Nd, vComplex::Nsimd()), + GridDefaultMpi()); // Gauge action - WilsonGaugeActionR Waction(HMCPar.beta); + GaugeAction Waction(HMCPar.beta); // Collect actions ActionLevel Level1(1); @@ -113,12 +120,14 @@ int main(int argc, char **argv) { << " threads" << std::endl; HmcRunner TheHMC; + // make input file name general InputFileReader Reader("input.wilson_gauge.params"); read(Reader, "HMC", TheHMC.HMCPar); std::cout << GridLogMessage << TheHMC.HMCPar << std::endl; // Seeds for the random number generators + // generalise std::vector SerSeed = strToVec(TheHMC.HMCPar.serial_seeds); std::vector ParSeed = strToVec(TheHMC.HMCPar.parallel_seeds); From 4e1ffdd17c2c95c88867d48966d1ad3e8a600bb7 Mon Sep 17 00:00:00 2001 From: Guido Cossu Date: Thu, 10 Nov 2016 18:44:36 +0000 Subject: [PATCH 033/214] Adding git info to the configure output --- configure.ac | 8 ++++++++ scripts/configure.commit | 19 +++++++++++++++++++ 2 files changed, 27 insertions(+) create mode 100755 scripts/configure.commit diff --git a/configure.ac b/configure.ac index 46fda677..944e53ef 100644 --- a/configure.ac +++ b/configure.ac @@ -9,6 +9,9 @@ AC_CONFIG_SRCDIR([lib/Grid.h]) AC_CONFIG_HEADERS([lib/Config.h]) m4_ifdef([AM_SILENT_RULES], [AM_SILENT_RULES([yes])]) +################ Get git info +#AC_REVISION([m4_esyscmd_s([./scripts/configure.commit])]) + ############### Checks for programs CXXFLAGS="-O3 $CXXFLAGS" AC_PROG_CXX @@ -379,10 +382,15 @@ AC_CONFIG_FILES(tests/qdpxx/Makefile) AC_CONFIG_FILES(benchmarks/Makefile) AC_OUTPUT +git_commit=`cd $srcdir && ./scripts/configure.commit` + echo "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Summary of configuration for $PACKAGE v$VERSION ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +----- GIT VERSION ------------------------------------- +$git_commit + ----- PLATFORM ---------------------------------------- architecture (build) : $build_cpu os (build) : $build_os diff --git a/scripts/configure.commit b/scripts/configure.commit new file mode 100755 index 00000000..77991392 --- /dev/null +++ b/scripts/configure.commit @@ -0,0 +1,19 @@ + + +#! /bin/sh +# Display the SHA1 of the commit in which configure.ac was last modified. +# If it's not checked in yet, use the SHA1 of HEAD plus -dirty. + +# + +if [ ! -d .git ] ; then + # if no .git directory, assume they're not using Git + printf 'unknown commit' +elif git diff --quiet HEAD -- configure.ac ; then + # configure.ac is not modified + printf 'commit: %s\n' `git rev-parse --short HEAD -- configure.ac` + printf 'branch: %s\n' `git rev-parse --abbrev-ref HEAD` +else # configure.ac is modified + printf 'commit: %s-dirty\n' `git rev-parse --short HEAD` + printf 'branch: %s\n' `git rev-parse --abbrev-ref HEAD` + fi \ No newline at end of file From 6f8b771a37f4ea2a78ba8a439f46a3db68774da3 Mon Sep 17 00:00:00 2001 From: Guido Cossu Date: Thu, 10 Nov 2016 18:52:00 +0000 Subject: [PATCH 034/214] Adding date of the last commit --- scripts/configure.commit | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/scripts/configure.commit b/scripts/configure.commit index 77991392..afc662eb 100755 --- a/scripts/configure.commit +++ b/scripts/configure.commit @@ -1,5 +1,3 @@ - - #! /bin/sh # Display the SHA1 of the commit in which configure.ac was last modified. # If it's not checked in yet, use the SHA1 of HEAD plus -dirty. @@ -13,7 +11,9 @@ elif git diff --quiet HEAD -- configure.ac ; then # configure.ac is not modified printf 'commit: %s\n' `git rev-parse --short HEAD -- configure.ac` printf 'branch: %s\n' `git rev-parse --abbrev-ref HEAD` + printf 'date : %s\n' `git log -1 --date=short --pretty=format:%cd` else # configure.ac is modified printf 'commit: %s-dirty\n' `git rev-parse --short HEAD` printf 'branch: %s\n' `git rev-parse --abbrev-ref HEAD` + printf 'date : %s\n' `git log -1 --date=short --pretty=format:%cd` fi \ No newline at end of file From 454302414db4a5803fd84065b41b2ae3cae66c58 Mon Sep 17 00:00:00 2001 From: Guido Cossu Date: Tue, 15 Nov 2016 12:31:13 +0000 Subject: [PATCH 035/214] Small modif at the test hmc --- gh-pages | 1 - tests/hmc/Test_hmc_WilsonFermionGauge_Binary.cc | 4 ++-- 2 files changed, 2 insertions(+), 3 deletions(-) delete mode 120000 gh-pages diff --git a/gh-pages b/gh-pages deleted file mode 120000 index 0f895714..00000000 --- a/gh-pages +++ /dev/null @@ -1 +0,0 @@ -../Grid_gh-pages/Grid/ \ No newline at end of file diff --git a/tests/hmc/Test_hmc_WilsonFermionGauge_Binary.cc b/tests/hmc/Test_hmc_WilsonFermionGauge_Binary.cc index e81c212d..65007673 100644 --- a/tests/hmc/Test_hmc_WilsonFermionGauge_Binary.cc +++ b/tests/hmc/Test_hmc_WilsonFermionGauge_Binary.cc @@ -86,12 +86,12 @@ class HmcRunner : public BinaryHmcRunner { // it with zeroes? FermionAction FermOp(U, *FGrid, *FrbGrid, mass); - ConjugateGradient CG(1.0e-8, 10000); + ConjugateGradient CG(1.0e-8, 2000); TwoFlavourPseudoFermionAction Nf2(FermOp, CG, CG); // Set smearing (true/false), default: false - Nf2.is_smeared = true; + Nf2.is_smeared = false; // Collect actions ActionLevel Level1(1); From 3834feb4b744c2b2732aebb014bf860fce5ccd9e Mon Sep 17 00:00:00 2001 From: Guido Cossu Date: Wed, 16 Nov 2016 16:46:49 +0000 Subject: [PATCH 036/214] Adding action names --- lib/qcd/action/ActionBase.h | 1 + lib/qcd/action/gauge/PlaqPlusRectangleAction.h | 18 ++++++++++-------- lib/qcd/action/gauge/WilsonGaugeAction.h | 4 +++- .../pseudofermion/OneFlavourEvenOddRational.h | 2 ++ .../OneFlavourEvenOddRationalRatio.h | 2 ++ .../action/pseudofermion/OneFlavourRational.h | 2 ++ .../pseudofermion/OneFlavourRationalRatio.h | 2 ++ lib/qcd/action/pseudofermion/TwoFlavour.h | 7 ++++++- .../action/pseudofermion/TwoFlavourEvenOdd.h | 2 ++ .../pseudofermion/TwoFlavourEvenOddRatio.h | 2 ++ lib/qcd/action/pseudofermion/TwoFlavourRatio.h | 2 ++ lib/qcd/hmc/integrators/Integrator.h | 8 +++++--- .../hmc/Test_hmc_WilsonFermionGauge_Binary.cc | 4 +++- tests/hmc/Test_hmc_WilsonGauge_Binary.cc | 1 + 14 files changed, 43 insertions(+), 14 deletions(-) diff --git a/lib/qcd/action/ActionBase.h b/lib/qcd/action/ActionBase.h index 7911462e..371ccd24 100644 --- a/lib/qcd/action/ActionBase.h +++ b/lib/qcd/action/ActionBase.h @@ -42,6 +42,7 @@ class Action { virtual RealD S(const GaugeField& U) = 0; // evaluate the action virtual void deriv(const GaugeField& U, GaugeField& dSdU) = 0; // evaluate the action derivative + virtual std::string action_name() = 0; // return the action name virtual ~Action(){}; }; diff --git a/lib/qcd/action/gauge/PlaqPlusRectangleAction.h b/lib/qcd/action/gauge/PlaqPlusRectangleAction.h index 6193bedb..b78ed939 100644 --- a/lib/qcd/action/gauge/PlaqPlusRectangleAction.h +++ b/lib/qcd/action/gauge/PlaqPlusRectangleAction.h @@ -47,6 +47,8 @@ namespace Grid{ public: PlaqPlusRectangleAction(RealD b,RealD c): c_plaq(b),c_rect(c){}; + + virtual std::string action_name(){return "PlaqPlusRectangleAction";} virtual void refresh(const GaugeField &U, GridParallelRNG& pRNG) {}; // noop as no pseudoferms @@ -108,32 +110,32 @@ namespace Grid{ class RBCGaugeAction : public PlaqPlusRectangleAction { public: INHERIT_GIMPL_TYPES(Gimpl); - RBCGaugeAction(RealD beta,RealD c1) : PlaqPlusRectangleAction(beta*(1.0-8.0*c1), beta*c1) { - }; + RBCGaugeAction(RealD beta,RealD c1) : PlaqPlusRectangleAction(beta*(1.0-8.0*c1), beta*c1) {}; + virtual std::string action_name(){return "RBCGaugeAction";} }; template class IwasakiGaugeAction : public RBCGaugeAction { public: INHERIT_GIMPL_TYPES(Gimpl); - IwasakiGaugeAction(RealD beta) : RBCGaugeAction(beta,-0.331) { - }; + IwasakiGaugeAction(RealD beta) : RBCGaugeAction(beta,-0.331) {}; + virtual std::string action_name(){return "IwasakiGaugeAction";} }; template class SymanzikGaugeAction : public RBCGaugeAction { public: INHERIT_GIMPL_TYPES(Gimpl); - SymanzikGaugeAction(RealD beta) : RBCGaugeAction(beta,-1.0/12.0) { - }; + SymanzikGaugeAction(RealD beta) : RBCGaugeAction(beta,-1.0/12.0) {}; + virtual std::string action_name(){return "SymanzikGaugeAction";} }; template class DBW2GaugeAction : public RBCGaugeAction { public: INHERIT_GIMPL_TYPES(Gimpl); - DBW2GaugeAction(RealD beta) : RBCGaugeAction(beta,-1.4067) { - }; + DBW2GaugeAction(RealD beta) : RBCGaugeAction(beta,-1.4067) {}; + virtual std::string action_name(){return "DBW2GaugeAction";} }; } diff --git a/lib/qcd/action/gauge/WilsonGaugeAction.h b/lib/qcd/action/gauge/WilsonGaugeAction.h index b9216d78..aa61abf2 100644 --- a/lib/qcd/action/gauge/WilsonGaugeAction.h +++ b/lib/qcd/action/gauge/WilsonGaugeAction.h @@ -51,6 +51,8 @@ class WilsonGaugeAction : public Action { public: WilsonGaugeAction(RealD b) : beta(b){}; + virtual std::string action_name(){return "WilsonGaugeAction";} + virtual void refresh(const GaugeField &U, GridParallelRNG &pRNG){}; // noop as no pseudoferms @@ -65,7 +67,6 @@ class WilsonGaugeAction : public Action { // not optimal implementation FIXME // extend Ta to include Lorentz indexes - // RealD factor = 0.5*beta/RealD(Nc); RealD factor = 0.5 * beta / RealD(Nc); GaugeLinkField Umu(U._grid); @@ -79,6 +80,7 @@ class WilsonGaugeAction : public Action { PokeIndex(dSdU, dSdU_mu, mu); } + }; }; diff --git a/lib/qcd/action/pseudofermion/OneFlavourEvenOddRational.h b/lib/qcd/action/pseudofermion/OneFlavourEvenOddRational.h index 080b1be2..ec3fa9e2 100644 --- a/lib/qcd/action/pseudofermion/OneFlavourEvenOddRational.h +++ b/lib/qcd/action/pseudofermion/OneFlavourEvenOddRational.h @@ -90,6 +90,8 @@ class OneFlavourEvenOddRationalPseudoFermionAction PowerNegQuarter.Init(remez, param.tolerance, true); }; + virtual std::string action_name(){return "OneFlavourEvenOddRationalPseudoFermionAction";} + virtual void refresh(const GaugeField &U, GridParallelRNG &pRNG) { // P(phi) = e^{- phi^dag (MpcdagMpc)^-1/2 phi} // = e^{- phi^dag (MpcdagMpc)^-1/4 (MpcdagMpc)^-1/4 phi} diff --git a/lib/qcd/action/pseudofermion/OneFlavourEvenOddRationalRatio.h b/lib/qcd/action/pseudofermion/OneFlavourEvenOddRationalRatio.h index 735cb284..65eaabae 100644 --- a/lib/qcd/action/pseudofermion/OneFlavourEvenOddRationalRatio.h +++ b/lib/qcd/action/pseudofermion/OneFlavourEvenOddRationalRatio.h @@ -87,6 +87,8 @@ namespace Grid{ PowerQuarter.Init(remez,param.tolerance,false); PowerNegQuarter.Init(remez,param.tolerance,true); }; + + virtual std::string action_name(){return "OneFlavourEvenOddRatioRationalPseudoFermionAction";} virtual void refresh(const GaugeField &U, GridParallelRNG& pRNG) { diff --git a/lib/qcd/action/pseudofermion/OneFlavourRational.h b/lib/qcd/action/pseudofermion/OneFlavourRational.h index 65a99afa..aebcea3d 100644 --- a/lib/qcd/action/pseudofermion/OneFlavourRational.h +++ b/lib/qcd/action/pseudofermion/OneFlavourRational.h @@ -83,6 +83,8 @@ namespace Grid{ PowerQuarter.Init(remez,param.tolerance,false); PowerNegQuarter.Init(remez,param.tolerance,true); }; + + virtual std::string action_name(){return "OneFlavourRationalPseudoFermionAction";} virtual void refresh(const GaugeField &U, GridParallelRNG& pRNG) { diff --git a/lib/qcd/action/pseudofermion/OneFlavourRationalRatio.h b/lib/qcd/action/pseudofermion/OneFlavourRationalRatio.h index 2207e119..244eba7a 100644 --- a/lib/qcd/action/pseudofermion/OneFlavourRationalRatio.h +++ b/lib/qcd/action/pseudofermion/OneFlavourRationalRatio.h @@ -81,6 +81,8 @@ namespace Grid{ PowerQuarter.Init(remez,param.tolerance,false); PowerNegQuarter.Init(remez,param.tolerance,true); }; + + virtual std::string action_name(){return "OneFlavourRatioRationalPseudoFermionAction";} virtual void refresh(const GaugeField &U, GridParallelRNG& pRNG) { diff --git a/lib/qcd/action/pseudofermion/TwoFlavour.h b/lib/qcd/action/pseudofermion/TwoFlavour.h index 6b65a95d..79fad380 100644 --- a/lib/qcd/action/pseudofermion/TwoFlavour.h +++ b/lib/qcd/action/pseudofermion/TwoFlavour.h @@ -62,6 +62,9 @@ class TwoFlavourPseudoFermionAction : public Action { ActionSolver(AS), Phi(Op.FermionGrid()){}; + + virtual std::string action_name(){return "TwoFlavourPseudoFermionAction";} + ////////////////////////////////////////////////////////////////////////////////////// // Push the gauge field in to the dops. Assume any BC's and smearing already // applied @@ -81,7 +84,9 @@ class TwoFlavourPseudoFermionAction : public Action { // in the Phi integral, and thus is only an irrelevant prefactor for // the partition function. // - RealD scale = std::sqrt(0.5); + + RealD scale = std::sqrt(0.5); + FermionField eta(FermOp.FermionGrid()); gaussian(pRNG, eta); diff --git a/lib/qcd/action/pseudofermion/TwoFlavourEvenOdd.h b/lib/qcd/action/pseudofermion/TwoFlavourEvenOdd.h index 5af1761e..009899ea 100644 --- a/lib/qcd/action/pseudofermion/TwoFlavourEvenOdd.h +++ b/lib/qcd/action/pseudofermion/TwoFlavourEvenOdd.h @@ -64,6 +64,8 @@ class TwoFlavourEvenOddPseudoFermionAction PhiEven(Op.FermionRedBlackGrid()), PhiOdd(Op.FermionRedBlackGrid()) {}; + + virtual std::string action_name(){return "TwoFlavourEvenOddPseudoFermionAction";} ////////////////////////////////////////////////////////////////////////////////////// // Push the gauge field in to the dops. Assume any BC's and smearing already applied diff --git a/lib/qcd/action/pseudofermion/TwoFlavourEvenOddRatio.h b/lib/qcd/action/pseudofermion/TwoFlavourEvenOddRatio.h index 5e3b80d9..a8bd9fe7 100644 --- a/lib/qcd/action/pseudofermion/TwoFlavourEvenOddRatio.h +++ b/lib/qcd/action/pseudofermion/TwoFlavourEvenOddRatio.h @@ -67,6 +67,8 @@ namespace Grid{ conformable(_NumOp.GaugeGrid(), _DenOp.GaugeGrid()); conformable(_NumOp.GaugeRedBlackGrid(), _DenOp.GaugeRedBlackGrid()); }; + + virtual std::string action_name(){return "TwoFlavourEvenOddRatioPseudoFermionAction";} virtual void refresh(const GaugeField &U, GridParallelRNG& pRNG) { diff --git a/lib/qcd/action/pseudofermion/TwoFlavourRatio.h b/lib/qcd/action/pseudofermion/TwoFlavourRatio.h index 26d21094..03d5fe07 100644 --- a/lib/qcd/action/pseudofermion/TwoFlavourRatio.h +++ b/lib/qcd/action/pseudofermion/TwoFlavourRatio.h @@ -57,6 +57,8 @@ namespace Grid{ OperatorFunction & AS ) : NumOp(_NumOp), DenOp(_DenOp), DerivativeSolver(DS), ActionSolver(AS), Phi(_NumOp.FermionGrid()) {}; + virtual std::string action_name(){return "TwoFlavourRatioPseudoFermionAction";} + virtual void refresh(const GaugeField &U, GridParallelRNG& pRNG) { // P(phi) = e^{- phi^dag V (MdagM)^-1 Vdag phi} diff --git a/lib/qcd/hmc/integrators/Integrator.h b/lib/qcd/hmc/integrators/Integrator.h index ec3d31fe..6f1e5c45 100644 --- a/lib/qcd/hmc/integrators/Integrator.h +++ b/lib/qcd/hmc/integrators/Integrator.h @@ -57,7 +57,7 @@ struct IntegratorParameters { void print_parameters() { - std::cout << GridLogMessage << "[Integrator] Trajectory length : " << trajL << std::endl; + std::cout << GridLogMessage << "[Integrator] Trajectory length : " << trajL << std::endl; std::cout << GridLogMessage << "[Integrator] Number of MD steps : " << MDsteps << std::endl; std::cout << GridLogMessage << "[Integrator] Step size : " << stepsize << std::endl; } @@ -101,8 +101,9 @@ class Integrator { repr_set.at(a)->deriv(Rep.U, forceR); GF force = Rep.RtoFundamentalProject(forceR); // Ta for the fundamental rep + Real force_abs = std::sqrt(norm2(force)); std::cout << GridLogIntegrator << "Hirep Force average: " - << norm2(force) / (U._grid->gSites()) << std::endl; + << force_abs / (U._grid->gSites()) << std::endl; Mom -= force * ep ; } } @@ -121,8 +122,9 @@ class Integrator { << std::endl; if (as[level].actions.at(a)->is_smeared) Smearer.smeared_force(force); force = FieldImplementation::projectForce(force); // Ta for gauge fields + Real force_abs = std::sqrt(norm2(force)); std::cout << GridLogIntegrator - << "Force average: " << norm2(force) / (U._grid->gSites()) + << "Force average: " << force_abs / (U._grid->gSites()) << std::endl; Mom -= force * ep; } diff --git a/tests/hmc/Test_hmc_WilsonFermionGauge_Binary.cc b/tests/hmc/Test_hmc_WilsonFermionGauge_Binary.cc index 65007673..42a903d6 100644 --- a/tests/hmc/Test_hmc_WilsonFermionGauge_Binary.cc +++ b/tests/hmc/Test_hmc_WilsonFermionGauge_Binary.cc @@ -123,11 +123,13 @@ class HmcRunner : public BinaryHmcRunner { ObservablesList.push_back(&Checkpoint); // Smearing section, omit if not needed + /* double rho = 0.1; // smearing parameter int Nsmear = 2; // number of smearing levels Smear_Stout Stout(rho); SmearedConfiguration SmearingPolicy( UGrid, Nsmear, Stout); + */ /////////////////// // Run(argc, argv, Checkpoint, SmearingPolicy); @@ -151,7 +153,7 @@ int main(int argc, char **argv) { std::vector ParSeed({6, 7, 8, 9, 10}); TheHMC.RNGSeeds(SerSeed, ParSeed); - TheHMC.MDparameters.set(5, 1.0);// MDsteps, traj length + TheHMC.MDparameters.set(10, 1.0);// MDsteps, traj length TheHMC.BuildTheAction(argc, argv); } diff --git a/tests/hmc/Test_hmc_WilsonGauge_Binary.cc b/tests/hmc/Test_hmc_WilsonGauge_Binary.cc index 2becb37c..4c650357 100644 --- a/tests/hmc/Test_hmc_WilsonGauge_Binary.cc +++ b/tests/hmc/Test_hmc_WilsonGauge_Binary.cc @@ -80,6 +80,7 @@ class HmcRunner : public BinaryHmcRunner { // Gauge action + std::cout << GridLogMessage << "Beta: " << HMCPar.beta << std::endl; GaugeAction Waction(HMCPar.beta); // Collect actions From 62749d05a6269b56c96c1bd0f553e40dc00832d7 Mon Sep 17 00:00:00 2001 From: Guido Cossu Date: Thu, 17 Nov 2016 12:26:20 +0000 Subject: [PATCH 037/214] Naming the scalar action --- lib/qcd/action/scalar/ScalarAction.h | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/lib/qcd/action/scalar/ScalarAction.h b/lib/qcd/action/scalar/ScalarAction.h index 048cde8d..b3e14109 100644 --- a/lib/qcd/action/scalar/ScalarAction.h +++ b/lib/qcd/action/scalar/ScalarAction.h @@ -51,6 +51,8 @@ class ScalarAction : public Action { public: ScalarAction(RealD ms, RealD l) : mass_square(ms), lambda(l){}; + virtual std::string action_name(){return "ScalarAction";} + virtual void refresh(const Field &U, GridParallelRNG &pRNG){}; // noop as no pseudoferms @@ -74,4 +76,4 @@ class ScalarAction : public Action { } } -#endif \ No newline at end of file +#endif From b812d5e39c57d14f3cc4c769ed1f72cf90691cb4 Mon Sep 17 00:00:00 2001 From: Guido Cossu Date: Tue, 6 Dec 2016 16:31:13 +0000 Subject: [PATCH 038/214] Added single threaded version of the derivative for the Ls vectorised DWF --- lib/cartesian/Cartesian_base.h | 48 +++-- lib/lattice/Lattice_rng.h | 75 +++++--- lib/qcd/action/fermion/FermionOperatorImpl.h | 168 +++++++++++------- lib/qcd/action/fermion/WilsonFermion5D.cc | 31 ++-- .../EvenOddSchurDifferentiable.h | 22 ++- .../pseudofermion/TwoFlavourEvenOddRatio.h | 4 +- lib/qcd/hmc/integrators/Integrator.h | 1 + lib/simd/Grid_vector_types.h | 13 ++ lib/tensors/Tensor_class.h | 48 +++++ tests/hmc/Test_hmc_EODWFRatio_Binary.cc | 30 +++- .../hmc/Test_hmc_WilsonFermionGauge_Binary.cc | 2 + 11 files changed, 307 insertions(+), 135 deletions(-) diff --git a/lib/cartesian/Cartesian_base.h b/lib/cartesian/Cartesian_base.h index 72b21ee3..334914e9 100644 --- a/lib/cartesian/Cartesian_base.h +++ b/lib/cartesian/Cartesian_base.h @@ -99,7 +99,7 @@ public: virtual int oIndex(std::vector &coor) { int idx=0; - // Works with either global or local coordinates + // Works with either global or local coordinates for(int d=0;d<_ndimension;d++) idx+=_ostride[d]*(coor[d]%_rdimensions[d]); return idx; } @@ -146,15 +146,15 @@ public: // Distance should be either 0,1,2.. // if ( _simd_layout[dimension] > 2 ) { - for(int d=0;d<_ndimension;d++){ - if ( d != dimension ) assert ( (_simd_layout[d]==1) ); - } - permute_type = RotateBit; // How to specify distance; this is not just direction. - return permute_type; + for(int d=0;d<_ndimension;d++){ + if ( d != dimension ) assert ( (_simd_layout[d]==1) ); + } + permute_type = RotateBit; // How to specify distance; this is not just direction. + return permute_type; } for(int d=_ndimension-1;d>dimension;d--){ - if (_simd_layout[d]>1 ) permute_type++; + if (_simd_layout[d]>1 ) permute_type++; } return permute_type; } @@ -174,6 +174,22 @@ public: inline const std::vector &LocalDimensions(void) { return _ldimensions;}; inline const std::vector &VirtualLocalDimensions(void) { return _ldimensions;}; + //////////////////////////////////////////////////////////////// + // Print decomposition + //////////////////////////////////////////////////////////////// + + void show_decomposition(){ + std::cout << GridLogMessage << "Full Dimensions : " << _fdimensions << std::endl; + std::cout << GridLogMessage << "Global Dimensions : " << _gdimensions << std::endl; + std::cout << GridLogMessage << "Local Dimensions : " << _ldimensions << std::endl; + std::cout << GridLogMessage << "Reduced Dimensions : " << _rdimensions << std::endl; + std::cout << GridLogMessage << "iSites : " << _isites << std::endl; + std::cout << GridLogMessage << "oSites : " << _osites << std::endl; + std::cout << GridLogMessage << "lSites : " << lSites() << std::endl; + std::cout << GridLogMessage << "gSites : " << gSites() << std::endl; + std::cout << GridLogMessage << "Nd : " << _ndimension << std::endl; + } + //////////////////////////////////////////////////////////////// // Global addressing //////////////////////////////////////////////////////////////// @@ -187,8 +203,8 @@ public: gidx=0; int mult=1; for(int mu=0;mu<_ndimension;mu++) { - gidx+=mult*gcoor[mu]; - mult*=_gdimensions[mu]; + gidx+=mult*gcoor[mu]; + mult*=_gdimensions[mu]; } } void GlobalCoorToProcessorCoorLocalCoor(std::vector &pcoor,std::vector &lcoor,const std::vector &gcoor) @@ -196,9 +212,9 @@ public: pcoor.resize(_ndimension); lcoor.resize(_ndimension); for(int mu=0;mu<_ndimension;mu++){ - int _fld = _fdimensions[mu]/_processors[mu]; - pcoor[mu] = gcoor[mu]/_fld; - lcoor[mu] = gcoor[mu]%_fld; + int _fld = _fdimensions[mu]/_processors[mu]; + pcoor[mu] = gcoor[mu]/_fld; + lcoor[mu] = gcoor[mu]%_fld; } } void GlobalCoorToRankIndex(int &rank, int &o_idx, int &i_idx ,const std::vector &gcoor) @@ -210,9 +226,9 @@ public: std::vector cblcoor(lcoor); for(int d=0;dCheckerBoarded(d) ) { - cblcoor[d] = lcoor[d]/2; - } + if( this->CheckerBoarded(d) ) { + cblcoor[d] = lcoor[d]/2; + } } i_idx= iIndex(cblcoor);// this does not imply divide by 2 on checker dim @@ -238,7 +254,7 @@ public: { RankIndexToGlobalCoor(rank,o_idx,i_idx ,fcoor); if(CheckerBoarded(0)){ - fcoor[0] = fcoor[0]*2+cb; + fcoor[0] = fcoor[0]*2+cb; } } void ProcessorCoorLocalCoorToGlobalCoor(std::vector &Pcoor,std::vector &Lcoor,std::vector &gcoor) diff --git a/lib/lattice/Lattice_rng.h b/lib/lattice/Lattice_rng.h index cd73b462..c5607ed8 100644 --- a/lib/lattice/Lattice_rng.h +++ b/lib/lattice/Lattice_rng.h @@ -6,8 +6,8 @@ Copyright (C) 2015 -Author: Peter Boyle -Author: paboyle + Author: Peter Boyle + Author: Guido Cossu 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 @@ -67,24 +67,42 @@ namespace Grid { return multiplicity; } + + + inline int RNGfillable_general(GridBase *coarse,GridBase *fine) + { + int rngdims = coarse->_ndimension; + + // trivially extended in higher dims, with locality guaranteeing RNG state is local to node + int lowerdims = fine->_ndimension - coarse->_ndimension; assert(lowerdims >= 0); + // assumes that the higher dimensions are not using more processors + // all further divisions are local + for(int d=0;d_processors[d]==1); + for(int d=0;d_processors[d] == fine->_processors[d+lowerdims]); + + + // then divide the number of local sites + // check that the total number of sims agree, meanse the iSites are the same + assert(fine->Nsimd() == coarse->Nsimd()); + + // check that the two grids divide cleanly + assert( (fine->lSites() / coarse->lSites() ) * coarse->lSites() == fine->lSites() ); + + return fine->lSites() / coarse->lSites(); + } + // Wrap seed_seq to give common interface with random_device class fixedSeed { public: - typedef std::seed_seq::result_type result_type; - std::seed_seq src; fixedSeed(const std::vector &seeds) : src(seeds.begin(),seeds.end()) {}; result_type operator () (void){ - std::vector list(1); - src.generate(list.begin(),list.end()); - return list[0]; - } }; @@ -252,24 +270,30 @@ namespace Grid { }; class GridParallelRNG : public GridRNGbase { + + double _time_counter; + public: GridBase *_grid; - int _vol; + unsigned int _vol; int generator_idx(int os,int is){ return is*_grid->oSites()+os; } GridParallelRNG(GridBase *grid) : GridRNGbase() { - _grid=grid; - _vol =_grid->iSites()*_grid->oSites(); + _grid = grid; + _vol =_grid->iSites()*_grid->oSites(); _generators.resize(_vol); _uniform.resize(_vol,std::uniform_real_distribution{0,1}); _gaussian.resize(_vol,std::normal_distribution(0.0,1.0) ); _bernoulli.resize(_vol,std::discrete_distribution{1,1}); - _seeded=0; + _seeded = 0; + + _time_counter = 0.0; + } @@ -325,37 +349,36 @@ namespace Grid { typedef typename vobj::scalar_type scalar_type; typedef typename vobj::vector_type vector_type; - int multiplicity = RNGfillable(_grid, l._grid); + double inner_time_counter = usecond(); - int Nsimd = _grid->Nsimd(); - int osites = _grid->oSites(); + int multiplicity = RNGfillable_general(_grid, l._grid); // l has finer or same grid + + int Nsimd = _grid->Nsimd();// guaranteed to be the same for l._grid too + int osites = _grid->oSites();// guaranteed to be <= l._grid->oSites() by a factor multiplicity int words = sizeof(scalar_object) / sizeof(scalar_type); PARALLEL_FOR_LOOP for (int ss = 0; ss < osites; ss++) { std::vector buf(Nsimd); - for (int m = 0; m < multiplicity; - m++) { // Draw from same generator multiplicity times + for (int m = 0; m < multiplicity; m++) { // Draw from same generator multiplicity times - int sm = multiplicity * ss + - m; // Maps the generator site to the fine site + int sm = multiplicity * ss + m; // Maps the generator site to the fine site for (int si = 0; si < Nsimd; si++) { int gdx = generator_idx(ss, si); // index of generator state scalar_type *pointer = (scalar_type *)&buf[si]; dist[gdx].reset(); - for (int idx = 0; idx < words; idx++) { - + for (int idx = 0; idx < words; idx++) fillScalar(pointer[idx], dist[gdx], _generators[gdx]); - } } - // merge into SIMD lanes merge(l._odata[sm], buf); } } + + _time_counter += usecond()- inner_time_counter; }; void SeedRandomDevice(void) { @@ -366,6 +389,12 @@ namespace Grid { fixedSeed src(seeds); Seed(src); } + + void Report(){ + std::cout << GridLogMessage << "Time spent in the fill() routine by GridParallelRNG: "<< _time_counter/1e3 << " ms" << std::endl; + } + + }; template inline void random(GridParallelRNG &rng,Lattice &l){ diff --git a/lib/qcd/action/fermion/FermionOperatorImpl.h b/lib/qcd/action/fermion/FermionOperatorImpl.h index 0800dea6..be4f629f 100644 --- a/lib/qcd/action/fermion/FermionOperatorImpl.h +++ b/lib/qcd/action/fermion/FermionOperatorImpl.h @@ -44,14 +44,14 @@ namespace QCD { // Ultimately need Impl to always define types where XXX is opaque // // typedef typename XXX Simd; - // typedef typename XXX GaugeLinkField; + // typedef typename XXX GaugeLinkField; // typedef typename XXX GaugeField; // typedef typename XXX GaugeActField; // typedef typename XXX FermionField; // typedef typename XXX DoubledGaugeField; // typedef typename XXX SiteSpinor; - // typedef typename XXX SiteHalfSpinor; - // typedef typename XXX Compressor; + // typedef typename XXX SiteHalfSpinor; + // typedef typename XXX Compressor; // // and Methods: // void ImportGauge(GridBase *GaugeGrid,DoubledGaugeField &Uds,const GaugeField &Umu) @@ -94,17 +94,17 @@ namespace QCD { //////////////////////////////////////////////////////////////////////// #define INHERIT_FIMPL_TYPES(Impl)\ - typedef typename Impl::FermionField FermionField; \ - typedef typename Impl::DoubledGaugeField DoubledGaugeField; \ - typedef typename Impl::SiteSpinor SiteSpinor; \ - typedef typename Impl::SiteHalfSpinor SiteHalfSpinor; \ - typedef typename Impl::Compressor Compressor; \ - typedef typename Impl::StencilImpl StencilImpl; \ - typedef typename Impl::ImplParams ImplParams; \ + typedef typename Impl::FermionField FermionField; \ + typedef typename Impl::DoubledGaugeField DoubledGaugeField; \ + typedef typename Impl::SiteSpinor SiteSpinor; \ + typedef typename Impl::SiteHalfSpinor SiteHalfSpinor; \ + typedef typename Impl::Compressor Compressor; \ + typedef typename Impl::StencilImpl StencilImpl; \ + typedef typename Impl::ImplParams ImplParams; \ typedef typename Impl::Coeff_t Coeff_t; #define INHERIT_IMPL_TYPES(Base) \ - INHERIT_GIMPL_TYPES(Base) \ + INHERIT_GIMPL_TYPES(Base) \ INHERIT_FIMPL_TYPES(Base) ///////////////////////////////////////////////////////////////////////////// @@ -148,11 +148,11 @@ namespace QCD { bool overlapCommsCompute(void) { return Params.overlapCommsCompute; }; inline void multLink(SiteHalfSpinor &phi, - const SiteDoubledGaugeField &U, - const SiteHalfSpinor &chi, - int mu, - StencilEntry *SE, - StencilImpl &St) { + const SiteDoubledGaugeField &U, + const SiteHalfSpinor &chi, + int mu, + StencilEntry *SE, + StencilImpl &St) { mult(&phi(), &U(mu), &chi()); } @@ -162,16 +162,16 @@ namespace QCD { } inline void DoubleStore(GridBase *GaugeGrid, - DoubledGaugeField &Uds, - const GaugeField &Umu) { + DoubledGaugeField &Uds, + const GaugeField &Umu) { conformable(Uds._grid, GaugeGrid); conformable(Umu._grid, GaugeGrid); GaugeLinkField U(GaugeGrid); for (int mu = 0; mu < Nd; mu++) { - U = PeekIndex(Umu, mu); - PokeIndex(Uds, U, mu); - U = adj(Cshift(U, mu, -1)); - PokeIndex(Uds, U, mu + 4); + U = PeekIndex(Umu, mu); + PokeIndex(Uds, U, mu); + U = adj(Cshift(U, mu, -1)); + PokeIndex(Uds, U, mu + 4); } } @@ -189,11 +189,11 @@ namespace QCD { PARALLEL_FOR_LOOP for(int sss=0;sssoSites();sss++){ - int sU=sss; - for(int s=0;s(outerProduct(Btilde[sF],Atilde[sF])); // ordering here - } + int sU=sss; + for(int s=0;s(outerProduct(Btilde[sF],Atilde[sF])); // ordering here + } } PokeIndex(mat,tmp,mu); @@ -248,12 +248,12 @@ class DomainWallVec5dImpl : public PeriodicGaugeImpl< GaugeImplTypes< S,Nrepres } inline void multLink(SiteHalfSpinor &phi, const SiteDoubledGaugeField &U, - const SiteHalfSpinor &chi, int mu, StencilEntry *SE, - StencilImpl &St) { + const SiteHalfSpinor &chi, int mu, StencilEntry *SE, + StencilImpl &St) { SiteGaugeLink UU; for (int i = 0; i < Nrepresentation; i++) { for (int j = 0; j < Nrepresentation; j++) { - vsplat(UU()()(i, j), U(mu)()(i, j)); + vsplat(UU()()(i, j), U(mu)()(i, j)); } } mult(&phi(), &UU(), &chi()); @@ -290,10 +290,40 @@ class DomainWallVec5dImpl : public PeriodicGaugeImpl< GaugeImplTypes< S,Nrepres { assert(0); } - - inline void InsertForce5D(GaugeField &mat, FermionField &Btilde,FermionField Ã, int mu) - { - assert(0); + + inline void InsertForce5D(GaugeField &mat, FermionField &Btilde, FermionField Ã, int mu) { + int LLs = Btilde._grid->_rdimensions[0]; + conformable(Atilde._grid,Btilde._grid); + GaugeLinkField tmp(mat._grid); + tmp = zero; + typedef decltype(traceIndex(outerProduct(Btilde[0], Atilde[0]))) result_type; + std::vector v_scalar_object(Btilde._grid->Nsimd()); + + PARALLEL_FOR_LOOP + for (int sss = 0; sss < tmp._grid->oSites(); sss++) { + std::vector ocoor; + tmp._grid->oCoorFromOindex(ocoor,sss); + for (int si = 0; si < tmp._grid->iSites(); si++){ + typename result_type::scalar_object scalar_object; + scalar_object = zero; + std::vector local_coor(tmp._grid->Nd()); + std::vector icoor; + tmp._grid->iCoorFromIindex(icoor,si); + for (int i = 0; i < tmp._grid->Nd(); i++) local_coor[i] = ocoor[i] + tmp._grid->_rdimensions[i]*icoor[i]; + + for (int s = 0; s < LLs; s++) { + std::vector slocal_coor(Btilde._grid->Nd()); + slocal_coor[0] = s; + for (int s4d = 1; s4d< Btilde._grid->Nd(); s4d++) slocal_coor[s4d] = local_coor[s4d-1]; + int sF = Btilde._grid->oIndexReduced(slocal_coor); + assert(sF < Btilde._grid->oSites()); + extract(traceIndex(outerProduct(Btilde[sF], Atilde[sF])), v_scalar_object); + for (int sv = 0; sv < v_scalar_object.size(); sv++) scalar_object += v_scalar_object[sv]; // sum across the 5d dimension + } + tmp._odata[sss].putlane(scalar_object, si); + } + } + PokeIndex(mat, tmp, mu); } }; @@ -339,19 +369,19 @@ class GparityWilsonImpl : public ConjugateGaugeImplNsimd(); - + int direction = St._directions[mu]; int distance = St._distances[mu]; int ptype = St._permute_type[mu]; @@ -359,13 +389,13 @@ class GparityWilsonImpl : public ConjugateGaugeImpl icoor; - + if ( SE->_around_the_world && Params.twists[mmu] ) { if ( sl == 2 ) { @@ -375,25 +405,25 @@ class GparityWilsonImpl : public ConjugateGaugeImpliCoorFromIindex(icoor,s); - - assert((icoor[direction]==0)||(icoor[direction]==1)); - - int permute_lane; - if ( distance == 1) { - permute_lane = icoor[direction]?1:0; - } else { - permute_lane = icoor[direction]?0:1; - } - - if ( permute_lane ) { - stmp(0) = vals[s](1); - stmp(1) = vals[s](0); - vals[s] = stmp; - } + grid->iCoorFromIindex(icoor,s); + + assert((icoor[direction]==0)||(icoor[direction]==1)); + + int permute_lane; + if ( distance == 1) { + permute_lane = icoor[direction]?1:0; + } else { + permute_lane = icoor[direction]?0:1; + } + + if ( permute_lane ) { + stmp(0) = vals[s](1); + stmp(1) = vals[s](0); + vals[s] = stmp; + } } merge(vtmp,vals); - + } else { vtmp(0) = chi(1); vtmp(1) = chi(0); @@ -418,11 +448,11 @@ class GparityWilsonImpl : public ConjugateGaugeImpl > coor(GaugeGrid); - + for(int mu=0;mu(Umu,mu); Uconj = conjugate(U); @@ -431,13 +461,13 @@ class GparityWilsonImpl : public ConjugateGaugeImpl_fdimensions[0]; - + GaugeLinkField tmp(mat._grid); tmp = zero; PARALLEL_FOR_LOOP diff --git a/lib/qcd/action/fermion/WilsonFermion5D.cc b/lib/qcd/action/fermion/WilsonFermion5D.cc index d2ac96e3..8b8d1e2d 100644 --- a/lib/qcd/action/fermion/WilsonFermion5D.cc +++ b/lib/qcd/action/fermion/WilsonFermion5D.cc @@ -271,11 +271,14 @@ void WilsonFermion5D::DhopDir(const FermionField &in, FermionField &out,in assert(dirdisp<=7); assert(dirdisp>=0); + int LLs = out._grid->_rdimensions[0]; + PARALLEL_FOR_LOOP for(int ss=0;ssoSites();ss++){ - for(int s=0;soSites()); Kernels::DiracOptDhopDir(Stencil,Umu,Stencil.CommBuf(),sF,sU,in,out,dirdisp,gamma); } } @@ -305,6 +308,8 @@ void WilsonFermion5D::DerivInternal(StencilImpl & st, DerivCommTime+=usecond(); Atilde=A; + int LLs = B._grid->_rdimensions[0]; + DerivComputeTime-=usecond(); for (int mu = 0; mu < Nd; mu++) { @@ -321,20 +326,18 @@ void WilsonFermion5D::DerivInternal(StencilImpl & st, DerivDhopComputeTime -= usecond(); PARALLEL_FOR_LOOP for (int sss = 0; sss < U._grid->oSites(); sss++) { - for (int s = 0; s < Ls; s++) { - int sU = sss; - int sF = s + Ls * sU; - + int sU = sss; + for (int s = 0; s < LLs; s++) { + int sF = s + LLs * sU; assert(sF < B._grid->oSites()); assert(sU < U._grid->oSites()); Kernels::DiracOptDhopDir(st, U, st.CommBuf(), sF, sU, B, Btilde, mu, gamma); - - //////////////////////////// - // spin trace outer product - //////////////////////////// } } + //////////////////////////// + // spin trace outer product + //////////////////////////// DerivDhopComputeTime += usecond(); Impl::InsertForce5D(mat, Btilde, Atilde, mu); } @@ -349,7 +352,7 @@ void WilsonFermion5D::DhopDeriv(GaugeField &mat, { conformable(A._grid,FermionGrid()); conformable(A._grid,B._grid); - conformable(GaugeGrid(),mat._grid); + //conformable(GaugeGrid(),mat._grid); mat.checkerboard = A.checkerboard; @@ -363,7 +366,7 @@ void WilsonFermion5D::DhopDerivEO(GaugeField &mat, int dag) { conformable(A._grid,FermionRedBlackGrid()); - conformable(GaugeRedBlackGrid(),mat._grid); + //conformable(GaugeRedBlackGrid(),mat._grid); conformable(A._grid,B._grid); assert(B.checkerboard==Odd); @@ -381,7 +384,7 @@ void WilsonFermion5D::DhopDerivOE(GaugeField &mat, int dag) { conformable(A._grid,FermionRedBlackGrid()); - conformable(GaugeRedBlackGrid(),mat._grid); + //conformable(GaugeRedBlackGrid(),mat._grid); conformable(A._grid,B._grid); assert(B.checkerboard==Even); diff --git a/lib/qcd/action/pseudofermion/EvenOddSchurDifferentiable.h b/lib/qcd/action/pseudofermion/EvenOddSchurDifferentiable.h index 6837bb19..6965fea9 100644 --- a/lib/qcd/action/pseudofermion/EvenOddSchurDifferentiable.h +++ b/lib/qcd/action/pseudofermion/EvenOddSchurDifferentiable.h @@ -68,8 +68,14 @@ namespace Grid{ assert(U.checkerboard==Odd); assert(V.checkerboard==U.checkerboard); - GaugeField ForceO(ucbgrid); - GaugeField ForceE(ucbgrid); + // NOTE Guido: WE DO NOT WANT TO USE THIS GRID FOR THE FORCE + // INHERIT FROM THE Force field + //GaugeField ForceO(ucbgrid); + //GaugeField ForceE(ucbgrid); + GridRedBlackCartesian* forcecb = new GridRedBlackCartesian(Force._grid); + GaugeField ForceO(forcecb); + GaugeField ForceE(forcecb); + // X^dag Der_oe MeeInv Meo Y // Use Mooee as nontrivial but gauge field indept @@ -110,8 +116,14 @@ namespace Grid{ assert(V.checkerboard==Odd); assert(V.checkerboard==V.checkerboard); - GaugeField ForceO(ucbgrid); - GaugeField ForceE(ucbgrid); + // NOTE Guido: WE DO NOT WANT TO USE THIS GRID FOR THE FORCE + // INHERIT FROM THE Force field + + //GaugeField ForceO(ucbgrid); + //GaugeField ForceE(ucbgrid); + GridRedBlackCartesian* forcecb = new GridRedBlackCartesian(Force._grid); + GaugeField ForceO(forcecb); + GaugeField ForceE(forcecb); // X^dag Der_oe MeeInv Meo Y // Use Mooee as nontrivial but gauge field indept @@ -130,6 +142,8 @@ namespace Grid{ setCheckerboard(Force,ForceE); setCheckerboard(Force,ForceO); Force=-Force; + + } }; diff --git a/lib/qcd/action/pseudofermion/TwoFlavourEvenOddRatio.h b/lib/qcd/action/pseudofermion/TwoFlavourEvenOddRatio.h index a8bd9fe7..d7a26695 100644 --- a/lib/qcd/action/pseudofermion/TwoFlavourEvenOddRatio.h +++ b/lib/qcd/action/pseudofermion/TwoFlavourEvenOddRatio.h @@ -166,7 +166,9 @@ namespace Grid{ FermionField X(NumOp.FermionRedBlackGrid()); FermionField Y(NumOp.FermionRedBlackGrid()); - GaugeField force(NumOp.GaugeGrid()); + //GaugeField force(NumOp.GaugeGrid()); + GaugeField force(dSdU._grid); + conformable(force._grid, dSdU._grid); //Y=Vdag phi //X = (Mdag M)^-1 V^dag phi diff --git a/lib/qcd/hmc/integrators/Integrator.h b/lib/qcd/hmc/integrators/Integrator.h index 6f1e5c45..bc076085 100644 --- a/lib/qcd/hmc/integrators/Integrator.h +++ b/lib/qcd/hmc/integrators/Integrator.h @@ -114,6 +114,7 @@ class Integrator { // Fundamental updates, include smearing for (int a = 0; a < as[level].actions.size(); ++a) { Field force(U._grid); + conformable(U._grid, Mom._grid); Field& Us = Smearer.get_U(as[level].actions.at(a)->is_smeared); as[level].actions.at(a)->deriv(Us, force); // deriv should NOT include Ta diff --git a/lib/simd/Grid_vector_types.h b/lib/simd/Grid_vector_types.h index 42f28b34..fc217cc5 100644 --- a/lib/simd/Grid_vector_types.h +++ b/lib/simd/Grid_vector_types.h @@ -386,6 +386,19 @@ class Grid_simd { } } + /////////////////////////////// + // Getting single lanes + /////////////////////////////// + inline Scalar_type getlane(int lane) { + return ((Scalar_type*)&v)[lane]; + } + + inline void putlane(const Scalar_type &S, int lane){ + ((Scalar_type*)&v)[lane] = S; + } + + + }; // end of Grid_simd class definition diff --git a/lib/tensors/Tensor_class.h b/lib/tensors/Tensor_class.h index 916fc09c..cdd57792 100644 --- a/lib/tensors/Tensor_class.h +++ b/lib/tensors/Tensor_class.h @@ -88,6 +88,21 @@ class iScalar { zeroit(*this); return *this; } + + + // managing the internal vector structure + strong_inline scalar_object getlane(int lane){ + scalar_object ret; + ret._internal = _internal.getlane(lane); + return ret; + } + + strong_inline void putlane(scalar_object &s, int lane){ + _internal.putlane(s._internal,lane); + } + + + friend strong_inline void vstream(iScalar &out, const iScalar &in) { vstream(out._internal, in._internal); @@ -226,6 +241,20 @@ class iVector { zeroit(*this); return *this; } + + strong_inline scalar_object getlane(int lane){ + scalar_object ret; + for (int i = 0; i < N; i++) ret._internal[i] = _internal[i].getlane(lane); + return ret; + } + + strong_inline void putlane(scalar_object &s, int lane){ + for (int i = 0; i < N; i++) _internal[i].putlane(s._internal[i],lane); + } + + + + friend strong_inline void zeroit(iVector &that) { for (int i = 0; i < N; i++) { zeroit(that._internal[i]); @@ -349,6 +378,25 @@ class iMatrix { return *this; } + + strong_inline scalar_object getlane(int lane){ + scalar_object ret; + for (int i = 0; i < N; i++) { + for (int j = 0; j < N; j++) { + ret._internal[i][j] = _internal[i][j].getlane(lane); + } + } + return ret; + } + + strong_inline void putlane(scalar_object &s, int lane){ + for (int i = 0; i < N; i++) + for (int j = 0; j < N; j++) _internal[i][j].putlane(s._internal[i][j],lane); + } + + + + friend strong_inline void zeroit(iMatrix &that){ for(int i=0;i FermionAction; typedef typename FermionAction::FermionField FermionField; - const int Ls = 12; + const int Ls = 8; UGrid = SpaceTimeGrid::makeFourDimGrid(GridDefaultLatt(), GridDefaultSimd(Nd,vComplex::Nsimd()),GridDefaultMpi()); UrbGrid = SpaceTimeGrid::makeFourDimRedBlackGrid(UGrid); + + GridCartesian* sUGrid = SpaceTimeGrid::makeFourDimDWFGrid(GridDefaultLatt(),GridDefaultMpi()); + GridRedBlackCartesian* sUrbGrid = SpaceTimeGrid::makeFourDimRedBlackGrid(sUGrid); + + + FGrid = SpaceTimeGrid::makeFiveDimDWFGrid(Ls,UGrid); + FrbGrid = SpaceTimeGrid::makeFiveDimDWFRedBlackGrid(Ls,UGrid); + + /* FGrid = SpaceTimeGrid::makeFiveDimGrid(Ls,UGrid); FrbGrid = SpaceTimeGrid::makeFiveDimRedBlackGrid(Ls,UGrid); + */ // temporarily need a gauge field LatticeGaugeField U(UGrid); // Gauge action double beta = 4.0; - IwasakiGaugeActionR Iaction(beta); + WilsonGaugeActionR Iaction(beta); Real mass = 0.04; Real pv = 1.0; RealD M5 = 1.5; RealD scale = 2.0; - FermionAction DenOp(U,*FGrid,*FrbGrid,*UGrid,*UrbGrid,mass,M5,scale); - FermionAction NumOp(U,*FGrid,*FrbGrid,*UGrid,*UrbGrid,pv,M5,scale); + FermionAction DenOp(U,*FGrid,*FrbGrid,*sUGrid,*sUrbGrid,mass,M5,scale); + FermionAction NumOp(U,*FGrid,*FrbGrid,*sUGrid,*sUrbGrid,pv,M5,scale); + + std::cout << GridLogMessage << "Frb Osites: " << FrbGrid->oSites() << std::endl; + std::cout << GridLogMessage << "sUGrid Osites: " << sUGrid->oSites() << std::endl; double StoppingCondition = 1.0e-8; double MaxCGIterations = 10000; @@ -94,7 +108,7 @@ public: TwoFlavourEvenOddRatioPseudoFermionAction Nf2(NumOp, DenOp,CG,CG); // Set smearing (true/false), default: false - Nf2.is_smeared = true; + Nf2.is_smeared = false; // Collect actions // here an example of 2 level integration @@ -154,7 +168,7 @@ int main(int argc, char **argv) { // Seeds for the random number generators std::vector SerSeed({1, 2, 3, 4, 5}); - std::vector ParSeed({6, 7, 8, 9, 10}); + std::vector ParSeed({6, 7, 8, 9, 5}); TheHMC.RNGSeeds(SerSeed, ParSeed); TheHMC.MDparameters.set(20, 1.0);// MDsteps, traj length diff --git a/tests/hmc/Test_hmc_WilsonFermionGauge_Binary.cc b/tests/hmc/Test_hmc_WilsonFermionGauge_Binary.cc index 42a903d6..cae53960 100644 --- a/tests/hmc/Test_hmc_WilsonFermionGauge_Binary.cc +++ b/tests/hmc/Test_hmc_WilsonFermionGauge_Binary.cc @@ -156,4 +156,6 @@ int main(int argc, char **argv) { TheHMC.MDparameters.set(10, 1.0);// MDsteps, traj length TheHMC.BuildTheAction(argc, argv); + + Grid_finalize(); } From 143c70e29f4785591e429277a7cdeb4461c9bfd4 Mon Sep 17 00:00:00 2001 From: Guido Cossu Date: Wed, 7 Dec 2016 04:40:25 +0000 Subject: [PATCH 039/214] Debugged the threaded version. Cleaning up --- lib/cartesian/Cartesian_base.h | 36 ++-- lib/qcd/action/fermion/FermionOperatorImpl.h | 52 +++-- lib/qcd/action/fermion/WilsonFermion.cc | 12 +- lib/qcd/action/fermion/WilsonFermion5D.cc | 70 ++----- .../EvenOddSchurDifferentiable.h | 144 +++++++------- .../pseudofermion/TwoFlavourEvenOddRatio.h | 188 +++++++++--------- lib/qcd/hmc/integrators/Integrator.h | 25 +-- tests/hmc/Test_hmc_EODWFRatio_Binary.cc | 1 + 8 files changed, 243 insertions(+), 285 deletions(-) diff --git a/lib/cartesian/Cartesian_base.h b/lib/cartesian/Cartesian_base.h index 334914e9..24ff5d4a 100644 --- a/lib/cartesian/Cartesian_base.h +++ b/lib/cartesian/Cartesian_base.h @@ -122,6 +122,12 @@ public: } + inline void InOutCoorToLocalCoor (std::vector &ocoor, std::vector &icoor, std::vector &lcoor) { + lcoor.resize(_ndimension); + for (int d = 0; d < _ndimension; d++) + lcoor[d] = ocoor[d] + _rdimensions[d] * icoor[d]; + } + ////////////////////////////////////////////////////////// // SIMD lane addressing ////////////////////////////////////////////////////////// @@ -129,6 +135,7 @@ public: { Lexicographic::CoorFromIndex(coor,lane,_simd_layout); } + inline int PermuteDim(int dimension){ return _simd_layout[dimension]>1; } @@ -175,20 +182,22 @@ public: inline const std::vector &VirtualLocalDimensions(void) { return _ldimensions;}; //////////////////////////////////////////////////////////////// - // Print decomposition + // Utility to print the full decomposition details //////////////////////////////////////////////////////////////// - void show_decomposition(){ - std::cout << GridLogMessage << "Full Dimensions : " << _fdimensions << std::endl; - std::cout << GridLogMessage << "Global Dimensions : " << _gdimensions << std::endl; - std::cout << GridLogMessage << "Local Dimensions : " << _ldimensions << std::endl; - std::cout << GridLogMessage << "Reduced Dimensions : " << _rdimensions << std::endl; - std::cout << GridLogMessage << "iSites : " << _isites << std::endl; - std::cout << GridLogMessage << "oSites : " << _osites << std::endl; - std::cout << GridLogMessage << "lSites : " << lSites() << std::endl; - std::cout << GridLogMessage << "gSites : " << gSites() << std::endl; - std::cout << GridLogMessage << "Nd : " << _ndimension << std::endl; - } + void show_decomposition(){ + std::cout << GridLogMessage << "Full Dimensions : " << _fdimensions << std::endl; + std::cout << GridLogMessage << "Global Dimensions : " << _gdimensions << std::endl; + std::cout << GridLogMessage << "Local Dimensions : " << _ldimensions << std::endl; + std::cout << GridLogMessage << "Reduced Dimensions : " << _rdimensions << std::endl; + std::cout << GridLogMessage << "Outer strides : " << _ostride << std::endl; + std::cout << GridLogMessage << "Inner strides : " << _istride << std::endl; + std::cout << GridLogMessage << "iSites : " << _isites << std::endl; + std::cout << GridLogMessage << "oSites : " << _osites << std::endl; + std::cout << GridLogMessage << "lSites : " << lSites() << std::endl; + std::cout << GridLogMessage << "gSites : " << gSites() << std::endl; + std::cout << GridLogMessage << "Nd : " << _ndimension << std::endl; + } //////////////////////////////////////////////////////////////// // Global addressing @@ -199,6 +208,9 @@ public: void LocalIndexToLocalCoor(int lidx,std::vector &lcoor){ Lexicographic::CoorFromIndex(lcoor,lidx,_ldimensions); } + + + void GlobalCoorToGlobalIndex(const std::vector & gcoor,int & gidx){ gidx=0; int mult=1; diff --git a/lib/qcd/action/fermion/FermionOperatorImpl.h b/lib/qcd/action/fermion/FermionOperatorImpl.h index be4f629f..78bc52b4 100644 --- a/lib/qcd/action/fermion/FermionOperatorImpl.h +++ b/lib/qcd/action/fermion/FermionOperatorImpl.h @@ -292,35 +292,43 @@ class DomainWallVec5dImpl : public PeriodicGaugeImpl< GaugeImplTypes< S,Nrepres } inline void InsertForce5D(GaugeField &mat, FermionField &Btilde, FermionField Ã, int mu) { - int LLs = Btilde._grid->_rdimensions[0]; - conformable(Atilde._grid,Btilde._grid); - GaugeLinkField tmp(mat._grid); - tmp = zero; typedef decltype(traceIndex(outerProduct(Btilde[0], Atilde[0]))) result_type; - std::vector v_scalar_object(Btilde._grid->Nsimd()); + unsigned int LLs = Btilde._grid->_rdimensions[0]; + conformable(Atilde._grid,Btilde._grid); + GridBase* grid = mat._grid; + GridBase* Bgrid = Btilde._grid; + unsigned int dimU = grid->Nd(); + unsigned int dimF = Bgrid->Nd(); + GaugeLinkField tmp(grid); + tmp = zero; + + // FIXME + // Current implementation works, thread safe, probably suboptimal PARALLEL_FOR_LOOP - for (int sss = 0; sss < tmp._grid->oSites(); sss++) { - std::vector ocoor; - tmp._grid->oCoorFromOindex(ocoor,sss); + for (int so = 0; so < grid->oSites(); so++) { + std::vector vres(Bgrid->Nsimd()); + std::vector ocoor; grid->oCoorFromOindex(ocoor,so); for (int si = 0; si < tmp._grid->iSites(); si++){ - typename result_type::scalar_object scalar_object; - scalar_object = zero; - std::vector local_coor(tmp._grid->Nd()); - std::vector icoor; - tmp._grid->iCoorFromIindex(icoor,si); - for (int i = 0; i < tmp._grid->Nd(); i++) local_coor[i] = ocoor[i] + tmp._grid->_rdimensions[i]*icoor[i]; - + typename result_type::scalar_object scalar_object; scalar_object = zero; + std::vector local_coor; + std::vector icoor; grid->iCoorFromIindex(icoor,si); + grid->InOutCoorToLocalCoor(ocoor, icoor, local_coor); + //for (int i = 0; i < dimU; i++) local_coor[i] = ocoor[i] + grid->_rdimensions[i]*icoor[i]; + //std::cout << "so: " << so << " si: "<< si << " local_coor: " << local_coor << std::endl; + for (int s = 0; s < LLs; s++) { - std::vector slocal_coor(Btilde._grid->Nd()); + std::vector slocal_coor(dimF); slocal_coor[0] = s; - for (int s4d = 1; s4d< Btilde._grid->Nd(); s4d++) slocal_coor[s4d] = local_coor[s4d-1]; - int sF = Btilde._grid->oIndexReduced(slocal_coor); - assert(sF < Btilde._grid->oSites()); - extract(traceIndex(outerProduct(Btilde[sF], Atilde[sF])), v_scalar_object); - for (int sv = 0; sv < v_scalar_object.size(); sv++) scalar_object += v_scalar_object[sv]; // sum across the 5d dimension + for (int s4d = 1; s4d< dimF; s4d++) slocal_coor[s4d] = local_coor[s4d-1]; + int sF = Bgrid->oIndexReduced(slocal_coor); + assert(sF < Bgrid->oSites()); + + extract(traceIndex(outerProduct(Btilde[sF], Atilde[sF])), vres); + // sum across the 5d dimension + for (auto v : vres) scalar_object += v; } - tmp._odata[sss].putlane(scalar_object, si); + tmp._odata[so].putlane(scalar_object, si); } } PokeIndex(mat, tmp, mu); diff --git a/lib/qcd/action/fermion/WilsonFermion.cc b/lib/qcd/action/fermion/WilsonFermion.cc index 99baa8a0..33f6b5ea 100644 --- a/lib/qcd/action/fermion/WilsonFermion.cc +++ b/lib/qcd/action/fermion/WilsonFermion.cc @@ -222,8 +222,7 @@ void WilsonFermion::DerivInternal(StencilImpl &st, DoubledGaugeField &U, //////////////////////// PARALLEL_FOR_LOOP for (int sss = 0; sss < B._grid->oSites(); sss++) { - Kernels::DiracOptDhopDir(st, U, st.CommBuf(), sss, sss, B, Btilde, mu, - gamma); + Kernels::DiracOptDhopDir(st, U, st.CommBuf(), sss, sss, B, Btilde, mu, gamma); } ////////////////////////////////////////////////// @@ -234,8 +233,7 @@ void WilsonFermion::DerivInternal(StencilImpl &st, DoubledGaugeField &U, } template -void WilsonFermion::DhopDeriv(GaugeField &mat, const FermionField &U, - const FermionField &V, int dag) { +void WilsonFermion::DhopDeriv(GaugeField &mat, const FermionField &U, const FermionField &V, int dag) { conformable(U._grid, _grid); conformable(U._grid, V._grid); conformable(U._grid, mat._grid); @@ -246,8 +244,7 @@ void WilsonFermion::DhopDeriv(GaugeField &mat, const FermionField &U, } template -void WilsonFermion::DhopDerivOE(GaugeField &mat, const FermionField &U, - const FermionField &V, int dag) { +void WilsonFermion::DhopDerivOE(GaugeField &mat, const FermionField &U, const FermionField &V, int dag) { conformable(U._grid, _cbgrid); conformable(U._grid, V._grid); conformable(U._grid, mat._grid); @@ -260,8 +257,7 @@ void WilsonFermion::DhopDerivOE(GaugeField &mat, const FermionField &U, } template -void WilsonFermion::DhopDerivEO(GaugeField &mat, const FermionField &U, - const FermionField &V, int dag) { +void WilsonFermion::DhopDerivEO(GaugeField &mat, const FermionField &U, const FermionField &V, int dag) { conformable(U._grid, _cbgrid); conformable(U._grid, V._grid); conformable(U._grid, mat._grid); diff --git a/lib/qcd/action/fermion/WilsonFermion5D.cc b/lib/qcd/action/fermion/WilsonFermion5D.cc index 8b8d1e2d..d930e87c 100644 --- a/lib/qcd/action/fermion/WilsonFermion5D.cc +++ b/lib/qcd/action/fermion/WilsonFermion5D.cc @@ -11,6 +11,7 @@ Author: Peter Boyle Author: Peter Boyle Author: Peter Boyle Author: paboyle +Author: Guido Cossu 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 @@ -132,48 +133,6 @@ WilsonFermion5D::WilsonFermion5D(GaugeField &_Umu, // Allocate the required comms buffer ImportGauge(_Umu); } - /* -template -WilsonFermion5D::WilsonFermion5D(int simd,GaugeField &_Umu, - GridCartesian &FiveDimGrid, - GridRedBlackCartesian &FiveDimRedBlackGrid, - GridCartesian &FourDimGrid, - RealD _M5,const ImplParams &p) : -{ - int nsimd = Simd::Nsimd(); - - // some assertions - assert(FiveDimGrid._ndimension==5); - assert(FiveDimRedBlackGrid._ndimension==5); - assert(FiveDimRedBlackGrid._checker_dim==0); // Checkerboard the s-direction - assert(FourDimGrid._ndimension==4); - - // Dimension zero of the five-d is the Ls direction - Ls=FiveDimGrid._fdimensions[0]; - assert(FiveDimGrid._processors[0] ==1); - assert(FiveDimGrid._simd_layout[0] ==nsimd); - - assert(FiveDimRedBlackGrid._fdimensions[0]==Ls); - assert(FiveDimRedBlackGrid._processors[0] ==1); - assert(FiveDimRedBlackGrid._simd_layout[0]==nsimd); - - // Other dimensions must match the decomposition of the four-D fields - for(int d=0;d<4;d++){ - assert(FiveDimRedBlackGrid._fdimensions[d+1]==FourDimGrid._fdimensions[d]); - assert(FiveDimRedBlackGrid._processors[d+1] ==FourDimGrid._processors[d]); - - assert(FourDimGrid._simd_layout[d]=1); - assert(FiveDimRedBlackGrid._simd_layout[d+1]==1); - - assert(FiveDimGrid._fdimensions[d+1] ==FourDimGrid._fdimensions[d]); - assert(FiveDimGrid._processors[d+1] ==FourDimGrid._processors[d]); - assert(FiveDimGrid._simd_layout[d+1] ==FourDimGrid._simd_layout[d]); - } - - { - } -} - */ template void WilsonFermion5D::Report(void) @@ -346,13 +305,14 @@ void WilsonFermion5D::DerivInternal(StencilImpl & st, template void WilsonFermion5D::DhopDeriv(GaugeField &mat, - const FermionField &A, - const FermionField &B, - int dag) + const FermionField &A, + const FermionField &B, + int dag) { conformable(A._grid,FermionGrid()); conformable(A._grid,B._grid); - //conformable(GaugeGrid(),mat._grid); + + //conformable(GaugeGrid(),mat._grid);// this is not general! leaving as a comment mat.checkerboard = A.checkerboard; @@ -361,12 +321,11 @@ void WilsonFermion5D::DhopDeriv(GaugeField &mat, template void WilsonFermion5D::DhopDerivEO(GaugeField &mat, - const FermionField &A, - const FermionField &B, - int dag) + const FermionField &A, + const FermionField &B, + int dag) { conformable(A._grid,FermionRedBlackGrid()); - //conformable(GaugeRedBlackGrid(),mat._grid); conformable(A._grid,B._grid); assert(B.checkerboard==Odd); @@ -379,12 +338,11 @@ void WilsonFermion5D::DhopDerivEO(GaugeField &mat, template void WilsonFermion5D::DhopDerivOE(GaugeField &mat, - const FermionField &A, - const FermionField &B, - int dag) + const FermionField &A, + const FermionField &B, + int dag) { conformable(A._grid,FermionRedBlackGrid()); - //conformable(GaugeRedBlackGrid(),mat._grid); conformable(A._grid,B._grid); assert(B.checkerboard==Even); @@ -396,8 +354,8 @@ void WilsonFermion5D::DhopDerivOE(GaugeField &mat, template void WilsonFermion5D::DhopInternal(StencilImpl & st, LebesgueOrder &lo, - DoubledGaugeField & U, - const FermionField &in, FermionField &out,int dag) + DoubledGaugeField & U, + const FermionField &in, FermionField &out,int dag) { // assert((dag==DaggerNo) ||(dag==DaggerYes)); Compressor compressor(dag); diff --git a/lib/qcd/action/pseudofermion/EvenOddSchurDifferentiable.h b/lib/qcd/action/pseudofermion/EvenOddSchurDifferentiable.h index 6965fea9..367a735d 100644 --- a/lib/qcd/action/pseudofermion/EvenOddSchurDifferentiable.h +++ b/lib/qcd/action/pseudofermion/EvenOddSchurDifferentiable.h @@ -7,6 +7,7 @@ Copyright (C) 2015 Author: Peter Boyle +Author: Guido Cossu 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 @@ -45,106 +46,97 @@ namespace Grid{ public: INHERIT_IMPL_TYPES(Impl); - typedef FermionOperator Matrix; + typedef FermionOperator Matrix; - SchurDifferentiableOperator (Matrix &Mat) : SchurDiagMooeeOperator(Mat) {}; + SchurDifferentiableOperator (Matrix &Mat) : SchurDiagMooeeOperator(Mat) {}; - void MpcDeriv(GaugeField &Force,const FermionField &U,const FermionField &V) { - - GridBase *fgrid = this->_Mat.FermionGrid(); - GridBase *fcbgrid = this->_Mat.FermionRedBlackGrid(); - GridBase *ugrid = this->_Mat.GaugeGrid(); - GridBase *ucbgrid = this->_Mat.GaugeRedBlackGrid(); + void MpcDeriv(GaugeField &Force,const FermionField &U,const FermionField &V) { + + GridBase *fgrid = this->_Mat.FermionGrid(); + GridBase *fcbgrid = this->_Mat.FermionRedBlackGrid(); - Real coeff = 1.0; + FermionField tmp1(fcbgrid); + FermionField tmp2(fcbgrid); - FermionField tmp1(fcbgrid); - FermionField tmp2(fcbgrid); + conformable(fcbgrid,U._grid); + conformable(fcbgrid,V._grid); - conformable(fcbgrid,U._grid); - conformable(fcbgrid,V._grid); + // Assert the checkerboard?? or code for either + assert(U.checkerboard==Odd); + assert(V.checkerboard==U.checkerboard); - // Assert the checkerboard?? or code for either - assert(U.checkerboard==Odd); - assert(V.checkerboard==U.checkerboard); - - // NOTE Guido: WE DO NOT WANT TO USE THIS GRID FOR THE FORCE - // INHERIT FROM THE Force field - //GaugeField ForceO(ucbgrid); - //GaugeField ForceE(ucbgrid); + // NOTE Guido: WE DO NOT WANT TO USE THE ucbgrid GRID FOR THE FORCE + // it is not conformable with the HMC force field + // INHERIT FROM THE Force field instead GridRedBlackCartesian* forcecb = new GridRedBlackCartesian(Force._grid); GaugeField ForceO(forcecb); GaugeField ForceE(forcecb); - // X^dag Der_oe MeeInv Meo Y - // Use Mooee as nontrivial but gauge field indept - this->_Mat.Meooe (V,tmp1); // odd->even -- implicit -0.5 factor to be applied - this->_Mat.MooeeInv(tmp1,tmp2); // even->even - this->_Mat.MoeDeriv(ForceO,U,tmp2,DaggerNo); - - // Accumulate X^dag M_oe MeeInv Der_eo Y - this->_Mat.MeooeDag (U,tmp1); // even->odd -- implicit -0.5 factor to be applied - this->_Mat.MooeeInvDag(tmp1,tmp2); // even->even - this->_Mat.MeoDeriv(ForceE,tmp2,V,DaggerNo); - - assert(ForceE.checkerboard==Even); - assert(ForceO.checkerboard==Odd); + // X^dag Der_oe MeeInv Meo Y + // Use Mooee as nontrivial but gauge field indept + this->_Mat.Meooe (V,tmp1); // odd->even -- implicit -0.5 factor to be applied + this->_Mat.MooeeInv(tmp1,tmp2); // even->even + this->_Mat.MoeDeriv(ForceO,U,tmp2,DaggerNo); + + // Accumulate X^dag M_oe MeeInv Der_eo Y + this->_Mat.MeooeDag (U,tmp1); // even->odd -- implicit -0.5 factor to be applied + this->_Mat.MooeeInvDag(tmp1,tmp2); // even->even + this->_Mat.MeoDeriv(ForceE,tmp2,V,DaggerNo); + + assert(ForceE.checkerboard==Even); + assert(ForceO.checkerboard==Odd); - setCheckerboard(Force,ForceE); - setCheckerboard(Force,ForceO); - Force=-Force; - } + setCheckerboard(Force,ForceE); + setCheckerboard(Force,ForceO); + Force=-Force; + + delete forcecb; + } - void MpcDagDeriv(GaugeField &Force,const FermionField &U,const FermionField &V) { - - GridBase *fgrid = this->_Mat.FermionGrid(); - GridBase *fcbgrid = this->_Mat.FermionRedBlackGrid(); - GridBase *ugrid = this->_Mat.GaugeGrid(); - GridBase *ucbgrid = this->_Mat.GaugeRedBlackGrid(); + void MpcDagDeriv(GaugeField &Force,const FermionField &U,const FermionField &V) { + + GridBase *fgrid = this->_Mat.FermionGrid(); + GridBase *fcbgrid = this->_Mat.FermionRedBlackGrid(); - Real coeff = 1.0; + FermionField tmp1(fcbgrid); + FermionField tmp2(fcbgrid); - FermionField tmp1(fcbgrid); - FermionField tmp2(fcbgrid); + conformable(fcbgrid,U._grid); + conformable(fcbgrid,V._grid); - conformable(fcbgrid,U._grid); - conformable(fcbgrid,V._grid); + // Assert the checkerboard?? or code for either + assert(V.checkerboard==Odd); + assert(V.checkerboard==V.checkerboard); - // Assert the checkerboard?? or code for either - assert(V.checkerboard==Odd); - assert(V.checkerboard==V.checkerboard); - - // NOTE Guido: WE DO NOT WANT TO USE THIS GRID FOR THE FORCE - // INHERIT FROM THE Force field - - //GaugeField ForceO(ucbgrid); - //GaugeField ForceE(ucbgrid); - GridRedBlackCartesian* forcecb = new GridRedBlackCartesian(Force._grid); + // NOTE Guido: WE DO NOT WANT TO USE THE ucbgrid GRID FOR THE FORCE + // it is not conformable with the HMC force field + // INHERIT FROM THE Force field instead + GridRedBlackCartesian* forcecb = new GridRedBlackCartesian(Force._grid); GaugeField ForceO(forcecb); GaugeField ForceE(forcecb); - // X^dag Der_oe MeeInv Meo Y - // Use Mooee as nontrivial but gauge field indept - this->_Mat.MeooeDag (V,tmp1); // odd->even -- implicit -0.5 factor to be applied - this->_Mat.MooeeInvDag(tmp1,tmp2); // even->even - this->_Mat.MoeDeriv(ForceO,U,tmp2,DaggerYes); - - // Accumulate X^dag M_oe MeeInv Der_eo Y - this->_Mat.Meooe (U,tmp1); // even->odd -- implicit -0.5 factor to be applied - this->_Mat.MooeeInv(tmp1,tmp2); // even->even - this->_Mat.MeoDeriv(ForceE,tmp2,V,DaggerYes); + // X^dag Der_oe MeeInv Meo Y + // Use Mooee as nontrivial but gauge field indept + this->_Mat.MeooeDag (V,tmp1); // odd->even -- implicit -0.5 factor to be applied + this->_Mat.MooeeInvDag(tmp1,tmp2); // even->even + this->_Mat.MoeDeriv(ForceO,U,tmp2,DaggerYes); + + // Accumulate X^dag M_oe MeeInv Der_eo Y + this->_Mat.Meooe (U,tmp1); // even->odd -- implicit -0.5 factor to be applied + this->_Mat.MooeeInv(tmp1,tmp2); // even->even + this->_Mat.MeoDeriv(ForceE,tmp2,V,DaggerYes); - assert(ForceE.checkerboard==Even); - assert(ForceO.checkerboard==Odd); + assert(ForceE.checkerboard==Even); + assert(ForceO.checkerboard==Odd); - setCheckerboard(Force,ForceE); - setCheckerboard(Force,ForceO); - Force=-Force; + setCheckerboard(Force,ForceE); + setCheckerboard(Force,ForceO); + Force=-Force; - - } + delete forcecb; + } }; diff --git a/lib/qcd/action/pseudofermion/TwoFlavourEvenOddRatio.h b/lib/qcd/action/pseudofermion/TwoFlavourEvenOddRatio.h index d7a26695..0f6f3680 100644 --- a/lib/qcd/action/pseudofermion/TwoFlavourEvenOddRatio.h +++ b/lib/qcd/action/pseudofermion/TwoFlavourEvenOddRatio.h @@ -52,68 +52,68 @@ namespace Grid{ public: TwoFlavourEvenOddRatioPseudoFermionAction(FermionOperator &_NumOp, - FermionOperator &_DenOp, - OperatorFunction & DS, - OperatorFunction & AS) : + FermionOperator &_DenOp, + OperatorFunction & DS, + OperatorFunction & AS) : NumOp(_NumOp), DenOp(_DenOp), DerivativeSolver(DS), ActionSolver(AS), PhiEven(_NumOp.FermionRedBlackGrid()), PhiOdd(_NumOp.FermionRedBlackGrid()) - { - conformable(_NumOp.FermionGrid(), _DenOp.FermionGrid()); - conformable(_NumOp.FermionRedBlackGrid(), _DenOp.FermionRedBlackGrid()); - conformable(_NumOp.GaugeGrid(), _DenOp.GaugeGrid()); - conformable(_NumOp.GaugeRedBlackGrid(), _DenOp.GaugeRedBlackGrid()); - }; + { + conformable(_NumOp.FermionGrid(), _DenOp.FermionGrid()); + conformable(_NumOp.FermionRedBlackGrid(), _DenOp.FermionRedBlackGrid()); + conformable(_NumOp.GaugeGrid(), _DenOp.GaugeGrid()); + conformable(_NumOp.GaugeRedBlackGrid(), _DenOp.GaugeRedBlackGrid()); + }; virtual std::string action_name(){return "TwoFlavourEvenOddRatioPseudoFermionAction";} virtual void refresh(const GaugeField &U, GridParallelRNG& pRNG) { - // P(phi) = e^{- phi^dag Vpc (MpcdagMpc)^-1 Vpcdag phi} - // - // NumOp == V - // DenOp == M - // - // Take phi_o = Vpcdag^{-1} Mpcdag eta_o ; eta_o = Mpcdag^{-1} Vpcdag Phi - // - // P(eta_o) = e^{- eta_o^dag eta_o} - // - // e^{x^2/2 sig^2} => sig^2 = 0.5. - // - RealD scale = std::sqrt(0.5); + // P(phi) = e^{- phi^dag Vpc (MpcdagMpc)^-1 Vpcdag phi} + // + // NumOp == V + // DenOp == M + // + // Take phi_o = Vpcdag^{-1} Mpcdag eta_o ; eta_o = Mpcdag^{-1} Vpcdag Phi + // + // P(eta_o) = e^{- eta_o^dag eta_o} + // + // e^{x^2/2 sig^2} => sig^2 = 0.5. + // + RealD scale = std::sqrt(0.5); - FermionField eta (NumOp.FermionGrid()); - FermionField etaOdd (NumOp.FermionRedBlackGrid()); - FermionField etaEven(NumOp.FermionRedBlackGrid()); - FermionField tmp (NumOp.FermionRedBlackGrid()); + FermionField eta (NumOp.FermionGrid()); + FermionField etaOdd (NumOp.FermionRedBlackGrid()); + FermionField etaEven(NumOp.FermionRedBlackGrid()); + FermionField tmp (NumOp.FermionRedBlackGrid()); - gaussian(pRNG,eta); + gaussian(pRNG,eta); - pickCheckerboard(Even,etaEven,eta); - pickCheckerboard(Odd,etaOdd,eta); + pickCheckerboard(Even,etaEven,eta); + pickCheckerboard(Odd,etaOdd,eta); - NumOp.ImportGauge(U); - DenOp.ImportGauge(U); + NumOp.ImportGauge(U); + DenOp.ImportGauge(U); - SchurDifferentiableOperator Mpc(DenOp); - SchurDifferentiableOperator Vpc(NumOp); + SchurDifferentiableOperator Mpc(DenOp); + SchurDifferentiableOperator Vpc(NumOp); - // Odd det factors - Mpc.MpcDag(etaOdd,PhiOdd); - tmp=zero; - ActionSolver(Vpc,PhiOdd,tmp); - Vpc.Mpc(tmp,PhiOdd); + // Odd det factors + Mpc.MpcDag(etaOdd,PhiOdd); + tmp=zero; + ActionSolver(Vpc,PhiOdd,tmp); + Vpc.Mpc(tmp,PhiOdd); - // Even det factors - DenOp.MooeeDag(etaEven,tmp); - NumOp.MooeeInvDag(tmp,PhiEven); + // Even det factors + DenOp.MooeeDag(etaEven,tmp); + NumOp.MooeeInvDag(tmp,PhiEven); - PhiOdd =PhiOdd*scale; - PhiEven=PhiEven*scale; - + PhiOdd =PhiOdd*scale; + PhiEven=PhiEven*scale; + }; ////////////////////////////////////////////////////// @@ -121,33 +121,33 @@ namespace Grid{ ////////////////////////////////////////////////////// virtual RealD S(const GaugeField &U) { - NumOp.ImportGauge(U); - DenOp.ImportGauge(U); + NumOp.ImportGauge(U); + DenOp.ImportGauge(U); - SchurDifferentiableOperator Mpc(DenOp); - SchurDifferentiableOperator Vpc(NumOp); + SchurDifferentiableOperator Mpc(DenOp); + SchurDifferentiableOperator Vpc(NumOp); - FermionField X(NumOp.FermionRedBlackGrid()); - FermionField Y(NumOp.FermionRedBlackGrid()); + FermionField X(NumOp.FermionRedBlackGrid()); + FermionField Y(NumOp.FermionRedBlackGrid()); - Vpc.MpcDag(PhiOdd,Y); // Y= Vdag phi - X=zero; - ActionSolver(Mpc,Y,X); // X= (MdagM)^-1 Vdag phi - //Mpc.Mpc(X,Y); // Y= Mdag^-1 Vdag phi - // Multiply by Ydag - RealD action = real(innerProduct(Y,X)); + Vpc.MpcDag(PhiOdd,Y); // Y= Vdag phi + X=zero; + ActionSolver(Mpc,Y,X); // X= (MdagM)^-1 Vdag phi + //Mpc.Mpc(X,Y); // Y= Mdag^-1 Vdag phi + // Multiply by Ydag + RealD action = real(innerProduct(Y,X)); - //RealD action = norm2(Y); + //RealD action = norm2(Y); - // The EE factorised block; normally can replace with zero if det is constant (gauge field indept) - // Only really clover term that creates this. Leave the EE portion as a future to do to make most - // rapid progresss on DWF for now. - // - NumOp.MooeeDag(PhiEven,X); - DenOp.MooeeInvDag(X,Y); - action = action + norm2(Y); + // The EE factorised block; normally can replace with zero if det is constant (gauge field indept) + // Only really clover term that creates this. Leave the EE portion as a future to do to make most + // rapid progresss on DWF for now. + // + NumOp.MooeeDag(PhiEven,X); + DenOp.MooeeInvDag(X,Y); + action = action + norm2(Y); - return action; + return action; }; ////////////////////////////////////////////////////// @@ -157,46 +157,44 @@ namespace Grid{ ////////////////////////////////////////////////////// virtual void deriv(const GaugeField &U,GaugeField & dSdU) { - NumOp.ImportGauge(U); - DenOp.ImportGauge(U); + NumOp.ImportGauge(U); + DenOp.ImportGauge(U); - SchurDifferentiableOperator Mpc(DenOp); - SchurDifferentiableOperator Vpc(NumOp); + SchurDifferentiableOperator Mpc(DenOp); + SchurDifferentiableOperator Vpc(NumOp); - FermionField X(NumOp.FermionRedBlackGrid()); - FermionField Y(NumOp.FermionRedBlackGrid()); + FermionField X(NumOp.FermionRedBlackGrid()); + FermionField Y(NumOp.FermionRedBlackGrid()); - //GaugeField force(NumOp.GaugeGrid()); - GaugeField force(dSdU._grid); - conformable(force._grid, dSdU._grid); + // This assignment is necessary to be compliant with the HMC grids + GaugeField force(dSdU._grid); - //Y=Vdag phi - //X = (Mdag M)^-1 V^dag phi - //Y = (Mdag)^-1 V^dag phi - Vpc.MpcDag(PhiOdd,Y); // Y= Vdag phi - X=zero; - DerivativeSolver(Mpc,Y,X); // X= (MdagM)^-1 Vdag phi - Mpc.Mpc(X,Y); // Y= Mdag^-1 Vdag phi + //Y=Vdag phi + //X = (Mdag M)^-1 V^dag phi + //Y = (Mdag)^-1 V^dag phi + Vpc.MpcDag(PhiOdd,Y); // Y= Vdag phi + X=zero; + DerivativeSolver(Mpc,Y,X); // X= (MdagM)^-1 Vdag phi + Mpc.Mpc(X,Y); // Y= Mdag^-1 Vdag phi - // phi^dag V (Mdag M)^-1 dV^dag phi - Vpc.MpcDagDeriv(force , X, PhiOdd ); dSdU=force; + // phi^dag V (Mdag M)^-1 dV^dag phi + Vpc.MpcDagDeriv(force , X, PhiOdd ); dSdU = force; - // phi^dag dV (Mdag M)^-1 V^dag phi - Vpc.MpcDeriv(force , PhiOdd, X ); dSdU=dSdU+force; + // phi^dag dV (Mdag M)^-1 V^dag phi + Vpc.MpcDeriv(force , PhiOdd, X ); dSdU = dSdU+force; - // - phi^dag V (Mdag M)^-1 Mdag dM (Mdag M)^-1 V^dag phi - // - phi^dag V (Mdag M)^-1 dMdag M (Mdag M)^-1 V^dag phi - Mpc.MpcDeriv(force,Y,X); dSdU=dSdU-force; - Mpc.MpcDagDeriv(force,X,Y); dSdU=dSdU-force; + // - phi^dag V (Mdag M)^-1 Mdag dM (Mdag M)^-1 V^dag phi + // - phi^dag V (Mdag M)^-1 dMdag M (Mdag M)^-1 V^dag phi + Mpc.MpcDeriv(force,Y,X); dSdU = dSdU-force; + Mpc.MpcDagDeriv(force,X,Y); dSdU = dSdU-force; - // FIXME No force contribution from EvenEven assumed here - // Needs a fix for clover. - assert(NumOp.ConstEE() == 1); - assert(DenOp.ConstEE() == 1); + // FIXME No force contribution from EvenEven assumed here + // Needs a fix for clover. + assert(NumOp.ConstEE() == 1); + assert(DenOp.ConstEE() == 1); - //dSdU = -Ta(dSdU); - dSdU = -dSdU; - + dSdU = -dSdU; + }; }; } diff --git a/lib/qcd/hmc/integrators/Integrator.h b/lib/qcd/hmc/integrators/Integrator.h index bc076085..db3712c0 100644 --- a/lib/qcd/hmc/integrators/Integrator.h +++ b/lib/qcd/hmc/integrators/Integrator.h @@ -57,7 +57,7 @@ struct IntegratorParameters { void print_parameters() { - std::cout << GridLogMessage << "[Integrator] Trajectory length : " << trajL << std::endl; + std::cout << GridLogMessage << "[Integrator] Trajectory length : " << trajL << std::endl; std::cout << GridLogMessage << "[Integrator] Number of MD steps : " << MDsteps << std::endl; std::cout << GridLogMessage << "[Integrator] Step size : " << stepsize << std::endl; } @@ -99,11 +99,9 @@ class Integrator { FieldType forceR(U._grid); // Implement smearing only for the fundamental representation now repr_set.at(a)->deriv(Rep.U, forceR); - GF force = - Rep.RtoFundamentalProject(forceR); // Ta for the fundamental rep - Real force_abs = std::sqrt(norm2(force)); - std::cout << GridLogIntegrator << "Hirep Force average: " - << force_abs / (U._grid->gSites()) << std::endl; + GF force = Rep.RtoFundamentalProject(forceR); // Ta for the fundamental rep + Real force_abs = std::sqrt(norm2(force)/(U._grid->gSites())); + std::cout << GridLogIntegrator << "Hirep Force average: " << force_abs << std::endl; Mom -= force * ep ; } } @@ -118,15 +116,11 @@ class Integrator { Field& Us = Smearer.get_U(as[level].actions.at(a)->is_smeared); as[level].actions.at(a)->deriv(Us, force); // deriv should NOT include Ta - std::cout << GridLogIntegrator - << "Smearing (on/off): " << as[level].actions.at(a)->is_smeared - << std::endl; + std::cout << GridLogIntegrator << "Smearing (on/off): " << as[level].actions.at(a)->is_smeared << std::endl; if (as[level].actions.at(a)->is_smeared) Smearer.smeared_force(force); force = FieldImplementation::projectForce(force); // Ta for gauge fields - Real force_abs = std::sqrt(norm2(force)); - std::cout << GridLogIntegrator - << "Force average: " << force_abs / (U._grid->gSites()) - << std::endl; + Real force_abs = std::sqrt(norm2(force)/U._grid->gSites()); + std::cout << GridLogIntegrator << "Force average: " << force_abs << std::endl; Mom -= force * ep; } @@ -139,10 +133,9 @@ class Integrator { t_U += ep; int fl = levels - 1; - std::cout << GridLogIntegrator << " " - << "[" << fl << "] U " - << " dt " << ep << " : t_U " << t_U << std::endl; + std::cout << GridLogIntegrator << " " << "[" << fl << "] U " << " dt " << ep << " : t_U " << t_U << std::endl; } + void update_U(MomentaField& Mom, Field& U, double ep) { // exponential of Mom*U in the gauge fields case FieldImplementation::update_field(Mom, U, ep); diff --git a/tests/hmc/Test_hmc_EODWFRatio_Binary.cc b/tests/hmc/Test_hmc_EODWFRatio_Binary.cc index 510de3ed..65833024 100644 --- a/tests/hmc/Test_hmc_EODWFRatio_Binary.cc +++ b/tests/hmc/Test_hmc_EODWFRatio_Binary.cc @@ -85,6 +85,7 @@ public: FrbGrid = SpaceTimeGrid::makeFiveDimRedBlackGrid(Ls,UGrid); */ + // temporarily need a gauge field LatticeGaugeField U(UGrid); From 2bd42339198d96e3df8fa938d5e62db0bf125e56 Mon Sep 17 00:00:00 2001 From: Guido Cossu Date: Wed, 7 Dec 2016 04:56:37 +0000 Subject: [PATCH 040/214] Completed testing of the HMC for Ls vectorised version (on AVX2) --- lib/cartesian/Cartesian_base.h | 1 + lib/lattice/Lattice_rng.h | 28 +-- lib/qcd/action/fermion/FermionOperatorImpl.h | 5 +- .../Test_hmc_EODWFRatioLsVectorised_Binary.cc | 170 ++++++++++++++++++ tests/hmc/Test_hmc_EODWFRatio_Binary.cc | 27 +-- 5 files changed, 193 insertions(+), 38 deletions(-) create mode 100644 tests/hmc/Test_hmc_EODWFRatioLsVectorised_Binary.cc diff --git a/lib/cartesian/Cartesian_base.h b/lib/cartesian/Cartesian_base.h index 24ff5d4a..71563b2b 100644 --- a/lib/cartesian/Cartesian_base.h +++ b/lib/cartesian/Cartesian_base.h @@ -8,6 +8,7 @@ Author: Peter Boyle Author: paboyle +Author: Guido Cossu 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 diff --git a/lib/lattice/Lattice_rng.h b/lib/lattice/Lattice_rng.h index c5607ed8..2d0e87c7 100644 --- a/lib/lattice/Lattice_rng.h +++ b/lib/lattice/Lattice_rng.h @@ -148,7 +148,7 @@ namespace Grid { ss<<_generators[gen]; ss.seekg(0,ss.beg); for(int i=0;i>saved[i]; + ss>>saved[i]; } } void SetState(std::vector & saved,int gen){ @@ -315,26 +315,26 @@ namespace Grid { for(int gidx=0;gidxGlobalIndexToGlobalCoor(gidx,gcoor); - _grid->GlobalCoorToRankIndex(rank,o_idx,i_idx,gcoor); + int rank,o_idx,i_idx; + _grid->GlobalIndexToGlobalCoor(gidx,gcoor); + _grid->GlobalCoorToRankIndex(rank,o_idx,i_idx,gcoor); - int l_idx=generator_idx(o_idx,i_idx); + int l_idx=generator_idx(o_idx,i_idx); - const int num_rand_seed=16; - std::vector site_seeds(num_rand_seed); - for(int i=0;i site_seeds(num_rand_seed); + for(int i=0;iBroadcast(0,(void *)&site_seeds[0],sizeof(int)*site_seeds.size()); + _grid->Broadcast(0,(void *)&site_seeds[0],sizeof(int)*site_seeds.size()); - if( rank == _grid->ThisRank() ){ + if( rank == _grid->ThisRank() ){ fixedSeed ssrc(site_seeds); typename source::result_type sinit = ssrc(); _generators[l_idx] = RngEngine(sinit); - } + } } _seeded=1; } @@ -373,7 +373,7 @@ namespace Grid { for (int idx = 0; idx < words; idx++) fillScalar(pointer[idx], dist[gdx], _generators[gdx]); } - // merge into SIMD lanes + // merge into SIMD lanes, FIXME suboptimal implementation merge(l._odata[sm], buf); } } diff --git a/lib/qcd/action/fermion/FermionOperatorImpl.h b/lib/qcd/action/fermion/FermionOperatorImpl.h index 78bc52b4..f658872d 100644 --- a/lib/qcd/action/fermion/FermionOperatorImpl.h +++ b/lib/qcd/action/fermion/FermionOperatorImpl.h @@ -304,6 +304,8 @@ class DomainWallVec5dImpl : public PeriodicGaugeImpl< GaugeImplTypes< S,Nrepres // FIXME // Current implementation works, thread safe, probably suboptimal + // Passing through the local coordinate for grid transformation + // the force grid is in general very different from the Ls vectorized grid PARALLEL_FOR_LOOP for (int so = 0; so < grid->oSites(); so++) { @@ -314,9 +316,6 @@ class DomainWallVec5dImpl : public PeriodicGaugeImpl< GaugeImplTypes< S,Nrepres std::vector local_coor; std::vector icoor; grid->iCoorFromIindex(icoor,si); grid->InOutCoorToLocalCoor(ocoor, icoor, local_coor); - //for (int i = 0; i < dimU; i++) local_coor[i] = ocoor[i] + grid->_rdimensions[i]*icoor[i]; - //std::cout << "so: " << so << " si: "<< si << " local_coor: " << local_coor << std::endl; - for (int s = 0; s < LLs; s++) { std::vector slocal_coor(dimF); slocal_coor[0] = s; diff --git a/tests/hmc/Test_hmc_EODWFRatioLsVectorised_Binary.cc b/tests/hmc/Test_hmc_EODWFRatioLsVectorised_Binary.cc new file mode 100644 index 00000000..13542e04 --- /dev/null +++ b/tests/hmc/Test_hmc_EODWFRatioLsVectorised_Binary.cc @@ -0,0 +1,170 @@ +/************************************************************************************* + +Grid physics library, www.github.com/paboyle/Grid + +Source file: ./tests/Test_hmc_WilsonFermionGauge.cc + +Copyright (C) 2015 + +Author: Peter Boyle +Author: neo +Author: Guido Cossu + +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 + +using namespace std; +using namespace Grid; +using namespace Grid::QCD; + +namespace Grid { +namespace QCD { + + class HMCRunnerParameters : Serializable { + public: + GRID_SERIALIZABLE_CLASS_MEMBERS(HMCRunnerParameters, + double, beta, + double, mass, + int, MaxCGIterations, + double, StoppingCondition, + bool, smearedAction, + int, SaveInterval, + std::string, format, + std::string, conf_prefix, + std::string, rng_prefix, + double, rho, + int, SmearingLevels, + ); + + HMCRunnerParameters() {} + }; + +// Derive from the BinaryHmcRunner (templated for gauge fields) +class HmcRunner : public BinaryHmcRunner { +public: + void BuildTheAction(int argc, char **argv) + + { + typedef DomainWallVec5dImplR ImplPolicy; + typedef ScaledShamirFermion FermionAction; + typedef typename FermionAction::FermionField FermionField; + + const int Ls = 8; + + UGrid = SpaceTimeGrid::makeFourDimGrid(GridDefaultLatt(), GridDefaultSimd(Nd,vComplex::Nsimd()),GridDefaultMpi()); + UrbGrid = SpaceTimeGrid::makeFourDimRedBlackGrid(UGrid); + + + GridCartesian* sUGrid = SpaceTimeGrid::makeFourDimDWFGrid(GridDefaultLatt(),GridDefaultMpi()); + GridRedBlackCartesian* sUrbGrid = SpaceTimeGrid::makeFourDimRedBlackGrid(sUGrid); + + + FGrid = SpaceTimeGrid::makeFiveDimDWFGrid(Ls,UGrid); + FrbGrid = SpaceTimeGrid::makeFiveDimDWFRedBlackGrid(Ls,UGrid); + + // temporarily need a gauge field + LatticeGaugeField U(UGrid); + + // Gauge action + double beta = 4.0; + WilsonGaugeActionR Waction(beta); + + Real mass = 0.04; + Real pv = 1.0; + RealD M5 = 1.5; + RealD scale = 2.0; + FermionAction DenOp(U,*FGrid,*FrbGrid,*sUGrid,*sUrbGrid,mass,M5,scale); + FermionAction NumOp(U,*FGrid,*FrbGrid,*sUGrid,*sUrbGrid,pv,M5,scale); + + double StoppingCondition = 1.0e-8; + double MaxCGIterations = 10000; + ConjugateGradient CG(StoppingCondition,MaxCGIterations); + TwoFlavourEvenOddRatioPseudoFermionAction Nf2(NumOp, DenOp,CG,CG); + + // Set smearing (true/false), default: false + Nf2.is_smeared = true; + + // Collect actions + // here an example of 2 level integration + ActionLevel Level1(1); + Level1.push_back(&Nf2); + + // this level will integrate with a + // step that is 4 times finer + // than the previous level + ActionLevel Level2(4); + Level2.push_back(&Waction); + + TheAction.push_back(Level1); + TheAction.push_back(Level2); + + // Add observables + int SaveInterval = 1; + std::string format = std::string("IEEE64BIG"); + std::string conf_prefix = std::string("DWF_ckpoint_lat"); + std::string rng_prefix = std::string("DWF_ckpoint_rng"); + BinaryHmcCheckpointer Checkpoint(conf_prefix, rng_prefix, SaveInterval, format); + // Can implement also a specific function in the hmcrunner + // AddCheckpoint (...) that takes the same parameters + a string/tag + // defining the type of the checkpointer + // with tags can be implemented by overloading and no ifs + // Then force all checkpoint to have few common functions + // return an object that is then passed to the Run function + + PlaquetteLogger PlaqLog(std::string("Plaquette")); + ObservablesList.push_back(&PlaqLog); + ObservablesList.push_back(&Checkpoint); + + // Smearing section, omit if not needed + double rho = 0.1; // smearing parameter + int Nsmear = 2; // number of smearing levels + Smear_Stout Stout(rho); + SmearedConfiguration SmearingPolicy( + UGrid, Nsmear, Stout); + /////////////////// + + Run(argc, argv, Checkpoint, SmearingPolicy); + //Run(argc, argv, Checkpoint); // no smearing +}; +}; +} +} + +int main(int argc, char **argv) { + Grid_init(&argc, &argv); + + int threads = GridThread::GetThreads(); + std::cout << GridLogMessage << "Grid is setup to use " << threads + << " threads" << std::endl; + + HmcRunner TheHMC; + + + // Seeds for the random number generators + std::vector SerSeed({1, 2, 3, 4, 5}); + std::vector ParSeed({6, 7, 8, 9, 5}); + TheHMC.RNGSeeds(SerSeed, ParSeed); + + TheHMC.MDparameters.set(20, 1.0);// MDsteps, traj length + + TheHMC.BuildTheAction(argc, argv); + + Grid_finalize(); +} diff --git a/tests/hmc/Test_hmc_EODWFRatio_Binary.cc b/tests/hmc/Test_hmc_EODWFRatio_Binary.cc index 65833024..481ff96d 100644 --- a/tests/hmc/Test_hmc_EODWFRatio_Binary.cc +++ b/tests/hmc/Test_hmc_EODWFRatio_Binary.cc @@ -62,8 +62,7 @@ public: void BuildTheAction(int argc, char **argv) { - //typedef WilsonImplR ImplPolicy; - typedef DomainWallVec5dImplR ImplPolicy; + typedef WilsonImplR ImplPolicy; typedef ScaledShamirFermion FermionAction; typedef typename FermionAction::FermionField FermionField; @@ -71,37 +70,23 @@ public: UGrid = SpaceTimeGrid::makeFourDimGrid(GridDefaultLatt(), GridDefaultSimd(Nd,vComplex::Nsimd()),GridDefaultMpi()); UrbGrid = SpaceTimeGrid::makeFourDimRedBlackGrid(UGrid); - - - GridCartesian* sUGrid = SpaceTimeGrid::makeFourDimDWFGrid(GridDefaultLatt(),GridDefaultMpi()); - GridRedBlackCartesian* sUrbGrid = SpaceTimeGrid::makeFourDimRedBlackGrid(sUGrid); - - FGrid = SpaceTimeGrid::makeFiveDimDWFGrid(Ls,UGrid); - FrbGrid = SpaceTimeGrid::makeFiveDimDWFRedBlackGrid(Ls,UGrid); - - /* FGrid = SpaceTimeGrid::makeFiveDimGrid(Ls,UGrid); FrbGrid = SpaceTimeGrid::makeFiveDimRedBlackGrid(Ls,UGrid); - */ - // temporarily need a gauge field LatticeGaugeField U(UGrid); // Gauge action double beta = 4.0; - WilsonGaugeActionR Iaction(beta); + WilsonGaugeActionR Waction(beta); Real mass = 0.04; Real pv = 1.0; RealD M5 = 1.5; RealD scale = 2.0; - FermionAction DenOp(U,*FGrid,*FrbGrid,*sUGrid,*sUrbGrid,mass,M5,scale); - FermionAction NumOp(U,*FGrid,*FrbGrid,*sUGrid,*sUrbGrid,pv,M5,scale); - - std::cout << GridLogMessage << "Frb Osites: " << FrbGrid->oSites() << std::endl; - std::cout << GridLogMessage << "sUGrid Osites: " << sUGrid->oSites() << std::endl; + FermionAction DenOp(U,*FGrid,*FrbGrid,*UGrid,*UrbGrid,mass,M5,scale); + FermionAction NumOp(U,*FGrid,*FrbGrid,*UGrid,*UrbGrid,pv,M5,scale); double StoppingCondition = 1.0e-8; double MaxCGIterations = 10000; @@ -109,7 +94,7 @@ public: TwoFlavourEvenOddRatioPseudoFermionAction Nf2(NumOp, DenOp,CG,CG); // Set smearing (true/false), default: false - Nf2.is_smeared = false; + Nf2.is_smeared = true; // Collect actions // here an example of 2 level integration @@ -120,7 +105,7 @@ public: // step that is 4 times finer // than the previous level ActionLevel Level2(4); - Level2.push_back(&Iaction); + Level2.push_back(&Waction); TheAction.push_back(Level1); TheAction.push_back(Level2); From 7bc206511390b532f998b3646a10723f15ce4018 Mon Sep 17 00:00:00 2001 From: Guido Cossu Date: Mon, 12 Dec 2016 04:21:34 +0000 Subject: [PATCH 041/214] Adding report at the end of the DWF HMC tests --- .../Test_hmc_EODWFRatioLsVectorised_Binary.cc | 26 +++++++++++++++---- tests/hmc/Test_hmc_EODWFRatio_Binary.cc | 9 +++++++ 2 files changed, 30 insertions(+), 5 deletions(-) diff --git a/tests/hmc/Test_hmc_EODWFRatioLsVectorised_Binary.cc b/tests/hmc/Test_hmc_EODWFRatioLsVectorised_Binary.cc index 13542e04..a2fb8a8b 100644 --- a/tests/hmc/Test_hmc_EODWFRatioLsVectorised_Binary.cc +++ b/tests/hmc/Test_hmc_EODWFRatioLsVectorised_Binary.cc @@ -63,7 +63,8 @@ public: { typedef DomainWallVec5dImplR ImplPolicy; - typedef ScaledShamirFermion FermionAction; + //typedef ScaledShamirFermion FermionAction; + typedef DomainWallFermion FermionAction; typedef typename FermionAction::FermionField FermionField; const int Ls = 8; @@ -83,15 +84,21 @@ public: LatticeGaugeField U(UGrid); // Gauge action - double beta = 4.0; + double beta = 5.6; WilsonGaugeActionR Waction(beta); Real mass = 0.04; Real pv = 1.0; RealD M5 = 1.5; RealD scale = 2.0; + /* + // Scaled Shamir FermionAction DenOp(U,*FGrid,*FrbGrid,*sUGrid,*sUrbGrid,mass,M5,scale); FermionAction NumOp(U,*FGrid,*FrbGrid,*sUGrid,*sUrbGrid,pv,M5,scale); + */ + // Std Domain wall fermion + FermionAction DenOp(U,*FGrid,*FrbGrid,*sUGrid,*sUrbGrid,mass,M5); + FermionAction NumOp(U,*FGrid,*FrbGrid,*sUGrid,*sUrbGrid,pv,M5); double StoppingCondition = 1.0e-8; double MaxCGIterations = 10000; @@ -99,7 +106,7 @@ public: TwoFlavourEvenOddRatioPseudoFermionAction Nf2(NumOp, DenOp,CG,CG); // Set smearing (true/false), default: false - Nf2.is_smeared = true; + Nf2.is_smeared = false; // Collect actions // here an example of 2 level integration @@ -140,8 +147,17 @@ public: UGrid, Nsmear, Stout); /////////////////// - Run(argc, argv, Checkpoint, SmearingPolicy); - //Run(argc, argv, Checkpoint); // no smearing + NumOp.ZeroCounters(); + DenOp.ZeroCounters(); + //Run(argc, argv, Checkpoint, SmearingPolicy); + Run(argc, argv, Checkpoint); // no smearing + + + std::cout << GridLogMessage << "Numerator report, Pauli-Villars term : " << std::endl; + NumOp.Report(); + std::cout << GridLogMessage << "Denominator report, Dw(m) term (includes CG) : " << std::endl; + DenOp.Report(); + }; }; } diff --git a/tests/hmc/Test_hmc_EODWFRatio_Binary.cc b/tests/hmc/Test_hmc_EODWFRatio_Binary.cc index 481ff96d..dccad55c 100644 --- a/tests/hmc/Test_hmc_EODWFRatio_Binary.cc +++ b/tests/hmc/Test_hmc_EODWFRatio_Binary.cc @@ -135,8 +135,17 @@ public: UGrid, Nsmear, Stout); /////////////////// + NumOp.ZeroCounters(); + DenOp.ZeroCounters(); Run(argc, argv, Checkpoint, SmearingPolicy); //Run(argc, argv, Checkpoint); // no smearing + + + + std::cout << GridLogMessage << "Numerator report, Pauli-Villars term : " << std::endl; + NumOp.Report(); + std::cout << GridLogMessage << "Denominator report, Dw(m) term (includes CG) : " << std::endl; + DenOp.Report(); }; }; } From ef72f322d2ec5953118cb450ecce1e98750a20da Mon Sep 17 00:00:00 2001 From: Guido Cossu Date: Tue, 13 Dec 2016 02:24:20 +0000 Subject: [PATCH 042/214] consistency of tests --- lib/serialisation/TextIO.cc | 22 ++++++--- lib/supported_compilers.h | 49 +++++++++++++++++++ .../Test_hmc_EODWFRatioLsVectorised_Binary.cc | 4 +- tests/hmc/Test_hmc_EODWFRatio_Binary.cc | 24 +++++---- 4 files changed, 80 insertions(+), 19 deletions(-) create mode 100644 lib/supported_compilers.h diff --git a/lib/serialisation/TextIO.cc b/lib/serialisation/TextIO.cc index 9d733099..b27b4f1c 100644 --- a/lib/serialisation/TextIO.cc +++ b/lib/serialisation/TextIO.cc @@ -28,10 +28,14 @@ *************************************************************************************/ /* END LEGAL */ #include +#include using namespace Grid; using namespace std; +#define GRID_TEXT_INDENT 2 //number of spaces for indentation of levels + + // Writer implementation /////////////////////////////////////////////////////// TextWriter::TextWriter(const string &fileName) : file_(fileName, ios::out) @@ -50,9 +54,8 @@ void TextWriter::pop(void) void TextWriter::indent(void) { for (int i = 0; i < level_; ++i) - { - file_ << '\t';//is this portable? - } + for (int t = 0; t < GRID_TEXT_INDENT; t++) + file_ << ' '; }; // Reader implementation /////////////////////////////////////////////////////// @@ -61,7 +64,7 @@ TextReader::TextReader(const string &fileName) file_.open(fileName, ios::in); if (!file_.is_open()) { std::cout << GridLogMessage << "TextReader: Error opening file " << fileName << std::endl; - exit(0);// write better error handling + exit(1);// write better error handling } } @@ -81,12 +84,15 @@ void TextReader::checkIndent(void) for (int i = 0; i < level_; ++i) { + bool check = true; + for (int t = 0; t< GRID_TEXT_INDENT; t++){ file_.get(c); - if (c != '\t') + check = check && isspace(c); + } + if (!check) { - cerr << "TextReader: mismatch on tab " << c << " level " << level_; - cerr << " i "<< i << endl; - abort(); + cerr << "TextReader: mismatch on level " << level_ << std::endl; + exit(1); } } } diff --git a/lib/supported_compilers.h b/lib/supported_compilers.h new file mode 100644 index 00000000..cec68713 --- /dev/null +++ b/lib/supported_compilers.h @@ -0,0 +1,49 @@ + /************************************************************************************* + + Grid physics library, www.github.com/paboyle/Grid + + Source file: ./lib/supported_compilers.h + + Copyright (C) 2016 + + Author: Guido Cossu + + + 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 */ + + + +#ifndef COMPILER_CHECK_H +#define COMPILER_CHECK_H + +// exclude unsupported compilers +#if defined(__clang__) + #define CLANG_VERSION (__clang_major__ * 10000 + __clang_minor__ * 100 + __clang_patchlevel__) + #if CLANG_VERSION < 30800 + #error "unsupported Clang version" + #endif +#elif defined(__GNUC__) + #define GCC_VERSION (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__) + #if GCC_VERSION < 40800 + #error "unsupported GCC version" + #endif +#endif + + +#endif diff --git a/tests/hmc/Test_hmc_EODWFRatioLsVectorised_Binary.cc b/tests/hmc/Test_hmc_EODWFRatioLsVectorised_Binary.cc index a2fb8a8b..ee2df810 100644 --- a/tests/hmc/Test_hmc_EODWFRatioLsVectorised_Binary.cc +++ b/tests/hmc/Test_hmc_EODWFRatioLsVectorised_Binary.cc @@ -175,10 +175,10 @@ int main(int argc, char **argv) { // Seeds for the random number generators std::vector SerSeed({1, 2, 3, 4, 5}); - std::vector ParSeed({6, 7, 8, 9, 5}); + std::vector ParSeed({6, 7, 8, 9, 10}); TheHMC.RNGSeeds(SerSeed, ParSeed); - TheHMC.MDparameters.set(20, 1.0);// MDsteps, traj length + TheHMC.MDparameters.set(40, 1.0);// MDsteps, traj length TheHMC.BuildTheAction(argc, argv); diff --git a/tests/hmc/Test_hmc_EODWFRatio_Binary.cc b/tests/hmc/Test_hmc_EODWFRatio_Binary.cc index dccad55c..49d4e94d 100644 --- a/tests/hmc/Test_hmc_EODWFRatio_Binary.cc +++ b/tests/hmc/Test_hmc_EODWFRatio_Binary.cc @@ -63,7 +63,8 @@ public: { typedef WilsonImplR ImplPolicy; - typedef ScaledShamirFermion FermionAction; + //typedef ScaledShamirFermion FermionAction; + typedef DomainWallFermionR FermionAction; typedef typename FermionAction::FermionField FermionField; const int Ls = 8; @@ -78,15 +79,19 @@ public: LatticeGaugeField U(UGrid); // Gauge action - double beta = 4.0; + double beta = 5.6; WilsonGaugeActionR Waction(beta); Real mass = 0.04; Real pv = 1.0; RealD M5 = 1.5; RealD scale = 2.0; + /* FermionAction DenOp(U,*FGrid,*FrbGrid,*UGrid,*UrbGrid,mass,M5,scale); FermionAction NumOp(U,*FGrid,*FrbGrid,*UGrid,*UrbGrid,pv,M5,scale); + */ + FermionAction DenOp(U,*FGrid,*FrbGrid,*UGrid,*UrbGrid,mass,M5); + FermionAction NumOp(U,*FGrid,*FrbGrid,*UGrid,*UrbGrid,pv,M5); double StoppingCondition = 1.0e-8; double MaxCGIterations = 10000; @@ -100,15 +105,16 @@ public: // here an example of 2 level integration ActionLevel Level1(1); Level1.push_back(&Nf2); + Level1.push_back(&Waction); // this level will integrate with a // step that is 4 times finer // than the previous level - ActionLevel Level2(4); - Level2.push_back(&Waction); + //ActionLevel Level2(4); + TheAction.push_back(Level1); - TheAction.push_back(Level2); + //TheAction.push_back(Level2); // Add observables int SaveInterval = 1; @@ -137,8 +143,8 @@ public: NumOp.ZeroCounters(); DenOp.ZeroCounters(); - Run(argc, argv, Checkpoint, SmearingPolicy); - //Run(argc, argv, Checkpoint); // no smearing + //Run(argc, argv, Checkpoint, SmearingPolicy); + Run(argc, argv, Checkpoint); // no smearing @@ -163,10 +169,10 @@ int main(int argc, char **argv) { // Seeds for the random number generators std::vector SerSeed({1, 2, 3, 4, 5}); - std::vector ParSeed({6, 7, 8, 9, 5}); + std::vector ParSeed({6, 7, 8, 9, 10}); TheHMC.RNGSeeds(SerSeed, ParSeed); - TheHMC.MDparameters.set(20, 1.0);// MDsteps, traj length + TheHMC.MDparameters.set(40, 1.0);// MDsteps, traj length TheHMC.BuildTheAction(argc, argv); From e0be2b6e6c4f47c41589529610ea6bdeb7f473b7 Mon Sep 17 00:00:00 2001 From: Guido Cossu Date: Tue, 13 Dec 2016 04:59:18 +0000 Subject: [PATCH 043/214] Adding a new tests for the Ls vec CG --- tests/solver/Test_dwf_cg_prec_LsVec.cc | 111 +++++++++++++++++++++++++ 1 file changed, 111 insertions(+) create mode 100644 tests/solver/Test_dwf_cg_prec_LsVec.cc diff --git a/tests/solver/Test_dwf_cg_prec_LsVec.cc b/tests/solver/Test_dwf_cg_prec_LsVec.cc new file mode 100644 index 00000000..744f0065 --- /dev/null +++ b/tests/solver/Test_dwf_cg_prec_LsVec.cc @@ -0,0 +1,111 @@ +/************************************************************************************* + +Grid physics library, www.github.com/paboyle/Grid + +Source file: ./tests/Test_dwf_cg_prec.cc + +Copyright (C) 2016 + +Author: Guido Cossu + +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 + +using namespace std; +using namespace Grid; +using namespace Grid::QCD; + +template +struct scal { + d internal; +}; + +Gamma::GammaMatrix Gmu[] = {Gamma::GammaX, Gamma::GammaY, Gamma::GammaZ, + Gamma::GammaT}; + +int main(int argc, char** argv) { + Grid_init(&argc, &argv); + + const int Ls = 16; + + GridCartesian* UGrid = SpaceTimeGrid::makeFourDimGrid( + GridDefaultLatt(), GridDefaultSimd(Nd, vComplex::Nsimd()), + GridDefaultMpi()); + GridRedBlackCartesian* UrbGrid = + SpaceTimeGrid::makeFourDimRedBlackGrid(UGrid); + + GridCartesian* sUGrid = + SpaceTimeGrid::makeFourDimDWFGrid(GridDefaultLatt(), GridDefaultMpi()); + GridRedBlackCartesian* sUrbGrid = + SpaceTimeGrid::makeFourDimRedBlackGrid(sUGrid); + + GridCartesian* FGrid = SpaceTimeGrid::makeFiveDimDWFGrid(Ls, UGrid); + GridRedBlackCartesian* FrbGrid = SpaceTimeGrid::makeFiveDimDWFRedBlackGrid(Ls, UGrid); + + std::vector seeds4({1, 2, 3, 4}); + std::vector seeds5({5, 6, 7, 8}); + GridParallelRNG RNG5(FGrid); + RNG5.SeedFixedIntegers(seeds5); + GridParallelRNG RNG4(UGrid); + RNG4.SeedFixedIntegers(seeds4); + + LatticeFermion src(FGrid); + random(RNG5, src); + LatticeFermion result(FGrid); + result = zero; + LatticeGaugeField Umu(UGrid); + + SU3::HotConfiguration(RNG4, Umu); + + std::cout << GridLogMessage << "Lattice dimensions: " << GridDefaultLatt() + << " Ls: " << Ls << std::endl; + + std::vector U(4, UGrid); + for (int mu = 0; mu < Nd; mu++) { + U[mu] = PeekIndex(Umu, mu); + } + + RealD mass = 0.01; + RealD M5 = 1.8; + DomainWallFermionVec5dR Ddwf(Umu, *FGrid, *FrbGrid, *sUGrid, *sUrbGrid, mass, M5); + + LatticeFermion src_o(FrbGrid); + LatticeFermion result_o(FrbGrid); + pickCheckerboard(Odd, src_o, src); + result_o = zero; + + GridStopWatch CGTimer; + + SchurDiagMooeeOperator HermOpEO(Ddwf); + ConjugateGradient CG(1.0e-8, 10000, 0);// switch off the assert + + Ddwf.ZeroCounters(); + CGTimer.Start(); + CG(HermOpEO, src_o, result_o); + CGTimer.Stop(); + + std::cout << GridLogMessage << "Total CG time : " << CGTimer.Elapsed() + << std::endl; + + std::cout << GridLogMessage << "######## Dhop calls summary" << std::endl; + Ddwf.Report(); + + Grid_finalize(); +} From 5c74b6028bbe90d2dbcb03103861d7ecabc5379c Mon Sep 17 00:00:00 2001 From: Guido Cossu Date: Tue, 13 Dec 2016 06:35:30 +0000 Subject: [PATCH 044/214] Commit for debugging, lot of IO --- lib/algorithms/LinearOperator.h | 8 +++++++- lib/algorithms/iterative/ConjugateGradient.h | 6 +++++- lib/qcd/action/fermion/CayleyFermion5D.cc | 4 ++++ tests/solver/Test_dwf_cg_prec_LsVec.cc | 8 +++----- 4 files changed, 19 insertions(+), 7 deletions(-) diff --git a/lib/algorithms/LinearOperator.h b/lib/algorithms/LinearOperator.h index ea47d43b..19375827 100644 --- a/lib/algorithms/LinearOperator.h +++ b/lib/algorithms/LinearOperator.h @@ -234,11 +234,17 @@ namespace Grid { virtual RealD MpcDag (const Field &in, Field &out){ Field tmp(in._grid); + std::cout << "norm in :" << norm2(in) << std::endl; _Mat.MeooeDag(in,tmp); - _Mat.MooeeInvDag(tmp,out); + std::cout << "norm tmp :" << norm2(tmp) << std::endl; + _Mat.MooeeInvDag(tmp,out); + std::cout << "norm out :" << norm2(out) << std::endl; _Mat.MeooeDag(out,tmp); + std::cout << "norm tmp :" << norm2(tmp) << std::endl; + _Mat.MooeeDag(in,out); + std::cout << "norm out :" << norm2(out) << std::endl; return axpy_norm(out,-1.0,tmp,out); } }; diff --git a/lib/algorithms/iterative/ConjugateGradient.h b/lib/algorithms/iterative/ConjugateGradient.h index cf3872c8..6fb69540 100644 --- a/lib/algorithms/iterative/ConjugateGradient.h +++ b/lib/algorithms/iterative/ConjugateGradient.h @@ -128,8 +128,12 @@ class ConjugateGradient : public OperatorFunction { p = p * b + r; LinalgTimer.Stop(); + std::cout << GridLogIterative << "ConjugateGradient: Iteration " << k << " residual " << cp << " target " << rsq << std::endl; + std::cout << GridLogDebug << "a = "<< a << " b_pred = "<< b_pred << " b = "<< b << std::endl; + std::cout << GridLogDebug << "qq = "<< qq << " d = "<< d << " c = "<< c << std::endl; + // Stopping condition if (cp <= rsq) { @@ -161,7 +165,7 @@ class ConjugateGradient : public OperatorFunction { } std::cout << GridLogMessage << "ConjugateGradient did NOT converge" << std::endl; - if (ErrorOnNoConverge) assert(0); + if (ErrorOnNoConverge) exit(1); } }; } diff --git a/lib/qcd/action/fermion/CayleyFermion5D.cc b/lib/qcd/action/fermion/CayleyFermion5D.cc index b8e98dce..e99a34be 100644 --- a/lib/qcd/action/fermion/CayleyFermion5D.cc +++ b/lib/qcd/action/fermion/CayleyFermion5D.cc @@ -214,7 +214,9 @@ void CayleyFermion5D::MeooeDag5D (const FermionField &psi, FermionField std::vector lower=cs; upper[Ls-1]=-mass*upper[Ls-1]; lower[0] =-mass*lower[0]; + std::cout << "MeooeDag5D: psi: " << norm2(psi) << std::endl; M5Ddag(psi,psi,Din,lower,diag,upper); + std::cout << "MeooeDag5D: Din: " << norm2(Din) << std::endl; } template @@ -280,7 +282,9 @@ void CayleyFermion5D::MeooeDag (const FermionField &psi, FermionField & } else { this->DhopOE(psi,tmp,DaggerYes); } + std::cout << "MeooeDag: tmp: " << norm2(tmp) << std::endl; MeooeDag5D(tmp,chi); + std::cout << "MeooeDag: chi: " << norm2(chi) << std::endl; } template diff --git a/tests/solver/Test_dwf_cg_prec_LsVec.cc b/tests/solver/Test_dwf_cg_prec_LsVec.cc index 744f0065..c6308958 100644 --- a/tests/solver/Test_dwf_cg_prec_LsVec.cc +++ b/tests/solver/Test_dwf_cg_prec_LsVec.cc @@ -51,12 +51,10 @@ int main(int argc, char** argv) { GridRedBlackCartesian* UrbGrid = SpaceTimeGrid::makeFourDimRedBlackGrid(UGrid); - GridCartesian* sUGrid = - SpaceTimeGrid::makeFourDimDWFGrid(GridDefaultLatt(), GridDefaultMpi()); - GridRedBlackCartesian* sUrbGrid = - SpaceTimeGrid::makeFourDimRedBlackGrid(sUGrid); + GridCartesian* sUGrid = SpaceTimeGrid::makeFourDimDWFGrid(GridDefaultLatt(), GridDefaultMpi()); + GridRedBlackCartesian* sUrbGrid = SpaceTimeGrid::makeFourDimRedBlackGrid(sUGrid); - GridCartesian* FGrid = SpaceTimeGrid::makeFiveDimDWFGrid(Ls, UGrid); + GridCartesian* FGrid = SpaceTimeGrid::makeFiveDimDWFGrid(Ls, UGrid); GridRedBlackCartesian* FrbGrid = SpaceTimeGrid::makeFiveDimDWFRedBlackGrid(Ls, UGrid); std::vector seeds4({1, 2, 3, 4}); From 2fb92dbc6e73f5a74812decb24490a8aab13beb5 Mon Sep 17 00:00:00 2001 From: Guido Cossu Date: Tue, 13 Dec 2016 07:53:43 +0000 Subject: [PATCH 045/214] Cleaning up previous debug lines --- lib/algorithms/LinearOperator.h | 6 ------ lib/qcd/action/fermion/CayleyFermion5D.cc | 4 ---- tests/hmc/Test_hmc_EODWFRatio.cc | 6 +++--- tests/solver/Test_dwf_cg_prec_LsVec.cc | 1 + 4 files changed, 4 insertions(+), 13 deletions(-) diff --git a/lib/algorithms/LinearOperator.h b/lib/algorithms/LinearOperator.h index 19375827..6cb77296 100644 --- a/lib/algorithms/LinearOperator.h +++ b/lib/algorithms/LinearOperator.h @@ -234,17 +234,11 @@ namespace Grid { virtual RealD MpcDag (const Field &in, Field &out){ Field tmp(in._grid); - std::cout << "norm in :" << norm2(in) << std::endl; _Mat.MeooeDag(in,tmp); - std::cout << "norm tmp :" << norm2(tmp) << std::endl; _Mat.MooeeInvDag(tmp,out); - std::cout << "norm out :" << norm2(out) << std::endl; _Mat.MeooeDag(out,tmp); - std::cout << "norm tmp :" << norm2(tmp) << std::endl; - _Mat.MooeeDag(in,out); - std::cout << "norm out :" << norm2(out) << std::endl; return axpy_norm(out,-1.0,tmp,out); } }; diff --git a/lib/qcd/action/fermion/CayleyFermion5D.cc b/lib/qcd/action/fermion/CayleyFermion5D.cc index e99a34be..b8e98dce 100644 --- a/lib/qcd/action/fermion/CayleyFermion5D.cc +++ b/lib/qcd/action/fermion/CayleyFermion5D.cc @@ -214,9 +214,7 @@ void CayleyFermion5D::MeooeDag5D (const FermionField &psi, FermionField std::vector lower=cs; upper[Ls-1]=-mass*upper[Ls-1]; lower[0] =-mass*lower[0]; - std::cout << "MeooeDag5D: psi: " << norm2(psi) << std::endl; M5Ddag(psi,psi,Din,lower,diag,upper); - std::cout << "MeooeDag5D: Din: " << norm2(Din) << std::endl; } template @@ -282,9 +280,7 @@ void CayleyFermion5D::MeooeDag (const FermionField &psi, FermionField & } else { this->DhopOE(psi,tmp,DaggerYes); } - std::cout << "MeooeDag: tmp: " << norm2(tmp) << std::endl; MeooeDag5D(tmp,chi); - std::cout << "MeooeDag: chi: " << norm2(chi) << std::endl; } template diff --git a/tests/hmc/Test_hmc_EODWFRatio.cc b/tests/hmc/Test_hmc_EODWFRatio.cc index 02b312b8..6010ea03 100644 --- a/tests/hmc/Test_hmc_EODWFRatio.cc +++ b/tests/hmc/Test_hmc_EODWFRatio.cc @@ -60,9 +60,9 @@ public: // Gauge action WilsonGaugeActionR Waction(5.6); - Real mass=0.04; - Real pv =1.0; - RealD M5=1.5; + Real mass= 0.04; + Real pv = 1.0; + RealD M5 = 1.5; FermionAction DenOp(U,*FGrid,*FrbGrid,*UGrid,*UrbGrid,mass,M5); FermionAction NumOp(U,*FGrid,*FrbGrid,*UGrid,*UrbGrid,pv,M5); diff --git a/tests/solver/Test_dwf_cg_prec_LsVec.cc b/tests/solver/Test_dwf_cg_prec_LsVec.cc index c6308958..790e4e06 100644 --- a/tests/solver/Test_dwf_cg_prec_LsVec.cc +++ b/tests/solver/Test_dwf_cg_prec_LsVec.cc @@ -64,6 +64,7 @@ int main(int argc, char** argv) { GridParallelRNG RNG4(UGrid); RNG4.SeedFixedIntegers(seeds4); + std::cout << GridLogMessage << "Generating source field" << std::endl; LatticeFermion src(FGrid); random(RNG5, src); LatticeFermion result(FGrid); From af0ccdd8e9d85da5bd0e185170c12d912f355093 Mon Sep 17 00:00:00 2001 From: Guido Cossu Date: Wed, 14 Dec 2016 02:02:42 +0000 Subject: [PATCH 046/214] Moving output order --- tests/solver/Test_dwf_cg_prec_LsVec.cc | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/tests/solver/Test_dwf_cg_prec_LsVec.cc b/tests/solver/Test_dwf_cg_prec_LsVec.cc index 790e4e06..3fbec4d3 100644 --- a/tests/solver/Test_dwf_cg_prec_LsVec.cc +++ b/tests/solver/Test_dwf_cg_prec_LsVec.cc @@ -57,6 +57,9 @@ int main(int argc, char** argv) { GridCartesian* FGrid = SpaceTimeGrid::makeFiveDimDWFGrid(Ls, UGrid); GridRedBlackCartesian* FrbGrid = SpaceTimeGrid::makeFiveDimDWFRedBlackGrid(Ls, UGrid); + std::cout << GridLogMessage << "Lattice dimensions: " << GridDefaultLatt() + << " Ls: " << Ls << std::endl; + std::vector seeds4({1, 2, 3, 4}); std::vector seeds5({5, 6, 7, 8}); GridParallelRNG RNG5(FGrid); @@ -64,17 +67,17 @@ int main(int argc, char** argv) { GridParallelRNG RNG4(UGrid); RNG4.SeedFixedIntegers(seeds4); - std::cout << GridLogMessage << "Generating source field" << std::endl; + std::cout << GridLogMessage << "Generating random ferrmion field" << std::endl; LatticeFermion src(FGrid); random(RNG5, src); LatticeFermion result(FGrid); result = zero; LatticeGaugeField Umu(UGrid); + std::cout << GridLogMessage << "Generating random gauge field" << std::endl; SU3::HotConfiguration(RNG4, Umu); - std::cout << GridLogMessage << "Lattice dimensions: " << GridDefaultLatt() - << " Ls: " << Ls << std::endl; + std::vector U(4, UGrid); for (int mu = 0; mu < Nd; mu++) { From 0bd296dda42b7cd65becf643fa62b4b1ad0be53d Mon Sep 17 00:00:00 2001 From: Guido Cossu Date: Wed, 14 Dec 2016 03:15:09 +0000 Subject: [PATCH 047/214] Adding check of the Dag part in the benchmark --- benchmarks/Benchmark_dwf.cc | 95 +++++++++++++++----- lib/algorithms/iterative/ConjugateGradient.h | 1 - lib/simd/Grid_avx.h | 4 +- 3 files changed, 76 insertions(+), 24 deletions(-) diff --git a/benchmarks/Benchmark_dwf.cc b/benchmarks/Benchmark_dwf.cc index 10e4521b..76625973 100644 --- a/benchmarks/Benchmark_dwf.cc +++ b/benchmarks/Benchmark_dwf.cc @@ -163,6 +163,24 @@ int main (int argc, char ** argv) Dw.Report(); } + if (1) { // Naive wilson dag implementation + ref = zero; + for (int mu = 0; mu < Nd; mu++) { + // ref = src - Gamma(Gamma::GammaX)* src ; // 1+gamma_x + tmp = U[mu] * Cshift(src, mu + 1, 1); + for (int i = 0; i < ref._odata.size(); i++) { + ref._odata[i] += tmp._odata[i] + Gamma(Gmu[mu]) * tmp._odata[i]; + } + + tmp = adj(U[mu]) * src; + tmp = Cshift(tmp, mu + 1, -1); + for (int i = 0; i < ref._odata.size(); i++) { + ref._odata[i] += tmp._odata[i] - Gamma(Gmu[mu]) * tmp._odata[i]; + } + } + ref = -0.5 * ref; + } + if (1) { @@ -245,6 +263,33 @@ int main (int argc, char ** argv) std::cout<::Dhop to naive wilson implementation Dag to verify correctness" << std::endl; + sDw.Dhop(ssrc,sresult,1); + sum=0; + for(int x=0;x site({s,x,y,z,t}); + SpinColourVector normal, simd; + peekSite(normal,ref,site); + peekSite(simd,sresult,site); + sum=sum+norm2(normal-simd); + if (norm2(normal-simd) > 1.0e-6 ) { + std::cout << "site "<1.0e-4) { setCheckerboard(ssrc,ssrc_o); setCheckerboard(ssrc,ssrc_e); std::cout<< ssrc << std::endl; } + + // Check the dag + std::cout << GridLogMessage << "Compare WilsonFermion5D::DhopEO to Dhop to verify correctness" << std::endl; + pickCheckerboard(Even,ssrc_e,ssrc); + pickCheckerboard(Odd,ssrc_o,ssrc); + sDw.DhopEO(ssrc_o,sr_e,DaggerYes); + sDw.DhopOE(ssrc_e,sr_o,DaggerYes); + sDw.Dhop (ssrc ,sresult,DaggerYes); + + pickCheckerboard(Even,ssrc_e,sresult); + pickCheckerboard(Odd ,ssrc_o,sresult); + ssrc_e = ssrc_e - sr_e; + error = norm2(ssrc_e); + + std::cout<1.0e-4) { + setCheckerboard(ssrc,ssrc_o); + setCheckerboard(ssrc,ssrc_e); + std::cout<< ssrc << std::endl; + } + + } } - if (1) - { // Naive wilson dag implementation - ref = zero; - for(int mu=0;mu { std::cout << GridLogDebug << "a = "<< a << " b_pred = "<< b_pred << " b = "<< b << std::endl; std::cout << GridLogDebug << "qq = "<< qq << " d = "<< d << " c = "<< c << std::endl; - // Stopping condition if (cp <= rsq) { SolverTimer.Stop(); diff --git a/lib/simd/Grid_avx.h b/lib/simd/Grid_avx.h index 36360102..77927b10 100644 --- a/lib/simd/Grid_avx.h +++ b/lib/simd/Grid_avx.h @@ -514,7 +514,7 @@ namespace Optimization { template static inline __m256 tRotate(__m256 in){ __m256 tmp = Permute::Permute0(in); - __m256 ret; + __m256 ret = in; if ( n > 3 ) { _mm256_alignr_epi32_grid(ret,in,tmp,n); } else { @@ -526,7 +526,7 @@ namespace Optimization { template static inline __m256d tRotate(__m256d in){ __m256d tmp = Permute::Permute0(in); - __m256d ret; + __m256d ret = in; if ( n > 1 ) { _mm256_alignr_epi64_grid(ret,in,tmp,n); } else { From ce1a115e0b8ff288c3615f8e150ef100053354bc Mon Sep 17 00:00:00 2001 From: Guido Cossu Date: Tue, 20 Dec 2016 17:51:30 +0000 Subject: [PATCH 048/214] Removing redundant arguments for integrator functions, step 1 --- lib/lattice/Lattice_base.h | 19 +++- lib/qcd/hmc/GenericHMCrunner.h | 39 ++++---- lib/qcd/hmc/integrators/Integrator.h | 3 +- lib/simd/Grid_avx.h | 115 +++++++++++------------ lib/supported_compilers.h | 2 +- tests/hmc/Test_hmc_WilsonGauge_Binary.cc | 60 +++++++++++- tests/solver/Test_dwf_cg_prec_LsVec.cc | 6 +- 7 files changed, 152 insertions(+), 92 deletions(-) diff --git a/lib/lattice/Lattice_base.h b/lib/lattice/Lattice_base.h index e4dc1ca8..e6536830 100644 --- a/lib/lattice/Lattice_base.h +++ b/lib/lattice/Lattice_base.h @@ -255,19 +255,28 @@ PARALLEL_FOR_LOOP } Lattice(const Lattice& r){ // copy constructor - _grid = r._grid; - checkerboard = r.checkerboard; + _grid = r._grid; + checkerboard = r.checkerboard; _odata.resize(_grid->oSites());// essential - PARALLEL_FOR_LOOP + PARALLEL_FOR_LOOP for(int ss=0;ss<_grid->oSites();ss++){ - _odata[ss]=r._odata[ss]; + _odata[ss]=r._odata[ss]; } - } + } virtual ~Lattice(void) = default; + void reset(GridBase* grid) { + if (_grid != grid) { + _grid = grid; + _odata.resize(grid->oSites()); + checkerboard = 0; + } + } + + template strong_inline Lattice & operator = (const sobj & r){ PARALLEL_FOR_LOOP for(int ss=0;ss<_grid->oSites();ss++){ diff --git a/lib/qcd/hmc/GenericHMCrunner.h b/lib/qcd/hmc/GenericHMCrunner.h index 114595b1..2530559f 100644 --- a/lib/qcd/hmc/GenericHMCrunner.h +++ b/lib/qcd/hmc/GenericHMCrunner.h @@ -27,17 +27,17 @@ with this program; if not, write to the Free Software Foundation, Inc., directory *************************************************************************************/ /* END LEGAL */ -#ifndef GENERIC_HMC_RUNNER -#define GENERIC_HMC_RUNNER +#ifndef GRID_GENERIC_HMC_RUNNER +#define GRID_GENERIC_HMC_RUNNER namespace Grid { namespace QCD { - // Virtual Class for HMC specific for gauge theories - // implement a specific theory by defining the BuildTheAction - template - class BinaryHmcRunnerTemplate { - public: +// Virtual Class for HMC specific for gauge theories +// implement a specific theory by defining the BuildTheAction +template +class BinaryHmcRunnerTemplate { +public: INHERIT_FIELD_TYPES(Implementation); typedef Implementation ImplPolicy; @@ -56,8 +56,10 @@ namespace QCD { IntegratorParameters MDparameters; GridCartesian * UGrid; - GridCartesian * FGrid; GridRedBlackCartesian *UrbGrid; + + // These two are unnecessary, eliminate + GridCartesian * FGrid; GridRedBlackCartesian *FrbGrid; std::vector SerialSeed; @@ -68,11 +70,11 @@ namespace QCD { ParallelSeed = P; } - virtual void BuildTheAction(int argc, char **argv) = 0; // necessary? + virtual void BuildTheAction(int argc, char **argv) = 0; // necessary? // A couple of wrapper classes template - void Run(int argc, char **argv, IOCheckpointer &Checkpoint) { + void Run(int argc, char **argv, IOCheckpointer &Checkpoint) { NoSmearing S; Runner(argc, argv, Checkpoint, S); } @@ -83,6 +85,8 @@ namespace QCD { } ////////////////////////////// + + template void Runner(int argc, @@ -141,11 +145,7 @@ namespace QCD { Field U(UGrid); - typedef MinimumNorm2 - IntegratorType; // change here to change the algorithm - + typedef MinimumNorm2 IntegratorType; // change here to change the algorithm IntegratorType MDynamics(UGrid, MDparameters, TheAction, Smearing); HMCparameters HMCpar; @@ -187,7 +187,7 @@ namespace QCD { // Run it HMC.evolve(); } - }; +}; // These are for gauge fields typedef BinaryHmcRunnerTemplate BinaryHmcRunner; @@ -199,6 +199,7 @@ namespace QCD { typedef BinaryHmcRunnerTemplate ScalarBinaryHmcRunner; -} -} -#endif + +} // namespace QCD +} // namespace Grid +#endif diff --git a/lib/qcd/hmc/integrators/Integrator.h b/lib/qcd/hmc/integrators/Integrator.h index db3712c0..48ec746c 100644 --- a/lib/qcd/hmc/integrators/Integrator.h +++ b/lib/qcd/hmc/integrators/Integrator.h @@ -189,7 +189,8 @@ class Integrator { // Initialization of momenta and actions void refresh(Field& U, GridParallelRNG& pRNG) { - assert(P._grid == U._grid); + //assert(P._grid == U._grid); + P.reset(U._grid); std::cout << GridLogIntegrator << "Integrator refresh\n"; FieldImplementation::generate_momenta(P, pRNG); diff --git a/lib/simd/Grid_avx.h b/lib/simd/Grid_avx.h index 77927b10..ac6ec9f4 100644 --- a/lib/simd/Grid_avx.h +++ b/lib/simd/Grid_avx.h @@ -1,6 +1,6 @@ /************************************************************************************* - Grid physics library, www.github.com/paboyle/Grid + Grid physics library, www.github.com/paboyle/Grid Source file: ./lib/simd/Grid_avx.h @@ -29,15 +29,6 @@ Author: paboyle See the full license in the file "LICENSE" in the top level distribution directory *************************************************************************************/ /* END LEGAL */ -//---------------------------------------------------------------------- -/*! @file Grid_avx.h - @brief Optimization libraries for AVX1/2 instructions set - - Using intrinsics -*/ -// Time-stamp: <2015-06-16 23:30:41 neo> -//---------------------------------------------------------------------- - #include #ifdef AVXFMA4 #include @@ -66,9 +57,9 @@ namespace Optimization { double f[4]; }; - struct Vsplat{ - //Complex float - inline __m256 operator()(float a, float b){ + struct Vsplat{ + // Complex float + inline __m256 operator()(float a, float b) { return _mm256_set_ps(b,a,b,a,b,a,b,a); } // Real float @@ -90,7 +81,7 @@ namespace Optimization { }; struct Vstore{ - //Float + //Float inline void operator()(__m256 a, float* F){ _mm256_store_ps(F,a); } @@ -119,15 +110,15 @@ namespace Optimization { }; struct Vset{ - // Complex float + // Complex float inline __m256 operator()(Grid::ComplexF *a){ return _mm256_set_ps(a[3].imag(),a[3].real(),a[2].imag(),a[2].real(),a[1].imag(),a[1].real(),a[0].imag(),a[0].real()); } - // Complex double + // Complex double inline __m256d operator()(Grid::ComplexD *a){ return _mm256_set_pd(a[1].imag(),a[1].real(),a[0].imag(),a[0].real()); } - // Real float + // Real float inline __m256 operator()(float *a){ return _mm256_set_ps(a[7],a[6],a[5],a[4],a[3],a[2],a[1],a[0]); } @@ -144,8 +135,8 @@ namespace Optimization { template struct Reduce{ - //Need templated class to overload output type - //General form must generate error if compiled + // Need templated class to overload output type + // General form must generate error if compiled inline Out_type operator()(In_type in){ printf("Error, using wrong Reduce function\n"); exit(1); @@ -224,7 +215,7 @@ namespace Optimization { ymm1 = _mm256_shuffle_ps(b,b,_MM_SELECT_FOUR_FOUR(2,3,0,1)); // ymm1 <- br,bi ymm2 = _mm256_shuffle_ps(a,a,_MM_SELECT_FOUR_FOUR(3,3,1,1)); // ymm2 <- ai,ai ymm1 = _mm256_mul_ps(ymm1,ymm2); // ymm1 <- br ai, ai bi - return _mm256_addsub_ps(ymm0,ymm1); + return _mm256_addsub_ps(ymm0,ymm1); #endif #if defined (AVXFMA4) __m256 a_real = _mm256_shuffle_ps(a,a,_MM_SELECT_FOUR_FOUR(2,2,0,0)); // ar ar, @@ -241,10 +232,10 @@ namespace Optimization { #endif } // Complex double - inline __m256d operator()(__m256d a, __m256d b){ - //Multiplication of (ak+ibk)*(ck+idk) + inline __m256d operator()(__m256d a, __m256d b) { + // Multiplication of (ak+ibk)*(ck+idk) // a + i b can be stored as a data structure - //From intel optimisation reference guide + // From intel optimisation reference guide /* movsldup xmm0, Src1; load real parts into the destination, ; a1, a1, a0, a0 @@ -268,7 +259,7 @@ namespace Optimization { __m256d ymm0,ymm1,ymm2; ymm0 = _mm256_shuffle_pd(a,a,0x0); // ymm0 <- ar ar, ar,ar b'00,00 ymm0 = _mm256_mul_pd(ymm0,b); // ymm0 <- ar bi, ar br - ymm1 = _mm256_shuffle_pd(b,b,0x5); // ymm1 <- br,bi b'01,01 + ymm1 = _mm256_shuffle_pd(b,b,0x5); // ymm1 <- br,bi b'01,01 ymm2 = _mm256_shuffle_pd(a,a,0xF); // ymm2 <- ai,ai b'11,11 ymm1 = _mm256_mul_pd(ymm1,ymm2); // ymm1 <- br ai, ai bi return _mm256_addsub_pd(ymm0,ymm1); @@ -365,10 +356,10 @@ namespace Optimization { } }; - struct Div{ + struct Div { // Real float - inline __m256 operator()(__m256 a, __m256 b){ - return _mm256_div_ps(a,b); + inline __m256 operator()(__m256 a, __m256 b) { + return _mm256_div_ps(a, b); } // Real double inline __m256d operator()(__m256d a, __m256d b){ @@ -454,7 +445,7 @@ namespace Optimization { #define _mm256_alignr_epi64_grid(ret,a,b,n) ret=(__m256d) _mm256_alignr_epi8((__m256i)a,(__m256i)b,(n*8)%16) #endif -#if defined (AVX1) || defined (AVXFMA) +#if defined (AVX1) || defined (AVXFMA) #define _mm256_alignr_epi32_grid(ret,a,b,n) { \ __m128 aa, bb; \ \ @@ -487,7 +478,7 @@ namespace Optimization { struct Rotate{ - static inline __m256 rotate(__m256 in,int n){ + static inline __m256 rotate(__m256 in,int n){ switch(n){ case 0: return tRotate<0>(in);break; case 1: return tRotate<1>(in);break; @@ -500,7 +491,7 @@ namespace Optimization { default: assert(0); } } - static inline __m256d rotate(__m256d in,int n){ + static inline __m256d rotate(__m256d in,int n){ switch(n){ case 0: return tRotate<0>(in);break; case 1: return tRotate<1>(in);break; @@ -509,28 +500,28 @@ namespace Optimization { default: assert(0); } } - - - template - static inline __m256 tRotate(__m256 in){ - __m256 tmp = Permute::Permute0(in); - __m256 ret = in; - if ( n > 3 ) { - _mm256_alignr_epi32_grid(ret,in,tmp,n); - } else { - _mm256_alignr_epi32_grid(ret,tmp,in,n); - } - return ret; - }; + template - static inline __m256d tRotate(__m256d in){ - __m256d tmp = Permute::Permute0(in); - __m256d ret = in; - if ( n > 1 ) { - _mm256_alignr_epi64_grid(ret,in,tmp,n); + static inline __m256 tRotate(__m256 in){ + __m256 tmp = Permute::Permute0(in); + __m256 ret; + if ( n > 3 ) { + _mm256_alignr_epi32_grid(ret,in,tmp,n); } else { - _mm256_alignr_epi64_grid(ret,tmp,in,n); + _mm256_alignr_epi32_grid(ret,tmp,in,n); + } + return ret; + } + + template + static inline __m256d tRotate(__m256d in){ + __m256d tmp = Permute::Permute0(in); + __m256d ret; + if ( n > 1 ) { + _mm256_alignr_epi64_grid(ret,in,tmp,n); + } else { + _mm256_alignr_epi64_grid(ret,tmp,in,n); } return ret; }; @@ -543,7 +534,7 @@ namespace Optimization { __m256 v1,v2; v1=Optimization::Permute::Permute0(in); // avx 256; quad complex single v1= _mm256_add_ps(v1,in); - v2=Optimization::Permute::Permute1(v1); + v2=Optimization::Permute::Permute1(v1); v1 = _mm256_add_ps(v1,v2); u256f conv; conv.v = v1; return Grid::ComplexF(conv.f[0],conv.f[1]); @@ -555,15 +546,15 @@ namespace Optimization { __m256 v1,v2; v1 = Optimization::Permute::Permute0(in); // avx 256; octo-double v1 = _mm256_add_ps(v1,in); - v2 = Optimization::Permute::Permute1(v1); + v2 = Optimization::Permute::Permute1(v1); v1 = _mm256_add_ps(v1,v2); - v2 = Optimization::Permute::Permute2(v1); + v2 = Optimization::Permute::Permute2(v1); v1 = _mm256_add_ps(v1,v2); u256f conv; conv.v=v1; return conv.f[0]; } - - + + //Complex double Reduce template<> inline Grid::ComplexD Reduce::operator()(__m256d in){ @@ -573,14 +564,14 @@ namespace Optimization { u256d conv; conv.v = v1; return Grid::ComplexD(conv.f[0],conv.f[1]); } - + //Real double Reduce template<> inline Grid::RealD Reduce::operator()(__m256d in){ __m256d v1,v2; v1 = Optimization::Permute::Permute0(in); // avx 256; quad double v1 = _mm256_add_pd(v1,in); - v2 = Optimization::Permute::Permute1(v1); + v2 = Optimization::Permute::Permute1(v1); v1 = _mm256_add_pd(v1,v2); u256d conv; conv.v = v1; return conv.f[0]; @@ -593,17 +584,17 @@ namespace Optimization { printf("Reduce : Missing integer implementation -> FIX\n"); assert(0); } - + } ////////////////////////////////////////////////////////////////////////////////////// -// Here assign types +// Here assign types typedef __m256 SIMD_Ftype; // Single precision type typedef __m256d SIMD_Dtype; // Double precision type typedef __m256i SIMD_Itype; // Integer type - // prefecthing + // prefecthing inline void v_prefetch0(int size, const char *ptr){ for(int i=0;i using ReduceSIMD = Optimization::Reduce; + template using ReduceSIMD = Optimization::Reduce; // Arithmetic operations typedef Optimization::Sum SumSIMD; @@ -632,4 +623,4 @@ namespace Optimization { typedef Optimization::TimesMinusI TimesMinusISIMD; typedef Optimization::TimesI TimesISIMD; -} +} // namespace Grid diff --git a/lib/supported_compilers.h b/lib/supported_compilers.h index cec68713..b4cd9a78 100644 --- a/lib/supported_compilers.h +++ b/lib/supported_compilers.h @@ -46,4 +46,4 @@ #endif -#endif +#endif // COMPILER_CHECK_H diff --git a/tests/hmc/Test_hmc_WilsonGauge_Binary.cc b/tests/hmc/Test_hmc_WilsonGauge_Binary.cc index 4c650357..d5228ce8 100644 --- a/tests/hmc/Test_hmc_WilsonGauge_Binary.cc +++ b/tests/hmc/Test_hmc_WilsonGauge_Binary.cc @@ -63,6 +63,11 @@ class HMCRunnerParameters : Serializable { class HmcRunner : public BinaryHmcRunner { public: HMCRunnerParameters HMCPar; + void BuildTheAction(int argc, char **argv){} +}; +/* + + // eliminate arcg and argv from here void BuildTheAction(int argc, char **argv) { @@ -90,6 +95,7 @@ class HmcRunner : public BinaryHmcRunner { // Add observables // options for checkpointers + // this can be moved outside the BuildTheAction //BinaryHmcCheckpointer //ILDGHmcCheckpointer //NerscHmcCheckpointer @@ -107,9 +113,11 @@ class HmcRunner : public BinaryHmcRunner { ObservablesList.push_back(&PlaqLog); ObservablesList.push_back(&Checkpoint); + // This must run from here so that the grids are defined Run(argc, argv, Checkpoint); // no smearing }; }; +*/ } } @@ -136,7 +144,57 @@ int main(int argc, char **argv) { TheHMC.MDparameters.set(TheHMC.HMCPar.MDsteps, TheHMC.HMCPar.TrajectorLength); - TheHMC.BuildTheAction(argc, argv); + //TheHMC.BuildTheAction(argc, argv); + + + + // Typedefs to simplify notation + typedef WilsonGaugeActionR GaugeAction; + typedef WilsonImplR ImplPolicy; + typedef WilsonFermionR FermionAction; + typedef typename FermionAction::FermionField FermionField; + + // this can be simplified too. MakeDefaultGrid(Nd) + TheHMC.UGrid = SpaceTimeGrid::makeFourDimGrid( + GridDefaultLatt(), + GridDefaultSimd(Nd, vComplex::Nsimd()), + GridDefaultMpi()); + + + // Gauge action + std::cout << GridLogMessage << "Beta: " << TheHMC.HMCPar.beta << std::endl; + GaugeAction Waction(TheHMC.HMCPar.beta); + + // Collect actions + ActionLevel Level1(1); + Level1.push_back(&Waction); + TheHMC.TheAction.push_back(Level1); + + // Add observables + // options for checkpointers + // this can be moved outside the BuildTheAction + //BinaryHmcCheckpointer + //ILDGHmcCheckpointer + //NerscHmcCheckpointer + NerscHmcCheckpointer Checkpoint( + TheHMC.HMCPar.conf_prefix, TheHMC.HMCPar.rng_prefix, TheHMC.HMCPar.SaveInterval, TheHMC.HMCPar.format); + // Can implement also a specific function in the hmcrunner + // AddCheckpoint (...) that takes the same parameters + a string/tag + // defining the type of the checkpointer + // with tags can be implemented by overloading and no ifs + // Then force all checkpoint to have few common functions + // return an object that is then passed to the Run function + + PlaquetteLogger PlaqLog( + std::string("Plaquette")); + TheHMC.ObservablesList.push_back(&PlaqLog); + TheHMC.ObservablesList.push_back(&Checkpoint); + + // This must run from here so that the grids are defined + TheHMC.Run(argc, argv, Checkpoint); // no smearing + + + Grid_finalize(); } diff --git a/tests/solver/Test_dwf_cg_prec_LsVec.cc b/tests/solver/Test_dwf_cg_prec_LsVec.cc index 3fbec4d3..dfa0a194 100644 --- a/tests/solver/Test_dwf_cg_prec_LsVec.cc +++ b/tests/solver/Test_dwf_cg_prec_LsVec.cc @@ -67,7 +67,7 @@ int main(int argc, char** argv) { GridParallelRNG RNG4(UGrid); RNG4.SeedFixedIntegers(seeds4); - std::cout << GridLogMessage << "Generating random ferrmion field" << std::endl; + std::cout << GridLogMessage << "Generating random fermion field" << std::endl; LatticeFermion src(FGrid); random(RNG5, src); LatticeFermion result(FGrid); @@ -96,7 +96,7 @@ int main(int argc, char** argv) { GridStopWatch CGTimer; SchurDiagMooeeOperator HermOpEO(Ddwf); - ConjugateGradient CG(1.0e-8, 10000, 0);// switch off the assert + ConjugateGradient CG(1.0e-8, 10000, 0); // switch off the assert Ddwf.ZeroCounters(); CGTimer.Start(); @@ -110,4 +110,4 @@ int main(int argc, char** argv) { Ddwf.Report(); Grid_finalize(); -} +} From 52148463418c22fd114dee45c84b11e303010897 Mon Sep 17 00:00:00 2001 From: Guido Cossu Date: Thu, 22 Dec 2016 12:41:56 +0000 Subject: [PATCH 049/214] Adding a resource manager --- lib/Grid.h | 2 + lib/qcd/action/ActionBase.h | 49 ++--- lib/qcd/action/gauge/WilsonGaugeAction.h | 17 +- lib/qcd/hmc/GenericHMCrunner.h | 257 +++++++++++------------ lib/qcd/hmc/HMC.h | 6 +- lib/qcd/hmc/HMCModules.h | 96 +++++++++ lib/qcd/hmc/HMCResourceManager.h | 110 ++++++++++ lib/qcd/hmc/integrators/Integrator.h | 19 +- tests/hmc/Test_hmc_WilsonGauge_Binary.cc | 188 ++++++----------- tests/solver/Test_dwf_cg_prec_LsVec.cc | 2 +- 10 files changed, 435 insertions(+), 311 deletions(-) create mode 100644 lib/qcd/hmc/HMCModules.h create mode 100644 lib/qcd/hmc/HMCResourceManager.h diff --git a/lib/Grid.h b/lib/Grid.h index 78b5a6bd..7eaf8511 100644 --- a/lib/Grid.h +++ b/lib/Grid.h @@ -87,6 +87,8 @@ Author: paboyle #include #include #include +#include +#include #include #include diff --git a/lib/qcd/action/ActionBase.h b/lib/qcd/action/ActionBase.h index 371ccd24..6ff4bcb1 100644 --- a/lib/qcd/action/ActionBase.h +++ b/lib/qcd/action/ActionBase.h @@ -36,14 +36,13 @@ template class Action { public: bool is_smeared = false; - // Boundary conditions? // Heatbath? - virtual void refresh(const GaugeField& U, - GridParallelRNG& pRNG) = 0; // refresh pseudofermions - virtual RealD S(const GaugeField& U) = 0; // evaluate the action - virtual void deriv(const GaugeField& U, - GaugeField& dSdU) = 0; // evaluate the action derivative - virtual std::string action_name() = 0; // return the action name - virtual ~Action(){}; + // Heatbath? + virtual void refresh(const GaugeField& U, const GridParallelRNG& pRNG) = 0; // refresh pseudofermions + virtual RealD S(const GaugeField& U) = 0; // evaluate the action + virtual void deriv(const GaugeField& U, GaugeField& dSdU) = 0; // evaluate the action derivative + virtual std::string action_name() = 0; // return the action name + virtual std::string LogParameters() = 0; // prints action parameters + virtual ~Action(){} }; // Indexing of tuple types @@ -60,32 +59,10 @@ struct Index> { static const std::size_t value = 1 + Index>::value; }; -/* -template -struct ActionLevel { - public: - typedef Action* - ActPtr; // now force the same colours as the rest of the code - - //Add supported representations here - - - unsigned int multiplier; - - std::vector actions; - - ActionLevel(unsigned int mul = 1) : actions(0), multiplier(mul) { - assert(mul >= 1); - }; - - void push_back(ActPtr ptr) { actions.push_back(ptr); } -}; -*/ - template struct ActionLevel { public: - unsigned int multiplier; + unsigned int multiplier; // Fundamental repr actions separated because of the smearing typedef Action* ActPtr; @@ -98,15 +75,13 @@ struct ActionLevel { std::vector& actions; - ActionLevel(unsigned int mul = 1) : actions(std::get<0>(actions_hirep)), multiplier(mul) { + explicit ActionLevel(unsigned int mul = 1) : actions(std::get<0>(actions_hirep)), multiplier(mul) { // initialize the hirep vectors to zero. - //apply(this->resize, actions_hirep, 0); //need a working resize + // apply(this->resize, actions_hirep, 0); //need a working resize assert(mul >= 1); - }; - - //void push_back(ActPtr ptr) { actions.push_back(ptr); } - + } + // void push_back(ActPtr ptr) { actions.push_back(ptr); } template < class GenField > void push_back(Action* ptr) { diff --git a/lib/qcd/action/gauge/WilsonGaugeAction.h b/lib/qcd/action/gauge/WilsonGaugeAction.h index aa61abf2..fd281e20 100644 --- a/lib/qcd/action/gauge/WilsonGaugeAction.h +++ b/lib/qcd/action/gauge/WilsonGaugeAction.h @@ -43,18 +43,22 @@ class WilsonGaugeAction : public Action { public: INHERIT_GIMPL_TYPES(Gimpl); - // typedef LorentzScalar GaugeLinkField; - private: RealD beta; public: - WilsonGaugeAction(RealD b) : beta(b){}; + explicit WilsonGaugeAction(RealD b) : beta(b){} - virtual std::string action_name(){return "WilsonGaugeAction";} + virtual std::string action_name() {return "WilsonGaugeAction";} + + virtual std::string LogParameters(){ + std::stringstream sstream; + sstream << GridLogMessage << "[WilsonGaugeAction] Beta: " << beta << std::endl; + return sstream.str(); + } virtual void refresh(const GaugeField &U, - GridParallelRNG &pRNG){}; // noop as no pseudoferms + const GridParallelRNG &pRNG){}; // noop as no pseudoferms virtual RealD S(const GaugeField &U) { RealD plaq = WilsonLoops::avgPlaquette(U); @@ -80,8 +84,7 @@ class WilsonGaugeAction : public Action { PokeIndex(dSdU, dSdU_mu, mu); } - - }; + } }; diff --git a/lib/qcd/hmc/GenericHMCrunner.h b/lib/qcd/hmc/GenericHMCrunner.h index 2530559f..1d328f8e 100644 --- a/lib/qcd/hmc/GenericHMCrunner.h +++ b/lib/qcd/hmc/GenericHMCrunner.h @@ -30,176 +30,167 @@ with this program; if not, write to the Free Software Foundation, Inc., #ifndef GRID_GENERIC_HMC_RUNNER #define GRID_GENERIC_HMC_RUNNER + +#include + namespace Grid { namespace QCD { -// Virtual Class for HMC specific for gauge theories -// implement a specific theory by defining the BuildTheAction -template +template class Integrator, + class RepresentationsPolicy = NoHirep > class BinaryHmcRunnerTemplate { public: - INHERIT_FIELD_TYPES(Implementation); - typedef Implementation ImplPolicy; + INHERIT_FIELD_TYPES(Implementation); + typedef Implementation ImplPolicy; // visible from outside + template < typename S = NoSmearing > + using IntegratorType = Integrator; - enum StartType_t { ColdStart, - HotStart, - TepidStart, - CheckpointStart }; + enum StartType_t + { + ColdStart, + HotStart, + TepidStart, + CheckpointStart, + FilenameStart + }; - ActionSet TheAction; + struct HMCPayload + { + StartType_t StartType; + HMCparameters Parameters; - // A vector of HmcObservable - // that can be injected from outside - std::vector *> - ObservablesList; + HMCPayload() { StartType = HotStart; } + }; - IntegratorParameters MDparameters; + // These can be rationalised, some private + HMCPayload Payload; // Parameters + HMCResourceManager Resources; + IntegratorParameters MDparameters; - GridCartesian * UGrid; - GridRedBlackCartesian *UrbGrid; + ActionSet TheAction; + + // A vector of HmcObservable that can be injected from outside + std::vector *> ObservablesList; + + //GridCartesian * UGrid; // These two are unnecessary, eliminate - GridCartesian * FGrid; - GridRedBlackCartesian *FrbGrid; + // GridRedBlackCartesian *UrbGrid; + // GridCartesian * FGrid; + // GridRedBlackCartesian *FrbGrid; - std::vector SerialSeed; - std::vector ParallelSeed; + void ReadCommandLine(int argc, char ** argv) { + std::string arg; - void RNGSeeds(std::vector S, std::vector P) { - SerialSeed = S; - ParallelSeed = P; - } + if (GridCmdOptionExists(argv, argv + argc, "--StartType")) { + arg = GridCmdOptionPayload(argv, argv + argc, "--StartType"); + if (arg == "HotStart") { + Payload.StartType = HotStart; + } else if (arg == "ColdStart") { + Payload.StartType = ColdStart; + } else if (arg == "TepidStart") { + Payload.StartType = TepidStart; + } else if (arg == "CheckpointStart") { + Payload.StartType = CheckpointStart; + } else { + std::cout << GridLogError << "Unrecognized option in --StartType\n"; + std::cout + << GridLogError + << "Valid [HotStart, ColdStart, TepidStart, CheckpointStart]\n"; + assert(0); + } + } - virtual void BuildTheAction(int argc, char **argv) = 0; // necessary? + if (GridCmdOptionExists(argv, argv + argc, "--StartTrajectory")) { + arg = GridCmdOptionPayload(argv, argv + argc, "--StartTrajectory"); + std::vector ivec(0); + GridCmdOptionIntVector(arg, ivec); + Payload.Parameters.StartTrajectory = ivec[0]; + } - // A couple of wrapper classes - template - void Run(int argc, char **argv, IOCheckpointer &Checkpoint) { - NoSmearing S; - Runner(argc, argv, Checkpoint, S); - } + if (GridCmdOptionExists(argv, argv + argc, "--Trajectories")) { + arg = GridCmdOptionPayload(argv, argv + argc, "--Trajectories"); + std::vector ivec(0); + GridCmdOptionIntVector(arg, ivec); + Payload.Parameters.Trajectories = ivec[0]; + } - template - void Run(int argc, char **argv, IOCheckpointer &CP, SmearingPolicy &S) { - Runner(argc, argv, CP, S); - } - ////////////////////////////// + if (GridCmdOptionExists(argv, argv + argc, "--Thermalizations")) { + arg = GridCmdOptionPayload(argv, argv + argc, "--Thermalizations"); + std::vector ivec(0); + GridCmdOptionIntVector(arg, ivec); + Payload.Parameters.NoMetropolisUntil = ivec[0]; + } - + } + // A couple of wrapper functions + template void Run(IOCheckpointer &CP) { + NoSmearing S; + Runner(CP, S); + } - template - void Runner(int argc, - char ** argv, - IOCheckpointer &Checkpoint, - SmearingPolicy &Smearing) { - StartType_t StartType = HotStart; + template void Run(IOCheckpointer &CP, SmearingPolicy &S) { + Runner(CP, S); + } - std::string arg; + ////////////////////////////////////////////////////////////////// - if (GridCmdOptionExists(argv, argv + argc, "--StartType")) { - arg = GridCmdOptionPayload(argv, argv + argc, "--StartType"); - if (arg == "HotStart") { - StartType = HotStart; - } else if (arg == "ColdStart") { - StartType = ColdStart; - } else if (arg == "TepidStart") { - StartType = TepidStart; - } else if (arg == "CheckpointStart") { - StartType = CheckpointStart; - } else { - std::cout << GridLogError << "Unrecognized option in --StartType\n"; - std::cout - << GridLogError - << "Valid [HotStart, ColdStart, TepidStart, CheckpointStart]\n"; - assert(0); - } - } +private: + template + void Runner(IOCheckpointer &Checkpoint, SmearingPolicy &Smearing) { + auto UGrid = Resources.GetCartesian(); + Resources.AddRNGs(); + Field U(UGrid); - int StartTraj = 0; - if (GridCmdOptionExists(argv, argv + argc, "--StartTrajectory")) { - arg = GridCmdOptionPayload(argv, argv + argc, "--StartTrajectory"); - std::vector ivec(0); - GridCmdOptionIntVector(arg, ivec); - StartTraj = ivec[0]; - } + typedef IntegratorType TheIntegrator; + TheIntegrator MDynamics(UGrid, MDparameters, TheAction, Smearing); - int NumTraj = 1; - if (GridCmdOptionExists(argv, argv + argc, "--Trajectories")) { - arg = GridCmdOptionPayload(argv, argv + argc, "--Trajectories"); - std::vector ivec(0); - GridCmdOptionIntVector(arg, ivec); - NumTraj = ivec[0]; - } - - int NumThermalizations = 10; - if (GridCmdOptionExists(argv, argv + argc, "--Thermalizations")) { - arg = GridCmdOptionPayload(argv, argv + argc, "--Thermalizations"); - std::vector ivec(0); - GridCmdOptionIntVector(arg, ivec); - NumThermalizations = ivec[0]; - } - - GridSerialRNG sRNG; - GridParallelRNG pRNG(UGrid); - Field U(UGrid); - - - typedef MinimumNorm2 IntegratorType; // change here to change the algorithm - IntegratorType MDynamics(UGrid, MDparameters, TheAction, Smearing); - - HMCparameters HMCpar; - HMCpar.StartTrajectory = StartTraj; - HMCpar.Trajectories = NumTraj; - HMCpar.NoMetropolisUntil = NumThermalizations; - - if (StartType == HotStart) { + if (Payload.StartType == HotStart) { // Hot start - HMCpar.MetropolisTest = true; - sRNG.SeedFixedIntegers(SerialSeed); - pRNG.SeedFixedIntegers(ParallelSeed); - Implementation::HotConfiguration(pRNG, U); - } else if (StartType == ColdStart) { + Payload.Parameters.MetropolisTest = true; + Resources.SeedFixedIntegers(); + Implementation::HotConfiguration(Resources.GetParallelRNG(), U); + } else if (Payload.StartType == ColdStart) { // Cold start - HMCpar.MetropolisTest = true; - sRNG.SeedFixedIntegers(SerialSeed); - pRNG.SeedFixedIntegers(ParallelSeed); - Implementation::ColdConfiguration(pRNG, U); - } else if (StartType == TepidStart) { + Payload.Parameters.MetropolisTest = true; + Resources.SeedFixedIntegers(); + Implementation::ColdConfiguration(Resources.GetParallelRNG(), U); + } else if (Payload.StartType == TepidStart) { // Tepid start - HMCpar.MetropolisTest = true; - sRNG.SeedFixedIntegers(SerialSeed); - pRNG.SeedFixedIntegers(ParallelSeed); - Implementation::TepidConfiguration(pRNG, U); - } else if (StartType == CheckpointStart) { - HMCpar.MetropolisTest = true; + Payload.Parameters.MetropolisTest = true; + Resources.SeedFixedIntegers(); + Implementation::TepidConfiguration(Resources.GetParallelRNG(), U); + } else if (Payload.StartType == CheckpointStart) { + Payload.Parameters.MetropolisTest = true; // CheckpointRestart - Checkpoint.CheckpointRestore(StartTraj, U, sRNG, pRNG); - } + Checkpoint.CheckpointRestore(Payload.Parameters.StartTrajectory, U, Resources.GetSerialRNG(), Resources.GetParallelRNG()); + } - Smearing.set_Field(U); + Smearing.set_Field(U); - HybridMonteCarlo HMC(HMCpar, MDynamics, sRNG, pRNG, U); + HybridMonteCarlo HMC(Payload.Parameters, MDynamics, Resources.GetSerialRNG(), Resources.GetParallelRNG(), U); - for (int obs = 0; obs < ObservablesList.size(); obs++) - HMC.AddObservable(ObservablesList[obs]); + for (int obs = 0; obs < ObservablesList.size(); obs++) + HMC.AddObservable(ObservablesList[obs]); // Run it - HMC.evolve(); - } + HMC.evolve(); +} }; - // These are for gauge fields - typedef BinaryHmcRunnerTemplate BinaryHmcRunner; - typedef BinaryHmcRunnerTemplate BinaryHmcRunnerF; - typedef BinaryHmcRunnerTemplate BinaryHmcRunnerD; +// These are for gauge fields, default integrator MinimumNorm2 +template