QUDA v0.4.0
A library for QCD on GPUs
quda/lib/dirac.cpp
Go to the documentation of this file.
00001 #include <dirac_quda.h>
00002 #include <dslash_quda.h>
00003 #include <blas_quda.h>
00004 
00005 #include <iostream>
00006 
00007 Dirac::Dirac(const DiracParam &param) 
00008   : gauge(*(param.gauge)), kappa(param.kappa), mass(param.mass), matpcType(param.matpcType), 
00009     dagger(param.dagger), flops(0), tmp1(param.tmp1), tmp2(param.tmp2), tune(QUDA_TUNE_NO),
00010     verbose(param.verbose)
00011 {
00012   for (int i=0; i<4; i++) commDim[i] = param.commDim[i];
00013 }
00014 
00015 Dirac::Dirac(const Dirac &dirac) 
00016   : gauge(dirac.gauge), kappa(dirac.kappa), matpcType(dirac.matpcType), 
00017     dagger(dirac.dagger), flops(0), tmp1(dirac.tmp1), tmp2(dirac.tmp2), tune(QUDA_TUNE_NO),
00018     verbose(dirac.verbose)
00019 {
00020   for (int i=0; i<4; i++) commDim[i] = dirac.commDim[i];
00021 }
00022 
00023 Dirac::~Dirac() {
00024 
00025 }
00026 
00027 Dirac& Dirac::operator=(const Dirac &dirac)
00028 {
00029   if(&dirac != this) {
00030     gauge = dirac.gauge;
00031     kappa = dirac.kappa;
00032     matpcType = dirac.matpcType;
00033     dagger = dirac.dagger;
00034     flops = 0;
00035     tmp1 = dirac.tmp1;
00036     tmp2 = dirac.tmp2;
00037     verbose = dirac.verbose;
00038 
00039     tune = dirac.tune;
00040 
00041     for (int i=0; i<4; i++) commDim[i] = dirac.commDim[i];
00042   }
00043 
00044   return *this;
00045 }
00046 
00047 bool Dirac::newTmp(cudaColorSpinorField **tmp, const cudaColorSpinorField &a) const {
00048   if (*tmp) return false;
00049   ColorSpinorParam param(a);
00050   param.create = QUDA_ZERO_FIELD_CREATE; // need to zero elements else padded region will be junk
00051   *tmp = new cudaColorSpinorField(a, param);
00052   return true;
00053 }
00054 
00055 void Dirac::deleteTmp(cudaColorSpinorField **a, const bool &reset) const {
00056   if (reset) {
00057     delete *a;
00058     *a = NULL;
00059   }
00060 }
00061 
00062 #define flip(x) (x) = ((x) == QUDA_DAG_YES ? QUDA_DAG_NO : QUDA_DAG_YES)
00063 
00064 void Dirac::Mdag(cudaColorSpinorField &out, const cudaColorSpinorField &in) const
00065 {
00066   flip(dagger);
00067   M(out, in);
00068   flip(dagger);
00069 }
00070 
00071 #undef flip
00072 
00073 void Dirac::checkParitySpinor(const cudaColorSpinorField &out, const cudaColorSpinorField &in) const
00074 {
00075   if (in.GammaBasis() != QUDA_UKQCD_GAMMA_BASIS || 
00076       out.GammaBasis() != QUDA_UKQCD_GAMMA_BASIS) {
00077     errorQuda("CUDA Dirac operator requires UKQCD basis, out = %d, in = %d", 
00078               out.GammaBasis(), in.GammaBasis());
00079   }
00080 
00081   if (in.Precision() != out.Precision()) {
00082     errorQuda("Input precision %d and output spinor precision %d don't match in dslash_quda",
00083               in.Precision(), out.Precision());
00084   }
00085 
00086   if (in.Stride() != out.Stride()) {
00087     errorQuda("Input %d and output %d spinor strides don't match in dslash_quda", 
00088               in.Stride(), out.Stride());
00089   }
00090 
00091   if (in.SiteSubset() != QUDA_PARITY_SITE_SUBSET || out.SiteSubset() != QUDA_PARITY_SITE_SUBSET) {
00092     errorQuda("ColorSpinorFields are not single parity: in = %d, out = %d", 
00093               in.SiteSubset(), out.SiteSubset());
00094   }
00095 
00096   if (out.Ndim() != 5) {
00097     if ((out.Volume() != gauge.Volume() && out.SiteSubset() == QUDA_FULL_SITE_SUBSET) ||
00098         (out.Volume() != gauge.VolumeCB() && out.SiteSubset() == QUDA_PARITY_SITE_SUBSET) ) {
00099       errorQuda("Spinor volume %d doesn't match gauge volume %d", out.Volume(), gauge.VolumeCB());
00100     }
00101   } else {
00102     // Domain wall fermions, compare 4d volumes not 5d
00103     if ((out.Volume()/out.X(4) != gauge.Volume() && out.SiteSubset() == QUDA_FULL_SITE_SUBSET) ||
00104         (out.Volume()/out.X(4) != gauge.VolumeCB() && out.SiteSubset() == QUDA_PARITY_SITE_SUBSET) ) {
00105       errorQuda("Spinor volume %d doesn't match gauge volume %d", out.Volume(), gauge.VolumeCB());
00106     }
00107   }
00108 }
00109 
00110 void Dirac::checkFullSpinor(const cudaColorSpinorField &out, const cudaColorSpinorField &in) const
00111 {
00112    if (in.SiteSubset() != QUDA_FULL_SITE_SUBSET || out.SiteSubset() != QUDA_FULL_SITE_SUBSET) {
00113     errorQuda("ColorSpinorFields are not full fields: in = %d, out = %d", 
00114               in.SiteSubset(), out.SiteSubset());
00115   } 
00116 }
00117 
00118 void Dirac::checkSpinorAlias(const cudaColorSpinorField &a, const cudaColorSpinorField &b) const {
00119   if (a.V() == b.V()) errorQuda("Aliasing pointers");
00120 }
00121 
00122 // Dirac operator factory
00123 Dirac* Dirac::create(const DiracParam &param)
00124 {
00125   if (param.type == QUDA_WILSON_DIRAC) {
00126     if (param.verbose >= QUDA_VERBOSE) printfQuda("Creating a DiracWilson operator\n");
00127     return new DiracWilson(param);
00128   } else if (param.type == QUDA_WILSONPC_DIRAC) {
00129     if (param.verbose >= QUDA_VERBOSE) printfQuda("Creating a DiracWilsonPC operator\n");
00130     return new DiracWilsonPC(param);
00131   } else if (param.type == QUDA_CLOVER_DIRAC) {
00132     if (param.verbose >= QUDA_VERBOSE) printfQuda("Creating a DiracClover operator\n");
00133     return new DiracClover(param);
00134   } else if (param.type == QUDA_CLOVERPC_DIRAC) {
00135     if (param.verbose >= QUDA_VERBOSE) printfQuda("Creating a DiracCloverPC operator\n");
00136     return new DiracCloverPC(param);
00137   } else if (param.type == QUDA_DOMAIN_WALL_DIRAC) {
00138     if (param.verbose >= QUDA_VERBOSE) printfQuda("Creating a DiracDomainWall operator\n");
00139     return new DiracDomainWall(param);
00140   } else if (param.type == QUDA_DOMAIN_WALLPC_DIRAC) {
00141     if (param.verbose >= QUDA_VERBOSE) printfQuda("Creating a DiracDomainWallPC operator\n");
00142     return new DiracDomainWallPC(param);
00143   } else if (param.type == QUDA_ASQTAD_DIRAC) {
00144     if (param.verbose >= QUDA_VERBOSE) printfQuda("Creating a DiracStaggered operator\n");
00145     return new DiracStaggered(param);
00146   } else if (param.type == QUDA_ASQTADPC_DIRAC) {
00147     if (param.verbose >= QUDA_VERBOSE) printfQuda("Creating a DiracStaggeredPC operator\n");
00148     return new DiracStaggeredPC(param);    
00149   } else if (param.type == QUDA_TWISTED_MASS_DIRAC) {
00150     if (param.verbose >= QUDA_VERBOSE) printfQuda("Creating a DiracTwistedMass operator\n");
00151     return new DiracTwistedMass(param);
00152   } else if (param.type == QUDA_TWISTED_MASSPC_DIRAC) {
00153     if (param.verbose >= QUDA_VERBOSE) printfQuda("Creating a DiracTwistedMassPC operator\n");
00154     return new DiracTwistedMassPC(param);    
00155   } else {
00156     return 0;
00157   }
00158 }
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines