CHROMA
hmc.cc
Go to the documentation of this file.
1 /*! \file
2  * \brief Main code for HMC with dynamical fermion generation
3  */
4 
5 #include "chroma.h"
6 #include <string>
7 
8 using namespace Chroma;
9 
10 namespace Chroma
11 {
12 
13  struct MCControl
14  {
16  QDP::Seed rng_seed;
17  unsigned long start_update_num;
18  unsigned long n_warm_up_updates;
19  unsigned long n_production_updates;
20  unsigned int n_updates_this_run;
21  unsigned int save_interval;
23  QDP_volfmt_t save_volfmt;
24  QDP_serialparallel_t save_pario;
26  bool repro_checkP;
28  bool rev_checkP;
30  bool monitorForcesP;
31 
32  };
33 
34  void read(XMLReader& xml, const std::string& path, MCControl& p)
35  {
36  START_CODE();
37 
38  try {
39  XMLReader paramtop(xml, path);
40  p.cfg = readXMLGroup(paramtop, "Cfg", "cfg_type");
41  read(paramtop, "./RNG", p.rng_seed);
42  read(paramtop, "./StartUpdateNum", p.start_update_num);
43  read(paramtop, "./NWarmUpUpdates", p.n_warm_up_updates);
44  read(paramtop, "./NProductionUpdates", p.n_production_updates);
45  read(paramtop, "./NUpdatesThisRun", p.n_updates_this_run);
46  read(paramtop, "./SaveInterval", p.save_interval);
47  read(paramtop, "./SavePrefix", p.save_prefix);
48  read(paramtop, "./SaveVolfmt", p.save_volfmt);
49 
50 
51 
52  bool parioP = Layout::isIOGridDefined() && ( Layout::numIONodeGrid() > 1); // Default
53 
54  if ( paramtop.count("./parallel_io") > 0 ) {
55  read(paramtop, "./parallel_io", parioP);
56  }
57  else {
58  // If there is a ParalelIO tag
59  if ( paramtop.count("./ParallelIO") > 0 ) {
60  read(paramtop, "./ParallelIO", parioP);
61  }
62  }
63 
64  if ( parioP ) {
65  QDPIO::cout << "Setting parallel write mode for saving configurations" << std::endl;
66  p.save_pario = QDPIO_PARALLEL;
67  }
68  else {
69  QDPIO::cout << "Setting serial write mode for saving configurations" << std::endl;
70  p.save_pario = QDPIO_SERIAL;
71 
72  }
73  // Default values: repro check is on, frequency is 10%
74  p.repro_checkP = true;
75  p.repro_check_frequency = 10;
76 
77 
78  // Now overwrite with user values
79  if( paramtop.count("./ReproCheckP") == 1 ) {
80  // Read user value if given
81  read(paramtop, "./ReproCheckP", p.repro_checkP);
82  }
83 
84  // If we do repro checking, read the frequency
85  if( p.repro_checkP ) {
86  if( paramtop.count("./ReproCheckFrequency") == 1 ) {
87  // Read user value if given
88  read(paramtop, "./ReproCheckFrequency", p.repro_check_frequency);
89  }
90  }
91 
92  // Reversibility checking enabled by default.
93  p.rev_checkP = true;
94  p.rev_check_frequency = 10;
95 
96  // Now overwrite with user values
97  if( paramtop.count("./ReverseCheckP") == 1 ) {
98  // Read user value if given
99  read(paramtop, "./ReverseCheckP", p.rev_checkP);
100  }
101 
102  // If we do repro checking, read the frequency
103  if( p.rev_checkP ) {
104  if( paramtop.count("./ReverseCheckFrequency") == 1 ) {
105  // Read user value if given
106  read(paramtop, "./ReverseCheckFrequency", p.rev_check_frequency);
107  }
108  }
109 
110  if( paramtop.count("./MonitorForces") == 1 ) {
111  read(paramtop, "./MonitorForces", p.monitorForcesP);
112  }
113  else {
114  p.monitorForcesP = true;
115  }
116 
117  if( paramtop.count("./InlineMeasurements") == 0 ) {
118  XMLBufferWriter dummy;
119  push(dummy, "InlineMeasurements");
120  pop(dummy); // InlineMeasurements
121  p.inline_measurement_xml = dummy.printCurrentContext();
122 
123  }
124  else {
125  XMLReader measurements_xml(paramtop, "./InlineMeasurements");
126  std::ostringstream inline_os;
127  measurements_xml.print(inline_os);
128  p.inline_measurement_xml = inline_os.str();
129  QDPIO::cout << "InlineMeasurements are: " << std::endl;
130  QDPIO::cout << p.inline_measurement_xml << std::endl;
131  }
132 
133 
134  }
135  catch(const std::string& e ) {
136  QDPIO::cerr << "Caught Exception: " << e << std::endl;
137  QDP_abort(1);
138  }
139 
140  END_CODE();
141  }
142 
143  void write(XMLWriter& xml, const std::string& path, const MCControl& p)
144  {
145  START_CODE();
146 
147  try {
148  push(xml, path);
149  xml << p.cfg.xml;
150  write(xml, "RNG", p.rng_seed);
151  write(xml, "StartUpdateNum", p.start_update_num);
152  write(xml, "NWarmUpUpdates", p.n_warm_up_updates);
153  write(xml, "NProductionUpdates", p.n_production_updates);
154  write(xml, "NUpdatesThisRun", p.n_updates_this_run);
155  write(xml, "SaveInterval", p.save_interval);
156  write(xml, "SavePrefix", p.save_prefix);
157  write(xml, "SaveVolfmt", p.save_volfmt);
158  {
159  bool pario = ( p.save_pario == QDPIO_PARALLEL );
160  write(xml, "ParallelIO", pario);
161  }
162  write(xml, "ReproCheckP", p.repro_checkP);
163  if( p.repro_checkP ) {
164  write(xml, "ReproCheckFrequency", p.repro_check_frequency);
165  }
166  write(xml, "ReverseCheckP", p.rev_checkP);
167  if( p.rev_checkP ) {
168  write(xml, "ReverseCheckFrequency", p.rev_check_frequency);
169  }
170  write(xml, "MonitorForces", p.monitorForcesP);
171 
172  xml << p.inline_measurement_xml;
173 
174  pop(xml);
175 
176  }
177  catch(const std::string& e ) {
178  QDPIO::cerr << "Caught Exception: " << e << std::endl;
179  QDP_abort(1);
180  }
181 
182  END_CODE();
183  }
184 
185 
186  struct HMCTrjParams
187  {
188  multi1d<int> nrow;
189 
190  // Polymorphic
191  std::string Monomials_xml; // XML for the monomials
192  std::string H_MC_xml; // XML for the Hamiltonian
193  std::string Integrator_xml; // XML for the Integrator
194  };
195 
196  void write(XMLWriter& xml, const std::string& path, const HMCTrjParams& p)
197  {
198  START_CODE();
199 
200  try {
201  push(xml, path);
202  write(xml, "nrow", p.nrow);
203  xml << p.Monomials_xml; // XML For the mon
204  xml << p.H_MC_xml;
205  xml << p.Integrator_xml;
206  pop(xml);
207  }
208  catch(const std::string& e ) {
209  QDPIO::cerr << "Caught Exception: " << e << std::endl;
210  QDP_abort(1);
211  }
212 
213  END_CODE();
214  }
215 
216 
217  void read(XMLReader& xml, const std::string& path, HMCTrjParams& p)
218  {
219  START_CODE();
220 
221  try {
222  XMLReader paramtop(xml, path);
223 
224  read(paramtop, "./nrow", p.nrow);
225  XMLReader Monomials_xml_reader(paramtop, "./Monomials");
226  std::ostringstream os_Monomials;
227  Monomials_xml_reader.print(os_Monomials);
228  p.Monomials_xml = os_Monomials.str();
229  QDPIO::cout << "Monomials xml is:" << std::endl;
230  QDPIO::cout << p.Monomials_xml << std::endl;
231 
232  // Now the XML for the Hamiltonians
233  XMLReader H_MC_xml(paramtop, "./Hamiltonian");
234  std::ostringstream os_H_MC;
235  H_MC_xml.print(os_H_MC);
236  p.H_MC_xml = os_H_MC.str();
237 
238  QDPIO::cout << "HMC_xml is: " << std::endl;
239  QDPIO::cout << p.H_MC_xml;
240 
241 
242  // Read the Integrator parameters
243  XMLReader MD_integrator_xml(paramtop, "./MDIntegrator");
244  std::ostringstream os_integrator;
245  MD_integrator_xml.print(os_integrator);
246  p.Integrator_xml = os_integrator.str();
247 
248  QDPIO::cout << "Integrator XML is: " << std::endl;
249  QDPIO::cout << p.Integrator_xml << std::endl;
250  }
251  catch( const std::string& e ) {
252  QDPIO::cerr << "Error reading XML : " << e << std::endl;
253  QDP_abort(1);
254  }
255 
256  END_CODE();
257  }
258 
259  template<typename UpdateParams>
260  void saveState(const UpdateParams& update_params,
261  MCControl& mc_control,
262  unsigned long update_no,
263  const multi1d<LatticeColorMatrix>& u) {
264  // Do nothing
265  }
266 
267  // Specialise
268  template<>
269  void saveState(const HMCTrjParams& update_params,
270  MCControl& mc_control,
271  unsigned long update_no,
272  const multi1d<LatticeColorMatrix>& u)
273  {
274  START_CODE();
275 
276  // File names
277  std::ostringstream restart_data_filename;
278  restart_data_filename << mc_control.save_prefix << "_restart_" << update_no << ".xml" ;
279 
280  std::ostringstream restart_config_filename;
281  restart_config_filename << mc_control.save_prefix << "_cfg_" << update_no << ".lime";
282 
283  XMLBufferWriter restart_data_buffer;
284 
285 
286  // Copy old params
287  MCControl p_new = mc_control;
288 
289  // Get Current RNG Seed
290  QDP::RNG::savern(p_new.rng_seed);
291 
292  // Set the current traj number
293  p_new.start_update_num = update_no;
294 
295  // Set the num_updates_this_run
296  unsigned long total = mc_control.n_warm_up_updates
297  + mc_control.n_production_updates ;
298 
299  if ( total < mc_control.n_updates_this_run + update_no ) {
300  p_new.n_updates_this_run = total - update_no;
301  }
302 
303  // Set the name and type of the config
304  {
305  // Parse the cfg XML including the parallel IO part
307 
308  // Reset the filename in it
309  cfg.cfg_file = restart_config_filename.str();
310  cfg.cfg_pario = mc_control.save_pario;
311 
312  // Prepare to write out
314  }
315 
316 
317  push(restart_data_buffer, "Params");
318  write(restart_data_buffer, "MCControl", p_new);
319  write(restart_data_buffer, "HMCTrj", update_params);
320  pop(restart_data_buffer);
321 
322 
323  // Save the config
324 
325  // some dummy header for the file
326  XMLBufferWriter file_xml;
327  push(file_xml, "HMC");
328  proginfo(file_xml);
329  pop(file_xml);
330 
331 
332  // Save the config
333  writeGauge(file_xml,
334  restart_data_buffer,
335  u,
336  restart_config_filename.str(),
337  p_new.save_volfmt,
338  p_new.save_pario);
339 
340 
341  // Write a restart DATA file from the buffer XML
342  // Do this after the config is written, so that if the cfg
343  // write fails, there is no restart file...
344  //
345  // production will then likely fall back to last good pair.
346 
347  XMLFileWriter restart_xml(restart_data_filename.str().c_str());
348  restart_xml << restart_data_buffer;
349  restart_xml.close();
350 
351  END_CODE();
352  }
353 
354 
355 
356  // Predeclare this
357  bool checkReproducability( const multi1d<LatticeColorMatrix>& P_new,
358  const multi1d<LatticeColorMatrix>& Q_new,
359  const QDP::Seed& seed_new,
360  const multi1d<LatticeColorMatrix>& P_old,
361  const multi1d<LatticeColorMatrix>& Q_old,
362  const QDP::Seed& seed_old );
363 
364  template<typename UpdateParams>
365  void doHMC(multi1d<LatticeColorMatrix>& u,
366  AbsHMCTrj<multi1d<LatticeColorMatrix>,
367  multi1d<LatticeColorMatrix> >& theHMCTrj,
368  MCControl& mc_control,
369  const UpdateParams& update_params,
370  multi1d< Handle<AbsInlineMeasurement> >& user_measurements)
371  {
372  START_CODE();
373 
374 
375  // Turn monitoring off/on
376  QDPIO::cout << "Setting Force monitoring to " << mc_control.monitorForcesP << std::endl;
377  setForceMonitoring(mc_control.monitorForcesP) ;
378  QDP::StopWatch swatch;
379 
380  XMLWriter& xml_out = TheXMLOutputWriter::Instance();
381  XMLWriter& xml_log = TheXMLLogWriter::Instance();
382 
383  push(xml_out, "doHMC");
384  push(xml_log, "doHMC");
385 
386  multi1d< Handle< AbsInlineMeasurement > > default_measurements(1);
387  InlinePlaquetteEnv::Params plaq_params;
388  plaq_params.frequency = 1;
389  // It is a handle
390  default_measurements[0] = new InlinePlaquetteEnv::InlineMeas(plaq_params);
391 
392  {
393  // Initialise the RNG
394  QDP::RNG::setrn(mc_control.rng_seed);
395 
396  // Fictitious momenta for now
397  multi1d<LatticeColorMatrix> p(Nd);
398 
399  // Create a field state
400  GaugeFieldState gauge_state(p,u);
401 
402  // Set the update number
403  unsigned long cur_update=mc_control.start_update_num;
404 
405  // Compute how many updates to do
406  unsigned long total_updates = mc_control.n_warm_up_updates
407  + mc_control.n_production_updates;
408 
409  unsigned long to_do = 0;
410  if ( total_updates >= mc_control.n_updates_this_run + cur_update +1 ) {
411  to_do = mc_control.n_updates_this_run;
412  }
413  else {
414  to_do = total_updates - cur_update ;
415  }
416 
417  QDPIO::cout << "MC Control: About to do " << to_do << " updates" << std::endl;
418 
419  // XML Output
420  push(xml_out, "MCUpdates");
421  push(xml_log, "MCUpdates");
422 
423  for(int i=0; i < to_do; i++)
424  {
425  push(xml_out, "elem"); // Caller writes elem rule
426  push(xml_log, "elem"); // Caller writes elem rule
427 
428  push(xml_out, "Update");
429  push(xml_log, "Update");
430  // Increase current update counter
431  cur_update++;
432 
433  // Decide if the next update is a warm up or not
434  bool warm_up_p = cur_update <= mc_control.n_warm_up_updates;
435  QDPIO::cout << "Doing Update: " << cur_update << " warm_up_p = " << warm_up_p << std::endl;
436 
437  // Log
438  write(xml_out, "update_no", cur_update);
439  write(xml_log, "update_no", cur_update);
440 
441  write(xml_out, "WarmUpP", warm_up_p);
442  write(xml_log, "WarmUpP", warm_up_p);
443 
444  bool do_reverse = false;
445  if( mc_control.rev_checkP
446  && ( cur_update % mc_control.rev_check_frequency == 0 )) {
447  do_reverse = true;
448  QDPIO::cout << "Doing Reversibility Test this traj" << std::endl;
449  }
450 
451 
452  // Check if I need to do any reproducibility testing
453  if( mc_control.repro_checkP
454  && (cur_update % mc_control.repro_check_frequency == 0 )
455  ) {
456 
457  // Yes - reproducibility trajectory
458  // Save fields and RNG at start of trajectory
459  QDPIO::cout << "Saving start config and RNG seed for reproducability test" << std::endl;
460 
461  GaugeFieldState repro_bkup_start( gauge_state.getP(), gauge_state.getQ());
462  QDP::Seed rng_seed_bkup_start;
463  QDP::RNG::savern(rng_seed_bkup_start);
464 
465  // DO the trajectory
466  QDPIO::cout << "Before HMC trajectory call" << std::endl;
467  swatch.reset();
468  swatch.start();
469 
470  // This may do a reversibility check
471  theHMCTrj( gauge_state, warm_up_p, do_reverse );
472  swatch.stop();
473 
474  QDPIO::cout << "After HMC trajectory call: time= "
475  << swatch.getTimeInSeconds()
476  << " secs" << std::endl;
477 
478  write(xml_out, "seconds_for_trajectory", swatch.getTimeInSeconds());
479  write(xml_log, "seconds_for_trajectory", swatch.getTimeInSeconds());
480 
481  // Save the fields and RNG at the end
482  QDPIO::cout << "Saving end config and RNG seed for reproducability test" << std::endl;
483  GaugeFieldState repro_bkup_end( gauge_state.getP(), gauge_state.getQ());
484  QDP::Seed rng_seed_bkup_end;
485  QDP::RNG::savern(rng_seed_bkup_end);
486 
487  // Restore the starting field and the starting RNG
488  QDPIO::cout << "Restoring start config and RNG for reproducability test" << std::endl;
489 
490  gauge_state.getP() = repro_bkup_start.getP();
491  gauge_state.getQ() = repro_bkup_start.getQ();
492  QDP::RNG::setrn(rng_seed_bkup_start);
493 
494  // Do the repro trajectory
495  QDPIO::cout << "Before HMC repro trajectory call" << std::endl;
496  swatch.reset();
497  swatch.start();
498  // Dont repeat the reversibility check in the repro test
499  theHMCTrj( gauge_state, warm_up_p, false );
500  swatch.stop();
501 
502  QDPIO::cout << "After HMC repro trajectory call: time= "
503  << swatch.getTimeInSeconds()
504  << " secs" << std::endl;
505 
506  write(xml_out, "seconds_for_repro_trajectory", swatch.getTimeInSeconds());
507  write(xml_log, "seconds_for_repro_trajectory", swatch.getTimeInSeconds());
508 
509  // Save seed at end of traj for comparison
510  QDP::Seed rng_seed_end2;
511  QDP::RNG::savern(rng_seed_end2);
512 
513 
514  // Check the reproducibility
515  bool pass = checkReproducability( gauge_state.getP(),
516  gauge_state.getQ(),
517  rng_seed_end2,
518  repro_bkup_end.getP(),
519  repro_bkup_end.getQ(),
520  rng_seed_bkup_end);
521 
522 
523  if( !pass ) {
524  QDPIO::cout << "Reproducability check failed on update " << cur_update << std::endl;
525  QDPIO::cout << "Aborting" << std::endl;
526  write(xml_out, "ReproCheck", pass);
527  write(xml_log, "ReproCheck", pass);
528  QDP_abort(1);
529  }
530  else {
531  QDPIO::cout << "Reproducability check passed on update " << cur_update << std::endl;
532  write(xml_out, "ReproCheck", pass);
533  write(xml_log, "ReproCheck", pass);
534  }
535 
536 
537  }
538  else {
539 
540  // Do the trajectory without accepting
541  QDPIO::cout << "Before HMC trajectory call" << std::endl;
542  swatch.reset();
543  swatch.start();
544  theHMCTrj( gauge_state, warm_up_p, do_reverse );
545  swatch.stop();
546 
547  QDPIO::cout << "After HMC trajectory call: time= "
548  << swatch.getTimeInSeconds()
549  << " secs" << std::endl;
550 
551  write(xml_out, "seconds_for_trajectory", swatch.getTimeInSeconds());
552  write(xml_log, "seconds_for_trajectory", swatch.getTimeInSeconds());
553 
554  }
555  swatch.reset();
556  swatch.start();
557 
558  // Create a gauge header for inline measurements.
559  // Since there are defaults always measured, we must always
560  // create a header.
561  //
562  // NOTE: THIS HEADER STUFF NEEDS A LOT MORE THOUGHT
563  //
564  QDPIO::cout << "HMC: start inline measurements" << std::endl;
565  {
566  XMLBufferWriter gauge_xml;
567  push(gauge_xml, "ChromaHMC");
568  write(gauge_xml, "update_no", cur_update);
569  write(gauge_xml, "HMCTrj", update_params);
570  pop(gauge_xml);
571 
572  // Reset and set the default gauge field
573  QDPIO::cout << "HMC: initial resetting default gauge field" << std::endl;
575  QDPIO::cout << "HMC: set default gauge field" << std::endl;
576  InlineDefaultGaugeField::set(gauge_state.getQ(), gauge_xml);
577  QDPIO::cout << "HMC: finished setting default gauge field" << std::endl;
578 
579  // Measure inline observables
580  push(xml_out, "InlineObservables");
581 
582  // Always measure defaults
583  for(int m=0; m < default_measurements.size(); m++)
584  {
585  QDPIO::cout << "HMC: do default measurement = " << m << std::endl;
586  QDPIO::cout << "HMC: dump named objects" << std::endl;
587  TheNamedObjMap::Instance().dump();
588 
589  // Caller writes elem rule
590  AbsInlineMeasurement& the_meas = *(default_measurements[m]);
591  push(xml_out, "elem");
592  the_meas(cur_update, xml_out);
593  pop(xml_out);
594 
595  QDPIO::cout << "HMC: finished default measurement = " << m << std::endl;
596  }
597 
598  // Always do user measurements - since they may involve
599  // things like subspace deleting or eigenbounds checking or plaquette
600  // which you may want to track through thermalization
601  // if there is something you fear is unstable during thermalization
602  // take it out of the inlineMeasurement lists
603  QDPIO::cout << "Doing " << user_measurements.size()
604  <<" user measurements" << std::endl;
605  for(int m=0; m < user_measurements.size(); m++) {
606 
607  QDPIO::cout << "HMC: considering user measurement number = " << m << std::endl;
608  AbsInlineMeasurement& the_meas = *(user_measurements[m]);
609  if( cur_update % the_meas.getFrequency() == 0 ) {
610 
611  // Caller writes elem rule
612  push(xml_out, "elem");
613  QDPIO::cout << "HMC: calling user measurement number = " << m << std::endl;
614  the_meas(cur_update, xml_out);
615  QDPIO::cout << "HMC: finished user measurement number = " << m << std::endl;
616  pop(xml_out);
617  }
618  }
619  QDPIO::cout << "HMC: finished user measurements" << std::endl;
620 
621  pop(xml_out); // pop("InlineObservables");
622 
623  // Reset the default gauge field
624  QDPIO::cout << "HMC: final resetting default gauge field" << std::endl;
626  QDPIO::cout << "HMC: finished final resetting default gauge field" << std::endl;
627  }
628 
629  swatch.stop();
630  QDPIO::cout << "After all measurements: time= "
631  << swatch.getTimeInSeconds()
632  << " secs" << std::endl;
633 
634  write(xml_out, "seconds_for_measurements", swatch.getTimeInSeconds());
635  write(xml_log, "seconds_for_measurements", swatch.getTimeInSeconds());
636 
637  if( cur_update % mc_control.save_interval == 0 )
638  {
639  swatch.reset();
640  swatch.start();
641 
642  // Save state
643  saveState<UpdateParams>(update_params, mc_control, cur_update, gauge_state.getQ());
644 
645  swatch.stop();
646  QDPIO::cout << "After saving state: time= "
647  << swatch.getTimeInSeconds()
648  << " secs" << std::endl;
649  }
650 
651  pop(xml_log); // pop("Update");
652  pop(xml_out); // pop("Update");
653 
654  pop(xml_log); // pop("elem");
655  pop(xml_out); // pop("elem");
656  }
657 
658  // Save state
659  saveState<UpdateParams>(update_params, mc_control, cur_update, gauge_state.getQ());
660 
661  pop(xml_log); // pop("MCUpdates")
662  pop(xml_out); // pop("MCUpdates")
663  }
664 
665  pop(xml_log); // pop("doHMC")
666  pop(xml_out); // pop("doHMC")
667 
668  END_CODE();
669  }
670 
671  bool linkageHack(void)
672  {
673  bool foo = true;
674 
675  // Gauge Monomials
677 
678  // Ferm Monomials
680 
681  // MD Integrators
683 
684  // Chrono predictor
686 
687  // Inline Measurements
689 
690  // Gauge initialization
691  foo &= GaugeInitEnv::registerAll();
692 
693  return foo;
694  }
695 }
696 
697 using namespace Chroma;
698 
699 //! Hybrid Monte Carlo
700 /*! \defgroup hmcmain Hybrid Monte Carlo
701  * \ingroup main
702  *
703  * Main program for dynamical fermion generation
704 xml */
705 
706 int main(int argc, char *argv[])
707 {
708  Chroma::initialize(&argc, &argv);
709 
710  START_CODE();
711 
712  // Chroma Init stuff -- Open DATA and XMLDAT
713  QDPIO::cout << "Linkage = " << linkageHack() << std::endl;
714 
715  StopWatch snoop;
716  snoop.reset();
717  snoop.start();
718 
719  XMLFileWriter& xml_out = Chroma::getXMLOutputInstance();
720  XMLFileWriter& xml_log = Chroma::getXMLLogInstance();
721 
722  push(xml_out, "hmc");
723  push(xml_log, "hmc");
724 
725  HMCTrjParams trj_params;
726  MCControl mc_control;
727 
728  try
729  {
730  XMLReader xml_in(Chroma::getXMLInputFileName());
731 
732  XMLReader paramtop(xml_in, "/Params");
733  read( paramtop, "./HMCTrj", trj_params);
734  read( paramtop, "./MCControl", mc_control);
735 
736  // Write out the input
737  write(xml_out, "Input", xml_in);
738  write(xml_log, "Input", xml_in);
739  }
740  catch(const std::string& e) {
741  QDPIO::cerr << "hmc: Caught Exception while reading file: " << e << std::endl;
742  QDP_abort(1);
743  }
744 
745  if (mc_control.start_update_num >= mc_control.n_production_updates)
746  {
747  QDPIO::cout << "hmc: run is finished" << std::endl;
748  pop(xml_log);
749  pop(xml_out);
750  exit(0);
751  }
752 
753  QDPIO::cout << "Call QDP create layout" << std::endl;
754  Layout::setLattSize(trj_params.nrow);
755  Layout::create();
756  QDPIO::cout << "Finished with QDP create layout" << std::endl;
757 
758  proginfo(xml_out); // Print out basic program info
759  proginfo(xml_log); // Print out basic program info
760 
761  // Start up the config
762  multi1d<LatticeColorMatrix> u(Nd);
763  try
764  {
765  XMLReader file_xml;
766  XMLReader config_xml;
767 
768  QDPIO::cout << "Initialize gauge field" << std::endl;
769  StopWatch swatch;
770  swatch.reset();
771  swatch.start();
772  {
773  std::istringstream xml_c(mc_control.cfg.xml);
774  XMLReader cfgtop(xml_c);
775  QDPIO::cout << "Gauge initialization: cfg_type = " << mc_control.cfg.id << std::endl;
776 
778  gaugeInit(TheGaugeInitFactory::Instance().createObject(mc_control.cfg.id,
779  cfgtop,
780  mc_control.cfg.path));
781  (*gaugeInit)(file_xml, config_xml, u);
782  }
783  swatch.stop();
784  QDPIO::cout << "Gauge field successfully initialized: time= "
785  << swatch.getTimeInSeconds()
786  << " secs" << std::endl;
787 
788  swatch.reset();
789  swatch.start();
790  int numbad = 0;
791  {
792  for(int mu=0; mu < Nd; mu++) {
793  int numbad_mu = 0;
794  reunit(u[mu],numbad_mu,REUNITARIZE_LABEL);
795  numbad += numbad_mu;
796  }
797  }
798  swatch.stop();
799  QDPIO::cout << "Gauge field reunitarization found " << numbad << " unitarity violations" << std::endl;
800  QDPIO::cout << "Gauge field reunitarized: time="
801  << swatch.getTimeInSeconds()
802  << " secs" << std::endl;
803 
804  // Write out the config header
805  write(xml_out, "Config_info", config_xml);
806  write(xml_log, "Config_info", config_xml);
807  }
808  catch(std::bad_cast)
809  {
810  QDPIO::cerr << "hmc: caught cast error" << std::endl;
811  QDP_abort(1);
812  }
813  catch(const std::string& e)
814  {
815  QDPIO::cerr << "hmc: Caught Exception: " << e << std::endl;
816  QDP_abort(1);
817  }
818  catch(std::exception& e)
819  {
820  QDPIO::cerr << "hmc: Caught standard library exception: " << e.what() << std::endl;
821  QDP_abort(1);
822  }
823  catch(...)
824  {
825  QDPIO::cerr << "hmc: caught generic exception during measurement" << std::endl;
826  QDP_abort(1);
827  }
828 
829 
830  // Set up the monomials
831  try {
832  std::istringstream Monomial_is(trj_params.Monomials_xml);
833  XMLReader monomial_reader(Monomial_is);
834  readNamedMonomialArray(monomial_reader, "/Monomials");
835  }
836  catch(const std::string& e) {
837  QDPIO::cout << "Caught Exception reading Monomials" << std::endl;
838  QDP_abort(1);
839  }
840 
841  std::istringstream H_MC_is(trj_params.H_MC_xml);
842  XMLReader H_MC_xml(H_MC_is);
843  ExactHamiltonianParams ham_params(H_MC_xml, "/Hamiltonian");
844 
846  multi1d<LatticeColorMatrix> > > H_MC(new ExactHamiltonian(ham_params));
847 
848 
849  std::istringstream MDInt_is(trj_params.Integrator_xml);
850  XMLReader MDInt_xml(MDInt_is);
851  LCMToplevelIntegratorParams int_par(MDInt_xml, "/MDIntegrator");
853  multi1d<LatticeColorMatrix> > > Integrator(new LCMToplevelIntegrator(int_par));
854 
855 
856  LatColMatHMCTrj theHMCTrj( H_MC, Integrator );
857 
858 
859  multi1d < Handle< AbsInlineMeasurement > > the_measurements;
860 
861  // Get the measurements
862  try
863  {
864  std::istringstream Measurements_is(mc_control.inline_measurement_xml);
865 
866  XMLReader MeasXML(Measurements_is);
867 
868  std::ostringstream os;
869  MeasXML.print(os);
870  QDPIO::cout << os.str() << std::endl << std::flush;
871 
872  read(MeasXML, "/InlineMeasurements", the_measurements);
873  }
874  catch(const std::string& e) {
875  QDPIO::cerr << "hmc: Caught exception while reading measurements: " << e << std::endl
876  << std::flush;
877 
878  QDP_abort(1);
879  }
880 
881  QDPIO::cout << "There are " << the_measurements.size() << " user measurements " << std::endl;
882 
883 
884  // Run
885  try {
886  doHMC<HMCTrjParams>(u, theHMCTrj, mc_control, trj_params, the_measurements);
887  }
888  catch(std::bad_cast)
889  {
890  QDPIO::cerr << "HMC: caught cast error" << std::endl;
891  QDP_abort(1);
892  }
893  catch(std::bad_alloc)
894  {
895  // This might happen on any node, so report it
896  std::cerr << "HMC: caught bad memory allocation" << std::endl;
897  QDP_abort(1);
898  }
899  catch(const std::string& e)
900  {
901  QDPIO::cerr << "HMC: Caught std::string exception: " << e << std::endl;
902  QDP_abort(1);
903  }
904  catch(std::exception& e)
905  {
906  QDPIO::cerr << "HMC: Caught standard library exception: " << e.what() << std::endl;
907  QDP_abort(1);
908  }
909  catch(...)
910  {
911  QDPIO::cerr << "HMC: Caught generic/unknown exception" << std::endl;
912  QDP_abort(1);
913  }
914 
915  pop(xml_log); // hmc
916  pop(xml_out); // hmc
917 
918  snoop.stop();
919  QDPIO::cout << "HMC: total time = "
920  << snoop.getTimeInSeconds()
921  << " secs" << std::endl;
922 
923  END_CODE();
924 
926  exit(0);
927 }
928 
929 
930 // Repro check
931 namespace Chroma {
932 
933  bool
934  checkReproducability( const multi1d<LatticeColorMatrix>& P_new,
935  const multi1d<LatticeColorMatrix>& Q_new,
936  const QDP::Seed& seed_new,
937  const multi1d<LatticeColorMatrix>& P_old,
938  const multi1d<LatticeColorMatrix>& Q_old,
939  const QDP::Seed& seed_old )
940  {
941 
942  // Compare local contributions of P
943  int diffs_found = 0;
944  if ( P_new.size() != P_old.size() ) {
945  // Something bad happened if P_old and P_new are not the same
946  return false;
947  }
948 
949  if ( Q_new.size() != Q_old.size() ) {
950  // Something bad happened if Q_old and Q_new are not the same
951  return false;
952  }
953 
954  // Count the number of bytes to compare
955  int bytes=
956  2*Nc*Nc*Layout::sitesOnNode()*sizeof(WordType< LatticeColorMatrix >::Type_t);
957 
958  // Compare P_s
959  for(int mu=0; mu < P_new.size(); mu++) {
960  const unsigned char *p1 = (const unsigned char *)P_new[mu].getF();
961  const unsigned char *p2 = (const unsigned char *)P_old[mu].getF();
962  for(int b=0; b < bytes; b++) {
963  unsigned char diff = *p1 - *p2;
964  if( diff != 0 ) diffs_found++;
965  p1++; p2++;
966  }
967  }
968 
969  // Sum up the number of diffs found globally
970  QDPInternal::globalSum(diffs_found);
971 
972  if( diffs_found != 0 ) {
973  QDPIO::cout << "Found " << diffs_found << " different bytes in momentum repro check" << std::endl;
974  return false;
975  }
976 
977  diffs_found = 0;
978  for(int mu=0; mu < P_new.size(); mu++) {
979  const unsigned char *p1 = (const unsigned char *)Q_new[mu].getF();
980  const unsigned char *p2 = (const unsigned char *)Q_old[mu].getF();
981  for(int b=0; b < bytes; b++) {
982  unsigned char diff = *p1 - *p2;
983  if( diff != 0 ) diffs_found++;
984  p1++; p2++;
985  }
986  }
987 
988  // Sum up the number of diffs found globally
989  QDPInternal::globalSum(diffs_found);
990 
991  if( diffs_found != 0 ) {
992  QDPIO::cout << "Found " << diffs_found << " different bytes in gauge repro check" << std::endl;
993  return false;
994  }
995 
996  if( ! toBool( seed_new == seed_old ) ) {
997  QDPIO::cout << "New and old RNG seeds do not match " << std::endl;
998  return false;
999  }
1000 
1001  return true;
1002  }
1003 
1004 }
Primary include file for CHROMA in application codes.
Abstract HMC trajectory.
Definition: abs_hmc.h:25
virtual unsigned long getFrequency(void) const =0
Tell me how often I should measure this beastie.
The Exact Hamiltonian Class - supplies internal field refreshment and energy calculations.
Pure gauge field state.
Definition: field_state.h:83
Class for counted reference semantics.
Definition: handle.h:33
HMC trajectory.
Definition: lcm_hmc.h:30
static T & Instance()
Definition: singleton.h:432
int numbad
Definition: cool.cc:28
int mu
Definition: cool.cc:24
void read(XMLReader &xml, const std::string &path, AsqtadFermActParams &param)
Read parameters.
void write(XMLWriter &xml, const std::string &path, const AsqtadFermActParams &param)
Writer parameters.
void proginfo(XMLWriter &xml)
Print out basic information about this program.
Definition: proginfo.cc:24
void reset()
Reset the default gauge field state.
void set(const multi1d< LatticeColorMatrix > &u, XMLBufferWriter &record_xml)
Set the default gauge field.
void readNamedMonomialArray(XMLReader &xml, const std::string &path)
Read an array of named monomials from an XML reader. use factory to create the monomials and put them...
Definition: monomial_io.cc:106
void writeGauge(XMLBufferWriter &file_xml, XMLBufferWriter &record_xml, const multi1d< LatticeColorMatrix > &u, const std::string &file, QDP_volfmt_t volfmt, QDP_serialparallel_t serpar)
Write a gauge config in QIO format.
Definition: gauge_io.cc:60
GroupXML_t readXMLGroup(XMLReader &xml_in, const std::string &path, const std::string &type_name)
Read group and return as a std::string.
int main(int argc, char *argv[])
Definition: hmc.cc:706
void setrn(int iseed[4])
Definition: make_seeds.cc:38
static int m[4]
Definition: make_seeds.cc:16
void savern(int iseed[4])
Definition: make_seeds.cc:46
Nd
Definition: meslate.cc:74
bool registerAll()
Register all the factories.
bool registerAll()
Register all the factories.
bool registerAll()
Register all the factories.
bool registerAll()
Register all the factories.
GroupXML_t createXMLGroup(const Params &p)
Returns a link smearing group with these params.
bool registerAll()
Register all the factories.
Asqtad Staggered-Dirac operator.
Definition: klein_gord.cc:10
XMLFileWriter & getXMLLogInstance()
Get xml log instance.
Definition: chroma_init.cc:378
static multi1d< LatticeColorMatrix > u
push(xml_out,"Condensates")
int i
Definition: pbg5p_w.cc:55
void saveState(const UpdateParams &update_params, MCControl &mc_control, unsigned long update_no, const multi1d< LatticeColorMatrix > &u)
Definition: const_hmc.cc:251
void initialize(int *argc, char ***argv)
Chroma initialisation routine.
Definition: chroma_init.cc:114
void finalize(void)
Chroma finalization routine.
Definition: chroma_init.cc:308
bool linkageHack(void)
Definition: const_hmc.cc:660
void reunit(LatticeColorMatrixF3 &xa)
Definition: reunit.cc:467
void doHMC(multi1d< LatticeColorMatrix > &u, AbsHMCTrj< multi1d< LatticeColorMatrix >, multi1d< LatticeColorMatrix > > &theHMCTrj, MCControl &mc_control, const UpdateParams &update_params, multi1d< Handle< AbsInlineMeasurement > > &user_measurements)
Definition: const_hmc.cc:356
@ REUNITARIZE_LABEL
Definition: reunit.h:29
void setForceMonitoring(bool monitorP)
std::string getXMLInputFileName()
Get input file name.
Definition: chroma_init.cc:88
pop(xml_out)
START_CODE()
Complex b
Definition: invbicg.cc:96
bool checkReproducability(const multi1d< LatticeColorMatrix > &P_new, const multi1d< LatticeColorMatrix > &Q_new, const QDP::Seed &seed_new, const multi1d< LatticeColorMatrix > &P_old, const multi1d< LatticeColorMatrix > &Q_old, const QDP::Seed &seed_old)
Definition: const_hmc.cc:920
XMLFileWriter & getXMLOutputInstance()
Get xml output instance.
Definition: chroma_init.cc:359
::std::string string
Definition: gtest.h:1979
Real dummy
Definition: qtopcor.cc:36
Parameter structure for new Hamiltonian.
Hold group xml and type id.
std::string Integrator_xml
Definition: const_hmc.cc:184
multi1d< int > nrow
Definition: const_hmc.cc:179
std::string H_MC_xml
Definition: const_hmc.cc:183
std::string Monomials_xml
Definition: const_hmc.cc:182
A Structure to hold the top level parameters.
Params controlling running of monte carlo.
Definition: const_hmc.cc:14
unsigned long n_warm_up_updates
Definition: const_hmc.cc:18
std::string inline_measurement_xml
Definition: const_hmc.cc:25
unsigned long n_production_updates
Definition: const_hmc.cc:19
QDP_serialparallel_t save_pario
Definition: const_hmc.cc:24
QDP::Seed rng_seed
Definition: const_hmc.cc:16
unsigned int save_interval
Definition: const_hmc.cc:21
unsigned int n_updates_this_run
Definition: const_hmc.cc:20
QDP_volfmt_t save_volfmt
Definition: const_hmc.cc:23
GroupXML_t cfg
Definition: const_hmc.cc:15
int repro_check_frequency
Definition: const_hmc.cc:27
std::string save_prefix
Definition: const_hmc.cc:22
unsigned long start_update_num
Definition: const_hmc.cc:17
Params for initializing config.