From: Bruno Turcksin <bruno.turcksin@gmail.com>
Date: Mon, 29 Jan 2018 15:44:59 +0000 (-0500)
Subject: Add AssertCusparse macro to check that a cuSPARSE routine was successful
X-Git-Tag: v9.0.0-rc1~493^2~1
X-Git-Url: https://gitweb.dealii.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=c8c8cba4015b72999bbc1e815c044da4560ede08;p=dealii.git

Add AssertCusparse macro to check that a cuSPARSE routine was successful
---

diff --git a/include/deal.II/base/exceptions.h b/include/deal.II/base/exceptions.h
index d16fa34125..b5c9d3e030 100644
--- a/include/deal.II/base/exceptions.h
+++ b/include/deal.II/base/exceptions.h
@@ -22,6 +22,11 @@
 #include <string>
 #include <ostream>
 
+#ifdef DEAL_II_WITH_CUDA
+#include <cusparse.h>
+#endif
+
+
 DEAL_II_NAMESPACE_OPEN
 
 
@@ -314,6 +319,13 @@ namespace deal_II_exceptions
                               const char       *cond,
                               const char       *exc_name,
                               ExceptionBase     e) noexcept;
+#ifdef DEAL_II_WITH_CUDA
+    /**
+     * Return a string given an error code. This is similar to the cudaGetErrorString
+     * function but there is no equivalent function for cuSPARSE.
+     */
+    std::string get_cusparse_error_string(const cusparseStatus_t error_code);
+#endif
   } /*namespace internals*/
 
 } /*namespace deal_II_exceptions*/
@@ -1131,6 +1143,13 @@ namespace StandardExceptions
   DeclException1 (ExcCudaError,
                   char *,
                   << arg1);
+  /**
+   * This exception is raised if an error happened in a cuSPARSE function.
+   */
+  DeclException1 (ExcCusparseError,
+                  std::string,
+                  << "There was an error in a cuSPARSE function: "
+                  << arg1);
 #endif
 //@}
 
@@ -1246,6 +1265,18 @@ namespace StandardExceptions
  */
 #define AssertCuda(error_code) Assert(error_code == cudaSuccess, \
                                       dealii::ExcCudaError(cudaGetErrorString(error_code)))
+
+/**
+ * An assertion that checks that the error code produced by calling a cuSPARSE
+ * routine is equal to CUSPARSE_STATUS_SUCCESS.
+ *
+ * @ingroup Exceptions
+ * @author Bruno Turcksin, 2018
+ */
+#define AssertCusparse(error_code) Assert(error_code == CUSPARSE_STATUS_SUCCESS, \
+                                          dealii::ExcCusparseError( \
+                                              dealii::deal_II_exceptions::internals:: \
+                                              get_cusparse_error_string(error_code)))
 #endif
 
 using namespace StandardExceptions;
diff --git a/source/base/exceptions.cc b/source/base/exceptions.cc
index 52c23a70c0..64f8f31425 100644
--- a/source/base/exceptions.cc
+++ b/source/base/exceptions.cc
@@ -484,6 +484,53 @@ namespace deal_II_exceptions
         }
     }
 
+
+
+#ifdef DEAL_II_WITH_CUDA
+    std::string get_cusparse_error_string(const cusparseStatus_t error_code)
+    {
+      switch (error_code)
+        {
+        case CUSPARSE_STATUS_NOT_INITIALIZED:
+        {
+          return "The cuSPARSE library was not initialized";
+        }
+        case CUSPARSE_STATUS_ALLOC_FAILED:
+        {
+          return "Resource allocation failed inside the cuSPARSE library";
+        }
+        case CUSPARSE_STATUS_INVALID_VALUE:
+        {
+          return "An unsupported value of parameter was passed to the function";
+        }
+        case CUSPARSE_STATUS_ARCH_MISMATCH:
+        {
+          return "The function requires a feature absent from the device architecture";
+        }
+        case CUSPARSE_STATUS_MAPPING_ERROR:
+        {
+          return "An access to GPU memory space failed";
+        }
+        case CUSPARSE_STATUS_EXECUTION_FAILED:
+        {
+          return "The GPU program failed to execute";
+        }
+        case CUSPARSE_STATUS_INTERNAL_ERROR:
+        {
+          return "An internal cuSPARSE operation failed";
+        }
+        case CUSPARSE_STATUS_MATRIX_TYPE_NOT_SUPPORTED:
+        {
+          return "The matrix type is not supported by this function";
+        }
+        default:
+        {
+          return "Unknown error";
+        }
+        }
+    }
+#endif
+
   } /*namespace internals*/
 } /*namespace deal_II_exceptions*/