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
69812ad7
Commit
69812ad7
authored
Jan 13, 2012
by
Peter Eastman
Browse files
Fixed bug in CustomIntegrator when atoms get reordered
parent
43e57ba0
Changes
6
Hide whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
184 additions
and
2 deletions
+184
-2
platforms/opencl/src/OpenCLContext.cpp
platforms/opencl/src/OpenCLContext.cpp
+8
-0
platforms/opencl/src/OpenCLContext.h
platforms/opencl/src/OpenCLContext.h
+17
-0
platforms/opencl/src/OpenCLKernels.cpp
platforms/opencl/src/OpenCLKernels.cpp
+42
-2
platforms/opencl/src/OpenCLKernels.h
platforms/opencl/src/OpenCLKernels.h
+1
-0
platforms/opencl/tests/TestOpenCLCustomIntegrator.cpp
platforms/opencl/tests/TestOpenCLCustomIntegrator.cpp
+58
-0
platforms/reference/tests/TestReferenceCustomIntegrator.cpp
platforms/reference/tests/TestReferenceCustomIntegrator.cpp
+58
-0
No files found.
platforms/opencl/src/OpenCLContext.cpp
View file @
69812ad7
...
@@ -203,6 +203,8 @@ OpenCLContext::OpenCLContext(int numParticles, int platformIndex, int deviceInde
...
@@ -203,6 +203,8 @@ OpenCLContext::OpenCLContext(int numParticles, int platformIndex, int deviceInde
OpenCLContext
::~
OpenCLContext
()
{
OpenCLContext
::~
OpenCLContext
()
{
for
(
int
i
=
0
;
i
<
(
int
)
forces
.
size
();
i
++
)
for
(
int
i
=
0
;
i
<
(
int
)
forces
.
size
();
i
++
)
delete
forces
[
i
];
delete
forces
[
i
];
for
(
int
i
=
0
;
i
<
(
int
)
reorderListeners
.
size
();
i
++
)
delete
reorderListeners
[
i
];
if
(
posq
!=
NULL
)
if
(
posq
!=
NULL
)
delete
posq
;
delete
posq
;
if
(
velm
!=
NULL
)
if
(
velm
!=
NULL
)
...
@@ -728,6 +730,12 @@ void OpenCLContext::reorderAtoms() {
...
@@ -728,6 +730,12 @@ void OpenCLContext::reorderAtoms() {
posq
->
upload
();
posq
->
upload
();
velm
->
upload
();
velm
->
upload
();
atomIndex
->
upload
();
atomIndex
->
upload
();
for
(
int
i
=
0
;
i
<
(
int
)
reorderListeners
.
size
();
i
++
)
reorderListeners
[
i
]
->
execute
();
}
void
OpenCLContext
::
addReorderListener
(
ReorderListener
*
listener
)
{
reorderListeners
.
push_back
(
listener
);
}
}
struct
OpenCLContext
::
WorkThread
::
ThreadData
{
struct
OpenCLContext
::
WorkThread
::
ThreadData
{
...
...
platforms/opencl/src/OpenCLContext.h
View file @
69812ad7
...
@@ -143,6 +143,7 @@ class OPENMM_EXPORT OpenCLContext {
...
@@ -143,6 +143,7 @@ class OPENMM_EXPORT OpenCLContext {
public:
public:
class
WorkTask
;
class
WorkTask
;
class
WorkThread
;
class
WorkThread
;
class
ReorderListener
;
static
const
int
ThreadBlockSize
;
static
const
int
ThreadBlockSize
;
static
const
int
TileSize
;
static
const
int
TileSize
;
OpenCLContext
(
int
numParticles
,
int
platformIndex
,
int
deviceIndex
,
OpenCLPlatform
::
PlatformData
&
platformData
);
OpenCLContext
(
int
numParticles
,
int
platformIndex
,
int
deviceIndex
,
OpenCLPlatform
::
PlatformData
&
platformData
);
...
@@ -467,6 +468,11 @@ public:
...
@@ -467,6 +468,11 @@ public:
* together in the arrays.
* together in the arrays.
*/
*/
void
reorderAtoms
();
void
reorderAtoms
();
/**
* Add a listener that should be called whenever atoms get reordered. The OpenCLContext
* assumes ownership of the object, and deletes it when the context itself is deleted.
*/
void
addReorderListener
(
ReorderListener
*
listener
);
private:
private:
struct
Molecule
;
struct
Molecule
;
struct
MoleculeGroup
;
struct
MoleculeGroup
;
...
@@ -513,6 +519,7 @@ private:
...
@@ -513,6 +519,7 @@ private:
OpenCLArray
<
cl_int
>*
atomIndex
;
OpenCLArray
<
cl_int
>*
atomIndex
;
std
::
vector
<
cl
::
Memory
*>
autoclearBuffers
;
std
::
vector
<
cl
::
Memory
*>
autoclearBuffers
;
std
::
vector
<
int
>
autoclearBufferSizes
;
std
::
vector
<
int
>
autoclearBufferSizes
;
std
::
vector
<
ReorderListener
*>
reorderListeners
;
OpenCLIntegrationUtilities
*
integration
;
OpenCLIntegrationUtilities
*
integration
;
OpenCLBondedUtilities
*
bonded
;
OpenCLBondedUtilities
*
bonded
;
OpenCLNonbondedUtilities
*
nonbonded
;
OpenCLNonbondedUtilities
*
nonbonded
;
...
@@ -562,6 +569,16 @@ private:
...
@@ -562,6 +569,16 @@ private:
pthread_t
thread
;
pthread_t
thread
;
};
};
/**
* This abstract class defines a function to be executed whenever atoms get reordered.
* Objects that need to know when reordering happens should create a reorderListener
* and register it by calling addReorderListener().
*/
class
OpenCLContext
::
ReorderListener
{
public:
virtual
void
execute
()
=
0
;
};
}
// namespace OpenMM
}
// namespace OpenMM
#endif
/*OPENMM_OPENCLCONTEXT_H_*/
#endif
/*OPENMM_OPENCLCONTEXT_H_*/
platforms/opencl/src/OpenCLKernels.cpp
View file @
69812ad7
...
@@ -3500,6 +3500,43 @@ void OpenCLIntegrateVariableLangevinStepKernel::execute(ContextImpl& context, co
...
@@ -3500,6 +3500,43 @@ void OpenCLIntegrateVariableLangevinStepKernel::execute(ContextImpl& context, co
cl.setStepCount(cl.getStepCount()+1);
cl.setStepCount(cl.getStepCount()+1);
}
}
class OpenCLIntegrateCustomStepKernel::ReorderListener : public OpenCLContext::ReorderListener {
public:
ReorderListener(OpenCLContext& cl, OpenCLParameterSet& perDofValues, vector<vector<cl_float> >& localPerDofValues) :
cl(cl), perDofValues(perDofValues), localPerDofValues(localPerDofValues) {
int numAtoms = cl.getNumAtoms();
lastAtomOrder.resize(numAtoms);
for (int i = 0; i < numAtoms; i++)
lastAtomOrder[i] = cl.getAtomIndex()[i];
}
void execute() {
// Reorder the per-DOF variables to reflect the new atom order.
int numAtoms = cl.getNumAtoms();
perDofValues.getParameterValues(localPerDofValues);
vector<vector<cl_float> > swap(3*numAtoms);
for (int i = 0; i < numAtoms; i++) {
swap[3*lastAtomOrder[i]] = localPerDofValues[3*i];
swap[3*lastAtomOrder[i]+1] = localPerDofValues[3*i+1];
swap[3*lastAtomOrder[i]+2] = localPerDofValues[3*i+2];
}
OpenCLArray<cl_int>& order = cl.getAtomIndex();
for (int i = 0; i < numAtoms; i++) {
localPerDofValues[3*i] = swap[3*order[i]];
localPerDofValues[3*i+1] = swap[3*order[i]+1];
localPerDofValues[3*i+2] = swap[3*order[i]+2];
}
perDofValues.setParameterValues(localPerDofValues);
for (int i = 0; i < numAtoms; i++)
lastAtomOrder[i] = order[i];
}
private:
OpenCLContext& cl;
OpenCLParameterSet& perDofValues;
vector<vector<cl_float> >& localPerDofValues;
std::vector<int> lastAtomOrder;
};
OpenCLIntegrateCustomStepKernel::~OpenCLIntegrateCustomStepKernel() {
OpenCLIntegrateCustomStepKernel::~OpenCLIntegrateCustomStepKernel() {
if (globalValues != NULL)
if (globalValues != NULL)
delete globalValues;
delete globalValues;
...
@@ -3619,6 +3656,7 @@ void OpenCLIntegrateCustomStepKernel::execute(ContextImpl& context, CustomIntegr
...
@@ -3619,6 +3656,7 @@ void OpenCLIntegrateCustomStepKernel::execute(ContextImpl& context, CustomIntegr
invalidatesForces.resize(numSteps, false);
invalidatesForces.resize(numSteps, false);
merged.resize(numSteps, false);
merged.resize(numSteps, false);
modifiesParameters = false;
modifiesParameters = false;
cl.addReorderListener(new ReorderListener(cl, *perDofValues, localPerDofValues));
map<string, string> defines;
map<string, string> defines;
defines["NUM_ATOMS"] = intToString(cl.getNumAtoms());
defines["NUM_ATOMS"] = intToString(cl.getNumAtoms());
defines["WORK_GROUP_SIZE"] = intToString(OpenCLContext::ThreadBlockSize);
defines["WORK_GROUP_SIZE"] = intToString(OpenCLContext::ThreadBlockSize);
...
@@ -3962,9 +4000,10 @@ void OpenCLIntegrateCustomStepKernel::getPerDofVariable(ContextImpl& context, in
...
@@ -3962,9 +4000,10 @@ void OpenCLIntegrateCustomStepKernel::getPerDofVariable(ContextImpl& context, in
localValuesAreCurrent = true;
localValuesAreCurrent = true;
}
}
values.resize(perDofValues->getNumObjects()/3);
values.resize(perDofValues->getNumObjects()/3);
OpenCLArray<cl_int>& order = cl.getAtomIndex();
for (int i = 0; i < (int) values.size(); i++)
for (int i = 0; i < (int) values.size(); i++)
for (int j = 0; j < 3; j++)
for (int j = 0; j < 3; j++)
values
[
i
][
j
]
=
localPerDofValues
[
3
*
i
+
j
][
variable
];
values[
order[i]
][j] = localPerDofValues[3*i+j][variable];
}
}
void OpenCLIntegrateCustomStepKernel::setPerDofVariable(ContextImpl& context, int variable, const vector<Vec3>& values) {
void OpenCLIntegrateCustomStepKernel::setPerDofVariable(ContextImpl& context, int variable, const vector<Vec3>& values) {
...
@@ -3972,9 +4011,10 @@ void OpenCLIntegrateCustomStepKernel::setPerDofVariable(ContextImpl& context, in
...
@@ -3972,9 +4011,10 @@ void OpenCLIntegrateCustomStepKernel::setPerDofVariable(ContextImpl& context, in
perDofValues->getParameterValues(localPerDofValues);
perDofValues->getParameterValues(localPerDofValues);
localValuesAreCurrent = true;
localValuesAreCurrent = true;
}
}
OpenCLArray<cl_int>& order = cl.getAtomIndex();
for (int i = 0; i < (int) values.size(); i++)
for (int i = 0; i < (int) values.size(); i++)
for (int j = 0; j < 3; j++)
for (int j = 0; j < 3; j++)
localPerDofValues
[
3
*
i
+
j
][
variable
]
=
(
float
)
values
[
i
][
j
];
localPerDofValues[3*i+j][variable] = (float) values[
order[i]
][j];
deviceValuesAreCurrent = false;
deviceValuesAreCurrent = false;
}
}
...
...
platforms/opencl/src/OpenCLKernels.h
View file @
69812ad7
...
@@ -946,6 +946,7 @@ public:
...
@@ -946,6 +946,7 @@ public:
*/
*/
void
setPerDofVariable
(
ContextImpl
&
context
,
int
variable
,
const
std
::
vector
<
Vec3
>&
values
);
void
setPerDofVariable
(
ContextImpl
&
context
,
int
variable
,
const
std
::
vector
<
Vec3
>&
values
);
private:
private:
class
ReorderListener
;
std
::
string
createGlobalComputation
(
const
std
::
string
&
variable
,
const
Lepton
::
ParsedExpression
&
expr
,
CustomIntegrator
&
integrator
);
std
::
string
createGlobalComputation
(
const
std
::
string
&
variable
,
const
Lepton
::
ParsedExpression
&
expr
,
CustomIntegrator
&
integrator
);
std
::
string
createPerDofComputation
(
const
std
::
string
&
variable
,
const
Lepton
::
ParsedExpression
&
expr
,
int
component
,
CustomIntegrator
&
integrator
);
std
::
string
createPerDofComputation
(
const
std
::
string
&
variable
,
const
Lepton
::
ParsedExpression
&
expr
,
int
component
,
CustomIntegrator
&
integrator
);
void
recordChangedParameters
(
ContextImpl
&
context
);
void
recordChangedParameters
(
ContextImpl
&
context
);
...
...
platforms/opencl/tests/TestOpenCLCustomIntegrator.cpp
View file @
69812ad7
...
@@ -467,6 +467,63 @@ void testRandomDistributions() {
...
@@ -467,6 +467,63 @@ void testRandomDistributions() {
ASSERT_EQUAL_TOL
(
0.0
,
c4
,
3.0
/
pow
(
numValues
,
1.0
/
4.0
));
ASSERT_EQUAL_TOL
(
0.0
,
c4
,
3.0
/
pow
(
numValues
,
1.0
/
4.0
));
}
}
/**
* Test getting and setting per-DOF variables.
*/
void
testPerDofVariables
()
{
const
int
numParticles
=
200
;
const
double
boxSize
=
10
;
OpenCLPlatform
platform
;
System
system
;
system
.
setDefaultPeriodicBoxVectors
(
Vec3
(
boxSize
,
0
,
0
),
Vec3
(
0
,
boxSize
,
0
),
Vec3
(
0
,
0
,
boxSize
));
NonbondedForce
*
nb
=
new
NonbondedForce
();
system
.
addForce
(
nb
);
nb
->
setNonbondedMethod
(
NonbondedForce
::
CutoffNonPeriodic
);
vector
<
Vec3
>
positions
(
numParticles
);
OpenMM_SFMT
::
SFMT
sfmt
;
init_gen_rand
(
0
,
sfmt
);
for
(
int
i
=
0
;
i
<
numParticles
;
i
++
)
{
system
.
addParticle
(
1.5
);
nb
->
addParticle
(
i
%
2
==
0
?
1
:
-
1
,
0.1
,
1
);
bool
close
=
true
;
while
(
close
)
{
positions
[
i
]
=
Vec3
(
boxSize
*
genrand_real2
(
sfmt
),
boxSize
*
genrand_real2
(
sfmt
),
boxSize
*
genrand_real2
(
sfmt
));
close
=
false
;
for
(
int
j
=
0
;
j
<
i
;
++
j
)
{
Vec3
delta
=
positions
[
i
]
-
positions
[
j
];
if
(
delta
.
dot
(
delta
)
<
0.1
)
close
=
true
;
}
}
}
CustomIntegrator
integrator
(
0.01
);
integrator
.
addPerDofVariable
(
"temp"
,
0
);
integrator
.
addPerDofVariable
(
"pos"
,
0
);
integrator
.
addComputePerDof
(
"v"
,
"v+dt*f/m"
);
integrator
.
addComputePerDof
(
"x"
,
"x+dt*v"
);
integrator
.
addComputePerDof
(
"pos"
,
"x"
);
Context
context
(
system
,
integrator
,
platform
);
context
.
setPositions
(
positions
);
vector
<
Vec3
>
initialValues
(
numParticles
);
for
(
int
i
=
0
;
i
<
numParticles
;
i
++
)
initialValues
[
i
]
=
Vec3
(
i
+
0.1
,
i
+
0.2
,
i
+
0.3
);
integrator
.
setPerDofVariable
(
0
,
initialValues
);
// Run a simulation, then query per-DOF values and see if they are correct.
vector
<
Vec3
>
values
;
for
(
int
i
=
0
;
i
<
100
;
++
i
)
{
integrator
.
step
(
1
);
State
state
=
context
.
getState
(
State
::
Positions
);
integrator
.
getPerDofVariable
(
0
,
values
);
for
(
int
j
=
0
;
j
<
numParticles
;
j
++
)
ASSERT_EQUAL_VEC
(
initialValues
[
j
],
values
[
j
],
1e-5
);
integrator
.
getPerDofVariable
(
1
,
values
);
for
(
int
j
=
0
;
j
<
numParticles
;
j
++
)
ASSERT_EQUAL_VEC
(
state
.
getPositions
()[
j
],
values
[
j
],
1e-5
);
}
}
int
main
()
{
int
main
()
{
try
{
try
{
testSingleBond
();
testSingleBond
();
...
@@ -477,6 +534,7 @@ int main() {
...
@@ -477,6 +534,7 @@ int main() {
testSum
();
testSum
();
testParameter
();
testParameter
();
testRandomDistributions
();
testRandomDistributions
();
testPerDofVariables
();
}
}
catch
(
const
exception
&
e
)
{
catch
(
const
exception
&
e
)
{
cout
<<
"exception: "
<<
e
.
what
()
<<
endl
;
cout
<<
"exception: "
<<
e
.
what
()
<<
endl
;
...
...
platforms/reference/tests/TestReferenceCustomIntegrator.cpp
View file @
69812ad7
...
@@ -453,6 +453,63 @@ void testRandomDistributions() {
...
@@ -453,6 +453,63 @@ void testRandomDistributions() {
ASSERT_EQUAL_TOL
(
0.0
,
c4
,
3.0
/
pow
(
numValues
,
1.0
/
4.0
));
ASSERT_EQUAL_TOL
(
0.0
,
c4
,
3.0
/
pow
(
numValues
,
1.0
/
4.0
));
}
}
/**
* Test getting and setting per-DOF variables.
*/
void
testPerDofVariables
()
{
const
int
numParticles
=
200
;
const
double
boxSize
=
10
;
ReferencePlatform
platform
;
System
system
;
system
.
setDefaultPeriodicBoxVectors
(
Vec3
(
boxSize
,
0
,
0
),
Vec3
(
0
,
boxSize
,
0
),
Vec3
(
0
,
0
,
boxSize
));
NonbondedForce
*
nb
=
new
NonbondedForce
();
system
.
addForce
(
nb
);
nb
->
setNonbondedMethod
(
NonbondedForce
::
CutoffNonPeriodic
);
vector
<
Vec3
>
positions
(
numParticles
);
OpenMM_SFMT
::
SFMT
sfmt
;
init_gen_rand
(
0
,
sfmt
);
for
(
int
i
=
0
;
i
<
numParticles
;
i
++
)
{
system
.
addParticle
(
1.5
);
nb
->
addParticle
(
i
%
2
==
0
?
1
:
-
1
,
0.1
,
1
);
bool
close
=
true
;
while
(
close
)
{
positions
[
i
]
=
Vec3
(
boxSize
*
genrand_real2
(
sfmt
),
boxSize
*
genrand_real2
(
sfmt
),
boxSize
*
genrand_real2
(
sfmt
));
close
=
false
;
for
(
int
j
=
0
;
j
<
i
;
++
j
)
{
Vec3
delta
=
positions
[
i
]
-
positions
[
j
];
if
(
delta
.
dot
(
delta
)
<
0.1
)
close
=
true
;
}
}
}
CustomIntegrator
integrator
(
0.01
);
integrator
.
addPerDofVariable
(
"temp"
,
0
);
integrator
.
addPerDofVariable
(
"pos"
,
0
);
integrator
.
addComputePerDof
(
"v"
,
"v+dt*f/m"
);
integrator
.
addComputePerDof
(
"x"
,
"x+dt*v"
);
integrator
.
addComputePerDof
(
"pos"
,
"x"
);
Context
context
(
system
,
integrator
,
platform
);
context
.
setPositions
(
positions
);
vector
<
Vec3
>
initialValues
(
numParticles
);
for
(
int
i
=
0
;
i
<
numParticles
;
i
++
)
initialValues
[
i
]
=
Vec3
(
i
+
0.1
,
i
+
0.2
,
i
+
0.3
);
integrator
.
setPerDofVariable
(
0
,
initialValues
);
// Run a simulation, then query per-DOF values and see if they are correct.
vector
<
Vec3
>
values
;
for
(
int
i
=
0
;
i
<
100
;
++
i
)
{
integrator
.
step
(
1
);
State
state
=
context
.
getState
(
State
::
Positions
);
integrator
.
getPerDofVariable
(
0
,
values
);
for
(
int
j
=
0
;
j
<
numParticles
;
j
++
)
ASSERT_EQUAL_VEC
(
initialValues
[
j
],
values
[
j
],
1e-5
);
integrator
.
getPerDofVariable
(
1
,
values
);
for
(
int
j
=
0
;
j
<
numParticles
;
j
++
)
ASSERT_EQUAL_VEC
(
state
.
getPositions
()[
j
],
values
[
j
],
1e-5
);
}
}
int
main
()
{
int
main
()
{
try
{
try
{
testSingleBond
();
testSingleBond
();
...
@@ -463,6 +520,7 @@ int main() {
...
@@ -463,6 +520,7 @@ int main() {
testSum
();
testSum
();
testParameter
();
testParameter
();
testRandomDistributions
();
testRandomDistributions
();
testPerDofVariables
();
}
}
catch
(
const
exception
&
e
)
{
catch
(
const
exception
&
e
)
{
cout
<<
"exception: "
<<
e
.
what
()
<<
endl
;
cout
<<
"exception: "
<<
e
.
what
()
<<
endl
;
...
...
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