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