Unverified Commit 78902bed authored by Peter Eastman's avatar Peter Eastman Committed by GitHub
Browse files

Optimize updateParametersInContext() (#4610)

* Optimize CustomNonbondedForce.updateParametersInContext()

* Optimized uploading changed values to GPU

* Optimized updateParametersInContext() for lots of bonded forces

* Optimized updateParametersInContext() for CustomExternalForce

* Optimized updateParametersInContext() for NonbondedForce

* Code changes for HIP platform
parent 66064fac
...@@ -6,7 +6,7 @@ ...@@ -6,7 +6,7 @@
* Biological Structures at Stanford, funded under the NIH Roadmap for * * Biological Structures at Stanford, funded under the NIH Roadmap for *
* Medical Research, grant U54 GM072970. See https://simtk.org. * * Medical Research, grant U54 GM072970. See https://simtk.org. *
* * * *
* Portions copyright (c) 2010-2021 Stanford University and the Authors. * * Portions copyright (c) 2010-2024 Stanford University and the Authors. *
* Authors: Peter Eastman * * Authors: Peter Eastman *
* Contributors: * * Contributors: *
* * * *
...@@ -97,7 +97,7 @@ map<string, double> CustomAngleForceImpl::getDefaultParameters() { ...@@ -97,7 +97,7 @@ map<string, double> CustomAngleForceImpl::getDefaultParameters() {
return parameters; return parameters;
} }
void CustomAngleForceImpl::updateParametersInContext(ContextImpl& context) { void CustomAngleForceImpl::updateParametersInContext(ContextImpl& context, int firstAngle, int lastAngle) {
kernel.getAs<CalcCustomAngleForceKernel>().copyParametersToContext(context, owner); kernel.getAs<CalcCustomAngleForceKernel>().copyParametersToContext(context, owner, firstAngle, lastAngle);
context.systemChanged(); context.systemChanged();
} }
...@@ -6,7 +6,7 @@ ...@@ -6,7 +6,7 @@
* Biological Structures at Stanford, funded under the NIH Roadmap for * * Biological Structures at Stanford, funded under the NIH Roadmap for *
* Medical Research, grant U54 GM072970. See https://simtk.org. * * Medical Research, grant U54 GM072970. See https://simtk.org. *
* * * *
* Portions copyright (c) 2008-2016 Stanford University and the Authors. * * Portions copyright (c) 2008-2024 Stanford University and the Authors. *
* Authors: Peter Eastman * * Authors: Peter Eastman *
* Contributors: * * Contributors: *
* * * *
...@@ -40,11 +40,9 @@ ...@@ -40,11 +40,9 @@
#include <utility> #include <utility>
using namespace OpenMM; using namespace OpenMM;
using std::string; using namespace std;
using std::stringstream;
using std::vector;
CustomBondForce::CustomBondForce(const string& energy) : energyExpression(energy), usePeriodic(false) { CustomBondForce::CustomBondForce(const string& energy) : energyExpression(energy), usePeriodic(false), numContexts(0) {
} }
const string& CustomBondForce::getEnergyFunction() const { const string& CustomBondForce::getEnergyFunction() const {
...@@ -126,14 +124,30 @@ void CustomBondForce::setBondParameters(int index, int particle1, int particle2, ...@@ -126,14 +124,30 @@ void CustomBondForce::setBondParameters(int index, int particle1, int particle2,
bonds[index].parameters = parameters; bonds[index].parameters = parameters;
bonds[index].particle1 = particle1; bonds[index].particle1 = particle1;
bonds[index].particle2 = particle2; bonds[index].particle2 = particle2;
if (numContexts > 0) {
firstChangedBond = min(index, firstChangedBond);
lastChangedBond = max(index, lastChangedBond);
}
} }
ForceImpl* CustomBondForce::createImpl() const { ForceImpl* CustomBondForce::createImpl() const {
if (numContexts == 0) {
// Begin tracking changes to bonds.
firstChangedBond = bonds.size();
lastChangedBond = -1;
}
numContexts++;
return new CustomBondForceImpl(*this); return new CustomBondForceImpl(*this);
} }
void CustomBondForce::updateParametersInContext(Context& context) { void CustomBondForce::updateParametersInContext(Context& context) {
dynamic_cast<CustomBondForceImpl&>(getImplInContext(context)).updateParametersInContext(getContextImpl(context)); dynamic_cast<CustomBondForceImpl&>(getImplInContext(context)).updateParametersInContext(getContextImpl(context), firstChangedBond, lastChangedBond);
if (numContexts == 1) {
// We just updated the only existing context for this force, so we can reset
// the tracking of changed bonds.
firstChangedBond = bonds.size();
lastChangedBond = -1;
}
} }
void CustomBondForce::setUsesPeriodicBoundaryConditions(bool periodic) { void CustomBondForce::setUsesPeriodicBoundaryConditions(bool periodic) {
......
...@@ -6,7 +6,7 @@ ...@@ -6,7 +6,7 @@
* Biological Structures at Stanford, funded under the NIH Roadmap for * * Biological Structures at Stanford, funded under the NIH Roadmap for *
* Medical Research, grant U54 GM072970. See https://simtk.org. * * Medical Research, grant U54 GM072970. See https://simtk.org. *
* * * *
* Portions copyright (c) 2008-2021 Stanford University and the Authors. * * Portions copyright (c) 2008-2024 Stanford University and the Authors. *
* Authors: Peter Eastman * * Authors: Peter Eastman *
* Contributors: * * Contributors: *
* * * *
...@@ -108,7 +108,7 @@ vector<pair<int, int> > CustomBondForceImpl::getBondedParticles() const { ...@@ -108,7 +108,7 @@ vector<pair<int, int> > CustomBondForceImpl::getBondedParticles() const {
return bonds; return bonds;
} }
void CustomBondForceImpl::updateParametersInContext(ContextImpl& context) { void CustomBondForceImpl::updateParametersInContext(ContextImpl& context, int firstBond, int lastBond) {
kernel.getAs<CalcCustomBondForceKernel>().copyParametersToContext(context, owner); kernel.getAs<CalcCustomBondForceKernel>().copyParametersToContext(context, owner, firstBond, lastBond);
context.systemChanged(); context.systemChanged();
} }
...@@ -6,7 +6,7 @@ ...@@ -6,7 +6,7 @@
* Biological Structures at Stanford, funded under the NIH Roadmap for * * Biological Structures at Stanford, funded under the NIH Roadmap for *
* Medical Research, grant U54 GM072970. See https://simtk.org. * * Medical Research, grant U54 GM072970. See https://simtk.org. *
* * * *
* Portions copyright (c) 2008-2012 Stanford University and the Authors. * * Portions copyright (c) 2008-2024 Stanford University and the Authors. *
* Authors: Peter Eastman * * Authors: Peter Eastman *
* Contributors: * * Contributors: *
* * * *
...@@ -40,11 +40,9 @@ ...@@ -40,11 +40,9 @@
#include <utility> #include <utility>
using namespace OpenMM; using namespace OpenMM;
using std::string; using namespace std;
using std::stringstream;
using std::vector;
CustomExternalForce::CustomExternalForce(const string& energy) : energyExpression(energy) { CustomExternalForce::CustomExternalForce(const string& energy) : energyExpression(energy), numContexts(0) {
} }
const string& CustomExternalForce::getEnergyFunction() const { const string& CustomExternalForce::getEnergyFunction() const {
...@@ -110,14 +108,29 @@ void CustomExternalForce::setParticleParameters(int index, int particle, const v ...@@ -110,14 +108,29 @@ void CustomExternalForce::setParticleParameters(int index, int particle, const v
ASSERT_VALID_INDEX(index, particles); ASSERT_VALID_INDEX(index, particles);
particles[index].parameters = parameters; particles[index].parameters = parameters;
particles[index].particle = particle; particles[index].particle = particle;
if (numContexts > 0) {
firstChangedParticle = min(index, firstChangedParticle);
lastChangedParticle = max(index, lastChangedParticle);
}
} }
ForceImpl* CustomExternalForce::createImpl() const { ForceImpl* CustomExternalForce::createImpl() const {
return new CustomExternalForceImpl(*this); if (numContexts == 0) {
// Begin tracking changes to particles.
firstChangedParticle = particles.size();
lastChangedParticle = -1;
}
numContexts++; return new CustomExternalForceImpl(*this);
} }
void CustomExternalForce::updateParametersInContext(Context& context) { void CustomExternalForce::updateParametersInContext(Context& context) {
dynamic_cast<CustomExternalForceImpl&>(getImplInContext(context)).updateParametersInContext(getContextImpl(context)); dynamic_cast<CustomExternalForceImpl&>(getImplInContext(context)).updateParametersInContext(getContextImpl(context), firstChangedParticle, lastChangedParticle);
if (numContexts == 1) {
// We just updated the only existing context for this force, so we can reset
// the tracking of changed particles.
firstChangedParticle = particles.size();
lastChangedParticle = -1;
}
} }
bool CustomExternalForce::usesPeriodicBoundaryConditions() const { bool CustomExternalForce::usesPeriodicBoundaryConditions() const {
......
...@@ -96,7 +96,7 @@ map<string, double> CustomExternalForceImpl::getDefaultParameters() { ...@@ -96,7 +96,7 @@ map<string, double> CustomExternalForceImpl::getDefaultParameters() {
return parameters; return parameters;
} }
void CustomExternalForceImpl::updateParametersInContext(ContextImpl& context) { void CustomExternalForceImpl::updateParametersInContext(ContextImpl& context, int firstParticle, int lastParticle) {
kernel.getAs<CalcCustomExternalForceKernel>().copyParametersToContext(context, owner); kernel.getAs<CalcCustomExternalForceKernel>().copyParametersToContext(context, owner, firstParticle, lastParticle);
context.systemChanged(); context.systemChanged();
} }
...@@ -6,7 +6,7 @@ ...@@ -6,7 +6,7 @@
* Biological Structures at Stanford, funded under the NIH Roadmap for * * Biological Structures at Stanford, funded under the NIH Roadmap for *
* Medical Research, grant U54 GM072970. See https://simtk.org. * * Medical Research, grant U54 GM072970. See https://simtk.org. *
* * * *
* Portions copyright (c) 2008-2022 Stanford University and the Authors. * * Portions copyright (c) 2008-2024 Stanford University and the Authors. *
* Authors: Peter Eastman * * Authors: Peter Eastman *
* Contributors: * * Contributors: *
* * * *
...@@ -40,18 +40,13 @@ ...@@ -40,18 +40,13 @@
#include <utility> #include <utility>
using namespace OpenMM; using namespace OpenMM;
using std::map; using namespace std;
using std::pair;
using std::set;
using std::string;
using std::stringstream;
using std::vector;
CustomNonbondedForce::CustomNonbondedForce(const string& energy) : energyExpression(energy), nonbondedMethod(NoCutoff), cutoffDistance(1.0), CustomNonbondedForce::CustomNonbondedForce(const string& energy) : energyExpression(energy), nonbondedMethod(NoCutoff), cutoffDistance(1.0),
switchingDistance(-1.0), useSwitchingFunction(false), useLongRangeCorrection(false) { switchingDistance(-1.0), useSwitchingFunction(false), useLongRangeCorrection(false), numContexts(0) {
} }
CustomNonbondedForce::CustomNonbondedForce(const CustomNonbondedForce& rhs) { CustomNonbondedForce::CustomNonbondedForce(const CustomNonbondedForce& rhs) : numContexts(0) {
// Copy everything and deep copy the tabulated functions // Copy everything and deep copy the tabulated functions
setForceGroup(rhs.getForceGroup()); setForceGroup(rhs.getForceGroup());
setName(rhs.getName()); setName(rhs.getName());
...@@ -194,6 +189,10 @@ void CustomNonbondedForce::getParticleParameters(int index, std::vector<double>& ...@@ -194,6 +189,10 @@ void CustomNonbondedForce::getParticleParameters(int index, std::vector<double>&
void CustomNonbondedForce::setParticleParameters(int index, const vector<double>& parameters) { void CustomNonbondedForce::setParticleParameters(int index, const vector<double>& parameters) {
ASSERT_VALID_INDEX(index, particles); ASSERT_VALID_INDEX(index, particles);
particles[index].parameters = parameters; particles[index].parameters = parameters;
if (numContexts > 0) {
firstChangedParticle = min(index, firstChangedParticle);
lastChangedParticle = max(index, lastChangedParticle);
}
} }
int CustomNonbondedForce::addExclusion(int particle1, int particle2) { int CustomNonbondedForce::addExclusion(int particle1, int particle2) {
...@@ -326,9 +325,21 @@ void CustomNonbondedForce::setInteractionGroupParameters(int index, const std::s ...@@ -326,9 +325,21 @@ void CustomNonbondedForce::setInteractionGroupParameters(int index, const std::s
} }
ForceImpl* CustomNonbondedForce::createImpl() const { ForceImpl* CustomNonbondedForce::createImpl() const {
if (numContexts == 0) {
// Begin tracking changes to particles.
firstChangedParticle = particles.size();
lastChangedParticle = -1;
}
numContexts++;
return new CustomNonbondedForceImpl(*this); return new CustomNonbondedForceImpl(*this);
} }
void CustomNonbondedForce::updateParametersInContext(Context& context) { void CustomNonbondedForce::updateParametersInContext(Context& context) {
dynamic_cast<CustomNonbondedForceImpl&>(getImplInContext(context)).updateParametersInContext(getContextImpl(context)); dynamic_cast<CustomNonbondedForceImpl&>(getImplInContext(context)).updateParametersInContext(getContextImpl(context), firstChangedParticle, lastChangedParticle);
if (numContexts == 1) {
// We just updated the only existing context for this force, so we can reset
// the tracking of changed particles.
firstChangedParticle = particles.size();
lastChangedParticle = -1;
}
} }
...@@ -159,8 +159,8 @@ map<string, double> CustomNonbondedForceImpl::getDefaultParameters() { ...@@ -159,8 +159,8 @@ map<string, double> CustomNonbondedForceImpl::getDefaultParameters() {
return parameters; return parameters;
} }
void CustomNonbondedForceImpl::updateParametersInContext(ContextImpl& context) { void CustomNonbondedForceImpl::updateParametersInContext(ContextImpl& context, int firstParticle, int lastParticle) {
kernel.getAs<CalcCustomNonbondedForceKernel>().copyParametersToContext(context, owner); kernel.getAs<CalcCustomNonbondedForceKernel>().copyParametersToContext(context, owner, firstParticle, lastParticle);
context.systemChanged(); context.systemChanged();
} }
......
...@@ -6,7 +6,7 @@ ...@@ -6,7 +6,7 @@
* Biological Structures at Stanford, funded under the NIH Roadmap for * * Biological Structures at Stanford, funded under the NIH Roadmap for *
* Medical Research, grant U54 GM072970. See https://simtk.org. * * Medical Research, grant U54 GM072970. See https://simtk.org. *
* * * *
* Portions copyright (c) 2010-2016 Stanford University and the Authors. * * Portions copyright (c) 2010-2024 Stanford University and the Authors. *
* Authors: Peter Eastman * * Authors: Peter Eastman *
* Contributors: * * Contributors: *
* * * *
...@@ -40,11 +40,9 @@ ...@@ -40,11 +40,9 @@
#include <utility> #include <utility>
using namespace OpenMM; using namespace OpenMM;
using std::string; using namespace std;
using std::stringstream;
using std::vector;
CustomTorsionForce::CustomTorsionForce(const string& energy) : energyExpression(energy), usePeriodic(false) { CustomTorsionForce::CustomTorsionForce(const string& energy) : energyExpression(energy), usePeriodic(false), numContexts(0) {
} }
const string& CustomTorsionForce::getEnergyFunction() const { const string& CustomTorsionForce::getEnergyFunction() const {
...@@ -130,14 +128,30 @@ void CustomTorsionForce::setTorsionParameters(int index, int particle1, int part ...@@ -130,14 +128,30 @@ void CustomTorsionForce::setTorsionParameters(int index, int particle1, int part
torsions[index].particle2 = particle2; torsions[index].particle2 = particle2;
torsions[index].particle3 = particle3; torsions[index].particle3 = particle3;
torsions[index].particle4 = particle4; torsions[index].particle4 = particle4;
if (numContexts > 0) {
firstChangedTorsion = min(index, firstChangedTorsion);
lastChangedTorsion = max(index, lastChangedTorsion);
}
} }
ForceImpl* CustomTorsionForce::createImpl() const { ForceImpl* CustomTorsionForce::createImpl() const {
if (numContexts == 0) {
// Begin tracking changes to torsions.
firstChangedTorsion = torsions.size();
lastChangedTorsion = -1;
}
numContexts++;
return new CustomTorsionForceImpl(*this); return new CustomTorsionForceImpl(*this);
} }
void CustomTorsionForce::updateParametersInContext(Context& context) { void CustomTorsionForce::updateParametersInContext(Context& context) {
dynamic_cast<CustomTorsionForceImpl&>(getImplInContext(context)).updateParametersInContext(getContextImpl(context)); dynamic_cast<CustomTorsionForceImpl&>(getImplInContext(context)).updateParametersInContext(getContextImpl(context), firstChangedTorsion, lastChangedTorsion);
if (numContexts == 1) {
// We just updated the only existing context for this force, so we can reset
// the tracking of changed torsions.
firstChangedTorsion = torsions.size();
lastChangedTorsion = -1;
}
} }
void CustomTorsionForce::setUsesPeriodicBoundaryConditions(bool periodic) { void CustomTorsionForce::setUsesPeriodicBoundaryConditions(bool periodic) {
......
...@@ -6,7 +6,7 @@ ...@@ -6,7 +6,7 @@
* Biological Structures at Stanford, funded under the NIH Roadmap for * * Biological Structures at Stanford, funded under the NIH Roadmap for *
* Medical Research, grant U54 GM072970. See https://simtk.org. * * Medical Research, grant U54 GM072970. See https://simtk.org. *
* * * *
* Portions copyright (c) 2010-2012 Stanford University and the Authors. * * Portions copyright (c) 2010-2024 Stanford University and the Authors. *
* Authors: Peter Eastman * * Authors: Peter Eastman *
* Contributors: * * Contributors: *
* * * *
...@@ -98,7 +98,7 @@ map<string, double> CustomTorsionForceImpl::getDefaultParameters() { ...@@ -98,7 +98,7 @@ map<string, double> CustomTorsionForceImpl::getDefaultParameters() {
return parameters; return parameters;
} }
void CustomTorsionForceImpl::updateParametersInContext(ContextImpl& context) { void CustomTorsionForceImpl::updateParametersInContext(ContextImpl& context, int firstTorsion, int lastTorsion) {
kernel.getAs<CalcCustomTorsionForceKernel>().copyParametersToContext(context, owner); kernel.getAs<CalcCustomTorsionForceKernel>().copyParametersToContext(context, owner, firstTorsion, lastTorsion);
context.systemChanged(); context.systemChanged();
} }
...@@ -6,7 +6,7 @@ ...@@ -6,7 +6,7 @@
* Biological Structures at Stanford, funded under the NIH Roadmap for * * Biological Structures at Stanford, funded under the NIH Roadmap for *
* Medical Research, grant U54 GM072970. See https://simtk.org. * * Medical Research, grant U54 GM072970. See https://simtk.org. *
* * * *
* Portions copyright (c) 2008-2016 Stanford University and the Authors. * * Portions copyright (c) 2008-2024 Stanford University and the Authors. *
* Authors: Peter Eastman * * Authors: Peter Eastman *
* Contributors: * * Contributors: *
* * * *
...@@ -36,8 +36,9 @@ ...@@ -36,8 +36,9 @@
#include "openmm/internal/HarmonicAngleForceImpl.h" #include "openmm/internal/HarmonicAngleForceImpl.h"
using namespace OpenMM; using namespace OpenMM;
using namespace std;
HarmonicAngleForce::HarmonicAngleForce() : usePeriodic(false) { HarmonicAngleForce::HarmonicAngleForce() : usePeriodic(false), numContexts(0) {
} }
int HarmonicAngleForce::addAngle(int particle1, int particle2, int particle3, double angle, double k) { int HarmonicAngleForce::addAngle(int particle1, int particle2, int particle3, double angle, double k) {
...@@ -61,14 +62,30 @@ void HarmonicAngleForce::setAngleParameters(int index, int particle1, int partic ...@@ -61,14 +62,30 @@ void HarmonicAngleForce::setAngleParameters(int index, int particle1, int partic
angles[index].particle3 = particle3; angles[index].particle3 = particle3;
angles[index].angle = angle; angles[index].angle = angle;
angles[index].k = k; angles[index].k = k;
if (numContexts > 0) {
firstChangedAngle = min(index, firstChangedAngle);
lastChangedAngle = max(index, lastChangedAngle);
}
} }
ForceImpl* HarmonicAngleForce::createImpl() const { ForceImpl* HarmonicAngleForce::createImpl() const {
if (numContexts == 0) {
// Begin tracking changes to angles.
firstChangedAngle = angles.size();
lastChangedAngle = -1;
}
numContexts++;
return new HarmonicAngleForceImpl(*this); return new HarmonicAngleForceImpl(*this);
} }
void HarmonicAngleForce::updateParametersInContext(Context& context) { void HarmonicAngleForce::updateParametersInContext(Context& context) {
dynamic_cast<HarmonicAngleForceImpl&>(getImplInContext(context)).updateParametersInContext(getContextImpl(context)); dynamic_cast<HarmonicAngleForceImpl&>(getImplInContext(context)).updateParametersInContext(getContextImpl(context), firstChangedAngle, lastChangedAngle);
if (numContexts == 1) {
// We just updated the only existing context for this force, so we can reset
// the tracking of changed angles.
firstChangedAngle = angles.size();
lastChangedAngle = -1;
}
} }
void HarmonicAngleForce::setUsesPeriodicBoundaryConditions(bool periodic) { void HarmonicAngleForce::setUsesPeriodicBoundaryConditions(bool periodic) {
......
...@@ -6,7 +6,7 @@ ...@@ -6,7 +6,7 @@
* Biological Structures at Stanford, funded under the NIH Roadmap for * * Biological Structures at Stanford, funded under the NIH Roadmap for *
* Medical Research, grant U54 GM072970. See https://simtk.org. * * Medical Research, grant U54 GM072970. See https://simtk.org. *
* * * *
* Portions copyright (c) 2008-2021 Stanford University and the Authors. * * Portions copyright (c) 2008-2024 Stanford University and the Authors. *
* Authors: Peter Eastman * * Authors: Peter Eastman *
* Contributors: * * Contributors: *
* * * *
...@@ -82,7 +82,7 @@ std::vector<std::string> HarmonicAngleForceImpl::getKernelNames() { ...@@ -82,7 +82,7 @@ std::vector<std::string> HarmonicAngleForceImpl::getKernelNames() {
return names; return names;
} }
void HarmonicAngleForceImpl::updateParametersInContext(ContextImpl& context) { void HarmonicAngleForceImpl::updateParametersInContext(ContextImpl& context, int firstAngle, int lastAngle) {
kernel.getAs<CalcHarmonicAngleForceKernel>().copyParametersToContext(context, owner); kernel.getAs<CalcHarmonicAngleForceKernel>().copyParametersToContext(context, owner, firstAngle, lastAngle);
context.systemChanged(); context.systemChanged();
} }
...@@ -6,7 +6,7 @@ ...@@ -6,7 +6,7 @@
* Biological Structures at Stanford, funded under the NIH Roadmap for * * Biological Structures at Stanford, funded under the NIH Roadmap for *
* Medical Research, grant U54 GM072970. See https://simtk.org. * * Medical Research, grant U54 GM072970. See https://simtk.org. *
* * * *
* Portions copyright (c) 2008-2012 Stanford University and the Authors. * * Portions copyright (c) 2008-2024 Stanford University and the Authors. *
* Authors: Peter Eastman * * Authors: Peter Eastman *
* Contributors: * * Contributors: *
* * * *
...@@ -36,8 +36,9 @@ ...@@ -36,8 +36,9 @@
#include "openmm/internal/HarmonicBondForceImpl.h" #include "openmm/internal/HarmonicBondForceImpl.h"
using namespace OpenMM; using namespace OpenMM;
using namespace std;
HarmonicBondForce::HarmonicBondForce() : usePeriodic(false) { HarmonicBondForce::HarmonicBondForce() : usePeriodic(false), numContexts(0) {
} }
int HarmonicBondForce::addBond(int particle1, int particle2, double length, double k) { int HarmonicBondForce::addBond(int particle1, int particle2, double length, double k) {
...@@ -59,14 +60,30 @@ void HarmonicBondForce::setBondParameters(int index, int particle1, int particle ...@@ -59,14 +60,30 @@ void HarmonicBondForce::setBondParameters(int index, int particle1, int particle
bonds[index].particle2 = particle2; bonds[index].particle2 = particle2;
bonds[index].length = length; bonds[index].length = length;
bonds[index].k = k; bonds[index].k = k;
if (numContexts > 0) {
firstChangedBond = min(index, firstChangedBond);
lastChangedBond = max(index, lastChangedBond);
}
} }
ForceImpl* HarmonicBondForce::createImpl() const { ForceImpl* HarmonicBondForce::createImpl() const {
if (numContexts == 0) {
// Begin tracking changes to bonds.
firstChangedBond = bonds.size();
lastChangedBond = -1;
}
numContexts++;
return new HarmonicBondForceImpl(*this); return new HarmonicBondForceImpl(*this);
} }
void HarmonicBondForce::updateParametersInContext(Context& context) { void HarmonicBondForce::updateParametersInContext(Context& context) {
dynamic_cast<HarmonicBondForceImpl&>(getImplInContext(context)).updateParametersInContext(getContextImpl(context)); dynamic_cast<HarmonicBondForceImpl&>(getImplInContext(context)).updateParametersInContext(getContextImpl(context), firstChangedBond, lastChangedBond);
if (numContexts == 1) {
// We just updated the only existing context for this force, so we can reset
// the tracking of changed bonds.
firstChangedBond = bonds.size();
lastChangedBond = -1;
}
} }
void HarmonicBondForce::setUsesPeriodicBoundaryConditions(bool periodic) { void HarmonicBondForce::setUsesPeriodicBoundaryConditions(bool periodic) {
......
...@@ -6,7 +6,7 @@ ...@@ -6,7 +6,7 @@
* Biological Structures at Stanford, funded under the NIH Roadmap for * * Biological Structures at Stanford, funded under the NIH Roadmap for *
* Medical Research, grant U54 GM072970. See https://simtk.org. * * Medical Research, grant U54 GM072970. See https://simtk.org. *
* * * *
* Portions copyright (c) 2008-2021 Stanford University and the Authors. * * Portions copyright (c) 2008-2024 Stanford University and the Authors. *
* Authors: Peter Eastman * * Authors: Peter Eastman *
* Contributors: * * Contributors: *
* * * *
...@@ -88,7 +88,7 @@ vector<pair<int, int> > HarmonicBondForceImpl::getBondedParticles() const { ...@@ -88,7 +88,7 @@ vector<pair<int, int> > HarmonicBondForceImpl::getBondedParticles() const {
return bonds; return bonds;
} }
void HarmonicBondForceImpl::updateParametersInContext(ContextImpl& context) { void HarmonicBondForceImpl::updateParametersInContext(ContextImpl& context, int firstBond, int lastBond) {
kernel.getAs<CalcHarmonicBondForceKernel>().copyParametersToContext(context, owner); kernel.getAs<CalcHarmonicBondForceKernel>().copyParametersToContext(context, owner, firstBond, lastBond);
context.systemChanged(); context.systemChanged();
} }
...@@ -6,7 +6,7 @@ ...@@ -6,7 +6,7 @@
* Biological Structures at Stanford, funded under the NIH Roadmap for * * Biological Structures at Stanford, funded under the NIH Roadmap for *
* Medical Research, grant U54 GM072970. See https://simtk.org. * * Medical Research, grant U54 GM072970. See https://simtk.org. *
* * * *
* Portions copyright (c) 2008-2021 Stanford University and the Authors. * * Portions copyright (c) 2008-2024 Stanford University and the Authors. *
* Authors: Peter Eastman * * Authors: Peter Eastman *
* Contributors: * * Contributors: *
* * * *
...@@ -40,16 +40,11 @@ ...@@ -40,16 +40,11 @@
#include <utility> #include <utility>
using namespace OpenMM; using namespace OpenMM;
using std::map; using namespace std;
using std::pair;
using std::set;
using std::string;
using std::stringstream;
using std::vector;
NonbondedForce::NonbondedForce() : nonbondedMethod(NoCutoff), cutoffDistance(1.0), switchingDistance(-1.0), rfDielectric(78.3), NonbondedForce::NonbondedForce() : nonbondedMethod(NoCutoff), cutoffDistance(1.0), switchingDistance(-1.0), rfDielectric(78.3),
ewaldErrorTol(5e-4), alpha(0.0), dalpha(0.0), useSwitchingFunction(false), useDispersionCorrection(true), exceptionsUsePeriodic(false), recipForceGroup(-1), ewaldErrorTol(5e-4), alpha(0.0), dalpha(0.0), useSwitchingFunction(false), useDispersionCorrection(true), exceptionsUsePeriodic(false), recipForceGroup(-1),
includeDirectSpace(true), nx(0), ny(0), nz(0), dnx(0), dny(0), dnz(0) { includeDirectSpace(true), nx(0), ny(0), nz(0), dnx(0), dny(0), dnz(0), numContexts(0) {
} }
NonbondedForce::NonbondedMethod NonbondedForce::getNonbondedMethod() const { NonbondedForce::NonbondedMethod NonbondedForce::getNonbondedMethod() const {
...@@ -155,7 +150,10 @@ void NonbondedForce::setParticleParameters(int index, double charge, double sigm ...@@ -155,7 +150,10 @@ void NonbondedForce::setParticleParameters(int index, double charge, double sigm
particles[index].charge = charge; particles[index].charge = charge;
particles[index].sigma = sigma; particles[index].sigma = sigma;
particles[index].epsilon = epsilon; particles[index].epsilon = epsilon;
} if (numContexts > 0) {
firstChangedParticle = min(index, firstChangedParticle);
lastChangedParticle = max(index, lastChangedParticle);
}}
int NonbondedForce::addException(int particle1, int particle2, double chargeProd, double sigma, double epsilon, bool replace) { int NonbondedForce::addException(int particle1, int particle2, double chargeProd, double sigma, double epsilon, bool replace) {
map<pair<int, int>, int>::iterator iter = exceptionMap.find(pair<int, int>(particle1, particle2)); map<pair<int, int>, int>::iterator iter = exceptionMap.find(pair<int, int>(particle1, particle2));
...@@ -198,9 +196,20 @@ void NonbondedForce::setExceptionParameters(int index, int particle1, int partic ...@@ -198,9 +196,20 @@ void NonbondedForce::setExceptionParameters(int index, int particle1, int partic
exceptions[index].chargeProd = chargeProd; exceptions[index].chargeProd = chargeProd;
exceptions[index].sigma = sigma; exceptions[index].sigma = sigma;
exceptions[index].epsilon = epsilon; exceptions[index].epsilon = epsilon;
} if (numContexts > 0) {
firstChangedException = min(index, firstChangedException);
lastChangedException = max(index, lastChangedException);
}}
ForceImpl* NonbondedForce::createImpl() const { ForceImpl* NonbondedForce::createImpl() const {
if (numContexts == 0) {
// Begin tracking changes to particles and exceptions.
firstChangedParticle = particles.size();
lastChangedParticle = -1;
firstChangedException = exceptions.size();
lastChangedException = -1;
}
numContexts++;
return new NonbondedForceImpl(*this); return new NonbondedForceImpl(*this);
} }
...@@ -353,7 +362,16 @@ void NonbondedForce::setIncludeDirectSpace(bool include) { ...@@ -353,7 +362,16 @@ void NonbondedForce::setIncludeDirectSpace(bool include) {
} }
void NonbondedForce::updateParametersInContext(Context& context) { void NonbondedForce::updateParametersInContext(Context& context) {
dynamic_cast<NonbondedForceImpl&>(getImplInContext(context)).updateParametersInContext(getContextImpl(context)); dynamic_cast<NonbondedForceImpl&>(getImplInContext(context)).updateParametersInContext(getContextImpl(context),
firstChangedParticle, lastChangedParticle, firstChangedException, lastChangedException);
if (numContexts == 1) {
// We just updated the only existing context for this force, so we can reset
// the tracking of changed particles and exceptions.
firstChangedParticle = particles.size();
lastChangedParticle = -1;
firstChangedException = exceptions.size();
lastChangedException = -1;
}
} }
bool NonbondedForce::getExceptionsUsePeriodicBoundaryConditions() const { bool NonbondedForce::getExceptionsUsePeriodicBoundaryConditions() const {
......
...@@ -345,8 +345,8 @@ double NonbondedForceImpl::calcDispersionCorrection(const System& system, const ...@@ -345,8 +345,8 @@ double NonbondedForceImpl::calcDispersionCorrection(const System& system, const
return 8*numParticles*numParticles*M_PI*(sum1/(9*pow(cutoff, 9))-sum2/(3*pow(cutoff, 3))+sum3); return 8*numParticles*numParticles*M_PI*(sum1/(9*pow(cutoff, 9))-sum2/(3*pow(cutoff, 3))+sum3);
} }
void NonbondedForceImpl::updateParametersInContext(ContextImpl& context) { void NonbondedForceImpl::updateParametersInContext(ContextImpl& context, int firstParticle, int lastParticle, int firstException, int lastException) {
kernel.getAs<CalcNonbondedForceKernel>().copyParametersToContext(context, owner); kernel.getAs<CalcNonbondedForceKernel>().copyParametersToContext(context, owner, firstParticle, lastParticle, firstException, lastException);
context.systemChanged(); context.systemChanged();
} }
......
...@@ -6,7 +6,7 @@ ...@@ -6,7 +6,7 @@
* Biological Structures at Stanford, funded under the NIH Roadmap for * * Biological Structures at Stanford, funded under the NIH Roadmap for *
* Medical Research, grant U54 GM072970. See https://simtk.org. * * Medical Research, grant U54 GM072970. See https://simtk.org. *
* * * *
* Portions copyright (c) 2008-2016 Stanford University and the Authors. * * Portions copyright (c) 2008-2024 Stanford University and the Authors. *
* Authors: Peter Eastman * * Authors: Peter Eastman *
* Contributors: * * Contributors: *
* * * *
...@@ -36,8 +36,9 @@ ...@@ -36,8 +36,9 @@
#include "openmm/internal/PeriodicTorsionForceImpl.h" #include "openmm/internal/PeriodicTorsionForceImpl.h"
using namespace OpenMM; using namespace OpenMM;
using namespace std;
PeriodicTorsionForce::PeriodicTorsionForce() : usePeriodic(false) { PeriodicTorsionForce::PeriodicTorsionForce() : usePeriodic(false), numContexts(0) {
} }
int PeriodicTorsionForce::addTorsion(int particle1, int particle2, int particle3, int particle4, int periodicity, double phase, double k) { int PeriodicTorsionForce::addTorsion(int particle1, int particle2, int particle3, int particle4, int periodicity, double phase, double k) {
...@@ -65,14 +66,30 @@ void PeriodicTorsionForce::setTorsionParameters(int index, int particle1, int pa ...@@ -65,14 +66,30 @@ void PeriodicTorsionForce::setTorsionParameters(int index, int particle1, int pa
periodicTorsions[index].periodicity = periodicity; periodicTorsions[index].periodicity = periodicity;
periodicTorsions[index].phase = phase; periodicTorsions[index].phase = phase;
periodicTorsions[index].k = k; periodicTorsions[index].k = k;
if (numContexts > 0) {
firstChangedTorsion = min(index, firstChangedTorsion);
lastChangedTorsion = max(index, lastChangedTorsion);
}
} }
ForceImpl* PeriodicTorsionForce::createImpl() const { ForceImpl* PeriodicTorsionForce::createImpl() const {
if (numContexts == 0) {
// Begin tracking changes to torsions.
firstChangedTorsion = periodicTorsions.size();
lastChangedTorsion = -1;
}
numContexts++;
return new PeriodicTorsionForceImpl(*this); return new PeriodicTorsionForceImpl(*this);
} }
void PeriodicTorsionForce::updateParametersInContext(Context& context) { void PeriodicTorsionForce::updateParametersInContext(Context& context) {
dynamic_cast<PeriodicTorsionForceImpl&>(getImplInContext(context)).updateParametersInContext(getContextImpl(context)); dynamic_cast<PeriodicTorsionForceImpl&>(getImplInContext(context)).updateParametersInContext(getContextImpl(context), firstChangedTorsion, lastChangedTorsion);
if (numContexts == 1) {
// We just updated the only existing context for this force, so we can reset
// the tracking of changed torsions.
firstChangedTorsion = periodicTorsions.size();
lastChangedTorsion = -1;
}
} }
void PeriodicTorsionForce::setUsesPeriodicBoundaryConditions(bool periodic) { void PeriodicTorsionForce::setUsesPeriodicBoundaryConditions(bool periodic) {
......
...@@ -6,7 +6,7 @@ ...@@ -6,7 +6,7 @@
* Biological Structures at Stanford, funded under the NIH Roadmap for * * Biological Structures at Stanford, funded under the NIH Roadmap for *
* Medical Research, grant U54 GM072970. See https://simtk.org. * * Medical Research, grant U54 GM072970. See https://simtk.org. *
* * * *
* Portions copyright (c) 2008-2021 Stanford University and the Authors. * * Portions copyright (c) 2008-2024 Stanford University and the Authors. *
* Authors: Peter Eastman * * Authors: Peter Eastman *
* Contributors: * * Contributors: *
* * * *
...@@ -78,7 +78,7 @@ std::vector<std::string> PeriodicTorsionForceImpl::getKernelNames() { ...@@ -78,7 +78,7 @@ std::vector<std::string> PeriodicTorsionForceImpl::getKernelNames() {
return names; return names;
} }
void PeriodicTorsionForceImpl::updateParametersInContext(ContextImpl& context) { void PeriodicTorsionForceImpl::updateParametersInContext(ContextImpl& context, int firstTorsion, int lastTorsion) {
kernel.getAs<CalcPeriodicTorsionForceKernel>().copyParametersToContext(context, owner); kernel.getAs<CalcPeriodicTorsionForceKernel>().copyParametersToContext(context, owner, firstTorsion, lastTorsion);
context.systemChanged(); context.systemChanged();
} }
...@@ -242,8 +242,10 @@ public: ...@@ -242,8 +242,10 @@ public:
* *
* @param context the context to copy parameters to * @param context the context to copy parameters to
* @param force the HarmonicBondForce to copy the parameters from * @param force the HarmonicBondForce to copy the parameters from
* @param firstBond the index of the first bond whose parameters might have changed
* @param lastBond the index of the last bond whose parameters might have changed
*/ */
void copyParametersToContext(ContextImpl& context, const HarmonicBondForce& force); void copyParametersToContext(ContextImpl& context, const HarmonicBondForce& force, int firstBond, int lastBond);
private: private:
class ForceInfo; class ForceInfo;
int numBonds; int numBonds;
...@@ -284,8 +286,10 @@ public: ...@@ -284,8 +286,10 @@ public:
* *
* @param context the context to copy parameters to * @param context the context to copy parameters to
* @param force the CustomBondForce to copy the parameters from * @param force the CustomBondForce to copy the parameters from
* @param firstBond the index of the first bond whose parameters might have changed
* @param lastBond the index of the last bond whose parameters might have changed
*/ */
void copyParametersToContext(ContextImpl& context, const CustomBondForce& force); void copyParametersToContext(ContextImpl& context, const CustomBondForce& force, int firstBond, int lastBond);
private: private:
class ForceInfo; class ForceInfo;
int numBonds; int numBonds;
...@@ -328,8 +332,10 @@ public: ...@@ -328,8 +332,10 @@ public:
* *
* @param context the context to copy parameters to * @param context the context to copy parameters to
* @param force the HarmonicAngleForce to copy the parameters from * @param force the HarmonicAngleForce to copy the parameters from
* @param firstAngle the index of the first bond whose parameters might have changed
* @param lastAngle the index of the last bond whose parameters might have changed
*/ */
void copyParametersToContext(ContextImpl& context, const HarmonicAngleForce& force); void copyParametersToContext(ContextImpl& context, const HarmonicAngleForce& force, int firstAngle, int lastAngle);
private: private:
class ForceInfo; class ForceInfo;
int numAngles; int numAngles;
...@@ -370,8 +376,10 @@ public: ...@@ -370,8 +376,10 @@ public:
* *
* @param context the context to copy parameters to * @param context the context to copy parameters to
* @param force the CustomAngleForce to copy the parameters from * @param force the CustomAngleForce to copy the parameters from
* @param firstAngle the index of the first bond whose parameters might have changed
* @param lastAngle the index of the last bond whose parameters might have changed
*/ */
void copyParametersToContext(ContextImpl& context, const CustomAngleForce& force); void copyParametersToContext(ContextImpl& context, const CustomAngleForce& force, int firstAngle, int lastAngle);
private: private:
class ForceInfo; class ForceInfo;
int numAngles; int numAngles;
...@@ -412,10 +420,12 @@ public: ...@@ -412,10 +420,12 @@ public:
/** /**
* Copy changed parameters over to a context. * Copy changed parameters over to a context.
* *
* @param context the context to copy parameters to * @param context the context to copy parameters to
* @param force the PeriodicTorsionForce to copy the parameters from * @param force the PeriodicTorsionForce to copy the parameters from
* @param firstTorsion the index of the first torsion whose parameters might have changed
* @param lastTorsion the index of the last torsion whose parameters might have changed
*/ */
void copyParametersToContext(ContextImpl& context, const PeriodicTorsionForce& force); void copyParametersToContext(ContextImpl& context, const PeriodicTorsionForce& force, int firstTorsion, int lastTorsion);
private: private:
class ForceInfo; class ForceInfo;
int numTorsions; int numTorsions;
...@@ -496,10 +506,12 @@ public: ...@@ -496,10 +506,12 @@ public:
/** /**
* Copy changed parameters over to a context. * Copy changed parameters over to a context.
* *
* @param context the context to copy parameters to * @param context the context to copy parameters to
* @param force the CustomTorsionForce to copy the parameters from * @param force the CustomTorsionForce to copy the parameters from
* @param firstTorsion the index of the first torsion whose parameters might have changed
* @param lastTorsion the index of the last torsion whose parameters might have changed
*/ */
void copyParametersToContext(ContextImpl& context, const CustomTorsionForce& force); void copyParametersToContext(ContextImpl& context, const CustomTorsionForce& force, int firstTorsion, int lastTorsion);
private: private:
class ForceInfo; class ForceInfo;
int numTorsions; int numTorsions;
...@@ -585,10 +597,12 @@ public: ...@@ -585,10 +597,12 @@ public:
/** /**
* Copy changed parameters over to a context. * Copy changed parameters over to a context.
* *
* @param context the context to copy parameters to * @param context the context to copy parameters to
* @param force the CustomExternalForce to copy the parameters from * @param force the CustomExternalForce to copy the parameters from
* @param firstParticle the index of the first particle whose parameters might have changed
* @param lastParticle the index of the last particle whose parameters might have changed
*/ */
void copyParametersToContext(ContextImpl& context, const CustomExternalForce& force); void copyParametersToContext(ContextImpl& context, const CustomExternalForce& force, int firstParticle, int lastParticle);
private: private:
class ForceInfo; class ForceInfo;
int numParticles; int numParticles;
...@@ -730,8 +744,10 @@ public: ...@@ -730,8 +744,10 @@ public:
* *
* @param context the context to copy parameters to * @param context the context to copy parameters to
* @param force the CustomNonbondedForce to copy the parameters from * @param force the CustomNonbondedForce to copy the parameters from
* @param firstParticle the index of the first particle whose parameters might have changed
* @param lastParticle the index of the last particle whose parameters might have changed
*/ */
void copyParametersToContext(ContextImpl& context, const CustomNonbondedForce& force); void copyParametersToContext(ContextImpl& context, const CustomNonbondedForce& force, int firstParticle, int lastParticle);
private: private:
class ForceInfo; class ForceInfo;
class LongRangePostComputation; class LongRangePostComputation;
......
...@@ -9,7 +9,7 @@ ...@@ -9,7 +9,7 @@
* Biological Structures at Stanford, funded under the NIH Roadmap for * * Biological Structures at Stanford, funded under the NIH Roadmap for *
* Medical Research, grant U54 GM072970. See https://simtk.org. * * Medical Research, grant U54 GM072970. See https://simtk.org. *
* * * *
* Portions copyright (c) 2019-2023 Stanford University and the Authors. * * Portions copyright (c) 2019-2024 Stanford University and the Authors. *
* Authors: Peter Eastman * * Authors: Peter Eastman *
* Contributors: * * Contributors: *
* * * *
...@@ -513,7 +513,7 @@ public: ...@@ -513,7 +513,7 @@ public:
* may be invalid. This should be called whenever force field parameters change. It will cause the * may be invalid. This should be called whenever force field parameters change. It will cause the
* definitions and order to be revalidated. * definitions and order to be revalidated.
*/ */
bool invalidateMolecules(ComputeForceInfo* force); bool invalidateMolecules(ComputeForceInfo* force, bool checkAtoms=true, bool checkGroups=true);
/** /**
* Make sure the current atom order is valid, based on the forces. If not, perform reordering * Make sure the current atom order is valid, based on the forces. If not, perform reordering
* to generate a new valid order. This method is only needed in very unusual situations. * to generate a new valid order. This method is only needed in very unusual situations.
......
...@@ -84,6 +84,17 @@ public: ...@@ -84,6 +84,17 @@ public:
*/ */
template <class T> template <class T>
void setParameterValues(const std::vector<std::vector<T> >& values, bool convert=false); void setParameterValues(const std::vector<std::vector<T> >& values, bool convert=false);
/**
* Set the values of all parameters for a subset of objects. They must be
* contained in a continuous range.
*
* @param first the index of the first object for which to set parameter values
* @param values values[i][j] contains the value of parameter j for object i+first
* @param convert if true, automatic conversions between single and double
* precision will be performed as necessary
*/
template <class T>
void setParameterValuesSubset(int first, const std::vector<std::vector<T> >& values, bool convert=false);
/** /**
* Get a vector of ComputeParameterInfo objects which describe the arrays * Get a vector of ComputeParameterInfo objects which describe the arrays
* containing the data. * containing the data.
......
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