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, by the GROMACS development team, led by
5 * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
6 * and including many others, as listed in the AUTHORS file in the
7 * top-level source directory and at http://www.gromacs.org.
9 * GROMACS is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU Lesser General Public License
11 * as published by the Free Software Foundation; either version 2.1
12 * of the License, or (at your option) any later version.
14 * GROMACS is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * Lesser General Public License for more details.
19 * You should have received a copy of the GNU Lesser General Public
20 * License along with GROMACS; if not, see
21 * http://www.gnu.org/licenses, or write to the Free Software Foundation,
22 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
24 * If you want to redistribute modifications to GROMACS, please
25 * consider that scientific software is very special. Version
26 * control is crucial - bugs must be traceable. We will be happy to
27 * consider code for inclusion in the official distribution, but
28 * derived work must not be called official GROMACS. Details are found
29 * in the README & COPYING files - if they are missing, get the
30 * official version at http://www.gromacs.org.
32 * To help us fund GROMACS development, we humbly ask that you cite
33 * the research papers on the package. Check out http://www.gromacs.org.
36 /* The source code in this file should be thread-safe.
37 Please keep it that way. */
40 #include "checkpoint.h"
49 #if GMX_NATIVE_WINDOWS
51 #include <sys/locking.h>
54 #include "buildinfo.h"
55 #include "gromacs/fileio/filetypes.h"
56 #include "gromacs/fileio/gmxfio.h"
57 #include "gromacs/fileio/gmxfio-xdr.h"
58 #include "gromacs/fileio/xdr_datatype.h"
59 #include "gromacs/fileio/xdrf.h"
60 #include "gromacs/gmxlib/network.h"
61 #include "gromacs/math/vec.h"
62 #include "gromacs/math/vecdump.h"
63 #include "gromacs/math/vectypes.h"
64 #include "gromacs/mdtypes/awh-correlation-history.h"
65 #include "gromacs/mdtypes/awh-history.h"
66 #include "gromacs/mdtypes/commrec.h"
67 #include "gromacs/mdtypes/df_history.h"
68 #include "gromacs/mdtypes/edsamhistory.h"
69 #include "gromacs/mdtypes/energyhistory.h"
70 #include "gromacs/mdtypes/inputrec.h"
71 #include "gromacs/mdtypes/md_enums.h"
72 #include "gromacs/mdtypes/observableshistory.h"
73 #include "gromacs/mdtypes/state.h"
74 #include "gromacs/mdtypes/swaphistory.h"
75 #include "gromacs/trajectory/trajectoryframe.h"
76 #include "gromacs/utility/arrayref.h"
77 #include "gromacs/utility/baseversion.h"
78 #include "gromacs/utility/cstringutil.h"
79 #include "gromacs/utility/fatalerror.h"
80 #include "gromacs/utility/futil.h"
81 #include "gromacs/utility/gmxassert.h"
82 #include "gromacs/utility/int64_to_int.h"
83 #include "gromacs/utility/programcontext.h"
84 #include "gromacs/utility/smalloc.h"
85 #include "gromacs/utility/sysinfo.h"
86 #include "gromacs/utility/txtdump.h"
92 #define CPT_MAGIC1 171817
93 #define CPT_MAGIC2 171819
94 #define CPTSTRLEN 1024
96 /* cpt_version should normally only be changed
97 * when the header or footer format changes.
98 * The state data format itself is backward and forward compatible.
99 * But old code can not read a new entry that is present in the file
100 * (but can read a new format when new entries are not present).
102 static const int cpt_version
= 17;
105 const char *est_names
[estNR
] =
108 "box", "box-rel", "box-v", "pres_prev",
109 "nosehoover-xi", "thermostat-integral",
110 "x", "v", "sdx-unsupported", "CGp", "LD-rng-unsupported", "LD-rng-i-unsupported",
111 "disre_initf", "disre_rm3tav",
112 "orire_initf", "orire_Dtav",
113 "svir_prev", "nosehoover-vxi", "v_eta", "vol0", "nhpres_xi", "nhpres_vxi", "fvir_prev", "fep_state", "MC-rng-unsupported", "MC-rng-i-unsupported"
118 eeksEKIN_N
, eeksEKINH
, eeksDEKINDL
, eeksMVCOS
, eeksEKINF
, eeksEKINO
, eeksEKINSCALEF
, eeksEKINSCALEH
, eeksVSCALE
, eeksEKINTOTAL
, eeksNR
121 const char *eeks_names
[eeksNR
] =
123 "Ekin_n", "Ekinh", "dEkindlambda", "mv_cos",
124 "Ekinf", "Ekinh_old", "EkinScaleF_NHC", "EkinScaleH_NHC", "Vscale_NHC", "Ekin_Total"
128 eenhENERGY_N
, eenhENERGY_AVER
, eenhENERGY_SUM
, eenhENERGY_NSUM
,
129 eenhENERGY_SUM_SIM
, eenhENERGY_NSUM_SIM
,
130 eenhENERGY_NSTEPS
, eenhENERGY_NSTEPS_SIM
,
131 eenhENERGY_DELTA_H_NN
,
132 eenhENERGY_DELTA_H_LIST
,
133 eenhENERGY_DELTA_H_STARTTIME
,
134 eenhENERGY_DELTA_H_STARTLAMBDA
,
138 const char *eenh_names
[eenhNR
] =
140 "energy_n", "energy_aver", "energy_sum", "energy_nsum",
141 "energy_sum_sim", "energy_nsum_sim",
142 "energy_nsteps", "energy_nsteps_sim",
144 "energy_delta_h_list",
145 "energy_delta_h_start_time",
146 "energy_delta_h_start_lambda"
149 /* free energy history variables -- need to be preserved over checkpoint */
151 edfhBEQUIL
, edfhNATLAMBDA
, edfhWLHISTO
, edfhWLDELTA
, edfhSUMWEIGHTS
, edfhSUMDG
, edfhSUMMINVAR
, edfhSUMVAR
,
152 edfhACCUMP
, edfhACCUMM
, edfhACCUMP2
, edfhACCUMM2
, edfhTIJ
, edfhTIJEMP
, edfhNR
154 /* free energy history variable names */
155 const char *edfh_names
[edfhNR
] =
157 "bEquilibrated", "N_at_state", "Wang-Landau Histogram", "Wang-Landau Delta", "Weights", "Free Energies", "minvar", "variance",
158 "accumulated_plus", "accumulated_minus", "accumulated_plus_2", "accumulated_minus_2", "Tij", "Tij_empirical"
161 /* AWH biasing history variables */
164 eawhhEQUILIBRATEHISTOGRAM
,
167 eawhhCOORDPOINT
, eawhhUMBRELLAGRIDPOINT
,
169 eawhhLOGSCALEDSAMPLEWEIGHT
,
171 eawhhFORCECORRELATIONGRID
,
175 const char *eawhh_names
[eawhhNR
] =
178 "awh_equilibrateHistogram",
181 "awh_coordpoint", "awh_umbrellaGridpoint",
183 "awh_logScaledSampleWeight",
185 "awh_forceCorrelationGrid"
188 //! Higher level vector element type, only used for formatting checkpoint dumps
189 enum class CptElementType
191 integer
, //!< integer
192 real
, //!< float or double, not linked to precision of type real
193 real3
, //!< float[3] or double[3], not linked to precision of type real
194 matrix3x3
//!< float[3][3] or double[3][3], not linked to precision of type real
197 //! \brief Parts of the checkpoint state, only used for reporting
200 microState
, //!< The microstate of the simulated system
201 kineticEnergy
, //!< Kinetic energy, needed for T/P-coupling state
202 energyHistory
, //!< Energy observable statistics
203 freeEnergyHistory
, //!< Free-energy state and observable statistics
204 accWeightHistogram
//!< Accelerated weight histogram method state
207 //! \brief Return the name of a checkpoint entry based on part and part entry
208 static const char *entryName(StatePart part
, int ecpt
)
212 case StatePart::microState
: return est_names
[ecpt
];
213 case StatePart::kineticEnergy
: return eeks_names
[ecpt
];
214 case StatePart::energyHistory
: return eenh_names
[ecpt
];
215 case StatePart::freeEnergyHistory
: return edfh_names
[ecpt
];
216 case StatePart::accWeightHistogram
: return eawhh_names
[ecpt
];
222 static void cp_warning(FILE *fp
)
224 fprintf(fp
, "\nWARNING: Checkpoint file is corrupted or truncated\n\n");
227 static void cp_error()
229 gmx_fatal(FARGS
, "Checkpoint file corrupted/truncated, or maybe you are out of disk space?");
232 static void do_cpt_string_err(XDR
*xd
, gmx_bool bRead
, const char *desc
, char **s
, FILE *list
)
238 if (xdr_string(xd
, s
, CPTSTRLEN
) == 0)
244 fprintf(list
, "%s = %s\n", desc
, *s
);
249 static int do_cpt_int(XDR
*xd
, const char *desc
, int *i
, FILE *list
)
251 if (xdr_int(xd
, i
) == 0)
257 fprintf(list
, "%s = %d\n", desc
, *i
);
262 static int do_cpt_u_chars(XDR
*xd
, const char *desc
, int n
, unsigned char *i
, FILE *list
)
266 fprintf(list
, "%s = ", desc
);
269 for (int j
= 0; j
< n
&& res
; j
++)
271 res
&= xdr_u_char(xd
, &i
[j
]);
274 fprintf(list
, "%02x", i
[j
]);
289 static void do_cpt_int_err(XDR
*xd
, const char *desc
, int *i
, FILE *list
)
291 if (do_cpt_int(xd
, desc
, i
, list
) < 0)
297 static void do_cpt_step_err(XDR
*xd
, const char *desc
, gmx_int64_t
*i
, FILE *list
)
299 char buf
[STEPSTRSIZE
];
301 if (xdr_int64(xd
, i
) == 0)
307 fprintf(list
, "%s = %s\n", desc
, gmx_step_str(*i
, buf
));
311 static void do_cpt_double_err(XDR
*xd
, const char *desc
, double *f
, FILE *list
)
313 if (xdr_double(xd
, f
) == 0)
319 fprintf(list
, "%s = %f\n", desc
, *f
);
323 static void do_cpt_real_err(XDR
*xd
, real
*f
)
326 bool_t res
= xdr_double(xd
, f
);
328 bool_t res
= xdr_float(xd
, f
);
336 static void do_cpt_n_rvecs_err(XDR
*xd
, const char *desc
, int n
, rvec f
[], FILE *list
)
338 for (int i
= 0; i
< n
; i
++)
340 for (int j
= 0; j
< DIM
; j
++)
342 do_cpt_real_err(xd
, &f
[i
][j
]);
348 pr_rvecs(list
, 0, desc
, f
, n
);
352 template <typename T
>
360 // cppcheck-suppress unusedStructMember
361 static const int value
= xdr_datatype_int
;
365 struct xdr_type
<float>
367 // cppcheck-suppress unusedStructMember
368 static const int value
= xdr_datatype_float
;
372 struct xdr_type
<double>
374 // cppcheck-suppress unusedStructMember
375 static const int value
= xdr_datatype_double
;
378 //! \brief Returns size in byte of an xdr_datatype
379 static inline unsigned int sizeOfXdrType(int xdrType
)
383 case xdr_datatype_int
:
386 case xdr_datatype_float
:
387 return sizeof(float);
389 case xdr_datatype_double
:
390 return sizeof(double);
392 default: GMX_RELEASE_ASSERT(false, "XDR data type not implemented");
398 //! \brief Returns the XDR process function for i/o of an XDR type
399 static inline xdrproc_t
xdrProc(int xdrType
)
403 case xdr_datatype_int
:
404 return reinterpret_cast<xdrproc_t
>(xdr_int
);
406 case xdr_datatype_float
:
407 return reinterpret_cast<xdrproc_t
>(xdr_float
);
409 case xdr_datatype_double
:
410 return reinterpret_cast<xdrproc_t
>(xdr_double
);
412 default: GMX_RELEASE_ASSERT(false, "XDR data type not implemented");
418 /*! \brief Lists or only reads an xdr vector from checkpoint file
420 * When list!=NULL reads and lists the \p nf vector elements of type \p xdrType.
421 * The header for the print is set by \p part and \p ecpt.
422 * The formatting of the printing is set by \p cptElementType.
423 * When list==NULL only reads the elements.
425 static bool_t
listXdrVector(XDR
*xd
, StatePart part
, int ecpt
, int nf
, int xdrType
,
426 FILE *list
, CptElementType cptElementType
)
430 const unsigned int elemSize
= sizeOfXdrType(xdrType
);
431 std::vector
<char> data(nf
*elemSize
);
432 res
= xdr_vector(xd
, data
.data(), nf
, elemSize
, xdrProc(xdrType
));
438 case xdr_datatype_int
:
439 pr_ivec(list
, 0, entryName(part
, ecpt
), reinterpret_cast<const int *>(data
.data()), nf
, TRUE
);
441 case xdr_datatype_float
:
443 if (cptElementType
== CptElementType::real3
)
445 // cppcheck-suppress invalidPointerCast
446 pr_rvecs(list
, 0, entryName(part
, ecpt
), reinterpret_cast<const rvec
*>(data
.data()), nf
/3);
451 /* Note: With double precision code dumping a single precision rvec will produce float iso rvec print, but that's a minor annoyance */
452 // cppcheck-suppress invalidPointerCast
453 pr_fvec(list
, 0, entryName(part
, ecpt
), reinterpret_cast<const float *>(data
.data()), nf
, TRUE
);
456 case xdr_datatype_double
:
458 if (cptElementType
== CptElementType::real3
)
460 // cppcheck-suppress invalidPointerCast
461 pr_rvecs(list
, 0, entryName(part
, ecpt
), reinterpret_cast<const rvec
*>(data
.data()), nf
/3);
466 /* Note: With single precision code dumping a double precision rvec will produce float iso rvec print, but that's a minor annoyance */
467 // cppcheck-suppress invalidPointerCast
468 pr_dvec(list
, 0, entryName(part
, ecpt
), reinterpret_cast<const double *>(data
.data()), nf
, TRUE
);
471 default: GMX_RELEASE_ASSERT(false, "Data type not implemented for listing");
478 //! \brief Convert a double array, typed char*, to float
479 gmx_unused
static void convertArrayRealPrecision(const char *c
, float *v
, int n
)
481 // cppcheck-suppress invalidPointerCast
482 const double *d
= reinterpret_cast<const double *>(c
);
483 for (int i
= 0; i
< n
; i
++)
485 v
[i
] = static_cast<float>(d
[i
]);
489 //! \brief Convert a float array, typed char*, to double
490 static void convertArrayRealPrecision(const char *c
, double *v
, int n
)
492 // cppcheck-suppress invalidPointerCast
493 const float *f
= reinterpret_cast<const float *>(c
);
494 for (int i
= 0; i
< n
; i
++)
496 v
[i
] = static_cast<double>(f
[i
]);
500 //! \brief Generate an error for trying to convert to integer
501 static void convertArrayRealPrecision(const char gmx_unused
*c
, int gmx_unused
*v
, int gmx_unused n
)
503 GMX_RELEASE_ASSERT(false, "We only expect type mismatches between float and double, not integer");
506 /*! \brief Low-level routine for reading/writing a vector of reals from/to file.
508 * This is the only routine that does the actually i/o of real vector,
509 * all other routines are intermediate level routines for specific real
510 * data types, calling this routine.
511 * Currently this routine is (too) complex, since it handles both real *
512 * and std::vector<real>. Using real * is deprecated and this routine
513 * will simplify a lot when only std::vector needs to be supported.
515 * The routine is generic to vectors with different allocators,
516 * because as part of reading a checkpoint there are vectors whose
517 * size is not known until reading has progressed far enough, so a
518 * resize method must be called.
520 * When not listing, we use either v or vector, depending on which is !=NULL.
521 * If nval >= 0, nval is used; on read this should match the passed value.
522 * If nval n<0, *nptr (with v) or vector->size() is used. On read using v,
523 * the value is stored in nptr
525 template<typename T
, typename AllocatorType
>
526 static int doVectorLow(XDR
*xd
, StatePart part
, int ecpt
, int sflags
,
528 T
**v
, std::vector
<T
, AllocatorType
> *vector
,
529 FILE *list
, CptElementType cptElementType
)
531 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");
535 int numElemInTheFile
;
540 GMX_RELEASE_ASSERT(nptr
== nullptr, "With nval>=0 we should have nptr==NULL");
541 numElemInTheFile
= nval
;
547 GMX_RELEASE_ASSERT(nptr
!= nullptr, "With nval<0 we should have nptr!=NULL");
548 // cppcheck-suppress nullPointer
549 numElemInTheFile
= *nptr
;
553 numElemInTheFile
= vector
->size();
557 /* Read/write the vector element count */
558 res
= xdr_int(xd
, &numElemInTheFile
);
563 /* Read/write the element data type */
564 constexpr int xdrTypeInTheCode
= xdr_type
<T
>::value
;
565 int xdrTypeInTheFile
= xdrTypeInTheCode
;
566 res
= xdr_int(xd
, &xdrTypeInTheFile
);
572 if (list
== nullptr && (sflags
& (1 << ecpt
)))
576 if (numElemInTheFile
!= nval
)
578 gmx_fatal(FARGS
, "Count mismatch for state entry %s, code count is %d, file count is %d\n", entryName(part
, ecpt
), nval
, numElemInTheFile
);
581 else if (nptr
!= nullptr)
583 *nptr
= numElemInTheFile
;
586 bool typesMatch
= (xdrTypeInTheFile
== xdrTypeInTheCode
);
590 sprintf(buf
, "mismatch for state entry %s, code precision is %s, file precision is %s",
591 entryName(part
, ecpt
),
592 xdr_datatype_names
[xdrTypeInTheCode
],
593 xdr_datatype_names
[xdrTypeInTheFile
]);
595 /* Matching int and real should never occur, but check anyhow */
596 if (xdrTypeInTheFile
== xdr_datatype_int
||
597 xdrTypeInTheCode
== xdr_datatype_int
)
599 gmx_fatal(FARGS
, "Type %s: incompatible checkpoint formats or corrupted checkpoint file.", buf
);
601 fprintf(stderr
, "Precision %s\n", buf
);
609 snew(*v
, numElemInTheFile
);
615 /* This conditional ensures that we don't resize on write.
616 * In particular in the state where this code was written
617 * PaddedRVecVector has a size of numElemInThefile and we
618 * don't want to lose that padding here.
620 if (vector
->size() < static_cast<unsigned int>(numElemInTheFile
))
622 vector
->resize(numElemInTheFile
);
630 vChar
= reinterpret_cast<char *>(vp
);
634 snew(vChar
, numElemInTheFile
*sizeOfXdrType(xdrTypeInTheFile
));
636 res
= xdr_vector(xd
, vChar
,
637 numElemInTheFile
, sizeOfXdrType(xdrTypeInTheFile
),
638 xdrProc(xdrTypeInTheFile
));
646 /* In the old code float-double conversion came for free.
647 * In the new code we still support it, mainly because
648 * the tip4p_continue regression test makes use of this.
649 * It's an open question if we do or don't want to allow this.
651 convertArrayRealPrecision(vChar
, vp
, numElemInTheFile
);
657 res
= listXdrVector(xd
, part
, ecpt
, numElemInTheFile
, xdrTypeInTheFile
,
658 list
, cptElementType
);
664 //! \brief Read/Write a std::vector.
665 template <typename T
>
666 static int doVector(XDR
*xd
, StatePart part
, int ecpt
, int sflags
,
667 std::vector
<T
> *vector
, FILE *list
)
669 return doVectorLow
<T
>(xd
, part
, ecpt
, sflags
, -1, nullptr, nullptr, vector
, list
, CptElementType::real
);
672 //! \brief Read/Write an ArrayRef<real>.
673 static int doRealArrayRef(XDR
*xd
, StatePart part
, int ecpt
, int sflags
,
674 gmx::ArrayRef
<real
> vector
, FILE *list
)
676 real
*v_real
= vector
.data();
677 return doVectorLow
< real
, std::allocator
< real
>>(xd
, part
, ecpt
, sflags
, vector
.size(), nullptr, &v_real
, nullptr, list
, CptElementType::real
);
680 //! \brief Read/Write a vector whose value_type is RVec and whose allocator is \c AllocatorType.
681 template <typename AllocatorType
>
682 static int doRvecVector(XDR
*xd
, StatePart part
, int ecpt
, int sflags
,
683 std::vector
<gmx::RVec
, AllocatorType
> *v
, int numAtoms
, FILE *list
)
685 const int numReals
= numAtoms
*DIM
;
689 GMX_RELEASE_ASSERT(sflags
& (1 << ecpt
), "When not listing, the flag for the entry should be set when requesting i/o");
690 GMX_RELEASE_ASSERT(v
->size() >= static_cast<size_t>(numAtoms
), "v should have sufficient size for numAtoms");
692 real
*v_real
= v
->data()->as_vec();
694 // PaddedRVecVector is padded beyond numAtoms, we should only write
696 gmx::ArrayRef
<real
> ref(v_real
, v_real
+ numReals
);
698 return doRealArrayRef(xd
, part
, ecpt
, sflags
, ref
, list
);
702 // Use the rebind facility to change the value_type of the
703 // allocator from RVec to real.
704 using realAllocator
= typename
AllocatorType::template rebind
<real
>::other
;
705 return doVectorLow
<real
, realAllocator
>(xd
, part
, ecpt
, sflags
, numReals
, nullptr, nullptr, nullptr, list
, CptElementType::real
);
709 /* This function stores n along with the reals for reading,
710 * but on reading it assumes that n matches the value in the checkpoint file,
711 * a fatal error is generated when this is not the case.
713 static int do_cpte_reals(XDR
*xd
, StatePart part
, int ecpt
, int sflags
,
714 int n
, real
**v
, FILE *list
)
716 return doVectorLow
< real
, std::allocator
< real
>>(xd
, part
, ecpt
, sflags
, n
, nullptr, v
, nullptr, list
, CptElementType::real
);
719 /* This function does the same as do_cpte_reals,
720 * except that on reading it ignores the passed value of *n
721 * and stores the value read from the checkpoint file in *n.
723 static int do_cpte_n_reals(XDR
*xd
, StatePart part
, int ecpt
, int sflags
,
724 int *n
, real
**v
, FILE *list
)
726 return doVectorLow
< real
, std::allocator
< real
>>(xd
, part
, ecpt
, sflags
, -1, n
, v
, nullptr, list
, CptElementType::real
);
729 static int do_cpte_real(XDR
*xd
, StatePart part
, int ecpt
, int sflags
,
732 return doVectorLow
< real
, std::allocator
< real
>>(xd
, part
, ecpt
, sflags
, 1, nullptr, &r
, nullptr, list
, CptElementType::real
);
735 static int do_cpte_ints(XDR
*xd
, StatePart part
, int ecpt
, int sflags
,
736 int n
, int **v
, FILE *list
)
738 return doVectorLow
< int, std::allocator
< int>>(xd
, part
, ecpt
, sflags
, n
, nullptr, v
, nullptr, list
, CptElementType::integer
);
741 static int do_cpte_int(XDR
*xd
, StatePart part
, int ecpt
, int sflags
,
744 return do_cpte_ints(xd
, part
, ecpt
, sflags
, 1, &i
, list
);
747 static int do_cpte_doubles(XDR
*xd
, StatePart part
, int ecpt
, int sflags
,
748 int n
, double **v
, FILE *list
)
750 return doVectorLow
< double, std::allocator
< double>>(xd
, part
, ecpt
, sflags
, n
, nullptr, v
, nullptr, list
, CptElementType::real
);
753 static int do_cpte_double(XDR
*xd
, StatePart part
, int ecpt
, int sflags
,
754 double *r
, FILE *list
)
756 return do_cpte_doubles(xd
, part
, ecpt
, sflags
, 1, &r
, list
);
759 static int do_cpte_matrix(XDR
*xd
, StatePart part
, int ecpt
, int sflags
,
760 matrix v
, FILE *list
)
766 ret
= doVectorLow
< real
, std::allocator
< real
>>(xd
, part
, ecpt
, sflags
,
767 DIM
*DIM
, nullptr, &vr
, nullptr, nullptr, CptElementType::matrix3x3
);
769 if (list
&& ret
== 0)
771 pr_rvecs(list
, 0, entryName(part
, ecpt
), v
, DIM
);
778 static int do_cpte_nmatrix(XDR
*xd
, StatePart part
, int ecpt
, int sflags
,
779 int n
, real
**v
, FILE *list
)
783 char name
[CPTSTRLEN
];
790 for (i
= 0; i
< n
; i
++)
792 reti
= doVectorLow
< real
, std::allocator
< real
>>(xd
, part
, ecpt
, sflags
, n
, nullptr, &(v
[i
]), nullptr, nullptr, CptElementType::matrix3x3
);
793 if (list
&& reti
== 0)
795 sprintf(name
, "%s[%d]", entryName(part
, ecpt
), i
);
796 pr_reals(list
, 0, name
, v
[i
], n
);
806 static int do_cpte_matrices(XDR
*xd
, StatePart part
, int ecpt
, int sflags
,
807 int n
, matrix
**v
, FILE *list
)
810 matrix
*vp
, *va
= nullptr;
816 res
= xdr_int(xd
, &nf
);
821 if (list
== nullptr && nf
!= n
)
823 gmx_fatal(FARGS
, "Count mismatch for state entry %s, code count is %d, file count is %d\n", entryName(part
, ecpt
), n
, nf
);
825 if (list
|| !(sflags
& (1<<ecpt
)))
838 snew(vr
, nf
*DIM
*DIM
);
839 for (i
= 0; i
< nf
; i
++)
841 for (j
= 0; j
< DIM
; j
++)
843 for (k
= 0; k
< DIM
; k
++)
845 vr
[(i
*DIM
+j
)*DIM
+k
] = vp
[i
][j
][k
];
849 ret
= doVectorLow
< real
, std::allocator
< real
>>(xd
, part
, ecpt
, sflags
,
850 nf
*DIM
*DIM
, nullptr, &vr
, nullptr, nullptr,
851 CptElementType::matrix3x3
);
852 for (i
= 0; i
< nf
; i
++)
854 for (j
= 0; j
< DIM
; j
++)
856 for (k
= 0; k
< DIM
; k
++)
858 vp
[i
][j
][k
] = vr
[(i
*DIM
+j
)*DIM
+k
];
864 if (list
&& ret
== 0)
866 for (i
= 0; i
< nf
; i
++)
868 pr_rvecs(list
, 0, entryName(part
, ecpt
), vp
[i
], DIM
);
879 static void do_cpt_header(XDR
*xd
, gmx_bool bRead
, int *file_version
,
880 char **version
, char **btime
, char **buser
, char **bhost
,
882 char **fprog
, char **ftime
,
883 int *eIntegrator
, int *simulation_part
,
884 gmx_int64_t
*step
, double *t
,
885 int *nnodes
, int *dd_nc
, int *npme
,
886 int *natoms
, int *ngtc
, int *nnhpres
, int *nhchainlength
,
887 int *nlambda
, int *flags_state
,
888 int *flags_eks
, int *flags_enh
, int *flags_dfh
, int *flags_awhh
,
889 int *nED
, int *eSwapCoords
,
905 res
= xdr_int(xd
, &magic
);
908 gmx_fatal(FARGS
, "The checkpoint file is empty/corrupted, or maybe you are out of disk space?");
910 if (magic
!= CPT_MAGIC1
)
912 gmx_fatal(FARGS
, "Start of file magic number mismatch, checkpoint file has %d, should be %d\n"
913 "The checkpoint file is corrupted or not a checkpoint file",
919 gmx_gethostname(fhost
, 255);
921 do_cpt_string_err(xd
, bRead
, "GROMACS version", version
, list
);
922 do_cpt_string_err(xd
, bRead
, "GROMACS build time", btime
, list
);
923 do_cpt_string_err(xd
, bRead
, "GROMACS build user", buser
, list
);
924 do_cpt_string_err(xd
, bRead
, "GROMACS build host", bhost
, list
);
925 do_cpt_string_err(xd
, bRead
, "generating program", fprog
, list
);
926 do_cpt_string_err(xd
, bRead
, "generation time", ftime
, list
);
927 *file_version
= cpt_version
;
928 do_cpt_int_err(xd
, "checkpoint file version", file_version
, list
);
929 if (*file_version
> cpt_version
)
931 gmx_fatal(FARGS
, "Attempting to read a checkpoint file of version %d with code of version %d\n", *file_version
, cpt_version
);
933 if (*file_version
>= 13)
935 do_cpt_int_err(xd
, "GROMACS double precision", double_prec
, list
);
941 if (*file_version
>= 12)
943 do_cpt_string_err(xd
, bRead
, "generating host", &fhost
, list
);
949 do_cpt_int_err(xd
, "#atoms", natoms
, list
);
950 do_cpt_int_err(xd
, "#T-coupling groups", ngtc
, list
);
951 if (*file_version
>= 10)
953 do_cpt_int_err(xd
, "#Nose-Hoover T-chains", nhchainlength
, list
);
959 if (*file_version
>= 11)
961 do_cpt_int_err(xd
, "#Nose-Hoover T-chains for barostat ", nnhpres
, list
);
967 if (*file_version
>= 14)
969 do_cpt_int_err(xd
, "# of total lambda states ", nlambda
, list
);
975 do_cpt_int_err(xd
, "integrator", eIntegrator
, list
);
976 if (*file_version
>= 3)
978 do_cpt_int_err(xd
, "simulation part #", simulation_part
, list
);
982 *simulation_part
= 1;
984 if (*file_version
>= 5)
986 do_cpt_step_err(xd
, "step", step
, list
);
990 do_cpt_int_err(xd
, "step", &idum
, list
);
993 do_cpt_double_err(xd
, "t", t
, list
);
994 do_cpt_int_err(xd
, "#PP-ranks", nnodes
, list
);
996 do_cpt_int_err(xd
, "dd_nc[x]", dd_nc
? &(dd_nc
[0]) : &idum
, list
);
997 do_cpt_int_err(xd
, "dd_nc[y]", dd_nc
? &(dd_nc
[1]) : &idum
, list
);
998 do_cpt_int_err(xd
, "dd_nc[z]", dd_nc
? &(dd_nc
[2]) : &idum
, list
);
999 do_cpt_int_err(xd
, "#PME-only ranks", npme
, list
);
1000 do_cpt_int_err(xd
, "state flags", flags_state
, list
);
1001 if (*file_version
>= 4)
1003 do_cpt_int_err(xd
, "ekin data flags", flags_eks
, list
);
1004 do_cpt_int_err(xd
, "energy history flags", flags_enh
, list
);
1009 *flags_enh
= (*flags_state
>> (estORIRE_DTAV
+1));
1010 *flags_state
= (*flags_state
& ~((1<<(estORIRE_DTAV
+1)) |
1011 (1<<(estORIRE_DTAV
+2)) |
1012 (1<<(estORIRE_DTAV
+3))));
1014 if (*file_version
>= 14)
1016 do_cpt_int_err(xd
, "df history flags", flags_dfh
, list
);
1023 if (*file_version
>= 15)
1025 do_cpt_int_err(xd
, "ED data sets", nED
, list
);
1032 if (*file_version
>= 16)
1034 do_cpt_int_err(xd
, "swap", eSwapCoords
, list
);
1038 *eSwapCoords
= eswapNO
;
1041 if (*file_version
>= 17)
1043 do_cpt_int_err(xd
, "AWH history flags", flags_awhh
, list
);
1051 static int do_cpt_footer(XDR
*xd
, int file_version
)
1056 if (file_version
>= 2)
1059 res
= xdr_int(xd
, &magic
);
1064 if (magic
!= CPT_MAGIC2
)
1073 static int do_cpt_state(XDR
*xd
,
1074 int fflags
, t_state
*state
,
1078 const StatePart part
= StatePart::microState
;
1079 const int sflags
= state
->flags
;
1080 // If reading, state->natoms was probably just read, so
1081 // allocations need to be managed. If writing, this won't change
1082 // anything that matters.
1083 state_change_natoms(state
, state
->natoms
);
1084 for (int i
= 0; (i
< estNR
&& ret
== 0); i
++)
1086 if (fflags
& (1<<i
))
1090 case estLAMBDA
: ret
= doRealArrayRef(xd
, part
, i
, sflags
, gmx::arrayRefFromArray
<real
>(state
->lambda
.data(), state
->lambda
.size()), list
); break;
1091 case estFEPSTATE
: ret
= do_cpte_int (xd
, part
, i
, sflags
, &state
->fep_state
, list
); break;
1092 case estBOX
: ret
= do_cpte_matrix(xd
, part
, i
, sflags
, state
->box
, list
); break;
1093 case estBOX_REL
: ret
= do_cpte_matrix(xd
, part
, i
, sflags
, state
->box_rel
, list
); break;
1094 case estBOXV
: ret
= do_cpte_matrix(xd
, part
, i
, sflags
, state
->boxv
, list
); break;
1095 case estPRES_PREV
: ret
= do_cpte_matrix(xd
, part
, i
, sflags
, state
->pres_prev
, list
); break;
1096 case estSVIR_PREV
: ret
= do_cpte_matrix(xd
, part
, i
, sflags
, state
->svir_prev
, list
); break;
1097 case estFVIR_PREV
: ret
= do_cpte_matrix(xd
, part
, i
, sflags
, state
->fvir_prev
, list
); break;
1098 case estNH_XI
: ret
= doVector
<double>(xd
, part
, i
, sflags
, &state
->nosehoover_xi
, list
); break;
1099 case estNH_VXI
: ret
= doVector
<double>(xd
, part
, i
, sflags
, &state
->nosehoover_vxi
, list
); break;
1100 case estNHPRES_XI
: ret
= doVector
<double>(xd
, part
, i
, sflags
, &state
->nhpres_xi
, list
); break;
1101 case estNHPRES_VXI
: ret
= doVector
<double>(xd
, part
, i
, sflags
, &state
->nhpres_vxi
, list
); break;
1102 case estTHERM_INT
: ret
= doVector
<double>(xd
, part
, i
, sflags
, &state
->therm_integral
, list
); break;
1103 case estBAROS_INT
: ret
= do_cpte_double(xd
, part
, i
, sflags
, &state
->baros_integral
, list
); break;
1104 case estVETA
: ret
= do_cpte_real(xd
, part
, i
, sflags
, &state
->veta
, list
); break;
1105 case estVOL0
: ret
= do_cpte_real(xd
, part
, i
, sflags
, &state
->vol0
, list
); break;
1106 case estX
: ret
= doRvecVector(xd
, part
, i
, sflags
, &state
->x
, state
->natoms
, list
); break;
1107 case estV
: ret
= doRvecVector(xd
, part
, i
, sflags
, &state
->v
, state
->natoms
, list
); break;
1108 /* The RNG entries are no longer written,
1109 * the next 4 lines are only for reading old files.
1111 case estLD_RNG_NOTSUPPORTED
: ret
= do_cpte_ints(xd
, part
, i
, sflags
, 0, nullptr, list
); break;
1112 case estLD_RNGI_NOTSUPPORTED
: ret
= do_cpte_ints(xd
, part
, i
, sflags
, 0, nullptr, list
); break;
1113 case estMC_RNG_NOTSUPPORTED
: ret
= do_cpte_ints(xd
, part
, i
, sflags
, 0, nullptr, list
); break;
1114 case estMC_RNGI_NOTSUPPORTED
: ret
= do_cpte_ints(xd
, part
, i
, sflags
, 0, nullptr, list
); break;
1115 case estDISRE_INITF
: ret
= do_cpte_real (xd
, part
, i
, sflags
, &state
->hist
.disre_initf
, list
); break;
1116 case estDISRE_RM3TAV
: ret
= do_cpte_n_reals(xd
, part
, i
, sflags
, &state
->hist
.ndisrepairs
, &state
->hist
.disre_rm3tav
, list
); break;
1117 case estORIRE_INITF
: ret
= do_cpte_real (xd
, part
, i
, sflags
, &state
->hist
.orire_initf
, list
); break;
1118 case estORIRE_DTAV
: ret
= do_cpte_n_reals(xd
, part
, i
, sflags
, &state
->hist
.norire_Dtav
, &state
->hist
.orire_Dtav
, list
); break;
1120 gmx_fatal(FARGS
, "Unknown state entry %d\n"
1121 "You are reading a checkpoint file written by different code, which is not supported", i
);
1129 static int do_cpt_ekinstate(XDR
*xd
, int fflags
, ekinstate_t
*ekins
,
1134 const StatePart part
= StatePart::kineticEnergy
;
1135 for (int i
= 0; (i
< eeksNR
&& ret
== 0); i
++)
1137 if (fflags
& (1<<i
))
1142 case eeksEKIN_N
: ret
= do_cpte_int(xd
, part
, i
, fflags
, &ekins
->ekin_n
, list
); break;
1143 case eeksEKINH
: ret
= do_cpte_matrices(xd
, part
, i
, fflags
, ekins
->ekin_n
, &ekins
->ekinh
, list
); break;
1144 case eeksEKINF
: ret
= do_cpte_matrices(xd
, part
, i
, fflags
, ekins
->ekin_n
, &ekins
->ekinf
, list
); break;
1145 case eeksEKINO
: ret
= do_cpte_matrices(xd
, part
, i
, fflags
, ekins
->ekin_n
, &ekins
->ekinh_old
, list
); break;
1146 case eeksEKINTOTAL
: ret
= do_cpte_matrix(xd
, part
, i
, fflags
, ekins
->ekin_total
, list
); break;
1147 case eeksEKINSCALEF
: ret
= doVector
<double>(xd
, part
, i
, fflags
, &ekins
->ekinscalef_nhc
, list
); break;
1148 case eeksVSCALE
: ret
= doVector
<double>(xd
, part
, i
, fflags
, &ekins
->vscale_nhc
, list
); break;
1149 case eeksEKINSCALEH
: ret
= doVector
<double>(xd
, part
, i
, fflags
, &ekins
->ekinscaleh_nhc
, list
); break;
1150 case eeksDEKINDL
: ret
= do_cpte_real(xd
, part
, i
, fflags
, &ekins
->dekindl
, list
); break;
1151 case eeksMVCOS
: ret
= do_cpte_real(xd
, part
, i
, fflags
, &ekins
->mvcos
, list
); break;
1153 gmx_fatal(FARGS
, "Unknown ekin data state entry %d\n"
1154 "You are probably reading a new checkpoint file with old code", i
);
1163 static int do_cpt_swapstate(XDR
*xd
, gmx_bool bRead
,
1164 int eSwapCoords
, swaphistory_t
*swapstate
, FILE *list
)
1166 int swap_cpt_version
= 2;
1168 if (eSwapCoords
== eswapNO
)
1173 swapstate
->bFromCpt
= bRead
;
1174 swapstate
->eSwapCoords
= eSwapCoords
;
1176 do_cpt_int_err(xd
, "swap checkpoint version", &swap_cpt_version
, list
);
1177 if (bRead
&& swap_cpt_version
< 2)
1179 gmx_fatal(FARGS
, "Cannot read checkpoint files that were written with old versions"
1180 "of the ion/water position swapping protocol.\n");
1183 do_cpt_int_err(xd
, "swap coupling steps", &swapstate
->nAverage
, list
);
1185 /* When reading, init_swapcoords has not been called yet,
1186 * so we have to allocate memory first. */
1187 do_cpt_int_err(xd
, "number of ion types", &swapstate
->nIonTypes
, list
);
1190 snew(swapstate
->ionType
, swapstate
->nIonTypes
);
1193 for (int ic
= 0; ic
< eCompNR
; ic
++)
1195 for (int ii
= 0; ii
< swapstate
->nIonTypes
; ii
++)
1197 swapstateIons_t
*gs
= &swapstate
->ionType
[ii
];
1201 do_cpt_int_err(xd
, "swap requested atoms", &gs
->nMolReq
[ic
], list
);
1205 do_cpt_int_err(xd
, "swap requested atoms p", gs
->nMolReq_p
[ic
], list
);
1210 do_cpt_int_err(xd
, "swap influx net", &gs
->inflow_net
[ic
], list
);
1214 do_cpt_int_err(xd
, "swap influx net p", gs
->inflow_net_p
[ic
], list
);
1217 if (bRead
&& (nullptr == gs
->nMolPast
[ic
]) )
1219 snew(gs
->nMolPast
[ic
], swapstate
->nAverage
);
1222 for (int j
= 0; j
< swapstate
->nAverage
; j
++)
1226 do_cpt_int_err(xd
, "swap past atom counts", &gs
->nMolPast
[ic
][j
], list
);
1230 do_cpt_int_err(xd
, "swap past atom counts p", &gs
->nMolPast_p
[ic
][j
], list
);
1236 /* Ion flux per channel */
1237 for (int ic
= 0; ic
< eChanNR
; ic
++)
1239 for (int ii
= 0; ii
< swapstate
->nIonTypes
; ii
++)
1241 swapstateIons_t
*gs
= &swapstate
->ionType
[ii
];
1245 do_cpt_int_err(xd
, "channel flux A->B", &gs
->fluxfromAtoB
[ic
], list
);
1249 do_cpt_int_err(xd
, "channel flux A->B p", gs
->fluxfromAtoB_p
[ic
], list
);
1254 /* Ion flux leakage */
1257 do_cpt_int_err(xd
, "flux leakage", &swapstate
->fluxleak
, list
);
1261 do_cpt_int_err(xd
, "flux leakage", swapstate
->fluxleak_p
, list
);
1265 for (int ii
= 0; ii
< swapstate
->nIonTypes
; ii
++)
1267 swapstateIons_t
*gs
= &swapstate
->ionType
[ii
];
1269 do_cpt_int_err(xd
, "number of ions", &gs
->nMol
, list
);
1273 snew(gs
->channel_label
, gs
->nMol
);
1274 snew(gs
->comp_from
, gs
->nMol
);
1277 do_cpt_u_chars(xd
, "channel history", gs
->nMol
, gs
->channel_label
, list
);
1278 do_cpt_u_chars(xd
, "domain history", gs
->nMol
, gs
->comp_from
, list
);
1281 /* Save the last known whole positions to checkpoint
1282 * file to be able to also make multimeric channels whole in PBC */
1283 do_cpt_int_err(xd
, "Ch0 atoms", &swapstate
->nat
[eChan0
], list
);
1284 do_cpt_int_err(xd
, "Ch1 atoms", &swapstate
->nat
[eChan1
], list
);
1287 snew(swapstate
->xc_old_whole
[eChan0
], swapstate
->nat
[eChan0
]);
1288 snew(swapstate
->xc_old_whole
[eChan1
], swapstate
->nat
[eChan1
]);
1289 do_cpt_n_rvecs_err(xd
, "Ch0 whole x", swapstate
->nat
[eChan0
], swapstate
->xc_old_whole
[eChan0
], list
);
1290 do_cpt_n_rvecs_err(xd
, "Ch1 whole x", swapstate
->nat
[eChan1
], swapstate
->xc_old_whole
[eChan1
], list
);
1294 do_cpt_n_rvecs_err(xd
, "Ch0 whole x", swapstate
->nat
[eChan0
], *swapstate
->xc_old_whole_p
[eChan0
], list
);
1295 do_cpt_n_rvecs_err(xd
, "Ch1 whole x", swapstate
->nat
[eChan1
], *swapstate
->xc_old_whole_p
[eChan1
], list
);
1302 static int do_cpt_enerhist(XDR
*xd
, gmx_bool bRead
,
1303 int fflags
, energyhistory_t
*enerhist
,
1313 GMX_RELEASE_ASSERT(enerhist
!= nullptr, "With energy history, we need a valid enerhist pointer");
1315 /* This is stored/read for backward compatibility */
1316 int energyHistoryNumEnergies
= 0;
1319 enerhist
->nsteps
= 0;
1321 enerhist
->nsteps_sim
= 0;
1322 enerhist
->nsum_sim
= 0;
1324 else if (enerhist
!= nullptr)
1326 energyHistoryNumEnergies
= enerhist
->ener_sum_sim
.size();
1329 delta_h_history_t
*deltaH
= enerhist
->deltaHForeignLambdas
.get();
1330 const StatePart part
= StatePart::energyHistory
;
1331 for (int i
= 0; (i
< eenhNR
&& ret
== 0); i
++)
1333 if (fflags
& (1<<i
))
1337 case eenhENERGY_N
: ret
= do_cpte_int(xd
, part
, i
, fflags
, &energyHistoryNumEnergies
, list
); break;
1338 case eenhENERGY_AVER
: ret
= doVector
<double>(xd
, part
, i
, fflags
, &enerhist
->ener_ave
, list
); break;
1339 case eenhENERGY_SUM
: ret
= doVector
<double>(xd
, part
, i
, fflags
, &enerhist
->ener_sum
, list
); break;
1340 case eenhENERGY_NSUM
: do_cpt_step_err(xd
, eenh_names
[i
], &enerhist
->nsum
, list
); break;
1341 case eenhENERGY_SUM_SIM
: ret
= doVector
<double>(xd
, part
, i
, fflags
, &enerhist
->ener_sum_sim
, list
); break;
1342 case eenhENERGY_NSUM_SIM
: do_cpt_step_err(xd
, eenh_names
[i
], &enerhist
->nsum_sim
, list
); break;
1343 case eenhENERGY_NSTEPS
: do_cpt_step_err(xd
, eenh_names
[i
], &enerhist
->nsteps
, list
); break;
1344 case eenhENERGY_NSTEPS_SIM
: do_cpt_step_err(xd
, eenh_names
[i
], &enerhist
->nsteps_sim
, list
); break;
1345 case eenhENERGY_DELTA_H_NN
:
1348 if (!bRead
&& deltaH
!= nullptr)
1350 numDeltaH
= deltaH
->dh
.size();
1352 do_cpt_int_err(xd
, eenh_names
[i
], &numDeltaH
, list
);
1355 if (deltaH
== nullptr)
1357 enerhist
->deltaHForeignLambdas
.reset(new delta_h_history_t
);
1358 deltaH
= enerhist
->deltaHForeignLambdas
.get();
1360 deltaH
->dh
.resize(numDeltaH
);
1361 deltaH
->start_lambda_set
= FALSE
;
1365 case eenhENERGY_DELTA_H_LIST
:
1366 for (auto dh
: deltaH
->dh
)
1368 ret
= doVector
<real
>(xd
, part
, i
, fflags
, &dh
, list
);
1371 case eenhENERGY_DELTA_H_STARTTIME
:
1372 ret
= do_cpte_double(xd
, part
, i
, fflags
, &(deltaH
->start_time
), list
); break;
1373 case eenhENERGY_DELTA_H_STARTLAMBDA
:
1374 ret
= do_cpte_double(xd
, part
, i
, fflags
, &(deltaH
->start_lambda
), list
); break;
1376 gmx_fatal(FARGS
, "Unknown energy history entry %d\n"
1377 "You are probably reading a new checkpoint file with old code", i
);
1382 if ((fflags
& (1<<eenhENERGY_SUM
)) && !(fflags
& (1<<eenhENERGY_SUM_SIM
)))
1384 /* Assume we have an old file format and copy sum to sum_sim */
1385 enerhist
->ener_sum_sim
= enerhist
->ener_sum
;
1388 if ( (fflags
& (1<<eenhENERGY_NSUM
)) &&
1389 !(fflags
& (1<<eenhENERGY_NSTEPS
)))
1391 /* Assume we have an old file format and copy nsum to nsteps */
1392 enerhist
->nsteps
= enerhist
->nsum
;
1394 if ( (fflags
& (1<<eenhENERGY_NSUM_SIM
)) &&
1395 !(fflags
& (1<<eenhENERGY_NSTEPS_SIM
)))
1397 /* Assume we have an old file format and copy nsum to nsteps */
1398 enerhist
->nsteps_sim
= enerhist
->nsum_sim
;
1404 static int do_cpt_df_hist(XDR
*xd
, int fflags
, int nlambda
, df_history_t
**dfhistPtr
, FILE *list
)
1413 if (*dfhistPtr
== nullptr)
1415 snew(*dfhistPtr
, 1);
1416 (*dfhistPtr
)->nlambda
= nlambda
;
1417 init_df_history(*dfhistPtr
, nlambda
);
1419 df_history_t
*dfhist
= *dfhistPtr
;
1421 const StatePart part
= StatePart::freeEnergyHistory
;
1422 for (int i
= 0; (i
< edfhNR
&& ret
== 0); i
++)
1424 if (fflags
& (1<<i
))
1428 case edfhBEQUIL
: ret
= do_cpte_int(xd
, part
, i
, fflags
, &dfhist
->bEquil
, list
); break;
1429 case edfhNATLAMBDA
: ret
= do_cpte_ints(xd
, part
, i
, fflags
, nlambda
, &dfhist
->n_at_lam
, list
); break;
1430 case edfhWLHISTO
: ret
= do_cpte_reals(xd
, part
, i
, fflags
, nlambda
, &dfhist
->wl_histo
, list
); break;
1431 case edfhWLDELTA
: ret
= do_cpte_real(xd
, part
, i
, fflags
, &dfhist
->wl_delta
, list
); break;
1432 case edfhSUMWEIGHTS
: ret
= do_cpte_reals(xd
, part
, i
, fflags
, nlambda
, &dfhist
->sum_weights
, list
); break;
1433 case edfhSUMDG
: ret
= do_cpte_reals(xd
, part
, i
, fflags
, nlambda
, &dfhist
->sum_dg
, list
); break;
1434 case edfhSUMMINVAR
: ret
= do_cpte_reals(xd
, part
, i
, fflags
, nlambda
, &dfhist
->sum_minvar
, list
); break;
1435 case edfhSUMVAR
: ret
= do_cpte_reals(xd
, part
, i
, fflags
, nlambda
, &dfhist
->sum_variance
, list
); break;
1436 case edfhACCUMP
: ret
= do_cpte_nmatrix(xd
, part
, i
, fflags
, nlambda
, dfhist
->accum_p
, list
); break;
1437 case edfhACCUMM
: ret
= do_cpte_nmatrix(xd
, part
, i
, fflags
, nlambda
, dfhist
->accum_m
, list
); break;
1438 case edfhACCUMP2
: ret
= do_cpte_nmatrix(xd
, part
, i
, fflags
, nlambda
, dfhist
->accum_p2
, list
); break;
1439 case edfhACCUMM2
: ret
= do_cpte_nmatrix(xd
, part
, i
, fflags
, nlambda
, dfhist
->accum_m2
, list
); break;
1440 case edfhTIJ
: ret
= do_cpte_nmatrix(xd
, part
, i
, fflags
, nlambda
, dfhist
->Tij
, list
); break;
1441 case edfhTIJEMP
: ret
= do_cpte_nmatrix(xd
, part
, i
, fflags
, nlambda
, dfhist
->Tij_empirical
, list
); break;
1444 gmx_fatal(FARGS
, "Unknown df history entry %d\n"
1445 "You are probably reading a new checkpoint file with old code", i
);
1454 /* This function stores the last whole configuration of the reference and
1455 * average structure in the .cpt file
1457 static int do_cpt_EDstate(XDR
*xd
, gmx_bool bRead
,
1458 int nED
, edsamhistory_t
*EDstate
, FILE *list
)
1465 EDstate
->bFromCpt
= bRead
;
1468 /* When reading, init_edsam has not been called yet,
1469 * so we have to allocate memory first. */
1472 snew(EDstate
->nref
, EDstate
->nED
);
1473 snew(EDstate
->old_sref
, EDstate
->nED
);
1474 snew(EDstate
->nav
, EDstate
->nED
);
1475 snew(EDstate
->old_sav
, EDstate
->nED
);
1478 /* Read/write the last whole conformation of SREF and SAV for each ED dataset (usually only one) */
1479 for (int i
= 0; i
< EDstate
->nED
; i
++)
1483 /* Reference structure SREF */
1484 sprintf(buf
, "ED%d # of atoms in reference structure", i
+1);
1485 do_cpt_int_err(xd
, buf
, &EDstate
->nref
[i
], list
);
1486 sprintf(buf
, "ED%d x_ref", i
+1);
1489 snew(EDstate
->old_sref
[i
], EDstate
->nref
[i
]);
1490 do_cpt_n_rvecs_err(xd
, buf
, EDstate
->nref
[i
], EDstate
->old_sref
[i
], list
);
1494 do_cpt_n_rvecs_err(xd
, buf
, EDstate
->nref
[i
], EDstate
->old_sref_p
[i
], list
);
1497 /* Average structure SAV */
1498 sprintf(buf
, "ED%d # of atoms in average structure", i
+1);
1499 do_cpt_int_err(xd
, buf
, &EDstate
->nav
[i
], list
);
1500 sprintf(buf
, "ED%d x_av", i
+1);
1503 snew(EDstate
->old_sav
[i
], EDstate
->nav
[i
]);
1504 do_cpt_n_rvecs_err(xd
, buf
, EDstate
->nav
[i
], EDstate
->old_sav
[i
], list
);
1508 do_cpt_n_rvecs_err(xd
, buf
, EDstate
->nav
[i
], EDstate
->old_sav_p
[i
], list
);
1515 static int do_cpt_correlation_grid(XDR
*xd
, gmx_bool bRead
, gmx_unused
int fflags
,
1516 gmx::CorrelationGridHistory
*corrGrid
,
1517 FILE *list
, int eawhh
)
1521 do_cpt_int_err(xd
, eawhh_names
[eawhh
], &(corrGrid
->numCorrelationTensors
), list
);
1522 do_cpt_int_err(xd
, eawhh_names
[eawhh
], &(corrGrid
->tensorSize
), list
);
1523 do_cpt_int_err(xd
, eawhh_names
[eawhh
], &(corrGrid
->blockDataListSize
), list
);
1527 initCorrelationGridHistory(corrGrid
, corrGrid
->numCorrelationTensors
, corrGrid
->tensorSize
, corrGrid
->blockDataListSize
);
1530 for (gmx::CorrelationBlockDataHistory
&blockData
: corrGrid
->blockDataBuffer
)
1532 do_cpt_double_err(xd
, eawhh_names
[eawhh
], &(blockData
.blockSumWeight
), list
);
1533 do_cpt_double_err(xd
, eawhh_names
[eawhh
], &(blockData
.blockSumSquareWeight
), list
);
1534 do_cpt_double_err(xd
, eawhh_names
[eawhh
], &(blockData
.blockSumWeightX
), list
);
1535 do_cpt_double_err(xd
, eawhh_names
[eawhh
], &(blockData
.blockSumWeightY
), list
);
1536 do_cpt_double_err(xd
, eawhh_names
[eawhh
], &(blockData
.sumOverBlocksSquareBlockWeight
), list
);
1537 do_cpt_double_err(xd
, eawhh_names
[eawhh
], &(blockData
.sumOverBlocksBlockSquareWeight
), list
);
1538 do_cpt_double_err(xd
, eawhh_names
[eawhh
], &(blockData
.sumOverBlocksBlockWeightBlockWeightX
), list
);
1539 do_cpt_double_err(xd
, eawhh_names
[eawhh
], &(blockData
.sumOverBlocksBlockWeightBlockWeightY
), list
);
1540 do_cpt_double_err(xd
, eawhh_names
[eawhh
], &(blockData
.blockLength
), list
);
1541 do_cpt_int_err(xd
, eawhh_names
[eawhh
], &(blockData
.previousBlockIndex
), list
);
1542 do_cpt_double_err(xd
, eawhh_names
[eawhh
], &(blockData
.correlationIntegral
), list
);
1548 static int do_cpt_awh_bias(XDR
*xd
, gmx_bool bRead
,
1549 int fflags
, gmx::AwhBiasHistory
*biasHistory
,
1554 gmx::AwhBiasStateHistory
*state
= &biasHistory
->state
;
1555 for (int i
= 0; (i
< eawhhNR
&& ret
== 0); i
++)
1557 if (fflags
& (1<<i
))
1561 case eawhhIN_INITIAL
:
1562 do_cpt_int_err(xd
, eawhh_names
[i
], &state
->in_initial
, list
); break;
1563 case eawhhEQUILIBRATEHISTOGRAM
:
1564 do_cpt_int_err(xd
, eawhh_names
[i
], &state
->equilibrateHistogram
, list
); break;
1566 do_cpt_double_err(xd
, eawhh_names
[i
], &state
->histSize
, list
); break;
1572 numPoints
= biasHistory
->pointState
.size();
1574 do_cpt_int_err(xd
, eawhh_names
[i
], &numPoints
, list
);
1577 biasHistory
->pointState
.resize(numPoints
);
1581 case eawhhCOORDPOINT
:
1582 for (auto &psh
: biasHistory
->pointState
)
1584 do_cpt_double_err(xd
, eawhh_names
[i
], &psh
.target
, list
);
1585 do_cpt_double_err(xd
, eawhh_names
[i
], &psh
.free_energy
, list
);
1586 do_cpt_double_err(xd
, eawhh_names
[i
], &psh
.bias
, list
);
1587 do_cpt_double_err(xd
, eawhh_names
[i
], &psh
.weightsum_iteration
, list
);
1588 do_cpt_double_err(xd
, eawhh_names
[i
], &psh
.weightsum_covering
, list
);
1589 do_cpt_double_err(xd
, eawhh_names
[i
], &psh
.weightsum_tot
, list
);
1590 do_cpt_double_err(xd
, eawhh_names
[i
], &psh
.weightsum_ref
, list
);
1591 do_cpt_step_err(xd
, eawhh_names
[i
], &psh
.last_update_index
, list
);
1592 do_cpt_double_err(xd
, eawhh_names
[i
], &psh
.log_pmfsum
, list
);
1593 do_cpt_double_err(xd
, eawhh_names
[i
], &psh
.visits_iteration
, list
);
1594 do_cpt_double_err(xd
, eawhh_names
[i
], &psh
.visits_tot
, list
);
1597 case eawhhUMBRELLAGRIDPOINT
:
1598 do_cpt_int_err(xd
, eawhh_names
[i
], &(state
->umbrellaGridpoint
), list
); break;
1599 case eawhhUPDATELIST
:
1600 do_cpt_int_err(xd
, eawhh_names
[i
], &(state
->origin_index_updatelist
), list
);
1601 do_cpt_int_err(xd
, eawhh_names
[i
], &(state
->end_index_updatelist
), list
);
1603 case eawhhLOGSCALEDSAMPLEWEIGHT
:
1604 do_cpt_double_err(xd
, eawhh_names
[i
], &(state
->logScaledSampleWeight
), list
);
1605 do_cpt_double_err(xd
, eawhh_names
[i
], &(state
->maxLogScaledSampleWeight
), list
);
1607 case eawhhNUMUPDATES
:
1608 do_cpt_step_err(xd
, eawhh_names
[i
], &(state
->numUpdates
), list
);
1610 case eawhhFORCECORRELATIONGRID
:
1611 ret
= do_cpt_correlation_grid(xd
, bRead
, fflags
, &biasHistory
->forceCorrelationGrid
, list
, i
);
1614 gmx_fatal(FARGS
, "Unknown awh history entry %d\n", i
);
1622 static int do_cpt_awh(XDR
*xd
, gmx_bool bRead
,
1623 int fflags
, gmx::AwhHistory
*awhHistory
,
1630 std::shared_ptr
<gmx::AwhHistory
> awhHistoryLocal
;
1632 if (awhHistory
== nullptr)
1634 GMX_RELEASE_ASSERT(bRead
, "do_cpt_awh should not be called for writing without an AwhHistory");
1636 awhHistoryLocal
= std::shared_ptr
<gmx::AwhHistory
>(new gmx::AwhHistory());
1637 awhHistory
= awhHistoryLocal
.get();
1640 /* To be able to read and write the AWH data several parameters determining the layout of the AWH structs need to be known
1641 (nbias, npoints, etc.). The best thing (?) would be to have these passed to this function. When writing to a checkpoint
1642 these parameters are available in awh_history (after calling init_awh_history). When reading from a checkpoint though, there
1643 is no initialized awh_history (it is initialized and set in this function). The AWH parameters have not always been read
1644 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
1645 when writing a checkpoint, also storing parameters needed for future reading of the checkpoint.
1647 Another issue is that some variables that AWH checkpoints don't have a registered enum and string (e.g. nbias below).
1648 One difficulty is the multilevel structure of the data which would need to be represented somehow. */
1653 numBias
= awhHistory
->bias
.size();
1655 do_cpt_int_err(xd
, "awh_nbias", &numBias
, list
);
1659 awhHistory
->bias
.resize(numBias
);
1661 for (auto &bias
: awhHistory
->bias
)
1663 ret
= do_cpt_awh_bias(xd
, bRead
, fflags
, &bias
, list
);
1669 do_cpt_double_err(xd
, "awh_potential_offset", &awhHistory
->potentialOffset
, list
);
1674 static int do_cpt_files(XDR
*xd
, gmx_bool bRead
,
1675 std::vector
<gmx_file_position_t
> *outputfiles
,
1676 FILE *list
, int file_version
)
1679 gmx_off_t mask
= 0xFFFFFFFFL
;
1680 int offset_high
, offset_low
;
1682 GMX_RELEASE_ASSERT(outputfiles
, "Must have valid outputfiles");
1684 // Ensure that reading pre-allocates outputfiles, while writing
1685 // writes what is already there.
1686 int nfiles
= outputfiles
->size();
1687 if (do_cpt_int(xd
, "number of output files", &nfiles
, list
) != 0)
1693 outputfiles
->resize(nfiles
);
1696 for (auto &outputfile
: *outputfiles
)
1698 /* 64-bit XDR numbers are not portable, so it is stored as separate high/low fractions */
1701 do_cpt_string_err(xd
, bRead
, "output filename", &buf
, list
);
1702 std::strncpy(outputfile
.filename
, buf
, CPTSTRLEN
-1);
1703 if (list
== nullptr)
1708 if (do_cpt_int(xd
, "file_offset_high", &offset_high
, list
) != 0)
1712 if (do_cpt_int(xd
, "file_offset_low", &offset_low
, list
) != 0)
1716 outputfile
.offset
= (static_cast<gmx_off_t
>(offset_high
) << 32 ) | ( static_cast<gmx_off_t
>(offset_low
) & mask
);
1720 buf
= outputfile
.filename
;
1721 do_cpt_string_err(xd
, bRead
, "output filename", &buf
, list
);
1723 offset
= outputfile
.offset
;
1731 offset_low
= static_cast<int>(offset
& mask
);
1732 offset_high
= static_cast<int>((offset
>> 32) & mask
);
1734 if (do_cpt_int(xd
, "file_offset_high", &offset_high
, list
) != 0)
1738 if (do_cpt_int(xd
, "file_offset_low", &offset_low
, list
) != 0)
1743 if (file_version
>= 8)
1745 if (do_cpt_int(xd
, "file_checksum_size", &outputfile
.chksum_size
,
1750 if (do_cpt_u_chars(xd
, "file_checksum", 16, outputfile
.chksum
, list
) != 0)
1757 outputfile
.chksum_size
= -1;
1764 void write_checkpoint(const char *fn
, gmx_bool bNumberAndKeep
,
1765 FILE *fplog
, t_commrec
*cr
,
1766 ivec domdecCells
, int nppnodes
,
1767 int eIntegrator
, int simulation_part
,
1768 gmx_bool bExpanded
, int elamstats
,
1769 gmx_int64_t step
, double t
,
1770 t_state
*state
, ObservablesHistory
*observablesHistory
)
1780 char *fntemp
; /* the temporary checkpoint file name */
1781 char timebuf
[STRLEN
];
1783 char buf
[1024], suffix
[5+STEPSTRSIZE
], sbuf
[STEPSTRSIZE
];
1787 if (DOMAINDECOMP(cr
))
1789 npmenodes
= cr
->npmenodes
;
1797 /* make the new temporary filename */
1798 snew(fntemp
, std::strlen(fn
)+5+STEPSTRSIZE
);
1799 std::strcpy(fntemp
, fn
);
1800 fntemp
[std::strlen(fn
) - std::strlen(ftp2ext(fn2ftp(fn
))) - 1] = '\0';
1801 sprintf(suffix
, "_%s%s", "step", gmx_step_str(step
, sbuf
));
1802 std::strcat(fntemp
, suffix
);
1803 std::strcat(fntemp
, fn
+std::strlen(fn
) - std::strlen(ftp2ext(fn2ftp(fn
))) - 1);
1805 /* if we can't rename, we just overwrite the cpt file.
1806 * dangerous if interrupted.
1808 snew(fntemp
, std::strlen(fn
));
1809 std::strcpy(fntemp
, fn
);
1811 gmx_format_current_time(timebuf
, STRLEN
);
1815 fprintf(fplog
, "Writing checkpoint, step %s at %s\n\n",
1816 gmx_step_str(step
, buf
), timebuf
);
1819 /* Get offsets for open files */
1820 auto outputfiles
= gmx_fio_get_output_file_positions();
1822 fp
= gmx_fio_open(fntemp
, "w");
1825 if (state
->ekinstate
.bUpToDate
)
1828 ((1<<eeksEKIN_N
) | (1<<eeksEKINH
) | (1<<eeksEKINF
) |
1829 (1<<eeksEKINO
) | (1<<eeksEKINSCALEF
) | (1<<eeksEKINSCALEH
) |
1830 (1<<eeksVSCALE
) | (1<<eeksDEKINDL
) | (1<<eeksMVCOS
));
1837 energyhistory_t
*enerhist
= observablesHistory
->energyHistory
.get();
1839 if (enerhist
!= nullptr && (enerhist
->nsum
> 0 || enerhist
->nsum_sim
> 0))
1841 flags_enh
|= (1<<eenhENERGY_N
) | (1<<eenhENERGY_NSTEPS
) | (1<<eenhENERGY_NSTEPS_SIM
);
1842 if (enerhist
->nsum
> 0)
1844 flags_enh
|= ((1<<eenhENERGY_AVER
) | (1<<eenhENERGY_SUM
) |
1845 (1<<eenhENERGY_NSUM
));
1847 if (enerhist
->nsum_sim
> 0)
1849 flags_enh
|= ((1<<eenhENERGY_SUM_SIM
) | (1<<eenhENERGY_NSUM_SIM
));
1851 if (enerhist
->deltaHForeignLambdas
!= nullptr)
1853 flags_enh
|= ( (1<< eenhENERGY_DELTA_H_NN
) |
1854 (1<< eenhENERGY_DELTA_H_LIST
) |
1855 (1<< eenhENERGY_DELTA_H_STARTTIME
) |
1856 (1<< eenhENERGY_DELTA_H_STARTLAMBDA
) );
1863 flags_dfh
= ((1<<edfhBEQUIL
) | (1<<edfhNATLAMBDA
) | (1<<edfhSUMWEIGHTS
) | (1<<edfhSUMDG
) |
1864 (1<<edfhTIJ
) | (1<<edfhTIJEMP
));
1867 flags_dfh
|= ((1<<edfhWLDELTA
) | (1<<edfhWLHISTO
));
1869 if ((elamstats
== elamstatsMINVAR
) || (elamstats
== elamstatsBARKER
) || (elamstats
== elamstatsMETROPOLIS
))
1871 flags_dfh
|= ((1<<edfhACCUMP
) | (1<<edfhACCUMM
) | (1<<edfhACCUMP2
) | (1<<edfhACCUMM2
)
1872 | (1<<edfhSUMMINVAR
) | (1<<edfhSUMVAR
));
1881 if (state
->awhHistory
!= nullptr && state
->awhHistory
->bias
.size() > 0)
1883 flags_awhh
|= ( (1 << eawhhIN_INITIAL
) |
1884 (1 << eawhhEQUILIBRATEHISTOGRAM
) |
1885 (1 << eawhhHISTSIZE
) |
1886 (1 << eawhhNPOINTS
) |
1887 (1 << eawhhCOORDPOINT
) |
1888 (1 << eawhhUMBRELLAGRIDPOINT
) |
1889 (1 << eawhhUPDATELIST
) |
1890 (1 << eawhhLOGSCALEDSAMPLEWEIGHT
) |
1891 (1 << eawhhNUMUPDATES
) |
1892 (1 << eawhhFORCECORRELATIONGRID
));
1895 /* We can check many more things now (CPU, acceleration, etc), but
1896 * it is highly unlikely to have two separate builds with exactly
1897 * the same version, user, time, and build host!
1900 version
= gmx_strdup(gmx_version());
1901 btime
= gmx_strdup(BUILD_TIME
);
1902 buser
= gmx_strdup(BUILD_USER
);
1903 bhost
= gmx_strdup(BUILD_HOST
);
1905 double_prec
= GMX_DOUBLE
;
1906 fprog
= gmx_strdup(gmx::getProgramContext().fullBinaryPath());
1908 ftime
= &(timebuf
[0]);
1910 int nlambda
= (state
->dfhist
? state
->dfhist
->nlambda
: 0);
1912 edsamhistory_t
*edsamhist
= observablesHistory
->edsamHistory
.get();
1913 int nED
= (edsamhist
? edsamhist
->nED
: 0);
1915 swaphistory_t
*swaphist
= observablesHistory
->swapHistory
.get();
1916 int eSwapCoords
= (swaphist
? swaphist
->eSwapCoords
: eswapNO
);
1918 do_cpt_header(gmx_fio_getxdr(fp
), FALSE
, &file_version
,
1919 &version
, &btime
, &buser
, &bhost
, &double_prec
, &fprog
, &ftime
,
1920 &eIntegrator
, &simulation_part
, &step
, &t
, &nppnodes
,
1921 DOMAINDECOMP(cr
) ? domdecCells
: nullptr, &npmenodes
,
1922 &state
->natoms
, &state
->ngtc
, &state
->nnhpres
,
1923 &state
->nhchainlength
, &nlambda
, &state
->flags
, &flags_eks
, &flags_enh
, &flags_dfh
, &flags_awhh
,
1933 if ((do_cpt_state(gmx_fio_getxdr(fp
), state
->flags
, state
, nullptr) < 0) ||
1934 (do_cpt_ekinstate(gmx_fio_getxdr(fp
), flags_eks
, &state
->ekinstate
, nullptr) < 0) ||
1935 (do_cpt_enerhist(gmx_fio_getxdr(fp
), FALSE
, flags_enh
, enerhist
, nullptr) < 0) ||
1936 (do_cpt_df_hist(gmx_fio_getxdr(fp
), flags_dfh
, nlambda
, &state
->dfhist
, nullptr) < 0) ||
1937 (do_cpt_EDstate(gmx_fio_getxdr(fp
), FALSE
, nED
, edsamhist
, nullptr) < 0) ||
1938 (do_cpt_awh(gmx_fio_getxdr(fp
), FALSE
, flags_awhh
, state
->awhHistory
.get(), NULL
) < 0) ||
1939 (do_cpt_swapstate(gmx_fio_getxdr(fp
), FALSE
, eSwapCoords
, swaphist
, nullptr) < 0) ||
1940 (do_cpt_files(gmx_fio_getxdr(fp
), FALSE
, &outputfiles
, nullptr,
1943 gmx_file("Cannot read/write checkpoint; corrupt file, or maybe you are out of disk space?");
1946 do_cpt_footer(gmx_fio_getxdr(fp
), file_version
);
1948 /* we really, REALLY, want to make sure to physically write the checkpoint,
1949 and all the files it depends on, out to disk. Because we've
1950 opened the checkpoint with gmx_fio_open(), it's in our list
1952 ret
= gmx_fio_all_output_fsync();
1958 "Cannot fsync '%s'; maybe you are out of disk space?",
1959 gmx_fio_getname(ret
));
1961 if (getenv(GMX_IGNORE_FSYNC_FAILURE_ENV
) == nullptr)
1971 if (gmx_fio_close(fp
) != 0)
1973 gmx_file("Cannot read/write checkpoint; corrupt file, or maybe you are out of disk space?");
1976 /* we don't move the checkpoint if the user specified they didn't want it,
1977 or if the fsyncs failed */
1979 if (!bNumberAndKeep
&& !ret
)
1983 /* Rename the previous checkpoint file */
1984 std::strcpy(buf
, fn
);
1985 buf
[std::strlen(fn
) - std::strlen(ftp2ext(fn2ftp(fn
))) - 1] = '\0';
1986 std::strcat(buf
, "_prev");
1987 std::strcat(buf
, fn
+std::strlen(fn
) - std::strlen(ftp2ext(fn2ftp(fn
))) - 1);
1989 /* we copy here so that if something goes wrong between now and
1990 * the rename below, there's always a state.cpt.
1991 * If renames are atomic (such as in POSIX systems),
1992 * this copying should be unneccesary.
1994 gmx_file_copy(fn
, buf
, FALSE
);
1995 /* We don't really care if this fails:
1996 * there's already a new checkpoint.
1999 gmx_file_rename(fn
, buf
);
2002 if (gmx_file_rename(fntemp
, fn
) != 0)
2004 gmx_file("Cannot rename checkpoint file; maybe you are out of disk space?");
2007 #endif /* GMX_NO_RENAME */
2012 /*code for alternate checkpointing scheme. moved from top of loop over
2014 fcRequestCheckPoint();
2015 if (fcCheckPointParallel( cr
->nodeid
, NULL
, 0) == 0)
2017 gmx_fatal( 3, __FILE__
, __LINE__
, "Checkpoint error on step %d\n", step
);
2019 #endif /* end GMX_FAHCORE block */
2022 static void print_flag_mismatch(FILE *fplog
, int sflags
, int fflags
)
2026 fprintf(fplog
, "\nState entry mismatch between the simulation and the checkpoint file\n");
2027 fprintf(fplog
, "Entries which are not present in the checkpoint file will not be updated\n");
2028 fprintf(fplog
, " %24s %11s %11s\n", "", "simulation", "checkpoint");
2029 for (i
= 0; i
< estNR
; i
++)
2031 if ((sflags
& (1<<i
)) || (fflags
& (1<<i
)))
2033 fprintf(fplog
, " %24s %11s %11s\n",
2035 (sflags
& (1<<i
)) ? " present " : "not present",
2036 (fflags
& (1<<i
)) ? " present " : "not present");
2041 static void check_int(FILE *fplog
, const char *type
, int p
, int f
, gmx_bool
*mm
)
2043 FILE *fp
= fplog
? fplog
: stderr
;
2047 fprintf(fp
, " %s mismatch,\n", type
);
2048 fprintf(fp
, " current program: %d\n", p
);
2049 fprintf(fp
, " checkpoint file: %d\n", f
);
2055 static void check_string(FILE *fplog
, const char *type
, const char *p
,
2056 const char *f
, gmx_bool
*mm
)
2058 FILE *fp
= fplog
? fplog
: stderr
;
2060 if (std::strcmp(p
, f
) != 0)
2062 fprintf(fp
, " %s mismatch,\n", type
);
2063 fprintf(fp
, " current program: %s\n", p
);
2064 fprintf(fp
, " checkpoint file: %s\n", f
);
2070 static void check_match(FILE *fplog
,
2072 char *btime
, char *buser
, char *bhost
, int double_prec
,
2074 const t_commrec
*cr
, int npp_f
, int npme_f
,
2075 const ivec dd_nc
, const ivec dd_nc_f
,
2076 gmx_bool reproducibilityRequested
)
2078 /* Note that this check_string on the version will also print a message
2079 * when only the minor version differs. But we only print a warning
2080 * message further down with reproducibilityRequested=TRUE.
2082 gmx_bool versionDiffers
= FALSE
;
2083 check_string(fplog
, "Version", gmx_version(), version
, &versionDiffers
);
2085 gmx_bool precisionDiffers
= FALSE
;
2086 check_int (fplog
, "Double prec.", GMX_DOUBLE
, double_prec
, &precisionDiffers
);
2087 if (precisionDiffers
)
2089 const char msg_precision_difference
[] =
2090 "You are continuing a simulation with a different precision. Not matching\n"
2091 "single/double precision will lead to precision or performance loss.\n";
2092 fprintf(stderr
, "%s\n", msg_precision_difference
);
2095 fprintf(fplog
, "%s\n", msg_precision_difference
);
2099 gmx_bool mm
= (versionDiffers
|| precisionDiffers
);
2101 if (reproducibilityRequested
)
2103 check_string(fplog
, "Build time", BUILD_TIME
, btime
, &mm
);
2104 check_string(fplog
, "Build user", BUILD_USER
, buser
, &mm
);
2105 check_string(fplog
, "Build host", BUILD_HOST
, bhost
, &mm
);
2106 check_string(fplog
, "Program name", gmx::getProgramContext().fullBinaryPath(), fprog
, &mm
);
2108 check_int (fplog
, "#ranks", cr
->nnodes
, npp_f
+npme_f
, &mm
);
2111 if (cr
->nnodes
> 1 && reproducibilityRequested
)
2113 check_int (fplog
, "#PME-ranks", cr
->npmenodes
, npme_f
, &mm
);
2115 int npp
= cr
->nnodes
;
2116 if (cr
->npmenodes
>= 0)
2118 npp
-= cr
->npmenodes
;
2122 check_int (fplog
, "#DD-cells[x]", dd_nc
[XX
], dd_nc_f
[XX
], &mm
);
2123 check_int (fplog
, "#DD-cells[y]", dd_nc
[YY
], dd_nc_f
[YY
], &mm
);
2124 check_int (fplog
, "#DD-cells[z]", dd_nc
[ZZ
], dd_nc_f
[ZZ
], &mm
);
2130 /* Gromacs should be able to continue from checkpoints between
2131 * different patch level versions, but we do not guarantee
2132 * compatibility between different major/minor versions - check this.
2136 sscanf(gmx_version(), "%5d", &gmx_major
);
2137 int ret
= sscanf(version
, "%5d", &cpt_major
);
2138 gmx_bool majorVersionDiffers
= (ret
< 1 || gmx_major
!= cpt_major
);
2140 const char msg_major_version_difference
[] =
2141 "The current GROMACS major version is not identical to the one that\n"
2142 "generated the checkpoint file. In principle GROMACS does not support\n"
2143 "continuation from checkpoints between different versions, so we advise\n"
2144 "against this. If you still want to try your luck we recommend that you use\n"
2145 "the -noappend flag to keep your output files from the two versions separate.\n"
2146 "This might also work around errors where the output fields in the energy\n"
2147 "file have changed between the different versions.\n";
2149 const char msg_mismatch_notice
[] =
2150 "GROMACS patchlevel, binary or parallel settings differ from previous run.\n"
2151 "Continuation is exact, but not guaranteed to be binary identical.\n";
2153 const char msg_logdetails
[] =
2154 "See the log file for details.\n";
2156 if (majorVersionDiffers
)
2158 fprintf(stderr
, "%s%s\n", msg_major_version_difference
, fplog
? msg_logdetails
: "");
2162 fprintf(fplog
, "%s\n", msg_major_version_difference
);
2165 else if (reproducibilityRequested
)
2167 /* Major & minor versions match at least, but something is different. */
2168 fprintf(stderr
, "%s%s\n", msg_mismatch_notice
, fplog
? msg_logdetails
: "");
2171 fprintf(fplog
, "%s\n", msg_mismatch_notice
);
2177 static void read_checkpoint(const char *fn
, FILE **pfplog
,
2178 const t_commrec
*cr
,
2180 int eIntegrator
, int *init_fep_state
, gmx_int64_t
*step
, double *t
,
2181 t_state
*state
, gmx_bool
*bReadEkin
,
2182 ObservablesHistory
*observablesHistory
,
2183 int *simulation_part
,
2184 gmx_bool bAppendOutputFiles
, gmx_bool bForceAppend
,
2185 gmx_bool reproducibilityRequested
)
2190 char *version
, *btime
, *buser
, *bhost
, *fprog
, *ftime
;
2192 char buf
[STEPSTRSIZE
];
2193 int eIntegrator_f
, nppnodes_f
, npmenodes_f
;
2195 int natoms
, ngtc
, nnhpres
, nhchainlength
, nlambda
, fflags
, flags_eks
, flags_enh
, flags_dfh
, flags_awhh
;
2196 int nED
, eSwapCoords
;
2198 t_fileio
*chksum_file
;
2199 FILE * fplog
= *pfplog
;
2200 unsigned char digest
[16];
2201 #if !defined __native_client__ && !GMX_NATIVE_WINDOWS
2202 struct flock fl
; /* don't initialize here: the struct order is OS
2206 const char *int_warn
=
2207 "WARNING: The checkpoint file was generated with integrator %s,\n"
2208 " while the simulation uses integrator %s\n\n";
2210 #if !defined __native_client__ && !GMX_NATIVE_WINDOWS
2211 fl
.l_type
= F_WRLCK
;
2212 fl
.l_whence
= SEEK_SET
;
2218 fp
= gmx_fio_open(fn
, "r");
2219 do_cpt_header(gmx_fio_getxdr(fp
), TRUE
, &file_version
,
2220 &version
, &btime
, &buser
, &bhost
, &double_prec
, &fprog
, &ftime
,
2221 &eIntegrator_f
, simulation_part
, step
, t
,
2222 &nppnodes_f
, dd_nc_f
, &npmenodes_f
,
2223 &natoms
, &ngtc
, &nnhpres
, &nhchainlength
, &nlambda
,
2224 &fflags
, &flags_eks
, &flags_enh
, &flags_dfh
, &flags_awhh
,
2225 &nED
, &eSwapCoords
, nullptr);
2227 if (bAppendOutputFiles
&&
2228 file_version
>= 13 && double_prec
!= GMX_DOUBLE
)
2230 gmx_fatal(FARGS
, "Output file appending requested, but the code and checkpoint file precision (single/double) don't match");
2233 if (cr
== nullptr || MASTER(cr
))
2235 fprintf(stderr
, "\nReading checkpoint file %s generated: %s\n\n",
2239 /* This will not be written if we do appending, since fplog is still NULL then */
2242 fprintf(fplog
, "\n");
2243 fprintf(fplog
, "Reading checkpoint file %s\n", fn
);
2244 fprintf(fplog
, " file generated by: %s\n", fprog
);
2245 fprintf(fplog
, " file generated at: %s\n", ftime
);
2246 fprintf(fplog
, " GROMACS build time: %s\n", btime
);
2247 fprintf(fplog
, " GROMACS build user: %s\n", buser
);
2248 fprintf(fplog
, " GROMACS build host: %s\n", bhost
);
2249 fprintf(fplog
, " GROMACS double prec.: %d\n", double_prec
);
2250 fprintf(fplog
, " simulation part #: %d\n", *simulation_part
);
2251 fprintf(fplog
, " step: %s\n", gmx_step_str(*step
, buf
));
2252 fprintf(fplog
, " time: %f\n", *t
);
2253 fprintf(fplog
, "\n");
2256 if (natoms
!= state
->natoms
)
2258 gmx_fatal(FARGS
, "Checkpoint file is for a system of %d atoms, while the current system consists of %d atoms", natoms
, state
->natoms
);
2260 if (ngtc
!= state
->ngtc
)
2262 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
);
2264 if (nnhpres
!= state
->nnhpres
)
2266 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
);
2269 int nlambdaHistory
= (state
->dfhist
? state
->dfhist
->nlambda
: 0);
2270 if (nlambda
!= nlambdaHistory
)
2272 gmx_fatal(FARGS
, "Checkpoint file is for a system with %d lambda states, while the current system consists of %d lambda states", nlambda
, nlambdaHistory
);
2275 init_gtc_state(state
, state
->ngtc
, state
->nnhpres
, nhchainlength
); /* need to keep this here to keep the tpr format working */
2276 /* write over whatever was read; we use the number of Nose-Hoover chains from the checkpoint */
2278 if (eIntegrator_f
!= eIntegrator
)
2282 fprintf(stderr
, int_warn
, EI(eIntegrator_f
), EI(eIntegrator
));
2284 if (bAppendOutputFiles
)
2287 "Output file appending requested, but input/checkpoint integrators do not match.\n"
2288 "Stopping the run to prevent you from ruining all your data...\n"
2289 "If you _really_ know what you are doing, try with the -noappend option.\n");
2293 fprintf(fplog
, int_warn
, EI(eIntegrator_f
), EI(eIntegrator
));
2297 if (fflags
!= state
->flags
)
2302 if (bAppendOutputFiles
)
2305 "Output file appending requested, but input and checkpoint states are not identical.\n"
2306 "Stopping the run to prevent you from ruining all your data...\n"
2307 "You can try with the -noappend option, and get more info in the log file.\n");
2310 if (getenv("GMX_ALLOW_CPT_MISMATCH") == nullptr)
2312 gmx_fatal(FARGS
, "You seem to have switched ensemble, integrator, T and/or P-coupling algorithm between the cpt and tpr file, or switched GROMACS version. 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");
2317 "WARNING: The checkpoint state entries do not match the simulation,\n"
2318 " see the log file for details\n\n");
2324 print_flag_mismatch(fplog
, state
->flags
, fflags
);
2331 check_match(fplog
, version
, btime
, buser
, bhost
, double_prec
, fprog
,
2332 cr
, nppnodes_f
, npmenodes_f
, dd_nc
, dd_nc_f
,
2333 reproducibilityRequested
);
2336 ret
= do_cpt_state(gmx_fio_getxdr(fp
), fflags
, state
, nullptr);
2337 *init_fep_state
= state
->fep_state
; /* there should be a better way to do this than setting it here.
2338 Investigate for 5.0. */
2343 ret
= do_cpt_ekinstate(gmx_fio_getxdr(fp
), flags_eks
, &state
->ekinstate
, nullptr);
2348 *bReadEkin
= ((flags_eks
& (1<<eeksEKINH
)) || (flags_eks
& (1<<eeksEKINF
)) || (flags_eks
& (1<<eeksEKINO
)) ||
2349 ((flags_eks
& (1<<eeksEKINSCALEF
)) | (flags_eks
& (1<<eeksEKINSCALEH
)) | (flags_eks
& (1<<eeksVSCALE
))));
2351 if (flags_enh
&& observablesHistory
->energyHistory
== nullptr)
2353 observablesHistory
->energyHistory
= std::unique_ptr
<energyhistory_t
>(new energyhistory_t
{});
2355 ret
= do_cpt_enerhist(gmx_fio_getxdr(fp
), TRUE
,
2356 flags_enh
, observablesHistory
->energyHistory
.get(), nullptr);
2362 if (file_version
< 6)
2364 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.";
2366 fprintf(stderr
, "\nWARNING: %s\n\n", warn
);
2369 fprintf(fplog
, "\nWARNING: %s\n\n", warn
);
2371 observablesHistory
->energyHistory
->nsum
= *step
;
2372 observablesHistory
->energyHistory
->nsum_sim
= *step
;
2375 ret
= do_cpt_df_hist(gmx_fio_getxdr(fp
), flags_dfh
, nlambda
, &state
->dfhist
, nullptr);
2381 if (nED
> 0 && observablesHistory
->edsamHistory
== nullptr)
2383 observablesHistory
->edsamHistory
= std::unique_ptr
<edsamhistory_t
>(new edsamhistory_t
{});
2385 ret
= do_cpt_EDstate(gmx_fio_getxdr(fp
), TRUE
, nED
, observablesHistory
->edsamHistory
.get(), nullptr);
2391 if (flags_awhh
!= 0 && state
->awhHistory
== nullptr)
2393 state
->awhHistory
= std::shared_ptr
<gmx::AwhHistory
>(new gmx::AwhHistory());
2395 ret
= do_cpt_awh(gmx_fio_getxdr(fp
), TRUE
,
2396 flags_awhh
, state
->awhHistory
.get(), NULL
);
2402 if (eSwapCoords
!= eswapNO
&& observablesHistory
->swapHistory
== nullptr)
2404 observablesHistory
->swapHistory
= std::unique_ptr
<swaphistory_t
>(new swaphistory_t
{});
2406 ret
= do_cpt_swapstate(gmx_fio_getxdr(fp
), TRUE
, eSwapCoords
, observablesHistory
->swapHistory
.get(), nullptr);
2412 std::vector
<gmx_file_position_t
> outputfiles
;
2413 ret
= do_cpt_files(gmx_fio_getxdr(fp
), TRUE
, &outputfiles
, nullptr, file_version
);
2419 ret
= do_cpt_footer(gmx_fio_getxdr(fp
), file_version
);
2424 if (gmx_fio_close(fp
) != 0)
2426 gmx_file("Cannot read/write checkpoint; corrupt file, or maybe you are out of disk space?");
2435 /* If the user wants to append to output files,
2436 * we use the file pointer positions of the output files stored
2437 * in the checkpoint file and truncate the files such that any frames
2438 * written after the checkpoint time are removed.
2439 * All files are md5sum checked such that we can be sure that
2440 * we do not truncate other (maybe imprortant) files.
2442 if (bAppendOutputFiles
)
2444 if (outputfiles
.empty())
2446 gmx_fatal(FARGS
, "No names of output files were recorded in the checkpoint");
2448 if (fn2ftp(outputfiles
[0].filename
) != efLOG
)
2450 /* make sure first file is log file so that it is OK to use it for
2453 gmx_fatal(FARGS
, "The first output file should always be the log "
2454 "file but instead is: %s. Cannot do appending because of this condition.", outputfiles
[0].filename
);
2456 bool firstFile
= true;
2457 for (const auto &outputfile
: outputfiles
)
2459 if (outputfile
.offset
< 0)
2461 gmx_fatal(FARGS
, "The original run wrote a file called '%s' which "
2462 "is larger than 2 GB, but mdrun did not support large file"
2463 " offsets. Can not append. Run mdrun with -noappend",
2464 outputfile
.filename
);
2467 chksum_file
= gmx_fio_open(outputfile
.filename
, "a");
2470 chksum_file
= gmx_fio_open(outputfile
.filename
, "r+");
2475 /* Note that there are systems where the lock operation
2476 * will succeed, but a second process can also lock the file.
2477 * We should probably try to detect this.
2479 #if defined __native_client__
2483 #elif GMX_NATIVE_WINDOWS
2484 if (_locking(fileno(gmx_fio_getfp(chksum_file
)), _LK_NBLCK
, LONG_MAX
) == -1)
2486 if (fcntl(fileno(gmx_fio_getfp(chksum_file
)), F_SETLK
, &fl
) == -1)
2489 if (errno
== ENOSYS
)
2493 gmx_fatal(FARGS
, "File locking is not supported on this system. Use -noappend or specify -append explicitly to append anyhow.");
2497 fprintf(stderr
, "\nNOTE: File locking is not supported on this system, will not lock %s\n\n", outputfile
.filename
);
2500 fprintf(fplog
, "\nNOTE: File locking not supported on this system, will not lock %s\n\n", outputfile
.filename
);
2504 else if (errno
== EACCES
|| errno
== EAGAIN
)
2506 gmx_fatal(FARGS
, "Failed to lock: %s. Already running "
2507 "simulation?", outputfile
.filename
);
2511 gmx_fatal(FARGS
, "Failed to lock: %s. %s.",
2512 outputfile
.filename
, std::strerror(errno
));
2517 /* compute md5 chksum */
2518 if (outputfile
.chksum_size
!= -1)
2520 if (gmx_fio_get_file_md5(chksum_file
, outputfile
.offset
,
2521 digest
) != outputfile
.chksum_size
) /*at the end of the call the file position is at the end of the file*/
2523 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.",
2524 outputfile
.chksum_size
,
2525 outputfile
.filename
);
2528 /* log file needs to be seeked in case we need to truncate
2529 * (other files are truncated below)*/
2532 if (gmx_fio_seek(chksum_file
, outputfile
.offset
))
2534 gmx_fatal(FARGS
, "Seek error! Failed to truncate log-file: %s.", std::strerror(errno
));
2539 /* open log file here - so that lock is never lifted
2540 * after chksum is calculated */
2543 *pfplog
= gmx_fio_getfp(chksum_file
);
2547 gmx_fio_close(chksum_file
);
2550 /* compare md5 chksum */
2551 if (outputfile
.chksum_size
!= -1 &&
2552 memcmp(digest
, outputfile
.chksum
, 16) != 0)
2556 fprintf(debug
, "chksum for %s: ", outputfile
.filename
);
2557 for (j
= 0; j
< 16; j
++)
2559 fprintf(debug
, "%02x", digest
[j
]);
2561 fprintf(debug
, "\n");
2563 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.",
2564 outputfile
.filename
);
2569 if (!firstFile
) /* log file is already seeked to correct position */
2571 #if !GMX_NATIVE_WINDOWS || !defined(GMX_FAHCORE)
2572 /* For FAHCORE, we do this elsewhere*/
2573 rc
= gmx_truncate(outputfile
.filename
, outputfile
.offset
);
2576 gmx_fatal(FARGS
, "Truncation of file %s failed. Cannot do appending because of this failure.", outputfile
.filename
);
2586 void load_checkpoint(const char *fn
, FILE **fplog
,
2587 const t_commrec
*cr
, const ivec dd_nc
,
2588 t_inputrec
*ir
, t_state
*state
,
2589 gmx_bool
*bReadEkin
,
2590 ObservablesHistory
*observablesHistory
,
2591 gmx_bool bAppend
, gmx_bool bForceAppend
,
2592 gmx_bool reproducibilityRequested
)
2599 /* Read the state from the checkpoint file */
2600 read_checkpoint(fn
, fplog
,
2602 ir
->eI
, &(ir
->fepvals
->init_fep_state
), &step
, &t
,
2603 state
, bReadEkin
, observablesHistory
,
2604 &ir
->simulation_part
, bAppend
, bForceAppend
,
2605 reproducibilityRequested
);
2609 gmx_bcast(sizeof(step
), &step
, cr
);
2610 gmx_bcast(sizeof(*bReadEkin
), bReadEkin
, cr
);
2612 ir
->bContinuation
= TRUE
;
2613 if (ir
->nsteps
>= 0)
2615 ir
->nsteps
+= ir
->init_step
- step
;
2617 ir
->init_step
= step
;
2618 ir
->simulation_part
+= 1;
2621 void read_checkpoint_part_and_step(const char *filename
,
2622 int *simulation_part
,
2626 char *version
, *btime
, *buser
, *bhost
, *fprog
, *ftime
;
2632 int flags_eks
, flags_enh
, flags_dfh
, flags_awhh
;
2635 int nED
, eSwapCoords
;
2638 if (filename
== nullptr ||
2639 !gmx_fexist(filename
) ||
2640 (!(fp
= gmx_fio_open(filename
, "r"))))
2642 *simulation_part
= 0;
2647 /* Not calling initializing state before use is nasty, but all we
2648 do is read into its member variables and throw the struct away
2649 again immediately. */
2651 do_cpt_header(gmx_fio_getxdr(fp
), TRUE
, &file_version
,
2652 &version
, &btime
, &buser
, &bhost
, &double_prec
, &fprog
, &ftime
,
2653 &eIntegrator
, simulation_part
, step
, &t
, &nppnodes
, dd_nc
, &npme
,
2654 &state
.natoms
, &state
.ngtc
, &state
.nnhpres
, &state
.nhchainlength
,
2655 &nlambda
, &state
.flags
, &flags_eks
, &flags_enh
, &flags_dfh
, &flags_awhh
,
2656 &nED
, &eSwapCoords
, nullptr);
2661 static void read_checkpoint_data(t_fileio
*fp
, int *simulation_part
,
2662 gmx_int64_t
*step
, double *t
, t_state
*state
,
2663 std::vector
<gmx_file_position_t
> *outputfiles
)
2666 char *version
, *btime
, *buser
, *bhost
, *fprog
, *ftime
;
2672 int flags_eks
, flags_enh
, flags_dfh
, flags_awhh
;
2673 int nED
, eSwapCoords
;
2676 do_cpt_header(gmx_fio_getxdr(fp
), TRUE
, &file_version
,
2677 &version
, &btime
, &buser
, &bhost
, &double_prec
, &fprog
, &ftime
,
2678 &eIntegrator
, simulation_part
, step
, t
, &nppnodes
, dd_nc
, &npme
,
2679 &state
->natoms
, &state
->ngtc
, &state
->nnhpres
, &state
->nhchainlength
,
2680 &nlambda
, &state
->flags
, &flags_eks
, &flags_enh
, &flags_dfh
, &flags_awhh
,
2681 &nED
, &eSwapCoords
, nullptr);
2683 do_cpt_state(gmx_fio_getxdr(fp
), state
->flags
, state
, nullptr);
2688 ret
= do_cpt_ekinstate(gmx_fio_getxdr(fp
), flags_eks
, &state
->ekinstate
, nullptr);
2694 energyhistory_t enerhist
;
2695 ret
= do_cpt_enerhist(gmx_fio_getxdr(fp
), TRUE
,
2696 flags_enh
, &enerhist
, nullptr);
2701 ret
= do_cpt_df_hist(gmx_fio_getxdr(fp
), flags_dfh
, nlambda
, &state
->dfhist
, nullptr);
2707 edsamhistory_t edsamhist
= {};
2708 ret
= do_cpt_EDstate(gmx_fio_getxdr(fp
), TRUE
, nED
, &edsamhist
, nullptr);
2714 ret
= do_cpt_awh(gmx_fio_getxdr(fp
), TRUE
,
2715 flags_awhh
, state
->awhHistory
.get(), NULL
);
2721 swaphistory_t swaphist
= {};
2722 ret
= do_cpt_swapstate(gmx_fio_getxdr(fp
), TRUE
, eSwapCoords
, &swaphist
, nullptr);
2728 ret
= do_cpt_files(gmx_fio_getxdr(fp
), TRUE
,
2730 nullptr, file_version
);
2737 ret
= do_cpt_footer(gmx_fio_getxdr(fp
), file_version
);
2750 void read_checkpoint_trxframe(t_fileio
*fp
, t_trxframe
*fr
)
2753 int simulation_part
;
2757 std::vector
<gmx_file_position_t
> outputfiles
;
2758 read_checkpoint_data(fp
, &simulation_part
, &step
, &t
, &state
, &outputfiles
);
2760 fr
->natoms
= state
.natoms
;
2762 fr
->step
= gmx_int64_to_int(step
,
2763 "conversion of checkpoint to trajectory");
2767 fr
->lambda
= state
.lambda
[efptFEP
];
2768 fr
->fep_state
= state
.fep_state
;
2770 fr
->bX
= (state
.flags
& (1<<estX
));
2773 fr
->x
= makeRvecArray(state
.x
, state
.natoms
);
2775 fr
->bV
= (state
.flags
& (1<<estV
));
2778 fr
->v
= makeRvecArray(state
.v
, state
.natoms
);
2781 fr
->bBox
= (state
.flags
& (1<<estBOX
));
2784 copy_mat(state
.box
, fr
->box
);
2788 void list_checkpoint(const char *fn
, FILE *out
)
2792 char *version
, *btime
, *buser
, *bhost
, *fprog
, *ftime
;
2794 int eIntegrator
, simulation_part
, nppnodes
, npme
;
2799 int flags_eks
, flags_enh
, flags_dfh
, flags_awhh
;;
2800 int nED
, eSwapCoords
;
2805 fp
= gmx_fio_open(fn
, "r");
2806 do_cpt_header(gmx_fio_getxdr(fp
), TRUE
, &file_version
,
2807 &version
, &btime
, &buser
, &bhost
, &double_prec
, &fprog
, &ftime
,
2808 &eIntegrator
, &simulation_part
, &step
, &t
, &nppnodes
, dd_nc
, &npme
,
2809 &state
.natoms
, &state
.ngtc
, &state
.nnhpres
, &state
.nhchainlength
,
2810 &nlambda
, &state
.flags
,
2811 &flags_eks
, &flags_enh
, &flags_dfh
, &flags_awhh
, &nED
, &eSwapCoords
,
2813 ret
= do_cpt_state(gmx_fio_getxdr(fp
), state
.flags
, &state
, out
);
2818 ret
= do_cpt_ekinstate(gmx_fio_getxdr(fp
), flags_eks
, &state
.ekinstate
, out
);
2824 energyhistory_t enerhist
;
2825 ret
= do_cpt_enerhist(gmx_fio_getxdr(fp
), TRUE
,
2826 flags_enh
, &enerhist
, out
);
2830 ret
= do_cpt_df_hist(gmx_fio_getxdr(fp
),
2831 flags_dfh
, nlambda
, &state
.dfhist
, out
);
2836 edsamhistory_t edsamhist
= {};
2837 ret
= do_cpt_EDstate(gmx_fio_getxdr(fp
), TRUE
, nED
, &edsamhist
, out
);
2842 ret
= do_cpt_awh(gmx_fio_getxdr(fp
), TRUE
,
2843 flags_awhh
, state
.awhHistory
.get(), out
);
2848 swaphistory_t swaphist
= {};
2849 ret
= do_cpt_swapstate(gmx_fio_getxdr(fp
), TRUE
, eSwapCoords
, &swaphist
, out
);
2854 std::vector
<gmx_file_position_t
> outputfiles
;
2855 ret
= do_cpt_files(gmx_fio_getxdr(fp
), TRUE
, &outputfiles
, out
, file_version
);
2860 ret
= do_cpt_footer(gmx_fio_getxdr(fp
), file_version
);
2867 if (gmx_fio_close(fp
) != 0)
2869 gmx_file("Cannot read/write checkpoint; corrupt file, or maybe you are out of disk space?");
2873 /* This routine cannot print tons of data, since it is called before the log file is opened. */
2875 read_checkpoint_simulation_part_and_filenames(t_fileio
*fp
,
2876 int *simulation_part
,
2877 std::vector
<gmx_file_position_t
> *outputfiles
)
2879 gmx_int64_t step
= 0;
2883 read_checkpoint_data(fp
, simulation_part
, &step
, &t
, &state
, outputfiles
);
2884 if (gmx_fio_close(fp
) != 0)
2886 gmx_file("Cannot read/write checkpoint; corrupt file, or maybe you are out of disk space?");