QUDA  v0.5.0
A library for QCD on GPUs
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
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), tune(QUDA_TUNE_NO),
15  verbose(param.verbose)
16  {
17  for (int i=0; i<4; i++) commDim[i] = param.commDim[i];
21  }
22 
24  : gauge(dirac.gauge), kappa(dirac.kappa), matpcType(dirac.matpcType),
25  dagger(dirac.dagger), flops(0), tmp1(dirac.tmp1), tmp2(dirac.tmp2), tune(QUDA_TUNE_NO),
26  verbose(dirac.verbose)
27  {
28  for (int i=0; i<4; i++) commDim[i] = dirac.commDim[i];
32  }
33 
35 
37  {
38  if(&dirac != this) {
39  gauge = dirac.gauge;
40  kappa = dirac.kappa;
41  matpcType = dirac.matpcType;
42  dagger = dirac.dagger;
43  flops = 0;
44  tmp1 = dirac.tmp1;
45  tmp2 = dirac.tmp2;
46  verbose = dirac.verbose;
47 
48  tune = dirac.tune;
49 
50  for (int i=0; i<4; i++) commDim[i] = dirac.commDim[i];
51  }
52  return *this;
53  }
54 
56  if (*tmp) return false;
58  param.create = QUDA_ZERO_FIELD_CREATE; // need to zero elements else padded region will be junk
59  *tmp = new cudaColorSpinorField(a, param);
60  return true;
61  }
62 
63  void Dirac::deleteTmp(cudaColorSpinorField **a, const bool &reset) const {
64  if (reset) {
65  delete *a;
66  *a = NULL;
67  }
68  }
69 
70 #define flip(x) (x) = ((x) == QUDA_DAG_YES ? QUDA_DAG_NO : QUDA_DAG_YES)
71 
73  {
74  flip(dagger);
75  M(out, in);
76  flip(dagger);
77  }
78 
79 #undef flip
80 
82  {
83  if (in.GammaBasis() != QUDA_UKQCD_GAMMA_BASIS ||
85  errorQuda("CUDA Dirac operator requires UKQCD basis, out = %d, in = %d",
86  out.GammaBasis(), in.GammaBasis());
87  }
88 
89  if (in.Precision() != out.Precision()) {
90  errorQuda("Input precision %d and output spinor precision %d don't match in dslash_quda",
91  in.Precision(), out.Precision());
92  }
93 
94  if (in.Stride() != out.Stride()) {
95  errorQuda("Input %d and output %d spinor strides don't match in dslash_quda",
96  in.Stride(), out.Stride());
97  }
98 
100  errorQuda("ColorSpinorFields are not single parity: in = %d, out = %d",
101  in.SiteSubset(), out.SiteSubset());
102  }
103 
104  if (out.Ndim() != 5) {
105  if ((out.Volume() != gauge.Volume() && out.SiteSubset() == QUDA_FULL_SITE_SUBSET) ||
106  (out.Volume() != gauge.VolumeCB() && out.SiteSubset() == QUDA_PARITY_SITE_SUBSET) ) {
107  errorQuda("Spinor volume %d doesn't match gauge volume %d", out.Volume(), gauge.VolumeCB());
108  }
109  } else {
110  // Domain wall fermions, compare 4d volumes not 5d
111  if ((out.Volume()/out.X(4) != gauge.Volume() && out.SiteSubset() == QUDA_FULL_SITE_SUBSET) ||
112  (out.Volume()/out.X(4) != gauge.VolumeCB() && out.SiteSubset() == QUDA_PARITY_SITE_SUBSET) ) {
113  errorQuda("Spinor volume %d doesn't match gauge volume %d", out.Volume(), gauge.VolumeCB());
114  }
115  }
116  }
117 
119  {
121  errorQuda("ColorSpinorFields are not full fields: in = %d, out = %d",
122  in.SiteSubset(), out.SiteSubset());
123  }
124  }
125 
127  if (a.V() == b.V()) errorQuda("Aliasing pointers");
128  }
129 
130  // Dirac operator factory
132  {
133  if (param.type == QUDA_WILSON_DIRAC) {
134  if (param.verbose >= QUDA_VERBOSE) printfQuda("Creating a DiracWilson operator\n");
135  return new DiracWilson(param);
136  } else if (param.type == QUDA_WILSONPC_DIRAC) {
137  if (param.verbose >= QUDA_VERBOSE) printfQuda("Creating a DiracWilsonPC operator\n");
138  return new DiracWilsonPC(param);
139  } else if (param.type == QUDA_CLOVER_DIRAC) {
140  if (param.verbose >= QUDA_VERBOSE) printfQuda("Creating a DiracClover operator\n");
141  return new DiracClover(param);
142  } else if (param.type == QUDA_CLOVERPC_DIRAC) {
143  if (param.verbose >= QUDA_VERBOSE) printfQuda("Creating a DiracCloverPC operator\n");
144  return new DiracCloverPC(param);
145  } else if (param.type == QUDA_DOMAIN_WALL_DIRAC) {
146  if (param.verbose >= QUDA_VERBOSE) printfQuda("Creating a DiracDomainWall operator\n");
147  return new DiracDomainWall(param);
148  } else if (param.type == QUDA_DOMAIN_WALLPC_DIRAC) {
149  if (param.verbose >= QUDA_VERBOSE) printfQuda("Creating a DiracDomainWallPC operator\n");
150  return new DiracDomainWallPC(param);
151  } else if (param.type == QUDA_ASQTAD_DIRAC) {
152  if (param.verbose >= QUDA_VERBOSE) printfQuda("Creating a DiracStaggered operator\n");
153  return new DiracStaggered(param);
154  } else if (param.type == QUDA_ASQTADPC_DIRAC) {
155  if (param.verbose >= QUDA_VERBOSE) printfQuda("Creating a DiracStaggeredPC operator\n");
156  return new DiracStaggeredPC(param);
157  } else if (param.type == QUDA_TWISTED_MASS_DIRAC) {
158  if (param.verbose >= QUDA_VERBOSE) printfQuda("Creating a DiracTwistedMass operator (%d flavor(s))\n", param.Ls);
159  if (param.Ls == 1) return new DiracTwistedMass(param, 4);
160  else return new DiracTwistedMass(param, 5);
161  } else if (param.type == QUDA_TWISTED_MASSPC_DIRAC) {
162  if (param.verbose >= QUDA_VERBOSE) printfQuda("Creating a DiracTwistedMassPC operator (%d flavor(s))\n", param.Ls);
163  if (param.Ls == 1) return new DiracTwistedMassPC(param, 4);
164  else return new DiracTwistedMassPC(param, 5);
165  } else {
166  return 0;
167  }
168  }
169 
170 } // namespace quda