2 * This file is part of the GROMACS molecular simulation package.
4 * Copyright (c) 2008,2009,2010,2011,2012 by the GROMACS development team.
5 * Copyright (c) 2013,2014,2015,2016,2017 by the GROMACS development team.
6 * Copyright (c) 2018,2019,2020,2021, by the GROMACS development team, led by
7 * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
8 * and including many others, as listed in the AUTHORS file in the
9 * top-level source directory and at http://www.gromacs.org.
11 * GROMACS is free software; you can redistribute it and/or
12 * modify it under the terms of the GNU Lesser General Public License
13 * as published by the Free Software Foundation; either version 2.1
14 * of the License, or (at your option) any later version.
16 * GROMACS is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19 * Lesser General Public License for more details.
21 * You should have received a copy of the GNU Lesser General Public
22 * License along with GROMACS; if not, see
23 * http://www.gnu.org/licenses, or write to the Free Software Foundation,
24 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
26 * If you want to redistribute modifications to GROMACS, please
27 * consider that scientific software is very special. Version
28 * control is crucial - bugs must be traceable. We will be happy to
29 * consider code for inclusion in the official distribution, but
30 * derived work must not be called official GROMACS. Details are found
31 * in the README & COPYING files - if they are missing, get the
32 * official version at http://www.gromacs.org.
34 * To help us fund GROMACS development, we humbly ask that you cite
35 * the research papers on the package. Check out http://www.gromacs.org.
38 /* The source code in this file should be thread-safe.
39 Please keep it that way. */
42 #include "checkpoint.h"
51 #include "buildinfo.h"
52 #include "gromacs/fileio/filetypes.h"
53 #include "gromacs/fileio/gmxfio.h"
54 #include "gromacs/fileio/gmxfio_xdr.h"
55 #include "gromacs/fileio/xdr_datatype.h"
56 #include "gromacs/fileio/xdrf.h"
57 #include "gromacs/gmxlib/network.h"
58 #include "gromacs/math/vec.h"
59 #include "gromacs/math/vecdump.h"
60 #include "gromacs/math/vectypes.h"
61 #include "gromacs/mdtypes/awh_correlation_history.h"
62 #include "gromacs/mdtypes/awh_history.h"
63 #include "gromacs/mdtypes/checkpointdata.h"
64 #include "gromacs/mdtypes/commrec.h"
65 #include "gromacs/mdtypes/df_history.h"
66 #include "gromacs/mdtypes/edsamhistory.h"
67 #include "gromacs/mdtypes/energyhistory.h"
68 #include "gromacs/mdtypes/inputrec.h"
69 #include "gromacs/mdtypes/md_enums.h"
70 #include "gromacs/mdtypes/mdrunoptions.h"
71 #include "gromacs/mdtypes/observableshistory.h"
72 #include "gromacs/mdtypes/pullhistory.h"
73 #include "gromacs/mdtypes/state.h"
74 #include "gromacs/mdtypes/swaphistory.h"
75 #include "gromacs/modularsimulator/modularsimulator.h"
76 #include "gromacs/trajectory/trajectoryframe.h"
77 #include "gromacs/utility/arrayref.h"
78 #include "gromacs/utility/baseversion.h"
79 #include "gromacs/utility/cstringutil.h"
80 #include "gromacs/utility/enumerationhelpers.h"
81 #include "gromacs/utility/fatalerror.h"
82 #include "gromacs/utility/futil.h"
83 #include "gromacs/utility/gmxassert.h"
84 #include "gromacs/utility/int64_to_int.h"
85 #include "gromacs/utility/keyvaluetree.h"
86 #include "gromacs/utility/keyvaluetreebuilder.h"
87 #include "gromacs/utility/keyvaluetreeserializer.h"
88 #include "gromacs/utility/mdmodulesnotifiers.h"
89 #include "gromacs/utility/programcontext.h"
90 #include "gromacs/utility/smalloc.h"
91 #include "gromacs/utility/sysinfo.h"
92 #include "gromacs/utility/textwriter.h"
93 #include "gromacs/utility/txtdump.h"
95 #define CPT_MAGIC1 171817
96 #define CPT_MAGIC2 171819
101 template<typename ValueType>
102 void readKvtCheckpointValue(compat::not_null<ValueType*> value,
103 const std::string& name,
104 const std::string& identifier,
105 const KeyValueTreeObject& kvt)
107 const std::string key = identifier + "-" + name;
108 if (!kvt.keyExists(key))
110 std::string errorMessage = "Cannot read requested checkpoint value " + key + " .";
111 GMX_THROW(InternalError(errorMessage));
113 *value = kvt[key].cast<ValueType>();
116 template void readKvtCheckpointValue(compat::not_null<std::int64_t*> value,
117 const std::string& name,
118 const std::string& identifier,
119 const KeyValueTreeObject& kvt);
120 template void readKvtCheckpointValue(compat::not_null<real*> value,
121 const std::string& name,
122 const std::string& identifier,
123 const KeyValueTreeObject& kvt);
125 template<typename ValueType>
126 void writeKvtCheckpointValue(const ValueType& value,
127 const std::string& name,
128 const std::string& identifier,
129 KeyValueTreeObjectBuilder kvtBuilder)
131 kvtBuilder.addValue<ValueType>(identifier + "-" + name, value);
134 template void writeKvtCheckpointValue(const std::int64_t& value,
135 const std::string& name,
136 const std::string& identifier,
137 KeyValueTreeObjectBuilder kvtBuilder);
138 template void writeKvtCheckpointValue(const real& value,
139 const std::string& name,
140 const std::string& identifier,
141 KeyValueTreeObjectBuilder kvtBuilder);
146 /*! \brief Version number of the file format written to checkpoint
147 * files by this version of the code.
149 * cpt_version should normally only be changed, via adding a new field
150 * to cptv enumeration, when the header or footer format changes.
152 * The state data format itself is backward and forward compatible.
153 * But old code can not read a new entry that is present in the file
154 * (but can read a new format when new entries are not present).
156 * The cpt_version increases whenever the file format in the main
157 * development branch changes, due to an extension of the CheckPointVersion
158 * enum (see src/gromacs/fileio/checkpoint.h).
159 * Backward compatibility for reading old run input files is maintained
160 * by checking this version number against that of the file and then using
161 * the correct code path. */
162 static constexpr CheckPointVersion cpt_version = CheckPointVersion::CurrentVersion;
164 const char* enumValueToString(StateEntry enumValue)
166 static constexpr gmx::EnumerationArray<StateEntry, const char*> stateEntryNames = {
173 "thermostat-integral",
178 "LD-rng-unsupported",
179 "LD-rng-i-unsupported",
192 "MC-rng-unsupported",
193 "MC-rng-i-unsupported",
196 return stateEntryNames[enumValue];
199 enum class StateKineticEntry : int
207 EkinNoseHooverScaleFullStep,
208 EkinNoseHooverScaleHalfStep,
214 static const char* enumValueToString(StateKineticEntry enumValue)
216 static constexpr gmx::EnumerationArray<StateKineticEntry, const char*> stateKineticEntryNames = {
217 "Ekin_n", "Ekinh", "dEkindlambda", "mv_cos", "Ekinf",
218 "Ekinh_old", "EkinScaleF_NHC", "EkinScaleH_NHC", "Vscale_NHC", "Ekin_Total"
220 return stateKineticEntryNames[enumValue];
223 enum class StateEnergyEntry : int
240 enum class StatePullEntry : int
249 enum class StatePullCoordEntry : int
261 static const char* enumValueToString(StatePullCoordEntry enumValue)
263 static constexpr gmx::EnumerationArray<StatePullCoordEntry, const char*> statePullCoordEntryNames = {
264 "reference-sum", "sum", "dr01-sum", "dr23-sum", "dr45-sum", "fscal-sum", "dynax-sum"
266 return statePullCoordEntryNames[enumValue];
269 enum class StatePullGroupEntry : int
275 static const char* enumValueToString(StatePullGroupEntry enumValue)
277 static constexpr gmx::EnumerationArray<StatePullGroupEntry, const char*> statePullGroupEntryNames = {
280 return statePullGroupEntryNames[enumValue];
283 static const char* enumValueToString(StateEnergyEntry enumValue)
285 static constexpr gmx::EnumerationArray<StateEnergyEntry, const char*> stateEnergyEntryNames = {
295 "energy_delta_h_list",
296 "energy_delta_h_start_time",
297 "energy_delta_h_start_lambda"
299 return stateEnergyEntryNames[enumValue];
302 static const char* enumValueToString(StatePullEntry enumValue)
304 static constexpr gmx::EnumerationArray<StatePullEntry, const char*> statePullEntryNames = {
305 "pullhistory_numcoordinates",
306 "pullhistory_numgroups",
307 "pullhistory_numvaluesinxsum",
308 "pullhistory_numvaluesinfsum"
310 return statePullEntryNames[enumValue];
313 /* free energy history variables -- need to be preserved over checkpoint */
314 enum class StateFepEntry : int
333 //! free energy history names
334 static const char* enumValueToString(StateFepEntry enumValue)
336 static constexpr gmx::EnumerationArray<StateFepEntry, const char*> stateFepEntryNames = {
339 "Wang-Landau Histogram",
347 "accumulated_plus_2",
348 "accumulated_minus_2",
352 return stateFepEntryNames[enumValue];
355 //! AWH biasing history variables
356 enum class StateAwhEntry : int
359 EquilibrateHistogram,
365 LogScaledSampleWeight,
367 ForceCorrelationGrid,
371 static const char* enumValueToString(StateAwhEntry enumValue)
373 static constexpr gmx::EnumerationArray<StateAwhEntry, const char*> stateAwhEntryNames = {
374 "awh_in_initial", "awh_equilibrateHistogram", "awh_histsize", "awh_npoints",
375 "awh_coordpoint", "awh_umbrellaGridpoint", "awh_updatelist", "awh_logScaledSampleWeight",
376 "awh_numupdates", "awh_forceCorrelationGrid"
378 return stateAwhEntryNames[enumValue];
381 enum class StatePullCommunicationEntry : int
387 //! Higher level vector element type, only used for formatting checkpoint dumps
388 enum class CptElementType
390 integer, //!< integer
391 real, //!< float or double, not linked to precision of type real
392 real3, //!< float[3] or double[3], not linked to precision of type real
393 matrix3x3 //!< float[3][3] or double[3][3], not linked to precision of type real
396 static void cp_warning(FILE* fp)
398 fprintf(fp, "\nWARNING: Checkpoint file is corrupted or truncated\n\n");
401 [[noreturn]] static void cp_error()
403 gmx_fatal(FARGS, "Checkpoint file corrupted/truncated, or maybe you are out of disk space?");
406 static void do_cpt_string_err(XDR* xd, const char* desc, gmx::ArrayRef<char> s, FILE* list)
408 char* data = s.data();
409 if (xdr_string(xd, &data, s.size()) == 0)
415 fprintf(list, "%s = %s\n", desc, data);
419 static int do_cpt_int(XDR* xd, const char* desc, int* i, FILE* list)
421 if (xdr_int(xd, i) == 0)
427 fprintf(list, "%s = %d\n", desc, *i);
432 static int do_cpt_u_chars(XDR* xd, const char* desc, int n, unsigned char* i, FILE* list)
436 fprintf(list, "%s = ", desc);
439 for (int j = 0; j < n && res; j++)
441 res &= xdr_u_char(xd, &i[j]);
444 fprintf(list, "%02x", i[j]);
459 template<typename EnumType>
460 static int do_cpt_enum_as_int(XDR* xd, const char* desc, EnumType* enumValue, FILE* list)
462 static_assert(std::is_same<std::underlying_type_t<EnumType>, int>::value,
463 "Only enums with underlying type int are supported.");
464 auto castedValue = static_cast<int>(*enumValue);
465 if (xdr_int(xd, &castedValue) == 0)
469 *enumValue = static_cast<EnumType>(castedValue);
472 fprintf(list, "%s = %d\n", desc, castedValue);
477 template<typename EnumType>
478 static int do_cpt_n_enum_as_int(XDR* xd, const char* desc, int n, EnumType* enumValue, FILE* list)
481 for (int j = 0; j < n && res; j++)
483 res &= do_cpt_enum_as_int<EnumType>(xd, desc, &enumValue[j], list);
493 static void do_cpt_int_err(XDR* xd, const char* desc, int* i, FILE* list)
495 if (do_cpt_int(xd, desc, i, list) < 0)
501 static void do_cpt_bool_err(XDR* xd, const char* desc, bool* b, FILE* list)
503 int i = static_cast<int>(*b);
505 if (do_cpt_int(xd, desc, &i, list) < 0)
513 static void do_cpt_step_err(XDR* xd, const char* desc, int64_t* i, FILE* list)
515 char buf[STEPSTRSIZE];
517 if (xdr_int64(xd, i) == 0)
523 fprintf(list, "%s = %s\n", desc, gmx_step_str(*i, buf));
527 static void do_cpt_double_err(XDR* xd, const char* desc, double* f, FILE* list)
529 if (xdr_double(xd, f) == 0)
535 fprintf(list, "%s = %f\n", desc, *f);
539 static void do_cpt_real_err(XDR* xd, real* f)
542 bool_t res = xdr_double(xd, f);
544 bool_t res = xdr_float(xd, f);
552 static void do_cpt_n_rvecs_err(XDR* xd, const char* desc, int n, rvec f[], FILE* list)
554 for (int i = 0; i < n; i++)
556 for (int j = 0; j < DIM; j++)
558 do_cpt_real_err(xd, &f[i][j]);
564 pr_rvecs(list, 0, desc, f, n);
576 static const XdrDataType value = XdrDataType::Int;
580 struct xdr_type<float>
582 static const XdrDataType value = XdrDataType::Float;
586 struct xdr_type<double>
588 static const XdrDataType value = XdrDataType::Double;
591 //! \brief Returns size in byte of an XdrDataType
592 static inline unsigned int sizeOfXdrType(XdrDataType xdrType)
596 case XdrDataType::Int: return sizeof(int);
597 case XdrDataType::Float: return sizeof(float);
598 case XdrDataType::Double: return sizeof(double);
599 default: GMX_RELEASE_ASSERT(false, "XDR data type not implemented");
605 //! \brief Returns the XDR process function for i/o of an XDR type
606 static inline xdrproc_t xdrProc(XdrDataType xdrType)
610 case XdrDataType::Int: return reinterpret_cast<xdrproc_t>(xdr_int);
611 case XdrDataType::Float: return reinterpret_cast<xdrproc_t>(xdr_float);
612 case XdrDataType::Double: return reinterpret_cast<xdrproc_t>(xdr_double);
613 default: GMX_RELEASE_ASSERT(false, "XDR data type not implemented");
619 /*! \brief Lists or only reads an xdr vector from checkpoint file
621 * When list!=NULL reads and lists the \p nf vector elements of type \p xdrType.
622 * The header for the print is set by \p part and \p ecpt.
623 * The formatting of the printing is set by \p cptElementType.
624 * When list==NULL only reads the elements.
626 template<typename Enum>
627 static bool_t listXdrVector(XDR* xd, Enum ecpt, int nf, XdrDataType xdrType, FILE* list, CptElementType cptElementType)
631 const unsigned int elemSize = sizeOfXdrType(xdrType);
632 std::vector<char> data(nf * elemSize);
633 res = xdr_vector(xd, data.data(), nf, elemSize, xdrProc(xdrType));
639 case XdrDataType::Int:
640 pr_ivec(list, 0, enumValueToString(ecpt), reinterpret_cast<const int*>(data.data()), nf, TRUE);
642 case XdrDataType::Float:
644 if (cptElementType == CptElementType::real3)
646 pr_rvecs(list, 0, enumValueToString(ecpt), reinterpret_cast<const rvec*>(data.data()), nf / 3);
651 /* Note: With double precision code dumping a single precision rvec will produce float iso rvec print, but that's a minor annoyance */
652 pr_fvec(list, 0, enumValueToString(ecpt), reinterpret_cast<const float*>(data.data()), nf, TRUE);
655 case XdrDataType::Double:
657 if (cptElementType == CptElementType::real3)
659 pr_rvecs(list, 0, enumValueToString(ecpt), reinterpret_cast<const rvec*>(data.data()), nf / 3);
664 /* Note: With single precision code dumping a double precision rvec will produce float iso rvec print, but that's a minor annoyance */
665 pr_dvec(list, 0, enumValueToString(ecpt), reinterpret_cast<const double*>(data.data()), nf, TRUE);
668 default: GMX_RELEASE_ASSERT(false, "Data type not implemented for listing");
675 //! \brief Convert a double array, typed char*, to float
676 gmx_unused static void convertArrayRealPrecision(const char* c, float* v, int n)
678 const double* d = reinterpret_cast<const double*>(c);
679 for (int i = 0; i < n; i++)
681 v[i] = static_cast<float>(d[i]);
685 //! \brief Convert a float array, typed char*, to double
686 static void convertArrayRealPrecision(const char* c, double* v, int n)
688 const float* f = reinterpret_cast<const float*>(c);
689 for (int i = 0; i < n; i++)
691 v[i] = static_cast<double>(f[i]);
695 //! \brief Generate an error for trying to convert to integer
696 static void convertArrayRealPrecision(const char gmx_unused* c, int gmx_unused* v, int gmx_unused n)
698 GMX_RELEASE_ASSERT(false,
699 "We only expect type mismatches between float and double, not integer");
702 /*! \brief Low-level routine for reading/writing a vector of reals from/to file.
704 * This is the only routine that does the actually i/o of real vector,
705 * all other routines are intermediate level routines for specific real
706 * data types, calling this routine.
707 * Currently this routine is (too) complex, since it handles both real *
708 * and std::vector<real>. Using real * is deprecated and this routine
709 * will simplify a lot when only std::vector needs to be supported.
711 * The routine is generic to vectors with different allocators,
712 * because as part of reading a checkpoint there are vectors whose
713 * size is not known until reading has progressed far enough, so a
714 * resize method must be called.
716 * When not listing, we use either v or vector, depending on which is !=NULL.
717 * If nval >= 0, nval is used; on read this should match the passed value.
718 * If nval n<0, *nptr (with v) or vector->size() is used. On read using v,
719 * the value is stored in nptr
721 template<typename T, typename AllocatorType, typename Enum>
722 static int doVectorLow(XDR* xd,
728 std::vector<T, AllocatorType>* vector,
730 CptElementType cptElementType)
732 GMX_RELEASE_ASSERT(list != nullptr || (v != nullptr && vector == nullptr)
733 || (v == nullptr && vector != nullptr),
734 "Without list, we should have exactly one of v and vector != NULL");
738 int numElemInTheFile;
743 GMX_RELEASE_ASSERT(nptr == nullptr, "With nval>=0 we should have nptr==NULL");
744 numElemInTheFile = nval;
750 GMX_RELEASE_ASSERT(nptr != nullptr, "With nval<0 we should have nptr!=NULL");
751 numElemInTheFile = *nptr;
755 numElemInTheFile = vector->size();
759 /* Read/write the vector element count */
760 res = xdr_int(xd, &numElemInTheFile);
765 /* Read/write the element data type */
766 constexpr XdrDataType xdrTypeInTheCode = xdr_type<T>::value;
767 XdrDataType xdrTypeInTheFile = xdrTypeInTheCode;
768 int xdrTypeInTheFileAsInt = static_cast<int>(xdrTypeInTheFile);
769 res = xdr_int(xd, &xdrTypeInTheFileAsInt);
770 xdrTypeInTheFile = static_cast<XdrDataType>(xdrTypeInTheFileAsInt);
776 if (list == nullptr && (sflags & enumValueToBitMask(ecpt)))
780 if (numElemInTheFile != nval)
783 "Count mismatch for state entry %s, code count is %d, file count is %d\n",
784 enumValueToString(ecpt),
789 else if (nptr != nullptr)
791 *nptr = numElemInTheFile;
794 bool typesMatch = (xdrTypeInTheFile == xdrTypeInTheCode);
799 "mismatch for state entry %s, code precision is %s, file precision is %s",
800 enumValueToString(ecpt),
801 enumValueToString(xdrTypeInTheCode),
802 enumValueToString(xdrTypeInTheFile));
804 /* Matching int and real should never occur, but check anyhow */
805 if (xdrTypeInTheFile == XdrDataType::Int || xdrTypeInTheCode == XdrDataType::Int)
808 "Type %s: incompatible checkpoint formats or corrupted checkpoint file.",
818 snew(*v, numElemInTheFile);
824 /* This conditional ensures that we don't resize on write.
825 * In particular in the state where this code was written
826 * vector has a size of numElemInThefile and we
827 * don't want to lose that padding here.
829 if (vector->size() < static_cast<unsigned int>(numElemInTheFile))
831 vector->resize(numElemInTheFile);
839 vChar = reinterpret_cast<char*>(vp);
843 snew(vChar, numElemInTheFile * sizeOfXdrType(xdrTypeInTheFile));
846 xd, vChar, numElemInTheFile, sizeOfXdrType(xdrTypeInTheFile), xdrProc(xdrTypeInTheFile));
854 /* In the old code float-double conversion came for free.
855 * In the new code we still support it, mainly because
856 * the tip4p_continue regression test makes use of this.
857 * It's an open question if we do or don't want to allow this.
859 convertArrayRealPrecision(vChar, vp, numElemInTheFile);
865 res = listXdrVector(xd, ecpt, numElemInTheFile, xdrTypeInTheFile, list, cptElementType);
871 //! \brief Read/Write a std::vector, on read checks the number of elements matches \p numElements, if specified.
872 template<typename T, typename Enum>
873 static int doVector(XDR* xd, Enum ecpt, int sflags, std::vector<T>* vector, FILE* list, int numElements = -1)
875 return doVectorLow<T>(
876 xd, ecpt, sflags, numElements, nullptr, nullptr, vector, list, CptElementType::real);
879 //! \brief Read/Write an ArrayRef<real>.
880 template<typename Enum>
881 static int doRealArrayRef(XDR* xd, Enum ecpt, int sflags, gmx::ArrayRef<real> vector, FILE* list)
883 real* v_real = vector.data();
884 return doVectorLow<real, std::allocator<real>>(
885 xd, ecpt, sflags, vector.size(), nullptr, &v_real, nullptr, list, CptElementType::real);
888 //! Convert from view of RVec to view of real.
889 static gmx::ArrayRef<real> realArrayRefFromRVecArrayRef(gmx::ArrayRef<gmx::RVec> ofRVecs)
891 return gmx::arrayRefFromArray<real>(reinterpret_cast<real*>(ofRVecs.data()), ofRVecs.size() * DIM);
894 //! \brief Read/Write a PaddedVector whose value_type is RVec.
895 template<typename PaddedVectorOfRVecType, typename Enum>
896 static int doRvecVector(XDR* xd, Enum ecpt, int sflags, PaddedVectorOfRVecType* v, int numAtoms, FILE* list)
898 const int numReals = numAtoms * DIM;
903 sflags & enumValueToBitMask(ecpt),
904 "When not listing, the flag for the entry should be set when requesting i/o");
905 GMX_RELEASE_ASSERT(v->size() == numAtoms, "v should have sufficient size for numAtoms");
907 return doRealArrayRef(xd, ecpt, sflags, realArrayRefFromRVecArrayRef(makeArrayRef(*v)), list);
911 // Use the rebind facility to change the value_type of the
912 // allocator from RVec to real.
913 using realAllocator =
914 typename std::allocator_traits<typename PaddedVectorOfRVecType::allocator_type>::template rebind_alloc<real>;
915 return doVectorLow<real, realAllocator>(
916 xd, ecpt, sflags, numReals, nullptr, nullptr, nullptr, list, CptElementType::real);
920 /* This function stores n along with the reals for reading,
921 * but on reading it assumes that n matches the value in the checkpoint file,
922 * a fatal error is generated when this is not the case.
924 template<typename Enum>
925 static int do_cpte_reals(XDR* xd, Enum ecpt, int sflags, int n, real** v, FILE* list)
927 return doVectorLow<real, std::allocator<real>>(
928 xd, ecpt, sflags, n, nullptr, v, nullptr, list, CptElementType::real);
931 template<typename Enum>
932 static int do_cpte_real(XDR* xd, Enum ecpt, int sflags, real* r, FILE* list)
934 return doVectorLow<real, std::allocator<real>>(
935 xd, ecpt, sflags, 1, nullptr, &r, nullptr, list, CptElementType::real);
938 template<typename Enum>
939 static int do_cpte_ints(XDR* xd, Enum ecpt, int sflags, int n, int** v, FILE* list)
941 return doVectorLow<int, std::allocator<int>>(
942 xd, ecpt, sflags, n, nullptr, v, nullptr, list, CptElementType::integer);
945 template<typename Enum>
946 static int do_cpte_int(XDR* xd, Enum ecpt, int sflags, int* i, FILE* list)
948 return do_cpte_ints(xd, ecpt, sflags, 1, &i, list);
951 template<typename Enum>
952 static int do_cpte_bool(XDR* xd, Enum ecpt, int sflags, bool* b, FILE* list)
954 int i = static_cast<int>(*b);
955 int ret = do_cpte_int(xd, ecpt, sflags, &i, list);
960 template<typename Enum>
961 static int do_cpte_doubles(XDR* xd, Enum ecpt, int sflags, int n, double** v, FILE* list)
963 return doVectorLow<double, std::allocator<double>>(
964 xd, ecpt, sflags, n, nullptr, v, nullptr, list, CptElementType::real);
967 template<typename Enum>
968 static int do_cpte_double(XDR* xd, Enum ecpt, int sflags, double* r, FILE* list)
970 return do_cpte_doubles(xd, ecpt, sflags, 1, &r, list);
973 template<typename Enum>
974 static int do_cpte_matrix(XDR* xd, Enum ecpt, int sflags, matrix v, FILE* list)
980 ret = doVectorLow<real, std::allocator<real>>(
981 xd, ecpt, sflags, DIM * DIM, nullptr, &vr, nullptr, nullptr, CptElementType::matrix3x3);
983 if (list && ret == 0)
985 pr_rvecs(list, 0, enumValueToString(ecpt), v, DIM);
991 template<typename Enum>
992 static int do_cpte_nmatrix(XDR* xd, Enum ecpt, int sflags, int n, real** v, FILE* list)
996 char name[CPTSTRLEN];
1003 for (i = 0; i < n; i++)
1005 reti = doVectorLow<real, std::allocator<real>>(
1006 xd, ecpt, sflags, n, nullptr, &(v[i]), nullptr, nullptr, CptElementType::matrix3x3);
1007 if (list && reti == 0)
1009 sprintf(name, "%s[%d]", enumValueToString(ecpt), i);
1010 pr_reals(list, 0, name, v[i], n);
1020 template<typename Enum>
1021 static int do_cpte_matrices(XDR* xd, Enum ecpt, int sflags, int n, matrix** v, FILE* list)
1024 matrix *vp, *va = nullptr;
1030 res = xdr_int(xd, &nf);
1035 if (list == nullptr && nf != n)
1038 "Count mismatch for state entry %s, code count is %d, file count is %d\n",
1039 enumValueToString(ecpt),
1043 if (list || !(sflags & enumValueToBitMask(ecpt)))
1056 snew(vr, nf * DIM * DIM);
1057 for (i = 0; i < nf; i++)
1059 for (j = 0; j < DIM; j++)
1061 for (k = 0; k < DIM; k++)
1063 vr[(i * DIM + j) * DIM + k] = vp[i][j][k];
1067 ret = doVectorLow<real, std::allocator<real>>(
1068 xd, ecpt, sflags, nf * DIM * DIM, nullptr, &vr, nullptr, nullptr, CptElementType::matrix3x3);
1069 for (i = 0; i < nf; i++)
1071 for (j = 0; j < DIM; j++)
1073 for (k = 0; k < DIM; k++)
1075 vp[i][j][k] = vr[(i * DIM + j) * DIM + k];
1081 if (list && ret == 0)
1083 for (i = 0; i < nf; i++)
1085 pr_rvecs(list, 0, enumValueToString(ecpt), vp[i], DIM);
1096 static void do_cpt_header(XDR* xd, gmx_bool bRead, FILE* list, CheckpointHeaderContents* contents)
1109 res = xdr_int(xd, &magic);
1113 "The checkpoint file is empty/corrupted, or maybe you are out of disk space?");
1115 if (magic != CPT_MAGIC1)
1118 "Start of file magic number mismatch, checkpoint file has %d, should be %d\n"
1119 "The checkpoint file is corrupted or not a checkpoint file",
1126 gmx_gethostname(fhost, 255);
1128 do_cpt_string_err(xd, "GROMACS version", contents->version, list);
1129 // The following fields are no longer ever written with meaningful
1130 // content, but because they precede the file version, there is no
1131 // good way for new code to read the old and new formats, nor a
1132 // good way for old code to avoid giving an error while reading a
1133 // new format. So we read and write a field that no longer has a
1135 do_cpt_string_err(xd, "GROMACS build time UNUSED", contents->btime_UNUSED, list);
1136 do_cpt_string_err(xd, "GROMACS build user UNUSED", contents->buser_UNUSED, list);
1137 do_cpt_string_err(xd, "GROMACS build host UNUSED", contents->bhost_UNUSED, list);
1138 do_cpt_string_err(xd, "generating program", contents->fprog, list);
1139 do_cpt_string_err(xd, "generation time", contents->ftime, list);
1140 contents->file_version = cpt_version;
1141 do_cpt_enum_as_int<CheckPointVersion>(xd, "checkpoint file version", &contents->file_version, list);
1142 if (contents->file_version > cpt_version)
1145 "Attempting to read a checkpoint file of version %d with code of version %d\n",
1146 static_cast<int>(contents->file_version),
1147 static_cast<int>(cpt_version));
1149 if (contents->file_version >= CheckPointVersion::DoublePrecisionBuild)
1151 do_cpt_int_err(xd, "GROMACS double precision", &contents->double_prec, list);
1155 contents->double_prec = -1;
1157 if (contents->file_version >= CheckPointVersion::HostInformation)
1159 do_cpt_string_err(xd, "generating host", fhost, list);
1161 do_cpt_int_err(xd, "#atoms", &contents->natoms, list);
1162 do_cpt_int_err(xd, "#T-coupling groups", &contents->ngtc, list);
1163 if (contents->file_version >= CheckPointVersion::NoseHooverThermostat)
1165 do_cpt_int_err(xd, "#Nose-Hoover T-chains", &contents->nhchainlength, list);
1169 contents->nhchainlength = 1;
1171 if (contents->file_version >= CheckPointVersion::NoseHooverBarostat)
1173 do_cpt_int_err(xd, "#Nose-Hoover T-chains for barostat ", &contents->nnhpres, list);
1177 contents->nnhpres = 0;
1179 if (contents->file_version >= CheckPointVersion::LambdaStateAndHistory)
1181 do_cpt_int_err(xd, "# of total lambda states ", &contents->nlambda, list);
1185 contents->nlambda = 0;
1188 int integrator = static_cast<int>(contents->eIntegrator);
1189 do_cpt_int_err(xd, "integrator", &integrator, list);
1192 contents->eIntegrator = static_cast<IntegrationAlgorithm>(integrator);
1195 if (contents->file_version >= CheckPointVersion::SafeSimulationPart)
1197 do_cpt_int_err(xd, "simulation part #", &contents->simulation_part, list);
1201 contents->simulation_part = 1;
1203 if (contents->file_version >= CheckPointVersion::SafeSteps)
1205 do_cpt_step_err(xd, "step", &contents->step, list);
1210 do_cpt_int_err(xd, "step", &idum, list);
1211 contents->step = static_cast<int64_t>(idum);
1213 do_cpt_double_err(xd, "t", &contents->t, list);
1214 do_cpt_int_err(xd, "#PP-ranks", &contents->nnodes, list);
1215 do_cpt_int_err(xd, "dd_nc[x]", &contents->dd_nc[XX], list);
1216 do_cpt_int_err(xd, "dd_nc[y]", &contents->dd_nc[YY], list);
1217 do_cpt_int_err(xd, "dd_nc[z]", &contents->dd_nc[ZZ], list);
1218 do_cpt_int_err(xd, "#PME-only ranks", &contents->npme, list);
1219 do_cpt_int_err(xd, "state flags", &contents->flags_state, list);
1220 if (contents->file_version >= CheckPointVersion::EkinDataAndFlags)
1222 do_cpt_int_err(xd, "ekin data flags", &contents->flags_eks, list);
1223 do_cpt_int_err(xd, "energy history flags", &contents->flags_enh, list);
1227 contents->flags_eks = 0;
1228 contents->flags_enh = (contents->flags_state >> (static_cast<int>(StateEntry::OrireDtav) + 1));
1229 contents->flags_state = (contents->flags_state
1230 & ~((1 << (static_cast<int>(StateEntry::OrireDtav) + 1))
1231 | (1 << (static_cast<int>(StateEntry::OrireDtav) + 2))
1232 | (1 << (static_cast<int>(StateEntry::OrireDtav) + 3))));
1234 if (contents->file_version >= CheckPointVersion::LambdaStateAndHistory)
1236 do_cpt_int_err(xd, "df history flags", &contents->flags_dfh, list);
1240 contents->flags_dfh = 0;
1243 if (contents->file_version >= CheckPointVersion::EssentialDynamics)
1245 do_cpt_int_err(xd, "ED data sets", &contents->nED, list);
1252 if (contents->file_version >= CheckPointVersion::SwapState)
1254 int swapState = static_cast<int>(contents->eSwapCoords);
1255 do_cpt_int_err(xd, "swap", &swapState, list);
1258 contents->eSwapCoords = static_cast<SwapType>(swapState);
1263 contents->eSwapCoords = SwapType::No;
1266 if (contents->file_version >= CheckPointVersion::AwhHistoryFlags)
1268 do_cpt_int_err(xd, "AWH history flags", &contents->flags_awhh, list);
1272 contents->flags_awhh = 0;
1275 if (contents->file_version >= CheckPointVersion::RemoveBuildMachineInformation)
1277 do_cpt_int_err(xd, "pull history flags", &contents->flagsPullHistory, list);
1281 contents->flagsPullHistory = 0;
1284 if (contents->file_version >= CheckPointVersion::ModularSimulator)
1287 xd, "Is modular simulator checkpoint", &contents->isModularSimulatorCheckpoint, list);
1291 contents->isModularSimulatorCheckpoint = false;
1295 static int do_cpt_footer(XDR* xd, CheckPointVersion file_version)
1300 if (file_version >= CheckPointVersion::AddMagicNumber)
1303 res = xdr_int(xd, &magic);
1308 if (magic != CPT_MAGIC2)
1317 static int do_cpt_state(XDR* xd, int fflags, t_state* state, FILE* list)
1320 const int sflags = state->flags;
1321 // If reading, state->natoms was probably just read, so
1322 // allocations need to be managed. If writing, this won't change
1323 // anything that matters.
1324 using StateFlags = gmx::EnumerationArray<StateEntry, bool>;
1325 state_change_natoms(state, state->natoms);
1326 for (auto i = StateFlags::keys().begin(); (i != StateFlags::keys().end() && ret == 0); i++)
1328 if (fflags & enumValueToBitMask(*i))
1332 case StateEntry::Lambda:
1333 ret = doRealArrayRef(xd, *i, sflags, state->lambda, list);
1335 case StateEntry::FepState:
1336 ret = do_cpte_int(xd, *i, sflags, &state->fep_state, list);
1338 case StateEntry::Box: ret = do_cpte_matrix(xd, *i, sflags, state->box, list); break;
1339 case StateEntry::BoxRel:
1340 ret = do_cpte_matrix(xd, *i, sflags, state->box_rel, list);
1342 case StateEntry::BoxV:
1343 ret = do_cpte_matrix(xd, *i, sflags, state->boxv, list);
1345 case StateEntry::PressurePrevious:
1346 ret = do_cpte_matrix(xd, *i, sflags, state->pres_prev, list);
1348 case StateEntry::SVirPrev:
1349 ret = do_cpte_matrix(xd, *i, sflags, state->svir_prev, list);
1351 case StateEntry::FVirPrev:
1352 ret = do_cpte_matrix(xd, *i, sflags, state->fvir_prev, list);
1354 case StateEntry::Nhxi:
1355 ret = doVector<double>(xd, *i, sflags, &state->nosehoover_xi, list);
1357 case StateEntry::Nhvxi:
1358 ret = doVector<double>(xd, *i, sflags, &state->nosehoover_vxi, list);
1360 case StateEntry::Nhpresxi:
1361 ret = doVector<double>(xd, *i, sflags, &state->nhpres_xi, list);
1363 case StateEntry::Nhpresvxi:
1364 ret = doVector<double>(xd, *i, sflags, &state->nhpres_vxi, list);
1366 case StateEntry::ThermInt:
1367 ret = doVector<double>(xd, *i, sflags, &state->therm_integral, list);
1369 case StateEntry::BarosInt:
1370 ret = do_cpte_double(xd, *i, sflags, &state->baros_integral, list);
1372 case StateEntry::Veta:
1373 ret = do_cpte_real(xd, *i, sflags, &state->veta, list);
1375 case StateEntry::Vol0:
1376 ret = do_cpte_real(xd, *i, sflags, &state->vol0, list);
1379 ret = doRvecVector(xd, *i, sflags, &state->x, state->natoms, list);
1382 ret = doRvecVector(xd, *i, sflags, &state->v, state->natoms, list);
1384 /* The RNG entries are no longer written,
1385 * the next 4 lines are only for reading old files.
1386 * It's OK that three case statements fall through.
1388 case StateEntry::LDRngNotSupported:
1389 case StateEntry::LDRngINotSupported:
1390 case StateEntry::MCRngNotSupported:
1391 case StateEntry::MCRngINotSupported:
1392 ret = do_cpte_ints(xd, *i, sflags, 0, nullptr, list);
1394 case StateEntry::DisreInitF:
1395 ret = do_cpte_real(xd, *i, sflags, &state->hist.disre_initf, list);
1397 case StateEntry::DisreRm3Tav:
1398 ret = doVector<real>(xd, *i, sflags, &state->hist.disre_rm3tav, list);
1400 case StateEntry::OrireInitF:
1401 ret = do_cpte_real(xd, *i, sflags, &state->hist.orire_initf, list);
1403 case StateEntry::OrireDtav:
1404 ret = doVector<real>(xd, *i, sflags, &state->hist.orire_Dtav, list);
1406 case StateEntry::PullComPrevStep:
1407 ret = doVector<double>(xd, *i, sflags, &state->pull_com_prev_step, list);
1411 "Unknown state entry %d\n"
1412 "You are reading a checkpoint file written by different code, which "
1414 enumValueToBitMask(*i));
1421 static int do_cpt_ekinstate(XDR* xd, int fflags, ekinstate_t* ekins, FILE* list)
1425 using StateFlags = gmx::EnumerationArray<StateKineticEntry, bool>;
1426 for (auto i = StateFlags::keys().begin(); (i != StateFlags::keys().end() && ret == 0); i++)
1428 if (fflags & enumValueToBitMask(*i))
1433 case StateKineticEntry::EkinNumber:
1434 ret = do_cpte_int(xd, *i, fflags, &ekins->ekin_n, list);
1436 case StateKineticEntry::EkinHalfStep:
1437 ret = do_cpte_matrices(xd, *i, fflags, ekins->ekin_n, &ekins->ekinh, list);
1439 case StateKineticEntry::EkinFullStep:
1440 ret = do_cpte_matrices(xd, *i, fflags, ekins->ekin_n, &ekins->ekinf, list);
1442 case StateKineticEntry::EkinHalfStepOld:
1443 ret = do_cpte_matrices(xd, *i, fflags, ekins->ekin_n, &ekins->ekinh_old, list);
1445 case StateKineticEntry::EkinTotal:
1446 ret = do_cpte_matrix(xd, *i, fflags, ekins->ekin_total, list);
1448 case StateKineticEntry::EkinNoseHooverScaleFullStep:
1449 ret = doVector<double>(xd, *i, fflags, &ekins->ekinscalef_nhc, list);
1451 case StateKineticEntry::VelocityScale:
1452 ret = doVector<double>(xd, *i, fflags, &ekins->vscale_nhc, list);
1454 case StateKineticEntry::EkinNoseHooverScaleHalfStep:
1455 ret = doVector<double>(xd, *i, fflags, &ekins->ekinscaleh_nhc, list);
1457 case StateKineticEntry::DEkinDLambda:
1458 ret = do_cpte_real(xd, *i, fflags, &ekins->dekindl, list);
1460 case StateKineticEntry::Mvcos:
1461 ret = do_cpte_real(xd, *i, fflags, &ekins->mvcos, list);
1465 "Unknown ekin data state entry %d\n"
1466 "You are probably reading a new checkpoint file with old code",
1467 enumValueToBitMask(*i));
1476 static int do_cpt_swapstate(XDR* xd, gmx_bool bRead, SwapType eSwapCoords, swaphistory_t* swapstate, FILE* list)
1478 int swap_cpt_version = 2;
1480 if (eSwapCoords == SwapType::No)
1485 swapstate->bFromCpt = bRead;
1486 swapstate->eSwapCoords = eSwapCoords;
1488 do_cpt_int_err(xd, "swap checkpoint version", &swap_cpt_version, list);
1489 if (bRead && swap_cpt_version < 2)
1492 "Cannot read checkpoint files that were written with old versions"
1493 "of the ion/water position swapping protocol.\n");
1496 do_cpt_int_err(xd, "swap coupling steps", &swapstate->nAverage, list);
1498 /* When reading, init_swapcoords has not been called yet,
1499 * so we have to allocate memory first. */
1500 do_cpt_int_err(xd, "number of ion types", &swapstate->nIonTypes, list);
1503 snew(swapstate->ionType, swapstate->nIonTypes);
1506 for (auto ic : gmx::EnumerationWrapper<Compartment>{})
1508 for (int ii = 0; ii < swapstate->nIonTypes; ii++)
1510 swapstateIons_t* gs = &swapstate->ionType[ii];
1514 do_cpt_int_err(xd, "swap requested atoms", &gs->nMolReq[ic], list);
1518 do_cpt_int_err(xd, "swap requested atoms p", gs->nMolReq_p[ic], list);
1523 do_cpt_int_err(xd, "swap influx net", &gs->inflow_net[ic], list);
1527 do_cpt_int_err(xd, "swap influx net p", gs->inflow_net_p[ic], list);
1530 if (bRead && (nullptr == gs->nMolPast[ic]))
1532 snew(gs->nMolPast[ic], swapstate->nAverage);
1535 for (int j = 0; j < swapstate->nAverage; j++)
1539 do_cpt_int_err(xd, "swap past atom counts", &gs->nMolPast[ic][j], list);
1543 do_cpt_int_err(xd, "swap past atom counts p", &gs->nMolPast_p[ic][j], list);
1549 /* Ion flux per channel */
1550 for (auto ic : gmx::EnumerationWrapper<Channel>{})
1552 for (int ii = 0; ii < swapstate->nIonTypes; ii++)
1554 swapstateIons_t* gs = &swapstate->ionType[ii];
1558 do_cpt_int_err(xd, "channel flux A->B", &gs->fluxfromAtoB[ic], list);
1562 do_cpt_int_err(xd, "channel flux A->B p", gs->fluxfromAtoB_p[ic], list);
1567 /* Ion flux leakage */
1570 do_cpt_int_err(xd, "flux leakage", &swapstate->fluxleak, list);
1574 do_cpt_int_err(xd, "flux leakage", swapstate->fluxleak_p, list);
1578 for (int ii = 0; ii < swapstate->nIonTypes; ii++)
1580 swapstateIons_t* gs = &swapstate->ionType[ii];
1582 do_cpt_int_err(xd, "number of ions", &gs->nMol, list);
1586 snew(gs->channel_label, gs->nMol);
1587 snew(gs->comp_from, gs->nMol);
1590 do_cpt_n_enum_as_int<ChannelHistory>(xd, "channel history", gs->nMol, gs->channel_label, list);
1591 do_cpt_n_enum_as_int<Domain>(xd, "domain history", gs->nMol, gs->comp_from, list);
1594 /* Save the last known whole positions to checkpoint
1595 * file to be able to also make multimeric channels whole in PBC */
1596 do_cpt_int_err(xd, "Ch0 atoms", &swapstate->nat[Channel::Zero], list);
1597 do_cpt_int_err(xd, "Ch1 atoms", &swapstate->nat[Channel::One], list);
1600 snew(swapstate->xc_old_whole[Channel::Zero], swapstate->nat[Channel::Zero]);
1601 snew(swapstate->xc_old_whole[Channel::One], swapstate->nat[Channel::One]);
1603 xd, "Ch0 whole x", swapstate->nat[Channel::Zero], swapstate->xc_old_whole[Channel::Zero], list);
1605 xd, "Ch1 whole x", swapstate->nat[Channel::One], swapstate->xc_old_whole[Channel::One], list);
1609 do_cpt_n_rvecs_err(xd,
1611 swapstate->nat[Channel::Zero],
1612 *swapstate->xc_old_whole_p[Channel::Zero],
1615 xd, "Ch1 whole x", swapstate->nat[Channel::One], *swapstate->xc_old_whole_p[Channel::One], list);
1622 static int do_cpt_enerhist(XDR* xd, gmx_bool bRead, int fflags, energyhistory_t* enerhist, FILE* list)
1631 GMX_RELEASE_ASSERT(enerhist != nullptr, "With energy history, we need a valid enerhist pointer");
1633 /* This is stored/read for backward compatibility */
1634 int energyHistoryNumEnergies = 0;
1637 enerhist->nsteps = 0;
1639 enerhist->nsteps_sim = 0;
1640 enerhist->nsum_sim = 0;
1642 else if (enerhist != nullptr)
1644 energyHistoryNumEnergies = enerhist->ener_sum_sim.size();
1647 delta_h_history_t* deltaH = enerhist->deltaHForeignLambdas.get();
1648 using StateFlags = gmx::EnumerationArray<StateEnergyEntry, bool>;
1649 for (auto i = StateFlags::keys().begin(); (i != StateFlags::keys().end() && ret == 0); i++)
1651 if (fflags & enumValueToBitMask(*i))
1655 case StateEnergyEntry::N:
1656 ret = do_cpte_int(xd, *i, fflags, &energyHistoryNumEnergies, list);
1658 case StateEnergyEntry::Aver:
1659 ret = doVector<double>(xd, *i, fflags, &enerhist->ener_ave, list);
1661 case StateEnergyEntry::Sum:
1662 ret = doVector<double>(xd, *i, fflags, &enerhist->ener_sum, list);
1664 case StateEnergyEntry::NumSum:
1665 do_cpt_step_err(xd, enumValueToString(*i), &enerhist->nsum, list);
1667 case StateEnergyEntry::SumSim:
1668 ret = doVector<double>(xd, *i, fflags, &enerhist->ener_sum_sim, list);
1670 case StateEnergyEntry::NumSumSim:
1671 do_cpt_step_err(xd, enumValueToString(*i), &enerhist->nsum_sim, list);
1673 case StateEnergyEntry::NumSteps:
1674 do_cpt_step_err(xd, enumValueToString(*i), &enerhist->nsteps, list);
1676 case StateEnergyEntry::NumStepsSim:
1677 do_cpt_step_err(xd, enumValueToString(*i), &enerhist->nsteps_sim, list);
1679 case StateEnergyEntry::DeltaHNN:
1682 if (!bRead && deltaH != nullptr)
1684 numDeltaH = deltaH->dh.size();
1686 do_cpt_int_err(xd, enumValueToString(*i), &numDeltaH, list);
1689 if (deltaH == nullptr)
1691 enerhist->deltaHForeignLambdas = std::make_unique<delta_h_history_t>();
1692 deltaH = enerhist->deltaHForeignLambdas.get();
1694 deltaH->dh.resize(numDeltaH);
1695 deltaH->start_lambda_set = FALSE;
1699 case StateEnergyEntry::DeltaHList:
1700 for (auto dh : deltaH->dh)
1702 ret = doVector<real>(xd, *i, fflags, &dh, list);
1705 case StateEnergyEntry::DeltaHStartTime:
1706 ret = do_cpte_double(xd, *i, fflags, &(deltaH->start_time), list);
1708 case StateEnergyEntry::DeltaHStartLambda:
1709 ret = do_cpte_double(xd, *i, fflags, &(deltaH->start_lambda), list);
1713 "Unknown energy history entry %d\n"
1714 "You are probably reading a new checkpoint file with old code",
1715 enumValueToBitMask(*i));
1720 if ((fflags & enumValueToBitMask(StateEnergyEntry::Sum))
1721 && !(fflags & enumValueToBitMask(StateEnergyEntry::SumSim)))
1723 /* Assume we have an old file format and copy sum to sum_sim */
1724 enerhist->ener_sum_sim = enerhist->ener_sum;
1727 if ((fflags & enumValueToBitMask(StateEnergyEntry::NumSum))
1728 && !(fflags & enumValueToBitMask(StateEnergyEntry::NumSteps)))
1730 /* Assume we have an old file format and copy nsum to nsteps */
1731 enerhist->nsteps = enerhist->nsum;
1733 if ((fflags & enumValueToBitMask(StateEnergyEntry::NumSumSim))
1734 && !(fflags & enumValueToBitMask(StateEnergyEntry::NumStepsSim)))
1736 /* Assume we have an old file format and copy nsum to nsteps */
1737 enerhist->nsteps_sim = enerhist->nsum_sim;
1743 static int doCptPullCoordHist(XDR* xd, PullCoordinateHistory* pullCoordHist, FILE* list)
1748 flags |= (enumValueToBitMask(StatePullCoordEntry::ValueReferenceSum)
1749 | enumValueToBitMask(StatePullCoordEntry::ValueSum)
1750 | enumValueToBitMask(StatePullCoordEntry::DR01Sum)
1751 | enumValueToBitMask(StatePullCoordEntry::DR23Sum)
1752 | enumValueToBitMask(StatePullCoordEntry::DR45Sum)
1753 | enumValueToBitMask(StatePullCoordEntry::FScalarSum));
1755 using StateFlags = gmx::EnumerationArray<StatePullCoordEntry, bool>;
1756 for (auto i = StateFlags::keys().begin(); (i != StateFlags::keys().end() && ret == 0); i++)
1760 case StatePullCoordEntry::ValueReferenceSum:
1761 ret = do_cpte_double(xd, *i, flags, &(pullCoordHist->valueRef), list);
1763 case StatePullCoordEntry::ValueSum:
1764 ret = do_cpte_double(xd, *i, flags, &(pullCoordHist->value), list);
1766 case StatePullCoordEntry::DR01Sum:
1767 for (int j = 0; j < DIM && ret == 0; j++)
1769 ret = do_cpte_double(xd, *i, flags, &(pullCoordHist->dr01[j]), list);
1772 case StatePullCoordEntry::DR23Sum:
1773 for (int j = 0; j < DIM && ret == 0; j++)
1775 ret = do_cpte_double(xd, *i, flags, &(pullCoordHist->dr23[j]), list);
1778 case StatePullCoordEntry::DR45Sum:
1779 for (int j = 0; j < DIM && ret == 0; j++)
1781 ret = do_cpte_double(xd, *i, flags, &(pullCoordHist->dr45[j]), list);
1784 case StatePullCoordEntry::FScalarSum:
1785 ret = do_cpte_double(xd, *i, flags, &(pullCoordHist->scalarForce), list);
1787 case StatePullCoordEntry::DynaxSum:
1788 for (int j = 0; j < DIM && ret == 0; j++)
1790 ret = do_cpte_double(xd, *i, flags, &(pullCoordHist->dynaX[j]), list);
1794 gmx_fatal(FARGS, "Unhandled StatePullCoordEntry enum value: %d", enumValueToBitMask(*i));
1801 static int doCptPullGroupHist(XDR* xd, PullGroupHistory* pullGroupHist, FILE* list)
1806 flags |= (enumValueToBitMask(StatePullGroupEntry::XSum));
1808 using StateFlags = gmx::EnumerationArray<StatePullGroupEntry, bool>;
1809 for (auto i = StateFlags::keys().begin(); (i != StateFlags::keys().end() && ret == 0); i++)
1813 case StatePullGroupEntry::XSum:
1814 for (int j = 0; j < DIM && ret == 0; j++)
1816 ret = do_cpte_double(xd, *i, flags, &(pullGroupHist->x[j]), list);
1819 default: gmx_fatal(FARGS, "Unhandled pull group state entry");
1827 static int doCptPullHist(XDR* xd, gmx_bool bRead, int fflags, PullHistory* pullHist, FILE* list)
1830 int pullHistoryNumCoordinates = 0;
1831 int pullHistoryNumGroups = 0;
1833 /* Retain the number of terms in the sum and the number of coordinates (used for writing
1834 * average pull forces and coordinates) in the pull history, in temporary variables,
1835 * in case they cannot be read from the checkpoint, in order to have backward compatibility */
1838 pullHist->numValuesInXSum = 0;
1839 pullHist->numValuesInFSum = 0;
1841 else if (pullHist != nullptr)
1843 pullHistoryNumCoordinates = pullHist->pullCoordinateSums.size();
1844 pullHistoryNumGroups = pullHist->pullGroupSums.size();
1848 GMX_RELEASE_ASSERT(fflags == 0, "Without pull history, all flags should be off");
1851 using StateFlags = gmx::EnumerationArray<StatePullEntry, bool>;
1852 for (auto i = StateFlags::keys().begin(); (i != StateFlags::keys().end() && ret == 0); i++)
1854 if (fflags & (1 << enumValueToBitMask(*i)))
1858 case StatePullEntry::NumCoordinates:
1859 ret = do_cpte_int(xd, *i, fflags, &pullHistoryNumCoordinates, list);
1861 case StatePullEntry::NumGroups:
1862 do_cpt_int_err(xd, enumValueToString(*i), &pullHistoryNumGroups, list);
1864 case StatePullEntry::NumValuesInXSum:
1865 do_cpt_int_err(xd, enumValueToString(*i), &pullHist->numValuesInXSum, list);
1867 case StatePullEntry::NumValuesInFSum:
1868 do_cpt_int_err(xd, enumValueToString(*i), &pullHist->numValuesInFSum, list);
1872 "Unknown pull history entry %d\n"
1873 "You are probably reading a new checkpoint file with old code",
1874 enumValueToBitMask(*i));
1880 pullHist->pullCoordinateSums.resize(pullHistoryNumCoordinates);
1881 pullHist->pullGroupSums.resize(pullHistoryNumGroups);
1883 if (pullHist->numValuesInXSum > 0 || pullHist->numValuesInFSum > 0)
1885 for (size_t i = 0; i < pullHist->pullCoordinateSums.size() && ret == 0; i++)
1887 ret = doCptPullCoordHist(xd, &(pullHist->pullCoordinateSums[i]), list);
1889 for (size_t i = 0; i < pullHist->pullGroupSums.size() && ret == 0; i++)
1891 ret = doCptPullGroupHist(xd, &(pullHist->pullGroupSums[i]), list);
1898 static int do_cpt_df_hist(XDR* xd, int fflags, int nlambda, df_history_t** dfhistPtr, FILE* list)
1907 if (*dfhistPtr == nullptr)
1909 snew(*dfhistPtr, 1);
1910 (*dfhistPtr)->nlambda = nlambda;
1911 init_df_history(*dfhistPtr, nlambda);
1913 df_history_t* dfhist = *dfhistPtr;
1915 using StateFlags = gmx::EnumerationArray<StateFepEntry, bool>;
1916 for (auto i = StateFlags::keys().begin(); (i != StateFlags::keys().end() && ret == 0); i++)
1918 if (fflags & enumValueToBitMask(*i))
1922 case StateFepEntry::IsEquilibrated:
1923 ret = do_cpte_bool(xd, *i, fflags, &dfhist->bEquil, list);
1925 case StateFepEntry::NumAtLambda:
1926 ret = do_cpte_ints(xd, *i, fflags, nlambda, &dfhist->n_at_lam, list);
1928 case StateFepEntry::WangLandauHistogram:
1929 ret = do_cpte_reals(xd, *i, fflags, nlambda, &dfhist->wl_histo, list);
1931 case StateFepEntry::WangLandauDelta:
1932 ret = do_cpte_real(xd, *i, fflags, &dfhist->wl_delta, list);
1934 case StateFepEntry::SumWeights:
1935 ret = do_cpte_reals(xd, *i, fflags, nlambda, &dfhist->sum_weights, list);
1937 case StateFepEntry::SumDG:
1938 ret = do_cpte_reals(xd, *i, fflags, nlambda, &dfhist->sum_dg, list);
1940 case StateFepEntry::SumMinVar:
1941 ret = do_cpte_reals(xd, *i, fflags, nlambda, &dfhist->sum_minvar, list);
1943 case StateFepEntry::SumVar:
1944 ret = do_cpte_reals(xd, *i, fflags, nlambda, &dfhist->sum_variance, list);
1946 case StateFepEntry::Accump:
1947 ret = do_cpte_nmatrix(xd, *i, fflags, nlambda, dfhist->accum_p, list);
1949 case StateFepEntry::Accumm:
1950 ret = do_cpte_nmatrix(xd, *i, fflags, nlambda, dfhist->accum_m, list);
1952 case StateFepEntry::Accump2:
1953 ret = do_cpte_nmatrix(xd, *i, fflags, nlambda, dfhist->accum_p2, list);
1955 case StateFepEntry::Accumm2:
1956 ret = do_cpte_nmatrix(xd, *i, fflags, nlambda, dfhist->accum_m2, list);
1958 case StateFepEntry::Tij:
1959 ret = do_cpte_nmatrix(xd, *i, fflags, nlambda, dfhist->Tij, list);
1961 case StateFepEntry::TijEmp:
1962 ret = do_cpte_nmatrix(xd, *i, fflags, nlambda, dfhist->Tij_empirical, list);
1967 "Unknown df history entry %d\n"
1968 "You are probably reading a new checkpoint file with old code",
1969 enumValueToBitMask(*i));
1978 /* This function stores the last whole configuration of the reference and
1979 * average structure in the .cpt file
1981 static int do_cpt_EDstate(XDR* xd, gmx_bool bRead, int nED, edsamhistory_t* EDstate, FILE* list)
1988 EDstate->bFromCpt = bRead;
1991 /* When reading, init_edsam has not been called yet,
1992 * so we have to allocate memory first. */
1995 snew(EDstate->nref, EDstate->nED);
1996 snew(EDstate->old_sref, EDstate->nED);
1997 snew(EDstate->nav, EDstate->nED);
1998 snew(EDstate->old_sav, EDstate->nED);
2001 /* Read/write the last whole conformation of SREF and SAV for each ED dataset (usually only one) */
2002 for (int i = 0; i < EDstate->nED; i++)
2006 /* Reference structure SREF */
2007 sprintf(buf, "ED%d # of atoms in reference structure", i + 1);
2008 do_cpt_int_err(xd, buf, &EDstate->nref[i], list);
2009 sprintf(buf, "ED%d x_ref", i + 1);
2012 snew(EDstate->old_sref[i], EDstate->nref[i]);
2013 do_cpt_n_rvecs_err(xd, buf, EDstate->nref[i], EDstate->old_sref[i], list);
2017 do_cpt_n_rvecs_err(xd, buf, EDstate->nref[i], EDstate->old_sref_p[i], list);
2020 /* Average structure SAV */
2021 sprintf(buf, "ED%d # of atoms in average structure", i + 1);
2022 do_cpt_int_err(xd, buf, &EDstate->nav[i], list);
2023 sprintf(buf, "ED%d x_av", i + 1);
2026 snew(EDstate->old_sav[i], EDstate->nav[i]);
2027 do_cpt_n_rvecs_err(xd, buf, EDstate->nav[i], EDstate->old_sav[i], list);
2031 do_cpt_n_rvecs_err(xd, buf, EDstate->nav[i], EDstate->old_sav_p[i], list);
2038 static int do_cpt_correlation_grid(XDR* xd,
2040 gmx_unused int fflags,
2041 gmx::CorrelationGridHistory* corrGrid,
2043 StateAwhEntry eawhh)
2047 do_cpt_int_err(xd, enumValueToString(eawhh), &(corrGrid->numCorrelationTensors), list);
2048 do_cpt_int_err(xd, enumValueToString(eawhh), &(corrGrid->tensorSize), list);
2049 do_cpt_int_err(xd, enumValueToString(eawhh), &(corrGrid->blockDataListSize), list);
2053 initCorrelationGridHistory(
2054 corrGrid, corrGrid->numCorrelationTensors, corrGrid->tensorSize, corrGrid->blockDataListSize);
2057 for (gmx::CorrelationBlockDataHistory& blockData : corrGrid->blockDataBuffer)
2059 do_cpt_double_err(xd, enumValueToString(eawhh), &(blockData.blockSumWeight), list);
2060 do_cpt_double_err(xd, enumValueToString(eawhh), &(blockData.blockSumSquareWeight), list);
2061 do_cpt_double_err(xd, enumValueToString(eawhh), &(blockData.blockSumWeightX), list);
2062 do_cpt_double_err(xd, enumValueToString(eawhh), &(blockData.blockSumWeightY), list);
2063 do_cpt_double_err(xd, enumValueToString(eawhh), &(blockData.sumOverBlocksSquareBlockWeight), list);
2064 do_cpt_double_err(xd, enumValueToString(eawhh), &(blockData.sumOverBlocksBlockSquareWeight), list);
2066 xd, enumValueToString(eawhh), &(blockData.sumOverBlocksBlockWeightBlockWeightX), list);
2068 xd, enumValueToString(eawhh), &(blockData.sumOverBlocksBlockWeightBlockWeightY), list);
2069 do_cpt_double_err(xd, enumValueToString(eawhh), &(blockData.blockLength), list);
2070 do_cpt_int_err(xd, enumValueToString(eawhh), &(blockData.previousBlockIndex), list);
2071 do_cpt_double_err(xd, enumValueToString(eawhh), &(blockData.correlationIntegral), list);
2077 static int do_cpt_awh_bias(XDR* xd, gmx_bool bRead, int fflags, gmx::AwhBiasHistory* biasHistory, FILE* list)
2081 gmx::AwhBiasStateHistory* state = &biasHistory->state;
2082 using StateFlags = gmx::EnumerationArray<StateAwhEntry, bool>;
2083 for (auto i = StateFlags::keys().begin(); (i != StateFlags::keys().end() && ret == 0); i++)
2085 if (fflags & enumValueToBitMask(*i))
2089 case StateAwhEntry::InInitial:
2090 do_cpt_bool_err(xd, enumValueToString(*i), &state->in_initial, list);
2092 case StateAwhEntry::EquilibrateHistogram:
2093 do_cpt_bool_err(xd, enumValueToString(*i), &state->equilibrateHistogram, list);
2095 case StateAwhEntry::HistogramSize:
2096 do_cpt_double_err(xd, enumValueToString(*i), &state->histSize, list);
2098 case StateAwhEntry::NumPoints:
2103 numPoints = biasHistory->pointState.size();
2105 do_cpt_int_err(xd, enumValueToString(*i), &numPoints, list);
2108 biasHistory->pointState.resize(numPoints);
2112 case StateAwhEntry::CoordPoint:
2113 for (auto& psh : biasHistory->pointState)
2115 do_cpt_double_err(xd, enumValueToString(*i), &psh.target, list);
2116 do_cpt_double_err(xd, enumValueToString(*i), &psh.free_energy, list);
2117 do_cpt_double_err(xd, enumValueToString(*i), &psh.bias, list);
2118 do_cpt_double_err(xd, enumValueToString(*i), &psh.weightsum_iteration, list);
2119 do_cpt_double_err(xd, enumValueToString(*i), &psh.weightsum_covering, list);
2120 do_cpt_double_err(xd, enumValueToString(*i), &psh.weightsum_tot, list);
2121 do_cpt_double_err(xd, enumValueToString(*i), &psh.weightsum_ref, list);
2122 do_cpt_step_err(xd, enumValueToString(*i), &psh.last_update_index, list);
2123 do_cpt_double_err(xd, enumValueToString(*i), &psh.log_pmfsum, list);
2124 do_cpt_double_err(xd, enumValueToString(*i), &psh.visits_iteration, list);
2125 do_cpt_double_err(xd, enumValueToString(*i), &psh.visits_tot, list);
2128 case StateAwhEntry::UmbrellaGridPoint:
2129 do_cpt_int_err(xd, enumValueToString(*i), &(state->umbrellaGridpoint), list);
2131 case StateAwhEntry::UpdateList:
2132 do_cpt_int_err(xd, enumValueToString(*i), &(state->origin_index_updatelist), list);
2133 do_cpt_int_err(xd, enumValueToString(*i), &(state->end_index_updatelist), list);
2135 case StateAwhEntry::LogScaledSampleWeight:
2136 do_cpt_double_err(xd, enumValueToString(*i), &(state->logScaledSampleWeight), list);
2137 do_cpt_double_err(xd, enumValueToString(*i), &(state->maxLogScaledSampleWeight), list);
2139 case StateAwhEntry::NumUpdates:
2140 do_cpt_step_err(xd, enumValueToString(*i), &(state->numUpdates), list);
2142 case StateAwhEntry::ForceCorrelationGrid:
2143 ret = do_cpt_correlation_grid(
2144 xd, bRead, fflags, &biasHistory->forceCorrelationGrid, list, *i);
2146 default: gmx_fatal(FARGS, "Unknown awh history entry %d\n", enumValueToBitMask(*i));
2154 static int do_cpt_awh(XDR* xd, gmx_bool bRead, int fflags, gmx::AwhHistory* awhHistory, FILE* list)
2160 std::shared_ptr<gmx::AwhHistory> awhHistoryLocal;
2162 if (awhHistory == nullptr)
2164 GMX_RELEASE_ASSERT(bRead,
2165 "do_cpt_awh should not be called for writing without an AwhHistory");
2167 awhHistoryLocal = std::make_shared<gmx::AwhHistory>();
2168 awhHistory = awhHistoryLocal.get();
2171 /* To be able to read and write the AWH data several parameters determining the layout of the AWH structs need to be known
2172 (nbias, npoints, etc.). The best thing (?) would be to have these passed to this function. When writing to a checkpoint
2173 these parameters are available in awh_history (after calling init_awh_history). When reading from a checkpoint though, there
2174 is no initialized awh_history (it is initialized and set in this function). The AWH parameters have not always been read
2175 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
2176 when writing a checkpoint, also storing parameters needed for future reading of the checkpoint.
2178 Another issue is that some variables that AWH checkpoints don't have a registered enum and string (e.g. nbias below).
2179 One difficulty is the multilevel structure of the data which would need to be represented somehow. */
2184 numBias = awhHistory->bias.size();
2186 do_cpt_int_err(xd, "awh_nbias", &numBias, list);
2190 awhHistory->bias.resize(numBias);
2192 for (auto& bias : awhHistory->bias)
2194 ret = do_cpt_awh_bias(xd, bRead, fflags, &bias, list);
2200 do_cpt_double_err(xd, "awh_potential_offset", &awhHistory->potentialOffset, list);
2205 static void do_cpt_mdmodules(CheckPointVersion fileVersion,
2206 t_fileio* checkpointFileHandle,
2207 const gmx::MDModulesNotifiers& mdModulesNotifiers,
2210 if (fileVersion >= CheckPointVersion::MDModules)
2212 gmx::FileIOXdrSerializer serializer(checkpointFileHandle);
2213 gmx::KeyValueTreeObject mdModuleCheckpointParameterTree =
2214 gmx::deserializeKeyValueTree(&serializer);
2217 gmx::TextWriter textWriter(outputFile);
2218 gmx::dumpKeyValueTree(&textWriter, mdModuleCheckpointParameterTree);
2220 gmx::MDModulesCheckpointReadingDataOnMaster mdModuleCheckpointReadingDataOnMaster = {
2221 mdModuleCheckpointParameterTree, fileVersion
2223 mdModulesNotifiers.checkpointingNotifier_.notify(mdModuleCheckpointReadingDataOnMaster);
2227 static int do_cpt_files(XDR* xd,
2229 std::vector<gmx_file_position_t>* outputfiles,
2231 CheckPointVersion file_version)
2234 gmx_off_t mask = 0xFFFFFFFFL;
2235 int offset_high, offset_low;
2236 std::array<char, CPTSTRLEN> buf;
2237 GMX_RELEASE_ASSERT(outputfiles, "Must have valid outputfiles");
2239 // Ensure that reading pre-allocates outputfiles, while writing
2240 // writes what is already there.
2241 int nfiles = outputfiles->size();
2242 if (do_cpt_int(xd, "number of output files", &nfiles, list) != 0)
2248 outputfiles->resize(nfiles);
2251 for (auto& outputfile : *outputfiles)
2253 /* 64-bit XDR numbers are not portable, so it is stored as separate high/low fractions */
2256 do_cpt_string_err(xd, "output filename", buf, list);
2257 std::copy(std::begin(buf), std::end(buf), std::begin(outputfile.filename));
2259 if (do_cpt_int(xd, "file_offset_high", &offset_high, list) != 0)
2263 if (do_cpt_int(xd, "file_offset_low", &offset_low, list) != 0)
2267 outputfile.offset = (static_cast<gmx_off_t>(offset_high) << 32)
2268 | (static_cast<gmx_off_t>(offset_low) & mask);
2272 do_cpt_string_err(xd, "output filename", outputfile.filename, list);
2274 offset = outputfile.offset;
2282 offset_low = static_cast<int>(offset & mask);
2283 offset_high = static_cast<int>((offset >> 32) & mask);
2285 if (do_cpt_int(xd, "file_offset_high", &offset_high, list) != 0)
2289 if (do_cpt_int(xd, "file_offset_low", &offset_low, list) != 0)
2294 if (file_version >= CheckPointVersion::FileChecksumAndSize)
2296 if (do_cpt_int(xd, "file_checksum_size", &outputfile.checksumSize, list) != 0)
2300 if (do_cpt_u_chars(xd, "file_checksum", outputfile.checksum.size(), outputfile.checksum.data(), list)
2308 outputfile.checksumSize = -1;
2314 void write_checkpoint_data(t_fileio* fp,
2315 CheckpointHeaderContents headerContents,
2317 LambdaWeightCalculation elamstats,
2319 ObservablesHistory* observablesHistory,
2320 const gmx::MDModulesNotifiers& mdModulesNotifiers,
2321 std::vector<gmx_file_position_t>* outputfiles,
2322 gmx::WriteCheckpointDataHolder* modularSimulatorCheckpointData)
2324 headerContents.flags_eks = 0;
2325 if (state->ekinstate.bUpToDate)
2327 headerContents.flags_eks = (enumValueToBitMask(StateKineticEntry::EkinNumber)
2328 | enumValueToBitMask(StateKineticEntry::EkinHalfStep)
2329 | enumValueToBitMask(StateKineticEntry::EkinFullStep)
2330 | enumValueToBitMask(StateKineticEntry::EkinHalfStepOld)
2331 | enumValueToBitMask(StateKineticEntry::EkinNoseHooverScaleFullStep)
2332 | enumValueToBitMask(StateKineticEntry::EkinNoseHooverScaleHalfStep)
2333 | enumValueToBitMask(StateKineticEntry::VelocityScale)
2334 | enumValueToBitMask(StateKineticEntry::DEkinDLambda)
2335 | enumValueToBitMask(StateKineticEntry::Mvcos));
2337 headerContents.isModularSimulatorCheckpoint = !modularSimulatorCheckpointData->empty();
2339 energyhistory_t* enerhist = observablesHistory->energyHistory.get();
2340 headerContents.flags_enh = 0;
2341 if (enerhist != nullptr && (enerhist->nsum > 0 || enerhist->nsum_sim > 0))
2343 headerContents.flags_enh |= enumValueToBitMask(StateEnergyEntry::N)
2344 | enumValueToBitMask(StateEnergyEntry::NumSteps)
2345 | enumValueToBitMask(StateEnergyEntry::NumStepsSim);
2346 if (enerhist->nsum > 0)
2348 headerContents.flags_enh |= (enumValueToBitMask(StateEnergyEntry::Aver)
2349 | enumValueToBitMask(StateEnergyEntry::Sum)
2350 | enumValueToBitMask(StateEnergyEntry::NumSum));
2352 if (enerhist->nsum_sim > 0)
2354 headerContents.flags_enh |= (enumValueToBitMask(StateEnergyEntry::SumSim)
2355 | enumValueToBitMask(StateEnergyEntry::NumSumSim));
2357 if (enerhist->deltaHForeignLambdas != nullptr)
2359 headerContents.flags_enh |= (enumValueToBitMask(StateEnergyEntry::DeltaHNN)
2360 | enumValueToBitMask(StateEnergyEntry::DeltaHList)
2361 | enumValueToBitMask(StateEnergyEntry::DeltaHStartTime)
2362 | enumValueToBitMask(StateEnergyEntry::DeltaHStartLambda));
2366 PullHistory* pullHist = observablesHistory->pullHistory.get();
2367 headerContents.flagsPullHistory = 0;
2368 if (pullHist != nullptr && (pullHist->numValuesInXSum > 0 || pullHist->numValuesInFSum > 0))
2370 headerContents.flagsPullHistory |= enumValueToBitMask(StatePullEntry::NumCoordinates);
2371 headerContents.flagsPullHistory |= (enumValueToBitMask(StatePullEntry::NumGroups)
2372 | enumValueToBitMask(StatePullEntry::NumValuesInXSum)
2373 | enumValueToBitMask(StatePullEntry::NumValuesInFSum));
2376 headerContents.flags_dfh = 0;
2379 headerContents.flags_dfh =
2380 (enumValueToBitMask(StateFepEntry::IsEquilibrated)
2381 | enumValueToBitMask(StateFepEntry::NumAtLambda)
2382 | enumValueToBitMask(StateFepEntry::SumWeights) | enumValueToBitMask(StateFepEntry::SumDG)
2383 | enumValueToBitMask(StateFepEntry::Tij) | enumValueToBitMask(StateFepEntry::TijEmp));
2386 headerContents.flags_dfh |= (enumValueToBitMask(StateFepEntry::WangLandauDelta)
2387 | enumValueToBitMask(StateFepEntry::WangLandauHistogram));
2389 if ((elamstats == LambdaWeightCalculation::Minvar) || (elamstats == LambdaWeightCalculation::Barker)
2390 || (elamstats == LambdaWeightCalculation::Metropolis))
2392 headerContents.flags_dfh |= (enumValueToBitMask(StateFepEntry::Accump)
2393 | enumValueToBitMask(StateFepEntry::Accumm)
2394 | enumValueToBitMask(StateFepEntry::Accump2)
2395 | enumValueToBitMask(StateFepEntry::Accumm2)
2396 | enumValueToBitMask(StateFepEntry::SumMinVar)
2397 | enumValueToBitMask(StateFepEntry::SumVar));
2401 headerContents.flags_awhh = 0;
2402 if (state->awhHistory != nullptr && !state->awhHistory->bias.empty())
2404 headerContents.flags_awhh |= (enumValueToBitMask(StateAwhEntry::InInitial)
2405 | enumValueToBitMask(StateAwhEntry::EquilibrateHistogram)
2406 | enumValueToBitMask(StateAwhEntry::HistogramSize)
2407 | enumValueToBitMask(StateAwhEntry::NumPoints)
2408 | enumValueToBitMask(StateAwhEntry::CoordPoint)
2409 | enumValueToBitMask(StateAwhEntry::UmbrellaGridPoint)
2410 | enumValueToBitMask(StateAwhEntry::UpdateList)
2411 | enumValueToBitMask(StateAwhEntry::LogScaledSampleWeight)
2412 | enumValueToBitMask(StateAwhEntry::NumUpdates)
2413 | enumValueToBitMask(StateAwhEntry::ForceCorrelationGrid));
2416 do_cpt_header(gmx_fio_getxdr(fp), FALSE, nullptr, &headerContents);
2418 if ((do_cpt_state(gmx_fio_getxdr(fp), state->flags, state, nullptr) < 0)
2419 || (do_cpt_ekinstate(gmx_fio_getxdr(fp), headerContents.flags_eks, &state->ekinstate, nullptr) < 0)
2420 || (do_cpt_enerhist(gmx_fio_getxdr(fp), FALSE, headerContents.flags_enh, enerhist, nullptr) < 0)
2421 || (doCptPullHist(gmx_fio_getxdr(fp), FALSE, headerContents.flagsPullHistory, pullHist, nullptr) < 0)
2422 || (do_cpt_df_hist(gmx_fio_getxdr(fp), headerContents.flags_dfh, headerContents.nlambda, &state->dfhist, nullptr)
2425 gmx_fio_getxdr(fp), FALSE, headerContents.nED, observablesHistory->edsamHistory.get(), nullptr)
2427 || (do_cpt_awh(gmx_fio_getxdr(fp), FALSE, headerContents.flags_awhh, state->awhHistory.get(), nullptr) < 0)
2428 || (do_cpt_swapstate(gmx_fio_getxdr(fp),
2430 headerContents.eSwapCoords,
2431 observablesHistory->swapHistory.get(),
2434 || (do_cpt_files(gmx_fio_getxdr(fp), FALSE, outputfiles, nullptr, headerContents.file_version) < 0))
2436 gmx_file("Cannot read/write checkpoint; corrupt file, or maybe you are out of disk space?");
2439 // Checkpointing MDModules
2441 gmx::KeyValueTreeBuilder builder;
2442 gmx::MDModulesWriteCheckpointData mdModulesWriteCheckpoint = { builder.rootObject(),
2443 headerContents.file_version };
2444 mdModulesNotifiers.checkpointingNotifier_.notify(mdModulesWriteCheckpoint);
2445 auto tree = builder.build();
2446 gmx::FileIOXdrSerializer serializer(fp);
2447 gmx::serializeKeyValueTree(tree, &serializer);
2450 // Checkpointing modular simulator
2452 gmx::FileIOXdrSerializer serializer(fp);
2453 modularSimulatorCheckpointData->serialize(&serializer);
2456 do_cpt_footer(gmx_fio_getxdr(fp), headerContents.file_version);
2458 /* Always FAH checkpoint immediately after a Gromacs checkpoint.
2460 * Note that it is critical that we save a FAH checkpoint directly
2461 * after writing a Gromacs checkpoint. If the program dies, either
2462 * by the machine powering off suddenly or the process being,
2463 * killed, FAH can recover files that have only appended data by
2464 * truncating them to the last recorded length. The Gromacs
2465 * checkpoint does not just append data, it is fully rewritten each
2466 * time so a crash between moving the new Gromacs checkpoint file in
2467 * to place and writing a FAH checkpoint is not recoverable. Thus
2468 * the time between these operations must be kept as short a
2475 static void check_int(FILE* fplog, const char* type, int p, int f, gmx_bool* mm)
2477 bool foundMismatch = (p != f);
2485 fprintf(fplog, " %s mismatch,\n", type);
2486 fprintf(fplog, " current program: %d\n", p);
2487 fprintf(fplog, " checkpoint file: %d\n", f);
2488 fprintf(fplog, "\n");
2492 static void check_string(FILE* fplog, const char* type, const char* p, const char* f, gmx_bool* mm)
2494 bool foundMismatch = (std::strcmp(p, f) != 0);
2502 fprintf(fplog, " %s mismatch,\n", type);
2503 fprintf(fplog, " current program: %s\n", p);
2504 fprintf(fplog, " checkpoint file: %s\n", f);
2505 fprintf(fplog, "\n");
2509 static void check_match(FILE* fplog,
2510 const t_commrec* cr,
2512 const CheckpointHeaderContents& headerContents,
2513 gmx_bool reproducibilityRequested)
2515 /* Note that this check_string on the version will also print a message
2516 * when only the minor version differs. But we only print a warning
2517 * message further down with reproducibilityRequested=TRUE.
2519 gmx_bool versionDiffers = FALSE;
2520 check_string(fplog, "Version", gmx_version(), headerContents.version, &versionDiffers);
2522 gmx_bool precisionDiffers = FALSE;
2523 check_int(fplog, "Double prec.", GMX_DOUBLE, headerContents.double_prec, &precisionDiffers);
2524 if (precisionDiffers)
2526 const char msg_precision_difference[] =
2527 "You are continuing a simulation with a different precision. Not matching\n"
2528 "mixed/double precision will lead to precision or performance loss.\n";
2531 fprintf(fplog, "%s\n", msg_precision_difference);
2535 gmx_bool mm = (versionDiffers || precisionDiffers);
2537 if (reproducibilityRequested)
2540 fplog, "Program name", gmx::getProgramContext().fullBinaryPath(), headerContents.fprog, &mm);
2542 check_int(fplog, "#ranks", cr->nnodes, headerContents.nnodes, &mm);
2545 if (cr->sizeOfDefaultCommunicator > 1 && reproducibilityRequested)
2547 // TODO: These checks are incorrect (see redmine #3309)
2548 check_int(fplog, "#PME-ranks", cr->npmenodes, headerContents.npme, &mm);
2550 int npp = cr->sizeOfDefaultCommunicator;
2551 if (cr->npmenodes >= 0)
2553 npp -= cr->npmenodes;
2555 int npp_f = headerContents.nnodes;
2556 if (headerContents.npme >= 0)
2558 npp_f -= headerContents.npme;
2562 check_int(fplog, "#DD-cells[x]", dd_nc[XX], headerContents.dd_nc[XX], &mm);
2563 check_int(fplog, "#DD-cells[y]", dd_nc[YY], headerContents.dd_nc[YY], &mm);
2564 check_int(fplog, "#DD-cells[z]", dd_nc[ZZ], headerContents.dd_nc[ZZ], &mm);
2570 /* Gromacs should be able to continue from checkpoints between
2571 * different patch level versions, but we do not guarantee
2572 * compatibility between different major/minor versions - check this.
2576 sscanf(gmx_version(), "%5d", &gmx_major);
2577 int ret = sscanf(headerContents.version, "%5d", &cpt_major);
2578 gmx_bool majorVersionDiffers = (ret < 1 || gmx_major != cpt_major);
2580 const char msg_major_version_difference[] =
2581 "The current GROMACS major version is not identical to the one that\n"
2582 "generated the checkpoint file. In principle GROMACS does not support\n"
2583 "continuation from checkpoints between different versions, so we advise\n"
2584 "against this. If you still want to try your luck we recommend that you use\n"
2585 "the -noappend flag to keep your output files from the two versions separate.\n"
2586 "This might also work around errors where the output fields in the energy\n"
2587 "file have changed between the different versions.\n";
2589 const char msg_mismatch_notice[] =
2590 "GROMACS patchlevel, binary or parallel settings differ from previous run.\n"
2591 "Continuation is exact, but not guaranteed to be binary identical.\n";
2593 if (majorVersionDiffers)
2597 fprintf(fplog, "%s\n", msg_major_version_difference);
2600 else if (reproducibilityRequested)
2602 /* Major & minor versions match at least, but something is different. */
2605 fprintf(fplog, "%s\n", msg_mismatch_notice);
2611 static void read_checkpoint(const char* fn,
2613 const t_commrec* cr,
2615 IntegrationAlgorithm eIntegrator,
2616 int* init_fep_state,
2617 CheckpointHeaderContents* headerContents,
2619 ObservablesHistory* observablesHistory,
2620 gmx_bool reproducibilityRequested,
2621 const gmx::MDModulesNotifiers& mdModulesNotifiers,
2622 gmx::ReadCheckpointDataHolder* modularSimulatorCheckpointData,
2623 bool useModularSimulator)
2626 char buf[STEPSTRSIZE];
2629 fp = gmx_fio_open(fn, "r");
2630 do_cpt_header(gmx_fio_getxdr(fp), TRUE, nullptr, headerContents);
2632 // If we are appending, then we don't want write to the open log
2633 // file because we still need to compute a checksum for it. In
2634 // that case, the filehandle will be nullptr. Otherwise, we report
2635 // to the new log file about the checkpoint file that we are
2637 FILE* fplog = gmx_fio_getfp(logfio);
2640 fprintf(fplog, "\n");
2641 fprintf(fplog, "Reading checkpoint file %s\n", fn);
2642 fprintf(fplog, " file generated by: %s\n", headerContents->fprog);
2643 fprintf(fplog, " file generated at: %s\n", headerContents->ftime);
2644 fprintf(fplog, " GROMACS double prec.: %d\n", headerContents->double_prec);
2645 fprintf(fplog, " simulation part #: %d\n", headerContents->simulation_part);
2646 fprintf(fplog, " step: %s\n", gmx_step_str(headerContents->step, buf));
2647 fprintf(fplog, " time: %f\n", headerContents->t);
2648 fprintf(fplog, "\n");
2651 if (headerContents->natoms != state->natoms)
2654 "Checkpoint file is for a system of %d atoms, while the current system consists "
2656 headerContents->natoms,
2659 if (headerContents->ngtc != state->ngtc)
2662 "Checkpoint file is for a system of %d T-coupling groups, while the current "
2663 "system consists of %d T-coupling groups",
2664 headerContents->ngtc,
2667 if (headerContents->nnhpres != state->nnhpres)
2670 "Checkpoint file is for a system of %d NH-pressure-coupling variables, while the "
2671 "current system consists of %d NH-pressure-coupling variables",
2672 headerContents->nnhpres,
2676 int nlambdaHistory = (state->dfhist ? state->dfhist->nlambda : 0);
2677 if (headerContents->nlambda != nlambdaHistory)
2680 "Checkpoint file is for a system with %d lambda states, while the current system "
2681 "consists of %d lambda states",
2682 headerContents->nlambda,
2686 init_gtc_state(state,
2689 headerContents->nhchainlength); /* need to keep this here to keep the tpr format working */
2690 /* write over whatever was read; we use the number of Nose-Hoover chains from the checkpoint */
2692 if (headerContents->eIntegrator != eIntegrator)
2695 "Cannot change integrator during a checkpoint restart. Perhaps you should make a "
2696 "new .tpr with grompp -f new.mdp -t %s",
2700 // For modular simulator, no state object is populated, so we cannot do this check here!
2701 if (headerContents->flags_state != state->flags && !useModularSimulator)
2704 "Cannot change a simulation algorithm during a checkpoint restart. Perhaps you "
2705 "should make a new .tpr with grompp -f new.mdp -t %s",
2709 GMX_RELEASE_ASSERT(!(headerContents->isModularSimulatorCheckpoint && !useModularSimulator),
2710 "Checkpoint file was written by modular simulator, but the current "
2711 "simulation uses the legacy simulator.\n\n"
2712 "Try the following steps:\n"
2713 "1. Make sure the GMX_DISABLE_MODULAR_SIMULATOR environment variable is not "
2714 "set to return to the default behavior. Retry running the simulation.\n"
2715 "2. If the problem persists, set the environment variable "
2716 "GMX_USE_MODULAR_SIMULATOR=ON to overwrite the default behavior and use "
2717 "modular simulator for all implemented use cases.");
2718 GMX_RELEASE_ASSERT(!(!headerContents->isModularSimulatorCheckpoint && useModularSimulator),
2719 "Checkpoint file was written by legacy simulator, but the current "
2720 "simulation uses the modular simulator.\n\n"
2721 "Try the following steps:\n"
2722 "1. Make sure the GMX_USE_MODULAR_SIMULATOR environment variable is not set "
2723 "to return to the default behavior. Retry running the simulation.\n"
2724 "2. If the problem persists, set the environment variable "
2725 "GMX_DISABLE_MODULAR_SIMULATOR=ON to overwrite the default behavior and use "
2726 "legacy simulator for all implemented use cases.");
2730 check_match(fplog, cr, dd_nc, *headerContents, reproducibilityRequested);
2733 ret = do_cpt_state(gmx_fio_getxdr(fp), headerContents->flags_state, state, nullptr);
2734 *init_fep_state = state->fep_state; /* there should be a better way to do this than setting it
2735 here. Investigate for 5.0. */
2740 ret = do_cpt_ekinstate(gmx_fio_getxdr(fp), headerContents->flags_eks, &state->ekinstate, nullptr);
2745 state->ekinstate.hasReadEkinState =
2746 (((headerContents->flags_eks & enumValueToBitMask(StateKineticEntry::EkinHalfStep)) != 0)
2747 || ((headerContents->flags_eks & enumValueToBitMask(StateKineticEntry::EkinFullStep)) != 0)
2748 || ((headerContents->flags_eks & enumValueToBitMask(StateKineticEntry::EkinHalfStepOld)) != 0)
2749 || (((headerContents->flags_eks & enumValueToBitMask(StateKineticEntry::EkinNoseHooverScaleFullStep))
2750 | (headerContents->flags_eks & enumValueToBitMask(StateKineticEntry::EkinNoseHooverScaleHalfStep))
2751 | (headerContents->flags_eks & enumValueToBitMask(StateKineticEntry::VelocityScale)))
2754 if (headerContents->flags_enh && observablesHistory->energyHistory == nullptr)
2756 observablesHistory->energyHistory = std::make_unique<energyhistory_t>();
2758 ret = do_cpt_enerhist(
2759 gmx_fio_getxdr(fp), TRUE, headerContents->flags_enh, observablesHistory->energyHistory.get(), nullptr);
2765 if (headerContents->flagsPullHistory)
2767 if (observablesHistory->pullHistory == nullptr)
2769 observablesHistory->pullHistory = std::make_unique<PullHistory>();
2771 ret = doCptPullHist(gmx_fio_getxdr(fp),
2773 headerContents->flagsPullHistory,
2774 observablesHistory->pullHistory.get(),
2782 if (headerContents->file_version < CheckPointVersion::Version45)
2785 "Continuing from checkpoint files written before GROMACS 4.5 is not supported");
2788 ret = do_cpt_df_hist(
2789 gmx_fio_getxdr(fp), headerContents->flags_dfh, headerContents->nlambda, &state->dfhist, nullptr);
2795 if (headerContents->nED > 0 && observablesHistory->edsamHistory == nullptr)
2797 observablesHistory->edsamHistory = std::make_unique<edsamhistory_t>(edsamhistory_t{});
2799 ret = do_cpt_EDstate(
2800 gmx_fio_getxdr(fp), TRUE, headerContents->nED, observablesHistory->edsamHistory.get(), nullptr);
2806 if (headerContents->flags_awhh != 0 && state->awhHistory == nullptr)
2808 state->awhHistory = std::make_shared<gmx::AwhHistory>();
2810 ret = do_cpt_awh(gmx_fio_getxdr(fp), TRUE, headerContents->flags_awhh, state->awhHistory.get(), nullptr);
2816 if (headerContents->eSwapCoords != SwapType::No && observablesHistory->swapHistory == nullptr)
2818 observablesHistory->swapHistory = std::make_unique<swaphistory_t>(swaphistory_t{});
2820 ret = do_cpt_swapstate(
2821 gmx_fio_getxdr(fp), TRUE, headerContents->eSwapCoords, observablesHistory->swapHistory.get(), nullptr);
2827 std::vector<gmx_file_position_t> outputfiles;
2828 ret = do_cpt_files(gmx_fio_getxdr(fp), TRUE, &outputfiles, nullptr, headerContents->file_version);
2833 do_cpt_mdmodules(headerContents->file_version, fp, mdModulesNotifiers, nullptr);
2834 if (headerContents->file_version >= CheckPointVersion::ModularSimulator)
2836 gmx::FileIOXdrSerializer serializer(fp);
2837 modularSimulatorCheckpointData->deserialize(&serializer);
2839 ret = do_cpt_footer(gmx_fio_getxdr(fp), headerContents->file_version);
2844 if (gmx_fio_close(fp) != 0)
2846 gmx_file("Cannot read/write checkpoint; corrupt file, or maybe you are out of disk space?");
2851 void load_checkpoint(const char* fn,
2853 const t_commrec* cr,
2857 ObservablesHistory* observablesHistory,
2858 gmx_bool reproducibilityRequested,
2859 const gmx::MDModulesNotifiers& mdModulesNotifiers,
2860 gmx::ReadCheckpointDataHolder* modularSimulatorCheckpointData,
2861 bool useModularSimulator)
2863 CheckpointHeaderContents headerContents;
2866 /* Read the state from the checkpoint file */
2872 &(ir->fepvals->init_fep_state),
2876 reproducibilityRequested,
2878 modularSimulatorCheckpointData,
2879 useModularSimulator);
2883 gmx_bcast(sizeof(headerContents.step), &headerContents.step, cr->mpiDefaultCommunicator);
2884 gmx::MDModulesCheckpointReadingBroadcast broadcastCheckPointData = {
2885 cr->mpiDefaultCommunicator, PAR(cr), headerContents.file_version
2887 mdModulesNotifiers.checkpointingNotifier_.notify(broadcastCheckPointData);
2889 ir->bContinuation = TRUE;
2890 if (ir->nsteps >= 0)
2892 // TODO Should the following condition be <=? Currently if you
2893 // pass a checkpoint written by an normal completion to a restart,
2894 // mdrun will read all input, does some work but no steps, and
2895 // write successful output. But perhaps that is not desirable.
2896 // Note that we do not intend to support the use of mdrun
2897 // -nsteps to circumvent this condition.
2898 if (ir->nsteps + ir->init_step < headerContents.step)
2900 char buf[STEPSTRSIZE];
2901 std::string message =
2902 gmx::formatString("The input requested %s steps, ", gmx_step_str(ir->nsteps, buf));
2903 if (ir->init_step > 0)
2905 message += gmx::formatString("starting from step %s, ", gmx_step_str(ir->init_step, buf));
2907 message += gmx::formatString(
2908 "however the checkpoint "
2909 "file has already reached step %s. The simulation will not "
2910 "proceed, because either your simulation is already complete, "
2911 "or your combination of input files don't match.",
2912 gmx_step_str(headerContents.step, buf));
2913 gmx_fatal(FARGS, "%s", message.c_str());
2915 ir->nsteps += ir->init_step - headerContents.step;
2917 ir->init_step = headerContents.step;
2918 ir->simulation_part = headerContents.simulation_part + 1;
2921 void read_checkpoint_part_and_step(const char* filename, int* simulation_part, int64_t* step)
2925 if (filename == nullptr || !gmx_fexist(filename) || ((fp = gmx_fio_open(filename, "r")) == nullptr))
2927 *simulation_part = 0;
2932 CheckpointHeaderContents headerContents;
2933 do_cpt_header(gmx_fio_getxdr(fp), TRUE, nullptr, &headerContents);
2935 *simulation_part = headerContents.simulation_part;
2936 *step = headerContents.step;
2939 static CheckpointHeaderContents read_checkpoint_data(t_fileio* fp,
2941 std::vector<gmx_file_position_t>* outputfiles,
2942 gmx::ReadCheckpointDataHolder* modularSimulatorCheckpointData)
2944 CheckpointHeaderContents headerContents;
2945 do_cpt_header(gmx_fio_getxdr(fp), TRUE, nullptr, &headerContents);
2946 state->natoms = headerContents.natoms;
2947 state->ngtc = headerContents.ngtc;
2948 state->nnhpres = headerContents.nnhpres;
2949 state->nhchainlength = headerContents.nhchainlength;
2950 state->flags = headerContents.flags_state;
2951 int ret = do_cpt_state(gmx_fio_getxdr(fp), state->flags, state, nullptr);
2956 ret = do_cpt_ekinstate(gmx_fio_getxdr(fp), headerContents.flags_eks, &state->ekinstate, nullptr);
2962 energyhistory_t enerhist;
2963 ret = do_cpt_enerhist(gmx_fio_getxdr(fp), TRUE, headerContents.flags_enh, &enerhist, nullptr);
2968 PullHistory pullHist = {};
2969 ret = doCptPullHist(gmx_fio_getxdr(fp), TRUE, headerContents.flagsPullHistory, &pullHist, nullptr);
2975 ret = do_cpt_df_hist(
2976 gmx_fio_getxdr(fp), headerContents.flags_dfh, headerContents.nlambda, &state->dfhist, nullptr);
2982 edsamhistory_t edsamhist = {};
2983 ret = do_cpt_EDstate(gmx_fio_getxdr(fp), TRUE, headerContents.nED, &edsamhist, nullptr);
2989 ret = do_cpt_awh(gmx_fio_getxdr(fp), TRUE, headerContents.flags_awhh, state->awhHistory.get(), nullptr);
2995 swaphistory_t swaphist = {};
2996 ret = do_cpt_swapstate(gmx_fio_getxdr(fp), TRUE, headerContents.eSwapCoords, &swaphist, nullptr);
3002 ret = do_cpt_files(gmx_fio_getxdr(fp), TRUE, outputfiles, nullptr, headerContents.file_version);
3008 gmx::MDModulesNotifiers mdModuleNotifiers;
3009 do_cpt_mdmodules(headerContents.file_version, fp, mdModuleNotifiers, nullptr);
3010 if (headerContents.file_version >= CheckPointVersion::ModularSimulator)
3012 // Store modular checkpoint data into modularSimulatorCheckpointData
3013 gmx::FileIOXdrSerializer serializer(fp);
3014 modularSimulatorCheckpointData->deserialize(&serializer);
3016 ret = do_cpt_footer(gmx_fio_getxdr(fp), headerContents.file_version);
3021 return headerContents;
3024 void read_checkpoint_trxframe(t_fileio* fp, t_trxframe* fr)
3027 std::vector<gmx_file_position_t> outputfiles;
3028 gmx::ReadCheckpointDataHolder modularSimulatorCheckpointData;
3029 CheckpointHeaderContents headerContents =
3030 read_checkpoint_data(fp, &state, &outputfiles, &modularSimulatorCheckpointData);
3031 if (headerContents.isModularSimulatorCheckpoint)
3033 gmx::ModularSimulator::readCheckpointToTrxFrame(fr, &modularSimulatorCheckpointData, headerContents);
3037 fr->natoms = state.natoms;
3039 fr->step = int64_to_int(headerContents.step, "conversion of checkpoint to trajectory");
3041 fr->time = headerContents.t;
3043 fr->lambda = state.lambda[FreeEnergyPerturbationCouplingType::Fep];
3044 fr->fep_state = state.fep_state;
3046 fr->bX = ((state.flags & enumValueToBitMask(StateEntry::X)) != 0);
3049 fr->x = makeRvecArray(state.x, state.natoms);
3051 fr->bV = ((state.flags & enumValueToBitMask(StateEntry::V)) != 0);
3054 fr->v = makeRvecArray(state.v, state.natoms);
3057 fr->bBox = ((state.flags & enumValueToBitMask(StateEntry::Box)) != 0);
3060 copy_mat(state.box, fr->box);
3064 void list_checkpoint(const char* fn, FILE* out)
3071 fp = gmx_fio_open(fn, "r");
3072 CheckpointHeaderContents headerContents;
3073 do_cpt_header(gmx_fio_getxdr(fp), TRUE, out, &headerContents);
3074 state.natoms = headerContents.natoms;
3075 state.ngtc = headerContents.ngtc;
3076 state.nnhpres = headerContents.nnhpres;
3077 state.nhchainlength = headerContents.nhchainlength;
3078 state.flags = headerContents.flags_state;
3079 ret = do_cpt_state(gmx_fio_getxdr(fp), state.flags, &state, out);
3084 ret = do_cpt_ekinstate(gmx_fio_getxdr(fp), headerContents.flags_eks, &state.ekinstate, out);
3090 energyhistory_t enerhist;
3091 ret = do_cpt_enerhist(gmx_fio_getxdr(fp), TRUE, headerContents.flags_enh, &enerhist, out);
3095 PullHistory pullHist = {};
3096 ret = doCptPullHist(gmx_fio_getxdr(fp), TRUE, headerContents.flagsPullHistory, &pullHist, out);
3101 ret = do_cpt_df_hist(
3102 gmx_fio_getxdr(fp), headerContents.flags_dfh, headerContents.nlambda, &state.dfhist, out);
3107 edsamhistory_t edsamhist = {};
3108 ret = do_cpt_EDstate(gmx_fio_getxdr(fp), TRUE, headerContents.nED, &edsamhist, out);
3113 ret = do_cpt_awh(gmx_fio_getxdr(fp), TRUE, headerContents.flags_awhh, state.awhHistory.get(), out);
3118 swaphistory_t swaphist = {};
3119 ret = do_cpt_swapstate(gmx_fio_getxdr(fp), TRUE, headerContents.eSwapCoords, &swaphist, out);
3124 std::vector<gmx_file_position_t> outputfiles;
3125 ret = do_cpt_files(gmx_fio_getxdr(fp), TRUE, &outputfiles, out, headerContents.file_version);
3127 gmx::MDModulesNotifiers mdModuleNotifiers;
3128 do_cpt_mdmodules(headerContents.file_version, fp, mdModuleNotifiers, out);
3129 if (headerContents.file_version >= CheckPointVersion::ModularSimulator)
3131 gmx::FileIOXdrSerializer serializer(fp);
3132 gmx::ReadCheckpointDataHolder modularSimulatorCheckpointData;
3133 modularSimulatorCheckpointData.deserialize(&serializer);
3134 modularSimulatorCheckpointData.dump(out);
3139 ret = do_cpt_footer(gmx_fio_getxdr(fp), headerContents.file_version);
3146 if (gmx_fio_close(fp) != 0)
3148 gmx_file("Cannot read/write checkpoint; corrupt file, or maybe you are out of disk space?");
3152 /* This routine cannot print tons of data, since it is called before the log file is opened. */
3153 CheckpointHeaderContents read_checkpoint_simulation_part_and_filenames(t_fileio* fp,
3154 std::vector<gmx_file_position_t>* outputfiles)
3157 gmx::ReadCheckpointDataHolder modularSimulatorCheckpointData;
3158 CheckpointHeaderContents headerContents =
3159 read_checkpoint_data(fp, &state, outputfiles, &modularSimulatorCheckpointData);
3160 if (gmx_fio_close(fp) != 0)
3162 gmx_file("Cannot read/write checkpoint; corrupt file, or maybe you are out of disk space?");
3164 return headerContents;