DPC++ Runtime
Runtime libraries for oneAPI DPC++
annotated_arg.hpp
Go to the documentation of this file.
1 //==----------- annotated_arg.hpp - SYCL annotated_arg extension -----------==//
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 <cstddef>
12 #include <type_traits>
13 
15 #include <sycl/exception.hpp>
18 
19 namespace sycl {
21 namespace ext {
22 namespace oneapi {
23 namespace experimental {
24 
25 namespace detail {
26 
27 // Type-trait for checking if a type defines `operator[]`.
28 template <typename T>
31  !std::is_void<decltype(std::declval<T>().operator[](0))>::value>{};
32 
33 // Deduce a `properties<>` type from given variadic properties
34 template <typename... Args> struct DeducedProperties {
35  using type = decltype(properties{std::declval<Args>()...});
36 };
37 
38 // Partial specialization for deducing a `properties<>` type by forwarding the
39 // given `properties<>` type
40 template <typename... Args>
41 struct DeducedProperties<detail::properties_t<Args...>> {
42  using type = detail::properties_t<Args...>;
43 };
44 
45 } // namespace detail
46 
47 // Deduction guide
48 template <typename T, typename... Args>
49 annotated_arg(T, Args...)
50  -> annotated_arg<T, typename detail::DeducedProperties<Args...>::type>;
51 
52 template <typename T, typename old, typename... ArgT>
53 annotated_arg(annotated_arg<T, old>, properties<std::tuple<ArgT...>>)
54  -> annotated_arg<
56 
57 template <typename T, typename PropertyListT = detail::empty_properties_t>
59  // This should always fail when instantiating the unspecialized version.
61  "Property list is invalid.");
62 };
63 
64 // Partial specialization for pointer type
65 template <typename T, typename... Props>
68  using property_list_t = detail::properties_t<Props...>;
69 
70 #ifdef __SYCL_DEVICE_ONLY__
72 #else
73  using global_pointer_t = T *;
74 #endif
75 
77 
78  template <typename T2, typename PropertyListT> friend class annotated_arg;
79 
80 #ifdef __SYCL_DEVICE_ONLY__
81  void __init([[__sycl_detail__::add_ir_attributes_kernel_parameter(
84  obj = _obj;
85  }
86 #endif
87 
88 public:
89  static_assert(is_property_list<property_list_t>::value,
90  "Property list is invalid.");
91 
92  annotated_arg() noexcept = default;
93  annotated_arg(const annotated_arg &) = default;
94  annotated_arg &operator=(annotated_arg &) = default;
95 
96  annotated_arg(T *_ptr,
97  const property_list_t &PropList = properties{}) noexcept
98  : obj(global_pointer_t(_ptr)) {
99  (void)PropList;
100  }
101 
102  // Constructs an annotated_arg object from a raw pointer and variadic
103  // properties. The new property set contains all properties of the input
104  // variadic properties. The same property in `Props...` and
105  // `PropertyValueTs...` must have the same property value.
106  template <typename... PropertyValueTs>
107  annotated_arg(T *_ptr, const PropertyValueTs &...props) noexcept
108  : obj(global_pointer_t(_ptr)) {
109  static_assert(
110  std::is_same<
111  property_list_t,
112  detail::merged_properties_t<property_list_t,
113  decltype(properties{props...})>>::value,
114  "The property list must contain all properties of the input of the "
115  "constructor");
116  }
117 
118  // Constructs an annotated_arg object from another annotated_arg object.
119  // The new property set contains all properties of the input
120  // annotated_arg object. The same property in `Props...` and `PropertyList2`
121  // must have the same property value.
122  template <typename T2, typename PropertyList2>
123  explicit annotated_arg(const annotated_arg<T2, PropertyList2> &other) noexcept
124  : obj(other.obj) {
125  static_assert(std::is_convertible<T2, T *>::value,
126  "The underlying data type of the input annotated_arg is not "
127  "compatible");
128 
129  static_assert(
130  std::is_same<
131  property_list_t,
133  "The constructed annotated_arg type must contain all the properties of "
134  "the input annotated_arg");
135  }
136 
137  // Constructs an annotated_arg object from another annotated_arg object and a
138  // property list. The new property set is the union of property lists
139  // `PropertyListU` and `PropertyListV`. The same property in `PropertyListU`
140  // and `PropertyListV` must have the same property value.
141  template <typename T2, typename PropertyListU, typename PropertyListV>
143  const PropertyListV &proplist) noexcept
144  : obj(other.obj) {
145  (void)proplist;
146  static_assert(std::is_convertible<T2, T *>::value,
147  "The underlying data type of the input annotated_arg is not "
148  "compatible");
149 
150  static_assert(
151  std::is_same<property_list_t, detail::merged_properties_t<
152  PropertyListU, PropertyListV>>::value,
153  "The property list of constructed annotated_arg type must be the union "
154  "of the input property lists");
155  }
156 
157  operator T *() noexcept { return obj; }
158  operator T *() const noexcept { return obj; }
159 
160  T &operator[](std::ptrdiff_t idx) const noexcept { return obj[idx]; }
161 
162  template <typename PropertyT> static constexpr bool has_property() {
163  return property_list_t::template has_property<PropertyT>();
164  }
165 
166  template <typename PropertyT> static constexpr auto get_property() {
167  return property_list_t::template get_property<PropertyT>();
168  }
169 };
170 
171 // Partial specialization for non-pointer type
172 template <typename T, typename... Props>
174 __SYCL_TYPE(annotated_arg) annotated_arg<T, detail::properties_t<Props...>> {
175  using property_list_t = detail::properties_t<Props...>;
176 
177  template <typename T2, typename PropertyListT> friend class annotated_arg;
178 
179  T obj;
180 
181 #ifdef __SYCL_DEVICE_ONLY__
182  void __init([[__sycl_detail__::add_ir_attributes_kernel_parameter(
183  detail::PropertyMetaInfo<Props>::name...,
184  detail::PropertyMetaInfo<Props>::value...)]] T _obj) {
185  obj = _obj;
186  }
187 #endif
188 
189 public:
190  static_assert(is_device_copyable_v<T>, "Type T must be device copyable.");
191  static_assert(is_property_list<property_list_t>::value,
192  "Property list is invalid.");
193  static_assert(check_property_list<T, Props...>::value,
194  "The property list contains invalid property.");
195 
196  annotated_arg() noexcept = default;
197  annotated_arg(const annotated_arg &) = default;
198  annotated_arg &operator=(annotated_arg &) = default;
199 
200  annotated_arg(const T &_obj,
201  const property_list_t &PropList = properties{}) noexcept
202  : obj(_obj) {
203  (void)PropList;
204  }
205 
206  // Constructs an annotated_arg object from a raw pointer and variadic
207  // properties. The new property set contains all properties of the input
208  // variadic properties. The same property in `Props...` and
209  // `PropertyValueTs...` must have the same property value.
210  template <typename... PropertyValueTs>
211  annotated_arg(const T &_obj, PropertyValueTs... props) noexcept : obj(_obj) {
212  static_assert(
213  std::is_same<
214  property_list_t,
215  detail::merged_properties_t<property_list_t,
216  decltype(properties{props...})>>::value,
217  "The property list must contain all properties of the input of the "
218  "constructor");
219  }
220 
221  // Constructs an annotated_arg object from another annotated_arg object.
222  // The new property set contains all properties of the input
223  // annotated_arg object. The same property in `Props...` and `PropertyList2`
224  // must have the same property value.
225  template <typename T2, typename PropertyList2>
226  explicit annotated_arg(const annotated_arg<T2, PropertyList2> &other) noexcept
227  : obj(other.obj) {
228  static_assert(std::is_convertible<T2, T>::value,
229  "The underlying data type of the input annotated_arg is not "
230  "compatible");
231 
232  static_assert(
233  std::is_same<
234  property_list_t,
235  detail::merged_properties_t<property_list_t, PropertyList2>>::value,
236  "The constructed annotated_arg type must contain all the properties of "
237  "the input annotated_arg");
238  }
239 
240  // Constructs an annotated_arg object from another annotated_arg object and a
241  // property list. The new property set is the union of property lists
242  // `PropertyListU` and `PropertyListV`. The same property in `PropertyListU`
243  // and `PropertyListV` must have the same property value.
244  template <typename T2, typename PropertyListU, typename PropertyListV>
245  explicit annotated_arg(const annotated_arg<T2, PropertyListU> &other,
246  const PropertyListV &proplist) noexcept
247  : obj(other.obj) {
248  (void)proplist;
249  static_assert(std::is_convertible<T2, T>::value,
250  "The underlying data type of the input annotated_arg is not "
251  "compatible");
252 
253  static_assert(
254  std::is_same<property_list_t, detail::merged_properties_t<
255  PropertyListU, PropertyListV>>::value,
256  "The property list of constructed annotated_arg type must be the union "
257  "of the input property lists");
258  }
259 
260  operator T() noexcept { return obj; }
261  operator T() const noexcept { return obj; }
262 
263  template <class RelayT = T>
264  std::enable_if_t<detail::HasSubscriptOperator<RelayT>::value,
265  decltype(std::declval<RelayT>().operator[](0))> &
266  operator[](std::ptrdiff_t idx) const noexcept {
267  return obj.operator[](idx);
268  }
269 
270  template <typename PropertyT> static constexpr bool has_property() {
271  return property_list_t::template has_property<PropertyT>();
272  }
273 
274  template <typename PropertyT> static constexpr auto get_property() {
275  return property_list_t::template get_property<PropertyT>();
276  }
277 };
278 
279 } // namespace experimental
280 } // namespace oneapi
281 } // namespace ext
282 } // __SYCL_INLINE_VER_NAMESPACE(_V1)
283 } // namespace sycl
properties.hpp
T
sycl::_V1::ext::oneapi::experimental::detail::HasSubscriptOperator
Definition: annotated_arg.hpp:29
sycl::_V1::ext::oneapi::experimental::annotated_arg
Definition: annotated_arg.hpp:58
sycl::_V1::detail::bool_constant
std::integral_constant< bool, V > bool_constant
Definition: stl_type_traits.hpp:40
sycl::_V1::ext::oneapi::experimental::obj
global_pointer_t obj
Definition: annotated_arg.hpp:76
__SYCL_INLINE_VER_NAMESPACE
#define __SYCL_INLINE_VER_NAMESPACE(X)
Definition: defines_elementary.hpp:11
sycl::_V1::ext::oneapi::experimental::detail::DeducedProperties::type
decltype(properties{std::declval< Args >()...}) type
Definition: annotated_arg.hpp:35
sycl::_V1::ext::oneapi::experimental::properties
Definition: properties.hpp:126
sycl::_V1::ext::oneapi::experimental::operator[]
T & operator[](std::ptrdiff_t idx) const noexcept
Definition: annotated_arg.hpp:160
properties.hpp
sycl
---— Error handling, matching OpenCL plugin semantics.
Definition: access.hpp:14
__SYCL_SPECIAL_CLASS
#define __SYCL_SPECIAL_CLASS
Definition: defines.hpp:30
stl_type_traits.hpp
sycl::_V1::ext::oneapi::experimental::annotated_arg
annotated_arg(const T &_obj, PropertyValueTs... props) noexcept
Definition: annotated_arg.hpp:211
sycl::_V1::ext::oneapi::experimental::has_property
static constexpr bool has_property()
Definition: annotated_arg.hpp:162
sycl::_V1::ext::oneapi::experimental::global_pointer_t
T * global_pointer_t
Definition: annotated_arg.hpp:73
sycl::_V1::ext::oneapi::experimental::detail::DeducedProperties
Definition: annotated_arg.hpp:34
sycl::_V1::ext::oneapi::experimental::detail::merged_properties_t
typename merged_properties< LHSPropertiesT, RHSPropertiesT >::type merged_properties_t
Definition: properties.hpp:222
sycl::_V1::ext::oneapi::experimental::is_property_list
Definition: properties.hpp:190
sycl::_V1::ext::oneapi::experimental::get_property
static constexpr auto get_property()
Definition: annotated_arg.hpp:166
sycl::_V1::ext::oneapi::experimental::detail::PropertyMetaInfo
Definition: property.hpp:212
sycl::_V1::multi_ptr::pointer
std::conditional_t< is_decorated, decorated_type *, std::add_pointer_t< value_type > > pointer
Definition: multi_ptr.hpp:90
exception.hpp
__SYCL_TYPE
#define __SYCL_TYPE(x)
Definition: defines.hpp:40
sycl::_V1::ext::oneapi::experimental::detail::properties_t
properties< std::tuple< PropertyValueTs... > > properties_t
Definition: properties.hpp:209