Bridge++  Ver. 2.0.2
asolver_SAP_MINRES-tmpl.h
Go to the documentation of this file.
1 
10 //====================================================================
11 
12 template<typename AFIELD>
14  = "ASolver_SAP_MINRES";
15 
16 //====================================================================
17 template<typename AFIELD>
19 {
21 
22  int nin = m_fopr->field_nin();
23  int nvol = m_fopr->field_nvol();
24  int nex = m_fopr->field_nex();
25 
26  m_r.reset(nin, nvol, nex);
27  m_p.reset(nin, nvol, nex);
28 
29  m_p2_block.resize(m_block_index->coarse_nvol());
30  m_alpha_block.resize(m_block_index->coarse_nvol());
31 
32 #ifdef DEBUG_MINRES
33  m_r2_block.resize(m_block_index->coarse_nvol());
34 #endif
35 
36  m_nconv = -1;
37  calc_flop_each();
38 }
39 
40 
41 //====================================================================
42 template<typename AFIELD>
44 {
45  // ThreadManager::assert_single_thread(class_name);
46  // nothing is to be deleted.
47 }
48 
49 
50 //====================================================================
51 template<typename AFIELD>
53 {
54  const string str_vlevel = params.get_string("verbose_level");
55 
56  m_vl = vout.set_verbose_level(str_vlevel);
57 
58  //- fetch and check input parameters
59  int Niter, Nrestart;
60  double Stop_cond;
61 
62  int err = 0;
63  err += params.fetch_int("maximum_number_of_iteration", Niter);
64  err += params.fetch_int("maximum_number_of_restart", Nrestart);
65  err += params.fetch_double("convergence_criterion_squared", Stop_cond);
66 
67  if (err) {
68  vout.crucial(m_vl, "Error at %s: input parameter not found.\n",
69  class_name.c_str());
70  exit(EXIT_FAILURE);
71  }
72 
73  int Niter2 = Niter * Nrestart;
74  set_parameters(Niter2, Stop_cond);
75 }
76 
77 
78 //====================================================================
79 template<typename AFIELD>
81  const real_t Stop_cond)
82 {
84 
85  m_Niter = Niter;
86  m_Stop_cond = Stop_cond;
87  std::string prec = "double";
88  if (sizeof(real_t) == 4) prec = "float";
89 
90  vout.general(m_vl, "%s:\n", class_name.c_str());
91  vout.general(m_vl, " Precision: %s\n", prec.c_str());
92  vout.general(m_vl, " Niter = %d\n", m_Niter);
93  vout.general(m_vl, " Stop_cond = %16.8e\n", m_Stop_cond);
94 }
95 
96 
97 //====================================================================
98 template<typename AFIELD>
100  int& Nconv, real_t& diff, const int eo)
101 {
102  assert(m_block_index);
103  assert(m_fopr);
104 
105  int ith, nth, is, ns;
106  set_threadtask(ith, nth, is, ns, m_block_index->coarse_nvol());
107 
108 #pragma omp barrier // fine
109 
110  // init
111  x.set(real_t(0.0));
112  copy(m_r, b);
113 
114 #pragma omp barrier // coarse
115 
116  for (int i = is; i < ns; ++i) {
117  m_p2_block[i] = real_t(1.0);
118  m_alpha_block[i] = complex_t(0.0, 0.0);
119  }
120 
121  // steps
122  for (int iter = 0; iter < m_Niter; ++iter) {
123  m_fopr->mult_sap(m_p, m_r, eo);
124 
125  block_norm2_eo(&(m_p2_block[0]), m_p, eo, *m_block_index);
126  block_dotc_eo(&(m_alpha_block[0]), m_p, m_r, eo, *m_block_index);
127 
128  for (int i = is; i < ns; ++i) {
129  if (m_p2_block[i] > 0.0) {
130  m_alpha_block[i] /= m_p2_block[i];
131  } else {
132  // if the probe m_p is null, stop updating
133  // as m_p is null, m_alpha is automatically zero.
134  // m_alpha_block[i]=0.0;
135  }
136  }
137  block_axpy_eo(x, &(m_alpha_block[0]), m_r, eo, real_t(1.0),
138  *m_block_index); // uses +m_alpha_block
139 
140  block_axpy_eo(m_r, &(m_alpha_block[0]), m_p, eo, real_t(-1.0),
141  *m_block_index); // used -m_alpha_block
142 
143 #ifdef DEBUG_MINRES
144  block_norm2_eo(&(m_r2_block[0]), m_r, eo, *m_block_index);
145 
146 #pragma omp barrier
147 
148 #pragma omp master
149  {
150  double r2 = 0.0;
151  double p2 = 0.0;
152  // printf(" block ie r2 p2\n");
153  for (int i = 0; i < m_block_index->coarse_nvol(); ++i) {
154  // printf(" %d %d %e %e\n", i, m_block_index->block_eo(i),
155  // m_r2_block[i], m_p2_block[i]);
156  if (m_block_index->block_eo(i) == eo) {
157  r2 += m_r2_block[i];
158  p2 += m_p2_block[i];
159  }
160  }
161  r2 = Communicator::reduce_sum(r2);
162  p2 = Communicator::reduce_sum(p2);
163  vout.general(m_vl, "iter=%d , sum(r2)=%e sum(p2)=%e\n", iter, r2, p2);
164  }// master
165 #pragma omp barrier
166 #endif // DEBUG_MINRES
167  } // iter
168 
169 #pragma omp barrier
170 }
171 
172 
173 //====================================================================
174 template<typename AFIELD>
176 {
177  return m_Niter * m_flop_each;
178 }
179 
180 
181 //====================================================================
182 template<typename AFIELD>
184 {
185  int Nin = m_fopr->field_nin();
186  int Nvol = m_fopr->field_nvol();
187  int Nex = m_fopr->field_nex();
188  int NPE = CommonParameters::NPE();
189 
190  // constexpr int Nc=3;
191  // constexpr int Nd=4;
192 
193  size_t nvol2 = m_block_index->coarse_nvol() / 2;
194  size_t block_vol = m_block_index->block_nvol();
195 
196  /*
197 
198  int block_x=m_block_index->fine_lattice_size(0)/m_block_index->coarse_lattice_size(0);
199  int block_y=m_block_index->fine_lattice_size(1)/m_block_index->coarse_lattice_size(1);
200  int block_z=m_block_index->fine_lattice_size(2)/m_block_index->coarse_lattice_size(2);
201  int block_t=m_block_index->fine_lattice_size(3)/m_block_index->coarse_lattice_size(3);
202 
203  constexpr int clover_site = 4*Nc*Nc*Nd*Nd;
204  constexpr int hop_x_site= Nc*Nd*(4*Nc+2);
205  constexpr int hop_y_site= Nc*Nd*(4*Nc+2);
206  constexpr int hop_z_site= Nc*Nd*(4*Nc+2);
207  constexpr int hop_t_site= Nc*Nd*(4*Nc+1);
208  constexpr int accum_site= 4*Nc*Nd;
209 
210  // assumes Dirac rep.
211  // todo move flop_fopr to the Clover (or Clover_SAP?)
212  double flop_x=2.0*static_cast<double>(hop_x_site)*(block_x-1)*block_y*block_z*block_t*nvol2*NPE;
213  double flop_y=2.0*static_cast<double>(hop_y_site)*block_x*(block_y-1)*block_z*block_t*nvol2*NPE;
214  double flop_z=2.0*static_cast<double>(hop_z_site)*block_x*block_y*(block_z-1)*block_t*nvol2*NPE;
215  double flop_t=2.0*static_cast<double>(hop_t_site)*block_x*block_y*block_z*(block_t-1)*nvol2*NPE;
216  double flop_fopr
217  =flop_x+flop_y+flop_z+flop_t+static_cast<double>(clover_site+accum_site)*nvol2*NPE;
218  */
219 
220  double flop_fopr = m_fopr->flop_count_sap();
221  double flop_norm2 = 8.0 * Nin * block_vol * nvol2 * NPE;
222  double flop_innerp = 8.0 * Nin * block_vol * nvol2 * NPE;
223  double flop_axpy = 8.0 * Nin * block_vol * nvol2 * NPE;
224 
225  double flop
226  = (flop_fopr + flop_norm2 + flop_innerp + 2 * flop_axpy
227  + 2 * nvol2 * NPE);
228 
229  m_flop_each = flop;
230 }
231 
232 
233 //============================================================END=====
ASolver_SAP_MINRES
Definition: asolver_SAP_MINRES.h:26
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
ASolver_SAP_MINRES::solve
void solve(AFIELD &xq, const AFIELD &b, int &nconv, real_t &diff, const int eo)
solver main.
Definition: asolver_SAP_MINRES-tmpl.h:99
ASolver_SAP_MINRES::calc_flop_each
void calc_flop_each()
Definition: asolver_SAP_MINRES-tmpl.h:183
real_t
double real_t
Definition: bridgeQXS_Clover_coarse_double.cpp:16
copy
void copy(Field &y, const Field &x)
copy(y, x): y = x
Definition: field.cpp:212
block_axpy_eo
void block_axpy_eo(AFIELD &v, const typename AFIELD::real_t *a, const AFIELD &w, const int ieo, const typename AFIELD::real_t fac, const INDEX &block_index)
Definition: afield_dd-inc.h:398
Communicator::reduce_sum
static int reduce_sum(int count, dcomplex *recv_buf, dcomplex *send_buf, int pattern=0)
make a global sum of an array of dcomplex over the communicator. pattern specifies the dimensions to ...
Definition: communicator.cpp:263
ASolver_SAP_MINRES::set_parameters
void set_parameters(const Parameters &params)
setting parameters by a Parameter object.
Definition: asolver_SAP_MINRES-tmpl.h:52
block_dotc_eo
void block_dotc_eo(typename AFIELD::complex_t *out, const AFIELD &v, const AFIELD &w, const int ieo, const INDEX &block_index)
Definition: afield_dd-inc.h:33
ASolver_SAP_MINRES::flop_count
double flop_count()
returns the floating point operation count.
Definition: asolver_SAP_MINRES-tmpl.h:175
CommonParameters::NPE
static int NPE()
Definition: commonParameters.h:101
ASolver_SAP_MINRES::real_t
AFIELD::real_t real_t
Definition: asolver_SAP_MINRES.h:29
Bridge::BridgeIO::set_verbose_level
static VerboseLevel set_verbose_level(const std::string &str)
Definition: bridgeIO.cpp:133
ASolver_SAP_MINRES::init
void init(void)
Definition: asolver_SAP_MINRES-tmpl.h:18
Parameters::fetch_double
int fetch_double(const string &key, double &value) const
Definition: parameters.cpp:327
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
ASolver_SAP_MINRES::tidyup
void tidyup(void)
Definition: asolver_SAP_MINRES-tmpl.h:43
block_norm2_eo
void block_norm2_eo(typename AFIELD::real_t *out, const AFIELD &v, const int ieo, const INDEX &block_index)
Definition: afield_dd-inc.h:141
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
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