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