"libraries/vecmath/vscode:/vscode.git/clone" did not exist on "8d0fee51a1529095e4905c00cfc32cd27aa4088d"
Commit 786e1ee7 authored by peastman's avatar peastman
Browse files

Implemented exclusions for CUDA version of CustomManyParticleForce

parent 65b56ee1
...@@ -931,7 +931,8 @@ private: ...@@ -931,7 +931,8 @@ private:
class CudaCalcCustomManyParticleForceKernel : public CalcCustomManyParticleForceKernel { class CudaCalcCustomManyParticleForceKernel : public CalcCustomManyParticleForceKernel {
public: public:
CudaCalcCustomManyParticleForceKernel(std::string name, const Platform& platform, CudaContext& cu, const System& system) : CalcCustomManyParticleForceKernel(name, platform), CudaCalcCustomManyParticleForceKernel(std::string name, const Platform& platform, CudaContext& cu, const System& system) : CalcCustomManyParticleForceKernel(name, platform),
hasInitializedKernel(false), cu(cu), params(NULL), globals(NULL), particleTypes(NULL), orderIndex(NULL), particleOrder(NULL), system(system) { hasInitializedKernel(false), cu(cu), params(NULL), globals(NULL), particleTypes(NULL), orderIndex(NULL), particleOrder(NULL), exclusions(NULL),
exclusionStartIndex(NULL), system(system) {
} }
~CudaCalcCustomManyParticleForceKernel(); ~CudaCalcCustomManyParticleForceKernel();
/** /**
...@@ -967,6 +968,8 @@ private: ...@@ -967,6 +968,8 @@ private:
CudaArray* particleTypes; CudaArray* particleTypes;
CudaArray* orderIndex; CudaArray* orderIndex;
CudaArray* particleOrder; CudaArray* particleOrder;
CudaArray* exclusions;
CudaArray* exclusionStartIndex;
std::vector<std::string> globalParamNames; std::vector<std::string> globalParamNames;
std::vector<float> globalParamValues; std::vector<float> globalParamValues;
std::vector<CudaArray*> tabulatedFunctions; std::vector<CudaArray*> tabulatedFunctions;
......
...@@ -4413,9 +4413,14 @@ public: ...@@ -4413,9 +4413,14 @@ public:
return true; return true;
} }
int getNumParticleGroups() { int getNumParticleGroups() {
return 0; return force.getNumExclusions();
} }
void getParticlesInGroup(int index, vector<int>& particles) { void getParticlesInGroup(int index, vector<int>& particles) {
int particle1, particle2;
force.getExclusionParticles(index, particle1, particle2);
particles.resize(2);
particles[0] = particle1;
particles[1] = particle2;
} }
bool areGroupsIdentical(int group1, int group2) { bool areGroupsIdentical(int group1, int group2) {
return true; return true;
...@@ -4436,6 +4441,10 @@ CudaCalcCustomManyParticleForceKernel::~CudaCalcCustomManyParticleForceKernel() ...@@ -4436,6 +4441,10 @@ CudaCalcCustomManyParticleForceKernel::~CudaCalcCustomManyParticleForceKernel()
delete particleOrder; delete particleOrder;
if (particleTypes != NULL) if (particleTypes != NULL)
delete particleTypes; delete particleTypes;
if (exclusions != NULL)
delete exclusions;
if (exclusionStartIndex != NULL)
delete exclusionStartIndex;
for (int i = 0; i < (int) tabulatedFunctions.size(); i++) for (int i = 0; i < (int) tabulatedFunctions.size(); i++)
delete tabulatedFunctions[i]; delete tabulatedFunctions[i];
} }
...@@ -4538,6 +4547,30 @@ void CudaCalcCustomManyParticleForceKernel::initialize(const System& system, con ...@@ -4538,6 +4547,30 @@ void CudaCalcCustomManyParticleForceKernel::initialize(const System& system, con
particleOrder->upload(flattenedOrder); particleOrder->upload(flattenedOrder);
} }
// Build data structures for exclusions.
if (force.getNumExclusions() > 0) {
vector<vector<int> > particleExclusions(numParticles);
for (int i = 0; i < force.getNumExclusions(); i++) {
int p1, p2;
force.getExclusionParticles(i, p1, p2);
particleExclusions[p1].push_back(p2);
particleExclusions[p2].push_back(p1);
}
vector<int> exclusionsVec;
vector<int> exclusionStartIndexVec(numParticles+1);
exclusionStartIndexVec[0] = 0;
for (int i = 0; i < numParticles; i++) {
sort(particleExclusions[i].begin(), particleExclusions[i].end());
exclusionsVec.insert(exclusionsVec.end(), particleExclusions[i].begin(), particleExclusions[i].end());
exclusionStartIndexVec[i+1] = exclusionsVec.size();
}
exclusions = CudaArray::create<int>(cu, exclusionsVec.size(), "customManyParticleExclusions");
exclusionStartIndex = CudaArray::create<int>(cu, exclusionStartIndexVec.size(), "customManyParticleExclusionStart");
exclusions->upload(exclusionsVec);
exclusionStartIndex->upload(exclusionStartIndexVec);
}
// Now to generate the kernel. First, it needs to calculate all distances, angles, // Now to generate the kernel. First, it needs to calculate all distances, angles,
// and dihedrals the expression depends on. // and dihedrals the expression depends on.
...@@ -4701,7 +4734,7 @@ void CudaCalcCustomManyParticleForceKernel::initialize(const System& system, con ...@@ -4701,7 +4734,7 @@ void CudaCalcCustomManyParticleForceKernel::initialize(const System& system, con
// Create other replacements that depend on the number of particles per set. // Create other replacements that depend on the number of particles per set.
stringstream numCombinations, atomsForCombination, isValidCombination, permute, loadData, verifyCutoff; stringstream numCombinations, atomsForCombination, isValidCombination, permute, loadData, verifyCutoff, verifyExclusions;
if (hasTypeFilters) { if (hasTypeFilters) {
permute<<"int particleSet[] = {"; permute<<"int particleSet[] = {";
for (int i = 0; i < particlesPerSet; i++) { for (int i = 0; i < particlesPerSet; i++) {
...@@ -4741,6 +4774,12 @@ void CudaCalcCustomManyParticleForceKernel::initialize(const System& system, con ...@@ -4741,6 +4774,12 @@ void CudaCalcCustomManyParticleForceKernel::initialize(const System& system, con
for (int j = i+1; j < particlesPerSet; j++) for (int j = i+1; j < particlesPerSet; j++)
verifyCutoff<<"includeInteraction &= (delta(pos"<<(i+1)<<", pos"<<(j+1)<<", periodicBoxSize, invPeriodicBoxSize).w < CUTOFF_SQUARED);\n"; verifyCutoff<<"includeInteraction &= (delta(pos"<<(i+1)<<", pos"<<(j+1)<<", periodicBoxSize, invPeriodicBoxSize).w < CUTOFF_SQUARED);\n";
} }
if (force.getNumExclusions() > 0) {
int startCheckFrom = 0;
for (int i = startCheckFrom; i < particlesPerSet; i++)
for (int j = i+1; j < particlesPerSet; j++)
verifyExclusions<<"includeInteraction &= !isInteractionExcluded(p"<<(i+1)<<", p"<<(j+1)<<", exclusions, exclusionStartIndex);\n";
}
string computeTypeIndex = "particleTypes[p"+cu.intToString(particlesPerSet)+"]"; string computeTypeIndex = "particleTypes[p"+cu.intToString(particlesPerSet)+"]";
for (int i = particlesPerSet-2; i >= 0; i--) for (int i = particlesPerSet-2; i >= 0; i--)
computeTypeIndex = "particleTypes[p"+cu.intToString(i+1)+"]+"+cu.intToString(numTypes)+"*("+computeTypeIndex+")"; computeTypeIndex = "particleTypes[p"+cu.intToString(i+1)+"]+"+cu.intToString(numTypes)+"*("+computeTypeIndex+")";
...@@ -4763,6 +4802,7 @@ void CudaCalcCustomManyParticleForceKernel::initialize(const System& system, con ...@@ -4763,6 +4802,7 @@ void CudaCalcCustomManyParticleForceKernel::initialize(const System& system, con
replacements["FIND_ATOMS_FOR_COMBINATION_INDEX"] = atomsForCombination.str(); replacements["FIND_ATOMS_FOR_COMBINATION_INDEX"] = atomsForCombination.str();
replacements["IS_VALID_COMBINATION"] = isValidCombination.str(); replacements["IS_VALID_COMBINATION"] = isValidCombination.str();
replacements["VERIFY_CUTOFF"] = verifyCutoff.str(); replacements["VERIFY_CUTOFF"] = verifyCutoff.str();
replacements["VERIFY_EXCLUSIONS"] = verifyExclusions.str();
replacements["PERMUTE_ATOMS"] = permute.str(); replacements["PERMUTE_ATOMS"] = permute.str();
replacements["LOAD_PARTICLE_DATA"] = loadData.str(); replacements["LOAD_PARTICLE_DATA"] = loadData.str();
replacements["COMPUTE_TYPE_INDEX"] = computeTypeIndex; replacements["COMPUTE_TYPE_INDEX"] = computeTypeIndex;
...@@ -4774,6 +4814,8 @@ void CudaCalcCustomManyParticleForceKernel::initialize(const System& system, con ...@@ -4774,6 +4814,8 @@ void CudaCalcCustomManyParticleForceKernel::initialize(const System& system, con
defines["USE_PERIODIC"] = "1"; defines["USE_PERIODIC"] = "1";
if (hasTypeFilters) if (hasTypeFilters)
defines["USE_FILTERS"] = "1"; defines["USE_FILTERS"] = "1";
if (force.getNumExclusions() > 0)
defines["USE_EXCLUSIONS"] = "1";
defines["NUM_ATOMS"] = cu.intToString(cu.getNumAtoms()); defines["NUM_ATOMS"] = cu.intToString(cu.getNumAtoms());
defines["PADDED_NUM_ATOMS"] = cu.intToString(cu.getPaddedNumAtoms()); defines["PADDED_NUM_ATOMS"] = cu.intToString(cu.getPaddedNumAtoms());
defines["M_PI"] = cu.doubleToString(M_PI); defines["M_PI"] = cu.doubleToString(M_PI);
...@@ -4797,6 +4839,10 @@ double CudaCalcCustomManyParticleForceKernel::execute(ContextImpl& context, bool ...@@ -4797,6 +4839,10 @@ double CudaCalcCustomManyParticleForceKernel::execute(ContextImpl& context, bool
forceArgs.push_back(&orderIndex->getDevicePointer()); forceArgs.push_back(&orderIndex->getDevicePointer());
forceArgs.push_back(&particleOrder->getDevicePointer()); forceArgs.push_back(&particleOrder->getDevicePointer());
} }
if (exclusions != NULL) {
forceArgs.push_back(&exclusions->getDevicePointer());
forceArgs.push_back(&exclusionStartIndex->getDevicePointer());
}
if (globals != NULL) if (globals != NULL)
forceArgs.push_back(&globals->getDevicePointer()); forceArgs.push_back(&globals->getDevicePointer());
for (int i = 0; i < (int) params->getBuffers().size(); i++) { for (int i = 0; i < (int) params->getBuffers().size(); i++) {
......
...@@ -58,6 +58,22 @@ inline __device__ real4 computeCross(real4 vec1, real4 vec2) { ...@@ -58,6 +58,22 @@ inline __device__ real4 computeCross(real4 vec1, real4 vec2) {
return make_real4(cp.x, cp.y, cp.z, cp.x*cp.x+cp.y*cp.y+cp.z*cp.z); return make_real4(cp.x, cp.y, cp.z, cp.x*cp.x+cp.y*cp.y+cp.z*cp.z);
} }
/**
* Determine whether a particular interaction is in the list of exclusions.
*/
inline __device__ bool isInteractionExcluded(int atom1, int atom2, int* __restrict__ exclusions, int* __restrict__ exclusionStartIndex) {
int first = exclusionStartIndex[atom1];
int last = exclusionStartIndex[atom1+1];
for (int i = last-1; i >= first; i--) {
int excluded = exclusions[i];
if (excluded == atom2)
return true;
if (excluded <= atom1)
return false;
}
return false;
}
/** /**
* Compute the interaction. * Compute the interaction.
*/ */
...@@ -66,6 +82,9 @@ extern "C" __global__ void computeInteraction( ...@@ -66,6 +82,9 @@ extern "C" __global__ void computeInteraction(
real4 periodicBoxSize, real4 invPeriodicBoxSize real4 periodicBoxSize, real4 invPeriodicBoxSize
#ifdef USE_FILTERS #ifdef USE_FILTERS
, int* __restrict__ particleTypes, int* __restrict__ orderIndex, int* __restrict__ particleOrder , int* __restrict__ particleTypes, int* __restrict__ orderIndex, int* __restrict__ particleOrder
#endif
#ifdef USE_EXCLUSIONS
, int* __restrict__ exclusions, int* __restrict__ exclusionStartIndex
#endif #endif
PARAMETER_ARGUMENTS) { PARAMETER_ARGUMENTS) {
real energy = 0.0f; real energy = 0.0f;
...@@ -87,6 +106,11 @@ extern "C" __global__ void computeInteraction( ...@@ -87,6 +106,11 @@ extern "C" __global__ void computeInteraction(
int order = orderIndex[COMPUTE_TYPE_INDEX]; int order = orderIndex[COMPUTE_TYPE_INDEX];
if (order == -1) if (order == -1)
includeInteraction = false; includeInteraction = false;
#endif
#ifdef USE_EXCLUSIONS
if (includeInteraction) {
VERIFY_EXCLUSIONS;
}
#endif #endif
if (includeInteraction) { if (includeInteraction) {
PERMUTE_ATOMS; PERMUTE_ATOMS;
......
...@@ -468,7 +468,7 @@ int main(int argc, char* argv[]) { ...@@ -468,7 +468,7 @@ int main(int argc, char* argv[]) {
testNoCutoff(); testNoCutoff();
testCutoff(); testCutoff();
testPeriodic(); testPeriodic();
// testExclusions(); testExclusions();
testAllTerms(); testAllTerms();
testParameters(); testParameters();
testTabulatedFunctions(); testTabulatedFunctions();
......
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