Skip to content

[SYCL][ESIMD] Move rounding functions out of experimental namespace #5785

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Mar 11, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
86 changes: 86 additions & 0 deletions sycl/include/sycl/ext/intel/esimd/detail/math_intrin.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,19 @@ __ESIMD_INTRIN __ESIMD_raw_vec_t(T, SZ)
__esimd_ieee_div(__ESIMD_raw_vec_t(T, SZ) src0,
__ESIMD_raw_vec_t(T, SZ) src1);

template <int SZ>
__ESIMD_INTRIN __ESIMD_DNS::vector_type_t<float, SZ>
__esimd_rndd(__ESIMD_DNS::vector_type_t<float, SZ> src0);
template <int SZ>
__ESIMD_INTRIN __ESIMD_DNS::vector_type_t<float, SZ>
__esimd_rndu(__ESIMD_DNS::vector_type_t<float, SZ> src0);
template <int SZ>
__ESIMD_INTRIN __ESIMD_DNS::vector_type_t<float, SZ>
__esimd_rnde(__ESIMD_DNS::vector_type_t<float, SZ> src0);
template <int SZ>
__ESIMD_INTRIN __ESIMD_DNS::vector_type_t<float, SZ>
__esimd_rndz(__ESIMD_DNS::vector_type_t<float, SZ> src0);

template <int N>
__ESIMD_INTRIN uint32_t
__esimd_pack_mask(__ESIMD_DNS::vector_type_t<uint16_t, N> src0);
Expand Down Expand Up @@ -605,6 +618,79 @@ __ESIMD_INTRIN __ESIMD_raw_vec_t(T, SZ)
return __ESIMD_DNS::convert_vector<T, CppT, SZ>(cpp_res);
}

template <int SZ>
__ESIMD_INTRIN __ESIMD_DNS::vector_type_t<float, SZ>
__esimd_rndd(__ESIMD_DNS::vector_type_t<float, SZ> src0) {
__ESIMD_DNS::vector_type_t<float, SZ> retv;

for (int i = 0; i < SZ; i++) {
SIMDCF_ELEMENT_SKIP(i);
retv[i] = floor(src0[i]);
}
return retv;
}

template <int SZ>
__ESIMD_INTRIN __ESIMD_DNS::vector_type_t<float, SZ>
__esimd_rndu(__ESIMD_DNS::vector_type_t<float, SZ> src0) {
__ESIMD_DNS::vector_type_t<float, SZ> retv;
int increment;

for (int i = 0; i < SZ; i++) {
SIMDCF_ELEMENT_SKIP(i);
if (src0[i] - floor(src0[i]) > 0.0f) {
increment = 1;
} else {
increment = 0;
}

retv[i] = floor(src0[i]) + increment;
}

return retv;
}

template <int SZ>
__ESIMD_INTRIN __ESIMD_DNS::vector_type_t<float, SZ>
__esimd_rnde(__ESIMD_DNS::vector_type_t<float, SZ> src0) {
__ESIMD_DNS::vector_type_t<float, SZ> retv;
int increment;

for (int i = 0; i < SZ; i++) {
SIMDCF_ELEMENT_SKIP(i);
if (src0[i] - floor(src0[i]) > 0.5f) {
increment = 1;
} else if (src0[i] - floor(src0[i]) < 0.5f) {
increment = 0;
} else {
increment = (int(floor(src0[i])) % 2 == 1);
}

retv[i] = floor(src0[i]) + increment;
}

return retv;
}

template <int SZ>
__ESIMD_INTRIN __ESIMD_DNS::vector_type_t<float, SZ>
__esimd_rndz(__ESIMD_DNS::vector_type_t<float, SZ> src0) {
__ESIMD_DNS::vector_type_t<float, SZ> retv;
int increment;

for (int i = 0; i < SZ; i++) {
SIMDCF_ELEMENT_SKIP(i);
if (fabs(src0[i]) < fabs(floor(src0[i]))) {
increment = 1;
} else {
increment = 0;
}
retv[i] = floor(src0[i]) + increment;
}

return retv;
}

template <int N>
__ESIMD_INTRIN uint32_t
__esimd_pack_mask(__ESIMD_DNS::vector_type_t<uint16_t, N> src0) {
Expand Down
130 changes: 130 additions & 0 deletions sycl/include/sycl/ext/intel/esimd/math.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -502,6 +502,136 @@ ESIMD_NODEBUG ESIMD_INLINE T exp(T src0, Sat sat = {}) {

/// @} sycl_esimd_math

/// @addtogroup sycl_esimd_conv
/// @{

////////////////////////////////////////////////////////////////////////////////
// Rounding intrinsics.
////////////////////////////////////////////////////////////////////////////////

#define __ESIMD_INTRINSIC_DEF(name) \
/** @tparam T Element type. */ \
/** @tparam SZ Number of elements in the input vector. */ \
/** @tparam Sat Saturation control. Default is \c \
* __ESIMD_NS::saturation_off_tag */ \
/** @param src0 The argument to perform rounding on. */ \
/** @param sat The type tag object to auto-deduce saturation control. */ \
/** can be \c saturation_off or \c saturation_on */ \
template <typename T, int SZ, class Sat = __ESIMD_NS::saturation_off_tag> \
__ESIMD_API __ESIMD_NS::simd<T, SZ> name(__ESIMD_NS::simd<float, SZ> src0, \
Sat sat = {}) { \
__ESIMD_NS::simd<float, SZ> Result = __esimd_##name<SZ>(src0.data()); \
if constexpr (std::is_same_v<Sat, __ESIMD_NS::saturation_off_tag>) \
return Result; \
else if constexpr (!std::is_same_v<float, T>) { \
auto RawRes = __ESIMD_NS::saturate<float>(Result).data(); \
return __ESIMD_DNS::convert_vector<T, float, SZ>(std::move(RawRes)); \
} else { \
return __ESIMD_NS::saturate<T>(Result); \
} \
} \
/** Scalar version. */ \
template <typename T, class Sat = __ESIMD_NS::saturation_off_tag> \
__ESIMD_API T name(float src0, Sat sat = {}) { \
__ESIMD_NS::simd<float, 1> Src0 = src0; \
__ESIMD_NS::simd<T, 1> Result = name<T>(Src0, sat); \
return Result[0]; \
}

/// Round-down (also known as \c floor). Supports only \c float.
/// Corner cases:
/// | _ | _ | _ | _ | _ | _ | _ | _
/// |----------|------|---------|----|----|---------|------|----
/// | **src0** | -inf | -denorm | -0 | +0 | +denorm | +inf | NaN
/// | **dst** | -inf | \* | -0 | +0 | +0 | +inf | NaN
/// - \* \c -1 or \c -0 depending on the Single Precision Denorm Mode.
__ESIMD_INTRINSIC_DEF(rndd)

/// Round-up (also known as \c ceil). Supports only \c float.
/// Corner cases:
/// | _ | _ | _ | _ | _ | _ | _ | _
/// |----------|------|---------|----|----|---------|------|----
/// | **src0** | -inf | -denorm | -0 | +0 | +denorm | +inf | NaN
/// | **dst** | -inf | -0 | -0 | +0 | \* | +inf | NaN
/// - \* \c +1 or \c +0 depending on the Single Precision Denorm Mode.
__ESIMD_INTRINSIC_DEF(rndu)

/// Round-to-even (also known as \c round). Supports only \c float.
/// Corner cases:
/// | _ | _ | _ | _ | _ | _ | _ | _
/// |----------|------|---------|----|----|---------|------|----
/// | **src0** | -inf | -denorm | -0 | +0 | +denorm | +inf | NaN
/// | **dst** | -inf | -0 | -0 | +0 | +0 | +inf | NaN
__ESIMD_INTRINSIC_DEF(rnde)

/// Round-to-zero (also known as \c trunc). Supports only \c float.
/// Corner cases:
/// | _ | _ | _ | _ | _ | _ | _ | _
/// |----------|------|---------|----|----|---------|------|----
/// | **src0** | -inf | -denorm | -0 | +0 | +denorm | +inf | NaN
/// | **dst** | -inf | -0 | -0 | +0 | +0 | +inf | NaN
__ESIMD_INTRINSIC_DEF(rndz)

#undef __ESIMD_INTRINSIC_DEF
/// @} sycl_esimd_conv

/// @addtogroup sycl_esimd_conv
/// @{

/// "Floor" operation, vector version - alias of \c rndd.
template <typename RT, int SZ, class Sat = __ESIMD_NS::saturation_off_tag>
ESIMD_INLINE __ESIMD_NS::simd<RT, SZ>
floor(const __ESIMD_NS::simd<float, SZ> src0, Sat sat = {}) {
return esimd::rndd<RT, SZ>(src0, sat);
}

/// "Floor" operation, scalar version - alias of \c rndd.
template <typename RT, class Sat = __ESIMD_NS::saturation_off_tag>
ESIMD_INLINE RT floor(float src0, Sat sat = {}) {
return esimd::rndd<RT, 1U>(src0, sat)[0];
}

/// "Ceiling" operation, vector version - alias of \c rndu.
template <typename RT, int SZ, class Sat = __ESIMD_NS::saturation_off_tag>
ESIMD_INLINE __ESIMD_NS::simd<RT, SZ>
ceil(const __ESIMD_NS::simd<float, SZ> src0, Sat sat = {}) {
return esimd::rndu<RT, SZ>(src0, sat);
}

/// "Ceiling" operation, scalar version - alias of \c rndu.
template <typename RT, class Sat = __ESIMD_NS::saturation_off_tag>
ESIMD_INLINE RT ceil(float src0, Sat sat = {}) {
return esimd::rndu<RT, 1U>(src0, sat);
}

/// Round to integral value using the round to zero rounding mode (vector
/// version). Alias of \c rndz.
/// @tparam RT element type of the return vector.
/// @tparam SZ size of the input and returned vectors.
/// @param src0 the input vector.
/// @param sat enables/disables the saturation (off by default). Possible
/// values: saturation_on/saturation_off.
/// @return vector of rounded values.
template <typename RT, int SZ, class Sat = __ESIMD_NS::saturation_off_tag>
__ESIMD_API __ESIMD_NS::simd<RT, SZ>
trunc(const __ESIMD_NS::simd<float, SZ> &src0, Sat sat = {}) {
return esimd::rndz<RT, SZ>(src0, sat);
}

/// Round to integral value using the round to zero rounding mode (scalar
/// version). Alias of \c rndz.
/// @tparam RT type of the return value.
/// @param src0 the input operand.
/// @param sat enables/disables the saturation (off by default). Possible
/// values: saturation_on/saturation_off.
/// @return rounded value.
template <typename RT, class Sat = __ESIMD_NS::saturation_off_tag>
__ESIMD_API RT trunc(float src0, Sat sat = {}) {
return esimd::rndz<RT, 1U>(src0, sat)[0];
}

/// @} sycl_esimd_conv

/// @addtogroup sycl_esimd_bitmanip
/// @{

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -88,19 +88,6 @@ __ESIMD_INTRIN __ESIMD_raw_vec_t(T0, SZ)
__esimd_sbfe(__ESIMD_raw_vec_t(T0, SZ) src0, __ESIMD_raw_vec_t(T0, SZ) src1,
__ESIMD_raw_vec_t(T0, SZ) src2);

template <int SZ>
__ESIMD_INTRIN __ESIMD_DNS::vector_type_t<float, SZ>
__esimd_rndd(__ESIMD_DNS::vector_type_t<float, SZ> src0);
template <int SZ>
__ESIMD_INTRIN __ESIMD_DNS::vector_type_t<float, SZ>
__esimd_rndu(__ESIMD_DNS::vector_type_t<float, SZ> src0);
template <int SZ>
__ESIMD_INTRIN __ESIMD_DNS::vector_type_t<float, SZ>
__esimd_rnde(__ESIMD_DNS::vector_type_t<float, SZ> src0);
template <int SZ>
__ESIMD_INTRIN __ESIMD_DNS::vector_type_t<float, SZ>
__esimd_rndz(__ESIMD_DNS::vector_type_t<float, SZ> src0);

template <typename T, int N>
__ESIMD_INTRIN __ESIMD_raw_vec_t(T, N)
__esimd_dp4(__ESIMD_raw_vec_t(T, N) v1, __ESIMD_raw_vec_t(T, N) v2)
Expand Down Expand Up @@ -452,79 +439,6 @@ __ESIMD_INTRIN __ESIMD_raw_vec_t(T, SZ)
return retv;
}

template <int SZ>
__ESIMD_INTRIN __ESIMD_DNS::vector_type_t<float, SZ>
__esimd_rndd(__ESIMD_DNS::vector_type_t<float, SZ> src0) {
__ESIMD_DNS::vector_type_t<float, SZ> retv;

for (int i = 0; i < SZ; i++) {
SIMDCF_ELEMENT_SKIP(i);
retv[i] = floor(src0[i]);
}
return retv;
}

template <int SZ>
__ESIMD_INTRIN __ESIMD_DNS::vector_type_t<float, SZ>
__esimd_rndu(__ESIMD_DNS::vector_type_t<float, SZ> src0) {
__ESIMD_DNS::vector_type_t<float, SZ> retv;
int increment;

for (int i = 0; i < SZ; i++) {
SIMDCF_ELEMENT_SKIP(i);
if (src0[i] - floor(src0[i]) > 0.0f) {
increment = 1;
} else {
increment = 0;
}

retv[i] = floor(src0[i]) + increment;
}

return retv;
}

template <int SZ>
__ESIMD_INTRIN __ESIMD_DNS::vector_type_t<float, SZ>
__esimd_rnde(__ESIMD_DNS::vector_type_t<float, SZ> src0) {
__ESIMD_DNS::vector_type_t<float, SZ> retv;
int increment;

for (int i = 0; i < SZ; i++) {
SIMDCF_ELEMENT_SKIP(i);
if (src0[i] - floor(src0[i]) > 0.5f) {
increment = 1;
} else if (src0[i] - floor(src0[i]) < 0.5f) {
increment = 0;
} else {
increment = (int(floor(src0[i])) % 2 == 1);
}

retv[i] = floor(src0[i]) + increment;
}

return retv;
}

template <int SZ>
__ESIMD_INTRIN __ESIMD_DNS::vector_type_t<float, SZ>
__esimd_rndz(__ESIMD_DNS::vector_type_t<float, SZ> src0) {
__ESIMD_DNS::vector_type_t<float, SZ> retv;
int increment;

for (int i = 0; i < SZ; i++) {
SIMDCF_ELEMENT_SKIP(i);
if (fabs(src0[i]) < fabs(floor(src0[i]))) {
increment = 1;
} else {
increment = 0;
}
retv[i] = floor(src0[i]) + increment;
}

return retv;
}

inline constexpr __ESIMD_NS::uint
__esimd_dpas_bits_precision(__ESIMD_ENS::argument_type precisionType) {
return precisionType == __ESIMD_ENS::argument_type::TF32 ? 32
Expand Down
Loading