CHROMA
quda_multigrid_params.cc
Go to the documentation of this file.
1 #include "chromabase.h"
2 #include <string>
4 
5 using namespace QDP;
6 
7 namespace Chroma {
8 
9  template<typename T>
10  void readArray(XMLReader& paramtop, const std::string& path, multi1d<T>& array, const T& defValue)
11  {
12 
13  multi1d<T> tmp;
14  // If path is not found use default
15  if ( paramtop.count(path) == 0 ) {
16 
17  QDPIO::cout << "Parameter with " << path << " not found. Setting default value "
18  << defValue << " for " << array.size() << " array members" << std::endl;
19 
20  for(int l=0; l < array.size() ; ++l) array[l] = defValue;
21  }
22  else {
23 
24  // If it is found read it to tmp
25  read(paramtop, path, tmp);
26  if ( tmp.size() == 1 ) {
27  QDPIO::cout << "Broadcasting " << path << " = " << tmp[0] << " to " << array.size() << " array members" << std::endl;
28  // if tmp is a single element array, broadcast it
29  for(int l=0; l < array.size(); ++l) array[l] = tmp[0];
30  }
31  else {
32 
33  // If tmp is the same size as array copy it
34  QDPIO::cout << "Copying " << path << " values to " << array.size() << " members " << std::endl;
35  if ( tmp.size() == array.size() ) {
36  for(int l=0; l < array.size(); ++l) array[l] = tmp[l];
37  }
38  else {
39  QDPIO::cout << "Error: Array with path " << path << "has size "
40  << tmp.size() << " but " << array.size() << " are expected. " << std::endl;
41  QDP_abort(1);
42  }
43  }
44  }
45  }
46 
47  MULTIGRIDSolverParams::MULTIGRIDSolverParams(XMLReader& xml,
48  const std::string& path)
49  {
50  XMLReader paramtop(xml, path);
51 
52 
53  read(paramtop, "Verbosity", verbosity);
54  read(paramtop, "Precision", prec);
55  read(paramtop, "Reconstruct", reconstruct);
56 
57  read(paramtop, "Blocking", blocking);
58  mg_levels = blocking.size()+1;
59 
60 
61 
62 
63 
64  nvec.resize(mg_levels-1);
65  nu_pre.resize(mg_levels-1);
66  nu_post.resize(mg_levels-1);
67  maxIterSubspaceCreate.resize(mg_levels-1);
68  maxIterSubspaceRefresh.resize(mg_levels-1);
69  rsdTargetSubspaceCreate.resize(mg_levels-1);
70 
71  coarseSolverType.resize(mg_levels-1);
72  readArray<QudaSolverType>(paramtop, "CoarseSolverType", coarseSolverType, GCR);
73 
74 
75  tol.resize(mg_levels);
76  readArray<Real>(paramtop, "CoarseResidual", tol, Real(0.0001));
77 
78  maxIterations.resize(mg_levels);
79  readArray<int>(paramtop, "MaxCoarseIterations", maxIterations, 12 );
80 
81  smootherType.resize(mg_levels);
82  readArray<QudaSolverType>(paramtop, "SmootherType", smootherType, MR);
83 
84 
85  smootherTol.resize(mg_levels);
86  readArray<Real>(paramtop, "SmootherTol", smootherTol, Real(0.25));
87 
88  smootherHaloPrecision.resize(mg_levels);
89  readArray<QudaPrecisionType>(paramtop, "SmootherHaloPrecision", smootherHaloPrecision, DEFAULT);
90 
91  smootherSchwarzType.resize(mg_levels);
92  readArray(paramtop, "SmootherSchwarzType", smootherSchwarzType, INVALID_SCHWARZ);
93 
94 
95  smootherSchwarzCycle.resize(mg_levels);
96  readArray(paramtop, "SmootherSchwarzCycle", smootherSchwarzCycle, 1);
97 
98  read(paramtop, "NullVectors", nvec);
99  read(paramtop, "Pre-SmootherApplications", nu_pre);
100  read(paramtop, "Post-SmootherApplications", nu_post);
101  if (nvec.size() != mg_levels-1 ) {
102 
103  QDPIO::cout<<"Warning. There are "<< blocking.size()
104  << " blockings but only " << nvec.size() << " sets of NullVectors" << std::endl;
105  QDP_abort(1);
106  }
107 
108  if (nu_pre.size() != mg_levels-1 ) {
109 
110  QDPIO::cout<<"Error. There are "<< (mg_levels-1)
111  << " blockings but only " << nu_pre.size() << " sets pre-smoothing iterations" << std::endl;
112  QDP_abort(1);
113  }
114 
115  subspaceSolver.resize(mg_levels-1);
116  readArray(paramtop, "SubspaceSolver", subspaceSolver, CG);
117 
118  if( paramtop.count("./RsdTargetSubspaceCreate") == 1 ) {
119  read(paramtop, "RsdTargetSubspaceCreate", rsdTargetSubspaceCreate);
120  }
121  else {
122  // Default values.
123  for(int l=0; l < mg_levels-1; ++l) {
124  rsdTargetSubspaceCreate[l] = 5.0e-6;
125  }
126  }
127 
128  if( paramtop.count("./MaxIterSubspaceCreate") == 1) {
129  read(paramtop, "./MaxIterSubspaceCreate", maxIterSubspaceCreate);
130  }
131  else {
132  for(int l=0; l < mg_levels-1; ++l) {
133  maxIterSubspaceCreate[l] = 500;
134  }
135  }
136 
137  if( paramtop.count("./MaxIterSubspaceRefresh") == 1) {
138  read(paramtop, "./MaxIterSubspaceRefresh", maxIterSubspaceRefresh);
139  }
140  else {
141  for(int l=0; l < mg_levels-1; ++l) {
142  maxIterSubspaceRefresh[l] = maxIterSubspaceCreate[l];
143  }
144  }
145 
146 
147  if( paramtop.count("./OuterGCRNKrylov") == 1 ) {
148  read(paramtop, "OuterGCRNKrylov", outer_gcr_nkrylov);
149  }
150  else {
151  outer_gcr_nkrylov = 12;
152  }
153 
154  if( paramtop.count("./PrecondGCRNKrylov") == 1 ) {
155  read(paramtop, "PrecondGCRNKrylov", precond_gcr_nkrylov);
156  }
157  else {
158  precond_gcr_nkrylov = 12;
159  }
160 
161  if (nu_post.size() != mg_levels-1 ) {
162 
163  QDPIO::cout<<"Warning. There are "<< blocking.size()
164  << " blockings but only " << nu_post.size() << " sets post-smoothing iterations " << std::endl;
165  QDP_abort(1);
166  }
167 
168  read(paramtop, "GenerateNullspace", generate_nullspace);
169 
170  if( paramtop.count("./CheckMultigridSetup") == 1 ) {
171  read(paramtop, "CheckMultigridSetup", check_multigrid_setup);
172  }
173  else {
174  check_multigrid_setup = true; // Default: Checks for suspace and coarss op ar one!
175  }
176 
177  read(paramtop, "GenerateAllLevels", generate_all_levels);
178 
179  //FIXME: Should be an enum
180  read(paramtop, "CycleType", cycle_type);
181 
182 
183  // Read optional params otherwise use defaults
184  if( paramtop.count("SchwarzType") > 0 ) {
185  read(paramtop, "SchwarzType", schwarzType);
186  }
187 
188  relaxationOmegaMG.resize(mg_levels);
189  readArray(paramtop, "RelaxationOmegaMG", relaxationOmegaMG, Real(1.0));
190 
191  // Read optional relaxation param
192  if( paramtop.count("RelaxationOmegaOuter") > 0 ) {
193  read(paramtop, "RelaxationOmegaOuter", relaxationOmegaOuter);
194  }
195  else {
196  relaxationOmegaOuter = Real(1.0);
197  }
198 
199  if(paramtop.count("SetupOnGPU") == 1) {
200  read(paramtop, "SetupOnGPU", setup_on_gpu);
201  if ( setup_on_gpu.size() != mg_levels - 1 ) {
202 
203  // if size != n_levels - 1 then it is an error
204  // unless size is 1 in which case we broadcast it.
205  //
206  if ( setup_on_gpu.size() == 1 ) {
207 
208  // Only one value was entered broadcast it
209  bool value = setup_on_gpu[0];
210  setup_on_gpu.resize(mg_levels-1);
211  for(int l=0; l < mg_levels-1; ++l) {
212  setup_on_gpu[l] = value;
213  }
214  }
215  else {
216  // Size mismatch and size is not 1 error.
217  QDPIO::cerr << "setup_on_gpu has size = " << setup_on_gpu.size() <<
218  " but it should be either 1 (broadcast to all levels) or " << mg_levels -1
219  << " (mg_levels -1) \n";
220  QDP_abort(1);
221  } // setup_on_gpu_size == 1
222  } // setup_on_gpu_size != mg_levels - 1
223  } // paramtop.count("SetupOnGPU") == 1
224  else {
225 
226  // No specification in XML. Default
227  // behaviour is that all levels set up on GPU
228  setup_on_gpu.resize(mg_levels-1);
229  for(int l=0; l < mg_levels-1; ++l) {
230  setup_on_gpu[l] = true;
231  }
232  }
233 
234  }
235 
236  void read(XMLReader& xml, const std::string& path,
238  {
239  MULTIGRIDSolverParams tmp(xml, path);
240  p = tmp;
241  }
242 
243 
244 
245  void write(XMLWriter& xml, const std::string& path,
246  const MULTIGRIDSolverParams& p) {
247  push(xml, path);
248  write(xml, "Residual", p.tol);
249  write(xml, "MaxIterations", p.maxIterations);
250  write(xml, "SmootherType", p.smootherType);
251  if ( p.smootherHaloPrecision[0] != DEFAULT ) {
252  write(xml, "SmootherHaloPrecision", p.smootherHaloPrecision);
253  }
254  write(xml, "RelaxationOmegaMG", p.relaxationOmegaMG);
255  write(xml, "RelaxationOmegaOuter", p.relaxationOmegaOuter);
256  write(xml, "Verbosity", p.verbosity);
257  write(xml, "Precision", p.prec);
258  write(xml, "Reconstruct", p.reconstruct);
259  write(xml, "SchwarzType", p.schwarzType);
260  write(xml, "NullVectors", p.nvec);
261  write(xml, "MultiGridLevels", p.mg_levels);
262  write(xml, "GenerateNullSpace", p.generate_nullspace);
263  write(xml, "GenerateAllLevels", p.generate_all_levels);
264  write(xml, "CheckMultigridSetup", p.check_multigrid_setup);
265  write(xml, "CycleType", p.cycle_type);
266  write(xml, "Pre-SmootherApplications", p.nu_pre);
267  write(xml, "Post-SmootherApplications", p.nu_post);
268  /* FIXME: This should go in the general solver interface, and work for all GCR solvers, not just GCR inner params */
269  write(xml, "OuterGCRNKrylov", p.outer_gcr_nkrylov);
270  write(xml, "PrecondGCRNKrylov", p.precond_gcr_nkrylov);
271  write(xml, "Blocking", p.blocking);
272  write(xml, "MaxIterSubspaceCreate", p.maxIterSubspaceCreate);
273  write(xml, "MaxIterSubspaceRefresh", p.maxIterSubspaceRefresh);
274  write(xml, "RsdTargetSubspaceCreate", p.rsdTargetSubspaceCreate);
275  write(xml, "SetupOnGPU", p.setup_on_gpu);
276  pop(xml);
277 
278  }
279 }
Primary include file for CHROMA library code.
Double tmp
Definition: meslate.cc:60
Asqtad Staggered-Dirac operator.
Definition: klein_gord.cc:10
void read(XMLReader &xml, const std::string &path, MULTIGRIDSolverParams &p)
void readArray(XMLReader &paramtop, const std::string &path, multi1d< T > &array, const T &defValue)
void write(XMLWriter &xml, const std::string &path, const MULTIGRIDSolverParams &p)
LinOpSysSolverMGProtoClover::T T
@ INVALID_SCHWARZ
Definition: enum_quda_io.h:102
::std::string string
Definition: gtest.h:1979
int l
Definition: pade_trln_w.cc:111
push(xml_out,"Cooled_Topology")
pop(xml_out)