QUDA  v1.1.0
A library for QCD on GPUs
dirac_twisted_mass.cpp
Go to the documentation of this file.
1 #include <dirac_quda.h>
2 #include <blas_quda.h>
3 #include <iostream>
4 #include <multigrid.h>
5 
6 namespace quda {
7 
9  DiracWilson(param, nDim),
10  mu(param.mu),
12  {
13  }
14 
17  mu(dirac.mu),
19  {
20  }
21 
23 
25  {
26  if (&dirac != this) {
28  }
29  return *this;
30  }
31 
32  // Protected method for applying twist
34  const QudaTwistGamma5Type twistType) const
35  {
36  checkParitySpinor(out, in);
37  ApplyTwistGamma(out, in, 4, kappa, mu, epsilon, dagger, twistType);
38  flops += 24ll*in.Volume();
39  }
40 
41  // Public method to apply the twist
43  {
45  }
46 
48  {
49 
50  if (in.TwistFlavor() == QUDA_TWIST_SINGLET) {
51  // this would really just be a Wilson dslash (not actually instantiated at present)
52  ApplyTwistedMass(out, in, *gauge, 0.0, 2 * mu * kappa, in, parity, dagger, commDim, profile);
53  flops += 1392ll * in.Volume();
54  } else {
55  // this would really just be a 2-way vectorized Wilson dslash (not actually instantiated at present)
57  out, in, *gauge, 0.0, 2 * mu * kappa, -2 * kappa * epsilon, in, parity, dagger, commDim, profile);
58  flops += (1440ll) * in.Volume();
59  }
60  }
61 
63  const ColorSpinorField &x, const double &k) const
64  {
65 
66  if (in.TwistFlavor() == QUDA_TWIST_SINGLET) {
67  // k * D * in + (1 + i*2*mu*kappa*gamma_5) *x
68  ApplyTwistedMass(out, in, *gauge, k, 2 * mu * kappa, x, parity, dagger, commDim, profile);
69  flops += 1416ll * in.Volume();
70  } else {
71  // k * D * in + (1 + i*2*mu*kappa*gamma_5*tau_3 - 2*epsilon*kappa*tau_1) * x
72  ApplyNdegTwistedMass(out, in, *gauge, k, 2 * mu * kappa, -2 * kappa * epsilon, x, parity, dagger, commDim, profile);
73  flops += (1464ll) * in.Volume();
74  }
75  }
76 
77  // apply full operator / (-kappa * D + (1 + i*2*mu*kappa*gamma_5*tau_3 - 2*epsilon*kappa*tau_1)) * in
79  {
80  checkFullSpinor(out, in);
81  if (in.TwistFlavor() != out.TwistFlavor())
82  errorQuda("Twist flavors %d %d don't match", in.TwistFlavor(), out.TwistFlavor());
83 
85  errorQuda("Twist flavor not set %d\n", in.TwistFlavor());
86  }
87 
88  if (in.TwistFlavor() == QUDA_TWIST_SINGLET) {
90  flops += 1416ll * in.Volume();
91  } else {
92  ApplyNdegTwistedMass(out, in, *gauge, -kappa, 2 * mu * kappa, -2 * kappa * epsilon, in, QUDA_INVALID_PARITY,
94  flops += (1464ll) * in.Volume();
95  }
96  }
97 
99  {
100  checkFullSpinor(out, in);
101  bool reset = newTmp(&tmp1, in);
102 
103  M(*tmp1, in);
104  Mdag(out, *tmp1);
105 
106  deleteTmp(&tmp1, reset);
107  }
108 
110  ColorSpinorField &b, const QudaSolutionType solType) const
111  {
112  if (solType == QUDA_MATPC_SOLUTION || solType == QUDA_MATPCDAG_MATPC_SOLUTION) {
113  errorQuda("Preconditioned solution requires a preconditioned solve_type");
114  }
115 
116  src = &b;
117  sol = &x;
118  }
119 
121  const QudaSolutionType solType) const
122  {
123  // do nothing
124  }
125 
127  double kappa, double mass, double mu, double mu_factor) const {
129  errorQuda("Wilson-type operators only support aggregation coarsening");
130 
131  double a = 2.0 * kappa * mu;
132  cudaCloverField *c = NULL;
134  }
135 
137 
139 
141  {
142 
143  }
144 
146  {
147  if (&dirac != this) {
149  }
150  return *this;
151  }
152 
153  // Public method to apply the inverse twist
155  {
157  }
158 
159  // apply hopping term, then inverse twist: (A_ee^-1 D_eo) or (A_oo^-1 D_oe),
160  // and likewise for dagger: (D^dagger_eo A_ee^-1) or (D^dagger_oe A_oo^-1)
162  {
163  checkParitySpinor(in, out);
164  checkSpinorAlias(in, out);
165 
166  if (in.TwistFlavor() != out.TwistFlavor())
167  errorQuda("Twist flavors %d %d don't match", in.TwistFlavor(), out.TwistFlavor());
169  errorQuda("Twist flavor not set %d\n", in.TwistFlavor());
170 
171  if (in.TwistFlavor() == QUDA_TWIST_SINGLET) {
172  double a = -2.0 * kappa * mu; // for inverse twist
173  double b = 1.0 / (1.0 + a * a);
174 
175  bool asymmetric
177  ApplyTwistedMassPreconditioned(out, in, *gauge, b, a, false, in, parity, dagger, asymmetric, commDim, profile);
178  flops += 1392ll * in.Volume(); // flops numbers are approximate since they will vary depending on the dagger or not
179  } else {//TWIST doublet :
180  double a = 2.0 * kappa * mu;
181  double b = 2.0 * kappa * epsilon;
182  double c = 1.0 / (1.0 + a * a - b * b);
183 
184  bool asymmetric
186  ApplyNdegTwistedMassPreconditioned(out, in, *gauge, c, -2.0 * mu * kappa, 2.0 * kappa * epsilon, false, in,
187  parity, dagger, asymmetric, commDim, profile);
188  flops += (1440ll) * in.Volume(); // flops are approx. since they will vary depending on the dagger or not
189  }
190  }
191 
192  // xpay version of the above
194  const ColorSpinorField &x, const double &k) const
195  {
196  checkParitySpinor(in, out);
197  checkSpinorAlias(in, out);
198  if (in.TwistFlavor() != out.TwistFlavor())
199  errorQuda("Twist flavors %d %d don't match", in.TwistFlavor(), out.TwistFlavor());
201  errorQuda("Twist flavor not set %d\n", in.TwistFlavor());
202 
203  if(in.TwistFlavor() == QUDA_TWIST_SINGLET) {
204  double a = -2.0 * kappa * mu; // for inverse twist
205  double b = k / (1.0 + a * a);
206  // asymmetric should never be true here since we never need to apply 1 + k * A^{-1} D^\dagger
207  bool asymmetric
209  ApplyTwistedMassPreconditioned(out, in, *gauge, b, a, true, x, parity, dagger, asymmetric, commDim, profile);
210  flops += 1416ll * in.Volume(); // flops numbers are approximate since they will vary depending on the dagger or not
211  } else {//TWIST_DOUBLET:
212  double a = 2.0 * kappa * mu;
213  double b = 2.0 * kappa * epsilon;
214  double c = 1.0 / (1.0 + a * a - b * b);
215 
216  bool asymmetric
218  ApplyNdegTwistedMassPreconditioned(out, in, *gauge, k * c, -2 * mu * kappa, 2 * kappa * epsilon, true, x, parity,
219  dagger, asymmetric, commDim, profile);
220  flops += (1464ll)
221  * in.Volume(); // flops numbers are approximate since they will vary depending on the dagger or not
222  }
223  }
224 
226  {
227  double kappa2 = -kappa*kappa;
228  bool reset = newTmp(&tmp1, in);
229 
230  bool symmetric =(matpcType == QUDA_MATPC_EVEN_EVEN || matpcType == QUDA_MATPC_ODD_ODD) ? true : false;
231  int odd_bit = (matpcType == QUDA_MATPC_ODD_ODD || matpcType == QUDA_MATPC_ODD_ODD_ASYMMETRIC) ? 1 : 0;
232  QudaParity parity[2] = {static_cast<QudaParity>((1 + odd_bit) % 2), static_cast<QudaParity>((0 + odd_bit) % 2)};
233 
234  if (symmetric) {
235  Dslash(*tmp1, in, parity[0]);
236  DslashXpay(out, *tmp1, parity[1], in, kappa2);
237  } else { // asymmetric preconditioning
238  Dslash(*tmp1, in, parity[0]);
239  DiracTwistedMass::DslashXpay(out, *tmp1, parity[1], in, kappa2);
240  }
241 
242  deleteTmp(&tmp1, reset);
243  }
244 
246  {
247  // need extra temporary because of symmetric preconditioning dagger
248  bool reset = newTmp(&tmp2, in);
249  M(*tmp2, in);
250  Mdag(out, *tmp2);
251  deleteTmp(&tmp2, reset);
252  }
253 
255  ColorSpinorField &b, const QudaSolutionType solType) const
256  {
257  // we desire solution to preconditioned system
258  if (solType == QUDA_MATPC_SOLUTION || solType == QUDA_MATPCDAG_MATPC_SOLUTION) {
259  src = &b;
260  sol = &x;
261  return;
262  }
263 
264  bool reset = newTmp(&tmp1, b.Even());
265 
266  bool symmetric = (matpcType == QUDA_MATPC_EVEN_EVEN || matpcType == QUDA_MATPC_ODD_ODD) ? true : false;
267  int odd_bit = (matpcType == QUDA_MATPC_ODD_ODD || matpcType == QUDA_MATPC_ODD_ODD_ASYMMETRIC) ? 1 : 0;
268 
269  src = odd_bit ? &(x.Even()) : &(x.Odd());
270  sol = odd_bit ? &(x.Odd()) : &(x.Even());
271 
272  TwistInv(symmetric ? *src : *tmp1, odd_bit ? b.Even() : b.Odd());
273 
274  // we desire solution to full system
275  if (b.TwistFlavor() == QUDA_TWIST_SINGLET) {
276 
278  // src = A_ee^-1 (b_e + k D_eo A_oo^-1 b_o)
280  } else if (matpcType == QUDA_MATPC_ODD_ODD) {
281  // src = A_oo^-1 (b_o + k D_oe A_ee^-1 b_e)
284  // src = b_e + k D_eo A_oo^-1 b_o
287  // src = b_o + k D_oe A_ee^-1 b_e
289  } else {
290  errorQuda("MatPCType %d not valid for DiracTwistedMassPC", matpcType);
291  }
292 
293  } else { // doublet:
294 
295  // repurpose the preconditioned dslash as a vectorized operator: 1+kappa*D
296  double mu_ = mu;
297  mu = 0.0;
298  double epsilon_ = epsilon;
299  epsilon = 0.0;
300 
301  // we desire solution to full system
303  // src = A_ee^-1(b_e + k D_eo A_oo^-1 b_o)
304  DslashXpay(*tmp1, *src, QUDA_EVEN_PARITY, b.Even(), kappa);
305  } else if (matpcType == QUDA_MATPC_ODD_ODD) {
306  // src = A_oo^-1 (b_o + k D_oe A_ee^-1 b_e)
307  DslashXpay(*tmp1, *src, QUDA_ODD_PARITY, b.Odd(), kappa);
309  // src = b_e + k D_eo A_oo^-1 b_o
310  DslashXpay(*src, *tmp1, QUDA_EVEN_PARITY, b.Even(), kappa);
312  // src = b_o + k D_oe A_ee^-1 b_e
313  DslashXpay(*src, *tmp1, QUDA_ODD_PARITY, b.Odd(), kappa);
314  } else {
315  errorQuda("MatPCType %d not valid for DiracTwistedMassPC", matpcType);
316  }
317 
318  mu = mu_;
319  epsilon = epsilon_;
320 
321  } // end of doublet
322 
323  if (symmetric) TwistInv(*src, *tmp1);
324 
325  // here we use final solution to store parity solution and parity source
326  // b is now up for grabs if we want
327 
328  deleteTmp(&tmp1, reset);
329  }
330 
332  const QudaSolutionType solType) const
333  {
334  if (solType == QUDA_MATPC_SOLUTION || solType == QUDA_MATPCDAG_MATPC_SOLUTION) { return; }
335 
336  checkFullSpinor(x, b);
337  bool reset = newTmp(&tmp1, b.Even());
338  int odd_bit = (matpcType == QUDA_MATPC_ODD_ODD || matpcType == QUDA_MATPC_ODD_ODD_ASYMMETRIC) ? 1 : 0;
339 
340  // create full solution
341  if (b.TwistFlavor() == QUDA_TWIST_SINGLET) {
343  // x_o = A_oo^-1 (b_o + k D_oe x_e)
346  // x_e = A_ee^-1 (b_e + k D_eo x_o)
348  } else {
349  errorQuda("MatPCType %d not valid for DiracTwistedMassPC", matpcType);
350  }
351  } else { // twist doublet:
352  double mu_ = mu;
353  mu = 0.0;
354  double epsilon_ = epsilon;
355  epsilon = 0.0;
356 
358  // x_o = A_oo^-1 (b_o + k D_oe x_e)
361  // x_e = A_ee^-1 (b_e + k D_eo x_o)
363  } else {
364  errorQuda("MatPCType %d not valid for DiracTwistedMassPC", matpcType);
365  }
366 
367  mu = mu_;
368  epsilon = epsilon_;
369  } // end of twist doublet...
370 
371  TwistInv(odd_bit ? x.Even() : x.Odd(), *tmp1);
372  deleteTmp(&tmp1, reset);
373  }
374 
376  double kappa, double mass, double mu, double mu_factor) const {
378  errorQuda("Wilson-type operators only support aggregation coarsening");
379 
380  double a = -2.0 * kappa * mu;
381  cudaCloverField *c = NULL;
383  }
384 } // namespace quda
const ColorSpinorField & Odd() const
QudaTwistFlavorType TwistFlavor() const
const ColorSpinorField & Even() const
unsigned long long flops
Definition: dirac_quda.h:150
bool newTmp(ColorSpinorField **, const ColorSpinorField &) const
Definition: dirac.cpp:72
double kappa
Definition: dirac_quda.h:145
QudaMatPCType matpcType
Definition: dirac_quda.h:148
cudaGaugeField * gauge
Definition: dirac_quda.h:144
double mass
Definition: dirac_quda.h:146
void deleteTmp(ColorSpinorField **, const bool &reset) const
Definition: dirac.cpp:83
virtual void checkParitySpinor(const ColorSpinorField &, const ColorSpinorField &) const
Check parity spinors are usable (check geometry ?)
Definition: dirac.cpp:108
ColorSpinorField * tmp1
Definition: dirac_quda.h:151
TimeProfile profile
Definition: dirac_quda.h:161
QudaDagType dagger
Definition: dirac_quda.h:149
void checkSpinorAlias(const ColorSpinorField &, const ColorSpinorField &) const
check spinors do not alias
Definition: dirac.cpp:146
virtual void checkFullSpinor(const ColorSpinorField &, const ColorSpinorField &) const
check full spinors are compatible (check geometry ?)
Definition: dirac.cpp:138
ColorSpinorField * tmp2
Definition: dirac_quda.h:152
int commDim[QUDA_MAX_DIM]
Definition: dirac_quda.h:159
void Mdag(ColorSpinorField &out, const ColorSpinorField &in) const
Apply Mdag (daggered operator of M.
Definition: dirac.cpp:92
virtual void prepare(ColorSpinorField *&src, ColorSpinorField *&sol, ColorSpinorField &x, ColorSpinorField &b, const QudaSolutionType) const
virtual void DslashXpay(ColorSpinorField &out, const ColorSpinorField &in, QudaParity parity, const ColorSpinorField &x, const double &k) const
Xpay version of Dslash.
virtual void reconstruct(ColorSpinorField &x, const ColorSpinorField &b, const QudaSolutionType) const
void twistedApply(ColorSpinorField &out, const ColorSpinorField &in, const QudaTwistGamma5Type twistType) const
void createCoarseOp(GaugeField &Y, GaugeField &X, const Transfer &T, double kappa, double mass, double mu, double mu_factor=0.) const
Create the coarse twisted-mass operator.
DiracTwistedMass(const DiracTwistedMass &dirac)
virtual void MdagM(ColorSpinorField &out, const ColorSpinorField &in) const
Apply MdagM operator which may be optimized.
virtual void M(ColorSpinorField &out, const ColorSpinorField &in) const
Apply M for the dirac op. E.g. the Schur Complement operator.
virtual void Dslash(ColorSpinorField &out, const ColorSpinorField &in, QudaParity parity) const
apply 'dslash' operator for the DiracOp. This may be e.g. AD
DiracTwistedMass & operator=(const DiracTwistedMass &dirac)
void Twist(ColorSpinorField &out, const ColorSpinorField &in) const
void reconstruct(ColorSpinorField &x, const ColorSpinorField &b, const QudaSolutionType) const
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 twisted-mass operator.
void M(ColorSpinorField &out, const ColorSpinorField &in) const
Apply M for the dirac op. E.g. the Schur Complement operator.
DiracTwistedMassPC(const DiracTwistedMassPC &dirac)
void prepare(ColorSpinorField *&src, ColorSpinorField *&sol, ColorSpinorField &x, ColorSpinorField &b, const QudaSolutionType) const
void MdagM(ColorSpinorField &out, const ColorSpinorField &in) const
Apply MdagM operator which may be optimized.
void TwistInv(ColorSpinorField &out, const ColorSpinorField &in) const
DiracTwistedMassPC & operator=(const DiracTwistedMassPC &dirac)
virtual void Dslash(ColorSpinorField &out, const ColorSpinorField &in, const QudaParity parity) const
apply 'dslash' operator for the DiracOp. This may be e.g. AD
virtual void DslashXpay(ColorSpinorField &out, const ColorSpinorField &in, const QudaParity parity, const ColorSpinorField &x, const double &k) const
Xpay version of Dslash.
DiracWilson & operator=(const DiracWilson &dirac)
virtual void DslashXpay(ColorSpinorField &out, const ColorSpinorField &in, const QudaParity parity, const ColorSpinorField &x, const double &k) const
Xpay version of Dslash.
QudaTransferType getTransferType() const
Definition: transfer.h:240
double kappa
double mass
double epsilon
double mu
quda::mgarray< double > mu_factor
GaugeCovDev * dirac
Definition: covdev_test.cpp:42
QudaParity parity
Definition: covdev_test.cpp:40
@ QUDA_TWISTED_MASSPC_DIRAC
Definition: enum_quda.h:312
@ QUDA_TWISTED_MASS_DIRAC
Definition: enum_quda.h:311
enum QudaTwistGamma5Type_s QudaTwistGamma5Type
@ QUDA_EVEN_PARITY
Definition: enum_quda.h:284
@ QUDA_ODD_PARITY
Definition: enum_quda.h:284
@ QUDA_INVALID_PARITY
Definition: enum_quda.h:284
@ QUDA_TRANSFER_AGGREGATE
Definition: enum_quda.h:453
enum QudaSolutionType_s QudaSolutionType
@ QUDA_MATPC_ODD_ODD_ASYMMETRIC
Definition: enum_quda.h:219
@ QUDA_MATPC_EVEN_EVEN_ASYMMETRIC
Definition: enum_quda.h:218
@ QUDA_MATPC_ODD_ODD
Definition: enum_quda.h:217
@ QUDA_MATPC_EVEN_EVEN
Definition: enum_quda.h:216
@ QUDA_MATPC_INVALID
Definition: enum_quda.h:220
@ QUDA_TWIST_GAMMA5_INVERSE
Definition: enum_quda.h:424
@ QUDA_TWIST_GAMMA5_DIRECT
Definition: enum_quda.h:423
@ QUDA_MATPC_SOLUTION
Definition: enum_quda.h:159
@ QUDA_MATPCDAG_MATPC_SOLUTION
Definition: enum_quda.h:161
@ QUDA_TWIST_SINGLET
Definition: enum_quda.h:400
@ QUDA_TWIST_NO
Definition: enum_quda.h:403
@ QUDA_TWIST_INVALID
Definition: enum_quda.h:404
enum QudaParity_s QudaParity
void ApplyNdegTwistedMass(ColorSpinorField &out, const ColorSpinorField &in, const GaugeField &U, double a, double b, double c, const ColorSpinorField &x, int parity, bool dagger, const int *comm_override, TimeProfile &profile)
Driver for applying the non-degenerate twisted-mass stencil.
void ApplyTwistGamma(ColorSpinorField &out, const ColorSpinorField &in, int d, double kappa, double mu, double epsilon, int dagger, QudaTwistGamma5Type type)
Apply the twisted-mass gamma operator to a color-spinor field.
void ApplyTwistedMass(ColorSpinorField &out, const ColorSpinorField &in, const GaugeField &U, double a, double b, const ColorSpinorField &x, int parity, bool dagger, const int *comm_override, TimeProfile &profile)
void ApplyTwistedMassPreconditioned(ColorSpinorField &out, const ColorSpinorField &in, const GaugeField &U, double a, double b, bool xpay, const ColorSpinorField &x, int parity, bool dagger, bool asymmetric, const int *comm_override, TimeProfile &profile)
Driver for applying the preconditioned twisted-mass stencil.
void CoarseOp(GaugeField &Y, GaugeField &X, const Transfer &T, const cudaGaugeField &gauge, const cudaCloverField *clover, double kappa, double mass, double mu, double mu_factor, QudaDiracType dirac, QudaMatPCType matpc)
Coarse operator construction from a fine-grid operator (Wilson / Clover)
void ApplyNdegTwistedMassPreconditioned(ColorSpinorField &out, const ColorSpinorField &in, const GaugeField &U, double a, double b, double c, bool xpay, const ColorSpinorField &x, int parity, bool dagger, bool asymmetric, const int *comm_override, TimeProfile &profile)
Driver for applying the preconditioned non-degenerate twisted-mass stencil.
QudaGaugeParam param
Definition: pack_test.cpp:18
#define errorQuda(...)
Definition: util_quda.h:120