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
779400a1
Unverified
Commit
779400a1
authored
Sep 19, 2021
by
Peter Eastman
Committed by
GitHub
Sep 19, 2021
Browse files
Optimized computing long range correction for CustomNonbondedForce (#3236)
parent
b7ee3022
Changes
8
Hide whitespace changes
Inline
Side-by-side
Showing
8 changed files
with
168 additions
and
60 deletions
+168
-60
openmmapi/include/openmm/internal/CustomNonbondedForceImpl.h
openmmapi/include/openmm/internal/CustomNonbondedForceImpl.h
+21
-2
openmmapi/src/CustomNonbondedForceImpl.cpp
openmmapi/src/CustomNonbondedForceImpl.cpp
+66
-31
platforms/common/include/openmm/common/CommonKernels.h
platforms/common/include/openmm/common/CommonKernels.h
+5
-1
platforms/common/src/CommonKernels.cpp
platforms/common/src/CommonKernels.cpp
+52
-16
platforms/cpu/include/CpuKernels.h
platforms/cpu/include/CpuKernels.h
+3
-1
platforms/cpu/src/CpuKernels.cpp
platforms/cpu/src/CpuKernels.cpp
+8
-5
platforms/reference/include/ReferenceKernels.h
platforms/reference/include/ReferenceKernels.h
+2
-0
platforms/reference/src/ReferenceKernels.cpp
platforms/reference/src/ReferenceKernels.cpp
+11
-4
No files found.
openmmapi/include/openmm/internal/CustomNonbondedForceImpl.h
View file @
779400a1
...
@@ -9,7 +9,7 @@
...
@@ -9,7 +9,7 @@
* Biological Structures at Stanford, funded under the NIH Roadmap for *
* Biological Structures at Stanford, funded under the NIH Roadmap for *
* Medical Research, grant U54 GM072970. See https://simtk.org. *
* Medical Research, grant U54 GM072970. See https://simtk.org. *
* *
* *
* Portions copyright (c) 2008-201
6
Stanford University and the Authors. *
* Portions copyright (c) 2008-20
2
1 Stanford University and the Authors. *
* Authors: Peter Eastman *
* Authors: Peter Eastman *
* Contributors: *
* Contributors: *
* *
* *
...
@@ -35,6 +35,7 @@
...
@@ -35,6 +35,7 @@
#include "ForceImpl.h"
#include "ForceImpl.h"
#include "openmm/CustomNonbondedForce.h"
#include "openmm/CustomNonbondedForce.h"
#include "openmm/Kernel.h"
#include "openmm/Kernel.h"
#include "openmm/internal/ThreadPool.h"
#include "lepton/CompiledExpression.h"
#include "lepton/CompiledExpression.h"
#include <utility>
#include <utility>
#include <map>
#include <map>
...
@@ -48,6 +49,7 @@ namespace OpenMM {
...
@@ -48,6 +49,7 @@ namespace OpenMM {
class
OPENMM_EXPORT
CustomNonbondedForceImpl
:
public
ForceImpl
{
class
OPENMM_EXPORT
CustomNonbondedForceImpl
:
public
ForceImpl
{
public:
public:
class
LongRangeCorrectionData
;
CustomNonbondedForceImpl
(
const
CustomNonbondedForce
&
owner
);
CustomNonbondedForceImpl
(
const
CustomNonbondedForce
&
owner
);
~
CustomNonbondedForceImpl
();
~
CustomNonbondedForceImpl
();
void
initialize
(
ContextImpl
&
context
);
void
initialize
(
ContextImpl
&
context
);
...
@@ -61,12 +63,19 @@ public:
...
@@ -61,12 +63,19 @@ public:
std
::
map
<
std
::
string
,
double
>
getDefaultParameters
();
std
::
map
<
std
::
string
,
double
>
getDefaultParameters
();
std
::
vector
<
std
::
string
>
getKernelNames
();
std
::
vector
<
std
::
string
>
getKernelNames
();
void
updateParametersInContext
(
ContextImpl
&
context
);
void
updateParametersInContext
(
ContextImpl
&
context
);
/**
* Prepare for computing the long range correction. This function pre-computes anything
* that depends only on the Force (such as particle parameters) but not on information in
* the Context (such as global parameters). This allows the coefficient to be updated
* more quickly when global parameters change.
*/
static
LongRangeCorrectionData
prepareLongRangeCorrection
(
const
CustomNonbondedForce
&
force
);
/**
/**
* Compute the coefficient which, when divided by the periodic box volume, gives the
* Compute the coefficient which, when divided by the periodic box volume, gives the
* long range correction to the energy. If the Force computes parameter derivatives,
* long range correction to the energy. If the Force computes parameter derivatives,
* also compute the corresponding derivatives of the correction.
* also compute the corresponding derivatives of the correction.
*/
*/
static
void
calcLongRangeCorrection
(
const
CustomNonbondedForce
&
force
,
const
Context
&
context
,
double
&
coefficient
,
std
::
vector
<
double
>&
derivatives
);
static
void
calcLongRangeCorrection
(
const
CustomNonbondedForce
&
force
,
LongRangeCorrectionData
&
data
,
const
Context
&
context
,
double
&
coefficient
,
std
::
vector
<
double
>&
derivatives
,
ThreadPool
&
threads
);
private:
private:
static
double
integrateInteraction
(
Lepton
::
CompiledExpression
&
expression
,
const
std
::
vector
<
double
>&
params1
,
const
std
::
vector
<
double
>&
params2
,
static
double
integrateInteraction
(
Lepton
::
CompiledExpression
&
expression
,
const
std
::
vector
<
double
>&
params1
,
const
std
::
vector
<
double
>&
params2
,
const
CustomNonbondedForce
&
force
,
const
Context
&
context
,
const
std
::
vector
<
std
::
string
>&
paramNames
);
const
CustomNonbondedForce
&
force
,
const
Context
&
context
,
const
std
::
vector
<
std
::
string
>&
paramNames
);
...
@@ -74,6 +83,16 @@ private:
...
@@ -74,6 +83,16 @@ private:
Kernel
kernel
;
Kernel
kernel
;
};
};
class
CustomNonbondedForceImpl
::
LongRangeCorrectionData
{
public:
CustomNonbondedForce
::
NonbondedMethod
method
;
std
::
vector
<
std
::
vector
<
double
>
>
classes
;
std
::
vector
<
std
::
string
>
paramNames
;
std
::
map
<
std
::
pair
<
int
,
int
>
,
long
long
int
>
interactionCount
;
Lepton
::
CompiledExpression
energyExpression
;
std
::
vector
<
Lepton
::
CompiledExpression
>
derivExpressions
;
};
}
// namespace OpenMM
}
// namespace OpenMM
#endif
/*OPENMM_CUSTOMNONBONDEDFORCEIMPL_H_*/
#endif
/*OPENMM_CUSTOMNONBONDEDFORCEIMPL_H_*/
openmmapi/src/CustomNonbondedForceImpl.cpp
View file @
779400a1
...
@@ -6,7 +6,7 @@
...
@@ -6,7 +6,7 @@
* Biological Structures at Stanford, funded under the NIH Roadmap for *
* Biological Structures at Stanford, funded under the NIH Roadmap for *
* Medical Research, grant U54 GM072970. See https://simtk.org. *
* Medical Research, grant U54 GM072970. See https://simtk.org. *
* *
* *
* Portions copyright (c) 2008-201
6
Stanford University and the Authors. *
* Portions copyright (c) 2008-20
2
1 Stanford University and the Authors. *
* Authors: Peter Eastman *
* Authors: Peter Eastman *
* Contributors: *
* Contributors: *
* *
* *
...
@@ -40,6 +40,7 @@
...
@@ -40,6 +40,7 @@
#include "ReferenceTabulatedFunction.h"
#include "ReferenceTabulatedFunction.h"
#include "lepton/ParsedExpression.h"
#include "lepton/ParsedExpression.h"
#include "lepton/Parser.h"
#include "lepton/Parser.h"
#include <atomic>
#include <cmath>
#include <cmath>
#include <sstream>
#include <sstream>
#include <utility>
#include <utility>
...
@@ -158,16 +159,15 @@ void CustomNonbondedForceImpl::updateParametersInContext(ContextImpl& context) {
...
@@ -158,16 +159,15 @@ void CustomNonbondedForceImpl::updateParametersInContext(ContextImpl& context) {
context
.
systemChanged
();
context
.
systemChanged
();
}
}
void
CustomNonbondedForceImpl
::
calc
LongRangeCorrection
(
const
CustomNonbondedForce
&
force
,
const
Context
&
context
,
double
&
coefficient
,
vector
<
double
>&
derivatives
)
{
CustomNonbondedForceImpl
::
LongRangeCorrection
Data
CustomNonbondedForce
Impl
::
prepareLongRangeCorrection
(
const
CustomNonbondedForce
&
force
)
{
if
(
force
.
getNonbondedMethod
()
==
CustomNonbondedForce
::
NoCutoff
||
force
.
getNonbondedMethod
()
==
CustomNonbondedForce
::
CutoffNonPeriodic
)
{
LongRangeCorrectionData
data
;
coefficient
=
0.0
;
data
.
method
=
force
.
getNonbondedMethod
()
;
return
;
if
(
data
.
method
==
CustomNonbondedForce
::
NoCutoff
||
data
.
method
==
CustomNonbondedForce
::
CutoffNonPeriodic
)
}
return
data
;
// Identify all particle classes (defined by parameters), and record the class of each particle.
// Identify all particle classes (defined by parameters), and record the class of each particle.
int
numParticles
=
force
.
getNumParticles
();
int
numParticles
=
force
.
getNumParticles
();
vector
<
vector
<
double
>
>
classes
;
map
<
vector
<
double
>
,
int
>
classIndex
;
map
<
vector
<
double
>
,
int
>
classIndex
;
vector
<
int
>
atomClass
(
numParticles
);
vector
<
int
>
atomClass
(
numParticles
);
vector
<
double
>
parameters
;
vector
<
double
>
parameters
;
...
@@ -175,18 +175,17 @@ void CustomNonbondedForceImpl::calcLongRangeCorrection(const CustomNonbondedForc
...
@@ -175,18 +175,17 @@ void CustomNonbondedForceImpl::calcLongRangeCorrection(const CustomNonbondedForc
force
.
getParticleParameters
(
i
,
parameters
);
force
.
getParticleParameters
(
i
,
parameters
);
map
<
vector
<
double
>
,
int
>::
iterator
entry
=
classIndex
.
find
(
parameters
);
map
<
vector
<
double
>
,
int
>::
iterator
entry
=
classIndex
.
find
(
parameters
);
if
(
entry
==
classIndex
.
end
())
{
if
(
entry
==
classIndex
.
end
())
{
classIndex
[
parameters
]
=
classes
.
size
();
classIndex
[
parameters
]
=
data
.
classes
.
size
();
atomClass
[
i
]
=
classes
.
size
();
atomClass
[
i
]
=
data
.
classes
.
size
();
classes
.
push_back
(
parameters
);
data
.
classes
.
push_back
(
parameters
);
}
}
else
else
atomClass
[
i
]
=
entry
->
second
;
atomClass
[
i
]
=
entry
->
second
;
}
}
int
numClasses
=
classes
.
size
();
int
numClasses
=
data
.
classes
.
size
();
// Count the total number of particle pairs for each pair of classes.
// Count the total number of particle pairs for each pair of classes.
map
<
pair
<
int
,
int
>
,
long
long
int
>
interactionCount
;
if
(
force
.
getNumInteractionGroups
()
==
0
)
{
if
(
force
.
getNumInteractionGroups
()
==
0
)
{
// Count the particles of each class.
// Count the particles of each class.
...
@@ -194,9 +193,9 @@ void CustomNonbondedForceImpl::calcLongRangeCorrection(const CustomNonbondedForc
...
@@ -194,9 +193,9 @@ void CustomNonbondedForceImpl::calcLongRangeCorrection(const CustomNonbondedForc
for
(
int
i
=
0
;
i
<
numParticles
;
i
++
)
for
(
int
i
=
0
;
i
<
numParticles
;
i
++
)
classCounts
[
atomClass
[
i
]]
++
;
classCounts
[
atomClass
[
i
]]
++
;
for
(
int
i
=
0
;
i
<
numClasses
;
i
++
)
{
for
(
int
i
=
0
;
i
<
numClasses
;
i
++
)
{
interactionCount
[
make_pair
(
i
,
i
)]
=
(
classCounts
[
i
]
*
(
classCounts
[
i
]
+
1
))
/
2
;
data
.
interactionCount
[
make_pair
(
i
,
i
)]
=
(
classCounts
[
i
]
*
(
classCounts
[
i
]
+
1
))
/
2
;
for
(
int
j
=
i
+
1
;
j
<
numClasses
;
j
++
)
for
(
int
j
=
i
+
1
;
j
<
numClasses
;
j
++
)
interactionCount
[
make_pair
(
i
,
j
)]
=
classCounts
[
i
]
*
classCounts
[
j
];
data
.
interactionCount
[
make_pair
(
i
,
j
)]
=
classCounts
[
i
]
*
classCounts
[
j
];
}
}
}
}
else
{
else
{
...
@@ -204,7 +203,7 @@ void CustomNonbondedForceImpl::calcLongRangeCorrection(const CustomNonbondedForc
...
@@ -204,7 +203,7 @@ void CustomNonbondedForceImpl::calcLongRangeCorrection(const CustomNonbondedForc
for
(
int
i
=
0
;
i
<
numClasses
;
i
++
)
{
for
(
int
i
=
0
;
i
<
numClasses
;
i
++
)
{
for
(
int
j
=
i
;
j
<
numClasses
;
j
++
)
for
(
int
j
=
i
;
j
<
numClasses
;
j
++
)
interactionCount
[
make_pair
(
i
,
j
)]
=
0
;
data
.
interactionCount
[
make_pair
(
i
,
j
)]
=
0
;
}
}
// Loop over interaction groups and count the interactions in each one.
// Loop over interaction groups and count the interactions in each one.
...
@@ -218,44 +217,80 @@ void CustomNonbondedForceImpl::calcLongRangeCorrection(const CustomNonbondedForc
...
@@ -218,44 +217,80 @@ void CustomNonbondedForceImpl::calcLongRangeCorrection(const CustomNonbondedForc
continue
;
continue
;
int
class1
=
atomClass
[
*
a1
];
int
class1
=
atomClass
[
*
a1
];
int
class2
=
atomClass
[
*
a2
];
int
class2
=
atomClass
[
*
a2
];
interactionCount
[
make_pair
(
min
(
class1
,
class2
),
max
(
class1
,
class2
))]
++
;
data
.
interactionCount
[
make_pair
(
min
(
class1
,
class2
),
max
(
class1
,
class2
))]
++
;
}
}
}
}
}
}
//
Compute the coefficient
.
//
Prepare for evaluating the expressions
.
map
<
string
,
Lepton
::
CustomFunction
*>
functions
;
map
<
string
,
Lepton
::
CustomFunction
*>
functions
;
for
(
int
i
=
0
;
i
<
force
.
getNumFunctions
();
i
++
)
for
(
int
i
=
0
;
i
<
force
.
getNumFunctions
();
i
++
)
functions
[
force
.
getTabulatedFunctionName
(
i
)]
=
createReferenceTabulatedFunction
(
force
.
getTabulatedFunction
(
i
));
functions
[
force
.
getTabulatedFunctionName
(
i
)]
=
createReferenceTabulatedFunction
(
force
.
getTabulatedFunction
(
i
));
double
nPart
=
(
double
)
numParticles
;
data
.
energyExpression
=
Lepton
::
Parser
::
parse
(
force
.
getEnergyFunction
(),
functions
).
createCompiledExpression
();
double
numInteractions
=
(
nPart
*
(
nPart
+
1
))
/
2
;
for
(
int
k
=
0
;
k
<
force
.
getNumEnergyParameterDerivatives
();
k
++
)
Lepton
::
CompiledExpression
expression
=
Lepton
::
Parser
::
parse
(
force
.
getEnergyFunction
(),
functions
).
createCompiledExpression
();
data
.
derivExpressions
.
push_back
(
Lepton
::
Parser
::
parse
(
force
.
getEnergyFunction
(),
functions
).
differentiate
(
force
.
getEnergyParameterDerivativeName
(
k
)).
createCompiledExpression
());
vector
<
string
>
paramNames
;
for
(
int
i
=
0
;
i
<
force
.
getNumPerParticleParameters
();
i
++
)
{
for
(
int
i
=
0
;
i
<
force
.
getNumPerParticleParameters
();
i
++
)
{
stringstream
name1
,
name2
;
stringstream
name1
,
name2
;
name1
<<
force
.
getPerParticleParameterName
(
i
)
<<
1
;
name1
<<
force
.
getPerParticleParameterName
(
i
)
<<
1
;
name2
<<
force
.
getPerParticleParameterName
(
i
)
<<
2
;
name2
<<
force
.
getPerParticleParameterName
(
i
)
<<
2
;
paramNames
.
push_back
(
name1
.
str
());
data
.
paramNames
.
push_back
(
name1
.
str
());
paramNames
.
push_back
(
name2
.
str
());
data
.
paramNames
.
push_back
(
name2
.
str
());
}
return
data
;
}
void
CustomNonbondedForceImpl
::
calcLongRangeCorrection
(
const
CustomNonbondedForce
&
force
,
LongRangeCorrectionData
&
data
,
const
Context
&
context
,
double
&
coefficient
,
vector
<
double
>&
derivatives
,
ThreadPool
&
threads
)
{
if
(
data
.
method
==
CustomNonbondedForce
::
NoCutoff
||
data
.
method
==
CustomNonbondedForce
::
CutoffNonPeriodic
)
{
coefficient
=
0.0
;
return
;
}
}
// Compute the coefficient. Use multiple threads to compute the integrals in parallel.
int
numClasses
=
data
.
classes
.
size
();
double
nPart
=
(
double
)
context
.
getSystem
().
getNumParticles
();
double
numInteractions
=
(
nPart
*
(
nPart
+
1
))
/
2
;
vector
<
double
>
threadSum
(
threads
.
getNumThreads
(),
0.0
);
atomic
<
int
>
atomicCounter
(
0
);
threads
.
execute
([
&
]
(
ThreadPool
&
threads
,
int
threadIndex
)
{
Lepton
::
CompiledExpression
expression
=
data
.
energyExpression
;
while
(
true
)
{
int
i
=
atomicCounter
++
;
if
(
i
>=
numClasses
)
break
;
for
(
int
j
=
i
;
j
<
numClasses
;
j
++
)
threadSum
[
threadIndex
]
+=
data
.
interactionCount
.
at
(
make_pair
(
i
,
j
))
*
integrateInteraction
(
expression
,
data
.
classes
[
i
],
data
.
classes
[
j
],
force
,
context
,
data
.
paramNames
);
}
});
threads
.
waitForThreads
();
double
sum
=
0
;
double
sum
=
0
;
for
(
int
i
=
0
;
i
<
numClasses
;
i
++
)
for
(
int
i
=
0
;
i
<
threadSum
.
size
();
i
++
)
for
(
int
j
=
i
;
j
<
numClasses
;
j
++
)
sum
+=
threadSum
[
i
];
sum
+=
interactionCount
[
make_pair
(
i
,
j
)]
*
integrateInteraction
(
expression
,
classes
[
i
],
classes
[
j
],
force
,
context
,
paramNames
);
sum
/=
numInteractions
;
sum
/=
numInteractions
;
coefficient
=
2
*
M_PI
*
nPart
*
nPart
*
sum
;
coefficient
=
2
*
M_PI
*
nPart
*
nPart
*
sum
;
// Now do the same for parameter derivatives.
// Now do the same for parameter derivatives.
int
numDerivs
=
force
.
getNumEnergyParameterDerivatives
();
int
numDerivs
=
data
.
derivExpressions
.
size
();
derivatives
.
resize
(
numDerivs
);
derivatives
.
resize
(
numDerivs
);
for
(
int
k
=
0
;
k
<
numDerivs
;
k
++
)
{
for
(
int
k
=
0
;
k
<
numDerivs
;
k
++
)
{
expression
=
Lepton
::
Parser
::
parse
(
force
.
getEnergyFunction
(),
functions
).
differentiate
(
force
.
getEnergyParameterDerivativeName
(
k
)).
createCompiledExpression
();
atomicCounter
=
0
;
threads
.
execute
([
&
]
(
ThreadPool
&
threads
,
int
threadIndex
)
{
threadSum
[
threadIndex
]
=
0
;
Lepton
::
CompiledExpression
expression
=
data
.
derivExpressions
[
k
];
while
(
true
)
{
int
i
=
atomicCounter
++
;
if
(
i
>=
numClasses
)
break
;
for
(
int
j
=
i
;
j
<
numClasses
;
j
++
)
threadSum
[
threadIndex
]
+=
data
.
interactionCount
.
at
(
make_pair
(
i
,
j
))
*
integrateInteraction
(
expression
,
data
.
classes
[
i
],
data
.
classes
[
j
],
force
,
context
,
data
.
paramNames
);
}
});
threads
.
waitForThreads
();
sum
=
0
;
sum
=
0
;
for
(
int
i
=
0
;
i
<
numClasses
;
i
++
)
for
(
int
i
=
0
;
i
<
threadSum
.
size
();
i
++
)
for
(
int
j
=
i
;
j
<
numClasses
;
j
++
)
sum
+=
threadSum
[
i
];
sum
+=
interactionCount
[
make_pair
(
i
,
j
)]
*
integrateInteraction
(
expression
,
classes
[
i
],
classes
[
j
],
force
,
context
,
paramNames
);
sum
/=
numInteractions
;
sum
/=
numInteractions
;
derivatives
[
k
]
=
2
*
M_PI
*
nPart
*
nPart
*
sum
;
derivatives
[
k
]
=
2
*
M_PI
*
nPart
*
nPart
*
sum
;
}
}
...
...
platforms/common/include/openmm/common/CommonKernels.h
View file @
779400a1
...
@@ -9,7 +9,7 @@
...
@@ -9,7 +9,7 @@
* Biological Structures at Stanford, funded under the NIH Roadmap for *
* Biological Structures at Stanford, funded under the NIH Roadmap for *
* Medical Research, grant U54 GM072970. See https://simtk.org. *
* Medical Research, grant U54 GM072970. See https://simtk.org. *
* *
* *
* Portions copyright (c) 2008-202
0
Stanford University and the Authors. *
* Portions copyright (c) 2008-202
1
Stanford University and the Authors. *
* Authors: Peter Eastman *
* Authors: Peter Eastman *
* Contributors: *
* Contributors: *
* *
* *
...
@@ -34,6 +34,7 @@
...
@@ -34,6 +34,7 @@
#include "openmm/kernels.h"
#include "openmm/kernels.h"
#include "openmm/internal/CompiledExpressionSet.h"
#include "openmm/internal/CompiledExpressionSet.h"
#include "openmm/internal/CustomIntegratorUtilities.h"
#include "openmm/internal/CustomIntegratorUtilities.h"
#include "openmm/internal/CustomNonbondedForceImpl.h"
#include "lepton/CompiledExpression.h"
#include "lepton/CompiledExpression.h"
#include "lepton/ExpressionProgram.h"
#include "lepton/ExpressionProgram.h"
...
@@ -616,6 +617,8 @@ public:
...
@@ -616,6 +617,8 @@ public:
void
copyParametersToContext
(
ContextImpl
&
context
,
const
CustomNonbondedForce
&
force
);
void
copyParametersToContext
(
ContextImpl
&
context
,
const
CustomNonbondedForce
&
force
);
private:
private:
class
ForceInfo
;
class
ForceInfo
;
class
LongRangePostComputation
;
class
LongRangeTask
;
void
initInteractionGroups
(
const
CustomNonbondedForce
&
force
,
const
std
::
string
&
interactionSource
,
const
std
::
vector
<
std
::
string
>&
tableTypes
);
void
initInteractionGroups
(
const
CustomNonbondedForce
&
force
,
const
std
::
string
&
interactionSource
,
const
std
::
vector
<
std
::
string
>&
tableTypes
);
ComputeContext
&
cc
;
ComputeContext
&
cc
;
ForceInfo
*
info
;
ForceInfo
*
info
;
...
@@ -631,6 +634,7 @@ private:
...
@@ -631,6 +634,7 @@ private:
bool
hasInitializedLongRangeCorrection
,
hasInitializedKernel
,
hasParamDerivs
,
useNeighborList
;
bool
hasInitializedLongRangeCorrection
,
hasInitializedKernel
,
hasParamDerivs
,
useNeighborList
;
int
numGroupThreadBlocks
;
int
numGroupThreadBlocks
;
CustomNonbondedForce
*
forceCopy
;
CustomNonbondedForce
*
forceCopy
;
CustomNonbondedForceImpl
::
LongRangeCorrectionData
longRangeCorrectionData
;
const
System
&
system
;
const
System
&
system
;
};
};
...
...
platforms/common/src/CommonKernels.cpp
View file @
779400a1
...
@@ -34,7 +34,6 @@
...
@@ -34,7 +34,6 @@
#include "openmm/internal/CustomCompoundBondForceImpl.h"
#include "openmm/internal/CustomCompoundBondForceImpl.h"
#include "openmm/internal/CustomHbondForceImpl.h"
#include "openmm/internal/CustomHbondForceImpl.h"
#include "openmm/internal/CustomManyParticleForceImpl.h"
#include "openmm/internal/CustomManyParticleForceImpl.h"
#include "openmm/internal/CustomNonbondedForceImpl.h"
#include "CommonKernelSources.h"
#include "CommonKernelSources.h"
#include "lepton/CustomFunction.h"
#include "lepton/CustomFunction.h"
#include "lepton/ExpressionTreeNode.h"
#include "lepton/ExpressionTreeNode.h"
...
@@ -1771,6 +1770,47 @@ private:
...
@@ -1771,6 +1770,47 @@ private:
vector<set<int> > groupsForParticle;
vector<set<int> > groupsForParticle;
};
};
class CommonCalcCustomNonbondedForceKernel::LongRangePostComputation : public ComputeContext::ForcePostComputation {
public:
LongRangePostComputation(ComputeContext& cc, double& longRangeCoefficient, vector<double>& longRangeCoefficientDerivs, CustomNonbondedForce* force) :
cc(cc), longRangeCoefficient(longRangeCoefficient), longRangeCoefficientDerivs(longRangeCoefficientDerivs), force(force) {
}
double computeForceAndEnergy(bool includeForces, bool includeEnergy, int groups) {
cc.getWorkThread().flush();
Vec3 a, b, c;
cc.getPeriodicBoxVectors(a, b, c);
double volume = a[0]*b[1]*c[2];
map<string, double>& derivs = cc.getEnergyParamDerivWorkspace();
for (int i = 0; i < longRangeCoefficientDerivs.size(); i++)
derivs[force->getEnergyParameterDerivativeName(i)] += longRangeCoefficientDerivs[i]/volume;
return longRangeCoefficient/volume;
}
private:
ComputeContext& cc;
double& longRangeCoefficient;
vector<double>& longRangeCoefficientDerivs;
CustomNonbondedForce* force;
};
class CommonCalcCustomNonbondedForceKernel::LongRangeTask : public ComputeContext::WorkTask {
public:
LongRangeTask(ComputeContext& cc, Context& context, CustomNonbondedForceImpl::LongRangeCorrectionData& data,
double& longRangeCoefficient, vector<double>& longRangeCoefficientDerivs, CustomNonbondedForce* force) :
cc(cc), context(context), data(data), longRangeCoefficient(longRangeCoefficient),
longRangeCoefficientDerivs(longRangeCoefficientDerivs), force(force) {
}
void execute() {
CustomNonbondedForceImpl::calcLongRangeCorrection(*force, data, context, longRangeCoefficient, longRangeCoefficientDerivs, cc.getThreadPool());
}
private:
ComputeContext& cc;
Context& context;
CustomNonbondedForceImpl::LongRangeCorrectionData& data;
double& longRangeCoefficient;
vector<double>& longRangeCoefficientDerivs;
CustomNonbondedForce* force;
};
CommonCalcCustomNonbondedForceKernel::~CommonCalcCustomNonbondedForceKernel() {
CommonCalcCustomNonbondedForceKernel::~CommonCalcCustomNonbondedForceKernel() {
cc.setAsCurrent();
cc.setAsCurrent();
if (params != NULL)
if (params != NULL)
...
@@ -1912,6 +1952,8 @@ void CommonCalcCustomNonbondedForceKernel::initialize(const System& system, cons
...
@@ -1912,6 +1952,8 @@ void CommonCalcCustomNonbondedForceKernel::initialize(const System& system, cons
if (force.getNonbondedMethod() == CustomNonbondedForce::CutoffPeriodic && force.getUseLongRangeCorrection() && cc.getContextIndex() == 0) {
if (force.getNonbondedMethod() == CustomNonbondedForce::CutoffPeriodic && force.getUseLongRangeCorrection() && cc.getContextIndex() == 0) {
forceCopy = new CustomNonbondedForce(force);
forceCopy = new CustomNonbondedForce(force);
longRangeCorrectionData = CustomNonbondedForceImpl::prepareLongRangeCorrection(force);
cc.addPostComputation(new LongRangePostComputation(cc, longRangeCoefficient, longRangeCoefficientDerivs, forceCopy));
hasInitializedLongRangeCorrection = false;
hasInitializedLongRangeCorrection = false;
}
}
else {
else {
...
@@ -2199,6 +2241,7 @@ double CommonCalcCustomNonbondedForceKernel::execute(ContextImpl& context, bool
...
@@ -2199,6 +2241,7 @@ double CommonCalcCustomNonbondedForceKernel::execute(ContextImpl& context, bool
// When using a neighbor list, run the whole calculation on a single device.
// When using a neighbor list, run the whole calculation on a single device.
return 0.0;
return 0.0;
}
}
bool recomputeLongRangeCorrection = !hasInitializedLongRangeCorrection;
if (globals.isInitialized()) {
if (globals.isInitialized()) {
bool changed = false;
bool changed = false;
for (int i = 0; i < (int) globalParamNames.size(); i++) {
for (int i = 0; i < (int) globalParamNames.size(); i++) {
...
@@ -2209,14 +2252,12 @@ double CommonCalcCustomNonbondedForceKernel::execute(ContextImpl& context, bool
...
@@ -2209,14 +2252,12 @@ double CommonCalcCustomNonbondedForceKernel::execute(ContextImpl& context, bool
}
}
if (changed) {
if (changed) {
globals.upload(globalParamValues);
globals.upload(globalParamValues);
if
(
forceCopy
!=
NULL
)
{
if (forceCopy != NULL)
CustomNonbondedForceImpl
::
calcLongRangeCorrection
(
*
forceCopy
,
context
.
getOwner
(),
longRangeCoefficient
,
longRangeCoefficientDerivs
);
recomputeLongRangeCorrection = true;
hasInitializedLongRangeCorrection
=
true
;
}
}
}
}
}
if
(
!
hasInitialized
LongRangeCorrection
)
{
if (
recompute
LongRangeCorrection) {
CustomNonbondedForceImpl
::
calcLongRangeCorrection
(
*
forceCopy
,
context
.
getOwner
(),
longRangeCoefficient
,
longRangeCoefficientDerivs
);
cc.getWorkThread().addTask(new LongRangeTask(cc
, context.getOwner(),
longRangeCorrectionData,
longRangeCoefficient, longRangeCoefficientDerivs
, forceCopy)
);
hasInitializedLongRangeCorrection = true;
hasInitializedLongRangeCorrection = true;
}
}
if (interactionGroupData.isInitialized()) {
if (interactionGroupData.isInitialized()) {
...
@@ -2264,13 +2305,7 @@ double CommonCalcCustomNonbondedForceKernel::execute(ContextImpl& context, bool
...
@@ -2264,13 +2305,7 @@ double CommonCalcCustomNonbondedForceKernel::execute(ContextImpl& context, bool
setPeriodicBoxArgs(cc, interactionGroupKernel, 6);
setPeriodicBoxArgs(cc, interactionGroupKernel, 6);
interactionGroupKernel->execute(numGroupThreadBlocks*forceThreadBlockSize, forceThreadBlockSize);
interactionGroupKernel->execute(numGroupThreadBlocks*forceThreadBlockSize, forceThreadBlockSize);
}
}
Vec3
a
,
b
,
c
;
return 0;
cc
.
getPeriodicBoxVectors
(
a
,
b
,
c
);
double
volume
=
a
[
0
]
*
b
[
1
]
*
c
[
2
];
map
<
string
,
double
>&
derivs
=
cc
.
getEnergyParamDerivWorkspace
();
for
(
int
i
=
0
;
i
<
longRangeCoefficientDerivs
.
size
();
i
++
)
derivs
[
forceCopy
->
getEnergyParameterDerivativeName
(
i
)]
+=
longRangeCoefficientDerivs
[
i
]
/
volume
;
return
longRangeCoefficient
/
volume
;
}
}
void CommonCalcCustomNonbondedForceKernel::copyParametersToContext(ContextImpl& context, const CustomNonbondedForce& force) {
void CommonCalcCustomNonbondedForceKernel::copyParametersToContext(ContextImpl& context, const CustomNonbondedForce& force) {
...
@@ -2296,8 +2331,9 @@ void CommonCalcCustomNonbondedForceKernel::copyParametersToContext(ContextImpl&
...
@@ -2296,8 +2331,9 @@ void CommonCalcCustomNonbondedForceKernel::copyParametersToContext(ContextImpl&
// If necessary, recompute the long range correction.
// If necessary, recompute the long range correction.
if (forceCopy != NULL) {
if (forceCopy != NULL) {
CustomNonbondedForceImpl
::
calcLongRangeCorrection
(
force
,
context
.
getOwner
(),
longRangeCoefficient
,
longRangeCoefficientDerivs
);
longRangeCorrectionData = CustomNonbondedForceImpl::prepareLongRangeCorrection(force);
hasInitializedLongRangeCorrection
=
true
;
CustomNonbondedForceImpl::calcLongRangeCorrection(force, longRangeCorrectionData, context.getOwner(), longRangeCoefficient, longRangeCoefficientDerivs, cc.getThreadPool());
hasInitializedLongRangeCorrection = false;
*forceCopy = force;
*forceCopy = force;
}
}
...
...
platforms/cpu/include/CpuKernels.h
View file @
779400a1
...
@@ -9,7 +9,7 @@
...
@@ -9,7 +9,7 @@
* Biological Structures at Stanford, funded under the NIH Roadmap for *
* Biological Structures at Stanford, funded under the NIH Roadmap for *
* Medical Research, grant U54 GM072970. See https://simtk.org. *
* Medical Research, grant U54 GM072970. See https://simtk.org. *
* *
* *
* Portions copyright (c) 2013-202
0
Stanford University and the Authors. *
* Portions copyright (c) 2013-202
1
Stanford University and the Authors. *
* Authors: Peter Eastman *
* Authors: Peter Eastman *
* Contributors: *
* Contributors: *
* *
* *
...
@@ -45,6 +45,7 @@
...
@@ -45,6 +45,7 @@
#include "CpuPlatform.h"
#include "CpuPlatform.h"
#include "openmm/kernels.h"
#include "openmm/kernels.h"
#include "openmm/System.h"
#include "openmm/System.h"
#include "openmm/internal/CustomNonbondedForceImpl.h"
#include <array>
#include <array>
#include <tuple>
#include <tuple>
...
@@ -326,6 +327,7 @@ private:
...
@@ -326,6 +327,7 @@ private:
double
nonbondedCutoff
,
switchingDistance
,
periodicBoxSize
[
3
],
longRangeCoefficient
;
double
nonbondedCutoff
,
switchingDistance
,
periodicBoxSize
[
3
],
longRangeCoefficient
;
bool
useSwitchingFunction
,
hasInitializedLongRangeCorrection
;
bool
useSwitchingFunction
,
hasInitializedLongRangeCorrection
;
CustomNonbondedForce
*
forceCopy
;
CustomNonbondedForce
*
forceCopy
;
CustomNonbondedForceImpl
::
LongRangeCorrectionData
longRangeCorrectionData
;
std
::
map
<
std
::
string
,
double
>
globalParamValues
;
std
::
map
<
std
::
string
,
double
>
globalParamValues
;
std
::
vector
<
std
::
set
<
int
>
>
exclusions
;
std
::
vector
<
std
::
set
<
int
>
>
exclusions
;
std
::
vector
<
std
::
string
>
parameterNames
,
globalParameterNames
,
energyParamDerivNames
;
std
::
vector
<
std
::
string
>
parameterNames
,
globalParameterNames
,
energyParamDerivNames
;
...
...
platforms/cpu/src/CpuKernels.cpp
View file @
779400a1
...
@@ -6,7 +6,7 @@
...
@@ -6,7 +6,7 @@
* Biological Structures at Stanford, funded under the NIH Roadmap for *
* Biological Structures at Stanford, funded under the NIH Roadmap for *
* Medical Research, grant U54 GM072970. See https://simtk.org. *
* Medical Research, grant U54 GM072970. See https://simtk.org. *
* *
* *
* Portions copyright (c) 2013-202
0
Stanford University and the Authors. *
* Portions copyright (c) 2013-202
1
Stanford University and the Authors. *
* Authors: Peter Eastman *
* Authors: Peter Eastman *
* Contributors: *
* Contributors: *
* *
* *
...
@@ -43,7 +43,6 @@
...
@@ -43,7 +43,6 @@
#include "openmm/OpenMMException.h"
#include "openmm/OpenMMException.h"
#include "openmm/Vec3.h"
#include "openmm/Vec3.h"
#include "openmm/internal/ContextImpl.h"
#include "openmm/internal/ContextImpl.h"
#include "openmm/internal/CustomNonbondedForceImpl.h"
#include "openmm/internal/NonbondedForceImpl.h"
#include "openmm/internal/NonbondedForceImpl.h"
#include "openmm/internal/vectorize.h"
#include "openmm/internal/vectorize.h"
#include "lepton/CompiledExpression.h"
#include "lepton/CompiledExpression.h"
...
@@ -975,10 +974,13 @@ double CpuCalcCustomNonbondedForceKernel::execute(ContextImpl& context, bool inc
...
@@ -975,10 +974,13 @@ double CpuCalcCustomNonbondedForceKernel::execute(ContextImpl& context, bool inc
// Add in the long range correction.
// Add in the long range correction.
if
(
!
hasInitializedLongRangeCorrection
||
(
globalParamsChanged
&&
forceCopy
!=
NULL
))
{
if
(
!
hasInitializedLongRangeCorrection
)
{
CustomNonbondedForceImpl
::
calcLongRangeCorrection
(
*
forceCopy
,
context
.
getOwner
(),
longRangeCoefficient
,
longRangeCoefficientDerivs
);
longRangeCorrectionData
=
CustomNonbondedForceImpl
::
prepareLongRangeCorrection
(
*
forceCopy
);
CustomNonbondedForceImpl
::
calcLongRangeCorrection
(
*
forceCopy
,
longRangeCorrectionData
,
context
.
getOwner
(),
longRangeCoefficient
,
longRangeCoefficientDerivs
,
data
.
threads
);
hasInitializedLongRangeCorrection
=
true
;
hasInitializedLongRangeCorrection
=
true
;
}
}
else
if
(
globalParamsChanged
&&
forceCopy
!=
NULL
)
CustomNonbondedForceImpl
::
calcLongRangeCorrection
(
*
forceCopy
,
longRangeCorrectionData
,
context
.
getOwner
(),
longRangeCoefficient
,
longRangeCoefficientDerivs
,
data
.
threads
);
double
volume
=
boxVectors
[
0
][
0
]
*
boxVectors
[
1
][
1
]
*
boxVectors
[
2
][
2
];
double
volume
=
boxVectors
[
0
][
0
]
*
boxVectors
[
1
][
1
]
*
boxVectors
[
2
][
2
];
energy
+=
longRangeCoefficient
/
volume
;
energy
+=
longRangeCoefficient
/
volume
;
for
(
int
i
=
0
;
i
<
longRangeCoefficientDerivs
.
size
();
i
++
)
for
(
int
i
=
0
;
i
<
longRangeCoefficientDerivs
.
size
();
i
++
)
...
@@ -1004,7 +1006,8 @@ void CpuCalcCustomNonbondedForceKernel::copyParametersToContext(ContextImpl& con
...
@@ -1004,7 +1006,8 @@ void CpuCalcCustomNonbondedForceKernel::copyParametersToContext(ContextImpl& con
// If necessary, recompute the long range correction.
// If necessary, recompute the long range correction.
if
(
forceCopy
!=
NULL
)
{
if
(
forceCopy
!=
NULL
)
{
CustomNonbondedForceImpl
::
calcLongRangeCorrection
(
force
,
context
.
getOwner
(),
longRangeCoefficient
,
longRangeCoefficientDerivs
);
longRangeCorrectionData
=
CustomNonbondedForceImpl
::
prepareLongRangeCorrection
(
force
);
CustomNonbondedForceImpl
::
calcLongRangeCorrection
(
force
,
longRangeCorrectionData
,
context
.
getOwner
(),
longRangeCoefficient
,
longRangeCoefficientDerivs
,
data
.
threads
);
hasInitializedLongRangeCorrection
=
true
;
hasInitializedLongRangeCorrection
=
true
;
*
forceCopy
=
force
;
*
forceCopy
=
force
;
}
}
...
...
platforms/reference/include/ReferenceKernels.h
View file @
779400a1
...
@@ -34,6 +34,7 @@
...
@@ -34,6 +34,7 @@
#include "ReferencePlatform.h"
#include "ReferencePlatform.h"
#include "openmm/kernels.h"
#include "openmm/kernels.h"
#include "openmm/internal/CustomNonbondedForceImpl.h"
#include "SimTKOpenMMRealType.h"
#include "SimTKOpenMMRealType.h"
#include "ReferenceNeighborList.h"
#include "ReferenceNeighborList.h"
#include "lepton/CompiledExpression.h"
#include "lepton/CompiledExpression.h"
...
@@ -686,6 +687,7 @@ private:
...
@@ -686,6 +687,7 @@ private:
double
nonbondedCutoff
,
switchingDistance
,
periodicBoxSize
[
3
],
longRangeCoefficient
;
double
nonbondedCutoff
,
switchingDistance
,
periodicBoxSize
[
3
],
longRangeCoefficient
;
bool
useSwitchingFunction
,
hasInitializedLongRangeCorrection
;
bool
useSwitchingFunction
,
hasInitializedLongRangeCorrection
;
CustomNonbondedForce
*
forceCopy
;
CustomNonbondedForce
*
forceCopy
;
CustomNonbondedForceImpl
::
LongRangeCorrectionData
longRangeCorrectionData
;
std
::
map
<
std
::
string
,
double
>
globalParamValues
;
std
::
map
<
std
::
string
,
double
>
globalParamValues
;
std
::
vector
<
std
::
set
<
int
>
>
exclusions
;
std
::
vector
<
std
::
set
<
int
>
>
exclusions
;
Lepton
::
CompiledExpression
energyExpression
,
forceExpression
;
Lepton
::
CompiledExpression
energyExpression
,
forceExpression
;
...
...
platforms/reference/src/ReferenceKernels.cpp
View file @
779400a1
...
@@ -76,7 +76,6 @@
...
@@ -76,7 +76,6 @@
#include "openmm/internal/CustomCentroidBondForceImpl.h"
#include "openmm/internal/CustomCentroidBondForceImpl.h"
#include "openmm/internal/CustomCompoundBondForceImpl.h"
#include "openmm/internal/CustomCompoundBondForceImpl.h"
#include "openmm/internal/CustomHbondForceImpl.h"
#include "openmm/internal/CustomHbondForceImpl.h"
#include "openmm/internal/CustomNonbondedForceImpl.h"
#include "openmm/internal/CMAPTorsionForceImpl.h"
#include "openmm/internal/CMAPTorsionForceImpl.h"
#include "openmm/internal/NonbondedForceImpl.h"
#include "openmm/internal/NonbondedForceImpl.h"
#include "openmm/Integrator.h"
#include "openmm/Integrator.h"
...
@@ -1260,10 +1259,16 @@ double ReferenceCalcCustomNonbondedForceKernel::execute(ContextImpl& context, bo
...
@@ -1260,10 +1259,16 @@ double ReferenceCalcCustomNonbondedForceKernel::execute(ContextImpl& context, bo
// Add in the long range correction.
// Add in the long range correction.
if
(
!
hasInitializedLongRangeCorrection
||
(
globalParamsChanged
&&
forceCopy
!=
NULL
))
{
if
(
!
hasInitializedLongRangeCorrection
)
{
CustomNonbondedForceImpl
::
calcLongRangeCorrection
(
*
forceCopy
,
context
.
getOwner
(),
longRangeCoefficient
,
longRangeCoefficientDerivs
);
longRangeCorrectionData
=
CustomNonbondedForceImpl
::
prepareLongRangeCorrection
(
*
forceCopy
);
ThreadPool
threads
;
CustomNonbondedForceImpl
::
calcLongRangeCorrection
(
*
forceCopy
,
longRangeCorrectionData
,
context
.
getOwner
(),
longRangeCoefficient
,
longRangeCoefficientDerivs
,
threads
);
hasInitializedLongRangeCorrection
=
true
;
hasInitializedLongRangeCorrection
=
true
;
}
}
else
if
(
globalParamsChanged
&&
forceCopy
!=
NULL
)
{
ThreadPool
threads
;
CustomNonbondedForceImpl
::
calcLongRangeCorrection
(
*
forceCopy
,
longRangeCorrectionData
,
context
.
getOwner
(),
longRangeCoefficient
,
longRangeCoefficientDerivs
,
threads
);
}
double
volume
=
boxVectors
[
0
][
0
]
*
boxVectors
[
1
][
1
]
*
boxVectors
[
2
][
2
];
double
volume
=
boxVectors
[
0
][
0
]
*
boxVectors
[
1
][
1
]
*
boxVectors
[
2
][
2
];
energy
+=
longRangeCoefficient
/
volume
;
energy
+=
longRangeCoefficient
/
volume
;
for
(
int
i
=
0
;
i
<
longRangeCoefficientDerivs
.
size
();
i
++
)
for
(
int
i
=
0
;
i
<
longRangeCoefficientDerivs
.
size
();
i
++
)
...
@@ -1289,7 +1294,9 @@ void ReferenceCalcCustomNonbondedForceKernel::copyParametersToContext(ContextImp
...
@@ -1289,7 +1294,9 @@ void ReferenceCalcCustomNonbondedForceKernel::copyParametersToContext(ContextImp
// If necessary, recompute the long range correction.
// If necessary, recompute the long range correction.
if
(
forceCopy
!=
NULL
)
{
if
(
forceCopy
!=
NULL
)
{
CustomNonbondedForceImpl
::
calcLongRangeCorrection
(
force
,
context
.
getOwner
(),
longRangeCoefficient
,
longRangeCoefficientDerivs
);
longRangeCorrectionData
=
CustomNonbondedForceImpl
::
prepareLongRangeCorrection
(
force
);
ThreadPool
threads
;
CustomNonbondedForceImpl
::
calcLongRangeCorrection
(
force
,
longRangeCorrectionData
,
context
.
getOwner
(),
longRangeCoefficient
,
longRangeCoefficientDerivs
,
threads
);
hasInitializedLongRangeCorrection
=
true
;
hasInitializedLongRangeCorrection
=
true
;
*
forceCopy
=
force
;
*
forceCopy
=
force
;
}
}
...
...
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