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