diff --git a/sycl/include/CL/sycl/accessor.hpp b/sycl/include/CL/sycl/accessor.hpp index 6ab337be1d075..9772865965513 100644 --- a/sycl/include/CL/sycl/accessor.hpp +++ b/sycl/include/CL/sycl/accessor.hpp @@ -730,13 +730,8 @@ class accessor #endif auto BufImpl = detail::getSyclObjImpl(bufferRef); if (AccessTarget == access::target::host_buffer) { - if (BufImpl->OpenCLInterop) { - throw cl::sycl::runtime_error( - "Host access to interoperability buffer is not allowed"); - } else { - simple_scheduler::Scheduler::getInstance() - .copyBack(*BufImpl); - } + simple_scheduler::Scheduler::getInstance() + .copyBack(*BufImpl); } if (BufImpl->OpenCLInterop && !BufImpl->isValidAccessToMem(accessMode)) { throw cl::sycl::runtime_error( @@ -818,13 +813,8 @@ class accessor #endif auto BufImpl = detail::getSyclObjImpl(bufferRef); if (AccessTarget == access::target::host_buffer) { - if (BufImpl->OpenCLInterop) { - throw cl::sycl::runtime_error( - "Host access to interoperability buffer is not allowed"); - } else { - simple_scheduler::Scheduler::getInstance() - .copyBack(*BufImpl); - } + simple_scheduler::Scheduler::getInstance() + .copyBack(*BufImpl); } if (BufImpl->OpenCLInterop && !BufImpl->isValidAccessToMem(accessMode)) { throw cl::sycl::runtime_error( @@ -913,13 +903,8 @@ class accessor bufferRef.get_range(), Offset)) { auto BufImpl = detail::getSyclObjImpl(bufferRef); if (AccessTarget == access::target::host_buffer) { - if (BufImpl->OpenCLInterop) { - throw cl::sycl::runtime_error( - "Host access to interoperability buffer is not allowed"); - } else { - simple_scheduler::Scheduler::getInstance() - .copyBack(*BufImpl); - } + simple_scheduler::Scheduler::getInstance() + .copyBack(*BufImpl); } if (BufImpl->OpenCLInterop && !BufImpl->isValidAccessToMem(accessMode)) { throw cl::sycl::runtime_error( diff --git a/sycl/include/CL/sycl/detail/buffer_impl.hpp b/sycl/include/CL/sycl/detail/buffer_impl.hpp index 4da8134a94424..aaf7b69ae24f3 100644 --- a/sycl/include/CL/sycl/detail/buffer_impl.hpp +++ b/sycl/include/CL/sycl/detail/buffer_impl.hpp @@ -135,16 +135,16 @@ template class buffer_impl { "Input context must be the same as the context of cl_mem"); OCLState.Mem = MemObject; CHECK_OCL_CODE(clRetainMemObject(MemObject)); + + BufData.resize(get_size()); + BufPtr = reinterpret_cast(BufData.data()); } size_t get_size() const { return SizeInBytes; } ~buffer_impl() { - if (!OpenCLInterop) - // TODO. Use node instead? - simple_scheduler::Scheduler::getInstance() - .copyBack( - *this); + simple_scheduler::Scheduler::getInstance() + .copyBack(*this); if (uploadData != nullptr && NeedWriteBack) { uploadData(); @@ -160,9 +160,6 @@ template class buffer_impl { void set_final_data(std::nullptr_t) { uploadData = nullptr; } template void set_final_data(weak_ptr_class final_data) { - if (OpenCLInterop) - throw cl::sycl::runtime_error( - "set_final_data could not be used with interoperability buffer"); uploadData = [this, final_data]() { if (auto finalData = final_data.lock()) { T *Ptr = reinterpret_cast(BufPtr); @@ -172,9 +169,6 @@ template class buffer_impl { } template void set_final_data(Destination final_data) { - if (OpenCLInterop) - throw cl::sycl::runtime_error( - "set_final_data could not be used with interoperability buffer"); static_assert(!std::is_const::value, "Can not write in a constant Destination. Destination should " "not be const."); @@ -390,11 +384,6 @@ void buffer_impl::moveMemoryTo( ContextImplPtr Context = detail::getSyclObjImpl(Queue->get_context()); - if (OpenCLInterop && (Context->getHandleRef() != OpenCLContext)) - throw cl::sycl::runtime_error( - "Interoperability buffer could not be used in a context other than the " - "context associated with the OpenCL memory object."); - // TODO: Move all implementation specific commands to separate file? // TODO: Make allocation in separate command? @@ -523,11 +512,6 @@ void buffer_impl::allocate(QueueImplPtr Queue, ContextImplPtr Context = detail::getSyclObjImpl(Queue->get_context()); - if (OpenCLInterop && (Context->getHandleRef() != OpenCLContext)) - throw cl::sycl::runtime_error( - "Interoperability buffer could not be used in a context other than the " - "context associated with the OpenCL memory object."); - if (OpenCLInterop) { // For interoperability instance of the SYCL buffer class being constructed // must wait for the SYCL event parameter, if one is provided, diff --git a/sycl/test/basic_tests/buffer/buffer_interop.cpp b/sycl/test/basic_tests/buffer/buffer_interop.cpp index f0bdaa2090711..aee484c7b2a65 100644 --- a/sycl/test/basic_tests/buffer/buffer_interop.cpp +++ b/sycl/test/basic_tests/buffer/buffer_interop.cpp @@ -18,7 +18,7 @@ using namespace cl::sycl; int main() { bool Failed = false; { - const size_t Size = 32; + constexpr size_t Size = 32; int Init[Size] = {5}; cl_int Error = CL_SUCCESS; cl::sycl::range<1> InteropRange; @@ -31,7 +31,7 @@ int main() { MyQueue.get_context().get(), CL_MEM_READ_WRITE | CL_MEM_COPY_HOST_PTR, Size * sizeof(int), Init, &Error); CHECK_OCL_CODE(Error); - buffer Buffer(OpenCLBuffer, MyQueue.get_context()); + buffer Buffer{OpenCLBuffer, MyQueue.get_context()}; if (Buffer.get_range() != InteropRange) { assert(false); @@ -55,8 +55,8 @@ int main() { int Data[Size] = {10}; std::vector Result(Size, 0); { - buffer BufferData(Data, range<1>(Size), - {property::buffer::use_host_ptr()}); + buffer BufferData{Data, range<1>(Size), + {property::buffer::use_host_ptr()}}; BufferData.set_final_data(Result.begin()); MyQueue.submit([&](handler &CGH) { auto Data = BufferData.get_access(CGH); @@ -79,5 +79,70 @@ int main() { } } } + // Check set_final_data + { + constexpr size_t Size = 32; + int Init[Size] = {5}; + int Result[Size] = {5}; + cl_int Error = CL_SUCCESS; + + queue MyQueue; + + cl_mem OpenCLBuffer = clCreateBuffer( + MyQueue.get_context().get(), CL_MEM_READ_WRITE | CL_MEM_COPY_HOST_PTR, + Size * sizeof(int), Init, &Error); + CHECK_OCL_CODE(Error); + { + buffer Buffer{OpenCLBuffer, MyQueue.get_context()}; + Buffer.set_final_data(Result); + + MyQueue.submit([&](handler &CGH) { + auto B = Buffer.get_access(CGH); + CGH.parallel_for( + range<1>{Size}, [=](id<1> Index) { B[Index] = 10; }); + }); + } + Error = clReleaseMemObject(OpenCLBuffer); + CHECK_OCL_CODE(Error); + for (size_t i = 0; i < Size; ++i) { + if (Result[i] != 10) { + std::cout << " array[" << i << "] is " << Result[i] << " expected " + << 10 << std::endl; + assert(false); + Failed = true; + } + } + } + // Check host accessor + { + constexpr size_t Size = 32; + int Init[Size] = {5}; + cl_int Error = CL_SUCCESS; + + queue MyQueue; + + cl_mem OpenCLBuffer = clCreateBuffer( + MyQueue.get_context().get(), CL_MEM_READ_WRITE | CL_MEM_COPY_HOST_PTR, + Size * sizeof(int), Init, &Error); + CHECK_OCL_CODE(Error); + buffer Buffer{OpenCLBuffer, MyQueue.get_context()}; + + MyQueue.submit([&](handler &CGH) { + auto B = Buffer.get_access(CGH); + CGH.parallel_for(range<1>{Size}, + [=](id<1> Index) { B[Index] = 10; }); + }); + auto Acc = Buffer.get_access(); + for (size_t i = 0; i < Size; ++i) { + if (Acc[i] != 10) { + std::cout << " array[" << i << "] is " << Acc[i] << " expected " + << 10 << std::endl; + assert(false); + Failed = true; + } + } + Error = clReleaseMemObject(OpenCLBuffer); + CHECK_OCL_CODE(Error); + } return Failed; }