]> https://gitweb.dealii.org/ - dealii.git/commitdiff
Avoid MPI calls in the HDF5 destructors when there is an exception
authorDaniel Garcia-Sanchez <daniel.garcia-sanchez@insp.upmc.fr>
Wed, 23 Dec 2020 08:58:11 +0000 (09:58 +0100)
committerDaniel Garcia-Sanchez <daniel.garcia-sanchez@insp.upmc.fr>
Wed, 23 Dec 2020 08:58:11 +0000 (09:58 +0100)
source/base/hdf5.cc

index 2575786a8162c16efed58189750a7198c543fdf1..9a93bc92b236ec6a17aae3a99e3ddb88fe17f359 100644 (file)
@@ -105,18 +105,80 @@ namespace HDF5
     , global_no_collective_cause(H5D_MPIO_SET_INDEPENDENT)
   {
     hdf5_reference = std::shared_ptr<hid_t>(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<hid_t>(new hid_t, [](hid_t *pointer) {
+    dataspace = std::shared_ptr<hid_t>(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
       // 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);
@@ -279,11 +341,42 @@ namespace HDF5
     : HDF5Object(name, mpi)
   {
     hdf5_reference = std::shared_ptr<hid_t>(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
       // Release the HDF5 resource
       const herr_t ret = H5Gclose(*pointer);
       AssertNothrow(ret >= 0, ExcInternalError());
       (void)ret;
       delete pointer;
+#  endif
     });
     switch (mode)
       {
@@ -367,11 +460,42 @@ namespace HDF5
     : Group(name, mpi)
   {
     hdf5_reference = std::shared_ptr<hid_t>(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
       // Release the HDF5 resource
       const herr_t err = H5Fclose(*pointer);
       AssertNothrow(err >= 0, ExcInternalError());
       (void)err;
       delete pointer;
+#  endif
     });
 
     hid_t  plist;

In the beginning the Universe was created. This has made a lot of people very angry and has been widely regarded as a bad move.

Douglas Adams


Typeset in Trocchi and Trocchi Bold Sans Serif.