@@ -192,7 +192,7 @@ class device_global_base<
192192
193193} // namespace detail
194194
195- template <typename T, typename PropertyListT = empty_properties_t >
195+ template <typename T, typename PropertyListT, typename Condition >
196196class
197197#ifdef __SYCL_DEVICE_ONLY__
198198 // FIXME: Temporary work-around. Remove when fixed.
@@ -204,20 +204,82 @@ class
204204 " Property list is invalid." );
205205};
206206
207+ #define DEVICE_GLOBAL_COMMON_METHODS () \
208+ using detail::device_global_base< \
209+ T, detail::properties_t <Props...>>::device_global_base; \
210+ \
211+ device_global (const device_global &) = delete ; \
212+ device_global (const device_global &&) = delete ; \
213+ device_global &operator =(const device_global &) = delete ; \
214+ device_global &operator =(const device_global &&) = delete ; \
215+ const T &get () const noexcept { \
216+ __SYCL_HOST_NOT_SUPPORTED (" get()" ) \
217+ return *this ->get_ptr (); \
218+ } \
219+ \
220+ operator const T &() const noexcept { \
221+ __SYCL_HOST_NOT_SUPPORTED (" Implicit conversion of device_global to T" ) \
222+ return get (); \
223+ } \
224+ \
225+ template <class RelayT = T> \
226+ std::remove_reference_t < \
227+ decltype (std::declval<RelayT>()[std::declval<std::ptrdiff_t >()])> \
228+ &operator [](std::ptrdiff_t idx) noexcept { \
229+ __SYCL_HOST_NOT_SUPPORTED (" Subscript operator" ) \
230+ return (*this ->get_ptr ())[idx]; \
231+ } \
232+ \
233+ template <class RelayT = T> \
234+ const std::remove_reference_t < \
235+ decltype (std::declval<RelayT>()[std::declval<std::ptrdiff_t >()])> \
236+ &operator [](std::ptrdiff_t idx) const noexcept { \
237+ __SYCL_HOST_NOT_SUPPORTED (" Subscript operator" ) \
238+ return (*this ->get_ptr ())[idx]; \
239+ } \
240+ \
241+ template <class RelayT = T> \
242+ std::enable_if_t <detail::HasArrowOperator<RelayT>::value || \
243+ std::is_pointer_v<RelayT>, \
244+ RelayT> \
245+ &operator ->() noexcept { \
246+ __SYCL_HOST_NOT_SUPPORTED (" operator-> on a device_global" ) \
247+ return *this ->get_ptr (); \
248+ } \
249+ \
250+ template <class RelayT = T> \
251+ std::enable_if_t <detail::HasArrowOperator<RelayT>::value || \
252+ std::is_pointer_v<RelayT>, \
253+ const RelayT> \
254+ &operator ->() const noexcept { \
255+ __SYCL_HOST_NOT_SUPPORTED (" operator-> on a device_global" ) \
256+ return *this ->get_ptr (); \
257+ } \
258+ \
259+ template <typename propertyT> static constexpr bool has_property () { \
260+ return property_list_t ::template has_property<propertyT>(); \
261+ } \
262+ \
263+ template <typename propertyT> static constexpr auto get_property () { \
264+ return property_list_t ::template get_property<propertyT>(); \
265+ }
266+
207267template <typename T, typename ... Props>
208268class
209269#ifdef __SYCL_DEVICE_ONLY__
210270 [[__sycl_detail__::global_variable_allowed, __sycl_detail__::device_global,
271+ __sycl_detail__::device_constant,
211272 __sycl_detail__::add_ir_attributes_global_variable (
212273 " sycl-device-global-size" ,
213274 __SYCL_DEVICE_GLOBAL_PROP_META_INFO (Props)::name..., sizeof(T),
214275 __SYCL_DEVICE_GLOBAL_PROP_META_INFO(Props)::value...)]]
215276#endif
216- device_global<T, detail::properties_t <Props...>>
277+ device_global<T, detail::properties_t <Props...>,
278+ std::enable_if_t <detail::properties_t <
279+ Props...>::template has_property<device_constant_key>()>>
217280 : public detail::device_global_base<T, detail::properties_t<Props...>> {
218281
219282 using property_list_t = detail::properties_t <Props...>;
220- using base_t = detail::device_global_base<T, property_list_t >;
221283
222284public:
223285 using element_type = std::remove_extent_t <T>;
@@ -233,22 +295,43 @@ class
233295 static_assert (is_property_list<property_list_t >::value,
234296 " Property list is invalid." );
235297
236- // Inherit the base class' constructors
237- using detail::device_global_base<T, property_list_t >::device_global_base ;
298+ DEVICE_GLOBAL_COMMON_METHODS ()
299+ } ;
238300
239- constexpr device_global (const device_global &DG)
240- : base_t (static_cast <const base_t &>(DG)) {}
301+ template <typename T, typename ... Props>
302+ class
303+ #ifdef __SYCL_DEVICE_ONLY__
304+ [[__sycl_detail__::global_variable_allowed, __sycl_detail__::device_global,
305+ __sycl_detail__::add_ir_attributes_global_variable (
306+ " sycl-device-global-size" ,
307+ __SYCL_DEVICE_GLOBAL_PROP_META_INFO (Props)::name..., sizeof(T),
308+ __SYCL_DEVICE_GLOBAL_PROP_META_INFO(Props)::value...)]]
309+ #endif
310+ device_global<
311+ T, detail::properties_t <Props...>,
312+ std::enable_if_t <!(detail::properties_t <Props...>::
313+ template has_property<device_constant_key>())>>
314+ : public detail::device_global_base<T, detail::properties_t<Props...>> {
241315
242- device_global (const device_global &&) = delete ;
243- device_global &operator =(const device_global &) = delete ;
244- device_global &operator =(const device_global &&) = delete ;
316+ using property_list_t = detail::properties_t <Props...>;
245317
246- T &get () noexcept {
247- __SYCL_HOST_NOT_SUPPORTED (" get()" )
248- return *this ->get_ptr ();
249- }
318+ public:
319+ using element_type = std::remove_extent_t <T>;
250320
251- const T &get () const noexcept {
321+ #if !__cpp_consteval
322+ static_assert (std::is_trivially_default_constructible_v<T>,
323+ " Type T must be trivially default constructable (until C++20 "
324+ " consteval is supported and enabled.)" );
325+ #endif // !__cpp_consteval
326+ static_assert (std::is_trivially_destructible_v<T>,
327+ " Type T must be trivially destructible." );
328+
329+ static_assert (is_property_list<property_list_t >::value,
330+ " Property list is invalid." );
331+
332+ DEVICE_GLOBAL_COMMON_METHODS ()
333+
334+ T &get () noexcept {
252335 __SYCL_HOST_NOT_SUPPORTED (" get()" )
253336 return *this ->get_ptr ();
254337 }
@@ -258,58 +341,11 @@ class
258341 return get ();
259342 }
260343
261- operator const T &() const noexcept {
262- __SYCL_HOST_NOT_SUPPORTED (" Implicit conversion of device_global to T" )
263- return get ();
264- }
265-
266344 device_global &operator =(const T &newValue) noexcept {
267345 __SYCL_HOST_NOT_SUPPORTED (" Assignment operator" )
268346 *this ->get_ptr () = newValue;
269347 return *this ;
270348 }
271-
272- template <class RelayT = T>
273- std::remove_reference_t <
274- decltype (std::declval<RelayT>()[std::declval<std::ptrdiff_t >()])> &
275- operator [](std::ptrdiff_t idx) noexcept {
276- __SYCL_HOST_NOT_SUPPORTED (" Subscript operator" )
277- return (*this ->get_ptr ())[idx];
278- }
279-
280- template <class RelayT = T>
281- const std::remove_reference_t <
282- decltype (std::declval<RelayT>()[std::declval<std::ptrdiff_t >()])> &
283- operator [](std::ptrdiff_t idx) const noexcept {
284- __SYCL_HOST_NOT_SUPPORTED (" Subscript operator" )
285- return (*this ->get_ptr ())[idx];
286- }
287-
288- template <class RelayT = T>
289- std::enable_if_t <detail::HasArrowOperator<RelayT>::value ||
290- std::is_pointer_v<RelayT>,
291- RelayT> &
292- operator ->() noexcept {
293- __SYCL_HOST_NOT_SUPPORTED (" operator-> on a device_global" )
294- return *this ->get_ptr ();
295- }
296-
297- template <class RelayT = T>
298- std::enable_if_t <detail::HasArrowOperator<RelayT>::value ||
299- std::is_pointer_v<RelayT>,
300- const RelayT> &
301- operator ->() const noexcept {
302- __SYCL_HOST_NOT_SUPPORTED (" operator-> on a device_global" )
303- return *this ->get_ptr ();
304- }
305-
306- template <typename propertyT> static constexpr bool has_property () {
307- return property_list_t ::template has_property<propertyT>();
308- }
309-
310- template <typename propertyT> static constexpr auto get_property () {
311- return property_list_t ::template get_property<propertyT>();
312- }
313349};
314350
315351} // namespace ext::oneapi::experimental
0 commit comments