From: Daniel Garcia-Sanchez Date: Wed, 30 Dec 2020 21:14:05 +0000 (+0100) Subject: Avoid MPI calls in the HDF5 destructors when there is an exception X-Git-Tag: v9.3.0-rc1~701^2 X-Git-Url: https://gitweb.dealii.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=refs%2Fpull%2F11440%2Fhead;p=dealii.git Avoid MPI calls in the HDF5 destructors when there is an exception --- diff --git a/source/base/hdf5.cc b/source/base/hdf5.cc index 9a93bc92b2..3c166cae65 100644 --- a/source/base/hdf5.cc +++ b/source/base/hdf5.cc @@ -50,18 +50,80 @@ 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 // 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) { + 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 // 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