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