Skip to content

Commit 4a5678f

Browse files
committed
[SYCL] Add E2E test for -foffload-fp32-prec-div/sqrt
Signed-off-by: Sidorov, Dmitry <[email protected]>
1 parent 0dfb947 commit 4a5678f

File tree

1 file changed

+67
-0
lines changed

1 file changed

+67
-0
lines changed
Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
// RUN: %{build} -foffload-fp32-prec-div -foffload-fp32-prec-sqrt -o %t.out
2+
// RUN: %{run} %t.out
3+
4+
// Test if div and sqrt become precise from IEEE-754 perspective when
5+
// -foffload-fp32-prec-div -foffload-fp32-prec-sqrt are passed.
6+
7+
#include <cmath>
8+
#include <sycl/ext/oneapi/experimental/builtins.hpp>
9+
#include <sycl/sycl.hpp>
10+
11+
constexpr float value = 560.0f;
12+
constexpr float divider = 280.0f;
13+
14+
// Reference
15+
// https://github.com/KhronosGroup/SYCL-CTS/blob/SYCL-2020/util/accuracy.h
16+
template <typename T> T get_ulp_std(T x) {
17+
const T inf = std::numeric_limits<T>::infinity();
18+
const T negative = std::fabs(std::nextafter(x, -inf) - x);
19+
const T positive = std::fabs(std::nextafter(x, inf) - x);
20+
return std::fmin(negative, positive);
21+
}
22+
23+
template <typename T> int ulp_difference(const T &lhs, const T &rhs) {
24+
return get_ulp_std(lhs) - get_ulp_std(rhs);
25+
}
26+
27+
void test_div() {
28+
sycl::queue q(sycl::default_selector_v, sycl::property::queue::in_order());
29+
float *in_value = (float *)sycl::malloc_shared(sizeof(float), q);
30+
float *in_divider = (float *)sycl::malloc_shared(sizeof(float), q);
31+
float *output = (float *)sycl::malloc_shared(sizeof(float), q);
32+
*in_value = value;
33+
*in_divider = divider;
34+
q.submit([&](sycl::handler &h) {
35+
h.single_task([=] {
36+
float res = *in_value / *in_divider;
37+
*output = res;
38+
});
39+
}).wait();
40+
41+
float hostRef = value / divider;
42+
int ulpDiff = ulp_difference<float>(hostRef, *output);
43+
assert(std::abs(ulpDiff) < 1 && "Division is not precise");
44+
}
45+
46+
void test_sqrt() {
47+
sycl::queue q(sycl::default_selector_v, sycl::property::queue::in_order());
48+
float *in_value = (float *)sycl::malloc_shared(sizeof(float), q);
49+
float *output = (float *)sycl::malloc_shared(sizeof(float), q);
50+
*in_value = value;
51+
q.submit([&](sycl::handler &h) {
52+
h.single_task([=] {
53+
float res = sycl::sqrt(*in_value);
54+
*output = res;
55+
});
56+
}).wait();
57+
58+
float hostRef = std::sqrt(value);
59+
int ulpDiff = ulp_difference<float>(hostRef, *output);
60+
assert(std::abs(ulpDiff) < 1 && "Sqrt is not precise");
61+
}
62+
63+
int main() {
64+
test_div();
65+
test_sqrt();
66+
return 0;
67+
}

0 commit comments

Comments
 (0)