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  rtCheck<TApi, TThrow>(error, ("'" + std::string(cmd) + "' returned error ").c_str(), file, line);
65  }
66  else
67  {
68  // reset the last error to avoid propagation to the next CUDA/HIP API call. Using std::ignore
69  // to discard unneeded return values is recommended by the C++ core guidelines.
70  std::ignore = TApi::getLastError();
71  }
72  }
73  }
74 
75  //! CUDA/HIP runtime API last error checking with log and exception.
76  template<typename TApi, bool TThrow>
77  ALPAKA_FN_HOST inline void rtCheckLastError(char const* desc, char const* file, int const& line) noexcept(!TThrow)
78  {
79  typename TApi::Error_t const error(TApi::getLastError());
80  rtCheck<TApi, TThrow>(error, desc, file, line);
81  }
82 } // namespace alpaka::uniform_cuda_hip::detail
83 
84 # define ALPAKA_UNIFORM_CUDA_HIP_RT_CHECK_IMPL(cmd, throw, ...) \
85  do \
86  { \
87  ::alpaka::uniform_cuda_hip::detail::rtCheckLastError<TApi, throw>( \
88  "'" #cmd "' A previous API call (not this one) set the error ", \
89  __FILE__, \
90  __LINE__); \
91  ::alpaka::uniform_cuda_hip::detail::rtCheckIgnore<TApi, throw>( \
92  cmd, \
93  #cmd, \
94  __FILE__, \
95  __LINE__, \
96  {__VA_ARGS__}); \
97  } while(0)
98 
99 //! CUDA/HIP runtime error checking with log and exception, ignoring specific error values
100 # define ALPAKA_UNIFORM_CUDA_HIP_RT_CHECK_IGNORE(cmd, ...) \
101  ALPAKA_UNIFORM_CUDA_HIP_RT_CHECK_IMPL(cmd, true, __VA_ARGS__)
102 
103 //! CUDA/HIP runtime error checking with log and exception.
104 # define ALPAKA_UNIFORM_CUDA_HIP_RT_CHECK(cmd) ALPAKA_UNIFORM_CUDA_HIP_RT_CHECK_IMPL(cmd, true, )
105 
106 //! CUDA/HIP runtime error checking with log and exception, ignoring specific error values
107 # define ALPAKA_UNIFORM_CUDA_HIP_RT_CHECK_IGNORE_NOEXCEPT(cmd, ...) \
108  ALPAKA_UNIFORM_CUDA_HIP_RT_CHECK_IMPL(cmd, false, __VA_ARGS__)
109 
110 //! CUDA/HIP runtime error checking with log.
111 # define ALPAKA_UNIFORM_CUDA_HIP_RT_CHECK_NOEXCEPT(cmd) ALPAKA_UNIFORM_CUDA_HIP_RT_CHECK_IMPL(cmd, false, )
112 #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.