Skip to content

Commit 1603bbe

Browse files
authored
[SYCL][ESIMD] Replace use of intrinsics with spirv functions for addc/subb (#13093)
1 parent 68c0fcc commit 1603bbe

File tree

5 files changed

+314
-275
lines changed

5 files changed

+314
-275
lines changed

sycl/include/sycl/__spirv/spirv_ops.hpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
#include <stddef.h> // for size_t
1616
#include <stdint.h> // for uint32_t
1717
#include <type_traits>
18+
#include <utility> // for pair
1819

1920
// Convergent attribute
2021
#ifdef __SYCL_DEVICE_ONLY__
@@ -1132,6 +1133,13 @@ extern __DPCPP_SYCL_EXTERNAL
11321133
std::enable_if_t<std::is_integral_v<to> && std::is_unsigned_v<to>, to>
11331134
__spirv_ConvertPtrToU(from val) noexcept;
11341135

1136+
template <typename T, int N>
1137+
extern __DPCPP_SYCL_EXTERNAL std::pair<__ocl_vec_t<T, N>, __ocl_vec_t<T, N>>
1138+
__spirv_IAddCarry(__ocl_vec_t<T, N> src0, __ocl_vec_t<T, N> src1);
1139+
1140+
template <typename T, int N>
1141+
extern __DPCPP_SYCL_EXTERNAL std::pair<__ocl_vec_t<T, N>, __ocl_vec_t<T, N>>
1142+
__spirv_ISubBorrow(__ocl_vec_t<T, N> src0, __ocl_vec_t<T, N> src1);
11351143
template <typename RetT, typename... ArgsT>
11361144
extern __DPCPP_SYCL_EXTERNAL __spv::__spirv_TaskSequenceINTEL *
11371145
__spirv_TaskSequenceCreateINTEL(RetT (*f)(ArgsT...), int Pipelined = -1,

sycl/include/sycl/ext/intel/esimd/math.hpp

Lines changed: 89 additions & 125 deletions
Original file line numberDiff line numberDiff line change
@@ -1720,131 +1720,95 @@ bfn(T src0, T src1, T src2) {
17201720

17211721
/// @} sycl_esimd_logical
17221722

1723-
/// Performs add with carry of 2 unsigned 32-bit vectors.
1724-
/// @tparam N size of the vectors
1725-
/// @param carry vector that is going to hold resulting carry flag
1726-
/// @param src0 first term
1727-
/// @param src1 second term
1728-
/// @return sum of 2 terms, carry flag is returned through \c carry parameter
1729-
template <int N>
1730-
__ESIMD_API __ESIMD_NS::simd<uint32_t, N>
1731-
addc(__ESIMD_NS::simd<uint32_t, N> &carry, __ESIMD_NS::simd<uint32_t, N> src0,
1732-
__ESIMD_NS::simd<uint32_t, N> src1) {
1733-
std::pair<__ESIMD_DNS::vector_type_t<uint32_t, N>,
1734-
__ESIMD_DNS::vector_type_t<uint32_t, N>>
1735-
Result = __esimd_addc<uint32_t, N>(src0.data(), src1.data());
1736-
1737-
carry = Result.first;
1738-
return Result.second;
1739-
}
1740-
1741-
/// Performs add with carry of a unsigned 32-bit vector and scalar.
1742-
/// @tparam N size of the vectors
1743-
/// @param carry vector that is going to hold resulting carry flag
1744-
/// @param src0 first term
1745-
/// @param src1 second term
1746-
/// @return sum of 2 terms, carry flag is returned through \c carry parameter
1747-
template <int N>
1748-
__ESIMD_API __ESIMD_NS::simd<uint32_t, N>
1749-
addc(__ESIMD_NS::simd<uint32_t, N> &carry, __ESIMD_NS::simd<uint32_t, N> src0,
1750-
uint32_t src1) {
1751-
__ESIMD_NS::simd<uint32_t, N> Src1V = src1;
1752-
return addc(carry, src0, Src1V);
1753-
}
1754-
1755-
/// Performs add with carry of a unsigned 32-bit scalar and vector.
1756-
/// @tparam N size of the vectors
1757-
/// @param carry vector that is going to hold resulting carry flag
1758-
/// @param src0 first term
1759-
/// @param src1 second term
1760-
/// @return sum of 2 terms, carry flag is returned through \c carry parameter
1761-
template <int N>
1762-
__ESIMD_API __ESIMD_NS::simd<uint32_t, N>
1763-
addc(__ESIMD_NS::simd<uint32_t, N> &carry, uint32_t src0,
1764-
__ESIMD_NS::simd<uint32_t, N> src1) {
1765-
__ESIMD_NS::simd<uint32_t, N> Src0V = src0;
1766-
return addc(carry, Src0V, src1);
1767-
}
1768-
1769-
/// Performs add with carry of a unsigned 32-bit scalars.
1770-
/// @tparam N size of the vectors
1771-
/// @param carry scalar that is going to hold resulting carry flag
1772-
/// @param src0 first term
1773-
/// @param src1 second term
1774-
/// @return sum of 2 terms, carry flag is returned through \c carry parameter
1775-
__ESIMD_API uint32_t addc(uint32_t &carry, uint32_t src0, uint32_t src1) {
1776-
__ESIMD_NS::simd<uint32_t, 1> CarryV = carry;
1777-
__ESIMD_NS::simd<uint32_t, 1> Src0V = src0;
1778-
__ESIMD_NS::simd<uint32_t, 1> Src1V = src1;
1779-
__ESIMD_NS::simd<uint32_t, 1> Res = addc(CarryV, Src0V, Src1V);
1780-
carry = CarryV[0];
1781-
return Res[0];
1782-
}
1783-
1784-
/// Performs substraction with borrow of 2 unsigned 32-bit vectors.
1785-
/// @tparam N size of the vectors
1786-
/// @param borrow vector that is going to hold resulting borrow flag
1787-
/// @param src0 first term
1788-
/// @param src1 second term
1789-
/// @return difference of 2 terms, borrow flag is returned through \c borrow
1790-
/// parameter
1791-
template <int N>
1792-
__ESIMD_API __ESIMD_NS::simd<uint32_t, N>
1793-
subb(__ESIMD_NS::simd<uint32_t, N> &borrow, __ESIMD_NS::simd<uint32_t, N> src0,
1794-
__ESIMD_NS::simd<uint32_t, N> src1) {
1795-
std::pair<__ESIMD_DNS::vector_type_t<uint32_t, N>,
1796-
__ESIMD_DNS::vector_type_t<uint32_t, N>>
1797-
Result = __esimd_subb<uint32_t, N>(src0.data(), src1.data());
1798-
1799-
borrow = Result.first;
1800-
return Result.second;
1801-
}
1802-
1803-
/// Performs substraction with borrow of unsigned 32-bit vector and scalar.
1804-
/// @tparam N size of the vectors
1805-
/// @param borrow vector that is going to hold resulting borrow flag
1806-
/// @param src0 first term
1807-
/// @param src1 second term
1808-
/// @return difference of 2 terms, borrow flag is returned through \c borrow
1809-
/// parameter
1810-
template <int N>
1811-
__ESIMD_API __ESIMD_NS::simd<uint32_t, N>
1812-
subb(__ESIMD_NS::simd<uint32_t, N> &borrow, __ESIMD_NS::simd<uint32_t, N> src0,
1813-
uint32_t src1) {
1814-
__ESIMD_NS::simd<uint32_t, N> Src1V = src1;
1815-
return subb(borrow, src0, Src1V);
1816-
}
1817-
1818-
/// Performs substraction with borrow of unsigned 32-bit scalar and vector.
1819-
/// @tparam N size of the vectors
1820-
/// @param borrow vector that is going to hold resulting borrow flag
1821-
/// @param src0 first term
1822-
/// @param src1 second term
1823-
/// @return difference of 2 terms, borrow flag is returned through \c borrow
1824-
/// parameter
1825-
template <int N>
1826-
__ESIMD_API __ESIMD_NS::simd<uint32_t, N>
1827-
subb(__ESIMD_NS::simd<uint32_t, N> &borrow, uint32_t src0,
1828-
__ESIMD_NS::simd<uint32_t, N> src1) {
1829-
__ESIMD_NS::simd<uint32_t, N> Src0V = src0;
1830-
return subb(borrow, Src0V, src1);
1831-
}
1832-
1833-
/// Performs substraction with borrow of 2 unsigned 32-bit scalars.
1834-
/// @tparam N size of the vectors
1835-
/// @param borrow scalar that is going to hold resulting borrow flag
1836-
/// @param src0 first term
1837-
/// @param src1 second term
1838-
/// @return difference of 2 terms, borrow flag is returned through \c borrow
1839-
/// parameter
1840-
__ESIMD_API uint32_t subb(uint32_t &borrow, uint32_t src0, uint32_t src1) {
1841-
__ESIMD_NS::simd<uint32_t, 1> BorrowV = borrow;
1842-
__ESIMD_NS::simd<uint32_t, 1> Src0V = src0;
1843-
__ESIMD_NS::simd<uint32_t, 1> Src1V = src1;
1844-
__ESIMD_NS::simd<uint32_t, 1> Res = subb(BorrowV, Src0V, Src1V);
1845-
borrow = BorrowV[0];
1846-
return Res[0];
1847-
}
1723+
#if defined(__SYCL_DEVICE_ONLY__)
1724+
#define __ESIMD_ADDC_IMPL(T) \
1725+
std::pair<__ESIMD_DNS::vector_type_t<T, N>, \
1726+
__ESIMD_DNS::vector_type_t<T, N>> \
1727+
Result = __spirv_IAddCarry<T, N>(src0.data(), src1.data()); \
1728+
carry = Result.second; \
1729+
return Result.first;
1730+
#else
1731+
#define __ESIMD_ADDC_IMPL(T) return 0;
1732+
#endif // __SYCL_DEVICE_ONLY__
1733+
1734+
#define __ESIMD_ADDC(T) \
1735+
template <int N> \
1736+
__ESIMD_API __ESIMD_NS::simd<T, N> addc(__ESIMD_NS::simd<T, N> &carry, \
1737+
__ESIMD_NS::simd<T, N> src0, \
1738+
__ESIMD_NS::simd<T, N> src1) { \
1739+
__ESIMD_ADDC_IMPL(T) \
1740+
} \
1741+
template <int N> \
1742+
__ESIMD_API __ESIMD_NS::simd<T, N> addc( \
1743+
__ESIMD_NS::simd<T, N> &carry, __ESIMD_NS::simd<T, N> src0, T src1) { \
1744+
__ESIMD_NS::simd<T, N> Src1V = src1; \
1745+
return addc(carry, src0, Src1V); \
1746+
} \
1747+
template <int N> \
1748+
__ESIMD_API __ESIMD_NS::simd<T, N> addc( \
1749+
__ESIMD_NS::simd<T, N> &carry, T src0, __ESIMD_NS::simd<T, N> src1) { \
1750+
__ESIMD_NS::simd<T, N> Src0V = src0; \
1751+
return addc(carry, Src0V, src1); \
1752+
} \
1753+
__ESIMD_API T addc(T &carry, T src0, T src1) { \
1754+
__ESIMD_NS::simd<T, 1> CarryV = carry; \
1755+
__ESIMD_NS::simd<T, 1> Src0V = src0; \
1756+
__ESIMD_NS::simd<T, 1> Src1V = src1; \
1757+
__ESIMD_NS::simd<T, 1> Res = addc(CarryV, Src0V, Src1V); \
1758+
carry = CarryV[0]; \
1759+
return Res[0]; \
1760+
}
1761+
1762+
__ESIMD_ADDC(uint32_t)
1763+
__ESIMD_ADDC(uint64_t)
1764+
1765+
#undef __ESIMD_ADDC
1766+
#undef __ESIMD_ADDC_IMPL
1767+
1768+
#if defined(__SYCL_DEVICE_ONLY__)
1769+
#define __ESIMD_SUBB_IMPL(T) \
1770+
std::pair<__ESIMD_DNS::vector_type_t<T, N>, \
1771+
__ESIMD_DNS::vector_type_t<T, N>> \
1772+
Result = __spirv_ISubBorrow<T, N>(src0.data(), src1.data()); \
1773+
borrow = Result.second; \
1774+
return Result.first;
1775+
#else
1776+
#define __ESIMD_SUBB_IMPL(T) return 0;
1777+
#endif // __SYCL_DEVICE_ONLY__
1778+
1779+
#define __ESIMD_SUBB(T) \
1780+
template <int N> \
1781+
__ESIMD_API __ESIMD_NS::simd<T, N> subb(__ESIMD_NS::simd<T, N> &borrow, \
1782+
__ESIMD_NS::simd<T, N> src0, \
1783+
__ESIMD_NS::simd<T, N> src1) { \
1784+
__ESIMD_SUBB_IMPL(T) \
1785+
} \
1786+
template <int N> \
1787+
__ESIMD_API __ESIMD_NS::simd<T, N> subb( \
1788+
__ESIMD_NS::simd<T, N> &borrow, __ESIMD_NS::simd<T, N> src0, T src1) { \
1789+
__ESIMD_NS::simd<T, N> Src1V = src1; \
1790+
return subb(borrow, src0, Src1V); \
1791+
} \
1792+
template <int N> \
1793+
__ESIMD_API __ESIMD_NS::simd<T, N> subb( \
1794+
__ESIMD_NS::simd<T, N> &borrow, T src0, __ESIMD_NS::simd<T, N> src1) { \
1795+
__ESIMD_NS::simd<T, N> Src0V = src0; \
1796+
return subb(borrow, Src0V, src1); \
1797+
} \
1798+
__ESIMD_API T subb(T &borrow, T src0, T src1) { \
1799+
__ESIMD_NS::simd<T, 1> BorrowV = borrow; \
1800+
__ESIMD_NS::simd<T, 1> Src0V = src0; \
1801+
__ESIMD_NS::simd<T, 1> Src1V = src1; \
1802+
__ESIMD_NS::simd<T, 1> Res = subb(BorrowV, Src0V, Src1V); \
1803+
borrow = BorrowV[0]; \
1804+
return Res[0]; \
1805+
} // namespace ext::intel::esimd
1806+
1807+
__ESIMD_SUBB(uint32_t)
1808+
__ESIMD_SUBB(uint64_t)
1809+
1810+
#undef __ESIMD_SUBB
1811+
#undef __ESIMD_SUBB_IMPL
18481812

18491813
/// rdtsc - get the value of timestamp counter.
18501814
/// @return the current value of timestamp counter

sycl/include/sycl/ext/intel/experimental/esimd/detail/math_intrin.hpp

Lines changed: 0 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -94,18 +94,6 @@ __ESIMD_INTRIN __ESIMD_DNS::vector_type_t<T, N> __esimd_dpasw_nosrc0(
9494
__ESIMD_DNS::vector_type_t<T1, N1> src1,
9595
__ESIMD_DNS::vector_type_t<T2, N2> src2) __ESIMD_INTRIN_END;
9696

97-
template <typename T, int N>
98-
__ESIMD_INTRIN std::pair<__ESIMD_DNS::vector_type_t<T, N>,
99-
__ESIMD_DNS::vector_type_t<T, N>>
100-
__esimd_addc(__ESIMD_DNS::vector_type_t<T, N> src0,
101-
__ESIMD_DNS::vector_type_t<T, N> src1) __ESIMD_INTRIN_END;
102-
103-
template <typename T, int N>
104-
__ESIMD_INTRIN std::pair<__ESIMD_DNS::vector_type_t<T, N>,
105-
__ESIMD_DNS::vector_type_t<T, N>>
106-
__esimd_subb(__ESIMD_DNS::vector_type_t<T, N> src0,
107-
__ESIMD_DNS::vector_type_t<T, N> src1) __ESIMD_INTRIN_END;
108-
10997
template <uint8_t FuncControl, typename T, int N>
11098
__ESIMD_INTRIN __ESIMD_raw_vec_t(T, N)
11199
__esimd_bfn(__ESIMD_raw_vec_t(T, N) src0, __ESIMD_raw_vec_t(T, N) src1,

0 commit comments

Comments
 (0)