/* The source code in this file should be thread-safe.
Please keep it that way. */
+#include "gmxpre.h"
+#include "gromacs/legacyheaders/checkpoint.h"
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
+#include "config.h"
+#include <errno.h>
+#include <stdlib.h>
#include <string.h>
-#include <time.h>
-
-#ifdef HAVE_SYS_TIME_H
-#include <sys/time.h>
-#endif
-
-#ifdef HAVE_UNISTD_H
-#include <unistd.h>
-#endif
+#include <fcntl.h>
#ifdef GMX_NATIVE_WINDOWS
-/* _chsize_s */
#include <io.h>
#include <sys/locking.h>
#endif
-#include "copyrite.h"
-#include "names.h"
-#include "typedefs.h"
-#include "types/commrec.h"
-#include "gromacs/utility/smalloc.h"
-#include "txtdump.h"
-#include "vec.h"
-#include "network.h"
-#include "checkpoint.h"
-#include "main.h"
-#include "gromacs/utility/cstringutil.h"
-#include <fcntl.h>
-
+#include "buildinfo.h"
#include "gromacs/fileio/filenm.h"
-#include "gromacs/fileio/futil.h"
#include "gromacs/fileio/gmxfio.h"
-#include "gromacs/fileio/xdrf.h"
#include "gromacs/fileio/xdr_datatype.h"
+#include "gromacs/fileio/xdrf.h"
+#include "gromacs/legacyheaders/copyrite.h"
+#include "gromacs/legacyheaders/names.h"
+#include "gromacs/legacyheaders/network.h"
+#include "gromacs/legacyheaders/txtdump.h"
+#include "gromacs/legacyheaders/typedefs.h"
+#include "gromacs/legacyheaders/types/commrec.h"
+#include "gromacs/math/vec.h"
#include "gromacs/utility/baseversion.h"
-#include "gmx_fatal.h"
-
-#include "buildinfo.h"
+#include "gromacs/utility/cstringutil.h"
+#include "gromacs/utility/fatalerror.h"
+#include "gromacs/utility/futil.h"
+#include "gromacs/utility/smalloc.h"
+#include "gromacs/utility/sysinfo.h"
#ifdef GMX_FAHCORE
#include "corewrap.h"
"accumulated_plus", "accumulated_minus", "accumulated_plus_2", "accumulated_minus_2", "Tij", "Tij_empirical"
};
-#ifdef GMX_NATIVE_WINDOWS
-static int
-gmx_wintruncate(const char *filename, __int64 size)
-{
-#ifdef GMX_FAHCORE
- /*we do this elsewhere*/
- return 0;
-#else
- FILE *fp;
- int rc;
-
- fp = fopen(filename, "rb+");
-
- if (fp == NULL)
- {
- return -1;
- }
-
-#ifdef _MSC_VER
- return _chsize_s( fileno(fp), size);
-#else
- return _chsize( fileno(fp), size);
-#endif
-#endif
-}
-#endif
-
-
enum {
ecprREAL, ecprRVEC, ecprMATRIX
};
{
if (dtc == xdr_datatype_double)
{
+ /* cppcheck-suppress invalidPointerCast
+ * Only executed if real is anyhow double */
vd = (double *)vp;
}
else
static int do_cpte_real(XDR *xd, int cptp, int ecpt, int sflags,
real *r, FILE *list)
{
- int n;
-
return do_cpte_reals_low(xd, cptp, ecpt, sflags, 1, NULL, &r, list, ecprREAL);
}
bool_t res = 0;
int dtc = xdr_datatype_int;
int *vp, *va = NULL;
- int nf, dt, i;
+ int nf, dt;
nf = n;
res = xdr_int(xd, &nf);
bool_t res = 0;
int dtc = xdr_datatype_double;
double *vp, *va = NULL;
- int nf, dt, i;
+ int nf, dt;
nf = n;
res = xdr_int(xd, &nf);
static int do_cpte_rvecs(XDR *xd, int cptp, int ecpt, int sflags,
int n, rvec **v, FILE *list)
{
- int n3;
-
return do_cpte_reals_low(xd, cptp, ecpt, sflags,
n*DIM, NULL, (real **)v, list, ecprRVEC);
}
matrix v, FILE *list)
{
real *vr;
- real ret;
+ int ret;
vr = (real *)&(v[0][0]);
ret = do_cpte_reals_low(xd, cptp, ecpt, sflags,
int n, real **v, FILE *list)
{
int i;
- real *vr;
- real ret, reti;
+ int ret, reti;
char name[CPTSTRLEN];
ret = 0;
}
for (i = 0; i < n; i++)
{
- reti = 0;
- vr = v[i];
reti = do_cpte_reals_low(xd, cptp, ecpt, sflags, n, NULL, &(v[i]), NULL, ecprREAL);
if (list && reti == 0)
{
sprintf(name, "%s[%d]", st_names(cptp, ecpt), i);
pr_reals(list, 0, name, v[i], n);
}
- if (reti == 0)
+ if (reti != 0)
{
- ret = 0;
+ ret = reti;
}
}
return ret;
bool_t res = 0;
int magic;
int idum = 0;
- int i;
char *fhost;
if (bRead)
{
enerhist->ener_sum_sim[i] = enerhist->ener_sum[i];
}
- fflags |= (1<<eenhENERGY_SUM_SIM);
}
if ( (fflags & (1<<eenhENERGY_NSUM)) &&
{
/* Assume we have an old file format and copy nsum to nsteps */
enerhist->nsteps = enerhist->nsum;
- fflags |= (1<<eenhENERGY_NSTEPS);
}
if ( (fflags & (1<<eenhENERGY_NSUM_SIM)) &&
!(fflags & (1<<eenhENERGY_NSTEPS_SIM)))
{
/* Assume we have an old file format and copy nsum to nsteps */
enerhist->nsteps_sim = enerhist->nsum_sim;
- fflags |= (1<<eenhENERGY_NSTEPS_SIM);
}
return ret;
static int do_cpt_EDstate(XDR *xd, gmx_bool bRead,
edsamstate_t *EDstate, FILE *list)
{
- int i, j;
+ int i;
int ret = 0;
char buf[STRLEN];
gmx_file_position_t **p_outputfiles, int *nfiles,
FILE *list, int file_version)
{
- int i, j;
+ int i;
gmx_off_t offset;
gmx_off_t mask = 0xFFFFFFFFL;
int offset_high, offset_low;
int double_prec;
char *fprog;
char *fntemp; /* the temporary checkpoint file name */
- time_t now;
char timebuf[STRLEN];
- int nppnodes, npmenodes, flag_64bit;
+ int nppnodes, npmenodes;
char buf[1024], suffix[5+STEPSTRSIZE], sbuf[STEPSTRSIZE];
gmx_file_position_t *outputfiles;
int noutputfiles;
char *ftime;
- int flags_eks, flags_enh, flags_dfh, i;
+ int flags_eks, flags_enh, flags_dfh;
t_fileio *ret;
if (DOMAINDECOMP(cr))
snew(fntemp, strlen(fn));
strcpy(fntemp, fn);
#endif
- time(&now);
- gmx_ctime_r(&now, timebuf, STRLEN);
+ gmx_format_current_time(timebuf, STRLEN);
if (fplog)
{
*/
int gmx_major, gmx_minor;
int cpt_major, cpt_minor;
- sscanf(gmx_version(), "VERSION %d.%d", &gmx_major, &gmx_minor);
- sscanf(version, "VERSION %d.%d", &cpt_major, &cpt_minor);
- version_differs = (gmx_major != cpt_major || gmx_minor != cpt_minor);
+ sscanf(gmx_version(), "VERSION %5d.%5d", &gmx_major, &gmx_minor);
+ int ret = sscanf(version, "VERSION %5d.%5d", &cpt_major, &cpt_minor);
+ version_differs = (ret < 2 || gmx_major != cpt_major ||
+ gmx_minor != cpt_minor);
}
check_string(fplog, "Build time", BUILD_TIME, btime, &mm);
if (mm)
{
const char msg_version_difference[] =
- "The current Gromacs major & minor version are not identical to those that\n"
- "generated the checkpoint file. In principle Gromacs does not support\n"
+ "The current GROMACS major & minor version are not identical to those that\n"
+ "generated the checkpoint file. In principle GROMACS does not support\n"
"continuation from checkpoints between different versions, so we advise\n"
"against this. If you still want to try your luck we recommend that you use\n"
"the -noappend flag to keep your output files from the two versions separate.\n"
"file have changed between the different major & minor versions.\n";
const char msg_mismatch_notice[] =
- "Gromacs patchlevel, binary or parallel settings differ from previous run.\n"
+ "GROMACS patchlevel, binary or parallel settings differ from previous run.\n"
"Continuation is exact, but not guaranteed to be binary identical.\n";
const char msg_logdetails[] =
int file_version;
char *version, *btime, *buser, *bhost, *fprog, *ftime;
int double_prec;
- char filename[STRLEN], buf[STEPSTRSIZE];
- int nppnodes, eIntegrator_f, nppnodes_f, npmenodes_f;
+ char buf[STEPSTRSIZE];
+ int eIntegrator_f, nppnodes_f, npmenodes_f;
ivec dd_nc_f;
int natoms, ngtc, nnhpres, nhchainlength, nlambda, fflags, flags_eks, flags_enh, flags_dfh;
int d;
if (!PAR(cr))
{
- nppnodes = 1;
cr->npmenodes = 0;
}
else if (cr->nnodes == nppnodes_f + npmenodes_f)
{
cr->npmenodes = npmenodes_f;
}
- nppnodes = cr->nnodes - cr->npmenodes;
+ int nppnodes = cr->nnodes - cr->npmenodes;
if (nppnodes == nppnodes_f)
{
for (d = 0; d < DIM; d++)
}
}
}
- else
- {
- /* The number of PP nodes has not been set yet */
- nppnodes = -1;
- }
if (fflags != state->flags)
{
if (i != 0) /*log file is already seeked to correct position */
{
-#ifdef GMX_NATIVE_WINDOWS
- rc = gmx_wintruncate(outputfiles[i].filename, outputfiles[i].offset);
-#else
- rc = truncate(outputfiles[i].filename, outputfiles[i].offset);
-#endif
+#if !defined(GMX_NATIVE_WINDOWS) || !defined(GMX_FAHCORE)
+ /* For FAHCORE, we do this elsewhere*/
+ rc = gmx_truncate(outputfiles[i].filename, outputfiles[i].offset);
if (rc != 0)
{
gmx_fatal(FARGS, "Truncation of file %s failed. Cannot do appending because of this failure.", outputfiles[i].filename);
}
+#endif
}
}
}
ir->simulation_part += 1;
}
+void read_checkpoint_part_and_step(const char *filename,
+ int *simulation_part,
+ gmx_int64_t *step)
+{
+ int file_version;
+ char *version, *btime, *buser, *bhost, *fprog, *ftime;
+ int double_prec;
+ int eIntegrator;
+ int nppnodes, npme;
+ ivec dd_nc;
+ int flags_eks, flags_enh, flags_dfh;
+ double t;
+ t_state state;
+ t_fileio *fp;
+
+ if (filename == NULL ||
+ !gmx_fexist(filename) ||
+ (!(fp = gmx_fio_open(filename, "r"))))
+ {
+ *simulation_part = 0;
+ *step = 0;
+ return;
+ }
+
+ /* Not calling initializing state before use is nasty, but all we
+ do is read into its member variables and throw the struct away
+ again immediately. */
+
+ do_cpt_header(gmx_fio_getxdr(fp), TRUE, &file_version,
+ &version, &btime, &buser, &bhost, &double_prec, &fprog, &ftime,
+ &eIntegrator, simulation_part, step, &t, &nppnodes, dd_nc, &npme,
+ &state.natoms, &state.ngtc, &state.nnhpres, &state.nhchainlength,
+ &(state.dfhist.nlambda), &state.flags, &flags_eks, &flags_enh, &flags_dfh,
+ &state.edsamstate.nED, &state.swapstate.eSwapCoords, NULL);
+
+ gmx_fio_close(fp);
+}
+
static void read_checkpoint_data(t_fileio *fp, int *simulation_part,
gmx_int64_t *step, double *t, t_state *state,
int *nfiles, gmx_file_position_t **outputfiles)
ivec dd_nc;
t_state state;
int flags_eks, flags_enh, flags_dfh;
- int indent;
- int i, j;
int ret;
gmx_file_position_t *outputfiles;
int nfiles;
done_state(&state);
}
-
-static gmx_bool exist_output_file(const char *fnm_cp, int nfile, const t_filenm fnm[])
-{
- int i;
-
- /* Check if the output file name stored in the checkpoint file
- * is one of the output file names of mdrun.
- */
- i = 0;
- while (i < nfile &&
- !(is_output(&fnm[i]) && strcmp(fnm_cp, fnm[i].fns[0]) == 0))
- {
- i++;
- }
-
- return (i < nfile && gmx_fexist(fnm_cp));
-}
-
/* This routine cannot print tons of data, since it is called before the log file is opened. */
-gmx_bool read_checkpoint_simulation_part(const char *filename, int *simulation_part,
- gmx_int64_t *cpt_step, t_commrec *cr,
- gmx_bool bAppendReq,
- int nfile, const t_filenm fnm[],
- const char *part_suffix, gmx_bool *bAddPart)
+void
+read_checkpoint_simulation_part_and_filenames(t_fileio *fp,
+ int *simulation_part,
+ int *nfiles,
+ gmx_file_position_t **outputfiles)
{
- t_fileio *fp;
- gmx_int64_t step = 0;
- double t;
- /* This next line is nasty because the sub-structures of t_state
- * cannot be assumed to be zeroed (or even initialized in ways the
- * rest of the code might assume). Using snew would be better, but
- * this will all go away for 5.0. */
- t_state state;
- int nfiles;
- gmx_file_position_t *outputfiles;
- int nexist, f;
- gmx_bool bAppend;
- char *fn, suf_up[STRLEN];
-
- bAppend = FALSE;
-
- if (SIMMASTER(cr))
- {
- if (!gmx_fexist(filename) || (!(fp = gmx_fio_open(filename, "r")) ))
- {
- *simulation_part = 0;
- }
- else
- {
- init_state(&state, 0, 0, 0, 0, 0);
-
- read_checkpoint_data(fp, simulation_part, &step, &t, &state,
- &nfiles, &outputfiles);
- if (gmx_fio_close(fp) != 0)
- {
- gmx_file("Cannot read/write checkpoint; corrupt file, or maybe you are out of disk space?");
- }
- done_state(&state);
-
- if (bAppendReq)
- {
- nexist = 0;
- for (f = 0; f < nfiles; f++)
- {
- if (exist_output_file(outputfiles[f].filename, nfile, fnm))
- {
- nexist++;
- }
- }
- if (nexist == nfiles)
- {
- bAppend = bAppendReq;
- }
- else if (nexist > 0)
- {
- fprintf(stderr,
- "Output file appending has been requested,\n"
- "but some output files listed in the checkpoint file %s\n"
- "are not present or are named differently by the current program:\n",
- filename);
- fprintf(stderr, "output files present:");
- for (f = 0; f < nfiles; f++)
- {
- if (exist_output_file(outputfiles[f].filename,
- nfile, fnm))
- {
- fprintf(stderr, " %s", outputfiles[f].filename);
- }
- }
- fprintf(stderr, "\n");
- fprintf(stderr, "output files not present or named differently:");
- for (f = 0; f < nfiles; f++)
- {
- if (!exist_output_file(outputfiles[f].filename,
- nfile, fnm))
- {
- fprintf(stderr, " %s", outputfiles[f].filename);
- }
- }
- fprintf(stderr, "\n");
-
- gmx_fatal(FARGS, "File appending requested, but %d of the %d output files are not present or are named differently", nfiles-nexist, nfiles);
- }
- }
+ gmx_int64_t step = 0;
+ double t;
+ t_state state;
- if (bAppend)
- {
- if (nfiles == 0)
- {
- gmx_fatal(FARGS, "File appending requested, but no output file information is stored in the checkpoint file");
- }
- fn = outputfiles[0].filename;
- if (strlen(fn) < 4 ||
- gmx_strcasecmp(fn+strlen(fn)-4, ftp2ext(efLOG)) == 0)
- {
- gmx_fatal(FARGS, "File appending requested, but the log file is not the first file listed in the checkpoint file");
- }
- /* Set bAddPart to whether the suffix string '.part' is present
- * in the log file name.
- */
- strcpy(suf_up, part_suffix);
- upstring(suf_up);
- *bAddPart = (strstr(fn, part_suffix) != NULL ||
- strstr(fn, suf_up) != NULL);
- }
-
- sfree(outputfiles);
- }
- }
- if (PAR(cr))
- {
- gmx_bcast(sizeof(*simulation_part), simulation_part, cr);
+ init_state(&state, 0, 0, 0, 0, 0);
- if (*simulation_part > 0 && bAppendReq)
- {
- gmx_bcast(sizeof(bAppend), &bAppend, cr);
- gmx_bcast(sizeof(*bAddPart), bAddPart, cr);
- }
- }
- if (NULL != cpt_step)
+ read_checkpoint_data(fp, simulation_part, &step, &t, &state,
+ nfiles, outputfiles);
+ if (gmx_fio_close(fp) != 0)
{
- *cpt_step = step;
+ gmx_file("Cannot read/write checkpoint; corrupt file, or maybe you are out of disk space?");
}
-
- return bAppend;
+ done_state(&state);
}