alpaka
Abstraction Library for Parallel Kernel Acceleration
UniformCudaHip.hpp
Go to the documentation of this file.
1 /* Copyright 2022 Axel Huebl, Benjamin Worpitz, Matthias Werner, RenĂ© Widera, Jan Stephan, Andrea Bocci, Bernhard
2  * Manfred Gruber
3  * SPDX-License-Identifier: MPL-2.0
4  */
5 
6 #pragma once
7 
9 #include "alpaka/core/Cuda.hpp"
10 #include "alpaka/core/Hip.hpp"
11 
12 #include <initializer_list>
13 #include <stdexcept>
14 #include <string>
15 #include <tuple>
16 #include <type_traits>
17 
18 #if defined(ALPAKA_ACC_GPU_CUDA_ENABLED) || defined(ALPAKA_ACC_GPU_HIP_ENABLED)
19 
21 {
22  //! CUDA/HIP runtime API error checking with log and exception, ignoring specific error values
23  template<typename TApi, bool TThrow>
24  ALPAKA_FN_HOST inline void rtCheck(
25  typename TApi::Error_t const& error,
26  char const* desc,
27  char const* file,
28  int const& line) noexcept(!TThrow)
29  {
30  if(error != TApi::success)
31  {
32  auto const sError = std::string{
33  std::string(file) + "(" + std::to_string(line) + ") " + std::string(desc) + " : '"
34  + TApi::getErrorName(error) + "': '" + std::string(TApi::getErrorString(error)) + "'!"};
35 
36  if constexpr(!TThrow || ALPAKA_DEBUG >= ALPAKA_DEBUG_MINIMAL)
37  std::cerr << sError << std::endl;
38 
40  // reset the last error to allow user side error handling. Using std::ignore to discard unneeded
41  // return values is suggested by the C++ core guidelines.
42  std::ignore = TApi::getLastError();
43 
44  if constexpr(TThrow)
45  throw std::runtime_error(sError);
46  }
47  }
48 
49  //! CUDA/HIP runtime API error checking with log and exception, ignoring specific error values
50  template<typename TApi, bool TThrow>
52  typename TApi::Error_t const& error,
53  char const* cmd,
54  char const* file,
55  int const& line,
56  std::initializer_list<typename TApi::Error_t> ignoredErrorCodes) noexcept(!TThrow)
57  {
58  if(error != TApi::success)
59  {
60  // If the error code is not one of the ignored ones.
61  if(std::find(std::cbegin(ignoredErrorCodes), std::cend(ignoredErrorCodes), error)
62  == std::cend(ignoredErrorCodes))
63  {
64  using namespace std::literals;
65  rtCheck<TApi, TThrow>(error, ("'"s + std::string(cmd) + "' returned error "s).c_str(), file, line);
66  }
67  else
68  {
69  // reset the last error to avoid propagation to the next CUDA/HIP API call. Using std::ignore
70  // to discard unneeded return values is recommended by the C++ core guidelines.
71  std::ignore = TApi::getLastError();
72  }
73  }
74  }
75 
76  //! CUDA/HIP runtime API last error checking with log and exception.
77  template<typename TApi, bool TThrow>
78  ALPAKA_FN_HOST inline void rtCheckLastError(char const* desc, char const* file, int const& line) noexcept(!TThrow)
79  {
80  typename TApi::Error_t const error(TApi::getLastError());
81  rtCheck<TApi, TThrow>(error, desc, file, line);
82  }
83 } // namespace alpaka::uniform_cuda_hip::detail
84 
85 # define ALPAKA_UNIFORM_CUDA_HIP_RT_CHECK_IMPL(cmd, throw, ...) \
86  do \
87  { \
88  ::alpaka::uniform_cuda_hip::detail::rtCheckLastError<TApi, throw>( \
89  "'" #cmd "' A previous API call (not this one) set the error ", \
90  __FILE__, \
91  __LINE__); \
92  ::alpaka::uniform_cuda_hip::detail::rtCheckIgnore<TApi, throw>( \
93  cmd, \
94  #cmd, \
95  __FILE__, \
96  __LINE__, \
97  {__VA_ARGS__}); \
98  } while(0)
99 
100 //! CUDA/HIP runtime error checking with log and exception, ignoring specific error values
101 # define ALPAKA_UNIFORM_CUDA_HIP_RT_CHECK_IGNORE(cmd, ...) \
102  ALPAKA_UNIFORM_CUDA_HIP_RT_CHECK_IMPL(cmd, true, __VA_ARGS__)
103 
104 //! CUDA/HIP runtime error checking with log and exception.
105 # define ALPAKA_UNIFORM_CUDA_HIP_RT_CHECK(cmd) ALPAKA_UNIFORM_CUDA_HIP_RT_CHECK_IMPL(cmd, true, )
106 
107 //! CUDA/HIP runtime error checking with log and exception, ignoring specific error values
108 # define ALPAKA_UNIFORM_CUDA_HIP_RT_CHECK_IGNORE_NOEXCEPT(cmd, ...) \
109  ALPAKA_UNIFORM_CUDA_HIP_RT_CHECK_IMPL(cmd, false, __VA_ARGS__)
110 
111 //! CUDA/HIP runtime error checking with log.
112 # define ALPAKA_UNIFORM_CUDA_HIP_RT_CHECK_NOEXCEPT(cmd) ALPAKA_UNIFORM_CUDA_HIP_RT_CHECK_IMPL(cmd, false, )
113 #endif
#define ALPAKA_DEBUG_MINIMAL
The minimal debug level.
Definition: Debug.hpp:16
#define ALPAKA_DEBUG
Set the minimum log level if it is not defined.
Definition: Debug.hpp:22
#define ALPAKA_DEBUG_BREAK
Definition: Debug.hpp:76
#define ALPAKA_FN_HOST
Definition: Common.hpp:40
ALPAKA_FN_HOST void rtCheck(typename TApi::Error_t const &error, char const *desc, char const *file, int const &line) noexcept(!TThrow)
CUDA/HIP runtime API error checking with log and exception, ignoring specific error values.
ALPAKA_FN_HOST void rtCheckIgnore(typename TApi::Error_t const &error, char const *cmd, char const *file, int const &line, std::initializer_list< typename TApi::Error_t > ignoredErrorCodes) noexcept(!TThrow)
CUDA/HIP runtime API error checking with log and exception, ignoring specific error values.
ALPAKA_FN_HOST void rtCheckLastError(char const *desc, char const *file, int const &line) noexcept(!TThrow)
CUDA/HIP runtime API last error checking with log and exception.