opm-simulators
cusparse_safe_call.hpp
1 /*
2  Copyright 2022-2023 SINTEF AS
3 
4  This file is part of the Open Porous Media project (OPM).
5 
6  OPM is free software: you can redistribute it and/or modify
7  it under the terms of the GNU General Public License as published by
8  the Free Software Foundation, either version 3 of the License, or
9  (at your option) any later version.
10 
11  OPM is distributed in the hope that it will be useful,
12  but WITHOUT ANY WARRANTY; without even the implied warranty of
13  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  GNU General Public License for more details.
15 
16  You should have received a copy of the GNU General Public License
17  along with OPM. If not, see <http://www.gnu.org/licenses/>.
18 */
19 #ifndef OPM_CUSPARSE_SAFE_CALL_HPP
20 #define OPM_CUSPARSE_SAFE_CALL_HPP
21 #include <cusparse.h>
22 #include <exception>
23 #include <fmt/core.h>
24 #include <opm/common/ErrorMacros.hpp>
25 #include <opm/common/OpmLog/OpmLog.hpp>
26 
27 namespace Opm::gpuistl::detail
28 {
29 
30 #define CHECK_CUSPARSE_ERROR_TYPE(code, x) \
31  if (code == x) { \
32  return #x; \
33  }
34 
39 inline std::string
41 {
42  CHECK_CUSPARSE_ERROR_TYPE(code, CUSPARSE_STATUS_SUCCESS);
43  CHECK_CUSPARSE_ERROR_TYPE(code, CUSPARSE_STATUS_NOT_INITIALIZED);
44  CHECK_CUSPARSE_ERROR_TYPE(code, CUSPARSE_STATUS_ALLOC_FAILED);
45  CHECK_CUSPARSE_ERROR_TYPE(code, CUSPARSE_STATUS_INVALID_VALUE);
46  CHECK_CUSPARSE_ERROR_TYPE(code, CUSPARSE_STATUS_ARCH_MISMATCH);
47  CHECK_CUSPARSE_ERROR_TYPE(code, CUSPARSE_STATUS_MAPPING_ERROR);
48  CHECK_CUSPARSE_ERROR_TYPE(code, CUSPARSE_STATUS_EXECUTION_FAILED);
49  CHECK_CUSPARSE_ERROR_TYPE(code, CUSPARSE_STATUS_INTERNAL_ERROR);
50  CHECK_CUSPARSE_ERROR_TYPE(code, CUSPARSE_STATUS_MATRIX_TYPE_NOT_SUPPORTED);
51  CHECK_CUSPARSE_ERROR_TYPE(code, CUSPARSE_STATUS_ZERO_PIVOT);
52  CHECK_CUSPARSE_ERROR_TYPE(code, CUSPARSE_STATUS_NOT_SUPPORTED);
53  CHECK_CUSPARSE_ERROR_TYPE(code, CUSPARSE_STATUS_INSUFFICIENT_RESOURCES);
54  return fmt::format(fmt::runtime("UNKNOWN CUSPARSE ERROR {}."), code);
55 }
56 
57 #undef CHECK_CUSPARSE_ERROR_TYPE
58 
73 inline std::string
74 getCusparseErrorMessage(cusparseStatus_t error,
75  const std::string_view& expression,
76  const std::string_view& filename,
77  const std::string_view& functionName,
78  size_t lineNumber)
79 {
80  return fmt::format(fmt::runtime("cuSparse expression did not execute correctly. Expression was: \n\n"
81  " {}\n\nin function {}, in {}, at line {}\n"
82  "CuSparse error code was: {}\n"),
83  expression,
84  functionName,
85  filename,
86  lineNumber,
88 }
89 
110 inline void
111 cusparseSafeCall(cusparseStatus_t error,
112  const std::string_view& expression,
113  const std::string_view& filename,
114  const std::string_view& functionName,
115  size_t lineNumber)
116 {
117  if (error != CUSPARSE_STATUS_SUCCESS) {
118  OPM_THROW(std::runtime_error, getCusparseErrorMessage(error, expression, filename, functionName, lineNumber));
119  }
120 }
121 
151 inline cusparseStatus_t
152 cusparseWarnIfError(cusparseStatus_t error,
153  const std::string_view& expression,
154  const std::string_view& filename,
155  const std::string_view& functionName,
156  size_t lineNumber)
157 {
158  if (error != CUSPARSE_STATUS_SUCCESS) {
159  OpmLog::warning(getCusparseErrorMessage(error, expression, filename, functionName, lineNumber));
160  }
161 
162  return error;
163 }
164 } // namespace Opm::gpuistl::detail
165 
166 
167 
185 #define OPM_CUSPARSE_SAFE_CALL(expression) \
186  ::Opm::gpuistl::detail::cusparseSafeCall(expression, #expression, __FILE__, __func__, __LINE__)
187 
206 #define OPM_CUSPARSE_WARN_IF_ERROR(expression) \
207  ::Opm::gpuistl::detail::cusparseWarnIfError(expression, #expression, __FILE__, __func__, __LINE__)
208 #endif // OPM_CUSPARSE_SAFE_CALL_HPP
cusparseStatus_t cusparseWarnIfError(cusparseStatus_t error, const std::string_view &expression, const std::string_view &filename, const std::string_view &functionName, size_t lineNumber)
cusparseWarnIfError checks the return type of the CUSPARSE expression (function call) and issues a wa...
Definition: cusparse_safe_call.hpp:152
void cusparseSafeCall(cusparseStatus_t error, const std::string_view &expression, const std::string_view &filename, const std::string_view &functionName, size_t lineNumber)
cusparseSafeCall checks the return type of the CUSPARSE expression (function call) and throws an exce...
Definition: cusparse_safe_call.hpp:111
std::string getCusparseErrorCodeToString(int code)
getCusparseErrorCodeToString Converts an error code returned from a cusparse function a human readabl...
Definition: cusparse_safe_call.hpp:40
std::string getCusparseErrorMessage(cusparseStatus_t error, const std::string_view &expression, const std::string_view &filename, const std::string_view &functionName, size_t lineNumber)
getCusparseErrorMessage generates the error message to display for a given error. ...
Definition: cusparse_safe_call.hpp:74
Contains wrappers to make the CuBLAS library behave as a modern C++ library with function overlading...
Definition: autotuner.hpp:29