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) {
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)
96 
97  if (MOpenCLInterop) {
98  const plugin &Plugin = getPlugin();
100  pi::cast<RT::PiMem>(MInteropMemObject));
101  }
102 }
104  assert((MInteropContext != nullptr) &&
105  "Trying to get Plugin from SYCLMemObjT with nullptr ContextImpl.");
106  return (MInteropContext->getPlugin());
107 }
108 
110  pi_native_handle MemObject) {
111  size_t BufSize = 0;
112  const detail::plugin &Plugin = Context->getPlugin();
113  // TODO is there something required to support non-OpenCL backends?
115  detail::pi::cast<detail::RT::PiMem>(MemObject), PI_MEM_SIZE,
116  sizeof(size_t), &BufSize, nullptr);
117  return BufSize;
118 }
119 
120 bool SYCLMemObjT::isInterop() const { return MOpenCLInterop; }
121 
123  bool InitFromUserData, void *&HostPtr,
124  bool &HostPtrReadOnly) {
125  // The data for the allocation can be provided via either the user pointer
126  // (InitFromUserData, can be read-only) or a runtime-allocated read-write
127  // HostPtr. We can have one of these scenarios:
128  // 1. The allocation is the first one and on host. InitFromUserData == true.
129  // 2. The allocation is the first one and isn't on host. InitFromUserData
130  // varies based on unified host memory support and whether or not the data can
131  // be discarded.
132  // 3. The allocation is not the first one and is on host. InitFromUserData ==
133  // false, HostPtr == nullptr. This can only happen if the allocation command
134  // is not linked since it would be a no-op otherwise. Attempt to reuse the
135  // user pointer if it's read-write, but do not copy its contents if it's not.
136  // 4. The allocation is not the first one and not on host. InitFromUserData ==
137  // false, HostPtr is provided if the command is linked. The host pointer is
138  // guaranteed to be reused in this case.
139  if (Context->is_host() && !MOpenCLInterop && !MHostPtrReadOnly)
140  InitFromUserData = true;
141 
142  if (InitFromUserData) {
143  assert(!HostPtr && "Cannot init from user data and reuse host ptr provided "
144  "simultaneously");
145  HostPtr = getUserPtr();
146  HostPtrReadOnly = MHostPtrReadOnly;
147  } else
148  HostPtrReadOnly = false;
149 }
150 } // namespace detail
151 } // __SYCL_INLINE_VER_NAMESPACE(_V1)
152 } // namespace sycl
The context class represents a SYCL context on which kernel functions may be executed.
Definition: context.hpp:41
static void releaseMemObj(ContextImplPtr TargetContext, SYCLMemObjI *MemObj, void *MemAllocation, void *UserPtr)
std::shared_ptr< MemObjRecord > MRecord
void determineHostPtr(const ContextImplPtr &Context, bool InitFromUserData, void *&HostPtr, bool &HostPtrReadOnly)
void releaseHostMem(void *Ptr) override
void releaseMem(ContextImplPtr Context, void *MemAllocation) override
const plugin & getPlugin() const
SYCLMemObjT(const size_t SizeInBytes, const property_list &Props, std::unique_ptr< SYCLMemObjAllocator > Allocator)
std::function< void(void)> MUploadDataFunctor
static size_t getBufSizeForContext(const ContextImplPtr &Context, pi_native_handle MemObject)
EventImplPtr addCopyBack(Requirement *Req)
Registers a command group, that copies most recent memory to the memory pointed by the requirement.
Definition: scheduler.cpp:170
void removeMemoryObject(detail::SYCLMemObjI *MemObj)
Removes buffer from the graph.
Definition: scheduler.cpp:259
static Scheduler & getInstance()
Definition: scheduler.cpp:207
The plugin class provides a unified interface to the underlying low-level runtimes for the device-agn...
Definition: plugin.hpp:90
void call(ArgsT... Args) const
Calls the API, traces the call, checks the result.
Definition: plugin.hpp:217
backend getBackend(void) const
Definition: plugin.hpp:229
An event object can be used to synchronize memory transfers, enqueues of kernels and signaling barrie...
Definition: event.hpp:40
#define __SYCL_INLINE_VER_NAMESPACE(X)
::pi_context PiContext
Definition: pi.hpp:114
std::shared_ptr< sycl::detail::context_impl > ContextImplPtr
Definition: event_impl.hpp:30
decltype(Obj::impl) getSyclObjImpl(const Obj &SyclObject)
Definition: common.hpp:248
std::shared_ptr< event_impl > EventImplPtr
Definition: cg.hpp:42
class __SYCL_EBO __SYCL_SPECIAL_CLASS __SYCL_TYPE(local_accessor) local_accessor class __SYCL_EBO __SYCL_SPECIAL_CLASS AccessMode
Definition: accessor.hpp:2782
---— Error handling, matching OpenCL plugin semantics.
Definition: access.hpp:14
uintptr_t pi_native_handle
Definition: pi.h:111
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)
pi_result piMemRetain(pi_mem mem)
pi_result piMemRelease(pi_mem mem)
pi_result piextMemCreateWithNativeHandle(pi_native_handle nativeHandle, pi_context context, bool ownNativeHandle, pi_mem *mem)
Creates PI mem object from a native handle.
@ PI_MEM_SIZE
Definition: pi.h:943
@ PI_MEM_CONTEXT
Definition: pi.h:943