Skip to content

Commit 39e2c74

Browse files
Fznamznonvladimirlaz
authored andcommitted
[SYCL] Allow host access for interoperability buffers
This change allows using set_final_data and host accessors with interoperability buffer Signed-off-by: Mariya Podchishchaeva <mariya.podchishchaeva@intel.com>
1 parent c9f21fa commit 39e2c74

File tree

3 files changed

+80
-46
lines changed

3 files changed

+80
-46
lines changed

sycl/include/CL/sycl/accessor.hpp

Lines changed: 6 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -730,13 +730,8 @@ class accessor
730730
#endif
731731
auto BufImpl = detail::getSyclObjImpl(bufferRef);
732732
if (AccessTarget == access::target::host_buffer) {
733-
if (BufImpl->OpenCLInterop) {
734-
throw cl::sycl::runtime_error(
735-
"Host access to interoperability buffer is not allowed");
736-
} else {
737-
simple_scheduler::Scheduler::getInstance()
738-
.copyBack<AccessMode, AccessTarget>(*BufImpl);
739-
}
733+
simple_scheduler::Scheduler::getInstance()
734+
.copyBack<AccessMode, AccessTarget>(*BufImpl);
740735
}
741736
if (BufImpl->OpenCLInterop && !BufImpl->isValidAccessToMem(accessMode)) {
742737
throw cl::sycl::runtime_error(
@@ -818,13 +813,8 @@ class accessor
818813
#endif
819814
auto BufImpl = detail::getSyclObjImpl(bufferRef);
820815
if (AccessTarget == access::target::host_buffer) {
821-
if (BufImpl->OpenCLInterop) {
822-
throw cl::sycl::runtime_error(
823-
"Host access to interoperability buffer is not allowed");
824-
} else {
825-
simple_scheduler::Scheduler::getInstance()
826-
.copyBack<AccessMode, AccessTarget>(*BufImpl);
827-
}
816+
simple_scheduler::Scheduler::getInstance()
817+
.copyBack<AccessMode, AccessTarget>(*BufImpl);
828818
}
829819
if (BufImpl->OpenCLInterop && !BufImpl->isValidAccessToMem(accessMode)) {
830820
throw cl::sycl::runtime_error(
@@ -913,13 +903,8 @@ class accessor
913903
bufferRef.MemRange, Offset)) {
914904
auto BufImpl = detail::getSyclObjImpl(bufferRef);
915905
if (AccessTarget == access::target::host_buffer) {
916-
if (BufImpl->OpenCLInterop) {
917-
throw cl::sycl::runtime_error(
918-
"Host access to interoperability buffer is not allowed");
919-
} else {
920-
simple_scheduler::Scheduler::getInstance()
921-
.copyBack<AccessMode, AccessTarget>(*BufImpl);
922-
}
906+
simple_scheduler::Scheduler::getInstance()
907+
.copyBack<AccessMode, AccessTarget>(*BufImpl);
923908
}
924909
if (BufImpl->OpenCLInterop && !BufImpl->isValidAccessToMem(accessMode)) {
925910
throw cl::sycl::runtime_error(

sycl/include/CL/sycl/detail/buffer_impl.hpp

Lines changed: 5 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -164,16 +164,16 @@ template <typename AllocatorT> class buffer_impl {
164164
"Input context must be the same as the context of cl_mem");
165165
OCLState.Mem = MemObject;
166166
CHECK_OCL_CODE(clRetainMemObject(MemObject));
167+
168+
BufData.resize(get_size());
169+
BufPtr = reinterpret_cast<void *>(BufData.data());
167170
}
168171

169172
size_t get_size() const { return SizeInBytes; }
170173

171174
~buffer_impl() {
172-
if (!OpenCLInterop)
173-
// TODO. Use node instead?
174-
simple_scheduler::Scheduler::getInstance()
175-
.copyBack<access::mode::read_write, access::target::host_buffer>(
176-
*this);
175+
simple_scheduler::Scheduler::getInstance()
176+
.copyBack<access::mode::read_write, access::target::host_buffer>(*this);
177177

178178
if (uploadData != nullptr && NeedWriteBack) {
179179
uploadData();
@@ -189,9 +189,6 @@ template <typename AllocatorT> class buffer_impl {
189189
void set_final_data(std::nullptr_t) { uploadData = nullptr; }
190190

191191
template <typename T> void set_final_data(weak_ptr_class<T> final_data) {
192-
if (OpenCLInterop)
193-
throw cl::sycl::runtime_error(
194-
"set_final_data could not be used with interoperability buffer");
195192
uploadData = [this, final_data]() {
196193
if (auto finalData = final_data.lock()) {
197194
T *Ptr = reinterpret_cast<T *>(BufPtr);
@@ -201,9 +198,6 @@ template <typename AllocatorT> class buffer_impl {
201198
}
202199

203200
template <typename Destination> void set_final_data(Destination final_data) {
204-
if (OpenCLInterop)
205-
throw cl::sycl::runtime_error(
206-
"set_final_data could not be used with interoperability buffer");
207201
static_assert(!std::is_const<Destination>::value,
208202
"Can not write in a constant Destination. Destination should "
209203
"not be const.");
@@ -419,11 +413,6 @@ void buffer_impl<AllocatorT>::moveMemoryTo(
419413

420414
ContextImplPtr Context = detail::getSyclObjImpl(Queue->get_context());
421415

422-
if (OpenCLInterop && (Context->getHandleRef() != OpenCLContext))
423-
throw cl::sycl::runtime_error(
424-
"Interoperability buffer could not be used in a context other than the "
425-
"context associated with the OpenCL memory object.");
426-
427416
// TODO: Move all implementation specific commands to separate file?
428417
// TODO: Make allocation in separate command?
429418

@@ -552,11 +541,6 @@ void buffer_impl<AllocatorT>::allocate(QueueImplPtr Queue,
552541

553542
ContextImplPtr Context = detail::getSyclObjImpl(Queue->get_context());
554543

555-
if (OpenCLInterop && (Context->getHandleRef() != OpenCLContext))
556-
throw cl::sycl::runtime_error(
557-
"Interoperability buffer could not be used in a context other than the "
558-
"context associated with the OpenCL memory object.");
559-
560544
if (OpenCLInterop) {
561545
// For interoperability instance of the SYCL buffer class being constructed
562546
// must wait for the SYCL event parameter, if one is provided,

sycl/test/basic_tests/buffer/buffer_interop.cpp

Lines changed: 69 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ using namespace cl::sycl;
1818
int main() {
1919
bool Failed = false;
2020
{
21-
const size_t Size = 32;
21+
constexpr size_t Size = 32;
2222
int Init[Size] = {5};
2323
cl_int Error = CL_SUCCESS;
2424
cl::sycl::range<1> InteropRange;
@@ -31,7 +31,7 @@ int main() {
3131
MyQueue.get_context().get(), CL_MEM_READ_WRITE | CL_MEM_COPY_HOST_PTR,
3232
Size * sizeof(int), Init, &Error);
3333
CHECK_OCL_CODE(Error);
34-
buffer<int, 1> Buffer(OpenCLBuffer, MyQueue.get_context());
34+
buffer<int, 1> Buffer{OpenCLBuffer, MyQueue.get_context()};
3535

3636
if (Buffer.get_range() != InteropRange) {
3737
assert(false);
@@ -55,8 +55,8 @@ int main() {
5555
int Data[Size] = {10};
5656
std::vector<int> Result(Size, 0);
5757
{
58-
buffer<int, 1> BufferData(Data, range<1>(Size),
59-
{property::buffer::use_host_ptr()});
58+
buffer<int, 1> BufferData{Data, range<1>(Size),
59+
{property::buffer::use_host_ptr()}};
6060
BufferData.set_final_data(Result.begin());
6161
MyQueue.submit([&](handler &CGH) {
6262
auto Data = BufferData.get_access<access::mode::write>(CGH);
@@ -79,5 +79,70 @@ int main() {
7979
}
8080
}
8181
}
82+
// Check set_final_data
83+
{
84+
constexpr size_t Size = 32;
85+
int Init[Size] = {5};
86+
int Result[Size] = {5};
87+
cl_int Error = CL_SUCCESS;
88+
89+
queue MyQueue;
90+
91+
cl_mem OpenCLBuffer = clCreateBuffer(
92+
MyQueue.get_context().get(), CL_MEM_READ_WRITE | CL_MEM_COPY_HOST_PTR,
93+
Size * sizeof(int), Init, &Error);
94+
CHECK_OCL_CODE(Error);
95+
{
96+
buffer<int, 1> Buffer{OpenCLBuffer, MyQueue.get_context()};
97+
Buffer.set_final_data(Result);
98+
99+
MyQueue.submit([&](handler &CGH) {
100+
auto B = Buffer.get_access<access::mode::write>(CGH);
101+
CGH.parallel_for<class FinalData>(
102+
range<1>{Size}, [=](id<1> Index) { B[Index] = 10; });
103+
});
104+
}
105+
Error = clReleaseMemObject(OpenCLBuffer);
106+
CHECK_OCL_CODE(Error);
107+
for (size_t i = 0; i < Size; ++i) {
108+
if (Result[i] != 10) {
109+
std::cout << " array[" << i << "] is " << Result[i] << " expected "
110+
<< 10 << std::endl;
111+
assert(false);
112+
Failed = true;
113+
}
114+
}
115+
}
116+
// Check host accessor
117+
{
118+
constexpr size_t Size = 32;
119+
int Init[Size] = {5};
120+
cl_int Error = CL_SUCCESS;
121+
122+
queue MyQueue;
123+
124+
cl_mem OpenCLBuffer = clCreateBuffer(
125+
MyQueue.get_context().get(), CL_MEM_READ_WRITE | CL_MEM_COPY_HOST_PTR,
126+
Size * sizeof(int), Init, &Error);
127+
CHECK_OCL_CODE(Error);
128+
buffer<int, 1> Buffer{OpenCLBuffer, MyQueue.get_context()};
129+
130+
MyQueue.submit([&](handler &CGH) {
131+
auto B = Buffer.get_access<access::mode::write>(CGH);
132+
CGH.parallel_for<class HostAccess>(range<1>{Size},
133+
[=](id<1> Index) { B[Index] = 10; });
134+
});
135+
auto Acc = Buffer.get_access<cl::sycl::access::mode::read>();
136+
for (size_t i = 0; i < Size; ++i) {
137+
if (Acc[i] != 10) {
138+
std::cout << " array[" << i << "] is " << Acc[i] << " expected "
139+
<< 10 << std::endl;
140+
assert(false);
141+
Failed = true;
142+
}
143+
}
144+
Error = clReleaseMemObject(OpenCLBuffer);
145+
CHECK_OCL_CODE(Error);
146+
}
82147
return Failed;
83148
}

0 commit comments

Comments
 (0)