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
14d3c584
Commit
14d3c584
authored
Aug 15, 2014
by
peastman
Browse files
Finished CPU implementation of CustomManyParticleForce
parent
be0d5cbe
Changes
6
Hide whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
124 additions
and
155 deletions
+124
-155
openmmapi/include/openmm/internal/vectorize_sse.h
openmmapi/include/openmm/internal/vectorize_sse.h
+2
-2
platforms/cpu/include/CpuCustomManyParticleForce.h
platforms/cpu/include/CpuCustomManyParticleForce.h
+54
-60
platforms/cpu/src/CpuCustomManyParticleForce.cpp
platforms/cpu/src/CpuCustomManyParticleForce.cpp
+66
-56
platforms/cpu/src/CpuKernels.cpp
platforms/cpu/src/CpuKernels.cpp
+1
-2
platforms/cpu/tests/TestCpuCustomManyParticleForce.cpp
platforms/cpu/tests/TestCpuCustomManyParticleForce.cpp
+0
-35
tests/TestVectorize.cpp
tests/TestVectorize.cpp
+1
-0
No files found.
openmmapi/include/openmm/internal/vectorize_sse.h
View file @
14d3c584
...
@@ -250,8 +250,8 @@ static inline float dot4(const fvec4& v1, const fvec4& v2) {
...
@@ -250,8 +250,8 @@ static inline float dot4(const fvec4& v1, const fvec4& v2) {
}
}
static
inline
fvec4
cross
(
const
fvec4
&
v1
,
const
fvec4
&
v2
)
{
static
inline
fvec4
cross
(
const
fvec4
&
v1
,
const
fvec4
&
v2
)
{
fvec4
temp
=
_mm_mul_ps
(
v
2
,
_mm_shuffle_ps
(
v
1
,
v
1
,
_MM_SHUFFLE
(
3
,
0
,
2
,
1
)))
-
fvec4
temp
=
_mm_mul_ps
(
v
1
,
_mm_shuffle_ps
(
v
2
,
v
2
,
_MM_SHUFFLE
(
3
,
0
,
2
,
1
)))
-
_mm_mul_ps
(
v
1
,
_mm_shuffle_ps
(
v
2
,
v
2
,
_MM_SHUFFLE
(
3
,
0
,
2
,
1
)));
_mm_mul_ps
(
v
2
,
_mm_shuffle_ps
(
v
1
,
v
1
,
_MM_SHUFFLE
(
3
,
0
,
2
,
1
)));
return
_mm_shuffle_ps
(
temp
,
temp
,
_MM_SHUFFLE
(
3
,
0
,
2
,
1
));
return
_mm_shuffle_ps
(
temp
,
temp
,
_MM_SHUFFLE
(
3
,
0
,
2
,
1
));
}
}
...
...
platforms/cpu/include/CpuCustomManyParticleForce.h
View file @
14d3c584
...
@@ -50,7 +50,7 @@ private:
...
@@ -50,7 +50,7 @@ private:
class
DihedralTermInfo
;
class
DihedralTermInfo
;
class
ComputeForceTask
;
class
ComputeForceTask
;
class
ThreadData
;
class
ThreadData
;
int
numParticlesPerSet
,
numPerParticleParameters
,
numTypes
;
int
numParticles
,
numParticlesPerSet
,
numPerParticleParameters
,
numTypes
;
bool
useCutoff
,
usePeriodic
;
bool
useCutoff
,
usePeriodic
;
RealOpenMM
cutoffDistance
;
RealOpenMM
cutoffDistance
;
RealOpenMM
periodicBoxSize
[
3
];
RealOpenMM
periodicBoxSize
[
3
];
...
@@ -62,9 +62,7 @@ private:
...
@@ -62,9 +62,7 @@ private:
std
::
vector
<
std
::
vector
<
int
>
>
particleOrder
;
std
::
vector
<
std
::
vector
<
int
>
>
particleOrder
;
std
::
vector
<
ThreadData
*>
threadData
;
std
::
vector
<
ThreadData
*>
threadData
;
// The following variables are used to make information accessible to the individual threads.
// The following variables are used to make information accessible to the individual threads.
int
numParticles
;
float
*
posq
;
float
*
posq
;
RealVec
const
*
atomCoordinates
;
RealOpenMM
**
particleParameters
;
RealOpenMM
**
particleParameters
;
const
std
::
map
<
std
::
string
,
double
>*
globalParameters
;
const
std
::
map
<
std
::
string
,
double
>*
globalParameters
;
std
::
vector
<
AlignedArray
<
float
>
>*
threadForce
;
std
::
vector
<
AlignedArray
<
float
>
>*
threadForce
;
...
@@ -76,6 +74,10 @@ private:
...
@@ -76,6 +74,10 @@ private:
*/
*/
void
threadComputeForce
(
ThreadPool
&
threads
,
int
threadIndex
);
void
threadComputeForce
(
ThreadPool
&
threads
,
int
threadIndex
);
/**
* This is called recursively to loop over all possible combination of a set of particles and evaluate the
* interaction for each one.
*/
void
loopOverInteractions
(
std
::
vector
<
int
>&
availableParticles
,
std
::
vector
<
int
>&
particleSet
,
int
loopIndex
,
int
startIndex
,
void
loopOverInteractions
(
std
::
vector
<
int
>&
availableParticles
,
std
::
vector
<
int
>&
particleSet
,
int
loopIndex
,
int
startIndex
,
RealOpenMM
**
particleParameters
,
float
*
forces
,
ThreadData
&
data
,
const
fvec4
&
boxSize
,
const
fvec4
&
invBoxSize
);
RealOpenMM
**
particleParameters
,
float
*
forces
,
ThreadData
&
data
,
const
fvec4
&
boxSize
,
const
fvec4
&
invBoxSize
);
...
@@ -85,82 +87,72 @@ private:
...
@@ -85,82 +87,72 @@ private:
@param particleSet the indices of the particles
@param particleSet the indices of the particles
@param posq atom coordinates in float format
@param posq atom coordinates in float format
@param atomCoordinates atom coordinates
@param particleParameters particle parameter values (particleParameters[particleIndex][parameterIndex])
@param particleParameters particle parameter values (particleParameters[particleIndex][parameterIndex])
@param forces force array (forces added)
@param forces force array (forces added)
@param totalEnergy total energy
@param totalEnergy total energy
--------------------------------------------------------------------------------------- */
--------------------------------------------------------------------------------------- */
void
calculateOneIxn
(
std
::
vector
<
int
>&
particleSet
,
/**
RealOpenMM
**
particleParameters
,
float
*
forces
,
ThreadData
&
data
,
const
fvec4
&
boxSize
,
const
fvec4
&
invBoxSize
);
* Calculate the interaction for one set of particles
*
* @param particleSet the indices of the particles
* @param particleParameters particle parameter values (particleParameters[particleIndex][parameterIndex])
* @param data information and workspace for the current thread
* @param boxSize the size of the periodic box
* @param invBoxSize the inverse size of the periodic box
*/
void
calculateOneIxn
(
std
::
vector
<
int
>&
particleSet
,
RealOpenMM
**
particleParameters
,
float
*
forces
,
ThreadData
&
data
,
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
* periodic boundary conditions.
* periodic boundary conditions.
*/
*/
void
getDeltaR
(
const
fvec4
&
posI
,
const
fvec4
&
posJ
,
fvec4
&
deltaR
,
float
&
r2
,
const
fvec4
&
boxSize
,
const
fvec4
&
invBoxSize
)
const
;
void
computeDelta
(
const
fvec4
&
posI
,
const
fvec4
&
posJ
,
fvec4
&
deltaR
,
float
&
r2
,
const
fvec4
&
boxSize
,
const
fvec4
&
invBoxSize
)
const
;
void
computeDelta
(
int
atom1
,
int
atom2
,
RealOpenMM
*
delta
,
const
OpenMM
::
RealVec
*
atomCoordinates
)
const
;
static
float
computeAngle
(
const
fvec4
&
vi
,
const
fvec4
&
vj
,
float
v2i
,
float
v2j
,
float
sign
);
static
RealOpenMM
computeAngle
(
RealOpenMM
*
vec1
,
RealOpenMM
*
vec2
,
float
sign
);
static
float
getDihedralAngleBetweenThreeVectors
(
const
fvec4
&
v1
,
const
fvec4
&
v2
,
const
fvec4
&
v3
,
fvec4
&
cross1
,
fvec4
&
cross2
,
const
fvec4
&
signVector
);
public:
public:
/**
/**---------------------------------------------------------------------------------------
* Create a new CpuCustomManyParticleForce.
*
Constructor
* @param force the CustomManyParticleForce to create it for
* @param threads the thread pool to use
--------------------------------------------------------------------------------------- */
*/
CpuCustomManyParticleForce
(
const
OpenMM
::
CustomManyParticleForce
&
force
,
ThreadPool
&
threads
);
CpuCustomManyParticleForce
(
const
OpenMM
::
CustomManyParticleForce
&
force
,
ThreadPool
&
threads
);
/**---------------------------------------------------------------------------------------
Destructor
--------------------------------------------------------------------------------------- */
~
CpuCustomManyParticleForce
();
~
CpuCustomManyParticleForce
();
/**---------------------------------------------------------------------------------------
/**
* Set the force to use a cutoff.
Set the force to use a cutoff.
*
* @param distance the cutoff distance
@param distance the cutoff distance
*/
--------------------------------------------------------------------------------------- */
void
setUseCutoff
(
RealOpenMM
distance
);
void
setUseCutoff
(
RealOpenMM
distance
);
/**---------------------------------------------------------------------------------------
/**
* Set the force to use periodic boundary conditions. This requires that a cutoff has
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
already been set, and the smallest side of the periodic box is at least twice the cutoff
* distance.
distance.
*
* @param boxSize the X, Y, and Z widths of the periodic box
@param boxSize the X, Y, and Z widths of the periodic box
*/
--------------------------------------------------------------------------------------- */
void
setPeriodic
(
OpenMM
::
RealVec
&
boxSize
);
void
setPeriodic
(
OpenMM
::
RealVec
&
boxSize
);
/**---------------------------------------------------------------------------------------
/**
* Calculate the interaction.
Calculate the interaction
*
* @param posq atom coordinates in float format
@param posq atom coordinates in float format
* @param particleParameters particle parameter values (particleParameters[particleIndex][parameterIndex])
@param atomCoordinates atom coordinates
* @param globalParameters the values of global parameters
@param particleParameters particle parameter values (particleParameters[particleIndex][parameterIndex])
* @param threadForce the collection of arrays for each thread to add forces to
@param globalParameters the values of global parameters
* @param includeForce whether to compute forces
@param forces force array (forces added)
* @param includeEnergy whether to compute energy
@param totalEnergy total energy
* @param energy the total energy is added to this
*/
--------------------------------------------------------------------------------------- */
void
calculateIxn
(
AlignedArray
<
float
>&
posq
,
RealOpenMM
**
particleParameters
,
const
std
::
map
<
std
::
string
,
double
>&
globalParameters
,
void
calculateIxn
(
AlignedArray
<
float
>&
posq
,
std
::
vector
<
OpenMM
::
RealVec
>&
atomCoordinates
,
RealOpenMM
**
particleParameters
,
const
std
::
map
<
std
::
string
,
double
>&
globalParameters
,
std
::
vector
<
AlignedArray
<
float
>
>&
threadForce
,
bool
includeForces
,
bool
includeEnergy
,
double
&
energy
);
std
::
vector
<
AlignedArray
<
float
>
>&
threadForce
,
bool
includeForces
,
bool
includeEnergy
,
double
&
energy
);
};
};
...
@@ -198,8 +190,7 @@ public:
...
@@ -198,8 +190,7 @@ public:
int
p1
,
p2
,
p3
,
p4
,
variableIndex
;
int
p1
,
p2
,
p3
,
p4
,
variableIndex
;
Lepton
::
CompiledExpression
forceExpression
;
Lepton
::
CompiledExpression
forceExpression
;
int
delta1
,
delta2
,
delta3
;
int
delta1
,
delta2
,
delta3
;
mutable
RealOpenMM
cross1
[
3
];
mutable
fvec4
cross1
,
cross2
;
mutable
RealOpenMM
cross2
[
3
];
DihedralTermInfo
(
const
std
::
string
&
name
,
const
std
::
vector
<
int
>&
atoms
,
const
Lepton
::
CompiledExpression
&
forceExpression
,
ThreadData
&
data
);
DihedralTermInfo
(
const
std
::
string
&
name
,
const
std
::
vector
<
int
>&
atoms
,
const
Lepton
::
CompiledExpression
&
forceExpression
,
ThreadData
&
data
);
};
};
...
@@ -213,6 +204,9 @@ public:
...
@@ -213,6 +204,9 @@ public:
std
::
vector
<
DistanceTermInfo
>
distanceTerms
;
std
::
vector
<
DistanceTermInfo
>
distanceTerms
;
std
::
vector
<
AngleTermInfo
>
angleTerms
;
std
::
vector
<
AngleTermInfo
>
angleTerms
;
std
::
vector
<
DihedralTermInfo
>
dihedralTerms
;
std
::
vector
<
DihedralTermInfo
>
dihedralTerms
;
AlignedArray
<
fvec4
>
delta
;
std
::
vector
<
float
>
normDelta
;
std
::
vector
<
float
>
norm2Delta
;
double
energy
;
double
energy
;
ThreadData
(
const
CustomManyParticleForce
&
force
,
Lepton
::
ParsedExpression
&
energyExpr
,
ThreadData
(
const
CustomManyParticleForce
&
force
,
Lepton
::
ParsedExpression
&
energyExpr
,
std
::
map
<
std
::
string
,
std
::
vector
<
int
>
>&
distances
,
std
::
map
<
std
::
string
,
std
::
vector
<
int
>
>&
angles
,
std
::
map
<
std
::
string
,
std
::
vector
<
int
>
>&
dihedrals
);
std
::
map
<
std
::
string
,
std
::
vector
<
int
>
>&
distances
,
std
::
map
<
std
::
string
,
std
::
vector
<
int
>
>&
angles
,
std
::
map
<
std
::
string
,
std
::
vector
<
int
>
>&
dihedrals
);
...
...
platforms/cpu/src/CpuCustomManyParticleForce.cpp
View file @
14d3c584
...
@@ -51,6 +51,7 @@ public:
...
@@ -51,6 +51,7 @@ public:
CpuCustomManyParticleForce
::
CpuCustomManyParticleForce
(
const
CustomManyParticleForce
&
force
,
ThreadPool
&
threads
)
:
CpuCustomManyParticleForce
::
CpuCustomManyParticleForce
(
const
CustomManyParticleForce
&
force
,
ThreadPool
&
threads
)
:
threads
(
threads
),
useCutoff
(
false
),
usePeriodic
(
false
),
neighborList
(
NULL
)
{
threads
(
threads
),
useCutoff
(
false
),
usePeriodic
(
false
),
neighborList
(
NULL
)
{
numParticles
=
force
.
getNumParticles
();
numParticlesPerSet
=
force
.
getNumParticlesPerSet
();
numParticlesPerSet
=
force
.
getNumParticlesPerSet
();
numPerParticleParameters
=
force
.
getNumPerParticleParameters
();
numPerParticleParameters
=
force
.
getNumPerParticleParameters
();
...
@@ -98,14 +99,12 @@ CpuCustomManyParticleForce::~CpuCustomManyParticleForce() {
...
@@ -98,14 +99,12 @@ CpuCustomManyParticleForce::~CpuCustomManyParticleForce() {
delete
threadData
[
i
];
delete
threadData
[
i
];
}
}
void
CpuCustomManyParticleForce
::
calculateIxn
(
AlignedArray
<
float
>&
posq
,
vector
<
RealVec
>&
atomCoordinates
,
RealOpenMM
**
particleParameters
,
void
CpuCustomManyParticleForce
::
calculateIxn
(
AlignedArray
<
float
>&
posq
,
RealOpenMM
**
particleParameters
,
const
map
<
string
,
double
>&
globalParameters
,
vector
<
AlignedArray
<
float
>
>&
threadForce
,
const
map
<
string
,
double
>&
globalParameters
,
vector
<
AlignedArray
<
float
>
>&
threadForce
,
bool
includeForces
,
bool
includeEnergy
,
double
&
energy
)
{
bool
includeForces
,
bool
includeEnergy
,
double
&
energy
)
{
// Record the parameters for the threads.
// Record the parameters for the threads.
this
->
numParticles
=
atomCoordinates
.
size
();
this
->
posq
=
&
posq
[
0
];
this
->
posq
=
&
posq
[
0
];
this
->
atomCoordinates
=
&
atomCoordinates
[
0
];
this
->
particleParameters
=
particleParameters
;
this
->
particleParameters
=
particleParameters
;
this
->
globalParameters
=
&
globalParameters
;
this
->
globalParameters
=
&
globalParameters
;
this
->
threadForce
=
&
threadForce
;
this
->
threadForce
=
&
threadForce
;
...
@@ -220,7 +219,7 @@ void CpuCustomManyParticleForce::loopOverInteractions(vector<int>& availablePart
...
@@ -220,7 +219,7 @@ void CpuCustomManyParticleForce::loopOverInteractions(vector<int>& availablePart
float
r2
;
float
r2
;
for
(
int
j
=
0
;
j
<
loopIndex
&&
include
;
j
++
)
{
for
(
int
j
=
0
;
j
<
loopIndex
&&
include
;
j
++
)
{
fvec4
pos2
(
posq
+
4
*
particleSet
[
j
]);
fvec4
pos2
(
posq
+
4
*
particleSet
[
j
]);
get
Delta
R
(
pos1
,
pos2
,
deltaR
,
r2
,
boxSize
,
invBoxSize
);
compute
Delta
(
pos1
,
pos2
,
deltaR
,
r2
,
boxSize
,
invBoxSize
);
include
&=
(
r2
<
cutoff2
);
include
&=
(
r2
<
cutoff2
);
}
}
}
}
...
@@ -266,29 +265,33 @@ void CpuCustomManyParticleForce::calculateOneIxn(vector<int>& particleSet, RealO
...
@@ -266,29 +265,33 @@ void CpuCustomManyParticleForce::calculateOneIxn(vector<int>& particleSet, RealO
// Compute inter-particle deltas.
// Compute inter-particle deltas.
int
numDeltas
=
data
.
deltaPairs
.
size
();
int
numDeltas
=
data
.
deltaPairs
.
size
();
RealOpenMM
delta
[
numDeltas
][
ReferenceForce
::
LastDeltaRIndex
];
AlignedArray
<
fvec4
>&
delta
=
data
.
delta
;
for
(
int
i
=
0
;
i
<
numDeltas
;
i
++
)
vector
<
float
>&
normDelta
=
data
.
normDelta
;
computeDelta
(
permutedParticles
[
data
.
deltaPairs
[
i
].
first
],
permutedParticles
[
data
.
deltaPairs
[
i
].
second
],
delta
[
i
],
atomCoordinates
);
vector
<
float
>&
norm2Delta
=
data
.
norm2Delta
;
for
(
int
i
=
0
;
i
<
numDeltas
;
i
++
)
{
int
p1
=
permutedParticles
[
data
.
deltaPairs
[
i
].
first
];
int
p2
=
permutedParticles
[
data
.
deltaPairs
[
i
].
second
];
computeDelta
(
fvec4
(
posq
+
4
*
p1
),
fvec4
(
posq
+
4
*
p2
),
delta
[
i
],
norm2Delta
[
i
],
boxSize
,
invBoxSize
);
normDelta
[
i
]
=
sqrtf
(
norm2Delta
[
i
]);
}
// Compute all of the variables the energy can depend on.
// Compute all of the variables the energy can depend on.
for
(
int
i
=
0
;
i
<
(
int
)
data
.
particleTerms
.
size
();
i
++
)
{
for
(
int
i
=
0
;
i
<
(
int
)
data
.
particleTerms
.
size
();
i
++
)
{
const
ParticleTermInfo
&
term
=
data
.
particleTerms
[
i
];
const
ParticleTermInfo
&
term
=
data
.
particleTerms
[
i
];
expressionSet
.
setVariable
(
term
.
variableIndex
,
atomCoordinates
[
permutedParticles
[
term
.
atom
]
][
term
.
component
]);
expressionSet
.
setVariable
(
term
.
variableIndex
,
posq
[
4
*
permutedParticles
[
term
.
atom
]
+
term
.
component
]);
}
}
for
(
int
i
=
0
;
i
<
(
int
)
data
.
distanceTerms
.
size
();
i
++
)
{
for
(
int
i
=
0
;
i
<
(
int
)
data
.
distanceTerms
.
size
();
i
++
)
{
const
DistanceTermInfo
&
term
=
data
.
distanceTerms
[
i
];
const
DistanceTermInfo
&
term
=
data
.
distanceTerms
[
i
];
expressionSet
.
setVariable
(
term
.
variableIndex
,
d
elta
[
term
.
delta
]
[
ReferenceForce
::
RIndex
]
);
expressionSet
.
setVariable
(
term
.
variableIndex
,
normD
elta
[
term
.
delta
]);
}
}
for
(
int
i
=
0
;
i
<
(
int
)
data
.
angleTerms
.
size
();
i
++
)
{
for
(
int
i
=
0
;
i
<
(
int
)
data
.
angleTerms
.
size
();
i
++
)
{
const
AngleTermInfo
&
term
=
data
.
angleTerms
[
i
];
const
AngleTermInfo
&
term
=
data
.
angleTerms
[
i
];
expressionSet
.
setVariable
(
term
.
variableIndex
,
computeAngle
(
delta
[
term
.
delta1
],
delta
[
term
.
delta2
],
term
.
delta1Sign
*
term
.
delta2Sign
));
expressionSet
.
setVariable
(
term
.
variableIndex
,
computeAngle
(
delta
[
term
.
delta1
],
delta
[
term
.
delta2
],
norm2Delta
[
term
.
delta1
],
norm2Delta
[
term
.
delta2
],
term
.
delta1Sign
*
term
.
delta2Sign
));
}
}
for
(
int
i
=
0
;
i
<
(
int
)
data
.
dihedralTerms
.
size
();
i
++
)
{
for
(
int
i
=
0
;
i
<
(
int
)
data
.
dihedralTerms
.
size
();
i
++
)
{
const
DihedralTermInfo
&
term
=
data
.
dihedralTerms
[
i
];
const
DihedralTermInfo
&
term
=
data
.
dihedralTerms
[
i
];
RealOpenMM
dotDihedral
,
signOfDihedral
;
expressionSet
.
setVariable
(
term
.
variableIndex
,
getDihedralAngleBetweenThreeVectors
(
delta
[
term
.
delta1
],
delta
[
term
.
delta2
],
delta
[
term
.
delta3
],
term
.
cross1
,
term
.
cross2
,
delta
[
term
.
delta1
]));
RealOpenMM
*
crossProduct
[]
=
{
term
.
cross1
,
term
.
cross2
};
expressionSet
.
setVariable
(
term
.
variableIndex
,
ReferenceBondIxn
::
getDihedralAngleBetweenThreeVectors
(
delta
[
term
.
delta1
],
delta
[
term
.
delta2
],
delta
[
term
.
delta3
],
crossProduct
,
&
dotDihedral
,
delta
[
term
.
delta1
],
&
signOfDihedral
,
1
));
}
}
if
(
includeForces
)
{
if
(
includeForces
)
{
...
@@ -309,8 +312,8 @@ void CpuCustomManyParticleForce::calculateOneIxn(vector<int>& particleSet, RealO
...
@@ -309,8 +312,8 @@ void CpuCustomManyParticleForce::calculateOneIxn(vector<int>& particleSet, RealO
for
(
int
i
=
0
;
i
<
(
int
)
data
.
distanceTerms
.
size
();
i
++
)
{
for
(
int
i
=
0
;
i
<
(
int
)
data
.
distanceTerms
.
size
();
i
++
)
{
const
DistanceTermInfo
&
term
=
data
.
distanceTerms
[
i
];
const
DistanceTermInfo
&
term
=
data
.
distanceTerms
[
i
];
RealOpenMM
dEdR
=
(
RealOpenMM
)
(
term
.
forceExpression
.
evaluate
()
*
term
.
deltaSign
/
(
d
elta
[
term
.
delta
]
[
ReferenceForce
::
RIndex
]
));
float
dEdR
=
(
float
)
(
term
.
forceExpression
.
evaluate
()
*
term
.
deltaSign
/
(
normD
elta
[
term
.
delta
]));
fvec4
force
=
-
dEdR
*
fvec4
((
float
)
delta
[
term
.
delta
]
[
0
],
(
float
)
delta
[
term
.
delta
][
1
],
(
float
)
delta
[
term
.
delta
][
2
],
0.0
f
)
;
fvec4
force
=
-
dEdR
*
delta
[
term
.
delta
];
f
[
term
.
p1
]
-=
force
;
f
[
term
.
p1
]
-=
force
;
f
[
term
.
p2
]
+=
force
;
f
[
term
.
p2
]
+=
force
;
}
}
...
@@ -319,17 +322,15 @@ void CpuCustomManyParticleForce::calculateOneIxn(vector<int>& particleSet, RealO
...
@@ -319,17 +322,15 @@ void CpuCustomManyParticleForce::calculateOneIxn(vector<int>& particleSet, RealO
for
(
int
i
=
0
;
i
<
(
int
)
data
.
angleTerms
.
size
();
i
++
)
{
for
(
int
i
=
0
;
i
<
(
int
)
data
.
angleTerms
.
size
();
i
++
)
{
const
AngleTermInfo
&
term
=
data
.
angleTerms
[
i
];
const
AngleTermInfo
&
term
=
data
.
angleTerms
[
i
];
RealOpenMM
dEdTheta
=
(
RealOpenMM
)
term
.
forceExpression
.
evaluate
();
float
dEdTheta
=
(
float
)
term
.
forceExpression
.
evaluate
();
fvec4
delta1
((
float
)
delta
[
term
.
delta1
][
0
],
(
float
)
delta
[
term
.
delta1
][
1
],
(
float
)
delta
[
term
.
delta1
][
2
],
0.0
f
);
fvec4
thetaCross
=
cross
(
delta
[
term
.
delta1
],
delta
[
term
.
delta2
]);
fvec4
delta2
((
float
)
delta
[
term
.
delta2
][
0
],
(
float
)
delta
[
term
.
delta2
][
1
],
(
float
)
delta
[
term
.
delta2
][
2
],
0.0
f
);
fvec4
thetaCross
=
cross
(
delta1
,
delta2
);
float
lengthThetaCross
=
sqrtf
(
dot3
(
thetaCross
,
thetaCross
));
float
lengthThetaCross
=
sqrtf
(
dot3
(
thetaCross
,
thetaCross
));
if
(
lengthThetaCross
<
1.0e-6
f
)
if
(
lengthThetaCross
<
1.0e-6
f
)
lengthThetaCross
=
1.0e-6
f
;
lengthThetaCross
=
1.0e-6
f
;
RealOpenMM
termA
=
dEdTheta
*
term
.
delta2Sign
/
(
d
elta
[
term
.
delta1
]
[
ReferenceForce
::
R2Index
]
*
lengthThetaCross
);
float
termA
=
dEdTheta
*
term
.
delta2Sign
/
(
norm2D
elta
[
term
.
delta1
]
*
lengthThetaCross
);
RealOpenMM
termC
=
-
dEdTheta
*
term
.
delta1Sign
/
(
d
elta
[
term
.
delta2
]
[
ReferenceForce
::
R2Index
]
*
lengthThetaCross
);
float
termC
=
-
dEdTheta
*
term
.
delta1Sign
/
(
norm2D
elta
[
term
.
delta2
]
*
lengthThetaCross
);
fvec4
deltaCross1
=
cross
(
delta
1
,
thetaCross
);
fvec4
deltaCross1
=
cross
(
delta
[
term
.
delta1
]
,
thetaCross
);
fvec4
deltaCross2
=
cross
(
delta
2
,
thetaCross
);
fvec4
deltaCross2
=
cross
(
delta
[
term
.
delta2
]
,
thetaCross
);
fvec4
force1
=
termA
*
deltaCross1
;
fvec4
force1
=
termA
*
deltaCross1
;
fvec4
force3
=
termC
*
deltaCross2
;
fvec4
force3
=
termC
*
deltaCross2
;
fvec4
force2
=
-
(
force1
+
force3
);
fvec4
force2
=
-
(
force1
+
force3
);
...
@@ -342,20 +343,19 @@ void CpuCustomManyParticleForce::calculateOneIxn(vector<int>& particleSet, RealO
...
@@ -342,20 +343,19 @@ void CpuCustomManyParticleForce::calculateOneIxn(vector<int>& particleSet, RealO
for
(
int
i
=
0
;
i
<
(
int
)
data
.
dihedralTerms
.
size
();
i
++
)
{
for
(
int
i
=
0
;
i
<
(
int
)
data
.
dihedralTerms
.
size
();
i
++
)
{
const
DihedralTermInfo
&
term
=
data
.
dihedralTerms
[
i
];
const
DihedralTermInfo
&
term
=
data
.
dihedralTerms
[
i
];
RealOpenMM
dEdTheta
=
(
RealOpenMM
)
term
.
forceExpression
.
evaluate
();
float
dEdTheta
=
(
float
)
term
.
forceExpression
.
evaluate
();
RealOpenMM
internalF
[
4
][
3
];
float
normCross1
=
dot3
(
term
.
cross1
,
term
.
cross1
);
RealOpenMM
forceFactors
[
4
];
float
normBC
=
normDelta
[
term
.
delta2
];
RealOpenMM
normCross1
=
DOT3
(
term
.
cross1
,
term
.
cross1
);
float
forceFactors
[
4
];
RealOpenMM
normBC
=
delta
[
term
.
delta2
][
ReferenceForce
::
RIndex
];
forceFactors
[
0
]
=
(
-
dEdTheta
*
normBC
)
/
normCross1
;
forceFactors
[
0
]
=
(
-
dEdTheta
*
normBC
)
/
normCross1
;
RealOpenMM
normCross2
=
DOT
3
(
term
.
cross2
,
term
.
cross2
);
float
normCross2
=
dot
3
(
term
.
cross2
,
term
.
cross2
);
forceFactors
[
3
]
=
(
dEdTheta
*
normBC
)
/
normCross2
;
forceFactors
[
3
]
=
(
dEdTheta
*
normBC
)
/
normCross2
;
forceFactors
[
1
]
=
DOT
3
(
delta
[
term
.
delta1
],
delta
[
term
.
delta2
]);
forceFactors
[
1
]
=
dot
3
(
delta
[
term
.
delta1
],
delta
[
term
.
delta2
]);
forceFactors
[
1
]
/=
d
elta
[
term
.
delta2
]
[
ReferenceForce
::
R2Index
]
;
forceFactors
[
1
]
/=
norm2D
elta
[
term
.
delta2
];
forceFactors
[
2
]
=
DOT
3
(
delta
[
term
.
delta3
],
delta
[
term
.
delta2
]);
forceFactors
[
2
]
=
dot
3
(
delta
[
term
.
delta3
],
delta
[
term
.
delta2
]);
forceFactors
[
2
]
/=
d
elta
[
term
.
delta2
]
[
ReferenceForce
::
R2Index
]
;
forceFactors
[
2
]
/=
norm2D
elta
[
term
.
delta2
];
fvec4
force1
=
forceFactors
[
0
]
*
fvec4
((
float
)
term
.
cross1
[
0
],
(
float
)
term
.
cross1
[
1
],
(
float
)
term
.
cross1
[
2
],
0.0
f
)
;
fvec4
force1
=
forceFactors
[
0
]
*
term
.
cross1
;
fvec4
force4
=
forceFactors
[
3
]
*
fvec4
((
float
)
term
.
cross2
[
0
],
(
float
)
term
.
cross2
[
1
],
(
float
)
term
.
cross2
[
2
],
0.0
f
)
;
fvec4
force4
=
forceFactors
[
3
]
*
term
.
cross2
;
fvec4
s
=
forceFactors
[
1
]
*
force1
-
forceFactors
[
2
]
*
force4
;
fvec4
s
=
forceFactors
[
1
]
*
force1
-
forceFactors
[
2
]
*
force4
;
f
[
term
.
p1
]
+=
force1
;
f
[
term
.
p1
]
+=
force1
;
f
[
term
.
p2
]
-=
force1
-
s
;
f
[
term
.
p2
]
-=
force1
-
s
;
...
@@ -377,27 +377,7 @@ void CpuCustomManyParticleForce::calculateOneIxn(vector<int>& particleSet, RealO
...
@@ -377,27 +377,7 @@ void CpuCustomManyParticleForce::calculateOneIxn(vector<int>& particleSet, RealO
data
.
energy
+=
data
.
energyExpression
.
evaluate
();
data
.
energy
+=
data
.
energyExpression
.
evaluate
();
}
}
void
CpuCustomManyParticleForce
::
computeDelta
(
int
atom1
,
int
atom2
,
RealOpenMM
*
delta
,
const
OpenMM
::
RealVec
*
atomCoordinates
)
const
{
void
CpuCustomManyParticleForce
::
computeDelta
(
const
fvec4
&
posI
,
const
fvec4
&
posJ
,
fvec4
&
deltaR
,
float
&
r2
,
const
fvec4
&
boxSize
,
const
fvec4
&
invBoxSize
)
const
{
if
(
usePeriodic
)
ReferenceForce
::
getDeltaRPeriodic
(
atomCoordinates
[
atom1
],
atomCoordinates
[
atom2
],
periodicBoxSize
,
delta
);
else
ReferenceForce
::
getDeltaR
(
atomCoordinates
[
atom1
],
atomCoordinates
[
atom2
],
delta
);
}
RealOpenMM
CpuCustomManyParticleForce
::
computeAngle
(
RealOpenMM
*
vec1
,
RealOpenMM
*
vec2
,
float
sign
)
{
RealOpenMM
dot
=
DOT3
(
vec1
,
vec2
)
*
sign
;
RealOpenMM
cosine
=
dot
/
SQRT
((
vec1
[
ReferenceForce
::
R2Index
]
*
vec2
[
ReferenceForce
::
R2Index
]));
RealOpenMM
angle
;
if
(
cosine
>=
1
)
angle
=
0
;
else
if
(
cosine
<=
-
1
)
angle
=
PI_M
;
else
angle
=
ACOS
(
cosine
);
return
angle
;
}
void
CpuCustomManyParticleForce
::
getDeltaR
(
const
fvec4
&
posI
,
const
fvec4
&
posJ
,
fvec4
&
deltaR
,
float
&
r2
,
const
fvec4
&
boxSize
,
const
fvec4
&
invBoxSize
)
const
{
deltaR
=
posJ
-
posI
;
deltaR
=
posJ
-
posI
;
if
(
usePeriodic
)
{
if
(
usePeriodic
)
{
fvec4
base
=
round
(
deltaR
*
invBoxSize
)
*
boxSize
;
fvec4
base
=
round
(
deltaR
*
invBoxSize
)
*
boxSize
;
...
@@ -406,6 +386,32 @@ void CpuCustomManyParticleForce::getDeltaR(const fvec4& posI, const fvec4& posJ,
...
@@ -406,6 +386,32 @@ void CpuCustomManyParticleForce::getDeltaR(const fvec4& posI, const fvec4& posJ,
r2
=
dot3
(
deltaR
,
deltaR
);
r2
=
dot3
(
deltaR
,
deltaR
);
}
}
float
CpuCustomManyParticleForce
::
computeAngle
(
const
fvec4
&
vi
,
const
fvec4
&
vj
,
float
v2i
,
float
v2j
,
float
sign
)
{
float
dot
=
dot3
(
vi
,
vj
)
*
sign
;
float
cosine
=
dot
/
sqrtf
(
v2i
*
v2j
);
if
(
cosine
>
0.99
f
||
cosine
<
-
0.99
f
)
{
// We're close to the singularity in acos(), so take the cross product and use asin() instead.
fvec4
cross12
=
cross
(
vi
,
vj
);
float
scale
=
v2i
*
v2j
;
float
angle
=
asinf
(
sqrtf
(
dot3
(
cross12
,
cross12
)
/
scale
));
if
(
cosine
<
0.0
f
)
angle
=
(
float
)
(
M_PI
-
angle
);
return
angle
;
}
return
acosf
(
cosine
);
}
float
CpuCustomManyParticleForce
::
getDihedralAngleBetweenThreeVectors
(
const
fvec4
&
v1
,
const
fvec4
&
v2
,
const
fvec4
&
v3
,
fvec4
&
cross1
,
fvec4
&
cross2
,
const
fvec4
&
signVector
)
{
cross1
=
cross
(
v1
,
v2
);
cross2
=
cross
(
v2
,
v3
);
float
angle
=
computeAngle
(
cross1
,
cross2
,
dot3
(
cross1
,
cross1
),
dot3
(
cross2
,
cross2
),
1.0
f
);
float
dotProduct
=
dot3
(
signVector
,
cross2
);
if
(
dotProduct
<
0
)
angle
=
-
angle
;
return
angle
;
}
CpuCustomManyParticleForce
::
ParticleTermInfo
::
ParticleTermInfo
(
const
string
&
name
,
int
atom
,
int
component
,
const
Lepton
::
CompiledExpression
&
forceExpression
,
ThreadData
&
data
)
:
CpuCustomManyParticleForce
::
ParticleTermInfo
::
ParticleTermInfo
(
const
string
&
name
,
int
atom
,
int
component
,
const
Lepton
::
CompiledExpression
&
forceExpression
,
ThreadData
&
data
)
:
name
(
name
),
atom
(
atom
),
component
(
component
),
forceExpression
(
forceExpression
)
{
name
(
name
),
atom
(
atom
),
component
(
component
),
forceExpression
(
forceExpression
)
{
variableIndex
=
data
.
expressionSet
.
getVariableIndex
(
name
);
variableIndex
=
data
.
expressionSet
.
getVariableIndex
(
name
);
...
@@ -471,6 +477,10 @@ CpuCustomManyParticleForce::ThreadData::ThreadData(const CustomManyParticleForce
...
@@ -471,6 +477,10 @@ CpuCustomManyParticleForce::ThreadData::ThreadData(const CustomManyParticleForce
expressionSet
.
registerExpression
(
angleTerms
[
i
].
forceExpression
);
expressionSet
.
registerExpression
(
angleTerms
[
i
].
forceExpression
);
for
(
int
i
=
0
;
i
<
dihedralTerms
.
size
();
i
++
)
for
(
int
i
=
0
;
i
<
dihedralTerms
.
size
();
i
++
)
expressionSet
.
registerExpression
(
dihedralTerms
[
i
].
forceExpression
);
expressionSet
.
registerExpression
(
dihedralTerms
[
i
].
forceExpression
);
int
numDeltas
=
deltaPairs
.
size
();
delta
.
resize
(
numDeltas
);
normDelta
.
resize
(
numDeltas
);
norm2Delta
.
resize
(
numDeltas
);
}
}
void
CpuCustomManyParticleForce
::
ThreadData
::
requestDeltaPair
(
int
p1
,
int
p2
,
int
&
pairIndex
,
float
&
pairSign
,
bool
allowReversed
)
{
void
CpuCustomManyParticleForce
::
ThreadData
::
requestDeltaPair
(
int
p1
,
int
p2
,
int
&
pairIndex
,
float
&
pairSign
,
bool
allowReversed
)
{
...
...
platforms/cpu/src/CpuKernels.cpp
View file @
14d3c584
...
@@ -869,7 +869,6 @@ void CpuCalcCustomManyParticleForceKernel::initialize(const System& system, cons
...
@@ -869,7 +869,6 @@ void CpuCalcCustomManyParticleForceKernel::initialize(const System& system, cons
}
}
double
CpuCalcCustomManyParticleForceKernel
::
execute
(
ContextImpl
&
context
,
bool
includeForces
,
bool
includeEnergy
)
{
double
CpuCalcCustomManyParticleForceKernel
::
execute
(
ContextImpl
&
context
,
bool
includeForces
,
bool
includeEnergy
)
{
vector
<
RealVec
>&
posData
=
extractPositions
(
context
);
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
]);
...
@@ -881,7 +880,7 @@ double CpuCalcCustomManyParticleForceKernel::execute(ContextImpl& context, bool
...
@@ -881,7 +880,7 @@ double CpuCalcCustomManyParticleForceKernel::execute(ContextImpl& context, bool
ixn
->
setPeriodic
(
box
);
ixn
->
setPeriodic
(
box
);
}
}
double
energy
=
0
;
double
energy
=
0
;
ixn
->
calculateIxn
(
data
.
posq
,
posData
,
particleParamArray
,
globalParameters
,
data
.
threadForce
,
includeForces
,
includeEnergy
,
energy
);
ixn
->
calculateIxn
(
data
.
posq
,
particleParamArray
,
globalParameters
,
data
.
threadForce
,
includeForces
,
includeEnergy
,
energy
);
return
energy
;
return
energy
;
}
}
...
...
platforms/cpu/tests/TestCpuCustomManyParticleForce.cpp
View file @
14d3c584
...
@@ -464,40 +464,6 @@ void testTypeFilters() {
...
@@ -464,40 +464,6 @@ void testTypeFilters() {
ASSERT_EQUAL_TOL
(
expectedEnergy
,
state
.
getPotentialEnergy
(),
1e-5
);
ASSERT_EQUAL_TOL
(
expectedEnergy
,
state
.
getPotentialEnergy
(),
1e-5
);
}
}
#include <sys/time.h>
void
benchmark
()
{
int
numParticles
=
5000
;
double
boxSize
=
5.0
;
CustomManyParticleForce
*
force
=
new
CustomManyParticleForce
(
3
,
"C*(1+3*cos(theta1)*cos(theta2)*cos(theta3))/(r12*r13*r23)^3;"
"theta1=angle(p1,p2,p3); theta2=angle(p2,p3,p1); theta3=angle(p3,p1,p2);"
"r12=distance(p1,p2); r13=distance(p1,p3); r23=distance(p2,p3)"
);
force
->
addGlobalParameter
(
"C"
,
1.5
);
force
->
setNonbondedMethod
(
CustomManyParticleForce
::
CutoffPeriodic
);
force
->
setCutoffDistance
(
0.6
);
vector
<
double
>
params
;
vector
<
Vec3
>
positions
;
System
system
;
OpenMM_SFMT
::
SFMT
sfmt
;
init_gen_rand
(
0
,
sfmt
);
for
(
int
i
=
0
;
i
<
numParticles
;
i
++
)
{
force
->
addParticle
(
params
);
positions
.
push_back
(
Vec3
(
genrand_real2
(
sfmt
),
genrand_real2
(
sfmt
),
genrand_real2
(
sfmt
))
*
boxSize
);
system
.
addParticle
(
1.0
);
}
system
.
setDefaultPeriodicBoxVectors
(
Vec3
(
boxSize
,
0
,
0
),
Vec3
(
0
,
boxSize
,
0
),
Vec3
(
0
,
0
,
boxSize
));
system
.
addForce
(
force
);
VerletIntegrator
integrator
(
0.001
);
CpuPlatform
platform
;
Context
context
(
system
,
integrator
,
platform
);
context
.
setPositions
(
positions
);
timeval
t1
,
t2
;
gettimeofday
(
&
t1
,
NULL
);
State
state
=
context
.
getState
(
State
::
Forces
|
State
::
Energy
);
gettimeofday
(
&
t2
,
NULL
);
printf
(
"%g %g
\n
"
,
state
.
getPotentialEnergy
(),
(
t2
.
tv_sec
-
t1
.
tv_sec
)
+
1e-6
*
(
t2
.
tv_usec
-
t1
.
tv_usec
));
}
int
main
()
{
int
main
()
{
try
{
try
{
testNoCutoff
();
testNoCutoff
();
...
@@ -508,7 +474,6 @@ int main() {
...
@@ -508,7 +474,6 @@ int main() {
testParameters
();
testParameters
();
testTabulatedFunctions
();
testTabulatedFunctions
();
testTypeFilters
();
testTypeFilters
();
benchmark
();
}
}
catch
(
const
exception
&
e
)
{
catch
(
const
exception
&
e
)
{
cout
<<
"exception: "
<<
e
.
what
()
<<
endl
;
cout
<<
"exception: "
<<
e
.
what
()
<<
endl
;
...
...
tests/TestVectorize.cpp
View file @
14d3c584
...
@@ -153,6 +153,7 @@ void testMathFunctions() {
...
@@ -153,6 +153,7 @@ void testMathFunctions() {
ASSERT
(
any
(
f1
>
0.5
));
ASSERT
(
any
(
f1
>
0.5
));
ASSERT
(
!
any
(
f1
>
2.0
));
ASSERT
(
!
any
(
f1
>
2.0
));
ASSERT_VEC4_EQUAL
(
blend
(
f1
,
f2
,
ivec4
(
-
1
,
0
,
-
1
,
0
)),
1.1
,
1.9
,
1.3
,
-
3.8
);
ASSERT_VEC4_EQUAL
(
blend
(
f1
,
f2
,
ivec4
(
-
1
,
0
,
-
1
,
0
)),
1.1
,
1.9
,
1.3
,
-
3.8
);
ASSERT_VEC4_EQUAL
(
cross
(
f1
,
f2
),
3.91
,
-
1.84
,
-
1.61
,
0.0
);
}
}
void
testTranspose
()
{
void
testTranspose
()
{
...
...
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