25
25
26
26
namespace sycl {
27
27
inline namespace _V1 {
28
+
29
+ // forward declarartion
30
+ namespace detail ::half_impl {
31
+ class half ;
32
+ }
33
+ using half = detail::half_impl::half;
34
+
28
35
namespace detail {
29
36
30
37
using memory_order = sycl::memory_order;
@@ -36,7 +43,7 @@ template <typename T> struct IsValidAtomicRefType {
36
43
std::is_same_v<T, long > || std::is_same_v<T, unsigned long > ||
37
44
std::is_same_v<T, long long > || std::is_same_v<T, unsigned long long > ||
38
45
std::is_same_v<T, float > || std::is_same_v<T, double > ||
39
- std::is_pointer_v<T>);
46
+ std::is_pointer_v<T> || std::is_same_v<T, sycl::half> );
40
47
};
41
48
42
49
template <sycl::access::address_space AS> struct IsValidAtomicRefAddressSpace {
@@ -116,7 +123,7 @@ class atomic_ref_base {
116
123
static_assert (
117
124
detail::IsValidAtomicRefType<T>::value,
118
125
" Invalid atomic type. Valid types are int, unsigned int, long, "
119
- " unsigned long, long long, unsigned long long, float, double "
126
+ " unsigned long, long long, unsigned long long, sycl::half, float, double "
120
127
" and pointer types" );
121
128
static_assert (detail::IsValidAtomicRefAddressSpace<AddressSpace>::value,
122
129
" Invalid atomic address_space. Valid address spaces are: "
@@ -259,7 +266,7 @@ class atomic_ref_base {
259
266
};
260
267
261
268
// Hook allowing partial specializations to inherit atomic_ref_base
262
- template <typename T, bool IsAspectAtomic64AttrUsed , memory_order DefaultOrder,
269
+ template <typename T, size_t SizeOfT , memory_order DefaultOrder,
263
270
memory_scope DefaultScope, access::address_space AddressSpace,
264
271
typename = void >
265
272
class atomic_ref_impl
@@ -270,10 +277,9 @@ class atomic_ref_impl
270
277
};
271
278
272
279
// Partial specialization for integral types
273
- template <typename T, bool IsAspectAtomic64AttrUsed , memory_order DefaultOrder,
280
+ template <typename T, size_t SizeOfT , memory_order DefaultOrder,
274
281
memory_scope DefaultScope, access::address_space AddressSpace>
275
- class atomic_ref_impl <T, IsAspectAtomic64AttrUsed, DefaultOrder, DefaultScope,
276
- AddressSpace,
282
+ class atomic_ref_impl <T, SizeOfT, DefaultOrder, DefaultScope, AddressSpace,
277
283
typename std::enable_if_t <std::is_integral_v<T>>>
278
284
: public atomic_ref_base<T, DefaultOrder, DefaultScope, AddressSpace> {
279
285
@@ -418,11 +424,11 @@ class atomic_ref_impl<T, IsAspectAtomic64AttrUsed, DefaultOrder, DefaultScope,
418
424
};
419
425
420
426
// Partial specialization for floating-point types
421
- template <typename T, bool IsAspectAtomic64AttrUsed , memory_order DefaultOrder,
427
+ template <typename T, size_t SizeOfT , memory_order DefaultOrder,
422
428
memory_scope DefaultScope, access::address_space AddressSpace>
423
- class atomic_ref_impl <T, IsAspectAtomic64AttrUsed , DefaultOrder, DefaultScope,
424
- AddressSpace,
425
- typename std::enable_if_t <std::is_floating_point_v<T >>>
429
+ class atomic_ref_impl <T, SizeOfT , DefaultOrder, DefaultScope, AddressSpace ,
430
+ typename std:: enable_if_t <std::is_floating_point_v<T> ||
431
+ std::is_same_v<T, sycl::half >>>
426
432
: public atomic_ref_base<T, DefaultOrder, DefaultScope, AddressSpace> {
427
433
428
434
public:
@@ -534,15 +540,15 @@ class atomic_ref_impl<
534
540
#else
535
541
class [[__sycl_detail__::__uses_aspects__(aspect::atomic64)]] atomic_ref_impl<
536
542
#endif
537
- T, /* IsAspectAtomic64AttrUsed = */ true , DefaultOrder, DefaultScope,
538
- AddressSpace, typename std::enable_if_t <std::is_integral_v<T>>>
539
- : public atomic_ref_impl<T, /* IsAspectAtomic64AttrUsed = */ false ,
540
- DefaultOrder, DefaultScope, AddressSpace> {
543
+ T, /* SizeOfT = */ 8 , DefaultOrder, DefaultScope, AddressSpace ,
544
+ typename std::enable_if_t <std::is_integral_v<T>>>
545
+ : public atomic_ref_impl<T, /* SizeOfT = */ 4 , DefaultOrder, DefaultScope ,
546
+ AddressSpace> {
541
547
public:
542
- using atomic_ref_impl<T, /* IsAspectAtomic64AttrUsed = */ false , DefaultOrder,
543
- DefaultScope, AddressSpace>::atomic_ref_impl;
544
- using atomic_ref_impl<T, /* IsAspectAtomic64AttrUsed = */ false , DefaultOrder,
545
- DefaultScope, AddressSpace>::atomic_ref_impl::operator =;
548
+ using atomic_ref_impl<T, /* SizeOfT = */ 4 , DefaultOrder, DefaultScope ,
549
+ AddressSpace>::atomic_ref_impl;
550
+ using atomic_ref_impl<T, /* SizeOfT = */ 4 , DefaultOrder, DefaultScope ,
551
+ AddressSpace>::atomic_ref_impl::operator =;
546
552
};
547
553
548
554
// Partial specialization for 64-bit floating-point types needed for optional
@@ -554,28 +560,51 @@ class atomic_ref_impl<
554
560
#else
555
561
class [[__sycl_detail__::__uses_aspects__(aspect::atomic64)]] atomic_ref_impl<
556
562
#endif
557
- T, /* IsAspectAtomic64AttrUsed = */ true , DefaultOrder, DefaultScope,
558
- AddressSpace, typename std::enable_if_t <std::is_floating_point_v<T>>>
559
- : public atomic_ref_impl<T, /* IsAspectAtomic64AttrUsed = */ false ,
560
- DefaultOrder, DefaultScope, AddressSpace> {
563
+ T, /* SizeOfT = */ 8 , DefaultOrder, DefaultScope, AddressSpace,
564
+ typename std::enable_if_t <std::is_floating_point_v<T> ||
565
+ std::is_same_v<T, sycl::half>>>
566
+ : public atomic_ref_impl<T, /* SizeOfT = */ 4 , DefaultOrder, DefaultScope,
567
+ AddressSpace> {
561
568
public:
562
- using atomic_ref_impl<T, /* IsAspectAtomic64AttrUsed = */ false , DefaultOrder,
563
- DefaultScope, AddressSpace>::atomic_ref_impl;
564
- using atomic_ref_impl<T, /* IsAspectAtomic64AttrUsed = */ false , DefaultOrder,
565
- DefaultScope, AddressSpace>::atomic_ref_impl::operator =;
569
+ using atomic_ref_impl<T, /* SizeOfT = */ 4 , DefaultOrder, DefaultScope,
570
+ AddressSpace>::atomic_ref_impl;
571
+ using atomic_ref_impl<T, /* SizeOfT = */ 4 , DefaultOrder, DefaultScope,
572
+ AddressSpace>::atomic_ref_impl::operator =;
573
+ };
574
+
575
+ // Partial specialization for 16-bit floating-point types needed for optional
576
+ // kernel features
577
+ template <typename T, memory_order DefaultOrder, memory_scope DefaultScope,
578
+ access::address_space AddressSpace>
579
+ #ifndef __SYCL_DEVICE_ONLY__
580
+ class atomic_ref_impl <
581
+ #else
582
+ class
583
+ [[__sycl_detail__::__uses_aspects__(aspect::ext_oneapi_atomic16)]] atomic_ref_impl<
584
+ #endif
585
+ T, /* SizeOfT = */ 2 , DefaultOrder, DefaultScope, AddressSpace,
586
+ typename std::enable_if_t <std::is_floating_point_v<T> ||
587
+ std::is_same_v<T, sycl::half>>>
588
+ : public atomic_ref_impl<T, /* SizeOfT = */ 4 , DefaultOrder, DefaultScope,
589
+ AddressSpace> {
590
+ public:
591
+ using atomic_ref_impl<T, /* SizeOfT = */ 4 , DefaultOrder, DefaultScope,
592
+ AddressSpace>::atomic_ref_impl;
593
+ using atomic_ref_impl<T, /* SizeOfT = */ 4 , DefaultOrder, DefaultScope,
594
+ AddressSpace>::atomic_ref_impl::operator =;
566
595
};
567
596
568
597
// Partial specialization for pointer types
569
598
// Arithmetic is emulated because target's representation of T* is unknown
570
599
// TODO: Find a way to use intptr_t or uintptr_t atomics instead
571
- template <typename T, bool IsAspectAtomic64AttrUsed , memory_order DefaultOrder,
600
+ template <typename T, size_t SizeOfT , memory_order DefaultOrder,
572
601
memory_scope DefaultScope, access::address_space AddressSpace>
573
602
#ifndef __SYCL_DEVICE_ONLY__
574
603
class atomic_ref_impl <
575
604
#else
576
605
class [[__sycl_detail__::__uses_aspects__(aspect::atomic64)]] atomic_ref_impl<
577
606
#endif
578
- T *, IsAspectAtomic64AttrUsed , DefaultOrder, DefaultScope, AddressSpace>
607
+ T *, SizeOfT , DefaultOrder, DefaultScope, AddressSpace>
579
608
: public atomic_ref_base<uintptr_t , DefaultOrder, DefaultScope,
580
609
AddressSpace> {
581
610
@@ -713,15 +742,17 @@ template <typename T, memory_order DefaultOrder, memory_scope DefaultScope,
713
742
access::address_space AddressSpace =
714
743
access::address_space::generic_space>
715
744
// if sizeof(T) == 8 bytes, then the type T is optional kernel feature, so it
716
- // was decorated with [[__sycl_detail__::__uses_aspects__(aspect::atomic64)) ]]
745
+ // was decorated with [[__sycl_detail__::__uses_aspects__(aspect::atomic64)]]
717
746
// attribute in detail::atomic_ref_impl partial specializations above
718
- class atomic_ref
719
- : public detail::atomic_ref_impl<T, sizeof (T) == 8 , DefaultOrder,
720
- DefaultScope, AddressSpace> {
747
+ //
748
+ // if sizeof(T) == 2 bytes, then decorated with
749
+ // [[__sycl_detail__::__uses_aspects__(aspect::ext_oneapi_atomic16)]]
750
+ class atomic_ref : public detail ::atomic_ref_impl<T, sizeof (T), DefaultOrder,
751
+ DefaultScope, AddressSpace> {
721
752
public:
722
- using detail::atomic_ref_impl<T, sizeof (T) == 8 , DefaultOrder, DefaultScope,
753
+ using detail::atomic_ref_impl<T, sizeof (T), DefaultOrder, DefaultScope,
723
754
AddressSpace>::atomic_ref_impl;
724
- using detail::atomic_ref_impl<T, sizeof (T) == 8 , DefaultOrder, DefaultScope,
755
+ using detail::atomic_ref_impl<T, sizeof (T), DefaultOrder, DefaultScope,
725
756
AddressSpace>::operator =;
726
757
};
727
758
0 commit comments