QUDA  v1.1.0
A library for QCD on GPUs
dslash_twisted_clover.cu
Go to the documentation of this file.
1 #include <gauge_field.h>
2 #include <color_spinor_field.h>
3 #include <clover_field.h>
4 #include <dslash.h>
5 #include <worker.h>
6 
7 #include <dslash_policy.cuh>
8 #include <kernels/dslash_wilson_clover.cuh>
9 
10 /**
11  This is the basic gauged twisted-clover operator
12 */
13 
14 namespace quda
15 {
16 
17  template <typename Arg> class TwistedClover : public Dslash<wilsonClover, Arg>
18  {
19  using Dslash = Dslash<wilsonClover, Arg>;
20  using Dslash::arg;
21  using Dslash::in;
22 
23  public:
24  TwistedClover(Arg &arg, const ColorSpinorField &out, const ColorSpinorField &in) : Dslash(arg, out, in) {}
25 
26  void apply(const qudaStream_t &stream)
27  {
28  TuneParam tp = tuneLaunch(*this, getTuning(), getVerbosity());
29  Dslash::setParam(tp);
30  if (arg.xpay)
31  this->template instantiate<packShmem, true>(tp, stream);
32  else
33  errorQuda("Twisted-clover operator only defined for xpay=true");
34  }
35 
36  long long flops() const
37  {
38  int clover_flops = 504 + 48;
39  long long flops = Dslash::flops();
40  switch (arg.kernel_type) {
41  case INTERIOR_KERNEL:
42  case UBER_KERNEL:
43  case KERNEL_POLICY: flops += clover_flops * in.Volume(); break;
44  default: break; // all clover flops are in the interior kernel
45  }
46  return flops;
47  }
48 
49  long long bytes() const
50  {
51  int clover_bytes = 72 * in.Precision() + (isFixed<typename Arg::Float>::value ? 2 * sizeof(float) : 0);
52 
53  long long bytes = Dslash::bytes();
54  switch (arg.kernel_type) {
55  case INTERIOR_KERNEL:
56  case UBER_KERNEL:
57  case KERNEL_POLICY: bytes += clover_bytes * in.Volume(); break;
58  default: break;
59  }
60 
61  return bytes;
62  }
63  };
64 
65  template <typename Float, int nColor, QudaReconstructType recon> struct TwistedCloverApply {
66 
67  inline TwistedCloverApply(ColorSpinorField &out, const ColorSpinorField &in, const GaugeField &U,
68  const CloverField &C, double a, double b, const ColorSpinorField &x, int parity,
69  bool dagger, const int *comm_override, TimeProfile &profile)
70  {
71  constexpr int nDim = 4;
72  WilsonCloverArg<Float, nColor, nDim, recon, true> arg(out, in, U, C, a, b, x, parity, dagger, comm_override);
73  TwistedClover<decltype(arg)> twisted(arg, out, in);
74 
75  dslash::DslashPolicyTune<decltype(twisted)> policy(
76  twisted, const_cast<cudaColorSpinorField *>(static_cast<const cudaColorSpinorField *>(&in)), in.VolumeCB(),
77  in.GhostFaceCB(), profile);
78  policy.apply(0);
79  }
80  };
81 
82  // Apply the twisted-mass Dslash operator
83  // out(x) = M*in = (A + i*b*gamma_5)*in(x) + a*\sum_mu U_{-\mu}(x)in(x+mu) + U^\dagger_mu(x-mu)in(x-mu)
84  // Uses the kappa normalization for the Wilson operator, with a = -kappa.
85  void ApplyTwistedClover(ColorSpinorField &out, const ColorSpinorField &in, const GaugeField &U, const CloverField &C,
86  double a, double b, const ColorSpinorField &x, int parity, bool dagger,
87  const int *comm_override, TimeProfile &profile)
88  {
89 #ifdef GPU_TWISTED_CLOVER_DIRAC
90  instantiate<TwistedCloverApply>(out, in, U, C, a, b, x, parity, dagger, comm_override, profile);
91 #else
92  errorQuda("Twisted-clover dslash has not been built");
93 #endif // GPU_TWISTED_CLOVEr_DIRAC
94  }
95 
96 } // namespace quda