Skip to content

Commit 7827590

Browse files
[SYCL][ABI-break] Promote guarded SYCL 2020 features and fix buffer reinterpret (#6541)
Promotes all SYCL 2020 features currently guarded by the SYCL2020_CONFORMANT_APIS macro. Additionally, buffer::reinterpret is changed to correctly rebind the allocator. To accomplish this, std::allocator_traits is specialized for aligned_allocator. Related change: intel/llvm-test-suite#1137
1 parent 82d423c commit 7827590

File tree

12 files changed

+87
-110
lines changed

12 files changed

+87
-110
lines changed

sycl/CMakeLists.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ set(SYCL_MINOR_VERSION 7)
3030
set(SYCL_PATCH_VERSION 0)
3131
# Don't forget to re-enable sycl_symbols_windows.dump once we leave ABI-breaking
3232
# window!
33-
set(SYCL_DEV_ABI_VERSION 4)
33+
set(SYCL_DEV_ABI_VERSION 5)
3434
if (SYCL_ADD_DEV_VERSION_POSTFIX)
3535
set(SYCL_VERSION_POSTFIX "-${SYCL_DEV_ABI_VERSION}")
3636
endif()

sycl/doc/PreprocessorMacros.md

Lines changed: 1 addition & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -55,24 +55,7 @@ This file describes macros that have effect on SYCL compiler and run-time.
5555
- **SYCL2020_CONFORMANT_APIS**
5656
This macro is used to comply with the SYCL 2020 specification, as some of the current
5757
implementations may be widespread and not conform to it.
58-
Description of what it changes:
59-
1) According to spec, `backend_return_t` for opencl event
60-
should be `std::vector<cl_event>` instead of `cl_event`. Defining this macro
61-
will change the behavior of `sycl::get_native()` function and using types for
62-
next structs: `interop<backend::opencl, event>`, `BackendInput<backend::opencl, event>`,
63-
`BackendReturn<backend::opencl, event>` to be in line with the spec.
64-
2) According to spec, `backend_return_t` for opencl buffer
65-
should be `std::vector<cl_mem>` instead of `cl_mem`. Defining this macro
66-
will change the behavior of `interop_handle::get_native_mem()` and `sycl::get_native()` functions
67-
and using type for `BackendReturn<backend::opencl, buffer>` to be in line with the spec.
68-
3) According to spec, `sycl::buffer_allocator` should be a template class taking a single
69-
type parameter denoting the data type of the associated buffer. Likewise, `sycl::buffer`
70-
with that take an allocator as a constructor argument should use
71-
`sycl::buffer_allocator<std::remove_const_t<T>>` by default, where `T` is the data type of
72-
that buffer. Defining this macro will change the definition of `sycl::buffer_allocator` to
73-
be templated and `sycl::buffer` will be using `sycl::buffer_allocator<std::remove_const_t<T>>`
74-
by default, where `T` is the data type of that buffer, if it is not explicitly given an
75-
allocator.
58+
Defining this macro currently has no effect on the API.
7659

7760
## Version macros
7861

sycl/include/sycl/backend.hpp

Lines changed: 2 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,6 @@ struct BufferInterop {
8686
}
8787
};
8888

89-
#ifdef SYCL2020_CONFORMANT_APIS
9089
template <typename DataT, int Dimensions, typename AllocatorT>
9190
struct BufferInterop<backend::opencl, DataT, Dimensions, AllocatorT> {
9291
using ReturnType =
@@ -101,7 +100,6 @@ struct BufferInterop<backend::opencl, DataT, Dimensions, AllocatorT> {
101100
return ReturnValue;
102101
}
103102
};
104-
#endif
105103

106104
template <backend BackendName, typename DataT, int Dimensions,
107105
typename AllocatorT>
@@ -143,30 +141,12 @@ auto get_native(const kernel_bundle<State> &Obj)
143141
}
144142

145143
template <backend BackendName, typename DataT, int Dimensions,
146-
typename AllocatorT,
147-
std::enable_if_t<BackendName == backend::opencl> * = nullptr>
148-
#ifndef SYCL2020_CONFORMANT_APIS
149-
__SYCL_DEPRECATED(
150-
"get_native<backend::opencl, buffer>, which return type "
151-
"cl_mem is deprecated. According to SYCL 2020 spec, please define "
152-
"SYCL2020_CONFORMANT_APIS and use vector<cl_mem> instead.")
153-
#endif
154-
auto get_native(const buffer<DataT, Dimensions, AllocatorT> &Obj)
155-
-> backend_return_t<BackendName, buffer<DataT, Dimensions, AllocatorT>> {
156-
return detail::get_native_buffer<BackendName>(Obj);
157-
}
158-
159-
template <backend BackendName, typename DataT, int Dimensions,
160-
typename AllocatorT,
161-
std::enable_if_t<BackendName != backend::opencl> * = nullptr>
144+
typename AllocatorT>
162145
auto get_native(const buffer<DataT, Dimensions, AllocatorT> &Obj)
163146
-> backend_return_t<BackendName, buffer<DataT, Dimensions, AllocatorT>> {
164147
return detail::get_native_buffer<BackendName>(Obj);
165148
}
166149

167-
// define SYCL2020_CONFORMANT_APIS to correspond SYCL 2020 spec and return
168-
// vector<cl_event> from get_native instead of just cl_event
169-
#ifdef SYCL2020_CONFORMANT_APIS
170150
template <>
171151
inline backend_return_t<backend::opencl, event>
172152
get_native<backend::opencl, event>(const event &Obj) {
@@ -184,24 +164,6 @@ get_native<backend::opencl, event>(const event &Obj) {
184164
}
185165
return ReturnValue;
186166
}
187-
#else
188-
// Specialization for cl_event with deprecation message
189-
template <>
190-
__SYCL_DEPRECATED(
191-
"get_native<backend::opencl, event>, which return type is "
192-
"cl_event is deprecated. According to SYCL 2020 spec, please define "
193-
"SYCL2020_CONFORMANT_APIS and use vector<cl_event> instead.")
194-
inline backend_return_t<backend::opencl, event> get_native<
195-
backend::opencl, event>(const event &Obj) {
196-
// TODO use SYCL 2020 exception when implemented
197-
if (Obj.get_backend() != backend::opencl) {
198-
throw sycl::runtime_error(errc::backend_mismatch, "Backends mismatch",
199-
PI_ERROR_INVALID_OPERATION);
200-
}
201-
return reinterpret_cast<
202-
typename detail::interop<backend::opencl, event>::type>(Obj.getNative());
203-
}
204-
#endif
205167

206168
// Native handle of an accessor should be accessed through interop_handler
207169
template <backend BackendName, typename DataT, int Dimensions,
@@ -334,7 +296,7 @@ typename std::enable_if<
334296
}
335297

336298
template <backend Backend, typename T, int Dimensions = 1,
337-
typename AllocatorT = detail::default_buffer_allocator<T>>
299+
typename AllocatorT = buffer_allocator<std::remove_const_t<T>>>
338300
typename std::enable_if<detail::InteropFeatureSupportMap<Backend>::MakeBuffer ==
339301
true &&
340302
Backend != backend::ext_oneapi_level_zero,

sycl/include/sycl/buffer.hpp

Lines changed: 14 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -23,27 +23,11 @@ class handler;
2323
class queue;
2424
template <int dimensions> class range;
2525

26-
// Guard SYCL 2020 buffer_allocator with template arguments behind the
27-
// SYCL2020_CONFORMANT_APIS macro.
28-
#ifdef SYCL2020_CONFORMANT_APIS
2926
template <typename DataT>
3027
using buffer_allocator = detail::sycl_memory_object_allocator<DataT>;
31-
#else
32-
using buffer_allocator = detail::sycl_memory_object_allocator<char>;
33-
#endif
3428

3529
namespace detail {
3630

37-
// Generalized implementation of the default allocator used by buffers.
38-
// TODO: When the SYCL 1.2.1 version of buffer_allocator is removed, this should
39-
// be removed.
40-
#ifdef SYCL2020_CONFORMANT_APIS
41-
template <typename DataT>
42-
using default_buffer_allocator = buffer_allocator<std::remove_const_t<DataT>>;
43-
#else
44-
template <typename> using default_buffer_allocator = buffer_allocator;
45-
#endif
46-
4731
template <typename T, int Dimensions, typename AllocatorT>
4832
buffer<T, Dimensions, AllocatorT, void>
4933
make_buffer_helper(pi_native_handle Handle, const context &Ctx, event Evt = {},
@@ -59,7 +43,7 @@ auto get_native_buffer(const buffer<DataT, Dimensions, Allocator, void> &Obj)
5943
buffer<DataT, Dimensions, Allocator, void>>;
6044

6145
template <backend Backend, typename DataT, int Dimensions,
62-
typename AllocatorT = detail::default_buffer_allocator<DataT>>
46+
typename AllocatorT = buffer_allocator<std::remove_const_t<DataT>>>
6347
struct BufferInterop;
6448
} // namespace detail
6549

@@ -72,7 +56,7 @@ struct BufferInterop;
7256
///
7357
/// \ingroup sycl_api
7458
template <typename T, int dimensions = 1,
75-
typename AllocatorT = detail::default_buffer_allocator<T>,
59+
typename AllocatorT = buffer_allocator<std::remove_const_t<T>>,
7660
typename __Enabled = typename detail::enable_if_t<(dimensions > 0) &&
7761
(dimensions <= 3)>>
7862
class buffer {
@@ -492,7 +476,9 @@ class buffer {
492476
bool is_sub_buffer() const { return IsSubBuffer; }
493477

494478
template <typename ReinterpretT, int ReinterpretDim>
495-
buffer<ReinterpretT, ReinterpretDim, AllocatorT>
479+
buffer<ReinterpretT, ReinterpretDim,
480+
typename std::allocator_traits<AllocatorT>::template rebind_alloc<
481+
ReinterpretT>>
496482
reinterpret(range<ReinterpretDim> reinterpretRange) const {
497483
if (sizeof(ReinterpretT) * reinterpretRange.size() != byte_size())
498484
throw sycl::invalid_object_error(
@@ -501,16 +487,22 @@ class buffer {
501487
"represented by the type and range of this SYCL buffer",
502488
PI_ERROR_INVALID_VALUE);
503489

504-
return buffer<ReinterpretT, ReinterpretDim, AllocatorT>(
490+
return buffer<ReinterpretT, ReinterpretDim,
491+
typename std::allocator_traits<
492+
AllocatorT>::template rebind_alloc<ReinterpretT>>(
505493
impl, reinterpretRange, OffsetInBytes, IsSubBuffer);
506494
}
507495

508496
template <typename ReinterpretT, int ReinterpretDim = dimensions>
509497
typename std::enable_if<
510498
(sizeof(ReinterpretT) == sizeof(T)) && (dimensions == ReinterpretDim),
511-
buffer<ReinterpretT, ReinterpretDim, AllocatorT>>::type
499+
buffer<ReinterpretT, ReinterpretDim,
500+
typename std::allocator_traits<AllocatorT>::template rebind_alloc<
501+
ReinterpretT>>>::type
512502
reinterpret() const {
513-
return buffer<ReinterpretT, ReinterpretDim, AllocatorT>(
503+
return buffer<ReinterpretT, ReinterpretDim,
504+
typename std::allocator_traits<
505+
AllocatorT>::template rebind_alloc<ReinterpretT>>(
514506
impl, get_range(), OffsetInBytes, IsSubBuffer);
515507
}
516508

sycl/include/sycl/detail/aligned_allocator.hpp

Lines changed: 60 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,11 +10,11 @@
1010

1111
#include <sycl/detail/common.hpp>
1212
#include <sycl/detail/os_util.hpp>
13-
#include <sycl/range.hpp>
1413

1514
#include <cstdlib>
1615
#include <cstring>
1716
#include <memory>
17+
#include <type_traits>
1818
#include <vector>
1919

2020
__SYCL_INLINE_NAMESPACE(cl) {
@@ -81,3 +81,62 @@ template <typename T> class aligned_allocator {
8181
} // namespace detail
8282
} // namespace sycl
8383
} // __SYCL_INLINE_NAMESPACE(cl)
84+
85+
namespace std {
86+
template <typename T>
87+
struct allocator_traits<sycl::detail::aligned_allocator<T>> {
88+
using allocator_type = typename sycl::detail::aligned_allocator<T>;
89+
using value_type = typename allocator_type::value_type;
90+
using pointer = typename allocator_type::pointer;
91+
using const_pointer = typename allocator_type::const_pointer;
92+
using void_pointer =
93+
typename std::pointer_traits<pointer>::template rebind<void>;
94+
using const_void_pointer =
95+
typename std::pointer_traits<pointer>::template rebind<const void>;
96+
using difference_type =
97+
typename std::pointer_traits<pointer>::difference_type;
98+
using size_type = typename std::make_unsigned<difference_type>::type;
99+
using propagate_on_container_copy_assignment = std::false_type;
100+
using propagate_on_container_move_assignment = std::false_type;
101+
using propagate_on_container_swap = std::false_type;
102+
using is_always_equal = typename std::is_empty<allocator_type>::type;
103+
104+
template <typename U>
105+
using rebind_alloc =
106+
typename sycl::detail::aligned_allocator<T>::template rebind<U>::other;
107+
template <typename U> using rebind_traits = allocator_traits<rebind_alloc<U>>;
108+
109+
static pointer allocate(allocator_type &Allocator, size_type NumElems) {
110+
return Allocator.allocate(NumElems);
111+
}
112+
113+
static pointer allocate(allocator_type &Allocator, size_type NumElems,
114+
const_void_pointer) {
115+
// TODO: Utilize the locality hint argument.
116+
return Allocator.allocate(NumElems);
117+
}
118+
119+
static void deallocate(allocator_type &Allocator, pointer Ptr,
120+
size_type NumElems) {
121+
Allocator.deallocate(Ptr, NumElems);
122+
}
123+
124+
template <class U, class... ArgsT>
125+
static void construct(allocator_type &Allocator, U *Ptr, ArgsT &&...Args) {
126+
return Allocator.construct(Ptr, Args...);
127+
}
128+
129+
template <class U> static void destroy(allocator_type &Allocator, U *Ptr) {
130+
Allocator.destroy(Ptr);
131+
}
132+
133+
static size_type max_size(const allocator_type &) noexcept {
134+
return std::numeric_limits<size_type>::max() / sizeof(value_type);
135+
}
136+
137+
static allocator_type
138+
select_on_container_copy_construction(const allocator_type &Allocator) {
139+
return Allocator;
140+
}
141+
};
142+
} // namespace std

sycl/include/sycl/detail/backend_traits_opencl.hpp

Lines changed: 0 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -84,17 +84,10 @@ struct BackendInput<backend::opencl, buffer<DataT, Dimensions, AllocatorT>> {
8484
using type = cl_mem;
8585
};
8686

87-
#ifdef SYCL2020_CONFORMANT_APIS
8887
template <typename DataT, int Dimensions, typename AllocatorT>
8988
struct BackendReturn<backend::opencl, buffer<DataT, Dimensions, AllocatorT>> {
9089
using type = std::vector<cl_mem>;
9190
};
92-
#else
93-
template <typename DataT, int Dimensions, typename AllocatorT>
94-
struct BackendReturn<backend::opencl, buffer<DataT, Dimensions, AllocatorT>> {
95-
using type = cl_mem;
96-
};
97-
#endif
9891

9992
template <> struct BackendInput<backend::opencl, context> {
10093
using type = cl_context;
@@ -112,7 +105,6 @@ template <> struct BackendReturn<backend::opencl, device> {
112105
using type = cl_device_id;
113106
};
114107

115-
#ifdef SYCL2020_CONFORMANT_APIS
116108
template <> struct interop<backend::opencl, event> {
117109
using type = std::vector<cl_event>;
118110
using value_type = cl_event;
@@ -125,17 +117,6 @@ template <> struct BackendReturn<backend::opencl, event> {
125117
using type = std::vector<cl_event>;
126118
using value_type = cl_event;
127119
};
128-
#else
129-
template <> struct interop<backend::opencl, event> {
130-
using type = cl_event;
131-
};
132-
template <> struct BackendInput<backend::opencl, event> {
133-
using type = cl_event;
134-
};
135-
template <> struct BackendReturn<backend::opencl, event> {
136-
using type = cl_event;
137-
};
138-
#endif
139120

140121
template <> struct BackendInput<backend::opencl, queue> {
141122
using type = cl_command_queue;

sycl/include/sycl/detail/sycl_mem_obj_allocator.hpp

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

99
#pragma once
1010

11+
#include <sycl/detail/aligned_allocator.hpp>
12+
1113
__SYCL_INLINE_NAMESPACE(cl) {
1214
namespace sycl {
1315
namespace detail {
1416

15-
template <typename T> class aligned_allocator;
16-
1717
template <typename DataT>
1818
using sycl_memory_object_allocator = aligned_allocator<DataT>;
1919

sycl/include/sycl/ext/oneapi/backend/level_zero.hpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -193,7 +193,7 @@ inline kernel make_kernel<backend::ext_oneapi_level_zero>(
193193

194194
// Specialization of sycl::make_buffer with event for Level-Zero backend.
195195
template <backend Backend, typename T, int Dimensions = 1,
196-
typename AllocatorT = detail::default_buffer_allocator<T>>
196+
typename AllocatorT = buffer_allocator<std::remove_const_t<T>>>
197197
typename std::enable_if<Backend == backend::ext_oneapi_level_zero,
198198
buffer<T, Dimensions, AllocatorT>>::type
199199
make_buffer(
@@ -208,7 +208,7 @@ make_buffer(
208208

209209
// Specialization of sycl::make_buffer for Level-Zero backend.
210210
template <backend Backend, typename T, int Dimensions = 1,
211-
typename AllocatorT = detail::default_buffer_allocator<T>>
211+
typename AllocatorT = buffer_allocator<std::remove_const_t<T>>>
212212
typename std::enable_if<Backend == backend::ext_oneapi_level_zero,
213213
buffer<T, Dimensions, AllocatorT>>::type
214214
make_buffer(

sycl/test/abi/layout_buffer.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,7 @@ void foo(sycl::buffer<int, 2>) {}
7979
// CHECK-NEXT: | [sizeof=184, dsize=184, align=8,
8080
// CHECK-NEXT: | nvsize=184, nvalign=8]
8181

82-
// CHECK: 0 | class sycl::buffer<int, 2, class sycl::detail::aligned_allocator<char>, void>
82+
// CHECK: 0 | class sycl::buffer<int, 2, class sycl::detail::aligned_allocator<int>, void>
8383
// CHECK-NEXT: 0 | class std::shared_ptr<class sycl::detail::buffer_impl> impl
8484
// CHECK-NEXT: 0 | class std::__shared_ptr<class sycl::detail::buffer_impl, __gnu_cxx::_S_atomic> (base)
8585
// CHECK-NEXT: 0 | class std::__shared_ptr_access<class sycl::detail::buffer_impl, __gnu_cxx::_S_atomic, false, false> (base) (empty)

sycl/test/abi/user_mangling.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ void acc(sycl::accessor<int, 1, sycl::access::mode::read, sycl::access::target::
4949
// CHK-HOST: define dso_local void @_Z3accN2cl4sycl8accessorINS0_3vecIiLi4EEELi1ELNS0_6access4modeE1024ELNS4_6targetE2019ELNS4_11placeholderE0ENS0_3ext6oneapi22accessor_property_listIJEEEEE({{.*}})
5050
void acc(sycl::accessor<sycl::cl_int4, 1, sycl::access::mode::read, sycl::access::target::host_image>) {}
5151

52-
// CHK-HOST: define dso_local void @_Z3bufN2cl4sycl6bufferIiLi1ENS0_6detail17aligned_allocatorIcEEvEE({{.*}})
52+
// CHK-HOST: define dso_local void @_Z3bufN2cl4sycl6bufferIiLi1ENS0_6detail17aligned_allocatorIiEEvEE({{.*}})
5353
void buf(sycl::buffer<int>) {}
5454

5555
// CHK-HOST: define dso_local void @_Z3ctxN2cl4sycl7contextE({{.*}})

sycl/test/regression/check_vector_of_opencl_event.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// RUN: %clangxx -fsycl -DSYCL2020_CONFORMANT_APIS %s -o %t.out
1+
// RUN: %clangxx -fsycl %s -o %t.out
22
// RUN: %RUN_ON_HOST %t.out
33
//
44
//===----------------------------------------------------------------------===//

sycl/unittests/scheduler/NoHostUnifiedMemory.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -221,8 +221,8 @@ TEST_F(SchedulerTest, NoHostUnifiedMemory) {
221221
InteropPiContext = detail::getSyclObjImpl(InteropContext)->getHandleRef();
222222
auto BufI = std::make_shared<detail::buffer_impl>(
223223
detail::pi::cast<pi_native_handle>(MockInteropBuffer), Q.get_context(),
224-
make_unique_ptr<detail::SYCLMemObjAllocatorHolder<
225-
detail::default_buffer_allocator<char>, char>>(),
224+
make_unique_ptr<
225+
detail::SYCLMemObjAllocatorHolder<buffer_allocator<char>, char>>(),
226226
/* OwnNativeHandle */ true, event());
227227

228228
detail::Requirement Req = getMockRequirement();

0 commit comments

Comments
 (0)