Bridge++  Ver. 2.0.2
asolver_CG-tmpl.h
Go to the documentation of this file.
1 template<typename AFIELD>
2 const std::string ASolver_CG<AFIELD>::class_name = "ASolver_CG";
3 //====================================================================
4 template<typename AFIELD>
6 {
8 
9  int nin = m_fopr->field_nin();
10  int nvol = m_fopr->field_nvol();
11  int nex = m_fopr->field_nex();
12 
13  m_x.reset(nin, nvol, nex);
14  m_r.reset(nin, nvol, nex);
15  m_p.reset(nin, nvol, nex);
16  m_s.reset(nin, nvol, nex);
17 
18  // m_vl = Bridge::DETAILED;
19 
20  m_nconv = -1;
21 }
22 
23 
24 //====================================================================
25 template<typename AFIELD>
27 {
28  // ThreadManager::assert_single_thread(class_name);
29  // nothing is to be deleted.
30 }
31 
32 
33 //====================================================================
34 template<typename AFIELD>
36 {
37  const string str_vlevel = params.get_string("verbose_level");
38 
39  m_vl = vout.set_verbose_level(str_vlevel);
40 
41  //- fetch and check input parameters
42  int Niter, Nrestart;
43  double Stop_cond;
44 
45  int err = 0;
46  err += params.fetch_int("maximum_number_of_iteration", Niter);
47  err += params.fetch_int("maximum_number_of_restart", Nrestart);
48  err += params.fetch_double("convergence_criterion_squared", Stop_cond);
49 
50  if (err) {
51  vout.crucial(m_vl, "Error at %s: input parameter not found.\n",
52  class_name.c_str());
53  exit(EXIT_FAILURE);
54  }
55 
56  InitialGuess init_guess_mode = InitialGuess::RHS;
57  if (params.find_string("initial_guess_mode")) {
58  const string initial_guess_mode = params.get_string("initial_guess_mode");
59  vout.detailed(m_vl, " initila_guess_mode %s\n", initial_guess_mode.c_str());
60  if (initial_guess_mode == "RHS") {
61  init_guess_mode = InitialGuess::RHS;
62  } else if (initial_guess_mode == "GIVEN") {
63  init_guess_mode = InitialGuess::GIVEN;
64  } else if (initial_guess_mode == "ZERO") {
65  init_guess_mode = InitialGuess::ZERO;
66  } else {
67  vout.crucial(m_vl, "Error at %s: unknown initial guess mode, %s\n", class_name.c_str(), initial_guess_mode.c_str());
68  exit(EXIT_FAILURE);
69  }
70  }
71 
72  int Niter2 = Niter * Nrestart;
73  set_parameters(Niter2, Stop_cond, init_guess_mode);
74 }
75 
76 
77 //====================================================================
78 template<typename AFIELD>
80  const real_t Stop_cond)
81 {
82  set_parameters(Niter, Stop_cond, InitialGuess::RHS);
83 }
84 
85 
86 //====================================================================
87 template<typename AFIELD>
89  const real_t Stop_cond,
90  const InitialGuess init_guess_mode)
91 {
93 
94  m_Niter = Niter;
95  m_Stop_cond = Stop_cond;
96  m_initial_mode = init_guess_mode;
97  std::string prec = "double";
98  if (sizeof(real_t) == 4) prec = "float";
99 
100  vout.general(m_vl, "%s:\n", class_name.c_str());
101  vout.general(m_vl, " Precision: %s\n", prec.c_str());
102  vout.general(m_vl, " Niter = %d\n", m_Niter);
103  vout.general(m_vl, " Stop_cond = %16.8e\n", m_Stop_cond);
104  vout.general(m_vl, " init_guess_mode: %d\n", m_initial_mode);
105 }
106 
107 
108 //====================================================================
109 template<typename AFIELD>
111  int& Nconv, real_t& diff)
112 {
113  copy(m_s, b);
114 
115  real_t sr = norm2(m_s);
116  real_t snorm = 1.0 / sr;
117  vout.detailed(m_vl, " snorm = %22.15e\n", snorm);
118 
119  real_t rr, rrp;
120  int nconv = -1;
121 
122  solve_CG_init(rrp, rr);
123  vout.detailed(m_vl, " init: %22.15e\n", rr * snorm);
124 
125  for (int iter = 0; iter < m_Niter; ++iter) {
126  solve_CG_step(rrp, rr);
127  vout.detailed(m_vl, "%6d %22.15e\n", iter, rr * snorm);
128 
129  if (rr * snorm < m_Stop_cond) {
130  nconv = iter;
131 #pragma omp master
132  {
133  m_nconv = nconv + 1;
134  }
135  break;
136  }
137  }
138 
139  if (nconv == -1) {
140  vout.crucial(m_vl, "Error at %s: not converged\n",
141  class_name.c_str());
142  vout.crucial(m_vl, " iter(final): %8d %22.15e\n",
143  m_Niter, rr * snorm);
144 #pragma omp barrier
145  //exit(EXIT_FAILURE);
146  }
147 
148  vout.detailed(m_vl, "converged:\n");
149  vout.detailed(m_vl, " nconv = %d\n", nconv);
150 
151  copy(xq, m_x);
152 
153  m_fopr->mult(m_s, xq);
154 
155  axpy(m_s, real_t(-1.0), b);
156  real_t diff2 = norm2(m_s);
157 
158 #pragma omp master
159  {
160  diff = diff2;
161  Nconv = m_nconv;
162  }
163 #pragma omp barrier
164 }
165 
166 
167 //====================================================================
168 template<typename AFIELD>
170 {
171  if (m_initial_mode == InitialGuess::RHS) {
172 #ifdef DEBUG
173  vout.general(m_vl, "%s: using InitialGuess::RHS\n", class_name.c_str());
174 #endif
175  copy(m_r, m_s);
176  copy(m_x, m_s);
177  m_fopr->mult(m_s, m_x);
178  axpy(m_r, real_t(-1.0), m_s);
179  copy(m_p, m_r);
180  rr = norm2(m_r);
181  rrp = rr;
182  } else if (m_initial_mode == InitialGuess::GIVEN) {
183  vout.crucial("%s: InitialGuess::GIVEN is not yet ready\n", class_name.c_str());
184  exit(EXIT_FAILURE);
185  } else if (m_initial_mode == InitialGuess::ZERO) {
186 #ifdef DEBUG
187  vout.general(m_vl, "%s: using InitialGuess::ZERO\n", class_name.c_str());
188 #endif
189  copy(m_r, m_s);
190  m_s.set(0.0);
191  m_x.set(0.0);
192  copy(m_p, m_r);
193  rr = norm2(m_r);
194  rrp = rr;
195  } else {
196  vout.crucial("%s: unkown init guess mode\n", class_name.c_str());
197  exit(EXIT_FAILURE);
198  }
199 }
200 
201 
202 //====================================================================
203 template<typename AFIELD>
205 {
206  using complex_t = typename AFIELD::complex_t;
207 
208  m_fopr->mult(m_s, m_p);
209 
210  real_t pap = dot(m_s, m_p);
211  // m_fopr->mult_normA_dev(pap, m_s, m_p);
212  real_t cr = rrp / pap;
213 
214  axpy(m_x, cr, m_p);
215 
216  axpy(m_r, -cr, m_s);
217  rr = norm2(m_r);
218 
219  real_t bk = rr / rrp;
220 
221  aypx(bk, m_p, m_r);
222 
223  rrp = rr;
224 }
225 
226 
227 //====================================================================
228 template<typename AFIELD>
230 {
231  int Nin = m_fopr->field_nin();
232  int Nvol = m_fopr->field_nvol();
233  int Nex = m_fopr->field_nex();
234  int NPE = CommonParameters::NPE();
235 
236  int ninit = 1;
237 
238  double flop_field = static_cast<double>(Nin * Nvol * Nex) * NPE;
239  double flop_vector = (6 + ninit * 4 + m_nconv * 11) * flop_field;
240  double flop_fopr = (1 + ninit + m_nconv) * m_fopr->flop_count();
241 
242  double flop = flop_vector + flop_fopr;
243 
244  return flop;
245 }
246 
247 
248 //====================================================================
249 //============================================================END=====
Parameters::find_string
bool find_string(const string &key) const
Definition: parameters.cpp:507
ASolver_CG::solve_CG_step
void solve_CG_step(real_t &rrp, real_t &rr)
Definition: asolver_CG-tmpl.h:204
Parameters
Class for parameters.
Definition: parameters.h:46
ASolver_CG::set_parameters
void set_parameters(const Parameters &params)
setting parameters by a Parameter object.
Definition: asolver_CG-tmpl.h:35
ASolver_CG::solve_CG_init
void solve_CG_init(real_t &rrp, real_t &rr)
Definition: asolver_CG-tmpl.h:169
ASolver_CG
Definition: asolver_CG.h:16
Bridge::BridgeIO::detailed
void detailed(const char *format,...)
Definition: bridgeIO.cpp:219
ASolver_CG::solve
void solve(AFIELD &xq, const AFIELD &b, int &nconv, real_t &diff)
solver main.
Definition: asolver_CG-tmpl.h:110
aypx
void aypx(const double a, Field &y, const Field &x)
aypx(y, a, x): y := a * y + x
Definition: field.cpp:509
axpy
void axpy(Field &y, const double a, const Field &x)
axpy(y, a, x): y := a * x + y
Definition: field.cpp:380
dot
double dot(const Field &y, const Field &x)
Definition: field.cpp:576
real_t
double real_t
Definition: bridgeQXS_Clover_coarse_double.cpp:16
norm2
REALTYPE norm2(const AField< REALTYPE, QXS > &v)
Definition: afield-inc.h:453
ASolver_CG::init
void init(void)
Definition: asolver_CG-tmpl.h:5
copy
void copy(Field &y, const Field &x)
copy(y, x): y = x
Definition: field.cpp:212
ASolver_CG::tidyup
void tidyup(void)
Definition: asolver_CG-tmpl.h:26
CommonParameters::NPE
static int NPE()
Definition: commonParameters.h:101
ASolver_CG::flop_count
double flop_count()
returns the floating point operation count.
Definition: asolver_CG-tmpl.h:229
Bridge::BridgeIO::set_verbose_level
static VerboseLevel set_verbose_level(const std::string &str)
Definition: bridgeIO.cpp:133
Parameters::fetch_double
int fetch_double(const string &key, double &value) const
Definition: parameters.cpp:327
ASolver::InitialGuess
InitialGuess
Definition: asolver.h:31
complex_t
ComplexTraits< double >::complex_t complex_t
Definition: afopr_Clover_coarse_double.cpp:23
Parameters::get_string
string get_string(const string &key) const
Definition: parameters.cpp:221
Bridge::BridgeIO::crucial
void crucial(const char *format,...)
Definition: bridgeIO.cpp:180
Field
Container of Field-type object.
Definition: field.h:46
Parameters::fetch_int
int fetch_int(const string &key, int &value) const
Definition: parameters.cpp:346
Bridge::BridgeIO::general
void general(const char *format,...)
Definition: bridgeIO.cpp:200
ASolver::real_t
AFIELD::real_t real_t
Definition: asolver.h:29
ThreadManager::assert_single_thread
static void assert_single_thread(const std::string &class_name)
assert currently running on single thread.
Definition: threadManager.cpp:372
Bridge::vout
BridgeIO vout
Definition: bridgeIO.cpp:512