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
eae8def5
Commit
eae8def5
authored
Jul 27, 2016
by
Peter Eastman
Browse files
Began CUDA implementation of parameter derivatives
parent
e47cf907
Changes
9
Hide whitespace changes
Inline
Side-by-side
Showing
9 changed files
with
202 additions
and
16 deletions
+202
-16
platforms/cuda/include/CudaBondedUtilities.h
platforms/cuda/include/CudaBondedUtilities.h
+11
-1
platforms/cuda/include/CudaContext.h
platforms/cuda/include/CudaContext.h
+31
-1
platforms/cuda/include/CudaNonbondedUtilities.h
platforms/cuda/include/CudaNonbondedUtilities.h
+11
-1
platforms/cuda/src/CudaBondedUtilities.cpp
platforms/cuda/src/CudaBondedUtilities.cpp
+27
-2
platforms/cuda/src/CudaContext.cpp
platforms/cuda/src/CudaContext.cpp
+20
-1
platforms/cuda/src/CudaKernels.cpp
platforms/cuda/src/CudaKernels.cpp
+58
-4
platforms/cuda/src/CudaNonbondedUtilities.cpp
platforms/cuda/src/CudaNonbondedUtilities.cpp
+30
-1
platforms/cuda/src/kernels/customNonbonded.cu
platforms/cuda/src/kernels/customNonbonded.cu
+8
-5
platforms/cuda/src/kernels/nonbonded.cu
platforms/cuda/src/kernels/nonbonded.cu
+6
-0
No files found.
platforms/cuda/include/CudaBondedUtilities.h
View file @
eae8def5
...
...
@@ -9,7 +9,7 @@
* Biological Structures at Stanford, funded under the NIH Roadmap for *
* Medical Research, grant U54 GM072970. See https://simtk.org. *
* *
* Portions copyright (c) 2011-201
5
Stanford University and the Authors. *
* Portions copyright (c) 2011-201
6
Stanford University and the Authors. *
* Authors: Peter Eastman *
* Contributors: *
* *
...
...
@@ -100,6 +100,15 @@ public:
* refer to it by this name.
*/
std
::
string
addArgument
(
CUdeviceptr
data
,
const
std
::
string
&
type
);
/**
* Register that the interaction kernel will be computing the derivative of the potential energy
* with respect to a parameter.
*
* @param param the name of the parameter
* @return the variable that will be used to accumulate the derivative. Any code you pass to addInteraction() should
* add its contributions to this variable.
*/
std
::
string
addEnergyParameterDerivative
(
const
std
::
string
&
param
);
/**
* Add some Cuda code that should be included in the program, before the start of the kernel.
* This can be used, for example, to define functions that will be called by the kernel.
...
...
@@ -129,6 +138,7 @@ private:
std
::
vector
<
std
::
string
>
argTypes
;
std
::
vector
<
std
::
vector
<
CudaArray
*>
>
atomIndices
;
std
::
vector
<
std
::
string
>
prefixCode
;
std
::
vector
<
std
::
string
>
energyParameterDerivatives
;
std
::
vector
<
void
*>
kernelArgs
;
int
numForceBuffers
,
maxBonds
,
allGroups
;
bool
hasInitializedKernels
,
hasInteractions
;
...
...
platforms/cuda/include/CudaContext.h
View file @
eae8def5
...
...
@@ -9,7 +9,7 @@
* Biological Structures at Stanford, funded under the NIH Roadmap for *
* Medical Research, grant U54 GM072970. See https://simtk.org. *
* *
* Portions copyright (c) 2009-201
5
Stanford University and the Authors. *
* Portions copyright (c) 2009-201
6
Stanford University and the Authors. *
* Authors: Peter Eastman *
* Contributors: *
* *
...
...
@@ -177,6 +177,12 @@ public:
CudaArray
&
getEnergyBuffer
()
{
return
*
energyBuffer
;
}
/**
* Get the array which contains the buffer in which derivatives of the energy with respect to parameters are computed.
*/
CudaArray
&
getEnergyParamDerivBuffer
()
{
return
*
energyParamDerivBuffer
;
}
/**
* Get a pointer to a block of pinned memory that can be used for efficient transfers between host and device.
* This is guaranteed to be at least as large as any of the arrays returned by methods of this class.
...
...
@@ -544,6 +550,27 @@ public:
std
::
vector
<
ForcePostComputation
*>&
getPostComputations
()
{
return
postComputations
;
}
/**
* Get the names of all parameters with respect to which energy derivatives are computed.
*/
const
std
::
vector
<
std
::
string
>&
getEnergyParamDerivNames
()
const
{
return
energyParamDerivNames
;
}
/**
* Get a workspace data structure used for accumulating the values of derivatives of the energy
* with respect to parameters.
*/
std
::
map
<
std
::
string
,
double
>&
getEnergyParamDerivWorkspace
()
{
return
energyParamDerivWorkspace
;
}
/**
* Register that the derivative of potential energy with respect to a context parameter
* will need to be calculated. If this is called multiple times for a single parameter,
* it is only added to the list once.
*
* @param param the name of the parameter to add
*/
void
addEnergyParameterDerivative
(
const
std
::
string
&
param
);
/**
* Mark that the current molecule definitions (and hence the atom order) may be invalid.
* This should be called whenever force field parameters change. It will cause the definitions
...
...
@@ -609,7 +636,10 @@ private:
CudaArray
*
velm
;
CudaArray
*
force
;
CudaArray
*
energyBuffer
;
CudaArray
*
energyParamDerivBuffer
;
CudaArray
*
atomIndexDevice
;
std
::
vector
<
std
::
string
>
energyParamDerivNames
;
std
::
map
<
std
::
string
,
double
>
energyParamDerivWorkspace
;
std
::
vector
<
int
>
atomIndex
;
std
::
vector
<
CUdeviceptr
>
autoclearBuffers
;
std
::
vector
<
int
>
autoclearBufferSizes
;
...
...
platforms/cuda/include/CudaNonbondedUtilities.h
View file @
eae8def5
...
...
@@ -9,7 +9,7 @@
* Biological Structures at Stanford, funded under the NIH Roadmap for *
* Medical Research, grant U54 GM072970. See https://simtk.org. *
* *
* Portions copyright (c) 2009-201
3
Stanford University and the Authors. *
* Portions copyright (c) 2009-201
6
Stanford University and the Authors. *
* Authors: Peter Eastman *
* Contributors: *
* *
...
...
@@ -88,6 +88,15 @@ public:
* Add an array (other than a per-atom parameter) that should be passed as an argument to the default interaction kernel.
*/
void
addArgument
(
const
ParameterInfo
&
parameter
);
/**
* Register that the interaction kernel will be computing the derivative of the potential energy
* with respect to a parameter.
*
* @param param the name of the parameter
* @return the variable that will be used to accumulate the derivative. Any code you pass to addInteraction() should
* add its contributions to this variable.
*/
std
::
string
addEnergyParameterDerivative
(
const
std
::
string
&
param
);
/**
* Specify the list of exclusions that an interaction outside the default kernel will depend on.
*
...
...
@@ -275,6 +284,7 @@ private:
std
::
vector
<
std
::
vector
<
int
>
>
atomExclusions
;
std
::
vector
<
ParameterInfo
>
parameters
;
std
::
vector
<
ParameterInfo
>
arguments
;
std
::
vector
<
std
::
string
>
energyParameterDerivatives
;
std
::
map
<
int
,
double
>
groupCutoff
;
std
::
map
<
int
,
std
::
string
>
groupKernelSource
;
double
lastCutoff
;
...
...
platforms/cuda/src/CudaBondedUtilities.cpp
View file @
eae8def5
...
...
@@ -6,7 +6,7 @@
* Biological Structures at Stanford, funded under the NIH Roadmap for *
* Medical Research, grant U54 GM072970. See https://simtk.org. *
* *
* Portions copyright (c) 2011-201
5
Stanford University and the Authors. *
* Portions copyright (c) 2011-201
6
Stanford University and the Authors. *
* Authors: Peter Eastman *
* Contributors: *
* *
...
...
@@ -52,12 +52,25 @@ void CudaBondedUtilities::addInteraction(const vector<vector<int> >& atoms, cons
}
}
std
::
string
CudaBondedUtilities
::
addArgument
(
CUdeviceptr
data
,
const
string
&
type
)
{
string
CudaBondedUtilities
::
addArgument
(
CUdeviceptr
data
,
const
string
&
type
)
{
arguments
.
push_back
(
data
);
argTypes
.
push_back
(
type
);
return
"customArg"
+
context
.
intToString
(
arguments
.
size
());
}
string
CudaBondedUtilities
::
addEnergyParameterDerivative
(
const
string
&
param
)
{
// See if the parameter has already been added.
int
index
;
for
(
index
=
0
;
index
<
energyParameterDerivatives
.
size
();
index
++
)
if
(
param
==
energyParameterDerivatives
[
index
])
break
;
if
(
index
==
energyParameterDerivatives
.
size
())
energyParameterDerivatives
.
push_back
(
param
);
context
.
addEnergyParameterDerivative
(
param
);
return
string
(
"energyParamDeriv"
)
+
context
.
intToString
(
index
);
}
void
CudaBondedUtilities
::
addPrefixCode
(
const
string
&
source
)
{
for
(
int
i
=
0
;
i
<
(
int
)
prefixCode
.
size
();
i
++
)
if
(
prefixCode
[
i
]
==
source
)
...
...
@@ -109,11 +122,21 @@ void CudaBondedUtilities::initialize(const System& system) {
}
for
(
int
i
=
0
;
i
<
(
int
)
arguments
.
size
();
i
++
)
s
<<
", "
<<
argTypes
[
i
]
<<
"* customArg"
<<
(
i
+
1
);
if
(
energyParameterDerivatives
.
size
()
>
0
)
s
<<
", mixed* __restrict__ energyParamDerivs"
;
s
<<
") {
\n
"
;
s
<<
"mixed energy = 0;
\n
"
;
for
(
int
i
=
0
;
i
<
energyParameterDerivatives
.
size
();
i
++
)
s
<<
"mixed energyParamDeriv"
<<
i
<<
" = 0;
\n
"
;
for
(
int
force
=
0
;
force
<
numForces
;
force
++
)
s
<<
createForceSource
(
force
,
forceAtoms
[
force
].
size
(),
forceAtoms
[
force
][
0
].
size
(),
forceGroup
[
force
],
forceSource
[
force
]);
s
<<
"energyBuffer[blockIdx.x*blockDim.x+threadIdx.x] += energy;
\n
"
;
const
vector
<
string
>&
allParamDerivNames
=
context
.
getEnergyParamDerivNames
();
int
numDerivs
=
allParamDerivNames
.
size
();
for
(
int
i
=
0
;
i
<
energyParameterDerivatives
.
size
();
i
++
)
for
(
int
index
=
0
;
index
<
numDerivs
;
index
++
)
if
(
allParamDerivNames
[
index
]
==
energyParameterDerivatives
[
i
])
s
<<
"energyParamDerivs[(blockIdx.x*blockDim.x+threadIdx.x)*"
<<
numDerivs
<<
"+"
<<
index
<<
"] += energyParamDeriv"
<<
i
<<
";
\n
"
;
s
<<
"}
\n
"
;
map
<
string
,
string
>
defines
;
defines
[
"PADDED_NUM_ATOMS"
]
=
context
.
intToString
(
context
.
getPaddedNumAtoms
());
...
...
@@ -171,6 +194,8 @@ void CudaBondedUtilities::computeInteractions(int groups) {
kernelArgs
.
push_back
(
&
atomIndices
[
i
][
j
]
->
getDevicePointer
());
for
(
int
i
=
0
;
i
<
(
int
)
arguments
.
size
();
i
++
)
kernelArgs
.
push_back
(
&
arguments
[
i
]);
if
(
energyParameterDerivatives
.
size
()
>
0
)
kernelArgs
.
push_back
(
&
context
.
getEnergyParamDerivBuffer
().
getDevicePointer
());
}
if
(
!
hasInteractions
)
return
;
...
...
platforms/cuda/src/CudaContext.cpp
View file @
eae8def5
...
...
@@ -76,7 +76,7 @@ bool CudaContext::hasInitializedCuda = false;
CudaContext
::
CudaContext
(
const
System
&
system
,
int
deviceIndex
,
bool
useBlockingSync
,
const
string
&
precision
,
const
string
&
compiler
,
const
string
&
tempDir
,
const
std
::
string
&
hostCompiler
,
CudaPlatform
::
PlatformData
&
platformData
)
:
system
(
system
),
currentStream
(
0
),
time
(
0.0
),
platformData
(
platformData
),
stepCount
(
0
),
computeForceCount
(
0
),
stepsSinceReorder
(
99999
),
contextIsValid
(
false
),
atomsWereReordered
(
false
),
hasCompilerKernel
(
false
),
pinnedBuffer
(
NULL
),
posq
(
NULL
),
posqCorrection
(
NULL
),
velm
(
NULL
),
force
(
NULL
),
energyBuffer
(
NULL
),
atomIndexDevice
(
NULL
),
integration
(
NULL
),
expression
(
NULL
),
bonded
(
NULL
),
nonbonded
(
NULL
),
thread
(
NULL
)
{
pinnedBuffer
(
NULL
),
posq
(
NULL
),
posqCorrection
(
NULL
),
velm
(
NULL
),
force
(
NULL
),
energyBuffer
(
NULL
),
energyParamDerivBuffer
(
NULL
),
atomIndexDevice
(
NULL
),
integration
(
NULL
),
expression
(
NULL
),
bonded
(
NULL
),
nonbonded
(
NULL
),
thread
(
NULL
)
{
this
->
compiler
=
"
\"
"
+
compiler
+
"
\"
"
;
if
(
platformData
.
context
!=
NULL
)
{
try
{
...
...
@@ -339,6 +339,8 @@ CudaContext::~CudaContext() {
delete
force
;
if
(
energyBuffer
!=
NULL
)
delete
energyBuffer
;
if
(
energyParamDerivBuffer
!=
NULL
)
delete
energyParamDerivBuffer
;
if
(
atomIndexDevice
!=
NULL
)
delete
atomIndexDevice
;
if
(
integration
!=
NULL
)
...
...
@@ -390,6 +392,14 @@ void CudaContext::initialize() {
force
=
CudaArray
::
create
<
long
long
>
(
*
this
,
paddedNumAtoms
*
3
,
"force"
);
addAutoclearBuffer
(
force
->
getDevicePointer
(),
force
->
getSize
()
*
force
->
getElementSize
());
addAutoclearBuffer
(
energyBuffer
->
getDevicePointer
(),
energyBuffer
->
getSize
()
*
energyBuffer
->
getElementSize
());
int
numEnergyParamDerivs
=
energyParamDerivNames
.
size
();
if
(
numEnergyParamDerivs
>
0
)
{
if
(
useDoublePrecision
||
useMixedPrecision
)
energyParamDerivBuffer
=
CudaArray
::
create
<
double
>
(
*
this
,
numEnergyParamDerivs
*
numEnergyBuffers
,
"energyParamDerivBuffer"
);
else
energyParamDerivBuffer
=
CudaArray
::
create
<
float
>
(
*
this
,
numEnergyParamDerivs
*
numEnergyBuffers
,
"energyParamDerivBuffer"
);
addAutoclearBuffer
(
*
energyParamDerivBuffer
);
}
atomIndexDevice
=
CudaArray
::
create
<
int
>
(
*
this
,
paddedNumAtoms
,
"atomIndex"
);
atomIndex
.
resize
(
paddedNumAtoms
);
for
(
int
i
=
0
;
i
<
paddedNumAtoms
;
++
i
)
...
...
@@ -1311,6 +1321,15 @@ void CudaContext::addPostComputation(ForcePostComputation* computation) {
postComputations
.
push_back
(
computation
);
}
void
CudaContext
::
addEnergyParameterDerivative
(
const
string
&
param
)
{
// See if this parameter has already been registered.
for
(
int
i
=
0
;
i
<
energyParamDerivNames
.
size
();
i
++
)
if
(
param
==
energyParamDerivNames
[
i
])
return
;
energyParamDerivNames
.
push_back
(
param
);
}
struct
CudaContext
::
WorkThread
::
ThreadData
{
ThreadData
(
std
::
queue
<
CudaContext
::
WorkTask
*>&
tasks
,
bool
&
waiting
,
bool
&
finished
,
pthread_mutex_t
&
queueLock
,
pthread_cond_t
&
waitForTaskCondition
,
pthread_cond_t
&
queueEmptyCondition
)
:
...
...
platforms/cuda/src/CudaKernels.cpp
View file @
eae8def5
...
...
@@ -43,6 +43,7 @@
#include "CudaIntegrationUtilities.h"
#include "CudaNonbondedUtilities.h"
#include "CudaKernelSources.h"
#include "lepton/CustomFunction.h"
#include "lepton/ExpressionTreeNode.h"
#include "lepton/Operation.h"
#include "lepton/Parser.h"
...
...
@@ -55,8 +56,7 @@
using
namespace
OpenMM
;
using
namespace
std
;
using
Lepton
::
ExpressionTreeNode
;
using
Lepton
::
Operation
;
using
namespace
Lepton
;
#define CHECK_RESULT(result, prefix) \
if (result != CUDA_SUCCESS) { \
...
...
@@ -102,6 +102,9 @@ void CudaCalcForcesAndEnergyKernel::beginComputation(ContextImpl& context, bool
CudaNonbondedUtilities
&
nb
=
cu
.
getNonbondedUtilities
();
cu
.
setComputeForceCount
(
cu
.
getComputeForceCount
()
+
1
);
nb
.
prepareInteractions
(
groups
);
map
<
string
,
double
>&
derivs
=
cu
.
getEnergyParamDerivWorkspace
();
for
(
map
<
string
,
double
>::
const_iterator
iter
=
context
.
getParameters
().
begin
();
iter
!=
context
.
getParameters
().
end
();
++
iter
)
derivs
[
iter
->
first
]
=
0
;
}
double
CudaCalcForcesAndEnergyKernel
::
finishComputation
(
ContextImpl
&
context
,
bool
includeForces
,
bool
includeEnergy
,
int
groups
,
bool
&
valid
)
{
...
...
@@ -340,7 +343,30 @@ void CudaUpdateStateDataKernel::getForces(ContextImpl& context, vector<Vec3>& fo
}
void
CudaUpdateStateDataKernel
::
getEnergyParameterDerivatives
(
ContextImpl
&
context
,
map
<
string
,
double
>&
derivs
)
{
const
vector
<
string
>&
paramDerivNames
=
cu
.
getEnergyParamDerivNames
();
int
numDerivs
=
paramDerivNames
.
size
();
if
(
numDerivs
==
0
)
return
;
derivs
=
cu
.
getEnergyParamDerivWorkspace
();
CudaArray
&
derivArray
=
cu
.
getEnergyParamDerivBuffer
();
if
(
cu
.
getUseDoublePrecision
()
||
cu
.
getUseMixedPrecision
())
{
vector
<
double
>
derivBuffers
;
derivArray
.
download
(
derivBuffers
);
for
(
int
i
=
numDerivs
;
i
<
derivArray
.
getSize
();
i
+=
numDerivs
)
for
(
int
j
=
0
;
j
<
numDerivs
;
j
++
)
derivBuffers
[
j
]
+=
derivBuffers
[
i
+
j
];
for
(
int
i
=
0
;
i
<
numDerivs
;
i
++
)
derivs
[
paramDerivNames
[
i
]]
+=
derivBuffers
[
i
];
}
else
{
vector
<
float
>
derivBuffers
;
derivArray
.
download
(
derivBuffers
);
for
(
int
i
=
numDerivs
;
i
<
derivArray
.
getSize
();
i
+=
numDerivs
)
for
(
int
j
=
0
;
j
<
numDerivs
;
j
++
)
derivBuffers
[
j
]
+=
derivBuffers
[
i
+
j
];
for
(
int
i
=
0
;
i
<
numDerivs
;
i
++
)
derivs
[
paramDerivNames
[
i
]]
+=
derivBuffers
[
i
];
}
}
void
CudaUpdateStateDataKernel
::
getPeriodicBoxVectors
(
ContextImpl
&
context
,
Vec3
&
a
,
Vec3
&
b
,
Vec3
&
c
)
const
{
...
...
@@ -653,6 +679,12 @@ void CudaCalcCustomBondForceKernel::initialize(const System& system, const Custo
variables
[
name
]
=
value
;
}
}
for
(
int
i
=
0
;
i
<
force
.
getNumEnergyParameterDerivatives
();
i
++
)
{
string
paramName
=
force
.
getEnergyParameterDerivativeName
(
i
);
string
derivVariable
=
cu
.
getBondedUtilities
().
addEnergyParameterDerivative
(
paramName
);
Lepton
::
ParsedExpression
derivExpression
=
energyExpression
.
differentiate
(
paramName
).
optimize
();
expressions
[
derivVariable
+
" += "
]
=
derivExpression
;
}
stringstream
compute
;
for
(
int
i
=
0
;
i
<
(
int
)
params
->
getBuffers
().
size
();
i
++
)
{
CudaNonbondedUtilities
::
ParameterInfo
&
buffer
=
params
->
getBuffers
()[
i
];
...
...
@@ -891,6 +923,12 @@ void CudaCalcCustomAngleForceKernel::initialize(const System& system, const Cust
variables
[
name
]
=
value
;
}
}
for
(
int
i
=
0
;
i
<
force
.
getNumEnergyParameterDerivatives
();
i
++
)
{
string
paramName
=
force
.
getEnergyParameterDerivativeName
(
i
);
string
derivVariable
=
cu
.
getBondedUtilities
().
addEnergyParameterDerivative
(
paramName
);
Lepton
::
ParsedExpression
derivExpression
=
energyExpression
.
differentiate
(
paramName
).
optimize
();
expressions
[
derivVariable
+
" += "
]
=
derivExpression
;
}
stringstream
compute
;
for
(
int
i
=
0
;
i
<
(
int
)
params
->
getBuffers
().
size
();
i
++
)
{
CudaNonbondedUtilities
::
ParameterInfo
&
buffer
=
params
->
getBuffers
()[
i
];
...
...
@@ -1362,6 +1400,12 @@ void CudaCalcCustomTorsionForceKernel::initialize(const System& system, const Cu
variables
[
name
]
=
value
;
}
}
for
(
int
i
=
0
;
i
<
force
.
getNumEnergyParameterDerivatives
();
i
++
)
{
string
paramName
=
force
.
getEnergyParameterDerivativeName
(
i
);
string
derivVariable
=
cu
.
getBondedUtilities
().
addEnergyParameterDerivative
(
paramName
);
Lepton
::
ParsedExpression
derivExpression
=
energyExpression
.
differentiate
(
paramName
).
optimize
();
expressions
[
derivVariable
+
" += "
]
=
derivExpression
;
}
stringstream
compute
;
for
(
int
i
=
0
;
i
<
(
int
)
params
->
getBuffers
().
size
();
i
++
)
{
CudaNonbondedUtilities
::
ParameterInfo
&
buffer
=
params
->
getBuffers
()[
i
];
...
...
@@ -2247,6 +2291,12 @@ void CudaCalcCustomNonbondedForceKernel::initialize(const System& system, const
string
value
=
"globals["
+
cu
.
intToString
(
i
)
+
"]"
;
variables
.
push_back
(
makeVariable
(
name
,
prefix
+
value
));
}
for
(
int
i
=
0
;
i
<
force
.
getNumEnergyParameterDerivatives
();
i
++
)
{
string
paramName
=
force
.
getEnergyParameterDerivativeName
(
i
);
string
derivVariable
=
cu
.
getNonbondedUtilities
().
addEnergyParameterDerivative
(
paramName
);
Lepton
::
ParsedExpression
derivExpression
=
energyExpression
.
differentiate
(
paramName
).
optimize
();
forceExpressions
[
derivVariable
+
" += interactionScale*switchValue*"
]
=
derivExpression
;
}
stringstream
compute
;
compute
<<
cu
.
getExpressionUtilities
().
createExpressions
(
forceExpressions
,
variables
,
functionList
,
functionDefinitions
,
prefix
+
"temp"
);
map
<
string
,
string
>
replacements
;
...
...
@@ -2572,7 +2622,11 @@ double CudaCalcCustomNonbondedForceKernel::execute(ContextImpl& context, bool in
cu
.
executeKernel
(
interactionGroupKernel
,
&
interactionGroupArgs
[
0
],
numGroupThreadBlocks
*
forceThreadBlockSize
,
forceThreadBlockSize
);
}
double4
boxSize
=
cu
.
getPeriodicBoxSize
();
return
longRangeCoefficient
/
(
boxSize
.
x
*
boxSize
.
y
*
boxSize
.
z
);
double
volume
=
boxSize
.
x
*
boxSize
.
y
*
boxSize
.
z
;
map
<
string
,
double
>&
derivs
=
cu
.
getEnergyParamDerivWorkspace
();
for
(
int
i
=
0
;
i
<
longRangeCoefficientDerivs
.
size
();
i
++
)
derivs
[
forceCopy
->
getEnergyParameterDerivativeName
(
i
)]
+=
longRangeCoefficientDerivs
[
i
]
/
volume
;
return
longRangeCoefficient
/
volume
;
}
void
CudaCalcCustomNonbondedForceKernel
::
copyParametersToContext
(
ContextImpl
&
context
,
const
CustomNonbondedForce
&
force
)
{
...
...
platforms/cuda/src/CudaNonbondedUtilities.cpp
View file @
eae8def5
...
...
@@ -6,7 +6,7 @@
* Biological Structures at Stanford, funded under the NIH Roadmap for *
* Medical Research, grant U54 GM072970. See https://simtk.org. *
* *
* Portions copyright (c) 2009-201
5
Stanford University and the Authors. *
* Portions copyright (c) 2009-201
6
Stanford University and the Authors. *
* Authors: Peter Eastman *
* Contributors: *
* *
...
...
@@ -146,6 +146,19 @@ void CudaNonbondedUtilities::addArgument(const ParameterInfo& parameter) {
arguments
.
push_back
(
parameter
);
}
string
CudaNonbondedUtilities
::
addEnergyParameterDerivative
(
const
string
&
param
)
{
// See if the parameter has already been added.
int
index
;
for
(
index
=
0
;
index
<
energyParameterDerivatives
.
size
();
index
++
)
if
(
param
==
energyParameterDerivatives
[
index
])
break
;
if
(
index
==
energyParameterDerivatives
.
size
())
energyParameterDerivatives
.
push_back
(
param
);
context
.
addEnergyParameterDerivative
(
param
);
return
string
(
"energyParamDeriv"
)
+
context
.
intToString
(
index
);
}
void
CudaNonbondedUtilities
::
requestExclusions
(
const
vector
<
vector
<
int
>
>&
exclusionList
)
{
if
(
anyExclusions
)
{
bool
sameExclusions
=
(
exclusionList
.
size
()
==
atomExclusions
.
size
());
...
...
@@ -308,6 +321,8 @@ void CudaNonbondedUtilities::initialize(const System& system) {
forceArgs
.
push_back
(
&
parameters
[
i
].
getMemory
());
for
(
int
i
=
0
;
i
<
(
int
)
arguments
.
size
();
i
++
)
forceArgs
.
push_back
(
&
arguments
[
i
].
getMemory
());
if
(
energyParameterDerivatives
.
size
()
>
0
)
forceArgs
.
push_back
(
&
context
.
getEnergyParamDerivBuffer
().
getDevicePointer
());
if
(
useCutoff
)
{
findBlockBoundsArgs
.
push_back
(
&
numAtoms
);
findBlockBoundsArgs
.
push_back
(
context
.
getPeriodicBoxSizePointer
());
...
...
@@ -515,6 +530,8 @@ CUfunction CudaNonbondedUtilities::createInteractionKernel(const string& source,
args
<<
"* __restrict__ "
;
args
<<
arguments
[
i
].
getName
();
}
if
(
energyParameterDerivatives
.
size
()
>
0
)
args
<<
", mixed* __restrict__ energyParamDerivs"
;
replacements
[
"PARAMETER_ARGUMENTS"
]
=
args
.
str
();
stringstream
load1
;
...
...
@@ -623,6 +640,18 @@ CUfunction CudaNonbondedUtilities::createInteractionKernel(const string& source,
}
}
replacements
[
"LOAD_ATOM2_PARAMETERS"
]
=
load2j
.
str
();
stringstream
initDerivs
;
for
(
int
i
=
0
;
i
<
energyParameterDerivatives
.
size
();
i
++
)
initDerivs
<<
"mixed energyParamDeriv"
<<
i
<<
" = 0;
\n
"
;
replacements
[
"INIT_DERIVATIVES"
]
=
initDerivs
.
str
();
stringstream
saveDerivs
;
const
vector
<
string
>&
allParamDerivNames
=
context
.
getEnergyParamDerivNames
();
int
numDerivs
=
allParamDerivNames
.
size
();
for
(
int
i
=
0
;
i
<
energyParameterDerivatives
.
size
();
i
++
)
for
(
int
index
=
0
;
index
<
numDerivs
;
index
++
)
if
(
allParamDerivNames
[
index
]
==
energyParameterDerivatives
[
i
])
saveDerivs
<<
"energyParamDerivs[(blockIdx.x*blockDim.x+threadIdx.x)*"
<<
numDerivs
<<
"+"
<<
index
<<
"] += energyParamDeriv"
<<
i
<<
";
\n
"
;
replacements
[
"SAVE_DERIVATIVES"
]
=
saveDerivs
.
str
();
stringstream
shuffleWarpData
;
if
(
useShuffle
)
{
...
...
platforms/cuda/src/kernels/customNonbonded.cu
View file @
eae8def5
...
...
@@ -4,15 +4,18 @@ if (!isExcluded && r2 < CUTOFF_SQUARED) {
if
(
!
isExcluded
)
{
#endif
real
tempForce
=
0
;
COMPUTE_FORCE
real
switchValue
=
1
,
switchDeriv
=
0
;
#if USE_SWITCH
if
(
r
>
SWITCH_CUTOFF
)
{
real
x
=
r
-
SWITCH_CUTOFF
;
real
switchValue
=
1
+
x
*
x
*
x
*
(
SWITCH_C3
+
x
*
(
SWITCH_C4
+
x
*
SWITCH_C5
));
real
switchDeriv
=
x
*
x
*
(
3
*
SWITCH_C3
+
x
*
(
4
*
SWITCH_C4
+
x
*
5
*
SWITCH_C5
));
tempForce
=
tempForce
*
switchValue
-
tempEnergy
*
switchDeriv
;
tempEnergy
*=
switchValue
;
switchValue
=
1
+
x
*
x
*
x
*
(
SWITCH_C3
+
x
*
(
SWITCH_C4
+
x
*
SWITCH_C5
));
switchDeriv
=
x
*
x
*
(
3
*
SWITCH_C3
+
x
*
(
4
*
SWITCH_C4
+
x
*
5
*
SWITCH_C5
));
}
#endif
COMPUTE_FORCE
#if USE_SWITCH
tempForce
=
tempForce
*
switchValue
-
tempEnergy
*
switchDeriv
;
tempEnergy
*=
switchValue
;
#endif
dEdR
+=
tempForce
*
invR
;
}
platforms/cuda/src/kernels/nonbonded.cu
View file @
eae8def5
...
...
@@ -113,6 +113,7 @@ extern "C" __global__ void computeNonbonded(
const
unsigned
int
tgx
=
threadIdx
.
x
&
(
TILE_SIZE
-
1
);
// index within the warp
const
unsigned
int
tbx
=
threadIdx
.
x
-
tgx
;
// block warpIndex
mixed
energy
=
0
;
INIT_DERIVATIVES
// used shared memory if the device cannot shuffle
#ifndef ENABLE_SHUFFLE
__shared__
AtomData
localData
[
THREAD_BLOCK_SIZE
];
...
...
@@ -175,6 +176,7 @@ extern "C" __global__ void computeNonbonded(
bool
isExcluded
=
(
atom1
>=
NUM_ATOMS
||
atom2
>=
NUM_ATOMS
||
!
(
excl
&
0x1
));
#endif
real
tempEnergy
=
0.0
f
;
const
real
interactionScale
=
0.5
f
;
COMPUTE_INTERACTION
energy
+=
0.5
f
*
tempEnergy
;
#ifdef INCLUDE_FORCES
...
...
@@ -243,6 +245,7 @@ extern "C" __global__ void computeNonbonded(
bool
isExcluded
=
(
atom1
>=
NUM_ATOMS
||
atom2
>=
NUM_ATOMS
||
!
(
excl
&
0x1
));
#endif
real
tempEnergy
=
0.0
f
;
const
real
interactionScale
=
1.0
f
;
COMPUTE_INTERACTION
energy
+=
tempEnergy
;
#ifdef INCLUDE_FORCES
...
...
@@ -448,6 +451,7 @@ extern "C" __global__ void computeNonbonded(
bool
isExcluded
=
(
atom1
>=
NUM_ATOMS
||
atom2
>=
NUM_ATOMS
);
#endif
real
tempEnergy
=
0.0
f
;
const
real
interactionScale
=
1.0
f
;
COMPUTE_INTERACTION
energy
+=
tempEnergy
;
#ifdef INCLUDE_FORCES
...
...
@@ -518,6 +522,7 @@ extern "C" __global__ void computeNonbonded(
bool
isExcluded
=
(
atom1
>=
NUM_ATOMS
||
atom2
>=
NUM_ATOMS
);
#endif
real
tempEnergy
=
0.0
f
;
const
real
interactionScale
=
1.0
f
;
COMPUTE_INTERACTION
energy
+=
tempEnergy
;
#ifdef INCLUDE_FORCES
...
...
@@ -586,4 +591,5 @@ extern "C" __global__ void computeNonbonded(
#ifdef INCLUDE_ENERGY
energyBuffer
[
blockIdx
.
x
*
blockDim
.
x
+
threadIdx
.
x
]
+=
energy
;
#endif
SAVE_DERIVATIVES
}
\ No newline at end of file
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