|
7 | 7 | //===----------------------------------------------------------------------===//
|
8 | 8 | #pragma once
|
9 | 9 |
|
| 10 | +#include <CL/__spirv/spirv_ops.hpp> |
10 | 11 | #include <sycl/detail/common.hpp>
|
11 | 12 | #include <sycl/detail/defines.hpp>
|
12 | 13 |
|
@@ -54,7 +55,12 @@ enum class address_space : int {
|
54 | 55 | generic_space = 6, // TODO generic_space address space is not supported yet
|
55 | 56 | };
|
56 | 57 |
|
57 |
| -enum class decorated : int { no = 0, yes = 1, legacy = 2 }; |
| 58 | +enum class decorated : int { |
| 59 | + no = 0, |
| 60 | + yes = 1, |
| 61 | + legacy __SYCL2020_DEPRECATED( |
| 62 | + "Legacy 'multi_ptr' is deprecated since SYCL 2020") = 2 |
| 63 | +}; |
58 | 64 | } // namespace access
|
59 | 65 |
|
60 | 66 | using access::target;
|
@@ -108,6 +114,14 @@ constexpr bool modeWritesNewData(access::mode m) {
|
108 | 114 | return m != access::mode::read;
|
109 | 115 | }
|
110 | 116 |
|
| 117 | +template <access::decorated Decorated> struct NegateDecorated; |
| 118 | +template <> struct NegateDecorated<access::decorated::yes> { |
| 119 | + static constexpr access::decorated value = access::decorated::no; |
| 120 | +}; |
| 121 | +template <> struct NegateDecorated<access::decorated::no> { |
| 122 | + static constexpr access::decorated value = access::decorated::yes; |
| 123 | +}; |
| 124 | + |
111 | 125 | #ifdef __SYCL_DEVICE_ONLY__
|
112 | 126 | #define __OPENCL_GLOBAL_AS__ __attribute__((opencl_global))
|
113 | 127 | #ifdef __ENABLE_USM_ADDR_SPACE__
|
@@ -199,82 +213,177 @@ template <typename ElementType>
|
199 | 213 | struct DecoratedType<ElementType, access::address_space::local_space> {
|
200 | 214 | using type = __OPENCL_LOCAL_AS__ ElementType;
|
201 | 215 | };
|
202 |
| -template <class T> struct remove_AS { |
203 |
| - typedef T type; |
204 |
| -}; |
205 | 216 |
|
206 | 217 | #ifdef __SYCL_DEVICE_ONLY__
|
207 | 218 | template <class T> struct deduce_AS {
|
208 | 219 | // Undecorated pointers are considered generic.
|
209 | 220 | // TODO: This assumes that the implementation uses generic as default. If
|
210 | 221 | // address space inference is used this may need to change.
|
211 |
| - static const access::address_space value = |
| 222 | + static constexpr access::address_space value = |
212 | 223 | access::address_space::generic_space;
|
213 | 224 | };
|
214 | 225 |
|
215 |
| -template <class T> struct remove_AS<__OPENCL_GLOBAL_AS__ T> { |
216 |
| - typedef T type; |
| 226 | +// Propagate through const qualifier. |
| 227 | +template <typename T> struct deduce_AS<const T> { |
| 228 | + static constexpr access::address_space value = deduce_AS<T>::value; |
217 | 229 | };
|
218 | 230 |
|
219 |
| -#ifdef __ENABLE_USM_ADDR_SPACE__ |
220 |
| -template <class T> struct remove_AS<__OPENCL_GLOBAL_DEVICE_AS__ T> { |
221 |
| - typedef T type; |
| 231 | +// Propagate through pointer. |
| 232 | +template <typename T> struct deduce_AS<T *> { |
| 233 | + static constexpr access::address_space value = deduce_AS<T>::value; |
| 234 | +}; |
| 235 | + |
| 236 | +// Propagate through const qualified pointer. |
| 237 | +template <typename T> struct deduce_AS<const T *> { |
| 238 | + static constexpr access::address_space value = deduce_AS<T>::value; |
222 | 239 | };
|
223 | 240 |
|
224 |
| -template <class T> struct remove_AS<__OPENCL_GLOBAL_HOST_AS__ T> { |
225 |
| - typedef T type; |
| 241 | +// Propagate through reference. |
| 242 | +template <typename T> struct deduce_AS<T &> { |
| 243 | + static constexpr access::address_space value = deduce_AS<T>::value; |
226 | 244 | };
|
227 | 245 |
|
| 246 | +// Propagate through const qualified reference. |
| 247 | +template <typename T> struct deduce_AS<const T &> { |
| 248 | + static constexpr access::address_space value = deduce_AS<T>::value; |
| 249 | +}; |
| 250 | + |
| 251 | +#ifdef __ENABLE_USM_ADDR_SPACE__ |
228 | 252 | template <class T> struct deduce_AS<__OPENCL_GLOBAL_DEVICE_AS__ T> {
|
229 |
| - static const access::address_space value = |
| 253 | + static constexpr access::address_space value = |
230 | 254 | access::address_space::ext_intel_global_device_space;
|
231 | 255 | };
|
232 | 256 |
|
233 | 257 | template <class T> struct deduce_AS<__OPENCL_GLOBAL_HOST_AS__ T> {
|
234 |
| - static const access::address_space value = |
| 258 | + static constexpr access::address_space value = |
235 | 259 | access::address_space::ext_intel_global_host_space;
|
236 | 260 | };
|
237 | 261 | #endif // __ENABLE_USM_ADDR_SPACE__
|
238 | 262 |
|
239 |
| -template <class T> struct remove_AS<__OPENCL_PRIVATE_AS__ T> { |
240 |
| - typedef T type; |
241 |
| -}; |
242 |
| - |
243 |
| -template <class T> struct remove_AS<__OPENCL_LOCAL_AS__ T> { |
244 |
| - typedef T type; |
245 |
| -}; |
246 |
| - |
247 |
| -template <class T> struct remove_AS<__OPENCL_CONSTANT_AS__ T> { |
248 |
| - typedef T type; |
249 |
| -}; |
250 |
| - |
251 | 263 | template <class T> struct deduce_AS<__OPENCL_GLOBAL_AS__ T> {
|
252 |
| - static const access::address_space value = |
| 264 | + static constexpr access::address_space value = |
253 | 265 | access::address_space::global_space;
|
254 | 266 | };
|
255 | 267 |
|
256 | 268 | template <class T> struct deduce_AS<__OPENCL_PRIVATE_AS__ T> {
|
257 |
| - static const access::address_space value = |
| 269 | + static constexpr access::address_space value = |
258 | 270 | access::address_space::private_space;
|
259 | 271 | };
|
260 | 272 |
|
261 | 273 | template <class T> struct deduce_AS<__OPENCL_LOCAL_AS__ T> {
|
262 |
| - static const access::address_space value = access::address_space::local_space; |
| 274 | + static constexpr access::address_space value = |
| 275 | + access::address_space::local_space; |
263 | 276 | };
|
264 | 277 |
|
265 | 278 | template <class T> struct deduce_AS<__OPENCL_CONSTANT_AS__ T> {
|
266 |
| - static const access::address_space value = |
| 279 | + static constexpr access::address_space value = |
267 | 280 | access::address_space::constant_space;
|
268 | 281 | };
|
269 | 282 | #endif
|
270 | 283 |
|
| 284 | +} // namespace detail |
| 285 | + |
| 286 | +template <typename T> struct remove_decoration { using type = T; }; |
| 287 | + |
| 288 | +// Propagate through const qualifier. |
| 289 | +template <typename T> struct remove_decoration<const T> { |
| 290 | + using type = const typename remove_decoration<T>::type; |
| 291 | +}; |
| 292 | + |
| 293 | +// Propagate through pointer. |
| 294 | +template <typename T> struct remove_decoration<T *> { |
| 295 | + using type = typename remove_decoration<T>::type *; |
| 296 | +}; |
| 297 | + |
| 298 | +// Propagate through const qualified pointer. |
| 299 | +template <typename T> struct remove_decoration<const T *> { |
| 300 | + using type = const typename remove_decoration<T>::type *; |
| 301 | +}; |
| 302 | + |
| 303 | +// Propagate through reference. |
| 304 | +template <typename T> struct remove_decoration<T &> { |
| 305 | + using type = typename remove_decoration<T>::type &; |
| 306 | +}; |
| 307 | + |
| 308 | +// Propagate through const qualified reference. |
| 309 | +template <typename T> struct remove_decoration<const T &> { |
| 310 | + using type = const typename remove_decoration<T>::type &; |
| 311 | +}; |
| 312 | + |
| 313 | +#ifdef __SYCL_DEVICE_ONLY__ |
| 314 | +template <typename T> struct remove_decoration<__OPENCL_GLOBAL_AS__ T> { |
| 315 | + using type = T; |
| 316 | +}; |
| 317 | + |
| 318 | +#ifdef __ENABLE_USM_ADDR_SPACE__ |
| 319 | +template <typename T> struct remove_decoration<__OPENCL_GLOBAL_DEVICE_AS__ T> { |
| 320 | + using type = T; |
| 321 | +}; |
| 322 | + |
| 323 | +template <typename T> struct remove_decoration<__OPENCL_GLOBAL_HOST_AS__ T> { |
| 324 | + using type = T; |
| 325 | +}; |
| 326 | + |
| 327 | +#endif // __ENABLE_USM_ADDR_SPACE__ |
| 328 | + |
| 329 | +template <typename T> struct remove_decoration<__OPENCL_PRIVATE_AS__ T> { |
| 330 | + using type = T; |
| 331 | +}; |
| 332 | + |
| 333 | +template <typename T> struct remove_decoration<__OPENCL_LOCAL_AS__ T> { |
| 334 | + using type = T; |
| 335 | +}; |
| 336 | + |
| 337 | +template <typename T> struct remove_decoration<__OPENCL_CONSTANT_AS__ T> { |
| 338 | + using type = T; |
| 339 | +}; |
| 340 | +#endif // __SYCL_DEVICE_ONLY__ |
| 341 | + |
| 342 | +template <typename T> |
| 343 | +using remove_decoration_t = typename remove_decoration<T>::type; |
| 344 | + |
| 345 | +namespace detail { |
| 346 | + |
| 347 | +// Helper function for selecting appropriate casts between address spaces. |
| 348 | +template <typename ToT, typename FromT> inline ToT cast_AS(FromT from) { |
| 349 | +#ifdef __SYCL_DEVICE_ONLY__ |
| 350 | + constexpr access::address_space ToAS = deduce_AS<ToT>::value; |
| 351 | + constexpr access::address_space FromAS = deduce_AS<FromT>::value; |
| 352 | + if constexpr (FromAS == access::address_space::generic_space) { |
| 353 | + using ToElemT = std::remove_pointer_t<remove_decoration_t<ToT>>; |
| 354 | + if constexpr (ToAS == access::address_space::global_space) |
| 355 | + return __SYCL_GenericCastToPtrExplicit_ToGlobal<ToElemT>(from); |
| 356 | + else if constexpr (ToAS == access::address_space::local_space) |
| 357 | + return __SYCL_GenericCastToPtrExplicit_ToLocal<ToElemT>(from); |
| 358 | + else if constexpr (ToAS == access::address_space::private_space) |
| 359 | + return __SYCL_GenericCastToPtrExplicit_ToPrivate<ToElemT>(from); |
| 360 | +#ifdef __ENABLE_USM_ADDR_SPACE__ |
| 361 | + else if constexpr (ToAS == access::address_space:: |
| 362 | + ext_intel_global_device_space || |
| 363 | + ToAS == |
| 364 | + access::address_space::ext_intel_global_host_space) |
| 365 | + // For extended address spaces we do not currently have a SPIR-V |
| 366 | + // conversion function, so we do a C-style cast. This may produce |
| 367 | + // warnings. |
| 368 | + return (ToT)from; |
| 369 | +#endif // __ENABLE_USM_ADDR_SPACE__ |
| 370 | + else |
| 371 | + return reinterpret_cast<ToT>(from); |
| 372 | + } else |
| 373 | +#endif // __SYCL_DEVICE_ONLY__ |
| 374 | + { |
| 375 | + return reinterpret_cast<ToT>(from); |
| 376 | + } |
| 377 | +} |
| 378 | + |
| 379 | +} // namespace detail |
| 380 | + |
271 | 381 | #undef __OPENCL_GLOBAL_AS__
|
272 | 382 | #undef __OPENCL_GLOBAL_DEVICE_AS__
|
273 | 383 | #undef __OPENCL_GLOBAL_HOST_AS__
|
274 | 384 | #undef __OPENCL_LOCAL_AS__
|
275 | 385 | #undef __OPENCL_CONSTANT_AS__
|
276 | 386 | #undef __OPENCL_PRIVATE_AS__
|
277 |
| -} // namespace detail |
278 | 387 |
|
279 | 388 | } // __SYCL_INLINE_VER_NAMESPACE(_V1)
|
280 | 389 | } // namespace sycl
|
0 commit comments