Skip to content

Commit 5124d7c

Browse files
Fznamznonvladimirlaz
authored andcommitted
[SYCL] Implement cl::sycl::buffer::reinterpret
Main changes (required to implement this method): Removed template parameters T and dimensions from buffer_impl class. Added buffer range to accessor. Currently it done to save handler::copy functionality but it also need to be used in multidimensional access. Moved range from buffer_impl to buffer. Used buffer_allocator as default allocator in buffer. Signed-off-by: Mariya Podchishchaeva <mariya.podchishchaeva@intel.com>
1 parent 647118f commit 5124d7c

File tree

10 files changed

+330
-230
lines changed

10 files changed

+330
-230
lines changed

sycl/include/CL/sycl/accessor.hpp

+47-49
Original file line numberDiff line numberDiff line change
@@ -125,11 +125,12 @@ SYCL_ACCESSOR_IMPL(isTargetHostAccess(accessTarget) && dimensions == 0) {
125125
SYCL_ACCESSOR_IMPL(isTargetHostAccess(accessTarget) && dimensions > 0) {
126126
dataT *Data;
127127
range<dimensions> Range;
128+
range<dimensions> BufRange;
128129
id<dimensions> Offset;
129130

130-
accessor_impl(dataT *Data, range<dimensions> Range,
131-
id<dimensions> Offset = {})
132-
: Data(Data), Range(Range), Offset(Offset) {}
131+
accessor_impl(dataT * Data, range<dimensions> Range,
132+
range<dimensions> BufRange, id<dimensions> Offset = {})
133+
: Data(Data), Range(Range), BufRange(BufRange), Offset(Offset) {}
133134

134135
// Returns the number of accessed elements.
135136
size_t get_count() const { return Range.size(); }
@@ -146,10 +147,9 @@ SYCL_ACCESSOR_IMPL(!isTargetHostAccess(accessTarget) &&
146147
// reinterpret casting while setting kernel arguments in order to get cl_mem
147148
// value from the buffer regardless of the accessor's dimensionality.
148149
#ifndef __SYCL_DEVICE_ONLY__
149-
detail::buffer_impl<dataT, 1> *m_Buf = nullptr;
150-
150+
detail::buffer_impl<buffer_allocator<char>> *m_Buf = nullptr;
151151
#else
152-
char padding[sizeof(detail::buffer_impl<dataT, dimensions> *)];
152+
char padding[sizeof(detail::buffer_impl<buffer_allocator<char>> *)];
153153
#endif // __SYCL_DEVICE_ONLY__
154154

155155
dataT *Data;
@@ -182,22 +182,23 @@ SYCL_ACCESSOR_IMPL(!isTargetHostAccess(accessTarget) &&
182182
// reinterpret casting while setting kernel arguments in order to get cl_mem
183183
// value from the buffer regardless of the accessor's dimensionality.
184184
#ifndef __SYCL_DEVICE_ONLY__
185-
detail::buffer_impl<dataT, dimensions> *m_Buf = nullptr;
185+
detail::buffer_impl<buffer_allocator<char>> *m_Buf = nullptr;
186186
#else
187-
char padding[sizeof(detail::buffer_impl<dataT, dimensions> *)];
187+
char padding[sizeof(detail::buffer_impl<buffer_allocator<char>> *)];
188188
#endif // __SYCL_DEVICE_ONLY__
189189

190190
dataT *Data;
191191
range<dimensions> Range;
192+
range<dimensions> BufRange;
192193
id<dimensions> Offset;
193194

194195
// Device accessors must be associated with a command group handler.
195196
// The handler though can be nullptr at the creation point if the
196197
// accessor is a placeholder accessor.
197-
accessor_impl(dataT *Data, range<dimensions> Range,
198-
handler *Handler = nullptr, id<dimensions> Offset = {})
199-
: Data(Data), Range(Range), Offset(Offset)
200-
{}
198+
accessor_impl(dataT * Data, range<dimensions> Range,
199+
range<dimensions> BufRange, handler *Handler = nullptr,
200+
id<dimensions> Offset = {})
201+
: Data(Data), Range(Range), BufRange(BufRange), Offset(Offset) {}
201202

202203
// Returns the number of accessed elements.
203204
size_t get_count() const { return Range.size(); }
@@ -633,8 +634,8 @@ class accessor
633634
#ifdef __SYCL_DEVICE_ONLY__
634635
; // This ctor can't be used in device code, so no need to define it.
635636
#else // !__SYCL_DEVICE_ONLY__
636-
: __impl(detail::getSyclObjImpl(bufferRef)->BufPtr,
637-
detail::getSyclObjImpl(bufferRef)->Range,
637+
: __impl((dataT *)detail::getSyclObjImpl(bufferRef)->BufPtr,
638+
bufferRef.get_range(), bufferRef.get_range(),
638639
&commandGroupHandlerRef) {
639640
auto BufImpl = detail::getSyclObjImpl(bufferRef);
640641
if (BufImpl->OpenCLInterop && !BufImpl->isValidAccessToMem(accessMode)) {
@@ -669,8 +670,8 @@ class accessor
669670
AccessTarget == access::target::constant_buffer))) &&
670671
Dimensions > 0),
671672
buffer<DataT, Dimensions>>::type &bufferRef)
672-
: __impl(detail::getSyclObjImpl(bufferRef)->BufPtr,
673-
detail::getSyclObjImpl(bufferRef)->Range) {
673+
: __impl((dataT *)detail::getSyclObjImpl(bufferRef)->BufPtr,
674+
bufferRef.get_range(), bufferRef.get_range()) {
674675
auto BufImpl = detail::getSyclObjImpl(bufferRef);
675676
if (AccessTarget == access::target::host_buffer) {
676677
if (BufImpl->OpenCLInterop) {
@@ -701,17 +702,17 @@ class accessor
701702
access::target AccessTarget = accessTarget,
702703
access::placeholder IsPlaceholder = isPlaceholder>
703704
accessor(typename std::enable_if<
704-
(IsPlaceholder == access::placeholder::false_t &&
705-
(AccessTarget == access::target::global_buffer ||
706-
AccessTarget == access::target::constant_buffer) &&
707-
Dimensions > 0),
708-
buffer<DataT, Dimensions>>::type &bufferRef,
705+
(IsPlaceholder == access::placeholder::false_t &&
706+
(AccessTarget == access::target::global_buffer ||
707+
AccessTarget == access::target::constant_buffer) &&
708+
Dimensions > 0),
709+
buffer<DataT, Dimensions>>::type &bufferRef,
709710
handler &commandGroupHandlerRef)
710711
#ifdef __SYCL_DEVICE_ONLY__
711712
; // This ctor can't be used in device code, so no need to define it.
712713
#else
713-
: __impl(detail::getSyclObjImpl(bufferRef)->BufPtr,
714-
detail::getSyclObjImpl(bufferRef)->Range,
714+
: __impl((dataT *)detail::getSyclObjImpl(bufferRef)->BufPtr,
715+
bufferRef.get_range(), bufferRef.get_range(),
715716
&commandGroupHandlerRef) {
716717
auto BufImpl = detail::getSyclObjImpl(bufferRef);
717718
if (BufImpl->OpenCLInterop && !BufImpl->isValidAccessToMem(accessMode)) {
@@ -739,20 +740,19 @@ class accessor
739740
access::target AccessTarget = accessTarget,
740741
access::placeholder IsPlaceholder = isPlaceholder>
741742
accessor(typename std::enable_if<
742-
((IsPlaceholder == access::placeholder::false_t &&
743-
AccessTarget == access::target::host_buffer) ||
744-
(IsPlaceholder == access::placeholder::true_t &&
745-
(AccessTarget == access::target::global_buffer ||
746-
AccessTarget == access::target::constant_buffer) &&
747-
Dimensions > 0)),
748-
buffer<DataT, Dimensions>>::type &bufferRef,
749-
range<Dimensions> Range,
750-
id<Dimensions> Offset = {}
751-
)
743+
((IsPlaceholder == access::placeholder::false_t &&
744+
AccessTarget == access::target::host_buffer) ||
745+
(IsPlaceholder == access::placeholder::true_t &&
746+
(AccessTarget == access::target::global_buffer ||
747+
AccessTarget == access::target::constant_buffer) &&
748+
Dimensions > 0)),
749+
buffer<DataT, Dimensions>>::type &bufferRef,
750+
range<Dimensions> Range, id<Dimensions> Offset = {})
752751
#ifdef __SYCL_DEVICE_ONLY__
753752
; // This ctor can't be used in device code, so no need to define it.
754-
#else // !__SYCL_DEVICE_ONLY__
755-
: __impl(detail::getSyclObjImpl(bufferRef)->BufPtr, Range, Offset) {
753+
#else // !__SYCL_DEVICE_ONLY__
754+
: __impl(detail::getSyclObjImpl(bufferRef)->BufPtr, Range,
755+
bufferRef.get_range(), Offset) {
756756
auto BufImpl = detail::getSyclObjImpl(bufferRef);
757757
if (AccessTarget == access::target::host_buffer) {
758758
if (BufImpl->OpenCLInterop) {
@@ -769,7 +769,7 @@ class accessor
769769
"interoperability buffer");
770770
}
771771
}
772-
#endif // !__SYCL_DEVICE_ONLY__
772+
#endif // !__SYCL_DEVICE_ONLY__
773773

774774
// buffer ctor #6:
775775
// accessor(buffer &, handler &, range Range, id Offset);
@@ -784,20 +784,18 @@ class accessor
784784
access::target AccessTarget = accessTarget,
785785
access::placeholder IsPlaceholder = isPlaceholder>
786786
accessor(typename std::enable_if<
787-
(IsPlaceholder == access::placeholder::false_t &&
788-
(AccessTarget == access::target::global_buffer ||
789-
AccessTarget == access::target::constant_buffer) &&
790-
Dimensions > 0),
791-
buffer<DataT, Dimensions>>::type &bufferRef,
792-
handler &commandGroupHandlerRef,
793-
range<Dimensions> Range,
794-
id<Dimensions> Offset = {}
795-
)
787+
(IsPlaceholder == access::placeholder::false_t &&
788+
(AccessTarget == access::target::global_buffer ||
789+
AccessTarget == access::target::constant_buffer) &&
790+
Dimensions > 0),
791+
buffer<DataT, Dimensions>>::type &bufferRef,
792+
handler &commandGroupHandlerRef, range<Dimensions> Range,
793+
id<Dimensions> Offset = {})
796794
#ifdef __SYCL_DEVICE_ONLY__
797795
; // This ctor can't be used in device code, so no need to define it.
798-
#else // !__SYCL_DEVICE_ONLY__
799-
: __impl(detail::getSyclObjImpl(bufferRef)->BufPtr, Range,
800-
&commandGroupHandlerRef, Offset) {
796+
#else // !__SYCL_DEVICE_ONLY__
797+
: __impl((dataT *)detail::getSyclObjImpl(bufferRef)->BufPtr, Range,
798+
bufferRef.get_range(), &commandGroupHandlerRef, Offset) {
801799
auto BufImpl = detail::getSyclObjImpl(bufferRef);
802800
if (BufImpl->OpenCLInterop && !BufImpl->isValidAccessToMem(accessMode)) {
803801
throw cl::sycl::runtime_error(
@@ -807,7 +805,7 @@ class accessor
807805
commandGroupHandlerRef.AddBufDep<AccessMode, AccessTarget>(*BufImpl);
808806
__impl.m_Buf = BufImpl.get();
809807
}
810-
#endif // !__SYCL_DEVICE_ONLY__
808+
#endif // !__SYCL_DEVICE_ONLY__
811809

812810
// TODO:
813811
// local accessor ctor #1

sycl/include/CL/sycl/buffer.hpp

+48-30
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ class queue;
2121
template <int dimentions> class range;
2222

2323
template <typename T, int dimensions = 1,
24-
typename AllocatorT = cl::sycl::buffer_allocator<T>>
24+
typename AllocatorT = cl::sycl::buffer_allocator<char>>
2525
class buffer {
2626
public:
2727
using value_type = T;
@@ -30,9 +30,10 @@ class buffer {
3030
using allocator_type = AllocatorT;
3131

3232
buffer(const range<dimensions> &bufferRange,
33-
const property_list &propList = {}) {
34-
impl = std::make_shared<detail::buffer_impl<T, dimensions, AllocatorT>>(
35-
bufferRange, propList);
33+
const property_list &propList = {})
34+
: Range(bufferRange) {
35+
impl = std::make_shared<detail::buffer_impl<AllocatorT>>(
36+
get_count() * sizeof(T), propList);
3637
}
3738

3839
// buffer(const range<dimensions> &bufferRange, AllocatorT allocator,
@@ -42,9 +43,10 @@ class buffer {
4243
// }
4344

4445
buffer(T *hostData, const range<dimensions> &bufferRange,
45-
const property_list &propList = {}) {
46-
impl = std::make_shared<detail::buffer_impl<T, dimensions, AllocatorT>>(
47-
hostData, bufferRange, propList);
46+
const property_list &propList = {})
47+
: Range(bufferRange) {
48+
impl = std::make_shared<detail::buffer_impl<AllocatorT>>(
49+
hostData, get_count() * sizeof(T), propList);
4850
}
4951

5052
// buffer(T *hostData, const range<dimensions> &bufferRange,
@@ -54,9 +56,10 @@ class buffer {
5456
// }
5557

5658
buffer(const T *hostData, const range<dimensions> &bufferRange,
57-
const property_list &propList = {}) {
58-
impl = std::make_shared<detail::buffer_impl<T, dimensions, AllocatorT>>(
59-
hostData, bufferRange, propList);
59+
const property_list &propList = {})
60+
: Range(bufferRange) {
61+
impl = std::make_shared<detail::buffer_impl<AllocatorT>>(
62+
hostData, get_count() * sizeof(T), propList);
6063
}
6164

6265
// buffer(const T *hostData, const range<dimensions> &bufferRange,
@@ -74,9 +77,10 @@ class buffer {
7477

7578
buffer(const shared_ptr_class<T> &hostData,
7679
const range<dimensions> &bufferRange,
77-
const property_list &propList = {}) {
78-
impl = std::make_shared<detail::buffer_impl<T, dimensions, AllocatorT>>(
79-
hostData, bufferRange, propList);
80+
const property_list &propList = {})
81+
: Range(bufferRange) {
82+
impl = std::make_shared<detail::buffer_impl<AllocatorT>>(
83+
hostData, get_count() * sizeof(T), propList);
8084
}
8185

8286
// template <class InputIterator>
@@ -89,9 +93,10 @@ class buffer {
8993
template <class InputIterator, int N = dimensions,
9094
typename = std::enable_if<N == 1>>
9195
buffer(InputIterator first, InputIterator last,
92-
const property_list &propList = {}) {
93-
impl = std::make_shared<detail::buffer_impl<T, dimensions, AllocatorT>>(
94-
first, last, propList);
96+
const property_list &propList = {})
97+
: Range(range<1>(std::distance(first, last))) {
98+
impl = std::make_shared<detail::buffer_impl<AllocatorT>>(
99+
first, last, get_count() * sizeof(T), propList);
95100
}
96101

97102
// buffer(buffer<T, dimensions, AllocatorT> b, const id<dimensions>
@@ -102,7 +107,7 @@ class buffer {
102107
template <int N = dimensions, typename = std::enable_if<N == 1>>
103108
buffer(cl_mem MemObject, const context &SyclContext,
104109
event AvailableEvent = {}) {
105-
impl = std::make_shared<detail::buffer_impl<T, dimensions, AllocatorT>>(
110+
impl = std::make_shared<detail::buffer_impl<AllocatorT>>(
106111
MemObject, SyclContext, AvailableEvent);
107112
}
108113

@@ -124,26 +129,27 @@ class buffer {
124129

125130
/* -- property interface members -- */
126131

127-
range<dimensions> get_range() const { return impl->get_range(); }
132+
range<dimensions> get_range() const { return Range; }
128133

129-
size_t get_count() const { return impl->get_count(); }
134+
size_t get_count() const { return Range.size(); }
130135

131136
size_t get_size() const { return impl->get_size(); }
132137

133-
AllocatorT get_allocator() const { return impl->get_allocator(); }
138+
// AllocatorT get_allocator() const { return impl->get_allocator(); }
134139

135140
template <access::mode mode,
136141
access::target target = access::target::global_buffer>
137142
accessor<T, dimensions, mode, target, access::placeholder::false_t>
138143
get_access(handler &commandGroupHandler) {
139-
return impl->template get_access<mode, target>(*this, commandGroupHandler);
144+
return impl->template get_access<T, dimensions, mode, target>(
145+
*this, commandGroupHandler);
140146
}
141147

142148
template <access::mode mode>
143149
accessor<T, dimensions, mode, access::target::host_buffer,
144150
access::placeholder::false_t>
145151
get_access() {
146-
return impl->template get_access<mode>(*this);
152+
return impl->template get_access<T, dimensions, mode>(*this);
147153
}
148154

149155
// template <access::mode mode, access::target target =
@@ -171,16 +177,29 @@ class buffer {
171177

172178
// bool is_sub_buffer() const { return impl->is_sub_buffer(); }
173179

174-
// template <typename ReinterpretT, int ReinterpretDim>
175-
// buffer<ReinterpretT, ReinterpretDim, AllocatorT>
176-
// reinterpret(range<ReinterpretDim> reinterpretRange) const {
177-
// return impl->reinterpret((reinterpretRange));
178-
// }
180+
template <typename ReinterpretT, int ReinterpretDim>
181+
buffer<ReinterpretT, ReinterpretDim, AllocatorT>
182+
reinterpret(range<ReinterpretDim> reinterpretRange) const {
183+
if (sizeof(ReinterpretT) * reinterpretRange.size() != get_size())
184+
throw cl::sycl::invalid_object_error(
185+
"Total size in bytes represented by the type and range of the "
186+
"reinterpreted SYCL buffer does not equal the total size in bytes "
187+
"represented by the type and range of this SYCL buffer");
188+
return buffer<ReinterpretT, ReinterpretDim, AllocatorT>(impl,
189+
reinterpretRange);
190+
}
179191

180192
private:
181-
shared_ptr_class<detail::buffer_impl<T, dimensions, AllocatorT>> impl;
193+
shared_ptr_class<detail::buffer_impl<AllocatorT>> impl;
182194
template <class Obj>
183195
friend decltype(Obj::impl) detail::getSyclObjImpl(const Obj &SyclObject);
196+
template <typename A, int dims, typename C> friend class buffer;
197+
range<dimensions> Range;
198+
199+
// Reinterpret contructor
200+
buffer(shared_ptr_class<detail::buffer_impl<AllocatorT>> Impl,
201+
range<dimensions> reinterpretRange)
202+
: impl(Impl), Range(reinterpretRange){};
184203
};
185204
} // namespace sycl
186205
} // namespace cl
@@ -190,8 +209,7 @@ template <typename T, int dimensions, typename AllocatorT>
190209
struct hash<cl::sycl::buffer<T, dimensions, AllocatorT>> {
191210
size_t
192211
operator()(const cl::sycl::buffer<T, dimensions, AllocatorT> &b) const {
193-
return hash<std::shared_ptr<
194-
cl::sycl::detail::buffer_impl<T, dimensions, AllocatorT>>>()(
212+
return hash<std::shared_ptr<cl::sycl::detail::buffer_impl<AllocatorT>>>()(
195213
cl::sycl::detail::getSyclObjImpl(b));
196214
}
197215
};

0 commit comments

Comments
 (0)