Introduce gmxpre.h for truly global definitions
[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 "gmxpre.h"
39
40 #include "gromacs/legacyheaders/checkpoint.h"
41
42 #include "config.h"
43
44 #include <errno.h>
45 #include <stdlib.h>
46 #include <string.h>
47 #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 "gromacs/legacyheaders/copyrite.h"
65 #include "gromacs/legacyheaders/names.h"
66 #include "gromacs/legacyheaders/typedefs.h"
67 #include "gromacs/legacyheaders/types/commrec.h"
68 #include "gromacs/legacyheaders/txtdump.h"
69 #include "gromacs/math/vec.h"
70 #include "gromacs/legacyheaders/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-ranks", 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 ranks", 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                 = FALSE;
1784     gmx_bool patchlevel_differs = FALSE;
1785     gmx_bool version_differs    = FALSE;
1786
1787     check_string(fplog, "Version", gmx_version(), version, &mm);
1788     patchlevel_differs = mm;
1789
1790     if (patchlevel_differs)
1791     {
1792         /* Gromacs should be able to continue from checkpoints between
1793          * different patch level versions, but we do not guarantee
1794          * compatibility between different major/minor versions - check this.
1795          */
1796         int   gmx_major, gmx_minor;
1797         int   cpt_major, cpt_minor;
1798         sscanf(gmx_version(), "VERSION %5d.%5d", &gmx_major, &gmx_minor);
1799         sscanf(version, "VERSION %5d.%5d", &cpt_major, &cpt_minor);
1800         version_differs = (gmx_major != cpt_major || gmx_minor != cpt_minor);
1801     }
1802
1803     check_string(fplog, "Build time", BUILD_TIME, btime, &mm);
1804     check_string(fplog, "Build user", BUILD_USER, buser, &mm);
1805     check_string(fplog, "Build host", BUILD_HOST, bhost, &mm);
1806     check_int   (fplog, "Double prec.", GMX_CPT_BUILD_DP, double_prec, &mm);
1807     check_string(fplog, "Program name", Program(), fprog, &mm);
1808
1809     check_int   (fplog, "#ranks", cr->nnodes, npp_f+npme_f, &mm);
1810     if (cr->nnodes > 1)
1811     {
1812         check_int (fplog, "#PME-ranks", cr->npmenodes, npme_f, &mm);
1813
1814         npp = cr->nnodes;
1815         if (cr->npmenodes >= 0)
1816         {
1817             npp -= cr->npmenodes;
1818         }
1819         if (npp == npp_f)
1820         {
1821             check_int (fplog, "#DD-cells[x]", dd_nc[XX], dd_nc_f[XX], &mm);
1822             check_int (fplog, "#DD-cells[y]", dd_nc[YY], dd_nc_f[YY], &mm);
1823             check_int (fplog, "#DD-cells[z]", dd_nc[ZZ], dd_nc_f[ZZ], &mm);
1824         }
1825     }
1826
1827     if (mm)
1828     {
1829         const char msg_version_difference[] =
1830             "The current Gromacs major & minor version are not identical to those that\n"
1831             "generated the checkpoint file. In principle Gromacs does not support\n"
1832             "continuation from checkpoints between different versions, so we advise\n"
1833             "against this. If you still want to try your luck we recommend that you use\n"
1834             "the -noappend flag to keep your output files from the two versions separate.\n"
1835             "This might also work around errors where the output fields in the energy\n"
1836             "file have changed between the different major & minor versions.\n";
1837
1838         const char msg_mismatch_notice[] =
1839             "Gromacs patchlevel, binary or parallel settings differ from previous run.\n"
1840             "Continuation is exact, but not guaranteed to be binary identical.\n";
1841
1842         const char msg_logdetails[] =
1843             "See the log file for details.\n";
1844
1845         if (version_differs)
1846         {
1847             fprintf(stderr, "%s%s\n", msg_version_difference, fplog ? msg_logdetails : "");
1848
1849             if (fplog)
1850             {
1851                 fprintf(fplog, "%s\n", msg_version_difference);
1852             }
1853         }
1854         else
1855         {
1856             /* Major & minor versions match at least, but something is different. */
1857             fprintf(stderr, "%s%s\n", msg_mismatch_notice, fplog ? msg_logdetails : "");
1858             if (fplog)
1859             {
1860                 fprintf(fplog, "%s\n", msg_mismatch_notice);
1861             }
1862         }
1863     }
1864 }
1865
1866 static void read_checkpoint(const char *fn, FILE **pfplog,
1867                             t_commrec *cr, ivec dd_nc,
1868                             int eIntegrator, int *init_fep_state, gmx_int64_t *step, double *t,
1869                             t_state *state, gmx_bool *bReadEkin,
1870                             int *simulation_part,
1871                             gmx_bool bAppendOutputFiles, gmx_bool bForceAppend)
1872 {
1873     t_fileio            *fp;
1874     int                  i, j, rc;
1875     int                  file_version;
1876     char                *version, *btime, *buser, *bhost, *fprog, *ftime;
1877     int                  double_prec;
1878     char                 buf[STEPSTRSIZE];
1879     int                  eIntegrator_f, nppnodes_f, npmenodes_f;
1880     ivec                 dd_nc_f;
1881     int                  natoms, ngtc, nnhpres, nhchainlength, nlambda, fflags, flags_eks, flags_enh, flags_dfh;
1882     int                  d;
1883     int                  ret;
1884     gmx_file_position_t *outputfiles;
1885     int                  nfiles;
1886     t_fileio            *chksum_file;
1887     FILE               * fplog = *pfplog;
1888     unsigned char        digest[16];
1889 #if !defined __native_client__ && !defined GMX_NATIVE_WINDOWS
1890     struct flock         fl; /* don't initialize here: the struct order is OS
1891                                 dependent! */
1892 #endif
1893
1894     const char *int_warn =
1895         "WARNING: The checkpoint file was generated with integrator %s,\n"
1896         "         while the simulation uses integrator %s\n\n";
1897
1898 #if !defined __native_client__ && !defined GMX_NATIVE_WINDOWS
1899     fl.l_type   = F_WRLCK;
1900     fl.l_whence = SEEK_SET;
1901     fl.l_start  = 0;
1902     fl.l_len    = 0;
1903     fl.l_pid    = 0;
1904 #endif
1905
1906     fp = gmx_fio_open(fn, "r");
1907     do_cpt_header(gmx_fio_getxdr(fp), TRUE, &file_version,
1908                   &version, &btime, &buser, &bhost, &double_prec, &fprog, &ftime,
1909                   &eIntegrator_f, simulation_part, step, t,
1910                   &nppnodes_f, dd_nc_f, &npmenodes_f,
1911                   &natoms, &ngtc, &nnhpres, &nhchainlength, &nlambda,
1912                   &fflags, &flags_eks, &flags_enh, &flags_dfh,
1913                   &state->edsamstate.nED, &state->swapstate.eSwapCoords, NULL);
1914
1915     if (bAppendOutputFiles &&
1916         file_version >= 13 && double_prec != GMX_CPT_BUILD_DP)
1917     {
1918         gmx_fatal(FARGS, "Output file appending requested, but the code and checkpoint file precision (single/double) don't match");
1919     }
1920
1921     if (cr == NULL || MASTER(cr))
1922     {
1923         fprintf(stderr, "\nReading checkpoint file %s generated: %s\n\n",
1924                 fn, ftime);
1925     }
1926
1927     /* This will not be written if we do appending, since fplog is still NULL then */
1928     if (fplog)
1929     {
1930         fprintf(fplog, "\n");
1931         fprintf(fplog, "Reading checkpoint file %s\n", fn);
1932         fprintf(fplog, "  file generated by:     %s\n", fprog);
1933         fprintf(fplog, "  file generated at:     %s\n", ftime);
1934         fprintf(fplog, "  GROMACS build time:    %s\n", btime);
1935         fprintf(fplog, "  GROMACS build user:    %s\n", buser);
1936         fprintf(fplog, "  GROMACS build host:    %s\n", bhost);
1937         fprintf(fplog, "  GROMACS double prec.:  %d\n", double_prec);
1938         fprintf(fplog, "  simulation part #:     %d\n", *simulation_part);
1939         fprintf(fplog, "  step:                  %s\n", gmx_step_str(*step, buf));
1940         fprintf(fplog, "  time:                  %f\n", *t);
1941         fprintf(fplog, "\n");
1942     }
1943
1944     if (natoms != state->natoms)
1945     {
1946         gmx_fatal(FARGS, "Checkpoint file is for a system of %d atoms, while the current system consists of %d atoms", natoms, state->natoms);
1947     }
1948     if (ngtc != state->ngtc)
1949     {
1950         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);
1951     }
1952     if (nnhpres != state->nnhpres)
1953     {
1954         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);
1955     }
1956
1957     if (nlambda != state->dfhist.nlambda)
1958     {
1959         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);
1960     }
1961
1962     init_gtc_state(state, state->ngtc, state->nnhpres, nhchainlength); /* need to keep this here to keep the tpr format working */
1963     /* write over whatever was read; we use the number of Nose-Hoover chains from the checkpoint */
1964
1965     if (eIntegrator_f != eIntegrator)
1966     {
1967         if (MASTER(cr))
1968         {
1969             fprintf(stderr, int_warn, EI(eIntegrator_f), EI(eIntegrator));
1970         }
1971         if (bAppendOutputFiles)
1972         {
1973             gmx_fatal(FARGS,
1974                       "Output file appending requested, but input/checkpoint integrators do not match.\n"
1975                       "Stopping the run to prevent you from ruining all your data...\n"
1976                       "If you _really_ know what you are doing, try with the -noappend option.\n");
1977         }
1978         if (fplog)
1979         {
1980             fprintf(fplog, int_warn, EI(eIntegrator_f), EI(eIntegrator));
1981         }
1982     }
1983
1984     if (!PAR(cr))
1985     {
1986         cr->npmenodes = 0;
1987     }
1988     else if (cr->nnodes == nppnodes_f + npmenodes_f)
1989     {
1990         if (cr->npmenodes < 0)
1991         {
1992             cr->npmenodes = npmenodes_f;
1993         }
1994         int nppnodes = cr->nnodes - cr->npmenodes;
1995         if (nppnodes == nppnodes_f)
1996         {
1997             for (d = 0; d < DIM; d++)
1998             {
1999                 if (dd_nc[d] == 0)
2000                 {
2001                     dd_nc[d] = dd_nc_f[d];
2002                 }
2003             }
2004         }
2005     }
2006
2007     if (fflags != state->flags)
2008     {
2009
2010         if (MASTER(cr))
2011         {
2012             if (bAppendOutputFiles)
2013             {
2014                 gmx_fatal(FARGS,
2015                           "Output file appending requested, but input and checkpoint states are not identical.\n"
2016                           "Stopping the run to prevent you from ruining all your data...\n"
2017                           "You can try with the -noappend option, and get more info in the log file.\n");
2018             }
2019
2020             if (getenv("GMX_ALLOW_CPT_MISMATCH") == NULL)
2021             {
2022                 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");
2023             }
2024             else
2025             {
2026                 fprintf(stderr,
2027                         "WARNING: The checkpoint state entries do not match the simulation,\n"
2028                         "         see the log file for details\n\n");
2029             }
2030         }
2031
2032         if (fplog)
2033         {
2034             print_flag_mismatch(fplog, state->flags, fflags);
2035         }
2036     }
2037     else
2038     {
2039         if (MASTER(cr))
2040         {
2041             check_match(fplog, version, btime, buser, bhost, double_prec, fprog,
2042                         cr, nppnodes_f, npmenodes_f, dd_nc, dd_nc_f);
2043         }
2044     }
2045     ret             = do_cpt_state(gmx_fio_getxdr(fp), TRUE, fflags, state, NULL);
2046     *init_fep_state = state->fep_state;  /* there should be a better way to do this than setting it here.
2047                                             Investigate for 5.0. */
2048     if (ret)
2049     {
2050         cp_error();
2051     }
2052     ret = do_cpt_ekinstate(gmx_fio_getxdr(fp), flags_eks, &state->ekinstate, NULL);
2053     if (ret)
2054     {
2055         cp_error();
2056     }
2057     *bReadEkin = ((flags_eks & (1<<eeksEKINH)) || (flags_eks & (1<<eeksEKINF)) || (flags_eks & (1<<eeksEKINO)) ||
2058                   ((flags_eks & (1<<eeksEKINSCALEF)) | (flags_eks & (1<<eeksEKINSCALEH)) | (flags_eks & (1<<eeksVSCALE))));
2059
2060     ret = do_cpt_enerhist(gmx_fio_getxdr(fp), TRUE,
2061                           flags_enh, &state->enerhist, NULL);
2062     if (ret)
2063     {
2064         cp_error();
2065     }
2066
2067     if (file_version < 6)
2068     {
2069         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.";
2070
2071         fprintf(stderr, "\nWARNING: %s\n\n", warn);
2072         if (fplog)
2073         {
2074             fprintf(fplog, "\nWARNING: %s\n\n", warn);
2075         }
2076         state->enerhist.nsum     = *step;
2077         state->enerhist.nsum_sim = *step;
2078     }
2079
2080     ret = do_cpt_df_hist(gmx_fio_getxdr(fp), flags_dfh, &state->dfhist, NULL);
2081     if (ret)
2082     {
2083         cp_error();
2084     }
2085
2086     ret = do_cpt_swapstate(gmx_fio_getxdr(fp), TRUE, &state->swapstate, NULL);
2087     if (ret)
2088     {
2089         cp_error();
2090     }
2091
2092     ret = do_cpt_EDstate(gmx_fio_getxdr(fp), TRUE, &state->edsamstate, NULL);
2093     if (ret)
2094     {
2095         cp_error();
2096     }
2097
2098     ret = do_cpt_files(gmx_fio_getxdr(fp), TRUE, &outputfiles, &nfiles, NULL, file_version);
2099     if (ret)
2100     {
2101         cp_error();
2102     }
2103
2104     ret = do_cpt_footer(gmx_fio_getxdr(fp), file_version);
2105     if (ret)
2106     {
2107         cp_error();
2108     }
2109     if (gmx_fio_close(fp) != 0)
2110     {
2111         gmx_file("Cannot read/write checkpoint; corrupt file, or maybe you are out of disk space?");
2112     }
2113
2114     sfree(fprog);
2115     sfree(ftime);
2116     sfree(btime);
2117     sfree(buser);
2118     sfree(bhost);
2119
2120     /* If the user wants to append to output files,
2121      * we use the file pointer positions of the output files stored
2122      * in the checkpoint file and truncate the files such that any frames
2123      * written after the checkpoint time are removed.
2124      * All files are md5sum checked such that we can be sure that
2125      * we do not truncate other (maybe imprortant) files.
2126      */
2127     if (bAppendOutputFiles)
2128     {
2129         if (fn2ftp(outputfiles[0].filename) != efLOG)
2130         {
2131             /* make sure first file is log file so that it is OK to use it for
2132              * locking
2133              */
2134             gmx_fatal(FARGS, "The first output file should always be the log "
2135                       "file but instead is: %s. Cannot do appending because of this condition.", outputfiles[0].filename);
2136         }
2137         for (i = 0; i < nfiles; i++)
2138         {
2139             if (outputfiles[i].offset < 0)
2140             {
2141                 gmx_fatal(FARGS, "The original run wrote a file called '%s' which "
2142                           "is larger than 2 GB, but mdrun did not support large file"
2143                           " offsets. Can not append. Run mdrun with -noappend",
2144                           outputfiles[i].filename);
2145             }
2146 #ifdef GMX_FAHCORE
2147             chksum_file = gmx_fio_open(outputfiles[i].filename, "a");
2148
2149 #else
2150             chksum_file = gmx_fio_open(outputfiles[i].filename, "r+");
2151
2152             /* lock log file */
2153             if (i == 0)
2154             {
2155                 /* Note that there are systems where the lock operation
2156                  * will succeed, but a second process can also lock the file.
2157                  * We should probably try to detect this.
2158                  */
2159 #if defined __native_client__
2160                 errno = ENOSYS;
2161                 if (1)
2162
2163 #elif defined GMX_NATIVE_WINDOWS
2164                 if (_locking(fileno(gmx_fio_getfp(chksum_file)), _LK_NBLCK, LONG_MAX) == -1)
2165 #else
2166                 if (fcntl(fileno(gmx_fio_getfp(chksum_file)), F_SETLK, &fl) == -1)
2167 #endif
2168                 {
2169                     if (errno == ENOSYS)
2170                     {
2171                         if (!bForceAppend)
2172                         {
2173                             gmx_fatal(FARGS, "File locking is not supported on this system. Use -noappend or specify -append explicitly to append anyhow.");
2174                         }
2175                         else
2176                         {
2177                             fprintf(stderr, "\nNOTE: File locking is not supported on this system, will not lock %s\n\n", outputfiles[i].filename);
2178                             if (fplog)
2179                             {
2180                                 fprintf(fplog, "\nNOTE: File locking not supported on this system, will not lock %s\n\n", outputfiles[i].filename);
2181                             }
2182                         }
2183                     }
2184                     else if (errno == EACCES || errno == EAGAIN)
2185                     {
2186                         gmx_fatal(FARGS, "Failed to lock: %s. Already running "
2187                                   "simulation?", outputfiles[i].filename);
2188                     }
2189                     else
2190                     {
2191                         gmx_fatal(FARGS, "Failed to lock: %s. %s.",
2192                                   outputfiles[i].filename, strerror(errno));
2193                     }
2194                 }
2195             }
2196
2197             /* compute md5 chksum */
2198             if (outputfiles[i].chksum_size != -1)
2199             {
2200                 if (gmx_fio_get_file_md5(chksum_file, outputfiles[i].offset,
2201                                          digest) != outputfiles[i].chksum_size) /*at the end of the call the file position is at the end of the file*/
2202                 {
2203                     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.",
2204                               outputfiles[i].chksum_size,
2205                               outputfiles[i].filename);
2206                 }
2207             }
2208             if (i == 0)  /*log file needs to be seeked in case we need to truncate (other files are truncated below)*/
2209             {
2210                 if (gmx_fio_seek(chksum_file, outputfiles[i].offset))
2211                 {
2212                     gmx_fatal(FARGS, "Seek error! Failed to truncate log-file: %s.", strerror(errno));
2213                 }
2214             }
2215 #endif
2216
2217             if (i == 0) /*open log file here - so that lock is never lifted
2218                            after chksum is calculated */
2219             {
2220                 *pfplog = gmx_fio_getfp(chksum_file);
2221             }
2222             else
2223             {
2224                 gmx_fio_close(chksum_file);
2225             }
2226 #ifndef GMX_FAHCORE
2227             /* compare md5 chksum */
2228             if (outputfiles[i].chksum_size != -1 &&
2229                 memcmp(digest, outputfiles[i].chksum, 16) != 0)
2230             {
2231                 if (debug)
2232                 {
2233                     fprintf(debug, "chksum for %s: ", outputfiles[i].filename);
2234                     for (j = 0; j < 16; j++)
2235                     {
2236                         fprintf(debug, "%02x", digest[j]);
2237                     }
2238                     fprintf(debug, "\n");
2239                 }
2240                 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.",
2241                           outputfiles[i].filename);
2242             }
2243 #endif
2244
2245
2246             if (i != 0) /*log file is already seeked to correct position */
2247             {
2248 #ifdef GMX_NATIVE_WINDOWS
2249                 rc = gmx_wintruncate(outputfiles[i].filename, outputfiles[i].offset);
2250 #else
2251                 rc = truncate(outputfiles[i].filename, outputfiles[i].offset);
2252 #endif
2253                 if (rc != 0)
2254                 {
2255                     gmx_fatal(FARGS, "Truncation of file %s failed. Cannot do appending because of this failure.", outputfiles[i].filename);
2256                 }
2257             }
2258         }
2259     }
2260
2261     sfree(outputfiles);
2262 }
2263
2264
2265 void load_checkpoint(const char *fn, FILE **fplog,
2266                      t_commrec *cr, ivec dd_nc,
2267                      t_inputrec *ir, t_state *state,
2268                      gmx_bool *bReadEkin,
2269                      gmx_bool bAppend, gmx_bool bForceAppend)
2270 {
2271     gmx_int64_t     step;
2272     double          t;
2273
2274     if (SIMMASTER(cr))
2275     {
2276         /* Read the state from the checkpoint file */
2277         read_checkpoint(fn, fplog,
2278                         cr, dd_nc,
2279                         ir->eI, &(ir->fepvals->init_fep_state), &step, &t, state, bReadEkin,
2280                         &ir->simulation_part, bAppend, bForceAppend);
2281     }
2282     if (PAR(cr))
2283     {
2284         gmx_bcast(sizeof(cr->npmenodes), &cr->npmenodes, cr);
2285         gmx_bcast(DIM*sizeof(dd_nc[0]), dd_nc, cr);
2286         gmx_bcast(sizeof(step), &step, cr);
2287         gmx_bcast(sizeof(*bReadEkin), bReadEkin, cr);
2288     }
2289     ir->bContinuation    = TRUE;
2290     if (ir->nsteps >= 0)
2291     {
2292         ir->nsteps          += ir->init_step - step;
2293     }
2294     ir->init_step        = step;
2295     ir->simulation_part += 1;
2296 }
2297
2298 static void read_checkpoint_data(t_fileio *fp, int *simulation_part,
2299                                  gmx_int64_t *step, double *t, t_state *state,
2300                                  int *nfiles, gmx_file_position_t **outputfiles)
2301 {
2302     int                  file_version;
2303     char                *version, *btime, *buser, *bhost, *fprog, *ftime;
2304     int                  double_prec;
2305     int                  eIntegrator;
2306     int                  nppnodes, npme;
2307     ivec                 dd_nc;
2308     int                  flags_eks, flags_enh, flags_dfh;
2309     int                  nfiles_loc;
2310     gmx_file_position_t *files_loc = NULL;
2311     int                  ret;
2312
2313     do_cpt_header(gmx_fio_getxdr(fp), TRUE, &file_version,
2314                   &version, &btime, &buser, &bhost, &double_prec, &fprog, &ftime,
2315                   &eIntegrator, simulation_part, step, t, &nppnodes, dd_nc, &npme,
2316                   &state->natoms, &state->ngtc, &state->nnhpres, &state->nhchainlength,
2317                   &(state->dfhist.nlambda), &state->flags, &flags_eks, &flags_enh, &flags_dfh,
2318                   &state->edsamstate.nED, &state->swapstate.eSwapCoords, NULL);
2319     ret =
2320         do_cpt_state(gmx_fio_getxdr(fp), TRUE, state->flags, state, NULL);
2321     if (ret)
2322     {
2323         cp_error();
2324     }
2325     ret = do_cpt_ekinstate(gmx_fio_getxdr(fp), flags_eks, &state->ekinstate, NULL);
2326     if (ret)
2327     {
2328         cp_error();
2329     }
2330     ret = do_cpt_enerhist(gmx_fio_getxdr(fp), TRUE,
2331                           flags_enh, &state->enerhist, NULL);
2332     if (ret)
2333     {
2334         cp_error();
2335     }
2336     ret = do_cpt_df_hist(gmx_fio_getxdr(fp), flags_dfh, &state->dfhist, NULL);
2337     if (ret)
2338     {
2339         cp_error();
2340     }
2341
2342     ret = do_cpt_EDstate(gmx_fio_getxdr(fp), TRUE, &state->edsamstate, NULL);
2343     if (ret)
2344     {
2345         cp_error();
2346     }
2347
2348     ret = do_cpt_swapstate(gmx_fio_getxdr(fp), TRUE, &state->swapstate, NULL);
2349     if (ret)
2350     {
2351         cp_error();
2352     }
2353
2354     ret = do_cpt_files(gmx_fio_getxdr(fp), TRUE,
2355                        outputfiles != NULL ? outputfiles : &files_loc,
2356                        outputfiles != NULL ? nfiles : &nfiles_loc,
2357                        NULL, file_version);
2358     if (files_loc != NULL)
2359     {
2360         sfree(files_loc);
2361     }
2362
2363     if (ret)
2364     {
2365         cp_error();
2366     }
2367
2368     ret = do_cpt_footer(gmx_fio_getxdr(fp), file_version);
2369     if (ret)
2370     {
2371         cp_error();
2372     }
2373
2374     sfree(fprog);
2375     sfree(ftime);
2376     sfree(btime);
2377     sfree(buser);
2378     sfree(bhost);
2379 }
2380
2381 void
2382 read_checkpoint_state(const char *fn, int *simulation_part,
2383                       gmx_int64_t *step, double *t, t_state *state)
2384 {
2385     t_fileio *fp;
2386
2387     fp = gmx_fio_open(fn, "r");
2388     read_checkpoint_data(fp, simulation_part, step, t, state, NULL, NULL);
2389     if (gmx_fio_close(fp) != 0)
2390     {
2391         gmx_file("Cannot read/write checkpoint; corrupt file, or maybe you are out of disk space?");
2392     }
2393 }
2394
2395 void read_checkpoint_trxframe(t_fileio *fp, t_trxframe *fr)
2396 {
2397     /* This next line is nasty because the sub-structures of t_state
2398      * cannot be assumed to be zeroed (or even initialized in ways the
2399      * rest of the code might assume). Using snew would be better, but
2400      * this will all go away for 5.0. */
2401     t_state         state;
2402     int             simulation_part;
2403     gmx_int64_t     step;
2404     double          t;
2405
2406     init_state(&state, 0, 0, 0, 0, 0);
2407
2408     read_checkpoint_data(fp, &simulation_part, &step, &t, &state, NULL, NULL);
2409
2410     fr->natoms  = state.natoms;
2411     fr->bTitle  = FALSE;
2412     fr->bStep   = TRUE;
2413     fr->step    = gmx_int64_to_int(step,
2414                                    "conversion of checkpoint to trajectory");
2415     fr->bTime      = TRUE;
2416     fr->time       = t;
2417     fr->bLambda    = TRUE;
2418     fr->lambda     = state.lambda[efptFEP];
2419     fr->fep_state  = state.fep_state;
2420     fr->bAtoms     = FALSE;
2421     fr->bX         = (state.flags & (1<<estX));
2422     if (fr->bX)
2423     {
2424         fr->x     = state.x;
2425         state.x   = NULL;
2426     }
2427     fr->bV      = (state.flags & (1<<estV));
2428     if (fr->bV)
2429     {
2430         fr->v     = state.v;
2431         state.v   = NULL;
2432     }
2433     fr->bF      = FALSE;
2434     fr->bBox    = (state.flags & (1<<estBOX));
2435     if (fr->bBox)
2436     {
2437         copy_mat(state.box, fr->box);
2438     }
2439     done_state(&state);
2440 }
2441
2442 void list_checkpoint(const char *fn, FILE *out)
2443 {
2444     t_fileio            *fp;
2445     int                  file_version;
2446     char                *version, *btime, *buser, *bhost, *fprog, *ftime;
2447     int                  double_prec;
2448     int                  eIntegrator, simulation_part, nppnodes, npme;
2449     gmx_int64_t          step;
2450     double               t;
2451     ivec                 dd_nc;
2452     t_state              state;
2453     int                  flags_eks, flags_enh, flags_dfh;
2454     int                  ret;
2455     gmx_file_position_t *outputfiles;
2456     int                  nfiles;
2457
2458     init_state(&state, -1, -1, -1, -1, 0);
2459
2460     fp = gmx_fio_open(fn, "r");
2461     do_cpt_header(gmx_fio_getxdr(fp), TRUE, &file_version,
2462                   &version, &btime, &buser, &bhost, &double_prec, &fprog, &ftime,
2463                   &eIntegrator, &simulation_part, &step, &t, &nppnodes, dd_nc, &npme,
2464                   &state.natoms, &state.ngtc, &state.nnhpres, &state.nhchainlength,
2465                   &(state.dfhist.nlambda), &state.flags,
2466                   &flags_eks, &flags_enh, &flags_dfh, &state.edsamstate.nED,
2467                   &state.swapstate.eSwapCoords, out);
2468     ret = do_cpt_state(gmx_fio_getxdr(fp), TRUE, state.flags, &state, out);
2469     if (ret)
2470     {
2471         cp_error();
2472     }
2473     ret = do_cpt_ekinstate(gmx_fio_getxdr(fp), flags_eks, &state.ekinstate, out);
2474     if (ret)
2475     {
2476         cp_error();
2477     }
2478     ret = do_cpt_enerhist(gmx_fio_getxdr(fp), TRUE,
2479                           flags_enh, &state.enerhist, out);
2480
2481     if (ret == 0)
2482     {
2483         ret = do_cpt_df_hist(gmx_fio_getxdr(fp),
2484                              flags_dfh, &state.dfhist, out);
2485     }
2486
2487     if (ret == 0)
2488     {
2489         ret = do_cpt_EDstate(gmx_fio_getxdr(fp), TRUE, &state.edsamstate, out);
2490     }
2491
2492     if (ret == 0)
2493     {
2494         ret = do_cpt_swapstate(gmx_fio_getxdr(fp), TRUE, &state.swapstate, out);
2495     }
2496
2497     if (ret == 0)
2498     {
2499         do_cpt_files(gmx_fio_getxdr(fp), TRUE, &outputfiles, &nfiles, out, file_version);
2500     }
2501
2502     if (ret == 0)
2503     {
2504         ret = do_cpt_footer(gmx_fio_getxdr(fp), file_version);
2505     }
2506
2507     if (ret)
2508     {
2509         cp_warning(out);
2510     }
2511     if (gmx_fio_close(fp) != 0)
2512     {
2513         gmx_file("Cannot read/write checkpoint; corrupt file, or maybe you are out of disk space?");
2514     }
2515
2516     done_state(&state);
2517 }
2518
2519
2520 static gmx_bool exist_output_file(const char *fnm_cp, int nfile, const t_filenm fnm[])
2521 {
2522     int i;
2523
2524     /* Check if the output file name stored in the checkpoint file
2525      * is one of the output file names of mdrun.
2526      */
2527     i = 0;
2528     while (i < nfile &&
2529            !(is_output(&fnm[i]) && strcmp(fnm_cp, fnm[i].fns[0]) == 0))
2530     {
2531         i++;
2532     }
2533
2534     return (i < nfile && gmx_fexist(fnm_cp));
2535 }
2536
2537 /* This routine cannot print tons of data, since it is called before the log file is opened. */
2538 gmx_bool read_checkpoint_simulation_part(const char *filename, int *simulation_part,
2539                                          gmx_int64_t *cpt_step, t_commrec *cr,
2540                                          gmx_bool bAppendReq,
2541                                          int nfile, const t_filenm fnm[],
2542                                          const char *part_suffix, gmx_bool *bAddPart)
2543 {
2544     t_fileio            *fp;
2545     gmx_int64_t          step = 0;
2546     double               t;
2547     /* This next line is nasty because the sub-structures of t_state
2548      * cannot be assumed to be zeroed (or even initialized in ways the
2549      * rest of the code might assume). Using snew would be better, but
2550      * this will all go away for 5.0. */
2551     t_state              state;
2552     int                  nfiles;
2553     gmx_file_position_t *outputfiles;
2554     int                  nexist, f;
2555     gmx_bool             bAppend;
2556     char                *fn, suf_up[STRLEN];
2557
2558     bAppend = FALSE;
2559
2560     if (SIMMASTER(cr))
2561     {
2562         if (!gmx_fexist(filename) || (!(fp = gmx_fio_open(filename, "r")) ))
2563         {
2564             *simulation_part = 0;
2565         }
2566         else
2567         {
2568             init_state(&state, 0, 0, 0, 0, 0);
2569
2570             read_checkpoint_data(fp, simulation_part, &step, &t, &state,
2571                                  &nfiles, &outputfiles);
2572             if (gmx_fio_close(fp) != 0)
2573             {
2574                 gmx_file("Cannot read/write checkpoint; corrupt file, or maybe you are out of disk space?");
2575             }
2576             done_state(&state);
2577
2578             if (bAppendReq)
2579             {
2580                 nexist = 0;
2581                 for (f = 0; f < nfiles; f++)
2582                 {
2583                     if (exist_output_file(outputfiles[f].filename, nfile, fnm))
2584                     {
2585                         nexist++;
2586                     }
2587                 }
2588                 if (nexist == nfiles)
2589                 {
2590                     bAppend = bAppendReq;
2591                 }
2592                 else if (nexist > 0)
2593                 {
2594                     fprintf(stderr,
2595                             "Output file appending has been requested,\n"
2596                             "but some output files listed in the checkpoint file %s\n"
2597                             "are not present or are named differently by the current program:\n",
2598                             filename);
2599                     fprintf(stderr, "output files present:");
2600                     for (f = 0; f < nfiles; f++)
2601                     {
2602                         if (exist_output_file(outputfiles[f].filename,
2603                                               nfile, fnm))
2604                         {
2605                             fprintf(stderr, " %s", outputfiles[f].filename);
2606                         }
2607                     }
2608                     fprintf(stderr, "\n");
2609                     fprintf(stderr, "output files not present or named differently:");
2610                     for (f = 0; f < nfiles; f++)
2611                     {
2612                         if (!exist_output_file(outputfiles[f].filename,
2613                                                nfile, fnm))
2614                         {
2615                             fprintf(stderr, " %s", outputfiles[f].filename);
2616                         }
2617                     }
2618                     fprintf(stderr, "\n");
2619
2620                     gmx_fatal(FARGS, "File appending requested, but %d of the %d output files are not present or are named differently", nfiles-nexist, nfiles);
2621                 }
2622             }
2623
2624             if (bAppend)
2625             {
2626                 if (nfiles == 0)
2627                 {
2628                     gmx_fatal(FARGS, "File appending requested, but no output file information is stored in the checkpoint file");
2629                 }
2630                 fn = outputfiles[0].filename;
2631                 if (strlen(fn) < 4 ||
2632                     gmx_strcasecmp(fn+strlen(fn)-4, ftp2ext(efLOG)) == 0)
2633                 {
2634                     gmx_fatal(FARGS, "File appending requested, but the log file is not the first file listed in the checkpoint file");
2635                 }
2636                 /* Set bAddPart to whether the suffix string '.part' is present
2637                  * in the log file name.
2638                  */
2639                 strcpy(suf_up, part_suffix);
2640                 upstring(suf_up);
2641                 *bAddPart = (strstr(fn, part_suffix) != NULL ||
2642                              strstr(fn, suf_up) != NULL);
2643             }
2644
2645             sfree(outputfiles);
2646         }
2647     }
2648     if (PAR(cr))
2649     {
2650         gmx_bcast(sizeof(*simulation_part), simulation_part, cr);
2651
2652         if (*simulation_part > 0 && bAppendReq)
2653         {
2654             gmx_bcast(sizeof(bAppend), &bAppend, cr);
2655             gmx_bcast(sizeof(*bAddPart), bAddPart, cr);
2656         }
2657     }
2658     if (NULL != cpt_step)
2659     {
2660         *cpt_step = step;
2661     }
2662
2663     return bAppend;
2664 }