DPC++ Runtime
Runtime libraries for oneAPI DPC++
accessor_property_list.hpp
Go to the documentation of this file.
1 //==----- accessor_property_list.hpp --- SYCL accessor property list -------==//
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/access/access.hpp> // for mode, placeholder, target
12 #include <sycl/detail/defines.hpp> // for __SYCL_TYPE
13 #include <sycl/detail/pi.h> // for PI_ERROR_INVALID_VALUE
14 #include <sycl/detail/property_helper.hpp> // for DataLessPropKind, Prop...
15 #include <sycl/detail/property_list_base.hpp> // for PropertyListBase
16 #include <sycl/exception.hpp> // for invalid_object_error
17 #include <sycl/property_list.hpp> // for property_list
18 
19 #include <bitset> // for bitset
20 #include <memory> // for shared_ptr
21 #include <type_traits> // for conditional_t, enable_...
22 #include <vector> // for vector
23 
24 namespace sycl {
25 inline namespace _V1 {
26 // Forward declaration
27 template <typename DataT, int Dimensions, access::mode AccessMode,
29  typename PropertyListT>
30 class accessor;
31 namespace detail {
32 // This helper template must be specialized for nested instance template
33 // of each compile-time-constant property.
34 template <typename T> struct IsCompileTimePropertyInstance : std::false_type {};
35 } // namespace detail
36 namespace ext::oneapi {
37 
38 template <typename T> struct is_compile_time_property : std::false_type {};
39 
50 template <typename... PropsT>
51 class __SYCL_TYPE(accessor_property_list) accessor_property_list
52  : protected sycl::detail::PropertyListBase {
53  // These structures check if compile-time-constant property is present in
54  // list. For runtime properties this check is always true.
55  template <class T, class U> struct AreSameTemplate : std::is_same<T, U> {};
56  template <template <class...> class T, class T1, class T2>
57  struct AreSameTemplate<T<T1>, T<T2>> : std::true_type {};
58 
59  // Declaring non-type template parameters with auto is a C++17 feature. Since
60  // the extension is written against SYCL 2020, which implies use of C++17,
61  // there's no need to provide alternative implementations for older standards.
62  template <template <auto...> class T, auto... T1, auto... T2>
63  struct AreSameTemplate<T<T1...>, T<T2...>> : std::true_type {};
64 
65  // This template helps to identify if PropListT parameter pack contains
66  // property of PropT type, where PropT is a nested instance template of
67  // compile-time-constant property.
68  template <typename PropT, typename... PropListT> struct ContainsProperty;
69  template <typename PropT> struct ContainsProperty<PropT> : std::false_type {};
70  template <typename PropT, typename Head, typename... Tail>
71  struct ContainsProperty<PropT, Head, Tail...>
72  : std::conditional_t<AreSameTemplate<PropT, Head>::value, std::true_type,
73  ContainsProperty<PropT, Tail...>> {};
74 
75  // PropertyContainer is a helper structure, that holds list of properties.
76  // It is used to avoid multiple parameter packs in templates.
77  template <typename...> struct PropertyContainer {
78  using Head = void;
79  using Rest = void;
80  };
81  template <typename T, typename... Other>
82  struct PropertyContainer<T, Other...> {
83  using Head = T;
84  using Rest = PropertyContainer<Other...>;
85  };
86  template <typename T> struct PropertyContainer<T> {
87  using Head = T;
88  using Rest = void;
89  };
90 
91  // This template serves the same purpose as ContainsProperty, but operates on
92  // template template arguments.
93  template <typename ContainerT, template <auto...> typename PropT,
94  auto... Args>
95  struct ContainsPropertyInstance
96  : std::conditional_t<
97  !std::is_same_v<typename ContainerT::Head, void> &&
98  AreSameTemplate<PropT<Args...>,
99  typename ContainerT::Head>::value,
100  std::true_type,
101  ContainsPropertyInstance<typename ContainerT::Rest, PropT,
102  Args...>> {};
103 
104  template <template <auto...> typename PropT, auto... Args>
105  struct ContainsPropertyInstance<void, PropT, Args...> : std::false_type {};
106 
107  // This template checks if two lists of properties contain the same set of
108  // compile-time-constant properties in any order. Run time properties are
109  // skipped.
110  template <typename ContainerT, typename... OtherProps>
111  struct ContainsSameProperties
112  : std::conditional_t<
113  !sycl::detail::IsCompileTimePropertyInstance<
114  typename ContainerT::Head>::value ||
115  ContainsProperty<typename ContainerT::Head,
116  OtherProps...>::value,
117  ContainsSameProperties<typename ContainerT::Rest, OtherProps...>,
118  std::false_type> {};
119  template <typename... OtherProps>
120  struct ContainsSameProperties<void, OtherProps...> : std::true_type {};
121 
122  // This template helps to extract exact property instance type based on
123  // template template argument. If there's an instance of target property in
124  // ContainerT, find instance template and use it as type. Otherwise, just
125  // use void as return type.
126  template <typename ContainerT, template <auto...> class PropT, auto... Args>
127  struct GetCompileTimePropertyHelper {
128  using type = typename std::conditional_t<
129  AreSameTemplate<typename ContainerT::Head, PropT<Args...>>::value,
130  typename ContainerT::Head,
131  typename GetCompileTimePropertyHelper<typename ContainerT::Rest, PropT,
132  Args...>::type>;
133  };
134  template <typename Head, template <auto...> class PropT, auto... Args>
135  struct GetCompileTimePropertyHelper<PropertyContainer<Head>, PropT, Args...> {
136  using type = typename std::conditional_t<
137  AreSameTemplate<Head, PropT<Args...>>::value, Head, void>;
138  };
139 
140  // The structs validate that all objects passed are SYCL properties.
141  // Properties are either run time SYCL 1.2.1 properties, and thus derive from
142  // either DataLessPropertyBase or from PropertyWithDataBase, or
143  // compile-time-constant properties, and thus specialize
144  // IsCompileTimePropertyInstance template.
145  template <typename... Tail> struct AllProperties : std::true_type {};
146  template <typename T, typename... Tail>
147  struct AllProperties<T, Tail...>
148  : std::conditional_t<
149  std::is_base_of_v<sycl::detail::DataLessPropertyBase, T> ||
150  std::is_base_of_v<sycl::detail::PropertyWithDataBase, T> ||
151  sycl::detail::IsCompileTimePropertyInstance<T>::value,
152  AllProperties<Tail...>, std::false_type> {};
153 
154  accessor_property_list(
155  std::bitset<sycl::detail::DataLessPropKind::DataLessPropKindSize>
156  DataLessProps,
157  std::vector<std::shared_ptr<sycl::detail::PropertyWithDataBase>>
158  PropsWithData)
159  : sycl::detail::PropertyListBase(DataLessProps, PropsWithData) {}
160 
161 public:
162  template <
163  typename = typename std::enable_if_t<AllProperties<PropsT...>::value>>
164  accessor_property_list(PropsT... Props)
165  : sycl::detail::PropertyListBase(false) {
166  ctorHelper(Props...);
167  }
168 
169  accessor_property_list(const sycl::property_list &Props)
170  : sycl::detail::PropertyListBase(Props.MDataLessProps,
171  Props.MPropsWithData) {}
172 
173  template <typename... OtherProps,
174  typename = typename std::enable_if_t<
175  ContainsSameProperties<PropertyContainer<PropsT...>,
176  OtherProps...>::value &&
177  ContainsSameProperties<PropertyContainer<OtherProps...>,
178  PropsT...>::value>>
179  accessor_property_list(const accessor_property_list<OtherProps...> &OtherList)
180  : sycl::detail::PropertyListBase(OtherList.MDataLessProps,
181  OtherList.MPropsWithData) {}
182 
183  template <typename PropT, typename = typename std::enable_if_t<
184  !is_compile_time_property<PropT>::value>>
185  PropT get_property() const {
186  if (!has_property<PropT>())
187  throw sycl::invalid_object_error("The property is not found",
188  PI_ERROR_INVALID_VALUE);
189 
190  return get_property_helper<PropT>();
191  }
192 
193  template <class PropT>
194  typename std::enable_if_t<!is_compile_time_property<PropT>::value, bool>
195  has_property() const {
196  return has_property_helper<PropT>();
197  }
198 
199  template <typename T>
200  static constexpr bool has_property(
201  typename std::enable_if_t<is_compile_time_property<T>::value> * = 0) {
202  return ContainsPropertyInstance<PropertyContainer<PropsT...>,
203  T::template instance>::value;
204  }
205 
206  template <typename T>
207  static constexpr auto get_property(
208  typename std::enable_if_t<
209  is_compile_time_property<T>::value &&
210  ContainsPropertyInstance<PropertyContainer<PropsT...>,
211  T::template instance>::value> * = 0) {
212  return typename GetCompileTimePropertyHelper<PropertyContainer<PropsT...>,
213  T::template instance>::type{};
214  }
215 
216  operator sycl::property_list() const {
217  return property_list(MDataLessProps, MPropsWithData);
218  }
219 
220 private:
221  template <typename, int, access::mode, access::target, access::placeholder,
222  typename PropertyListT>
223  friend class sycl::accessor;
224 
225  template <typename... OtherProps> friend class accessor_property_list;
226 
227  friend class sycl::property_list;
228 
229  // Helper method, used by accessor to restrict conversions to compatible
230  // property lists.
231  template <typename... OtherPropsT>
232  static constexpr bool areSameCompileTimeProperties() {
233  return ContainsSameProperties<PropertyContainer<OtherPropsT...>,
234  PropsT...>::value;
235  }
236 };
237 } // namespace ext::oneapi
238 
239 } // namespace _V1
240 } // namespace sycl
Objects of the property_list class are containers for the SYCL properties.
class __SYCL_EBO __SYCL_SPECIAL_CLASS __SYCL_TYPE(accessor) accessor accessor(buffer< DataT, Dimensions, AllocatorT >) -> accessor< DataT, Dimensions, access::mode::read_write, target::device, access::placeholder::true_t >
Buffer accessor.
static constexpr bool has_property()
static constexpr auto get_property()
class __SYCL_EBO __SYCL_SPECIAL_CLASS __SYCL_TYPE(local_accessor) local_accessor class __SYCL_EBO __SYCL_SPECIAL_CLASS Dimensions
Definition: accessor.hpp:3235
class __SYCL_EBO __SYCL_SPECIAL_CLASS __SYCL_TYPE(local_accessor) local_accessor class __SYCL_EBO __SYCL_SPECIAL_CLASS IsPlaceholder
Definition: accessor.hpp:3236
class __SYCL_EBO __SYCL_SPECIAL_CLASS __SYCL_TYPE(local_accessor) local_accessor class __SYCL_EBO __SYCL_SPECIAL_CLASS AccessMode
Definition: accessor.hpp:3235
Definition: access.hpp:18