Skip to content
Open
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
6 changes: 3 additions & 3 deletions include/xvec/detail/core.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -401,7 +401,7 @@ template <class... _Flags> struct flags {
namespace detail {
class flag_convert {};
class flag_aligned {};
template<size_t _N> class flag_overaligned {};
template<std::size_t _N> class flag_overaligned {};
class flag_unchecked {};

// Add extra flags to the existing flags.
Expand All @@ -421,7 +421,7 @@ inline constexpr flags<> flag_default{};
inline constexpr flags<detail::flag_convert> flag_convert{};
inline constexpr flags<detail::flag_aligned> flag_aligned{};

template<size_t _N> requires (std::has_single_bit(_N)) inline constexpr flags<detail::flag_overaligned<_N>> flag_overaligned{};
template<std::size_t _N> requires (std::has_single_bit(_N)) inline constexpr flags<detail::flag_overaligned<_N>> flag_overaligned{};

/// @} cpp26_flags

Expand Down Expand Up @@ -453,7 +453,7 @@ struct vec_traits
static constexpr simd_size_type _numDataElements = complex_number<_Tp> ? 2 * _Np : _Np;

/// The number of storage elements. This could be bigger than the number of data elements.
static constexpr simd_size_type _numStorageElements = isLlvm ? _numDataElements : std::bit_ceil((uint64_t)_numDataElements);
static constexpr simd_size_type _numStorageElements = isLlvm ? _numDataElements : std::bit_ceil((std::uint64_t)_numDataElements);

/// The bare storage type used by the compiler for the elements. For
/// arithmetic types this will typically be the same as the type itself, but
Expand Down
17 changes: 9 additions & 8 deletions include/xvec/detail/loadstore.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@

#include <xvec/detail/config.hpp>

#include <cstddef> // std::size_t
#include <iterator> // std::contiguous_iterator, std::iter_value_t

namespace _XVEC_NAMESPACE::simd
Expand Down Expand Up @@ -146,7 +147,7 @@ partial_load(_It first, std::iter_difference_t<_It> n,
/// @param f Memory-operation flags.
template<typename _Vp = std::nullptr_t, std::contiguous_iterator _It, std::sized_sentinel_for<_It> _Sent, typename... _Flags>
constexpr detail::load_return_type_iter<_Vp, _It> partial_load(_It first, _Sent last, flags<_Flags...> f = {})
{ return partial_load<_Vp>(std::span(first, static_cast<size_t>(last - first)), f); }
{ return partial_load<_Vp>(std::span(first, static_cast<std::size_t>(last - first)), f); }

/// @brief Masked partial load from an iterator and sized sentinel.
/// @param first The beginning of the source range.
Expand All @@ -156,7 +157,7 @@ constexpr detail::load_return_type_iter<_Vp, _It> partial_load(_It first, _Sent
template<typename _Vp = std::nullptr_t, std::contiguous_iterator _It, std::sized_sentinel_for<_It> _Sent, typename... _Flags>
constexpr detail::load_return_type_iter<_Vp, _It>
partial_load(_It first, _Sent last, const detail::load_mask_type_iter<_Vp, _It>& m, flags<_Flags...> f = {})
{ return partial_load<_Vp>(std::span(first, static_cast<size_t>(last - first)), m, f); }
{ return partial_load<_Vp>(std::span(first, static_cast<std::size_t>(last - first)), m, f); }

/// @brief Unchecked load from a contiguous sized range.
/// @param r The source range.
Expand Down Expand Up @@ -199,7 +200,7 @@ unchecked_load(_It first, std::iter_difference_t<_It> n,
/// @param f Memory-operation flags.
template<typename _Vp = std::nullptr_t, std::contiguous_iterator _It, std::sized_sentinel_for<_It> _Sent, typename... _Flags>
constexpr detail::load_return_type_iter<_Vp, _It> unchecked_load(_It first, _Sent last, flags<_Flags...> f = {})
{ return partial_load<_Vp>(std::span{first, static_cast<size_t>(last - first)}, detail::add_unchecked_flag(f)); }
{ return partial_load<_Vp>(std::span{first, static_cast<std::size_t>(last - first)}, detail::add_unchecked_flag(f)); }

/// @brief Masked unchecked load from an iterator and sized sentinel.
/// @param first The beginning of the source range.
Expand All @@ -209,7 +210,7 @@ constexpr detail::load_return_type_iter<_Vp, _It> unchecked_load(_It first, _Sen
template<typename _Vp = std::nullptr_t, std::contiguous_iterator _It, std::sized_sentinel_for<_It> _Sent, typename... _Flags>
constexpr detail::load_return_type_iter<_Vp, _It>
unchecked_load(_It first, _Sent last, const detail::load_mask_type_iter<_Vp, _It>& m, flags<_Flags...> f = {})
{ return partial_load<_Vp>(std::span(first, static_cast<size_t>(last - first)), m, detail::add_unchecked_flag(f)); }
{ return partial_load<_Vp>(std::span(first, static_cast<std::size_t>(last - first)), m, detail::add_unchecked_flag(f)); }

/// @brief Store the elements from a basic_vec value into a contiguous range,
/// performing a suitable conversion if necessary. Both unmasked and masked
Expand Down Expand Up @@ -308,7 +309,7 @@ constexpr void partial_store(const basic_vec<_Tp, _Abi>& value, _It first, std::
template<typename _Tp, typename _Abi, std::contiguous_iterator _It, std::sized_sentinel_for<_It> _Sent, typename... _Flags>
requires std::indirectly_writable<_It, _Tp>
constexpr void partial_store(const basic_vec<_Tp, _Abi>& value, _It first, _Sent last, flags<_Flags...> f = {})
{ partial_store(value, std::span(first, static_cast<size_t>(last - first)), f); }
{ partial_store(value, std::span(first, static_cast<std::size_t>(last - first)), f); }

/// @brief Masked partial store using an iterator and sized sentinel.
/// @param value The source vector.
Expand All @@ -320,7 +321,7 @@ template<typename _Tp, typename _Abi, std::contiguous_iterator _It, std::sized_s
requires std::indirectly_writable<_It, _Tp>
constexpr void partial_store(const basic_vec<_Tp, _Abi>& value, _It first, _Sent last,
const typename basic_vec<_Tp, _Abi>::mask_type& m, flags<_Flags...> f = {})
{ partial_store(value, std::span(first, static_cast<size_t>(last - first)), m, f); }
{ partial_store(value, std::span(first, static_cast<std::size_t>(last - first)), m, f); }

/// @brief Unchecked store into a contiguous sized range.
/// @param value The source vector.
Expand Down Expand Up @@ -372,7 +373,7 @@ constexpr void unchecked_store(const basic_vec<_Tp, _Abi>& value, _It first, std
template<typename _Tp, typename _Abi, std::contiguous_iterator _It, std::sized_sentinel_for<_It> _Sent, typename... _Flags>
requires std::indirectly_writable<_It, _Tp>
constexpr void unchecked_store(const basic_vec<_Tp, _Abi>& value, _It first, _Sent last, flags<_Flags...> f = {})
{ partial_store(value, std::span(first, static_cast<size_t>(last - first)), detail::add_unchecked_flag(f)); }
{ partial_store(value, std::span(first, static_cast<std::size_t>(last - first)), detail::add_unchecked_flag(f)); }

/// @brief Masked unchecked store using an iterator and sized sentinel.
/// @param value The source vector.
Expand All @@ -384,7 +385,7 @@ template<typename _Tp, typename _Abi, std::contiguous_iterator _It, std::sized_s
requires std::indirectly_writable<_It, _Tp>
constexpr void unchecked_store(const basic_vec<_Tp, _Abi>& value, _It first, _Sent last,
const typename basic_vec<_Tp, _Abi>::mask_type& m, flags<_Flags...> f = {})
{ partial_store(value, std::span(first, static_cast<size_t>(last - first)), m, detail::add_unchecked_flag(f)); }
{ partial_store(value, std::span(first, static_cast<std::size_t>(last - first)), m, detail::add_unchecked_flag(f)); }

/// @} cpp26_load_store

Expand Down
4 changes: 2 additions & 2 deletions include/xvec/detail/mask.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -570,9 +570,9 @@ constexpr auto mask_from_count(simd_size_type n) noexcept {
// CTAD, to convert a basic_mask into a basic_vec, equivalent to decltype(+mask).
/// @brief Deduce a vector type from a mask, equivalent to decltype(+k).
/// @ingroup cpp26_ctor
template<size_t _Bytes, typename _Abi>
template<std::size_t _Bytes, typename _Abi>
basic_vec(basic_mask<_Bytes, _Abi> k) ->
basic_vec<typename basic_mask<_Bytes, _Abi>::traits::element_signed_container_type, _Abi>;


} // namespace _XVEC_NAMESPACE::simd
} // namespace _XVEC_NAMESPACE::simd
2 changes: 1 addition & 1 deletion include/xvec/detail/reduce.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ inline _Tp reduce_helper(const basic_vec<_Tp, _Abi>& v, _BinaryFn binop) {
// register. It is better to handle anything small as a complete register,
// rather than extracting and inserting sub-register pieces in the final
// stages of the reduction.
constexpr int halfSize = std::bit_ceil((uint64_t)_Size) / 2;
constexpr int halfSize = std::bit_ceil((std::uint64_t)_Size) / 2;
constexpr auto opSize = std::max(register_size<_Tp, 1>, halfSize);

const auto lower = permute<opSize>(v, perm_uninitResize);
Expand Down
6 changes: 3 additions & 3 deletions include/xvec/detail/std_bit.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -171,9 +171,9 @@ constexpr _Vp bit_ceil(const _Vp& x) noexcept {
// Normally bit_ceil would need to be wary of shifts, since some types get
// promoted and would give the wrong result. This is't a problem for SIMD
// operations since promotion doesn't occur.
constexpr auto one = _Vp(uint8_t(1));
constexpr auto one = _Vp(std::uint8_t(1));
auto shift_amount = _Vp(bit_width(x - one));
return select(x < uint8_t(2), one, one << shift_amount);
return select(x < std::uint8_t(2), one, one << shift_amount);
}
}

Expand All @@ -190,7 +190,7 @@ constexpr _Vp bit_floor(const _Vp& v) noexcept {
else
{
auto log2 = rebind_cast<_Tp>(detail::cw<std::numeric_limits<_Tp>::digits - 1> - countl_zero(v));
return select(v != _Vp(), uint8_t(1) << log2, _Vp());
return select(v != _Vp(), std::uint8_t(1) << log2, _Vp());
}
}

Expand Down
5 changes: 3 additions & 2 deletions include/xvec/detail/std_math.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
#pragma once

#include <concepts>
#include <cstdint> // std::uint8_t
#include <limits> // std::numeric_limits
#include <type_traits>

Expand Down Expand Up @@ -240,7 +241,7 @@ constexpr deduced_mask_t<_Vp> isnan(generic_tag, const _Vp& v)
// ones, and the fraction nonzero. Checking a NaN against itself is another
// way but is fragile with respect to compiler optimisations.
const auto asC = vec_as_container(v);
return ((asC & expMask) == expMask) & ((asC & fractionMask) != uint8_t(0));
return ((asC & expMask) == expMask) & ((asC & fractionMask) != std::uint8_t(0));
}

/// Generic implementation of infinity classification.
Expand Down Expand Up @@ -270,7 +271,7 @@ template<detail::math_floating_point _Vp>
constexpr detail::deduced_mask_t<_Vp> signbit(generic_tag, const _Vp& v)
{
constexpr auto signBit = vec_as_container(_Vp(typename _Vp::value_type(-0.0)));
auto m = (vec_as_container(v) & signBit) != uint8_t(0);
auto m = (vec_as_container(v) & signBit) != std::uint8_t(0);
return detail::deduced_mask_t<_Vp>(m);
}

Expand Down
30 changes: 15 additions & 15 deletions include/xvec/generic/generic_impl.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -982,7 +982,7 @@ constexpr basic_vec<_Tp, _Abi> rotate_right(generic_tag, const basic_vec<_Tp, _A
template<vec_unsigned_integer _Vp, vec_integral _Sp>
requires (sizeof(typename _Vp::value_type) == sizeof(typename _Sp::value_type))
constexpr _Vp fsr(generic_tag, const _Vp& high, const _Vp& low, const _Sp& s) {
constexpr uint8_t numBits = sizeof(typename _Vp::value_type) * 8;
constexpr std::uint8_t numBits = sizeof(typename _Vp::value_type) * 8;
const auto sm = _Vp(s) % numBits;
const _Vp r = (low >> sm) | (high << ((numBits - sm) % numBits));
return select(sm != _Vp(), r, low);
Expand All @@ -991,7 +991,7 @@ constexpr _Vp fsr(generic_tag, const _Vp& high, const _Vp& low, const _Sp& s) {
template<vec_unsigned_integer _Vp, vec_integral _Sp>
requires (sizeof(typename _Vp::value_type) == sizeof(typename _Sp::value_type))
constexpr _Vp fsl(generic_tag, const _Vp& high, const _Vp& low, const _Sp& s) {
constexpr uint8_t numBits = sizeof(typename _Vp::value_type) * 8;
constexpr std::uint8_t numBits = sizeof(typename _Vp::value_type) * 8;
const auto sm = _Vp(s) % numBits;
const _Vp r = (high << sm) | (low >> ((numBits - sm) % numBits));
return select(sm != _Vp(), r, high);
Expand Down Expand Up @@ -1093,7 +1093,7 @@ constexpr basic_vec<_Tp, _Abi> byteswap(_Vendor, const basic_vec<_Tp, _Abi>& x)
// elements).
auto impl = [](auto piece)
{
const auto asBytes = simd_bit_cast<uint8_t>(piece);
const auto asBytes = simd_bit_cast<std::uint8_t>(piece);
const auto rev = permute(asBytes, [](simd_size_type idx) -> simd_size_type { return idx ^ (sizeof(_Tp) - 1); });
return simd_bit_cast<_Tp>(rev);
};
Expand All @@ -1109,7 +1109,7 @@ template<vec_integral _Vp> // :TODO: Should be unsigned_integral once bitswap is
constexpr _Vp bitreverse(generic_tag, const _Vp& x) noexcept {

auto doBrev = []<vec_type X>(X bits) {
auto asBytes = simd_bit_cast<uint8_t>(bits);
auto asBytes = simd_bit_cast<std::uint8_t>(bits);
using BM = decltype(asBytes);

constexpr BM m1(cw<0x55u>);
Expand Down Expand Up @@ -1178,7 +1178,7 @@ constexpr basic_vec<_Tp, _Abi> mask_to_vec(compact_mask_tag, const basic_mask<_B
/// @internal
template<typename _Tp, typename _Abi>
constexpr auto has_single_bit(generic_tag, const basic_vec<_Tp, _Abi>& x) noexcept {
return (x != uint8_t(0)) && ((x & (x - uint8_t(1))) == uint8_t(0));
return (x != std::uint8_t(0)) && ((x & (x - std::uint8_t(1))) == std::uint8_t(0));
}

/// @brief Perform a reduction to boolean on a mask value. The functions below are correct but very likely
Expand All @@ -1189,7 +1189,7 @@ constexpr auto has_single_bit(generic_tag, const basic_vec<_Tp, _Abi>& x) noexce
constexpr bool mask_all_of(generic_tag, const mask_type auto& mask) noexcept {
bool allSet = true; // Assume until otherwise
auto processBlock = [&]<mask_type _S>(_S m) {
constexpr uint64_t allBits = (uint64_t(1) << _S::size) - 1;
constexpr std::uint64_t allBits = (std::uint64_t(1) << _S::size) - 1;
allSet &= (allBits == m.to_ullong());
};

Expand All @@ -1207,7 +1207,7 @@ constexpr bool mask_any_of(generic_tag, const mask_type auto& mask) noexcept {
// really big masks. Note also that it would be more efficient to OR the
// values together as vecs and call to_ullong at the end, but the
// compiler (clang/oneAPI) figures this out for itself anyway.
uint64_t reducedBits = 0;
std::uint64_t reducedBits = 0;
chunked_invoke([&](auto m) { reducedBits |= m.to_ullong(); }, mask);
return reducedBits != 0;
}
Expand All @@ -1222,7 +1222,7 @@ constexpr bool mask_none_of(generic_tag, const mask_type auto& mask) noexcept {
// really big masks. Note also that it would be more efficient to OR the
// values together as vecs and call to_ullong at the end, but the
// compiler (clang/oneAPI) figures this out for itself anyway.
uint64_t reducedBits = 0;
std::uint64_t reducedBits = 0;
chunked_invoke([&](auto m) { reducedBits |= m.to_ullong(); }, mask);
return reducedBits == 0;
}
Expand Down Expand Up @@ -1277,13 +1277,13 @@ constexpr simd_size_type mask_reduce_min_index(compact_mask_tag, const _Mp& mask
// limit of 128 bits anyway, so exploit that to make the code simpler.
static_assert(_Mp::size <= 128, "This function only handles up to 128 bits");

auto lowResult = std::countr_zero((uint64_t)mask.to_builtin());
auto lowResult = std::countr_zero((std::uint64_t)mask.to_builtin());

if constexpr (_Mp::size <= 64)
return lowResult;
else
{
auto highResult = std::countr_zero((uint64_t)(mask.to_builtin() >> 64));
auto highResult = std::countr_zero((std::uint64_t)(mask.to_builtin() >> 64));
if (lowResult < 64) return lowResult;
else return highResult + 64;
}
Expand Down Expand Up @@ -1315,13 +1315,13 @@ constexpr simd_size_type mask_reduce_max_index(compact_mask_tag, const _Mp& mask
// limit of 128 bits anyway, so exploit that to make the code simpler.
static_assert(_Mp::size <= 128, "This function only handles up to 128 bits");

auto lowResult = 63 - std::countl_zero((uint64_t)mask.to_builtin());
auto lowResult = 63 - std::countl_zero((std::uint64_t)mask.to_builtin());

if constexpr (_Mp::size <= 64)
return lowResult;
else
{
auto upperBits = (uint64_t)(mask.to_builtin() >> 64);
auto upperBits = (std::uint64_t)(mask.to_builtin() >> 64);
if (upperBits != 0)
return 127 - std::countl_zero(upperBits);
else
Expand All @@ -1348,7 +1348,7 @@ constexpr auto get_n_bit_mask(generic_tag, const _Mp&, simd_size_type _n) {
// mask means switching to unsigned bytes. Even then it can only go to 256
// elements, but for now this will do.
auto unsignedIota = iota<typename _Mp::traits::unsigned_vec_for_mask>;
return unsignedIota < uint8_t(std::min<std::size_t>(_n, 255));
return unsignedIota < std::uint8_t(std::min<std::size_t>(_n, 255));
} else {
using _X = typename _Mp::traits::signed_vec_for_mask;
return iota<_X> < (typename _X::value_type)std::min(_n, _Mp::size());
Expand Down Expand Up @@ -1550,7 +1550,7 @@ constexpr _Result generate_mask_from_unsigned(compact_mask_tag, std::unsigned_in

template<vec_floating_point _Vp>
constexpr _Vp rcp(generic_tag, const _Vp& x)
{ return uint8_t(1) / x; }
{ return std::uint8_t(1) / x; }

template<vec_floating_point _Vp>
constexpr _Vp sqrt(generic_tag, const _Vp& x) {
Expand All @@ -1563,7 +1563,7 @@ constexpr _Vp sqrt(generic_tag, const _Vp& x) {

template<vec_floating_point _Vp>
constexpr _Vp rsqrt(generic_tag, const _Vp& x)
{ return uint8_t(1) / sqrt(x); }
{ return std::uint8_t(1) / sqrt(x); }

enum class RoundOp{CEIL, FLOOR, TRUNC, ROUND, RINT};

Expand Down
10 changes: 5 additions & 5 deletions include/xvec/x86/intrin.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ concept zmm_register = (sizeof(_Vec) > 32 && sizeof(_Vec) <= 64) && (std::same_a
/// @param b The input byte elements.
/// @param m The matrix elements.
/// @return The transformed byte elements.
template<uint8_t imm_byte = 0, vec_type _Bytes, vec_type _Matrix>
template<std::uint8_t imm_byte = 0, vec_type _Bytes, vec_type _Matrix>
requires ((sizeof(typename _Bytes::value_type) == 1) &&
(sizeof(typename _Matrix::value_type) == 8) &&
((_Matrix::size() * 8) == _Bytes::size()))
Expand All @@ -79,7 +79,7 @@ inline _Bytes gf2p8affine(const _Bytes& b, const _Matrix& m)
};

return std::bit_cast<_Bytes>(chunked_invoke([=](auto x, auto y) { return decltype(x)(impl(x, y)); },
simd_bit_cast<uint8_t>(b), simd_bit_cast<uint8_t>(m)));
simd_bit_cast<std::uint8_t>(b), simd_bit_cast<std::uint8_t>(m)));
}

/// This variant of the GFNI affine instruction provides an easy way of
Expand All @@ -90,13 +90,13 @@ inline _Bytes gf2p8affine(const _Bytes& b, const _Matrix& m)
/// @param b The input byte elements.
/// @param m The shared matrix.
/// @return The transformed byte elements.
template<uint8_t imm_byte = 0, vec_type _Bytes>
template<std::uint8_t imm_byte = 0, vec_type _Bytes>
requires (sizeof(typename _Bytes::value_type) == 1) // Allow any type of single byte element to be transformed.
inline _Bytes gf2p8affine(const _Bytes& b, uint64_t m)
inline _Bytes gf2p8affine(const _Bytes& b, std::uint64_t m)
{
constexpr int roundedTo8 = ((_Bytes::size() + 7) / 8) * 8;
auto resizeTo8 = permute<roundedTo8>(b, detail::perm_uninitResize);
auto r = gf2p8affine<imm_byte>(resizeTo8, vec<uint64_t, roundedTo8 / 8>(m));
auto r = gf2p8affine<imm_byte>(resizeTo8, vec<std::uint64_t, roundedTo8 / 8>(m));
return take<(int)_Bytes::size()>(r);
}

Expand Down
Loading
Loading