Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Pass multisim record to Colvars for mwABF #4

Draft
wants to merge 1 commit into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 9 additions & 7 deletions src/external/colvars/colvarbias_abf.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -99,14 +99,16 @@ int colvarbias_abf::init(std::string const &conf)
get_keyval(conf, "shared", shared_on, false);
if (shared_on) {
cvm::main()->cite_feature("Multiple-walker ABF implementation");
if ((proxy->replica_enabled() != COLVARS_OK) ||
(proxy->num_replicas() <= 1)) {
return cvm::error("Error: shared ABF requires more than one replica.",
COLVARS_INPUT_ERROR);
// Do not check for replicas in Gromacs preprocessing, in VMD, etc.
if (proxy->simulation_running()) {
if (proxy->replica_enabled() != COLVARS_OK || proxy->num_replicas() <= 1) {
return cvm::error("Error: shared ABF requires more than one replica.",
COLVARS_INPUT_ERROR);
} else {
cvm::log("shared ABF will be applied among "+
cvm::to_str(proxy->num_replicas()) + " replicas.\n");
}
}
cvm::log("shared ABF will be applied among "+
cvm::to_str(proxy->num_replicas()) + " replicas.\n");

// If shared_freq is not set, we default to output_freq
get_keyval(conf, "sharedFreq", shared_freq, output_freq);
}
Expand Down
74 changes: 72 additions & 2 deletions src/gromacs/applied_forces/colvars/colvarproxygromacs.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@
*/

#include "colvarproxygromacs.h"
#include "gromacs/mdrunutility/multisim.h"

#include <sstream>

Expand All @@ -56,7 +57,9 @@ ColvarProxyGromacs::ColvarProxyGromacs(const std::string& colvarsConfigString,
bool doParsing,
const std::map<std::string, std::string>& inputStrings,
real ensembleTemperature,
int seed) :
int seed,
const gmx_multisim_t* ms,
bool simRunning) :
gmxAtoms_(atoms), pbcType_(pbcType), logger_(logger), doParsing_(doParsing)
{
engine_name_ = "GROMACS";
Expand All @@ -77,6 +80,9 @@ ColvarProxyGromacs::ColvarProxyGromacs(const std::string& colvarsConfigString,
// $ units -ts 'k' 'kJ/mol/K/avogadro'
boltzmann_ = 0.0083144621;

// False in grompp but true in mdrun
b_simulation_running = simRunning;

// Get the thermostat temperature.
set_target_temperature(ensembleTemperature);

Expand All @@ -92,7 +98,6 @@ ColvarProxyGromacs::ColvarProxyGromacs(const std::string& colvarsConfigString,
rng_.seed(seed);
}


// Read configuration file and set up the proxy during pre-processing
// and during simulation phase but only on the master node.
if (doParsing)
Expand All @@ -119,6 +124,18 @@ ColvarProxyGromacs::ColvarProxyGromacs(const std::string& colvarsConfigString,
cvm::log("Initializing the colvars proxy object.\n");
}

if (isMultiSim(ms)) {
inter_me = ms->simulationIndex_;
inter_num = ms->numSimulations_;
inter_comm = ms->mainRanksComm_;
cvm::log("Multiple-replica simulation: this is replica " + cvm::to_str(inter_me + 1)
+ " of " + cvm::to_str(inter_num));
} else {
inter_me = 0;
inter_num = 0;
inter_comm = MPI_COMM_NULL;
}

int errorCode = colvarproxy::setup();
errorCode |= colvars->read_config_string(colvarsConfigString);
errorCode |= colvars->update_engine_parameters();
Expand Down Expand Up @@ -242,6 +259,59 @@ void ColvarProxyGromacs::updateAtomProperties(int index)
atoms_charges[index] = gmxAtoms_.atom[atoms_ids[index]].q;
}


// multi-replica support

int ColvarProxyGromacs::replica_enabled()
{
return (inter_comm != MPI_COMM_NULL) ? COLVARS_OK : COLVARS_NOT_IMPLEMENTED;
}


int ColvarProxyGromacs::replica_index()
{
return inter_me;
}


int ColvarProxyGromacs::num_replicas()
{
return inter_num;
}


void ColvarProxyGromacs::replica_comm_barrier()
{
MPI_Barrier(inter_comm);
}


int ColvarProxyGromacs::replica_comm_recv(char* msg_data,
int buf_len, int src_rep)
{
MPI_Status status;
int retval;

retval = MPI_Recv(msg_data,buf_len,MPI_CHAR,src_rep,0,inter_comm,&status);
if (retval == MPI_SUCCESS) {
MPI_Get_count(&status, MPI_CHAR, &retval);
} else retval = 0;
return retval;
}


int ColvarProxyGromacs::replica_comm_send(char* msg_data,
int msg_len, int dest_rep)
{
int retval;
retval = MPI_Send(msg_data,msg_len,MPI_CHAR,dest_rep,0,inter_comm);
if (retval == MPI_SUCCESS) {
retval = msg_len;
} else retval = 0;
return retval;
}


ColvarProxyGromacs::~ColvarProxyGromacs()
{
if (colvars != nullptr)
Expand Down
25 changes: 23 additions & 2 deletions src/gromacs/applied_forces/colvars/colvarproxygromacs.h
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,8 @@
#include "gromacs/random/threefry.h"
#include "gromacs/topology/atoms.h"
#include "gromacs/utility/logger.h"

#include "gromacs/utility/gmxmpi.h"
struct gmx_multisim_t;

namespace gmx
{
Expand Down Expand Up @@ -83,6 +84,8 @@ class ColvarProxyGromacs : public colvarproxy
//! Activate or not the parsing of the Colvars config file
bool doParsing_;

MPI_Comm inter_comm; // MPI comm with 1 root proc from each world
int inter_me, inter_num; // rank for the inter replica comm

// GROMACS random number generation.
DefaultRandomEngine rng_; // gromacs random number generator
Expand All @@ -102,6 +105,8 @@ class ColvarProxyGromacs : public colvarproxy
* \param[in] inputStrings Input files stored as string in the TPR's KVT
* \param[in] ensembleTemperature the constant ensemble temperature
* \param[in] seed the colvars seed for random number generator
* \param[in] ms the multisim record
* \param[in] simRunning whether we are in mdrun (as opposed to grompp)
*/
ColvarProxyGromacs(const std::string& colvarsConfigString,
t_atoms atoms,
Expand All @@ -110,7 +115,9 @@ class ColvarProxyGromacs : public colvarproxy
bool doParsing,
const std::map<std::string, std::string>& inputStrings,
real ensembleTemperature,
int seed);
int seed,
const gmx_multisim_t* ms,
bool simRunning);
~ColvarProxyGromacs() override;

//! Update colvars topology of one atom mass and charge from the GROMACS topology
Expand Down Expand Up @@ -138,6 +145,20 @@ class ColvarProxyGromacs : public colvarproxy

//! Compute the minimum distance with respect to the PBC between 2 atoms.
cvm::rvector position_distance(cvm::atom_pos const& pos1, cvm::atom_pos const& pos2) const override;

//! Are we running a multi-replica simulation? (multisim in gromacs)
int replica_enabled() override;
//! Index of the local replica in the array
int replica_index() override;
//! Total number of replicas
int num_replicas() override;

//! Communication barrier between replicas
void replica_comm_barrier() override;
//! MPI receive between replicas
int replica_comm_recv(char *msg_data, int buf_len, int src_rep) override;
//! MPI send between replicas
int replica_comm_send(char *msg_data, int msg_len, int dest_rep) override;
};

} // namespace gmx
Expand Down
15 changes: 14 additions & 1 deletion src/gromacs/applied_forces/colvars/colvarsMDModule.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,11 @@
#include "colvarsoptions.h"
#include "colvarssimulationsparameters.h"

#include <iostream>

//struct gmx_multisim_t;
#include "gromacs/mdrunutility/multisim.h"


namespace gmx
{
Expand Down Expand Up @@ -87,7 +92,7 @@ class ColvarsMDModule final : public IMDModule
* KeyValueTreeObjectBuilder as parameter
* - Acess topology using gmx_mtop_t notification
* - Access MDLogger for notifications output
* - Access warninp for for grompp warnings output
* - Access warning for for grompp warnings output
* - Coordinates, PBC and box for setting up the proxy
*/
void subscribeToPreProcessingNotifications(MDModulesNotifiers* notifier) override
Expand Down Expand Up @@ -182,6 +187,13 @@ class ColvarsMDModule final : public IMDModule
};
notifier->simulationSetupNotifier_.subscribe(setCommFunction);

// Retrieve the Multisim Record during simulations setup
const auto setMultisimFunction = [this](const gmx_multisim_t *ms) {
std::cout << "GETTING MULTISIM: " << ms->numSimulations_ << "simulations\n";
this->ColvarsSimulationsParameters_.setMultisim(ms);
};
notifier->simulationSetupNotifier_.subscribe(setMultisimFunction);

// setting the simulation time step
const auto setSimulationTimeStepFunction = [this](const SimulationTimeStep& simulationTimeStep) {
this->ColvarsSimulationsParameters_.setSimulationTimeStep(simulationTimeStep.delta_t);
Expand Down Expand Up @@ -241,6 +253,7 @@ class ColvarsMDModule final : public IMDModule
colvarsOptions_.colvarsSeed(),
ColvarsSimulationsParameters_.localAtomSetManager(),
ColvarsSimulationsParameters_.comm(),
ColvarsSimulationsParameters_.ms(),
ColvarsSimulationsParameters_.simulationTimeStep(),
colvarsOptions_.colvarsAtomCoords(),
colvarsOptions_.colvarsOutputPrefix(),
Expand Down
4 changes: 3 additions & 1 deletion src/gromacs/applied_forces/colvars/colvarsforceprovider.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@
#include "gromacs/mdtypes/commrec.h"
#include "gromacs/mdtypes/enerdata.h"
#include "gromacs/mdtypes/forceoutput.h"
#include "gromacs/mdrunutility/multisim.h"


namespace gmx
Expand Down Expand Up @@ -155,11 +156,12 @@ ColvarsForceProvider::ColvarsForceProvider(const std::string& colvarsConfigStrin
int seed,
LocalAtomSetManager* localAtomSetManager,
const t_commrec* cr,
const gmx_multisim_t* ms,
double simulationTimeStep,
const std::vector<RVec>& colvarsCoords,
const std::string& outputPrefix,
const ColvarsForceProviderState& state) :
ColvarProxyGromacs(colvarsConfigString, atoms, pbcType, logger, MAIN(cr), inputStrings, ensembleTemperature, seed),
ColvarProxyGromacs(colvarsConfigString, atoms, pbcType, logger, MAIN(cr), inputStrings, ensembleTemperature, seed, ms, true),
stateToCheckpoint_(state)
{

Expand Down
3 changes: 2 additions & 1 deletion src/gromacs/applied_forces/colvars/colvarsforceprovider.h
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@

#include "colvarproxygromacs.h"


struct gmx_multisim_t;
namespace gmx
{

Expand Down Expand Up @@ -178,6 +178,7 @@ class ColvarsForceProvider final : public ColvarProxyGromacs, public IForceProvi
int seed,
LocalAtomSetManager* localAtomSetManager,
const t_commrec* cr,
const gmx_multisim_t* ms,
double simulationTimeStep,
const std::vector<RVec>& colvarsCoords,
const std::string& outputPrefix,
Expand Down
5 changes: 3 additions & 2 deletions src/gromacs/applied_forces/colvars/colvarspreprocessor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -62,10 +62,11 @@ ColvarsPreProcessor::ColvarsPreProcessor(const std::string& colvarsConfigStrin
true,
std::map<std::string, std::string>(),
ensembleTemperature,
seed),
seed,
nullptr,
false),
x_(x)
{

// Initialize t_pbc struct
set_pbc(&gmxPbc_, pbcType, box);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,16 @@ const t_commrec* ColvarsSimulationsParameters::comm() const
return cr_;
}

void ColvarsSimulationsParameters::setMultisim(const gmx_multisim_t *ms)
{
ms_ = ms;
}

const gmx_multisim_t* ColvarsSimulationsParameters::ms() const
{
return ms_;
}


void ColvarsSimulationsParameters::setLogger(const MDLogger& logger)
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@
#include "gromacs/pbcutil/pbc.h"
#include "gromacs/topology/atoms.h"
#include "gromacs/utility/logger.h"
struct gmx_multisim_t;

namespace gmx
{
Expand Down Expand Up @@ -104,7 +105,12 @@ class ColvarsSimulationsParameters
//! Return the communicator
const t_commrec* comm() const;

/*! \brief Set the logger for QMMM during mdrun
//! Set the Multisim record
void setMultisim(const gmx_multisim_t *ms);
//! Return Multisim record
const gmx_multisim_t* ms() const;

/*! \brief Set the logger for Colvars during mdrun
* \param[in] logger Logger instance to be used for output
*/
void setLogger(const MDLogger& logger);
Expand All @@ -123,6 +129,8 @@ class ColvarsSimulationsParameters
t_atoms gmxAtoms_;
//! The communicator
const t_commrec* cr_;
//! The multisim record
const gmx_multisim_t *ms_;
//! MDLogger for notifications during mdrun
const MDLogger* logger_ = nullptr;

Expand Down
1 change: 1 addition & 0 deletions src/gromacs/mdrun/runner.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1795,6 +1795,7 @@ int Mdrunner::mdrunner()
if (thisRankHasDuty(cr, DUTY_PP))
{
setupNotifier.notify(*cr);
setupNotifier.notify(ms);
setupNotifier.notify(&atomSets);
setupNotifier.notify(mtop);
setupNotifier.notify(inputrec->pbcType);
Expand Down
2 changes: 2 additions & 0 deletions src/gromacs/mdrunutility/mdmodulesnotifiers.h
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ struct gmx_mtop_t;
class WarningHandler;
enum class PbcType : int;
struct t_inputrec;
struct gmx_multisim_t;

namespace gmx
{
Expand Down Expand Up @@ -374,6 +375,7 @@ struct MDModulesNotifiers
SeparatePmeRanksPermitted*,
const PbcType&,
const SimulationTimeStep&,
const gmx_multisim_t*,
const t_commrec&,
const MdRunInputFilename&,
const EdrOutputFilename&>::type simulationSetupNotifier_;
Expand Down