From e5ea144e480c7b28162a1477b3d462cfc221ff61 Mon Sep 17 00:00:00 2001 From: Romanov Vlad <17316488+romanovvlad@users.noreply.github.com> Date: Wed, 22 Jul 2020 09:41:06 +0300 Subject: [PATCH] [SYCL] Adding support for buffer::use_pinned_host_memory property (#2080) --- sycl/CMakeLists.txt | 2 +- .../UsePinnedMemoryPropery.adoc | 22 +++++++++ sycl/include/CL/sycl/detail/buffer_impl.hpp | 43 +++++++++++++++++- .../include/CL/sycl/detail/memory_manager.hpp | 15 +++++-- sycl/include/CL/sycl/property_list.hpp | 45 +++++++++++++++---- sycl/source/detail/buffer_impl.cpp | 2 +- sycl/source/detail/image_impl.cpp | 2 +- sycl/source/detail/memory_manager.cpp | 39 ++++++++++------ sycl/test/abi/sycl_symbols_linux.dump | 14 +++--- .../basic_tests/use_pinned_host_memory.cpp | 45 +++++++++++++++++++ 10 files changed, 192 insertions(+), 37 deletions(-) create mode 100644 sycl/doc/extensions/UsePinnedMemoryProperty/UsePinnedMemoryPropery.adoc create mode 100644 sycl/test/basic_tests/use_pinned_host_memory.cpp diff --git a/sycl/CMakeLists.txt b/sycl/CMakeLists.txt index 231917e47a9e3..1d69044e48078 100644 --- a/sycl/CMakeLists.txt +++ b/sycl/CMakeLists.txt @@ -14,7 +14,7 @@ include(AddSYCLExecutable) set(SYCL_MAJOR_VERSION 2) set(SYCL_MINOR_VERSION 1) set(SYCL_PATCH_VERSION 0) -set(SYCL_DEV_ABI_VERSION 0) +set(SYCL_DEV_ABI_VERSION 1) if (SYCL_ADD_DEV_VERSION_POSTFIX) set(SYCL_VERSION_POSTFIX "-${SYCL_DEV_ABI_VERSION}") endif() diff --git a/sycl/doc/extensions/UsePinnedMemoryProperty/UsePinnedMemoryPropery.adoc b/sycl/doc/extensions/UsePinnedMemoryProperty/UsePinnedMemoryPropery.adoc new file mode 100644 index 0000000000000..8c97dbdd88759 --- /dev/null +++ b/sycl/doc/extensions/UsePinnedMemoryProperty/UsePinnedMemoryPropery.adoc @@ -0,0 +1,22 @@ += SYCL Proposals: Use Pinned Host Memory Property +Vlad Romanov +v0.1 +:source-highlighter: pygments +:icons: font +== Introduction +This document describes an extension that introduces a +sycl::ext::oneapi::property::buffer::use_pinned_host_memory+ property for the `sycl::buffer`. Some SYCL backends can accelerate copies between host and device by allocating pinned memory. The property can be passed to the `sycl::buffer` constructor in order to enable such an allocation. + +== Name Strings + ++SYCL_INTEL_use_pinned_host_memory+ + +== Use Pinned Host Memory Property + +.Proposed Buffer Property +[cols="^50,50",options="header"] +|=== + +|Property |Description +|`syc::ext::oneapi::property::buffer::use_pinned_host_memory` +| The `use_pinned_host_memory` property adds the requirement that the SYCL runtime must allocate host pinned memory for the `sycl::buffer`. The property cannot be used with the `sycl::buffer` constructors that take hostData parameter, an invalid_object_error SYCL exception must be thrown in this case. +|=== diff --git a/sycl/include/CL/sycl/detail/buffer_impl.hpp b/sycl/include/CL/sycl/detail/buffer_impl.hpp index d66692a5ea688..0ff488cf97363 100644 --- a/sycl/include/CL/sycl/detail/buffer_impl.hpp +++ b/sycl/include/CL/sycl/detail/buffer_impl.hpp @@ -45,12 +45,25 @@ class __SYCL_EXPORT buffer_impl final : public SYCLMemObjT { public: buffer_impl(size_t SizeInBytes, size_t, const property_list &Props, unique_ptr_class Allocator) - : BaseT(SizeInBytes, Props, std::move(Allocator)) {} + : BaseT(SizeInBytes, Props, std::move(Allocator)) { + + if (Props.has_property()) + throw sycl::invalid_object_error( + "The use_host_ptr property requires host pointer to be provided", + PI_INVALID_OPERATION); + } buffer_impl(void *HostData, size_t SizeInBytes, size_t RequiredAlign, const property_list &Props, unique_ptr_class Allocator) : BaseT(SizeInBytes, Props, std::move(Allocator)) { + + if (Props.has_property< + sycl::ext::oneapi::property::buffer::use_pinned_host_memory>()) + throw sycl::invalid_object_error( + "The use_pinned_host_memory cannot be used with host pointer", + PI_INVALID_OPERATION); + BaseT::handleHostData(HostData, RequiredAlign); } @@ -58,6 +71,13 @@ class __SYCL_EXPORT buffer_impl final : public SYCLMemObjT { const property_list &Props, unique_ptr_class Allocator) : BaseT(SizeInBytes, Props, std::move(Allocator)) { + + if (Props.has_property< + sycl::ext::oneapi::property::buffer::use_pinned_host_memory>()) + throw sycl::invalid_object_error( + "The use_pinned_host_memory cannot be used with host pointer", + PI_INVALID_OPERATION); + BaseT::handleHostData(HostData, RequiredAlign); } @@ -66,6 +86,13 @@ class __SYCL_EXPORT buffer_impl final : public SYCLMemObjT { size_t RequiredAlign, const property_list &Props, unique_ptr_class Allocator) : BaseT(SizeInBytes, Props, std::move(Allocator)) { + + if (Props.has_property< + sycl::ext::oneapi::property::buffer::use_pinned_host_memory>()) + throw sycl::invalid_object_error( + "The use_pinned_host_memory cannot be used with host pointer", + PI_INVALID_OPERATION); + BaseT::handleHostData(HostData, RequiredAlign); } @@ -79,6 +106,13 @@ class __SYCL_EXPORT buffer_impl final : public SYCLMemObjT { const property_list &Props, unique_ptr_class Allocator) : BaseT(SizeInBytes, Props, std::move(Allocator)) { + + if (Props.has_property()) + throw sycl::invalid_object_error( + "Buffer constructor from a pair of iterator values cannot have the " + "use_host_ptr property.", + PI_INVALID_OPERATION); + BaseT::handleHostData(First, Last, RequiredAlign); } @@ -92,6 +126,13 @@ class __SYCL_EXPORT buffer_impl final : public SYCLMemObjT { const property_list &Props, unique_ptr_class Allocator) : BaseT(SizeInBytes, Props, std::move(Allocator)) { + + if (Props.has_property()) + throw sycl::invalid_object_error( + "Buffer constructor from a pair of iterator values cannot have the " + "use_host_ptr property.", + PI_INVALID_OPERATION); + BaseT::handleHostData(First, Last, RequiredAlign); } diff --git a/sycl/include/CL/sycl/detail/memory_manager.hpp b/sycl/include/CL/sycl/detail/memory_manager.hpp index 711d9a0ac0347..8f17f0f7d95f1 100644 --- a/sycl/include/CL/sycl/detail/memory_manager.hpp +++ b/sycl/include/CL/sycl/detail/memory_manager.hpp @@ -12,6 +12,7 @@ #include #include #include +#include #include #include @@ -71,6 +72,7 @@ class __SYCL_EXPORT MemoryManager { bool HostPtrReadOnly, size_t Size, const EventImplPtr &InteropEvent, const ContextImplPtr &InteropContext, + const sycl::property_list &PropsList, RT::PiEvent &OutEventToWait); // Allocates images in specified context taking into account situations such @@ -80,7 +82,8 @@ class __SYCL_EXPORT MemoryManager { ContextImplPtr TargetContext, SYCLMemObjI *MemObj, void *UserPtr, bool HostPtrReadOnly, size_t Size, const RT::PiMemImageDesc &Desc, const RT::PiMemImageFormat &Format, const EventImplPtr &InteropEvent, - const ContextImplPtr &InteropContext, RT::PiEvent &OutEventToWait); + const ContextImplPtr &InteropContext, + const sycl::property_list &PropsList, RT::PiEvent &OutEventToWait); // Releases memory object(buffer or image). TargetContext should be device // one(not host). @@ -88,21 +91,25 @@ class __SYCL_EXPORT MemoryManager { void *MemAllocation, void *UserPtr); static void *allocateHostMemory(SYCLMemObjI *MemObj, void *UserPtr, - bool HostPtrReadOnly, size_t Size); + bool HostPtrReadOnly, size_t Size, + const sycl::property_list &PropsList); static void *allocateInteropMemObject(ContextImplPtr TargetContext, void *UserPtr, const EventImplPtr &InteropEvent, const ContextImplPtr &InteropContext, + const sycl::property_list &PropsList, RT::PiEvent &OutEventToWait); static void *allocateImageObject(ContextImplPtr TargetContext, void *UserPtr, bool HostPtrReadOnly, const RT::PiMemImageDesc &Desc, - const RT::PiMemImageFormat &Format); + const RT::PiMemImageFormat &Format, + const sycl::property_list &PropsList); static void *allocateBufferObject(ContextImplPtr TargetContext, void *UserPtr, - bool HostPtrReadOnly, const size_t Size); + bool HostPtrReadOnly, const size_t Size, + const sycl::property_list &PropsList); // Copies memory between: host and device, host and host, // device and device if memory objects bound to the one context. diff --git a/sycl/include/CL/sycl/property_list.hpp b/sycl/include/CL/sycl/property_list.hpp index 90aea2d60164a..b727bf05671c2 100644 --- a/sycl/include/CL/sycl/property_list.hpp +++ b/sycl/include/CL/sycl/property_list.hpp @@ -47,6 +47,11 @@ class noinit; namespace detail { +// Will be aliased in the sycl::ext::oneapi::property namespace +namespace buffer_ { +class use_pinned_host_memory; +} + // List of all properties' IDs. enum PropKind { // Buffer properties @@ -66,6 +71,8 @@ enum PropKind { // Accessor NoInit, + BufferUsePinnedHostMemory, + PropKindSize }; @@ -148,6 +155,8 @@ RegisterProp(PropKind::ImageContextBound, image::context_bound); RegisterProp(PropKind::BufferUseHostPtr, buffer::use_host_ptr); RegisterProp(PropKind::BufferUseMutex, buffer::use_mutex); RegisterProp(PropKind::BufferContextBound, buffer::context_bound); +RegisterProp(PropKind::BufferUsePinnedHostMemory, + buffer_::use_pinned_host_memory); // Queue RegisterProp(PropKind::QueueEnableProfiling, queue::enable_profiling); @@ -212,8 +221,16 @@ class context_bound public: context_bound(cl::sycl::context Context) : ContextBoundBase(Context) {} }; + } // namespace buffer +namespace detail { +namespace buffer_ { +class use_pinned_host_memory + : public detail::Prop {}; +} // namespace buffer_ +} // namespace detail + namespace queue { class enable_profiling : public detail::Prop {}; @@ -225,6 +242,17 @@ class noinit : public detail::Prop {}; } // namespace property +namespace ext { +namespace oneapi { +namespace property { +namespace buffer { +using use_pinned_host_memory = + sycl::property::detail::buffer_::use_pinned_host_memory; +} // namespace buffer +} // namespace property +} // namespace oneapi +} // namespace ext + #if __cplusplus > 201402L inline constexpr property::noinit noinit; @@ -280,17 +308,18 @@ class property_list { } template propertyT get_property() const { - static_assert((int)(propertyT::getKind()) <= - property::detail::PropKind::PropKindSize, - "Invalid option passed."); - const auto &PropHolder = std::get<(int)(propertyT::getKind())>(m_PropsList); - if (PropHolder.isInitialized()) { - return PropHolder.getProp(); + if (!has_property()) { + throw sycl::invalid_object_error(); } - throw invalid_object_error(); + const auto &PropHolder = + std::get(propertyT::getKind())>(m_PropsList); + return PropHolder.getProp(); } template bool has_property() const { + if (static_cast(propertyT::getKind()) > + property::detail::PropKind::PropKindSize) + return false; return std::get<(int)(propertyT::getKind())>(m_PropsList).isInitialized(); } @@ -299,7 +328,7 @@ class property_list { template void ctorHelper(PropT &Prop, propertyTN... props) { - std::get<(int)(PropT::getKind())>(m_PropsList).setProp(Prop); + std::get(PropT::getKind())>(m_PropsList).setProp(Prop); ctorHelper(props...); } diff --git a/sycl/source/detail/buffer_impl.cpp b/sycl/source/detail/buffer_impl.cpp index a9aa0e4194f9e..26e189f1abffd 100644 --- a/sycl/source/detail/buffer_impl.cpp +++ b/sycl/source/detail/buffer_impl.cpp @@ -29,7 +29,7 @@ void *buffer_impl::allocateMem(ContextImplPtr Context, bool InitFromUserData, return MemoryManager::allocateMemBuffer( std::move(Context), this, UserPtr, BaseT::MHostPtrReadOnly, - BaseT::getSize(), BaseT::MInteropEvent, BaseT::MInteropContext, + BaseT::getSize(), BaseT::MInteropEvent, BaseT::MInteropContext, MProps, OutEventToWait); } } // namespace detail diff --git a/sycl/source/detail/image_impl.cpp b/sycl/source/detail/image_impl.cpp index 9d7ccf51e2f79..747f3b193fd85 100644 --- a/sycl/source/detail/image_impl.cpp +++ b/sycl/source/detail/image_impl.cpp @@ -325,7 +325,7 @@ void *image_impl::allocateMem(ContextImplPtr Context, return MemoryManager::allocateMemImage( std::move(Context), this, UserPtr, BaseT::MHostPtrReadOnly, BaseT::getSize(), Desc, Format, BaseT::MInteropEvent, - BaseT::MInteropContext, OutEventToWait); + BaseT::MInteropContext, MProps, OutEventToWait); } template diff --git a/sycl/source/detail/memory_manager.cpp b/sycl/source/detail/memory_manager.cpp index fc0d79b4c05cf..f80073fbddace 100644 --- a/sycl/source/detail/memory_manager.cpp +++ b/sycl/source/detail/memory_manager.cpp @@ -106,7 +106,8 @@ void *MemoryManager::wrapIntoImageBuffer(ContextImplPtr TargetContext, } void *MemoryManager::allocateHostMemory(SYCLMemObjI *MemObj, void *UserPtr, - bool HostPtrReadOnly, size_t Size) { + bool HostPtrReadOnly, size_t Size, + const sycl::property_list &) { // Can return user pointer directly if it points to writable memory. if (UserPtr && HostPtrReadOnly == false) return UserPtr; @@ -123,7 +124,7 @@ void *MemoryManager::allocateHostMemory(SYCLMemObjI *MemObj, void *UserPtr, void *MemoryManager::allocateInteropMemObject( ContextImplPtr TargetContext, void *UserPtr, const EventImplPtr &InteropEvent, const ContextImplPtr &InteropContext, - RT::PiEvent &OutEventToWait) { + const sycl::property_list &, RT::PiEvent &OutEventToWait) { // If memory object is created with interop c'tor. // Return cl_mem as is if contexts match. if (TargetContext == InteropContext) { @@ -144,7 +145,8 @@ void *MemoryManager::allocateInteropMemObject( void *MemoryManager::allocateImageObject(ContextImplPtr TargetContext, void *UserPtr, bool HostPtrReadOnly, const RT::PiMemImageDesc &Desc, - const RT::PiMemImageFormat &Format) { + const RT::PiMemImageFormat &Format, + const sycl::property_list &) { // Create read_write mem object by default to handle arbitrary uses. RT::PiMemFlags CreationFlags = PI_MEM_FLAGS_ACCESS_RW; if (UserPtr) @@ -159,16 +161,20 @@ void *MemoryManager::allocateImageObject(ContextImplPtr TargetContext, return NewMem; } -void *MemoryManager::allocateBufferObject(ContextImplPtr TargetContext, - void *UserPtr, bool HostPtrReadOnly, - const size_t Size) { +void * +MemoryManager::allocateBufferObject(ContextImplPtr TargetContext, void *UserPtr, + bool HostPtrReadOnly, const size_t Size, + const sycl::property_list &PropsList) { // Create read_write mem object by default to handle arbitrary uses. RT::PiMemFlags CreationFlags = PI_MEM_FLAGS_ACCESS_RW; if (UserPtr) CreationFlags |= HostPtrReadOnly ? PI_MEM_FLAGS_HOST_PTR_COPY : PI_MEM_FLAGS_HOST_PTR_USE; + else if (PropsList.has_property< + sycl::ext::oneapi::property::buffer::use_pinned_host_memory>()) + CreationFlags |= PI_MEM_FLAGS_HOST_PTR_ALLOC; - RT::PiMem NewMem; + RT::PiMem NewMem = nullptr; const detail::plugin &Plugin = TargetContext->getPlugin(); Plugin.call( TargetContext->getHandleRef(), CreationFlags, Size, UserPtr, &NewMem); @@ -180,27 +186,32 @@ void *MemoryManager::allocateMemBuffer(ContextImplPtr TargetContext, bool HostPtrReadOnly, size_t Size, const EventImplPtr &InteropEvent, const ContextImplPtr &InteropContext, + const sycl::property_list &PropsList, RT::PiEvent &OutEventToWait) { if (TargetContext->is_host()) - return allocateHostMemory(MemObj, UserPtr, HostPtrReadOnly, Size); + return allocateHostMemory(MemObj, UserPtr, HostPtrReadOnly, Size, + PropsList); if (UserPtr && InteropContext) return allocateInteropMemObject(TargetContext, UserPtr, InteropEvent, - InteropContext, OutEventToWait); - return allocateBufferObject(TargetContext, UserPtr, HostPtrReadOnly, Size); + InteropContext, PropsList, OutEventToWait); + return allocateBufferObject(TargetContext, UserPtr, HostPtrReadOnly, Size, + PropsList); } void *MemoryManager::allocateMemImage( ContextImplPtr TargetContext, SYCLMemObjI *MemObj, void *UserPtr, bool HostPtrReadOnly, size_t Size, const RT::PiMemImageDesc &Desc, const RT::PiMemImageFormat &Format, const EventImplPtr &InteropEvent, - const ContextImplPtr &InteropContext, RT::PiEvent &OutEventToWait) { + const ContextImplPtr &InteropContext, const sycl::property_list &PropsList, + RT::PiEvent &OutEventToWait) { if (TargetContext->is_host()) - return allocateHostMemory(MemObj, UserPtr, HostPtrReadOnly, Size); + return allocateHostMemory(MemObj, UserPtr, HostPtrReadOnly, Size, + PropsList); if (UserPtr && InteropContext) return allocateInteropMemObject(TargetContext, UserPtr, InteropEvent, - InteropContext, OutEventToWait); + InteropContext, PropsList, OutEventToWait); return allocateImageObject(TargetContext, UserPtr, HostPtrReadOnly, Desc, - Format); + Format, PropsList); } void *MemoryManager::allocateMemSubBuffer(ContextImplPtr TargetContext, diff --git a/sycl/test/abi/sycl_symbols_linux.dump b/sycl/test/abi/sycl_symbols_linux.dump index 956aebea9d0c2..9ff2e1195cac9 100644 --- a/sycl/test/abi/sycl_symbols_linux.dump +++ b/sycl/test/abi/sycl_symbols_linux.dump @@ -3728,15 +3728,15 @@ _ZN2cl4sycl6detail12sampler_implD2Ev _ZN2cl4sycl6detail12split_stringERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEc _ZN2cl4sycl6detail13MemoryManager12prefetch_usmEPvSt10shared_ptrINS1_10queue_implEEmSt6vectorIP9_pi_eventSaIS9_EERS9_ _ZN2cl4sycl6detail13MemoryManager13releaseMemObjESt10shared_ptrINS1_12context_implEEPNS1_11SYCLMemObjIEPvS8_ -_ZN2cl4sycl6detail13MemoryManager16allocateMemImageESt10shared_ptrINS1_12context_implEEPNS1_11SYCLMemObjIEPvbmRK14_pi_image_descRK16_pi_image_formatRKS3_INS1_10event_implEERKS5_RP9_pi_event -_ZN2cl4sycl6detail13MemoryManager17allocateMemBufferESt10shared_ptrINS1_12context_implEEPNS1_11SYCLMemObjIEPvbmRKS3_INS1_10event_implEERKS5_RP9_pi_event -_ZN2cl4sycl6detail13MemoryManager18allocateHostMemoryEPNS1_11SYCLMemObjIEPvbm -_ZN2cl4sycl6detail13MemoryManager18releaseImageBufferESt10shared_ptrINS1_12context_implEEPv -_ZN2cl4sycl6detail13MemoryManager19allocateImageObjectESt10shared_ptrINS1_12context_implEEPvbRK14_pi_image_descRK16_pi_image_format +_ZN2cl4sycl6detail13MemoryManager19allocateImageObjectESt10shared_ptrINS1_12context_implEEPvbRK14_pi_image_descRK16_pi_image_formatRKNS0_13property_listE +_ZN2cl4sycl6detail13MemoryManager16allocateMemImageESt10shared_ptrINS1_12context_implEEPNS1_11SYCLMemObjIEPvbmRK14_pi_image_descRK16_pi_image_formatRKS3_INS1_10event_implEERKS5_RKNS0_13property_listERP9_pi_event +_ZN2cl4sycl6detail13MemoryManager24allocateInteropMemObjectESt10shared_ptrINS1_12context_implEEPvRKS3_INS1_10event_implEERKS5_RKNS0_13property_listERP9_pi_event +_ZN2cl4sycl6detail13MemoryManager20allocateBufferObjectESt10shared_ptrINS1_12context_implEEPvbmRKNS0_13property_listE +_ZN2cl4sycl6detail13MemoryManager18allocateHostMemoryEPNS1_11SYCLMemObjIEPvbmRKNS0_13property_listE _ZN2cl4sycl6detail13MemoryManager19wrapIntoImageBufferESt10shared_ptrINS1_12context_implEEPvPNS1_11SYCLMemObjIE -_ZN2cl4sycl6detail13MemoryManager20allocateBufferObjectESt10shared_ptrINS1_12context_implEEPvbm +_ZN2cl4sycl6detail13MemoryManager18releaseImageBufferESt10shared_ptrINS1_12context_implEEPv +_ZN2cl4sycl6detail13MemoryManager17allocateMemBufferESt10shared_ptrINS1_12context_implEEPNS1_11SYCLMemObjIEPvbmRKS3_INS1_10event_implEERKS5_RKNS0_13property_listERP9_pi_event _ZN2cl4sycl6detail13MemoryManager20allocateMemSubBufferESt10shared_ptrINS1_12context_implEEPvmmNS0_5rangeILi3EEESt6vectorIS3_INS1_10event_implEESaISB_EERP9_pi_event -_ZN2cl4sycl6detail13MemoryManager24allocateInteropMemObjectESt10shared_ptrINS1_12context_implEEPvRKS3_INS1_10event_implEERKS5_RP9_pi_event _ZN2cl4sycl6detail13MemoryManager3mapEPNS1_11SYCLMemObjIEPvSt10shared_ptrINS1_10queue_implEENS0_6access4modeEjNS0_5rangeILi3EEESC_NS0_2idILi3EEEjSt6vectorIP9_pi_eventSaISH_EERSH_ _ZN2cl4sycl6detail13MemoryManager4copyEPNS1_11SYCLMemObjIEPvSt10shared_ptrINS1_10queue_implEEjNS0_5rangeILi3EEESA_NS0_2idILi3EEEjS5_S8_jSA_SA_SC_jSt6vectorIP9_pi_eventSaISF_EERSF_ _ZN2cl4sycl6detail13MemoryManager4fillEPNS1_11SYCLMemObjIEPvSt10shared_ptrINS1_10queue_implEEmPKcjNS0_5rangeILi3EEESC_NS0_2idILi3EEEjSt6vectorIP9_pi_eventSaISH_EERSH_ diff --git a/sycl/test/basic_tests/use_pinned_host_memory.cpp b/sycl/test/basic_tests/use_pinned_host_memory.cpp new file mode 100644 index 0000000000000..a596093313cdf --- /dev/null +++ b/sycl/test/basic_tests/use_pinned_host_memory.cpp @@ -0,0 +1,45 @@ +// RUN: %clangxx -fsycl -fsycl-targets=%sycl_triple %s -o %t.out +// RUN: env SYCL_PI_TRACE=2 %CPU_RUN_PLACEHOLDER %t.out 2>&1 %CPU_CHECK_PLACEHOLDER + +#include + +#include + +int main() { + const sycl::range<1> N{1}; + sycl::buffer Buf( + N, {sycl::ext::oneapi::property::buffer::use_pinned_host_memory()}); + if (!Buf.has_property< + sycl::ext::oneapi::property::buffer::use_pinned_host_memory>()) { + std::cerr << "Buffer should have the use_pinned_host_memory property" + << std::endl; + return 1; + } + + sycl::queue Q; + Q.submit([&](sycl::handler &CGH) { + auto Acc = Buf.get_access(CGH); + CGH.single_task([=]() {}); + }); + + try { + int Data = 0; + sycl::buffer Buf( + &Data, N, + {sycl::ext::oneapi::property::buffer::use_pinned_host_memory()}); + // Expected that exception is thrown + return 1; + } catch (sycl::invalid_object_error &E) { + if (std::string(E.what()).find( + "The use_pinned_host_memory cannot be used with host pointer") == + std::string::npos) { + return 1; + } + + return 0; + } +} + +// CHECK:---> piMemBufferCreate +// CHECK-NEXT: {{.*}} : {{.*}} +// CHECK-NEXT: {{.*}} : 17