diff --git a/src/cooling.c b/src/cooling.c index bd60510c98b292972bd694f09241730360911eb1..89a04b30f8ce3f106d90a6db1364a3caadba6deb 100644 --- a/src/cooling.c +++ b/src/cooling.c @@ -63,7 +63,7 @@ void cooling_print(const struct cooling_function_data* cooling) { void cooling_struct_dump(const struct cooling_function_data* cooling, FILE* stream) { restart_write_blocks((void*)cooling, sizeof(struct cooling_function_data), 1, - stream, "cooling function"); + stream, "cooling", "cooling function"); } /** @@ -76,5 +76,5 @@ void cooling_struct_dump(const struct cooling_function_data* cooling, void cooling_struct_restore(const struct cooling_function_data* cooling, FILE* stream) { restart_read_blocks((void*)cooling, sizeof(struct cooling_function_data), 1, - stream, "cooling function"); + stream, NULL, "cooling function"); } diff --git a/src/engine.c b/src/engine.c index 92bc245abe10c9d1bb88dd2545956765f234dd6b..3c0aaa6a279d74299b062733001137b786ac5662 100644 --- a/src/engine.c +++ b/src/engine.c @@ -5797,7 +5797,7 @@ void engine_struct_dump(struct engine *e, FILE *stream) { /* Dump the engine. Save the current tasks_per_cell estimate. */ e->restart_max_tasks = engine_estimate_nr_tasks(e); - restart_write_blocks(e, sizeof(struct engine), 1, stream, "engine struct"); + restart_write_blocks(e, sizeof(struct engine), 1, stream, "engine", "engine struct"); /* And all the engine pointed data, these use their own dump functions. */ space_struct_dump(e->s, stream); @@ -5827,7 +5827,7 @@ void engine_struct_dump(struct engine *e, FILE *stream) { void engine_struct_restore(struct engine *e, FILE *stream) { /* Read the engine. */ - restart_read_blocks(e, sizeof(struct engine), 1, stream, "engine struct"); + restart_read_blocks(e, sizeof(struct engine), 1, stream, NULL, "engine struct"); /* Re-initializations as necessary for our struct and its members. */ e->sched.tasks = NULL; diff --git a/src/gravity_properties.c b/src/gravity_properties.c index 11c44284e3ffdc36724a786742bfa2fdb7e0f358..475a1cb93d0ad64ac0e02ea78498261fdec87938 100644 --- a/src/gravity_properties.c +++ b/src/gravity_properties.c @@ -105,7 +105,7 @@ void gravity_props_print_snapshot(hid_t h_grpgrav, */ void gravity_props_struct_dump(const struct gravity_props *p, FILE *stream) { restart_write_blocks((void *)p, sizeof(struct gravity_props), 1, stream, - "gravity props"); + "gravity", "gravity props"); } /** @@ -117,5 +117,5 @@ void gravity_props_struct_dump(const struct gravity_props *p, FILE *stream) { */ void gravity_props_struct_restore(const struct gravity_props *p, FILE *stream) { restart_read_blocks((void *)p, sizeof(struct gravity_props), 1, stream, - "gravity props"); + NULL, "gravity props"); } diff --git a/src/hydro_properties.c b/src/hydro_properties.c index 4f3422f5ba4bcb4a1d702694eea80c22016e4e45..7ea7a82ab3502acc275356f2140a70b3b5df2b15 100644 --- a/src/hydro_properties.c +++ b/src/hydro_properties.c @@ -136,7 +136,7 @@ void hydro_props_print_snapshot(hid_t h_grpsph, const struct hydro_props *p) { */ void hydro_props_struct_dump(const struct hydro_props *p, FILE *stream) { restart_write_blocks((void *)p, sizeof(struct hydro_props), 1, stream, - "hydro props"); + "hydroprops", "hydro props"); } /** @@ -148,5 +148,5 @@ void hydro_props_struct_dump(const struct hydro_props *p, FILE *stream) { */ void hydro_props_struct_restore(const struct hydro_props *p, FILE *stream) { restart_read_blocks((void *)p, sizeof(struct hydro_props), 1, stream, - "hydro props"); + NULL, "hydro props"); } diff --git a/src/parser.c b/src/parser.c index efbef47daddadcd348fe7dbd5b956c00a109f3dc..cbd63e913010066cbd39418b81609f4669404213 100644 --- a/src/parser.c +++ b/src/parser.c @@ -794,7 +794,7 @@ void parser_write_params_to_hdf5(const struct swift_params *params, hid_t grp) { */ void parser_struct_dump(const struct swift_params *params, FILE *stream) { restart_write_blocks((void *)params, sizeof(struct swift_params), 1, stream, - "parameters"); + "parameters", "parameters"); } /** @@ -806,5 +806,5 @@ void parser_struct_dump(const struct swift_params *params, FILE *stream) { */ void parser_struct_restore(const struct swift_params *params, FILE *stream) { restart_read_blocks((void *)params, sizeof(struct swift_params), 1, stream, - "parameters"); + NULL, "parameters"); } diff --git a/src/partition.c b/src/partition.c index 2613ee3d92a08dd435bbeaeb0e7ab2988885a8b3..edf65bd1f51fb789145455ff4f49bf64598849e1 100644 --- a/src/partition.c +++ b/src/partition.c @@ -1309,13 +1309,13 @@ void partition_restore_celllist(struct space *s, struct repartition *reparttype) */ void partition_struct_dump(struct repartition *reparttype, FILE *stream) { restart_write_blocks(reparttype, sizeof(struct repartition), 1, stream, - "repartition params"); + "repartition", "repartition params"); /* Also save the celllist, if we have one. */ if (reparttype->ncelllist > 0) restart_write_blocks(reparttype->celllist, sizeof(int) * reparttype->ncelllist, 1, stream, - "repartition celllist"); + "celllist", "repartition celllist"); } /** @@ -1327,7 +1327,7 @@ void partition_struct_dump(struct repartition *reparttype, FILE *stream) { */ void partition_struct_restore(struct repartition *reparttype, FILE *stream) { restart_read_blocks(reparttype, sizeof(struct repartition), 1, stream, - "repartition params"); + NULL, "repartition params"); /* Also restore the celllist, if we have one. */ if (reparttype->ncelllist > 0) { @@ -1335,6 +1335,6 @@ void partition_struct_restore(struct repartition *reparttype, FILE *stream) { if (reparttype->celllist == NULL) error("Failed to allocate celllist"); restart_read_blocks(reparttype->celllist, sizeof(int) * reparttype->ncelllist, 1, stream, - "repartition celllist"); + NULL, "repartition celllist"); } } diff --git a/src/physical_constants.c b/src/physical_constants.c index e8edf7df0b4411ef303a341dd94b9afef8cc94dc..b70b80574e7f73fe3568e18f0809350548564c4b 100644 --- a/src/physical_constants.c +++ b/src/physical_constants.c @@ -132,7 +132,7 @@ void phys_const_print(struct phys_const *internal_const) { void phys_const_struct_dump(const struct phys_const *internal_const, FILE *stream) { restart_write_blocks((void *)internal_const, sizeof(struct phys_const), 1, - stream, "phys_const params"); + stream, "physconst", "phys_const params"); } /** @@ -145,5 +145,5 @@ void phys_const_struct_dump(const struct phys_const *internal_const, void phys_const_struct_restore(const struct phys_const *internal_const, FILE *stream) { restart_read_blocks((void *)internal_const, sizeof(struct phys_const), 1, - stream, "phys_const params"); + stream, NULL, "phys_const params"); } diff --git a/src/potential.c b/src/potential.c index f4926bbfb766d821fac96e0824af6949615f3b7b..1fda6fc8752ff626a5262d7824ea68fd3bc16d46 100644 --- a/src/potential.c +++ b/src/potential.c @@ -63,7 +63,7 @@ void potential_print(const struct external_potential* potential) { void potential_struct_dump(const struct external_potential* potential, FILE* stream) { restart_write_blocks((void*)potential, sizeof(struct external_potential), 1, - stream, "external potential"); + stream, "externalpotential", "external potential"); } /** @@ -76,5 +76,5 @@ void potential_struct_dump(const struct external_potential* potential, void potential_struct_restore(const struct external_potential* potential, FILE* stream) { restart_read_blocks((void*)potential, sizeof(struct external_potential), 1, - stream, "external potential"); + stream, NULL, "external potential"); } diff --git a/src/restart.c b/src/restart.c index 703a07d45cdca9e0d65573de61705ebaf7c2ffd7..b25632e23860993e0350e41f012c1552179d7d30 100644 --- a/src/restart.c +++ b/src/restart.c @@ -39,7 +39,17 @@ #include "restart.h" #include "version.h" +/* The signature for restart files. */ +#define SWIFT_RESTART_SIGNATURE "SWIFT-restart-file" + #define FNAMELEN 200 +#define LABLEN 20 + +/* Structure for a dumped header. */ +struct header { + size_t len; /* Total length of data in bytes. */ + char label[LABLEN+1]; /* A label for data */ +}; /** * @brief generate a name for a restart file. @@ -122,9 +132,9 @@ void restart_write(struct engine *e, const char *filename) { /* Dump our signature and version. */ restart_write_blocks(SWIFT_RESTART_SIGNATURE, strlen(SWIFT_RESTART_SIGNATURE), - 1, stream, "SWIFT signature"); + 1, stream, "signature", "SWIFT signature"); restart_write_blocks((void *)package_version(), strlen(package_version()), 1, - stream, "SWIFT version"); + stream, "version", "SWIFT version"); engine_struct_dump(e, stream); fclose(stream); @@ -145,24 +155,24 @@ void restart_read(struct engine *e, const char *filename) { /* Get our version and signature back. These should match. */ char signature[strlen(SWIFT_RESTART_SIGNATURE) + 1]; int len = strlen(SWIFT_RESTART_SIGNATURE); - restart_read_blocks(signature, len, 1, stream, "SWIFT signature"); + restart_read_blocks(signature, len, 1, stream, NULL, "SWIFT signature"); signature[len] = '\0'; if (strncmp(signature, SWIFT_RESTART_SIGNATURE, len) != 0) error( - "Do not recognise this as a SWIFT restart file, found %s " - "expected %s", + "Do not recognise this as a SWIFT restart file, found '%s' " + "expected '%s'", signature, SWIFT_RESTART_SIGNATURE); char version[FNAMELEN]; len = strlen(package_version()); - restart_read_blocks(version, len, 1, stream, "SWIFT version"); + restart_read_blocks(version, len, 1, stream, NULL, "SWIFT version"); version[len] = '\0'; /* It might work! */ if (strncmp(version, package_version(), len) != 0) message( "WARNING: restoring from a different version of SWIFT.\n You have:" - " %s and the restarts files are from: %s. This may fail" + " '%s' and the restarts files are from: '%s'. This may fail" " badly.", package_version(), version); @@ -172,22 +182,38 @@ void restart_read(struct engine *e, const char *filename) { /** * @brief Read blocks of memory from a file stream into a memory location. - * Exits the application if the read fails and does nothing - * if the size is zero. + * Exits the application if the read fails and does nothing if the + * size is zero. * * @param ptr pointer to the memory * @param size size of a block * @param nblocks number of blocks to read * @param stream the file stream + * @param label the label recovered for the block, needs to be at least 20 + * characters, set to NULL if not required * @param errstr a context string to qualify any errors. */ void restart_read_blocks(void *ptr, size_t size, size_t nblocks, FILE *stream, - const char *errstr) { + char *label, const char *errstr) { if (size > 0) { - size_t nread = fread(ptr, size, nblocks, stream); - if (nread != nblocks) - error("Failed to restore %s from restart file (%s)", errstr, - ferror(stream) ? strerror(errno) : "unexpected end of file"); + struct header head; + size_t nread = fread(&head, sizeof(struct header), 1, stream); + if (nread != 1) + error("Failed to read the %s header from restart file (%s)", errstr, strerror(errno)); + + /* Check that the stored length is the same as the expected one. */ + if (head.len != nblocks * size) + error("Mismatched data length in restart file for %s (%zu != %zu)", + errstr, head.len, nblocks * size); + + /* Return label, if required. */ + if (label != NULL) + strncpy(label, head.label, LABLEN); + + nread = fread(ptr, size, nblocks, stream); + if (nread != nblocks) + error("Failed to restore %s from restart file (%s)", errstr, + ferror(stream) ? strerror(errno) : "unexpected end of file"); } } @@ -200,15 +226,28 @@ void restart_read_blocks(void *ptr, size_t size, size_t nblocks, FILE *stream, * @param size the blocks * @param nblocks number of blocks to write * @param stream the file stream + * @param label a label for the content, can only be 20 characters. * @param errstr a context string to qualify any errors. */ void restart_write_blocks(void *ptr, size_t size, size_t nblocks, FILE *stream, - const char *errstr) { - if (size > 0) { - size_t nwrite = fwrite(ptr, size, nblocks, stream); - if (nwrite != nblocks) - error("Failed to save %s to restart file (%s)", errstr, strerror(errno)); - } + const char *label, const char *errstr) { + if (size > 0) { + + /* Add a preamble header. */ + struct header head; + head.len = nblocks * size; + strncpy(head.label, label, LABLEN); + head.label[LABLEN] = '\0'; + + /* Now dump it and the data. */ + size_t nwrite = fwrite(&head, sizeof(struct header), 1, stream); + if (nwrite != 1) + error("Failed to save %s header to restart file (%s)", errstr, strerror(errno)); + + nwrite = fwrite(ptr, size, nblocks, stream); + if (nwrite != nblocks) + error("Failed to save %s to restart file (%s)", errstr, strerror(errno)); + } } /** diff --git a/src/restart.h b/src/restart.h index 56af102e9aa1269449cf5ad77d2ef75836625d06..80e6c6755c09be4d3bda84860774b7da9e1a07cd 100644 --- a/src/restart.h +++ b/src/restart.h @@ -23,11 +23,6 @@ struct engine; -/* The signature for restart files. */ -#ifndef SWIFT_RESTART_SIGNATURE -#define SWIFT_RESTART_SIGNATURE "SWIFT-restart-file" -#endif - void restart_write(struct engine *e, const char *filename); void restart_read(struct engine *e, const char *filename); @@ -37,10 +32,10 @@ int restart_genname(const char *dir, const char *basename, int nodeID, char *name, int size); void restart_read_blocks(void *ptr, size_t size, size_t nblocks, FILE *stream, - const char *errstr); + char *label, const char *errstr); void restart_write_blocks(void *ptr, size_t size, size_t nblocks, FILE *stream, - const char *errstr); + const char *label, const char *errstr); int restart_stop_now(const char *dir, int cleanup); diff --git a/src/sourceterms.c b/src/sourceterms.c index 3b89e5dcfb893bb128ea40fe79381943d0cccd6f..994658740a50a764edd3988ef7d6b78e00546f8f 100644 --- a/src/sourceterms.c +++ b/src/sourceterms.c @@ -68,7 +68,7 @@ void sourceterms_print(struct sourceterms *source) { void sourceterms_struct_dump(const struct sourceterms *sourceterms, FILE *stream) { restart_write_blocks((void *)sourceterms, sizeof(struct sourceterms), 1, - stream, "sourceterms"); + stream, "sourceterms", "sourceterms"); } /** @@ -81,5 +81,5 @@ void sourceterms_struct_dump(const struct sourceterms *sourceterms, void sourceterms_struct_restore(const struct sourceterms *sourceterms, FILE *stream) { restart_read_blocks((void *)sourceterms, sizeof(struct sourceterms), 1, - stream, "sourceterms"); + stream, NULL, "sourceterms"); } diff --git a/src/space.c b/src/space.c index ec7676fb59f7217252a2f94301f126a3d387a2ec..7d5d01044bf799357493adb6819d7027784b327c 100644 --- a/src/space.c +++ b/src/space.c @@ -3249,22 +3249,22 @@ void space_clean(struct space *s) { */ void space_struct_dump(struct space *s, FILE *stream) { - restart_write_blocks(s, sizeof(struct space), 1, stream, "space struct"); + restart_write_blocks(s, sizeof(struct space), 1, stream, "space", "space struct"); /* More things to write. */ if (s->nr_parts > 0) { restart_write_blocks(s->parts, s->nr_parts, sizeof(struct part), stream, - "parts"); + "parts", "parts"); restart_write_blocks(s->xparts, s->nr_parts, sizeof(struct xpart), stream, - "xparts"); + "xparts", "xparts"); } if (s->nr_gparts > 0) restart_write_blocks(s->gparts, s->nr_gparts, sizeof(struct gpart), stream, - "gparts"); + "gparts", "gparts"); if (s->nr_sparts > 0) restart_write_blocks(s->sparts, s->nr_sparts, sizeof(struct spart), stream, - "sparts"); + "sparts", "sparts"); } /** @@ -3276,7 +3276,7 @@ void space_struct_dump(struct space *s, FILE *stream) { */ void space_struct_restore(struct space *s, FILE *stream) { - restart_read_blocks(s, sizeof(struct space), 1, stream, "space struct"); + restart_read_blocks(s, sizeof(struct space), 1, stream, NULL, "space struct"); /* Things that should be reconstructed in a rebuild. */ s->cells_top = NULL; @@ -3308,9 +3308,9 @@ void space_struct_restore(struct space *s, FILE *stream) { error("Failed to allocate restore xpart array."); restart_read_blocks(s->parts, s->nr_parts, sizeof(struct part), stream, - "parts"); + NULL, "parts"); restart_read_blocks(s->xparts, s->nr_parts, sizeof(struct xpart), stream, - "xparts"); + NULL, "xparts"); } s->gparts = NULL; if (s->nr_gparts > 0) { @@ -3319,7 +3319,7 @@ void space_struct_restore(struct space *s, FILE *stream) { error("Failed to allocate restore gpart array."); restart_read_blocks(s->gparts, s->nr_gparts, sizeof(struct gpart), stream, - "gparts"); + NULL, "gparts"); } s->sparts = NULL; @@ -3329,7 +3329,7 @@ void space_struct_restore(struct space *s, FILE *stream) { error("Failed to allocate restore spart array."); restart_read_blocks(s->sparts, s->nr_sparts, sizeof(struct spart), stream, - "sparts"); + NULL, "sparts"); } /* Need to reconnect the gravity parts to their hydro and star particles. */ diff --git a/src/units.c b/src/units.c index d928e20286d2fac4246c289fda7a213ef7d6aa04..e963db3a986cbc7a05f8d5404f116ed837cc4451 100644 --- a/src/units.c +++ b/src/units.c @@ -612,7 +612,7 @@ void units_print(const struct unit_system* us) { */ void units_struct_dump(const struct unit_system* us, FILE* stream) { restart_write_blocks((void*)us, sizeof(struct unit_system), 1, stream, - "units"); + "units", "units"); } /** @@ -622,6 +622,6 @@ void units_struct_dump(const struct unit_system* us, FILE* stream) { * @param stream the file stream */ void units_struct_restore(const struct unit_system* us, FILE* stream) { - restart_read_blocks((void*)us, sizeof(struct unit_system), 1, stream, - "units"); + restart_read_blocks((void*)us, sizeof(struct unit_system), 1, stream, + NULL, "units"); }