Skip to content

Commit aa4e878

Browse files
authored
[SYCL][ESIMD] Add srnd API to ESIMD (#12167)
1 parent ec98d47 commit aa4e878

File tree

4 files changed

+97
-1
lines changed

4 files changed

+97
-1
lines changed

llvm/lib/SYCLLowerIR/ESIMD/LowerESIMD.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -659,7 +659,8 @@ class ESIMDIntrinDescTable {
659659
{"__spirv_ConvertBF16ToFINTEL", {a(0)}}},
660660
{"addc", {"addc", {l(0)}}},
661661
{"subb", {"subb", {l(0)}}},
662-
{"bfn", {"bfn", {a(0), a(1), a(2), t(0)}}}};
662+
{"bfn", {"bfn", {a(0), a(1), a(2), t(0)}}},
663+
{"srnd", {"srnd", {a(0), a(1)}}}};
663664
}
664665
// clang-format on
665666

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

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -146,6 +146,12 @@ __ESIMD_INTRIN __ESIMD_raw_vec_t(T, N)
146146
__esimd_bfn(__ESIMD_raw_vec_t(T, N) src0, __ESIMD_raw_vec_t(T, N) src1,
147147
__ESIMD_raw_vec_t(T, N) src2) __ESIMD_INTRIN_END;
148148

149+
template <int N>
150+
__ESIMD_INTRIN __ESIMD_raw_vec_t(sycl::half, N)
151+
__esimd_srnd(__ESIMD_DNS::vector_type_t<float, N> src1,
152+
__ESIMD_DNS::vector_type_t<uint16_t, N> src2)
153+
__ESIMD_INTRIN_END;
154+
149155
#undef __ESIMD_raw_vec_t
150156
#undef __ESIMD_cpp_vec_t
151157

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

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1665,6 +1665,19 @@ __ESIMD_NS::simd<T, N> dp4(__ESIMD_NS::simd<T, N> v1,
16651665
return retv;
16661666
}
16671667

1668+
/// srnd - perform stochastic rounding.
1669+
/// Supported conversions:
1670+
/// float -> half
1671+
/// Available on PVC_XT+
1672+
/// \param src0 the operand to be rounded
1673+
/// \param src1 random number used for rounding
1674+
/// \return the converted value
1675+
template <int N>
1676+
ESIMD_INLINE __ESIMD_NS::simd<sycl::half, N>
1677+
srnd(__ESIMD_NS::simd<float, N> src0, __ESIMD_NS::simd<uint16_t, N> src1) {
1678+
return __esimd_srnd<N>(src0.data(), src1.data());
1679+
}
1680+
16681681
/// @} sycl_esimd_math
16691682

16701683
/// @addtogroup sycl_esimd_logical

sycl/test-e2e/ESIMD/srnd.cpp

Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
//==---------------- srnd.cpp - DPC++ ESIMD srnd function test -----------==//
2+
//
3+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM
4+
// Exceptions. See https://llvm.org/LICENSE.txt for license information.
5+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6+
//
7+
//===----------------------------------------------------------------------===//
8+
// REQUIRES: gpu-intel-pvc
9+
// RUN: %{build} -o %t.out
10+
// RUN: %{run} %t.out
11+
12+
#include "esimd_test_utils.hpp"
13+
14+
#include <sycl/ext/intel/esimd.hpp>
15+
#include <sycl/sycl.hpp>
16+
17+
#include <iostream>
18+
19+
using namespace sycl;
20+
using namespace sycl::ext::intel::esimd;
21+
using namespace sycl::ext::intel::experimental::esimd;
22+
23+
bool test(queue &Q) {
24+
25+
constexpr int N = 8;
26+
float *Input = malloc_shared<float>(N, Q);
27+
half *Output = malloc_shared<half>(N * 2, Q);
28+
29+
for (int i = 0; i < N; ++i) {
30+
float value = esimd_test::getRandomValue<float>();
31+
while (fabs(value) > std::numeric_limits<half>::max() ||
32+
fabs(value) < std::numeric_limits<half>::min() || std::isnan(value))
33+
value = esimd_test::getRandomValue<float>();
34+
35+
Input[i] = value;
36+
}
37+
38+
Q.single_task([=]() SYCL_ESIMD_KERNEL {
39+
simd<float, N> InputVector;
40+
InputVector.copy_from(Input);
41+
{
42+
simd<uint16_t, N> RandomVector(0);
43+
simd<half, N> OutputVector = srnd(InputVector, RandomVector);
44+
OutputVector.copy_to(Output);
45+
}
46+
{
47+
simd<uint16_t, N> RandomVector(0xFFFF);
48+
simd<half, N> OutputVector = srnd(InputVector, RandomVector);
49+
OutputVector.copy_to(Output + N);
50+
}
51+
}).wait();
52+
bool ReturnValue = true;
53+
for (int i = 0; i < N; ++i) {
54+
if (Output[i + N] == Output[i]) {
55+
ReturnValue = false;
56+
break;
57+
}
58+
}
59+
60+
free(Input, Q);
61+
free(Output, Q);
62+
return ReturnValue;
63+
}
64+
65+
// --- The entry point.
66+
67+
int main(void) {
68+
queue Q(esimd_test::ESIMDSelector, esimd_test::createExceptionHandler());
69+
esimd_test::printTestLabel(Q);
70+
bool Pass = true;
71+
72+
Pass &= test(Q);
73+
74+
std::cout << (Pass ? "Test Passed\n" : "Test FAILED\n");
75+
return Pass ? 0 : 1;
76+
}

0 commit comments

Comments
 (0)