Skip to content

Commit 690efd8

Browse files
authored
[SYCL][ESIMD] Use SPIR-V rsqrt for double (#15609)
The driver added a perf optimization for this case and asked us to use `__spirv_ocl_rsqrt` instead of `inv(sqrt)` or `__spirv_ocl_native_rsqrt` for double `rsqrt` only. There is already an E2E test for rsqrt. Signed-off-by: Sarnie, Nick <nick.sarnie@intel.com>
1 parent 1d58d6b commit 690efd8

File tree

3 files changed

+26
-4
lines changed

3 files changed

+26
-4
lines changed

sycl/include/sycl/ext/intel/esimd/detail/math_intrin.hpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,11 @@ extern __DPCPP_SYCL_EXTERNAL __ESIMD_raw_vec_t(T, N)
102102
__spirv_ocl_fmax(__ESIMD_raw_vec_t(T, N),
103103
__ESIMD_raw_vec_t(T, N)) __ESIMD_INTRIN_END;
104104

105+
template <typename T> extern __DPCPP_SYCL_EXTERNAL T __spirv_ocl_rsqrt(T);
106+
template <typename T, int N>
107+
extern __DPCPP_SYCL_EXTERNAL __ESIMD_raw_vec_t(T, N)
108+
__spirv_ocl_rsqrt(__ESIMD_raw_vec_t(T, N)) __ESIMD_INTRIN_END;
109+
105110
// saturation intrinsics
106111
template <typename T0, typename T1, int SZ>
107112
__ESIMD_INTRIN __ESIMD_raw_vec_t(T0, SZ)

sycl/include/sycl/ext/intel/esimd/math.hpp

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -456,20 +456,24 @@ __ESIMD_UNARY_INTRINSIC_DEF(__ESIMD_EMATH_SPIRV_COND, cos, cos)
456456
template <class T, int N, class Sat = saturation_off_tag>
457457
__ESIMD_API std::enable_if_t<std::is_same_v<T, double>, simd<double, N>>
458458
rsqrt(simd<T, N> src, Sat sat = {}) {
459+
__ESIMD_DNS::vector_type_t<__ESIMD_DNS::__raw_t<double>, N> res =
460+
__spirv_ocl_rsqrt<__ESIMD_DNS::__raw_t<double>, N>(src.data());
459461
if constexpr (std::is_same_v<Sat, saturation_off_tag>)
460-
return inv(sqrt(src));
462+
return res;
461463
else
462-
return esimd::saturate<double>(inv(sqrt(src)));
464+
return esimd::saturate<double>(simd<double, N>(res));
463465
}
464466

465467
/** Scalar version. */
466468
template <class T, class Sat = saturation_off_tag>
467469
__ESIMD_API std::enable_if_t<std::is_same_v<T, double>, double>
468470
rsqrt(T src, Sat sat = {}) {
471+
__ESIMD_DNS::__raw_t<double> res =
472+
__spirv_ocl_rsqrt<__ESIMD_DNS::__raw_t<double>>(src);
469473
if constexpr (std::is_same_v<Sat, saturation_off_tag>)
470-
return inv(sqrt(src));
474+
return res;
471475
else
472-
return esimd::saturate<double>(inv(sqrt(src)));
476+
return esimd::saturate<double>(simd<double, 1>(res))[0];
473477
}
474478

475479
#undef __ESIMD_UNARY_INTRINSIC_DEF
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
// RUN: %clangxx -fsycl -fsycl-device-only -S -emit-llvm %s -o - | \
2+
// RUN: FileCheck %s --implicit-check-not=recip
3+
4+
// This test checks that all we use SPIR-V rsqrt for doubles.
5+
6+
#include <sycl/ext/intel/esimd.hpp>
7+
#include <sycl/sycl.hpp>
8+
9+
SYCL_ESIMD_KERNEL SYCL_EXTERNAL void kernel() {
10+
__ESIMD_NS::simd<double, 16> v(0, 1);
11+
v = __ESIMD_NS::rsqrt(v);
12+
// CHECK: __spirv_ocl_rsqrt
13+
}

0 commit comments

Comments
 (0)