Skip to content
GitLab
Menu
Projects
Groups
Snippets
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Menu
Open sidebar
tsoc
openmm
Commits
6a4ac837
"...ssh:/git@developer.sourcefind.cn:2222/tsoc/openmm.git" did not exist on "b245e77212179e9cb0060f7f4cff60970519fccf"
Commit
6a4ac837
authored
Oct 07, 2014
by
peastman
Browse files
Parallelized CpuCustomGBForce
parent
bb70341a
Changes
3
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
380 additions
and
231 deletions
+380
-231
platforms/cpu/include/CpuCustomGBForce.h
platforms/cpu/include/CpuCustomGBForce.h
+86
-71
platforms/cpu/src/CpuCustomGBForce.cpp
platforms/cpu/src/CpuCustomGBForce.cpp
+291
-157
platforms/cpu/src/CpuKernels.cpp
platforms/cpu/src/CpuKernels.cpp
+3
-3
No files found.
platforms/cpu/include/CpuCustomGBForce.h
View file @
6a4ac837
...
@@ -29,6 +29,7 @@
...
@@ -29,6 +29,7 @@
#include "CpuNeighborList.h"
#include "CpuNeighborList.h"
#include "lepton/CompiledExpression.h"
#include "lepton/CompiledExpression.h"
#include "openmm/CustomGBForce.h"
#include "openmm/CustomGBForce.h"
#include "openmm/internal/ThreadPool.h"
#include "openmm/internal/vectorize.h"
#include "openmm/internal/vectorize.h"
#include <map>
#include <map>
#include <set>
#include <set>
...
@@ -38,59 +39,63 @@ namespace OpenMM {
...
@@ -38,59 +39,63 @@ namespace OpenMM {
class
CpuCustomGBForce
{
class
CpuCustomGBForce
{
private:
private:
class
ComputeForceTask
;
class
ThreadData
;
bool
cutoff
;
bool
cutoff
;
bool
periodic
;
bool
periodic
;
const
CpuNeighborList
*
neighborList
;
const
CpuNeighborList
*
neighborList
;
float
periodicBoxSize
[
3
];
float
periodicBoxSize
[
3
];
float
cutoffDistance
;
float
cutoffDistance
;
CompiledExpressionSet
expressionSet
;
const
std
::
vector
<
std
::
set
<
int
>
>
exclusions
;
std
::
vector
<
Lepton
::
CompiledExpression
>
valueExpressions
;
std
::
vector
<
std
::
vector
<
Lepton
::
CompiledExpression
>
>
valueDerivExpressions
;
std
::
vector
<
std
::
vector
<
Lepton
::
CompiledExpression
>
>
valueGradientExpressions
;
std
::
vector
<
std
::
string
>
valueNames
;
std
::
vector
<
std
::
string
>
valueNames
;
std
::
vector
<
int
>
valueIndex
;
std
::
vector
<
CustomGBForce
::
ComputationType
>
valueTypes
;
std
::
vector
<
CustomGBForce
::
ComputationType
>
valueTypes
;
std
::
vector
<
Lepton
::
CompiledExpression
>
energyExpressions
;
std
::
vector
<
std
::
vector
<
Lepton
::
CompiledExpression
>
>
energyDerivExpressions
;
std
::
vector
<
std
::
vector
<
Lepton
::
CompiledExpression
>
>
energyGradientExpressions
;
std
::
vector
<
std
::
string
>
paramNames
;
std
::
vector
<
std
::
string
>
paramNames
;
std
::
vector
<
int
>
paramIndex
;
std
::
vector
<
CustomGBForce
::
ComputationType
>
energyTypes
;
std
::
vector
<
CustomGBForce
::
ComputationType
>
energyTypes
;
std
::
vector
<
int
>
particleParamIndex
;
ThreadPool
&
threads
;
std
::
vector
<
int
>
particleValueIndex
;
std
::
vector
<
ThreadData
*>
threadData
;
int
xindex
,
yindex
,
zindex
,
rindex
;
std
::
vector
<
double
>
threadEnergy
;
// Workspace vectors
// Workspace vectors
std
::
vector
<
std
::
vector
<
float
>
>
values
,
dEdV
;
std
::
vector
<
std
::
vector
<
float
>
>
values
,
dEdV
;
std
::
vector
<
float
>
dVdR1
,
dVdR2
,
dVdX
,
dVdY
,
dVdZ
;
// 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 of type SingleParticle
* Calculate a computed value of type SingleParticle
*
*
* @param index the index of the value to compute
* @param index the index of the value to compute
* @param data workspace for the current thread
* @param numAtoms number of atoms
* @param numAtoms number of atoms
* @param posq atom coordinates
* @param posq atom coordinates
* @param values the vector to store computed values into
* @param atomParameters atomParameters[atomIndex][paramterIndex]
* @param atomParameters atomParameters[atomIndex][paramterIndex]
*/
*/
void
calculateSingleParticleValue
(
int
index
,
int
numAtoms
,
float
*
posq
,
std
::
vector
<
std
::
vector
<
float
>
>&
values
,
void
calculateSingleParticleValue
(
int
index
,
ThreadData
&
data
,
int
numAtoms
,
float
*
posq
,
RealOpenMM
**
atomParameters
);
RealOpenMM
**
atomParameters
);
/**
/**
* Calculate a computed value that is based on particle pairs
* Calculate a computed value that is based on particle pairs
*
*
* @param index the index of the value to compute
* @param index the index of the value to compute
* @param data workspace for the current thread
* @param numAtoms number of atoms
* @param numAtoms number of atoms
* @param posq atom coordinates
* @param posq atom coordinates
* @param atomParameters atomParameters[atomIndex][paramterIndex]
* @param atomParameters atomParameters[atomIndex][paramterIndex]
* @param values the vector to store computed values into
* @param exclusions exclusions[i] is the set of excluded indices for atom i
* @param useExclusions specifies whether to use exclusions
* @param useExclusions specifies whether to use exclusions
*/
*/
void
calculateParticlePairValue
(
int
index
,
int
numAtoms
,
float
*
posq
,
RealOpenMM
**
atomParameters
,
void
calculateParticlePairValue
(
int
index
,
ThreadData
&
data
,
int
numAtoms
,
float
*
posq
,
RealOpenMM
**
atomParameters
,
std
::
vector
<
std
::
vector
<
float
>
>&
values
,
bool
useExclusions
,
const
fvec4
&
boxSize
,
const
fvec4
&
invBoxSize
);
const
std
::
vector
<
std
::
set
<
int
>
>&
exclusions
,
bool
useExclusions
,
const
fvec4
&
boxSize
,
const
fvec4
&
invBoxSize
);
/**
/**
* Evaluate a single atom pair as part of calculating a computed value
* Evaluate a single atom pair as part of calculating a computed value
...
@@ -98,51 +103,43 @@ private:
...
@@ -98,51 +103,43 @@ private:
* @param index the index of the value to compute
* @param index the index of the value to compute
* @param atom1 the index of the first atom in the pair
* @param atom1 the index of the first atom in the pair
* @param atom2 the index of the second 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 posq atom coordinates
* @param atomParameters atomParameters[atomIndex][paramterIndex]
* @param atomParameters atomParameters[atomIndex][paramterIndex]
* @param values the vector to store computed values into
*/
*/
void
calculateOnePairValue
(
int
index
,
int
atom1
,
int
atom2
,
float
*
posq
,
RealOpenMM
**
atomParameters
,
void
calculateOnePairValue
(
int
index
,
int
atom1
,
int
atom2
,
ThreadData
&
data
,
float
*
posq
,
RealOpenMM
**
atomParameters
,
std
::
vector
<
std
::
vector
<
float
>
>
&
value
s
,
const
fvec4
&
boxSize
,
const
fvec4
&
invBoxSize
);
std
::
vector
<
float
>&
value
Array
,
const
fvec4
&
boxSize
,
const
fvec4
&
invBoxSize
);
/**
/**
* Calculate an energy term of type SingleParticle
* Calculate an energy term of type SingleParticle
*
*
* @param index the index of the value to compute
* @param index the index of the value to compute
* @param data workspace for the current thread
* @param numAtoms number of atoms
* @param numAtoms number of atoms
* @param posq atom coordinates
* @param posq atom coordinates
* @param values the vector containing computed values
* @param atomParameters atomParameters[atomIndex][paramterIndex]
* @param atomParameters atomParameters[atomIndex][paramterIndex]
* @param forces forces on atoms are added to this
* @param forces forces on atoms are added to this
* @param totalEnergy the energy contribution is added to this
* @param totalEnergy the energy contribution is added to this
* @param dEdV the derivative of energy with respect to computed values is stored in this
*/
*/
void
calculateSingleParticleEnergyTerm
(
int
index
,
int
numAtoms
,
float
*
posq
,
const
std
::
vector
<
std
::
vector
<
float
>
>&
values
,
void
calculateSingleParticleEnergyTerm
(
int
index
,
ThreadData
&
data
,
int
numAtoms
,
float
*
posq
,
RealOpenMM
**
atomParameters
,
float
*
forces
,
double
&
totalEnergy
);
RealOpenMM
**
atomParameters
,
float
*
forces
,
double
*
totalEnergy
,
std
::
vector
<
std
::
vector
<
float
>
>&
dEdV
);
/**
/**
* Calculate an energy term that is based on particle pairs
* Calculate an energy term that is based on particle pairs
*
*
* @param index the index of the term to compute
* @param index the index of the term to compute
* @param data workspace for the current thread
* @param numAtoms number of atoms
* @param numAtoms number of atoms
* @param posq atom coordinates
* @param posq atom coordinates
* @param atomParameters atomParameters[atomIndex][paramterIndex]
* @param atomParameters atomParameters[atomIndex][paramterIndex]
* @param values the vector containing computed values
* @param exclusions exclusions[i] is the set of excluded indices for atom i
* @param useExclusions specifies whether to use exclusions
* @param useExclusions specifies whether to use exclusions
* @param forces forces on atoms are added to this
* @param forces forces on atoms are added to this
* @param totalEnergy the energy contribution is added to this
* @param totalEnergy the energy contribution is added to this
* @param dEdV the derivative of energy with respect to computed values is stored in this
*/
*/
void
calculateParticlePairEnergyTerm
(
int
index
,
int
numAtoms
,
float
*
posq
,
RealOpenMM
**
atomParameters
,
void
calculateParticlePairEnergyTerm
(
int
index
,
ThreadData
&
data
,
int
numAtoms
,
float
*
posq
,
RealOpenMM
**
atomParameters
,
const
std
::
vector
<
std
::
vector
<
float
>
>&
values
,
bool
useExclusions
,
float
*
forces
,
double
&
totalEnergy
,
const
fvec4
&
boxSize
,
const
fvec4
&
invBoxSize
);
const
std
::
vector
<
std
::
set
<
int
>
>&
exclusions
,
bool
useExclusions
,
float
*
forces
,
double
*
totalEnergy
,
std
::
vector
<
std
::
vector
<
float
>
>&
dEdV
,
const
fvec4
&
boxSize
,
const
fvec4
&
invBoxSize
);
/**
/**
* Evaluate a single atom pair as part of calculating an energy term
* Evaluate a single atom pair as part of calculating an energy term
...
@@ -150,54 +147,43 @@ private:
...
@@ -150,54 +147,43 @@ private:
* @param index the index of the term to compute
* @param index the index of the term to compute
* @param atom1 the index of the first atom in the pair
* @param atom1 the index of the first atom in the pair
* @param atom2 the index of the second 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 posq atom coordinates
* @param atomParameters atomParameters[atomIndex][paramterIndex]
* @param atomParameters atomParameters[atomIndex][paramterIndex]
* @param values the vector containing computed values
* @param forces forces on atoms are added to this
* @param forces forces on atoms are added to this
* @param totalEnergy the energy contribution is added to this
* @param totalEnergy the energy contribution is added to this
* @param dEdV the derivative of energy with respect to computed values is stored in this
*/
*/
void
calculateOnePairEnergyTerm
(
int
index
,
int
atom1
,
int
atom2
,
float
*
posq
,
RealOpenMM
**
atomParameters
,
void
calculateOnePairEnergyTerm
(
int
index
,
int
atom1
,
int
atom2
,
ThreadData
&
data
,
float
*
posq
,
RealOpenMM
**
atomParameters
,
const
std
::
vector
<
std
::
vector
<
float
>
>&
values
,
float
*
forces
,
double
&
totalEnergy
,
const
fvec4
&
boxSize
,
const
fvec4
&
invBoxSize
);
float
*
forces
,
double
*
totalEnergy
,
std
::
vector
<
std
::
vector
<
float
>
>&
dEdV
,
const
fvec4
&
boxSize
,
const
fvec4
&
invBoxSize
);
/**
/**
* Apply the chain rule to compute forces on atoms
* Apply the chain rule to compute forces on atoms
*
*
* @param data workspace for the current thread
* @param numAtoms number of atoms
* @param numAtoms number of atoms
* @param posq atom coordinates
* @param posq atom coordinates
* @param atomParameters atomParameters[atomIndex][paramterIndex]
* @param atomParameters atomParameters[atomIndex][paramterIndex]
* @param values the vector containing computed values
* @param exclusions exclusions[i] is the set of excluded indices for atom i
* @param forces forces on atoms are added to this
* @param forces forces on atoms are added to this
* @param dEdV the derivative of energy with respect to computed values is stored in this
*/
*/
void
calculateChainRuleForces
(
int
numAtoms
,
float
*
posq
,
RealOpenMM
**
atomParameters
,
void
calculateChainRuleForces
(
ThreadData
&
data
,
int
numAtoms
,
float
*
posq
,
RealOpenMM
**
atomParameters
,
const
std
::
vector
<
std
::
vector
<
float
>
>&
values
,
float
*
forces
,
const
fvec4
&
boxSize
,
const
fvec4
&
invBoxSize
);
const
std
::
vector
<
std
::
set
<
int
>
>&
exclusions
,
float
*
forces
,
std
::
vector
<
std
::
vector
<
float
>
>&
dEdV
,
const
fvec4
&
boxSize
,
const
fvec4
&
invBoxSize
);
/**
/**
* Evaluate a single atom pair as part of applying the chain rule
* Evaluate a single atom pair as part of applying the chain rule
*
*
* @param atom1 the index of the first atom in the pair
* @param atom1 the index of the first atom in the pair
* @param atom2 the index of the second 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 posq atom coordinates
* @param atomParameters atomParameters[atomIndex][paramterIndex]
* @param atomParameters atomParameters[atomIndex][paramterIndex]
* @param values the vector containing computed values
* @param forces forces on atoms are added to this
* @param forces forces on atoms are added to this
* @param dEdV the derivative of energy with respect to computed values is stored in this
* @param isExcluded specifies whether this is an excluded pair
* @param isExcluded specifies whether this is an excluded pair
*/
*/
void
calculateOnePairChainRule
(
int
atom1
,
int
atom2
,
float
*
posq
,
RealOpenMM
**
atomParameters
,
void
calculateOnePairChainRule
(
int
atom1
,
int
atom2
,
ThreadData
&
data
,
float
*
posq
,
RealOpenMM
**
atomParameters
,
const
std
::
vector
<
std
::
vector
<
float
>
>&
values
,
float
*
forces
,
bool
isExcluded
,
const
fvec4
&
boxSize
,
const
fvec4
&
invBoxSize
);
float
*
forces
,
std
::
vector
<
std
::
vector
<
float
>
>&
dEdV
,
bool
isExcluded
,
const
fvec4
&
boxSize
,
const
fvec4
&
invBoxSize
);
/**
/**
* Compute the displacement and squared distance between two points, optionally using
* Compute the displacement and squared distance between two points, optionally using
...
@@ -211,16 +197,17 @@ public:
...
@@ -211,16 +197,17 @@ public:
* Construct a new CpuCustomGBForce.
* Construct a new CpuCustomGBForce.
*/
*/
CpuCustomGBForce
(
int
numAtoms
,
const
std
::
vector
<
Lepton
::
CompiledExpression
>&
valueExpressions
,
CpuCustomGBForce
(
int
numAtoms
,
const
std
::
vector
<
std
::
set
<
int
>
>&
exclusions
,
const
std
::
vector
<
std
::
vector
<
Lepton
::
CompiledExpression
>
>&
valueDerivExpressions
,
const
std
::
vector
<
Lepton
::
CompiledExpression
>&
valueExpressions
,
const
std
::
vector
<
std
::
vector
<
Lepton
::
CompiledExpression
>
>&
valueGradientExpressions
,
const
std
::
vector
<
std
::
vector
<
Lepton
::
CompiledExpression
>
>&
valueDerivExpressions
,
const
std
::
vector
<
std
::
string
>&
valueNames
,
const
std
::
vector
<
std
::
vector
<
Lepton
::
CompiledExpression
>
>&
valueGradientExpressions
,
const
std
::
vector
<
CustomGBForce
::
ComputationType
>&
valueTypes
,
const
std
::
vector
<
std
::
string
>&
valueNames
,
const
std
::
vector
<
Lepton
::
CompiledExpression
>&
energyExpressions
,
const
std
::
vector
<
CustomGBForce
::
ComputationType
>&
valueTypes
,
const
std
::
vector
<
std
::
vector
<
Lepton
::
CompiledExpression
>
>&
energyDerivExpressions
,
const
std
::
vector
<
Lepton
::
CompiledExpression
>&
energyExpressions
,
const
std
::
vector
<
std
::
vector
<
Lepton
::
CompiledExpression
>
>&
energyGradientExpressions
,
const
std
::
vector
<
std
::
vector
<
Lepton
::
CompiledExpression
>
>&
energyDerivExpressions
,
const
std
::
vector
<
CustomGBForce
::
ComputationType
>&
energyTypes
,
const
std
::
vector
<
std
::
vector
<
Lepton
::
CompiledExpression
>
>&
energyGradientExpressions
,
const
std
::
vector
<
std
::
string
>&
parameterNames
);
const
std
::
vector
<
CustomGBForce
::
ComputationType
>&
energyTypes
,
const
std
::
vector
<
std
::
string
>&
parameterNames
,
ThreadPool
&
threads
);
~
CpuCustomGBForce
();
~
CpuCustomGBForce
();
...
@@ -249,14 +236,42 @@ public:
...
@@ -249,14 +236,42 @@ public:
* @param numberOfAtoms number of atoms
* @param numberOfAtoms number of atoms
* @param posq atom coordinates
* @param posq atom coordinates
* @param atomParameters atomParameters[atomIndex][paramterIndex]
* @param atomParameters atomParameters[atomIndex][paramterIndex]
* @param exclusions exclusions[i] is the set of excluded indices for atom i
* @param globalParameters the values of global parameters
* @param globalParameters the values of global parameters
* @param forces force array (forces added)
* @param forces force array (forces added)
* @param totalEnergy total energy
* @param totalEnergy total energy
*/
*/
void
calculateIxn
(
int
numberOfAtoms
,
float
*
posq
,
RealOpenMM
**
atomParameters
,
const
std
::
vector
<
std
::
set
<
int
>
>&
exclusions
,
void
calculateIxn
(
int
numberOfAtoms
,
float
*
posq
,
RealOpenMM
**
atomParameters
,
std
::
map
<
std
::
string
,
double
>&
globalParameters
,
float
*
forces
,
double
*
totalEnergy
);
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
}
// namespace OpenMM
...
...
platforms/cpu/src/CpuCustomGBForce.cpp
View file @
6a4ac837
...
@@ -30,23 +30,34 @@
...
@@ -30,23 +30,34 @@
#include "SimTKOpenMMUtilities.h"
#include "SimTKOpenMMUtilities.h"
#include "ReferenceForce.h"
#include "ReferenceForce.h"
#include "CpuCustomGBForce.h"
#include "CpuCustomGBForce.h"
#include "gmx_atomic.h"
using
namespace
OpenMM
;
using
namespace
OpenMM
;
using
namespace
std
;
using
namespace
std
;
CpuCustomGBForce
::
CpuCustomGBForce
(
int
numAtoms
,
const
vector
<
Lepton
::
CompiledExpression
>&
valueExpressions
,
class
CpuCustomGBForce
::
ComputeForceTask
:
public
ThreadPool
::
Task
{
const
vector
<
vector
<
Lepton
::
CompiledExpression
>
>&
valueDerivExpressions
,
public:
const
vector
<
vector
<
Lepton
::
CompiledExpression
>
>&
valueGradientExpressions
,
ComputeForceTask
(
CpuCustomGBForce
&
owner
)
:
owner
(
owner
)
{
const
vector
<
string
>&
valueNames
,
}
const
vector
<
CustomGBForce
::
ComputationType
>&
valueTypes
,
void
execute
(
ThreadPool
&
threads
,
int
threadIndex
)
{
const
vector
<
Lepton
::
CompiledExpression
>&
energyExpressions
,
owner
.
threadComputeForce
(
threads
,
threadIndex
);
const
vector
<
vector
<
Lepton
::
CompiledExpression
>
>&
energyDerivExpressions
,
}
const
vector
<
vector
<
Lepton
::
CompiledExpression
>
>&
energyGradientExpressions
,
CpuCustomGBForce
&
owner
;
const
vector
<
CustomGBForce
::
ComputationType
>&
energyTypes
,
};
const
vector
<
string
>&
parameterNames
)
:
cutoff
(
false
),
periodic
(
false
),
valueExpressions
(
valueExpressions
),
valueDerivExpressions
(
valueDerivExpressions
),
valueGradientExpressions
(
valueGradientExpressions
),
CpuCustomGBForce
::
ThreadData
::
ThreadData
(
int
numAtoms
,
int
numThreads
,
int
threadIndex
,
valueNames
(
valueNames
),
valueTypes
(
valueTypes
),
energyExpressions
(
energyExpressions
),
energyDerivExpressions
(
energyDerivExpressions
),
energyGradientExpressions
(
energyGradientExpressions
),
const
vector
<
Lepton
::
CompiledExpression
>&
valueExpressions
,
energyTypes
(
energyTypes
),
paramNames
(
parameterNames
)
{
const
vector
<
vector
<
Lepton
::
CompiledExpression
>
>&
valueDerivExpressions
,
const
vector
<
vector
<
Lepton
::
CompiledExpression
>
>&
valueGradientExpressions
,
const
vector
<
string
>&
valueNames
,
const
vector
<
Lepton
::
CompiledExpression
>&
energyExpressions
,
const
vector
<
vector
<
Lepton
::
CompiledExpression
>
>&
energyDerivExpressions
,
const
vector
<
vector
<
Lepton
::
CompiledExpression
>
>&
energyGradientExpressions
,
const
vector
<
string
>&
parameterNames
)
:
valueExpressions
(
valueExpressions
),
valueDerivExpressions
(
valueDerivExpressions
),
valueGradientExpressions
(
valueGradientExpressions
),
energyExpressions
(
energyExpressions
),
energyDerivExpressions
(
energyDerivExpressions
),
energyGradientExpressions
(
energyGradientExpressions
)
{
firstAtom
=
(
threadIndex
*
(
long
long
)
numAtoms
)
/
numThreads
;
lastAtom
=
((
threadIndex
+
1
)
*
(
long
long
)
numAtoms
)
/
numThreads
;
for
(
int
i
=
0
;
i
<
(
int
)
valueExpressions
.
size
();
i
++
)
for
(
int
i
=
0
;
i
<
(
int
)
valueExpressions
.
size
();
i
++
)
expressionSet
.
registerExpression
(
this
->
valueExpressions
[
i
]);
expressionSet
.
registerExpression
(
this
->
valueExpressions
[
i
]);
for
(
int
i
=
0
;
i
<
(
int
)
valueDerivExpressions
.
size
();
i
++
)
for
(
int
i
=
0
;
i
<
(
int
)
valueDerivExpressions
.
size
();
i
++
)
...
@@ -67,11 +78,11 @@ CpuCustomGBForce::CpuCustomGBForce(int numAtoms, const vector<Lepton::CompiledEx
...
@@ -67,11 +78,11 @@ CpuCustomGBForce::CpuCustomGBForce(int numAtoms, const vector<Lepton::CompiledEx
yindex
=
expressionSet
.
getVariableIndex
(
"y"
);
yindex
=
expressionSet
.
getVariableIndex
(
"y"
);
zindex
=
expressionSet
.
getVariableIndex
(
"z"
);
zindex
=
expressionSet
.
getVariableIndex
(
"z"
);
rindex
=
expressionSet
.
getVariableIndex
(
"r"
);
rindex
=
expressionSet
.
getVariableIndex
(
"r"
);
for
(
int
i
=
0
;
i
<
(
int
)
paramNames
.
size
();
i
++
)
{
for
(
int
i
=
0
;
i
<
(
int
)
param
eter
Names
.
size
();
i
++
)
{
paramIndex
.
push_back
(
expressionSet
.
getVariableIndex
(
paramNames
[
i
]));
paramIndex
.
push_back
(
expressionSet
.
getVariableIndex
(
param
eter
Names
[
i
]));
for
(
int
j
=
1
;
j
<
3
;
j
++
)
{
for
(
int
j
=
1
;
j
<
3
;
j
++
)
{
stringstream
name
;
stringstream
name
;
name
<<
paramNames
[
i
]
<<
j
;
name
<<
param
eter
Names
[
i
]
<<
j
;
particleParamIndex
.
push_back
(
expressionSet
.
getVariableIndex
(
name
.
str
()));
particleParamIndex
.
push_back
(
expressionSet
.
getVariableIndex
(
name
.
str
()));
}
}
}
}
...
@@ -83,12 +94,10 @@ CpuCustomGBForce::CpuCustomGBForce(int numAtoms, const vector<Lepton::CompiledEx
...
@@ -83,12 +94,10 @@ CpuCustomGBForce::CpuCustomGBForce(int numAtoms, const vector<Lepton::CompiledEx
particleValueIndex
.
push_back
(
expressionSet
.
getVariableIndex
(
name
.
str
()));
particleValueIndex
.
push_back
(
expressionSet
.
getVariableIndex
(
name
.
str
()));
}
}
}
}
values
.
resize
(
valueTypes
.
size
());
value0
.
resize
(
numAtoms
);
dEdV
.
resize
(
valueTypes
.
size
());
dEdV
.
resize
(
valueNames
.
size
());
for
(
int
i
=
0
;
i
<
(
int
)
values
.
size
();
i
++
)
{
for
(
int
i
=
0
;
i
<
(
int
)
dEdV
.
size
();
i
++
)
values
[
i
].
resize
(
numAtoms
);
dEdV
[
i
].
resize
(
numAtoms
);
dEdV
[
i
].
resize
(
numAtoms
);
}
dVdX
.
resize
(
valueDerivExpressions
.
size
());
dVdX
.
resize
(
valueDerivExpressions
.
size
());
dVdY
.
resize
(
valueDerivExpressions
.
size
());
dVdY
.
resize
(
valueDerivExpressions
.
size
());
dVdZ
.
resize
(
valueDerivExpressions
.
size
());
dVdZ
.
resize
(
valueDerivExpressions
.
size
());
...
@@ -96,7 +105,33 @@ CpuCustomGBForce::CpuCustomGBForce(int numAtoms, const vector<Lepton::CompiledEx
...
@@ -96,7 +105,33 @@ CpuCustomGBForce::CpuCustomGBForce(int numAtoms, const vector<Lepton::CompiledEx
dVdR2
.
resize
(
valueDerivExpressions
.
size
());
dVdR2
.
resize
(
valueDerivExpressions
.
size
());
}
}
CpuCustomGBForce
::
CpuCustomGBForce
(
int
numAtoms
,
const
std
::
vector
<
std
::
set
<
int
>
>&
exclusions
,
const
vector
<
Lepton
::
CompiledExpression
>&
valueExpressions
,
const
vector
<
vector
<
Lepton
::
CompiledExpression
>
>&
valueDerivExpressions
,
const
vector
<
vector
<
Lepton
::
CompiledExpression
>
>&
valueGradientExpressions
,
const
vector
<
string
>&
valueNames
,
const
vector
<
CustomGBForce
::
ComputationType
>&
valueTypes
,
const
vector
<
Lepton
::
CompiledExpression
>&
energyExpressions
,
const
vector
<
vector
<
Lepton
::
CompiledExpression
>
>&
energyDerivExpressions
,
const
vector
<
vector
<
Lepton
::
CompiledExpression
>
>&
energyGradientExpressions
,
const
vector
<
CustomGBForce
::
ComputationType
>&
energyTypes
,
const
vector
<
string
>&
parameterNames
,
ThreadPool
&
threads
)
:
exclusions
(
exclusions
),
cutoff
(
false
),
periodic
(
false
),
valueNames
(
valueNames
),
valueTypes
(
valueTypes
),
energyTypes
(
energyTypes
),
paramNames
(
parameterNames
),
threads
(
threads
)
{
for
(
int
i
=
0
;
i
<
threads
.
getNumThreads
();
i
++
)
threadData
.
push_back
(
new
ThreadData
(
numAtoms
,
threads
.
getNumThreads
(),
i
,
valueExpressions
,
valueDerivExpressions
,
valueGradientExpressions
,
valueNames
,
energyExpressions
,
energyDerivExpressions
,
energyGradientExpressions
,
parameterNames
));
values
.
resize
(
valueNames
.
size
());
dEdV
.
resize
(
valueNames
.
size
());
for
(
int
i
=
0
;
i
<
(
int
)
values
.
size
();
i
++
)
{
values
[
i
].
resize
(
numAtoms
);
dEdV
[
i
].
resize
(
numAtoms
);
}
}
CpuCustomGBForce
::~
CpuCustomGBForce
()
{
CpuCustomGBForce
::~
CpuCustomGBForce
()
{
for
(
int
i
=
0
;
i
<
(
int
)
threadData
.
size
();
i
++
)
delete
threadData
[
i
];
}
}
void
CpuCustomGBForce
::
setUseCutoff
(
float
distance
,
const
CpuNeighborList
&
neighbors
)
{
void
CpuCustomGBForce
::
setUseCutoff
(
float
distance
,
const
CpuNeighborList
&
neighbors
)
{
...
@@ -106,7 +141,6 @@ void CpuCustomGBForce::setUseCutoff(float distance, const CpuNeighborList& neigh
...
@@ -106,7 +141,6 @@ void CpuCustomGBForce::setUseCutoff(float distance, const CpuNeighborList& neigh
}
}
void
CpuCustomGBForce
::
setPeriodic
(
RealVec
&
boxSize
)
{
void
CpuCustomGBForce
::
setPeriodic
(
RealVec
&
boxSize
)
{
if
(
cutoff
)
{
if
(
cutoff
)
{
assert
(
boxSize
[
0
]
>=
2.0
*
cutoffDistance
);
assert
(
boxSize
[
0
]
>=
2.0
*
cutoffDistance
);
assert
(
boxSize
[
1
]
>=
2.0
*
cutoffDistance
);
assert
(
boxSize
[
1
]
>=
2.0
*
cutoffDistance
);
...
@@ -119,68 +153,157 @@ void CpuCustomGBForce::setPeriodic(RealVec& boxSize) {
...
@@ -119,68 +153,157 @@ void CpuCustomGBForce::setPeriodic(RealVec& boxSize) {
}
}
void
CpuCustomGBForce
::
calculateIxn
(
int
numberOfAtoms
,
float
*
posq
,
RealOpenMM
**
atomParameters
,
void
CpuCustomGBForce
::
calculateIxn
(
int
numberOfAtoms
,
float
*
posq
,
RealOpenMM
**
atomParameters
,
const
vector
<
set
<
int
>
>&
exclusions
,
map
<
string
,
double
>&
globalParameters
,
float
*
forces
,
map
<
string
,
double
>&
globalParameters
,
vector
<
AlignedArray
<
float
>
>&
threadForce
,
double
*
totalEnergy
)
{
bool
includeForce
,
bool
includeEnergy
,
double
&
totalEnergy
)
{
// Record the parameters for the threads.
this
->
numberOfAtoms
=
numberOfAtoms
;
this
->
posq
=
posq
;
this
->
atomParameters
=
atomParameters
;
this
->
globalParameters
=
&
globalParameters
;
this
->
threadForce
=
&
threadForce
;
this
->
includeForce
=
includeForce
;
this
->
includeEnergy
=
includeEnergy
;
threadEnergy
.
resize
(
threads
.
getNumThreads
());
gmx_atomic_t
counter
;
this
->
atomicCounter
=
&
counter
;
// Calculate the first computed value.
ComputeForceTask
task
(
*
this
);
gmx_atomic_set
(
&
counter
,
0
);
threads
.
execute
(
task
);
threads
.
waitForThreads
();
// Calculate the remaining computed values.
threads
.
resumeThreads
();
threads
.
waitForThreads
();
// Calculate the energy terms.
for
(
int
i
=
0
;
i
<
(
int
)
threadData
[
0
]
->
energyExpressions
.
size
();
i
++
)
{
gmx_atomic_set
(
&
counter
,
0
);
threads
.
execute
(
task
);
threads
.
waitForThreads
();
}
// Sum the energy derivatives.
threads
.
resumeThreads
();
threads
.
waitForThreads
();
// Apply the chain rule to evaluate forces.
gmx_atomic_set
(
&
counter
,
0
);
threads
.
resumeThreads
();
threads
.
waitForThreads
();
// Combine the energies from all the threads.
if
(
includeEnergy
)
{
int
numThreads
=
threads
.
getNumThreads
();
for
(
int
i
=
0
;
i
<
numThreads
;
i
++
)
totalEnergy
+=
threadEnergy
[
i
];
}
}
void
CpuCustomGBForce
::
threadComputeForce
(
ThreadPool
&
threads
,
int
threadIndex
)
{
// Compute this thread's subset of interactions.
int
numThreads
=
threads
.
getNumThreads
();
threadEnergy
[
threadIndex
]
=
0
;
double
&
energy
=
threadEnergy
[
threadIndex
];
float
*
forces
=
&
(
*
threadForce
)[
threadIndex
][
0
];
ThreadData
&
data
=
*
threadData
[
threadIndex
];
fvec4
boxSize
(
periodicBoxSize
[
0
],
periodicBoxSize
[
1
],
periodicBoxSize
[
2
],
0
);
fvec4
boxSize
(
periodicBoxSize
[
0
],
periodicBoxSize
[
1
],
periodicBoxSize
[
2
],
0
);
fvec4
invBoxSize
((
1
/
periodicBoxSize
[
0
]),
(
1
/
periodicBoxSize
[
1
]),
(
1
/
periodicBoxSize
[
2
]),
0
);
fvec4
invBoxSize
((
1
/
periodicBoxSize
[
0
]),
(
1
/
periodicBoxSize
[
1
]),
(
1
/
periodicBoxSize
[
2
]),
0
);
for
(
map
<
string
,
double
>::
const_iterator
iter
=
globalParameters
.
begin
();
iter
!=
globalParameters
.
end
();
++
iter
)
for
(
map
<
string
,
double
>::
const_iterator
iter
=
globalParameters
->
begin
();
iter
!=
globalParameters
->
end
();
++
iter
)
expressionSet
.
setVariable
(
expressionSet
.
getVariableIndex
(
iter
->
first
),
iter
->
second
);
data
.
expressionSet
.
setVariable
(
data
.
expressionSet
.
getVariableIndex
(
iter
->
first
),
iter
->
second
);
// Calculate the first computed value.
for
(
int
i
=
0
;
i
<
(
int
)
data
.
value0
.
size
();
i
++
)
data
.
value0
[
i
]
=
0.0
f
;
if
(
valueTypes
[
0
]
==
CustomGBForce
::
ParticlePair
)
calculateParticlePairValue
(
0
,
data
,
numberOfAtoms
,
posq
,
atomParameters
,
true
,
boxSize
,
invBoxSize
);
else
calculateParticlePairValue
(
0
,
data
,
numberOfAtoms
,
posq
,
atomParameters
,
false
,
boxSize
,
invBoxSize
);
threads
.
syncThreads
();
// Sum the first computed value.
for
(
int
atom
=
data
.
firstAtom
;
atom
<
data
.
lastAtom
;
atom
++
)
{
float
sum
=
0.0
f
;
for
(
int
j
=
0
;
j
<
(
int
)
threadData
.
size
();
j
++
)
sum
+=
threadData
[
j
]
->
value0
[
atom
];
values
[
0
][
atom
]
=
sum
;
}
//
First c
alculate the computed values.
//
C
alculate the
remaining
computed values.
int
numValues
=
valueTypes
.
size
();
int
numValues
=
valueTypes
.
size
();
for
(
int
valueIndex
=
0
;
valueIndex
<
numValues
;
valueIndex
++
)
{
for
(
int
i
=
1
;
i
<
numValues
;
i
++
)
if
(
valueTypes
[
valueIndex
]
==
CustomGBForce
::
SingleParticle
)
calculateSingleParticleValue
(
i
,
data
,
numberOfAtoms
,
posq
,
atomParameters
);
calculateSingleParticleValue
(
valueIndex
,
numberOfAtoms
,
posq
,
values
,
atomParameters
);
threads
.
syncThreads
();
else
if
(
valueTypes
[
valueIndex
]
==
CustomGBForce
::
ParticlePair
)
calculateParticlePairValue
(
valueIndex
,
numberOfAtoms
,
posq
,
atomParameters
,
values
,
exclusions
,
true
,
boxSize
,
invBoxSize
);
else
calculateParticlePairValue
(
valueIndex
,
numberOfAtoms
,
posq
,
atomParameters
,
values
,
exclusions
,
false
,
boxSize
,
invBoxSize
);
}
// Now calculate the energy and its derivatives.
// Now calculate the energy and its derivatives.
for
(
int
i
=
0
;
i
<
(
int
)
dEdV
.
size
();
i
++
)
for
(
int
i
=
0
;
i
<
(
int
)
data
.
dEdV
.
size
();
i
++
)
for
(
int
j
=
0
;
j
<
(
int
)
dEdV
[
i
].
size
();
j
++
)
for
(
int
j
=
0
;
j
<
(
int
)
data
.
dEdV
[
i
].
size
();
j
++
)
dEdV
[
i
][
j
]
=
0.0
;
data
.
dEdV
[
i
][
j
]
=
0.0
;
for
(
int
termIndex
=
0
;
termIndex
<
(
int
)
energyExpressions
.
size
();
termIndex
++
)
{
for
(
int
termIndex
=
0
;
termIndex
<
(
int
)
data
.
energyExpressions
.
size
();
termIndex
++
)
{
if
(
energyTypes
[
termIndex
]
==
CustomGBForce
::
SingleParticle
)
if
(
energyTypes
[
termIndex
]
==
CustomGBForce
::
SingleParticle
)
calculateSingleParticleEnergyTerm
(
termIndex
,
numberOfAtoms
,
posq
,
values
,
atomParameters
,
forces
,
totalEnergy
,
dEdV
);
calculateSingleParticleEnergyTerm
(
termIndex
,
data
,
numberOfAtoms
,
posq
,
atomParameters
,
forces
,
energy
);
else
if
(
energyTypes
[
termIndex
]
==
CustomGBForce
::
ParticlePair
)
else
if
(
energyTypes
[
termIndex
]
==
CustomGBForce
::
ParticlePair
)
calculateParticlePairEnergyTerm
(
termIndex
,
numberOfAtoms
,
posq
,
atomParameters
,
values
,
exclusions
,
true
,
forces
,
totalEnergy
,
dEdV
,
boxSize
,
invBoxSize
);
calculateParticlePairEnergyTerm
(
termIndex
,
data
,
numberOfAtoms
,
posq
,
atomParameters
,
true
,
forces
,
energy
,
boxSize
,
invBoxSize
);
else
else
calculateParticlePairEnergyTerm
(
termIndex
,
numberOfAtoms
,
posq
,
atomParameters
,
values
,
exclusions
,
false
,
forces
,
totalEnergy
,
dEdV
,
boxSize
,
invBoxSize
);
calculateParticlePairEnergyTerm
(
termIndex
,
data
,
numberOfAtoms
,
posq
,
atomParameters
,
false
,
forces
,
energy
,
boxSize
,
invBoxSize
);
threads
.
syncThreads
();
}
// Sum the energy derivatives.
for
(
int
atom
=
data
.
firstAtom
;
atom
<
data
.
lastAtom
;
atom
++
)
{
for
(
int
i
=
0
;
i
<
(
int
)
dEdV
.
size
();
i
++
)
{
float
sum
=
0.0
f
;
for
(
int
j
=
0
;
j
<
(
int
)
threadData
.
size
();
j
++
)
sum
+=
threadData
[
j
]
->
dEdV
[
i
][
atom
];
dEdV
[
i
][
atom
]
=
sum
;
}
}
}
threads
.
syncThreads
();
// Apply the chain rule to evaluate forces.
// Apply the chain rule to evaluate forces.
calculateChainRuleForces
(
numberOfAtoms
,
posq
,
atomParameters
,
values
,
exclusions
,
forces
,
dEdV
,
boxSize
,
invBoxSize
);
calculateChainRuleForces
(
data
,
numberOfAtoms
,
posq
,
atomParameters
,
forces
,
boxSize
,
invBoxSize
);
}
}
void
CpuCustomGBForce
::
calculateSingleParticleValue
(
int
index
,
int
numAtoms
,
float
*
posq
,
vector
<
vector
<
float
>
>&
values
,
void
CpuCustomGBForce
::
calculateSingleParticleValue
(
int
index
,
ThreadData
&
data
,
int
numAtoms
,
float
*
posq
,
RealOpenMM
**
atomParameters
)
{
RealOpenMM
**
atomParameters
)
{
for
(
int
i
=
data
.
firstAtom
;
i
<
data
.
lastAtom
;
i
++
)
{
values
[
index
].
resize
(
numAtoms
);
data
.
expressionSet
.
setVariable
(
data
.
xindex
,
posq
[
4
*
i
]);
for
(
int
i
=
0
;
i
<
numAtoms
;
i
++
)
{
data
.
expressionSet
.
setVariable
(
data
.
yindex
,
posq
[
4
*
i
+
1
]);
expressionSet
.
setVariable
(
xindex
,
posq
[
4
*
i
]);
data
.
expressionSet
.
setVariable
(
data
.
zindex
,
posq
[
4
*
i
+
2
]);
expressionSet
.
setVariable
(
yindex
,
posq
[
4
*
i
+
1
]);
expressionSet
.
setVariable
(
zindex
,
posq
[
4
*
i
+
2
]);
for
(
int
j
=
0
;
j
<
(
int
)
paramNames
.
size
();
j
++
)
for
(
int
j
=
0
;
j
<
(
int
)
paramNames
.
size
();
j
++
)
expressionSet
.
setVariable
(
paramIndex
[
j
],
atomParameters
[
i
][
j
]);
data
.
expressionSet
.
setVariable
(
data
.
paramIndex
[
j
],
atomParameters
[
i
][
j
]);
for
(
int
j
=
0
;
j
<
index
;
j
++
)
for
(
int
j
=
0
;
j
<
index
;
j
++
)
expressionSet
.
setVariable
(
valueIndex
[
j
],
values
[
j
][
i
]);
data
.
expressionSet
.
setVariable
(
data
.
valueIndex
[
j
],
values
[
j
][
i
]);
values
[
index
][
i
]
=
(
float
)
valueExpressions
[
index
].
evaluate
();
values
[
index
][
i
]
=
(
float
)
data
.
valueExpressions
[
index
].
evaluate
();
}
}
}
}
void
CpuCustomGBForce
::
calculateParticlePairValue
(
int
index
,
int
numAtoms
,
float
*
posq
,
RealOpenMM
**
atomParameters
,
void
CpuCustomGBForce
::
calculateParticlePairValue
(
int
index
,
ThreadData
&
data
,
int
numAtoms
,
float
*
posq
,
RealOpenMM
**
atomParameters
,
vector
<
vector
<
float
>
>&
values
,
const
vector
<
set
<
int
>
>&
exclusions
,
bool
useExclusions
,
const
fvec4
&
boxSize
,
const
fvec4
&
invBoxSize
)
{
bool
useExclusions
,
const
fvec4
&
boxSize
,
const
fvec4
&
invBoxSize
)
{
values
[
index
].
resize
(
numAtoms
);
for
(
int
i
=
0
;
i
<
numAtoms
;
i
++
)
for
(
int
i
=
0
;
i
<
numAtoms
;
i
++
)
values
[
index
][
i
]
=
0.0
f
;
values
[
index
][
i
]
=
0.0
f
;
vector
<
float
>&
valueArray
=
(
index
==
0
?
data
.
value0
:
values
[
index
]);
if
(
cutoff
)
{
if
(
cutoff
)
{
// Loop over all pairs in the neighbor list.
// Loop over all pairs in the neighbor list.
for
(
int
blockIndex
=
0
;
blockIndex
<
neighborList
->
getNumBlocks
();
blockIndex
++
)
{
while
(
true
)
{
int
blockIndex
=
gmx_atomic_fetch_add
(
reinterpret_cast
<
gmx_atomic_t
*>
(
atomicCounter
),
1
);
if
(
blockIndex
>=
neighborList
->
getNumBlocks
())
break
;
const
int
*
blockAtom
=
&
neighborList
->
getSortedAtoms
()[
4
*
blockIndex
];
const
int
*
blockAtom
=
&
neighborList
->
getSortedAtoms
()[
4
*
blockIndex
];
const
vector
<
int
>&
neighbors
=
neighborList
->
getBlockNeighbors
(
blockIndex
);
const
vector
<
int
>&
neighbors
=
neighborList
->
getBlockNeighbors
(
blockIndex
);
const
vector
<
char
>&
blockExclusions
=
neighborList
->
getBlockExclusions
(
blockIndex
);
const
vector
<
char
>&
blockExclusions
=
neighborList
->
getBlockExclusions
(
blockIndex
);
...
@@ -191,8 +314,8 @@ void CpuCustomGBForce::calculateParticlePairValue(int index, int numAtoms, float
...
@@ -191,8 +314,8 @@ void CpuCustomGBForce::calculateParticlePairValue(int index, int numAtoms, float
int
second
=
blockAtom
[
k
];
int
second
=
blockAtom
[
k
];
if
(
useExclusions
&&
exclusions
[
first
].
find
(
second
)
!=
exclusions
[
first
].
end
())
if
(
useExclusions
&&
exclusions
[
first
].
find
(
second
)
!=
exclusions
[
first
].
end
())
continue
;
continue
;
calculateOnePairValue
(
index
,
first
,
second
,
posq
,
atomParameters
,
value
s
,
boxSize
,
invBoxSize
);
calculateOnePairValue
(
index
,
first
,
second
,
data
,
posq
,
atomParameters
,
value
Array
,
boxSize
,
invBoxSize
);
calculateOnePairValue
(
index
,
second
,
first
,
posq
,
atomParameters
,
value
s
,
boxSize
,
invBoxSize
);
calculateOnePairValue
(
index
,
second
,
first
,
data
,
posq
,
atomParameters
,
value
Array
,
boxSize
,
invBoxSize
);
}
}
}
}
}
}
...
@@ -201,19 +324,22 @@ void CpuCustomGBForce::calculateParticlePairValue(int index, int numAtoms, float
...
@@ -201,19 +324,22 @@ void CpuCustomGBForce::calculateParticlePairValue(int index, int numAtoms, float
else
{
else
{
// Perform an O(N^2) loop over all atom pairs.
// Perform an O(N^2) loop over all atom pairs.
for
(
int
i
=
0
;
i
<
numAtoms
;
i
++
)
{
while
(
true
)
{
int
i
=
gmx_atomic_fetch_add
(
reinterpret_cast
<
gmx_atomic_t
*>
(
atomicCounter
),
1
);
if
(
i
>=
numAtoms
)
break
;
for
(
int
j
=
i
+
1
;
j
<
numAtoms
;
j
++
)
{
for
(
int
j
=
i
+
1
;
j
<
numAtoms
;
j
++
)
{
if
(
useExclusions
&&
exclusions
[
i
].
find
(
j
)
!=
exclusions
[
i
].
end
())
if
(
useExclusions
&&
exclusions
[
i
].
find
(
j
)
!=
exclusions
[
i
].
end
())
continue
;
continue
;
calculateOnePairValue
(
index
,
i
,
j
,
posq
,
atomParameters
,
value
s
,
boxSize
,
invBoxSize
);
calculateOnePairValue
(
index
,
i
,
j
,
data
,
posq
,
atomParameters
,
value
Array
,
boxSize
,
invBoxSize
);
calculateOnePairValue
(
index
,
j
,
i
,
posq
,
atomParameters
,
value
s
,
boxSize
,
invBoxSize
);
calculateOnePairValue
(
index
,
j
,
i
,
data
,
posq
,
atomParameters
,
value
Array
,
boxSize
,
invBoxSize
);
}
}
}
}
}
}
}
}
void
CpuCustomGBForce
::
calculateOnePairValue
(
int
index
,
int
atom1
,
int
atom2
,
float
*
posq
,
RealOpenMM
**
atomParameters
,
void
CpuCustomGBForce
::
calculateOnePairValue
(
int
index
,
int
atom1
,
int
atom2
,
ThreadData
&
data
,
float
*
posq
,
RealOpenMM
**
atomParameters
,
vector
<
vector
<
float
>
>
&
value
s
,
const
fvec4
&
boxSize
,
const
fvec4
&
invBoxSize
)
{
vector
<
float
>&
value
Array
,
const
fvec4
&
boxSize
,
const
fvec4
&
invBoxSize
)
{
fvec4
deltaR
;
fvec4
deltaR
;
fvec4
pos1
(
posq
+
4
*
atom1
);
fvec4
pos1
(
posq
+
4
*
atom1
);
fvec4
pos2
(
posq
+
4
*
atom2
);
fvec4
pos2
(
posq
+
4
*
atom2
);
...
@@ -223,45 +349,46 @@ void CpuCustomGBForce::calculateOnePairValue(int index, int atom1, int atom2, fl
...
@@ -223,45 +349,46 @@ void CpuCustomGBForce::calculateOnePairValue(int index, int atom1, int atom2, fl
if
(
cutoff
&&
r
>=
cutoffDistance
)
if
(
cutoff
&&
r
>=
cutoffDistance
)
return
;
return
;
for
(
int
i
=
0
;
i
<
(
int
)
paramNames
.
size
();
i
++
)
{
for
(
int
i
=
0
;
i
<
(
int
)
paramNames
.
size
();
i
++
)
{
expressionSet
.
setVariable
(
particleParamIndex
[
i
*
2
],
atomParameters
[
atom1
][
i
]);
data
.
expressionSet
.
setVariable
(
data
.
particleParamIndex
[
i
*
2
],
atomParameters
[
atom1
][
i
]);
expressionSet
.
setVariable
(
particleParamIndex
[
i
*
2
+
1
],
atomParameters
[
atom2
][
i
]);
data
.
expressionSet
.
setVariable
(
data
.
particleParamIndex
[
i
*
2
+
1
],
atomParameters
[
atom2
][
i
]);
}
}
expressionSet
.
setVariable
(
rindex
,
r
);
data
.
expressionSet
.
setVariable
(
data
.
rindex
,
r
);
for
(
int
i
=
0
;
i
<
index
;
i
++
)
{
for
(
int
i
=
0
;
i
<
index
;
i
++
)
{
expressionSet
.
setVariable
(
particleValueIndex
[
i
*
2
],
values
[
i
][
atom1
]);
data
.
expressionSet
.
setVariable
(
data
.
particleValueIndex
[
i
*
2
],
values
[
i
][
atom1
]);
expressionSet
.
setVariable
(
particleValueIndex
[
i
*
2
+
1
],
values
[
i
][
atom2
]);
data
.
expressionSet
.
setVariable
(
data
.
particleValueIndex
[
i
*
2
+
1
],
values
[
i
][
atom2
]);
}
}
value
s
[
index
]
[
atom1
]
+=
(
float
)
valueExpressions
[
index
].
evaluate
();
value
Array
[
atom1
]
+=
(
float
)
data
.
valueExpressions
[
index
].
evaluate
();
}
}
void
CpuCustomGBForce
::
calculateSingleParticleEnergyTerm
(
int
index
,
int
numAtoms
,
float
*
posq
,
const
vector
<
vector
<
float
>
>&
values
,
void
CpuCustomGBForce
::
calculateSingleParticleEnergyTerm
(
int
index
,
ThreadData
&
data
,
int
numAtoms
,
float
*
posq
,
RealOpenMM
**
atomParameters
,
float
*
forces
,
double
*
totalEnergy
,
RealOpenMM
**
atomParameters
,
float
*
forces
,
double
&
totalEnergy
)
{
vector
<
vector
<
float
>
>&
dEdV
)
{
for
(
int
i
=
data
.
firstAtom
;
i
<
data
.
lastAtom
;
i
++
)
{
for
(
int
i
=
0
;
i
<
numAtoms
;
i
++
)
{
data
.
expressionSet
.
setVariable
(
data
.
xindex
,
posq
[
4
*
i
]);
expressionSet
.
setVariable
(
xindex
,
posq
[
4
*
i
]);
data
.
expressionSet
.
setVariable
(
data
.
yindex
,
posq
[
4
*
i
+
1
]);
expressionSet
.
setVariable
(
yindex
,
posq
[
4
*
i
+
1
]);
data
.
expressionSet
.
setVariable
(
data
.
zindex
,
posq
[
4
*
i
+
2
]);
expressionSet
.
setVariable
(
zindex
,
posq
[
4
*
i
+
2
]);
for
(
int
j
=
0
;
j
<
(
int
)
paramNames
.
size
();
j
++
)
for
(
int
j
=
0
;
j
<
(
int
)
paramNames
.
size
();
j
++
)
expressionSet
.
setVariable
(
paramIndex
[
j
],
atomParameters
[
i
][
j
]);
data
.
expressionSet
.
setVariable
(
data
.
paramIndex
[
j
],
atomParameters
[
i
][
j
]);
for
(
int
j
=
0
;
j
<
(
int
)
valueNames
.
size
();
j
++
)
for
(
int
j
=
0
;
j
<
(
int
)
valueNames
.
size
();
j
++
)
expressionSet
.
setVariable
(
valueIndex
[
j
],
values
[
j
][
i
]);
data
.
expressionSet
.
setVariable
(
data
.
valueIndex
[
j
],
values
[
j
][
i
]);
if
(
totalEnergy
!=
NULL
)
if
(
includeEnergy
)
*
totalEnergy
+=
(
float
)
energyExpressions
[
index
].
evaluate
();
totalEnergy
+=
(
float
)
data
.
energyExpressions
[
index
].
evaluate
();
for
(
int
j
=
0
;
j
<
(
int
)
valueNames
.
size
();
j
++
)
for
(
int
j
=
0
;
j
<
(
int
)
valueNames
.
size
();
j
++
)
dEdV
[
j
][
i
]
+=
(
float
)
energyDerivExpressions
[
index
][
j
].
evaluate
();
data
.
dEdV
[
j
][
i
]
+=
(
float
)
data
.
energyDerivExpressions
[
index
][
j
].
evaluate
();
forces
[
4
*
i
+
0
]
-=
(
float
)
energyGradientExpressions
[
index
][
0
].
evaluate
();
forces
[
4
*
i
+
0
]
-=
(
float
)
data
.
energyGradientExpressions
[
index
][
0
].
evaluate
();
forces
[
4
*
i
+
1
]
-=
(
float
)
energyGradientExpressions
[
index
][
1
].
evaluate
();
forces
[
4
*
i
+
1
]
-=
(
float
)
data
.
energyGradientExpressions
[
index
][
1
].
evaluate
();
forces
[
4
*
i
+
2
]
-=
(
float
)
energyGradientExpressions
[
index
][
2
].
evaluate
();
forces
[
4
*
i
+
2
]
-=
(
float
)
data
.
energyGradientExpressions
[
index
][
2
].
evaluate
();
}
}
}
}
void
CpuCustomGBForce
::
calculateParticlePairEnergyTerm
(
int
index
,
int
numAtoms
,
float
*
posq
,
RealOpenMM
**
atomParameters
,
void
CpuCustomGBForce
::
calculateParticlePairEnergyTerm
(
int
index
,
ThreadData
&
data
,
int
numAtoms
,
float
*
posq
,
RealOpenMM
**
atomParameters
,
const
vector
<
vector
<
float
>
>&
values
,
const
vector
<
set
<
int
>
>&
exclusions
,
bool
useExclusions
,
bool
useExclusions
,
float
*
forces
,
double
&
totalEnergy
,
const
fvec4
&
boxSize
,
const
fvec4
&
invBoxSize
)
{
float
*
forces
,
double
*
totalEnergy
,
vector
<
vector
<
float
>
>&
dEdV
,
const
fvec4
&
boxSize
,
const
fvec4
&
invBoxSize
)
{
if
(
cutoff
)
{
if
(
cutoff
)
{
// Loop over all pairs in the neighbor list.
// Loop over all pairs in the neighbor list.
for
(
int
blockIndex
=
0
;
blockIndex
<
neighborList
->
getNumBlocks
();
blockIndex
++
)
{
while
(
true
)
{
int
blockIndex
=
gmx_atomic_fetch_add
(
reinterpret_cast
<
gmx_atomic_t
*>
(
atomicCounter
),
1
);
if
(
blockIndex
>=
neighborList
->
getNumBlocks
())
break
;
const
int
*
blockAtom
=
&
neighborList
->
getSortedAtoms
()[
4
*
blockIndex
];
const
int
*
blockAtom
=
&
neighborList
->
getSortedAtoms
()[
4
*
blockIndex
];
const
vector
<
int
>&
neighbors
=
neighborList
->
getBlockNeighbors
(
blockIndex
);
const
vector
<
int
>&
neighbors
=
neighborList
->
getBlockNeighbors
(
blockIndex
);
const
vector
<
char
>&
blockExclusions
=
neighborList
->
getBlockExclusions
(
blockIndex
);
const
vector
<
char
>&
blockExclusions
=
neighborList
->
getBlockExclusions
(
blockIndex
);
...
@@ -272,7 +399,7 @@ void CpuCustomGBForce::calculateParticlePairEnergyTerm(int index, int numAtoms,
...
@@ -272,7 +399,7 @@ void CpuCustomGBForce::calculateParticlePairEnergyTerm(int index, int numAtoms,
int
second
=
blockAtom
[
k
];
int
second
=
blockAtom
[
k
];
if
(
useExclusions
&&
exclusions
[
first
].
find
(
second
)
!=
exclusions
[
first
].
end
())
if
(
useExclusions
&&
exclusions
[
first
].
find
(
second
)
!=
exclusions
[
first
].
end
())
continue
;
continue
;
calculateOnePairEnergyTerm
(
index
,
first
,
second
,
posq
,
atomParameters
,
values
,
forces
,
totalEnergy
,
dEdV
,
boxSize
,
invBoxSize
);
calculateOnePairEnergyTerm
(
index
,
first
,
second
,
data
,
posq
,
atomParameters
,
forces
,
totalEnergy
,
boxSize
,
invBoxSize
);
}
}
}
}
}
}
...
@@ -281,19 +408,21 @@ void CpuCustomGBForce::calculateParticlePairEnergyTerm(int index, int numAtoms,
...
@@ -281,19 +408,21 @@ void CpuCustomGBForce::calculateParticlePairEnergyTerm(int index, int numAtoms,
else
{
else
{
// Perform an O(N^2) loop over all atom pairs.
// Perform an O(N^2) loop over all atom pairs.
for
(
int
i
=
0
;
i
<
numAtoms
;
i
++
)
{
while
(
true
)
{
int
i
=
gmx_atomic_fetch_add
(
reinterpret_cast
<
gmx_atomic_t
*>
(
atomicCounter
),
1
);
if
(
i
>=
numAtoms
)
break
;
for
(
int
j
=
i
+
1
;
j
<
numAtoms
;
j
++
)
{
for
(
int
j
=
i
+
1
;
j
<
numAtoms
;
j
++
)
{
if
(
useExclusions
&&
exclusions
[
i
].
find
(
j
)
!=
exclusions
[
i
].
end
())
if
(
useExclusions
&&
exclusions
[
i
].
find
(
j
)
!=
exclusions
[
i
].
end
())
continue
;
continue
;
calculateOnePairEnergyTerm
(
index
,
i
,
j
,
posq
,
atomParameters
,
values
,
forces
,
totalEnergy
,
dEdV
,
boxSize
,
invBoxSize
);
calculateOnePairEnergyTerm
(
index
,
i
,
j
,
data
,
posq
,
atomParameters
,
forces
,
totalEnergy
,
boxSize
,
invBoxSize
);
}
}
}
}
}
}
}
}
void
CpuCustomGBForce
::
calculateOnePairEnergyTerm
(
int
index
,
int
atom1
,
int
atom2
,
float
*
posq
,
RealOpenMM
**
atomParameters
,
void
CpuCustomGBForce
::
calculateOnePairEnergyTerm
(
int
index
,
int
atom1
,
int
atom2
,
ThreadData
&
data
,
float
*
posq
,
RealOpenMM
**
atomParameters
,
const
vector
<
vector
<
float
>
>&
values
,
float
*
forces
,
double
*
totalEnergy
,
float
*
forces
,
double
&
totalEnergy
,
const
fvec4
&
boxSize
,
const
fvec4
&
invBoxSize
)
{
vector
<
vector
<
float
>
>&
dEdV
,
const
fvec4
&
boxSize
,
const
fvec4
&
invBoxSize
)
{
// Compute the displacement.
// Compute the displacement.
fvec4
deltaR
;
fvec4
deltaR
;
...
@@ -308,37 +437,39 @@ void CpuCustomGBForce::calculateOnePairEnergyTerm(int index, int atom1, int atom
...
@@ -308,37 +437,39 @@ void CpuCustomGBForce::calculateOnePairEnergyTerm(int index, int atom1, int atom
// Record variables for evaluating expressions.
// Record variables for evaluating expressions.
for
(
int
i
=
0
;
i
<
(
int
)
paramNames
.
size
();
i
++
)
{
for
(
int
i
=
0
;
i
<
(
int
)
paramNames
.
size
();
i
++
)
{
expressionSet
.
setVariable
(
particleParamIndex
[
i
*
2
],
atomParameters
[
atom1
][
i
]);
data
.
expressionSet
.
setVariable
(
data
.
particleParamIndex
[
i
*
2
],
atomParameters
[
atom1
][
i
]);
expressionSet
.
setVariable
(
particleParamIndex
[
i
*
2
+
1
],
atomParameters
[
atom2
][
i
]);
data
.
expressionSet
.
setVariable
(
data
.
particleParamIndex
[
i
*
2
+
1
],
atomParameters
[
atom2
][
i
]);
}
}
expressionSet
.
setVariable
(
rindex
,
r
);
data
.
expressionSet
.
setVariable
(
data
.
rindex
,
r
);
for
(
int
i
=
0
;
i
<
(
int
)
valueNames
.
size
();
i
++
)
{
for
(
int
i
=
0
;
i
<
(
int
)
valueNames
.
size
();
i
++
)
{
expressionSet
.
setVariable
(
particleValueIndex
[
i
*
2
],
values
[
i
][
atom1
]);
data
.
expressionSet
.
setVariable
(
data
.
particleValueIndex
[
i
*
2
],
values
[
i
][
atom1
]);
expressionSet
.
setVariable
(
particleValueIndex
[
i
*
2
+
1
],
values
[
i
][
atom2
]);
data
.
expressionSet
.
setVariable
(
data
.
particleValueIndex
[
i
*
2
+
1
],
values
[
i
][
atom2
]);
}
}
// Evaluate the energy and its derivatives.
// Evaluate the energy and its derivatives.
if
(
totalEnergy
!=
NULL
)
if
(
includeEnergy
)
*
totalEnergy
+=
(
float
)
energyExpressions
[
index
].
evaluate
();
totalEnergy
+=
(
float
)
data
.
energyExpressions
[
index
].
evaluate
();
float
dEdR
=
(
float
)
energyDerivExpressions
[
index
][
0
].
evaluate
();
float
dEdR
=
(
float
)
data
.
energyDerivExpressions
[
index
][
0
].
evaluate
();
dEdR
*=
1
/
r
;
dEdR
*=
1
/
r
;
fvec4
result
=
deltaR
*
dEdR
;
fvec4
result
=
deltaR
*
dEdR
;
(
fvec4
(
forces
+
4
*
atom1
)
-
result
).
store
(
forces
+
4
*
atom1
);
(
fvec4
(
forces
+
4
*
atom1
)
-
result
).
store
(
forces
+
4
*
atom1
);
(
fvec4
(
forces
+
4
*
atom2
)
+
result
).
store
(
forces
+
4
*
atom2
);
(
fvec4
(
forces
+
4
*
atom2
)
+
result
).
store
(
forces
+
4
*
atom2
);
for
(
int
i
=
0
;
i
<
(
int
)
valueNames
.
size
();
i
++
)
{
for
(
int
i
=
0
;
i
<
(
int
)
valueNames
.
size
();
i
++
)
{
dEdV
[
i
][
atom1
]
+=
(
float
)
energyDerivExpressions
[
index
][
2
*
i
+
1
].
evaluate
();
data
.
dEdV
[
i
][
atom1
]
+=
(
float
)
data
.
energyDerivExpressions
[
index
][
2
*
i
+
1
].
evaluate
();
dEdV
[
i
][
atom2
]
+=
(
float
)
energyDerivExpressions
[
index
][
2
*
i
+
2
].
evaluate
();
data
.
dEdV
[
i
][
atom2
]
+=
(
float
)
data
.
energyDerivExpressions
[
index
][
2
*
i
+
2
].
evaluate
();
}
}
}
}
void
CpuCustomGBForce
::
calculateChainRuleForces
(
int
numAtoms
,
float
*
posq
,
RealOpenMM
**
atomParameters
,
void
CpuCustomGBForce
::
calculateChainRuleForces
(
ThreadData
&
data
,
int
numAtoms
,
float
*
posq
,
RealOpenMM
**
atomParameters
,
const
vector
<
vector
<
float
>
>&
values
,
const
vector
<
set
<
int
>
>&
exclusions
,
float
*
forces
,
vector
<
vector
<
float
>
>&
dEdV
,
float
*
forces
,
const
fvec4
&
boxSize
,
const
fvec4
&
invBoxSize
)
{
const
fvec4
&
boxSize
,
const
fvec4
&
invBoxSize
)
{
if
(
cutoff
)
{
if
(
cutoff
)
{
// Loop over all pairs in the neighbor list.
// Loop over all pairs in the neighbor list.
for
(
int
blockIndex
=
0
;
blockIndex
<
neighborList
->
getNumBlocks
();
blockIndex
++
)
{
while
(
true
)
{
int
blockIndex
=
gmx_atomic_fetch_add
(
reinterpret_cast
<
gmx_atomic_t
*>
(
atomicCounter
),
1
);
if
(
blockIndex
>=
neighborList
->
getNumBlocks
())
break
;
const
int
*
blockAtom
=
&
neighborList
->
getSortedAtoms
()[
4
*
blockIndex
];
const
int
*
blockAtom
=
&
neighborList
->
getSortedAtoms
()[
4
*
blockIndex
];
const
vector
<
int
>&
neighbors
=
neighborList
->
getBlockNeighbors
(
blockIndex
);
const
vector
<
int
>&
neighbors
=
neighborList
->
getBlockNeighbors
(
blockIndex
);
const
vector
<
char
>&
blockExclusions
=
neighborList
->
getBlockExclusions
(
blockIndex
);
const
vector
<
char
>&
blockExclusions
=
neighborList
->
getBlockExclusions
(
blockIndex
);
...
@@ -348,8 +479,8 @@ void CpuCustomGBForce::calculateChainRuleForces(int numAtoms, float* posq, RealO
...
@@ -348,8 +479,8 @@ void CpuCustomGBForce::calculateChainRuleForces(int numAtoms, float* posq, RealO
if
((
blockExclusions
[
i
]
&
(
1
<<
k
))
==
0
)
{
if
((
blockExclusions
[
i
]
&
(
1
<<
k
))
==
0
)
{
int
second
=
blockAtom
[
k
];
int
second
=
blockAtom
[
k
];
bool
isExcluded
=
(
exclusions
[
first
].
find
(
second
)
!=
exclusions
[
first
].
end
());
bool
isExcluded
=
(
exclusions
[
first
].
find
(
second
)
!=
exclusions
[
first
].
end
());
calculateOnePairChainRule
(
first
,
second
,
posq
,
atomParameters
,
values
,
forces
,
dEdV
,
isExcluded
,
boxSize
,
invBoxSize
);
calculateOnePairChainRule
(
first
,
second
,
data
,
posq
,
atomParameters
,
forces
,
isExcluded
,
boxSize
,
invBoxSize
);
calculateOnePairChainRule
(
second
,
first
,
posq
,
atomParameters
,
values
,
forces
,
dEdV
,
isExcluded
,
boxSize
,
invBoxSize
);
calculateOnePairChainRule
(
second
,
first
,
data
,
posq
,
atomParameters
,
forces
,
isExcluded
,
boxSize
,
invBoxSize
);
}
}
}
}
}
}
...
@@ -358,46 +489,49 @@ void CpuCustomGBForce::calculateChainRuleForces(int numAtoms, float* posq, RealO
...
@@ -358,46 +489,49 @@ void CpuCustomGBForce::calculateChainRuleForces(int numAtoms, float* posq, RealO
else
{
else
{
// Perform an O(N^2) loop over all atom pairs.
// Perform an O(N^2) loop over all atom pairs.
for
(
int
i
=
0
;
i
<
numAtoms
;
i
++
)
{
while
(
true
)
{
int
i
=
gmx_atomic_fetch_add
(
reinterpret_cast
<
gmx_atomic_t
*>
(
atomicCounter
),
1
);
if
(
i
>=
numAtoms
)
break
;
for
(
int
j
=
i
+
1
;
j
<
numAtoms
;
j
++
)
{
for
(
int
j
=
i
+
1
;
j
<
numAtoms
;
j
++
)
{
bool
isExcluded
=
(
exclusions
[
i
].
find
(
j
)
!=
exclusions
[
i
].
end
());
bool
isExcluded
=
(
exclusions
[
i
].
find
(
j
)
!=
exclusions
[
i
].
end
());
calculateOnePairChainRule
(
i
,
j
,
posq
,
atomParameters
,
values
,
forces
,
dEdV
,
isExcluded
,
boxSize
,
invBoxSize
);
calculateOnePairChainRule
(
i
,
j
,
data
,
posq
,
atomParameters
,
forces
,
isExcluded
,
boxSize
,
invBoxSize
);
calculateOnePairChainRule
(
j
,
i
,
posq
,
atomParameters
,
values
,
forces
,
dEdV
,
isExcluded
,
boxSize
,
invBoxSize
);
calculateOnePairChainRule
(
j
,
i
,
data
,
posq
,
atomParameters
,
forces
,
isExcluded
,
boxSize
,
invBoxSize
);
}
}
}
}
}
}
// Compute chain rule terms for computed values that depend explicitly on particle coordinates.
// Compute chain rule terms for computed values that depend explicitly on particle coordinates.
for
(
int
i
=
0
;
i
<
num
Atom
s
;
i
++
)
{
for
(
int
i
=
data
.
firstAtom
;
i
<
data
.
last
Atom
;
i
++
)
{
expressionSet
.
setVariable
(
xindex
,
posq
[
4
*
i
]);
data
.
expressionSet
.
setVariable
(
data
.
xindex
,
posq
[
4
*
i
]);
expressionSet
.
setVariable
(
yindex
,
posq
[
4
*
i
+
1
]);
data
.
expressionSet
.
setVariable
(
data
.
yindex
,
posq
[
4
*
i
+
1
]);
expressionSet
.
setVariable
(
zindex
,
posq
[
4
*
i
+
2
]);
data
.
expressionSet
.
setVariable
(
data
.
zindex
,
posq
[
4
*
i
+
2
]);
for
(
int
j
=
0
;
j
<
(
int
)
paramNames
.
size
();
j
++
)
for
(
int
j
=
0
;
j
<
(
int
)
paramNames
.
size
();
j
++
)
expressionSet
.
setVariable
(
paramIndex
[
j
],
atomParameters
[
i
][
j
]);
data
.
expressionSet
.
setVariable
(
data
.
paramIndex
[
j
],
atomParameters
[
i
][
j
]);
for
(
int
j
=
1
;
j
<
(
int
)
valueNames
.
size
();
j
++
)
{
for
(
int
j
=
1
;
j
<
(
int
)
valueNames
.
size
();
j
++
)
{
expressionSet
.
setVariable
(
valueIndex
[
j
-
1
],
values
[
j
-
1
][
i
]);
data
.
expressionSet
.
setVariable
(
data
.
valueIndex
[
j
-
1
],
values
[
j
-
1
][
i
]);
dVdX
[
j
]
=
0.0
;
data
.
dVdX
[
j
]
=
0.0
;
dVdY
[
j
]
=
0.0
;
data
.
dVdY
[
j
]
=
0.0
;
dVdZ
[
j
]
=
0.0
;
data
.
dVdZ
[
j
]
=
0.0
;
for
(
int
k
=
1
;
k
<
j
;
k
++
)
{
for
(
int
k
=
1
;
k
<
j
;
k
++
)
{
float
dVdV
=
(
float
)
valueDerivExpressions
[
j
][
k
].
evaluate
();
float
dVdV
=
(
float
)
data
.
valueDerivExpressions
[
j
][
k
].
evaluate
();
dVdX
[
j
]
+=
dVdV
*
dVdX
[
k
];
data
.
dVdX
[
j
]
+=
dVdV
*
data
.
dVdX
[
k
];
dVdY
[
j
]
+=
dVdV
*
dVdY
[
k
];
data
.
dVdY
[
j
]
+=
dVdV
*
data
.
dVdY
[
k
];
dVdZ
[
j
]
+=
dVdV
*
dVdZ
[
k
];
data
.
dVdZ
[
j
]
+=
dVdV
*
data
.
dVdZ
[
k
];
}
}
dVdX
[
j
]
+=
(
float
)
valueGradientExpressions
[
j
][
0
].
evaluate
();
data
.
dVdX
[
j
]
+=
(
float
)
data
.
valueGradientExpressions
[
j
][
0
].
evaluate
();
dVdY
[
j
]
+=
(
float
)
valueGradientExpressions
[
j
][
1
].
evaluate
();
data
.
dVdY
[
j
]
+=
(
float
)
data
.
valueGradientExpressions
[
j
][
1
].
evaluate
();
dVdZ
[
j
]
+=
(
float
)
valueGradientExpressions
[
j
][
2
].
evaluate
();
data
.
dVdZ
[
j
]
+=
(
float
)
data
.
valueGradientExpressions
[
j
][
2
].
evaluate
();
forces
[
4
*
i
+
0
]
-=
dEdV
[
j
][
i
]
*
dVdX
[
j
];
forces
[
4
*
i
+
0
]
-=
dEdV
[
j
][
i
]
*
data
.
dVdX
[
j
];
forces
[
4
*
i
+
1
]
-=
dEdV
[
j
][
i
]
*
dVdY
[
j
];
forces
[
4
*
i
+
1
]
-=
dEdV
[
j
][
i
]
*
data
.
dVdY
[
j
];
forces
[
4
*
i
+
2
]
-=
dEdV
[
j
][
i
]
*
dVdZ
[
j
];
forces
[
4
*
i
+
2
]
-=
dEdV
[
j
][
i
]
*
data
.
dVdZ
[
j
];
}
}
}
}
}
}
void
CpuCustomGBForce
::
calculateOnePairChainRule
(
int
atom1
,
int
atom2
,
float
*
posq
,
RealOpenMM
**
atomParameters
,
void
CpuCustomGBForce
::
calculateOnePairChainRule
(
int
atom1
,
int
atom2
,
ThreadData
&
data
,
float
*
posq
,
RealOpenMM
**
atomParameters
,
const
vector
<
vector
<
float
>
>&
values
,
float
*
forces
,
vector
<
vector
<
float
>
>&
dEdV
,
bool
isExcluded
,
const
fvec4
&
boxSize
,
const
fvec4
&
invBoxSize
)
{
float
*
forces
,
bool
isExcluded
,
const
fvec4
&
boxSize
,
const
fvec4
&
invBoxSize
)
{
// Compute the displacement.
// Compute the displacement.
fvec4
deltaR
;
fvec4
deltaR
;
...
@@ -412,40 +546,40 @@ void CpuCustomGBForce::calculateOnePairChainRule(int atom1, int atom2, float* po
...
@@ -412,40 +546,40 @@ void CpuCustomGBForce::calculateOnePairChainRule(int atom1, int atom2, float* po
// Record variables for evaluating expressions.
// Record variables for evaluating expressions.
for
(
int
i
=
0
;
i
<
(
int
)
paramNames
.
size
();
i
++
)
{
for
(
int
i
=
0
;
i
<
(
int
)
paramNames
.
size
();
i
++
)
{
expressionSet
.
setVariable
(
particleParamIndex
[
i
*
2
],
atomParameters
[
atom1
][
i
]);
data
.
expressionSet
.
setVariable
(
data
.
particleParamIndex
[
i
*
2
],
atomParameters
[
atom1
][
i
]);
expressionSet
.
setVariable
(
particleParamIndex
[
i
*
2
+
1
],
atomParameters
[
atom2
][
i
]);
data
.
expressionSet
.
setVariable
(
data
.
particleParamIndex
[
i
*
2
+
1
],
atomParameters
[
atom2
][
i
]);
}
}
expressionSet
.
setVariable
(
rindex
,
r
);
data
.
expressionSet
.
setVariable
(
data
.
rindex
,
r
);
expressionSet
.
setVariable
(
particleValueIndex
[
0
],
values
[
0
][
atom1
]);
data
.
expressionSet
.
setVariable
(
data
.
particleValueIndex
[
0
],
values
[
0
][
atom1
]);
expressionSet
.
setVariable
(
particleValueIndex
[
1
],
values
[
0
][
atom2
]);
data
.
expressionSet
.
setVariable
(
data
.
particleValueIndex
[
1
],
values
[
0
][
atom2
]);
// Evaluate the derivative of each parameter with respect to position and apply forces.
// Evaluate the derivative of each parameter with respect to position and apply forces.
float
rinv
=
1
/
r
;
float
rinv
=
1
/
r
;
deltaR
*=
rinv
;
deltaR
*=
rinv
;
if
(
!
isExcluded
||
valueTypes
[
0
]
!=
CustomGBForce
::
ParticlePair
)
{
if
(
!
isExcluded
||
valueTypes
[
0
]
!=
CustomGBForce
::
ParticlePair
)
{
dVdR1
[
0
]
=
(
float
)
valueDerivExpressions
[
0
][
0
].
evaluate
();
data
.
dVdR1
[
0
]
=
(
float
)
data
.
valueDerivExpressions
[
0
][
0
].
evaluate
();
dVdR2
[
0
]
=
-
dVdR1
[
0
];
data
.
dVdR2
[
0
]
=
-
data
.
dVdR1
[
0
];
(
fvec4
(
forces
+
4
*
atom1
)
-
deltaR
*
(
dEdV
[
0
][
atom1
]
*
dVdR1
[
0
])).
store
(
forces
+
4
*
atom1
);
(
fvec4
(
forces
+
4
*
atom1
)
-
deltaR
*
(
dEdV
[
0
][
atom1
]
*
data
.
dVdR1
[
0
])).
store
(
forces
+
4
*
atom1
);
(
fvec4
(
forces
+
4
*
atom2
)
-
deltaR
*
(
dEdV
[
0
][
atom1
]
*
dVdR2
[
0
])).
store
(
forces
+
4
*
atom2
);
(
fvec4
(
forces
+
4
*
atom2
)
-
deltaR
*
(
dEdV
[
0
][
atom1
]
*
data
.
dVdR2
[
0
])).
store
(
forces
+
4
*
atom2
);
}
}
for
(
int
i
=
0
;
i
<
(
int
)
paramNames
.
size
();
i
++
)
for
(
int
i
=
0
;
i
<
(
int
)
paramNames
.
size
();
i
++
)
expressionSet
.
setVariable
(
paramIndex
[
i
],
atomParameters
[
atom1
][
i
]);
data
.
expressionSet
.
setVariable
(
data
.
paramIndex
[
i
],
atomParameters
[
atom1
][
i
]);
expressionSet
.
setVariable
(
valueIndex
[
0
],
values
[
0
][
atom1
]);
data
.
expressionSet
.
setVariable
(
data
.
valueIndex
[
0
],
values
[
0
][
atom1
]);
for
(
int
i
=
1
;
i
<
(
int
)
valueNames
.
size
();
i
++
)
{
for
(
int
i
=
1
;
i
<
(
int
)
valueNames
.
size
();
i
++
)
{
expressionSet
.
setVariable
(
valueIndex
[
i
],
values
[
i
][
atom1
]);
data
.
expressionSet
.
setVariable
(
data
.
valueIndex
[
i
],
values
[
i
][
atom1
]);
expressionSet
.
setVariable
(
xindex
,
posq
[
4
*
atom1
]);
data
.
expressionSet
.
setVariable
(
data
.
xindex
,
posq
[
4
*
atom1
]);
expressionSet
.
setVariable
(
yindex
,
posq
[
4
*
atom1
+
1
]);
data
.
expressionSet
.
setVariable
(
data
.
yindex
,
posq
[
4
*
atom1
+
1
]);
expressionSet
.
setVariable
(
zindex
,
posq
[
4
*
atom1
+
2
]);
data
.
expressionSet
.
setVariable
(
data
.
zindex
,
posq
[
4
*
atom1
+
2
]);
dVdR1
[
i
]
=
0.0
;
data
.
dVdR1
[
i
]
=
0.0
;
dVdR2
[
i
]
=
0.0
;
data
.
dVdR2
[
i
]
=
0.0
;
for
(
int
j
=
0
;
j
<
i
;
j
++
)
{
for
(
int
j
=
0
;
j
<
i
;
j
++
)
{
float
dVdV
=
(
float
)
valueDerivExpressions
[
i
][
j
].
evaluate
();
float
dVdV
=
(
float
)
data
.
valueDerivExpressions
[
i
][
j
].
evaluate
();
dVdR1
[
i
]
+=
dVdV
*
dVdR1
[
j
];
data
.
dVdR1
[
i
]
+=
dVdV
*
data
.
dVdR1
[
j
];
dVdR2
[
i
]
+=
dVdV
*
dVdR2
[
j
];
data
.
dVdR2
[
i
]
+=
dVdV
*
data
.
dVdR2
[
j
];
}
}
(
fvec4
(
forces
+
4
*
atom1
)
-
deltaR
*
(
dEdV
[
i
][
atom1
]
*
dVdR1
[
i
])).
store
(
forces
+
4
*
atom1
);
(
fvec4
(
forces
+
4
*
atom1
)
-
deltaR
*
(
dEdV
[
i
][
atom1
]
*
data
.
dVdR1
[
i
])).
store
(
forces
+
4
*
atom1
);
(
fvec4
(
forces
+
4
*
atom2
)
-
deltaR
*
(
dEdV
[
i
][
atom1
]
*
dVdR2
[
i
])).
store
(
forces
+
4
*
atom2
);
(
fvec4
(
forces
+
4
*
atom2
)
-
deltaR
*
(
dEdV
[
i
][
atom1
]
*
data
.
dVdR2
[
i
])).
store
(
forces
+
4
*
atom2
);
}
}
}
}
...
...
platforms/cpu/src/CpuKernels.cpp
View file @
6a4ac837
...
@@ -957,8 +957,8 @@ void CpuCalcCustomGBForceKernel::initialize(const System& system, const CustomGB
...
@@ -957,8 +957,8 @@ void CpuCalcCustomGBForceKernel::initialize(const System& system, const CustomGB
for
(
map
<
string
,
Lepton
::
CustomFunction
*>::
iterator
iter
=
functions
.
begin
();
iter
!=
functions
.
end
();
iter
++
)
for
(
map
<
string
,
Lepton
::
CustomFunction
*>::
iterator
iter
=
functions
.
begin
();
iter
!=
functions
.
end
();
iter
++
)
delete
iter
->
second
;
delete
iter
->
second
;
ixn
=
new
CpuCustomGBForce
(
numParticles
,
valueExpressions
,
valueDerivExpressions
,
valueGradientExpressions
,
valueNames
,
valueTypes
,
energyExpressions
,
ixn
=
new
CpuCustomGBForce
(
numParticles
,
exclusions
,
valueExpressions
,
valueDerivExpressions
,
valueGradientExpressions
,
valueNames
,
valueTypes
,
energyExpressions
,
energyDerivExpressions
,
energyGradientExpressions
,
energyTypes
,
particleParameterNames
);
energyDerivExpressions
,
energyGradientExpressions
,
energyTypes
,
particleParameterNames
,
data
.
threads
);
data
.
isPeriodic
=
(
force
.
getNonbondedMethod
()
==
CustomGBForce
::
CutoffPeriodic
);
data
.
isPeriodic
=
(
force
.
getNonbondedMethod
()
==
CustomGBForce
::
CutoffPeriodic
);
}
}
...
@@ -977,7 +977,7 @@ double CpuCalcCustomGBForceKernel::execute(ContextImpl& context, bool includeFor
...
@@ -977,7 +977,7 @@ double CpuCalcCustomGBForceKernel::execute(ContextImpl& context, bool includeFor
map
<
string
,
double
>
globalParameters
;
map
<
string
,
double
>
globalParameters
;
for
(
int
i
=
0
;
i
<
(
int
)
globalParameterNames
.
size
();
i
++
)
for
(
int
i
=
0
;
i
<
(
int
)
globalParameterNames
.
size
();
i
++
)
globalParameters
[
globalParameterNames
[
i
]]
=
context
.
getParameter
(
globalParameterNames
[
i
]);
globalParameters
[
globalParameterNames
[
i
]]
=
context
.
getParameter
(
globalParameterNames
[
i
]);
ixn
->
calculateIxn
(
numParticles
,
&
data
.
posq
[
0
],
particleParamArray
,
exclusions
,
globalParameters
,
&
data
.
threadForce
[
0
][
0
]
,
includeEnergy
?
&
energy
:
NULL
);
ixn
->
calculateIxn
(
numParticles
,
&
data
.
posq
[
0
],
particleParamArray
,
globalParameters
,
data
.
threadForce
,
includeForces
,
includeEnergy
,
energy
);
return
energy
;
return
energy
;
}
}
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment