Bridge++  Ver.2.1.3
afopr_Sign-tmpl.h
Go to the documentation of this file.
1 
14 #include "Fopr/afopr_Sign.h"
16 
17 #ifdef USE_FACTORY_AUTOREGISTER
18 namespace {
20 }
21 #endif
22 
23 template<typename AFIELD>
24 const std::string AFopr_Sign<AFIELD>::class_name = "AFopr_Sign";
25 
26 //====================================================================
27 template<typename AFIELD>
29 {
31 
32  m_vl = CommonParameters::Vlevel();
33 
34  vout.general(m_vl, "%s: construction\n", class_name.c_str());
35  vout.general(m_vl, " -- Sign function with Zolotarev approximation\n");
37 
38  m_Nin = m_fopr->field_nin();
39  m_Nvol = m_fopr->field_nvol();
40  m_Nex = m_fopr->field_nex();
41 
42  m_Nsbt = 0;
43  m_ev = 0;
44  m_vk = 0;
45 
46  m_Np = 0;
47 
48  set_parameters(params);
49 
51  vout.general(m_vl, "%s: construction finished.\n",
52  class_name.c_str());
53 }
54 
55 
56 //====================================================================
57 template<typename AFIELD>
59 {
61 
62  m_vl = CommonParameters::Vlevel();
63 
64  vout.general(m_vl, "%s: construction (obsolete)\n", class_name.c_str());
65  vout.general(m_vl, " -- Sign function with Zolotarev approximation\n");
66 
67  m_Nin = m_fopr->field_nin();
68  m_Nvol = m_fopr->field_nvol();
69  m_Nex = m_fopr->field_nex();
70 
71  m_Nsbt = 0;
72  m_ev = 0;
73  m_vk = 0;
74 
75  vout.general(m_vl, "%s: construction finished.\n",
76  class_name.c_str());
77 }
78 
79 
80 //====================================================================
81 template<typename AFIELD>
83 {
84  delete m_solver;
85 }
86 
87 
88 //====================================================================
89 template<typename AFIELD>
91 {
92 #pragma omp barrier
93  int ith = ThreadManager::get_thread_id();
94 
95  std::string vlevel;
96  if (!params.fetch_string("verbose_level", vlevel)) {
97  if (ith == 0) m_vl = vout.set_verbose_level(vlevel);
98  }
99 #pragma omp barrier
100 
101  //- fetch and check input parameters
102  int Np;
103  double x_min, x_max;
104  int Niter;
105  double Stop_cond;
106 
107  int err = 0;
108  err += params.fetch_int("number_of_poles", Np);
109  err += params.fetch_double("lower_bound", x_min);
110  err += params.fetch_double("upper_bound", x_max);
111  err += params.fetch_int("maximum_number_of_iteration", Niter);
112  err += params.fetch_double("convergence_criterion_squared", Stop_cond);
113 
114  if (err) {
115  vout.crucial(m_vl, "Error at %s: input parameter not found.\n",
116  class_name.c_str());
117  exit(EXIT_FAILURE);
118  }
119 
120  set_parameters(Np, real_t(x_min), real_t(x_max),
121  Niter, real_t(Stop_cond));
122 }
123 
124 
125 //====================================================================
126 template<typename AFIELD>
128  const real_t x_min,
129  const real_t x_max,
130  const int Niter,
131  const real_t Stop_cond)
132 {
133 #pragma omp barrier
134  int ith = ThreadManager::get_thread_id();
135 
136  //- range check
137  int err = 0;
138  err += ParameterCheck::non_zero(Np);
139  // NB. x_min,x_max == 0 is allowed.
140  err += ParameterCheck::non_zero(Niter);
141  err += ParameterCheck::square_non_zero(Stop_cond);
142 
143  if (err) {
144  vout.crucial(m_vl, "Error at %s: parameter range check failed.\n",
145  class_name.c_str());
146  exit(EXIT_FAILURE);
147  }
148 
149  int Np_prev;
150  if (ith == 0) {
151  Np_prev = m_Np;
152  m_Np = Np;
153  m_x_min = x_min;
154  m_x_max = x_max;
155  m_Niter = Niter;
156  m_Stop_cond = Stop_cond;
157 
158  m_sigma.resize(m_Np);
159  m_cl.resize(2 * m_Np);
160  m_bl.resize(m_Np);
161  }
162 #pragma omp barrier
163 
164  //- print input parameters
165  vout.general(m_vl, "%s: parameters\n", class_name.c_str());
166  vout.general(m_vl, " Np = %4d\n", m_Np);
167  vout.general(m_vl, " x_min = %12.8f\n", m_x_min);
168  vout.general(m_vl, " x_max = %12.8f\n", m_x_max);
169  vout.general(m_vl, " Niter = %6d\n", m_Niter);
170  vout.general(m_vl, " Stop_cond = %8.2e\n", m_Stop_cond);
171 
172  if(m_Np != Np_prev){
173  init_parameters();
174  }
175 
176 }
177 
178 //====================================================================
179 template<typename AFIELD>
181 {
182 #pragma omp barrier
183  int ith = ThreadManager::get_thread_id();
184 
186 
187  if (ith == 0) {
188  m_sigma.resize(m_Np);
189  m_cl.resize(2 * m_Np);
190  m_bl.resize(m_Np);
191 
192  // Zolotarev coefficient defined
193  const real_t bmax = m_x_max / m_x_min;
194 
195  Math_Sign_Zolotarev sign_func(m_Np, bmax);
196  sign_func.get_sign_parameters(m_cl, m_bl);
197 
198  for (int i = 0; i < m_Np; i++) {
199  m_sigma[i] = m_cl[2 * i] * m_x_min * m_x_min;
200  }
201 
202  for (int i = 0; i < m_Np; i++) {
203  vout.general(m_vl, " %3d %12.4e %12.4e %12.4e\n",
204  i, m_cl[i], m_cl[i + m_Np], m_bl[i]);
205  }
206 
207  m_xq.resize(m_Np);
208  for (int i = 0; i < m_Np; ++i) {
209  m_xq[i].reset(m_Nin, m_Nvol, m_Nex);
210  }
211 
212  Parameters params_solver;
213  params_solver.set_int("number_of_shifts", m_Np);
214  params_solver.set_int("maximum_number_of_iteration", m_Niter);
215  params_solver.set_double("convergence_criterion_squared", m_Stop_cond);
216  params_solver.set_string("verbose_level", vout.get_verbose_level(m_vl));
217 
218  m_solver = new AShiftsolver_CG<AFIELD, AFOPR>(
219  m_fopr, params_solver);
220  // m_Niter,
221  // m_Stop_cond);
222  // m_solver->set_parameter_verboselevel(m_vl);
223 
224  m_w1.reset(m_Nin, m_Nvol, m_Nex);
225  }
226 
228 
229 #pragma omp barrier
230 }
231 
232 
233 //====================================================================
234 template<typename AFIELD>
236 {
237  params.set_int("number_of_poles", m_Np);
238  params.set_double("lower_bound", double(m_x_min));
239  params.set_double("upper_bound", double(m_x_max));
240  params.set_int("maximum_number_of_iteration", m_Niter);
241  params.set_double("convergence_criterion_squared", double(m_Stop_cond));
242 
243  params.set_string("verbose_level", vout.get_verbose_level(m_vl));
244 }
245 
246 
247 //====================================================================
248 template<typename AFIELD>
250 {
251  m_fopr->set_config(U);
252 }
253 
254 
255 //====================================================================
256 template<typename AFIELD>
257 void AFopr_Sign<AFIELD>::set_mode(const std::string mode)
258 {
259 #pragma omp barrier
260 
261  int ith = ThreadManager::get_thread_id();
262  if (ith == 0) m_mode = mode;
263 
264  m_fopr->set_mode(mode); // this operation is irrlevant since
265  // reset in mult.
266 
267 #pragma omp barrier
268 }
269 
270 
271 //====================================================================
272 template<typename AFIELD>
274  std::vector<real_t> *ev,
275  std::vector<AFIELD> *vk)
276 {
277  if ((Nsbt > ev->size()) || (Nsbt > vk->size())) {
278  vout.crucial(m_vl, "Error at %s: Nsbt is larger than array size\n",
279  class_name.c_str());
280  exit(EXIT_FAILURE);
281  }
282 
283  m_Nsbt = Nsbt;
284  m_ev = ev;
285  m_vk = vk;
286 }
287 
288 
289 //====================================================================
290 template<typename AFIELD>
292 {
293  assert(b.check_size(m_Nin, m_Nvol, m_Nex));
294  assert(v.check_size(m_Nin, m_Nvol, m_Nex));
295 
296 #pragma omp barrier
297 
298  copy(m_w1, b);
299  if (m_Nsbt > 0) subtract_lowmodes(m_w1);
300 
301  m_fopr->set_mode("DdagD");
302 
303  int Nconv;
304  real_t diff;
305  m_solver->solve(m_xq, m_sigma, m_w1, Nconv, diff);
306 
307  // scal(v, 0.0);
308  v.set(0.0);
309 
310  for (int i = 0; i < m_Np; i++) {
311  axpy(v, m_bl[i], m_xq[i]);
312  }
313 #pragma omp barrier
314 
315  m_fopr->mult(m_w1, v);
316 
317  const real_t coeff = m_cl[2 * m_Np - 1] * m_x_min * m_x_min;
318  axpy(m_w1, coeff, v);
319 
320  m_fopr->set_mode("H");
321  m_fopr->mult(v, m_w1);
322 
323  scal(v, 1.0 / m_x_min); // v *= 1/m_x_min;
324 #pragma omp barrier
325 
326  if (m_Nsbt > 0) evaluate_lowmodes(v, b);
327 }
328 
329 
330 //====================================================================
331 template<typename AFIELD>
333 {
334 #pragma omp barrier
335 
336  for (int k = 0; k < m_Nsbt; ++k) {
337  complex_t prod = dotc((*m_vk)[k], w);
338  axpy(w, -prod, (*m_vk)[k]);
339  }
340 #pragma omp barrier
341 }
342 
343 
344 //====================================================================
345 template<typename AFIELD>
347 {
348 #pragma omp barrier
349 
350  for (int k = 0; k < m_Nsbt; ++k) {
351  complex_t prod = dotc((*m_vk)[k], w);
352 
353  real_t ev = (*m_ev)[k];
354  real_t sgn = ev / fabs(ev);
355  prod *= sgn;
356  axpy(x, prod, (*m_vk)[k]);
357  }
358 #pragma omp barrier
359 }
360 
361 
362 //====================================================================
363 template<typename AFIELD>
365 {
366 // cl[2*Np], bl[Np]: coefficients of rational approx.
367 
368  real_t x2R = 0.0;
369 
370  for (int l = 0; l < m_Np; l++) {
371  x2R += m_bl[l] / (x * x + m_cl[2 * l]);
372  }
373  x2R = x2R * (x * x + m_cl[2 * m_Np - 1]);
374 
375  return x * x2R;
376 }
377 
378 
379 //====================================================================
380 template<typename AFIELD>
382 {
383  flop_count(m_mode);
384 }
385 
386 
387 //====================================================================
388 template<typename AFIELD>
389 double AFopr_Sign<AFIELD>::flop_count(const std::string mode)
390 {
391  int NPE = CommonParameters::NPE();
392 
393  double gflop_solver = m_solver->flop_count();
394 
395  double gflop_fopr = m_fopr->flop_count("DdagD")
396  + m_fopr->flop_count("H");
397 
398  double flop_blas = m_Nin * m_Nex * ((m_Np + 1) * 2 + 1);
399  // (Np + 1) axpy + 1 scal
400 
401  int flop_subt = m_Nsbt * m_Nin * m_Nex * 4 * 2 * 2;
402  // for each subt vector, (dotc + complex axpy) * 2 (subt and eval)
403  // dotc and axpy respectively amount Nin * 4 * Nex.
404  // Note that this counting is for a complex Field.
405 
406  double flop_site = double(flop_blas) + double(flop_subt);
407 
408  double gflop = flop_site * double(m_Nvol) * double(NPE) * 1.0e-9;
409 
410  gflop += gflop_solver + gflop_fopr;
411 
412  return gflop;
413 }
414 
415 
416 //============================================================END=====
AFopr_Sign::set_lowmodes
void set_lowmodes(const int Nsbt, std::vector< real_t > *, std::vector< AFIELD > *)
Definition: afopr_Sign-tmpl.h:273
AFopr_Sign::get_parameters
void get_parameters(Parameters &params) const
gets parameters by a Parameter object: to be implemented in a subclass.
Definition: afopr_Sign-tmpl.h:235
Parameters::set_string
void set_string(const string &key, const string &value)
Definition: parameters.cpp:39
AFopr_Sign::set_config
void set_config(Field *U)
sets the gauge configuration.
Definition: afopr_Sign-tmpl.h:249
AFopr_Sign
Sign function of a given fermion operator.
Definition: afopr_Sign.h:56
Field::set
void set(const int jin, const int site, const int jex, double v)
Definition: field.h:175
Parameters
Class for parameters.
Definition: parameters.h:46
AFopr_Sign::set_parameters
void set_parameters(const Parameters &params)
sets parameters by a Parameter object: to be implemented in a subclass.
Definition: afopr_Sign-tmpl.h:90
Math_Sign_Zolotarev::get_sign_parameters
void get_sign_parameters(std::vector< double > &cl, std::vector< double > &bl)
Definition: math_Sign_Zolotarev.cpp:25
Parameters::set_double
void set_double(const string &key, const double value)
Definition: parameters.cpp:33
Bridge::BridgeIO::decrease_indent
void decrease_indent()
Definition: bridgeIO.cpp:518
Bridge::BridgeIO::increase_indent
void increase_indent()
Definition: bridgeIO.cpp:508
Field::check_size
bool check_size(const int nin, const int nvol, const int nex) const
checking size parameters. [23 May 2016 H.Matsufuru]
Definition: field.h:135
AFopr_Sign< Field >::complex_t
ComplexTraits< real_t >::complex_t complex_t
Definition: afopr_Sign.h:61
axpy
void axpy(Field &y, const double a, const Field &x)
axpy(y, a, x): y := a * x + y
Definition: field.cpp:381
AFopr_Sign::sign_zolotarev
real_t sign_zolotarev(const real_t x)
Definition: afopr_Sign-tmpl.h:364
copy
void copy(Field &y, const Field &x)
copy(y, x): y = x
Definition: field.cpp:213
Field::real_t
double real_t
Definition: field.h:51
afopr_Sign.h
ParameterCheck::square_non_zero
int square_non_zero(const double v)
Definition: parameterCheck.cpp:43
AFopr_Sign::evaluate_lowmodes
void evaluate_lowmodes(AFIELD &, const AFIELD &)
Definition: afopr_Sign-tmpl.h:346
threadManager.h
dotc
dcomplex dotc(const Field &y, const Field &x)
Definition: field.cpp:713
CommonParameters::NPE
static int NPE()
Definition: commonParameters.h:101
real_t
double real_t
Definition: bridgeACC_AField_double.cpp:14
AFopr_Sign< Field >::real_t
Field ::real_t real_t
Definition: afopr_Sign.h:60
AFopr_Sign::subtract_lowmodes
void subtract_lowmodes(AFIELD &)
Definition: afopr_Sign-tmpl.h:332
CommonParameters::Vlevel
static Bridge::VerboseLevel Vlevel()
Definition: commonParameters.h:122
Bridge::BridgeIO::set_verbose_level
static VerboseLevel set_verbose_level(const std::string &str)
Definition: bridgeIO.cpp:195
ParameterCheck::non_zero
int non_zero(const double v)
Definition: parameterCheck.cpp:32
AFopr_Sign::set_mode
void set_mode(const std::string mode)
setting the mode of multiplication if necessary. Default implementation here is just to avoid irrelev...
Definition: afopr_Sign-tmpl.h:257
Parameters::set_int
void set_int(const string &key, const int value)
Definition: parameters.cpp:36
AFopr_Sign::init
void init()
Definition: afopr_Sign-tmpl.h:58
scal
void scal(Field &x, const double a)
scal(x, a): x = a * x
Definition: field.cpp:262
Parameters::fetch_string
int fetch_string(const string &key, string &value) const
Definition: parameters.cpp:378
Parameters::fetch_double
int fetch_double(const string &key, double &value) const
Definition: parameters.cpp:327
Bridge::BridgeIO::crucial
void crucial(const char *format,...)
Definition: bridgeIO.cpp:242
AFopr_Sign::mult
void mult(AFIELD &v, const AFIELD &w)
multiplies fermion operator to a given field.
Definition: afopr_Sign-tmpl.h:291
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
AShiftsolver_CG
Multishift Conjugate Gradient solver.
Definition: ashiftsolver_CG.h:33
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
AFopr_Sign::init_parameters
void init_parameters()
Definition: afopr_Sign-tmpl.h:180
ThreadManager::assert_single_thread
static void assert_single_thread(const std::string &class_name)
assert currently running on single thread.
Definition: threadManager.cpp:372
AFopr_Sign::flop_count
double flop_count()
returns the number of floating point operations.
Definition: afopr_Sign-tmpl.h:381
Bridge::vout
BridgeIO vout
Definition: bridgeIO.cpp:572
Bridge::BridgeIO::get_verbose_level
static std::string get_verbose_level(const VerboseLevel vl)
Definition: bridgeIO.cpp:216
AFopr_Sign::tidyup
void tidyup()
Definition: afopr_Sign-tmpl.h:82
Math_Sign_Zolotarev
Determination of Zolotarev coefficients.
Definition: math_Sign_Zolotarev.h:36