QUDA  v1.1.0
A library for QCD on GPUs
dirac_staggered_kd.cpp
Go to the documentation of this file.
1 #include <dirac_quda.h>
2 #include <blas_quda.h>
3 #include <multigrid.h>
5 
6 namespace quda
7 {
8 
10 
12 
14 
16  {
17  if (&dirac != this) {
19  Xinv = dirac.Xinv;
20  }
21  return *this;
22  }
23 
25  {
26  if (in.Ndim() != 5 || out.Ndim() != 5) { errorQuda("Staggered dslash requires 5-d fermion fields"); }
27 
28  if (in.Precision() != out.Precision()) {
29  errorQuda("Input and output spinor precisions don't match in dslash_quda");
30  }
31 
33  errorQuda("ColorSpinorFields are not full parity, in = %d, out = %d", in.SiteSubset(), out.SiteSubset());
34  }
35 
36  if (out.Volume() / out.X(4) != 2 * gauge->VolumeCB() && out.SiteSubset() == QUDA_FULL_SITE_SUBSET) {
37  errorQuda("Spinor volume %lu doesn't match gauge volume %lu", out.Volume(), gauge->VolumeCB());
38  }
39  }
40 
42  {
43  errorQuda("The staggered Kahler-Dirac operator does not have a single parity form");
44  }
45 
47  const ColorSpinorField &x, const double &k) const
48  {
49  errorQuda("The staggered Kahler-Dirac operator does not have a single parity form");
50  }
51 
52  // Full staggered operator
54  {
55  // Due to the staggered convention, the staggered part is applying
56  // ( 2m -D_eo ) (x_e) = (b_e)
57  // ( -D_oe 2m ) (x_o) = (b_o)
58  // ... but under the hood we need to catch the zero mass case.
59 
60  // TODO: add left vs right precond
61 
62  checkFullSpinor(out, in);
63 
64  bool reset = newTmp(&tmp2, in);
65 
66  bool right_block_precond = false;
67 
68  if (right_block_precond) {
69  if (dagger == QUDA_DAG_NO) {
70  // K-D op is right-block preconditioned
72  flops += (8ll * 48 - 2ll) * 48 * in.Volume() / 16; // for 2^4 block
73  if (mass == 0.) {
75  flops += 570ll * in.Volume();
76  } else {
78  flops += 582ll * in.Volume();
79  }
80  } else { // QUDA_DAG_YES
81 
82  if (mass == 0.) {
84  flops += 570ll * in.Volume();
85  } else {
87  flops += 582ll * in.Volume();
88  }
90  flops += (8ll * 48 - 2ll) * 48 * in.Volume() / 16; // for 2^4 block
91  }
92  } else { // left preconditioned
93  if (dagger == QUDA_DAG_NO) {
94 
95  if (mass == 0.) {
97  flops += 570ll * in.Volume();
98  } else {
100  flops += 582ll * in.Volume();
101  }
103  flops += (8ll * 48 - 2ll) * 48 * in.Volume() / 16; // for 2^4 block
104 
105  } else { // QUDA_DAG_YES
106 
108  flops += (8ll * 48 - 2ll) * 48 * in.Volume() / 16; // for 2^4 block
109 
110  if (mass == 0.) {
112  flops += 570ll * in.Volume();
113  } else {
115  flops += 582ll * in.Volume();
116  }
117  }
118  }
119 
120  deleteTmp(&tmp2, reset);
121  }
122 
124  {
125 
126  bool reset = newTmp(&tmp1, in);
127 
128  M(*tmp1, in);
129  Mdag(out, *tmp1);
130 
131  deleteTmp(&tmp1, reset);
132  }
133 
135  {
137  }
138 
140  ColorSpinorField &b, const QudaSolutionType solType) const
141  {
142  // TODO: technically KD is a different type of preconditioning.
143  // Should we support "preparing" and "reconstructing"?
144  if (solType == QUDA_MATPC_SOLUTION || solType == QUDA_MATPCDAG_MATPC_SOLUTION) {
145  errorQuda("Preconditioned solution requires a preconditioned solve_type");
146  }
147 
148  sol = &x;
149  src = &b;
150  }
151 
153  ColorSpinorField &b, const QudaSolutionType solType) const
154  {
155  // TODO: technically KD is a different type of preconditioning.
156  // Should we support "preparing" and "reconstructing"?
157  if (solType == QUDA_MATPC_SOLUTION || solType == QUDA_MATPCDAG_MATPC_SOLUTION) {
158  errorQuda("Preconditioned solution requires a preconditioned solve_type");
159  }
160 
161  checkFullSpinor(x, b);
162 
163  bool right_block_precond = false;
164 
165  if (right_block_precond) {
166  // need to modify the solution
167  src = &b;
168  sol = &x;
169  } else {
170  // need to modify rhs
171  bool reset = newTmp(&tmp1, b);
172 
173  KahlerDiracInv(*tmp1, b);
174  b = *tmp1;
175 
176  deleteTmp(&tmp1, reset);
177  sol = &x;
178  src = &b;
179  }
180  }
181 
183  {
184  // do nothing
185 
186  // TODO: technically KD is a different type of preconditioning.
187  // Should we support "preparing" and "reconstructing"?
188  }
189 
191  const QudaSolutionType solType) const
192  {
193  // do nothing
194 
195  // TODO: technically KD is a different type of preconditioning.
196  // Should we support "preparing" and "reconstructing"?
197 
198  checkFullSpinor(x, b);
199 
200  bool right_block_precond = false;
201 
202  if (right_block_precond) {
203  bool reset = newTmp(&tmp1, b.Even());
204 
205  KahlerDiracInv(*tmp1, x);
206  x = *tmp1;
207 
208  deleteTmp(&tmp1, reset);
209  }
210  // nothing required for left block preconditioning
211  }
212 
214  cudaGaugeField *long_gauge_in, cudaCloverField *clover_in)
215  {
216  Dirac::updateFields(gauge_in, nullptr, nullptr, nullptr);
217 
218  // Recompute Xinv (I guess we should do that here?)
220  }
221 
223  double mu, double mu_factor) const
224  {
225  errorQuda("Staggered KD operators do not support MG coarsening yet");
226 
227  // if (T.getTransferType() != QUDA_TRANSFER_AGGREGATE)
228  // errorQuda("Staggered KD operators only support aggregation coarsening");
229  // StaggeredCoarseOp(Y, X, T, *gauge, Xinv, mass, QUDA_STAGGEREDKD_DIRAC, QUDA_MATPC_INVALID);
230  }
231 
233  {
234  DiracStaggered::prefetch(mem_space, stream);
235  if (Xinv != nullptr) Xinv->prefetch(mem_space, stream);
236  }
237 
238 } // namespace quda
QudaSiteSubset SiteSubset() const
const ColorSpinorField & Even() const
const int * X() const
unsigned long long flops
Definition: dirac_quda.h:150
bool newTmp(ColorSpinorField **, const ColorSpinorField &) const
Definition: dirac.cpp:72
virtual void updateFields(cudaGaugeField *gauge_in, cudaGaugeField *fat_gauge_in, cudaGaugeField *long_gauge_in, cudaCloverField *clover_in)
Update the internal gauge, fat gauge, long gauge, clover field pointer as appropriate....
Definition: dirac_quda.h:360
virtual void prefetch(QudaFieldLocation mem_space, qudaStream_t stream=0) const
If managed memory and prefetch is enabled, prefetch the gauge field and temporary spinors to the CPU ...
Definition: dirac.cpp:305
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
ColorSpinorField * tmp1
Definition: dirac_quda.h:151
TimeProfile profile
Definition: dirac_quda.h:161
QudaDagType dagger
Definition: dirac_quda.h:149
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
DiracStaggered & operator=(const DiracStaggered &dirac)
virtual void reconstruct(ColorSpinorField &x, const ColorSpinorField &b, const QudaSolutionType) const
DiracStaggeredKD & operator=(const DiracStaggeredKD &dirac)
virtual void M(ColorSpinorField &out, const ColorSpinorField &in) const
Apply M for the dirac op. E.g. the Schur Complement operator.
virtual void prepareSpecialMG(ColorSpinorField *&src, ColorSpinorField *&sol, ColorSpinorField &x, ColorSpinorField &b, const QudaSolutionType solType) const
void createCoarseOp(GaugeField &Y, GaugeField &X, const Transfer &T, double kappa, double mass, double mu=0., double mu_factor=0.) const
Create the coarse staggered KD operator.
DiracStaggeredKD(const DiracParam &param)
void KahlerDiracInv(ColorSpinorField &out, const ColorSpinorField &in) const
virtual void reconstructSpecialMG(ColorSpinorField &x, const ColorSpinorField &b, const QudaSolutionType solType) const
virtual void checkParitySpinor(const ColorSpinorField &, const ColorSpinorField &) const
Check parity spinors are usable (check geometry ?)
virtual void MdagM(ColorSpinorField &out, const ColorSpinorField &in) const
Apply MdagM operator which may be optimized.
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 prefetch(QudaFieldLocation mem_space, qudaStream_t stream=0) const
If managed memory and prefetch is enabled, prefetch all relevant memory fields (gauge,...
cudaGaugeField * Xinv
Definition: dirac_quda.h:1273
virtual void DslashXpay(ColorSpinorField &out, const ColorSpinorField &in, const QudaParity parity, const ColorSpinorField &x, const double &k) const
Xpay version of Dslash.
virtual void updateFields(cudaGaugeField *gauge_in, cudaGaugeField *fat_gauge_in, cudaGaugeField *long_gauge_in, cudaCloverField *clover_in)
Update the internal gauge, fat gauge, long gauge, clover field pointer as appropriate....
virtual void prepare(ColorSpinorField *&src, ColorSpinorField *&sol, ColorSpinorField &x, ColorSpinorField &b, const QudaSolutionType) const
QudaPrecision Precision() const
size_t VolumeCB() const
void prefetch(QudaFieldLocation mem_space, qudaStream_t stream=0) const
If managed memory and prefetch is enabled, prefetch the gauge field and buffers to the CPU or the GPU...
double kappa
double mass
double mu
quda::mgarray< double > mu_factor
GaugeCovDev * dirac
Definition: covdev_test.cpp:42
QudaParity parity
Definition: covdev_test.cpp:40
@ QUDA_DAG_NO
Definition: enum_quda.h:223
@ QUDA_DAG_YES
Definition: enum_quda.h:223
@ QUDA_FULL_SITE_SUBSET
Definition: enum_quda.h:333
@ QUDA_INVALID_PARITY
Definition: enum_quda.h:284
enum QudaSolutionType_s QudaSolutionType
enum QudaFieldLocation_s QudaFieldLocation
@ QUDA_MATPC_SOLUTION
Definition: enum_quda.h:159
@ QUDA_MATPCDAG_MATPC_SOLUTION
Definition: enum_quda.h:161
enum QudaParity_s QudaParity
void BuildStaggeredKahlerDiracInverse(GaugeField &Xinv, const cudaGaugeField &gauge, const double mass)
Build the Kahler-Dirac inverse block for KD operators.
void ApplyStaggered(ColorSpinorField &out, const ColorSpinorField &in, const GaugeField &U, double a, const ColorSpinorField &x, int parity, bool dagger, const int *comm_override, TimeProfile &profile)
Apply the staggered dslash operator to a color-spinor field.
qudaStream_t * stream
void ApplyStaggeredKahlerDiracInverse(ColorSpinorField &out, const ColorSpinorField &in, const GaugeField &Xinv, bool dagger)
Apply the (improved) staggered Kahler-Dirac inverse block to a color-spinor field.
QudaGaugeParam param
Definition: pack_test.cpp:18
cudaStream_t qudaStream_t
Definition: quda_api.h:9
#define errorQuda(...)
Definition: util_quda.h:120