From 5bd8acc4bcc7e0c2186bf3f7bbc9d577a8109a91 Mon Sep 17 00:00:00 2001 From: David Wells Date: Wed, 30 Dec 2020 20:28:40 -0500 Subject: [PATCH] Refactor the HDF5 abort code. --- source/base/hdf5.cc | 244 ++++++++++---------------------------------- 1 file changed, 56 insertions(+), 188 deletions(-) diff --git a/source/base/hdf5.cc b/source/base/hdf5.cc index 3c166cae65..78548a605c 100644 --- a/source/base/hdf5.cc +++ b/source/base/hdf5.cc @@ -25,6 +25,50 @@ DEAL_II_NAMESPACE_OPEN namespace HDF5 { + namespace internal + { + namespace HDF5ObjectImplementation + { + /** + * Abort, should there be an exception being processed (see the error + * message). + */ + void + check_exception(const std::string &type, const std::string &name) + { +# ifdef DEAL_II_WITH_MPI +# if __cpp_lib_uncaught_exceptions >= 201411 + // std::uncaught_exception() is deprecated in c++17 + if (std::uncaught_exceptions() != 0) +# else + if (std::uncaught_exception() == true) +# endif + { + std::cerr + << "---------------------------------------------------------\n" + << "HDF5 " + type + " objects call " + name + + " to end access to\n" + << "them and release any resources they acquired. This call\n" + << "requires MPI synchronization. Since an exception is\n" + << "currently uncaught, this synchronization would likely\n" + << "deadlock because only the current process is trying to\n" + << "destroy the object. As a consequence, the program will be\n" + << "aborted and the HDF5 might be corrupted.\n" + << "---------------------------------------------------------" + << std::endl; + + MPI_Abort(MPI_COMM_WORLD, 1); + } +# else + (void)type; + (void)name; +# endif + } + } // namespace HDF5ObjectImplementation + } // namespace internal + + + HDF5Object::HDF5Object(const std::string &name, const bool mpi) : name(name) , mpi(mpi) @@ -50,80 +94,22 @@ namespace HDF5 , global_no_collective_cause(H5D_MPIO_SET_INDEPENDENT) { hdf5_reference = std::shared_ptr(new hid_t, [](hid_t *pointer) { -# ifdef DEAL_II_WITH_MPI -# if __cpp_lib_uncaught_exceptions >= 201411 - // std::uncaught_exception() is deprecated in c++17 - if (std::uncaught_exceptions() == 0) -# else - if (std::uncaught_exception() == false) -# endif - { - // Release the HDF5 resource - const herr_t ret = H5Dclose(*pointer); - AssertNothrow(ret >= 0, ExcInternalError()); - (void)ret; - delete pointer; - } - else - { - std::cerr - << "---------------------------------------------------------\n" - << "HDF5 DataSet objects call H5Dclose to end access to the\n" - << "dataset and release resources used by it. This call\n" - << "requires MPI synchronization. Since an exception is\n" - << "currently uncaught, this synchronization will be skipped\n" - << "to avoid a possible deadlock. As a result the HDF5 file\n" - << "might be corrupted.\n" - << "---------------------------------------------------------" - << std::endl; - - MPI_Abort(MPI_COMM_WORLD, 1); - } -# else + internal::HDF5ObjectImplementation::check_exception("DataSet", + "H5Dclose"); // Release the HDF5 resource const herr_t ret = H5Dclose(*pointer); AssertNothrow(ret >= 0, ExcInternalError()); (void)ret; delete pointer; -# endif }); - dataspace = std::shared_ptr(new hid_t, [](hid_t *pointer) { -# ifdef DEAL_II_WITH_MPI -# if __cpp_lib_uncaught_exceptions >= 201411 - // std::uncaught_exception() is deprecated in c++17 - if (std::uncaught_exceptions() == 0) -# else - if (std::uncaught_exception() == false) -# endif - { - // Release the HDF5 resource - const herr_t ret = H5Sclose(*pointer); - AssertNothrow(ret >= 0, ExcInternalError()); - (void)ret; - delete pointer; - } - else - { - std::cerr - << "---------------------------------------------------------\n" - << "HDF5 DataSet objects call H5Sclose to end access to the\n" - << "dataset and release resources used by it. This call\n" - << "requires MPI synchronization. Since an exception is\n" - << "currently uncaught, this synchronization will be skipped\n" - << "to avoid a possible deadlock. As a result the HDF5 file\n" - << "might be corrupted.\n" - << "---------------------------------------------------------" - << std::endl; - - MPI_Abort(MPI_COMM_WORLD, 1); - } -# else + dataspace = std::shared_ptr(new hid_t, [](hid_t *pointer) { + internal::HDF5ObjectImplementation::check_exception("DataSpace", + "H5Sclose"); // Release the HDF5 resource const herr_t ret = H5Sclose(*pointer); AssertNothrow(ret >= 0, ExcInternalError()); (void)ret; delete pointer; -# endif }); // rank_ret can take a negative value if the functions @@ -167,80 +153,22 @@ namespace HDF5 , global_no_collective_cause(H5D_MPIO_SET_INDEPENDENT) { hdf5_reference = std::shared_ptr(new hid_t, [](hid_t *pointer) { -# ifdef DEAL_II_WITH_MPI -# if __cpp_lib_uncaught_exceptions >= 201411 - // std::uncaught_exception() is deprecated in c++17 - if (std::uncaught_exceptions() == 0) -# else - if (std::uncaught_exception() == false) -# endif - { - // Release the HDF5 resource - const herr_t ret = H5Dclose(*pointer); - AssertNothrow(ret >= 0, ExcInternalError()); - (void)ret; - delete pointer; - } - else - { - std::cerr - << "---------------------------------------------------------\n" - << "HDF5 DataSet objects call H5Dclose to end access to the\n" - << "dataset and release resources used by it. This call\n" - << "requires MPI synchronization. Since an exception is\n" - << "currently uncaught, this synchronization will be skipped\n" - << "to avoid a possible deadlock. As a result the HDF5 file\n" - << "might be corrupted.\n" - << "---------------------------------------------------------" - << std::endl; - - MPI_Abort(MPI_COMM_WORLD, 1); - } -# else + internal::HDF5ObjectImplementation::check_exception("DataSet", + "H5Dclose"); // Release the HDF5 resource const herr_t ret = H5Dclose(*pointer); AssertNothrow(ret >= 0, ExcInternalError()); (void)ret; delete pointer; -# endif }); - dataspace = std::shared_ptr(new hid_t, [](hid_t *pointer) { -# ifdef DEAL_II_WITH_MPI -# if __cpp_lib_uncaught_exceptions >= 201411 - // std::uncaught_exception() is deprecated in c++17 - if (std::uncaught_exceptions() == 0) -# else - if (std::uncaught_exception() == false) -# endif - { - // Release the HDF5 resource - const herr_t ret = H5Sclose(*pointer); - AssertNothrow(ret >= 0, ExcInternalError()); - (void)ret; - delete pointer; - } - else - { - std::cerr - << "---------------------------------------------------------\n" - << "HDF5 DataSet objects call H5Sclose to end access to the\n" - << "dataspace and release resources used by it. This call\n" - << "requires MPI synchronization. Since an exception is\n" - << "currently uncaught, this synchronization will be skipped\n" - << "to avoid a possible deadlock. As a result the HDF5 file\n" - << "might be corrupted.\n" - << "---------------------------------------------------------" - << std::endl; - - MPI_Abort(MPI_COMM_WORLD, 1); - } -# else + dataspace = std::shared_ptr(new hid_t, [](hid_t *pointer) { + internal::HDF5ObjectImplementation::check_exception("DataSpace", + "H5Sclose"); // Release the HDF5 resource const herr_t ret = H5Sclose(*pointer); AssertNothrow(ret >= 0, ExcInternalError()); (void)ret; delete pointer; -# endif }); *dataspace = H5Screate_simple(rank, dimensions.data(), nullptr); @@ -403,42 +331,12 @@ namespace HDF5 : HDF5Object(name, mpi) { hdf5_reference = std::shared_ptr(new hid_t, [](hid_t *pointer) { -# ifdef DEAL_II_WITH_MPI -# if __cpp_lib_uncaught_exceptions >= 201411 - // std::uncaught_exception() is deprecated in c++17 - if (std::uncaught_exceptions() == 0) -# else - if (std::uncaught_exception() == false) -# endif - { - // Release the HDF5 resource - const herr_t ret = H5Gclose(*pointer); - AssertNothrow(ret >= 0, ExcInternalError()); - (void)ret; - delete pointer; - } - else - { - std::cerr - << "---------------------------------------------------------\n" - << "HDF5 Group objects call H5Gclose to end access to the\n" - << "group and release resources used by it. This call\n" - << "requires MPI synchronization. Since an exception is\n" - << "currently uncaught, this synchronization will be skipped\n" - << "to avoid a possible deadlock. As a result the HDF5 file\n" - << "might be corrupted.\n" - << "---------------------------------------------------------" - << std::endl; - - MPI_Abort(MPI_COMM_WORLD, 1); - } -# else + internal::HDF5ObjectImplementation::check_exception("Group", "H5Gclose"); // Release the HDF5 resource const herr_t ret = H5Gclose(*pointer); AssertNothrow(ret >= 0, ExcInternalError()); (void)ret; delete pointer; -# endif }); switch (mode) { @@ -522,42 +420,12 @@ namespace HDF5 : Group(name, mpi) { hdf5_reference = std::shared_ptr(new hid_t, [](hid_t *pointer) { -# ifdef DEAL_II_WITH_MPI -# if __cpp_lib_uncaught_exceptions >= 201411 - // std::uncaught_exception() is deprecated in c++17 - if (std::uncaught_exceptions() == 0) -# else - if (std::uncaught_exception() == false) -# endif - { - // Release the HDF5 resource - const herr_t err = H5Fclose(*pointer); - AssertNothrow(err >= 0, ExcInternalError()); - (void)err; - delete pointer; - } - else - { - std::cerr - << "---------------------------------------------------------\n" - << "HDF5 File objects call H5Fclose to end access to the\n" - << "file and release resources used by it. This call\n" - << "requires MPI synchronization. Since an exception is\n" - << "currently uncaught, this synchronization will be skipped\n" - << "to avoid a possible deadlock. As a result the HDF5 file\n" - << "might be corrupted.\n" - << "---------------------------------------------------------" - << std::endl; - - MPI_Abort(MPI_COMM_WORLD, 1); - } -# else + internal::HDF5ObjectImplementation::check_exception("File", "H5Fclose"); // Release the HDF5 resource const herr_t err = H5Fclose(*pointer); AssertNothrow(err >= 0, ExcInternalError()); (void)err; delete pointer; -# endif }); hid_t plist; -- 2.39.5