25 #include <type_traits>
28 inline namespace _V1 {
47 using EnableIfOutputPointerT = std::enable_if_t<
48 std::is_pointer<T>::value>;
51 using EnableIfOutputIteratorT = std::enable_if_t<
52 !std::is_pointer<T>::value>;
56 std::unique_ptr<SYCLMemObjAllocator> Allocator)
57 : MAllocator(
std::move(Allocator)), MProps(Props), MInteropEvent(nullptr),
58 MInteropContext(nullptr), MInteropMemObject(nullptr),
59 MOpenCLInterop(false), MHostPtrReadOnly(false), MNeedWriteBack(true),
60 MSizeInBytes(SizeInBytes), MUserPtr(nullptr), MShadowCopy(nullptr),
61 MUploadDataFunctor(nullptr), MSharedPtrStorage(nullptr),
62 MHostPtrProvided(false) {}
65 std::unique_ptr<SYCLMemObjAllocator> Allocator)
69 const size_t SizeInBytes,
event AvailableEvent,
70 std::unique_ptr<SYCLMemObjAllocator> Allocator);
74 std::unique_ptr<SYCLMemObjAllocator> Allocator)
76 (size_t)0, AvailableEvent,
77 std::move(Allocator)) {}
80 bool OwnNativeHandle,
event AvailableEvent,
81 std::unique_ptr<SYCLMemObjAllocator> Allocator);
84 bool OwnNativeHandle,
event AvailableEvent,
85 std::unique_ptr<SYCLMemObjAllocator> Allocator,
96 size_t get_count()
const {
return size(); }
98 size_t AllocatorValueSize = MAllocator->getValueSize();
99 return (getSizeInBytes() + AllocatorValueSize - 1) / AllocatorValueSize;
103 return MProps.has_property<propertyT>();
107 return MProps.get_property<propertyT>();
111 MProps.add_or_replace_accessor_properties(PropertyList);
115 MProps.delete_accessor_property(Kind);
126 MAllocator->deallocate(Ptr, size());
129 void releaseMem(
ContextImplPtr Context,
void *MemAllocation)
override;
132 return MOpenCLInterop ?
static_cast<void *
>(MInteropMemObject) : MUserPtr;
140 MUploadDataFunctor = [
this]() {
141 if (MSharedPtrStorage.use_count() > 1) {
142 void *FinalData =
const_cast<void *
>(MSharedPtrStorage.get());
143 updateHostMemory(FinalData);
146 MHostPtrProvided =
true;
150 const std::function<
void(
const std::function<
void(
void *
const Ptr)> &)>
153 auto UpdateFunc = [
this](
void *
const Ptr) { updateHostMemory(Ptr); };
154 MUploadDataFunctor = [FinalDataFunc, UpdateFunc]() {
155 FinalDataFunc(UpdateFunc);
157 MHostPtrProvided =
true;
161 void updateHostMemory(
void *
const Ptr);
168 void updateHostMemory();
172 return has_property<property::buffer::use_host_ptr>() ||
173 has_property<property::image::use_host_ptr>();
178 (
reinterpret_cast<std::uintptr_t
>(HostPtr) % RequiredAlign) == 0;
179 return Aligned || useHostPtr();
183 return !MHostPtrReadOnly && canReadHostPtr(HostPtr, RequiredAlign);
187 MHostPtrProvided =
true;
188 if (!MHostPtrReadOnly && HostPtr) {
189 set_final_data([HostPtr](
const std::function<
void(
void *
const Ptr)> &F) {
195 if (canReuseHostPtr(HostPtr, RequiredAlign)) {
197 }
else if (canReadHostPtr(HostPtr, RequiredAlign)) {
199 MCreateShadowCopy = [
this, RequiredAlign, HostPtr]() ->
void {
200 setAlign(RequiredAlign);
201 MShadowCopy = allocateHostMem();
202 MUserPtr = MShadowCopy;
203 std::memcpy(MUserPtr, HostPtr, MSizeInBytes);
206 setAlign(RequiredAlign);
207 MShadowCopy = allocateHostMem();
208 MUserPtr = MShadowCopy;
209 std::memcpy(MUserPtr, HostPtr, MSizeInBytes);
215 MHostPtrReadOnly =
true;
216 handleHostData(
const_cast<void *
>(HostPtr), RequiredAlign);
220 const size_t RequiredAlign,
bool IsConstPtr) {
221 MHostPtrProvided =
true;
222 MSharedPtrStorage = HostPtr;
223 MHostPtrReadOnly = IsConstPtr;
225 if (!MHostPtrReadOnly)
226 set_final_data_from_storage();
228 if (canReuseHostPtr(HostPtr.get(), RequiredAlign)) {
229 MUserPtr = HostPtr.get();
230 }
else if (canReadHostPtr(HostPtr.get(), RequiredAlign)) {
231 MUserPtr = HostPtr.get();
232 MCreateShadowCopy = [
this, RequiredAlign, HostPtr]() ->
void {
233 setAlign(RequiredAlign);
234 MShadowCopy = allocateHostMem();
235 MUserPtr = MShadowCopy;
236 std::memcpy(MUserPtr, HostPtr.get(), MSizeInBytes);
239 setAlign(RequiredAlign);
240 MShadowCopy = allocateHostMem();
241 MUserPtr = MShadowCopy;
242 std::memcpy(MUserPtr, HostPtr.get(), MSizeInBytes);
248 const size_t RequiredAlign,
bool IsConstPtr) {
249 MHostPtrReadOnly = IsConstPtr;
250 setAlign(RequiredAlign);
253 "Buffer constructor from a pair of iterator values does not support "
254 "use_host_ptr property.",
255 PI_ERROR_INVALID_OPERATION);
257 setAlign(RequiredAlign);
258 MShadowCopy = allocateHostMem();
259 MUserPtr = MShadowCopy;
261 CopyFromInput(MUserPtr);
265 MAllocator->setAlignment(RequiredAlign);
271 void handleWriteAccessorCreation();
277 (void)InitFromUserData;
280 throw runtime_error(
"Not implemented", PI_ERROR_INVALID_OPERATION);
287 bool isInterop()
const override;
298 void detachMemoryObject(
const std::shared_ptr<SYCLMemObjT> &Self)
const;
314 size_t CurrentVal = MGraphUseCount;
315 if (CurrentVal == 0) {
318 if (MGraphUseCount.compare_exchange_strong(CurrentVal, CurrentVal - 1) ==
330 void determineHostPtr(
const ContextImplPtr &Context,
bool InitFromUserData,
331 void *&HostPtr,
bool &HostPtrReadOnly);
371 bool MIsInternal =
false;
373 std::atomic<size_t> MGraphUseCount = 0;
377 std::function<void(
void)> MCreateShadowCopy = []() ->
void {};
378 bool MOwnNativeHandle =
true;
The context class represents a SYCL context on which kernel functions may be executed.
const std::unique_ptr< SYCLMemObjAllocator > & get_allocator_internal() const
ContextImplPtr getInteropContext() const override
__SYCL2020_DEPRECATED("get_count() is deprecated, please use size() instead") size_t get_count() const
void * allocateMem(ContextImplPtr Context, bool InitFromUserData, void *HostPtr, sycl::detail::pi::PiEvent &InteropEvent) override
void * allocateHostMem() override
virtual ~SYCLMemObjT()=default
bool has_property() const noexcept
void markNoLongerBeingUsedInGraph()
Decrement an internal counter for how many graphs are currently using this memory object.
ContextImplPtr MInteropContext
size_t getSizeInBytes() const noexcept override
void handleHostData(const std::shared_ptr< void > &HostPtr, const size_t RequiredAlign, bool IsConstPtr)
void releaseHostMem(void *Ptr) override
SYCLMemObjT(const property_list &Props, std::unique_ptr< SYCLMemObjAllocator > Allocator)
bool needsWriteBack() const
Returns true if this memory object requires a write_back on destruction.
std::shared_ptr< const void > MSharedPtrStorage
MemObjType getType() const override
sycl::detail::pi::PiMem MInteropMemObject
bool hasUserDataPtr() const override
void addOrReplaceAccessorProperties(const property_list &PropertyList)
EventImplPtr MInteropEvent
void * getUserPtr() const
size_t size() const noexcept
void setAlign(size_t RequiredAlign)
SYCLMemObjT(cl_mem MemObject, const context &SyclContext, event AvailableEvent, std::unique_ptr< SYCLMemObjAllocator > Allocator)
void markBeingUsedInGraph()
Increment an internal counter for how many graphs are currently using this memory object.
bool canReadHostPtr(void *HostPtr, const size_t RequiredAlign)
SYCLMemObjT(const size_t SizeInBytes, const property_list &Props, std::unique_ptr< SYCLMemObjAllocator > Allocator)
std::function< void(void)> MUploadDataFunctor
void set_final_data(const std::function< void(const std::function< void(void *const Ptr)> &)> &FinalDataFunc)
bool isHostPointerReadOnly() const override
void set_final_data(std::nullptr_t)
void handleHostData(const void *HostPtr, const size_t RequiredAlign)
void deleteAccessorProperty(const PropWithDataKind &Kind)
void set_write_back(bool NeedWriteBack)
std::unique_ptr< SYCLMemObjAllocator > MAllocator
bool usesPinnedHostMemory() const override
void set_final_data_from_storage()
bool isUsedInGraph() const
Returns true if any graphs are currently using this memory object.
void handleHostData(void *HostPtr, const size_t RequiredAlign)
void handleHostData(const std::function< void(void *)> &CopyFromInput, const size_t RequiredAlign, bool IsConstPtr)
bool canReuseHostPtr(void *HostPtr, const size_t RequiredAlign)
propertyT get_property() const
An event object can be used to synchronize memory transfers, enqueues of kernels and signaling barrie...
Objects of the property_list class are containers for the SYCL properties.
PiProgram cast(cl_program)=delete
std::shared_ptr< sycl::detail::context_impl > ContextImplPtr
static const PluginPtr & getPlugin(backend Backend)
std::shared_ptr< event_impl > EventImplPtr
std::shared_ptr< plugin > PluginPtr
static constexpr bool has_property()
class __SYCL_EBO __SYCL_SPECIAL_CLASS Dimensions
uintptr_t pi_native_handle
_Abi const simd< _Tp, _Abi > & noexcept