Skip to content

Commit a97e30d

Browse files
authored
[SYCL] Initial support for sycl_ext_oneapi_atomic16 (#15158)
Spec: https://github.com/intel/llvm/blob/sycl/sycl/doc/extensions/proposed/sycl_ext_oneapi_atomic16.asciidoc This patch adds support for atomic_ref half specialization and introduces a new atomic16 aspect. There is no yet native support for 16bit float compare_exchange function, extension is needed. 16bit int (incl. bfloat16) atomics will be supported later, when there is a spec allowing these instructions.
1 parent fad405c commit a97e30d

File tree

24 files changed

+287
-40
lines changed

24 files changed

+287
-40
lines changed

clang/lib/Driver/ToolChains/Clang.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10614,7 +10614,8 @@ static void getTripleBasedSPIRVTransOpts(Compilation &C,
1061410614
",+SPV_INTEL_tensor_float32_conversion"
1061510615
",+SPV_INTEL_optnone"
1061610616
",+SPV_KHR_non_semantic_info"
10617-
",+SPV_KHR_cooperative_matrix";
10617+
",+SPV_KHR_cooperative_matrix"
10618+
",+SPV_EXT_shader_atomic_float16_add";
1061810619
if (IsCPU)
1061910620
ExtArg += ",+SPV_INTEL_fp_max_error";
1062010621

clang/test/Driver/sycl-spirv-ext-old-model.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,8 @@
6161
// CHECK-DEFAULT-SAME:,+SPV_INTEL_tensor_float32_conversion
6262
// CHECK-DEFAULT-SAME:,+SPV_INTEL_optnone
6363
// CHECK-DEFAULT-SAME:,+SPV_KHR_non_semantic_info
64-
// CHECK-DEFAULT-SAME:,+SPV_KHR_cooperative_matrix"
64+
// CHECK-DEFAULT-SAME:,+SPV_KHR_cooperative_matrix
65+
// CHECK-DEFAULT-SAME:,+SPV_EXT_shader_atomic_float16_add"
6566
// CHECK-FPGA-HW: llvm-spirv{{.*}}"-spirv-ext=-all
6667
// CHECK-FPGA-HW-SAME:,+SPV_EXT_shader_atomic_float_add
6768
// CHECK-FPGA-HW-SAME:,+SPV_EXT_shader_atomic_float_min_max

clang/test/Driver/sycl-spirv-metadata-old-model.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
// RUN: FileCheck -check-prefix CHECK-WITHOUT %s
1010

1111
// CHECK-WITH: llvm-spirv{{.*}} "--spirv-preserve-auxdata"
12-
// CHECK-WITH-SAME: "-spirv-ext=-all,{{.*}},+SPV_KHR_cooperative_matrix"
12+
// CHECK-WITH-SAME: "-spirv-ext=-all,{{.*}},+SPV_EXT_shader_atomic_float16_add"
1313

1414
// CHECK-WITHOUT: "{{.*}}llvm-spirv"
1515
// CHECK-WITHOUT-NOT: --spirv-preserve-auxdata

clang/test/Driver/sycl-spirv-obj-old-model.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
// SPIRV_DEVICE_OBJ-SAME: "-o" "[[DEVICE_BC:.+\.bc]]"
1212
// SPIRV_DEVICE_OBJ: llvm-spirv{{.*}} "-o" "[[DEVICE_SPV:.+\.spv]]"
1313
// SPIRV_DEVICE_OBJ-SAME: "--spirv-preserve-auxdata"
14-
// SPIRV_DEVICE_OBJ-SAME: "-spirv-ext=-all,{{.*}},+SPV_KHR_cooperative_matrix"
14+
// SPIRV_DEVICE_OBJ-SAME: "-spirv-ext=-all,{{.*}},+SPV_EXT_shader_atomic_float16_add"
1515
// SPIRV_DEVICE_OBJ-SAME: "[[DEVICE_BC]]"
1616
// SPIRV_DEVICE_OBJ: clang{{.*}} "-cc1" "-triple" "x86_64-unknown-linux-gnu"
1717
// SPIRV_DEVICE_OBJ-SAME: "-fsycl-is-host"

clang/test/Driver/sycl-spirv-obj.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
// SPIRV_DEVICE_OBJ-SAME: "-o" "[[DEVICE_BC:.+\.bc]]"
1212
// SPIRV_DEVICE_OBJ: llvm-spirv{{.*}} "-o" "[[DEVICE_SPV:.+\.spv]]"
1313
// SPIRV_DEVICE_OBJ-SAME: "--spirv-preserve-auxdata"
14-
// SPIRV_DEVICE_OBJ-SAME: "-spirv-ext=-all,{{.*}},+SPV_KHR_cooperative_matrix"
14+
// SPIRV_DEVICE_OBJ-SAME: "-spirv-ext=-all,{{.*}},+SPV_EXT_shader_atomic_float16_add"
1515
// SPIRV_DEVICE_OBJ-SAME: "[[DEVICE_BC]]"
1616
// SPIRV_DEVICE_OBJ: clang-offload-packager{{.*}} "--image=file=[[DEVICE_SPV]]{{.*}}"
1717
// SPIRV_DEVICE_OBJ: clang{{.*}} "-cc1" "-triple" "x86_64-unknown-linux-gnu"

llvm/include/llvm/SYCLLowerIR/DeviceConfigFile.td

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,7 @@ def AspectExt_oneapi_queue_profiling_tag : Aspect<"ext_oneapi_queue_profiling_ta
8484
def AspectExt_oneapi_virtual_mem : Aspect<"ext_oneapi_virtual_mem">;
8585
def AspectExt_oneapi_cuda_cluster_group : Aspect<"ext_oneapi_cuda_cluster_group">;
8686
def AspectExt_intel_fpga_task_sequence : Aspect<"ext_intel_fpga_task_sequence">;
87+
def AspectExt_oneapi_atomic16 : Aspect<"ext_oneapi_atomic16">;
8788
// Deprecated aspects
8889
def AspectInt64_base_atomics : Aspect<"int64_base_atomics">;
8990
def AspectInt64_extended_atomics : Aspect<"int64_extended_atomics">;
@@ -146,7 +147,8 @@ def : TargetInfo<"__TestAspectList",
146147
AspectExt_oneapi_tangle_group, AspectExt_intel_matrix, AspectExt_oneapi_is_composite, AspectExt_oneapi_is_component,
147148
AspectExt_oneapi_graph, AspectExt_oneapi_limited_graph, AspectExt_oneapi_private_alloca,
148149
AspectExt_oneapi_queue_profiling_tag, AspectExt_oneapi_virtual_mem, AspectExt_oneapi_cuda_cluster_group,
149-
AspectExt_intel_fpga_task_sequence],
150+
AspectExt_intel_fpga_task_sequence,
151+
AspectExt_oneapi_atomic16],
150152
[]>;
151153
// This definition serves the only purpose of testing whether the deprecated aspect list defined in here and in SYCL RT
152154
// match.

sycl/include/CL/__spirv/spirv_ops.hpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -505,6 +505,7 @@ extern __DPCPP_SYCL_EXTERNAL
505505
macro(__attribute__((opencl_global)), Arg) \
506506
macro(__attribute__((opencl_local)), Arg) macro(, Arg)
507507

508+
__SPIRV_ATOMICS(__SPIRV_ATOMIC_FLOAT, _Float16)
508509
__SPIRV_ATOMICS(__SPIRV_ATOMIC_FLOAT, float)
509510
__SPIRV_ATOMICS(__SPIRV_ATOMIC_FLOAT, double)
510511
__SPIRV_ATOMICS(__SPIRV_ATOMIC_SIGNED, int)

sycl/include/sycl/atomic_ref.hpp

Lines changed: 65 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,13 @@
2525

2626
namespace sycl {
2727
inline namespace _V1 {
28+
29+
// forward declarartion
30+
namespace detail::half_impl {
31+
class half;
32+
}
33+
using half = detail::half_impl::half;
34+
2835
namespace detail {
2936

3037
using memory_order = sycl::memory_order;
@@ -36,7 +43,7 @@ template <typename T> struct IsValidAtomicRefType {
3643
std::is_same_v<T, long> || std::is_same_v<T, unsigned long> ||
3744
std::is_same_v<T, long long> || std::is_same_v<T, unsigned long long> ||
3845
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>);
4047
};
4148

4249
template <sycl::access::address_space AS> struct IsValidAtomicRefAddressSpace {
@@ -116,7 +123,7 @@ class atomic_ref_base {
116123
static_assert(
117124
detail::IsValidAtomicRefType<T>::value,
118125
"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 "
120127
"and pointer types");
121128
static_assert(detail::IsValidAtomicRefAddressSpace<AddressSpace>::value,
122129
"Invalid atomic address_space. Valid address spaces are: "
@@ -259,7 +266,7 @@ class atomic_ref_base {
259266
};
260267

261268
// 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,
263270
memory_scope DefaultScope, access::address_space AddressSpace,
264271
typename = void>
265272
class atomic_ref_impl
@@ -270,10 +277,9 @@ class atomic_ref_impl
270277
};
271278

272279
// Partial specialization for integral types
273-
template <typename T, bool IsAspectAtomic64AttrUsed, memory_order DefaultOrder,
280+
template <typename T, size_t SizeOfT, memory_order DefaultOrder,
274281
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,
277283
typename std::enable_if_t<std::is_integral_v<T>>>
278284
: public atomic_ref_base<T, DefaultOrder, DefaultScope, AddressSpace> {
279285

@@ -418,11 +424,11 @@ class atomic_ref_impl<T, IsAspectAtomic64AttrUsed, DefaultOrder, DefaultScope,
418424
};
419425

420426
// 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,
422428
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>>>
426432
: public atomic_ref_base<T, DefaultOrder, DefaultScope, AddressSpace> {
427433

428434
public:
@@ -534,15 +540,15 @@ class atomic_ref_impl<
534540
#else
535541
class [[__sycl_detail__::__uses_aspects__(aspect::atomic64)]] atomic_ref_impl<
536542
#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> {
541547
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=;
546552
};
547553

548554
// Partial specialization for 64-bit floating-point types needed for optional
@@ -554,28 +560,51 @@ class atomic_ref_impl<
554560
#else
555561
class [[__sycl_detail__::__uses_aspects__(aspect::atomic64)]] atomic_ref_impl<
556562
#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> {
561568
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=;
566595
};
567596

568597
// Partial specialization for pointer types
569598
// Arithmetic is emulated because target's representation of T* is unknown
570599
// 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,
572601
memory_scope DefaultScope, access::address_space AddressSpace>
573602
#ifndef __SYCL_DEVICE_ONLY__
574603
class atomic_ref_impl<
575604
#else
576605
class [[__sycl_detail__::__uses_aspects__(aspect::atomic64)]] atomic_ref_impl<
577606
#endif
578-
T *, IsAspectAtomic64AttrUsed, DefaultOrder, DefaultScope, AddressSpace>
607+
T *, SizeOfT, DefaultOrder, DefaultScope, AddressSpace>
579608
: public atomic_ref_base<uintptr_t, DefaultOrder, DefaultScope,
580609
AddressSpace> {
581610

@@ -713,15 +742,17 @@ template <typename T, memory_order DefaultOrder, memory_scope DefaultScope,
713742
access::address_space AddressSpace =
714743
access::address_space::generic_space>
715744
// 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)]]
717746
// 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> {
721752
public:
722-
using detail::atomic_ref_impl<T, sizeof(T) == 8, DefaultOrder, DefaultScope,
753+
using detail::atomic_ref_impl<T, sizeof(T), DefaultOrder, DefaultScope,
723754
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,
725756
AddressSpace>::operator=;
726757
};
727758

sycl/include/sycl/detail/spirv.hpp

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -560,6 +560,17 @@ AtomicLoad(multi_ptr<T, AddressSpace, IsDecorated> MPtr, memory_scope Scope,
560560
return sycl::bit_cast<T>(ResultInt);
561561
}
562562

563+
template <typename T, access::address_space AddressSpace,
564+
access::decorated IsDecorated>
565+
inline typename std::enable_if_t<std::is_same_v<T, half>, T>
566+
AtomicLoad(multi_ptr<T, AddressSpace, IsDecorated> MPtr, memory_scope Scope,
567+
memory_order Order) {
568+
auto *Ptr = GetMultiPtrDecoratedAs<_Float16>(MPtr);
569+
auto SPIRVOrder = getMemorySemanticsMask(Order);
570+
auto SPIRVScope = getScope(Scope);
571+
return __spirv_AtomicLoad(Ptr, SPIRVScope, SPIRVOrder);
572+
}
573+
563574
template <typename T, access::address_space AddressSpace,
564575
access::decorated IsDecorated>
565576
inline typename std::enable_if_t<std::is_integral<T>::value>
@@ -584,6 +595,17 @@ AtomicStore(multi_ptr<T, AddressSpace, IsDecorated> MPtr, memory_scope Scope,
584595
__spirv_AtomicStore(PtrInt, SPIRVScope, SPIRVOrder, ValueInt);
585596
}
586597

598+
template <typename T, access::address_space AddressSpace,
599+
access::decorated IsDecorated>
600+
inline typename std::enable_if_t<std::is_same_v<T, half>>
601+
AtomicStore(multi_ptr<T, AddressSpace, IsDecorated> MPtr, memory_scope Scope,
602+
memory_order Order, T Value) {
603+
auto *Ptr = GetMultiPtrDecoratedAs<_Float16>(MPtr);
604+
auto SPIRVOrder = getMemorySemanticsMask(Order);
605+
auto SPIRVScope = getScope(Scope);
606+
__spirv_AtomicStore(Ptr, SPIRVScope, SPIRVOrder, Value);
607+
}
608+
587609
template <typename T, access::address_space AddressSpace,
588610
access::decorated IsDecorated>
589611
inline typename std::enable_if_t<std::is_integral<T>::value, T>
@@ -610,6 +632,17 @@ AtomicExchange(multi_ptr<T, AddressSpace, IsDecorated> MPtr, memory_scope Scope,
610632
return sycl::bit_cast<T>(ResultInt);
611633
}
612634

635+
template <typename T, access::address_space AddressSpace,
636+
access::decorated IsDecorated>
637+
inline typename std::enable_if_t<std::is_same_v<half, T>, T>
638+
AtomicExchange(multi_ptr<T, AddressSpace, IsDecorated> MPtr, memory_scope Scope,
639+
memory_order Order, T Value) {
640+
auto *Ptr = GetMultiPtrDecoratedAs<_Float16>(MPtr);
641+
auto SPIRVOrder = getMemorySemanticsMask(Order);
642+
auto SPIRVScope = getScope(Scope);
643+
return __spirv_AtomicExchange(Ptr, SPIRVScope, SPIRVOrder, Value);
644+
}
645+
613646
template <typename T, access::address_space AddressSpace,
614647
access::decorated IsDecorated>
615648
inline typename std::enable_if_t<std::is_integral<T>::value, T>
@@ -643,6 +676,17 @@ AtomicFAdd(multi_ptr<T, AddressSpace, IsDecorated> MPtr, memory_scope Scope,
643676
return __spirv_AtomicFAddEXT(Ptr, SPIRVScope, SPIRVOrder, Value);
644677
}
645678

679+
template <typename T, access::address_space AddressSpace,
680+
access::decorated IsDecorated>
681+
inline typename std::enable_if_t<std::is_same_v<half, T>, T>
682+
AtomicFAdd(multi_ptr<T, AddressSpace, IsDecorated> MPtr, memory_scope Scope,
683+
memory_order Order, T Value) {
684+
auto *Ptr = GetMultiPtrDecoratedAs<_Float16>(MPtr);
685+
auto SPIRVOrder = getMemorySemanticsMask(Order);
686+
auto SPIRVScope = getScope(Scope);
687+
return __spirv_AtomicFAddEXT(Ptr, SPIRVScope, SPIRVOrder, Value);
688+
}
689+
646690
template <typename T, access::address_space AddressSpace,
647691
access::decorated IsDecorated>
648692
inline typename std::enable_if_t<std::is_integral<T>::value, T>
@@ -698,6 +742,17 @@ AtomicMin(multi_ptr<T, AddressSpace, IsDecorated> MPtr, memory_scope Scope,
698742
return __spirv_AtomicMin(Ptr, SPIRVScope, SPIRVOrder, Value);
699743
}
700744

745+
template <typename T, access::address_space AddressSpace,
746+
access::decorated IsDecorated>
747+
inline typename std::enable_if_t<std::is_same_v<half, T>, T>
748+
AtomicMin(multi_ptr<T, AddressSpace, IsDecorated> MPtr, memory_scope Scope,
749+
memory_order Order, T Value) {
750+
auto *Ptr = GetMultiPtrDecoratedAs<_Float16>(MPtr);
751+
auto SPIRVOrder = getMemorySemanticsMask(Order);
752+
auto SPIRVScope = getScope(Scope);
753+
return __spirv_AtomicFMinEXT(Ptr, SPIRVScope, SPIRVOrder, Value);
754+
}
755+
701756
template <typename T, access::address_space AddressSpace,
702757
access::decorated IsDecorated>
703758
inline typename std::enable_if_t<std::is_integral<T>::value, T>
@@ -720,6 +775,17 @@ AtomicMax(multi_ptr<T, AddressSpace, IsDecorated> MPtr, memory_scope Scope,
720775
return __spirv_AtomicMax(Ptr, SPIRVScope, SPIRVOrder, Value);
721776
}
722777

778+
template <typename T, access::address_space AddressSpace,
779+
access::decorated IsDecorated>
780+
inline typename std::enable_if_t<std::is_same_v<half, T>, T>
781+
AtomicMax(multi_ptr<T, AddressSpace, IsDecorated> MPtr, memory_scope Scope,
782+
memory_order Order, T Value) {
783+
auto *Ptr = GetMultiPtrDecoratedAs<_Float16>(MPtr);
784+
auto SPIRVOrder = getMemorySemanticsMask(Order);
785+
auto SPIRVScope = getScope(Scope);
786+
return __spirv_AtomicFMaxEXT(Ptr, SPIRVScope, SPIRVOrder, Value);
787+
}
788+
723789
// Native shuffles map directly to a shuffle intrinsic:
724790
// - The Intel SPIR-V extension natively supports all arithmetic types.
725791
// However, OpenCL extension natively supports float vectors,

sycl/include/sycl/detail/type_traits.hpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -333,6 +333,9 @@ template <typename T>
333333
struct is_floating_point
334334
: is_floating_point_impl<std::remove_cv_t<get_elem_type_t<T>>> {};
335335

336+
template <typename T>
337+
constexpr bool is_floating_point_v = is_floating_point<T>::value;
338+
336339
// is_arithmetic
337340
template <typename T>
338341
struct is_arithmetic

sycl/include/sycl/device_aspect_macros.hpp

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -390,6 +390,11 @@
390390
#define __SYCL_ALL_DEVICES_HAVE_ext_oneapi_bindless_images_sample_2d_usm__ 0
391391
#endif
392392

393+
#ifndef __SYCL_ALL_DEVICES_HAVE_ext_oneapi_atomic16__
394+
//__SYCL_ASPECT(ext_oneapi_oneapi_atomic16, 80)
395+
#define __SYCL_ALL_DEVICES_HAVE_ext_oneapi_atomic16__ 0
396+
#endif
397+
393398
#ifndef __SYCL_ANY_DEVICE_HAS_host__
394399
// __SYCL_ASPECT(host, 0)
395400
#define __SYCL_ANY_DEVICE_HAS_host__ 0
@@ -769,3 +774,8 @@
769774
//__SYCL_ASPECT(ext_oneapi_bindless_images_sample_2d_usm, 79)
770775
#define __SYCL_ANY_DEVICE_HAS_ext_oneapi_bindless_images_sample_2d_usm__ 0
771776
#endif
777+
778+
#ifndef __SYCL_ANY_DEVICE_HAS_ext_oneapi_atomic16__
779+
//__SYCL_ASPECT(ext_oneapi_oneapi_atomic16, 80)
780+
#define __SYCL_ANY_DEVICE_HAS_ext_oneapi_atomic16__ 0
781+
#endif

sycl/include/sycl/info/aspects.def

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,3 +70,4 @@ __SYCL_ASPECT(ext_oneapi_image_array, 76)
7070
__SYCL_ASPECT(ext_oneapi_unique_addressing_per_dim, 77)
7171
__SYCL_ASPECT(ext_oneapi_bindless_images_sample_1d_usm, 78)
7272
__SYCL_ASPECT(ext_oneapi_bindless_images_sample_2d_usm, 79)
73+
__SYCL_ASPECT(ext_oneapi_atomic16, 80)

0 commit comments

Comments
 (0)