CHROMA
invmr.cc
Go to the documentation of this file.
1 /*! \file
2  * \brief Minimal-Residual (MR) for a generic fermion Linear Operator
3  */
4 
5 #include "chromabase.h"
7 
8 using namespace QDP::Hints;
9 
10 namespace Chroma
11 {
12 
13  //! Minimal-residual (MR) algorithm for a generic Linear Operator
14  /*! \ingroup invert
15  * This subroutine uses the Minimal Residual (MR) algorithm to determine
16  * the solution of the set of linear equations. Here we allow M to be nonhermitian.
17  *
18  * Chi = M . Psi
19  *
20  * Algorithm:
21  *
22  * Psi[0] Argument
23  * r[0] := Chi - M . Psi[0] ; Initial residual
24  * IF |r[0]| <= RsdCG |Chi| THEN RETURN; Converged?
25  * FOR k FROM 1 TO MaxCG DO MR iterations
26  * a[k-1] := <M.r[k-1],r[k-1]> / <M.r[k-1],M.r[k-1]> ;
27  * ap[k-1] := MRovpar * a[k] ; Overrelaxtion step
28  * Psi[k] += ap[k-1] r[k-1] ; New solution std::vector
29  * r[k] -= ap[k-1] A . r[k-1] ; New residual
30  * IF |r[k]| <= RsdCG |Chi| THEN RETURN; Converged?
31 
32  * Arguments:
33 
34  * \param M Linear Operator (Read)
35  * \param chi Source (Read)
36  * \param psi Solution (Modify)
37  * \param RsdCG MR residual accuracy (Read)
38  * \param MRovpar Overrelaxation parameter (Read)
39  * \param MaxMR Maximum MR iterations (Read)
40 
41  * Local Variables:
42 
43  * r Residual std::vector
44  * cp | r[k] |**2
45  * c | r[k-1] |**2
46  * k MR iteration counter
47  * a a[k]
48  * d < M.r[k], M.r[k] >
49  * R_Aux Temporary for M.Psi
50  * Mr Temporary for M.r
51 
52  * Global Variables:
53 
54  * MaxMR Maximum number of MR iterations allowed
55  * RsdCG Maximum acceptable MR residual (relative to source)
56  *
57  * Subroutines:
58  *
59  * M Apply matrix to std::vector
60  *
61  * @{
62  */
63 
64  template<typename T, typename C>
65  SystemSolverResults_t
66  InvMR_a(const C& M,
67  const T& chi,
68  T& psi,
69  const Real& MRovpar,
70  const Real& RsdMR,
71  int MaxMR,
72  enum PlusMinus isign)
73  {
74  START_CODE();
75 
76  const Subset& s = M.subset();
77 
79  moveToFastMemoryHint(psi,true);
80  T Mr; moveToFastMemoryHint(Mr);
81  T chi_internal; moveToFastMemoryHint(chi_internal);
82 
83  chi_internal[s] = chi;
84 
85  Complex a;
86  DComplex c;
87  Double d;
88  int k;
89 
90  QDPIO::cout << "InvMR: starting" << std::endl;
91  FlopCounter flopcount;
92  flopcount.reset();
93  StopWatch swatch;
94  swatch.reset();
95  swatch.start();
96 
97  Real rsd_sq = (RsdMR * RsdMR) * Real(norm2(chi_internal,s));
98  flopcount.addSiteFlops(4*Nc*Ns,s);
99 
100  /* r[0] := Chi - M . Psi[0] */
101  /* r := M . Psi */
102  M(Mr, psi, isign);
103  flopcount.addFlops(M.nFlops());
104 
105  T r; moveToFastMemoryHint(r);
106  r[s] = chi_internal - Mr;
107  flopcount.addSiteFlops(2*Nc*Ns,s);
108 
109  /* Cp = |r[0]|^2 */
110  Double cp = norm2(r, s); /* 2 Nc Ns flops */
111  flopcount.addSiteFlops(4*Nc*Ns, s);
112 
113 // QDPIO::cout << "InvMR: k = 0 cp = " << cp << " rsd_sq = " << rsd_sq << std::endl;
114 
115  /* IF |r[0]| <= RsdMR |Chi| THEN RETURN; */
116  if ( toBool(cp <= rsd_sq) )
117  {
118  res.n_count = 0;
119  res.resid = sqrt(cp);
120  swatch.stop();
121  flopcount.report("invMR", swatch.getTimeInSeconds());
122  revertFromFastMemoryHint(psi,true);
123  END_CODE();
124  return res;
125  }
126 
127  /* FOR k FROM 1 TO MaxMR DO */
128  k = 0;
129  while( (k < MaxMR) && (toBool(cp > rsd_sq)) )
130  {
131  ++k;
132 
133  /* a[k-1] := < M.r[k-1], r[k-1] >/ < M.r[k-1], M.r[k-1] > ; */
134  /* Mr = M * r */
135  M(Mr, r, isign); flopcount.addFlops(M.nFlops());
136 
137  /* c = < M.r, r > */
138  c = innerProduct(Mr, r, s); flopcount.addSiteFlops(4*Nc*Ns,s);
139 
140  /* d = | M.r | ** 2 */
141  d = norm2(Mr, s); flopcount.addSiteFlops(4*Nc*Ns,s);
142 
143  /* a = c / d */
144  a = c / d;
145 
146  /* a[k-1] *= MRovpar ; */
147  a = a * MRovpar;
148 
149  /* Psi[k] += a[k-1] r[k-1] ; */
150  psi[s] += r * a; flopcount.addSiteFlops(4*Nc*Ns,s);
151 
152  /* r[k] -= a[k-1] M . r[k-1] ; */
153  r[s] -= Mr * a; flopcount.addSiteFlops(4*Nc*Ns,s);
154 
155  /* cp = | r[k] |**2 */
156  cp = norm2(r, s); flopcount.addSiteFlops(4*Nc*Ns,s);
157 
158 // QDPIO::cout << "InvMR: k = " << k << " cp = " << cp << std::endl;
159  }
160  res.n_count = k;
161  res.resid = sqrt(cp);
162  swatch.stop();
163  QDPIO::cout << "InvMR: k = " << k << " cp = " << cp << std::endl;
164  flopcount.report("invmr", swatch.getTimeInSeconds());
165  revertFromFastMemoryHint(psi,true);
166 
167  // Compute the actual residual
168  {
169  M(Mr, psi, isign);
170  Double actual_res = norm2(chi_internal - Mr,s);
171  res.resid = sqrt(actual_res);
172  }
173 
174  if ( res.n_count == MaxMR )
175  QDPIO::cerr << "Nonconvergence Warning" << std::endl;
176 
177  END_CODE();
178  return res;
179  }
180 
181 
182  // Fix here for now
183  template<>
184  SystemSolverResults_t
186  const LatticeFermion& chi,
187  LatticeFermion& psi,
188  const Real& MRovpar,
189  const Real& RsdMR,
190  int MaxMR,
191  enum PlusMinus isign)
192  {
193  return InvMR_a(M, chi, psi, MRovpar, RsdMR, MaxMR, isign);
194  }
195 
196 
197  // Fix here for now
198  template<>
199  SystemSolverResults_t
201  const LatticeStaggeredFermion& chi,
202  LatticeStaggeredFermion& psi,
203  const Real& MRovpar,
204  const Real& RsdMR,
205  int MaxMR,
206  enum PlusMinus isign)
207  {
208  return InvMR_a(M, chi, psi, MRovpar, RsdMR, MaxMR, isign);
209  }
210 
211  /*! @} */ // end of group invert
212 
213 } // end namespace Chroma
Primary include file for CHROMA library code.
#define END_CODE()
Definition: chromabase.h:65
#define START_CODE()
Definition: chromabase.h:64
SystemSolverResults_t InvMR(const LinearOperator< LatticeStaggeredFermion > &M, const LatticeStaggeredFermion &chi, LatticeStaggeredFermion &psi, const Real &MRovpar, const Real &RsdMR, int MaxMR, enum PlusMinus isign)
Definition: invmr.cc:200
SystemSolverResults_t InvMR_a(const C &M, const T &chi, T &psi, const Real &MRovpar, const Real &RsdMR, int MaxMR, enum PlusMinus isign)
Minimal-residual (MR) algorithm for a generic Linear Operator.
Definition: invmr.cc:66
Minimal-Residual (MR) for a generic fermion Linear Operator.
unsigned s
Definition: ldumul_w.cc:37
int c
Definition: meslate.cc:61
SpinMatrix C()
C = Gamma(10)
Definition: barspinmat_w.cc:29
BinaryReturn< C1, C2, FnInnerProduct >::Type_t innerProduct(const QDPSubType< T1, C1 > &s1, const QDPType< T2, C2 > &s2)
Asqtad Staggered-Dirac operator.
Definition: klein_gord.cc:10
LinOpSysSolverMGProtoClover::T T
Real rsd_sq
Definition: invbicg.cc:121
Double cp
Definition: invbicg.cc:107
Complex a
Definition: invbicg.cc:95
DComplex d
Definition: invbicg.cc:99
int k
Definition: invbicg.cc:119
FloatingPoint< double > Double
Definition: gtest.h:7351
RsdMR
Definition: pade_trln_w.cc:26
multi1d< LatticeFermion > r(Ncb)
chi
Definition: pade_trln_w.cc:24
psi
Definition: pade_trln_w.cc:191
Holds return info from SystemSolver call.
Definition: syssolver.h:17