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