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
27ff4f1b
Commit
27ff4f1b
authored
May 15, 2009
by
Peter Eastman
Browse files
Improved how the constraint matrices for C-SHAKE get built
parent
043c7b6c
Changes
3
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
96 additions
and
121 deletions
+96
-121
platforms/cuda/src/kernels/gpu.cpp
platforms/cuda/src/kernels/gpu.cpp
+96
-3
platforms/cuda/src/kernels/gputypes.h
platforms/cuda/src/kernels/gputypes.h
+0
-1
platforms/cuda/src/kernels/kCShake.cu
platforms/cuda/src/kernels/kCShake.cu
+0
-117
No files found.
platforms/cuda/src/kernels/gpu.cpp
View file @
27ff4f1b
...
@@ -48,8 +48,11 @@ using namespace std;
...
@@ -48,8 +48,11 @@ using namespace std;
#include "cudaKernels.h"
#include "cudaKernels.h"
#include "hilbert.h"
#include "hilbert.h"
#include "openmm/OpenMMException.h"
#include "openmm/OpenMMException.h"
#include "jama_svd.h"
using
OpenMM
::
OpenMMException
;
using
OpenMM
::
OpenMMException
;
using
TNT
::
Array2D
;
using
JAMA
::
SVD
;
struct
ShakeCluster
{
struct
ShakeCluster
{
int
centralID
;
int
centralID
;
...
@@ -464,7 +467,7 @@ static void markShakeClusterInvalid(ShakeCluster& cluster, map<int, ShakeCluster
...
@@ -464,7 +467,7 @@ static void markShakeClusterInvalid(ShakeCluster& cluster, map<int, ShakeCluster
}
}
}
}
static
void
findRigidClusters
(
gpuContext
gpu
,
const
vector
<
int
>&
firstAtom
,
const
vector
<
int
>&
secondAtom
,
vector
<
int
>&
constraintIndices
)
static
void
findRigidClusters
(
gpuContext
gpu
,
const
vector
<
int
>&
firstAtom
,
const
vector
<
int
>&
secondAtom
,
const
vector
<
float
>&
invMass1
,
const
vector
<
float
>&
invMass2
,
const
vector
<
float
>&
distance
,
vector
<
int
>&
constraintIndices
)
{
{
vector
<
map
<
int
,
int
>
>
atomConstraints
(
firstAtom
.
size
());
vector
<
map
<
int
,
int
>
>
atomConstraints
(
firstAtom
.
size
());
for
(
int
i
=
0
;
i
<
(
int
)
constraintIndices
.
size
();
i
++
)
{
for
(
int
i
=
0
;
i
<
(
int
)
constraintIndices
.
size
();
i
++
)
{
...
@@ -583,7 +586,97 @@ static void findRigidClusters(gpuContext gpu, const vector<int>& firstAtom, cons
...
@@ -583,7 +586,97 @@ static void findRigidClusters(gpuContext gpu, const vector<int>& firstAtom, cons
while
(
gpu
->
sim
.
clusterShakeBlockSize
<
maxClusterSize
)
while
(
gpu
->
sim
.
clusterShakeBlockSize
<
maxClusterSize
)
gpu
->
sim
.
clusterShakeBlockSize
*=
2
;
gpu
->
sim
.
clusterShakeBlockSize
*=
2
;
psRigidClusterConstraintIndex
->
Upload
();
psRigidClusterConstraintIndex
->
Upload
();
gpu
->
hasInitializedRigidClusters
=
false
;
// Build the inverse coupling matrix for each cluster.
unsigned
int
elementIndex
=
0
;
for
(
unsigned
int
i
=
0
;
i
<
rigidClusters
.
size
();
i
++
)
{
// Compute the constraint coupling matrix for this cluster.
const
vector
<
int
>&
cluster
=
rigidClusters
[
i
];
unsigned
int
size
=
cluster
.
size
();
Array2D
<
double
>
matrix
(
size
,
size
);
for
(
int
j
=
0
;
j
<
(
int
)
size
;
j
++
)
{
for
(
int
k
=
0
;
k
<
(
int
)
size
;
k
++
)
{
if
(
j
==
k
)
{
matrix
[
j
][
j
]
=
1.0
;
continue
;
}
double
scale
;
int
atomj0
=
firstAtom
[
cluster
[
j
]];
int
atomj1
=
secondAtom
[
cluster
[
j
]];
int
atomk0
=
firstAtom
[
cluster
[
k
]];
int
atomk1
=
secondAtom
[
cluster
[
k
]];
int
atoma
,
atomb
;
if
(
atomj0
==
atomk0
)
{
atoma
=
atomj1
;
atomb
=
atomk1
;
scale
=
invMass1
[
cluster
[
j
]]
/
(
invMass1
[
cluster
[
j
]]
+
invMass2
[
cluster
[
j
]]);
}
else
if
(
atomj1
==
atomk1
)
{
atoma
=
atomj0
;
atomb
=
atomk0
;
scale
=
invMass2
[
cluster
[
j
]]
/
(
invMass1
[
cluster
[
j
]]
+
invMass2
[
cluster
[
j
]]);
}
else
if
(
atomj0
==
atomk1
)
{
atoma
=
atomj1
;
atomb
=
atomk0
;
scale
=
invMass1
[
cluster
[
j
]]
/
(
invMass1
[
cluster
[
j
]]
+
invMass2
[
cluster
[
j
]]);
}
else
if
(
atomj1
==
atomk0
)
{
atoma
=
atomj0
;
atomb
=
atomk1
;
scale
=
invMass2
[
cluster
[
j
]]
/
(
invMass1
[
cluster
[
j
]]
+
invMass2
[
cluster
[
j
]]);
}
else
{
matrix
[
j
][
k
]
=
0.0
;
continue
;
// These constraints are not connected.
}
// Find the third constraint forming a triangle with these two.
for
(
int
m
=
0
;
m
<
size
;
m
++
)
{
int
other
=
cluster
[
m
];
if
((
firstAtom
[
other
]
==
atoma
&&
secondAtom
[
other
]
==
atomb
)
||
(
firstAtom
[
other
]
==
atomb
&&
secondAtom
[
other
]
==
atoma
))
{
double
d1
=
distance
[
cluster
[
j
]];
double
d2
=
distance
[
cluster
[
k
]];
double
d3
=
distance
[
other
];
matrix
[
j
][
k
]
=
scale
*
(
d1
*
d1
+
d2
*
d2
-
d3
*
d3
)
/
(
2.0
*
d1
*
d2
);
break
;
}
}
}
}
// Invert it using SVD.
Array2D
<
double
>
u
,
v
;
Array1D
<
double
>
w
;
SVD
<
double
>
svd
(
matrix
);
svd
.
getU
(
u
);
svd
.
getV
(
v
);
svd
.
getSingularValues
(
w
);
double
singularValueCutoff
=
0.01
*
w
[
0
];
for
(
int
j
=
0
;
j
<
(
int
)
size
;
j
++
)
w
[
j
]
=
(
w
[
j
]
<
singularValueCutoff
?
0.0
:
1.0
/
w
[
j
]);
for
(
int
j
=
0
;
j
<
(
int
)
size
;
j
++
)
{
for
(
int
k
=
0
;
k
<
(
int
)
size
;
k
++
)
{
matrix
[
j
][
k
]
=
0.0
;
for
(
int
m
=
0
;
m
<
(
int
)
size
;
m
++
)
matrix
[
j
][
k
]
+=
v
[
j
][
m
]
*
w
[
m
]
*
u
[
k
][
m
];
}
}
// Record the inverted matrix.
(
*
gpu
->
psRigidClusterMatrixIndex
)[
i
]
=
elementIndex
;
for
(
int
j
=
0
;
j
<
(
int
)
size
;
j
++
)
for
(
int
k
=
0
;
k
<
(
int
)
size
;
k
++
)
(
*
gpu
->
psRigidClusterMatrix
)[
elementIndex
++
]
=
(
float
)(
matrix
[
k
][
j
]
*
distance
[
cluster
[
j
]]
/
distance
[
cluster
[
k
]]);
}
(
*
gpu
->
psRigidClusterMatrixIndex
)[
gpu
->
sim
.
rigidClusters
]
=
elementIndex
;
gpu
->
psRigidClusterMatrix
->
Upload
();
gpu
->
psRigidClusterMatrixIndex
->
Upload
();
}
}
extern
"C"
extern
"C"
...
@@ -791,7 +884,7 @@ void gpuSetConstraintParameters(gpuContext gpu, const vector<int>& atom1, const
...
@@ -791,7 +884,7 @@ void gpuSetConstraintParameters(gpuContext gpu, const vector<int>& atom1, const
// Identify rigid clusters of atoms.
// Identify rigid clusters of atoms.
findRigidClusters
(
gpu
,
atom1
,
atom2
,
lincsConstraints
);
findRigidClusters
(
gpu
,
atom1
,
atom2
,
invMass1
,
invMass2
,
distance
,
lincsConstraints
);
// Record the connections between constraints.
// Record the connections between constraints.
...
...
platforms/cuda/src/kernels/gputypes.h
View file @
27ff4f1b
...
@@ -75,7 +75,6 @@ struct _gpuContext {
...
@@ -75,7 +75,6 @@ struct _gpuContext {
bool
bRecalculateBornRadii
;
bool
bRecalculateBornRadii
;
bool
bOutputBufferPerWarp
;
bool
bOutputBufferPerWarp
;
bool
bIncludeGBSA
;
bool
bIncludeGBSA
;
bool
hasInitializedRigidClusters
;
unsigned
long
seed
;
unsigned
long
seed
;
SM_VERSION
sm_version
;
SM_VERSION
sm_version
;
CUDPPHandle
cudpp
;
CUDPPHandle
cudpp
;
...
...
platforms/cuda/src/kernels/kCShake.cu
View file @
27ff4f1b
...
@@ -27,12 +27,9 @@
...
@@ -27,12 +27,9 @@
#include <cuda.h>
#include <cuda.h>
#include <vector_functions.h>
#include <vector_functions.h>
#include <vector>
#include <vector>
#include "jama_svd.h"
#include "gputypes.h"
#include "gputypes.h"
using
namespace
std
;
using
namespace
std
;
using
TNT
::
Array2D
;
using
JAMA
::
SVD
;
static
__constant__
cudaGmxSimulation
cSim
;
static
__constant__
cudaGmxSimulation
cSim
;
...
@@ -204,127 +201,13 @@ __global__ void kApplyCShake_kernel(float4* atomPositions, bool addOldPosition)
...
@@ -204,127 +201,13 @@ __global__ void kApplyCShake_kernel(float4* atomPositions, bool addOldPosition)
cSim
.
pSyncCounter
[
blockIdx
.
x
]
=
-
1
;
cSim
.
pSyncCounter
[
blockIdx
.
x
]
=
-
1
;
}
}
static
void
initInverseMatrices
(
gpuContext
gpu
,
bool
useNewPositions
)
{
// Build the inverse constraint matrix for each cluster.
gpu
->
psPosq4
->
Download
();
gpu
->
psVelm4
->
Download
();
if
(
useNewPositions
)
gpu
->
psPosqP4
->
Download
();
unsigned
int
elementIndex
=
0
;
for
(
unsigned
int
i
=
0
;
i
<
gpu
->
sim
.
rigidClusters
;
i
++
)
{
// Compute the constraint coupling matrix for this cluster.
unsigned
int
startIndex
=
(
*
gpu
->
psRigidClusterConstraintIndex
)[
i
];
unsigned
int
endIndex
=
(
*
gpu
->
psRigidClusterConstraintIndex
)[
i
+
1
];
unsigned
int
size
=
endIndex
-
startIndex
;
vector
<
float3
>
r
(
size
);
for
(
unsigned
int
j
=
0
;
j
<
size
;
j
++
)
{
int2
atoms
=
(
*
gpu
->
psLincsAtoms
)[
startIndex
+
j
];
float4
pos1
,
pos2
;
if
(
useNewPositions
)
{
float4
oldpos1
=
(
*
gpu
->
psPosq4
)[
atoms
.
x
];
float4
oldpos2
=
(
*
gpu
->
psPosq4
)[
atoms
.
y
];
pos1
=
(
*
gpu
->
psPosqP4
)[
atoms
.
x
];
pos2
=
(
*
gpu
->
psPosqP4
)[
atoms
.
y
];
pos1
.
x
+=
oldpos1
.
x
;
pos1
.
y
+=
oldpos1
.
y
;
pos1
.
z
+=
oldpos1
.
z
;
pos2
.
x
+=
oldpos2
.
x
;
pos2
.
y
+=
oldpos2
.
y
;
pos2
.
z
+=
oldpos2
.
z
;
}
else
{
pos1
=
(
*
gpu
->
psPosq4
)[
atoms
.
x
];
pos2
=
(
*
gpu
->
psPosq4
)[
atoms
.
y
];
}
r
[
j
]
=
make_float3
(
pos1
.
x
-
pos2
.
x
,
pos1
.
y
-
pos2
.
y
,
pos1
.
z
-
pos2
.
z
);
float
invLength
=
1.0
f
/
sqrt
(
r
[
j
].
x
*
r
[
j
].
x
+
r
[
j
].
y
*
r
[
j
].
y
+
r
[
j
].
z
*
r
[
j
].
z
);
r
[
j
].
x
*=
invLength
;
r
[
j
].
y
*=
invLength
;
r
[
j
].
z
*=
invLength
;
}
Array2D
<
double
>
matrix
(
size
,
size
);
for
(
int
j
=
0
;
j
<
(
int
)
size
;
j
++
)
{
int2
atomsj
=
(
*
gpu
->
psLincsAtoms
)[
startIndex
+
j
];
for
(
int
k
=
0
;
k
<
(
int
)
size
;
k
++
)
{
int2
atomsk
=
(
*
gpu
->
psLincsAtoms
)[
startIndex
+
k
];
float
invMassj0
=
(
*
gpu
->
psVelm4
)[
atomsj
.
x
].
w
;
float
invMassj1
=
(
*
gpu
->
psVelm4
)[
atomsj
.
y
].
w
;
double
dot
=
r
[
j
].
x
*
r
[
k
].
x
+
r
[
j
].
y
*
r
[
k
].
y
+
r
[
j
].
z
*
r
[
k
].
z
;
if
(
atomsj
.
x
==
atomsk
.
x
)
dot
*=
invMassj0
/
(
invMassj0
+
invMassj1
);
else
if
(
atomsj
.
y
==
atomsk
.
y
)
dot
*=
invMassj1
/
(
invMassj0
+
invMassj1
);
else
if
(
atomsj
.
x
==
atomsk
.
y
)
dot
*=
-
invMassj0
/
(
invMassj0
+
invMassj1
);
else
if
(
atomsj
.
y
==
atomsk
.
x
)
dot
*=
-
invMassj1
/
(
invMassj0
+
invMassj1
);
else
dot
=
0.0
;
matrix
[
j
][
k
]
=
dot
;
}
matrix
[
j
][
j
]
=
1.0
;
}
// Invert it using SVD.
Array2D
<
double
>
u
,
v
;
Array1D
<
double
>
w
;
SVD
<
double
>
svd
(
matrix
);
svd
.
getU
(
u
);
svd
.
getV
(
v
);
svd
.
getSingularValues
(
w
);
double
singularValueCutoff
=
0.01
*
w
[
0
];
for
(
int
j
=
0
;
j
<
(
int
)
size
;
j
++
)
w
[
j
]
=
(
w
[
j
]
<
singularValueCutoff
?
0.0
:
1.0
/
w
[
j
]);
for
(
int
j
=
0
;
j
<
(
int
)
size
;
j
++
)
{
for
(
int
k
=
0
;
k
<
(
int
)
size
;
k
++
)
{
matrix
[
j
][
k
]
=
0.0
;
for
(
int
m
=
0
;
m
<
(
int
)
size
;
m
++
)
matrix
[
j
][
k
]
+=
v
[
j
][
m
]
*
w
[
m
]
*
u
[
k
][
m
];
}
}
// Record the inverted matrix.
(
*
gpu
->
psRigidClusterMatrixIndex
)[
i
]
=
elementIndex
;
for
(
int
j
=
0
;
j
<
(
int
)
size
;
j
++
)
{
float
distance1
=
(
*
gpu
->
psLincsDistance
)[
startIndex
+
j
].
w
;
for
(
int
k
=
0
;
k
<
(
int
)
size
;
k
++
)
{
float
distance2
=
(
*
gpu
->
psLincsDistance
)[
startIndex
+
k
].
w
;
(
*
gpu
->
psRigidClusterMatrix
)[
elementIndex
++
]
=
(
float
)(
matrix
[
k
][
j
]
*
distance1
/
distance2
);
}
}
}
(
*
gpu
->
psRigidClusterMatrixIndex
)[
gpu
->
sim
.
rigidClusters
]
=
elementIndex
;
gpu
->
psRigidClusterMatrix
->
Upload
();
gpu
->
psRigidClusterMatrixIndex
->
Upload
();
}
void
kApplyFirstCShake
(
gpuContext
gpu
)
void
kApplyFirstCShake
(
gpuContext
gpu
)
{
{
// printf("kApplyFirstCShake\n");
// printf("kApplyFirstCShake\n");
if
(
gpu
->
sim
.
lincsConstraints
>
0
)
if
(
gpu
->
sim
.
lincsConstraints
>
0
)
{
{
if
(
!
gpu
->
hasInitializedRigidClusters
)
{
// Build preliminary constraint matrices for use on this call.
initInverseMatrices
(
gpu
,
false
);
}
kApplyCShake_kernel
<<<
gpu
->
sim
.
blocks
,
gpu
->
sim
.
lincs_threads_per_block
,
4
*
gpu
->
sim
.
lincs_threads_per_block
>>>
(
gpu
->
sim
.
pPosqP
,
true
);
kApplyCShake_kernel
<<<
gpu
->
sim
.
blocks
,
gpu
->
sim
.
lincs_threads_per_block
,
4
*
gpu
->
sim
.
lincs_threads_per_block
>>>
(
gpu
->
sim
.
pPosqP
,
true
);
LAUNCHERROR
(
"kApplyCShake"
);
LAUNCHERROR
(
"kApplyCShake"
);
if
(
!
gpu
->
hasInitializedRigidClusters
)
{
// Rebuild the constraint matrices, now that we know all constraints are really satisfied.
initInverseMatrices
(
gpu
,
true
);
gpu
->
hasInitializedRigidClusters
=
true
;
}
}
}
}
}
...
...
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