Skip to content

Commit 60b6e3f

Browse files
Ivan Karachunromanovvlad
authored andcommitted
[SYCL] Subbuffer reinterpretation
Before this patch `reinterpret` method didn't take into account new shape and offset. This patch partially solves this problem. For now, `reinterpret` method recalculates an offset in elements of reinterpreted type. Currently this way works only for 1D to 1D subbuffer reinterpretation. To enable all sorts of reinterpretation (from any dimension to any dimension with different types) some significant changes needs to be done in SYCL runtime library. Signed-off-by: Ivan Karachun <ivan.karachun@intel.com>
1 parent 800c8c0 commit 60b6e3f

File tree

2 files changed

+124
-4
lines changed

2 files changed

+124
-4
lines changed

sycl/include/CL/sycl/buffer.hpp

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -229,8 +229,15 @@ class buffer {
229229
"Total size in bytes represented by the type and range of the "
230230
"reinterpreted SYCL buffer does not equal the total size in bytes "
231231
"represented by the type and range of this SYCL buffer");
232-
return buffer<ReinterpretT, ReinterpretDim, AllocatorT>(impl,
233-
reinterpretRange);
232+
233+
// This is not the best approach since for now it works only for
234+
// 1D subbuffers. Other cases are not supported for now.
235+
id<ReinterpretDim> NewOffset{};
236+
NewOffset[ReinterpretDim - 1] =
237+
Offset[dimensions - 1] * sizeof(T) / sizeof(ReinterpretT);
238+
239+
return buffer<ReinterpretT, ReinterpretDim, AllocatorT>(
240+
impl, reinterpretRange, NewOffset, IsSubBuffer);
234241
}
235242

236243
template <typename propertyT> bool has_property() const {
@@ -260,8 +267,10 @@ class buffer {
260267

261268
// Reinterpret contructor
262269
buffer(shared_ptr_class<detail::buffer_impl<AllocatorT>> Impl,
263-
range<dimensions> reinterpretRange)
264-
: impl(Impl), Range(reinterpretRange), MemRange(reinterpretRange) {};
270+
range<dimensions> reinterpretRange, id<dimensions>reinterpretOffset,
271+
bool isSubBuffer)
272+
: impl(Impl), Range(reinterpretRange), MemRange(reinterpretRange),
273+
IsSubBuffer(isSubBuffer), Offset(reinterpretOffset) {};
265274
};
266275
} // namespace sycl
267276
} // namespace cl

sycl/test/basic_tests/buffer/reinterpret.cpp

Lines changed: 111 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,5 +81,116 @@ int main() {
8181
<< std::endl;
8282
}
8383

84+
// subbuffer reinterpret
85+
// 1d int -> char
86+
{
87+
std::size_t size = 12, offset = 4;
88+
std::vector<int> data(size + offset, 8);
89+
std::vector<int> expected_data(size + offset, 8);
90+
char *ptr = reinterpret_cast<char *>(&expected_data[offset]);
91+
for (int i = 0; i < size * sizeof(int); ++i) {
92+
*(ptr + i) = 13;
93+
}
94+
{
95+
cl::sycl::range<1> rng(size + offset);
96+
cl::sycl::buffer<int, 1> buffer_1(data.data(), rng);
97+
cl::sycl::buffer<int, 1> subbuffer_1(buffer_1, cl::sycl::id<1>(offset),
98+
cl::sycl::range<1>(size));
99+
cl::sycl::buffer<char, 1> reinterpret_subbuffer(
100+
subbuffer_1.reinterpret<char, 1>(
101+
cl::sycl::range<1>(subbuffer_1.get_size())));
102+
103+
cl::sycl::queue cmd_queue;
104+
105+
cmd_queue.submit([&](cl::sycl::handler &cgh) {
106+
auto rb_acc = reinterpret_subbuffer
107+
.get_access<cl::sycl::access::mode::read_write>(cgh);
108+
cgh.parallel_for<class foo_1>(
109+
cl::sycl::range<1>(reinterpret_subbuffer.get_count()),
110+
[=](cl::sycl::id<1> index) { rb_acc[index] = 13; });
111+
});
112+
}
113+
114+
for (std::size_t i = 0; i < size + offset; ++i) {
115+
assert(data[i] == expected_data[i]);
116+
}
117+
}
118+
119+
// 1d char -> int
120+
{
121+
std::size_t size = 12, offset = 4;
122+
std::vector<char> data(size + offset, 8);
123+
std::vector<char> expected_data(size + offset, 8);
124+
for (std::size_t i = offset; i < size + offset; ++i) {
125+
expected_data[i] = i % sizeof(int) == 0 ? 1 : 0;
126+
}
127+
128+
{
129+
cl::sycl::range<1> rng(size + offset);
130+
cl::sycl::buffer<char, 1> buffer_1(data.data(), rng);
131+
cl::sycl::buffer<char, 1> subbuffer_1(buffer_1, cl::sycl::id<1>(offset),
132+
cl::sycl::range<1>(size));
133+
cl::sycl::buffer<int, 1> reinterpret_subbuffer =
134+
subbuffer_1.reinterpret<int, 1>(
135+
cl::sycl::range<1>(subbuffer_1.get_size() / sizeof(int)));
136+
137+
cl::sycl::queue cmd_queue;
138+
cmd_queue.submit([&](cl::sycl::handler &cgh) {
139+
auto rb_acc = reinterpret_subbuffer
140+
.get_access<cl::sycl::access::mode::read_write>(cgh);
141+
cgh.parallel_for<class foo_2>(
142+
cl::sycl::range<1>(reinterpret_subbuffer.get_count()),
143+
[=](cl::sycl::id<1> index) { rb_acc[index] = 1; });
144+
});
145+
}
146+
147+
for (std::size_t i = 0; i < size + offset; ++i) {
148+
assert(data[i] == expected_data[i]);
149+
}
150+
}
151+
152+
// reinterpret 2D buffer to 1D buffer (same data type)
153+
// create subbuffer from 1D buffer with an offset
154+
// reinterpret subbuffer as 1D buffer of different data type
155+
{
156+
std::size_t size = 4, offset = 2, total_size = size + offset;
157+
cl::sycl::range<2> rng(total_size, total_size);
158+
159+
std::vector<int> data(total_size * total_size, 8);
160+
std::vector<int> expected_data(total_size * total_size, 8);
161+
std::fill(expected_data.begin() + offset, expected_data.end(), 8);
162+
char *ptr =
163+
reinterpret_cast<char *>(&expected_data[offset * total_size + offset]);
164+
for (int i = 0; i < size * sizeof(int); ++i) {
165+
*(ptr + i) = 13;
166+
}
167+
168+
{
169+
cl::sycl::buffer<int, 2> buffer_2d(data.data(), rng);
170+
cl::sycl::buffer<int, 1> buffer_1d = buffer_2d.reinterpret<int, 1>(
171+
cl::sycl::range<1>(buffer_2d.get_count()));
172+
// let's make an offset like for 2d buffer {offset, offset}
173+
// with a range = size elements
174+
cl::sycl::buffer<int, 1> subbuffer_1d(
175+
buffer_1d, cl::sycl::id<1>(offset * total_size + offset),
176+
cl::sycl::range<1>(size));
177+
178+
cl::sycl::buffer<char, 1> reinterpret_subbuf =
179+
subbuffer_1d.reinterpret<char, 1>(subbuffer_1d.get_size());
180+
181+
cl::sycl::queue cmd_queue;
182+
cmd_queue.submit([&](cl::sycl::handler &cgh) {
183+
auto rb_acc =
184+
reinterpret_subbuf.get_access<cl::sycl::access::mode::write>(cgh);
185+
cgh.parallel_for<class foo_3>(
186+
reinterpret_subbuf.get_range(),
187+
[=](cl::sycl::id<1> index) { rb_acc[index] = 13; });
188+
});
189+
}
190+
191+
for (std::size_t i = 0; i < total_size; ++i)
192+
for (std::size_t j = 0; j < total_size; ++j)
193+
assert(data[i * total_size + j] == expected_data[i * total_size + j]);
194+
}
84195
return failed;
85196
}

0 commit comments

Comments
 (0)