Cleaned up memory usage in gmx traj and trjconv
[gromacs.git] / src / gromacs / fileio / checkpoint.cpp
blob9377b60f451ebbf198dd694009fdb552662b5188
1 /*
2 * This file is part of the GROMACS molecular simulation package.
4 * Copyright (c) 2008,2009,2010,2011,2012,2013,2014,2015,2016,2017, 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. */
38 #include "gmxpre.h"
40 #include "checkpoint.h"
42 #include "config.h"
44 #include <cerrno>
45 #include <cstdlib>
46 #include <cstring>
48 #include <fcntl.h>
49 #if GMX_NATIVE_WINDOWS
50 #include <io.h>
51 #include <sys/locking.h>
52 #endif
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/arrayref.h"
72 #include "gromacs/utility/baseversion.h"
73 #include "gromacs/utility/cstringutil.h"
74 #include "gromacs/utility/fatalerror.h"
75 #include "gromacs/utility/futil.h"
76 #include "gromacs/utility/gmxassert.h"
77 #include "gromacs/utility/int64_to_int.h"
78 #include "gromacs/utility/programcontext.h"
79 #include "gromacs/utility/smalloc.h"
80 #include "gromacs/utility/sysinfo.h"
81 #include "gromacs/utility/txtdump.h"
83 #ifdef GMX_FAHCORE
84 #include "corewrap.h"
85 #endif
87 #define CPT_MAGIC1 171817
88 #define CPT_MAGIC2 171819
89 #define CPTSTRLEN 1024
91 /* cpt_version should normally only be changed
92 * when the header or footer format changes.
93 * The state data format itself is backward and forward compatible.
94 * But old code can not read a new entry that is present in the file
95 * (but can read a new format when new entries are not present).
97 static const int cpt_version = 16;
100 const char *est_names[estNR] =
102 "FE-lambda",
103 "box", "box-rel", "box-v", "pres_prev",
104 "nosehoover-xi", "thermostat-integral",
105 "x", "v", "sdx-unsupported", "CGp", "LD-rng-unsupported", "LD-rng-i-unsupported",
106 "disre_initf", "disre_rm3tav",
107 "orire_initf", "orire_Dtav",
108 "svir_prev", "nosehoover-vxi", "v_eta", "vol0", "nhpres_xi", "nhpres_vxi", "fvir_prev", "fep_state", "MC-rng-unsupported", "MC-rng-i-unsupported"
111 enum {
112 eeksEKIN_N, eeksEKINH, eeksDEKINDL, eeksMVCOS, eeksEKINF, eeksEKINO, eeksEKINSCALEF, eeksEKINSCALEH, eeksVSCALE, eeksEKINTOTAL, eeksNR
115 const char *eeks_names[eeksNR] =
117 "Ekin_n", "Ekinh", "dEkindlambda", "mv_cos",
118 "Ekinf", "Ekinh_old", "EkinScaleF_NHC", "EkinScaleH_NHC", "Vscale_NHC", "Ekin_Total"
121 enum {
122 eenhENERGY_N, eenhENERGY_AVER, eenhENERGY_SUM, eenhENERGY_NSUM,
123 eenhENERGY_SUM_SIM, eenhENERGY_NSUM_SIM,
124 eenhENERGY_NSTEPS, eenhENERGY_NSTEPS_SIM,
125 eenhENERGY_DELTA_H_NN,
126 eenhENERGY_DELTA_H_LIST,
127 eenhENERGY_DELTA_H_STARTTIME,
128 eenhENERGY_DELTA_H_STARTLAMBDA,
129 eenhNR
132 const char *eenh_names[eenhNR] =
134 "energy_n", "energy_aver", "energy_sum", "energy_nsum",
135 "energy_sum_sim", "energy_nsum_sim",
136 "energy_nsteps", "energy_nsteps_sim",
137 "energy_delta_h_nn",
138 "energy_delta_h_list",
139 "energy_delta_h_start_time",
140 "energy_delta_h_start_lambda"
143 /* free energy history variables -- need to be preserved over checkpoint */
144 enum {
145 edfhBEQUIL, edfhNATLAMBDA, edfhWLHISTO, edfhWLDELTA, edfhSUMWEIGHTS, edfhSUMDG, edfhSUMMINVAR, edfhSUMVAR,
146 edfhACCUMP, edfhACCUMM, edfhACCUMP2, edfhACCUMM2, edfhTIJ, edfhTIJEMP, edfhNR
148 /* free energy history variable names */
149 const char *edfh_names[edfhNR] =
151 "bEquilibrated", "N_at_state", "Wang-Landau Histogram", "Wang-Landau Delta", "Weights", "Free Energies", "minvar", "variance",
152 "accumulated_plus", "accumulated_minus", "accumulated_plus_2", "accumulated_minus_2", "Tij", "Tij_empirical"
155 //! Higher level vector element type, only used for formatting checkpoint dumps
156 enum class CptElementType
158 integer, //!< integer
159 real, //!< float or double, not linked to precision of type real
160 real3, //!< float[3] or double[3], not linked to precision of type real
161 matrix3x3 //!< float[3][3] or double[3][3], not linked to precision of type real
164 //! \brief Parts of the checkpoint state, only used for reporting
165 enum class StatePart
167 microState, //!< The microstate of the simulated system
168 kineticEnergy, //!< Kinetic energy, needed for T/P-coupling state
169 energyHistory, //!< Energy observable statistics
170 freeEnergyHistory //!< Free-energy state and observable statistics
173 //! \brief Return the name of a checkpoint entry based on part and part entry
174 static const char *entryName(StatePart part, int ecpt)
176 switch (part)
178 case StatePart::microState: return est_names [ecpt];
179 case StatePart::kineticEnergy: return eeks_names[ecpt];
180 case StatePart::energyHistory: return eenh_names[ecpt];
181 case StatePart::freeEnergyHistory: return edfh_names[ecpt];
184 return nullptr;
187 static void cp_warning(FILE *fp)
189 fprintf(fp, "\nWARNING: Checkpoint file is corrupted or truncated\n\n");
192 static void cp_error()
194 gmx_fatal(FARGS, "Checkpoint file corrupted/truncated, or maybe you are out of disk space?");
197 static void do_cpt_string_err(XDR *xd, gmx_bool bRead, const char *desc, char **s, FILE *list)
199 if (bRead)
201 snew(*s, CPTSTRLEN);
203 if (xdr_string(xd, s, CPTSTRLEN) == 0)
205 cp_error();
207 if (list)
209 fprintf(list, "%s = %s\n", desc, *s);
210 sfree(*s);
214 static int do_cpt_int(XDR *xd, const char *desc, int *i, FILE *list)
216 if (xdr_int(xd, i) == 0)
218 return -1;
220 if (list)
222 fprintf(list, "%s = %d\n", desc, *i);
224 return 0;
227 static int do_cpt_u_chars(XDR *xd, const char *desc, int n, unsigned char *i, FILE *list)
229 if (list)
231 fprintf(list, "%s = ", desc);
233 bool_t res = 1;
234 for (int j = 0; j < n && res; j++)
236 res &= xdr_u_char(xd, &i[j]);
237 if (list)
239 fprintf(list, "%02x", i[j]);
242 if (list)
244 fprintf(list, "\n");
246 if (res == 0)
248 return -1;
251 return 0;
254 static void do_cpt_int_err(XDR *xd, const char *desc, int *i, FILE *list)
256 if (do_cpt_int(xd, desc, i, list) < 0)
258 cp_error();
262 static void do_cpt_step_err(XDR *xd, const char *desc, gmx_int64_t *i, FILE *list)
264 char buf[STEPSTRSIZE];
266 if (xdr_int64(xd, i) == 0)
268 cp_error();
270 if (list)
272 fprintf(list, "%s = %s\n", desc, gmx_step_str(*i, buf));
276 static void do_cpt_double_err(XDR *xd, const char *desc, double *f, FILE *list)
278 if (xdr_double(xd, f) == 0)
280 cp_error();
282 if (list)
284 fprintf(list, "%s = %f\n", desc, *f);
288 static void do_cpt_real_err(XDR *xd, real *f)
290 #if GMX_DOUBLE
291 bool_t res = xdr_double(xd, f);
292 #else
293 bool_t res = xdr_float(xd, f);
294 #endif
295 if (res == 0)
297 cp_error();
301 static void do_cpt_n_rvecs_err(XDR *xd, const char *desc, int n, rvec f[], FILE *list)
303 for (int i = 0; i < n; i++)
305 for (int j = 0; j < DIM; j++)
307 do_cpt_real_err(xd, &f[i][j]);
311 if (list)
313 pr_rvecs(list, 0, desc, f, n);
317 template <typename T>
318 struct xdr_type
322 template <>
323 struct xdr_type<int>
325 // cppcheck-suppress unusedStructMember
326 static const int value = xdr_datatype_int;
329 template <>
330 struct xdr_type<float>
332 // cppcheck-suppress unusedStructMember
333 static const int value = xdr_datatype_float;
336 template <>
337 struct xdr_type<double>
339 // cppcheck-suppress unusedStructMember
340 static const int value = xdr_datatype_double;
343 //! \brief Returns size in byte of an xdr_datatype
344 static inline unsigned int sizeOfXdrType(int xdrType)
346 switch (xdrType)
348 case xdr_datatype_int:
349 return sizeof(int);
350 break;
351 case xdr_datatype_float:
352 return sizeof(float);
353 break;
354 case xdr_datatype_double:
355 return sizeof(double);
356 break;
357 default: GMX_RELEASE_ASSERT(false, "XDR data type not implemented");
360 return 0;
363 //! \brief Returns the XDR process function for i/o of an XDR type
364 static inline xdrproc_t xdrProc(int xdrType)
366 switch (xdrType)
368 case xdr_datatype_int:
369 return reinterpret_cast<xdrproc_t>(xdr_int);
370 break;
371 case xdr_datatype_float:
372 return reinterpret_cast<xdrproc_t>(xdr_float);
373 break;
374 case xdr_datatype_double:
375 return reinterpret_cast<xdrproc_t>(xdr_double);
376 break;
377 default: GMX_RELEASE_ASSERT(false, "XDR data type not implemented");
380 return nullptr;
383 /*! \brief Lists or only reads an xdr vector from checkpoint file
385 * When list!=NULL reads and lists the \p nf vector elements of type \p xdrType.
386 * The header for the print is set by \p part and \p ecpt.
387 * The formatting of the printing is set by \p cptElementType.
388 * When list==NULL only reads the elements.
390 static bool_t listXdrVector(XDR *xd, StatePart part, int ecpt, int nf, int xdrType,
391 FILE *list, CptElementType cptElementType)
393 bool_t res = 0;
395 const unsigned int elemSize = sizeOfXdrType(xdrType);
396 std::vector<char> data(nf*elemSize);
397 res = xdr_vector(xd, data.data(), nf, elemSize, xdrProc(xdrType));
399 if (list != nullptr)
401 switch (xdrType)
403 case xdr_datatype_int:
404 pr_ivec(list, 0, entryName(part, ecpt), reinterpret_cast<const int *>(data.data()), nf, TRUE);
405 break;
406 case xdr_datatype_float:
407 #if !GMX_DOUBLE
408 if (cptElementType == CptElementType::real3)
410 // cppcheck-suppress invalidPointerCast
411 pr_rvecs(list, 0, entryName(part, ecpt), reinterpret_cast<const rvec *>(data.data()), nf/3);
413 else
414 #endif
416 /* Note: With double precision code dumping a single precision rvec will produce float iso rvec print, but that's a minor annoyance */
417 // cppcheck-suppress invalidPointerCast
418 pr_fvec(list, 0, entryName(part, ecpt), reinterpret_cast<const float *>(data.data()), nf, TRUE);
420 break;
421 case xdr_datatype_double:
422 #if GMX_DOUBLE
423 if (cptElementType == CptElementType::real3)
425 // cppcheck-suppress invalidPointerCast
426 pr_rvecs(list, 0, entryName(part, ecpt), reinterpret_cast<const rvec *>(data.data()), nf/3);
428 else
429 #endif
431 /* Note: With single precision code dumping a double precision rvec will produce float iso rvec print, but that's a minor annoyance */
432 // cppcheck-suppress invalidPointerCast
433 pr_dvec(list, 0, entryName(part, ecpt), reinterpret_cast<const double *>(data.data()), nf, TRUE);
435 break;
436 default: GMX_RELEASE_ASSERT(false, "Data type not implemented for listing");
440 return res;
443 //! \brief Convert a double array, typed char*, to float
444 static void convertArrayRealPrecision(const char *c, float *v, int n)
446 // cppcheck-suppress invalidPointerCast
447 const double *d = reinterpret_cast<const double *>(c);
448 for (int i = 0; i < n; i++)
450 v[i] = static_cast<float>(d[i]);
454 //! \brief Convert a float array, typed char*, to double
455 static void convertArrayRealPrecision(const char *c, double *v, int n)
457 // cppcheck-suppress invalidPointerCast
458 const float *f = reinterpret_cast<const float *>(c);
459 for (int i = 0; i < n; i++)
461 v[i] = static_cast<double>(f[i]);
465 //! \brief Generate an error for trying to convert to integer
466 static void convertArrayRealPrecision(const char gmx_unused *c, int gmx_unused *v, int gmx_unused n)
468 GMX_RELEASE_ASSERT(false, "We only expect type mismatches between float and double, not integer");
471 /*! \brief Low-level routine for reading/writing a vector of reals from/to file.
473 * This is the only routine that does the actually i/o of real vector,
474 * all other routines are intermediate level routines for specific real
475 * data types, calling this routine.
476 * Currently this routine is (too) complex, since it handles both real *
477 * and std::vector<real>. Using real * is deprecated and this routine
478 * will simplify a lot when only std::vector needs to be supported.
480 * When not listing, we use either v or vector, depending on which is !=NULL.
481 * If nval >= 0, nval is used; on read this should match the passed value.
482 * If nval n<0, *nptr (with v) or vector->size() is used. On read using v,
483 * the value is stored in nptr
485 template<typename T>
486 static int doVectorLow(XDR *xd, StatePart part, int ecpt, int sflags,
487 int nval, int *nptr,
488 T **v, std::vector<T> *vector,
489 FILE *list, CptElementType cptElementType)
491 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");
493 bool_t res = 0;
495 int numElemInTheFile;
496 if (list == nullptr)
498 if (nval >= 0)
500 GMX_RELEASE_ASSERT(nptr == nullptr, "With nval>=0 we should have nptr==NULL");
501 numElemInTheFile = nval;
503 else
505 if (v != nullptr)
507 GMX_RELEASE_ASSERT(nptr != nullptr, "With nval<0 we should have nptr!=NULL");
508 // cppcheck-suppress nullPointer
509 numElemInTheFile = *nptr;
511 else
513 numElemInTheFile = vector->size();
517 /* Read/write the vector element count */
518 res = xdr_int(xd, &numElemInTheFile);
519 if (res == 0)
521 return -1;
523 /* Read/write the element data type */
524 gmx_constexpr int xdrTypeInTheCode = xdr_type<T>::value;
525 int xdrTypeInTheFile = xdrTypeInTheCode;
526 res = xdr_int(xd, &xdrTypeInTheFile);
527 if (res == 0)
529 return -1;
532 if (list == nullptr && (sflags & (1 << ecpt)))
534 if (nval >= 0)
536 if (numElemInTheFile != nval)
538 gmx_fatal(FARGS, "Count mismatch for state entry %s, code count is %d, file count is %d\n", entryName(part, ecpt), nval, numElemInTheFile);
541 else if (nptr != nullptr)
543 *nptr = numElemInTheFile;
546 bool typesMatch = (xdrTypeInTheFile == xdrTypeInTheCode);
547 if (!typesMatch)
549 char buf[STRLEN];
550 sprintf(buf, "mismatch for state entry %s, code precision is %s, file precision is %s",
551 entryName(part, ecpt),
552 xdr_datatype_names[xdrTypeInTheCode],
553 xdr_datatype_names[xdrTypeInTheFile]);
555 /* Matching int and real should never occur, but check anyhow */
556 if (xdrTypeInTheFile == xdr_datatype_int ||
557 xdrTypeInTheCode == xdr_datatype_int)
559 gmx_fatal(FARGS, "Type %s: incompatible checkpoint formats or corrupted checkpoint file.", buf);
561 fprintf(stderr, "Precision %s\n", buf);
564 T *vp;
565 if (v != nullptr)
567 if (*v == nullptr)
569 snew(*v, numElemInTheFile);
571 vp = *v;
573 else
575 /* This conditional ensures that we don't resize on write.
576 * In particular in the state where this code was written
577 * PaddedRVecVector has a size of numElemInThefile and we
578 * don't want to lose that padding here.
580 if (vector->size() < static_cast<unsigned int>(numElemInTheFile))
582 vector->resize(numElemInTheFile);
584 vp = vector->data();
587 char *vChar;
588 if (typesMatch)
590 vChar = reinterpret_cast<char *>(vp);
592 else
594 snew(vChar, numElemInTheFile*sizeOfXdrType(xdrTypeInTheFile));
596 res = xdr_vector(xd, vChar,
597 numElemInTheFile, sizeOfXdrType(xdrTypeInTheFile),
598 xdrProc(xdrTypeInTheFile));
599 if (res == 0)
601 return -1;
604 if (!typesMatch)
606 /* In the old code float-double conversion came for free.
607 * In the new code we still support it, mainly because
608 * the tip4p_continue regression test makes use of this.
609 * It's an open question if we do or don't want to allow this.
611 convertArrayRealPrecision(vChar, vp, numElemInTheFile);
612 sfree(vChar);
615 else
617 res = listXdrVector(xd, part, ecpt, numElemInTheFile, xdrTypeInTheFile,
618 list, cptElementType);
621 return 0;
624 //! \brief Read/Write a std::vector.
625 template <typename T>
626 static int doVector(XDR *xd, StatePart part, int ecpt, int sflags,
627 std::vector<T> *vector, FILE *list)
629 return doVectorLow<T>(xd, part, ecpt, sflags, -1, nullptr, nullptr, vector, list, CptElementType::real);
632 //! \brief Read/Write an ArrayRef<real>.
633 static int doRealArrayRef(XDR *xd, StatePart part, int ecpt, int sflags,
634 gmx::ArrayRef<real> vector, FILE *list)
636 real *v_real = vector.data();
637 return doVectorLow<real>(xd, part, ecpt, sflags, vector.size(), nullptr, &v_real, nullptr, list, CptElementType::real);
640 //! \brief Read/Write a PaddedRVecVector.
641 static int doPaddedRvecVector(XDR *xd, StatePart part, int ecpt, int sflags,
642 gmx::PaddedRVecVector *vector, FILE *list)
644 real *v_real;
646 if (list == nullptr && (sflags & (1 << ecpt)))
648 v_real = vector->data()->as_vec();
650 else
652 v_real = nullptr;
654 // The current invariant of a PaddedRVecVector is that its size is
655 // one larger than necessary to store the data. Make sure that we
656 // read/write only the valid data, and don't leak to the outside
657 // world that currently we find it convenient internally to
658 // allocate one extra element.
659 gmx::ArrayRef<real> ref(v_real, v_real + (vector->size()-1) * DIM);
661 return doRealArrayRef(xd, part, ecpt, sflags, ref, list);
664 /* This function stores n along with the reals for reading,
665 * but on reading it assumes that n matches the value in the checkpoint file,
666 * a fatal error is generated when this is not the case.
668 static int do_cpte_reals(XDR *xd, StatePart part, int ecpt, int sflags,
669 int n, real **v, FILE *list)
671 return doVectorLow<real>(xd, part, ecpt, sflags, n, nullptr, v, nullptr, list, CptElementType::real);
674 /* This function does the same as do_cpte_reals,
675 * except that on reading it ignores the passed value of *n
676 * and stores the value read from the checkpoint file in *n.
678 static int do_cpte_n_reals(XDR *xd, StatePart part, int ecpt, int sflags,
679 int *n, real **v, FILE *list)
681 return doVectorLow<real>(xd, part, ecpt, sflags, -1, n, v, nullptr, list, CptElementType::real);
684 static int do_cpte_real(XDR *xd, StatePart part, int ecpt, int sflags,
685 real *r, FILE *list)
687 return doVectorLow<real>(xd, part, ecpt, sflags, 1, nullptr, &r, nullptr, list, CptElementType::real);
690 static int do_cpte_ints(XDR *xd, StatePart part, int ecpt, int sflags,
691 int n, int **v, FILE *list)
693 return doVectorLow<int>(xd, part, ecpt, sflags, n, nullptr, v, nullptr, list, CptElementType::integer);
696 static int do_cpte_int(XDR *xd, StatePart part, int ecpt, int sflags,
697 int *i, FILE *list)
699 return do_cpte_ints(xd, part, ecpt, sflags, 1, &i, list);
702 static int do_cpte_doubles(XDR *xd, StatePart part, int ecpt, int sflags,
703 int n, double **v, FILE *list)
705 return doVectorLow<double>(xd, part, ecpt, sflags, n, nullptr, v, nullptr, list, CptElementType::real);
708 static int do_cpte_double(XDR *xd, StatePart part, int ecpt, int sflags,
709 double *r, FILE *list)
711 return do_cpte_doubles(xd, part, ecpt, sflags, 1, &r, list);
714 static int do_cpte_matrix(XDR *xd, StatePart part, int ecpt, int sflags,
715 matrix v, FILE *list)
717 real *vr;
718 int ret;
720 vr = &(v[0][0]);
721 ret = doVectorLow<real>(xd, part, ecpt, sflags,
722 DIM*DIM, nullptr, &vr, nullptr, nullptr, CptElementType::matrix3x3);
724 if (list && ret == 0)
726 pr_rvecs(list, 0, entryName(part, ecpt), v, DIM);
729 return ret;
733 static int do_cpte_nmatrix(XDR *xd, StatePart part, int ecpt, int sflags,
734 int n, real **v, FILE *list)
736 int i;
737 int ret, reti;
738 char name[CPTSTRLEN];
740 ret = 0;
741 if (v == nullptr)
743 snew(v, n);
745 for (i = 0; i < n; i++)
747 reti = doVectorLow<real>(xd, part, ecpt, sflags, n, nullptr, &(v[i]), nullptr, nullptr, CptElementType::matrix3x3);
748 if (list && reti == 0)
750 sprintf(name, "%s[%d]", entryName(part, ecpt), i);
751 pr_reals(list, 0, name, v[i], n);
753 if (reti != 0)
755 ret = reti;
758 return ret;
761 static int do_cpte_matrices(XDR *xd, StatePart part, int ecpt, int sflags,
762 int n, matrix **v, FILE *list)
764 bool_t res = 0;
765 matrix *vp, *va = nullptr;
766 real *vr;
767 int nf, i, j, k;
768 int ret;
770 nf = n;
771 res = xdr_int(xd, &nf);
772 if (res == 0)
774 return -1;
776 if (list == nullptr && nf != n)
778 gmx_fatal(FARGS, "Count mismatch for state entry %s, code count is %d, file count is %d\n", entryName(part, ecpt), n, nf);
780 if (list || !(sflags & (1<<ecpt)))
782 snew(va, nf);
783 vp = va;
785 else
787 if (*v == nullptr)
789 snew(*v, nf);
791 vp = *v;
793 snew(vr, nf*DIM*DIM);
794 for (i = 0; i < nf; i++)
796 for (j = 0; j < DIM; j++)
798 for (k = 0; k < DIM; k++)
800 vr[(i*DIM+j)*DIM+k] = vp[i][j][k];
804 ret = doVectorLow<real>(xd, part, ecpt, sflags,
805 nf*DIM*DIM, nullptr, &vr, nullptr, nullptr,
806 CptElementType::matrix3x3);
807 for (i = 0; i < nf; i++)
809 for (j = 0; j < DIM; j++)
811 for (k = 0; k < DIM; k++)
813 vp[i][j][k] = vr[(i*DIM+j)*DIM+k];
817 sfree(vr);
819 if (list && ret == 0)
821 for (i = 0; i < nf; i++)
823 pr_rvecs(list, 0, entryName(part, ecpt), vp[i], DIM);
826 if (va)
828 sfree(va);
831 return ret;
834 static void do_cpt_header(XDR *xd, gmx_bool bRead, int *file_version,
835 char **version, char **btime, char **buser, char **bhost,
836 int *double_prec,
837 char **fprog, char **ftime,
838 int *eIntegrator, int *simulation_part,
839 gmx_int64_t *step, double *t,
840 int *nnodes, int *dd_nc, int *npme,
841 int *natoms, int *ngtc, int *nnhpres, int *nhchainlength,
842 int *nlambda, int *flags_state,
843 int *flags_eks, int *flags_enh, int *flags_dfh,
844 int *nED, int *eSwapCoords,
845 FILE *list)
847 bool_t res = 0;
848 int magic;
849 int idum = 0;
850 char *fhost;
852 if (bRead)
854 magic = -1;
856 else
858 magic = CPT_MAGIC1;
860 res = xdr_int(xd, &magic);
861 if (res == 0)
863 gmx_fatal(FARGS, "The checkpoint file is empty/corrupted, or maybe you are out of disk space?");
865 if (magic != CPT_MAGIC1)
867 gmx_fatal(FARGS, "Start of file magic number mismatch, checkpoint file has %d, should be %d\n"
868 "The checkpoint file is corrupted or not a checkpoint file",
869 magic, CPT_MAGIC1);
871 if (!bRead)
873 snew(fhost, 255);
874 gmx_gethostname(fhost, 255);
876 do_cpt_string_err(xd, bRead, "GROMACS version", version, list);
877 do_cpt_string_err(xd, bRead, "GROMACS build time", btime, list);
878 do_cpt_string_err(xd, bRead, "GROMACS build user", buser, list);
879 do_cpt_string_err(xd, bRead, "GROMACS build host", bhost, list);
880 do_cpt_string_err(xd, bRead, "generating program", fprog, list);
881 do_cpt_string_err(xd, bRead, "generation time", ftime, list);
882 *file_version = cpt_version;
883 do_cpt_int_err(xd, "checkpoint file version", file_version, list);
884 if (*file_version > cpt_version)
886 gmx_fatal(FARGS, "Attempting to read a checkpoint file of version %d with code of version %d\n", *file_version, cpt_version);
888 if (*file_version >= 13)
890 do_cpt_int_err(xd, "GROMACS double precision", double_prec, list);
892 else
894 *double_prec = -1;
896 if (*file_version >= 12)
898 do_cpt_string_err(xd, bRead, "generating host", &fhost, list);
899 if (list == nullptr)
901 sfree(fhost);
904 do_cpt_int_err(xd, "#atoms", natoms, list);
905 do_cpt_int_err(xd, "#T-coupling groups", ngtc, list);
906 if (*file_version >= 10)
908 do_cpt_int_err(xd, "#Nose-Hoover T-chains", nhchainlength, list);
910 else
912 *nhchainlength = 1;
914 if (*file_version >= 11)
916 do_cpt_int_err(xd, "#Nose-Hoover T-chains for barostat ", nnhpres, list);
918 else
920 *nnhpres = 0;
922 if (*file_version >= 14)
924 do_cpt_int_err(xd, "# of total lambda states ", nlambda, list);
926 else
928 *nlambda = 0;
930 do_cpt_int_err(xd, "integrator", eIntegrator, list);
931 if (*file_version >= 3)
933 do_cpt_int_err(xd, "simulation part #", simulation_part, list);
935 else
937 *simulation_part = 1;
939 if (*file_version >= 5)
941 do_cpt_step_err(xd, "step", step, list);
943 else
945 do_cpt_int_err(xd, "step", &idum, list);
946 *step = idum;
948 do_cpt_double_err(xd, "t", t, list);
949 do_cpt_int_err(xd, "#PP-ranks", nnodes, list);
950 idum = 1;
951 do_cpt_int_err(xd, "dd_nc[x]", dd_nc ? &(dd_nc[0]) : &idum, list);
952 do_cpt_int_err(xd, "dd_nc[y]", dd_nc ? &(dd_nc[1]) : &idum, list);
953 do_cpt_int_err(xd, "dd_nc[z]", dd_nc ? &(dd_nc[2]) : &idum, list);
954 do_cpt_int_err(xd, "#PME-only ranks", npme, list);
955 do_cpt_int_err(xd, "state flags", flags_state, list);
956 if (*file_version >= 4)
958 do_cpt_int_err(xd, "ekin data flags", flags_eks, list);
959 do_cpt_int_err(xd, "energy history flags", flags_enh, list);
961 else
963 *flags_eks = 0;
964 *flags_enh = (*flags_state >> (estORIRE_DTAV+1));
965 *flags_state = (*flags_state & ~((1<<(estORIRE_DTAV+1)) |
966 (1<<(estORIRE_DTAV+2)) |
967 (1<<(estORIRE_DTAV+3))));
969 if (*file_version >= 14)
971 do_cpt_int_err(xd, "df history flags", flags_dfh, list);
973 else
975 *flags_dfh = 0;
978 if (*file_version >= 15)
980 do_cpt_int_err(xd, "ED data sets", nED, list);
982 else
984 *nED = 0;
986 if (*file_version >= 16)
988 do_cpt_int_err(xd, "swap", eSwapCoords, list);
990 else
992 *eSwapCoords = eswapNO;
996 static int do_cpt_footer(XDR *xd, int file_version)
998 bool_t res = 0;
999 int magic;
1001 if (file_version >= 2)
1003 magic = CPT_MAGIC2;
1004 res = xdr_int(xd, &magic);
1005 if (res == 0)
1007 cp_error();
1009 if (magic != CPT_MAGIC2)
1011 return -1;
1015 return 0;
1018 static int do_cpt_state(XDR *xd,
1019 int fflags, t_state *state,
1020 FILE *list)
1022 int ret = 0;
1023 const StatePart part = StatePart::microState;
1024 const int sflags = state->flags;
1025 // If reading, state->natoms was probably just read, so
1026 // allocations need to be managed. If writing, this won't change
1027 // anything that matters.
1028 state_change_natoms(state, state->natoms);
1029 for (int i = 0; (i < estNR && ret == 0); i++)
1031 if (fflags & (1<<i))
1033 switch (i)
1035 case estLAMBDA: ret = doRealArrayRef(xd, part, i, sflags, gmx::arrayRefFromArray<real>(state->lambda.data(), state->lambda.size()), list); break;
1036 case estFEPSTATE: ret = do_cpte_int (xd, part, i, sflags, &state->fep_state, list); break;
1037 case estBOX: ret = do_cpte_matrix(xd, part, i, sflags, state->box, list); break;
1038 case estBOX_REL: ret = do_cpte_matrix(xd, part, i, sflags, state->box_rel, list); break;
1039 case estBOXV: ret = do_cpte_matrix(xd, part, i, sflags, state->boxv, list); break;
1040 case estPRES_PREV: ret = do_cpte_matrix(xd, part, i, sflags, state->pres_prev, list); break;
1041 case estSVIR_PREV: ret = do_cpte_matrix(xd, part, i, sflags, state->svir_prev, list); break;
1042 case estFVIR_PREV: ret = do_cpte_matrix(xd, part, i, sflags, state->fvir_prev, list); break;
1043 case estNH_XI: ret = doVector<double>(xd, part, i, sflags, &state->nosehoover_xi, list); break;
1044 case estNH_VXI: ret = doVector<double>(xd, part, i, sflags, &state->nosehoover_vxi, list); break;
1045 case estNHPRES_XI: ret = doVector<double>(xd, part, i, sflags, &state->nhpres_xi, list); break;
1046 case estNHPRES_VXI: ret = doVector<double>(xd, part, i, sflags, &state->nhpres_vxi, list); break;
1047 case estTC_INT: ret = doVector<double>(xd, part, i, sflags, &state->therm_integral, list); break;
1048 case estVETA: ret = do_cpte_real(xd, part, i, sflags, &state->veta, list); break;
1049 case estVOL0: ret = do_cpte_real(xd, part, i, sflags, &state->vol0, list); break;
1050 case estX: ret = doPaddedRvecVector(xd, part, i, sflags, &state->x, list); break;
1051 case estV: ret = doPaddedRvecVector(xd, part, i, sflags, &state->v, list); break;
1052 /* The RNG entries are no longer written,
1053 * the next 4 lines are only for reading old files.
1055 case estLD_RNG_NOTSUPPORTED: ret = do_cpte_ints(xd, part, i, sflags, 0, nullptr, list); break;
1056 case estLD_RNGI_NOTSUPPORTED: ret = do_cpte_ints(xd, part, i, sflags, 0, nullptr, list); break;
1057 case estMC_RNG_NOTSUPPORTED: ret = do_cpte_ints(xd, part, i, sflags, 0, nullptr, list); break;
1058 case estMC_RNGI_NOTSUPPORTED: ret = do_cpte_ints(xd, part, i, sflags, 0, nullptr, list); break;
1059 case estDISRE_INITF: ret = do_cpte_real (xd, part, i, sflags, &state->hist.disre_initf, list); break;
1060 case estDISRE_RM3TAV: ret = do_cpte_n_reals(xd, part, i, sflags, &state->hist.ndisrepairs, &state->hist.disre_rm3tav, list); break;
1061 case estORIRE_INITF: ret = do_cpte_real (xd, part, i, sflags, &state->hist.orire_initf, list); break;
1062 case estORIRE_DTAV: ret = do_cpte_n_reals(xd, part, i, sflags, &state->hist.norire_Dtav, &state->hist.orire_Dtav, list); break;
1063 default:
1064 gmx_fatal(FARGS, "Unknown state entry %d\n"
1065 "You are reading a checkpoint file written by different code, which is not supported", i);
1070 return ret;
1073 static int do_cpt_ekinstate(XDR *xd, int fflags, ekinstate_t *ekins,
1074 FILE *list)
1076 int ret = 0;
1078 const StatePart part = StatePart::kineticEnergy;
1079 for (int i = 0; (i < eeksNR && ret == 0); i++)
1081 if (fflags & (1<<i))
1083 switch (i)
1086 case eeksEKIN_N: ret = do_cpte_int(xd, part, i, fflags, &ekins->ekin_n, list); break;
1087 case eeksEKINH: ret = do_cpte_matrices(xd, part, i, fflags, ekins->ekin_n, &ekins->ekinh, list); break;
1088 case eeksEKINF: ret = do_cpte_matrices(xd, part, i, fflags, ekins->ekin_n, &ekins->ekinf, list); break;
1089 case eeksEKINO: ret = do_cpte_matrices(xd, part, i, fflags, ekins->ekin_n, &ekins->ekinh_old, list); break;
1090 case eeksEKINTOTAL: ret = do_cpte_matrix(xd, part, i, fflags, ekins->ekin_total, list); break;
1091 case eeksEKINSCALEF: ret = doVector<double>(xd, part, i, fflags, &ekins->ekinscalef_nhc, list); break;
1092 case eeksVSCALE: ret = doVector<double>(xd, part, i, fflags, &ekins->vscale_nhc, list); break;
1093 case eeksEKINSCALEH: ret = doVector<double>(xd, part, i, fflags, &ekins->ekinscaleh_nhc, list); break;
1094 case eeksDEKINDL: ret = do_cpte_real(xd, part, i, fflags, &ekins->dekindl, list); break;
1095 case eeksMVCOS: ret = do_cpte_real(xd, part, i, fflags, &ekins->mvcos, list); break;
1096 default:
1097 gmx_fatal(FARGS, "Unknown ekin data state entry %d\n"
1098 "You are probably reading a new checkpoint file with old code", i);
1103 return ret;
1107 static int do_cpt_swapstate(XDR *xd, gmx_bool bRead,
1108 int eSwapCoords, swapstate_t **swapstatePtr, FILE *list)
1110 int swap_cpt_version = 2;
1112 if (eSwapCoords == eswapNO)
1114 return 0;
1117 if (*swapstatePtr == nullptr)
1119 snew(*swapstatePtr, 1);
1121 swapstate_t *swapstate = *swapstatePtr;
1122 swapstate->bFromCpt = bRead;
1123 swapstate->eSwapCoords = eSwapCoords;
1125 do_cpt_int_err(xd, "swap checkpoint version", &swap_cpt_version, list);
1126 if (bRead && swap_cpt_version < 2)
1128 gmx_fatal(FARGS, "Cannot read checkpoint files that were written with old versions"
1129 "of the ion/water position swapping protocol.\n");
1132 do_cpt_int_err(xd, "swap coupling steps", &swapstate->nAverage, list);
1134 /* When reading, init_swapcoords has not been called yet,
1135 * so we have to allocate memory first. */
1136 do_cpt_int_err(xd, "number of ion types", &swapstate->nIonTypes, list);
1137 if (bRead)
1139 snew(swapstate->ionType, swapstate->nIonTypes);
1142 for (int ic = 0; ic < eCompNR; ic++)
1144 for (int ii = 0; ii < swapstate->nIonTypes; ii++)
1146 swapstateIons_t *gs = &swapstate->ionType[ii];
1148 if (bRead)
1150 do_cpt_int_err(xd, "swap requested atoms", &gs->nMolReq[ic], list);
1152 else
1154 do_cpt_int_err(xd, "swap requested atoms p", gs->nMolReq_p[ic], list);
1157 if (bRead)
1159 do_cpt_int_err(xd, "swap influx net", &gs->inflow_net[ic], list);
1161 else
1163 do_cpt_int_err(xd, "swap influx net p", gs->inflow_net_p[ic], list);
1166 if (bRead && (nullptr == gs->nMolPast[ic]) )
1168 snew(gs->nMolPast[ic], swapstate->nAverage);
1171 for (int j = 0; j < swapstate->nAverage; j++)
1173 if (bRead)
1175 do_cpt_int_err(xd, "swap past atom counts", &gs->nMolPast[ic][j], list);
1177 else
1179 do_cpt_int_err(xd, "swap past atom counts p", &gs->nMolPast_p[ic][j], list);
1185 /* Ion flux per channel */
1186 for (int ic = 0; ic < eChanNR; ic++)
1188 for (int ii = 0; ii < swapstate->nIonTypes; ii++)
1190 swapstateIons_t *gs = &swapstate->ionType[ii];
1192 if (bRead)
1194 do_cpt_int_err(xd, "channel flux A->B", &gs->fluxfromAtoB[ic], list);
1196 else
1198 do_cpt_int_err(xd, "channel flux A->B p", gs->fluxfromAtoB_p[ic], list);
1203 /* Ion flux leakage */
1204 if (bRead)
1206 do_cpt_int_err(xd, "flux leakage", &swapstate->fluxleak, list);
1208 else
1210 do_cpt_int_err(xd, "flux leakage", swapstate->fluxleak_p, list);
1213 /* Ion history */
1214 for (int ii = 0; ii < swapstate->nIonTypes; ii++)
1216 swapstateIons_t *gs = &swapstate->ionType[ii];
1218 do_cpt_int_err(xd, "number of ions", &gs->nMol, list);
1220 if (bRead)
1222 snew(gs->channel_label, gs->nMol);
1223 snew(gs->comp_from, gs->nMol);
1226 do_cpt_u_chars(xd, "channel history", gs->nMol, gs->channel_label, list);
1227 do_cpt_u_chars(xd, "domain history", gs->nMol, gs->comp_from, list);
1230 /* Save the last known whole positions to checkpoint
1231 * file to be able to also make multimeric channels whole in PBC */
1232 do_cpt_int_err(xd, "Ch0 atoms", &swapstate->nat[eChan0], list);
1233 do_cpt_int_err(xd, "Ch1 atoms", &swapstate->nat[eChan1], list);
1234 if (bRead)
1236 snew(swapstate->xc_old_whole[eChan0], swapstate->nat[eChan0]);
1237 snew(swapstate->xc_old_whole[eChan1], swapstate->nat[eChan1]);
1238 do_cpt_n_rvecs_err(xd, "Ch0 whole x", swapstate->nat[eChan0], swapstate->xc_old_whole[eChan0], list);
1239 do_cpt_n_rvecs_err(xd, "Ch1 whole x", swapstate->nat[eChan1], swapstate->xc_old_whole[eChan1], list);
1241 else
1243 do_cpt_n_rvecs_err(xd, "Ch0 whole x", swapstate->nat[eChan0], *swapstate->xc_old_whole_p[eChan0], list);
1244 do_cpt_n_rvecs_err(xd, "Ch1 whole x", swapstate->nat[eChan1], *swapstate->xc_old_whole_p[eChan1], list);
1247 return 0;
1251 static int do_cpt_enerhist(XDR *xd, gmx_bool bRead,
1252 int fflags, energyhistory_t *enerhist,
1253 FILE *list)
1255 int ret = 0;
1257 /* This is stored/read for backward compatibility */
1258 int energyHistoryNumEnergies = 0;
1259 if (bRead)
1261 enerhist->nsteps = 0;
1262 enerhist->nsum = 0;
1263 enerhist->nsteps_sim = 0;
1264 enerhist->nsum_sim = 0;
1266 else
1268 energyHistoryNumEnergies = enerhist->ener_sum_sim.size();
1271 delta_h_history_t *deltaH = enerhist->deltaHForeignLambdas.get();
1272 const StatePart part = StatePart::energyHistory;
1273 for (int i = 0; (i < eenhNR && ret == 0); i++)
1275 if (fflags & (1<<i))
1277 switch (i)
1279 case eenhENERGY_N: ret = do_cpte_int(xd, part, i, fflags, &energyHistoryNumEnergies, list); break;
1280 case eenhENERGY_AVER: ret = doVector<double>(xd, part, i, fflags, &enerhist->ener_ave, list); break;
1281 case eenhENERGY_SUM: ret = doVector<double>(xd, part, i, fflags, &enerhist->ener_sum, list); break;
1282 case eenhENERGY_NSUM: do_cpt_step_err(xd, eenh_names[i], &enerhist->nsum, list); break;
1283 case eenhENERGY_SUM_SIM: ret = doVector<double>(xd, part, i, fflags, &enerhist->ener_sum_sim, list); break;
1284 case eenhENERGY_NSUM_SIM: do_cpt_step_err(xd, eenh_names[i], &enerhist->nsum_sim, list); break;
1285 case eenhENERGY_NSTEPS: do_cpt_step_err(xd, eenh_names[i], &enerhist->nsteps, list); break;
1286 case eenhENERGY_NSTEPS_SIM: do_cpt_step_err(xd, eenh_names[i], &enerhist->nsteps_sim, list); break;
1287 case eenhENERGY_DELTA_H_NN:
1289 int numDeltaH = 0;
1290 if (!bRead && deltaH != nullptr)
1292 numDeltaH = deltaH->dh.size();
1294 do_cpt_int_err(xd, eenh_names[i], &numDeltaH, list);
1295 if (bRead)
1297 if (deltaH == nullptr)
1299 enerhist->deltaHForeignLambdas.reset(new delta_h_history_t);
1300 deltaH = enerhist->deltaHForeignLambdas.get();
1302 deltaH->dh.resize(numDeltaH);
1303 deltaH->start_lambda_set = FALSE;
1305 break;
1307 case eenhENERGY_DELTA_H_LIST:
1308 for (auto dh : deltaH->dh)
1310 ret = doVector<real>(xd, part, i, fflags, &dh, list);
1312 break;
1313 case eenhENERGY_DELTA_H_STARTTIME:
1314 ret = do_cpte_double(xd, part, i, fflags, &(deltaH->start_time), list); break;
1315 case eenhENERGY_DELTA_H_STARTLAMBDA:
1316 ret = do_cpte_double(xd, part, i, fflags, &(deltaH->start_lambda), list); break;
1317 default:
1318 gmx_fatal(FARGS, "Unknown energy history entry %d\n"
1319 "You are probably reading a new checkpoint file with old code", i);
1324 if ((fflags & (1<<eenhENERGY_SUM)) && !(fflags & (1<<eenhENERGY_SUM_SIM)))
1326 /* Assume we have an old file format and copy sum to sum_sim */
1327 enerhist->ener_sum_sim = enerhist->ener_sum;
1330 if ( (fflags & (1<<eenhENERGY_NSUM)) &&
1331 !(fflags & (1<<eenhENERGY_NSTEPS)))
1333 /* Assume we have an old file format and copy nsum to nsteps */
1334 enerhist->nsteps = enerhist->nsum;
1336 if ( (fflags & (1<<eenhENERGY_NSUM_SIM)) &&
1337 !(fflags & (1<<eenhENERGY_NSTEPS_SIM)))
1339 /* Assume we have an old file format and copy nsum to nsteps */
1340 enerhist->nsteps_sim = enerhist->nsum_sim;
1343 return ret;
1346 static int do_cpt_df_hist(XDR *xd, int fflags, int nlambda, df_history_t **dfhistPtr, FILE *list)
1348 int ret = 0;
1350 if (fflags == 0)
1352 return 0;
1355 if (*dfhistPtr == nullptr)
1357 snew(*dfhistPtr, 1);
1358 (*dfhistPtr)->nlambda = nlambda;
1359 init_df_history(*dfhistPtr, nlambda);
1361 df_history_t *dfhist = *dfhistPtr;
1363 const StatePart part = StatePart::freeEnergyHistory;
1364 for (int i = 0; (i < edfhNR && ret == 0); i++)
1366 if (fflags & (1<<i))
1368 switch (i)
1370 case edfhBEQUIL: ret = do_cpte_int(xd, part, i, fflags, &dfhist->bEquil, list); break;
1371 case edfhNATLAMBDA: ret = do_cpte_ints(xd, part, i, fflags, nlambda, &dfhist->n_at_lam, list); break;
1372 case edfhWLHISTO: ret = do_cpte_reals(xd, part, i, fflags, nlambda, &dfhist->wl_histo, list); break;
1373 case edfhWLDELTA: ret = do_cpte_real(xd, part, i, fflags, &dfhist->wl_delta, list); break;
1374 case edfhSUMWEIGHTS: ret = do_cpte_reals(xd, part, i, fflags, nlambda, &dfhist->sum_weights, list); break;
1375 case edfhSUMDG: ret = do_cpte_reals(xd, part, i, fflags, nlambda, &dfhist->sum_dg, list); break;
1376 case edfhSUMMINVAR: ret = do_cpte_reals(xd, part, i, fflags, nlambda, &dfhist->sum_minvar, list); break;
1377 case edfhSUMVAR: ret = do_cpte_reals(xd, part, i, fflags, nlambda, &dfhist->sum_variance, list); break;
1378 case edfhACCUMP: ret = do_cpte_nmatrix(xd, part, i, fflags, nlambda, dfhist->accum_p, list); break;
1379 case edfhACCUMM: ret = do_cpte_nmatrix(xd, part, i, fflags, nlambda, dfhist->accum_m, list); break;
1380 case edfhACCUMP2: ret = do_cpte_nmatrix(xd, part, i, fflags, nlambda, dfhist->accum_p2, list); break;
1381 case edfhACCUMM2: ret = do_cpte_nmatrix(xd, part, i, fflags, nlambda, dfhist->accum_m2, list); break;
1382 case edfhTIJ: ret = do_cpte_nmatrix(xd, part, i, fflags, nlambda, dfhist->Tij, list); break;
1383 case edfhTIJEMP: ret = do_cpte_nmatrix(xd, part, i, fflags, nlambda, dfhist->Tij_empirical, list); break;
1385 default:
1386 gmx_fatal(FARGS, "Unknown df history entry %d\n"
1387 "You are probably reading a new checkpoint file with old code", i);
1392 return ret;
1396 /* This function stores the last whole configuration of the reference and
1397 * average structure in the .cpt file
1399 static int do_cpt_EDstate(XDR *xd, gmx_bool bRead,
1400 int nED, edsamstate_t **EDstatePtr, FILE *list)
1402 if (nED == 0)
1404 return 0;
1407 if (*EDstatePtr == nullptr)
1409 snew(*EDstatePtr, 1);
1411 edsamstate_t *EDstate = *EDstatePtr;
1413 EDstate->bFromCpt = bRead;
1414 EDstate->nED = nED;
1416 /* When reading, init_edsam has not been called yet,
1417 * so we have to allocate memory first. */
1418 if (bRead)
1420 snew(EDstate->nref, EDstate->nED);
1421 snew(EDstate->old_sref, EDstate->nED);
1422 snew(EDstate->nav, EDstate->nED);
1423 snew(EDstate->old_sav, EDstate->nED);
1426 /* Read/write the last whole conformation of SREF and SAV for each ED dataset (usually only one) */
1427 for (int i = 0; i < EDstate->nED; i++)
1429 char buf[STRLEN];
1431 /* Reference structure SREF */
1432 sprintf(buf, "ED%d # of atoms in reference structure", i+1);
1433 do_cpt_int_err(xd, buf, &EDstate->nref[i], list);
1434 sprintf(buf, "ED%d x_ref", i+1);
1435 if (bRead)
1437 snew(EDstate->old_sref[i], EDstate->nref[i]);
1438 do_cpt_n_rvecs_err(xd, buf, EDstate->nref[i], EDstate->old_sref[i], list);
1440 else
1442 do_cpt_n_rvecs_err(xd, buf, EDstate->nref[i], EDstate->old_sref_p[i], list);
1445 /* Average structure SAV */
1446 sprintf(buf, "ED%d # of atoms in average structure", i+1);
1447 do_cpt_int_err(xd, buf, &EDstate->nav[i], list);
1448 sprintf(buf, "ED%d x_av", i+1);
1449 if (bRead)
1451 snew(EDstate->old_sav[i], EDstate->nav[i]);
1452 do_cpt_n_rvecs_err(xd, buf, EDstate->nav[i], EDstate->old_sav[i], list);
1454 else
1456 do_cpt_n_rvecs_err(xd, buf, EDstate->nav[i], EDstate->old_sav_p[i], list);
1460 return 0;
1464 static int do_cpt_files(XDR *xd, gmx_bool bRead,
1465 gmx_file_position_t **p_outputfiles, int *nfiles,
1466 FILE *list, int file_version)
1468 int i;
1469 gmx_off_t offset;
1470 gmx_off_t mask = 0xFFFFFFFFL;
1471 int offset_high, offset_low;
1472 char *buf;
1473 gmx_file_position_t *outputfiles;
1475 if (do_cpt_int(xd, "number of output files", nfiles, list) != 0)
1477 return -1;
1480 if (bRead)
1482 snew(*p_outputfiles, *nfiles);
1485 outputfiles = *p_outputfiles;
1487 for (i = 0; i < *nfiles; i++)
1489 /* 64-bit XDR numbers are not portable, so it is stored as separate high/low fractions */
1490 if (bRead)
1492 do_cpt_string_err(xd, bRead, "output filename", &buf, list);
1493 std::strncpy(outputfiles[i].filename, buf, CPTSTRLEN-1);
1494 if (list == nullptr)
1496 sfree(buf);
1499 if (do_cpt_int(xd, "file_offset_high", &offset_high, list) != 0)
1501 return -1;
1503 if (do_cpt_int(xd, "file_offset_low", &offset_low, list) != 0)
1505 return -1;
1507 outputfiles[i].offset = (static_cast<gmx_off_t>(offset_high) << 32 ) | ( static_cast<gmx_off_t>(offset_low) & mask );
1509 else
1511 buf = outputfiles[i].filename;
1512 do_cpt_string_err(xd, bRead, "output filename", &buf, list);
1513 /* writing */
1514 offset = outputfiles[i].offset;
1515 if (offset == -1)
1517 offset_low = -1;
1518 offset_high = -1;
1520 else
1522 offset_low = static_cast<int>(offset & mask);
1523 offset_high = static_cast<int>((offset >> 32) & mask);
1525 if (do_cpt_int(xd, "file_offset_high", &offset_high, list) != 0)
1527 return -1;
1529 if (do_cpt_int(xd, "file_offset_low", &offset_low, list) != 0)
1531 return -1;
1534 if (file_version >= 8)
1536 if (do_cpt_int(xd, "file_checksum_size", &(outputfiles[i].chksum_size),
1537 list) != 0)
1539 return -1;
1541 if (do_cpt_u_chars(xd, "file_checksum", 16, outputfiles[i].chksum, list) != 0)
1543 return -1;
1546 else
1548 outputfiles[i].chksum_size = -1;
1551 return 0;
1555 void write_checkpoint(const char *fn, gmx_bool bNumberAndKeep,
1556 FILE *fplog, t_commrec *cr,
1557 ivec domdecCells, int nppnodes,
1558 int eIntegrator, int simulation_part,
1559 gmx_bool bExpanded, int elamstats,
1560 gmx_int64_t step, double t,
1561 t_state *state, energyhistory_t *enerhist)
1563 t_fileio *fp;
1564 int file_version;
1565 char *version;
1566 char *btime;
1567 char *buser;
1568 char *bhost;
1569 int double_prec;
1570 char *fprog;
1571 char *fntemp; /* the temporary checkpoint file name */
1572 char timebuf[STRLEN];
1573 int npmenodes;
1574 char buf[1024], suffix[5+STEPSTRSIZE], sbuf[STEPSTRSIZE];
1575 gmx_file_position_t *outputfiles;
1576 int noutputfiles;
1577 char *ftime;
1578 int flags_eks, flags_enh, flags_dfh;
1579 t_fileio *ret;
1581 if (DOMAINDECOMP(cr))
1583 npmenodes = cr->npmenodes;
1585 else
1587 npmenodes = 0;
1590 #if !GMX_NO_RENAME
1591 /* make the new temporary filename */
1592 snew(fntemp, std::strlen(fn)+5+STEPSTRSIZE);
1593 std::strcpy(fntemp, fn);
1594 fntemp[std::strlen(fn) - std::strlen(ftp2ext(fn2ftp(fn))) - 1] = '\0';
1595 sprintf(suffix, "_%s%s", "step", gmx_step_str(step, sbuf));
1596 std::strcat(fntemp, suffix);
1597 std::strcat(fntemp, fn+std::strlen(fn) - std::strlen(ftp2ext(fn2ftp(fn))) - 1);
1598 #else
1599 /* if we can't rename, we just overwrite the cpt file.
1600 * dangerous if interrupted.
1602 snew(fntemp, std::strlen(fn));
1603 std::strcpy(fntemp, fn);
1604 #endif
1605 gmx_format_current_time(timebuf, STRLEN);
1607 if (fplog)
1609 fprintf(fplog, "Writing checkpoint, step %s at %s\n\n",
1610 gmx_step_str(step, buf), timebuf);
1613 /* Get offsets for open files */
1614 gmx_fio_get_output_file_positions(&outputfiles, &noutputfiles);
1616 fp = gmx_fio_open(fntemp, "w");
1618 if (state->ekinstate.bUpToDate)
1620 flags_eks =
1621 ((1<<eeksEKIN_N) | (1<<eeksEKINH) | (1<<eeksEKINF) |
1622 (1<<eeksEKINO) | (1<<eeksEKINSCALEF) | (1<<eeksEKINSCALEH) |
1623 (1<<eeksVSCALE) | (1<<eeksDEKINDL) | (1<<eeksMVCOS));
1625 else
1627 flags_eks = 0;
1630 flags_enh = 0;
1631 if (enerhist->nsum > 0 || enerhist->nsum_sim > 0)
1633 flags_enh |= (1<<eenhENERGY_N) | (1<<eenhENERGY_NSTEPS) | (1<<eenhENERGY_NSTEPS_SIM);
1634 if (enerhist->nsum > 0)
1636 flags_enh |= ((1<<eenhENERGY_AVER) | (1<<eenhENERGY_SUM) |
1637 (1<<eenhENERGY_NSUM));
1639 if (enerhist->nsum_sim > 0)
1641 flags_enh |= ((1<<eenhENERGY_SUM_SIM) | (1<<eenhENERGY_NSUM_SIM));
1643 if (enerhist->deltaHForeignLambdas != nullptr)
1645 flags_enh |= ( (1<< eenhENERGY_DELTA_H_NN) |
1646 (1<< eenhENERGY_DELTA_H_LIST) |
1647 (1<< eenhENERGY_DELTA_H_STARTTIME) |
1648 (1<< eenhENERGY_DELTA_H_STARTLAMBDA) );
1652 if (bExpanded)
1654 flags_dfh = ((1<<edfhBEQUIL) | (1<<edfhNATLAMBDA) | (1<<edfhSUMWEIGHTS) | (1<<edfhSUMDG) |
1655 (1<<edfhTIJ) | (1<<edfhTIJEMP));
1656 if (EWL(elamstats))
1658 flags_dfh |= ((1<<edfhWLDELTA) | (1<<edfhWLHISTO));
1660 if ((elamstats == elamstatsMINVAR) || (elamstats == elamstatsBARKER) || (elamstats == elamstatsMETROPOLIS))
1662 flags_dfh |= ((1<<edfhACCUMP) | (1<<edfhACCUMM) | (1<<edfhACCUMP2) | (1<<edfhACCUMM2)
1663 | (1<<edfhSUMMINVAR) | (1<<edfhSUMVAR));
1666 else
1668 flags_dfh = 0;
1671 /* We can check many more things now (CPU, acceleration, etc), but
1672 * it is highly unlikely to have two separate builds with exactly
1673 * the same version, user, time, and build host!
1676 version = gmx_strdup(gmx_version());
1677 btime = gmx_strdup(BUILD_TIME);
1678 buser = gmx_strdup(BUILD_USER);
1679 bhost = gmx_strdup(BUILD_HOST);
1681 double_prec = GMX_DOUBLE;
1682 fprog = gmx_strdup(gmx::getProgramContext().fullBinaryPath());
1684 ftime = &(timebuf[0]);
1686 int nlambda = (state->dfhist ? state->dfhist->nlambda : 0);
1687 int nED = (state->edsamstate ? state->edsamstate->nED : 0);
1688 int eSwapCoords = (state->swapstate ? state->swapstate->eSwapCoords : eswapNO);
1690 do_cpt_header(gmx_fio_getxdr(fp), FALSE, &file_version,
1691 &version, &btime, &buser, &bhost, &double_prec, &fprog, &ftime,
1692 &eIntegrator, &simulation_part, &step, &t, &nppnodes,
1693 DOMAINDECOMP(cr) ? domdecCells : nullptr, &npmenodes,
1694 &state->natoms, &state->ngtc, &state->nnhpres,
1695 &state->nhchainlength, &nlambda, &state->flags, &flags_eks, &flags_enh, &flags_dfh,
1696 &nED, &eSwapCoords,
1697 nullptr);
1699 sfree(version);
1700 sfree(btime);
1701 sfree(buser);
1702 sfree(bhost);
1703 sfree(fprog);
1705 if ((do_cpt_state(gmx_fio_getxdr(fp), state->flags, state, nullptr) < 0) ||
1706 (do_cpt_ekinstate(gmx_fio_getxdr(fp), flags_eks, &state->ekinstate, nullptr) < 0) ||
1707 (do_cpt_enerhist(gmx_fio_getxdr(fp), FALSE, flags_enh, enerhist, nullptr) < 0) ||
1708 (do_cpt_df_hist(gmx_fio_getxdr(fp), flags_dfh, nlambda, &state->dfhist, nullptr) < 0) ||
1709 (do_cpt_EDstate(gmx_fio_getxdr(fp), FALSE, nED, &state->edsamstate, nullptr) < 0) ||
1710 (do_cpt_swapstate(gmx_fio_getxdr(fp), FALSE, eSwapCoords, &state->swapstate, nullptr) < 0) ||
1711 (do_cpt_files(gmx_fio_getxdr(fp), FALSE, &outputfiles, &noutputfiles, nullptr,
1712 file_version) < 0))
1714 gmx_file("Cannot read/write checkpoint; corrupt file, or maybe you are out of disk space?");
1717 do_cpt_footer(gmx_fio_getxdr(fp), file_version);
1719 /* we really, REALLY, want to make sure to physically write the checkpoint,
1720 and all the files it depends on, out to disk. Because we've
1721 opened the checkpoint with gmx_fio_open(), it's in our list
1722 of open files. */
1723 ret = gmx_fio_all_output_fsync();
1725 if (ret)
1727 char buf[STRLEN];
1728 sprintf(buf,
1729 "Cannot fsync '%s'; maybe you are out of disk space?",
1730 gmx_fio_getname(ret));
1732 if (getenv(GMX_IGNORE_FSYNC_FAILURE_ENV) == nullptr)
1734 gmx_file(buf);
1736 else
1738 gmx_warning(buf);
1742 if (gmx_fio_close(fp) != 0)
1744 gmx_file("Cannot read/write checkpoint; corrupt file, or maybe you are out of disk space?");
1747 /* we don't move the checkpoint if the user specified they didn't want it,
1748 or if the fsyncs failed */
1749 #if !GMX_NO_RENAME
1750 if (!bNumberAndKeep && !ret)
1752 if (gmx_fexist(fn))
1754 /* Rename the previous checkpoint file */
1755 std::strcpy(buf, fn);
1756 buf[std::strlen(fn) - std::strlen(ftp2ext(fn2ftp(fn))) - 1] = '\0';
1757 std::strcat(buf, "_prev");
1758 std::strcat(buf, fn+std::strlen(fn) - std::strlen(ftp2ext(fn2ftp(fn))) - 1);
1759 #ifndef GMX_FAHCORE
1760 /* we copy here so that if something goes wrong between now and
1761 * the rename below, there's always a state.cpt.
1762 * If renames are atomic (such as in POSIX systems),
1763 * this copying should be unneccesary.
1765 gmx_file_copy(fn, buf, FALSE);
1766 /* We don't really care if this fails:
1767 * there's already a new checkpoint.
1769 #else
1770 gmx_file_rename(fn, buf);
1771 #endif
1773 if (gmx_file_rename(fntemp, fn) != 0)
1775 gmx_file("Cannot rename checkpoint file; maybe you are out of disk space?");
1778 #endif /* GMX_NO_RENAME */
1780 sfree(outputfiles);
1781 sfree(fntemp);
1783 #ifdef GMX_FAHCORE
1784 /*code for alternate checkpointing scheme. moved from top of loop over
1785 steps */
1786 fcRequestCheckPoint();
1787 if (fcCheckPointParallel( cr->nodeid, NULL, 0) == 0)
1789 gmx_fatal( 3, __FILE__, __LINE__, "Checkpoint error on step %d\n", step );
1791 #endif /* end GMX_FAHCORE block */
1794 static void print_flag_mismatch(FILE *fplog, int sflags, int fflags)
1796 int i;
1798 fprintf(fplog, "\nState entry mismatch between the simulation and the checkpoint file\n");
1799 fprintf(fplog, "Entries which are not present in the checkpoint file will not be updated\n");
1800 fprintf(fplog, " %24s %11s %11s\n", "", "simulation", "checkpoint");
1801 for (i = 0; i < estNR; i++)
1803 if ((sflags & (1<<i)) || (fflags & (1<<i)))
1805 fprintf(fplog, " %24s %11s %11s\n",
1806 est_names[i],
1807 (sflags & (1<<i)) ? " present " : "not present",
1808 (fflags & (1<<i)) ? " present " : "not present");
1813 static void check_int(FILE *fplog, const char *type, int p, int f, gmx_bool *mm)
1815 FILE *fp = fplog ? fplog : stderr;
1817 if (p != f)
1819 fprintf(fp, " %s mismatch,\n", type);
1820 fprintf(fp, " current program: %d\n", p);
1821 fprintf(fp, " checkpoint file: %d\n", f);
1822 fprintf(fp, "\n");
1823 *mm = TRUE;
1827 static void check_string(FILE *fplog, const char *type, const char *p,
1828 const char *f, gmx_bool *mm)
1830 FILE *fp = fplog ? fplog : stderr;
1832 if (std::strcmp(p, f) != 0)
1834 fprintf(fp, " %s mismatch,\n", type);
1835 fprintf(fp, " current program: %s\n", p);
1836 fprintf(fp, " checkpoint file: %s\n", f);
1837 fprintf(fp, "\n");
1838 *mm = TRUE;
1842 static void check_match(FILE *fplog,
1843 char *version,
1844 char *btime, char *buser, char *bhost, int double_prec,
1845 char *fprog,
1846 const t_commrec *cr, int npp_f, int npme_f,
1847 ivec dd_nc, ivec dd_nc_f,
1848 gmx_bool reproducibilityRequested)
1850 /* Note that this check_string on the version will also print a message
1851 * when only the minor version differs. But we only print a warning
1852 * message further down with reproducibilityRequested=TRUE.
1854 gmx_bool versionDiffers = FALSE;
1855 check_string(fplog, "Version", gmx_version(), version, &versionDiffers);
1857 gmx_bool precisionDiffers = FALSE;
1858 check_int (fplog, "Double prec.", GMX_DOUBLE, double_prec, &precisionDiffers);
1859 if (precisionDiffers)
1861 const char msg_precision_difference[] =
1862 "You are continuing a simulation with a different precision. Not matching\n"
1863 "single/double precision will lead to precision or performance loss.\n";
1864 fprintf(stderr, "%s\n", msg_precision_difference);
1865 if (fplog)
1867 fprintf(fplog, "%s\n", msg_precision_difference);
1871 gmx_bool mm = (versionDiffers || precisionDiffers);
1873 if (reproducibilityRequested)
1875 check_string(fplog, "Build time", BUILD_TIME, btime, &mm);
1876 check_string(fplog, "Build user", BUILD_USER, buser, &mm);
1877 check_string(fplog, "Build host", BUILD_HOST, bhost, &mm);
1878 check_string(fplog, "Program name", gmx::getProgramContext().fullBinaryPath(), fprog, &mm);
1880 check_int (fplog, "#ranks", cr->nnodes, npp_f+npme_f, &mm);
1883 if (cr->nnodes > 1 && reproducibilityRequested)
1885 check_int (fplog, "#PME-ranks", cr->npmenodes, npme_f, &mm);
1887 int npp = cr->nnodes;
1888 if (cr->npmenodes >= 0)
1890 npp -= cr->npmenodes;
1892 if (npp == npp_f)
1894 check_int (fplog, "#DD-cells[x]", dd_nc[XX], dd_nc_f[XX], &mm);
1895 check_int (fplog, "#DD-cells[y]", dd_nc[YY], dd_nc_f[YY], &mm);
1896 check_int (fplog, "#DD-cells[z]", dd_nc[ZZ], dd_nc_f[ZZ], &mm);
1900 if (mm)
1902 /* Gromacs should be able to continue from checkpoints between
1903 * different patch level versions, but we do not guarantee
1904 * compatibility between different major/minor versions - check this.
1906 int gmx_major;
1907 int cpt_major;
1908 sscanf(gmx_version(), "%5d", &gmx_major);
1909 int ret = sscanf(version, "%5d", &cpt_major);
1910 gmx_bool majorVersionDiffers = (ret < 1 || gmx_major != cpt_major);
1912 const char msg_major_version_difference[] =
1913 "The current GROMACS major version is not identical to the one that\n"
1914 "generated the checkpoint file. In principle GROMACS does not support\n"
1915 "continuation from checkpoints between different versions, so we advise\n"
1916 "against this. If you still want to try your luck we recommend that you use\n"
1917 "the -noappend flag to keep your output files from the two versions separate.\n"
1918 "This might also work around errors where the output fields in the energy\n"
1919 "file have changed between the different versions.\n";
1921 const char msg_mismatch_notice[] =
1922 "GROMACS patchlevel, binary or parallel settings differ from previous run.\n"
1923 "Continuation is exact, but not guaranteed to be binary identical.\n";
1925 const char msg_logdetails[] =
1926 "See the log file for details.\n";
1928 if (majorVersionDiffers)
1930 fprintf(stderr, "%s%s\n", msg_major_version_difference, fplog ? msg_logdetails : "");
1932 if (fplog)
1934 fprintf(fplog, "%s\n", msg_major_version_difference);
1937 else if (reproducibilityRequested)
1939 /* Major & minor versions match at least, but something is different. */
1940 fprintf(stderr, "%s%s\n", msg_mismatch_notice, fplog ? msg_logdetails : "");
1941 if (fplog)
1943 fprintf(fplog, "%s\n", msg_mismatch_notice);
1949 static void read_checkpoint(const char *fn, FILE **pfplog,
1950 const t_commrec *cr,
1951 ivec dd_nc, int *npme,
1952 int eIntegrator, int *init_fep_state, gmx_int64_t *step, double *t,
1953 t_state *state, gmx_bool *bReadEkin,
1954 energyhistory_t *enerhist,
1955 int *simulation_part,
1956 gmx_bool bAppendOutputFiles, gmx_bool bForceAppend,
1957 gmx_bool reproducibilityRequested)
1959 t_fileio *fp;
1960 int i, j, rc;
1961 int file_version;
1962 char *version, *btime, *buser, *bhost, *fprog, *ftime;
1963 int double_prec;
1964 char buf[STEPSTRSIZE];
1965 int eIntegrator_f, nppnodes_f, npmenodes_f;
1966 ivec dd_nc_f;
1967 int natoms, ngtc, nnhpres, nhchainlength, nlambda, fflags, flags_eks, flags_enh, flags_dfh;
1968 int nED, eSwapCoords;
1969 int d;
1970 int ret;
1971 gmx_file_position_t *outputfiles;
1972 int nfiles;
1973 t_fileio *chksum_file;
1974 FILE * fplog = *pfplog;
1975 unsigned char digest[16];
1976 #if !defined __native_client__ && !GMX_NATIVE_WINDOWS
1977 struct flock fl; /* don't initialize here: the struct order is OS
1978 dependent! */
1979 #endif
1981 const char *int_warn =
1982 "WARNING: The checkpoint file was generated with integrator %s,\n"
1983 " while the simulation uses integrator %s\n\n";
1985 #if !defined __native_client__ && !GMX_NATIVE_WINDOWS
1986 fl.l_type = F_WRLCK;
1987 fl.l_whence = SEEK_SET;
1988 fl.l_start = 0;
1989 fl.l_len = 0;
1990 fl.l_pid = 0;
1991 #endif
1993 fp = gmx_fio_open(fn, "r");
1994 do_cpt_header(gmx_fio_getxdr(fp), TRUE, &file_version,
1995 &version, &btime, &buser, &bhost, &double_prec, &fprog, &ftime,
1996 &eIntegrator_f, simulation_part, step, t,
1997 &nppnodes_f, dd_nc_f, &npmenodes_f,
1998 &natoms, &ngtc, &nnhpres, &nhchainlength, &nlambda,
1999 &fflags, &flags_eks, &flags_enh, &flags_dfh,
2000 &nED, &eSwapCoords, nullptr);
2002 if (bAppendOutputFiles &&
2003 file_version >= 13 && double_prec != GMX_DOUBLE)
2005 gmx_fatal(FARGS, "Output file appending requested, but the code and checkpoint file precision (single/double) don't match");
2008 if (cr == nullptr || MASTER(cr))
2010 fprintf(stderr, "\nReading checkpoint file %s generated: %s\n\n",
2011 fn, ftime);
2014 /* This will not be written if we do appending, since fplog is still NULL then */
2015 if (fplog)
2017 fprintf(fplog, "\n");
2018 fprintf(fplog, "Reading checkpoint file %s\n", fn);
2019 fprintf(fplog, " file generated by: %s\n", fprog);
2020 fprintf(fplog, " file generated at: %s\n", ftime);
2021 fprintf(fplog, " GROMACS build time: %s\n", btime);
2022 fprintf(fplog, " GROMACS build user: %s\n", buser);
2023 fprintf(fplog, " GROMACS build host: %s\n", bhost);
2024 fprintf(fplog, " GROMACS double prec.: %d\n", double_prec);
2025 fprintf(fplog, " simulation part #: %d\n", *simulation_part);
2026 fprintf(fplog, " step: %s\n", gmx_step_str(*step, buf));
2027 fprintf(fplog, " time: %f\n", *t);
2028 fprintf(fplog, "\n");
2031 if (natoms != state->natoms)
2033 gmx_fatal(FARGS, "Checkpoint file is for a system of %d atoms, while the current system consists of %d atoms", natoms, state->natoms);
2035 if (ngtc != state->ngtc)
2037 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);
2039 if (nnhpres != state->nnhpres)
2041 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);
2044 int nlambdaHistory = (state->dfhist ? state->dfhist->nlambda : 0);
2045 if (nlambda != nlambdaHistory)
2047 gmx_fatal(FARGS, "Checkpoint file is for a system with %d lambda states, while the current system consists of %d lambda states", nlambda, nlambdaHistory);
2050 init_gtc_state(state, state->ngtc, state->nnhpres, nhchainlength); /* need to keep this here to keep the tpr format working */
2051 /* write over whatever was read; we use the number of Nose-Hoover chains from the checkpoint */
2053 if (eIntegrator_f != eIntegrator)
2055 if (MASTER(cr))
2057 fprintf(stderr, int_warn, EI(eIntegrator_f), EI(eIntegrator));
2059 if (bAppendOutputFiles)
2061 gmx_fatal(FARGS,
2062 "Output file appending requested, but input/checkpoint integrators do not match.\n"
2063 "Stopping the run to prevent you from ruining all your data...\n"
2064 "If you _really_ know what you are doing, try with the -noappend option.\n");
2066 if (fplog)
2068 fprintf(fplog, int_warn, EI(eIntegrator_f), EI(eIntegrator));
2072 if (!PAR(cr))
2074 *npme = 0;
2076 else if (cr->nnodes == nppnodes_f + npmenodes_f)
2078 if (*npme < 0)
2080 *npme = npmenodes_f;
2082 int nppnodes = cr->nnodes - *npme;
2083 if (nppnodes == nppnodes_f)
2085 for (d = 0; d < DIM; d++)
2087 if (dd_nc[d] == 0)
2089 dd_nc[d] = dd_nc_f[d];
2095 if (fflags != state->flags)
2098 if (MASTER(cr))
2100 if (bAppendOutputFiles)
2102 gmx_fatal(FARGS,
2103 "Output file appending requested, but input and checkpoint states are not identical.\n"
2104 "Stopping the run to prevent you from ruining all your data...\n"
2105 "You can try with the -noappend option, and get more info in the log file.\n");
2108 if (getenv("GMX_ALLOW_CPT_MISMATCH") == nullptr)
2110 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 else
2114 fprintf(stderr,
2115 "WARNING: The checkpoint state entries do not match the simulation,\n"
2116 " see the log file for details\n\n");
2120 if (fplog)
2122 print_flag_mismatch(fplog, state->flags, fflags);
2125 else
2127 if (MASTER(cr))
2129 check_match(fplog, version, btime, buser, bhost, double_prec, fprog,
2130 cr, nppnodes_f, npmenodes_f, dd_nc, dd_nc_f,
2131 reproducibilityRequested);
2134 ret = do_cpt_state(gmx_fio_getxdr(fp), fflags, state, nullptr);
2135 *init_fep_state = state->fep_state; /* there should be a better way to do this than setting it here.
2136 Investigate for 5.0. */
2137 if (ret)
2139 cp_error();
2141 ret = do_cpt_ekinstate(gmx_fio_getxdr(fp), flags_eks, &state->ekinstate, nullptr);
2142 if (ret)
2144 cp_error();
2146 *bReadEkin = ((flags_eks & (1<<eeksEKINH)) || (flags_eks & (1<<eeksEKINF)) || (flags_eks & (1<<eeksEKINO)) ||
2147 ((flags_eks & (1<<eeksEKINSCALEF)) | (flags_eks & (1<<eeksEKINSCALEH)) | (flags_eks & (1<<eeksVSCALE))));
2149 ret = do_cpt_enerhist(gmx_fio_getxdr(fp), TRUE,
2150 flags_enh, enerhist, nullptr);
2151 if (ret)
2153 cp_error();
2156 if (file_version < 6)
2158 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.";
2160 fprintf(stderr, "\nWARNING: %s\n\n", warn);
2161 if (fplog)
2163 fprintf(fplog, "\nWARNING: %s\n\n", warn);
2165 enerhist->nsum = *step;
2166 enerhist->nsum_sim = *step;
2169 ret = do_cpt_df_hist(gmx_fio_getxdr(fp), flags_dfh, nlambda, &state->dfhist, nullptr);
2170 if (ret)
2172 cp_error();
2175 ret = do_cpt_EDstate(gmx_fio_getxdr(fp), TRUE, nED, &state->edsamstate, nullptr);
2176 if (ret)
2178 cp_error();
2181 ret = do_cpt_swapstate(gmx_fio_getxdr(fp), TRUE, eSwapCoords, &state->swapstate, nullptr);
2182 if (ret)
2184 cp_error();
2187 ret = do_cpt_files(gmx_fio_getxdr(fp), TRUE, &outputfiles, &nfiles, nullptr, file_version);
2188 if (ret)
2190 cp_error();
2193 ret = do_cpt_footer(gmx_fio_getxdr(fp), file_version);
2194 if (ret)
2196 cp_error();
2198 if (gmx_fio_close(fp) != 0)
2200 gmx_file("Cannot read/write checkpoint; corrupt file, or maybe you are out of disk space?");
2203 sfree(fprog);
2204 sfree(ftime);
2205 sfree(btime);
2206 sfree(buser);
2207 sfree(bhost);
2209 /* If the user wants to append to output files,
2210 * we use the file pointer positions of the output files stored
2211 * in the checkpoint file and truncate the files such that any frames
2212 * written after the checkpoint time are removed.
2213 * All files are md5sum checked such that we can be sure that
2214 * we do not truncate other (maybe imprortant) files.
2216 if (bAppendOutputFiles)
2218 if (fn2ftp(outputfiles[0].filename) != efLOG)
2220 /* make sure first file is log file so that it is OK to use it for
2221 * locking
2223 gmx_fatal(FARGS, "The first output file should always be the log "
2224 "file but instead is: %s. Cannot do appending because of this condition.", outputfiles[0].filename);
2226 for (i = 0; i < nfiles; i++)
2228 if (outputfiles[i].offset < 0)
2230 gmx_fatal(FARGS, "The original run wrote a file called '%s' which "
2231 "is larger than 2 GB, but mdrun did not support large file"
2232 " offsets. Can not append. Run mdrun with -noappend",
2233 outputfiles[i].filename);
2235 #ifdef GMX_FAHCORE
2236 chksum_file = gmx_fio_open(outputfiles[i].filename, "a");
2238 #else
2239 chksum_file = gmx_fio_open(outputfiles[i].filename, "r+");
2241 /* lock log file */
2242 if (i == 0)
2244 /* Note that there are systems where the lock operation
2245 * will succeed, but a second process can also lock the file.
2246 * We should probably try to detect this.
2248 #if defined __native_client__
2249 errno = ENOSYS;
2250 if (1)
2252 #elif GMX_NATIVE_WINDOWS
2253 if (_locking(fileno(gmx_fio_getfp(chksum_file)), _LK_NBLCK, LONG_MAX) == -1)
2254 #else
2255 if (fcntl(fileno(gmx_fio_getfp(chksum_file)), F_SETLK, &fl) == -1)
2256 #endif
2258 if (errno == ENOSYS)
2260 if (!bForceAppend)
2262 gmx_fatal(FARGS, "File locking is not supported on this system. Use -noappend or specify -append explicitly to append anyhow.");
2264 else
2266 fprintf(stderr, "\nNOTE: File locking is not supported on this system, will not lock %s\n\n", outputfiles[i].filename);
2267 if (fplog)
2269 fprintf(fplog, "\nNOTE: File locking not supported on this system, will not lock %s\n\n", outputfiles[i].filename);
2273 else if (errno == EACCES || errno == EAGAIN)
2275 gmx_fatal(FARGS, "Failed to lock: %s. Already running "
2276 "simulation?", outputfiles[i].filename);
2278 else
2280 gmx_fatal(FARGS, "Failed to lock: %s. %s.",
2281 outputfiles[i].filename, std::strerror(errno));
2286 /* compute md5 chksum */
2287 if (outputfiles[i].chksum_size != -1)
2289 if (gmx_fio_get_file_md5(chksum_file, outputfiles[i].offset,
2290 digest) != outputfiles[i].chksum_size) /*at the end of the call the file position is at the end of the file*/
2292 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.",
2293 outputfiles[i].chksum_size,
2294 outputfiles[i].filename);
2297 if (i == 0) /*log file needs to be seeked in case we need to truncate (other files are truncated below)*/
2299 if (gmx_fio_seek(chksum_file, outputfiles[i].offset))
2301 gmx_fatal(FARGS, "Seek error! Failed to truncate log-file: %s.", std::strerror(errno));
2304 #endif
2306 if (i == 0) /*open log file here - so that lock is never lifted
2307 after chksum is calculated */
2309 *pfplog = gmx_fio_getfp(chksum_file);
2311 else
2313 gmx_fio_close(chksum_file);
2315 #ifndef GMX_FAHCORE
2316 /* compare md5 chksum */
2317 if (outputfiles[i].chksum_size != -1 &&
2318 memcmp(digest, outputfiles[i].chksum, 16) != 0)
2320 if (debug)
2322 fprintf(debug, "chksum for %s: ", outputfiles[i].filename);
2323 for (j = 0; j < 16; j++)
2325 fprintf(debug, "%02x", digest[j]);
2327 fprintf(debug, "\n");
2329 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.",
2330 outputfiles[i].filename);
2332 #endif
2335 if (i != 0) /*log file is already seeked to correct position */
2337 #if !GMX_NATIVE_WINDOWS || !defined(GMX_FAHCORE)
2338 /* For FAHCORE, we do this elsewhere*/
2339 rc = gmx_truncate(outputfiles[i].filename, outputfiles[i].offset);
2340 if (rc != 0)
2342 gmx_fatal(FARGS, "Truncation of file %s failed. Cannot do appending because of this failure.", outputfiles[i].filename);
2344 #endif
2349 sfree(outputfiles);
2353 void load_checkpoint(const char *fn, FILE **fplog,
2354 const t_commrec *cr, ivec dd_nc, int *npme,
2355 t_inputrec *ir, t_state *state,
2356 gmx_bool *bReadEkin,
2357 energyhistory_t *enerhist,
2358 gmx_bool bAppend, gmx_bool bForceAppend,
2359 gmx_bool reproducibilityRequested)
2361 gmx_int64_t step;
2362 double t;
2364 if (SIMMASTER(cr))
2366 /* Read the state from the checkpoint file */
2367 read_checkpoint(fn, fplog,
2368 cr, dd_nc, npme,
2369 ir->eI, &(ir->fepvals->init_fep_state), &step, &t,
2370 state, bReadEkin, enerhist,
2371 &ir->simulation_part, bAppend, bForceAppend,
2372 reproducibilityRequested);
2374 if (PAR(cr))
2376 gmx_bcast(sizeof(*npme), npme, cr);
2377 gmx_bcast(DIM*sizeof(dd_nc[0]), dd_nc, cr);
2378 gmx_bcast(sizeof(step), &step, cr);
2379 gmx_bcast(sizeof(*bReadEkin), bReadEkin, cr);
2381 ir->bContinuation = TRUE;
2382 if (ir->nsteps >= 0)
2384 ir->nsteps += ir->init_step - step;
2386 ir->init_step = step;
2387 ir->simulation_part += 1;
2390 void read_checkpoint_part_and_step(const char *filename,
2391 int *simulation_part,
2392 gmx_int64_t *step)
2394 int file_version;
2395 char *version, *btime, *buser, *bhost, *fprog, *ftime;
2396 int double_prec;
2397 int eIntegrator;
2398 int nppnodes, npme;
2399 ivec dd_nc;
2400 int nlambda;
2401 int flags_eks, flags_enh, flags_dfh;
2402 double t;
2403 t_state state;
2404 int nED, eSwapCoords;
2405 t_fileio *fp;
2407 if (filename == nullptr ||
2408 !gmx_fexist(filename) ||
2409 (!(fp = gmx_fio_open(filename, "r"))))
2411 *simulation_part = 0;
2412 *step = 0;
2413 return;
2416 /* Not calling initializing state before use is nasty, but all we
2417 do is read into its member variables and throw the struct away
2418 again immediately. */
2420 do_cpt_header(gmx_fio_getxdr(fp), TRUE, &file_version,
2421 &version, &btime, &buser, &bhost, &double_prec, &fprog, &ftime,
2422 &eIntegrator, simulation_part, step, &t, &nppnodes, dd_nc, &npme,
2423 &state.natoms, &state.ngtc, &state.nnhpres, &state.nhchainlength,
2424 &nlambda, &state.flags, &flags_eks, &flags_enh, &flags_dfh,
2425 &nED, &eSwapCoords, nullptr);
2427 gmx_fio_close(fp);
2430 static void read_checkpoint_data(t_fileio *fp, int *simulation_part,
2431 gmx_int64_t *step, double *t, t_state *state,
2432 int *nfiles, gmx_file_position_t **outputfiles)
2434 int file_version;
2435 char *version, *btime, *buser, *bhost, *fprog, *ftime;
2436 int double_prec;
2437 int eIntegrator;
2438 int nppnodes, npme;
2439 ivec dd_nc;
2440 int nlambda;
2441 int flags_eks, flags_enh, flags_dfh;
2442 int nED, eSwapCoords;
2443 int nfiles_loc;
2444 gmx_file_position_t *files_loc = nullptr;
2445 int ret;
2447 do_cpt_header(gmx_fio_getxdr(fp), TRUE, &file_version,
2448 &version, &btime, &buser, &bhost, &double_prec, &fprog, &ftime,
2449 &eIntegrator, simulation_part, step, t, &nppnodes, dd_nc, &npme,
2450 &state->natoms, &state->ngtc, &state->nnhpres, &state->nhchainlength,
2451 &nlambda, &state->flags, &flags_eks, &flags_enh, &flags_dfh,
2452 &nED, &eSwapCoords, nullptr);
2453 ret =
2454 do_cpt_state(gmx_fio_getxdr(fp), state->flags, state, nullptr);
2455 if (ret)
2457 cp_error();
2459 ret = do_cpt_ekinstate(gmx_fio_getxdr(fp), flags_eks, &state->ekinstate, nullptr);
2460 if (ret)
2462 cp_error();
2465 energyhistory_t enerhist;
2466 ret = do_cpt_enerhist(gmx_fio_getxdr(fp), TRUE,
2467 flags_enh, &enerhist, nullptr);
2468 if (ret)
2470 cp_error();
2472 ret = do_cpt_df_hist(gmx_fio_getxdr(fp), flags_dfh, nlambda, &state->dfhist, nullptr);
2473 if (ret)
2475 cp_error();
2478 ret = do_cpt_EDstate(gmx_fio_getxdr(fp), TRUE, nED, &state->edsamstate, nullptr);
2479 if (ret)
2481 cp_error();
2484 ret = do_cpt_swapstate(gmx_fio_getxdr(fp), TRUE, eSwapCoords, &state->swapstate, nullptr);
2485 if (ret)
2487 cp_error();
2490 ret = do_cpt_files(gmx_fio_getxdr(fp), TRUE,
2491 &files_loc,
2492 &nfiles_loc,
2493 nullptr, file_version);
2494 if (outputfiles != nullptr)
2496 *outputfiles = files_loc;
2498 else
2500 sfree(files_loc);
2502 if (nfiles != nullptr)
2504 *nfiles = nfiles_loc;
2507 if (ret)
2509 cp_error();
2512 ret = do_cpt_footer(gmx_fio_getxdr(fp), file_version);
2513 if (ret)
2515 cp_error();
2518 sfree(fprog);
2519 sfree(ftime);
2520 sfree(btime);
2521 sfree(buser);
2522 sfree(bhost);
2525 void
2526 read_checkpoint_state(const char *fn, int *simulation_part,
2527 gmx_int64_t *step, double *t, t_state *state)
2529 t_fileio *fp;
2531 fp = gmx_fio_open(fn, "r");
2532 read_checkpoint_data(fp, simulation_part, step, t, state, nullptr, nullptr);
2533 if (gmx_fio_close(fp) != 0)
2535 gmx_file("Cannot read/write checkpoint; corrupt file, or maybe you are out of disk space?");
2539 void read_checkpoint_trxframe(t_fileio *fp, t_trxframe *fr)
2541 t_state state;
2542 int simulation_part;
2543 gmx_int64_t step;
2544 double t;
2546 read_checkpoint_data(fp, &simulation_part, &step, &t, &state, nullptr, nullptr);
2548 fr->natoms = state.natoms;
2549 fr->bStep = TRUE;
2550 fr->step = gmx_int64_to_int(step,
2551 "conversion of checkpoint to trajectory");
2552 fr->bTime = TRUE;
2553 fr->time = t;
2554 fr->bLambda = TRUE;
2555 fr->lambda = state.lambda[efptFEP];
2556 fr->fep_state = state.fep_state;
2557 fr->bAtoms = FALSE;
2558 fr->bX = (state.flags & (1<<estX));
2559 if (fr->bX)
2561 fr->x = getRvecArrayFromPaddedRVecVector(&state.x, state.natoms);
2563 fr->bV = (state.flags & (1<<estV));
2564 if (fr->bV)
2566 fr->v = getRvecArrayFromPaddedRVecVector(&state.v, state.natoms);
2568 fr->bF = FALSE;
2569 fr->bBox = (state.flags & (1<<estBOX));
2570 if (fr->bBox)
2572 copy_mat(state.box, fr->box);
2576 void list_checkpoint(const char *fn, FILE *out)
2578 t_fileio *fp;
2579 int file_version;
2580 char *version, *btime, *buser, *bhost, *fprog, *ftime;
2581 int double_prec;
2582 int eIntegrator, simulation_part, nppnodes, npme;
2583 gmx_int64_t step;
2584 double t;
2585 ivec dd_nc;
2586 int nlambda;
2587 int flags_eks, flags_enh, flags_dfh;
2588 int nED, eSwapCoords;
2589 int ret;
2590 gmx_file_position_t *outputfiles;
2591 int nfiles;
2593 t_state state;
2595 fp = gmx_fio_open(fn, "r");
2596 do_cpt_header(gmx_fio_getxdr(fp), TRUE, &file_version,
2597 &version, &btime, &buser, &bhost, &double_prec, &fprog, &ftime,
2598 &eIntegrator, &simulation_part, &step, &t, &nppnodes, dd_nc, &npme,
2599 &state.natoms, &state.ngtc, &state.nnhpres, &state.nhchainlength,
2600 &nlambda, &state.flags,
2601 &flags_eks, &flags_enh, &flags_dfh, &nED, &eSwapCoords,
2602 out);
2603 ret = do_cpt_state(gmx_fio_getxdr(fp), state.flags, &state, out);
2604 if (ret)
2606 cp_error();
2608 ret = do_cpt_ekinstate(gmx_fio_getxdr(fp), flags_eks, &state.ekinstate, out);
2609 if (ret)
2611 cp_error();
2614 energyhistory_t enerhist;
2615 ret = do_cpt_enerhist(gmx_fio_getxdr(fp), TRUE,
2616 flags_enh, &enerhist, out);
2618 if (ret == 0)
2620 ret = do_cpt_df_hist(gmx_fio_getxdr(fp),
2621 flags_dfh, nlambda, &state.dfhist, out);
2624 if (ret == 0)
2626 ret = do_cpt_EDstate(gmx_fio_getxdr(fp), TRUE, nED, &state.edsamstate, out);
2629 if (ret == 0)
2631 ret = do_cpt_swapstate(gmx_fio_getxdr(fp), TRUE, eSwapCoords, &state.swapstate, out);
2634 if (ret == 0)
2636 do_cpt_files(gmx_fio_getxdr(fp), TRUE, &outputfiles, &nfiles, out, file_version);
2639 if (ret == 0)
2641 ret = do_cpt_footer(gmx_fio_getxdr(fp), file_version);
2644 if (ret)
2646 cp_warning(out);
2648 if (gmx_fio_close(fp) != 0)
2650 gmx_file("Cannot read/write checkpoint; corrupt file, or maybe you are out of disk space?");
2654 /* This routine cannot print tons of data, since it is called before the log file is opened. */
2655 void
2656 read_checkpoint_simulation_part_and_filenames(t_fileio *fp,
2657 int *simulation_part,
2658 int *nfiles,
2659 gmx_file_position_t **outputfiles)
2661 gmx_int64_t step = 0;
2662 double t;
2663 t_state state;
2665 read_checkpoint_data(fp, simulation_part, &step, &t, &state,
2666 nfiles, outputfiles);
2667 if (gmx_fio_close(fp) != 0)
2669 gmx_file("Cannot read/write checkpoint; corrupt file, or maybe you are out of disk space?");