DPC++ Runtime
Runtime libraries for oneAPI DPC++
math.hpp
Go to the documentation of this file.
1 //==------------- math.hpp - Intel specific math API -----------------------==//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 // The main header of Intel specific math API
9 //===----------------------------------------------------------------------===//
10 
11 #pragma once
12 #include <sycl/builtins.hpp>
15 #include <sycl/half_type.hpp>
16 #include <type_traits>
17 
18 // _iml_half_internal is internal representation for fp16 type used in intel
19 // math device library. The definition here should align with definition in
20 // https://github.com/intel/llvm/blob/sycl/libdevice/imf_half.hpp
21 #if defined(__SPIR__)
22 using _iml_half_internal = _Float16;
23 #else
24 using _iml_half_internal = uint16_t;
25 #endif
26 
27 extern "C" {
28 float __imf_saturatef(float);
29 float __imf_copysignf(float, float);
30 double __imf_copysign(double, double);
32 float __imf_ceilf(float);
33 double __imf_ceil(double);
35 float __imf_floorf(float);
36 double __imf_floor(double);
38 float __imf_rintf(float);
39 double __imf_rint(double);
41 float __imf_invf(float);
42 double __imf_inv(double);
44 float __imf_sqrtf(float);
45 double __imf_sqrt(double);
47 float __imf_rsqrtf(float);
48 double __imf_rsqrt(double);
50 float __imf_truncf(float);
51 double __imf_trunc(double);
53 };
54 
55 namespace sycl {
57 namespace ext::intel::math {
58 
59 static_assert(sizeof(sycl::half) == sizeof(_iml_half_internal),
60  "sycl::half is not compatible with _iml_half_internal.");
61 
62 template <typename Tp>
63 std::enable_if_t<std::is_same_v<Tp, float>, float> saturate(Tp x) {
64  return __imf_saturatef(x);
65 }
66 
67 template <typename Tp>
68 std::enable_if_t<std::is_same_v<Tp, float>, float> copysign(Tp x, Tp y) {
69  return __imf_copysignf(x, y);
70 }
71 
72 template <typename Tp>
73 std::enable_if_t<std::is_same_v<Tp, double>, double> copysign(Tp x, Tp y) {
74  return __imf_copysign(x, y);
75 }
76 
77 template <typename Tp>
78 std::enable_if_t<std::is_same_v<Tp, sycl::half>, sycl::half> copysign(Tp x,
79  Tp y) {
80  _iml_half_internal xi = __builtin_bit_cast(_iml_half_internal, x);
81  _iml_half_internal yi = __builtin_bit_cast(_iml_half_internal, y);
82  return __builtin_bit_cast(sycl::half, __imf_copysignf16(xi, yi));
83 }
84 
85 template <typename Tp>
86 std::enable_if_t<std::is_same_v<Tp, float>, float> ceil(Tp x) {
87  return __imf_ceilf(x);
88 }
89 
90 template <typename Tp>
91 std::enable_if_t<std::is_same_v<Tp, double>, double> ceil(Tp x) {
92  return __imf_ceil(x);
93 }
94 
95 template <typename Tp>
96 std::enable_if_t<std::is_same_v<Tp, sycl::half>, sycl::half> ceil(Tp x) {
97  _iml_half_internal xi = __builtin_bit_cast(_iml_half_internal, x);
98  return __builtin_bit_cast(sycl::half, __imf_ceilf16(xi));
99 }
100 
101 template <typename Tp>
102 std::enable_if_t<std::is_same_v<Tp, sycl::half2>, sycl::half2> ceil(Tp x) {
103  return sycl::half2{ceil(x.s0()), ceil(x.s1())};
104 }
105 
106 template <typename Tp>
107 std::enable_if_t<std::is_same_v<Tp, float>, float> floor(Tp x) {
108  return __imf_floorf(x);
109 }
110 
111 template <typename Tp>
112 std::enable_if_t<std::is_same_v<Tp, double>, double> floor(Tp x) {
113  return __imf_floor(x);
114 }
115 
116 template <typename Tp>
117 std::enable_if_t<std::is_same_v<Tp, sycl::half>, sycl::half> floor(Tp x) {
118  _iml_half_internal xi = __builtin_bit_cast(_iml_half_internal, x);
119  return __builtin_bit_cast(sycl::half, __imf_floorf16(xi));
120 }
121 
122 template <typename Tp>
123 std::enable_if_t<std::is_same_v<Tp, sycl::half2>, sycl::half2> floor(Tp x) {
124  return sycl::half2{floor(x.s0()), floor(x.s1())};
125 }
126 
127 template <typename Tp>
128 std::enable_if_t<std::is_same_v<Tp, float>, float> inv(Tp x) {
129  return __imf_invf(x);
130 }
131 
132 template <typename Tp>
133 std::enable_if_t<std::is_same_v<Tp, double>, double> inv(Tp x) {
134  return __imf_inv(x);
135 }
136 
137 template <typename Tp>
138 std::enable_if_t<std::is_same_v<Tp, sycl::half>, sycl::half> inv(Tp x) {
139  _iml_half_internal xi = __builtin_bit_cast(_iml_half_internal, x);
140  return __builtin_bit_cast(sycl::half, __imf_invf16(xi));
141 }
142 
143 template <typename Tp>
144 std::enable_if_t<std::is_same_v<Tp, sycl::half2>, sycl::half2> inv(Tp x) {
145  return sycl::half2{inv(x.s0()), inv(x.s1())};
146 }
147 
148 template <typename Tp>
149 std::enable_if_t<std::is_same_v<Tp, float>, float> rint(Tp x) {
150  return __imf_rintf(x);
151 }
152 
153 template <typename Tp>
154 std::enable_if_t<std::is_same_v<Tp, double>, double> rint(Tp x) {
155  return __imf_rint(x);
156 }
157 
158 template <typename Tp>
159 std::enable_if_t<std::is_same_v<Tp, sycl::half>, sycl::half> rint(Tp x) {
160  _iml_half_internal xi = __builtin_bit_cast(_iml_half_internal, x);
161  return __builtin_bit_cast(sycl::half, __imf_rintf16(xi));
162 }
163 
164 template <typename Tp>
165 std::enable_if_t<std::is_same_v<Tp, sycl::half2>, sycl::half2> rint(Tp x) {
166  return sycl::half2{rint(x.s0()), rint(x.s1())};
167 }
168 
169 template <typename Tp>
170 std::enable_if_t<std::is_same_v<Tp, float>, float> sqrt(Tp x) {
171  return __imf_sqrtf(x);
172 }
173 
174 template <typename Tp>
175 std::enable_if_t<std::is_same_v<Tp, double>, double> sqrt(Tp x) {
176  return __imf_sqrt(x);
177 }
178 
179 template <typename Tp>
180 std::enable_if_t<std::is_same_v<Tp, sycl::half>, sycl::half> sqrt(Tp x) {
181  _iml_half_internal xi = __builtin_bit_cast(_iml_half_internal, x);
182  return __builtin_bit_cast(sycl::half, __imf_sqrtf16(xi));
183 }
184 
185 template <typename Tp>
186 std::enable_if_t<std::is_same_v<Tp, sycl::half2>, sycl::half2> sqrt(Tp x) {
187  return sycl::half2{sqrt(x.s0()), sqrt(x.s1())};
188 }
189 
190 template <typename Tp>
191 std::enable_if_t<std::is_same_v<Tp, float>, float> rsqrt(Tp x) {
192  return __imf_rsqrtf(x);
193 }
194 
195 template <typename Tp>
196 std::enable_if_t<std::is_same_v<Tp, double>, double> rsqrt(Tp x) {
197  return __imf_rsqrt(x);
198 }
199 
200 template <typename Tp>
201 std::enable_if_t<std::is_same_v<Tp, sycl::half>, sycl::half> rsqrt(Tp x) {
202  _iml_half_internal xi = __builtin_bit_cast(_iml_half_internal, x);
203  return __builtin_bit_cast(sycl::half, __imf_rsqrtf16(xi));
204 }
205 
206 template <typename Tp>
207 std::enable_if_t<std::is_same_v<Tp, sycl::half2>, sycl::half2> rsqrt(Tp x) {
208  return sycl::half2{rsqrt(x.s0()), rsqrt(x.s1())};
209 }
210 
211 template <typename Tp>
212 std::enable_if_t<std::is_same_v<Tp, float>, float> trunc(Tp x) {
213  return __imf_truncf(x);
214 }
215 
216 template <typename Tp>
217 std::enable_if_t<std::is_same_v<Tp, double>, double> trunc(Tp x) {
218  return __imf_trunc(x);
219 }
220 
221 template <typename Tp>
222 std::enable_if_t<std::is_same_v<Tp, sycl::half>, sycl::half> trunc(Tp x) {
223  _iml_half_internal xi = __builtin_bit_cast(_iml_half_internal, x);
224  return __builtin_bit_cast(sycl::half, __imf_truncf16(xi));
225 }
226 
227 template <typename Tp>
228 std::enable_if_t<std::is_same_v<Tp, sycl::half2>, sycl::half2> trunc(Tp x) {
229  return sycl::half2{trunc(x.s0()), trunc(x.s1())};
230 }
231 
232 } // namespace ext::intel::math
233 } // __SYCL_INLINE_VER_NAMESPACE(_V1)
234 } // namespace sycl
__imf_rintf16
_iml_half_internal __imf_rintf16(_iml_half_internal)
builtins.hpp
__imf_copysign
double __imf_copysign(double, double)
sycl::_V1::ext::intel::math::rint
std::enable_if_t< std::is_same_v< Tp, sycl::half2 >, sycl::half2 > rint(Tp x)
Definition: math.hpp:165
_iml_half_internal
uint16_t _iml_half_internal
Definition: math.hpp:24
__imf_truncf
float __imf_truncf(float)
__SYCL_INLINE_VER_NAMESPACE
#define __SYCL_INLINE_VER_NAMESPACE(X)
Definition: defines_elementary.hpp:11
sycl::_V1::ext::intel::math::ceil
std::enable_if_t< std::is_same_v< Tp, sycl::half2 >, sycl::half2 > ceil(Tp x)
Definition: math.hpp:102
__imf_floorf16
_iml_half_internal __imf_floorf16(_iml_half_internal)
__imf_sqrt
double __imf_sqrt(double)
sycl::_V1::ext::intel::math::copysign
std::enable_if_t< std::is_same_v< Tp, sycl::half >, sycl::half > copysign(Tp x, Tp y)
Definition: math.hpp:78
sycl::_V1::ext::intel::math::inv
std::enable_if_t< std::is_same_v< Tp, sycl::half2 >, sycl::half2 > inv(Tp x)
Definition: math.hpp:144
sycl
---— Error handling, matching OpenCL plugin semantics.
Definition: access.hpp:14
__imf_sqrtf16
_iml_half_internal __imf_sqrtf16(_iml_half_internal)
__imf_ceilf16
_iml_half_internal __imf_ceilf16(_iml_half_internal)
__imf_floor
double __imf_floor(double)
__imf_invf16
_iml_half_internal __imf_invf16(_iml_half_internal)
__imf_truncf16
_iml_half_internal __imf_truncf16(_iml_half_internal)
__imf_saturatef
float __imf_saturatef(float)
imf_half_trivial.hpp
__imf_rsqrt
double __imf_rsqrt(double)
__imf_ceilf
float __imf_ceilf(float)
sycl::_V1::ext::intel::math::trunc
std::enable_if_t< std::is_same_v< Tp, sycl::half2 >, sycl::half2 > trunc(Tp x)
Definition: math.hpp:228
sycl::_V1::half
sycl::detail::half_impl::half half
Definition: aliases.hpp:103
__imf_floorf
float __imf_floorf(float)
__imf_trunc
double __imf_trunc(double)
imf_simd.hpp
__imf_rsqrtf
float __imf_rsqrtf(float)
__imf_rintf
float __imf_rintf(float)
__imf_copysignf
float __imf_copysignf(float, float)
sycl::_V1::ext::intel::math::sqrt
std::enable_if_t< std::is_same_v< Tp, sycl::half2 >, sycl::half2 > sqrt(Tp x)
Definition: math.hpp:186
__imf_invf
float __imf_invf(float)
__imf_inv
double __imf_inv(double)
half_type.hpp
__imf_rsqrtf16
_iml_half_internal __imf_rsqrtf16(_iml_half_internal)
__imf_rint
double __imf_rint(double)
sycl::_V1::ext::intel::math::rsqrt
std::enable_if_t< std::is_same_v< Tp, sycl::half2 >, sycl::half2 > rsqrt(Tp x)
Definition: math.hpp:207
__imf_sqrtf
float __imf_sqrtf(float)
__imf_copysignf16
_iml_half_internal __imf_copysignf16(_iml_half_internal, _iml_half_internal)
sycl::_V1::ext::intel::math::saturate
std::enable_if_t< std::is_same_v< Tp, float >, float > saturate(Tp x)
Definition: math.hpp:63
__imf_ceil
double __imf_ceil(double)
sycl::_V1::ext::intel::math::floor
std::enable_if_t< std::is_same_v< Tp, sycl::half2 >, sycl::half2 > floor(Tp x)
Definition: math.hpp:123