1 #include <gauge_field.h>
2 #include <color_spinor_field.h>
6 #include <dslash_policy.cuh>
7 #include <kernels/dslash_twisted_mass_preconditioned.cuh>
10 This is the preconditioned gauged twisted-mass operator
16 // trait to ensure we don't instantiate asymmetric & xpay
17 template <bool symmetric> constexpr bool xpay_() { return true; }
18 template <> constexpr bool xpay_<true>() { return false; }
20 // trait to ensure we don't instantiate asymmetric & !dagger
21 template <bool symmetric> constexpr bool not_dagger_() { return false; }
22 template <> constexpr bool not_dagger_<true>() { return true; }
24 template <typename Arg> class TwistedMassPreconditioned : public Dslash<twistedMassPreconditioned, Arg>
26 using Dslash = Dslash<twistedMassPreconditioned, Arg>;
31 TwistedMassPreconditioned(Arg &arg, const ColorSpinorField &out, const ColorSpinorField &in) : Dslash(arg, out, in)
35 void apply(const qudaStream_t &stream)
37 TuneParam tp = tuneLaunch(*this, getTuning(), getVerbosity());
39 if (arg.asymmetric && !arg.dagger) errorQuda("asymmetric operator only defined for dagger");
40 if (arg.asymmetric && arg.xpay) errorQuda("asymmetric operator not defined for xpay");
41 if (arg.nParity != 1) errorQuda("Preconditioned twisted-mass operator not defined nParity=%d", arg.nParity);
45 Dslash::template instantiate<packShmem, 1, true, xpay_<Arg::asymmetric>()>(tp, stream);
47 Dslash::template instantiate<packShmem, 1, true, false>(tp, stream);
50 Dslash::template instantiate<packShmem, 1, not_dagger_<Arg::asymmetric>(), xpay_<Arg::asymmetric>()>(tp, stream);
52 Dslash::template instantiate<packShmem, 1, not_dagger_<Arg::asymmetric>(), false>(tp, stream);
56 long long flops() const
58 long long flops = Dslash::flops();
59 switch (arg.kernel_type) {
63 flops += 2 * in.Ncolor() * 4 * 2 * in.Volume(); // complex * Nc * Ns * fma * vol
71 template <typename Float, int nColor, QudaReconstructType recon> struct TwistedMassPreconditionedApply {
73 inline TwistedMassPreconditionedApply(ColorSpinorField &out, const ColorSpinorField &in, const GaugeField &U,
74 double a, double b, bool xpay, const ColorSpinorField &x, int parity, bool dagger, bool asymmetric,
75 const int *comm_override, TimeProfile &profile)
77 constexpr int nDim = 4;
79 TwistedMassArg<Float, nColor, nDim, recon, true> arg(out, in, U, a, b, xpay, x, parity, dagger, comm_override);
80 TwistedMassPreconditioned<decltype(arg)> twisted(arg, out, in);
82 dslash::DslashPolicyTune<decltype(twisted)> policy(twisted,
83 const_cast<cudaColorSpinorField *>(static_cast<const cudaColorSpinorField *>(&in)), in.VolumeCB(),
84 in.GhostFaceCB(), profile);
87 TwistedMassArg<Float, nColor, nDim, recon, false> arg(out, in, U, a, b, xpay, x, parity, dagger, comm_override);
88 TwistedMassPreconditioned<decltype(arg)> twisted(arg, out, in);
90 dslash::DslashPolicyTune<decltype(twisted)> policy(twisted,
91 const_cast<cudaColorSpinorField *>(static_cast<const cudaColorSpinorField *>(&in)), in.VolumeCB(),
92 in.GhostFaceCB(), profile);
99 Apply the preconditioned twisted-mass Dslash operator
101 out = x + A^{-1} D * in = x + a*(1 + i*b*gamma_5)*\sum_mu U_{-\mu}(x)in(x+mu) + U^\dagger_mu(x-mu)in(x-mu)
103 void ApplyTwistedMassPreconditioned(ColorSpinorField &out, const ColorSpinorField &in, const GaugeField &U, double a,
104 double b, bool xpay, const ColorSpinorField &x, int parity, bool dagger, bool asymmetric,
105 const int *comm_override, TimeProfile &profile)
107 #ifdef GPU_TWISTED_MASS_DIRAC
108 // with symmetric dagger operator we must use kernel packing
109 if (dagger && !asymmetric) pushKernelPackT(true);
111 instantiate<TwistedMassPreconditionedApply>(
112 out, in, U, a, b, xpay, x, parity, dagger, asymmetric, comm_override, profile);
114 if (dagger && !asymmetric) popKernelPackT();
116 errorQuda("Twisted-mass dslash has not been built");
117 #endif // GPU_TWISTED_MASS_DIRAC