QUDA v0.4.0
A library for QCD on GPUs
|
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