24 #include <type_traits>
39 class aligned_allocator;
51 std::is_pointer<T>::value>;
55 !std::is_pointer<T>::value>;
58 using EnableIfDefaultAllocator =
62 using EnableIfNonDefaultAllocator =
67 std::unique_ptr<SYCLMemObjAllocator> Allocator)
68 : MAllocator(
std::move(Allocator)), MProps(Props), MInteropEvent(nullptr),
69 MInteropContext(nullptr), MInteropMemObject(nullptr),
70 MOpenCLInterop(false), MHostPtrReadOnly(false), MNeedWriteBack(true),
71 MSizeInBytes(SizeInBytes), MUserPtr(nullptr), MShadowCopy(nullptr),
72 MUploadDataFunctor(nullptr), MSharedPtrStorage(nullptr) {}
75 std::unique_ptr<SYCLMemObjAllocator> Allocator)
80 const size_t SizeInBytes,
event AvailableEvent,
81 std::unique_ptr<SYCLMemObjAllocator> Allocator);
84 const size_t SizeInBytes,
event AvailableEvent,
85 std::unique_ptr<SYCLMemObjAllocator> Allocator);
89 std::unique_ptr<SYCLMemObjAllocator> Allocator)
90 :
SYCLMemObjT(MemObject, SyclContext, 0, AvailableEvent,
91 std::move(Allocator)) {}
94 bool OwmNativeHandle,
event AvailableEvent,
95 std::unique_ptr<SYCLMemObjAllocator> Allocator);
101 __SYCL_DLL_LOCAL
size_t getSize()
const override {
return MSizeInBytes; }
103 __SYCL_DLL_LOCAL
size_t get_count()
const {
return size(); }
104 __SYCL_DLL_LOCAL
size_t size() const noexcept {
105 size_t AllocatorValueSize = MAllocator->getValueSize();
106 return (getSize() + AllocatorValueSize - 1) / AllocatorValueSize;
109 template <
typename propertyT> __SYCL_DLL_LOCAL
bool has_property()
const {
110 return MProps.has_property<propertyT>();
113 template <
typename propertyT>
115 return MProps.get_property<propertyT>();
118 __SYCL_DLL_LOCAL
void
120 MProps.add_or_replace_accessor_properties(PropertyList);
124 MProps.delete_accessor_property(Kind);
127 template <
typename AllocatorT>
129 return MAllocator->getAllocator<AllocatorT>();
133 return MAllocator->allocate(size());
138 MAllocator->deallocate(Ptr, size());
141 void releaseMem(
ContextImplPtr Context,
void *MemAllocation)
override;
144 return MOpenCLInterop ?
static_cast<void *
>(MInteropMemObject) : MUserPtr;
148 MNeedWriteBack = NeedWriteBack;
152 MUploadDataFunctor =
nullptr;
155 template <
template <
typename T>
class PtrT,
typename T>
159 std::weak_ptr<T> TempFinalData(FinalData);
160 set_final_data(TempFinalData);
163 template <
typename T>
165 MUploadDataFunctor = [
this, FinalData]() {
166 if (std::shared_ptr<T> LockedFinalData = FinalData.lock()) {
167 updateHostMemory(LockedFinalData.get());
173 MUploadDataFunctor = [
this]() {
174 if (MSharedPtrStorage.use_count() > 1) {
175 void *FinalData =
const_cast<void *
>(MSharedPtrStorage.get());
176 updateHostMemory(FinalData);
181 template <
typename Destination>
182 __SYCL_DLL_LOCAL EnableIfOutputPointerT<Destination>
185 MUploadDataFunctor =
nullptr;
187 MUploadDataFunctor = [
this, FinalData]() {
188 updateHostMemory(FinalData);
192 template <
typename Destination>
193 __SYCL_DLL_LOCAL EnableIfOutputIteratorT<Destination>
195 MUploadDataFunctor = [
this, FinalData]() {
200 const size_t Size = MSizeInBytes /
sizeof(DestinationValueT);
201 std::unique_ptr<DestinationValueT[]> ContiguousStorage(
202 new DestinationValueT[Size]);
203 updateHostMemory(ContiguousStorage.get());
204 std::copy(ContiguousStorage.get(), ContiguousStorage.get() + Size,
210 void updateHostMemory(
void *
const Ptr);
217 void updateHostMemory();
221 return has_property<property::buffer::use_host_ptr>() ||
222 has_property<property::image::use_host_ptr>();
226 const size_t RequiredAlign) {
228 (
reinterpret_cast<std::uintptr_t
>(HostPtr) % RequiredAlign) == 0;
229 return Aligned || useHostPtr();
233 const size_t RequiredAlign) {
234 if (!MHostPtrReadOnly)
235 set_final_data(
reinterpret_cast<char *
>(HostPtr));
237 if (canReuseHostPtr(HostPtr, RequiredAlign)) {
240 setAlign(RequiredAlign);
241 MShadowCopy = allocateHostMem();
242 MUserPtr = MShadowCopy;
248 const size_t RequiredAlign) {
249 MHostPtrReadOnly =
true;
250 handleHostData(
const_cast<void *
>(HostPtr), RequiredAlign);
253 template <
typename T>
255 const size_t RequiredAlign) {
256 MSharedPtrStorage = HostPtr;
257 MHostPtrReadOnly = std::is_const<T>::value;
259 if (!MHostPtrReadOnly)
260 set_final_data_from_storage();
262 if (canReuseHostPtr(HostPtr.get(), RequiredAlign))
263 MUserPtr = HostPtr.get();
265 setAlign(RequiredAlign);
266 MShadowCopy = allocateHostMem();
267 MUserPtr = MShadowCopy;
268 std::memcpy(MUserPtr, HostPtr.get(), MSizeInBytes);
273 template <
class InputIterator>
275 const size_t RequiredAlign) {
277 setAlign(RequiredAlign);
280 "Buffer constructor from a pair of iterator values does not support "
281 "use_host_ptr property.",
284 setAlign(RequiredAlign);
285 MShadowCopy = allocateHostMem();
286 MUserPtr = MShadowCopy;
292 using IteratorPointerToNonConstValueType =
294 std::copy(First, Last,
295 static_cast<IteratorPointerToNonConstValueType
>(MUserPtr));
298 __SYCL_DLL_LOCAL
void setAlign(
size_t RequiredAlign) {
299 MAllocator->setAlignment(RequiredAlign);
310 bool InitFromUserData,
void *HostPtr,
313 (void)InitFromUserData;
320 return MemObjType::Undefined;
327 bool isInterop()
const;
331 void determineHostPtr(
const ContextImplPtr &Context,
bool InitFromUserData,
332 void *&HostPtr,
bool &HostPtrReadOnly);