Skip to content

Comments

Try reinitializing context if updateParametersInContext fails#309

Open
lilyminium wants to merge 3 commits intoleeping:masterfrom
lilyminium:update-parameter-context
Open

Try reinitializing context if updateParametersInContext fails#309
lilyminium wants to merge 3 commits intoleeping:masterfrom
lilyminium:update-parameter-context

Conversation

@lilyminium
Copy link

@lilyminium lilyminium commented Feb 19, 2026

This PR addresses the issue in OpenMM where trying to update a simulation without actually changing parameters triggers a pretty esoteric error. This arose for me during Iteration 0 of trying to reproduce a past TIP4P-FB fit, because update_simulation is called even though the FF has not been optimized yet.

Opening as a draft PR for now to see if existing tests trigger the error -- if not, I'll come up with my own test :-)

I ran a timing test and reinitializing the context is about an order of magnitude slower than updateParametersInContext -- reinitializing takes ~35 ms compared to 4.6 ms for updateParametersInContext. So I think the try/except is much more preferable than reinitializing every time.

Code below, and notebook PDF

from openmm.app import *
from openmm import *
from openmm.unit import *
from sys import stdout
import random

pdb = PDBFile('liquid.pdb')
forcefield = ForceField('amber14/tip3pfb.xml')
system = forcefield.createSystem(pdb.topology, nonbondedMethod=PME,
        nonbondedCutoff=0.9*nanometer, constraints=HBonds)
integrator = LangevinMiddleIntegrator(300*kelvin, 1/picosecond, 0.004*picoseconds)
simulation = Simulation(pdb.topology, system, integrator)
simulation.context.setPositions(pdb.positions)

def update_parameters():
    for i in range(simulation.system.getNumForces()):
        if hasattr(simulation.system.getForce(i),'updateParametersInContext'):
            simulation.system.getForce(i).updateParametersInContext(simulation.context)

def reinitialize_context():
    simulation.context.reinitialize(preserveState=True)

def randomize_parameters_and_update(func):
    for fc in simulation.system.getForces():
        if "Nonbond" in type(fc).__name__:
            units = [x.unit for x in fc.getParticleParameters(0)]
            for i in range(fc.getNumParticles()):
                q_ = random.random()
                sigma_ = random.random()
                eps_ = random.random()
                fc.setParticleParameters(i, q_ * units[0], sigma_ * units[1], eps_ * units[2])
    func()

%timeit randomize_parameters_and_update(update_parameters)
%timeit randomize_parameters_and_update(reinitialize_context)

time-reinitialization.pdf

@lilyminium lilyminium marked this pull request as ready for review February 23, 2026 00:46
@lilyminium
Copy link
Author

I realised that this error may be dependent on CUDA (at least, that's the only way I could trigger the error originally). I did verify that the 9925286 commit triggers that error on a CUDA machine, then verified that 267b442 fixes it. I'm not sure how better to test this on GitHub CI :/

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant