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