1 /* -*- mode: c; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; c-file-style: "stroustrup"; -*-
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
16 * Gnomes, ROck Monsters And Chili Sauce
19 /* The source code in this file should be thread-safe.
20 Please keep it that way. */
26 #include "gmx_header_config.h"
31 #ifdef HAVE_SYS_TIME_H
36 #ifdef GMX_NATIVE_WINDOWS
39 #include <sys/locking.h>
53 #include "gmx_random.h"
54 #include "checkpoint.h"
65 /* Portable version of ctime_r implemented in src/gmxlib/string2.c, but we do not want it declared in public installed headers */
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
75 #define GMX_CPT_BUILD_DP 1
77 #define GMX_CPT_BUILD_DP 0
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
]=
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
,
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",
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
140 gmx_wintruncate(const char *filename
, __int64 size
)
143 /*we do this elsewhere*/
149 fp
=fopen(filename
,"rb+");
156 return _chsize_s( fileno(fp
), size
);
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
)
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;
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
)
204 res
= xdr_string(xd
,s
,CPTSTRLEN
);
211 fprintf(list
,"%s = %s\n",desc
,*s
);
216 static int do_cpt_int(XDR
*xd
,const char *desc
,int *i
,FILE *list
)
227 fprintf(list
,"%s = %d\n",desc
,*i
);
232 static int do_cpt_u_chars(XDR
*xd
,const char *desc
,int n
,unsigned char *i
,FILE *list
)
238 fprintf(list
,"%s = ",desc
);
240 for (j
=0; j
<n
&& res
; j
++)
242 res
&= xdr_u_char(xd
,&i
[j
]);
245 fprintf(list
,"%02x",i
[j
]);
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)
268 static void do_cpt_step_err(XDR
*xd
,const char *desc
,gmx_large_int_t
*i
,FILE *list
)
271 char buf
[STEPSTRSIZE
];
273 res
= xdr_gmx_large_int(xd
,i
,"reading checkpoint file");
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
)
288 res
= xdr_double(xd
,f
);
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
)
308 int dtc
=xdr_datatype_float
;
310 int dtc
=xdr_datatype_double
;
327 gmx_incons("*ntpr=NULL in do_cpte_reals_low");
332 res
= xdr_int(xd
,&nf
);
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
);
352 res
= xdr_int(xd
,&dt
);
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
)))
376 if (dt
== xdr_datatype_float
)
378 if (dtc
== xdr_datatype_float
)
386 res
= xdr_vector(xd
,(char *)vf
,nf
,
387 (unsigned int)sizeof(float),(xdrproc_t
)xdr_float
);
392 if (dtc
!= xdr_datatype_float
)
403 if (dtc
== xdr_datatype_double
)
411 res
= xdr_vector(xd
,(char *)vd
,nf
,
412 (unsigned int)sizeof(double),(xdrproc_t
)xdr_double
);
417 if (dtc
!= xdr_datatype_double
)
432 pr_reals(list
,0,st_names(cptp
,ecpt
),vp
,nf
);
435 pr_rvecs(list
,0,st_names(cptp
,ecpt
),(rvec
*)vp
,nf
/3);
438 gmx_incons("Unknown checkpoint real type");
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
,
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
)
482 int dtc
=xdr_datatype_int
;
487 res
= xdr_int(xd
,&nf
);
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
);
497 res
= xdr_int(xd
,&dt
);
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
)
521 res
= xdr_vector(xd
,(char *)vp
,nf
,
522 (unsigned int)sizeof(int),(xdrproc_t
)xdr_int
);
529 pr_ivec(list
,0,st_names(cptp
,ecpt
),vp
,nf
,TRUE
);
539 static int do_cpte_int(XDR
*xd
,int cptp
,int ecpt
,int sflags
,
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
)
549 int dtc
=xdr_datatype_double
;
554 res
= xdr_int(xd
,&nf
);
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
);
564 res
= xdr_int(xd
,&dt
);
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
)))
588 res
= xdr_vector(xd
,(char *)vp
,nf
,
589 (unsigned int)sizeof(double),(xdrproc_t
)xdr_double
);
596 pr_doubles(list
,0,st_names(cptp
,ecpt
),vp
,nf
);
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
)
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
,
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
);
641 static int do_cpte_nmatrix(XDR
*xd
,int cptp
,int ecpt
,int sflags
,
642 int n
, real
**v
,FILE *list
)
647 char name
[CPTSTRLEN
];
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
);
672 static int do_cpte_matrices(XDR
*xd
,int cptp
,int ecpt
,int sflags
,
673 int n
,matrix
**v
,FILE *list
)
682 res
= xdr_int(xd
,&nf
);
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
)))
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
);
723 vp
[i
][j
][k
] = vr
[(i
*DIM
+j
)*DIM
+k
];
729 if (list
&& ret
== 0)
733 pr_rvecs(list
,0,st_names(cptp
,ecpt
),vp
[i
],DIM
);
744 static void do_cpt_header(XDR
*xd
,gmx_bool bRead
,int *file_version
,
745 char **version
,char **btime
,char **buser
,char **bhost
,
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
,
770 res
= xdr_int(xd
,&magic
);
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",
785 if (gethostname(fhost
,255) != 0)
787 sprintf(fhost
,"unknown");
790 sprintf(fhost
,"unknown");
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
);
813 if (*file_version
>= 12)
815 do_cpt_string_err(xd
,bRead
,"generating host" ,&fhost
,list
);
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
);
831 if (*file_version
>= 11)
833 do_cpt_int_err(xd
,"#Nose-Hoover T-chains for barostat ",nnhpres
,list
);
839 if (*file_version
>= 14)
841 do_cpt_int_err(xd
,"# of total lambda states ",nlambda
,list
);
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
);
854 *simulation_part
= 1;
856 if (*file_version
>= 5)
858 do_cpt_step_err(xd
,"step" ,step
,list
);
862 do_cpt_int_err(xd
,"step" ,&idum
,list
);
865 do_cpt_double_err(xd
,"t" ,t
,list
);
866 do_cpt_int_err(xd
,"#PP-nodes" ,nnodes
,list
);
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
);
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
);
894 static int do_cpt_footer(XDR
*xd
,gmx_bool bRead
,int file_version
)
899 if (file_version
>= 2)
902 res
= xdr_int(xd
,&magic
);
907 if (magic
!= CPT_MAGIC2
)
916 static int do_cpt_state(XDR
*xd
,gmx_bool bRead
,
917 int fflags
,t_state
*state
,
918 gmx_bool bReadRNG
,FILE *list
)
921 int **rng_p
,**rngi_p
;
928 nnht
= state
->nhchainlength
*state
->ngtc
;
929 nnhtp
= state
->nhchainlength
*state
->nnhpres
;
933 rng_p
= (int **)&state
->ld_rng
;
934 rngi_p
= &state
->ld_rngi
;
938 /* Do not read the RNG data */
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
++)
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;
978 gmx_fatal(FARGS
,"Unknown state entry %d\n"
979 "You are probably reading a new checkpoint file with old code",i
);
987 static int do_cpt_ekinstate(XDR
*xd
,gmx_bool bRead
,
988 int fflags
,ekinstate_t
*ekins
,
996 for(i
=0; (i
<eeksNR
&& ret
== 0); 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;
1014 gmx_fatal(FARGS
,"Unknown ekin data state entry %d\n"
1015 "You are probably reading a new checkpoint file with old code",i
);
1024 static int do_cpt_enerhist(XDR
*xd
,gmx_bool bRead
,
1025 int fflags
,energyhistory_t
*enerhist
,
1036 enerhist
->nsteps
= 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
))
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
;
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
);
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;
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
);
1123 static int do_cpt_df_hist(XDR
*xd
,gmx_bool bRead
,int fflags
,df_history_t
*dfhist
,FILE *list
)
1128 nlambda
= dfhist
->nlambda
;
1131 for(i
=0; (i
<edfhNR
&& ret
== 0); i
++)
1133 if (fflags
& (1<<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;
1153 gmx_fatal(FARGS
,"Unknown df history entry %d\n"
1154 "You are probably reading a new checkpoint file with old code",i
);
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
)
1168 gmx_off_t mask
= 0xFFFFFFFFL
;
1169 int offset_high
,offset_low
;
1171 gmx_file_position_t
*outputfiles
;
1173 if (do_cpt_int(xd
,"number of output files",nfiles
,list
) != 0)
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 */
1190 do_cpt_string_err(xd
,bRead
,"output filename",&buf
,list
);
1191 strncpy(outputfiles
[i
].filename
,buf
,CPTSTRLEN
-1);
1197 if (do_cpt_int(xd
,"file_offset_high",&offset_high
,list
) != 0)
1201 if (do_cpt_int(xd
,"file_offset_low",&offset_low
,list
) != 0)
1205 #if (SIZEOF_GMX_OFF_T > 4)
1206 outputfiles
[i
].offset
= ( ((gmx_off_t
) offset_high
) << 32 ) | ( (gmx_off_t
) offset_low
& mask
);
1208 outputfiles
[i
].offset
= offset_low
;
1213 buf
= outputfiles
[i
].filename
;
1214 do_cpt_string_err(xd
,bRead
,"output filename",&buf
,list
);
1216 offset
= outputfiles
[i
].offset
;
1224 #if (SIZEOF_GMX_OFF_T > 4)
1225 offset_low
= (int) (offset
& mask
);
1226 offset_high
= (int) ((offset
>> 32) & mask
);
1228 offset_low
= offset
;
1232 if (do_cpt_int(xd
,"file_offset_high",&offset_high
,list
) != 0)
1236 if (do_cpt_int(xd
,"file_offset_low",&offset_low
,list
) != 0)
1241 if (file_version
>= 8)
1243 if (do_cpt_int(xd
,"file_checksum_size",&(outputfiles
[i
].chksum_size
),
1248 if (do_cpt_u_chars(xd
,"file_checksum",16,outputfiles
[i
].chksum
,list
) != 0)
1255 outputfiles
[i
].chksum_size
= -1;
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
)
1276 char *fntemp
; /* the temporary checkpoint file name */
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
;
1284 int flags_eks
,flags_enh
,flags_dfh
,i
;
1289 if (DOMAINDECOMP(cr
))
1291 nppnodes
= cr
->dd
->nnodes
;
1292 npmenodes
= cr
->npmenodes
;
1296 nppnodes
= cr
->nnodes
;
1306 /* make the new temporary filename */
1307 snew(fntemp
, strlen(fn
)+5+STEPSTRSIZE
);
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);
1315 gmx_ctime_r(&now
,timebuf
,STRLEN
);
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
)
1331 ((1<<eeksEKIN_N
) | (1<<eeksEKINH
) | (1<<eeksEKINF
) |
1332 (1<<eeksEKINO
) | (1<<eeksEKINSCALEF
) | (1<<eeksEKINSCALEH
) |
1333 (1<<eeksVSCALE
) | (1<<eeksDEKINDL
) | (1<<eeksMVCOS
));
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
) );
1365 flags_dfh
= ((1<<edfhBEQUIL
) | (1<<edfhNATLAMBDA
) | (1<<edfhSUMWEIGHTS
) | (1<<edfhSUMDG
) |
1366 (1<<edfhTIJ
) | (1<<edfhTIJEMP
));
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
));
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
,
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
,
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
1425 ret
=gmx_fio_all_output_fsync();
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
)
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
)
1455 /* Rename the previous checkpoint file */
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);
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.
1471 gmx_file_rename(fn
, buf
);
1474 if (gmx_file_rename(fntemp
, fn
) != 0)
1476 gmx_file("Cannot rename checkpoint file; maybe you are out of disk space?");
1484 /*code for alternate checkpointing scheme. moved from top of loop over
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
)
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",
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
;
1518 fprintf(fp
," %s mismatch,\n",type
);
1519 fprintf(fp
," current program: %d\n",p
);
1520 fprintf(fp
," checkpoint file: %d\n",f
);
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
);
1541 static void check_match(FILE *fplog
,
1543 char *btime
,char *buser
,char *bhost
,int double_prec
,
1545 t_commrec
*cr
,gmx_bool bPartDecomp
,int npp_f
,int npme_f
,
1546 ivec dd_nc
,ivec dd_nc_f
)
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
);
1569 check_int (fplog
,"#PME-nodes" ,cr
->npmenodes
,npme_f
,&mm
);
1572 if (cr
->npmenodes
>= 0)
1574 npp
-= cr
->npmenodes
;
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
);
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" : "");
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
)
1610 char *version
,*btime
,*buser
,*bhost
,*fprog
,*ftime
;
1612 char filename
[STRLEN
],buf
[STEPSTRSIZE
];
1613 int nppnodes
,eIntegrator_f
,nppnodes_f
,npmenodes_f
;
1615 int natoms
,ngtc
,nnhpres
,nhchainlength
,nlambda
,fflags
,flags_eks
,flags_enh
,flags_dfh
;
1618 gmx_file_position_t
*outputfiles
;
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
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
1638 fl
.l_whence
=SEEK_SET
;
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",
1670 /* This will not be written if we do appending, since fplog is still NULL then */
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
)
1712 fprintf(stderr
,int_warn
,EI(eIntegrator_f
),EI(eIntegrator
));
1714 if(bAppendOutputFiles
)
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");
1723 fprintf(fplog
,int_warn
,EI(eIntegrator_f
),EI(eIntegrator
));
1732 else if (bPartDecomp
)
1734 nppnodes
= cr
->nnodes
;
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
++)
1750 dd_nc
[d
] = dd_nc_f
[d
];
1757 /* The number of PP nodes has not been set yet */
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
;
1771 if (fflags
!= state
->flags
)
1776 if(bAppendOutputFiles
)
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");
1791 "WARNING: The checkpoint state entries do not match the simulation,\n"
1792 " see the log file for details\n\n");
1798 print_flag_mismatch(fplog
,state
->flags
,fflags
);
1803 if ((EI_SD(eIntegrator
) || eIntegrator
== eiBD
) &&
1804 nppnodes
!= nppnodes_f
)
1809 fprintf(stderr
,sd_note
,nppnodes_f
,nppnodes
);
1813 fprintf(fplog
,sd_note
,nppnodes_f
,nppnodes
);
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. */
1829 ret
= do_cpt_ekinstate(gmx_fio_getxdr(fp
),TRUE
,
1830 flags_eks
,&state
->ekinstate
,NULL
);
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
);
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
);
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
);
1865 ret
= do_cpt_files(gmx_fio_getxdr(fp
),TRUE
,&outputfiles
,&nfiles
,NULL
,file_version
);
1871 ret
= do_cpt_footer(gmx_fio_getxdr(fp
),TRUE
,file_version
);
1876 if( gmx_fio_close(fp
) != 0)
1878 gmx_file("Cannot read/write checkpoint; corrupt file, or maybe you are out of disk space?");
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
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
);
1914 chksum_file
=gmx_fio_open(outputfiles
[i
].filename
,"a");
1917 chksum_file
=gmx_fio_open(outputfiles
[i
].filename
,"r+");
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
)
1930 if (_locking(fileno(gmx_fio_getfp(chksum_file
)), _LK_NBLCK
, LONG_MAX
)==-1)
1933 if (errno
== ENOSYS
)
1937 gmx_fatal(FARGS
,"File locking is not supported on this system. Use -noappend or specify -append explicitly to append anyhow.");
1941 fprintf(stderr
,"\nNOTE: File locking is not supported on this system, will not lock %s\n\n",outputfiles
[i
].filename
);
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
);
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
));
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
);
1988 gmx_fio_close(chksum_file
);
1991 /* compare md5 chksum */
1992 if (outputfiles
[i
].chksum_size
!= -1 &&
1993 memcmp(digest
,outputfiles
[i
].chksum
,16)!=0)
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
);
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
);
2015 rc
= truncate(outputfiles
[i
].filename
,outputfiles
[i
].offset
);
2019 gmx_fatal(FARGS
,"Truncation of file %s failed. Cannot do appending because of this failure.",outputfiles
[i
].filename
);
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
;
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
);
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
,
2064 int *nfiles
,gmx_file_position_t
**outputfiles
)
2067 char *version
,*btime
,*buser
,*bhost
,*fprog
,*ftime
;
2072 int flags_eks
,flags_enh
,flags_dfh
;
2074 gmx_file_position_t
*files_loc
=NULL
;
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
);
2083 do_cpt_state(gmx_fio_getxdr(fp
),TRUE
,state
->flags
,state
,bReadRNG
,NULL
);
2088 ret
= do_cpt_ekinstate(gmx_fio_getxdr(fp
),TRUE
,
2089 flags_eks
,&state
->ekinstate
,NULL
);
2094 ret
= do_cpt_enerhist(gmx_fio_getxdr(fp
),TRUE
,
2095 flags_enh
,&state
->enerhist
,NULL
);
2100 ret
= do_cpt_df_hist(gmx_fio_getxdr(fp
),TRUE
,
2101 flags_dfh
,&state
->dfhist
,NULL
);
2107 ret
= do_cpt_files(gmx_fio_getxdr(fp
),TRUE
,
2108 outputfiles
!= NULL
? outputfiles
: &files_loc
,
2109 outputfiles
!= NULL
? nfiles
: &nfiles_loc
,
2111 if (files_loc
!= NULL
)
2121 ret
= do_cpt_footer(gmx_fio_getxdr(fp
),TRUE
,file_version
);
2135 read_checkpoint_state(const char *fn
,int *simulation_part
,
2136 gmx_large_int_t
*step
,double *t
,t_state
*state
)
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
)
2151 int simulation_part
;
2152 gmx_large_int_t step
;
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
;
2162 fr
->step
= gmx_large_int_to_int(step
,
2163 "conversion of checkpoint to trajectory");
2167 fr
->lambda
= state
.lambda
[efptFEP
];
2168 fr
->fep_state
= state
.fep_state
;
2170 fr
->bX
= (state
.flags
& (1<<estX
));
2176 fr
->bV
= (state
.flags
& (1<<estV
));
2183 fr
->bBox
= (state
.flags
& (1<<estBOX
));
2186 copy_mat(state
.box
,fr
->box
);
2191 void list_checkpoint(const char *fn
,FILE *out
)
2195 char *version
,*btime
,*buser
,*bhost
,*fprog
,*ftime
;
2197 int eIntegrator
,simulation_part
,nppnodes
,npme
;
2198 gmx_large_int_t step
;
2202 int flags_eks
,flags_enh
,flags_dfh
;
2206 gmx_file_position_t
*outputfiles
;
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
);
2223 ret
= do_cpt_ekinstate(gmx_fio_getxdr(fp
),TRUE
,
2224 flags_eks
,&state
.ekinstate
,out
);
2229 ret
= do_cpt_enerhist(gmx_fio_getxdr(fp
),TRUE
,
2230 flags_enh
,&state
.enerhist
,out
);
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
);
2240 do_cpt_files(gmx_fio_getxdr(fp
),TRUE
,&outputfiles
,&nfiles
,out
,file_version
);
2245 ret
= do_cpt_footer(gmx_fio_getxdr(fp
),TRUE
,file_version
);
2252 if( gmx_fio_close(fp
) != 0)
2254 gmx_file("Cannot read/write checkpoint; corrupt file, or maybe you are out of disk space?");
2261 static gmx_bool
exist_output_file(const char *fnm_cp
,int nfile
,const t_filenm fnm
[])
2265 /* Check if the output file name stored in the checkpoint file
2266 * is one of the output file names of mdrun.
2270 !(is_output(&fnm
[i
]) && strcmp(fnm_cp
,fnm
[i
].fns
[0]) == 0))
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
)
2286 gmx_large_int_t step
=0;
2290 gmx_file_position_t
*outputfiles
;
2293 char *fn
,suf_up
[STRLEN
];
2297 if (SIMMASTER(cr
)) {
2298 if(!gmx_fexist(filename
) || (!(fp
= gmx_fio_open(filename
,"r")) ))
2300 *simulation_part
= 0;
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?");
2317 for(f
=0; f
<nfiles
; f
++)
2319 if (exist_output_file(outputfiles
[f
].filename
,nfile
,fnm
))
2324 if (nexist
== nfiles
)
2326 bAppend
= bAppendReq
;
2328 else if (nexist
> 0)
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",
2335 fprintf(stderr
,"output files present:");
2336 for(f
=0; f
<nfiles
; f
++)
2338 if (exist_output_file(outputfiles
[f
].filename
,
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
,
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
);
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
);
2377 *bAddPart
= (strstr(fn
,part_suffix
) != NULL
||
2378 strstr(fn
,suf_up
) != NULL
);
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
)