diff --git a/sycl/include/sycl/detail/property_helper.hpp b/sycl/include/sycl/detail/property_helper.hpp index 356a68637dc1b..2896de2ec66a6 100644 --- a/sycl/include/sycl/detail/property_helper.hpp +++ b/sycl/include/sycl/detail/property_helper.hpp @@ -90,6 +90,7 @@ class PropertyWithDataBase { PropertyWithDataBase(int ID) : MID(ID) {} bool isSame(int ID) const { return ID == MID; } virtual ~PropertyWithDataBase() = default; + int getKind() const { return MID; } private: int MID = -1; @@ -101,7 +102,7 @@ class PropertyWithDataBase { template class PropertyWithData : public PropertyWithDataBase { public: PropertyWithData() : PropertyWithDataBase(ID) {} - static int getKind() { return ID; } + static constexpr int getKind() { return ID; } }; } // namespace detail diff --git a/sycl/include/sycl/detail/property_list_base.hpp b/sycl/include/sycl/detail/property_list_base.hpp index 9b1447492d902..6d4ea3f08b9f9 100644 --- a/sycl/include/sycl/detail/property_list_base.hpp +++ b/sycl/include/sycl/detail/property_list_base.hpp @@ -126,6 +126,25 @@ class PropertyListBase { } } + void checkPropsAndThrow(std::function FunctionForDataless, + std::function FunctionForData) const { + static const auto ErrorCode = sycl::make_error_code(errc::invalid); + static const auto ErrorMessage = "The property list contains property " + "unsupported for the current object"; + + for (int PropertyKind = 0; + PropertyKind < static_cast(MDataLessProps.size()); + PropertyKind++) { + if (MDataLessProps[PropertyKind] && !FunctionForDataless(PropertyKind)) + throw sycl::exception(ErrorCode, ErrorMessage); + } + + for (const auto &PropertyItem : MPropsWithData) { + if (!FunctionForData(PropertyItem->getKind())) + throw sycl::exception(ErrorCode, ErrorMessage); + } + } + // Stores enabled/disabled for simple properties std::bitset MDataLessProps; // Stores shared_ptrs to complex properties diff --git a/sycl/include/sycl/properties/accessor_properties.hpp b/sycl/include/sycl/properties/accessor_properties.hpp index 7fa61e67850e3..fafd6367f0cfd 100644 --- a/sycl/include/sycl/properties/accessor_properties.hpp +++ b/sycl/include/sycl/properties/accessor_properties.hpp @@ -20,19 +20,17 @@ namespace sycl { inline namespace _V1 { -namespace property { - -class no_init : public detail::DataLessProperty {}; - -class __SYCL2020_DEPRECATED("spelling is now: no_init") noinit - : public detail::DataLessProperty {}; - -} // namespace property - -inline constexpr property::no_init no_init; -__SYCL2020_DEPRECATED("spelling is now: no_init") -inline constexpr property::noinit noinit; +#define __SYCL_DATA_LESS_PROP_DEPRECATED_ALIAS(NS_QUALIFIER, PROP_NAME, \ + ENUM_VAL, WARNING) \ + namespace NS_QUALIFIER { \ + class WARNING PROP_NAME \ + : public sycl::detail::DataLessProperty {}; \ + } \ + WARNING inline constexpr NS_QUALIFIER::PROP_NAME PROP_NAME; +#define __SYCL_DATA_LESS_PROP(NS_QUALIFIER, PROP_NAME, ENUM_VAL) \ + __SYCL_DATA_LESS_PROP_DEPRECATED_ALIAS(NS_QUALIFIER, PROP_NAME, ENUM_VAL, ) +#include namespace ext::intel { namespace property { diff --git a/sycl/include/sycl/properties/buffer_properties.def b/sycl/include/sycl/properties/buffer_properties.def new file mode 100644 index 0000000000000..779c3454fe518 --- /dev/null +++ b/sycl/include/sycl/properties/buffer_properties.def @@ -0,0 +1,19 @@ +// --*- c++ -*--- +#ifndef __SYCL_DATA_LESS_PROP +#define __SYCL_DATA_LESS_PROP(NS_QUALIFIER, PROP_NAME, ENUM_VAL) +#endif +#ifndef __SYCL_MANUALLY_DEFINED_PROP +#define __SYCL_MANUALLY_DEFINED_PROP(NS_QUALIFIER, PROP_NAME) +#endif + +__SYCL_DATA_LESS_PROP(property::buffer, use_host_ptr, BufferUseHostPtr) +__SYCL_DATA_LESS_PROP(ext::oneapi::property::buffer, use_pinned_host_memory, BufferUsePinnedHostMemory) + +// Contains data field, defined explicitly. +__SYCL_MANUALLY_DEFINED_PROP(property::buffer, use_mutex) +__SYCL_MANUALLY_DEFINED_PROP(property::buffer, context_bound) +__SYCL_MANUALLY_DEFINED_PROP(property::buffer, mem_channel) +__SYCL_MANUALLY_DEFINED_PROP(property::buffer::detail, buffer_location) + +#undef __SYCL_DATA_LESS_PROP +#undef __SYCL_MANUALLY_DEFINED_PROP diff --git a/sycl/include/sycl/properties/buffer_properties.hpp b/sycl/include/sycl/properties/buffer_properties.hpp index d904597944eec..d41ccaa656a49 100644 --- a/sycl/include/sycl/properties/buffer_properties.hpp +++ b/sycl/include/sycl/properties/buffer_properties.hpp @@ -19,11 +19,14 @@ namespace sycl { inline namespace _V1 { +#define __SYCL_DATA_LESS_PROP(NS_QUALIFIER, PROP_NAME, ENUM_VAL) \ + namespace NS_QUALIFIER { \ + class PROP_NAME \ + : public sycl::detail::DataLessProperty {}; \ + } +#include namespace property::buffer { -class use_host_ptr : public detail::DataLessProperty { -}; - class use_mutex : public detail::PropertyWithData { public: use_mutex(std::mutex &MutexRef) : MMutex(MutexRef) {} @@ -69,41 +72,19 @@ class buffer_location } // namespace detail } // namespace property::buffer -namespace ext::oneapi::property::buffer { - -class use_pinned_host_memory : public sycl::detail::DataLessProperty< - sycl::detail::BufferUsePinnedHostMemory> {}; -} // namespace ext::oneapi::property::buffer - // Forward declaration template class buffer; -// Buffer property trait specializations -template -struct is_property_of> - : std::true_type {}; -template -struct is_property_of> - : std::true_type {}; -template -struct is_property_of> - : std::true_type {}; -template -struct is_property_of> - : std::true_type {}; -template -struct is_property_of> - : std::true_type {}; -template -struct is_property_of> - : std::true_type {}; +#define __SYCL_MANUALLY_DEFINED_PROP(NS_QUALIFIER, PROP_NAME) \ + template \ + struct is_property_of> \ + : std::true_type {}; +#define __SYCL_DATA_LESS_PROP(NS_QUALIFIER, PROP_NAME, ENUM_VAL) \ + __SYCL_MANUALLY_DEFINED_PROP(NS_QUALIFIER, PROP_NAME) + +#include } // namespace _V1 } // namespace sycl diff --git a/sycl/include/sycl/properties/image_properties.def b/sycl/include/sycl/properties/image_properties.def new file mode 100644 index 0000000000000..9e5c02a346e12 --- /dev/null +++ b/sycl/include/sycl/properties/image_properties.def @@ -0,0 +1,16 @@ +// --*- c++ -*--- +#ifndef __SYCL_DATA_LESS_PROP +#define __SYCL_DATA_LESS_PROP(NS_QUALIFIER, PROP_NAME, ENUM_VAL) +#endif +#ifndef __SYCL_MANUALLY_DEFINED_PROP +#define __SYCL_MANUALLY_DEFINED_PROP(NS_QUALIFIER, PROP_NAME) +#endif + +__SYCL_DATA_LESS_PROP(property::image, use_host_ptr, ImageUseHostPtr) + +// Contains data field, defined explicitly. +__SYCL_MANUALLY_DEFINED_PROP(property::image, use_mutex) +__SYCL_MANUALLY_DEFINED_PROP(property::image, context_bound) + +#undef __SYCL_DATA_LESS_PROP +#undef __SYCL_MANUALLY_DEFINED_PROP diff --git a/sycl/include/sycl/properties/image_properties.hpp b/sycl/include/sycl/properties/image_properties.hpp index 43e6a22d81713..394ab4fd78c6f 100644 --- a/sycl/include/sycl/properties/image_properties.hpp +++ b/sycl/include/sycl/properties/image_properties.hpp @@ -18,10 +18,14 @@ namespace sycl { inline namespace _V1 { -namespace property::image { -class use_host_ptr : public detail::DataLessProperty { -}; +#define __SYCL_DATA_LESS_PROP(NS_QUALIFIER, PROP_NAME, ENUM_VAL) \ + namespace NS_QUALIFIER { \ + class PROP_NAME \ + : public sycl::detail::DataLessProperty {}; \ + } +#include +namespace property::image { class use_mutex : public detail::PropertyWithData { public: use_mutex(std::mutex &MutexRef) : MMutex(MutexRef) {} @@ -50,41 +54,32 @@ template class sampled_image; template class unsampled_image; // SYCL 1.2.1 image property trait specializations -template -struct is_property_of> : std::true_type {}; -template -struct is_property_of> - : std::true_type {}; -template -struct is_property_of> : std::true_type {}; +#define __SYCL_MANUALLY_DEFINED_PROP(NS_QUALIFIER, PROP_NAME) \ + template \ + struct is_property_of> : std::true_type {}; +#define __SYCL_DATA_LESS_PROP(NS_QUALIFIER, PROP_NAME, ENUM_VAL) \ + __SYCL_MANUALLY_DEFINED_PROP(NS_QUALIFIER, PROP_NAME) +#include // SYCL 2020 image property trait specializations -template -struct is_property_of> : std::true_type { -}; -template -struct is_property_of> : std::true_type { -}; -template -struct is_property_of> : std::true_type { -}; -template -struct is_property_of> - : std::true_type {}; -template -struct is_property_of> - : std::true_type {}; -template -struct is_property_of> - : std::true_type {}; +#define __SYCL_MANUALLY_DEFINED_PROP(NS_QUALIFIER, PROP_NAME) \ + template \ + struct is_property_of> \ + : std::true_type {}; +#define __SYCL_DATA_LESS_PROP(NS_QUALIFIER, PROP_NAME, ENUM_VAL) \ + __SYCL_MANUALLY_DEFINED_PROP(NS_QUALIFIER, PROP_NAME) +#include + +#define __SYCL_MANUALLY_DEFINED_PROP(NS_QUALIFIER, PROP_NAME) \ + template \ + struct is_property_of> \ + : std::true_type {}; +#define __SYCL_DATA_LESS_PROP(NS_QUALIFIER, PROP_NAME, ENUM_VAL) \ + __SYCL_MANUALLY_DEFINED_PROP(NS_QUALIFIER, PROP_NAME) +#include } // namespace _V1 } // namespace sycl diff --git a/sycl/include/sycl/properties/reduction_properties.def b/sycl/include/sycl/properties/reduction_properties.def new file mode 100644 index 0000000000000..49b6480c3d123 --- /dev/null +++ b/sycl/include/sycl/properties/reduction_properties.def @@ -0,0 +1,12 @@ +// --*- c++ -*--- +#ifndef __SYCL_DATA_LESS_PROP +#define __SYCL_DATA_LESS_PROP(NS_QUALIFIER, PROP_NAME, ENUM_VAL) +#endif +#ifndef __SYCL_MANUALLY_DEFINED_PROP +#define __SYCL_MANUALLY_DEFINED_PROP(NS_QUALIFIER, PROP_NAME) +#endif + +__SYCL_DATA_LESS_PROP(property::reduction, initialize_to_identity, InitializeToIdentity) + +#undef __SYCL_DATA_LESS_PROP +#undef __SYCL_MANUALLY_DEFINED_PROP diff --git a/sycl/include/sycl/properties/reduction_properties.hpp b/sycl/include/sycl/properties/reduction_properties.hpp index eaabf22524979..ae112479e9efd 100644 --- a/sycl/include/sycl/properties/reduction_properties.hpp +++ b/sycl/include/sycl/properties/reduction_properties.hpp @@ -12,10 +12,12 @@ namespace sycl { inline namespace _V1 { -namespace property::reduction { -class initialize_to_identity - : public detail::DataLessProperty {}; -} // namespace property::reduction +#define __SYCL_DATA_LESS_PROP(NS_QUALIFIER, PROP_NAME, ENUM_VAL) \ + namespace NS_QUALIFIER { \ + class PROP_NAME \ + : public sycl::detail::DataLessProperty {}; \ + } +#include // Reduction property trait specializations } // namespace _V1 diff --git a/sycl/include/sycl/properties/runtime_accessor_properties.def b/sycl/include/sycl/properties/runtime_accessor_properties.def new file mode 100644 index 0000000000000..36bf997f83dae --- /dev/null +++ b/sycl/include/sycl/properties/runtime_accessor_properties.def @@ -0,0 +1,17 @@ +// --*- c++ -*--- +#ifndef __SYCL_DATA_LESS_PROP +#define __SYCL_DATA_LESS_PROP(NS_QUALIFIER, PROP_NAME, ENUM_VAL) +#endif +#ifndef __SYCL_MANUALLY_DEFINED_PROP +#define __SYCL_MANUALLY_DEFINED_PROP(NS_QUALIFIER, PROP_NAME) +#endif +#ifndef __SYCL_DATA_LESS_PROP_DEPRECATED_ALIAS +#define __SYCL_DATA_LESS_PROP_DEPRECATED_ALIAS(NS_QUALIFIER, PROP_NAME, ENUM_VAL, WARNING) +#endif + +__SYCL_DATA_LESS_PROP(property, no_init, NoInit) +__SYCL_DATA_LESS_PROP_DEPRECATED_ALIAS(property, noinit, NoInit, __SYCL2020_DEPRECATED("spelling is now: no_init")) + +#undef __SYCL_DATA_LESS_PROP +#undef __SYCL_MANUALLY_DEFINED_PROP +#undef __SYCL_DATA_LESS_PROP_DEPRECATED_ALIAS diff --git a/sycl/include/sycl/property_list.hpp b/sycl/include/sycl/property_list.hpp index 714aed9b9b049..59620f56a707c 100644 --- a/sycl/include/sycl/property_list.hpp +++ b/sycl/include/sycl/property_list.hpp @@ -23,6 +23,9 @@ inline namespace _V1 { namespace ext::oneapi { template class accessor_property_list; } // namespace ext::oneapi +namespace detail { +class PropertyValidator; +} // namespace detail /// Objects of the property_list class are containers for the SYCL properties /// @@ -72,7 +75,19 @@ class property_list : protected detail::PropertyListBase { template friend class ext::oneapi::accessor_property_list; + friend class detail::PropertyValidator; }; +namespace detail { +class PropertyValidator { +public: + static void checkPropsAndThrow(const property_list &PropList, + std::function FunctionForDataless, + std::function FunctionForData) { + PropList.checkPropsAndThrow(FunctionForDataless, FunctionForData); + } +}; +} // namespace detail + } // namespace _V1 } // namespace sycl diff --git a/sycl/include/sycl/reduction.hpp b/sycl/include/sycl/reduction.hpp index 44ad02e4d595f..2859d3b7871f4 100644 --- a/sycl/include/sycl/reduction.hpp +++ b/sycl/include/sycl/reduction.hpp @@ -503,6 +503,8 @@ class ReducerElement { private: value_type MValue; }; + +__SYCL_EXPORT void verifyReductionProps(const property_list &Props); } // namespace detail // We explicitly claim std::optional as device-copyable in sycl/types.hpp. @@ -2842,6 +2844,7 @@ template auto reduction(buffer Var, handler &CGH, BinaryOperation Combiner, const property_list &PropList = {}) { std::ignore = CGH; + detail::verifyReductionProps(PropList); bool InitializeToIdentity = PropList.has_property(); return detail::make_reduction( @@ -2856,6 +2859,7 @@ auto reduction(buffer Var, handler &CGH, template auto reduction(T *Var, BinaryOperation Combiner, const property_list &PropList = {}) { + detail::verifyReductionProps(PropList); bool InitializeToIdentity = PropList.has_property(); return detail::make_reduction( @@ -2869,6 +2873,7 @@ template auto reduction(buffer Var, handler &CGH, const T &Identity, BinaryOperation Combiner, const property_list &PropList = {}) { std::ignore = CGH; + detail::verifyReductionProps(PropList); bool InitializeToIdentity = PropList.has_property(); return detail::make_reduction( @@ -2881,6 +2886,7 @@ auto reduction(buffer Var, handler &CGH, const T &Identity, template auto reduction(T *Var, const T &Identity, BinaryOperation Combiner, const property_list &PropList = {}) { + detail::verifyReductionProps(PropList); bool InitializeToIdentity = PropList.has_property(); return detail::make_reduction( @@ -2896,6 +2902,7 @@ template > auto reduction(span Span, BinaryOperation Combiner, const property_list &PropList = {}) { + detail::verifyReductionProps(PropList); bool InitializeToIdentity = PropList.has_property(); return detail::make_reduction( @@ -2909,6 +2916,7 @@ template > auto reduction(span Span, const T &Identity, BinaryOperation Combiner, const property_list &PropList = {}) { + detail::verifyReductionProps(PropList); bool InitializeToIdentity = PropList.has_property(); return detail::make_reduction( diff --git a/sycl/include/sycl/usm/usm_allocator.hpp b/sycl/include/sycl/usm/usm_allocator.hpp index fde0dae175b48..4f3b0fb63a313 100644 --- a/sycl/include/sycl/usm/usm_allocator.hpp +++ b/sycl/include/sycl/usm/usm_allocator.hpp @@ -21,6 +21,11 @@ namespace sycl { inline namespace _V1 { + +/// Validates usm_allocator properties +/// Throws sycl::exception if incorrect property is passed. +__SYCL_EXPORT void verifyUSMAllocatorProperties(const property_list &PropList); + template class usm_allocator { public: @@ -41,10 +46,14 @@ class usm_allocator { usm_allocator() = delete; usm_allocator(const context &Ctxt, const device &Dev, const property_list &PropList = {}) - : MContext(Ctxt), MDevice(Dev), MPropList(PropList) {} + : MContext(Ctxt), MDevice(Dev), MPropList(PropList) { + verifyUSMAllocatorProperties(MPropList); + } usm_allocator(const queue &Q, const property_list &PropList = {}) : MContext(Q.get_context()), MDevice(Q.get_device()), - MPropList(PropList) {} + MPropList(PropList) { + verifyUSMAllocatorProperties(MPropList); + } usm_allocator(const usm_allocator &) = default; usm_allocator(usm_allocator &&) noexcept = default; usm_allocator &operator=(const usm_allocator &Other) { diff --git a/sycl/source/accessor.cpp b/sycl/source/accessor.cpp index aa3547a4a44a6..0b1fab02fa6bd 100644 --- a/sycl/source/accessor.cpp +++ b/sycl/source/accessor.cpp @@ -23,12 +23,39 @@ device getDeviceFromHandler(handler &cgh) { return getSyclObjImpl(cgh)->MGraph->getDevice(); } +// property::no_init is supported now for +// accessor +// host_accessor +// unsampled_image_accessor +// host_unsampled_image_accessor + +static void verifyAccessorProps(const property_list &Props) { + auto CheckDataLessProperties = [](int PropertyKind) { +#define __SYCL_DATA_LESS_PROP(NS_QUALIFIER, PROP_NAME, ENUM_VAL) \ + case NS_QUALIFIER::PROP_NAME::getKind(): \ + return true; +#define __SYCL_MANUALLY_DEFINED_PROP(NS_QUALIFIER, PROP_NAME) + switch (PropertyKind) { +#include + default: + return false; + } + }; + // When new properties with data are added - please implement the second + // function with props include. + // Absence of any properties causes warning (+error) now. + auto NoAllowedPropertiesCheck = [](int) { return false; }; + detail::PropertyValidator::checkPropsAndThrow(Props, CheckDataLessProperties, + NoAllowedPropertiesCheck); +} + AccessorBaseHost::AccessorBaseHost(id<3> Offset, range<3> AccessRange, range<3> MemoryRange, access::mode AccessMode, void *SYCLMemObject, int Dims, int ElemSize, size_t OffsetInBytes, bool IsSubBuffer, const property_list &PropertyList) { + verifyAccessorProps(PropertyList); impl = std::shared_ptr( new AccessorImplHost(Offset, AccessRange, MemoryRange, AccessMode, (detail::SYCLMemObjI *)SYCLMemObject, Dims, ElemSize, @@ -41,6 +68,7 @@ AccessorBaseHost::AccessorBaseHost(id<3> Offset, range<3> AccessRange, int Dims, int ElemSize, bool IsPlaceH, size_t OffsetInBytes, bool IsSubBuffer, const property_list &PropertyList) { + verifyAccessorProps(PropertyList); impl = std::shared_ptr( new AccessorImplHost(Offset, AccessRange, MemoryRange, AccessMode, (detail::SYCLMemObjI *)SYCLMemObject, Dims, ElemSize, @@ -82,6 +110,7 @@ bool AccessorBaseHost::isMemoryObjectUsedByGraph() const { LocalAccessorBaseHost::LocalAccessorBaseHost( sycl::range<3> Size, int Dims, int ElemSize, const property_list &PropertyList) { + verifyAccessorProps(PropertyList); impl = std::shared_ptr( new LocalAccessorImplHost(Size, Dims, ElemSize, PropertyList)); } @@ -115,6 +144,7 @@ UnsampledImageAccessorBaseHost::UnsampledImageAccessorBaseHost( sycl::range<3> Size, access_mode AccessMode, void *SYCLMemObject, int Dims, int ElemSize, id<3> Pitch, image_channel_type ChannelType, image_channel_order ChannelOrder, const property_list &PropertyList) { + verifyAccessorProps(PropertyList); impl = std::make_shared( Size, AccessMode, (detail::SYCLMemObjI *)SYCLMemObject, Dims, ElemSize, Pitch, ChannelType, ChannelOrder, PropertyList); @@ -152,6 +182,11 @@ SampledImageAccessorBaseHost::SampledImageAccessorBaseHost( id<3> Pitch, image_channel_type ChannelType, image_channel_order ChannelOrder, image_sampler Sampler, const property_list &PropertyList) { + { + auto NoAllowedPropertiesCheck = [](int PropertyKind) { return false; }; + detail::PropertyValidator::checkPropsAndThrow( + PropertyList, NoAllowedPropertiesCheck, NoAllowedPropertiesCheck); + } impl = std::make_shared( Size, (detail::SYCLMemObjI *)SYCLMemObject, Dims, ElemSize, Pitch, ChannelType, ChannelOrder, Sampler, PropertyList); diff --git a/sycl/source/detail/buffer_impl.cpp b/sycl/source/detail/buffer_impl.cpp index 1746cf85159ef..777091f6be572 100644 --- a/sycl/source/detail/buffer_impl.cpp +++ b/sycl/source/detail/buffer_impl.cpp @@ -13,6 +13,7 @@ #include #include #include +#include namespace sycl { inline namespace _V1 { @@ -101,6 +102,34 @@ buffer_impl::getNativeVector(backend BackendName) const { addInteropObject(Handles); return Handles; } + +void buffer_impl::verifyProps(const property_list &Props) const { + auto CheckDataLessProperties = [](int PropertyKind) { +#define __SYCL_DATA_LESS_PROP(NS_QUALIFIER, PROP_NAME, ENUM_VAL) \ + case NS_QUALIFIER::PROP_NAME::getKind(): \ + return true; +#define __SYCL_MANUALLY_DEFINED_PROP(NS_QUALIFIER, PROP_NAME) + switch (PropertyKind) { +#include + default: + return false; + } + }; + auto CheckPropertiesWithData = [](int PropertyKind) { +#define __SYCL_DATA_LESS_PROP(NS_QUALIFIER, PROP_NAME, ENUM_VAL) +#define __SYCL_MANUALLY_DEFINED_PROP(NS_QUALIFIER, PROP_NAME) \ + case NS_QUALIFIER::PROP_NAME::getKind(): \ + return true; + switch (PropertyKind) { +#include + default: + return false; + } + }; + detail::PropertyValidator::checkPropsAndThrow(Props, CheckDataLessProperties, + CheckPropertiesWithData); +} + } // namespace detail } // namespace _V1 } // namespace sycl diff --git a/sycl/source/detail/buffer_impl.hpp b/sycl/source/detail/buffer_impl.hpp index 3c81af88be1db..f7a7e0999344d 100644 --- a/sycl/source/detail/buffer_impl.hpp +++ b/sycl/source/detail/buffer_impl.hpp @@ -46,7 +46,7 @@ class buffer_impl final : public SYCLMemObjT { buffer_impl(size_t SizeInBytes, size_t, const property_list &Props, std::unique_ptr Allocator) : BaseT(SizeInBytes, Props, std::move(Allocator)) { - + verifyProps(Props); if (Props.has_property()) throw sycl::exception( make_error_code(errc::invalid), @@ -57,7 +57,7 @@ class buffer_impl final : public SYCLMemObjT { const property_list &Props, std::unique_ptr Allocator) : BaseT(SizeInBytes, Props, std::move(Allocator)) { - + verifyProps(Props); if (Props.has_property< sycl::ext::oneapi::property::buffer::use_pinned_host_memory>()) throw sycl::exception( @@ -71,7 +71,7 @@ class buffer_impl final : public SYCLMemObjT { const property_list &Props, std::unique_ptr Allocator) : BaseT(SizeInBytes, Props, std::move(Allocator)) { - + verifyProps(Props); if (Props.has_property< sycl::ext::oneapi::property::buffer::use_pinned_host_memory>()) throw sycl::exception( @@ -86,7 +86,7 @@ class buffer_impl final : public SYCLMemObjT { const property_list &Props, std::unique_ptr Allocator, bool IsConstPtr) : BaseT(SizeInBytes, Props, std::move(Allocator)) { - + verifyProps(Props); if (Props.has_property< sycl::ext::oneapi::property::buffer::use_pinned_host_memory>()) throw sycl::exception( @@ -103,6 +103,7 @@ class buffer_impl final : public SYCLMemObjT { std::unique_ptr Allocator, bool IsConstPtr) : BaseT(SizeInBytes, Props, std::move(Allocator)) { + verifyProps(Props); if (Props.has_property< sycl::ext::oneapi::property::buffer::use_pinned_host_memory>()) throw sycl::exception( @@ -152,6 +153,8 @@ class buffer_impl final : public SYCLMemObjT { void addInteropObject(std::vector &Handles) const; std::vector getNativeVector(backend BackendName) const; + + void verifyProps(const property_list &Props) const; }; } // namespace detail diff --git a/sycl/source/detail/context_impl.cpp b/sycl/source/detail/context_impl.cpp index 698d0680728b1..dda9478f6a2bb 100644 --- a/sycl/source/detail/context_impl.cpp +++ b/sycl/source/detail/context_impl.cpp @@ -32,6 +32,7 @@ context_impl::context_impl(const device &Device, async_handler AsyncHandler, MContext(nullptr), MPlatform(detail::getSyclObjImpl(Device.get_platform())), MPropList(PropList), MSupportBufferLocationByDevices(NotChecked) { + verifyProps(PropList); MKernelProgramCache.setContextPtr(this); } @@ -41,6 +42,7 @@ context_impl::context_impl(const std::vector Devices, : MOwnedByRuntime(true), MAsyncHandler(AsyncHandler), MDevices(Devices), MContext(nullptr), MPlatform(), MPropList(PropList), MSupportBufferLocationByDevices(NotChecked) { + verifyProps(PropList); MPlatform = detail::getSyclObjImpl(MDevices[0].get_platform()); std::vector DeviceIds; for (const auto &D : MDevices) { @@ -537,6 +539,12 @@ context_impl::getProgramForHostPipe(const device &Device, return getProgramForDevImgs(Device, ImgIdentifiers, "host_pipe"); } +void context_impl::verifyProps(const property_list &Props) const { + auto NoAllowedPropertiesCheck = [](int PropertyKind) { return false; }; + detail::PropertyValidator::checkPropsAndThrow(Props, NoAllowedPropertiesCheck, + NoAllowedPropertiesCheck); +} + } // namespace detail } // namespace _V1 } // namespace sycl diff --git a/sycl/source/detail/context_impl.hpp b/sycl/source/detail/context_impl.hpp index 2013ab1c73df6..4fde73c8ba90c 100644 --- a/sycl/source/detail/context_impl.hpp +++ b/sycl/source/detail/context_impl.hpp @@ -305,6 +305,8 @@ class context_impl { std::unique_ptr> MDeviceGlobalUnregisteredData; std::mutex MDeviceGlobalUnregisteredDataMutex; + + void verifyProps(const property_list &Props) const; }; template diff --git a/sycl/source/detail/image_impl.cpp b/sycl/source/detail/image_impl.cpp index 76479463a92ef..a8582a2893943 100644 --- a/sycl/source/detail/image_impl.cpp +++ b/sycl/source/detail/image_impl.cpp @@ -482,6 +482,33 @@ void image_impl::unsampledImageDestructorNotification(void *UserObj) { XPTIRegistry::unsampledImageDestructorNotification(UserObj); } +void image_impl::verifyProps(const property_list &Props) const { + auto CheckDataLessProperties = [](int PropertyKind) { +#define __SYCL_DATA_LESS_PROP(NS_QUALIFIER, PROP_NAME, ENUM_VAL) \ + case NS_QUALIFIER::PROP_NAME::getKind(): \ + return true; +#define __SYCL_MANUALLY_DEFINED_PROP(NS_QUALIFIER, PROP_NAME) + switch (PropertyKind) { +#include + default: + return false; + } + }; + auto CheckPropertiesWithData = [](int PropertyKind) { +#define __SYCL_DATA_LESS_PROP(NS_QUALIFIER, PROP_NAME, ENUM_VAL) +#define __SYCL_MANUALLY_DEFINED_PROP(NS_QUALIFIER, PROP_NAME) \ + case NS_QUALIFIER::PROP_NAME::getKind(): \ + return true; + switch (PropertyKind) { +#include + default: + return false; + } + }; + detail::PropertyValidator::checkPropsAndThrow(Props, CheckDataLessProperties, + CheckPropertiesWithData); +} + } // namespace detail } // namespace _V1 } // namespace sycl diff --git a/sycl/source/detail/image_impl.hpp b/sycl/source/detail/image_impl.hpp index 5ee3b473aac8b..7b4c7508effaf 100644 --- a/sycl/source/detail/image_impl.hpp +++ b/sycl/source/detail/image_impl.hpp @@ -102,6 +102,7 @@ class image_impl final : public SYCLMemObjT { MRange(ImageRange), MOrder(Order), MType(Type), MNumChannels(getImageNumberChannels(MOrder)), MElementSize(getImageElementSize(MNumChannels, MType)) { + verifyProps(PropList); setPitches(); BaseT::handleHostData(HData, detail::getNextPowerOfTwo(MElementSize)); } @@ -114,6 +115,7 @@ class image_impl final : public SYCLMemObjT { MRange(ImageRange), MOrder(Order), MType(Type), MNumChannels(getImageNumberChannels(MOrder)), MElementSize(getImageElementSize(MNumChannels, MType)) { + verifyProps(PropList); setPitches(); BaseT::handleHostData(HData, detail::getNextPowerOfTwo(MElementSize)); } @@ -126,6 +128,7 @@ class image_impl final : public SYCLMemObjT { MRange(ImageRange), MOrder(Order), MType(Type), MNumChannels(getImageNumberChannels(MOrder)), MElementSize(getImageElementSize(MNumChannels, MType)) { + verifyProps(PropList); setPitches(Pitch); BaseT::handleHostData(HData, detail::getNextPowerOfTwo(MElementSize)); } @@ -139,6 +142,7 @@ class image_impl final : public SYCLMemObjT { MRange(ImageRange), MOrder(Order), MType(Type), MNumChannels(getImageNumberChannels(MOrder)), MElementSize(getImageElementSize(MNumChannels, MType)) { + verifyProps(PropList); setPitches(); BaseT::handleHostData(std::const_pointer_cast(HData), detail::getNextPowerOfTwo(MElementSize), IsConstPtr); @@ -153,6 +157,7 @@ class image_impl final : public SYCLMemObjT { MRange(ImageRange), MOrder(Order), MType(Type), MNumChannels(getImageNumberChannels(MOrder)), MElementSize(getImageElementSize(MNumChannels, MType)) { + verifyProps(PropList); setPitches(Pitch); BaseT::handleHostData(std::const_pointer_cast(HData), detail::getNextPowerOfTwo(MElementSize), IsConstPtr); @@ -168,6 +173,7 @@ class image_impl final : public SYCLMemObjT { MNumChannels(getImageNumberChannels(MOrder)), MElementSize(getImageElementSize(MNumChannels, MType)), MSampler(Sampler) { + verifyProps(PropList); setPitches(); BaseT::handleHostData(HData, detail::getNextPowerOfTwo(MElementSize)); } @@ -182,6 +188,7 @@ class image_impl final : public SYCLMemObjT { MNumChannels(getImageNumberChannels(MOrder)), MElementSize(getImageElementSize(MNumChannels, MType)), MSampler(Sampler) { + verifyProps(PropList); setPitches(Pitch); BaseT::handleHostData(HData, detail::getNextPowerOfTwo(MElementSize)); } @@ -196,6 +203,7 @@ class image_impl final : public SYCLMemObjT { MNumChannels(getImageNumberChannels(MOrder)), MElementSize(getImageElementSize(MNumChannels, MType)), MSampler(Sampler) { + verifyProps(PropList); setPitches(); BaseT::handleHostData(std::const_pointer_cast(HData), detail::getNextPowerOfTwo(MElementSize), @@ -213,6 +221,7 @@ class image_impl final : public SYCLMemObjT { MNumChannels(getImageNumberChannels(MOrder)), MElementSize(getImageElementSize(MNumChannels, MType)), MSampler(Sampler) { + verifyProps(PropList); setPitches(Pitch); BaseT::handleHostData(std::const_pointer_cast(HData), detail::getNextPowerOfTwo(MElementSize), @@ -346,6 +355,8 @@ class image_impl final : public SYCLMemObjT { // Image may carry a 2020 sampler. std::optional MSampler = std::nullopt; + + void verifyProps(const property_list &Props) const; }; } // namespace detail } // namespace _V1 diff --git a/sycl/source/detail/queue_impl.cpp b/sycl/source/detail/queue_impl.cpp index 869529bb75162..4d59af47f21a4 100644 --- a/sycl/source/detail/queue_impl.cpp +++ b/sycl/source/detail/queue_impl.cpp @@ -803,6 +803,33 @@ void queue_impl::doUnenqueuedCommandCleanup( tryToCleanup(MDefaultGraphDeps); } +void queue_impl::verifyProps(const property_list &Props) const { + auto CheckDataLessProperties = [](int PropertyKind) { +#define __SYCL_DATA_LESS_PROP(NS_QUALIFIER, PROP_NAME, ENUM_VAL) \ + case NS_QUALIFIER::PROP_NAME::getKind(): \ + return true; +#define __SYCL_MANUALLY_DEFINED_PROP(NS_QUALIFIER, PROP_NAME) + switch (PropertyKind) { +#include + default: + return false; + } + }; + auto CheckPropertiesWithData = [](int PropertyKind) { +#define __SYCL_DATA_LESS_PROP(NS_QUALIFIER, PROP_NAME, ENUM_VAL) +#define __SYCL_MANUALLY_DEFINED_PROP(NS_QUALIFIER, PROP_NAME) \ + case NS_QUALIFIER::PROP_NAME::getKind(): \ + return true; + switch (PropertyKind) { +#include + default: + return false; + } + }; + detail::PropertyValidator::checkPropsAndThrow(Props, CheckDataLessProperties, + CheckPropertiesWithData); +} + } // namespace detail } // namespace _V1 } // namespace sycl diff --git a/sycl/source/detail/queue_impl.hpp b/sycl/source/detail/queue_impl.hpp index 6bf9c338e6f3f..8b9ad7dc22995 100644 --- a/sycl/source/detail/queue_impl.hpp +++ b/sycl/source/detail/queue_impl.hpp @@ -113,6 +113,7 @@ class queue_impl { MIsProfilingEnabled(has_property()), MQueueID{ MNextAvailableQueueID.fetch_add(1, std::memory_order_relaxed)} { + verifyProps(PropList); if (has_property()) { if (has_property()) throw sycl::exception(make_error_code(errc::invalid), @@ -242,6 +243,7 @@ class queue_impl { MIsProfilingEnabled(has_property()), MQueueID{ MNextAvailableQueueID.fetch_add(1, std::memory_order_relaxed)} { + verifyProps(PropList); queue_impl_interop(UrQueue); } @@ -960,6 +962,8 @@ class queue_impl { std::mutex MMissedCleanupRequestsMtx; friend class sycl::ext::oneapi::experimental::detail::node_impl; + + void verifyProps(const property_list &Props) const; }; } // namespace detail diff --git a/sycl/source/detail/reduction.cpp b/sycl/source/detail/reduction.cpp index 4ad7d207fe6ec..6e2d49d909f29 100644 --- a/sycl/source/detail/reduction.cpp +++ b/sycl/source/detail/reduction.cpp @@ -179,6 +179,23 @@ addCounterInit(handler &CGH, std::shared_ptr &Queue, CGH.depends_on(createSyclObjFromImpl(EventImpl)); } +__SYCL_EXPORT void verifyReductionProps(const property_list &Props) { + auto CheckDataLessProperties = [](int PropertyKind) { +#define __SYCL_DATA_LESS_PROP(NS_QUALIFIER, PROP_NAME, ENUM_VAL) \ + case NS_QUALIFIER::PROP_NAME::getKind(): \ + return true; +#define __SYCL_MANUALLY_DEFINED_PROP(NS_QUALIFIER, PROP_NAME) + switch (PropertyKind) { +#include + default: + return false; + } + }; + auto NoAllowedPropertiesCheck = [](int) { return false; }; + detail::PropertyValidator::checkPropsAndThrow(Props, CheckDataLessProperties, + NoAllowedPropertiesCheck); +} + } // namespace detail } // namespace _V1 } // namespace sycl diff --git a/sycl/source/detail/sampler_impl.cpp b/sycl/source/detail/sampler_impl.cpp index 77f151b69c1dd..0377966582c8a 100644 --- a/sycl/source/detail/sampler_impl.cpp +++ b/sycl/source/detail/sampler_impl.cpp @@ -19,7 +19,9 @@ sampler_impl::sampler_impl(coordinate_normalization_mode normalizationMode, filtering_mode filteringMode, const property_list &propList) : MCoordNormMode(normalizationMode), MAddrMode(addressingMode), - MFiltMode(filteringMode), MPropList(propList) {} + MFiltMode(filteringMode), MPropList(propList) { + verifyProps(MPropList); +} sampler_impl::sampler_impl(cl_sampler clSampler, const context &syclContext) { const AdapterPtr &Adapter = getSyclObjImpl(syclContext)->getAdapter(); @@ -155,6 +157,12 @@ sampler_impl::get_coordinate_normalization_mode() const { return MCoordNormMode; } +void sampler_impl::verifyProps(const property_list &Props) const { + auto NoAllowedPropertiesCheck = [](int PropertyKind) { return false; }; + detail::PropertyValidator::checkPropsAndThrow(Props, NoAllowedPropertiesCheck, + NoAllowedPropertiesCheck); +} + } // namespace detail } // namespace _V1 } // namespace sycl diff --git a/sycl/source/detail/sampler_impl.hpp b/sycl/source/detail/sampler_impl.hpp index cfa4c83b15607..2589ad9244a3a 100644 --- a/sycl/source/detail/sampler_impl.hpp +++ b/sycl/source/detail/sampler_impl.hpp @@ -55,6 +55,8 @@ class sampler_impl { addressing_mode MAddrMode; filtering_mode MFiltMode; property_list MPropList; + + void verifyProps(const property_list &Props) const; }; } // namespace detail diff --git a/sycl/source/detail/stream_impl.cpp b/sycl/source/detail/stream_impl.cpp index d0094c025c844..54ae19f82c586 100644 --- a/sycl/source/detail/stream_impl.cpp +++ b/sycl/source/detail/stream_impl.cpp @@ -23,6 +23,7 @@ stream_impl::stream_impl(size_t BufferSize, size_t MaxStatementSize, : BufferSize_(BufferSize), MaxStatementSize_(MaxStatementSize), PropList_(PropList), Buf_(range<1>(BufferSize + OffsetSize + 1)), FlushBuf_(range<1>(MaxStatementSize + FLUSH_BUF_OFFSET_SIZE)) { + verifyProps(PropList_); // Additional place is allocated in the stream buffer for the offset variable // and the end of line symbol. Buffers are created without host pointers so // that they are released in a deferred manner. Disable copy back on buffer @@ -97,6 +98,12 @@ void stream_impl::generateFlushCommand(handler &cgh) { }); } +void stream_impl::verifyProps(const property_list &Props) const { + auto NoAllowedPropertiesCheck = [](int PropertyKind) { return false; }; + detail::PropertyValidator::checkPropsAndThrow(Props, NoAllowedPropertiesCheck, + NoAllowedPropertiesCheck); +} + } // namespace detail } // namespace _V1 } // namespace sycl diff --git a/sycl/source/detail/stream_impl.hpp b/sycl/source/detail/stream_impl.hpp index 87edfdec0bd90..69f85acffb6f4 100644 --- a/sycl/source/detail/stream_impl.hpp +++ b/sycl/source/detail/stream_impl.hpp @@ -67,6 +67,8 @@ class stream_impl { // Additinonal memory is allocated in the beginning of the stream buffer for // 2 variables: offset in the stream buffer and offset in the flush buffer. static const size_t OffsetSize = 2 * sizeof(unsigned); + + void verifyProps(const property_list &Props) const; }; } // namespace detail diff --git a/sycl/source/detail/usm/usm_impl.cpp b/sycl/source/detail/usm/usm_impl.cpp index 74a54197e7640..3a8e839fd0775 100644 --- a/sycl/source/detail/usm/usm_impl.cpp +++ b/sycl/source/detail/usm/usm_impl.cpp @@ -649,5 +649,11 @@ void release_from_device_copy(const void *Ptr, const queue &Queue) { } } // namespace ext::oneapi::experimental +__SYCL_EXPORT void verifyUSMAllocatorProperties(const property_list &PropList) { + auto NoAllowedPropertiesCheck = [](int PropertyKind) { return false; }; + detail::PropertyValidator::checkPropsAndThrow( + PropList, NoAllowedPropertiesCheck, NoAllowedPropertiesCheck); +} + } // namespace _V1 } // namespace sycl diff --git a/sycl/test-e2e/Basic/sampler/sampler.cpp b/sycl/test-e2e/Basic/sampler/sampler.cpp index 738408812f098..45081127f6314 100644 --- a/sycl/test-e2e/Basic/sampler/sampler.cpp +++ b/sycl/test-e2e/Basic/sampler/sampler.cpp @@ -83,21 +83,5 @@ int main() { }); } - { - sycl::sampler Sampler( - sycl::coordinate_normalization_mode::unnormalized, - sycl::addressing_mode::clamp, sycl::filtering_mode::nearest, - sycl::property_list{sycl::property::buffer::use_host_ptr{}}); - - if (!Sampler.has_property()) { - std::cerr << "Line " << __LINE__ << ": Property was not found" - << std::endl; - return 1; - } - - sycl::property::buffer::use_host_ptr Prop = - Sampler.get_property(); - } - return 0; } diff --git a/sycl/test-e2e/Basic/stream/stream.cpp b/sycl/test-e2e/Basic/stream/stream.cpp index fe3429cffad2b..171bea8be9812 100644 --- a/sycl/test-e2e/Basic/stream/stream.cpp +++ b/sycl/test-e2e/Basic/stream/stream.cpp @@ -33,15 +33,9 @@ int main() { // Check constructor and getters Queue.submit([&](handler &CGH) { - stream Out(1024, 80, CGH, - property_list{property::buffer::context_bound{Context}}); + stream Out(1024, 80, CGH); assert(Out.size() == 1024); assert(Out.get_work_item_buffer_size() == 80); - assert(Out.has_property()); - assert(!Out.has_property()); - assert( - Out.get_property().get_context() == - Context); sycl::accessor accSize(bufSize, CGH, sycl::write_only); sycl::accessor accWorkItemBufferSize(bufWorkItemBufferSize, CGH, diff --git a/sycl/test/abi/sycl_symbols_linux.dump b/sycl/test/abi/sycl_symbols_linux.dump index bf5542036a2e2..30f1cb9d25308 100644 --- a/sycl/test/abi/sycl_symbols_linux.dump +++ b/sycl/test/abi/sycl_symbols_linux.dump @@ -2984,6 +2984,7 @@ _ZN4sycl3_V121__isgreaterequal_implENS0_6detail9half_impl4halfES3_ _ZN4sycl3_V121__isgreaterequal_implEdd _ZN4sycl3_V121__isgreaterequal_implEff _ZN4sycl3_V122accelerator_selector_vERKNS0_6deviceE +_ZN4sycl3_V128verifyUSMAllocatorPropertiesERKNS0_13property_listE _ZN4sycl3_V13ext5intel12experimental15online_compilerILNS3_15source_languageE0EE7compileIJSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaISE_EEEEES8_IhSaIhEERKSE_DpRKT_ _ZN4sycl3_V13ext5intel12experimental15online_compilerILNS3_15source_languageE1EE7compileIJSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaISE_EEEEES8_IhSaIhEERKSE_DpRKT_ _ZN4sycl3_V13ext5intel12experimental9pipe_base13get_pipe_nameB5cxx11EPKv @@ -3265,6 +3266,7 @@ _ZN4sycl3_V16detail20associateWithHandlerERNS0_7handlerEPNS1_28SampledImageAcces _ZN4sycl3_V16detail20associateWithHandlerERNS0_7handlerEPNS1_30UnsampledImageAccessorBaseHostENS0_12image_targetE _ZN4sycl3_V16detail20getDeviceFromHandlerERNS0_7handlerE _ZN4sycl3_V16detail20markBufferAsInternalERKSt10shared_ptrINS1_11buffer_implEE +_ZN4sycl3_V16detail20verifyReductionPropsERKNS0_13property_listE _ZN4sycl3_V16detail21LocalAccessorBaseHost12getNumOfDimsEv _ZN4sycl3_V16detail21LocalAccessorBaseHost14getElementSizeEv _ZN4sycl3_V16detail21LocalAccessorBaseHost6getPtrEv diff --git a/sycl/test/abi/sycl_symbols_windows.dump b/sycl/test/abi/sycl_symbols_windows.dump index 17a1e6b9fc167..0235b489f24f0 100644 --- a/sycl/test/abi/sycl_symbols_windows.dump +++ b/sycl/test/abi/sycl_symbols_windows.dump @@ -4267,10 +4267,12 @@ ?update@executable_command_graph@detail@experimental@oneapi@ext@_V1@sycl@@QEAAXAEBV?$vector@Vnode@experimental@oneapi@ext@_V1@sycl@@V?$allocator@Vnode@experimental@oneapi@ext@_V1@sycl@@@std@@@std@@@Z ?update@executable_command_graph@detail@experimental@oneapi@ext@_V1@sycl@@QEAAXAEBVnode@34567@@Z ?updateAccessor@dynamic_parameter_base@detail@experimental@oneapi@ext@_V1@sycl@@IEAAXPEBVAccessorBaseHost@267@@Z -?updateValue@dynamic_parameter_base@detail@experimental@oneapi@ext@_V1@sycl@@IEAAXPEBX_K@Z ?updateValue@dynamic_parameter_base@detail@experimental@oneapi@ext@_V1@sycl@@IEAAXPEBVraw_kernel_arg@34567@_K@Z +?updateValue@dynamic_parameter_base@detail@experimental@oneapi@ext@_V1@sycl@@IEAAXPEBX_K@Z ?use_kernel_bundle@handler@_V1@sycl@@QEAAXAEBV?$kernel_bundle@$01@23@@Z ?verifyDeviceHasProgressGuarantee@handler@_V1@sycl@@AEAAXW4forward_progress_guarantee@experimental@oneapi@ext@23@W4execution_scope@56723@1@Z +?verifyReductionProps@detail@_V1@sycl@@YAXAEBVproperty_list@23@@Z +?verifyUSMAllocatorProperties@_V1@sycl@@YAXAEBVproperty_list@12@@Z ?verifyUsedKernelBundleInternal@handler@_V1@sycl@@AEAAXVstring_view@detail@23@@Z ?wait@event@_V1@sycl@@QEAAXXZ ?wait@event@_V1@sycl@@SAXAEBV?$vector@Vevent@_V1@sycl@@V?$allocator@Vevent@_V1@sycl@@@std@@@std@@@Z diff --git a/sycl/test/include_deps/sycl_accessor.hpp.cpp b/sycl/test/include_deps/sycl_accessor.hpp.cpp index 599ec1835d9cf..14f14242d4f82 100644 --- a/sycl/test/include_deps/sycl_accessor.hpp.cpp +++ b/sycl/test/include_deps/sycl_accessor.hpp.cpp @@ -83,6 +83,7 @@ // CHECK-NEXT: detail/handler_proxy.hpp // CHECK-NEXT: pointers.hpp // CHECK-NEXT: properties/accessor_properties.hpp +// CHECK-NEXT: properties/runtime_accessor_properties.def // CHECK-NEXT: properties/buffer_properties.hpp // CHECK-NEXT: context.hpp // CHECK-NEXT: async_handler.hpp @@ -111,4 +112,5 @@ // CHECK-NEXT: detail/string_view.hpp // CHECK-NEXT: detail/util.hpp // CHECK-NEXT: device_selector.hpp +// CHECK-NEXT: buffer_properties.def // CHECK-EMPTY: diff --git a/sycl/test/include_deps/sycl_detail_core.hpp.cpp b/sycl/test/include_deps/sycl_detail_core.hpp.cpp index 9b9ab56deb6c7..a9ca815bcfffd 100644 --- a/sycl/test/include_deps/sycl_detail_core.hpp.cpp +++ b/sycl/test/include_deps/sycl_detail_core.hpp.cpp @@ -84,6 +84,7 @@ // CHECK-NEXT: detail/handler_proxy.hpp // CHECK-NEXT: pointers.hpp // CHECK-NEXT: properties/accessor_properties.hpp +// CHECK-NEXT: properties/runtime_accessor_properties.def // CHECK-NEXT: properties/buffer_properties.hpp // CHECK-NEXT: context.hpp // CHECK-NEXT: async_handler.hpp @@ -112,6 +113,7 @@ // CHECK-NEXT: detail/string_view.hpp // CHECK-NEXT: detail/util.hpp // CHECK-NEXT: device_selector.hpp +// CHECK-NEXT: properties/buffer_properties.def // CHECK-NEXT: queue.hpp // CHECK-NEXT: detail/assert_happened.hpp // CHECK-NEXT: detail/cg_types.hpp diff --git a/sycl/unittests/CMakeLists.txt b/sycl/unittests/CMakeLists.txt index ec740f913ed4d..cc103358a10ad 100644 --- a/sycl/unittests/CMakeLists.txt +++ b/sycl/unittests/CMakeLists.txt @@ -57,3 +57,5 @@ add_subdirectory(buffer/l0_specific) if (NOT WIN32) add_subdirectory(xpti_trace) endif() +add_subdirectory(sampler) +add_subdirectory(reduction) diff --git a/sycl/unittests/accessor/CMakeLists.txt b/sycl/unittests/accessor/CMakeLists.txt index cb5e27e6d6aae..e41fc54a30f8e 100644 --- a/sycl/unittests/accessor/CMakeLists.txt +++ b/sycl/unittests/accessor/CMakeLists.txt @@ -7,4 +7,5 @@ add_sycl_unittest(AccessorTests OBJECT HostAccessorIterator.cpp HostAccessorReverseIterator.cpp LocalAccessorDefaultCtor.cpp + RuntimeProperties.cpp ) diff --git a/sycl/unittests/accessor/RuntimeProperties.cpp b/sycl/unittests/accessor/RuntimeProperties.cpp new file mode 100644 index 0000000000000..0346a30ac44c9 --- /dev/null +++ b/sycl/unittests/accessor/RuntimeProperties.cpp @@ -0,0 +1,154 @@ +//==---- RuntimeProperties.cpp --- check properties handling in RT --- -----==// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#include +#include +#include + +TEST(AccessorProperties, ValidPropsNoInit) { + sycl::unittest::UrMock<> Mock; + sycl::queue Queue; + try { + sycl::buffer Buf{1}; + std::ignore = Queue.submit([&](sycl::handler &cgh) { + sycl::accessor + BuffAcc(Buf, cgh, sycl::property::no_init{}); + cgh.fill(BuffAcc, 1); + }); + // no explicit checks, we expect no exception to be thrown + } catch (...) { + FAIL(); + } +} + +TEST(AccessorProperties, SetUnsupportedParam) { + sycl::unittest::UrMock<> Mock; + sycl::queue Queue; + try { + sycl::buffer Buf{1}; + std::ignore = Queue.submit([&](sycl::handler &cgh) { + // compile-time property is not supported in runtime + sycl::accessor + BuffAcc(Buf, cgh, sycl::ext::oneapi::property::no_alias{}); + cgh.fill(BuffAcc, 1); + }); + } catch (sycl::exception &e) { + EXPECT_EQ(e.code(), sycl::errc::invalid); + EXPECT_STREQ(e.what(), "The property list contains property unsupported " + "for the current object"); + return; + } +} + +TEST(HostAccessorProperties, ValidPropsNoInit) { + sycl::unittest::UrMock<> Mock; + sycl::queue Queue; + try { + sycl::buffer Buf{1}; + sycl::host_accessor BuffAcc( + Buf, sycl::property::no_init{}); + // no explicit checks, we expect no exception to be thrown + } catch (...) { + FAIL(); + } +} + +TEST(HostAccessorProperties, SetUnsupportedParam) { + sycl::unittest::UrMock<> Mock; + sycl::queue Queue; + try { + sycl::buffer Buf{1}; + sycl::host_accessor BuffAcc( + Buf, sycl::ext::oneapi::property::no_alias{}); + } catch (sycl::exception &e) { + EXPECT_EQ(e.code(), sycl::errc::invalid); + EXPECT_STREQ(e.what(), "The property list contains property unsupported " + "for the current object"); + return; + } +} + +// no test for image_accesor since it doesn't have property parameter in +// constructor. + +TEST(SampledAccessorProperties, NoSupportedProps) { + sycl::unittest::UrMock<> Mock; + sycl::queue Queue; + try { + sycl::image_sampler Sampler{ + sycl::addressing_mode::none, + sycl::coordinate_normalization_mode::unnormalized, + sycl::filtering_mode::linear}; + + constexpr size_t ElementsCount = 4; + constexpr size_t ChannelsCount = 4; + int InitValue[ElementsCount * ChannelsCount]; + sycl::sampled_image<1> Image(&InitValue, sycl::image_format::r8g8b8a8_unorm, + Sampler, sycl::range<1>(ElementsCount), + sycl::property::image::use_host_ptr{}); + std::ignore = Queue.submit([&](sycl::handler &cgh) { + sycl::sampled_image_accessor + ImageAcc(Image, cgh, sycl::property::no_init{}); + cgh.single_task([=]() {}); + }); + } catch (sycl::exception &e) { + EXPECT_EQ(e.code(), sycl::errc::invalid); + EXPECT_STREQ(e.what(), "The property list contains property unsupported " + "for the current object"); + return; + } + FAIL() << "Test must exit in exception handler. Exception is not thrown."; +} + +TEST(UnsampledImageAccessor, ValidPropsNoInit) { + sycl::unittest::UrMock<> Mock; + sycl::queue Queue; + try { + constexpr size_t ElementsCount = 4; + constexpr size_t ChannelsCount = 4; + int InitValue[ElementsCount * ChannelsCount]; + sycl::unsampled_image<1> Image( + &InitValue, sycl::image_format::r8g8b8a8_unorm, + sycl::range<1>(ElementsCount), sycl::property::image::use_host_ptr{}); + std::ignore = Queue.submit([&](sycl::handler &cgh) { + sycl::unsampled_image_accessor + ImageAcc(Image, cgh, sycl::property::no_init{}); + cgh.single_task([=]() {}); + }); + } catch (sycl::exception &e) { + EXPECT_EQ(e.code(), sycl::errc::feature_not_supported); + EXPECT_STREQ(e.what(), "Device associated with command group handler does " + "not have aspect::image."); + return; + } +} + +TEST(UnsampledImageAccessor, SetUnsupportedParam) { + sycl::unittest::UrMock<> Mock; + sycl::queue Queue; + try { + constexpr size_t ElementsCount = 4; + sycl::unsampled_image<1> Image(sycl::image_format::r8g8b8a8_unorm, + sycl::range<1>(ElementsCount), + sycl::property::buffer::use_host_ptr{}); + std::ignore = Queue.submit([&](sycl::handler &cgh) { + sycl::unsampled_image_accessor + ImageAcc(Image, cgh, sycl::ext::oneapi::property::no_alias{}); + cgh.single_task([=]() {}); + }); + } catch (sycl::exception &e) { + EXPECT_EQ(e.code(), sycl::errc::invalid); + EXPECT_STREQ(e.what(), "The property list contains property unsupported " + "for the current object"); + return; + } + + FAIL() << "Test must exit in exception handler. Exception is not thrown."; +} diff --git a/sycl/unittests/buffer/CMakeLists.txt b/sycl/unittests/buffer/CMakeLists.txt index 4f520dfe60879..744ad2ef12ad6 100644 --- a/sycl/unittests/buffer/CMakeLists.txt +++ b/sycl/unittests/buffer/CMakeLists.txt @@ -6,4 +6,5 @@ add_sycl_unittest(BufferTests OBJECT MemChannel.cpp KernelArgMemObj.cpp SubbufferLargeSize.cpp + Properties.cpp ) diff --git a/sycl/unittests/buffer/Properties.cpp b/sycl/unittests/buffer/Properties.cpp new file mode 100644 index 0000000000000..56393f643b6b5 --- /dev/null +++ b/sycl/unittests/buffer/Properties.cpp @@ -0,0 +1,253 @@ +//==-------- Properties.cpp --- check properties handling in RT --- --------==// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#include +#include +#include + +TEST(BufferProps, ValidPropsHostPtr) { + try { + int HostPtr[1]; + sycl::buffer Buf{HostPtr, 1, + sycl::property::buffer::use_host_ptr{}}; + // no explicit checks, we expect no exception to be thrown + } catch (...) { + FAIL(); + } +} + +TEST(BufferProps, ValidPropsContextBound) { + try { + sycl::unittest::UrMock<> Mock; + sycl::context Context; + sycl::buffer Buf{1, sycl::property::buffer::context_bound{Context}}; + // no explicit checks, we expect no exception to be thrown + } catch (...) { + FAIL(); + } +} + +TEST(BufferProps, ValidPropsMutex) { + try { + std::mutex Mutex; + sycl::buffer Buf{1, sycl::property::buffer::use_mutex{Mutex}}; + // no explicit checks, we expect no exception to be thrown + } catch (...) { + FAIL(); + } +} + +TEST(BufferProps, ValidPropsPinnedHostMem) { + try { + sycl::buffer Buf( + 1, {sycl::ext::oneapi::property::buffer::use_pinned_host_memory()}); + // no explicit checks, we expect no exception to be thrown + } catch (...) { + FAIL(); + } +} + +TEST(BufferProps, ValidPropsMemChannel) { + try { + sycl::buffer Buf(1, sycl::property::buffer::mem_channel{1}); + // no explicit checks, we expect no exception to be thrown + } catch (...) { + FAIL(); + } +} + +TEST(BufferProps, SetAndQueryMatch) { + try { + sycl::unittest::UrMock<> Mock; + std::mutex Mutex; + sycl::context Context; + int HostPtr[1]; + + sycl::buffer buf{HostPtr, + 1, + {sycl::property::buffer::use_host_ptr{}, + sycl::property::buffer::context_bound{Context}, + sycl::property::buffer::use_mutex{Mutex}}}; + + ASSERT_TRUE(buf.has_property()); + EXPECT_EQ( + buf.get_property().get_context(), + Context); + ASSERT_TRUE(buf.has_property()); + EXPECT_EQ( + buf.get_property().get_mutex_ptr(), + &Mutex); + EXPECT_TRUE(buf.has_property()); + // check some random not supported and not sent param + EXPECT_FALSE(buf.has_property()); + } catch (...) { + FAIL(); + } +} + +TEST(BufferProps, SetUnsupportedParam) { + try { + sycl::buffer buf{1, {sycl::property::image::use_host_ptr{}}}; + } catch (sycl::exception &e) { + EXPECT_EQ(e.code(), sycl::errc::invalid); + EXPECT_STREQ(e.what(), "The property list contains property unsupported " + "for the current object"); + return; + } + + FAIL() << "Test must exit in exception handler. Exception is not thrown."; +} + +TEST(ImageProps, ValidPropsHostPtr) { + try { + constexpr size_t ElementsCount = 4; + constexpr size_t ChannelsCount = 4; + float InitValue[ElementsCount * ChannelsCount]; + sycl::image<1> Image(&InitValue, sycl::image_channel_order::rgba, + sycl::image_channel_type::fp32, + sycl::range<1>(ElementsCount), + sycl::property::image::use_host_ptr{}); + // no explicit checks, we expect no exception to be thrown + } catch (...) { + FAIL(); + } +} + +TEST(ImageProps, ValidPropsContextBound) { + try { + sycl::unittest::UrMock<> Mock; + sycl::context Context; + constexpr size_t ElementsCount = 4; + sycl::image<1> Image(sycl::image_channel_order::rgba, + sycl::image_channel_type::fp32, + sycl::range<1>(ElementsCount), + sycl::property::image::context_bound{Context}); + // no explicit checks, we expect no exception to be thrown + } catch (...) { + FAIL(); + } +} + +TEST(ImageProps, ValidPropsMutex) { + try { + std::mutex Mutex; + constexpr size_t ElementsCount = 4; + sycl::image<1> Image( + sycl::image_channel_order::rgba, sycl::image_channel_type::fp32, + sycl::range<1>(ElementsCount), sycl::property::image::use_mutex{Mutex}); + // no explicit checks, we expect no exception to be thrown + } catch (...) { + FAIL(); + } +} + +TEST(ImageProps, SetUnsupportedParam) { + try { + std::mutex Mutex; + constexpr size_t ElementsCount = 4; + sycl::image<1> Image(sycl::image_channel_order::rgba, + sycl::image_channel_type::fp32, + sycl::range<1>(ElementsCount), + sycl::property::buffer::use_mutex{Mutex}); + } catch (sycl::exception &e) { + EXPECT_EQ(e.code(), sycl::errc::invalid); + EXPECT_STREQ(e.what(), "The property list contains property unsupported " + "for the current object"); + return; + } + + FAIL() << "Test must exit in exception handler. Exception is not thrown."; +} + +TEST(USMAllocator, Properties) { + sycl::unittest::UrMock<> Mock; + try { + sycl::queue Q; + sycl::usm_allocator Allocator( + Q, sycl::property::buffer::use_host_ptr{}); + } catch (sycl::exception &e) { + EXPECT_EQ(e.code(), sycl::errc::invalid); + EXPECT_STREQ(e.what(), "The property list contains property unsupported " + "for the current object"); + return; + } + + FAIL() << "Test must exit in exception handler. Exception is not thrown."; +} + +TEST(SampledImage, ValidPropsHostPtr) { + try { + sycl::image_sampler Sampler{ + sycl::addressing_mode::none, + sycl::coordinate_normalization_mode::unnormalized, + sycl::filtering_mode::linear}; + + constexpr size_t ElementsCount = 4; + constexpr size_t ChannelsCount = 4; + int InitValue[ElementsCount * ChannelsCount]; + sycl::sampled_image<1> Image(&InitValue, sycl::image_format::r8g8b8a8_unorm, + Sampler, sycl::range<1>(ElementsCount), + sycl::property::image::use_host_ptr{}); + // no explicit checks, we expect no exception to be thrown + } catch (...) { + FAIL(); + } +} + +TEST(SampledImage, SetUnsupportedParam) { + try { + sycl::image_sampler Sampler{ + sycl::addressing_mode::none, + sycl::coordinate_normalization_mode::unnormalized, + sycl::filtering_mode::linear}; + + constexpr size_t ElementsCount = 4; + constexpr size_t ChannelsCount = 4; + int InitValue[ElementsCount * ChannelsCount]; + sycl::sampled_image<1> Image(&InitValue, sycl::image_format::r8g8b8a8_unorm, + Sampler, sycl::range<1>(ElementsCount), + sycl::property::buffer::use_host_ptr{}); + } catch (sycl::exception &e) { + EXPECT_EQ(e.code(), sycl::errc::invalid); + EXPECT_STREQ(e.what(), "The property list contains property unsupported " + "for the current object"); + return; + } + + FAIL() << "Test must exit in exception handler. Exception is not thrown."; +} + +TEST(UnsampledImage, ValidPropsHostPtr) { + try { + constexpr size_t ElementsCount = 4; + constexpr size_t ChannelsCount = 4; + int InitValue[ElementsCount * ChannelsCount]; + sycl::unsampled_image<1> Image( + &InitValue, sycl::image_format::r8g8b8a8_unorm, + sycl::range<1>(ElementsCount), sycl::property::image::use_host_ptr{}); + // no explicit checks, we expect no exception to be thrown + } catch (...) { + FAIL(); + } +} + +TEST(UnsampledImage, SetUnsupportedParam) { + try { + constexpr size_t ElementsCount = 4; + sycl::unsampled_image<1> Image(sycl::image_format::r8g8b8a8_unorm, + sycl::range<1>(ElementsCount), + sycl::property::buffer::use_host_ptr{}); + } catch (sycl::exception &e) { + EXPECT_EQ(e.code(), sycl::errc::invalid); + EXPECT_STREQ(e.what(), "The property list contains property unsupported " + "for the current object"); + return; + } + + FAIL() << "Test must exit in exception handler. Exception is not thrown."; +} diff --git a/sycl/unittests/context_device/Context.cpp b/sycl/unittests/context_device/Context.cpp index 3680a9de7bc97..548a909e80df8 100644 --- a/sycl/unittests/context_device/Context.cpp +++ b/sycl/unittests/context_device/Context.cpp @@ -61,3 +61,16 @@ TEST_F(ContextTest, CopyAssignmentOperator) { ASSERT_EQ(hash, std::hash()(WillContextCopy)); ASSERT_EQ(Context, WillContextCopy); } + +TEST_F(ContextTest, Properties) { + try { + sycl::context Context(sycl::property::queue::in_order{}); + } catch (sycl::exception &e) { + EXPECT_EQ(e.code(), sycl::errc::invalid); + EXPECT_STREQ(e.what(), "The property list contains property unsupported " + "for the current object"); + return; + } + + FAIL() << "Test must exit in exception handler. Exception is not thrown."; +} diff --git a/sycl/unittests/queue/CMakeLists.txt b/sycl/unittests/queue/CMakeLists.txt index 5317d82354f77..07a5601c359c6 100644 --- a/sycl/unittests/queue/CMakeLists.txt +++ b/sycl/unittests/queue/CMakeLists.txt @@ -8,4 +8,5 @@ add_sycl_unittest(QueueTests OBJECT ShortcutFunctions.cpp InOrderQueue.cpp InteropRetain.cpp + Properties.cpp ) diff --git a/sycl/unittests/queue/Properties.cpp b/sycl/unittests/queue/Properties.cpp new file mode 100644 index 0000000000000..af7c6c941ef08 --- /dev/null +++ b/sycl/unittests/queue/Properties.cpp @@ -0,0 +1,90 @@ +//==-------- Properties.cpp --- check properties handling in RT --- --------==// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#include +#include +#include +#include + +template void DatalessQueuePropertyCheck() { + try { + sycl::queue Queue{PropertyType{}}; + ASSERT_TRUE(Queue.has_property()); + Queue.get_property(); + // no explicit checks, we expect no exception to be thrown + } catch (...) { + FAIL(); + } +} + +TEST(QueueProperties, ValidDatalessProperties) { + sycl::unittest::UrMock<> Mock; + DatalessQueuePropertyCheck(); + DatalessQueuePropertyCheck(); + DatalessQueuePropertyCheck< + sycl::ext::oneapi::property::queue::discard_events>(); + DatalessQueuePropertyCheck< + sycl::ext::oneapi::property::queue::priority_normal>(); + DatalessQueuePropertyCheck< + sycl::ext::oneapi::property::queue::priority_low>(); + DatalessQueuePropertyCheck< + sycl::ext::oneapi::property::queue::priority_high>(); + DatalessQueuePropertyCheck< + sycl::ext::intel::property::queue::no_immediate_command_list>(); + DatalessQueuePropertyCheck< + sycl::ext::intel::property::queue::immediate_command_list>(); + DatalessQueuePropertyCheck< + sycl::ext::oneapi::cuda::property::queue::use_default_stream>(); +} + +inline ur_result_t urDeviceGetInfoRedefined(void *pParams) { + auto params = reinterpret_cast(pParams); + switch (*params->ppropName) { + case UR_DEVICE_INFO_MAX_COMPUTE_QUEUE_INDICES: { + if (*params->ppPropValue) + *static_cast(*params->ppPropValue) = 8; + if (*params->ppPropSizeRet) + **params->ppPropSizeRet = sizeof(int32_t); + return UR_RESULT_SUCCESS; + } + default: + return UR_RESULT_SUCCESS; + } +} + +TEST(QueueProperties, ValidPropertyComputeIndex) { + sycl::unittest::UrMock<> Mock; + mock::getCallbacks().set_after_callback("urDeviceGetInfo", + &urDeviceGetInfoRedefined); + try { + sycl::queue Queue{sycl::ext::intel::property::queue::compute_index{1}}; + ASSERT_TRUE( + Queue.has_property()); + EXPECT_EQ( + Queue.get_property() + .get_index(), + 1); + // no explicit checks, we expect no exception to be thrown + } catch (...) { + FAIL(); + } +} + +TEST(QueueProperties, SetUnsupportedParam) { + sycl::unittest::UrMock<> Mock; + try { + sycl::queue Queue{sycl::property::image::use_host_ptr{}}; + } catch (sycl::exception &e) { + EXPECT_EQ(e.code(), sycl::errc::invalid); + EXPECT_STREQ(e.what(), "The property list contains property unsupported " + "for the current object"); + return; + } + + FAIL() << "Test must exit in exception handler. Exception is not thrown."; +} diff --git a/sycl/unittests/reduction/CMakeLists.txt b/sycl/unittests/reduction/CMakeLists.txt new file mode 100644 index 0000000000000..47d16980ceb66 --- /dev/null +++ b/sycl/unittests/reduction/CMakeLists.txt @@ -0,0 +1,3 @@ +add_sycl_unittest(ReductionTests OBJECT + Properties.cpp +) diff --git a/sycl/unittests/reduction/Properties.cpp b/sycl/unittests/reduction/Properties.cpp new file mode 100644 index 0000000000000..1b04b046016c6 --- /dev/null +++ b/sycl/unittests/reduction/Properties.cpp @@ -0,0 +1,40 @@ +//==-------- Properties.cpp --- check properties handling in RT --- --------==// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#include +#include +#include + +TEST(ReductionTest, InvalidProperties) { + int ReduVar = 0; + try { + auto Redu = sycl::reduction( + &ReduVar, int{0}, sycl::plus<>(), + sycl::property_list{sycl::property::buffer::use_host_ptr{}}); + } catch (sycl::exception &e) { + EXPECT_EQ(e.code(), sycl::errc::invalid); + EXPECT_STREQ(e.what(), "The property list contains property unsupported " + "for the current object"); + return; + } + + FAIL() << "Test must exit in exception handler. Exception is not thrown."; +} + +TEST(ReductionTest, ValidPropertyInitializeToIdentity) { + int ReduVar = 0; + try { + auto Redu = sycl::reduction( + &ReduVar, int{0}, sycl::plus<>(), + sycl::property_list{ + sycl::property::reduction::initialize_to_identity{}}); + // no explicit checks, we expect no exception to be thrown + } catch (...) { + FAIL(); + } +} diff --git a/sycl/unittests/sampler/CMakeLists.txt b/sycl/unittests/sampler/CMakeLists.txt new file mode 100644 index 0000000000000..f26b608afa5e4 --- /dev/null +++ b/sycl/unittests/sampler/CMakeLists.txt @@ -0,0 +1,3 @@ +add_sycl_unittest(SamplerTests OBJECT + Properties.cpp +) diff --git a/sycl/unittests/sampler/Properties.cpp b/sycl/unittests/sampler/Properties.cpp new file mode 100644 index 0000000000000..f828be32fb951 --- /dev/null +++ b/sycl/unittests/sampler/Properties.cpp @@ -0,0 +1,26 @@ +//==-------- Properties.cpp --- check properties handling in RT --- --------==// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#include +#include + +TEST(SamplerTest, Properties) { + try { + sycl::sampler Sampler( + sycl::coordinate_normalization_mode::unnormalized, + sycl::addressing_mode::clamp, sycl::filtering_mode::nearest, + sycl::property_list{sycl::property::buffer::use_host_ptr{}}); + } catch (sycl::exception &e) { + EXPECT_EQ(e.code(), sycl::errc::invalid); + EXPECT_STREQ(e.what(), "The property list contains property unsupported " + "for the current object"); + return; + } + + FAIL() << "Test must exit in exception handler. Exception is not thrown."; +} diff --git a/sycl/unittests/stream/stream.cpp b/sycl/unittests/stream/stream.cpp index 0811abff8cf77..7fee0309f84c3 100644 --- a/sycl/unittests/stream/stream.cpp +++ b/sycl/unittests/stream/stream.cpp @@ -59,3 +59,26 @@ TEST(Stream, TestStreamConstructorExceptionNoAllocation) { ASSERT_EQ(GBufferCreateCounter, 0u) << "Buffers were unexpectedly created."; } + +TEST(Stream, Properties) { + sycl::unittest::UrMock<> Mock; + sycl::queue Queue; + Queue + .submit([&](sycl::handler &CGH) { + try { + sycl::stream Stream{256, 256, CGH, sycl::property::queue::in_order{}}; + FAIL() << "No exception was thrown."; + } catch (const sycl::exception &e) { + EXPECT_EQ(e.code(), sycl::errc::invalid); + EXPECT_STREQ(e.what(), + "The property list contains property unsupported " + "for the current object"); + return; + } catch (...) { + FAIL() << "Unexpected exception was thrown."; + } + + CGH.single_task>([=]() {}); + }) + .wait(); +}