diff --git a/sycl/include/sycl/accessor.hpp b/sycl/include/sycl/accessor.hpp index 834fc0cbcc246..3f3b0da4bcc26 100644 --- a/sycl/include/sycl/accessor.hpp +++ b/sycl/include/sycl/accessor.hpp @@ -19,12 +19,14 @@ #include #include #include +#include #include #include #include #include #include #include +#include #include #include #include @@ -264,20 +266,6 @@ template <> struct IsCxPropertyList> { constexpr static bool value = false; }; -// The function extends or truncates number of dimensions of objects of id -// or ranges classes. When extending the new values are filled with -// DefaultValue, truncation just removes extra values. -template class T, int OldDim> -static T convertToArrayOfN(T OldObj) { - T NewObj = InitializedVal::template get<0>(); - const int CopyDims = NewDim > OldDim ? OldDim : NewDim; - for (int I = 0; I < CopyDims; ++I) - NewObj[I] = OldObj[I]; - for (int I = CopyDims; I < NewDim; ++I) - NewObj[I] = DefaultValue; - return NewObj; -} - __SYCL_EXPORT device getDeviceFromHandler(handler &CommandGroupHandlerRef); template getRowPitch(), - detail::getSyclObjImpl(ImageRef)->getSlicePitch(), 0}, + : AccessorBaseHost({ImageRef.getRowPitch(), ImageRef.getSlicePitch(), 0}, detail::convertToArrayOfN<3, 1>(ImageRef.get_range()), detail::convertToArrayOfN<3, 1>(ImageRef.get_range()), AccessMode, detail::getSyclObjImpl(ImageRef).get(), Dimensions, ImageElementSize), MImageCount(ImageRef.size()), - MImgChannelOrder(detail::getSyclObjImpl(ImageRef)->getChannelOrder()), - MImgChannelType(detail::getSyclObjImpl(ImageRef)->getChannelType()) { + MImgChannelOrder(ImageRef.getChannelOrder()), + MImgChannelType(ImageRef.getChannelType()) { addHostAccessorAndWait(AccessorBaseHost::impl.get()); } #endif @@ -557,15 +544,14 @@ class image_accessor // host. } #else - : AccessorBaseHost({detail::getSyclObjImpl(ImageRef)->getRowPitch(), - detail::getSyclObjImpl(ImageRef)->getSlicePitch(), 0}, + : AccessorBaseHost({ImageRef.getRowPitch(), ImageRef.getSlicePitch(), 0}, detail::convertToArrayOfN<3, 1>(ImageRef.get_range()), detail::convertToArrayOfN<3, 1>(ImageRef.get_range()), AccessMode, detail::getSyclObjImpl(ImageRef).get(), Dimensions, ImageElementSize), MImageCount(ImageRef.size()), - MImgChannelOrder(detail::getSyclObjImpl(ImageRef)->getChannelOrder()), - MImgChannelType(detail::getSyclObjImpl(ImageRef)->getChannelType()) { + MImgChannelOrder(ImageRef.getChannelOrder()), + MImgChannelType(ImageRef.getChannelType()) { checkDeviceFeatureSupported( getDeviceFromHandler(CommandGroupHandlerRef)); } @@ -1203,7 +1189,7 @@ class __SYCL_SPECIAL_CLASS accessor : const property_list &PropertyList = {}, const detail::code_location CodeLoc = detail::code_location::current()) : accessor(BufferRef, PropertyList, CodeLoc) { - adjustAccPropsInBuf(detail::getSyclObjImpl(BufferRef).get()); + adjustAccPropsInBuf(BufferRef); } template AccessOffset, TagT, const property_list &PropertyList = {}, const detail::code_location CodeLoc = detail::code_location::current()) : accessor(BufferRef, AccessRange, AccessOffset, PropertyList, CodeLoc) { - adjustAccPropsInBuf(detail::getSyclObjImpl(BufferRef).get()); + adjustAccPropsInBuf(BufferRef); } template = 201703L - template - void adjustAccPropsInBuf(detail::SYCLMemObjI *SYCLMemObject) { + template + void adjustAccPropsInBuf(BufT &Buffer) { if constexpr (PropertyListT::template has_property< sycl::ext::intel::property::buffer_location>()) { auto location = (PropertyListT::template get_property< @@ -1863,18 +1849,14 @@ class __SYCL_SPECIAL_CLASS accessor : .get_location(); property_list PropList{ sycl::property::buffer::detail::buffer_location(location)}; - detail::SYCLMemObjT *SYCLMemObjectT = - dynamic_cast(SYCLMemObject); - SYCLMemObjectT->addOrReplaceAccessorProperties(PropList); + Buffer.addOrReplaceAccessorProperties(PropList); } else { - deleteAccPropsFromBuf(SYCLMemObject); + deleteAccPropsFromBuf(Buffer); } } - void deleteAccPropsFromBuf(detail::SYCLMemObjI *SYCLMemObject) { - detail::SYCLMemObjT *SYCLMemObjectT = - dynamic_cast(SYCLMemObject); - SYCLMemObjectT->deleteAccessorProperty( + template void deleteAccPropsFromBuf(BufT &Buffer) { + Buffer.deleteAccProps( sycl::detail::PropWithDataKind::AccPropBufferLocation); } #endif @@ -2261,8 +2243,7 @@ class __SYCL_SPECIAL_CLASS accessor( - Image, CommandGroupHandler, - (detail::getSyclObjImpl(Image))->getElementSize()) { + Image, CommandGroupHandler, Image.getElementSize()) { #ifndef __SYCL_DEVICE_ONLY__ detail::associateWithHandler(CommandGroupHandler, this, access::target::image); @@ -2274,8 +2255,7 @@ class __SYCL_SPECIAL_CLASS accessor( - Image, CommandGroupHandler, - (detail::getSyclObjImpl(Image))->getElementSize()) { + Image, CommandGroupHandler, Image.getElementSize()) { (void)propList; #ifndef __SYCL_DEVICE_ONLY__ detail::associateWithHandler(CommandGroupHandler, this, @@ -2319,14 +2299,14 @@ class accessor &Image) : detail::image_accessor( - Image, (detail::getSyclObjImpl(Image))->getElementSize()) {} + Image, Image.getElementSize()) {} template accessor(sycl::image &Image, const property_list &propList) : detail::image_accessor( - Image, (detail::getSyclObjImpl(Image))->getElementSize()) { + Image, Image.getElementSize()) { (void)propList; } }; @@ -2368,8 +2348,7 @@ class __SYCL_SPECIAL_CLASS accessor( - Image, CommandGroupHandler, - (detail::getSyclObjImpl(Image))->getElementSize()) { + Image, CommandGroupHandler, Image.getElementSize()) { #ifndef __SYCL_DEVICE_ONLY__ detail::associateWithHandler(CommandGroupHandler, this, access::target::image_array); @@ -2381,8 +2360,7 @@ class __SYCL_SPECIAL_CLASS accessor( - Image, CommandGroupHandler, - (detail::getSyclObjImpl(Image))->getElementSize()) { + Image, CommandGroupHandler, Image.getElementSize()) { (void)propList; #ifndef __SYCL_DEVICE_ONLY__ detail::associateWithHandler(CommandGroupHandler, this, diff --git a/sycl/include/sycl/buffer.hpp b/sycl/include/sycl/buffer.hpp index 39308e515251e..3225f7827737c 100644 --- a/sycl/include/sycl/buffer.hpp +++ b/sycl/include/sycl/buffer.hpp @@ -8,12 +8,14 @@ #pragma once -#include #include #include +#include +#include #include #include #include +#include #include namespace sycl { @@ -26,8 +28,16 @@ template class range; template using buffer_allocator = detail::sycl_memory_object_allocator; +template +class host_accessor; + +template +class buffer; + namespace detail { +class buffer_impl; + template buffer make_buffer_helper(pi_native_handle Handle, const context &Ctx, event Evt = {}, @@ -45,6 +55,71 @@ auto get_native_buffer(const buffer &Obj) template >> struct BufferInterop; + +// The non-template base for the sycl::buffer class +class __SYCL_EXPORT buffer_plain { +protected: + buffer_plain(size_t SizeInBytes, size_t, const property_list &Props, + std::unique_ptr Allocator); + + buffer_plain(void *HostData, size_t SizeInBytes, size_t RequiredAlign, + const property_list &Props, + std::unique_ptr Allocator); + + buffer_plain(const void *HostData, size_t SizeInBytes, size_t RequiredAlign, + const property_list &Props, + std::unique_ptr Allocator); + + buffer_plain(const std::shared_ptr &HostData, + const size_t SizeInBytes, size_t RequiredAlign, + const property_list &Props, + std::unique_ptr Allocator, + bool IsConstPtr); + + buffer_plain(const std::function + &CopyFromInput, // EnableIfNotConstIterator + // First, InputIterator Last, + const size_t SizeInBytes, size_t RequiredAlign, + const property_list &Props, + std::unique_ptr Allocator, + bool IsConstPtr); + + buffer_plain(pi_native_handle MemObject, context SyclContext, + std::unique_ptr Allocator, + bool OwnNativeHandle, event AvailableEvent); + + buffer_plain(const std::shared_ptr &impl) : impl(impl) {} + + void set_final_data_internal(); + + void set_final_data_internal( + const std::function &)> + &FinalDataFunc); + + void set_write_back(bool NeedWriteBack); + + void constructorNotification(const detail::code_location &CodeLoc, + void *UserObj, const void *HostObj, + const void *Type, uint32_t Dim, + uint32_t ElemType, size_t Range[3]); + + template bool has_property() const noexcept; + + template propertyT get_property() const; + + std::vector getNativeVector(backend BackendName) const; + + const std::unique_ptr &get_allocator_internal() const; + + void deleteAccProps(const sycl::detail::PropWithDataKind &Kind); + + void addOrReplaceAccessorProperties(const property_list &PropertyList); + + size_t getSize() const; + + std::shared_ptr impl; +}; + } // namespace detail /// Defines a shared array that can be used by kernels in queues. @@ -59,7 +134,7 @@ template >, typename __Enabled = typename detail::enable_if_t<(dimensions > 0) && (dimensions <= 3)>> -class buffer { +class buffer : public detail::buffer_plain { // TODO check is_device_copyable::value after converting sycl::vec into a // trivially copyable class. static_assert(!std::is_same::value, @@ -97,53 +172,55 @@ class buffer { buffer(const range &bufferRange, const property_list &propList = {}, const detail::code_location CodeLoc = detail::code_location::current()) - : Range(bufferRange) { - impl = std::make_shared( - size() * sizeof(T), detail::getNextPowerOfTwo(sizeof(T)), propList, - make_unique_ptr>()); - impl->constructorNotification(CodeLoc, (void *)impl.get(), nullptr, - (const void *)typeid(T).name(), dimensions, - sizeof(T), rangeToArray(Range).data()); + : buffer_plain(bufferRange.size() * sizeof(T), + detail::getNextPowerOfTwo(sizeof(T)), propList, + make_unique_ptr< + detail::SYCLMemObjAllocatorHolder>()), + Range(bufferRange) { + buffer_plain::constructorNotification( + CodeLoc, (void *)impl.get(), nullptr, (const void *)typeid(T).name(), + dimensions, sizeof(T), rangeToArray(Range).data()); } buffer(const range &bufferRange, AllocatorT allocator, const property_list &propList = {}, const detail::code_location CodeLoc = detail::code_location::current()) - : Range(bufferRange) { - impl = std::make_shared( - size() * sizeof(T), detail::getNextPowerOfTwo(sizeof(T)), propList, - make_unique_ptr>( - allocator)); - impl->constructorNotification(CodeLoc, (void *)impl.get(), nullptr, - (const void *)typeid(T).name(), dimensions, - sizeof(T), rangeToArray(Range).data()); + : buffer_plain( + bufferRange.size() * sizeof(T), + detail::getNextPowerOfTwo(sizeof(T)), propList, + make_unique_ptr>( + allocator)), + Range(bufferRange) { + buffer_plain::constructorNotification( + CodeLoc, (void *)impl.get(), nullptr, (const void *)typeid(T).name(), + dimensions, sizeof(T), rangeToArray(Range).data()); } buffer(T *hostData, const range &bufferRange, const property_list &propList = {}, const detail::code_location CodeLoc = detail::code_location::current()) - : Range(bufferRange) { - impl = std::make_shared( - hostData, size() * sizeof(T), detail::getNextPowerOfTwo(sizeof(T)), - propList, - make_unique_ptr>()); - impl->constructorNotification(CodeLoc, (void *)impl.get(), hostData, - (const void *)typeid(T).name(), dimensions, - sizeof(T), rangeToArray(Range).data()); + : buffer_plain(hostData, bufferRange.size() * sizeof(T), + detail::getNextPowerOfTwo(sizeof(T)), propList, + make_unique_ptr< + detail::SYCLMemObjAllocatorHolder>()), + Range(bufferRange) { + buffer_plain::constructorNotification( + CodeLoc, (void *)impl.get(), hostData, (const void *)typeid(T).name(), + dimensions, sizeof(T), rangeToArray(Range).data()); } buffer(T *hostData, const range &bufferRange, AllocatorT allocator, const property_list &propList = {}, const detail::code_location CodeLoc = detail::code_location::current()) - : Range(bufferRange) { - impl = std::make_shared( - hostData, size() * sizeof(T), detail::getNextPowerOfTwo(sizeof(T)), - propList, - make_unique_ptr>( - allocator)); - impl->constructorNotification(CodeLoc, (void *)impl.get(), hostData, - (const void *)typeid(T).name(), dimensions, - sizeof(T), rangeToArray(Range).data()); + : buffer_plain( + hostData, bufferRange.size() * sizeof(T), + detail::getNextPowerOfTwo(sizeof(T)), propList, + make_unique_ptr>( + allocator)), + Range(bufferRange) { + buffer_plain::constructorNotification( + CodeLoc, (void *)impl.get(), hostData, (const void *)typeid(T).name(), + dimensions, sizeof(T), rangeToArray(Range).data()); } template @@ -151,14 +228,14 @@ class buffer { const range &bufferRange, const property_list &propList = {}, const detail::code_location CodeLoc = detail::code_location::current()) - : Range(bufferRange) { - impl = std::make_shared( - hostData, size() * sizeof(T), detail::getNextPowerOfTwo(sizeof(T)), - propList, - make_unique_ptr>()); - impl->constructorNotification(CodeLoc, (void *)impl.get(), hostData, - (const void *)typeid(T).name(), dimensions, - sizeof(T), rangeToArray(Range).data()); + : buffer_plain(hostData, bufferRange.size() * sizeof(T), + detail::getNextPowerOfTwo(sizeof(T)), propList, + make_unique_ptr< + detail::SYCLMemObjAllocatorHolder>()), + Range(bufferRange) { + buffer_plain::constructorNotification( + CodeLoc, (void *)impl.get(), hostData, (const void *)typeid(T).name(), + dimensions, sizeof(T), rangeToArray(Range).data()); } template @@ -166,77 +243,81 @@ class buffer { const range &bufferRange, AllocatorT allocator, const property_list &propList = {}, const detail::code_location CodeLoc = detail::code_location::current()) - : Range(bufferRange) { - impl = std::make_shared( - hostData, size() * sizeof(T), detail::getNextPowerOfTwo(sizeof(T)), - propList, - make_unique_ptr>( - allocator)); - impl->constructorNotification(CodeLoc, (void *)impl.get(), hostData, - (const void *)typeid(T).name(), dimensions, - sizeof(T), rangeToArray(Range).data()); + : buffer_plain( + bufferRange.size() * sizeof(T), + detail::getNextPowerOfTwo(sizeof(T)), propList, + make_unique_ptr>( + allocator)), + Range(bufferRange) { + buffer_plain::constructorNotification( + CodeLoc, (void *)impl.get(), hostData, (const void *)typeid(T).name(), + dimensions, sizeof(T), rangeToArray(Range).data()); } buffer(const std::shared_ptr &hostData, const range &bufferRange, AllocatorT allocator, const property_list &propList = {}, const detail::code_location CodeLoc = detail::code_location::current()) - : Range(bufferRange) { - impl = std::make_shared( - hostData, size() * sizeof(T), detail::getNextPowerOfTwo(sizeof(T)), - propList, - make_unique_ptr>( - allocator)); - impl->constructorNotification(CodeLoc, (void *)impl.get(), - (void *)hostData.get(), - (const void *)typeid(T).name(), dimensions, - sizeof(T), rangeToArray(Range).data()); + : buffer_plain( + hostData, bufferRange.size() * sizeof(T), + detail::getNextPowerOfTwo(sizeof(T)), propList, + make_unique_ptr>( + allocator), + std::is_const::value), + Range(bufferRange) { + buffer_plain::constructorNotification( + CodeLoc, (void *)impl.get(), (void *)hostData.get(), + (const void *)typeid(T).name(), dimensions, sizeof(T), + rangeToArray(Range).data()); } buffer(const std::shared_ptr &hostData, const range &bufferRange, AllocatorT allocator, const property_list &propList = {}, const detail::code_location CodeLoc = detail::code_location::current()) - : Range(bufferRange) { - impl = std::make_shared( - hostData, size() * sizeof(T), detail::getNextPowerOfTwo(sizeof(T)), - propList, - make_unique_ptr>( - allocator)); - impl->constructorNotification(CodeLoc, (void *)impl.get(), - (void *)hostData.get(), - (const void *)typeid(T).name(), dimensions, - sizeof(T), rangeToArray(Range).data()); + : buffer_plain( + hostData, bufferRange.size() * sizeof(T), + detail::getNextPowerOfTwo(sizeof(T)), propList, + make_unique_ptr>( + allocator), + std::is_const::value), + Range(bufferRange) { + buffer_plain::constructorNotification( + CodeLoc, (void *)impl.get(), (void *)hostData.get(), + (const void *)typeid(T).name(), dimensions, sizeof(T), + rangeToArray(Range).data()); } buffer(const std::shared_ptr &hostData, const range &bufferRange, const property_list &propList = {}, const detail::code_location CodeLoc = detail::code_location::current()) - : Range(bufferRange) { - impl = std::make_shared( - hostData, size() * sizeof(T), detail::getNextPowerOfTwo(sizeof(T)), - propList, - make_unique_ptr>()); - impl->constructorNotification(CodeLoc, (void *)impl.get(), - (void *)hostData.get(), - (const void *)typeid(T).name(), dimensions, - sizeof(T), rangeToArray(Range).data()); + : buffer_plain( + hostData, bufferRange.size() * sizeof(T), + detail::getNextPowerOfTwo(sizeof(T)), propList, + make_unique_ptr>(), + std::is_const::value), + Range(bufferRange) { + buffer_plain::constructorNotification( + CodeLoc, (void *)impl.get(), (void *)hostData.get(), + (const void *)typeid(T).name(), dimensions, sizeof(T), + rangeToArray(Range).data()); } buffer(const std::shared_ptr &hostData, const range &bufferRange, const property_list &propList = {}, const detail::code_location CodeLoc = detail::code_location::current()) - : Range(bufferRange) { - impl = std::make_shared( - hostData, size() * sizeof(T), detail::getNextPowerOfTwo(sizeof(T)), - propList, - make_unique_ptr>()); - impl->constructorNotification(CodeLoc, (void *)impl.get(), - (void *)hostData.get(), - (const void *)typeid(T).name(), dimensions, - sizeof(T), rangeToArray(Range).data()); + : buffer_plain( + hostData, bufferRange.size() * sizeof(T), + detail::getNextPowerOfTwo(sizeof(T)), propList, + make_unique_ptr>(), + std::is_const::value), + Range(bufferRange) { + buffer_plain::constructorNotification( + CodeLoc, (void *)impl.get(), (void *)hostData.get(), + (const void *)typeid(T).name(), dimensions, sizeof(T), + rangeToArray(Range).data()); } template (std::distance(first, last))) { - impl = std::make_shared( - first, last, size() * sizeof(T), detail::getNextPowerOfTwo(sizeof(T)), - propList, - make_unique_ptr>( - allocator)); + : buffer_plain( + // The functor which will be used to initialize the data + [first, last](void *ToPtr) { + // We need to cast MUserPtr to pointer to the iteration type to + // get correct offset in std::copy when it will increment + // destination pointer. + using IteratorValueType = + detail::iterator_value_type_t; + using IteratorNonConstValueType = + detail::remove_const_t; + using IteratorPointerToNonConstValueType = + detail::add_pointer_t; + std::copy(first, last, + static_cast(ToPtr)); + }, + std::distance(first, last) * sizeof(T), + detail::getNextPowerOfTwo(sizeof(T)), propList, + make_unique_ptr>( + allocator), + detail::iterator_to_const_type_t::value), + Range(range<1>(std::distance(first, last))) { size_t r[3] = {Range[0], 0, 0}; - impl->constructorNotification(CodeLoc, (void *)impl.get(), &first, - (const void *)typeid(T).name(), dimensions, - sizeof(T), r); + buffer_plain::constructorNotification(CodeLoc, (void *)impl.get(), &first, + (const void *)typeid(T).name(), + dimensions, sizeof(T), r); } template (std::distance(first, last))) { - impl = std::make_shared( - first, last, size() * sizeof(T), detail::getNextPowerOfTwo(sizeof(T)), - propList, - make_unique_ptr>()); + : buffer_plain( + // The functor which will be used to initialize the data + [first, last](void *ToPtr) { + // We need to cast MUserPtr to pointer to the iteration type to + // get correct offset in std::copy when it will increment + // destination pointer. + using IteratorValueType = + detail::iterator_value_type_t; + using IteratorNonConstValueType = + detail::remove_const_t; + using IteratorPointerToNonConstValueType = + detail::add_pointer_t; + std::copy(first, last, + static_cast(ToPtr)); + }, + std::distance(first, last) * sizeof(T), + detail::getNextPowerOfTwo(sizeof(T)), propList, + make_unique_ptr>(), + detail::iterator_to_const_type_t::value), + Range(range<1>(std::distance(first, last))) { size_t r[3] = {Range[0], 0, 0}; - impl->constructorNotification(CodeLoc, (void *)impl.get(), &first, - (const void *)typeid(T).name(), dimensions, - sizeof(T), r); + buffer_plain::constructorNotification(CodeLoc, (void *)impl.get(), &first, + (const void *)typeid(T).name(), + dimensions, sizeof(T), r); } // This constructor is a prototype for a future SYCL specification @@ -281,16 +392,16 @@ class buffer { buffer(Container &container, AllocatorT allocator, const property_list &propList = {}, const detail::code_location CodeLoc = detail::code_location::current()) - : Range(range<1>(container.size())) { - impl = std::make_shared( - container.data(), size() * sizeof(T), - detail::getNextPowerOfTwo(sizeof(T)), propList, - make_unique_ptr>( - allocator)); + : buffer_plain( + container.data(), container.size() * sizeof(T), + detail::getNextPowerOfTwo(sizeof(T)), propList, + make_unique_ptr>( + allocator)), + Range(range<1>(container.size())) { size_t r[3] = {Range[0], 0, 0}; - impl->constructorNotification(CodeLoc, (void *)impl.get(), container.data(), - (const void *)typeid(T).name(), dimensions, - sizeof(T), r); + buffer_plain::constructorNotification( + CodeLoc, (void *)impl.get(), container.data(), + (const void *)typeid(T).name(), dimensions, sizeof(T), r); } // This constructor is a prototype for a future SYCL specification @@ -304,12 +415,12 @@ class buffer { buffer(buffer &b, const id &baseIndex, const range &subRange, const detail::code_location CodeLoc = detail::code_location::current()) - : impl(b.impl), Range(subRange), + : buffer_plain(b.impl), Range(subRange), OffsetInBytes(getOffsetInBytes(baseIndex, b.Range)), IsSubBuffer(true) { - impl->constructorNotification(CodeLoc, (void *)impl.get(), impl.get(), - (const void *)typeid(T).name(), dimensions, - sizeof(T), rangeToArray(Range).data()); + buffer_plain::constructorNotification( + CodeLoc, (void *)impl.get(), impl.get(), (const void *)typeid(T).name(), + dimensions, sizeof(T), rangeToArray(Range).data()); if (b.is_sub_buffer()) throw sycl::invalid_object_error( @@ -324,40 +435,22 @@ class buffer { PI_ERROR_INVALID_VALUE); } -#ifdef __SYCL_INTERNAL_API - template > - buffer(cl_mem MemObject, const context &SyclContext, - event AvailableEvent = {}, - const detail::code_location CodeLoc = detail::code_location::current()) - : Range{0} { - - impl = std::make_shared( - detail::pi::cast(MemObject), SyclContext, - make_unique_ptr>(), - /* OwnNativeHandle */ true, AvailableEvent); - Range[0] = impl->getSize() / sizeof(T); - impl->constructorNotification(CodeLoc, (void *)impl.get(), &MemObject, - (const void *)typeid(T).name(), dimensions, - sizeof(T), rangeToArray(Range).data()); - } -#endif - buffer(const buffer &rhs, const detail::code_location CodeLoc = detail::code_location::current()) - : impl(rhs.impl), Range(rhs.Range), OffsetInBytes(rhs.OffsetInBytes), - IsSubBuffer(rhs.IsSubBuffer) { - impl->constructorNotification(CodeLoc, (void *)impl.get(), impl.get(), - (const void *)typeid(T).name(), dimensions, - sizeof(T), rangeToArray(Range).data()); + : buffer_plain(rhs.impl), Range(rhs.Range), + OffsetInBytes(rhs.OffsetInBytes), IsSubBuffer(rhs.IsSubBuffer) { + buffer_plain::constructorNotification( + CodeLoc, (void *)impl.get(), impl.get(), (const void *)typeid(T).name(), + dimensions, sizeof(T), rangeToArray(Range).data()); } buffer(buffer &&rhs, const detail::code_location CodeLoc = detail::code_location::current()) - : impl(std::move(rhs.impl)), Range(rhs.Range), + : buffer_plain(std::move(rhs.impl)), Range(rhs.Range), OffsetInBytes(rhs.OffsetInBytes), IsSubBuffer(rhs.IsSubBuffer) { - impl->constructorNotification(CodeLoc, (void *)impl.get(), impl.get(), - (const void *)typeid(T).name(), dimensions, - sizeof(T), rangeToArray(Range).data()); + buffer_plain::constructorNotification( + CodeLoc, (void *)impl.get(), impl.get(), (const void *)typeid(T).name(), + dimensions, sizeof(T), rangeToArray(Range).data()); } buffer &operator=(const buffer &rhs) = default; @@ -386,7 +479,8 @@ class buffer { size_t byte_size() const noexcept { return size() * sizeof(T); } AllocatorT get_allocator() const { - return impl->template get_allocator(); + return buffer_plain::get_allocator_internal() + ->template getAllocator(); } template @@ -468,10 +562,65 @@ class buffer { template void set_final_data(Destination finalData = nullptr) { - impl->set_final_data(finalData); + this->set_final_data_internal(finalData); + } + + void set_final_data_internal(std::nullptr_t) { + buffer_plain::set_final_data_internal(); } - void set_write_back(bool flag = true) { impl->set_write_back(flag); } + template