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
0e6cbcea
"platforms/cuda/vscode:/vscode.git/clone" did not exist on "b8c86406e9b279d167438bd167b17ea91cfba3d9"
Commit
0e6cbcea
authored
May 09, 2012
by
Peter Eastman
Browse files
Created OpenCL implementation of CustomCompoundBondForce
parent
35aef079
Changes
11
Show whitespace changes
Inline
Side-by-side
Showing
11 changed files
with
656 additions
and
5 deletions
+656
-5
platforms/opencl/src/OpenCLBondedUtilities.cpp
platforms/opencl/src/OpenCLBondedUtilities.cpp
+6
-0
platforms/opencl/src/OpenCLBondedUtilities.h
platforms/opencl/src/OpenCLBondedUtilities.h
+8
-0
platforms/opencl/src/OpenCLKernelFactory.cpp
platforms/opencl/src/OpenCLKernelFactory.cpp
+4
-0
platforms/opencl/src/OpenCLKernels.cpp
platforms/opencl/src/OpenCLKernels.cpp
+293
-0
platforms/opencl/src/OpenCLKernels.h
platforms/opencl/src/OpenCLKernels.h
+37
-0
platforms/opencl/src/OpenCLParallelKernels.cpp
platforms/opencl/src/OpenCLParallelKernels.cpp
+36
-0
platforms/opencl/src/OpenCLParallelKernels.h
platforms/opencl/src/OpenCLParallelKernels.h
+31
-0
platforms/opencl/src/OpenCLPlatform.cpp
platforms/opencl/src/OpenCLPlatform.cpp
+1
-0
platforms/opencl/src/kernels/customCompoundBond.cl
platforms/opencl/src/kernels/customCompoundBond.cl
+38
-0
platforms/opencl/tests/TestOpenCLCustomCompoundBondForce.cpp
platforms/opencl/tests/TestOpenCLCustomCompoundBondForce.cpp
+198
-0
platforms/reference/tests/TestReferenceCustomCompoundBondForce.cpp
.../reference/tests/TestReferenceCustomCompoundBondForce.cpp
+4
-5
No files found.
platforms/opencl/src/OpenCLBondedUtilities.cpp
View file @
0e6cbcea
...
...
@@ -61,6 +61,10 @@ std::string OpenCLBondedUtilities::addArgument(cl::Memory& data, const string& t
return
"customArg"
+
OpenCLExpressionUtilities
::
intToString
(
arguments
.
size
());
}
void
OpenCLBondedUtilities
::
addPrefixCode
(
const
string
&
source
)
{
prefixCode
.
push_back
(
source
);
}
void
OpenCLBondedUtilities
::
initialize
(
const
System
&
system
)
{
int
numForces
=
forceAtoms
.
size
();
if
(
numForces
==
0
)
...
...
@@ -155,6 +159,8 @@ void OpenCLBondedUtilities::initialize(const System& system) {
const
vector
<
int
>&
set
=
*
iter
;
int
setSize
=
set
.
size
();
stringstream
s
;
for
(
int
i
=
0
;
i
<
(
int
)
prefixCode
.
size
();
i
++
)
s
<<
prefixCode
[
i
];
s
<<
"__kernel void computeBondedForces(__global float4* restrict forceBuffers, __global float* restrict energyBuffer, __global const float4* restrict posq, int groups"
;
for
(
int
i
=
0
;
i
<
setSize
;
i
++
)
{
int
force
=
set
[
i
];
...
...
platforms/opencl/src/OpenCLBondedUtilities.h
View file @
0e6cbcea
...
...
@@ -100,6 +100,13 @@ public:
* refer to it by this name.
*/
std
::
string
addArgument
(
cl
::
Memory
&
data
,
const
std
::
string
&
type
);
/**
* Add some OpenCL code that should be included in the program, before the start of the kernel.
* This can be used, for example, to define functions that will be called by the kernel.
*
* @param source the code to include
*/
void
addPrefixCode
(
const
std
::
string
&
source
);
/**
* Initialize this object in preparation for a simulation.
*/
...
...
@@ -129,6 +136,7 @@ private:
std
::
vector
<
std
::
string
>
argTypes
;
std
::
vector
<
OpenCLArray
<
cl_uint
>*>
atomIndices
;
std
::
vector
<
OpenCLArray
<
cl_uint
>*>
bufferIndices
;
std
::
vector
<
std
::
string
>
prefixCode
;
int
numForceBuffers
,
maxBonds
;
bool
hasInitializedKernels
;
};
...
...
platforms/opencl/src/OpenCLKernelFactory.cpp
View file @
0e6cbcea
...
...
@@ -62,6 +62,8 @@ KernelImpl* OpenCLKernelFactory::createKernelImpl(std::string name, const Platfo
return
new
OpenCLParallelCalcCustomExternalForceKernel
(
name
,
platform
,
data
,
context
.
getSystem
());
if
(
name
==
CalcCustomHbondForceKernel
::
Name
())
return
new
OpenCLParallelCalcCustomHbondForceKernel
(
name
,
platform
,
data
,
context
.
getSystem
());
if
(
name
==
CalcCustomCompoundBondForceKernel
::
Name
())
return
new
OpenCLParallelCalcCustomCompoundBondForceKernel
(
name
,
platform
,
data
,
context
.
getSystem
());
}
OpenCLContext
&
cl
=
*
data
.
contexts
[
0
];
if
(
name
==
CalcForcesAndEnergyKernel
::
Name
())
...
...
@@ -100,6 +102,8 @@ KernelImpl* OpenCLKernelFactory::createKernelImpl(std::string name, const Platfo
return
new
OpenCLCalcCustomExternalForceKernel
(
name
,
platform
,
cl
,
context
.
getSystem
());
if
(
name
==
CalcCustomHbondForceKernel
::
Name
())
return
new
OpenCLCalcCustomHbondForceKernel
(
name
,
platform
,
cl
,
context
.
getSystem
());
if
(
name
==
CalcCustomCompoundBondForceKernel
::
Name
())
return
new
OpenCLCalcCustomCompoundBondForceKernel
(
name
,
platform
,
cl
,
context
.
getSystem
());
if
(
name
==
IntegrateVerletStepKernel
::
Name
())
return
new
OpenCLIntegrateVerletStepKernel
(
name
,
platform
,
cl
);
if
(
name
==
IntegrateLangevinStepKernel
::
Name
())
...
...
platforms/opencl/src/OpenCLKernels.cpp
View file @
0e6cbcea
...
...
@@ -31,6 +31,7 @@
#include "openmm/internal/AndersenThermostatImpl.h"
#include "openmm/internal/CMAPTorsionForceImpl.h"
#include "openmm/internal/ContextImpl.h"
#include "openmm/internal/CustomCompoundBondForceImpl.h"
#include "openmm/internal/CustomHbondForceImpl.h"
#include "openmm/internal/NonbondedForceImpl.h"
#include "OpenCLBondedUtilities.h"
...
...
@@ -3196,6 +3197,298 @@ double OpenCLCalcCustomHbondForceKernel::execute(ContextImpl& context, bool incl
return
0.0
;
}
class
OpenCLCustomCompoundBondForceInfo
:
public
OpenCLForceInfo
{
public:
OpenCLCustomCompoundBondForceInfo
(
const
CustomCompoundBondForce
&
force
)
:
OpenCLForceInfo
(
1
),
force
(
force
)
{
}
int
getNumParticleGroups
()
{
return
force
.
getNumBonds
();
}
void
getParticlesInGroup
(
int
index
,
vector
<
int
>&
particles
)
{
vector
<
double
>
parameters
;
force
.
getBondParameters
(
index
,
particles
,
parameters
);
}
bool
areGroupsIdentical
(
int
group1
,
int
group2
)
{
vector
<
int
>
particles
;
vector
<
double
>
parameters1
,
parameters2
;
force
.
getBondParameters
(
group1
,
particles
,
parameters1
);
force
.
getBondParameters
(
group2
,
particles
,
parameters2
);
for
(
int
i
=
0
;
i
<
(
int
)
parameters1
.
size
();
i
++
)
if
(
parameters1
[
i
]
!=
parameters2
[
i
])
return
false
;
return
true
;
}
private:
const
CustomCompoundBondForce
&
force
;
};
OpenCLCalcCustomCompoundBondForceKernel
::~
OpenCLCalcCustomCompoundBondForceKernel
()
{
if
(
params
!=
NULL
)
delete
params
;
if
(
globals
!=
NULL
)
delete
globals
;
if
(
tabulatedFunctionParams
!=
NULL
)
delete
tabulatedFunctionParams
;
for
(
int
i
=
0
;
i
<
(
int
)
tabulatedFunctions
.
size
();
i
++
)
delete
tabulatedFunctions
[
i
];
}
void
OpenCLCalcCustomCompoundBondForceKernel
::
initialize
(
const
System
&
system
,
const
CustomCompoundBondForce
&
force
)
{
int
numContexts
=
cl
.
getPlatformData
().
contexts
.
size
();
int
startIndex
=
cl
.
getContextIndex
()
*
force
.
getNumBonds
()
/
numContexts
;
int
endIndex
=
(
cl
.
getContextIndex
()
+
1
)
*
force
.
getNumBonds
()
/
numContexts
;
numBonds
=
endIndex
-
startIndex
;
if
(
numBonds
==
0
)
return
;
int
particlesPerBond
=
force
.
getNumParticlesPerBond
();
vector
<
vector
<
int
>
>
atoms
(
numBonds
,
vector
<
int
>
(
particlesPerBond
));
params
=
new
OpenCLParameterSet
(
cl
,
force
.
getNumPerBondParameters
(),
numBonds
,
"customCompoundBondParams"
);
vector
<
vector
<
cl_float
>
>
paramVector
(
numBonds
);
for
(
int
i
=
0
;
i
<
numBonds
;
i
++
)
{
vector
<
double
>
parameters
;
force
.
getBondParameters
(
startIndex
+
i
,
atoms
[
i
],
parameters
);
paramVector
[
i
].
resize
(
parameters
.
size
());
for
(
int
j
=
0
;
j
<
(
int
)
parameters
.
size
();
j
++
)
paramVector
[
i
][
j
]
=
(
cl_float
)
parameters
[
j
];
}
params
->
setParameterValues
(
paramVector
);
cl
.
addForce
(
new
OpenCLCustomCompoundBondForceInfo
(
force
));
// Record the tabulated functions.
OpenCLExpressionUtilities
::
FunctionPlaceholder
fp
;
map
<
string
,
Lepton
::
CustomFunction
*>
functions
;
vector
<
pair
<
string
,
string
>
>
functionDefinitions
;
vector
<
mm_float4
>
tabulatedFunctionParamsVec
(
force
.
getNumFunctions
());
stringstream
tableArgs
;
for
(
int
i
=
0
;
i
<
force
.
getNumFunctions
();
i
++
)
{
string
name
;
vector
<
double
>
values
;
double
min
,
max
;
force
.
getFunctionParameters
(
i
,
name
,
values
,
min
,
max
);
functions
[
name
]
=
&
fp
;
tabulatedFunctionParamsVec
[
i
]
=
mm_float4
((
float
)
min
,
(
float
)
max
,
(
float
)
((
values
.
size
()
-
1
)
/
(
max
-
min
)),
(
float
)
values
.
size
()
-
2
);
vector
<
mm_float4
>
f
=
OpenCLExpressionUtilities
::
computeFunctionCoefficients
(
values
,
min
,
max
);
OpenCLArray
<
mm_float4
>*
array
=
new
OpenCLArray
<
mm_float4
>
(
cl
,
values
.
size
()
-
1
,
"TabulatedFunction"
);
tabulatedFunctions
.
push_back
(
array
);
array
->
upload
(
f
);
string
arrayName
=
cl
.
getBondedUtilities
().
addArgument
(
array
->
getDeviceBuffer
(),
"float4"
);
functionDefinitions
.
push_back
(
make_pair
(
name
,
arrayName
));
}
string
functionParamsName
;
if
(
force
.
getNumFunctions
()
>
0
)
{
tabulatedFunctionParams
=
new
OpenCLArray
<
mm_float4
>
(
cl
,
tabulatedFunctionParamsVec
.
size
(),
"tabulatedFunctionParameters"
,
false
,
CL_MEM_READ_ONLY
);
tabulatedFunctionParams
->
upload
(
tabulatedFunctionParamsVec
);
functionParamsName
=
cl
.
getBondedUtilities
().
addArgument
(
tabulatedFunctionParams
->
getDeviceBuffer
(),
"float4"
);
}
// Record information about parameters.
globalParamNames
.
resize
(
force
.
getNumGlobalParameters
());
globalParamValues
.
resize
(
force
.
getNumGlobalParameters
());
for
(
int
i
=
0
;
i
<
force
.
getNumGlobalParameters
();
i
++
)
{
globalParamNames
[
i
]
=
force
.
getGlobalParameterName
(
i
);
globalParamValues
[
i
]
=
(
cl_float
)
force
.
getGlobalParameterDefaultValue
(
i
);
}
map
<
string
,
string
>
variables
;
for
(
int
i
=
0
;
i
<
particlesPerBond
;
i
++
)
{
string
index
=
intToString
(
i
+
1
);
variables
[
"x"
+
index
]
=
"pos"
+
index
+
".x"
;
variables
[
"y"
+
index
]
=
"pos"
+
index
+
".y"
;
variables
[
"z"
+
index
]
=
"pos"
+
index
+
".z"
;
}
for
(
int
i
=
0
;
i
<
force
.
getNumPerBondParameters
();
i
++
)
{
const
string
&
name
=
force
.
getPerBondParameterName
(
i
);
variables
[
name
]
=
"bondParams"
+
params
->
getParameterSuffix
(
i
);
}
if
(
force
.
getNumGlobalParameters
()
>
0
)
{
globals
=
new
OpenCLArray
<
cl_float
>
(
cl
,
force
.
getNumGlobalParameters
(),
"customCompoundBondGlobals"
,
false
,
CL_MEM_READ_ONLY
);
globals
->
upload
(
globalParamValues
);
string
argName
=
cl
.
getBondedUtilities
().
addArgument
(
globals
->
getDeviceBuffer
(),
"float"
);
for
(
int
i
=
0
;
i
<
force
.
getNumGlobalParameters
();
i
++
)
{
const
string
&
name
=
force
.
getGlobalParameterName
(
i
);
string
value
=
argName
+
"["
+
intToString
(
i
)
+
"]"
;
variables
[
name
]
=
value
;
}
}
// Now to generate the kernel. First, it needs to calculate all distances, angles,
// and dihedrals the expression depends on.
map
<
string
,
vector
<
int
>
>
distances
;
map
<
string
,
vector
<
int
>
>
angles
;
map
<
string
,
vector
<
int
>
>
dihedrals
;
Lepton
::
ParsedExpression
energyExpression
=
CustomCompoundBondForceImpl
::
prepareExpression
(
force
,
functions
,
distances
,
angles
,
dihedrals
);
map
<
string
,
Lepton
::
ParsedExpression
>
forceExpressions
;
set
<
string
>
computedDeltas
;
vector
<
string
>
atomNames
,
posNames
;
for
(
int
i
=
0
;
i
<
particlesPerBond
;
i
++
)
{
string
index
=
intToString
(
i
+
1
);
atomNames
.
push_back
(
"P"
+
index
);
posNames
.
push_back
(
"pos"
+
index
);
}
stringstream
compute
;
int
index
=
0
;
for
(
map
<
string
,
vector
<
int
>
>::
const_iterator
iter
=
distances
.
begin
();
iter
!=
distances
.
end
();
++
iter
,
++
index
)
{
const
vector
<
int
>&
atoms
=
iter
->
second
;
string
deltaName
=
atomNames
[
atoms
[
0
]]
+
atomNames
[
atoms
[
1
]];
if
(
computedDeltas
.
count
(
deltaName
)
==
0
)
{
compute
<<
"float4 delta"
<<
deltaName
<<
" = ccb_delta("
<<
posNames
[
atoms
[
0
]]
<<
", "
<<
posNames
[
atoms
[
1
]]
<<
");
\n
"
;
computedDeltas
.
insert
(
deltaName
);
}
compute
<<
"float r_"
<<
deltaName
<<
" = sqrt(delta"
<<
deltaName
<<
".w);
\n
"
;
variables
[
iter
->
first
]
=
"r_"
+
deltaName
;
forceExpressions
[
"float dEdDistance"
+
intToString
(
index
)
+
" = "
]
=
energyExpression
.
differentiate
(
iter
->
first
).
optimize
();
}
index
=
0
;
for
(
map
<
string
,
vector
<
int
>
>::
const_iterator
iter
=
angles
.
begin
();
iter
!=
angles
.
end
();
++
iter
,
++
index
)
{
const
vector
<
int
>&
atoms
=
iter
->
second
;
string
deltaName1
=
atomNames
[
atoms
[
1
]]
+
atomNames
[
atoms
[
0
]];
string
deltaName2
=
atomNames
[
atoms
[
1
]]
+
atomNames
[
atoms
[
2
]];
string
angleName
=
"angle_"
+
atomNames
[
atoms
[
0
]]
+
atomNames
[
atoms
[
1
]]
+
atomNames
[
atoms
[
2
]];
if
(
computedDeltas
.
count
(
deltaName1
)
==
0
)
{
compute
<<
"float4 delta"
<<
deltaName1
<<
" = ccb_delta("
<<
posNames
[
atoms
[
1
]]
<<
", "
<<
posNames
[
atoms
[
0
]]
<<
");
\n
"
;
computedDeltas
.
insert
(
deltaName1
);
}
if
(
computedDeltas
.
count
(
deltaName2
)
==
0
)
{
compute
<<
"float4 delta"
<<
deltaName2
<<
" = ccb_delta("
<<
posNames
[
atoms
[
1
]]
<<
", "
<<
posNames
[
atoms
[
2
]]
<<
");
\n
"
;
computedDeltas
.
insert
(
deltaName2
);
}
compute
<<
"float "
<<
angleName
<<
" = ccb_computeAngle(delta"
<<
deltaName1
<<
", delta"
<<
deltaName2
<<
");
\n
"
;
variables
[
iter
->
first
]
=
angleName
;
forceExpressions
[
"float dEdAngle"
+
intToString
(
index
)
+
" = "
]
=
energyExpression
.
differentiate
(
iter
->
first
).
optimize
();
}
index
=
0
;
for
(
map
<
string
,
vector
<
int
>
>::
const_iterator
iter
=
dihedrals
.
begin
();
iter
!=
dihedrals
.
end
();
++
iter
,
++
index
)
{
const
vector
<
int
>&
atoms
=
iter
->
second
;
string
deltaName1
=
atomNames
[
atoms
[
0
]]
+
atomNames
[
atoms
[
1
]];
string
deltaName2
=
atomNames
[
atoms
[
2
]]
+
atomNames
[
atoms
[
1
]];
string
deltaName3
=
atomNames
[
atoms
[
2
]]
+
atomNames
[
atoms
[
3
]];
string
crossName1
=
"cross_"
+
deltaName1
+
"_"
+
deltaName2
;
string
crossName2
=
"cross_"
+
deltaName2
+
"_"
+
deltaName3
;
string
dihedralName
=
"dihedral_"
+
atomNames
[
atoms
[
0
]]
+
atomNames
[
atoms
[
1
]]
+
atomNames
[
atoms
[
2
]]
+
atomNames
[
atoms
[
3
]];
if
(
computedDeltas
.
count
(
deltaName1
)
==
0
)
{
compute
<<
"float4 delta"
<<
deltaName1
<<
" = ccb_delta("
<<
posNames
[
atoms
[
0
]]
<<
", "
<<
posNames
[
atoms
[
1
]]
<<
");
\n
"
;
computedDeltas
.
insert
(
deltaName1
);
}
if
(
computedDeltas
.
count
(
deltaName2
)
==
0
)
{
compute
<<
"float4 delta"
<<
deltaName2
<<
" = ccb_delta("
<<
posNames
[
atoms
[
2
]]
<<
", "
<<
posNames
[
atoms
[
1
]]
<<
");
\n
"
;
computedDeltas
.
insert
(
deltaName2
);
}
if
(
computedDeltas
.
count
(
deltaName3
)
==
0
)
{
compute
<<
"float4 delta"
<<
deltaName3
<<
" = ccb_delta("
<<
posNames
[
atoms
[
2
]]
<<
", "
<<
posNames
[
atoms
[
3
]]
<<
");
\n
"
;
computedDeltas
.
insert
(
deltaName3
);
}
compute
<<
"float4 "
<<
crossName1
<<
" = ccb_computeCross(delta"
<<
deltaName1
<<
", delta"
<<
deltaName2
<<
");
\n
"
;
compute
<<
"float4 "
<<
crossName2
<<
" = ccb_computeCross(delta"
<<
deltaName2
<<
", delta"
<<
deltaName3
<<
");
\n
"
;
compute
<<
"float "
<<
dihedralName
<<
" = ccb_computeAngle("
<<
crossName1
<<
", "
<<
crossName2
<<
");
\n
"
;
compute
<<
dihedralName
<<
" *= (delta"
<<
deltaName1
<<
".x*"
<<
crossName2
<<
".x + delta"
<<
deltaName1
<<
".y*"
<<
crossName2
<<
".y + delta"
<<
deltaName1
<<
".z*"
<<
crossName2
<<
".z < 0 ? -1 : 1);
\n
"
;
variables
[
iter
->
first
]
=
dihedralName
;
forceExpressions
[
"float dEdDihedral"
+
intToString
(
index
)
+
" = "
]
=
energyExpression
.
differentiate
(
iter
->
first
).
optimize
();
}
// Now evaluate the expressions.
for
(
int
i
=
0
;
i
<
(
int
)
params
->
getBuffers
().
size
();
i
++
)
{
const
OpenCLNonbondedUtilities
::
ParameterInfo
&
buffer
=
params
->
getBuffers
()[
i
];
string
argName
=
cl
.
getBondedUtilities
().
addArgument
(
buffer
.
getMemory
(),
buffer
.
getType
());
compute
<<
buffer
.
getType
()
<<
" bondParams"
<<
(
i
+
1
)
<<
" = "
<<
argName
<<
"[index];
\n
"
;
}
forceExpressions
[
"energy += "
]
=
energyExpression
;
compute
<<
OpenCLExpressionUtilities
::
createExpressions
(
forceExpressions
,
variables
,
functionDefinitions
,
"temp"
,
functionParamsName
);
// Finally, apply forces to atoms.
vector
<
string
>
forceNames
;
for
(
int
i
=
0
;
i
<
particlesPerBond
;
i
++
)
{
string
istr
=
intToString
(
i
+
1
);
string
forceName
=
"force"
+
istr
;
forceNames
.
push_back
(
forceName
);
compute
<<
"float4 "
<<
forceName
<<
" = (float4) (0.0f, 0.0f, 0.0f, 0.0f);
\n
"
;
compute
<<
"{
\n
"
;
Lepton
::
ParsedExpression
forceExpressionX
=
energyExpression
.
differentiate
(
"x"
+
istr
).
optimize
();
Lepton
::
ParsedExpression
forceExpressionY
=
energyExpression
.
differentiate
(
"y"
+
istr
).
optimize
();
Lepton
::
ParsedExpression
forceExpressionZ
=
energyExpression
.
differentiate
(
"z"
+
istr
).
optimize
();
map
<
string
,
Lepton
::
ParsedExpression
>
expressions
;
if
(
!
isZeroExpression
(
forceExpressionX
))
expressions
[
forceName
+
".x -= "
]
=
forceExpressionX
;
if
(
!
isZeroExpression
(
forceExpressionY
))
expressions
[
forceName
+
".y -= "
]
=
forceExpressionY
;
if
(
!
isZeroExpression
(
forceExpressionZ
))
expressions
[
forceName
+
".z -= "
]
=
forceExpressionZ
;
if
(
expressions
.
size
()
>
0
)
compute
<<
OpenCLExpressionUtilities
::
createExpressions
(
expressions
,
variables
,
functionDefinitions
,
"coordtemp"
,
functionParamsName
);
compute
<<
"}
\n
"
;
}
index
=
0
;
for
(
map
<
string
,
vector
<
int
>
>::
const_iterator
iter
=
distances
.
begin
();
iter
!=
distances
.
end
();
++
iter
,
++
index
)
{
const
vector
<
int
>&
atoms
=
iter
->
second
;
string
deltaName
=
atomNames
[
atoms
[
0
]]
+
atomNames
[
atoms
[
1
]];
string
value
=
"(dEdDistance"
+
intToString
(
index
)
+
"/r_"
+
deltaName
+
")*delta"
+
deltaName
+
".xyz"
;
compute
<<
forceNames
[
atoms
[
0
]]
<<
".xyz += "
<<
"-"
<<
value
<<
";
\n
"
;
compute
<<
forceNames
[
atoms
[
1
]]
<<
".xyz += "
<<
value
<<
";
\n
"
;
}
index
=
0
;
for
(
map
<
string
,
vector
<
int
>
>::
const_iterator
iter
=
angles
.
begin
();
iter
!=
angles
.
end
();
++
iter
,
++
index
)
{
const
vector
<
int
>&
atoms
=
iter
->
second
;
string
deltaName1
=
atomNames
[
atoms
[
1
]]
+
atomNames
[
atoms
[
0
]];
string
deltaName2
=
atomNames
[
atoms
[
1
]]
+
atomNames
[
atoms
[
2
]];
compute
<<
"{
\n
"
;
compute
<<
"float4 crossProd = cross(delta"
<<
deltaName2
<<
", delta"
<<
deltaName1
<<
");
\n
"
;
compute
<<
"float lengthCross = max(length(crossProd), 1e-6f);
\n
"
;
compute
<<
"float4 deltaCross0 = -cross(delta"
<<
deltaName1
<<
", crossProd)*dEdAngle"
<<
intToString
(
index
)
<<
"/(delta"
<<
deltaName1
<<
".w*lengthCross);
\n
"
;
compute
<<
"float4 deltaCross2 = cross(delta"
<<
deltaName2
<<
", crossProd)*dEdAngle"
<<
intToString
(
index
)
<<
"/(delta"
<<
deltaName2
<<
".w*lengthCross);
\n
"
;
compute
<<
"float4 deltaCross1 = -(deltaCross0+deltaCross2);
\n
"
;
compute
<<
forceNames
[
atoms
[
0
]]
<<
".xyz += deltaCross0.xyz;
\n
"
;
compute
<<
forceNames
[
atoms
[
1
]]
<<
".xyz += deltaCross1.xyz;
\n
"
;
compute
<<
forceNames
[
atoms
[
2
]]
<<
".xyz += deltaCross2.xyz;
\n
"
;
compute
<<
"}
\n
"
;
}
index
=
0
;
for
(
map
<
string
,
vector
<
int
>
>::
const_iterator
iter
=
dihedrals
.
begin
();
iter
!=
dihedrals
.
end
();
++
iter
,
++
index
)
{
const
vector
<
int
>&
atoms
=
iter
->
second
;
string
deltaName1
=
atomNames
[
atoms
[
0
]]
+
atomNames
[
atoms
[
1
]];
string
deltaName2
=
atomNames
[
atoms
[
2
]]
+
atomNames
[
atoms
[
1
]];
string
deltaName3
=
atomNames
[
atoms
[
2
]]
+
atomNames
[
atoms
[
3
]];
string
crossName1
=
"cross_"
+
deltaName1
+
"_"
+
deltaName2
;
string
crossName2
=
"cross_"
+
deltaName2
+
"_"
+
deltaName3
;
compute
<<
"{
\n
"
;
compute
<<
"float r = sqrt(delta"
<<
deltaName2
<<
".w);
\n
"
;
compute
<<
"float4 ff;
\n
"
;
compute
<<
"ff.x = (-dEdDihedral"
<<
intToString
(
index
)
<<
"*r)/"
<<
crossName1
<<
".w;
\n
"
;
compute
<<
"ff.y = (delta"
<<
deltaName1
<<
".x*delta"
<<
deltaName2
<<
".x + delta"
<<
deltaName1
<<
".y*delta"
<<
deltaName2
<<
".y + delta"
<<
deltaName1
<<
".z*delta"
<<
deltaName2
<<
".z)/delta"
<<
deltaName2
<<
".w;
\n
"
;
compute
<<
"ff.z = (delta"
<<
deltaName3
<<
".x*delta"
<<
deltaName2
<<
".x + delta"
<<
deltaName3
<<
".y*delta"
<<
deltaName2
<<
".y + delta"
<<
deltaName3
<<
".z*delta"
<<
deltaName2
<<
".z)/delta"
<<
deltaName2
<<
".w;
\n
"
;
compute
<<
"ff.w = (dEdDihedral"
<<
intToString
(
index
)
<<
"*r)/"
<<
crossName2
<<
".w;
\n
"
;
compute
<<
"float4 internalF0 = ff.x*"
<<
crossName1
<<
";
\n
"
;
compute
<<
"float4 internalF3 = ff.w*"
<<
crossName2
<<
";
\n
"
;
compute
<<
"float4 s = ff.y*internalF0 - ff.z*internalF3;
\n
"
;
compute
<<
forceNames
[
atoms
[
0
]]
<<
".xyz += internalF0.xyz;
\n
"
;
compute
<<
forceNames
[
atoms
[
1
]]
<<
".xyz += s.xyz-internalF0.xyz;
\n
"
;
compute
<<
forceNames
[
atoms
[
2
]]
<<
".xyz += -s.xyz-internalF3.xyz;
\n
"
;
compute
<<
forceNames
[
atoms
[
3
]]
<<
".xyz += internalF3.xyz;
\n
"
;
compute
<<
"}
\n
"
;
}
cl
.
getBondedUtilities
().
addInteraction
(
atoms
,
compute
.
str
(),
force
.
getForceGroup
());
map
<
string
,
string
>
replacements
;
replacements
[
"M_PI"
]
=
doubleToString
(
M_PI
);
cl
.
getBondedUtilities
().
addPrefixCode
(
cl
.
replaceStrings
(
OpenCLKernelSources
::
customCompoundBond
,
replacements
));;
}
double
OpenCLCalcCustomCompoundBondForceKernel
::
execute
(
ContextImpl
&
context
,
bool
includeForces
,
bool
includeEnergy
)
{
if
(
globals
!=
NULL
)
{
bool
changed
=
false
;
for
(
int
i
=
0
;
i
<
(
int
)
globalParamNames
.
size
();
i
++
)
{
cl_float
value
=
(
cl_float
)
context
.
getParameter
(
globalParamNames
[
i
]);
if
(
value
!=
globalParamValues
[
i
])
changed
=
true
;
globalParamValues
[
i
]
=
value
;
}
if
(
changed
)
globals
->
upload
(
globalParamValues
);
}
return
0.0
;
}
OpenCLIntegrateVerletStepKernel
::~
OpenCLIntegrateVerletStepKernel
()
{
}
...
...
platforms/opencl/src/OpenCLKernels.h
View file @
0e6cbcea
...
...
@@ -762,6 +762,43 @@ private:
cl
::
Kernel
donorKernel
,
acceptorKernel
;
};
/**
* This kernel is invoked by CustomCompoundBondForce to calculate the forces acting on the system.
*/
class
OpenCLCalcCustomCompoundBondForceKernel
:
public
CalcCustomCompoundBondForceKernel
{
public:
OpenCLCalcCustomCompoundBondForceKernel
(
std
::
string
name
,
const
Platform
&
platform
,
OpenCLContext
&
cl
,
System
&
system
)
:
CalcCustomCompoundBondForceKernel
(
name
,
platform
),
cl
(
cl
),
params
(
NULL
),
globals
(
NULL
),
tabulatedFunctionParams
(
NULL
),
system
(
system
)
{
}
~
OpenCLCalcCustomCompoundBondForceKernel
();
/**
* Initialize the kernel.
*
* @param system the System this kernel will be applied to
* @param force the CustomCompoundBondForce this kernel will be used for
*/
void
initialize
(
const
System
&
system
,
const
CustomCompoundBondForce
&
force
);
/**
* Execute the kernel to calculate the forces and/or energy.
*
* @param context the context in which to execute this kernel
* @param includeForces true if forces should be calculated
* @param includeEnergy true if the energy should be calculated
* @return the potential energy due to the force
*/
double
execute
(
ContextImpl
&
context
,
bool
includeForces
,
bool
includeEnergy
);
private:
int
numBonds
;
OpenCLContext
&
cl
;
OpenCLParameterSet
*
params
;
OpenCLArray
<
cl_float
>*
globals
;
OpenCLArray
<
mm_float4
>*
tabulatedFunctionParams
;
std
::
vector
<
std
::
string
>
globalParamNames
;
std
::
vector
<
cl_float
>
globalParamValues
;
std
::
vector
<
OpenCLArray
<
mm_float4
>*>
tabulatedFunctions
;
System
&
system
;
};
/**
* This kernel is invoked by VerletIntegrator to take one time step.
*/
...
...
platforms/opencl/src/OpenCLParallelKernels.cpp
View file @
0e6cbcea
...
...
@@ -629,3 +629,39 @@ double OpenCLParallelCalcCustomHbondForceKernel::execute(ContextImpl& context, b
}
return
0.0
;
}
class
OpenCLParallelCalcCustomCompoundBondForceKernel
::
Task
:
public
OpenCLContext
::
WorkTask
{
public:
Task
(
ContextImpl
&
context
,
OpenCLCalcCustomCompoundBondForceKernel
&
kernel
,
bool
includeForce
,
bool
includeEnergy
,
double
&
energy
)
:
context
(
context
),
kernel
(
kernel
),
includeForce
(
includeForce
),
includeEnergy
(
includeEnergy
),
energy
(
energy
)
{
}
void
execute
()
{
energy
+=
kernel
.
execute
(
context
,
includeForce
,
includeEnergy
);
}
private:
ContextImpl
&
context
;
OpenCLCalcCustomCompoundBondForceKernel
&
kernel
;
bool
includeForce
,
includeEnergy
;
double
&
energy
;
};
OpenCLParallelCalcCustomCompoundBondForceKernel
::
OpenCLParallelCalcCustomCompoundBondForceKernel
(
std
::
string
name
,
const
Platform
&
platform
,
OpenCLPlatform
::
PlatformData
&
data
,
System
&
system
)
:
CalcCustomCompoundBondForceKernel
(
name
,
platform
),
data
(
data
)
{
for
(
int
i
=
0
;
i
<
(
int
)
data
.
contexts
.
size
();
i
++
)
kernels
.
push_back
(
Kernel
(
new
OpenCLCalcCustomCompoundBondForceKernel
(
name
,
platform
,
*
data
.
contexts
[
i
],
system
)));
}
void
OpenCLParallelCalcCustomCompoundBondForceKernel
::
initialize
(
const
System
&
system
,
const
CustomCompoundBondForce
&
force
)
{
for
(
int
i
=
0
;
i
<
(
int
)
kernels
.
size
();
i
++
)
getKernel
(
i
).
initialize
(
system
,
force
);
}
double
OpenCLParallelCalcCustomCompoundBondForceKernel
::
execute
(
ContextImpl
&
context
,
bool
includeForces
,
bool
includeEnergy
)
{
for
(
int
i
=
0
;
i
<
(
int
)
data
.
contexts
.
size
();
i
++
)
{
OpenCLContext
&
cl
=
*
data
.
contexts
[
i
];
OpenCLContext
::
WorkThread
&
thread
=
cl
.
getWorkThread
();
thread
.
addTask
(
new
Task
(
context
,
getKernel
(
i
),
includeForces
,
includeEnergy
,
data
.
contextEnergy
[
i
]));
}
return
0.0
;
}
platforms/opencl/src/OpenCLParallelKernels.h
View file @
0e6cbcea
...
...
@@ -462,6 +462,37 @@ private:
std
::
vector
<
Kernel
>
kernels
;
};
/**
* This kernel is invoked by CustomCompoundBondForce to calculate the forces acting on the system.
*/
class
OpenCLParallelCalcCustomCompoundBondForceKernel
:
public
CalcCustomCompoundBondForceKernel
{
public:
OpenCLParallelCalcCustomCompoundBondForceKernel
(
std
::
string
name
,
const
Platform
&
platform
,
OpenCLPlatform
::
PlatformData
&
data
,
System
&
system
);
OpenCLCalcCustomCompoundBondForceKernel
&
getKernel
(
int
index
)
{
return
dynamic_cast
<
OpenCLCalcCustomCompoundBondForceKernel
&>
(
kernels
[
index
].
getImpl
());
}
/**
* Initialize the kernel.
*
* @param system the System this kernel will be applied to
* @param force the CustomCompoundBondForce this kernel will be used for
*/
void
initialize
(
const
System
&
system
,
const
CustomCompoundBondForce
&
force
);
/**
* Execute the kernel to calculate the forces and/or energy.
*
* @param context the context in which to execute this kernel
* @param includeForces true if forces should be calculated
* @param includeEnergy true if the energy should be calculated
* @return the potential energy due to the force
*/
double
execute
(
ContextImpl
&
context
,
bool
includeForces
,
bool
includeEnergy
);
private:
class
Task
;
OpenCLPlatform
::
PlatformData
&
data
;
std
::
vector
<
Kernel
>
kernels
;
};
}
// namespace OpenMM
#endif
/*OPENMM_OPENCLPARALLELKERNELS_H_*/
platforms/opencl/src/OpenCLPlatform.cpp
View file @
0e6cbcea
...
...
@@ -63,6 +63,7 @@ OpenCLPlatform::OpenCLPlatform() {
registerKernelFactory
(
CalcCustomGBForceKernel
::
Name
(),
factory
);
registerKernelFactory
(
CalcCustomExternalForceKernel
::
Name
(),
factory
);
registerKernelFactory
(
CalcCustomHbondForceKernel
::
Name
(),
factory
);
registerKernelFactory
(
CalcCustomCompoundBondForceKernel
::
Name
(),
factory
);
registerKernelFactory
(
IntegrateVerletStepKernel
::
Name
(),
factory
);
registerKernelFactory
(
IntegrateLangevinStepKernel
::
Name
(),
factory
);
registerKernelFactory
(
IntegrateBrownianStepKernel
::
Name
(),
factory
);
...
...
platforms/opencl/src/kernels/customCompoundBond.cl
0 → 100644
View file @
0e6cbcea
/**
*
Compute
the
difference
between
two
vectors,
setting
the
fourth
component
to
the
squared
magnitude.
*/
float4
ccb_delta
(
float4
vec1,
float4
vec2
)
{
float4
result
=
(
float4
)
(
vec1.x-vec2.x,
vec1.y-vec2.y,
vec1.z-vec2.z,
0.0f
)
;
result.w
=
result.x*result.x
+
result.y*result.y
+
result.z*result.z
;
return
result
;
}
/**
*
Compute
the
angle
between
two
vectors.
The
w
component
of
each
vector
should
contain
the
squared
magnitude.
*/
float
ccb_computeAngle
(
float4
vec1,
float4
vec2
)
{
float
dotProduct
=
vec1.x*vec2.x
+
vec1.y*vec2.y
+
vec1.z*vec2.z
;
float
cosine
=
dotProduct*RSQRT
(
vec1.w*vec2.w
)
;
float
angle
;
if
(
cosine
>
0.99f
||
cosine
<
-0.99f
)
{
//
We
're
close
to
the
singularity
in
acos
()
,
so
take
the
cross
product
and
use
asin
()
instead.
float4
crossProduct
=
cross
(
vec1,
vec2
)
;
float
scale
=
vec1.w*vec2.w
;
angle
=
asin
(
SQRT
(
dot
(
crossProduct,
crossProduct
)
/scale
))
;
if
(
cosine
<
0.0f
)
angle
=
M_PI-angle
;
}
else
angle
=
acos
(
cosine
)
;
return
angle
;
}
/**
*
Compute
the
cross
product
of
two
vectors,
setting
the
fourth
component
to
the
squared
magnitude.
*/
float4
ccb_computeCross
(
float4
vec1,
float4
vec2
)
{
float4
result
=
cross
(
vec1,
vec2
)
;
result.w
=
result.x*result.x
+
result.y*result.y
+
result.z*result.z
;
return
result
;
}
platforms/opencl/tests/TestOpenCLCustomCompoundBondForce.cpp
0 → 100644
View file @
0e6cbcea
/* -------------------------------------------------------------------------- *
* 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) 2012 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 CustomCompoundBondForce.
*/
#include "openmm/internal/AssertionUtilities.h"
#include "openmm/Context.h"
#include "OpenCLPlatform.h"
#include "openmm/CustomCompoundBondForce.h"
#include "openmm/HarmonicAngleForce.h"
#include "openmm/HarmonicBondForce.h"
#include "openmm/PeriodicTorsionForce.h"
#include "openmm/System.h"
#include "openmm/VerletIntegrator.h"
#include "sfmt/SFMT.h"
#include <iostream>
#include <vector>
using
namespace
OpenMM
;
using
namespace
std
;
const
double
TOL
=
1e-5
;
void
testBond
()
{
OpenCLPlatform
platform
;
// Create a system using a CustomCompoundBondForce.
System
customSystem
;
customSystem
.
addParticle
(
1.0
);
customSystem
.
addParticle
(
1.0
);
customSystem
.
addParticle
(
1.0
);
customSystem
.
addParticle
(
1.0
);
CustomCompoundBondForce
*
custom
=
new
CustomCompoundBondForce
(
4
,
"0.5*kb*((distance(p1,p2)-b0)^2+(distance(p2,p3)-b0)^2)+0.5*ka*(angle(p2,p3,p4)-a0)^2+kt*(1+cos(dihedral(p1,p2,p3,p4)-t0))"
);
custom
->
addPerBondParameter
(
"kb"
);
custom
->
addPerBondParameter
(
"ka"
);
custom
->
addPerBondParameter
(
"kt"
);
custom
->
addPerBondParameter
(
"b0"
);
custom
->
addPerBondParameter
(
"a0"
);
custom
->
addPerBondParameter
(
"t0"
);
vector
<
int
>
particles
(
4
);
particles
[
0
]
=
0
;
particles
[
1
]
=
1
;
particles
[
2
]
=
3
;
particles
[
3
]
=
2
;
vector
<
double
>
parameters
(
6
);
parameters
[
0
]
=
1.5
;
parameters
[
1
]
=
0.8
;
parameters
[
2
]
=
0.6
;
parameters
[
3
]
=
1.1
;
parameters
[
4
]
=
2.9
;
parameters
[
5
]
=
1.3
;
custom
->
addBond
(
particles
,
parameters
);
customSystem
.
addForce
(
custom
);
// Create an identical system using standard forces.
System
standardSystem
;
standardSystem
.
addParticle
(
1.0
);
standardSystem
.
addParticle
(
1.0
);
standardSystem
.
addParticle
(
1.0
);
standardSystem
.
addParticle
(
1.0
);
HarmonicBondForce
*
bonds
=
new
HarmonicBondForce
();
bonds
->
addBond
(
0
,
1
,
1.1
,
1.5
);
bonds
->
addBond
(
1
,
3
,
1.1
,
1.5
);
standardSystem
.
addForce
(
bonds
);
HarmonicAngleForce
*
angles
=
new
HarmonicAngleForce
();
angles
->
addAngle
(
1
,
3
,
2
,
2.9
,
0.8
);
standardSystem
.
addForce
(
angles
);
PeriodicTorsionForce
*
torsions
=
new
PeriodicTorsionForce
();
torsions
->
addTorsion
(
0
,
1
,
3
,
2
,
1
,
1.3
,
0.6
);
standardSystem
.
addForce
(
torsions
);
// Set the atoms in various positions, and verify that both systems give identical forces and energy.
OpenMM_SFMT
::
SFMT
sfmt
;
init_gen_rand
(
0
,
sfmt
);
VerletIntegrator
integrator1
(
0.01
);
VerletIntegrator
integrator2
(
0.01
);
Context
c1
(
customSystem
,
integrator1
,
platform
);
Context
c2
(
standardSystem
,
integrator2
,
platform
);
vector
<
Vec3
>
positions
(
4
);
for
(
int
i
=
0
;
i
<
10
;
i
++
)
{
for
(
int
j
=
0
;
j
<
(
int
)
positions
.
size
();
j
++
)
positions
[
j
]
=
Vec3
(
5.0
*
genrand_real2
(
sfmt
),
5.0
*
genrand_real2
(
sfmt
),
5.0
*
genrand_real2
(
sfmt
));
c1
.
setPositions
(
positions
);
c2
.
setPositions
(
positions
);
State
s1
=
c1
.
getState
(
State
::
Forces
|
State
::
Energy
);
State
s2
=
c2
.
getState
(
State
::
Forces
|
State
::
Energy
);
for
(
int
i
=
0
;
i
<
customSystem
.
getNumParticles
();
i
++
)
ASSERT_EQUAL_VEC
(
s1
.
getForces
()[
i
],
s2
.
getForces
()[
i
],
TOL
);
ASSERT_EQUAL_TOL
(
s1
.
getPotentialEnergy
(),
s2
.
getPotentialEnergy
(),
TOL
);
}
}
void
testPositionDependence
()
{
OpenCLPlatform
platform
;
System
customSystem
;
customSystem
.
addParticle
(
1.0
);
customSystem
.
addParticle
(
1.0
);
CustomCompoundBondForce
*
custom
=
new
CustomCompoundBondForce
(
2
,
"scale1*distance(p1,p2)+scale2*x1+2*y2"
);
custom
->
addGlobalParameter
(
"scale1"
,
0.3
);
custom
->
addGlobalParameter
(
"scale2"
,
0.2
);
vector
<
int
>
particles
(
2
);
particles
[
0
]
=
0
;
particles
[
1
]
=
1
;
vector
<
double
>
parameters
;
custom
->
addBond
(
particles
,
parameters
);
customSystem
.
addForce
(
custom
);
vector
<
Vec3
>
positions
(
2
);
positions
[
0
]
=
Vec3
(
0.5
,
1
,
0
);
positions
[
1
]
=
Vec3
(
1.5
,
1
,
0
);
VerletIntegrator
integrator
(
0.01
);
Context
context
(
customSystem
,
integrator
,
platform
);
context
.
setPositions
(
positions
);
State
state
=
context
.
getState
(
State
::
Forces
|
State
::
Energy
);
ASSERT_EQUAL_TOL
(
0.3
*
1.0
+
0.2
*
0.5
+
2
*
1
,
state
.
getPotentialEnergy
(),
1e-5
);
ASSERT_EQUAL_VEC
(
Vec3
(
0.3
-
0.2
,
0
,
0
),
state
.
getForces
()[
0
],
1e-5
);
ASSERT_EQUAL_VEC
(
Vec3
(
-
0.3
,
-
2
,
0
),
state
.
getForces
()[
1
],
1e-5
);
}
void
testParallelComputation
()
{
OpenCLPlatform
platform
;
System
system
;
const
int
numParticles
=
200
;
for
(
int
i
=
0
;
i
<
numParticles
;
i
++
)
system
.
addParticle
(
1.0
);
CustomCompoundBondForce
*
force
=
new
CustomCompoundBondForce
(
2
,
(
"(distance(p1,p2)-1.1)^2"
));
vector
<
int
>
particles
(
2
);
vector
<
double
>
params
;
for
(
int
i
=
1
;
i
<
numParticles
;
i
++
)
{
particles
[
0
]
=
i
-
1
;
particles
[
1
]
=
i
;
force
->
addBond
(
particles
,
params
);
}
system
.
addForce
(
force
);
vector
<
Vec3
>
positions
(
numParticles
);
for
(
int
i
=
0
;
i
<
numParticles
;
i
++
)
positions
[
i
]
=
Vec3
(
i
,
0
,
0
);
VerletIntegrator
integrator1
(
0.01
);
Context
context1
(
system
,
integrator1
,
platform
);
context1
.
setPositions
(
positions
);
State
state1
=
context1
.
getState
(
State
::
Forces
|
State
::
Energy
);
VerletIntegrator
integrator2
(
0.01
);
string
deviceIndex
=
platform
.
getPropertyValue
(
context1
,
OpenCLPlatform
::
OpenCLDeviceIndex
());
map
<
string
,
string
>
props
;
props
[
OpenCLPlatform
::
OpenCLDeviceIndex
()]
=
deviceIndex
+
","
+
deviceIndex
;
Context
context2
(
system
,
integrator2
,
platform
,
props
);
context2
.
setPositions
(
positions
);
State
state2
=
context2
.
getState
(
State
::
Forces
|
State
::
Energy
);
ASSERT_EQUAL_TOL
(
state1
.
getPotentialEnergy
(),
state2
.
getPotentialEnergy
(),
1e-5
);
for
(
int
i
=
0
;
i
<
numParticles
;
i
++
)
ASSERT_EQUAL_VEC
(
state1
.
getForces
()[
i
],
state2
.
getForces
()[
i
],
1e-5
);
}
int
main
()
{
try
{
testBond
();
testPositionDependence
();
testParallelComputation
();
}
catch
(
const
exception
&
e
)
{
cout
<<
"exception: "
<<
e
.
what
()
<<
endl
;
return
1
;
}
cout
<<
"Done"
<<
endl
;
return
0
;
}
platforms/reference/tests/TestReferenceCustomCompoundBondForce.cpp
View file @
0e6cbcea
...
...
@@ -105,13 +105,12 @@ void testBond() {
OpenMM_SFMT
::
SFMT
sfmt
;
init_gen_rand
(
0
,
sfmt
);
vector
<
Vec3
>
positions
(
4
);
for
(
int
i
=
0
;
i
<
10
;
i
++
)
{
VerletIntegrator
integrator1
(
0.01
);
VerletIntegrator
integrator2
(
0.01
);
Context
c1
(
customSystem
,
integrator1
,
platform
);
Context
c2
(
standardSystem
,
integrator2
,
platform
);
vector
<
Vec3
>
positions
(
4
);
for
(
int
i
=
0
;
i
<
10
;
i
++
)
{
for
(
int
j
=
0
;
j
<
(
int
)
positions
.
size
();
j
++
)
positions
[
j
]
=
Vec3
(
5.0
*
genrand_real2
(
sfmt
),
5.0
*
genrand_real2
(
sfmt
),
5.0
*
genrand_real2
(
sfmt
));
c1
.
setPositions
(
positions
);
...
...
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