CHROMA
eoprec_dwf_qprop_array_cg_dwf_w.h
Go to the documentation of this file.
1 // -*- C++ -*-
2 /*! \file
3  * \brief 4D style even-odd preconditioned domain-wall fermion action
4  */
5 
6 #include "chroma_config.h"
7 
8 #ifndef CHROMA_USE_CG_DWF_LOWMEM
9 
10 #ifndef __prec_dwf_qprop_array_cg_dwf_w_h__
11 #define __prec_dwf_qprop_array_cg_dwf_w_h__
12 
14 #include "io/aniso_io.h"
16 
17 
18 namespace Chroma
19 {
20 
21  //! SSE Propagator DWF qpropT
22  /*! \ingroup qprop
23  *
24  * Propagator solver for DWF fermions
25  */
26  template< typename SinglePrecSolver, typename DoublePrecSolver >
27  class CGDWFQpropT : public SystemSolverArray<LatticeFermion>
28  {
29  public:
30  // Typedefs to save typing
31  typedef LatticeFermion T;
32  typedef multi1d<LatticeColorMatrix> P;
33  typedef multi1d<LatticeColorMatrix> Q;
34 
35 
36  //! Alternative constructor for compatibility
37  /*!
38  * \param m_q_ quark mass ( Read )
39  */
41  Handle< LinOpSystemSolverArray<T> > invA_, // throw away
42  Handle< FermState<T,P,Q> > state_,
43  const Real& OverMass_,
44  const Real& Mass_,
45  const AnisoParam_t& anisoParam_,
46  const GroupXML_t& invParam_) :
47  A(A_), OverMass(OverMass_), Mass(Mass_),
48  N5(A->size()), anisoParam(anisoParam_)
49  {init(state_, invParam_);}
50 
51  //! Need a real destructor
53 
54  //! Expected length of array index
55  int size() const {return N5;}
56 
57  //! Return the subset on which the operator acts
58  const Subset& subset() const {return all;}
59 
60  //! Solver the linear system
61  /*!
62  * \param psi quark propagator ( Modify )
63  * \param chi source ( Read )
64  * \return number of CG iterations
65  */
66  SystemSolverResults_t operator() (multi1d<LatticeFermion>& psi, const multi1d<LatticeFermion>& chi) const
67  {
68 
69  QDPIO::cout << "entering CGDWFQpropT::operator()" << std::endl;
70 
71  START_CODE();
72 
74 
75  // init(); // only needed because 2 qpropT might be active - SSE CG does not allow this
76 
77  Real ff = where(anisoParam.anisoP, anisoParam.nu / anisoParam.xi_0, Real(1));
78 
79  // Apply SSE inverter
80  Real a5 = 1;
81  double M5 = toDouble(1 + a5*(1 + (Nd-1)*ff - OverMass));
82  double m_f = toDouble(Mass);
83  double out_eps;
84  int single_count = 0;
85  int double_count = 0;
86  res.n_count = 0;
87 #ifdef SINGLE_PREC_SOLVER
88  {
89 
90  double rsd = toDouble(invParam.RsdCG);
91  double rsd_sq = rsd * rsd;
92  int max_iter = invParam.MaxCG;
93 
94  QDPIO::cout << "CGDWFQpropT: Beginning Single Precision Solve" << std::endl;
95  single_prec_solver.cgSolver(psi, M5, m_f,
96  chi, psi, rsd_sq, max_iter, out_eps, single_count);
97  res.n_count += single_count;
98  }
99 #endif
100 #ifdef DOUBLE_PREC_SOLVER
101  {
102  double rsd = toDouble(invParam.RsdCGRestart);
103  double rsd_sq = rsd * rsd;
104  int max_iter = invParam.MaxCGRestart;
105 
106  QDPIO::cout << "CGDWFQpropT: Beginning Double Precision Solve" << std::endl;
107  double_prec_solver.cgSolver(psi, M5, m_f,
108  chi, psi, rsd_sq, max_iter, out_eps, double_count);
109  res.n_count += double_count;
110  }
111 #endif
112  QDPIO::cout << "CGDWFQpropT: Single Prec. Iters = " << single_count << " Double Prec. Iters = " << double_count << " Total Iters = " << res.n_count << std::endl;
113 
114  // Compute actual residual
115  {
116  multi1d<LatticeFermion> r(N5);
117  A->unprecLinOp(r, psi, PLUS);
118  r -= chi;
119  res.resid = sqrt(norm2(r));
120  }
121 
122  QDPIO::cout << "exiting CGDWFQpropT::operator()" << std::endl;
123 
124  END_CODE();
125 
126  return res;
127  }
128 
129  protected:
130  //! Private internal initializer
132  {
133  QDPIO::cout << "entering CGDWFQpropT::init" << std::endl;
134 
135  if (Nd != 4 || Nc != 3) {
136 
137  QDPIO::cerr << "CGDWFQpropT: only supports Nd=4 and Nc=3" << std::endl;
138  QDP_abort(1);
139 
140  }
141 
142  // Read the XML for the CG params
143  try {
144 
145  std::istringstream is(inv.xml);
146  XMLReader paramtop(is);
147 
148  read(paramtop, inv.path, invParam);
149  }
150  catch (const std::string& e) {
151 
152  QDPIO::cerr << "CGDWFQpropT: only support a CG inverter" << std::endl;
153  QDP_abort(1);
154  }
155 
156  multi1d<int> lattice_size(Nd+1);
157  lattice_size[Nd] = N5;
158  for(int i=0; i < Nd; ++i)
159  lattice_size[i] = Layout::lattSize()[i];
160 
161  if (N5 % 4 != 0) {
162 
163  QDPIO::cerr << "SSE qpropT only N5 that is multiple of 2" << std::endl;
164  QDP_abort(1);
165  }
166 
167 #ifdef SINGLE_PREC_SOLVER
168  std::string dwf_error_str = "single prec.";
169  int stat = single_prec_solver.init(lattice_size.slice(), NULL, NULL);
170  if ( stat != 0) {
171 
172  QDPIO::cerr << __func__ << ": error in SP solver init: " << dwf_error_str << " error code is " << stat << std::endl;
173  QDP_abort(1);
174  }
175 #endif
176 #ifdef DOUBLE_PREC_SOLVER
177  std::string dwf_error_str2 = "double prec.";
178  int stat2 = double_prec_solver.init(lattice_size.slice(), NULL, NULL);
179  if ( stat2 != 0) {
180 
181  QDPIO::cerr << __func__ << ": error in DP solver init: " << dwf_error_str2 << " error code is " << stat2 << std::endl;
182  QDP_abort(1);
183  }
184 #endif
185  // Transform the U fields
186  multi1d<LatticeColorMatrix> u = state->getLinks();
187 
188  if (anisoParam.anisoP) {
189 
190  Real ff = where(anisoParam.anisoP, anisoParam.nu / anisoParam.xi_0, Real(1));
191 
192  // Rescale the u fields by the anisotropy
193  for(int mu=0; mu < u.size(); ++mu) {
194 
195  if (mu != anisoParam.t_dir)
196  u[mu] *= ff;
197  }
198  }
199 
200  // Construct shifted gauge field
201  multi1d<LatticeColorMatrix> v(Nd);
202  for (int i = 0; i < Nd; i++)
203  v[i] = shift(u[i], -1, i); // as viewed from the destination
204 
205  StopWatch swatch;
206 #ifdef SINGLE_PREC_SOLVER
207 
208  swatch.reset(); swatch.start();
209  single_prec_solver.loadGauge(&u, &v);
210  swatch.stop();
211  QDPIO::cout << "Single Precision Gauge Field Import took: " << swatch.getTimeInSeconds() << " seconds " << std::endl;
212 #endif
213 #ifdef DOUBLE_PREC_SOLVER
214  swatch.reset(); swatch.start();
215  double_prec_solver.loadGauge(&u, &v);
216  swatch.stop();
217  QDPIO::cout << "Double Precision Gauge Field Import took: " << swatch.getTimeInSeconds() << " seconds " << std::endl;
218 #endif
219 
220  QDPIO::cout << "exiting CGDWFQpropT::init" << std::endl;
221  }
222 
223  //! Private internal destructor
224  void fini() {
225  QDPIO::cout << "CGDWFQpropT: calling destructor" << std::endl;
226 #ifdef SINGLE_PREC_SOLVER
227  single_prec_solver.deleteGauge();
228  single_prec_solver.fini();
229 #endif
230 
231 #ifdef DOUBLE_PREC_SOLVER
232  double_prec_solver.deleteGauge();
233  double_prec_solver.fini();
234 #endif
235  }
236 
237  private:
238 #ifdef SINGLE_PREC_SOLVER
239  SinglePrecSolver single_prec_solver;
240 #endif
241 
242 #ifdef DOUBLE_PREC_SOLVER
243  DoublePrecSolver double_prec_solver;
244 #endif
245 
247  Real OverMass;
248  Real Mass;
249  int N5;
252  };
253 
254 }
255 #endif
256 
257 #endif
Anisotropy parameters.
SSE Propagator DWF qpropT.
multi1d< LatticeColorMatrix > P
SystemSolverResults_t operator()(multi1d< LatticeFermion > &psi, const multi1d< LatticeFermion > &chi) const
Solver the linear system.
multi1d< LatticeColorMatrix > Q
void fini()
Private internal destructor.
int size() const
Expected length of array index.
const Subset & subset() const
Return the subset on which the operator acts.
CGDWFQpropT(Handle< EvenOddPrecConstDetLinearOperatorArray< T, P, Q > > A_, Handle< LinOpSystemSolverArray< T > > invA_, Handle< FermState< T, P, Q > > state_, const Real &OverMass_, const Real &Mass_, const AnisoParam_t &anisoParam_, const GroupXML_t &invParam_)
Alternative constructor for compatibility.
~CGDWFQpropT()
Need a real destructor.
void init(Handle< FermState< T, P, Q > > state, const GroupXML_t &inv)
Private internal initializer.
Handle< EvenOddPrecConstDetLinearOperatorArray< T, P, Q > > A
Even-odd preconditioned linear operator including derivatives for arrays.
Support class for fermion actions and linear operators.
Definition: state.h:94
Class for counted reference semantics.
Definition: handle.h:33
SystemSolver disambiguator.
Linear system solvers of arrays.
Definition: syssolver.h:62
int mu
Definition: cool.cc:24
Even-odd const determinant Wilson-like fermact.
void read(XMLReader &xml, const std::string &path, AsqtadFermActParams &param)
Read parameters.
Nd
Definition: meslate.cc:74
Asqtad Staggered-Dirac operator.
Definition: klein_gord.cc:10
static multi1d< LatticeColorMatrix > u
Real rsd_sq
Definition: invbicg.cc:121
int i
Definition: pbg5p_w.cc:55
@ PLUS
Definition: chromabase.h:45
multi1d< LatticeFermion > chi(Ncb)
LatticeFermion psi
Definition: mespbg5p_w.cc:35
START_CODE()
const WilsonTypeFermAct< multi1d< LatticeFermion > > Handle< const ConnectState > state
Definition: pbg5p_w.cc:28
::std::string string
Definition: gtest.h:1979
Parameters for anisotropy.
Definition: aniso_io.h:24
Hold group xml and type id.
Params for CG inverter.
Holds return info from SystemSolver call.
Definition: syssolver.h:17
Solve a CG1 system.