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
efc1083e
Commit
efc1083e
authored
Sep 25, 2009
by
Peter Eastman
Browse files
Created OpenCL implementations of VerletIntegrator and SHAKE.
parent
695c066f
Changes
11
Hide whitespace changes
Inline
Side-by-side
Showing
11 changed files
with
922 additions
and
135 deletions
+922
-135
platforms/opencl/src/OpenCLArray.h
platforms/opencl/src/OpenCLArray.h
+18
-2
platforms/opencl/src/OpenCLContext.cpp
platforms/opencl/src/OpenCLContext.cpp
+6
-4
platforms/opencl/src/OpenCLContext.h
platforms/opencl/src/OpenCLContext.h
+35
-1
platforms/opencl/src/OpenCLIntegrationUtilities.cpp
platforms/opencl/src/OpenCLIntegrationUtilities.cpp
+285
-0
platforms/opencl/src/OpenCLIntegrationUtilities.h
platforms/opencl/src/OpenCLIntegrationUtilities.h
+80
-0
platforms/opencl/src/OpenCLKernelFactory.cpp
platforms/opencl/src/OpenCLKernelFactory.cpp
+18
-17
platforms/opencl/src/OpenCLKernels.cpp
platforms/opencl/src/OpenCLKernels.cpp
+90
-75
platforms/opencl/src/OpenCLKernels.h
platforms/opencl/src/OpenCLKernels.h
+37
-36
platforms/opencl/src/kernels/shakeHydrogens.cl
platforms/opencl/src/kernels/shakeHydrogens.cl
+101
-0
platforms/opencl/src/kernels/verlet.cl
platforms/opencl/src/kernels/verlet.cl
+36
-0
platforms/opencl/tests/TestOpenCLVerletIntegrator.cpp
platforms/opencl/tests/TestOpenCLVerletIntegrator.cpp
+216
-0
No files found.
platforms/opencl/src/OpenCLArray.h
View file @
efc1083e
...
@@ -29,6 +29,8 @@
...
@@ -29,6 +29,8 @@
#include "OpenCLContext.h"
#include "OpenCLContext.h"
#include "openmm/OpenMMException.h"
#include "openmm/OpenMMException.h"
#include <iostream>
#include <sstream>
#include <vector>
#include <vector>
namespace
OpenMM
{
namespace
OpenMM
{
...
@@ -117,13 +119,27 @@ public:
...
@@ -117,13 +119,27 @@ public:
* Copy the values in a vector to the Buffer.
* Copy the values in a vector to the Buffer.
*/
*/
void
upload
(
std
::
vector
<
T
>&
data
)
{
void
upload
(
std
::
vector
<
T
>&
data
)
{
context
.
getQueue
().
enqueueWriteBuffer
(
*
buffer
,
CL_TRUE
,
0
,
size
*
sizeof
(
T
),
&
data
[
0
]);
try
{
context
.
getQueue
().
enqueueWriteBuffer
(
*
buffer
,
CL_TRUE
,
0
,
size
*
sizeof
(
T
),
&
data
[
0
]);
}
catch
(
cl
::
Error
err
)
{
std
::
stringstream
str
;
str
<<
"Error uploading array "
<<
name
<<
": "
<<
err
.
what
()
<<
" ("
<<
err
.
err
()
<<
")"
;
throw
OpenMMException
(
str
.
str
());
}
}
}
/**
/**
* Copy the values in the Buffer to a vector.
* Copy the values in the Buffer to a vector.
*/
*/
void
download
(
std
::
vector
<
T
>&
data
)
const
{
void
download
(
std
::
vector
<
T
>&
data
)
const
{
context
.
getQueue
().
enqueueReadBuffer
(
*
buffer
,
CL_TRUE
,
0
,
size
*
sizeof
(
T
),
&
data
[
0
]);
try
{
context
.
getQueue
().
enqueueReadBuffer
(
*
buffer
,
CL_TRUE
,
0
,
size
*
sizeof
(
T
),
&
data
[
0
]);
}
catch
(
cl
::
Error
err
)
{
std
::
stringstream
str
;
str
<<
"Error downloading array "
<<
name
<<
": "
<<
err
.
what
()
<<
" ("
<<
err
.
err
()
<<
")"
;
throw
OpenMMException
(
str
.
str
());
}
}
}
/**
/**
* Copy the values in the host buffer to the OpenCL Buffer.
* Copy the values in the host buffer to the OpenCL Buffer.
...
...
platforms/opencl/src/OpenCLContext.cpp
View file @
efc1083e
...
@@ -27,6 +27,7 @@
...
@@ -27,6 +27,7 @@
#include "OpenCLContext.h"
#include "OpenCLContext.h"
#include "OpenCLArray.h"
#include "OpenCLArray.h"
#include "OpenCLForceInfo.h"
#include "OpenCLForceInfo.h"
#include "OpenCLIntegrationUtilities.h"
#include "openmm/Platform.h"
#include "openmm/Platform.h"
#include "openmm/System.h"
#include "openmm/System.h"
#include <fstream>
#include <fstream>
...
@@ -36,7 +37,7 @@
...
@@ -36,7 +37,7 @@
using
namespace
OpenMM
;
using
namespace
OpenMM
;
using
namespace
std
;
using
namespace
std
;
OpenCLContext
::
OpenCLContext
(
int
numParticles
,
int
deviceIndex
)
{
OpenCLContext
::
OpenCLContext
(
int
numParticles
,
int
deviceIndex
)
:
time
(
0.0
),
stepCount
(
0
)
{
context
=
cl
::
Context
(
CL_DEVICE_TYPE_ALL
);
context
=
cl
::
Context
(
CL_DEVICE_TYPE_ALL
);
vector
<
cl
::
Device
>
devices
=
context
.
getInfo
<
CL_CONTEXT_DEVICES
>
();
vector
<
cl
::
Device
>
devices
=
context
.
getInfo
<
CL_CONTEXT_DEVICES
>
();
const
int
minThreadBlockSize
=
32
;
const
int
minThreadBlockSize
=
32
;
...
@@ -79,6 +80,7 @@ OpenCLContext::~OpenCLContext() {
...
@@ -79,6 +80,7 @@ OpenCLContext::~OpenCLContext() {
delete
forceBuffers
;
delete
forceBuffers
;
delete
energyBuffer
;
delete
energyBuffer
;
delete
atomIndex
;
delete
atomIndex
;
delete
integration
;
}
}
void
OpenCLContext
::
initialize
(
const
System
&
system
)
{
void
OpenCLContext
::
initialize
(
const
System
&
system
)
{
...
@@ -93,7 +95,7 @@ void OpenCLContext::initialize(const System& system) {
...
@@ -93,7 +95,7 @@ void OpenCLContext::initialize(const System& system) {
posq
=
new
OpenCLArray
<
mm_float4
>
(
*
this
,
paddedNumAtoms
,
"posq"
,
true
);
posq
=
new
OpenCLArray
<
mm_float4
>
(
*
this
,
paddedNumAtoms
,
"posq"
,
true
);
velm
=
new
OpenCLArray
<
mm_float4
>
(
*
this
,
paddedNumAtoms
,
"velm"
,
true
);
velm
=
new
OpenCLArray
<
mm_float4
>
(
*
this
,
paddedNumAtoms
,
"velm"
,
true
);
for
(
int
i
=
0
;
i
<
numAtoms
;
i
++
)
for
(
int
i
=
0
;
i
<
numAtoms
;
i
++
)
(
*
velm
)[
i
].
w
=
system
.
getParticleMass
(
i
);
(
*
velm
)[
i
].
w
=
(
float
)
(
1.0
/
system
.
getParticleMass
(
i
)
)
;
velm
->
upload
();
velm
->
upload
();
numForceBuffers
=
1
;
numForceBuffers
=
1
;
for
(
int
i
=
0
;
i
<
(
int
)
forces
.
size
();
i
++
)
for
(
int
i
=
0
;
i
<
(
int
)
forces
.
size
();
i
++
)
...
@@ -105,6 +107,7 @@ void OpenCLContext::initialize(const System& system) {
...
@@ -105,6 +107,7 @@ void OpenCLContext::initialize(const System& system) {
for
(
int
i
=
0
;
i
<
paddedNumAtoms
;
++
i
)
for
(
int
i
=
0
;
i
<
paddedNumAtoms
;
++
i
)
(
*
atomIndex
)[
i
]
=
i
;
(
*
atomIndex
)[
i
]
=
i
;
atomIndex
->
upload
();
atomIndex
->
upload
();
integration
=
new
OpenCLIntegrationUtilities
(
*
this
,
system
);
}
}
void
OpenCLContext
::
addForce
(
OpenCLForceInfo
*
force
)
{
void
OpenCLContext
::
addForce
(
OpenCLForceInfo
*
force
)
{
...
@@ -144,8 +147,7 @@ void OpenCLContext::executeKernel(cl::Kernel& kernel, int workUnits) {
...
@@ -144,8 +147,7 @@ void OpenCLContext::executeKernel(cl::Kernel& kernel, int workUnits) {
}
}
catch
(
cl
::
Error
err
)
{
catch
(
cl
::
Error
err
)
{
stringstream
str
;
stringstream
str
;
str
<<
"Error invoking kernel "
;
str
<<
"Error invoking kernel "
<<
kernel
.
getInfo
<
CL_KERNEL_FUNCTION_NAME
>
()
<<
": "
<<
err
.
what
()
<<
" ("
<<
err
.
err
()
<<
")"
;
str
<<
kernel
.
getInfo
<
CL_KERNEL_FUNCTION_NAME
>
()
<<
": "
<<
err
.
what
()
<<
" ("
<<
err
.
err
()
<<
")"
;
throw
OpenMMException
(
str
.
str
());
throw
OpenMMException
(
str
.
str
());
}
}
}
}
...
...
platforms/opencl/src/OpenCLContext.h
View file @
efc1083e
...
@@ -35,6 +35,7 @@ namespace OpenMM {
...
@@ -35,6 +35,7 @@ namespace OpenMM {
template
<
class
T
>
template
<
class
T
>
class
OpenCLArray
;
class
OpenCLArray
;
class
OpenCLForceInfo
;
class
OpenCLForceInfo
;
class
OpenCLIntegrationUtilities
;
class
System
;
class
System
;
/**
/**
...
@@ -100,7 +101,7 @@ public:
...
@@ -100,7 +101,7 @@ public:
return
*
posq
;
return
*
posq
;
}
}
/**
/**
* Get the array which contains the velocity and massof each atom.
* Get the array which contains the velocity and
inverse
mass
of each atom.
*/
*/
OpenCLArray
<
mm_float4
>&
getVelm
()
{
OpenCLArray
<
mm_float4
>&
getVelm
()
{
return
*
velm
;
return
*
velm
;
...
@@ -160,6 +161,30 @@ public:
...
@@ -160,6 +161,30 @@ public:
* @param numBuffers the number of buffers packed into the array
* @param numBuffers the number of buffers packed into the array
*/
*/
void
reduceBuffer
(
OpenCLArray
<
mm_float4
>&
array
,
int
numBuffers
);
void
reduceBuffer
(
OpenCLArray
<
mm_float4
>&
array
,
int
numBuffers
);
/**
* Get the current simulation time.
*/
double
getTime
()
{
return
time
;
}
/**
* Set the current simulation time.
*/
void
setTime
(
double
t
)
{
time
=
t
;
}
/**
* Get the number of integration steps that have been taken.
*/
int
getStepCount
()
{
return
stepCount
;
}
/**
* Set the number of integration steps that have been taken.
*/
void
setStepCount
(
int
steps
)
{
stepCount
=
steps
;;
}
/**
/**
* Get the number of atoms.
* Get the number of atoms.
*/
*/
...
@@ -197,7 +222,15 @@ public:
...
@@ -197,7 +222,15 @@ public:
int
getNumForceBuffers
()
const
{
int
getNumForceBuffers
()
const
{
return
numForceBuffers
;
return
numForceBuffers
;
}
}
/**
* Get the OpenCLIntegrationUtilities for this context.
*/
OpenCLIntegrationUtilities
&
getIntegrationUtilties
()
{
return
*
integration
;
}
private:
private:
double
time
;
int
stepCount
;
int
numAtoms
;
int
numAtoms
;
int
paddedNumAtoms
;
int
paddedNumAtoms
;
int
numAtomBlocks
;
int
numAtomBlocks
;
...
@@ -217,6 +250,7 @@ private:
...
@@ -217,6 +250,7 @@ private:
OpenCLArray
<
mm_float4
>*
forceBuffers
;
OpenCLArray
<
mm_float4
>*
forceBuffers
;
OpenCLArray
<
cl_float
>*
energyBuffer
;
OpenCLArray
<
cl_float
>*
energyBuffer
;
OpenCLArray
<
cl_int
>*
atomIndex
;
OpenCLArray
<
cl_int
>*
atomIndex
;
OpenCLIntegrationUtilities
*
integration
;
};
};
}
// namespace OpenMM
}
// namespace OpenMM
...
...
platforms/opencl/src/OpenCLIntegrationUtilities.cpp
0 → 100644
View file @
efc1083e
/* -------------------------------------------------------------------------- *
* OpenMM *
* -------------------------------------------------------------------------- *
* This is part of the OpenMM molecular simulation toolkit originating from *
* Simbios, the NIH National Center for Physics-Based Simulation of *
* Biological Structures at Stanford, funded under the NIH Roadmap for *
* Medical Research, grant U54 GM072970. See https://simtk.org. *
* *
* Portions copyright (c) 2009 Stanford University and the Authors. *
* Authors: Peter Eastman *
* Contributors: *
* *
* This program is free software: you can redistribute it and/or modify *
* it under the terms of the GNU Lesser General Public License as published *
* by the Free Software Foundation, either version 3 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU Lesser General Public License for more details. *
* *
* You should have received a copy of the GNU Lesser General Public License *
* along with this program. If not, see <http://www.gnu.org/licenses/>. *
* -------------------------------------------------------------------------- */
#include "OpenCLIntegrationUtilities.h"
#include "OpenCLArray.h"
#include <map>
using
namespace
OpenMM
;
using
namespace
std
;
struct
OpenCLIntegrationUtilities
::
ShakeCluster
{
int
centralID
;
int
peripheralID
[
3
];
int
size
;
bool
valid
;
double
distance
;
double
centralInvMass
,
peripheralInvMass
;
ShakeCluster
()
:
valid
(
true
)
{
}
ShakeCluster
(
int
centralID
,
double
invMass
)
:
centralID
(
centralID
),
centralInvMass
(
invMass
),
size
(
0
),
valid
(
true
)
{
}
void
addAtom
(
int
id
,
double
dist
,
double
invMass
)
{
if
(
size
==
3
||
(
size
>
0
&&
dist
!=
distance
)
||
(
size
>
0
&&
invMass
!=
peripheralInvMass
))
valid
=
false
;
else
{
peripheralID
[
size
++
]
=
id
;
distance
=
dist
;
peripheralInvMass
=
invMass
;
}
}
void
markInvalid
(
map
<
int
,
ShakeCluster
>&
allClusters
,
vector
<
bool
>&
invalidForShake
)
{
valid
=
false
;
invalidForShake
[
centralID
]
=
true
;
for
(
int
i
=
0
;
i
<
size
;
i
++
)
{
invalidForShake
[
peripheralID
[
i
]]
=
true
;
map
<
int
,
ShakeCluster
>::
iterator
otherCluster
=
allClusters
.
find
(
peripheralID
[
i
]);
if
(
otherCluster
!=
allClusters
.
end
()
&&
otherCluster
->
second
.
valid
)
otherCluster
->
second
.
markInvalid
(
allClusters
,
invalidForShake
);
}
}
};
OpenCLIntegrationUtilities
::
OpenCLIntegrationUtilities
(
OpenCLContext
&
context
,
const
System
&
system
)
:
context
(
context
),
oldPos
(
NULL
),
posDelta
(
NULL
),
settleAtoms
(
NULL
),
settleParams
(
NULL
),
shakeAtoms
(
NULL
),
shakeParams
(
NULL
)
{
// Create workspace arrays.
posDelta
=
new
OpenCLArray
<
mm_float4
>
(
context
,
context
.
getPaddedNumAtoms
(),
"posDelta"
);
oldPos
=
new
OpenCLArray
<
mm_float4
>
(
context
,
context
.
getPaddedNumAtoms
(),
"oldPos"
);
// Create kernels for enforcing constraints.
cl
::
Program
program
=
context
.
createProgram
(
context
.
loadSourceFromFile
(
"shakeHydrogens.cl"
));
shakeKernel
=
cl
::
Kernel
(
program
,
"applyShakeToHydrogens"
);
// Record the set of constraints and how many constraints each atom is involved in.
int
numConstraints
=
system
.
getNumConstraints
();
vector
<
int
>
atom1
(
numConstraints
);
vector
<
int
>
atom2
(
numConstraints
);
vector
<
double
>
distance
(
numConstraints
);
vector
<
int
>
constraintCount
(
context
.
getNumAtoms
(),
0
);
for
(
int
i
=
0
;
i
<
numConstraints
;
i
++
)
{
system
.
getConstraintParameters
(
i
,
atom1
[
i
],
atom2
[
i
],
distance
[
i
]);
constraintCount
[
atom1
[
i
]]
++
;
constraintCount
[
atom2
[
i
]]
++
;
}
// Identify clusters of three atoms that can be treated with SETTLE. First, for every
// atom that might be part of such a cluster, make a list of the two other atoms it is
// connected to.
vector
<
map
<
int
,
float
>
>
settleConstraints
(
system
.
getNumParticles
());
for
(
int
i
=
0
;
i
<
(
int
)
atom1
.
size
();
i
++
)
{
if
(
constraintCount
[
atom1
[
i
]]
==
2
&&
constraintCount
[
atom2
[
i
]]
==
2
)
{
settleConstraints
[
atom1
[
i
]][
atom2
[
i
]]
=
distance
[
i
];
settleConstraints
[
atom2
[
i
]][
atom1
[
i
]]
=
distance
[
i
];
}
}
// Now remove the ones that don't actually form closed loops of three atoms.
vector
<
int
>
settleClusters
;
for
(
int
i
=
0
;
i
<
(
int
)
settleConstraints
.
size
();
i
++
)
{
if
(
settleConstraints
[
i
].
size
()
==
2
)
{
int
partner1
=
settleConstraints
[
i
].
begin
()
->
first
;
int
partner2
=
(
++
settleConstraints
[
i
].
begin
())
->
first
;
if
(
settleConstraints
[
partner1
].
size
()
!=
2
||
settleConstraints
[
partner2
].
size
()
!=
2
||
settleConstraints
[
partner1
].
find
(
partner2
)
==
settleConstraints
[
partner1
].
end
())
settleConstraints
[
i
].
clear
();
else
if
(
i
<
partner1
&&
i
<
partner2
)
settleClusters
.
push_back
(
i
);
}
else
settleConstraints
[
i
].
clear
();
}
// Record the SETTLE clusters.
vector
<
bool
>
isShakeAtom
(
system
.
getNumParticles
(),
false
);
if
(
settleClusters
.
size
()
>
0
)
{
vector
<
mm_int4
>
atoms
(
settleAtoms
->
getSize
());
vector
<
mm_float2
>
params
(
settleParams
->
getSize
());
for
(
int
i
=
0
;
i
<
(
int
)
settleClusters
.
size
();
i
++
)
{
int
atom1
=
settleClusters
[
i
];
int
atom2
=
settleConstraints
[
atom1
].
begin
()
->
first
;
int
atom3
=
(
++
settleConstraints
[
atom1
].
begin
())
->
first
;
float
dist12
=
settleConstraints
[
atom1
].
find
(
atom2
)
->
second
;
float
dist13
=
settleConstraints
[
atom1
].
find
(
atom3
)
->
second
;
float
dist23
=
settleConstraints
[
atom2
].
find
(
atom3
)
->
second
;
if
(
dist12
==
dist13
)
{
// atom1 is the central atom
atoms
.
push_back
((
mm_int4
)
{
atom1
,
atom2
,
atom3
,
0
});
params
.
push_back
((
mm_float2
)
{
dist12
,
dist23
});
}
else
if
(
dist12
==
dist23
)
{
// atom2 is the central atom
atoms
.
push_back
((
mm_int4
)
{
atom2
,
atom1
,
atom3
,
0
});
params
.
push_back
((
mm_float2
)
{
dist12
,
dist13
});
}
else
if
(
dist13
==
dist23
)
{
// atom3 is the central atom
atoms
.
push_back
((
mm_int4
)
{
atom3
,
atom1
,
atom2
,
0
});
params
.
push_back
((
mm_float2
)
{
dist13
,
dist12
});
}
else
throw
OpenMMException
(
"Two of the three distances constrained with SETTLE must be the same."
);
isShakeAtom
[
atom1
]
=
true
;
isShakeAtom
[
atom2
]
=
true
;
isShakeAtom
[
atom3
]
=
true
;
}
settleAtoms
=
new
OpenCLArray
<
mm_int4
>
(
context
,
atoms
.
size
(),
"settleAtoms"
);
settleParams
=
new
OpenCLArray
<
mm_float2
>
(
context
,
params
.
size
(),
"settleParams"
);
settleAtoms
->
upload
(
atoms
);
settleParams
->
upload
(
params
);
}
// Find clusters consisting of a central atom with up to three peripheral atoms.
map
<
int
,
ShakeCluster
>
clusters
;
vector
<
bool
>
invalidForShake
(
system
.
getNumParticles
(),
false
);
for
(
int
i
=
0
;
i
<
(
int
)
atom1
.
size
();
i
++
)
{
if
(
isShakeAtom
[
atom1
[
i
]])
continue
;
// This is being taken care of with SETTLE.
// Determine which is the central atom.
bool
firstIsCentral
;
if
(
constraintCount
[
atom1
[
i
]]
>
1
)
firstIsCentral
=
true
;
else
if
(
constraintCount
[
atom2
[
i
]]
>
1
)
firstIsCentral
=
false
;
else
if
(
atom1
[
i
]
<
atom2
[
i
])
firstIsCentral
=
true
;
else
firstIsCentral
=
false
;
int
centralID
,
peripheralID
;
if
(
firstIsCentral
)
{
centralID
=
atom1
[
i
];
peripheralID
=
atom2
[
i
];
}
else
{
centralID
=
atom2
[
i
];
peripheralID
=
atom1
[
i
];
}
// Add it to the cluster.
if
(
clusters
.
find
(
centralID
)
==
clusters
.
end
())
{
clusters
[
centralID
]
=
ShakeCluster
(
centralID
,
1.0
/
system
.
getParticleMass
(
centralID
));
}
ShakeCluster
&
cluster
=
clusters
[
centralID
];
cluster
.
addAtom
(
peripheralID
,
distance
[
i
],
1.0
/
system
.
getParticleMass
(
peripheralID
));
if
(
constraintCount
[
peripheralID
]
!=
1
||
invalidForShake
[
atom1
[
i
]]
||
invalidForShake
[
atom2
[
i
]])
{
cluster
.
markInvalid
(
clusters
,
invalidForShake
);
map
<
int
,
ShakeCluster
>::
iterator
otherCluster
=
clusters
.
find
(
peripheralID
);
if
(
otherCluster
!=
clusters
.
end
()
&&
otherCluster
->
second
.
valid
)
otherCluster
->
second
.
markInvalid
(
clusters
,
invalidForShake
);
}
}
int
validShakeClusters
=
0
;
for
(
map
<
int
,
ShakeCluster
>::
iterator
iter
=
clusters
.
begin
();
iter
!=
clusters
.
end
();
++
iter
)
{
ShakeCluster
&
cluster
=
iter
->
second
;
if
(
cluster
.
valid
)
{
cluster
.
valid
=
!
invalidForShake
[
cluster
.
centralID
];
for
(
int
i
=
0
;
i
<
cluster
.
size
;
i
++
)
if
(
invalidForShake
[
cluster
.
peripheralID
[
i
]])
cluster
.
valid
=
false
;
if
(
cluster
.
valid
)
++
validShakeClusters
;
}
}
// Record the SHAKE clusters.
if
(
validShakeClusters
>
0
)
{
vector
<
mm_int4
>
atoms
(
shakeAtoms
->
getSize
());
vector
<
mm_float4
>
params
(
shakeParams
->
getSize
());
int
index
=
0
;
for
(
map
<
int
,
ShakeCluster
>::
const_iterator
iter
=
clusters
.
begin
();
iter
!=
clusters
.
end
();
++
iter
)
{
const
ShakeCluster
&
cluster
=
iter
->
second
;
if
(
!
cluster
.
valid
)
continue
;
atoms
.
push_back
((
mm_int4
)
{
cluster
.
centralID
,
cluster
.
peripheralID
[
0
],
(
cluster
.
size
>
1
?
cluster
.
peripheralID
[
1
]
:
-
1
),
(
cluster
.
size
>
2
?
cluster
.
peripheralID
[
2
]
:
-
1
)});
params
.
push_back
((
mm_float4
)
{
cluster
.
centralInvMass
,
0.5
f
/
(
cluster
.
centralInvMass
+
cluster
.
peripheralInvMass
),
cluster
.
distance
*
cluster
.
distance
,
cluster
.
peripheralInvMass
});
isShakeAtom
[
cluster
.
centralID
]
=
true
;
isShakeAtom
[
cluster
.
peripheralID
[
0
]]
=
true
;
if
(
cluster
.
size
>
1
)
isShakeAtom
[
cluster
.
peripheralID
[
1
]]
=
true
;
if
(
cluster
.
size
>
2
)
isShakeAtom
[
cluster
.
peripheralID
[
2
]]
=
true
;
++
index
;
}
shakeAtoms
=
new
OpenCLArray
<
mm_int4
>
(
context
,
atoms
.
size
(),
"shakeAtoms"
);
shakeParams
=
new
OpenCLArray
<
mm_float4
>
(
context
,
params
.
size
(),
"shakeParams"
);
shakeAtoms
->
upload
(
atoms
);
shakeParams
->
upload
(
params
);
}
}
OpenCLIntegrationUtilities
::~
OpenCLIntegrationUtilities
()
{
if
(
posDelta
!=
NULL
)
delete
posDelta
;
if
(
oldPos
!=
NULL
)
delete
oldPos
;
if
(
settleAtoms
!=
NULL
)
delete
settleAtoms
;
if
(
settleParams
!=
NULL
)
delete
settleParams
;
if
(
shakeAtoms
!=
NULL
)
delete
shakeAtoms
;
if
(
shakeParams
!=
NULL
)
delete
shakeParams
;
}
void
OpenCLIntegrationUtilities
::
applyConstraints
(
double
tol
,
OpenCLArray
<
mm_float4
>&
oldPositions
,
OpenCLArray
<
mm_float4
>&
positionDeltas
,
OpenCLArray
<
mm_float4
>&
newDeltas
)
{
if
(
shakeAtoms
!=
NULL
)
{
shakeKernel
.
setArg
<
cl_int
>
(
0
,
shakeAtoms
->
getSize
());
shakeKernel
.
setArg
<
cl_float
>
(
1
,
tol
);
shakeKernel
.
setArg
<
cl
::
Buffer
>
(
2
,
oldPositions
.
getDeviceBuffer
());
shakeKernel
.
setArg
<
cl
::
Buffer
>
(
3
,
positionDeltas
.
getDeviceBuffer
());
shakeKernel
.
setArg
<
cl
::
Buffer
>
(
4
,
newDeltas
.
getDeviceBuffer
());
shakeKernel
.
setArg
<
cl
::
Buffer
>
(
5
,
shakeAtoms
->
getDeviceBuffer
());
shakeKernel
.
setArg
<
cl
::
Buffer
>
(
6
,
shakeParams
->
getDeviceBuffer
());
context
.
executeKernel
(
shakeKernel
,
shakeAtoms
->
getSize
());
}
}
//
//void OpenCLIntegrationUtilities::clearBuffer(OpenCLArray<mm_float4>& array) {
// clearBufferKernel.setArg<cl::Buffer>(0, array.getDeviceBuffer());
// clearBufferKernel.setArg<cl_int>(1, array.getSize()*4);
// executeKernel(clearBufferKernel, array.getSize()*4);
//}
//
//void OpenCLIntegrationUtilities::reduceBuffer(OpenCLArray<mm_float4>& array, int numBuffers) {
// int bufferSize = array.getSize()/numBuffers;
// reduceFloat4Kernel.setArg<cl::Buffer>(0, array.getDeviceBuffer());
// reduceFloat4Kernel.setArg<cl_int>(1, bufferSize);
// reduceFloat4Kernel.setArg<cl_int>(2, numBuffers);
// executeKernel(reduceFloat4Kernel, bufferSize);
//}
platforms/opencl/src/OpenCLIntegrationUtilities.h
0 → 100644
View file @
efc1083e
#ifndef OPENMM_OPENCLINTEGRATIONUTILITIES_H_
#define OPENMM_OPENCLINTEGRATIONUTILITIES_H_
/* -------------------------------------------------------------------------- *
* OpenMM *
* -------------------------------------------------------------------------- *
* This is part of the OpenMM molecular simulation toolkit originating from *
* Simbios, the NIH National Center for Physics-Based Simulation of *
* Biological Structures at Stanford, funded under the NIH Roadmap for *
* Medical Research, grant U54 GM072970. See https://simtk.org. *
* *
* Portions copyright (c) 2009 Stanford University and the Authors. *
* Authors: Peter Eastman *
* Contributors: *
* *
* This program is free software: you can redistribute it and/or modify *
* it under the terms of the GNU Lesser General Public License as published *
* by the Free Software Foundation, either version 3 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU Lesser General Public License for more details. *
* *
* You should have received a copy of the GNU Lesser General Public License *
* along with this program. If not, see <http://www.gnu.org/licenses/>. *
* -------------------------------------------------------------------------- */
#include "OpenMM/System.h"
#include "OpenCLContext.h"
namespace
OpenMM
{
/**
* This class implements features that are used by many different integrators, including
* common workspace arrays and enforcing constraints.
*/
class
OpenCLIntegrationUtilities
{
public:
OpenCLIntegrationUtilities
(
OpenCLContext
&
context
,
const
System
&
system
);
~
OpenCLIntegrationUtilities
();
/**
* Get the array which contains position deltas.
*/
OpenCLArray
<
mm_float4
>&
getPosDelta
()
{
return
*
posDelta
;
}
/**
* Get the array which contains positions from before the current time step.
*/
OpenCLArray
<
mm_float4
>&
getOldPos
()
{
return
*
oldPos
;
}
/**
* Apply constraints to the atom positions.
*
* @param tol the constraint tolerance
* @param oldPositions the atom positions from before the current time step
* @param positionDeltas the offsets being added to atom positions
* @param newDeltas the array to store constrained deltas into
*/
void
applyConstraints
(
double
tol
,
OpenCLArray
<
mm_float4
>&
oldPositions
,
OpenCLArray
<
mm_float4
>&
positionDeltas
,
OpenCLArray
<
mm_float4
>&
newDeltas
);
private:
OpenCLContext
&
context
;
// cl::Kernel clearBufferKernel;
cl
::
Kernel
shakeKernel
;
OpenCLArray
<
mm_float4
>*
posDelta
;
OpenCLArray
<
mm_float4
>*
oldPos
;
OpenCLArray
<
mm_int4
>*
settleAtoms
;
OpenCLArray
<
mm_float2
>*
settleParams
;
OpenCLArray
<
mm_int4
>*
shakeAtoms
;
OpenCLArray
<
mm_float4
>*
shakeParams
;
struct
ShakeCluster
;
};
}
// namespace OpenMM
#endif
/*OPENMM_OPENCLINTEGRATIONUTILITIES_H_*/
platforms/opencl/src/OpenCLKernelFactory.cpp
View file @
efc1083e
...
@@ -33,39 +33,40 @@ using namespace OpenMM;
...
@@ -33,39 +33,40 @@ using namespace OpenMM;
KernelImpl
*
OpenCLKernelFactory
::
createKernelImpl
(
std
::
string
name
,
const
Platform
&
platform
,
ContextImpl
&
context
)
const
{
KernelImpl
*
OpenCLKernelFactory
::
createKernelImpl
(
std
::
string
name
,
const
Platform
&
platform
,
ContextImpl
&
context
)
const
{
OpenCLPlatform
::
PlatformData
&
data
=
*
static_cast
<
OpenCLPlatform
::
PlatformData
*>
(
context
.
getPlatformData
());
OpenCLPlatform
::
PlatformData
&
data
=
*
static_cast
<
OpenCLPlatform
::
PlatformData
*>
(
context
.
getPlatformData
());
OpenCLContext
&
cl
=
*
data
.
context
;
if
(
name
==
CalcForcesAndEnergyKernel
::
Name
())
if
(
name
==
CalcForcesAndEnergyKernel
::
Name
())
return
new
OpenCLCalcForcesAndEnergyKernel
(
name
,
platform
,
data
);
return
new
OpenCLCalcForcesAndEnergyKernel
(
name
,
platform
,
cl
);
if
(
name
==
UpdateStateDataKernel
::
Name
())
if
(
name
==
UpdateStateDataKernel
::
Name
())
return
new
OpenCLUpdateStateDataKernel
(
name
,
platform
,
data
);
return
new
OpenCLUpdateStateDataKernel
(
name
,
platform
,
cl
);
if
(
name
==
CalcHarmonicBondForceKernel
::
Name
())
if
(
name
==
CalcHarmonicBondForceKernel
::
Name
())
return
new
OpenCLCalcHarmonicBondForceKernel
(
name
,
platform
,
data
,
context
.
getSystem
());
return
new
OpenCLCalcHarmonicBondForceKernel
(
name
,
platform
,
cl
,
context
.
getSystem
());
if
(
name
==
CalcHarmonicAngleForceKernel
::
Name
())
if
(
name
==
CalcHarmonicAngleForceKernel
::
Name
())
return
new
OpenCLCalcHarmonicAngleForceKernel
(
name
,
platform
,
data
,
context
.
getSystem
());
return
new
OpenCLCalcHarmonicAngleForceKernel
(
name
,
platform
,
cl
,
context
.
getSystem
());
if
(
name
==
CalcPeriodicTorsionForceKernel
::
Name
())
if
(
name
==
CalcPeriodicTorsionForceKernel
::
Name
())
return
new
OpenCLCalcPeriodicTorsionForceKernel
(
name
,
platform
,
data
,
context
.
getSystem
());
return
new
OpenCLCalcPeriodicTorsionForceKernel
(
name
,
platform
,
cl
,
context
.
getSystem
());
if
(
name
==
CalcRBTorsionForceKernel
::
Name
())
if
(
name
==
CalcRBTorsionForceKernel
::
Name
())
return
new
OpenCLCalcRBTorsionForceKernel
(
name
,
platform
,
data
,
context
.
getSystem
());
return
new
OpenCLCalcRBTorsionForceKernel
(
name
,
platform
,
cl
,
context
.
getSystem
());
// if (name == CalcNonbondedForceKernel::Name())
// if (name == CalcNonbondedForceKernel::Name())
// return new OpenCLCalcNonbondedForceKernel(name, platform,
data
, context.getSystem());
// return new OpenCLCalcNonbondedForceKernel(name, platform,
cl
, context.getSystem());
// if (name == CalcCustomNonbondedForceKernel::Name())
// if (name == CalcCustomNonbondedForceKernel::Name())
// return new OpenCLCalcCustomNonbondedForceKernel(name, platform,
data
, context.getSystem());
// return new OpenCLCalcCustomNonbondedForceKernel(name, platform,
cl
, context.getSystem());
// if (name == CalcGBSAOBCForceKernel::Name())
// if (name == CalcGBSAOBCForceKernel::Name())
// return new OpenCLCalcGBSAOBCForceKernel(name, platform,
data
);
// return new OpenCLCalcGBSAOBCForceKernel(name, platform,
cl
);
if
(
name
==
IntegrateVerletStepKernel
::
Name
())
if
(
name
==
IntegrateVerletStepKernel
::
Name
())
return
new
OpenCLIntegrateVerletStepKernel
(
name
,
platform
,
data
);
return
new
OpenCLIntegrateVerletStepKernel
(
name
,
platform
,
cl
);
// if (name == IntegrateLangevinStepKernel::Name())
// if (name == IntegrateLangevinStepKernel::Name())
// return new OpenCLIntegrateLangevinStepKernel(name, platform,
data
);
// return new OpenCLIntegrateLangevinStepKernel(name, platform,
cl
);
// if (name == IntegrateBrownianStepKernel::Name())
// if (name == IntegrateBrownianStepKernel::Name())
// return new OpenCLIntegrateBrownianStepKernel(name, platform,
data
);
// return new OpenCLIntegrateBrownianStepKernel(name, platform,
cl
);
// if (name == IntegrateVariableVerletStepKernel::Name())
// if (name == IntegrateVariableVerletStepKernel::Name())
// return new OpenCLIntegrateVariableVerletStepKernel(name, platform,
data
);
// return new OpenCLIntegrateVariableVerletStepKernel(name, platform,
cl
);
// if (name == IntegrateVariableLangevinStepKernel::Name())
// if (name == IntegrateVariableLangevinStepKernel::Name())
// return new OpenCLIntegrateVariableLangevinStepKernel(name, platform,
data
);
// return new OpenCLIntegrateVariableLangevinStepKernel(name, platform,
cl
);
// if (name == ApplyAndersenThermostatKernel::Name())
// if (name == ApplyAndersenThermostatKernel::Name())
// return new OpenCLApplyAndersenThermostatKernel(name, platform,
data
);
// return new OpenCLApplyAndersenThermostatKernel(name, platform,
cl
);
if
(
name
==
CalcKineticEnergyKernel
::
Name
())
if
(
name
==
CalcKineticEnergyKernel
::
Name
())
return
new
OpenCLCalcKineticEnergyKernel
(
name
,
platform
,
data
);
return
new
OpenCLCalcKineticEnergyKernel
(
name
,
platform
,
cl
);
// if (name == RemoveCMMotionKernel::Name())
// if (name == RemoveCMMotionKernel::Name())
// return new OpenCLRemoveCMMotionKernel(name, platform,
data
);
// return new OpenCLRemoveCMMotionKernel(name, platform,
cl
);
throw
OpenMMException
((
std
::
string
(
"Tried to create kernel with illegal kernel name '"
)
+
name
+
"'"
).
c_str
());
throw
OpenMMException
((
std
::
string
(
"Tried to create kernel with illegal kernel name '"
)
+
name
+
"'"
).
c_str
());
}
}
platforms/opencl/src/OpenCLKernels.cpp
View file @
efc1083e
...
@@ -29,6 +29,7 @@
...
@@ -29,6 +29,7 @@
#include "openmm/LangevinIntegrator.h"
#include "openmm/LangevinIntegrator.h"
#include "openmm/Context.h"
#include "openmm/Context.h"
#include "openmm/internal/ContextImpl.h"
#include "openmm/internal/ContextImpl.h"
#include "OpenCLIntegrationUtilities.h"
#include <cmath>
#include <cmath>
using
namespace
OpenMM
;
using
namespace
OpenMM
;
...
@@ -38,19 +39,19 @@ void OpenCLCalcForcesAndEnergyKernel::initialize(const System& system) {
...
@@ -38,19 +39,19 @@ void OpenCLCalcForcesAndEnergyKernel::initialize(const System& system) {
}
}
void
OpenCLCalcForcesAndEnergyKernel
::
beginForceComputation
(
ContextImpl
&
context
)
{
void
OpenCLCalcForcesAndEnergyKernel
::
beginForceComputation
(
ContextImpl
&
context
)
{
data
.
context
->
clearBuffer
(
data
.
context
->
getForceBuffers
());
cl
.
clearBuffer
(
cl
.
getForceBuffers
());
}
}
void
OpenCLCalcForcesAndEnergyKernel
::
finishForceComputation
(
ContextImpl
&
context
)
{
void
OpenCLCalcForcesAndEnergyKernel
::
finishForceComputation
(
ContextImpl
&
context
)
{
data
.
context
->
reduceBuffer
(
data
.
context
->
getForceBuffers
(),
data
.
context
->
getNumForceBuffers
());
cl
.
reduceBuffer
(
cl
.
getForceBuffers
(),
cl
.
getNumForceBuffers
());
}
}
void
OpenCLCalcForcesAndEnergyKernel
::
beginEnergyComputation
(
ContextImpl
&
context
)
{
void
OpenCLCalcForcesAndEnergyKernel
::
beginEnergyComputation
(
ContextImpl
&
context
)
{
data
.
context
->
clearBuffer
(
data
.
context
->
getEnergyBuffer
());
cl
.
clearBuffer
(
cl
.
getEnergyBuffer
());
}
}
double
OpenCLCalcForcesAndEnergyKernel
::
finishEnergyComputation
(
ContextImpl
&
context
)
{
double
OpenCLCalcForcesAndEnergyKernel
::
finishEnergyComputation
(
ContextImpl
&
context
)
{
OpenCLArray
<
cl_float
>&
energy
=
data
.
context
->
getEnergyBuffer
();
OpenCLArray
<
cl_float
>&
energy
=
cl
.
getEnergyBuffer
();
energy
.
download
();
energy
.
download
();
double
sum
=
0.0
f
;
double
sum
=
0.0
f
;
for
(
int
i
=
0
;
i
<
energy
.
getSize
();
i
++
)
for
(
int
i
=
0
;
i
<
energy
.
getSize
();
i
++
)
...
@@ -62,17 +63,17 @@ void OpenCLUpdateStateDataKernel::initialize(const System& system) {
...
@@ -62,17 +63,17 @@ void OpenCLUpdateStateDataKernel::initialize(const System& system) {
}
}
double
OpenCLUpdateStateDataKernel
::
getTime
(
const
ContextImpl
&
context
)
const
{
double
OpenCLUpdateStateDataKernel
::
getTime
(
const
ContextImpl
&
context
)
const
{
return
data
.
t
ime
;
return
cl
.
getT
ime
()
;
}
}
void
OpenCLUpdateStateDataKernel
::
setTime
(
ContextImpl
&
context
,
double
time
)
{
void
OpenCLUpdateStateDataKernel
::
setTime
(
ContextImpl
&
context
,
double
time
)
{
data
.
time
=
time
;
cl
.
setTime
(
time
)
;
}
}
void
OpenCLUpdateStateDataKernel
::
getPositions
(
ContextImpl
&
context
,
std
::
vector
<
Vec3
>&
positions
)
{
void
OpenCLUpdateStateDataKernel
::
getPositions
(
ContextImpl
&
context
,
std
::
vector
<
Vec3
>&
positions
)
{
OpenCLArray
<
mm_float4
>&
posq
=
data
.
context
->
getPosq
();
OpenCLArray
<
mm_float4
>&
posq
=
cl
.
getPosq
();
posq
.
download
();
posq
.
download
();
OpenCLArray
<
cl_int
>&
order
=
data
.
context
->
getAtomIndex
();
OpenCLArray
<
cl_int
>&
order
=
cl
.
getAtomIndex
();
int
numParticles
=
context
.
getSystem
().
getNumParticles
();
int
numParticles
=
context
.
getSystem
().
getNumParticles
();
positions
.
resize
(
numParticles
);
positions
.
resize
(
numParticles
);
for
(
int
i
=
0
;
i
<
numParticles
;
++
i
)
{
for
(
int
i
=
0
;
i
<
numParticles
;
++
i
)
{
...
@@ -84,8 +85,8 @@ void OpenCLUpdateStateDataKernel::getPositions(ContextImpl& context, std::vector
...
@@ -84,8 +85,8 @@ void OpenCLUpdateStateDataKernel::getPositions(ContextImpl& context, std::vector
}
}
void
OpenCLUpdateStateDataKernel
::
setPositions
(
ContextImpl
&
context
,
const
std
::
vector
<
Vec3
>&
positions
)
{
void
OpenCLUpdateStateDataKernel
::
setPositions
(
ContextImpl
&
context
,
const
std
::
vector
<
Vec3
>&
positions
)
{
OpenCLArray
<
mm_float4
>&
posq
=
data
.
context
->
getPosq
();
OpenCLArray
<
mm_float4
>&
posq
=
cl
.
getPosq
();
OpenCLArray
<
cl_int
>&
order
=
data
.
context
->
getAtomIndex
();
OpenCLArray
<
cl_int
>&
order
=
cl
.
getAtomIndex
();
int
numParticles
=
context
.
getSystem
().
getNumParticles
();
int
numParticles
=
context
.
getSystem
().
getNumParticles
();
for
(
int
i
=
0
;
i
<
numParticles
;
++
i
)
{
for
(
int
i
=
0
;
i
<
numParticles
;
++
i
)
{
mm_float4
&
pos
=
posq
[
i
];
mm_float4
&
pos
=
posq
[
i
];
...
@@ -100,9 +101,9 @@ void OpenCLUpdateStateDataKernel::setPositions(ContextImpl& context, const std::
...
@@ -100,9 +101,9 @@ void OpenCLUpdateStateDataKernel::setPositions(ContextImpl& context, const std::
}
}
void
OpenCLUpdateStateDataKernel
::
getVelocities
(
ContextImpl
&
context
,
std
::
vector
<
Vec3
>&
velocities
)
{
void
OpenCLUpdateStateDataKernel
::
getVelocities
(
ContextImpl
&
context
,
std
::
vector
<
Vec3
>&
velocities
)
{
OpenCLArray
<
mm_float4
>&
velm
=
data
.
context
->
getVelm
();
OpenCLArray
<
mm_float4
>&
velm
=
cl
.
getVelm
();
velm
.
download
();
velm
.
download
();
OpenCLArray
<
cl_int
>&
order
=
data
.
context
->
getAtomIndex
();
OpenCLArray
<
cl_int
>&
order
=
cl
.
getAtomIndex
();
int
numParticles
=
context
.
getSystem
().
getNumParticles
();
int
numParticles
=
context
.
getSystem
().
getNumParticles
();
velocities
.
resize
(
numParticles
);
velocities
.
resize
(
numParticles
);
for
(
int
i
=
0
;
i
<
numParticles
;
++
i
)
{
for
(
int
i
=
0
;
i
<
numParticles
;
++
i
)
{
...
@@ -112,8 +113,8 @@ void OpenCLUpdateStateDataKernel::getVelocities(ContextImpl& context, std::vecto
...
@@ -112,8 +113,8 @@ void OpenCLUpdateStateDataKernel::getVelocities(ContextImpl& context, std::vecto
}
}
void
OpenCLUpdateStateDataKernel
::
setVelocities
(
ContextImpl
&
context
,
const
std
::
vector
<
Vec3
>&
velocities
)
{
void
OpenCLUpdateStateDataKernel
::
setVelocities
(
ContextImpl
&
context
,
const
std
::
vector
<
Vec3
>&
velocities
)
{
OpenCLArray
<
mm_float4
>&
velm
=
data
.
context
->
getVelm
();
OpenCLArray
<
mm_float4
>&
velm
=
cl
.
getVelm
();
OpenCLArray
<
cl_int
>&
order
=
data
.
context
->
getAtomIndex
();
OpenCLArray
<
cl_int
>&
order
=
cl
.
getAtomIndex
();
int
numParticles
=
context
.
getSystem
().
getNumParticles
();
int
numParticles
=
context
.
getSystem
().
getNumParticles
();
for
(
int
i
=
0
;
i
<
numParticles
;
++
i
)
{
for
(
int
i
=
0
;
i
<
numParticles
;
++
i
)
{
mm_float4
&
vel
=
velm
[
i
];
mm_float4
&
vel
=
velm
[
i
];
...
@@ -126,9 +127,9 @@ void OpenCLUpdateStateDataKernel::setVelocities(ContextImpl& context, const std:
...
@@ -126,9 +127,9 @@ void OpenCLUpdateStateDataKernel::setVelocities(ContextImpl& context, const std:
}
}
void
OpenCLUpdateStateDataKernel
::
getForces
(
ContextImpl
&
context
,
std
::
vector
<
Vec3
>&
forces
)
{
void
OpenCLUpdateStateDataKernel
::
getForces
(
ContextImpl
&
context
,
std
::
vector
<
Vec3
>&
forces
)
{
OpenCLArray
<
mm_float4
>&
force
=
data
.
context
->
getForce
();
OpenCLArray
<
mm_float4
>&
force
=
cl
.
getForce
();
force
.
download
();
force
.
download
();
OpenCLArray
<
cl_int
>&
order
=
data
.
context
->
getAtomIndex
();
OpenCLArray
<
cl_int
>&
order
=
cl
.
getAtomIndex
();
int
numParticles
=
context
.
getSystem
().
getNumParticles
();
int
numParticles
=
context
.
getSystem
().
getNumParticles
();
forces
.
resize
(
numParticles
);
forces
.
resize
(
numParticles
);
for
(
int
i
=
0
;
i
<
numParticles
;
++
i
)
{
for
(
int
i
=
0
;
i
<
numParticles
;
++
i
)
{
...
@@ -172,8 +173,8 @@ OpenCLCalcHarmonicBondForceKernel::~OpenCLCalcHarmonicBondForceKernel() {
...
@@ -172,8 +173,8 @@ OpenCLCalcHarmonicBondForceKernel::~OpenCLCalcHarmonicBondForceKernel() {
void
OpenCLCalcHarmonicBondForceKernel
::
initialize
(
const
System
&
system
,
const
HarmonicBondForce
&
force
)
{
void
OpenCLCalcHarmonicBondForceKernel
::
initialize
(
const
System
&
system
,
const
HarmonicBondForce
&
force
)
{
numBonds
=
force
.
getNumBonds
();
numBonds
=
force
.
getNumBonds
();
params
=
new
OpenCLArray
<
mm_float2
>
(
*
data
.
context
,
numBonds
,
"bondParams"
);
params
=
new
OpenCLArray
<
mm_float2
>
(
cl
,
numBonds
,
"bondParams"
);
indices
=
new
OpenCLArray
<
mm_int4
>
(
*
data
.
context
,
numBonds
,
"bondIndices"
);
indices
=
new
OpenCLArray
<
mm_int4
>
(
cl
,
numBonds
,
"bondIndices"
);
vector
<
int
>
forceBufferCounter
(
system
.
getNumParticles
(),
0
);
vector
<
int
>
forceBufferCounter
(
system
.
getNumParticles
(),
0
);
vector
<
mm_float2
>
paramVector
(
numBonds
);
vector
<
mm_float2
>
paramVector
(
numBonds
);
vector
<
mm_int4
>
indicesVector
(
numBonds
);
vector
<
mm_int4
>
indicesVector
(
numBonds
);
...
@@ -191,20 +192,20 @@ void OpenCLCalcHarmonicBondForceKernel::initialize(const System& system, const H
...
@@ -191,20 +192,20 @@ void OpenCLCalcHarmonicBondForceKernel::initialize(const System& system, const H
for
(
int
i
=
0
;
i
<
forceBufferCounter
.
size
();
i
++
)
{
for
(
int
i
=
0
;
i
<
forceBufferCounter
.
size
();
i
++
)
{
maxBuffers
=
max
(
maxBuffers
,
forceBufferCounter
[
i
]);
maxBuffers
=
max
(
maxBuffers
,
forceBufferCounter
[
i
]);
}
}
data
.
context
->
addForce
(
new
OpenCLBondForceInfo
(
maxBuffers
,
force
));
cl
.
addForce
(
new
OpenCLBondForceInfo
(
maxBuffers
,
force
));
cl
::
Program
program
=
data
.
context
->
createProgram
(
data
.
context
->
loadSourceFromFile
(
"harmonicBondForce.cl"
));
cl
::
Program
program
=
cl
.
createProgram
(
cl
.
loadSourceFromFile
(
"harmonicBondForce.cl"
));
kernel
=
cl
::
Kernel
(
program
,
"calcHarmonicBondForce"
);
kernel
=
cl
::
Kernel
(
program
,
"calcHarmonicBondForce"
);
}
}
void
OpenCLCalcHarmonicBondForceKernel
::
executeForces
(
ContextImpl
&
context
)
{
void
OpenCLCalcHarmonicBondForceKernel
::
executeForces
(
ContextImpl
&
context
)
{
kernel
.
setArg
<
cl_int
>
(
0
,
data
.
context
->
getPaddedNumAtoms
());
kernel
.
setArg
<
cl_int
>
(
0
,
cl
.
getPaddedNumAtoms
());
kernel
.
setArg
<
cl_int
>
(
1
,
numBonds
);
kernel
.
setArg
<
cl_int
>
(
1
,
numBonds
);
kernel
.
setArg
<
cl
::
Buffer
>
(
2
,
data
.
context
->
getForceBuffers
().
getDeviceBuffer
());
kernel
.
setArg
<
cl
::
Buffer
>
(
2
,
cl
.
getForceBuffers
().
getDeviceBuffer
());
kernel
.
setArg
<
cl
::
Buffer
>
(
3
,
data
.
context
->
getEnergyBuffer
().
getDeviceBuffer
());
kernel
.
setArg
<
cl
::
Buffer
>
(
3
,
cl
.
getEnergyBuffer
().
getDeviceBuffer
());
kernel
.
setArg
<
cl
::
Buffer
>
(
4
,
data
.
context
->
getPosq
().
getDeviceBuffer
());
kernel
.
setArg
<
cl
::
Buffer
>
(
4
,
cl
.
getPosq
().
getDeviceBuffer
());
kernel
.
setArg
<
cl
::
Buffer
>
(
5
,
params
->
getDeviceBuffer
());
kernel
.
setArg
<
cl
::
Buffer
>
(
5
,
params
->
getDeviceBuffer
());
kernel
.
setArg
<
cl
::
Buffer
>
(
6
,
indices
->
getDeviceBuffer
());
kernel
.
setArg
<
cl
::
Buffer
>
(
6
,
indices
->
getDeviceBuffer
());
data
.
context
->
executeKernel
(
kernel
,
numBonds
);
cl
.
executeKernel
(
kernel
,
numBonds
);
}
}
double
OpenCLCalcHarmonicBondForceKernel
::
executeEnergy
(
ContextImpl
&
context
)
{
double
OpenCLCalcHarmonicBondForceKernel
::
executeEnergy
(
ContextImpl
&
context
)
{
...
@@ -248,8 +249,8 @@ OpenCLCalcHarmonicAngleForceKernel::~OpenCLCalcHarmonicAngleForceKernel() {
...
@@ -248,8 +249,8 @@ OpenCLCalcHarmonicAngleForceKernel::~OpenCLCalcHarmonicAngleForceKernel() {
void
OpenCLCalcHarmonicAngleForceKernel
::
initialize
(
const
System
&
system
,
const
HarmonicAngleForce
&
force
)
{
void
OpenCLCalcHarmonicAngleForceKernel
::
initialize
(
const
System
&
system
,
const
HarmonicAngleForce
&
force
)
{
numAngles
=
force
.
getNumAngles
();
numAngles
=
force
.
getNumAngles
();
params
=
new
OpenCLArray
<
mm_float2
>
(
*
data
.
context
,
numAngles
,
"angleParams"
);
params
=
new
OpenCLArray
<
mm_float2
>
(
cl
,
numAngles
,
"angleParams"
);
indices
=
new
OpenCLArray
<
mm_int8
>
(
*
data
.
context
,
numAngles
,
"angleIndices"
);
indices
=
new
OpenCLArray
<
mm_int8
>
(
cl
,
numAngles
,
"angleIndices"
);
vector
<
int
>
forceBufferCounter
(
system
.
getNumParticles
(),
0
);
vector
<
int
>
forceBufferCounter
(
system
.
getNumParticles
(),
0
);
vector
<
mm_float2
>
paramVector
(
numAngles
);
vector
<
mm_float2
>
paramVector
(
numAngles
);
vector
<
mm_int8
>
indicesVector
(
numAngles
);
vector
<
mm_int8
>
indicesVector
(
numAngles
);
...
@@ -268,20 +269,20 @@ void OpenCLCalcHarmonicAngleForceKernel::initialize(const System& system, const
...
@@ -268,20 +269,20 @@ void OpenCLCalcHarmonicAngleForceKernel::initialize(const System& system, const
for
(
int
i
=
0
;
i
<
forceBufferCounter
.
size
();
i
++
)
{
for
(
int
i
=
0
;
i
<
forceBufferCounter
.
size
();
i
++
)
{
maxBuffers
=
max
(
maxBuffers
,
forceBufferCounter
[
i
]);
maxBuffers
=
max
(
maxBuffers
,
forceBufferCounter
[
i
]);
}
}
data
.
context
->
addForce
(
new
OpenCLAngleForceInfo
(
maxBuffers
,
force
));
cl
.
addForce
(
new
OpenCLAngleForceInfo
(
maxBuffers
,
force
));
cl
::
Program
program
=
data
.
context
->
createProgram
(
data
.
context
->
loadSourceFromFile
(
"harmonicAngleForce.cl"
));
cl
::
Program
program
=
cl
.
createProgram
(
cl
.
loadSourceFromFile
(
"harmonicAngleForce.cl"
));
kernel
=
cl
::
Kernel
(
program
,
"calcHarmonicAngleForce"
);
kernel
=
cl
::
Kernel
(
program
,
"calcHarmonicAngleForce"
);
}
}
void
OpenCLCalcHarmonicAngleForceKernel
::
executeForces
(
ContextImpl
&
context
)
{
void
OpenCLCalcHarmonicAngleForceKernel
::
executeForces
(
ContextImpl
&
context
)
{
kernel
.
setArg
<
cl_int
>
(
0
,
data
.
context
->
getPaddedNumAtoms
());
kernel
.
setArg
<
cl_int
>
(
0
,
cl
.
getPaddedNumAtoms
());
kernel
.
setArg
<
cl_int
>
(
1
,
numAngles
);
kernel
.
setArg
<
cl_int
>
(
1
,
numAngles
);
kernel
.
setArg
<
cl
::
Buffer
>
(
2
,
data
.
context
->
getForceBuffers
().
getDeviceBuffer
());
kernel
.
setArg
<
cl
::
Buffer
>
(
2
,
cl
.
getForceBuffers
().
getDeviceBuffer
());
kernel
.
setArg
<
cl
::
Buffer
>
(
3
,
data
.
context
->
getEnergyBuffer
().
getDeviceBuffer
());
kernel
.
setArg
<
cl
::
Buffer
>
(
3
,
cl
.
getEnergyBuffer
().
getDeviceBuffer
());
kernel
.
setArg
<
cl
::
Buffer
>
(
4
,
data
.
context
->
getPosq
().
getDeviceBuffer
());
kernel
.
setArg
<
cl
::
Buffer
>
(
4
,
cl
.
getPosq
().
getDeviceBuffer
());
kernel
.
setArg
<
cl
::
Buffer
>
(
5
,
params
->
getDeviceBuffer
());
kernel
.
setArg
<
cl
::
Buffer
>
(
5
,
params
->
getDeviceBuffer
());
kernel
.
setArg
<
cl
::
Buffer
>
(
6
,
indices
->
getDeviceBuffer
());
kernel
.
setArg
<
cl
::
Buffer
>
(
6
,
indices
->
getDeviceBuffer
());
data
.
context
->
executeKernel
(
kernel
,
numAngles
);
cl
.
executeKernel
(
kernel
,
numAngles
);
}
}
double
OpenCLCalcHarmonicAngleForceKernel
::
executeEnergy
(
ContextImpl
&
context
)
{
double
OpenCLCalcHarmonicAngleForceKernel
::
executeEnergy
(
ContextImpl
&
context
)
{
...
@@ -326,8 +327,8 @@ OpenCLCalcPeriodicTorsionForceKernel::~OpenCLCalcPeriodicTorsionForceKernel() {
...
@@ -326,8 +327,8 @@ OpenCLCalcPeriodicTorsionForceKernel::~OpenCLCalcPeriodicTorsionForceKernel() {
void
OpenCLCalcPeriodicTorsionForceKernel
::
initialize
(
const
System
&
system
,
const
PeriodicTorsionForce
&
force
)
{
void
OpenCLCalcPeriodicTorsionForceKernel
::
initialize
(
const
System
&
system
,
const
PeriodicTorsionForce
&
force
)
{
numTorsions
=
force
.
getNumTorsions
();
numTorsions
=
force
.
getNumTorsions
();
params
=
new
OpenCLArray
<
mm_float4
>
(
*
data
.
context
,
numTorsions
,
"periodicTorsionParams"
);
params
=
new
OpenCLArray
<
mm_float4
>
(
cl
,
numTorsions
,
"periodicTorsionParams"
);
indices
=
new
OpenCLArray
<
mm_int8
>
(
*
data
.
context
,
numTorsions
,
"periodicTorsionIndices"
);
indices
=
new
OpenCLArray
<
mm_int8
>
(
cl
,
numTorsions
,
"periodicTorsionIndices"
);
vector
<
int
>
forceBufferCounter
(
system
.
getNumParticles
(),
0
);
vector
<
int
>
forceBufferCounter
(
system
.
getNumParticles
(),
0
);
vector
<
mm_float4
>
paramVector
(
numTorsions
);
vector
<
mm_float4
>
paramVector
(
numTorsions
);
vector
<
mm_int8
>
indicesVector
(
numTorsions
);
vector
<
mm_int8
>
indicesVector
(
numTorsions
);
...
@@ -346,20 +347,20 @@ void OpenCLCalcPeriodicTorsionForceKernel::initialize(const System& system, cons
...
@@ -346,20 +347,20 @@ void OpenCLCalcPeriodicTorsionForceKernel::initialize(const System& system, cons
for
(
int
i
=
0
;
i
<
forceBufferCounter
.
size
();
i
++
)
{
for
(
int
i
=
0
;
i
<
forceBufferCounter
.
size
();
i
++
)
{
maxBuffers
=
max
(
maxBuffers
,
forceBufferCounter
[
i
]);
maxBuffers
=
max
(
maxBuffers
,
forceBufferCounter
[
i
]);
}
}
data
.
context
->
addForce
(
new
OpenCLPeriodicTorsionForceInfo
(
maxBuffers
,
force
));
cl
.
addForce
(
new
OpenCLPeriodicTorsionForceInfo
(
maxBuffers
,
force
));
cl
::
Program
program
=
data
.
context
->
createProgram
(
data
.
context
->
loadSourceFromFile
(
"periodicTorsionForce.cl"
));
cl
::
Program
program
=
cl
.
createProgram
(
cl
.
loadSourceFromFile
(
"periodicTorsionForce.cl"
));
kernel
=
cl
::
Kernel
(
program
,
"calcPeriodicTorsionForce"
);
kernel
=
cl
::
Kernel
(
program
,
"calcPeriodicTorsionForce"
);
}
}
void
OpenCLCalcPeriodicTorsionForceKernel
::
executeForces
(
ContextImpl
&
context
)
{
void
OpenCLCalcPeriodicTorsionForceKernel
::
executeForces
(
ContextImpl
&
context
)
{
kernel
.
setArg
<
cl_int
>
(
0
,
data
.
context
->
getPaddedNumAtoms
());
kernel
.
setArg
<
cl_int
>
(
0
,
cl
.
getPaddedNumAtoms
());
kernel
.
setArg
<
cl_int
>
(
1
,
numTorsions
);
kernel
.
setArg
<
cl_int
>
(
1
,
numTorsions
);
kernel
.
setArg
<
cl
::
Buffer
>
(
2
,
data
.
context
->
getForceBuffers
().
getDeviceBuffer
());
kernel
.
setArg
<
cl
::
Buffer
>
(
2
,
cl
.
getForceBuffers
().
getDeviceBuffer
());
kernel
.
setArg
<
cl
::
Buffer
>
(
3
,
data
.
context
->
getEnergyBuffer
().
getDeviceBuffer
());
kernel
.
setArg
<
cl
::
Buffer
>
(
3
,
cl
.
getEnergyBuffer
().
getDeviceBuffer
());
kernel
.
setArg
<
cl
::
Buffer
>
(
4
,
data
.
context
->
getPosq
().
getDeviceBuffer
());
kernel
.
setArg
<
cl
::
Buffer
>
(
4
,
cl
.
getPosq
().
getDeviceBuffer
());
kernel
.
setArg
<
cl
::
Buffer
>
(
5
,
params
->
getDeviceBuffer
());
kernel
.
setArg
<
cl
::
Buffer
>
(
5
,
params
->
getDeviceBuffer
());
kernel
.
setArg
<
cl
::
Buffer
>
(
6
,
indices
->
getDeviceBuffer
());
kernel
.
setArg
<
cl
::
Buffer
>
(
6
,
indices
->
getDeviceBuffer
());
data
.
context
->
executeKernel
(
kernel
,
numTorsions
);
cl
.
executeKernel
(
kernel
,
numTorsions
);
}
}
double
OpenCLCalcPeriodicTorsionForceKernel
::
executeEnergy
(
ContextImpl
&
context
)
{
double
OpenCLCalcPeriodicTorsionForceKernel
::
executeEnergy
(
ContextImpl
&
context
)
{
...
@@ -404,8 +405,8 @@ OpenCLCalcRBTorsionForceKernel::~OpenCLCalcRBTorsionForceKernel() {
...
@@ -404,8 +405,8 @@ OpenCLCalcRBTorsionForceKernel::~OpenCLCalcRBTorsionForceKernel() {
void
OpenCLCalcRBTorsionForceKernel
::
initialize
(
const
System
&
system
,
const
RBTorsionForce
&
force
)
{
void
OpenCLCalcRBTorsionForceKernel
::
initialize
(
const
System
&
system
,
const
RBTorsionForce
&
force
)
{
numTorsions
=
force
.
getNumTorsions
();
numTorsions
=
force
.
getNumTorsions
();
params
=
new
OpenCLArray
<
mm_float8
>
(
*
data
.
context
,
numTorsions
,
"rbTorsionParams"
);
params
=
new
OpenCLArray
<
mm_float8
>
(
cl
,
numTorsions
,
"rbTorsionParams"
);
indices
=
new
OpenCLArray
<
mm_int8
>
(
*
data
.
context
,
numTorsions
,
"rbTorsionIndices"
);
indices
=
new
OpenCLArray
<
mm_int8
>
(
cl
,
numTorsions
,
"rbTorsionIndices"
);
vector
<
int
>
forceBufferCounter
(
system
.
getNumParticles
(),
0
);
vector
<
int
>
forceBufferCounter
(
system
.
getNumParticles
(),
0
);
vector
<
mm_float8
>
paramVector
(
numTorsions
);
vector
<
mm_float8
>
paramVector
(
numTorsions
);
vector
<
mm_int8
>
indicesVector
(
numTorsions
);
vector
<
mm_int8
>
indicesVector
(
numTorsions
);
...
@@ -424,20 +425,20 @@ void OpenCLCalcRBTorsionForceKernel::initialize(const System& system, const RBTo
...
@@ -424,20 +425,20 @@ void OpenCLCalcRBTorsionForceKernel::initialize(const System& system, const RBTo
for
(
int
i
=
0
;
i
<
forceBufferCounter
.
size
();
i
++
)
{
for
(
int
i
=
0
;
i
<
forceBufferCounter
.
size
();
i
++
)
{
maxBuffers
=
max
(
maxBuffers
,
forceBufferCounter
[
i
]);
maxBuffers
=
max
(
maxBuffers
,
forceBufferCounter
[
i
]);
}
}
data
.
context
->
addForce
(
new
OpenCLRBTorsionForceInfo
(
maxBuffers
,
force
));
cl
.
addForce
(
new
OpenCLRBTorsionForceInfo
(
maxBuffers
,
force
));
cl
::
Program
program
=
data
.
context
->
createProgram
(
data
.
context
->
loadSourceFromFile
(
"rbTorsionForce.cl"
));
cl
::
Program
program
=
cl
.
createProgram
(
cl
.
loadSourceFromFile
(
"rbTorsionForce.cl"
));
kernel
=
cl
::
Kernel
(
program
,
"calcRBTorsionForce"
);
kernel
=
cl
::
Kernel
(
program
,
"calcRBTorsionForce"
);
}
}
void
OpenCLCalcRBTorsionForceKernel
::
executeForces
(
ContextImpl
&
context
)
{
void
OpenCLCalcRBTorsionForceKernel
::
executeForces
(
ContextImpl
&
context
)
{
kernel
.
setArg
<
cl_int
>
(
0
,
data
.
context
->
getPaddedNumAtoms
());
kernel
.
setArg
<
cl_int
>
(
0
,
cl
.
getPaddedNumAtoms
());
kernel
.
setArg
<
cl_int
>
(
1
,
numTorsions
);
kernel
.
setArg
<
cl_int
>
(
1
,
numTorsions
);
kernel
.
setArg
<
cl
::
Buffer
>
(
2
,
data
.
context
->
getForceBuffers
().
getDeviceBuffer
());
kernel
.
setArg
<
cl
::
Buffer
>
(
2
,
cl
.
getForceBuffers
().
getDeviceBuffer
());
kernel
.
setArg
<
cl
::
Buffer
>
(
3
,
data
.
context
->
getEnergyBuffer
().
getDeviceBuffer
());
kernel
.
setArg
<
cl
::
Buffer
>
(
3
,
cl
.
getEnergyBuffer
().
getDeviceBuffer
());
kernel
.
setArg
<
cl
::
Buffer
>
(
4
,
data
.
context
->
getPosq
().
getDeviceBuffer
());
kernel
.
setArg
<
cl
::
Buffer
>
(
4
,
cl
.
getPosq
().
getDeviceBuffer
());
kernel
.
setArg
<
cl
::
Buffer
>
(
5
,
params
->
getDeviceBuffer
());
kernel
.
setArg
<
cl
::
Buffer
>
(
5
,
params
->
getDeviceBuffer
());
kernel
.
setArg
<
cl
::
Buffer
>
(
6
,
indices
->
getDeviceBuffer
());
kernel
.
setArg
<
cl
::
Buffer
>
(
6
,
indices
->
getDeviceBuffer
());
data
.
context
->
executeKernel
(
kernel
,
numTorsions
);
cl
.
executeKernel
(
kernel
,
numTorsions
);
}
}
double
OpenCLCalcRBTorsionForceKernel
::
executeEnergy
(
ContextImpl
&
context
)
{
double
OpenCLCalcRBTorsionForceKernel
::
executeEnergy
(
ContextImpl
&
context
)
{
...
@@ -794,31 +795,45 @@ OpenCLIntegrateVerletStepKernel::~OpenCLIntegrateVerletStepKernel() {
...
@@ -794,31 +795,45 @@ OpenCLIntegrateVerletStepKernel::~OpenCLIntegrateVerletStepKernel() {
}
}
void
OpenCLIntegrateVerletStepKernel
::
initialize
(
const
System
&
system
,
const
VerletIntegrator
&
integrator
)
{
void
OpenCLIntegrateVerletStepKernel
::
initialize
(
const
System
&
system
,
const
VerletIntegrator
&
integrator
)
{
// initializeIntegration(system, data, integrator);
cl
.
initialize
(
system
);
data
.
context
->
initialize
(
system
);
cl
::
Program
program
=
cl
.
createProgram
(
cl
.
loadSourceFromFile
(
"verlet.cl"
));
prevStepSize
=
-
1.0
;
kernel1
=
cl
::
Kernel
(
program
,
"integrateVerletPart1"
);
kernel2
=
cl
::
Kernel
(
program
,
"integrateVerletPart2"
);
}
}
void
OpenCLIntegrateVerletStepKernel
::
execute
(
ContextImpl
&
context
,
const
VerletIntegrator
&
integrator
)
{
void
OpenCLIntegrateVerletStepKernel
::
execute
(
ContextImpl
&
context
,
const
VerletIntegrator
&
integrator
)
{
// _gpuContext* gpu = data.gpu;
OpenCLIntegrationUtilities
&
integration
=
cl
.
getIntegrationUtilties
();
// double stepSize = integrator.getStepSize();
int
numAtoms
=
cl
.
getNumAtoms
();
// if (stepSize != prevStepSize) {
double
dt
=
integrator
.
getStepSize
();
// // Initialize the GPU parameters.
//
// Call the first integration kernel.
// gpuSetVerletIntegrationParameters(gpu, (float) stepSize, 0.0f);
// gpuSetConstants(gpu);
kernel1
.
setArg
<
cl_int
>
(
0
,
numAtoms
);
// prevStepSize = stepSize;
kernel1
.
setArg
<
cl_float
>
(
1
,
dt
);
// }
kernel1
.
setArg
<
cl
::
Buffer
>
(
2
,
cl
.
getPosq
().
getDeviceBuffer
());
// kVerletUpdatePart1(gpu);
kernel1
.
setArg
<
cl
::
Buffer
>
(
3
,
cl
.
getVelm
().
getDeviceBuffer
());
// kApplyFirstShake(gpu);
kernel1
.
setArg
<
cl
::
Buffer
>
(
4
,
cl
.
getForce
().
getDeviceBuffer
());
// kApplyFirstSettle(gpu);
kernel1
.
setArg
<
cl
::
Buffer
>
(
5
,
integration
.
getPosDelta
().
getDeviceBuffer
());
// kApplyFirstCCMA(gpu);
kernel1
.
setArg
<
cl
::
Buffer
>
(
6
,
integration
.
getOldPos
().
getDeviceBuffer
());
// if (data.removeCM)
cl
.
executeKernel
(
kernel1
,
numAtoms
);
// if (data.stepCount%data.cmMotionFrequency == 0)
// gpu->bCalculateCM = true;
// Apply constraints.
// kVerletUpdatePart2(gpu);
// data.time += stepSize;
integration
.
applyConstraints
(
integrator
.
getConstraintTolerance
(),
integration
.
getOldPos
(),
integration
.
getPosDelta
(),
integration
.
getPosDelta
());
// data.stepCount++;
// Call the second integration kernel.
kernel2
.
setArg
<
cl_int
>
(
0
,
numAtoms
);
kernel2
.
setArg
<
cl_float
>
(
1
,
dt
);
kernel2
.
setArg
<
cl
::
Buffer
>
(
2
,
cl
.
getPosq
().
getDeviceBuffer
());
kernel2
.
setArg
<
cl
::
Buffer
>
(
3
,
cl
.
getVelm
().
getDeviceBuffer
());
kernel2
.
setArg
<
cl
::
Buffer
>
(
4
,
integration
.
getPosDelta
().
getDeviceBuffer
());
cl
.
executeKernel
(
kernel2
,
numAtoms
);
// Update the time and step count.
cl
.
setTime
(
cl
.
getTime
()
+
dt
);
cl
.
setStepCount
(
cl
.
getStepCount
()
+
1
);
}
}
//OpenCLIntegrateLangevinStepKernel::~OpenCLIntegrateLangevinStepKernel() {
//OpenCLIntegrateLangevinStepKernel::~OpenCLIntegrateLangevinStepKernel() {
...
@@ -1023,7 +1038,7 @@ double OpenCLCalcKineticEnergyKernel::execute(ContextImpl& context) {
...
@@ -1023,7 +1038,7 @@ double OpenCLCalcKineticEnergyKernel::execute(ContextImpl& context) {
// We don't currently have a GPU kernel to do this, so we retrieve the velocities and calculate the energy
// We don't currently have a GPU kernel to do this, so we retrieve the velocities and calculate the energy
// on the CPU.
// on the CPU.
OpenCLArray
<
mm_float4
>&
velm
=
data
.
context
->
getVelm
();
OpenCLArray
<
mm_float4
>&
velm
=
cl
.
getVelm
();
double
energy
=
0.0
;
double
energy
=
0.0
;
for
(
size_t
i
=
0
;
i
<
masses
.
size
();
++
i
)
{
for
(
size_t
i
=
0
;
i
<
masses
.
size
();
++
i
)
{
mm_float4
v
=
velm
[
i
];
mm_float4
v
=
velm
[
i
];
...
...
platforms/opencl/src/OpenCLKernels.h
View file @
efc1083e
...
@@ -42,7 +42,7 @@ namespace OpenMM {
...
@@ -42,7 +42,7 @@ namespace OpenMM {
*/
*/
class
OpenCLCalcForcesAndEnergyKernel
:
public
CalcForcesAndEnergyKernel
{
class
OpenCLCalcForcesAndEnergyKernel
:
public
CalcForcesAndEnergyKernel
{
public:
public:
OpenCLCalcForcesAndEnergyKernel
(
std
::
string
name
,
const
Platform
&
platform
,
OpenCL
Platform
::
PlatformData
&
data
)
:
CalcForcesAndEnergyKernel
(
name
,
platform
),
data
(
data
)
{
OpenCLCalcForcesAndEnergyKernel
(
std
::
string
name
,
const
Platform
&
platform
,
OpenCL
Context
&
cl
)
:
CalcForcesAndEnergyKernel
(
name
,
platform
),
cl
(
cl
)
{
}
}
/**
/**
* Initialize the kernel.
* Initialize the kernel.
...
@@ -82,7 +82,7 @@ public:
...
@@ -82,7 +82,7 @@ public:
*/
*/
double
finishEnergyComputation
(
ContextImpl
&
context
);
double
finishEnergyComputation
(
ContextImpl
&
context
);
private:
private:
OpenCL
Platform
::
PlatformData
&
data
;
OpenCL
Context
&
cl
;
};
};
/**
/**
...
@@ -91,7 +91,7 @@ private:
...
@@ -91,7 +91,7 @@ private:
*/
*/
class
OpenCLUpdateStateDataKernel
:
public
UpdateStateDataKernel
{
class
OpenCLUpdateStateDataKernel
:
public
UpdateStateDataKernel
{
public:
public:
OpenCLUpdateStateDataKernel
(
std
::
string
name
,
const
Platform
&
platform
,
OpenCL
Platform
::
PlatformData
&
data
)
:
UpdateStateDataKernel
(
name
,
platform
),
data
(
data
)
{
OpenCLUpdateStateDataKernel
(
std
::
string
name
,
const
Platform
&
platform
,
OpenCL
Context
&
cl
)
:
UpdateStateDataKernel
(
name
,
platform
),
cl
(
cl
)
{
}
}
/**
/**
* Initialize the kernel.
* Initialize the kernel.
...
@@ -142,7 +142,7 @@ public:
...
@@ -142,7 +142,7 @@ public:
*/
*/
void
getForces
(
ContextImpl
&
context
,
std
::
vector
<
Vec3
>&
forces
);
void
getForces
(
ContextImpl
&
context
,
std
::
vector
<
Vec3
>&
forces
);
private:
private:
OpenCL
Platform
::
PlatformData
&
data
;
OpenCL
Context
&
cl
;
};
};
/**
/**
...
@@ -150,8 +150,8 @@ private:
...
@@ -150,8 +150,8 @@ private:
*/
*/
class
OpenCLCalcHarmonicBondForceKernel
:
public
CalcHarmonicBondForceKernel
{
class
OpenCLCalcHarmonicBondForceKernel
:
public
CalcHarmonicBondForceKernel
{
public:
public:
OpenCLCalcHarmonicBondForceKernel
(
std
::
string
name
,
const
Platform
&
platform
,
OpenCL
Platform
::
PlatformData
&
data
,
System
&
system
)
:
OpenCLCalcHarmonicBondForceKernel
(
std
::
string
name
,
const
Platform
&
platform
,
OpenCL
Context
&
cl
,
System
&
system
)
:
CalcHarmonicBondForceKernel
(
name
,
platform
),
data
(
data
),
system
(
system
),
params
(
NULL
),
indices
(
NULL
)
{
CalcHarmonicBondForceKernel
(
name
,
platform
),
cl
(
cl
),
system
(
system
),
params
(
NULL
),
indices
(
NULL
)
{
}
}
~
OpenCLCalcHarmonicBondForceKernel
();
~
OpenCLCalcHarmonicBondForceKernel
();
/**
/**
...
@@ -176,7 +176,7 @@ public:
...
@@ -176,7 +176,7 @@ public:
double
executeEnergy
(
ContextImpl
&
context
);
double
executeEnergy
(
ContextImpl
&
context
);
private:
private:
int
numBonds
;
int
numBonds
;
OpenCL
Platform
::
PlatformData
&
data
;
OpenCL
Context
&
cl
;
System
&
system
;
System
&
system
;
OpenCLArray
<
mm_float2
>*
params
;
OpenCLArray
<
mm_float2
>*
params
;
OpenCLArray
<
mm_int4
>*
indices
;
OpenCLArray
<
mm_int4
>*
indices
;
...
@@ -188,7 +188,7 @@ private:
...
@@ -188,7 +188,7 @@ private:
*/
*/
class
OpenCLCalcHarmonicAngleForceKernel
:
public
CalcHarmonicAngleForceKernel
{
class
OpenCLCalcHarmonicAngleForceKernel
:
public
CalcHarmonicAngleForceKernel
{
public:
public:
OpenCLCalcHarmonicAngleForceKernel
(
std
::
string
name
,
const
Platform
&
platform
,
OpenCL
Platform
::
PlatformData
&
data
,
System
&
system
)
:
CalcHarmonicAngleForceKernel
(
name
,
platform
),
data
(
data
),
system
(
system
)
{
OpenCLCalcHarmonicAngleForceKernel
(
std
::
string
name
,
const
Platform
&
platform
,
OpenCL
Context
&
cl
,
System
&
system
)
:
CalcHarmonicAngleForceKernel
(
name
,
platform
),
cl
(
cl
),
system
(
system
)
{
}
}
~
OpenCLCalcHarmonicAngleForceKernel
();
~
OpenCLCalcHarmonicAngleForceKernel
();
/**
/**
...
@@ -213,7 +213,7 @@ public:
...
@@ -213,7 +213,7 @@ public:
double
executeEnergy
(
ContextImpl
&
context
);
double
executeEnergy
(
ContextImpl
&
context
);
private:
private:
int
numAngles
;
int
numAngles
;
OpenCL
Platform
::
PlatformData
&
data
;
OpenCL
Context
&
cl
;
System
&
system
;
System
&
system
;
OpenCLArray
<
mm_float2
>*
params
;
OpenCLArray
<
mm_float2
>*
params
;
OpenCLArray
<
mm_int8
>*
indices
;
OpenCLArray
<
mm_int8
>*
indices
;
...
@@ -225,7 +225,7 @@ private:
...
@@ -225,7 +225,7 @@ private:
*/
*/
class
OpenCLCalcPeriodicTorsionForceKernel
:
public
CalcPeriodicTorsionForceKernel
{
class
OpenCLCalcPeriodicTorsionForceKernel
:
public
CalcPeriodicTorsionForceKernel
{
public:
public:
OpenCLCalcPeriodicTorsionForceKernel
(
std
::
string
name
,
const
Platform
&
platform
,
OpenCL
Platform
::
PlatformData
&
data
,
System
&
system
)
:
CalcPeriodicTorsionForceKernel
(
name
,
platform
),
data
(
data
),
system
(
system
)
{
OpenCLCalcPeriodicTorsionForceKernel
(
std
::
string
name
,
const
Platform
&
platform
,
OpenCL
Context
&
cl
,
System
&
system
)
:
CalcPeriodicTorsionForceKernel
(
name
,
platform
),
cl
(
cl
),
system
(
system
)
{
}
}
~
OpenCLCalcPeriodicTorsionForceKernel
();
~
OpenCLCalcPeriodicTorsionForceKernel
();
/**
/**
...
@@ -250,7 +250,7 @@ public:
...
@@ -250,7 +250,7 @@ public:
double
executeEnergy
(
ContextImpl
&
context
);
double
executeEnergy
(
ContextImpl
&
context
);
private:
private:
int
numTorsions
;
int
numTorsions
;
OpenCL
Platform
::
PlatformData
&
data
;
OpenCL
Context
&
cl
;
System
&
system
;
System
&
system
;
OpenCLArray
<
mm_float4
>*
params
;
OpenCLArray
<
mm_float4
>*
params
;
OpenCLArray
<
mm_int8
>*
indices
;
OpenCLArray
<
mm_int8
>*
indices
;
...
@@ -262,7 +262,7 @@ private:
...
@@ -262,7 +262,7 @@ private:
*/
*/
class
OpenCLCalcRBTorsionForceKernel
:
public
CalcRBTorsionForceKernel
{
class
OpenCLCalcRBTorsionForceKernel
:
public
CalcRBTorsionForceKernel
{
public:
public:
OpenCLCalcRBTorsionForceKernel
(
std
::
string
name
,
const
Platform
&
platform
,
OpenCL
Platform
::
PlatformData
&
data
,
System
&
system
)
:
CalcRBTorsionForceKernel
(
name
,
platform
),
data
(
data
),
system
(
system
)
{
OpenCLCalcRBTorsionForceKernel
(
std
::
string
name
,
const
Platform
&
platform
,
OpenCL
Context
&
cl
,
System
&
system
)
:
CalcRBTorsionForceKernel
(
name
,
platform
),
cl
(
cl
),
system
(
system
)
{
}
}
~
OpenCLCalcRBTorsionForceKernel
();
~
OpenCLCalcRBTorsionForceKernel
();
/**
/**
...
@@ -287,7 +287,7 @@ public:
...
@@ -287,7 +287,7 @@ public:
double
executeEnergy
(
ContextImpl
&
context
);
double
executeEnergy
(
ContextImpl
&
context
);
private:
private:
int
numTorsions
;
int
numTorsions
;
OpenCL
Platform
::
PlatformData
&
data
;
OpenCL
Context
&
cl
;
System
&
system
;
System
&
system
;
OpenCLArray
<
mm_float8
>*
params
;
OpenCLArray
<
mm_float8
>*
params
;
OpenCLArray
<
mm_int8
>*
indices
;
OpenCLArray
<
mm_int8
>*
indices
;
...
@@ -299,7 +299,7 @@ private:
...
@@ -299,7 +299,7 @@ private:
// */
// */
//class OpenCLCalcNonbondedForceKernel : public CalcNonbondedForceKernel {
//class OpenCLCalcNonbondedForceKernel : public CalcNonbondedForceKernel {
//public:
//public:
// OpenCLCalcNonbondedForceKernel(std::string name, const Platform& platform, OpenCL
Platform::PlatformData& data
, System& system) : CalcNonbondedForceKernel(name, platform),
data(data
), system(system) {
// OpenCLCalcNonbondedForceKernel(std::string name, const Platform& platform, OpenCL
Context& cl
, System& system) : CalcNonbondedForceKernel(name, platform),
cl(cl
), system(system) {
// }
// }
// ~OpenCLCalcNonbondedForceKernel();
// ~OpenCLCalcNonbondedForceKernel();
// /**
// /**
...
@@ -323,7 +323,7 @@ private:
...
@@ -323,7 +323,7 @@ private:
// */
// */
// double executeEnergy(ContextImpl& context);
// double executeEnergy(ContextImpl& context);
//private:
//private:
// OpenCL
Platform::PlatformData& data
;
// OpenCL
Context& cl
;
// int numParticles;
// int numParticles;
// System& system;
// System& system;
//};
//};
...
@@ -333,7 +333,7 @@ private:
...
@@ -333,7 +333,7 @@ private:
// */
// */
//class OpenCLCalcCustomNonbondedForceKernel : public CalcCustomNonbondedForceKernel {
//class OpenCLCalcCustomNonbondedForceKernel : public CalcCustomNonbondedForceKernel {
//public:
//public:
// OpenCLCalcCustomNonbondedForceKernel(std::string name, const Platform& platform, OpenCL
Platform::PlatformData& data
, System& system) : CalcCustomNonbondedForceKernel(name, platform),
data(data
), system(system) {
// OpenCLCalcCustomNonbondedForceKernel(std::string name, const Platform& platform, OpenCL
Context& cl
, System& system) : CalcCustomNonbondedForceKernel(name, platform),
cl(cl
), system(system) {
// }
// }
// ~OpenCLCalcCustomNonbondedForceKernel();
// ~OpenCLCalcCustomNonbondedForceKernel();
// /**
// /**
...
@@ -358,7 +358,7 @@ private:
...
@@ -358,7 +358,7 @@ private:
// double executeEnergy(ContextImpl& context);
// double executeEnergy(ContextImpl& context);
//private:
//private:
// void updateGlobalParams(ContextImpl& context);
// void updateGlobalParams(ContextImpl& context);
// OpenCL
Platform::PlatformData& data
;
// OpenCL
Context& cl
;
// int numParticles;
// int numParticles;
// std::vector<std::string> globalParamNames;
// std::vector<std::string> globalParamNames;
// std::vector<float> globalParamValues;
// std::vector<float> globalParamValues;
...
@@ -370,7 +370,7 @@ private:
...
@@ -370,7 +370,7 @@ private:
// */
// */
//class OpenCLCalcGBSAOBCForceKernel : public CalcGBSAOBCForceKernel {
//class OpenCLCalcGBSAOBCForceKernel : public CalcGBSAOBCForceKernel {
//public:
//public:
// OpenCLCalcGBSAOBCForceKernel(std::string name, const Platform& platform, OpenCL
Platform::PlatformData& data
) : CalcGBSAOBCForceKernel(name, platform),
data(data
) {
// OpenCLCalcGBSAOBCForceKernel(std::string name, const Platform& platform, OpenCL
Context& cl
) : CalcGBSAOBCForceKernel(name, platform),
cl(cl
) {
// }
// }
// ~OpenCLCalcGBSAOBCForceKernel();
// ~OpenCLCalcGBSAOBCForceKernel();
// /**
// /**
...
@@ -394,7 +394,7 @@ private:
...
@@ -394,7 +394,7 @@ private:
// */
// */
// double executeEnergy(ContextImpl& context);
// double executeEnergy(ContextImpl& context);
//private:
//private:
// OpenCL
Platform::PlatformData& data
;
// OpenCL
Context& cl
;
//};
//};
/**
/**
...
@@ -402,7 +402,7 @@ private:
...
@@ -402,7 +402,7 @@ private:
*/
*/
class
OpenCLIntegrateVerletStepKernel
:
public
IntegrateVerletStepKernel
{
class
OpenCLIntegrateVerletStepKernel
:
public
IntegrateVerletStepKernel
{
public:
public:
OpenCLIntegrateVerletStepKernel
(
std
::
string
name
,
const
Platform
&
platform
,
OpenCL
Platform
::
PlatformData
&
data
)
:
IntegrateVerletStepKernel
(
name
,
platform
),
data
(
data
)
{
OpenCLIntegrateVerletStepKernel
(
std
::
string
name
,
const
Platform
&
platform
,
OpenCL
Context
&
cl
)
:
IntegrateVerletStepKernel
(
name
,
platform
),
cl
(
cl
)
{
}
}
~
OpenCLIntegrateVerletStepKernel
();
~
OpenCLIntegrateVerletStepKernel
();
/**
/**
...
@@ -420,8 +420,9 @@ public:
...
@@ -420,8 +420,9 @@ public:
*/
*/
void
execute
(
ContextImpl
&
context
,
const
VerletIntegrator
&
integrator
);
void
execute
(
ContextImpl
&
context
,
const
VerletIntegrator
&
integrator
);
private:
private:
OpenCLPlatform
::
PlatformData
&
data
;
OpenCLContext
&
cl
;
double
prevStepSize
;
cl
::
Kernel
kernel1
;
cl
::
Kernel
kernel2
;
};
};
///**
///**
...
@@ -429,7 +430,7 @@ private:
...
@@ -429,7 +430,7 @@ private:
// */
// */
//class OpenCLIntegrateLangevinStepKernel : public IntegrateLangevinStepKernel {
//class OpenCLIntegrateLangevinStepKernel : public IntegrateLangevinStepKernel {
//public:
//public:
// OpenCLIntegrateLangevinStepKernel(std::string name, const Platform& platform, OpenCL
Platform::PlatformData& data
) : IntegrateLangevinStepKernel(name, platform),
data(data
) {
// OpenCLIntegrateLangevinStepKernel(std::string name, const Platform& platform, OpenCL
Context& cl
) : IntegrateLangevinStepKernel(name, platform),
cl(cl
) {
// }
// }
// ~OpenCLIntegrateLangevinStepKernel();
// ~OpenCLIntegrateLangevinStepKernel();
// /**
// /**
...
@@ -447,7 +448,7 @@ private:
...
@@ -447,7 +448,7 @@ private:
// */
// */
// void execute(ContextImpl& context, const LangevinIntegrator& integrator);
// void execute(ContextImpl& context, const LangevinIntegrator& integrator);
//private:
//private:
// OpenCL
Platform::PlatformData& data
;
// OpenCL
Context& cl
;
// double prevTemp, prevFriction, prevStepSize;
// double prevTemp, prevFriction, prevStepSize;
//};
//};
//
//
...
@@ -456,7 +457,7 @@ private:
...
@@ -456,7 +457,7 @@ private:
// */
// */
//class OpenCLIntegrateBrownianStepKernel : public IntegrateBrownianStepKernel {
//class OpenCLIntegrateBrownianStepKernel : public IntegrateBrownianStepKernel {
//public:
//public:
// OpenCLIntegrateBrownianStepKernel(std::string name, const Platform& platform, OpenCL
Platform::PlatformData& data
) : IntegrateBrownianStepKernel(name, platform),
data(data
) {
// OpenCLIntegrateBrownianStepKernel(std::string name, const Platform& platform, OpenCL
Context& cl
) : IntegrateBrownianStepKernel(name, platform),
cl(cl
) {
// }
// }
// ~OpenCLIntegrateBrownianStepKernel();
// ~OpenCLIntegrateBrownianStepKernel();
// /**
// /**
...
@@ -474,7 +475,7 @@ private:
...
@@ -474,7 +475,7 @@ private:
// */
// */
// void execute(ContextImpl& context, const BrownianIntegrator& integrator);
// void execute(ContextImpl& context, const BrownianIntegrator& integrator);
//private:
//private:
// OpenCL
Platform::PlatformData& data
;
// OpenCL
Context& cl
;
// double prevTemp, prevFriction, prevStepSize;
// double prevTemp, prevFriction, prevStepSize;
//};
//};
//
//
...
@@ -483,7 +484,7 @@ private:
...
@@ -483,7 +484,7 @@ private:
// */
// */
//class OpenCLIntegrateVariableVerletStepKernel : public IntegrateVariableVerletStepKernel {
//class OpenCLIntegrateVariableVerletStepKernel : public IntegrateVariableVerletStepKernel {
//public:
//public:
// OpenCLIntegrateVariableVerletStepKernel(std::string name, const Platform& platform, OpenCL
Platform::PlatformData& data
) : IntegrateVariableVerletStepKernel(name, platform),
data(data
) {
// OpenCLIntegrateVariableVerletStepKernel(std::string name, const Platform& platform, OpenCL
Context& cl
) : IntegrateVariableVerletStepKernel(name, platform),
cl(cl
) {
// }
// }
// ~OpenCLIntegrateVariableVerletStepKernel();
// ~OpenCLIntegrateVariableVerletStepKernel();
// /**
// /**
...
@@ -502,7 +503,7 @@ private:
...
@@ -502,7 +503,7 @@ private:
// */
// */
// void execute(ContextImpl& context, const VariableVerletIntegrator& integrator, double maxTime);
// void execute(ContextImpl& context, const VariableVerletIntegrator& integrator, double maxTime);
//private:
//private:
// OpenCL
Platform::PlatformData& data
;
// OpenCL
Context& cl
;
// double prevErrorTol;
// double prevErrorTol;
//};
//};
//
//
...
@@ -511,7 +512,7 @@ private:
...
@@ -511,7 +512,7 @@ private:
// */
// */
//class OpenCLIntegrateVariableLangevinStepKernel : public IntegrateVariableLangevinStepKernel {
//class OpenCLIntegrateVariableLangevinStepKernel : public IntegrateVariableLangevinStepKernel {
//public:
//public:
// OpenCLIntegrateVariableLangevinStepKernel(std::string name, const Platform& platform, OpenCL
Platform::PlatformData& data
) : IntegrateVariableLangevinStepKernel(name, platform),
data(data
) {
// OpenCLIntegrateVariableLangevinStepKernel(std::string name, const Platform& platform, OpenCL
Context& cl
) : IntegrateVariableLangevinStepKernel(name, platform),
cl(cl
) {
// }
// }
// ~OpenCLIntegrateVariableLangevinStepKernel();
// ~OpenCLIntegrateVariableLangevinStepKernel();
// /**
// /**
...
@@ -530,7 +531,7 @@ private:
...
@@ -530,7 +531,7 @@ private:
// */
// */
// void execute(ContextImpl& context, const VariableLangevinIntegrator& integrator, double maxTime);
// void execute(ContextImpl& context, const VariableLangevinIntegrator& integrator, double maxTime);
//private:
//private:
// OpenCL
Platform::PlatformData& data
;
// OpenCL
Context& cl
;
// double prevTemp, prevFriction, prevErrorTol;
// double prevTemp, prevFriction, prevErrorTol;
//};
//};
//
//
...
@@ -539,7 +540,7 @@ private:
...
@@ -539,7 +540,7 @@ private:
// */
// */
//class OpenCLApplyAndersenThermostatKernel : public ApplyAndersenThermostatKernel {
//class OpenCLApplyAndersenThermostatKernel : public ApplyAndersenThermostatKernel {
//public:
//public:
// OpenCLApplyAndersenThermostatKernel(std::string name, const Platform& platform, OpenCL
Platform::PlatformData& data
) : ApplyAndersenThermostatKernel(name, platform),
data(data
) {
// OpenCLApplyAndersenThermostatKernel(std::string name, const Platform& platform, OpenCL
Context& cl
) : ApplyAndersenThermostatKernel(name, platform),
cl(cl
) {
// }
// }
// ~OpenCLApplyAndersenThermostatKernel();
// ~OpenCLApplyAndersenThermostatKernel();
// /**
// /**
...
@@ -556,7 +557,7 @@ private:
...
@@ -556,7 +557,7 @@ private:
// */
// */
// void execute(ContextImpl& context);
// void execute(ContextImpl& context);
//private:
//private:
// OpenCL
Platform::PlatformData& data
;
// OpenCL
Context& cl
;
// double prevTemp, prevFrequency, prevStepSize;
// double prevTemp, prevFrequency, prevStepSize;
//};
//};
...
@@ -565,7 +566,7 @@ private:
...
@@ -565,7 +566,7 @@ private:
*/
*/
class
OpenCLCalcKineticEnergyKernel
:
public
CalcKineticEnergyKernel
{
class
OpenCLCalcKineticEnergyKernel
:
public
CalcKineticEnergyKernel
{
public:
public:
OpenCLCalcKineticEnergyKernel
(
std
::
string
name
,
const
Platform
&
platform
,
OpenCL
Platform
::
PlatformData
&
data
)
:
CalcKineticEnergyKernel
(
name
,
platform
),
data
(
data
)
{
OpenCLCalcKineticEnergyKernel
(
std
::
string
name
,
const
Platform
&
platform
,
OpenCL
Context
&
cl
)
:
CalcKineticEnergyKernel
(
name
,
platform
),
cl
(
cl
)
{
}
}
/**
/**
* Initialize the kernel.
* Initialize the kernel.
...
@@ -580,7 +581,7 @@ public:
...
@@ -580,7 +581,7 @@ public:
*/
*/
double
execute
(
ContextImpl
&
context
);
double
execute
(
ContextImpl
&
context
);
private:
private:
OpenCL
Platform
::
PlatformData
&
data
;
OpenCL
Context
&
cl
;
std
::
vector
<
double
>
masses
;
std
::
vector
<
double
>
masses
;
};
};
...
@@ -589,7 +590,7 @@ private:
...
@@ -589,7 +590,7 @@ private:
// */
// */
//class OpenCLRemoveCMMotionKernel : public RemoveCMMotionKernel {
//class OpenCLRemoveCMMotionKernel : public RemoveCMMotionKernel {
//public:
//public:
// OpenCLRemoveCMMotionKernel(std::string name, const Platform& platform, OpenCL
Platform::PlatformData& data
) : RemoveCMMotionKernel(name, platform),
data(data
) {
// OpenCLRemoveCMMotionKernel(std::string name, const Platform& platform, OpenCL
Context& cl
) : RemoveCMMotionKernel(name, platform),
cl(cl
) {
// }
// }
// /**
// /**
// * Initialize the kernel, setting up the particle masses.
// * Initialize the kernel, setting up the particle masses.
...
@@ -605,7 +606,7 @@ private:
...
@@ -605,7 +606,7 @@ private:
// */
// */
// void execute(ContextImpl& context);
// void execute(ContextImpl& context);
//private:
//private:
// OpenCL
Platform::PlatformData& data
;
// OpenCL
Context& cl
;
//};
//};
}
// namespace OpenMM
}
// namespace OpenMM
...
...
platforms/opencl/src/kernels/shakeHydrogens.cl
0 → 100644
View file @
efc1083e
/**
*
Enforce
constraints
on
SHAKE
clusters
*/
__kernel
void
applyShakeToHydrogens
(
int
numClusters,
float
tol,
__global
float4*
oldPos,
__global
float4*
posDelta,
__global
float4*
newDelta,
__global
int4*
clusterAtoms,
__global
float4*
clusterParams
)
{
int
index
=
get_global_id
(
0
)
;
while
(
index
<
numClusters
)
{
//
Load
the
data
for
this
cluster.
int4
atoms
=
clusterAtoms[index]
;
float4
params
=
clusterParams[index]
;
float4
pos
=
oldPos[atoms.x]
;
float4
xpi
=
posDelta[atoms.x]
;
float4
pos1
=
oldPos[atoms.y]
;
float4
xpj1
=
posDelta[atoms.y]
;
float4
pos2
=
{0.0f,
0.0f,
0.0f,
0.0f}
;
float4
xpj2
=
{0.0f,
0.0f,
0.0f,
0.0f}
;
float
invMassCentral
=
params.x
;
float
avgMass
=
params.y
;
float
d2
=
params.z
;
float
invMassPeripheral
=
params.w
;
if
(
atoms.z
!=
-1
)
{
pos2
=
oldPos[atoms.z]
;
xpj2
=
posDelta[atoms.z]
;
}
float4
pos3
=
{0.0f,
0.0f,
0.0f,
0.0f}
;
float4
xpj3
=
{0.0f,
0.0f,
0.0f,
0.0f}
;
if
(
atoms.w
!=
-1
)
{
pos3
=
oldPos[atoms.w]
;
xpj3
=
posDelta[atoms.w]
;
}
//
Precompute
quantities.
float4
rij1
=
pos-pos1
;
float4
rij2
=
pos-pos2
;
float4
rij3
=
pos-pos3
;
float
rij1sq
=
rij1.x*rij1.x
+
rij1.y*rij1.y
+
rij1.z*rij1.z
;
float
rij2sq
=
rij2.x*rij2.x
+
rij2.y*rij2.y
+
rij2.z*rij2.z
;
float
rij3sq
=
rij3.x*rij3.x
+
rij3.y*rij3.y
+
rij3.z*rij3.z
;
float
ld1
=
d2-rij1sq
;
float
ld2
=
d2-rij2sq
;
float
ld3
=
d2-rij3sq
;
//
Iterate
until
convergence.
bool
converged
=
false
;
int
iteration
=
0
;
while
(
iteration
<
15
&&
!converged
)
{
converged
=
true
;
float4
rpij
=
xpi-xpj1
;
float
rpsqij
=
rpij.x*rpij.x
+
rpij.y*rpij.y
+
rpij.z*rpij.z
;
float
rrpr
=
rij1.x*rpij.x
+
rij1.y*rpij.y
+
rij1.z*rpij.z
;
float
diff
=
fabs
(
ld1-2.0f*rrpr-rpsqij
)
/
(
d2*tol
)
;
if
(
diff
>=
1.0f
)
{
float
acor
=
(
ld1-2.0f*rrpr-rpsqij
)
*avgMass
/
(
rrpr+rij1sq
)
;
float4
dr
=
rij1*acor
;
xpi.xyz
+=
dr.xyz*invMassCentral
;
xpj1.xyz
-=
dr.xyz*invMassPeripheral
;
converged
=
false
;
}
if
(
atoms.z
!=
-1
)
{
rpij.xyz
=
xpi.xyz-xpj2.xyz
;
rpsqij
=
rpij.x*rpij.x
+
rpij.y*rpij.y
+
rpij.z*rpij.z
;
rrpr
=
rij2.x*rpij.x
+
rij2.y*rpij.y
+
rij2.z*rpij.z
;
diff
=
fabs
(
ld2-2.0f*rrpr-rpsqij
)
/
(
d2*tol
)
;
if
(
diff
>=
1.0f
)
{
float
acor
=
(
ld2
-
2.0f*rrpr
-
rpsqij
)
*avgMass
/
(
rrpr
+
rij2sq
)
;
float4
dr
=
rij2*acor
;
xpi.xyz
+=
dr.xyz*invMassCentral
;
xpj2.xyz
-=
dr.xyz*invMassPeripheral
;
converged
=
false
;
}
}
if
(
atoms.w
!=
-1
)
{
rpij.xyz
=
xpi.xyz-xpj3.xyz
;
rpsqij
=
rpij.x*rpij.x
+
rpij.y*rpij.y
+
rpij.z*rpij.z
;
rrpr
=
rij3.x*rpij.x
+
rij3.y*rpij.y
+
rij3.z*rpij.z
;
diff
=
fabs
(
ld3
-
2.0f*rrpr
-
rpsqij
)
/
(
d2*tol
)
;
if
(
diff
>=
1.0f
)
{
float
acor
=
(
ld3-2.0f*rrpr-rpsqij
)
*avgMass
/
(
rrpr+rij3sq
)
;
float4
dr
=
rij3*acor
;
xpi.xyz
+=
dr.xyz*invMassCentral
;
xpj3.xyz
-=
dr.xyz*invMassPeripheral
;
converged
=
false
;
}
}
iteration++
;
}
//
Record
the
new
positions.
newDelta[atoms.x]
=
xpi
;
newDelta[atoms.y]
=
xpj1
;
if
(
atoms.z
!=
-1
)
newDelta[atoms.z]
=
xpj2
;
if
(
atoms.w
!=
-1
)
newDelta[atoms.w]
=
xpj3
;
index
+=
get_global_size
(
0
)
;
}
}
platforms/opencl/src/kernels/verlet.cl
0 → 100644
View file @
efc1083e
/**
*
Perform
the
first
step
of
verlet
integration.
*/
__kernel
void
integrateVerletPart1
(
int
numAtoms,
float
dt,
__global
float4*
posq,
__global
float4*
velm,
__global
float4*
force,
__global
float4*
posDelta,
__global
float4*
oldPos
)
{
int
index
=
get_global_id
(
0
)
;
while
(
index
<
numAtoms
)
{
float4
pos
=
posq[index]
;
float4
velocity
=
velm[index]
;
oldPos[index]
=
pos
;
velocity.xyz
+=
force[index].xyz*dt*velocity.w
;
pos.xyz
=
velocity.xyz*dt
;
posDelta[index]
=
pos
;
velm[index]
=
velocity
;
index
+=
get_global_size
(
0
)
;
}
}
/**
*
Perform
the
second
step
of
verlet
integration.
*/
__kernel
void
integrateVerletPart2
(
int
numAtoms,
float
dt,
__global
float4*
posq,
__global
float4*
velm,
__global
float4*
posDelta
)
{
int
index
=
get_global_id
(
0
)
;
float
oneOverDt
=
1.0f/dt
;
while
(
index
<
numAtoms
)
{
float4
pos
=
posq[index]
;
float4
delta
=
posDelta[index]
;
float4
velocity
=
velm[index]
;
pos.xyz
+=
delta.xyz
;
velocity.xyz
=
delta.xyz*oneOverDt
;
posq[index]
=
pos
;
velm[index]
=
velocity
;
index
+=
get_global_size
(
0
)
;
}
}
platforms/opencl/tests/TestOpenCLVerletIntegrator.cpp
0 → 100644
View file @
efc1083e
/* -------------------------------------------------------------------------- *
* OpenMM *
* -------------------------------------------------------------------------- *
* This is part of the OpenMM molecular simulation toolkit originating from *
* Simbios, the NIH National Center for Physics-Based Simulation of *
* Biological Structures at Stanford, funded under the NIH Roadmap for *
* Medical Research, grant U54 GM072970. See https://simtk.org. *
* *
* Portions copyright (c) 2008-2009 Stanford University and the Authors. *
* Authors: Peter Eastman *
* Contributors: *
* *
* Permission is hereby granted, free of charge, to any person obtaining a *
* copy of this software and associated documentation files (the "Software"), *
* to deal in the Software without restriction, including without limitation *
* the rights to use, copy, modify, merge, publish, distribute, sublicense, *
* and/or sell copies of the Software, and to permit persons to whom the *
* Software is furnished to do so, subject to the following conditions: *
* *
* The above copyright notice and this permission notice shall be included in *
* all copies or substantial portions of the Software. *
* *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR *
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *
* THE AUTHORS, CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, *
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR *
* OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE *
* USE OR OTHER DEALINGS IN THE SOFTWARE. *
* -------------------------------------------------------------------------- */
/**
* This tests the OpenCL implementation of VerletIntegrator.
*/
#include "../../../tests/AssertionUtilities.h"
#include "openmm/Context.h"
#include "OpenCLPlatform.h"
#include "openmm/HarmonicBondForce.h"
#include "openmm/NonbondedForce.h"
#include "openmm/System.h"
#include "openmm/VerletIntegrator.h"
#include "../src/SimTKUtilities/SimTKOpenMMRealType.h"
#include "../src/sfmt/SFMT.h"
#include <iostream>
#include <vector>
using
namespace
OpenMM
;
using
namespace
std
;
const
double
TOL
=
1e-5
;
void
testSingleBond
()
{
OpenCLPlatform
platform
;
System
system
;
system
.
addParticle
(
2.0
);
system
.
addParticle
(
2.0
);
VerletIntegrator
integrator
(
0.01
);
HarmonicBondForce
*
forceField
=
new
HarmonicBondForce
();
forceField
->
addBond
(
0
,
1
,
1.5
,
1
);
system
.
addForce
(
forceField
);
Context
context
(
system
,
integrator
,
platform
);
vector
<
Vec3
>
positions
(
2
);
positions
[
0
]
=
Vec3
(
-
1
,
0
,
0
);
positions
[
1
]
=
Vec3
(
1
,
0
,
0
);
context
.
setPositions
(
positions
);
// This is simply a harmonic oscillator, so compare it to the analytical solution.
const
double
freq
=
1.0
;;
State
state
=
context
.
getState
(
State
::
Energy
);
const
double
initialEnergy
=
state
.
getKineticEnergy
()
+
state
.
getPotentialEnergy
();
for
(
int
i
=
0
;
i
<
1000
;
++
i
)
{
state
=
context
.
getState
(
State
::
Positions
|
State
::
Velocities
|
State
::
Energy
);
double
time
=
state
.
getTime
();
double
expectedDist
=
1.5
+
0.5
*
std
::
cos
(
freq
*
time
);
ASSERT_EQUAL_VEC
(
Vec3
(
-
0.5
*
expectedDist
,
0
,
0
),
state
.
getPositions
()[
0
],
0.02
);
ASSERT_EQUAL_VEC
(
Vec3
(
0.5
*
expectedDist
,
0
,
0
),
state
.
getPositions
()[
1
],
0.02
);
double
expectedSpeed
=
-
0.5
*
freq
*
std
::
sin
(
freq
*
time
);
ASSERT_EQUAL_VEC
(
Vec3
(
-
0.5
*
expectedSpeed
,
0
,
0
),
state
.
getVelocities
()[
0
],
0.02
);
ASSERT_EQUAL_VEC
(
Vec3
(
0.5
*
expectedSpeed
,
0
,
0
),
state
.
getVelocities
()[
1
],
0.02
);
double
energy
=
state
.
getKineticEnergy
()
+
state
.
getPotentialEnergy
();
ASSERT_EQUAL_TOL
(
initialEnergy
,
energy
,
0.01
);
integrator
.
step
(
1
);
}
}
void
testConstraints
()
{
const
int
numParticles
=
8
;
const
int
numConstraints
=
5
;
const
double
temp
=
100.0
;
OpenCLPlatform
platform
;
System
system
;
VerletIntegrator
integrator
(
0.001
);
integrator
.
setConstraintTolerance
(
1e-5
);
NonbondedForce
*
forceField
=
new
NonbondedForce
();
for
(
int
i
=
0
;
i
<
numParticles
;
++
i
)
{
system
.
addParticle
(
10.0
);
forceField
->
addParticle
((
i
%
2
==
0
?
0.2
:
-
0.2
),
0.5
,
5.0
);
}
system
.
addConstraint
(
0
,
1
,
1.0
);
system
.
addConstraint
(
1
,
2
,
1.0
);
system
.
addConstraint
(
2
,
3
,
1.0
);
system
.
addConstraint
(
4
,
5
,
1.0
);
system
.
addConstraint
(
6
,
7
,
1.0
);
system
.
addForce
(
forceField
);
Context
context
(
system
,
integrator
,
platform
);
vector
<
Vec3
>
positions
(
numParticles
);
vector
<
Vec3
>
velocities
(
numParticles
);
init_gen_rand
(
0
);
for
(
int
i
=
0
;
i
<
numParticles
;
++
i
)
{
positions
[
i
]
=
Vec3
(
i
/
2
,
(
i
+
1
)
/
2
,
0
);
velocities
[
i
]
=
Vec3
(
genrand_real2
()
-
0.5
,
genrand_real2
()
-
0.5
,
genrand_real2
()
-
0.5
);
}
context
.
setPositions
(
positions
);
context
.
setVelocities
(
velocities
);
// Simulate it and see whether the constraints remain satisfied.
double
initialEnergy
=
0.0
;
for
(
int
i
=
0
;
i
<
1000
;
++
i
)
{
State
state
=
context
.
getState
(
State
::
Positions
|
State
::
Energy
);
for
(
int
j
=
0
;
j
<
numConstraints
;
++
j
)
{
int
particle1
,
particle2
;
double
distance
;
system
.
getConstraintParameters
(
j
,
particle1
,
particle2
,
distance
);
Vec3
p1
=
state
.
getPositions
()[
particle1
];
Vec3
p2
=
state
.
getPositions
()[
particle2
];
double
dist
=
std
::
sqrt
((
p1
[
0
]
-
p2
[
0
])
*
(
p1
[
0
]
-
p2
[
0
])
+
(
p1
[
1
]
-
p2
[
1
])
*
(
p1
[
1
]
-
p2
[
1
])
+
(
p1
[
2
]
-
p2
[
2
])
*
(
p1
[
2
]
-
p2
[
2
]));
ASSERT_EQUAL_TOL
(
distance
,
dist
,
1e-4
);
}
double
energy
=
state
.
getKineticEnergy
()
+
state
.
getPotentialEnergy
();
if
(
i
==
1
)
initialEnergy
=
energy
;
else
if
(
i
>
1
)
ASSERT_EQUAL_TOL
(
initialEnergy
,
energy
,
0.05
);
integrator
.
step
(
1
);
}
}
void
testConstrainedClusters
()
{
const
int
numParticles
=
7
;
const
double
temp
=
500.0
;
OpenCLPlatform
platform
;
System
system
;
VerletIntegrator
integrator
(
0.002
);
integrator
.
setConstraintTolerance
(
1e-5
);
NonbondedForce
*
forceField
=
new
NonbondedForce
();
for
(
int
i
=
0
;
i
<
numParticles
;
++
i
)
{
system
.
addParticle
(
i
>
1
?
1.0
:
10.0
);
forceField
->
addParticle
((
i
%
2
==
0
?
0.2
:
-
0.2
),
0.5
,
5.0
);
}
system
.
addConstraint
(
0
,
1
,
1.0
);
system
.
addConstraint
(
0
,
2
,
1.0
);
system
.
addConstraint
(
0
,
3
,
1.0
);
system
.
addConstraint
(
0
,
4
,
1.0
);
system
.
addConstraint
(
1
,
5
,
1.0
);
system
.
addConstraint
(
1
,
6
,
1.0
);
system
.
addConstraint
(
2
,
3
,
sqrt
(
2.0
));
system
.
addConstraint
(
2
,
4
,
sqrt
(
2.0
));
system
.
addConstraint
(
3
,
4
,
sqrt
(
2.0
));
system
.
addConstraint
(
5
,
6
,
sqrt
(
2.0
));
system
.
addForce
(
forceField
);
Context
context
(
system
,
integrator
,
platform
);
vector
<
Vec3
>
positions
(
numParticles
);
positions
[
0
]
=
Vec3
(
0
,
0
,
0
);
positions
[
1
]
=
Vec3
(
1
,
0
,
0
);
positions
[
2
]
=
Vec3
(
-
1
,
0
,
0
);
positions
[
3
]
=
Vec3
(
0
,
1
,
0
);
positions
[
4
]
=
Vec3
(
0
,
0
,
1
);
positions
[
5
]
=
Vec3
(
2
,
0
,
0
);
positions
[
6
]
=
Vec3
(
1
,
1
,
0
);
vector
<
Vec3
>
velocities
(
numParticles
);
init_gen_rand
(
0
);
for
(
int
i
=
0
;
i
<
numParticles
;
++
i
)
velocities
[
i
]
=
Vec3
(
genrand_real2
()
-
0.5
,
genrand_real2
()
-
0.5
,
genrand_real2
()
-
0.5
);
context
.
setPositions
(
positions
);
context
.
setVelocities
(
velocities
);
// Simulate it and see whether the constraints remain satisfied.
double
initialEnergy
=
0.0
;
for
(
int
i
=
0
;
i
<
1000
;
++
i
)
{
State
state
=
context
.
getState
(
State
::
Positions
|
State
::
Energy
);
for
(
int
j
=
0
;
j
<
system
.
getNumConstraints
();
++
j
)
{
int
particle1
,
particle2
;
double
distance
;
system
.
getConstraintParameters
(
j
,
particle1
,
particle2
,
distance
);
Vec3
p1
=
state
.
getPositions
()[
particle1
];
Vec3
p2
=
state
.
getPositions
()[
particle2
];
double
dist
=
std
::
sqrt
((
p1
[
0
]
-
p2
[
0
])
*
(
p1
[
0
]
-
p2
[
0
])
+
(
p1
[
1
]
-
p2
[
1
])
*
(
p1
[
1
]
-
p2
[
1
])
+
(
p1
[
2
]
-
p2
[
2
])
*
(
p1
[
2
]
-
p2
[
2
]));
ASSERT_EQUAL_TOL
(
distance
,
dist
,
2e-5
);
}
double
energy
=
state
.
getKineticEnergy
()
+
state
.
getPotentialEnergy
();
if
(
i
==
1
)
initialEnergy
=
energy
;
else
if
(
i
>
1
)
ASSERT_EQUAL_TOL
(
initialEnergy
,
energy
,
0.05
);
integrator
.
step
(
1
);
}
}
int
main
()
{
try
{
testSingleBond
();
// testConstraints();
// testConstrainedClusters();
}
catch
(
const
exception
&
e
)
{
cout
<<
"exception: "
<<
e
.
what
()
<<
endl
;
return
1
;
}
cout
<<
"Done"
<<
endl
;
return
0
;
}
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