Commit 3344bb7a authored by Peter Eastman's avatar Peter Eastman
Browse files

Switched erfc table to use constant memory instead of texture cache

parent 40891bab
...@@ -1209,32 +1209,14 @@ void OpenCLCalcNonbondedForceKernel::initialize(const System& system, const Nonb ...@@ -1209,32 +1209,14 @@ void OpenCLCalcNonbondedForceKernel::initialize(const System& system, const Nonb
// Tabulate values of erfc(). // Tabulate values of erfc().
if (force.getNonbondedMethod() == NonbondedForce::Ewald || force.getNonbondedMethod() == NonbondedForce::PME) { if (force.getNonbondedMethod() == NonbondedForce::Ewald || force.getNonbondedMethod() == NonbondedForce::PME) {
if (cl.getDevice().getInfo<CL_DEVICE_IMAGE_SUPPORT>()) { const int tableSize = 2048;
try defines["ERFC_TABLE_SCALE"] = doubleToString((tableSize-1)/(alpha*force.getCutoffDistance()));
{ erfcTable = new OpenCLArray<cl_float>(cl, tableSize, "ErfcTable", false, CL_MEM_READ_ONLY);
const int tableSize = 2048; vector<cl_float> erfcVector(tableSize);
defines["USE_TABULATED_ERFC"] = "1"; for (int i = 0; i < tableSize; ++i)
defines["ERFC_TABLE_SCALE"] = doubleToString((tableSize-1)/(alpha*force.getCutoffDistance())); erfcVector[i] = (float) erfc(i*(alpha*force.getCutoffDistance())/(tableSize-1));
erfcTable = new cl::Image2D(cl.getContext(), CL_MEM_READ_ONLY, cl::ImageFormat(CL_INTENSITY, CL_FLOAT), tableSize, 1, 0); erfcTable->upload(erfcVector);
vector<cl_float> erfcVector(tableSize); cl.getNonbondedUtilities().addArgument(OpenCLNonbondedUtilities::ParameterInfo("erfcTable", "float", sizeof(cl_float), erfcTable->getDeviceBuffer()));
for (int i = 0; i < tableSize; ++i)
erfcVector[i] = (float) erfc(i*(alpha*force.getCutoffDistance())/(tableSize-1));
cl::size_t<3> origin, region;
origin.push_back(0);
origin.push_back(0);
origin.push_back(0);
region.push_back(tableSize);
region.push_back(1);
region.push_back(1);
cl.getQueue().enqueueWriteImage(*erfcTable, CL_TRUE, origin, region, 0, 0, &erfcVector[0]);
cl.getNonbondedUtilities().addArgument(OpenCLNonbondedUtilities::ParameterInfo("erfcTable", "image2d_t", sizeof(cl_float), *erfcTable));
}
catch (cl::Error err) {
std::stringstream str;
str<<"Error creating erfc() image: "<<err.what()<<" ("<<err.err()<<")";
throw OpenMMException(str.str());
}
}
} }
// Add the interaction to the default nonbonded kernel. // Add the interaction to the default nonbonded kernel.
......
...@@ -476,9 +476,9 @@ private: ...@@ -476,9 +476,9 @@ private:
OpenCLArray<mm_float4>* pmeBsplineDtheta; OpenCLArray<mm_float4>* pmeBsplineDtheta;
OpenCLArray<cl_int>* pmeAtomRange; OpenCLArray<cl_int>* pmeAtomRange;
OpenCLArray<mm_float2>* pmeAtomGridIndex; OpenCLArray<mm_float2>* pmeAtomGridIndex;
OpenCLArray<cl_float>* erfcTable;
OpenCLSort<mm_float2>* sort; OpenCLSort<mm_float2>* sort;
OpenCLFFT3D* fft; OpenCLFFT3D* fft;
cl::Image2D* erfcTable;
cl::Kernel exceptionsKernel; cl::Kernel exceptionsKernel;
cl::Kernel ewaldSumsKernel; cl::Kernel ewaldSumsKernel;
cl::Kernel ewaldForcesKernel; cl::Kernel ewaldForcesKernel;
......
...@@ -3,15 +3,16 @@ bool needCorrection = isExcluded && atom1 != atom2 && atom1 < NUM_ATOMS && atom2 ...@@ -3,15 +3,16 @@ bool needCorrection = isExcluded && atom1 != atom2 && atom1 < NUM_ATOMS && atom2
if (!isExcluded || needCorrection) { if (!isExcluded || needCorrection) {
const float prefactor = 138.935456f*posq1.w*posq2.w*invR; const float prefactor = 138.935456f*posq1.w*posq2.w*invR;
float alphaR = EWALD_ALPHA*r; float alphaR = EWALD_ALPHA*r;
#ifdef USE_TABULATED_ERFC float erfcAlphaR = 0.0f;
float normalized = ERFC_TABLE_SCALE*alphaR; if (r2 < CUTOFF_SQUARED) {
int tableIndex = (int) normalized; float normalized = ERFC_TABLE_SCALE*alphaR;
float fract2 = normalized-tableIndex; int tableIndex = (int) normalized;
float fract1 = 1.0f-fract2; float fract2 = normalized-tableIndex;
float erfcAlphaR = fract1*read_imagef(erfcTable, sampler, (int2)(tableIndex, 0)).x + fract2*read_imagef(erfcTable, sampler, (int2)(tableIndex+1, 0)).x; float fract1 = 1.0f-fract2;
#else erfcAlphaR = fract1*erfcTable[tableIndex] + fract2*erfcTable[tableIndex+1];
float erfcAlphaR = erfc(alphaR); }
#endif else if (needCorrection)
erfcAlphaR = erfc(alphaR);
float tempForce = 0.0f; float tempForce = 0.0f;
if (needCorrection) { if (needCorrection) {
// Subtract off the part of this interaction that was included in the reciprocal space contribution. // Subtract off the part of this interaction that was included in the reciprocal space contribution.
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment