Commit 77f2d93b authored by Peter Eastman's avatar Peter Eastman
Browse files

Optimized CUDA implementation of CustomNonbondedForce

parent 39ca36ee
...@@ -249,8 +249,8 @@ enum CudaNonbondedMethod ...@@ -249,8 +249,8 @@ enum CudaNonbondedMethod
}; };
enum ExpressionOp { enum ExpressionOp {
CONSTANT = 0, VARIABLE0, VARIABLE1, VARIABLE2, VARIABLE3, VARIABLE4, VARIABLE5, VARIABLE6, VARIABLE7, VARIABLE8, GLOBAL, CUSTOM, CUSTOM_DERIV, ADD, SUBTRACT, MULTIPLY, DIVIDE, VARIABLE0 = 0, VARIABLE1, VARIABLE2, VARIABLE3, VARIABLE4, VARIABLE5, VARIABLE6, VARIABLE7, MULTIPLY, DIVIDE, ADD, SUBTRACT, POWER, MULTIPLY_CONSTANT, POWER_CONSTANT, ADD_CONSTANT,
POWER, NEGATE, SQRT, EXP, LOG, SIN, COS, SEC, CSC, TAN, COT, ASIN, ACOS, ATAN, SQUARE, CUBE, RECIPROCAL, ADD_CONSTANT, MULTIPLY_CONSTANT, POWER_CONSTANT GLOBAL, CONSTANT, CUSTOM, CUSTOM_DERIV, NEGATE, RECIPROCAL, SQRT, EXP, LOG, SQUARE, CUBE, SIN, COS, SEC, CSC, TAN, COT, ASIN, ACOS, ATAN
}; };
template<int SIZE> template<int SIZE>
......
...@@ -168,8 +168,6 @@ static Expression<SIZE> createExpression(gpuContext gpu, const string& expressio ...@@ -168,8 +168,6 @@ static Expression<SIZE> createExpression(gpuContext gpu, const string& expressio
exp.op[i] = VARIABLE6; exp.op[i] = VARIABLE6;
else if (variables.size() > 7 && op.getName() == variables[7]) else if (variables.size() > 7 && op.getName() == variables[7])
exp.op[i] = VARIABLE7; exp.op[i] = VARIABLE7;
else if (variables.size() > 8 && op.getName() == variables[8])
exp.op[i] = VARIABLE8;
else { else {
int j; int j;
for (j = 0; j < globalParamNames.size() && op.getName() != globalParamNames[j]; j++); for (j = 0; j < globalParamNames.size() && op.getName() != globalParamNames[j]; j++);
...@@ -731,7 +729,6 @@ void gpuSetCustomNonbondedParameters(gpuContext gpu, const vector<vector<double> ...@@ -731,7 +729,6 @@ void gpuSetCustomNonbondedParameters(gpuContext gpu, const vector<vector<double>
SetCustomNonbondedForceExpression(createExpression<128>(gpu, energyExp, Lepton::Parser::parse(energyExp, functions).differentiate("r").optimize().createProgram(), variables, globalParamNames, gpu->sim.customExpressionStackSize)); SetCustomNonbondedForceExpression(createExpression<128>(gpu, energyExp, Lepton::Parser::parse(energyExp, functions).differentiate("r").optimize().createProgram(), variables, globalParamNames, gpu->sim.customExpressionStackSize));
Expression<64> paramExpressions[4]; Expression<64> paramExpressions[4];
vector<string> combiningRuleParams; vector<string> combiningRuleParams;
combiningRuleParams.push_back("");
for (int j = 1; j < 3; j++) { for (int j = 1; j < 3; j++) {
for (int i = 0; i < paramNames.size(); i++) { for (int i = 0; i < paramNames.size(); i++) {
stringstream name; stringstream name;
......
...@@ -103,176 +103,139 @@ void SetCustomNonbondedGlobalParams(float* paramValues) ...@@ -103,176 +103,139 @@ void SetCustomNonbondedGlobalParams(float* paramValues)
} }
#define STACK(y) stack[(y)*blockDim.x+threadIdx.x] #define STACK(y) stack[(y)*blockDim.x+threadIdx.x]
#define VARIABLE(y) variables[(y)*blockDim.x+threadIdx.x]
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* variables)
{ {
int stackPointer = -1; int stackPointer = -1;
for (int i = 0; i < expression->length; i++) for (int i = 0; i < expression->length; i++)
{ {
int op = expression->op[i]; int op = expression->op[i];
if (op < SQRT) { if (op < MULTIPLY) {
if (op < VARIABLE8) { STACK(++stackPointer) = VARIABLE(op-VARIABLE0);
if (op < VARIABLE4) { }
if (op == CONSTANT) { else if (op < NEGATE) {
STACK(++stackPointer) = expression->arg[i]; if (op < MULTIPLY_CONSTANT) {
} if (op == MULTIPLY) {
else if (op == VARIABLE0) { float temp = STACK(stackPointer);
STACK(++stackPointer) = var0; STACK(--stackPointer) *= temp;
}
else if (op == VARIABLE1) {
STACK(++stackPointer) = vars1.x;
}
else if (op == VARIABLE2) {
STACK(++stackPointer) = vars1.y;
}
else if (op == VARIABLE3) {
STACK(++stackPointer) = vars1.z;
}
} }
else { else if (op == DIVIDE) {
if (op == VARIABLE4) { float temp = STACK(stackPointer);
STACK(++stackPointer) = vars1.w; STACK(stackPointer) = temp/STACK(--stackPointer);
} }
else if (op == VARIABLE5) { else if (op == ADD) {
STACK(++stackPointer) = vars2.x; float temp = STACK(stackPointer);
} STACK(--stackPointer) += temp;
else if (op == VARIABLE6) { }
STACK(++stackPointer) = vars2.y; else if (op == SUBTRACT) {
} float temp = STACK(stackPointer);
else if (op == VARIABLE7) { STACK(stackPointer) = temp-STACK(--stackPointer);
STACK(++stackPointer) = vars2.z; }
} else if (op == POWER) {
float temp = STACK(stackPointer);
STACK(stackPointer) = pow(temp, STACK(--stackPointer));
}
}
else if (op < GLOBAL) {
if (op == MULTIPLY_CONSTANT) {
STACK(stackPointer) *= expression->arg[i];
}
else if (op == POWER_CONSTANT) {
STACK(stackPointer) = pow(STACK(stackPointer), expression->arg[i]);
}
else if (op == ADD_CONSTANT) {
STACK(stackPointer) += expression->arg[i];
} }
} }
else { else {
if (op < MULTIPLY) { if (op == GLOBAL) {
if (op == VARIABLE8) { STACK(++stackPointer) = globalParams[(int) expression->arg[i]];
STACK(++stackPointer) = vars2.w;
}
else if (op == GLOBAL) {
STACK(++stackPointer) = globalParams[(int) expression->arg[i]];
}
else if (op == CUSTOM || op == CUSTOM_DERIV) {
int function = (int) expression->arg[i];
float x = STACK(stackPointer);
float4 params = cSim.pTabulatedFunctionParams[function];
if (x < params.x || x > params.y)
STACK(stackPointer) = 0.0f;
else
{
int index = floor((x-params.x)*params.z);
float4 coeff;
if (function == 0)
coeff = tex1Dfetch(texRef0, index);
else if (function == 1)
coeff = tex1Dfetch(texRef1, index);
else if (function == 2)
coeff = tex1Dfetch(texRef2, index);
else
coeff = tex1Dfetch(texRef3, index);
x = (x-params.x)*params.z-index;
if (op == CUSTOM)
STACK(stackPointer) = coeff.x+x*(coeff.y+x*(coeff.z+x*coeff.w));
else
STACK(stackPointer) = (coeff.y+x*(2.0f*coeff.z+x*3.0f*coeff.w))*params.z;
}
}
else if (op == ADD) {
float temp = STACK(stackPointer);
STACK(--stackPointer) += temp;
}
else if (op == SUBTRACT) {
float temp = STACK(stackPointer);
STACK(stackPointer) = temp-STACK(--stackPointer);
}
} }
else { else if (op == CONSTANT) {
if (op == MULTIPLY) { STACK(++stackPointer) = expression->arg[i];
float temp = STACK(stackPointer); }
STACK(--stackPointer) *= temp; else if (op == CUSTOM || op == CUSTOM_DERIV) {
} int function = (int) expression->arg[i];
else if (op == DIVIDE) { float x = STACK(stackPointer);
float temp = STACK(stackPointer); float4 params = cSim.pTabulatedFunctionParams[function];
STACK(stackPointer) = temp/STACK(--stackPointer); if (x < params.x || x > params.y)
} STACK(stackPointer) = 0.0f;
else if (op == POWER) { else
float temp = STACK(stackPointer); {
STACK(stackPointer) = pow(temp, STACK(--stackPointer)); int index = floor((x-params.x)*params.z);
} float4 coeff;
else if (op == NEGATE) { if (function == 0)
STACK(stackPointer) *= -1.0f; coeff = tex1Dfetch(texRef0, index);
else if (function == 1)
coeff = tex1Dfetch(texRef1, index);
else if (function == 2)
coeff = tex1Dfetch(texRef2, index);
else
coeff = tex1Dfetch(texRef3, index);
x = (x-params.x)*params.z-index;
if (op == CUSTOM)
STACK(stackPointer) = coeff.x+x*(coeff.y+x*(coeff.z+x*coeff.w));
else
STACK(stackPointer) = (coeff.y+x*(2.0f*coeff.z+x*3.0f*coeff.w))*params.z;
} }
} }
} }
} }
else { else {
if (op < ASIN) { if (op < SIN) {
if (op < SEC) { if (op == NEGATE) {
if (op == SQRT) { STACK(stackPointer) *= -1.0f;
STACK(stackPointer) = sqrt(STACK(stackPointer));
}
else if (op == EXP) {
STACK(stackPointer) = exp(STACK(stackPointer));
}
else if (op == LOG) {
STACK(stackPointer) = log(STACK(stackPointer));
}
else if (op == SIN) {
STACK(stackPointer) = sin(STACK(stackPointer));
}
else if (op == COS) {
STACK(stackPointer) = cos(STACK(stackPointer));
}
} }
else { else if (op == RECIPROCAL) {
if (op == SEC) { STACK(stackPointer) = 1.0f/STACK(stackPointer);
STACK(stackPointer) = 1.0f/cos(STACK(stackPointer)); }
} else if (op == SQRT) {
else if (op == CSC) { STACK(stackPointer) = sqrt(STACK(stackPointer));
STACK(stackPointer) = 1.0f/sin(STACK(stackPointer)); }
} else if (op == EXP) {
else if (op == TAN) { STACK(stackPointer) = exp(STACK(stackPointer));
STACK(stackPointer) = tan(STACK(stackPointer)); }
} else if (op == LOG) {
else if (op == COT) { STACK(stackPointer) = log(STACK(stackPointer));
STACK(stackPointer) = 1.0f/tan(STACK(stackPointer)); }
} else if (op == SQUARE) {
float temp = STACK(stackPointer);
STACK(stackPointer) *= temp;
}
else if (op == CUBE) {
float temp = STACK(stackPointer);
STACK(stackPointer) *= temp*temp;
} }
} }
else { else {
if (op < RECIPROCAL) { if (op == SIN) {
if (op == ASIN) { STACK(stackPointer) = sin(STACK(stackPointer));
STACK(stackPointer) = asin(STACK(stackPointer));
}
else if (op == ACOS) {
STACK(stackPointer) = acos(STACK(stackPointer));
}
else if (op == ATAN) {
STACK(stackPointer) = atan(STACK(stackPointer));
}
else if (op == SQUARE) {
float temp = STACK(stackPointer);
STACK(stackPointer) *= temp;
}
else if (op == CUBE) {
float temp = STACK(stackPointer);
STACK(stackPointer) *= temp*temp;
}
} }
else { else if (op == COS) {
if (op == RECIPROCAL) { STACK(stackPointer) = cos(STACK(stackPointer));
STACK(stackPointer) = 1.0f/STACK(stackPointer); }
} else if (op == SEC) {
else if (op == ADD_CONSTANT) { STACK(stackPointer) = 1.0f/cos(STACK(stackPointer));
STACK(stackPointer) += expression->arg[i]; }
} else if (op == CSC) {
else if (op == MULTIPLY_CONSTANT) { STACK(stackPointer) = 1.0f/sin(STACK(stackPointer));
STACK(stackPointer) *= expression->arg[i]; }
} else if (op == TAN) {
else if (op == POWER_CONSTANT) { STACK(stackPointer) = tan(STACK(stackPointer));
STACK(stackPointer) = pow(STACK(stackPointer), expression->arg[i]); }
} else if (op == COT) {
STACK(stackPointer) = 1.0f/tan(STACK(stackPointer));
}
else if (op == ASIN) {
STACK(stackPointer) = asin(STACK(stackPointer));
}
else if (op == ACOS) {
STACK(stackPointer) = acos(STACK(stackPointer));
}
else if (op == ATAN) {
STACK(stackPointer) = atan(STACK(stackPointer));
} }
} }
} }
...@@ -336,7 +299,7 @@ void kCalculateCustomNonbondedForces(gpuContext gpu, bool neighborListValid) ...@@ -336,7 +299,7 @@ void kCalculateCustomNonbondedForces(gpuContext gpu, bool neighborListValid)
cudaBindTexture(NULL, &texRef3, gpu->tabulatedFunctions[3].coefficients->_pDevData, &channelDesc, gpu->tabulatedFunctions[3].coefficients->_length*sizeof(float4)); cudaBindTexture(NULL, &texRef3, gpu->tabulatedFunctions[3].coefficients->_pDevData, &channelDesc, gpu->tabulatedFunctions[3].coefficients->_length*sizeof(float4));
gpu->tabulatedFunctionsChanged = false; gpu->tabulatedFunctionsChanged = false;
} }
int sharedPerThread = sizeof(Atom)+gpu->sim.customExpressionStackSize*sizeof(float); int sharedPerThread = sizeof(Atom)+gpu->sim.customExpressionStackSize*sizeof(float)+8*sizeof(float);
if (gpu->sim.customNonbondedMethod != NO_CUTOFF) if (gpu->sim.customNonbondedMethod != NO_CUTOFF)
sharedPerThread += sizeof(float3); sharedPerThread += sizeof(float3);
int threads = gpu->sim.nonbond_threads_per_block; int threads = gpu->sim.nonbond_threads_per_block;
...@@ -392,7 +355,7 @@ void kCalculateCustomNonbondedForces(gpuContext gpu, bool neighborListValid) ...@@ -392,7 +355,7 @@ void kCalculateCustomNonbondedForces(gpuContext gpu, bool neighborListValid)
kCalculateCustomNonbondedPeriodicForces_kernel<<<gpu->sim.nonbond_blocks, threads, sharedPerThread*threads>>>(gpu->sim.pInteractingWorkUnit); kCalculateCustomNonbondedPeriodicForces_kernel<<<gpu->sim.nonbond_blocks, threads, sharedPerThread*threads>>>(gpu->sim.pInteractingWorkUnit);
LAUNCHERROR("kCalculateCustomNonbondedPeriodicForces"); LAUNCHERROR("kCalculateCustomNonbondedPeriodicForces");
kCalculateCustomNonbondedPeriodicExceptions_kernel<<<gpu->sim.blocks, gpu->sim.custom_exception_threads_per_block, kCalculateCustomNonbondedPeriodicExceptions_kernel<<<gpu->sim.blocks, gpu->sim.custom_exception_threads_per_block,
gpu->sim.customExpressionStackSize*sizeof(float)*gpu->sim.custom_exception_threads_per_block>>>(); (gpu->sim.customExpressionStackSize+8)*sizeof(float)*gpu->sim.custom_exception_threads_per_block>>>();
LAUNCHERROR("kCalculateCustomNonbondedPeriodicExceptions"); LAUNCHERROR("kCalculateCustomNonbondedPeriodicExceptions");
break; break;
} }
......
...@@ -34,6 +34,7 @@ __global__ void METHOD_NAME(kCalculateCustomNonbonded, Forces_kernel)(unsigned i ...@@ -34,6 +34,7 @@ __global__ void METHOD_NAME(kCalculateCustomNonbonded, Forces_kernel)(unsigned i
{ {
extern __shared__ float stack[]; extern __shared__ float stack[];
Atom* sA = (Atom*) &stack[cSim.customExpressionStackSize*blockDim.x]; Atom* sA = (Atom*) &stack[cSim.customExpressionStackSize*blockDim.x];
float* variables = (float*) &sA[blockDim.x];
unsigned int totalWarps = cSim.nonbond_blocks*cSim.nonbond_threads_per_block/GRID; unsigned int totalWarps = cSim.nonbond_blocks*cSim.nonbond_threads_per_block/GRID;
unsigned int warp = (blockIdx.x*blockDim.x+threadIdx.x)/GRID; unsigned int warp = (blockIdx.x*blockDim.x+threadIdx.x)/GRID;
unsigned int numWorkUnits = cSim.pInteractionCount[0]; unsigned int numWorkUnits = cSim.pInteractionCount[0];
...@@ -79,26 +80,38 @@ __global__ void METHOD_NAME(kCalculateCustomNonbonded, Forces_kernel)(unsigned i ...@@ -79,26 +80,38 @@ __global__ void METHOD_NAME(kCalculateCustomNonbonded, Forces_kernel)(unsigned i
{ {
// Apply the combining rules to the parameters. // Apply the combining rules to the parameters.
float4 combinedParams = make_float4(0, 0, 0, 0); float combinedParams[4];
VARIABLE(0) = params.x;
VARIABLE(1) = params.y;
VARIABLE(2) = params.z;
VARIABLE(3) = params.w;
for (int k = 0; k < cSim.customParameters; k++) for (int k = 0; k < cSim.customParameters; k++)
{ {
float value = kEvaluateExpression_kernel(&combiningRules[k], stack, 0.0f, params, psA[j].params); VARIABLE(4) = psA[j].params.x;
VARIABLE(5) = psA[j].params.y;
VARIABLE(6) = psA[j].params.z;
VARIABLE(7) = psA[j].params.w;
float value = kEvaluateExpression_kernel(&combiningRules[k], stack, variables);
switch (k) switch (k)
{ {
case 0: case 0:
combinedParams.x = value; combinedParams[0] = value;
break; break;
case 1: case 1:
combinedParams.y = value; combinedParams[1] = value;
break; break;
case 2: case 2:
combinedParams.z = value; combinedParams[2] = value;
break; break;
case 3: case 3:
combinedParams.w = value; combinedParams[3] = value;
break; break;
} }
} }
VARIABLE(1) = combinedParams[0];
VARIABLE(2) = combinedParams[1];
VARIABLE(3) = combinedParams[2];
VARIABLE(4) = combinedParams[3];
// Compute the force. // Compute the force.
...@@ -112,8 +125,9 @@ __global__ void METHOD_NAME(kCalculateCustomNonbonded, Forces_kernel)(unsigned i ...@@ -112,8 +125,9 @@ __global__ void METHOD_NAME(kCalculateCustomNonbonded, Forces_kernel)(unsigned i
#endif #endif
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, r, combinedParams, combinedParams)*invR; VARIABLE(0) = r;
float energy = kEvaluateExpression_kernel(&energyExp, stack, r, combinedParams, combinedParams); float dEdR = -kEvaluateExpression_kernel(&forceExp, stack, variables)*invR;
float energy = kEvaluateExpression_kernel(&energyExp, stack, variables);
#ifdef USE_CUTOFF #ifdef USE_CUTOFF
if (!(excl & 0x1) || r > cSim.nonbondedCutoff) if (!(excl & 0x1) || r > cSim.nonbondedCutoff)
#else #else
...@@ -183,26 +197,38 @@ __global__ void METHOD_NAME(kCalculateCustomNonbonded, Forces_kernel)(unsigned i ...@@ -183,26 +197,38 @@ __global__ void METHOD_NAME(kCalculateCustomNonbonded, Forces_kernel)(unsigned i
{ {
// Apply the combining rules to the parameters. // Apply the combining rules to the parameters.
float4 combinedParams = make_float4(0, 0, 0, 0); float combinedParams[4];
VARIABLE(0) = params.x;
VARIABLE(1) = params.y;
VARIABLE(2) = params.z;
VARIABLE(3) = params.w;
for (int k = 0; k < cSim.customParameters; k++) for (int k = 0; k < cSim.customParameters; k++)
{ {
float value = kEvaluateExpression_kernel(&combiningRules[k], stack, 0.0f, params, psA[tj].params); VARIABLE(4) = psA[j].params.x;
VARIABLE(5) = psA[j].params.y;
VARIABLE(6) = psA[j].params.z;
VARIABLE(7) = psA[j].params.w;
float value = kEvaluateExpression_kernel(&combiningRules[k], stack, variables);
switch (k) switch (k)
{ {
case 0: case 0:
combinedParams.x = value; combinedParams[0] = value;
break; break;
case 1: case 1:
combinedParams.y = value; combinedParams[1] = value;
break; break;
case 2: case 2:
combinedParams.z = value; combinedParams[2] = value;
break; break;
case 3: case 3:
combinedParams.w = value; combinedParams[3] = value;
break; break;
} }
} }
VARIABLE(1) = combinedParams[0];
VARIABLE(2) = combinedParams[1];
VARIABLE(3) = combinedParams[2];
VARIABLE(4) = combinedParams[3];
// Compute the force. // Compute the force.
...@@ -216,8 +242,9 @@ __global__ void METHOD_NAME(kCalculateCustomNonbonded, Forces_kernel)(unsigned i ...@@ -216,8 +242,9 @@ __global__ void METHOD_NAME(kCalculateCustomNonbonded, Forces_kernel)(unsigned i
#endif #endif
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, r, combinedParams, combinedParams)*invR; VARIABLE(0) = r;
float energy = kEvaluateExpression_kernel(&energyExp, stack, r, combinedParams, combinedParams); float dEdR = -kEvaluateExpression_kernel(&forceExp, stack, variables)*invR;
float energy = kEvaluateExpression_kernel(&energyExp, stack, variables);
#ifdef USE_CUTOFF #ifdef USE_CUTOFF
if (r > cSim.nonbondedCutoff) if (r > cSim.nonbondedCutoff)
{ {
...@@ -249,26 +276,38 @@ __global__ void METHOD_NAME(kCalculateCustomNonbonded, Forces_kernel)(unsigned i ...@@ -249,26 +276,38 @@ __global__ void METHOD_NAME(kCalculateCustomNonbonded, Forces_kernel)(unsigned i
{ {
// Apply the combining rules to the parameters. // Apply the combining rules to the parameters.
float4 combinedParams = make_float4(0, 0, 0, 0); float combinedParams[4];
VARIABLE(0) = params.x;
VARIABLE(1) = params.y;
VARIABLE(2) = params.z;
VARIABLE(3) = params.w;
for (int k = 0; k < cSim.customParameters; k++) for (int k = 0; k < cSim.customParameters; k++)
{ {
float value = kEvaluateExpression_kernel(&combiningRules[k], stack, 0.0f, params, psA[j].params); VARIABLE(4) = psA[j].params.x;
VARIABLE(5) = psA[j].params.y;
VARIABLE(6) = psA[j].params.z;
VARIABLE(7) = psA[j].params.w;
float value = kEvaluateExpression_kernel(&combiningRules[k], stack, variables);
switch (k) switch (k)
{ {
case 0: case 0:
combinedParams.x = value; combinedParams[0] = value;
break; break;
case 1: case 1:
combinedParams.y = value; combinedParams[1] = value;
break; break;
case 2: case 2:
combinedParams.z = value; combinedParams[2] = value;
break; break;
case 3: case 3:
combinedParams.w = value; combinedParams[3] = value;
break; break;
} }
} }
VARIABLE(1) = combinedParams[0];
VARIABLE(2) = combinedParams[1];
VARIABLE(3) = combinedParams[2];
VARIABLE(4) = combinedParams[3];
// Compute the force. // Compute the force.
...@@ -282,8 +321,9 @@ __global__ void METHOD_NAME(kCalculateCustomNonbonded, Forces_kernel)(unsigned i ...@@ -282,8 +321,9 @@ __global__ void METHOD_NAME(kCalculateCustomNonbonded, Forces_kernel)(unsigned i
#endif #endif
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, r, combinedParams, combinedParams)*invR; VARIABLE(0) = r;
float energy = kEvaluateExpression_kernel(&energyExp, stack, r, combinedParams, combinedParams); float dEdR = -kEvaluateExpression_kernel(&forceExp, stack, variables)*invR;
float energy = kEvaluateExpression_kernel(&energyExp, stack, variables);
#ifdef USE_CUTOFF #ifdef USE_CUTOFF
if (r > cSim.nonbondedCutoff) if (r > cSim.nonbondedCutoff)
{ {
...@@ -351,26 +391,38 @@ __global__ void METHOD_NAME(kCalculateCustomNonbonded, Forces_kernel)(unsigned i ...@@ -351,26 +391,38 @@ __global__ void METHOD_NAME(kCalculateCustomNonbonded, Forces_kernel)(unsigned i
{ {
// Apply the combining rules to the parameters. // Apply the combining rules to the parameters.
float4 combinedParams = make_float4(0, 0, 0, 0); float combinedParams[4];
VARIABLE(0) = params.x;
VARIABLE(1) = params.y;
VARIABLE(2) = params.z;
VARIABLE(3) = params.w;
for (int k = 0; k < cSim.customParameters; k++) for (int k = 0; k < cSim.customParameters; k++)
{ {
float value = kEvaluateExpression_kernel(&combiningRules[k], stack, 0.0f, params, psA[tj].params); VARIABLE(4) = psA[j].params.x;
VARIABLE(5) = psA[j].params.y;
VARIABLE(6) = psA[j].params.z;
VARIABLE(7) = psA[j].params.w;
float value = kEvaluateExpression_kernel(&combiningRules[k], stack, variables);
switch (k) switch (k)
{ {
case 0: case 0:
combinedParams.x = value; combinedParams[0] = value;
break; break;
case 1: case 1:
combinedParams.y = value; combinedParams[1] = value;
break; break;
case 2: case 2:
combinedParams.z = value; combinedParams[2] = value;
break; break;
case 3: case 3:
combinedParams.w = value; combinedParams[3] = value;
break; break;
} }
} }
VARIABLE(1) = combinedParams[0];
VARIABLE(2) = combinedParams[1];
VARIABLE(3) = combinedParams[2];
VARIABLE(4) = combinedParams[3];
// Compute the force. // Compute the force.
...@@ -384,8 +436,9 @@ __global__ void METHOD_NAME(kCalculateCustomNonbonded, Forces_kernel)(unsigned i ...@@ -384,8 +436,9 @@ __global__ void METHOD_NAME(kCalculateCustomNonbonded, Forces_kernel)(unsigned i
#endif #endif
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, r, combinedParams, combinedParams)*invR; VARIABLE(0) = r;
float energy = kEvaluateExpression_kernel(&energyExp, stack, r, combinedParams, combinedParams); float dEdR = -kEvaluateExpression_kernel(&forceExp, stack, variables)*invR;
float energy = kEvaluateExpression_kernel(&energyExp, stack, variables);
#ifdef USE_CUTOFF #ifdef USE_CUTOFF
if (!(excl & 0x1) || r > cSim.nonbondedCutoff) if (!(excl & 0x1) || r > cSim.nonbondedCutoff)
#else #else
...@@ -450,6 +503,7 @@ __global__ void METHOD_NAME(kCalculateCustomNonbonded, Forces_kernel)(unsigned i ...@@ -450,6 +503,7 @@ __global__ void METHOD_NAME(kCalculateCustomNonbonded, Forces_kernel)(unsigned i
__global__ void METHOD_NAME(kCalculateCustomNonbonded, Exceptions_kernel)() __global__ void METHOD_NAME(kCalculateCustomNonbonded, Exceptions_kernel)()
{ {
extern __shared__ float stack[]; extern __shared__ float stack[];
float* variables = (float*) &stack[cSim.customExpressionStackSize*blockDim.x];
unsigned int pos = blockIdx.x * blockDim.x + threadIdx.x; unsigned int pos = blockIdx.x * blockDim.x + threadIdx.x;
float totalEnergy = 0.0f; float totalEnergy = 0.0f;
...@@ -469,8 +523,13 @@ __global__ void METHOD_NAME(kCalculateCustomNonbonded, Exceptions_kernel)() ...@@ -469,8 +523,13 @@ __global__ void METHOD_NAME(kCalculateCustomNonbonded, Exceptions_kernel)()
#endif #endif
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, r, params, params)*invR; VARIABLE(0) = r;
float energy = kEvaluateExpression_kernel(&energyExp, stack, r, params, params); VARIABLE(1) = params.x;
VARIABLE(2) = params.y;
VARIABLE(3) = params.z;
VARIABLE(4) = params.w;
float dEdR = -kEvaluateExpression_kernel(&forceExp, stack, variables)*invR;
float energy = kEvaluateExpression_kernel(&energyExp, stack, variables);
#ifdef USE_CUTOFF #ifdef USE_CUTOFF
if (r > cSim.nonbondedCutoff) if (r > cSim.nonbondedCutoff)
{ {
......
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