added Verlet scheme and NxN non-bonded functionality
[gromacs.git] / src / gmxlib / checkpoint.c
blob927f82fa384661a8eb3456882a3575435cbc4790
1 /* -*- mode: c; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; c-file-style: "stroustrup"; -*-
3 *
4 * This file is part of Gromacs Copyright (c) 1991-2008
5 * David van der Spoel, Erik Lindahl, Berk Hess, University of Groningen.
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.
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
15 * And Hey:
16 * Gnomes, ROck Monsters And Chili Sauce
19 /* The source code in this file should be thread-safe.
20 Please keep it that way. */
23 #ifdef HAVE_CONFIG_H
24 #include <config.h>
25 #endif
26 #include "gmx_header_config.h"
28 #include <string.h>
29 #include <time.h>
31 #ifdef HAVE_SYS_TIME_H
32 #include <sys/time.h>
33 #endif
36 #ifdef GMX_NATIVE_WINDOWS
37 /* _chsize_s */
38 #include <io.h>
39 #include <sys/locking.h>
40 #endif
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>
60 #ifdef GMX_FAHCORE
61 #include "corewrap.h"
62 #endif
65 /* Portable version of ctime_r implemented in src/gmxlib/string2.c, but we do not want it declared in public installed headers */
66 char *
67 gmx_ctime_r(const time_t *clock,char *buf, int n);
70 #define CPT_MAGIC1 171817
71 #define CPT_MAGIC2 171819
72 #define CPTSTRLEN 1024
74 #ifdef GMX_DOUBLE
75 #define GMX_CPT_BUILD_DP 1
76 #else
77 #define GMX_CPT_BUILD_DP 0
78 #endif
80 /* cpt_version should normally only be changed
81 * when the header of footer format changes.
82 * The state data format itself is backward and forward compatible.
83 * But old code can not read a new entry that is present in the file
84 * (but can read a new format when new entries are not present).
86 static const int cpt_version = 14;
89 const char *est_names[estNR]=
91 "FE-lambda",
92 "box", "box-rel", "box-v", "pres_prev",
93 "nosehoover-xi", "thermostat-integral",
94 "x", "v", "SDx", "CGp", "LD-rng", "LD-rng-i",
95 "disre_initf", "disre_rm3tav",
96 "orire_initf", "orire_Dtav",
97 "svir_prev", "nosehoover-vxi", "v_eta", "vol0", "nhpres_xi", "nhpres_vxi", "fvir_prev","fep_state", "MC-rng", "MC-rng-i"
100 enum { eeksEKIN_N, eeksEKINH, eeksDEKINDL, eeksMVCOS, eeksEKINF, eeksEKINO, eeksEKINSCALEF, eeksEKINSCALEH, eeksVSCALE, eeksEKINTOTAL, eeksNR };
102 const char *eeks_names[eeksNR]=
104 "Ekin_n", "Ekinh", "dEkindlambda", "mv_cos",
105 "Ekinf", "Ekinh_old", "EkinScaleF_NHC", "EkinScaleH_NHC","Vscale_NHC","Ekin_Total"
108 enum { eenhENERGY_N, eenhENERGY_AVER, eenhENERGY_SUM, eenhENERGY_NSUM,
109 eenhENERGY_SUM_SIM, eenhENERGY_NSUM_SIM,
110 eenhENERGY_NSTEPS, eenhENERGY_NSTEPS_SIM,
111 eenhENERGY_DELTA_H_NN,
112 eenhENERGY_DELTA_H_LIST,
113 eenhENERGY_DELTA_H_STARTTIME,
114 eenhENERGY_DELTA_H_STARTLAMBDA,
115 eenhNR };
117 const char *eenh_names[eenhNR]=
119 "energy_n", "energy_aver", "energy_sum", "energy_nsum",
120 "energy_sum_sim", "energy_nsum_sim",
121 "energy_nsteps", "energy_nsteps_sim",
122 "energy_delta_h_nn",
123 "energy_delta_h_list",
124 "energy_delta_h_start_time",
125 "energy_delta_h_start_lambda"
128 /* free energy history variables -- need to be preserved over checkpoint */
129 enum { edfhBEQUIL,edfhNATLAMBDA,edfhWLHISTO,edfhWLDELTA,edfhSUMWEIGHTS,edfhSUMDG,edfhSUMMINVAR,edfhSUMVAR,
130 edfhACCUMP,edfhACCUMM,edfhACCUMP2,edfhACCUMM2,edfhTIJ,edfhTIJEMP,edfhNR };
131 /* free energy history variable names */
132 const char *edfh_names[edfhNR]=
134 "bEquilibrated","N_at_state", "Wang-Landau_Histogram", "Wang-Landau-delta", "Weights", "Free Energies", "minvar","variance",
135 "accumulated_plus", "accumulated_minus", "accumulated_plus_2", "accumulated_minus_2", "Tij", "Tij_empirical"
138 #ifdef GMX_NATIVE_WINDOWS
139 static int
140 gmx_wintruncate(const char *filename, __int64 size)
142 #ifdef GMX_FAHCORE
143 /*we do this elsewhere*/
144 return 0;
145 #else
146 FILE *fp;
147 int rc;
149 fp=fopen(filename,"rb+");
151 if(fp==NULL)
153 return -1;
156 return _chsize_s( fileno(fp), size);
157 #endif
159 #endif
162 enum { ecprREAL, ecprRVEC, ecprMATRIX };
164 enum { cptpEST, cptpEEKS, cptpEENH, cptpEDFH };
165 /* enums for the different components of checkpoint variables, replacing the hard coded ones.
166 cptpEST - state variables.
167 cptpEEKS - Kinetic energy state variables.
168 cptpEENH - Energy history state variables.
169 cptpEDFH - free energy history variables.
173 static const char *st_names(int cptp,int ecpt)
175 switch (cptp)
177 case cptpEST: return est_names [ecpt]; break;
178 case cptpEEKS: return eeks_names[ecpt]; break;
179 case cptpEENH: return eenh_names[ecpt]; break;
180 case cptpEDFH: return edfh_names[ecpt]; break;
183 return NULL;
186 static void cp_warning(FILE *fp)
188 fprintf(fp,"\nWARNING: Checkpoint file is corrupted or truncated\n\n");
191 static void cp_error()
193 gmx_fatal(FARGS,"Checkpoint file corrupted/truncated, or maybe you are out of disk space?");
196 static void do_cpt_string_err(XDR *xd,gmx_bool bRead,const char *desc,char **s,FILE *list)
198 bool_t res=0;
200 if (bRead)
202 snew(*s,CPTSTRLEN);
204 res = xdr_string(xd,s,CPTSTRLEN);
205 if (res == 0)
207 cp_error();
209 if (list)
211 fprintf(list,"%s = %s\n",desc,*s);
212 sfree(*s);
216 static int do_cpt_int(XDR *xd,const char *desc,int *i,FILE *list)
218 bool_t res=0;
220 res = xdr_int(xd,i);
221 if (res == 0)
223 return -1;
225 if (list)
227 fprintf(list,"%s = %d\n",desc,*i);
229 return 0;
232 static int do_cpt_u_chars(XDR *xd,const char *desc,int n,unsigned char *i,FILE *list)
234 bool_t res=1;
235 int j;
236 if (list)
238 fprintf(list,"%s = ",desc);
240 for (j=0; j<n && res; j++)
242 res &= xdr_u_char(xd,&i[j]);
243 if (list)
245 fprintf(list,"%02x",i[j]);
248 if (list)
250 fprintf(list,"\n");
252 if (res == 0)
254 return -1;
257 return 0;
260 static void do_cpt_int_err(XDR *xd,const char *desc,int *i,FILE *list)
262 if (do_cpt_int(xd,desc,i,list) < 0)
264 cp_error();
268 static void do_cpt_step_err(XDR *xd,const char *desc,gmx_large_int_t *i,FILE *list)
270 bool_t res=0;
271 char buf[STEPSTRSIZE];
273 res = xdr_gmx_large_int(xd,i,"reading checkpoint file");
274 if (res == 0)
276 cp_error();
278 if (list)
280 fprintf(list,"%s = %s\n",desc,gmx_step_str(*i,buf));
284 static void do_cpt_double_err(XDR *xd,const char *desc,double *f,FILE *list)
286 bool_t res=0;
288 res = xdr_double(xd,f);
289 if (res == 0)
291 cp_error();
293 if (list)
295 fprintf(list,"%s = %f\n",desc,*f);
299 /* If nval >= 0, nval is used; on read this should match the passed value.
300 * If nval n<0, *nptr is used; on read the value is stored in nptr
302 static int do_cpte_reals_low(XDR *xd,int cptp,int ecpt,int sflags,
303 int nval,int *nptr,real **v,
304 FILE *list,int erealtype)
306 bool_t res=0;
307 #ifndef GMX_DOUBLE
308 int dtc=xdr_datatype_float;
309 #else
310 int dtc=xdr_datatype_double;
311 #endif
312 real *vp,*va=NULL;
313 float *vf;
314 double *vd;
315 int nf,dt,i;
317 if (list == NULL)
319 if (nval >= 0)
321 nf = nval;
323 else
325 if (nptr == NULL)
327 gmx_incons("*ntpr=NULL in do_cpte_reals_low");
329 nf = *nptr;
332 res = xdr_int(xd,&nf);
333 if (res == 0)
335 return -1;
337 if (list == NULL)
339 if (nval >= 0)
341 if (nf != nval)
343 gmx_fatal(FARGS,"Count mismatch for state entry %s, code count is %d, file count is %d\n",st_names(cptp,ecpt),nval,nf);
346 else
348 *nptr = nf;
351 dt = dtc;
352 res = xdr_int(xd,&dt);
353 if (res == 0)
355 return -1;
357 if (dt != dtc)
359 fprintf(stderr,"Precision mismatch for state entry %s, code precision is %s, file precision is %s\n",
360 st_names(cptp,ecpt),xdr_datatype_names[dtc],
361 xdr_datatype_names[dt]);
363 if (list || !(sflags & (1<<ecpt)))
365 snew(va,nf);
366 vp = va;
368 else
370 if (*v == NULL)
372 snew(*v,nf);
374 vp = *v;
376 if (dt == xdr_datatype_float)
378 if (dtc == xdr_datatype_float)
380 vf = (float *)vp;
382 else
384 snew(vf,nf);
386 res = xdr_vector(xd,(char *)vf,nf,
387 (unsigned int)sizeof(float),(xdrproc_t)xdr_float);
388 if (res == 0)
390 return -1;
392 if (dtc != xdr_datatype_float)
394 for(i=0; i<nf; i++)
396 vp[i] = vf[i];
398 sfree(vf);
401 else
403 if (dtc == xdr_datatype_double)
405 vd = (double *)vp;
407 else
409 snew(vd,nf);
411 res = xdr_vector(xd,(char *)vd,nf,
412 (unsigned int)sizeof(double),(xdrproc_t)xdr_double);
413 if (res == 0)
415 return -1;
417 if (dtc != xdr_datatype_double)
419 for(i=0; i<nf; i++)
421 vp[i] = vd[i];
423 sfree(vd);
427 if (list)
429 switch (erealtype)
431 case ecprREAL:
432 pr_reals(list,0,st_names(cptp,ecpt),vp,nf);
433 break;
434 case ecprRVEC:
435 pr_rvecs(list,0,st_names(cptp,ecpt),(rvec *)vp,nf/3);
436 break;
437 default:
438 gmx_incons("Unknown checkpoint real type");
441 if (va)
443 sfree(va);
446 return 0;
450 /* This function stores n along with the reals for reading,
451 * but on reading it assumes that n matches the value in the checkpoint file,
452 * a fatal error is generated when this is not the case.
454 static int do_cpte_reals(XDR *xd,int cptp,int ecpt,int sflags,
455 int n,real **v,FILE *list)
457 return do_cpte_reals_low(xd,cptp,ecpt,sflags,n,NULL,v,list,ecprREAL);
460 /* This function does the same as do_cpte_reals,
461 * except that on reading it ignores the passed value of *n
462 * and stored the value read from the checkpoint file in *n.
464 static int do_cpte_n_reals(XDR *xd,int cptp,int ecpt,int sflags,
465 int *n,real **v,FILE *list)
467 return do_cpte_reals_low(xd,cptp,ecpt,sflags,-1,n,v,list,ecprREAL);
470 static int do_cpte_real(XDR *xd,int cptp,int ecpt,int sflags,
471 real *r,FILE *list)
473 int n;
475 return do_cpte_reals_low(xd,cptp,ecpt,sflags,1,NULL,&r,list,ecprREAL);
478 static int do_cpte_ints(XDR *xd,int cptp,int ecpt,int sflags,
479 int n,int **v,FILE *list)
481 bool_t res=0;
482 int dtc=xdr_datatype_int;
483 int *vp,*va=NULL;
484 int nf,dt,i;
486 nf = n;
487 res = xdr_int(xd,&nf);
488 if (res == 0)
490 return -1;
492 if (list == NULL && v != NULL && nf != n)
494 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 dt = dtc;
497 res = xdr_int(xd,&dt);
498 if (res == 0)
500 return -1;
502 if (dt != dtc)
504 gmx_fatal(FARGS,"Type mismatch for state entry %s, code type is %s, file type is %s\n",
505 st_names(cptp,ecpt),xdr_datatype_names[dtc],
506 xdr_datatype_names[dt]);
508 if (list || !(sflags & (1<<ecpt)) || v == NULL)
510 snew(va,nf);
511 vp = va;
513 else
515 if (*v == NULL)
517 snew(*v,nf);
519 vp = *v;
521 res = xdr_vector(xd,(char *)vp,nf,
522 (unsigned int)sizeof(int),(xdrproc_t)xdr_int);
523 if (res == 0)
525 return -1;
527 if (list)
529 pr_ivec(list,0,st_names(cptp,ecpt),vp,nf,TRUE);
531 if (va)
533 sfree(va);
536 return 0;
539 static int do_cpte_int(XDR *xd,int cptp,int ecpt,int sflags,
540 int *i,FILE *list)
542 return do_cpte_ints(xd,cptp,ecpt,sflags,1,&i,list);
545 static int do_cpte_doubles(XDR *xd,int cptp,int ecpt,int sflags,
546 int n,double **v,FILE *list)
548 bool_t res=0;
549 int dtc=xdr_datatype_double;
550 double *vp,*va=NULL;
551 int nf,dt,i;
553 nf = n;
554 res = xdr_int(xd,&nf);
555 if (res == 0)
557 return -1;
559 if (list == NULL && nf != n)
561 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 dt = dtc;
564 res = xdr_int(xd,&dt);
565 if (res == 0)
567 return -1;
569 if (dt != dtc)
571 gmx_fatal(FARGS,"Precision mismatch for state entry %s, code precision is %s, file precision is %s\n",
572 st_names(cptp,ecpt),xdr_datatype_names[dtc],
573 xdr_datatype_names[dt]);
575 if (list || !(sflags & (1<<ecpt)))
577 snew(va,nf);
578 vp = va;
580 else
582 if (*v == NULL)
584 snew(*v,nf);
586 vp = *v;
588 res = xdr_vector(xd,(char *)vp,nf,
589 (unsigned int)sizeof(double),(xdrproc_t)xdr_double);
590 if (res == 0)
592 return -1;
594 if (list)
596 pr_doubles(list,0,st_names(cptp,ecpt),vp,nf);
598 if (va)
600 sfree(va);
603 return 0;
606 static int do_cpte_double(XDR *xd,int cptp,int ecpt,int sflags,
607 double *r,FILE *list)
609 return do_cpte_doubles(xd,cptp,ecpt,sflags,1,&r,list);
613 static int do_cpte_rvecs(XDR *xd,int cptp,int ecpt,int sflags,
614 int n,rvec **v,FILE *list)
616 int n3;
618 return do_cpte_reals_low(xd,cptp,ecpt,sflags,
619 n*DIM,NULL,(real **)v,list,ecprRVEC);
622 static int do_cpte_matrix(XDR *xd,int cptp,int ecpt,int sflags,
623 matrix v,FILE *list)
625 real *vr;
626 real ret;
628 vr = (real *)&(v[0][0]);
629 ret = do_cpte_reals_low(xd,cptp,ecpt,sflags,
630 DIM*DIM,NULL,&vr,NULL,ecprMATRIX);
632 if (list && ret == 0)
634 pr_rvecs(list,0,st_names(cptp,ecpt),v,DIM);
637 return ret;
641 static int do_cpte_nmatrix(XDR *xd,int cptp,int ecpt,int sflags,
642 int n, real **v,FILE *list)
644 int i;
645 real *vr;
646 real ret,reti;
647 char name[CPTSTRLEN];
649 ret = 0;
650 if (v==NULL)
652 snew(v,n);
654 for (i=0;i<n;i++)
656 reti = 0;
657 vr = v[i];
658 reti = do_cpte_reals_low(xd,cptp,ecpt,sflags,n,NULL,&(v[i]),NULL,ecprREAL);
659 if (list && reti == 0)
661 sprintf(name,"%s[%d]",st_names(cptp,ecpt),i);
662 pr_reals(list,0,name,v[i],n);
664 if (reti == 0)
666 ret = 0;
669 return ret;
672 static int do_cpte_matrices(XDR *xd,int cptp,int ecpt,int sflags,
673 int n,matrix **v,FILE *list)
675 bool_t res=0;
676 matrix *vp,*va=NULL;
677 real *vr;
678 int nf,i,j,k;
679 int ret;
681 nf = n;
682 res = xdr_int(xd,&nf);
683 if (res == 0)
685 return -1;
687 if (list == NULL && nf != n)
689 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 if (list || !(sflags & (1<<ecpt)))
693 snew(va,nf);
694 vp = va;
696 else
698 if (*v == NULL)
700 snew(*v,nf);
702 vp = *v;
704 snew(vr,nf*DIM*DIM);
705 for(i=0; i<nf; i++)
707 for(j=0; j<DIM; j++)
709 for(k=0; k<DIM; k++)
711 vr[(i*DIM+j)*DIM+k] = vp[i][j][k];
715 ret = do_cpte_reals_low(xd,cptp,ecpt,sflags,
716 nf*DIM*DIM,NULL,&vr,NULL,ecprMATRIX);
717 for(i=0; i<nf; i++)
719 for(j=0; j<DIM; j++)
721 for(k=0; k<DIM; k++)
723 vp[i][j][k] = vr[(i*DIM+j)*DIM+k];
727 sfree(vr);
729 if (list && ret == 0)
731 for(i=0; i<nf; i++)
733 pr_rvecs(list,0,st_names(cptp,ecpt),vp[i],DIM);
736 if (va)
738 sfree(va);
741 return ret;
744 static void do_cpt_header(XDR *xd,gmx_bool bRead,int *file_version,
745 char **version,char **btime,char **buser,char **bhost,
746 int *double_prec,
747 char **fprog,char **ftime,
748 int *eIntegrator,int *simulation_part,
749 gmx_large_int_t *step,double *t,
750 int *nnodes,int *dd_nc,int *npme,
751 int *natoms,int *ngtc, int *nnhpres, int *nhchainlength,
752 int *nlambda, int *flags_state,
753 int *flags_eks,int *flags_enh, int *flags_dfh,
754 FILE *list)
756 bool_t res=0;
757 int magic;
758 int idum=0;
759 int i;
760 char *fhost;
762 if (bRead)
764 magic = -1;
766 else
768 magic = CPT_MAGIC1;
770 res = xdr_int(xd,&magic);
771 if (res == 0)
773 gmx_fatal(FARGS,"The checkpoint file is empty/corrupted, or maybe you are out of disk space?");
775 if (magic != CPT_MAGIC1)
777 gmx_fatal(FARGS,"Start of file magic number mismatch, checkpoint file has %d, should be %d\n"
778 "The checkpoint file is corrupted or not a checkpoint file",
779 magic,CPT_MAGIC1);
781 if (!bRead)
783 snew(fhost,255);
784 #ifdef HAVE_UNISTD_H
785 if (gethostname(fhost,255) != 0)
787 sprintf(fhost,"unknown");
789 #else
790 sprintf(fhost,"unknown");
791 #endif
793 do_cpt_string_err(xd,bRead,"GROMACS version" ,version,list);
794 do_cpt_string_err(xd,bRead,"GROMACS build time" ,btime,list);
795 do_cpt_string_err(xd,bRead,"GROMACS build user" ,buser,list);
796 do_cpt_string_err(xd,bRead,"GROMACS build host" ,bhost,list);
797 do_cpt_string_err(xd,bRead,"generating program" ,fprog,list);
798 do_cpt_string_err(xd,bRead,"generation time" ,ftime,list);
799 *file_version = cpt_version;
800 do_cpt_int_err(xd,"checkpoint file version",file_version,list);
801 if (*file_version > cpt_version)
803 gmx_fatal(FARGS,"Attempting to read a checkpoint file of version %d with code of version %d\n",*file_version,cpt_version);
805 if (*file_version >= 13)
807 do_cpt_int_err(xd,"GROMACS double precision",double_prec,list);
809 else
811 *double_prec = -1;
813 if (*file_version >= 12)
815 do_cpt_string_err(xd,bRead,"generating host" ,&fhost,list);
816 if (list == NULL)
818 sfree(fhost);
821 do_cpt_int_err(xd,"#atoms" ,natoms ,list);
822 do_cpt_int_err(xd,"#T-coupling groups",ngtc ,list);
823 if (*file_version >= 10)
825 do_cpt_int_err(xd,"#Nose-Hoover T-chains",nhchainlength,list);
827 else
829 *nhchainlength = 1;
831 if (*file_version >= 11)
833 do_cpt_int_err(xd,"#Nose-Hoover T-chains for barostat ",nnhpres,list);
835 else
837 *nnhpres = 0;
839 if (*file_version >= 14)
841 do_cpt_int_err(xd,"# of total lambda states ",nlambda,list);
843 else
845 *nlambda = 0;
847 do_cpt_int_err(xd,"integrator" ,eIntegrator,list);
848 if (*file_version >= 3)
850 do_cpt_int_err(xd,"simulation part #", simulation_part,list);
852 else
854 *simulation_part = 1;
856 if (*file_version >= 5)
858 do_cpt_step_err(xd,"step" ,step ,list);
860 else
862 do_cpt_int_err(xd,"step" ,&idum ,list);
863 *step = idum;
865 do_cpt_double_err(xd,"t" ,t ,list);
866 do_cpt_int_err(xd,"#PP-nodes" ,nnodes ,list);
867 idum = 1;
868 do_cpt_int_err(xd,"dd_nc[x]",dd_nc ? &(dd_nc[0]) : &idum,list);
869 do_cpt_int_err(xd,"dd_nc[y]",dd_nc ? &(dd_nc[1]) : &idum,list);
870 do_cpt_int_err(xd,"dd_nc[z]",dd_nc ? &(dd_nc[2]) : &idum,list);
871 do_cpt_int_err(xd,"#PME-only nodes",npme,list);
872 do_cpt_int_err(xd,"state flags",flags_state,list);
873 if (*file_version >= 4)
875 do_cpt_int_err(xd,"ekin data flags",flags_eks,list);
876 do_cpt_int_err(xd,"energy history flags",flags_enh,list);
878 else
880 *flags_eks = 0;
881 *flags_enh = (*flags_state >> (estORIRE_DTAV+1));
882 *flags_state = (*flags_state & ~((1<<(estORIRE_DTAV+1)) |
883 (1<<(estORIRE_DTAV+2)) |
884 (1<<(estORIRE_DTAV+3))));
886 if (*file_version >= 14)
888 do_cpt_int_err(xd,"df history flags",flags_dfh,list);
889 } else {
890 *flags_dfh = 0;
894 static int do_cpt_footer(XDR *xd,gmx_bool bRead,int file_version)
896 bool_t res=0;
897 int magic;
899 if (file_version >= 2)
901 magic = CPT_MAGIC2;
902 res = xdr_int(xd,&magic);
903 if (res == 0)
905 cp_error();
907 if (magic != CPT_MAGIC2)
909 return -1;
913 return 0;
916 static int do_cpt_state(XDR *xd,gmx_bool bRead,
917 int fflags,t_state *state,
918 gmx_bool bReadRNG,FILE *list)
920 int sflags;
921 int **rng_p,**rngi_p;
922 int i;
923 int ret;
924 int nnht,nnhtp;
926 ret = 0;
928 nnht = state->nhchainlength*state->ngtc;
929 nnhtp = state->nhchainlength*state->nnhpres;
931 if (bReadRNG)
933 rng_p = (int **)&state->ld_rng;
934 rngi_p = &state->ld_rngi;
936 else
938 /* Do not read the RNG data */
939 rng_p = NULL;
940 rngi_p = NULL;
942 /* We want the MC_RNG the same across all the notes for now -- lambda MC is global */
944 sflags = state->flags;
945 for(i=0; (i<estNR && ret == 0); i++)
947 if (fflags & (1<<i))
949 switch (i)
951 case estLAMBDA: ret = do_cpte_reals(xd,cptpEST,i,sflags,efptNR,&(state->lambda),list); break;
952 case estFEPSTATE: ret = do_cpte_int (xd,cptpEST,i,sflags,&state->fep_state,list); break;
953 case estBOX: ret = do_cpte_matrix(xd,cptpEST,i,sflags,state->box,list); break;
954 case estBOX_REL: ret = do_cpte_matrix(xd,cptpEST,i,sflags,state->box_rel,list); break;
955 case estBOXV: ret = do_cpte_matrix(xd,cptpEST,i,sflags,state->boxv,list); break;
956 case estPRES_PREV: ret = do_cpte_matrix(xd,cptpEST,i,sflags,state->pres_prev,list); break;
957 case estSVIR_PREV: ret = do_cpte_matrix(xd,cptpEST,i,sflags,state->svir_prev,list); break;
958 case estFVIR_PREV: ret = do_cpte_matrix(xd,cptpEST,i,sflags,state->fvir_prev,list); break;
959 case estNH_XI: ret = do_cpte_doubles(xd,cptpEST,i,sflags,nnht,&state->nosehoover_xi,list); break;
960 case estNH_VXI: ret = do_cpte_doubles(xd,cptpEST,i,sflags,nnht,&state->nosehoover_vxi,list); break;
961 case estNHPRES_XI: ret = do_cpte_doubles(xd,cptpEST,i,sflags,nnhtp,&state->nhpres_xi,list); break;
962 case estNHPRES_VXI: ret = do_cpte_doubles(xd,cptpEST,i,sflags,nnhtp,&state->nhpres_vxi,list); break;
963 case estTC_INT: ret = do_cpte_doubles(xd,cptpEST,i,sflags,state->ngtc,&state->therm_integral,list); break;
964 case estVETA: ret = do_cpte_real(xd,cptpEST,i,sflags,&state->veta,list); break;
965 case estVOL0: ret = do_cpte_real(xd,cptpEST,i,sflags,&state->vol0,list); break;
966 case estX: ret = do_cpte_rvecs(xd,cptpEST,i,sflags,state->natoms,&state->x,list); break;
967 case estV: ret = do_cpte_rvecs(xd,cptpEST,i,sflags,state->natoms,&state->v,list); break;
968 case estSDX: ret = do_cpte_rvecs(xd,cptpEST,i,sflags,state->natoms,&state->sd_X,list); break;
969 case estLD_RNG: ret = do_cpte_ints(xd,cptpEST,i,sflags,state->nrng,rng_p,list); break;
970 case estLD_RNGI: ret = do_cpte_ints(xd,cptpEST,i,sflags,state->nrngi,rngi_p,list); break;
971 case estMC_RNG: ret = do_cpte_ints(xd,cptpEST,i,sflags,state->nmcrng,(int **)&state->mc_rng,list); break;
972 case estMC_RNGI: ret = do_cpte_ints(xd,cptpEST,i,sflags,1,&state->mc_rngi,list); break;
973 case estDISRE_INITF: ret = do_cpte_real (xd,cptpEST,i,sflags,&state->hist.disre_initf,list); break;
974 case estDISRE_RM3TAV: ret = do_cpte_reals(xd,cptpEST,i,sflags,state->hist.ndisrepairs,&state->hist.disre_rm3tav,list); break;
975 case estORIRE_INITF: ret = do_cpte_real (xd,cptpEST,i,sflags,&state->hist.orire_initf,list); break;
976 case estORIRE_DTAV: ret = do_cpte_reals(xd,cptpEST,i,sflags,state->hist.norire_Dtav,&state->hist.orire_Dtav,list); break;
977 default:
978 gmx_fatal(FARGS,"Unknown state entry %d\n"
979 "You are probably reading a new checkpoint file with old code",i);
984 return ret;
987 static int do_cpt_ekinstate(XDR *xd,gmx_bool bRead,
988 int fflags,ekinstate_t *ekins,
989 FILE *list)
991 int i;
992 int ret;
994 ret = 0;
996 for(i=0; (i<eeksNR && ret == 0); i++)
998 if (fflags & (1<<i))
1000 switch (i)
1003 case eeksEKIN_N: ret = do_cpte_int(xd,cptpEEKS,i,fflags,&ekins->ekin_n,list); break;
1004 case eeksEKINH : ret = do_cpte_matrices(xd,cptpEEKS,i,fflags,ekins->ekin_n,&ekins->ekinh,list); break;
1005 case eeksEKINF: ret = do_cpte_matrices(xd,cptpEEKS,i,fflags,ekins->ekin_n,&ekins->ekinf,list); break;
1006 case eeksEKINO: ret = do_cpte_matrices(xd,cptpEEKS,i,fflags,ekins->ekin_n,&ekins->ekinh_old,list); break;
1007 case eeksEKINTOTAL: ret = do_cpte_matrix(xd,cptpEEKS,i,fflags,ekins->ekin_total,list); break;
1008 case eeksEKINSCALEF: ret = do_cpte_doubles(xd,cptpEEKS,i,fflags,ekins->ekin_n,&ekins->ekinscalef_nhc,list); break;
1009 case eeksVSCALE: ret = do_cpte_doubles(xd,1,cptpEEKS,fflags,ekins->ekin_n,&ekins->vscale_nhc,list); break;
1010 case eeksEKINSCALEH: ret = do_cpte_doubles(xd,1,cptpEEKS,fflags,ekins->ekin_n,&ekins->ekinscaleh_nhc,list); break;
1011 case eeksDEKINDL : ret = do_cpte_real(xd,1,cptpEEKS,fflags,&ekins->dekindl,list); break;
1012 case eeksMVCOS: ret = do_cpte_real(xd,1,cptpEEKS,fflags,&ekins->mvcos,list); break;
1013 default:
1014 gmx_fatal(FARGS,"Unknown ekin data state entry %d\n"
1015 "You are probably reading a new checkpoint file with old code",i);
1020 return ret;
1024 static int do_cpt_enerhist(XDR *xd,gmx_bool bRead,
1025 int fflags,energyhistory_t *enerhist,
1026 FILE *list)
1028 int i;
1029 int j;
1030 int ret;
1032 ret = 0;
1034 if (bRead)
1036 enerhist->nsteps = 0;
1037 enerhist->nsum = 0;
1038 enerhist->nsteps_sim = 0;
1039 enerhist->nsum_sim = 0;
1040 enerhist->dht = NULL;
1042 if (fflags & (1<< eenhENERGY_DELTA_H_NN) )
1044 snew(enerhist->dht,1);
1045 enerhist->dht->ndh = NULL;
1046 enerhist->dht->dh = NULL;
1047 enerhist->dht->start_lambda_set=FALSE;
1051 for(i=0; (i<eenhNR && ret == 0); i++)
1053 if (fflags & (1<<i))
1055 switch (i)
1057 case eenhENERGY_N: ret = do_cpte_int(xd,cptpEENH,i,fflags,&enerhist->nener,list); break;
1058 case eenhENERGY_AVER: ret = do_cpte_doubles(xd,cptpEENH,i,fflags,enerhist->nener,&enerhist->ener_ave,list); break;
1059 case eenhENERGY_SUM: ret = do_cpte_doubles(xd,cptpEENH,i,fflags,enerhist->nener,&enerhist->ener_sum,list); break;
1060 case eenhENERGY_NSUM: do_cpt_step_err(xd,eenh_names[i],&enerhist->nsum,list); break;
1061 case eenhENERGY_SUM_SIM: ret = do_cpte_doubles(xd,cptpEENH,i,fflags,enerhist->nener,&enerhist->ener_sum_sim,list); break;
1062 case eenhENERGY_NSUM_SIM: do_cpt_step_err(xd,eenh_names[i],&enerhist->nsum_sim,list); break;
1063 case eenhENERGY_NSTEPS: do_cpt_step_err(xd,eenh_names[i],&enerhist->nsteps,list); break;
1064 case eenhENERGY_NSTEPS_SIM: do_cpt_step_err(xd,eenh_names[i],&enerhist->nsteps_sim,list); break;
1065 case eenhENERGY_DELTA_H_NN: do_cpt_int_err(xd,eenh_names[i], &(enerhist->dht->nndh), list);
1066 if (bRead) /* now allocate memory for it */
1068 snew(enerhist->dht->dh, enerhist->dht->nndh);
1069 snew(enerhist->dht->ndh, enerhist->dht->nndh);
1070 for(j=0;j<enerhist->dht->nndh;j++)
1072 enerhist->dht->ndh[j] = 0;
1073 enerhist->dht->dh[j] = NULL;
1076 break;
1077 case eenhENERGY_DELTA_H_LIST:
1078 for(j=0;j<enerhist->dht->nndh;j++)
1080 ret=do_cpte_n_reals(xd, cptpEENH, i, fflags, &enerhist->dht->ndh[j], &(enerhist->dht->dh[j]), list);
1082 break;
1083 case eenhENERGY_DELTA_H_STARTTIME:
1084 ret=do_cpte_double(xd, cptpEENH, i, fflags, &(enerhist->dht->start_time), list); break;
1085 case eenhENERGY_DELTA_H_STARTLAMBDA:
1086 ret=do_cpte_double(xd, cptpEENH, i, fflags, &(enerhist->dht->start_lambda), list); break;
1087 default:
1088 gmx_fatal(FARGS,"Unknown energy history entry %d\n"
1089 "You are probably reading a new checkpoint file with old code",i);
1094 if ((fflags & (1<<eenhENERGY_SUM)) && !(fflags & (1<<eenhENERGY_SUM_SIM)))
1096 /* Assume we have an old file format and copy sum to sum_sim */
1097 srenew(enerhist->ener_sum_sim,enerhist->nener);
1098 for(i=0; i<enerhist->nener; i++)
1100 enerhist->ener_sum_sim[i] = enerhist->ener_sum[i];
1102 fflags |= (1<<eenhENERGY_SUM_SIM);
1105 if ( (fflags & (1<<eenhENERGY_NSUM)) &&
1106 !(fflags & (1<<eenhENERGY_NSTEPS)))
1108 /* Assume we have an old file format and copy nsum to nsteps */
1109 enerhist->nsteps = enerhist->nsum;
1110 fflags |= (1<<eenhENERGY_NSTEPS);
1112 if ( (fflags & (1<<eenhENERGY_NSUM_SIM)) &&
1113 !(fflags & (1<<eenhENERGY_NSTEPS_SIM)))
1115 /* Assume we have an old file format and copy nsum to nsteps */
1116 enerhist->nsteps_sim = enerhist->nsum_sim;
1117 fflags |= (1<<eenhENERGY_NSTEPS_SIM);
1120 return ret;
1123 static int do_cpt_df_hist(XDR *xd,gmx_bool bRead,int fflags,df_history_t *dfhist,FILE *list)
1125 int i,nlambda;
1126 int ret;
1128 nlambda = dfhist->nlambda;
1129 ret = 0;
1131 for(i=0; (i<edfhNR && ret == 0); i++)
1133 if (fflags & (1<<i))
1135 switch (i)
1137 case edfhBEQUIL: ret = do_cpte_int(xd,cptpEDFH,i,fflags,&dfhist->bEquil,list); break;
1138 case edfhNATLAMBDA: ret = do_cpte_ints(xd,cptpEDFH,i,fflags,nlambda,&dfhist->n_at_lam,list); break;
1139 case edfhWLHISTO: ret = do_cpte_reals(xd,cptpEDFH,i,fflags,nlambda,&dfhist->wl_histo,list); break;
1140 case edfhWLDELTA: ret = do_cpte_real(xd,cptpEDFH,i,fflags,&dfhist->wl_delta,list); break;
1141 case edfhSUMWEIGHTS: ret = do_cpte_reals(xd,cptpEDFH,i,fflags,nlambda,&dfhist->sum_weights,list); break;
1142 case edfhSUMDG: ret = do_cpte_reals(xd,cptpEDFH,i,fflags,nlambda,&dfhist->sum_dg,list); break;
1143 case edfhSUMMINVAR: ret = do_cpte_reals(xd,cptpEDFH,i,fflags,nlambda,&dfhist->sum_minvar,list); break;
1144 case edfhSUMVAR: ret = do_cpte_reals(xd,cptpEDFH,i,fflags,nlambda,&dfhist->sum_variance,list); break;
1145 case edfhACCUMP: ret = do_cpte_nmatrix(xd,cptpEDFH,i,fflags,nlambda,dfhist->accum_p,list); break;
1146 case edfhACCUMM: ret = do_cpte_nmatrix(xd,cptpEDFH,i,fflags,nlambda,dfhist->accum_m,list); break;
1147 case edfhACCUMP2: ret = do_cpte_nmatrix(xd,cptpEDFH,i,fflags,nlambda,dfhist->accum_p2,list); break;
1148 case edfhACCUMM2: ret = do_cpte_nmatrix(xd,cptpEDFH,i,fflags,nlambda,dfhist->accum_m2,list); break;
1149 case edfhTIJ: ret = do_cpte_nmatrix(xd,cptpEDFH,i,fflags,nlambda,dfhist->Tij,list); break;
1150 case edfhTIJEMP: ret = do_cpte_nmatrix(xd,cptpEDFH,i,fflags,nlambda,dfhist->Tij_empirical,list); break;
1152 default:
1153 gmx_fatal(FARGS,"Unknown df history entry %d\n"
1154 "You are probably reading a new checkpoint file with old code",i);
1159 return ret;
1162 static int do_cpt_files(XDR *xd, gmx_bool bRead,
1163 gmx_file_position_t **p_outputfiles, int *nfiles,
1164 FILE *list, int file_version)
1166 int i,j;
1167 gmx_off_t offset;
1168 gmx_off_t mask = 0xFFFFFFFFL;
1169 int offset_high,offset_low;
1170 char *buf;
1171 gmx_file_position_t *outputfiles;
1173 if (do_cpt_int(xd,"number of output files",nfiles,list) != 0)
1175 return -1;
1178 if(bRead)
1180 snew(*p_outputfiles,*nfiles);
1183 outputfiles = *p_outputfiles;
1185 for(i=0;i<*nfiles;i++)
1187 /* 64-bit XDR numbers are not portable, so it is stored as separate high/low fractions */
1188 if(bRead)
1190 do_cpt_string_err(xd,bRead,"output filename",&buf,list);
1191 strncpy(outputfiles[i].filename,buf,CPTSTRLEN-1);
1192 if(list==NULL)
1194 sfree(buf);
1197 if (do_cpt_int(xd,"file_offset_high",&offset_high,list) != 0)
1199 return -1;
1201 if (do_cpt_int(xd,"file_offset_low",&offset_low,list) != 0)
1203 return -1;
1205 #if (SIZEOF_GMX_OFF_T > 4)
1206 outputfiles[i].offset = ( ((gmx_off_t) offset_high) << 32 ) | ( (gmx_off_t) offset_low & mask );
1207 #else
1208 outputfiles[i].offset = offset_low;
1209 #endif
1211 else
1213 buf = outputfiles[i].filename;
1214 do_cpt_string_err(xd,bRead,"output filename",&buf,list);
1215 /* writing */
1216 offset = outputfiles[i].offset;
1217 if (offset == -1)
1219 offset_low = -1;
1220 offset_high = -1;
1222 else
1224 #if (SIZEOF_GMX_OFF_T > 4)
1225 offset_low = (int) (offset & mask);
1226 offset_high = (int) ((offset >> 32) & mask);
1227 #else
1228 offset_low = offset;
1229 offset_high = 0;
1230 #endif
1232 if (do_cpt_int(xd,"file_offset_high",&offset_high,list) != 0)
1234 return -1;
1236 if (do_cpt_int(xd,"file_offset_low",&offset_low,list) != 0)
1238 return -1;
1241 if (file_version >= 8)
1243 if (do_cpt_int(xd,"file_checksum_size",&(outputfiles[i].chksum_size),
1244 list) != 0)
1246 return -1;
1248 if (do_cpt_u_chars(xd,"file_checksum",16,outputfiles[i].chksum,list) != 0)
1250 return -1;
1253 else
1255 outputfiles[i].chksum_size = -1;
1258 return 0;
1262 void write_checkpoint(const char *fn,gmx_bool bNumberAndKeep,
1263 FILE *fplog,t_commrec *cr,
1264 int eIntegrator,int simulation_part,
1265 gmx_bool bExpanded, int elamstats,
1266 gmx_large_int_t step,double t,t_state *state)
1268 t_fileio *fp;
1269 int file_version;
1270 char *version;
1271 char *btime;
1272 char *buser;
1273 char *bhost;
1274 int double_prec;
1275 char *fprog;
1276 char *fntemp; /* the temporary checkpoint file name */
1277 time_t now;
1278 char timebuf[STRLEN];
1279 int nppnodes,npmenodes,flag_64bit;
1280 char buf[1024],suffix[5+STEPSTRSIZE],sbuf[STEPSTRSIZE];
1281 gmx_file_position_t *outputfiles;
1282 int noutputfiles;
1283 char *ftime;
1284 int flags_eks,flags_enh,flags_dfh,i;
1285 t_fileio *ret;
1287 if (PAR(cr))
1289 if (DOMAINDECOMP(cr))
1291 nppnodes = cr->dd->nnodes;
1292 npmenodes = cr->npmenodes;
1294 else
1296 nppnodes = cr->nnodes;
1297 npmenodes = 0;
1300 else
1302 nppnodes = 1;
1303 npmenodes = 0;
1306 /* make the new temporary filename */
1307 snew(fntemp, strlen(fn)+5+STEPSTRSIZE);
1308 strcpy(fntemp,fn);
1309 fntemp[strlen(fn) - strlen(ftp2ext(fn2ftp(fn))) - 1] = '\0';
1310 sprintf(suffix,"_%s%s","step",gmx_step_str(step,sbuf));
1311 strcat(fntemp,suffix);
1312 strcat(fntemp,fn+strlen(fn) - strlen(ftp2ext(fn2ftp(fn))) - 1);
1314 time(&now);
1315 gmx_ctime_r(&now,timebuf,STRLEN);
1317 if (fplog)
1319 fprintf(fplog,"Writing checkpoint, step %s at %s\n\n",
1320 gmx_step_str(step,buf),timebuf);
1323 /* Get offsets for open files */
1324 gmx_fio_get_output_file_positions(&outputfiles, &noutputfiles);
1326 fp = gmx_fio_open(fntemp,"w");
1328 if (state->ekinstate.bUpToDate)
1330 flags_eks =
1331 ((1<<eeksEKIN_N) | (1<<eeksEKINH) | (1<<eeksEKINF) |
1332 (1<<eeksEKINO) | (1<<eeksEKINSCALEF) | (1<<eeksEKINSCALEH) |
1333 (1<<eeksVSCALE) | (1<<eeksDEKINDL) | (1<<eeksMVCOS));
1335 else
1337 flags_eks = 0;
1340 flags_enh = 0;
1341 if (state->enerhist.nsum > 0 || state->enerhist.nsum_sim > 0)
1343 flags_enh |= (1<<eenhENERGY_N);
1344 if (state->enerhist.nsum > 0)
1346 flags_enh |= ((1<<eenhENERGY_AVER) | (1<<eenhENERGY_SUM) |
1347 (1<<eenhENERGY_NSTEPS) | (1<<eenhENERGY_NSUM));
1349 if (state->enerhist.nsum_sim > 0)
1351 flags_enh |= ((1<<eenhENERGY_SUM_SIM) | (1<<eenhENERGY_NSTEPS_SIM) |
1352 (1<<eenhENERGY_NSUM_SIM));
1354 if (state->enerhist.dht)
1356 flags_enh |= ( (1<< eenhENERGY_DELTA_H_NN) |
1357 (1<< eenhENERGY_DELTA_H_LIST) |
1358 (1<< eenhENERGY_DELTA_H_STARTTIME) |
1359 (1<< eenhENERGY_DELTA_H_STARTLAMBDA) );
1363 if (bExpanded)
1365 flags_dfh = ((1<<edfhBEQUIL) | (1<<edfhNATLAMBDA) | (1<<edfhSUMWEIGHTS) | (1<<edfhSUMDG) |
1366 (1<<edfhTIJ) | (1<<edfhTIJEMP));
1367 if (EWL(elamstats))
1369 flags_dfh |= ((1<<edfhWLDELTA) | (1<<edfhWLHISTO));
1371 if ((elamstats == elamstatsMINVAR) || (elamstats == elamstatsBARKER) || (elamstats == elamstatsMETROPOLIS))
1373 flags_dfh |= ((1<<edfhACCUMP) | (1<<edfhACCUMM) | (1<<edfhACCUMP2) | (1<<edfhACCUMM2)
1374 | (1<<edfhSUMMINVAR) | (1<<edfhSUMVAR));
1376 } else {
1377 flags_dfh = 0;
1380 /* We can check many more things now (CPU, acceleration, etc), but
1381 * it is highly unlikely to have two separate builds with exactly
1382 * the same version, user, time, and build host!
1385 version = gmx_strdup(VERSION);
1386 btime = gmx_strdup(BUILD_TIME);
1387 buser = gmx_strdup(BUILD_USER);
1388 bhost = gmx_strdup(BUILD_HOST);
1390 double_prec = GMX_CPT_BUILD_DP;
1391 fprog = gmx_strdup(Program());
1393 ftime = &(timebuf[0]);
1395 do_cpt_header(gmx_fio_getxdr(fp),FALSE,&file_version,
1396 &version,&btime,&buser,&bhost,&double_prec,&fprog,&ftime,
1397 &eIntegrator,&simulation_part,&step,&t,&nppnodes,
1398 DOMAINDECOMP(cr) ? cr->dd->nc : NULL,&npmenodes,
1399 &state->natoms,&state->ngtc,&state->nnhpres,
1400 &state->nhchainlength,&(state->dfhist.nlambda),&state->flags,&flags_eks,&flags_enh,&flags_dfh,
1401 NULL);
1403 sfree(version);
1404 sfree(btime);
1405 sfree(buser);
1406 sfree(bhost);
1407 sfree(fprog);
1409 if((do_cpt_state(gmx_fio_getxdr(fp),FALSE,state->flags,state,TRUE,NULL) < 0) ||
1410 (do_cpt_ekinstate(gmx_fio_getxdr(fp),FALSE,flags_eks,&state->ekinstate,NULL) < 0)||
1411 (do_cpt_enerhist(gmx_fio_getxdr(fp),FALSE,flags_enh,&state->enerhist,NULL) < 0) ||
1412 (do_cpt_df_hist(gmx_fio_getxdr(fp),FALSE,flags_dfh,&state->dfhist,NULL) < 0) ||
1413 (do_cpt_files(gmx_fio_getxdr(fp),FALSE,&outputfiles,&noutputfiles,NULL,
1414 file_version) < 0))
1416 gmx_file("Cannot read/write checkpoint; corrupt file, or maybe you are out of disk space?");
1419 do_cpt_footer(gmx_fio_getxdr(fp),FALSE,file_version);
1421 /* we really, REALLY, want to make sure to physically write the checkpoint,
1422 and all the files it depends on, out to disk. Because we've
1423 opened the checkpoint with gmx_fio_open(), it's in our list
1424 of open files. */
1425 ret=gmx_fio_all_output_fsync();
1427 if (ret)
1429 char buf[STRLEN];
1430 sprintf(buf,
1431 "Cannot fsync '%s'; maybe you are out of disk space?",
1432 gmx_fio_getname(ret));
1434 if (getenv(GMX_IGNORE_FSYNC_FAILURE_ENV)==NULL)
1436 gmx_file(buf);
1438 else
1440 gmx_warning(buf);
1444 if( gmx_fio_close(fp) != 0)
1446 gmx_file("Cannot read/write checkpoint; corrupt file, or maybe you are out of disk space?");
1449 /* we don't move the checkpoint if the user specified they didn't want it,
1450 or if the fsyncs failed */
1451 if (!bNumberAndKeep && !ret)
1453 if (gmx_fexist(fn))
1455 /* Rename the previous checkpoint file */
1456 strcpy(buf,fn);
1457 buf[strlen(fn) - strlen(ftp2ext(fn2ftp(fn))) - 1] = '\0';
1458 strcat(buf,"_prev");
1459 strcat(buf,fn+strlen(fn) - strlen(ftp2ext(fn2ftp(fn))) - 1);
1460 #ifndef GMX_FAHCORE
1461 /* we copy here so that if something goes wrong between now and
1462 * the rename below, there's always a state.cpt.
1463 * If renames are atomic (such as in POSIX systems),
1464 * this copying should be unneccesary.
1466 gmx_file_copy(fn, buf, FALSE);
1467 /* We don't really care if this fails:
1468 * there's already a new checkpoint.
1470 #else
1471 gmx_file_rename(fn, buf);
1472 #endif
1474 if (gmx_file_rename(fntemp, fn) != 0)
1476 gmx_file("Cannot rename checkpoint file; maybe you are out of disk space?");
1480 sfree(outputfiles);
1481 sfree(fntemp);
1483 #ifdef GMX_FAHCORE
1484 /*code for alternate checkpointing scheme. moved from top of loop over
1485 steps */
1486 fcRequestCheckPoint();
1487 if ( fcCheckPointParallel( cr->nodeid, NULL,0) == 0 ) {
1488 gmx_fatal( 3,__FILE__,__LINE__, "Checkpoint error on step %d\n", step );
1490 #endif /* end GMX_FAHCORE block */
1493 static void print_flag_mismatch(FILE *fplog,int sflags,int fflags)
1495 int i;
1497 fprintf(fplog,"\nState entry mismatch between the simulation and the checkpoint file\n");
1498 fprintf(fplog,"Entries which are not present in the checkpoint file will not be updated\n");
1499 fprintf(fplog," %24s %11s %11s\n","","simulation","checkpoint");
1500 for(i=0; i<estNR; i++)
1502 if ((sflags & (1<<i)) || (fflags & (1<<i)))
1504 fprintf(fplog," %24s %11s %11s\n",
1505 est_names[i],
1506 (sflags & (1<<i)) ? " present " : "not present",
1507 (fflags & (1<<i)) ? " present " : "not present");
1512 static void check_int(FILE *fplog,const char *type,int p,int f,gmx_bool *mm)
1514 FILE *fp = fplog ? fplog : stderr;
1516 if (p != f)
1518 fprintf(fp," %s mismatch,\n",type);
1519 fprintf(fp," current program: %d\n",p);
1520 fprintf(fp," checkpoint file: %d\n",f);
1521 fprintf(fp,"\n");
1522 *mm = TRUE;
1526 static void check_string(FILE *fplog,const char *type,const char *p,
1527 const char *f,gmx_bool *mm)
1529 FILE *fp = fplog ? fplog : stderr;
1531 if (strcmp(p,f) != 0)
1533 fprintf(fp," %s mismatch,\n",type);
1534 fprintf(fp," current program: %s\n",p);
1535 fprintf(fp," checkpoint file: %s\n",f);
1536 fprintf(fp,"\n");
1537 *mm = TRUE;
1541 static void check_match(FILE *fplog,
1542 char *version,
1543 char *btime,char *buser,char *bhost,int double_prec,
1544 char *fprog,
1545 t_commrec *cr,gmx_bool bPartDecomp,int npp_f,int npme_f,
1546 ivec dd_nc,ivec dd_nc_f)
1548 int npp;
1549 gmx_bool mm;
1551 mm = FALSE;
1553 check_string(fplog,"Version" ,VERSION ,version,&mm);
1554 check_string(fplog,"Build time" ,BUILD_TIME ,btime ,&mm);
1555 check_string(fplog,"Build user" ,BUILD_USER ,buser ,&mm);
1556 check_string(fplog,"Build host" ,BUILD_HOST ,bhost ,&mm);
1557 check_int (fplog,"Double prec." ,GMX_CPT_BUILD_DP,double_prec,&mm);
1558 check_string(fplog,"Program name" ,Program() ,fprog ,&mm);
1560 check_int (fplog,"#nodes" ,cr->nnodes ,npp_f+npme_f ,&mm);
1561 if (bPartDecomp)
1563 dd_nc[XX] = 1;
1564 dd_nc[YY] = 1;
1565 dd_nc[ZZ] = 1;
1567 if (cr->nnodes > 1)
1569 check_int (fplog,"#PME-nodes" ,cr->npmenodes,npme_f ,&mm);
1571 npp = cr->nnodes;
1572 if (cr->npmenodes >= 0)
1574 npp -= cr->npmenodes;
1576 if (npp == npp_f)
1578 check_int (fplog,"#DD-cells[x]",dd_nc[XX] ,dd_nc_f[XX],&mm);
1579 check_int (fplog,"#DD-cells[y]",dd_nc[YY] ,dd_nc_f[YY],&mm);
1580 check_int (fplog,"#DD-cells[z]",dd_nc[ZZ] ,dd_nc_f[ZZ],&mm);
1584 if (mm)
1586 fprintf(stderr,
1587 "Gromacs binary or parallel settings not identical to previous run.\n"
1588 "Continuation is exact, but is not guaranteed to be binary identical%s.\n\n",
1589 fplog ? ",\n see the log file for details" : "");
1591 if (fplog)
1593 fprintf(fplog,
1594 "Gromacs binary or parallel settings not identical to previous run.\n"
1595 "Continuation is exact, but is not guaranteed to be binary identical.\n\n");
1600 static void read_checkpoint(const char *fn,FILE **pfplog,
1601 t_commrec *cr,gmx_bool bPartDecomp,ivec dd_nc,
1602 int eIntegrator, int *init_fep_state, gmx_large_int_t *step,double *t,
1603 t_state *state,gmx_bool *bReadRNG,gmx_bool *bReadEkin,
1604 int *simulation_part,
1605 gmx_bool bAppendOutputFiles,gmx_bool bForceAppend)
1607 t_fileio *fp;
1608 int i,j,rc;
1609 int file_version;
1610 char *version,*btime,*buser,*bhost,*fprog,*ftime;
1611 int double_prec;
1612 char filename[STRLEN],buf[STEPSTRSIZE];
1613 int nppnodes,eIntegrator_f,nppnodes_f,npmenodes_f;
1614 ivec dd_nc_f;
1615 int natoms,ngtc,nnhpres,nhchainlength,nlambda,fflags,flags_eks,flags_enh,flags_dfh;
1616 int d;
1617 int ret;
1618 gmx_file_position_t *outputfiles;
1619 int nfiles;
1620 t_fileio *chksum_file;
1621 FILE* fplog = *pfplog;
1622 unsigned char digest[16];
1623 #ifndef GMX_NATIVE_WINDOWS
1624 struct flock fl; /* don't initialize here: the struct order is OS
1625 dependent! */
1626 #endif
1628 const char *int_warn=
1629 "WARNING: The checkpoint file was generated with integrator %s,\n"
1630 " while the simulation uses integrator %s\n\n";
1631 const char *sd_note=
1632 "NOTE: The checkpoint file was for %d nodes doing SD or BD,\n"
1633 " while the simulation uses %d SD or BD nodes,\n"
1634 " continuation will be exact, except for the random state\n\n";
1636 #ifndef GMX_NATIVE_WINDOWS
1637 fl.l_type=F_WRLCK;
1638 fl.l_whence=SEEK_SET;
1639 fl.l_start=0;
1640 fl.l_len=0;
1641 fl.l_pid=0;
1642 #endif
1644 if (PARTDECOMP(cr))
1646 gmx_fatal(FARGS,
1647 "read_checkpoint not (yet) supported with particle decomposition");
1650 fp = gmx_fio_open(fn,"r");
1651 do_cpt_header(gmx_fio_getxdr(fp),TRUE,&file_version,
1652 &version,&btime,&buser,&bhost,&double_prec,&fprog,&ftime,
1653 &eIntegrator_f,simulation_part,step,t,
1654 &nppnodes_f,dd_nc_f,&npmenodes_f,
1655 &natoms,&ngtc,&nnhpres,&nhchainlength,&nlambda,
1656 &fflags,&flags_eks,&flags_enh,&flags_dfh,NULL);
1658 if (bAppendOutputFiles &&
1659 file_version >= 13 && double_prec != GMX_CPT_BUILD_DP)
1661 gmx_fatal(FARGS,"Output file appending requested, but the code and checkpoint file precision (single/double) don't match");
1664 if (cr == NULL || MASTER(cr))
1666 fprintf(stderr,"\nReading checkpoint file %s generated: %s\n\n",
1667 fn,ftime);
1670 /* This will not be written if we do appending, since fplog is still NULL then */
1671 if (fplog)
1673 fprintf(fplog,"\n");
1674 fprintf(fplog,"Reading checkpoint file %s\n",fn);
1675 fprintf(fplog," file generated by: %s\n",fprog);
1676 fprintf(fplog," file generated at: %s\n",ftime);
1677 fprintf(fplog," GROMACS build time: %s\n",btime);
1678 fprintf(fplog," GROMACS build user: %s\n",buser);
1679 fprintf(fplog," GROMACS build host: %s\n",bhost);
1680 fprintf(fplog," GROMACS double prec.: %d\n",double_prec);
1681 fprintf(fplog," simulation part #: %d\n",*simulation_part);
1682 fprintf(fplog," step: %s\n",gmx_step_str(*step,buf));
1683 fprintf(fplog," time: %f\n",*t);
1684 fprintf(fplog,"\n");
1687 if (natoms != state->natoms)
1689 gmx_fatal(FARGS,"Checkpoint file is for a system of %d atoms, while the current system consists of %d atoms",natoms,state->natoms);
1691 if (ngtc != state->ngtc)
1693 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 if (nnhpres != state->nnhpres)
1697 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);
1700 if (nlambda != state->dfhist.nlambda)
1702 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);
1705 init_gtc_state(state,state->ngtc,state->nnhpres,nhchainlength); /* need to keep this here to keep the tpr format working */
1706 /* write over whatever was read; we use the number of Nose-Hoover chains from the checkpoint */
1708 if (eIntegrator_f != eIntegrator)
1710 if (MASTER(cr))
1712 fprintf(stderr,int_warn,EI(eIntegrator_f),EI(eIntegrator));
1714 if(bAppendOutputFiles)
1716 gmx_fatal(FARGS,
1717 "Output file appending requested, but input/checkpoint integrators do not match.\n"
1718 "Stopping the run to prevent you from ruining all your data...\n"
1719 "If you _really_ know what you are doing, try with the -noappend option.\n");
1721 if (fplog)
1723 fprintf(fplog,int_warn,EI(eIntegrator_f),EI(eIntegrator));
1727 if (!PAR(cr))
1729 nppnodes = 1;
1730 cr->npmenodes = 0;
1732 else if (bPartDecomp)
1734 nppnodes = cr->nnodes;
1735 cr->npmenodes = 0;
1737 else if (cr->nnodes == nppnodes_f + npmenodes_f)
1739 if (cr->npmenodes < 0)
1741 cr->npmenodes = npmenodes_f;
1743 nppnodes = cr->nnodes - cr->npmenodes;
1744 if (nppnodes == nppnodes_f)
1746 for(d=0; d<DIM; d++)
1748 if (dd_nc[d] == 0)
1750 dd_nc[d] = dd_nc_f[d];
1755 else
1757 /* The number of PP nodes has not been set yet */
1758 nppnodes = -1;
1761 if ((EI_SD(eIntegrator) || eIntegrator == eiBD) && nppnodes > 0)
1763 /* Correct the RNG state size for the number of PP nodes.
1764 * Such assignments should all be moved to one central function.
1766 state->nrng = nppnodes*gmx_rng_n();
1767 state->nrngi = nppnodes;
1770 *bReadRNG = TRUE;
1771 if (fflags != state->flags)
1774 if (MASTER(cr))
1776 if(bAppendOutputFiles)
1778 gmx_fatal(FARGS,
1779 "Output file appending requested, but input and checkpoint states are not identical.\n"
1780 "Stopping the run to prevent you from ruining all your data...\n"
1781 "You can try with the -noappend option, and get more info in the log file.\n");
1784 if (getenv("GMX_ALLOW_CPT_MISMATCH") == NULL)
1786 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 else
1790 fprintf(stderr,
1791 "WARNING: The checkpoint state entries do not match the simulation,\n"
1792 " see the log file for details\n\n");
1796 if(fplog)
1798 print_flag_mismatch(fplog,state->flags,fflags);
1801 else
1803 if ((EI_SD(eIntegrator) || eIntegrator == eiBD) &&
1804 nppnodes != nppnodes_f)
1806 *bReadRNG = FALSE;
1807 if (MASTER(cr))
1809 fprintf(stderr,sd_note,nppnodes_f,nppnodes);
1811 if (fplog)
1813 fprintf(fplog ,sd_note,nppnodes_f,nppnodes);
1816 if (MASTER(cr))
1818 check_match(fplog,version,btime,buser,bhost,double_prec,fprog,
1819 cr,bPartDecomp,nppnodes_f,npmenodes_f,dd_nc,dd_nc_f);
1822 ret = do_cpt_state(gmx_fio_getxdr(fp),TRUE,fflags,state,*bReadRNG,NULL);
1823 *init_fep_state = state->fep_state; /* there should be a better way to do this than setting it here.
1824 Investigate for 5.0. */
1825 if (ret)
1827 cp_error();
1829 ret = do_cpt_ekinstate(gmx_fio_getxdr(fp),TRUE,
1830 flags_eks,&state->ekinstate,NULL);
1831 if (ret)
1833 cp_error();
1835 *bReadEkin = ((flags_eks & (1<<eeksEKINH)) || (flags_eks & (1<<eeksEKINF)) || (flags_eks & (1<<eeksEKINO)) ||
1836 ((flags_eks & (1<<eeksEKINSCALEF)) | (flags_eks & (1<<eeksEKINSCALEH)) | (flags_eks & (1<<eeksVSCALE))));
1838 ret = do_cpt_enerhist(gmx_fio_getxdr(fp),TRUE,
1839 flags_enh,&state->enerhist,NULL);
1840 if (ret)
1842 cp_error();
1845 if (file_version < 6)
1847 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 fprintf(stderr,"\nWARNING: %s\n\n",warn);
1850 if (fplog)
1852 fprintf(fplog,"\nWARNING: %s\n\n",warn);
1854 state->enerhist.nsum = *step;
1855 state->enerhist.nsum_sim = *step;
1858 ret = do_cpt_df_hist(gmx_fio_getxdr(fp),TRUE,
1859 flags_dfh,&state->dfhist,NULL);
1860 if (ret)
1862 cp_error();
1865 ret = do_cpt_files(gmx_fio_getxdr(fp),TRUE,&outputfiles,&nfiles,NULL,file_version);
1866 if (ret)
1868 cp_error();
1871 ret = do_cpt_footer(gmx_fio_getxdr(fp),TRUE,file_version);
1872 if (ret)
1874 cp_error();
1876 if( gmx_fio_close(fp) != 0)
1878 gmx_file("Cannot read/write checkpoint; corrupt file, or maybe you are out of disk space?");
1881 sfree(fprog);
1882 sfree(ftime);
1883 sfree(btime);
1884 sfree(buser);
1885 sfree(bhost);
1887 /* If the user wants to append to output files,
1888 * we use the file pointer positions of the output files stored
1889 * in the checkpoint file and truncate the files such that any frames
1890 * written after the checkpoint time are removed.
1891 * All files are md5sum checked such that we can be sure that
1892 * we do not truncate other (maybe imprortant) files.
1894 if (bAppendOutputFiles)
1896 if (fn2ftp(outputfiles[0].filename)!=efLOG)
1898 /* make sure first file is log file so that it is OK to use it for
1899 * locking
1901 gmx_fatal(FARGS,"The first output file should always be the log "
1902 "file but instead is: %s. Cannot do appending because of this condition.", outputfiles[0].filename);
1904 for(i=0;i<nfiles;i++)
1906 if (outputfiles[i].offset < 0)
1908 gmx_fatal(FARGS,"The original run wrote a file called '%s' which "
1909 "is larger than 2 GB, but mdrun did not support large file"
1910 " offsets. Can not append. Run mdrun with -noappend",
1911 outputfiles[i].filename);
1913 #ifdef GMX_FAHCORE
1914 chksum_file=gmx_fio_open(outputfiles[i].filename,"a");
1916 #else
1917 chksum_file=gmx_fio_open(outputfiles[i].filename,"r+");
1919 /* lock log file */
1920 if (i==0)
1922 /* Note that there are systems where the lock operation
1923 * will succeed, but a second process can also lock the file.
1924 * We should probably try to detect this.
1926 #ifndef GMX_NATIVE_WINDOWS
1927 if (fcntl(fileno(gmx_fio_getfp(chksum_file)), F_SETLK, &fl)
1928 ==-1)
1929 #else
1930 if (_locking(fileno(gmx_fio_getfp(chksum_file)), _LK_NBLCK, LONG_MAX)==-1)
1931 #endif
1933 if (errno == ENOSYS)
1935 if (!bForceAppend)
1937 gmx_fatal(FARGS,"File locking is not supported on this system. Use -noappend or specify -append explicitly to append anyhow.");
1939 else
1941 fprintf(stderr,"\nNOTE: File locking is not supported on this system, will not lock %s\n\n",outputfiles[i].filename);
1942 if (fplog)
1944 fprintf(fplog,"\nNOTE: File locking not supported on this system, will not lock %s\n\n",outputfiles[i].filename);
1948 else if (errno == EACCES || errno == EAGAIN)
1950 gmx_fatal(FARGS,"Failed to lock: %s. Already running "
1951 "simulation?", outputfiles[i].filename);
1953 else
1955 gmx_fatal(FARGS,"Failed to lock: %s. %s.",
1956 outputfiles[i].filename, strerror(errno));
1961 /* compute md5 chksum */
1962 if (outputfiles[i].chksum_size != -1)
1964 if (gmx_fio_get_file_md5(chksum_file,outputfiles[i].offset,
1965 digest) != outputfiles[i].chksum_size) /*at the end of the call the file position is at the end of the file*/
1967 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.",
1968 outputfiles[i].chksum_size,
1969 outputfiles[i].filename);
1972 if (i==0) /*log file needs to be seeked in case we need to truncate (other files are truncated below)*/
1974 if (gmx_fio_seek(chksum_file,outputfiles[i].offset))
1976 gmx_fatal(FARGS,"Seek error! Failed to truncate log-file: %s.", strerror(errno));
1979 #endif
1981 if (i==0) /*open log file here - so that lock is never lifted
1982 after chksum is calculated */
1984 *pfplog = gmx_fio_getfp(chksum_file);
1986 else
1988 gmx_fio_close(chksum_file);
1990 #ifndef GMX_FAHCORE
1991 /* compare md5 chksum */
1992 if (outputfiles[i].chksum_size != -1 &&
1993 memcmp(digest,outputfiles[i].chksum,16)!=0)
1995 if (debug)
1997 fprintf(debug,"chksum for %s: ",outputfiles[i].filename);
1998 for (j=0; j<16; j++)
2000 fprintf(debug,"%02x",digest[j]);
2002 fprintf(debug,"\n");
2004 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.",
2005 outputfiles[i].filename);
2007 #endif
2010 if (i!=0) /*log file is already seeked to correct position */
2012 #ifdef GMX_NATIVE_WINDOWS
2013 rc = gmx_wintruncate(outputfiles[i].filename,outputfiles[i].offset);
2014 #else
2015 rc = truncate(outputfiles[i].filename,outputfiles[i].offset);
2016 #endif
2017 if(rc!=0)
2019 gmx_fatal(FARGS,"Truncation of file %s failed. Cannot do appending because of this failure.",outputfiles[i].filename);
2025 sfree(outputfiles);
2029 void load_checkpoint(const char *fn,FILE **fplog,
2030 t_commrec *cr,gmx_bool bPartDecomp,ivec dd_nc,
2031 t_inputrec *ir,t_state *state,
2032 gmx_bool *bReadRNG,gmx_bool *bReadEkin,
2033 gmx_bool bAppend,gmx_bool bForceAppend)
2035 gmx_large_int_t step;
2036 double t;
2038 if (SIMMASTER(cr)) {
2039 /* Read the state from the checkpoint file */
2040 read_checkpoint(fn,fplog,
2041 cr,bPartDecomp,dd_nc,
2042 ir->eI,&(ir->fepvals->init_fep_state),&step,&t,state,bReadRNG,bReadEkin,
2043 &ir->simulation_part,bAppend,bForceAppend);
2045 if (PAR(cr)) {
2046 gmx_bcast(sizeof(cr->npmenodes),&cr->npmenodes,cr);
2047 gmx_bcast(DIM*sizeof(dd_nc[0]),dd_nc,cr);
2048 gmx_bcast(sizeof(step),&step,cr);
2049 gmx_bcast(sizeof(*bReadRNG),bReadRNG,cr);
2050 gmx_bcast(sizeof(*bReadEkin),bReadEkin,cr);
2052 ir->bContinuation = TRUE;
2053 if (ir->nsteps >= 0)
2055 ir->nsteps += ir->init_step - step;
2057 ir->init_step = step;
2058 ir->simulation_part += 1;
2061 static void read_checkpoint_data(t_fileio *fp,int *simulation_part,
2062 gmx_large_int_t *step,double *t,t_state *state,
2063 gmx_bool bReadRNG,
2064 int *nfiles,gmx_file_position_t **outputfiles)
2066 int file_version;
2067 char *version,*btime,*buser,*bhost,*fprog,*ftime;
2068 int double_prec;
2069 int eIntegrator;
2070 int nppnodes,npme;
2071 ivec dd_nc;
2072 int flags_eks,flags_enh,flags_dfh;
2073 int nfiles_loc;
2074 gmx_file_position_t *files_loc=NULL;
2075 int ret;
2077 do_cpt_header(gmx_fio_getxdr(fp),TRUE,&file_version,
2078 &version,&btime,&buser,&bhost,&double_prec,&fprog,&ftime,
2079 &eIntegrator,simulation_part,step,t,&nppnodes,dd_nc,&npme,
2080 &state->natoms,&state->ngtc,&state->nnhpres,&state->nhchainlength,
2081 &(state->dfhist.nlambda),&state->flags,&flags_eks,&flags_enh,&flags_dfh,NULL);
2082 ret =
2083 do_cpt_state(gmx_fio_getxdr(fp),TRUE,state->flags,state,bReadRNG,NULL);
2084 if (ret)
2086 cp_error();
2088 ret = do_cpt_ekinstate(gmx_fio_getxdr(fp),TRUE,
2089 flags_eks,&state->ekinstate,NULL);
2090 if (ret)
2092 cp_error();
2094 ret = do_cpt_enerhist(gmx_fio_getxdr(fp),TRUE,
2095 flags_enh,&state->enerhist,NULL);
2096 if (ret)
2098 cp_error();
2100 ret = do_cpt_df_hist(gmx_fio_getxdr(fp),TRUE,
2101 flags_dfh,&state->dfhist,NULL);
2102 if (ret)
2104 cp_error();
2107 ret = do_cpt_files(gmx_fio_getxdr(fp),TRUE,
2108 outputfiles != NULL ? outputfiles : &files_loc,
2109 outputfiles != NULL ? nfiles : &nfiles_loc,
2110 NULL,file_version);
2111 if (files_loc != NULL)
2113 sfree(files_loc);
2116 if (ret)
2118 cp_error();
2121 ret = do_cpt_footer(gmx_fio_getxdr(fp),TRUE,file_version);
2122 if (ret)
2124 cp_error();
2127 sfree(fprog);
2128 sfree(ftime);
2129 sfree(btime);
2130 sfree(buser);
2131 sfree(bhost);
2134 void
2135 read_checkpoint_state(const char *fn,int *simulation_part,
2136 gmx_large_int_t *step,double *t,t_state *state)
2138 t_fileio *fp;
2140 fp = gmx_fio_open(fn,"r");
2141 read_checkpoint_data(fp,simulation_part,step,t,state,FALSE,NULL,NULL);
2142 if( gmx_fio_close(fp) != 0)
2144 gmx_file("Cannot read/write checkpoint; corrupt file, or maybe you are out of disk space?");
2148 void read_checkpoint_trxframe(t_fileio *fp,t_trxframe *fr)
2150 t_state state;
2151 int simulation_part;
2152 gmx_large_int_t step;
2153 double t;
2155 init_state(&state,0,0,0,0,0);
2157 read_checkpoint_data(fp,&simulation_part,&step,&t,&state,FALSE,NULL,NULL);
2159 fr->natoms = state.natoms;
2160 fr->bTitle = FALSE;
2161 fr->bStep = TRUE;
2162 fr->step = gmx_large_int_to_int(step,
2163 "conversion of checkpoint to trajectory");
2164 fr->bTime = TRUE;
2165 fr->time = t;
2166 fr->bLambda = TRUE;
2167 fr->lambda = state.lambda[efptFEP];
2168 fr->fep_state = state.fep_state;
2169 fr->bAtoms = FALSE;
2170 fr->bX = (state.flags & (1<<estX));
2171 if (fr->bX)
2173 fr->x = state.x;
2174 state.x = NULL;
2176 fr->bV = (state.flags & (1<<estV));
2177 if (fr->bV)
2179 fr->v = state.v;
2180 state.v = NULL;
2182 fr->bF = FALSE;
2183 fr->bBox = (state.flags & (1<<estBOX));
2184 if (fr->bBox)
2186 copy_mat(state.box,fr->box);
2188 done_state(&state);
2191 void list_checkpoint(const char *fn,FILE *out)
2193 t_fileio *fp;
2194 int file_version;
2195 char *version,*btime,*buser,*bhost,*fprog,*ftime;
2196 int double_prec;
2197 int eIntegrator,simulation_part,nppnodes,npme;
2198 gmx_large_int_t step;
2199 double t;
2200 ivec dd_nc;
2201 t_state state;
2202 int flags_eks,flags_enh,flags_dfh;
2203 int indent;
2204 int i,j;
2205 int ret;
2206 gmx_file_position_t *outputfiles;
2207 int nfiles;
2209 init_state(&state,-1,-1,-1,-1,0);
2211 fp = gmx_fio_open(fn,"r");
2212 do_cpt_header(gmx_fio_getxdr(fp),TRUE,&file_version,
2213 &version,&btime,&buser,&bhost,&double_prec,&fprog,&ftime,
2214 &eIntegrator,&simulation_part,&step,&t,&nppnodes,dd_nc,&npme,
2215 &state.natoms,&state.ngtc,&state.nnhpres,&state.nhchainlength,
2216 &(state.dfhist.nlambda),&state.flags,
2217 &flags_eks,&flags_enh,&flags_dfh,out);
2218 ret = do_cpt_state(gmx_fio_getxdr(fp),TRUE,state.flags,&state,TRUE,out);
2219 if (ret)
2221 cp_error();
2223 ret = do_cpt_ekinstate(gmx_fio_getxdr(fp),TRUE,
2224 flags_eks,&state.ekinstate,out);
2225 if (ret)
2227 cp_error();
2229 ret = do_cpt_enerhist(gmx_fio_getxdr(fp),TRUE,
2230 flags_enh,&state.enerhist,out);
2232 if (ret == 0)
2234 init_df_history(&state.dfhist,state.dfhist.nlambda,0); /* reinitialize state with correct sizes */
2235 ret = do_cpt_df_hist(gmx_fio_getxdr(fp),TRUE,
2236 flags_dfh,&state.dfhist,out);
2238 if (ret == 0)
2240 do_cpt_files(gmx_fio_getxdr(fp),TRUE,&outputfiles,&nfiles,out,file_version);
2243 if (ret == 0)
2245 ret = do_cpt_footer(gmx_fio_getxdr(fp),TRUE,file_version);
2248 if (ret)
2250 cp_warning(out);
2252 if( gmx_fio_close(fp) != 0)
2254 gmx_file("Cannot read/write checkpoint; corrupt file, or maybe you are out of disk space?");
2257 done_state(&state);
2261 static gmx_bool exist_output_file(const char *fnm_cp,int nfile,const t_filenm fnm[])
2263 int i;
2265 /* Check if the output file name stored in the checkpoint file
2266 * is one of the output file names of mdrun.
2268 i = 0;
2269 while (i < nfile &&
2270 !(is_output(&fnm[i]) && strcmp(fnm_cp,fnm[i].fns[0]) == 0))
2272 i++;
2275 return (i < nfile && gmx_fexist(fnm_cp));
2278 /* This routine cannot print tons of data, since it is called before the log file is opened. */
2279 gmx_bool read_checkpoint_simulation_part(const char *filename, int *simulation_part,
2280 gmx_large_int_t *cpt_step,t_commrec *cr,
2281 gmx_bool bAppendReq,
2282 int nfile,const t_filenm fnm[],
2283 const char *part_suffix,gmx_bool *bAddPart)
2285 t_fileio *fp;
2286 gmx_large_int_t step=0;
2287 double t;
2288 t_state state;
2289 int nfiles;
2290 gmx_file_position_t *outputfiles;
2291 int nexist,f;
2292 gmx_bool bAppend;
2293 char *fn,suf_up[STRLEN];
2295 bAppend = FALSE;
2297 if (SIMMASTER(cr)) {
2298 if(!gmx_fexist(filename) || (!(fp = gmx_fio_open(filename,"r")) ))
2300 *simulation_part = 0;
2302 else
2304 init_state(&state,0,0,0,0,0);
2306 read_checkpoint_data(fp,simulation_part,&step,&t,&state,FALSE,
2307 &nfiles,&outputfiles);
2308 if( gmx_fio_close(fp) != 0)
2310 gmx_file("Cannot read/write checkpoint; corrupt file, or maybe you are out of disk space?");
2312 done_state(&state);
2314 if (bAppendReq)
2316 nexist = 0;
2317 for(f=0; f<nfiles; f++)
2319 if (exist_output_file(outputfiles[f].filename,nfile,fnm))
2321 nexist++;
2324 if (nexist == nfiles)
2326 bAppend = bAppendReq;
2328 else if (nexist > 0)
2330 fprintf(stderr,
2331 "Output file appending has been requested,\n"
2332 "but some output files listed in the checkpoint file %s\n"
2333 "are not present or are named differently by the current program:\n",
2334 filename);
2335 fprintf(stderr,"output files present:");
2336 for(f=0; f<nfiles; f++)
2338 if (exist_output_file(outputfiles[f].filename,
2339 nfile,fnm))
2341 fprintf(stderr," %s",outputfiles[f].filename);
2344 fprintf(stderr,"\n");
2345 fprintf(stderr,"output files not present or named differently:");
2346 for(f=0; f<nfiles; f++)
2348 if (!exist_output_file(outputfiles[f].filename,
2349 nfile,fnm))
2351 fprintf(stderr," %s",outputfiles[f].filename);
2354 fprintf(stderr,"\n");
2356 gmx_fatal(FARGS,"File appending requested, but only %d of the %d output files are present",nexist,nfiles);
2360 if (bAppend)
2362 if (nfiles == 0)
2364 gmx_fatal(FARGS,"File appending requested, but no output file information is stored in the checkpoint file");
2366 fn = outputfiles[0].filename;
2367 if (strlen(fn) < 4 ||
2368 gmx_strcasecmp(fn+strlen(fn)-4,ftp2ext(efLOG)) == 0)
2370 gmx_fatal(FARGS,"File appending requested, but the log file is not the first file listed in the checkpoint file");
2372 /* Set bAddPart to whether the suffix string '.part' is present
2373 * in the log file name.
2375 strcpy(suf_up,part_suffix);
2376 upstring(suf_up);
2377 *bAddPart = (strstr(fn,part_suffix) != NULL ||
2378 strstr(fn,suf_up) != NULL);
2381 sfree(outputfiles);
2384 if (PAR(cr))
2386 gmx_bcast(sizeof(*simulation_part),simulation_part,cr);
2388 if (*simulation_part > 0 && bAppendReq)
2390 gmx_bcast(sizeof(bAppend),&bAppend,cr);
2391 gmx_bcast(sizeof(*bAddPart),bAddPart,cr);
2394 if (NULL != cpt_step)
2396 *cpt_step = step;
2399 return bAppend;