CHROMA
mg_proto_qphix_helpers.cc
Go to the documentation of this file.
1 /*
2  * mg_proto_helpers.cpp
3  *
4  * Created on: Mar 24, 2017
5  * Author: bjoo
6  */
7 #include "chromabase.h"
10 #include "lattice/fine_qdpxx/mg_params_qdpxx.h"
11 #include "lattice/qphix/mg_level_qphix.h"
12 #include "lattice/qphix/vcycle_recursive_qphix.h"
13 #include "lattice/qphix/qphix_clover_linear_operator.h"
14 
15 #include <vector>
16 #include <memory>
17 
18 using std::shared_ptr;
19 using std::make_shared;
20 using std::vector;
21 
22 using namespace QDP;
23 
24 
25 namespace Chroma {
26 namespace MGProtoHelpersQPhiX{
27 
28 template<typename QPhiXLinOpT>
29 shared_ptr<QPhiXLinOpT>
30 createFineLinOpT( const MGProtoSolverParams& params, const multi1d<LatticeColorMatrix>& u,
31  const MG::LatticeInfo& info)
32 {
33  shared_ptr<QPhiXLinOpT> M_fine=nullptr;
34 
35  bool anisoP = params.CloverParams.anisoParam.anisoP;
36  double m_q=toDouble(params.CloverParams.Mass);
37  double u0 = toDouble(params.CloverParams.u0);
38 
39  multi1d<LatticeColorMatrix> working_u(Nd);
40  for(int mu=0; mu < Nd; ++mu) {
41  working_u[mu] = u[mu];
42  }
43 
44  // If the fields are periodic t_bc=1 is fine.
45  int t_bc = 1;
46 
47  // If the fields are supposed to be antiperiodic
48  // then the links will have that multiplied in.
49  // we flop the BC-s off on our copy.
50  if( params.AntiPeriodicT ) {
51 
52  // OK The fields already have antiperiodic BCs applied, but the LinOp Construction
53  // Needs the unmodified fields. So we will flip the BC-s off
54  working_u[Nd-1] *= where(Layout::latticeCoordinate(Nd-1) == (Layout::lattSize()[Nd-1]-1),
55  Integer(-1), Integer(1));
56 
57  t_bc = -1;
58  }
59 
60  if( !anisoP ) {
61  double c_sw=toDouble(params.CloverParams.clovCoeffR);
62  M_fine = make_shared<QPhiXLinOpT>(info,m_q,c_sw,t_bc,working_u);
63  }
64  else {
65  QDPIO::cout << "Using aniso interface" << std::endl;
66 
67  double xi0 = toDouble(params.CloverParams.anisoParam.xi_0);
68  double nu=toDouble(params.CloverParams.anisoParam.nu);
69  double c_sw_r = toDouble(params.CloverParams.clovCoeffR);
70  double c_sw_t = toDouble(params.CloverParams.clovCoeffT);
71  M_fine = make_shared<QPhiXLinOpT>(info,m_q,u0,xi0,nu,c_sw_r,c_sw_t,t_bc,working_u);
72  }
73 
74  return M_fine;
75 }
76 
77 std::shared_ptr<MGPreconditioner::LinOpFT>
78 createFineLinOpF( const MGProtoSolverParams& params, const multi1d<LatticeColorMatrix>& u,
79  const MG::LatticeInfo& info)
80 {
81  return createFineLinOpT<typename MGPreconditioner::LinOpFT>(params,u,info);
82 }
83 
84 std::shared_ptr<MGPreconditioner::LinOpT>
85 createFineLinOp( const MGProtoSolverParams& params, const multi1d<LatticeColorMatrix>& u,
86  const MG::LatticeInfo& info)
87 {
88  return createFineLinOpT<typename MGPreconditioner::LinOpT>(params,u,info);
89 }
90 
91 std::shared_ptr<MGPreconditionerEO::LinOpFT>
92 createFineEOLinOpF( const MGProtoSolverParams& params, const multi1d<LatticeColorMatrix>& u,
93  const MG::LatticeInfo& info)
94 {
95  return createFineLinOpT<typename MGPreconditionerEO::LinOpFT>(params,u,info);
96 }
97 
98 std::shared_ptr<MGPreconditionerEO::LinOpT>
99 createFineEOLinOp( const MGProtoSolverParams& params, const multi1d<LatticeColorMatrix>& u,
100  const MG::LatticeInfo& info)
101 {
102  return createFineLinOpT<typename MGPreconditionerEO::LinOpT>(params,u,info);
103 }
104 
105 template<typename PrecT>
106 void deleteMGPreconditionerT(const std::string& subspaceId)
107 {
108 
109  QDPIO::cout << "Deleting MG_Proto preconditioner with subspaceID=" << subspaceId << std::endl;
110  // Look up in named object map
111  QDPIO::cout << "Looking Up " << subspaceId << " in the Named Onject Map" << std::endl;
112  if( TheNamedObjMap::Instance().check(subspaceId) ) {
113  // Found it... Delete it.
114  QDPIO::cout << " ... Subspace ID found... Deleting" <<std::endl;
115 
116  // This will erase the MGPreconditioner, which has in it shared pointers.
117  // If the shared pointers are destroyed, and there are no references remaining
118  // then MG Levels will be destroyed as weill v_cycle
119  // These only hold allocated data by shared pointer, so they too should be cleaned
120  TheNamedObjMap::Instance().erase(subspaceId);
121  }
122 }
123 
124 void deleteMGPreconditioner(const std::string& subspaceId)
125 {
126  deleteMGPreconditionerT<MGPreconditioner>(subspaceId);
127 }
128 void deleteMGPreconditionerEO(const std::string& subspaceId)
129 {
130  deleteMGPreconditionerT<MGPreconditionerEO>(subspaceId);
131 }
132 
133 template<typename PrecT>
134 void
135 createMGPreconditionerT( const MGProtoSolverParams& params, const multi1d<LatticeColorMatrix>& u)
136 {
137  START_CODE();
138  StopWatch swatch;
139  swatch.reset();
140  swatch.start();
141 
142  const std::string& subspaceId = params.SubspaceId;
143  QDPIO::cout << "Creating MG_Proto preconditioner with subspaceID=" << subspaceId << std::endl;
144  // Look up in named object map
145  QDPIO::cout << "Looking Up " << subspaceId << " in the Named Onject Map" << std::endl;
146  if( TheNamedObjMap::Instance().check(subspaceId) ) {
147  // Found it... Delete it.
148  QDPIO::cout << " ... Subspace ID found... Deleting" <<std::endl;
149  deleteMGPreconditionerT<PrecT>(subspaceId);
150  }
151 
152 
153  // Now make a new one.
154  shared_ptr<typename PrecT::LevelT> mg_levels = make_shared<typename PrecT::LevelT>();
155 
156  // First make an info from the lattice parameters:
157  IndexArray latdims = {{ QDP::Layout::subgridLattSize()[0],
158  QDP::Layout::subgridLattSize()[1],
159  QDP::Layout::subgridLattSize()[2],
160  QDP::Layout::subgridLattSize()[3] }};
161 
162  (mg_levels->fine_level).info = std::make_shared<LatticeInfo>( latdims, 4,3,NodeInfo());
163 
164  // First make M
165  QDPIO::cout << "Creating M..." ;
166  shared_ptr<typename PrecT::LinOpT> M=createFineLinOpT<typename PrecT::LinOpT>( params, u, *((mg_levels->fine_level).info) );
167  QDPIO::cout << "Done" << std::endl;
168 
169  QDPIO::cout << "Creating single prec M...";
170  shared_ptr<typename PrecT::LinOpFT> M_f=createFineLinOpT<typename PrecT::LinOpFT>( params, u, *((mg_levels->fine_level).info) );
171  QDPIO::cout << "Done" << std::endl;
172 
173  QDPIO::cout << "Creating MG Levels ... " ;
174  MG::SetupParams level_params;
175  int n_levels = params.MGLevels;
176  level_params.n_levels = n_levels;
177  level_params.n_vecs.resize(n_levels-1);
178  level_params.null_solver_max_iter.resize(n_levels-1);
179  level_params.null_solver_rsd_target.resize(n_levels -1);
180  level_params.null_solver_verboseP.resize(n_levels -1);
181  for(int l=0; l < n_levels-1;++l) {
182  QDPIO::cout << "Level L=" << l << " Null Vecs=" << params.NullVecs[l] << std::endl;
183 
184  level_params.n_vecs[l] = params.NullVecs[l];
185  level_params.null_solver_max_iter[l]=params.NullSolverMaxIters[l];
186  level_params.null_solver_rsd_target[l]=toDouble(params.NullSolverRsdTarget[l]);
187  level_params.null_solver_verboseP[l]=toDouble(params.NullSolverVerboseP[l]);
188  }
189  level_params.block_sizes.resize(n_levels-1);
190  for(int l=0; l < n_levels-1;++l) {
191  for(int mu=0; mu < 4; ++mu) {
192  (level_params.block_sizes[l])[mu] = (params.Blocking[l])[mu];
193  }
194  }
195 
196  MG::SetupQPhiXMGLevels(level_params, *mg_levels, M_f );
197  QDPIO::cout << "... Done " << std::endl;
198 
199  if( (mg_levels->fine_level).M == nullptr ) {
200  QDPIO::cout << "Error... Barfaroni. Fine Level M is null after subspace setup" << std::endl;
201  QDP_abort(1);
202  }
203 
204  QDPIO::cout << "Creating VCycle Parameters..." << std::endl;
205  vector<MG::VCycleParams> v_params(n_levels-1);
206  for(int l=0; l < n_levels-1;++l) {
207  QDPIO::cout << " Level " << l << std::endl;
208  v_params[l].pre_smoother_params.MaxIter=params.VCyclePreSmootherMaxIters[l];
209  v_params[l].pre_smoother_params.RsdTarget=toDouble(params.VCyclePreSmootherRsdTarget[l]);
210  v_params[l].pre_smoother_params.VerboseP =params.VCyclePreSmootherVerboseP[l];
211  v_params[l].pre_smoother_params.Omega =toDouble(params.VCyclePreSmootherRelaxOmega[l]);
212 
213  v_params[l].post_smoother_params.MaxIter=params.VCyclePostSmootherMaxIters[l];
214  v_params[l].post_smoother_params.RsdTarget=toDouble(params.VCyclePostSmootherRsdTarget[l]);
215  v_params[l].post_smoother_params.VerboseP =params.VCyclePostSmootherVerboseP[l];
216  v_params[l].post_smoother_params.Omega =toDouble(params.VCyclePostSmootherRelaxOmega[l]);
217 
218  v_params[l].bottom_solver_params.MaxIter=params.VCycleBottomSolverMaxIters[l];
219  v_params[l].bottom_solver_params.NKrylov = params.VCycleBottomSolverNKrylov[l];
220  v_params[l].bottom_solver_params.RsdTarget= toDouble(params.VCycleBottomSolverRsdTarget[l]);
221  v_params[l].bottom_solver_params.VerboseP = params.VCycleBottomSolverVerboseP[l];
222 
223  v_params[l].cycle_params.MaxIter=params.VCycleMaxIters[l];
224  v_params[l].cycle_params.RsdTarget=toDouble(params.VCycleRsdTarget[l]);
225  v_params[l].cycle_params.VerboseP = params.VCycleVerboseP[l];
226  }
227 
228  QDPIO::cout << "Creating VCycle Preconditioner...";
229 
230  shared_ptr<typename PrecT::VCycleT> v_cycle=make_shared<typename PrecT::VCycleT>(v_params, *mg_levels);
231 
232  QDPIO::cout << "Done";
233 
234  QDPIO::cout << "Saving in Map" << std::endl;
235  QDPIO::cout << "Creating Named Object Map Entry for subspace" << std::endl;
236  XMLBufferWriter file_xml;
237  push(file_xml, "FileXML");
238  pop(file_xml);
239 
240  XMLBufferWriter record_xml;
241  push(record_xml, "RecordXML");
242  write(record_xml, "InvertParam", params);
243  pop(record_xml);
244 
245  TheNamedObjMap::Instance().create<shared_ptr<PrecT>>(subspaceId);
246  TheNamedObjMap::Instance().get(subspaceId).setFileXML(file_xml);
247  TheNamedObjMap::Instance().get(subspaceId).setRecordXML(record_xml);
248  TheNamedObjMap::Instance().getData<shared_ptr<PrecT>>(subspaceId)=make_shared<PrecT>();
249  TheNamedObjMap::Instance().getData<shared_ptr<PrecT>>(subspaceId)->mg_levels = mg_levels;
250  TheNamedObjMap::Instance().getData<shared_ptr<PrecT>>(subspaceId)->v_cycle = v_cycle;
251  TheNamedObjMap::Instance().getData<shared_ptr<PrecT>>(subspaceId)->M = M;
252 
253  swatch.stop();
254  QDPIO::cout << "MG_PROTO_QPHIX_SETUP: Subspace Creation Took : " << swatch.getTimeInSeconds() << " sec" << std::endl;
255 
256  END_CODE();
257 }
258 
259 void
260 createMGPreconditioner( const MGProtoSolverParams& params, const multi1d<LatticeColorMatrix>& u)
261 {
262  createMGPreconditionerT<MGPreconditioner>(params,u);
263 }
264 
265 
266 void
267 createMGPreconditionerEO( const MGProtoSolverParams& params, const multi1d<LatticeColorMatrix>& u)
268 {
269  createMGPreconditionerT<MGPreconditionerEO>(params,u);
270 }
271 
272 
273 
274 template<typename PrecT>
275 shared_ptr<PrecT> getMGPreconditionerT(const std::string& subspaceId)
276 {
277  shared_ptr<PrecT> ret_val = nullptr;
278  if( TheNamedObjMap::Instance().check(subspaceId) ) {
279  // Found it... Delete it.
280  QDPIO::cout << " ... Subspace ID found... returning" <<std::endl;
281 
282  // This will erase the MGPreconditioner, which has in it shared pointers.
283  // If the shared pointers are destroyed, and there are no references remaining
284  // then MG Levels will be destroyed as weill v_cycle
285  // These only hold allocated data by shared pointer so they too should be cleaned
286  ret_val = TheNamedObjMap::Instance().getData<shared_ptr<PrecT>>(subspaceId);
287 
288  }
289  else {
290  QDPIO::cout << "Object Not Found... Returning Null" << std::endl;
291  ret_val = nullptr;
292 
293  }
294  return ret_val;
295 
296 }
297 
298 shared_ptr<MGPreconditioner> getMGPreconditioner(const std::string& subspaceId)
299  {
300  return getMGPreconditionerT<MGPreconditioner>(subspaceId);
301  }
302 
303 
304 shared_ptr<MGPreconditionerEO> getMGPreconditionerEO(const std::string& subspaceId)
305  {
306  return getMGPreconditionerT<MGPreconditionerEO>(subspaceId);
307  }
308 
309 
310 }
311 
312 }
Primary include file for CHROMA library code.
#define END_CODE()
Definition: chromabase.h:65
#define START_CODE()
Definition: chromabase.h:64
Real u0
int mu
Definition: cool.cc:24
int nu
Definition: cool.cc:25
void write(XMLWriter &xml, const std::string &path, const AsqtadFermActParams &param)
Writer parameters.
Params params
Nd
Definition: meslate.cc:74
Named object function std::map.
std::shared_ptr< MGPreconditionerEO::LinOpFT > createFineEOLinOpF(const MGProtoSolverParams &params, const multi1d< LatticeColorMatrix > &u, const MG::LatticeInfo &info)
shared_ptr< PrecT > getMGPreconditionerT(const std::string &subspaceId)
void createMGPreconditioner(const MGProtoSolverParams &params, const multi1d< LatticeColorMatrix > &u)
void deleteMGPreconditionerT(const std::string &subspaceId)
shared_ptr< MGPreconditionerEO > getMGPreconditionerEO(const std::string &subspaceId)
shared_ptr< QPhiXLinOpT > createFineLinOpT(const MGProtoSolverParams &params, const multi1d< LatticeColorMatrix > &u, const MG::LatticeInfo &info)
void deleteMGPreconditionerEO(const std::string &subspaceId)
void createMGPreconditionerT(const MGProtoSolverParams &params, const multi1d< LatticeColorMatrix > &u)
std::shared_ptr< MGPreconditioner::LinOpFT > createFineLinOpF(const MGProtoSolverParams &params, const multi1d< LatticeColorMatrix > &u, const MG::LatticeInfo &info)
void deleteMGPreconditioner(const std::string &subspaceId)
std::shared_ptr< MGPreconditioner::LinOpT > createFineLinOp(const MGProtoSolverParams &params, const multi1d< LatticeColorMatrix > &u, const MG::LatticeInfo &info)
shared_ptr< MGPreconditioner > getMGPreconditioner(const std::string &subspaceId)
std::shared_ptr< MGPreconditionerEO::LinOpT > createFineEOLinOp(const MGProtoSolverParams &params, const multi1d< LatticeColorMatrix > &u, const MG::LatticeInfo &info)
void createMGPreconditionerEO(const MGProtoSolverParams &params, const multi1d< LatticeColorMatrix > &u)
Asqtad Staggered-Dirac operator.
Definition: klein_gord.cc:10
static multi1d< LatticeColorMatrix > u
static bool anisoP()
Definition: grelax.cc:17
static QOP_info_t info
::std::string string
Definition: gtest.h:1979
int l
Definition: pade_trln_w.cc:111
push(xml_out,"Cooled_Topology")
pop(xml_out)