Implementation of vec::convert
.
More...
#include <sycl/detail/generic_type_traits.hpp>
#include <sycl/exception.hpp>
#include <cfenv>
#include <type_traits>
Go to the source code of this file.
Namespaces | |
sycl | |
sycl::_V1 | |
sycl::_V1::detail | |
Typedefs | |
template<typename T , typename R > | |
using | sycl::_V1::detail::is_sint_to_sint = std::bool_constant< is_sigeninteger_v< T > &&is_sigeninteger_v< R > > |
template<typename T , typename R > | |
using | sycl::_V1::detail::is_uint_to_uint = std::bool_constant< is_sugeninteger_v< T > &&is_sugeninteger_v< R > > |
template<typename T , typename R > | |
using | sycl::_V1::detail::is_sint_to_from_uint = std::bool_constant<(detail::is_sigeninteger_v< T > &&detail::is_sugeninteger_v< R >)||(detail::is_sugeninteger_v< T > &&detail::is_sigeninteger_v< R >)> |
template<typename T , typename R > | |
using | sycl::_V1::detail::is_sint_to_float = std::bool_constant< std::is_integral_v< T > &&!std::is_unsigned_v< T > &&detail::is_floating_point< R >::value > |
template<typename T , typename R > | |
using | sycl::_V1::detail::is_uint_to_float = std::bool_constant< std::is_unsigned_v< T > &&detail::is_floating_point< R >::value > |
template<typename T , typename R > | |
using | sycl::_V1::detail::is_int_to_float = std::bool_constant< std::is_integral_v< T > &&detail::is_floating_point< R >::value > |
template<typename T , typename R > | |
using | sycl::_V1::detail::is_float_to_uint = std::bool_constant< detail::is_floating_point< T >::value &&std::is_unsigned_v< R > > |
template<typename T , typename R > | |
using | sycl::_V1::detail::is_float_to_sint = std::bool_constant< detail::is_floating_point< T >::value &&std::is_integral_v< R > &&!std::is_unsigned_v< R > > |
template<typename T , typename R > | |
using | sycl::_V1::detail::is_float_to_float = std::bool_constant< detail::is_floating_point< T >::value &&detail::is_floating_point< R >::value > |
Enumerations | |
enum class | sycl::rounding_mode { sycl::automatic = 0 , sycl::rte = 1 , sycl::rtz = 2 , sycl::rtp = 3 , sycl::rtn = 4 } |
Functions | |
float | sycl::_V1::ceil (float) |
double | sycl::_V1::ceil (double) |
float | sycl::_V1::floor (float) |
double | sycl::_V1::floor (double) |
float | sycl::_V1::rint (float) |
double | sycl::_V1::rint (double) |
float | sycl::_V1::trunc (float) |
double | sycl::_V1::trunc (double) |
template<typename From , typename To , int VecSize, typename Enable = std::enable_if_t<VecSize == 1>> | |
To | sycl::_V1::detail::SConvert (From Value) |
template<typename From , typename To , int VecSize, typename Enable = std::enable_if_t<VecSize == 1>> | |
To | sycl::_V1::detail::UConvert (From Value) |
template<typename From , typename To , int VecSize, typename Enable = std::enable_if_t<VecSize == 1>> | |
To | sycl::_V1::detail::ConvertSToF (From Value) |
template<typename From , typename To , int VecSize, typename Enable = std::enable_if_t<VecSize == 1>> | |
To | sycl::_V1::detail::ConvertUToF (From Value) |
template<typename From , typename To , int VecSize, typename Enable = std::enable_if_t<VecSize == 1>, sycl::rounding_mode RM> | |
To | sycl::_V1::detail::FConvert (From Value) |
template<typename From , typename To , int VecSize, typename Enable = std::enable_if_t<VecSize == 1>, sycl::rounding_mode roundingMode> | |
To | sycl::_V1::detail::ConvertFToS (From Value) |
template<typename From , typename To , int VecSize, typename Enable = std::enable_if_t<VecSize == 1>, sycl::rounding_mode roundingMode> | |
To | sycl::_V1::detail::ConvertFToU (From Value) |
template<typename FromT , typename ToT , sycl::rounding_mode RoundingMode, int VecSize, typename NativeFromT , typename NativeToT > | |
NativeToT | sycl::_V1::detail::convertImpl (NativeFromT Value) |
Entry point helper for all kinds of converts between scalars and vectors, it dispatches to a right function depending on source and destination types. More... | |
Implementation of vec::convert
.
Implementation consists of a bunch of helper functions to do different conversions, as well as a single entry point function, which performs a dispatch into the right helper.
Helpers are made to match corresponding SPIR-V instructions defined in section 3.42.11. Conversion Instructions (SPIR-V specification version 1.6, revision 2, unified):
OpConvertFToU
- float to unsigned integerOpConvertFToS
- float to signed integerOpConvertSToF
- signed integer to floatOpConvertUToF
- unsigned integer to floatOpUConvert
- unsigned integer to unsigned integerOpSConvert
- signed integer to signed integerOpConvertF
- float to floatOpSatConvertSToU
- signed integer to unsigned integerOpSatConvertUToS
- unsigned integer to signed integerTo get the right SPIR-V instruction emitted from SYCL code, we need to make a call to a specific built-in in the following format: __spirv_
[Op]_R[DestType][N?][_RoundingMode?] where:
[Op] is the name of instruction from the list above, without "Op" prefix.
[DestType] is the name of scalar return type
[N?] is vector size; omitted for scalars
[RoundingMode?] is rounding mode suffix, can be omittedImplementation below is essentially split into two parts: for host and for device.
Host part is really simple, as we only have scalar conversions available in there. Most of them are implemented as regular static_cast
with exception for float to integer conversions, which require rounding mode handling.
Device part is more complicated, because we need to generate calls to those __spirv*
built-ins. To do so, macro code generation is used: we emit number of function templates, which are conditionally enabled using SFINAE for each destination type and vector size to each call their own __spriv*
built-in.
Finally, there is single entry point which performs a dispatch to the right helper depending on source and destination types.
Definition in file vector_convert.hpp.