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
6307eb0d
Unverified
Commit
6307eb0d
authored
May 16, 2019
by
Andy Simmonett
Browse files
Nose-Hoover working on CUDA
parent
799d4b1f
Changes
8
Hide whitespace changes
Inline
Side-by-side
Showing
8 changed files
with
225 additions
and
83 deletions
+225
-83
openmmapi/src/VelocityVerletIntegrator.cpp
openmmapi/src/VelocityVerletIntegrator.cpp
+2
-3
platforms/cuda/include/CudaKernels.h
platforms/cuda/include/CudaKernels.h
+6
-1
platforms/cuda/src/CudaKernels.cpp
platforms/cuda/src/CudaKernels.cpp
+94
-26
platforms/cuda/src/kernels/noseHooverChain.cu
platforms/cuda/src/kernels/noseHooverChain.cu
+83
-49
platforms/cuda/tests/TestCudaNoseHooverThermostat.cpp
platforms/cuda/tests/TestCudaNoseHooverThermostat.cpp
+36
-0
platforms/reference/tests/TestReferenceNoseHooverThermostat.cpp
...rms/reference/tests/TestReferenceNoseHooverThermostat.cpp
+2
-0
tests/TestNoseHooverThermostat.h
tests/TestNoseHooverThermostat.h
+0
-2
wrappers/python/setup.py
wrappers/python/setup.py
+2
-2
No files found.
openmmapi/src/VelocityVerletIntegrator.cpp
View file @
6307eb0d
...
@@ -64,11 +64,10 @@ int VelocityVerletIntegrator::addNoseHooverChainThermostat(System& system, doubl
...
@@ -64,11 +64,10 @@ int VelocityVerletIntegrator::addNoseHooverChainThermostat(System& system, doubl
if
(
context
)
{
if
(
context
)
{
throw
OpenMMException
(
"addNoseHooverChainThermostat cannot be called after binding this integrator to a context."
);
throw
OpenMMException
(
"addNoseHooverChainThermostat cannot be called after binding this integrator to a context."
);
}
}
std
::
vector
<
int
>
mask
,
parents
;
int
nDOF
=
0
;
int
nDOF
=
0
;
int
numForces
=
system
.
getNumForces
();
int
numForces
=
system
.
getNumForces
();
vector
<
int
>
thermostatedParticles
;
std
::
vector
<
int
>
thermostatedParticles
;
vector
<
int
>
parentParticles
;
std
::
vector
<
int
>
parentParticles
;
for
(
int
particle
=
0
;
particle
<
system
.
getNumParticles
();
++
particle
)
{
for
(
int
particle
=
0
;
particle
<
system
.
getNumParticles
();
++
particle
)
{
if
(
system
.
getParticleMass
(
particle
)
>
0
)
{
if
(
system
.
getParticleMass
(
particle
)
>
0
)
{
nDOF
+=
3
;
nDOF
+=
3
;
...
...
platforms/cuda/include/CudaKernels.h
View file @
6307eb0d
...
@@ -1762,9 +1762,14 @@ public:
...
@@ -1762,9 +1762,14 @@ public:
private:
private:
CudaContext
&
cu
;
CudaContext
&
cu
;
CudaArray
scaleFactor
,
chainMasses
,
chainForces
,
heatBathEnergy
;
CudaArray
scaleFactorBuffer
,
kineticEnergyBuffer
,
chainMasses
,
chainForces
,
heatBathEnergy
;
std
::
vector
<
CudaArray
>
masks
;
std
::
map
<
int
,
CUfunction
>
propagateKernels
;
std
::
map
<
int
,
CUfunction
>
propagateKernels
;
CUfunction
reduceEnergyKernel
;
CUfunction
computeHeatBathEnergyKernel
;
CUfunction
computeHeatBathEnergyKernel
;
CUfunction
computeMaskedKineticEnergyKernel
;
CUfunction
scaleVelocitiesKernel
;
CUfunction
zeroEnergyBuffersKernel
;
};
};
/**
/**
...
...
platforms/cuda/src/CudaKernels.cpp
View file @
6307eb0d
...
@@ -57,6 +57,7 @@
...
@@ -57,6 +57,7 @@
#include <cmath>
#include <cmath>
#include <iterator>
#include <iterator>
#include <set>
#include <set>
#include <assert.h>
using namespace OpenMM;
using namespace OpenMM;
using namespace std;
using namespace std;
...
@@ -8365,6 +8366,10 @@ void CudaNoseHooverChainKernel::initialize() {
...
@@ -8365,6 +8366,10 @@ void CudaNoseHooverChainKernel::initialize() {
propagateKernels[5] = cu.getKernel(module, "propagateNoseHooverChain");
propagateKernels[5] = cu.getKernel(module, "propagateNoseHooverChain");
computeHeatBathEnergyKernel = cu.getKernel(module, "computeHeatBathEnergy");
computeHeatBathEnergyKernel = cu.getKernel(module, "computeHeatBathEnergy");
computeMaskedKineticEnergyKernel = cu.getKernel(module, "computeMaskedKineticEnergy");
scaleVelocitiesKernel = cu.getKernel(module, "scaleVelocities");
CUmodule utilities = cu.createModule(CudaKernelSources::vectorOps+CudaKernelSources::utilities);
reduceEnergyKernel = cu.getKernel(utilities, "reduceEnergy");
}
}
double CudaNoseHooverChainKernel::propagateChain(ContextImpl& context, const NoseHooverChain &nhc, double kineticEnergy, double timeStep) {
double CudaNoseHooverChainKernel::propagateChain(ContextImpl& context, const NoseHooverChain &nhc, double kineticEnergy, double timeStep) {
...
@@ -8386,24 +8391,24 @@ double CudaNoseHooverChainKernel::propagateChain(ContextImpl& context, const Nos
...
@@ -8386,24 +8391,24 @@ double CudaNoseHooverChainKernel::propagateChain(ContextImpl& context, const Nos
// We need to upload the CUDA array
// We need to upload the CUDA array
if(useDouble){
if(useDouble){
chainState[chainID].initialize<double2>(cu, chainLength, "chainState" + std::to_string(chainID));
chainState[chainID].initialize<double2>(cu, chainLength, "chainState" + std::to_string(chainID));
std::vector<double2> zeros(chainLength,
{0.
0, 0
.0}
);
std::vector<double2> zeros(chainLength,
make_double2(
0, 0
)
);
chainState[chainID].upload(zeros);
chainState[chainID].upload(zeros
.data()
);
} else {
} else {
chainState[chainID].initialize<float2>(cu, chainLength, "chainState" + std::to_string(chainID));
chainState[chainID].initialize<float2>(cu, chainLength, "chainState" + std::to_string(chainID));
std::vector<float2> zeros(chainLength,
{0.
0, 0
.0}
);
std::vector<float2> zeros(chainLength,
make_float2(
0, 0
)
);
chainState[chainID].upload(zeros);
chainState[chainID].upload(zeros
.data()
);
}
}
}
}
if (!scaleFactor.isInitialized() ||scaleFactor.getSize() == 0) {
if (!scaleFactor
Buffer
.isInitialized() ||scaleFactor
Buffer
.getSize() == 0) {
if(useDouble){
if(useDouble){
std::vector<double> one(1);
std::vector<double> one(1);
scaleFactor.initialize<double>(cu, 1, "scaleFactor");
scaleFactor
Buffer
.initialize<double>(cu, 1, "scaleFactor
Buffer
");
scaleFactor.upload(one);
scaleFactor
Buffer
.upload(one);
} else {
} else {
std::vector<float> one(1);
std::vector<float> one(1);
scaleFactor.initialize<float>(cu, 1, "scaleFactor");
scaleFactor
Buffer
.initialize<float>(cu, 1, "scaleFactor
Buffer
");
scaleFactor.upload(one);
scaleFactor
Buffer
.upload(one);
}
}
}
}
...
@@ -8422,23 +8427,24 @@ double CudaNoseHooverChainKernel::propagateChain(ContextImpl& context, const Nos
...
@@ -8422,23 +8427,24 @@ double CudaNoseHooverChainKernel::propagateChain(ContextImpl& context, const Nos
chainForces.upload(zeros);
chainForces.upload(zeros);
}
}
}
}
double kT = BOLTZ * temperature;
double kT = BOLTZ * temperature;
float kTfloat = (float) kT;
float kTfloat = (float) kT;
float timeStepFloat = (float) timeStep;
float timeStepFloat = (float) timeStep;
float frequencyFloat = (float) frequency;
float frequencyFloat = (float) frequency;
float kineticEnergyFloat = (float) kineticEnergy;
// N.B. We ignore the incoming kineticEnergy and grab it from the device buffer instead
void *args[] = {
void *args[] = {&scaleFactor.getDevicePointer(),
&chainState[chainID].getDevicePointer(),
&kineticEnergyBuffer.getDevicePointer(),
&scaleFactorBuffer.getDevicePointer(),
&chainMasses.getDevicePointer(),
&chainMasses.getDevicePointer(),
&chainForces.getDevicePointer(),
&chainForces.getDevicePointer(),
&chainLength, &numMTS, &numDOFs,
&chainLength, &numMTS, &numDOFs,
&timeStepFloat,
&timeStepFloat,
useDouble ? (void*) &kT : (void*) &kTfloat,
useDouble ? (void*) &kT : (void*) &kTfloat,
&frequencyFloat
,
&frequencyFloat
useDouble ? (void*) &kineticEnergy : (void*) &kineticEnergyFloat, &chainState[chainID].getDevicePointer()
};
};
if (numYS == 1 || numYS == 3 || numYS == 5) {
if (numYS == 1 || numYS == 3 || numYS == 5) {
cu.executeKernel(propagateKernels[numYS], args, 1);
cu.executeKernel(propagateKernels[numYS], args,
1,
1);
} else {
} else {
throw OpenMMException("Number of Yoshida Suzuki time steps has to be 1, 3, or 5.");
throw OpenMMException("Number of Yoshida Suzuki time steps has to be 1, 3, or 5.");
}
}
...
@@ -8481,25 +8487,87 @@ double CudaNoseHooverChainKernel::computeHeatBathEnergy(ContextImpl& context, co
...
@@ -8481,25 +8487,87 @@ double CudaNoseHooverChainKernel::computeHeatBathEnergy(ContextImpl& context, co
useDouble ? (void*) &kT : (void*) & kTfloat,
useDouble ? (void*) &kT : (void*) & kTfloat,
&frequencyFloat, &chainState[chainID].getDevicePointer()};
&frequencyFloat, &chainState[chainID].getDevicePointer()};
cu.executeKernel(computeHeatBathEnergyKernel, args, 1);
cu.executeKernel(computeHeatBathEnergyKernel, args,
1,
1);
void * pinnedBuffer = cu.getPinnedBuffer();
heatBathEnergy.download(pinnedBuffer);
if (useDouble){
if (useDouble){
std::vector<double> energy(1);
return *((double*) pinnedBuffer);
heatBathEnergy.download(energy);
return energy[0];
} else {
} else {
std::vector<float> energy(1);
return *((float*) pinnedBuffer);
heatBathEnergy.download(energy);
return (double) energy[0];
}
}
}
}
double CudaNoseHooverChainKernel::computeMaskedKineticEnergy(ContextImpl& context, const NoseHooverChain &n
oseHooverChain
) {
double CudaNoseHooverChainKernel::computeMaskedKineticEnergy(ContextImpl& context, const NoseHooverChain &n
hc
) {
cu.setAsCurrent();
cu.setAsCurrent();
return 1;
bool useDouble = cu.getUseDoublePrecision() || cu.getUseMixedPrecision();
int chainID = nhc.getDefaultChainID();
const auto & parents = nhc.getParentAtoms();
const auto & thermostatedAtoms = nhc.getThermostatedAtoms();
if (chainID >= masks.size()) masks.resize(chainID+1);
auto nAtoms = cu.getPaddedNumAtoms();
if (!masks[chainID].isInitialized()) {
// We need to upload the CUDA array
std::vector<int> maskVec(nAtoms);
for (int i = 0; i < nAtoms; ++i) maskVec[i] = i;
if (parents.size() ) {
assert(parents.size() == thermostatedAtoms.size());
for ( size_t i = 0; i < parents.size(); ++i) {
int atom = thermostatedAtoms[i];
maskVec[atom] = parents[i];
}
} else {
for ( const auto & atom : thermostatedAtoms) {
maskVec[atom] = -1L;
}
}
// Account for padding in the paddedNumAtoms loops
for(int i = thermostatedAtoms.size(); i < nAtoms; ++i){
maskVec[i] = i;
}
masks[chainID].initialize<int>(cu, nAtoms, "mask" + std::to_string(chainID));
masks[chainID].upload(maskVec);
}
if (masks[chainID].getSize() != nAtoms) {
throw OpenMMException("Number of atoms changed. Cannot be handled by the same Nose-Hoover thermostat.");
}
if (!kineticEnergyBuffer.isInitialized() || kineticEnergyBuffer.getSize() == 0) {
if(useDouble){
std::vector<double> one(1);
kineticEnergyBuffer.initialize<double>(cu, 1, "kineticEnergyBuffer");
kineticEnergyBuffer.upload(one);
} else {
std::vector<float> one(1);
kineticEnergyBuffer.initialize<float>(cu, 1, "kineticEnergyBuffer");
kineticEnergyBuffer.upload(one);
}
}
cu.clearBuffer(cu.getEnergyBuffer());
void *args[] = {&cu.getEnergyBuffer().getDevicePointer(),&nAtoms, &cu.getVelm().getDevicePointer(), &masks[chainID].getDevicePointer()};
cu.executeKernel(computeMaskedKineticEnergyKernel, args, nAtoms);
//taken from CudaContext::reduceEnergy(); the final kinetic energy will live in the kineticEnergy buffer
int bufferSize = cu.getEnergyBuffer().getSize();
int workGroupSize = 512;
void* args2[] = {&cu.getEnergyBuffer().getDevicePointer(), &kineticEnergyBuffer.getDevicePointer(), &bufferSize, &workGroupSize};
cu.executeKernel(reduceEnergyKernel, args2, workGroupSize, workGroupSize, workGroupSize*cu.getEnergyBuffer().getElementSize());
return 0;
}
}
void CudaNoseHooverChainKernel::scaleVelocities(ContextImpl& context, const NoseHooverChain &noseHooverChain, double scaleFactor) {
void CudaNoseHooverChainKernel::scaleVelocities(ContextImpl& context, const NoseHooverChain &nhc, double scaleFactor) {
// For now we assume that the mask info is valid, because computeMaskedKineticEnergy must have been
// called before this kernel. If that ever ceases to be true, some sanity checks are needed here.
cu.setAsCurrent();
auto nAtoms = cu.getPaddedNumAtoms();
int chainID = nhc.getDefaultChainID();
void *args[] = {&scaleFactorBuffer.getDevicePointer(),
&nAtoms, &cu.getVelm().getDevicePointer(), &masks[chainID].getDevicePointer()};
cu.executeKernel(scaleVelocitiesKernel, args, nAtoms);
}
}
void CudaApplyMonteCarloBarostatKernel::initialize(const System& system, const Force& thermostat) {
void CudaApplyMonteCarloBarostatKernel::initialize(const System& system, const Force& thermostat) {
...
...
platforms/cuda/src/kernels/noseHooverChain.cu
View file @
6307eb0d
...
@@ -4,67 +4,101 @@
...
@@ -4,67 +4,101 @@
/**
/**
* Propagate the Nose-Hoover chain with one yoshida-suzuki term
* Propagate the Nose-Hoover chain with one yoshida-suzuki term
*/
*/
extern
"C"
__global__
void
propagateNoseHooverChain
(
real
*
__restrict__
scaleFactor
,
real
*
__restrict__
chainMasses
,
real
*
__restrict__
chainForces
,
extern
"C"
__global__
void
propagateNoseHooverChain
(
mixed2
*
__restrict__
chainData
,
const
mixed
*
__restrict__
energySum
,
mixed
*
__restrict__
scaleFactor
,
mixed
*
__restrict__
chainMasses
,
mixed
*
__restrict__
chainForces
,
int
chainLength
,
int
numMTS
,
int
numDOFs
,
float
timeStep
,
int
chainLength
,
int
numMTS
,
int
numDOFs
,
float
timeStep
,
real
kT
,
float
frequency
,
real
kineticEnergy
,
real2
*
__restrict__
chainData
){
mixed
kT
,
float
frequency
){
mixed
&
scale
=
scaleFactor
[
0
];
real
&
scale
=
scaleFactor
[
0
];
scale
=
(
mixed
)
1
;
scale
=
(
real
)
1
;
const
mixed
&
kineticEnergy
=
energySum
[
0
];
for
(
int
bead
=
0
;
bead
<
chainLength
;
++
bead
)
chainMasses
[
bead
]
=
kT
/
(
frequency
*
frequency
);
if
(
kineticEnergy
<
1e-8
)
return
;
chainMasses
[
0
]
*=
numDOFs
;
for
(
int
bead
=
0
;
bead
<
chainLength
;
++
bead
)
chainMasses
[
bead
]
=
kT
/
(
frequency
*
frequency
);
real
KE2
=
2.0
f
*
kineticEnergy
;
chainMasses
[
0
]
*=
numDOFs
;
real
timeOverMTS
=
timeStep
/
numMTS
;
mixed
KE2
=
2.0
f
*
kineticEnergy
;
chainForces
[
0
]
=
(
KE2
-
numDOFs
*
kT
)
/
chainMasses
[
0
];
mixed
timeOverMTS
=
timeStep
/
numMTS
;
for
(
int
bead
=
0
;
bead
<
chainLength
-
1
;
++
bead
)
{
chainForces
[
0
]
=
(
KE2
-
numDOFs
*
kT
)
/
chainMasses
[
0
];
chainForces
[
bead
+
1
]
=
(
chainMasses
[
bead
]
*
chainData
[
bead
].
y
*
chainData
[
bead
].
y
-
kT
)
/
chainMasses
[
bead
+
1
];
for
(
int
bead
=
0
;
bead
<
chainLength
-
1
;
++
bead
)
{
}
chainForces
[
bead
+
1
]
=
(
chainMasses
[
bead
]
*
chainData
[
bead
].
y
*
chainData
[
bead
].
y
-
kT
)
/
chainMasses
[
bead
+
1
];
for
(
int
mts
=
0
;
mts
<
numMTS
;
++
mts
)
{
}
BEGIN_YS_LOOP
for
(
int
mts
=
0
;
mts
<
numMTS
;
++
mts
)
{
real
wdt
=
ys
*
timeOverMTS
;
BEGIN_YS_LOOP
chainData
[
chainLength
-
1
].
y
+=
0.25
f
*
wdt
*
chainForces
[
chainLength
-
1
];
mixed
wdt
=
ys
*
timeOverMTS
;
for
(
int
bead
=
chainLength
-
2
;
bead
>=
0
;
--
bead
)
{
chainData
[
chainLength
-
1
].
y
+=
0.25
f
*
wdt
*
chainForces
[
chainLength
-
1
];
real
aa
=
exp
(
-
0.125
f
*
wdt
*
chainData
[
bead
+
1
].
y
);
for
(
int
bead
=
chainLength
-
2
;
bead
>=
0
;
--
bead
)
{
chainData
[
bead
].
y
=
aa
*
(
chainData
[
bead
].
y
*
aa
+
0.25
f
*
wdt
*
chainForces
[
bead
]);
mixed
aa
=
EXP
(
-
0.125
f
*
wdt
*
chainData
[
bead
+
1
].
y
);
}
chainData
[
bead
].
y
=
aa
*
(
chainData
[
bead
].
y
*
aa
+
0.25
f
*
wdt
*
chainForces
[
bead
]);
// update particle velocities
}
real
aa
=
exp
(
-
0.5
f
*
wdt
*
chainData
[
0
].
y
);
// update particle velocities
scale
*=
aa
;
mixed
aa
=
EXP
(
-
0.5
f
*
wdt
*
chainData
[
0
].
y
);
// update the thermostat positions
scale
*=
aa
;
for
(
int
bead
=
0
;
bead
<
chainLength
;
++
bead
)
{
// update the thermostat positions
chainData
[
bead
].
x
+=
0.5
f
*
chainData
[
bead
].
y
*
wdt
;
for
(
int
bead
=
0
;
bead
<
chainLength
;
++
bead
)
{
}
chainData
[
bead
].
x
+=
0.5
f
*
chainData
[
bead
].
y
*
wdt
;
// update the forces
}
chainForces
[
0
]
=
(
scale
*
scale
*
KE2
-
numDOFs
*
kT
)
/
chainMasses
[
0
];
// update the forces
// update thermostat velocities
chainForces
[
0
]
=
(
scale
*
scale
*
KE2
-
numDOFs
*
kT
)
/
chainMasses
[
0
];
for
(
int
bead
=
0
;
bead
<
chainLength
-
1
;
++
bead
)
{
// update thermostat velocities
real
aa
=
exp
(
-
0.125
f
*
wdt
*
chainData
[
bead
+
1
].
y
);
for
(
int
bead
=
0
;
bead
<
chainLength
-
1
;
++
bead
)
{
chainData
[
bead
].
y
=
aa
*
(
aa
*
chainData
[
bead
].
y
+
0.25
f
*
wdt
*
chainForces
[
bead
]);
mixed
aa
=
EXP
(
-
0.125
f
*
wdt
*
chainData
[
bead
+
1
].
y
);
chainForces
[
bead
+
1
]
=
(
chainMasses
[
bead
]
*
chainData
[
bead
].
y
*
chainData
[
bead
].
y
-
kT
)
/
chainMasses
[
bead
+
1
];
chainData
[
bead
].
y
=
aa
*
(
aa
*
chainData
[
bead
].
y
+
0.25
f
*
wdt
*
chainForces
[
bead
]);
}
chainForces
[
bead
+
1
]
=
(
chainMasses
[
bead
]
*
chainData
[
bead
].
y
*
chainData
[
bead
].
y
-
kT
)
/
chainMasses
[
bead
+
1
];
chainData
[
chainLength
-
1
].
y
+=
0.25
f
*
wdt
*
chainForces
[
chainLength
-
1
];
}
END_YS_LOOP
chainData
[
chainLength
-
1
].
y
+=
0.25
f
*
wdt
*
chainForces
[
chainLength
-
1
];
}
// MTS loop
END_YS_LOOP
//printf("SCALE %f\n", scale);
}
// MTS loop
}
}
/**
/**
* Compute total (potential + kinetic) energy of the Nose-Hoover beads
* Compute total (potential + kinetic) energy of the Nose-Hoover beads
*/
*/
extern
"C"
__global__
void
computeHeatBathEnergy
(
real
*
__restrict__
heatBathEnergy
,
int
chainLength
,
int
numDOFs
,
extern
"C"
__global__
void
computeHeatBathEnergy
(
mixed
*
__restrict__
heatBathEnergy
,
int
chainLength
,
int
numDOFs
,
real
kT
,
float
frequency
,
real
2
*
__restrict__
chainData
){
mixed
kT
,
float
frequency
,
const
mixed
2
*
__restrict__
chainData
){
real
&
energy
=
heatBathEnergy
[
0
];
mixed
&
energy
=
heatBathEnergy
[
0
];
energy
=
(
real
)
0
;
energy
=
(
mixed
)
0
;
for
(
int
i
=
0
;
i
<
chainLength
;
++
i
)
{
for
(
int
i
=
0
;
i
<
chainLength
;
++
i
)
{
real
prefac
=
i
?
1
:
numDOFs
;
mixed
prefac
=
i
?
1
:
numDOFs
;
real
mass
=
prefac
*
kT
/
(
frequency
*
frequency
);
mixed
mass
=
prefac
*
kT
/
(
frequency
*
frequency
);
real
velocity
=
chainData
[
i
].
y
;
mixed
velocity
=
chainData
[
i
].
y
;
// The kinetic energy of this bead
// The kinetic energy of this bead
energy
+=
0.5
f
*
mass
*
velocity
*
velocity
;
energy
+=
0.5
f
*
mass
*
velocity
*
velocity
;
// The potential energy of this bead
// The potential energy of this bead
real
position
=
chainData
[
i
].
x
;
mixed
position
=
chainData
[
i
].
x
;
energy
+=
prefac
*
kT
*
position
;
energy
+=
prefac
*
kT
*
position
;
}
}
}
}
extern
"C"
__global__
void
computeMaskedKineticEnergy
(
mixed
*
__restrict__
energyBuffer
,
int
paddedNumAtoms
,
const
mixed4
*
__restrict__
velm
,
const
int
*
__restrict__
mask
){
mixed
energy
=
0
;
//energy = 1; return;
for
(
int
index
=
blockIdx
.
x
*
blockDim
.
x
+
threadIdx
.
x
;
index
<
paddedNumAtoms
;
index
+=
blockDim
.
x
*
gridDim
.
x
)
{
mixed4
v
=
velm
[
index
];
mixed
mass
=
v
.
w
==
0
?
0
:
1
/
v
.
w
;
if
(
mask
[
index
]
>=
0
){
const
mixed4
&
vparent
=
velm
[
mask
[
index
]];
mixed
massp
=
vparent
.
w
==
0
?
0
:
1
/
vparent
.
w
;
mass
=
(
massp
+
mass
)
==
0
?
0
:
(
massp
*
mass
)
/
(
massp
+
mass
);
v
.
x
-=
vparent
.
x
;
v
.
y
-=
vparent
.
y
;
v
.
z
-=
vparent
.
z
;
}
energy
+=
0.5
f
*
mass
*
(
v
.
x
*
v
.
x
+
v
.
y
*
v
.
y
+
v
.
z
*
v
.
z
);
}
energyBuffer
[
blockIdx
.
x
*
blockDim
.
x
+
threadIdx
.
x
]
=
energy
;
}
extern
"C"
__global__
void
scaleVelocities
(
mixed
*
__restrict__
scaleFactor
,
int
paddedNumAtoms
,
mixed4
*
__restrict__
velm
,
const
int
*
__restrict__
mask
){
const
mixed
&
scale
=
scaleFactor
[
0
];
for
(
int
index
=
blockIdx
.
x
*
blockDim
.
x
+
threadIdx
.
x
;
index
<
paddedNumAtoms
;
index
+=
blockDim
.
x
*
gridDim
.
x
)
{
mixed4
&
v
=
velm
[
index
];
mixed4
vparent
=
mask
[
index
]
>=
0
?
velm
[
mask
[
index
]]
:
make_mixed4
(
0.0
f
,
0.0
f
,
0.0
f
,
0.0
f
);
mixed
maskedScale
=
mask
[
index
]
==
index
?
1
:
scale
;
v
.
x
=
vparent
.
x
+
maskedScale
*
(
v
.
x
-
vparent
.
x
);
v
.
y
=
vparent
.
y
+
maskedScale
*
(
v
.
y
-
vparent
.
y
);
v
.
z
=
vparent
.
z
+
maskedScale
*
(
v
.
z
-
vparent
.
z
);
}
}
platforms/cuda/tests/TestCudaNoseHooverThermostat.cpp
0 → 100644
View file @
6307eb0d
/* -------------------------------------------------------------------------- *
* 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) 2019 Stanford University and the Authors. *
* Authors: Andreas Krämer and Andrew C. Simmonett *
* 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. *
* -------------------------------------------------------------------------- */
#include "CudaTests.h"
#include "TestNoseHooverThermostat.h"
void
runPlatformTests
()
{
}
platforms/reference/tests/TestReferenceNoseHooverThermostat.cpp
View file @
6307eb0d
...
@@ -33,4 +33,6 @@
...
@@ -33,4 +33,6 @@
#include "TestNoseHooverThermostat.h"
#include "TestNoseHooverThermostat.h"
void
runPlatformTests
()
{
void
runPlatformTests
()
{
testNHCPropagation
();
testPropagateChainConsistentWithPythonReference
();
}
}
tests/TestNoseHooverThermostat.h
View file @
6307eb0d
...
@@ -265,8 +265,6 @@ void runPlatformTests();
...
@@ -265,8 +265,6 @@ void runPlatformTests();
int
main
(
int
argc
,
char
*
argv
[])
{
int
main
(
int
argc
,
char
*
argv
[])
{
try
{
try
{
initializeTests
(
argc
,
argv
);
initializeTests
(
argc
,
argv
);
testNHCPropagation
();
testPropagateChainConsistentWithPythonReference
();
testHarmonicOscillator
();
testHarmonicOscillator
();
bool
constrain
;
bool
constrain
;
constrain
=
false
;
testDimerBox
(
constrain
);
constrain
=
false
;
testDimerBox
(
constrain
);
...
...
wrappers/python/setup.py
View file @
6307eb0d
...
@@ -184,7 +184,7 @@ def buildKeywordDictionary(major_version_num=MAJOR_VERSION_NUM,
...
@@ -184,7 +184,7 @@ def buildKeywordDictionary(major_version_num=MAJOR_VERSION_NUM,
if
not
openmm_lib_path
:
if
not
openmm_lib_path
:
reportError
(
"Set OPENMM_LIB_PATH to point to the lib directory for OpenMM"
)
reportError
(
"Set OPENMM_LIB_PATH to point to the lib directory for OpenMM"
)
extra_compile_args
=
[]
extra_compile_args
=
[
'-std=c++11'
]
extra_link_args
=
[]
extra_link_args
=
[]
if
platform
.
system
()
==
"Windows"
:
if
platform
.
system
()
==
"Windows"
:
define_macros
.
append
(
(
'WIN32'
,
None
)
)
define_macros
.
append
(
(
'WIN32'
,
None
)
)
...
@@ -193,7 +193,7 @@ def buildKeywordDictionary(major_version_num=MAJOR_VERSION_NUM,
...
@@ -193,7 +193,7 @@ def buildKeywordDictionary(major_version_num=MAJOR_VERSION_NUM,
extra_compile_args
.
append
(
'/EHsc'
)
extra_compile_args
.
append
(
'/EHsc'
)
else
:
else
:
if
platform
.
system
()
==
'Darwin'
:
if
platform
.
system
()
==
'Darwin'
:
extra_compile_args
+=
[
'-stdlib=libc++'
,
'-mmacosx-version-min=10.7'
]
extra_compile_args
+=
[
'
-std=c++11
-stdlib=libc++'
,
'-mmacosx-version-min=10.7'
]
extra_link_args
+=
[
'-stdlib=libc++'
,
'-mmacosx-version-min=10.7'
,
'-Wl'
,
'-rpath'
,
openmm_lib_path
]
extra_link_args
+=
[
'-stdlib=libc++'
,
'-mmacosx-version-min=10.7'
,
'-Wl'
,
'-rpath'
,
openmm_lib_path
]
# Hard-code CC and CXX to clang, since gcc/g++ will *not* work with
# Hard-code CC and CXX to clang, since gcc/g++ will *not* work with
# Anaconda, despite the fact that distutils will try to use them.
# Anaconda, despite the fact that distutils will try to use them.
...
...
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