Commit 9b38a77e authored by Matthieu Schaller's avatar Matthieu Schaller
Browse files

Use a single function to create the snapshot names across all the i/o schemes

parent 9bfd0ca3
......@@ -2492,3 +2492,47 @@ void io_make_snapshot_subdir(const char* dirname) {
safe_checkdir(dirname, /*create=*/1);
}
}
/**
* @brief Construct the file names for a single-file hdf5 snapshots and
*
* @param filename (return) The file name of the hdf5 snapshot.
* @param xmf_filename (return) The file name of the associated XMF file.
* @param use_time_label Are we using time labels for the snapshot indices?
* @param snapshots_invoke_stf Are we calling STF when dumping a snapshot?
* @param time The current simulation time.
* @param stf_count The counter of STF outputs.
* @param snap_count The counter of snapshot outputs.
* @param subdir The sub-directory in which the snapshots are written.
* @param basename The common part of the snapshot names.
*/
void io_get_snapshot_filename(char filename[1024], char xmf_filename[1024],
const int use_time_label,
const int snapshots_invoke_stf, const double time,
const int stf_count, const int snap_count,
const char* subdir, const char* basename) {
int snap_number = -1;
if (use_time_label)
snap_number = (int)round(time);
else if (snapshots_invoke_stf)
snap_number = stf_count;
else
snap_number = snap_count;
int number_digits = -1;
if (use_time_label)
number_digits = 6;
else
number_digits = 4;
/* Are we using a sub-dir? */
if (strlen(subdir) > 0) {
sprintf(filename, "%s/%s_%0*d.hdf5", subdir, basename, number_digits,
snap_number);
sprintf(xmf_filename, "%s/%s.xmf", subdir, basename);
} else {
sprintf(filename, "%s_%0*d.hdf5", basename, number_digits, snap_number);
sprintf(xmf_filename, "%s.xmf", basename);
}
}
......@@ -174,4 +174,10 @@ void io_write_output_field_parameter(const char* filename);
void io_make_snapshot_subdir(const char* dirname);
void io_get_snapshot_filename(char filename[1024], char xmf_filename[1024],
const int use_time_label,
const int snapshots_invoke_stf, const double time,
const int stf_count, const int snap_count,
const char* subdir, const char* basename);
#endif /* SWIFT_COMMON_IO_H */
......@@ -3587,22 +3587,6 @@ void engine_dump_snapshot(struct engine *e) {
engine_collect_stars_counter(e);
#endif
/* Determine snapshot location */
char snapshotBase[FILENAME_BUFFER_SIZE];
if (strnlen(e->snapshot_subdir, PARSER_MAX_LINE_SIZE) > 0) {
if (snprintf(snapshotBase, FILENAME_BUFFER_SIZE, "%s/%s",
e->snapshot_subdir,
e->snapshot_base_name) >= FILENAME_BUFFER_SIZE) {
error(
"FILENAME_BUFFER_SIZE is too small for snapshot path and file name");
}
} else {
if (snprintf(snapshotBase, FILENAME_BUFFER_SIZE, "%s",
e->snapshot_base_name) >= FILENAME_BUFFER_SIZE) {
error("FILENAME_BUFFER_SIZE is too small for snapshot file name");
}
}
/* Dump (depending on the chosen strategy) ... */
#if defined(HAVE_HDF5)
#if defined(WITH_MPI)
......@@ -3614,16 +3598,15 @@ void engine_dump_snapshot(struct engine *e) {
} else {
#if defined(HAVE_PARALLEL_HDF5)
write_output_parallel(e, snapshotBase, e->internal_units, e->snapshot_units,
e->nodeID, e->nr_nodes, MPI_COMM_WORLD,
MPI_INFO_NULL);
write_output_parallel(e, e->internal_units, e->snapshot_units, e->nodeID,
e->nr_nodes, MPI_COMM_WORLD, MPI_INFO_NULL);
#else
write_output_serial(e, snapshotBase, e->internal_units, e->snapshot_units,
e->nodeID, e->nr_nodes, MPI_COMM_WORLD, MPI_INFO_NULL);
write_output_serial(e, e->internal_units, e->snapshot_units, e->nodeID,
e->nr_nodes, MPI_COMM_WORLD, MPI_INFO_NULL);
#endif
}
#else
write_output_single(e, snapshotBase, e->internal_units, e->snapshot_units);
write_output_single(e, e->internal_units, e->snapshot_units);
#endif
#endif
......
......@@ -378,7 +378,7 @@ void read_array_parallel(hid_t grp, struct io_props props, size_t N,
* @param N_total The total number of particles to write in this array.
* @param snapshot_units The units used for the data in this snapshot.
*/
void prepare_array_parallel(struct engine* e, hid_t grp, char* fileName,
void prepare_array_parallel(struct engine* e, hid_t grp, const char* fileName,
FILE* xmfFile, char* partTypeGroupName,
struct io_props props, long long N_total,
const struct unit_system* snapshot_units) {
......@@ -1041,12 +1041,12 @@ void read_ic_parallel(char* fileName, const struct unit_system* internal_units,
* @brief Prepares a file for a parallel write.
*
* @param e The #engine.
* @param baseName The base name of the snapshots.
* @param N_total The total number of particles of each type to write.
* @param internal_units The #unit_system used internally.
* @param snapshot_units The #unit_system used in the snapshots.
*/
void prepare_file(struct engine* e, const char* baseName, long long N_total[6],
void prepare_file(struct engine* e, const char* fileName,
const char* xmfFileName, long long N_total[6],
const struct unit_system* internal_units,
const struct unit_system* snapshot_units) {
......@@ -1071,23 +1071,10 @@ void prepare_file(struct engine* e, const char* baseName, long long N_total[6],
int numFiles = 1;
/* First time, we need to create the XMF file */
if (e->snapshot_output_count == 0) xmf_create_file(baseName);
if (e->snapshot_output_count == 0) xmf_create_file(xmfFileName);
/* Prepare the XMF file for the new entry */
xmfFile = xmf_prepare_file(baseName);
/* HDF5 File name */
char fileName[FILENAME_BUFFER_SIZE];
if (e->snapshot_int_time_label_on)
snprintf(fileName, FILENAME_BUFFER_SIZE, "%s_%06i.hdf5", baseName,
(int)round(e->time));
else if (e->snapshot_invoke_stf) {
snprintf(fileName, FILENAME_BUFFER_SIZE, "%s_%04i.hdf5", baseName,
e->stf_output_count);
} else {
snprintf(fileName, FILENAME_BUFFER_SIZE, "%s_%04i.hdf5", baseName,
e->snapshot_output_count);
}
xmfFile = xmf_prepare_file(xmfFileName);
/* Open HDF5 file with the chosen parameters */
hid_t h_file = H5Fcreate(fileName, H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT);
......@@ -1301,7 +1288,6 @@ void prepare_file(struct engine* e, const char* baseName, long long N_total[6],
*its XMF descriptor
*
* @param e The engine containing all the system.
* @param baseName The common part of the snapshot file name.
* @param internal_units The #unit_system used internally
* @param snapshot_units The #unit_system used in the snapshots
* @param mpi_rank The MPI rank of this node.
......@@ -1317,7 +1303,7 @@ void prepare_file(struct engine* e, const char* baseName, long long N_total[6],
* Calls #error() if an error occurs.
*
*/
void write_output_parallel(struct engine* e, const char* baseName,
void write_output_parallel(struct engine* e,
const struct unit_system* internal_units,
const struct unit_system* snapshot_units,
int mpi_rank, int mpi_size, MPI_Comm comm,
......@@ -1389,9 +1375,18 @@ void write_output_parallel(struct engine* e, const char* baseName,
ticks tic = getticks();
#endif
/* File names */
char fileName[FILENAME_BUFFER_SIZE];
char xmfFileName[FILENAME_BUFFER_SIZE];
io_get_snapshot_filename(fileName, xmfFileName, e->snapshot_int_time_label_on,
e->snapshot_invoke_stf, e->time, e->stf_output_count,
e->snapshot_output_count, e->snapshot_subdir,
e->snapshot_base_name);
/* Rank 0 prepares the file */
if (mpi_rank == 0)
prepare_file(e, baseName, N_total, internal_units, snapshot_units);
prepare_file(e, fileName, xmfFileName, N_total, internal_units,
snapshot_units);
MPI_Barrier(MPI_COMM_WORLD);
......@@ -1403,19 +1398,6 @@ void write_output_parallel(struct engine* e, const char* baseName,
tic = getticks();
#endif
/* HDF5 File name */
char fileName[FILENAME_BUFFER_SIZE];
if (e->snapshot_int_time_label_on)
snprintf(fileName, FILENAME_BUFFER_SIZE, "%s_%06i.hdf5", baseName,
(int)round(e->time));
else if (e->snapshot_invoke_stf) {
snprintf(fileName, FILENAME_BUFFER_SIZE, "%s_%04i.hdf5", baseName,
e->stf_output_count);
} else {
snprintf(fileName, FILENAME_BUFFER_SIZE, "%s_%04i.hdf5", baseName,
e->snapshot_output_count);
}
/* Now write the top-level cell structure */
hid_t h_file_cells = 0, h_grp_cells = 0;
if (mpi_rank == 0) {
......
......@@ -44,7 +44,7 @@ void read_ic_parallel(char* fileName, const struct unit_system* internal_units,
int mpi_size, MPI_Comm comm, MPI_Info info,
int nr_threads, int dry_run);
void write_output_parallel(struct engine* e, const char* baseName,
void write_output_parallel(struct engine* e,
const struct unit_system* internal_units,
const struct unit_system* snapshot_units,
int mpi_rank, int mpi_size, MPI_Comm comm,
......
......@@ -841,7 +841,6 @@ void read_ic_serial(char* fileName, const struct unit_system* internal_units,
* @brief Writes an HDF5 output file (GADGET-3 type) with its XMF descriptor
*
* @param e The engine containing all the system.
* @param baseName The common part of the snapshot file name.
* @param internal_units The #unit_system used internally
* @param snapshot_units The #unit_system used in the snapshots
* @param mpi_rank The MPI rank of this node.
......@@ -857,7 +856,7 @@ void read_ic_serial(char* fileName, const struct unit_system* internal_units,
* Calls #error() if an error occurs.
*
*/
void write_output_serial(struct engine* e, const char* baseName,
void write_output_serial(struct engine* e,
const struct unit_system* internal_units,
const struct unit_system* snapshot_units, int mpi_rank,
int mpi_size, MPI_Comm comm, MPI_Info info) {
......@@ -914,16 +913,11 @@ void write_output_serial(struct engine* e, const char* baseName,
/* File name */
char fileName[FILENAME_BUFFER_SIZE];
if (e->snapshot_int_time_label_on)
snprintf(fileName, FILENAME_BUFFER_SIZE, "%s_%06i.hdf5", baseName,
(int)round(e->time));
else if (e->snapshot_invoke_stf) {
snprintf(fileName, FILENAME_BUFFER_SIZE, "%s_%04i.hdf5", baseName,
e->stf_output_count);
} else {
snprintf(fileName, FILENAME_BUFFER_SIZE, "%s_%04i.hdf5", baseName,
e->snapshot_output_count);
}
char xmfFileName[FILENAME_BUFFER_SIZE];
io_get_snapshot_filename(fileName, xmfFileName, e->snapshot_int_time_label_on,
e->snapshot_invoke_stf, e->time, e->stf_output_count,
e->snapshot_output_count, e->snapshot_subdir,
e->snapshot_base_name);
/* Compute offset in the file and total number of particles */
size_t N[swift_type_count] = {Ngas_written, Ndm_written,
......@@ -945,10 +939,10 @@ void write_output_serial(struct engine* e, const char* baseName,
if (mpi_rank == 0) {
/* First time, we need to create the XMF file */
if (e->snapshot_output_count == 0) xmf_create_file(baseName);
if (e->snapshot_output_count == 0) xmf_create_file(xmfFileName);
/* Prepare the XMF file for the new entry */
xmfFile = xmf_prepare_file(baseName);
xmfFile = xmf_prepare_file(xmfFileName);
/* Write the part corresponding to this specific output */
xmf_write_outputheader(xmfFile, fileName, e->time);
......
......@@ -45,7 +45,7 @@ void read_ic_serial(char* fileName, const struct unit_system* internal_units,
double h, double a, int mpi_rank, int mpi_size,
MPI_Comm comm, MPI_Info info, int n_threads, int dry_run);
void write_output_serial(struct engine* e, const char* baseName,
void write_output_serial(struct engine* e,
const struct unit_system* internal_units,
const struct unit_system* snapshot_units, int mpi_rank,
int mpi_size, MPI_Comm comm, MPI_Info info);
......
......@@ -705,7 +705,6 @@ void read_ic_single(const char* fileName,
* @brief Writes an HDF5 output file (GADGET-3 type) with its XMF descriptor
*
* @param e The engine containing all the system.
* @param baseName The common part of the snapshot file name.
* @param internal_units The #unit_system used internally
* @param snapshot_units The #unit_system used in the snapshots
*
......@@ -717,7 +716,7 @@ void read_ic_single(const char* fileName,
* Calls #error() if an error occurs.
*
*/
void write_output_single(struct engine* e, const char* baseName,
void write_output_single(struct engine* e,
const struct unit_system* internal_units,
const struct unit_system* snapshot_units) {
......@@ -777,22 +776,18 @@ void write_output_single(struct engine* e, const char* baseName,
/* File name */
char fileName[FILENAME_BUFFER_SIZE];
if (e->snapshot_int_time_label_on)
snprintf(fileName, FILENAME_BUFFER_SIZE, "%s_%06i.hdf5", baseName,
(int)round(e->time));
else if (e->snapshot_invoke_stf) {
snprintf(fileName, FILENAME_BUFFER_SIZE, "%s_%04i.hdf5", baseName,
e->stf_output_count);
} else
snprintf(fileName, FILENAME_BUFFER_SIZE, "%s_%04i.hdf5", baseName,
e->snapshot_output_count);
char xmfFileName[FILENAME_BUFFER_SIZE];
io_get_snapshot_filename(fileName, xmfFileName, e->snapshot_int_time_label_on,
e->snapshot_invoke_stf, e->time, e->stf_output_count,
e->snapshot_output_count, e->snapshot_subdir,
e->snapshot_base_name);
/* First time, we need to create the XMF file */
if (e->snapshot_output_count == 0) xmf_create_file(baseName);
if (e->snapshot_output_count == 0) xmf_create_file(xmfFileName);
/* Prepare the XMF file for the new entry */
FILE* xmfFile = 0;
xmfFile = xmf_prepare_file(baseName);
xmfFile = xmf_prepare_file(xmfFileName);
/* Write the part corresponding to this specific output */
xmf_write_outputheader(xmfFile, fileName, e->time);
......
......@@ -40,7 +40,7 @@ void read_ic_single(const char* fileName,
int with_cosmology, int cleanup_h, int cleanup_sqrt_a,
double h, double a, int nr_threads, int dry_run);
void write_output_single(struct engine* e, const char* baseName,
void write_output_single(struct engine* e,
const struct unit_system* internal_units,
const struct unit_system* snapshot_units);
......
......@@ -51,15 +51,13 @@ static const char* xmf_basename(const char* hdfFileName) {
/**
* @brief Prepare the XMF file corresponding to a snapshot.
*
* @param baseName The common part of the file name.
* @param fileName The name of the file.
*/
FILE* xmf_prepare_file(const char* baseName) {
FILE* xmf_prepare_file(const char* fileName) {
char buffer[1024];
char fileName[FILENAME_BUFFER_SIZE];
char tempFileName[FILENAME_BUFFER_SIZE];
snprintf(fileName, FILENAME_BUFFER_SIZE, "%s.xmf", baseName);
snprintf(tempFileName, FILENAME_BUFFER_SIZE, "%s_temp.xmf", baseName);
snprintf(tempFileName, FILENAME_BUFFER_SIZE, "%s.temp", fileName);
FILE* xmfFile = fopen(fileName, "r");
FILE* tempFile = fopen(tempFileName, "w");
......@@ -101,11 +99,11 @@ FILE* xmf_prepare_file(const char* baseName) {
*
* @todo Exploit the XML nature of the XMF format to write a proper XML writer
* and simplify all the XMF-related stuff.
*
* @param fileName The name of the file.
*/
void xmf_create_file(const char* baseName) {
void xmf_create_file(const char* fileName) {
char fileName[FILENAME_BUFFER_SIZE];
snprintf(fileName, FILENAME_BUFFER_SIZE, "%s.xmf", baseName);
FILE* xmfFile = fopen(fileName, "w");
if (xmfFile == NULL) error("Unable to create XMF file.");
......@@ -134,7 +132,8 @@ void xmf_create_file(const char* baseName) {
* @param hdfFileName The name of the HDF5 file corresponding to this output.
* @param time The current simulation time.
*/
void xmf_write_outputheader(FILE* xmfFile, char* hdfFileName, float time) {
void xmf_write_outputheader(FILE* xmfFile, const char* hdfFileName,
float time) {
/* Write end of file */
fprintf(xmfFile, "<!-- XMF description for file: %s -->\n", hdfFileName);
......@@ -171,7 +170,7 @@ void xmf_write_outputfooter(FILE* xmfFile, int output, float time) {
* @param N The number of particles to write.
* @param ptype The particle type we are writing.
*/
void xmf_write_groupheader(FILE* xmfFile, char* hdfFileName, size_t N,
void xmf_write_groupheader(FILE* xmfFile, const char* hdfFileName, size_t N,
enum part_type ptype) {
fprintf(xmfFile, "\n<Grid Name=\"%s\" GridType=\"Uniform\">\n",
......
......@@ -26,11 +26,11 @@
#include "common_io.h"
#include "part_type.h"
void xmf_create_file(const char* baseName);
FILE* xmf_prepare_file(const char* baseName);
void xmf_write_outputheader(FILE* xmfFile, char* hdfFileName, float time);
void xmf_create_file(const char* fileName);
FILE* xmf_prepare_file(const char* fileName);
void xmf_write_outputheader(FILE* xmfFile, const char* hdfFileName, float time);
void xmf_write_outputfooter(FILE* xmfFile, int outputCount, float time);
void xmf_write_groupheader(FILE* xmfFile, char* hdfFileName, size_t N,
void xmf_write_groupheader(FILE* xmfFile, const char* hdfFileName, size_t N,
enum part_type ptype);
void xmf_write_groupfooter(FILE* xmfFile, enum part_type ptype);
void xmf_write_line(FILE* xmfFile, const char* fileName,
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment