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