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
"platforms/cpu/vscode:/vscode.git/clone" did not exist on "7dc2ff9eb4cee8cfdd9fb7af9dd3c0a8a405c391"
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
Show 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
());
}
}
double
sum
=
0
;
return
data
;
for
(
int
i
=
0
;
i
<
numClasses
;
i
++
)
}
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
++
)
for
(
int
j
=
i
;
j
<
numClasses
;
j
++
)
sum
+=
interactionCount
[
make_pair
(
i
,
j
)]
*
integrateInteraction
(
expression
,
classes
[
i
],
classes
[
j
],
force
,
context
,
paramNames
);
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
;
for
(
int
i
=
0
;
i
<
threadSum
.
size
();
i
++
)
sum
+=
threadSum
[
i
];
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
;
sum
=
0
;
threads
.
execute
([
&
]
(
ThreadPool
&
threads
,
int
threadIndex
)
{
for
(
int
i
=
0
;
i
<
numClasses
;
i
++
)
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
++
)
for
(
int
j
=
i
;
j
<
numClasses
;
j
++
)
sum
+=
interactionCount
[
make_pair
(
i
,
j
)]
*
integrateInteraction
(
expression
,
classes
[
i
],
classes
[
j
],
force
,
context
,
paramNames
);
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
;
for
(
int
i
=
0
;
i
<
threadSum
.
size
();
i
++
)
sum
+=
threadSum
[
i
];
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