From 68d59b0947010381a4ed808c39c9e796989dddfb Mon Sep 17 00:00:00 2001 From: Steffen Larsen Date: Wed, 10 Nov 2021 17:55:31 +0300 Subject: [PATCH 01/24] [SYCL] Adds compile-time property list Implements the compile-time property list extension (https://github.com/intel/llvm/blob/sycl/sycl/doc/extensions/PropertyList/SYCL_EXT_ONEAPI_property_list.asciidoc) adding the sycl::ext::oneapi::property_list and sycl::ext::oneapi::property_value classes. These allow for compile-time inspection of properties passed to SYCL objects. These changes do not add support for the new property lists to any existing SYCL classes however. Signed-off-by: Steffen Larsen --- sycl/include/CL/sycl.hpp | 2 + .../CL/sycl/detail/property_helper.hpp | 16 +- .../oneapi/property_list/property_list.hpp | 195 +++++++++++++++ .../oneapi/property_list/property_utils.hpp | 233 ++++++++++++++++++ .../oneapi/property_list/property_value.hpp | 106 ++++++++ .../mock_compile_time_properties.hpp | 68 +++++ .../property_list_ctor_negative.cpp | 31 +++ .../property_list_device_copyable.cpp | 55 +++++ .../property_list/property_list_equality.cpp | 16 ++ .../property_list_get_property.cpp | 35 +++ .../property_list_get_property_negative.cpp | 46 ++++ .../property_list_has_property.cpp | 39 +++ .../property_list_is_property_list.cpp | 67 +++++ 13 files changed, 907 insertions(+), 2 deletions(-) create mode 100644 sycl/include/sycl/ext/oneapi/property_list/property_list.hpp create mode 100644 sycl/include/sycl/ext/oneapi/property_list/property_utils.hpp create mode 100644 sycl/include/sycl/ext/oneapi/property_list/property_value.hpp create mode 100644 sycl/test/extensions/property_list/mock_compile_time_properties.hpp create mode 100644 sycl/test/extensions/property_list/property_list_ctor_negative.cpp create mode 100644 sycl/test/extensions/property_list/property_list_device_copyable.cpp create mode 100644 sycl/test/extensions/property_list/property_list_equality.cpp create mode 100644 sycl/test/extensions/property_list/property_list_get_property.cpp create mode 100644 sycl/test/extensions/property_list/property_list_get_property_negative.cpp create mode 100644 sycl/test/extensions/property_list/property_list_has_property.cpp create mode 100644 sycl/test/extensions/property_list/property_list_is_property_list.cpp diff --git a/sycl/include/CL/sycl.hpp b/sycl/include/CL/sycl.hpp index 4837a656136bf..2d4c58348d54b 100644 --- a/sycl/include/CL/sycl.hpp +++ b/sycl/include/CL/sycl.hpp @@ -57,6 +57,8 @@ #include #include #include +#include +#include #include #include #include diff --git a/sycl/include/CL/sycl/detail/property_helper.hpp b/sycl/include/CL/sycl/detail/property_helper.hpp index d87e03c53167d..e870249f17985 100644 --- a/sycl/include/CL/sycl/detail/property_helper.hpp +++ b/sycl/include/CL/sycl/detail/property_helper.hpp @@ -49,6 +49,12 @@ enum PropWithDataKind { PropWithDataKindSize = 5 }; +// Base class for all properties to expose a unique ID. +template class IdentifyablePropertyBase { +public: + static constexpr int PropertyID = ID; +}; + // Base class for dataless properties, needed to check that the type of an // object passed to the property_list is a property. class DataLessPropertyBase {}; @@ -56,7 +62,9 @@ class DataLessPropertyBase {}; // Helper class for the dataless properties. Every such property is supposed // to inherit from it. The ID template parameter should be one from // DataLessPropKind. -template class DataLessProperty : DataLessPropertyBase { +template +class DataLessProperty : DataLessPropertyBase, + public IdentifyablePropertyBase { public: static constexpr int getKind() { return ID; } }; @@ -77,7 +85,11 @@ class PropertyWithDataBase { // Helper class for the properties with data. Every such property is supposed // to inherit from it. The ID template parameter should be one from // PropWithDataKind. -template class PropertyWithData : public PropertyWithDataBase { +template +class PropertyWithData + : public PropertyWithDataBase, + public IdentifyablePropertyBase< + ID + static_cast(DataLessPropKind::DataLessPropKindSize)> { public: PropertyWithData() : PropertyWithDataBase(ID) {} static int getKind() { return ID; } diff --git a/sycl/include/sycl/ext/oneapi/property_list/property_list.hpp b/sycl/include/sycl/ext/oneapi/property_list/property_list.hpp new file mode 100644 index 0000000000000..5c8a1bf587df5 --- /dev/null +++ b/sycl/include/sycl/ext/oneapi/property_list/property_list.hpp @@ -0,0 +1,195 @@ +//==-------- property_list.hpp --- SYCL extended property list -------------==// +// +// 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 +// +//===----------------------------------------------------------------------===// + +#pragma once + +#include +#include +#include + +#include + +__SYCL_INLINE_NAMESPACE(cl) { +namespace sycl { +namespace ext { +namespace oneapi { + +namespace detail { + +// Checks if a tuple of properties contains a property. +template +struct ContainsProperty : std::false_type {}; +template +struct ContainsProperty> + : ContainsProperty> {}; +template +struct ContainsProperty> : std::true_type {}; +template +struct ContainsProperty< + PropT, std::tuple, Rest...>> + : std::true_type {}; + +// Finds the full property_value type of a property in a tuple of properties. +// type is void if the type was not found in the tuple of properties. +template +struct FindCompileTimePropertyValueType { + using type = void; +}; +template +struct FindCompileTimePropertyValueType> { + using type = + typename FindCompileTimePropertyValueType>::type; +}; +template +struct FindCompileTimePropertyValueType< + CTPropertyT, + std::tuple, Rest...>> { + using type = property_value; +}; + +// Filters for all runtime properties with data in a tuple of properties. +// NOTE: We only need storage for runtime properties with data. +template struct RuntimePropertyStorage {}; +template struct RuntimePropertyStorage> { + using type = std::tuple<>; +}; +template +struct RuntimePropertyStorage> + : detail::conditional_t::value, + PrependTuple>::type>, + RuntimePropertyStorage>> {}; + +// Helper class to extract a subset of elements from a tuple. +// NOTES: This assumes no duplicate properties and that all properties in the +// struct template argument appear in the tuple passed to Extract. +template struct ExtractProperties {}; +template +struct ExtractProperties> { + template + using ExtractedPropertiesT = std::tuple<>; + + template + static ExtractedPropertiesT + Extract(std::tuple PropertyValues) { + return {}; + } +}; +template +struct ExtractProperties> { + template + using NextExtractedPropertiesT = + typename ExtractProperties>:: + template ExtractedPropertiesT; + template + using ExtractedPropertiesT = + typename PrependTuple>::type; + + template + static ExtractedPropertiesT + Extract(std::tuple PropertyValues) { + PropertyT ThisExtractedProperty = std::get(PropertyValues); + NextExtractedPropertiesT NextExtractedProperties = + ExtractProperties>::template Extract< + PropertyValueTs...>(PropertyValues); + return std::tuple_cat(std::tuple{ThisExtractedProperty}, + NextExtractedProperties); + } +}; + +} // namespace detail + +template class property_list { + static_assert(detail::IsTuple::value, + "Properties must be in a tuple."); + static_assert(detail::AllProperties::value, + "Unrecognized property in property list."); + static_assert(detail::IsSorted::value, + "Properties in property list are not sorted."); + static_assert(detail::AllUnique::value, + "Duplicate properties in property list."); + +public: + template + property_list(PropertyValueTs... props) + : Storage(detail::ExtractProperties::Extract( + std::tuple{props...})) {} + + template + static constexpr detail::enable_if_t< + detail::IntrospectiveIsProperty::value, bool> + has_property() { + return detail::ContainsProperty::value; + } + + template + typename detail::enable_if_t< + detail::IsRuntimePropertyWithData::value, PropertyT> + get_property() const { + static_assert(has_property(), + "Property list does not contain the requested property."); + return std::get(Storage); + } + + template + typename detail::enable_if_t< + detail::IsRuntimeDatalessProperty::value, PropertyT> + get_property() const { + static_assert(has_property(), + "Property list does not contain the requested property."); + return {}; + } + + template + static constexpr typename detail::enable_if_t< + detail::IsCompileTimeProperty::value, + typename detail::FindCompileTimePropertyValueType::type> + get_property() { + static_assert(has_property(), + "Property list does not contain the requested property."); + return {}; + } + +private: + using StorageT = typename detail::RuntimePropertyStorage::type; + + StorageT Storage; +}; + +#ifdef __cpp_deduction_guides +// Deduction guides +template +property_list(PropertyValueTs... props) + -> property_list::type>; +#endif + +template +using property_list_t = + property_list::type>; + +// Property list traits +template struct is_property_list : std::false_type {}; +template +struct is_property_list>> + : std::is_same>, + property_list_t> {}; + +#if __cplusplus > 201402L +template +inline constexpr bool is_property_list_v = + is_property_list::value; +#endif + +} // namespace oneapi +} // namespace ext +} // namespace sycl +} // __SYCL_INLINE_NAMESPACE(cl) diff --git a/sycl/include/sycl/ext/oneapi/property_list/property_utils.hpp b/sycl/include/sycl/ext/oneapi/property_list/property_utils.hpp new file mode 100644 index 0000000000000..e0ea06896b2e9 --- /dev/null +++ b/sycl/include/sycl/ext/oneapi/property_list/property_utils.hpp @@ -0,0 +1,233 @@ +//==-- property_utils.hpp --- SYCL extended property list common utilities -==// +// +// 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 +// +//===----------------------------------------------------------------------===// + +#pragma once + +#include + +#include + +__SYCL_INLINE_NAMESPACE(cl) { +namespace sycl { +namespace ext { +namespace oneapi { + +// Forward declaration +template struct property_value; + +namespace detail { + +//****************************************************************************** +// Misc +//****************************************************************************** + +// Checks if a type is a tuple. +template struct IsTuple : std::false_type {}; +template struct IsTuple> : std::true_type {}; + +// Gets the first type in a parameter pack of types. +template +using GetFirstType = typename std::tuple_element<0, std::tuple>::type; + +// Prepends a value to a tuple. +template struct PrependTuple {}; +template +struct PrependTuple> { + using type = std::tuple; +}; + +// Checks if a type T has a static value member variable. +template struct HasValue : std::false_type {}; +template +struct HasValue : std::true_type {}; + +// Checks that all types in a tuple have unique PropertyID. +template struct AllUnique {}; +template +struct AllUnique> : std::true_type {}; +template struct AllUnique> : std::true_type {}; +template +struct AllUnique> + : detail::conditional_t>, + std::false_type> {}; + +//****************************************************************************** +// Property identification +//****************************************************************************** + +// Checks if a type is a runtime property with data. +template struct IsRuntimePropertyWithData { + static constexpr bool value = + is_property::value && std::is_base_of::value; +}; + +// Checks if a type is a dataless runtime property. +template struct IsRuntimeDatalessProperty { + static constexpr bool value = + is_property::value && std::is_base_of::value; +}; + +// Checks if a type is a runtime property. +template struct IsRuntimeProperty { + static constexpr bool value = + is_property::value && + (std::is_base_of::value || + std::is_base_of::value); +}; + +// Checks if a type is either a runtime property (with or without data) or if +// it is a compile-time property (inside a property_value) +template struct IntrospectiveIsProperty : is_property {}; +template +struct IntrospectiveIsProperty> + : is_property {}; + +// Checks that a type is a compile-time property. value is true if either T is +// a non-runtime property or if it is a property_value containing a non-runtime +// property. +template struct IsCompileTimeProperty { + static constexpr bool value = + IntrospectiveIsProperty::value && !IsRuntimeProperty::value; +}; + +// Checks that all types in a tuple are valid properties. +template struct AllProperties {}; +template +struct AllProperties> : std::true_type {}; +template +struct AllProperties> + : detail::conditional_t::value, + AllProperties>, std::false_type> { +}; + +//****************************************************************************** +// Property type sorting +//****************************************************************************** + +// Splits a tuple into head and tail if ShouldSplit is true. If ShouldSplit is +// false the head will be void and the tail will be the full tuple. +template struct HeadSplit {}; +template +struct HeadSplit, true> { + using htype = T; + using ttype = std::tuple; +}; +template struct HeadSplit, false> { + using htype = void; + using ttype = std::tuple; +}; + +// Selects the one of two types that is not void. This assumes that at least one +// of the two template arguemnts is void. +template struct SelectNonVoid {}; +template struct SelectNonVoid { using type = LHS; }; +template struct SelectNonVoid { using type = RHS; }; + +// Merges two tuples by recursively extracting the type with the minimum +// PropertyID in the two tuples and prepending it to the merging of the +// remaining elements. +template struct Merge {}; +template struct Merge, std::tuple<>> { + using type = std::tuple; +}; +template struct Merge, std::tuple> { + using type = std::tuple; +}; +template +struct Merge, std::tuple> { + using l_head = GetFirstType; + using r_head = GetFirstType; + static constexpr bool left_has_min = l_head::PropertyID < r_head::PropertyID; + using l_split = HeadSplit, left_has_min>; + using r_split = HeadSplit, !left_has_min>; + using min = typename SelectNonVoid::type; + using merge_tails = + typename Merge::type; + using type = typename PrependTuple::type; +}; + +// Creates pairs of tuples with a single element from a tuple with N elements. +// Resulting tuple will have ceil(N/2) elements. +template struct CreateTuplePairs { + using type = typename std::tuple<>; +}; +template struct CreateTuplePairs { + using type = typename std::tuple, std::tuple<>>>; +}; +template +struct CreateTuplePairs { + using type = + typename PrependTuple, std::tuple>, + typename CreateTuplePairs::type>::type; +}; + +// Merges pairs of tuples and creates new pairs of the merged pairs. Let N be +// the number of pairs in the supplied tuple, then the resulting tuple will +// contain ceil(N/2) pairs of tuples. +template struct MergePairs { using type = std::tuple<>; }; +template +struct MergePairs< + std::tuple, std::tuple>, Rest...>> { + using merged = typename Merge, std::tuple>::type; + using type = std::tuple>>; +}; +template +struct MergePairs< + std::tuple, std::tuple>, + std::pair, std::tuple>, Rest...>> { + using lmerged = + typename Merge, std::tuple>::type; + using rmerged = + typename Merge, std::tuple>::type; + using type = typename PrependTuple< + std::pair, + typename MergePairs>::type>::type; +}; + +// Recursively merges all pairs of tuples until only a single pair of tuples +// is left, where the right element of the pair is an empty tuple. +template struct MergeAll {}; +template struct MergeAll> { + using type = std::tuple; +}; +template +struct MergeAll, std::tuple<>>>> { + using type = std::tuple; +}; +template struct MergeAll> { + using reduced = typename MergePairs>::type; + using type = typename MergeAll::type; +}; + +// Performs merge-sort on types with PropertyID. +template struct Sorted { + static_assert(detail::AllProperties>::value, + "Unrecognized property in property list."); + using split = typename CreateTuplePairs::type; + using type = typename MergeAll::type; +}; + +// Checks if the types in a tuple are sorted w.r.t. their PropertyID. +template struct IsSorted {}; +template +struct IsSorted> : std::true_type {}; +template struct IsSorted> : std::true_type {}; +template +struct IsSorted> + : detail::conditional_t>, std::false_type> { +}; + +} // namespace detail +} // namespace oneapi +} // namespace ext +} // namespace sycl +} // __SYCL_INLINE_NAMESPACE(cl) diff --git a/sycl/include/sycl/ext/oneapi/property_list/property_value.hpp b/sycl/include/sycl/ext/oneapi/property_list/property_value.hpp new file mode 100644 index 0000000000000..3194b60a8b044 --- /dev/null +++ b/sycl/include/sycl/ext/oneapi/property_list/property_value.hpp @@ -0,0 +1,106 @@ +//==------ property_value.hpp --- SYCL compile-time property values --------==// +// +// 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 +// +//===----------------------------------------------------------------------===// + +// HOW-TO: Add new compile-time property +// 1. Define property class with `value_t` that must be `property_value` with +// the first template argument being the property class itself. +// 2. Add a new enumerator to `sycl::ext::oneapi::detail::CompileTimePropKind` +// representing the new property. Increment +// `sycl::ext::oneapi::detail::CompileTimePropKind::CompileTimePropKindSize` +// 3. Specialize `sycl::ext::oneapi::detail::CompileTimePropertyToKind` for the +// new property class. The specialization should have a `value` member +// with the value equal to the enumerator added in 2. +// 4. Add an `inline constexpr` variable in the same namespace as the property. +// The variable should have the same type as `value_t` of the property class +// and should be named as the property class with `_v` appended, e.g. for a +// property `foo`, there should be a definition +// `inline constexpr foo::value_t foo_v`. +// 5. Specialize `sycl::is_property` and `sycl::is_property_of` for the +// property class. + +#pragma once + +#include +#include + +__SYCL_INLINE_NAMESPACE(cl) { +namespace sycl { +namespace ext { +namespace oneapi { +namespace detail { + +// List of all compile-time properties +enum CompileTimePropKind { + CompileTimePropKindSize = 0, +}; + +// This trait must be specialized for all compile-time properties and must have +// a unique constexpr CompileTimePropKind member named PropKind +template struct CompileTimePropertyToKind {}; + +// Get unique ID for compile-time property +template struct CompileTimePropertyID { + static constexpr int value = + static_cast(CompileTimePropertyToKind::PropKind) + + static_cast(PropWithDataKind::PropWithDataKindSize) + + static_cast(DataLessPropKind::DataLessPropKindSize); +}; + +// Base class for property values with a single type value. +struct SingleTypePropertyValueBase {}; + +// Base class for properties with 0 or more than 1 values. +struct EmptyPropertyValueBase {}; + +// Base class for property values with a single non-type value +template struct SingleNontypePropertyValueBase { + static constexpr auto value = T::value; +}; + +// Helper class for property values with a single value +template +struct SinglePropertyValue + : public detail::conditional_t::value, + SingleNontypePropertyValueBase, + SingleTypePropertyValueBase> { + using value_t = T; +}; + +} // namespace detail + +template +struct property_value + : public detail::IdentifyablePropertyBase< + detail::CompileTimePropertyID::value>, + public detail::conditional_t< + sizeof...(Ts) == 0 && !std::is_same::value, + detail::SinglePropertyValue, detail::EmptyPropertyValueBase> { +}; + +template +constexpr detail::enable_if_t::value && + !detail::IsRuntimeProperty::value, + bool> +operator==(const property_value &LHS, + const property_value &RHS) { + return (std::is_same::value && ...); +} + +template +constexpr detail::enable_if_t::value && + !detail::IsRuntimeProperty::value, + bool> +operator!=(const property_value &LHS, + const property_value &RHS) { + return (!std::is_same::value || ...); +} + +} // namespace oneapi +} // namespace ext +} // namespace sycl +} // __SYCL_INLINE_NAMESPACE(cl) diff --git a/sycl/test/extensions/property_list/mock_compile_time_properties.hpp b/sycl/test/extensions/property_list/mock_compile_time_properties.hpp new file mode 100644 index 0000000000000..dd31e6b3e1f48 --- /dev/null +++ b/sycl/test/extensions/property_list/mock_compile_time_properties.hpp @@ -0,0 +1,68 @@ +//==--- mock_compile_time_properties.hpp - Mock compile-time properties ---==// +// +// 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 +// +//===----------------------------------------------------------------------===// + +// Since we do not currently have any compile-time properties this header cheats +// a little by defining its own compile-time properties. These are intended for +// testing and users should not replicate this behavior. + +#pragma once + +namespace sycl { +namespace ext { +namespace oneapi { + +struct bar { + using value_t = property_value; +}; + +struct baz { + template + using value_t = property_value>; +}; + +struct boo { + template using value_t = property_value; +}; + +namespace detail { +template <> struct CompileTimePropertyToKind { + static constexpr CompileTimePropKind PropKind = + static_cast( + CompileTimePropKind::CompileTimePropKindSize + 0); +}; +template <> struct CompileTimePropertyToKind { + static constexpr CompileTimePropKind PropKind = + static_cast( + CompileTimePropKind::CompileTimePropKindSize + 1); +}; +template <> struct CompileTimePropertyToKind { + static constexpr CompileTimePropKind PropKind = + static_cast( + CompileTimePropKind::CompileTimePropKindSize + 2); +}; +} // namespace detail + +inline constexpr bar::value_t bar_v; +template inline constexpr baz::value_t baz_v; +template inline constexpr boo::value_t boo_v; + +} // namespace oneapi +} // namespace ext + +template <> struct is_property : std::true_type {}; +template <> struct is_property : std::true_type {}; +template <> struct is_property : 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 {}; + +} // namespace sycl diff --git a/sycl/test/extensions/property_list/property_list_ctor_negative.cpp b/sycl/test/extensions/property_list/property_list_ctor_negative.cpp new file mode 100644 index 0000000000000..a85724d453a1b --- /dev/null +++ b/sycl/test/extensions/property_list/property_list_ctor_negative.cpp @@ -0,0 +1,31 @@ +// RUN: not %clangxx -fsycl -fsycl-targets=%sycl_triple %s -o %t.bin -DTEST_CASE=1 2> %t_1.err +// RUN: FileCheck --check-prefix=CHECK-ERROR-1 < %t_1.err %s +// RUN: not %clangxx -fsycl -fsycl-targets=%sycl_triple %s -o %t.bin -DTEST_CASE=2 2> %t_2.err +// RUN: FileCheck --check-prefix=CHECK-ERROR-2 < %t_2.err %s +// RUN: not %clangxx -fsycl -fsycl-targets=%sycl_triple %s -o %t.bin -DTEST_CASE=3 2> %t_3.err +// RUN: FileCheck --check-prefix=CHECK-ERROR-3 < %t_3.err %s +// RUN: not %clangxx -fsycl -fsycl-targets=%sycl_triple %s -o %t.bin -DTEST_CASE=4 2> %t_4.err +// RUN: FileCheck --check-prefix=CHECK-ERROR-4 < %t_4.err %s + +#include + +#include "mock_compile_time_properties.hpp" + +int main() { +#if(TEST_CASE == 1) + auto InvalidPropertyList = sycl::ext::oneapi::property_list(1); + // CHECK-ERROR-1: Unrecognized property in property list. +#elif(TEST_CASE == 2) + auto InvalidPropertyList = + sycl::ext::oneapi::property_list(sycl::property::no_init{}, true); + // CHECK-ERROR-2: Unrecognized property in property list. +#elif(TEST_CASE == 3) + auto InvalidPropertyList = sycl::ext::oneapi::property_list( + sycl::property::no_init{}, sycl::property::no_init{}); + // CHECK-ERROR-3: Duplicate properties in property list. +#elif(TEST_CASE == 4) + auto InvalidPropertyList = sycl::ext::oneapi::property_list( + sycl::ext::oneapi::bar_v, sycl::ext::oneapi::bar_v); + // CHECK-ERROR-4: Duplicate properties in property list. +#endif +} diff --git a/sycl/test/extensions/property_list/property_list_device_copyable.cpp b/sycl/test/extensions/property_list/property_list_device_copyable.cpp new file mode 100644 index 0000000000000..d334806baee78 --- /dev/null +++ b/sycl/test/extensions/property_list/property_list_device_copyable.cpp @@ -0,0 +1,55 @@ +// RUN: %clangxx -fsycl -fsycl-targets=%sycl_triple %s -o %t.out +// RUN: %t.out + +#include + +#include "mock_compile_time_properties.hpp" + +class TestClass1 {}; +class TestClass2 {}; + +int main() { + // Check only compile-time properties are device-copyable + using P1 = sycl::ext::oneapi::property_list_t< + sycl::ext::oneapi::baz::value_t<1>, + sycl::ext::oneapi::boo::value_t, + sycl::ext::oneapi::bar::value_t>; + + static_assert(sycl::is_device_copyable_v>); + static_assert(sycl::is_device_copyable_v< + sycl::ext::oneapi::boo::value_t>); + static_assert(sycl::is_device_copyable_v); + static_assert(sycl::is_device_copyable_v); + + // Check property list with non-device-copyable property + using P2 = + sycl::ext::oneapi::property_list_t; + static_assert( + !sycl::is_device_copyable_v); + static_assert(!sycl::is_device_copyable_v); + + // Check property list with device-copyable compile-time and runtime + // properties + using P3 = + sycl::ext::oneapi::property_list_t, + sycl::property::image::use_host_ptr>; + static_assert( + sycl::is_device_copyable_v); + static_assert(sycl::is_device_copyable_v); + + // Check that device-copyable property list can indeed be used in a kernel + const auto PropertyList = sycl::ext::oneapi::property_list( + sycl::ext::oneapi::baz_v<1>, sycl::property::image::use_host_ptr{}); + + sycl::queue Q; + Q.submit([&](sycl::handler &CGH) { + CGH.single_task([=]() { + decltype(PropertyList)::has_property(); + decltype(PropertyList)::has_property< + sycl::property::image::use_host_ptr>(); + PropertyList.get_property(); + PropertyList.get_property(); + }); + }); +} diff --git a/sycl/test/extensions/property_list/property_list_equality.cpp b/sycl/test/extensions/property_list/property_list_equality.cpp new file mode 100644 index 0000000000000..9fd407f896ce1 --- /dev/null +++ b/sycl/test/extensions/property_list/property_list_equality.cpp @@ -0,0 +1,16 @@ +// RUN: %clangxx -fsycl -fsycl-targets=%sycl_triple %s -o %t.out +// RUN: %t.out + +#include + +#include "mock_compile_time_properties.hpp" + +int main() { + using P1 = + sycl::ext::oneapi::property_list_t, + sycl::ext::oneapi::bar::value_t>; + using P2 = + sycl::ext::oneapi::property_list_t>; + static_assert(std::is_same::value); +} diff --git a/sycl/test/extensions/property_list/property_list_get_property.cpp b/sycl/test/extensions/property_list/property_list_get_property.cpp new file mode 100644 index 0000000000000..2303231917afa --- /dev/null +++ b/sycl/test/extensions/property_list/property_list_get_property.cpp @@ -0,0 +1,35 @@ +// RUN: %clangxx -fsycl -fsycl-targets=%sycl_triple %s -o %t.out +// RUN: %t.out + +#include + +#include "mock_compile_time_properties.hpp" + +int main() { + using P1 = + sycl::ext::oneapi::property_list_t, + sycl::ext::oneapi::bar::value_t>; + // Check that get_property of compile-time properties are the same as _v + static_assert(P1::get_property() == + sycl::ext::oneapi::baz_v<1>); + static_assert(P1::get_property() == + sycl::ext::oneapi::bar_v); + + // Check value on returned property + static_assert(P1::get_property().value == 1); + + // Check runtime and compile-time properties on property-list object + sycl::queue Q; + auto PropertyList = sycl::ext::oneapi::property_list( + sycl::ext::oneapi::baz_v<1>, sycl::ext::oneapi::bar_v, + sycl::property::no_init{}, + sycl::property::buffer::context_bound{Q.get_context()}); + static_assert( + decltype(PropertyList)::get_property() == + sycl::ext::oneapi::baz_v<1>); + static_assert( + decltype(PropertyList)::get_property() == + sycl::ext::oneapi::bar_v); + assert(PropertyList.get_property() + .get_context() == Q.get_context()); +} diff --git a/sycl/test/extensions/property_list/property_list_get_property_negative.cpp b/sycl/test/extensions/property_list/property_list_get_property_negative.cpp new file mode 100644 index 0000000000000..aa96c14105c73 --- /dev/null +++ b/sycl/test/extensions/property_list/property_list_get_property_negative.cpp @@ -0,0 +1,46 @@ +// RUN: not %clangxx -fsycl -fsycl-targets=%sycl_triple %s -o %t.bin -DTEST_CASE=1 2> %t_1.err +// RUN: FileCheck --check-prefix=CHECK-ERROR-1 < %t_1.err %s +// RUN: not %clangxx -fsycl -fsycl-targets=%sycl_triple %s -o %t.bin -DTEST_CASE=2 2> %t_2.err +// RUN: FileCheck --check-prefix=CHECK-ERROR-2 < %t_2.err %s +// RUN: not %clangxx -fsycl -fsycl-targets=%sycl_triple %s -o %t.bin -DTEST_CASE=3 2> %t_3.err +// RUN: FileCheck --check-prefix=CHECK-ERROR-3 < %t_3.err %s +// RUN: not %clangxx -fsycl -fsycl-targets=%sycl_triple %s -o %t.bin -DTEST_CASE=4 2> %t_4.err +// RUN: FileCheck --check-prefix=CHECK-ERROR-4 < %t_4.err %s +// RUN: not %clangxx -fsycl -fsycl-targets=%sycl_triple %s -o %t.bin -DTEST_CASE=5 2> %t_5.err +// RUN: FileCheck --check-prefix=CHECK-ERROR-5 < %t_5.err %s +// RUN: not %clangxx -fsycl -fsycl-targets=%sycl_triple %s -o %t.bin -DTEST_CASE=6 2> %t_6.err +// RUN: FileCheck --check-prefix=CHECK-ERROR-6 < %t_6.err %s + +#include + +#include "mock_compile_time_properties.hpp" + +int main() { + auto EmptyPropertyList = sycl::ext::oneapi::property_list(); +#if(TEST_CASE == 1) + decltype(EmptyPropertyList)::get_property(); + // CHECK-ERROR-1: Property list does not contain the requested property. +#elif(TEST_CASE == 2) + EmptyPropertyList.get_property(); + // CHECK-ERROR-2: Property list does not contain the requested property. +#elif(TEST_CASE == 3) + EmptyPropertyList.get_property(); + // CHECK-ERROR-3: Property list does not contain the requested property. +#endif + + sycl::queue Q; + auto PopulatedPropertyList = sycl::ext::oneapi::property_list( + sycl::property::image::context_bound{Q.get_context()}, + sycl::ext::oneapi::bar_v, + sycl::property::context::cuda::use_primary_context{}); +#if(TEST_CASE == 4) + decltype(PopulatedPropertyList)::get_property(); + // CHECK-ERROR-4: Property list does not contain the requested property. +#elif(TEST_CASE == 5) + PopulatedPropertyList.get_property(); + // CHECK-ERROR-5: Property list does not contain the requested property. +#elif(TEST_CASE == 6) + PopulatedPropertyList.get_property(); + // CHECK-ERROR-6: Property list does not contain the requested property. +#endif +} diff --git a/sycl/test/extensions/property_list/property_list_has_property.cpp b/sycl/test/extensions/property_list/property_list_has_property.cpp new file mode 100644 index 0000000000000..c93d41ea52f0b --- /dev/null +++ b/sycl/test/extensions/property_list/property_list_has_property.cpp @@ -0,0 +1,39 @@ +// RUN: %clangxx -fsycl -fsycl-targets=%sycl_triple %s -o %t.out +// RUN: %t.out + +#include + +#include "mock_compile_time_properties.hpp" + +int main() { + // Check has_property for compile-time properties + using P1 = + sycl::ext::oneapi::property_list_t, + sycl::ext::oneapi::bar::value_t>; + static_assert(P1::has_property()); + static_assert(P1::has_property()); + static_assert(!P1::has_property()); + static_assert(!P1::has_property()); + static_assert(!P1::has_property()); + + // Check has_property for runtime properties + using P2 = + sycl::ext::oneapi::property_list_t; + static_assert(!P2::has_property()); + static_assert(!P2::has_property()); + static_assert(!P2::has_property()); + static_assert(P2::has_property()); + static_assert(P2::has_property()); + + // Check has_property for a mix properties + using P3 = + sycl::ext::oneapi::property_list_t, + sycl::property::image::context_bound>; + static_assert(!P3::has_property()); + static_assert(P3::has_property()); + static_assert(!P3::has_property()); + static_assert(P3::has_property()); + static_assert(P3::has_property()); +} diff --git a/sycl/test/extensions/property_list/property_list_is_property_list.cpp b/sycl/test/extensions/property_list/property_list_is_property_list.cpp new file mode 100644 index 0000000000000..dd20d7596709f --- /dev/null +++ b/sycl/test/extensions/property_list/property_list_is_property_list.cpp @@ -0,0 +1,67 @@ +// RUN: %clangxx -fsycl -fsycl-targets=%sycl_triple %s -o %t.out +// RUN: %t.out + +#include + +#include "mock_compile_time_properties.hpp" + +int main() { + // Check is_property_list for empty property list + using EmptyP = sycl::ext::oneapi::property_list_t<>; + static_assert(sycl::ext::oneapi::is_property_list::value); + static_assert(sycl::ext::oneapi::is_property_list_v); + + // Check is_property_list for compile-time properties + using P1 = + sycl::ext::oneapi::property_list_t, + sycl::ext::oneapi::bar::value_t>; + static_assert(sycl::ext::oneapi::is_property_list::value); + static_assert(sycl::ext::oneapi::is_property_list_v); + + // Check is_property_list for runtime properties + using P2 = + sycl::ext::oneapi::property_list_t; + static_assert(sycl::ext::oneapi::is_property_list::value); + static_assert(sycl::ext::oneapi::is_property_list_v); + + // Check is_property_list for a mix properties + using P3 = + sycl::ext::oneapi::property_list_t, + sycl::property::image::context_bound>; + static_assert(sycl::ext::oneapi::is_property_list::value); + static_assert(sycl::ext::oneapi::is_property_list_v); + + // Check is_property_list for compile-time properties on object + auto PropertyList1 = sycl::ext::oneapi::property_list( + sycl::ext::oneapi::baz_v<1>, sycl::ext::oneapi::bar_v); + static_assert( + sycl::ext::oneapi::is_property_list::value); + static_assert(sycl::ext::oneapi::is_property_list_v); + + // Check is_property_list for runtime properties on object + sycl::queue Q; + auto PropertyList2 = sycl::ext::oneapi::property_list( + sycl::property::buffer::use_host_ptr{}, + sycl::property::image::context_bound{Q.get_context()}); + static_assert( + sycl::ext::oneapi::is_property_list::value); + static_assert(sycl::ext::oneapi::is_property_list_v); + + // Check is_property_list for a mix properties on object + auto PropertyList3 = sycl::ext::oneapi::property_list( + sycl::property::buffer::use_host_ptr{}, sycl::ext::oneapi::baz_v<1>, + sycl::property::image::context_bound{Q.get_context()}); + static_assert( + sycl::ext::oneapi::is_property_list::value); + static_assert(sycl::ext::oneapi::is_property_list_v); + + // Check is_property_list on types that are not valid + // sycl::ext::oneapi::property_list. + static_assert(!sycl::ext::oneapi::is_property_list::value); + static_assert(!sycl::ext::oneapi::is_property_list_v); + static_assert( + !sycl::ext::oneapi::is_property_list::value); + static_assert(!sycl::ext::oneapi::is_property_list_v); +} From 861af21b9ca7cc481110a7137261a01e80a24b2c Mon Sep 17 00:00:00 2001 From: Steffen Larsen Date: Wed, 17 Nov 2021 18:23:17 +0300 Subject: [PATCH 02/24] Fix formatting Signed-off-by: Steffen Larsen --- sycl/include/CL/sycl/detail/property_helper.hpp | 2 +- .../sycl/ext/oneapi/property_list/property_value.hpp | 3 +-- .../property_list/property_list_ctor_negative.cpp | 8 ++++---- .../property_list_get_property_negative.cpp | 12 ++++++------ 4 files changed, 12 insertions(+), 13 deletions(-) diff --git a/sycl/include/CL/sycl/detail/property_helper.hpp b/sycl/include/CL/sycl/detail/property_helper.hpp index e870249f17985..9c31e5f485cb9 100644 --- a/sycl/include/CL/sycl/detail/property_helper.hpp +++ b/sycl/include/CL/sycl/detail/property_helper.hpp @@ -50,7 +50,7 @@ enum PropWithDataKind { }; // Base class for all properties to expose a unique ID. -template class IdentifyablePropertyBase { +template class IdentifyablePropertyBase { public: static constexpr int PropertyID = ID; }; diff --git a/sycl/include/sycl/ext/oneapi/property_list/property_value.hpp b/sycl/include/sycl/ext/oneapi/property_list/property_value.hpp index 3194b60a8b044..25d26d5488b4c 100644 --- a/sycl/include/sycl/ext/oneapi/property_list/property_value.hpp +++ b/sycl/include/sycl/ext/oneapi/property_list/property_value.hpp @@ -79,8 +79,7 @@ struct property_value detail::CompileTimePropertyID::value>, public detail::conditional_t< sizeof...(Ts) == 0 && !std::is_same::value, - detail::SinglePropertyValue, detail::EmptyPropertyValueBase> { -}; + detail::SinglePropertyValue, detail::EmptyPropertyValueBase> {}; template constexpr detail::enable_if_t::value && diff --git a/sycl/test/extensions/property_list/property_list_ctor_negative.cpp b/sycl/test/extensions/property_list/property_list_ctor_negative.cpp index a85724d453a1b..372ff28c9d38e 100644 --- a/sycl/test/extensions/property_list/property_list_ctor_negative.cpp +++ b/sycl/test/extensions/property_list/property_list_ctor_negative.cpp @@ -12,18 +12,18 @@ #include "mock_compile_time_properties.hpp" int main() { -#if(TEST_CASE == 1) +#if (TEST_CASE == 1) auto InvalidPropertyList = sycl::ext::oneapi::property_list(1); // CHECK-ERROR-1: Unrecognized property in property list. -#elif(TEST_CASE == 2) +#elif (TEST_CASE == 2) auto InvalidPropertyList = sycl::ext::oneapi::property_list(sycl::property::no_init{}, true); // CHECK-ERROR-2: Unrecognized property in property list. -#elif(TEST_CASE == 3) +#elif (TEST_CASE == 3) auto InvalidPropertyList = sycl::ext::oneapi::property_list( sycl::property::no_init{}, sycl::property::no_init{}); // CHECK-ERROR-3: Duplicate properties in property list. -#elif(TEST_CASE == 4) +#elif (TEST_CASE == 4) auto InvalidPropertyList = sycl::ext::oneapi::property_list( sycl::ext::oneapi::bar_v, sycl::ext::oneapi::bar_v); // CHECK-ERROR-4: Duplicate properties in property list. diff --git a/sycl/test/extensions/property_list/property_list_get_property_negative.cpp b/sycl/test/extensions/property_list/property_list_get_property_negative.cpp index aa96c14105c73..91c52ffac10e1 100644 --- a/sycl/test/extensions/property_list/property_list_get_property_negative.cpp +++ b/sycl/test/extensions/property_list/property_list_get_property_negative.cpp @@ -17,13 +17,13 @@ int main() { auto EmptyPropertyList = sycl::ext::oneapi::property_list(); -#if(TEST_CASE == 1) +#if (TEST_CASE == 1) decltype(EmptyPropertyList)::get_property(); // CHECK-ERROR-1: Property list does not contain the requested property. -#elif(TEST_CASE == 2) +#elif (TEST_CASE == 2) EmptyPropertyList.get_property(); // CHECK-ERROR-2: Property list does not contain the requested property. -#elif(TEST_CASE == 3) +#elif (TEST_CASE == 3) EmptyPropertyList.get_property(); // CHECK-ERROR-3: Property list does not contain the requested property. #endif @@ -33,13 +33,13 @@ int main() { sycl::property::image::context_bound{Q.get_context()}, sycl::ext::oneapi::bar_v, sycl::property::context::cuda::use_primary_context{}); -#if(TEST_CASE == 4) +#if (TEST_CASE == 4) decltype(PopulatedPropertyList)::get_property(); // CHECK-ERROR-4: Property list does not contain the requested property. -#elif(TEST_CASE == 5) +#elif (TEST_CASE == 5) PopulatedPropertyList.get_property(); // CHECK-ERROR-5: Property list does not contain the requested property. -#elif(TEST_CASE == 6) +#elif (TEST_CASE == 6) PopulatedPropertyList.get_property(); // CHECK-ERROR-6: Property list does not contain the requested property. #endif From 27a9e26c2cf6140079b55d2127db1ca6ca3a9d2f Mon Sep 17 00:00:00 2001 From: Steffen Larsen Date: Wed, 17 Nov 2021 18:37:31 +0300 Subject: [PATCH 03/24] Fix formatting but clang-format does not agree Signed-off-by: Steffen Larsen --- .../property_list/property_list_device_copyable.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sycl/test/extensions/property_list/property_list_device_copyable.cpp b/sycl/test/extensions/property_list/property_list_device_copyable.cpp index d334806baee78..fcee70036a221 100644 --- a/sycl/test/extensions/property_list/property_list_device_copyable.cpp +++ b/sycl/test/extensions/property_list/property_list_device_copyable.cpp @@ -46,8 +46,8 @@ int main() { Q.submit([&](sycl::handler &CGH) { CGH.single_task([=]() { decltype(PropertyList)::has_property(); - decltype(PropertyList)::has_property< - sycl::property::image::use_host_ptr>(); + decltype( + PropertyList)::has_property(); PropertyList.get_property(); PropertyList.get_property(); }); From c61d569486b2aaae74cd9d3d3a159ec2f3f452ba Mon Sep 17 00:00:00 2001 From: Steffen Larsen Date: Wed, 17 Nov 2021 21:32:55 +0300 Subject: [PATCH 04/24] Mark test XFAIL on CUDA Signed-off-by: Steffen Larsen --- .../extensions/property_list/property_list_device_copyable.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/sycl/test/extensions/property_list/property_list_device_copyable.cpp b/sycl/test/extensions/property_list/property_list_device_copyable.cpp index fcee70036a221..d5cfe7db66843 100644 --- a/sycl/test/extensions/property_list/property_list_device_copyable.cpp +++ b/sycl/test/extensions/property_list/property_list_device_copyable.cpp @@ -1,6 +1,9 @@ // RUN: %clangxx -fsycl -fsycl-targets=%sycl_triple %s -o %t.out // RUN: %t.out +// CUDA backend currently generates invalid binaries for this +// XFAIL: cuda + #include #include "mock_compile_time_properties.hpp" From 1f283f99f54f5dfc3b95546f606894b9a02c18e1 Mon Sep 17 00:00:00 2001 From: Steffen Larsen Date: Wed, 17 Nov 2021 22:03:58 +0300 Subject: [PATCH 05/24] Attempt to fix MSVC overload issue Signed-off-by: Steffen Larsen --- .../sycl/ext/oneapi/property_list/property_list.hpp | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/sycl/include/sycl/ext/oneapi/property_list/property_list.hpp b/sycl/include/sycl/ext/oneapi/property_list/property_list.hpp index 5c8a1bf587df5..efb3596e5ba38 100644 --- a/sycl/include/sycl/ext/oneapi/property_list/property_list.hpp +++ b/sycl/include/sycl/ext/oneapi/property_list/property_list.hpp @@ -149,14 +149,14 @@ template class property_list { } template - static constexpr typename detail::enable_if_t< - detail::IsCompileTimeProperty::value, - typename detail::FindCompileTimePropertyValueType::type> - get_property() { + static constexpr auto get_property( + typename std::enable_if_t::value> + * = 0) { static_assert(has_property(), "Property list does not contain the requested property."); - return {}; + return + typename detail::FindCompileTimePropertyValueType::type{}; } private: From f565f5cafc8dc46c41fbd018f354296610d9e716 Mon Sep 17 00:00:00 2001 From: Steffen Larsen Date: Thu, 18 Nov 2021 11:54:14 +0300 Subject: [PATCH 06/24] Propagate is_device_copyable on property_list Signed-off-by: Steffen Larsen --- .../sycl/ext/oneapi/property_list/property_list.hpp | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/sycl/include/sycl/ext/oneapi/property_list/property_list.hpp b/sycl/include/sycl/ext/oneapi/property_list/property_list.hpp index efb3596e5ba38..25a693284636c 100644 --- a/sycl/include/sycl/ext/oneapi/property_list/property_list.hpp +++ b/sycl/include/sycl/ext/oneapi/property_list/property_list.hpp @@ -9,10 +9,12 @@ #pragma once #include +#include #include #include #include +#include __SYCL_INLINE_NAMESPACE(cl) { namespace sycl { @@ -191,5 +193,14 @@ inline constexpr bool is_property_list_v = } // namespace oneapi } // namespace ext + +// If property_list is not trivially copyable, allow properties to propagate +// is_device_copyable +template +struct is_device_copyable, + std::enable_if_t>::value>> + : is_device_copyable {}; + } // namespace sycl } // __SYCL_INLINE_NAMESPACE(cl) From 9601c4ccf071017fcb36c3906aa586e9a339ee81 Mon Sep 17 00:00:00 2001 From: Steffen Larsen Date: Thu, 18 Nov 2021 13:37:01 +0300 Subject: [PATCH 07/24] Propagate is_device_copyable onto const Signed-off-by: Steffen Larsen --- sycl/include/CL/sycl/types.hpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/sycl/include/CL/sycl/types.hpp b/sycl/include/CL/sycl/types.hpp index 5ec1c9325c79a..7f56a66b52e31 100644 --- a/sycl/include/CL/sycl/types.hpp +++ b/sycl/include/CL/sycl/types.hpp @@ -2399,6 +2399,12 @@ struct is_device_copyable< T, std::enable_if_t::value>> : std::true_type {}; +// Specializations of device copyable should propagate onto constants. +template +struct is_device_copyable< + const T, std::enable_if_t::value>> + : is_device_copyable {}; + #if __cplusplus >= 201703L template inline constexpr bool is_device_copyable_v = is_device_copyable::value; From 17fe53cb65006e627283d7d25eaadaaacb93ac8c Mon Sep 17 00:00:00 2001 From: Steffen Larsen Date: Thu, 2 Dec 2021 16:44:29 +0300 Subject: [PATCH 08/24] Disallow SYCL 2020 properties and add runtime properties Runtime properties for the new property lists need to be seperately defined from the ones defined in SYCL 2020. These changes remove the support for SYCL 2020 properties in the compile-time property_list and adds the notion of runtime properties as a separate system. Signed-off-by: Steffen Larsen --- .../CL/sycl/detail/property_helper.hpp | 16 +- .../ext/oneapi/property_list/properties.hpp | 167 ++++++++++++++++++ .../oneapi/property_list/property_list.hpp | 22 +-- .../oneapi/property_list/property_utils.hpp | 62 +++---- .../oneapi/property_list/property_value.hpp | 59 ++----- .../mock_compile_time_properties.hpp | 68 +++++-- .../property_list_ctor_negative.cpp | 4 +- .../property_list_device_copyable.cpp | 20 +-- .../property_list_get_property.cpp | 10 +- .../property_list_get_property_negative.cpp | 24 +-- .../property_list_has_property.cpp | 22 ++- .../property_list_is_property_list.cpp | 15 +- 12 files changed, 310 insertions(+), 179 deletions(-) create mode 100644 sycl/include/sycl/ext/oneapi/property_list/properties.hpp diff --git a/sycl/include/CL/sycl/detail/property_helper.hpp b/sycl/include/CL/sycl/detail/property_helper.hpp index 9c31e5f485cb9..d87e03c53167d 100644 --- a/sycl/include/CL/sycl/detail/property_helper.hpp +++ b/sycl/include/CL/sycl/detail/property_helper.hpp @@ -49,12 +49,6 @@ enum PropWithDataKind { PropWithDataKindSize = 5 }; -// Base class for all properties to expose a unique ID. -template class IdentifyablePropertyBase { -public: - static constexpr int PropertyID = ID; -}; - // Base class for dataless properties, needed to check that the type of an // object passed to the property_list is a property. class DataLessPropertyBase {}; @@ -62,9 +56,7 @@ class DataLessPropertyBase {}; // Helper class for the dataless properties. Every such property is supposed // to inherit from it. The ID template parameter should be one from // DataLessPropKind. -template -class DataLessProperty : DataLessPropertyBase, - public IdentifyablePropertyBase { +template class DataLessProperty : DataLessPropertyBase { public: static constexpr int getKind() { return ID; } }; @@ -85,11 +77,7 @@ class PropertyWithDataBase { // Helper class for the properties with data. Every such property is supposed // to inherit from it. The ID template parameter should be one from // PropWithDataKind. -template -class PropertyWithData - : public PropertyWithDataBase, - public IdentifyablePropertyBase< - ID + static_cast(DataLessPropKind::DataLessPropKindSize)> { +template class PropertyWithData : public PropertyWithDataBase { public: PropertyWithData() : PropertyWithDataBase(ID) {} static int getKind() { return ID; } diff --git a/sycl/include/sycl/ext/oneapi/property_list/properties.hpp b/sycl/include/sycl/ext/oneapi/property_list/properties.hpp new file mode 100644 index 0000000000000..4a0163eed19d3 --- /dev/null +++ b/sycl/include/sycl/ext/oneapi/property_list/properties.hpp @@ -0,0 +1,167 @@ +//==---------- properties.hpp --- SYCL extension property tooling ----------==// +// +// 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 +// +//===----------------------------------------------------------------------===// + +// HOW-TO: Add new compile-time property +// 1. Add a new enumerator to `sycl::ext::oneapi::detail::PropKind` +// representing the new property. Increment +// `sycl::ext::oneapi::detail::PropKind::PropKindSize` +// 2. Define property class with `value_t` that must be `property_value` with +// the first template argument being the property class itself. +// 3. Add an `inline constexpr` variable in the same namespace as the property. +// The variable should have the same type as `value_t` of the property class +// and should be named as the property class with `_v` appended, e.g. for a +// property `foo`, there should be a definition +// `inline constexpr foo::value_t foo_v`. +// 4. Specialize `sycl::ext::oneapi::detail::PropertyToKind` for the new +// property class. The specialization should have a `Kind` member with the +// value equal to the enumerator added in 1. +// 5. Specialize `sycl::ext::oneapi::detail::IsCompileTimeProperty` for the new +// property class. This specialization should derive from `std::true_type`. +// 6. Specialize `sycl::is_property` and `sycl::is_property_of` for the +// property class. +/******************************** EXAMPLE ************************************** +---------- sycl/include/sycl/ext/oneapi/property_list/properties.hpp ----------- +// (1.) +enum PropKind : uint32_t { + ... + Bar, + PropKindSize = N + 1, // N was the previous value +}; +---------------------- path/to/new/property/file.hpp --------------------------- +namespace sycl { +namespace ext { +namespace oneapi { + +// (2.) +struct bar { + using value_t = property_value; +}; + +// (3.) +inline constexpr bar::value_t bar_v; + +namespace detail { + +// (4.) +template <> struct PropertyToKind { + static constexpr PropKind Kind = PropKind::Bar; +}; + +// (5.) +template <> struct IsCompileTimeProperty : std::true_type {}; + +} // namespace detail +} // namespace oneapi +} // namespace ext + +// (6.) +template <> struct is_property : std::true_type {}; +// Replace SYCL_OBJ with the SYCL object to support the property. +template <> struct is_property_of + : std::true_type {}; + +} // namespace sycl +*******************************************************************************/ + +// HOW-TO: Add new runtime property +// 1. Add a new enumerator to `sycl::ext::oneapi::detail::PropKind` +// representing the new property. Increment +// `sycl::ext::oneapi::detail::PropKind::PropKindSize` +// 2. Define property class. +// 3. Overload the `==` and `!=` operators for the new property class. The +// comparison should compare all data members of the property class. +// 4. Specialize `sycl::ext::oneapi::detail::PropertyToKind` for the new +// property class. The specialization should have a `Kind` member with the +// value equal to the enumerator added in 1. +// 5. Specialize `sycl::ext::oneapi::detail::IsRuntimeProperty` for the new +// property class. This specialization should derive from `std::true_type`. +// 6. Specialize `sycl::is_property` and `sycl::is_property_of` for the +// property class. +/******************************* EXAMPLE *************************************** +---------- sycl/include/sycl/ext/oneapi/property_list/properties.hpp ----------- +// (1.) +enum PropKind : uint32_t { + ... + Foo, + PropKindSize = N + 1, // N was the previous value +}; +---------------------- path/to/new/property/file.hpp --------------------------- +namespace sycl { +namespace ext { +namespace oneapi { + +// (2.) +struct foo { + foo(int v) : value(v) {} + int value; +}; + +// (3.) +inline bool operator==(const foo &lhs, const foo &rhs) { + return lhs.value == rhs.value; +} +inline bool operator!=(const foo &lhs, const foo &rhs) { + return !(lhs == rhs); +} + +namespace detail { + +// (4.) +template <> struct PropertyToKind { + static constexpr PropKind Kind = PropKind::Foo; +}; + +// (5.) +template <> struct IsRuntimeProperty : std::true_type {}; +} // namespace detail +} // namespace oneapi +} // namespace ext + +// (6.) +template <> struct is_property : std::true_type {}; +// Replace SYCL_OBJ with the SYCL object to support the property. +template <> struct is_property_of + : std::true_type {}; + +} // namespace sycl +*******************************************************************************/ + +#pragma once + +__SYCL_INLINE_NAMESPACE(cl) { +namespace sycl { +namespace ext { +namespace oneapi { +namespace detail { + +// List of all properties. +enum PropKind : uint32_t { + PropKindSize = 0, +}; + +// This trait must be specialized for all properties and must have a unique +// constexpr PropKind member named Kind. +template struct PropertyToKind {}; + +// Get unique ID for property. +template struct PropertyID { + static constexpr int value = + static_cast(PropertyToKind::Kind); +}; + +// Trait for identifying runtime properties. +template struct IsRuntimeProperty : std::false_type {}; + +// Trait for identifying compile-time properties. +template struct IsCompileTimeProperty : std::false_type {}; + +} // namespace detail +} // namespace oneapi +} // namespace ext +} // namespace sycl +} // __SYCL_INLINE_NAMESPACE(cl) diff --git a/sycl/include/sycl/ext/oneapi/property_list/property_list.hpp b/sycl/include/sycl/ext/oneapi/property_list/property_list.hpp index 25a693284636c..c095570c7b041 100644 --- a/sycl/include/sycl/ext/oneapi/property_list/property_list.hpp +++ b/sycl/include/sycl/ext/oneapi/property_list/property_list.hpp @@ -10,6 +10,7 @@ #include #include +#include #include #include @@ -64,7 +65,7 @@ template struct RuntimePropertyStorage> { }; template struct RuntimePropertyStorage> - : detail::conditional_t::value, + : detail::conditional_t::value, PrependTuple>::type>, RuntimePropertyStorage>> {}; @@ -112,7 +113,7 @@ struct ExtractProperties> { template class property_list { static_assert(detail::IsTuple::value, "Properties must be in a tuple."); - static_assert(detail::AllProperties::value, + static_assert(detail::AllPropertyValues::value, "Unrecognized property in property list."); static_assert(detail::IsSorted::value, "Properties in property list are not sorted."); @@ -126,30 +127,21 @@ template class property_list { std::tuple{props...})) {} template - static constexpr detail::enable_if_t< - detail::IntrospectiveIsProperty::value, bool> + static constexpr detail::enable_if_t::value, + bool> has_property() { return detail::ContainsProperty::value; } template - typename detail::enable_if_t< - detail::IsRuntimePropertyWithData::value, PropertyT> + typename detail::enable_if_t::value, + PropertyT> get_property() const { static_assert(has_property(), "Property list does not contain the requested property."); return std::get(Storage); } - template - typename detail::enable_if_t< - detail::IsRuntimeDatalessProperty::value, PropertyT> - get_property() const { - static_assert(has_property(), - "Property list does not contain the requested property."); - return {}; - } - template static constexpr auto get_property( typename std::enable_if_t::value> diff --git a/sycl/include/sycl/ext/oneapi/property_list/property_utils.hpp b/sycl/include/sycl/ext/oneapi/property_list/property_utils.hpp index e0ea06896b2e9..8191e18148dff 100644 --- a/sycl/include/sycl/ext/oneapi/property_list/property_utils.hpp +++ b/sycl/include/sycl/ext/oneapi/property_list/property_utils.hpp @@ -9,6 +9,7 @@ #pragma once #include +#include #include @@ -53,7 +54,7 @@ struct AllUnique> : std::true_type {}; template struct AllUnique> : std::true_type {}; template struct AllUnique> - : detail::conditional_t::value != PropertyID::value, AllUnique>, std::false_type> {}; @@ -61,50 +62,34 @@ struct AllUnique> // Property identification //****************************************************************************** -// Checks if a type is a runtime property with data. -template struct IsRuntimePropertyWithData { - static constexpr bool value = - is_property::value && std::is_base_of::value; -}; +// Checks if a type is a compile-time property values. +// Note: This is specialized for property_value elsewhere. +template +struct IsCompileTimePropertyValue : std::false_type {}; -// Checks if a type is a dataless runtime property. -template struct IsRuntimeDatalessProperty { +// Checks if a type is either a runtime property or if it is a compile-time +// property +template struct IsProperty { static constexpr bool value = - is_property::value && std::is_base_of::value; + IsRuntimeProperty::value || IsCompileTimeProperty::value; }; -// Checks if a type is a runtime property. -template struct IsRuntimeProperty { - static constexpr bool value = - is_property::value && - (std::is_base_of::value || - std::is_base_of::value); -}; - -// Checks if a type is either a runtime property (with or without data) or if -// it is a compile-time property (inside a property_value) -template struct IntrospectiveIsProperty : is_property {}; -template -struct IntrospectiveIsProperty> - : is_property {}; - -// Checks that a type is a compile-time property. value is true if either T is -// a non-runtime property or if it is a property_value containing a non-runtime -// property. -template struct IsCompileTimeProperty { +// Checks if a type is a valid property value, i.e either runtime property or +// property_value with a valid compile-time property +template struct IsPropertyValue { static constexpr bool value = - IntrospectiveIsProperty::value && !IsRuntimeProperty::value; + IsRuntimeProperty::value || IsCompileTimePropertyValue::value; }; // Checks that all types in a tuple are valid properties. -template struct AllProperties {}; +template struct AllPropertyValues {}; template -struct AllProperties> : std::true_type {}; +struct AllPropertyValues> : std::true_type {}; template -struct AllProperties> - : detail::conditional_t::value, - AllProperties>, std::false_type> { -}; +struct AllPropertyValues> + : detail::conditional_t::value, + AllPropertyValues>, + std::false_type> {}; //****************************************************************************** // Property type sorting @@ -143,7 +128,8 @@ template struct Merge, std::tuple> { using l_head = GetFirstType; using r_head = GetFirstType; - static constexpr bool left_has_min = l_head::PropertyID < r_head::PropertyID; + static constexpr bool left_has_min = + PropertyID::value < PropertyID::value; using l_split = HeadSplit, left_has_min>; using r_split = HeadSplit, !left_has_min>; using min = typename SelectNonVoid struct MergeAll> { // Performs merge-sort on types with PropertyID. template struct Sorted { - static_assert(detail::AllProperties>::value, + static_assert(detail::AllPropertyValues>::value, "Unrecognized property in property list."); using split = typename CreateTuplePairs::type; using type = typename MergeAll::type; @@ -222,7 +208,7 @@ struct IsSorted> : std::true_type {}; template struct IsSorted> : std::true_type {}; template struct IsSorted> - : detail::conditional_t::value <= PropertyID::value, IsSorted>, std::false_type> { }; diff --git a/sycl/include/sycl/ext/oneapi/property_list/property_value.hpp b/sycl/include/sycl/ext/oneapi/property_list/property_value.hpp index 25d26d5488b4c..5fc6e0a02e72d 100644 --- a/sycl/include/sycl/ext/oneapi/property_list/property_value.hpp +++ b/sycl/include/sycl/ext/oneapi/property_list/property_value.hpp @@ -6,26 +6,9 @@ // //===----------------------------------------------------------------------===// -// HOW-TO: Add new compile-time property -// 1. Define property class with `value_t` that must be `property_value` with -// the first template argument being the property class itself. -// 2. Add a new enumerator to `sycl::ext::oneapi::detail::CompileTimePropKind` -// representing the new property. Increment -// `sycl::ext::oneapi::detail::CompileTimePropKind::CompileTimePropKindSize` -// 3. Specialize `sycl::ext::oneapi::detail::CompileTimePropertyToKind` for the -// new property class. The specialization should have a `value` member -// with the value equal to the enumerator added in 2. -// 4. Add an `inline constexpr` variable in the same namespace as the property. -// The variable should have the same type as `value_t` of the property class -// and should be named as the property class with `_v` appended, e.g. for a -// property `foo`, there should be a definition -// `inline constexpr foo::value_t foo_v`. -// 5. Specialize `sycl::is_property` and `sycl::is_property_of` for the -// property class. - #pragma once -#include +#include #include __SYCL_INLINE_NAMESPACE(cl) { @@ -34,23 +17,6 @@ namespace ext { namespace oneapi { namespace detail { -// List of all compile-time properties -enum CompileTimePropKind { - CompileTimePropKindSize = 0, -}; - -// This trait must be specialized for all compile-time properties and must have -// a unique constexpr CompileTimePropKind member named PropKind -template struct CompileTimePropertyToKind {}; - -// Get unique ID for compile-time property -template struct CompileTimePropertyID { - static constexpr int value = - static_cast(CompileTimePropertyToKind::PropKind) + - static_cast(PropWithDataKind::PropWithDataKindSize) + - static_cast(DataLessPropKind::DataLessPropKindSize); -}; - // Base class for property values with a single type value. struct SingleTypePropertyValueBase {}; @@ -75,15 +41,12 @@ struct SinglePropertyValue template struct property_value - : public detail::IdentifyablePropertyBase< - detail::CompileTimePropertyID::value>, - public detail::conditional_t< + : public detail::conditional_t< sizeof...(Ts) == 0 && !std::is_same::value, detail::SinglePropertyValue, detail::EmptyPropertyValueBase> {}; template -constexpr detail::enable_if_t::value && - !detail::IsRuntimeProperty::value, +constexpr detail::enable_if_t::value, bool> operator==(const property_value &LHS, const property_value &RHS) { @@ -91,14 +54,26 @@ operator==(const property_value &LHS, } template -constexpr detail::enable_if_t::value && - !detail::IsRuntimeProperty::value, +constexpr detail::enable_if_t::value, bool> operator!=(const property_value &LHS, const property_value &RHS) { return (!std::is_same::value || ...); } +namespace detail { + +// Specialization of PropertyID for propagating IDs through property_value. +template +struct PropertyID> + : PropertyID {}; + +// Specialization of IsCompileTimePropertyValue for property values. +template +struct IsCompileTimePropertyValue> + : IsCompileTimeProperty {}; + +} // namespace detail } // namespace oneapi } // namespace ext } // namespace sycl diff --git a/sycl/test/extensions/property_list/mock_compile_time_properties.hpp b/sycl/test/extensions/property_list/mock_compile_time_properties.hpp index dd31e6b3e1f48..7b7bfdeae096b 100644 --- a/sycl/test/extensions/property_list/mock_compile_time_properties.hpp +++ b/sycl/test/extensions/property_list/mock_compile_time_properties.hpp @@ -29,22 +29,60 @@ struct boo { template using value_t = property_value; }; +struct foo { + foo(int v) : value(v) {} + int value; +}; + +inline bool operator==(const foo &lhs, const foo &rhs) { + return lhs.value == rhs.value; +} +inline bool operator!=(const foo &lhs, const foo &rhs) { return !(lhs == rhs); } + +struct foz { + foz(float v1, bool v2) : value1(v1), value2(v2) {} + // Define copy constructor to make foz non-trivially copyable + foz(const foz &f) { + value1 = f.value1; + value2 = f.value2; + } + float value1; + bool value2; +}; + +inline bool operator==(const foz &lhs, const foz &rhs) { + return lhs.value1 == rhs.value1 && lhs.value2 == rhs.value2; +} +inline bool operator!=(const foz &lhs, const foz &rhs) { return !(lhs == rhs); } + namespace detail { -template <> struct CompileTimePropertyToKind { - static constexpr CompileTimePropKind PropKind = - static_cast( - CompileTimePropKind::CompileTimePropKindSize + 0); +template <> struct PropertyToKind { + static constexpr PropKind Kind = + static_cast(PropKind::PropKindSize + 0); }; -template <> struct CompileTimePropertyToKind { - static constexpr CompileTimePropKind PropKind = - static_cast( - CompileTimePropKind::CompileTimePropKindSize + 1); +template <> struct PropertyToKind { + static constexpr PropKind Kind = + static_cast(PropKind::PropKindSize + 1); }; -template <> struct CompileTimePropertyToKind { - static constexpr CompileTimePropKind PropKind = - static_cast( - CompileTimePropKind::CompileTimePropKindSize + 2); +template <> struct PropertyToKind { + static constexpr PropKind Kind = + static_cast(PropKind::PropKindSize + 2); }; +template <> struct PropertyToKind { + static constexpr PropKind Kind = + static_cast(PropKind::PropKindSize + 3); +}; +template <> struct PropertyToKind { + static constexpr PropKind Kind = + static_cast(PropKind::PropKindSize + 4); +}; + +template <> struct IsCompileTimeProperty : std::true_type {}; +template <> struct IsCompileTimeProperty : std::true_type {}; +template <> struct IsCompileTimeProperty : std::true_type {}; + +template <> struct IsRuntimeProperty : std::true_type {}; +template <> struct IsRuntimeProperty : std::true_type {}; } // namespace detail inline constexpr bar::value_t bar_v; @@ -57,6 +95,8 @@ template inline constexpr boo::value_t boo_v; template <> struct is_property : std::true_type {}; template <> struct is_property : std::true_type {}; template <> struct is_property : std::true_type {}; +template <> struct is_property : std::true_type {}; +template <> struct is_property : std::true_type {}; template struct is_property_of : std::true_type {}; @@ -64,5 +104,9 @@ 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 {}; } // namespace sycl diff --git a/sycl/test/extensions/property_list/property_list_ctor_negative.cpp b/sycl/test/extensions/property_list/property_list_ctor_negative.cpp index 372ff28c9d38e..4860f178c086c 100644 --- a/sycl/test/extensions/property_list/property_list_ctor_negative.cpp +++ b/sycl/test/extensions/property_list/property_list_ctor_negative.cpp @@ -17,11 +17,11 @@ int main() { // CHECK-ERROR-1: Unrecognized property in property list. #elif (TEST_CASE == 2) auto InvalidPropertyList = - sycl::ext::oneapi::property_list(sycl::property::no_init{}, true); + sycl::ext::oneapi::property_list(sycl::ext::oneapi::foo{1}, true); // CHECK-ERROR-2: Unrecognized property in property list. #elif (TEST_CASE == 3) auto InvalidPropertyList = sycl::ext::oneapi::property_list( - sycl::property::no_init{}, sycl::property::no_init{}); + sycl::ext::oneapi::foo{0}, sycl::ext::oneapi::foo{1}); // CHECK-ERROR-3: Duplicate properties in property list. #elif (TEST_CASE == 4) auto InvalidPropertyList = sycl::ext::oneapi::property_list( diff --git a/sycl/test/extensions/property_list/property_list_device_copyable.cpp b/sycl/test/extensions/property_list/property_list_device_copyable.cpp index d5cfe7db66843..f78ab264d5112 100644 --- a/sycl/test/extensions/property_list/property_list_device_copyable.cpp +++ b/sycl/test/extensions/property_list/property_list_device_copyable.cpp @@ -25,34 +25,30 @@ int main() { static_assert(sycl::is_device_copyable_v); // Check property list with non-device-copyable property - using P2 = - sycl::ext::oneapi::property_list_t; - static_assert( - !sycl::is_device_copyable_v); + using P2 = sycl::ext::oneapi::property_list_t; + static_assert(!sycl::is_device_copyable_v); static_assert(!sycl::is_device_copyable_v); // Check property list with device-copyable compile-time and runtime // properties using P3 = sycl::ext::oneapi::property_list_t, - sycl::property::image::use_host_ptr>; - static_assert( - sycl::is_device_copyable_v); + sycl::ext::oneapi::foo>; + static_assert(sycl::is_device_copyable_v); static_assert(sycl::is_device_copyable_v); // Check that device-copyable property list can indeed be used in a kernel const auto PropertyList = sycl::ext::oneapi::property_list( - sycl::ext::oneapi::baz_v<1>, sycl::property::image::use_host_ptr{}); + sycl::ext::oneapi::baz_v<1>, sycl::ext::oneapi::foo{0}); sycl::queue Q; Q.submit([&](sycl::handler &CGH) { CGH.single_task([=]() { decltype(PropertyList)::has_property(); - decltype( - PropertyList)::has_property(); + decltype(PropertyList)::has_property(); PropertyList.get_property(); - PropertyList.get_property(); + PropertyList.get_property(); }); }); } diff --git a/sycl/test/extensions/property_list/property_list_get_property.cpp b/sycl/test/extensions/property_list/property_list_get_property.cpp index 2303231917afa..e06f3108fbb34 100644 --- a/sycl/test/extensions/property_list/property_list_get_property.cpp +++ b/sycl/test/extensions/property_list/property_list_get_property.cpp @@ -20,16 +20,16 @@ int main() { // Check runtime and compile-time properties on property-list object sycl::queue Q; + sycl::ext::oneapi::foo FooProp{3}; auto PropertyList = sycl::ext::oneapi::property_list( - sycl::ext::oneapi::baz_v<1>, sycl::ext::oneapi::bar_v, - sycl::property::no_init{}, - sycl::property::buffer::context_bound{Q.get_context()}); + sycl::ext::oneapi::baz_v<1>, sycl::ext::oneapi::bar_v, FooProp); static_assert( decltype(PropertyList)::get_property() == sycl::ext::oneapi::baz_v<1>); static_assert( decltype(PropertyList)::get_property() == sycl::ext::oneapi::bar_v); - assert(PropertyList.get_property() - .get_context() == Q.get_context()); + assert(PropertyList.get_property() == FooProp); + assert(PropertyList.get_property().value == + FooProp.value); } diff --git a/sycl/test/extensions/property_list/property_list_get_property_negative.cpp b/sycl/test/extensions/property_list/property_list_get_property_negative.cpp index 91c52ffac10e1..6d19f85ba4324 100644 --- a/sycl/test/extensions/property_list/property_list_get_property_negative.cpp +++ b/sycl/test/extensions/property_list/property_list_get_property_negative.cpp @@ -6,10 +6,6 @@ // RUN: FileCheck --check-prefix=CHECK-ERROR-3 < %t_3.err %s // RUN: not %clangxx -fsycl -fsycl-targets=%sycl_triple %s -o %t.bin -DTEST_CASE=4 2> %t_4.err // RUN: FileCheck --check-prefix=CHECK-ERROR-4 < %t_4.err %s -// RUN: not %clangxx -fsycl -fsycl-targets=%sycl_triple %s -o %t.bin -DTEST_CASE=5 2> %t_5.err -// RUN: FileCheck --check-prefix=CHECK-ERROR-5 < %t_5.err %s -// RUN: not %clangxx -fsycl -fsycl-targets=%sycl_triple %s -o %t.bin -DTEST_CASE=6 2> %t_6.err -// RUN: FileCheck --check-prefix=CHECK-ERROR-6 < %t_6.err %s #include @@ -21,26 +17,18 @@ int main() { decltype(EmptyPropertyList)::get_property(); // CHECK-ERROR-1: Property list does not contain the requested property. #elif (TEST_CASE == 2) - EmptyPropertyList.get_property(); + EmptyPropertyList.get_property(); // CHECK-ERROR-2: Property list does not contain the requested property. -#elif (TEST_CASE == 3) - EmptyPropertyList.get_property(); - // CHECK-ERROR-3: Property list does not contain the requested property. #endif sycl::queue Q; auto PopulatedPropertyList = sycl::ext::oneapi::property_list( - sycl::property::image::context_bound{Q.get_context()}, - sycl::ext::oneapi::bar_v, - sycl::property::context::cuda::use_primary_context{}); -#if (TEST_CASE == 4) + sycl::ext::oneapi::foz{.0f, true}, sycl::ext::oneapi::bar_v); +#if (TEST_CASE == 3) decltype(PopulatedPropertyList)::get_property(); + // CHECK-ERROR-3: Property list does not contain the requested property. +#elif (TEST_CASE == 4) + PopulatedPropertyList.get_property(); // CHECK-ERROR-4: Property list does not contain the requested property. -#elif (TEST_CASE == 5) - PopulatedPropertyList.get_property(); - // CHECK-ERROR-5: Property list does not contain the requested property. -#elif (TEST_CASE == 6) - PopulatedPropertyList.get_property(); - // CHECK-ERROR-6: Property list does not contain the requested property. #endif } diff --git a/sycl/test/extensions/property_list/property_list_has_property.cpp b/sycl/test/extensions/property_list/property_list_has_property.cpp index c93d41ea52f0b..e0842640c7d7e 100644 --- a/sycl/test/extensions/property_list/property_list_has_property.cpp +++ b/sycl/test/extensions/property_list/property_list_has_property.cpp @@ -13,27 +13,25 @@ int main() { static_assert(P1::has_property()); static_assert(P1::has_property()); static_assert(!P1::has_property()); - static_assert(!P1::has_property()); - static_assert(!P1::has_property()); + static_assert(!P1::has_property()); + static_assert(!P1::has_property()); // Check has_property for runtime properties - using P2 = - sycl::ext::oneapi::property_list_t; + using P2 = sycl::ext::oneapi::property_list_t; static_assert(!P2::has_property()); static_assert(!P2::has_property()); static_assert(!P2::has_property()); - static_assert(P2::has_property()); - static_assert(P2::has_property()); + static_assert(P2::has_property()); + static_assert(P2::has_property()); // Check has_property for a mix properties using P3 = - sycl::ext::oneapi::property_list_t, - sycl::property::image::context_bound>; + sycl::ext::oneapi::property_list_t>; static_assert(!P3::has_property()); static_assert(P3::has_property()); static_assert(!P3::has_property()); - static_assert(P3::has_property()); - static_assert(P3::has_property()); + static_assert(P3::has_property()); + static_assert(!P3::has_property()); } diff --git a/sycl/test/extensions/property_list/property_list_is_property_list.cpp b/sycl/test/extensions/property_list/property_list_is_property_list.cpp index dd20d7596709f..e7d47e679e66f 100644 --- a/sycl/test/extensions/property_list/property_list_is_property_list.cpp +++ b/sycl/test/extensions/property_list/property_list_is_property_list.cpp @@ -19,17 +19,16 @@ int main() { static_assert(sycl::ext::oneapi::is_property_list_v); // Check is_property_list for runtime properties - using P2 = - sycl::ext::oneapi::property_list_t; + using P2 = sycl::ext::oneapi::property_list_t; static_assert(sycl::ext::oneapi::is_property_list::value); static_assert(sycl::ext::oneapi::is_property_list_v); // Check is_property_list for a mix properties using P3 = - sycl::ext::oneapi::property_list_t, - sycl::property::image::context_bound>; + sycl::ext::oneapi::foz>; static_assert(sycl::ext::oneapi::is_property_list::value); static_assert(sycl::ext::oneapi::is_property_list_v); @@ -43,16 +42,14 @@ int main() { // Check is_property_list for runtime properties on object sycl::queue Q; auto PropertyList2 = sycl::ext::oneapi::property_list( - sycl::property::buffer::use_host_ptr{}, - sycl::property::image::context_bound{Q.get_context()}); + sycl::ext::oneapi::foo{1}, sycl::ext::oneapi::foz{.123f, false}); static_assert( sycl::ext::oneapi::is_property_list::value); static_assert(sycl::ext::oneapi::is_property_list_v); // Check is_property_list for a mix properties on object auto PropertyList3 = sycl::ext::oneapi::property_list( - sycl::property::buffer::use_host_ptr{}, sycl::ext::oneapi::baz_v<1>, - sycl::property::image::context_bound{Q.get_context()}); + sycl::ext::oneapi::foo{42}, sycl::ext::oneapi::baz_v<1>); static_assert( sycl::ext::oneapi::is_property_list::value); static_assert(sycl::ext::oneapi::is_property_list_v); From 31d391e1fa748e3d535cc15dab1175942d0a1129 Mon Sep 17 00:00:00 2001 From: Steffen Larsen Date: Thu, 2 Dec 2021 17:42:38 +0300 Subject: [PATCH 09/24] Fix formatting Signed-off-by: Steffen Larsen --- sycl/include/sycl/ext/oneapi/property_list/properties.hpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/sycl/include/sycl/ext/oneapi/property_list/properties.hpp b/sycl/include/sycl/ext/oneapi/property_list/properties.hpp index 4a0163eed19d3..61618a36de158 100644 --- a/sycl/include/sycl/ext/oneapi/property_list/properties.hpp +++ b/sycl/include/sycl/ext/oneapi/property_list/properties.hpp @@ -100,7 +100,7 @@ struct foo { foo(int v) : value(v) {} int value; }; - + // (3.) inline bool operator==(const foo &lhs, const foo &rhs) { return lhs.value == rhs.value; @@ -110,12 +110,12 @@ inline bool operator!=(const foo &lhs, const foo &rhs) { } namespace detail { - + // (4.) template <> struct PropertyToKind { static constexpr PropKind Kind = PropKind::Foo; }; - + // (5.) template <> struct IsRuntimeProperty : std::true_type {}; } // namespace detail @@ -127,7 +127,7 @@ template <> struct is_property : std::true_type {}; // Replace SYCL_OBJ with the SYCL object to support the property. template <> struct is_property_of : std::true_type {}; - + } // namespace sycl *******************************************************************************/ From 0f9bf8f32b22825faa927db6fcfae494a755f521 Mon Sep 17 00:00:00 2001 From: Steffen Larsen Date: Fri, 14 Jan 2022 16:43:35 +0300 Subject: [PATCH 10/24] Move property_list to experimental Signed-off-by: Steffen Larsen --- .../ext/oneapi/property_list/properties.hpp | 2 + .../oneapi/property_list/property_list.hpp | 25 +++--- .../oneapi/property_list/property_utils.hpp | 20 +++-- .../oneapi/property_list/property_value.hpp | 18 ++-- .../mock_compile_time_properties.hpp | 32 ++++--- .../property_list_ctor_negative.cpp | 16 ++-- .../property_list_device_copyable.cpp | 49 ++++++----- .../property_list/property_list_equality.cpp | 12 +-- .../property_list_get_property.cpp | 44 +++++----- .../property_list_get_property_negative.cpp | 17 ++-- .../property_list_has_property.cpp | 47 +++++----- .../property_list_is_property_list.cpp | 87 ++++++++++--------- 12 files changed, 209 insertions(+), 160 deletions(-) diff --git a/sycl/include/sycl/ext/oneapi/property_list/properties.hpp b/sycl/include/sycl/ext/oneapi/property_list/properties.hpp index 61618a36de158..a834986260e43 100644 --- a/sycl/include/sycl/ext/oneapi/property_list/properties.hpp +++ b/sycl/include/sycl/ext/oneapi/property_list/properties.hpp @@ -137,6 +137,7 @@ __SYCL_INLINE_NAMESPACE(cl) { namespace sycl { namespace ext { namespace oneapi { +namespace experimental { namespace detail { // List of all properties. @@ -161,6 +162,7 @@ template struct IsRuntimeProperty : std::false_type {}; template struct IsCompileTimeProperty : std::false_type {}; } // namespace detail +} // namespace experimental } // namespace oneapi } // namespace ext } // namespace sycl diff --git a/sycl/include/sycl/ext/oneapi/property_list/property_list.hpp b/sycl/include/sycl/ext/oneapi/property_list/property_list.hpp index c095570c7b041..1c0613bd17482 100644 --- a/sycl/include/sycl/ext/oneapi/property_list/property_list.hpp +++ b/sycl/include/sycl/ext/oneapi/property_list/property_list.hpp @@ -21,6 +21,7 @@ __SYCL_INLINE_NAMESPACE(cl) { namespace sycl { namespace ext { namespace oneapi { +namespace experimental { namespace detail { @@ -65,10 +66,11 @@ template struct RuntimePropertyStorage> { }; template struct RuntimePropertyStorage> - : detail::conditional_t::value, - PrependTuple>::type>, - RuntimePropertyStorage>> {}; + : sycl::detail::conditional_t< + IsRuntimeProperty::value, + PrependTuple< + T, typename RuntimePropertyStorage>::type>, + RuntimePropertyStorage>> {}; // Helper class to extract a subset of elements from a tuple. // NOTES: This assumes no duplicate properties and that all properties in the @@ -127,15 +129,14 @@ template class property_list { std::tuple{props...})) {} template - static constexpr detail::enable_if_t::value, - bool> + static constexpr std::enable_if_t::value, bool> has_property() { return detail::ContainsProperty::value; } template - typename detail::enable_if_t::value, - PropertyT> + typename std::enable_if_t::value, + PropertyT> get_property() const { static_assert(has_property(), "Property list does not contain the requested property."); @@ -183,15 +184,17 @@ inline constexpr bool is_property_list_v = is_property_list::value; #endif +} // namespace experimental } // namespace oneapi } // namespace ext // If property_list is not trivially copyable, allow properties to propagate // is_device_copyable template -struct is_device_copyable, - std::enable_if_t>::value>> +struct is_device_copyable< + ext::oneapi::experimental::property_list, + std::enable_if_t>::value>> : is_device_copyable {}; } // namespace sycl diff --git a/sycl/include/sycl/ext/oneapi/property_list/property_utils.hpp b/sycl/include/sycl/ext/oneapi/property_list/property_utils.hpp index 8191e18148dff..5884c79c48d4a 100644 --- a/sycl/include/sycl/ext/oneapi/property_list/property_utils.hpp +++ b/sycl/include/sycl/ext/oneapi/property_list/property_utils.hpp @@ -17,6 +17,7 @@ __SYCL_INLINE_NAMESPACE(cl) { namespace sycl { namespace ext { namespace oneapi { +namespace experimental { // Forward declaration template struct property_value; @@ -54,9 +55,9 @@ struct AllUnique> : std::true_type {}; template struct AllUnique> : std::true_type {}; template struct AllUnique> - : detail::conditional_t::value != PropertyID::value, - AllUnique>, - std::false_type> {}; + : sycl::detail::conditional_t::value != PropertyID::value, + AllUnique>, + std::false_type> {}; //****************************************************************************** // Property identification @@ -87,9 +88,9 @@ template struct AllPropertyValues> : std::true_type {}; template struct AllPropertyValues> - : detail::conditional_t::value, - AllPropertyValues>, - std::false_type> {}; + : sycl::detail::conditional_t::value, + AllPropertyValues>, + std::false_type> {}; //****************************************************************************** // Property type sorting @@ -208,11 +209,12 @@ struct IsSorted> : std::true_type {}; template struct IsSorted> : std::true_type {}; template struct IsSorted> - : detail::conditional_t::value <= PropertyID::value, - IsSorted>, std::false_type> { -}; + : sycl::detail::conditional_t::value <= PropertyID::value, + IsSorted>, + std::false_type> {}; } // namespace detail +} // namespace experimental } // namespace oneapi } // namespace ext } // namespace sycl diff --git a/sycl/include/sycl/ext/oneapi/property_list/property_value.hpp b/sycl/include/sycl/ext/oneapi/property_list/property_value.hpp index 5fc6e0a02e72d..b79c63427eaf1 100644 --- a/sycl/include/sycl/ext/oneapi/property_list/property_value.hpp +++ b/sycl/include/sycl/ext/oneapi/property_list/property_value.hpp @@ -15,6 +15,7 @@ __SYCL_INLINE_NAMESPACE(cl) { namespace sycl { namespace ext { namespace oneapi { +namespace experimental { namespace detail { // Base class for property values with a single type value. @@ -31,9 +32,9 @@ template struct SingleNontypePropertyValueBase { // Helper class for property values with a single value template struct SinglePropertyValue - : public detail::conditional_t::value, - SingleNontypePropertyValueBase, - SingleTypePropertyValueBase> { + : public sycl::detail::conditional_t::value, + SingleNontypePropertyValueBase, + SingleTypePropertyValueBase> { using value_t = T; }; @@ -41,21 +42,21 @@ struct SinglePropertyValue template struct property_value - : public detail::conditional_t< + : public sycl::detail::conditional_t< sizeof...(Ts) == 0 && !std::is_same::value, detail::SinglePropertyValue, detail::EmptyPropertyValueBase> {}; template -constexpr detail::enable_if_t::value, - bool> +constexpr std::enable_if_t::value, + bool> operator==(const property_value &LHS, const property_value &RHS) { return (std::is_same::value && ...); } template -constexpr detail::enable_if_t::value, - bool> +constexpr std::enable_if_t::value, + bool> operator!=(const property_value &LHS, const property_value &RHS) { return (!std::is_same::value || ...); @@ -74,6 +75,7 @@ struct IsCompileTimePropertyValue> : IsCompileTimeProperty {}; } // namespace detail +} // namespace experimental } // namespace oneapi } // namespace ext } // namespace sycl diff --git a/sycl/test/extensions/property_list/mock_compile_time_properties.hpp b/sycl/test/extensions/property_list/mock_compile_time_properties.hpp index 7b7bfdeae096b..1e54f011ce9db 100644 --- a/sycl/test/extensions/property_list/mock_compile_time_properties.hpp +++ b/sycl/test/extensions/property_list/mock_compile_time_properties.hpp @@ -15,6 +15,7 @@ namespace sycl { namespace ext { namespace oneapi { +namespace experimental { struct bar { using value_t = property_value; @@ -89,24 +90,35 @@ inline constexpr bar::value_t bar_v; template inline constexpr baz::value_t baz_v; template inline constexpr boo::value_t boo_v; +} // namespace experimental } // namespace oneapi } // namespace ext -template <> struct is_property : std::true_type {}; -template <> struct is_property : std::true_type {}; -template <> struct is_property : std::true_type {}; -template <> struct is_property : std::true_type {}; -template <> struct is_property : std::true_type {}; +template <> +struct is_property : std::true_type {}; +template <> +struct is_property : std::true_type {}; +template <> +struct is_property : std::true_type {}; +template <> +struct is_property : std::true_type {}; +template <> +struct is_property : std::true_type {}; template -struct is_property_of : std::true_type {}; +struct is_property_of + : std::true_type {}; template -struct is_property_of : std::true_type {}; +struct is_property_of + : std::true_type {}; template -struct is_property_of : std::true_type {}; +struct is_property_of + : std::true_type {}; template -struct is_property_of : std::true_type {}; +struct is_property_of + : std::true_type {}; template -struct is_property_of : std::true_type {}; +struct is_property_of + : std::true_type {}; } // namespace sycl diff --git a/sycl/test/extensions/property_list/property_list_ctor_negative.cpp b/sycl/test/extensions/property_list/property_list_ctor_negative.cpp index 4860f178c086c..873dfd71c9c38 100644 --- a/sycl/test/extensions/property_list/property_list_ctor_negative.cpp +++ b/sycl/test/extensions/property_list/property_list_ctor_negative.cpp @@ -13,19 +13,21 @@ int main() { #if (TEST_CASE == 1) - auto InvalidPropertyList = sycl::ext::oneapi::property_list(1); + auto InvalidPropertyList = sycl::ext::oneapi::experimental::property_list(1); // CHECK-ERROR-1: Unrecognized property in property list. #elif (TEST_CASE == 2) - auto InvalidPropertyList = - sycl::ext::oneapi::property_list(sycl::ext::oneapi::foo{1}, true); + auto InvalidPropertyList = sycl::ext::oneapi::experimental::property_list( + sycl::ext::oneapi::experimental::foo{1}, true); // CHECK-ERROR-2: Unrecognized property in property list. #elif (TEST_CASE == 3) - auto InvalidPropertyList = sycl::ext::oneapi::property_list( - sycl::ext::oneapi::foo{0}, sycl::ext::oneapi::foo{1}); + auto InvalidPropertyList = sycl::ext::oneapi::experimental::property_list( + sycl::ext::oneapi::experimental::foo{0}, + sycl::ext::oneapi::experimental::foo{1}); // CHECK-ERROR-3: Duplicate properties in property list. #elif (TEST_CASE == 4) - auto InvalidPropertyList = sycl::ext::oneapi::property_list( - sycl::ext::oneapi::bar_v, sycl::ext::oneapi::bar_v); + auto InvalidPropertyList = sycl::ext::oneapi::experimental::property_list( + sycl::ext::oneapi::experimental::bar_v, + sycl::ext::oneapi::experimental::bar_v); // CHECK-ERROR-4: Duplicate properties in property list. #endif } diff --git a/sycl/test/extensions/property_list/property_list_device_copyable.cpp b/sycl/test/extensions/property_list/property_list_device_copyable.cpp index f78ab264d5112..384d5ebec611a 100644 --- a/sycl/test/extensions/property_list/property_list_device_copyable.cpp +++ b/sycl/test/extensions/property_list/property_list_device_copyable.cpp @@ -13,42 +13,51 @@ class TestClass2 {}; int main() { // Check only compile-time properties are device-copyable - using P1 = sycl::ext::oneapi::property_list_t< - sycl::ext::oneapi::baz::value_t<1>, - sycl::ext::oneapi::boo::value_t, - sycl::ext::oneapi::bar::value_t>; + using P1 = sycl::ext::oneapi::experimental::property_list_t< + sycl::ext::oneapi::experimental::baz::value_t<1>, + sycl::ext::oneapi::experimental::boo::value_t, + sycl::ext::oneapi::experimental::bar::value_t>; - static_assert(sycl::is_device_copyable_v>); static_assert(sycl::is_device_copyable_v< - sycl::ext::oneapi::boo::value_t>); - static_assert(sycl::is_device_copyable_v); + sycl::ext::oneapi::experimental::baz::value_t<1>>); + static_assert( + sycl::is_device_copyable_v>); + static_assert(sycl::is_device_copyable_v< + sycl::ext::oneapi::experimental::bar::value_t>); static_assert(sycl::is_device_copyable_v); // Check property list with non-device-copyable property - using P2 = sycl::ext::oneapi::property_list_t; - static_assert(!sycl::is_device_copyable_v); + using P2 = sycl::ext::oneapi::experimental::property_list_t< + sycl::ext::oneapi::experimental::bar::value_t, + sycl::ext::oneapi::experimental::foz>; + static_assert( + !sycl::is_device_copyable_v); static_assert(!sycl::is_device_copyable_v); // Check property list with device-copyable compile-time and runtime // properties - using P3 = - sycl::ext::oneapi::property_list_t, - sycl::ext::oneapi::foo>; - static_assert(sycl::is_device_copyable_v); + using P3 = sycl::ext::oneapi::experimental::property_list_t< + sycl::ext::oneapi::experimental::baz::value_t<1>, + sycl::ext::oneapi::experimental::foo>; + static_assert( + sycl::is_device_copyable_v); static_assert(sycl::is_device_copyable_v); // Check that device-copyable property list can indeed be used in a kernel - const auto PropertyList = sycl::ext::oneapi::property_list( - sycl::ext::oneapi::baz_v<1>, sycl::ext::oneapi::foo{0}); + const auto PropertyList = sycl::ext::oneapi::experimental::property_list( + sycl::ext::oneapi::experimental::baz_v<1>, + sycl::ext::oneapi::experimental::foo{0}); sycl::queue Q; Q.submit([&](sycl::handler &CGH) { CGH.single_task([=]() { - decltype(PropertyList)::has_property(); - decltype(PropertyList)::has_property(); - PropertyList.get_property(); - PropertyList.get_property(); + decltype(PropertyList)::has_property< + sycl::ext::oneapi::experimental::baz>(); + decltype(PropertyList)::has_property< + sycl::ext::oneapi::experimental::foo>(); + PropertyList.get_property(); + PropertyList.get_property(); }); }); } diff --git a/sycl/test/extensions/property_list/property_list_equality.cpp b/sycl/test/extensions/property_list/property_list_equality.cpp index 9fd407f896ce1..aab8b1d5365c1 100644 --- a/sycl/test/extensions/property_list/property_list_equality.cpp +++ b/sycl/test/extensions/property_list/property_list_equality.cpp @@ -6,11 +6,11 @@ #include "mock_compile_time_properties.hpp" int main() { - using P1 = - sycl::ext::oneapi::property_list_t, - sycl::ext::oneapi::bar::value_t>; - using P2 = - sycl::ext::oneapi::property_list_t>; + using P1 = sycl::ext::oneapi::experimental::property_list_t< + sycl::ext::oneapi::experimental::baz::value_t<1>, + sycl::ext::oneapi::experimental::bar::value_t>; + using P2 = sycl::ext::oneapi::experimental::property_list_t< + sycl::ext::oneapi::experimental::bar::value_t, + sycl::ext::oneapi::experimental::baz::value_t<1>>; static_assert(std::is_same::value); } diff --git a/sycl/test/extensions/property_list/property_list_get_property.cpp b/sycl/test/extensions/property_list/property_list_get_property.cpp index e06f3108fbb34..f4300db36b360 100644 --- a/sycl/test/extensions/property_list/property_list_get_property.cpp +++ b/sycl/test/extensions/property_list/property_list_get_property.cpp @@ -6,30 +6,34 @@ #include "mock_compile_time_properties.hpp" int main() { - using P1 = - sycl::ext::oneapi::property_list_t, - sycl::ext::oneapi::bar::value_t>; + using P1 = sycl::ext::oneapi::experimental::property_list_t< + sycl::ext::oneapi::experimental::baz::value_t<1>, + sycl::ext::oneapi::experimental::bar::value_t>; // Check that get_property of compile-time properties are the same as _v - static_assert(P1::get_property() == - sycl::ext::oneapi::baz_v<1>); - static_assert(P1::get_property() == - sycl::ext::oneapi::bar_v); + static_assert(P1::get_property() == + sycl::ext::oneapi::experimental::baz_v<1>); + static_assert(P1::get_property() == + sycl::ext::oneapi::experimental::bar_v); // Check value on returned property - static_assert(P1::get_property().value == 1); + static_assert( + P1::get_property().value == 1); // Check runtime and compile-time properties on property-list object sycl::queue Q; - sycl::ext::oneapi::foo FooProp{3}; - auto PropertyList = sycl::ext::oneapi::property_list( - sycl::ext::oneapi::baz_v<1>, sycl::ext::oneapi::bar_v, FooProp); - static_assert( - decltype(PropertyList)::get_property() == - sycl::ext::oneapi::baz_v<1>); - static_assert( - decltype(PropertyList)::get_property() == - sycl::ext::oneapi::bar_v); - assert(PropertyList.get_property() == FooProp); - assert(PropertyList.get_property().value == - FooProp.value); + sycl::ext::oneapi::experimental::foo FooProp{3}; + auto PropertyList = sycl::ext::oneapi::experimental::property_list( + sycl::ext::oneapi::experimental::baz_v<1>, + sycl::ext::oneapi::experimental::bar_v, FooProp); + static_assert(decltype(PropertyList)::get_property< + sycl::ext::oneapi::experimental::baz>() == + sycl::ext::oneapi::experimental::baz_v<1>); + static_assert(decltype(PropertyList)::get_property< + sycl::ext::oneapi::experimental::bar>() == + sycl::ext::oneapi::experimental::bar_v); + assert(PropertyList.get_property() == + FooProp); + assert( + PropertyList.get_property().value == + FooProp.value); } diff --git a/sycl/test/extensions/property_list/property_list_get_property_negative.cpp b/sycl/test/extensions/property_list/property_list_get_property_negative.cpp index 6d19f85ba4324..95017f07c9093 100644 --- a/sycl/test/extensions/property_list/property_list_get_property_negative.cpp +++ b/sycl/test/extensions/property_list/property_list_get_property_negative.cpp @@ -12,23 +12,26 @@ #include "mock_compile_time_properties.hpp" int main() { - auto EmptyPropertyList = sycl::ext::oneapi::property_list(); + auto EmptyPropertyList = sycl::ext::oneapi::experimental::property_list(); #if (TEST_CASE == 1) - decltype(EmptyPropertyList)::get_property(); + decltype(EmptyPropertyList)::get_property< + sycl::ext::oneapi::experimental::boo>(); // CHECK-ERROR-1: Property list does not contain the requested property. #elif (TEST_CASE == 2) - EmptyPropertyList.get_property(); + EmptyPropertyList.get_property(); // CHECK-ERROR-2: Property list does not contain the requested property. #endif sycl::queue Q; - auto PopulatedPropertyList = sycl::ext::oneapi::property_list( - sycl::ext::oneapi::foz{.0f, true}, sycl::ext::oneapi::bar_v); + auto PopulatedPropertyList = sycl::ext::oneapi::experimental::property_list( + sycl::ext::oneapi::experimental::foz{.0f, true}, + sycl::ext::oneapi::experimental::bar_v); #if (TEST_CASE == 3) - decltype(PopulatedPropertyList)::get_property(); + decltype(PopulatedPropertyList)::get_property< + sycl::ext::oneapi::experimental::boo>(); // CHECK-ERROR-3: Property list does not contain the requested property. #elif (TEST_CASE == 4) - PopulatedPropertyList.get_property(); + PopulatedPropertyList.get_property(); // CHECK-ERROR-4: Property list does not contain the requested property. #endif } diff --git a/sycl/test/extensions/property_list/property_list_has_property.cpp b/sycl/test/extensions/property_list/property_list_has_property.cpp index e0842640c7d7e..ee374d7d31c3a 100644 --- a/sycl/test/extensions/property_list/property_list_has_property.cpp +++ b/sycl/test/extensions/property_list/property_list_has_property.cpp @@ -7,31 +7,32 @@ int main() { // Check has_property for compile-time properties - using P1 = - sycl::ext::oneapi::property_list_t, - sycl::ext::oneapi::bar::value_t>; - static_assert(P1::has_property()); - static_assert(P1::has_property()); - static_assert(!P1::has_property()); - static_assert(!P1::has_property()); - static_assert(!P1::has_property()); + using P1 = sycl::ext::oneapi::experimental::property_list_t< + sycl::ext::oneapi::experimental::baz::value_t<1>, + sycl::ext::oneapi::experimental::bar::value_t>; + static_assert(P1::has_property()); + static_assert(P1::has_property()); + static_assert(!P1::has_property()); + static_assert(!P1::has_property()); + static_assert(!P1::has_property()); // Check has_property for runtime properties - using P2 = sycl::ext::oneapi::property_list_t; - static_assert(!P2::has_property()); - static_assert(!P2::has_property()); - static_assert(!P2::has_property()); - static_assert(P2::has_property()); - static_assert(P2::has_property()); + using P2 = sycl::ext::oneapi::experimental::property_list_t< + sycl::ext::oneapi::experimental::foo, + sycl::ext::oneapi::experimental::foz>; + static_assert(!P2::has_property()); + static_assert(!P2::has_property()); + static_assert(!P2::has_property()); + static_assert(P2::has_property()); + static_assert(P2::has_property()); // Check has_property for a mix properties - using P3 = - sycl::ext::oneapi::property_list_t>; - static_assert(!P3::has_property()); - static_assert(P3::has_property()); - static_assert(!P3::has_property()); - static_assert(P3::has_property()); - static_assert(!P3::has_property()); + using P3 = sycl::ext::oneapi::experimental::property_list_t< + sycl::ext::oneapi::experimental::foo, + sycl::ext::oneapi::experimental::baz::value_t<1>>; + static_assert(!P3::has_property()); + static_assert(P3::has_property()); + static_assert(!P3::has_property()); + static_assert(P3::has_property()); + static_assert(!P3::has_property()); } diff --git a/sycl/test/extensions/property_list/property_list_is_property_list.cpp b/sycl/test/extensions/property_list/property_list_is_property_list.cpp index e7d47e679e66f..de860cfa5a6d9 100644 --- a/sycl/test/extensions/property_list/property_list_is_property_list.cpp +++ b/sycl/test/extensions/property_list/property_list_is_property_list.cpp @@ -7,58 +7,67 @@ int main() { // Check is_property_list for empty property list - using EmptyP = sycl::ext::oneapi::property_list_t<>; - static_assert(sycl::ext::oneapi::is_property_list::value); - static_assert(sycl::ext::oneapi::is_property_list_v); + using EmptyP = sycl::ext::oneapi::experimental::property_list_t<>; + static_assert( + sycl::ext::oneapi::experimental::is_property_list::value); + static_assert(sycl::ext::oneapi::experimental::is_property_list_v); // Check is_property_list for compile-time properties - using P1 = - sycl::ext::oneapi::property_list_t, - sycl::ext::oneapi::bar::value_t>; - static_assert(sycl::ext::oneapi::is_property_list::value); - static_assert(sycl::ext::oneapi::is_property_list_v); + using P1 = sycl::ext::oneapi::experimental::property_list_t< + sycl::ext::oneapi::experimental::baz::value_t<1>, + sycl::ext::oneapi::experimental::bar::value_t>; + static_assert(sycl::ext::oneapi::experimental::is_property_list::value); + static_assert(sycl::ext::oneapi::experimental::is_property_list_v); // Check is_property_list for runtime properties - using P2 = sycl::ext::oneapi::property_list_t; - static_assert(sycl::ext::oneapi::is_property_list::value); - static_assert(sycl::ext::oneapi::is_property_list_v); + using P2 = sycl::ext::oneapi::experimental::property_list_t< + sycl::ext::oneapi::experimental::foo, + sycl::ext::oneapi::experimental::foz>; + static_assert(sycl::ext::oneapi::experimental::is_property_list::value); + static_assert(sycl::ext::oneapi::experimental::is_property_list_v); // Check is_property_list for a mix properties - using P3 = - sycl::ext::oneapi::property_list_t, - sycl::ext::oneapi::foz>; - static_assert(sycl::ext::oneapi::is_property_list::value); - static_assert(sycl::ext::oneapi::is_property_list_v); + using P3 = sycl::ext::oneapi::experimental::property_list_t< + sycl::ext::oneapi::experimental::foo, + sycl::ext::oneapi::experimental::baz::value_t<1>, + sycl::ext::oneapi::experimental::foz>; + static_assert(sycl::ext::oneapi::experimental::is_property_list::value); + static_assert(sycl::ext::oneapi::experimental::is_property_list_v); // Check is_property_list for compile-time properties on object - auto PropertyList1 = sycl::ext::oneapi::property_list( - sycl::ext::oneapi::baz_v<1>, sycl::ext::oneapi::bar_v); - static_assert( - sycl::ext::oneapi::is_property_list::value); - static_assert(sycl::ext::oneapi::is_property_list_v); + auto PropertyList1 = sycl::ext::oneapi::experimental::property_list( + sycl::ext::oneapi::experimental::baz_v<1>, + sycl::ext::oneapi::experimental::bar_v); + static_assert(sycl::ext::oneapi::experimental::is_property_list< + decltype(PropertyList1)>::value); + static_assert(sycl::ext::oneapi::experimental::is_property_list_v< + decltype(PropertyList1)>); // Check is_property_list for runtime properties on object sycl::queue Q; - auto PropertyList2 = sycl::ext::oneapi::property_list( - sycl::ext::oneapi::foo{1}, sycl::ext::oneapi::foz{.123f, false}); - static_assert( - sycl::ext::oneapi::is_property_list::value); - static_assert(sycl::ext::oneapi::is_property_list_v); + auto PropertyList2 = sycl::ext::oneapi::experimental::property_list( + sycl::ext::oneapi::experimental::foo{1}, + sycl::ext::oneapi::experimental::foz{.123f, false}); + static_assert(sycl::ext::oneapi::experimental::is_property_list< + decltype(PropertyList2)>::value); + static_assert(sycl::ext::oneapi::experimental::is_property_list_v< + decltype(PropertyList2)>); // Check is_property_list for a mix properties on object - auto PropertyList3 = sycl::ext::oneapi::property_list( - sycl::ext::oneapi::foo{42}, sycl::ext::oneapi::baz_v<1>); - static_assert( - sycl::ext::oneapi::is_property_list::value); - static_assert(sycl::ext::oneapi::is_property_list_v); + auto PropertyList3 = sycl::ext::oneapi::experimental::property_list( + sycl::ext::oneapi::experimental::foo{42}, + sycl::ext::oneapi::experimental::baz_v<1>); + static_assert(sycl::ext::oneapi::experimental::is_property_list< + decltype(PropertyList3)>::value); + static_assert(sycl::ext::oneapi::experimental::is_property_list_v< + decltype(PropertyList3)>); // Check is_property_list on types that are not valid - // sycl::ext::oneapi::property_list. - static_assert(!sycl::ext::oneapi::is_property_list::value); - static_assert(!sycl::ext::oneapi::is_property_list_v); - static_assert( - !sycl::ext::oneapi::is_property_list::value); - static_assert(!sycl::ext::oneapi::is_property_list_v); + // sycl::ext::oneapi::experimental::property_list. + static_assert(!sycl::ext::oneapi::experimental::is_property_list::value); + static_assert(!sycl::ext::oneapi::experimental::is_property_list_v); + static_assert(!sycl::ext::oneapi::experimental::is_property_list< + sycl::property_list>::value); + static_assert(!sycl::ext::oneapi::experimental::is_property_list_v< + sycl::property_list>); } From 43149a4716564dd92b2d6714acd023c9ca3e9a9b Mon Sep 17 00:00:00 2001 From: Steffen Larsen Date: Fri, 14 Jan 2022 20:19:40 +0300 Subject: [PATCH 11/24] Adjust for renaming Signed-off-by: Steffen Larsen --- sycl/include/CL/sycl.hpp | 4 +- .../properties.hpp} | 38 +++--- .../property.hpp} | 129 +++++++++--------- .../property_utils.hpp | 4 +- .../property_value.hpp | 34 +++-- .../mock_compile_time_properties.hpp | 89 ++++++------ .../properties_ctor_negative.cpp} | 12 +- .../properties_device_copyable.cpp} | 40 +++--- .../properties/properties_equality.cpp | 16 +++ .../properties/properties_get_property.cpp | 39 ++++++ .../properties_get_property_negative.cpp} | 15 +- .../properties_has_property.cpp} | 48 +++---- .../properties/properties_is_property_key.cpp | 89 ++++++++++++ .../properties_is_property_list.cpp} | 34 ++--- .../properties_is_property_value.cpp | 88 ++++++++++++ .../property_list/property_list_equality.cpp | 16 --- .../property_list_get_property.cpp | 39 ------ 17 files changed, 461 insertions(+), 273 deletions(-) rename sycl/include/sycl/ext/oneapi/{property_list/property_list.hpp => properties/properties.hpp} (85%) rename sycl/include/sycl/ext/oneapi/{property_list/properties.hpp => properties/property.hpp} (51%) rename sycl/include/sycl/ext/oneapi/{property_list => properties}/property_utils.hpp (98%) rename sycl/include/sycl/ext/oneapi/{property_list => properties}/property_value.hpp (69%) rename sycl/test/extensions/{property_list => properties}/mock_compile_time_properties.hpp (54%) rename sycl/test/extensions/{property_list/property_list_ctor_negative.cpp => properties/properties_ctor_negative.cpp} (90%) rename sycl/test/extensions/{property_list/property_list_device_copyable.cpp => properties/properties_device_copyable.cpp} (60%) create mode 100644 sycl/test/extensions/properties/properties_equality.cpp create mode 100644 sycl/test/extensions/properties/properties_get_property.cpp rename sycl/test/extensions/{property_list/property_list_get_property_negative.cpp => properties/properties_get_property_negative.cpp} (84%) rename sycl/test/extensions/{property_list/property_list_has_property.cpp => properties/properties_has_property.cpp} (63%) create mode 100644 sycl/test/extensions/properties/properties_is_property_key.cpp rename sycl/test/extensions/{property_list/property_list_is_property_list.cpp => properties/properties_is_property_list.cpp} (72%) create mode 100644 sycl/test/extensions/properties/properties_is_property_value.cpp delete mode 100644 sycl/test/extensions/property_list/property_list_equality.cpp delete mode 100644 sycl/test/extensions/property_list/property_list_get_property.cpp diff --git a/sycl/include/CL/sycl.hpp b/sycl/include/CL/sycl.hpp index 2d4c58348d54b..b5513d3ccc6b0 100644 --- a/sycl/include/CL/sycl.hpp +++ b/sycl/include/CL/sycl.hpp @@ -57,8 +57,8 @@ #include #include #include -#include -#include +#include +#include #include #include #include diff --git a/sycl/include/sycl/ext/oneapi/property_list/property_list.hpp b/sycl/include/sycl/ext/oneapi/properties/properties.hpp similarity index 85% rename from sycl/include/sycl/ext/oneapi/property_list/property_list.hpp rename to sycl/include/sycl/ext/oneapi/properties/properties.hpp index 1c0613bd17482..eee0a6cf1b9e1 100644 --- a/sycl/include/sycl/ext/oneapi/property_list/property_list.hpp +++ b/sycl/include/sycl/ext/oneapi/properties/properties.hpp @@ -1,4 +1,4 @@ -//==-------- property_list.hpp --- SYCL extended property list -------------==// +//==---------- properties.hpp --- SYCL extended property list --------------==// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -10,9 +10,9 @@ #include #include -#include -#include -#include +#include +#include +#include #include #include @@ -112,7 +112,7 @@ struct ExtractProperties> { } // namespace detail -template class property_list { +template class properties { static_assert(detail::IsTuple::value, "Properties must be in a tuple."); static_assert(detail::AllPropertyValues::value, @@ -124,7 +124,7 @@ template class property_list { public: template - property_list(PropertyValueTs... props) + properties(PropertyValueTs... props) : Storage(detail::ExtractProperties::Extract( std::tuple{props...})) {} @@ -163,25 +163,21 @@ template class property_list { #ifdef __cpp_deduction_guides // Deduction guides template -property_list(PropertyValueTs... props) - -> property_list::type>; +properties(PropertyValueTs... props) + -> properties::type>; #endif -template -using property_list_t = - property_list::type>; - // Property list traits -template struct is_property_list : std::false_type {}; +template struct is_property_list : std::false_type {}; template -struct is_property_list>> - : std::is_same>, - property_list_t> {}; +struct is_property_list>> + : std::is_same< + properties>, + properties::type>> {}; #if __cplusplus > 201402L -template -inline constexpr bool is_property_list_v = - is_property_list::value; +template +inline constexpr bool is_property_list_v = is_property_list::value; #endif } // namespace experimental @@ -192,9 +188,9 @@ inline constexpr bool is_property_list_v = // is_device_copyable template struct is_device_copyable< - ext::oneapi::experimental::property_list, + ext::oneapi::experimental::properties, std::enable_if_t>::value>> + ext::oneapi::experimental::properties>::value>> : is_device_copyable {}; } // namespace sycl diff --git a/sycl/include/sycl/ext/oneapi/property_list/properties.hpp b/sycl/include/sycl/ext/oneapi/properties/property.hpp similarity index 51% rename from sycl/include/sycl/ext/oneapi/property_list/properties.hpp rename to sycl/include/sycl/ext/oneapi/properties/property.hpp index a834986260e43..b41cf8ea93470 100644 --- a/sycl/include/sycl/ext/oneapi/property_list/properties.hpp +++ b/sycl/include/sycl/ext/oneapi/properties/property.hpp @@ -7,25 +7,30 @@ //===----------------------------------------------------------------------===// // HOW-TO: Add new compile-time property -// 1. Add a new enumerator to `sycl::ext::oneapi::detail::PropKind` -// representing the new property. Increment -// `sycl::ext::oneapi::detail::PropKind::PropKindSize` -// 2. Define property class with `value_t` that must be `property_value` with -// the first template argument being the property class itself. -// 3. Add an `inline constexpr` variable in the same namespace as the property. -// The variable should have the same type as `value_t` of the property class -// and should be named as the property class with `_v` appended, e.g. for a -// property `foo`, there should be a definition -// `inline constexpr foo::value_t foo_v`. -// 4. Specialize `sycl::ext::oneapi::detail::PropertyToKind` for the new -// property class. The specialization should have a `Kind` member with the -// value equal to the enumerator added in 1. -// 5. Specialize `sycl::ext::oneapi::detail::IsCompileTimeProperty` for the new -// property class. This specialization should derive from `std::true_type`. -// 6. Specialize `sycl::is_property` and `sycl::is_property_of` for the -// property class. +// 1. Add a new enumerator to +// `sycl::ext::oneapi::experimental::detail::PropKind` representing the new +// property. Increment +// `sycl::ext::oneapi::experimental::detail::PropKind::PropKindSize` +// 2. Define property key class with `value_t` that must be `property_value` +// with the first template argument being the property class itself. The +// name of the key class must be the property name suffixed by `_key`, i.e. +// for a property `foo` the class should be named `foo_key`. +// 3. Add an `inline constexpr` variable in the same namespace as the property +// key. The variable should have the same type as `value_t` of the property +// class, e.g. for a property `foo`, there should be a definition +// `inline constexpr foo_key::value_t foo`. +// 4. Specialize `sycl::ext::oneapi::experimental::is_property` and +// `sycl::ext::oneapi::experimental::is_property_of` for the property key +// class. +// 5. Specialize `sycl::ext::oneapi::experimental::detail::PropertyToKind` for +// the new property key class. The specialization should have a `Kind` +// member with the value equal to the enumerator added in 1. +// 6. Specialize +// `sycl::ext::oneapi::experimental::detail::IsCompileTimeProperty` for the +// new property key class. This specialization should derive from +// `std::true_type`. /******************************** EXAMPLE ************************************** ----------- sycl/include/sycl/ext/oneapi/property_list/properties.hpp ----------- +------------- sycl/include/sycl/ext/oneapi/properties/property.hpp ------------- // (1.) enum PropKind : uint32_t { ... @@ -33,57 +38,55 @@ enum PropKind : uint32_t { PropKindSize = N + 1, // N was the previous value }; ---------------------- path/to/new/property/file.hpp --------------------------- -namespace sycl { -namespace ext { -namespace oneapi { +namespace sycl::ext::oneapi::experimental { // (2.) -struct bar { - using value_t = property_value; +struct bar_key { + using value_t = property_value; }; // (3.) -inline constexpr bar::value_t bar_v; +inline constexpr bar_key::value_t bar; + +// (4.) +template <> struct is_property : std::true_type {}; +// Replace SYCL_OBJ with the SYCL object to support the property. +template <> struct is_property_of : std::true_type {}; namespace detail { -// (4.) -template <> struct PropertyToKind { +// (5.) +template <> struct PropertyToKind { static constexpr PropKind Kind = PropKind::Bar; }; -// (5.) -template <> struct IsCompileTimeProperty : std::true_type {}; - -} // namespace detail -} // namespace oneapi -} // namespace ext - // (6.) -template <> struct is_property : std::true_type {}; -// Replace SYCL_OBJ with the SYCL object to support the property. -template <> struct is_property_of - : std::true_type {}; +template <> struct IsCompileTimeProperty : std::true_type {}; -} // namespace sycl +} // namespace detail +} // namespace sycl::ext::oneapi::experimental *******************************************************************************/ // HOW-TO: Add new runtime property // 1. Add a new enumerator to `sycl::ext::oneapi::detail::PropKind` // representing the new property. Increment -// `sycl::ext::oneapi::detail::PropKind::PropKindSize` +// `sycl::ext::oneapi::experimental::detail::PropKind::PropKindSize` // 2. Define property class. -// 3. Overload the `==` and `!=` operators for the new property class. The +// 3. Declare the property key as an alias to the property class. The name of +// the key class must be the property name suffixed by `_key`, i.e. for a +// property `foo` the class should be named `foo_key`. +// 4. Overload the `==` and `!=` operators for the new property class. The // comparison should compare all data members of the property class. -// 4. Specialize `sycl::ext::oneapi::detail::PropertyToKind` for the new +// 5. Specialize `sycl::ext::oneapi::experimental::is_property` and +// `sycl::ext::oneapi::experimental::is_property_of` for the property class. +// 6. Specialize `sycl::ext::oneapi::detail::PropertyToKind` for the new // property class. The specialization should have a `Kind` member with the // value equal to the enumerator added in 1. -// 5. Specialize `sycl::ext::oneapi::detail::IsRuntimeProperty` for the new -// property class. This specialization should derive from `std::true_type`. -// 6. Specialize `sycl::is_property` and `sycl::is_property_of` for the -// property class. +// 7. Specialize `sycl::ext::oneapi::experimental::detail::IsRuntimeProperty` +// for the new property class. This specialization should derive from +// `std::true_type`. /******************************* EXAMPLE *************************************** ----------- sycl/include/sycl/ext/oneapi/property_list/properties.hpp ----------- +------------- sycl/include/sycl/ext/oneapi/properties/property.hpp ------------- // (1.) enum PropKind : uint32_t { ... @@ -91,9 +94,7 @@ enum PropKind : uint32_t { PropKindSize = N + 1, // N was the previous value }; ---------------------- path/to/new/property/file.hpp --------------------------- -namespace sycl { -namespace ext { -namespace oneapi { +namespace sycl::ext::oneapi::experimental { // (2.) struct foo { @@ -101,7 +102,10 @@ struct foo { int value; }; -// (3.) +// 3. +using foo_key = foo; + +// (4.) inline bool operator==(const foo &lhs, const foo &rhs) { return lhs.value == rhs.value; } @@ -109,26 +113,23 @@ inline bool operator!=(const foo &lhs, const foo &rhs) { return !(lhs == rhs); } +// (5.) +template <> struct is_property_key : std::true_type {}; +// Replace SYCL_OBJ with the SYCL object to support the property. +template <> struct is_property_key_of : std::true_type {}; + namespace detail { -// (4.) +// (6.) template <> struct PropertyToKind { static constexpr PropKind Kind = PropKind::Foo; }; -// (5.) +// (7.) template <> struct IsRuntimeProperty : std::true_type {}; -} // namespace detail -} // namespace oneapi -} // namespace ext - -// (6.) -template <> struct is_property : std::true_type {}; -// Replace SYCL_OBJ with the SYCL object to support the property. -template <> struct is_property_of - : std::true_type {}; -} // namespace sycl +} // namespace detail +} // namespace sycl::ext::oneapi::experimental *******************************************************************************/ #pragma once @@ -162,6 +163,10 @@ template struct IsRuntimeProperty : std::false_type {}; template struct IsCompileTimeProperty : std::false_type {}; } // namespace detail + +template struct is_property_key : std::false_type {}; +template struct is_property_key_of : std::false_type {}; + } // namespace experimental } // namespace oneapi } // namespace ext diff --git a/sycl/include/sycl/ext/oneapi/property_list/property_utils.hpp b/sycl/include/sycl/ext/oneapi/properties/property_utils.hpp similarity index 98% rename from sycl/include/sycl/ext/oneapi/property_list/property_utils.hpp rename to sycl/include/sycl/ext/oneapi/properties/property_utils.hpp index 5884c79c48d4a..74a5810810473 100644 --- a/sycl/include/sycl/ext/oneapi/property_list/property_utils.hpp +++ b/sycl/include/sycl/ext/oneapi/properties/property_utils.hpp @@ -9,7 +9,7 @@ #pragma once #include -#include +#include #include @@ -20,7 +20,7 @@ namespace oneapi { namespace experimental { // Forward declaration -template struct property_value; +template struct property_value; namespace detail { diff --git a/sycl/include/sycl/ext/oneapi/property_list/property_value.hpp b/sycl/include/sycl/ext/oneapi/properties/property_value.hpp similarity index 69% rename from sycl/include/sycl/ext/oneapi/property_list/property_value.hpp rename to sycl/include/sycl/ext/oneapi/properties/property_value.hpp index b79c63427eaf1..3acae70c2952d 100644 --- a/sycl/include/sycl/ext/oneapi/property_list/property_value.hpp +++ b/sycl/include/sycl/ext/oneapi/properties/property_value.hpp @@ -8,8 +8,8 @@ #pragma once -#include -#include +#include +#include __SYCL_INLINE_NAMESPACE(cl) { namespace sycl { @@ -25,12 +25,12 @@ struct SingleTypePropertyValueBase {}; struct EmptyPropertyValueBase {}; // Base class for property values with a single non-type value -template struct SingleNontypePropertyValueBase { +template struct SingleNontypePropertyValueBase { static constexpr auto value = T::value; }; // Helper class for property values with a single value -template +template struct SinglePropertyValue : public sycl::detail::conditional_t::value, SingleNontypePropertyValueBase, @@ -40,13 +40,15 @@ struct SinglePropertyValue } // namespace detail -template +template struct property_value : public sycl::detail::conditional_t< sizeof...(Ts) == 0 && !std::is_same::value, - detail::SinglePropertyValue, detail::EmptyPropertyValueBase> {}; + detail::SinglePropertyValue, detail::EmptyPropertyValueBase> { + using key_t = PropertyT; +}; -template +template constexpr std::enable_if_t::value, bool> operator==(const property_value &LHS, @@ -54,7 +56,7 @@ operator==(const property_value &LHS, return (std::is_same::value && ...); } -template +template constexpr std::enable_if_t::value, bool> operator!=(const property_value &LHS, @@ -62,6 +64,22 @@ operator!=(const property_value &LHS, return (!std::is_same::value || ...); } +template struct is_property_value { + static constexpr bool value = + detail::IsRuntimeProperty::value && is_property_key::value; +}; +template struct is_property_value_of { + static constexpr bool value = + detail::IsRuntimeProperty::value && is_property_key_of::value; +}; +// Specialization for compile-time-constant properties +template +struct is_property_value> + : is_property_key {}; +template +struct is_property_value_of> + : is_property_key_of {}; + namespace detail { // Specialization of PropertyID for propagating IDs through property_value. diff --git a/sycl/test/extensions/property_list/mock_compile_time_properties.hpp b/sycl/test/extensions/properties/mock_compile_time_properties.hpp similarity index 54% rename from sycl/test/extensions/property_list/mock_compile_time_properties.hpp rename to sycl/test/extensions/properties/mock_compile_time_properties.hpp index 1e54f011ce9db..61ff723379346 100644 --- a/sycl/test/extensions/property_list/mock_compile_time_properties.hpp +++ b/sycl/test/extensions/properties/mock_compile_time_properties.hpp @@ -17,17 +17,17 @@ namespace ext { namespace oneapi { namespace experimental { -struct bar { - using value_t = property_value; +struct bar_key { + using value_t = property_value; }; -struct baz { +struct baz_key { template - using value_t = property_value>; + using value_t = property_value>; }; -struct boo { - template using value_t = property_value; +struct boo_key { + template using value_t = property_value; }; struct foo { @@ -56,69 +56,60 @@ inline bool operator==(const foz &lhs, const foz &rhs) { } inline bool operator!=(const foz &lhs, const foz &rhs) { return !(lhs == rhs); } +inline constexpr bar_key::value_t bar; +template inline constexpr baz_key::value_t baz; +template inline constexpr boo_key::value_t boo; + +using foo_key = foo; +using foz_key = foz; + +template <> struct is_property_key : std::true_type {}; +template <> struct is_property_key : std::true_type {}; +template <> struct is_property_key : std::true_type {}; +template <> struct is_property_key : std::true_type {}; +template <> struct is_property_key : std::true_type {}; + +template +struct is_property_key_of : std::true_type {}; +template +struct is_property_key_of : std::true_type {}; +template +struct is_property_key_of : std::true_type {}; +template +struct is_property_key_of : std::true_type {}; +template +struct is_property_key_of : std::true_type {}; + namespace detail { -template <> struct PropertyToKind { +template <> struct PropertyToKind { static constexpr PropKind Kind = static_cast(PropKind::PropKindSize + 0); }; -template <> struct PropertyToKind { +template <> struct PropertyToKind { static constexpr PropKind Kind = static_cast(PropKind::PropKindSize + 1); }; -template <> struct PropertyToKind { +template <> struct PropertyToKind { static constexpr PropKind Kind = static_cast(PropKind::PropKindSize + 2); }; -template <> struct PropertyToKind { +template <> struct PropertyToKind { static constexpr PropKind Kind = static_cast(PropKind::PropKindSize + 3); }; -template <> struct PropertyToKind { +template <> struct PropertyToKind { static constexpr PropKind Kind = static_cast(PropKind::PropKindSize + 4); }; -template <> struct IsCompileTimeProperty : std::true_type {}; -template <> struct IsCompileTimeProperty : std::true_type {}; -template <> struct IsCompileTimeProperty : std::true_type {}; +template <> struct IsCompileTimeProperty : std::true_type {}; +template <> struct IsCompileTimeProperty : std::true_type {}; +template <> struct IsCompileTimeProperty : std::true_type {}; -template <> struct IsRuntimeProperty : std::true_type {}; -template <> struct IsRuntimeProperty : std::true_type {}; +template <> struct IsRuntimeProperty : std::true_type {}; +template <> struct IsRuntimeProperty : std::true_type {}; } // namespace detail - -inline constexpr bar::value_t bar_v; -template inline constexpr baz::value_t baz_v; -template inline constexpr boo::value_t boo_v; - } // namespace experimental } // namespace oneapi } // namespace ext - -template <> -struct is_property : std::true_type {}; -template <> -struct is_property : std::true_type {}; -template <> -struct is_property : std::true_type {}; -template <> -struct is_property : std::true_type {}; -template <> -struct is_property : 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 {}; - } // namespace sycl diff --git a/sycl/test/extensions/property_list/property_list_ctor_negative.cpp b/sycl/test/extensions/properties/properties_ctor_negative.cpp similarity index 90% rename from sycl/test/extensions/property_list/property_list_ctor_negative.cpp rename to sycl/test/extensions/properties/properties_ctor_negative.cpp index 873dfd71c9c38..a884e4d9d0df5 100644 --- a/sycl/test/extensions/property_list/property_list_ctor_negative.cpp +++ b/sycl/test/extensions/properties/properties_ctor_negative.cpp @@ -13,21 +13,21 @@ int main() { #if (TEST_CASE == 1) - auto InvalidPropertyList = sycl::ext::oneapi::experimental::property_list(1); + auto InvalidPropertyList = sycl::ext::oneapi::experimental::properties(1); // CHECK-ERROR-1: Unrecognized property in property list. #elif (TEST_CASE == 2) - auto InvalidPropertyList = sycl::ext::oneapi::experimental::property_list( + auto InvalidPropertyList = sycl::ext::oneapi::experimental::properties( sycl::ext::oneapi::experimental::foo{1}, true); // CHECK-ERROR-2: Unrecognized property in property list. #elif (TEST_CASE == 3) - auto InvalidPropertyList = sycl::ext::oneapi::experimental::property_list( + auto InvalidPropertyList = sycl::ext::oneapi::experimental::properties( sycl::ext::oneapi::experimental::foo{0}, sycl::ext::oneapi::experimental::foo{1}); // CHECK-ERROR-3: Duplicate properties in property list. #elif (TEST_CASE == 4) - auto InvalidPropertyList = sycl::ext::oneapi::experimental::property_list( - sycl::ext::oneapi::experimental::bar_v, - sycl::ext::oneapi::experimental::bar_v); + auto InvalidPropertyList = sycl::ext::oneapi::experimental::properties( + sycl::ext::oneapi::experimental::bar, + sycl::ext::oneapi::experimental::bar); // CHECK-ERROR-4: Duplicate properties in property list. #endif } diff --git a/sycl/test/extensions/property_list/property_list_device_copyable.cpp b/sycl/test/extensions/properties/properties_device_copyable.cpp similarity index 60% rename from sycl/test/extensions/property_list/property_list_device_copyable.cpp rename to sycl/test/extensions/properties/properties_device_copyable.cpp index 384d5ebec611a..9393673560693 100644 --- a/sycl/test/extensions/property_list/property_list_device_copyable.cpp +++ b/sycl/test/extensions/properties/properties_device_copyable.cpp @@ -13,51 +13,51 @@ class TestClass2 {}; int main() { // Check only compile-time properties are device-copyable - using P1 = sycl::ext::oneapi::experimental::property_list_t< - sycl::ext::oneapi::experimental::baz::value_t<1>, - sycl::ext::oneapi::experimental::boo::value_t, - sycl::ext::oneapi::experimental::bar::value_t>; + using P1 = decltype(sycl::ext::oneapi::experimental::properties( + sycl::ext::oneapi::experimental::baz<1>, + sycl::ext::oneapi::experimental::boo, + sycl::ext::oneapi::experimental::bar)); static_assert(sycl::is_device_copyable_v< - sycl::ext::oneapi::experimental::baz::value_t<1>>); + sycl::ext::oneapi::experimental::baz_key::value_t<1>>); static_assert( - sycl::is_device_copyable_v>); + sycl::is_device_copyable_v>); static_assert(sycl::is_device_copyable_v< - sycl::ext::oneapi::experimental::bar::value_t>); + sycl::ext::oneapi::experimental::bar_key::value_t>); static_assert(sycl::is_device_copyable_v); // Check property list with non-device-copyable property - using P2 = sycl::ext::oneapi::experimental::property_list_t< - sycl::ext::oneapi::experimental::bar::value_t, - sycl::ext::oneapi::experimental::foz>; + using P2 = decltype(sycl::ext::oneapi::experimental::properties( + sycl::ext::oneapi::experimental::bar, + sycl::ext::oneapi::experimental::foz{42.42, false})); static_assert( !sycl::is_device_copyable_v); static_assert(!sycl::is_device_copyable_v); // Check property list with device-copyable compile-time and runtime // properties - using P3 = sycl::ext::oneapi::experimental::property_list_t< - sycl::ext::oneapi::experimental::baz::value_t<1>, - sycl::ext::oneapi::experimental::foo>; + using P3 = decltype(sycl::ext::oneapi::experimental::properties( + sycl::ext::oneapi::experimental::baz<1>, + sycl::ext::oneapi::experimental::foo{1234})); static_assert( sycl::is_device_copyable_v); static_assert(sycl::is_device_copyable_v); // Check that device-copyable property list can indeed be used in a kernel - const auto PropertyList = sycl::ext::oneapi::experimental::property_list( - sycl::ext::oneapi::experimental::baz_v<1>, + const auto PropertyList = sycl::ext::oneapi::experimental::properties( + sycl::ext::oneapi::experimental::baz<1>, sycl::ext::oneapi::experimental::foo{0}); sycl::queue Q; Q.submit([&](sycl::handler &CGH) { CGH.single_task([=]() { decltype(PropertyList)::has_property< - sycl::ext::oneapi::experimental::baz>(); + sycl::ext::oneapi::experimental::baz_key>(); decltype(PropertyList)::has_property< - sycl::ext::oneapi::experimental::foo>(); - PropertyList.get_property(); - PropertyList.get_property(); + sycl::ext::oneapi::experimental::foo_key>(); + PropertyList.get_property(); + PropertyList.get_property(); }); }); } diff --git a/sycl/test/extensions/properties/properties_equality.cpp b/sycl/test/extensions/properties/properties_equality.cpp new file mode 100644 index 0000000000000..f00b5a2c77757 --- /dev/null +++ b/sycl/test/extensions/properties/properties_equality.cpp @@ -0,0 +1,16 @@ +// RUN: %clangxx -fsycl -fsycl-targets=%sycl_triple %s -o %t.out +// RUN: %t.out + +#include + +#include "mock_compile_time_properties.hpp" + +int main() { + using P1 = decltype(sycl::ext::oneapi::experimental::properties( + sycl::ext::oneapi::experimental::baz<1>, + sycl::ext::oneapi::experimental::bar)); + using P2 = decltype(sycl::ext::oneapi::experimental::properties( + sycl::ext::oneapi::experimental::bar, + sycl::ext::oneapi::experimental::baz<1>)); + static_assert(std::is_same::value); +} diff --git a/sycl/test/extensions/properties/properties_get_property.cpp b/sycl/test/extensions/properties/properties_get_property.cpp new file mode 100644 index 0000000000000..f1f586278df0b --- /dev/null +++ b/sycl/test/extensions/properties/properties_get_property.cpp @@ -0,0 +1,39 @@ +// RUN: %clangxx -fsycl -fsycl-targets=%sycl_triple %s -o %t.out +// RUN: %t.out + +#include + +#include "mock_compile_time_properties.hpp" + +int main() { + using P1 = decltype(sycl::ext::oneapi::experimental::properties( + sycl::ext::oneapi::experimental::baz<1>, + sycl::ext::oneapi::experimental::bar)); + // Check that get_property of compile-time properties are the same as _v + static_assert(P1::get_property() == + sycl::ext::oneapi::experimental::baz<1>); + static_assert(P1::get_property() == + sycl::ext::oneapi::experimental::bar); + + // Check value on returned property + static_assert( + P1::get_property().value == 1); + + // Check runtime and compile-time properties on property-list object + sycl::queue Q; + sycl::ext::oneapi::experimental::foo FooProp{3}; + auto PropertyList = sycl::ext::oneapi::experimental::properties( + sycl::ext::oneapi::experimental::baz<1>, + sycl::ext::oneapi::experimental::bar, FooProp); + static_assert(decltype(PropertyList)::get_property< + sycl::ext::oneapi::experimental::baz_key>() == + sycl::ext::oneapi::experimental::baz<1>); + static_assert(decltype(PropertyList)::get_property< + sycl::ext::oneapi::experimental::bar_key>() == + sycl::ext::oneapi::experimental::bar); + assert( + PropertyList.get_property() == + FooProp); + assert(PropertyList.get_property() + .value == FooProp.value); +} diff --git a/sycl/test/extensions/property_list/property_list_get_property_negative.cpp b/sycl/test/extensions/properties/properties_get_property_negative.cpp similarity index 84% rename from sycl/test/extensions/property_list/property_list_get_property_negative.cpp rename to sycl/test/extensions/properties/properties_get_property_negative.cpp index 95017f07c9093..ea6df95488942 100644 --- a/sycl/test/extensions/property_list/property_list_get_property_negative.cpp +++ b/sycl/test/extensions/properties/properties_get_property_negative.cpp @@ -12,26 +12,27 @@ #include "mock_compile_time_properties.hpp" int main() { - auto EmptyPropertyList = sycl::ext::oneapi::experimental::property_list(); + auto EmptyPropertyList = sycl::ext::oneapi::experimental::properties(); #if (TEST_CASE == 1) decltype(EmptyPropertyList)::get_property< - sycl::ext::oneapi::experimental::boo>(); + sycl::ext::oneapi::experimental::boo_key>(); // CHECK-ERROR-1: Property list does not contain the requested property. #elif (TEST_CASE == 2) - EmptyPropertyList.get_property(); + EmptyPropertyList.get_property(); // CHECK-ERROR-2: Property list does not contain the requested property. #endif sycl::queue Q; - auto PopulatedPropertyList = sycl::ext::oneapi::experimental::property_list( + auto PopulatedPropertyList = sycl::ext::oneapi::experimental::properties( sycl::ext::oneapi::experimental::foz{.0f, true}, - sycl::ext::oneapi::experimental::bar_v); + sycl::ext::oneapi::experimental::bar); #if (TEST_CASE == 3) decltype(PopulatedPropertyList)::get_property< - sycl::ext::oneapi::experimental::boo>(); + sycl::ext::oneapi::experimental::boo_key>(); // CHECK-ERROR-3: Property list does not contain the requested property. #elif (TEST_CASE == 4) - PopulatedPropertyList.get_property(); + PopulatedPropertyList + .get_property(); // CHECK-ERROR-4: Property list does not contain the requested property. #endif } diff --git a/sycl/test/extensions/property_list/property_list_has_property.cpp b/sycl/test/extensions/properties/properties_has_property.cpp similarity index 63% rename from sycl/test/extensions/property_list/property_list_has_property.cpp rename to sycl/test/extensions/properties/properties_has_property.cpp index ee374d7d31c3a..cbb6cf3f48696 100644 --- a/sycl/test/extensions/property_list/property_list_has_property.cpp +++ b/sycl/test/extensions/properties/properties_has_property.cpp @@ -7,32 +7,32 @@ int main() { // Check has_property for compile-time properties - using P1 = sycl::ext::oneapi::experimental::property_list_t< - sycl::ext::oneapi::experimental::baz::value_t<1>, - sycl::ext::oneapi::experimental::bar::value_t>; - static_assert(P1::has_property()); - static_assert(P1::has_property()); - static_assert(!P1::has_property()); - static_assert(!P1::has_property()); - static_assert(!P1::has_property()); + using P1 = decltype(sycl::ext::oneapi::experimental::properties( + sycl::ext::oneapi::experimental::baz<1>, + sycl::ext::oneapi::experimental::bar)); + static_assert(P1::has_property()); + static_assert(P1::has_property()); + static_assert(!P1::has_property()); + static_assert(!P1::has_property()); + static_assert(!P1::has_property()); // Check has_property for runtime properties - using P2 = sycl::ext::oneapi::experimental::property_list_t< - sycl::ext::oneapi::experimental::foo, - sycl::ext::oneapi::experimental::foz>; - static_assert(!P2::has_property()); - static_assert(!P2::has_property()); - static_assert(!P2::has_property()); - static_assert(P2::has_property()); - static_assert(P2::has_property()); + using P2 = decltype(sycl::ext::oneapi::experimental::properties( + sycl::ext::oneapi::experimental::foo{2}, + sycl::ext::oneapi::experimental::foz{1.23, true})); + static_assert(!P2::has_property()); + static_assert(!P2::has_property()); + static_assert(!P2::has_property()); + static_assert(P2::has_property()); + static_assert(P2::has_property()); // Check has_property for a mix properties - using P3 = sycl::ext::oneapi::experimental::property_list_t< - sycl::ext::oneapi::experimental::foo, - sycl::ext::oneapi::experimental::baz::value_t<1>>; - static_assert(!P3::has_property()); - static_assert(P3::has_property()); - static_assert(!P3::has_property()); - static_assert(P3::has_property()); - static_assert(!P3::has_property()); + using P3 = decltype(sycl::ext::oneapi::experimental::properties( + sycl::ext::oneapi::experimental::foo{1000}, + sycl::ext::oneapi::experimental::baz<1>)); + static_assert(!P3::has_property()); + static_assert(P3::has_property()); + static_assert(!P3::has_property()); + static_assert(P3::has_property()); + static_assert(!P3::has_property()); } diff --git a/sycl/test/extensions/properties/properties_is_property_key.cpp b/sycl/test/extensions/properties/properties_is_property_key.cpp new file mode 100644 index 0000000000000..bbf410770e8cb --- /dev/null +++ b/sycl/test/extensions/properties/properties_is_property_key.cpp @@ -0,0 +1,89 @@ +// RUN: %clangxx -fsycl -fsycl-targets=%sycl_triple %s -o %t.out +// RUN: %t.out + +#include + +#include "mock_compile_time_properties.hpp" + +class NotAPropertyKey {}; + +int main() { + // Check is_property_key for compile-time property keys. + static_assert(sycl::ext::oneapi::experimental::is_property_key< + sycl::ext::oneapi::experimental::bar_key>::value); + static_assert(sycl::ext::oneapi::experimental::is_property_key< + sycl::ext::oneapi::experimental::baz_key>::value); + static_assert(sycl::ext::oneapi::experimental::is_property_key< + sycl::ext::oneapi::experimental::boo_key>::value); + + // Check is_property_key for runtime property keys. + static_assert(sycl::ext::oneapi::experimental::is_property_key< + sycl::ext::oneapi::experimental::foo_key>::value); + static_assert(sycl::ext::oneapi::experimental::is_property_key< + sycl::ext::oneapi::experimental::foz_key>::value); + + // Check is_property_key for compile-time property values. + static_assert(!sycl::ext::oneapi::experimental::is_property_key< + decltype(sycl::ext::oneapi::experimental::bar)>::value); + static_assert(!sycl::ext::oneapi::experimental::is_property_key< + decltype(sycl::ext::oneapi::experimental::baz<42>)>::value); + static_assert(!sycl::ext::oneapi::experimental::is_property_key< + decltype(sycl::ext::oneapi::experimental::boo)>::value); + static_assert( + !sycl::ext::oneapi::experimental::is_property_key< + decltype(sycl::ext::oneapi::experimental::boo)>::value); + + // Check is_property_key for runtime property values. + // NOTE: For runtime properties the key is an alias of the value. + static_assert(sycl::ext::oneapi::experimental::is_property_key< + sycl::ext::oneapi::experimental::foo>::value); + static_assert(sycl::ext::oneapi::experimental::is_property_key< + sycl::ext::oneapi::experimental::foz>::value); + + // Check is_property_key for non-property-key types. + static_assert(!sycl::ext::oneapi::experimental::is_property_key::value); + static_assert(!sycl::ext::oneapi::experimental::is_property_key< + NotAPropertyKey>::value); + + // Check is_property_key_of for compile-time property keys. + static_assert(sycl::ext::oneapi::experimental::is_property_key_of< + sycl::ext::oneapi::experimental::bar_key, sycl::queue>::value); + static_assert(sycl::ext::oneapi::experimental::is_property_key_of< + sycl::ext::oneapi::experimental::baz_key, sycl::queue>::value); + static_assert(sycl::ext::oneapi::experimental::is_property_key_of< + sycl::ext::oneapi::experimental::boo_key, sycl::queue>::value); + + // Check is_property_key_of for runtime property keys. + static_assert(sycl::ext::oneapi::experimental::is_property_key_of< + sycl::ext::oneapi::experimental::foo_key, sycl::queue>::value); + static_assert(sycl::ext::oneapi::experimental::is_property_key_of< + sycl::ext::oneapi::experimental::foz_key, sycl::queue>::value); + + // Check is_property_key_of for compile-time property values. + static_assert(!sycl::ext::oneapi::experimental::is_property_key< + decltype(sycl::ext::oneapi::experimental::bar)>::value); + static_assert(!sycl::ext::oneapi::experimental::is_property_key_of< + decltype(sycl::ext::oneapi::experimental::baz<42>), + sycl::queue>::value); + static_assert(!sycl::ext::oneapi::experimental::is_property_key_of< + decltype(sycl::ext::oneapi::experimental::boo), + sycl::queue>::value); + static_assert(!sycl::ext::oneapi::experimental::is_property_key_of< + decltype(sycl::ext::oneapi::experimental::boo), + sycl::queue>::value); + + // Check is_property_key_of for runtime property keys. + // NOTE: For runtime properties the key is an alias of the value. + static_assert(sycl::ext::oneapi::experimental::is_property_key_of< + sycl::ext::oneapi::experimental::foo, sycl::queue>::value); + static_assert(sycl::ext::oneapi::experimental::is_property_key_of< + sycl::ext::oneapi::experimental::foz, sycl::queue>::value); + + // Check is_property_key_of for non-property-key types. + static_assert( + !sycl::ext::oneapi::experimental::is_property_key_of::value); + static_assert( + !sycl::ext::oneapi::experimental::is_property_key_of::value); +} \ No newline at end of file diff --git a/sycl/test/extensions/property_list/property_list_is_property_list.cpp b/sycl/test/extensions/properties/properties_is_property_list.cpp similarity index 72% rename from sycl/test/extensions/property_list/property_list_is_property_list.cpp rename to sycl/test/extensions/properties/properties_is_property_list.cpp index de860cfa5a6d9..10255caf3afc0 100644 --- a/sycl/test/extensions/property_list/property_list_is_property_list.cpp +++ b/sycl/test/extensions/properties/properties_is_property_list.cpp @@ -7,37 +7,37 @@ int main() { // Check is_property_list for empty property list - using EmptyP = sycl::ext::oneapi::experimental::property_list_t<>; + using EmptyP = decltype(sycl::ext::oneapi::experimental::properties()); static_assert( sycl::ext::oneapi::experimental::is_property_list::value); static_assert(sycl::ext::oneapi::experimental::is_property_list_v); // Check is_property_list for compile-time properties - using P1 = sycl::ext::oneapi::experimental::property_list_t< - sycl::ext::oneapi::experimental::baz::value_t<1>, - sycl::ext::oneapi::experimental::bar::value_t>; + using P1 = decltype(sycl::ext::oneapi::experimental::properties( + sycl::ext::oneapi::experimental::baz<1>, + sycl::ext::oneapi::experimental::bar)); static_assert(sycl::ext::oneapi::experimental::is_property_list::value); static_assert(sycl::ext::oneapi::experimental::is_property_list_v); // Check is_property_list for runtime properties - using P2 = sycl::ext::oneapi::experimental::property_list_t< - sycl::ext::oneapi::experimental::foo, - sycl::ext::oneapi::experimental::foz>; + using P2 = decltype(sycl::ext::oneapi::experimental::properties( + sycl::ext::oneapi::experimental::foo{42}, + sycl::ext::oneapi::experimental::foz{3.14159265, false})); static_assert(sycl::ext::oneapi::experimental::is_property_list::value); static_assert(sycl::ext::oneapi::experimental::is_property_list_v); // Check is_property_list for a mix properties - using P3 = sycl::ext::oneapi::experimental::property_list_t< - sycl::ext::oneapi::experimental::foo, - sycl::ext::oneapi::experimental::baz::value_t<1>, - sycl::ext::oneapi::experimental::foz>; + using P3 = decltype(sycl::ext::oneapi::experimental::properties( + sycl::ext::oneapi::experimental::foo{0}, + sycl::ext::oneapi::experimental::baz<1>, + sycl::ext::oneapi::experimental::foz{1.2, true})); static_assert(sycl::ext::oneapi::experimental::is_property_list::value); static_assert(sycl::ext::oneapi::experimental::is_property_list_v); // Check is_property_list for compile-time properties on object - auto PropertyList1 = sycl::ext::oneapi::experimental::property_list( - sycl::ext::oneapi::experimental::baz_v<1>, - sycl::ext::oneapi::experimental::bar_v); + auto PropertyList1 = sycl::ext::oneapi::experimental::properties( + sycl::ext::oneapi::experimental::baz<1>, + sycl::ext::oneapi::experimental::bar); static_assert(sycl::ext::oneapi::experimental::is_property_list< decltype(PropertyList1)>::value); static_assert(sycl::ext::oneapi::experimental::is_property_list_v< @@ -45,7 +45,7 @@ int main() { // Check is_property_list for runtime properties on object sycl::queue Q; - auto PropertyList2 = sycl::ext::oneapi::experimental::property_list( + auto PropertyList2 = sycl::ext::oneapi::experimental::properties( sycl::ext::oneapi::experimental::foo{1}, sycl::ext::oneapi::experimental::foz{.123f, false}); static_assert(sycl::ext::oneapi::experimental::is_property_list< @@ -54,9 +54,9 @@ int main() { decltype(PropertyList2)>); // Check is_property_list for a mix properties on object - auto PropertyList3 = sycl::ext::oneapi::experimental::property_list( + auto PropertyList3 = sycl::ext::oneapi::experimental::properties( sycl::ext::oneapi::experimental::foo{42}, - sycl::ext::oneapi::experimental::baz_v<1>); + sycl::ext::oneapi::experimental::baz<1>); static_assert(sycl::ext::oneapi::experimental::is_property_list< decltype(PropertyList3)>::value); static_assert(sycl::ext::oneapi::experimental::is_property_list_v< diff --git a/sycl/test/extensions/properties/properties_is_property_value.cpp b/sycl/test/extensions/properties/properties_is_property_value.cpp new file mode 100644 index 0000000000000..8e0bebc5a47d4 --- /dev/null +++ b/sycl/test/extensions/properties/properties_is_property_value.cpp @@ -0,0 +1,88 @@ +// RUN: %clangxx -fsycl -fsycl-targets=%sycl_triple %s -o %t.out +// RUN: %t.out + +#include + +#include "mock_compile_time_properties.hpp" + +class NotAPropertyKey {}; + +int main() { + // Check is_property_value for compile-time property values. + static_assert(sycl::ext::oneapi::experimental::is_property_value< + decltype(sycl::ext::oneapi::experimental::bar)>::value); + static_assert(sycl::ext::oneapi::experimental::is_property_value< + decltype(sycl::ext::oneapi::experimental::baz<42>)>::value); + static_assert(sycl::ext::oneapi::experimental::is_property_value< + decltype(sycl::ext::oneapi::experimental::boo)>::value); + static_assert( + sycl::ext::oneapi::experimental::is_property_value< + decltype(sycl::ext::oneapi::experimental::boo)>::value); + + // Check is_property_value for runtime property values. + static_assert(sycl::ext::oneapi::experimental::is_property_value< + sycl::ext::oneapi::experimental::foo>::value); + static_assert(sycl::ext::oneapi::experimental::is_property_value< + sycl::ext::oneapi::experimental::foz>::value); + + // Check is_property_value for compile-time property keys. + static_assert(!sycl::ext::oneapi::experimental::is_property_value< + sycl::ext::oneapi::experimental::bar_key>::value); + static_assert(!sycl::ext::oneapi::experimental::is_property_value< + sycl::ext::oneapi::experimental::baz_key>::value); + static_assert(!sycl::ext::oneapi::experimental::is_property_value< + sycl::ext::oneapi::experimental::boo_key>::value); + + // Check is_property_value for runtime property keys. + // NOTE: For runtime properties the key is an alias of the value. + static_assert(sycl::ext::oneapi::experimental::is_property_value< + sycl::ext::oneapi::experimental::foo_key>::value); + static_assert(sycl::ext::oneapi::experimental::is_property_value< + sycl::ext::oneapi::experimental::foz_key>::value); + + // Check is_property_value for non-property-key types. + static_assert( + !sycl::ext::oneapi::experimental::is_property_value::value); + static_assert(!sycl::ext::oneapi::experimental::is_property_value< + NotAPropertyKey>::value); + + // Check is_property_value_of for compile-time property values. + static_assert(sycl::ext::oneapi::experimental::is_property_value< + decltype(sycl::ext::oneapi::experimental::bar)>::value); + static_assert(sycl::ext::oneapi::experimental::is_property_value_of< + decltype(sycl::ext::oneapi::experimental::baz<42>), + sycl::queue>::value); + static_assert(sycl::ext::oneapi::experimental::is_property_value_of< + decltype(sycl::ext::oneapi::experimental::boo), + sycl::queue>::value); + static_assert(sycl::ext::oneapi::experimental::is_property_value_of< + decltype(sycl::ext::oneapi::experimental::boo), + sycl::queue>::value); + + // Check is_property_value_of for runtime property keys. + static_assert(sycl::ext::oneapi::experimental::is_property_value_of< + sycl::ext::oneapi::experimental::foo, sycl::queue>::value); + static_assert(sycl::ext::oneapi::experimental::is_property_value_of< + sycl::ext::oneapi::experimental::foz, sycl::queue>::value); + + // Check is_property_value_of for compile-time property keys. + static_assert(!sycl::ext::oneapi::experimental::is_property_value_of< + sycl::ext::oneapi::experimental::bar_key, sycl::queue>::value); + static_assert(!sycl::ext::oneapi::experimental::is_property_value_of< + sycl::ext::oneapi::experimental::baz_key, sycl::queue>::value); + static_assert(!sycl::ext::oneapi::experimental::is_property_value_of< + sycl::ext::oneapi::experimental::boo_key, sycl::queue>::value); + + // Check is_property_value_of for runtime property keys. + // NOTE: For runtime properties the key is an alias of the value. + static_assert(sycl::ext::oneapi::experimental::is_property_value_of< + sycl::ext::oneapi::experimental::foo_key, sycl::queue>::value); + static_assert(sycl::ext::oneapi::experimental::is_property_value_of< + sycl::ext::oneapi::experimental::foz_key, sycl::queue>::value); + + // Check is_property_value_of for non-property-key types. + static_assert(!sycl::ext::oneapi::experimental::is_property_value_of< + int, sycl::queue>::value); + static_assert(!sycl::ext::oneapi::experimental::is_property_value_of< + NotAPropertyKey, sycl::queue>::value); +} \ No newline at end of file diff --git a/sycl/test/extensions/property_list/property_list_equality.cpp b/sycl/test/extensions/property_list/property_list_equality.cpp deleted file mode 100644 index aab8b1d5365c1..0000000000000 --- a/sycl/test/extensions/property_list/property_list_equality.cpp +++ /dev/null @@ -1,16 +0,0 @@ -// RUN: %clangxx -fsycl -fsycl-targets=%sycl_triple %s -o %t.out -// RUN: %t.out - -#include - -#include "mock_compile_time_properties.hpp" - -int main() { - using P1 = sycl::ext::oneapi::experimental::property_list_t< - sycl::ext::oneapi::experimental::baz::value_t<1>, - sycl::ext::oneapi::experimental::bar::value_t>; - using P2 = sycl::ext::oneapi::experimental::property_list_t< - sycl::ext::oneapi::experimental::bar::value_t, - sycl::ext::oneapi::experimental::baz::value_t<1>>; - static_assert(std::is_same::value); -} diff --git a/sycl/test/extensions/property_list/property_list_get_property.cpp b/sycl/test/extensions/property_list/property_list_get_property.cpp deleted file mode 100644 index f4300db36b360..0000000000000 --- a/sycl/test/extensions/property_list/property_list_get_property.cpp +++ /dev/null @@ -1,39 +0,0 @@ -// RUN: %clangxx -fsycl -fsycl-targets=%sycl_triple %s -o %t.out -// RUN: %t.out - -#include - -#include "mock_compile_time_properties.hpp" - -int main() { - using P1 = sycl::ext::oneapi::experimental::property_list_t< - sycl::ext::oneapi::experimental::baz::value_t<1>, - sycl::ext::oneapi::experimental::bar::value_t>; - // Check that get_property of compile-time properties are the same as _v - static_assert(P1::get_property() == - sycl::ext::oneapi::experimental::baz_v<1>); - static_assert(P1::get_property() == - sycl::ext::oneapi::experimental::bar_v); - - // Check value on returned property - static_assert( - P1::get_property().value == 1); - - // Check runtime and compile-time properties on property-list object - sycl::queue Q; - sycl::ext::oneapi::experimental::foo FooProp{3}; - auto PropertyList = sycl::ext::oneapi::experimental::property_list( - sycl::ext::oneapi::experimental::baz_v<1>, - sycl::ext::oneapi::experimental::bar_v, FooProp); - static_assert(decltype(PropertyList)::get_property< - sycl::ext::oneapi::experimental::baz>() == - sycl::ext::oneapi::experimental::baz_v<1>); - static_assert(decltype(PropertyList)::get_property< - sycl::ext::oneapi::experimental::bar>() == - sycl::ext::oneapi::experimental::bar_v); - assert(PropertyList.get_property() == - FooProp); - assert( - PropertyList.get_property().value == - FooProp.value); -} From 335be0cf5ae1809db1c3cf8280dd43977ad6eb85 Mon Sep 17 00:00:00 2001 From: Steffen Larsen Date: Fri, 21 Jan 2022 16:12:05 +0300 Subject: [PATCH 12/24] XFAIL properties_device_copyable on HIP backend Signed-off-by: Steffen Larsen --- .../test/extensions/properties/properties_device_copyable.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sycl/test/extensions/properties/properties_device_copyable.cpp b/sycl/test/extensions/properties/properties_device_copyable.cpp index 9393673560693..91cc894a4d402 100644 --- a/sycl/test/extensions/properties/properties_device_copyable.cpp +++ b/sycl/test/extensions/properties/properties_device_copyable.cpp @@ -1,8 +1,8 @@ // RUN: %clangxx -fsycl -fsycl-targets=%sycl_triple %s -o %t.out // RUN: %t.out -// CUDA backend currently generates invalid binaries for this -// XFAIL: cuda +// CUDA and HIP backends currently generates invalid binaries for this +// XFAIL: cuda && hip_amd #include From 5e6cbac8705074f43931131a10c82a665b5ca621 Mon Sep 17 00:00:00 2001 From: Steffen Larsen Date: Fri, 21 Jan 2022 16:41:36 +0300 Subject: [PATCH 13/24] Fix XFAIL Signed-off-by: Steffen Larsen --- sycl/test/extensions/properties/properties_device_copyable.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sycl/test/extensions/properties/properties_device_copyable.cpp b/sycl/test/extensions/properties/properties_device_copyable.cpp index 91cc894a4d402..a0225fc517137 100644 --- a/sycl/test/extensions/properties/properties_device_copyable.cpp +++ b/sycl/test/extensions/properties/properties_device_copyable.cpp @@ -2,7 +2,7 @@ // RUN: %t.out // CUDA and HIP backends currently generates invalid binaries for this -// XFAIL: cuda && hip_amd +// XFAIL: cuda || hip #include From 83a9875f17499d1081dbbaaf709155b415720532 Mon Sep 17 00:00:00 2001 From: Steffen Larsen Date: Fri, 21 Jan 2022 17:04:26 +0300 Subject: [PATCH 14/24] Fix XFAIL part 2 Signed-off-by: Steffen Larsen --- sycl/test/extensions/properties/properties_device_copyable.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sycl/test/extensions/properties/properties_device_copyable.cpp b/sycl/test/extensions/properties/properties_device_copyable.cpp index a0225fc517137..8887917d8a359 100644 --- a/sycl/test/extensions/properties/properties_device_copyable.cpp +++ b/sycl/test/extensions/properties/properties_device_copyable.cpp @@ -2,7 +2,7 @@ // RUN: %t.out // CUDA and HIP backends currently generates invalid binaries for this -// XFAIL: cuda || hip +// XFAIL: cuda || hip_amd #include From 8e3a42e1b9593329801f3d6ecf867b308d263e12 Mon Sep 17 00:00:00 2001 From: Steffen Larsen Date: Mon, 24 Jan 2022 21:12:58 +0300 Subject: [PATCH 15/24] Testing and error reporting cleanup Signed-off-by: Steffen Larsen --- .../sycl/ext/oneapi/properties/properties.hpp | 31 +++++++++++--- .../properties/properties_ctor_negative.cpp | 33 ++++++--------- .../properties/properties_device_copyable.cpp | 9 ++-- .../properties/properties_equality.cpp | 5 ++- .../properties/properties_get_property.cpp | 1 + .../properties_get_property_negative.cpp | 41 ++++++++----------- .../properties/properties_has_property.cpp | 6 ++- .../properties/properties_is_property_key.cpp | 6 ++- .../properties_is_property_list.cpp | 6 ++- .../properties_is_property_value.cpp | 6 ++- 10 files changed, 81 insertions(+), 63 deletions(-) diff --git a/sycl/include/sycl/ext/oneapi/properties/properties.hpp b/sycl/include/sycl/ext/oneapi/properties/properties.hpp index eee0a6cf1b9e1..41ed8a945fa3f 100644 --- a/sycl/include/sycl/ext/oneapi/properties/properties.hpp +++ b/sycl/include/sycl/ext/oneapi/properties/properties.hpp @@ -58,6 +58,19 @@ struct FindCompileTimePropertyValueType< using type = property_value; }; +template +static constexpr std::enable_if_t< + HasProperty, + typename FindCompileTimePropertyValueType::type> +get_property() { + return {}; +} + +template +static constexpr std::enable_if_t get_property() { + return; +} + // Filters for all runtime properties with data in a tuple of properties. // NOTE: We only need storage for runtime properties with data. template struct RuntimePropertyStorage {}; @@ -135,12 +148,21 @@ template class properties { } template - typename std::enable_if_t::value, + typename std::enable_if_t::value && + has_property(), PropertyT> + get_property() const { + return std::get(Storage); + } + + template + typename std::enable_if_t::value && + !has_property(), + void> get_property() const { static_assert(has_property(), "Property list does not contain the requested property."); - return std::get(Storage); + return; } template @@ -149,9 +171,8 @@ template class properties { * = 0) { static_assert(has_property(), "Property list does not contain the requested property."); - return - typename detail::FindCompileTimePropertyValueType::type{}; + return detail::get_property(), + PropertiesT>(); } private: diff --git a/sycl/test/extensions/properties/properties_ctor_negative.cpp b/sycl/test/extensions/properties/properties_ctor_negative.cpp index a884e4d9d0df5..9ff6af171052c 100644 --- a/sycl/test/extensions/properties/properties_ctor_negative.cpp +++ b/sycl/test/extensions/properties/properties_ctor_negative.cpp @@ -1,33 +1,24 @@ -// RUN: not %clangxx -fsycl -fsycl-targets=%sycl_triple %s -o %t.bin -DTEST_CASE=1 2> %t_1.err -// RUN: FileCheck --check-prefix=CHECK-ERROR-1 < %t_1.err %s -// RUN: not %clangxx -fsycl -fsycl-targets=%sycl_triple %s -o %t.bin -DTEST_CASE=2 2> %t_2.err -// RUN: FileCheck --check-prefix=CHECK-ERROR-2 < %t_2.err %s -// RUN: not %clangxx -fsycl -fsycl-targets=%sycl_triple %s -o %t.bin -DTEST_CASE=3 2> %t_3.err -// RUN: FileCheck --check-prefix=CHECK-ERROR-3 < %t_3.err %s -// RUN: not %clangxx -fsycl -fsycl-targets=%sycl_triple %s -o %t.bin -DTEST_CASE=4 2> %t_4.err -// RUN: FileCheck --check-prefix=CHECK-ERROR-4 < %t_4.err %s +// RUN: %clangxx -fsycl -fsycl-targets=%sycl_triple -fsyntax-only -Xclang -verify -Xclang -verify-ignore-unexpected=note,warning %s #include #include "mock_compile_time_properties.hpp" int main() { -#if (TEST_CASE == 1) - auto InvalidPropertyList = sycl::ext::oneapi::experimental::properties(1); - // CHECK-ERROR-1: Unrecognized property in property list. -#elif (TEST_CASE == 2) - auto InvalidPropertyList = sycl::ext::oneapi::experimental::properties( + // expected-error@sycl/ext/oneapi/properties/property_utils.hpp:* {{static_assert failed due to requirement 'detail::AllPropertyValues>::value' "Unrecognized property in property list."}} + // expected-error@+1 {{no viable constructor or deduction guide for deduction of template arguments of 'properties'}} + auto InvalidPropertyList1 = sycl::ext::oneapi::experimental::properties(1); + // expected-error@sycl/ext/oneapi/properties/property_utils.hpp:* {{static_assert failed due to requirement 'detail::AllPropertyValues>::value' "Unrecognized property in property list."}} + // expected-error@+1 {{no viable constructor or deduction guide for deduction of template arguments of 'properties'}} + auto InvalidPropertyList2 = sycl::ext::oneapi::experimental::properties( sycl::ext::oneapi::experimental::foo{1}, true); - // CHECK-ERROR-2: Unrecognized property in property list. -#elif (TEST_CASE == 3) - auto InvalidPropertyList = sycl::ext::oneapi::experimental::properties( + // expected-error@sycl/ext/oneapi/properties/properties.hpp:* {{static_assert failed due to requirement 'detail::AllUnique>::value' "Duplicate properties in property list."}} + auto InvalidPropertyList3 = sycl::ext::oneapi::experimental::properties( sycl::ext::oneapi::experimental::foo{0}, sycl::ext::oneapi::experimental::foo{1}); - // CHECK-ERROR-3: Duplicate properties in property list. -#elif (TEST_CASE == 4) - auto InvalidPropertyList = sycl::ext::oneapi::experimental::properties( + // expected-error@sycl/ext/oneapi/properties/properties.hpp:* {{static_assert failed due to requirement 'detail::AllUnique, cl::sycl::ext::oneapi::experimental::property_value>>::value' "Duplicate properties in property list."}} + auto InvalidPropertyList4 = sycl::ext::oneapi::experimental::properties( sycl::ext::oneapi::experimental::bar, sycl::ext::oneapi::experimental::bar); - // CHECK-ERROR-4: Duplicate properties in property list. -#endif + return 0; } diff --git a/sycl/test/extensions/properties/properties_device_copyable.cpp b/sycl/test/extensions/properties/properties_device_copyable.cpp index 8887917d8a359..1ade3ac1bff64 100644 --- a/sycl/test/extensions/properties/properties_device_copyable.cpp +++ b/sycl/test/extensions/properties/properties_device_copyable.cpp @@ -1,8 +1,8 @@ -// RUN: %clangxx -fsycl -fsycl-targets=%sycl_triple %s -o %t.out -// RUN: %t.out +// RUN: %clangxx -fsycl -fsycl-targets=%sycl_triple -fsyntax-only -Xclang -verify -Xclang -verify-ignore-unexpected=note,warning %s +// expected-no-diagnostics -// CUDA and HIP backends currently generates invalid binaries for this -// XFAIL: cuda || hip_amd +// CUDA backend currently generates invalid binaries on linux +// XFAIL: cuda && linux #include @@ -60,4 +60,5 @@ int main() { PropertyList.get_property(); }); }); + return 0; } diff --git a/sycl/test/extensions/properties/properties_equality.cpp b/sycl/test/extensions/properties/properties_equality.cpp index f00b5a2c77757..2f2f871ddc18d 100644 --- a/sycl/test/extensions/properties/properties_equality.cpp +++ b/sycl/test/extensions/properties/properties_equality.cpp @@ -1,5 +1,5 @@ -// RUN: %clangxx -fsycl -fsycl-targets=%sycl_triple %s -o %t.out -// RUN: %t.out +// RUN: %clangxx -fsycl -fsycl-targets=%sycl_triple -fsyntax-only -Xclang -verify -Xclang -verify-ignore-unexpected=note,warning %s +// expected-no-diagnostics #include @@ -13,4 +13,5 @@ int main() { sycl::ext::oneapi::experimental::bar, sycl::ext::oneapi::experimental::baz<1>)); static_assert(std::is_same::value); + return 0; } diff --git a/sycl/test/extensions/properties/properties_get_property.cpp b/sycl/test/extensions/properties/properties_get_property.cpp index f1f586278df0b..a7ee46b1d065c 100644 --- a/sycl/test/extensions/properties/properties_get_property.cpp +++ b/sycl/test/extensions/properties/properties_get_property.cpp @@ -36,4 +36,5 @@ int main() { FooProp); assert(PropertyList.get_property() .value == FooProp.value); + return 0; } diff --git a/sycl/test/extensions/properties/properties_get_property_negative.cpp b/sycl/test/extensions/properties/properties_get_property_negative.cpp index ea6df95488942..28ffbbc3c47ac 100644 --- a/sycl/test/extensions/properties/properties_get_property_negative.cpp +++ b/sycl/test/extensions/properties/properties_get_property_negative.cpp @@ -1,11 +1,4 @@ -// RUN: not %clangxx -fsycl -fsycl-targets=%sycl_triple %s -o %t.bin -DTEST_CASE=1 2> %t_1.err -// RUN: FileCheck --check-prefix=CHECK-ERROR-1 < %t_1.err %s -// RUN: not %clangxx -fsycl -fsycl-targets=%sycl_triple %s -o %t.bin -DTEST_CASE=2 2> %t_2.err -// RUN: FileCheck --check-prefix=CHECK-ERROR-2 < %t_2.err %s -// RUN: not %clangxx -fsycl -fsycl-targets=%sycl_triple %s -o %t.bin -DTEST_CASE=3 2> %t_3.err -// RUN: FileCheck --check-prefix=CHECK-ERROR-3 < %t_3.err %s -// RUN: not %clangxx -fsycl -fsycl-targets=%sycl_triple %s -o %t.bin -DTEST_CASE=4 2> %t_4.err -// RUN: FileCheck --check-prefix=CHECK-ERROR-4 < %t_4.err %s +// RUN: %clangxx -fsycl -fsycl-targets=%sycl_triple -fsyntax-only -Xclang -verify -Xclang -verify-ignore-unexpected=note,warning %s #include @@ -13,26 +6,28 @@ int main() { auto EmptyPropertyList = sycl::ext::oneapi::experimental::properties(); -#if (TEST_CASE == 1) - decltype(EmptyPropertyList)::get_property< + // expected-error@sycl/ext/oneapi/properties/properties.hpp:* {{static_assert failed due to requirement 'has_property()' "Property list does not contain the requested property."}} + // expected-error@+1 {{variable has incomplete type 'const void'}} + constexpr auto boo_val1 = decltype(EmptyPropertyList)::get_property< sycl::ext::oneapi::experimental::boo_key>(); - // CHECK-ERROR-1: Property list does not contain the requested property. -#elif (TEST_CASE == 2) - EmptyPropertyList.get_property(); - // CHECK-ERROR-2: Property list does not contain the requested property. -#endif + // expected-error@sycl/ext/oneapi/properties/properties.hpp:* {{static_assert failed due to requirement 'has_property()' "Property list does not contain the requested property."}} + // expected-error@+1 {{no viable conversion from 'typename std::enable_if_t::value && !has_property(), void>' (aka 'void') to 'sycl::ext::oneapi::experimental::foo'}} + sycl::ext::oneapi::experimental::foo foo_val1 = + EmptyPropertyList + .get_property(); sycl::queue Q; auto PopulatedPropertyList = sycl::ext::oneapi::experimental::properties( sycl::ext::oneapi::experimental::foz{.0f, true}, sycl::ext::oneapi::experimental::bar); -#if (TEST_CASE == 3) - decltype(PopulatedPropertyList)::get_property< + // expected-error@sycl/ext/oneapi/properties/properties.hpp:* {{static_assert failed due to requirement 'has_property()' "Property list does not contain the requested property."}} + // expected-error@+1 {{variable has incomplete type 'const void'}} + constexpr auto boo_val2 = decltype(PopulatedPropertyList)::get_property< sycl::ext::oneapi::experimental::boo_key>(); - // CHECK-ERROR-3: Property list does not contain the requested property. -#elif (TEST_CASE == 4) - PopulatedPropertyList - .get_property(); - // CHECK-ERROR-4: Property list does not contain the requested property. -#endif + // expected-error@sycl/ext/oneapi/properties/properties.hpp:* {{static_assert failed due to requirement 'has_property()' "Property list does not contain the requested property."}} + // expected-error@+1 {{no viable conversion from 'typename std::enable_if_t::value && !has_property(), void>' (aka 'void') to 'sycl::ext::oneapi::experimental::foo'}} + sycl::ext::oneapi::experimental::foo foo_val2 = + PopulatedPropertyList + .get_property(); + return 0; } diff --git a/sycl/test/extensions/properties/properties_has_property.cpp b/sycl/test/extensions/properties/properties_has_property.cpp index cbb6cf3f48696..1e44533e314d3 100644 --- a/sycl/test/extensions/properties/properties_has_property.cpp +++ b/sycl/test/extensions/properties/properties_has_property.cpp @@ -1,5 +1,5 @@ -// RUN: %clangxx -fsycl -fsycl-targets=%sycl_triple %s -o %t.out -// RUN: %t.out +// RUN: %clangxx -fsycl -fsycl-targets=%sycl_triple -fsyntax-only -Xclang -verify -Xclang -verify-ignore-unexpected=note,warning %s +// expected-no-diagnostics #include @@ -35,4 +35,6 @@ int main() { static_assert(!P3::has_property()); static_assert(P3::has_property()); static_assert(!P3::has_property()); + + return 0; } diff --git a/sycl/test/extensions/properties/properties_is_property_key.cpp b/sycl/test/extensions/properties/properties_is_property_key.cpp index bbf410770e8cb..559fd7decb52a 100644 --- a/sycl/test/extensions/properties/properties_is_property_key.cpp +++ b/sycl/test/extensions/properties/properties_is_property_key.cpp @@ -1,5 +1,5 @@ -// RUN: %clangxx -fsycl -fsycl-targets=%sycl_triple %s -o %t.out -// RUN: %t.out +// RUN: %clangxx -fsycl -fsycl-targets=%sycl_triple -fsyntax-only -Xclang -verify -Xclang -verify-ignore-unexpected=note,warning %s +// expected-no-diagnostics #include @@ -86,4 +86,6 @@ int main() { static_assert( !sycl::ext::oneapi::experimental::is_property_key_of::value); + + return 0; } \ No newline at end of file diff --git a/sycl/test/extensions/properties/properties_is_property_list.cpp b/sycl/test/extensions/properties/properties_is_property_list.cpp index 10255caf3afc0..fc8a937e2fee0 100644 --- a/sycl/test/extensions/properties/properties_is_property_list.cpp +++ b/sycl/test/extensions/properties/properties_is_property_list.cpp @@ -1,5 +1,5 @@ -// RUN: %clangxx -fsycl -fsycl-targets=%sycl_triple %s -o %t.out -// RUN: %t.out +// RUN: %clangxx -fsycl -fsycl-targets=%sycl_triple -fsyntax-only -Xclang -verify -Xclang -verify-ignore-unexpected=note,warning %s +// expected-no-diagnostics #include @@ -70,4 +70,6 @@ int main() { sycl::property_list>::value); static_assert(!sycl::ext::oneapi::experimental::is_property_list_v< sycl::property_list>); + + return 0; } diff --git a/sycl/test/extensions/properties/properties_is_property_value.cpp b/sycl/test/extensions/properties/properties_is_property_value.cpp index 8e0bebc5a47d4..42b8f9e0142d2 100644 --- a/sycl/test/extensions/properties/properties_is_property_value.cpp +++ b/sycl/test/extensions/properties/properties_is_property_value.cpp @@ -1,5 +1,5 @@ -// RUN: %clangxx -fsycl -fsycl-targets=%sycl_triple %s -o %t.out -// RUN: %t.out +// RUN: %clangxx -fsycl -fsycl-targets=%sycl_triple -fsyntax-only -Xclang -verify -Xclang -verify-ignore-unexpected=note,warning %s +// expected-no-diagnostics #include @@ -85,4 +85,6 @@ int main() { int, sycl::queue>::value); static_assert(!sycl::ext::oneapi::experimental::is_property_value_of< NotAPropertyKey, sycl::queue>::value); + + return 0; } \ No newline at end of file From cd4b002d8114e2d5cdf2e498f7df084948d2e6d5 Mon Sep 17 00:00:00 2001 From: Steffen Larsen Date: Mon, 24 Jan 2022 21:45:46 +0300 Subject: [PATCH 16/24] Renable device_copyable test for CUDA Signed-off-by: Steffen Larsen --- sycl/test/extensions/properties/properties_device_copyable.cpp | 3 --- 1 file changed, 3 deletions(-) diff --git a/sycl/test/extensions/properties/properties_device_copyable.cpp b/sycl/test/extensions/properties/properties_device_copyable.cpp index 1ade3ac1bff64..17a2803e22c6c 100644 --- a/sycl/test/extensions/properties/properties_device_copyable.cpp +++ b/sycl/test/extensions/properties/properties_device_copyable.cpp @@ -1,9 +1,6 @@ // RUN: %clangxx -fsycl -fsycl-targets=%sycl_triple -fsyntax-only -Xclang -verify -Xclang -verify-ignore-unexpected=note,warning %s // expected-no-diagnostics -// CUDA backend currently generates invalid binaries on linux -// XFAIL: cuda && linux - #include #include "mock_compile_time_properties.hpp" From 0b23c3ed99aa5446040d64cfb8be5524b773de44 Mon Sep 17 00:00:00 2001 From: Steffen Larsen Date: Mon, 24 Jan 2022 21:56:59 +0300 Subject: [PATCH 17/24] Simplify negative tests Signed-off-by: Steffen Larsen --- .../properties/properties_ctor_negative.cpp | 8 ++++---- .../properties_get_property_negative.cpp | 16 ++++++++-------- 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/sycl/test/extensions/properties/properties_ctor_negative.cpp b/sycl/test/extensions/properties/properties_ctor_negative.cpp index 9ff6af171052c..914b79f64eb53 100644 --- a/sycl/test/extensions/properties/properties_ctor_negative.cpp +++ b/sycl/test/extensions/properties/properties_ctor_negative.cpp @@ -5,18 +5,18 @@ #include "mock_compile_time_properties.hpp" int main() { - // expected-error@sycl/ext/oneapi/properties/property_utils.hpp:* {{static_assert failed due to requirement 'detail::AllPropertyValues>::value' "Unrecognized property in property list."}} + // expected-error-re@sycl/ext/oneapi/properties/property_utils.hpp:* {{static_assert failed due to requirement {{.+}} "Unrecognized property in property list."}} // expected-error@+1 {{no viable constructor or deduction guide for deduction of template arguments of 'properties'}} auto InvalidPropertyList1 = sycl::ext::oneapi::experimental::properties(1); - // expected-error@sycl/ext/oneapi/properties/property_utils.hpp:* {{static_assert failed due to requirement 'detail::AllPropertyValues>::value' "Unrecognized property in property list."}} + // expected-error-re@sycl/ext/oneapi/properties/property_utils.hpp:* {{static_assert failed due to requirement {{.+}} "Unrecognized property in property list."}} // expected-error@+1 {{no viable constructor or deduction guide for deduction of template arguments of 'properties'}} auto InvalidPropertyList2 = sycl::ext::oneapi::experimental::properties( sycl::ext::oneapi::experimental::foo{1}, true); - // expected-error@sycl/ext/oneapi/properties/properties.hpp:* {{static_assert failed due to requirement 'detail::AllUnique>::value' "Duplicate properties in property list."}} + // expected-error-re@sycl/ext/oneapi/properties/properties.hpp:* {{static_assert failed due to requirement {{.+}} "Duplicate properties in property list."}} auto InvalidPropertyList3 = sycl::ext::oneapi::experimental::properties( sycl::ext::oneapi::experimental::foo{0}, sycl::ext::oneapi::experimental::foo{1}); - // expected-error@sycl/ext/oneapi/properties/properties.hpp:* {{static_assert failed due to requirement 'detail::AllUnique, cl::sycl::ext::oneapi::experimental::property_value>>::value' "Duplicate properties in property list."}} + // expected-error-re@sycl/ext/oneapi/properties/properties.hpp:* {{static_assert failed due to requirement {{.+}} "Duplicate properties in property list."}} auto InvalidPropertyList4 = sycl::ext::oneapi::experimental::properties( sycl::ext::oneapi::experimental::bar, sycl::ext::oneapi::experimental::bar); diff --git a/sycl/test/extensions/properties/properties_get_property_negative.cpp b/sycl/test/extensions/properties/properties_get_property_negative.cpp index 28ffbbc3c47ac..26d61f29c5b84 100644 --- a/sycl/test/extensions/properties/properties_get_property_negative.cpp +++ b/sycl/test/extensions/properties/properties_get_property_negative.cpp @@ -6,12 +6,12 @@ int main() { auto EmptyPropertyList = sycl::ext::oneapi::experimental::properties(); - // expected-error@sycl/ext/oneapi/properties/properties.hpp:* {{static_assert failed due to requirement 'has_property()' "Property list does not contain the requested property."}} - // expected-error@+1 {{variable has incomplete type 'const void'}} + // expected-error-re@sycl/ext/oneapi/properties/properties.hpp:* {{static_assert failed due to requirement {{.+}} "Property list does not contain the requested property."}} + // expected-error-re@+1 {{variable has incomplete type {{.+}}}} constexpr auto boo_val1 = decltype(EmptyPropertyList)::get_property< sycl::ext::oneapi::experimental::boo_key>(); - // expected-error@sycl/ext/oneapi/properties/properties.hpp:* {{static_assert failed due to requirement 'has_property()' "Property list does not contain the requested property."}} - // expected-error@+1 {{no viable conversion from 'typename std::enable_if_t::value && !has_property(), void>' (aka 'void') to 'sycl::ext::oneapi::experimental::foo'}} + // expected-error-re@sycl/ext/oneapi/properties/properties.hpp:* {{static_assert failed due to requirement {{.+}} "Property list does not contain the requested property."}} + // expected-error-re@+1 {{no viable conversion from {{.+}} to 'sycl::ext::oneapi::experimental::foo'}} sycl::ext::oneapi::experimental::foo foo_val1 = EmptyPropertyList .get_property(); @@ -20,12 +20,12 @@ int main() { auto PopulatedPropertyList = sycl::ext::oneapi::experimental::properties( sycl::ext::oneapi::experimental::foz{.0f, true}, sycl::ext::oneapi::experimental::bar); - // expected-error@sycl/ext/oneapi/properties/properties.hpp:* {{static_assert failed due to requirement 'has_property()' "Property list does not contain the requested property."}} - // expected-error@+1 {{variable has incomplete type 'const void'}} + // expected-error-re@sycl/ext/oneapi/properties/properties.hpp:* {{static_assert failed due to requirement {{.+}} "Property list does not contain the requested property."}} + // expected-error-re@+1 {{variable has incomplete type {{.+}}}} constexpr auto boo_val2 = decltype(PopulatedPropertyList)::get_property< sycl::ext::oneapi::experimental::boo_key>(); - // expected-error@sycl/ext/oneapi/properties/properties.hpp:* {{static_assert failed due to requirement 'has_property()' "Property list does not contain the requested property."}} - // expected-error@+1 {{no viable conversion from 'typename std::enable_if_t::value && !has_property(), void>' (aka 'void') to 'sycl::ext::oneapi::experimental::foo'}} + // expected-error-re@sycl/ext/oneapi/properties/properties.hpp:* {{static_assert failed due to requirement {{.+}} "Property list does not contain the requested property."}} + // expected-error-re@+1 {{no viable conversion from {{.+}} to 'sycl::ext::oneapi::experimental::foo'}} sycl::ext::oneapi::experimental::foo foo_val2 = PopulatedPropertyList .get_property(); From 294efcb0d8561f858a7df93c6a3937f817255a57 Mon Sep 17 00:00:00 2001 From: Steffen Larsen Date: Wed, 2 Feb 2022 13:43:22 +0300 Subject: [PATCH 18/24] is_device_copyable specialization for const properties and associated tests Signed-off-by: Steffen Larsen --- sycl/include/CL/sycl/types.hpp | 6 --- .../sycl/ext/oneapi/properties/properties.hpp | 6 +++ .../mock_compile_time_properties.hpp | 25 +++++++++++++ .../properties/properties_device_copyable.cpp | 37 +++++++++++++++++-- 4 files changed, 64 insertions(+), 10 deletions(-) diff --git a/sycl/include/CL/sycl/types.hpp b/sycl/include/CL/sycl/types.hpp index 7f56a66b52e31..5ec1c9325c79a 100644 --- a/sycl/include/CL/sycl/types.hpp +++ b/sycl/include/CL/sycl/types.hpp @@ -2399,12 +2399,6 @@ struct is_device_copyable< T, std::enable_if_t::value>> : std::true_type {}; -// Specializations of device copyable should propagate onto constants. -template -struct is_device_copyable< - const T, std::enable_if_t::value>> - : is_device_copyable {}; - #if __cplusplus >= 201703L template inline constexpr bool is_device_copyable_v = is_device_copyable::value; diff --git a/sycl/include/sycl/ext/oneapi/properties/properties.hpp b/sycl/include/sycl/ext/oneapi/properties/properties.hpp index 41ed8a945fa3f..2857251ab1e51 100644 --- a/sycl/include/sycl/ext/oneapi/properties/properties.hpp +++ b/sycl/include/sycl/ext/oneapi/properties/properties.hpp @@ -213,6 +213,12 @@ struct is_device_copyable< std::enable_if_t>::value>> : is_device_copyable {}; +template +struct is_device_copyable< + const ext::oneapi::experimental::properties, + std::enable_if_t>::value>> + : is_device_copyable {}; } // namespace sycl } // __SYCL_INLINE_NAMESPACE(cl) diff --git a/sycl/test/extensions/properties/mock_compile_time_properties.hpp b/sycl/test/extensions/properties/mock_compile_time_properties.hpp index 61ff723379346..0bc6a3cf21742 100644 --- a/sycl/test/extensions/properties/mock_compile_time_properties.hpp +++ b/sycl/test/extensions/properties/mock_compile_time_properties.hpp @@ -56,18 +56,36 @@ inline bool operator==(const foz &lhs, const foz &rhs) { } inline bool operator!=(const foz &lhs, const foz &rhs) { return !(lhs == rhs); } +struct fir { + fir(float v1, bool v2) : value1(v1), value2(v2) {} + // Define copy constructor to make foz non-trivially copyable + fir(const foz &f) { + value1 = f.value1; + value2 = f.value2; + } + float value1; + bool value2; +}; + +inline bool operator==(const fir &lhs, const fir &rhs) { + return lhs.value1 == rhs.value1 && lhs.value2 == rhs.value2; +} +inline bool operator!=(const fir &lhs, const fir &rhs) { return !(lhs == rhs); } + inline constexpr bar_key::value_t bar; template inline constexpr baz_key::value_t baz; template inline constexpr boo_key::value_t boo; using foo_key = foo; using foz_key = foz; +using fir_key = fir; template <> struct is_property_key : std::true_type {}; template <> struct is_property_key : std::true_type {}; template <> struct is_property_key : std::true_type {}; template <> struct is_property_key : std::true_type {}; template <> struct is_property_key : std::true_type {}; +template <> struct is_property_key : std::true_type {}; template struct is_property_key_of : std::true_type {}; @@ -79,6 +97,8 @@ template struct is_property_key_of : std::true_type {}; template struct is_property_key_of : std::true_type {}; +template +struct is_property_key_of : std::true_type {}; namespace detail { template <> struct PropertyToKind { @@ -101,6 +121,10 @@ template <> struct PropertyToKind { static constexpr PropKind Kind = static_cast(PropKind::PropKindSize + 4); }; +template <> struct PropertyToKind { + static constexpr PropKind Kind = + static_cast(PropKind::PropKindSize + 4); +}; template <> struct IsCompileTimeProperty : std::true_type {}; template <> struct IsCompileTimeProperty : std::true_type {}; @@ -108,6 +132,7 @@ template <> struct IsCompileTimeProperty : std::true_type {}; template <> struct IsRuntimeProperty : std::true_type {}; template <> struct IsRuntimeProperty : std::true_type {}; +template <> struct IsRuntimeProperty : std::true_type {}; } // namespace detail } // namespace experimental } // namespace oneapi diff --git a/sycl/test/extensions/properties/properties_device_copyable.cpp b/sycl/test/extensions/properties/properties_device_copyable.cpp index 17a2803e22c6c..0b320e9121774 100644 --- a/sycl/test/extensions/properties/properties_device_copyable.cpp +++ b/sycl/test/extensions/properties/properties_device_copyable.cpp @@ -8,13 +8,23 @@ class TestClass1 {}; class TestClass2 {}; +namespace sycl { +// Explicitly mark fir property as device-copyable +template <> +struct is_device_copyable + : std::true_type {}; +template <> +struct is_device_copyable + : std::true_type {}; +} + int main() { // Check only compile-time properties are device-copyable using P1 = decltype(sycl::ext::oneapi::experimental::properties( sycl::ext::oneapi::experimental::baz<1>, sycl::ext::oneapi::experimental::boo, sycl::ext::oneapi::experimental::bar)); - + using CP1 = const P1; static_assert(sycl::is_device_copyable_v< sycl::ext::oneapi::experimental::baz_key::value_t<1>>); static_assert( @@ -23,28 +33,44 @@ int main() { static_assert(sycl::is_device_copyable_v< sycl::ext::oneapi::experimental::bar_key::value_t>); static_assert(sycl::is_device_copyable_v); + static_assert(sycl::is_device_copyable_v); // Check property list with non-device-copyable property using P2 = decltype(sycl::ext::oneapi::experimental::properties( sycl::ext::oneapi::experimental::bar, sycl::ext::oneapi::experimental::foz{42.42, false})); + using CP2 = const P2; static_assert( !sycl::is_device_copyable_v); static_assert(!sycl::is_device_copyable_v); + static_assert(!sycl::is_device_copyable_v); + + // Check property list with explicit device-copyable property + using P3 = decltype(sycl::ext::oneapi::experimental::properties( + sycl::ext::oneapi::experimental::bar, + sycl::ext::oneapi::experimental::fir{42.42, false})); + using CP3 = const P3; + static_assert( + sycl::is_device_copyable_v); + static_assert(sycl::is_device_copyable_v); + static_assert(sycl::is_device_copyable_v); // Check property list with device-copyable compile-time and runtime // properties - using P3 = decltype(sycl::ext::oneapi::experimental::properties( + using P4 = decltype(sycl::ext::oneapi::experimental::properties( sycl::ext::oneapi::experimental::baz<1>, sycl::ext::oneapi::experimental::foo{1234})); + using CP4 = const P4; static_assert( sycl::is_device_copyable_v); - static_assert(sycl::is_device_copyable_v); + static_assert(sycl::is_device_copyable_v); + static_assert(sycl::is_device_copyable_v); // Check that device-copyable property list can indeed be used in a kernel const auto PropertyList = sycl::ext::oneapi::experimental::properties( sycl::ext::oneapi::experimental::baz<1>, - sycl::ext::oneapi::experimental::foo{0}); + sycl::ext::oneapi::experimental::foo{0}, + sycl::ext::oneapi::experimental::fir{12.34, true}); sycl::queue Q; Q.submit([&](sycl::handler &CGH) { @@ -53,8 +79,11 @@ int main() { sycl::ext::oneapi::experimental::baz_key>(); decltype(PropertyList)::has_property< sycl::ext::oneapi::experimental::foo_key>(); + decltype(PropertyList)::has_property< + sycl::ext::oneapi::experimental::fir_key>(); PropertyList.get_property(); PropertyList.get_property(); + PropertyList.get_property(); }); }); return 0; From 95682f1cfa1c821c63c01c48095836ad5294bc38 Mon Sep 17 00:00:00 2001 From: Steffen Larsen Date: Wed, 2 Feb 2022 13:52:47 +0300 Subject: [PATCH 19/24] Rename and clarify AllUnique type-trait Signed-off-by: Steffen Larsen --- .../sycl/ext/oneapi/properties/properties.hpp | 2 +- .../ext/oneapi/properties/property_utils.hpp | 22 +++++++++---------- 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/sycl/include/sycl/ext/oneapi/properties/properties.hpp b/sycl/include/sycl/ext/oneapi/properties/properties.hpp index 2857251ab1e51..b961572158801 100644 --- a/sycl/include/sycl/ext/oneapi/properties/properties.hpp +++ b/sycl/include/sycl/ext/oneapi/properties/properties.hpp @@ -132,7 +132,7 @@ template class properties { "Unrecognized property in property list."); static_assert(detail::IsSorted::value, "Properties in property list are not sorted."); - static_assert(detail::AllUnique::value, + static_assert(detail::SortedAllUnique::value, "Duplicate properties in property list."); public: diff --git a/sycl/include/sycl/ext/oneapi/properties/property_utils.hpp b/sycl/include/sycl/ext/oneapi/properties/property_utils.hpp index 74a5810810473..ad091007edbed 100644 --- a/sycl/include/sycl/ext/oneapi/properties/property_utils.hpp +++ b/sycl/include/sycl/ext/oneapi/properties/property_utils.hpp @@ -48,17 +48,6 @@ template struct HasValue : std::false_type {}; template struct HasValue : std::true_type {}; -// Checks that all types in a tuple have unique PropertyID. -template struct AllUnique {}; -template -struct AllUnique> : std::true_type {}; -template struct AllUnique> : std::true_type {}; -template -struct AllUnique> - : sycl::detail::conditional_t::value != PropertyID::value, - AllUnique>, - std::false_type> {}; - //****************************************************************************** // Property identification //****************************************************************************** @@ -213,6 +202,17 @@ struct IsSorted> IsSorted>, std::false_type> {}; +// Checks that all types in a sorted tuple have unique PropertyID. +template struct SortedAllUnique {}; +template +struct SortedAllUnique> : std::true_type {}; +template struct SortedAllUnique> : std::true_type {}; +template +struct SortedAllUnique> + : sycl::detail::conditional_t::value != PropertyID::value, + SortedAllUnique>, + std::false_type> {}; + } // namespace detail } // namespace experimental } // namespace oneapi From 0cae2e52088c3015a2105c09f9d03eaf52d099cb Mon Sep 17 00:00:00 2001 From: Steffen Larsen Date: Wed, 2 Feb 2022 14:06:42 +0300 Subject: [PATCH 20/24] Fix formatting Signed-off-by: Steffen Larsen --- sycl/test/extensions/properties/properties_device_copyable.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sycl/test/extensions/properties/properties_device_copyable.cpp b/sycl/test/extensions/properties/properties_device_copyable.cpp index 0b320e9121774..7bc4943fab782 100644 --- a/sycl/test/extensions/properties/properties_device_copyable.cpp +++ b/sycl/test/extensions/properties/properties_device_copyable.cpp @@ -16,7 +16,7 @@ struct is_device_copyable template <> struct is_device_copyable : std::true_type {}; -} +} // namespace sycl int main() { // Check only compile-time properties are device-copyable From 4f41fd4669378cd39ef22a906050e4f24c34c320 Mon Sep 17 00:00:00 2001 From: Steffen Larsen Date: Wed, 2 Feb 2022 13:06:47 +0000 Subject: [PATCH 21/24] Add missing end-of-file lines --- sycl/test/extensions/properties/properties_is_property_key.cpp | 2 +- .../test/extensions/properties/properties_is_property_value.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/sycl/test/extensions/properties/properties_is_property_key.cpp b/sycl/test/extensions/properties/properties_is_property_key.cpp index 559fd7decb52a..3da9fbcd286d7 100644 --- a/sycl/test/extensions/properties/properties_is_property_key.cpp +++ b/sycl/test/extensions/properties/properties_is_property_key.cpp @@ -88,4 +88,4 @@ int main() { sycl::queue>::value); return 0; -} \ No newline at end of file +} diff --git a/sycl/test/extensions/properties/properties_is_property_value.cpp b/sycl/test/extensions/properties/properties_is_property_value.cpp index 42b8f9e0142d2..b4515fc2fd76c 100644 --- a/sycl/test/extensions/properties/properties_is_property_value.cpp +++ b/sycl/test/extensions/properties/properties_is_property_value.cpp @@ -87,4 +87,4 @@ int main() { NotAPropertyKey, sycl::queue>::value); return 0; -} \ No newline at end of file +} From 46086763550f7debe50ec55d11660fa38f89203d Mon Sep 17 00:00:00 2001 From: Steffen Larsen Date: Thu, 24 Feb 2022 14:45:28 +0300 Subject: [PATCH 22/24] Fix reference to is_property in how-to Signed-off-by: Steffen Larsen --- sycl/include/sycl/ext/oneapi/properties/property.hpp | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/sycl/include/sycl/ext/oneapi/properties/property.hpp b/sycl/include/sycl/ext/oneapi/properties/property.hpp index b41cf8ea93470..504f9d3d2c7eb 100644 --- a/sycl/include/sycl/ext/oneapi/properties/property.hpp +++ b/sycl/include/sycl/ext/oneapi/properties/property.hpp @@ -19,8 +19,8 @@ // key. The variable should have the same type as `value_t` of the property // class, e.g. for a property `foo`, there should be a definition // `inline constexpr foo_key::value_t foo`. -// 4. Specialize `sycl::ext::oneapi::experimental::is_property` and -// `sycl::ext::oneapi::experimental::is_property_of` for the property key +// 4. Specialize `sycl::ext::oneapi::experimental::is_property_key` and +// `sycl::ext::oneapi::experimental::is_property_key_of` for the property key // class. // 5. Specialize `sycl::ext::oneapi::experimental::detail::PropertyToKind` for // the new property key class. The specialization should have a `Kind` @@ -49,9 +49,9 @@ struct bar_key { inline constexpr bar_key::value_t bar; // (4.) -template <> struct is_property : std::true_type {}; +template <> struct is_property_key : std::true_type {}; // Replace SYCL_OBJ with the SYCL object to support the property. -template <> struct is_property_of : std::true_type {}; +template <> struct is_property_key_of : std::true_type {}; namespace detail { @@ -77,8 +77,8 @@ template <> struct IsCompileTimeProperty : std::true_type {}; // property `foo` the class should be named `foo_key`. // 4. Overload the `==` and `!=` operators for the new property class. The // comparison should compare all data members of the property class. -// 5. Specialize `sycl::ext::oneapi::experimental::is_property` and -// `sycl::ext::oneapi::experimental::is_property_of` for the property class. +// 5. Specialize `sycl::ext::oneapi::experimental::is_property_key` and +// `sycl::ext::oneapi::experimental::is_property_key_of` for the property class. // 6. Specialize `sycl::ext::oneapi::detail::PropertyToKind` for the new // property class. The specialization should have a `Kind` member with the // value equal to the enumerator added in 1. From de41a0fabc94a253b9a0244474c48e5bab0c0e17 Mon Sep 17 00:00:00 2001 From: Steffen Larsen Date: Thu, 24 Feb 2022 14:53:25 +0300 Subject: [PATCH 23/24] Fix formatting Signed-off-by: Steffen Larsen --- sycl/include/sycl/ext/oneapi/properties/property.hpp | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/sycl/include/sycl/ext/oneapi/properties/property.hpp b/sycl/include/sycl/ext/oneapi/properties/property.hpp index 504f9d3d2c7eb..955c112798611 100644 --- a/sycl/include/sycl/ext/oneapi/properties/property.hpp +++ b/sycl/include/sycl/ext/oneapi/properties/property.hpp @@ -20,8 +20,8 @@ // class, e.g. for a property `foo`, there should be a definition // `inline constexpr foo_key::value_t foo`. // 4. Specialize `sycl::ext::oneapi::experimental::is_property_key` and -// `sycl::ext::oneapi::experimental::is_property_key_of` for the property key -// class. +// `sycl::ext::oneapi::experimental::is_property_key_of` for the property +// key class. // 5. Specialize `sycl::ext::oneapi::experimental::detail::PropertyToKind` for // the new property key class. The specialization should have a `Kind` // member with the value equal to the enumerator added in 1. @@ -78,7 +78,8 @@ template <> struct IsCompileTimeProperty : std::true_type {}; // 4. Overload the `==` and `!=` operators for the new property class. The // comparison should compare all data members of the property class. // 5. Specialize `sycl::ext::oneapi::experimental::is_property_key` and -// `sycl::ext::oneapi::experimental::is_property_key_of` for the property class. +// `sycl::ext::oneapi::experimental::is_property_key_of` for the property +// class. // 6. Specialize `sycl::ext::oneapi::detail::PropertyToKind` for the new // property class. The specialization should have a `Kind` member with the // value equal to the enumerator added in 1. From d33bc776a330b15131494aea96ab336ca552a81d Mon Sep 17 00:00:00 2001 From: Steffen Larsen Date: Thu, 24 Feb 2022 15:41:24 +0300 Subject: [PATCH 24/24] Adhere to new formatting Signed-off-by: Steffen Larsen --- .../sycl/ext/oneapi/properties/property_utils.hpp | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/sycl/include/sycl/ext/oneapi/properties/property_utils.hpp b/sycl/include/sycl/ext/oneapi/properties/property_utils.hpp index ad091007edbed..9ddcc0352dda4 100644 --- a/sycl/include/sycl/ext/oneapi/properties/property_utils.hpp +++ b/sycl/include/sycl/ext/oneapi/properties/property_utils.hpp @@ -101,8 +101,12 @@ template struct HeadSplit, false> { // Selects the one of two types that is not void. This assumes that at least one // of the two template arguemnts is void. template struct SelectNonVoid {}; -template struct SelectNonVoid { using type = LHS; }; -template struct SelectNonVoid { using type = RHS; }; +template struct SelectNonVoid { + using type = LHS; +}; +template struct SelectNonVoid { + using type = RHS; +}; // Merges two tuples by recursively extracting the type with the minimum // PropertyID in the two tuples and prepending it to the merging of the @@ -147,7 +151,9 @@ struct CreateTuplePairs { // Merges pairs of tuples and creates new pairs of the merged pairs. Let N be // the number of pairs in the supplied tuple, then the resulting tuple will // contain ceil(N/2) pairs of tuples. -template struct MergePairs { using type = std::tuple<>; }; +template struct MergePairs { + using type = std::tuple<>; +}; template struct MergePairs< std::tuple, std::tuple>, Rest...>> {