Skip to content

Commit d26ee82

Browse files
committed
Add a patch for GROMACS 2026
There is no patch for GROMACS 2026, so `plumed patch -e` offers nothing newer than gromacs-2025.0 and there is no supported way to build a PLUMED-enabled GROMACS 2026. Applying the 2025.0 patch to 2026.4 does not work. GROMACS replaced the t_commrec plumbing with the MpiComm abstraction in db61f87e0a ("Use MpiComm in t_commrec"), so PlumedOptions now carries `const MpiComm* mpiComm_` instead of `const t_commrec* cr_`: $ plumed patch -p -e gromacs-2025.0 # on a 2026.4 tree patching file ./src/gromacs/applied_forces/plumed/plumedforceprovider.cpp Hunk plumed#3 FAILED at 113. 1 out of 4 hunks FAILED -- saving rejects to ...plumedforceprovider.cpp.rej patching file ./src/gromacs/CMakeLists.txt Reversed (or previously applied) patch detected! Skipping patch. 2 out of 2 hunks ignored -- saving rejects to ./src/gromacs/CMakeLists.txt.rej and six further files apply only with fuzz 5. The failing hunk is the one that hands PLUMED the multi-replica communicators, which is the most damaging thing to lose silently: `GREX setMPIIntercomm` is what populates PlumedMain::multi_sim_comm (GREX.cpp), so without it every multi-replica action degrades to a single replica without any error. The new patch is the 2025.0 one carried onto the 2026 API: * the GREX/multisim block uses MpiComm::isMainRank() and MpiComm::comm() * src/gromacs/CMakeLists.txt is dropped entirely -- GROMACS 2026 already calls gmx_manage_plumed() early, which is why those hunks reported as already applied * setNumOMPthreads is carried over from plumed#1435 * the replex_ plumbing, the PLUMED_LOG_FILE override and forcing GMX_USE_PLUMED=ON are unchanged in substance It also fixes one bug in GROMACS's own code. The same MpiComm commit rewrote - plumed_->cmd("setMPIComm", &options.cr_->mpi_comm_mygroup); + plumed_->cmd("setMPIComm", options.mpiComm_->comm()); dropping the address-of. MpiComm::comm() returns MPI_Comm by value, but PLUMED reads that argument as `*(const MPI_Comm*)` (Communicator::Set_comm), so where MPI_Comm is a pointer type this compiles and silently passes the wrong handle. The patch passes the address of a named local instead. This is worth reporting to GROMACS separately; until it is fixed there, any domain-decomposed PLUMED run on 2026 is affected. Verified on GROMACS 2026.4 with clang 20.1.1, OpenMPI 5.0.7 and libc++: * `plumed patch -p -e gromacs-2026.0` applies with no fuzz and no rejects, and `plumed patch -r` restores the tree byte-for-byte * the patched GROMACS builds clean (GMX_MPI=ON, GMX_THREAD_MPI=OFF, GMX_OPENMP=ON); the four changed translation units compile with no errors and no warnings * a two-replica `mdrun -multidir` run expands `@replicas:` to a different value per replica, which is only possible when multi_sim_comm has been set up Scope for 2027: the plumed module sources on GROMACS main are currently identical to release-2026, and the runner.cpp and mdmodulesnotifiers.h edits apply there unchanged; only the stored .preplumed snapshots would need regenerating once 2027 branches.
1 parent 54b4da9 commit d26ee82

17 files changed

Lines changed: 8833 additions & 0 deletions

patches/gromacs-2026.0.config

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
2+
3+
function plumed_preliminary_test(){
4+
# check if the README contains the word GROMACS and if gromacs has been already configured
5+
grep -q GROMACS README 1>/dev/null 2>/dev/null
6+
}
7+
8+
function plumed_patch_info(){
9+
cat << EOF
10+
A basic PLUMED interface is already present in GROMACS
11+
12+
This patch previes extra features to be implemented in the official PLUMED integration in the next GROMACS version
13+
14+
Patching must be done in the gromacs root directory _before_ the cmake command is invoked.
15+
16+
The GROMACS integration has some improvements with the compatibility wiht the multi-threading implementation
17+
but it is still preferable to configure gromacs as
18+
19+
cmake -DGMX_THREAD_MPI=OFF and add -DGMX_MPI=ON if you want to use MPI.
20+
21+
To enable PLUMED in a gromacs simulation one should use
22+
mdrun with an extra -plumed flag. The flag can be used to
23+
specify the name of the PLUMED input file, e.g.:
24+
25+
gmx mdrun -plumed plumed.dat
26+
27+
For more information on gromacs you should visit http://www.gromacs.org
28+
29+
EOF
30+
}
31+
32+
plumed_before_patch(){
33+
plumed_patch_info
34+
}
35+
36+
PLUMED_PATCH_NO_INCLUDE=true
37+
38+
#this will be added later
39+
#PLUMED_PATCH_EXTRA_FILES="src/external/plumed/PlumedInclude.h src/external/plumed/PlumedKernel.cpp src/gromacs/applied_forces/plumed/PlumedOutside.cpp src/gromacs/applied_forces/plumed/PlumedOutside.h"
Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
#
2+
# This file is part of the GROMACS molecular simulation package.
3+
#
4+
# Copyright 2024- The GROMACS Authors
5+
# and the project initiators Erik Lindahl, Berk Hess and David van der Spoel.
6+
# Consult the AUTHORS/COPYING files and https://www.gromacs.org for details.
7+
#
8+
# GROMACS is free software; you can redistribute it and/or
9+
# modify it under the terms of the GNU Lesser General Public License
10+
# as published by the Free Software Foundation; either version 2.1
11+
# of the License, or (at your option) any later version.
12+
#
13+
# GROMACS is distributed in the hope that it will be useful,
14+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
15+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16+
# Lesser General Public License for more details.
17+
#
18+
# You should have received a copy of the GNU Lesser General Public
19+
# License along with GROMACS; if not, see
20+
# https://www.gnu.org/licenses, or write to the Free Software Foundation,
21+
# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
22+
#
23+
# If you want to redistribute modifications to GROMACS, please
24+
# consider that scientific software is very special. Version
25+
# control is crucial - bugs must be traceable. We will be happy to
26+
# consider code for inclusion in the official distribution, but
27+
# derived work must not be called official GROMACS. Details are found
28+
# in the README & COPYING files - if they are missing, get the
29+
# official version at https://www.gromacs.org.
30+
#
31+
# To help us fund GROMACS development, we humbly ask that you cite
32+
# the research papers on the package. Check out https://www.gromacs.org.
33+
34+
35+
36+
37+
38+
39+
40+
# Builds the interface to plumed and add the linkage to libPlumed
41+
42+
gmx_option_multichoice(GMX_USE_PLUMED
43+
"Build the PLUMED wrapper with GROMACS"
44+
ON
45+
ON)
46+
mark_as_advanced(GMX_USE_PLUMED)
47+
48+
function(gmx_manage_plumed)
49+
# Create a link target, leave it empty if the plumed option is not active
50+
add_library(plumedgmx INTERFACE)
51+
set (GMX_PLUMED_ACTIVE OFF PARENT_SCOPE)
52+
if(WIN32)
53+
if(GMX_USE_PLUMED STREQUAL "ON")
54+
message(FATAL_ERROR "PLUMED is not supported on Windows. Reconfigure with -DGMX_USE_PLUMED=OFF.")
55+
endif()
56+
elseif(NOT GMX_USE_PLUMED STREQUAL "OFF")
57+
include(CMakePushCheckState)
58+
cmake_push_check_state(RESET)
59+
set(CMAKE_REQUIRED_LIBRARIES ${CMAKE_DL_LIBS})
60+
include(CheckFunctionExists)
61+
check_function_exists(dlopen HAVE_DLOPEN)
62+
cmake_pop_check_state()
63+
if(HAVE_DLOPEN)
64+
# Plumed.h compiled in c++ mode creates a fully inlined interface
65+
# So we just need to activate the directory in applied_forces
66+
set(PLUMED_DIR "${CMAKE_SOURCE_DIR}/src/external/plumed")
67+
target_link_libraries( plumedgmx INTERFACE ${CMAKE_DL_LIBS} )
68+
# The plumedgmx already exists, now we set it up:
69+
target_include_directories(plumedgmx SYSTEM INTERFACE $<BUILD_INTERFACE:${PLUMED_DIR}>)
70+
set (GMX_PLUMED_ACTIVE ON PARENT_SCOPE)
71+
else()
72+
if(GMX_USE_PLUMED STREQUAL "ON")
73+
message(FATAL_ERROR "PLUMED needs dlopen or anything equivalent. Reconfigure with -DGMX_USE_PLUMED=OFF.")
74+
else() # "AUTO"
75+
message(STATUS "PLUMED needs dlopen or anything equivalent. Disabling support.")
76+
endif()
77+
78+
endif()
79+
80+
endif()
81+
82+
endfunction()
Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
#
2+
# This file is part of the GROMACS molecular simulation package.
3+
#
4+
# Copyright 2024- The GROMACS Authors
5+
# and the project initiators Erik Lindahl, Berk Hess and David van der Spoel.
6+
# Consult the AUTHORS/COPYING files and https://www.gromacs.org for details.
7+
#
8+
# GROMACS is free software; you can redistribute it and/or
9+
# modify it under the terms of the GNU Lesser General Public License
10+
# as published by the Free Software Foundation; either version 2.1
11+
# of the License, or (at your option) any later version.
12+
#
13+
# GROMACS is distributed in the hope that it will be useful,
14+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
15+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16+
# Lesser General Public License for more details.
17+
#
18+
# You should have received a copy of the GNU Lesser General Public
19+
# License along with GROMACS; if not, see
20+
# https://www.gnu.org/licenses, or write to the Free Software Foundation,
21+
# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
22+
#
23+
# If you want to redistribute modifications to GROMACS, please
24+
# consider that scientific software is very special. Version
25+
# control is crucial - bugs must be traceable. We will be happy to
26+
# consider code for inclusion in the official distribution, but
27+
# derived work must not be called official GROMACS. Details are found
28+
# in the README & COPYING files - if they are missing, get the
29+
# official version at https://www.gromacs.org.
30+
#
31+
# To help us fund GROMACS development, we humbly ask that you cite
32+
# the research papers on the package. Check out https://www.gromacs.org.
33+
34+
35+
36+
37+
38+
39+
40+
# Builds the interface to plumed and add the linkage to libPlumed
41+
42+
gmx_option_multichoice(GMX_USE_PLUMED
43+
"Build the PLUMED wrapper with GROMACS"
44+
AUTO
45+
AUTO ON OFF)
46+
mark_as_advanced(GMX_USE_PLUMED)
47+
48+
function(gmx_manage_plumed)
49+
# Create a link target, leave it empty if the plumed option is not active
50+
add_library(plumedgmx INTERFACE)
51+
set (GMX_PLUMED_ACTIVE OFF PARENT_SCOPE)
52+
if(WIN32)
53+
if(GMX_USE_PLUMED STREQUAL "ON")
54+
message(FATAL_ERROR "PLUMED is not supported on Windows. Reconfigure with -DGMX_USE_PLUMED=OFF.")
55+
endif()
56+
elseif(NOT GMX_USE_PLUMED STREQUAL "OFF")
57+
include(CMakePushCheckState)
58+
cmake_push_check_state(RESET)
59+
set(CMAKE_REQUIRED_LIBRARIES ${CMAKE_DL_LIBS})
60+
include(CheckFunctionExists)
61+
check_function_exists(dlopen HAVE_DLOPEN)
62+
cmake_pop_check_state()
63+
if(HAVE_DLOPEN)
64+
# Plumed.h compiled in c++ mode creates a fully inlined interface
65+
# So we just need to activate the directory in applied_forces
66+
set(PLUMED_DIR "${CMAKE_SOURCE_DIR}/src/external/plumed")
67+
target_link_libraries( plumedgmx INTERFACE ${CMAKE_DL_LIBS} )
68+
# The plumedgmx already exists, now we set it up:
69+
target_include_directories(plumedgmx SYSTEM INTERFACE $<BUILD_INTERFACE:${PLUMED_DIR}>)
70+
set (GMX_PLUMED_ACTIVE ON PARENT_SCOPE)
71+
else()
72+
if(GMX_USE_PLUMED STREQUAL "ON")
73+
message(FATAL_ERROR "PLUMED needs dlopen or anything equivalent. Reconfigure with -DGMX_USE_PLUMED=OFF.")
74+
else() # "AUTO"
75+
message(STATUS "PLUMED needs dlopen or anything equivalent. Disabling support.")
76+
endif()
77+
78+
endif()
79+
80+
endif()
81+
82+
endfunction()
Lines changed: 182 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,182 @@
1+
/*
2+
* This file is part of the GROMACS molecular simulation package.
3+
*
4+
* Copyright 2024- The GROMACS Authors
5+
* and the project initiators Erik Lindahl, Berk Hess and David van der Spoel.
6+
* Consult the AUTHORS/COPYING files and https://www.gromacs.org for details.
7+
*
8+
* GROMACS is free software; you can redistribute it and/or
9+
* modify it under the terms of the GNU Lesser General Public License
10+
* as published by the Free Software Foundation; either version 2.1
11+
* of the License, or (at your option) any later version.
12+
*
13+
* GROMACS is distributed in the hope that it will be useful,
14+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
15+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16+
* Lesser General Public License for more details.
17+
*
18+
* You should have received a copy of the GNU Lesser General Public
19+
* License along with GROMACS; if not, see
20+
* https://www.gnu.org/licenses, or write to the Free Software Foundation,
21+
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
22+
*
23+
* If you want to redistribute modifications to GROMACS, please
24+
* consider that scientific software is very special. Version
25+
* control is crucial - bugs must be traceable. We will be happy to
26+
* consider code for inclusion in the official distribution, but
27+
* derived work must not be called official GROMACS. Details are found
28+
* in the README & COPYING files - if they are missing, get the
29+
* official version at https://www.gromacs.org.
30+
*
31+
* To help us fund GROMACS development, we humbly ask that you cite
32+
* the research papers on the package. Check out https://www.gromacs.org.
33+
*/
34+
/*! \internal \file
35+
* \brief
36+
* Implements Plumed MDModule class
37+
*
38+
* \author Daniele Rapetti <drapetti@sissa.it>
39+
* \ingroup module_applied_forces
40+
*/
41+
#include "gmxpre.h"
42+
43+
#include "plumedMDModule.h"
44+
45+
#include <memory>
46+
#include <string>
47+
48+
#include "gromacs/fileio/checkpoint.h"
49+
#include "gromacs/mdrunutility/mdmodulesnotifiers.h"
50+
#include "gromacs/mdtypes/imdmodule.h"
51+
#include "gromacs/utility/keyvaluetreebuilder.h"
52+
53+
#include "plumedOptions.h"
54+
#include "plumedforceprovider.h"
55+
56+
namespace gmx
57+
{
58+
59+
namespace
60+
{
61+
62+
/*! \internal
63+
* \brief Plumed module
64+
*
65+
* Class that implements the plumed MDModule
66+
*/
67+
class PlumedMDModule final : public IMDModule
68+
{
69+
public:
70+
//! \brief Construct the plumed module.
71+
explicit PlumedMDModule() = default;
72+
// Now callbacks for several kinds of MdModuleNotification are created
73+
// and subscribed, and will be dispatched correctly at run time
74+
// based on the type of the parameter required by the lambda.
75+
76+
/*! \brief Requests to be notified during pre-processing.
77+
*
78+
* Plumed does not act during the preprocessing phase of a simulation, so the input are ignored
79+
*/
80+
void subscribeToPreProcessingNotifications(MDModulesNotifiers* /*notifier*/) override {}
81+
82+
/*! \brief Subscribe to MDModules notifications for information needed just before the simulation.
83+
*/
84+
void subscribeToSimulationSetupNotifications(MDModulesNotifiers* notifier) override
85+
{
86+
// TODO: add a check for threadmpi (see #5104, https://gitlab.com/gromacs/gromacs/-/merge_requests/4367#note_2102475958, the manual and the force provider for the details)
87+
88+
// Access the plumed filename this is used to activate the plumed module
89+
notifier->simulationSetupNotifier_.subscribe(
90+
[this](const PlumedInputFilename& plumedFilename)
91+
{
92+
this->options_.setPlumedFile(plumedFilename.plumedFilename_);
93+
this->options_.setReplex(plumedFilename.replex_);
94+
});
95+
// Retrieve the multi-simulation object, needed to set up PLUMED's
96+
// multi-replica communicator
97+
notifier->simulationSetupNotifier_.subscribe([this](const gmx_multisim_t* ms)
98+
{ this->options_.setMultisim(ms); });
99+
// Access the temperature if it is constant during the simulation
100+
notifier->simulationSetupNotifier_.subscribe(
101+
[this](const EnsembleTemperature& ensembleT)
102+
{ this->options_.setEnsembleTemperature(ensembleT); });
103+
// Access of the topology
104+
notifier->simulationSetupNotifier_.subscribe([this](const gmx_mtop_t& mtop)
105+
{ this->options_.setTopology(mtop); });
106+
// Retrieve the Communication Record during simulations setup
107+
notifier->simulationSetupNotifier_.subscribe([this](const MpiComm& mpiComm)
108+
{ this->options_.setComm(mpiComm); });
109+
// setting the simulation time step
110+
notifier->simulationSetupNotifier_.subscribe(
111+
[this](const SimulationTimeStep& simulationTimeStep)
112+
{ this->options_.setSimulationTimeStep(simulationTimeStep.delta_t); });
113+
// Retrieve the starting behavior
114+
notifier->simulationSetupNotifier_.subscribe(
115+
[this](const StartingBehavior& startingBehavior)
116+
{ this->options_.setStartingBehavior(startingBehavior); });
117+
// writing checkpoint data
118+
notifier->checkpointingNotifier_.subscribe(
119+
[this](MDModulesWriteCheckpointData /*checkpointData*/)
120+
{
121+
if (options_.active())
122+
{
123+
plumedForceProvider_->writeCheckpointData();
124+
}
125+
});
126+
}
127+
128+
/*! \brief Subscribe to MDModules notifications for information needed during the simulation.
129+
*/
130+
void subscribeToSimulationRunNotifications(MDModulesNotifiers* notifier) override
131+
{
132+
if (!options_.active())
133+
{
134+
return;
135+
}
136+
137+
// Retrieve the global atom indices
138+
notifier->simulationRunNotifier_.subscribe(
139+
[this](const MDModulesAtomsRedistributedSignal& atomsRedistributedSignal) {
140+
plumedForceProvider_->setGlobalAtomIndices(atomsRedistributedSignal.globalAtomIndices_);
141+
});
142+
}
143+
144+
//! From IMDModule
145+
IMdpOptionProvider* mdpOptionProvider() override { return nullptr; }
146+
//! From IMDModule
147+
IMDOutputProvider* outputProvider() override
148+
{ // Plumed provide its own output
149+
return nullptr;
150+
}
151+
//! From IMDModule - Adds this module to the force providers if active
152+
void initForceProviders(ForceProviders* forceProviders) override
153+
{
154+
if (options_.active())
155+
{
156+
plumedForceProvider_ = std::make_unique<PlumedForceProvider>(options_.options());
157+
forceProviders->addForceProvider(plumedForceProvider_.get(),
158+
std::string(PlumedModuleInfo::sc_name));
159+
}
160+
}
161+
162+
163+
private:
164+
//! Parameters that become available at simulation setup time.
165+
PlumedOptionProvider options_{};
166+
//! Object that evaluates the forces
167+
std::unique_ptr<PlumedForceProvider> plumedForceProvider_{};
168+
};
169+
170+
} // namespace
171+
172+
std::unique_ptr<IMDModule> PlumedModuleInfo::create()
173+
{
174+
return std::make_unique<PlumedMDModule>();
175+
}
176+
177+
std::string plumedDescription()
178+
{
179+
return "enabled";
180+
}
181+
182+
} // namespace gmx

0 commit comments

Comments
 (0)