Skip to content

Commit 3b13547

Browse files
[SYCL][NFCI] Drop __spirv_ops.hpp from core.hpp (#18839)
Our device compiler have been capable of automagically declaring necessary SPIR-V built-ins on the fly for a while now, meaning that we don't need them to be forward-declared in headers. This PR drops includes of `__spirv_ops.hpp` so that they don't appear anymore in `core.hpp` (and some other headers). The header is not removed entirely, however, because not every built-in is known to the compiler, i.e. some of them still have to be forward-declared in the header. Most likely there are other places which can be made free of uses of the header and the header itself can probably be cleaned up agressively, but I will leave it for separate future PRs. --------- Co-authored-by: Udit Kumar Agarwal <[email protected]>
1 parent 493ac99 commit 3b13547

20 files changed

+287
-240
lines changed

sycl/include/sycl/__spirv/spirv_ops.hpp

Lines changed: 5 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -233,10 +233,12 @@ template <typename RetT, class HandleT>
233233
extern __DPCPP_SYCL_EXTERNAL
234234
RetT __spirv_ConvertHandleToSampledImageINTEL(HandleT);
235235

236-
#define __SYCL_OpGroupAsyncCopyGlobalToLocal __spirv_GroupAsyncCopy
237-
#define __SYCL_OpGroupAsyncCopyLocalToGlobal __spirv_GroupAsyncCopy
238-
239236
// Atomic SPIR-V builtins
237+
// TODO: drop these forward-declarations.
238+
// As of now, compiler does not forward-declare long long overloads for
239+
// these and as such we can't drop anything from here. But ideally, we should
240+
// rely on the compiler to generate those - that would allow to drop
241+
// spirv_ops.hpp include from more files.
240242
#define __SPIRV_ATOMIC_LOAD(AS, Type) \
241243
extern __DPCPP_SYCL_EXTERNAL Type __spirv_AtomicLoad(AS Type *P, int S, \
242244
int O) noexcept;
@@ -792,10 +794,6 @@ extern __DPCPP_SYCL_EXTERNAL __ocl_WPipeTy<dataT>
792794
__spirv_CreatePipeFromPipeStorage_write(
793795
const ConstantPipeStorage *Storage) noexcept;
794796

795-
extern __DPCPP_SYCL_EXTERNAL void
796-
__spirv_ocl_prefetch(const __attribute__((opencl_global)) char *Ptr,
797-
size_t NumBytes) noexcept;
798-
799797
extern __DPCPP_SYCL_EXTERNAL float
800798
__spirv_ConvertBF16ToFINTEL(uint16_t) noexcept;
801799
extern __DPCPP_SYCL_EXTERNAL uint16_t
@@ -967,43 +965,4 @@ extern __DPCPP_SYCL_EXTERNAL RetT __spirv_TaskSequenceGetINTEL(
967965
extern __DPCPP_SYCL_EXTERNAL void __spirv_TaskSequenceReleaseINTEL(
968966
__spv::__spirv_TaskSequenceINTEL *TaskSequence) noexcept;
969967

970-
#else // if !__SYCL_DEVICE_ONLY__
971-
972-
template <typename dataT>
973-
__SYCL_CONVERGENT__ extern __ocl_event_t
974-
__SYCL_OpGroupAsyncCopyGlobalToLocal(int32_t, dataT *Dest, const dataT *Src,
975-
size_t NumElements, size_t Stride,
976-
__ocl_event_t) noexcept {
977-
for (size_t i = 0; i < NumElements; i++) {
978-
Dest[i] = Src[i * Stride];
979-
}
980-
// A real instance of the class is not needed, return dummy pointer.
981-
return nullptr;
982-
}
983-
984-
template <typename dataT>
985-
__SYCL_CONVERGENT__ extern __ocl_event_t
986-
__SYCL_OpGroupAsyncCopyLocalToGlobal(int32_t, dataT *Dest, const dataT *Src,
987-
size_t NumElements, size_t Stride,
988-
__ocl_event_t) noexcept {
989-
for (size_t i = 0; i < NumElements; i++) {
990-
Dest[i * Stride] = Src[i];
991-
}
992-
// A real instance of the class is not needed, return dummy pointer.
993-
return nullptr;
994-
}
995-
996-
extern __SYCL_EXPORT void __spirv_ocl_prefetch(const char *Ptr,
997-
size_t NumBytes) noexcept;
998-
999-
__SYCL_CONVERGENT__ extern __DPCPP_SYCL_EXTERNAL __SYCL_EXPORT void
1000-
__spirv_ControlBarrier(__spv::Scope Execution, __spv::Scope Memory,
1001-
uint32_t Semantics) noexcept;
1002-
1003-
__SYCL_CONVERGENT__ extern __DPCPP_SYCL_EXTERNAL __SYCL_EXPORT void
1004-
__spirv_MemoryBarrier(__spv::Scope Memory, uint32_t Semantics) noexcept;
1005-
1006-
__SYCL_CONVERGENT__ extern __DPCPP_SYCL_EXTERNAL __SYCL_EXPORT void
1007-
__spirv_GroupWaitEvents(__spv::Scope Execution, uint32_t NumEvents,
1008-
__ocl_event_t *WaitEvents) noexcept;
1009968
#endif // !__SYCL_DEVICE_ONLY__

sycl/include/sycl/access/access.hpp

Lines changed: 0 additions & 118 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@
1111
#include <sycl/detail/defines_elementary.hpp> // for __SYCL2020_DEPRECATED
1212

1313
#ifdef __SYCL_DEVICE_ONLY__
14-
#include <sycl/__spirv/spirv_ops.hpp>
1514
#include <type_traits>
1615
#endif
1716

@@ -319,123 +318,6 @@ template <typename T> struct remove_decoration<const T &> {
319318
template <typename T>
320319
using remove_decoration_t = typename remove_decoration<T>::type;
321320

322-
namespace detail {
323-
#ifdef __SYCL_DEVICE_ONLY__
324-
inline constexpr bool
325-
address_space_cast_is_possible(access::address_space Src,
326-
access::address_space Dst) {
327-
// constant_space is unique and is not interchangeable with any other.
328-
auto constant_space = access::address_space::constant_space;
329-
if (Src == constant_space || Dst == constant_space)
330-
return Src == Dst;
331-
332-
auto generic_space = access::address_space::generic_space;
333-
if (Src == Dst || Src == generic_space || Dst == generic_space)
334-
return true;
335-
336-
// global_host/global_device could be casted to/from global
337-
auto global_space = access::address_space::global_space;
338-
auto global_device = access::address_space::ext_intel_global_device_space;
339-
auto global_host = access::address_space::ext_intel_global_host_space;
340-
341-
if (Src == global_space || Dst == global_space) {
342-
auto Other = Src == global_space ? Dst : Src;
343-
if (Other == global_device || Other == global_host)
344-
return true;
345-
}
346-
347-
// No more compatible combinations.
348-
return false;
349-
}
350-
351-
template <access::address_space Space, typename ElementType>
352-
auto static_address_cast(ElementType *Ptr) {
353-
constexpr auto SrcAS = deduce_AS<ElementType *>::value;
354-
static_assert(address_space_cast_is_possible(SrcAS, Space));
355-
356-
using dst_type = typename DecoratedType<
357-
std::remove_pointer_t<remove_decoration_t<ElementType *>>, Space>::type *;
358-
359-
// Note: reinterpret_cast isn't enough for some of the casts between different
360-
// address spaces, use C-style cast instead.
361-
return (dst_type)Ptr;
362-
}
363-
364-
// Previous implementation (`castAS`, used in `multi_ptr` ctors among other
365-
// places), used C-style cast instead of a proper dynamic check for some
366-
// backends/spaces. `SupressNotImplementedAssert = true` parameter is emulating
367-
// that previous behavior until the proper support is added for compatibility
368-
// reasons.
369-
template <access::address_space Space, bool SupressNotImplementedAssert = false,
370-
typename ElementType>
371-
auto dynamic_address_cast(ElementType *Ptr) {
372-
constexpr auto generic_space = access::address_space::generic_space;
373-
constexpr auto global_space = access::address_space::global_space;
374-
constexpr auto local_space = access::address_space::local_space;
375-
constexpr auto private_space = access::address_space::private_space;
376-
constexpr auto global_device =
377-
access::address_space::ext_intel_global_device_space;
378-
constexpr auto global_host =
379-
access::address_space::ext_intel_global_host_space;
380-
381-
constexpr auto SrcAS = deduce_AS<ElementType *>::value;
382-
using dst_type = typename DecoratedType<
383-
std::remove_pointer_t<remove_decoration_t<ElementType *>>, Space>::type *;
384-
using RemoveCvT = std::remove_cv_t<ElementType>;
385-
386-
if constexpr (!address_space_cast_is_possible(SrcAS, Space)) {
387-
return (dst_type) nullptr;
388-
} else if constexpr (Space == generic_space) {
389-
return (dst_type)Ptr;
390-
} else if constexpr (Space == global_space &&
391-
(SrcAS == global_device || SrcAS == global_host)) {
392-
return (dst_type)Ptr;
393-
} else if constexpr (SrcAS == global_space &&
394-
(Space == global_device || Space == global_host)) {
395-
#if defined(__ENABLE_USM_ADDR_SPACE__)
396-
static_assert(SupressNotImplementedAssert || Space != Space,
397-
"Not supported yet!");
398-
return detail::static_address_cast<Space>(Ptr);
399-
#else
400-
// If __ENABLE_USM_ADDR_SPACE__ isn't defined then both
401-
// global_device/global_host are just aliases for global_space.
402-
static_assert(std::is_same_v<dst_type, ElementType *>);
403-
return (dst_type)Ptr;
404-
#endif
405-
} else if constexpr (Space == global_space) {
406-
return (dst_type)__spirv_GenericCastToPtrExplicit_ToGlobal(
407-
const_cast<RemoveCvT *>(Ptr), __spv::StorageClass::CrossWorkgroup);
408-
} else if constexpr (Space == local_space) {
409-
return (dst_type)__spirv_GenericCastToPtrExplicit_ToLocal(
410-
const_cast<RemoveCvT *>(Ptr), __spv::StorageClass::Workgroup);
411-
} else if constexpr (Space == private_space) {
412-
return (dst_type)__spirv_GenericCastToPtrExplicit_ToPrivate(
413-
const_cast<RemoveCvT *>(Ptr), __spv::StorageClass::Function);
414-
#if !defined(__ENABLE_USM_ADDR_SPACE__)
415-
} else if constexpr (SrcAS == generic_space &&
416-
(Space == global_device || Space == global_host)) {
417-
return (dst_type)__spirv_GenericCastToPtrExplicit_ToGlobal(
418-
const_cast<RemoveCvT *>(Ptr), __spv::StorageClass::CrossWorkgroup);
419-
#endif
420-
} else {
421-
static_assert(SupressNotImplementedAssert || Space != Space,
422-
"Not supported yet!");
423-
return detail::static_address_cast<Space>(Ptr);
424-
}
425-
}
426-
#else // __SYCL_DEVICE_ONLY__
427-
template <access::address_space Space, typename ElementType>
428-
auto static_address_cast(ElementType *Ptr) {
429-
return Ptr;
430-
}
431-
template <access::address_space Space, bool SupressNotImplementedAssert = false,
432-
typename ElementType>
433-
auto dynamic_address_cast(ElementType *Ptr) {
434-
return Ptr;
435-
}
436-
#endif // __SYCL_DEVICE_ONLY__
437-
} // namespace detail
438-
439321
#undef __OPENCL_GLOBAL_AS__
440322
#undef __OPENCL_GLOBAL_DEVICE_AS__
441323
#undef __OPENCL_GLOBAL_HOST_AS__
Lines changed: 137 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,137 @@
1+
//==------- address_space_cast.hpp --- Implementation of AS casts ----------==//
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+
11+
#include <sycl/__spirv/spirv_types.hpp>
12+
#include <sycl/access/access.hpp>
13+
14+
#include <type_traits>
15+
16+
namespace sycl {
17+
inline namespace _V1 {
18+
19+
namespace detail {
20+
#ifdef __SYCL_DEVICE_ONLY__
21+
inline constexpr bool
22+
address_space_cast_is_possible(access::address_space Src,
23+
access::address_space Dst) {
24+
// constant_space is unique and is not interchangeable with any other.
25+
auto constant_space = access::address_space::constant_space;
26+
if (Src == constant_space || Dst == constant_space)
27+
return Src == Dst;
28+
29+
auto generic_space = access::address_space::generic_space;
30+
if (Src == Dst || Src == generic_space || Dst == generic_space)
31+
return true;
32+
33+
// global_host/global_device could be casted to/from global
34+
auto global_space = access::address_space::global_space;
35+
auto global_device = access::address_space::ext_intel_global_device_space;
36+
auto global_host = access::address_space::ext_intel_global_host_space;
37+
38+
if (Src == global_space || Dst == global_space) {
39+
auto Other = Src == global_space ? Dst : Src;
40+
if (Other == global_device || Other == global_host)
41+
return true;
42+
}
43+
44+
// No more compatible combinations.
45+
return false;
46+
}
47+
48+
template <access::address_space Space, typename ElementType>
49+
auto static_address_cast(ElementType *Ptr) {
50+
constexpr auto SrcAS = deduce_AS<ElementType *>::value;
51+
static_assert(address_space_cast_is_possible(SrcAS, Space));
52+
53+
using dst_type = typename DecoratedType<
54+
std::remove_pointer_t<remove_decoration_t<ElementType *>>, Space>::type *;
55+
56+
// Note: reinterpret_cast isn't enough for some of the casts between different
57+
// address spaces, use C-style cast instead.
58+
return (dst_type)Ptr;
59+
}
60+
61+
// Previous implementation (`castAS`, used in `multi_ptr` ctors among other
62+
// places), used C-style cast instead of a proper dynamic check for some
63+
// backends/spaces. `SupressNotImplementedAssert = true` parameter is emulating
64+
// that previous behavior until the proper support is added for compatibility
65+
// reasons.
66+
template <access::address_space Space, bool SupressNotImplementedAssert = false,
67+
typename ElementType>
68+
auto dynamic_address_cast(ElementType *Ptr) {
69+
constexpr auto generic_space = access::address_space::generic_space;
70+
constexpr auto global_space = access::address_space::global_space;
71+
constexpr auto local_space = access::address_space::local_space;
72+
constexpr auto private_space = access::address_space::private_space;
73+
constexpr auto global_device =
74+
access::address_space::ext_intel_global_device_space;
75+
constexpr auto global_host =
76+
access::address_space::ext_intel_global_host_space;
77+
78+
constexpr auto SrcAS = deduce_AS<ElementType *>::value;
79+
using dst_type = typename DecoratedType<
80+
std::remove_pointer_t<remove_decoration_t<ElementType *>>, Space>::type *;
81+
using RemoveCvT = std::remove_cv_t<ElementType>;
82+
83+
if constexpr (!address_space_cast_is_possible(SrcAS, Space)) {
84+
return (dst_type) nullptr;
85+
} else if constexpr (Space == generic_space) {
86+
return (dst_type)Ptr;
87+
} else if constexpr (Space == global_space &&
88+
(SrcAS == global_device || SrcAS == global_host)) {
89+
return (dst_type)Ptr;
90+
} else if constexpr (SrcAS == global_space &&
91+
(Space == global_device || Space == global_host)) {
92+
#if defined(__ENABLE_USM_ADDR_SPACE__)
93+
static_assert(SupressNotImplementedAssert || Space != Space,
94+
"Not supported yet!");
95+
return detail::static_address_cast<Space>(Ptr);
96+
#else
97+
// If __ENABLE_USM_ADDR_SPACE__ isn't defined then both
98+
// global_device/global_host are just aliases for global_space.
99+
static_assert(std::is_same_v<dst_type, ElementType *>);
100+
return (dst_type)Ptr;
101+
#endif
102+
} else if constexpr (Space == global_space) {
103+
return (dst_type)__spirv_GenericCastToPtrExplicit_ToGlobal(
104+
const_cast<RemoveCvT *>(Ptr), __spv::StorageClass::CrossWorkgroup);
105+
} else if constexpr (Space == local_space) {
106+
return (dst_type)__spirv_GenericCastToPtrExplicit_ToLocal(
107+
const_cast<RemoveCvT *>(Ptr), __spv::StorageClass::Workgroup);
108+
} else if constexpr (Space == private_space) {
109+
return (dst_type)__spirv_GenericCastToPtrExplicit_ToPrivate(
110+
const_cast<RemoveCvT *>(Ptr), __spv::StorageClass::Function);
111+
#if !defined(__ENABLE_USM_ADDR_SPACE__)
112+
} else if constexpr (SrcAS == generic_space &&
113+
(Space == global_device || Space == global_host)) {
114+
return (dst_type)__spirv_GenericCastToPtrExplicit_ToGlobal(
115+
const_cast<RemoveCvT *>(Ptr), __spv::StorageClass::CrossWorkgroup);
116+
#endif
117+
} else {
118+
static_assert(SupressNotImplementedAssert || Space != Space,
119+
"Not supported yet!");
120+
return detail::static_address_cast<Space>(Ptr);
121+
}
122+
}
123+
#else // __SYCL_DEVICE_ONLY__
124+
template <access::address_space Space, typename ElementType>
125+
auto static_address_cast(ElementType *Ptr) {
126+
return Ptr;
127+
}
128+
template <access::address_space Space, bool SupressNotImplementedAssert = false,
129+
typename ElementType>
130+
auto dynamic_address_cast(ElementType *Ptr) {
131+
return Ptr;
132+
}
133+
#endif // __SYCL_DEVICE_ONLY__
134+
} // namespace detail
135+
136+
} // namespace _V1
137+
} // namespace sycl

sycl/include/sycl/detail/spirv.hpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,13 @@
1010

1111
#ifdef __SYCL_DEVICE_ONLY__
1212

13+
// Some __spirv_* inrinsics are automatically forward-declared by the compiler,
14+
// but not all of them. For example:
15+
// __spirv_AtomicStore(unsigned long long*, ...)
16+
// Therefore, we need the following include to get forward-declarations of those
17+
// versions.
18+
#include <sycl/__spirv/spirv_ops.hpp>
19+
1320
#include <sycl/ext/oneapi/experimental/non_uniform_groups.hpp> // for IdToMaskPosition
1421

1522
#if defined(__NVPTX__)

sycl/include/sycl/device_event.hpp

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@
88

99
#pragma once
1010

11-
#include <sycl/__spirv/spirv_ops.hpp>
1211
#include <sycl/__spirv/spirv_types.hpp>
1312

1413
namespace sycl {
@@ -31,7 +30,12 @@ class device_event {
3130

3231
device_event(__ocl_event_t Event) : m_Event(Event) {}
3332

34-
void wait() { __spirv_GroupWaitEvents(__spv::Scope::Workgroup, 1, &m_Event); }
33+
void wait() {
34+
(void)m_Event;
35+
#ifdef __SYCL_DEVICE_ONLY__
36+
__spirv_GroupWaitEvents(__spv::Scope::Workgroup, 1, &m_Event);
37+
#endif
38+
}
3539
};
3640

3741
} // namespace _V1

sycl/include/sycl/ext/intel/esimd/detail/memory_intrin.hpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,10 @@
1919
#include <sycl/ext/intel/esimd/detail/util.hpp>
2020
#include <sycl/vector.hpp>
2121

22+
#ifdef __SYCL_DEVICE_ONLY__
23+
#include <sycl/__spirv/spirv_ops.hpp>
24+
#endif
25+
2226
#include <cstdint>
2327

2428
namespace sycl {

sycl/include/sycl/ext/oneapi/experimental/address_cast.hpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88

99
#pragma once
1010

11-
#include <sycl/detail/spirv.hpp>
11+
#include <sycl/detail/address_space_cast.hpp>
1212
#include <sycl/multi_ptr.hpp>
1313

1414
namespace sycl {

0 commit comments

Comments
 (0)