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);