QUDA  1.0.0
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros
dirac_clover.cpp
Go to the documentation of this file.
1 #include <iostream>
2 #include <dirac_quda.h>
3 #include <blas_quda.h>
4 #include <multigrid.h>
5 
6 #define NEW_DSLASH
7 
8 namespace quda {
9 
10  DiracClover::DiracClover(const DiracParam &param) : DiracWilson(param), clover(*(param.clover)) {}
11 
13 
15 
17  {
18  if (&dirac != this) {
20  clover = dirac.clover;
21  }
22  return *this;
23  }
24 
26  {
27  Dirac::checkParitySpinor(out, in);
28 
29  if (out.Volume() != clover.VolumeCB()) {
30  errorQuda("Parity spinor volume %d doesn't match clover checkboard volume %d",
31  out.Volume(), clover.VolumeCB());
32  }
33  }
34 
37  const QudaParity parity, const ColorSpinorField &x,
38  const double &k) const
39  {
40  checkParitySpinor(in, out);
41  checkSpinorAlias(in, out);
42 
43  ApplyWilsonClover(out, in, *gauge, clover, k, x, parity, dagger, commDim, profile);
44  flops += 1872ll*in.Volume();
45  }
46 
47  // Public method to apply the clover term only
49  {
50  checkParitySpinor(in, out);
51 
52  ApplyClover(out, in, clover, false, parity);
53  flops += 504ll*in.Volume();
54  }
55 
57  {
59  flops += 1872ll * in.Volume();
60  }
61 
63  {
64  checkFullSpinor(out, in);
65 
66  bool reset = newTmp(&tmp1, in);
67  checkFullSpinor(*tmp1, in);
68 
69  M(*tmp1, in);
70  Mdag(out, *tmp1);
71 
72  deleteTmp(&tmp1, reset);
73  }
74 
77  const QudaSolutionType solType) const
78  {
79  if (solType == QUDA_MATPC_SOLUTION || solType == QUDA_MATPCDAG_MATPC_SOLUTION) {
80  errorQuda("Preconditioned solution requires a preconditioned solve_type");
81  }
82 
83  src = &b;
84  sol = &x;
85  }
86 
88  const QudaSolutionType solType) const
89  {
90  // do nothing
91  }
92 
94  double kappa, double mass, double mu, double mu_factor) const {
95  double a = 2.0 * kappa * mu * T.Vectors().TwistFlavor();
96  CoarseOp(Y, X, T, *gauge, &clover, kappa, a, mu_factor, QUDA_CLOVER_DIRAC, QUDA_MATPC_INVALID);
97  }
98 
100  DiracClover(param)
101  {
102  // For the preconditioned operator, we need to check that the inverse of the clover term is present
103  if (!clover.cloverInv) errorQuda("Clover inverse required for DiracCloverPC");
104  }
105 
107 
109 
111  {
112  if (&dirac != this) {
113  DiracClover::operator=(dirac);
114  }
115  return *this;
116  }
117 
118  // Public method
120  const QudaParity parity) const
121  {
122  checkParitySpinor(in, out);
123 
124  ApplyClover(out, in, clover, true, parity);
125  flops += 504ll*in.Volume();
126  }
127 
128  // apply hopping term, then clover: (A_ee^-1 D_eo) or (A_oo^-1 D_oe),
129  // and likewise for dagger: (A_ee^-1 D^dagger_eo) or (A_oo^-1 D^dagger_oe)
130  // NOTE - this isn't Dslash dagger since order should be reversed!
132  const QudaParity parity) const
133  {
134  checkParitySpinor(in, out);
135  checkSpinorAlias(in, out);
136 
137  ApplyWilsonCloverPreconditioned(out, in, *gauge, clover, 0.0, in, parity, dagger, commDim, profile);
138  flops += 1824ll*in.Volume();
139  }
140 
141  // xpay version of the above
143  const QudaParity parity, const ColorSpinorField &x,
144  const double &k) const
145  {
146  checkParitySpinor(in, out);
147  checkSpinorAlias(in, out);
148 
149  ApplyWilsonCloverPreconditioned(out, in, *gauge, clover, k, x, parity, dagger, commDim, profile);
150  flops += 1872ll*in.Volume();
151  }
152 
153  // Apply the even-odd preconditioned clover-improved Dirac operator
155  {
156  double kappa2 = -kappa*kappa;
157  bool reset1 = newTmp(&tmp1, in);
158 
159  bool symmetric =(matpcType == QUDA_MATPC_EVEN_EVEN || matpcType == QUDA_MATPC_ODD_ODD) ? true : false;
160  int odd_bit = (matpcType == QUDA_MATPC_ODD_ODD || matpcType == QUDA_MATPC_ODD_ODD_ASYMMETRIC) ? 1 : 0;
161  QudaParity parity[2] = {static_cast<QudaParity>((1 + odd_bit) % 2), static_cast<QudaParity>((0 + odd_bit) % 2)};
162 
163  if (!symmetric) {
164  // DiracCloverPC::Dslash applies A^{-1}Dslash
165  Dslash(*tmp1, in, parity[0]);
166  // DiracClover::DslashXpay applies (A - kappa^2 D)
167  DiracClover::DslashXpay(out, *tmp1, parity[1], in, kappa2);
168  } else if (!dagger) { // symmetric preconditioning
169  Dslash(*tmp1, in, parity[0]);
170  DslashXpay(out, *tmp1, parity[1], in, kappa2);
171  } else { // symmetric preconditioning, dagger
172  CloverInv(out, in, parity[1]);
173  Dslash(*tmp1, out, parity[0]);
174  DiracWilson::DslashXpay(out, *tmp1, parity[1], in, kappa2);
175  }
176 
177  deleteTmp(&tmp1, reset1);
178  }
179 
181  {
182  // need extra temporary because of symmetric preconditioning dagger
183  // and for multi-gpu the input and output fields cannot alias
184  bool reset = newTmp(&tmp2, in);
185  M(*tmp2, in);
186  Mdag(out, *tmp2);
187  deleteTmp(&tmp2, reset);
188  }
189 
192  const QudaSolutionType solType) const
193  {
194  // we desire solution to preconditioned system
195  if (solType == QUDA_MATPC_SOLUTION || solType == QUDA_MATPCDAG_MATPC_SOLUTION) {
196  src = &b;
197  sol = &x;
198  return;
199  }
200 
201  bool reset = newTmp(&tmp1, b.Even());
202 
203  // we desire solution to full system
205  // src = A_ee^-1 (b_e + k D_eo A_oo^-1 b_o)
206  src = &(x.Odd());
207  CloverInv(*src, b.Odd(), QUDA_ODD_PARITY);
210  sol = &(x.Even());
211  } else if (matpcType == QUDA_MATPC_ODD_ODD) {
212  // src = A_oo^-1 (b_o + k D_oe A_ee^-1 b_e)
213  src = &(x.Even());
214  CloverInv(*src, b.Even(), QUDA_EVEN_PARITY);
216  CloverInv(*src, *tmp1, QUDA_ODD_PARITY);
217  sol = &(x.Odd());
219  // src = b_e + k D_eo A_oo^-1 b_o
220  src = &(x.Odd());
221  CloverInv(*tmp1, b.Odd(), QUDA_ODD_PARITY); // safe even when *tmp1 = b.odd
223  sol = &(x.Even());
225  // src = b_o + k D_oe A_ee^-1 b_e
226  src = &(x.Even());
227  CloverInv(*tmp1, b.Even(), QUDA_EVEN_PARITY); // safe even when *tmp1 = b.even
229  sol = &(x.Odd());
230  } else {
231  errorQuda("MatPCType %d not valid for DiracCloverPC", matpcType);
232  }
233 
234  // here we use final solution to store parity solution and parity source
235  // b is now up for grabs if we want
236 
237  deleteTmp(&tmp1, reset);
238 
239  }
240 
242  const QudaSolutionType solType) const
243  {
244  if (solType == QUDA_MATPC_SOLUTION || solType == QUDA_MATPCDAG_MATPC_SOLUTION) {
245  return;
246  }
247 
248  checkFullSpinor(x, b);
249 
250  bool reset = newTmp(&tmp1, b.Even());
251 
252  // create full solution
253 
256  // x_o = A_oo^-1 (b_o + k D_oe x_e)
259  } else if (matpcType == QUDA_MATPC_ODD_ODD ||
261  // x_e = A_ee^-1 (b_e + k D_eo x_o)
264  } else {
265  errorQuda("MatPCType %d not valid for DiracCloverPC", matpcType);
266  }
267 
268  deleteTmp(&tmp1, reset);
269 
270  }
271 
273  double kappa, double mass, double mu, double mu_factor) const {
274  double a = - 2.0 * kappa * mu * T.Vectors().TwistFlavor();
275  CoarseOp(Y, X, T, *gauge, &clover, kappa, a, -mu_factor, QUDA_CLOVERPC_DIRAC, matpcType);
276  }
277 
278 } // namespace quda
unsigned long long flops
Definition: dirac_quda.h:121
double mu
Definition: test_util.cpp:1648
virtual void prepare(ColorSpinorField *&src, ColorSpinorField *&sol, ColorSpinorField &x, ColorSpinorField &b, const QudaSolutionType) const
#define errorQuda(...)
Definition: util_quda.h:121
cudaGaugeField * gauge
Definition: dirac_quda.h:115
virtual void reconstruct(ColorSpinorField &x, const ColorSpinorField &b, const QudaSolutionType) const
virtual void checkFullSpinor(const ColorSpinorField &, const ColorSpinorField &) const
Definition: dirac.cpp:146
virtual void MdagM(ColorSpinorField &out, const ColorSpinorField &in) const
void ApplyWilsonCloverPreconditioned(ColorSpinorField &out, const ColorSpinorField &in, const GaugeField &U, const CloverField &A, double kappa, const ColorSpinorField &x, int parity, bool dagger, const int *comm_override, TimeProfile &profile)
Driver for applying the preconditioned Wilson-clover stencil.
const ColorSpinorField & Even() const
void deleteTmp(ColorSpinorField **, const bool &reset) const
Definition: dirac.cpp:81
void CoarseOp(GaugeField &Y, GaugeField &X, const Transfer &T, const cudaGaugeField &gauge, const cudaCloverField *clover, double kappa, double mu, double mu_factor, QudaDiracType dirac, QudaMatPCType matpc)
Coarse operator construction from a fine-grid operator (Wilson / Clover)
Definition: coarse_op.cu:201
const ColorSpinorField & Odd() const
TimeProfile profile
Definition: dirac_quda.h:132
virtual void M(ColorSpinorField &out, const ColorSpinorField &in) const
DiracWilson & operator=(const DiracWilson &dirac)
void MdagM(ColorSpinorField &out, const ColorSpinorField &in) const
virtual ~DiracClover()
virtual void DslashXpay(ColorSpinorField &out, const ColorSpinorField &in, const QudaParity parity, const ColorSpinorField &x, const double &k) const
QudaGaugeParam param
Definition: pack_test.cpp:17
bool newTmp(ColorSpinorField **, const ColorSpinorField &) const
Definition: dirac.cpp:70
int commDim[QUDA_MAX_DIM]
Definition: dirac_quda.h:130
void reconstruct(ColorSpinorField &x, const ColorSpinorField &b, const QudaSolutionType) const
DiracClover & operator=(const DiracClover &dirac)
void Clover(ColorSpinorField &out, const ColorSpinorField &in, const QudaParity parity) const
cudaCloverField & clover
Definition: dirac_quda.h:269
void checkSpinorAlias(const ColorSpinorField &, const ColorSpinorField &) const
Definition: dirac.cpp:154
cpuColorSpinorField * in
virtual void DslashXpay(ColorSpinorField &out, const ColorSpinorField &in, const QudaParity parity, const ColorSpinorField &x, const double &k) const
double mass
Definition: dirac_quda.h:117
enum QudaSolutionType_s QudaSolutionType
QudaDagType dagger
Definition: dirac_quda.h:120
int X[4]
Definition: covdev_test.cpp:70
enum QudaParity_s QudaParity
DiracCloverPC(const DiracParam &param)
void DslashXpay(ColorSpinorField &out, const ColorSpinorField &in, const QudaParity parity, const ColorSpinorField &x, const double &k) const
double kappa
Definition: dirac_quda.h:116
QudaMatPCType matpcType
Definition: dirac_quda.h:119
DiracClover(const DiracParam &param)
void Mdag(ColorSpinorField &out, const ColorSpinorField &in) const
Definition: dirac.cpp:90
GaugeCovDev * dirac
Definition: covdev_test.cpp:73
cpuColorSpinorField * out
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 even-odd preconditioned clover operator. Unlike the Wilson operator, the coarsening of the preconditioned clover operator differs from that of the unpreconditioned clover operator, so we need to specialize it.
void ApplyClover(ColorSpinorField &out, const ColorSpinorField &in, const CloverField &clover, bool inverse, int parity)
Apply clover-matrix field to a color-spinor field.
Definition: dslash_quda.cu:604
void ApplyWilsonClover(ColorSpinorField &out, const ColorSpinorField &in, const GaugeField &U, const CloverField &A, double kappa, const ColorSpinorField &x, int parity, bool dagger, const int *comm_override, TimeProfile &profile)
Driver for applying the Wilson-clover stencil.
void M(ColorSpinorField &out, const ColorSpinorField &in) const
int VolumeCB() const
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 clover operator.
QudaTwistFlavorType TwistFlavor() const
double mu_factor[QUDA_MAX_MG_LEVEL]
Definition: test_util.cpp:1674
void Dslash(ColorSpinorField &out, const ColorSpinorField &in, const QudaParity parity) const
virtual void checkParitySpinor(const ColorSpinorField &, const ColorSpinorField &) const
Definition: dirac.cpp:106
DiracCloverPC & operator=(const DiracCloverPC &dirac)
void CloverInv(ColorSpinorField &out, const ColorSpinorField &in, const QudaParity parity) const
void prepare(ColorSpinorField *&src, ColorSpinorField *&sol, ColorSpinorField &x, ColorSpinorField &b, const QudaSolutionType) 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
void checkParitySpinor(const ColorSpinorField &, const ColorSpinorField &) const
ColorSpinorField * tmp1
Definition: dirac_quda.h:122