CHROMA
inline_prop_and_matelem_distillation_w.cc
Go to the documentation of this file.
1 /*! \file
2  * \brief Compute propagators from distillation
3  *
4  * Propagator calculation in distillation
5  */
6 
7 #include "qdp.h"
8 #include "fermact.h"
11 #include "meas/glue/mesplq.h"
12 #include "qdp_map_obj.h"
13 #include "qdp_map_obj_disk.h"
14 #include "qdp_map_obj_disk_multiple.h"
15 #include "qdp_map_obj_memory.h"
16 #include "qdp_disk_map_slice.h"
22 #include "util/ferm/key_val_db.h"
23 #include "util/ferm/transf.h"
24 #include "util/ferm/spin_rep.h"
25 #include "util/ferm/diractodr.h"
27 #include "util/ft/sftmom.h"
28 #include "util/ft/time_slice_set.h"
29 #include "util/info/proginfo.h"
30 #include "util/info/proginfo.h"
34 
36 
37 #include "chroma_config.h"
38 
39 #ifndef QDP_IS_QDPJIT_NO_NVPTX
40 
41 #ifdef BUILD_JIT_CONTRACTION_KERNELS
42 #include "custom_kernels/custom_kernels.h"
43 #endif
44 
45 namespace Chroma
46 {
47  //----------------------------------------------------------------------------
48  // Utilities
49  namespace
50  {
51  multi1d<SubsetVectorWeight_t> readEigVals(const std::string& meta)
52  {
53  std::istringstream xml_l(meta);
54  XMLReader eigtop(xml_l);
55 
56  std::string pat("/MODMetaData/Weights");
57  // multi1d<SubsetVectorWeight_t> eigenvalues;
58  multi1d< multi1d<Real> > eigens;
59  try
60  {
61  read(eigtop, pat, eigens);
62  }
63  catch(const std::string& e)
64  {
65  QDPIO::cerr << __func__ << ": Caught Exception reading meta= XX" << meta << "XX with path= " << pat << " error= " << e << std::endl;
66  QDP_abort(1);
67  }
68 
69  eigtop.close();
70 
71  multi1d<SubsetVectorWeight_t> eigenvalues(eigens.size());
72 
73  for(int i=0; i < eigens.size(); ++i)
74  eigenvalues[i].weights = eigens[i];
75 
76  return eigenvalues;
77  }
78  }
79 
80 
81  //----------------------------------------------------------------------------
82  namespace InlinePropAndMatElemDistillationEnv
83  {
84  //! Propagator input
85  void read(XMLReader& xml, const std::string& path, Params::NamedObject_t& input)
86  {
87  XMLReader inputtop(xml, path);
88 
89  read(inputtop, "gauge_id", input.gauge_id);
90  read(inputtop, "colorvec_files", input.colorvec_files);
91  read(inputtop, "prop_op_file", input.prop_op_file);
92  }
93 
94  //! Propagator output
95  void write(XMLWriter& xml, const std::string& path, const Params::NamedObject_t& input)
96  {
97  push(xml, path);
98 
99  write(xml, "gauge_id", input.gauge_id);
100  write(xml, "colorvec_files", input.colorvec_files);
101  write(xml, "prop_op_file", input.prop_op_file);
102 
103  pop(xml);
104  }
105 
106 
107  //! Propagator input
108  void read(XMLReader& xml, const std::string& path, Params::Param_t::Contract_t& input)
109  {
110  XMLReader inputtop(xml, path);
111 
112  read(inputtop, "num_vecs", input.num_vecs);
113  read(inputtop, "t_sources", input.t_sources);
114  read(inputtop, "decay_dir", input.decay_dir);
115  read(inputtop, "Nt_forward", input.Nt_forward);
116  read(inputtop, "Nt_backward", input.Nt_backward);
117  read(inputtop, "mass_label", input.mass_label);
118  read(inputtop, "num_tries", input.num_tries);
119 
120  input.zero_colorvecs = false;
121  if( inputtop.count("zero_colorvecs") == 1 ) {
122  read(inputtop, "zero_colorvecs", input.zero_colorvecs );
123  if (input.zero_colorvecs)
124  {
125  QDPIO::cout << "zero_colorvecs found, *** timing mode activated ***\n";
126  }
127  }
128 
129  input.fuse_timeloop = false;
130  if( inputtop.count("fuse_timeloop") == 1 ) {
131  read(inputtop, "fuse_timeloop", input.fuse_timeloop );
132  if (input.fuse_timeloop)
133  {
134  QDPIO::cout << "fuse_timeloop found!\n";
135  }
136  }
137 
138  }
139 
140  //! Propagator output
141  void write(XMLWriter& xml, const std::string& path, const Params::Param_t::Contract_t& input)
142  {
143  push(xml, path);
144 
145  write(xml, "num_vecs", input.num_vecs);
146  write(xml, "t_sources", input.t_sources);
147  write(xml, "decay_dir", input.decay_dir);
148  write(xml, "Nt_forward", input.Nt_forward);
149  write(xml, "Nt_backward", input.Nt_backward);
150  write(xml, "mass_label", input.mass_label);
151  write(xml, "num_tries", input.num_tries);
152 
153  pop(xml);
154  }
155 
156 
157  //! Propagator input
158  void read(XMLReader& xml, const std::string& path, Params::Param_t& input)
159  {
160  XMLReader inputtop(xml, path);
161 
162  read(inputtop, "Propagator", input.prop);
163  read(inputtop, "Contractions", input.contract);
164  }
165 
166  //! Propagator output
167  void write(XMLWriter& xml, const std::string& path, const Params::Param_t& input)
168  {
169  push(xml, path);
170 
171  write(xml, "Propagator", input.prop);
172  write(xml, "Contractions", input.contract);
173 
174  pop(xml);
175  }
176 
177 
178  //! Propagator input
179  void read(XMLReader& xml, const std::string& path, Params& input)
180  {
181  Params tmp(xml, path);
182  input = tmp;
183  }
184 
185  //! Propagator output
186  void write(XMLWriter& xml, const std::string& path, const Params& input)
187  {
188  push(xml, path);
189 
190  write(xml, "Param", input.param);
191  write(xml, "NamedObject", input.named_obj);
192 
193  pop(xml);
194  }
195  } // namespace InlinePropDistillationEnv
196 
197 
198  //----------------------------------------------------------------------------
199  //----------------------------------------------------------------------------
200  namespace InlinePropAndMatElemDistillationEnv
201  {
202  //----------------------------------------------------------------------------
203  // Convenience type
204  typedef QDP::MapObjectDisk<KeyTimeSliceColorVec_t, TimeSliceIO<LatticeColorVectorF> > MOD_t;
205 
206  // Convenience type
207  typedef QDP::MapObjectDiskMultiple<KeyTimeSliceColorVec_t, TimeSliceIO<LatticeColorVectorF> > MODS_t;
208 
209  // Convenience type
210  typedef QDP::MapObjectMemory<KeyTimeSliceColorVec_t, SubLatticeColorVectorF> SUB_MOD_t;
211 
212  // Anonymous namespace
213  namespace
214  {
215  //----------------------------------------------------------------------------
216  //! Class to hold std::map of eigenvectors
217  class SubEigenMap
218  {
219  public:
220  //! Constructor
221  SubEigenMap(MODS_t& eigen_source_, int decay_dir, bool zero_colorvecs) : eigen_source(eigen_source_), time_slice_set(decay_dir), zero_colorvecs(zero_colorvecs) {}
222 
223  //! Getter
224  const SubLatticeColorVectorF& getVec(int t_source, int colorvec_src) const;
225 
226  //! The set to be used in sumMulti
227  const Set& getSet() const {return time_slice_set.getSet();}
228 
229  private:
230  //! Eigenvectors
232 
233  // The time-slice set
235 
236  private:
237  //! Where we store the sublattice versions
240  };
241 
242  //----------------------------------------------------------------------------
243  //! Getter
244  const SubLatticeColorVectorF& SubEigenMap::getVec(int t_source, int colorvec_src) const
245  {
246  // The key
247  KeyTimeSliceColorVec_t src_key(t_source, colorvec_src);
248  // If item does not exist, read from original std::map and put in memory std::map
249  if (! sub_eigen.exist(src_key))
250  {
251  QDPIO::cout << __func__ << ": on t_source= " << t_source << " colorvec_src= " << colorvec_src << std::endl;
252 
253  // No need to initialize with 'zero' - we are returning a subtype.
254  LatticeColorVectorF vec_srce;
255 
256  if (!zero_colorvecs)
257  {
258  TimeSliceIO<LatticeColorVectorF> time_slice_io(vec_srce, t_source);
259  eigen_source.get(src_key, time_slice_io);
260  }
261 
262  SubLatticeColorVectorF tmp(getSet()[t_source], vec_srce);
263 
264  sub_eigen.insert(src_key, tmp);
265  }
266  return sub_eigen[src_key];
267  }
268 
269 
270  //----------------------------------------------------------------------------
271  //! Get active time-slices
272  std::vector<bool> getActiveTSlices(int t_source, int Nt_forward, int Nt_backward)
273  {
274  // Initialize the active time slices
275  const int decay_dir = Nd-1;
276  const int Lt = Layout::lattSize()[decay_dir];
277 
278  std::vector<bool> active_t_slices(Lt);
279  for(int t=0; t < Lt; ++t)
280  {
281  active_t_slices[t] = false;
282  }
283 
284  // Forward
285  for(int dt=0; dt < Nt_forward; ++dt)
286  {
287  int t = t_source + dt;
288  active_t_slices[t % Lt] = true;
289  }
290 
291  // Backward
292  for(int dt=0; dt < Nt_backward; ++dt)
293  {
294  int t = t_source - dt;
295  while (t < 0) {t += Lt;}
296 
297  active_t_slices[t % Lt] = true;
298  }
299 
300  return active_t_slices;
301  }
302 
303 
304  //----------------------------------------------------------------------------
305  //! Get sink keys
306  std::list<KeyPropElementalOperator_t> getSnkKeys(int t_source, int spin_source, int Nt_forward, int Nt_backward, const std::string mass)
307  {
308  std::list<KeyPropElementalOperator_t> keys;
309 
310  std::vector<bool> active_t_slices = getActiveTSlices(t_source, Nt_forward, Nt_backward);
311 
312  const int decay_dir = Nd-1;
313  const int Lt = Layout::lattSize()[decay_dir];
314 
315  for(int spin_sink=0; spin_sink < Ns; ++spin_sink)
316  {
317  for(int t=0; t < Lt; ++t)
318  {
319  if (! active_t_slices[t]) {continue;}
320 
322 
323  key.t_source = t_source;
324  key.t_slice = t;
325  key.spin_src = spin_source;
326  key.spin_snk = spin_sink;
327  key.mass_label = mass;
328 
329  keys.push_back(key);
330  } // for t
331  } // for spin_sink
332 
333  return keys;
334  }
335 
336  } // end anonymous
337  } // end namespace
338 
339 
340  //----------------------------------------------------------------------------
341  namespace InlinePropAndMatElemDistillationEnv
342  {
343  namespace
344  {
345  AbsInlineMeasurement* createMeasurement(XMLReader& xml_in,
346  const std::string& path)
347  {
348  return new InlineMeas(Params(xml_in, path));
349  }
350 
351  //! Local registration flag
352  bool registered = false;
353  }
354 
355  const std::string name = "PROP_AND_MATELEM_DISTILLATION";
356 
357  //! Register all the factories
358  bool registerAll()
359  {
360  bool success = true;
361  if (! registered)
362  {
364  success &= TheInlineMeasurementFactory::Instance().registerObject(name, createMeasurement);
365  registered = true;
366  }
367  return success;
368  }
369 
370 
371  //----------------------------------------------------------------------------
372  // Param stuff
374 
375  Params::Params(XMLReader& xml_in, const std::string& path)
376  {
377  try
378  {
379  XMLReader paramtop(xml_in, path);
380 
381  if (paramtop.count("Frequency") == 1)
382  read(paramtop, "Frequency", frequency);
383  else
384  frequency = 1;
385 
386  // Parameters for source construction
387  read(paramtop, "Param", param);
388 
389  // Read in the output propagator/source configuration info
390  read(paramtop, "NamedObject", named_obj);
391 
392  // Possible alternate XML file pattern
393  if (paramtop.count("xml_file") != 0)
394  {
395  read(paramtop, "xml_file", xml_file);
396  }
397  }
398  catch(const std::string& e)
399  {
400  QDPIO::cerr << __func__ << ": Caught Exception reading XML: " << e << std::endl;
401  QDP_abort(1);
402  }
403  }
404 
405 
406  //----------------------------------------------------------------------------
407  //----------------------------------------------------------------------------
408  // Function call
409  void
410  InlineMeas::operator()(unsigned long update_no,
411  XMLWriter& xml_out)
412  {
413  // If xml file not empty, then use alternate
414  if (params.xml_file != "")
415  {
416  std::string xml_file = makeXMLFileName(params.xml_file, update_no);
417 
418  push(xml_out, "PropDistillation");
419  write(xml_out, "update_no", update_no);
420  write(xml_out, "xml_file", xml_file);
421  pop(xml_out);
422 
423  XMLFileWriter xml(xml_file);
424  func(update_no, xml);
425  }
426  else
427  {
428  func(update_no, xml_out);
429  }
430  }
431 
432 
433  // Real work done here
434  void
435  InlineMeas::func(unsigned long update_no,
436  XMLWriter& xml_out)
437  {
438  START_CODE();
439 
440  StopWatch snoop;
441  snoop.reset();
442  snoop.start();
443 
444  // Test and grab a reference to the gauge field
445  multi1d<LatticeColorMatrix> u;
446  XMLBufferWriter gauge_xml;
447  try
448  {
449  u = TheNamedObjMap::Instance().getData< multi1d<LatticeColorMatrix> >(params.named_obj.gauge_id);
450  TheNamedObjMap::Instance().get(params.named_obj.gauge_id).getRecordXML(gauge_xml);
451  }
452  catch( std::bad_cast )
453  {
454  QDPIO::cerr << name << ": caught dynamic cast error" << std::endl;
455  QDP_abort(1);
456  }
457  catch (const std::string& e)
458  {
459  QDPIO::cerr << name << ": std::map call failed: " << e << std::endl;
460  QDP_abort(1);
461  }
462 
463  push(xml_out, "PropDistillation");
464  write(xml_out, "update_no", update_no);
465 
466  QDPIO::cout << name << ": propagator calculation" << std::endl;
467 
468  proginfo(xml_out); // Print out basic program info
469 
470  // Write out the input
471  write(xml_out, "Input", params);
472 
473  // Write out the config header
474  write(xml_out, "Config_info", gauge_xml);
475 
476  push(xml_out, "Output_version");
477  write(xml_out, "out_version", 1);
478  pop(xml_out);
479 
480  // Calculate some gauge invariant observables just for info.
481  MesPlq(xml_out, "Observables", u);
482 
483  // Will use TimeSliceSet-s a lot
484  const int decay_dir = params.param.contract.decay_dir;
485  const int Lt = Layout::lattSize()[decay_dir];
486 
487  // A sanity check
488  if (decay_dir != Nd-1)
489  {
490  QDPIO::cerr << name << ": TimeSliceIO only supports decay_dir= " << Nd-1 << "\n";
491  QDP_abort(1);
492  }
493 
494  // Reset
495  if (params.param.contract.num_tries <= 0)
496  {
498  }
499 
500 
501  //
502  // Read in the source along with relevant information.
503  //
504  QDPIO::cout << "Snarf the source from a std::map object disk file" << std::endl;
505 
507  eigen_source.setDebug(0);
508 
509  std::string eigen_meta_data; // holds the eigenvalues
510 
512  {
513  try
514  {
515  // Open
516  QDPIO::cout << "Open file= " << params.named_obj.colorvec_files[0] << std::endl;
518 
519  // Snarf the source info.
520  QDPIO::cout << "Get user data" << std::endl;
521  eigen_source.getUserdata(eigen_meta_data);
522  // QDPIO::cout << "User data= " << eigen_meta_data << std::endl;
523 
524  // Write it
525  // QDPIO::cout << "Write to an xml file" << std::endl;
526  // XMLBufferWriter xml_buf(eigen_meta_data);
527  // write(xml_out, "Source_info", xml_buf);
528  }
529  catch (std::bad_cast) {
530  QDPIO::cerr << name << ": caught dynamic cast error" << std::endl;
531  QDP_abort(1);
532  }
533  catch (const std::string& e) {
534  QDPIO::cerr << name << ": error extracting source_header: " << e << std::endl;
535  QDP_abort(1);
536  }
537  catch( const char* e) {
538  QDPIO::cerr << name <<": Caught some char* exception:" << std::endl;
539  QDPIO::cerr << e << std::endl;
540  QDPIO::cerr << "Rethrowing" << std::endl;
541  throw;
542  }
543 
544  QDPIO::cout << "Source successfully read and parsed" << std::endl;
545  }
546 
547 #if 0
548  // Sanity check
550  {
551  QDPIO::cerr << name << ": number of available eigenvectors is too small\n";
552  QDP_abort(1);
553  }
554 #endif
555 
556  QDPIO::cout << "Number of vecs available is large enough" << std::endl;
557 
558  // The sub-lattice eigenstd::vector std::map
559  QDPIO::cout << "Initialize sub-lattice std::map" << std::endl;
560  SubEigenMap sub_eigen_map(eigen_source, decay_dir, params.param.contract.zero_colorvecs);
561  QDPIO::cout << "Finished initializing sub-lattice std::map" << std::endl;
562 
563 
564  //
565  // DB storage
566  //
567  BinaryStoreDB< SerialDBKey<KeyPropElementalOperator_t>, SerialDBData<ValPropElementalOperator_t> > qdp_db;
568 
570  {
571  // Open the file, and write the meta-data and the binary for this operator
572  if (! qdp_db.fileExists(params.named_obj.prop_op_file))
573  {
574  XMLBufferWriter file_xml;
575  push(file_xml, "DBMetaData");
576  write(file_xml, "id", std::string("propElemOp"));
577  write(file_xml, "lattSize", QDP::Layout::lattSize());
578  write(file_xml, "decay_dir", params.param.contract.decay_dir);
579  proginfo(file_xml); // Print out basic program info
580  write(file_xml, "Params", params.param);
581  write(file_xml, "Config_info", gauge_xml);
583  write(file_xml, "Weights", readEigVals(eigen_meta_data));
584  pop(file_xml);
585 
586  std::string file_str(file_xml.str());
587  qdp_db.setMaxUserInfoLen(file_str.size());
588 
589  qdp_db.open(params.named_obj.prop_op_file, O_RDWR | O_CREAT, 0664);
590 
591  qdp_db.insertUserdata(file_str);
592  }
593  else
594  {
595  qdp_db.open(params.named_obj.prop_op_file, O_RDWR, 0664);
596  }
597 
598  QDPIO::cout << "Finished opening peram file" << std::endl;
599  }
600 
601  // Total number of iterations
602  int ncg_had = 0;
603 
604  //
605  // Try the factories
606  //
607  try
608  {
609  StopWatch swatch;
610  swatch.reset();
611  QDPIO::cout << "Try the various factories" << std::endl;
612 
613  // Typedefs to save typing
614  typedef LatticeFermion T;
615  typedef multi1d<LatticeColorMatrix> P;
616  typedef multi1d<LatticeColorMatrix> Q;
617 
618  //
619  // Initialize fermion action
620  //
621  std::istringstream xml_s(params.param.prop.fermact.xml);
622  XMLReader fermacttop(xml_s);
623  QDPIO::cout << "FermAct = " << params.param.prop.fermact.id << std::endl;
624 
625  // Generic Wilson-Type stuff
628  fermacttop,
630 
631  Handle< FermState<T,P,Q> > state(S_f->createState(u));
632 
635 
636  QDPIO::cout << "Suitable factory found: compute all the quark props" << std::endl;
637  swatch.start();
638 
639 #ifdef BUILD_JIT_CONTRACTION_KERNELS
641  QDPIO::cout << "Using JIT contraction kernels (fused timeloop)\n";
642  else
643  QDPIO::cout << "Using JIT contraction kernels (non-fused timeloop)\n";
644 #endif
645 
646  //
647  // Loop over the source color and spin, creating the source
648  // and calling the relevant propagator routines.
649  //
650  const int num_vecs = params.param.contract.num_vecs;
651  const multi1d<int>& t_sources = params.param.contract.t_sources;
652 
653 
654  // Loop over each time source
655  for(int tt=0; tt < t_sources.size(); ++tt)
656  {
657  int t_source = t_sources[tt]; // This is the actual time-slice.
658  QDPIO::cout << "t_source = " << t_source << std::endl;
659 
660  // Loop over each spin source
661  for(int spin_source=0; spin_source < Ns; ++spin_source)
662  {
663  QDPIO::cout << "spin_source = " << spin_source << std::endl;
664 
665  // These are the common parts of a perambulator that are needed for this time source
666  std::list<KeyPropElementalOperator_t> snk_keys(getSnkKeys(t_source,
667  spin_source,
671 
672  if (1) {
673  // The final perambulator
674  QDP::MapObjectMemory<KeyPropElementalOperator_t, ValPropElementalOperator_t> peram;
675 
676  // Initialize
677  for(std::list<KeyPropElementalOperator_t>::const_iterator key = snk_keys.begin();
678  key != snk_keys.end();
679  ++key)
680  {
681  // The perambulator value
683  peram.insert(*key, tmp);
684 
685  peram[*key].mat.resize(num_vecs,num_vecs);
686  peram[*key].mat = zero;
687  } // key
688  QDPIO::cout << "peram initialized! " << std::endl;
689 
690  //
691  // The space distillation loop
692  //
693  for(int colorvec_src=0; colorvec_src < num_vecs; ++colorvec_src)
694  {
695  StopWatch sniss1;
696  sniss1.reset();
697  sniss1.start();
698 
699  StopWatch snarss1;
700  snarss1.reset();
701  snarss1.start();
702  QDPIO::cout << "Do spin_source= " << spin_source << " colorvec_src= " << colorvec_src << std::endl;
703 
704  // Get the source std::vector
705  LatticeColorVector vec_srce = zero;
706 
708  {
709  vec_srce = sub_eigen_map.getVec(t_source, colorvec_src);
710  }
711 
712  //
713  // Loop over each spin source and invert.
714  // Use the same colorstd::vector source. No spin dilution will be used.
715  //
716  multi1d<LatticeColorVector> ferm_out(Ns);
717 
718  // Insert a ColorVector into spin index spin_source
719  // This only overwrites sections, so need to initialize first
720  LatticeFermion chi = zero;
721  CvToFerm(vec_srce, chi, spin_source);
722 
723  LatticeFermion quark_soln = zero;
724 
726  {
727  // Do the propagator inversion
728  // Check if bad things are happening
729  bool badP = true;
730  for(int nn = 1; nn <= params.param.contract.num_tries; ++nn)
731  {
732  // Reset
733  quark_soln = zero;
734  badP = false;
735 
736  // Solve for the solution std::vector
737  SystemSolverResults_t res = (*PP)(quark_soln, chi);
738 
739  ncg_had += res.n_count;
740 
741  // Some sanity checks
742  if (toDouble(res.resid) > 1.0e-3)
743  {
744  QDPIO::cerr << name << ": have a resid > 1.0e-3. That is unacceptable" << std::endl;
745  QDP_abort(1);
746  }
747 
748  // Check for finite values - neither NaN nor Inf
749  if (isfinite(quark_soln))
750  {
751  // Okay
752  break;
753  }
754  else
755  {
756  QDPIO::cerr << name << ": WARNING - found something not finite, may retry\n";
757  badP = true;
758  }
759  }
760 
761  // Sanity check
762  if (badP)
763  {
764  QDPIO::cerr << name << ": this is bad - did not get a finite solution std::vector after num_tries= "
765  << params.param.contract.num_tries << std::endl;
766  QDP_abort(1);
767  }
768  } // zero_colorvecs ??
769 
770  // Extract into the temporary output array
771  for(int spin_sink=0; spin_sink < Ns; ++spin_sink)
772  {
773  ferm_out(spin_sink) = peekSpin(quark_soln, spin_sink);
774  }
775 
776  snarss1.stop();
777  QDPIO::cout << "Time to compute prop for spin_source= " << spin_source << " colorvec_src= " << colorvec_src << " time = "
778  << snarss1.getTimeInSeconds()
779  << " secs" << std::endl;
780 
781  // The perambulator part
782  // Loop over time
783 
784 #ifndef BUILD_JIT_CONTRACTION_KERNELS
785  for(int t_slice = 0; t_slice < Lt; ++t_slice)
786  {
787  // Loop over all the keys
788  for(std::list<KeyPropElementalOperator_t>::const_iterator key= snk_keys.begin();
789  key != snk_keys.end();
790  ++key)
791  {
792  if (key->t_slice != t_slice) {continue;}
793 
794  // Loop over the sink colorvec, form the innerproduct and the resulting perambulator
795  for(int colorvec_sink=0; colorvec_sink < num_vecs; ++colorvec_sink)
796  {
797  peram[*key].mat(colorvec_sink,colorvec_src) = innerProduct(sub_eigen_map.getVec(t_slice, colorvec_sink),
798  ferm_out(key->spin_snk));
799  } // for colorvec_sink
800  } // for key
801  } // for t_slice
802 #else
804  {
805  //
806  // fused timeloop
807  //
808  for(int spin_snk = 0; spin_snk < Ns; ++spin_snk)
809  {
810  int count = 0;
811  for(std::list<KeyPropElementalOperator_t>::const_iterator key= snk_keys.begin(); key != snk_keys.end(); ++key)
812  {
813  if (key->spin_snk != spin_snk) { continue;}
814  count += num_vecs;
815  }
816 
817  //QDPIO::cout << "spin_snk = " << spin_snk << ", count = " << count << "\n";
818 
819  multi1d<SubLatticeColorVectorF*> vec_ptr( count );
820  multi1d<ComplexD*> contr_ptr( count );
821 
822  int run_count = 0;
823 
824  // Loop over all the keys
825  for(std::list<KeyPropElementalOperator_t>::const_iterator key= snk_keys.begin();
826  key != snk_keys.end();
827  ++key)
828  {
829  if (key->spin_snk != spin_snk) {continue;}
830 
831  //
832  // Pack pointers to the vectors and matrix elements
833  //
834  for (int i=0 ; i < num_vecs ; ++i ) {
835  vec_ptr[run_count] = const_cast<SubLatticeColorVectorF*>( &sub_eigen_map.getVec( key->t_slice , i ) );
836  contr_ptr[run_count] = &peram[*key].mat( i , colorvec_src );
837  ++run_count;
838  }
839  }
840 
841  //
842  // Big call-out
843  //
844  multi_innerProduct( contr_ptr , vec_ptr , ferm_out(spin_snk) );
845 
846  } // for spin_snk
847  }
848  else
849  {
850  //
851  // non-fused timeloop
852  //
853  for(int t_slice = 0; t_slice < Lt; ++t_slice)
854  {
855  // Loop over all the keys
856  for(std::list<KeyPropElementalOperator_t>::const_iterator key= snk_keys.begin();
857  key != snk_keys.end();
858  ++key)
859  {
860  if (key->t_slice != t_slice) {continue;}
861  //
862  // Pack pointers to the vectors and matrix elements
863  //
864  multi1d<SubLatticeColorVectorF*> vec_ptr( num_vecs );
865  multi1d<ComplexD*> contr_ptr( num_vecs );
866  for (int i=0 ; i < num_vecs ; ++i ) {
867  vec_ptr[i] = const_cast<SubLatticeColorVectorF*>( &sub_eigen_map.getVec( t_slice , i ) );
868  contr_ptr[i] = &peram[*key].mat( i , colorvec_src );
869  }
870 
871  //
872  // Big call-out
873  //
874  multi_innerProduct( contr_ptr , vec_ptr , ferm_out(key->spin_snk) );
875  } // for key
876  } // for t_slice
877  }
878 #endif
879 
880  sniss1.stop();
881  QDPIO::cout << "Time to compute and assemble peram for spin_source= " << spin_source << " colorvec_src= " << colorvec_src << " time = "
882  << sniss1.getTimeInSeconds()
883  << " secs"
884  << " (for contraction: " << sniss1.getTimeInSeconds() - snarss1.getTimeInSeconds() << ")"
885  << std::endl;
886 
887  } // for colorvec_src
888 
890  {
891  // Write out each time-slice chunk of a lattice colorvec soln to disk
892  QDPIO::cout << "Write perambulator for spin_source= " << spin_source << " to disk" << std::endl;
893  StopWatch sniss2;
894  sniss2.reset();
895  sniss2.start();
896 
897  // The perambulator is complete. Write it.
898  for(std::list<KeyPropElementalOperator_t>::const_iterator key= snk_keys.begin();
899  key != snk_keys.end();
900  ++key)
901  {
902  // Insert/write to disk
903  qdp_db.insert(*key, peram[*key]);
904 
905  } // for key
906 
907  sniss2.stop();
908  QDPIO::cout << "Time to write perambulators for spin_src= " << spin_source << " time = "
909  << sniss2.getTimeInSeconds()
910  << " secs" << std::endl;
911  }
912 
913  } // this ends the lifetime of qdp_db.
914  } // for spin_src
915  } // for tt
916 
917  swatch.stop();
918  QDPIO::cout << "Propagators computed: time= "
919  << swatch.getTimeInSeconds()
920  << " secs" << std::endl;
921  }
922  catch (const std::string& e)
923  {
924  QDPIO::cout << name << ": caught exception around qprop: " << e << std::endl;
925  QDP_abort(1);
926  }
927 
928  push(xml_out,"Relaxation_Iterations");
929  write(xml_out, "ncg_had", ncg_had);
930  pop(xml_out);
931 
932  pop(xml_out); // prop_dist
933 
934  snoop.stop();
935  QDPIO::cout << name << ": total time = "
936  << snoop.getTimeInSeconds()
937  << " secs" << std::endl;
938 
939  QDPIO::cout << name << ": ran successfully" << std::endl;
940 
941  END_CODE();
942  }
943 
944  }
945 
946 } // namespace Chroma
947 
948 #endif
Inline measurement factory.
Class for counted reference semantics.
Definition: handle.h:33
void operator()(const unsigned long update_no, XMLWriter &xml_out)
Do the measurement.
void func(const unsigned long update_no, XMLWriter &xml_out)
Do the measurement.
Serializable value harness.
Definition: key_val_db.h:69
static T & Instance()
Definition: singleton.h:432
Builds time slice subsets.
const Set & getSet() const
The set to be used in sumMulti.
EXTERN Real dt
Basis rotation matrix from Dirac to Degrand-Rossi (and reverse)
Class structure for fermion actions.
Fermion action factories.
All Wilson-type fermion actions.
void CvToFerm(const LatticeColorVectorF &a, LatticeFermionF &b, int spin_index)
Convert (insert) a LatticeColorVector into a LatticeFermion.
Definition: transf.cc:18
void read(XMLReader &xml, const std::string &path, AsqtadFermActParams &param)
Read parameters.
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.
MODS_t & eigen_source
Eigenvectors.
SUB_MOD_t sub_eigen
Where we store the sublattice versions.
Compute the propagator from distillation.
Key for propagator colorstd::vector sources.
Key for vanilla distillation propagator sources and solutions.
Key for propagator colorstd::vector matrix elements.
Key for time-sliced color eigenvectors.
Key and values for DB.
Make xml file writer.
int t
Definition: meslate.cc:37
int t_slice
Definition: meslate.cc:23
Nd
Definition: meslate.cc:74
Named object function std::map.
static bool registered
Local registration flag.
multi1d< LatticeColorMatrix > P
BinaryReturn< C1, C2, FnInnerProduct >::Type_t innerProduct(const QDPSubType< T1, C1 > &s1, const QDPType< T2, C2 > &s2)
QDP::MapObjectDiskMultiple< KeyTimeSliceColorVec_t, TimeSliceIO< LatticeColorVectorF > > MODS_t
QDP::MapObjectMemory< KeyTimeSliceColorVec_t, SubLatticeColorVectorF > SUB_MOD_t
void write(XMLWriter &xml, const std::string &path, const Params::NamedObject_t &input)
Propagator output.
void read(XMLReader &xml, const std::string &path, Params::NamedObject_t &input)
Propagator input.
QDP::MapObjectDisk< KeyTimeSliceColorVec_t, TimeSliceIO< LatticeColorVectorF > > MOD_t
bool registerAll()
Register all the factories.
Asqtad Staggered-Dirac operator.
Definition: klein_gord.cc:10
static multi1d< LatticeColorMatrix > u
LinOpSysSolverMGProtoClover::Q Q
LatticeFermion tmp
Definition: mespbg5p_w.cc:36
push(xml_out,"Condensates")
LinOpSysSolverMGProtoClover::T T
int i
Definition: pbg5p_w.cc:55
Double mass
Definition: pbg5p_w.cc:54
multi1d< LatticeFermion > chi(Ncb)
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
int count
Definition: octave.h:14
::std::string string
Definition: gtest.h:1979
Print out basic info about this program.
Fourier transform phase factor support.
Sparse matrix representation of spin matrices.
GroupXML_t invParam
Definition: qprop_io.h:84
GroupXML_t fermact
Definition: qprop_io.h:80
Holds return info from SystemSolver call.
Definition: syssolver.h:17
Holds of vectors and weights.
Convenience for building time-slice subsets.
Contraction operators for two quarks.