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
Show 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 @@
...
@@ -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) 2011-201
5
Stanford University and the Authors. *
* Portions copyright (c) 2011-201
6
Stanford University and the Authors. *
* Authors: Peter Eastman *
* Authors: Peter Eastman *
* Contributors: *
* Contributors: *
* *
* *
...
@@ -100,6 +100,15 @@ public:
...
@@ -100,6 +100,15 @@ public:
* refer to it by this name.
* refer to it by this name.
*/
*/
std
::
string
addArgument
(
CUdeviceptr
data
,
const
std
::
string
&
type
);
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.
* 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.
* This can be used, for example, to define functions that will be called by the kernel.
...
@@ -129,6 +138,7 @@ private:
...
@@ -129,6 +138,7 @@ private:
std
::
vector
<
std
::
string
>
argTypes
;
std
::
vector
<
std
::
string
>
argTypes
;
std
::
vector
<
std
::
vector
<
CudaArray
*>
>
atomIndices
;
std
::
vector
<
std
::
vector
<
CudaArray
*>
>
atomIndices
;
std
::
vector
<
std
::
string
>
prefixCode
;
std
::
vector
<
std
::
string
>
prefixCode
;
std
::
vector
<
std
::
string
>
energyParameterDerivatives
;
std
::
vector
<
void
*>
kernelArgs
;
std
::
vector
<
void
*>
kernelArgs
;
int
numForceBuffers
,
maxBonds
,
allGroups
;
int
numForceBuffers
,
maxBonds
,
allGroups
;
bool
hasInitializedKernels
,
hasInteractions
;
bool
hasInitializedKernels
,
hasInteractions
;
...
...
platforms/cuda/include/CudaContext.h
View file @
eae8def5
...
@@ -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) 2009-201
5
Stanford University and the Authors. *
* Portions copyright (c) 2009-201
6
Stanford University and the Authors. *
* Authors: Peter Eastman *
* Authors: Peter Eastman *
* Contributors: *
* Contributors: *
* *
* *
...
@@ -177,6 +177,12 @@ public:
...
@@ -177,6 +177,12 @@ public:
CudaArray
&
getEnergyBuffer
()
{
CudaArray
&
getEnergyBuffer
()
{
return
*
energyBuffer
;
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.
* 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.
* 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:
...
@@ -544,6 +550,27 @@ public:
std
::
vector
<
ForcePostComputation
*>&
getPostComputations
()
{
std
::
vector
<
ForcePostComputation
*>&
getPostComputations
()
{
return
postComputations
;
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.
* 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
* This should be called whenever force field parameters change. It will cause the definitions
...
@@ -609,7 +636,10 @@ private:
...
@@ -609,7 +636,10 @@ private:
CudaArray
*
velm
;
CudaArray
*
velm
;
CudaArray
*
force
;
CudaArray
*
force
;
CudaArray
*
energyBuffer
;
CudaArray
*
energyBuffer
;
CudaArray
*
energyParamDerivBuffer
;
CudaArray
*
atomIndexDevice
;
CudaArray
*
atomIndexDevice
;
std
::
vector
<
std
::
string
>
energyParamDerivNames
;
std
::
map
<
std
::
string
,
double
>
energyParamDerivWorkspace
;
std
::
vector
<
int
>
atomIndex
;
std
::
vector
<
int
>
atomIndex
;
std
::
vector
<
CUdeviceptr
>
autoclearBuffers
;
std
::
vector
<
CUdeviceptr
>
autoclearBuffers
;
std
::
vector
<
int
>
autoclearBufferSizes
;
std
::
vector
<
int
>
autoclearBufferSizes
;
...
...
platforms/cuda/include/CudaNonbondedUtilities.h
View file @
eae8def5
...
@@ -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) 2009-201
3
Stanford University and the Authors. *
* Portions copyright (c) 2009-201
6
Stanford University and the Authors. *
* Authors: Peter Eastman *
* Authors: Peter Eastman *
* Contributors: *
* Contributors: *
* *
* *
...
@@ -88,6 +88,15 @@ public:
...
@@ -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.
* 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
);
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.
* Specify the list of exclusions that an interaction outside the default kernel will depend on.
*
*
...
@@ -275,6 +284,7 @@ private:
...
@@ -275,6 +284,7 @@ private:
std
::
vector
<
std
::
vector
<
int
>
>
atomExclusions
;
std
::
vector
<
std
::
vector
<
int
>
>
atomExclusions
;
std
::
vector
<
ParameterInfo
>
parameters
;
std
::
vector
<
ParameterInfo
>
parameters
;
std
::
vector
<
ParameterInfo
>
arguments
;
std
::
vector
<
ParameterInfo
>
arguments
;
std
::
vector
<
std
::
string
>
energyParameterDerivatives
;
std
::
map
<
int
,
double
>
groupCutoff
;
std
::
map
<
int
,
double
>
groupCutoff
;
std
::
map
<
int
,
std
::
string
>
groupKernelSource
;
std
::
map
<
int
,
std
::
string
>
groupKernelSource
;
double
lastCutoff
;
double
lastCutoff
;
...
...
platforms/cuda/src/CudaBondedUtilities.cpp
View file @
eae8def5
...
@@ -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) 2011-201
5
Stanford University and the Authors. *
* Portions copyright (c) 2011-201
6
Stanford University and the Authors. *
* Authors: Peter Eastman *
* Authors: Peter Eastman *
* Contributors: *
* Contributors: *
* *
* *
...
@@ -52,12 +52,25 @@ void CudaBondedUtilities::addInteraction(const vector<vector<int> >& atoms, cons
...
@@ -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
);
arguments
.
push_back
(
data
);
argTypes
.
push_back
(
type
);
argTypes
.
push_back
(
type
);
return
"customArg"
+
context
.
intToString
(
arguments
.
size
());
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
)
{
void
CudaBondedUtilities
::
addPrefixCode
(
const
string
&
source
)
{
for
(
int
i
=
0
;
i
<
(
int
)
prefixCode
.
size
();
i
++
)
for
(
int
i
=
0
;
i
<
(
int
)
prefixCode
.
size
();
i
++
)
if
(
prefixCode
[
i
]
==
source
)
if
(
prefixCode
[
i
]
==
source
)
...
@@ -109,11 +122,21 @@ void CudaBondedUtilities::initialize(const System& system) {
...
@@ -109,11 +122,21 @@ void CudaBondedUtilities::initialize(const System& system) {
}
}
for
(
int
i
=
0
;
i
<
(
int
)
arguments
.
size
();
i
++
)
for
(
int
i
=
0
;
i
<
(
int
)
arguments
.
size
();
i
++
)
s
<<
", "
<<
argTypes
[
i
]
<<
"* customArg"
<<
(
i
+
1
);
s
<<
", "
<<
argTypes
[
i
]
<<
"* customArg"
<<
(
i
+
1
);
if
(
energyParameterDerivatives
.
size
()
>
0
)
s
<<
", mixed* __restrict__ energyParamDerivs"
;
s
<<
") {
\n
"
;
s
<<
") {
\n
"
;
s
<<
"mixed energy = 0;
\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
++
)
for
(
int
force
=
0
;
force
<
numForces
;
force
++
)
s
<<
createForceSource
(
force
,
forceAtoms
[
force
].
size
(),
forceAtoms
[
force
][
0
].
size
(),
forceGroup
[
force
],
forceSource
[
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
"
;
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
"
;
s
<<
"}
\n
"
;
map
<
string
,
string
>
defines
;
map
<
string
,
string
>
defines
;
defines
[
"PADDED_NUM_ATOMS"
]
=
context
.
intToString
(
context
.
getPaddedNumAtoms
());
defines
[
"PADDED_NUM_ATOMS"
]
=
context
.
intToString
(
context
.
getPaddedNumAtoms
());
...
@@ -171,6 +194,8 @@ void CudaBondedUtilities::computeInteractions(int groups) {
...
@@ -171,6 +194,8 @@ void CudaBondedUtilities::computeInteractions(int groups) {
kernelArgs
.
push_back
(
&
atomIndices
[
i
][
j
]
->
getDevicePointer
());
kernelArgs
.
push_back
(
&
atomIndices
[
i
][
j
]
->
getDevicePointer
());
for
(
int
i
=
0
;
i
<
(
int
)
arguments
.
size
();
i
++
)
for
(
int
i
=
0
;
i
<
(
int
)
arguments
.
size
();
i
++
)
kernelArgs
.
push_back
(
&
arguments
[
i
]);
kernelArgs
.
push_back
(
&
arguments
[
i
]);
if
(
energyParameterDerivatives
.
size
()
>
0
)
kernelArgs
.
push_back
(
&
context
.
getEnergyParamDerivBuffer
().
getDevicePointer
());
}
}
if
(
!
hasInteractions
)
if
(
!
hasInteractions
)
return
;
return
;
...
...
platforms/cuda/src/CudaContext.cpp
View file @
eae8def5
...
@@ -76,7 +76,7 @@ bool CudaContext::hasInitializedCuda = false;
...
@@ -76,7 +76,7 @@ bool CudaContext::hasInitializedCuda = false;
CudaContext
::
CudaContext
(
const
System
&
system
,
int
deviceIndex
,
bool
useBlockingSync
,
const
string
&
precision
,
const
string
&
compiler
,
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
),
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
),
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
+
"
\"
"
;
this
->
compiler
=
"
\"
"
+
compiler
+
"
\"
"
;
if
(
platformData
.
context
!=
NULL
)
{
if
(
platformData
.
context
!=
NULL
)
{
try
{
try
{
...
@@ -339,6 +339,8 @@ CudaContext::~CudaContext() {
...
@@ -339,6 +339,8 @@ CudaContext::~CudaContext() {
delete
force
;
delete
force
;
if
(
energyBuffer
!=
NULL
)
if
(
energyBuffer
!=
NULL
)
delete
energyBuffer
;
delete
energyBuffer
;
if
(
energyParamDerivBuffer
!=
NULL
)
delete
energyParamDerivBuffer
;
if
(
atomIndexDevice
!=
NULL
)
if
(
atomIndexDevice
!=
NULL
)
delete
atomIndexDevice
;
delete
atomIndexDevice
;
if
(
integration
!=
NULL
)
if
(
integration
!=
NULL
)
...
@@ -390,6 +392,14 @@ void CudaContext::initialize() {
...
@@ -390,6 +392,14 @@ void CudaContext::initialize() {
force
=
CudaArray
::
create
<
long
long
>
(
*
this
,
paddedNumAtoms
*
3
,
"force"
);
force
=
CudaArray
::
create
<
long
long
>
(
*
this
,
paddedNumAtoms
*
3
,
"force"
);
addAutoclearBuffer
(
force
->
getDevicePointer
(),
force
->
getSize
()
*
force
->
getElementSize
());
addAutoclearBuffer
(
force
->
getDevicePointer
(),
force
->
getSize
()
*
force
->
getElementSize
());
addAutoclearBuffer
(
energyBuffer
->
getDevicePointer
(),
energyBuffer
->
getSize
()
*
energyBuffer
->
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"
);
atomIndexDevice
=
CudaArray
::
create
<
int
>
(
*
this
,
paddedNumAtoms
,
"atomIndex"
);
atomIndex
.
resize
(
paddedNumAtoms
);
atomIndex
.
resize
(
paddedNumAtoms
);
for
(
int
i
=
0
;
i
<
paddedNumAtoms
;
++
i
)
for
(
int
i
=
0
;
i
<
paddedNumAtoms
;
++
i
)
...
@@ -1311,6 +1321,15 @@ void CudaContext::addPostComputation(ForcePostComputation* computation) {
...
@@ -1311,6 +1321,15 @@ void CudaContext::addPostComputation(ForcePostComputation* computation) {
postComputations
.
push_back
(
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
{
struct
CudaContext
::
WorkThread
::
ThreadData
{
ThreadData
(
std
::
queue
<
CudaContext
::
WorkTask
*>&
tasks
,
bool
&
waiting
,
bool
&
finished
,
ThreadData
(
std
::
queue
<
CudaContext
::
WorkTask
*>&
tasks
,
bool
&
waiting
,
bool
&
finished
,
pthread_mutex_t
&
queueLock
,
pthread_cond_t
&
waitForTaskCondition
,
pthread_cond_t
&
queueEmptyCondition
)
:
pthread_mutex_t
&
queueLock
,
pthread_cond_t
&
waitForTaskCondition
,
pthread_cond_t
&
queueEmptyCondition
)
:
...
...
platforms/cuda/src/CudaKernels.cpp
View file @
eae8def5
...
@@ -43,6 +43,7 @@
...
@@ -43,6 +43,7 @@
#include "CudaIntegrationUtilities.h"
#include "CudaIntegrationUtilities.h"
#include "CudaNonbondedUtilities.h"
#include "CudaNonbondedUtilities.h"
#include "CudaKernelSources.h"
#include "CudaKernelSources.h"
#include "lepton/CustomFunction.h"
#include "lepton/ExpressionTreeNode.h"
#include "lepton/ExpressionTreeNode.h"
#include "lepton/Operation.h"
#include "lepton/Operation.h"
#include "lepton/Parser.h"
#include "lepton/Parser.h"
...
@@ -55,8 +56,7 @@
...
@@ -55,8 +56,7 @@
using namespace OpenMM;
using namespace OpenMM;
using namespace std;
using namespace std;
using Lepton::ExpressionTreeNode;
using namespace Lepton;
using Lepton::Operation;
#define CHECK_RESULT(result, prefix) \
#define CHECK_RESULT(result, prefix) \
if (result != CUDA_SUCCESS) { \
if (result != CUDA_SUCCESS) { \
...
@@ -102,6 +102,9 @@ void CudaCalcForcesAndEnergyKernel::beginComputation(ContextImpl& context, bool
...
@@ -102,6 +102,9 @@ void CudaCalcForcesAndEnergyKernel::beginComputation(ContextImpl& context, bool
CudaNonbondedUtilities& nb = cu.getNonbondedUtilities();
CudaNonbondedUtilities& nb = cu.getNonbondedUtilities();
cu.setComputeForceCount(cu.getComputeForceCount()+1);
cu.setComputeForceCount(cu.getComputeForceCount()+1);
nb.prepareInteractions(groups);
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) {
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
...
@@ -340,7 +343,30 @@ void CudaUpdateStateDataKernel::getForces(ContextImpl& context, vector<Vec3>& fo
}
}
void CudaUpdateStateDataKernel::getEnergyParameterDerivatives(ContextImpl& context, map<string, double>& derivs) {
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 {
void CudaUpdateStateDataKernel::getPeriodicBoxVectors(ContextImpl& context, Vec3& a, Vec3& b, Vec3& c) const {
...
@@ -653,6 +679,12 @@ void CudaCalcCustomBondForceKernel::initialize(const System& system, const Custo
...
@@ -653,6 +679,12 @@ void CudaCalcCustomBondForceKernel::initialize(const System& system, const Custo
variables[name] = value;
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;
stringstream compute;
for (int i = 0; i < (int) params->getBuffers().size(); i++) {
for (int i = 0; i < (int) params->getBuffers().size(); i++) {
CudaNonbondedUtilities::ParameterInfo& buffer = params->getBuffers()[i];
CudaNonbondedUtilities::ParameterInfo& buffer = params->getBuffers()[i];
...
@@ -891,6 +923,12 @@ void CudaCalcCustomAngleForceKernel::initialize(const System& system, const Cust
...
@@ -891,6 +923,12 @@ void CudaCalcCustomAngleForceKernel::initialize(const System& system, const Cust
variables[name] = value;
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;
stringstream compute;
for (int i = 0; i < (int) params->getBuffers().size(); i++) {
for (int i = 0; i < (int) params->getBuffers().size(); i++) {
CudaNonbondedUtilities::ParameterInfo& buffer = params->getBuffers()[i];
CudaNonbondedUtilities::ParameterInfo& buffer = params->getBuffers()[i];
...
@@ -1362,6 +1400,12 @@ void CudaCalcCustomTorsionForceKernel::initialize(const System& system, const Cu
...
@@ -1362,6 +1400,12 @@ void CudaCalcCustomTorsionForceKernel::initialize(const System& system, const Cu
variables[name] = value;
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;
stringstream compute;
for (int i = 0; i < (int) params->getBuffers().size(); i++) {
for (int i = 0; i < (int) params->getBuffers().size(); i++) {
CudaNonbondedUtilities::ParameterInfo& buffer = params->getBuffers()[i];
CudaNonbondedUtilities::ParameterInfo& buffer = params->getBuffers()[i];
...
@@ -2247,6 +2291,12 @@ void CudaCalcCustomNonbondedForceKernel::initialize(const System& system, const
...
@@ -2247,6 +2291,12 @@ void CudaCalcCustomNonbondedForceKernel::initialize(const System& system, const
string value = "globals["+cu.intToString(i)+"]";
string value = "globals["+cu.intToString(i)+"]";
variables.push_back(makeVariable(name, prefix+value));
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;
stringstream compute;
compute << cu.getExpressionUtilities().createExpressions(forceExpressions, variables, functionList, functionDefinitions, prefix+"temp");
compute << cu.getExpressionUtilities().createExpressions(forceExpressions, variables, functionList, functionDefinitions, prefix+"temp");
map<string, string> replacements;
map<string, string> replacements;
...
@@ -2572,7 +2622,11 @@ double CudaCalcCustomNonbondedForceKernel::execute(ContextImpl& context, bool in
...
@@ -2572,7 +2622,11 @@ double CudaCalcCustomNonbondedForceKernel::execute(ContextImpl& context, bool in
cu.executeKernel(interactionGroupKernel, &interactionGroupArgs[0], numGroupThreadBlocks*forceThreadBlockSize, forceThreadBlockSize);
cu.executeKernel(interactionGroupKernel, &interactionGroupArgs[0], numGroupThreadBlocks*forceThreadBlockSize, forceThreadBlockSize);
}
}
double4 boxSize = cu.getPeriodicBoxSize();
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) {
void CudaCalcCustomNonbondedForceKernel::copyParametersToContext(ContextImpl& context, const CustomNonbondedForce& force) {
...
...
platforms/cuda/src/CudaNonbondedUtilities.cpp
View file @
eae8def5
...
@@ -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) 2009-201
5
Stanford University and the Authors. *
* Portions copyright (c) 2009-201
6
Stanford University and the Authors. *
* Authors: Peter Eastman *
* Authors: Peter Eastman *
* Contributors: *
* Contributors: *
* *
* *
...
@@ -146,6 +146,19 @@ void CudaNonbondedUtilities::addArgument(const ParameterInfo& parameter) {
...
@@ -146,6 +146,19 @@ void CudaNonbondedUtilities::addArgument(const ParameterInfo& parameter) {
arguments
.
push_back
(
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
)
{
void
CudaNonbondedUtilities
::
requestExclusions
(
const
vector
<
vector
<
int
>
>&
exclusionList
)
{
if
(
anyExclusions
)
{
if
(
anyExclusions
)
{
bool
sameExclusions
=
(
exclusionList
.
size
()
==
atomExclusions
.
size
());
bool
sameExclusions
=
(
exclusionList
.
size
()
==
atomExclusions
.
size
());
...
@@ -308,6 +321,8 @@ void CudaNonbondedUtilities::initialize(const System& system) {
...
@@ -308,6 +321,8 @@ void CudaNonbondedUtilities::initialize(const System& system) {
forceArgs
.
push_back
(
&
parameters
[
i
].
getMemory
());
forceArgs
.
push_back
(
&
parameters
[
i
].
getMemory
());
for
(
int
i
=
0
;
i
<
(
int
)
arguments
.
size
();
i
++
)
for
(
int
i
=
0
;
i
<
(
int
)
arguments
.
size
();
i
++
)
forceArgs
.
push_back
(
&
arguments
[
i
].
getMemory
());
forceArgs
.
push_back
(
&
arguments
[
i
].
getMemory
());
if
(
energyParameterDerivatives
.
size
()
>
0
)
forceArgs
.
push_back
(
&
context
.
getEnergyParamDerivBuffer
().
getDevicePointer
());
if
(
useCutoff
)
{
if
(
useCutoff
)
{
findBlockBoundsArgs
.
push_back
(
&
numAtoms
);
findBlockBoundsArgs
.
push_back
(
&
numAtoms
);
findBlockBoundsArgs
.
push_back
(
context
.
getPeriodicBoxSizePointer
());
findBlockBoundsArgs
.
push_back
(
context
.
getPeriodicBoxSizePointer
());
...
@@ -515,6 +530,8 @@ CUfunction CudaNonbondedUtilities::createInteractionKernel(const string& source,
...
@@ -515,6 +530,8 @@ CUfunction CudaNonbondedUtilities::createInteractionKernel(const string& source,
args
<<
"* __restrict__ "
;
args
<<
"* __restrict__ "
;
args
<<
arguments
[
i
].
getName
();
args
<<
arguments
[
i
].
getName
();
}
}
if
(
energyParameterDerivatives
.
size
()
>
0
)
args
<<
", mixed* __restrict__ energyParamDerivs"
;
replacements
[
"PARAMETER_ARGUMENTS"
]
=
args
.
str
();
replacements
[
"PARAMETER_ARGUMENTS"
]
=
args
.
str
();
stringstream
load1
;
stringstream
load1
;
...
@@ -623,6 +640,18 @@ CUfunction CudaNonbondedUtilities::createInteractionKernel(const string& source,
...
@@ -623,6 +640,18 @@ CUfunction CudaNonbondedUtilities::createInteractionKernel(const string& source,
}
}
}
}
replacements
[
"LOAD_ATOM2_PARAMETERS"
]
=
load2j
.
str
();
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
;
stringstream
shuffleWarpData
;
if
(
useShuffle
)
{
if
(
useShuffle
)
{
...
...
platforms/cuda/src/kernels/customNonbonded.cu
View file @
eae8def5
...
@@ -4,15 +4,18 @@ if (!isExcluded && r2 < CUTOFF_SQUARED) {
...
@@ -4,15 +4,18 @@ if (!isExcluded && r2 < CUTOFF_SQUARED) {
if
(
!
isExcluded
)
{
if
(
!
isExcluded
)
{
#endif
#endif
real
tempForce
=
0
;
real
tempForce
=
0
;
COMPUTE_FORCE
real
switchValue
=
1
,
switchDeriv
=
0
;
#if USE_SWITCH
#if USE_SWITCH
if
(
r
>
SWITCH_CUTOFF
)
{
if
(
r
>
SWITCH_CUTOFF
)
{
real
x
=
r
-
SWITCH_CUTOFF
;
real
x
=
r
-
SWITCH_CUTOFF
;
real
switchValue
=
1
+
x
*
x
*
x
*
(
SWITCH_C3
+
x
*
(
SWITCH_C4
+
x
*
SWITCH_C5
));
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
));
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
;
tempForce
=
tempForce
*
switchValue
-
tempEnergy
*
switchDeriv
;
tempEnergy
*=
switchValue
;
tempEnergy
*=
switchValue
;
}
#endif
#endif
dEdR
+=
tempForce
*
invR
;
dEdR
+=
tempForce
*
invR
;
}
}
platforms/cuda/src/kernels/nonbonded.cu
View file @
eae8def5
...
@@ -113,6 +113,7 @@ extern "C" __global__ void computeNonbonded(
...
@@ -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
tgx
=
threadIdx
.
x
&
(
TILE_SIZE
-
1
);
// index within the warp
const
unsigned
int
tbx
=
threadIdx
.
x
-
tgx
;
// block warpIndex
const
unsigned
int
tbx
=
threadIdx
.
x
-
tgx
;
// block warpIndex
mixed
energy
=
0
;
mixed
energy
=
0
;
INIT_DERIVATIVES
// used shared memory if the device cannot shuffle
// used shared memory if the device cannot shuffle
#ifndef ENABLE_SHUFFLE
#ifndef ENABLE_SHUFFLE
__shared__
AtomData
localData
[
THREAD_BLOCK_SIZE
];
__shared__
AtomData
localData
[
THREAD_BLOCK_SIZE
];
...
@@ -175,6 +176,7 @@ extern "C" __global__ void computeNonbonded(
...
@@ -175,6 +176,7 @@ extern "C" __global__ void computeNonbonded(
bool
isExcluded
=
(
atom1
>=
NUM_ATOMS
||
atom2
>=
NUM_ATOMS
||
!
(
excl
&
0x1
));
bool
isExcluded
=
(
atom1
>=
NUM_ATOMS
||
atom2
>=
NUM_ATOMS
||
!
(
excl
&
0x1
));
#endif
#endif
real
tempEnergy
=
0.0
f
;
real
tempEnergy
=
0.0
f
;
const
real
interactionScale
=
0.5
f
;
COMPUTE_INTERACTION
COMPUTE_INTERACTION
energy
+=
0.5
f
*
tempEnergy
;
energy
+=
0.5
f
*
tempEnergy
;
#ifdef INCLUDE_FORCES
#ifdef INCLUDE_FORCES
...
@@ -243,6 +245,7 @@ extern "C" __global__ void computeNonbonded(
...
@@ -243,6 +245,7 @@ extern "C" __global__ void computeNonbonded(
bool
isExcluded
=
(
atom1
>=
NUM_ATOMS
||
atom2
>=
NUM_ATOMS
||
!
(
excl
&
0x1
));
bool
isExcluded
=
(
atom1
>=
NUM_ATOMS
||
atom2
>=
NUM_ATOMS
||
!
(
excl
&
0x1
));
#endif
#endif
real
tempEnergy
=
0.0
f
;
real
tempEnergy
=
0.0
f
;
const
real
interactionScale
=
1.0
f
;
COMPUTE_INTERACTION
COMPUTE_INTERACTION
energy
+=
tempEnergy
;
energy
+=
tempEnergy
;
#ifdef INCLUDE_FORCES
#ifdef INCLUDE_FORCES
...
@@ -448,6 +451,7 @@ extern "C" __global__ void computeNonbonded(
...
@@ -448,6 +451,7 @@ extern "C" __global__ void computeNonbonded(
bool
isExcluded
=
(
atom1
>=
NUM_ATOMS
||
atom2
>=
NUM_ATOMS
);
bool
isExcluded
=
(
atom1
>=
NUM_ATOMS
||
atom2
>=
NUM_ATOMS
);
#endif
#endif
real
tempEnergy
=
0.0
f
;
real
tempEnergy
=
0.0
f
;
const
real
interactionScale
=
1.0
f
;
COMPUTE_INTERACTION
COMPUTE_INTERACTION
energy
+=
tempEnergy
;
energy
+=
tempEnergy
;
#ifdef INCLUDE_FORCES
#ifdef INCLUDE_FORCES
...
@@ -518,6 +522,7 @@ extern "C" __global__ void computeNonbonded(
...
@@ -518,6 +522,7 @@ extern "C" __global__ void computeNonbonded(
bool
isExcluded
=
(
atom1
>=
NUM_ATOMS
||
atom2
>=
NUM_ATOMS
);
bool
isExcluded
=
(
atom1
>=
NUM_ATOMS
||
atom2
>=
NUM_ATOMS
);
#endif
#endif
real
tempEnergy
=
0.0
f
;
real
tempEnergy
=
0.0
f
;
const
real
interactionScale
=
1.0
f
;
COMPUTE_INTERACTION
COMPUTE_INTERACTION
energy
+=
tempEnergy
;
energy
+=
tempEnergy
;
#ifdef INCLUDE_FORCES
#ifdef INCLUDE_FORCES
...
@@ -586,4 +591,5 @@ extern "C" __global__ void computeNonbonded(
...
@@ -586,4 +591,5 @@ extern "C" __global__ void computeNonbonded(
#ifdef INCLUDE_ENERGY
#ifdef INCLUDE_ENERGY
energyBuffer
[
blockIdx
.
x
*
blockDim
.
x
+
threadIdx
.
x
]
+=
energy
;
energyBuffer
[
blockIdx
.
x
*
blockDim
.
x
+
threadIdx
.
x
]
+=
energy
;
#endif
#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