opm-simulators
gpu_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_GPU_SAFE_CALL_HPP
20 #define OPM_GPU_SAFE_CALL_HPP
21 #include <cuda_runtime.h>
22 #if CUDA_VERSION >= 12100
23 #include <fmt/core.h>
24 #else
25 #include <sstream>
26 #endif
27 #include <opm/common/ErrorMacros.hpp>
28 #include <opm/common/OpmLog/OpmLog.hpp>
29 #include <string_view>
30 
31 namespace Opm::gpuistl::detail
32 {
48 inline std::string
49 getCudaErrorMessage(cudaError_t error,
50  const std::string_view& expression,
51  const std::string_view& filename,
52  const std::string_view& functionName,
53  size_t lineNumber)
54 {
55 #if CUDA_VERSION >= 12100
56  return fmt::format(fmt::runtime("GPU expression did not execute correctly. Expression was: \n"
57  " {}\n"
58  "GPU error was {}\n"
59  "in function {}, in {}, at line {}\n"),
60  expression,
61  cudaGetErrorString(error),
62  functionName,
63  filename,
64  lineNumber);
65 #else
66  std::stringstream str;
67  str << "GPU expression did not execute correctly. Expression was: \n"
68  << " " << expression
69  << "\nGPU error was " << cudaGetErrorString(error)
70  << "\nin function " << functionName << ", in " << filename
71  << ", at line " << lineNumber << '\n';
72  return str.str();
73 #endif
74 }
75 
95 inline void
96 cudaSafeCall(cudaError_t error,
97  const std::string_view& expression,
98  const std::string_view& filename,
99  const std::string_view& functionName,
100  size_t lineNumber)
101 {
102  if (error != cudaSuccess) {
103  OPM_THROW(std::runtime_error, getCudaErrorMessage(error, expression, filename, functionName, lineNumber));
104  }
105 }
106 
134 inline void
135 cudaWarnIfError(cudaError_t error,
136  const std::string_view& expression,
137  const std::string_view& filename,
138  const std::string_view& functionName,
139  size_t lineNumber)
140 {
141  if (error != cudaSuccess) {
142  OpmLog::warning(getCudaErrorMessage(error, expression, filename, functionName, lineNumber));
143  }
144 }
145 } // namespace Opm::gpuistl::detail
146 
164 #define OPM_GPU_SAFE_CALL(expression) \
165  ::Opm::gpuistl::detail::cudaSafeCall(expression, #expression, __FILE__, __func__, __LINE__)
166 
167 
185 #define OPM_GPU_WARN_IF_ERROR(expression) \
186  ::Opm::gpuistl::detail::cudaWarnIfError(expression, #expression, __FILE__, __func__, __LINE__)
187 
188 #endif
std::string getCudaErrorMessage(cudaError_t error, const std::string_view &expression, const std::string_view &filename, const std::string_view &functionName, size_t lineNumber)
getCudaErrorMessage generates the error message to display for a given error.
Definition: gpu_safe_call.hpp:49
void cudaWarnIfError(cudaError_t error, const std::string_view &expression, const std::string_view &filename, const std::string_view &functionName, size_t lineNumber)
cudaWarnIfError checks the return type of the GPU expression (function call) and issues a warning if ...
Definition: gpu_safe_call.hpp:135
Contains wrappers to make the CuBLAS library behave as a modern C++ library with function overlading...
Definition: autotuner.hpp:29
void cudaSafeCall(cudaError_t error, const std::string_view &expression, const std::string_view &filename, const std::string_view &functionName, size_t lineNumber)
cudaSafeCall checks the return type of the GPU expression (function call) and throws an exception if ...
Definition: gpu_safe_call.hpp:96