Repository navigation
GROMACS 2025/2026 patches and kernel: fix the virial with an ENERGY bias, a replica exchange deadlock, COMMITTOR, virtual sites, MTS and shells - #1506
Merged
carlocamilloni merged 10 commits intoOct 15, 2026
Conversation
On the domains other than the first, the Box input was flagged noforce, so that the virial computed by PLUMED is added only once. But the same flag also stopped ENERGY from rescaling that rank's share of the virial of the MD code, which is spread over all ranks. The pressure was then wrong with any bias on ENERGY and domain decomposition: in a GROMACS test, the virial at step 0 was -725.7 on 2 ranks instead of 5.457. PLUMED 2.9 rescaled the virial on all ranks. A new flag, forces_added_elsewhere, now only stops adding PLUMED's forces on those ranks. rescale_force skips a buffer the MD code did not pass, as PLUMED 2.9 did for the virial. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The patches passed setStopFlag to PLUMED but never read the flag, so COMMITTOR could not stop mdrun. The GROMACS 2024 patch set bLastStep after the force calculation, which with simulations that share state (e.g. WALKERS_MPI) stops one simulation and deadlocks the others. The force provider now reports the request with requestsStop(), and runner.cpp registers it as a stop condition with the StopHandlerBuilder. GROMACS then passes it to all ranks and to the simulations that share state, in the legacy and in the modular simulator, and mdrun stops at the next step at which GROMACS communicates signals (every nstglobalcomm steps, and at least every 200 steps between simulations), writing a checkpoint, with exit code 0. Only the main rank signals, since the flag is the same on all ranks. The modular simulator stops at the next neighbor-search step instead: when a stop is signalled for another step, it clears the task queue it is running from, and crashes (seen with md-vv). Tested on ala2 with COMMITTOR: the run stops 4-9 steps after committing with leap-frog on 1 and 2 ranks, 13-25 steps after with md-vv, and two walkers stop together. Before, all ran to the end. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…he energy path When PLUMED needs the potential energy, it runs at the end of do_force(), after GROMACS has spread the forces on the virtual sites and cleared them. The forces PLUMED applied on virtual sites were then lost. They are now spread like the other forces with an explicit virial in postProcessForces(), on the steps when the atoms that PLUMED uses include virtual sites: applyAfterPotentialEnergy() now returns whether they do. That list is the same on all ranks, so that all take the same decision. The extra spread costs about 45 us per step (2% of a GPU step for a 68k-atom TIP4P box), so inputs that only bias the energy, e.g. OPES multithermal, do not pay for it. Tested on TIP4P water with a restraint between two M sites: adding ENERGY to the input changed the forces on those waters by 6.9e3 kJ/mol/nm, now by 0.001 on 1 rank and by 0 on 2 ranks. With the restraint between two oxygens the forces do not change and there is no extra spread. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…fast step With multiple time stepping, the slow forces and their energies are computed only every mts-level2-factor steps. If PLUMED needed the energy on another step, it got an energy without the slow terms: in a TIP4P test with mts-level2-factor 2, ENERGY was off by 650-1250 kJ/mol on the odd steps. mdrun now stops with an error, which says to need the energy only on the slow steps (e.g. no bias on ENERGY) or not to use multiple time stepping. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The force provider rethrew every exception as an InternalError, so GROMACS reported e.g. replica exchange with a PLUMED bias as "Internal error (bug)". GROMACS exceptions now pass unchanged, so this is reported as "Feature not implemented"; PLUMED errors are still wrapped as before. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…laxation With shell (polarizable) particles, relax_shell_flexcon() calls do_force() again for each shell relaxation iteration, passing step 1. PLUMED then calculated and updated on each of them, as step 1: e.g. PRINT printed extra lines at step 1, and actions updating at every step (e.g. PACE=1) were updated several times per step. PLUMED now uses the step from prepareStep(), and only recalculates its forces (performCalcNoUpdate) when called again on the same step. This is limited to MD, where prepareStep() gives the step: e.g. the frames of a rerun can all have the same step, and the conjugate gradient minimizer passes step -1. On a SW water dimer, COLVAR now has one line per step. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
In a rerun, GROMACS sets isLastStep from the stop handler at the start of each frame, but then overwrites it with the result of reading the next frame: a stop request, e.g. from COMMITTOR through the stop condition of the PLUMED module, was ignored and the rerun went through all the frames. rerun.cpp is now patched to keep it, as in the GROMACS 2020-2024 patches. Found by a regression test: a rerun with COMMITTOR committing at the first frame went through all 11 frames. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
GREX::savePositions() shares the positions of all atoms (shareAll), but then waits only for the inputs that are active on this step (waitData). When no action needs atoms on an exchange step, the domain decomposition started its exchange but never completed it. With asynchronous sharing (the default on fewer than 10 ranks), the sends were never received: the next exchange waited for them forever with large messages, and with small ones the following receives could get the positions of an earlier step. PLUMED 2.9 always waited. Found by a GROMACS regression test: -hrex with two TIP4P water replicas on 2 ranks each hung at the step after the first exchange attempt with the PLUMED 2.10 kernel, and ran with the 2.9 one. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
A table in the list of MD codes compares the PLUMED module of GROMACS 2025 and later with the patches for GROMACS 2025/2026 and for the older versions (ENERGY, multiple walkers, checkpoints, stop requests, shells, replica exchange, lambda dynamics), as tested by the regression tests of the PLUMED testcenter. The descriptions of the 2025/2026 patches also list stop requests and shells. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This was referenced Oct 15, 2026
2 of 7 tasks
Contributor
Author
|
Follow-up in #1509: the constraint virial with MTS, shells in reruns and a warning for shells with ENERGY, reruns stopping at the frame that asks, and notes in the docs table. #1508 has the follow-up for v2.9. 🤖 Generated with Claude Code |
invemichele-peptone
added a commit
to invemichele-peptone/plumed2
that referenced
this pull request
Oct 15, 2026
A table in the list of MD codes of the master manual compares the PLUMED module of GROMACS 2025 and later with the patches for GROMACS 2025/2026 and for GROMACS 2024 (ENERGY, multiple simulations through MPI, checkpoints, stop requests, shells, replica exchange, lambda dynamics), as tested by the regression tests of the PLUMED testcenter, with notes on the limitations. It replaces the sentence that suggested the patch for GROMACS 2025/2026 for replica exchange and lambda dynamics, which only the patch for GROMACS 2024 has. v2.10 has the same table in user-doc/Introduction.md (plumed#1506, plumed#1509). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2 of 7 tasks
carlocamilloni
pushed a commit
that referenced
this pull request
Oct 15, 2026
… MTS, shells in reruns and with ENERGY, rerun stop, docs) (#1509) * GROMACS 2025/2026 patches: with MTS, add PLUMED's forces also to the normal force buffer When PLUMED needs the energy, it applies its forces after the force calculation, and with multiple time stepping to the combined MTS buffer, which the update uses. On the slow steps that compute the virial, GROMACS computes the constraint virial from the normal buffer (and writes it to the trajectory), which then lacked the part of PLUMED's forces that the constraints pass on: e.g. 2.7, -0.5 and 3.8 kJ/mol on the virial of a restraint between two water oxygens, against the GROMACS pull code. The difference PLUMED made to the combined buffer is now added to the normal one too. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * GROMACS 2025/2026 patches: shells in reruns, a warning for shells with ENERGY, and the stop of reruns - Reruns now call prepareStep() too, and a call is "repeated" when PLUMED already calculated since the last prepareStep(), not on the same step number (frames of a rerun can share it). With shells, reruns then update PLUMED once per frame, as MD does, instead of on each iteration of the shell relaxation, as step 1. - PLUMED updates on the first force calculation of the step, before the shells are relaxed. When the input needs the energy, that energy is the one before the relaxation: mdrun now prints a warning, once. - A rerun stops after the frame on which PLUMED asks for it, as with the GROMACS 2020-2024 patches, instead of after the next one. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Docs: notes on the GROMACS interfaces table, and corrections to CHANGES - The table now notes that GROMACS 2026.0-2026.3 without patches stop with more than one MPI rank, that ENERGY and the checkpoint data need the legacy simulator with md-vv (GMX_DISABLE_MODULAR_SIMULATOR=1), that with MTS the energy is available on the slow steps only, and the limitation of shells with ENERGY. Multiple walkers through files also work without patches: the row is about simulations that communicate through MPI. - CHANGES and patch descriptions: after a stop request, mdrun runs one more step after the next communication of signals, which between simulations happens every 200 steps or more; \ref links for the doxygen manual of v2.10. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
carlocamilloni
pushed a commit
that referenced
this pull request
Oct 15, 2026
A table in the list of MD codes of the master manual compares the PLUMED module of GROMACS 2025 and later with the patches for GROMACS 2025/2026 and for GROMACS 2024 (ENERGY, multiple simulations through MPI, checkpoints, stop requests, shells, replica exchange, lambda dynamics), as tested by the regression tests of the PLUMED testcenter, with notes on the limitations. It replaces the sentence that suggested the patch for GROMACS 2025/2026 for replica exchange and lambda dynamics, which only the patch for GROMACS 2024 has. v2.10 has the same table in user-doc/Introduction.md (#1506, #1509). Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Description
Follow-up of #1504, which fixed checkpointing in the GROMACS 2025/2026 patches. These are the other bugs I found in those patches, plus one in the PLUMED 2.10 kernel that affects all the GROMACS patches. The bugs in the GROMACS 2020-2024 patches (among them a double-counted PLUMED virial, i.e. a wrong pressure, since the GROMACS 2019 patch) are fixed in #1505 (for v2.9); the GROMACS 2022.5, 2023.5 and 2024.3 patches are identical in v2.9 and v2.10, so they get those fixes when v2.9 is merged here. #1507 ports both PRs to master.
Each commit fixes one bug, with a CHANGES entry. Two of the bugs (the virial, and replica exchange on several ranks) are in the kernel and affect all the GROMACS patches:
Virial with a bias on ENERGY and domain decomposition (kernel,
src/core)On the domains other than the first, the Box input was flagged
noforce, so that the virial computed by PLUMED is added only once. But the same flag also stopped ENERGY from rescaling that rank's share of the virial of the MD code, which is spread over all ranks. The pressure was then wrong with any bias on ENERGY (e.g. OPES multithermal-multibaric) and domain decomposition, with all the GROMACS patches. A new flag,forces_added_elsewhere, now only stops adding PLUMED's own forces on those ranks, as PLUMED 2.9 did.RESTRAINT ARG=ene SLOPE=-0.5, Pres-XX at step 0: 16.92 on 1 rank, 895.6 on 2 ranks and 29.8 on 3 ranks (GROMACS 2023.5 patch); now 16.92 on 1, 2 and 3 ranks, also with the GROMACS 2024.3 and 2026.4 patches.Replica exchange with more than one rank per replica (kernel,
src/core/GREX.cpp)GREX::savePositions()shares the positions of all atoms, but then waits only for the inputs that are active on the step. When no action needs atoms on an exchange step, the exchange of the domain decomposition was started but never completed: with asynchronous sharing (the default on fewer than 10 ranks), the next exchange waited forever for messages that were never received, or, with small messages, received the positions of an earlier step. PLUMED 2.9 always waited. This affects-replexand-hrexwith any GROMACS patch.-hrex, a distance printed every 10 steps: hung at the step after the first exchange attempt with the 2.10 kernel (also with the current patches); now runs, with zero exchange energy for identical replicas.PLUMED asking to stop, e.g. COMMITTOR
The GROMACS 2025/2026 patches ignored the request: the simulation ran to the end. It is now a stop condition of the GROMACS stop handler, registered in
runner.cpp: it reaches all ranks and the simulations that share state, and mdrun stops at the next step at which GROMACS communicates signals (every nstglobalcomm steps, and at least every 200 steps between simulations), writing a checkpoint. The modular simulator (md-vv) stops at the next neighbor-search step instead: when asked to stop at another step, it clears the task queue it is running from, and crashes (a GROMACS bug).Virtual sites in the energy path
When PLUMED needs the potential energy, it runs at the end of
do_force(), after GROMACS has spread the forces on the virtual sites and cleared them. The forces PLUMED applied on virtual sites (e.g. the M site of TIP4P water) were lost. They are now spread with their virial, on the steps when the atoms that PLUMED uses include virtual sites (fromcreateFullList, which is the same on all ranks). The extra spread costs about 45 us per step, i.e. 2% of a GPU step for a 68k-atom TIP4P box (0.6% on CPU), so inputs that only bias the energy, e.g. OPES multithermal, do not pay for it.Energy on MTS fast steps
With multiple time stepping, the slow forces and their energy are computed only every mts-level2-factor steps, so the energy passed to PLUMED on the other steps lacked the slow terms (650-1250 kJ/mol in a water test). mdrun now stops with an error if PLUMED needs the energy on such a step.
Shell (polarizable) particles
The shell relaxation calls
do_force()again for each iteration, passing step 1: PLUMED calculated and updated on each of them, as step 1 (e.g. PRINT printed extra lines at step 1). PLUMED now uses the step fromprepareStep(), and only recalculates its forces (performCalcNoUpdate) when called again on the same MD step (only in MD: the frames of a rerun can share a step, and CG minimization passes step -1).Smaller fixes
rerun.cppis now patched, as in the GROMACS 2020-2024 patches.NotImplementedErrorfor replica exchange with a bias) were caught and reported as internal errors ("bug"); their type and message are now kept.gmx_multisim_twas forward-declared as a class but defined as a struct.Docs
The list of MD codes said that GROMACS 2025 and later have limited support, without saying what the patches add. It now has a table of what the PLUMED module of GROMACS 2025 and later, the patches for GROMACS 2025/2026 and the patches for GROMACS 2022-2024 support: ENERGY, multiple walkers, checkpoints, stop requests, shells, replica exchange with a bias, and lambda dynamics. The table follows the results of the regression tests below. The descriptions of the 2025/2026 patches (
plumed patch --info) also list stop requests and shells.Tests
The CI does not build GROMACS, so I wrote regression tests for PLUMED with GROMACS, and proposed them to the PLUMED testcenter in plumed-testcenter/plumed-testcenter#95, where they would run every week on all the GROMACS versions that PLUMED can patch. They compare PLUMED with references that do not depend on the versions (e.g. a RESTRAINT against the GROMACS pull code, or the same run on 1, 2 and 3 ranks), so the same tests run on any combination of GROMACS, patch and kernel. With GROMACS 2025.0 and 2026.4, they fail where described above with v2.10 and all pass with this branch; the replica exchange deadlock was found by them. They also show what the GROMACS 2025/2026 patches add to the PLUMED module of GROMACS: GROMACS 2025 without patches fails the tests of ENERGY, checkpoints, COMMITTOR, shells and replica exchange with a bias. I also tested by hand, with GROMACS 2025.0 and 2026.4 (MPI build) patched with this branch and with v2.10, and the PLUMED kernel of this branch:
-replexwith a PLUMED input that only prints still runs;rt-average,rt-output-colvar-multi-dd);Target release
I would like my code to appear in release v2.10
Type of contribution
Copyright
COPYRIGHTfile with the correct license information. Code should be released under an open source license. I also used the commandcd src && ./header.sh mymodulenamein order to make sure the headers of the module are correct.Tests
🤖 Generated with Claude Code