"vscode:/vscode.git/clone" did not exist on "f4c6e598aea0893251fd536b1ed23cbb791e86fe"
Commit 923ccea5 authored by peastman's avatar peastman
Browse files

Merge pull request #765 from swails/stochastic-forces

Make it so that random forces and integrators generate unique seeds each time a Context is made
parents 9972e293 df99352d
...@@ -33,7 +33,6 @@ ...@@ -33,7 +33,6 @@
#include "openmm/Context.h" #include "openmm/Context.h"
#include "openmm/OpenMMException.h" #include "openmm/OpenMMException.h"
#include "openmm/internal/ContextImpl.h" #include "openmm/internal/ContextImpl.h"
#include "openmm/internal/OSRngSeed.h"
#include "openmm/kernels.h" #include "openmm/kernels.h"
#include <limits> #include <limits>
#include <string> #include <string>
...@@ -48,7 +47,7 @@ VariableLangevinIntegrator::VariableLangevinIntegrator(double temperature, doubl ...@@ -48,7 +47,7 @@ VariableLangevinIntegrator::VariableLangevinIntegrator(double temperature, doubl
setFriction(frictionCoeff); setFriction(frictionCoeff);
setErrorTolerance(errorTol); setErrorTolerance(errorTol);
setConstraintTolerance(1e-5); setConstraintTolerance(1e-5);
setRandomNumberSeed(osrngseed()); setRandomNumberSeed(0);
setStepSize(0.0); setStepSize(0.0);
} }
......
...@@ -23,6 +23,7 @@ ...@@ -23,6 +23,7 @@
*/ */
#include "CpuRandom.h" #include "CpuRandom.h"
#include "openmm/internal/OSRngSeed.h"
#include "openmm/OpenMMException.h" #include "openmm/OpenMMException.h"
#include <cmath> #include <cmath>
...@@ -49,9 +50,13 @@ void CpuRandom::initialize(int seed, int numThreads) { ...@@ -49,9 +50,13 @@ void CpuRandom::initialize(int seed, int numThreads) {
nextGaussian.resize(numThreads); nextGaussian.resize(numThreads);
nextGaussianIsValid.resize(numThreads, false); nextGaussianIsValid.resize(numThreads, false);
// Use a quick and dirty RNG to pick seeds for the real random number generator. /* Use a quick and dirty RNG to pick seeds for the real random number generator.
* A random seed of 0 means pick a unique seed
*/
unsigned int r = (unsigned int) seed; unsigned int r = (unsigned int) seed;
if (r == 0)
r = (unsigned int) osrngseed();
for (int i = 0; i < numThreads; i++) { for (int i = 0; i < numThreads; i++) {
r = (1664525*r + 1013904223) & 0xFFFFFFFF; r = (1664525*r + 1013904223) & 0xFFFFFFFF;
threadRandom[i] = new OpenMM_SFMT::SFMT(); threadRandom[i] = new OpenMM_SFMT::SFMT();
......
...@@ -27,6 +27,7 @@ ...@@ -27,6 +27,7 @@
#include "CudaIntegrationUtilities.h" #include "CudaIntegrationUtilities.h"
#include "CudaArray.h" #include "CudaArray.h"
#include "CudaKernelSources.h" #include "CudaKernelSources.h"
#include "openmm/internal/OSRngSeed.h"
#include "openmm/HarmonicAngleForce.h" #include "openmm/HarmonicAngleForce.h"
#include "openmm/VirtualSite.h" #include "openmm/VirtualSite.h"
#include "quern.h" #include "quern.h"
...@@ -858,6 +859,7 @@ void CudaIntegrationUtilities::initRandomNumberGenerator(unsigned int randomNumb ...@@ -858,6 +859,7 @@ void CudaIntegrationUtilities::initRandomNumberGenerator(unsigned int randomNumb
vector<int4> seed(randomSeed->getSize()); vector<int4> seed(randomSeed->getSize());
unsigned int r = randomNumberSeed; unsigned int r = randomNumberSeed;
if (r == 0) r = (unsigned int) osrngseed();
for (int i = 0; i < randomSeed->getSize(); i++) { for (int i = 0; i < randomSeed->getSize(); i++) {
seed[i].x = r = (1664525*r + 1013904223) & 0xFFFFFFFF; seed[i].x = r = (1664525*r + 1013904223) & 0xFFFFFFFF;
seed[i].y = r = (1664525*r + 1013904223) & 0xFFFFFFFF; seed[i].y = r = (1664525*r + 1013904223) & 0xFFFFFFFF;
......
...@@ -36,6 +36,7 @@ ...@@ -36,6 +36,7 @@
#include "openmm/internal/CustomManyParticleForceImpl.h" #include "openmm/internal/CustomManyParticleForceImpl.h"
#include "openmm/internal/CustomNonbondedForceImpl.h" #include "openmm/internal/CustomNonbondedForceImpl.h"
#include "openmm/internal/NonbondedForceImpl.h" #include "openmm/internal/NonbondedForceImpl.h"
#include "openmm/internal/OSRngSeed.h"
#include "CudaBondedUtilities.h" #include "CudaBondedUtilities.h"
#include "CudaExpressionUtilities.h" #include "CudaExpressionUtilities.h"
#include "CudaIntegrationUtilities.h" #include "CudaIntegrationUtilities.h"
...@@ -5967,7 +5968,11 @@ void CudaIntegrateCustomStepKernel::prepareForComputation(ContextImpl& context, ...@@ -5967,7 +5968,11 @@ void CudaIntegrateCustomStepKernel::prepareForComputation(ContextImpl& context,
uniformRandoms = CudaArray::create<float4>(cu, maxUniformRandoms, "uniformRandoms"); uniformRandoms = CudaArray::create<float4>(cu, maxUniformRandoms, "uniformRandoms");
randomSeed = CudaArray::create<int4>(cu, cu.getNumThreadBlocks()*CudaContext::ThreadBlockSize, "randomSeed"); randomSeed = CudaArray::create<int4>(cu, cu.getNumThreadBlocks()*CudaContext::ThreadBlockSize, "randomSeed");
vector<int4> seed(randomSeed->getSize()); vector<int4> seed(randomSeed->getSize());
unsigned int r = integrator.getRandomNumberSeed()+1; int rseed = integrator.getRandomNumberSeed();
// A random seed of 0 means use a unique one
if (rseed == 0)
rseed = osrngseed();
unsigned int r = (unsigned int) (rseed+1);
for (int i = 0; i < randomSeed->getSize(); i++) { for (int i = 0; i < randomSeed->getSize(); i++) {
seed[i].x = r = (1664525*r + 1013904223) & 0xFFFFFFFF; seed[i].x = r = (1664525*r + 1013904223) & 0xFFFFFFFF;
seed[i].y = r = (1664525*r + 1013904223) & 0xFFFFFFFF; seed[i].y = r = (1664525*r + 1013904223) & 0xFFFFFFFF;
......
...@@ -27,6 +27,7 @@ ...@@ -27,6 +27,7 @@
#include "OpenCLIntegrationUtilities.h" #include "OpenCLIntegrationUtilities.h"
#include "OpenCLArray.h" #include "OpenCLArray.h"
#include "OpenCLKernelSources.h" #include "OpenCLKernelSources.h"
#include "openmm/internal/OSRngSeed.h"
#include "openmm/HarmonicAngleForce.h" #include "openmm/HarmonicAngleForce.h"
#include "openmm/VirtualSite.h" #include "openmm/VirtualSite.h"
#include "quern.h" #include "quern.h"
...@@ -1003,6 +1004,8 @@ void OpenCLIntegrationUtilities::initRandomNumberGenerator(unsigned int randomNu ...@@ -1003,6 +1004,8 @@ void OpenCLIntegrationUtilities::initRandomNumberGenerator(unsigned int randomNu
vector<mm_int4> seed(randomSeed->getSize()); vector<mm_int4> seed(randomSeed->getSize());
unsigned int r = randomNumberSeed; unsigned int r = randomNumberSeed;
// A seed of 0 means use a unique one
if (r == 0) r = (unsigned int) osrngseed();
for (int i = 0; i < randomSeed->getSize(); i++) { for (int i = 0; i < randomSeed->getSize(); i++) {
seed[i].x = r = (1664525*r + 1013904223) & 0xFFFFFFFF; seed[i].x = r = (1664525*r + 1013904223) & 0xFFFFFFFF;
seed[i].y = r = (1664525*r + 1013904223) & 0xFFFFFFFF; seed[i].y = r = (1664525*r + 1013904223) & 0xFFFFFFFF;
......
...@@ -36,6 +36,7 @@ ...@@ -36,6 +36,7 @@
#include "openmm/internal/CustomManyParticleForceImpl.h" #include "openmm/internal/CustomManyParticleForceImpl.h"
#include "openmm/internal/CustomNonbondedForceImpl.h" #include "openmm/internal/CustomNonbondedForceImpl.h"
#include "openmm/internal/NonbondedForceImpl.h" #include "openmm/internal/NonbondedForceImpl.h"
#include "openmm/internal/OSRngSeed.h"
#include "OpenCLBondedUtilities.h" #include "OpenCLBondedUtilities.h"
#include "OpenCLExpressionUtilities.h" #include "OpenCLExpressionUtilities.h"
#include "OpenCLIntegrationUtilities.h" #include "OpenCLIntegrationUtilities.h"
...@@ -6200,7 +6201,11 @@ void OpenCLIntegrateCustomStepKernel::prepareForComputation(ContextImpl& context ...@@ -6200,7 +6201,11 @@ void OpenCLIntegrateCustomStepKernel::prepareForComputation(ContextImpl& context
uniformRandoms = OpenCLArray::create<mm_float4>(cl, maxUniformRandoms, "uniformRandoms"); uniformRandoms = OpenCLArray::create<mm_float4>(cl, maxUniformRandoms, "uniformRandoms");
randomSeed = OpenCLArray::create<mm_int4>(cl, cl.getNumThreadBlocks()*OpenCLContext::ThreadBlockSize, "randomSeed"); randomSeed = OpenCLArray::create<mm_int4>(cl, cl.getNumThreadBlocks()*OpenCLContext::ThreadBlockSize, "randomSeed");
vector<mm_int4> seed(randomSeed->getSize()); vector<mm_int4> seed(randomSeed->getSize());
unsigned int r = integrator.getRandomNumberSeed()+1; int rseed = integrator.getRandomNumberSeed();
// A random seed of 0 means use a unique one
if (rseed == 0)
rseed = osrngseed();
unsigned int r = (unsigned int) (rseed+1);
for (int i = 0; i < randomSeed->getSize(); i++) { for (int i = 0; i < randomSeed->getSize(); i++) {
seed[i].x = r = (1664525*r + 1013904223) & 0xFFFFFFFF; seed[i].x = r = (1664525*r + 1013904223) & 0xFFFFFFFF;
seed[i].y = r = (1664525*r + 1013904223) & 0xFFFFFFFF; seed[i].y = r = (1664525*r + 1013904223) & 0xFFFFFFFF;
......
...@@ -24,6 +24,7 @@ ...@@ -24,6 +24,7 @@
// class of shared, static utility methods // class of shared, static utility methods
#include "openmm/internal/OSRngSeed.h"
#include "SimTKOpenMMUtilities.h" #include "SimTKOpenMMUtilities.h"
#include "SimTKOpenMMLog.h" #include "SimTKOpenMMLog.h"
#include "sfmt/SFMT.h" #include "sfmt/SFMT.h"
...@@ -361,7 +362,11 @@ void SimTKOpenMMUtilities::setRandomNumberSeed( uint32_t seed ) { ...@@ -361,7 +362,11 @@ void SimTKOpenMMUtilities::setRandomNumberSeed( uint32_t seed ) {
// --------------------------------------------------------------------------------------- // ---------------------------------------------------------------------------------------
_randomNumberSeed = seed; // If the seed is 0, use a unique seed
if (seed == 0)
_randomNumberSeed = (uint32_t) osrngseed();
else
_randomNumberSeed = seed;
_randomInitialized = false; _randomInitialized = false;
} }
......
...@@ -142,6 +142,10 @@ public: ...@@ -142,6 +142,10 @@ public:
* the other hand, no guarantees are made about the behavior of simulations that use the same seed. * the other hand, no guarantees are made about the behavior of simulations that use the same seed.
* In particular, Platforms are permitted to use non-deterministic algorithms which produce different * In particular, Platforms are permitted to use non-deterministic algorithms which produce different
* results on successive runs, even if those runs were initialized identically. * results on successive runs, even if those runs were initialized identically.
*
* If seed is set to 0 (which is the default value assigned), a unique seed is chosen when a Context
* is created from this Force. This is done to ensure that each Context receives unique random seeds
* without you needing to set them explicitly.
*/ */
void setRandomNumberSeed(int seed) { void setRandomNumberSeed(int seed) {
randomNumberSeed = seed; randomNumberSeed = seed;
......
...@@ -33,7 +33,6 @@ ...@@ -33,7 +33,6 @@
#include "openmm/Context.h" #include "openmm/Context.h"
#include "openmm/OpenMMException.h" #include "openmm/OpenMMException.h"
#include "openmm/internal/ContextImpl.h" #include "openmm/internal/ContextImpl.h"
#include "openmm/internal/OSRngSeed.h"
#include "openmm/DrudeKernels.h" #include "openmm/DrudeKernels.h"
#include <ctime> #include <ctime>
#include <string> #include <string>
...@@ -49,7 +48,7 @@ DrudeLangevinIntegrator::DrudeLangevinIntegrator(double temperature, double fric ...@@ -49,7 +48,7 @@ DrudeLangevinIntegrator::DrudeLangevinIntegrator(double temperature, double fric
setDrudeFriction(drudeFrictionCoeff); setDrudeFriction(drudeFrictionCoeff);
setStepSize(stepSize); setStepSize(stepSize);
setConstraintTolerance(1e-5); setConstraintTolerance(1e-5);
setRandomNumberSeed(osrngseed()); setRandomNumberSeed(0);
} }
void DrudeLangevinIntegrator::initialize(ContextImpl& contextRef) { void DrudeLangevinIntegrator::initialize(ContextImpl& contextRef) {
......
...@@ -155,6 +155,10 @@ public: ...@@ -155,6 +155,10 @@ public:
* the other hand, no guarantees are made about the behavior of simulations that use the same seed. * the other hand, no guarantees are made about the behavior of simulations that use the same seed.
* In particular, Platforms are permitted to use non-deterministic algorithms which produce different * In particular, Platforms are permitted to use non-deterministic algorithms which produce different
* results on successive runs, even if those runs were initialized identically. * results on successive runs, even if those runs were initialized identically.
*
* If seed is set to 0 (which is the default value assigned), a unique seed is chosen when a Context
* is created from this Force. This is done to ensure that each Context receives unique random seeds
* without you needing to set them explicitly.
*/ */
void setRandomNumberSeed(int seed) { void setRandomNumberSeed(int seed) {
randomNumberSeed = seed; randomNumberSeed = seed;
......
...@@ -33,7 +33,6 @@ ...@@ -33,7 +33,6 @@
#include "openmm/Context.h" #include "openmm/Context.h"
#include "openmm/OpenMMException.h" #include "openmm/OpenMMException.h"
#include "openmm/internal/ContextImpl.h" #include "openmm/internal/ContextImpl.h"
#include "openmm/internal/OSRngSeed.h"
#include "openmm/RpmdKernels.h" #include "openmm/RpmdKernels.h"
#include "SimTKOpenMMRealType.h" #include "SimTKOpenMMRealType.h"
#include <cmath> #include <cmath>
...@@ -48,7 +47,7 @@ RPMDIntegrator::RPMDIntegrator(int numCopies, double temperature, double frictio ...@@ -48,7 +47,7 @@ RPMDIntegrator::RPMDIntegrator(int numCopies, double temperature, double frictio
setFriction(frictionCoeff); setFriction(frictionCoeff);
setStepSize(stepSize); setStepSize(stepSize);
setConstraintTolerance(1e-5); setConstraintTolerance(1e-5);
setRandomNumberSeed(osrngseed()); setRandomNumberSeed(0);
} }
RPMDIntegrator::RPMDIntegrator(int numCopies, double temperature, double frictionCoeff, double stepSize) : RPMDIntegrator::RPMDIntegrator(int numCopies, double temperature, double frictionCoeff, double stepSize) :
...@@ -57,7 +56,7 @@ RPMDIntegrator::RPMDIntegrator(int numCopies, double temperature, double frictio ...@@ -57,7 +56,7 @@ RPMDIntegrator::RPMDIntegrator(int numCopies, double temperature, double frictio
setFriction(frictionCoeff); setFriction(frictionCoeff);
setStepSize(stepSize); setStepSize(stepSize);
setConstraintTolerance(1e-5); setConstraintTolerance(1e-5);
setRandomNumberSeed(osrngseed()); setRandomNumberSeed(0);
} }
void RPMDIntegrator::initialize(ContextImpl& contextRef) { void RPMDIntegrator::initialize(ContextImpl& contextRef) {
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment