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 
13 #include <cstdint>
14 
15 // _iml_half_internal is internal representation for fp16 type used in intel
16 // math device library. The definition here should align with definition in
17 // https://github.com/intel/llvm/blob/sycl/libdevice/imf_half.hpp
18 #if defined(__SPIR__) || defined(__SPIRV__)
19 using _iml_half_internal = _Float16;
20 #else
21 using _iml_half_internal = uint16_t;
22 #endif
23 
24 #include <sycl/bit_cast.hpp>
25 #include <sycl/builtins.hpp>
32 #include <sycl/half_type.hpp>
33 #include <type_traits>
34 
35 extern "C" {
36 float __imf_saturatef(float);
37 float __imf_copysignf(float, float);
38 double __imf_copysign(double, double);
40 float __imf_ceilf(float);
41 double __imf_ceil(double);
43 float __imf_floorf(float);
44 double __imf_floor(double);
46 float __imf_rintf(float);
47 double __imf_rint(double);
49 float __imf_invf(float);
50 double __imf_inv(double);
52 float __imf_sqrtf(float);
53 double __imf_sqrt(double);
55 float __imf_rsqrtf(float);
56 double __imf_rsqrt(double);
58 float __imf_truncf(float);
59 double __imf_trunc(double);
61 double __imf_rcp64h(double);
62 };
63 
64 namespace sycl {
65 inline namespace _V1 {
66 namespace ext::intel::math {
67 
68 static_assert(sizeof(sycl::half) == sizeof(_iml_half_internal),
69  "sycl::half is not compatible with _iml_half_internal.");
70 
71 template <typename Tp>
72 std::enable_if_t<std::is_same_v<Tp, float>, float> saturate(Tp x) {
73  return __imf_saturatef(x);
74 }
75 
76 template <typename Tp>
77 std::enable_if_t<std::is_same_v<Tp, float>, float> copysign(Tp x, Tp y) {
78  return __imf_copysignf(x, y);
79 }
80 
81 template <typename Tp>
82 std::enable_if_t<std::is_same_v<Tp, double>, double> copysign(Tp x, Tp y) {
83  return __imf_copysign(x, y);
84 }
85 
86 template <typename Tp>
87 std::enable_if_t<std::is_same_v<Tp, sycl::half>, sycl::half> copysign(Tp x,
88  Tp y) {
89  _iml_half_internal xi = sycl::bit_cast<_iml_half_internal>(x);
90  _iml_half_internal yi = sycl::bit_cast<_iml_half_internal>(y);
91  return sycl::bit_cast<sycl::half>(__imf_copysignf16(xi, yi));
92 }
93 
94 template <typename Tp>
95 std::enable_if_t<std::is_same_v<Tp, float>, float> ceil(Tp x) {
96  return __imf_ceilf(x);
97 }
98 
99 template <typename Tp>
100 std::enable_if_t<std::is_same_v<Tp, double>, double> ceil(Tp x) {
101  return __imf_ceil(x);
102 }
103 
104 template <typename Tp>
105 std::enable_if_t<std::is_same_v<Tp, sycl::half>, sycl::half> ceil(Tp x) {
106  _iml_half_internal xi = sycl::bit_cast<_iml_half_internal>(x);
107  return sycl::bit_cast<sycl::half>(__imf_ceilf16(xi));
108 }
109 
110 template <typename Tp>
111 std::enable_if_t<std::is_same_v<Tp, sycl::half2>, sycl::half2> ceil(Tp x) {
112  return sycl::half2{ceil(x.s0()), ceil(x.s1())};
113 }
114 
115 template <typename Tp>
116 std::enable_if_t<std::is_same_v<Tp, float>, float> floor(Tp x) {
117  return __imf_floorf(x);
118 }
119 
120 template <typename Tp>
121 std::enable_if_t<std::is_same_v<Tp, double>, double> floor(Tp x) {
122  return __imf_floor(x);
123 }
124 
125 template <typename Tp>
126 std::enable_if_t<std::is_same_v<Tp, sycl::half>, sycl::half> floor(Tp x) {
127  _iml_half_internal xi = sycl::bit_cast<_iml_half_internal>(x);
128  return sycl::bit_cast<sycl::half>(__imf_floorf16(xi));
129 }
130 
131 template <typename Tp>
132 std::enable_if_t<std::is_same_v<Tp, sycl::half2>, sycl::half2> floor(Tp x) {
133  return sycl::half2{floor(x.s0()), floor(x.s1())};
134 }
135 
136 template <typename Tp>
137 std::enable_if_t<std::is_same_v<Tp, float>, float> inv(Tp x) {
138  return __imf_invf(x);
139 }
140 
141 template <typename Tp>
142 std::enable_if_t<std::is_same_v<Tp, double>, double> inv(Tp x) {
143  return __imf_inv(x);
144 }
145 
146 template <typename Tp>
147 std::enable_if_t<std::is_same_v<Tp, sycl::half>, sycl::half> inv(Tp x) {
148  _iml_half_internal xi = sycl::bit_cast<_iml_half_internal>(x);
149  return sycl::bit_cast<sycl::half>(__imf_invf16(xi));
150 }
151 
152 template <typename Tp>
153 std::enable_if_t<std::is_same_v<Tp, sycl::half2>, sycl::half2> inv(Tp x) {
154  return sycl::half2{inv(x.s0()), inv(x.s1())};
155 }
156 
157 template <typename Tp>
158 std::enable_if_t<std::is_same_v<Tp, float>, float> rint(Tp x) {
159  return __imf_rintf(x);
160 }
161 
162 template <typename Tp>
163 std::enable_if_t<std::is_same_v<Tp, double>, double> rint(Tp x) {
164  return __imf_rint(x);
165 }
166 
167 template <typename Tp>
168 std::enable_if_t<std::is_same_v<Tp, sycl::half>, sycl::half> rint(Tp x) {
169  _iml_half_internal xi = sycl::bit_cast<_iml_half_internal>(x);
170  return sycl::bit_cast<sycl::half>(__imf_rintf16(xi));
171 }
172 
173 template <typename Tp>
174 std::enable_if_t<std::is_same_v<Tp, sycl::half2>, sycl::half2> rint(Tp x) {
175  return sycl::half2{rint(x.s0()), rint(x.s1())};
176 }
177 
178 template <typename Tp>
179 std::enable_if_t<std::is_same_v<Tp, float>, float> sqrt(Tp x) {
180  return __imf_sqrtf(x);
181 }
182 
183 template <typename Tp>
184 std::enable_if_t<std::is_same_v<Tp, double>, double> sqrt(Tp x) {
185  return __imf_sqrt(x);
186 }
187 
188 template <typename Tp>
189 std::enable_if_t<std::is_same_v<Tp, sycl::half>, sycl::half> sqrt(Tp x) {
190  _iml_half_internal xi = sycl::bit_cast<_iml_half_internal>(x);
191  return sycl::bit_cast<sycl::half>(__imf_sqrtf16(xi));
192 }
193 
194 template <typename Tp>
195 std::enable_if_t<std::is_same_v<Tp, sycl::half2>, sycl::half2> sqrt(Tp x) {
196  return sycl::half2{sqrt(x.s0()), sqrt(x.s1())};
197 }
198 
199 template <typename Tp>
200 std::enable_if_t<std::is_same_v<Tp, float>, float> rsqrt(Tp x) {
201  return __imf_rsqrtf(x);
202 }
203 
204 template <typename Tp>
205 std::enable_if_t<std::is_same_v<Tp, double>, double> rsqrt(Tp x) {
206  return __imf_rsqrt(x);
207 }
208 
209 template <typename Tp>
210 std::enable_if_t<std::is_same_v<Tp, sycl::half>, sycl::half> rsqrt(Tp x) {
211  _iml_half_internal xi = sycl::bit_cast<_iml_half_internal>(x);
212  return sycl::bit_cast<sycl::half>(__imf_rsqrtf16(xi));
213 }
214 
215 template <typename Tp>
216 std::enable_if_t<std::is_same_v<Tp, sycl::half2>, sycl::half2> rsqrt(Tp x) {
217  return sycl::half2{rsqrt(x.s0()), rsqrt(x.s1())};
218 }
219 
220 template <typename Tp>
221 std::enable_if_t<std::is_same_v<Tp, float>, float> trunc(Tp x) {
222  return __imf_truncf(x);
223 }
224 
225 template <typename Tp>
226 std::enable_if_t<std::is_same_v<Tp, double>, double> trunc(Tp x) {
227  return __imf_trunc(x);
228 }
229 
230 template <typename Tp>
231 std::enable_if_t<std::is_same_v<Tp, sycl::half>, sycl::half> trunc(Tp x) {
232  _iml_half_internal xi = sycl::bit_cast<_iml_half_internal>(x);
233  return sycl::bit_cast<sycl::half>(__imf_truncf16(xi));
234 }
235 
236 template <typename Tp>
237 std::enable_if_t<std::is_same_v<Tp, sycl::half2>, sycl::half2> trunc(Tp x) {
238  return sycl::half2{trunc(x.s0()), trunc(x.s1())};
239 }
240 
241 template <typename Tp>
242 std::enable_if_t<std::is_same_v<Tp, double>, double> rcp64h(Tp x) {
243  return __imf_rcp64h(x);
244 }
245 
246 } // namespace ext::intel::math
247 } // namespace _V1
248 } // namespace sycl
uint16_t _iml_half_internal
Definition: math.hpp:21
float __imf_truncf(float)
float __imf_saturatef(float)
float __imf_rsqrtf(float)
double __imf_rint(double)
double __imf_ceil(double)
_iml_half_internal __imf_invf16(_iml_half_internal)
double __imf_sqrt(double)
float __imf_sqrtf(float)
double __imf_trunc(double)
_iml_half_internal __imf_rintf16(_iml_half_internal)
float __imf_ceilf(float)
double __imf_rsqrt(double)
float __imf_copysignf(float, float)
_iml_half_internal __imf_floorf16(_iml_half_internal)
double __imf_floor(double)
_iml_half_internal __imf_sqrtf16(_iml_half_internal)
double __imf_inv(double)
float __imf_invf(float)
_iml_half_internal __imf_truncf16(_iml_half_internal)
double __imf_rcp64h(double)
float __imf_floorf(float)
double __imf_copysign(double, double)
float __imf_rintf(float)
_iml_half_internal __imf_copysignf16(_iml_half_internal, _iml_half_internal)
_iml_half_internal __imf_rsqrtf16(_iml_half_internal)
_iml_half_internal __imf_ceilf16(_iml_half_internal)
std::enable_if_t< std::is_same_v< Tp, float >, float > sqrt(Tp x)
Definition: math.hpp:179
std::enable_if_t< std::is_same_v< Tp, float >, float > ceil(Tp x)
Definition: math.hpp:95
std::enable_if_t< std::is_same_v< Tp, float >, float > trunc(Tp x)
Definition: math.hpp:221
std::enable_if_t< std::is_same_v< Tp, float >, float > copysign(Tp x, Tp y)
Definition: math.hpp:77
std::enable_if_t< std::is_same_v< Tp, float >, float > rint(Tp x)
Definition: math.hpp:158
std::enable_if_t< std::is_same_v< Tp, float >, float > floor(Tp x)
Definition: math.hpp:116
std::enable_if_t< std::is_same_v< Tp, float >, float > saturate(Tp x)
Definition: math.hpp:72
std::enable_if_t< std::is_same_v< Tp, float >, float > inv(Tp x)
Definition: math.hpp:137
std::enable_if_t< std::is_same_v< Tp, double >, double > rcp64h(Tp x)
Definition: math.hpp:242
std::enable_if_t< std::is_same_v< Tp, float >, float > rsqrt(Tp x)
Definition: math.hpp:200
autodecltype(x) x
Definition: access.hpp:18