CHROMA
multi_syssolver_mdagm_cg_chrono_clover.h
Go to the documentation of this file.
1 // -*- C++ -*-
2 /*! \file
3  * \brief Solve a MdagM*psi=chi linear system by CG2 using CG
4  */
5 
6 #ifndef __multi_syssolver_mdagm_cg_chrono_clover_h__
7 #define __multi_syssolver_mdagm_cg_chrono_clover_h__
8 
9 #include "handle.h"
10 #include "syssolver.h"
11 #include "linearop.h"
16 #include "init/chroma_init.h"
21 #include "lmdagm.h"
22 
23 namespace Chroma
24 {
25 
26  //! CG2 system solver namespace
27  namespace MdagMMultiSysSolverCGChronoCloverEnv
28  {
29  //! Register the syssolver
30  bool registerAll();
31  }
32 
34  MultiSysSolverCGChronoCloverParams(XMLReader& xml, const std::string& path);
37  clovParams = p.clovParams;
38  MaxIter = p.MaxIter;
39  MaxChrono = p.MaxChrono;
40  Delta = p.Delta;
41  CutoffRsd = p.CutoffRsd;
42  RsdTarget = p.RsdTarget; // Array Copy
43  }
45  int MaxIter;
46  int MaxChrono;
47 
48  Real Delta;
49  Real CutoffRsd;
50  multi1d<Real> RsdTarget;
51 
52  };
53 
54 #if 1
55  void read(XMLReader& xml, const std::string& path, MultiSysSolverCGChronoCloverParams& p);
56 
57  void write(XMLWriter& xml, const std::string& path,
59 #endif
60 
61  //! Solve a CG2 system. Here, the operator is NOT assumed to be hermitian
62  /*! \ingroup invert
63  */
65  {
66  public:
67  typedef LatticeFermion T;
68  typedef LatticeColorMatrix U;
69  typedef multi1d<LatticeColorMatrix> Q;
70  typedef multi1d<LatticeColorMatrix> P;
71 
72  typedef LatticeFermionF TF;
73  typedef LatticeColorMatrixF UF;
74  typedef multi1d<LatticeColorMatrixF> QF;
75  typedef multi1d<LatticeColorMatrixF> PF;
76 
77  typedef LatticeFermionD TD;
78  typedef LatticeColorMatrixD UD;
79  typedef multi1d<LatticeColorMatrixD> QD;
80  typedef multi1d<LatticeColorMatrixD> PD;
81 
82  //! Constructor
83  /*!
84  * \param M_ Linear operator ( Read )
85  * \param invParam inverter parameters ( Read )
86  */
88  Handle< FermState<T,P,Q> > state_,
89  const MultiSysSolverCGChronoCloverParams& invParam_) :
90  M(M_), invParam(invParam_)
91  {
92  QF links_single; links_single.resize(Nd);
93  QD links_double; links_double.resize(Nd);
94 
95  const Q& links = state_->getLinks();
96  for(int mu=0; mu < Nd; mu++) {
97  links_single[mu] = links[mu];
98  links_double[mu] = links[mu];
99  }
100 
101  // Links single hold the possibly stouted links
102  // with gaugeBCs applied...
103  // Now I need to create a single prec state...
104  fstate_single = new PeriodicFermState<TF,QF,QF>(links_single);
105  fstate_double = new PeriodicFermState<TD,QD,QD>(links_double);
106 
107  }
108 
109  //! Destructor is automatic
111 
112  //! Return the subset on which the operator acts
113  const Subset& subset() const {return M->subset();}
114 
115  //! Solver the linear system
116  /*!
117  * \param psi solution ( Modify )
118  * \param chi source ( Read )
119  * \return syssolver results
120  */
121  SystemSolverResults_t operator() (multi1d<T>& psi, const multi1d<Real>& shifts, const T& chi) const
122  {
123  START_CODE();
124  StopWatch swatch;
125  swatch.reset();
126  swatch.start();
128  res.n_count = 0;
129 
130  multi1d<Real> RsdCG(shifts.size());
131  if (invParam.RsdTarget.size() == 1) {
132  RsdCG = invParam.RsdTarget[0];
133  }
134  else if (invParam.RsdTarget.size() == RsdCG.size()) {
135 
137  }
138  else {
139 
140  QDPIO::cerr << "MdagMMultiSysSolverCGChronoClover: shifts incompatible" << std::endl;
141  QDP_abort(1);
142  }
143 
144 
145  // Setup residua to Single Prec CG Solver
146  multi1d<RealF> modRsdCG(shifts.size());
147  for(int i=0; i < shifts.size(); i++) {
148  if( toBool( RsdCG[i] < invParam.CutoffRsd ) ) {
149  modRsdCG[i] = invParam.CutoffRsd;
150  }
151  else {
152  modRsdCG[i] = RsdCG[i];
153  }
154  }
155 
156 
157 
158 
160  multi1d<TF> psi_f(shifts.size());
161  {
162 
163  TF chi_f;
164 
165  // Single Prec RHC
166  chi_f[M->subset()] = chi;
167  for(int i=0; i < shifts.size(); i++) {
168  psi_f[i][M->subset()] = zero;
169  }
170 
171  // Setup single prec shifts
172  multi1d<RealF> shifts_r(shifts.size());
173  for(int i=0; i < shifts.size(); i++ ) {
174  shifts_r[i] = shifts[i];
175  }
176 
177  MInvCG2(*M_single,
178  chi_f,
179  psi_f,
180  shifts_r,
181  modRsdCG,
183  res.n_count);
184 
185  }
186 
187 
188  psi.resize(shifts.size());
189 
191 
192  Handle<LinearOperator<TD> > MM( new MdagMLinOp<TD>(M_double));
193 
195 
196  chrono.reset();
197  TD chi_d; chi_d[M->subset()] = chi;
198  TD psi_d;
199  for(int i=shifts.size()-1; i >= 0; i--) {
200  RealD rshift = sqrt(shifts[i]);
201  RealF rshift_s = rshift;
202  RealD dshift = shifts[i];
203  SystemSolverResults_t res_tmp;
204  Handle< LinearOperator<TD> > Ms(new lopishift<TD,RealD>(M_double, rshift));
205  Handle< LinearOperator<TF> > Ms_single( new lopishift<TF,RealF>(M_single, rshift_s) );
206 
207 
208  psi_d[M->subset()] = psi_f[i];
209 
210  chrono.predictX(psi_d, dshift, chi_d);
211 
212  res_tmp= InvCGReliable(*(Ms),*(Ms_single), chi_d, psi_d, RsdCG[i],invParam.Delta, invParam.MaxIter);
213 
214  chrono.newXVector(psi_d);
215  psi[i][M->subset()] = psi_d;
216  QDPIO::cout << "n_count = " << res_tmp.n_count << std::endl;
217  res.n_count += res_tmp.n_count;
218  }
219 
220 
221 #if 0
222  XMLFileWriter& log = Chroma::getXMLLogInstance();
223  push(log, "MultiCG");
224  write(log, "shifts", shifts);
225  write(log, "RsdCG", RsdCG);
226  write(log, "n_count", res.n_count);
227  Double chinorm=norm2(chi, M->subset());
228  multi1d<Double> r_rel(shifts.size());
229 
230  for(int i=0; i < shifts.size(); i++) {
231  T tmp1,tmp2;
232  (*M)(tmp1, psi[i], PLUS);
233  (*M)(tmp2, tmp1, MINUS); // tmp2 = A^\dagger A psi
234  tmp2[ M->subset() ] += shifts[i]* psi[i]; // tmp2 = ( A^\dagger A + shift_i ) psi
235  T r;
236  r[ M->subset() ] = chi - tmp2;
237  r_rel[i] = sqrt(norm2(r, M->subset())/chinorm );
238 #if 1
239  QDPIO::cout << "r[" <<i <<"] = " << r_rel[i] << std::endl;
240 #endif
241 
242  }
243  write(log, "ResidRel", r_rel);
244  pop(log);
245 #endif
246  swatch.stop();
247  double time = swatch.getTimeInSeconds();
248  QDPIO::cout << "MULTI_CG_CHRONO_CLOVER_SOLVER: " << res.n_count << " iterations. Rsd = " << res.resid << std::endl;
249  QDPIO::cout << "MULTI_CG_CHRONO_CLOVER_SOLVER: "<<time<< " sec" << std::endl;
250  END_CODE();
251 
252  return res;
253  }
254 
255 
256  private:
257  // Hide default constructor
259 
264 
265  };
266 
267 
268 } // End namespace
269 
270 #endif
271 
Initialization of Chroma.
Even-odd preconditioned Clover-Dirac operator.
Even-odd preconditioned Clover-Dirac operator.
Support class for fermion actions and linear operators.
Definition: state.h:94
Class for counted reference semantics.
Definition: handle.h:33
Linear Operator.
Definition: linearop.h:27
M^dag.M linear operator.
Definition: lmdagm.h:22
Solve a CG2 system. Here, the operator is NOT assumed to be hermitian.
const Subset & subset() const
Return the subset on which the operator acts.
SystemSolverResults_t operator()(multi1d< T > &psi, const multi1d< Real > &shifts, const T &chi) const
Solver the linear system.
MdagMMultiSysSolverCGChronoClover(Handle< LinearOperator< T > > M_, Handle< FermState< T, P, Q > > state_, const MultiSysSolverCGChronoCloverParams &invParam_)
Constructor.
Periodic version of FermState.
Parameters for Clover fermion action.
int mu
Definition: cool.cc:24
Even-odd preconditioned Clover fermion linear operator.
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 MInvCG2(const LinearOperator< LatticeFermionF > &M, const LatticeFermionF &chi, multi1d< LatticeFermionF > &psi, const multi1d< RealF > &shifts, const multi1d< RealF > &RsdCG, int MaxCG, int &n_count)
Definition: minvcg2.cc:376
SystemSolverResults_t InvCGReliable(const LinearOperator< LatticeFermionF > &A, const LatticeFermionF &chi, LatticeFermionF &psi, const Real &RsdCG, const Real &Delta, int MaxCG)
Bi-CG stabilized.
Definition: reliable_cg.cc:193
Class for counted reference semantics.
Linear Operators.
M^dag*M composition of a linear operator.
Nd
Definition: meslate.cc:74
Double tmp2
Definition: mesq.cc:30
Multishift Conjugate-Gradient algorithm for a Linear Operator.
Minimal residual predictor.
Disambiguator for multi-shift MdagM system solvers.
Asqtad Staggered-Dirac operator.
Definition: klein_gord.cc:10
const WilsonTypeFermAct< multi1d< LatticeFermion > > Handle< const ConnectState > const multi1d< Real > enum InvType invType const multi1d< Real > & RsdCG
Definition: pbg5p_w.cc:30
XMLFileWriter & getXMLLogInstance()
Get xml log instance.
Definition: chroma_init.cc:378
push(xml_out,"Condensates")
int i
Definition: pbg5p_w.cc:55
@ MINUS
Definition: chromabase.h:45
@ PLUS
Definition: chromabase.h:45
multi1d< LatticeFermion > chi(Ncb)
LatticeFermion psi
Definition: mespbg5p_w.cc:35
pop(xml_out)
START_CODE()
Double zero
Definition: invbicg.cc:106
FloatingPoint< double > Double
Definition: gtest.h:7351
::std::string string
Definition: gtest.h:1979
Periodic ferm state and a creator.
BiCGStab Solver with reliable updates.
Params for clover ferm acts.
SystemSolver disambiguator.
MultiSysSolverCGChronoCloverParams(const MultiSysSolverCGChronoCloverParams &p)
Holds return info from SystemSolver call.
Definition: syssolver.h:17
Linear system solvers.