Grid 0.7.0
HMC.h
Go to the documentation of this file.
1/*************************************************************************************
2
3Grid physics library, www.github.com/paboyle/Grid
4
5Source file: ./lib/qcd/hmc/HMC.h
6
7Copyright (C) 2015
8
9Author: Azusa Yamaguchi <ayamaguc@staffmail.ed.ac.uk>
10Author: Peter Boyle <paboyle@ph.ed.ac.uk>
11Author: neo <cossu@post.kek.jp>
12Author: paboyle <paboyle@ph.ed.ac.uk>
13
14This program is free software; you can redistribute it and/or modify
15it under the terms of the GNU General Public License as published by
16the Free Software Foundation; either version 2 of the License, or
17(at your option) any later version.
18
19This program is distributed in the hope that it will be useful,
20but WITHOUT ANY WARRANTY; without even the implied warranty of
21MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22GNU General Public License for more details.
23
24You should have received a copy of the GNU General Public License along
25with this program; if not, write to the Free Software Foundation, Inc.,
2651 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
27
28See the full license in the file "LICENSE" in the top level distribution
29directory
30*************************************************************************************/
31 /* END LEGAL */
32 //--------------------------------------------------------------------
39 //--------------------------------------------------------------------
40#pragma once
41
42#include <string>
43#include <list>
44
47
49
50struct HMCparameters: Serializable {
52 Integer, StartTrajectory,
53 Integer, Trajectories, /* @brief Number of sweeps in this run */
54 bool, MetropolisTest,
55 Integer, NoMetropolisUntil,
56 bool, PerformRandomShift, /* @brief Randomly shift the gauge configuration at the start of a trajectory */
57 std::string, StartingType,
59
62 MetropolisTest = true;
63 NoMetropolisUntil = 10;
64 StartTrajectory = 0;
65 Trajectories = 10;
66 StartingType = "HotStart";
67 PerformRandomShift = true;
69 }
70
71 template <class ReaderClass >
72 HMCparameters(Reader<ReaderClass> & TheReader){
73 initialize(TheReader);
74 }
75
76 template < class ReaderClass >
77 void initialize(Reader<ReaderClass> &TheReader){
78 std::cout << GridLogMessage << "Reading HMC\n";
79 read(TheReader, "HMC", *this);
80 }
81
82
83 void print_parameters() const {
84 std::cout << GridLogMessage << "[HMC parameters] Trajectories : " << Trajectories << "\n";
85 std::cout << GridLogMessage << "[HMC parameters] Start trajectory : " << StartTrajectory << "\n";
86 std::cout << GridLogMessage << "[HMC parameters] Metropolis test (on/off): " << std::boolalpha << MetropolisTest << "\n";
87 std::cout << GridLogMessage << "[HMC parameters] Thermalization trajs : " << NoMetropolisUntil << "\n";
88 std::cout << GridLogMessage << "[HMC parameters] Doing random shift : " << std::boolalpha << PerformRandomShift << "\n";
89 std::cout << GridLogMessage << "[HMC parameters] Starting type : " << StartingType << "\n";
90 MD.print_parameters();
91 }
92
93};
94
95template <class IntegratorType>
97private:
99
100 typedef typename IntegratorType::Field Field;
101 typedef typename IntegratorType::FieldImplementation FieldImplementation;
102 typedef std::vector< HmcObservable<Field> * > ObsListType;
103
104 //pass these from the resource manager
107
109
110 IntegratorType &TheIntegrator;
112
114 // Metropolis step
116 bool metropolis_test(const RealD DeltaH) {
117 RealD rn_test;
118
119 RealD prob = std::exp(-DeltaH);
120
121 random(sRNG, rn_test);
122
123 std::cout << GridLogHMC << "--------------------------------------------------\n";
124 std::cout << GridLogHMC << "exp(-dH) = " << prob << " Random = " << rn_test << "\n";
125 std::cout << GridLogHMC << "Acc. Probability = " << ((prob < 1.0) ? prob : 1.0) << "\n";
126
127 if ((prob > 1.0) || (rn_test <= prob)) { // accepted
128 std::cout << GridLogHMC << "Metropolis_test -- ACCEPTED\n";
129 std::cout << GridLogHMC << "--------------------------------------------------\n";
130 return true;
131 } else { // rejected
132 std::cout << GridLogHMC << "Metropolis_test -- REJECTED\n";
133 std::cout << GridLogHMC << "--------------------------------------------------\n";
134 return false;
135 }
136 }
137
139 // Evolution
142
143 GridBase *Grid = U.Grid();
144
145 if(Params.PerformRandomShift){
146#if 0
148 // Mainly for DDHMC perform a random translation of U modulo volume
150 std::cout << GridLogMessage << "--------------------------------------------------\n";
151 std::cout << GridLogMessage << "Random shifting gauge field by [";
152
153 std::vector<typename FieldImplementation::GaugeLinkField> Umu(Grid->Nd(), U.Grid());
154 for(int mu=0;mu<Grid->Nd();mu++) Umu[mu] = PeekIndex<LorentzIndex>(U, mu);
155
156 for(int d=0;d<Grid->Nd();d++) {
157
158 int L = Grid->GlobalDimensions()[d];
159
160 RealD rn_uniform; random(sRNG, rn_uniform);
161
162 int shift = (int) (rn_uniform*L);
163
164 std::cout << shift;
165 if(d<Grid->Nd()-1) std::cout <<",";
166 else std::cout <<"]\n";
167
168 //shift all fields together in a way that respects the gauge BCs
169 for(int mu=0; mu < Grid->Nd(); mu++)
170 Umu[mu] = FieldImplementation::CshiftLink(Umu[mu],d,shift);
171
172 for(int mu=0;mu<Grid->Nd();mu++) PokeIndex<LorentzIndex>(U,Umu[mu],mu);
173 }
174 std::cout << GridLogMessage << "--------------------------------------------------\n";
175#endif
176 }
177
178 TheIntegrator.reset_timer();
179
181 // set U and initialize P and phi's
183 std::cout << GridLogMessage << "--------------------------------------------------\n";
184 std::cout << GridLogMessage << "Refresh momenta and pseudofermions";
185 TheIntegrator.refresh(U, sRNG, pRNG);
186 std::cout << GridLogMessage << "--------------------------------------------------\n";
187
189 // initial state action
191 std::cout << GridLogMessage << "--------------------------------------------------\n";
192 std::cout << GridLogMessage << "Compute initial action";
193 RealD H0 = TheIntegrator.Sinitial(U);
194 std::cout << GridLogMessage << "--------------------------------------------------\n";
195
196 std::streamsize current_precision = std::cout.precision();
197 std::cout.precision(15);
198 std::cout << GridLogHMC << "Total H before trajectory = " << H0 << "\n";
199 std::cout.precision(current_precision);
200
201 std::cout << GridLogMessage << "--------------------------------------------------\n";
202 std::cout << GridLogMessage << " Molecular Dynamics evolution ";
203 TheIntegrator.integrate(U);
204 std::cout << GridLogMessage << "--------------------------------------------------\n";
205
207 // updated state action
209 std::cout << GridLogMessage << "--------------------------------------------------\n";
210 std::cout << GridLogMessage << "Compute final action";
211 RealD H1 = TheIntegrator.S(U);
212 std::cout << GridLogMessage << "--------------------------------------------------\n";
213
214
215
217 if(0){
218 std::cout << "------------------------- Reversibility test" << std::endl;
219 TheIntegrator.reverse_momenta();
220 TheIntegrator.integrate(U);
221
222 H1 = TheIntegrator.S(U); // updated state action
223 std::cout << "--------------------------------------------" << std::endl;
224 }
226
227 std::cout.precision(15);
228
229 std::cout << GridLogHMC << "--------------------------------------------------\n";
230 std::cout << GridLogHMC << "Total H after trajectory = " << H1 << " dH = " << H1 - H0 << "\n";
231 std::cout << GridLogHMC << "--------------------------------------------------\n";
232
233 std::cout.precision(current_precision);
234
235 return (H1 - H0);
236 }
237
238public:
240 // Constructor
242 HybridMonteCarlo(HMCparameters _Pams, IntegratorType &_Int,
243 GridSerialRNG &_sRNG, GridParallelRNG &_pRNG,
244 ObsListType _Obs, Field &_U)
245 : Params(_Pams), TheIntegrator(_Int), sRNG(_sRNG), pRNG(_pRNG), Observables(_Obs), Ucur(_U) {}
247
248 void evolve(void) {
249 Real DeltaH;
250
251 Field Ucopy(Ucur.Grid());
252
253 Params.print_parameters();
254 TheIntegrator.print_actions();
255
256 // Actual updates (evolve a copy Ucopy then copy back eventually)
257 unsigned int FinalTrajectory = Params.Trajectories + Params.NoMetropolisUntil + Params.StartTrajectory;
258
259 for (int traj = Params.StartTrajectory; traj < FinalTrajectory; ++traj) {
260
261 std::cout << GridLogHMC << "-- # Trajectory = " << traj << "\n";
262
263 if (traj < Params.StartTrajectory + Params.NoMetropolisUntil) {
264 std::cout << GridLogHMC << "-- Thermalization" << std::endl;
265 }
266
267 double t0=usecond();
268 Ucopy = Ucur;
269
270 DeltaH = evolve_hmc_step(Ucopy);
271 // Metropolis-Hastings test
272 bool accept = true;
273 if (Params.MetropolisTest && traj >= Params.StartTrajectory + Params.NoMetropolisUntil) {
274 accept = metropolis_test(DeltaH);
275 } else {
276 std::cout << GridLogHMC << "Skipping Metropolis test" << std::endl;
277 }
278
279 if (accept)
280 Ucur = Ucopy;
281
282 double t1=usecond();
283 std::cout << GridLogHMC << "Total time for trajectory (s): " << (t1-t0)/1e6 << std::endl;
284
285 TheIntegrator.print_timer();
286
287 TheIntegrator.Smearer.set_Field(Ucur);
288 for (int obs = 0; obs < Observables.size(); obs++) {
289 std::cout << GridLogDebug << "Observables # " << obs << std::endl;
290 std::cout << GridLogDebug << "Observables total " << Observables.size() << std::endl;
291 std::cout << GridLogDebug << "Observables pointer " << Observables[obs] << std::endl;
292 Observables[obs]->TrajectoryComplete(traj + 1, TheIntegrator.Smearer, sRNG, pRNG);
293 }
294 std::cout << GridLogHMC << ":::::::::::::::::::::::::::::::::::::::::::" << std::endl;
295 }
296 }
297
298};
299
301// april 11 2017 merge, Guido, commenting out
302//#include <Grid/parallelIO/NerscIO.h>
303//#include <Grid/qcd/hmc/NerscCheckpointer.h>
304//#include <Grid/qcd/hmc/HmcRunner.h>
305
Declaration of classes for the Molecular Dynamics algorithms.
void PokeIndex(Lattice< vobj > &lhs, const Lattice< decltype(peekIndex< Index >(vobj(), 0))> &rhs, int i)
auto PeekIndex(const Lattice< vobj > &lhs, int i) -> Lattice< decltype(peekIndex< Index >(vobj(), i))>
void random(GridParallelRNG &rng, Lattice< vobj > &l)
GridLogger GridLogDebug(1, "Debug", GridLogColours, "PURPLE")
GridLogger GridLogHMC(1, "HMC", GridLogColours, "BLUE")
GridLogger GridLogMessage(1, "Message", GridLogColours, "NORMAL")
#define NAMESPACE_BEGIN(A)
Definition Namespace.h:35
#define NAMESPACE_END(A)
Definition Namespace.h:36
static constexpr int Nd
Definition QCD.h:52
uint32_t Integer
Definition Simd.h:58
RealF Real
Definition Simd.h:65
double RealD
Definition Simd.h:61
double usecond(void)
Definition Timer.h:50
static INTERNAL_PRECISION U
Definition Zolotarev.cc:230
IntegratorType::Field Field
Definition HMC.h:100
IntegratorType::FieldImplementation FieldImplementation
Definition HMC.h:101
IntegratorType & TheIntegrator
Definition HMC.h:110
RealD evolve_hmc_step(Field &U)
Definition HMC.h:141
const HMCparameters Params
Definition HMC.h:98
std::vector< HmcObservable< Field > * > ObsListType
Definition HMC.h:102
HybridMonteCarlo(HMCparameters _Pams, IntegratorType &_Int, GridSerialRNG &_sRNG, GridParallelRNG &_pRNG, ObsListType _Obs, Field &_U)
Definition HMC.h:242
ObsListType Observables
Definition HMC.h:111
void evolve(void)
Definition HMC.h:248
~HybridMonteCarlo()
Definition HMC.h:246
bool metropolis_test(const RealD DeltaH)
Definition HMC.h:116
Field & Ucur
Definition HMC.h:108
GridParallelRNG & pRNG
Definition HMC.h:106
GridSerialRNG & sRNG
Definition HMC.h:105
HMCparameters(Reader< ReaderClass > &TheReader)
Definition HMC.h:72
GRID_SERIALIZABLE_CLASS_MEMBERS(HMCparameters, Integer, StartTrajectory, Integer, Trajectories, bool, MetropolisTest, Integer, NoMetropolisUntil, bool, PerformRandomShift, std::string, StartingType, IntegratorParameters, MD) HMCparameters()
Definition HMC.h:51
void initialize(Reader< ReaderClass > &TheReader)
Definition HMC.h:77
void print_parameters() const
Definition HMC.h:83