Commit b8bae04c authored by peastman's avatar peastman
Browse files

Merge pull request #644 from peastman/cpugb

Created CPU implementation of CustomGBForce
parents ff586f5f 4c8750ad
/* Portions copyright (c) 2009-2014 Stanford University and Simbios.
* Contributors: Peter Eastman
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject
* to the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS, CONTRIBUTORS OR COPYRIGHT HOLDERS BE
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#ifndef OPENMM_CPU_CUSTOM_GB_FORCE_H__
#define OPENMM_CPU_CUSTOM_GB_FORCE_H__
#include "CompiledExpressionSet.h"
#include "CpuNeighborList.h"
#include "lepton/CompiledExpression.h"
#include "openmm/CustomGBForce.h"
#include "openmm/internal/ThreadPool.h"
#include "openmm/internal/vectorize.h"
#include <map>
#include <set>
#include <vector>
namespace OpenMM {
class CpuCustomGBForce {
private:
class ComputeForceTask;
class ThreadData;
bool cutoff;
bool periodic;
const CpuNeighborList* neighborList;
float periodicBoxSize[3];
float cutoffDistance, cutoffDistance2;
const std::vector<std::set<int> > exclusions;
std::vector<std::string> valueNames;
std::vector<CustomGBForce::ComputationType> valueTypes;
std::vector<std::string> paramNames;
std::vector<CustomGBForce::ComputationType> energyTypes;
ThreadPool& threads;
std::vector<ThreadData*> threadData;
std::vector<double> threadEnergy;
// Workspace vectors
std::vector<std::vector<float> > values, dEdV;
// The following variables are used to make information accessible to the individual threads.
int numberOfAtoms;
float* posq;
RealOpenMM** atomParameters;
const std::map<std::string, double>* globalParameters;
std::vector<AlignedArray<float> >* threadForce;
bool includeForce, includeEnergy;
void* atomicCounter;
/**
* This routine contains the code executed by each thread.
*/
void threadComputeForce(ThreadPool& threads, int threadIndex);
/**
* Calculate a computed value that is based on particle pairs
*
* @param index the index of the value to compute
* @param data workspace for the current thread
* @param numAtoms number of atoms
* @param posq atom coordinates
* @param atomParameters atomParameters[atomIndex][paramterIndex]
* @param useExclusions specifies whether to use exclusions
*/
void calculateParticlePairValue(int index, ThreadData& data, int numAtoms, float* posq, RealOpenMM** atomParameters,
bool useExclusions, const fvec4& boxSize, const fvec4& invBoxSize);
/**
* Evaluate a single atom pair as part of calculating a computed value
*
* @param index the index of the value to compute
* @param atom1 the index of the first atom in the pair
* @param atom2 the index of the second atom in the pair
* @param data workspace for the current thread
* @param posq atom coordinates
* @param atomParameters atomParameters[atomIndex][paramterIndex]
*/
void calculateOnePairValue(int index, int atom1, int atom2, ThreadData& data, float* posq, RealOpenMM** atomParameters,
std::vector<float>& valueArray, const fvec4& boxSize, const fvec4& invBoxSize);
/**
* Calculate an energy term of type SingleParticle
*
* @param index the index of the value to compute
* @param data workspace for the current thread
* @param numAtoms number of atoms
* @param posq atom coordinates
* @param atomParameters atomParameters[atomIndex][paramterIndex]
* @param forces forces on atoms are added to this
* @param totalEnergy the energy contribution is added to this
*/
void calculateSingleParticleEnergyTerm(int index, ThreadData& data, int numAtoms, float* posq, RealOpenMM** atomParameters, float* forces, double& totalEnergy);
/**
* Calculate an energy term that is based on particle pairs
*
* @param index the index of the term to compute
* @param data workspace for the current thread
* @param numAtoms number of atoms
* @param posq atom coordinates
* @param atomParameters atomParameters[atomIndex][paramterIndex]
* @param useExclusions specifies whether to use exclusions
* @param forces forces on atoms are added to this
* @param totalEnergy the energy contribution is added to this
*/
void calculateParticlePairEnergyTerm(int index, ThreadData& data, int numAtoms, float* posq, RealOpenMM** atomParameters,
bool useExclusions, float* forces, double& totalEnergy, const fvec4& boxSize, const fvec4& invBoxSize);
/**
* Evaluate a single atom pair as part of calculating an energy term
*
* @param index the index of the term to compute
* @param atom1 the index of the first atom in the pair
* @param atom2 the index of the second atom in the pair
* @param data workspace for the current thread
* @param posq atom coordinates
* @param atomParameters atomParameters[atomIndex][paramterIndex]
* @param forces forces on atoms are added to this
* @param totalEnergy the energy contribution is added to this
*/
void calculateOnePairEnergyTerm(int index, int atom1, int atom2, ThreadData& data, float* posq, RealOpenMM** atomParameters,
float* forces, double& totalEnergy, const fvec4& boxSize, const fvec4& invBoxSize);
/**
* Apply the chain rule to compute forces on atoms
*
* @param data workspace for the current thread
* @param numAtoms number of atoms
* @param posq atom coordinates
* @param atomParameters atomParameters[atomIndex][paramterIndex]
* @param forces forces on atoms are added to this
*/
void calculateChainRuleForces(ThreadData& data, int numAtoms, float* posq, RealOpenMM** atomParameters,
float* forces, const fvec4& boxSize, const fvec4& invBoxSize);
/**
* Evaluate a single atom pair as part of applying the chain rule
*
* @param atom1 the index of the first atom in the pair
* @param atom2 the index of the second atom in the pair
* @param data workspace for the current thread
* @param posq atom coordinates
* @param atomParameters atomParameters[atomIndex][paramterIndex]
* @param forces forces on atoms are added to this
* @param isExcluded specifies whether this is an excluded pair
*/
void calculateOnePairChainRule(int atom1, int atom2, ThreadData& data, float* posq, RealOpenMM** atomParameters,
float* forces, bool isExcluded, const fvec4& boxSize, const fvec4& invBoxSize);
/**
* Compute the displacement and squared distance between two points, optionally using
* periodic boundary conditions.
*/
void getDeltaR(const fvec4& posI, const fvec4& posJ, fvec4& deltaR, float& r2, bool periodic, const fvec4& boxSize, const fvec4& invBoxSize) const;
public:
/**
* Construct a new CpuCustomGBForce.
*/
CpuCustomGBForce(int numAtoms, const std::vector<std::set<int> >& exclusions,
const std::vector<Lepton::CompiledExpression>& valueExpressions,
const std::vector<std::vector<Lepton::CompiledExpression> >& valueDerivExpressions,
const std::vector<std::vector<Lepton::CompiledExpression> >& valueGradientExpressions,
const std::vector<std::string>& valueNames,
const std::vector<CustomGBForce::ComputationType>& valueTypes,
const std::vector<Lepton::CompiledExpression>& energyExpressions,
const std::vector<std::vector<Lepton::CompiledExpression> >& energyDerivExpressions,
const std::vector<std::vector<Lepton::CompiledExpression> >& energyGradientExpressions,
const std::vector<CustomGBForce::ComputationType>& energyTypes,
const std::vector<std::string>& parameterNames, ThreadPool& threads);
~CpuCustomGBForce();
/**
* Set the force to use a cutoff.
*
* @param distance the cutoff distance
* @param neighbors the neighbor list to use
*/
void setUseCutoff(float distance, const CpuNeighborList& neighbors);
/**
* Set the force to use periodic boundary conditions. This requires that a cutoff has
* already been set, and the smallest side of the periodic box is at least twice the cutoff
* distance.
*
* @param boxSize the X, Y, and Z widths of the periodic box
*/
void setPeriodic(RealVec& boxSize);
/**
* Calculate custom GB ixn
*
* @param numberOfAtoms number of atoms
* @param posq atom coordinates
* @param atomParameters atomParameters[atomIndex][paramterIndex]
* @param globalParameters the values of global parameters
* @param forces force array (forces added)
* @param totalEnergy total energy
*/
void calculateIxn(int numberOfAtoms, float* posq, RealOpenMM** atomParameters,
std::map<std::string, double>& globalParameters, std::vector<AlignedArray<float> >& threadForce, bool includeForce, bool includeEnergy, double& totalEnergy);
};
class CpuCustomGBForce::ThreadData {
public:
ThreadData(int numAtoms, int numThreads, int threadIndex,
const std::vector<Lepton::CompiledExpression>& valueExpressions,
const std::vector<std::vector<Lepton::CompiledExpression> >& valueDerivExpressions,
const std::vector<std::vector<Lepton::CompiledExpression> >& valueGradientExpressions,
const std::vector<std::string>& valueNames,
const std::vector<Lepton::CompiledExpression>& energyExpressions,
const std::vector<std::vector<Lepton::CompiledExpression> >& energyDerivExpressions,
const std::vector<std::vector<Lepton::CompiledExpression> >& energyGradientExpressions,
const std::vector<std::string>& parameterNames);
CompiledExpressionSet expressionSet;
std::vector<Lepton::CompiledExpression> valueExpressions;
std::vector<std::vector<Lepton::CompiledExpression> > valueDerivExpressions;
std::vector<std::vector<Lepton::CompiledExpression> > valueGradientExpressions;
std::vector<int> valueIndex;
std::vector<Lepton::CompiledExpression> energyExpressions;
std::vector<std::vector<Lepton::CompiledExpression> > energyDerivExpressions;
std::vector<std::vector<Lepton::CompiledExpression> > energyGradientExpressions;
std::vector<int> paramIndex;
std::vector<int> particleParamIndex;
std::vector<int> particleValueIndex;
int xindex, yindex, zindex, rindex;
int firstAtom, lastAtom;
// Workspace vectors
std::vector<float> value0, dVdR1, dVdR2, dVdX, dVdY, dVdZ;
std::vector<std::vector<float> > dEdV;
};
} // namespace OpenMM
#endif // OPENMM_CPU_CUSTOM_GB_FORCE_H__
......@@ -33,6 +33,7 @@
* -------------------------------------------------------------------------- */
#include "CpuBondForce.h"
#include "CpuCustomGBForce.h"
#include "CpuCustomManyParticleForce.h"
#include "CpuCustomNonbondedForce.h"
#include "CpuGBSAOBCForce.h"
......@@ -303,6 +304,53 @@ private:
CpuGBSAOBCForce obc;
};
/**
* This kernel is invoked by CustomGBForce to calculate the forces acting on the system.
*/
class CpuCalcCustomGBForceKernel : public CalcCustomGBForceKernel {
public:
CpuCalcCustomGBForceKernel(std::string name, const Platform& platform, CpuPlatform::PlatformData& data) :
CalcCustomGBForceKernel(name, platform), data(data) {
}
~CpuCalcCustomGBForceKernel();
/**
* Initialize the kernel.
*
* @param system the System this kernel will be applied to
* @param force the CustomGBForce this kernel will be used for
*/
void initialize(const System& system, const CustomGBForce& force);
/**
* Execute the kernel to calculate the forces and/or energy.
*
* @param context the context in which to execute this kernel
* @param includeForces true if forces should be calculated
* @param includeEnergy true if the energy should be calculated
* @return the potential energy due to the force
*/
double execute(ContextImpl& context, bool includeForces, bool includeEnergy);
/**
* Copy changed parameters over to a context.
*
* @param context the context to copy parameters to
* @param force the CustomGBForce to copy the parameters from
*/
void copyParametersToContext(ContextImpl& context, const CustomGBForce& force);
private:
CpuPlatform::PlatformData& data;
int numParticles;
bool isPeriodic;
RealOpenMM **particleParamArray;
RealOpenMM nonbondedCutoff;
CpuCustomGBForce* ixn;
std::vector<std::set<int> > exclusions;
std::vector<std::string> particleParameterNames, globalParameterNames, valueNames;
std::vector<OpenMM::CustomGBForce::ComputationType> valueTypes;
std::vector<OpenMM::CustomGBForce::ComputationType> energyTypes;
NonbondedMethod nonbondedMethod;
CpuNeighborList* neighborList;
};
/**
* This kernel is invoked by CustomManyParticleForce to calculate the forces acting on the system and the energy of the system.
*/
......
This diff is collapsed.
......@@ -182,9 +182,7 @@ void CpuCustomNonbondedForce::threadComputeForce(ThreadPool& threads, int thread
int blockIndex = gmx_atomic_fetch_add(reinterpret_cast<gmx_atomic_t*>(atomicCounter), 1);
if (blockIndex >= neighborList->getNumBlocks())
break;
int blockAtom[4];
for (int i = 0; i < 4; i++)
blockAtom[i] = neighborList->getSortedAtoms()[4*blockIndex+i];
const int* blockAtom = &neighborList->getSortedAtoms()[4*blockIndex];
const vector<int>& neighbors = neighborList->getBlockNeighbors(blockIndex);
const vector<char>& exclusions = neighborList->getBlockExclusions(blockIndex);
for (int i = 0; i < (int) neighbors.size(); i++) {
......
......@@ -53,6 +53,8 @@ KernelImpl* CpuKernelFactory::createKernelImpl(std::string name, const Platform&
return new CpuCalcCustomManyParticleForceKernel(name, platform, data);
if (name == CalcGBSAOBCForceKernel::Name())
return new CpuCalcGBSAOBCForceKernel(name, platform, data);
if (name == CalcCustomGBForceKernel::Name())
return new CpuCalcCustomGBForceKernel(name, platform, data);
if (name == IntegrateLangevinStepKernel::Name())
return new CpuIntegrateLangevinStepKernel(name, platform, data);
throw OpenMMException((std::string("Tried to create kernel with illegal kernel name '") + name + "'").c_str());
......
......@@ -835,6 +835,168 @@ void CpuCalcGBSAOBCForceKernel::copyParametersToContext(ContextImpl& context, co
obc.setParticleParameters(particleParams);
}
CpuCalcCustomGBForceKernel::~CpuCalcCustomGBForceKernel() {
if (particleParamArray != NULL) {
for (int i = 0; i < numParticles; i++)
delete[] particleParamArray[i];
delete[] particleParamArray;
}
if (neighborList != NULL)
delete neighborList;
if (ixn != NULL)
delete ixn;
}
void CpuCalcCustomGBForceKernel::initialize(const System& system, const CustomGBForce& force) {
if (force.getNumComputedValues() > 0) {
string name, expression;
CustomGBForce::ComputationType type;
force.getComputedValueParameters(0, name, expression, type);
if (type == CustomGBForce::SingleParticle)
throw OpenMMException("CpuPlatform requires that the first computed value for a CustomGBForce be of type ParticlePair or ParticlePairNoExclusions.");
for (int i = 1; i < force.getNumComputedValues(); i++) {
force.getComputedValueParameters(i, name, expression, type);
if (type != CustomGBForce::SingleParticle)
throw OpenMMException("CpuPlatform requires that a CustomGBForce only have one computed value of type ParticlePair or ParticlePairNoExclusions.");
}
}
// Record the exclusions.
numParticles = force.getNumParticles();
exclusions.resize(numParticles);
for (int i = 0; i < force.getNumExclusions(); i++) {
int particle1, particle2;
force.getExclusionParticles(i, particle1, particle2);
exclusions[particle1].insert(particle2);
exclusions[particle2].insert(particle1);
}
// Build the arrays.
int numPerParticleParameters = force.getNumPerParticleParameters();
particleParamArray = new double*[numParticles];
for (int i = 0; i < numParticles; i++)
particleParamArray[i] = new double[numPerParticleParameters];
for (int i = 0; i < numParticles; ++i) {
vector<double> parameters;
force.getParticleParameters(i, parameters);
for (int j = 0; j < numPerParticleParameters; j++)
particleParamArray[i][j] = static_cast<RealOpenMM>(parameters[j]);
}
for (int i = 0; i < numPerParticleParameters; i++)
particleParameterNames.push_back(force.getPerParticleParameterName(i));
for (int i = 0; i < force.getNumGlobalParameters(); i++)
globalParameterNames.push_back(force.getGlobalParameterName(i));
nonbondedMethod = CalcCustomGBForceKernel::NonbondedMethod(force.getNonbondedMethod());
nonbondedCutoff = (RealOpenMM) force.getCutoffDistance();
if (nonbondedMethod == NoCutoff)
neighborList = NULL;
else
neighborList = new CpuNeighborList(4);
// Create custom functions for the tabulated functions.
map<string, Lepton::CustomFunction*> functions;
for (int i = 0; i < force.getNumFunctions(); i++)
functions[force.getTabulatedFunctionName(i)] = createReferenceTabulatedFunction(force.getTabulatedFunction(i));
// Parse the expressions for computed values.
vector<vector<Lepton::CompiledExpression> > valueDerivExpressions(force.getNumComputedValues());
vector<vector<Lepton::CompiledExpression> > valueGradientExpressions(force.getNumComputedValues());
vector<Lepton::CompiledExpression> valueExpressions;
vector<Lepton::CompiledExpression> energyExpressions;
for (int i = 0; i < force.getNumComputedValues(); i++) {
string name, expression;
CustomGBForce::ComputationType type;
force.getComputedValueParameters(i, name, expression, type);
Lepton::ParsedExpression ex = Lepton::Parser::parse(expression, functions).optimize();
valueExpressions.push_back(ex.createCompiledExpression());
valueTypes.push_back(type);
valueNames.push_back(name);
if (i == 0)
valueDerivExpressions[i].push_back(ex.differentiate("r").createCompiledExpression());
else {
valueGradientExpressions[i].push_back(ex.differentiate("x").createCompiledExpression());
valueGradientExpressions[i].push_back(ex.differentiate("y").createCompiledExpression());
valueGradientExpressions[i].push_back(ex.differentiate("z").createCompiledExpression());
for (int j = 0; j < i; j++)
valueDerivExpressions[i].push_back(ex.differentiate(valueNames[j]).createCompiledExpression());
}
}
// Parse the expressions for energy terms.
vector<vector<Lepton::CompiledExpression> > energyDerivExpressions(force.getNumEnergyTerms());
vector<vector<Lepton::CompiledExpression> > energyGradientExpressions(force.getNumEnergyTerms());
for (int i = 0; i < force.getNumEnergyTerms(); i++) {
string expression;
CustomGBForce::ComputationType type;
force.getEnergyTermParameters(i, expression, type);
Lepton::ParsedExpression ex = Lepton::Parser::parse(expression, functions).optimize();
energyExpressions.push_back(ex.createCompiledExpression());
energyTypes.push_back(type);
if (type != CustomGBForce::SingleParticle)
energyDerivExpressions[i].push_back(ex.differentiate("r").createCompiledExpression());
for (int j = 0; j < force.getNumComputedValues(); j++) {
if (type == CustomGBForce::SingleParticle) {
energyDerivExpressions[i].push_back(ex.differentiate(valueNames[j]).createCompiledExpression());
energyGradientExpressions[i].push_back(ex.differentiate("x").createCompiledExpression());
energyGradientExpressions[i].push_back(ex.differentiate("y").createCompiledExpression());
energyGradientExpressions[i].push_back(ex.differentiate("z").createCompiledExpression());
}
else {
energyDerivExpressions[i].push_back(ex.differentiate(valueNames[j]+"1").createCompiledExpression());
energyDerivExpressions[i].push_back(ex.differentiate(valueNames[j]+"2").createCompiledExpression());
}
}
}
// Delete the custom functions.
for (map<string, Lepton::CustomFunction*>::iterator iter = functions.begin(); iter != functions.end(); iter++)
delete iter->second;
ixn = new CpuCustomGBForce(numParticles, exclusions, valueExpressions, valueDerivExpressions, valueGradientExpressions, valueNames, valueTypes, energyExpressions,
energyDerivExpressions, energyGradientExpressions, energyTypes, particleParameterNames, data.threads);
data.isPeriodic = (force.getNonbondedMethod() == CustomGBForce::CutoffPeriodic);
}
double CpuCalcCustomGBForceKernel::execute(ContextImpl& context, bool includeForces, bool includeEnergy) {
vector<RealVec>& forceData = extractForces(context);
RealOpenMM energy = 0;
RealVec& box = extractBoxSize(context);
float floatBoxSize[3] = {(float) box[0], (float) box[1], (float) box[2]};
if (data.isPeriodic)
ixn->setPeriodic(extractBoxSize(context));
if (nonbondedMethod != NoCutoff) {
vector<set<int> > noExclusions(numParticles);
neighborList->computeNeighborList(numParticles, data.posq, exclusions, floatBoxSize, data.isPeriodic, nonbondedCutoff, data.threads);
ixn->setUseCutoff(nonbondedCutoff, *neighborList);
}
map<string, double> globalParameters;
for (int i = 0; i < (int) globalParameterNames.size(); i++)
globalParameters[globalParameterNames[i]] = context.getParameter(globalParameterNames[i]);
ixn->calculateIxn(numParticles, &data.posq[0], particleParamArray, globalParameters, data.threadForce, includeForces, includeEnergy, energy);
return energy;
}
void CpuCalcCustomGBForceKernel::copyParametersToContext(ContextImpl& context, const CustomGBForce& force) {
if (numParticles != force.getNumParticles())
throw OpenMMException("updateParametersInContext: The number of particles has changed");
// Record the values.
int numParameters = force.getNumPerParticleParameters();
vector<double> params;
for (int i = 0; i < numParticles; ++i) {
vector<double> parameters;
force.getParticleParameters(i, parameters);
for (int j = 0; j < numParameters; j++)
particleParamArray[i][j] = static_cast<RealOpenMM>(parameters[j]);
}
}
CpuCalcCustomManyParticleForceKernel::~CpuCalcCustomManyParticleForceKernel() {
if (particleParamArray != NULL) {
for (int i = 0; i < numParticles; i++)
......
......@@ -48,13 +48,11 @@ CpuNonbondedForceVec4::CpuNonbondedForceVec4() {
void CpuNonbondedForceVec4::calculateBlockIxn(int blockIndex, float* forces, double* totalEnergy, const fvec4& boxSize, const fvec4& invBoxSize) {
// Load the positions and parameters of the atoms in the block.
int blockAtom[4];
const int* blockAtom = &neighborList->getSortedAtoms()[4*blockIndex];
fvec4 blockAtomPosq[4];
fvec4 blockAtomForceX(0.0f), blockAtomForceY(0.0f), blockAtomForceZ(0.0f);
for (int i = 0; i < 4; i++) {
blockAtom[i] = neighborList->getSortedAtoms()[4*blockIndex+i];
for (int i = 0; i < 4; i++)
blockAtomPosq[i] = fvec4(posq+4*blockAtom[i]);
}
fvec4 blockAtomX = fvec4(blockAtomPosq[0][0], blockAtomPosq[1][0], blockAtomPosq[2][0], blockAtomPosq[3][0]);
fvec4 blockAtomY = fvec4(blockAtomPosq[0][1], blockAtomPosq[1][1], blockAtomPosq[2][1], blockAtomPosq[3][1]);
fvec4 blockAtomZ = fvec4(blockAtomPosq[0][2], blockAtomPosq[1][2], blockAtomPosq[2][2], blockAtomPosq[3][2]);
......@@ -159,13 +157,11 @@ void CpuNonbondedForceVec4::calculateBlockIxn(int blockIndex, float* forces, dou
void CpuNonbondedForceVec4::calculateBlockEwaldIxn(int blockIndex, float* forces, double* totalEnergy, const fvec4& boxSize, const fvec4& invBoxSize) {
// Load the positions and parameters of the atoms in the block.
int blockAtom[4];
const int* blockAtom = &neighborList->getSortedAtoms()[4*blockIndex];
fvec4 blockAtomPosq[4];
fvec4 blockAtomForceX(0.0f), blockAtomForceY(0.0f), blockAtomForceZ(0.0f);
for (int i = 0; i < 4; i++) {
blockAtom[i] = neighborList->getSortedAtoms()[4*blockIndex+i];
for (int i = 0; i < 4; i++)
blockAtomPosq[i] = fvec4(posq+4*blockAtom[i]);
}
fvec4 blockAtomX = fvec4(blockAtomPosq[0][0], blockAtomPosq[1][0], blockAtomPosq[2][0], blockAtomPosq[3][0]);
fvec4 blockAtomY = fvec4(blockAtomPosq[0][1], blockAtomPosq[1][1], blockAtomPosq[2][1], blockAtomPosq[3][1]);
fvec4 blockAtomZ = fvec4(blockAtomPosq[0][2], blockAtomPosq[1][2], blockAtomPosq[2][2], blockAtomPosq[3][2]);
......
......@@ -74,14 +74,12 @@ CpuNonbondedForceVec8::CpuNonbondedForceVec8() {
void CpuNonbondedForceVec8::calculateBlockIxn(int blockIndex, float* forces, double* totalEnergy, const fvec4& boxSize, const fvec4& invBoxSize) {
// Load the positions and parameters of the atoms in the block.
int blockAtom[8];
const int* blockAtom = &neighborList->getSortedAtoms()[8*blockIndex];
fvec4 blockAtomPosq[8];
fvec8 blockAtomForceX(0.0f), blockAtomForceY(0.0f), blockAtomForceZ(0.0f);
fvec8 blockAtomX, blockAtomY, blockAtomZ, blockAtomCharge;
for (int i = 0; i < 8; i++) {
blockAtom[i] = neighborList->getSortedAtoms()[8*blockIndex+i];
for (int i = 0; i < 8; i++)
blockAtomPosq[i] = fvec4(posq+4*blockAtom[i]);
}
transpose(blockAtomPosq[0], blockAtomPosq[1], blockAtomPosq[2], blockAtomPosq[3], blockAtomPosq[4], blockAtomPosq[5], blockAtomPosq[6], blockAtomPosq[7], blockAtomX, blockAtomY, blockAtomZ, blockAtomCharge);
blockAtomCharge *= ONE_4PI_EPS0;
fvec8 blockAtomSigma(atomParameters[blockAtom[0]].first, atomParameters[blockAtom[1]].first, atomParameters[blockAtom[2]].first, atomParameters[blockAtom[3]].first, atomParameters[blockAtom[4]].first, atomParameters[blockAtom[5]].first, atomParameters[blockAtom[6]].first, atomParameters[blockAtom[7]].first);
......@@ -184,14 +182,12 @@ void CpuNonbondedForceVec8::calculateBlockIxn(int blockIndex, float* forces, dou
void CpuNonbondedForceVec8::calculateBlockEwaldIxn(int blockIndex, float* forces, double* totalEnergy, const fvec4& boxSize, const fvec4& invBoxSize) {
// Load the positions and parameters of the atoms in the block.
int blockAtom[8];
const int* blockAtom = &neighborList->getSortedAtoms()[8*blockIndex];
fvec4 blockAtomPosq[8];
fvec8 blockAtomForceX(0.0f), blockAtomForceY(0.0f), blockAtomForceZ(0.0f);
fvec8 blockAtomX, blockAtomY, blockAtomZ, blockAtomCharge;
for (int i = 0; i < 8; i++) {
blockAtom[i] = neighborList->getSortedAtoms()[8*blockIndex+i];
for (int i = 0; i < 8; i++)
blockAtomPosq[i] = fvec4(posq+4*blockAtom[i]);
}
transpose(blockAtomPosq[0], blockAtomPosq[1], blockAtomPosq[2], blockAtomPosq[3], blockAtomPosq[4], blockAtomPosq[5], blockAtomPosq[6], blockAtomPosq[7], blockAtomX, blockAtomY, blockAtomZ, blockAtomCharge);
blockAtomCharge *= ONE_4PI_EPS0;
fvec8 blockAtomSigma(atomParameters[blockAtom[0]].first, atomParameters[blockAtom[1]].first, atomParameters[blockAtom[2]].first, atomParameters[blockAtom[3]].first, atomParameters[blockAtom[4]].first, atomParameters[blockAtom[5]].first, atomParameters[blockAtom[6]].first, atomParameters[blockAtom[7]].first);
......
......@@ -67,6 +67,7 @@ CpuPlatform::CpuPlatform() {
registerKernelFactory(CalcCustomNonbondedForceKernel::Name(), factory);
registerKernelFactory(CalcCustomManyParticleForceKernel::Name(), factory);
registerKernelFactory(CalcGBSAOBCForceKernel::Name(), factory);
registerKernelFactory(CalcCustomGBForceKernel::Name(), factory);
registerKernelFactory(IntegrateLangevinStepKernel::Name(), factory);
platformProperties.push_back(CpuThreads());
int threads = getNumProcessors();
......
This diff is collapsed.
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