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