60 #ifndef __SYCL_DEVICE_ONLY__
64 #include <type_traits>
70 inline namespace _V1 {
71 #ifndef __SYCL_DEVICE_ONLY__
74 inline double ceil(
double);
78 inline double rint(
double);
84 template <
typename T,
typename R>
86 std::bool_constant<is_sigeninteger_v<T> && is_sigeninteger_v<R>>;
88 template <
typename T,
typename R>
90 std::bool_constant<is_sugeninteger_v<T> && is_sugeninteger_v<R>>;
92 template <
typename T,
typename R>
94 (detail::is_sigeninteger_v<T> && detail::is_sugeninteger_v<R>) ||
95 (detail::is_sugeninteger_v<T> && detail::is_sigeninteger_v<R>)>;
97 template <
typename T,
typename R>
99 std::bool_constant<std::is_integral_v<T> && !std::is_unsigned_v<T> &&
102 template <
typename T,
typename R>
104 std::bool_constant<std::is_unsigned_v<T> &&
107 template <
typename T,
typename R>
111 template <
typename T,
typename R>
113 std::bool_constant<detail::is_floating_point<T>::value &&
114 std::is_unsigned_v<R>>;
116 template <
typename T,
typename R>
118 std::bool_constant<detail::is_floating_point<T>::value &&
119 std::is_integral_v<R> && !std::is_unsigned_v<R>>;
121 template <
typename T,
typename R>
123 std::bool_constant<detail::is_floating_point<T>::value &&
126 #ifndef __SYCL_DEVICE_ONLY__
127 template <
typename From,
typename To,
int VecSize,
128 typename Enable = std::enable_if_t<VecSize == 1>>
130 return static_cast<To
>(Value);
133 template <
typename From,
typename To,
int VecSize,
134 typename Enable = std::enable_if_t<VecSize == 1>>
136 return static_cast<To
>(Value);
139 template <
typename From,
typename To,
int VecSize,
140 typename Enable = std::enable_if_t<VecSize == 1>>
142 return static_cast<To
>(Value);
145 template <
typename From,
typename To,
int VecSize,
146 typename Enable = std::enable_if_t<VecSize == 1>>
148 return static_cast<To
>(Value);
151 template <
typename From,
typename To,
int VecSize,
152 typename Enable = std::enable_if_t<VecSize == 1>,
155 return static_cast<To
>(Value);
158 template <
typename From,
typename To,
int VecSize,
159 typename Enable = std::enable_if_t<VecSize == 1>,
162 switch (roundingMode) {
167 int OldRoundingDirection = std::fegetround();
168 int Err = std::fesetround(FE_TONEAREST);
171 "Unable to set rounding mode to FE_TONEAREST");
173 Err = std::fesetround(OldRoundingDirection);
176 "Unable to restore rounding mode.");
189 assert(
false &&
"Unsupported rounding mode!");
190 return static_cast<To
>(Value);
193 template <
typename From,
typename To,
int VecSize,
194 typename Enable = std::enable_if_t<VecSize == 1>,
197 return ConvertFToS<From, To, VecSize, Enable, roundingMode>(Value);
206 template <rounding_mode Mode>
using AnyRM = std::bool_constant<true>;
208 template <rounding_mode Mode>
212 template <rounding_mode Mode>
213 using Rtz = std::bool_constant<Mode == rounding_mode::rtz>;
215 template <rounding_mode Mode>
216 using Rtp = std::bool_constant<Mode == rounding_mode::rtp>;
218 template <rounding_mode Mode>
219 using Rtn = std::bool_constant<Mode == rounding_mode::rtn>;
221 template <
int VecSize>
using IsScalar = std::bool_constant<VecSize == 1>;
223 template <
int ExpectedVecSize,
int ActualVecSize>
224 using IsVectorOf = std::bool_constant<ActualVecSize == ExpectedVecSize>;
229 template <
typename ExpectedType,
typename ActualType>
230 using IsExpectedIntType =
231 std::bool_constant<std::is_same_v<ExpectedType, ActualType> ||
232 (std::is_same_v<ExpectedType, sycl::opencl::cl_char> &&
233 std::is_same_v<ActualType, signed char>)>;
236 template <
typename ExpectedType,
typename ActualType,
int VecSize,
238 template <sycl::rounding_mode>
typename RoundingModeCondition,
240 struct enable_if_to_int_scalar
241 : std::enable_if<IsExpectedIntType<ExpectedType, ActualType>::value &&
242 IsScalar<VecSize>::value &&
243 RoundingModeCondition<RoundingMode>::value,
246 template <
typename ExpectedType,
typename ActualType,
int VecSize,
248 template <sycl::rounding_mode>
typename RoundingModeCondition = AnyRM,
250 using enable_if_to_int_scalar_t =
251 typename enable_if_to_int_scalar<ExpectedType, ActualType, VecSize,
252 ReturnType, RoundingModeCondition,
255 template <
typename ExpectedType,
typename ActualType,
int ExpectedVecSize,
256 int ActualVecSize,
typename ReturnType,
257 template <sycl::rounding_mode>
typename RoundingModeCondition,
259 struct enable_if_to_int_vector
260 : std::enable_if<IsExpectedIntType<ExpectedType, ActualType>::value &&
261 IsVectorOf<ExpectedVecSize, ActualVecSize>::value &&
262 RoundingModeCondition<RoundingMode>::value,
265 template <
typename ExpectedType,
typename ActualType,
int ExpectedVecSize,
266 int ActualVecSize,
typename ReturnType,
267 template <sycl::rounding_mode>
typename RoundingModeCondition = AnyRM,
269 using enable_if_to_int_vector_t =
270 typename enable_if_to_int_vector<ExpectedType, ActualType, ExpectedVecSize,
271 ActualVecSize, ReturnType,
272 RoundingModeCondition, RoundingMode>::type;
275 #define __SYCL_SCALAR_INT_INT_CONVERT(Op, DestType) \
276 template <typename From, typename To, int VecSize, typename Enable> \
277 enable_if_to_int_scalar_t<sycl::opencl::cl_##DestType, Enable, VecSize, To> \
278 Op##Convert(From value) { \
279 return __spirv_##Op##Convert_R##DestType(value); \
282 #define __SYCL_VECTOR_INT_INT_CONVERT(Op, N, DestType) \
283 template <typename From, typename To, int VecSize, typename Enable> \
284 enable_if_to_int_vector_t<sycl::opencl::cl_##DestType, Enable, N, VecSize, \
286 Op##Convert(From value) { \
287 return __spirv_##Op##Convert_R##DestType##N(value); \
290 #define __SYCL_INT_INT_CONVERT(Op, DestType) \
291 __SYCL_SCALAR_INT_INT_CONVERT(Op, DestType) \
292 __SYCL_VECTOR_INT_INT_CONVERT(Op, 2, DestType) \
293 __SYCL_VECTOR_INT_INT_CONVERT(Op, 3, DestType) \
294 __SYCL_VECTOR_INT_INT_CONVERT(Op, 4, DestType) \
295 __SYCL_VECTOR_INT_INT_CONVERT(Op, 8, DestType) \
296 __SYCL_VECTOR_INT_INT_CONVERT(Op, 16, DestType)
298 __SYCL_INT_INT_CONVERT(S,
char)
299 __SYCL_INT_INT_CONVERT(S,
short)
300 __SYCL_INT_INT_CONVERT(S,
int)
301 __SYCL_INT_INT_CONVERT(S,
long)
303 __SYCL_INT_INT_CONVERT(U,
uchar)
304 __SYCL_INT_INT_CONVERT(U,
ushort)
305 __SYCL_INT_INT_CONVERT(U,
uint)
306 __SYCL_INT_INT_CONVERT(U, ulong)
308 #undef __SYCL_SCALAR_INT_INT_CONVERT
309 #undef __SYCL_VECTOR_INT_INT_CONVERT
310 #undef __SYCL_INT_INT_CONVERT
313 #define __SYCL_SCALAR_FLOAT_INT_CONVERT(Op, DestType, RoundingMode, \
314 RoundingModeCondition) \
315 template <typename From, typename To, int VecSize, typename Enable, \
316 sycl::rounding_mode RM> \
317 enable_if_to_int_scalar_t<sycl::opencl::cl_##DestType, Enable, VecSize, To, \
318 RoundingModeCondition, RM> \
319 Convert##Op(From Value) { \
320 return __spirv_Convert##Op##_R##DestType##_##RoundingMode(Value); \
323 #define __SYCL_VECTOR_FLOAT_INT_CONVERT(Op, N, DestType, RoundingMode, \
324 RoundingModeCondition) \
325 template <typename From, typename To, int VecSize, typename Enable, \
326 sycl::rounding_mode RM> \
327 enable_if_to_int_vector_t<sycl::opencl::cl_##DestType, Enable, N, VecSize, \
328 To, RoundingModeCondition, RM> \
329 Convert##Op(From Value) { \
330 return __spirv_Convert##Op##_R##DestType##N##_##RoundingMode(Value); \
333 #define __SYCL_FLOAT_INT_CONVERT(Op, DestType, RoundingMode, \
334 RoundingModeCondition) \
335 __SYCL_SCALAR_FLOAT_INT_CONVERT(Op, DestType, RoundingMode, \
336 RoundingModeCondition) \
337 __SYCL_VECTOR_FLOAT_INT_CONVERT(Op, 2, DestType, RoundingMode, \
338 RoundingModeCondition) \
339 __SYCL_VECTOR_FLOAT_INT_CONVERT(Op, 3, DestType, RoundingMode, \
340 RoundingModeCondition) \
341 __SYCL_VECTOR_FLOAT_INT_CONVERT(Op, 4, DestType, RoundingMode, \
342 RoundingModeCondition) \
343 __SYCL_VECTOR_FLOAT_INT_CONVERT(Op, 8, DestType, RoundingMode, \
344 RoundingModeCondition) \
345 __SYCL_VECTOR_FLOAT_INT_CONVERT(Op, 16, DestType, RoundingMode, \
346 RoundingModeCondition)
348 #define __SYCL_FLOAT_INT_CONVERT_FOR_TYPE(Op, DestType) \
349 __SYCL_FLOAT_INT_CONVERT(Op, DestType, rte, RteOrAutomatic) \
350 __SYCL_FLOAT_INT_CONVERT(Op, DestType, rtz, Rtz) \
351 __SYCL_FLOAT_INT_CONVERT(Op, DestType, rtp, Rtp) \
352 __SYCL_FLOAT_INT_CONVERT(Op, DestType, rtn, Rtn)
354 __SYCL_FLOAT_INT_CONVERT_FOR_TYPE(FToS,
char)
355 __SYCL_FLOAT_INT_CONVERT_FOR_TYPE(FToS,
short)
356 __SYCL_FLOAT_INT_CONVERT_FOR_TYPE(FToS,
int)
357 __SYCL_FLOAT_INT_CONVERT_FOR_TYPE(FToS,
long)
359 __SYCL_FLOAT_INT_CONVERT_FOR_TYPE(FToU,
uchar)
360 __SYCL_FLOAT_INT_CONVERT_FOR_TYPE(FToU,
ushort)
361 __SYCL_FLOAT_INT_CONVERT_FOR_TYPE(FToU,
uint)
362 __SYCL_FLOAT_INT_CONVERT_FOR_TYPE(FToU, ulong)
364 #undef __SYCL_SCALAR_FLOAT_INT_CONVERT
365 #undef __SYCL_VECTOR_FLOAT_INT_CONVERT
366 #undef __SYCL_FLOAT_INT_CONVERT
367 #undef __SYCL_FLOAT_INT_CONVERT_FOR_TYPE
370 template <
typename ExpectedType,
typename ActualType>
371 using IsExpectedFloatType =
372 std::bool_constant<std::is_same_v<ExpectedType, ActualType> ||
373 (std::is_same_v<ExpectedType, sycl::opencl::cl_half> &&
374 std::is_same_v<ActualType, _Float16>)>;
376 template <
typename ExpectedType,
typename ActualType,
int VecSize,
378 template <sycl::rounding_mode>
typename RoundingModeCondition,
380 struct enable_if_to_float_scalar
381 : std::enable_if<IsExpectedFloatType<ExpectedType, ActualType>::value &&
382 IsScalar<VecSize>::value &&
383 RoundingModeCondition<RoundingMode>::value,
386 template <
typename ExpectedType,
typename ActualType,
int VecSize,
388 template <sycl::rounding_mode>
typename RoundingModeCondition = AnyRM,
390 using enable_if_to_float_scalar_t =
391 typename enable_if_to_float_scalar<ExpectedType, ActualType, VecSize,
392 ReturnType, RoundingModeCondition,
395 template <
typename ExpectedType,
typename ActualType,
int ExpectedVecSize,
396 int ActualVecSize,
typename ReturnType,
397 template <sycl::rounding_mode>
typename RoundingModeCondition,
399 struct enable_if_to_float_vector
400 : std::enable_if<IsExpectedFloatType<ExpectedType, ActualType>::value &&
401 IsVectorOf<ExpectedVecSize, ActualVecSize>::value &&
402 RoundingModeCondition<RoundingMode>::value,
405 template <
typename ExpectedType,
typename ActualType,
int ExpectedVecSize,
406 int ActualVecSize,
typename ReturnType,
407 template <sycl::rounding_mode>
typename RoundingModeCondition = AnyRM,
409 using enable_if_to_float_vector_t =
typename enable_if_to_float_vector<
410 ExpectedType, ActualType, ExpectedVecSize, ActualVecSize, ReturnType,
411 RoundingModeCondition, RoundingMode>::type;
414 #define __SYCL_SCALAR_INT_FLOAT_CONVERT(Op, DestType) \
415 template <typename From, typename To, int VecSize, typename Enable> \
416 enable_if_to_float_scalar_t<sycl::opencl::cl_##DestType, Enable, VecSize, \
418 Convert##Op(From value) { \
419 return __spirv_Convert##Op##_R##DestType(value); \
422 #define __SYCL_VECTOR_INT_FLOAT_CONVERT(Op, N, DestType) \
423 template <typename From, typename To, int VecSize, typename Enable> \
424 enable_if_to_float_vector_t<sycl::opencl::cl_##DestType, Enable, N, VecSize, \
426 Convert##Op(From value) { \
427 return __spirv_Convert##Op##_R##DestType##N(value); \
430 #define __SYCL_INT_FLOAT_CONVERT(Op, DestType) \
431 __SYCL_SCALAR_INT_FLOAT_CONVERT(Op, DestType) \
432 __SYCL_VECTOR_INT_FLOAT_CONVERT(Op, 2, DestType) \
433 __SYCL_VECTOR_INT_FLOAT_CONVERT(Op, 3, DestType) \
434 __SYCL_VECTOR_INT_FLOAT_CONVERT(Op, 4, DestType) \
435 __SYCL_VECTOR_INT_FLOAT_CONVERT(Op, 8, DestType) \
436 __SYCL_VECTOR_INT_FLOAT_CONVERT(Op, 16, DestType)
438 __SYCL_INT_FLOAT_CONVERT(SToF,
half)
439 __SYCL_INT_FLOAT_CONVERT(SToF,
float)
440 __SYCL_INT_FLOAT_CONVERT(SToF,
double)
442 __SYCL_INT_FLOAT_CONVERT(UToF,
half)
443 __SYCL_INT_FLOAT_CONVERT(UToF,
float)
444 __SYCL_INT_FLOAT_CONVERT(UToF,
double)
446 #undef __SYCL_SCALAR_INT_FLOAT_CONVERT
447 #undef __SYCL_VECTOR_INT_FLOAT_CONVERT
448 #undef __SYCL_INT_FLOAT_CONVERT
451 #define __SYCL_SCALAR_FLOAT_FLOAT_CONVERT(DestType, RoundingMode, \
452 RoundingModeCondition) \
453 template <typename From, typename To, int VecSize, typename Enable, \
454 sycl::rounding_mode RM> \
455 enable_if_to_float_scalar_t<sycl::opencl::cl_##DestType, Enable, VecSize, \
456 To, RoundingModeCondition, RM> \
457 FConvert(From Value) { \
458 return __spirv_FConvert_R##DestType##_##RoundingMode(Value); \
461 #define __SYCL_VECTOR_FLOAT_FLOAT_CONVERT(N, DestType, RoundingMode, \
462 RoundingModeCondition) \
463 template <typename From, typename To, int VecSize, typename Enable, \
464 sycl::rounding_mode RM> \
465 enable_if_to_float_vector_t<sycl::opencl::cl_##DestType, Enable, N, VecSize, \
466 To, RoundingModeCondition, RM> \
467 FConvert(From Value) { \
468 return __spirv_FConvert_R##DestType##N##_##RoundingMode(Value); \
471 #define __SYCL_FLOAT_FLOAT_CONVERT(DestType, RoundingMode, \
472 RoundingModeCondition) \
473 __SYCL_SCALAR_FLOAT_FLOAT_CONVERT(DestType, RoundingMode, \
474 RoundingModeCondition) \
475 __SYCL_VECTOR_FLOAT_FLOAT_CONVERT(2, DestType, RoundingMode, \
476 RoundingModeCondition) \
477 __SYCL_VECTOR_FLOAT_FLOAT_CONVERT(3, DestType, RoundingMode, \
478 RoundingModeCondition) \
479 __SYCL_VECTOR_FLOAT_FLOAT_CONVERT(4, DestType, RoundingMode, \
480 RoundingModeCondition) \
481 __SYCL_VECTOR_FLOAT_FLOAT_CONVERT(8, DestType, RoundingMode, \
482 RoundingModeCondition) \
483 __SYCL_VECTOR_FLOAT_FLOAT_CONVERT(16, DestType, RoundingMode, \
484 RoundingModeCondition)
486 #define __SYCL_FLOAT_FLOAT_CONVERT_FOR_TYPE(DestType) \
487 __SYCL_FLOAT_FLOAT_CONVERT(DestType, rte, RteOrAutomatic) \
488 __SYCL_FLOAT_FLOAT_CONVERT(DestType, rtz, Rtz) \
489 __SYCL_FLOAT_FLOAT_CONVERT(DestType, rtp, Rtp) \
490 __SYCL_FLOAT_FLOAT_CONVERT(DestType, rtn, Rtn)
492 __SYCL_FLOAT_FLOAT_CONVERT_FOR_TYPE(
half)
493 __SYCL_FLOAT_FLOAT_CONVERT_FOR_TYPE(
float)
494 __SYCL_FLOAT_FLOAT_CONVERT_FOR_TYPE(
double)
496 #undef __SYCL_SCALAR_FLOAT_FLOAT_CONVERT
497 #undef __SYCL_VECTOR_FLOAT_FLOAT_CONVERT
498 #undef __SYCL_FLOAT_FLOAT_CONVERT
499 #undef __SYCL_FLOAT_FLOAT_CONVERT_FOR_TYPE
524 int VecSize,
typename NativeFromT,
typename NativeToT>
526 static_assert(!std::is_same_v<FromT, ToT>);
527 static_assert(!std::is_same_v<NativeFromT, NativeToT>);
530 return SConvert<NativeFromT, NativeToT, VecSize, ElemTy>(Value);
532 return UConvert<NativeFromT, NativeToT, VecSize, ElemTy>(Value);
534 return ConvertSToF<NativeFromT, NativeToT, VecSize, ElemTy>(Value);
536 return ConvertUToF<NativeFromT, NativeToT, VecSize, ElemTy>(Value);
538 return FConvert<NativeFromT, NativeToT, VecSize, ElemTy, RoundingMode>(
541 return ConvertFToS<NativeFromT, NativeToT, VecSize, ElemTy, RoundingMode>(
544 return ConvertFToU<NativeFromT, NativeToT, VecSize, ElemTy, RoundingMode>(
548 "Unexpected conversion type");
549 static_assert(VecSize == 1,
"Conversion between signed and unsigned data "
550 "types is only available for scalars");
557 return static_cast<NativeToT
>(Value);
To ConvertUToF(From Value)
std::bool_constant<(detail::is_sigeninteger_v< T > &&detail::is_sugeninteger_v< R >)||(detail::is_sugeninteger_v< T > &&detail::is_sigeninteger_v< R >)> is_sint_to_from_uint
std::bool_constant< is_sigeninteger_v< T > &&is_sigeninteger_v< R > > is_sint_to_sint
std::bool_constant< detail::is_floating_point< T >::value &&std::is_integral_v< R > &&!std::is_unsigned_v< R > > is_float_to_sint
std::bool_constant< std::is_integral_v< T > &&!std::is_unsigned_v< T > &&detail::is_floating_point< R >::value > is_sint_to_float
NativeToT convertImpl(NativeFromT Value)
Entry point helper for all kinds of converts between scalars and vectors, it dispatches to a right fu...
std::bool_constant< std::is_unsigned_v< T > &&detail::is_floating_point< R >::value > is_uint_to_float
std::bool_constant< is_sugeninteger_v< T > &&is_sugeninteger_v< R > > is_uint_to_uint
To ConvertSToF(From Value)
To ConvertFToU(From Value)
std::bool_constant< detail::is_floating_point< T >::value &&std::is_unsigned_v< R > > is_float_to_uint
To ConvertFToS(From Value)
decltype(convertToOpenCLType(std::declval< T >())) ConvertToOpenCLType_t
std::bool_constant< std::is_integral_v< T > &&detail::is_floating_point< R >::value > is_int_to_float
std::bool_constant< detail::is_floating_point< T >::value &&detail::is_floating_point< R >::value > is_float_to_float
std::error_code make_error_code(sycl::errc E) noexcept
Constructs an error code using e and sycl_category()
sycl::detail::half_impl::half half