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
84d482e2
"wrappers/vscode:/vscode.git/clone" did not exist on "79fd69c367b1c475db43d2a55bb5b399ddcb8de5"
Commit
84d482e2
authored
Oct 30, 2009
by
Peter Eastman
Browse files
Began OpenCL implementation of CustomNonbondedForce
parent
20943acb
Changes
12
Show whitespace changes
Inline
Side-by-side
Showing
12 changed files
with
802 additions
and
159 deletions
+802
-159
platforms/opencl/src/OpenCLArray.h
platforms/opencl/src/OpenCLArray.h
+3
-2
platforms/opencl/src/OpenCLExpressionUtilities.cpp
platforms/opencl/src/OpenCLExpressionUtilities.cpp
+114
-0
platforms/opencl/src/OpenCLExpressionUtilities.h
platforms/opencl/src/OpenCLExpressionUtilities.h
+51
-0
platforms/opencl/src/OpenCLKernelFactory.cpp
platforms/opencl/src/OpenCLKernelFactory.cpp
+2
-2
platforms/opencl/src/OpenCLKernels.cpp
platforms/opencl/src/OpenCLKernels.cpp
+250
-115
platforms/opencl/src/OpenCLKernels.h
platforms/opencl/src/OpenCLKernels.h
+41
-36
platforms/opencl/src/OpenCLNonbondedUtilities.cpp
platforms/opencl/src/OpenCLNonbondedUtilities.cpp
+19
-2
platforms/opencl/src/OpenCLNonbondedUtilities.h
platforms/opencl/src/OpenCLNonbondedUtilities.h
+7
-1
platforms/opencl/src/OpenCLPlatform.cpp
platforms/opencl/src/OpenCLPlatform.cpp
+1
-1
platforms/opencl/src/kernels/customNonbonded.cl
platforms/opencl/src/kernels/customNonbonded.cl
+9
-0
platforms/opencl/src/kernels/customNonbondedExceptions.cl
platforms/opencl/src/kernels/customNonbondedExceptions.cl
+52
-0
platforms/opencl/tests/TestOpenCLCustomNonbondedForce.cpp
platforms/opencl/tests/TestOpenCLCustomNonbondedForce.cpp
+253
-0
No files found.
platforms/opencl/src/OpenCLArray.h
View file @
84d482e2
...
@@ -51,11 +51,12 @@ public:
...
@@ -51,11 +51,12 @@ public:
* @param name the name of the array
* @param name the name of the array
* @param createHostBuffer specifies whether to create a buffer in host memory for copying data to and from
* @param createHostBuffer specifies whether to create a buffer in host memory for copying data to and from
* the OpenCL Buffer
* the OpenCL Buffer
* @param flags the set of flags to specify when creating the OpenCL Buffer
*/
*/
OpenCLArray
(
OpenCLContext
&
context
,
int
size
,
const
std
::
string
&
name
,
bool
createHostBuffer
=
false
)
:
OpenCLArray
(
OpenCLContext
&
context
,
int
size
,
const
std
::
string
&
name
,
bool
createHostBuffer
=
false
,
cl_int
flags
=
CL_MEM_READ_WRITE
)
:
context
(
context
),
size
(
size
),
name
(
name
),
local
(
createHostBuffer
?
size
:
0
),
ownsBuffer
(
true
)
{
context
(
context
),
size
(
size
),
name
(
name
),
local
(
createHostBuffer
?
size
:
0
),
ownsBuffer
(
true
)
{
try
{
try
{
buffer
=
new
cl
::
Buffer
(
context
.
getContext
(),
CL_MEM_READ_WRITE
,
size
*
sizeof
(
T
));
buffer
=
new
cl
::
Buffer
(
context
.
getContext
(),
flags
,
size
*
sizeof
(
T
));
}
}
catch
(
cl
::
Error
err
)
{
catch
(
cl
::
Error
err
)
{
std
::
stringstream
str
;
std
::
stringstream
str
;
...
...
platforms/opencl/src/OpenCLExpressionUtilities.cpp
0 → 100644
View file @
84d482e2
/* -------------------------------------------------------------------------- *
* 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 "OpenCLExpressionUtilities.h"
#include "openmm/OpenMMException.h"
#include "lepton/Operation.h"
#include <sstream>
using
namespace
OpenMM
;
using
namespace
Lepton
;
using
namespace
std
;
static
string
doubleToString
(
double
value
)
{
stringstream
s
;
s
.
precision
(
8
);
s
<<
scientific
<<
value
<<
"f"
;
return
s
.
str
();
}
static
string
intToString
(
int
value
)
{
stringstream
s
;
s
<<
value
;
return
s
.
str
();
}
string
OpenCLExpressionUtilities
::
createExpression
(
const
ParsedExpression
&
expression
,
const
map
<
string
,
string
>&
variables
)
{
return
processExpression
(
expression
.
getRootNode
(),
variables
);
}
string
OpenCLExpressionUtilities
::
processExpression
(
const
ExpressionTreeNode
&
node
,
const
map
<
string
,
string
>&
variables
)
{
switch
(
node
.
getOperation
().
getId
())
{
case
Operation
::
CONSTANT
:
return
doubleToString
(
dynamic_cast
<
const
Operation
::
Constant
*>
(
&
node
.
getOperation
())
->
getValue
());
case
Operation
::
VARIABLE
:
{
map
<
string
,
string
>::
const_iterator
iter
=
variables
.
find
(
node
.
getOperation
().
getName
());
if
(
iter
==
variables
.
end
())
throw
OpenMMException
(
"Unknown variable in expression: "
+
node
.
getOperation
().
getName
());
return
iter
->
second
;
}
case
Operation
::
ADD
:
return
"("
+
processExpression
(
node
.
getChildren
()[
0
],
variables
)
+
")+("
+
processExpression
(
node
.
getChildren
()[
1
],
variables
)
+
")"
;
case
Operation
::
SUBTRACT
:
return
"("
+
processExpression
(
node
.
getChildren
()[
0
],
variables
)
+
")-("
+
processExpression
(
node
.
getChildren
()[
1
],
variables
)
+
")"
;
case
Operation
::
MULTIPLY
:
return
"("
+
processExpression
(
node
.
getChildren
()[
0
],
variables
)
+
")*("
+
processExpression
(
node
.
getChildren
()[
1
],
variables
)
+
")"
;
case
Operation
::
DIVIDE
:
return
"("
+
processExpression
(
node
.
getChildren
()[
0
],
variables
)
+
")/("
+
processExpression
(
node
.
getChildren
()[
1
],
variables
)
+
")"
;
case
Operation
::
POWER
:
return
"pow(("
+
processExpression
(
node
.
getChildren
()[
0
],
variables
)
+
"), ("
+
processExpression
(
node
.
getChildren
()[
1
],
variables
)
+
"))"
;
case
Operation
::
NEGATE
:
return
"-("
+
processExpression
(
node
.
getChildren
()[
0
],
variables
)
+
")"
;
case
Operation
::
SQRT
:
return
"sqrt("
+
processExpression
(
node
.
getChildren
()[
0
],
variables
)
+
")"
;
case
Operation
::
EXP
:
return
"exp("
+
processExpression
(
node
.
getChildren
()[
0
],
variables
)
+
")"
;
case
Operation
::
LOG
:
return
"log("
+
processExpression
(
node
.
getChildren
()[
0
],
variables
)
+
")"
;
case
Operation
::
SIN
:
return
"sin("
+
processExpression
(
node
.
getChildren
()[
0
],
variables
)
+
")"
;
case
Operation
::
COS
:
return
"cos("
+
processExpression
(
node
.
getChildren
()[
0
],
variables
)
+
")"
;
case
Operation
::
SEC
:
return
"1.0f/cos("
+
processExpression
(
node
.
getChildren
()[
0
],
variables
)
+
")"
;
case
Operation
::
CSC
:
return
"1.0f/sin("
+
processExpression
(
node
.
getChildren
()[
0
],
variables
)
+
")"
;
case
Operation
::
TAN
:
return
"tan("
+
processExpression
(
node
.
getChildren
()[
0
],
variables
)
+
")"
;
case
Operation
::
COT
:
return
"1.0f/tan("
+
processExpression
(
node
.
getChildren
()[
0
],
variables
)
+
")"
;
case
Operation
::
ASIN
:
return
"asin("
+
processExpression
(
node
.
getChildren
()[
0
],
variables
)
+
")"
;
case
Operation
::
ACOS
:
return
"acos("
+
processExpression
(
node
.
getChildren
()[
0
],
variables
)
+
")"
;
case
Operation
::
ATAN
:
return
"atan("
+
processExpression
(
node
.
getChildren
()[
0
],
variables
)
+
")"
;
case
Operation
::
SQUARE
:
return
"pow(("
+
processExpression
(
node
.
getChildren
()[
0
],
variables
)
+
"), 2.0f)"
;
case
Operation
::
CUBE
:
return
"pow(("
+
processExpression
(
node
.
getChildren
()[
0
],
variables
)
+
"), 3.0f)"
;
case
Operation
::
RECIPROCAL
:
return
"1.0f/("
+
processExpression
(
node
.
getChildren
()[
0
],
variables
)
+
")"
;
case
Operation
::
ADD_CONSTANT
:
return
doubleToString
(
dynamic_cast
<
const
Operation
::
AddConstant
*>
(
&
node
.
getOperation
())
->
getValue
())
+
"+("
+
processExpression
(
node
.
getChildren
()[
0
],
variables
)
+
")"
;
case
Operation
::
MULTIPLY_CONSTANT
:
return
doubleToString
(
dynamic_cast
<
const
Operation
::
MultiplyConstant
*>
(
&
node
.
getOperation
())
->
getValue
())
+
"*("
+
processExpression
(
node
.
getChildren
()[
0
],
variables
)
+
")"
;
case
Operation
::
POWER_CONSTANT
:
return
"pow(("
+
processExpression
(
node
.
getChildren
()[
0
],
variables
)
+
"), "
+
doubleToString
(
dynamic_cast
<
const
Operation
::
PowerConstant
*>
(
&
node
.
getOperation
())
->
getValue
())
+
")"
;
}
throw
OpenMMException
(
"Internal error: Unknown operation in user-defined expression: "
+
node
.
getOperation
().
getName
());
}
platforms/opencl/src/OpenCLExpressionUtilities.h
0 → 100644
View file @
84d482e2
#ifndef OPENMM_OPENCLEXPRESSIONUTILITIES_H_
#define OPENMM_OPENCLEXPRESSIONUTILITIES_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 "lepton/ExpressionTreeNode.h"
#include "lepton/ParsedExpression.h"
#include <map>
#include <string>
namespace
OpenMM
{
/**
* This class is used by various classes to generate OpenCL source code implementing
* user defined mathematical expressions.
*/
class
OpenCLExpressionUtilities
{
public:
static
std
::
string
createExpression
(
const
Lepton
::
ParsedExpression
&
expression
,
const
std
::
map
<
std
::
string
,
std
::
string
>&
variables
);
private:
static
std
::
string
processExpression
(
const
Lepton
::
ExpressionTreeNode
&
node
,
const
std
::
map
<
std
::
string
,
std
::
string
>&
variables
);
};
}
// namespace OpenMM
#endif
/*OPENMM_OPENCLEXPRESSIONUTILITIES_H_*/
platforms/opencl/src/OpenCLKernelFactory.cpp
View file @
84d482e2
...
@@ -48,8 +48,8 @@ KernelImpl* OpenCLKernelFactory::createKernelImpl(std::string name, const Platfo
...
@@ -48,8 +48,8 @@ KernelImpl* OpenCLKernelFactory::createKernelImpl(std::string name, const Platfo
return
new
OpenCLCalcRBTorsionForceKernel
(
name
,
platform
,
cl
,
context
.
getSystem
());
return
new
OpenCLCalcRBTorsionForceKernel
(
name
,
platform
,
cl
,
context
.
getSystem
());
if
(
name
==
CalcNonbondedForceKernel
::
Name
())
if
(
name
==
CalcNonbondedForceKernel
::
Name
())
return
new
OpenCLCalcNonbondedForceKernel
(
name
,
platform
,
cl
,
context
.
getSystem
());
return
new
OpenCLCalcNonbondedForceKernel
(
name
,
platform
,
cl
,
context
.
getSystem
());
//
if (name == CalcCustomNonbondedForceKernel::Name())
if
(
name
==
CalcCustomNonbondedForceKernel
::
Name
())
//
return new OpenCLCalcCustomNonbondedForceKernel(name, platform, cl, context.getSystem());
return
new
OpenCLCalcCustomNonbondedForceKernel
(
name
,
platform
,
cl
,
context
.
getSystem
());
if
(
name
==
CalcGBSAOBCForceKernel
::
Name
())
if
(
name
==
CalcGBSAOBCForceKernel
::
Name
())
return
new
OpenCLCalcGBSAOBCForceKernel
(
name
,
platform
,
cl
);
return
new
OpenCLCalcGBSAOBCForceKernel
(
name
,
platform
,
cl
);
if
(
name
==
IntegrateVerletStepKernel
::
Name
())
if
(
name
==
IntegrateVerletStepKernel
::
Name
())
...
...
platforms/opencl/src/OpenCLKernels.cpp
View file @
84d482e2
...
@@ -30,8 +30,11 @@
...
@@ -30,8 +30,11 @@
#include "openmm/Context.h"
#include "openmm/Context.h"
#include "openmm/internal/ContextImpl.h"
#include "openmm/internal/ContextImpl.h"
#include "openmm/internal/NonbondedForceImpl.h"
#include "openmm/internal/NonbondedForceImpl.h"
#include "OpenCLExpressionUtilities.h"
#include "OpenCLIntegrationUtilities.h"
#include "OpenCLIntegrationUtilities.h"
#include "OpenCLNonbondedUtilities.h"
#include "OpenCLNonbondedUtilities.h"
#include "lepton/Parser.h"
#include "lepton/ParsedExpression.h"
#include <cmath>
#include <cmath>
using
namespace
OpenMM
;
using
namespace
OpenMM
;
...
@@ -666,122 +669,254 @@ double OpenCLCalcNonbondedForceKernel::executeEnergy(ContextImpl& context) {
...
@@ -666,122 +669,254 @@ double OpenCLCalcNonbondedForceKernel::executeEnergy(ContextImpl& context) {
return
ewaldSelfEnergy
;
return
ewaldSelfEnergy
;
}
}
//OpenCLCalcCustomNonbondedForceKernel::~OpenCLCalcCustomNonbondedForceKernel() {
class
OpenCLCustomNonbondedForceInfo
:
public
OpenCLForceInfo
{
//}
public:
//
OpenCLCustomNonbondedForceInfo
(
int
requiredBuffers
,
const
CustomNonbondedForce
&
force
)
:
OpenCLForceInfo
(
requiredBuffers
),
force
(
force
)
{
//void OpenCLCalcCustomNonbondedForceKernel::initialize(const System& system, const CustomNonbondedForce& force) {
}
// data.primaryKernel = this; // This must always be the primary kernel so it can update the global parameters
bool
areParticlesIdentical
(
int
particle1
,
int
particle2
)
{
// data.hasCustomNonbonded = true;
vector
<
double
>
params1
;
// numParticles = force.getNumParticles();
vector
<
double
>
params2
;
// _gpuContext* gpu = data.gpu;
force
.
getParticleParameters
(
particle1
,
params1
);
//
force
.
getParticleParameters
(
particle2
,
params2
);
// // Identify which exceptions are actual interactions.
for
(
int
i
=
0
;
i
<
params1
.
size
();
i
++
)
//
if
(
params1
[
i
]
!=
params2
[
i
])
// vector<pair<int, int> > exclusions;
return
false
;
// vector<int> exceptions;
return
true
;
// {
}
// vector<double> parameters;
int
getNumParticleGroups
()
{
// for (int i = 0; i < force.getNumExceptions(); i++) {
return
force
.
getNumExceptions
();
// int particle1, particle2;
}
// force.getExceptionParameters(i, particle1, particle2, parameters);
void
getParticlesInGroup
(
int
index
,
std
::
vector
<
int
>&
particles
)
{
// exclusions.push_back(pair<int, int>(particle1, particle2));
int
particle1
,
particle2
;
// if (parameters.size() > 0)
vector
<
double
>
params
;
// exceptions.push_back(i);
force
.
getExceptionParameters
(
index
,
particle1
,
particle2
,
params
);
// }
particles
.
resize
(
2
);
// }
particles
[
0
]
=
particle1
;
//
particles
[
1
]
=
particle2
;
// // Initialize nonbonded interactions.
}
//
bool
areGroupsIdentical
(
int
group1
,
int
group2
)
{
// vector<int> particle(numParticles);
int
particle1
,
particle2
;
// vector<vector<double> > parameters(numParticles);
vector
<
double
>
params1
;
// vector<vector<int> > exclusionList(numParticles);
vector
<
double
>
params2
;
// for (int i = 0; i < numParticles; i++) {
force
.
getExceptionParameters
(
group1
,
particle1
,
particle2
,
params1
);
// force.getParticleParameters(i, parameters[i]);
force
.
getExceptionParameters
(
group2
,
particle1
,
particle2
,
params2
);
// particle[i] = i;
for
(
int
i
=
0
;
i
<
params1
.
size
();
i
++
)
// exclusionList[i].push_back(i);
if
(
params1
[
i
]
!=
params2
[
i
])
// }
return
false
;
// for (int i = 0; i < (int)exclusions.size(); i++) {
return
true
;
// exclusionList[exclusions[i].first].push_back(exclusions[i].second);
}
// exclusionList[exclusions[i].second].push_back(exclusions[i].first);
private:
// }
const
CustomNonbondedForce
&
force
;
// Vec3 boxVectors[3];
};
// system.getPeriodicBoxVectors(boxVectors[0], boxVectors[1], boxVectors[2]);
// gpuSetPeriodicBoxSize(gpu, (float)boxVectors[0][0], (float)boxVectors[1][1], (float)boxVectors[2][2]);
OpenCLCalcCustomNonbondedForceKernel
::~
OpenCLCalcCustomNonbondedForceKernel
()
{
// OpenCLNonbondedMethod method = NO_CUTOFF;
if
(
params
!=
NULL
)
// if (force.getNonbondedMethod() != CustomNonbondedForce::NoCutoff)
delete
params
;
// method = CUTOFF;
if
(
globals
!=
NULL
)
// if (force.getNonbondedMethod() == CustomNonbondedForce::CutoffPeriodic) {
delete
globals
;
// method = PERIODIC;
if
(
exceptionParams
!=
NULL
)
// }
delete
exceptionParams
;
// data.customNonbondedMethod = method;
if
(
exceptionIndices
!=
NULL
)
//
delete
exceptionIndices
;
// // Initialize exceptions.
}
//
// int numExceptions = exceptions.size();
void
OpenCLCalcCustomNonbondedForceKernel
::
initialize
(
const
System
&
system
,
const
CustomNonbondedForce
&
force
)
{
// vector<int> exceptionParticle1(numExceptions);
if
(
force
.
getNumParameters
()
>
4
)
// vector<int> exceptionParticle2(numExceptions);
throw
OpenMMException
(
"OpenCLPlatform only supports four per-atom parameters for custom nonbonded forces"
);
// vector<vector<double> > exceptionParams(numExceptions);
int
forceIndex
;
// for (int i = 0; i < numExceptions; i++)
for
(
forceIndex
=
0
;
forceIndex
<
system
.
getNumForces
()
&&
&
system
.
getForce
(
forceIndex
)
!=
&
force
;
++
forceIndex
)
// force.getExceptionParameters(exceptions[i], exceptionParticle1[i], exceptionParticle2[i], exceptionParams[i]);
;
//
string
prefix
=
"custom"
+
intToString
(
forceIndex
)
+
"_"
;
// // Record the tabulated functions.
//
// Identify which exceptions are actual interactions.
// for (int i = 0; i < force.getNumFunctions(); i++) {
// string name;
vector
<
pair
<
int
,
int
>
>
exclusions
;
// vector<double> values;
vector
<
int
>
exceptions
;
// double min, max;
{
// bool interpolating;
vector
<
double
>
parameters
;
// force.getFunctionParameters(i, name, values, min, max, interpolating);
for
(
int
i
=
0
;
i
<
force
.
getNumExceptions
();
i
++
)
{
int
particle1
,
particle2
;
force
.
getExceptionParameters
(
i
,
particle1
,
particle2
,
parameters
);
exclusions
.
push_back
(
pair
<
int
,
int
>
(
particle1
,
particle2
));
if
(
parameters
.
size
()
>
0
)
exceptions
.
push_back
(
i
);
}
}
// Record parameters and exclusions.
int
numParticles
=
force
.
getNumParticles
();
params
=
new
OpenCLArray
<
mm_float4
>
(
cl
,
numParticles
,
"customNonbondedParameters"
);
if
(
force
.
getNumGlobalParameters
()
>
0
)
globals
=
new
OpenCLArray
<
cl_float
>
(
cl
,
force
.
getNumGlobalParameters
(),
"customNonbondedGlobals"
,
false
,
CL_MEM_READ_ONLY
);
vector
<
mm_float4
>
paramVec
(
numParticles
);
vector
<
vector
<
int
>
>
exclusionList
(
numParticles
);
for
(
int
i
=
0
;
i
<
numParticles
;
i
++
)
{
vector
<
double
>
parameters
;
force
.
getParticleParameters
(
i
,
parameters
);
if
(
parameters
.
size
()
>
0
)
paramVec
[
i
].
x
=
(
cl_float
)
parameters
[
0
];
if
(
parameters
.
size
()
>
1
)
paramVec
[
i
].
y
=
(
cl_float
)
parameters
[
1
];
if
(
parameters
.
size
()
>
2
)
paramVec
[
i
].
z
=
(
cl_float
)
parameters
[
2
];
if
(
parameters
.
size
()
>
3
)
paramVec
[
i
].
w
=
(
cl_float
)
parameters
[
3
];
exclusionList
[
i
].
push_back
(
i
);
}
for
(
int
i
=
0
;
i
<
(
int
)
exclusions
.
size
();
i
++
)
{
exclusionList
[
exclusions
[
i
].
first
].
push_back
(
exclusions
[
i
].
second
);
exclusionList
[
exclusions
[
i
].
second
].
push_back
(
exclusions
[
i
].
first
);
}
params
->
upload
(
paramVec
);
// Record the tabulated functions.
for
(
int
i
=
0
;
i
<
force
.
getNumFunctions
();
i
++
)
{
string
name
;
vector
<
double
>
values
;
double
min
,
max
;
bool
interpolating
;
force
.
getFunctionParameters
(
i
,
name
,
values
,
min
,
max
,
interpolating
);
// gpuSetTabulatedFunction(gpu, i, name, values, min, max, interpolating);
// gpuSetTabulatedFunction(gpu, i, name, values, min, max, interpolating);
// }
}
//
// // Record information for the expressions.
// Record information for the expressions.
//
// vector<string> paramNames;
vector
<
string
>
paramNames
;
// vector<string> combiningRules;
vector
<
string
>
combiningRules
;
// for (int i = 0; i < force.getNumParameters(); i++) {
for
(
int
i
=
0
;
i
<
force
.
getNumParameters
();
i
++
)
{
// paramNames.push_back(force.getParameterName(i));
paramNames
.
push_back
(
force
.
getParameterName
(
i
));
// combiningRules.push_back(force.getParameterCombiningRule(i));
combiningRules
.
push_back
(
force
.
getParameterCombiningRule
(
i
));
// }
}
// globalParamNames.resize(force.getNumGlobalParameters());
globalParamNames
.
resize
(
force
.
getNumGlobalParameters
());
// globalParamValues.resize(force.getNumGlobalParameters());
globalParamValues
.
resize
(
force
.
getNumGlobalParameters
());
// for (int i = 0; i < force.getNumGlobalParameters(); i++) {
for
(
int
i
=
0
;
i
<
force
.
getNumGlobalParameters
();
i
++
)
{
// globalParamNames[i] = force.getGlobalParameterName(i);
globalParamNames
[
i
]
=
force
.
getGlobalParameterName
(
i
);
// globalParamValues[i] = force.getGlobalParameterDefaultValue(i);
globalParamValues
[
i
]
=
(
cl_float
)
force
.
getGlobalParameterDefaultValue
(
i
);
// }
}
// gpuSetCustomNonbondedParameters(gpu, parameters, exclusionList, exceptionParticle1, exceptionParticle2, exceptionParams, method,
if
(
globals
!=
NULL
)
// (float)force.getCutoffDistance(), force.getEnergyFunction(), combiningRules, paramNames, globalParamNames);
globals
->
upload
(
globalParamValues
);
// if (globalParamValues.size() > 0)
bool
useCutoff
=
(
force
.
getNonbondedMethod
()
!=
CustomNonbondedForce
::
NoCutoff
);
// SetCustomNonbondedGlobalParams(&globalParamValues[0]);
bool
usePeriodic
=
(
force
.
getNonbondedMethod
()
!=
CustomNonbondedForce
::
NoCutoff
&&
force
.
getNonbondedMethod
()
!=
CustomNonbondedForce
::
CutoffNonPeriodic
);
//}
Lepton
::
ParsedExpression
energyExpression
=
Lepton
::
Parser
::
parse
(
force
.
getEnergyFunction
()).
optimize
();
//
Lepton
::
ParsedExpression
forceExpression
=
energyExpression
.
differentiate
(
"r"
).
optimize
();
//void OpenCLCalcCustomNonbondedForceKernel::executeForces(ContextImpl& context) {
// if (data.primaryKernel == this) {
// Create the kernels.
// updateGlobalParams(context);
// calcForces(context, data);
map
<
string
,
string
>
paramVariables
;
// }
map
<
string
,
string
>
forceVariables
;
//}
map
<
string
,
string
>
exceptionVariables
;
//
forceVariables
[
"r"
]
=
"r"
;
//double OpenCLCalcCustomNonbondedForceKernel::executeEnergy(ContextImpl& context) {
exceptionVariables
[
"r"
]
=
"r"
;
// if (data.primaryKernel == this) {
string
suffixes
[]
=
{
".x"
,
".y"
,
".z"
,
".w"
};
// updateGlobalParams(context);
for
(
int
i
=
0
;
i
<
force
.
getNumParameters
();
i
++
)
{
// return calcEnergy(context, data, system);
const
string
&
name
=
force
.
getParameterName
(
i
);
// }
paramVariables
[
name
+
"1"
]
=
prefix
+
"params1"
+
suffixes
[
i
];
// return 0.0;
paramVariables
[
name
+
"2"
]
=
prefix
+
"params2"
+
suffixes
[
i
];
//}
forceVariables
[
name
]
=
prefix
+
name
;
//
exceptionVariables
[
name
]
=
"exceptionParams"
+
suffixes
[
i
];
//void OpenCLCalcCustomNonbondedForceKernel::updateGlobalParams(ContextImpl& context) {
}
// bool changed = false;
for
(
int
i
=
0
;
i
<
force
.
getNumGlobalParameters
();
i
++
)
{
// for (int i = 0; i < globalParamNames.size(); i++) {
const
string
&
name
=
force
.
getGlobalParameterName
(
i
);
// float value = (float) context.getParameter(globalParamNames[i]);
string
value
=
"globals["
+
intToString
(
i
)
+
"]"
;
// if (value != globalParamValues[i])
paramVariables
[
name
]
=
prefix
+
value
;
// changed = true;
forceVariables
[
name
]
=
prefix
+
value
;
// globalParamValues[i] = value;
exceptionVariables
[
name
]
=
value
;
// }
}
// if (changed)
stringstream
compute
;
// SetCustomNonbondedGlobalParams(&globalParamValues[0]);
for
(
int
i
=
0
;
i
<
force
.
getNumParameters
();
i
++
)
{
//}
Lepton
::
ParsedExpression
expression
=
Lepton
::
Parser
::
parse
(
force
.
getParameterCombiningRule
(
i
)).
optimize
();
//
compute
<<
"float "
<<
prefix
<<
force
.
getParameterName
(
i
)
<<
" = "
<<
OpenCLExpressionUtilities
::
createExpression
(
expression
,
paramVariables
)
<<
";
\n
"
;
}
compute
<<
"tempEnergy += "
<<
OpenCLExpressionUtilities
::
createExpression
(
energyExpression
,
forceVariables
)
<<
";
\n
"
;
compute
<<
"tempForce -= "
<<
OpenCLExpressionUtilities
::
createExpression
(
forceExpression
,
forceVariables
)
<<
";
\n
"
;
map
<
string
,
string
>
replacements
;
replacements
[
"COMPUTE_FORCE"
]
=
compute
.
str
();
string
source
=
cl
.
loadSourceFromFile
(
"customNonbonded.cl"
,
replacements
);
cl
.
getNonbondedUtilities
().
addInteraction
(
useCutoff
,
usePeriodic
,
true
,
force
.
getCutoffDistance
(),
exclusionList
,
source
);
cl
.
getNonbondedUtilities
().
addParameter
(
OpenCLNonbondedUtilities
::
ParameterInfo
(
prefix
+
"params"
,
"float4"
,
sizeof
(
cl_float4
),
params
->
getDeviceBuffer
()));
if
(
globals
!=
NULL
)
{
globals
->
upload
(
globalParamValues
);
cl
.
getNonbondedUtilities
().
addArgument
(
OpenCLNonbondedUtilities
::
ParameterInfo
(
prefix
+
"globals"
,
"float"
,
sizeof
(
cl_float
),
globals
->
getDeviceBuffer
()));
}
stringstream
computeExceptions
;
computeExceptions
<<
"energy += "
<<
OpenCLExpressionUtilities
::
createExpression
(
energyExpression
,
exceptionVariables
)
<<
";
\n
"
;
computeExceptions
<<
"dEdR = "
<<
OpenCLExpressionUtilities
::
createExpression
(
forceExpression
,
exceptionVariables
)
<<
";
\n
"
;
replacements
[
"COMPUTE_FORCE"
]
=
computeExceptions
.
str
();
map
<
string
,
string
>
defines
;
if
(
globals
!=
NULL
)
defines
[
"HAS_GLOBALS"
]
=
"1"
;
cl
::
Program
program
=
cl
.
createProgram
(
cl
.
loadSourceFromFile
(
"customNonbondedExceptions.cl"
,
replacements
),
defines
);
exceptionsKernel
=
cl
::
Kernel
(
program
,
"computeCustomNonbondedExceptions"
);
// Initialize exception parameters.
int
numExceptions
=
exceptions
.
size
();
int
maxBuffers
=
cl
.
getNonbondedUtilities
().
getNumForceBuffers
();
if
(
numExceptions
>
0
)
{
exceptionParams
=
new
OpenCLArray
<
mm_float4
>
(
cl
,
numExceptions
,
"customExceptionParams"
);
exceptionIndices
=
new
OpenCLArray
<
mm_int4
>
(
cl
,
numExceptions
,
"customExceptionIndices"
);
vector
<
mm_float4
>
exceptionParamsVector
(
numExceptions
);
vector
<
mm_int4
>
exceptionIndicesVector
(
numExceptions
);
vector
<
int
>
forceBufferCounter
(
system
.
getNumParticles
(),
0
);
for
(
int
i
=
0
;
i
<
numExceptions
;
i
++
)
{
int
particle1
,
particle2
;
vector
<
double
>
parameters
;
force
.
getExceptionParameters
(
exceptions
[
i
],
particle1
,
particle2
,
parameters
);
if
(
parameters
.
size
()
>
0
)
exceptionParamsVector
[
i
].
x
=
(
cl_float
)
parameters
[
0
];
if
(
parameters
.
size
()
>
1
)
exceptionParamsVector
[
i
].
y
=
(
cl_float
)
parameters
[
1
];
if
(
parameters
.
size
()
>
2
)
exceptionParamsVector
[
i
].
z
=
(
cl_float
)
parameters
[
2
];
if
(
parameters
.
size
()
>
3
)
exceptionParamsVector
[
i
].
w
=
(
cl_float
)
parameters
[
3
];
exceptionIndicesVector
[
i
]
=
(
mm_int4
)
{
particle1
,
particle2
,
forceBufferCounter
[
particle1
]
++
,
forceBufferCounter
[
particle2
]
++
};
}
exceptionParams
->
upload
(
exceptionParamsVector
);
exceptionIndices
->
upload
(
exceptionIndicesVector
);
for
(
int
i
=
0
;
i
<
forceBufferCounter
.
size
();
i
++
)
maxBuffers
=
max
(
maxBuffers
,
forceBufferCounter
[
i
]);
}
cl
.
addForce
(
new
OpenCLCustomNonbondedForceInfo
(
maxBuffers
,
force
));
}
void
OpenCLCalcCustomNonbondedForceKernel
::
executeForces
(
ContextImpl
&
context
)
{
if
(
exceptionParams
!=
NULL
)
{
if
(
!
hasCreatedKernels
)
{
hasCreatedKernels
=
true
;
exceptionsKernel
.
setArg
<
cl_int
>
(
0
,
cl
.
getPaddedNumAtoms
());
exceptionsKernel
.
setArg
<
cl_int
>
(
1
,
exceptionParams
->
getSize
());
exceptionsKernel
.
setArg
<
cl_float
>
(
2
,
cl
.
getNonbondedUtilities
().
getCutoffDistance
()
*
cl
.
getNonbondedUtilities
().
getCutoffDistance
());
exceptionsKernel
.
setArg
<
mm_float4
>
(
3
,
cl
.
getNonbondedUtilities
().
getPeriodicBoxSize
());
exceptionsKernel
.
setArg
<
cl
::
Buffer
>
(
4
,
cl
.
getForceBuffers
().
getDeviceBuffer
());
exceptionsKernel
.
setArg
<
cl
::
Buffer
>
(
5
,
cl
.
getEnergyBuffer
().
getDeviceBuffer
());
exceptionsKernel
.
setArg
<
cl
::
Buffer
>
(
6
,
cl
.
getPosq
().
getDeviceBuffer
());
exceptionsKernel
.
setArg
<
cl
::
Buffer
>
(
7
,
exceptionParams
->
getDeviceBuffer
());
exceptionsKernel
.
setArg
<
cl
::
Buffer
>
(
8
,
exceptionIndices
->
getDeviceBuffer
());
if
(
globals
!=
NULL
)
exceptionsKernel
.
setArg
<
cl
::
Buffer
>
(
9
,
globals
->
getDeviceBuffer
());
}
cl
.
executeKernel
(
exceptionsKernel
,
exceptionIndices
->
getSize
());
}
if
(
globals
==
NULL
)
return
;
bool
changed
=
false
;
for
(
int
i
=
0
;
i
<
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
);
}
double
OpenCLCalcCustomNonbondedForceKernel
::
executeEnergy
(
ContextImpl
&
context
)
{
executeForces
(
context
);
return
0.0
;
}
class
OpenCLGBSAOBCForceInfo
:
public
OpenCLForceInfo
{
class
OpenCLGBSAOBCForceInfo
:
public
OpenCLForceInfo
{
public:
public:
...
...
platforms/opencl/src/OpenCLKernels.h
View file @
84d482e2
...
@@ -335,42 +335,47 @@ private:
...
@@ -335,42 +335,47 @@ private:
double
cutoffSquared
,
ewaldSelfEnergy
;
double
cutoffSquared
,
ewaldSelfEnergy
;
};
};
///**
/**
// * This kernel is invoked by CustomNonbondedForce to calculate the forces acting on the system.
* This kernel is invoked by CustomNonbondedForce to calculate the forces acting on the system.
// */
*/
//class OpenCLCalcCustomNonbondedForceKernel : public CalcCustomNonbondedForceKernel {
class
OpenCLCalcCustomNonbondedForceKernel
:
public
CalcCustomNonbondedForceKernel
{
//public:
public:
// OpenCLCalcCustomNonbondedForceKernel(std::string name, const Platform& platform, OpenCLContext& cl, System& system) : CalcCustomNonbondedForceKernel(name, platform), cl(cl), system(system) {
OpenCLCalcCustomNonbondedForceKernel
(
std
::
string
name
,
const
Platform
&
platform
,
OpenCLContext
&
cl
,
System
&
system
)
:
CalcCustomNonbondedForceKernel
(
name
,
platform
),
// }
hasCreatedKernels
(
false
),
cl
(
cl
),
params
(
NULL
),
globals
(
NULL
),
exceptionParams
(
NULL
),
exceptionIndices
(
NULL
),
system
(
system
)
{
// ~OpenCLCalcCustomNonbondedForceKernel();
}
// /**
~
OpenCLCalcCustomNonbondedForceKernel
();
// * Initialize the kernel.
/**
// *
* Initialize the kernel.
// * @param system the System this kernel will be applied to
*
// * @param force the CustomNonbondedForce this kernel will be used for
* @param system the System this kernel will be applied to
// */
* @param force the CustomNonbondedForce this kernel will be used for
// void initialize(const System& system, const CustomNonbondedForce& force);
*/
// /**
void
initialize
(
const
System
&
system
,
const
CustomNonbondedForce
&
force
);
// * Execute the kernel to calculate the forces.
/**
// *
* Execute the kernel to calculate the forces.
// * @param context the context in which to execute this kernel
*
// */
* @param context the context in which to execute this kernel
// void executeForces(ContextImpl& context);
*/
// /**
void
executeForces
(
ContextImpl
&
context
);
// * Execute the kernel to calculate the energy.
/**
// *
* Execute the kernel to calculate the energy.
// * @param context the context in which to execute this kernel
*
// * @return the potential energy due to the CustomNonbondedForce
* @param context the context in which to execute this kernel
// */
* @return the potential energy due to the CustomNonbondedForce
// double executeEnergy(ContextImpl& context);
*/
//private:
double
executeEnergy
(
ContextImpl
&
context
);
// void updateGlobalParams(ContextImpl& context);
private:
// OpenCLContext& cl;
bool
hasCreatedKernels
;
// int numParticles;
OpenCLContext
&
cl
;
// std::vector<std::string> globalParamNames;
OpenCLArray
<
mm_float4
>*
params
;
// std::vector<float> globalParamValues;
OpenCLArray
<
cl_float
>*
globals
;
// System& system;
OpenCLArray
<
mm_float4
>*
exceptionParams
;
//};
OpenCLArray
<
mm_int4
>*
exceptionIndices
;
cl
::
Kernel
exceptionsKernel
;
std
::
vector
<
std
::
string
>
globalParamNames
;
std
::
vector
<
cl_float
>
globalParamValues
;
System
&
system
;
};
/**
/**
* This kernel is invoked by GBSAOBCForce to calculate the forces acting on the system.
* This kernel is invoked by GBSAOBCForce to calculate the forces acting on the system.
...
...
platforms/opencl/src/OpenCLNonbondedUtilities.cpp
View file @
84d482e2
...
@@ -103,6 +103,10 @@ void OpenCLNonbondedUtilities::addParameter(const ParameterInfo& parameter) {
...
@@ -103,6 +103,10 @@ void OpenCLNonbondedUtilities::addParameter(const ParameterInfo& parameter) {
parameters
.
push_back
(
parameter
);
parameters
.
push_back
(
parameter
);
}
}
void
OpenCLNonbondedUtilities
::
addArgument
(
const
ParameterInfo
&
parameter
)
{
arguments
.
push_back
(
parameter
);
}
void
OpenCLNonbondedUtilities
::
initialize
(
const
System
&
system
)
{
void
OpenCLNonbondedUtilities
::
initialize
(
const
System
&
system
)
{
if
(
cutoff
==
-
1.0
)
if
(
cutoff
==
-
1.0
)
return
;
// There are no nonbonded interactions in the System.
return
;
// There are no nonbonded interactions in the System.
...
@@ -222,7 +226,7 @@ void OpenCLNonbondedUtilities::initialize(const System& system) {
...
@@ -222,7 +226,7 @@ void OpenCLNonbondedUtilities::initialize(const System& system) {
// Create kernels.
// Create kernels.
forceKernel
=
createInteractionKernel
(
kernelSource
,
parameters
,
true
);
forceKernel
=
createInteractionKernel
(
kernelSource
,
parameters
,
arguments
,
true
);
if
(
useCutoff
)
{
if
(
useCutoff
)
{
map
<
string
,
string
>
defines
;
map
<
string
,
string
>
defines
;
if
(
forceBufferPerAtomBlock
)
if
(
forceBufferPerAtomBlock
)
...
@@ -274,7 +278,7 @@ void OpenCLNonbondedUtilities::computeInteractions() {
...
@@ -274,7 +278,7 @@ void OpenCLNonbondedUtilities::computeInteractions() {
context
.
executeKernel
(
forceKernel
,
tiles
->
getSize
()
*
OpenCLContext
::
TileSize
);
context
.
executeKernel
(
forceKernel
,
tiles
->
getSize
()
*
OpenCLContext
::
TileSize
);
}
}
cl
::
Kernel
OpenCLNonbondedUtilities
::
createInteractionKernel
(
const
string
&
source
,
const
vector
<
ParameterInfo
>
params
,
bool
useExclusions
)
const
{
cl
::
Kernel
OpenCLNonbondedUtilities
::
createInteractionKernel
(
const
string
&
source
,
const
vector
<
ParameterInfo
>
&
params
,
const
vector
<
ParameterInfo
>&
arguments
,
bool
useExclusions
)
const
{
map
<
string
,
string
>
replacements
;
map
<
string
,
string
>
replacements
;
replacements
[
"COMPUTE_INTERACTION"
]
=
source
;
replacements
[
"COMPUTE_INTERACTION"
]
=
source
;
stringstream
args
;
stringstream
args
;
...
@@ -288,6 +292,15 @@ cl::Kernel OpenCLNonbondedUtilities::createInteractionKernel(const string& sourc
...
@@ -288,6 +292,15 @@ cl::Kernel OpenCLNonbondedUtilities::createInteractionKernel(const string& sourc
args
<<
"* local_"
;
args
<<
"* local_"
;
args
<<
params
[
i
].
getName
();
args
<<
params
[
i
].
getName
();
}
}
for
(
int
i
=
0
;
i
<
arguments
.
size
();
i
++
)
{
if
((
arguments
[
i
].
getBuffer
().
getInfo
<
CL_MEM_FLAGS
>
()
&
CL_MEM_READ_ONLY
)
==
0
)
args
<<
", __global "
;
else
args
<<
", __constant "
;
args
<<
arguments
[
i
].
getType
();
args
<<
"* "
;
args
<<
arguments
[
i
].
getName
();
}
replacements
[
"PARAMETER_ARGUMENTS"
]
=
args
.
str
();
replacements
[
"PARAMETER_ARGUMENTS"
]
=
args
.
str
();
stringstream
loadLocal1
;
stringstream
loadLocal1
;
for
(
int
i
=
0
;
i
<
params
.
size
();
i
++
)
{
for
(
int
i
=
0
;
i
<
params
.
size
();
i
++
)
{
...
@@ -383,5 +396,9 @@ cl::Kernel OpenCLNonbondedUtilities::createInteractionKernel(const string& sourc
...
@@ -383,5 +396,9 @@ cl::Kernel OpenCLNonbondedUtilities::createInteractionKernel(const string& sourc
kernel
.
setArg
<
cl
::
Buffer
>
(
i
*
2
+
paramBase
,
params
[
i
].
getBuffer
());
kernel
.
setArg
<
cl
::
Buffer
>
(
i
*
2
+
paramBase
,
params
[
i
].
getBuffer
());
kernel
.
setArg
(
i
*
2
+
paramBase
+
1
,
OpenCLContext
::
ThreadBlockSize
*
params
[
i
].
getSize
(),
NULL
);
kernel
.
setArg
(
i
*
2
+
paramBase
+
1
,
OpenCLContext
::
ThreadBlockSize
*
params
[
i
].
getSize
(),
NULL
);
}
}
paramBase
+=
2
*
params
.
size
();
for
(
int
i
=
0
;
i
<
(
int
)
arguments
.
size
();
i
++
)
{
kernel
.
setArg
<
cl
::
Buffer
>
(
i
+
paramBase
,
arguments
[
i
].
getBuffer
());
}
return
kernel
;
return
kernel
;
}
}
platforms/opencl/src/OpenCLNonbondedUtilities.h
View file @
84d482e2
...
@@ -81,6 +81,10 @@ public:
...
@@ -81,6 +81,10 @@ public:
* Add a per-atom parameter that the default interaction kernel may depend on.
* Add a per-atom parameter that the default interaction kernel may depend on.
*/
*/
void
addParameter
(
const
ParameterInfo
&
parameter
);
void
addParameter
(
const
ParameterInfo
&
parameter
);
/**
* Add an array (other than a per-atom parameter) that should be passed as an argument to the default interaction kernel.
*/
void
addArgument
(
const
ParameterInfo
&
parameter
);
/**
/**
* Initialize this object in preparation for a simulation.
* Initialize this object in preparation for a simulation.
*/
*/
...
@@ -173,9 +177,10 @@ public:
...
@@ -173,9 +177,10 @@ public:
*
*
* @param source the source code for evaluating the force and energy
* @param source the source code for evaluating the force and energy
* @param params the per-atom parameters this kernel may depend on
* @param params the per-atom parameters this kernel may depend on
* @param arguments arrays (other than per-atom parameters) that should be passed as arguments to the kernel
* @param useExclusions specifies whether exclusions are applied to this interaction
* @param useExclusions specifies whether exclusions are applied to this interaction
*/
*/
cl
::
Kernel
createInteractionKernel
(
const
std
::
string
&
source
,
const
std
::
vector
<
ParameterInfo
>
params
,
bool
useExclusions
)
const
;
cl
::
Kernel
createInteractionKernel
(
const
std
::
string
&
source
,
const
std
::
vector
<
ParameterInfo
>
&
params
,
const
std
::
vector
<
ParameterInfo
>&
arguments
,
bool
useExclusions
)
const
;
private:
private:
OpenCLContext
&
context
;
OpenCLContext
&
context
;
cl
::
Kernel
forceKernel
;
cl
::
Kernel
forceKernel
;
...
@@ -192,6 +197,7 @@ private:
...
@@ -192,6 +197,7 @@ private:
OpenCLArray
<
mm_float4
>*
blockBoundingBox
;
OpenCLArray
<
mm_float4
>*
blockBoundingBox
;
std
::
vector
<
std
::
vector
<
int
>
>
atomExclusions
;
std
::
vector
<
std
::
vector
<
int
>
>
atomExclusions
;
std
::
vector
<
ParameterInfo
>
parameters
;
std
::
vector
<
ParameterInfo
>
parameters
;
std
::
vector
<
ParameterInfo
>
arguments
;
OpenCLCompact
*
compact
;
OpenCLCompact
*
compact
;
std
::
string
kernelSource
;
std
::
string
kernelSource
;
std
::
map
<
std
::
string
,
std
::
string
>
kernelDefines
;
std
::
map
<
std
::
string
,
std
::
string
>
kernelDefines
;
...
...
platforms/opencl/src/OpenCLPlatform.cpp
View file @
84d482e2
...
@@ -52,7 +52,7 @@ OpenCLPlatform::OpenCLPlatform() {
...
@@ -52,7 +52,7 @@ OpenCLPlatform::OpenCLPlatform() {
registerKernelFactory
(
CalcPeriodicTorsionForceKernel
::
Name
(),
factory
);
registerKernelFactory
(
CalcPeriodicTorsionForceKernel
::
Name
(),
factory
);
registerKernelFactory
(
CalcRBTorsionForceKernel
::
Name
(),
factory
);
registerKernelFactory
(
CalcRBTorsionForceKernel
::
Name
(),
factory
);
registerKernelFactory
(
CalcNonbondedForceKernel
::
Name
(),
factory
);
registerKernelFactory
(
CalcNonbondedForceKernel
::
Name
(),
factory
);
//
registerKernelFactory(CalcCustomNonbondedForceKernel::Name(), factory);
registerKernelFactory
(
CalcCustomNonbondedForceKernel
::
Name
(),
factory
);
registerKernelFactory
(
CalcGBSAOBCForceKernel
::
Name
(),
factory
);
registerKernelFactory
(
CalcGBSAOBCForceKernel
::
Name
(),
factory
);
registerKernelFactory
(
IntegrateVerletStepKernel
::
Name
(),
factory
);
registerKernelFactory
(
IntegrateVerletStepKernel
::
Name
(),
factory
);
registerKernelFactory
(
IntegrateLangevinStepKernel
::
Name
(),
factory
);
registerKernelFactory
(
IntegrateLangevinStepKernel
::
Name
(),
factory
);
...
...
platforms/opencl/src/kernels/customNonbonded.cl
0 → 100644
View file @
84d482e2
#
ifdef
USE_CUTOFF
if
(
!isExcluded
&&
r2
<
CUTOFF_SQUARED
)
{
#
else
if
(
!isExcluded
)
{
#
endif
float
tempForce
=
0.0f
;
COMPUTE_FORCE
dEdR
+=
tempForce*invR
;
}
platforms/opencl/src/kernels/customNonbondedExceptions.cl
0 → 100644
View file @
84d482e2
/**
*
Compute
custom
nonbonded
exceptions.
*/
__kernel
void
computeCustomNonbondedExceptions
(
int
numAtoms,
int
numExceptions,
float
cutoffSquared,
float4
periodicBoxSize,
__global
float4*
forceBuffers,
__global
float*
energyBuffer,
__global
float4*
posq,
__global
float4*
params,
__global
int4*
indices
#
ifdef
HAS_GLOBALS
,
__constant
float*
globals
)
{
#
else
)
{
#
endif
int
index
=
get_global_id
(
0
)
;
float
energy
=
0.0f
;
while
(
index
<
numExceptions
)
{
//
Look
up
the
data
for
this
exception.
int4
atoms
=
indices[index]
;
float4
exceptionParams
=
params[index]
;
float4
delta
=
posq[atoms.y]-posq[atoms.x]
;
#
ifdef
USE_PERIODIC
delta.x
-=
floor
(
delta.x/periodicBoxSize.x+0.5f
)
*periodicBoxSize.x
;
delta.y
-=
floor
(
delta.y/periodicBoxSize.y+0.5f
)
*periodicBoxSize.y
;
delta.z
-=
floor
(
delta.z/periodicBoxSize.z+0.5f
)
*periodicBoxSize.z
;
#
endif
//
Compute
the
force.
float
r2
=
delta.x*delta.x
+
delta.y*delta.y
+
delta.z*delta.z
;
#
ifdef
USE_CUTOFF
if
(
r2
>
cutoffSquared
)
{
#
else
{
#
endif
float
r
=
sqrt
(
r2
)
;
float
dEdR
;
COMPUTE_FORCE
delta.xyz
*=
-dEdR/r
;
//
Record
the
force
on
each
of
the
two
atoms.
unsigned
int
offsetA
=
atoms.x+atoms.z*numAtoms
;
unsigned
int
offsetB
=
atoms.y+atoms.w*numAtoms
;
float4
forceA
=
forceBuffers[offsetA]
;
float4
forceB
=
forceBuffers[offsetB]
;
forceA.xyz
-=
delta.xyz
;
forceB.xyz
+=
delta.xyz
;
forceBuffers[offsetA]
=
forceA
;
forceBuffers[offsetB]
=
forceB
;
}
index
+=
get_global_size
(
0
)
;
}
energyBuffer[get_global_id
(
0
)
]
+=
energy
;
}
platforms/opencl/tests/TestOpenCLCustomNonbondedForce.cpp
0 → 100644
View file @
84d482e2
/* -------------------------------------------------------------------------- *
* 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 all the different force terms in the OpenCL implementation of CustomNonbondedForce.
*/
#include "../../../tests/AssertionUtilities.h"
#include "openmm/Context.h"
#include "OpenCLPlatform.h"
#include "openmm/CustomNonbondedForce.h"
#include "openmm/System.h"
#include "openmm/VerletIntegrator.h"
#include <iostream>
#include <vector>
using
namespace
OpenMM
;
using
namespace
std
;
const
double
TOL
=
1e-5
;
void
testSimpleExpression
()
{
OpenCLPlatform
platform
;
System
system
;
system
.
addParticle
(
1.0
);
system
.
addParticle
(
1.0
);
VerletIntegrator
integrator
(
0.01
);
CustomNonbondedForce
*
forceField
=
new
CustomNonbondedForce
(
"-0.1*r^3"
);
forceField
->
addParticle
(
vector
<
double
>
());
forceField
->
addParticle
(
vector
<
double
>
());
system
.
addForce
(
forceField
);
Context
context
(
system
,
integrator
,
platform
);
vector
<
Vec3
>
positions
(
2
);
positions
[
0
]
=
Vec3
(
0
,
0
,
0
);
positions
[
1
]
=
Vec3
(
2
,
0
,
0
);
context
.
setPositions
(
positions
);
State
state
=
context
.
getState
(
State
::
Forces
|
State
::
Energy
);
const
vector
<
Vec3
>&
forces
=
state
.
getForces
();
double
force
=
0.1
*
3
*
(
2
*
2
);
ASSERT_EQUAL_VEC
(
Vec3
(
-
force
,
0
,
0
),
forces
[
0
],
TOL
);
ASSERT_EQUAL_VEC
(
Vec3
(
force
,
0
,
0
),
forces
[
1
],
TOL
);
ASSERT_EQUAL_TOL
(
-
0.1
*
(
2
*
2
*
2
),
state
.
getPotentialEnergy
(),
TOL
);
}
void
testParameters
()
{
OpenCLPlatform
platform
;
System
system
;
system
.
addParticle
(
1.0
);
system
.
addParticle
(
1.0
);
VerletIntegrator
integrator
(
0.01
);
CustomNonbondedForce
*
forceField
=
new
CustomNonbondedForce
(
"scale*a*(r*b)^3"
);
forceField
->
addParameter
(
"a"
,
"a1*a2"
);
forceField
->
addParameter
(
"b"
,
"c+b1+b2"
);
forceField
->
addGlobalParameter
(
"scale"
,
3.0
);
forceField
->
addGlobalParameter
(
"c"
,
-
1.0
);
vector
<
double
>
params
(
2
);
params
[
0
]
=
1.5
;
params
[
1
]
=
2.0
;
forceField
->
addParticle
(
params
);
params
[
0
]
=
2.0
;
params
[
1
]
=
3.0
;
forceField
->
addParticle
(
params
);
system
.
addForce
(
forceField
);
Context
context
(
system
,
integrator
,
platform
);
vector
<
Vec3
>
positions
(
2
);
positions
[
0
]
=
Vec3
(
0
,
0
,
0
);
positions
[
1
]
=
Vec3
(
2
,
0
,
0
);
context
.
setPositions
(
positions
);
context
.
setParameter
(
"scale"
,
1.0
);
context
.
setParameter
(
"c"
,
0.0
);
State
state
=
context
.
getState
(
State
::
Forces
|
State
::
Energy
);
vector
<
Vec3
>
forces
=
state
.
getForces
();
double
force
=
-
3.0
*
3
*
5.0
*
(
10
*
10
);
ASSERT_EQUAL_VEC
(
Vec3
(
-
force
,
0
,
0
),
forces
[
0
],
TOL
);
ASSERT_EQUAL_VEC
(
Vec3
(
force
,
0
,
0
),
forces
[
1
],
TOL
);
ASSERT_EQUAL_TOL
(
3.0
*
(
10
*
10
*
10
),
state
.
getPotentialEnergy
(),
TOL
);
context
.
setParameter
(
"scale"
,
1.5
);
context
.
setParameter
(
"c"
,
1.0
);
state
=
context
.
getState
(
State
::
Forces
|
State
::
Energy
);
forces
=
state
.
getForces
();
force
=
-
1.5
*
3.0
*
3
*
6.0
*
(
12
*
12
);
ASSERT_EQUAL_VEC
(
Vec3
(
-
force
,
0
,
0
),
forces
[
0
],
TOL
);
ASSERT_EQUAL_VEC
(
Vec3
(
force
,
0
,
0
),
forces
[
1
],
TOL
);
ASSERT_EQUAL_TOL
(
1.5
*
3.0
*
(
12
*
12
*
12
),
state
.
getPotentialEnergy
(),
TOL
);
}
void
testExceptions
()
{
OpenCLPlatform
platform
;
System
system
;
VerletIntegrator
integrator
(
0.01
);
CustomNonbondedForce
*
nonbonded
=
new
CustomNonbondedForce
(
"a*r"
);
nonbonded
->
addParameter
(
"a"
,
"a1+a2"
);
vector
<
double
>
params
(
1
);
vector
<
Vec3
>
positions
(
4
);
for
(
int
i
=
0
;
i
<
4
;
i
++
)
{
system
.
addParticle
(
1.0
);
params
[
0
]
=
i
+
1
;
nonbonded
->
addParticle
(
params
);
positions
[
i
]
=
Vec3
(
i
,
0
,
0
);
}
nonbonded
->
addException
(
0
,
1
,
vector
<
double
>
());
nonbonded
->
addException
(
1
,
2
,
vector
<
double
>
());
nonbonded
->
addException
(
2
,
3
,
vector
<
double
>
());
params
[
0
]
=
0.5
;
nonbonded
->
addException
(
0
,
2
,
params
);
nonbonded
->
addException
(
1
,
3
,
params
);
system
.
addForce
(
nonbonded
);
Context
context
(
system
,
integrator
,
platform
);
context
.
setPositions
(
positions
);
State
state
=
context
.
getState
(
State
::
Forces
|
State
::
Energy
);
const
vector
<
Vec3
>&
forces
=
state
.
getForces
();
ASSERT_EQUAL_VEC
(
Vec3
(
0.5
+
1
+
4
,
0
,
0
),
forces
[
0
],
TOL
);
ASSERT_EQUAL_VEC
(
Vec3
(
0.5
,
0
,
0
),
forces
[
1
],
TOL
);
ASSERT_EQUAL_VEC
(
Vec3
(
-
0.5
,
0
,
0
),
forces
[
2
],
TOL
);
ASSERT_EQUAL_VEC
(
Vec3
(
-
(
0.5
+
1
+
4
),
0
,
0
),
forces
[
3
],
TOL
);
ASSERT_EQUAL_TOL
((
1
+
4
)
*
3
+
0.5
*
2
+
0.5
*
2
,
state
.
getPotentialEnergy
(),
TOL
);
}
void
testCutoff
()
{
OpenCLPlatform
platform
;
System
system
;
system
.
addParticle
(
1.0
);
system
.
addParticle
(
1.0
);
system
.
addParticle
(
1.0
);
VerletIntegrator
integrator
(
0.01
);
CustomNonbondedForce
*
forceField
=
new
CustomNonbondedForce
(
"r"
);
forceField
->
addParticle
(
vector
<
double
>
());
forceField
->
addParticle
(
vector
<
double
>
());
forceField
->
addParticle
(
vector
<
double
>
());
forceField
->
setNonbondedMethod
(
CustomNonbondedForce
::
CutoffNonPeriodic
);
forceField
->
setCutoffDistance
(
2.5
);
system
.
addForce
(
forceField
);
Context
context
(
system
,
integrator
,
platform
);
vector
<
Vec3
>
positions
(
3
);
positions
[
0
]
=
Vec3
(
0
,
0
,
0
);
positions
[
1
]
=
Vec3
(
0
,
2
,
0
);
positions
[
2
]
=
Vec3
(
0
,
3
,
0
);
context
.
setPositions
(
positions
);
State
state
=
context
.
getState
(
State
::
Forces
|
State
::
Energy
);
const
vector
<
Vec3
>&
forces
=
state
.
getForces
();
ASSERT_EQUAL_VEC
(
Vec3
(
0
,
1
,
0
),
forces
[
0
],
TOL
);
ASSERT_EQUAL_VEC
(
Vec3
(
0
,
0
,
0
),
forces
[
1
],
TOL
);
ASSERT_EQUAL_VEC
(
Vec3
(
0
,
-
1
,
0
),
forces
[
2
],
TOL
);
ASSERT_EQUAL_TOL
(
2.0
+
1.0
,
state
.
getPotentialEnergy
(),
TOL
);
}
void
testPeriodic
()
{
OpenCLPlatform
platform
;
System
system
;
system
.
addParticle
(
1.0
);
system
.
addParticle
(
1.0
);
system
.
addParticle
(
1.0
);
VerletIntegrator
integrator
(
0.01
);
CustomNonbondedForce
*
forceField
=
new
CustomNonbondedForce
(
"r"
);
forceField
->
addParticle
(
vector
<
double
>
());
forceField
->
addParticle
(
vector
<
double
>
());
forceField
->
addParticle
(
vector
<
double
>
());
forceField
->
setNonbondedMethod
(
CustomNonbondedForce
::
CutoffPeriodic
);
forceField
->
setCutoffDistance
(
2.0
);
system
.
setPeriodicBoxVectors
(
Vec3
(
4
,
0
,
0
),
Vec3
(
0
,
4
,
0
),
Vec3
(
0
,
0
,
4
));
system
.
addForce
(
forceField
);
Context
context
(
system
,
integrator
,
platform
);
vector
<
Vec3
>
positions
(
3
);
positions
[
0
]
=
Vec3
(
0
,
0
,
0
);
positions
[
1
]
=
Vec3
(
0
,
2.1
,
0
);
positions
[
2
]
=
Vec3
(
0
,
3
,
0
);
context
.
setPositions
(
positions
);
State
state
=
context
.
getState
(
State
::
Forces
|
State
::
Energy
);
const
vector
<
Vec3
>&
forces
=
state
.
getForces
();
ASSERT_EQUAL_VEC
(
Vec3
(
0
,
-
2
,
0
),
forces
[
0
],
TOL
);
ASSERT_EQUAL_VEC
(
Vec3
(
0
,
2
,
0
),
forces
[
1
],
TOL
);
ASSERT_EQUAL_VEC
(
Vec3
(
0
,
0
,
0
),
forces
[
2
],
TOL
);
ASSERT_EQUAL_TOL
(
1.9
+
1
+
0.9
,
state
.
getPotentialEnergy
(),
TOL
);
}
void
testTabulatedFunction
(
bool
interpolating
)
{
OpenCLPlatform
platform
;
System
system
;
system
.
addParticle
(
1.0
);
system
.
addParticle
(
1.0
);
VerletIntegrator
integrator
(
0.01
);
CustomNonbondedForce
*
forceField
=
new
CustomNonbondedForce
(
"fn(r)+1"
);
forceField
->
addParticle
(
vector
<
double
>
());
forceField
->
addParticle
(
vector
<
double
>
());
vector
<
double
>
table
;
for
(
int
i
=
0
;
i
<
21
;
i
++
)
table
.
push_back
(
std
::
sin
(
0.25
*
i
));
forceField
->
addFunction
(
"fn"
,
table
,
1.0
,
6.0
,
interpolating
);
system
.
addForce
(
forceField
);
Context
context
(
system
,
integrator
,
platform
);
vector
<
Vec3
>
positions
(
2
);
positions
[
0
]
=
Vec3
(
0
,
0
,
0
);
double
tol
=
0.01
;
for
(
int
i
=
1
;
i
<
30
;
i
++
)
{
double
x
=
(
7.0
/
30.0
)
*
i
;
positions
[
1
]
=
Vec3
(
x
,
0
,
0
);
context
.
setPositions
(
positions
);
State
state
=
context
.
getState
(
State
::
Forces
|
State
::
Energy
);
const
vector
<
Vec3
>&
forces
=
state
.
getForces
();
double
force
=
(
x
<
1.0
||
x
>
6.0
?
0.0
:
-
std
::
cos
(
x
-
1.0
));
double
energy
=
(
x
<
1.0
||
x
>
6.0
?
0.0
:
std
::
sin
(
x
-
1.0
))
+
1.0
;
ASSERT_EQUAL_VEC
(
Vec3
(
-
force
,
0
,
0
),
forces
[
0
],
0.1
);
ASSERT_EQUAL_VEC
(
Vec3
(
force
,
0
,
0
),
forces
[
1
],
0.1
);
ASSERT_EQUAL_TOL
(
energy
,
state
.
getPotentialEnergy
(),
0.02
);
}
}
int
main
()
{
try
{
testSimpleExpression
();
testParameters
();
testExceptions
();
testCutoff
();
testPeriodic
();
// testTabulatedFunction(true);
// testTabulatedFunction(false);
}
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