|
| 1 | +//==------- properties.hpp - SYCL properties associated with kernels -------==// |
| 2 | +// |
| 3 | +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. |
| 4 | +// See https://llvm.org/LICENSE.txt for license information. |
| 5 | +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception |
| 6 | +// |
| 7 | +//===----------------------------------------------------------------------===// |
| 8 | + |
| 9 | +#pragma once |
| 10 | + |
| 11 | +#include <sycl/ext/oneapi/properties/property.hpp> |
| 12 | +#include <sycl/ext/oneapi/properties/property_value.hpp> |
| 13 | + |
| 14 | +#include <array> |
| 15 | + |
| 16 | +namespace sycl { |
| 17 | +__SYCL_INLINE_VER_NAMESPACE(_V1) { |
| 18 | +namespace ext { |
| 19 | +namespace oneapi { |
| 20 | +namespace experimental { |
| 21 | +namespace detail { |
| 22 | +// Trait for checking that all size_t values are non-zero. |
| 23 | +template <size_t... Xs> struct AllNonZero { |
| 24 | + static inline constexpr bool value = true; |
| 25 | +}; |
| 26 | +template <size_t X, size_t... Xs> struct AllNonZero<X, Xs...> { |
| 27 | + static inline constexpr bool value = X > 0 && AllNonZero<Xs...>::value; |
| 28 | +}; |
| 29 | + |
| 30 | +// Simple helpers for containing primitive types as template arguments. |
| 31 | +template <size_t... Sizes> struct SizeList {}; |
| 32 | +template <char... Sizes> struct CharList {}; |
| 33 | + |
| 34 | +// Helper for converting characters to a constexpr string. |
| 35 | +template <char... Chars> struct CharsToStr { |
| 36 | + static inline constexpr const char value[] = {Chars..., '\0'}; |
| 37 | +}; |
| 38 | + |
| 39 | +// Helper for converting a list of size_t values to a comma-separated string |
| 40 | +// representation. This is done by extracting the digit one-by-one and when |
| 41 | +// finishing a value, the parsed result is added to a separate list of |
| 42 | +// "parsed" characters with the delimiter. |
| 43 | +template <typename List, typename ParsedList, char... Chars> |
| 44 | +struct SizeListToStrHelper; |
| 45 | +template <size_t Value, size_t... Values, char... ParsedChars, char... Chars> |
| 46 | +struct SizeListToStrHelper<SizeList<Value, Values...>, CharList<ParsedChars...>, |
| 47 | + Chars...> |
| 48 | + : SizeListToStrHelper<SizeList<Value / 10, Values...>, |
| 49 | + CharList<ParsedChars...>, '0' + (Value % 10), |
| 50 | + Chars...> {}; |
| 51 | +template <size_t... Values, char... ParsedChars, char... Chars> |
| 52 | +struct SizeListToStrHelper<SizeList<0, Values...>, CharList<ParsedChars...>, |
| 53 | + Chars...> |
| 54 | + : SizeListToStrHelper<SizeList<Values...>, |
| 55 | + CharList<ParsedChars..., Chars..., ','>> {}; |
| 56 | +template <char... ParsedChars, char... Chars> |
| 57 | +struct SizeListToStrHelper<SizeList<0>, CharList<ParsedChars...>, Chars...> |
| 58 | + : CharsToStr<ParsedChars..., Chars...> {}; |
| 59 | + |
| 60 | +// Converts size_t values to a comma-separated string representation. |
| 61 | +template <size_t... Sizes> |
| 62 | +struct SizeListToStr : SizeListToStrHelper<SizeList<Sizes...>, CharList<>> {}; |
| 63 | +} // namespace detail |
| 64 | + |
| 65 | +struct properties_tag {}; |
| 66 | + |
| 67 | +struct work_group_size_key { |
| 68 | + template <size_t... Dims> |
| 69 | + using value_t = property_value<work_group_size_key, |
| 70 | + std::integral_constant<size_t, Dims>...>; |
| 71 | +}; |
| 72 | + |
| 73 | +struct work_group_size_hint_key { |
| 74 | + template <size_t... Dims> |
| 75 | + using value_t = property_value<work_group_size_hint_key, |
| 76 | + std::integral_constant<size_t, Dims>...>; |
| 77 | +}; |
| 78 | + |
| 79 | +struct sub_group_size_key { |
| 80 | + template <uint32_t Size> |
| 81 | + using value_t = property_value<sub_group_size_key, |
| 82 | + std::integral_constant<uint32_t, Size>>; |
| 83 | +}; |
| 84 | + |
| 85 | +template <size_t Dim0, size_t... Dims> |
| 86 | +struct property_value<work_group_size_key, std::integral_constant<size_t, Dim0>, |
| 87 | + std::integral_constant<size_t, Dims>...> { |
| 88 | + static_assert( |
| 89 | + sizeof...(Dims) + 1 <= 3, |
| 90 | + "work_group_size property currently only supports up to three values."); |
| 91 | + static_assert(detail::AllNonZero<Dim0, Dims...>::value, |
| 92 | + "work_group_size property must only contain non-zero values."); |
| 93 | + |
| 94 | + using key_t = work_group_size_key; |
| 95 | + |
| 96 | + constexpr size_t operator[](int Dim) const { |
| 97 | + return std::array<size_t, sizeof...(Dims) + 1>{Dim0, Dims...}[Dim]; |
| 98 | + } |
| 99 | +}; |
| 100 | + |
| 101 | +template <size_t Dim0, size_t... Dims> |
| 102 | +struct property_value<work_group_size_hint_key, |
| 103 | + std::integral_constant<size_t, Dim0>, |
| 104 | + std::integral_constant<size_t, Dims>...> { |
| 105 | + static_assert(sizeof...(Dims) + 1 <= 3, |
| 106 | + "work_group_size_hint property currently " |
| 107 | + "only supports up to three values."); |
| 108 | + static_assert( |
| 109 | + detail::AllNonZero<Dim0, Dims...>::value, |
| 110 | + "work_group_size_hint property must only contain non-zero values."); |
| 111 | + |
| 112 | + using key_t = work_group_size_hint_key; |
| 113 | + |
| 114 | + constexpr size_t operator[](int Dim) const { |
| 115 | + return std::array<size_t, sizeof...(Dims) + 1>{Dim0, Dims...}[Dim]; |
| 116 | + } |
| 117 | +}; |
| 118 | + |
| 119 | +template <uint32_t Size> |
| 120 | +struct property_value<sub_group_size_key, |
| 121 | + std::integral_constant<uint32_t, Size>> { |
| 122 | + static_assert(Size != 0, |
| 123 | + "sub_group_size_key property must contain a non-zero value."); |
| 124 | + |
| 125 | + using key_t = sub_group_size_key; |
| 126 | + using value_t = std::integral_constant<uint32_t, Size>; |
| 127 | + static constexpr uint32_t value = Size; |
| 128 | +}; |
| 129 | + |
| 130 | +template <size_t Dim0, size_t... Dims> |
| 131 | +inline constexpr work_group_size_key::value_t<Dim0, Dims...> work_group_size; |
| 132 | + |
| 133 | +template <size_t Dim0, size_t... Dims> |
| 134 | +inline constexpr work_group_size_hint_key::value_t<Dim0, Dims...> |
| 135 | + work_group_size_hint; |
| 136 | + |
| 137 | +template <uint32_t Size> |
| 138 | +inline constexpr sub_group_size_key::value_t<Size> sub_group_size; |
| 139 | + |
| 140 | +template <> struct is_property_key<work_group_size_key> : std::true_type {}; |
| 141 | +template <> |
| 142 | +struct is_property_key<work_group_size_hint_key> : std::true_type {}; |
| 143 | +template <> struct is_property_key<sub_group_size_key> : std::true_type {}; |
| 144 | + |
| 145 | +namespace detail { |
| 146 | +template <> struct PropertyToKind<work_group_size_key> { |
| 147 | + static constexpr PropKind Kind = PropKind::WorkGroupSize; |
| 148 | +}; |
| 149 | +template <> struct PropertyToKind<work_group_size_hint_key> { |
| 150 | + static constexpr PropKind Kind = PropKind::WorkGroupSizeHint; |
| 151 | +}; |
| 152 | +template <> struct PropertyToKind<sub_group_size_key> { |
| 153 | + static constexpr PropKind Kind = PropKind::SubGroupSize; |
| 154 | +}; |
| 155 | + |
| 156 | +template <> |
| 157 | +struct IsCompileTimeProperty<work_group_size_key> : std::true_type {}; |
| 158 | +template <> |
| 159 | +struct IsCompileTimeProperty<work_group_size_hint_key> : std::true_type {}; |
| 160 | +template <> |
| 161 | +struct IsCompileTimeProperty<sub_group_size_key> : std::true_type {}; |
| 162 | + |
| 163 | +template <size_t Dim0, size_t... Dims> |
| 164 | +struct PropertyMetaInfo<work_group_size_key::value_t<Dim0, Dims...>> { |
| 165 | + static constexpr const char *name = "sycl-work-group-size"; |
| 166 | + static constexpr const char *value = SizeListToStr<Dim0, Dims...>::value; |
| 167 | +}; |
| 168 | +template <size_t Dim0, size_t... Dims> |
| 169 | +struct PropertyMetaInfo<work_group_size_hint_key::value_t<Dim0, Dims...>> { |
| 170 | + static constexpr const char *name = "sycl-work-group-size-hint"; |
| 171 | + static constexpr const char *value = SizeListToStr<Dim0, Dims...>::value; |
| 172 | +}; |
| 173 | +template <uint32_t Size> |
| 174 | +struct PropertyMetaInfo<sub_group_size_key::value_t<Size>> { |
| 175 | + static constexpr const char *name = "sycl-sub-group-size"; |
| 176 | + static constexpr uint32_t value = Size; |
| 177 | +}; |
| 178 | + |
| 179 | +template <typename T, typename = void> |
| 180 | +struct HasKernelPropertiesGetMethod : std::false_type {}; |
| 181 | + |
| 182 | +template <typename T> |
| 183 | +struct HasKernelPropertiesGetMethod< |
| 184 | + T, sycl::detail::void_t<decltype(std::declval<T>().get( |
| 185 | + std::declval<properties_tag>()))>> : std::true_type { |
| 186 | + using properties_t = |
| 187 | + decltype(std::declval<T>().get(std::declval<properties_tag>())); |
| 188 | +}; |
| 189 | + |
| 190 | +} // namespace detail |
| 191 | +} // namespace experimental |
| 192 | +} // namespace oneapi |
| 193 | +} // namespace ext |
| 194 | +} // __SYCL_INLINE_VER_NAMESPACE(_V1) |
| 195 | +} // namespace sycl |
0 commit comments