diff --git a/sycl/include/CL/sycl/detail/buffer_impl.hpp b/sycl/include/CL/sycl/detail/buffer_impl.hpp index e1d29619f34ed..0f60b38fb50a3 100644 --- a/sycl/include/CL/sycl/detail/buffer_impl.hpp +++ b/sycl/include/CL/sycl/detail/buffer_impl.hpp @@ -390,31 +390,46 @@ void buffer_impl::moveMemoryTo( Event->setIsHostEvent(false); OCLState.Queue = std::move(Queue); - OCLState.Mem = nullptr; return; } // Copy from host to OCL device. if (OCLState.Queue->is_host() && !Queue->is_host()) { - const size_t ByteSize = get_size(); + if (nullptr == BufPtr) { + return; + } + cl_int Error; - cl_mem Mem = - clCreateBuffer(Context->getHandleRef(), CL_MEM_READ_WRITE, ByteSize, - /*host_ptr=*/nullptr, &Error); - CHECK_OCL_CODE(Error); + const size_t ByteSize = get_size(); - OCLState.Queue = std::move(Queue); - OCLState.Mem = Mem; + // We don't create new OpenCL buffer object to copy from OCL device to host + // when we already have them in OCLState. But if contexts of buffer object + // from OCLState and input Queue are not same - we should create new OpenCL + // buffer object. + bool NeedToCreateCLBuffer = true; + + if (OCLState.Mem != nullptr) { + cl_context MemCtx; + Error = clGetMemObjectInfo(OCLState.Mem, CL_MEM_CONTEXT, + sizeof(cl_context), &MemCtx, nullptr); + CHECK_OCL_CODE(Error); + NeedToCreateCLBuffer = MemCtx != Context->getHandleRef(); + } - // Just exit if nothing to read from host. - if (nullptr == BufPtr) { - return; + if (NeedToCreateCLBuffer) { + OCLState.Mem = + clCreateBuffer(Context->getHandleRef(), CL_MEM_READ_WRITE, ByteSize, + /*host_ptr=*/nullptr, &Error); + CHECK_OCL_CODE(Error); } + + OCLState.Queue = std::move(Queue); + std::vector CLEvents = detail::getOrWaitEvents(std::move(DepEvents), Context); cl_event &WriteBufEvent = Event->getHandleRef(); // Enqueue copying from host to new OCL buffer. Error = - clEnqueueWriteBuffer(OCLState.Queue->getHandleRef(), Mem, + clEnqueueWriteBuffer(OCLState.Queue->getHandleRef(), OCLState.Mem, /*blocking_write=*/CL_FALSE, /*offset=*/0, ByteSize, BufPtr, CLEvents.size(), CLEvents.data(), &WriteBufEvent); // replace &WriteBufEvent to NULL