Commit a3464898 authored by Peter Eastman's avatar Peter Eastman
Browse files

Continuing CUDA implementation of CustomNonbondedForce

parent 673b555b
...@@ -82,7 +82,6 @@ static double calcEnergy(ContextImpl& context, CudaPlatform::PlatformData& data, ...@@ -82,7 +82,6 @@ static double calcEnergy(ContextImpl& context, CudaPlatform::PlatformData& data,
pos[i] = Vec3(posData[3*i], posData[3*i+1], posData[3*i+2]); pos[i] = Vec3(posData[3*i], posData[3*i+1], posData[3*i+2]);
delete[] posData; delete[] posData;
refContext.setPositions(pos); refContext.setPositions(pos);
// printf("Total CPU energies: %f\n", refContext.getState(State::Energy).getPotentialEnergy());
return refContext.getState(State::Energy).getPotentialEnergy(); return refContext.getState(State::Energy).getPotentialEnergy();
} }
else else
...@@ -97,9 +96,10 @@ static double calcEnergy(ContextImpl& context, CudaPlatform::PlatformData& data, ...@@ -97,9 +96,10 @@ static double calcEnergy(ContextImpl& context, CudaPlatform::PlatformData& data,
kReduceObcGbsaBornForces(gpu); kReduceObcGbsaBornForces(gpu);
kCalculateObcGbsaForces2(gpu); kCalculateObcGbsaForces2(gpu);
} }
else if (data.hasNonbonded) { else if (data.hasNonbonded)
kCalculateCDLJForces(gpu); kCalculateCDLJForces(gpu);
} if (data.hasCustomNonbonded)
kCalculateCustomNonbondedForces(gpu, data.hasNonbonded);
kCalculateLocalForces(gpu); kCalculateLocalForces(gpu);
if (gpu->bIncludeGBSA) if (gpu->bIncludeGBSA)
kReduceBornSumAndForces(gpu); kReduceBornSumAndForces(gpu);
...@@ -389,8 +389,7 @@ CudaCalcCustomNonbondedForceKernel::~CudaCalcCustomNonbondedForceKernel() { ...@@ -389,8 +389,7 @@ CudaCalcCustomNonbondedForceKernel::~CudaCalcCustomNonbondedForceKernel() {
} }
void CudaCalcCustomNonbondedForceKernel::initialize(const System& system, const CustomNonbondedForce& force) { void CudaCalcCustomNonbondedForceKernel::initialize(const System& system, const CustomNonbondedForce& force) {
if (data.primaryKernel == NULL) data.primaryKernel = this; // This must always be the primary kernel so it can update the global parameters
data.primaryKernel = this;
data.hasCustomNonbonded = true; data.hasCustomNonbonded = true;
numParticles = force.getNumParticles(); numParticles = force.getNumParticles();
_gpuContext* gpu = data.gpu; _gpuContext* gpu = data.gpu;
...@@ -452,21 +451,45 @@ void CudaCalcCustomNonbondedForceKernel::initialize(const System& system, const ...@@ -452,21 +451,45 @@ void CudaCalcCustomNonbondedForceKernel::initialize(const System& system, const
paramNames.push_back(force.getParameterName(i)); paramNames.push_back(force.getParameterName(i));
combiningRules.push_back(force.getParameterCombiningRule(i)); combiningRules.push_back(force.getParameterCombiningRule(i));
} }
globalParamNames.resize(force.getNumGlobalParameters());
globalParamValues.resize(force.getNumGlobalParameters());
for (int i = 0; i < force.getNumGlobalParameters(); i++) {
globalParamNames[i] = force.getGlobalParameterName(i);
globalParamValues[i] = force.getGlobalParameterDefaultValue(i);
}
gpuSetCustomNonbondedParameters(gpu, parameters, exclusionList, exceptionParticle1, exceptionParticle2, exceptionParams, method, gpuSetCustomNonbondedParameters(gpu, parameters, exclusionList, exceptionParticle1, exceptionParticle2, exceptionParams, method,
(float)force.getCutoffDistance(), force.getEnergyFunction(), combiningRules, paramNames); (float)force.getCutoffDistance(), force.getEnergyFunction(), combiningRules, paramNames, globalParamNames);
if (globalParamValues.size() > 0)
SetCustomNonbondedGlobalParams(globalParamValues);
} }
void CudaCalcCustomNonbondedForceKernel::executeForces(ContextImpl& context) { void CudaCalcCustomNonbondedForceKernel::executeForces(ContextImpl& context) {
if (data.primaryKernel == this) if (data.primaryKernel == this) {
updateGlobalParams(context);
calcForces(context, data); calcForces(context, data);
}
} }
double CudaCalcCustomNonbondedForceKernel::executeEnergy(ContextImpl& context) { double CudaCalcCustomNonbondedForceKernel::executeEnergy(ContextImpl& context) {
if (data.primaryKernel == this) if (data.primaryKernel == this) {
updateGlobalParams(context);
return calcEnergy(context, data, system); return calcEnergy(context, data, system);
}
return 0.0; return 0.0;
} }
void CudaCalcCustomNonbondedForceKernel::updateGlobalParams(ContextImpl& context) {
bool changed = false;
for (int i = 0; i < globalParamNames.size(); i++) {
float value = (float) context.getParameter(globalParamNames[i]);
if (value != globalParamValues[i])
changed = true;
globalParamValues[i] = value;
}
if (changed)
SetCustomNonbondedGlobalParams(globalParamValues);
}
CudaCalcGBSAOBCForceKernel::~CudaCalcGBSAOBCForceKernel() { CudaCalcGBSAOBCForceKernel::~CudaCalcGBSAOBCForceKernel() {
} }
......
...@@ -289,8 +289,11 @@ public: ...@@ -289,8 +289,11 @@ public:
*/ */
double executeEnergy(ContextImpl& context); double executeEnergy(ContextImpl& context);
private: private:
void updateGlobalParams(ContextImpl& context);
CudaPlatform::PlatformData& data; CudaPlatform::PlatformData& data;
int numParticles; int numParticles;
std::vector<std::string> globalParamNames;
std::vector<float> globalParamValues;
System& system; System& system;
}; };
......
...@@ -96,3 +96,4 @@ extern void GetRandomSim(gpuContext gpu); ...@@ -96,3 +96,4 @@ extern void GetRandomSim(gpuContext gpu);
extern void SetCustomNonbondedForceExpression(const Expression<128>& expression); extern void SetCustomNonbondedForceExpression(const Expression<128>& expression);
extern void SetCustomNonbondedEnergyExpression(const Expression<128>& expression); extern void SetCustomNonbondedEnergyExpression(const Expression<128>& expression);
extern void SetCustomNonbondedCombiningRules(const Expression<64>* expressions); extern void SetCustomNonbondedCombiningRules(const Expression<64>* expressions);
extern void SetCustomNonbondedGlobalParams(const std::vector<float>& paramValues);
...@@ -244,7 +244,7 @@ enum CudaNonbondedMethod ...@@ -244,7 +244,7 @@ enum CudaNonbondedMethod
}; };
enum ExpressionOp { enum ExpressionOp {
CONSTANT = 0, VARIABLE0, VARIABLE1, VARIABLE2, VARIABLE3, VARIABLE4, VARIABLE5, VARIABLE6, VARIABLE7, VARIABLE8, CUSTOM, ADD, SUBTRACT, MULTIPLY, DIVIDE, CONSTANT = 0, VARIABLE0, VARIABLE1, VARIABLE2, VARIABLE3, VARIABLE4, VARIABLE5, VARIABLE6, VARIABLE7, VARIABLE8, GLOBAL, CUSTOM, ADD, SUBTRACT, MULTIPLY, DIVIDE,
POWER, NEGATE, SQRT, EXP, LOG, SIN, COS, SEC, CSC, TAN, COT, ASIN, ACOS, ATAN, SQUARE, CUBE, RECIPROCAL, INCREMENT, DECREMENT POWER, NEGATE, SQRT, EXP, LOG, SIN, COS, SEC, CSC, TAN, COT, ASIN, ACOS, ATAN, SQUARE, CUBE, RECIPROCAL, INCREMENT, DECREMENT
}; };
......
...@@ -132,7 +132,7 @@ static const float BOLTZ = (RGAS / KILO); // (k ...@@ -132,7 +132,7 @@ static const float BOLTZ = (RGAS / KILO); // (k
#define DUMP_PARAMETERS 0 #define DUMP_PARAMETERS 0
template <int SIZE> template <int SIZE>
static Expression<SIZE> createExpression(const string& expression, const Lepton::ExpressionProgram& program, const vector<string>& variables) { static Expression<SIZE> createExpression(const string& expression, const Lepton::ExpressionProgram& program, const vector<string>& variables, const vector<string>& globalParamNames) {
Expression<SIZE> exp; Expression<SIZE> exp;
if (program.getNumOperations() > SIZE) if (program.getNumOperations() > SIZE)
throw OpenMMException("Expression contains too many operations: "+expression); throw OpenMMException("Expression contains too many operations: "+expression);
...@@ -164,8 +164,14 @@ static Expression<SIZE> createExpression(const string& expression, const Lepton: ...@@ -164,8 +164,14 @@ static Expression<SIZE> createExpression(const string& expression, const Lepton:
exp.op[i] = VARIABLE7; exp.op[i] = VARIABLE7;
else if (variables.size() > 8 && op.getName() == variables[8]) else if (variables.size() > 8 && op.getName() == variables[8])
exp.op[i] = VARIABLE8; exp.op[i] = VARIABLE8;
else else {
throw OpenMMException("Unknown variable '"+op.getName()+"' in expression: "+expression); int j;
for (j = 0; j < globalParamNames.size() && op.getName() != globalParamNames[j]; j++);
if (j == globalParamNames.size())
throw OpenMMException("Unknown variable '"+op.getName()+"' in expression: "+expression);
exp.op[i] = GLOBAL;
exp.arg[i] = j;
}
break; break;
case Operation::ADD: case Operation::ADD:
exp.op[i] = ADD; exp.op[i] = ADD;
...@@ -560,12 +566,15 @@ void gpuSetNonbondedCutoff(gpuContext gpu, float cutoffDistance, float solventDi ...@@ -560,12 +566,15 @@ void gpuSetNonbondedCutoff(gpuContext gpu, float cutoffDistance, float solventDi
extern "C" extern "C"
void gpuSetCustomNonbondedParameters(gpuContext gpu, const vector<vector<double> >& parameters, const vector<vector<int> >& exclusions, void gpuSetCustomNonbondedParameters(gpuContext gpu, const vector<vector<double> >& parameters, const vector<vector<int> >& exclusions,
const vector<int>& exceptionAtom1, const vector<int>& exceptionAtom2, const vector<vector<double> >& exceptionParams, const vector<int>& exceptionAtom1, const vector<int>& exceptionAtom2, const vector<vector<double> >& exceptionParams,
CudaNonbondedMethod method, float cutoffDistance, const string& energyExp, const vector<string>& combiningRules, const vector<string>& paramNames) CudaNonbondedMethod method, float cutoffDistance, const string& energyExp, const vector<string>& combiningRules,
const vector<string>& paramNames, const vector<string>& globalParamNames)
{ {
if (gpu->sim.nonbondedCutoff != 0.0f && gpu->sim.nonbondedCutoff != cutoffDistance) if (gpu->sim.nonbondedCutoff != 0.0f && gpu->sim.nonbondedCutoff != cutoffDistance)
throw OpenMMException("All nonbonded forces must use the same cutoff"); throw OpenMMException("All nonbonded forces must use the same cutoff");
if (paramNames.size() > 4) if (paramNames.size() > 4)
throw OpenMMException("CudaPlatform only supports four per-atom parameters for custom nonbonded forces"); throw OpenMMException("CudaPlatform only supports four per-atom parameters for custom nonbonded forces");
if (globalParamNames.size() > 8)
throw OpenMMException("CudaPlatform only supports eight global parameters for custom nonbonded forces");
gpu->sim.nonbondedCutoff = cutoffDistance; gpu->sim.nonbondedCutoff = cutoffDistance;
gpu->sim.nonbondedCutoffSqr = cutoffDistance*cutoffDistance; gpu->sim.nonbondedCutoffSqr = cutoffDistance*cutoffDistance;
gpu->sim.customNonbondedMethod = method; gpu->sim.customNonbondedMethod = method;
...@@ -612,8 +621,8 @@ void gpuSetCustomNonbondedParameters(gpuContext gpu, const vector<vector<double> ...@@ -612,8 +621,8 @@ void gpuSetCustomNonbondedParameters(gpuContext gpu, const vector<vector<double>
variables.push_back("r"); variables.push_back("r");
for (int i = 0; i < paramNames.size(); i++) for (int i = 0; i < paramNames.size(); i++)
variables.push_back(paramNames[i]); variables.push_back(paramNames[i]);
SetCustomNonbondedEnergyExpression(createExpression<128>(energyExp, Lepton::Parser::parse(energyExp).optimize().createProgram(), variables)); SetCustomNonbondedEnergyExpression(createExpression<128>(energyExp, Lepton::Parser::parse(energyExp).optimize().createProgram(), variables, globalParamNames));
SetCustomNonbondedForceExpression(createExpression<128>(energyExp, Lepton::Parser::parse(energyExp).differentiate("r").optimize().createProgram(), variables)); SetCustomNonbondedForceExpression(createExpression<128>(energyExp, Lepton::Parser::parse(energyExp).differentiate("r").optimize().createProgram(), variables, globalParamNames));
Expression<64> paramExpressions[4]; Expression<64> paramExpressions[4];
vector<string> combiningRuleParams; vector<string> combiningRuleParams;
combiningRuleParams.push_back(""); combiningRuleParams.push_back("");
...@@ -627,7 +636,7 @@ void gpuSetCustomNonbondedParameters(gpuContext gpu, const vector<vector<double> ...@@ -627,7 +636,7 @@ void gpuSetCustomNonbondedParameters(gpuContext gpu, const vector<vector<double>
combiningRuleParams.push_back(""); combiningRuleParams.push_back("");
} }
for (int i = 0; i < paramNames.size(); i++) for (int i = 0; i < paramNames.size(); i++)
paramExpressions[i] = createExpression<64>(combiningRules[i], Lepton::Parser::parse(combiningRules[i]).optimize().createProgram(), combiningRuleParams); paramExpressions[i] = createExpression<64>(combiningRules[i], Lepton::Parser::parse(combiningRules[i]).optimize().createProgram(), combiningRuleParams, globalParamNames);
SetCustomNonbondedCombiningRules(paramExpressions); SetCustomNonbondedCombiningRules(paramExpressions);
} }
......
...@@ -186,7 +186,7 @@ extern "C" ...@@ -186,7 +186,7 @@ extern "C"
void gpuSetCustomNonbondedParameters(gpuContext gpu, const std::vector<std::vector<double> >& parameters, const std::vector<std::vector<int> >& exclusions, void gpuSetCustomNonbondedParameters(gpuContext gpu, const std::vector<std::vector<double> >& parameters, const std::vector<std::vector<int> >& exclusions,
const std::vector<int>& exceptionAtom1, const std::vector<int>& exceptionAtom2, const std::vector<std::vector<double> >& exceptionParams, const std::vector<int>& exceptionAtom1, const std::vector<int>& exceptionAtom2, const std::vector<std::vector<double> >& exceptionParams,
CudaNonbondedMethod method, float cutoffDistance, const std::string& energyExp, const std::vector<std::string>& combiningRules, CudaNonbondedMethod method, float cutoffDistance, const std::string& energyExp, const std::vector<std::string>& combiningRules,
const std::vector<std::string>& paramNames); const std::vector<std::string>& paramNames, const std::vector<std::string>& globalParamNames);
extern "C" extern "C"
void gpuSetEwaldParameters(gpuContext gpu, float alpha, int kmaxx, int kmaxy, int kmaxz); void gpuSetEwaldParameters(gpuContext gpu, float alpha, int kmaxx, int kmaxy, int kmaxz);
......
...@@ -53,6 +53,7 @@ static __constant__ cudaGmxSimulation cSim; ...@@ -53,6 +53,7 @@ static __constant__ cudaGmxSimulation cSim;
static __constant__ Expression<128> forceExp; static __constant__ Expression<128> forceExp;
static __constant__ Expression<128> energyExp; static __constant__ Expression<128> energyExp;
static __constant__ Expression<64> combiningRules[4]; static __constant__ Expression<64> combiningRules[4];
static __constant__ float globalParams[8];
void SetCalculateCustomNonbondedForcesSim(gpuContext gpu) void SetCalculateCustomNonbondedForcesSim(gpuContext gpu)
{ {
...@@ -89,6 +90,13 @@ void SetCustomNonbondedCombiningRules(const Expression<64>* expressions) ...@@ -89,6 +90,13 @@ void SetCustomNonbondedCombiningRules(const Expression<64>* expressions)
RTERROR(status, "SetCustomNonbondedCombiningRules: cudaMemcpyToSymbol failed"); RTERROR(status, "SetCustomNonbondedCombiningRules: cudaMemcpyToSymbol failed");
} }
void SetCustomNonbondedGlobalParams(const vector<float>& paramValues)
{
cudaError_t status;
status = cudaMemcpyToSymbol(globalParams, &paramValues[0], sizeof(globalParams));
RTERROR(status, "SetCustomNonbondedGlobalParams: cudaMemcpyToSymbol failed");
}
template<int SIZE> template<int SIZE>
__device__ float kEvaluateExpression_kernel(Expression<SIZE>* expression, float* stack, float var0, float4 vars1, float4 vars2) __device__ float kEvaluateExpression_kernel(Expression<SIZE>* expression, float* stack, float var0, float4 vars1, float4 vars2)
{ {
...@@ -127,6 +135,9 @@ __device__ float kEvaluateExpression_kernel(Expression<SIZE>* expression, float* ...@@ -127,6 +135,9 @@ __device__ float kEvaluateExpression_kernel(Expression<SIZE>* expression, float*
case VARIABLE8: case VARIABLE8:
stack[++stackPointer] = vars2.w; stack[++stackPointer] = vars2.w;
break; break;
case GLOBAL:
stack[++stackPointer] = globalParams[(int) expression->arg[i]];
break;
case ADD: case ADD:
{ {
float temp = stack[stackPointer]; float temp = stack[stackPointer];
......
...@@ -39,6 +39,7 @@ __global__ void METHOD_NAME(kCalculateCustomNonbonded, Forces_kernel)(unsigned i ...@@ -39,6 +39,7 @@ __global__ void METHOD_NAME(kCalculateCustomNonbonded, Forces_kernel)(unsigned i
unsigned int numWorkUnits = cSim.pInteractionCount[0]; unsigned int numWorkUnits = cSim.pInteractionCount[0];
unsigned int pos = warp*numWorkUnits/totalWarps; unsigned int pos = warp*numWorkUnits/totalWarps;
unsigned int end = (warp+1)*numWorkUnits/totalWarps; unsigned int end = (warp+1)*numWorkUnits/totalWarps;
float totalEnergy = 0.0f;
#ifdef USE_CUTOFF #ifdef USE_CUTOFF
float3* tempBuffer = (float3*) &sA[cSim.nonbond_threads_per_block]; float3* tempBuffer = (float3*) &sA[cSim.nonbond_threads_per_block];
#endif #endif
...@@ -112,6 +113,7 @@ __global__ void METHOD_NAME(kCalculateCustomNonbonded, Forces_kernel)(unsigned i ...@@ -112,6 +113,7 @@ __global__ void METHOD_NAME(kCalculateCustomNonbonded, Forces_kernel)(unsigned i
float r = sqrt(dx*dx + dy*dy + dz*dz); float r = sqrt(dx*dx + dy*dy + dz*dz);
float invR = 1.0f/r; float invR = 1.0f/r;
float dEdR = -kEvaluateExpression_kernel(&forceExp, &stack[MAX_STACK_SIZE*threadIdx.x], r, combinedParams, combinedParams)*invR; float dEdR = -kEvaluateExpression_kernel(&forceExp, &stack[MAX_STACK_SIZE*threadIdx.x], r, combinedParams, combinedParams)*invR;
float energy = kEvaluateExpression_kernel(&energyExp, &stack[MAX_STACK_SIZE*threadIdx.x], r, combinedParams, combinedParams);
#ifdef USE_CUTOFF #ifdef USE_CUTOFF
if (!(excl & 0x1) || r > cSim.nonbondedCutoff) if (!(excl & 0x1) || r > cSim.nonbondedCutoff)
#else #else
...@@ -119,7 +121,9 @@ __global__ void METHOD_NAME(kCalculateCustomNonbonded, Forces_kernel)(unsigned i ...@@ -119,7 +121,9 @@ __global__ void METHOD_NAME(kCalculateCustomNonbonded, Forces_kernel)(unsigned i
#endif #endif
{ {
dEdR = 0.0f; dEdR = 0.0f;
energy = 0.0f;
} }
totalEnergy += 0.5f*energy;
dx *= dEdR; dx *= dEdR;
dy *= dEdR; dy *= dEdR;
dz *= dEdR; dz *= dEdR;
...@@ -213,12 +217,15 @@ __global__ void METHOD_NAME(kCalculateCustomNonbonded, Forces_kernel)(unsigned i ...@@ -213,12 +217,15 @@ __global__ void METHOD_NAME(kCalculateCustomNonbonded, Forces_kernel)(unsigned i
float r = sqrt(dx*dx + dy*dy + dz*dz); float r = sqrt(dx*dx + dy*dy + dz*dz);
float invR = 1.0f/r; float invR = 1.0f/r;
float dEdR = -kEvaluateExpression_kernel(&forceExp, &stack[MAX_STACK_SIZE*threadIdx.x], r, combinedParams, combinedParams)*invR; float dEdR = -kEvaluateExpression_kernel(&forceExp, &stack[MAX_STACK_SIZE*threadIdx.x], r, combinedParams, combinedParams)*invR;
float energy = kEvaluateExpression_kernel(&energyExp, &stack[MAX_STACK_SIZE*threadIdx.x], r, combinedParams, combinedParams);
#ifdef USE_CUTOFF #ifdef USE_CUTOFF
if (r > cSim.nonbondedCutoff) if (r > cSim.nonbondedCutoff)
{ {
dEdR = 0.0f; dEdR = 0.0f;
energy = 0.0f;
} }
#endif #endif
totalEnergy += energy;
dx *= dEdR; dx *= dEdR;
dy *= dEdR; dy *= dEdR;
dz *= dEdR; dz *= dEdR;
...@@ -276,12 +283,15 @@ __global__ void METHOD_NAME(kCalculateCustomNonbonded, Forces_kernel)(unsigned i ...@@ -276,12 +283,15 @@ __global__ void METHOD_NAME(kCalculateCustomNonbonded, Forces_kernel)(unsigned i
float r = sqrt(dx*dx + dy*dy + dz*dz); float r = sqrt(dx*dx + dy*dy + dz*dz);
float invR = 1.0f/r; float invR = 1.0f/r;
float dEdR = -kEvaluateExpression_kernel(&forceExp, &stack[MAX_STACK_SIZE*threadIdx.x], r, combinedParams, combinedParams)*invR; float dEdR = -kEvaluateExpression_kernel(&forceExp, &stack[MAX_STACK_SIZE*threadIdx.x], r, combinedParams, combinedParams)*invR;
float energy = kEvaluateExpression_kernel(&energyExp, &stack[MAX_STACK_SIZE*threadIdx.x], r, combinedParams, combinedParams);
#ifdef USE_CUTOFF #ifdef USE_CUTOFF
if (r > cSim.nonbondedCutoff) if (r > cSim.nonbondedCutoff)
{ {
dEdR = 0.0f; dEdR = 0.0f;
energy = 0.0f;
} }
#endif #endif
totalEnergy += energy;
dx *= dEdR; dx *= dEdR;
dy *= dEdR; dy *= dEdR;
dz *= dEdR; dz *= dEdR;
...@@ -375,6 +385,7 @@ __global__ void METHOD_NAME(kCalculateCustomNonbonded, Forces_kernel)(unsigned i ...@@ -375,6 +385,7 @@ __global__ void METHOD_NAME(kCalculateCustomNonbonded, Forces_kernel)(unsigned i
float r = sqrt(dx*dx + dy*dy + dz*dz); float r = sqrt(dx*dx + dy*dy + dz*dz);
float invR = 1.0f/r; float invR = 1.0f/r;
float dEdR = -kEvaluateExpression_kernel(&forceExp, &stack[MAX_STACK_SIZE*threadIdx.x], r, combinedParams, combinedParams)*invR; float dEdR = -kEvaluateExpression_kernel(&forceExp, &stack[MAX_STACK_SIZE*threadIdx.x], r, combinedParams, combinedParams)*invR;
float energy = kEvaluateExpression_kernel(&energyExp, &stack[MAX_STACK_SIZE*threadIdx.x], r, combinedParams, combinedParams);
#ifdef USE_CUTOFF #ifdef USE_CUTOFF
if (!(excl & 0x1) || r > cSim.nonbondedCutoff) if (!(excl & 0x1) || r > cSim.nonbondedCutoff)
#else #else
...@@ -382,7 +393,9 @@ __global__ void METHOD_NAME(kCalculateCustomNonbonded, Forces_kernel)(unsigned i ...@@ -382,7 +393,9 @@ __global__ void METHOD_NAME(kCalculateCustomNonbonded, Forces_kernel)(unsigned i
#endif #endif
{ {
dEdR = 0.0f; dEdR = 0.0f;
energy = 0.0f;
} }
totalEnergy += energy;
dx *= dEdR; dx *= dEdR;
dy *= dEdR; dy *= dEdR;
dz *= dEdR; dz *= dEdR;
...@@ -430,4 +443,5 @@ __global__ void METHOD_NAME(kCalculateCustomNonbonded, Forces_kernel)(unsigned i ...@@ -430,4 +443,5 @@ __global__ void METHOD_NAME(kCalculateCustomNonbonded, Forces_kernel)(unsigned i
pos++; pos++;
} }
cSim.pEnergy[blockIdx.x*blockDim.x+threadIdx.x] += totalEnergy;
} }
...@@ -205,7 +205,7 @@ void testPeriodic() { ...@@ -205,7 +205,7 @@ void testPeriodic() {
int main() { int main() {
try { try {
testSimpleExpression(); testSimpleExpression();
// testParameters(); testParameters();
// testExceptions(); // testExceptions();
testCutoff(); testCutoff();
testPeriodic(); testPeriodic();
......
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