2 * This file is part of the GROMACS molecular simulation package.
4 * Copyright (c) 2008,2009,2010,2011,2012,2013,2014,2015,2016,2017,2018,2019, 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>
57 #include "buildinfo.h"
58 #include "gromacs/fileio/filetypes.h"
59 #include "gromacs/fileio/gmxfio.h"
60 #include "gromacs/fileio/gmxfio_xdr.h"
61 #include "gromacs/fileio/xdr_datatype.h"
62 #include "gromacs/fileio/xdrf.h"
63 #include "gromacs/gmxlib/network.h"
64 #include "gromacs/math/vec.h"
65 #include "gromacs/math/vecdump.h"
66 #include "gromacs/math/vectypes.h"
67 #include "gromacs/mdtypes/awh_correlation_history.h"
68 #include "gromacs/mdtypes/awh_history.h"
69 #include "gromacs/mdtypes/commrec.h"
70 #include "gromacs/mdtypes/df_history.h"
71 #include "gromacs/mdtypes/edsamhistory.h"
72 #include "gromacs/mdtypes/energyhistory.h"
73 #include "gromacs/mdtypes/inputrec.h"
74 #include "gromacs/mdtypes/md_enums.h"
75 #include "gromacs/mdtypes/observableshistory.h"
76 #include "gromacs/mdtypes/pullhistory.h"
77 #include "gromacs/mdtypes/state.h"
78 #include "gromacs/mdtypes/swaphistory.h"
79 #include "gromacs/trajectory/trajectoryframe.h"
80 #include "gromacs/utility/arrayref.h"
81 #include "gromacs/utility/baseversion.h"
82 #include "gromacs/utility/cstringutil.h"
83 #include "gromacs/utility/fatalerror.h"
84 #include "gromacs/utility/futil.h"
85 #include "gromacs/utility/gmxassert.h"
86 #include "gromacs/utility/int64_to_int.h"
87 #include "gromacs/utility/programcontext.h"
88 #include "gromacs/utility/smalloc.h"
89 #include "gromacs/utility/sysinfo.h"
90 #include "gromacs/utility/txtdump.h"
96 #define CPT_MAGIC1 171817
97 #define CPT_MAGIC2 171819
98 #define CPTSTRLEN 1024
100 /*! \brief Enum of values that describe the contents of a cpt file
101 * whose format matches a version number
103 * The enum helps the code be more self-documenting and ensure merges
104 * do not silently resolve when two patches make the same bump. When
105 * adding new functionality, add a new element just above cptv_Count
106 * in this enumeration, and write code below that does the right thing
107 * according to the value of file_version.
110 cptv_Unknown = 17, /**< Version before numbering scheme */
111 cptv_RemoveBuildMachineInformation, /**< remove functionality that makes mdrun builds non-reproducible */
112 cptv_ComPrevStepAsPullGroupReference, /**< Allow using COM of previous step as pull group PBC reference */
113 cptv_PullAverage, /**< Added possibility to output average pull force and position */
114 cptv_Count /**< the total number of cptv versions */
117 /*! \brief Version number of the file format written to checkpoint
118 * files by this version of the code.
120 * cpt_version should normally only be changed, via adding a new field
121 * to cptv enumeration, when the header or footer format changes.
123 * The state data format itself is backward and forward compatible.
124 * But old code can not read a new entry that is present in the file
125 * (but can read a new format when new entries are not present).
127 * The cpt_version increases whenever the file format in the main
128 * development branch changes, due to an extension of the cptv enum above.
129 * Backward compatibility for reading old run input files is maintained
130 * by checking this version number against that of the file and then using
131 * the correct code path. */
132 static const int cpt_version = cptv_Count - 1;
135 const char *est_names[estNR] =
138 "box", "box-rel", "box-v", "pres_prev",
139 "nosehoover-xi", "thermostat-integral",
140 "x", "v", "sdx-unsupported", "CGp", "LD-rng-unsupported", "LD-rng-i-unsupported",
141 "disre_initf", "disre_rm3tav",
142 "orire_initf", "orire_Dtav",
143 "svir_prev", "nosehoover-vxi", "v_eta", "vol0", "nhpres_xi", "nhpres_vxi", "fvir_prev", "fep_state", "MC-rng-unsupported", "MC-rng-i-unsupported",
148 eeksEKIN_N, eeksEKINH, eeksDEKINDL, eeksMVCOS, eeksEKINF, eeksEKINO, eeksEKINSCALEF, eeksEKINSCALEH, eeksVSCALE, eeksEKINTOTAL, eeksNR
151 static const char *eeks_names[eeksNR] =
153 "Ekin_n", "Ekinh", "dEkindlambda", "mv_cos",
154 "Ekinf", "Ekinh_old", "EkinScaleF_NHC", "EkinScaleH_NHC", "Vscale_NHC", "Ekin_Total"
158 eenhENERGY_N, eenhENERGY_AVER, eenhENERGY_SUM, eenhENERGY_NSUM,
159 eenhENERGY_SUM_SIM, eenhENERGY_NSUM_SIM,
160 eenhENERGY_NSTEPS, eenhENERGY_NSTEPS_SIM,
161 eenhENERGY_DELTA_H_NN,
162 eenhENERGY_DELTA_H_LIST,
163 eenhENERGY_DELTA_H_STARTTIME,
164 eenhENERGY_DELTA_H_STARTLAMBDA,
169 epullhPULL_NUMCOORDINATES, epullhPULL_NUMGROUPS, epullhPULL_NUMVALUESINXSUM,
170 epullhPULL_NUMVALUESINFSUM, epullhNR
174 epullcoordh_VALUE_REF_SUM, epullcoordh_VALUE_SUM, epullcoordh_DR01_SUM,
175 epullcoordh_DR23_SUM, epullcoordh_DR45_SUM, epullcoordh_FSCAL_SUM,
176 epullcoordh_DYNAX_SUM, epullcoordh_NR
180 epullgrouph_X_SUM, epullgrouph_NR
183 static const char *eenh_names[eenhNR] =
185 "energy_n", "energy_aver", "energy_sum", "energy_nsum",
186 "energy_sum_sim", "energy_nsum_sim",
187 "energy_nsteps", "energy_nsteps_sim",
189 "energy_delta_h_list",
190 "energy_delta_h_start_time",
191 "energy_delta_h_start_lambda"
194 static const char *ePullhNames[epullhNR] =
196 "pullhistory_numcoordinates", "pullhistory_numgroups", "pullhistory_numvaluesinxsum",
197 "pullhistory_numvaluesinfsum"
200 /* free energy history variables -- need to be preserved over checkpoint */
202 edfhBEQUIL, edfhNATLAMBDA, edfhWLHISTO, edfhWLDELTA, edfhSUMWEIGHTS, edfhSUMDG, edfhSUMMINVAR, edfhSUMVAR,
203 edfhACCUMP, edfhACCUMM, edfhACCUMP2, edfhACCUMM2, edfhTIJ, edfhTIJEMP, edfhNR
205 /* free energy history variable names */
206 static const char *edfh_names[edfhNR] =
208 "bEquilibrated", "N_at_state", "Wang-Landau Histogram", "Wang-Landau Delta", "Weights", "Free Energies", "minvar", "variance",
209 "accumulated_plus", "accumulated_minus", "accumulated_plus_2", "accumulated_minus_2", "Tij", "Tij_empirical"
212 /* AWH biasing history variables */
215 eawhhEQUILIBRATEHISTOGRAM,
218 eawhhCOORDPOINT, eawhhUMBRELLAGRIDPOINT,
220 eawhhLOGSCALEDSAMPLEWEIGHT,
222 eawhhFORCECORRELATIONGRID,
226 static const char *eawhh_names[eawhhNR] =
229 "awh_equilibrateHistogram",
232 "awh_coordpoint", "awh_umbrellaGridpoint",
234 "awh_logScaledSampleWeight",
236 "awh_forceCorrelationGrid"
244 static const char *epull_prev_step_com_names[epullsNR] =
246 "Pull groups prev step COM"
250 //! Higher level vector element type, only used for formatting checkpoint dumps
251 enum class CptElementType
253 integer, //!< integer
254 real, //!< float or double, not linked to precision of type real
255 real3, //!< float[3] or double[3], not linked to precision of type real
256 matrix3x3 //!< float[3][3] or double[3][3], not linked to precision of type real
259 //! \brief Parts of the checkpoint state, only used for reporting
262 microState, //!< The microstate of the simulated system
263 kineticEnergy, //!< Kinetic energy, needed for T/P-coupling state
264 energyHistory, //!< Energy observable statistics
265 freeEnergyHistory, //!< Free-energy state and observable statistics
266 accWeightHistogram, //!< Accelerated weight histogram method state
267 pullState, //!< COM of previous step.
268 pullHistory //!< Pull history statistics (sums since last written output)
271 //! \brief Return the name of a checkpoint entry based on part and part entry
272 static const char *entryName(StatePart part, int ecpt)
276 case StatePart::microState: return est_names [ecpt];
277 case StatePart::kineticEnergy: return eeks_names[ecpt];
278 case StatePart::energyHistory: return eenh_names[ecpt];
279 case StatePart::freeEnergyHistory: return edfh_names[ecpt];
280 case StatePart::accWeightHistogram: return eawhh_names[ecpt];
281 case StatePart::pullState: return epull_prev_step_com_names[ecpt];
282 case StatePart::pullHistory: return ePullhNames[ecpt];
288 static void cp_warning(FILE *fp)
290 fprintf(fp, "\nWARNING: Checkpoint file is corrupted or truncated\n\n");
293 [[ noreturn ]] static void cp_error()
295 gmx_fatal(FARGS, "Checkpoint file corrupted/truncated, or maybe you are out of disk space?");
298 static void do_cpt_string_err(XDR *xd, const char *desc, gmx::ArrayRef<char> s, FILE *list)
300 char *data = s.data();
301 if (xdr_string(xd, &data, s.size()) == 0)
307 fprintf(list, "%s = %s\n", desc, data);
311 static int do_cpt_int(XDR *xd, const char *desc, int *i, FILE *list)
313 if (xdr_int(xd, i) == 0)
319 fprintf(list, "%s = %d\n", desc, *i);
324 static int do_cpt_u_chars(XDR *xd, const char *desc, int n, unsigned char *i, FILE *list)
328 fprintf(list, "%s = ", desc);
331 for (int j = 0; j < n && res; j++)
333 res &= xdr_u_char(xd, &i[j]);
336 fprintf(list, "%02x", i[j]);
351 static void do_cpt_int_err(XDR *xd, const char *desc, int *i, FILE *list)
353 if (do_cpt_int(xd, desc, i, list) < 0)
359 static void do_cpt_bool_err(XDR *xd, const char *desc, bool *b, FILE *list)
361 int i = static_cast<int>(*b);
363 if (do_cpt_int(xd, desc, &i, list) < 0)
371 static void do_cpt_step_err(XDR *xd, const char *desc, int64_t *i, FILE *list)
373 char buf[STEPSTRSIZE];
375 if (xdr_int64(xd, i) == 0)
381 fprintf(list, "%s = %s\n", desc, gmx_step_str(*i, buf));
385 static void do_cpt_double_err(XDR *xd, const char *desc, double *f, FILE *list)
387 if (xdr_double(xd, f) == 0)
393 fprintf(list, "%s = %f\n", desc, *f);
397 static void do_cpt_real_err(XDR *xd, real *f)
400 bool_t res = xdr_double(xd, f);
402 bool_t res = xdr_float(xd, f);
410 static void do_cpt_n_rvecs_err(XDR *xd, const char *desc, int n, rvec f[], FILE *list)
412 for (int i = 0; i < n; i++)
414 for (int j = 0; j < DIM; j++)
416 do_cpt_real_err(xd, &f[i][j]);
422 pr_rvecs(list, 0, desc, f, n);
426 template <typename T>
434 static const int value = xdr_datatype_int;
438 struct xdr_type<float>
440 static const int value = xdr_datatype_float;
444 struct xdr_type<double>
446 static const int value = xdr_datatype_double;
449 //! \brief Returns size in byte of an xdr_datatype
450 static inline unsigned int sizeOfXdrType(int xdrType)
454 case xdr_datatype_int:
456 case xdr_datatype_float:
457 return sizeof(float);
458 case xdr_datatype_double:
459 return sizeof(double);
460 default: GMX_RELEASE_ASSERT(false, "XDR data type not implemented");
466 //! \brief Returns the XDR process function for i/o of an XDR type
467 static inline xdrproc_t xdrProc(int xdrType)
471 case xdr_datatype_int:
472 return reinterpret_cast<xdrproc_t>(xdr_int);
473 case xdr_datatype_float:
474 return reinterpret_cast<xdrproc_t>(xdr_float);
475 case xdr_datatype_double:
476 return reinterpret_cast<xdrproc_t>(xdr_double);
477 default: GMX_RELEASE_ASSERT(false, "XDR data type not implemented");
483 /*! \brief Lists or only reads an xdr vector from checkpoint file
485 * When list!=NULL reads and lists the \p nf vector elements of type \p xdrType.
486 * The header for the print is set by \p part and \p ecpt.
487 * The formatting of the printing is set by \p cptElementType.
488 * When list==NULL only reads the elements.
490 static bool_t listXdrVector(XDR *xd, StatePart part, int ecpt, int nf, int xdrType,
491 FILE *list, CptElementType cptElementType)
495 const unsigned int elemSize = sizeOfXdrType(xdrType);
496 std::vector<char> data(nf*elemSize);
497 res = xdr_vector(xd, data.data(), nf, elemSize, xdrProc(xdrType));
503 case xdr_datatype_int:
504 pr_ivec(list, 0, entryName(part, ecpt), reinterpret_cast<const int *>(data.data()), nf, TRUE);
506 case xdr_datatype_float:
508 if (cptElementType == CptElementType::real3)
510 pr_rvecs(list, 0, entryName(part, ecpt), reinterpret_cast<const rvec *>(data.data()), nf/3);
515 /* Note: With double precision code dumping a single precision rvec will produce float iso rvec print, but that's a minor annoyance */
516 pr_fvec(list, 0, entryName(part, ecpt), reinterpret_cast<const float *>(data.data()), nf, TRUE);
519 case xdr_datatype_double:
521 if (cptElementType == CptElementType::real3)
523 pr_rvecs(list, 0, entryName(part, ecpt), reinterpret_cast<const rvec *>(data.data()), nf/3);
528 /* Note: With single precision code dumping a double precision rvec will produce float iso rvec print, but that's a minor annoyance */
529 pr_dvec(list, 0, entryName(part, ecpt), reinterpret_cast<const double *>(data.data()), nf, TRUE);
532 default: GMX_RELEASE_ASSERT(false, "Data type not implemented for listing");
539 //! \brief Convert a double array, typed char*, to float
540 gmx_unused static void convertArrayRealPrecision(const char *c, float *v, int n)
542 const double *d = reinterpret_cast<const double *>(c);
543 for (int i = 0; i < n; i++)
545 v[i] = static_cast<float>(d[i]);
549 //! \brief Convert a float array, typed char*, to double
550 static void convertArrayRealPrecision(const char *c, double *v, int n)
552 const float *f = reinterpret_cast<const float *>(c);
553 for (int i = 0; i < n; i++)
555 v[i] = static_cast<double>(f[i]);
559 //! \brief Generate an error for trying to convert to integer
560 static void convertArrayRealPrecision(const char gmx_unused *c, int gmx_unused *v, int gmx_unused n)
562 GMX_RELEASE_ASSERT(false, "We only expect type mismatches between float and double, not integer");
565 /*! \brief Low-level routine for reading/writing a vector of reals from/to file.
567 * This is the only routine that does the actually i/o of real vector,
568 * all other routines are intermediate level routines for specific real
569 * data types, calling this routine.
570 * Currently this routine is (too) complex, since it handles both real *
571 * and std::vector<real>. Using real * is deprecated and this routine
572 * will simplify a lot when only std::vector needs to be supported.
574 * The routine is generic to vectors with different allocators,
575 * because as part of reading a checkpoint there are vectors whose
576 * size is not known until reading has progressed far enough, so a
577 * resize method must be called.
579 * When not listing, we use either v or vector, depending on which is !=NULL.
580 * If nval >= 0, nval is used; on read this should match the passed value.
581 * If nval n<0, *nptr (with v) or vector->size() is used. On read using v,
582 * the value is stored in nptr
584 template<typename T, typename AllocatorType>
585 static int doVectorLow(XDR *xd, StatePart part, int ecpt, int sflags,
587 T **v, std::vector<T, AllocatorType> *vector,
588 FILE *list, CptElementType cptElementType)
590 GMX_RELEASE_ASSERT(list != nullptr || (v != nullptr && vector == nullptr) || (v == nullptr && vector != nullptr), "Without list, we should have exactly one of v and vector != NULL");
594 int numElemInTheFile;
599 GMX_RELEASE_ASSERT(nptr == nullptr, "With nval>=0 we should have nptr==NULL");
600 numElemInTheFile = nval;
606 GMX_RELEASE_ASSERT(nptr != nullptr, "With nval<0 we should have nptr!=NULL");
607 numElemInTheFile = *nptr;
611 numElemInTheFile = vector->size();
615 /* Read/write the vector element count */
616 res = xdr_int(xd, &numElemInTheFile);
621 /* Read/write the element data type */
622 constexpr int xdrTypeInTheCode = xdr_type<T>::value;
623 int xdrTypeInTheFile = xdrTypeInTheCode;
624 res = xdr_int(xd, &xdrTypeInTheFile);
630 if (list == nullptr && (sflags & (1 << ecpt)))
634 if (numElemInTheFile != nval)
636 gmx_fatal(FARGS, "Count mismatch for state entry %s, code count is %d, file count is %d\n", entryName(part, ecpt), nval, numElemInTheFile);
639 else if (nptr != nullptr)
641 *nptr = numElemInTheFile;
644 bool typesMatch = (xdrTypeInTheFile == xdrTypeInTheCode);
648 sprintf(buf, "mismatch for state entry %s, code precision is %s, file precision is %s",
649 entryName(part, ecpt),
650 xdr_datatype_names[xdrTypeInTheCode],
651 xdr_datatype_names[xdrTypeInTheFile]);
653 /* Matching int and real should never occur, but check anyhow */
654 if (xdrTypeInTheFile == xdr_datatype_int ||
655 xdrTypeInTheCode == xdr_datatype_int)
657 gmx_fatal(FARGS, "Type %s: incompatible checkpoint formats or corrupted checkpoint file.", buf);
666 snew(*v, numElemInTheFile);
672 /* This conditional ensures that we don't resize on write.
673 * In particular in the state where this code was written
674 * vector has a size of numElemInThefile and we
675 * don't want to lose that padding here.
677 if (vector->size() < static_cast<unsigned int>(numElemInTheFile))
679 vector->resize(numElemInTheFile);
687 vChar = reinterpret_cast<char *>(vp);
691 snew(vChar, numElemInTheFile*sizeOfXdrType(xdrTypeInTheFile));
693 res = xdr_vector(xd, vChar,
694 numElemInTheFile, sizeOfXdrType(xdrTypeInTheFile),
695 xdrProc(xdrTypeInTheFile));
703 /* In the old code float-double conversion came for free.
704 * In the new code we still support it, mainly because
705 * the tip4p_continue regression test makes use of this.
706 * It's an open question if we do or don't want to allow this.
708 convertArrayRealPrecision(vChar, vp, numElemInTheFile);
714 res = listXdrVector(xd, part, ecpt, numElemInTheFile, xdrTypeInTheFile,
715 list, cptElementType);
721 //! \brief Read/Write a std::vector, on read checks the number of elements matches \p numElements, if specified.
722 template <typename T>
723 static int doVector(XDR *xd, StatePart part, int ecpt, int sflags,
724 std::vector<T> *vector, FILE *list, int numElements = -1)
726 return doVectorLow<T>(xd, part, ecpt, sflags, numElements, nullptr, nullptr, vector, list, CptElementType::real);
729 //! \brief Read/Write an ArrayRef<real>.
730 static int doRealArrayRef(XDR *xd, StatePart part, int ecpt, int sflags,
731 gmx::ArrayRef<real> vector, FILE *list)
733 real *v_real = vector.data();
734 return doVectorLow < real, std::allocator < real>>(xd, part, ecpt, sflags, vector.size(), nullptr, &v_real, nullptr, list, CptElementType::real);
737 //! Convert from view of RVec to view of real.
738 static gmx::ArrayRef<real>
739 realArrayRefFromRVecArrayRef(gmx::ArrayRef<gmx::RVec> ofRVecs)
741 return gmx::arrayRefFromArray<real>(reinterpret_cast<real *>(ofRVecs.data()), ofRVecs.size() * DIM);
744 //! \brief Read/Write a PaddedVector whose value_type is RVec.
745 template <typename PaddedVectorOfRVecType>
746 static int doRvecVector(XDR *xd, StatePart part, int ecpt, int sflags,
747 PaddedVectorOfRVecType *v, int numAtoms, FILE *list)
749 const int numReals = numAtoms*DIM;
753 GMX_RELEASE_ASSERT(sflags & (1 << ecpt), "When not listing, the flag for the entry should be set when requesting i/o");
754 GMX_RELEASE_ASSERT(v->size() == numAtoms, "v should have sufficient size for numAtoms");
756 return doRealArrayRef(xd, part, ecpt, sflags, realArrayRefFromRVecArrayRef(makeArrayRef(*v)), list);
760 // Use the rebind facility to change the value_type of the
761 // allocator from RVec to real.
762 using realAllocator = typename std::allocator_traits<typename PaddedVectorOfRVecType::allocator_type>::template rebind_alloc<real>;
763 return doVectorLow<real, realAllocator>(xd, part, ecpt, sflags, numReals, nullptr, nullptr, nullptr, list, CptElementType::real);
767 /* This function stores n along with the reals for reading,
768 * but on reading it assumes that n matches the value in the checkpoint file,
769 * a fatal error is generated when this is not the case.
771 static int do_cpte_reals(XDR *xd, StatePart part, int ecpt, int sflags,
772 int n, real **v, FILE *list)
774 return doVectorLow < real, std::allocator < real>>(xd, part, ecpt, sflags, n, nullptr, v, nullptr, list, CptElementType::real);
777 /* This function does the same as do_cpte_reals,
778 * except that on reading it ignores the passed value of *n
779 * and stores the value read from the checkpoint file in *n.
781 static int do_cpte_n_reals(XDR *xd, StatePart part, int ecpt, int sflags,
782 int *n, real **v, FILE *list)
784 return doVectorLow < real, std::allocator < real>>(xd, part, ecpt, sflags, -1, n, v, nullptr, list, CptElementType::real);
787 static int do_cpte_real(XDR *xd, StatePart part, int ecpt, int sflags,
790 return doVectorLow < real, std::allocator < real>>(xd, part, ecpt, sflags, 1, nullptr, &r, nullptr, list, CptElementType::real);
793 static int do_cpte_ints(XDR *xd, StatePart part, int ecpt, int sflags,
794 int n, int **v, FILE *list)
796 return doVectorLow < int, std::allocator < int>>(xd, part, ecpt, sflags, n, nullptr, v, nullptr, list, CptElementType::integer);
799 static int do_cpte_int(XDR *xd, StatePart part, int ecpt, int sflags,
802 return do_cpte_ints(xd, part, ecpt, sflags, 1, &i, list);
805 static int do_cpte_bool(XDR *xd, StatePart part, int ecpt, int sflags,
808 int i = static_cast<int>(*b);
809 int ret = do_cpte_int(xd, part, ecpt, sflags, &i, list);
814 static int do_cpte_doubles(XDR *xd, StatePart part, int ecpt, int sflags,
815 int n, double **v, FILE *list)
817 return doVectorLow < double, std::allocator < double>>(xd, part, ecpt, sflags, n, nullptr, v, nullptr, list, CptElementType::real);
820 static int do_cpte_double(XDR *xd, StatePart part, int ecpt, int sflags,
821 double *r, FILE *list)
823 return do_cpte_doubles(xd, part, ecpt, sflags, 1, &r, list);
826 static int do_cpte_matrix(XDR *xd, StatePart part, int ecpt, int sflags,
827 matrix v, FILE *list)
833 ret = doVectorLow < real, std::allocator < real>>(xd, part, ecpt, sflags,
834 DIM*DIM, nullptr, &vr, nullptr, nullptr, CptElementType::matrix3x3);
836 if (list && ret == 0)
838 pr_rvecs(list, 0, entryName(part, ecpt), v, DIM);
845 static int do_cpte_nmatrix(XDR *xd, StatePart part, int ecpt, int sflags,
846 int n, real **v, FILE *list)
850 char name[CPTSTRLEN];
857 for (i = 0; i < n; i++)
859 reti = doVectorLow < real, std::allocator < real>>(xd, part, ecpt, sflags, n, nullptr, &(v[i]), nullptr, nullptr, CptElementType::matrix3x3);
860 if (list && reti == 0)
862 sprintf(name, "%s[%d]", entryName(part, ecpt), i);
863 pr_reals(list, 0, name, v[i], n);
873 static int do_cpte_matrices(XDR *xd, StatePart part, int ecpt, int sflags,
874 int n, matrix **v, FILE *list)
877 matrix *vp, *va = nullptr;
883 res = xdr_int(xd, &nf);
888 if (list == nullptr && nf != n)
890 gmx_fatal(FARGS, "Count mismatch for state entry %s, code count is %d, file count is %d\n", entryName(part, ecpt), n, nf);
892 if (list || !(sflags & (1<<ecpt)))
905 snew(vr, nf*DIM*DIM);
906 for (i = 0; i < nf; i++)
908 for (j = 0; j < DIM; j++)
910 for (k = 0; k < DIM; k++)
912 vr[(i*DIM+j)*DIM+k] = vp[i][j][k];
916 ret = doVectorLow < real, std::allocator < real>>(xd, part, ecpt, sflags,
917 nf*DIM*DIM, nullptr, &vr, nullptr, nullptr,
918 CptElementType::matrix3x3);
919 for (i = 0; i < nf; i++)
921 for (j = 0; j < DIM; j++)
923 for (k = 0; k < DIM; k++)
925 vp[i][j][k] = vr[(i*DIM+j)*DIM+k];
931 if (list && ret == 0)
933 for (i = 0; i < nf; i++)
935 pr_rvecs(list, 0, entryName(part, ecpt), vp[i], DIM);
946 // TODO Expand this into being a container of all data for
947 // serialization of a checkpoint, which can be stored by the caller
948 // (e.g. so that mdrun doesn't have to open the checkpoint twice).
949 // This will separate issues of allocation from those of
950 // serialization, help separate comparison from reading, and have
951 // better defined transformation functions to/from trajectory frame
954 // Several fields were once written to checkpoint file headers, but
955 // have been removed. So that old files can continue to be read,
956 // the names of such fields contain the string "_UNUSED" so that it
957 // is clear they should not be used.
958 struct CheckpointHeaderContents
961 char version[CPTSTRLEN];
962 char btime_UNUSED[CPTSTRLEN];
963 char buser_UNUSED[CPTSTRLEN];
964 char bhost_UNUSED[CPTSTRLEN];
966 char fprog[CPTSTRLEN];
967 char ftime[CPTSTRLEN];
983 int flagsPullHistory;
990 static void do_cpt_header(XDR *xd, gmx_bool bRead, FILE *list,
991 CheckpointHeaderContents *contents)
1004 res = xdr_int(xd, &magic);
1007 gmx_fatal(FARGS, "The checkpoint file is empty/corrupted, or maybe you are out of disk space?");
1009 if (magic != CPT_MAGIC1)
1011 gmx_fatal(FARGS, "Start of file magic number mismatch, checkpoint file has %d, should be %d\n"
1012 "The checkpoint file is corrupted or not a checkpoint file",
1018 gmx_gethostname(fhost, 255);
1020 do_cpt_string_err(xd, "GROMACS version", contents->version, list);
1021 // The following fields are no longer ever written with meaningful
1022 // content, but because they precede the file version, there is no
1023 // good way for new code to read the old and new formats, nor a
1024 // good way for old code to avoid giving an error while reading a
1025 // new format. So we read and write a field that no longer has a
1027 do_cpt_string_err(xd, "GROMACS build time UNUSED", contents->btime_UNUSED, list);
1028 do_cpt_string_err(xd, "GROMACS build user UNUSED", contents->buser_UNUSED, list);
1029 do_cpt_string_err(xd, "GROMACS build host UNUSED", contents->bhost_UNUSED, list);
1030 do_cpt_string_err(xd, "generating program", contents->fprog, list);
1031 do_cpt_string_err(xd, "generation time", contents->ftime, list);
1032 contents->file_version = cpt_version;
1033 do_cpt_int_err(xd, "checkpoint file version", &contents->file_version, list);
1034 if (contents->file_version > cpt_version)
1036 gmx_fatal(FARGS, "Attempting to read a checkpoint file of version %d with code of version %d\n", contents->file_version, cpt_version);
1038 if (contents->file_version >= 13)
1040 do_cpt_int_err(xd, "GROMACS double precision", &contents->double_prec, list);
1044 contents->double_prec = -1;
1046 if (contents->file_version >= 12)
1048 do_cpt_string_err(xd, "generating host", fhost, list);
1050 do_cpt_int_err(xd, "#atoms", &contents->natoms, list);
1051 do_cpt_int_err(xd, "#T-coupling groups", &contents->ngtc, list);
1052 if (contents->file_version >= 10)
1054 do_cpt_int_err(xd, "#Nose-Hoover T-chains", &contents->nhchainlength, list);
1058 contents->nhchainlength = 1;
1060 if (contents->file_version >= 11)
1062 do_cpt_int_err(xd, "#Nose-Hoover T-chains for barostat ", &contents->nnhpres, list);
1066 contents->nnhpres = 0;
1068 if (contents->file_version >= 14)
1070 do_cpt_int_err(xd, "# of total lambda states ", &contents->nlambda, list);
1074 contents->nlambda = 0;
1076 do_cpt_int_err(xd, "integrator", &contents->eIntegrator, list);
1077 if (contents->file_version >= 3)
1079 do_cpt_int_err(xd, "simulation part #", &contents->simulation_part, list);
1083 contents->simulation_part = 1;
1085 if (contents->file_version >= 5)
1087 do_cpt_step_err(xd, "step", &contents->step, list);
1092 do_cpt_int_err(xd, "step", &idum, list);
1093 contents->step = static_cast<int64_t>(idum);
1095 do_cpt_double_err(xd, "t", &contents->t, list);
1096 do_cpt_int_err(xd, "#PP-ranks", &contents->nnodes, list);
1097 do_cpt_int_err(xd, "dd_nc[x]", &contents->dd_nc[XX], list);
1098 do_cpt_int_err(xd, "dd_nc[y]", &contents->dd_nc[YY], list);
1099 do_cpt_int_err(xd, "dd_nc[z]", &contents->dd_nc[ZZ], list);
1100 do_cpt_int_err(xd, "#PME-only ranks", &contents->npme, list);
1101 do_cpt_int_err(xd, "state flags", &contents->flags_state, list);
1102 if (contents->file_version >= 4)
1104 do_cpt_int_err(xd, "ekin data flags", &contents->flags_eks, list);
1105 do_cpt_int_err(xd, "energy history flags", &contents->flags_enh, list);
1109 contents->flags_eks = 0;
1110 contents->flags_enh = (contents->flags_state >> (estORIRE_DTAV+1));
1111 contents->flags_state = (contents->flags_state & ~((1<<(estORIRE_DTAV+1)) |
1112 (1<<(estORIRE_DTAV+2)) |
1113 (1<<(estORIRE_DTAV+3))));
1115 if (contents->file_version >= 14)
1117 do_cpt_int_err(xd, "df history flags", &contents->flags_dfh, list);
1121 contents->flags_dfh = 0;
1124 if (contents->file_version >= 15)
1126 do_cpt_int_err(xd, "ED data sets", &contents->nED, list);
1133 if (contents->file_version >= 16)
1135 do_cpt_int_err(xd, "swap", &contents->eSwapCoords, list);
1139 contents->eSwapCoords = eswapNO;
1142 if (contents->file_version >= 17)
1144 do_cpt_int_err(xd, "AWH history flags", &contents->flags_awhh, list);
1148 contents->flags_awhh = 0;
1151 if (contents->file_version >= 18)
1153 do_cpt_int_err(xd, "pull history flags", &contents->flagsPullHistory, list);
1157 contents->flagsPullHistory = 0;
1161 static int do_cpt_footer(XDR *xd, int file_version)
1166 if (file_version >= 2)
1169 res = xdr_int(xd, &magic);
1174 if (magic != CPT_MAGIC2)
1183 static int do_cpt_state(XDR *xd,
1184 int fflags, t_state *state,
1188 const StatePart part = StatePart::microState;
1189 const int sflags = state->flags;
1190 // If reading, state->natoms was probably just read, so
1191 // allocations need to be managed. If writing, this won't change
1192 // anything that matters.
1193 state_change_natoms(state, state->natoms);
1194 for (int i = 0; (i < estNR && ret == 0); i++)
1196 if (fflags & (1<<i))
1200 case estLAMBDA: ret = doRealArrayRef(xd, part, i, sflags, gmx::arrayRefFromArray<real>(state->lambda.data(), state->lambda.size()), list); break;
1201 case estFEPSTATE: ret = do_cpte_int (xd, part, i, sflags, &state->fep_state, list); break;
1202 case estBOX: ret = do_cpte_matrix(xd, part, i, sflags, state->box, list); break;
1203 case estBOX_REL: ret = do_cpte_matrix(xd, part, i, sflags, state->box_rel, list); break;
1204 case estBOXV: ret = do_cpte_matrix(xd, part, i, sflags, state->boxv, list); break;
1205 case estPRES_PREV: ret = do_cpte_matrix(xd, part, i, sflags, state->pres_prev, list); break;
1206 case estSVIR_PREV: ret = do_cpte_matrix(xd, part, i, sflags, state->svir_prev, list); break;
1207 case estFVIR_PREV: ret = do_cpte_matrix(xd, part, i, sflags, state->fvir_prev, list); break;
1208 case estNH_XI: ret = doVector<double>(xd, part, i, sflags, &state->nosehoover_xi, list); break;
1209 case estNH_VXI: ret = doVector<double>(xd, part, i, sflags, &state->nosehoover_vxi, list); break;
1210 case estNHPRES_XI: ret = doVector<double>(xd, part, i, sflags, &state->nhpres_xi, list); break;
1211 case estNHPRES_VXI: ret = doVector<double>(xd, part, i, sflags, &state->nhpres_vxi, list); break;
1212 case estTHERM_INT: ret = doVector<double>(xd, part, i, sflags, &state->therm_integral, list); break;
1213 case estBAROS_INT: ret = do_cpte_double(xd, part, i, sflags, &state->baros_integral, list); break;
1214 case estVETA: ret = do_cpte_real(xd, part, i, sflags, &state->veta, list); break;
1215 case estVOL0: ret = do_cpte_real(xd, part, i, sflags, &state->vol0, list); break;
1216 case estX: ret = doRvecVector(xd, part, i, sflags, &state->x, state->natoms, list); break;
1217 case estV: ret = doRvecVector(xd, part, i, sflags, &state->v, state->natoms, list); break;
1218 /* The RNG entries are no longer written,
1219 * the next 4 lines are only for reading old files.
1221 case estLD_RNG_NOTSUPPORTED: ret = do_cpte_ints(xd, part, i, sflags, 0, nullptr, list); break;
1222 case estLD_RNGI_NOTSUPPORTED: ret = do_cpte_ints(xd, part, i, sflags, 0, nullptr, list); break;
1223 case estMC_RNG_NOTSUPPORTED: ret = do_cpte_ints(xd, part, i, sflags, 0, nullptr, list); break;
1224 case estMC_RNGI_NOTSUPPORTED: ret = do_cpte_ints(xd, part, i, sflags, 0, nullptr, list); break;
1225 case estDISRE_INITF: ret = do_cpte_real (xd, part, i, sflags, &state->hist.disre_initf, list); break;
1226 case estDISRE_RM3TAV: ret = do_cpte_n_reals(xd, part, i, sflags, &state->hist.ndisrepairs, &state->hist.disre_rm3tav, list); break;
1227 case estORIRE_INITF: ret = do_cpte_real (xd, part, i, sflags, &state->hist.orire_initf, list); break;
1228 case estORIRE_DTAV: ret = do_cpte_n_reals(xd, part, i, sflags, &state->hist.norire_Dtav, &state->hist.orire_Dtav, list); break;
1229 case estPULLCOMPREVSTEP: ret = doVector<double>(xd, part, i, sflags, &state->pull_com_prev_step, list); break;
1231 gmx_fatal(FARGS, "Unknown state entry %d\n"
1232 "You are reading a checkpoint file written by different code, which is not supported", i);
1239 static int do_cpt_ekinstate(XDR *xd, int fflags, ekinstate_t *ekins,
1244 const StatePart part = StatePart::kineticEnergy;
1245 for (int i = 0; (i < eeksNR && ret == 0); i++)
1247 if (fflags & (1<<i))
1252 case eeksEKIN_N: ret = do_cpte_int(xd, part, i, fflags, &ekins->ekin_n, list); break;
1253 case eeksEKINH: ret = do_cpte_matrices(xd, part, i, fflags, ekins->ekin_n, &ekins->ekinh, list); break;
1254 case eeksEKINF: ret = do_cpte_matrices(xd, part, i, fflags, ekins->ekin_n, &ekins->ekinf, list); break;
1255 case eeksEKINO: ret = do_cpte_matrices(xd, part, i, fflags, ekins->ekin_n, &ekins->ekinh_old, list); break;
1256 case eeksEKINTOTAL: ret = do_cpte_matrix(xd, part, i, fflags, ekins->ekin_total, list); break;
1257 case eeksEKINSCALEF: ret = doVector<double>(xd, part, i, fflags, &ekins->ekinscalef_nhc, list); break;
1258 case eeksVSCALE: ret = doVector<double>(xd, part, i, fflags, &ekins->vscale_nhc, list); break;
1259 case eeksEKINSCALEH: ret = doVector<double>(xd, part, i, fflags, &ekins->ekinscaleh_nhc, list); break;
1260 case eeksDEKINDL: ret = do_cpte_real(xd, part, i, fflags, &ekins->dekindl, list); break;
1261 case eeksMVCOS: ret = do_cpte_real(xd, part, i, fflags, &ekins->mvcos, list); break;
1263 gmx_fatal(FARGS, "Unknown ekin data state entry %d\n"
1264 "You are probably reading a new checkpoint file with old code", i);
1273 static int do_cpt_swapstate(XDR *xd, gmx_bool bRead,
1274 int eSwapCoords, swaphistory_t *swapstate, FILE *list)
1276 int swap_cpt_version = 2;
1278 if (eSwapCoords == eswapNO)
1283 swapstate->bFromCpt = bRead;
1284 swapstate->eSwapCoords = eSwapCoords;
1286 do_cpt_int_err(xd, "swap checkpoint version", &swap_cpt_version, list);
1287 if (bRead && swap_cpt_version < 2)
1289 gmx_fatal(FARGS, "Cannot read checkpoint files that were written with old versions"
1290 "of the ion/water position swapping protocol.\n");
1293 do_cpt_int_err(xd, "swap coupling steps", &swapstate->nAverage, list);
1295 /* When reading, init_swapcoords has not been called yet,
1296 * so we have to allocate memory first. */
1297 do_cpt_int_err(xd, "number of ion types", &swapstate->nIonTypes, list);
1300 snew(swapstate->ionType, swapstate->nIonTypes);
1303 for (int ic = 0; ic < eCompNR; ic++)
1305 for (int ii = 0; ii < swapstate->nIonTypes; ii++)
1307 swapstateIons_t *gs = &swapstate->ionType[ii];
1311 do_cpt_int_err(xd, "swap requested atoms", &gs->nMolReq[ic], list);
1315 do_cpt_int_err(xd, "swap requested atoms p", gs->nMolReq_p[ic], list);
1320 do_cpt_int_err(xd, "swap influx net", &gs->inflow_net[ic], list);
1324 do_cpt_int_err(xd, "swap influx net p", gs->inflow_net_p[ic], list);
1327 if (bRead && (nullptr == gs->nMolPast[ic]) )
1329 snew(gs->nMolPast[ic], swapstate->nAverage);
1332 for (int j = 0; j < swapstate->nAverage; j++)
1336 do_cpt_int_err(xd, "swap past atom counts", &gs->nMolPast[ic][j], list);
1340 do_cpt_int_err(xd, "swap past atom counts p", &gs->nMolPast_p[ic][j], list);
1346 /* Ion flux per channel */
1347 for (int ic = 0; ic < eChanNR; ic++)
1349 for (int ii = 0; ii < swapstate->nIonTypes; ii++)
1351 swapstateIons_t *gs = &swapstate->ionType[ii];
1355 do_cpt_int_err(xd, "channel flux A->B", &gs->fluxfromAtoB[ic], list);
1359 do_cpt_int_err(xd, "channel flux A->B p", gs->fluxfromAtoB_p[ic], list);
1364 /* Ion flux leakage */
1367 do_cpt_int_err(xd, "flux leakage", &swapstate->fluxleak, list);
1371 do_cpt_int_err(xd, "flux leakage", swapstate->fluxleak_p, list);
1375 for (int ii = 0; ii < swapstate->nIonTypes; ii++)
1377 swapstateIons_t *gs = &swapstate->ionType[ii];
1379 do_cpt_int_err(xd, "number of ions", &gs->nMol, list);
1383 snew(gs->channel_label, gs->nMol);
1384 snew(gs->comp_from, gs->nMol);
1387 do_cpt_u_chars(xd, "channel history", gs->nMol, gs->channel_label, list);
1388 do_cpt_u_chars(xd, "domain history", gs->nMol, gs->comp_from, list);
1391 /* Save the last known whole positions to checkpoint
1392 * file to be able to also make multimeric channels whole in PBC */
1393 do_cpt_int_err(xd, "Ch0 atoms", &swapstate->nat[eChan0], list);
1394 do_cpt_int_err(xd, "Ch1 atoms", &swapstate->nat[eChan1], list);
1397 snew(swapstate->xc_old_whole[eChan0], swapstate->nat[eChan0]);
1398 snew(swapstate->xc_old_whole[eChan1], swapstate->nat[eChan1]);
1399 do_cpt_n_rvecs_err(xd, "Ch0 whole x", swapstate->nat[eChan0], swapstate->xc_old_whole[eChan0], list);
1400 do_cpt_n_rvecs_err(xd, "Ch1 whole x", swapstate->nat[eChan1], swapstate->xc_old_whole[eChan1], list);
1404 do_cpt_n_rvecs_err(xd, "Ch0 whole x", swapstate->nat[eChan0], *swapstate->xc_old_whole_p[eChan0], list);
1405 do_cpt_n_rvecs_err(xd, "Ch1 whole x", swapstate->nat[eChan1], *swapstate->xc_old_whole_p[eChan1], list);
1412 static int do_cpt_enerhist(XDR *xd, gmx_bool bRead,
1413 int fflags, energyhistory_t *enerhist,
1423 GMX_RELEASE_ASSERT(enerhist != nullptr, "With energy history, we need a valid enerhist pointer");
1425 /* This is stored/read for backward compatibility */
1426 int energyHistoryNumEnergies = 0;
1429 enerhist->nsteps = 0;
1431 enerhist->nsteps_sim = 0;
1432 enerhist->nsum_sim = 0;
1434 else if (enerhist != nullptr)
1436 energyHistoryNumEnergies = enerhist->ener_sum_sim.size();
1439 delta_h_history_t *deltaH = enerhist->deltaHForeignLambdas.get();
1440 const StatePart part = StatePart::energyHistory;
1441 for (int i = 0; (i < eenhNR && ret == 0); i++)
1443 if (fflags & (1<<i))
1447 case eenhENERGY_N: ret = do_cpte_int(xd, part, i, fflags, &energyHistoryNumEnergies, list); break;
1448 case eenhENERGY_AVER: ret = doVector<double>(xd, part, i, fflags, &enerhist->ener_ave, list); break;
1449 case eenhENERGY_SUM: ret = doVector<double>(xd, part, i, fflags, &enerhist->ener_sum, list); break;
1450 case eenhENERGY_NSUM: do_cpt_step_err(xd, eenh_names[i], &enerhist->nsum, list); break;
1451 case eenhENERGY_SUM_SIM: ret = doVector<double>(xd, part, i, fflags, &enerhist->ener_sum_sim, list); break;
1452 case eenhENERGY_NSUM_SIM: do_cpt_step_err(xd, eenh_names[i], &enerhist->nsum_sim, list); break;
1453 case eenhENERGY_NSTEPS: do_cpt_step_err(xd, eenh_names[i], &enerhist->nsteps, list); break;
1454 case eenhENERGY_NSTEPS_SIM: do_cpt_step_err(xd, eenh_names[i], &enerhist->nsteps_sim, list); break;
1455 case eenhENERGY_DELTA_H_NN:
1458 if (!bRead && deltaH != nullptr)
1460 numDeltaH = deltaH->dh.size();
1462 do_cpt_int_err(xd, eenh_names[i], &numDeltaH, list);
1465 if (deltaH == nullptr)
1467 enerhist->deltaHForeignLambdas = std::make_unique<delta_h_history_t>();
1468 deltaH = enerhist->deltaHForeignLambdas.get();
1470 deltaH->dh.resize(numDeltaH);
1471 deltaH->start_lambda_set = FALSE;
1475 case eenhENERGY_DELTA_H_LIST:
1476 for (auto dh : deltaH->dh)
1478 ret = doVector<real>(xd, part, i, fflags, &dh, list);
1481 case eenhENERGY_DELTA_H_STARTTIME:
1482 ret = do_cpte_double(xd, part, i, fflags, &(deltaH->start_time), list); break;
1483 case eenhENERGY_DELTA_H_STARTLAMBDA:
1484 ret = do_cpte_double(xd, part, i, fflags, &(deltaH->start_lambda), list); break;
1486 gmx_fatal(FARGS, "Unknown energy history entry %d\n"
1487 "You are probably reading a new checkpoint file with old code", i);
1492 if ((fflags & (1<<eenhENERGY_SUM)) && !(fflags & (1<<eenhENERGY_SUM_SIM)))
1494 /* Assume we have an old file format and copy sum to sum_sim */
1495 enerhist->ener_sum_sim = enerhist->ener_sum;
1498 if ( (fflags & (1<<eenhENERGY_NSUM)) &&
1499 !(fflags & (1<<eenhENERGY_NSTEPS)))
1501 /* Assume we have an old file format and copy nsum to nsteps */
1502 enerhist->nsteps = enerhist->nsum;
1504 if ( (fflags & (1<<eenhENERGY_NSUM_SIM)) &&
1505 !(fflags & (1<<eenhENERGY_NSTEPS_SIM)))
1507 /* Assume we have an old file format and copy nsum to nsteps */
1508 enerhist->nsteps_sim = enerhist->nsum_sim;
1514 static int doCptPullCoordHist(XDR *xd, PullCoordinateHistory *pullCoordHist,
1515 const StatePart part, FILE *list)
1520 flags |= ((1<<epullcoordh_VALUE_REF_SUM) | (1<<epullcoordh_VALUE_SUM) | (1<<epullcoordh_DR01_SUM) |
1521 (1<<epullcoordh_DR23_SUM) | (1<<epullcoordh_DR45_SUM) | (1<<epullcoordh_FSCAL_SUM));
1523 for (int i = 0; i < epullcoordh_NR && ret == 0; i++)
1527 case epullcoordh_VALUE_REF_SUM: ret = do_cpte_double(xd, part, i, flags, &(pullCoordHist->valueRef), list); break;
1528 case epullcoordh_VALUE_SUM: ret = do_cpte_double(xd, part, i, flags, &(pullCoordHist->value), list); break;
1529 case epullcoordh_DR01_SUM:
1530 for (int j = 0; j < DIM && ret == 0; j++)
1532 ret = do_cpte_double(xd, part, i, flags, &(pullCoordHist->dr01[j]), list);
1535 case epullcoordh_DR23_SUM:
1536 for (int j = 0; j < DIM && ret == 0; j++)
1538 ret = do_cpte_double(xd, part, i, flags, &(pullCoordHist->dr23[j]), list);
1541 case epullcoordh_DR45_SUM:
1542 for (int j = 0; j < DIM && ret == 0; j++)
1544 ret = do_cpte_double(xd, part, i, flags, &(pullCoordHist->dr45[j]), list);
1547 case epullcoordh_FSCAL_SUM: ret = do_cpte_double(xd, part, i, flags, &(pullCoordHist->scalarForce), list); break;
1548 case epullcoordh_DYNAX_SUM:
1549 for (int j = 0; j < DIM && ret == 0; j++)
1551 ret = do_cpte_double(xd, part, i, flags, &(pullCoordHist->dynaX[j]), list);
1560 static int doCptPullGroupHist(XDR *xd, PullGroupHistory *pullGroupHist,
1561 const StatePart part, FILE *list)
1566 flags |= ((1<<epullgrouph_X_SUM));
1568 for (int i = 0; i < epullgrouph_NR; i++)
1572 case epullgrouph_X_SUM:
1573 for (int j = 0; j < DIM && ret == 0; j++)
1575 ret = do_cpte_double(xd, part, i, flags, &(pullGroupHist->x[j]), list);
1585 static int doCptPullHist(XDR *xd, gmx_bool bRead,
1586 int fflags, PullHistory *pullHist,
1587 const StatePart part,
1591 int pullHistoryNumCoordinates = 0;
1592 int pullHistoryNumGroups = 0;
1594 /* Retain the number of terms in the sum and the number of coordinates (used for writing
1595 * average pull forces and coordinates) in the pull history, in temporary variables,
1596 * in case they cannot be read from the checkpoint, in order to have backward compatibility */
1599 pullHist->numValuesInXSum = 0;
1600 pullHist->numValuesInFSum = 0;
1602 else if (pullHist != nullptr)
1604 pullHistoryNumCoordinates = pullHist->pullCoordinateSums.size();
1605 pullHistoryNumGroups = pullHist->pullGroupSums.size();
1609 GMX_RELEASE_ASSERT(fflags == 0, "Without pull history, all flags should be off");
1612 for (int i = 0; (i < epullhNR && ret == 0); i++)
1614 if (fflags & (1<<i))
1618 case epullhPULL_NUMCOORDINATES: ret = do_cpte_int(xd, part, i, fflags, &pullHistoryNumCoordinates, list); break;
1619 case epullhPULL_NUMGROUPS: do_cpt_int_err(xd, eenh_names[i], &pullHistoryNumGroups, list); break;
1620 case epullhPULL_NUMVALUESINXSUM: do_cpt_int_err(xd, eenh_names[i], &pullHist->numValuesInXSum, list); break;
1621 case epullhPULL_NUMVALUESINFSUM: do_cpt_int_err(xd, eenh_names[i], &pullHist->numValuesInFSum, list); break;
1623 gmx_fatal(FARGS, "Unknown pull history entry %d\n"
1624 "You are probably reading a new checkpoint file with old code", i);
1630 pullHist->pullCoordinateSums.resize(pullHistoryNumCoordinates);
1631 pullHist->pullGroupSums.resize(pullHistoryNumGroups);
1633 if (pullHist->numValuesInXSum > 0 || pullHist->numValuesInFSum > 0)
1635 for (size_t i = 0; i < pullHist->pullCoordinateSums.size() && ret == 0; i++)
1637 ret = doCptPullCoordHist(xd, &(pullHist->pullCoordinateSums[i]), part, list);
1639 for (size_t i = 0; i < pullHist->pullGroupSums.size() && ret == 0; i++)
1641 ret = doCptPullGroupHist(xd, &(pullHist->pullGroupSums[i]), part, list);
1648 static int do_cpt_df_hist(XDR *xd, int fflags, int nlambda, df_history_t **dfhistPtr, FILE *list)
1657 if (*dfhistPtr == nullptr)
1659 snew(*dfhistPtr, 1);
1660 (*dfhistPtr)->nlambda = nlambda;
1661 init_df_history(*dfhistPtr, nlambda);
1663 df_history_t *dfhist = *dfhistPtr;
1665 const StatePart part = StatePart::freeEnergyHistory;
1666 for (int i = 0; (i < edfhNR && ret == 0); i++)
1668 if (fflags & (1<<i))
1672 case edfhBEQUIL: ret = do_cpte_bool(xd, part, i, fflags, &dfhist->bEquil, list); break;
1673 case edfhNATLAMBDA: ret = do_cpte_ints(xd, part, i, fflags, nlambda, &dfhist->n_at_lam, list); break;
1674 case edfhWLHISTO: ret = do_cpte_reals(xd, part, i, fflags, nlambda, &dfhist->wl_histo, list); break;
1675 case edfhWLDELTA: ret = do_cpte_real(xd, part, i, fflags, &dfhist->wl_delta, list); break;
1676 case edfhSUMWEIGHTS: ret = do_cpte_reals(xd, part, i, fflags, nlambda, &dfhist->sum_weights, list); break;
1677 case edfhSUMDG: ret = do_cpte_reals(xd, part, i, fflags, nlambda, &dfhist->sum_dg, list); break;
1678 case edfhSUMMINVAR: ret = do_cpte_reals(xd, part, i, fflags, nlambda, &dfhist->sum_minvar, list); break;
1679 case edfhSUMVAR: ret = do_cpte_reals(xd, part, i, fflags, nlambda, &dfhist->sum_variance, list); break;
1680 case edfhACCUMP: ret = do_cpte_nmatrix(xd, part, i, fflags, nlambda, dfhist->accum_p, list); break;
1681 case edfhACCUMM: ret = do_cpte_nmatrix(xd, part, i, fflags, nlambda, dfhist->accum_m, list); break;
1682 case edfhACCUMP2: ret = do_cpte_nmatrix(xd, part, i, fflags, nlambda, dfhist->accum_p2, list); break;
1683 case edfhACCUMM2: ret = do_cpte_nmatrix(xd, part, i, fflags, nlambda, dfhist->accum_m2, list); break;
1684 case edfhTIJ: ret = do_cpte_nmatrix(xd, part, i, fflags, nlambda, dfhist->Tij, list); break;
1685 case edfhTIJEMP: ret = do_cpte_nmatrix(xd, part, i, fflags, nlambda, dfhist->Tij_empirical, list); break;
1688 gmx_fatal(FARGS, "Unknown df history entry %d\n"
1689 "You are probably reading a new checkpoint file with old code", i);
1698 /* This function stores the last whole configuration of the reference and
1699 * average structure in the .cpt file
1701 static int do_cpt_EDstate(XDR *xd, gmx_bool bRead,
1702 int nED, edsamhistory_t *EDstate, FILE *list)
1709 EDstate->bFromCpt = bRead;
1712 /* When reading, init_edsam has not been called yet,
1713 * so we have to allocate memory first. */
1716 snew(EDstate->nref, EDstate->nED);
1717 snew(EDstate->old_sref, EDstate->nED);
1718 snew(EDstate->nav, EDstate->nED);
1719 snew(EDstate->old_sav, EDstate->nED);
1722 /* Read/write the last whole conformation of SREF and SAV for each ED dataset (usually only one) */
1723 for (int i = 0; i < EDstate->nED; i++)
1727 /* Reference structure SREF */
1728 sprintf(buf, "ED%d # of atoms in reference structure", i+1);
1729 do_cpt_int_err(xd, buf, &EDstate->nref[i], list);
1730 sprintf(buf, "ED%d x_ref", i+1);
1733 snew(EDstate->old_sref[i], EDstate->nref[i]);
1734 do_cpt_n_rvecs_err(xd, buf, EDstate->nref[i], EDstate->old_sref[i], list);
1738 do_cpt_n_rvecs_err(xd, buf, EDstate->nref[i], EDstate->old_sref_p[i], list);
1741 /* Average structure SAV */
1742 sprintf(buf, "ED%d # of atoms in average structure", i+1);
1743 do_cpt_int_err(xd, buf, &EDstate->nav[i], list);
1744 sprintf(buf, "ED%d x_av", i+1);
1747 snew(EDstate->old_sav[i], EDstate->nav[i]);
1748 do_cpt_n_rvecs_err(xd, buf, EDstate->nav[i], EDstate->old_sav[i], list);
1752 do_cpt_n_rvecs_err(xd, buf, EDstate->nav[i], EDstate->old_sav_p[i], list);
1759 static int do_cpt_correlation_grid(XDR *xd, gmx_bool bRead, gmx_unused int fflags,
1760 gmx::CorrelationGridHistory *corrGrid,
1761 FILE *list, int eawhh)
1765 do_cpt_int_err(xd, eawhh_names[eawhh], &(corrGrid->numCorrelationTensors), list);
1766 do_cpt_int_err(xd, eawhh_names[eawhh], &(corrGrid->tensorSize), list);
1767 do_cpt_int_err(xd, eawhh_names[eawhh], &(corrGrid->blockDataListSize), list);
1771 initCorrelationGridHistory(corrGrid, corrGrid->numCorrelationTensors, corrGrid->tensorSize, corrGrid->blockDataListSize);
1774 for (gmx::CorrelationBlockDataHistory &blockData : corrGrid->blockDataBuffer)
1776 do_cpt_double_err(xd, eawhh_names[eawhh], &(blockData.blockSumWeight), list);
1777 do_cpt_double_err(xd, eawhh_names[eawhh], &(blockData.blockSumSquareWeight), list);
1778 do_cpt_double_err(xd, eawhh_names[eawhh], &(blockData.blockSumWeightX), list);
1779 do_cpt_double_err(xd, eawhh_names[eawhh], &(blockData.blockSumWeightY), list);
1780 do_cpt_double_err(xd, eawhh_names[eawhh], &(blockData.sumOverBlocksSquareBlockWeight), list);
1781 do_cpt_double_err(xd, eawhh_names[eawhh], &(blockData.sumOverBlocksBlockSquareWeight), list);
1782 do_cpt_double_err(xd, eawhh_names[eawhh], &(blockData.sumOverBlocksBlockWeightBlockWeightX), list);
1783 do_cpt_double_err(xd, eawhh_names[eawhh], &(blockData.sumOverBlocksBlockWeightBlockWeightY), list);
1784 do_cpt_double_err(xd, eawhh_names[eawhh], &(blockData.blockLength), list);
1785 do_cpt_int_err(xd, eawhh_names[eawhh], &(blockData.previousBlockIndex), list);
1786 do_cpt_double_err(xd, eawhh_names[eawhh], &(blockData.correlationIntegral), list);
1792 static int do_cpt_awh_bias(XDR *xd, gmx_bool bRead,
1793 int fflags, gmx::AwhBiasHistory *biasHistory,
1798 gmx::AwhBiasStateHistory *state = &biasHistory->state;
1799 for (int i = 0; (i < eawhhNR && ret == 0); i++)
1801 if (fflags & (1<<i))
1805 case eawhhIN_INITIAL:
1806 do_cpt_bool_err(xd, eawhh_names[i], &state->in_initial, list); break;
1807 case eawhhEQUILIBRATEHISTOGRAM:
1808 do_cpt_bool_err(xd, eawhh_names[i], &state->equilibrateHistogram, list); break;
1810 do_cpt_double_err(xd, eawhh_names[i], &state->histSize, list); break;
1816 numPoints = biasHistory->pointState.size();
1818 do_cpt_int_err(xd, eawhh_names[i], &numPoints, list);
1821 biasHistory->pointState.resize(numPoints);
1825 case eawhhCOORDPOINT:
1826 for (auto &psh : biasHistory->pointState)
1828 do_cpt_double_err(xd, eawhh_names[i], &psh.target, list);
1829 do_cpt_double_err(xd, eawhh_names[i], &psh.free_energy, list);
1830 do_cpt_double_err(xd, eawhh_names[i], &psh.bias, list);
1831 do_cpt_double_err(xd, eawhh_names[i], &psh.weightsum_iteration, list);
1832 do_cpt_double_err(xd, eawhh_names[i], &psh.weightsum_covering, list);
1833 do_cpt_double_err(xd, eawhh_names[i], &psh.weightsum_tot, list);
1834 do_cpt_double_err(xd, eawhh_names[i], &psh.weightsum_ref, list);
1835 do_cpt_step_err(xd, eawhh_names[i], &psh.last_update_index, list);
1836 do_cpt_double_err(xd, eawhh_names[i], &psh.log_pmfsum, list);
1837 do_cpt_double_err(xd, eawhh_names[i], &psh.visits_iteration, list);
1838 do_cpt_double_err(xd, eawhh_names[i], &psh.visits_tot, list);
1841 case eawhhUMBRELLAGRIDPOINT:
1842 do_cpt_int_err(xd, eawhh_names[i], &(state->umbrellaGridpoint), list); break;
1843 case eawhhUPDATELIST:
1844 do_cpt_int_err(xd, eawhh_names[i], &(state->origin_index_updatelist), list);
1845 do_cpt_int_err(xd, eawhh_names[i], &(state->end_index_updatelist), list);
1847 case eawhhLOGSCALEDSAMPLEWEIGHT:
1848 do_cpt_double_err(xd, eawhh_names[i], &(state->logScaledSampleWeight), list);
1849 do_cpt_double_err(xd, eawhh_names[i], &(state->maxLogScaledSampleWeight), list);
1851 case eawhhNUMUPDATES:
1852 do_cpt_step_err(xd, eawhh_names[i], &(state->numUpdates), list);
1854 case eawhhFORCECORRELATIONGRID:
1855 ret = do_cpt_correlation_grid(xd, bRead, fflags, &biasHistory->forceCorrelationGrid, list, i);
1858 gmx_fatal(FARGS, "Unknown awh history entry %d\n", i);
1866 static int do_cpt_awh(XDR *xd, gmx_bool bRead,
1867 int fflags, gmx::AwhHistory *awhHistory,
1874 std::shared_ptr<gmx::AwhHistory> awhHistoryLocal;
1876 if (awhHistory == nullptr)
1878 GMX_RELEASE_ASSERT(bRead, "do_cpt_awh should not be called for writing without an AwhHistory");
1880 awhHistoryLocal = std::make_shared<gmx::AwhHistory>();
1881 awhHistory = awhHistoryLocal.get();
1884 /* To be able to read and write the AWH data several parameters determining the layout of the AWH structs need to be known
1885 (nbias, npoints, etc.). The best thing (?) would be to have these passed to this function. When writing to a checkpoint
1886 these parameters are available in awh_history (after calling init_awh_history). When reading from a checkpoint though, there
1887 is no initialized awh_history (it is initialized and set in this function). The AWH parameters have not always been read
1888 at the time when this function is called for reading so I don't know how to pass them as input. Here, this is solved by
1889 when writing a checkpoint, also storing parameters needed for future reading of the checkpoint.
1891 Another issue is that some variables that AWH checkpoints don't have a registered enum and string (e.g. nbias below).
1892 One difficulty is the multilevel structure of the data which would need to be represented somehow. */
1897 numBias = awhHistory->bias.size();
1899 do_cpt_int_err(xd, "awh_nbias", &numBias, list);
1903 awhHistory->bias.resize(numBias);
1905 for (auto &bias : awhHistory->bias)
1907 ret = do_cpt_awh_bias(xd, bRead, fflags, &bias, list);
1913 do_cpt_double_err(xd, "awh_potential_offset", &awhHistory->potentialOffset, list);
1918 static int do_cpt_files(XDR *xd, gmx_bool bRead,
1919 std::vector<gmx_file_position_t> *outputfiles,
1920 FILE *list, int file_version)
1923 gmx_off_t mask = 0xFFFFFFFFL;
1924 int offset_high, offset_low;
1925 std::array<char, CPTSTRLEN> buf;
1926 GMX_RELEASE_ASSERT(outputfiles, "Must have valid outputfiles");
1928 // Ensure that reading pre-allocates outputfiles, while writing
1929 // writes what is already there.
1930 int nfiles = outputfiles->size();
1931 if (do_cpt_int(xd, "number of output files", &nfiles, list) != 0)
1937 outputfiles->resize(nfiles);
1940 for (auto &outputfile : *outputfiles)
1942 /* 64-bit XDR numbers are not portable, so it is stored as separate high/low fractions */
1945 do_cpt_string_err(xd, "output filename", buf, list);
1946 std::copy(std::begin(buf), std::end(buf), std::begin(outputfile.filename));
1948 if (do_cpt_int(xd, "file_offset_high", &offset_high, list) != 0)
1952 if (do_cpt_int(xd, "file_offset_low", &offset_low, list) != 0)
1956 outputfile.offset = (static_cast<gmx_off_t>(offset_high) << 32 ) | ( static_cast<gmx_off_t>(offset_low) & mask );
1960 do_cpt_string_err(xd, "output filename", outputfile.filename, list);
1962 offset = outputfile.offset;
1970 offset_low = static_cast<int>(offset & mask);
1971 offset_high = static_cast<int>((offset >> 32) & mask);
1973 if (do_cpt_int(xd, "file_offset_high", &offset_high, list) != 0)
1977 if (do_cpt_int(xd, "file_offset_low", &offset_low, list) != 0)
1982 if (file_version >= 8)
1984 if (do_cpt_int(xd, "file_checksum_size", &outputfile.checksumSize,
1989 if (do_cpt_u_chars(xd, "file_checksum", outputfile.checksum.size(), outputfile.checksum.data(), list) != 0)
1996 outputfile.checksumSize = -1;
2003 void write_checkpoint(const char *fn, gmx_bool bNumberAndKeep,
2004 FILE *fplog, const t_commrec *cr,
2005 ivec domdecCells, int nppnodes,
2006 int eIntegrator, int simulation_part,
2007 gmx_bool bExpanded, int elamstats,
2008 int64_t step, double t,
2009 t_state *state, ObservablesHistory *observablesHistory)
2012 char *fntemp; /* the temporary checkpoint file name */
2014 char buf[1024], suffix[5+STEPSTRSIZE], sbuf[STEPSTRSIZE];
2017 if (DOMAINDECOMP(cr))
2019 npmenodes = cr->npmenodes;
2027 /* make the new temporary filename */
2028 snew(fntemp, std::strlen(fn)+5+STEPSTRSIZE);
2029 std::strcpy(fntemp, fn);
2030 fntemp[std::strlen(fn) - std::strlen(ftp2ext(fn2ftp(fn))) - 1] = '\0';
2031 sprintf(suffix, "_%s%s", "step", gmx_step_str(step, sbuf));
2032 std::strcat(fntemp, suffix);
2033 std::strcat(fntemp, fn+std::strlen(fn) - std::strlen(ftp2ext(fn2ftp(fn))) - 1);
2035 /* if we can't rename, we just overwrite the cpt file.
2036 * dangerous if interrupted.
2038 snew(fntemp, std::strlen(fn));
2039 std::strcpy(fntemp, fn);
2041 std::string timebuf = gmx_format_current_time();
2045 fprintf(fplog, "Writing checkpoint, step %s at %s\n\n",
2046 gmx_step_str(step, buf), timebuf.c_str());
2049 /* Get offsets for open files */
2050 auto outputfiles = gmx_fio_get_output_file_positions();
2052 fp = gmx_fio_open(fntemp, "w");
2055 if (state->ekinstate.bUpToDate)
2058 ((1<<eeksEKIN_N) | (1<<eeksEKINH) | (1<<eeksEKINF) |
2059 (1<<eeksEKINO) | (1<<eeksEKINSCALEF) | (1<<eeksEKINSCALEH) |
2060 (1<<eeksVSCALE) | (1<<eeksDEKINDL) | (1<<eeksMVCOS));
2067 energyhistory_t *enerhist = observablesHistory->energyHistory.get();
2069 if (enerhist != nullptr && (enerhist->nsum > 0 || enerhist->nsum_sim > 0))
2071 flags_enh |= (1<<eenhENERGY_N) | (1<<eenhENERGY_NSTEPS) | (1<<eenhENERGY_NSTEPS_SIM);
2072 if (enerhist->nsum > 0)
2074 flags_enh |= ((1<<eenhENERGY_AVER) | (1<<eenhENERGY_SUM) |
2075 (1<<eenhENERGY_NSUM));
2077 if (enerhist->nsum_sim > 0)
2079 flags_enh |= ((1<<eenhENERGY_SUM_SIM) | (1<<eenhENERGY_NSUM_SIM));
2081 if (enerhist->deltaHForeignLambdas != nullptr)
2083 flags_enh |= ( (1<< eenhENERGY_DELTA_H_NN) |
2084 (1<< eenhENERGY_DELTA_H_LIST) |
2085 (1<< eenhENERGY_DELTA_H_STARTTIME) |
2086 (1<< eenhENERGY_DELTA_H_STARTLAMBDA) );
2090 PullHistory *pullHist = observablesHistory->pullHistory.get();
2091 int flagsPullHistory = 0;
2092 if (pullHist != nullptr && (pullHist->numValuesInXSum > 0 || pullHist->numValuesInFSum > 0))
2094 flagsPullHistory |= (1<<epullhPULL_NUMCOORDINATES);
2095 flagsPullHistory |= ((1<<epullhPULL_NUMGROUPS) | (1<<epullhPULL_NUMVALUESINXSUM) | (1<<epullhPULL_NUMVALUESINFSUM));
2101 flags_dfh = ((1<<edfhBEQUIL) | (1<<edfhNATLAMBDA) | (1<<edfhSUMWEIGHTS) | (1<<edfhSUMDG) |
2102 (1<<edfhTIJ) | (1<<edfhTIJEMP));
2105 flags_dfh |= ((1<<edfhWLDELTA) | (1<<edfhWLHISTO));
2107 if ((elamstats == elamstatsMINVAR) || (elamstats == elamstatsBARKER) || (elamstats == elamstatsMETROPOLIS))
2109 flags_dfh |= ((1<<edfhACCUMP) | (1<<edfhACCUMM) | (1<<edfhACCUMP2) | (1<<edfhACCUMM2)
2110 | (1<<edfhSUMMINVAR) | (1<<edfhSUMVAR));
2119 if (state->awhHistory != nullptr && !state->awhHistory->bias.empty())
2121 flags_awhh |= ( (1 << eawhhIN_INITIAL) |
2122 (1 << eawhhEQUILIBRATEHISTOGRAM) |
2123 (1 << eawhhHISTSIZE) |
2124 (1 << eawhhNPOINTS) |
2125 (1 << eawhhCOORDPOINT) |
2126 (1 << eawhhUMBRELLAGRIDPOINT) |
2127 (1 << eawhhUPDATELIST) |
2128 (1 << eawhhLOGSCALEDSAMPLEWEIGHT) |
2129 (1 << eawhhNUMUPDATES) |
2130 (1 << eawhhFORCECORRELATIONGRID));
2133 /* We can check many more things now (CPU, acceleration, etc), but
2134 * it is highly unlikely to have two separate builds with exactly
2135 * the same version, user, time, and build host!
2138 int nlambda = (state->dfhist ? state->dfhist->nlambda : 0);
2140 edsamhistory_t *edsamhist = observablesHistory->edsamHistory.get();
2141 int nED = (edsamhist ? edsamhist->nED : 0);
2143 swaphistory_t *swaphist = observablesHistory->swapHistory.get();
2144 int eSwapCoords = (swaphist ? swaphist->eSwapCoords : eswapNO);
2146 CheckpointHeaderContents headerContents =
2148 0, {0}, {0}, {0}, {0}, GMX_DOUBLE, {0}, {0},
2149 eIntegrator, simulation_part, step, t, nppnodes,
2151 state->natoms, state->ngtc, state->nnhpres,
2152 state->nhchainlength, nlambda, state->flags, flags_eks, flags_enh,
2153 flagsPullHistory, flags_dfh, flags_awhh,
2156 std::strcpy(headerContents.version, gmx_version());
2157 std::strcpy(headerContents.fprog, gmx::getProgramContext().fullBinaryPath());
2158 std::strcpy(headerContents.ftime, timebuf.c_str());
2159 if (DOMAINDECOMP(cr))
2161 copy_ivec(domdecCells, headerContents.dd_nc);
2164 do_cpt_header(gmx_fio_getxdr(fp), FALSE, nullptr, &headerContents);
2166 if ((do_cpt_state(gmx_fio_getxdr(fp), state->flags, state, nullptr) < 0) ||
2167 (do_cpt_ekinstate(gmx_fio_getxdr(fp), flags_eks, &state->ekinstate, nullptr) < 0) ||
2168 (do_cpt_enerhist(gmx_fio_getxdr(fp), FALSE, flags_enh, enerhist, nullptr) < 0) ||
2169 (doCptPullHist(gmx_fio_getxdr(fp), FALSE, flagsPullHistory, pullHist, StatePart::pullHistory, nullptr) < 0) ||
2170 (do_cpt_df_hist(gmx_fio_getxdr(fp), flags_dfh, nlambda, &state->dfhist, nullptr) < 0) ||
2171 (do_cpt_EDstate(gmx_fio_getxdr(fp), FALSE, nED, edsamhist, nullptr) < 0) ||
2172 (do_cpt_awh(gmx_fio_getxdr(fp), FALSE, flags_awhh, state->awhHistory.get(), nullptr) < 0) ||
2173 (do_cpt_swapstate(gmx_fio_getxdr(fp), FALSE, eSwapCoords, swaphist, nullptr) < 0) ||
2174 (do_cpt_files(gmx_fio_getxdr(fp), FALSE, &outputfiles, nullptr,
2175 headerContents.file_version) < 0))
2177 gmx_file("Cannot read/write checkpoint; corrupt file, or maybe you are out of disk space?");
2180 do_cpt_footer(gmx_fio_getxdr(fp), headerContents.file_version);
2182 /* we really, REALLY, want to make sure to physically write the checkpoint,
2183 and all the files it depends on, out to disk. Because we've
2184 opened the checkpoint with gmx_fio_open(), it's in our list
2186 ret = gmx_fio_all_output_fsync();
2192 "Cannot fsync '%s'; maybe you are out of disk space?",
2193 gmx_fio_getname(ret));
2195 if (getenv(GMX_IGNORE_FSYNC_FAILURE_ENV) == nullptr)
2201 gmx_warning("%s", buf);
2205 if (gmx_fio_close(fp) != 0)
2207 gmx_file("Cannot read/write checkpoint; corrupt file, or maybe you are out of disk space?");
2210 /* we don't move the checkpoint if the user specified they didn't want it,
2211 or if the fsyncs failed */
2213 if (!bNumberAndKeep && !ret)
2217 /* Rename the previous checkpoint file */
2218 std::strcpy(buf, fn);
2219 buf[std::strlen(fn) - std::strlen(ftp2ext(fn2ftp(fn))) - 1] = '\0';
2220 std::strcat(buf, "_prev");
2221 std::strcat(buf, fn+std::strlen(fn) - std::strlen(ftp2ext(fn2ftp(fn))) - 1);
2224 /* we copy here so that if something goes wrong between now and
2225 * the rename below, there's always a state.cpt.
2226 * If renames are atomic (such as in POSIX systems),
2227 * this copying should be unneccesary.
2229 gmx_file_copy(fn, buf, FALSE);
2230 /* We don't really care if this fails:
2231 * there's already a new checkpoint.
2236 gmx_file_rename(fn, buf);
2239 if (gmx_file_rename(fntemp, fn) != 0)
2241 gmx_file("Cannot rename checkpoint file; maybe you are out of disk space?");
2244 #endif /* GMX_NO_RENAME */
2249 /*code for alternate checkpointing scheme. moved from top of loop over
2251 fcRequestCheckPoint();
2252 if (fcCheckPointParallel( cr->nodeid, NULL, 0) == 0)
2254 gmx_fatal( 3, __FILE__, __LINE__, "Checkpoint error on step %d\n", step );
2256 #endif /* end GMX_FAHCORE block */
2259 static void check_int(FILE *fplog, const char *type, int p, int f, gmx_bool *mm)
2261 bool foundMismatch = (p != f);
2269 fprintf(fplog, " %s mismatch,\n", type);
2270 fprintf(fplog, " current program: %d\n", p);
2271 fprintf(fplog, " checkpoint file: %d\n", f);
2272 fprintf(fplog, "\n");
2276 static void check_string(FILE *fplog, const char *type, const char *p,
2277 const char *f, gmx_bool *mm)
2279 bool foundMismatch = (std::strcmp(p, f) != 0);
2287 fprintf(fplog, " %s mismatch,\n", type);
2288 fprintf(fplog, " current program: %s\n", p);
2289 fprintf(fplog, " checkpoint file: %s\n", f);
2290 fprintf(fplog, "\n");
2294 static void check_match(FILE *fplog, const t_commrec *cr, const ivec dd_nc,
2295 const CheckpointHeaderContents &headerContents,
2296 gmx_bool reproducibilityRequested)
2298 /* Note that this check_string on the version will also print a message
2299 * when only the minor version differs. But we only print a warning
2300 * message further down with reproducibilityRequested=TRUE.
2302 gmx_bool versionDiffers = FALSE;
2303 check_string(fplog, "Version", gmx_version(), headerContents.version, &versionDiffers);
2305 gmx_bool precisionDiffers = FALSE;
2306 check_int (fplog, "Double prec.", GMX_DOUBLE, headerContents.double_prec, &precisionDiffers);
2307 if (precisionDiffers)
2309 const char msg_precision_difference[] =
2310 "You are continuing a simulation with a different precision. Not matching\n"
2311 "single/double precision will lead to precision or performance loss.\n";
2314 fprintf(fplog, "%s\n", msg_precision_difference);
2318 gmx_bool mm = (versionDiffers || precisionDiffers);
2320 if (reproducibilityRequested)
2322 check_string(fplog, "Program name", gmx::getProgramContext().fullBinaryPath(), headerContents.fprog, &mm);
2324 check_int (fplog, "#ranks", cr->nnodes, headerContents.nnodes, &mm);
2327 if (cr->nnodes > 1 && reproducibilityRequested)
2329 check_int (fplog, "#PME-ranks", cr->npmenodes, headerContents.npme, &mm);
2331 int npp = cr->nnodes;
2332 if (cr->npmenodes >= 0)
2334 npp -= cr->npmenodes;
2336 int npp_f = headerContents.nnodes;
2337 if (headerContents.npme >= 0)
2339 npp_f -= headerContents.npme;
2343 check_int (fplog, "#DD-cells[x]", dd_nc[XX], headerContents.dd_nc[XX], &mm);
2344 check_int (fplog, "#DD-cells[y]", dd_nc[YY], headerContents.dd_nc[YY], &mm);
2345 check_int (fplog, "#DD-cells[z]", dd_nc[ZZ], headerContents.dd_nc[ZZ], &mm);
2351 /* Gromacs should be able to continue from checkpoints between
2352 * different patch level versions, but we do not guarantee
2353 * compatibility between different major/minor versions - check this.
2357 sscanf(gmx_version(), "%5d", &gmx_major);
2358 int ret = sscanf(headerContents.version, "%5d", &cpt_major);
2359 gmx_bool majorVersionDiffers = (ret < 1 || gmx_major != cpt_major);
2361 const char msg_major_version_difference[] =
2362 "The current GROMACS major version is not identical to the one that\n"
2363 "generated the checkpoint file. In principle GROMACS does not support\n"
2364 "continuation from checkpoints between different versions, so we advise\n"
2365 "against this. If you still want to try your luck we recommend that you use\n"
2366 "the -noappend flag to keep your output files from the two versions separate.\n"
2367 "This might also work around errors where the output fields in the energy\n"
2368 "file have changed between the different versions.\n";
2370 const char msg_mismatch_notice[] =
2371 "GROMACS patchlevel, binary or parallel settings differ from previous run.\n"
2372 "Continuation is exact, but not guaranteed to be binary identical.\n";
2374 if (majorVersionDiffers)
2378 fprintf(fplog, "%s\n", msg_major_version_difference);
2381 else if (reproducibilityRequested)
2383 /* Major & minor versions match at least, but something is different. */
2386 fprintf(fplog, "%s\n", msg_mismatch_notice);
2392 static void lockLogFile(FILE *fplog,
2393 t_fileio *chksum_file,
2394 const char *filename,
2397 /* Note that there are systems where the lock operation
2398 * will succeed, but a second process can also lock the file.
2399 * We should probably try to detect this.
2401 #if defined __native_client__
2404 #elif GMX_NATIVE_WINDOWS
2405 if (_locking(fileno(gmx_fio_getfp(chksum_file)), _LK_NBLCK, LONG_MAX) == -1)
2407 struct flock fl; /* don't initialize here: the struct order is OS
2409 fl.l_type = F_WRLCK;
2410 fl.l_whence = SEEK_SET;
2415 if (fcntl(fileno(gmx_fio_getfp(chksum_file)), F_SETLK, &fl) == -1)
2418 if (errno == ENOSYS)
2422 gmx_fatal(FARGS, "File locking is not supported on this system. Use -noappend or specify -append explicitly to append anyhow.");
2428 fprintf(fplog, "\nNOTE: File locking not supported on this system, will not lock %s\n\n", filename);
2432 else if (errno == EACCES || errno == EAGAIN)
2434 gmx_fatal(FARGS, "Failed to lock: %s. Already running "
2435 "simulation?", filename);
2439 gmx_fatal(FARGS, "Failed to lock: %s. %s.",
2440 filename, std::strerror(errno));
2445 //! Check whether chksum_file output file has a checksum that matches \c outputfile from the checkpoint.
2446 static void checkOutputFile(t_fileio *chksum_file,
2447 const gmx_file_position_t &outputfile)
2449 /* compute md5 chksum */
2450 std::array<unsigned char, 16> digest;
2451 if (outputfile.checksumSize != -1)
2453 if (gmx_fio_get_file_md5(chksum_file, outputfile.offset,
2454 &digest) != outputfile.checksumSize) /*at the end of the call the file position is at the end of the file*/
2456 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.",
2457 outputfile.checksumSize,
2458 outputfile.filename);
2462 /* compare md5 chksum */
2463 if (outputfile.checksumSize != -1 &&
2464 digest != outputfile.checksum)
2468 fprintf(debug, "chksum for %s: ", outputfile.filename);
2469 for (int j = 0; j < 16; j++)
2471 fprintf(debug, "%02x", digest[j]);
2473 fprintf(debug, "\n");
2475 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.",
2476 outputfile.filename);
2480 static void read_checkpoint(const char *fn, t_fileio *logfio,
2481 const t_commrec *cr,
2484 int *init_fep_state,
2485 CheckpointHeaderContents *headerContents,
2486 t_state *state, gmx_bool *bReadEkin,
2487 ObservablesHistory *observablesHistory,
2488 gmx_bool bAppendOutputFiles, gmx_bool bForceAppend,
2489 gmx_bool reproducibilityRequested)
2493 char buf[STEPSTRSIZE];
2496 fp = gmx_fio_open(fn, "r");
2497 do_cpt_header(gmx_fio_getxdr(fp), TRUE, nullptr, headerContents);
2499 if (bAppendOutputFiles &&
2500 headerContents->file_version >= 13 && headerContents->double_prec != GMX_DOUBLE)
2502 gmx_fatal(FARGS, "Output file appending requested, but the code and checkpoint file precision (single/double) don't match");
2505 // If we are appending, then we don't write to the open log file
2506 // because we still need to compute a checksum for it. Otherwise
2507 // we report to the new log file about the checkpoint file that we
2508 // are reading from.
2509 FILE *fplog = bAppendOutputFiles ? nullptr : gmx_fio_getfp(logfio);
2512 fprintf(fplog, "\n");
2513 fprintf(fplog, "Reading checkpoint file %s\n", fn);
2514 fprintf(fplog, " file generated by: %s\n", headerContents->fprog);
2515 fprintf(fplog, " file generated at: %s\n", headerContents->ftime);
2516 fprintf(fplog, " GROMACS double prec.: %d\n", headerContents->double_prec);
2517 fprintf(fplog, " simulation part #: %d\n", headerContents->simulation_part);
2518 fprintf(fplog, " step: %s\n", gmx_step_str(headerContents->step, buf));
2519 fprintf(fplog, " time: %f\n", headerContents->t);
2520 fprintf(fplog, "\n");
2523 if (headerContents->natoms != state->natoms)
2525 gmx_fatal(FARGS, "Checkpoint file is for a system of %d atoms, while the current system consists of %d atoms", headerContents->natoms, state->natoms);
2527 if (headerContents->ngtc != state->ngtc)
2529 gmx_fatal(FARGS, "Checkpoint file is for a system of %d T-coupling groups, while the current system consists of %d T-coupling groups", headerContents->ngtc, state->ngtc);
2531 if (headerContents->nnhpres != state->nnhpres)
2533 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", headerContents->nnhpres, state->nnhpres);
2536 int nlambdaHistory = (state->dfhist ? state->dfhist->nlambda : 0);
2537 if (headerContents->nlambda != nlambdaHistory)
2539 gmx_fatal(FARGS, "Checkpoint file is for a system with %d lambda states, while the current system consists of %d lambda states", headerContents->nlambda, nlambdaHistory);
2542 init_gtc_state(state, state->ngtc, state->nnhpres, headerContents->nhchainlength); /* need to keep this here to keep the tpr format working */
2543 /* write over whatever was read; we use the number of Nose-Hoover chains from the checkpoint */
2545 if (headerContents->eIntegrator != eIntegrator)
2547 gmx_fatal(FARGS, "Cannot change integrator during a checkpoint restart. Perhaps you should make a new .tpr with grompp -f new.mdp -t %s", fn);
2550 if (headerContents->flags_state != state->flags)
2552 gmx_fatal(FARGS, "Cannot change a simulation algorithm during a checkpoint restart. Perhaps you should make a new .tpr with grompp -f new.mdp -t %s", fn);
2557 check_match(fplog, cr, dd_nc, *headerContents,
2558 reproducibilityRequested);
2561 ret = do_cpt_state(gmx_fio_getxdr(fp), headerContents->flags_state, state, nullptr);
2562 *init_fep_state = state->fep_state; /* there should be a better way to do this than setting it here.
2563 Investigate for 5.0. */
2568 ret = do_cpt_ekinstate(gmx_fio_getxdr(fp), headerContents->flags_eks, &state->ekinstate, nullptr);
2573 *bReadEkin = (((headerContents->flags_eks & (1<<eeksEKINH)) != 0) ||
2574 ((headerContents->flags_eks & (1<<eeksEKINF)) != 0) ||
2575 ((headerContents->flags_eks & (1<<eeksEKINO)) != 0) ||
2576 (((headerContents->flags_eks & (1<<eeksEKINSCALEF)) |
2577 (headerContents->flags_eks & (1<<eeksEKINSCALEH)) |
2578 (headerContents->flags_eks & (1<<eeksVSCALE))) != 0));
2580 if (headerContents->flags_enh && observablesHistory->energyHistory == nullptr)
2582 observablesHistory->energyHistory = std::make_unique<energyhistory_t>();
2584 ret = do_cpt_enerhist(gmx_fio_getxdr(fp), TRUE,
2585 headerContents->flags_enh, observablesHistory->energyHistory.get(), nullptr);
2591 if (headerContents->flagsPullHistory)
2593 if (observablesHistory->pullHistory == nullptr)
2595 observablesHistory->pullHistory = std::make_unique<PullHistory>();
2597 ret = doCptPullHist(gmx_fio_getxdr(fp), TRUE,
2598 headerContents->flagsPullHistory, observablesHistory->pullHistory.get(), StatePart::pullHistory, nullptr);
2605 if (headerContents->file_version < 6)
2607 gmx_fatal(FARGS, "Continuing from checkpoint files written before GROMACS 4.5 is not supported");
2610 ret = do_cpt_df_hist(gmx_fio_getxdr(fp), headerContents->flags_dfh, headerContents->nlambda, &state->dfhist, nullptr);
2616 if (headerContents->nED > 0 && observablesHistory->edsamHistory == nullptr)
2618 observablesHistory->edsamHistory = std::make_unique<edsamhistory_t>(edsamhistory_t {});
2620 ret = do_cpt_EDstate(gmx_fio_getxdr(fp), TRUE, headerContents->nED, observablesHistory->edsamHistory.get(), nullptr);
2626 if (headerContents->flags_awhh != 0 && state->awhHistory == nullptr)
2628 state->awhHistory = std::make_shared<gmx::AwhHistory>();
2630 ret = do_cpt_awh(gmx_fio_getxdr(fp), TRUE,
2631 headerContents->flags_awhh, state->awhHistory.get(), nullptr);
2637 if (headerContents->eSwapCoords != eswapNO && observablesHistory->swapHistory == nullptr)
2639 observablesHistory->swapHistory = std::make_unique<swaphistory_t>(swaphistory_t {});
2641 ret = do_cpt_swapstate(gmx_fio_getxdr(fp), TRUE, headerContents->eSwapCoords, observablesHistory->swapHistory.get(), nullptr);
2647 std::vector<gmx_file_position_t> outputfiles;
2648 ret = do_cpt_files(gmx_fio_getxdr(fp), TRUE, &outputfiles, nullptr, headerContents->file_version);
2654 ret = do_cpt_footer(gmx_fio_getxdr(fp), headerContents->file_version);
2659 if (gmx_fio_close(fp) != 0)
2661 gmx_file("Cannot read/write checkpoint; corrupt file, or maybe you are out of disk space?");
2664 /* If the user wants to append to output files,
2665 * we use the file pointer positions of the output files stored
2666 * in the checkpoint file and truncate the files such that any frames
2667 * written after the checkpoint time are removed.
2668 * All files are md5sum checked such that we can be sure that
2669 * we do not truncate other (maybe imprortant) files.
2671 if (bAppendOutputFiles)
2673 if (outputfiles.empty())
2675 gmx_fatal(FARGS, "No names of output files were recorded in the checkpoint");
2677 if (fn2ftp(outputfiles[0].filename) != efLOG)
2679 /* make sure first file is log file so that it is OK to use it for
2682 gmx_fatal(FARGS, "The first output file should always be the log "
2683 "file but instead is: %s. Cannot do appending because of this condition.", outputfiles[0].filename);
2685 for (const auto &outputfile : outputfiles)
2687 if (outputfile.offset < 0)
2689 gmx_fatal(FARGS, "The original run wrote a file called '%s' which "
2690 "is larger than 2 GB, but mdrun did not support large file"
2691 " offsets. Can not append. Run mdrun with -noappend",
2692 outputfile.filename);
2696 // Handle the log file separately - it comes first in the
2697 // list, so we make sure that we retain a lock on the open
2698 // file that is never lifted after the checksum is calculated.
2700 const gmx_file_position_t &logOutputFile = outputfiles[0];
2703 lockLogFile(fplog, logfio, logOutputFile.filename, bForceAppend);
2704 checkOutputFile(logfio, logOutputFile);
2706 if (gmx_fio_seek(logfio, logOutputFile.offset))
2708 gmx_fatal(FARGS, "Seek error! Failed to truncate log-file: %s.", std::strerror(errno));
2714 // Now handle the remaining outputfiles
2715 gmx::ArrayRef<gmx_file_position_t> outputfilesView(outputfiles);
2716 for (const auto &outputfile : outputfilesView.subArray(1, outputfiles.size()-1))
2718 t_fileio *chksum_file = gmx_fio_open(outputfile.filename, "r+");
2719 checkOutputFile(chksum_file, outputfile);
2720 gmx_fio_close(chksum_file);
2722 if (!GMX_NATIVE_WINDOWS)
2724 /* For FAHCORE, we do this elsewhere*/
2725 rc = gmx_truncate(outputfile.filename, outputfile.offset);
2728 gmx_fatal(FARGS, "Truncation of file %s failed. Cannot do appending because of this failure.", outputfile.filename);
2737 void load_checkpoint(const char *fn, t_fileio *logfio,
2738 const t_commrec *cr, const ivec dd_nc,
2739 t_inputrec *ir, t_state *state,
2740 gmx_bool *bReadEkin,
2741 ObservablesHistory *observablesHistory,
2742 gmx_bool bAppend, gmx_bool bForceAppend,
2743 gmx_bool reproducibilityRequested)
2745 CheckpointHeaderContents headerContents;
2748 /* Read the state from the checkpoint file */
2749 read_checkpoint(fn, logfio,
2751 ir->eI, &(ir->fepvals->init_fep_state),
2753 state, bReadEkin, observablesHistory,
2754 bAppend, bForceAppend,
2755 reproducibilityRequested);
2759 gmx_bcast(sizeof(headerContents.step), &headerContents.step, cr);
2760 gmx_bcast(sizeof(*bReadEkin), bReadEkin, cr);
2762 ir->bContinuation = TRUE;
2763 // TODO Should the following condition be <=? Currently if you
2764 // pass a checkpoint written by an normal completion to a restart,
2765 // mdrun will read all input, does some work but no steps, and
2766 // write successful output. But perhaps that is not desirable.
2767 if ((ir->nsteps >= 0) && (ir->nsteps < headerContents.step))
2769 // Note that we do not intend to support the use of mdrun
2770 // -nsteps to circumvent this condition.
2771 char nstepsString[STEPSTRSIZE], stepString[STEPSTRSIZE];
2772 gmx_step_str(ir->nsteps, nstepsString);
2773 gmx_step_str(headerContents.step, stepString);
2774 gmx_fatal(FARGS, "The input requested %s steps, however the checkpoint "
2775 "file has already reached step %s. The simulation will not "
2776 "proceed, because either your simulation is already complete, "
2777 "or your combination of input files don't match.",
2778 nstepsString, stepString);
2780 if (ir->nsteps >= 0)
2782 ir->nsteps += ir->init_step - headerContents.step;
2784 ir->init_step = headerContents.step;
2785 ir->simulation_part = headerContents.simulation_part + 1;
2788 void read_checkpoint_part_and_step(const char *filename,
2789 int *simulation_part,
2794 if (filename == nullptr ||
2795 !gmx_fexist(filename) ||
2796 ((fp = gmx_fio_open(filename, "r")) == nullptr))
2798 *simulation_part = 0;
2803 CheckpointHeaderContents headerContents;
2804 do_cpt_header(gmx_fio_getxdr(fp), TRUE, nullptr, &headerContents);
2806 *simulation_part = headerContents.simulation_part;
2807 *step = headerContents.step;
2810 static void read_checkpoint_data(t_fileio *fp, int *simulation_part,
2811 int64_t *step, double *t, t_state *state,
2812 std::vector<gmx_file_position_t> *outputfiles)
2816 CheckpointHeaderContents headerContents;
2817 do_cpt_header(gmx_fio_getxdr(fp), TRUE, nullptr, &headerContents);
2818 *simulation_part = headerContents.simulation_part;
2819 *step = headerContents.step;
2820 *t = headerContents.t;
2821 state->natoms = headerContents.natoms;
2822 state->ngtc = headerContents.ngtc;
2823 state->nnhpres = headerContents.nnhpres;
2824 state->nhchainlength = headerContents.nhchainlength;
2825 state->flags = headerContents.flags_state;
2827 do_cpt_state(gmx_fio_getxdr(fp), state->flags, state, nullptr);
2832 ret = do_cpt_ekinstate(gmx_fio_getxdr(fp), headerContents.flags_eks, &state->ekinstate, nullptr);
2838 energyhistory_t enerhist;
2839 ret = do_cpt_enerhist(gmx_fio_getxdr(fp), TRUE,
2840 headerContents.flags_enh, &enerhist, nullptr);
2845 PullHistory pullHist = {};
2846 ret = doCptPullHist(gmx_fio_getxdr(fp), TRUE,
2847 headerContents.flagsPullHistory, &pullHist, StatePart::pullHistory, nullptr);
2853 ret = do_cpt_df_hist(gmx_fio_getxdr(fp), headerContents.flags_dfh, headerContents.nlambda, &state->dfhist, nullptr);
2859 edsamhistory_t edsamhist = {};
2860 ret = do_cpt_EDstate(gmx_fio_getxdr(fp), TRUE, headerContents.nED, &edsamhist, nullptr);
2866 ret = do_cpt_awh(gmx_fio_getxdr(fp), TRUE,
2867 headerContents.flags_awhh, state->awhHistory.get(), nullptr);
2873 swaphistory_t swaphist = {};
2874 ret = do_cpt_swapstate(gmx_fio_getxdr(fp), TRUE, headerContents.eSwapCoords, &swaphist, nullptr);
2880 ret = do_cpt_files(gmx_fio_getxdr(fp), TRUE,
2882 nullptr, headerContents.file_version);
2889 ret = do_cpt_footer(gmx_fio_getxdr(fp), headerContents.file_version);
2896 void read_checkpoint_trxframe(t_fileio *fp, t_trxframe *fr)
2899 int simulation_part;
2903 std::vector<gmx_file_position_t> outputfiles;
2904 read_checkpoint_data(fp, &simulation_part, &step, &t, &state, &outputfiles);
2906 fr->natoms = state.natoms;
2908 fr->step = int64_to_int(step,
2909 "conversion of checkpoint to trajectory");
2913 fr->lambda = state.lambda[efptFEP];
2914 fr->fep_state = state.fep_state;
2916 fr->bX = ((state.flags & (1<<estX)) != 0);
2919 fr->x = makeRvecArray(state.x, state.natoms);
2921 fr->bV = ((state.flags & (1<<estV)) != 0);
2924 fr->v = makeRvecArray(state.v, state.natoms);
2927 fr->bBox = ((state.flags & (1<<estBOX)) != 0);
2930 copy_mat(state.box, fr->box);
2934 void list_checkpoint(const char *fn, FILE *out)
2941 fp = gmx_fio_open(fn, "r");
2942 CheckpointHeaderContents headerContents;
2943 do_cpt_header(gmx_fio_getxdr(fp), TRUE, out, &headerContents);
2944 state.natoms = headerContents.natoms;
2945 state.ngtc = headerContents.ngtc;
2946 state.nnhpres = headerContents.nnhpres;
2947 state.nhchainlength = headerContents.nhchainlength;
2948 state.flags = headerContents.flags_state;
2949 ret = do_cpt_state(gmx_fio_getxdr(fp), state.flags, &state, out);
2954 ret = do_cpt_ekinstate(gmx_fio_getxdr(fp), headerContents.flags_eks, &state.ekinstate, out);
2960 energyhistory_t enerhist;
2961 ret = do_cpt_enerhist(gmx_fio_getxdr(fp), TRUE,
2962 headerContents.flags_enh, &enerhist, out);
2966 PullHistory pullHist = {};
2967 ret = doCptPullHist(gmx_fio_getxdr(fp), TRUE,
2968 headerContents.flagsPullHistory, &pullHist, StatePart::pullHistory, out);
2973 ret = do_cpt_df_hist(gmx_fio_getxdr(fp),
2974 headerContents.flags_dfh, headerContents.nlambda, &state.dfhist, out);
2979 edsamhistory_t edsamhist = {};
2980 ret = do_cpt_EDstate(gmx_fio_getxdr(fp), TRUE, headerContents.nED, &edsamhist, out);
2985 ret = do_cpt_awh(gmx_fio_getxdr(fp), TRUE,
2986 headerContents.flags_awhh, state.awhHistory.get(), out);
2991 swaphistory_t swaphist = {};
2992 ret = do_cpt_swapstate(gmx_fio_getxdr(fp), TRUE, headerContents.eSwapCoords, &swaphist, out);
2997 std::vector<gmx_file_position_t> outputfiles;
2998 ret = do_cpt_files(gmx_fio_getxdr(fp), TRUE, &outputfiles, out, headerContents.file_version);
3003 ret = do_cpt_footer(gmx_fio_getxdr(fp), headerContents.file_version);
3010 if (gmx_fio_close(fp) != 0)
3012 gmx_file("Cannot read/write checkpoint; corrupt file, or maybe you are out of disk space?");
3016 /* This routine cannot print tons of data, since it is called before the log file is opened. */
3018 read_checkpoint_simulation_part_and_filenames(t_fileio *fp,
3019 int *simulation_part,
3020 std::vector<gmx_file_position_t> *outputfiles)
3026 read_checkpoint_data(fp, simulation_part, &step, &t, &state, outputfiles);
3027 if (gmx_fio_close(fp) != 0)
3029 gmx_file("Cannot read/write checkpoint; corrupt file, or maybe you are out of disk space?");