Move code for managing mdrun -cpi and -append
[alexxy/gromacs.git] / src / gromacs / gmxlib / checkpoint.cpp
1 /*
2  * This file is part of the GROMACS molecular simulation package.
3  *
4  * Copyright (c) 2008,2009,2010,2011,2012,2013,2014,2015, 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.
8  *
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.
13  *
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.
18  *
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.
23  *
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.
31  *
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.
34  */
35
36 /* The source code in this file should be thread-safe.
37    Please keep it that way. */
38 #include "gmxpre.h"
39
40 #include "gromacs/legacyheaders/checkpoint.h"
41
42 #include "config.h"
43
44 #include <errno.h>
45 #include <stdlib.h>
46 #include <string.h>
47
48 #include <fcntl.h>
49 #ifdef GMX_NATIVE_WINDOWS
50 #include <io.h>
51 #include <sys/locking.h>
52 #endif
53
54 #include "buildinfo.h"
55 #include "gromacs/fileio/filenm.h"
56 #include "gromacs/fileio/gmxfio.h"
57 #include "gromacs/fileio/xdr_datatype.h"
58 #include "gromacs/fileio/xdrf.h"
59 #include "gromacs/legacyheaders/copyrite.h"
60 #include "gromacs/legacyheaders/names.h"
61 #include "gromacs/legacyheaders/network.h"
62 #include "gromacs/legacyheaders/txtdump.h"
63 #include "gromacs/legacyheaders/typedefs.h"
64 #include "gromacs/legacyheaders/types/commrec.h"
65 #include "gromacs/math/vec.h"
66 #include "gromacs/utility/baseversion.h"
67 #include "gromacs/utility/cstringutil.h"
68 #include "gromacs/utility/fatalerror.h"
69 #include "gromacs/utility/futil.h"
70 #include "gromacs/utility/smalloc.h"
71 #include "gromacs/utility/sysinfo.h"
72
73 #ifdef GMX_FAHCORE
74 #include "corewrap.h"
75 #endif
76
77 #define CPT_MAGIC1 171817
78 #define CPT_MAGIC2 171819
79 #define CPTSTRLEN 1024
80
81 #ifdef GMX_DOUBLE
82 #define GMX_CPT_BUILD_DP 1
83 #else
84 #define GMX_CPT_BUILD_DP 0
85 #endif
86
87 /* cpt_version should normally only be changed
88  * when the header of footer format changes.
89  * The state data format itself is backward and forward compatible.
90  * But old code can not read a new entry that is present in the file
91  * (but can read a new format when new entries are not present).
92  */
93 static const int cpt_version = 16;
94
95
96 const char *est_names[estNR] =
97 {
98     "FE-lambda",
99     "box", "box-rel", "box-v", "pres_prev",
100     "nosehoover-xi", "thermostat-integral",
101     "x", "v", "SDx", "CGp", "LD-rng", "LD-rng-i",
102     "disre_initf", "disre_rm3tav",
103     "orire_initf", "orire_Dtav",
104     "svir_prev", "nosehoover-vxi", "v_eta", "vol0", "nhpres_xi", "nhpres_vxi", "fvir_prev", "fep_state", "MC-rng", "MC-rng-i"
105 };
106
107 enum {
108     eeksEKIN_N, eeksEKINH, eeksDEKINDL, eeksMVCOS, eeksEKINF, eeksEKINO, eeksEKINSCALEF, eeksEKINSCALEH, eeksVSCALE, eeksEKINTOTAL, eeksNR
109 };
110
111 const char *eeks_names[eeksNR] =
112 {
113     "Ekin_n", "Ekinh", "dEkindlambda", "mv_cos",
114     "Ekinf", "Ekinh_old", "EkinScaleF_NHC", "EkinScaleH_NHC", "Vscale_NHC", "Ekin_Total"
115 };
116
117 enum {
118     eenhENERGY_N, eenhENERGY_AVER, eenhENERGY_SUM, eenhENERGY_NSUM,
119     eenhENERGY_SUM_SIM, eenhENERGY_NSUM_SIM,
120     eenhENERGY_NSTEPS, eenhENERGY_NSTEPS_SIM,
121     eenhENERGY_DELTA_H_NN,
122     eenhENERGY_DELTA_H_LIST,
123     eenhENERGY_DELTA_H_STARTTIME,
124     eenhENERGY_DELTA_H_STARTLAMBDA,
125     eenhNR
126 };
127
128 const char *eenh_names[eenhNR] =
129 {
130     "energy_n", "energy_aver", "energy_sum", "energy_nsum",
131     "energy_sum_sim", "energy_nsum_sim",
132     "energy_nsteps", "energy_nsteps_sim",
133     "energy_delta_h_nn",
134     "energy_delta_h_list",
135     "energy_delta_h_start_time",
136     "energy_delta_h_start_lambda"
137 };
138
139 /* free energy history variables -- need to be preserved over checkpoint */
140 enum {
141     edfhBEQUIL, edfhNATLAMBDA, edfhWLHISTO, edfhWLDELTA, edfhSUMWEIGHTS, edfhSUMDG, edfhSUMMINVAR, edfhSUMVAR,
142     edfhACCUMP, edfhACCUMM, edfhACCUMP2, edfhACCUMM2, edfhTIJ, edfhTIJEMP, edfhNR
143 };
144 /* free energy history variable names  */
145 const char *edfh_names[edfhNR] =
146 {
147     "bEquilibrated", "N_at_state", "Wang-Landau Histogram", "Wang-Landau Delta", "Weights", "Free Energies", "minvar", "variance",
148     "accumulated_plus", "accumulated_minus", "accumulated_plus_2",  "accumulated_minus_2", "Tij", "Tij_empirical"
149 };
150
151 enum {
152     ecprREAL, ecprRVEC, ecprMATRIX
153 };
154
155 enum {
156     cptpEST, cptpEEKS, cptpEENH, cptpEDFH
157 };
158 /* enums for the different components of checkpoint variables, replacing the hard coded ones.
159    cptpEST - state variables.
160    cptpEEKS - Kinetic energy state variables.
161    cptpEENH - Energy history state variables.
162    cptpEDFH - free energy history variables.
163  */
164
165
166 static const char *st_names(int cptp, int ecpt)
167 {
168     switch (cptp)
169     {
170         case cptpEST: return est_names [ecpt]; break;
171         case cptpEEKS: return eeks_names[ecpt]; break;
172         case cptpEENH: return eenh_names[ecpt]; break;
173         case cptpEDFH: return edfh_names[ecpt]; break;
174     }
175
176     return NULL;
177 }
178
179 static void cp_warning(FILE *fp)
180 {
181     fprintf(fp, "\nWARNING: Checkpoint file is corrupted or truncated\n\n");
182 }
183
184 static void cp_error()
185 {
186     gmx_fatal(FARGS, "Checkpoint file corrupted/truncated, or maybe you are out of disk space?");
187 }
188
189 static void do_cpt_string_err(XDR *xd, gmx_bool bRead, const char *desc, char **s, FILE *list)
190 {
191     bool_t res = 0;
192
193     if (bRead)
194     {
195         snew(*s, CPTSTRLEN);
196     }
197     res = xdr_string(xd, s, CPTSTRLEN);
198     if (res == 0)
199     {
200         cp_error();
201     }
202     if (list)
203     {
204         fprintf(list, "%s = %s\n", desc, *s);
205         sfree(*s);
206     }
207 }
208
209 static int do_cpt_int(XDR *xd, const char *desc, int *i, FILE *list)
210 {
211     bool_t res = 0;
212
213     res = xdr_int(xd, i);
214     if (res == 0)
215     {
216         return -1;
217     }
218     if (list)
219     {
220         fprintf(list, "%s = %d\n", desc, *i);
221     }
222     return 0;
223 }
224
225 static int do_cpt_u_chars(XDR *xd, const char *desc, int n, unsigned char *i, FILE *list)
226 {
227     bool_t res = 1;
228     int    j;
229     if (list)
230     {
231         fprintf(list, "%s = ", desc);
232     }
233     for (j = 0; j < n && res; j++)
234     {
235         res &= xdr_u_char(xd, &i[j]);
236         if (list)
237         {
238             fprintf(list, "%02x", i[j]);
239         }
240     }
241     if (list)
242     {
243         fprintf(list, "\n");
244     }
245     if (res == 0)
246     {
247         return -1;
248     }
249
250     return 0;
251 }
252
253 static void do_cpt_int_err(XDR *xd, const char *desc, int *i, FILE *list)
254 {
255     if (do_cpt_int(xd, desc, i, list) < 0)
256     {
257         cp_error();
258     }
259 }
260
261 static void do_cpt_step_err(XDR *xd, const char *desc, gmx_int64_t *i, FILE *list)
262 {
263     bool_t res = 0;
264     char   buf[STEPSTRSIZE];
265
266     res = xdr_int64(xd, i);
267     if (res == 0)
268     {
269         cp_error();
270     }
271     if (list)
272     {
273         fprintf(list, "%s = %s\n", desc, gmx_step_str(*i, buf));
274     }
275 }
276
277 static void do_cpt_double_err(XDR *xd, const char *desc, double *f, FILE *list)
278 {
279     bool_t res = 0;
280
281     res = xdr_double(xd, f);
282     if (res == 0)
283     {
284         cp_error();
285     }
286     if (list)
287     {
288         fprintf(list, "%s = %f\n", desc, *f);
289     }
290 }
291
292 static void do_cpt_real_err(XDR *xd, real *f)
293 {
294     bool_t res = 0;
295
296 #ifdef GMX_DOUBLE
297     res = xdr_double(xd, f);
298 #else
299     res = xdr_float(xd, f);
300 #endif
301     if (res == 0)
302     {
303         cp_error();
304     }
305 }
306
307 static void do_cpt_n_rvecs_err(XDR *xd, const char *desc, int n, rvec f[], FILE *list)
308 {
309     int i, j;
310
311     for (i = 0; i < n; i++)
312     {
313         for (j = 0; j < DIM; j++)
314         {
315             do_cpt_real_err(xd, &f[i][j]);
316         }
317     }
318
319     if (list)
320     {
321         pr_rvecs(list, 0, desc, f, n);
322     }
323 }
324
325 /* If nval >= 0, nval is used; on read this should match the passed value.
326  * If nval n<0, *nptr is used; on read the value is stored in nptr
327  */
328 static int do_cpte_reals_low(XDR *xd, int cptp, int ecpt, int sflags,
329                              int nval, int *nptr, real **v,
330                              FILE *list, int erealtype)
331 {
332     bool_t  res = 0;
333 #ifndef GMX_DOUBLE
334     int     dtc = xdr_datatype_float;
335 #else
336     int     dtc = xdr_datatype_double;
337 #endif
338     real   *vp, *va = NULL;
339     float  *vf;
340     double *vd;
341     int     nf, dt, i;
342
343     if (list == NULL)
344     {
345         if (nval >= 0)
346         {
347             nf = nval;
348         }
349         else
350         {
351             if (nptr == NULL)
352             {
353                 gmx_incons("*ntpr=NULL in do_cpte_reals_low");
354             }
355             nf = *nptr;
356         }
357     }
358     res = xdr_int(xd, &nf);
359     if (res == 0)
360     {
361         return -1;
362     }
363     if (list == NULL)
364     {
365         if (nval >= 0)
366         {
367             if (nf != nval)
368             {
369                 gmx_fatal(FARGS, "Count mismatch for state entry %s, code count is %d, file count is %d\n", st_names(cptp, ecpt), nval, nf);
370             }
371         }
372         else
373         {
374             *nptr = nf;
375         }
376     }
377     dt  = dtc;
378     res = xdr_int(xd, &dt);
379     if (res == 0)
380     {
381         return -1;
382     }
383     if (dt != dtc)
384     {
385         fprintf(stderr, "Precision mismatch for state entry %s, code precision is %s, file precision is %s\n",
386                 st_names(cptp, ecpt), xdr_datatype_names[dtc],
387                 xdr_datatype_names[dt]);
388     }
389     if (list || !(sflags & (1<<ecpt)))
390     {
391         snew(va, nf);
392         vp = va;
393     }
394     else
395     {
396         if (*v == NULL)
397         {
398             snew(*v, nf);
399         }
400         vp = *v;
401     }
402     if (dt == xdr_datatype_float)
403     {
404         if (dtc == xdr_datatype_float)
405         {
406             vf = (float *)vp;
407         }
408         else
409         {
410             snew(vf, nf);
411         }
412         res = xdr_vector(xd, (char *)vf, nf,
413                          (unsigned int)sizeof(float), (xdrproc_t)xdr_float);
414         if (res == 0)
415         {
416             return -1;
417         }
418         if (dtc != xdr_datatype_float)
419         {
420             for (i = 0; i < nf; i++)
421             {
422                 vp[i] = vf[i];
423             }
424             sfree(vf);
425         }
426     }
427     else
428     {
429         if (dtc == xdr_datatype_double)
430         {
431             /* cppcheck-suppress invalidPointerCast
432              * Only executed if real is anyhow double */
433             vd = (double *)vp;
434         }
435         else
436         {
437             snew(vd, nf);
438         }
439         res = xdr_vector(xd, (char *)vd, nf,
440                          (unsigned int)sizeof(double), (xdrproc_t)xdr_double);
441         if (res == 0)
442         {
443             return -1;
444         }
445         if (dtc != xdr_datatype_double)
446         {
447             for (i = 0; i < nf; i++)
448             {
449                 vp[i] = vd[i];
450             }
451             sfree(vd);
452         }
453     }
454
455     if (list)
456     {
457         switch (erealtype)
458         {
459             case ecprREAL:
460                 pr_reals(list, 0, st_names(cptp, ecpt), vp, nf);
461                 break;
462             case ecprRVEC:
463                 pr_rvecs(list, 0, st_names(cptp, ecpt), (rvec *)vp, nf/3);
464                 break;
465             default:
466                 gmx_incons("Unknown checkpoint real type");
467         }
468     }
469     if (va)
470     {
471         sfree(va);
472     }
473
474     return 0;
475 }
476
477
478 /* This function stores n along with the reals for reading,
479  * but on reading it assumes that n matches the value in the checkpoint file,
480  * a fatal error is generated when this is not the case.
481  */
482 static int do_cpte_reals(XDR *xd, int cptp, int ecpt, int sflags,
483                          int n, real **v, FILE *list)
484 {
485     return do_cpte_reals_low(xd, cptp, ecpt, sflags, n, NULL, v, list, ecprREAL);
486 }
487
488 /* This function does the same as do_cpte_reals,
489  * except that on reading it ignores the passed value of *n
490  * and stored the value read from the checkpoint file in *n.
491  */
492 static int do_cpte_n_reals(XDR *xd, int cptp, int ecpt, int sflags,
493                            int *n, real **v, FILE *list)
494 {
495     return do_cpte_reals_low(xd, cptp, ecpt, sflags, -1, n, v, list, ecprREAL);
496 }
497
498 static int do_cpte_real(XDR *xd, int cptp, int ecpt, int sflags,
499                         real *r, FILE *list)
500 {
501     return do_cpte_reals_low(xd, cptp, ecpt, sflags, 1, NULL, &r, list, ecprREAL);
502 }
503
504 static int do_cpte_ints(XDR *xd, int cptp, int ecpt, int sflags,
505                         int n, int **v, FILE *list)
506 {
507     bool_t res = 0;
508     int    dtc = xdr_datatype_int;
509     int   *vp, *va = NULL;
510     int    nf, dt;
511
512     nf  = n;
513     res = xdr_int(xd, &nf);
514     if (res == 0)
515     {
516         return -1;
517     }
518     if (list == NULL && v != NULL && nf != n)
519     {
520         gmx_fatal(FARGS, "Count mismatch for state entry %s, code count is %d, file count is %d\n", st_names(cptp, ecpt), n, nf);
521     }
522     dt  = dtc;
523     res = xdr_int(xd, &dt);
524     if (res == 0)
525     {
526         return -1;
527     }
528     if (dt != dtc)
529     {
530         gmx_fatal(FARGS, "Type mismatch for state entry %s, code type is %s, file type is %s\n",
531                   st_names(cptp, ecpt), xdr_datatype_names[dtc],
532                   xdr_datatype_names[dt]);
533     }
534     if (list || !(sflags & (1<<ecpt)) || v == NULL)
535     {
536         snew(va, nf);
537         vp = va;
538     }
539     else
540     {
541         if (*v == NULL)
542         {
543             snew(*v, nf);
544         }
545         vp = *v;
546     }
547     res = xdr_vector(xd, (char *)vp, nf,
548                      (unsigned int)sizeof(int), (xdrproc_t)xdr_int);
549     if (res == 0)
550     {
551         return -1;
552     }
553     if (list)
554     {
555         pr_ivec(list, 0, st_names(cptp, ecpt), vp, nf, TRUE);
556     }
557     if (va)
558     {
559         sfree(va);
560     }
561
562     return 0;
563 }
564
565 static int do_cpte_int(XDR *xd, int cptp, int ecpt, int sflags,
566                        int *i, FILE *list)
567 {
568     return do_cpte_ints(xd, cptp, ecpt, sflags, 1, &i, list);
569 }
570
571 static int do_cpte_doubles(XDR *xd, int cptp, int ecpt, int sflags,
572                            int n, double **v, FILE *list)
573 {
574     bool_t  res = 0;
575     int     dtc = xdr_datatype_double;
576     double *vp, *va = NULL;
577     int     nf, dt;
578
579     nf  = n;
580     res = xdr_int(xd, &nf);
581     if (res == 0)
582     {
583         return -1;
584     }
585     if (list == NULL && nf != n)
586     {
587         gmx_fatal(FARGS, "Count mismatch for state entry %s, code count is %d, file count is %d\n", st_names(cptp, ecpt), n, nf);
588     }
589     dt  = dtc;
590     res = xdr_int(xd, &dt);
591     if (res == 0)
592     {
593         return -1;
594     }
595     if (dt != dtc)
596     {
597         gmx_fatal(FARGS, "Precision mismatch for state entry %s, code precision is %s, file precision is %s\n",
598                   st_names(cptp, ecpt), xdr_datatype_names[dtc],
599                   xdr_datatype_names[dt]);
600     }
601     if (list || !(sflags & (1<<ecpt)))
602     {
603         snew(va, nf);
604         vp = va;
605     }
606     else
607     {
608         if (*v == NULL)
609         {
610             snew(*v, nf);
611         }
612         vp = *v;
613     }
614     res = xdr_vector(xd, (char *)vp, nf,
615                      (unsigned int)sizeof(double), (xdrproc_t)xdr_double);
616     if (res == 0)
617     {
618         return -1;
619     }
620     if (list)
621     {
622         pr_doubles(list, 0, st_names(cptp, ecpt), vp, nf);
623     }
624     if (va)
625     {
626         sfree(va);
627     }
628
629     return 0;
630 }
631
632 static int do_cpte_double(XDR *xd, int cptp, int ecpt, int sflags,
633                           double *r, FILE *list)
634 {
635     return do_cpte_doubles(xd, cptp, ecpt, sflags, 1, &r, list);
636 }
637
638
639 static int do_cpte_rvecs(XDR *xd, int cptp, int ecpt, int sflags,
640                          int n, rvec **v, FILE *list)
641 {
642     return do_cpte_reals_low(xd, cptp, ecpt, sflags,
643                              n*DIM, NULL, (real **)v, list, ecprRVEC);
644 }
645
646 static int do_cpte_matrix(XDR *xd, int cptp, int ecpt, int sflags,
647                           matrix v, FILE *list)
648 {
649     real *vr;
650     int   ret;
651
652     vr  = (real *)&(v[0][0]);
653     ret = do_cpte_reals_low(xd, cptp, ecpt, sflags,
654                             DIM*DIM, NULL, &vr, NULL, ecprMATRIX);
655
656     if (list && ret == 0)
657     {
658         pr_rvecs(list, 0, st_names(cptp, ecpt), v, DIM);
659     }
660
661     return ret;
662 }
663
664
665 static int do_cpte_nmatrix(XDR *xd, int cptp, int ecpt, int sflags,
666                            int n, real **v, FILE *list)
667 {
668     int   i;
669     int   ret, reti;
670     char  name[CPTSTRLEN];
671
672     ret = 0;
673     if (v == NULL)
674     {
675         snew(v, n);
676     }
677     for (i = 0; i < n; i++)
678     {
679         reti = do_cpte_reals_low(xd, cptp, ecpt, sflags, n, NULL, &(v[i]), NULL, ecprREAL);
680         if (list && reti == 0)
681         {
682             sprintf(name, "%s[%d]", st_names(cptp, ecpt), i);
683             pr_reals(list, 0, name, v[i], n);
684         }
685         if (reti != 0)
686         {
687             ret = reti;
688         }
689     }
690     return ret;
691 }
692
693 static int do_cpte_matrices(XDR *xd, int cptp, int ecpt, int sflags,
694                             int n, matrix **v, FILE *list)
695 {
696     bool_t  res = 0;
697     matrix *vp, *va = NULL;
698     real   *vr;
699     int     nf, i, j, k;
700     int     ret;
701
702     nf  = n;
703     res = xdr_int(xd, &nf);
704     if (res == 0)
705     {
706         return -1;
707     }
708     if (list == NULL && nf != n)
709     {
710         gmx_fatal(FARGS, "Count mismatch for state entry %s, code count is %d, file count is %d\n", st_names(cptp, ecpt), n, nf);
711     }
712     if (list || !(sflags & (1<<ecpt)))
713     {
714         snew(va, nf);
715         vp = va;
716     }
717     else
718     {
719         if (*v == NULL)
720         {
721             snew(*v, nf);
722         }
723         vp = *v;
724     }
725     snew(vr, nf*DIM*DIM);
726     for (i = 0; i < nf; i++)
727     {
728         for (j = 0; j < DIM; j++)
729         {
730             for (k = 0; k < DIM; k++)
731             {
732                 vr[(i*DIM+j)*DIM+k] = vp[i][j][k];
733             }
734         }
735     }
736     ret = do_cpte_reals_low(xd, cptp, ecpt, sflags,
737                             nf*DIM*DIM, NULL, &vr, NULL, ecprMATRIX);
738     for (i = 0; i < nf; i++)
739     {
740         for (j = 0; j < DIM; j++)
741         {
742             for (k = 0; k < DIM; k++)
743             {
744                 vp[i][j][k] = vr[(i*DIM+j)*DIM+k];
745             }
746         }
747     }
748     sfree(vr);
749
750     if (list && ret == 0)
751     {
752         for (i = 0; i < nf; i++)
753         {
754             pr_rvecs(list, 0, st_names(cptp, ecpt), vp[i], DIM);
755         }
756     }
757     if (va)
758     {
759         sfree(va);
760     }
761
762     return ret;
763 }
764
765 static void do_cpt_header(XDR *xd, gmx_bool bRead, int *file_version,
766                           char **version, char **btime, char **buser, char **bhost,
767                           int *double_prec,
768                           char **fprog, char **ftime,
769                           int *eIntegrator, int *simulation_part,
770                           gmx_int64_t *step, double *t,
771                           int *nnodes, int *dd_nc, int *npme,
772                           int *natoms, int *ngtc, int *nnhpres, int *nhchainlength,
773                           int *nlambda, int *flags_state,
774                           int *flags_eks, int *flags_enh, int *flags_dfh,
775                           int *nED, int *eSwapCoords,
776                           FILE *list)
777 {
778     bool_t res = 0;
779     int    magic;
780     int    idum = 0;
781     char  *fhost;
782
783     if (bRead)
784     {
785         magic = -1;
786     }
787     else
788     {
789         magic = CPT_MAGIC1;
790     }
791     res = xdr_int(xd, &magic);
792     if (res == 0)
793     {
794         gmx_fatal(FARGS, "The checkpoint file is empty/corrupted, or maybe you are out of disk space?");
795     }
796     if (magic != CPT_MAGIC1)
797     {
798         gmx_fatal(FARGS, "Start of file magic number mismatch, checkpoint file has %d, should be %d\n"
799                   "The checkpoint file is corrupted or not a checkpoint file",
800                   magic, CPT_MAGIC1);
801     }
802     if (!bRead)
803     {
804         snew(fhost, 255);
805         gmx_gethostname(fhost, 255);
806     }
807     do_cpt_string_err(xd, bRead, "GROMACS version", version, list);
808     do_cpt_string_err(xd, bRead, "GROMACS build time", btime, list);
809     do_cpt_string_err(xd, bRead, "GROMACS build user", buser, list);
810     do_cpt_string_err(xd, bRead, "GROMACS build host", bhost, list);
811     do_cpt_string_err(xd, bRead, "generating program", fprog, list);
812     do_cpt_string_err(xd, bRead, "generation time", ftime, list);
813     *file_version = cpt_version;
814     do_cpt_int_err(xd, "checkpoint file version", file_version, list);
815     if (*file_version > cpt_version)
816     {
817         gmx_fatal(FARGS, "Attempting to read a checkpoint file of version %d with code of version %d\n", *file_version, cpt_version);
818     }
819     if (*file_version >= 13)
820     {
821         do_cpt_int_err(xd, "GROMACS double precision", double_prec, list);
822     }
823     else
824     {
825         *double_prec = -1;
826     }
827     if (*file_version >= 12)
828     {
829         do_cpt_string_err(xd, bRead, "generating host", &fhost, list);
830         if (list == NULL)
831         {
832             sfree(fhost);
833         }
834     }
835     do_cpt_int_err(xd, "#atoms", natoms, list);
836     do_cpt_int_err(xd, "#T-coupling groups", ngtc, list);
837     if (*file_version >= 10)
838     {
839         do_cpt_int_err(xd, "#Nose-Hoover T-chains", nhchainlength, list);
840     }
841     else
842     {
843         *nhchainlength = 1;
844     }
845     if (*file_version >= 11)
846     {
847         do_cpt_int_err(xd, "#Nose-Hoover T-chains for barostat ", nnhpres, list);
848     }
849     else
850     {
851         *nnhpres = 0;
852     }
853     if (*file_version >= 14)
854     {
855         do_cpt_int_err(xd, "# of total lambda states ", nlambda, list);
856     }
857     else
858     {
859         *nlambda = 0;
860     }
861     do_cpt_int_err(xd, "integrator", eIntegrator, list);
862     if (*file_version >= 3)
863     {
864         do_cpt_int_err(xd, "simulation part #", simulation_part, list);
865     }
866     else
867     {
868         *simulation_part = 1;
869     }
870     if (*file_version >= 5)
871     {
872         do_cpt_step_err(xd, "step", step, list);
873     }
874     else
875     {
876         do_cpt_int_err(xd, "step", &idum, list);
877         *step = idum;
878     }
879     do_cpt_double_err(xd, "t", t, list);
880     do_cpt_int_err(xd, "#PP-ranks", nnodes, list);
881     idum = 1;
882     do_cpt_int_err(xd, "dd_nc[x]", dd_nc ? &(dd_nc[0]) : &idum, list);
883     do_cpt_int_err(xd, "dd_nc[y]", dd_nc ? &(dd_nc[1]) : &idum, list);
884     do_cpt_int_err(xd, "dd_nc[z]", dd_nc ? &(dd_nc[2]) : &idum, list);
885     do_cpt_int_err(xd, "#PME-only ranks", npme, list);
886     do_cpt_int_err(xd, "state flags", flags_state, list);
887     if (*file_version >= 4)
888     {
889         do_cpt_int_err(xd, "ekin data flags", flags_eks, list);
890         do_cpt_int_err(xd, "energy history flags", flags_enh, list);
891     }
892     else
893     {
894         *flags_eks   = 0;
895         *flags_enh   = (*flags_state >> (estORIRE_DTAV+1));
896         *flags_state = (*flags_state & ~((1<<(estORIRE_DTAV+1)) |
897                                          (1<<(estORIRE_DTAV+2)) |
898                                          (1<<(estORIRE_DTAV+3))));
899     }
900     if (*file_version >= 14)
901     {
902         do_cpt_int_err(xd, "df history flags", flags_dfh, list);
903     }
904     else
905     {
906         *flags_dfh = 0;
907     }
908
909     if (*file_version >= 15)
910     {
911         do_cpt_int_err(xd, "ED data sets", nED, list);
912     }
913     else
914     {
915         *nED = 0;
916     }
917     if (*file_version >= 16)
918     {
919         do_cpt_int_err(xd, "swap", eSwapCoords, list);
920     }
921 }
922
923 static int do_cpt_footer(XDR *xd, int file_version)
924 {
925     bool_t res = 0;
926     int    magic;
927
928     if (file_version >= 2)
929     {
930         magic = CPT_MAGIC2;
931         res   = xdr_int(xd, &magic);
932         if (res == 0)
933         {
934             cp_error();
935         }
936         if (magic != CPT_MAGIC2)
937         {
938             return -1;
939         }
940     }
941
942     return 0;
943 }
944
945 static int do_cpt_state(XDR *xd, gmx_bool bRead,
946                         int fflags, t_state *state,
947                         FILE *list)
948 {
949     int    sflags;
950     int    i;
951     int    ret;
952     int    nnht, nnhtp;
953
954     ret = 0;
955
956     nnht  = state->nhchainlength*state->ngtc;
957     nnhtp = state->nhchainlength*state->nnhpres;
958
959     if (bRead) /* we need to allocate space for dfhist if we are reading */
960     {
961         init_df_history(&state->dfhist, state->dfhist.nlambda);
962     }
963
964     sflags = state->flags;
965     for (i = 0; (i < estNR && ret == 0); i++)
966     {
967         if (fflags & (1<<i))
968         {
969             switch (i)
970             {
971                 case estLAMBDA:  ret      = do_cpte_reals(xd, cptpEST, i, sflags, efptNR, &(state->lambda), list); break;
972                 case estFEPSTATE: ret     = do_cpte_int (xd, cptpEST, i, sflags, &state->fep_state, list); break;
973                 case estBOX:     ret      = do_cpte_matrix(xd, cptpEST, i, sflags, state->box, list); break;
974                 case estBOX_REL: ret      = do_cpte_matrix(xd, cptpEST, i, sflags, state->box_rel, list); break;
975                 case estBOXV:    ret      = do_cpte_matrix(xd, cptpEST, i, sflags, state->boxv, list); break;
976                 case estPRES_PREV: ret    = do_cpte_matrix(xd, cptpEST, i, sflags, state->pres_prev, list); break;
977                 case estSVIR_PREV:  ret   = do_cpte_matrix(xd, cptpEST, i, sflags, state->svir_prev, list); break;
978                 case estFVIR_PREV:  ret   = do_cpte_matrix(xd, cptpEST, i, sflags, state->fvir_prev, list); break;
979                 case estNH_XI:   ret      = do_cpte_doubles(xd, cptpEST, i, sflags, nnht, &state->nosehoover_xi, list); break;
980                 case estNH_VXI:  ret      = do_cpte_doubles(xd, cptpEST, i, sflags, nnht, &state->nosehoover_vxi, list); break;
981                 case estNHPRES_XI:   ret  = do_cpte_doubles(xd, cptpEST, i, sflags, nnhtp, &state->nhpres_xi, list); break;
982                 case estNHPRES_VXI:  ret  = do_cpte_doubles(xd, cptpEST, i, sflags, nnhtp, &state->nhpres_vxi, list); break;
983                 case estTC_INT:  ret      = do_cpte_doubles(xd, cptpEST, i, sflags, state->ngtc, &state->therm_integral, list); break;
984                 case estVETA:    ret      = do_cpte_real(xd, cptpEST, i, sflags, &state->veta, list); break;
985                 case estVOL0:    ret      = do_cpte_real(xd, cptpEST, i, sflags, &state->vol0, list); break;
986                 case estX:       ret      = do_cpte_rvecs(xd, cptpEST, i, sflags, state->natoms, &state->x, list); break;
987                 case estV:       ret      = do_cpte_rvecs(xd, cptpEST, i, sflags, state->natoms, &state->v, list); break;
988                 case estSDX:     ret      = do_cpte_rvecs(xd, cptpEST, i, sflags, state->natoms, &state->sd_X, list); break;
989                 /* The RNG entries are no longer written,
990                  * the next 4 lines are only for reading old files.
991                  */
992                 case estLD_RNG:  ret      = do_cpte_ints(xd, cptpEST, i, sflags, 0, NULL, list); break;
993                 case estLD_RNGI: ret      = do_cpte_ints(xd, cptpEST, i, sflags, 0, NULL, list); break;
994                 case estMC_RNG:  ret      = do_cpte_ints(xd, cptpEST, i, sflags, 0, NULL, list); break;
995                 case estMC_RNGI: ret      = do_cpte_ints(xd, cptpEST, i, sflags, 0, NULL, list); break;
996                 case estDISRE_INITF:  ret = do_cpte_real (xd, cptpEST, i, sflags, &state->hist.disre_initf, list); break;
997                 case estDISRE_RM3TAV: ret = do_cpte_n_reals(xd, cptpEST, i, sflags, &state->hist.ndisrepairs, &state->hist.disre_rm3tav, list); break;
998                 case estORIRE_INITF:  ret = do_cpte_real (xd, cptpEST, i, sflags, &state->hist.orire_initf, list); break;
999                 case estORIRE_DTAV:   ret = do_cpte_n_reals(xd, cptpEST, i, sflags, &state->hist.norire_Dtav, &state->hist.orire_Dtav, list); break;
1000                 default:
1001                     gmx_fatal(FARGS, "Unknown state entry %d\n"
1002                               "You are probably reading a new checkpoint file with old code", i);
1003             }
1004         }
1005     }
1006
1007     return ret;
1008 }
1009
1010 static int do_cpt_ekinstate(XDR *xd, int fflags, ekinstate_t *ekins,
1011                             FILE *list)
1012 {
1013     int  i;
1014     int  ret;
1015
1016     ret = 0;
1017
1018     for (i = 0; (i < eeksNR && ret == 0); i++)
1019     {
1020         if (fflags & (1<<i))
1021         {
1022             switch (i)
1023             {
1024
1025                 case eeksEKIN_N:     ret = do_cpte_int(xd, cptpEEKS, i, fflags, &ekins->ekin_n, list); break;
1026                 case eeksEKINH:     ret  = do_cpte_matrices(xd, cptpEEKS, i, fflags, ekins->ekin_n, &ekins->ekinh, list); break;
1027                 case eeksEKINF:      ret = do_cpte_matrices(xd, cptpEEKS, i, fflags, ekins->ekin_n, &ekins->ekinf, list); break;
1028                 case eeksEKINO:      ret = do_cpte_matrices(xd, cptpEEKS, i, fflags, ekins->ekin_n, &ekins->ekinh_old, list); break;
1029                 case eeksEKINTOTAL:  ret = do_cpte_matrix(xd, cptpEEKS, i, fflags, ekins->ekin_total, list); break;
1030                 case eeksEKINSCALEF: ret = do_cpte_doubles(xd, cptpEEKS, i, fflags, ekins->ekin_n, &ekins->ekinscalef_nhc, list); break;
1031                 case eeksVSCALE:     ret = do_cpte_doubles(xd, 1, cptpEEKS, fflags, ekins->ekin_n, &ekins->vscale_nhc, list); break;
1032                 case eeksEKINSCALEH: ret = do_cpte_doubles(xd, 1, cptpEEKS, fflags, ekins->ekin_n, &ekins->ekinscaleh_nhc, list); break;
1033                 case eeksDEKINDL:   ret  = do_cpte_real(xd, 1, cptpEEKS, fflags, &ekins->dekindl, list); break;
1034                 case eeksMVCOS:      ret = do_cpte_real(xd, 1, cptpEEKS, fflags, &ekins->mvcos, list); break;
1035                 default:
1036                     gmx_fatal(FARGS, "Unknown ekin data state entry %d\n"
1037                               "You are probably reading a new checkpoint file with old code", i);
1038             }
1039         }
1040     }
1041
1042     return ret;
1043 }
1044
1045
1046 static int do_cpt_swapstate(XDR *xd, gmx_bool bRead, swapstate_t *swapstate, FILE *list)
1047 {
1048     int ii, ic, j;
1049     int ret              = 0;
1050     int swap_cpt_version = 1;
1051
1052
1053     if (eswapNO == swapstate->eSwapCoords)
1054     {
1055         return ret;
1056     }
1057
1058     swapstate->bFromCpt = bRead;
1059
1060     do_cpt_int_err(xd, "swap checkpoint version", &swap_cpt_version, list);
1061     do_cpt_int_err(xd, "swap coupling steps", &swapstate->nAverage, list);
1062
1063     /* When reading, init_swapcoords has not been called yet,
1064      * so we have to allocate memory first. */
1065
1066     for (ic = 0; ic < eCompNR; ic++)
1067     {
1068         for (ii = 0; ii < eIonNR; ii++)
1069         {
1070             if (bRead)
1071             {
1072                 do_cpt_int_err(xd, "swap requested atoms", &swapstate->nat_req[ic][ii], list);
1073             }
1074             else
1075             {
1076                 do_cpt_int_err(xd, "swap requested atoms p", swapstate->nat_req_p[ic][ii], list);
1077             }
1078
1079             if (bRead)
1080             {
1081                 do_cpt_int_err(xd, "swap influx netto", &swapstate->inflow_netto[ic][ii], list);
1082             }
1083             else
1084             {
1085                 do_cpt_int_err(xd, "swap influx netto p", swapstate->inflow_netto_p[ic][ii], list);
1086             }
1087
1088             if (bRead && (NULL == swapstate->nat_past[ic][ii]) )
1089             {
1090                 snew(swapstate->nat_past[ic][ii], swapstate->nAverage);
1091             }
1092
1093             for (j = 0; j < swapstate->nAverage; j++)
1094             {
1095                 if (bRead)
1096                 {
1097                     do_cpt_int_err(xd, "swap past atom counts", &swapstate->nat_past[ic][ii][j], list);
1098                 }
1099                 else
1100                 {
1101                     do_cpt_int_err(xd, "swap past atom counts p", &swapstate->nat_past_p[ic][ii][j], list);
1102                 }
1103             }
1104         }
1105     }
1106
1107     /* Ion flux per channel */
1108     for (ic = 0; ic < eChanNR; ic++)
1109     {
1110         for (ii = 0; ii < eIonNR; ii++)
1111         {
1112             if (bRead)
1113             {
1114                 do_cpt_int_err(xd, "channel flux", &swapstate->fluxfromAtoB[ic][ii], list);
1115             }
1116             else
1117             {
1118                 do_cpt_int_err(xd, "channel flux p", swapstate->fluxfromAtoB_p[ic][ii], list);
1119             }
1120         }
1121     }
1122
1123     /* Ion flux leakage */
1124     if (bRead)
1125     {
1126         snew(swapstate->fluxleak, 1);
1127     }
1128     do_cpt_int_err(xd, "flux leakage", swapstate->fluxleak, list);
1129
1130     /* Ion history */
1131     do_cpt_int_err(xd, "number of ions", &swapstate->nions, list);
1132
1133     if (bRead)
1134     {
1135         snew(swapstate->channel_label, swapstate->nions);
1136         snew(swapstate->comp_from, swapstate->nions);
1137     }
1138
1139     do_cpt_u_chars(xd, "channel history", swapstate->nions, swapstate->channel_label, list);
1140     do_cpt_u_chars(xd, "domain history", swapstate->nions, swapstate->comp_from, list);
1141
1142     /* Save the last known whole positions to checkpoint
1143      * file to be able to also make multimeric channels whole in PBC */
1144     do_cpt_int_err(xd, "Ch0 atoms", &swapstate->nat[eChan0], list);
1145     do_cpt_int_err(xd, "Ch1 atoms", &swapstate->nat[eChan1], list);
1146     if (bRead)
1147     {
1148         snew(swapstate->xc_old_whole[eChan0], swapstate->nat[eChan0]);
1149         snew(swapstate->xc_old_whole[eChan1], swapstate->nat[eChan1]);
1150         do_cpt_n_rvecs_err(xd, "Ch0 whole x", swapstate->nat[eChan0], swapstate->xc_old_whole[eChan0], list);
1151         do_cpt_n_rvecs_err(xd, "Ch1 whole x", swapstate->nat[eChan1], swapstate->xc_old_whole[eChan1], list);
1152     }
1153     else
1154     {
1155         do_cpt_n_rvecs_err(xd, "Ch0 whole x", swapstate->nat[eChan0], *swapstate->xc_old_whole_p[eChan0], list);
1156         do_cpt_n_rvecs_err(xd, "Ch1 whole x", swapstate->nat[eChan1], *swapstate->xc_old_whole_p[eChan1], list);
1157     }
1158
1159     return ret;
1160 }
1161
1162
1163 static int do_cpt_enerhist(XDR *xd, gmx_bool bRead,
1164                            int fflags, energyhistory_t *enerhist,
1165                            FILE *list)
1166 {
1167     int  i;
1168     int  j;
1169     int  ret;
1170
1171     ret = 0;
1172
1173     if (bRead)
1174     {
1175         enerhist->nsteps     = 0;
1176         enerhist->nsum       = 0;
1177         enerhist->nsteps_sim = 0;
1178         enerhist->nsum_sim   = 0;
1179         enerhist->dht        = NULL;
1180
1181         if (fflags & (1<< eenhENERGY_DELTA_H_NN) )
1182         {
1183             snew(enerhist->dht, 1);
1184             enerhist->dht->ndh              = NULL;
1185             enerhist->dht->dh               = NULL;
1186             enerhist->dht->start_lambda_set = FALSE;
1187         }
1188     }
1189
1190     for (i = 0; (i < eenhNR && ret == 0); i++)
1191     {
1192         if (fflags & (1<<i))
1193         {
1194             switch (i)
1195             {
1196                 case eenhENERGY_N:     ret = do_cpte_int(xd, cptpEENH, i, fflags, &enerhist->nener, list); break;
1197                 case eenhENERGY_AVER:  ret = do_cpte_doubles(xd, cptpEENH, i, fflags, enerhist->nener, &enerhist->ener_ave, list); break;
1198                 case eenhENERGY_SUM:   ret = do_cpte_doubles(xd, cptpEENH, i, fflags, enerhist->nener, &enerhist->ener_sum, list); break;
1199                 case eenhENERGY_NSUM:  do_cpt_step_err(xd, eenh_names[i], &enerhist->nsum, list); break;
1200                 case eenhENERGY_SUM_SIM: ret = do_cpte_doubles(xd, cptpEENH, i, fflags, enerhist->nener, &enerhist->ener_sum_sim, list); break;
1201                 case eenhENERGY_NSUM_SIM:   do_cpt_step_err(xd, eenh_names[i], &enerhist->nsum_sim, list); break;
1202                 case eenhENERGY_NSTEPS:     do_cpt_step_err(xd, eenh_names[i], &enerhist->nsteps, list); break;
1203                 case eenhENERGY_NSTEPS_SIM: do_cpt_step_err(xd, eenh_names[i], &enerhist->nsteps_sim, list); break;
1204                 case eenhENERGY_DELTA_H_NN: do_cpt_int_err(xd, eenh_names[i], &(enerhist->dht->nndh), list);
1205                     if (bRead) /* now allocate memory for it */
1206                     {
1207                         snew(enerhist->dht->dh, enerhist->dht->nndh);
1208                         snew(enerhist->dht->ndh, enerhist->dht->nndh);
1209                         for (j = 0; j < enerhist->dht->nndh; j++)
1210                         {
1211                             enerhist->dht->ndh[j] = 0;
1212                             enerhist->dht->dh[j]  = NULL;
1213                         }
1214                     }
1215                     break;
1216                 case eenhENERGY_DELTA_H_LIST:
1217                     for (j = 0; j < enerhist->dht->nndh; j++)
1218                     {
1219                         ret = do_cpte_n_reals(xd, cptpEENH, i, fflags, &enerhist->dht->ndh[j], &(enerhist->dht->dh[j]), list);
1220                     }
1221                     break;
1222                 case eenhENERGY_DELTA_H_STARTTIME:
1223                     ret = do_cpte_double(xd, cptpEENH, i, fflags, &(enerhist->dht->start_time), list); break;
1224                 case eenhENERGY_DELTA_H_STARTLAMBDA:
1225                     ret = do_cpte_double(xd, cptpEENH, i, fflags, &(enerhist->dht->start_lambda), list); break;
1226                 default:
1227                     gmx_fatal(FARGS, "Unknown energy history entry %d\n"
1228                               "You are probably reading a new checkpoint file with old code", i);
1229             }
1230         }
1231     }
1232
1233     if ((fflags & (1<<eenhENERGY_SUM)) && !(fflags & (1<<eenhENERGY_SUM_SIM)))
1234     {
1235         /* Assume we have an old file format and copy sum to sum_sim */
1236         srenew(enerhist->ener_sum_sim, enerhist->nener);
1237         for (i = 0; i < enerhist->nener; i++)
1238         {
1239             enerhist->ener_sum_sim[i] = enerhist->ener_sum[i];
1240         }
1241     }
1242
1243     if ( (fflags & (1<<eenhENERGY_NSUM)) &&
1244          !(fflags & (1<<eenhENERGY_NSTEPS)))
1245     {
1246         /* Assume we have an old file format and copy nsum to nsteps */
1247         enerhist->nsteps = enerhist->nsum;
1248     }
1249     if ( (fflags & (1<<eenhENERGY_NSUM_SIM)) &&
1250          !(fflags & (1<<eenhENERGY_NSTEPS_SIM)))
1251     {
1252         /* Assume we have an old file format and copy nsum to nsteps */
1253         enerhist->nsteps_sim = enerhist->nsum_sim;
1254     }
1255
1256     return ret;
1257 }
1258
1259 static int do_cpt_df_hist(XDR *xd, int fflags, df_history_t *dfhist, FILE *list)
1260 {
1261     int  i, nlambda;
1262     int  ret;
1263
1264     nlambda = dfhist->nlambda;
1265     ret     = 0;
1266
1267     for (i = 0; (i < edfhNR && ret == 0); i++)
1268     {
1269         if (fflags & (1<<i))
1270         {
1271             switch (i)
1272             {
1273                 case edfhBEQUIL:       ret = do_cpte_int(xd, cptpEDFH, i, fflags, &dfhist->bEquil, list); break;
1274                 case edfhNATLAMBDA:    ret = do_cpte_ints(xd, cptpEDFH, i, fflags, nlambda, &dfhist->n_at_lam, list); break;
1275                 case edfhWLHISTO:      ret = do_cpte_reals(xd, cptpEDFH, i, fflags, nlambda, &dfhist->wl_histo, list); break;
1276                 case edfhWLDELTA:      ret = do_cpte_real(xd, cptpEDFH, i, fflags, &dfhist->wl_delta, list); break;
1277                 case edfhSUMWEIGHTS:   ret = do_cpte_reals(xd, cptpEDFH, i, fflags, nlambda, &dfhist->sum_weights, list); break;
1278                 case edfhSUMDG:        ret = do_cpte_reals(xd, cptpEDFH, i, fflags, nlambda, &dfhist->sum_dg, list); break;
1279                 case edfhSUMMINVAR:    ret = do_cpte_reals(xd, cptpEDFH, i, fflags, nlambda, &dfhist->sum_minvar, list); break;
1280                 case edfhSUMVAR:       ret = do_cpte_reals(xd, cptpEDFH, i, fflags, nlambda, &dfhist->sum_variance, list); break;
1281                 case edfhACCUMP:       ret = do_cpte_nmatrix(xd, cptpEDFH, i, fflags, nlambda, dfhist->accum_p, list); break;
1282                 case edfhACCUMM:       ret = do_cpte_nmatrix(xd, cptpEDFH, i, fflags, nlambda, dfhist->accum_m, list); break;
1283                 case edfhACCUMP2:      ret = do_cpte_nmatrix(xd, cptpEDFH, i, fflags, nlambda, dfhist->accum_p2, list); break;
1284                 case edfhACCUMM2:      ret = do_cpte_nmatrix(xd, cptpEDFH, i, fflags, nlambda, dfhist->accum_m2, list); break;
1285                 case edfhTIJ:          ret = do_cpte_nmatrix(xd, cptpEDFH, i, fflags, nlambda, dfhist->Tij, list); break;
1286                 case edfhTIJEMP:       ret = do_cpte_nmatrix(xd, cptpEDFH, i, fflags, nlambda, dfhist->Tij_empirical, list); break;
1287
1288                 default:
1289                     gmx_fatal(FARGS, "Unknown df history entry %d\n"
1290                               "You are probably reading a new checkpoint file with old code", i);
1291             }
1292         }
1293     }
1294
1295     return ret;
1296 }
1297
1298
1299 /* This function stores the last whole configuration of the reference and
1300  * average structure in the .cpt file
1301  */
1302 static int do_cpt_EDstate(XDR *xd, gmx_bool bRead,
1303                           edsamstate_t *EDstate, FILE *list)
1304 {
1305     int  i;
1306     int  ret = 0;
1307     char buf[STRLEN];
1308
1309
1310     EDstate->bFromCpt = bRead;
1311
1312     if (EDstate->nED <= 0)
1313     {
1314         return ret;
1315     }
1316
1317     /* When reading, init_edsam has not been called yet,
1318      * so we have to allocate memory first. */
1319     if (bRead)
1320     {
1321         snew(EDstate->nref, EDstate->nED);
1322         snew(EDstate->old_sref, EDstate->nED);
1323         snew(EDstate->nav, EDstate->nED);
1324         snew(EDstate->old_sav, EDstate->nED);
1325     }
1326
1327     /* Read/write the last whole conformation of SREF and SAV for each ED dataset (usually only one) */
1328     for (i = 0; i < EDstate->nED; i++)
1329     {
1330         /* Reference structure SREF */
1331         sprintf(buf, "ED%d # of atoms in reference structure", i+1);
1332         do_cpt_int_err(xd, buf, &EDstate->nref[i], list);
1333         sprintf(buf, "ED%d x_ref", i+1);
1334         if (bRead)
1335         {
1336             snew(EDstate->old_sref[i], EDstate->nref[i]);
1337             do_cpt_n_rvecs_err(xd, buf, EDstate->nref[i], EDstate->old_sref[i], list);
1338         }
1339         else
1340         {
1341             do_cpt_n_rvecs_err(xd, buf, EDstate->nref[i], EDstate->old_sref_p[i], list);
1342         }
1343
1344         /* Average structure SAV */
1345         sprintf(buf, "ED%d # of atoms in average structure", i+1);
1346         do_cpt_int_err(xd, buf, &EDstate->nav[i], list);
1347         sprintf(buf, "ED%d x_av", i+1);
1348         if (bRead)
1349         {
1350             snew(EDstate->old_sav[i], EDstate->nav[i]);
1351             do_cpt_n_rvecs_err(xd, buf, EDstate->nav[i], EDstate->old_sav[i], list);
1352         }
1353         else
1354         {
1355             do_cpt_n_rvecs_err(xd, buf, EDstate->nav[i], EDstate->old_sav_p[i], list);
1356         }
1357     }
1358
1359     return ret;
1360 }
1361
1362
1363 static int do_cpt_files(XDR *xd, gmx_bool bRead,
1364                         gmx_file_position_t **p_outputfiles, int *nfiles,
1365                         FILE *list, int file_version)
1366 {
1367     int                  i;
1368     gmx_off_t            offset;
1369     gmx_off_t            mask = 0xFFFFFFFFL;
1370     int                  offset_high, offset_low;
1371     char                *buf;
1372     gmx_file_position_t *outputfiles;
1373
1374     if (do_cpt_int(xd, "number of output files", nfiles, list) != 0)
1375     {
1376         return -1;
1377     }
1378
1379     if (bRead)
1380     {
1381         snew(*p_outputfiles, *nfiles);
1382     }
1383
1384     outputfiles = *p_outputfiles;
1385
1386     for (i = 0; i < *nfiles; i++)
1387     {
1388         /* 64-bit XDR numbers are not portable, so it is stored as separate high/low fractions */
1389         if (bRead)
1390         {
1391             do_cpt_string_err(xd, bRead, "output filename", &buf, list);
1392             strncpy(outputfiles[i].filename, buf, CPTSTRLEN-1);
1393             if (list == NULL)
1394             {
1395                 sfree(buf);
1396             }
1397
1398             if (do_cpt_int(xd, "file_offset_high", &offset_high, list) != 0)
1399             {
1400                 return -1;
1401             }
1402             if (do_cpt_int(xd, "file_offset_low", &offset_low, list) != 0)
1403             {
1404                 return -1;
1405             }
1406             outputfiles[i].offset = ( ((gmx_off_t) offset_high) << 32 ) | ( (gmx_off_t) offset_low & mask );
1407         }
1408         else
1409         {
1410             buf = outputfiles[i].filename;
1411             do_cpt_string_err(xd, bRead, "output filename", &buf, list);
1412             /* writing */
1413             offset      = outputfiles[i].offset;
1414             if (offset == -1)
1415             {
1416                 offset_low  = -1;
1417                 offset_high = -1;
1418             }
1419             else
1420             {
1421                 offset_low  = (int) (offset & mask);
1422                 offset_high = (int) ((offset >> 32) & mask);
1423             }
1424             if (do_cpt_int(xd, "file_offset_high", &offset_high, list) != 0)
1425             {
1426                 return -1;
1427             }
1428             if (do_cpt_int(xd, "file_offset_low", &offset_low, list) != 0)
1429             {
1430                 return -1;
1431             }
1432         }
1433         if (file_version >= 8)
1434         {
1435             if (do_cpt_int(xd, "file_checksum_size", &(outputfiles[i].chksum_size),
1436                            list) != 0)
1437             {
1438                 return -1;
1439             }
1440             if (do_cpt_u_chars(xd, "file_checksum", 16, outputfiles[i].chksum, list) != 0)
1441             {
1442                 return -1;
1443             }
1444         }
1445         else
1446         {
1447             outputfiles[i].chksum_size = -1;
1448         }
1449     }
1450     return 0;
1451 }
1452
1453
1454 void write_checkpoint(const char *fn, gmx_bool bNumberAndKeep,
1455                       FILE *fplog, t_commrec *cr,
1456                       int eIntegrator, int simulation_part,
1457                       gmx_bool bExpanded, int elamstats,
1458                       gmx_int64_t step, double t, t_state *state)
1459 {
1460     t_fileio            *fp;
1461     int                  file_version;
1462     char                *version;
1463     char                *btime;
1464     char                *buser;
1465     char                *bhost;
1466     int                  double_prec;
1467     char                *fprog;
1468     char                *fntemp; /* the temporary checkpoint file name */
1469     char                 timebuf[STRLEN];
1470     int                  nppnodes, npmenodes;
1471     char                 buf[1024], suffix[5+STEPSTRSIZE], sbuf[STEPSTRSIZE];
1472     gmx_file_position_t *outputfiles;
1473     int                  noutputfiles;
1474     char                *ftime;
1475     int                  flags_eks, flags_enh, flags_dfh;
1476     t_fileio            *ret;
1477
1478     if (DOMAINDECOMP(cr))
1479     {
1480         nppnodes  = cr->dd->nnodes;
1481         npmenodes = cr->npmenodes;
1482     }
1483     else
1484     {
1485         nppnodes  = 1;
1486         npmenodes = 0;
1487     }
1488
1489 #ifndef GMX_NO_RENAME
1490     /* make the new temporary filename */
1491     snew(fntemp, strlen(fn)+5+STEPSTRSIZE);
1492     strcpy(fntemp, fn);
1493     fntemp[strlen(fn) - strlen(ftp2ext(fn2ftp(fn))) - 1] = '\0';
1494     sprintf(suffix, "_%s%s", "step", gmx_step_str(step, sbuf));
1495     strcat(fntemp, suffix);
1496     strcat(fntemp, fn+strlen(fn) - strlen(ftp2ext(fn2ftp(fn))) - 1);
1497 #else
1498     /* if we can't rename, we just overwrite the cpt file.
1499      * dangerous if interrupted.
1500      */
1501     snew(fntemp, strlen(fn));
1502     strcpy(fntemp, fn);
1503 #endif
1504     gmx_format_current_time(timebuf, STRLEN);
1505
1506     if (fplog)
1507     {
1508         fprintf(fplog, "Writing checkpoint, step %s at %s\n\n",
1509                 gmx_step_str(step, buf), timebuf);
1510     }
1511
1512     /* Get offsets for open files */
1513     gmx_fio_get_output_file_positions(&outputfiles, &noutputfiles);
1514
1515     fp = gmx_fio_open(fntemp, "w");
1516
1517     if (state->ekinstate.bUpToDate)
1518     {
1519         flags_eks =
1520             ((1<<eeksEKIN_N) | (1<<eeksEKINH) | (1<<eeksEKINF) |
1521              (1<<eeksEKINO) | (1<<eeksEKINSCALEF) | (1<<eeksEKINSCALEH) |
1522              (1<<eeksVSCALE) | (1<<eeksDEKINDL) | (1<<eeksMVCOS));
1523     }
1524     else
1525     {
1526         flags_eks = 0;
1527     }
1528
1529     flags_enh = 0;
1530     if (state->enerhist.nsum > 0 || state->enerhist.nsum_sim > 0)
1531     {
1532         flags_enh |= (1<<eenhENERGY_N);
1533         if (state->enerhist.nsum > 0)
1534         {
1535             flags_enh |= ((1<<eenhENERGY_AVER) | (1<<eenhENERGY_SUM) |
1536                           (1<<eenhENERGY_NSTEPS) | (1<<eenhENERGY_NSUM));
1537         }
1538         if (state->enerhist.nsum_sim > 0)
1539         {
1540             flags_enh |= ((1<<eenhENERGY_SUM_SIM) | (1<<eenhENERGY_NSTEPS_SIM) |
1541                           (1<<eenhENERGY_NSUM_SIM));
1542         }
1543         if (state->enerhist.dht)
1544         {
1545             flags_enh |= ( (1<< eenhENERGY_DELTA_H_NN) |
1546                            (1<< eenhENERGY_DELTA_H_LIST) |
1547                            (1<< eenhENERGY_DELTA_H_STARTTIME) |
1548                            (1<< eenhENERGY_DELTA_H_STARTLAMBDA) );
1549         }
1550     }
1551
1552     if (bExpanded)
1553     {
1554         flags_dfh = ((1<<edfhBEQUIL) | (1<<edfhNATLAMBDA) | (1<<edfhSUMWEIGHTS) |  (1<<edfhSUMDG)  |
1555                      (1<<edfhTIJ) | (1<<edfhTIJEMP));
1556         if (EWL(elamstats))
1557         {
1558             flags_dfh |= ((1<<edfhWLDELTA) | (1<<edfhWLHISTO));
1559         }
1560         if ((elamstats == elamstatsMINVAR) || (elamstats == elamstatsBARKER) || (elamstats == elamstatsMETROPOLIS))
1561         {
1562             flags_dfh |= ((1<<edfhACCUMP) | (1<<edfhACCUMM) | (1<<edfhACCUMP2) | (1<<edfhACCUMM2)
1563                           | (1<<edfhSUMMINVAR) | (1<<edfhSUMVAR));
1564         }
1565     }
1566     else
1567     {
1568         flags_dfh = 0;
1569     }
1570
1571     /* We can check many more things now (CPU, acceleration, etc), but
1572      * it is highly unlikely to have two separate builds with exactly
1573      * the same version, user, time, and build host!
1574      */
1575
1576     version = gmx_strdup(gmx_version());
1577     btime   = gmx_strdup(BUILD_TIME);
1578     buser   = gmx_strdup(BUILD_USER);
1579     bhost   = gmx_strdup(BUILD_HOST);
1580
1581     double_prec = GMX_CPT_BUILD_DP;
1582     fprog       = gmx_strdup(Program());
1583
1584     ftime   = &(timebuf[0]);
1585
1586     do_cpt_header(gmx_fio_getxdr(fp), FALSE, &file_version,
1587                   &version, &btime, &buser, &bhost, &double_prec, &fprog, &ftime,
1588                   &eIntegrator, &simulation_part, &step, &t, &nppnodes,
1589                   DOMAINDECOMP(cr) ? cr->dd->nc : NULL, &npmenodes,
1590                   &state->natoms, &state->ngtc, &state->nnhpres,
1591                   &state->nhchainlength, &(state->dfhist.nlambda), &state->flags, &flags_eks, &flags_enh, &flags_dfh,
1592                   &state->edsamstate.nED, &state->swapstate.eSwapCoords,
1593                   NULL);
1594
1595     sfree(version);
1596     sfree(btime);
1597     sfree(buser);
1598     sfree(bhost);
1599     sfree(fprog);
1600
1601     if ((do_cpt_state(gmx_fio_getxdr(fp), FALSE, state->flags, state, NULL) < 0)        ||
1602         (do_cpt_ekinstate(gmx_fio_getxdr(fp), flags_eks, &state->ekinstate, NULL) < 0) ||
1603         (do_cpt_enerhist(gmx_fio_getxdr(fp), FALSE, flags_enh, &state->enerhist, NULL) < 0)  ||
1604         (do_cpt_df_hist(gmx_fio_getxdr(fp), flags_dfh, &state->dfhist, NULL) < 0)  ||
1605         (do_cpt_EDstate(gmx_fio_getxdr(fp), FALSE, &state->edsamstate, NULL) < 0)      ||
1606         (do_cpt_swapstate(gmx_fio_getxdr(fp), FALSE, &state->swapstate, NULL) < 0) ||
1607         (do_cpt_files(gmx_fio_getxdr(fp), FALSE, &outputfiles, &noutputfiles, NULL,
1608                       file_version) < 0))
1609     {
1610         gmx_file("Cannot read/write checkpoint; corrupt file, or maybe you are out of disk space?");
1611     }
1612
1613     do_cpt_footer(gmx_fio_getxdr(fp), file_version);
1614
1615     /* we really, REALLY, want to make sure to physically write the checkpoint,
1616        and all the files it depends on, out to disk. Because we've
1617        opened the checkpoint with gmx_fio_open(), it's in our list
1618        of open files.  */
1619     ret = gmx_fio_all_output_fsync();
1620
1621     if (ret)
1622     {
1623         char buf[STRLEN];
1624         sprintf(buf,
1625                 "Cannot fsync '%s'; maybe you are out of disk space?",
1626                 gmx_fio_getname(ret));
1627
1628         if (getenv(GMX_IGNORE_FSYNC_FAILURE_ENV) == NULL)
1629         {
1630             gmx_file(buf);
1631         }
1632         else
1633         {
1634             gmx_warning(buf);
1635         }
1636     }
1637
1638     if (gmx_fio_close(fp) != 0)
1639     {
1640         gmx_file("Cannot read/write checkpoint; corrupt file, or maybe you are out of disk space?");
1641     }
1642
1643     /* we don't move the checkpoint if the user specified they didn't want it,
1644        or if the fsyncs failed */
1645 #ifndef GMX_NO_RENAME
1646     if (!bNumberAndKeep && !ret)
1647     {
1648         if (gmx_fexist(fn))
1649         {
1650             /* Rename the previous checkpoint file */
1651             strcpy(buf, fn);
1652             buf[strlen(fn) - strlen(ftp2ext(fn2ftp(fn))) - 1] = '\0';
1653             strcat(buf, "_prev");
1654             strcat(buf, fn+strlen(fn) - strlen(ftp2ext(fn2ftp(fn))) - 1);
1655 #ifndef GMX_FAHCORE
1656             /* we copy here so that if something goes wrong between now and
1657              * the rename below, there's always a state.cpt.
1658              * If renames are atomic (such as in POSIX systems),
1659              * this copying should be unneccesary.
1660              */
1661             gmx_file_copy(fn, buf, FALSE);
1662             /* We don't really care if this fails:
1663              * there's already a new checkpoint.
1664              */
1665 #else
1666             gmx_file_rename(fn, buf);
1667 #endif
1668         }
1669         if (gmx_file_rename(fntemp, fn) != 0)
1670         {
1671             gmx_file("Cannot rename checkpoint file; maybe you are out of disk space?");
1672         }
1673     }
1674 #endif  /* GMX_NO_RENAME */
1675
1676     sfree(outputfiles);
1677     sfree(fntemp);
1678
1679 #ifdef GMX_FAHCORE
1680     /*code for alternate checkpointing scheme.  moved from top of loop over
1681        steps */
1682     fcRequestCheckPoint();
1683     if (fcCheckPointParallel( cr->nodeid, NULL, 0) == 0)
1684     {
1685         gmx_fatal( 3, __FILE__, __LINE__, "Checkpoint error on step %d\n", step );
1686     }
1687 #endif /* end GMX_FAHCORE block */
1688 }
1689
1690 static void print_flag_mismatch(FILE *fplog, int sflags, int fflags)
1691 {
1692     int i;
1693
1694     fprintf(fplog, "\nState entry mismatch between the simulation and the checkpoint file\n");
1695     fprintf(fplog, "Entries which are not present in the checkpoint file will not be updated\n");
1696     fprintf(fplog, "  %24s    %11s    %11s\n", "", "simulation", "checkpoint");
1697     for (i = 0; i < estNR; i++)
1698     {
1699         if ((sflags & (1<<i)) || (fflags & (1<<i)))
1700         {
1701             fprintf(fplog, "  %24s    %11s    %11s\n",
1702                     est_names[i],
1703                     (sflags & (1<<i)) ? "  present  " : "not present",
1704                     (fflags & (1<<i)) ? "  present  " : "not present");
1705         }
1706     }
1707 }
1708
1709 static void check_int(FILE *fplog, const char *type, int p, int f, gmx_bool *mm)
1710 {
1711     FILE *fp = fplog ? fplog : stderr;
1712
1713     if (p != f)
1714     {
1715         fprintf(fp, "  %s mismatch,\n", type);
1716         fprintf(fp, "    current program: %d\n", p);
1717         fprintf(fp, "    checkpoint file: %d\n", f);
1718         fprintf(fp, "\n");
1719         *mm = TRUE;
1720     }
1721 }
1722
1723 static void check_string(FILE *fplog, const char *type, const char *p,
1724                          const char *f, gmx_bool *mm)
1725 {
1726     FILE *fp = fplog ? fplog : stderr;
1727
1728     if (strcmp(p, f) != 0)
1729     {
1730         fprintf(fp, "  %s mismatch,\n", type);
1731         fprintf(fp, "    current program: %s\n", p);
1732         fprintf(fp, "    checkpoint file: %s\n", f);
1733         fprintf(fp, "\n");
1734         *mm = TRUE;
1735     }
1736 }
1737
1738 static void check_match(FILE *fplog,
1739                         char *version,
1740                         char *btime, char *buser, char *bhost, int double_prec,
1741                         char *fprog,
1742                         t_commrec *cr, int npp_f, int npme_f,
1743                         ivec dd_nc, ivec dd_nc_f)
1744 {
1745     int      npp;
1746     gmx_bool mm                 = FALSE;
1747     gmx_bool patchlevel_differs = FALSE;
1748     gmx_bool version_differs    = FALSE;
1749
1750     check_string(fplog, "Version", gmx_version(), version, &mm);
1751     patchlevel_differs = mm;
1752
1753     if (patchlevel_differs)
1754     {
1755         /* Gromacs should be able to continue from checkpoints between
1756          * different patch level versions, but we do not guarantee
1757          * compatibility between different major/minor versions - check this.
1758          */
1759         int   gmx_major, gmx_minor;
1760         int   cpt_major, cpt_minor;
1761         sscanf(gmx_version(), "VERSION %5d.%5d", &gmx_major, &gmx_minor);
1762         int   ret = sscanf(version, "VERSION %5d.%5d", &cpt_major, &cpt_minor);
1763         version_differs = (ret < 2 || gmx_major != cpt_major ||
1764                            gmx_minor != cpt_minor);
1765     }
1766
1767     check_string(fplog, "Build time", BUILD_TIME, btime, &mm);
1768     check_string(fplog, "Build user", BUILD_USER, buser, &mm);
1769     check_string(fplog, "Build host", BUILD_HOST, bhost, &mm);
1770     check_int   (fplog, "Double prec.", GMX_CPT_BUILD_DP, double_prec, &mm);
1771     check_string(fplog, "Program name", Program(), fprog, &mm);
1772
1773     check_int   (fplog, "#ranks", cr->nnodes, npp_f+npme_f, &mm);
1774     if (cr->nnodes > 1)
1775     {
1776         check_int (fplog, "#PME-ranks", cr->npmenodes, npme_f, &mm);
1777
1778         npp = cr->nnodes;
1779         if (cr->npmenodes >= 0)
1780         {
1781             npp -= cr->npmenodes;
1782         }
1783         if (npp == npp_f)
1784         {
1785             check_int (fplog, "#DD-cells[x]", dd_nc[XX], dd_nc_f[XX], &mm);
1786             check_int (fplog, "#DD-cells[y]", dd_nc[YY], dd_nc_f[YY], &mm);
1787             check_int (fplog, "#DD-cells[z]", dd_nc[ZZ], dd_nc_f[ZZ], &mm);
1788         }
1789     }
1790
1791     if (mm)
1792     {
1793         const char msg_version_difference[] =
1794             "The current GROMACS major & minor version are not identical to those that\n"
1795             "generated the checkpoint file. In principle GROMACS does not support\n"
1796             "continuation from checkpoints between different versions, so we advise\n"
1797             "against this. If you still want to try your luck we recommend that you use\n"
1798             "the -noappend flag to keep your output files from the two versions separate.\n"
1799             "This might also work around errors where the output fields in the energy\n"
1800             "file have changed between the different major & minor versions.\n";
1801
1802         const char msg_mismatch_notice[] =
1803             "GROMACS patchlevel, binary or parallel settings differ from previous run.\n"
1804             "Continuation is exact, but not guaranteed to be binary identical.\n";
1805
1806         const char msg_logdetails[] =
1807             "See the log file for details.\n";
1808
1809         if (version_differs)
1810         {
1811             fprintf(stderr, "%s%s\n", msg_version_difference, fplog ? msg_logdetails : "");
1812
1813             if (fplog)
1814             {
1815                 fprintf(fplog, "%s\n", msg_version_difference);
1816             }
1817         }
1818         else
1819         {
1820             /* Major & minor versions match at least, but something is different. */
1821             fprintf(stderr, "%s%s\n", msg_mismatch_notice, fplog ? msg_logdetails : "");
1822             if (fplog)
1823             {
1824                 fprintf(fplog, "%s\n", msg_mismatch_notice);
1825             }
1826         }
1827     }
1828 }
1829
1830 static void read_checkpoint(const char *fn, FILE **pfplog,
1831                             t_commrec *cr, ivec dd_nc,
1832                             int eIntegrator, int *init_fep_state, gmx_int64_t *step, double *t,
1833                             t_state *state, gmx_bool *bReadEkin,
1834                             int *simulation_part,
1835                             gmx_bool bAppendOutputFiles, gmx_bool bForceAppend)
1836 {
1837     t_fileio            *fp;
1838     int                  i, j, rc;
1839     int                  file_version;
1840     char                *version, *btime, *buser, *bhost, *fprog, *ftime;
1841     int                  double_prec;
1842     char                 buf[STEPSTRSIZE];
1843     int                  eIntegrator_f, nppnodes_f, npmenodes_f;
1844     ivec                 dd_nc_f;
1845     int                  natoms, ngtc, nnhpres, nhchainlength, nlambda, fflags, flags_eks, flags_enh, flags_dfh;
1846     int                  d;
1847     int                  ret;
1848     gmx_file_position_t *outputfiles;
1849     int                  nfiles;
1850     t_fileio            *chksum_file;
1851     FILE               * fplog = *pfplog;
1852     unsigned char        digest[16];
1853 #if !defined __native_client__ && !defined GMX_NATIVE_WINDOWS
1854     struct flock         fl; /* don't initialize here: the struct order is OS
1855                                 dependent! */
1856 #endif
1857
1858     const char *int_warn =
1859         "WARNING: The checkpoint file was generated with integrator %s,\n"
1860         "         while the simulation uses integrator %s\n\n";
1861
1862 #if !defined __native_client__ && !defined GMX_NATIVE_WINDOWS
1863     fl.l_type   = F_WRLCK;
1864     fl.l_whence = SEEK_SET;
1865     fl.l_start  = 0;
1866     fl.l_len    = 0;
1867     fl.l_pid    = 0;
1868 #endif
1869
1870     fp = gmx_fio_open(fn, "r");
1871     do_cpt_header(gmx_fio_getxdr(fp), TRUE, &file_version,
1872                   &version, &btime, &buser, &bhost, &double_prec, &fprog, &ftime,
1873                   &eIntegrator_f, simulation_part, step, t,
1874                   &nppnodes_f, dd_nc_f, &npmenodes_f,
1875                   &natoms, &ngtc, &nnhpres, &nhchainlength, &nlambda,
1876                   &fflags, &flags_eks, &flags_enh, &flags_dfh,
1877                   &state->edsamstate.nED, &state->swapstate.eSwapCoords, NULL);
1878
1879     if (bAppendOutputFiles &&
1880         file_version >= 13 && double_prec != GMX_CPT_BUILD_DP)
1881     {
1882         gmx_fatal(FARGS, "Output file appending requested, but the code and checkpoint file precision (single/double) don't match");
1883     }
1884
1885     if (cr == NULL || MASTER(cr))
1886     {
1887         fprintf(stderr, "\nReading checkpoint file %s generated: %s\n\n",
1888                 fn, ftime);
1889     }
1890
1891     /* This will not be written if we do appending, since fplog is still NULL then */
1892     if (fplog)
1893     {
1894         fprintf(fplog, "\n");
1895         fprintf(fplog, "Reading checkpoint file %s\n", fn);
1896         fprintf(fplog, "  file generated by:     %s\n", fprog);
1897         fprintf(fplog, "  file generated at:     %s\n", ftime);
1898         fprintf(fplog, "  GROMACS build time:    %s\n", btime);
1899         fprintf(fplog, "  GROMACS build user:    %s\n", buser);
1900         fprintf(fplog, "  GROMACS build host:    %s\n", bhost);
1901         fprintf(fplog, "  GROMACS double prec.:  %d\n", double_prec);
1902         fprintf(fplog, "  simulation part #:     %d\n", *simulation_part);
1903         fprintf(fplog, "  step:                  %s\n", gmx_step_str(*step, buf));
1904         fprintf(fplog, "  time:                  %f\n", *t);
1905         fprintf(fplog, "\n");
1906     }
1907
1908     if (natoms != state->natoms)
1909     {
1910         gmx_fatal(FARGS, "Checkpoint file is for a system of %d atoms, while the current system consists of %d atoms", natoms, state->natoms);
1911     }
1912     if (ngtc != state->ngtc)
1913     {
1914         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);
1915     }
1916     if (nnhpres != state->nnhpres)
1917     {
1918         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);
1919     }
1920
1921     if (nlambda != state->dfhist.nlambda)
1922     {
1923         gmx_fatal(FARGS, "Checkpoint file is for a system with %d lambda states, while the current system consists of %d lambda states", nlambda, state->dfhist.nlambda);
1924     }
1925
1926     init_gtc_state(state, state->ngtc, state->nnhpres, nhchainlength); /* need to keep this here to keep the tpr format working */
1927     /* write over whatever was read; we use the number of Nose-Hoover chains from the checkpoint */
1928
1929     if (eIntegrator_f != eIntegrator)
1930     {
1931         if (MASTER(cr))
1932         {
1933             fprintf(stderr, int_warn, EI(eIntegrator_f), EI(eIntegrator));
1934         }
1935         if (bAppendOutputFiles)
1936         {
1937             gmx_fatal(FARGS,
1938                       "Output file appending requested, but input/checkpoint integrators do not match.\n"
1939                       "Stopping the run to prevent you from ruining all your data...\n"
1940                       "If you _really_ know what you are doing, try with the -noappend option.\n");
1941         }
1942         if (fplog)
1943         {
1944             fprintf(fplog, int_warn, EI(eIntegrator_f), EI(eIntegrator));
1945         }
1946     }
1947
1948     if (!PAR(cr))
1949     {
1950         cr->npmenodes = 0;
1951     }
1952     else if (cr->nnodes == nppnodes_f + npmenodes_f)
1953     {
1954         if (cr->npmenodes < 0)
1955         {
1956             cr->npmenodes = npmenodes_f;
1957         }
1958         int nppnodes = cr->nnodes - cr->npmenodes;
1959         if (nppnodes == nppnodes_f)
1960         {
1961             for (d = 0; d < DIM; d++)
1962             {
1963                 if (dd_nc[d] == 0)
1964                 {
1965                     dd_nc[d] = dd_nc_f[d];
1966                 }
1967             }
1968         }
1969     }
1970
1971     if (fflags != state->flags)
1972     {
1973
1974         if (MASTER(cr))
1975         {
1976             if (bAppendOutputFiles)
1977             {
1978                 gmx_fatal(FARGS,
1979                           "Output file appending requested, but input and checkpoint states are not identical.\n"
1980                           "Stopping the run to prevent you from ruining all your data...\n"
1981                           "You can try with the -noappend option, and get more info in the log file.\n");
1982             }
1983
1984             if (getenv("GMX_ALLOW_CPT_MISMATCH") == NULL)
1985             {
1986                 gmx_fatal(FARGS, "You seem to have switched ensemble, integrator, T and/or P-coupling algorithm between the cpt and tpr file. The recommended way of doing this is passing the cpt file to grompp (with option -t) instead of to mdrun. If you know what you are doing, you can override this error by setting the env.var. GMX_ALLOW_CPT_MISMATCH");
1987             }
1988             else
1989             {
1990                 fprintf(stderr,
1991                         "WARNING: The checkpoint state entries do not match the simulation,\n"
1992                         "         see the log file for details\n\n");
1993             }
1994         }
1995
1996         if (fplog)
1997         {
1998             print_flag_mismatch(fplog, state->flags, fflags);
1999         }
2000     }
2001     else
2002     {
2003         if (MASTER(cr))
2004         {
2005             check_match(fplog, version, btime, buser, bhost, double_prec, fprog,
2006                         cr, nppnodes_f, npmenodes_f, dd_nc, dd_nc_f);
2007         }
2008     }
2009     ret             = do_cpt_state(gmx_fio_getxdr(fp), TRUE, fflags, state, NULL);
2010     *init_fep_state = state->fep_state;  /* there should be a better way to do this than setting it here.
2011                                             Investigate for 5.0. */
2012     if (ret)
2013     {
2014         cp_error();
2015     }
2016     ret = do_cpt_ekinstate(gmx_fio_getxdr(fp), flags_eks, &state->ekinstate, NULL);
2017     if (ret)
2018     {
2019         cp_error();
2020     }
2021     *bReadEkin = ((flags_eks & (1<<eeksEKINH)) || (flags_eks & (1<<eeksEKINF)) || (flags_eks & (1<<eeksEKINO)) ||
2022                   ((flags_eks & (1<<eeksEKINSCALEF)) | (flags_eks & (1<<eeksEKINSCALEH)) | (flags_eks & (1<<eeksVSCALE))));
2023
2024     ret = do_cpt_enerhist(gmx_fio_getxdr(fp), TRUE,
2025                           flags_enh, &state->enerhist, NULL);
2026     if (ret)
2027     {
2028         cp_error();
2029     }
2030
2031     if (file_version < 6)
2032     {
2033         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.";
2034
2035         fprintf(stderr, "\nWARNING: %s\n\n", warn);
2036         if (fplog)
2037         {
2038             fprintf(fplog, "\nWARNING: %s\n\n", warn);
2039         }
2040         state->enerhist.nsum     = *step;
2041         state->enerhist.nsum_sim = *step;
2042     }
2043
2044     ret = do_cpt_df_hist(gmx_fio_getxdr(fp), flags_dfh, &state->dfhist, NULL);
2045     if (ret)
2046     {
2047         cp_error();
2048     }
2049
2050     ret = do_cpt_EDstate(gmx_fio_getxdr(fp), TRUE, &state->edsamstate, NULL);
2051     if (ret)
2052     {
2053         cp_error();
2054     }
2055
2056     ret = do_cpt_swapstate(gmx_fio_getxdr(fp), TRUE, &state->swapstate, NULL);
2057     if (ret)
2058     {
2059         cp_error();
2060     }
2061
2062     ret = do_cpt_files(gmx_fio_getxdr(fp), TRUE, &outputfiles, &nfiles, NULL, file_version);
2063     if (ret)
2064     {
2065         cp_error();
2066     }
2067
2068     ret = do_cpt_footer(gmx_fio_getxdr(fp), file_version);
2069     if (ret)
2070     {
2071         cp_error();
2072     }
2073     if (gmx_fio_close(fp) != 0)
2074     {
2075         gmx_file("Cannot read/write checkpoint; corrupt file, or maybe you are out of disk space?");
2076     }
2077
2078     sfree(fprog);
2079     sfree(ftime);
2080     sfree(btime);
2081     sfree(buser);
2082     sfree(bhost);
2083
2084     /* If the user wants to append to output files,
2085      * we use the file pointer positions of the output files stored
2086      * in the checkpoint file and truncate the files such that any frames
2087      * written after the checkpoint time are removed.
2088      * All files are md5sum checked such that we can be sure that
2089      * we do not truncate other (maybe imprortant) files.
2090      */
2091     if (bAppendOutputFiles)
2092     {
2093         if (fn2ftp(outputfiles[0].filename) != efLOG)
2094         {
2095             /* make sure first file is log file so that it is OK to use it for
2096              * locking
2097              */
2098             gmx_fatal(FARGS, "The first output file should always be the log "
2099                       "file but instead is: %s. Cannot do appending because of this condition.", outputfiles[0].filename);
2100         }
2101         for (i = 0; i < nfiles; i++)
2102         {
2103             if (outputfiles[i].offset < 0)
2104             {
2105                 gmx_fatal(FARGS, "The original run wrote a file called '%s' which "
2106                           "is larger than 2 GB, but mdrun did not support large file"
2107                           " offsets. Can not append. Run mdrun with -noappend",
2108                           outputfiles[i].filename);
2109             }
2110 #ifdef GMX_FAHCORE
2111             chksum_file = gmx_fio_open(outputfiles[i].filename, "a");
2112
2113 #else
2114             chksum_file = gmx_fio_open(outputfiles[i].filename, "r+");
2115
2116             /* lock log file */
2117             if (i == 0)
2118             {
2119                 /* Note that there are systems where the lock operation
2120                  * will succeed, but a second process can also lock the file.
2121                  * We should probably try to detect this.
2122                  */
2123 #if defined __native_client__
2124                 errno = ENOSYS;
2125                 if (1)
2126
2127 #elif defined GMX_NATIVE_WINDOWS
2128                 if (_locking(fileno(gmx_fio_getfp(chksum_file)), _LK_NBLCK, LONG_MAX) == -1)
2129 #else
2130                 if (fcntl(fileno(gmx_fio_getfp(chksum_file)), F_SETLK, &fl) == -1)
2131 #endif
2132                 {
2133                     if (errno == ENOSYS)
2134                     {
2135                         if (!bForceAppend)
2136                         {
2137                             gmx_fatal(FARGS, "File locking is not supported on this system. Use -noappend or specify -append explicitly to append anyhow.");
2138                         }
2139                         else
2140                         {
2141                             fprintf(stderr, "\nNOTE: File locking is not supported on this system, will not lock %s\n\n", outputfiles[i].filename);
2142                             if (fplog)
2143                             {
2144                                 fprintf(fplog, "\nNOTE: File locking not supported on this system, will not lock %s\n\n", outputfiles[i].filename);
2145                             }
2146                         }
2147                     }
2148                     else if (errno == EACCES || errno == EAGAIN)
2149                     {
2150                         gmx_fatal(FARGS, "Failed to lock: %s. Already running "
2151                                   "simulation?", outputfiles[i].filename);
2152                     }
2153                     else
2154                     {
2155                         gmx_fatal(FARGS, "Failed to lock: %s. %s.",
2156                                   outputfiles[i].filename, strerror(errno));
2157                     }
2158                 }
2159             }
2160
2161             /* compute md5 chksum */
2162             if (outputfiles[i].chksum_size != -1)
2163             {
2164                 if (gmx_fio_get_file_md5(chksum_file, outputfiles[i].offset,
2165                                          digest) != outputfiles[i].chksum_size) /*at the end of the call the file position is at the end of the file*/
2166                 {
2167                     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.",
2168                               outputfiles[i].chksum_size,
2169                               outputfiles[i].filename);
2170                 }
2171             }
2172             if (i == 0)  /*log file needs to be seeked in case we need to truncate (other files are truncated below)*/
2173             {
2174                 if (gmx_fio_seek(chksum_file, outputfiles[i].offset))
2175                 {
2176                     gmx_fatal(FARGS, "Seek error! Failed to truncate log-file: %s.", strerror(errno));
2177                 }
2178             }
2179 #endif
2180
2181             if (i == 0) /*open log file here - so that lock is never lifted
2182                            after chksum is calculated */
2183             {
2184                 *pfplog = gmx_fio_getfp(chksum_file);
2185             }
2186             else
2187             {
2188                 gmx_fio_close(chksum_file);
2189             }
2190 #ifndef GMX_FAHCORE
2191             /* compare md5 chksum */
2192             if (outputfiles[i].chksum_size != -1 &&
2193                 memcmp(digest, outputfiles[i].chksum, 16) != 0)
2194             {
2195                 if (debug)
2196                 {
2197                     fprintf(debug, "chksum for %s: ", outputfiles[i].filename);
2198                     for (j = 0; j < 16; j++)
2199                     {
2200                         fprintf(debug, "%02x", digest[j]);
2201                     }
2202                     fprintf(debug, "\n");
2203                 }
2204                 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.",
2205                           outputfiles[i].filename);
2206             }
2207 #endif
2208
2209
2210             if (i != 0) /*log file is already seeked to correct position */
2211             {
2212 #if !defined(GMX_NATIVE_WINDOWS) || !defined(GMX_FAHCORE)
2213                 /* For FAHCORE, we do this elsewhere*/
2214                 rc = gmx_truncate(outputfiles[i].filename, outputfiles[i].offset);
2215                 if (rc != 0)
2216                 {
2217                     gmx_fatal(FARGS, "Truncation of file %s failed. Cannot do appending because of this failure.", outputfiles[i].filename);
2218                 }
2219 #endif
2220             }
2221         }
2222     }
2223
2224     sfree(outputfiles);
2225 }
2226
2227
2228 void load_checkpoint(const char *fn, FILE **fplog,
2229                      t_commrec *cr, ivec dd_nc,
2230                      t_inputrec *ir, t_state *state,
2231                      gmx_bool *bReadEkin,
2232                      gmx_bool bAppend, gmx_bool bForceAppend)
2233 {
2234     gmx_int64_t     step;
2235     double          t;
2236
2237     if (SIMMASTER(cr))
2238     {
2239         /* Read the state from the checkpoint file */
2240         read_checkpoint(fn, fplog,
2241                         cr, dd_nc,
2242                         ir->eI, &(ir->fepvals->init_fep_state), &step, &t, state, bReadEkin,
2243                         &ir->simulation_part, bAppend, bForceAppend);
2244     }
2245     if (PAR(cr))
2246     {
2247         gmx_bcast(sizeof(cr->npmenodes), &cr->npmenodes, cr);
2248         gmx_bcast(DIM*sizeof(dd_nc[0]), dd_nc, cr);
2249         gmx_bcast(sizeof(step), &step, cr);
2250         gmx_bcast(sizeof(*bReadEkin), bReadEkin, cr);
2251     }
2252     ir->bContinuation    = TRUE;
2253     if (ir->nsteps >= 0)
2254     {
2255         ir->nsteps          += ir->init_step - step;
2256     }
2257     ir->init_step        = step;
2258     ir->simulation_part += 1;
2259 }
2260
2261 void read_checkpoint_part_and_step(const char  *filename,
2262                                    int         *simulation_part,
2263                                    gmx_int64_t *step)
2264 {
2265     int       file_version;
2266     char     *version, *btime, *buser, *bhost, *fprog, *ftime;
2267     int       double_prec;
2268     int       eIntegrator;
2269     int       nppnodes, npme;
2270     ivec      dd_nc;
2271     int       flags_eks, flags_enh, flags_dfh;
2272     double    t;
2273     t_state   state;
2274     t_fileio *fp;
2275
2276     if (filename == NULL ||
2277         !gmx_fexist(filename) ||
2278         (!(fp = gmx_fio_open(filename, "r"))))
2279     {
2280         *simulation_part = 0;
2281         *step            = 0;
2282         return;
2283     }
2284
2285     /* Not calling initializing state before use is nasty, but all we
2286        do is read into its member variables and throw the struct away
2287        again immediately. */
2288
2289     do_cpt_header(gmx_fio_getxdr(fp), TRUE, &file_version,
2290                   &version, &btime, &buser, &bhost, &double_prec, &fprog, &ftime,
2291                   &eIntegrator, simulation_part, step, &t, &nppnodes, dd_nc, &npme,
2292                   &state.natoms, &state.ngtc, &state.nnhpres, &state.nhchainlength,
2293                   &(state.dfhist.nlambda), &state.flags, &flags_eks, &flags_enh, &flags_dfh,
2294                   &state.edsamstate.nED, &state.swapstate.eSwapCoords, NULL);
2295
2296     gmx_fio_close(fp);
2297 }
2298
2299 static void read_checkpoint_data(t_fileio *fp, int *simulation_part,
2300                                  gmx_int64_t *step, double *t, t_state *state,
2301                                  int *nfiles, gmx_file_position_t **outputfiles)
2302 {
2303     int                  file_version;
2304     char                *version, *btime, *buser, *bhost, *fprog, *ftime;
2305     int                  double_prec;
2306     int                  eIntegrator;
2307     int                  nppnodes, npme;
2308     ivec                 dd_nc;
2309     int                  flags_eks, flags_enh, flags_dfh;
2310     int                  nfiles_loc;
2311     gmx_file_position_t *files_loc = NULL;
2312     int                  ret;
2313
2314     do_cpt_header(gmx_fio_getxdr(fp), TRUE, &file_version,
2315                   &version, &btime, &buser, &bhost, &double_prec, &fprog, &ftime,
2316                   &eIntegrator, simulation_part, step, t, &nppnodes, dd_nc, &npme,
2317                   &state->natoms, &state->ngtc, &state->nnhpres, &state->nhchainlength,
2318                   &(state->dfhist.nlambda), &state->flags, &flags_eks, &flags_enh, &flags_dfh,
2319                   &state->edsamstate.nED, &state->swapstate.eSwapCoords, NULL);
2320     ret =
2321         do_cpt_state(gmx_fio_getxdr(fp), TRUE, state->flags, state, NULL);
2322     if (ret)
2323     {
2324         cp_error();
2325     }
2326     ret = do_cpt_ekinstate(gmx_fio_getxdr(fp), flags_eks, &state->ekinstate, NULL);
2327     if (ret)
2328     {
2329         cp_error();
2330     }
2331     ret = do_cpt_enerhist(gmx_fio_getxdr(fp), TRUE,
2332                           flags_enh, &state->enerhist, NULL);
2333     if (ret)
2334     {
2335         cp_error();
2336     }
2337     ret = do_cpt_df_hist(gmx_fio_getxdr(fp), flags_dfh, &state->dfhist, NULL);
2338     if (ret)
2339     {
2340         cp_error();
2341     }
2342
2343     ret = do_cpt_EDstate(gmx_fio_getxdr(fp), TRUE, &state->edsamstate, NULL);
2344     if (ret)
2345     {
2346         cp_error();
2347     }
2348
2349     ret = do_cpt_swapstate(gmx_fio_getxdr(fp), TRUE, &state->swapstate, NULL);
2350     if (ret)
2351     {
2352         cp_error();
2353     }
2354
2355     ret = do_cpt_files(gmx_fio_getxdr(fp), TRUE,
2356                        outputfiles != NULL ? outputfiles : &files_loc,
2357                        outputfiles != NULL ? nfiles : &nfiles_loc,
2358                        NULL, file_version);
2359     if (files_loc != NULL)
2360     {
2361         sfree(files_loc);
2362     }
2363
2364     if (ret)
2365     {
2366         cp_error();
2367     }
2368
2369     ret = do_cpt_footer(gmx_fio_getxdr(fp), file_version);
2370     if (ret)
2371     {
2372         cp_error();
2373     }
2374
2375     sfree(fprog);
2376     sfree(ftime);
2377     sfree(btime);
2378     sfree(buser);
2379     sfree(bhost);
2380 }
2381
2382 void
2383 read_checkpoint_state(const char *fn, int *simulation_part,
2384                       gmx_int64_t *step, double *t, t_state *state)
2385 {
2386     t_fileio *fp;
2387
2388     fp = gmx_fio_open(fn, "r");
2389     read_checkpoint_data(fp, simulation_part, step, t, state, NULL, NULL);
2390     if (gmx_fio_close(fp) != 0)
2391     {
2392         gmx_file("Cannot read/write checkpoint; corrupt file, or maybe you are out of disk space?");
2393     }
2394 }
2395
2396 void read_checkpoint_trxframe(t_fileio *fp, t_trxframe *fr)
2397 {
2398     /* This next line is nasty because the sub-structures of t_state
2399      * cannot be assumed to be zeroed (or even initialized in ways the
2400      * rest of the code might assume). Using snew would be better, but
2401      * this will all go away for 5.0. */
2402     t_state         state;
2403     int             simulation_part;
2404     gmx_int64_t     step;
2405     double          t;
2406
2407     init_state(&state, 0, 0, 0, 0, 0);
2408
2409     read_checkpoint_data(fp, &simulation_part, &step, &t, &state, NULL, NULL);
2410
2411     fr->natoms  = state.natoms;
2412     fr->bTitle  = FALSE;
2413     fr->bStep   = TRUE;
2414     fr->step    = gmx_int64_to_int(step,
2415                                    "conversion of checkpoint to trajectory");
2416     fr->bTime      = TRUE;
2417     fr->time       = t;
2418     fr->bLambda    = TRUE;
2419     fr->lambda     = state.lambda[efptFEP];
2420     fr->fep_state  = state.fep_state;
2421     fr->bAtoms     = FALSE;
2422     fr->bX         = (state.flags & (1<<estX));
2423     if (fr->bX)
2424     {
2425         fr->x     = state.x;
2426         state.x   = NULL;
2427     }
2428     fr->bV      = (state.flags & (1<<estV));
2429     if (fr->bV)
2430     {
2431         fr->v     = state.v;
2432         state.v   = NULL;
2433     }
2434     fr->bF      = FALSE;
2435     fr->bBox    = (state.flags & (1<<estBOX));
2436     if (fr->bBox)
2437     {
2438         copy_mat(state.box, fr->box);
2439     }
2440     done_state(&state);
2441 }
2442
2443 void list_checkpoint(const char *fn, FILE *out)
2444 {
2445     t_fileio            *fp;
2446     int                  file_version;
2447     char                *version, *btime, *buser, *bhost, *fprog, *ftime;
2448     int                  double_prec;
2449     int                  eIntegrator, simulation_part, nppnodes, npme;
2450     gmx_int64_t          step;
2451     double               t;
2452     ivec                 dd_nc;
2453     t_state              state;
2454     int                  flags_eks, flags_enh, flags_dfh;
2455     int                  ret;
2456     gmx_file_position_t *outputfiles;
2457     int                  nfiles;
2458
2459     init_state(&state, -1, -1, -1, -1, 0);
2460
2461     fp = gmx_fio_open(fn, "r");
2462     do_cpt_header(gmx_fio_getxdr(fp), TRUE, &file_version,
2463                   &version, &btime, &buser, &bhost, &double_prec, &fprog, &ftime,
2464                   &eIntegrator, &simulation_part, &step, &t, &nppnodes, dd_nc, &npme,
2465                   &state.natoms, &state.ngtc, &state.nnhpres, &state.nhchainlength,
2466                   &(state.dfhist.nlambda), &state.flags,
2467                   &flags_eks, &flags_enh, &flags_dfh, &state.edsamstate.nED,
2468                   &state.swapstate.eSwapCoords, out);
2469     ret = do_cpt_state(gmx_fio_getxdr(fp), TRUE, state.flags, &state, out);
2470     if (ret)
2471     {
2472         cp_error();
2473     }
2474     ret = do_cpt_ekinstate(gmx_fio_getxdr(fp), flags_eks, &state.ekinstate, out);
2475     if (ret)
2476     {
2477         cp_error();
2478     }
2479     ret = do_cpt_enerhist(gmx_fio_getxdr(fp), TRUE,
2480                           flags_enh, &state.enerhist, out);
2481
2482     if (ret == 0)
2483     {
2484         ret = do_cpt_df_hist(gmx_fio_getxdr(fp),
2485                              flags_dfh, &state.dfhist, out);
2486     }
2487
2488     if (ret == 0)
2489     {
2490         ret = do_cpt_EDstate(gmx_fio_getxdr(fp), TRUE, &state.edsamstate, out);
2491     }
2492
2493     if (ret == 0)
2494     {
2495         ret = do_cpt_swapstate(gmx_fio_getxdr(fp), TRUE, &state.swapstate, out);
2496     }
2497
2498     if (ret == 0)
2499     {
2500         do_cpt_files(gmx_fio_getxdr(fp), TRUE, &outputfiles, &nfiles, out, file_version);
2501     }
2502
2503     if (ret == 0)
2504     {
2505         ret = do_cpt_footer(gmx_fio_getxdr(fp), file_version);
2506     }
2507
2508     if (ret)
2509     {
2510         cp_warning(out);
2511     }
2512     if (gmx_fio_close(fp) != 0)
2513     {
2514         gmx_file("Cannot read/write checkpoint; corrupt file, or maybe you are out of disk space?");
2515     }
2516
2517     done_state(&state);
2518 }
2519
2520 /* This routine cannot print tons of data, since it is called before the log file is opened. */
2521 void
2522 read_checkpoint_simulation_part_and_filenames(t_fileio             *fp,
2523                                               int                  *simulation_part,
2524                                               int                  *nfiles,
2525                                               gmx_file_position_t **outputfiles)
2526 {
2527     gmx_int64_t step = 0;
2528     double      t;
2529     t_state     state;
2530
2531     init_state(&state, 0, 0, 0, 0, 0);
2532
2533     read_checkpoint_data(fp, simulation_part, &step, &t, &state,
2534                          nfiles, outputfiles);
2535     if (gmx_fio_close(fp) != 0)
2536     {
2537         gmx_file("Cannot read/write checkpoint; corrupt file, or maybe you are out of disk space?");
2538     }
2539     done_state(&state);
2540 }