18 template<
typename AFIELD>
42 template<
typename AFIELD>
47 if (size !=
sizeof(
double)) {
48 vout.
crucial(
"ASolver_MG must be instanced with double prec. field\n");
55 template<
typename AFIELD>
62 template<
typename AFIELD>
90 set_parameters_level0(params);
93 set_parameters_level1(params_coarse);
98 template<
typename AFIELD>
101 m_params_asolver_outer = params;
106 template<
typename AFIELD>
111 m_nvec = params.
get_int(
"setup_number_of_vectors");
112 m_nsetup = params.
get_int(
"setup_number_of_step");
115 m_smoother_niter = params.
get_int(
"smoother_number_of_iteration");
116 m_smoother_stop_cond = params.
get_double(
"smoother_convergence_criterion_squared");
120 m_params_asolver_coarse = params;
122 set_lattice(m_sap_block_size);
127 template<
typename AFIELD>
131 const std::string& outer_vlevel,
132 const std::vector<int>& sap_block_size,
135 const int coarse_niter,
136 const real_t coarse_stop_cond,
137 const std::string& coarse_vlevel,
138 const int smoother_niter,
139 const real_t smoother_stop_cond)
145 param_level0.
set_int(
"maximum_number_of_iteration", Niter);
146 param_level0.
set_int(
"maximum_number_of_restart", 1);
147 param_level0.
set_double(
"convergence_criterion_squared", Stop_cond);
148 param_level0.
set_string(
"verbose_level", outer_vlevel);
149 set_parameters_level0(param_level0);
156 param_level1.
set_int(
"number_of_vectors", nvec);
158 param_level1.
set_int(
"maximum_number_of_iteration", coarse_niter);
159 param_level1.
set_int(
"maximum_number_of_restart", 1);
160 param_level1.
set_double(
"convergence_criterion_squared",
162 param_level1.
set_string(
"verbose_level", coarse_vlevel);
164 param_level1.
set_int(
"smoother_number_of_iteration", smoother_niter);
165 param_level1.
set_int(
"smoother_convergence_criterion_squared",
168 set_parameters_level1(param_level1);
173 template<
typename AFIELD>
176 #ifdef USE_FOPR_FOR_SMOOTHER
185 template<
typename AFIELD>
188 #ifdef USE_FOPR_FOR_SMOOTHER
189 return new FoprSmoother_t(param);
197 template<
typename AFIELD>
203 m_afopr_fineD =
dynamic_cast<FoprD_t *
>(foprD);
206 if (m_afopr_fineD ==
nullptr) {
207 vout.
crucial(
"%s: bad afopr: only AFopr_Clover is vaild for FoprD]\n",
215 template<
typename AFIELD>
218 m_afopr_fineF =
dynamic_cast<FoprF_t *
>(foprF);
219 if (m_afopr_fineF ==
nullptr) {
220 vout.
crucial(
"%s: bad afopr: only AFopr_Clover_dd is vaild for FoprF]\n",
224 #ifndef USE_FOPR_FOR_SMOOTHER
225 m_afopr_smoother = m_afopr_fineF;
231 template<
typename AFIELD>
234 #ifdef USE_FOPR_FOR_SMOOTHER
235 m_afopr_smoother =
dynamic_cast<FoprSmoother_t *
>(foprF);
236 if (m_afopr_fineF ==
nullptr) {
237 vout.
crucial(
"%s: bad afopr: only AFopr_Clover_dd is vaild for Fopr smoother]\n",
242 vout.
general(
"%s: set_foprF_smoother is called but ignored. The same one given with set_foprF will be used.\n", class_name.c_str());
248 template<
typename AFIELD>
255 if (!m_afopr_fineF) {
256 vout.
crucial(m_vl,
"%s: init_solver, single prec. afopr is not yet set.\n",
260 if (!m_afopr_fineD) {
261 vout.
crucial(m_vl,
"%s: init_solver, double prec. afopr is not yet set.\n",
267 m_afopr_fineD->set_mode(m_mode);
268 m_afopr_fineF->set_mode(m_mode);
274 m_outer_solver.reset(
new OuterSolver_t(m_afopr_fineD, m_prec_mg.get()));
275 m_outer_solver->set_parameters(m_params_asolver_outer);
280 #ifndef SKIP_INIT_COARSE
281 template<
typename AFIELD>
284 vout.
detailed(m_vl,
"%s: init_coarse_grid() [template version] is called\n",
296 multigrid->
init(m_coarse_lattice, fine_lattice, 2 * Nc * Nd, m_nvec);
298 m_multigrid.reset(multigrid);
309 m_afopr_coarse.reset(afopr_coarse);
311 vout.
general(m_vl,
"afopr_coarse version is created\n");
317 m_asolver_coarse.reset(asolver_coarse);
320 #ifdef USE_SAP_FOR_SMOOTHER
322 new Smoother_t(m_afopr_smoother, m_multigrid->get_block_index());
326 asolver_smoother->
set_parameters(m_smoother_niter, m_smoother_stop_cond);
327 m_asolver_smoother.reset(asolver_smoother);
331 m_prec_mg->set_coarse_solver(m_asolver_coarse.get());
332 m_prec_mg->set_smoother(m_asolver_smoother.get());
333 m_prec_mg->set_multigrid(m_multigrid.get());
334 m_prec_mg->set_fopr(m_afopr_fineD, m_afopr_fineF);
341 template<
typename AFIELD>
348 m_coarse_lattice.resize(4);
355 if (sap_block_size.size() != 4) {
356 vout.
crucial(m_vl,
"%s: bad sap_block_size: Must be 4-dim, but the given dimension is %.\n",
357 class_name.c_str(), sap_block_size.size());
361 for (
int i = 0; i < 4; ++i) {
362 m_coarse_lattice[i] = fine_lattice[i] / sap_block_size[i];
363 if (m_coarse_lattice[i] * sap_block_size[i] != fine_lattice[i]) {
364 vout.
crucial(m_vl,
"bad sap_block_size: i=%d, sap_block_size=%d, fine_lattice=%d, coarse_lattice=%d\n",
365 i, sap_block_size[i], fine_lattice[i], m_coarse_lattice[i]);
380 template<
typename AFIELD>
383 assert(m_nvec == testvec_work.size());
385 Timer timer_setup(
"setup total (work vectors given)");
389 m_timer_gramschmidt.reset(
new Timer(
"Gramschmidt in the setup"));
390 m_timer_generate_coarse_op.reset(
new Timer(
"generate coarse op"));
393 run_setup_initial(testvec_work);
394 run_setup_iterative(m_nsetup, testvec_work);
400 m_timer_gramschmidt->report();
401 m_timer_generate_coarse_op->report();
402 m_prec_mg->report_timer();
403 m_prec_mg->reset_flop_count();
411 template<
typename AFIELD>
416 Timer timer_setup(
"setup total");
419 const int num_vectors = m_nvec;
420 const int Nin = m_afopr_fineD->field_nin();
421 const int Nvol = m_afopr_fineD->field_nvol();
422 const int Nex = m_afopr_fineD->field_nex();
426 std::vector<AFIELD_f> testvec_work(num_vectors);
427 for (
int i = 0; i < num_vectors; ++i) {
428 testvec_work[i].reset(Nin, Nvol, Nex);
432 run_setup(testvec_work);
440 template<
typename AFIELD>
442 std::vector<AFIELD_f>& testvec_work)
449 vout.
detailed(
"run_setup: using single precision Gramschmidt\n");
452 assert(testvec_work.size() == m_nvec);
453 unique_ptr<Timer> timer_initial_setup;
456 timer_initial_setup.reset(
new Timer(
"initial setup"));
457 timer_initial_setup->start();
464 m_multigrid->set_testvectors();
468 for (
int i = 0; i < m_nvec; ++i) {
471 asolver_setup->
solve(testvec_work[i],
472 (*m_multigrid->get_testvectors())[i],
477 m_timer_gramschmidt->start();
479 m_multigrid->gramschmidt(testvec_work);
482 m_timer_gramschmidt->stop();
484 m_multigrid->set_testvectors(testvec_work);
490 m_timer_generate_coarse_op->start();
493 *m_multigrid->get_testvectors());
496 m_timer_generate_coarse_op->stop();
498 vout.
general(m_vl,
"afopr_coarse version is ready\n");
502 timer_initial_setup->stop();
503 timer_initial_setup->report();
510 template<
typename AFIELD>
512 std::vector<AFIELD_f>& testvec_work)
523 assert(testvec_work.size() == m_nvec);
524 unique_ptr<Timer> timer_setup;
527 timer_setup.reset(
new Timer(
"each setup"));
529 for (
int n = 0; n < niter; ++n) {
532 timer_setup->reset();
533 timer_setup->start();
535 for (
int i = 0; i < m_nvec; ++i) {
537 m_prec_mg->mult_as_setup(testvec_work[i],
538 (*m_multigrid->get_testvectors())[i]);
545 m_timer_gramschmidt->start();
547 m_multigrid->gramschmidt(testvec_work);
550 m_timer_gramschmidt->stop();
552 m_multigrid->set_testvectors(testvec_work);
557 m_timer_generate_coarse_op->start();
560 *m_multigrid->get_testvectors());
563 m_timer_generate_coarse_op->stop();
565 vout.
general(m_vl,
"renewed afopr_coarse: n=%d / %d\n", n, niter);
569 timer_setup->report();
577 template<
typename AFIELD>
581 m_outer_solver->solve(x, b, nconv, diff);
586 template<
typename AFIELD>
590 m_prec_mg->reset_flop_count();
595 template<
typename AFIELD>
598 double flop_solve = m_outer_solver->flop_count();
599 double flop_outer = flop_solve - m_prec_mg->flop_count();
600 double flop_coarse = m_prec_mg->flop_count_coarse();
601 double flop_smoother = m_prec_mg->flop_count_smoother();
602 double flop_other = m_prec_mg->flop_count_other();
603 double flop_double = m_prec_mg->flop_count_double();
604 m_prec_mg->report_timer();
606 vout.
general(m_vl,
"flop count (MG solver) [GFlop]:\n");
607 vout.
general(m_vl,
" solve total (double+float): %e\n", flop_solve * 1.0e-9);
608 vout.
general(m_vl,
" solve coarse (float): %e\n", flop_coarse * 1.0e-9);
609 vout.
general(m_vl,
" solve smoother (float): %e\n", flop_smoother * 1.0e-9);
610 vout.
general(m_vl,
" solve other (float): %e\n", flop_other * 1.0e-9);
611 vout.
general(m_vl,
" solve other (double): %e\n", flop_double * 1.0e-9);