DPC++ Runtime
Runtime libraries for oneAPI DPC++
common.hpp
Go to the documentation of this file.
1 //==---------- common.hpp ----- Common declarations ------------------------==//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 
9 #pragma once
10 
14 #include <CL/sycl/detail/pi.hpp>
16 
17 #include <cstdint>
18 #include <string>
19 
20 // Default signature enables the passing of user code location information to
21 // public methods as a default argument. If the end-user wants to disable the
22 // code location information, they must compile the code with
23 // -DDISABLE_SYCL_INSTRUMENTATION_METADATA flag
25 namespace sycl {
26 namespace detail {
27 
28 #if !defined(NDEBUG) && (_MSC_VER > 1929 || __has_builtin(__builtin_FILE))
29 #define __CODELOC_FILE_NAME __builtin_FILE()
30 #else
31 #define __CODELOC_FILE_NAME nullptr
32 #endif
33 
34 #if _MSC_VER > 1929 || __has_builtin(__builtin_FUNCTION)
35 #define __CODELOC_FUNCTION __builtin_FUNCTION()
36 #else
37 #define __CODELOC_FUNCTION nullptr
38 #endif
39 
40 #if _MSC_VER > 1929 || __has_builtin(__builtin_LINE)
41 #define __CODELOC_LINE __builtin_LINE()
42 #else
43 #define __CODELOC_LINE 0
44 #endif
45 
46 #if _MSC_VER > 1929 || __has_builtin(__builtin_COLUMN)
47 #define __CODELOC_COLUMN __builtin_COLUMN()
48 #else
49 #define __CODELOC_COLUMN 0
50 #endif
51 
52 // Data structure that captures the user code location information using the
53 // builtin capabilities of the compiler
54 struct code_location {
55  static constexpr code_location
56  current(const char *fileName = __CODELOC_FILE_NAME,
57  const char *funcName = __CODELOC_FUNCTION,
58  unsigned long lineNo = __CODELOC_LINE,
59  unsigned long columnNo = __CODELOC_COLUMN) noexcept {
60  return code_location(fileName, funcName, lineNo, columnNo);
61  }
62 
63 #undef __CODELOC_FILE_NAME
64 #undef __CODELOC_FUNCTION
65 #undef __CODELOC_LINE
66 #undef __CODELOC_COLUMN
67 
68  constexpr code_location(const char *file, const char *func, int line,
69  int col) noexcept
70  : MFileName(file), MFunctionName(func), MLineNo(line), MColumnNo(col) {}
71 
72  constexpr code_location() noexcept
73  : MFileName(nullptr), MFunctionName(nullptr), MLineNo(0), MColumnNo(0) {}
74 
75  constexpr unsigned long lineNumber() const noexcept { return MLineNo; }
76  constexpr unsigned long columnNumber() const noexcept { return MColumnNo; }
77  constexpr const char *fileName() const noexcept { return MFileName; }
78  constexpr const char *functionName() const noexcept { return MFunctionName; }
79 
80 private:
81  const char *MFileName;
82  const char *MFunctionName;
83  unsigned long MLineNo;
84  unsigned long MColumnNo;
85 };
86 } // namespace detail
87 } // namespace sycl
88 } // __SYCL_INLINE_NAMESPACE(cl)
89 
91 namespace sycl {
92 namespace detail {
93 
94 __SYCL_EXPORT const char *stringifyErrorCode(pi_int32 error);
95 
96 static inline std::string codeToString(pi_int32 code) {
97  return std::string(std::to_string(code) + " (" + stringifyErrorCode(code) +
98  ")");
99 }
100 
101 } // namespace detail
102 } // namespace sycl
103 } // __SYCL_INLINE_NAMESPACE(cl)
104 
105 #ifdef __SYCL_DEVICE_ONLY__
106 // TODO remove this when 'assert' is supported in device code
107 #define __SYCL_ASSERT(x)
108 #else
109 #define __SYCL_ASSERT(x) assert(x)
110 #endif // #ifdef __SYCL_DEVICE_ONLY__
111 
112 #define __SYCL_PI_ERROR_REPORT \
113  "Native API failed. " /*__FILE__*/ \
114  /* TODO: replace __FILE__ to report only relative path*/ \
115  /* ":" __SYCL_STRINGIFY(__LINE__) ": " */ \
116  "Native API returns: "
117 
118 #ifndef __SYCL_SUPPRESS_PI_ERROR_REPORT
119 #include <iostream>
120 // TODO: rename all names with direct use of OCL/OPENCL to be backend agnostic.
121 #define __SYCL_REPORT_PI_ERR_TO_STREAM(expr) \
122  { \
123  auto code = expr; \
124  if (code != PI_SUCCESS) { \
125  std::cerr << __SYCL_PI_ERROR_REPORT \
126  << cl::sycl::detail::codeToString(code) << std::endl; \
127  } \
128  }
129 #endif
130 
131 #ifndef SYCL_SUPPRESS_EXCEPTIONS
132 #include <CL/sycl/exception.hpp>
133 // SYCL 1.2.1 exceptions
134 #define __SYCL_REPORT_PI_ERR_TO_EXC(expr, exc, str) \
135  { \
136  auto code = expr; \
137  if (code != PI_SUCCESS) { \
138  std::string err_str = \
139  str ? "\n" + std::string(str) + "\n" : std::string{}; \
140  throw exc(__SYCL_PI_ERROR_REPORT + \
141  cl::sycl::detail::codeToString(code) + err_str, \
142  code); \
143  } \
144  }
145 #define __SYCL_REPORT_PI_ERR_TO_EXC_THROW(code, exc, str) \
146  __SYCL_REPORT_PI_ERR_TO_EXC(code, exc, str)
147 #define __SYCL_REPORT_PI_ERR_TO_EXC_BASE(code) \
148  __SYCL_REPORT_PI_ERR_TO_EXC(code, cl::sycl::runtime_error, nullptr)
149 #else
150 #define __SYCL_REPORT_PI_ERR_TO_EXC_BASE(code) \
151  __SYCL_REPORT_PI_ERR_TO_STREAM(code)
152 #endif
153 // SYCL 2020 exceptions
154 #define __SYCL_REPORT_ERR_TO_EXC_VIA_ERRC(expr, errc) \
155  { \
156  auto code = expr; \
157  if (code != PI_SUCCESS) { \
158  throw sycl::exception(sycl::make_error_code(errc), \
159  __SYCL_PI_ERROR_REPORT + \
160  cl::sycl::detail::codeToString(code)); \
161  } \
162  }
163 #define __SYCL_REPORT_ERR_TO_EXC_THROW_VIA_ERRC(code, errc) \
164  __SYCL_REPORT_ERR_TO_EXC_VIA_ERRC(code, errc)
165 
166 #ifdef __SYCL_SUPPRESS_PI_ERROR_REPORT
167 // SYCL 1.2.1 exceptions
168 #define __SYCL_CHECK_OCL_CODE(X) (void)(X)
169 #define __SYCL_CHECK_OCL_CODE_THROW(X, EXC, STR) \
170  { \
171  (void)(X); \
172  (void)(STR); \
173  }
174 #define __SYCL_CHECK_OCL_CODE_NO_EXC(X) (void)(X)
175 // SYCL 2020 exceptions
176 #define __SYCL_CHECK_CODE_THROW_VIA_ERRC(X, ERRC) (void)(X)
177 #else
178 // SYCL 1.2.1 exceptions
179 #define __SYCL_CHECK_OCL_CODE(X) __SYCL_REPORT_PI_ERR_TO_EXC_BASE(X)
180 #define __SYCL_CHECK_OCL_CODE_THROW(X, EXC, STR) \
181  __SYCL_REPORT_PI_ERR_TO_EXC_THROW(X, EXC, STR)
182 #define __SYCL_CHECK_OCL_CODE_NO_EXC(X) __SYCL_REPORT_PI_ERR_TO_STREAM(X)
183 // SYCL 2020 exceptions
184 #define __SYCL_CHECK_CODE_THROW_VIA_ERRC(X, ERRC) \
185  __SYCL_REPORT_ERR_TO_EXC_THROW_VIA_ERRC(X, ERRC)
186 #endif
187 
189 namespace sycl {
190 namespace detail {
191 
192 // Helper function for extracting implementation from SYCL's interface objects.
193 // Note! This function relies on the fact that all SYCL interface classes
194 // contain "impl" field that points to implementation object. "impl" field
195 // should be accessible from this function.
196 //
197 // Note that due to a bug in MSVC compilers (including MSVC2019 v19.20), it
198 // may not recognize the usage of this function in friend member declarations
199 // if the template parameter name there is not equal to the name used here,
200 // i.e. 'Obj'. For example, using 'Obj' here and 'T' in such declaration
201 // would trigger that error in MSVC:
202 // template <class T>
203 // friend decltype(T::impl) detail::getSyclObjImpl(const T &SyclObject);
204 template <class Obj> decltype(Obj::impl) getSyclObjImpl(const Obj &SyclObject) {
205  return SyclObject.impl;
206 }
207 
208 // Returns the raw pointer to the impl object of given face object. The caller
209 // must make sure the returned pointer is not captured in a field or otherwise
210 // stored - i.e. must live only as on-stack value.
211 template <class T>
212 typename detail::add_pointer_t<typename decltype(T::impl)::element_type>
213 getRawSyclObjImpl(const T &SyclObject) {
214  return SyclObject.impl.get();
215 }
216 
217 // Helper function for creation SYCL interface objects from implementations.
218 // Note! This function relies on the fact that all SYCL interface classes
219 // contain "impl" field that points to implementation object. "impl" field
220 // should be accessible from this function.
221 template <class T> T createSyclObjFromImpl(decltype(T::impl) ImplObj) {
222  return T(ImplObj);
223 }
224 
225 // Produces N-dimensional object of type T whose all components are initialized
226 // to given integer value.
227 template <int N, template <int> class T> struct InitializedVal {
228  template <int Val> static T<N> get();
229 };
230 
231 // Specialization for a one-dimensional type.
232 template <template <int> class T> struct InitializedVal<1, T> {
233  template <int Val> static T<1> get() { return T<1>{Val}; }
234 };
235 
236 // Specialization for a two-dimensional type.
237 template <template <int> class T> struct InitializedVal<2, T> {
238  template <int Val> static T<2> get() { return T<2>{Val, Val}; }
239 };
240 
241 // Specialization for a three-dimensional type.
242 template <template <int> class T> struct InitializedVal<3, T> {
243  template <int Val> static T<3> get() { return T<3>{Val, Val, Val}; }
244 };
245 
247 template <int NDIMS, int DIM, template <int> class LoopBoundTy, typename FuncTy,
248  template <int> class LoopIndexTy>
250  NDLoopIterateImpl(const LoopIndexTy<NDIMS> &LowerBound,
251  const LoopBoundTy<NDIMS> &Stride,
252  const LoopBoundTy<NDIMS> &UpperBound, FuncTy f,
253  LoopIndexTy<NDIMS> &Index) {
254  constexpr size_t AdjIdx = NDIMS - 1 - DIM;
255  for (Index[AdjIdx] = LowerBound[AdjIdx]; Index[AdjIdx] < UpperBound[AdjIdx];
256  Index[AdjIdx] += Stride[AdjIdx]) {
257 
258  NDLoopIterateImpl<NDIMS, DIM - 1, LoopBoundTy, FuncTy, LoopIndexTy>{
259  LowerBound, Stride, UpperBound, f, Index};
260  }
261  }
262 };
263 
264 // Specialization for DIM=0 to terminate recursion
265 template <int NDIMS, template <int> class LoopBoundTy, typename FuncTy,
266  template <int> class LoopIndexTy>
267 struct NDLoopIterateImpl<NDIMS, 0, LoopBoundTy, FuncTy, LoopIndexTy> {
268  NDLoopIterateImpl(const LoopIndexTy<NDIMS> &LowerBound,
269  const LoopBoundTy<NDIMS> &Stride,
270  const LoopBoundTy<NDIMS> &UpperBound, FuncTy f,
271  LoopIndexTy<NDIMS> &Index) {
272 
273  constexpr size_t AdjIdx = NDIMS - 1;
274  for (Index[AdjIdx] = LowerBound[AdjIdx]; Index[AdjIdx] < UpperBound[AdjIdx];
275  Index[AdjIdx] += Stride[AdjIdx]) {
276 
277  f(Index);
278  }
279  }
280 };
281 
288 template <int NDIMS> struct NDLoop {
292  template <template <int> class LoopBoundTy, typename FuncTy,
293  template <int> class LoopIndexTy = LoopBoundTy>
294  static __SYCL_ALWAYS_INLINE void iterate(const LoopBoundTy<NDIMS> &UpperBound,
295  FuncTy f) {
296  const LoopIndexTy<NDIMS> LowerBound =
298  const LoopBoundTy<NDIMS> Stride =
300  LoopIndexTy<NDIMS> Index =
302 
303  NDLoopIterateImpl<NDIMS, NDIMS - 1, LoopBoundTy, FuncTy, LoopIndexTy>{
304  LowerBound, Stride, UpperBound, f, Index};
305  }
306 
310  template <template <int> class LoopBoundTy, typename FuncTy,
311  template <int> class LoopIndexTy = LoopBoundTy>
312  static __SYCL_ALWAYS_INLINE void iterate(const LoopIndexTy<NDIMS> &LowerBound,
313  const LoopBoundTy<NDIMS> &Stride,
314  const LoopBoundTy<NDIMS> &UpperBound,
315  FuncTy f) {
316  LoopIndexTy<NDIMS> Index =
318  NDLoopIterateImpl<NDIMS, NDIMS - 1, LoopBoundTy, FuncTy, LoopIndexTy>{
319  LowerBound, Stride, UpperBound, f, Index};
320  }
321 };
322 
323 constexpr size_t getNextPowerOfTwoHelper(size_t Var, size_t Offset) {
324  return Offset != 64
325  ? getNextPowerOfTwoHelper(Var | (Var >> Offset), Offset * 2)
326  : Var;
327 }
328 
329 // Returns the smallest power of two not less than Var
330 constexpr size_t getNextPowerOfTwo(size_t Var) {
331  return getNextPowerOfTwoHelper(Var - 1, 1) + 1;
332 }
333 
334 // Returns linear index by given index and range
335 template <int Dims, template <int> class T, template <int> class U>
336 size_t getLinearIndex(const T<Dims> &Index, const U<Dims> &Range) {
337  size_t LinearIndex = 0;
338  for (int I = 0; I < Dims; ++I)
339  LinearIndex = LinearIndex * Range[I] + Index[I];
340  return LinearIndex;
341 }
342 
343 // Kernel set ID, used to group kernels (represented by OSModule & kernel name
344 // pairs) into disjoint sets based on the kernel distribution among device
345 // images.
346 using KernelSetId = size_t;
347 // Kernel set ID for kernels contained within the SPIR-V file specified via
348 // environment.
349 constexpr KernelSetId SpvFileKSId = 0;
351 
352 template <typename T> struct InlineVariableHelper {
353  static constexpr T value{};
354 };
355 
356 template <typename T> constexpr T InlineVariableHelper<T>::value;
357 } // namespace detail
358 } // namespace sycl
359 } // __SYCL_INLINE_NAMESPACE(cl)
__CODELOC_COLUMN
#define __CODELOC_COLUMN
Definition: common.hpp:49
cl::sycl::detail::getRawSyclObjImpl
detail::add_pointer_t< typename decltype(T::impl)::element_type > getRawSyclObjImpl(const T &SyclObject)
Definition: common.hpp:213
cl::sycl::detail::getLinearIndex
size_t getLinearIndex(const T< Dims > &Index, const U< Dims > &Range)
Definition: common.hpp:336
cl::sycl::detail::get< 0 >
Definition: tuple.hpp:75
cl::sycl::detail::getNextPowerOfTwoHelper
constexpr size_t getNextPowerOfTwoHelper(size_t Var, size_t Offset)
Definition: common.hpp:323
__CODELOC_FUNCTION
#define __CODELOC_FUNCTION
Definition: common.hpp:37
cl::sycl::detail::stringifyErrorCode
const char * stringifyErrorCode(pi_int32 error)
Definition: common.cpp:16
cl::sycl::detail::SpvFileKSId
constexpr KernelSetId SpvFileKSId
Definition: common.hpp:349
defines_elementary.hpp
cl::sycl::detail::code_location::code_location
constexpr code_location(const char *file, const char *func, int line, int col) noexcept
Definition: common.hpp:68
cl::sycl::detail::createSyclObjFromImpl
T createSyclObjFromImpl(decltype(T::impl) ImplObj)
Definition: common.hpp:221
cl::sycl::detail::code_location::fileName
constexpr const char * fileName() const noexcept
Definition: common.hpp:77
cl::sycl::detail::InitializedVal
Definition: common.hpp:227
cl::sycl::detail::LastKSId
constexpr KernelSetId LastKSId
Definition: common.hpp:350
cl::sycl::ext::intel::experimental::esimd::line
ESIMD_NODEBUG ESIMD_INLINE std::enable_if_t< __ESIMD_DNS::is_fp_or_dword_type< T >::value &&std::is_floating_point< T >::value, sycl::ext::intel::esimd::simd< T, SZ > > line(sycl::ext::intel::esimd::simd< T, 4 > src0, sycl::ext::intel::esimd::simd< T, SZ > src1, Sat sat={})
Linear equation.
Definition: math.hpp:900
cl::sycl::detail::NDLoopIterateImpl
Helper class for the NDLoop.
Definition: common.hpp:249
__CODELOC_LINE
#define __CODELOC_LINE
Definition: common.hpp:43
sycl
Definition: invoke_simd.hpp:68
cl::sycl::detail::InlineVariableHelper
Definition: common.hpp:352
cl::sycl::detail::KernelSetId
size_t KernelSetId
Definition: common.hpp:346
cl::sycl::detail::code_location::columnNumber
constexpr unsigned long columnNumber() const noexcept
Definition: common.hpp:76
cl::sycl::detail::code_location::current
static constexpr code_location current(const char *fileName=__CODELOC_FILE_NAME, const char *funcName=__CODELOC_FUNCTION, unsigned long lineNo=__CODELOC_LINE, unsigned long columnNo=__CODELOC_COLUMN) noexcept
Definition: common.hpp:56
cl::sycl::detail::code_location
Definition: common.hpp:54
pi.hpp
cl::sycl::detail::InitializedVal< 1, T >::get
static T< 1 > get()
Definition: common.hpp:233
cl::sycl::detail::get
Definition: tuple.hpp:59
cl::sycl::detail::InitializedVal< 2, T >::get
static T< 2 > get()
Definition: common.hpp:238
stl_type_traits.hpp
cl::sycl::detail::NDLoop
Generates an NDIMS-dimensional perfect loop nest.
Definition: common.hpp:288
export.hpp
__SYCL_ALWAYS_INLINE
#define __SYCL_ALWAYS_INLINE
Definition: defines_elementary.hpp:29
cl::sycl::detail::codeToString
static std::string codeToString(pi_int32 code)
Definition: common.hpp:96
defines.hpp
cl
We provide new interfaces for matrix muliply in this patch:
Definition: access.hpp:13
cl::sycl::detail::NDLoopIterateImpl::NDLoopIterateImpl
NDLoopIterateImpl(const LoopIndexTy< NDIMS > &LowerBound, const LoopBoundTy< NDIMS > &Stride, const LoopBoundTy< NDIMS > &UpperBound, FuncTy f, LoopIndexTy< NDIMS > &Index)
Definition: common.hpp:250
cl::sycl::detail::getNextPowerOfTwo
constexpr size_t getNextPowerOfTwo(size_t Var)
Definition: common.hpp:330
std::get
constexpr tuple_element< I, tuple< Types... > >::type & get(cl::sycl::detail::tuple< Types... > &Arg) noexcept
Definition: tuple.hpp:199
cl::sycl::detail::add_pointer_t
typename std::add_pointer< T >::type add_pointer_t
Definition: stl_type_traits.hpp:37
cl::sycl::detail::getSyclObjImpl
decltype(Obj::impl) getSyclObjImpl(const Obj &SyclObject)
Definition: common.hpp:204
exception.hpp
cl::sycl::detail::code_location::functionName
constexpr const char * functionName() const noexcept
Definition: common.hpp:78
cl::sycl::detail::NDLoopIterateImpl< NDIMS, 0, LoopBoundTy, FuncTy, LoopIndexTy >::NDLoopIterateImpl
NDLoopIterateImpl(const LoopIndexTy< NDIMS > &LowerBound, const LoopBoundTy< NDIMS > &Stride, const LoopBoundTy< NDIMS > &UpperBound, FuncTy f, LoopIndexTy< NDIMS > &Index)
Definition: common.hpp:268
__CODELOC_FILE_NAME
#define __CODELOC_FILE_NAME
Definition: common.hpp:31
cl::sycl::detail::NDLoop::iterate
static __SYCL_ALWAYS_INLINE void iterate(const LoopBoundTy< NDIMS > &UpperBound, FuncTy f)
Generates ND loop nest with {0,..0} .
Definition: common.hpp:294
cl::sycl::detail::InitializedVal< 3, T >::get
static T< 3 > get()
Definition: common.hpp:243
cl::sycl::detail::code_location::lineNumber
constexpr unsigned long lineNumber() const noexcept
Definition: common.hpp:75
cl::sycl::detail::code_location::code_location
constexpr code_location() noexcept
Definition: common.hpp:72
pi_int32
int32_t pi_int32
Definition: pi.h:93
cl::sycl::detail::NDLoop::iterate
static __SYCL_ALWAYS_INLINE void iterate(const LoopIndexTy< NDIMS > &LowerBound, const LoopBoundTy< NDIMS > &Stride, const LoopBoundTy< NDIMS > &UpperBound, FuncTy f)
Generates ND loop nest with LowerBound .
Definition: common.hpp:312
__SYCL_INLINE_NAMESPACE
#define __SYCL_INLINE_NAMESPACE(X)
Definition: defines_elementary.hpp:12