How to make my own code compatable with restart utility in Gromacs 2016.4

Hi Gromacs developers,

I had my own code implemented with a new particle method in Gromacs 2016.4. but I don’t know how to make it compatible with restart utility. Could any one guide how to do so (For example, telling me what kind of information should be stored for restart, which class or struct is heading restart utility and how this class or struct is used in md.cpp)?

Thanks
Fan

The easiest way to get proper checkpoint handling is to make your code into a MDModule, if this is not already the case. You can look at the source for the DensityFitting module in src/gromacs/applied_force/densityfitting/densityfitting.cpp, in particular the class DensityFitting, for an example.

The MDModule interface you will implement contains a subscribeToSimulationSetupNotifications method. You can subscribe to the checkpoint reading and writing like such:

    void subscribeToSimulationSetupNotifications(MDModulesNotifiers* notifiers) override
    {
        // reading checkpoint data
        const auto checkpointDataReading = [this](MDModulesCheckpointReadingDataOnMain checkpointData) {
            readCheckpoint(checkpointData.checkpointedData_);
        };
        notifiers->checkpointingNotifier_.subscribe(checkpointDataReading);

        // writing checkpoint data
        const auto checkpointDataBroadcast = [this](MDModulesWriteCheckpointData checkpointData) {
            writeCheckpoint(checkpointData);
        };
        notifiers->checkpointingNotifier_.subscribe(checkpointDataBroadcast);
    }


You need to write the readCheckpoint and writeCheckpoint function depending on what you want to store/restore on restart. An example:

void  writeCheckpoint(gmx::MDModulesWriteCheckpointData checkpointData) {
    std::string currentkey = "my-data-1";
    checkpointData.builder_.addValue(currentkey, someDataINeedToSave);
        
        
    currentkey = "my-data-2";
    checkpointData.builder_.addValue(currentkey, someOtherData);
}

void readCheckpoint(const gmx::KeyValueTreeObject& checkpointData) {
        std::string  currentkey     = "my-data-1";
        someDataINeedToSave = checkpointData[currentkey].cast<decltype(someDataINeedToSave)>();
        
        currentkey     = "my-data-2";
        someOtherData = checkpointData[currentkey].cast<decltype(someOtherData)>();
}

What you need to save, is at least the state that is not in the tpr file or provided during the run (i.e., you don’t need to save mdp parameters - those are either provided when restarting using the MDModule interface. If you are using the ForceProvider interface, you will also get the atom position each step, so no need to save them yourself) or directly derivable from, say, the current step number. For instance, you might have a conserved quantity or some sort of virtual velocity you would need to save. Very dependent on exactly what you are doing.

1 Like

Hi ebriand,

Thank you for your suggestions and guidance.
I found src/gromacs/applied_force/densityfitting/densityfitting.cpp in Gromacs 2022, but I did not find it the Gromacs 2016.4 where my code is implemented. I wonder if the MDModule is also available in 2016.4 version?

Right, the above-described checkpoint interface was added ~2020. I’m not sure what facilities, if any, there are in 2016 for easy checkpoint handling.

Do you eventually intend to make your method public? If so, it might have benefit to make it a MDModule and keep it on top of the main branch.

I know this might mean a significant initial investment of time/ressources to port it, and then some additional effort to keep it up-to-date. The argument for doing this would be:

  • Giving your method better reach: people will be reluctant to use a much older version of Gromacs, because of
    • Loss of performance compared to current version
    • Inability to build the software (software rot): despite theoretical backward compatibility promises, compiler and library change over time, leading to new error or bugs when building that version against modern version of its dependencies
    • Inability to get proper support: some features of 2016 have been superseded or changed, and users will be unable to get effective support for their problems on, for instance, this forum
  • Make it easy to release your method with each subsequent version of Gromacs
    • Keeping an out-of-tree module up to date with current main branch is a non-zero amount of work (maybe 1-2 day of work every few months - quite dependent on the specifics of your method), but it is much less than the work needed to upgrade a method from an older version to a new version in one go.

Otherwise, maybe developers around in 2016 can comment on the easiest way to add restart support in those days.

1 Like

Thank you for your reply.

I will try to see if I can port my code to latest version of Gromacs. But I don’t have experience with latest gromacs, so I asked in the forum with some details of new method.

https://gromacs.bioexcel.eu/t/port-my-code-to-latest-gromacs/5682

Hopefully, the developers of latest Gromacs can give me some guidances.