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