void DiracDomainWallPC::prepare(ColorSpinorField* &src, ColorSpinorField* &sol, ColorSpinorField &x, ColorSpinorField &b, const QudaSolutionType solType) const { // we desire solution to preconditioned system if (solType == QUDA_MATPC_SOLUTION || solType == QUDA_MATPCDAG_MATPC_SOLUTION) { src = &b; sol = &x; } else { // we desire solution to full system if (matpcType == QUDA_MATPC_EVEN_EVEN) { // src = b_e + k D_eo b_o DslashXpay(x.Odd(), b.Odd(), QUDA_EVEN_PARITY, b.Even(), kappa5); src = &(x.Odd()); sol = &(x.Even()); } else if (matpcType == QUDA_MATPC_ODD_ODD) { // src = b_o + k D_oe b_e DslashXpay(x.Even(), b.Even(), QUDA_ODD_PARITY, b.Odd(), kappa5); src = &(x.Even()); sol = &(x.Odd()); } else { errorQuda("MatPCType %d not valid for DiracDomainWallPC", matpcType); } // here we use final solution to store parity solution and parity source // b is now up for grabs if we want } }
cpuColorSpinorField::cpuColorSpinorField(const ColorSpinorField &src) : ColorSpinorField(src), init(false), order_double(NULL), order_single(NULL) { create(QUDA_COPY_FIELD_CREATE); if (src.FieldLocation() == QUDA_CPU_FIELD_LOCATION) { memcpy(v, dynamic_cast<const cpuColorSpinorField&>(src).v, bytes); } else if (src.FieldLocation() == QUDA_CUDA_FIELD_LOCATION) { dynamic_cast<const cudaColorSpinorField&>(src).saveCPUSpinorField(*this); } else { errorQuda("FieldType not supported"); } }
cudaColorSpinorField::cudaColorSpinorField(const ColorSpinorField &src) : ColorSpinorField(src), alloc(false), init(true) { fieldLocation = QUDA_CUDA_FIELD_LOCATION; create(QUDA_COPY_FIELD_CREATE); if (src.FieldLocation() == QUDA_CUDA_FIELD_LOCATION) { copy(dynamic_cast<const cudaColorSpinorField&>(src)); } else if (src.FieldLocation() == QUDA_CPU_FIELD_LOCATION) { loadCPUSpinorField(src); } else { errorQuda("FieldLocation not supported"); } }
// Apply the even-odd preconditioned clover-improved Dirac operator void DiracDomainWallPC::M(ColorSpinorField &out, const ColorSpinorField &in) const { if ( in.Ndim() != 5 || out.Ndim() != 5) errorQuda("Wrong number of dimensions\n"); double kappa2 = -kappa5*kappa5; bool reset = newTmp(&tmp1, in); if (matpcType == QUDA_MATPC_EVEN_EVEN) { Dslash(*tmp1, in, QUDA_ODD_PARITY); DslashXpay(out, *tmp1, QUDA_EVEN_PARITY, in, kappa2); } else if (matpcType == QUDA_MATPC_ODD_ODD) { Dslash(*tmp1, in, QUDA_EVEN_PARITY); DslashXpay(out, *tmp1, QUDA_ODD_PARITY, in, kappa2); } else { errorQuda("MatPCType %d not valid for DiracDomainWallPC", matpcType); } deleteTmp(&tmp1, reset); }
/* This is special case constructor used to create parity subset references with in a full field */ cpuColorSpinorField::cpuColorSpinorField(const ColorSpinorField &src, const ColorSpinorParam ¶m) : ColorSpinorField(src), init(false), reference(false) { // can only overide if we parity subset reference special case if ( param.create == QUDA_REFERENCE_FIELD_CREATE && src.SiteSubset() == QUDA_FULL_SITE_SUBSET && param.siteSubset == QUDA_PARITY_SITE_SUBSET && typeid(src) == typeid(cpuColorSpinorField) ) { reset(param); } else { errorQuda("Undefined behaviour"); // else silent bug possible? } // need to set this before create if (param.create == QUDA_REFERENCE_FIELD_CREATE) { v = (void*)src.V(); norm = (void*)src.Norm(); } create(param.create); }
void DiracStaggered::Dslash(ColorSpinorField &out, const ColorSpinorField &in, const QudaParity parity) const { checkParitySpinor(in, out); if (checkLocation(out, in) == QUDA_CUDA_FIELD_LOCATION) { staggeredDslashCuda(&static_cast<cudaColorSpinorField&>(out), *gauge, &static_cast<const cudaColorSpinorField&>(in), parity, dagger, 0, 0, commDim, profile); } else { errorQuda("Not supported"); } flops += 570ll*in.Volume(); }
void DiracStaggered::MdagM(ColorSpinorField &out, const ColorSpinorField &in) const { bool reset = newTmp(&tmp1, in); //even Dslash(tmp1->Even(), in.Even(), QUDA_ODD_PARITY); DslashXpay(out.Even(), tmp1->Even(), QUDA_EVEN_PARITY, in.Even(), 4*mass*mass); //odd Dslash(tmp1->Even(), in.Odd(), QUDA_EVEN_PARITY); DslashXpay(out.Odd(), tmp1->Even(), QUDA_ODD_PARITY, in.Odd(), 4*mass*mass); deleteTmp(&tmp1, reset); }
void DiracDomainWall::Dslash(ColorSpinorField &out, const ColorSpinorField &in, const QudaParity parity) const { if ( in.Ndim() != 5 || out.Ndim() != 5) errorQuda("Wrong number of dimensions\n"); checkParitySpinor(in, out); checkSpinorAlias(in, out); if (checkLocation(out, in) == QUDA_CUDA_FIELD_LOCATION) { domainWallDslashCuda(&static_cast<cudaColorSpinorField&>(out), *gauge, &static_cast<const cudaColorSpinorField&>(in), parity, dagger, 0, mass, 0, commDim, profile); } else { errorQuda("Not implemented"); } long long Ls = in.X(4); long long bulk = (Ls-2)*(in.Volume()/Ls); long long wall = 2*in.Volume()/Ls; flops += 1320LL*(long long)in.Volume() + 96LL*bulk + 120LL*wall; }
void DiracDomainWallPC::reconstruct(ColorSpinorField &x, const ColorSpinorField &b, const QudaSolutionType solType) const { if (solType == QUDA_MATPC_SOLUTION || solType == QUDA_MATPCDAG_MATPC_SOLUTION) { return; } // create full solution checkFullSpinor(x, b); if (matpcType == QUDA_MATPC_EVEN_EVEN) { // x_o = b_o + k D_oe x_e DslashXpay(x.Odd(), x.Even(), QUDA_ODD_PARITY, b.Odd(), kappa5); } else if (matpcType == QUDA_MATPC_ODD_ODD) { // x_e = b_e + k D_eo x_o DslashXpay(x.Even(), x.Odd(), QUDA_EVEN_PARITY, b.Even(), kappa5); } else { errorQuda("MatPCType %d not valid for DiracDomainWallPC", matpcType); } }
// creates a copy of src, any differences defined in param cudaColorSpinorField::cudaColorSpinorField(const ColorSpinorField &src, const ColorSpinorParam ¶m) : ColorSpinorField(src), v(0), norm(0), alloc(false), init(true) { // can only overide if we are not using a reference or parity special case if (param.create != QUDA_REFERENCE_FIELD_CREATE || (param.create == QUDA_REFERENCE_FIELD_CREATE && src.SiteSubset() == QUDA_FULL_SITE_SUBSET && param.siteSubset == QUDA_PARITY_SITE_SUBSET && src.FieldLocation() == QUDA_CUDA_FIELD_LOCATION) ) { reset(param); } else { errorQuda("Undefined behaviour"); // else silent bug possible? } fieldLocation = QUDA_CUDA_FIELD_LOCATION; create(param.create); if (param.create == QUDA_NULL_FIELD_CREATE) { // do nothing } else if (param.create == QUDA_ZERO_FIELD_CREATE) { zero(); } else if (param.create == QUDA_COPY_FIELD_CREATE) { if (src.FieldLocation() == QUDA_CUDA_FIELD_LOCATION) { copy(dynamic_cast<const cudaColorSpinorField&>(src)); } else if (src.FieldLocation() == QUDA_CPU_FIELD_LOCATION) { loadCPUSpinorField(dynamic_cast<const cpuColorSpinorField&>(src)); } else { errorQuda("FieldLocation %d not supported", src.FieldLocation()); } } else if (param.create == QUDA_REFERENCE_FIELD_CREATE) { if (src.FieldLocation() == QUDA_CUDA_FIELD_LOCATION) { v = (dynamic_cast<const cudaColorSpinorField&>(src)).v; norm = (dynamic_cast<const cudaColorSpinorField&>(src)).norm; } else { errorQuda("Cannot reference a non cuda field"); } } else { errorQuda("CreateType %d not implemented", param.create); } }
void DiracDomainWall::M(ColorSpinorField &out, const ColorSpinorField &in) const { checkFullSpinor(out, in); DslashXpay(out.Odd(), in.Even(), QUDA_ODD_PARITY, in.Odd(), -kappa5); DslashXpay(out.Even(), in.Odd(), QUDA_EVEN_PARITY, in.Even(), -kappa5); }
// Full staggered operator void DiracStaggered::M(ColorSpinorField &out, const ColorSpinorField &in) const { DslashXpay(out.Even(), in.Odd(), QUDA_EVEN_PARITY, in.Even(), 2*mass); DslashXpay(out.Odd(), in.Even(), QUDA_ODD_PARITY, in.Odd(), 2*mass); }
void DiracStaggered::checkParitySpinor(const ColorSpinorField &in, const ColorSpinorField &out) const { if (in.Ndim() != 5 || out.Ndim() != 5) { errorQuda("Staggered dslash requires 5-d fermion fields"); } if (in.Precision() != out.Precision()) { errorQuda("Input and output spinor precisions don't match in dslash_quda"); } if (in.Stride() != out.Stride()) { errorQuda("Input %d and output %d spinor strides don't match in dslash_quda", in.Stride(), out.Stride()); } if (in.SiteSubset() != QUDA_PARITY_SITE_SUBSET || out.SiteSubset() != QUDA_PARITY_SITE_SUBSET) { errorQuda("ColorSpinorFields are not single parity, in = %d, out = %d", in.SiteSubset(), out.SiteSubset()); } if ((out.Volume()/out.X(4) != 2*gauge->VolumeCB() && out.SiteSubset() == QUDA_FULL_SITE_SUBSET) || (out.Volume()/out.X(4) != gauge->VolumeCB() && out.SiteSubset() == QUDA_PARITY_SITE_SUBSET) ) { errorQuda("Spinor volume %d doesn't match gauge volume %d", out.Volume(), gauge->VolumeCB()); } }
// For kernels with precision conversion built in void ColorSpinorField::checkField(const ColorSpinorField &a, const ColorSpinorField &b) { if (a.Length() != b.Length()) { errorQuda("checkSpinor: lengths do not match: %d %d", a.Length(), b.Length()); } if (a.Ncolor() != b.Ncolor()) { errorQuda("checkSpinor: colors do not match: %d %d", a.Ncolor(), b.Ncolor()); } if (a.Nspin() != b.Nspin()) { errorQuda("checkSpinor: spins do not match: %d %d", a.Nspin(), b.Nspin()); } if (a.TwistFlavor() != b.TwistFlavor()) { errorQuda("checkSpinor: twist flavors do not match: %d %d", a.TwistFlavor(), b.TwistFlavor()); } }
ColorSpinorParam::ColorSpinorParam(const ColorSpinorField &field) { field.fill(*this); }