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