QUDA  0.9.0
dirac.cpp
Go to the documentation of this file.
1 #include <dirac_quda.h>
2 #include <dslash_quda.h>
3 #include <blas_quda.h>
4 
5 #include <iostream>
6 
7 namespace quda {
8 
9  // FIXME: At the moment, it's unsafe for more than one Dirac operator to be active unless
10  // they all have the same volume, etc. (used to initialize the various CUDA constants).
11 
13  : gauge(param.gauge), kappa(param.kappa), mass(param.mass), matpcType(param.matpcType),
14  dagger(param.dagger), flops(0), tmp1(param.tmp1), tmp2(param.tmp2), type(param.type),
15  tune(QUDA_TUNE_NO), profile("Dirac", false)
16  {
17  for (int i=0; i<4; i++) commDim[i] = param.commDim[i];
18  }
19 
21  : gauge(dirac.gauge), kappa(dirac.kappa), matpcType(dirac.matpcType),
22  dagger(dirac.dagger), flops(0), tmp1(dirac.tmp1), tmp2(dirac.tmp2), type(dirac.type),
23  tune(QUDA_TUNE_NO), profile("Dirac", false)
24  {
25  for (int i=0; i<4; i++) commDim[i] = dirac.commDim[i];
26  }
27 
30  }
31 
33  {
34  if (&dirac != this) {
35  gauge = dirac.gauge;
36  kappa = dirac.kappa;
37  matpcType = dirac.matpcType;
38  dagger = dirac.dagger;
39  flops = 0;
40  tmp1 = dirac.tmp1;
41  tmp2 = dirac.tmp2;
42  tune = dirac.tune;
43 
44  for (int i=0; i<4; i++) commDim[i] = dirac.commDim[i];
45 
46  profile = dirac.profile;
47 
48  if (type != dirac.type) errorQuda("Trying to copy between incompatible types %d %d", type, dirac.type);
49  }
50  return *this;
51  }
52 
54  if (*tmp) return false;
56  param.create = QUDA_ZERO_FIELD_CREATE; // need to zero elements else padded region will be junk
57 
58  if (typeid(a) == typeid(cudaColorSpinorField)) *tmp = new cudaColorSpinorField(a, param);
59  else *tmp = new cpuColorSpinorField(param);
60 
61  return true;
62  }
63 
64  void Dirac::deleteTmp(ColorSpinorField **a, const bool &reset) const {
65  if (reset) {
66  delete *a;
67  *a = NULL;
68  }
69  }
70 
71 #define flip(x) (x) = ((x) == QUDA_DAG_YES ? QUDA_DAG_NO : QUDA_DAG_YES)
72 
74  {
75  flip(dagger);
76  M(out, in);
77  flip(dagger);
78  }
79 
81  {
82  flip(dagger);
83  MdagM(out, in);
84  flip(dagger);
85  }
86 
87 #undef flip
88 
90  {
91  if ( (in.GammaBasis() != QUDA_UKQCD_GAMMA_BASIS || out.GammaBasis() != QUDA_UKQCD_GAMMA_BASIS) &&
92  in.Nspin() == 4) {
93  errorQuda("CUDA Dirac operator requires UKQCD basis, out = %d, in = %d",
94  out.GammaBasis(), in.GammaBasis());
95  }
96 
97  if (in.Precision() != out.Precision()) {
98  errorQuda("Input precision %d and output spinor precision %d don't match in dslash_quda",
99  in.Precision(), out.Precision());
100  }
101 
102  if (in.Stride() != out.Stride()) {
103  errorQuda("Input %d and output %d spinor strides don't match in dslash_quda",
104  in.Stride(), out.Stride());
105  }
106 
107  if (in.SiteSubset() != QUDA_PARITY_SITE_SUBSET || out.SiteSubset() != QUDA_PARITY_SITE_SUBSET) {
108  errorQuda("ColorSpinorFields are not single parity: in = %d, out = %d",
109  in.SiteSubset(), out.SiteSubset());
110  }
111 
112  if (!static_cast<const cudaColorSpinorField&>(in).isNative()) errorQuda("Input field is not in native order");
113  if (!static_cast<const cudaColorSpinorField&>(out).isNative()) errorQuda("Output field is not in native order");
114 
115  if (out.Ndim() != 5) {
116  if ((out.Volume() != gauge->Volume() && out.SiteSubset() == QUDA_FULL_SITE_SUBSET) ||
117  (out.Volume() != gauge->VolumeCB() && out.SiteSubset() == QUDA_PARITY_SITE_SUBSET) ) {
118  errorQuda("Spinor volume %d doesn't match gauge volume %d", out.Volume(), gauge->VolumeCB());
119  }
120  } else {
121  // Domain wall fermions, compare 4d volumes not 5d
122  if ((out.Volume()/out.X(4) != gauge->Volume() && out.SiteSubset() == QUDA_FULL_SITE_SUBSET) ||
123  (out.Volume()/out.X(4) != gauge->VolumeCB() && out.SiteSubset() == QUDA_PARITY_SITE_SUBSET) ) {
124  errorQuda("Spinor volume %d doesn't match gauge volume %d", out.Volume(), gauge->VolumeCB());
125  }
126  }
127  }
128 
130  {
131  if (in.SiteSubset() != QUDA_FULL_SITE_SUBSET || out.SiteSubset() != QUDA_FULL_SITE_SUBSET) {
132  errorQuda("ColorSpinorFields are not full fields: in = %d, out = %d",
133  in.SiteSubset(), out.SiteSubset());
134  }
135  }
136 
138  if (a.V() == b.V()) errorQuda("Aliasing pointers");
139  }
140 
141  // Dirac operator factory
143  {
144  if (param.type == QUDA_WILSON_DIRAC) {
145  if (getVerbosity() >= QUDA_DEBUG_VERBOSE) printfQuda("Creating a DiracWilson operator\n");
146  return new DiracWilson(param);
147  } else if (param.type == QUDA_WILSONPC_DIRAC) {
148  if (getVerbosity() >= QUDA_DEBUG_VERBOSE) printfQuda("Creating a DiracWilsonPC operator\n");
149  return new DiracWilsonPC(param);
150  } else if (param.type == QUDA_CLOVER_DIRAC) {
151  if (getVerbosity() >= QUDA_DEBUG_VERBOSE) printfQuda("Creating a DiracClover operator\n");
152  return new DiracClover(param);
153  } else if (param.type == QUDA_CLOVERPC_DIRAC) {
154  if (getVerbosity() >= QUDA_DEBUG_VERBOSE) printfQuda("Creating a DiracCloverPC operator\n");
155  return new DiracCloverPC(param);
156  } else if (param.type == QUDA_DOMAIN_WALL_DIRAC) {
157  if (getVerbosity() >= QUDA_DEBUG_VERBOSE) printfQuda("Creating a DiracDomainWall operator\n");
158  return new DiracDomainWall(param);
159  } else if (param.type == QUDA_DOMAIN_WALLPC_DIRAC) {
160  if (getVerbosity() >= QUDA_DEBUG_VERBOSE) printfQuda("Creating a DiracDomainWallPC operator\n");
161  return new DiracDomainWallPC(param);
162  } else if (param.type == QUDA_DOMAIN_WALL_4DPC_DIRAC) {
163  if (getVerbosity() >= QUDA_DEBUG_VERBOSE) printfQuda("Creating a DiracDomainWall4DPC operator\n");
164  return new DiracDomainWall4DPC(param);
165  } else if (param.type == QUDA_MOBIUS_DOMAIN_WALL_DIRAC) {
166  if (getVerbosity() >= QUDA_DEBUG_VERBOSE) printfQuda("Creating a DiracMobius operator\n");
167  return new DiracMobius(param);
169  if (getVerbosity() >= QUDA_DEBUG_VERBOSE) printfQuda("Creating a DiracMobiusPC operator\n");
170  return new DiracMobiusPC(param);
171  } else if (param.type == QUDA_STAGGERED_DIRAC) {
172  if (getVerbosity() >= QUDA_DEBUG_VERBOSE) printfQuda("Creating a DiracStaggered operator\n");
173  return new DiracStaggered(param);
174  } else if (param.type == QUDA_STAGGEREDPC_DIRAC) {
175  if (getVerbosity() >= QUDA_DEBUG_VERBOSE) printfQuda("Creating a DiracStaggeredPC operator\n");
176  return new DiracStaggeredPC(param);
177  } else if (param.type == QUDA_ASQTAD_DIRAC) {
178  if (getVerbosity() >= QUDA_DEBUG_VERBOSE) printfQuda("Creating a DiracImprovedStaggered operator\n");
179  return new DiracImprovedStaggered(param);
180  } else if (param.type == QUDA_ASQTADPC_DIRAC) {
181  if (getVerbosity() >= QUDA_DEBUG_VERBOSE) printfQuda("Creating a DiracImprovedStaggeredPC operator\n");
182  return new DiracImprovedStaggeredPC(param);
183  } else if (param.type == QUDA_TWISTED_CLOVER_DIRAC) {
184  if (getVerbosity() >= QUDA_DEBUG_VERBOSE) printfQuda("Creating a DiracTwistedClover operator (%d flavor(s))\n", param.Ls);
185  if (param.Ls == 1) {
186  return new DiracTwistedClover(param, 4);
187  } else {
188  errorQuda("Cannot create DiracTwistedClover operator for %d flavors\n", param.Ls);
189  }
190  } else if (param.type == QUDA_TWISTED_CLOVERPC_DIRAC) {
191  if (getVerbosity() >= QUDA_DEBUG_VERBOSE) printfQuda("Creating a DiracTwistedCloverPC operator (%d flavor(s))\n", param.Ls);
192  if (param.Ls == 1) {
193  return new DiracTwistedCloverPC(param, 4);
194  } else {
195  errorQuda("Cannot create DiracTwistedCloverPC operator for %d flavors\n", param.Ls);
196  }
197  } else if (param.type == QUDA_TWISTED_MASS_DIRAC) {
198  if (getVerbosity() >= QUDA_DEBUG_VERBOSE) printfQuda("Creating a DiracTwistedMass operator (%d flavor(s))\n", param.Ls);
199  if (param.Ls == 1) return new DiracTwistedMass(param, 4);
200  else return new DiracTwistedMass(param, 5);
201  } else if (param.type == QUDA_TWISTED_MASSPC_DIRAC) {
202  if (getVerbosity() >= QUDA_DEBUG_VERBOSE) printfQuda("Creating a DiracTwistedMassPC operator (%d flavor(s))\n", param.Ls);
203  if (param.Ls == 1) return new DiracTwistedMassPC(param, 4);
204  else return new DiracTwistedMassPC(param, 5);
205  } else if (param.type == QUDA_COARSE_DIRAC) {
206  if (getVerbosity() >= QUDA_DEBUG_VERBOSE) printfQuda("Creating a DiracCoarse operator\n");
207  return new DiracCoarse(param);
208  } else if (param.type == QUDA_COARSEPC_DIRAC) {
209  if (getVerbosity() >= QUDA_DEBUG_VERBOSE) printfQuda("Creating a DiracCoarsePC operator\n");
210  return new DiracCoarsePC(param);
211  } else if (param.type == QUDA_GAUGE_COVDEV_DIRAC) {
212  if (getVerbosity() >= QUDA_DEBUG_VERBOSE) printfQuda("Creating a GaugeCovDev operator\n");
213  return new GaugeCovDev(param);
214  } else if (param.type == QUDA_GAUGE_LAPLACE_DIRAC) {
215  if (getVerbosity() >= QUDA_DEBUG_VERBOSE) printfQuda("Creating a GaugeLaplace operator\n");
216  return new GaugeLaplace(param);
217  } else if (param.type == QUDA_GAUGE_LAPLACEPC_DIRAC) {
218  if (getVerbosity() >= QUDA_DEBUG_VERBOSE) printfQuda("Creating a GaugeLaplacePC operator\n");
219  return new GaugeLaplacePC(param);
220  } else {
221  errorQuda("Unsupported Dirac type %d", param.type);
222  }
223 
224  return nullptr;
225  }
226 
227  // Count the number of stencil applications per dslash application.
229  {
230  int steps = 0;
231  switch (type)
232  {
233  case QUDA_COARSE_DIRAC: // single fused operator
236  steps = 1;
237  break;
238  case QUDA_WILSON_DIRAC:
239  case QUDA_CLOVER_DIRAC:
243  case QUDA_ASQTAD_DIRAC:
246  steps = 2; // For D_{eo} and D_{oe} piece.
247  break;
248  case QUDA_WILSONPC_DIRAC:
249  case QUDA_CLOVERPC_DIRAC:
254  case QUDA_ASQTADPC_DIRAC:
257  case QUDA_COARSEPC_DIRAC:
259  steps = 2;
260  break;
261  default:
262  errorQuda("Unsupported Dslash type %d.\n", type);
263  steps = 0;
264  break;
265  }
266 
267  return steps;
268  }
269 
270 } // namespace quda
Dirac(const DiracParam &param)
Definition: dirac.cpp:12
Even-odd preconditioned Gauge Laplace operator.
Definition: dirac_quda.h:926
QudaDiracType type
Definition: dirac_quda.h:103
unsigned long long flops
Definition: dirac_quda.h:100
QudaVerbosity getVerbosity()
Definition: util_quda.cpp:20
QudaLinkType type
Definition: quda.h:35
#define errorQuda(...)
Definition: util_quda.h:90
#define flip(x)
Definition: dirac.cpp:71
cudaGaugeField * gauge
Definition: dirac_quda.h:95
virtual void checkFullSpinor(const ColorSpinorField &, const ColorSpinorField &) const
Definition: dirac.cpp:129
cudaColorSpinorField * tmp
Definition: covdev_test.cpp:44
void deleteTmp(ColorSpinorField **, const bool &reset) const
Definition: dirac.cpp:64
TimeProfile profile
Definition: dirac_quda.h:112
int getStencilSteps() const
Definition: dirac.cpp:228
virtual ~Dirac()
Definition: dirac.cpp:28
virtual void MdagM(ColorSpinorField &out, const ColorSpinorField &in) const =0
QudaGaugeParam param
Definition: pack_test.cpp:17
bool newTmp(ColorSpinorField **, const ColorSpinorField &) const
Definition: dirac.cpp:53
#define b
int commDim[QUDA_MAX_DIM]
Definition: dirac_quda.h:110
bool tune
VOLATILE spinorFloat kappa
void MMdag(ColorSpinorField &out, const ColorSpinorField &in) const
Definition: dirac.cpp:80
#define tmp2
Definition: tmc_core.h:16
void checkSpinorAlias(const ColorSpinorField &, const ColorSpinorField &) const
Definition: dirac.cpp:137
cpuColorSpinorField * in
void Print()
Definition: timer.cpp:6
QudaTune tune
Definition: dirac_quda.h:108
QudaDagType dagger
Definition: dirac_quda.h:99
int Volume() const
#define tmp1
Definition: tmc_core.h:15
double kappa
Definition: dirac_quda.h:96
QudaMatPCType matpcType
Definition: dirac_quda.h:98
void Mdag(ColorSpinorField &out, const ColorSpinorField &in) const
Definition: dirac.cpp:73
virtual void M(ColorSpinorField &out, const ColorSpinorField &in) const =0
Dirac & operator=(const Dirac &dirac)
Definition: dirac.cpp:32
GaugeCovDev * dirac
Definition: covdev_test.cpp:75
cpuColorSpinorField * out
Full Gauge Laplace operator. Although not a Dirac operator per se, it&#39;s a linear operator so it&#39;s con...
Definition: dirac_quda.h:901
if(err !=cudaSuccess)
#define printfQuda(...)
Definition: util_quda.h:84
int VolumeCB() const
unsigned long long flops
Definition: blas_quda.cu:42
static Dirac * create(const DiracParam &param)
Definition: dirac.cpp:142
virtual void checkParitySpinor(const ColorSpinorField &, const ColorSpinorField &) const
Definition: dirac.cpp:89
Full Covariant Derivative operator. Although not a Dirac operator per se, it&#39;s a linear operator so i...
Definition: dirac_quda.h:948
ColorSpinorField * tmp2
Definition: dirac_quda.h:102
#define a
ColorSpinorField * tmp1
Definition: dirac_quda.h:101