QUDA v0.4.0
A library for QCD on GPUs
|
00001 #include <iostream> 00002 #include <dirac_quda.h> 00003 #include <blas_quda.h> 00004 00005 DiracDomainWall::DiracDomainWall(const DiracParam ¶m) : 00006 DiracWilson(param), m5(param.m5), kappa5(0.5/(5.0 + m5)) { } 00007 00008 DiracDomainWall::DiracDomainWall(const DiracDomainWall &dirac) : 00009 DiracWilson(dirac), m5(dirac.m5), kappa5(0.5/(5.0 + m5)) { } 00010 00011 DiracDomainWall::~DiracDomainWall() { } 00012 00013 DiracDomainWall& DiracDomainWall::operator=(const DiracDomainWall &dirac) 00014 { 00015 if (&dirac != this) { 00016 DiracWilson::operator=(dirac); 00017 m5 = dirac.m5; 00018 kappa5 = dirac.kappa5; 00019 } 00020 return *this; 00021 } 00022 00023 void DiracDomainWall::Dslash(cudaColorSpinorField &out, const cudaColorSpinorField &in, 00024 const QudaParity parity) const 00025 { 00026 if ( in.Ndim() != 5 || out.Ndim() != 5) errorQuda("Wrong number of dimensions\n"); 00027 if (!initDslash) initDslashConstants(gauge, in.Stride()); 00028 if (!initDomainWall) initDomainWallConstants(in.X(4)); 00029 checkParitySpinor(in, out); 00030 checkSpinorAlias(in, out); 00031 00032 domainWallDslashCuda(&out, gauge, &in, parity, dagger, 0, mass, 0); 00033 00034 long long Ls = in.X(4); 00035 long long bulk = (Ls-2)*(in.Volume()/Ls); 00036 long long wall = 2*in.Volume()/Ls; 00037 flops += 1320LL*(long long)in.Volume() + 96LL*bulk + 120LL*wall; 00038 } 00039 00040 void DiracDomainWall::DslashXpay(cudaColorSpinorField &out, const cudaColorSpinorField &in, 00041 const QudaParity parity, const cudaColorSpinorField &x, 00042 const double &k) const 00043 { 00044 if ( in.Ndim() != 5 || out.Ndim() != 5) errorQuda("Wrong number of dimensions\n"); 00045 if (!initDslash) initDslashConstants(gauge, in.Stride()); 00046 if (!initDomainWall) initDomainWallConstants(in.X(4)); 00047 checkParitySpinor(in, out); 00048 checkSpinorAlias(in, out); 00049 00050 domainWallDslashCuda(&out, gauge, &in, parity, dagger, &x, mass, k); 00051 00052 long long Ls = in.X(4); 00053 long long bulk = (Ls-2)*(in.Volume()/Ls); 00054 long long wall = 2*in.Volume()/Ls; 00055 flops += (1320LL+48LL)*(long long)in.Volume() + 96LL*bulk + 120LL*wall; 00056 } 00057 00058 void DiracDomainWall::M(cudaColorSpinorField &out, const cudaColorSpinorField &in) const 00059 { 00060 checkFullSpinor(out, in); 00061 DslashXpay(out.Odd(), in.Even(), QUDA_ODD_PARITY, in.Odd(), -kappa5); 00062 DslashXpay(out.Even(), in.Odd(), QUDA_EVEN_PARITY, in.Even(), -kappa5); 00063 } 00064 00065 void DiracDomainWall::MdagM(cudaColorSpinorField &out, const cudaColorSpinorField &in) const 00066 { 00067 checkFullSpinor(out, in); 00068 00069 bool reset = newTmp(&tmp1, in); 00070 00071 M(*tmp1, in); 00072 Mdag(out, *tmp1); 00073 00074 deleteTmp(&tmp1, reset); 00075 } 00076 00077 void DiracDomainWall::prepare(cudaColorSpinorField* &src, cudaColorSpinorField* &sol, 00078 cudaColorSpinorField &x, cudaColorSpinorField &b, 00079 const QudaSolutionType solType) const 00080 { 00081 if (solType == QUDA_MATPC_SOLUTION || solType == QUDA_MATPCDAG_MATPC_SOLUTION) { 00082 errorQuda("Preconditioned solution requires a preconditioned solve_type"); 00083 } 00084 00085 src = &b; 00086 sol = &x; 00087 } 00088 00089 void DiracDomainWall::reconstruct(cudaColorSpinorField &x, const cudaColorSpinorField &b, 00090 const QudaSolutionType solType) const 00091 { 00092 // do nothing 00093 } 00094 00095 DiracDomainWallPC::DiracDomainWallPC(const DiracParam ¶m) 00096 : DiracDomainWall(param) 00097 { 00098 00099 } 00100 00101 DiracDomainWallPC::DiracDomainWallPC(const DiracDomainWallPC &dirac) 00102 : DiracDomainWall(dirac) 00103 { 00104 00105 } 00106 00107 DiracDomainWallPC::~DiracDomainWallPC() 00108 { 00109 00110 } 00111 00112 DiracDomainWallPC& DiracDomainWallPC::operator=(const DiracDomainWallPC &dirac) 00113 { 00114 if (&dirac != this) { 00115 DiracDomainWall::operator=(dirac); 00116 } 00117 00118 return *this; 00119 } 00120 00121 // Apply the even-odd preconditioned clover-improved Dirac operator 00122 void DiracDomainWallPC::M(cudaColorSpinorField &out, const cudaColorSpinorField &in) const 00123 { 00124 if ( in.Ndim() != 5 || out.Ndim() != 5) errorQuda("Wrong number of dimensions\n"); 00125 double kappa2 = -kappa5*kappa5; 00126 00127 bool reset = newTmp(&tmp1, in); 00128 00129 if (matpcType == QUDA_MATPC_EVEN_EVEN) { 00130 Dslash(*tmp1, in, QUDA_ODD_PARITY); 00131 DslashXpay(out, *tmp1, QUDA_EVEN_PARITY, in, kappa2); 00132 } else if (matpcType == QUDA_MATPC_ODD_ODD) { 00133 Dslash(*tmp1, in, QUDA_EVEN_PARITY); 00134 DslashXpay(out, *tmp1, QUDA_ODD_PARITY, in, kappa2); 00135 } else { 00136 errorQuda("MatPCType %d not valid for DiracDomainWallPC", matpcType); 00137 } 00138 00139 deleteTmp(&tmp1, reset); 00140 } 00141 00142 void DiracDomainWallPC::MdagM(cudaColorSpinorField &out, const cudaColorSpinorField &in) const 00143 { 00144 M(out, in); 00145 Mdag(out, out); 00146 } 00147 00148 void DiracDomainWallPC::prepare(cudaColorSpinorField* &src, cudaColorSpinorField* &sol, 00149 cudaColorSpinorField &x, cudaColorSpinorField &b, 00150 const QudaSolutionType solType) const 00151 { 00152 // we desire solution to preconditioned system 00153 if (solType == QUDA_MATPC_SOLUTION || solType == QUDA_MATPCDAG_MATPC_SOLUTION) { 00154 src = &b; 00155 sol = &x; 00156 } else { 00157 // we desire solution to full system 00158 if (matpcType == QUDA_MATPC_EVEN_EVEN) { 00159 // src = b_e + k D_eo b_o 00160 DslashXpay(x.Odd(), b.Odd(), QUDA_EVEN_PARITY, b.Even(), kappa5); 00161 src = &(x.Odd()); 00162 sol = &(x.Even()); 00163 } else if (matpcType == QUDA_MATPC_ODD_ODD) { 00164 // src = b_o + k D_oe b_e 00165 DslashXpay(x.Even(), b.Even(), QUDA_ODD_PARITY, b.Odd(), kappa5); 00166 src = &(x.Even()); 00167 sol = &(x.Odd()); 00168 } else { 00169 errorQuda("MatPCType %d not valid for DiracDomainWallPC", matpcType); 00170 } 00171 // here we use final solution to store parity solution and parity source 00172 // b is now up for grabs if we want 00173 } 00174 00175 } 00176 00177 void DiracDomainWallPC::reconstruct(cudaColorSpinorField &x, const cudaColorSpinorField &b, 00178 const QudaSolutionType solType) const 00179 { 00180 if (solType == QUDA_MATPC_SOLUTION || solType == QUDA_MATPCDAG_MATPC_SOLUTION) { 00181 return; 00182 } 00183 00184 // create full solution 00185 00186 checkFullSpinor(x, b); 00187 if (matpcType == QUDA_MATPC_EVEN_EVEN) { 00188 // x_o = b_o + k D_oe x_e 00189 DslashXpay(x.Odd(), x.Even(), QUDA_ODD_PARITY, b.Odd(), kappa5); 00190 } else if (matpcType == QUDA_MATPC_ODD_ODD) { 00191 // x_e = b_e + k D_eo x_o 00192 DslashXpay(x.Even(), x.Odd(), QUDA_EVEN_PARITY, b.Even(), kappa5); 00193 } else { 00194 errorQuda("MatPCType %d not valid for DiracDomainWallPC", matpcType); 00195 } 00196 } 00197