#endif
}
+void check_multi_int(FILE *log, const gmx_multisim_t *ms, int val,
+ const char *name,
+ gmx_bool bQuiet)
+{
+ int *ibuf, p;
+ gmx_bool bCompatible;
+
+ if (nullptr != log && !bQuiet)
+ {
+ fprintf(log, "Multi-checking %s ... ", name);
+ }
+
+ if (ms == nullptr)
+ {
+ gmx_fatal(FARGS,
+ "check_multi_int called with a NULL communication pointer");
+ }
+
+ snew(ibuf, ms->nsim);
+ ibuf[ms->sim] = val;
+ gmx_sumi_sim(ms->nsim, ibuf, ms);
+
+ bCompatible = TRUE;
+ for (p = 1; p < ms->nsim; p++)
+ {
+ bCompatible = bCompatible && (ibuf[p-1] == ibuf[p]);
+ }
+
+ if (bCompatible)
+ {
+ if (nullptr != log && !bQuiet)
+ {
+ fprintf(log, "OK\n");
+ }
+ }
+ else
+ {
+ if (nullptr != log)
+ {
+ fprintf(log, "\n%s is not equal for all subsystems\n", name);
+ for (p = 0; p < ms->nsim; p++)
+ {
+ fprintf(log, " subsystem %d: %d\n", p, ibuf[p]);
+ }
+ }
+ gmx_fatal(FARGS, "The %d subsystems are not compatible\n", ms->nsim);
+ }
+
+ sfree(ibuf);
+}
+
+void check_multi_int64(FILE *log, const gmx_multisim_t *ms,
+ int64_t val, const char *name,
+ gmx_bool bQuiet)
+{
+ int64_t *ibuf;
+ int p;
+ gmx_bool bCompatible;
+
+ if (nullptr != log && !bQuiet)
+ {
+ fprintf(log, "Multi-checking %s ... ", name);
+ }
+
+ if (ms == nullptr)
+ {
+ gmx_fatal(FARGS,
+ "check_multi_int called with a NULL communication pointer");
+ }
+
+ snew(ibuf, ms->nsim);
+ ibuf[ms->sim] = val;
+ gmx_sumli_sim(ms->nsim, ibuf, ms);
+
+ bCompatible = TRUE;
+ for (p = 1; p < ms->nsim; p++)
+ {
+ bCompatible = bCompatible && (ibuf[p-1] == ibuf[p]);
+ }
+
+ if (bCompatible)
+ {
+ if (nullptr != log && !bQuiet)
+ {
+ fprintf(log, "OK\n");
+ }
+ }
+ else
+ {
+ // TODO Part of this error message would also be good to go to
+ // stderr (from one rank of one sim only)
+ if (nullptr != log)
+ {
+ fprintf(log, "\n%s is not equal for all subsystems\n", name);
+ for (p = 0; p < ms->nsim; p++)
+ {
+ char strbuf[255];
+ /* first make the format string */
+ snprintf(strbuf, 255, " subsystem %%d: %s\n",
+ "%" PRId64);
+ fprintf(log, strbuf, p, ibuf[p]);
+ }
+ }
+ gmx_fatal(FARGS, "The %d subsystems are not compatible\n", ms->nsim);
+ }
+
+ sfree(ibuf);
+}
+
const char *opt2fn_master(const char *opt, int nfile, const t_filenm fnm[],
t_commrec *cr)
{
void gmx_sumd_sim(int nr, double r[], const struct gmx_multisim_t *ms);
/* Calculate the sum over the simulations of an array of doubles */
+void check_multi_int(FILE *log, const gmx_multisim_t *ms,
+ int val, const char *name,
+ gmx_bool bQuiet);
+void check_multi_int64(FILE *log, const gmx_multisim_t *ms,
+ int64_t val, const char *name,
+ gmx_bool bQuiet);
+/* Check if val is the same on all processors for a mdrun -multidir run
+ * The string name is used to print to the log file and in a fatal error
+ * if the val's don't match. If bQuiet is true and the check passes,
+ * no output is written.
+ */
+
#if GMX_DOUBLE
#define gmx_sum gmx_sumd
#define gmx_sum_sim gmx_sumd_sim
#include "gromacs/gmxlib/network.h"
#include "gromacs/math/functions.h"
#include "gromacs/math/vec.h"
-#include "gromacs/mdlib/main.h"
#include "gromacs/mdtypes/commrec.h"
#include "gromacs/mdtypes/fcdata.h"
#include "gromacs/mdtypes/inputrec.h"
#include "gromacs/math/do_fit.h"
#include "gromacs/math/functions.h"
#include "gromacs/math/vec.h"
-#include "gromacs/mdlib/main.h"
#include "gromacs/mdtypes/commrec.h"
#include "gromacs/mdtypes/fcdata.h"
#include "gromacs/mdtypes/inputrec.h"
+++ /dev/null
-/*
- * This file is part of the GROMACS molecular simulation package.
- *
- * Copyright (c) 1991-2000, University of Groningen, The Netherlands.
- * Copyright (c) 2001-2004, The GROMACS development team.
- * Copyright (c) 2013,2014,2015,2016,2017,2018, by the GROMACS development team, led by
- * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
- * and including many others, as listed in the AUTHORS file in the
- * top-level source directory and at http://www.gromacs.org.
- *
- * GROMACS is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public License
- * as published by the Free Software Foundation; either version 2.1
- * of the License, or (at your option) any later version.
- *
- * GROMACS is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with GROMACS; if not, see
- * http://www.gnu.org/licenses, or write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * If you want to redistribute modifications to GROMACS, please
- * consider that scientific software is very special. Version
- * control is crucial - bugs must be traceable. We will be happy to
- * consider code for inclusion in the official distribution, but
- * derived work must not be called official GROMACS. Details are found
- * in the README & COPYING files - if they are missing, get the
- * official version at http://www.gromacs.org.
- *
- * To help us fund GROMACS development, we humbly ask that you cite
- * the research papers on the package. Check out http://www.gromacs.org.
- */
-#include "gmxpre.h"
-
-#include "main.h"
-
-#include "config.h"
-
-#include <cstdio>
-#include <cstdlib>
-#include <cstring>
-
-#include <string>
-
-#include "gromacs/commandline/filenm.h"
-#include "gromacs/fileio/gmxfio.h"
-#include "gromacs/gmxlib/network.h"
-#include "gromacs/mdtypes/commrec.h"
-#include "gromacs/utility/binaryinformation.h"
-#include "gromacs/utility/cstringutil.h"
-#include "gromacs/utility/exceptions.h"
-#include "gromacs/utility/fatalerror.h"
-#include "gromacs/utility/futil.h"
-#include "gromacs/utility/gmxassert.h"
-#include "gromacs/utility/gmxmpi.h"
-#include "gromacs/utility/path.h"
-#include "gromacs/utility/programcontext.h"
-#include "gromacs/utility/smalloc.h"
-#include "gromacs/utility/snprintf.h"
-#include "gromacs/utility/stringutil.h"
-#include "gromacs/utility/sysinfo.h"
-
-/* The source code in this file should be thread-safe.
- Please keep it that way. */
-
-// TODO move this to multi-sim module
-void check_multi_int(FILE *log, const gmx_multisim_t *ms, int val,
- const char *name,
- gmx_bool bQuiet)
-{
- int *ibuf, p;
- gmx_bool bCompatible;
-
- if (nullptr != log && !bQuiet)
- {
- fprintf(log, "Multi-checking %s ... ", name);
- }
-
- if (ms == nullptr)
- {
- gmx_fatal(FARGS,
- "check_multi_int called with a NULL communication pointer");
- }
-
- snew(ibuf, ms->nsim);
- ibuf[ms->sim] = val;
- gmx_sumi_sim(ms->nsim, ibuf, ms);
-
- bCompatible = TRUE;
- for (p = 1; p < ms->nsim; p++)
- {
- bCompatible = bCompatible && (ibuf[p-1] == ibuf[p]);
- }
-
- if (bCompatible)
- {
- if (nullptr != log && !bQuiet)
- {
- fprintf(log, "OK\n");
- }
- }
- else
- {
- if (nullptr != log)
- {
- fprintf(log, "\n%s is not equal for all subsystems\n", name);
- for (p = 0; p < ms->nsim; p++)
- {
- fprintf(log, " subsystem %d: %d\n", p, ibuf[p]);
- }
- }
- gmx_fatal(FARGS, "The %d subsystems are not compatible\n", ms->nsim);
- }
-
- sfree(ibuf);
-}
-
-// TODO move this to multi-sim module
-void check_multi_int64(FILE *log, const gmx_multisim_t *ms,
- int64_t val, const char *name,
- gmx_bool bQuiet)
-{
- int64_t *ibuf;
- int p;
- gmx_bool bCompatible;
-
- if (nullptr != log && !bQuiet)
- {
- fprintf(log, "Multi-checking %s ... ", name);
- }
-
- if (ms == nullptr)
- {
- gmx_fatal(FARGS,
- "check_multi_int called with a NULL communication pointer");
- }
-
- snew(ibuf, ms->nsim);
- ibuf[ms->sim] = val;
- gmx_sumli_sim(ms->nsim, ibuf, ms);
-
- bCompatible = TRUE;
- for (p = 1; p < ms->nsim; p++)
- {
- bCompatible = bCompatible && (ibuf[p-1] == ibuf[p]);
- }
-
- if (bCompatible)
- {
- if (nullptr != log && !bQuiet)
- {
- fprintf(log, "OK\n");
- }
- }
- else
- {
- // TODO Part of this error message would also be good to go to
- // stderr (from one rank of one sim only)
- if (nullptr != log)
- {
- fprintf(log, "\n%s is not equal for all subsystems\n", name);
- for (p = 0; p < ms->nsim; p++)
- {
- char strbuf[255];
- /* first make the format string */
- snprintf(strbuf, 255, " subsystem %%d: %s\n",
- "%" PRId64);
- fprintf(log, strbuf, p, ibuf[p]);
- }
- }
- gmx_fatal(FARGS, "The %d subsystems are not compatible\n", ms->nsim);
- }
-
- sfree(ibuf);
-}
-
-
-void gmx_log_open(const char *lognm, const t_commrec *cr,
- gmx_bool bAppendFiles, FILE** fplog)
-{
- int pid;
- char host[256];
- char timebuf[STRLEN];
- FILE *fp = *fplog;
-
- if (!bAppendFiles)
- {
- fp = gmx_fio_fopen(lognm, bAppendFiles ? "a+" : "w+" );
- }
-
- gmx_fatal_set_log_file(fp);
-
- /* Get some machine parameters */
- gmx_gethostname(host, 256);
- pid = gmx_getpid();
- gmx_format_current_time(timebuf, STRLEN);
-
- if (bAppendFiles)
- {
- fprintf(fp,
- "\n"
- "\n"
- "-----------------------------------------------------------\n"
- "Restarting from checkpoint, appending to previous log file.\n"
- "\n"
- );
- }
-
- fprintf(fp,
- "Log file opened on %s"
- "Host: %s pid: %d rank ID: %d number of ranks: %d\n",
- timebuf, host, pid, cr->nodeid, cr->nnodes);
- try
- {
- gmx::BinaryInformationSettings settings;
- settings.extendedInfo(true);
- settings.copyright(!bAppendFiles);
- gmx::printBinaryInformation(fp, gmx::getProgramContext(), settings);
- }
- GMX_CATCH_ALL_AND_EXIT_WITH_FATAL_ERROR;
- fprintf(fp, "\n");
-
- fflush(fp);
-
- *fplog = fp;
-}
-
-void gmx_log_close(FILE *fp)
-{
- if (fp)
- {
- gmx_fatal_set_log_file(nullptr);
- gmx_fio_fclose(fp);
- }
-}
-
-// TODO move this to multi-sim module
-gmx_multisim_t *init_multisystem(MPI_Comm comm,
- gmx::ArrayRef<const std::string> multidirs)
-{
- gmx_multisim_t *ms;
-#if GMX_MPI
- MPI_Group mpi_group_world;
- int *rank;
-#endif
-
- if (multidirs.empty())
- {
- return nullptr;
- }
-
- if (!GMX_LIB_MPI && !multidirs.empty())
- {
- gmx_fatal(FARGS, "mdrun -multidir is only supported when GROMACS has been "
- "configured with a proper external MPI library.");
- }
-
- if (multidirs.size() == 1)
- {
- /* NOTE: It would be nice if this special case worked, but this requires checks/tests. */
- gmx_fatal(FARGS, "To run mdrun in multiple simulation mode, more then one "
- "actual simulation is required. The single simulation case is not supported.");
- }
-
-#if GMX_MPI
- int numRanks;
- MPI_Comm_size(comm, &numRanks);
- if (numRanks % multidirs.size() != 0)
- {
- gmx_fatal(FARGS, "The number of ranks (%d) is not a multiple of the number of simulations (%td)", numRanks, multidirs.size());
- }
-
- int numRanksPerSim = numRanks/multidirs.size();
- int rankWithinComm;
- MPI_Comm_rank(comm, &rankWithinComm);
-
- if (debug)
- {
- fprintf(debug, "We have %td simulations, %d ranks per simulation, local simulation is %d\n", multidirs.size(), numRanksPerSim, rankWithinComm/numRanksPerSim);
- }
-
- ms = new gmx_multisim_t;
- ms->nsim = multidirs.size();
- ms->sim = rankWithinComm/numRanksPerSim;
- /* Create a communicator for the master nodes */
- snew(rank, ms->nsim);
- for (int i = 0; i < ms->nsim; i++)
- {
- rank[i] = i*numRanksPerSim;
- }
- MPI_Comm_group(comm, &mpi_group_world);
- MPI_Group_incl(mpi_group_world, ms->nsim, rank, &ms->mpi_group_masters);
- sfree(rank);
- MPI_Comm_create(MPI_COMM_WORLD, ms->mpi_group_masters,
- &ms->mpi_comm_masters);
-
-#if !MPI_IN_PLACE_EXISTS
- /* initialize the MPI_IN_PLACE replacement buffers */
- snew(ms->mpb, 1);
- ms->mpb->ibuf = NULL;
- ms->mpb->libuf = NULL;
- ms->mpb->fbuf = NULL;
- ms->mpb->dbuf = NULL;
- ms->mpb->ibuf_alloc = 0;
- ms->mpb->libuf_alloc = 0;
- ms->mpb->fbuf_alloc = 0;
- ms->mpb->dbuf_alloc = 0;
-#endif
-
- // TODO This should throw upon error
- gmx_chdir(multidirs[ms->sim].c_str());
-#else
- GMX_UNUSED_VALUE(comm);
- ms = nullptr;
-#endif
-
- return ms;
-}
-
-void done_multisim(gmx_multisim_t *ms)
-{
- if (nullptr != ms)
- {
- done_mpi_in_place_buf(ms->mpb);
- delete ms;
- }
-}
gmx_add_libgromacs_sources(
integrator.cpp
+ logging.cpp
md.cpp
minimize.cpp
+ multisim.cpp
+ replicaexchange.cpp
runner.cpp
tpi.cpp
)
--- /dev/null
+/*
+ * This file is part of the GROMACS molecular simulation package.
+ *
+ * Copyright (c) 2018, by the GROMACS development team, led by
+ * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
+ * and including many others, as listed in the AUTHORS file in the
+ * top-level source directory and at http://www.gromacs.org.
+ *
+ * GROMACS is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * as published by the Free Software Foundation; either version 2.1
+ * of the License, or (at your option) any later version.
+ *
+ * GROMACS is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with GROMACS; if not, see
+ * http://www.gnu.org/licenses, or write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * If you want to redistribute modifications to GROMACS, please
+ * consider that scientific software is very special. Version
+ * control is crucial - bugs must be traceable. We will be happy to
+ * consider code for inclusion in the official distribution, but
+ * derived work must not be called official GROMACS. Details are found
+ * in the README & COPYING files - if they are missing, get the
+ * official version at http://www.gromacs.org.
+ *
+ * To help us fund GROMACS development, we humbly ask that you cite
+ * the research papers on the package. Check out http://www.gromacs.org.
+ */
+/*! \internal \file
+ *
+ * \brief Implements the MD log file handling routines.
+ *
+ * \author Mark Abraham <mark.j.abraham@gmail.com>
+ * \ingroup module_mdrun
+ */
+#include "gmxpre.h"
+
+#include "logging.h"
+
+#include "gromacs/fileio/gmxfio.h"
+#include "gromacs/mdtypes/commrec.h"
+#include "gromacs/utility/binaryinformation.h"
+#include "gromacs/utility/cstringutil.h"
+#include "gromacs/utility/exceptions.h"
+#include "gromacs/utility/fatalerror.h"
+#include "gromacs/utility/programcontext.h"
+#include "gromacs/utility/smalloc.h"
+#include "gromacs/utility/sysinfo.h"
+
+void gmx_log_open(const char *lognm, const t_commrec *cr,
+ gmx_bool bAppendFiles, FILE** fplog)
+{
+ int pid;
+ char host[256];
+ char timebuf[STRLEN];
+ FILE *fp = *fplog;
+
+ if (!bAppendFiles)
+ {
+ fp = gmx_fio_fopen(lognm, bAppendFiles ? "a+" : "w+" );
+ }
+
+ gmx_fatal_set_log_file(fp);
+
+ /* Get some machine parameters */
+ gmx_gethostname(host, 256);
+ pid = gmx_getpid();
+ gmx_format_current_time(timebuf, STRLEN);
+
+ if (bAppendFiles)
+ {
+ fprintf(fp,
+ "\n"
+ "\n"
+ "-----------------------------------------------------------\n"
+ "Restarting from checkpoint, appending to previous log file.\n"
+ "\n"
+ );
+ }
+
+ fprintf(fp,
+ "Log file opened on %s"
+ "Host: %s pid: %d rank ID: %d number of ranks: %d\n",
+ timebuf, host, pid, cr->nodeid, cr->nnodes);
+ try
+ {
+ gmx::BinaryInformationSettings settings;
+ settings.extendedInfo(true);
+ settings.copyright(!bAppendFiles);
+ gmx::printBinaryInformation(fp, gmx::getProgramContext(), settings);
+ }
+ GMX_CATCH_ALL_AND_EXIT_WITH_FATAL_ERROR;
+ fprintf(fp, "\n");
+
+ fflush(fp);
+
+ *fplog = fp;
+}
+
+void gmx_log_close(FILE *fp)
+{
+ if (fp)
+ {
+ gmx_fatal_set_log_file(nullptr);
+ gmx_fio_fclose(fp);
+ }
+}
--- /dev/null
+/*
+ * This file is part of the GROMACS molecular simulation package.
+ *
+ * Copyright (c) 2018, by the GROMACS development team, led by
+ * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
+ * and including many others, as listed in the AUTHORS file in the
+ * top-level source directory and at http://www.gromacs.org.
+ *
+ * GROMACS is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * as published by the Free Software Foundation; either version 2.1
+ * of the License, or (at your option) any later version.
+ *
+ * GROMACS is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with GROMACS; if not, see
+ * http://www.gnu.org/licenses, or write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * If you want to redistribute modifications to GROMACS, please
+ * consider that scientific software is very special. Version
+ * control is crucial - bugs must be traceable. We will be happy to
+ * consider code for inclusion in the official distribution, but
+ * derived work must not be called official GROMACS. Details are found
+ * in the README & COPYING files - if they are missing, get the
+ * official version at http://www.gromacs.org.
+ *
+ * To help us fund GROMACS development, we humbly ask that you cite
+ * the research papers on the package. Check out http://www.gromacs.org.
+ */
+/*! \libinternal \file
+ *
+ * \brief Declares the MD log file handling routines.
+ *
+ * \author Mark Abraham <mark.j.abraham@gmail.com>
+ * \inlibraryapi
+ * \ingroup module_mdrun
+ */
+#ifndef GMX_MDRUN_LOGGING_H
+#define GMX_MDRUN_LOGGING_H
+
+#include <cstdio>
+
+#include "gromacs/utility/basedefinitions.h"
+
+struct gmx_multisim_t;
+struct t_commrec;
+
+/*! \brief Open the log file */
+void gmx_log_open(const char *fn, const t_commrec *cr,
+ gmx_bool bAppendFiles, FILE** /*fplog*/);
+
+/*! \brief Close the log file */
+void gmx_log_close(FILE *fp);
+
+#endif
#include "gromacs/mdlib/nb_verlet.h"
#include "gromacs/mdlib/nbnxn_gpu_data_mgmt.h"
#include "gromacs/mdlib/ns.h"
-#include "gromacs/mdlib/repl_ex.h"
#include "gromacs/mdlib/shellfc.h"
#include "gromacs/mdlib/sighandler.h"
#include "gromacs/mdlib/sim_util.h"
#include "gromacs/utility/smalloc.h"
#include "integrator.h"
+#include "replicaexchange.h"
#ifdef GMX_FAHCORE
#include "corewrap.h"
--- /dev/null
+/*
+ * This file is part of the GROMACS molecular simulation package.
+ *
+ * Copyright (c) 2018, by the GROMACS development team, led by
+ * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
+ * and including many others, as listed in the AUTHORS file in the
+ * top-level source directory and at http://www.gromacs.org.
+ *
+ * GROMACS is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * as published by the Free Software Foundation; either version 2.1
+ * of the License, or (at your option) any later version.
+ *
+ * GROMACS is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with GROMACS; if not, see
+ * http://www.gnu.org/licenses, or write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * If you want to redistribute modifications to GROMACS, please
+ * consider that scientific software is very special. Version
+ * control is crucial - bugs must be traceable. We will be happy to
+ * consider code for inclusion in the official distribution, but
+ * derived work must not be called official GROMACS. Details are found
+ * in the README & COPYING files - if they are missing, get the
+ * official version at http://www.gromacs.org.
+ *
+ * To help us fund GROMACS development, we humbly ask that you cite
+ * the research papers on the package. Check out http://www.gromacs.org.
+ */
+/*! \internal \file
+ *
+ * \brief Implements the multi-simulation support routines.
+ *
+ * \author Mark Abraham <mark.j.abraham@gmail.com>
+ * \ingroup module_mdrun
+ */
+#include "gmxpre.h"
+
+#include "multisim.h"
+
+#include "config.h"
+
+#include "gromacs/gmxlib/network.h"
+#include "gromacs/mdtypes/commrec.h"
+#include "gromacs/utility/fatalerror.h"
+#include "gromacs/utility/futil.h"
+#include "gromacs/utility/smalloc.h"
+
+gmx_multisim_t *init_multisystem(MPI_Comm comm,
+ gmx::ArrayRef<const std::string> multidirs)
+{
+ gmx_multisim_t *ms;
+#if GMX_MPI
+ MPI_Group mpi_group_world;
+ int *rank;
+#endif
+
+ if (multidirs.empty())
+ {
+ return nullptr;
+ }
+
+ if (!GMX_LIB_MPI && !multidirs.empty())
+ {
+ gmx_fatal(FARGS, "mdrun -multidir is only supported when GROMACS has been "
+ "configured with a proper external MPI library.");
+ }
+
+ if (multidirs.size() == 1)
+ {
+ /* NOTE: It would be nice if this special case worked, but this requires checks/tests. */
+ gmx_fatal(FARGS, "To run mdrun in multiple simulation mode, more then one "
+ "actual simulation is required. The single simulation case is not supported.");
+ }
+
+#if GMX_MPI
+ int numRanks;
+ MPI_Comm_size(comm, &numRanks);
+ if (numRanks % multidirs.size() != 0)
+ {
+ gmx_fatal(FARGS, "The number of ranks (%d) is not a multiple of the number of simulations (%td)", numRanks, multidirs.size());
+ }
+
+ int numRanksPerSim = numRanks/multidirs.size();
+ int rankWithinComm;
+ MPI_Comm_rank(comm, &rankWithinComm);
+
+ if (debug)
+ {
+ fprintf(debug, "We have %td simulations, %d ranks per simulation, local simulation is %d\n", multidirs.size(), numRanksPerSim, rankWithinComm/numRanksPerSim);
+ }
+
+ ms = new gmx_multisim_t;
+ ms->nsim = multidirs.size();
+ ms->sim = rankWithinComm/numRanksPerSim;
+ /* Create a communicator for the master nodes */
+ snew(rank, ms->nsim);
+ for (int i = 0; i < ms->nsim; i++)
+ {
+ rank[i] = i*numRanksPerSim;
+ }
+ MPI_Comm_group(comm, &mpi_group_world);
+ MPI_Group_incl(mpi_group_world, ms->nsim, rank, &ms->mpi_group_masters);
+ sfree(rank);
+ MPI_Comm_create(MPI_COMM_WORLD, ms->mpi_group_masters,
+ &ms->mpi_comm_masters);
+
+#if !MPI_IN_PLACE_EXISTS
+ /* initialize the MPI_IN_PLACE replacement buffers */
+ snew(ms->mpb, 1);
+ ms->mpb->ibuf = NULL;
+ ms->mpb->libuf = NULL;
+ ms->mpb->fbuf = NULL;
+ ms->mpb->dbuf = NULL;
+ ms->mpb->ibuf_alloc = 0;
+ ms->mpb->libuf_alloc = 0;
+ ms->mpb->fbuf_alloc = 0;
+ ms->mpb->dbuf_alloc = 0;
+#endif
+
+ // TODO This should throw upon error
+ gmx_chdir(multidirs[ms->sim].c_str());
+#else
+ GMX_UNUSED_VALUE(comm);
+ ms = nullptr;
+#endif
+
+ return ms;
+}
+
+void done_multisim(gmx_multisim_t *ms)
+{
+ if (nullptr != ms)
+ {
+ done_mpi_in_place_buf(ms->mpb);
+ delete ms;
+ }
+}
/*
* This file is part of the GROMACS molecular simulation package.
*
- * Copyright (c) 1991-2000, University of Groningen, The Netherlands.
- * Copyright (c) 2001-2004, The GROMACS development team.
- * Copyright (c) 2013,2014,2015,2016,2018, by the GROMACS development team, led by
+ * Copyright (c) 2018, by the GROMACS development team, led by
* Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
* and including many others, as listed in the AUTHORS file in the
* top-level source directory and at http://www.gromacs.org.
* To help us fund GROMACS development, we humbly ask that you cite
* the research papers on the package. Check out http://www.gromacs.org.
*/
-#ifndef GMX_MDLIB_MAIN_H
-#define GMX_MDLIB_MAIN_H
-
-#include <cstdio>
+/*! \libinternal \file
+ *
+ * \brief Declares the multi-simulation support routines.
+ *
+ * \author Mark Abraham <mark.j.abraham@gmail.com>
+ * \inlibraryapi
+ * \ingroup module_mdrun
+ */
+#ifndef GMX_MDRUN_MULTISIM_H
+#define GMX_MDRUN_MULTISIM_H
#include <string>
-#include <vector>
#include "gromacs/utility/arrayref.h"
-#include "gromacs/utility/basedefinitions.h"
#include "gromacs/utility/gmxmpi.h"
struct gmx_multisim_t;
-struct t_commrec;
-struct t_filenm;
-
-void gmx_log_open(const char *fn, const t_commrec *cr,
- gmx_bool bAppendFiles, FILE** /*fplog*/);
-/* Open the log file, if necessary (nprocs > 1) the logfile name is
- * communicated around the ring.
- */
-
-void gmx_log_close(FILE *fp);
-/* Close the log file */
-
-void check_multi_int(FILE *log, const gmx_multisim_t *ms,
- int val, const char *name,
- gmx_bool bQuiet);
-void check_multi_int64(FILE *log, const gmx_multisim_t *ms,
- int64_t val, const char *name,
- gmx_bool bQuiet);
-/* Check if val is the same on all processors for a mdrun -multidir run
- * The string name is used to print to the log file and in a fatal error
- * if the val's don't match. If bQuiet is true and the check passes,
- * no output is written.
- */
+/*! \brief Initializes multi-simulations.
+ *
+ * Splits the communication into multidirs.size() separate
+ * simulations, if >1, and creates a communication structure between
+ * the master these simulations. */
gmx_multisim_t *init_multisystem(MPI_Comm comm,
gmx::ArrayRef<const std::string> multidirs);
-/* Splits the communication into multidirs.size() separate simulations, if >1,
- * and creates a communication structure between the master
- * these simulations.
- */
//! Cleans up multi-system handler.
void done_multisim(gmx_multisim_t *ms);
* the research papers on the package. Check out http://www.gromacs.org.
*/
+/*! \internal \file
+ *
+ * \brief Implements the replica exchange routines.
+ *
+ * \author David van der Spoel <david.vanderspoel@icm.uu.se>
+ * \author Mark Abraham <mark.j.abraham@gmail.com>
+ * \ingroup module_mdrun
+ */
#include "gmxpre.h"
-#include "repl_ex.h"
+#include "replicaexchange.h"
#include "config.h"
#include "gromacs/gmxlib/network.h"
#include "gromacs/math/units.h"
#include "gromacs/math/vec.h"
-#include "gromacs/mdlib/main.h"
+#include "gromacs/mdrun/multisim.h"
#include "gromacs/mdtypes/commrec.h"
#include "gromacs/mdtypes/enerdata.h"
#include "gromacs/mdtypes/inputrec.h"
#include "gromacs/utility/pleasecite.h"
#include "gromacs/utility/smalloc.h"
+//! Helps cut off probability values.
+constexpr int c_probabilityCutoff = 100;
-#define PROBABILITYCUTOFF 100
/* we don't bother evaluating if events are more rare than exp(-100) = 3.7x10^-44 */
-//! Rank in the multisimulaiton
+//! Rank in the multisimulation
#define MSRANK(ms, nodeid) (nodeid)
+//! Enum for replica exchange flavours
enum {
ereTEMP, ereLAMBDA, ereENDSINGLE, ereTL, ereNR
};
+/*! \brief Strings describing replica exchange flavours.
+ *
+ * end_single_marker merely notes the end of single variable replica
+ * exchange. All types higher than it are multiple replica exchange
+ * methods.
+ *
+ * Eventually, should add 'pressure', 'temperature and pressure',
+ * 'lambda_and_pressure', 'temperature_lambda_pressure'?; Let's wait
+ * until we feel better about the pressure control methods giving
+ * exact ensembles. Right now, we assume constant pressure */
static const char *erename[ereNR] = { "temperature", "lambda", "end_single_marker", "temperature and lambda"};
-/* end_single_marker merely notes the end of single variable replica exchange. All types higher than
- it are multiple replica exchange methods */
-/* Eventually, should add 'pressure', 'temperature and pressure', 'lambda_and_pressure', 'temperature_lambda_pressure'?;
- Let's wait until we feel better about the pressure control methods giving exact ensembles. Right now, we assume constant pressure */
-typedef struct gmx_repl_ex
+//! Working data for replica exchange.
+struct gmx_repl_ex
{
- int repl; /* replica ID */
- int nrepl; /* total number of replica */
- real temp; /* temperature */
- int type; /* replica exchange type from ere enum */
- real **q; /* quantity, e.g. temperature or lambda; first index is ere, second index is replica ID */
- gmx_bool bNPT; /* use constant pressure and temperature */
- real *pres; /* replica pressures */
- int *ind; /* replica indices */
- int *allswaps; /* used for keeping track of all the replica swaps */
- int nst; /* replica exchange interval (number of steps) */
- int nex; /* number of exchanges per interval */
- int seed; /* random seed */
- int nattempt[2]; /* number of even and odd replica change attempts */
- real *prob_sum; /* sum of probabilities */
- int **nmoves; /* number of moves between replicas i and j */
- int *nexchange; /* i-th element of the array is the number of exchanges between replica i-1 and i */
-
- /* these are helper arrays for replica exchange; allocated here so they
- don't have to be allocated each time */
+ //! Replica ID
+ int repl;
+ //! Total number of replica
+ int nrepl;
+ //! Temperature
+ real temp;
+ //! Replica exchange type from ere enum
+ int type;
+ //! Quantity, e.g. temperature or lambda; first index is ere, second index is replica ID
+ real **q;
+ //! Use constant pressure and temperature
+ gmx_bool bNPT;
+ //! Replica pressures
+ real *pres;
+ //! Replica indices
+ int *ind;
+ //! Used for keeping track of all the replica swaps
+ int *allswaps;
+ //! Replica exchange interval (number of steps)
+ int nst;
+ //! Number of exchanges per interval
+ int nex;
+ //! Random seed
+ int seed;
+ //! Number of even and odd replica change attempts
+ int nattempt[2];
+ //! Sum of probabilities
+ real *prob_sum;
+ //! Number of moves between replicas i and j
+ int **nmoves;
+ //! i-th element of the array is the number of exchanges between replica i-1 and i
+ int *nexchange;
+
+ /*! \brief Helper arrays for replica exchange; allocated here
+ * so they don't have to be allocated each time */
+ //! \{
int *destinations;
int **cyclic;
int **order;
int *tmpswap;
gmx_bool *incycle;
gmx_bool *bEx;
+ //! \}
- /* helper arrays to hold the quantities that are exchanged */
+ //! Helper arrays to hold the quantities that are exchanged.
+ //! \{
real *prob;
real *Epot;
real *beta;
real *Vol;
real **de;
+ //! \}
+};
-} t_gmx_repl_ex;
+// TODO We should add Doxygen here some time.
+//! \cond
static gmx_bool repl_quantity(const gmx_multisim_t *ms,
struct gmx_repl_ex *re, int ere, real q)
}
else
{
- if (delta > PROBABILITYCUTOFF)
+ if (delta > c_probabilityCutoff)
{
prob[0] = 0;
}
}
else
{
- if (delta > PROBABILITYCUTOFF)
+ if (delta > c_probabilityCutoff)
{
prob[i] = 0;
}
/* print the transition matrix */
print_transition_matrix(fplog, re->nrepl, re->nmoves, re->nattempt);
}
+
+//! \endcond
* To help us fund GROMACS development, we humbly ask that you cite
* the research papers on the package. Check out http://www.gromacs.org.
*/
-
-#ifndef _repl_ex_h
-#define _repl_ex_h
+/*! \libinternal \file
+ *
+ * \brief Declares the routines for replica exchange.
+ *
+ * \author David van der Spoel <david.vanderspoel@icm.uu.se>
+ * \author Mark Abraham <mark.j.abraham@gmail.com>
+ *
+ * \ingroup module_mdrun
+ */
+#ifndef GMX_MDRUN_REPLICAEXCHANGE_H
+#define GMX_MDRUN_REPLICAEXCHANGE_H
#include <cstdio>
struct t_inputrec;
class t_state;
-/* The parameters for the replica exchange algorithm */
+/*! \libinternal
+ * \brief The parameters for the replica exchange algorithm. */
struct ReplicaExchangeParameters
{
ReplicaExchangeParameters() :
{
}
- int exchangeInterval; /* Interval in steps at which to attempt exchanges, 0 means no replica exchange */
- int numExchanges; /* The number of exchanges to attempt at an exchange step */
- int randomSeed; /* The random seed, -1 means generate a seed */
+ //! Interval in steps at which to attempt exchanges, 0 means no replica exchange.
+ int exchangeInterval;
+ //! The number of exchanges to attempt at an exchange step.
+ int numExchanges;
+ //! The random seed, -1 means generate a seed.
+ int randomSeed;
};
-/* Abstract type for replica exchange */
+//! Abstract type for replica exchange
typedef struct gmx_repl_ex *gmx_repl_ex_t;
+/*! \brief Setup function.
+ *
+ * Should only be called on the master ranks */
gmx_repl_ex_t
init_replica_exchange(FILE *fplog,
const gmx_multisim_t *ms,
int numAtomsInSystem,
const t_inputrec *ir,
const ReplicaExchangeParameters &replExParams);
-/* Should only be called on the master ranks */
+/*! \brief Attempts replica exchange.
+ *
+ * Should be called on all ranks. When running each replica in
+ * parallel, this routine collects the state on the master rank before
+ * exchange. With domain decomposition, the global state after
+ * exchange is stored in state and still needs to be redistributed
+ * over the ranks.
+ *
+ * \returns TRUE if the state has been exchanged.
+ */
gmx_bool replica_exchange(FILE *fplog,
const t_commrec *cr,
const gmx_multisim_t *ms,
t_state *state, const gmx_enerdata_t *enerd,
t_state *state_local,
int64_t step, real time);
-/* Attempts replica exchange, should be called on all ranks.
- * Returns TRUE if this state has been exchanged.
- * When running each replica in parallel,
- * this routine collects the state on the master rank before exchange.
- * With domain decomposition, the global state after exchange is stored
- * in state and still needs to be redistributed over the ranks.
- */
+/*! \brief Prints replica exchange statistics to the log file.
+ *
+ * Should only be called on the master ranks */
void print_replica_exchange_statistics(FILE *fplog, gmx_repl_ex_t re);
-/* Should only be called on the master ranks */
-#endif /* _repl_ex_h */
+#endif
#include "gromacs/mdlib/calc_verletbuf.h"
#include "gromacs/mdlib/forcerec.h"
#include "gromacs/mdlib/gmx_omp_nthreads.h"
-#include "gromacs/mdlib/main.h"
#include "gromacs/mdlib/makeconstraints.h"
#include "gromacs/mdlib/md_support.h"
#include "gromacs/mdlib/mdatoms.h"
#include "gromacs/mdlib/nbnxn_search.h"
#include "gromacs/mdlib/nbnxn_tuning.h"
#include "gromacs/mdlib/qmmm.h"
-#include "gromacs/mdlib/repl_ex.h"
#include "gromacs/mdlib/sighandler.h"
#include "gromacs/mdlib/sim_util.h"
+#include "gromacs/mdrun/logging.h"
+#include "gromacs/mdrun/multisim.h"
#include "gromacs/mdrunutility/mdmodules.h"
#include "gromacs/mdrunutility/threadaffinity.h"
#include "gromacs/mdtypes/commrec.h"
#include "gromacs/utility/stringutil.h"
#include "integrator.h"
+#include "replicaexchange.h"
#ifdef GMX_FAHCORE
#include "corewrap.h"
#include "gromacs/hardware/hw_info.h"
#include "gromacs/math/vec.h"
#include "gromacs/mdlib/mdrun.h"
-#include "gromacs/mdlib/repl_ex.h"
#include "gromacs/utility/basedefinitions.h"
#include "gromacs/utility/real.h"
+#include "replicaexchange.h"
+
struct gmx_output_env_t;
struct ReplicaExchangeParameters;
struct t_commrec;
#include "gromacs/fileio/checkpoint.h"
#include "gromacs/fileio/gmxfio.h"
#include "gromacs/gmxlib/network.h"
-#include "gromacs/mdlib/main.h"
#include "gromacs/mdtypes/commrec.h"
#include "gromacs/utility/basedefinitions.h"
#include "gromacs/utility/fatalerror.h"
#include "gromacs/commandline/pargs.h"
#include "gromacs/domdec/domdec.h"
#include "gromacs/gmxlib/network.h"
-#include "gromacs/mdlib/main.h"
#include "gromacs/mdlib/mdrun.h"
-#include "gromacs/mdlib/repl_ex.h"
+#include "gromacs/mdrun/logging.h"
+#include "gromacs/mdrun/multisim.h"
+#include "gromacs/mdrun/replicaexchange.h"
#include "gromacs/mdrun/runner.h"
#include "gromacs/mdrunutility/handlerestart.h"
#include "gromacs/mdtypes/commrec.h"