QUDA  v0.7.0
A library for QCD on GPUs
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
dirac_clover.cpp
Go to the documentation of this file.
1 #include <iostream>
2 #include <dirac_quda.h>
3 #include <blas_quda.h>
4 
5 namespace quda {
6 
7  namespace clover {
8 #include <dslash_init.cuh>
9  }
10 
11  namespace asym_clover {
12 #include <dslash_init.cuh>
13  }
14 
16  : DiracWilson(param), clover(*(param.clover))
17  {
18  clover::initConstants(*param.gauge, profile);
19  asym_clover::initConstants(*param.gauge, profile);
20  }
21 
23  : DiracWilson(dirac), clover(dirac.clover)
24  {
25  clover::initConstants(dirac.gauge, profile);
26  asym_clover::initConstants(dirac.gauge, profile);
27  }
28 
30 
32  {
33  if (&dirac != this) {
35  clover = dirac.clover;
36  }
37  return *this;
38  }
39 
41  {
42  Dirac::checkParitySpinor(out, in);
43 
44  if (out.Volume() != clover.VolumeCB()) {
45  errorQuda("Parity spinor volume %d doesn't match clover checkboard volume %d",
46  out.Volume(), clover.VolumeCB());
47  }
48  }
49 
53  const double &k) const
54  {
55  asym_clover::setFace(face1,face2); // FIXME: temporary hack maintain C linkage for dslashCuda
56 
57  checkParitySpinor(in, out);
58  checkSpinorAlias(in, out);
59 
60  FullClover cs(clover);
61  asymCloverDslashCuda(&out, gauge, cs, &in, parity, dagger, &x, k, commDim, profile);
62 
63  flops += 1872ll*in.Volume();
64  }
65 
66  // Public method to apply the clover term only
68  {
69  checkParitySpinor(in, out);
70 
71  // regular clover term
72  FullClover cs(clover);
73  cloverCuda(&out, gauge, cs, &in, parity);
74 
75  flops += 504ll*in.Volume();
76  }
77 
79  {
80  checkFullSpinor(out, in);
81  DslashXpay(out.Odd(), in.Even(), QUDA_ODD_PARITY, in.Odd(), -kappa);
82  DslashXpay(out.Even(), in.Odd(), QUDA_EVEN_PARITY, in.Even(), -kappa);
83  }
84 
86  {
87  checkFullSpinor(out, in);
88 
89  bool reset = newTmp(&tmp1, in);
90  checkFullSpinor(*tmp1, in);
91 
92  M(*tmp1, in);
93  Mdag(out, *tmp1);
94 
95  deleteTmp(&tmp1, reset);
96  }
97 
100  const QudaSolutionType solType) const
101  {
102  if (solType == QUDA_MATPC_SOLUTION || solType == QUDA_MATPCDAG_MATPC_SOLUTION) {
103  errorQuda("Preconditioned solution requires a preconditioned solve_type");
104  }
105 
106  src = &b;
107  sol = &x;
108  }
109 
111  const QudaSolutionType solType) const
112  {
113  // do nothing
114  }
115 
117  DiracClover(param)
118  {
119  // For the preconditioned operator, we need to check that the inverse of the clover term is present
120  if (!clover.cloverInv) errorQuda("Clover inverse required for DiracCloverPC");
121  }
122 
124 
126 
128  {
129  if (&dirac != this) {
130  DiracClover::operator=(dirac);
131  }
132  return *this;
133  }
134 
135  // Public method
137  const QudaParity parity) const
138  {
139  checkParitySpinor(in, out);
140 
141  // needs to be cloverinv
142  FullClover cs(clover, true);
143  cloverCuda(&out, gauge, cs, &in, parity);
144 
145  flops += 504ll*in.Volume();
146  }
147 
148  // apply hopping term, then clover: (A_ee^-1 D_eo) or (A_oo^-1 D_oe),
149  // and likewise for dagger: (A_ee^-1 D^dagger_eo) or (A_oo^-1 D^dagger_oe)
150  // NOTE - this isn't Dslash dagger since order should be reversed!
152  const QudaParity parity) const
153  {
154  clover::setFace(face1,face2); // FIXME: temporary hack maintain C linkage for dslashCuda
155 
156  checkParitySpinor(in, out);
157  checkSpinorAlias(in, out);
158 
159  FullClover cs(clover, true);
160  cloverDslashCuda(&out, gauge, cs, &in, parity, dagger, 0, 0.0, commDim, profile);
161 
162  flops += 1824ll*in.Volume();
163  }
164 
165  // xpay version of the above
167  const QudaParity parity, const cudaColorSpinorField &x,
168  const double &k) const
169  {
170  clover::setFace(face1,face2); // FIXME: temporary hack maintain C linkage for dslashCuda
171 
172  checkParitySpinor(in, out);
173  checkSpinorAlias(in, out);
174 
175  FullClover cs(clover, true);
176  cloverDslashCuda(&out, gauge, cs, &in, parity, dagger, &x, k, commDim, profile);
177 
178  flops += 1872ll*in.Volume();
179  }
180 
181  // Apply the even-odd preconditioned clover-improved Dirac operator
183  {
184  double kappa2 = -kappa*kappa;
185  bool reset1 = newTmp(&tmp1, in);
186 
188  // DiracCloverPC::Dslash applies A^{-1}Dslash
189  Dslash(*tmp1, in, QUDA_ODD_PARITY);
190  // DiracClover::DslashXpay applies (A - kappa^2 D)
191  DiracClover::DslashXpay(out, *tmp1, QUDA_EVEN_PARITY, in, kappa2);
193  // DiracCloverPC::Dslash applies A^{-1}Dslash
195  // DiracClover::DslashXpay applies (A - kappa^2 D)
196  DiracClover::DslashXpay(out, *tmp1, QUDA_ODD_PARITY, in, kappa2);
197  } else if (!dagger) { // symmetric preconditioning
199  Dslash(*tmp1, in, QUDA_ODD_PARITY);
200  DslashXpay(out, *tmp1, QUDA_EVEN_PARITY, in, kappa2);
201  } else if (matpcType == QUDA_MATPC_ODD_ODD) {
203  DslashXpay(out, *tmp1, QUDA_ODD_PARITY, in, kappa2);
204  } else {
205  errorQuda("Invalid matpcType");
206  }
207  } else { // symmetric preconditioning, dagger
209  CloverInv(out, in, QUDA_EVEN_PARITY);
210  Dslash(*tmp1, out, QUDA_ODD_PARITY);
211  DiracWilson::DslashXpay(out, *tmp1, QUDA_EVEN_PARITY, in, kappa2);
212  } else if (matpcType == QUDA_MATPC_ODD_ODD) {
213  CloverInv(out, in, QUDA_ODD_PARITY);
214  Dslash(*tmp1, out, QUDA_EVEN_PARITY);
215  DiracWilson::DslashXpay(out, *tmp1, QUDA_ODD_PARITY, in, kappa2);
216  } else {
217  errorQuda("MatPCType %d not valid for DiracCloverPC", matpcType);
218  }
219  }
220 
221  deleteTmp(&tmp1, reset1);
222  }
223 
225  {
226  // need extra temporary because of symmetric preconditioning dagger
227  // and for multi-gpu the input and output fields cannot alias
228  bool reset = newTmp(&tmp2, in);
229  M(*tmp2, in);
230  Mdag(out, *tmp2);
231  deleteTmp(&tmp2, reset);
232  }
233 
236  const QudaSolutionType solType) const
237  {
238  // we desire solution to preconditioned system
239  if (solType == QUDA_MATPC_SOLUTION || solType == QUDA_MATPCDAG_MATPC_SOLUTION) {
240  src = &b;
241  sol = &x;
242  return;
243  }
244 
245  bool reset = newTmp(&tmp1, b.Even());
246 
247  // we desire solution to full system
249  // src = A_ee^-1 (b_e + k D_eo A_oo^-1 b_o)
250  src = &(x.Odd());
251  CloverInv(*src, b.Odd(), QUDA_ODD_PARITY);
254  sol = &(x.Even());
255  } else if (matpcType == QUDA_MATPC_ODD_ODD) {
256  // src = A_oo^-1 (b_o + k D_oe A_ee^-1 b_e)
257  src = &(x.Even());
258  CloverInv(*src, b.Even(), QUDA_EVEN_PARITY);
260  CloverInv(*src, *tmp1, QUDA_ODD_PARITY);
261  sol = &(x.Odd());
263  // src = b_e + k D_eo A_oo^-1 b_o
264  src = &(x.Odd());
265  CloverInv(*tmp1, b.Odd(), QUDA_ODD_PARITY); // safe even when *tmp1 = b.odd
267  sol = &(x.Even());
269  // src = b_o + k D_oe A_ee^-1 b_e
270  src = &(x.Even());
271  CloverInv(*tmp1, b.Even(), QUDA_EVEN_PARITY); // safe even when *tmp1 = b.even
273  sol = &(x.Odd());
274  } else {
275  errorQuda("MatPCType %d not valid for DiracCloverPC", matpcType);
276  }
277 
278  // here we use final solution to store parity solution and parity source
279  // b is now up for grabs if we want
280 
281  deleteTmp(&tmp1, reset);
282 
283  }
284 
286  const QudaSolutionType solType) const
287  {
288  if (solType == QUDA_MATPC_SOLUTION || solType == QUDA_MATPCDAG_MATPC_SOLUTION) {
289  return;
290  }
291 
292  checkFullSpinor(x, b);
293 
294  bool reset = newTmp(&tmp1, b.Even());
295 
296  // create full solution
297 
300  // x_o = A_oo^-1 (b_o + k D_oe x_e)
303  } else if (matpcType == QUDA_MATPC_ODD_ODD ||
305  // x_e = A_ee^-1 (b_e + k D_eo x_o)
308  } else {
309  errorQuda("MatPCType %d not valid for DiracCloverPC", matpcType);
310  }
311 
312  deleteTmp(&tmp1, reset);
313 
314  }
315 
316 } // namespace quda
FaceBuffer face1
Definition: dirac_quda.h:148
cudaGaugeField & gauge
Definition: dirac_quda.h:88
virtual void checkParitySpinor(const cudaColorSpinorField &, const cudaColorSpinorField &) const
Definition: dirac.cpp:84
unsigned long long flops
Definition: dirac_quda.h:93
int VolumeCB() const
void Clover(cudaColorSpinorField &out, const cudaColorSpinorField &in, const QudaParity parity) const
#define errorQuda(...)
Definition: util_quda.h:73
virtual void MdagM(cudaColorSpinorField &out, const cudaColorSpinorField &in) const
bool newTmp(cudaColorSpinorField **, const cudaColorSpinorField &) const
Definition: dirac.cpp:51
void CloverInv(cudaColorSpinorField &out, const cudaColorSpinorField &in, const QudaParity parity) const
TimeProfile profile
Definition: dirac_quda.h:104
DiracWilson & operator=(const DiracWilson &dirac)
virtual ~DiracClover()
cudaGaugeField * gauge
Definition: dirac_quda.h:30
QudaGaugeParam param
Definition: pack_test.cpp:17
void checkSpinorAlias(const cudaColorSpinorField &, const cudaColorSpinorField &) const
Definition: dirac.cpp:129
cudaColorSpinorField & Odd() const
void cloverDslashCuda(cudaColorSpinorField *out, const cudaGaugeField &gauge, const FullClover cloverInv, const cudaColorSpinorField *in, const int oddBit, const int daggerBit, const cudaColorSpinorField *x, const double &k, const int *commDim, TimeProfile &profile, const QudaDslashPolicy &dslashPolicy=QUDA_DSLASH2)
int commDim[QUDA_MAX_DIM]
Definition: dirac_quda.h:102
virtual void M(cudaColorSpinorField &out, const cudaColorSpinorField &in) const
virtual void DslashXpay(cudaColorSpinorField &out, const cudaColorSpinorField &in, const QudaParity parity, const cudaColorSpinorField &x, const double &k) const
DiracClover & operator=(const DiracClover &dirac)
void M(cudaColorSpinorField &out, const cudaColorSpinorField &in) const
void cloverCuda(cudaColorSpinorField *out, const cudaGaugeField &gauge, const FullClover clover, const cudaColorSpinorField *in, const int oddBit)
Definition: dslash_quda.cu:229
cudaCloverField & clover
Definition: dirac_quda.h:199
cpuColorSpinorField * in
void MdagM(cudaColorSpinorField &out, const cudaColorSpinorField &in) const
enum QudaSolutionType_s QudaSolutionType
void deleteTmp(cudaColorSpinorField **, const bool &reset) const
Definition: dirac.cpp:59
Dirac * dirac
Definition: dslash_test.cpp:45
QudaDagType dagger
Definition: dirac_quda.h:92
void asymCloverDslashCuda(cudaColorSpinorField *out, const cudaGaugeField &gauge, const FullClover cloverInv, const cudaColorSpinorField *in, const int oddBit, const int daggerBit, const cudaColorSpinorField *x, const double &k, const int *commDim, TimeProfile &profile, const QudaDslashPolicy &dslashPolicy=QUDA_DSLASH2)
void Dslash(cudaColorSpinorField &out, const cudaColorSpinorField &in, const QudaParity parity) const
enum QudaParity_s QudaParity
DiracCloverPC(const DiracParam &param)
int x[4]
void prepare(cudaColorSpinorField *&src, cudaColorSpinorField *&sol, cudaColorSpinorField &x, cudaColorSpinorField &b, const QudaSolutionType) const
double kappa
Definition: dirac_quda.h:89
QudaMatPCType matpcType
Definition: dirac_quda.h:91
DiracClover(const DiracParam &param)
FaceBuffer face2
Definition: dirac_quda.h:148
cudaColorSpinorField * tmp2
Definition: dirac_quda.h:95
virtual void checkFullSpinor(const cudaColorSpinorField &, const cudaColorSpinorField &) const
Definition: dirac.cpp:121
virtual void DslashXpay(cudaColorSpinorField &out, const cudaColorSpinorField &in, const QudaParity parity, const cudaColorSpinorField &x, const double &k) const
cpuColorSpinorField * out
cudaColorSpinorField * tmp1
Definition: dirac_quda.h:94
void DslashXpay(cudaColorSpinorField &out, const cudaColorSpinorField &in, const QudaParity parity, const cudaColorSpinorField &x, const double &k) const
void Mdag(cudaColorSpinorField &out, const cudaColorSpinorField &in) const
Definition: dirac.cpp:68
DiracCloverPC & operator=(const DiracCloverPC &dirac)
virtual void reconstruct(cudaColorSpinorField &x, const cudaColorSpinorField &b, const QudaSolutionType) const
void reconstruct(cudaColorSpinorField &x, const cudaColorSpinorField &b, const QudaSolutionType) const
const QudaParity parity
Definition: dslash_test.cpp:29
void checkParitySpinor(const cudaColorSpinorField &, const cudaColorSpinorField &) const
cudaColorSpinorField & Even() const
virtual void prepare(cudaColorSpinorField *&src, cudaColorSpinorField *&sol, cudaColorSpinorField &x, cudaColorSpinorField &b, const QudaSolutionType) const