Bridge++  Ver.2.1.3
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 #pragma omp barrier
114 
115  int ith = ThreadManager::get_thread_id();
116 
117  copy(m_s, b);
118 
119  real_t sr = norm2(m_s);
120  real_t snorm = 1.0 / sr;
121  vout.detailed(m_vl, " snorm = %22.15e\n", snorm);
122 
123  real_t rr, rrp;
124  int nconv = -1;
125 
126  solve_CG_init(rrp, rr);
127  vout.detailed(m_vl, " init: %22.15e\n", rr * snorm);
128 
129  if(rr * snorm < m_Stop_cond) {
130  nconv = 0;
131  if(ith == 0) m_nconv = nconv;
132  goto converged;
133  }
134 
135  for (int iter = 0; iter < m_Niter; ++iter) {
136 
137  solve_CG_step(rrp, rr);
138  vout.detailed(m_vl, "%6d %22.15e\n", iter, rr * snorm);
139 
140  if (rr * snorm < m_Stop_cond) {
141  nconv = iter;
142  if(ith == 0) m_nconv = nconv + 1;
143  break;
144  }
145  }
146 
147  if (nconv == -1) {
148  vout.crucial(m_vl, "Error at %s: not converged\n",
149  class_name.c_str());
150  vout.crucial(m_vl, " iter(final): %8d %22.15e\n",
151  m_Niter, rr * snorm);
152 #pragma omp barrier
153  //exit(EXIT_FAILURE);
154  }
155 
156  converged:
157  if(nconv != -1){
158  vout.detailed(m_vl, "converged:\n");
159  vout.detailed(m_vl, " nconv = %d\n", nconv);
160  }
161 
162  copy(xq, m_x);
163 
164  m_fopr->mult(m_s, xq);
165 
166  axpy(m_s, real_t(-1.0), b);
167  real_t diff2 = norm2(m_s);
168 
169  if(ith == 0){
170  diff = diff2;
171  Nconv = m_nconv;
172  }
173 #pragma omp barrier
174 
175 }
176 
177 
178 //====================================================================
179 template<typename AFIELD>
181 {
182  if (m_initial_mode == InitialGuess::RHS) {
183 #ifdef DEBUG
184  vout.general(m_vl, "%s: using InitialGuess::RHS\n", class_name.c_str());
185 #endif
186  copy(m_r, m_s);
187  copy(m_x, m_s);
188  m_fopr->mult(m_s, m_x);
189  axpy(m_r, real_t(-1.0), m_s);
190  copy(m_p, m_r);
191  rr = norm2(m_r);
192  rrp = rr;
193  } else if (m_initial_mode == InitialGuess::GIVEN) {
194  vout.crucial("%s: InitialGuess::GIVEN is not yet ready\n", class_name.c_str());
195  exit(EXIT_FAILURE);
196  } else if (m_initial_mode == InitialGuess::ZERO) {
197 #ifdef DEBUG
198  vout.general(m_vl, "%s: using InitialGuess::ZERO\n", class_name.c_str());
199 #endif
200  copy(m_r, m_s);
201  m_s.set(0.0);
202  m_x.set(0.0);
203  copy(m_p, m_r);
204  rr = norm2(m_r);
205  rrp = rr;
206  } else {
207  vout.crucial("%s: unkown init guess mode\n", class_name.c_str());
208  exit(EXIT_FAILURE);
209  }
210 }
211 
212 
213 //====================================================================
214 template<typename AFIELD>
216 {
217  using complex_t = typename AFIELD::complex_t;
218 
219  m_fopr->mult(m_s, m_p);
220 
221  real_t pap = dot(m_s, m_p);
222  // m_fopr->mult_normA_dev(pap, m_s, m_p);
223  real_t cr = rrp / pap;
224 
225  axpy(m_x, cr, m_p);
226 
227  axpy(m_r, -cr, m_s);
228  rr = norm2(m_r);
229 
230  real_t bk = rr / rrp;
231 
232  aypx(bk, m_p, m_r);
233 
234  rrp = rr;
235 }
236 
237 
238 //====================================================================
239 template<typename AFIELD>
241 {
242  int Nin = m_fopr->field_nin();
243  int Nvol = m_fopr->field_nvol();
244  int Nex = m_fopr->field_nex();
245  int NPE = CommonParameters::NPE();
246 
247  int ninit = 1;
248 
249  double flop_field = static_cast<double>(Nin * Nvol * Nex) * NPE;
250  double flop_vector = (6 + ninit * 4 + m_nconv * 11) * flop_field;
251  double flop_fopr = (1 + ninit + m_nconv) * m_fopr->flop_count();
252 
253  double flop = flop_vector + flop_fopr;
254 
255  return flop;
256 }
257 
258 
259 //====================================================================
260 //============================================================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:215
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:180
ASolver_CG
Definition: asolver_CG.h:16
Bridge::BridgeIO::detailed
void detailed(const char *format,...)
Definition: bridgeIO.cpp:281
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:510
axpy
void axpy(Field &y, const double a, const Field &x)
axpy(y, a, x): y := a * x + y
Definition: field.cpp:381
dot
double dot(const Field &y, const Field &x)
Definition: field.cpp:577
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:213
ASolver_CG::tidyup
void tidyup(void)
Definition: asolver_CG-tmpl.h:26
CommonParameters::NPE
static int NPE()
Definition: commonParameters.h:101
BridgeACC::norm2
double norm2(double *restrict v1, int nin, int nvol)
real_t
double real_t
Definition: bridgeACC_AField_double.cpp:14
ASolver_CG::flop_count
double flop_count()
returns the floating point operation count.
Definition: asolver_CG-tmpl.h:240
Bridge::BridgeIO::set_verbose_level
static VerboseLevel set_verbose_level(const std::string &str)
Definition: bridgeIO.cpp:195
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:242
Field
Container of Field-type object.
Definition: field.h:46
ThreadManager::get_thread_id
static int get_thread_id()
returns thread id.
Definition: threadManager.cpp:253
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:262
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:572