QUDA  v0.5.0
A library for QCD on GPUs
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
color_spinor_field.h
Go to the documentation of this file.
1 #ifndef _COLOR_SPINOR_FIELD_H
2 #define _COLOR_SPINOR_FIELD_H
3 
4 #include <quda_internal.h>
5 #include <quda.h>
6 
7 #include <iostream>
8 #include <complex>
9 
10 #include <lattice_field.h>
11 
12 namespace quda {
13  typedef std::complex<double> Complex;
14 
15  struct FullClover;
16 
18  public:
19  int nColor; // Number of colors of the field
20  int nSpin; // =1 for staggered, =2 for coarse Dslash, =4 for 4d spinor
21  int nDim; // number of spacetime dimensions
22  int x[QUDA_MAX_DIM]; // size of each dimension
23  QudaPrecision precision; // Precision of the field
24  int pad; // volumetric padding
25 
26  QudaTwistFlavorType twistFlavor; // used by twisted mass
27 
28  QudaSiteSubset siteSubset; // Full, even or odd
29  QudaSiteOrder siteOrder; // defined for full fields
30 
31  QudaFieldOrder fieldOrder; // Float, Float2, Float4 etc.
34 
35  void *v; // pointer to field
36  void *norm;
37 
39 
41 
48  {
49  for(int d=0; d<QUDA_MAX_DIM; d++) x[d] = 0;
50  }
51 
52  // used to create cpu params
53  ColorSpinorParam(void *V, QudaFieldLocation location, QudaInvertParam &inv_param, const int *X, const bool pc_solution)
54  : nColor(3), nSpin(inv_param.dslash_type == QUDA_ASQTAD_DSLASH ? 1 : 4), nDim(4),
56  fieldOrder(QUDA_INVALID_FIELD_ORDER), gammaBasis(inv_param.gamma_basis),
57  create(QUDA_REFERENCE_FIELD_CREATE), v(V), verbose(inv_param.verbosity)
58  {
59 
60  if (nDim > QUDA_MAX_DIM) errorQuda("Number of dimensions too great");
61  for (int d=0; d<nDim; d++) x[d] = X[d];
62 
63  if (location == QUDA_CPU_FIELD_LOCATION) {
64  precision = inv_param.cpu_prec;
65  } else {
66  precision = inv_param.cuda_prec;
67  }
68 
69  if (!pc_solution) {
71  } else {
72  x[0] /= 2; // X defined the full lattice dimensions
74  }
75 
76  if (inv_param.dslash_type == QUDA_DOMAIN_WALL_DSLASH) {
77  nDim++;
78  x[4] = inv_param.Ls;
79  }
81  nDim++;
82  x[4] = 2;//for two flavors
83  }
84 
85  if (inv_param.dirac_order == QUDA_INTERNAL_DIRAC_ORDER) {
89  } else if (inv_param.dirac_order == QUDA_CPS_WILSON_DIRAC_ORDER) {
92  } else if (inv_param.dirac_order == QUDA_QDP_DIRAC_ORDER) {
95  } else if (inv_param.dirac_order == QUDA_DIRAC_ORDER) {
98  } else {
99  errorQuda("Dirac order %d not supported", inv_param.dirac_order);
100  }
101  }
102 
103  // used to create cuda param from a cpu param
105  : nColor(cpuParam.nColor), nSpin(cpuParam.nSpin),
106  nDim(cpuParam.nDim), precision(inv_param.cuda_prec), pad(inv_param.sp_pad),
107  twistFlavor(cpuParam.twistFlavor), siteSubset(cpuParam.siteSubset),
111  {
112  if (nDim > QUDA_MAX_DIM) errorQuda("Number of dimensions too great");
113  for (int d=0; d<nDim; d++) x[d] = cpuParam.x[d];
114 
117  }
118 
120  this->precision = precision;
121  fieldOrder = (precision == QUDA_DOUBLE_PRECISION || nSpin == 1) ?
123  }
124 
125  void print() {
126  printfQuda("nColor = %d\n", nColor);
127  printfQuda("nSpin = %d\n", nSpin);
128  printfQuda("twistFlavor = %d\n", twistFlavor);
129  printfQuda("nDim = %d\n", nDim);
130  for (int d=0; d<nDim; d++) printfQuda("x[%d] = %d\n", d, x[d]);
131  printfQuda("precision = %d\n", precision);
132  printfQuda("pad = %d\n", pad);
133  printfQuda("siteSubset = %d\n", siteSubset);
134  printfQuda("siteOrder = %d\n", siteOrder);
135  printfQuda("fieldOrder = %d\n", fieldOrder);
136  printfQuda("gammaBasis = %d\n", gammaBasis);
137  printfQuda("create = %d\n", create);
138  printfQuda("v = %lx\n", (unsigned long)v);
139  printfQuda("norm = %lx\n", (unsigned long)norm);
140  }
141 
142  virtual ~ColorSpinorParam() {
143  }
144  };
145 
146  class cpuColorSpinorField;
147  class cudaColorSpinorField;
148 
150 
151  private:
152  void create(int nDim, const int *x, int Nc, int Ns, QudaTwistFlavorType Twistflavor,
155  void destroy();
156 
157  QudaVerbosity verbose;
158 
159  protected:
160  bool init;
162 
163  int nColor;
164  int nSpin;
165 
166  int nDim;
167  int x[QUDA_MAX_DIM];
168 
169  int volume;
170  int pad;
171  int stride;
172 
174 
175  int real_length; // physical length only
176  int length; // length including pads, but not ghost zone - used for BLAS
177 
178  void *v; // the field elements
179  void *norm; // the normalization field
180 
181  // multi-GPU parameters
182  void* ghost[QUDA_MAX_DIM]; // pointers to the ghost regions - NULL by default
183  void* ghostNorm[QUDA_MAX_DIM]; // pointers to ghost norms - NULL by default
184 
185  int ghostFace[QUDA_MAX_DIM];// the size of each face
186  int ghostOffset[QUDA_MAX_DIM]; // offsets to each ghost zone
187  int ghostNormOffset[QUDA_MAX_DIM]; // offsets to each ghost zone for norm field
188 
189  int ghost_length; // length of ghost zone
190  int ghost_norm_length; // length of ghost zone for norm
191  int total_length; // total length of spinor (physical + pad + ghost)
192  int total_norm_length; // total length of norm
193 
194  size_t bytes; // size in bytes of spinor field
195  size_t norm_bytes; // size in bytes of norm field
196 
201 
202  // in the case of full fields, these are references to the even / odd sublattices
205 
206  void createGhostZone();
207 
208  // resets the above attributes based on contents of param
209  void reset(const ColorSpinorParam &);
210  void fill(ColorSpinorParam &) const;
211  static void checkField(const ColorSpinorField &, const ColorSpinorField &);
212  void clearGhostPointers();
213 
214  public:
215  //ColorSpinorField();
218 
219  virtual ~ColorSpinorField();
220 
221  virtual ColorSpinorField& operator=(const ColorSpinorField &);
222 
223  QudaPrecision Precision() const { return precision; }
224  int Ncolor() const { return nColor; }
225  int Nspin() const { return nSpin; }
227  int Ndim() const { return nDim; }
228  const int* X() const { return x; }
229  int X(int d) const { return x[d]; }
230  int RealLength() const { return real_length; }
231  int Length() const { return length; }
232  int TotalLength() const { return total_length; }
233  int Stride() const { return stride; }
234  int Volume() const { return volume; }
235  int Pad() const { return pad; }
236  size_t Bytes() const { return bytes; }
237  size_t NormBytes() const { return norm_bytes; }
238  void PrintDims() const { printfQuda("dimensions=%d %d %d %d\n", x[0], x[1], x[2], x[3]); }
239 
240  virtual QudaFieldLocation Location() const = 0;
242  QudaSiteOrder SiteOrder() const { return siteOrder; }
245 
246  int GhostLength() const { return ghost_length; }
247  const int *GhostFace() const { return ghostFace; }
248  int GhostOffset(const int i) const { return ghostOffset[i]; }
249  int GhostNormOffset(const int i ) const { return ghostNormOffset[i]; }
250  void* Ghost(const int i);
251  const void* Ghost(const int i) const;
252  void* GhostNorm(const int i);
253  const void* GhostNorm(const int i) const;
254 
255  friend std::ostream& operator<<(std::ostream &out, const ColorSpinorField &);
256  friend class ColorSpinorParam;
257  };
258 
259  // CUDA implementation
261 
262  friend class cpuColorSpinorField;
263 
264  private:
265  //void *v; // the field elements
266  //void *norm; // the normalization field
267  bool alloc; // whether we allocated memory
268  bool init;
269 
270  bool texInit; // whether a texture object has been created or not
271 #ifdef USE_TEXTURE_OBJECTS
272  cudaTextureObject_t tex;
273  cudaTextureObject_t texNorm;
274  void createTexObject();
275  void destroyTexObject();
276 #endif
277 
278  bool reference; // whether the field is a reference or not
279 
280  static void *buffer_h;// pinned memory
281  static void *buffer_d;// device_mapped pointer to buffer
282  static bool bufferInit;
283  static size_t bufferBytes;
284 
285  static void* ghostFaceBuffer; // gpu memory
286  static void* fwdGhostFaceBuffer[QUDA_MAX_DIM]; // pointers to ghostFaceBuffer
287  static void* backGhostFaceBuffer[QUDA_MAX_DIM]; // pointers to ghostFaceBuffer
288  static int initGhostFaceBuffer;
289  static QudaPrecision facePrecision;
290 
291  void create(const QudaFieldCreate);
292  void destroy();
293  void copy(const cudaColorSpinorField &);
294 
295  void zeroPad();
296 
297  void resizeBuffer(size_t bytes) const;
298  void loadSpinorField(const ColorSpinorField &src);
299  void saveSpinorField (ColorSpinorField &src) const;
300  bool isNative() const;
301 
302  public:
303  //cudaColorSpinorField();
308  virtual ~cudaColorSpinorField();
309 
313 
314  void allocateGhostBuffer(void);
315  static void freeGhostBuffer(void);
316 
317  void packGhost(const QudaParity parity, const int dagger, cudaStream_t* stream);
318  void sendGhost(void *ghost_spinor, const int dim, const QudaDirection dir,
319  const int dagger, cudaStream_t *stream);
320  void unpackGhost(void* ghost_spinor, const int dim, const QudaDirection dir,
321  const int dagger, cudaStream_t* stream);
322 
323  void* V() {return v;}
324  const void* V() const {return v;}
325  void* Norm(){return norm;}
326  const void* Norm() const {return norm;}
327 
328 #ifdef USE_TEXTURE_OBJECTS
329  const cudaTextureObject_t& Tex() const { return tex; }
330  const cudaTextureObject_t& TexNorm() const { return texNorm; }
331 #endif
332 
333  cudaColorSpinorField& Even() const;
334  cudaColorSpinorField& Odd() const;
335 
336  static void freeBuffer();
337 
338  void zero();
339 
340  QudaFieldLocation Location() const;
341 
342  friend std::ostream& operator<<(std::ostream &out, const cudaColorSpinorField &);
343  };
344 
345  // Forward declaration of accessor functors
346  template <typename Float> class ColorSpinorFieldOrder;
347  template <typename Float> class SpaceColorSpinOrder;
348  template <typename Float> class SpaceSpinColorOrder;
349  template <typename Float> class QOPDomainWallOrder;
350 
351  // CPU implementation
353 
354  friend class cudaColorSpinorField;
355 
356  template <typename Float> friend class SpaceColorSpinOrder;
357  template <typename Float> friend class SpaceSpinColorOrder;
358  template <typename Float> friend class QOPDomainWallOrder;
359 
360  public:
361  static void* fwdGhostFaceBuffer[QUDA_MAX_DIM]; //cpu memory
362  static void* backGhostFaceBuffer[QUDA_MAX_DIM]; //cpu memory
363  static void* fwdGhostFaceSendBuffer[QUDA_MAX_DIM]; //cpu memory
364  static void* backGhostFaceSendBuffer[QUDA_MAX_DIM]; //cpu memory
366 
367  private:
368  //void *v; // the field elements
369  //void *norm; // the normalization field
370  bool init;
371  bool reference; // whether the field is a reference or not
372 
373  void create(const QudaFieldCreate);
374  void destroy();
375 
376  void createOrder(); // create the accessor for a given field ordering
377  ColorSpinorFieldOrder<double> *order_double; // accessor functor used to access fp64 elements
378  ColorSpinorFieldOrder<float> *order_single; // accessor functor used to access fp32 elements
379 
380  public:
381  //cpuColorSpinorField();
385  virtual ~cpuColorSpinorField();
386 
390 
391  //cpuColorSpinorField& Even() const;
392  //cpuColorSpinorField& Odd() const;
393 
394  void Source(const QudaSourceType sourceType, const int st=0, const int s=0, const int c=0);
395  static int Compare(const cpuColorSpinorField &a, const cpuColorSpinorField &b, const int resolution=1);
396  void PrintVector(unsigned int x);
397 
398  void allocateGhostBuffer(void);
399  static void freeGhostBuffer(void);
400 
401  void packGhost(void* ghost_spinor, const int dim,
402  const QudaDirection dir, const QudaParity parity, const int dagger);
403  void unpackGhost(void* ghost_spinor, const int dim,
404  const QudaDirection dir, const int dagger);
405 
406  void* V() { return v; }
407  const void * V() const { return v; }
408 
409  void copy(const cpuColorSpinorField&);
410  void zero();
411 
412  QudaFieldLocation Location() const;
413  };
414 
415 } // namespace quda
416 
417 #endif // _COLOR_SPINOR_FIELD_H