22 template<
typename AFIELD>
46 template<
typename AFIELD>
51 if (size !=
sizeof(
double)) {
52 vout.
crucial(
"ASolver_MG_double must be instanced with double prec. field\n");
59 template<
typename AFIELD>
66 template<
typename AFIELD>
94 set_parameters_level0(params);
97 set_parameters_level1(params_coarse);
102 template<
typename AFIELD>
105 m_params_asolver_outer = params;
110 template<
typename AFIELD>
115 m_nvec = params.
get_int(
"setup_number_of_vectors");
116 m_nsetup = params.
get_int(
"setup_number_of_step");
119 m_smoother_niter = params.
get_int(
"smoother_number_of_iteration");
120 m_smoother_stop_cond = params.
get_double(
"smoother_convergence_criterion_squared");
124 m_params_asolver_coarse = params;
126 set_lattice(m_sap_block_size);
131 template<
typename AFIELD>
135 const std::string& outer_vlevel,
136 const std::vector<int>& sap_block_size,
139 const int coarse_niter,
140 const real_t coarse_stop_cond,
141 const std::string& coarse_vlevel,
142 const int smoother_niter,
143 const real_t smoother_stop_cond)
149 param_level0.
set_int(
"maximum_number_of_iteration", Niter);
150 param_level0.
set_int(
"maximum_number_of_restart", 1);
151 param_level0.
set_double(
"convergence_criterion_squared", Stop_cond);
152 param_level0.
set_string(
"verbose_level", outer_vlevel);
153 set_parameters_level0(param_level0);
160 param_level1.
set_int(
"number_of_vectors", nvec);
162 param_level1.
set_int(
"maximum_number_of_iteration", coarse_niter);
163 param_level1.
set_int(
"maximum_number_of_restart", 1);
164 param_level1.
set_double(
"convergence_criterion_squared",
166 param_level1.
set_string(
"verbose_level", coarse_vlevel);
168 param_level1.
set_int(
"smoother_number_of_iteration", smoother_niter);
169 param_level1.
set_int(
"smoother_convergence_criterion_squared",
172 set_parameters_level1(param_level1);
177 template<
typename AFIELD>
180 m_afopr_fineD =
dynamic_cast<FoprD_t *
>(foprD);
181 if (m_afopr_fineD ==
nullptr) {
182 vout.
crucial(
"%s: bad afopr: only AFopr_Clover is vaild for FoprD]\n",
190 template<
typename AFIELD>
193 m_afopr_fineF =
dynamic_cast<FoprF_t *
>(foprF);
194 if (m_afopr_fineF ==
nullptr) {
195 vout.
crucial(
"%s: bad afopr: only AFopr_Clover is vaild for FoprF]\n",
203 template<
typename AFIELD>
210 if (!m_afopr_fineF) {
211 vout.
crucial(m_vl,
"%s: init_solver, single prec. afopr is not yet set.\n",
215 if (!m_afopr_fineD) {
216 vout.
crucial(m_vl,
"%s: init_solver, double prec. afopr is not yet set.\n",
222 m_afopr_fineD->set_mode(m_mode);
223 m_afopr_fineF->set_mode(m_mode);
229 m_outer_solver.reset(
new OuterSolver_t(m_afopr_fineD, m_prec_mg.get()));
230 m_outer_solver->set_parameters(m_params_asolver_outer);
235 #ifndef SKIP_INIT_COARSE
236 template<
typename AFIELD>
239 vout.
detailed(m_vl,
"%s: init_coarse_grid() [template version] is called\n",
251 multigrid->
init(m_coarse_lattice, fine_lattice, 2 * Nc * Nd, m_nvec);
253 m_multigrid.reset(multigrid);
264 m_afopr_coarse.reset(afopr_coarse);
266 vout.
general(m_vl,
"afopr_coarse version is created\n");
272 m_asolver_coarse.reset(asolver_coarse);
275 #ifdef USE_SAP_FOR_SMOOTHER
277 new Smoother_t(m_afopr_fineF, m_multigrid->get_block_index());
281 asolver_smoother->
set_parameters(m_smoother_niter, m_smoother_stop_cond);
282 m_asolver_smoother.reset(asolver_smoother);
286 m_prec_mg->set_coarse_solver(m_asolver_coarse.get());
287 m_prec_mg->set_smoother(m_asolver_smoother.get());
288 m_prec_mg->set_multigrid(m_multigrid.get());
289 m_prec_mg->set_fopr(m_afopr_fineD, m_afopr_fineF);
296 template<
typename AFIELD>
303 m_coarse_lattice.resize(4);
310 if (sap_block_size.size() != 4) {
311 vout.
crucial(m_vl,
"%s: bad sap_block_size: Must be 4-dim, but the given dimension is %.\n",
312 class_name.c_str(), sap_block_size.size());
316 for (
int i = 0; i < 4; ++i) {
317 m_coarse_lattice[i] = fine_lattice[i] / sap_block_size[i];
318 if (m_coarse_lattice[i] * sap_block_size[i] != fine_lattice[i]) {
319 vout.
crucial(m_vl,
"bad sap_block_size: i=%d, sap_block_size=%d, fine_lattice=%d, coarse_lattice=%d\n",
320 i, sap_block_size[i], fine_lattice[i], m_coarse_lattice[i]);
335 template<
typename AFIELD>
340 Timer timer_setup(
"setup total");
343 const int num_vectors = m_nvec;
344 const int Nin = m_afopr_fineD->field_nin();
345 const int Nvol = m_afopr_fineD->field_nvol();
346 const int Nex = m_afopr_fineD->field_nex();
350 std::vector<AFIELD2> testvec_work(num_vectors);
351 for (
int i = 0; i < num_vectors; ++i) {
352 testvec_work[i].reset(Nin, Nvol, Nex);
355 m_timer_gramschmidt.reset(
new Timer(
"Gramschmidt in the setup"));
356 m_timer_generate_coarse_op.reset(
new Timer(
"generate coarse op"));
358 run_setup_initial(testvec_work);
359 run_setup_iterative(m_nsetup, testvec_work);
363 m_timer_gramschmidt->report();
364 m_timer_generate_coarse_op->report();
365 m_prec_mg->report_timer();
366 m_prec_mg->reset_flop_count();
374 template<
typename AFIELD>
376 std::vector<AFIELD2>& testvec_work)
381 unique_ptr<Timer> timer_initial_setup(
new Timer(
"initial setup"));
383 assert(testvec_work.size() == m_nvec);
387 timer_initial_setup->start();
389 vout.
detailed(
"run_setup: using single precision Gramschmidt\n");
392 m_multigrid->set_testvectors();
397 for (
int i = 0; i < m_nvec; ++i) {
401 asolver_setup->
solve(testvec_work[i],
402 (*m_multigrid->get_testvectors())[i],
408 m_timer_gramschmidt->start();
410 m_multigrid->gramschmidt(testvec_work);
413 m_timer_gramschmidt->stop();
416 m_multigrid->set_testvectors(testvec_work);
421 m_timer_generate_coarse_op->start();
424 *m_multigrid->get_testvectors());
427 m_timer_generate_coarse_op->stop();
429 vout.
general(m_vl,
"afopr_coarse version is ready\n");
433 timer_initial_setup->stop();
434 timer_initial_setup->report();
441 template<
typename AFIELD>
443 std::vector<AFIELD2>& testvec_work)
448 unique_ptr<Timer> timer_setup(
new Timer(
"each setup"));
449 assert(testvec_work.size() == m_nvec);
453 for (
int n = 0; n < niter; ++n) {
456 timer_setup->reset();
457 timer_setup->start();
459 for (
int i = 0; i < m_nvec; ++i) {
461 m_prec_mg->mult_as_setup(testvec_work[i],
462 (*m_multigrid->get_testvectors())[i]);
466 m_timer_gramschmidt->start();
468 m_multigrid->gramschmidt(testvec_work);
471 m_timer_gramschmidt->stop();
473 m_multigrid->set_testvectors(testvec_work);
478 m_timer_generate_coarse_op->start();
481 *m_multigrid->get_testvectors());
484 m_timer_generate_coarse_op->stop();
486 vout.
general(m_vl,
"renewed afopr_coarse: n=%d / %d\n", n, niter);
490 timer_setup->report();
498 template<
typename AFIELD>
502 m_outer_solver->solve(x, b, nconv, diff);
507 template<
typename AFIELD>
511 m_prec_mg->reset_flop_count();
516 template<
typename AFIELD>
519 double flop_solve = m_outer_solver->flop_count();
520 double flop_outer = flop_solve - m_prec_mg->flop_count();
521 double flop_coarse = m_prec_mg->flop_count_coarse();
522 double flop_smoother = m_prec_mg->flop_count_smoother();
523 double flop_other = m_prec_mg->flop_count_other();
524 double flop_double = m_prec_mg->flop_count_double();
525 m_prec_mg->report_timer();
527 vout.
general(m_vl,
"flop count (MG solver) [GFlop]:\n");
528 vout.
general(m_vl,
" solve total (double+float): %e\n", flop_solve * 1.0e-9);
529 vout.
general(m_vl,
" solve coarse (float): %e\n", flop_coarse * 1.0e-9);
530 vout.
general(m_vl,
" solve smoother (float): %e\n", flop_smoother * 1.0e-9);
531 vout.
general(m_vl,
" solve other (float): %e\n", flop_other * 1.0e-9);
532 vout.
general(m_vl,
" solve other (double): %e\n", flop_double * 1.0e-9);