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