QUDA  0.9.0
coarsecoarse_op.cu
Go to the documentation of this file.
1 #include <transfer.h>
2 #include <color_spinor_field.h>
4 #include <gauge_field.h>
5 #include <gauge_field_order.h>
6 #include <complex_quda.h>
7 #include <index_helper.cuh>
8 #include <gamma.cuh>
9 #include <blas_cublas.h>
10 #include <coarse_op.cuh>
11 
12 namespace quda {
13 
14 #ifdef GPU_MULTIGRID
15 
16  template <typename Float, int fineColor, int fineSpin, int coarseColor, int coarseSpin>
17  void calculateYcoarse(GaugeField &Y, GaugeField &X, GaugeField &Xinv, GaugeField &Yhat,
18  ColorSpinorField &uv, const Transfer &T, const GaugeField &g, const GaugeField &clover,
19  const GaugeField &cloverInv, double kappa, double mu, double mu_factor, QudaDiracType dirac, QudaMatPCType matpc) {
20 
21  if (Y.Location() == QUDA_CPU_FIELD_LOCATION) {
22 
24  constexpr QudaGaugeFieldOrder gOrder = QUDA_QDP_GAUGE_ORDER;
25 
26  if (T.Vectors(Y.Location()).FieldOrder() != csOrder)
27  errorQuda("Unsupported field order %d\n", T.Vectors(Y.Location()).FieldOrder());
28  if (g.FieldOrder() != gOrder) errorQuda("Unsupported field order %d\n", g.FieldOrder());
29 
30  typedef typename colorspinor::FieldOrderCB<Float,fineSpin,fineColor,coarseColor,csOrder> F;
31  typedef typename colorspinor::FieldOrderCB<Float,2*fineSpin,fineColor,coarseColor,csOrder> F2;
32  typedef typename gauge::FieldOrder<Float,fineColor*fineSpin,fineSpin,gOrder> gFine;
33  typedef typename gauge::FieldOrder<Float,coarseColor*coarseSpin,coarseSpin,gOrder> gCoarse;
34 
35  const ColorSpinorField &v = T.Vectors(Y.Location());
36 
37  F vAccessor(const_cast<ColorSpinorField&>(v));
38  F2 uvAccessor(const_cast<ColorSpinorField&>(uv));
39  gFine gAccessor(const_cast<GaugeField&>(g));
40  gFine cAccessor(const_cast<GaugeField&>(clover));
41  gFine cInvAccessor(const_cast<GaugeField&>(cloverInv));
42  gCoarse yAccessor(const_cast<GaugeField&>(Y));
43  gCoarse xAccessor(const_cast<GaugeField&>(X));
44  gCoarse xInvAccessor(const_cast<GaugeField&>(Xinv));
45 
46  calculateY<true,Float,fineSpin,fineColor,coarseSpin,coarseColor,gOrder>
47  (yAccessor, xAccessor, xInvAccessor, uvAccessor, vAccessor, vAccessor, gAccessor, cAccessor, cInvAccessor,
48  Y, X, Xinv, Yhat, const_cast<ColorSpinorField&>(v), v, kappa, mu, mu_factor, dirac, matpc);
49 
50  } else {
51 
52  constexpr QudaFieldOrder csOrder = QUDA_FLOAT2_FIELD_ORDER;
54 
55  if (T.Vectors(Y.Location()).FieldOrder() != csOrder)
56  errorQuda("Unsupported field order %d\n", T.Vectors(Y.Location()).FieldOrder());
57  if (g.FieldOrder() != gOrder) errorQuda("Unsupported field order %d\n", g.FieldOrder());
58 
59  typedef typename colorspinor::FieldOrderCB<Float,fineSpin,fineColor,coarseColor,csOrder> F;
60  typedef typename colorspinor::FieldOrderCB<Float,2*fineSpin,fineColor,coarseColor,csOrder> F2;
61  typedef typename gauge::FieldOrder<Float,fineColor*fineSpin,fineSpin,gOrder> gFine;
62  typedef typename gauge::FieldOrder<Float,coarseColor*coarseSpin,coarseSpin,gOrder> gCoarse;
63 
64  const ColorSpinorField &v = T.Vectors(Y.Location());
65 
66  F vAccessor(const_cast<ColorSpinorField&>(v));
67  F2 uvAccessor(const_cast<ColorSpinorField&>(uv));
68  gFine gAccessor(const_cast<GaugeField&>(g));
69  gFine cAccessor(const_cast<GaugeField&>(clover));
70  gFine cInvAccessor(const_cast<GaugeField&>(cloverInv));
71  gCoarse yAccessor(const_cast<GaugeField&>(Y));
72  gCoarse xAccessor(const_cast<GaugeField&>(X));
73  gCoarse xInvAccessor(const_cast<GaugeField&>(Xinv));
74 
75  calculateY<true,Float,fineSpin,fineColor,coarseSpin,coarseColor,gOrder>
76  (yAccessor, xAccessor, xInvAccessor, uvAccessor, vAccessor, vAccessor, gAccessor, cAccessor, cInvAccessor,
77  Y, X, Xinv, Yhat, const_cast<ColorSpinorField&>(v), v, kappa, mu, mu_factor, dirac, matpc);
78 
79  }
80 
81  }
82 
83  // template on the number of coarse degrees of freedom
84  template <typename Float, int fineColor, int fineSpin>
85  void calculateYcoarse(GaugeField &Y, GaugeField &X, GaugeField &Xinv, GaugeField &Yhat,
86  ColorSpinorField &uv, const Transfer &T, const GaugeField &g, const GaugeField &clover,
87  const GaugeField &cloverInv, double kappa, double mu, double mu_factor, QudaDiracType dirac, QudaMatPCType matpc) {
88  if (T.Vectors().Nspin()/T.Spin_bs() != 2)
89  errorQuda("Unsupported number of coarse spins %d\n",T.Vectors().Nspin()/T.Spin_bs());
90  const int coarseSpin = 2;
91  const int coarseColor = Y.Ncolor() / coarseSpin;
92 
93  if (coarseColor == 2) {
94  calculateYcoarse<Float,fineColor,fineSpin,2,coarseSpin>(Y, X, Xinv, Yhat, uv, T, g, clover, cloverInv, kappa, mu, mu_factor, dirac, matpc);
95 #if 0
96  } else if (coarseColor == 8) {
97  calculateYcoarse<Float,fineColor,fineSpin,8,coarseSpin>(Y, X, Xinv, Yhat, uv, T, g, clover, cloverInv, kappa, mu, mu_factor, dirac, matpc);
98  } else if (coarseColor == 16) {
99  calculateYcoarse<Float,fineColor,fineSpin,16,coarseSpin>(Y, X, Xinv, Yhat, uv, T, g, clover, cloverInv, kappa, mu, mu_factor, dirac, matpc);
100 #endif
101  } else if (coarseColor == 24) {
102  calculateYcoarse<Float,fineColor,fineSpin,24,coarseSpin>(Y, X, Xinv, Yhat, uv, T, g, clover, cloverInv, kappa, mu, mu_factor, dirac, matpc);
103  } else if (coarseColor == 32) {
104  calculateYcoarse<Float,fineColor,fineSpin,32,coarseSpin>(Y, X, Xinv, Yhat, uv, T, g, clover, cloverInv, kappa, mu, mu_factor, dirac, matpc);
105  } else {
106  errorQuda("Unsupported number of coarse dof %d\n", Y.Ncolor());
107  }
108  }
109 
110  // template on fine spin
111  template <typename Float, int fineColor>
112  void calculateYcoarse(GaugeField &Y, GaugeField &X, GaugeField &Xinv, GaugeField &Yhat,
113  ColorSpinorField &uv, const Transfer &T, const GaugeField &g, const GaugeField &clover,
114  const GaugeField &cloverInv, double kappa, double mu, double mu_factor, QudaDiracType dirac, QudaMatPCType matpc) {
115  if (T.Vectors().Nspin() == 2) {
116  calculateYcoarse<Float,fineColor,2>(Y, X, Xinv, Yhat, uv, T, g, clover, cloverInv, kappa, mu, mu_factor, dirac, matpc);
117  } else {
118  errorQuda("Unsupported number of spins %d\n", T.Vectors().Nspin());
119  }
120  }
121 
122  // template on fine colors
123  template <typename Float>
124  void calculateYcoarse(GaugeField &Y, GaugeField &X, GaugeField &Xinv, GaugeField &Yhat,
125  ColorSpinorField &uv, const Transfer &T, const GaugeField &g, const GaugeField &clover,
126  const GaugeField &cloverInv, double kappa, double mu, double mu_factor, QudaDiracType dirac, QudaMatPCType matpc) {
127  if (g.Ncolor()/T.Vectors().Nspin() == 2) {
128  calculateYcoarse<Float,2>(Y, X, Xinv, Yhat, uv, T, g, clover, cloverInv, kappa, mu, mu_factor, dirac, matpc);
129 #if 0
130  } else if (g.Ncolor()/T.Vectors().Nspin() == 8) {
131  calculateYcoarse<Float,8>(Y, X, Xinv, Yhat, uv, T, g, clover, cloverInv, kappa, mu, mu_factor, dirac, matpc);
132  } else if (g.Ncolor()/T.Vectors().Nspin() == 16) {
133  calculateYcoarse<Float,16>(Y, X, Xinv, Yhat, uv, T, g, clover, cloverInv, kappa, mu, mu_factor, dirac, matpc);
134 #endif
135  } else if (g.Ncolor()/T.Vectors().Nspin() == 24) {
136  calculateYcoarse<Float,24>(Y, X, Xinv, Yhat, uv, T, g, clover, cloverInv, kappa, mu, mu_factor, dirac, matpc);
137  } else if (g.Ncolor()/T.Vectors().Nspin() == 32) {
138  calculateYcoarse<Float,32>(Y, X, Xinv, Yhat, uv, T, g, clover, cloverInv, kappa, mu, mu_factor, dirac, matpc);
139  } else {
140  errorQuda("Unsupported number of colors %d\n", g.Ncolor());
141  }
142  }
143 
144  //Does the heavy lifting of creating the coarse color matrices Y
145  void calculateYcoarse(GaugeField &Y, GaugeField &X, GaugeField &Xinv, GaugeField &Yhat, ColorSpinorField &uv,
146  const Transfer &T, const GaugeField &g, const GaugeField &clover, const GaugeField &cloverInv,
147  double kappa, double mu, double mu_factor, QudaDiracType dirac, QudaMatPCType matpc) {
148  checkPrecision(X, Y, uv, T.Vectors(), g);
149 
150  printfQuda("Computing Y field......\n");
151  if (Y.Precision() == QUDA_DOUBLE_PRECISION) {
152 #ifdef GPU_MULTIGRID_DOUBLE
153  calculateYcoarse<double>(Y, X, Xinv, Yhat, uv, T, g, clover, cloverInv, kappa, mu, mu_factor, dirac, matpc);
154 #else
155  errorQuda("Double precision multigrid has not been enabled");
156 #endif
157  } else if (Y.Precision() == QUDA_SINGLE_PRECISION) {
158  calculateYcoarse<float>(Y, X, Xinv, Yhat, uv, T, g, clover, cloverInv, kappa, mu, mu_factor, dirac, matpc);
159  } else {
160  errorQuda("Unsupported precision %d\n", Y.Precision());
161  }
162  printfQuda("....done computing Y field\n");
163  }
164 
165 #endif // GPU_MULTIGRID
166 
167  //Calculates the coarse color matrix and puts the result in Y.
168  //N.B. Assumes Y, X have been allocated.
170  const GaugeField &gauge, const GaugeField &clover, const GaugeField &cloverInv,
171  double kappa, double mu, double mu_factor, QudaDiracType dirac, QudaMatPCType matpc) {
172 
173 #ifdef GPU_MULTIGRID
174  QudaPrecision precision = Y.Precision();
175  QudaFieldLocation location = checkLocation(X, Y, Xinv, Yhat, gauge, clover, cloverInv);
176 
177  //Create a field UV which holds U*V. Has the same similar
178  //structure to V but double the number of spins so we can store
179  //the four distinct block chiral multiplications in a single UV
180  //computation.
181  ColorSpinorParam UVparam(T.Vectors(location));
182  UVparam.create = QUDA_ZERO_FIELD_CREATE;
183  UVparam.location = location;
184  UVparam.nSpin *= 2; // so nSpin == 4
185 
187 
188  calculateYcoarse(Y, X, Xinv, Yhat, *uv, T, gauge, clover, cloverInv, kappa, mu, mu_factor, dirac, matpc);
189 
190  delete uv;
191 #else
192  errorQuda("Multigrid has not been built");
193 #endif // GPU_MULTIGRID
194  }
195 
196 } //namespace quda
double mu
Definition: test_util.cpp:1643
enum QudaPrecision_s QudaPrecision
#define checkPrecision(...)
#define errorQuda(...)
Definition: util_quda.h:90
double mu_factor[QUDA_MAX_MG_LEVEL]
Definition: test_util.cpp:1659
enum QudaFieldOrder_s QudaFieldOrder
static ColorSpinorField * Create(const ColorSpinorParam &param)
void matpc(void *outEven, void **gauge, void *inEven, double kappa, QudaMatPCType matpc_type, int dagger_bit, QudaPrecision sPrecision, QudaPrecision gPrecision, double mferm)
const ColorSpinorField & Vectors(QudaFieldLocation location=QUDA_CPU_FIELD_LOCATION) const
Definition: transfer.h:195
VOLATILE spinorFloat kappa
enum QudaMatPCType_s QudaMatPCType
#define checkLocation(...)
enum QudaGaugeFieldOrder_s QudaGaugeFieldOrder
Main header file for host and device accessors to GaugeFields.
void CoarseCoarseOp(GaugeField &Y, GaugeField &X, GaugeField &Xinv, GaugeField &Yhat, const Transfer &T, const GaugeField &gauge, const GaugeField &clover, const GaugeField &cloverInv, double kappa, double mu, double mu_factor, QudaDiracType dirac, QudaMatPCType matpc)
Coarse operator construction from an intermediate-grid operator (Coarse)
enum QudaFieldLocation_s QudaFieldLocation
GaugeCovDev * dirac
Definition: covdev_test.cpp:75
#define printfQuda(...)
Definition: util_quda.h:84
QudaPrecision Precision() const
enum QudaDiracType_s QudaDiracType