QUDA  1.0.0
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros
dirac_coarse.cpp
Go to the documentation of this file.
1 #include <string.h>
2 #include <multigrid.h>
3 #include <algorithm>
4 
5 namespace quda {
6 
7  DiracCoarse::DiracCoarse(const DiracParam &param, bool gpu_setup, bool mapped) :
8  Dirac(param),
9  mu(param.mu),
10  mu_factor(param.mu_factor),
11  transfer(param.transfer),
12  dirac(param.dirac),
13  need_bidirectional(param.need_bidirectional),
14  Y_h(nullptr),
15  X_h(nullptr),
16  Xinv_h(nullptr),
17  Yhat_h(nullptr),
18  Y_d(nullptr),
19  X_d(nullptr),
20  Xinv_d(nullptr),
21  Yhat_d(nullptr),
22  enable_gpu(false),
23  enable_cpu(false),
24  gpu_setup(gpu_setup),
25  init_gpu(gpu_setup),
26  init_cpu(!gpu_setup),
27  mapped(mapped)
28  {
30  }
31 
33  cpuGaugeField *Yhat_h, // cpu link fields
35  cudaGaugeField *Yhat_d) // gpu link field
36  :
37  Dirac(param),
38  mu(param.mu),
39  mu_factor(param.mu_factor),
40  transfer(nullptr),
41  dirac(nullptr),
42  need_bidirectional(false),
43  Y_h(Y_h),
44  X_h(X_h),
45  Xinv_h(Xinv_h),
46  Yhat_h(Yhat_h),
47  Y_d(Y_d),
48  X_d(X_d),
49  Xinv_d(Xinv_d),
50  Yhat_d(Yhat_d),
51  enable_gpu(Y_d ? true : false),
52  enable_cpu(Y_h ? true : false),
53  gpu_setup(true),
54  init_gpu(enable_gpu ? false : true),
55  init_cpu(enable_cpu ? false : true),
56  mapped(Y_d->MemType() == QUDA_MEMORY_MAPPED)
57  {
58 
59  }
60 
62  Dirac(param),
63  mu(param.mu),
64  mu_factor(param.mu_factor),
65  transfer(param.transfer),
66  dirac(param.dirac),
68  Y_h(dirac.Y_h),
69  X_h(dirac.X_h),
70  Xinv_h(dirac.Xinv_h),
71  Yhat_h(dirac.Yhat_h),
72  Y_d(dirac.Y_d),
73  X_d(dirac.X_d),
74  Xinv_d(dirac.Xinv_d),
75  Yhat_d(dirac.Yhat_d),
76  enable_gpu(dirac.enable_gpu),
77  enable_cpu(dirac.enable_cpu),
78  gpu_setup(dirac.gpu_setup),
79  init_gpu(enable_gpu ? false : true),
80  init_cpu(enable_cpu ? false : true),
81  mapped(dirac.mapped)
82  {
83 
84  }
85 
87  {
88  if (init_cpu) {
89  if (Y_h) delete Y_h;
90  if (X_h) delete X_h;
91  if (Xinv_h) delete Xinv_h;
92  if (Yhat_h) delete Yhat_h;
93  }
94  if (init_gpu) {
95  if (Y_d) delete Y_d;
96  if (X_d) delete X_d;
97  if (Xinv_d) delete Xinv_d;
98  if (Yhat_d) delete Yhat_d;
99  }
100  }
101 
102  void DiracCoarse::createY(bool gpu, bool mapped) const
103  {
104  int ndim = transfer->Vectors().Ndim();
105  int x[QUDA_MAX_DIM];
106  const int *geo_bs = transfer->Geo_bs(); // Number of coarse sites.
107  for (int i = 0; i < ndim; i++) x[i] = transfer->Vectors().X(i)/geo_bs[i];
108  int Nc_c = transfer->nvec(); // Coarse Color
109  int Ns_c = transfer->Vectors().Nspin()/transfer->Spin_bs(); // Coarse Spin
111  memcpy(gParam.x, x, QUDA_MAX_DIM*sizeof(int));
112  gParam.nColor = Nc_c*Ns_c;
115  gParam.link_type = QUDA_COARSE_LINKS;
116  gParam.t_boundary = QUDA_PERIODIC_T;
118  // use null-space precision for coarse links on gpu
120  gParam.nDim = ndim;
123  gParam.nFace = 1;
125  if (mapped) gParam.mem_type = QUDA_MEMORY_MAPPED;
126 
127  int pad = std::max( { (x[0]*x[1]*x[2])/2, (x[1]*x[2]*x[3])/2, (x[0]*x[2]*x[3])/2, (x[0]*x[1]*x[3])/2 } );
128  gParam.pad = gpu ? gParam.nFace * pad * 2 : 0; // factor of 2 since we have to store bi-directional ghost zone
129 
130  if (gpu) Y_d = new cudaGaugeField(gParam);
131  else Y_h = new cpuGaugeField(gParam);
132 
134  gParam.nFace = 0;
136  gParam.pad = 0;
137 
138  if (gpu) X_d = new cudaGaugeField(gParam);
139  else X_h = new cpuGaugeField(gParam);
140  }
141 
142  void DiracCoarse::createYhat(bool gpu) const
143  {
144  int ndim = transfer->Vectors().Ndim();
145  int x[QUDA_MAX_DIM];
146  const int *geo_bs = transfer->Geo_bs(); // Number of coarse sites.
147  for (int i = 0; i < ndim; i++) x[i] = transfer->Vectors().X(i)/geo_bs[i];
148  int Nc_c = transfer->nvec(); // Coarse Color
149  int Ns_c = transfer->Vectors().Nspin()/transfer->Spin_bs(); // Coarse Spin
150 
152  memcpy(gParam.x, x, QUDA_MAX_DIM*sizeof(int));
153  gParam.nColor = Nc_c*Ns_c;
156  gParam.link_type = QUDA_COARSE_LINKS;
157  gParam.t_boundary = QUDA_PERIODIC_T;
159  // use null-space precision for preconditioned links on gpu
161  gParam.nDim = ndim;
164  gParam.nFace = 1;
166 
167  int pad = std::max( { (x[0]*x[1]*x[2])/2, (x[1]*x[2]*x[3])/2, (x[0]*x[2]*x[3])/2, (x[0]*x[1]*x[3])/2 } );
168  gParam.pad = gpu ? gParam.nFace * pad * 2 : 0; // factor of 2 since we have to store bi-directional ghost zone
169 
170  if (gpu) Yhat_d = new cudaGaugeField(gParam);
171  else Yhat_h = new cpuGaugeField(gParam);
172 
173  gParam.setPrecision(gpu ? X_d->Precision() : X_h->Precision());
175  gParam.nFace = 0;
177  gParam.pad = 0;
178 
179  if (gpu) Xinv_d = new cudaGaugeField(gParam);
180  else Xinv_h = new cpuGaugeField(gParam);
181  }
182 
184  {
186 
189 
191 
194 
195  if (gpu_setup) {
196  enable_gpu = true;
197  init_gpu = true;
198  } else {
199  enable_cpu = true;
200  init_cpu = true;
201  }
202  }
203 
204  // we only copy to host or device lazily on demand
206  {
207  if (!enable_cpu && !enable_gpu) errorQuda("Neither CPU or GPU coarse fields initialized");
208  switch(location) {
210  if (enable_gpu) return;
211  createY(true, mapped);
212  createYhat(true);
213  Y_d->copy(*Y_h);
214  Yhat_d->copy(*Yhat_h);
215  X_d->copy(*X_h);
216  Xinv_d->copy(*Xinv_h);
217  enable_gpu = true;
218  init_gpu = true;
219  break;
221  if (enable_cpu) return;
222  createY(false);
223  createYhat(false);
224  Y_h->copy(*Y_d);
225  Yhat_h->copy(*Yhat_d);
226  X_h->copy(*X_d);
227  Xinv_h->copy(*Xinv_d);
228  enable_cpu = true;
229  init_cpu = true;
230  break;
231  default:
232  errorQuda("Unknown location");
233  }
234  }
235 
237  calculateYhat(Yhat, Xinv, Y, X);
238  }
239 
241  {
242  if (&in == &out) errorQuda("Fields cannot alias");
243  QudaFieldLocation location = checkLocation(out,in);
244  initializeLazy(location);
245  if (location == QUDA_CUDA_FIELD_LOCATION) {
246  ApplyCoarse(out, in, in, *Y_d, *X_d, kappa, parity, false, true, dagger, commDim);
247  } else if (location == QUDA_CPU_FIELD_LOCATION) {
248  ApplyCoarse(out, in, in, *Y_h, *X_h, kappa, parity, false, true, dagger, commDim);
249  }
250  int n = in.Nspin()*in.Ncolor();
251  flops += (8*n*n-2*n)*(long long)in.VolumeCB();
252  }
253 
255  {
256  if (&in == &out) errorQuda("Fields cannot alias");
257  QudaFieldLocation location = checkLocation(out,in);
258  initializeLazy(location);
259  if ( location == QUDA_CUDA_FIELD_LOCATION ) {
260  ApplyCoarse(out, in, in, *Y_d, *Xinv_d, kappa, parity, false, true, dagger, commDim);
261  } else if ( location == QUDA_CPU_FIELD_LOCATION ) {
262  ApplyCoarse(out, in, in, *Y_h, *Xinv_h, kappa, parity, false, true, dagger, commDim);
263  }
264  int n = in.Nspin()*in.Ncolor();
265  flops += (8*n*n-2*n)*(long long)in.VolumeCB();
266  }
267 
269  const QudaParity parity) const
270  {
271  QudaFieldLocation location = checkLocation(out,in);
272  initializeLazy(location);
273  if ( location == QUDA_CUDA_FIELD_LOCATION ) {
274  ApplyCoarse(out, in, in, *Y_d, *X_d, kappa, parity, true, false, dagger, commDim, halo_precision);
275  } else if ( location == QUDA_CPU_FIELD_LOCATION ) {
276  ApplyCoarse(out, in, in, *Y_h, *X_h, kappa, parity, true, false, dagger, commDim, halo_precision);
277  }
278  int n = in.Nspin()*in.Ncolor();
279  flops += (8*(8*n*n)-2*n)*(long long)in.VolumeCB()*in.SiteSubset();
280  }
281 
283  const QudaParity parity, const ColorSpinorField &x,
284  const double &k) const
285  {
286  if (k!=1.0) errorQuda("%s not supported for k!=1.0", __func__);
287 
288  QudaFieldLocation location = checkLocation(out,in);
289  initializeLazy(location);
290  if ( location == QUDA_CUDA_FIELD_LOCATION ) {
291  ApplyCoarse(out, in, x, *Y_d, *X_d, kappa, parity, true, true, dagger, commDim, halo_precision);
292  } else if ( location == QUDA_CPU_FIELD_LOCATION ) {
293  ApplyCoarse(out, in, x, *Y_h, *X_h, kappa, parity, true, true, dagger, commDim, halo_precision);
294  }
295  int n = in.Nspin()*in.Ncolor();
296  flops += (9*(8*n*n)-2*n)*(long long)in.VolumeCB()*in.SiteSubset();
297  }
298 
300  {
301  QudaFieldLocation location = checkLocation(out,in);
302  initializeLazy(location);
303  if ( location == QUDA_CUDA_FIELD_LOCATION ) {
304  ApplyCoarse(out, in, in, *Y_d, *X_d, kappa, QUDA_INVALID_PARITY, true, true, dagger, commDim, halo_precision);
305  } else if ( location == QUDA_CPU_FIELD_LOCATION ) {
306  ApplyCoarse(out, in, in, *Y_h, *X_h, kappa, QUDA_INVALID_PARITY, true, true, dagger, commDim, halo_precision);
307  }
308  int n = in.Nspin()*in.Ncolor();
309  flops += (9*(8*n*n)-2*n)*(long long)in.VolumeCB()*in.SiteSubset();
310  }
311 
313  {
314  bool reset1 = newTmp(&tmp1, in);
315  if (tmp1->SiteSubset() != QUDA_FULL_SITE_SUBSET) errorQuda("Temporary vector is not full-site vector");
316 
317  M(*tmp1, in);
318  Mdag(out, *tmp1);
319 
320  deleteTmp(&tmp1, reset1);
321  }
322 
325  const QudaSolutionType solType) const
326  {
327  if (solType == QUDA_MATPC_SOLUTION || solType == QUDA_MATPCDAG_MATPC_SOLUTION) {
328  errorQuda("Preconditioned solution requires a preconditioned solve_type");
329  }
330 
331  src = &b;
332  sol = &x;
333  }
334 
336  const QudaSolutionType solType) const
337  {
338  /* do nothing */
339  }
340 
341  //Make the coarse operator one level down. Pass both the coarse gauge field and coarse clover field.
342  void DiracCoarse::createCoarseOp(GaugeField &Y, GaugeField &X, const Transfer &T, double kappa, double mass, double mu, double mu_factor) const
343  {
344  double a = 2.0 * kappa * mu * T.Vectors().TwistFlavor();
345  if (checkLocation(Y, X) == QUDA_CPU_FIELD_LOCATION) {
347  CoarseCoarseOp(Y, X, T, *(this->Y_h), *(this->X_h), *(this->Xinv_h), kappa, a, mu_factor, QUDA_COARSE_DIRAC,
349  } else {
351  CoarseCoarseOp(Y, X, T, *(this->Y_d), *(this->X_d), *(this->Xinv_d), kappa, a, mu_factor, QUDA_COARSE_DIRAC,
353  }
354  }
355 
357  {
358  /* do nothing */
359  }
360 
362  {
363  /* do nothing */
364  }
365 
367 
369  {
370  QudaFieldLocation location = checkLocation(out,in);
371  initializeLazy(location);
372  if ( location == QUDA_CUDA_FIELD_LOCATION) {
373  ApplyCoarse(out, in, in, *Yhat_d, *X_d, kappa, parity, true, false, dagger, commDim, halo_precision);
374  } else if ( location == QUDA_CPU_FIELD_LOCATION ) {
375  ApplyCoarse(out, in, in, *Yhat_h, *X_h, kappa, parity, true, false, dagger, commDim, halo_precision);
376  }
377 
378  int n = in.Nspin()*in.Ncolor();
379  flops += (8*(8*n*n)-2*n)*in.VolumeCB()*in.SiteSubset();
380  }
381 
383  const ColorSpinorField &x, const double &k) const
384  {
385  // emulated for now
386  Dslash(out, in, parity);
387  blas::xpay(const_cast<ColorSpinorField&>(x), k, out);
388 
389  int n = in.Nspin()*in.Ncolor();
390  flops += (8*(8*n*n)-2*n)*in.VolumeCB(); // blas flops counted separately so only need to count dslash flops
391  }
392 
394  {
395  bool reset1 = newTmp(&tmp1, in);
396 
399  errorQuda("Cannot apply preconditioned operator to full field (subsets = %d %d %d)",
400  in.SiteSubset(), out.SiteSubset(), tmp1->SiteSubset());
401 
403  // DiracCoarsePC::Dslash applies A^{-1}Dslash
404  Dslash(*tmp1, in, QUDA_ODD_PARITY);
405  // DiracCoarse::DslashXpay applies (A - D) // FIXME this ignores the -1
408  blas::xpay(*tmp1, -1.0, out);
410  // DiracCoarsePC::Dslash applies A^{-1}Dslash
412  // DiracCoarse::DslashXpay applies (A - D) // FIXME this ignores the -1
414  Clover(*tmp1, in, QUDA_ODD_PARITY);
415  blas::xpay(*tmp1, -1.0, out);
416  } else if (matpcType == QUDA_MATPC_EVEN_EVEN) {
417  Dslash(*tmp1, in, QUDA_ODD_PARITY);
418  DslashXpay(out, *tmp1, QUDA_EVEN_PARITY, in, -1.0);
419  } else if (matpcType == QUDA_MATPC_ODD_ODD) {
421  DslashXpay(out, *tmp1, QUDA_ODD_PARITY, in, -1.0);
422  } else {
423  errorQuda("MatPCType %d not valid for DiracCoarsePC", matpcType);
424  }
425 
426  deleteTmp(&tmp1, reset1);
427  }
428 
430  {
431  bool reset1 = newTmp(&tmp2, in);
432  M(*tmp2, in);
433  Mdag(out, *tmp2);
434  deleteTmp(&tmp2, reset1);
435  }
436 
438  const QudaSolutionType solType) const
439  {
440  // we desire solution to preconditioned system
441  if (solType == QUDA_MATPC_SOLUTION || solType == QUDA_MATPCDAG_MATPC_SOLUTION) {
442  src = &b;
443  sol = &x;
444  return;
445  }
446 
447  bool reset = newTmp(&tmp1, b.Even());
448 
449  // we desire solution to full system
451  // src = A_ee^-1 (b_e - D_eo A_oo^-1 b_o)
452  src = &(x.Odd());
453  CloverInv(*src, b.Odd(), QUDA_ODD_PARITY);
455  blas::xpay(const_cast<ColorSpinorField&>(b.Even()), -1.0, *tmp1);
457  sol = &(x.Even());
458  } else if (matpcType == QUDA_MATPC_ODD_ODD) {
459  // src = A_oo^-1 (b_o - D_oe A_ee^-1 b_e)
460  src = &(x.Even());
461  CloverInv(*src, b.Even(), QUDA_EVEN_PARITY);
463  blas::xpay(const_cast<ColorSpinorField&>(b.Odd()), -1.0, *tmp1);
464  CloverInv(*src, *tmp1, QUDA_ODD_PARITY);
465  sol = &(x.Odd());
467  // src = b_e - D_eo A_oo^-1 b_o
468  src = &(x.Odd());
471  blas::xpay(const_cast<ColorSpinorField&>(b.Even()), -1.0, *src);
472  sol = &(x.Even());
474  // src = b_o - D_oe A_ee^-1 b_e
475  src = &(x.Even());
478  blas::xpay(const_cast<ColorSpinorField&>(b.Odd()), -1.0, *src);
479  sol = &(x.Odd());
480  } else {
481  errorQuda("MatPCType %d not valid for DiracCloverPC", matpcType);
482  }
483 
484  // here we use final solution to store parity solution and parity source
485  // b is now up for grabs if we want
486 
487  deleteTmp(&tmp1, reset);
488  }
489 
491  {
492  if (solType == QUDA_MATPC_SOLUTION || solType == QUDA_MATPCDAG_MATPC_SOLUTION) {
493  return;
494  }
495 
496  checkFullSpinor(x, b);
497 
498  bool reset = newTmp(&tmp1, b.Even());
499 
500  // create full solution
501 
504  // x_o = A_oo^-1 (b_o - D_oe x_e)
506  blas::xpay(const_cast<ColorSpinorField&>(b.Odd()), -1.0, *tmp1);
508  } else if (matpcType == QUDA_MATPC_ODD_ODD ||
510  // x_e = A_ee^-1 (b_e - D_eo x_o)
512  blas::xpay(const_cast<ColorSpinorField&>(b.Even()), -1.0, *tmp1);
514  } else {
515  errorQuda("MatPCType %d not valid for DiracCoarsePC", matpcType);
516  }
517 
518  deleteTmp(&tmp1, reset);
519  }
520 
521  //Make the coarse operator one level down. For the preconditioned
522  //operator we are coarsening the Yhat links, not the Y links. We
523  //pass the fine clover fields, though they are actually ignored.
524  void DiracCoarsePC::createCoarseOp(GaugeField &Y, GaugeField &X, const Transfer &T, double kappa, double mass, double mu, double mu_factor) const
525  {
526  double a = -2.0 * kappa * mu * T.Vectors().TwistFlavor();
527  if (checkLocation(Y, X) == QUDA_CPU_FIELD_LOCATION) {
529  CoarseCoarseOp(Y, X, T, *(this->Yhat_h), *(this->X_h), *(this->Xinv_h), kappa, a, -mu_factor, QUDA_COARSEPC_DIRAC,
530  matpcType, true);
531  } else {
533  CoarseCoarseOp(Y, X, T, *(this->Yhat_d), *(this->X_d), *(this->Xinv_d), kappa, a, -mu_factor, QUDA_COARSEPC_DIRAC,
534  matpcType, true);
535  }
536  }
537 
538 }
virtual ~DiracCoarse()
QudaTboundary t_boundary
Definition: gauge_field.h:20
QudaGhostExchange ghostExchange
Definition: lattice_field.h:76
unsigned long long flops
Definition: dirac_quda.h:121
void ApplyCoarse(ColorSpinorField &out, const ColorSpinorField &inA, const ColorSpinorField &inB, const GaugeField &Y, const GaugeField &X, double kappa, int parity=QUDA_INVALID_PARITY, bool dslash=true, bool clover=true, bool dagger=false, const int *commDim=0, QudaPrecision halo_precision=QUDA_INVALID_PRECISION)
Apply the coarse dslash stencil. This single driver accounts for all variations with and without the ...
double mu
Definition: test_util.cpp:1648
void prepare(ColorSpinorField *&src, ColorSpinorField *&sol, ColorSpinorField &x, ColorSpinorField &b, const QudaSolutionType) const
void CoarseCoarseOp(GaugeField &Y, GaugeField &X, const Transfer &T, const GaugeField &gauge, const GaugeField &clover, const GaugeField &cloverInv, double kappa, double mu, double mu_factor, QudaDiracType dirac, QudaMatPCType matpc, bool need_bidirectional)
Coarse operator construction from an intermediate-grid operator (Coarse)
cpuGaugeField * X_h
Definition: dirac_quda.h:819
virtual void createCoarseOp(GaugeField &Y, GaugeField &X, const Transfer &T, double kappa, double mass=0., double mu=0., double mu_factor=0.) const
Create the coarse operator (virtual parent)
Definition: dirac_quda.h:196
#define errorQuda(...)
Definition: util_quda.h:121
void CloverInv(ColorSpinorField &out, const ColorSpinorField &in, const QudaParity parity) const
Apply the inverse coarse clover operator.
virtual void checkFullSpinor(const ColorSpinorField &, const ColorSpinorField &) const
Definition: dirac.cpp:146
void M(ColorSpinorField &out, const ColorSpinorField &in) const
Apply the full operator.
void Dslash(ColorSpinorField &out, const ColorSpinorField &in, const QudaParity parity) const
Apply DslashXpay out = (D * in)
const ColorSpinorField & Even() const
void deleteTmp(ColorSpinorField **, const bool &reset) const
Definition: dirac.cpp:81
const ColorSpinorField & Odd() const
cudaGaugeField * Yhat_d
virtual void DslashXpay(ColorSpinorField &out, const ColorSpinorField &in, const QudaParity parity, const ColorSpinorField &x, const double &k) const
Apply DslashXpay out = (D * in + A * x)
const bool need_bidirectional
Definition: dirac_quda.h:816
void createPreconditionedCoarseOp(GaugeField &Yhat, GaugeField &Xinv, const GaugeField &Y, const GaugeField &X)
Create the precondtioned coarse operator.
void createY(bool gpu=true, bool mapped=false) const
Allocate the Y and X fields.
int nvec() const
Definition: transfer.h:218
void createCoarseOp(GaugeField &Y, GaugeField &X, const Transfer &T, double kappa, double mass, double mu, double mu_factor=0.) const
Create the coarse operator from this coarse operator.
void Clover(ColorSpinorField &out, const ColorSpinorField &in, const QudaParity parity) const
Apply the coarse clover operator.
virtual void prepare(ColorSpinorField *&src, ColorSpinorField *&sol, ColorSpinorField &x, ColorSpinorField &b, const QudaSolutionType) const
virtual void MdagM(ColorSpinorField &out, const ColorSpinorField &in) const
QudaSiteSubset siteSubset
Definition: lattice_field.h:71
cpuGaugeField * Y_h
void createCoarseOp(GaugeField &Y, GaugeField &X, const Transfer &T, double kappa, double mass, double mu, double mu_factor=0.) const
Create the coarse even-odd preconditioned coarse operator. Unlike the Wilson operator, the coarsening of the preconditioned coarse operator differs from that of the unpreconditioned coarse operator, so we need to specialize it.
void xpay(ColorSpinorField &x, double a, ColorSpinorField &y)
Definition: blas_quda.h:37
void DslashXpay(ColorSpinorField &out, const ColorSpinorField &in, const QudaParity parity, const ColorSpinorField &x, const double &k) const
Apply DslashXpay out = (D * in + A * x)
QudaGaugeParam param
Definition: pack_test.cpp:17
cudaGaugeField * Y_d
Definition: dirac_quda.h:823
bool newTmp(ColorSpinorField **, const ColorSpinorField &) const
Definition: dirac.cpp:70
static int ndim
Definition: layout_hyper.c:53
void MdagM(ColorSpinorField &out, const ColorSpinorField &in) const
int x[QUDA_MAX_DIM]
Definition: lattice_field.h:67
int commDim[QUDA_MAX_DIM]
Definition: dirac_quda.h:130
virtual void Dslash(ColorSpinorField &out, const ColorSpinorField &in, const QudaParity parity) const
Apply DslashXpay out = (D * in)
cudaGaugeField * Xinv_d
cpuGaugeField * Yhat_h
void reconstruct(ColorSpinorField &x, const ColorSpinorField &b, const QudaSolutionType) const
const Transfer * transfer
Definition: dirac_quda.h:814
void copy(const GaugeField &src)
cpuGaugeField * Xinv_h
const bool gpu_setup
Definition: dirac_quda.h:843
cpuColorSpinorField * in
void initializeCoarse()
Initialize the coarse gauge fields. Location is determined by gpu_setup variable. ...
QudaSiteSubset SiteSubset() const
double mass
Definition: dirac_quda.h:117
QudaGaugeFieldOrder order
Definition: gauge_field.h:17
#define checkLocation(...)
enum QudaSolutionType_s QudaSolutionType
QudaDagType dagger
Definition: dirac_quda.h:120
int Spin_bs() const
Definition: transfer.h:224
int X[4]
Definition: covdev_test.cpp:70
cudaGaugeField * X_d
Definition: dirac_quda.h:824
enum QudaParity_s QudaParity
double Mu() const
Definition: dirac_quda.h:862
double kappa
Definition: dirac_quda.h:116
QudaMatPCType matpcType
Definition: dirac_quda.h:119
void calculateYhat(GaugeField &Yhat, GaugeField &Xinv, const GaugeField &Y, const GaugeField &X)
Calculate preconditioned coarse links and coarse clover inverse field.
cudaGaugeField * X_d
QudaPrecision halo_precision
Definition: dirac_quda.h:125
DiracCoarsePC(const DiracParam &param, bool gpu_setup=true)
const int * Geo_bs() const
Definition: transfer.h:230
void Mdag(ColorSpinorField &out, const ColorSpinorField &in) const
Definition: dirac.cpp:90
QudaPrecision NullPrecision(QudaFieldLocation location) const
The precision of the packed null-space vectors.
Definition: transfer.h:195
enum QudaFieldLocation_s QudaFieldLocation
void setPrecision(QudaPrecision precision, bool force_native=false)
Helper function for setting the precision and corresponding field order for QUDA internal fields...
Definition: gauge_field.h:131
cudaGaugeField * Xinv_d
Definition: dirac_quda.h:825
GaugeCovDev * dirac
Definition: covdev_test.cpp:73
cpuColorSpinorField * out
GaugeFieldParam gParam
virtual void reconstruct(ColorSpinorField &x, const ColorSpinorField &b, const QudaSolutionType) const
cudaGaugeField * Yhat_d
Definition: dirac_quda.h:826
cpuGaugeField * Xinv_h
Definition: dirac_quda.h:820
cpuGaugeField * X_h
QudaLinkType link_type
Definition: gauge_field.h:19
cpuGaugeField * Y_h
Definition: dirac_quda.h:818
QudaMemoryType mem_type
Definition: lattice_field.h:73
cudaGaugeField * Y_d
QudaTwistFlavorType TwistFlavor() const
double mu_factor[QUDA_MAX_MG_LEVEL]
Definition: test_util.cpp:1674
int transfer
Definition: covdev_test.cpp:55
cpuGaugeField * Yhat_h
Definition: dirac_quda.h:821
QudaReconstructType reconstruct
Definition: gauge_field.h:16
QudaFieldCreate create
Definition: gauge_field.h:26
void initializeLazy(QudaFieldLocation location) const
Create the CPU or GPU coarse gauge fields on demand (requires that the fields have been created in th...
const int * X() const
#define QUDA_MAX_DIM
Maximum number of dimensions supported by QUDA. In practice, no routines make use of more than 5...
double MuFactor() const
Definition: dirac_quda.h:863
QudaFieldGeometry geometry
Definition: gauge_field.h:28
virtual void M(ColorSpinorField &out, const ColorSpinorField &in) const
Apply the full operator.
const Dirac * dirac
Definition: dirac_quda.h:815
void createYhat(bool gpu=true) const
Allocate the Yhat and Xinv fields.
void copy(const GaugeField &src)
QudaPrecision Precision() const
QudaParity parity
Definition: covdev_test.cpp:54
ColorSpinorField * tmp2
Definition: dirac_quda.h:123
const ColorSpinorField & Vectors(QudaFieldLocation location=QUDA_INVALID_FIELD_LOCATION) const
Definition: transfer.h:205
DiracCoarse(const DiracParam &param, bool gpu_setup=true, bool mapped=false)
Definition: dirac_coarse.cpp:7
const bool mapped
Definition: dirac_quda.h:846
ColorSpinorField * tmp1
Definition: dirac_quda.h:122