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