DPC++ Runtime
Runtime libraries for oneAPI DPC++
sycl_mem_obj_t.cpp
Go to the documentation of this file.
1 //==------------ sycl_mem_obj_t.cpp - SYCL standard header file ------------==//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 
10 #include <detail/event_impl.hpp>
12 #include <detail/plugin.hpp>
15 
16 namespace sycl {
18 namespace detail {
19 
20 SYCLMemObjT::SYCLMemObjT(pi_native_handle MemObject, const context &SyclContext,
21  const size_t, event AvailableEvent,
22  std::unique_ptr<SYCLMemObjAllocator> Allocator)
23  : SYCLMemObjT(MemObject, SyclContext, true, AvailableEvent,
24  std::move(Allocator)) {}
25 
26 SYCLMemObjT::SYCLMemObjT(pi_native_handle MemObject, const context &SyclContext,
27  bool OwnNativeHandle, event AvailableEvent,
28  std::unique_ptr<SYCLMemObjAllocator> Allocator)
29  : MAllocator(std::move(Allocator)), MProps(),
30  MInteropEvent(detail::getSyclObjImpl(std::move(AvailableEvent))),
31  MInteropContext(detail::getSyclObjImpl(SyclContext)),
32  MOpenCLInterop(true), MHostPtrReadOnly(false), MNeedWriteBack(true),
33  MUserPtr(nullptr), MShadowCopy(nullptr), MUploadDataFunctor(nullptr),
34  MSharedPtrStorage(nullptr), MHostPtrProvided(true) {
35  if (MInteropContext->is_host())
36  throw sycl::invalid_parameter_error(
37  "Creation of interoperability memory object using host context is "
38  "not allowed",
39  PI_ERROR_INVALID_CONTEXT);
40 
41  RT::PiContext Context = nullptr;
42  const plugin &Plugin = getPlugin();
43 
45  MemObject, MInteropContext->getHandleRef(), OwnNativeHandle,
47 
48  // Get the size of the buffer in bytes
50  MInteropMemObject, PI_MEM_SIZE, sizeof(size_t), &MSizeInBytes, nullptr);
51 
53  sizeof(Context), &Context, nullptr);
54 
55  if (MInteropContext->getHandleRef() != Context)
56  throw sycl::invalid_parameter_error(
57  "Input context must be the same as the context of cl_mem",
58  PI_ERROR_INVALID_CONTEXT);
59 
60  if (Plugin.getBackend() == backend::opencl)
62 }
63 
64 void SYCLMemObjT::releaseMem(ContextImplPtr Context, void *MemAllocation) {
65  void *Ptr = getUserPtr();
66  return MemoryManager::releaseMemObj(Context, this, MemAllocation, Ptr);
67 }
68 
69 void SYCLMemObjT::updateHostMemory(void *const Ptr) {
70  const id<3> Offset{0, 0, 0};
71  const range<3> AccessRange{MSizeInBytes, 1, 1};
72  const range<3> MemoryRange{MSizeInBytes, 1, 1};
74  SYCLMemObjI *SYCLMemObject = this;
75  const int Dims = 1;
76  const int ElemSize = 1;
77 
78  Requirement Req(Offset, AccessRange, MemoryRange, AccessMode, SYCLMemObject,
79  Dims, ElemSize);
80  Req.MData = Ptr;
81 
83  if (Event)
84  Event->wait(Event);
85 }
86 
88  if ((MUploadDataFunctor != nullptr) && MNeedWriteBack)
90 
91  // If we're attached to a memory record, process the deletion of the memory
92  // record. We may get detached before we do this.
93  if (MRecord) {
94  bool Result = Scheduler::getInstance().removeMemoryObject(this);
95  std::ignore = Result; // for no assert build
96  assert(
97  Result &&
98  "removeMemoryObject should not return false in mem object destructor");
99  }
101 
102  if (MOpenCLInterop) {
103  const plugin &Plugin = getPlugin();
105  pi::cast<RT::PiMem>(MInteropMemObject));
106  }
107 }
109  assert((MInteropContext != nullptr) &&
110  "Trying to get Plugin from SYCLMemObjT with nullptr ContextImpl.");
111  return (MInteropContext->getPlugin());
112 }
113 
115  pi_native_handle MemObject) {
116  size_t BufSize = 0;
117  const detail::plugin &Plugin = Context->getPlugin();
118  // TODO is there something required to support non-OpenCL backends?
120  detail::pi::cast<detail::RT::PiMem>(MemObject), PI_MEM_SIZE,
121  sizeof(size_t), &BufSize, nullptr);
122  return BufSize;
123 }
124 
125 bool SYCLMemObjT::isInterop() const { return MOpenCLInterop; }
126 
128  bool InitFromUserData, void *&HostPtr,
129  bool &HostPtrReadOnly) {
130  // The data for the allocation can be provided via either the user pointer
131  // (InitFromUserData, can be read-only) or a runtime-allocated read-write
132  // HostPtr. We can have one of these scenarios:
133  // 1. The allocation is the first one and on host. InitFromUserData == true.
134  // 2. The allocation is the first one and isn't on host. InitFromUserData
135  // varies based on unified host memory support and whether or not the data can
136  // be discarded.
137  // 3. The allocation is not the first one and is on host. InitFromUserData ==
138  // false, HostPtr == nullptr. This can only happen if the allocation command
139  // is not linked since it would be a no-op otherwise. Attempt to reuse the
140  // user pointer if it's read-write, but do not copy its contents if it's not.
141  // 4. The allocation is not the first one and not on host. InitFromUserData ==
142  // false, HostPtr is provided if the command is linked. The host pointer is
143  // guaranteed to be reused in this case.
144  if (Context->is_host() && !MOpenCLInterop && !MHostPtrReadOnly)
145  InitFromUserData = true;
146 
147  if (InitFromUserData) {
148  assert(!HostPtr && "Cannot init from user data and reuse host ptr provided "
149  "simultaneously");
150  HostPtr = getUserPtr();
151  HostPtrReadOnly = MHostPtrReadOnly;
152  } else
153  HostPtrReadOnly = false;
154 }
155 
157  const std::shared_ptr<SYCLMemObjT> &Self) const {
158  // Check MRecord without read lock because at this point we expect that no
159  // commands that operate on the buffer can be created. MRecord is nullptr on
160  // buffer creation and set to meaningfull
161  // value only if any operation on buffer submitted inside addCG call. addCG is
162  // called from queue::submit and buffer destruction could not overlap with it.
163  // ForceDeferredMemObjRelease is a workaround for managing auxiliary resources
164  // while preserving backward compatibility, see the comment for
165  // ForceDeferredMemObjRelease in scheduler.
168 }
169 
170 } // namespace detail
171 } // __SYCL_INLINE_VER_NAMESPACE(_V1)
172 } // namespace sycl
piMemGetInfo
pi_result piMemGetInfo(pi_mem mem, pi_mem_info param_name, size_t param_value_size, void *param_value, size_t *param_value_size_ret)
Definition: pi_esimd_emulator.cpp:1093
event_impl.hpp
sycl::_V1::access::mode
mode
Definition: access.hpp:30
context_impl.hpp
sycl::_V1::detail::SYCLMemObjT::MUploadDataFunctor
std::function< void(void)> MUploadDataFunctor
Definition: sycl_mem_obj_t.hpp:293
sycl::_V1::detail::ContextImplPtr
std::shared_ptr< sycl::detail::context_impl > ContextImplPtr
Definition: event_impl.hpp:30
sycl::_V1::detail::SYCLMemObjT::determineHostPtr
void determineHostPtr(const ContextImplPtr &Context, bool InitFromUserData, void *&HostPtr, bool &HostPtrReadOnly)
Definition: sycl_mem_obj_t.cpp:127
sycl::_V1::detail::SYCLMemObjT::releaseHostMem
void releaseHostMem(void *Ptr) override
Definition: sycl_mem_obj_t.hpp:116
sycl::_V1::detail::AccessorImplHost
Definition: accessor_impl.hpp:42
__SYCL_INLINE_VER_NAMESPACE
#define __SYCL_INLINE_VER_NAMESPACE(X)
Definition: defines_elementary.hpp:11
sycl::_V1::detail::SYCLMemObjT::releaseMem
void releaseMem(ContextImplPtr Context, void *MemAllocation) override
Definition: sycl_mem_obj_t.cpp:64
sycl::_V1::detail::SYCLMemObjT::MInteropMemObject
RT::PiMem MInteropMemObject
Definition: sycl_mem_obj_t.hpp:278
PI_MEM_SIZE
@ PI_MEM_SIZE
Definition: pi.h:976
sycl::_V1::detail::SYCLMemObjT::getPlugin
const plugin & getPlugin() const
Definition: sycl_mem_obj_t.cpp:108
sycl
---— Error handling, matching OpenCL plugin semantics.
Definition: access.hpp:14
plugin.hpp
sycl::_V1::detail::plugin::getBackend
backend getBackend(void) const
Definition: plugin.hpp:229
sycl::_V1::event
An event object can be used to synchronize memory transfers, enqueues of kernels and signaling barrie...
Definition: event.hpp:40
sycl::_V1::id< 3 >
scheduler.hpp
sycl::_V1::range< 3 >
sycl::_V1::detail::Scheduler::addCopyBack
EventImplPtr addCopyBack(Requirement *Req)
Registers a command group, that copies most recent memory to the memory pointed by the requirement.
Definition: scheduler.cpp:214
sycl::_V1::detail::plugin
The plugin class provides a unified interface to the underlying low-level runtimes for the device-agn...
Definition: plugin.hpp:90
piMemRelease
pi_result piMemRelease(pi_mem mem)
Definition: pi_esimd_emulator.cpp:1105
sycl::_V1::detail::SYCLMemObjT::getUserPtr
void * getUserPtr() const
Definition: sycl_mem_obj_t.hpp:123
sycl::_V1::detail::SYCLMemObjT::MHostPtrReadOnly
bool MHostPtrReadOnly
Definition: sycl_mem_obj_t.hpp:283
sycl::_V1::detail::pi::PiContext
::pi_context PiContext
Definition: pi.hpp:128
sycl::_V1::detail::Scheduler::removeMemoryObject
bool removeMemoryObject(detail::SYCLMemObjI *MemObj, bool StrictLock=true)
Removes buffer from the graph.
Definition: scheduler.cpp:266
sycl::_V1::detail::MemoryManager::releaseMemObj
static void releaseMemObj(ContextImplPtr TargetContext, SYCLMemObjI *MemObj, void *MemAllocation, void *UserPtr)
Definition: memory_manager.cpp:247
sycl::_V1::detail::EventImplPtr
std::shared_ptr< event_impl > EventImplPtr
Definition: cg.hpp:42
sycl::_V1::detail::SYCLMemObjT::SYCLMemObjT
SYCLMemObjT(const size_t SizeInBytes, const property_list &Props, std::unique_ptr< SYCLMemObjAllocator > Allocator)
Definition: sycl_mem_obj_t.hpp:54
sycl::_V1::detail::Scheduler::deferMemObjRelease
void deferMemObjRelease(const std::shared_ptr< detail::SYCLMemObjI > &MemObj)
Definition: scheduler.cpp:480
sycl::_V1::detail::SYCLMemObjT::MNeedWriteBack
bool MNeedWriteBack
Definition: sycl_mem_obj_t.hpp:285
pi_native_handle
uintptr_t pi_native_handle
Definition: pi.h:128
sycl::_V1::detail::SYCLMemObjT::MOpenCLInterop
bool MOpenCLInterop
Definition: sycl_mem_obj_t.hpp:281
sycl::_V1::detail::SYCLMemObjT::MShadowCopy
void * MShadowCopy
Definition: sycl_mem_obj_t.hpp:291
sycl::_V1::detail::SYCLMemObjT::getBufSizeForContext
static size_t getBufSizeForContext(const ContextImplPtr &Context, pi_native_handle MemObject)
Definition: sycl_mem_obj_t.cpp:114
PI_MEM_CONTEXT
@ PI_MEM_CONTEXT
Definition: pi.h:976
sycl::_V1::backend::opencl
@ opencl
piMemRetain
pi_result piMemRetain(pi_mem mem)
Definition: pi_esimd_emulator.cpp:1097
sycl::_V1::detail::SYCLMemObjT::updateHostMemory
void updateHostMemory()
Definition: sycl_mem_obj_t.cpp:87
sycl::_V1::detail::plugin::call
void call(ArgsT... Args) const
Calls the API, traces the call, checks the result.
Definition: plugin.hpp:217
sycl::_V1::detail::SYCLMemObjT::MHostPtrProvided
bool MHostPtrProvided
Definition: sycl_mem_obj_t.hpp:301
std
Definition: accessor.hpp:3201
sycl::_V1::detail::SYCLMemObjT::MSizeInBytes
size_t MSizeInBytes
Definition: sycl_mem_obj_t.hpp:287
sycl::_V1::detail::Scheduler::getInstance
static Scheduler & getInstance()
Definition: scheduler.cpp:252
piextMemCreateWithNativeHandle
pi_result piextMemCreateWithNativeHandle(pi_native_handle nativeHandle, pi_context context, bool ownNativeHandle, pi_mem *mem)
Creates PI mem object from a native handle.
Definition: pi_esimd_emulator.cpp:1295
sycl::_V1::detail::SYCLMemObjI
Definition: sycl_mem_obj_i.hpp:28
sycl::_V1::detail::AccessorImplHost::MData
void *& MData
Definition: accessor_impl.hpp:116
sycl::_V1::detail::SYCLMemObjT
Definition: sycl_mem_obj_t.hpp:39
sycl::_V1::detail::Scheduler::ForceDeferredMemObjRelease
static thread_local bool ForceDeferredMemObjRelease
Definition: scheduler.hpp:882
sycl::_V1::detail::SYCLMemObjT::detachMemoryObject
void detachMemoryObject(const std::shared_ptr< SYCLMemObjT > &Self) const
Definition: sycl_mem_obj_t.cpp:156
sycl::_V1::detail::SYCLMemObjT::MInteropContext
ContextImplPtr MInteropContext
Definition: sycl_mem_obj_t.hpp:275
sycl::_V1::AccessMode
class __SYCL_EBO __SYCL_SPECIAL_CLASS __SYCL_TYPE(local_accessor) local_accessor class __SYCL_EBO __SYCL_SPECIAL_CLASS AccessMode
Definition: accessor.hpp:2825
sycl::_V1::detail::SYCLMemObjT::isInterop
bool isInterop() const
Definition: sycl_mem_obj_t.cpp:125
sycl::_V1::detail::SYCLMemObjI::MRecord
std::shared_ptr< MemObjRecord > MRecord
Definition: sycl_mem_obj_i.hpp:74
sycl::_V1::access::mode::read
@ read
sycl_mem_obj_t.hpp
sycl::_V1::detail::getSyclObjImpl
decltype(Obj::impl) getSyclObjImpl(const Obj &SyclObject)
Definition: common.hpp:300
sycl::_V1::context
The context class represents a SYCL context on which kernel functions may be executed.
Definition: context.hpp:41
memory_manager.hpp