Skip to content

Commit 0f5d54e

Browse files
committed
[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 7e5a7aa commit 0f5d54e

File tree

3 files changed

+80
-46
lines changed

3 files changed

+80
-46
lines changed

sycl/include/CL/sycl/accessor.hpp

+6-21
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.get_range(), 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

+5-21
Original file line numberDiff line numberDiff line change
@@ -135,16 +135,16 @@ template <typename AllocatorT> class buffer_impl {
135135
"Input context must be the same as the context of cl_mem");
136136
OCLState.Mem = MemObject;
137137
CHECK_OCL_CODE(clRetainMemObject(MemObject));
138+
139+
BufData.resize(get_size());
140+
BufPtr = reinterpret_cast<void *>(BufData.data());
138141
}
139142

140143
size_t get_size() const { return SizeInBytes; }
141144

142145
~buffer_impl() {
143-
if (!OpenCLInterop)
144-
// TODO. Use node instead?
145-
simple_scheduler::Scheduler::getInstance()
146-
.copyBack<access::mode::read_write, access::target::host_buffer>(
147-
*this);
146+
simple_scheduler::Scheduler::getInstance()
147+
.copyBack<access::mode::read_write, access::target::host_buffer>(*this);
148148

149149
if (uploadData != nullptr && NeedWriteBack) {
150150
uploadData();
@@ -160,9 +160,6 @@ template <typename AllocatorT> class buffer_impl {
160160
void set_final_data(std::nullptr_t) { uploadData = nullptr; }
161161

162162
template <typename T> void set_final_data(weak_ptr_class<T> final_data) {
163-
if (OpenCLInterop)
164-
throw cl::sycl::runtime_error(
165-
"set_final_data could not be used with interoperability buffer");
166163
uploadData = [this, final_data]() {
167164
if (auto finalData = final_data.lock()) {
168165
T *Ptr = reinterpret_cast<T *>(BufPtr);
@@ -172,9 +169,6 @@ template <typename AllocatorT> class buffer_impl {
172169
}
173170

174171
template <typename Destination> void set_final_data(Destination final_data) {
175-
if (OpenCLInterop)
176-
throw cl::sycl::runtime_error(
177-
"set_final_data could not be used with interoperability buffer");
178172
static_assert(!std::is_const<Destination>::value,
179173
"Can not write in a constant Destination. Destination should "
180174
"not be const.");
@@ -390,11 +384,6 @@ void buffer_impl<AllocatorT>::moveMemoryTo(
390384

391385
ContextImplPtr Context = detail::getSyclObjImpl(Queue->get_context());
392386

393-
if (OpenCLInterop && (Context->getHandleRef() != OpenCLContext))
394-
throw cl::sycl::runtime_error(
395-
"Interoperability buffer could not be used in a context other than the "
396-
"context associated with the OpenCL memory object.");
397-
398387
// TODO: Move all implementation specific commands to separate file?
399388
// TODO: Make allocation in separate command?
400389

@@ -523,11 +512,6 @@ void buffer_impl<AllocatorT>::allocate(QueueImplPtr Queue,
523512

524513
ContextImplPtr Context = detail::getSyclObjImpl(Queue->get_context());
525514

526-
if (OpenCLInterop && (Context->getHandleRef() != OpenCLContext))
527-
throw cl::sycl::runtime_error(
528-
"Interoperability buffer could not be used in a context other than the "
529-
"context associated with the OpenCL memory object.");
530-
531515
if (OpenCLInterop) {
532516
// For interoperability instance of the SYCL buffer class being constructed
533517
// must wait for the SYCL event parameter, if one is provided,

sycl/test/basic_tests/buffer/buffer_interop.cpp

+69-4
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)