2 * This file is part of the GROMACS molecular simulation package.
4 * Copyright (c) 2008,2009,2010,2011,2012,2013,2014,2015,2016, by the GROMACS development team, led by
5 * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
6 * and including many others, as listed in the AUTHORS file in the
7 * top-level source directory and at http://www.gromacs.org.
9 * GROMACS is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU Lesser General Public License
11 * as published by the Free Software Foundation; either version 2.1
12 * of the License, or (at your option) any later version.
14 * GROMACS is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * Lesser General Public License for more details.
19 * You should have received a copy of the GNU Lesser General Public
20 * License along with GROMACS; if not, see
21 * http://www.gnu.org/licenses, or write to the Free Software Foundation,
22 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
24 * If you want to redistribute modifications to GROMACS, please
25 * consider that scientific software is very special. Version
26 * control is crucial - bugs must be traceable. We will be happy to
27 * consider code for inclusion in the official distribution, but
28 * derived work must not be called official GROMACS. Details are found
29 * in the README & COPYING files - if they are missing, get the
30 * official version at http://www.gromacs.org.
32 * To help us fund GROMACS development, we humbly ask that you cite
33 * the research papers on the package. Check out http://www.gromacs.org.
36 /* The source code in this file should be thread-safe.
37 Please keep it that way. */
40 #include "checkpoint.h"
49 #if GMX_NATIVE_WINDOWS
51 #include <sys/locking.h>
54 #include "buildinfo.h"
55 #include "gromacs/fileio/filetypes.h"
56 #include "gromacs/fileio/gmxfio.h"
57 #include "gromacs/fileio/gmxfio-xdr.h"
58 #include "gromacs/fileio/xdr_datatype.h"
59 #include "gromacs/fileio/xdrf.h"
60 #include "gromacs/gmxlib/network.h"
61 #include "gromacs/math/vec.h"
62 #include "gromacs/math/vecdump.h"
63 #include "gromacs/math/vectypes.h"
64 #include "gromacs/mdtypes/commrec.h"
65 #include "gromacs/mdtypes/df_history.h"
66 #include "gromacs/mdtypes/energyhistory.h"
67 #include "gromacs/mdtypes/inputrec.h"
68 #include "gromacs/mdtypes/md_enums.h"
69 #include "gromacs/mdtypes/state.h"
70 #include "gromacs/trajectory/trajectoryframe.h"
71 #include "gromacs/utility/baseversion.h"
72 #include "gromacs/utility/cstringutil.h"
73 #include "gromacs/utility/fatalerror.h"
74 #include "gromacs/utility/futil.h"
75 #include "gromacs/utility/gmxassert.h"
76 #include "gromacs/utility/int64_to_int.h"
77 #include "gromacs/utility/programcontext.h"
78 #include "gromacs/utility/smalloc.h"
79 #include "gromacs/utility/sysinfo.h"
80 #include "gromacs/utility/txtdump.h"
86 #define CPT_MAGIC1 171817
87 #define CPT_MAGIC2 171819
88 #define CPTSTRLEN 1024
90 /* cpt_version should normally only be changed
91 * when the header of footer format changes.
92 * The state data format itself is backward and forward compatible.
93 * But old code can not read a new entry that is present in the file
94 * (but can read a new format when new entries are not present).
96 static const int cpt_version = 16;
99 const char *est_names[estNR] =
102 "box", "box-rel", "box-v", "pres_prev",
103 "nosehoover-xi", "thermostat-integral",
104 "x", "v", "sdx-unsupported", "CGp", "LD-rng", "LD-rng-i",
105 "disre_initf", "disre_rm3tav",
106 "orire_initf", "orire_Dtav",
107 "svir_prev", "nosehoover-vxi", "v_eta", "vol0", "nhpres_xi", "nhpres_vxi", "fvir_prev", "fep_state", "MC-rng", "MC-rng-i"
111 eeksEKIN_N, eeksEKINH, eeksDEKINDL, eeksMVCOS, eeksEKINF, eeksEKINO, eeksEKINSCALEF, eeksEKINSCALEH, eeksVSCALE, eeksEKINTOTAL, eeksNR
114 const char *eeks_names[eeksNR] =
116 "Ekin_n", "Ekinh", "dEkindlambda", "mv_cos",
117 "Ekinf", "Ekinh_old", "EkinScaleF_NHC", "EkinScaleH_NHC", "Vscale_NHC", "Ekin_Total"
121 eenhENERGY_N, eenhENERGY_AVER, eenhENERGY_SUM, eenhENERGY_NSUM,
122 eenhENERGY_SUM_SIM, eenhENERGY_NSUM_SIM,
123 eenhENERGY_NSTEPS, eenhENERGY_NSTEPS_SIM,
124 eenhENERGY_DELTA_H_NN,
125 eenhENERGY_DELTA_H_LIST,
126 eenhENERGY_DELTA_H_STARTTIME,
127 eenhENERGY_DELTA_H_STARTLAMBDA,
131 const char *eenh_names[eenhNR] =
133 "energy_n", "energy_aver", "energy_sum", "energy_nsum",
134 "energy_sum_sim", "energy_nsum_sim",
135 "energy_nsteps", "energy_nsteps_sim",
137 "energy_delta_h_list",
138 "energy_delta_h_start_time",
139 "energy_delta_h_start_lambda"
142 /* free energy history variables -- need to be preserved over checkpoint */
144 edfhBEQUIL, edfhNATLAMBDA, edfhWLHISTO, edfhWLDELTA, edfhSUMWEIGHTS, edfhSUMDG, edfhSUMMINVAR, edfhSUMVAR,
145 edfhACCUMP, edfhACCUMM, edfhACCUMP2, edfhACCUMM2, edfhTIJ, edfhTIJEMP, edfhNR
147 /* free energy history variable names */
148 const char *edfh_names[edfhNR] =
150 "bEquilibrated", "N_at_state", "Wang-Landau Histogram", "Wang-Landau Delta", "Weights", "Free Energies", "minvar", "variance",
151 "accumulated_plus", "accumulated_minus", "accumulated_plus_2", "accumulated_minus_2", "Tij", "Tij_empirical"
154 //! Higher level vector element type, only used for formatting checkpoint dumps
155 enum class CptElementType
157 integer, //!< integer
158 real, //!< float or double, not linked to precision of type real
159 real3, //!< float[3] or double[3], not linked to precision of type real
160 matrix3x3 //!< float[3][3] or double[3][3], not linked to precision of type real
163 //! \brief Parts of the checkpoint state, only used for reporting
166 microState, //!< The microstate of the simulated system
167 kineticEnergy, //!< Kinetic energy, needed for T/P-coupling state
168 energyHistory, //!< Energy observable statistics
169 freeEnergyHistory //!< Free-energy state and observable statistics
172 //! \brief Return the name of a checkpoint entry based on part and part entry
173 static const char *entryName(StatePart part, int ecpt)
177 case StatePart::microState: return est_names [ecpt];
178 case StatePart::kineticEnergy: return eeks_names[ecpt];
179 case StatePart::energyHistory: return eenh_names[ecpt];
180 case StatePart::freeEnergyHistory: return edfh_names[ecpt];
186 static void cp_warning(FILE *fp)
188 fprintf(fp, "\nWARNING: Checkpoint file is corrupted or truncated\n\n");
191 static void cp_error()
193 gmx_fatal(FARGS, "Checkpoint file corrupted/truncated, or maybe you are out of disk space?");
196 static void do_cpt_string_err(XDR *xd, gmx_bool bRead, const char *desc, char **s, FILE *list)
202 if (xdr_string(xd, s, CPTSTRLEN) == 0)
208 fprintf(list, "%s = %s\n", desc, *s);
213 static int do_cpt_int(XDR *xd, const char *desc, int *i, FILE *list)
215 if (xdr_int(xd, i) == 0)
221 fprintf(list, "%s = %d\n", desc, *i);
226 static int do_cpt_u_chars(XDR *xd, const char *desc, int n, unsigned char *i, FILE *list)
230 fprintf(list, "%s = ", desc);
233 for (int j = 0; j < n && res; j++)
235 res &= xdr_u_char(xd, &i[j]);
238 fprintf(list, "%02x", i[j]);
253 static void do_cpt_int_err(XDR *xd, const char *desc, int *i, FILE *list)
255 if (do_cpt_int(xd, desc, i, list) < 0)
261 static void do_cpt_step_err(XDR *xd, const char *desc, gmx_int64_t *i, FILE *list)
263 char buf[STEPSTRSIZE];
265 if (xdr_int64(xd, i) == 0)
271 fprintf(list, "%s = %s\n", desc, gmx_step_str(*i, buf));
275 static void do_cpt_double_err(XDR *xd, const char *desc, double *f, FILE *list)
277 if (xdr_double(xd, f) == 0)
283 fprintf(list, "%s = %f\n", desc, *f);
287 static void do_cpt_real_err(XDR *xd, real *f)
290 bool_t res = xdr_double(xd, f);
292 bool_t res = xdr_float(xd, f);
300 static void do_cpt_n_rvecs_err(XDR *xd, const char *desc, int n, rvec f[], FILE *list)
302 for (int i = 0; i < n; i++)
304 for (int j = 0; j < DIM; j++)
306 do_cpt_real_err(xd, &f[i][j]);
312 pr_rvecs(list, 0, desc, f, n);
316 template <typename T>
324 // cppcheck-suppress unusedStructMember
325 static const int value = xdr_datatype_int;
329 struct xdr_type<float>
331 // cppcheck-suppress unusedStructMember
332 static const int value = xdr_datatype_float;
336 struct xdr_type<double>
338 // cppcheck-suppress unusedStructMember
339 static const int value = xdr_datatype_double;
342 //! \brief Returns size in byte of an xdr_datatype
343 static inline unsigned int sizeOfXdrType(int xdrType)
347 case xdr_datatype_int:
350 case xdr_datatype_float:
351 return sizeof(float);
353 case xdr_datatype_double:
354 return sizeof(double);
356 default: GMX_RELEASE_ASSERT(false, "XDR data type not implemented");
362 //! \brief Returns the XDR process function for i/o of an XDR type
363 static inline xdrproc_t xdrProc(int xdrType)
367 case xdr_datatype_int:
368 return reinterpret_cast<xdrproc_t>(xdr_int);
370 case xdr_datatype_float:
371 return reinterpret_cast<xdrproc_t>(xdr_float);
373 case xdr_datatype_double:
374 return reinterpret_cast<xdrproc_t>(xdr_double);
376 default: GMX_RELEASE_ASSERT(false, "XDR data type not implemented");
382 /*! \brief Lists or only reads an xdr vector from checkpoint file
384 * When list!=NULL reads and lists the \p nf vector elements of type \p xdrType.
385 * The header for the print is set by \p part and \p ecpt.
386 * The formatting of the printing is set by \p cptElementType.
387 * When list==NULL only reads the elements.
389 static bool_t listXdrVector(XDR *xd, StatePart part, int ecpt, int nf, int xdrType,
390 FILE *list, CptElementType cptElementType)
394 const unsigned int elemSize = sizeOfXdrType(xdrType);
395 std::vector<char> data(nf*elemSize);
396 res = xdr_vector(xd, data.data(), nf, elemSize, xdrProc(xdrType));
402 case xdr_datatype_int:
403 pr_ivec(list, 0, entryName(part, ecpt), reinterpret_cast<const int *>(data.data()), nf, TRUE);
405 case xdr_datatype_float:
407 if (cptElementType == CptElementType::real3)
409 // cppcheck-suppress invalidPointerCast
410 pr_rvecs(list, 0, entryName(part, ecpt), reinterpret_cast<const rvec *>(data.data()), nf/3);
415 /* Note: With double precision code dumping a single precision rvec will produce float iso rvec print, but that's a minor annoyance */
416 // cppcheck-suppress invalidPointerCast
417 pr_fvec(list, 0, entryName(part, ecpt), reinterpret_cast<const float *>(data.data()), nf, TRUE);
420 case xdr_datatype_double:
422 if (cptElementType == CptElementType::real3)
424 // cppcheck-suppress invalidPointerCast
425 pr_rvecs(list, 0, entryName(part, ecpt), reinterpret_cast<const rvec *>(data.data()), nf/3);
430 /* Note: With single precision code dumping a double precision rvec will produce float iso rvec print, but that's a minor annoyance */
431 // cppcheck-suppress invalidPointerCast
432 pr_dvec(list, 0, entryName(part, ecpt), reinterpret_cast<const double *>(data.data()), nf, TRUE);
435 default: GMX_RELEASE_ASSERT(false, "Data type not implemented for listing");
442 //! \brief Convert a double array, typed char*, to float
443 static void convertArrayRealPrecision(const char *c, float *v, int n)
445 const double *d = reinterpret_cast<const double *>(c);
446 for (int i = 0; i < n; i++)
448 v[i] = static_cast<float>(d[i]);
452 //! \brief Convert a float array, typed char*, to double
453 static void convertArrayRealPrecision(const char *c, double *v, int n)
455 const float *f = reinterpret_cast<const float *>(c);
456 for (int i = 0; i < n; i++)
458 v[i] = static_cast<double>(f[i]);
462 //! \brief Generate an error for trying to convert to integer
463 static void convertArrayRealPrecision(const char gmx_unused *c, int gmx_unused *v, int gmx_unused n)
465 GMX_RELEASE_ASSERT(false, "We only expect type mismatches between float and double, not integer");
468 /*! \brief Low-level routine for reading/writing a vector of reals from/to file.
470 * This is the only routine that does the actually i/o of real vector,
471 * all other routines are intermediate level routines for specific real
472 * data types, calling this routine.
473 * Currently this routine is (too) complex, since it handles both real *
474 * and std::vector<real>. Using real * is deprecated and this routine
475 * will simplify a lot when only std::vector needs to be supported.
477 * When not listing, we use either v or vector, depending on which is !=NULL.
478 * If nval >= 0, nval is used; on read this should match the passed value.
479 * If nval n<0, *nptr (with v) or vector->size() is used. On read using v,
480 * the value is stored in nptr
483 static int doVectorLow(XDR *xd, StatePart part, int ecpt, int sflags,
485 T **v, std::vector<T> *vector,
486 FILE *list, CptElementType cptElementType)
488 GMX_RELEASE_ASSERT(list != NULL || (v != NULL && vector == NULL) || (v == NULL && vector != NULL), "Without list, we should have exactly one of v and vector != NULL");
492 int numElemInTheFile;
497 GMX_RELEASE_ASSERT(nptr == NULL, "With nval>=0 we should have nptr==NULL");
498 numElemInTheFile = nval;
504 GMX_RELEASE_ASSERT(nptr != NULL, "With nval<0 we should have nptr!=NULL");
505 // cppcheck-suppress nullPointer
506 numElemInTheFile = *nptr;
510 numElemInTheFile = vector->size();
514 /* Read/write the vector element count */
515 res = xdr_int(xd, &numElemInTheFile);
520 /* Read/write the element data type */
521 gmx_constexpr int xdrTypeInTheCode = xdr_type<T>::value;
522 int xdrTypeInTheFile = xdrTypeInTheCode;
523 res = xdr_int(xd, &xdrTypeInTheFile);
529 if (list == NULL && (sflags & (1 << ecpt)))
533 if (numElemInTheFile != nval)
535 gmx_fatal(FARGS, "Count mismatch for state entry %s, code count is %d, file count is %d\n", entryName(part, ecpt), nval, numElemInTheFile);
538 else if (nptr != NULL)
540 *nptr = numElemInTheFile;
543 bool typesMatch = (xdrTypeInTheFile == xdrTypeInTheCode);
547 sprintf(buf, "mismatch for state entry %s, code precision is %s, file precision is %s",
548 entryName(part, ecpt),
549 xdr_datatype_names[xdrTypeInTheCode],
550 xdr_datatype_names[xdrTypeInTheFile]);
552 /* Matchting int and real should never occur, but check anyhow */
553 if (xdrTypeInTheFile == xdr_datatype_int ||
554 xdrTypeInTheCode == xdr_datatype_int)
556 gmx_fatal(FARGS, "Type %s: incompatible checkpoint formats or corrupted checkpoint file.", buf);
558 fprintf(stderr, "Precision %s\n", buf);
566 snew(*v, numElemInTheFile);
572 /* This conditional ensures that we don't resize on write.
573 * In particular in the state where this code was written
574 * PaddedRVecVector has a size of numElemInThefile and we
575 * don't want to loose that padding here.
577 if (vector->size() < static_cast<unsigned int>(numElemInTheFile))
579 vector->resize(numElemInTheFile);
587 vChar = reinterpret_cast<char *>(vp);
591 snew(vChar, numElemInTheFile*sizeOfXdrType(xdrTypeInTheFile));
593 res = xdr_vector(xd, vChar,
594 numElemInTheFile, sizeOfXdrType(xdrTypeInTheFile),
595 xdrProc(xdrTypeInTheFile));
603 /* In the old code float-double conversion came for free.
604 * In the new code we still support it, mainly because
605 * the tip4p_continue regression test makes use of this.
606 * It's an open question if we do or don't want to allow this.
608 convertArrayRealPrecision(vChar, vp, numElemInTheFile);
614 res = listXdrVector(xd, part, ecpt, numElemInTheFile, xdrTypeInTheFile,
615 list, cptElementType);
621 //! \brief Read/Write an std::vector
622 template <typename T>
623 static int doVector(XDR *xd, StatePart part, int ecpt, int sflags,
624 std::vector<T> *vector, FILE *list)
626 return doVectorLow<T>(xd, part, ecpt, sflags, -1, NULL, NULL, vector, list, CptElementType::real);
629 //! \brief Read/Write an std::vector, on read checks the number of elements matches \p numElements
630 template <typename T>
631 static int doVector(XDR *xd, StatePart part, int ecpt, int sflags,
632 int numElements, std::vector<T> *vector, FILE *list)
634 return doVectorLow<T>(xd, part, ecpt, sflags, numElements, NULL, NULL, vector, list, CptElementType::real);
637 //! \brief Read/Write a PaddedRVecVector, on read checks the number of elements matches \p numElements
638 static int doPaddedVector(XDR *xd, StatePart part, int ecpt, int sflags,
639 int numElements, PaddedRVecVector *v, FILE *list)
643 if (list == NULL && (sflags & (1 << ecpt)))
645 /* We resize the vector here to avoid pointer reallocation in
646 * do_cpte_reals_low. Note the we allocate 1 element extra for SIMD.
648 v->resize(numElements + 1);
649 v_rvec = as_rvec_array(v->data());
656 return doVectorLow<real>(xd, part, ecpt, sflags,
657 numElements*DIM, NULL, (real **)(&v_rvec), NULL,
658 list, CptElementType::real3);
661 /* This function stores n along with the reals for reading,
662 * but on reading it assumes that n matches the value in the checkpoint file,
663 * a fatal error is generated when this is not the case.
665 static int do_cpte_reals(XDR *xd, StatePart part, int ecpt, int sflags,
666 int n, real **v, FILE *list)
668 return doVectorLow<real>(xd, part, ecpt, sflags, n, NULL, v, NULL, list, CptElementType::real);
671 /* This function does the same as do_cpte_reals,
672 * except that on reading it ignores the passed value of *n
673 * and stores the value read from the checkpoint file in *n.
675 static int do_cpte_n_reals(XDR *xd, StatePart part, int ecpt, int sflags,
676 int *n, real **v, FILE *list)
678 return doVectorLow<real>(xd, part, ecpt, sflags, -1, n, v, NULL, list, CptElementType::real);
681 static int do_cpte_real(XDR *xd, StatePart part, int ecpt, int sflags,
684 return doVectorLow<real>(xd, part, ecpt, sflags, 1, NULL, &r, NULL, list, CptElementType::real);
687 static int do_cpte_ints(XDR *xd, StatePart part, int ecpt, int sflags,
688 int n, int **v, FILE *list)
690 return doVectorLow<int>(xd, part, ecpt, sflags, n, NULL, v, NULL, list, CptElementType::integer);
693 static int do_cpte_int(XDR *xd, StatePart part, int ecpt, int sflags,
696 return do_cpte_ints(xd, part, ecpt, sflags, 1, &i, list);
699 static int do_cpte_doubles(XDR *xd, StatePart part, int ecpt, int sflags,
700 int n, double **v, FILE *list)
702 return doVectorLow<double>(xd, part, ecpt, sflags, n, NULL, v, NULL, list, CptElementType::real);
705 static int do_cpte_double(XDR *xd, StatePart part, int ecpt, int sflags,
706 double *r, FILE *list)
708 return do_cpte_doubles(xd, part, ecpt, sflags, 1, &r, list);
711 static int do_cpte_matrix(XDR *xd, StatePart part, int ecpt, int sflags,
712 matrix v, FILE *list)
718 ret = doVectorLow<real>(xd, part, ecpt, sflags,
719 DIM*DIM, NULL, &vr, NULL, NULL, CptElementType::matrix3x3);
721 if (list && ret == 0)
723 pr_rvecs(list, 0, entryName(part, ecpt), v, DIM);
730 static int do_cpte_nmatrix(XDR *xd, StatePart part, int ecpt, int sflags,
731 int n, real **v, FILE *list)
735 char name[CPTSTRLEN];
742 for (i = 0; i < n; i++)
744 reti = doVectorLow<real>(xd, part, ecpt, sflags, n, NULL, &(v[i]), NULL, NULL, CptElementType::matrix3x3);
745 if (list && reti == 0)
747 sprintf(name, "%s[%d]", entryName(part, ecpt), i);
748 pr_reals(list, 0, name, v[i], n);
758 static int do_cpte_matrices(XDR *xd, StatePart part, int ecpt, int sflags,
759 int n, matrix **v, FILE *list)
762 matrix *vp, *va = NULL;
768 res = xdr_int(xd, &nf);
773 if (list == NULL && nf != n)
775 gmx_fatal(FARGS, "Count mismatch for state entry %s, code count is %d, file count is %d\n", entryName(part, ecpt), n, nf);
777 if (list || !(sflags & (1<<ecpt)))
790 snew(vr, nf*DIM*DIM);
791 for (i = 0; i < nf; i++)
793 for (j = 0; j < DIM; j++)
795 for (k = 0; k < DIM; k++)
797 vr[(i*DIM+j)*DIM+k] = vp[i][j][k];
801 ret = doVectorLow<real>(xd, part, ecpt, sflags,
802 nf*DIM*DIM, NULL, &vr, NULL, NULL,
803 CptElementType::matrix3x3);
804 for (i = 0; i < nf; i++)
806 for (j = 0; j < DIM; j++)
808 for (k = 0; k < DIM; k++)
810 vp[i][j][k] = vr[(i*DIM+j)*DIM+k];
816 if (list && ret == 0)
818 for (i = 0; i < nf; i++)
820 pr_rvecs(list, 0, entryName(part, ecpt), vp[i], DIM);
831 static void do_cpt_header(XDR *xd, gmx_bool bRead, int *file_version,
832 char **version, char **btime, char **buser, char **bhost,
834 char **fprog, char **ftime,
835 int *eIntegrator, int *simulation_part,
836 gmx_int64_t *step, double *t,
837 int *nnodes, int *dd_nc, int *npme,
838 int *natoms, int *ngtc, int *nnhpres, int *nhchainlength,
839 int *nlambda, int *flags_state,
840 int *flags_eks, int *flags_enh, int *flags_dfh,
841 int *nED, int *eSwapCoords,
857 res = xdr_int(xd, &magic);
860 gmx_fatal(FARGS, "The checkpoint file is empty/corrupted, or maybe you are out of disk space?");
862 if (magic != CPT_MAGIC1)
864 gmx_fatal(FARGS, "Start of file magic number mismatch, checkpoint file has %d, should be %d\n"
865 "The checkpoint file is corrupted or not a checkpoint file",
871 gmx_gethostname(fhost, 255);
873 do_cpt_string_err(xd, bRead, "GROMACS version", version, list);
874 do_cpt_string_err(xd, bRead, "GROMACS build time", btime, list);
875 do_cpt_string_err(xd, bRead, "GROMACS build user", buser, list);
876 do_cpt_string_err(xd, bRead, "GROMACS build host", bhost, list);
877 do_cpt_string_err(xd, bRead, "generating program", fprog, list);
878 do_cpt_string_err(xd, bRead, "generation time", ftime, list);
879 *file_version = cpt_version;
880 do_cpt_int_err(xd, "checkpoint file version", file_version, list);
881 if (*file_version > cpt_version)
883 gmx_fatal(FARGS, "Attempting to read a checkpoint file of version %d with code of version %d\n", *file_version, cpt_version);
885 if (*file_version >= 13)
887 do_cpt_int_err(xd, "GROMACS double precision", double_prec, list);
893 if (*file_version >= 12)
895 do_cpt_string_err(xd, bRead, "generating host", &fhost, list);
901 do_cpt_int_err(xd, "#atoms", natoms, list);
902 do_cpt_int_err(xd, "#T-coupling groups", ngtc, list);
903 if (*file_version >= 10)
905 do_cpt_int_err(xd, "#Nose-Hoover T-chains", nhchainlength, list);
911 if (*file_version >= 11)
913 do_cpt_int_err(xd, "#Nose-Hoover T-chains for barostat ", nnhpres, list);
919 if (*file_version >= 14)
921 do_cpt_int_err(xd, "# of total lambda states ", nlambda, list);
927 do_cpt_int_err(xd, "integrator", eIntegrator, list);
928 if (*file_version >= 3)
930 do_cpt_int_err(xd, "simulation part #", simulation_part, list);
934 *simulation_part = 1;
936 if (*file_version >= 5)
938 do_cpt_step_err(xd, "step", step, list);
942 do_cpt_int_err(xd, "step", &idum, list);
945 do_cpt_double_err(xd, "t", t, list);
946 do_cpt_int_err(xd, "#PP-ranks", nnodes, list);
948 do_cpt_int_err(xd, "dd_nc[x]", dd_nc ? &(dd_nc[0]) : &idum, list);
949 do_cpt_int_err(xd, "dd_nc[y]", dd_nc ? &(dd_nc[1]) : &idum, list);
950 do_cpt_int_err(xd, "dd_nc[z]", dd_nc ? &(dd_nc[2]) : &idum, list);
951 do_cpt_int_err(xd, "#PME-only ranks", npme, list);
952 do_cpt_int_err(xd, "state flags", flags_state, list);
953 if (*file_version >= 4)
955 do_cpt_int_err(xd, "ekin data flags", flags_eks, list);
956 do_cpt_int_err(xd, "energy history flags", flags_enh, list);
961 *flags_enh = (*flags_state >> (estORIRE_DTAV+1));
962 *flags_state = (*flags_state & ~((1<<(estORIRE_DTAV+1)) |
963 (1<<(estORIRE_DTAV+2)) |
964 (1<<(estORIRE_DTAV+3))));
966 if (*file_version >= 14)
968 do_cpt_int_err(xd, "df history flags", flags_dfh, list);
975 if (*file_version >= 15)
977 do_cpt_int_err(xd, "ED data sets", nED, list);
983 if (*file_version >= 16)
985 do_cpt_int_err(xd, "swap", eSwapCoords, list);
989 *eSwapCoords = eswapNO;
993 static int do_cpt_footer(XDR *xd, int file_version)
998 if (file_version >= 2)
1001 res = xdr_int(xd, &magic);
1006 if (magic != CPT_MAGIC2)
1015 static int do_cpt_state(XDR *xd,
1016 int fflags, t_state *state,
1021 const int nnht = state->nhchainlength*state->ngtc;
1022 const int nnhtp = state->nhchainlength*state->nnhpres;
1024 const StatePart part = StatePart::microState;
1025 const int sflags = state->flags;
1026 for (int i = 0; (i < estNR && ret == 0); i++)
1028 if (fflags & (1<<i))
1032 case estLAMBDA: ret = doVector<real>(xd, part, i, sflags, static_cast<int>(efptNR), &state->lambda, list); break;
1033 case estFEPSTATE: ret = do_cpte_int (xd, part, i, sflags, &state->fep_state, list); break;
1034 case estBOX: ret = do_cpte_matrix(xd, part, i, sflags, state->box, list); break;
1035 case estBOX_REL: ret = do_cpte_matrix(xd, part, i, sflags, state->box_rel, list); break;
1036 case estBOXV: ret = do_cpte_matrix(xd, part, i, sflags, state->boxv, list); break;
1037 case estPRES_PREV: ret = do_cpte_matrix(xd, part, i, sflags, state->pres_prev, list); break;
1038 case estSVIR_PREV: ret = do_cpte_matrix(xd, part, i, sflags, state->svir_prev, list); break;
1039 case estFVIR_PREV: ret = do_cpte_matrix(xd, part, i, sflags, state->fvir_prev, list); break;
1040 case estNH_XI: ret = doVector<double>(xd, part, i, sflags, nnht, &state->nosehoover_xi, list); break;
1041 case estNH_VXI: ret = doVector<double>(xd, part, i, sflags, nnht, &state->nosehoover_vxi, list); break;
1042 case estNHPRES_XI: ret = doVector<double>(xd, part, i, sflags, nnhtp, &state->nhpres_xi, list); break;
1043 case estNHPRES_VXI: ret = doVector<double>(xd, part, i, sflags, nnhtp, &state->nhpres_vxi, list); break;
1044 case estTC_INT: ret = doVector<double>(xd, part, i, sflags, state->ngtc, &state->therm_integral, list); break;
1045 case estVETA: ret = do_cpte_real(xd, part, i, sflags, &state->veta, list); break;
1046 case estVOL0: ret = do_cpte_real(xd, part, i, sflags, &state->vol0, list); break;
1047 case estX: ret = doPaddedVector(xd, part, i, sflags, state->natoms, &state->x, list); break;
1048 case estV: ret = doPaddedVector(xd, part, i, sflags, state->natoms, &state->v, list); break;
1049 /* The RNG entries are no longer written,
1050 * the next 4 lines are only for reading old files.
1052 case estLD_RNG: ret = do_cpte_ints(xd, part, i, sflags, 0, NULL, list); break;
1053 case estLD_RNGI: ret = do_cpte_ints(xd, part, i, sflags, 0, NULL, list); break;
1054 case estMC_RNG: ret = do_cpte_ints(xd, part, i, sflags, 0, NULL, list); break;
1055 case estMC_RNGI: ret = do_cpte_ints(xd, part, i, sflags, 0, NULL, list); break;
1056 case estDISRE_INITF: ret = do_cpte_real (xd, part, i, sflags, &state->hist.disre_initf, list); break;
1057 case estDISRE_RM3TAV: ret = do_cpte_n_reals(xd, part, i, sflags, &state->hist.ndisrepairs, &state->hist.disre_rm3tav, list); break;
1058 case estORIRE_INITF: ret = do_cpte_real (xd, part, i, sflags, &state->hist.orire_initf, list); break;
1059 case estORIRE_DTAV: ret = do_cpte_n_reals(xd, part, i, sflags, &state->hist.norire_Dtav, &state->hist.orire_Dtav, list); break;
1061 gmx_fatal(FARGS, "Unknown state entry %d\n"
1062 "You are reading a checkpoint file written by different code, which is not supported", i);
1070 static int do_cpt_ekinstate(XDR *xd, int fflags, ekinstate_t *ekins,
1075 const StatePart part = StatePart::kineticEnergy;
1076 for (int i = 0; (i < eeksNR && ret == 0); i++)
1078 if (fflags & (1<<i))
1083 case eeksEKIN_N: ret = do_cpte_int(xd, part, i, fflags, &ekins->ekin_n, list); break;
1084 case eeksEKINH: ret = do_cpte_matrices(xd, part, i, fflags, ekins->ekin_n, &ekins->ekinh, list); break;
1085 case eeksEKINF: ret = do_cpte_matrices(xd, part, i, fflags, ekins->ekin_n, &ekins->ekinf, list); break;
1086 case eeksEKINO: ret = do_cpte_matrices(xd, part, i, fflags, ekins->ekin_n, &ekins->ekinh_old, list); break;
1087 case eeksEKINTOTAL: ret = do_cpte_matrix(xd, part, i, fflags, ekins->ekin_total, list); break;
1088 case eeksEKINSCALEF: ret = doVector<double>(xd, part, i, fflags, ekins->ekin_n, &ekins->ekinscalef_nhc, list); break;
1089 case eeksVSCALE: ret = doVector<double>(xd, part, i, fflags, ekins->ekin_n, &ekins->vscale_nhc, list); break;
1090 case eeksEKINSCALEH: ret = doVector<double>(xd, part, i, fflags, ekins->ekin_n, &ekins->ekinscaleh_nhc, list); break;
1091 case eeksDEKINDL: ret = do_cpte_real(xd, part, i, fflags, &ekins->dekindl, list); break;
1092 case eeksMVCOS: ret = do_cpte_real(xd, part, i, fflags, &ekins->mvcos, list); break;
1094 gmx_fatal(FARGS, "Unknown ekin data state entry %d\n"
1095 "You are probably reading a new checkpoint file with old code", i);
1104 static int do_cpt_swapstate(XDR *xd, gmx_bool bRead,
1105 int eSwapCoords, swapstate_t **swapstatePtr, FILE *list)
1107 int swap_cpt_version = 2;
1109 if (eSwapCoords == eswapNO)
1114 if (*swapstatePtr == NULL)
1116 snew(*swapstatePtr, 1);
1118 swapstate_t *swapstate = *swapstatePtr;
1119 swapstate->bFromCpt = bRead;
1120 swapstate->eSwapCoords = eSwapCoords;
1122 do_cpt_int_err(xd, "swap checkpoint version", &swap_cpt_version, list);
1123 if (bRead && swap_cpt_version < 2)
1125 gmx_fatal(FARGS, "Cannot read checkpoint files that were written with old versions"
1126 "of the ion/water position swapping protocol.\n");
1129 do_cpt_int_err(xd, "swap coupling steps", &swapstate->nAverage, list);
1131 /* When reading, init_swapcoords has not been called yet,
1132 * so we have to allocate memory first. */
1133 do_cpt_int_err(xd, "number of ion types", &swapstate->nIonTypes, list);
1136 snew(swapstate->ionType, swapstate->nIonTypes);
1139 for (int ic = 0; ic < eCompNR; ic++)
1141 for (int ii = 0; ii < swapstate->nIonTypes; ii++)
1143 swapstateIons_t *gs = &swapstate->ionType[ii];
1147 do_cpt_int_err(xd, "swap requested atoms", &gs->nMolReq[ic], list);
1151 do_cpt_int_err(xd, "swap requested atoms p", gs->nMolReq_p[ic], list);
1156 do_cpt_int_err(xd, "swap influx net", &gs->inflow_net[ic], list);
1160 do_cpt_int_err(xd, "swap influx net p", gs->inflow_net_p[ic], list);
1163 if (bRead && (NULL == gs->nMolPast[ic]) )
1165 snew(gs->nMolPast[ic], swapstate->nAverage);
1168 for (int j = 0; j < swapstate->nAverage; j++)
1172 do_cpt_int_err(xd, "swap past atom counts", &gs->nMolPast[ic][j], list);
1176 do_cpt_int_err(xd, "swap past atom counts p", &gs->nMolPast_p[ic][j], list);
1182 /* Ion flux per channel */
1183 for (int ic = 0; ic < eChanNR; ic++)
1185 for (int ii = 0; ii < swapstate->nIonTypes; ii++)
1187 swapstateIons_t *gs = &swapstate->ionType[ii];
1191 do_cpt_int_err(xd, "channel flux A->B", &gs->fluxfromAtoB[ic], list);
1195 do_cpt_int_err(xd, "channel flux A->B p", gs->fluxfromAtoB_p[ic], list);
1200 /* Ion flux leakage */
1203 do_cpt_int_err(xd, "flux leakage", &swapstate->fluxleak, list);
1207 do_cpt_int_err(xd, "flux leakage", swapstate->fluxleak_p, list);
1211 for (int ii = 0; ii < swapstate->nIonTypes; ii++)
1213 swapstateIons_t *gs = &swapstate->ionType[ii];
1215 do_cpt_int_err(xd, "number of ions", &gs->nMol, list);
1219 snew(gs->channel_label, gs->nMol);
1220 snew(gs->comp_from, gs->nMol);
1223 do_cpt_u_chars(xd, "channel history", gs->nMol, gs->channel_label, list);
1224 do_cpt_u_chars(xd, "domain history", gs->nMol, gs->comp_from, list);
1227 /* Save the last known whole positions to checkpoint
1228 * file to be able to also make multimeric channels whole in PBC */
1229 do_cpt_int_err(xd, "Ch0 atoms", &swapstate->nat[eChan0], list);
1230 do_cpt_int_err(xd, "Ch1 atoms", &swapstate->nat[eChan1], list);
1233 snew(swapstate->xc_old_whole[eChan0], swapstate->nat[eChan0]);
1234 snew(swapstate->xc_old_whole[eChan1], swapstate->nat[eChan1]);
1235 do_cpt_n_rvecs_err(xd, "Ch0 whole x", swapstate->nat[eChan0], swapstate->xc_old_whole[eChan0], list);
1236 do_cpt_n_rvecs_err(xd, "Ch1 whole x", swapstate->nat[eChan1], swapstate->xc_old_whole[eChan1], list);
1240 do_cpt_n_rvecs_err(xd, "Ch0 whole x", swapstate->nat[eChan0], *swapstate->xc_old_whole_p[eChan0], list);
1241 do_cpt_n_rvecs_err(xd, "Ch1 whole x", swapstate->nat[eChan1], *swapstate->xc_old_whole_p[eChan1], list);
1248 static int do_cpt_enerhist(XDR *xd, gmx_bool bRead,
1249 int fflags, energyhistory_t *enerhist,
1254 /* This is stored/read for backward compatibility */
1255 int energyHistoryNumEnergies = 0;
1258 enerhist->nsteps = 0;
1260 enerhist->nsteps_sim = 0;
1261 enerhist->nsum_sim = 0;
1265 energyHistoryNumEnergies = enerhist->ener_sum_sim.size();
1268 delta_h_history_t *deltaH = enerhist->deltaHForeignLambdas.get();
1269 const StatePart part = StatePart::energyHistory;
1270 for (int i = 0; (i < eenhNR && ret == 0); i++)
1272 if (fflags & (1<<i))
1276 case eenhENERGY_N: ret = do_cpte_int(xd, part, i, fflags, &energyHistoryNumEnergies, list); break;
1277 case eenhENERGY_AVER: ret = doVector<double>(xd, part, i, fflags, energyHistoryNumEnergies, &enerhist->ener_ave, list); break;
1278 case eenhENERGY_SUM: ret = doVector<double>(xd, part, i, fflags, energyHistoryNumEnergies, &enerhist->ener_sum, list); break;
1279 case eenhENERGY_NSUM: do_cpt_step_err(xd, eenh_names[i], &enerhist->nsum, list); break;
1280 case eenhENERGY_SUM_SIM: ret = doVector<double>(xd, part, i, fflags, energyHistoryNumEnergies, &enerhist->ener_sum_sim, list); break;
1281 case eenhENERGY_NSUM_SIM: do_cpt_step_err(xd, eenh_names[i], &enerhist->nsum_sim, list); break;
1282 case eenhENERGY_NSTEPS: do_cpt_step_err(xd, eenh_names[i], &enerhist->nsteps, list); break;
1283 case eenhENERGY_NSTEPS_SIM: do_cpt_step_err(xd, eenh_names[i], &enerhist->nsteps_sim, list); break;
1284 case eenhENERGY_DELTA_H_NN:
1287 if (!bRead && deltaH != nullptr)
1289 numDeltaH = deltaH->dh.size();
1291 do_cpt_int_err(xd, eenh_names[i], &numDeltaH, list);
1294 if (deltaH == nullptr)
1296 enerhist->deltaHForeignLambdas.reset(new delta_h_history_t);
1297 deltaH = enerhist->deltaHForeignLambdas.get();
1299 deltaH->dh.resize(numDeltaH);
1300 deltaH->start_lambda_set = FALSE;
1304 case eenhENERGY_DELTA_H_LIST:
1305 for (auto dh : deltaH->dh)
1307 ret = doVector<real>(xd, part, i, fflags, &dh, list);
1310 case eenhENERGY_DELTA_H_STARTTIME:
1311 ret = do_cpte_double(xd, part, i, fflags, &(deltaH->start_time), list); break;
1312 case eenhENERGY_DELTA_H_STARTLAMBDA:
1313 ret = do_cpte_double(xd, part, i, fflags, &(deltaH->start_lambda), list); break;
1315 gmx_fatal(FARGS, "Unknown energy history entry %d\n"
1316 "You are probably reading a new checkpoint file with old code", i);
1321 if ((fflags & (1<<eenhENERGY_SUM)) && !(fflags & (1<<eenhENERGY_SUM_SIM)))
1323 /* Assume we have an old file format and copy sum to sum_sim */
1324 enerhist->ener_sum_sim = enerhist->ener_sum;
1327 if ( (fflags & (1<<eenhENERGY_NSUM)) &&
1328 !(fflags & (1<<eenhENERGY_NSTEPS)))
1330 /* Assume we have an old file format and copy nsum to nsteps */
1331 enerhist->nsteps = enerhist->nsum;
1333 if ( (fflags & (1<<eenhENERGY_NSUM_SIM)) &&
1334 !(fflags & (1<<eenhENERGY_NSTEPS_SIM)))
1336 /* Assume we have an old file format and copy nsum to nsteps */
1337 enerhist->nsteps_sim = enerhist->nsum_sim;
1343 static int do_cpt_df_hist(XDR *xd, int fflags, int nlambda, df_history_t **dfhistPtr, FILE *list)
1352 if (*dfhistPtr == NULL)
1354 snew(*dfhistPtr, 1);
1355 (*dfhistPtr)->nlambda = nlambda;
1356 init_df_history(*dfhistPtr, nlambda);
1358 df_history_t *dfhist = *dfhistPtr;
1360 const StatePart part = StatePart::freeEnergyHistory;
1361 for (int i = 0; (i < edfhNR && ret == 0); i++)
1363 if (fflags & (1<<i))
1367 case edfhBEQUIL: ret = do_cpte_int(xd, part, i, fflags, &dfhist->bEquil, list); break;
1368 case edfhNATLAMBDA: ret = do_cpte_ints(xd, part, i, fflags, nlambda, &dfhist->n_at_lam, list); break;
1369 case edfhWLHISTO: ret = do_cpte_reals(xd, part, i, fflags, nlambda, &dfhist->wl_histo, list); break;
1370 case edfhWLDELTA: ret = do_cpte_real(xd, part, i, fflags, &dfhist->wl_delta, list); break;
1371 case edfhSUMWEIGHTS: ret = do_cpte_reals(xd, part, i, fflags, nlambda, &dfhist->sum_weights, list); break;
1372 case edfhSUMDG: ret = do_cpte_reals(xd, part, i, fflags, nlambda, &dfhist->sum_dg, list); break;
1373 case edfhSUMMINVAR: ret = do_cpte_reals(xd, part, i, fflags, nlambda, &dfhist->sum_minvar, list); break;
1374 case edfhSUMVAR: ret = do_cpte_reals(xd, part, i, fflags, nlambda, &dfhist->sum_variance, list); break;
1375 case edfhACCUMP: ret = do_cpte_nmatrix(xd, part, i, fflags, nlambda, dfhist->accum_p, list); break;
1376 case edfhACCUMM: ret = do_cpte_nmatrix(xd, part, i, fflags, nlambda, dfhist->accum_m, list); break;
1377 case edfhACCUMP2: ret = do_cpte_nmatrix(xd, part, i, fflags, nlambda, dfhist->accum_p2, list); break;
1378 case edfhACCUMM2: ret = do_cpte_nmatrix(xd, part, i, fflags, nlambda, dfhist->accum_m2, list); break;
1379 case edfhTIJ: ret = do_cpte_nmatrix(xd, part, i, fflags, nlambda, dfhist->Tij, list); break;
1380 case edfhTIJEMP: ret = do_cpte_nmatrix(xd, part, i, fflags, nlambda, dfhist->Tij_empirical, list); break;
1383 gmx_fatal(FARGS, "Unknown df history entry %d\n"
1384 "You are probably reading a new checkpoint file with old code", i);
1393 /* This function stores the last whole configuration of the reference and
1394 * average structure in the .cpt file
1396 static int do_cpt_EDstate(XDR *xd, gmx_bool bRead,
1397 int nED, edsamstate_t **EDstatePtr, FILE *list)
1404 if (*EDstatePtr == NULL)
1406 snew(*EDstatePtr, 1);
1408 edsamstate_t *EDstate = *EDstatePtr;
1410 EDstate->bFromCpt = bRead;
1413 /* When reading, init_edsam has not been called yet,
1414 * so we have to allocate memory first. */
1417 snew(EDstate->nref, EDstate->nED);
1418 snew(EDstate->old_sref, EDstate->nED);
1419 snew(EDstate->nav, EDstate->nED);
1420 snew(EDstate->old_sav, EDstate->nED);
1423 /* Read/write the last whole conformation of SREF and SAV for each ED dataset (usually only one) */
1424 for (int i = 0; i < EDstate->nED; i++)
1428 /* Reference structure SREF */
1429 sprintf(buf, "ED%d # of atoms in reference structure", i+1);
1430 do_cpt_int_err(xd, buf, &EDstate->nref[i], list);
1431 sprintf(buf, "ED%d x_ref", i+1);
1434 snew(EDstate->old_sref[i], EDstate->nref[i]);
1435 do_cpt_n_rvecs_err(xd, buf, EDstate->nref[i], EDstate->old_sref[i], list);
1439 do_cpt_n_rvecs_err(xd, buf, EDstate->nref[i], EDstate->old_sref_p[i], list);
1442 /* Average structure SAV */
1443 sprintf(buf, "ED%d # of atoms in average structure", i+1);
1444 do_cpt_int_err(xd, buf, &EDstate->nav[i], list);
1445 sprintf(buf, "ED%d x_av", i+1);
1448 snew(EDstate->old_sav[i], EDstate->nav[i]);
1449 do_cpt_n_rvecs_err(xd, buf, EDstate->nav[i], EDstate->old_sav[i], list);
1453 do_cpt_n_rvecs_err(xd, buf, EDstate->nav[i], EDstate->old_sav_p[i], list);
1461 static int do_cpt_files(XDR *xd, gmx_bool bRead,
1462 gmx_file_position_t **p_outputfiles, int *nfiles,
1463 FILE *list, int file_version)
1467 gmx_off_t mask = 0xFFFFFFFFL;
1468 int offset_high, offset_low;
1470 gmx_file_position_t *outputfiles;
1472 if (do_cpt_int(xd, "number of output files", nfiles, list) != 0)
1479 snew(*p_outputfiles, *nfiles);
1482 outputfiles = *p_outputfiles;
1484 for (i = 0; i < *nfiles; i++)
1486 /* 64-bit XDR numbers are not portable, so it is stored as separate high/low fractions */
1489 do_cpt_string_err(xd, bRead, "output filename", &buf, list);
1490 std::strncpy(outputfiles[i].filename, buf, CPTSTRLEN-1);
1496 if (do_cpt_int(xd, "file_offset_high", &offset_high, list) != 0)
1500 if (do_cpt_int(xd, "file_offset_low", &offset_low, list) != 0)
1504 outputfiles[i].offset = (static_cast<gmx_off_t>(offset_high) << 32 ) | ( static_cast<gmx_off_t>(offset_low) & mask );
1508 buf = outputfiles[i].filename;
1509 do_cpt_string_err(xd, bRead, "output filename", &buf, list);
1511 offset = outputfiles[i].offset;
1519 offset_low = static_cast<int>(offset & mask);
1520 offset_high = static_cast<int>((offset >> 32) & mask);
1522 if (do_cpt_int(xd, "file_offset_high", &offset_high, list) != 0)
1526 if (do_cpt_int(xd, "file_offset_low", &offset_low, list) != 0)
1531 if (file_version >= 8)
1533 if (do_cpt_int(xd, "file_checksum_size", &(outputfiles[i].chksum_size),
1538 if (do_cpt_u_chars(xd, "file_checksum", 16, outputfiles[i].chksum, list) != 0)
1545 outputfiles[i].chksum_size = -1;
1552 void write_checkpoint(const char *fn, gmx_bool bNumberAndKeep,
1553 FILE *fplog, t_commrec *cr,
1554 ivec domdecCells, int nppnodes,
1555 int eIntegrator, int simulation_part,
1556 gmx_bool bExpanded, int elamstats,
1557 gmx_int64_t step, double t,
1558 t_state *state, energyhistory_t *enerhist)
1568 char *fntemp; /* the temporary checkpoint file name */
1569 char timebuf[STRLEN];
1571 char buf[1024], suffix[5+STEPSTRSIZE], sbuf[STEPSTRSIZE];
1572 gmx_file_position_t *outputfiles;
1575 int flags_eks, flags_enh, flags_dfh;
1578 if (DOMAINDECOMP(cr))
1580 npmenodes = cr->npmenodes;
1588 /* make the new temporary filename */
1589 snew(fntemp, std::strlen(fn)+5+STEPSTRSIZE);
1590 std::strcpy(fntemp, fn);
1591 fntemp[std::strlen(fn) - std::strlen(ftp2ext(fn2ftp(fn))) - 1] = '\0';
1592 sprintf(suffix, "_%s%s", "step", gmx_step_str(step, sbuf));
1593 std::strcat(fntemp, suffix);
1594 std::strcat(fntemp, fn+std::strlen(fn) - std::strlen(ftp2ext(fn2ftp(fn))) - 1);
1596 /* if we can't rename, we just overwrite the cpt file.
1597 * dangerous if interrupted.
1599 snew(fntemp, std::strlen(fn));
1600 std::strcpy(fntemp, fn);
1602 gmx_format_current_time(timebuf, STRLEN);
1606 fprintf(fplog, "Writing checkpoint, step %s at %s\n\n",
1607 gmx_step_str(step, buf), timebuf);
1610 /* Get offsets for open files */
1611 gmx_fio_get_output_file_positions(&outputfiles, &noutputfiles);
1613 fp = gmx_fio_open(fntemp, "w");
1615 if (state->ekinstate.bUpToDate)
1618 ((1<<eeksEKIN_N) | (1<<eeksEKINH) | (1<<eeksEKINF) |
1619 (1<<eeksEKINO) | (1<<eeksEKINSCALEF) | (1<<eeksEKINSCALEH) |
1620 (1<<eeksVSCALE) | (1<<eeksDEKINDL) | (1<<eeksMVCOS));
1628 if (enerhist->nsum > 0 || enerhist->nsum_sim > 0)
1630 flags_enh |= (1<<eenhENERGY_N) | (1<<eenhENERGY_NSTEPS) | (1<<eenhENERGY_NSTEPS_SIM);
1631 if (enerhist->nsum > 0)
1633 flags_enh |= ((1<<eenhENERGY_AVER) | (1<<eenhENERGY_SUM) |
1634 (1<<eenhENERGY_NSUM));
1636 if (enerhist->nsum_sim > 0)
1638 flags_enh |= ((1<<eenhENERGY_SUM_SIM) | (1<<eenhENERGY_NSUM_SIM));
1640 if (enerhist->deltaHForeignLambdas != nullptr)
1642 flags_enh |= ( (1<< eenhENERGY_DELTA_H_NN) |
1643 (1<< eenhENERGY_DELTA_H_LIST) |
1644 (1<< eenhENERGY_DELTA_H_STARTTIME) |
1645 (1<< eenhENERGY_DELTA_H_STARTLAMBDA) );
1651 flags_dfh = ((1<<edfhBEQUIL) | (1<<edfhNATLAMBDA) | (1<<edfhSUMWEIGHTS) | (1<<edfhSUMDG) |
1652 (1<<edfhTIJ) | (1<<edfhTIJEMP));
1655 flags_dfh |= ((1<<edfhWLDELTA) | (1<<edfhWLHISTO));
1657 if ((elamstats == elamstatsMINVAR) || (elamstats == elamstatsBARKER) || (elamstats == elamstatsMETROPOLIS))
1659 flags_dfh |= ((1<<edfhACCUMP) | (1<<edfhACCUMM) | (1<<edfhACCUMP2) | (1<<edfhACCUMM2)
1660 | (1<<edfhSUMMINVAR) | (1<<edfhSUMVAR));
1668 /* We can check many more things now (CPU, acceleration, etc), but
1669 * it is highly unlikely to have two separate builds with exactly
1670 * the same version, user, time, and build host!
1673 version = gmx_strdup(gmx_version());
1674 btime = gmx_strdup(BUILD_TIME);
1675 buser = gmx_strdup(BUILD_USER);
1676 bhost = gmx_strdup(BUILD_HOST);
1678 double_prec = GMX_DOUBLE;
1679 fprog = gmx_strdup(gmx::getProgramContext().fullBinaryPath());
1681 ftime = &(timebuf[0]);
1683 int nlambda = (state->dfhist ? state->dfhist->nlambda : 0);
1684 int nED = (state->edsamstate ? state->edsamstate->nED : 0);
1685 int eSwapCoords = (state->swapstate ? state->swapstate->eSwapCoords : eswapNO);
1687 do_cpt_header(gmx_fio_getxdr(fp), FALSE, &file_version,
1688 &version, &btime, &buser, &bhost, &double_prec, &fprog, &ftime,
1689 &eIntegrator, &simulation_part, &step, &t, &nppnodes,
1690 DOMAINDECOMP(cr) ? domdecCells : NULL, &npmenodes,
1691 &state->natoms, &state->ngtc, &state->nnhpres,
1692 &state->nhchainlength, &nlambda, &state->flags, &flags_eks, &flags_enh, &flags_dfh,
1702 if ((do_cpt_state(gmx_fio_getxdr(fp), state->flags, state, NULL) < 0) ||
1703 (do_cpt_ekinstate(gmx_fio_getxdr(fp), flags_eks, &state->ekinstate, NULL) < 0) ||
1704 (do_cpt_enerhist(gmx_fio_getxdr(fp), FALSE, flags_enh, enerhist, NULL) < 0) ||
1705 (do_cpt_df_hist(gmx_fio_getxdr(fp), flags_dfh, nlambda, &state->dfhist, NULL) < 0) ||
1706 (do_cpt_EDstate(gmx_fio_getxdr(fp), FALSE, nED, &state->edsamstate, NULL) < 0) ||
1707 (do_cpt_swapstate(gmx_fio_getxdr(fp), FALSE, eSwapCoords, &state->swapstate, NULL) < 0) ||
1708 (do_cpt_files(gmx_fio_getxdr(fp), FALSE, &outputfiles, &noutputfiles, NULL,
1711 gmx_file("Cannot read/write checkpoint; corrupt file, or maybe you are out of disk space?");
1714 do_cpt_footer(gmx_fio_getxdr(fp), file_version);
1716 /* we really, REALLY, want to make sure to physically write the checkpoint,
1717 and all the files it depends on, out to disk. Because we've
1718 opened the checkpoint with gmx_fio_open(), it's in our list
1720 ret = gmx_fio_all_output_fsync();
1726 "Cannot fsync '%s'; maybe you are out of disk space?",
1727 gmx_fio_getname(ret));
1729 if (getenv(GMX_IGNORE_FSYNC_FAILURE_ENV) == NULL)
1739 if (gmx_fio_close(fp) != 0)
1741 gmx_file("Cannot read/write checkpoint; corrupt file, or maybe you are out of disk space?");
1744 /* we don't move the checkpoint if the user specified they didn't want it,
1745 or if the fsyncs failed */
1747 if (!bNumberAndKeep && !ret)
1751 /* Rename the previous checkpoint file */
1752 std::strcpy(buf, fn);
1753 buf[std::strlen(fn) - std::strlen(ftp2ext(fn2ftp(fn))) - 1] = '\0';
1754 std::strcat(buf, "_prev");
1755 std::strcat(buf, fn+std::strlen(fn) - std::strlen(ftp2ext(fn2ftp(fn))) - 1);
1757 /* we copy here so that if something goes wrong between now and
1758 * the rename below, there's always a state.cpt.
1759 * If renames are atomic (such as in POSIX systems),
1760 * this copying should be unneccesary.
1762 gmx_file_copy(fn, buf, FALSE);
1763 /* We don't really care if this fails:
1764 * there's already a new checkpoint.
1767 gmx_file_rename(fn, buf);
1770 if (gmx_file_rename(fntemp, fn) != 0)
1772 gmx_file("Cannot rename checkpoint file; maybe you are out of disk space?");
1775 #endif /* GMX_NO_RENAME */
1781 /*code for alternate checkpointing scheme. moved from top of loop over
1783 fcRequestCheckPoint();
1784 if (fcCheckPointParallel( cr->nodeid, NULL, 0) == 0)
1786 gmx_fatal( 3, __FILE__, __LINE__, "Checkpoint error on step %d\n", step );
1788 #endif /* end GMX_FAHCORE block */
1791 static void print_flag_mismatch(FILE *fplog, int sflags, int fflags)
1795 fprintf(fplog, "\nState entry mismatch between the simulation and the checkpoint file\n");
1796 fprintf(fplog, "Entries which are not present in the checkpoint file will not be updated\n");
1797 fprintf(fplog, " %24s %11s %11s\n", "", "simulation", "checkpoint");
1798 for (i = 0; i < estNR; i++)
1800 if ((sflags & (1<<i)) || (fflags & (1<<i)))
1802 fprintf(fplog, " %24s %11s %11s\n",
1804 (sflags & (1<<i)) ? " present " : "not present",
1805 (fflags & (1<<i)) ? " present " : "not present");
1810 static void check_int(FILE *fplog, const char *type, int p, int f, gmx_bool *mm)
1812 FILE *fp = fplog ? fplog : stderr;
1816 fprintf(fp, " %s mismatch,\n", type);
1817 fprintf(fp, " current program: %d\n", p);
1818 fprintf(fp, " checkpoint file: %d\n", f);
1824 static void check_string(FILE *fplog, const char *type, const char *p,
1825 const char *f, gmx_bool *mm)
1827 FILE *fp = fplog ? fplog : stderr;
1829 if (std::strcmp(p, f) != 0)
1831 fprintf(fp, " %s mismatch,\n", type);
1832 fprintf(fp, " current program: %s\n", p);
1833 fprintf(fp, " checkpoint file: %s\n", f);
1839 static void check_match(FILE *fplog,
1841 char *btime, char *buser, char *bhost, int double_prec,
1843 const t_commrec *cr, int npp_f, int npme_f,
1844 ivec dd_nc, ivec dd_nc_f,
1845 gmx_bool reproducibilityRequested)
1847 /* Note that this check_string on the version will also print a message
1848 * when only the minor version differs. But we only print a warning
1849 * message further down with reproducibilityRequested=TRUE.
1851 gmx_bool versionDiffers = FALSE;
1852 check_string(fplog, "Version", gmx_version(), version, &versionDiffers);
1854 gmx_bool precisionDiffers = FALSE;
1855 check_int (fplog, "Double prec.", GMX_DOUBLE, double_prec, &precisionDiffers);
1856 if (precisionDiffers)
1858 const char msg_precision_difference[] =
1859 "You are continuing a simulation with a different precision. Not matching\n"
1860 "single/double precision will lead to precision or performance loss.\n";
1861 fprintf(stderr, "%s\n", msg_precision_difference);
1864 fprintf(fplog, "%s\n", msg_precision_difference);
1868 gmx_bool mm = (versionDiffers || precisionDiffers);
1870 if (reproducibilityRequested)
1872 check_string(fplog, "Build time", BUILD_TIME, btime, &mm);
1873 check_string(fplog, "Build user", BUILD_USER, buser, &mm);
1874 check_string(fplog, "Build host", BUILD_HOST, bhost, &mm);
1875 check_string(fplog, "Program name", gmx::getProgramContext().fullBinaryPath(), fprog, &mm);
1877 check_int (fplog, "#ranks", cr->nnodes, npp_f+npme_f, &mm);
1880 if (cr->nnodes > 1 && reproducibilityRequested)
1882 check_int (fplog, "#PME-ranks", cr->npmenodes, npme_f, &mm);
1884 int npp = cr->nnodes;
1885 if (cr->npmenodes >= 0)
1887 npp -= cr->npmenodes;
1891 check_int (fplog, "#DD-cells[x]", dd_nc[XX], dd_nc_f[XX], &mm);
1892 check_int (fplog, "#DD-cells[y]", dd_nc[YY], dd_nc_f[YY], &mm);
1893 check_int (fplog, "#DD-cells[z]", dd_nc[ZZ], dd_nc_f[ZZ], &mm);
1899 /* Gromacs should be able to continue from checkpoints between
1900 * different patch level versions, but we do not guarantee
1901 * compatibility between different major/minor versions - check this.
1905 sscanf(gmx_version(), "%5d", &gmx_major);
1906 int ret = sscanf(version, "%5d", &cpt_major);
1907 gmx_bool majorVersionDiffers = (ret < 1 || gmx_major != cpt_major);
1909 const char msg_major_version_difference[] =
1910 "The current GROMACS major version is not identical to the one that\n"
1911 "generated the checkpoint file. In principle GROMACS does not support\n"
1912 "continuation from checkpoints between different versions, so we advise\n"
1913 "against this. If you still want to try your luck we recommend that you use\n"
1914 "the -noappend flag to keep your output files from the two versions separate.\n"
1915 "This might also work around errors where the output fields in the energy\n"
1916 "file have changed between the different versions.\n";
1918 const char msg_mismatch_notice[] =
1919 "GROMACS patchlevel, binary or parallel settings differ from previous run.\n"
1920 "Continuation is exact, but not guaranteed to be binary identical.\n";
1922 const char msg_logdetails[] =
1923 "See the log file for details.\n";
1925 if (majorVersionDiffers)
1927 fprintf(stderr, "%s%s\n", msg_major_version_difference, fplog ? msg_logdetails : "");
1931 fprintf(fplog, "%s\n", msg_major_version_difference);
1934 else if (reproducibilityRequested)
1936 /* Major & minor versions match at least, but something is different. */
1937 fprintf(stderr, "%s%s\n", msg_mismatch_notice, fplog ? msg_logdetails : "");
1940 fprintf(fplog, "%s\n", msg_mismatch_notice);
1946 static void read_checkpoint(const char *fn, FILE **pfplog,
1947 const t_commrec *cr,
1948 ivec dd_nc, int *npme,
1949 int eIntegrator, int *init_fep_state, gmx_int64_t *step, double *t,
1950 t_state *state, gmx_bool *bReadEkin,
1951 energyhistory_t *enerhist,
1952 int *simulation_part,
1953 gmx_bool bAppendOutputFiles, gmx_bool bForceAppend,
1954 gmx_bool reproducibilityRequested)
1959 char *version, *btime, *buser, *bhost, *fprog, *ftime;
1961 char buf[STEPSTRSIZE];
1962 int eIntegrator_f, nppnodes_f, npmenodes_f;
1964 int natoms, ngtc, nnhpres, nhchainlength, nlambda, fflags, flags_eks, flags_enh, flags_dfh;
1965 int nED, eSwapCoords;
1968 gmx_file_position_t *outputfiles;
1970 t_fileio *chksum_file;
1971 FILE * fplog = *pfplog;
1972 unsigned char digest[16];
1973 #if !defined __native_client__ && !GMX_NATIVE_WINDOWS
1974 struct flock fl; /* don't initialize here: the struct order is OS
1978 const char *int_warn =
1979 "WARNING: The checkpoint file was generated with integrator %s,\n"
1980 " while the simulation uses integrator %s\n\n";
1982 #if !defined __native_client__ && !GMX_NATIVE_WINDOWS
1983 fl.l_type = F_WRLCK;
1984 fl.l_whence = SEEK_SET;
1990 fp = gmx_fio_open(fn, "r");
1991 do_cpt_header(gmx_fio_getxdr(fp), TRUE, &file_version,
1992 &version, &btime, &buser, &bhost, &double_prec, &fprog, &ftime,
1993 &eIntegrator_f, simulation_part, step, t,
1994 &nppnodes_f, dd_nc_f, &npmenodes_f,
1995 &natoms, &ngtc, &nnhpres, &nhchainlength, &nlambda,
1996 &fflags, &flags_eks, &flags_enh, &flags_dfh,
1997 &nED, &eSwapCoords, NULL);
1999 if (bAppendOutputFiles &&
2000 file_version >= 13 && double_prec != GMX_DOUBLE)
2002 gmx_fatal(FARGS, "Output file appending requested, but the code and checkpoint file precision (single/double) don't match");
2005 if (cr == NULL || MASTER(cr))
2007 fprintf(stderr, "\nReading checkpoint file %s generated: %s\n\n",
2011 /* This will not be written if we do appending, since fplog is still NULL then */
2014 fprintf(fplog, "\n");
2015 fprintf(fplog, "Reading checkpoint file %s\n", fn);
2016 fprintf(fplog, " file generated by: %s\n", fprog);
2017 fprintf(fplog, " file generated at: %s\n", ftime);
2018 fprintf(fplog, " GROMACS build time: %s\n", btime);
2019 fprintf(fplog, " GROMACS build user: %s\n", buser);
2020 fprintf(fplog, " GROMACS build host: %s\n", bhost);
2021 fprintf(fplog, " GROMACS double prec.: %d\n", double_prec);
2022 fprintf(fplog, " simulation part #: %d\n", *simulation_part);
2023 fprintf(fplog, " step: %s\n", gmx_step_str(*step, buf));
2024 fprintf(fplog, " time: %f\n", *t);
2025 fprintf(fplog, "\n");
2028 if (natoms != state->natoms)
2030 gmx_fatal(FARGS, "Checkpoint file is for a system of %d atoms, while the current system consists of %d atoms", natoms, state->natoms);
2032 if (ngtc != state->ngtc)
2034 gmx_fatal(FARGS, "Checkpoint file is for a system of %d T-coupling groups, while the current system consists of %d T-coupling groups", ngtc, state->ngtc);
2036 if (nnhpres != state->nnhpres)
2038 gmx_fatal(FARGS, "Checkpoint file is for a system of %d NH-pressure-coupling variables, while the current system consists of %d NH-pressure-coupling variables", nnhpres, state->nnhpres);
2041 int nlambdaHistory = (state->dfhist ? state->dfhist->nlambda : 0);
2042 if (nlambda != nlambdaHistory)
2044 gmx_fatal(FARGS, "Checkpoint file is for a system with %d lambda states, while the current system consists of %d lambda states", nlambda, nlambdaHistory);
2047 init_gtc_state(state, state->ngtc, state->nnhpres, nhchainlength); /* need to keep this here to keep the tpr format working */
2048 /* write over whatever was read; we use the number of Nose-Hoover chains from the checkpoint */
2050 if (eIntegrator_f != eIntegrator)
2054 fprintf(stderr, int_warn, EI(eIntegrator_f), EI(eIntegrator));
2056 if (bAppendOutputFiles)
2059 "Output file appending requested, but input/checkpoint integrators do not match.\n"
2060 "Stopping the run to prevent you from ruining all your data...\n"
2061 "If you _really_ know what you are doing, try with the -noappend option.\n");
2065 fprintf(fplog, int_warn, EI(eIntegrator_f), EI(eIntegrator));
2073 else if (cr->nnodes == nppnodes_f + npmenodes_f)
2077 *npme = npmenodes_f;
2079 int nppnodes = cr->nnodes - *npme;
2080 if (nppnodes == nppnodes_f)
2082 for (d = 0; d < DIM; d++)
2086 dd_nc[d] = dd_nc_f[d];
2092 if (fflags != state->flags)
2097 if (bAppendOutputFiles)
2100 "Output file appending requested, but input and checkpoint states are not identical.\n"
2101 "Stopping the run to prevent you from ruining all your data...\n"
2102 "You can try with the -noappend option, and get more info in the log file.\n");
2105 if (getenv("GMX_ALLOW_CPT_MISMATCH") == NULL)
2107 gmx_fatal(FARGS, "You seem to have switched ensemble, integrator, T and/or P-coupling algorithm between the cpt and tpr file. The recommended way of doing this is passing the cpt file to grompp (with option -t) instead of to mdrun. If you know what you are doing, you can override this error by setting the env.var. GMX_ALLOW_CPT_MISMATCH");
2112 "WARNING: The checkpoint state entries do not match the simulation,\n"
2113 " see the log file for details\n\n");
2119 print_flag_mismatch(fplog, state->flags, fflags);
2126 check_match(fplog, version, btime, buser, bhost, double_prec, fprog,
2127 cr, nppnodes_f, npmenodes_f, dd_nc, dd_nc_f,
2128 reproducibilityRequested);
2131 ret = do_cpt_state(gmx_fio_getxdr(fp), fflags, state, NULL);
2132 *init_fep_state = state->fep_state; /* there should be a better way to do this than setting it here.
2133 Investigate for 5.0. */
2138 ret = do_cpt_ekinstate(gmx_fio_getxdr(fp), flags_eks, &state->ekinstate, NULL);
2143 *bReadEkin = ((flags_eks & (1<<eeksEKINH)) || (flags_eks & (1<<eeksEKINF)) || (flags_eks & (1<<eeksEKINO)) ||
2144 ((flags_eks & (1<<eeksEKINSCALEF)) | (flags_eks & (1<<eeksEKINSCALEH)) | (flags_eks & (1<<eeksVSCALE))));
2146 ret = do_cpt_enerhist(gmx_fio_getxdr(fp), TRUE,
2147 flags_enh, enerhist, NULL);
2153 if (file_version < 6)
2155 const char *warn = "Reading checkpoint file in old format, assuming that the run that generated this file started at step 0, if this is not the case the averages stored in the energy file will be incorrect.";
2157 fprintf(stderr, "\nWARNING: %s\n\n", warn);
2160 fprintf(fplog, "\nWARNING: %s\n\n", warn);
2162 enerhist->nsum = *step;
2163 enerhist->nsum_sim = *step;
2166 ret = do_cpt_df_hist(gmx_fio_getxdr(fp), flags_dfh, nlambda, &state->dfhist, NULL);
2172 ret = do_cpt_EDstate(gmx_fio_getxdr(fp), TRUE, nED, &state->edsamstate, NULL);
2178 ret = do_cpt_swapstate(gmx_fio_getxdr(fp), TRUE, eSwapCoords, &state->swapstate, NULL);
2184 ret = do_cpt_files(gmx_fio_getxdr(fp), TRUE, &outputfiles, &nfiles, NULL, file_version);
2190 ret = do_cpt_footer(gmx_fio_getxdr(fp), file_version);
2195 if (gmx_fio_close(fp) != 0)
2197 gmx_file("Cannot read/write checkpoint; corrupt file, or maybe you are out of disk space?");
2206 /* If the user wants to append to output files,
2207 * we use the file pointer positions of the output files stored
2208 * in the checkpoint file and truncate the files such that any frames
2209 * written after the checkpoint time are removed.
2210 * All files are md5sum checked such that we can be sure that
2211 * we do not truncate other (maybe imprortant) files.
2213 if (bAppendOutputFiles)
2215 if (fn2ftp(outputfiles[0].filename) != efLOG)
2217 /* make sure first file is log file so that it is OK to use it for
2220 gmx_fatal(FARGS, "The first output file should always be the log "
2221 "file but instead is: %s. Cannot do appending because of this condition.", outputfiles[0].filename);
2223 for (i = 0; i < nfiles; i++)
2225 if (outputfiles[i].offset < 0)
2227 gmx_fatal(FARGS, "The original run wrote a file called '%s' which "
2228 "is larger than 2 GB, but mdrun did not support large file"
2229 " offsets. Can not append. Run mdrun with -noappend",
2230 outputfiles[i].filename);
2233 chksum_file = gmx_fio_open(outputfiles[i].filename, "a");
2236 chksum_file = gmx_fio_open(outputfiles[i].filename, "r+");
2241 /* Note that there are systems where the lock operation
2242 * will succeed, but a second process can also lock the file.
2243 * We should probably try to detect this.
2245 #if defined __native_client__
2249 #elif GMX_NATIVE_WINDOWS
2250 if (_locking(fileno(gmx_fio_getfp(chksum_file)), _LK_NBLCK, LONG_MAX) == -1)
2252 if (fcntl(fileno(gmx_fio_getfp(chksum_file)), F_SETLK, &fl) == -1)
2255 if (errno == ENOSYS)
2259 gmx_fatal(FARGS, "File locking is not supported on this system. Use -noappend or specify -append explicitly to append anyhow.");
2263 fprintf(stderr, "\nNOTE: File locking is not supported on this system, will not lock %s\n\n", outputfiles[i].filename);
2266 fprintf(fplog, "\nNOTE: File locking not supported on this system, will not lock %s\n\n", outputfiles[i].filename);
2270 else if (errno == EACCES || errno == EAGAIN)
2272 gmx_fatal(FARGS, "Failed to lock: %s. Already running "
2273 "simulation?", outputfiles[i].filename);
2277 gmx_fatal(FARGS, "Failed to lock: %s. %s.",
2278 outputfiles[i].filename, std::strerror(errno));
2283 /* compute md5 chksum */
2284 if (outputfiles[i].chksum_size != -1)
2286 if (gmx_fio_get_file_md5(chksum_file, outputfiles[i].offset,
2287 digest) != outputfiles[i].chksum_size) /*at the end of the call the file position is at the end of the file*/
2289 gmx_fatal(FARGS, "Can't read %d bytes of '%s' to compute checksum. The file has been replaced or its contents have been modified. Cannot do appending because of this condition.",
2290 outputfiles[i].chksum_size,
2291 outputfiles[i].filename);
2294 if (i == 0) /*log file needs to be seeked in case we need to truncate (other files are truncated below)*/
2296 if (gmx_fio_seek(chksum_file, outputfiles[i].offset))
2298 gmx_fatal(FARGS, "Seek error! Failed to truncate log-file: %s.", std::strerror(errno));
2303 if (i == 0) /*open log file here - so that lock is never lifted
2304 after chksum is calculated */
2306 *pfplog = gmx_fio_getfp(chksum_file);
2310 gmx_fio_close(chksum_file);
2313 /* compare md5 chksum */
2314 if (outputfiles[i].chksum_size != -1 &&
2315 memcmp(digest, outputfiles[i].chksum, 16) != 0)
2319 fprintf(debug, "chksum for %s: ", outputfiles[i].filename);
2320 for (j = 0; j < 16; j++)
2322 fprintf(debug, "%02x", digest[j]);
2324 fprintf(debug, "\n");
2326 gmx_fatal(FARGS, "Checksum wrong for '%s'. The file has been replaced or its contents have been modified. Cannot do appending because of this condition.",
2327 outputfiles[i].filename);
2332 if (i != 0) /*log file is already seeked to correct position */
2334 #if !GMX_NATIVE_WINDOWS || !defined(GMX_FAHCORE)
2335 /* For FAHCORE, we do this elsewhere*/
2336 rc = gmx_truncate(outputfiles[i].filename, outputfiles[i].offset);
2339 gmx_fatal(FARGS, "Truncation of file %s failed. Cannot do appending because of this failure.", outputfiles[i].filename);
2350 void load_checkpoint(const char *fn, FILE **fplog,
2351 const t_commrec *cr, ivec dd_nc, int *npme,
2352 t_inputrec *ir, t_state *state,
2353 gmx_bool *bReadEkin,
2354 energyhistory_t *enerhist,
2355 gmx_bool bAppend, gmx_bool bForceAppend,
2356 gmx_bool reproducibilityRequested)
2363 /* Read the state from the checkpoint file */
2364 read_checkpoint(fn, fplog,
2366 ir->eI, &(ir->fepvals->init_fep_state), &step, &t,
2367 state, bReadEkin, enerhist,
2368 &ir->simulation_part, bAppend, bForceAppend,
2369 reproducibilityRequested);
2373 gmx_bcast(sizeof(*npme), npme, cr);
2374 gmx_bcast(DIM*sizeof(dd_nc[0]), dd_nc, cr);
2375 gmx_bcast(sizeof(step), &step, cr);
2376 gmx_bcast(sizeof(*bReadEkin), bReadEkin, cr);
2378 ir->bContinuation = TRUE;
2379 if (ir->nsteps >= 0)
2381 ir->nsteps += ir->init_step - step;
2383 ir->init_step = step;
2384 ir->simulation_part += 1;
2387 void read_checkpoint_part_and_step(const char *filename,
2388 int *simulation_part,
2392 char *version, *btime, *buser, *bhost, *fprog, *ftime;
2398 int flags_eks, flags_enh, flags_dfh;
2401 int nED, eSwapCoords;
2404 if (filename == NULL ||
2405 !gmx_fexist(filename) ||
2406 (!(fp = gmx_fio_open(filename, "r"))))
2408 *simulation_part = 0;
2413 /* Not calling initializing state before use is nasty, but all we
2414 do is read into its member variables and throw the struct away
2415 again immediately. */
2417 do_cpt_header(gmx_fio_getxdr(fp), TRUE, &file_version,
2418 &version, &btime, &buser, &bhost, &double_prec, &fprog, &ftime,
2419 &eIntegrator, simulation_part, step, &t, &nppnodes, dd_nc, &npme,
2420 &state.natoms, &state.ngtc, &state.nnhpres, &state.nhchainlength,
2421 &nlambda, &state.flags, &flags_eks, &flags_enh, &flags_dfh,
2422 &nED, &eSwapCoords, NULL);
2427 static void read_checkpoint_data(t_fileio *fp, int *simulation_part,
2428 gmx_int64_t *step, double *t, t_state *state,
2429 int *nfiles, gmx_file_position_t **outputfiles)
2432 char *version, *btime, *buser, *bhost, *fprog, *ftime;
2438 int flags_eks, flags_enh, flags_dfh;
2439 int nED, eSwapCoords;
2441 gmx_file_position_t *files_loc = NULL;
2444 do_cpt_header(gmx_fio_getxdr(fp), TRUE, &file_version,
2445 &version, &btime, &buser, &bhost, &double_prec, &fprog, &ftime,
2446 &eIntegrator, simulation_part, step, t, &nppnodes, dd_nc, &npme,
2447 &state->natoms, &state->ngtc, &state->nnhpres, &state->nhchainlength,
2448 &nlambda, &state->flags, &flags_eks, &flags_enh, &flags_dfh,
2449 &nED, &eSwapCoords, NULL);
2451 do_cpt_state(gmx_fio_getxdr(fp), state->flags, state, NULL);
2456 ret = do_cpt_ekinstate(gmx_fio_getxdr(fp), flags_eks, &state->ekinstate, NULL);
2462 energyhistory_t enerhist;
2463 ret = do_cpt_enerhist(gmx_fio_getxdr(fp), TRUE,
2464 flags_enh, &enerhist, NULL);
2469 ret = do_cpt_df_hist(gmx_fio_getxdr(fp), flags_dfh, nlambda, &state->dfhist, NULL);
2475 ret = do_cpt_EDstate(gmx_fio_getxdr(fp), TRUE, nED, &state->edsamstate, NULL);
2481 ret = do_cpt_swapstate(gmx_fio_getxdr(fp), TRUE, eSwapCoords, &state->swapstate, NULL);
2487 ret = do_cpt_files(gmx_fio_getxdr(fp), TRUE,
2490 NULL, file_version);
2491 if (outputfiles != nullptr)
2493 *outputfiles = files_loc;
2499 if (nfiles != nullptr)
2501 *nfiles = nfiles_loc;
2509 ret = do_cpt_footer(gmx_fio_getxdr(fp), file_version);
2523 read_checkpoint_state(const char *fn, int *simulation_part,
2524 gmx_int64_t *step, double *t, t_state *state)
2528 fp = gmx_fio_open(fn, "r");
2529 read_checkpoint_data(fp, simulation_part, step, t, state, NULL, NULL);
2530 if (gmx_fio_close(fp) != 0)
2532 gmx_file("Cannot read/write checkpoint; corrupt file, or maybe you are out of disk space?");
2536 void read_checkpoint_trxframe(t_fileio *fp, t_trxframe *fr)
2538 /* This next line is nasty because the sub-structures of t_state
2539 * cannot be assumed to be zeroed (or even initialized in ways the
2540 * rest of the code might assume). Using snew would be better, but
2541 * this will all go away for 5.0. */
2543 int simulation_part;
2547 init_state(&state, 0, 0, 0, 0, 0);
2549 read_checkpoint_data(fp, &simulation_part, &step, &t, &state, NULL, NULL);
2551 fr->natoms = state.natoms;
2554 fr->step = gmx_int64_to_int(step,
2555 "conversion of checkpoint to trajectory");
2559 fr->lambda = state.lambda[efptFEP];
2560 fr->fep_state = state.fep_state;
2562 fr->bX = (state.flags & (1<<estX));
2565 fr->x = getRvecArrayFromPaddedRVecVector(&state.x, state.natoms);
2567 fr->bV = (state.flags & (1<<estV));
2570 fr->v = getRvecArrayFromPaddedRVecVector(&state.v, state.natoms);
2573 fr->bBox = (state.flags & (1<<estBOX));
2576 copy_mat(state.box, fr->box);
2580 void list_checkpoint(const char *fn, FILE *out)
2584 char *version, *btime, *buser, *bhost, *fprog, *ftime;
2586 int eIntegrator, simulation_part, nppnodes, npme;
2591 int flags_eks, flags_enh, flags_dfh;
2592 int nED, eSwapCoords;
2594 gmx_file_position_t *outputfiles;
2598 init_state(&state, 0, 0, 0, 0, 0);
2600 fp = gmx_fio_open(fn, "r");
2601 do_cpt_header(gmx_fio_getxdr(fp), TRUE, &file_version,
2602 &version, &btime, &buser, &bhost, &double_prec, &fprog, &ftime,
2603 &eIntegrator, &simulation_part, &step, &t, &nppnodes, dd_nc, &npme,
2604 &state.natoms, &state.ngtc, &state.nnhpres, &state.nhchainlength,
2605 &nlambda, &state.flags,
2606 &flags_eks, &flags_enh, &flags_dfh, &nED, &eSwapCoords,
2608 ret = do_cpt_state(gmx_fio_getxdr(fp), state.flags, &state, out);
2613 ret = do_cpt_ekinstate(gmx_fio_getxdr(fp), flags_eks, &state.ekinstate, out);
2619 energyhistory_t enerhist;
2620 ret = do_cpt_enerhist(gmx_fio_getxdr(fp), TRUE,
2621 flags_enh, &enerhist, out);
2625 ret = do_cpt_df_hist(gmx_fio_getxdr(fp),
2626 flags_dfh, nlambda, &state.dfhist, out);
2631 ret = do_cpt_EDstate(gmx_fio_getxdr(fp), TRUE, nED, &state.edsamstate, out);
2636 ret = do_cpt_swapstate(gmx_fio_getxdr(fp), TRUE, eSwapCoords, &state.swapstate, out);
2641 do_cpt_files(gmx_fio_getxdr(fp), TRUE, &outputfiles, &nfiles, out, file_version);
2646 ret = do_cpt_footer(gmx_fio_getxdr(fp), file_version);
2653 if (gmx_fio_close(fp) != 0)
2655 gmx_file("Cannot read/write checkpoint; corrupt file, or maybe you are out of disk space?");
2659 /* This routine cannot print tons of data, since it is called before the log file is opened. */
2661 read_checkpoint_simulation_part_and_filenames(t_fileio *fp,
2662 int *simulation_part,
2664 gmx_file_position_t **outputfiles)
2666 gmx_int64_t step = 0;
2670 init_state(&state, 0, 0, 0, 0, 0);
2672 read_checkpoint_data(fp, simulation_part, &step, &t, &state,
2673 nfiles, outputfiles);
2674 if (gmx_fio_close(fp) != 0)
2676 gmx_file("Cannot read/write checkpoint; corrupt file, or maybe you are out of disk space?");