CHROMA
inline_ritz_H_w.cc
Go to the documentation of this file.
1 /*! \file
2  * \brief Inline construction of eigenvalues (Ritz)
3  *
4  * Eigenvalue calculations
5  */
6 
7 #include "fermact.h"
12 #include "meas/glue/mesplq.h"
13 #include "util/ft/sftmom.h"
14 #include "util/info/proginfo.h"
15 #include "util/info/unique_id.h"
16 #include "util/ferm/eigeninfo.h"
19 #include "meas/eig/eig_spec.h"
21 #include "io/eigen_io.h"
22 #include "io/xml_group_reader.h"
23 
24 
25 namespace Chroma
26 {
27  //! Eigeninfo input
28  void read(XMLReader& xml, const std::string& path, InlineRitzEnv::Params::Param_t& input)
29  {
30  XMLReader inputtop(xml, path);
31 
32  read(inputtop, "version", input.version);
33  input.fermact = readXMLGroup(inputtop, "FermionAction", "FermAct");
34  read(inputtop, "RitzParams", input.ritz_params);
35 
36  }
37 
38  //! Eigeninfo output
39  void write(XMLWriter& xml, const std::string& path, const InlineRitzEnv::Params::Param_t& input)
40  {
41  push(xml, path);
42 
43  write(xml, "version", input.version);
44  xml << input.fermact.xml;
45  write(xml, "RitzParams", input.ritz_params);
46 
47  pop(xml);
48  }
49 
50 
51  //! Eigeninfo input
52  void read(XMLReader& xml, const std::string& path, InlineRitzEnv::Params::NamedObject_t& input)
53  {
54  XMLReader inputtop(xml, path);
55 
56  read(inputtop, "gauge_id", input.gauge_id);
57  read(inputtop, "eigen_id", input.eigen_id);
58  }
59 
60  //! Eigeninfo output
61  void write(XMLWriter& xml, const std::string& path, const InlineRitzEnv::Params::NamedObject_t& input)
62  {
63  push(xml, path);
64 
65  write(xml, "gauge_id", input.gauge_id);
66  write(xml, "eigen_id", input.eigen_id);
67 
68  pop(xml);
69  }
70 
71 
72  namespace InlineRitzEnv
73  {
74  namespace
75  {
76  AbsInlineMeasurement* createMeasurement(XMLReader& xml_in,
77  const std::string& path)
78  {
79  return new InlineMeas(Params(xml_in, path));
80  }
81 
82  //! Local registration flag
83  bool registered = false;
84  }
85 
86  const std::string name = "RITZ_KS_HERM_WILSON";
87 
88  //! Register all the factories
89  bool registerAll()
90  {
91  bool success = true;
92  if (! registered)
93  {
95  success &= TheInlineMeasurementFactory::Instance().registerObject(name, createMeasurement);
96  registered = true;
97  }
98  return success;
99  }
100 
101 
102  // Param stuff
104  {
105  frequency = 0;
106  }
107 
108  Params::Params(XMLReader& xml_in, const std::string& path)
109  {
110  try
111  {
112  XMLReader inputtop(xml_in, path);
113 
114  if (inputtop.count("Frequency") == 1)
115  read(inputtop, "Frequency", frequency);
116  else
117  frequency = 1;
118 
119  // Parameters for source construction
120  read(inputtop, "Param", param);
121 
122  // Read any auxiliary state information
123  if( inputtop.count("Param/StateInfo") == 1 ) {
124  XMLReader xml_state_info(inputtop, "Param/StateInfo");
125  std::ostringstream os;
126  xml_state_info.print(os);
127  stateInfo = os.str();
128  }
129  else {
130  XMLBufferWriter s_i_xml;
131  push(s_i_xml, "StateInfo");
132  pop(s_i_xml);
133  stateInfo = s_i_xml.printCurrentContext();
134  }
135 
136  // Read in the output propagator/source configuration info
137  read(inputtop, "NamedObject", named_obj);
138 
139  // Possible alternate XML file pattern
140  if (inputtop.count("xml_file") != 0)
141  {
142  read(inputtop, "xml_file", xml_file);
143  }
144  }
145  catch(const std::string& e)
146  {
147  QDPIO::cerr << __func__ << ": Caught Exception reading XML: " << e << std::endl;
148  QDP_abort(1);
149  }
150  }
151 
152 
153  void
154  Params::writeXML(XMLWriter& xml_out, const std::string& path)
155  {
156  push(xml_out, path);
157 
158  write(xml_out, "Frequency", frequency);
159  write(xml_out, "Param", param);
160  {
161  //QDP::write(xml_out, "StateInfo", stateInfo);
162  std::istringstream header_is(stateInfo);
163  XMLReader xml_header(header_is);
164  xml_out << xml_header;
165  }
166  write(xml_out, "NamedObject", named_obj);
167 
168  pop(xml_out); // Path
169  }
170 
171 
174  const RitzParams_t& params,
175  XMLWriter& xml_out,
176  EigenInfo<LatticeFermion>& eigenvec_val);
177 
178 
179  // Function call
180  void
181  InlineMeas::operator()(unsigned long update_no,
182  XMLWriter& xml_out)
183  {
184  // If xml file not empty, then use alternate
185  if (params.xml_file != "")
186  {
187  std::string xml_file = makeXMLFileName(params.xml_file, update_no);
188 
189 
190  push(xml_out, "RitzEigenHw");
191  write(xml_out, "update_no", update_no);
192  write(xml_out, "xml_file", xml_file);
193  pop(xml_out);
194 
195  XMLFileWriter xml(xml_file);
196  func(update_no, xml);
197  }
198  else
199  {
200  func(update_no, xml_out);
201  }
202  }
203 
204 
205  // Real work done here
206  void
207  InlineMeas::func(unsigned long update_no,
208  XMLWriter& xml_out)
209  {
210  START_CODE();
211 
212  QDP::StopWatch snoop;
213  snoop.reset();
214  snoop.start();
215 
216  // Grab the gauge field
217  XMLBufferWriter gauge_xml;
218  multi1d<LatticeColorMatrix> u =
219  TheNamedObjMap::Instance().getData< multi1d<LatticeColorMatrix> >(params.named_obj.gauge_id);
220  TheNamedObjMap::Instance().get(params.named_obj.gauge_id).getRecordXML(gauge_xml);
221 
222  push(xml_out, "RitzEigenHw");
223  write(xml_out, "update_no", update_no);
224 
225  QDPIO::cout << InlineRitzEnv::name << ": RitzEigenHw" << std::endl;
226 
227  proginfo(xml_out); // Print out basic program info
228 
229  // Write out the input
230  params.writeXML(xml_out, "Input");
231 
232  XMLBufferWriter record_xml;
233  params.writeXML(record_xml, "RecordXML");
234 
235  // Write out the config header
236  write(xml_out, "Config_info", gauge_xml);
237 
238  push(xml_out, "Output_version");
239  write(xml_out, "out_version", 1);
240  pop(xml_out);
241 
242  // Calculate some gauge invariant observables just for info.
243  MesPlq(xml_out, "Observables", u);
244 
245 
247  EigenInfo<LatticeFermion>& eigenvec_val =
249 
250 
251  // File XML - the name of the measurement and and ID
252  XMLBufferWriter file_xml;
253  push(file_xml, "RitzEigenHw");
254  write(file_xml, "id", uniqueId()); // NOTE: new ID form
255  pop(file_xml);
256 
257 
258  TheNamedObjMap::Instance().get(params.named_obj.eigen_id).setFileXML(file_xml);
259  TheNamedObjMap::Instance().get(params.named_obj.eigen_id).setRecordXML(record_xml);
260  //
261  // Initialize fermion action
262  //
263  std::istringstream xml_s(params.param.fermact.xml);
264  XMLReader fermacttop(xml_s);
265 
266  // Make a reader for the stateInfo
267  std::istringstream state_info_is(params.stateInfo);
268  XMLReader state_info_xml(state_info_is);
269  std::string state_info_path="/StateInfo";
270 
271  bool success = false;
272 
273  if (! success)
274  {
275 
276  try {
277  StopWatch swatch;
278  swatch.reset();
279  QDPIO::cout << "Try the various factories" << std::endl;
280 
281  // Typedefs to save typing
282  typedef LatticeFermion T;
283  typedef multi1d<LatticeColorMatrix> P;
284  typedef multi1d<LatticeColorMatrix> Q;
285 
288  fermacttop,
290 
291  Handle< FermState<T,P,Q> > state(S_f->createState(u,
292  state_info_xml,
293  state_info_path));
294 
296 
297  Handle< LinearOperator<LatticeFermion> > H(S_f->hermitianLinOp(state));
298  swatch.start();
299  RitzCode4DHw(MM, H, params.param.ritz_params, xml_out, eigenvec_val);
300  swatch.stop();
301  QDPIO::cout << "Eigenvalues/-vectors computed: time= "
302  << swatch.getTimeInSeconds()
303  << " secs" << std::endl;
304 
305  success = true;
306  }
307 
308  catch (const std::string& e)
309  {
310  QDPIO::cout << InlineRitzEnv::name << ": caught exception around quarkprop: " << e << std::endl;
311  }
312  }
313 
314  if (! success)
315  {
316  QDPIO::cerr << "Error: no fermact found" << std::endl;
317  QDP_abort(1);
318  }
319 
320  snoop.stop();
321  QDPIO::cout << InlineRitzEnv::name << ": total time = "
322  << snoop.getTimeInSeconds()
323  << " secs" << std::endl;
324 
325  QDPIO::cout << InlineRitzEnv::name << ": ran successfully" << std::endl;
326 
327  pop(xml_out);
328 
329  END_CODE();
330  }
331 
332 
333 
336  const RitzParams_t& params,
337  XMLWriter& xml_out,
338  EigenInfo<LatticeFermion>& eigenvec_val)
339  {
340 
341  // Try and get lowest eigenvalue of MM
342  const Subset& s = MM->subset();
343 
344  multi1d<Real> lambda(params.Neig+params.Ndummy);
345  multi1d<Real> check_norm(params.Neig);
346  multi1d<LatticeFermion> psi(params.Neig
347  +params.Ndummy);
348 
349 
350  for(int i =0; i < params.Neig + params.Ndummy; i++){
351  psi[i] = zero;
352  gaussian(psi[i],s);
353  lambda[i] = Real(1);
354  }
355 
356 
357  int n_CG_count;
358  Real delta_cycle = Real(1);
359  XMLBufferWriter eig_spec_xml;
360  int n_KS_count = 0;
361  int n_jacob_count = 0;
362  EigSpecRitzKS(*MM,
363  lambda,
364  psi,
365  params.Neig,
366  params.Ndummy, // No of dummies
367  params.Nrenorm,
368  params.MinKSIter,
369  params.MaxKSIter, // Max iters / KS cycle
370  params.MaxKS, // Max no of KS cycles
371  params.GammaFactor, // Gamma factor
372  params.MaxCG,
373  params.RsdR,
374  params.RsdA,
375  params.RsdZero,
376  params.ProjApsiP,
377  n_CG_count,
378  n_KS_count,
379  n_jacob_count,
380  eig_spec_xml);
381 
382  // Dump output
383  xml_out << eig_spec_xml;
384  write(xml_out, "lambda_Msq", lambda);
385 
386  // Check norms
387  for(int i=0; i < params.Neig; i++) {
388  LatticeFermion Me;
389  LatticeFermion lambda_e;
390  (*MM)(Me, psi[i], PLUS);
391  lambda_e[s] = lambda[i]*psi[i];
392 
393 
394  LatticeFermion r_norm;
395  r_norm[s] = Me - lambda_e;
396 
397  check_norm[i] = norm2(r_norm,s);
398  check_norm[i] = sqrt(check_norm[i]);
399  }
400  write(xml_out, "check_norm", check_norm);
401 
402  for(int i=0; i < params.Neig; i++) {
403  check_norm[i] /= fabs(lambda[i]);
404  }
405  write(xml_out, "check_norm_rel", check_norm);
406 
407  // Fix to ev-s of gamma_5 wilson...
408  // Try to get one:
409  multi1d<bool> valid_eig(params.Neig);
410  int n_valid;
411  int n_jacob;
412 
413  fixMMev2Mev(*H,
414  lambda,
415  psi,
416  params.Neig,
417  params.RsdR,
418  params.RsdA,
419  params.RsdZero,
420  valid_eig,
421  n_valid,
422  n_jacob);
423 
424  push(xml_out, "eigFix");
425  write(xml_out, "lambda_Hw", lambda);
426  write(xml_out, "n_valid", n_valid);
427  write(xml_out, "valid_eig", valid_eig);
428 
429  for(int i=0; i < params.Neig; i++) {
430  LatticeFermion Me;
431  (*H)(Me, psi[i], PLUS);
432 
433  bool zeroP = toBool( fabs(lambda[i]) < params.RsdZero );
434  if( zeroP ) {
435  check_norm[i] = norm2(Me,s);
436  check_norm[i] = sqrt(check_norm[i]);
437  }
438  else {
439  LatticeFermion lambda_e;
440  LatticeFermion r_norm;
441 
442  lambda_e[s] = lambda[i]*psi[i];
443  r_norm[s] = Me - lambda_e;
444 
445 
446  check_norm[i] = norm2(r_norm,s);
447  check_norm[i] = sqrt(check_norm[i]);
448  }
449 
450  QDPIO::cout << "lambda_lo[" << i << "] = " << lambda[i] << " ";
451  QDPIO::cout << "check_norm["<<i<<"] = " << check_norm[i] << std::endl;
452  }
453  write(xml_out, "check_norm", check_norm);
454 
455  for(int i=0; i < params.Neig; i++) {
456  check_norm[i] /= fabs(lambda[i]);
457  QDPIO::cout << "check_norm_rel["<< i <<"] = " << check_norm[i] << std::endl;
458  }
459  QDPIO::cout << std::flush ;
460  write(xml_out, "check_norm_rel", check_norm);
461  pop(xml_out);
462 
463 
464  // Now get the absolute value of the highest e-value
465  // Work with H^{dag}H = M^{dag}M
466  Real hi_RsdR = 1.0e-4;
467  Real hi_RsdA = 1.0e-4;
468 
469  multi1d<Real> lambda_high_aux(1);
470  multi1d<LatticeFermion> lambda_high_vec(1);
471 
472  gaussian(lambda_high_vec[0],s);
473 
474  lambda_high_vec[0][s] /= sqrt(norm2(lambda_high_vec[0],s));
475 
476  int n_cg_high;
477  XMLBufferWriter high_xml;
478 
480  // Initial guess -- upper bound on spectrum
481  lambda_high_aux[0] = Real(8);
482 
483 
484  push(high_xml, "LambdaHighRitz");
485 
486  // Minus MM ought to produce a negative e-value
487  // since MM is herm_pos_def
488  // ie minus MM is hermitian -ve definite
489 
490  EigSpecRitzCG( *MinusMM,
491  lambda_high_aux,
492  lambda_high_vec,
493  1,
494  params.Nrenorm,
495  params.MinKSIter,
496  params.MaxCG,
497  hi_RsdR,
498  hi_RsdA,
499  params.RsdZero,
500  params.ProjApsiP,
501  n_cg_high,
502  high_xml);
503 
504  QDPIO::cout << "Got Here" << std::endl << std::flush ;
505 
506  lambda_high_aux[0] = sqrt(fabs(lambda_high_aux[0]));
507  QDPIO::cout << "|| lambda_hi || = " << lambda_high_aux[0] << " hi_Rsd_r = " << hi_RsdR << std::endl;
508 
509  pop(high_xml);
510  xml_out << high_xml;
511 
512  push(xml_out, "Highest");
513  write(xml_out, "lambda_hi", lambda_high_aux[0]);
514  pop(xml_out);
515 
516  eigenvec_val.getEvalues().resize(params.Neig);
517  eigenvec_val.getEvectors().resize(params.Neig);
518  for (int i=0; i<params.Neig; i++)
519  eigenvec_val.getEvalues()[i]=lambda[i];
520  eigenvec_val.getLargest()=lambda_high_aux[0];
521  for (int i=0; i<params.Neig; i++)
522  eigenvec_val.getEvectors()[i]=psi[i];
523 
524 
525 // QDPIO::cout << "Writing low eigenvalues/vectors" << std::endl;
526 // writeEigen(input, lambda, psi, lambda_high_aux[0], QDPIO_SERIAL);
527 
528  }
529 
530  } // namespace InlineRitzEnv
531 
532 } // namespace Chroma
Inline measurement factory.
Hold eigenvalues and eigenvectors.
Definition: eigeninfo.h:19
const Real & getLargest() const
Getter.
Definition: eigeninfo.h:50
const multi1d< T > & getEvectors() const
Getter.
Definition: eigeninfo.h:55
const multi1d< Real > & getEvalues() const
Getter.
Definition: eigeninfo.h:45
Class for counted reference semantics.
Definition: handle.h:33
Inline measurement of eigenvalues.
void func(const unsigned long update_no, XMLWriter &xml_out)
Do the measurement.
void operator()(const unsigned long update_no, XMLWriter &xml_out)
Do the measurement.
static T & Instance()
Definition: singleton.h:432
Scaled Linear Operator.
Definition: lopscl.h:22
Eigenvalue IO.
Hold eigenvalues and eigenvectors.
Class structure for fermion actions.
Fermion action factories.
All Wilson-type fermion actions.
void EigSpecRitzCG(const LinearOperator< LatticeFermion > &M, multi1d< Real > &lambda_H, multi1d< LatticeFermion > &psi, int n_eig, int n_renorm, int n_min, int MaxCG, const Real &Rsd_r, const Real &Rsd_a, const Real &zero_cutoff, const bool ProjApsiP, int &n_cg_tot, XMLWriter &xml_out)
Compute low lying eigenvalues of the hermitian H.
Definition: eig_spec.cc:41
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.
std::string uniqueId()
Return a unique id.
Definition: unique_id.cc:18
void proginfo(XMLWriter &xml)
Print out basic information about this program.
Definition: proginfo.cc:24
std::string makeXMLFileName(std::string xml_file, unsigned long update_no)
Return a xml file name for inline measurements.
GroupXML_t readXMLGroup(XMLReader &xml_in, const std::string &path, const std::string &type_name)
Read group and return as a std::string.
Params params
Inline construction of eigenvalues (Ritz)
Make xml file writer.
Named object function std::map.
static bool registered
Local registration flag.
multi1d< LatticeColorMatrix > P
bool registerAll()
Register all the factories.
const std::string name
void RitzCode4DHw(Handle< LinearOperator< LatticeFermion > > &MM, Handle< LinearOperator< LatticeFermion > > &H, const RitzParams_t &params, XMLWriter &xml_out, EigenInfo< LatticeFermion > &eigenvec_val)
bool registerAll()
Register all the factories.
Asqtad Staggered-Dirac operator.
Definition: klein_gord.cc:10
gaussian(aux)
void fixMMev2Mev(const LinearOperator< LatticeFermion > &M, multi1d< Real > &lambda, multi1d< LatticeFermion > &ev_psi, const int n_eig, const Real &Rsd_r, const Real &Rsd_a, const Real &zero_cutoff, multi1d< bool > &valid_eig, int &n_valid, int &n_jacob)
Definition: eig_spec.cc:321
void EigSpecRitzKS(const LinearOperator< LatticeFermion > &M, multi1d< Real > &lambda_H, multi1d< LatticeFermion > &psi, int n_eig, int n_dummy, int n_renorm, int n_min, int n_max, int n_max_KS, const Real &gamma_factor, int MaxCG, const Real &Rsd_r, const Real &Rsd_a, const Real &zero_cutoff, const bool ProjApsiP, int &n_cg_tot, int &n_KS, int &n_jacob_tot, XMLWriter &xml_out)
Definition: eig_spec.cc:124
static multi1d< LatticeColorMatrix > u
LinOpSysSolverMGProtoClover::Q Q
push(xml_out,"Condensates")
LinOpSysSolverMGProtoClover::T T
int i
Definition: pbg5p_w.cc:55
@ PLUS
Definition: chromabase.h:45
LatticeFermion psi
Definition: mespbg5p_w.cc:35
pop(xml_out)
void MesPlq(const multi1d< LatticeColorMatrixF3 > &u, multi2d< Double > &plane_plaq, Double &link)
Definition: mesplq.cc:83
START_CODE()
const WilsonTypeFermAct< multi1d< LatticeFermion > > Handle< const ConnectState > state
Definition: pbg5p_w.cc:28
const WilsonTypeFermAct< multi1d< LatticeFermion > > & S_f
Definition: pbg5p_w.cc:27
Double zero
Definition: invbicg.cc:106
multi1d< LatticeFermion > s(Ncb)
::std::string string
Definition: gtest.h:1979
Double r_norm
Definition: pade_trln_w.cc:86
Print out basic info about this program.
Fourier transform phase factor support.
struct Chroma::InlineRitzEnv::Params::Param_t param
void writeXML(XMLWriter &xml_out, const std::string &path)
struct Chroma::InlineRitzEnv::Params::NamedObject_t named_obj
Struct for parameters needed for a Ritz KS type solve.
Definition: eigen_io.h:22
Generate a unique id.
Read an XML group as a std::string.