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>
12 #include <sycl/detail/common.hpp>
14 #include <sycl/property_list.hpp>
15 
16 namespace sycl {
18 // Forward declaration
19 template <typename DataT, int Dimensions, access::mode AccessMode,
21  typename PropertyListT>
22 class accessor;
23 namespace detail {
24 // This helper template must be specialized for nested instance template
25 // of each compile-time-constant property.
26 template <typename T> struct IsCompileTimePropertyInstance : std::false_type {};
27 } // namespace detail
28 namespace ext {
29 namespace oneapi {
30 
31 template <typename T> struct is_compile_time_property : std::false_type {};
32 
43 template <typename... PropsT>
44 class __SYCL_TYPE(accessor_property_list) accessor_property_list
45  : protected sycl::detail::PropertyListBase {
46  // These structures check if compile-time-constant property is present in
47  // list. For runtime properties this check is always true.
48  template <class T, class U> struct AreSameTemplate : std::is_same<T, U> {};
49  template <template <class...> class T, class T1, class T2>
50  struct AreSameTemplate<T<T1>, T<T2>> : std::true_type {};
51 #if __cplusplus >= 201703L
52  // Declaring non-type template parameters with auto is a C++17 feature. Since
53  // the extension is written against SYCL 2020, which implies use of C++17,
54  // there's no need to provide alternative implementations for older standards.
55  template <template <auto...> class T, auto... T1, auto... T2>
56  struct AreSameTemplate<T<T1...>, T<T2...>> : std::true_type {};
57 #endif
58  // This template helps to identify if PropListT parameter pack contains
59  // property of PropT type, where PropT is a nested instance template of
60  // compile-time-constant property.
61  template <typename PropT, typename... PropListT> struct ContainsProperty;
62  template <typename PropT> struct ContainsProperty<PropT> : std::false_type {};
63  template <typename PropT, typename Head, typename... Tail>
64  struct ContainsProperty<PropT, Head, Tail...>
65  : sycl::detail::conditional_t<AreSameTemplate<PropT, Head>::value,
66  std::true_type,
67  ContainsProperty<PropT, Tail...>> {};
68 
69  // PropertyContainer is a helper structure, that holds list of properties.
70  // It is used to avoid multiple parameter packs in templates.
71  template <typename...> struct PropertyContainer {
72  using Head = void;
73  using Rest = void;
74  };
75  template <typename T, typename... Other>
76  struct PropertyContainer<T, Other...> {
77  using Head = T;
78  using Rest = PropertyContainer<Other...>;
79  };
80  template <typename T> struct PropertyContainer<T> {
81  using Head = T;
82  using Rest = void;
83  };
84 
85 #if __cplusplus >= 201703L
86  // This template serves the same purpose as ContainsProperty, but operates on
87  // template template arguments.
88  template <typename ContainerT, template <auto...> typename PropT,
89  auto... Args>
90  struct ContainsPropertyInstance
92  !std::is_same_v<typename ContainerT::Head, void> &&
93  AreSameTemplate<PropT<Args...>,
94  typename ContainerT::Head>::value,
95  std::true_type,
96  ContainsPropertyInstance<typename ContainerT::Rest, PropT,
97  Args...>> {};
98 
99  template <template <auto...> typename PropT, auto... Args>
100  struct ContainsPropertyInstance<void, PropT, Args...> : std::false_type {};
101 #endif
102 
103  // This template checks if two lists of properties contain the same set of
104  // compile-time-constant properties in any order. Run time properties are
105  // skipped.
106  template <typename ContainerT, typename... OtherProps>
107  struct ContainsSameProperties
109  !sycl::detail::IsCompileTimePropertyInstance<
110  typename ContainerT::Head>::value ||
111  ContainsProperty<typename ContainerT::Head,
112  OtherProps...>::value,
113  ContainsSameProperties<typename ContainerT::Rest, OtherProps...>,
114  std::false_type> {};
115  template <typename... OtherProps>
116  struct ContainsSameProperties<void, OtherProps...> : std::true_type {};
117 
118 #if __cplusplus >= 201703L
119  // This template helps to extract exact property instance type based on
120  // template template argument. If there's an instance of target property in
121  // ContainerT, find instance template and use it as type. Otherwise, just
122  // use void as return type.
123  template <typename ContainerT, template <auto...> class PropT, auto... Args>
124  struct GetCompileTimePropertyHelper {
125  using type = typename sycl::detail::conditional_t<
126  AreSameTemplate<typename ContainerT::Head, PropT<Args...>>::value,
127  typename ContainerT::Head,
128  typename GetCompileTimePropertyHelper<typename ContainerT::Rest, PropT,
129  Args...>::type>;
130  };
131  template <typename Head, template <auto...> class PropT, auto... Args>
132  struct GetCompileTimePropertyHelper<PropertyContainer<Head>, PropT, Args...> {
133  using type = typename sycl::detail::conditional_t<
134  AreSameTemplate<Head, PropT<Args...>>::value, Head, void>;
135  };
136 #endif
137 
138  // The structs validate that all objects passed are SYCL properties.
139  // Properties are either run time SYCL 1.2.1 properties, and thus derive from
140  // either DataLessPropertyBase or from PropertyWithDataBase, or
141  // compile-time-constant properties, and thus specialize
142  // IsCompileTimePropertyInstance template.
143  template <typename... Tail> struct AllProperties : std::true_type {};
144  template <typename T, typename... Tail>
145  struct AllProperties<T, Tail...>
147  std::is_base_of<sycl::detail::DataLessPropertyBase, T>::value ||
148  std::is_base_of<sycl::detail::PropertyWithDataBase, T>::value ||
149  sycl::detail::IsCompileTimePropertyInstance<T>::value,
150  AllProperties<Tail...>, std::false_type> {};
151 
152  accessor_property_list(
153  std::bitset<sycl::detail::DataLessPropKind::DataLessPropKindSize>
154  DataLessProps,
155  std::vector<std::shared_ptr<sycl::detail::PropertyWithDataBase>>
156  PropsWithData)
157  : sycl::detail::PropertyListBase(DataLessProps, PropsWithData) {}
158 
159 public:
160  template <
161  typename = typename std::enable_if_t<AllProperties<PropsT...>::value>>
162  accessor_property_list(PropsT... Props)
163  : sycl::detail::PropertyListBase(false) {
164  ctorHelper(Props...);
165  }
166 
167  accessor_property_list(const sycl::property_list &Props)
168  : sycl::detail::PropertyListBase(Props.MDataLessProps,
169  Props.MPropsWithData) {}
170 
171  template <typename... OtherProps,
172  typename = typename std::enable_if_t<
173  ContainsSameProperties<PropertyContainer<PropsT...>,
174  OtherProps...>::value &&
175  ContainsSameProperties<PropertyContainer<OtherProps...>,
176  PropsT...>::value>>
177  accessor_property_list(const accessor_property_list<OtherProps...> &OtherList)
178  : sycl::detail::PropertyListBase(OtherList.MDataLessProps,
179  OtherList.MPropsWithData) {}
180 
181  template <typename PropT, typename = typename std::enable_if_t<
182  !is_compile_time_property<PropT>::value>>
183  PropT get_property() const {
184  if (!has_property<PropT>())
185  throw sycl::invalid_object_error("The property is not found",
186  PI_ERROR_INVALID_VALUE);
187 
188  return get_property_helper<PropT>();
189  }
190 
191  template <class PropT>
192  typename std::enable_if_t<!is_compile_time_property<PropT>::value, bool>
193  has_property() const {
194  return has_property_helper<PropT>();
195  }
196 
197 #if __cplusplus >= 201703L
198  template <typename T>
199  static constexpr bool has_property(
200  typename std::enable_if_t<is_compile_time_property<T>::value> * = 0) {
201  return ContainsPropertyInstance<PropertyContainer<PropsT...>,
202  T::template instance>::value;
203  }
204 
205  template <typename T>
206  static constexpr auto get_property(
207  typename std::enable_if_t<
208  is_compile_time_property<T>::value &&
209  ContainsPropertyInstance<PropertyContainer<PropsT...>,
210  T::template instance>::value> * = 0) {
211  return typename GetCompileTimePropertyHelper<PropertyContainer<PropsT...>,
212  T::template instance>::type{};
213  }
214 #endif
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 oneapi
238 } // namespace ext
239 
240 } // __SYCL_INLINE_VER_NAMESPACE(_V1)
241 } // namespace sycl
#define __SYCL_INLINE_VER_NAMESPACE(X)
static constexpr std::enable_if_t< HasProperty, typename FindCompileTimePropertyValueType< CTPropertyT, PropertiesT >::type > get_property()
Definition: properties.hpp:65
class __SYCL_EBO __SYCL_SPECIAL_CLASS __SYCL_TYPE(local_accessor) local_accessor class __SYCL_EBO __SYCL_SPECIAL_CLASS Dimensions
Definition: accessor.hpp:2782
class __SYCL_EBO __SYCL_SPECIAL_CLASS __SYCL_TYPE(local_accessor) local_accessor class __SYCL_EBO __SYCL_SPECIAL_CLASS IsPlaceholder
Definition: accessor.hpp:2783
class __SYCL_EBO __SYCL_SPECIAL_CLASS __SYCL_TYPE(local_accessor) local_accessor class __SYCL_EBO __SYCL_SPECIAL_CLASS AccessMode
Definition: accessor.hpp:2782
---— Error handling, matching OpenCL plugin semantics.
Definition: access.hpp:14