QUDA v0.4.0
A library for QCD on GPUs
quda/include/color_spinor_field.h
Go to the documentation of this file.
00001 #include <quda_internal.h>
00002 #include <quda.h>
00003 
00004 #include <iostream>
00005 #include <complex>
00006 
00007 namespace quda {
00008   typedef std::complex<double> Complex;
00009 }
00010 
00011 #ifndef _COLOR_SPINOR_FIELD_H
00012 #define _COLOR_SPINOR_FIELD_H
00013 
00014 // Probably want some checking for this limit
00015 #define QUDA_MAX_DIM 6
00016 
00017 #include <lattice_field.h>
00018 
00019 struct FullClover;
00020 
00021 class ColorSpinorParam {
00022  public:
00023   QudaFieldLocation fieldLocation; // cpu, cuda etc. 
00024   int nColor; // Number of colors of the field
00025   int nSpin; // =1 for staggered, =2 for coarse Dslash, =4 for 4d spinor
00026   int nDim; // number of spacetime dimensions
00027   int x[QUDA_MAX_DIM]; // size of each dimension
00028   QudaPrecision precision; // Precision of the field
00029   int pad; // volumetric padding
00030 
00031   QudaTwistFlavorType twistFlavor; // used by twisted mass
00032 
00033   QudaSiteSubset siteSubset; // Full, even or odd
00034   QudaSiteOrder siteOrder; // defined for full fields
00035   
00036   QudaFieldOrder fieldOrder; // Float, Float2, Float4 etc.
00037   QudaGammaBasis gammaBasis;
00038   QudaFieldCreate create; // 
00039 
00040   void *v; // pointer to field
00041   void *norm;
00042 
00043   ColorSpinorParam(const ColorSpinorField &a);
00044 
00045   QudaVerbosity verbose;
00046 
00047  ColorSpinorParam()
00048    : fieldLocation(QUDA_INVALID_FIELD_LOCATION), nColor(0), nSpin(0), nDim(0), 
00049     precision(QUDA_INVALID_PRECISION), pad(0), twistFlavor(QUDA_TWIST_INVALID),
00050     siteSubset(QUDA_INVALID_SITE_SUBSET), siteOrder(QUDA_INVALID_SITE_ORDER), 
00051     fieldOrder(QUDA_INVALID_FIELD_ORDER), gammaBasis(QUDA_INVALID_GAMMA_BASIS), 
00052     create(QUDA_INVALID_FIELD_CREATE), verbose(QUDA_SILENT)
00053     { 
00054       for(int d=0; d<QUDA_MAX_DIM; d++) {
00055         x[d] = 0; 
00056       }
00057     }
00058   
00059   // used to create cpu params
00060  ColorSpinorParam(void *V, QudaInvertParam &inv_param, const int *X, const bool pc_solution)
00061    : fieldLocation(QUDA_CPU_FIELD_LOCATION), nColor(3), 
00062     nSpin(inv_param.dslash_type == QUDA_ASQTAD_DSLASH ? 1 : 4), nDim(4), 
00063     precision(inv_param.cpu_prec), pad(0), twistFlavor(inv_param.twist_flavor), 
00064     siteSubset(QUDA_INVALID_SITE_SUBSET), siteOrder(QUDA_INVALID_SITE_ORDER), 
00065     fieldOrder(QUDA_INVALID_FIELD_ORDER), gammaBasis(inv_param.gamma_basis), 
00066     create(QUDA_REFERENCE_FIELD_CREATE), v(V), verbose(inv_param.verbosity)
00067   { 
00068 
00069     if (nDim > QUDA_MAX_DIM) errorQuda("Number of dimensions too great");
00070     for (int d=0; d<nDim; d++) x[d] = X[d];
00071 
00072     if (!pc_solution) {
00073       siteSubset = QUDA_FULL_SITE_SUBSET;;
00074     } else {
00075       x[0] /= 2; // X defined the full lattice dimensions
00076       siteSubset = QUDA_PARITY_SITE_SUBSET;
00077     }
00078 
00079     if (inv_param.dslash_type == QUDA_DOMAIN_WALL_DSLASH) {
00080       nDim++;
00081       x[4] = inv_param.Ls;
00082     }
00083 
00084     if (inv_param.dirac_order == QUDA_CPS_WILSON_DIRAC_ORDER) {
00085       fieldOrder = QUDA_SPACE_SPIN_COLOR_FIELD_ORDER;
00086       siteOrder = QUDA_ODD_EVEN_SITE_ORDER;
00087     } else if (inv_param.dirac_order == QUDA_QDP_DIRAC_ORDER) {
00088       fieldOrder = QUDA_SPACE_COLOR_SPIN_FIELD_ORDER;
00089       siteOrder = QUDA_EVEN_ODD_SITE_ORDER;
00090     } else if (inv_param.dirac_order == QUDA_DIRAC_ORDER) {
00091       fieldOrder = QUDA_SPACE_SPIN_COLOR_FIELD_ORDER;
00092       siteOrder = QUDA_EVEN_ODD_SITE_ORDER;
00093     } else {
00094       errorQuda("Dirac order %d not supported", inv_param.dirac_order);
00095     }
00096   }
00097 
00098   // used to create cuda param from a cpu param
00099  ColorSpinorParam(ColorSpinorParam &cpuParam, QudaInvertParam &inv_param) 
00100     : fieldLocation(QUDA_CUDA_FIELD_LOCATION), nColor(cpuParam.nColor), nSpin(cpuParam.nSpin), 
00101     nDim(cpuParam.nDim), precision(inv_param.cuda_prec), pad(inv_param.sp_pad),  
00102     twistFlavor(cpuParam.twistFlavor), siteSubset(cpuParam.siteSubset), 
00103     siteOrder(QUDA_EVEN_ODD_SITE_ORDER), fieldOrder(QUDA_INVALID_FIELD_ORDER), 
00104     gammaBasis(nSpin == 4? QUDA_UKQCD_GAMMA_BASIS : QUDA_DEGRAND_ROSSI_GAMMA_BASIS), 
00105     create(QUDA_COPY_FIELD_CREATE), v(0), verbose(cpuParam.verbose)
00106   {
00107     if (nDim > QUDA_MAX_DIM) errorQuda("Number of dimensions too great");
00108     for (int d=0; d<nDim; d++) x[d] = cpuParam.x[d];
00109 
00110     if (precision == QUDA_DOUBLE_PRECISION || nSpin == 1) {
00111       fieldOrder = QUDA_FLOAT2_FIELD_ORDER;
00112     } else {
00113       fieldOrder = QUDA_FLOAT4_FIELD_ORDER;
00114     }
00115 
00116   }
00117 
00118   void print() {
00119     printfQuda("fieldLocation = %d\n", fieldLocation);
00120     printfQuda("nColor = %d\n", nColor);
00121     printfQuda("nSpin = %d\n", nSpin);
00122     printfQuda("twistFlavor = %d\n", twistFlavor);
00123     printfQuda("nDim = %d\n", nDim);
00124     for (int d=0; d<nDim; d++) printfQuda("x[%d] = %d\n", d, x[d]);
00125     printfQuda("precision = %d\n", precision);
00126     printfQuda("pad = %d\n", pad);
00127     printfQuda("siteSubset = %d\n", siteSubset);
00128     printfQuda("siteOrder = %d\n", siteOrder);
00129     printfQuda("fieldOrder = %d\n", fieldOrder);
00130     printfQuda("gammaBasis = %d\n", gammaBasis);
00131     printfQuda("create = %d\n", create);
00132     printfQuda("v = %lx\n", (unsigned long)v);
00133     printfQuda("norm = %lx\n", (unsigned long)norm);
00134   }
00135 
00136   virtual ~ColorSpinorParam() {
00137   }
00138 };
00139 
00140 class cpuColorSpinorField;
00141 class cudaColorSpinorField;
00142 
00143 class ColorSpinorField {
00144 
00145  private:
00146   void create(int nDim, const int *x, int Nc, int Ns, QudaTwistFlavorType Twistflavor, 
00147               QudaPrecision precision, int pad, QudaFieldLocation location, QudaSiteSubset subset, 
00148               QudaSiteOrder siteOrder, QudaFieldOrder fieldOrder, QudaGammaBasis gammaBasis);
00149   void destroy();  
00150 
00151   QudaVerbosity verbose;
00152 
00153  protected:
00154   bool init;
00155   QudaPrecision precision;
00156 
00157   int nColor;
00158   int nSpin;
00159   
00160   int nDim;
00161   int x[QUDA_MAX_DIM];
00162 
00163   int volume;
00164   int pad;
00165   int stride;
00166 
00167   QudaTwistFlavorType twistFlavor;
00168   
00169   int real_length; // physical length only
00170   int length; // length including pads, but not ghost zone - used for BLAS
00171 
00172   // multi-GPU parameters
00173   int ghostFace[QUDA_MAX_DIM];// the size of each face
00174   int ghostOffset[QUDA_MAX_DIM]; // offsets to each ghost zone
00175   int ghostNormOffset[QUDA_MAX_DIM]; // offsets to each ghost zone for norm field
00176 
00177   int ghost_length; // length of ghost zone
00178   int ghost_norm_length; // length of ghost zone for norm
00179   int total_length; // total length of spinor (physical + pad + ghost)
00180   int total_norm_length; // total length of norm
00181 
00182   size_t bytes; // size in bytes of spinor field
00183   size_t norm_bytes; // size in bytes of norm field
00184 
00185   QudaFieldLocation fieldLocation;
00186   QudaSiteSubset siteSubset;
00187   QudaSiteOrder siteOrder;
00188   QudaFieldOrder fieldOrder;
00189   QudaGammaBasis gammaBasis;
00190   
00191   // in the case of full fields, these are references to the even / odd sublattices
00192   ColorSpinorField *even;
00193   ColorSpinorField *odd;
00194 
00195   void createGhostZone();
00196 
00197   // resets the above attributes based on contents of param
00198   void reset(const ColorSpinorParam &);
00199   void fill(ColorSpinorParam &) const;
00200   static void checkField(const ColorSpinorField &, const ColorSpinorField &);
00201 
00202  public:
00203   //ColorSpinorField();
00204   ColorSpinorField(const ColorSpinorField &);
00205   ColorSpinorField(const ColorSpinorParam &);
00206 
00207   virtual ~ColorSpinorField();
00208 
00209   ColorSpinorField& operator=(const ColorSpinorField &);
00210 
00211   QudaPrecision Precision() const { return precision; }
00212   int Ncolor() const { return nColor; } 
00213   int Nspin() const { return nSpin; } 
00214   int TwistFlavor() const { return twistFlavor; } 
00215   int Ndim() const { return nDim; }
00216   const int* X() const { return x; }
00217   int X(int d) const { return x[d]; }
00218   int RealLength() const { return real_length; }
00219   int Length() const { return length; }
00220   int Stride() const { return stride; }
00221   int Volume() const { return volume; }
00222   size_t Bytes() const { return bytes; }
00223   size_t NormBytes() const { return norm_bytes; }
00224   void PrintDims() const { printf("dimensions=%d %d %d %d\n",
00225                                   x[0], x[1], x[2], x[3]);}
00226   
00227   QudaFieldLocation FieldLocation() const { return fieldLocation; }
00228   QudaSiteSubset SiteSubset() const { return siteSubset; }
00229   QudaSiteOrder SiteOrder() const { return siteOrder; }
00230   QudaFieldOrder FieldOrder() const { return fieldOrder; }
00231   QudaGammaBasis GammaBasis() const { return gammaBasis; }
00232 
00233   int GhostLength() const { return ghost_length; }
00234   const int *GhostFace() const { return ghostFace; }  
00235   int GhostOffset(const int i) const { return ghostOffset[i]; }  
00236   int GhostNormOffset(const int i ) const { return ghostNormOffset[i]; }  
00237 
00238   friend std::ostream& operator<<(std::ostream &out, const ColorSpinorField &);
00239   friend class ColorSpinorParam;
00240 };
00241 
00242 // CUDA implementation
00243 class cudaColorSpinorField : public ColorSpinorField {
00244 
00245   friend class cpuColorSpinorField;
00246 
00247  private:
00248   void *v; // the field elements
00249   void *norm; // the normalization field
00250   bool alloc; // whether we allocated memory
00251   bool init;
00252 
00253   static void *buffer;// pinned memory
00254   static bool bufferInit;
00255   static size_t bufferBytes;
00256 
00257   static void* fwdGhostFaceBuffer[QUDA_MAX_DIM]; //gpu memory
00258   static void* backGhostFaceBuffer[QUDA_MAX_DIM]; //gpu memory
00259   static int initGhostFaceBuffer;
00260   static QudaPrecision facePrecision;
00261 
00262   void create(const QudaFieldCreate);
00263   void destroy();
00264   void copy(const cudaColorSpinorField &);
00265 
00266   void zeroPad();
00267 
00268  public:
00269   //cudaColorSpinorField();
00270   cudaColorSpinorField(const cudaColorSpinorField&);
00271   cudaColorSpinorField(const ColorSpinorField&, const ColorSpinorParam&);
00272   cudaColorSpinorField(const ColorSpinorField&);
00273   cudaColorSpinorField(const ColorSpinorParam&);
00274   virtual ~cudaColorSpinorField();
00275 
00276   cudaColorSpinorField& operator=(const cudaColorSpinorField&);
00277   cudaColorSpinorField& operator=(const cpuColorSpinorField&);
00278 
00279   void loadCPUSpinorField(const cpuColorSpinorField &src);
00280   void saveCPUSpinorField (cpuColorSpinorField &src) const;
00281 
00282   void allocateGhostBuffer(void);
00283   static void freeGhostBuffer(void);
00284 
00285   void packGhost(const int dim, const QudaParity parity, const int dagger, cudaStream_t* stream);
00286   void sendGhost(void *ghost_spinor, const int dim, const QudaDirection dir,
00287                  const int dagger, cudaStream_t *stream);
00288   void unpackGhost(void* ghost_spinor, const int dim, const QudaDirection dir, 
00289                    const int dagger, cudaStream_t* stream);
00290 
00291   void* V() {return v;}
00292   const void* V() const {return v;}
00293   void* Norm(){return norm;}
00294   const void* Norm() const {return norm;}
00295 
00296   cudaColorSpinorField& Even() const;
00297   cudaColorSpinorField& Odd() const;
00298 
00299   static void freeBuffer();
00300 
00301   void zero();
00302 
00303   friend std::ostream& operator<<(std::ostream &out, const cudaColorSpinorField &);
00304 };
00305 
00306 // Forward declaration of accessor functors
00307 template <typename Float> class ColorSpinorFieldOrder;
00308 template <typename Float> class SpaceColorSpinOrder;
00309 template <typename Float> class SpaceSpinColorOrder;
00310 template <typename Float> class QOPDomainWallOrder;
00311 
00312 // CPU implementation
00313 class cpuColorSpinorField : public ColorSpinorField {
00314 
00315   friend class cudaColorSpinorField;
00316 
00317   template <typename Float> friend class SpaceColorSpinOrder;
00318   template <typename Float> friend class SpaceSpinColorOrder;
00319   template <typename Float> friend class QOPDomainWallOrder;
00320 
00321  public:
00322   static void* fwdGhostFaceBuffer[QUDA_MAX_DIM]; //cpu memory
00323   static void* backGhostFaceBuffer[QUDA_MAX_DIM]; //cpu memory
00324   static void* fwdGhostFaceSendBuffer[QUDA_MAX_DIM]; //cpu memory
00325   static void* backGhostFaceSendBuffer[QUDA_MAX_DIM]; //cpu memory
00326   static int initGhostFaceBuffer;
00327 
00328  private:
00329   void *v; // the field elements
00330   void *norm; // the normalization field
00331   bool init;
00332   
00333   void create(const QudaFieldCreate);
00334   void destroy();
00335 
00336   void createOrder(); // create the accessor for a given field ordering
00337   ColorSpinorFieldOrder<double> *order_double; // accessor functor used to access fp64 elements
00338   ColorSpinorFieldOrder<float> *order_single; // accessor functor used to access fp32 elements
00339 
00340  public:
00341   //cpuColorSpinorField();
00342   cpuColorSpinorField(const cpuColorSpinorField&);
00343   cpuColorSpinorField(const ColorSpinorField&);
00344   cpuColorSpinorField(const ColorSpinorParam&);
00345   virtual ~cpuColorSpinorField();
00346 
00347   cpuColorSpinorField& operator=(const cpuColorSpinorField&);
00348   cpuColorSpinorField& operator=(const cudaColorSpinorField&);
00349 
00350   //cpuColorSpinorField& Even() const;
00351   //cpuColorSpinorField& Odd() const;
00352 
00353   void Source(const QudaSourceType sourceType, const int st=0, const int s=0, const int c=0);
00354   static int Compare(const cpuColorSpinorField &a, const cpuColorSpinorField &b, const int resolution=1);
00355   void PrintVector(unsigned int x);
00356 
00357   void allocateGhostBuffer(void);
00358   static void freeGhostBuffer(void);
00359         
00360   void packGhost(void* ghost_spinor, const int dim, 
00361                  const QudaDirection dir, const QudaParity parity, const int dagger);
00362   void unpackGhost(void* ghost_spinor, const int dim, 
00363                    const QudaDirection dir, const int dagger);
00364   
00365   void* V() { return v; }
00366   const void * V() const { return v; }
00367 
00368   void copy(const cpuColorSpinorField&);
00369   void zero();
00370 };
00371 
00372 
00373 
00374 #endif // _COLOR_SPINOR_FIELD_H
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines