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