1
0
mirror of https://github.com/paboyle/Grid.git synced 2024-11-09 23:45:36 +00:00

Started a tidy up in the HMC sector. Now comfortable with the two level integrators;

to a little figure out what Guido had done & why -- but there is a neat saving of force
evaluations across the nesting time boundary making use of linearity of the leapP in dt.

I cleaned up the printing, reduced the volume of code, in the process sharing printing
between all integrators. Placed an assert that the total integration time for all integrators
must match at end of trajectory.

Have now verified e-dH = 1 for nested integrators in Wilson/Wilson runs with both
Omelyan and with Leapfrog so substantial confidence gained.
This commit is contained in:
Peter Boyle 2015-08-29 17:18:43 +01:00
parent dc814f30da
commit 76d752585b
12 changed files with 241 additions and 107 deletions

11
TODO
View File

@ -15,18 +15,17 @@ TODO:
=> Lanczos
- Rectangle gauge actions.
- Rectangle gauge actions.
Iwasaki,
Symanzik,
... etc...
- Prepare multigrid for HMC.
Alternate setup schemes.
- Alternate setup schemes.
* Parallel io improvements
- optional parallel MPI2 IO
- move Plaquette and link trace checks into nersc reader from the Grid_nersc_io.cc test.
* Support for ILDG
* Parallel io improvements DONE
- move Plaquette and link trace checks into nersc reader from the Grid_nersc_io.cc test. DONE
* Support for ILDG --- ugly, not done
* Flavour matrices?

2
configure vendored
View File

@ -6533,7 +6533,7 @@ esac
if test "${enable_precision+set}" = set; then :
enableval=$enable_precision; ac_PRECISION=${enable_precision}
else
ac_PRECISION=single
ac_PRECISION=double
fi
case ${ac_PRECISION} in

View File

@ -118,7 +118,7 @@ case ${ac_SIMD} in
;;
esac
AC_ARG_ENABLE([precision],[AC_HELP_STRING([--enable-precision=single|double],[Select default word size of Real])],[ac_PRECISION=${enable_precision}],[ac_PRECISION=single])
AC_ARG_ENABLE([precision],[AC_HELP_STRING([--enable-precision=single|double],[Select default word size of Real])],[ac_PRECISION=${enable_precision}],[ac_PRECISION=double])
case ${ac_PRECISION} in
single)
echo default precision is single

View File

@ -108,11 +108,11 @@ class BinaryIO {
}
}
template<class vobj,class fobj,class munger> static inline void Uint32Checksum(Lattice<vobj> &lat,munger munge,uint32_t &csum)
template<class vobj,class fobj,class munger> static inline void Uint32Checksum(Lattice<vobj> lat,munger munge,uint32_t &csum)
{
typedef typename vobj::scalar_object sobj;
GridBase *grid = lat._grid ;
std::cout <<GridLogMessage<< "Uint32Checksum "<<norm2(lat)<<std::endl;
sobj siteObj;
fobj fileObj;

View File

@ -8,8 +8,8 @@ namespace Grid{
////////////////////////////// Default values
Nsweeps = 200;
TotalSweeps = 220;
ThermalizationSteps = 20;
TotalSweeps = 240;
ThermalizationSteps = 40;
StartingConfig = 0;
SaveInterval = 1;
Filename_prefix = "Conf_";

View File

@ -103,8 +103,7 @@ namespace Grid{
// Actual updates (evolve a copy Ucopy then copy back eventually)
LatticeGaugeField Ucopy(Uin._grid);
for(int iter=Params.StartingConfig;
iter < Params.Nsweeps+Params.StartingConfig; ++iter){
for(int iter=Params.StartingConfig; iter < Params.Nsweeps+Params.StartingConfig; ++iter){
std::cout<<GridLogMessage << "-- # Sweep = "<< iter << "\n";
Ucopy = Uin;

View File

@ -42,7 +42,6 @@ namespace Grid{
Nexp(Nexp_),MDsteps(MDsteps_),trajL(trajL_),stepsize(trajL/MDsteps){};
};
namespace MDutils{
void generate_momenta(LatticeGaugeField&,GridParallelRNG&);
void generate_momenta_su3(LatticeGaugeField&,GridParallelRNG&);
@ -52,23 +51,34 @@ namespace Grid{
template< class IntegratorAlgorithm >
class Integrator{
private:
int levels;
std::vector<double> t_P;
double t_U;
IntegratorParameters Params;
const ActionSet as;
std::unique_ptr<LatticeGaugeField> P;
GridParallelRNG pRNG;
//ObserverList observers; // not yet
IntegratorAlgorithm TheIntegrator;
void register_observers();
void notify_observers();
void update_P(LatticeGaugeField&U, int level,double ep){
t_P[level]+=ep;
for(int a=0; a<as[level].actions.size(); ++a){
LatticeGaugeField force(U._grid);
as[level].actions.at(a)->deriv(U,force);
*P -= force*ep;
}
std::cout<<GridLogMessage;
for(int l=0; l<level;++l) std::cout<<" ";
std::cout<<"["<<level<<"] P " << " dt "<< ep <<" : t_P "<< t_P[level] <<std::endl;
}
void update_U(LatticeGaugeField&U, double ep){
@ -81,18 +91,34 @@ namespace Grid{
Umu = expMat(Pmu, ep, Params.Nexp)*Umu;
PokeIndex<LorentzIndex>(U, Umu, mu);
}
t_U+=ep;
int fl = levels-1;
std::cout<<GridLogMessage<<" ";
for(int l=0; l<fl;++l) std::cout<<" ";
std::cout<<"["<<fl<<"] U " << " dt "<< ep <<" : t_U "<< t_U <<std::endl;
}
friend void IntegratorAlgorithm::step (LatticeGaugeField& U,
int level, std::vector<int>& clock,
Integrator<IntegratorAlgorithm>* Integ);
public:
Integrator(GridBase* grid, IntegratorParameters Par,
Integrator(GridBase* grid,
IntegratorParameters Par,
ActionSet& Aset):
Params(Par),as(Aset),P(new LatticeGaugeField(grid)),pRNG(grid){
pRNG.SeedRandomDevice();
Params(Par),
as(Aset),
P(new LatticeGaugeField(grid)),
pRNG(grid),
levels(Aset.size())
{
std::vector<int> seeds({1,2,3,4,5});
pRNG.SeedFixedIntegers(seeds);
t_P.resize(levels,0.0);
t_U=0.0;
};
~Integrator(){}
@ -120,14 +146,17 @@ namespace Grid{
Complex Hsum = sum(Hloc);
RealD H = Hsum.real();
RealD Hterm;
std::cout<<GridLogMessage << "Momentum action H_p = "<< H << "\n";
// Actions
for(int level=0; level<as.size(); ++level)
for(int actionID=0; actionID<as[level].actions.size(); ++actionID)
H += as[level].actions.at(actionID)->S(U);
for(int level=0; level<as.size(); ++level){
for(int actionID=0; actionID<as[level].actions.size(); ++actionID){
Hterm = as[level].actions.at(actionID)->S(U);
std::cout<<GridLogMessage << "Level "<<level<<" term "<<actionID<<" H = "<<Hterm<<std::endl;
H += Hterm;
}
}
std::cout<<GridLogMessage << "Total action H = "<< H << "\n";
return H;
@ -136,17 +165,16 @@ namespace Grid{
void integrate(LatticeGaugeField& U){
std::vector<int> clock;
clock.resize(as.size(),0);
for(int step=0; step< Params.MDsteps; ++step) // MD step
for(int step=0; step< Params.MDsteps; ++step){ // MD step
TheIntegrator.step(U,0,clock, (this));
}
for(int level=0; level<as.size(); ++level){
assert(fabs(t_U - t_P[level])<1.0e-3);
std::cout<<GridLogMessage<<" times["<<level<<"]= "<<t_P[level]<< " " << t_U <<std::endl;
}
}
};
}
}
#endif//INTEGRATOR_INCLUDED

View File

@ -9,80 +9,158 @@
#ifndef INTEGRATOR_ALG_INCLUDED
#define INTEGRATOR_ALG_INCLUDED
namespace Grid{
namespace QCD{
/*
Chroma: Recursive min norm
00132 Real dtau = traj_length / Real(n_steps);
00133 Real lambda_dt = dtau*lambda;
00134 Real dtauby2 = dtau / Real(2);
00135 Real one_minus_2lambda_dt = (Real(1)-Real(2)*lambda)*dtau;
00136 Real two_lambda_dt = lambda_dt*Real(2);
00137
00138 // Its sts so:
00139 expSdt(s, lambda_dt);
00140 for(int i=0; i < n_steps-1; i++) { // N-1 full steps
00141 // Roll the exp(lambda_dt T) here and start
00142 // Next iter into one
00143 subIntegrator(s, dtauby2); <--- either leapU or next integrator
00144 expSdt(s, one_minus_2lambda_dt);
00145 subIntegrator(s, dtauby2); <--- either leapU or next integrator
00146 expSdt(s, two_lambda_dt);
00147 }
00148 // Last step, can't roll the first and last exp(lambda_dt T)
00149 // together.
00150 subIntegrator(s, dtauby2);
00151 expSdt(s, one_minus_2lambda_dt);
00152 subIntegrator(s, dtauby2);
00153 expSdt(s, lambda_dt);
*
*/
class MinimumNorm2{
const double lambda = 0.1931833275037836;
public:
void step (LatticeLorentzColourMatrix& U,
int level, std::vector<int>& clock,
Integrator<MinimumNorm2>* Integ){
// level : current level
// fl : final level
// eps : current step size
int fl = Integ->as.size() -1;
double eps = Integ->Params.stepsize;
for(int l=0; l<=level; ++l) eps/= 2.0*Integ->as[l].multiplier;
// which is final half step
int fin = Integ->as[0].multiplier;
for(int l=1; l<=level; ++l) fin*= 2.0*Integ->as[l].multiplier;
fin = 3*Integ->Params.MDsteps*fin -1;
for(int e=0; e<Integ->as[level].multiplier; ++e){
int multiplier = Integ->as[level].multiplier;
for(int e=0; e<multiplier; ++e){ // steps per step
if(clock[level] == 0){ // initial half step
Integ->update_P(U,level,lambda*eps);
++clock[level];
for(int l=0; l<level;++l) std::cout<<GridLogMessage<<" ";
std::cout<<GridLogMessage<<"P "<< clock[level] <<std::endl;
Integ->update_P(U,level,lambda*eps); ++clock[level];
}
if(level == fl){ // lowest level
Integ->update_U(U,0.5*eps);
for(int l=0; l<level;++l) std::cout<<GridLogMessage<<" ";
std::cout<<GridLogMessage<<"U "<< (clock[level]+1) <<std::endl;
}else{ // recursive function call
step(U,level+1,clock, Integ);
}
Integ->update_P(U,level,(1.0-2.0*lambda)*eps);
++clock[level];
for(int l=0; l<level;++l) std::cout<<GridLogMessage<<" ";
std::cout<<GridLogMessage<<"P "<< (clock[level]) <<std::endl;
Integ->update_P(U,level,(1.0-2.0*lambda)*eps); ++clock[level];
if(level == fl){ // lowest level
Integ->update_U(U,0.5*eps);
for(int l=0; l<level;++l) std::cout<<GridLogMessage<<" ";
std::cout<<GridLogMessage<<"U "<< (clock[level]+1) <<std::endl;
}else{ // recursive function call
step(U,level+1,clock, Integ);
}
if(clock[level] == fin){ // final half step
Integ->update_P(U,level,lambda*eps);
++clock[level];
for(int l=0; l<level;++l) std::cout<<GridLogMessage<<" ";
std::cout<<GridLogMessage<<"P "<< clock[level] <<std::endl;
}else{ // bulk step
Integ->update_P(U,level,lambda*2.0*eps);
clock[level]+=2;
for(int l=0; l<level;++l) std::cout<<GridLogMessage<<" ";
std::cout<<GridLogMessage<<"P "<< clock[level] <<std::endl;
}
// Handle the final half step
std::cout << GridLogMessage << " P[" <<level<<"] clock = "<<clock[level]<<"/"<<fin<<std::endl;
int mm = (clock[level]==fin) ? 1 : 2;
Integ->update_P(U,level,lambda*eps*mm); clock[level]+=mm;
}
}
};
/*
Chroma: Recursive leapfrog
00124 Real dtau = traj_length / n_steps;
00125 Real dtauby2 = dtau/2;
00126
00127 // Its sts so:
00128 expSdt(s, dtauby2); // First half step
00129 for(int i=0; i < n_steps-1; i++) { // N-1 full steps
00130 subIntegrator(s, dtau); <--- either leapU or next integrator
00131 expSdt(s, dtau);
00132 }
00133 subIntegrator(s, dtau); // Last Full Step
00134 expSdt(s, dtauby2); // Last Half Step
* Nested 1:4; units in dt for top level integrator
* CHROMA GUIDO
* 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
* 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
* Total
*/
class LeapFrog{
public:
void step (LatticeLorentzColourMatrix& U,
@ -94,46 +172,45 @@ namespace Grid{
// eps : current step size
int fl = Integ->as.size() -1;
double eps = Integ->Params.stepsize;
// Get current level step size
int fin = 2*Integ->Params.MDsteps;
for(int l=0; l<=level; ++l) fin*= Integ->as[l].multiplier;
fin = fin-1;
double eps = Integ->Params.stepsize;
for(int l=0; l<=level; ++l) eps/= Integ->as[l].multiplier;
int fin = 1;
for(int l=0; l<=level; ++l) fin*= Integ->as[l].multiplier;
fin = 2*Integ->Params.MDsteps*fin - 1;
for(int e=0; e<Integ->as[level].multiplier; ++e){
if(clock[level] == 0){ // initial half step
Integ->update_P(U, level,eps/2.0);
++clock[level];
for(int l=0; l<level;++l) std::cout<<GridLogMessage<<" ";
std::cout<<GridLogMessage<<"P "<< 0.5*clock[level] <<std::endl;
int multiplier = Integ->as[level].multiplier;
for(int e=0; e<multiplier; ++e){
int first_step,last_step;
if ( level==0 ) {
first_step = (clock[level]==0);
last_step = (clock[level]==fin);
} else {
first_step = (e==0);
last_step = (e==multiplier-1);
}
if(first_step){ // initial half step
Integ->update_P(U, level,eps/2.0); ++clock[level];
}
if(level == fl){ // lowest level
Integ->update_U(U, eps);
for(int l=0; l<level;++l) std::cout<<GridLogMessage<<" ";
std::cout<<GridLogMessage<<"U "<< 0.5*(clock[level]+1) <<std::endl;
}else{ // recursive function call
step(U, level+1,clock, Integ);
}
if(clock[level] == fin){ // final half step
Integ->update_P(U, level,eps/2.0);
++clock[level];
for(int l=0; l<level;++l) std::cout<<GridLogMessage<<" ";
std::cout<<GridLogMessage<<"P "<< 0.5*clock[level] <<std::endl;
}else{ // bulk step
Integ->update_P(U, level,eps);
clock[level]+=2;
for(int l=0; l<level;++l) std::cout<<GridLogMessage<<" ";
std::cout<<GridLogMessage<<"P "<< 0.5*clock[level] <<std::endl;
}
// Handle the final half step
std::cout << GridLogMessage << " P[" <<level<<"] clock = "<<clock[level]<<"/"<<fin<<std::endl;
int mm = last_step ? 1 : 2;
Integ->update_P(U, level,mm*eps/2.0);
clock[level]+=mm;
}
}
};
@ -141,6 +218,4 @@ namespace Grid{
}
}
#endif//INTEGRATOR_INCLUDED

View File

@ -1,6 +1,31 @@
#!/bin/bash
LOG=$1
SWEEPS=$2
grep Plaq $LOG | tail -n $SWEEPS | awk '{ S=S+$10} END { print S/NR} '
grep dH $LOG | tail -n $SWEEPS | awk '{ S=S+exp(-$10)} END { print S/NR} '
SWEEPS=`grep dH $LOG | wc -l`
SWEEPS=`expr $SWEEPS - 80`
echo
echo $SWEEPS thermalised sweeps
echo
plaq=`grep Plaq $LOG | tail -n $SWEEPS | awk '{ S=S+$10} END { print S/NR} ' `
echo Plaquette: $plaq
echo
edH=`grep dH $LOG | tail -n $SWEEPS | awk '{ S=S+exp(-$10)} END { print S/NR} '`
echo "<e-dH>: $edH"
TRAJ=`grep Acc $LOG | wc -l`
ACC=`grep Acc $LOG | grep ACCE | wc -l`
PACC=`expr 100 \* ${ACC} / ${TRAJ} `
echo
echo "Acceptance $PACC % $ACC / $TRAJ "
grep Plaq $LOG | awk '{ print $10 }' | uniq > plaq.dat
grep dH $LOG | awk '{ print $10 }' > dH.dat
echo set yrange [-1:1] > plot.gnu
echo set terminal 'pdf' >> plot.gnu
echo "set output 'plaq.${LOG}.pdf'" >> plot.gnu
echo "plot 'plaq.dat' w l, 'dH.dat' w l " >> plot.gnu
echo
gnuplot plot.gnu >& gnu.errs
open plaq.${LOG}.pdf

View File

@ -16,7 +16,8 @@ int main (int argc, char ** argv)
GridCartesian Fine(latt_size,simd_layout,mpi_layout);
GridRedBlackCartesian RBFine(latt_size,simd_layout,mpi_layout);
GridParallelRNG pRNG(&Fine);
pRNG.SeedRandomDevice();
std::vector<int> seeds({6,7,8,80});
pRNG.SeedFixedIntegers(seeds);
LatticeLorentzColourMatrix U(&Fine);
SU3::HotConfiguration(pRNG, U);
@ -28,22 +29,24 @@ int main (int argc, char ** argv)
WilsonFermionR FermOp(U,Fine,RBFine,mass);
ConjugateGradient<LatticeFermion> CG(1.0e-8,10000);
ConjugateGradient<LatticeFermion> CGmd(1.0e-6,10000);
TwoFlavourEvenOddPseudoFermionAction<WilsonImplR> WilsonNf2(FermOp,CG,CG);
//Collect actions
ActionLevel Level1;
ActionLevel Level1(1);
ActionLevel Level2(4);
Level1.push_back(&WilsonNf2);
Level1.push_back(&Waction);
Level2.push_back(&Waction);
ActionSet FullSet;
FullSet.push_back(Level1);
FullSet.push_back(Level2);
// Create integrator
// typedef MinimumNorm2 IntegratorAlgorithm;// change here to change the algorithm
typedef LeapFrog IntegratorAlgorithm;// change here to change the algorithm
IntegratorParameters MDpar(12,40,1.0);
std::vector<int> rel ={1};
// typedef LeapFrog IntegratorAlgorithm;// change here to change the algorithm
// IntegratorParameters MDpar(12,40,1.0);
typedef MinimumNorm2 IntegratorAlgorithm;// change here to change the algorithm
IntegratorParameters MDpar(12,10,1.0);
Integrator<IntegratorAlgorithm> MDynamics(&Fine,MDpar, FullSet);
// Create HMC

View File

@ -16,7 +16,9 @@ int main (int argc, char ** argv)
GridCartesian Fine(latt_size,simd_layout,mpi_layout);
GridRedBlackCartesian RBFine(latt_size,simd_layout,mpi_layout);
GridParallelRNG pRNG(&Fine);
pRNG.SeedRandomDevice();
std::vector<int> seeds({5,6,7,8});
pRNG.SeedFixedIntegers(seeds);
LatticeLorentzColourMatrix U(&Fine);
SU3::HotConfiguration(pRNG, U);
@ -28,14 +30,16 @@ int main (int argc, char ** argv)
WilsonFermionR FermOp(U,Fine,RBFine,mass);
ConjugateGradient<LatticeFermion> CG(1.0e-8,10000);
ConjugateGradient<LatticeFermion> CGmd(1.0e-6,10000);
TwoFlavourPseudoFermionAction<WilsonImplR> WilsonNf2(FermOp,CG,CG);
//Collect actions
ActionLevel Level1;
ActionLevel Level1(1);
ActionLevel Level2(4);
Level1.push_back(&WilsonNf2);
Level1.push_back(&Waction);
// Level1.push_back(&Waction);
ActionSet FullSet;
FullSet.push_back(Level1);
// FullSet.push_back(Level2);

View File

@ -23,7 +23,8 @@ int main (int argc, char ** argv)
GridCartesian Fine(latt_size,simd_layout,mpi_layout);
GridParallelRNG pRNG(&Fine);
pRNG.SeedRandomDevice();
std::vector<int> seeds({1,2,3,4,5,6,7,8});
pRNG.SeedFixedIntegers(seeds);
LatticeGaugeField U(&Fine);
SU3::HotConfiguration(pRNG, U);
@ -40,7 +41,7 @@ int main (int argc, char ** argv)
// Create integrator
typedef MinimumNorm2 IntegratorAlgorithm;// change here to modify the algorithm
IntegratorParameters MDpar(12,5,1.0);
IntegratorParameters MDpar(12,20,1.0);
Integrator<IntegratorAlgorithm> MDynamics(&Fine,MDpar, FullSet);
// Create HMC