hmc.cc

Go to the documentation of this file.
00001 // $Id: hmc.cc,v 3.24 2009/06/01 16:24:54 bjoo Exp $
00002 /*! \file
00003  *  \brief Main code for HMC with dynamical fermion generation
00004  */
00005 
00006 #include "chroma.h"
00007 #include <string>
00008 
00009 using namespace Chroma;
00010 
00011 namespace Chroma 
00012 { 
00013   
00014   struct MCControl 
00015   {
00016     GroupXML_t    cfg;
00017     QDP::Seed     rng_seed;
00018     unsigned long start_update_num;
00019     unsigned long n_warm_up_updates;
00020     unsigned long n_production_updates;
00021     unsigned int  n_updates_this_run;
00022     unsigned int  save_interval;
00023     std::string   save_prefix;
00024     QDP_volfmt_t  save_volfmt;
00025     std::string   inline_measurement_xml;
00026     bool          repro_checkP;
00027     int           repro_check_frequency;
00028     bool          rev_checkP;
00029     int           rev_check_frequency;
00030     bool          monitorForcesP;
00031 
00032   };
00033   
00034   void read(XMLReader& xml, const std::string& path, MCControl& p) 
00035   {
00036     START_CODE();
00037 
00038     try { 
00039       XMLReader paramtop(xml, path);
00040       p.cfg = readXMLGroup(paramtop, "Cfg", "cfg_type");
00041       read(paramtop, "./RNG", p.rng_seed);
00042       read(paramtop, "./StartUpdateNum", p.start_update_num);
00043       read(paramtop, "./NWarmUpUpdates", p.n_warm_up_updates);
00044       read(paramtop, "./NProductionUpdates", p.n_production_updates);
00045       read(paramtop, "./NUpdatesThisRun", p.n_updates_this_run);
00046       read(paramtop, "./SaveInterval", p.save_interval);
00047       read(paramtop, "./SavePrefix", p.save_prefix);
00048       read(paramtop, "./SaveVolfmt", p.save_volfmt);
00049 
00050 
00051       // Default values: repro check is on, frequency is 10%
00052       p.repro_checkP = true;
00053       p.repro_check_frequency = 10;
00054 
00055 
00056       // Now overwrite with user values
00057       if( paramtop.count("./ReproCheckP") == 1 ) {
00058         // Read user value if given
00059         read(paramtop, "./ReproCheckP", p.repro_checkP);
00060       }
00061 
00062       // If we do repro checking, read the frequency
00063       if( p.repro_checkP ) { 
00064         if( paramtop.count("./ReproCheckFrequency") == 1 ) {
00065           // Read user value if given
00066           read(paramtop, "./ReproCheckFrequency", p.repro_check_frequency);
00067         }
00068       }
00069 
00070       // Reversibility checking enabled by default.
00071       p.rev_checkP = true;
00072       p.rev_check_frequency = 10;
00073 
00074       // Now overwrite with user values
00075       if( paramtop.count("./ReverseCheckP") == 1 ) {
00076         // Read user value if given
00077         read(paramtop, "./ReverseCheckP", p.rev_checkP);
00078       }
00079 
00080       // If we do repro checking, read the frequency
00081       if( p.rev_checkP ) { 
00082         if( paramtop.count("./ReverseCheckFrequency") == 1 ) {
00083           // Read user value if given
00084           read(paramtop, "./ReverseCheckFrequency", p.rev_check_frequency);
00085         }
00086       }
00087 
00088       if( paramtop.count("./MonitorForces") == 1 ) {
00089         read(paramtop, "./MonitorForces", p.monitorForcesP);
00090       }
00091       else { 
00092         p.monitorForcesP = true;
00093       }
00094 
00095       if( paramtop.count("./InlineMeasurements") == 0 ) {
00096         XMLBufferWriter dummy;
00097         push(dummy, "InlineMeasurements");
00098         pop(dummy); // InlineMeasurements
00099         p.inline_measurement_xml = dummy.printCurrentContext();
00100         
00101       }
00102       else {
00103         XMLReader measurements_xml(paramtop, "./InlineMeasurements");
00104         std::ostringstream inline_os;
00105         measurements_xml.print(inline_os);
00106         p.inline_measurement_xml = inline_os.str();
00107         QDPIO::cout << "InlineMeasurements are: " << endl;
00108         QDPIO::cout << p.inline_measurement_xml << endl;
00109       }
00110 
00111       
00112     }
00113     catch(const std::string& e ) { 
00114       QDPIO::cerr << "Caught Exception: " << e << endl;
00115       QDP_abort(1);
00116     }
00117     
00118     END_CODE();
00119   }
00120 
00121   void write(XMLWriter& xml, const std::string& path, const MCControl& p) 
00122   {
00123     START_CODE();
00124     
00125     try {
00126       push(xml, path);
00127       xml << p.cfg.xml;
00128       write(xml, "RNG", p.rng_seed);
00129       write(xml, "StartUpdateNum", p.start_update_num);
00130       write(xml, "NWarmUpUpdates", p.n_warm_up_updates);
00131       write(xml, "NProductionUpdates", p.n_production_updates);
00132       write(xml, "NUpdatesThisRun", p.n_updates_this_run);
00133       write(xml, "SaveInterval", p.save_interval);
00134       write(xml, "SavePrefix", p.save_prefix);
00135       write(xml, "SaveVolfmt", p.save_volfmt);
00136       write(xml, "ReproCheckP", p.repro_checkP);
00137       if( p.repro_checkP ) { 
00138         write(xml, "ReproCheckFrequency", p.repro_check_frequency);
00139       }
00140       write(xml, "ReverseCheckP", p.rev_checkP);
00141       if( p.rev_checkP ) { 
00142         write(xml, "ReverseCheckFrequency", p.rev_check_frequency);
00143       }
00144       write(xml, "MonitorForces", p.monitorForcesP);
00145 
00146       xml << p.inline_measurement_xml;
00147       
00148       pop(xml);
00149       
00150     }
00151     catch(const std::string& e ) { 
00152       QDPIO::cerr << "Caught Exception: " << e << endl;
00153       QDP_abort(1);
00154     }
00155     
00156     END_CODE();
00157   }
00158 
00159 
00160   struct HMCTrjParams 
00161   { 
00162     multi1d<int> nrow;
00163     
00164     // Polymorphic
00165     std::string Monomials_xml; // XML for the monomials
00166     std::string H_MC_xml;      // XML for the Hamiltonian
00167     std::string Integrator_xml; // XML for the Integrator
00168   };
00169   
00170   void write(XMLWriter& xml, const std::string& path, const HMCTrjParams& p)
00171   {
00172     START_CODE();
00173     
00174     try { 
00175       push(xml, path);
00176       write(xml, "nrow", p.nrow);
00177       xml << p.Monomials_xml;   // XML For the mon
00178       xml << p.H_MC_xml;
00179       xml << p.Integrator_xml;
00180       pop(xml);
00181     }
00182     catch(const std::string& e ) { 
00183       QDPIO::cerr << "Caught Exception: " << e << endl;
00184       QDP_abort(1);
00185     }
00186     
00187     END_CODE();
00188   }
00189 
00190 
00191   void read(XMLReader& xml, const std::string& path, HMCTrjParams& p) 
00192   {
00193     START_CODE();
00194     
00195     try {
00196       XMLReader paramtop(xml, path);
00197       
00198       read(paramtop, "./nrow", p.nrow);
00199       XMLReader Monomials_xml_reader(paramtop, "./Monomials");
00200       std::ostringstream os_Monomials;
00201       Monomials_xml_reader.print(os_Monomials);
00202       p.Monomials_xml = os_Monomials.str();
00203       QDPIO::cout << "Monomials xml is:" << endl;
00204       QDPIO::cout << p.Monomials_xml << endl;
00205 
00206       // Now the XML for the Hamiltonians
00207       XMLReader H_MC_xml(paramtop, "./Hamiltonian");
00208       std::ostringstream os_H_MC;
00209       H_MC_xml.print(os_H_MC);
00210       p.H_MC_xml = os_H_MC.str();
00211       
00212       QDPIO::cout << "HMC_xml is: " << endl;
00213       QDPIO::cout << p.H_MC_xml;
00214       
00215       
00216       // Read the Integrator parameters
00217       XMLReader MD_integrator_xml(paramtop, "./MDIntegrator");
00218       std::ostringstream os_integrator;
00219       MD_integrator_xml.print(os_integrator);
00220       p.Integrator_xml = os_integrator.str();
00221 
00222       QDPIO::cout << "Integrator XML is: " << endl;
00223       QDPIO::cout << p.Integrator_xml << endl;
00224     }
00225     catch( const std::string& e ) { 
00226       QDPIO::cerr << "Error reading XML : " << e << endl;
00227       QDP_abort(1);
00228     }
00229     
00230     END_CODE();
00231   }
00232 
00233   template<typename UpdateParams>
00234   void saveState(const UpdateParams& update_params, 
00235                  MCControl& mc_control,
00236                  unsigned long update_no,
00237                 const multi1d<LatticeColorMatrix>& u) {
00238     // Do nothing
00239   }
00240 
00241   // Specialise
00242   template<>
00243   void saveState(const HMCTrjParams& update_params, 
00244                  MCControl& mc_control,
00245                  unsigned long update_no,
00246                  const multi1d<LatticeColorMatrix>& u)
00247   {
00248     START_CODE();
00249     
00250     // File names
00251     std::ostringstream restart_data_filename;
00252     restart_data_filename << mc_control.save_prefix << "_restart_" << update_no << ".xml" ;
00253     
00254     std::ostringstream restart_config_filename;
00255     restart_config_filename << mc_control.save_prefix << "_cfg_" << update_no << ".lime";
00256       
00257     XMLBufferWriter restart_data_buffer;
00258 
00259     
00260     // Copy old params
00261     MCControl p_new = mc_control;
00262     
00263     // Get Current RNG Seed
00264     QDP::RNG::savern(p_new.rng_seed);
00265    
00266     // Set the current traj number
00267     p_new.start_update_num = update_no;
00268     
00269     // Set the num_updates_this_run
00270     unsigned long total = mc_control.n_warm_up_updates 
00271       + mc_control.n_production_updates ;
00272 
00273     if ( total < mc_control.n_updates_this_run + update_no ) { 
00274       p_new.n_updates_this_run = total - update_no;
00275     }
00276 
00277     // Set the name and type of the config 
00278     {
00279       SZINQIOGaugeInitEnv::Params  cfg;
00280       cfg.cfg_file = restart_config_filename.str();
00281 
00282       p_new.cfg = SZINQIOGaugeInitEnv::createXMLGroup(cfg);
00283     }
00284 
00285 
00286     push(restart_data_buffer, "Params");
00287     write(restart_data_buffer, "MCControl", p_new);
00288     write(restart_data_buffer, "HMCTrj", update_params);
00289     pop(restart_data_buffer);
00290 
00291     // Write a restart DATA file from the buffer XML
00292     
00293     XMLFileWriter restart_xml(restart_data_filename.str().c_str());
00294     restart_xml << restart_data_buffer;
00295     restart_xml.close();
00296 
00297     // Save the config
00298 
00299     // some dummy header for the file
00300     XMLBufferWriter file_xml;
00301     push(file_xml, "HMC");
00302     proginfo(file_xml);
00303     pop(file_xml);
00304 
00305 
00306     // Save the config
00307     writeGauge(file_xml, 
00308                restart_data_buffer,
00309                u,
00310                restart_config_filename.str(),
00311                p_new.save_volfmt,
00312                QDPIO_SERIAL);    
00313     
00314     END_CODE();
00315   }
00316 
00317 
00318  
00319   // Predeclare this 
00320   bool checkReproducability( const multi1d<LatticeColorMatrix>& P_new, 
00321                              const multi1d<LatticeColorMatrix>& Q_new,
00322                              const QDP::Seed& seed_new,
00323                              const multi1d<LatticeColorMatrix>& P_old,
00324                              const multi1d<LatticeColorMatrix>& Q_old,
00325                              const QDP::Seed& seed_old );
00326 
00327   template<typename UpdateParams>
00328   void doHMC(multi1d<LatticeColorMatrix>& u,
00329              AbsHMCTrj<multi1d<LatticeColorMatrix>,
00330                        multi1d<LatticeColorMatrix> >& theHMCTrj,
00331              MCControl& mc_control, 
00332              const UpdateParams& update_params,
00333              multi1d< Handle<AbsInlineMeasurement> >& user_measurements) 
00334   {
00335     START_CODE();
00336 
00337 
00338     // Turn monitoring off/on
00339     QDPIO::cout << "Setting Force monitoring to " << mc_control.monitorForcesP  << endl;
00340     setForceMonitoring(mc_control.monitorForcesP) ;
00341     QDP::StopWatch swatch;
00342 
00343     XMLWriter& xml_out = TheXMLOutputWriter::Instance();
00344     XMLWriter& xml_log = TheXMLLogWriter::Instance();
00345 
00346     push(xml_out, "doHMC");
00347     push(xml_log, "doHMC");
00348 
00349     multi1d< Handle< AbsInlineMeasurement > > default_measurements(1);
00350     InlinePlaquetteEnv::Params plaq_params;
00351     plaq_params.frequency = 1;
00352     // It is a handle
00353     default_measurements[0] = new InlinePlaquetteEnv::InlineMeas(plaq_params);
00354 
00355     {
00356       // Initialise the RNG
00357       QDP::RNG::setrn(mc_control.rng_seed);
00358       
00359       // Fictitious momenta for now
00360       multi1d<LatticeColorMatrix> p(Nd);
00361       
00362       // Create a field state
00363       GaugeFieldState gauge_state(p,u);
00364       
00365       // Set the update number
00366       unsigned long cur_update=mc_control.start_update_num;
00367       
00368       // Compute how many updates to do
00369       unsigned long total_updates = mc_control.n_warm_up_updates
00370         + mc_control.n_production_updates;
00371       
00372       unsigned long to_do = 0;
00373       if ( total_updates >= mc_control.n_updates_this_run + cur_update +1 ) {
00374         to_do = mc_control.n_updates_this_run;
00375       }
00376       else {
00377         to_do = total_updates - cur_update ;
00378       }
00379       
00380       QDPIO::cout << "MC Control: About to do " << to_do << " updates" << endl;
00381 
00382       // XML Output
00383       push(xml_out, "MCUpdates");
00384       push(xml_log, "MCUpdates");
00385 
00386       for(int i=0; i < to_do; i++) 
00387       {
00388         push(xml_out, "elem"); // Caller writes elem rule
00389         push(xml_log, "elem"); // Caller writes elem rule
00390 
00391         push(xml_out, "Update");
00392         push(xml_log, "Update");
00393         // Increase current update counter
00394         cur_update++;
00395         
00396         // Decide if the next update is a warm up or not
00397         bool warm_up_p = cur_update  <= mc_control.n_warm_up_updates;
00398         QDPIO::cout << "Doing Update: " << cur_update << " warm_up_p = " << warm_up_p << endl;
00399 
00400         // Log
00401         write(xml_out, "update_no", cur_update);
00402         write(xml_log, "update_no", cur_update);
00403 
00404         write(xml_out, "WarmUpP", warm_up_p);
00405         write(xml_log, "WarmUpP", warm_up_p);
00406 
00407         bool do_reverse = false;
00408         if( mc_control.rev_checkP 
00409             && ( cur_update % mc_control.rev_check_frequency == 0 )) {
00410           do_reverse = true;
00411           QDPIO::cout << "Doing Reversibility Test this traj" << endl;
00412         }
00413 
00414 
00415         // Check if I need to do any reproducibility testing
00416         if( mc_control.repro_checkP 
00417             && (cur_update % mc_control.repro_check_frequency == 0 ) 
00418             ) { 
00419 
00420           // Yes - reproducibility trajectory
00421           // Save fields and RNG at start of trajectory
00422           QDPIO::cout << "Saving start config and RNG seed for reproducability test" << endl;
00423 
00424           GaugeFieldState repro_bkup_start( gauge_state.getP(), gauge_state.getQ());
00425           QDP::Seed rng_seed_bkup_start;
00426           QDP::RNG::savern(rng_seed_bkup_start);
00427           
00428           // DO the trajectory
00429           QDPIO::cout << "Before HMC trajectory call" << endl;
00430           swatch.reset(); 
00431           swatch.start();
00432 
00433           // This may do a reversibility check 
00434           theHMCTrj( gauge_state, warm_up_p, do_reverse ); 
00435           swatch.stop(); 
00436           
00437           QDPIO::cout << "After HMC trajectory call: time= "
00438                       << swatch.getTimeInSeconds() 
00439                       << " secs" << endl;
00440           
00441           write(xml_out, "seconds_for_trajectory", swatch.getTimeInSeconds());
00442           write(xml_log, "seconds_for_trajectory", swatch.getTimeInSeconds());
00443 
00444           // Save the fields and RNG at the end
00445           QDPIO::cout << "Saving end config and RNG seed for reproducability test" << endl;
00446           GaugeFieldState repro_bkup_end( gauge_state.getP(), gauge_state.getQ());
00447           QDP::Seed rng_seed_bkup_end;
00448           QDP::RNG::savern(rng_seed_bkup_end);
00449 
00450           // Restore the starting field and the starting RNG
00451           QDPIO::cout << "Restoring start config and RNG for reproducability test" << endl;
00452 
00453           gauge_state.getP() = repro_bkup_start.getP(); 
00454           gauge_state.getQ() = repro_bkup_start.getQ(); 
00455           QDP::RNG::setrn(rng_seed_bkup_start); 
00456 
00457           // Do the repro trajectory
00458           QDPIO::cout << "Before HMC repro trajectory call" << endl;
00459           swatch.reset(); 
00460           swatch.start();
00461           // Dont repeat the reversibility check in the repro test
00462           theHMCTrj( gauge_state, warm_up_p, false ); 
00463           swatch.stop(); 
00464           
00465           QDPIO::cout << "After HMC repro trajectory call: time= "
00466                       << swatch.getTimeInSeconds() 
00467                       << " secs" << endl;
00468           
00469           write(xml_out, "seconds_for_repro_trajectory", swatch.getTimeInSeconds());
00470           write(xml_log, "seconds_for_repro_trajectory", swatch.getTimeInSeconds());
00471  
00472           // Save seed at end of traj for comparison
00473           QDP::Seed rng_seed_end2;
00474           QDP::RNG::savern(rng_seed_end2);
00475 
00476 
00477           // Check the reproducibility 
00478           bool pass = checkReproducability( gauge_state.getP(), 
00479                                             gauge_state.getQ(), 
00480                                             rng_seed_end2,
00481                                             repro_bkup_end.getP(), 
00482                                             repro_bkup_end.getQ(), 
00483                                             rng_seed_bkup_end);
00484 
00485           
00486           if( !pass ) { 
00487             QDPIO::cout << "Reproducability check failed on update " << cur_update << endl;
00488             QDPIO::cout << "Aborting" << endl;
00489             write(xml_out, "ReproCheck", pass);
00490             write(xml_log, "ReproCheck", pass);
00491             QDP_abort(1);
00492           }
00493           else { 
00494             QDPIO::cout << "Reproducability check passed on update " << cur_update << endl;
00495             write(xml_out, "ReproCheck", pass);
00496             write(xml_log, "ReproCheck", pass);
00497           }
00498 
00499 
00500         }
00501         else { 
00502 
00503           // Do the trajectory without accepting
00504           QDPIO::cout << "Before HMC trajectory call" << endl;
00505           swatch.reset();
00506           swatch.start();
00507           theHMCTrj( gauge_state, warm_up_p, do_reverse  );
00508           swatch.stop();
00509         
00510           QDPIO::cout << "After HMC trajectory call: time= "
00511                       << swatch.getTimeInSeconds() 
00512                       << " secs" << endl;
00513           
00514           write(xml_out, "seconds_for_trajectory", swatch.getTimeInSeconds());
00515           write(xml_log, "seconds_for_trajectory", swatch.getTimeInSeconds());
00516 
00517         }
00518         swatch.reset();
00519         swatch.start();
00520 
00521         // Create a gauge header for inline measurements.
00522         // Since there are defaults always measured, we must always
00523         // create a header.
00524         //
00525         // NOTE: THIS HEADER STUFF NEEDS A LOT MORE THOUGHT
00526         //
00527         QDPIO::cout << "HMC: start inline measurements" << endl;
00528         {
00529           XMLBufferWriter gauge_xml;
00530           push(gauge_xml, "ChromaHMC");
00531           write(gauge_xml, "update_no", cur_update);
00532           write(gauge_xml, "HMCTrj", update_params);
00533           pop(gauge_xml);
00534 
00535           // Reset and set the default gauge field
00536           QDPIO::cout << "HMC: initial resetting default gauge field" << endl;
00537           InlineDefaultGaugeField::reset();
00538           QDPIO::cout << "HMC: set default gauge field" << endl;
00539           InlineDefaultGaugeField::set(gauge_state.getQ(), gauge_xml);
00540           QDPIO::cout << "HMC: finished setting default gauge field" << endl;
00541 
00542           // Measure inline observables 
00543           push(xml_out, "InlineObservables");
00544 
00545           // Always measure defaults
00546           for(int m=0; m < default_measurements.size(); m++) 
00547           {
00548             QDPIO::cout << "HMC: do default measurement = " << m << endl;
00549             QDPIO::cout << "HMC: dump named objects" << endl;
00550             TheNamedObjMap::Instance().dump();
00551 
00552             // Caller writes elem rule 
00553             AbsInlineMeasurement& the_meas = *(default_measurements[m]);
00554             push(xml_out, "elem");
00555             the_meas(cur_update, xml_out);
00556             pop(xml_out);
00557 
00558             QDPIO::cout << "HMC: finished default measurement = " << m << endl;
00559           }
00560         
00561           // Only measure user measurements after warm up
00562           if( ! warm_up_p ) 
00563           {
00564             QDPIO::cout << "Doing " << user_measurements.size() 
00565                         <<" user measurements" << endl;
00566             for(int m=0; m < user_measurements.size(); m++) 
00567             {
00568               QDPIO::cout << "HMC: considering user measurement number = " << m << endl;
00569               AbsInlineMeasurement& the_meas = *(user_measurements[m]);
00570               if( cur_update % the_meas.getFrequency() == 0 ) 
00571               { 
00572                 // Caller writes elem rule
00573                 push(xml_out, "elem");
00574                 QDPIO::cout << "HMC: calling user measurement number = " << m << endl;
00575                 the_meas(cur_update, xml_out);
00576                 QDPIO::cout << "HMC: finished user measurement number = " << m << endl;
00577                 pop(xml_out); 
00578               }
00579             }
00580             QDPIO::cout << "HMC: finished user measurements" << endl;
00581           }
00582           pop(xml_out); // pop("InlineObservables");
00583 
00584           // Reset the default gauge field
00585           QDPIO::cout << "HMC: final resetting default gauge field" << endl;
00586           InlineDefaultGaugeField::reset();
00587           QDPIO::cout << "HMC: finished final resetting default gauge field" << endl;
00588         }
00589 
00590         swatch.stop();
00591         QDPIO::cout << "After all measurements: time= "
00592                     << swatch.getTimeInSeconds() 
00593                     << " secs" << endl;
00594 
00595         write(xml_out, "seconds_for_measurements", swatch.getTimeInSeconds());
00596         write(xml_log, "seconds_for_measurements", swatch.getTimeInSeconds());
00597 
00598         if( cur_update % mc_control.save_interval == 0 ) 
00599         {
00600           swatch.reset();
00601           swatch.start();
00602 
00603           // Save state
00604           saveState<UpdateParams>(update_params, mc_control, cur_update, gauge_state.getQ());
00605 
00606           swatch.stop();
00607           QDPIO::cout << "After saving state: time= "
00608                       << swatch.getTimeInSeconds() 
00609                       << " secs" << endl;
00610         }
00611 
00612         pop(xml_log); // pop("Update");
00613         pop(xml_out); // pop("Update");
00614 
00615         pop(xml_log); // pop("elem");
00616         pop(xml_out); // pop("elem");
00617       }   
00618       
00619       // Save state
00620       saveState<UpdateParams>(update_params, mc_control, cur_update, gauge_state.getQ());
00621       
00622       pop(xml_log); // pop("MCUpdates")
00623       pop(xml_out); // pop("MCUpdates")
00624     }
00625 
00626     pop(xml_log); // pop("doHMC")
00627     pop(xml_out); // pop("doHMC")
00628     
00629     END_CODE();
00630   }
00631   
00632   bool linkageHack(void)
00633   {
00634     bool foo = true;
00635     
00636     // Gauge Monomials
00637     foo &= GaugeMonomialEnv::registerAll();
00638     
00639     // Ferm Monomials
00640     foo &= WilsonTypeFermMonomialAggregrateEnv::registerAll();
00641     
00642     // MD Integrators
00643     foo &= LCMMDComponentIntegratorAggregateEnv::registerAll();
00644 
00645     // Chrono predictor
00646     foo &= ChronoPredictorAggregrateEnv::registerAll();
00647 
00648     // Inline Measurements
00649     foo &= InlineAggregateEnv::registerAll();
00650 
00651     // Gauge initialization
00652     foo &= GaugeInitEnv::registerAll();
00653 
00654     return foo;
00655   }
00656 };
00657 
00658 using namespace Chroma;
00659 
00660 //! Hybrid Monte Carlo
00661 /*! \defgroup hmcmain Hybrid Monte Carlo
00662  *  \ingroup main
00663  *
00664  * Main program for dynamical fermion generation
00665 xml */
00666 
00667 int main(int argc, char *argv[]) 
00668 {
00669   Chroma::initialize(&argc, &argv);
00670   
00671   START_CODE();
00672 
00673   // Chroma Init stuff -- Open DATA and XMLDAT
00674   QDPIO::cout << "Linkage = " << linkageHack() << endl;
00675 
00676   StopWatch snoop;
00677   snoop.reset();
00678   snoop.start();
00679 
00680   XMLFileWriter& xml_out = Chroma::getXMLOutputInstance();
00681   XMLFileWriter& xml_log = Chroma::getXMLLogInstance();
00682 
00683   push(xml_out, "hmc");
00684   push(xml_log, "hmc");
00685 
00686   HMCTrjParams trj_params;
00687   MCControl    mc_control;
00688 
00689   try
00690   {
00691     XMLReader xml_in(Chroma::getXMLInputFileName());
00692 
00693     XMLReader paramtop(xml_in, "/Params");
00694     read( paramtop, "./HMCTrj", trj_params);
00695     read( paramtop, "./MCControl", mc_control);
00696     
00697     // Write out the input
00698     write(xml_out, "Input", xml_in);
00699     write(xml_log, "Input", xml_in);
00700   }
00701   catch(const std::string& e) {
00702     QDPIO::cerr << "hmc: Caught Exception while reading file: " << e << endl;
00703     QDP_abort(1);
00704   }
00705 
00706   if (mc_control.start_update_num >= mc_control.n_production_updates)
00707   {
00708     QDPIO::cout << "hmc: run is finished" << endl;
00709     pop(xml_log);
00710     pop(xml_out);
00711     exit(0);
00712   }
00713 
00714   QDPIO::cout << "Call QDP create layout" << endl;
00715   Layout::setLattSize(trj_params.nrow);
00716   Layout::create();
00717   QDPIO::cout << "Finished with QDP create layout" << endl;
00718 
00719   proginfo(xml_out);    // Print out basic program info
00720   proginfo(xml_log);    // Print out basic program info
00721 
00722   // Start up the config
00723   multi1d<LatticeColorMatrix> u(Nd);
00724   try
00725   {
00726     XMLReader file_xml;
00727     XMLReader config_xml;
00728     
00729     QDPIO::cout << "Initialize gauge field" << endl;
00730     StopWatch swatch;
00731     swatch.reset();
00732     swatch.start();
00733     {
00734       std::istringstream  xml_c(mc_control.cfg.xml);
00735       XMLReader  cfgtop(xml_c);
00736       QDPIO::cout << "Gauge initialization: cfg_type = " << mc_control.cfg.id << endl;
00737 
00738       Handle< GaugeInit >
00739         gaugeInit(TheGaugeInitFactory::Instance().createObject(mc_control.cfg.id,
00740                                                                cfgtop,
00741                                                                mc_control.cfg.path));
00742       (*gaugeInit)(file_xml, config_xml, u);
00743     }
00744     swatch.stop();
00745     QDPIO::cout << "Gauge field successfully initialized: time= " 
00746                 << swatch.getTimeInSeconds() 
00747                 << " secs" << endl;
00748 
00749     swatch.reset();
00750     swatch.start();
00751     {
00752       for(int mu=0; mu < Nd; mu++) { 
00753         reunit(u[mu]);
00754       }
00755     }
00756     swatch.stop();
00757     QDPIO::cout << "Gauge field reunitarized: time="
00758                 << swatch.getTimeInSeconds()
00759                 << " secs" << endl;
00760 
00761     // Write out the config header
00762     write(xml_out, "Config_info", config_xml);
00763     write(xml_log, "Config_info", config_xml);
00764   }
00765   catch(std::bad_cast) 
00766   {
00767     QDPIO::cerr << "hmc: caught cast error" << endl;
00768     QDP_abort(1);
00769   }
00770   catch(const std::string& e) 
00771   {
00772     QDPIO::cerr << "hmc: Caught Exception: " << e << endl;
00773     QDP_abort(1);
00774   }
00775   catch(std::exception& e) 
00776   {
00777     QDPIO::cerr << "hmc: Caught standard library exception: " << e.what() << endl;
00778     QDP_abort(1);
00779   }
00780   catch(...)
00781   {
00782     QDPIO::cerr << "hmc: caught generic exception during measurement" << endl;
00783     QDP_abort(1);
00784   }
00785 
00786   
00787   // Set up the monomials
00788   try { 
00789     std::istringstream Monomial_is(trj_params.Monomials_xml);
00790     XMLReader monomial_reader(Monomial_is);
00791     readNamedMonomialArray(monomial_reader, "/Monomials");
00792   }
00793   catch(const std::string& e) { 
00794     QDPIO::cout << "Caught Exception reading Monomials" << endl;
00795     QDP_abort(1);
00796   }
00797 
00798   std::istringstream H_MC_is(trj_params.H_MC_xml);
00799   XMLReader H_MC_xml(H_MC_is);
00800   ExactHamiltonianParams ham_params(H_MC_xml, "/Hamiltonian");
00801     
00802   Handle< AbsHamiltonian< multi1d<LatticeColorMatrix>,     
00803     multi1d<LatticeColorMatrix> > > H_MC(new ExactHamiltonian(ham_params));
00804  
00805 
00806   std::istringstream MDInt_is(trj_params.Integrator_xml);
00807   XMLReader MDInt_xml(MDInt_is);
00808   LCMToplevelIntegratorParams int_par(MDInt_xml, "/MDIntegrator");
00809   Handle< AbsMDIntegrator< multi1d<LatticeColorMatrix>,
00810     multi1d<LatticeColorMatrix> > > Integrator(new LCMToplevelIntegrator(int_par));
00811 
00812 
00813   LatColMatHMCTrj theHMCTrj( H_MC, Integrator );
00814 
00815  
00816   multi1d < Handle< AbsInlineMeasurement > > the_measurements;
00817 
00818   // Get the measurements
00819   try 
00820   { 
00821     std::istringstream Measurements_is(mc_control.inline_measurement_xml);
00822 
00823     XMLReader MeasXML(Measurements_is);
00824 
00825     std::ostringstream os;
00826     MeasXML.print(os);
00827     QDPIO::cout << os.str() << endl << flush;
00828 
00829     read(MeasXML, "/InlineMeasurements", the_measurements);
00830   }
00831   catch(const std::string& e) { 
00832     QDPIO::cerr << "hmc: Caught exception while reading measurements: " << e << endl
00833                 << flush;
00834 
00835     QDP_abort(1);
00836   }
00837 
00838   QDPIO::cout << "There are " << the_measurements.size() << " user measurements " << endl;
00839 
00840   
00841   // Run
00842   try { 
00843     doHMC<HMCTrjParams>(u, theHMCTrj, mc_control, trj_params, the_measurements);
00844   } 
00845   catch(std::bad_cast) 
00846   {
00847     QDPIO::cerr << "HMC: caught cast error" << endl;
00848     QDP_abort(1);
00849   }
00850   catch(std::bad_alloc) 
00851   { 
00852     // This might happen on any node, so report it
00853     cerr << "HMC: caught bad memory allocation" << endl;
00854     QDP_abort(1);
00855   }
00856   catch(const std::string& e) 
00857   { 
00858     QDPIO::cerr << "HMC: Caught string exception: " << e << endl;
00859     QDP_abort(1);
00860   }
00861   catch(std::exception& e) 
00862   {
00863     QDPIO::cerr << "HMC: Caught standard library exception: " << e.what() << endl;
00864     QDP_abort(1);
00865   }
00866   catch(...) 
00867   {
00868     QDPIO::cerr << "HMC: Caught generic/unknown exception" << endl;
00869     QDP_abort(1);
00870   }
00871 
00872   pop(xml_log);  // hmc
00873   pop(xml_out);  // hmc
00874 
00875   snoop.stop();
00876   QDPIO::cout << "HMC: total time = "
00877               << snoop.getTimeInSeconds() 
00878               << " secs" << endl;
00879 
00880   END_CODE();
00881 
00882   Chroma::finalize();
00883   exit(0);
00884 }
00885 
00886 
00887 // Repro check
00888 namespace Chroma { 
00889 
00890   bool 
00891   checkReproducability( const multi1d<LatticeColorMatrix>& P_new, 
00892                         const multi1d<LatticeColorMatrix>& Q_new,
00893                         const QDP::Seed& seed_new,
00894                         const multi1d<LatticeColorMatrix>& P_old,
00895                         const multi1d<LatticeColorMatrix>& Q_old,
00896                         const QDP::Seed& seed_old ) 
00897   {
00898     
00899     // Compare local contributions of P
00900     int diffs_found = 0;
00901     if ( P_new.size() != P_old.size() ) { 
00902       // Something bad happened if P_old and P_new are not the same
00903       return false;
00904     }
00905     
00906     if ( Q_new.size() != Q_old.size() ) { 
00907       // Something bad happened if Q_old and Q_new are not the same
00908       return false;
00909     }
00910     
00911     // Count the number of bytes to compare
00912     int bytes=
00913       2*Nc*Nc*Layout::sitesOnNode()*sizeof(WordType< LatticeColorMatrix >::Type_t);
00914     
00915     // Compare P_s
00916     for(int mu=0; mu < P_new.size(); mu++) { 
00917       const unsigned char *p1 = (const unsigned char *)P_new[mu].getF();
00918       const unsigned char *p2 = (const unsigned char *)P_old[mu].getF();
00919       for(int b=0; b < bytes; b++) {
00920         unsigned char diff = *p1 - *p2; 
00921         if( diff != 0 ) diffs_found++;
00922         p1++; p2++;
00923       }
00924     }
00925     
00926     // Sum up the number of diffs found globally
00927     Internal::globalSum(diffs_found);
00928     
00929     if( diffs_found != 0 ) { 
00930       QDPIO::cout << "Found " << diffs_found << " different bytes in momentum repro check" << endl;
00931       return false;
00932     }
00933     
00934     diffs_found = 0;
00935     for(int mu=0; mu < P_new.size(); mu++) { 
00936       const unsigned char *p1 = (const unsigned char *)Q_new[mu].getF();
00937       const unsigned char *p2 = (const unsigned char *)Q_old[mu].getF();
00938       for(int b=0; b < bytes; b++) {
00939         unsigned char diff = *p1 - *p2; 
00940         if( diff != 0 ) diffs_found++;
00941         p1++; p2++;
00942       }
00943     }
00944     
00945     // Sum up the number of diffs found globally
00946     Internal::globalSum(diffs_found);
00947     
00948     if( diffs_found != 0 ) { 
00949       QDPIO::cout << "Found " << diffs_found << " different bytes in gauge repro check" << endl;
00950       return false;
00951     }
00952   
00953     if( ! toBool( seed_new == seed_old ) ) { 
00954       QDPIO::cout << "New and old RNG seeds do not match " << endl;
00955       return false;
00956     }
00957     
00958     return true;
00959   }
00960 
00961 }

Generated on Sun Nov 22 04:31:28 2009 for CHROMA by  doxygen 1.4.7