diff --git a/INSTALL.swift b/INSTALL.swift index 12e7372509601d74cbe8252cba3767c71ed0bc39..bafa8b7c236dd8f7a8d0c97b79b444de4e727e32 100644 --- a/INSTALL.swift +++ b/INSTALL.swift @@ -99,7 +99,7 @@ before you can build it. - HDF5: - A HDF5 library (v. 1.8.x or higher) is required to read and + A HDF5 library (v. 1.10.x or higher) is required to read and write particle data. One of the commands "h5cc" or "h5pcc" should be available. If "h5pcc" is located then a parallel HDF5 built for the version of MPI located should be diff --git a/doc/RTD/source/GettingStarted/compiling_code.rst b/doc/RTD/source/GettingStarted/compiling_code.rst index 26a3b940888ba9103180e920ab0f623ad97bf3cc..9498fe90392b1420b2172bfa35b3febfd40a9874 100644 --- a/doc/RTD/source/GettingStarted/compiling_code.rst +++ b/doc/RTD/source/GettingStarted/compiling_code.rst @@ -31,10 +31,10 @@ To compile SWIFT, you will need the following libraries: HDF5 ~~~~ -Version 1.8.x or higher is required. Input and output files are stored as HDF5 +Version 1.10.x or higher is required. Input and output files are stored as HDF5 and are compatible with the existing GADGET-2 specification. Please consider using a build of parallel-HDF5, as SWIFT can leverage this when writing and -reading snapshots. We recommend using HDF5 > 1.10.x as this is *vastly superior* +reading snapshots. We recommend using HDF5 >= 1.12.x as this is *vastly superior* in parallel. HDF5 is widely available through system package managers. diff --git a/doc/onboardingGuide/source/dependencies.rst b/doc/onboardingGuide/source/dependencies.rst index 217e02d7c0b12e4b8a499b2ac01e3c5e6ba27593..33d64eaa3ca476ed180a13cad0ac92b0ad5992de 100644 --- a/doc/onboardingGuide/source/dependencies.rst +++ b/doc/onboardingGuide/source/dependencies.rst @@ -8,9 +8,9 @@ To compile SWIFT, you will need the following libraries: HDF5 ~~~~ -Version 1.8.x or higher is required. Input and output files are stored as HDF5 +Version 1.10.x or higher is required. Input and output files are stored as HDF5 and are compatible with the GADGET-2 specification. A parallel-HDF5 build -and HDF5 > 1.10.x is recommended when running over MPI. +and HDF5 >= 1.12.x is recommended when running over MPI. MPI ~~~ diff --git a/src/common_io.h b/src/common_io.h index 3e66e574d636ead198e2b82b8eea48051e262bac..69a89fdf285332d26abe233714c36cb066649bab 100644 --- a/src/common_io.h +++ b/src/common_io.h @@ -31,6 +31,8 @@ #define PARTICLE_GROUP_BUFFER_SIZE 50 #define FILENAME_BUFFER_SIZE 150 #define IO_BUFFER_ALIGNMENT 1024 +#define HDF5_LOWEST_FILE_FORMAT_VERSION H5F_LIBVER_V18 +#define HDF5_HIGHEST_FILE_FORMAT_VERSION H5F_LIBVER_LATEST /* Avoid cyclic inclusion problems */ struct cell; diff --git a/src/distributed_io.c b/src/distributed_io.c index 483eeb1631092f01d554ad5f6dc9f22a0b24b223..2634111d29792953867317a742e13e06633d1dfc 100644 --- a/src/distributed_io.c +++ b/src/distributed_io.c @@ -508,8 +508,14 @@ void write_virtual_file(struct engine* e, const char* fileName_base, * specific output */ xmf_write_outputheader(xmfFile, fileName, e->time); + /* Set the minimal API version to avoid issues with advanced features */ + hid_t h_props = H5Pcreate(H5P_FILE_ACCESS); + herr_t err = H5Pset_libver_bounds(h_props, HDF5_LOWEST_FILE_FORMAT_VERSION, + HDF5_HIGHEST_FILE_FORMAT_VERSION); + if (err < 0) error("Error setting the hdf5 API version"); + /* Open HDF5 file with the chosen parameters */ - hid_t h_file = H5Fcreate(fileName, H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT); + hid_t h_file = H5Fcreate(fileName, H5F_ACC_TRUNC, H5P_DEFAULT, h_props); if (h_file < 0) error("Error while opening file '%s'.", fileName); /* Open header to write simulation properties */ @@ -741,8 +747,9 @@ void write_virtual_file(struct engine* e, const char* fileName_base, /* Write LXMF file descriptor */ xmf_write_outputfooter(xmfFile, e->snapshot_output_count, e->time); - /* Close the file for now */ + /* Close the file */ H5Fclose(h_file); + H5Pclose(h_props); #else error( @@ -1002,9 +1009,15 @@ void write_output_distributed(struct engine* e, } } + /* Set the minimal API version to avoid issues with advanced features */ + hid_t h_props = H5Pcreate(H5P_FILE_ACCESS); + herr_t err = H5Pset_libver_bounds(h_props, HDF5_LOWEST_FILE_FORMAT_VERSION, + HDF5_HIGHEST_FILE_FORMAT_VERSION); + if (err < 0) error("Error setting the hdf5 API version"); + /* Open file */ /* message("Opening file '%s'.", fileName); */ - h_file = H5Fcreate(fileName, H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT); + h_file = H5Fcreate(fileName, H5F_ACC_TRUNC, H5P_DEFAULT, h_props); if (h_file < 0) error("Error while opening file '%s'.", fileName); /* Open header to write simulation properties */ @@ -1490,6 +1503,7 @@ void write_output_distributed(struct engine* e, /* Close file */ H5Fclose(h_file); + H5Pclose(h_props); #if H5_VERSION_GE(1, 10, 0) @@ -1512,8 +1526,13 @@ void write_output_distributed(struct engine* e, char fileName_virtual[1030]; sprintf(fileName_virtual, "%s.hdf5", fileName_base); + h_props = H5Pcreate(H5P_FILE_ACCESS); + err = H5Pset_libver_bounds(h_props, HDF5_LOWEST_FILE_FORMAT_VERSION, + HDF5_HIGHEST_FILE_FORMAT_VERSION); + if (err < 0) error("Error setting the hdf5 API version"); + /* Open the snapshot on rank 0 */ - h_file_cells = H5Fopen(fileName_virtual, H5F_ACC_RDWR, H5P_DEFAULT); + h_file_cells = H5Fopen(fileName_virtual, H5F_ACC_RDWR, h_props); if (h_file_cells < 0) error("Error while opening file '%s' on rank %d.", fileName_virtual, mpi_rank); @@ -1541,6 +1560,7 @@ void write_output_distributed(struct engine* e, if (mpi_rank == 0) { H5Gclose(h_grp_cells); H5Fclose(h_file_cells); + H5Pclose(h_props); } #endif diff --git a/src/fof_catalogue_io.c b/src/fof_catalogue_io.c index 4b44724267f00f642358040be957bc36a2f56c36..e290341deb5d6af668c925ea413e66b984f49699 100644 --- a/src/fof_catalogue_io.c +++ b/src/fof_catalogue_io.c @@ -305,8 +305,14 @@ void write_fof_virtual_file(const struct fof_props* props, sprintf(file_name_base, "%s/%s", subdir_name, base); sprintf(file_name, "%s/%s.hdf5", subdir_name, base); + /* Set the minimal API version to avoid issues with advanced features */ + hid_t h_props = H5Pcreate(H5P_FILE_ACCESS); + herr_t err = H5Pset_libver_bounds(h_props, HDF5_LOWEST_FILE_FORMAT_VERSION, + HDF5_HIGHEST_FILE_FORMAT_VERSION); + if (err < 0) error("Error setting the hdf5 API version"); + /* Open HDF5 file with the chosen parameters */ - hid_t h_file = H5Fcreate(file_name, H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT); + hid_t h_file = H5Fcreate(file_name, H5F_ACC_TRUNC, H5P_DEFAULT, h_props); if (h_file < 0) error("Error while opening file '%s'.", file_name); /* Start by writing the header */ @@ -356,6 +362,7 @@ void write_fof_virtual_file(const struct fof_props* props, /* Close everything */ H5Gclose(h_grp); H5Fclose(h_file); + H5Pclose(h_props); #endif } @@ -533,7 +540,13 @@ void write_fof_hdf5_catalogue(const struct fof_props* props, e->snapshot_output_count); #endif - hid_t h_file = H5Fcreate(file_name, H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT); + /* Set the minimal API version to avoid issues with advanced features */ + hid_t h_props = H5Pcreate(H5P_FILE_ACCESS); + herr_t err = H5Pset_libver_bounds(h_props, HDF5_LOWEST_FILE_FORMAT_VERSION, + HDF5_HIGHEST_FILE_FORMAT_VERSION); + if (err < 0) error("Error setting the hdf5 API version"); + + hid_t h_file = H5Fcreate(file_name, H5F_ACC_TRUNC, H5P_DEFAULT, h_props); if (h_file < 0) error("Error while opening file '%s'.", file_name); /* Compute the number of groups */ @@ -593,6 +606,7 @@ void write_fof_hdf5_catalogue(const struct fof_props* props, /* Close everything */ H5Gclose(h_grp); H5Fclose(h_file); + H5Pclose(h_props); #ifdef WITH_MPI #if H5_VERSION_GE(1, 10, 0) diff --git a/src/lightcone/lightcone.c b/src/lightcone/lightcone.c index d04076384afbbd52f7ed294c0e1d7494db9089b2..7a431ed83791dcac27079e66a2fb079be9141f78 100644 --- a/src/lightcone/lightcone.c +++ b/src/lightcone/lightcone.c @@ -864,7 +864,7 @@ void lightcone_flush_particle_buffers(struct lightcone_props *props, double a, if ((types_to_flush > 0) || (end_file && props->file_needs_finalizing)) { /* We have data to flush, so open or create the output file */ - hid_t file_id; + hid_t file_id, h_props; char fname[FILENAME_BUFFER_SIZE]; if (props->start_new_file) { @@ -873,8 +873,14 @@ void lightcone_flush_particle_buffers(struct lightcone_props *props, double a, particle_file_name(fname, FILENAME_BUFFER_SIZE, props->subdir, props->basename, props->current_file, engine_rank); + h_props = H5Pcreate(H5P_FILE_ACCESS); + herr_t err = + H5Pset_libver_bounds(h_props, HDF5_LOWEST_FILE_FORMAT_VERSION, + HDF5_HIGHEST_FILE_FORMAT_VERSION); + if (err < 0) error("Error setting the hdf5 API version"); + /* Create the file */ - file_id = H5Fcreate(fname, H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT); + file_id = H5Fcreate(fname, H5F_ACC_TRUNC, H5P_DEFAULT, h_props); if (file_id < 0) error("Unable to create new lightcone file: %s", fname); /* This new file has not been finalized yet */ @@ -924,10 +930,16 @@ void lightcone_flush_particle_buffers(struct lightcone_props *props, double a, } else { + h_props = H5Pcreate(H5P_FILE_ACCESS); + herr_t err = + H5Pset_libver_bounds(h_props, HDF5_LOWEST_FILE_FORMAT_VERSION, + HDF5_HIGHEST_FILE_FORMAT_VERSION); + if (err < 0) error("Error setting the hdf5 API version"); + /* Re-open an existing file */ particle_file_name(fname, FILENAME_BUFFER_SIZE, props->subdir, props->basename, props->current_file, engine_rank); - file_id = H5Fopen(fname, H5F_ACC_RDWR, H5P_DEFAULT); + file_id = H5Fopen(fname, H5F_ACC_RDWR, h_props); if (file_id < 0) error("Unable to open current lightcone file: %s", fname); } @@ -969,6 +981,7 @@ void lightcone_flush_particle_buffers(struct lightcone_props *props, double a, /* We're done updating the output file */ H5Fclose(file_id); + H5Pclose(h_props); } /* If we need to start a new file next time, record this */ @@ -1101,6 +1114,12 @@ void lightcone_dump_completed_shells(struct lightcone_props *props, /* Create the output file for this shell */ hid_t fapl_id = H5Pcreate(H5P_FILE_ACCESS); + /* Set the minimal API version to avoid issues with advanced features */ + herr_t err = + H5Pset_libver_bounds(fapl_id, HDF5_LOWEST_FILE_FORMAT_VERSION, + HDF5_HIGHEST_FILE_FORMAT_VERSION); + if (err < 0) error("Error setting the hdf5 API version"); + /* Set MPI collective mode, if necessary */ int collective = 0; #ifdef WITH_MPI @@ -1710,8 +1729,13 @@ void lightcone_write_index(struct lightcone_props *props, check_snprintf(fname, FILENAME_BUFFER_SIZE, "%s/%s_index.hdf5", props->subdir, props->basename); + hid_t h_props = H5Pcreate(H5P_FILE_ACCESS); + herr_t err = H5Pset_libver_bounds(h_props, HDF5_LOWEST_FILE_FORMAT_VERSION, + HDF5_HIGHEST_FILE_FORMAT_VERSION); + if (err < 0) error("Error setting the hdf5 API version"); + /* Create the file */ - hid_t file_id = H5Fcreate(fname, H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT); + hid_t file_id = H5Fcreate(fname, H5F_ACC_TRUNC, H5P_DEFAULT, h_props); /* Write number of MPI ranks and number of files */ hid_t group_id = @@ -1755,6 +1779,7 @@ void lightcone_write_index(struct lightcone_props *props, H5Gclose(group_id); H5Fclose(file_id); + H5Pclose(h_props); } free(current_file_on_rank); diff --git a/src/line_of_sight.c b/src/line_of_sight.c index 519aa09d89b58234fba501ea54dffd14008e5764..1a63a17954d67da46594e9563ebefe29a9f0e711 100644 --- a/src/line_of_sight.c +++ b/src/line_of_sight.c @@ -770,14 +770,21 @@ void do_line_of_sight(struct engine *e) { #endif /* Node 0 creates the HDF5 file. */ - hid_t h_file = -1, h_grp = -1; + hid_t h_file = -1, h_grp = -1, h_props = -1; char fileName[256], groupName[200]; if (e->nodeID == 0) { sprintf(fileName, "%s_%04i.hdf5", LOS_params->basename, e->los_output_count); if (verbose) message("Creating LOS file: %s", fileName); - h_file = H5Fcreate(fileName, H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT); + + /* Set the minimal API version to avoid issues with advanced features */ + h_props = H5Pcreate(H5P_FILE_ACCESS); + hid_t err = H5Pset_libver_bounds(h_props, HDF5_LOWEST_FILE_FORMAT_VERSION, + HDF5_HIGHEST_FILE_FORMAT_VERSION); + if (err < 0) error("Error setting the hdf5 API version"); + + h_file = H5Fcreate(fileName, H5F_ACC_TRUNC, H5P_DEFAULT, h_props); if (h_file < 0) error("Error while opening file '%s'.", fileName); } @@ -1082,6 +1089,7 @@ void do_line_of_sight(struct engine *e) { /* Close HDF5 file */ H5Fclose(h_file); + H5Pclose(h_props); } /* Up the LOS counter. */ diff --git a/src/parallel_io.c b/src/parallel_io.c index 51b0dac1cb498f7d203c3d8555c4629ec3ea66f7..cf67c9fe9d775f7b6678aa684dc86572792e7435 100644 --- a/src/parallel_io.c +++ b/src/parallel_io.c @@ -1191,8 +1191,14 @@ void prepare_file(struct engine* e, const char* fileName, /* Prepare the XMF file for the new entry */ xmfFile = xmf_prepare_file(xmfFileName); + /* Set the minimal API version to avoid issues with advanced features */ + hid_t h_props = H5Pcreate(H5P_FILE_ACCESS); + herr_t err = H5Pset_libver_bounds(h_props, HDF5_LOWEST_FILE_FORMAT_VERSION, + HDF5_HIGHEST_FILE_FORMAT_VERSION); + if (err < 0) error("Error setting the hdf5 API version"); + /* Open HDF5 file with the chosen parameters */ - hid_t h_file = H5Fcreate(fileName, H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT); + hid_t h_file = H5Fcreate(fileName, H5F_ACC_TRUNC, H5P_DEFAULT, h_props); if (h_file < 0) error("Error while opening file '%s'.", fileName); /* Write the part of the XMF file corresponding to this @@ -1430,6 +1436,7 @@ void prepare_file(struct engine* e, const char* fileName, /* Close the file for now */ H5Fclose(h_file); + H5Pclose(h_props); } /** @@ -1685,6 +1692,11 @@ void write_output_parallel(struct engine* e, /* Prepare some file-access properties */ hid_t plist_id = H5Pcreate(H5P_FILE_ACCESS); + /* Set the minimal API version to avoid issues with advanced features */ + herr_t err = H5Pset_libver_bounds(plist_id, HDF5_LOWEST_FILE_FORMAT_VERSION, + HDF5_HIGHEST_FILE_FORMAT_VERSION); + if (err < 0) error("Error setting the hdf5 API version"); + /* Set some MPI-IO parameters */ // MPI_Info_set(info, "IBM_largeblock_io", "true"); MPI_Info_set(info, "romio_cb_write", "enable"); diff --git a/src/serial_io.c b/src/serial_io.c index d6a3c9904a098a953ec1a5640b02da14a043c486..8e8cc9f5d0cc6a570022e4fc9874a62a5fe152dc 100644 --- a/src/serial_io.c +++ b/src/serial_io.c @@ -782,7 +782,14 @@ void read_ic_serial(char* fileName, const struct unit_system* internal_units, /* Is it this rank's turn to read ? */ if (rank == mpi_rank) { - h_file = H5Fopen(fileName, H5F_ACC_RDONLY, H5P_DEFAULT); + /* Set the minimal API version to avoid issues with advanced features */ + hid_t h_props = H5Pcreate(H5P_FILE_ACCESS); + herr_t err = + H5Pset_libver_bounds(h_props, HDF5_LOWEST_FILE_FORMAT_VERSION, + HDF5_HIGHEST_FILE_FORMAT_VERSION); + if (err < 0) error("Error setting the hdf5 API version"); + + h_file = H5Fopen(fileName, H5F_ACC_RDONLY, h_props); if (h_file < 0) error("Error while opening file '%s' on rank %d.", fileName, mpi_rank); @@ -889,6 +896,7 @@ void read_ic_serial(char* fileName, const struct unit_system* internal_units, /* Close file */ H5Fclose(h_file); + H5Pclose(h_props); } /* Wait for the read of the reading to complete */ @@ -1165,9 +1173,15 @@ void write_output_serial(struct engine* e, /* Write the part corresponding to this specific output */ xmf_write_outputheader(xmfFile, fileName, e->time); + /* Set the minimal API version to avoid issues with advanced features */ + hid_t h_props = H5Pcreate(H5P_FILE_ACCESS); + herr_t err = H5Pset_libver_bounds(h_props, HDF5_LOWEST_FILE_FORMAT_VERSION, + HDF5_HIGHEST_FILE_FORMAT_VERSION); + if (err < 0) error("Error setting the hdf5 API version"); + /* Open file */ /* message("Opening file '%s'.", fileName); */ - h_file = H5Fcreate(fileName, H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT); + h_file = H5Fcreate(fileName, H5F_ACC_TRUNC, H5P_DEFAULT, h_props); if (h_file < 0) error("Error while opening file '%s'.", fileName); /* Open header to write simulation properties */ @@ -1307,14 +1321,21 @@ void write_output_serial(struct engine* e, /* Close file */ H5Fclose(h_file); + H5Pclose(h_props); } /* Now write the top-level cell structure */ - hid_t h_file_cells = 0, h_grp_cells = 0; + hid_t h_file_cells = 0, h_grp_cells = 0, h_props_cells = 0; if (mpi_rank == 0) { + /* Set the minimal API version to avoid issues with advanced features */ + h_props_cells = H5Pcreate(H5P_FILE_ACCESS); + herr_t err = H5Pset_libver_bounds(h_props, HDF5_LOWEST_FILE_FORMAT_VERSION, + HDF5_HIGHEST_FILE_FORMAT_VERSION); + if (err < 0) error("Error setting the hdf5 API version"); + /* Open the snapshot on rank 0 */ - h_file_cells = H5Fopen(fileName, H5F_ACC_RDWR, H5P_DEFAULT); + h_file_cells = H5Fopen(fileName, H5F_ACC_RDWR, h_props_cells); if (h_file_cells < 0) error("Error while opening file '%s' on rank %d.", fileName, mpi_rank); @@ -1343,7 +1364,14 @@ void write_output_serial(struct engine* e, /* Is it this rank's turn to write ? */ if (rank == mpi_rank) { - h_file = H5Fopen(fileName, H5F_ACC_RDWR, H5P_DEFAULT); + /* Set the minimal API version to avoid issues with advanced features */ + hid_t h_props = H5Pcreate(H5P_FILE_ACCESS); + herr_t err = + H5Pset_libver_bounds(h_props, HDF5_LOWEST_FILE_FORMAT_VERSION, + HDF5_HIGHEST_FILE_FORMAT_VERSION); + if (err < 0) error("Error setting the hdf5 API version"); + + h_file = H5Fopen(fileName, H5F_ACC_RDWR, h_props); if (h_file < 0) error("Error while opening file '%s' on rank %d.", fileName, mpi_rank); @@ -1706,6 +1734,7 @@ void write_output_serial(struct engine* e, /* Close file */ H5Fclose(h_file); + H5Pclose(h_props); } /* Wait for the read of the reading to complete */ diff --git a/src/single_io.c b/src/single_io.c index c63be580b02106b0b9d21a70ae9a592e63ed2c89..5ea174ae970026669d0109ab93e1db3c835712b9 100644 --- a/src/single_io.c +++ b/src/single_io.c @@ -990,9 +990,15 @@ void write_output_single(struct engine* e, }; + /* Set the minimal API version to avoid issues with advanced features */ + hid_t h_props = H5Pcreate(H5P_FILE_ACCESS); + herr_t err = H5Pset_libver_bounds(h_props, HDF5_LOWEST_FILE_FORMAT_VERSION, + HDF5_HIGHEST_FILE_FORMAT_VERSION); + if (err < 0) error("Error setting the hdf5 API version"); + /* Open file */ /* message("Opening file '%s'.", fileName); */ - h_file = H5Fcreate(fileName, H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT); + h_file = H5Fcreate(fileName, H5F_ACC_TRUNC, H5P_DEFAULT, h_props); if (h_file < 0) error("Error while opening file '%s'.", fileName); /* Open header to write simulation properties */ @@ -1481,6 +1487,7 @@ void write_output_single(struct engine* e, /* Close file */ H5Fclose(h_file); + H5Pclose(h_props); e->snapshot_output_count++; if (e->snapshot_invoke_stf) e->stf_output_count++;