Skip to content

Commit

Permalink
Move self_leq to the is_less_equal callable (#2054)
Browse files Browse the repository at this point in the history
  • Loading branch information
SadiinsoSnowfall authored Feb 3, 2025
1 parent a1088f6 commit bd25bb6
Show file tree
Hide file tree
Showing 18 changed files with 329 additions and 248 deletions.
14 changes: 8 additions & 6 deletions include/eve/arch/cpu/wide.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,8 @@
#include <eve/module/core/regular/shl.hpp>
#include <eve/module/core/regular/shr.hpp>
#include <eve/module/core/regular/is_greater.hpp>
#include <eve/module/core/regular/is_less.hpp>
#include <eve/module/core/regular/is_less_equal.hpp>
#include <eve/memory/soa_ptr.hpp>
#include <eve/traits/product_type.hpp>

Expand Down Expand Up @@ -953,32 +955,32 @@ namespace eve
}

//! @brief Element-wise less-or-equal comparison between eve::wide
friend EVE_FORCEINLINE auto operator<=(wide v, wide w) noexcept
friend EVE_FORCEINLINE auto operator<=(wide a, wide b) noexcept
#if !defined(EVE_DOXYGEN_INVOKED)
requires(supports_ordering_v<Type>)
#endif
{
return detail::self_leq(v, w);
return is_less_equal(a, b);
}

//! @brief Element-wise less-or-equal comparison between a eve::wide and a scalar
template<scalar_value S>
friend EVE_FORCEINLINE auto operator<=(wide v, S w) noexcept
friend EVE_FORCEINLINE auto operator<=(wide w, S s) noexcept
#if !defined(EVE_DOXYGEN_INVOKED)
requires(supports_ordering_v<Type>)
#endif
{
return v <= wide {w};
return is_less_equal(w, s);
}

//! @brief Element-wise less-or-equal comparison between a scalar and a eve::wide
template<scalar_value S>
friend EVE_FORCEINLINE auto operator<=(S v, wide w) noexcept
friend EVE_FORCEINLINE auto operator<=(S s, wide w) noexcept
#if !defined(EVE_DOXYGEN_INVOKED)
requires(supports_ordering_v<Type>)
#endif
{
return wide {v} <= w;
return is_less_equal(s, w);
}

//! Computes the logical negation of its parameter
Expand Down
33 changes: 0 additions & 33 deletions include/eve/detail/function/simd/arm/neon/friends.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -94,37 +94,4 @@ namespace eve::detail
else if constexpr( sizeof(T) == 8 )
return map([]<typename E>(E const& e, E const& f){ return as_logical_t<E>(e >= f); }, v, w);
}

template<typename T, typename N>
EVE_FORCEINLINE logical<wide<T,N>> self_leq(wide<T, N> v,wide<T, N> w) noexcept
requires arm_abi<abi_t<T, N>>
{
constexpr auto cat = categorize<wide<T, N>>();

if constexpr( cat == category::int32x4 ) return vcleq_s32(v, w);
else if constexpr( cat == category::int16x8 ) return vcleq_s16(v, w);
else if constexpr( cat == category::int8x16 ) return vcleq_s8(v, w);
else if constexpr( cat == category::uint32x4 ) return vcleq_u32(v, w);
else if constexpr( cat == category::uint16x8 ) return vcleq_u16(v, w);
else if constexpr( cat == category::uint8x16 ) return vcleq_u8(v, w);
else if constexpr( cat == category::float32x4) return vcleq_f32(v, w);
else if constexpr( cat == category::int32x2 ) return vcle_s32(v, w);
else if constexpr( cat == category::int16x4 ) return vcle_s16(v, w);
else if constexpr( cat == category::int8x8 ) return vcle_s8(v, w);
else if constexpr( cat == category::uint32x2 ) return vcle_u32(v, w);
else if constexpr( cat == category::uint16x4 ) return vcle_u16(v, w);
else if constexpr( cat == category::uint8x8 ) return vcle_u8(v, w);
else if constexpr( cat == category::float32x2) return vcle_f32(v, w);
else if constexpr( current_api >= asimd)
{
if constexpr( cat == category::float64x1) return vcle_f64(v, w);
else if constexpr( cat == category::int64x1) return vcle_s64(v, w);
else if constexpr( cat == category::uint64x1) return vcle_u64(v, w);
else if constexpr( cat == category::float64x2) return vcleq_f64(v, w);
else if constexpr( cat == category::int64x2) return vcleq_s64(v, w);
else if constexpr( cat == category::uint64x2) return vcleq_u64(v, w);
}
else if constexpr( sizeof(T) == 8 )
return map([]<typename E>(E const& e, E const& f){ return as_logical_t<E>(e <= f); }, v, w);
}
}
5 changes: 0 additions & 5 deletions include/eve/detail/function/simd/arm/sve/friends.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -22,11 +22,6 @@ EVE_FORCEINLINE auto
self_neq(wide<T, N> v, wide<T, N> w) noexcept -> as_logical_t<wide<T, N>>
requires sve_abi<abi_t<T, N>> { return svcmpne(sve_true<T>(), v, w); }

template<arithmetic_scalar_value T, typename N>
EVE_FORCEINLINE auto
self_leq(wide<T, N> v, wide<T, N> w) noexcept -> as_logical_t<wide<T, N>>
requires sve_abi<abi_t<T, N>> { return svcmple(sve_true<T>(), v, w); }

template<arithmetic_scalar_value T, typename N>
EVE_FORCEINLINE auto
self_geq(wide<T, N> v, wide<T, N> w) noexcept -> as_logical_t<wide<T, N>>
Expand Down
13 changes: 0 additions & 13 deletions include/eve/detail/function/simd/common/friends.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -99,19 +99,6 @@ namespace eve::detail

//================================================================================================
// Ordering operators
template<simd_value Wide>
EVE_FORCEINLINE auto self_leq(Wide const& v,Wide const& w) noexcept
{
if constexpr( product_type<Wide> )
{
return convert(kumi::to_tuple(v) <= kumi::to_tuple(w), as_element<as_logical_t<Wide>>());
}
else
{
constexpr auto ge = []<typename E>(E const& e, E const& f) { return as_logical_t<E>(e <= f); };
return apply_over(ge, v, w);
}
}

template<simd_value Wide>
EVE_FORCEINLINE auto self_geq(Wide const& v,Wide const& w) noexcept
Expand Down
10 changes: 0 additions & 10 deletions include/eve/detail/function/simd/ppc/friends.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -37,14 +37,4 @@ namespace eve::detail
else
return !(v < w);
}

template<arithmetic_scalar_value T, typename N>
EVE_FORCEINLINE auto self_leq(wide<T, N> const &v, wide<T, N> const &w) noexcept
requires ppc_abi<abi_t<T, N>>
{
if constexpr(std::is_floating_point_v<T>)
return logical<wide<T, N>>(vec_cmple(v.storage(), w.storage()));
else
return !(v > w);
}
}
31 changes: 0 additions & 31 deletions include/eve/detail/function/simd/riscv/friends.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -44,37 +44,6 @@ requires rvv_abi<abi_t<T, N>>
return self_geq_impl(lhs, rhs);
}

template<plain_scalar_value T, typename N, value U>
EVE_FORCEINLINE auto
self_leq_impl(wide<T, N> lhs, U rhs) noexcept -> logical<wide<T, N>>
requires rvv_abi<abi_t<T, N>> && (std::same_as<wide<T, N>, U> || scalar_value<U>)
{
if constexpr( scalar_value<U> && !std::same_as<T, U> ) return self_leq(lhs, static_cast<T>(rhs));
else
{
constexpr auto c = categorize<wide<T, N>>();
if constexpr( match(c, category::int_) ) return __riscv_vmsle(lhs, rhs, N::value);
else if constexpr( match(c, category::uint_) ) return __riscv_vmsleu(lhs, rhs, N::value);
else if constexpr( match(c, category::float_) ) return __riscv_vmfle(lhs, rhs, N::value);
}
}

template<plain_scalar_value T, typename N>
EVE_FORCEINLINE auto
self_leq(wide<T, N> lhs, wide<T, N> rhs) noexcept -> logical<wide<T, N>>
requires rvv_abi<abi_t<T, N>>
{
return self_leq_impl(lhs, rhs);
}

template<plain_scalar_value T, typename N>
EVE_FORCEINLINE auto
self_leq(wide<T, N> lhs, std::convertible_to<T> auto rhs) noexcept -> logical<wide<T, N>>
requires rvv_abi<abi_t<T, N>>
{
return self_leq_impl(lhs, rhs);
}

template<plain_scalar_value T, typename N, value U>
EVE_FORCEINLINE auto
self_eq_impl(wide<T, N> lhs, U rhs) noexcept -> logical<wide<T, N>>
Expand Down
51 changes: 0 additions & 51 deletions include/eve/detail/function/simd/x86/friends.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -229,55 +229,4 @@ EVE_FORCEINLINE as_logical_t<wide<T, N>>
else return !(v < w);
}
}

//================================================================================================
template<arithmetic_scalar_value T, typename N>
EVE_FORCEINLINE as_logical_t<wide<T, N>>
self_leq(wide<T, N> v, wide<T, N> w) noexcept requires x86_abi<abi_t<T, N>>
{
constexpr auto c = categorize<wide<T, N>>();
constexpr auto f = to_integer(cmp_flt::le_oq);

if constexpr( current_api >= avx512 )
{
if constexpr( c == category::float32x16 ) return mask16 {_mm512_cmp_ps_mask(v, w, f)};
else if constexpr( c == category::float32x8 ) return mask8 {_mm256_cmp_ps_mask(v, w, f)};
else if constexpr( c == category::float32x4 ) return mask8 {_mm_cmp_ps_mask(v, w, f)};
else if constexpr( c == category::float64x8 ) return mask8 {_mm512_cmp_pd_mask(v, w, f)};
else if constexpr( c == category::float64x4 ) return mask8 {_mm256_cmp_pd_mask(v, w, f)};
else if constexpr( c == category::float64x2 ) return mask8 {_mm_cmp_pd_mask(v, w, f)};
else if constexpr( c == category::uint64x8 ) return mask8 {_mm512_cmple_epu64_mask(v, w)};
else if constexpr( c == category::uint64x4 ) return mask8 {_mm256_cmple_epu64_mask(v, w)};
else if constexpr( c == category::uint64x2 ) return mask8 {_mm_cmple_epu64_mask(v, w)};
else if constexpr( c == category::uint32x16 ) return mask16 {_mm512_cmple_epu32_mask(v, w)};
else if constexpr( c == category::uint32x8 ) return mask8 {_mm256_cmple_epu32_mask(v, w)};
else if constexpr( c == category::uint32x4 ) return mask8 {_mm_cmple_epu32_mask(v, w)};
else if constexpr( c == category::uint16x32 ) return mask32 {_mm512_cmple_epu16_mask(v, w)};
else if constexpr( c == category::uint16x16 ) return mask16 {_mm256_cmple_epu16_mask(v, w)};
else if constexpr( c == category::uint16x8 ) return mask8 {_mm_cmple_epu16_mask(v, w)};
else if constexpr( c == category::uint8x64 ) return mask64 {_mm512_cmple_epu8_mask(v, w)};
else if constexpr( c == category::uint8x32 ) return mask32 {_mm256_cmple_epu8_mask(v, w)};
else if constexpr( c == category::uint8x16 ) return mask16 {_mm_cmple_epu8_mask(v, w)};
else if constexpr( c == category::int64x8 ) return mask8 {_mm512_cmple_epi64_mask(v, w)};
else if constexpr( c == category::int64x4 ) return mask8 {_mm256_cmple_epi64_mask(v, w)};
else if constexpr( c == category::int64x2 ) return mask8 {_mm_cmple_epi64_mask(v, w)};
else if constexpr( c == category::int32x16 ) return mask16 {_mm512_cmple_epi32_mask(v, w)};
else if constexpr( c == category::int32x8 ) return mask8 {_mm256_cmple_epi32_mask(v, w)};
else if constexpr( c == category::int32x4 ) return mask8 {_mm_cmple_epi32_mask(v, w)};
else if constexpr( c == category::int16x32 ) return mask32 {_mm512_cmple_epi16_mask(v, w)};
else if constexpr( c == category::int16x16 ) return mask16 {_mm256_cmple_epi16_mask(v, w)};
else if constexpr( c == category::int16x8 ) return mask8 {_mm_cmple_epi16_mask(v, w)};
else if constexpr( c == category::int8x64 ) return mask64 {_mm512_cmple_epi8_mask(v, w)};
else if constexpr( c == category::int8x32 ) return mask32 {_mm256_cmple_epi8_mask(v, w)};
else if constexpr( c == category::int8x16 ) return mask16 {_mm_cmple_epi8_mask(v, w)};
}
else
{
if constexpr( c == category::float32x8 ) return _mm256_cmp_ps(v, w, f);
else if constexpr( c == category::float64x4 ) return _mm256_cmp_pd(v, w, f);
else if constexpr( c == category::float32x4 ) return _mm_cmple_ps(v, w);
else if constexpr( c == category::float64x2 ) return _mm_cmple_pd(v, w);
else return !(v > w);
}
}
}
4 changes: 2 additions & 2 deletions include/eve/module/core/regular/impl/is_less.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,10 @@
//==================================================================================================
#pragma once

#include <eve/module/core/regular/if_else.hpp>
#include <eve/module/core/regular/fam.hpp>
#include <eve/module/core/regular/prev.hpp>
#include <eve/module/core/regular/max.hpp>
#include <eve/traits/as_logical.hpp>

namespace eve::detail
{
Expand All @@ -31,7 +31,7 @@ namespace eve::detail
else
{
if constexpr (scalar_value<T>) return as_logical_t<T>(a < b);
else return map([](auto e, auto f) { return e < f; }, a, b);
else return map([]<typename E>(E e, E f){ return as_logical_t<E>(e < f); }, a, b);
}
}
}
36 changes: 36 additions & 0 deletions include/eve/module/core/regular/impl/is_less_equal.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
//==================================================================================================
/*
EVE - Expressive Vector Engine
Copyright : EVE Project Contributors
SPDX-License-Identifier: BSL-1.0
*/
//==================================================================================================
#pragma once

#include <eve/module/core/regular/fam.hpp>
#include <eve/module/core/regular/next.hpp>
#include <eve/module/core/regular/max.hpp>
#include <eve/traits/as_logical.hpp>

namespace eve::detail
{
template<callable_options O, typename T>
EVE_FORCEINLINE constexpr as_logical_t<T> is_less_equal_(EVE_REQUIRES(cpu_), O const& o, T a, T b) noexcept
{
if constexpr (O::contains(almost))
{
auto tol = o[almost].value(T{});
if constexpr(integral_value<decltype(tol)>) return a <= eve::next(b, tol);
else return a <= fam(b, tol, eve::max(eve::abs(a), eve::abs(b)));
}
else if constexpr (product_type<T>)
{
return kumi::to_tuple(a) <= kumi::to_tuple(b);
}
else
{
if constexpr (scalar_value<T>) return as_logical_t<T>(a <= b);
else return map([]<typename E>(E e, E f){ return as_logical_t<E>(e <= f); }, a, b);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ namespace eve::detail
else if constexpr (cat == category::int64x2) return vcltq_s64(a, b);
else if constexpr (cat == category::uint64x2) return vcltq_u64(a, b);
}
else return map(is_less, a, b);
else return map([]<typename E>(E e, E f){ return as_logical_t<E>(e < f); }, a, b);
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
//==================================================================================================
/*
EVE - Expressive Vector Engine
Copyright : EVE Project Contributors
SPDX-License-Identifier: BSL-1.0
*/
//==================================================================================================
#pragma once

#include <eve/concept/value.hpp>
#include <eve/detail/abi.hpp>
#include <eve/detail/category.hpp>
#include <eve/forward.hpp>

namespace eve::detail
{
template<callable_options O, arithmetic_scalar_value T, typename N>
EVE_FORCEINLINE logical<wide<T, N>> is_less_equal_(EVE_REQUIRES(neon128_), O const& opts, wide<T, N> a, wide<T, N> b) noexcept
requires arm_abi<abi_t<T, N>>
{
if constexpr (O::contains(almost))
{
return is_less_equal.behavior(cpu_{}, opts, a, b);
}
else
{
constexpr auto cat = categorize<wide<T, N>>();

if constexpr (cat == category::int32x4) return vcleq_s32(a, b);
else if constexpr (cat == category::int16x8) return vcleq_s16(a, b);
else if constexpr (cat == category::int8x16) return vcleq_s8(a, b);
else if constexpr (cat == category::uint32x4) return vcleq_u32(a, b);
else if constexpr (cat == category::uint16x8) return vcleq_u16(a, b);
else if constexpr (cat == category::uint8x16) return vcleq_u8(a, b);
else if constexpr (cat == category::float32x4) return vcleq_f32(a, b);
else if constexpr (cat == category::int32x2) return vcle_s32(a, b);
else if constexpr (cat == category::int16x4) return vcle_s16(a, b);
else if constexpr (cat == category::int8x8) return vcle_s8(a, b);
else if constexpr (cat == category::uint32x2) return vcle_u32(a, b);
else if constexpr (cat == category::uint16x4) return vcle_u16(a, b);
else if constexpr (cat == category::uint8x8) return vcle_u8(a, b);
else if constexpr (cat == category::float32x2) return vcle_f32(a, b);
else if constexpr (current_api >= asimd)
{
if constexpr (cat == category::float64x1) return vcle_f64(a, b);
else if constexpr (cat == category::int64x1) return vcle_s64(a, b);
else if constexpr (cat == category::uint64x1) return vcle_u64(a, b);
else if constexpr (cat == category::float64x2) return vcleq_f64(a, b);
else if constexpr (cat == category::int64x2) return vcleq_s64(a, b);
else if constexpr (cat == category::uint64x2) return vcleq_u64(a, b);
}
else return map([]<typename E>(E e, E f){ return as_logical_t<E>(e <= f); }, a, b);
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
//==================================================================================================
/*
EVE - Expressive Vector Engine
Copyright : EVE Project Contributors
SPDX-License-Identifier: BSL-1.0
*/
//==================================================================================================
#pragma once

#include <eve/concept/value.hpp>
#include <eve/detail/implementation.hpp>

namespace eve::detail
{
template<callable_options O, typename T, typename N>
EVE_FORCEINLINE logical<wide<T, N>> is_less_equal_(EVE_REQUIRES(sve_), O const& opts, wide<T, N> a, wide<T, N> b) noexcept
requires sve_abi<abi_t<T, N>>
{
if constexpr (O::contains(almost)) return is_less_equal.behavior(cpu_{}, opts, a, b);
else return svcmple(sve_true<T>(), a, b);
}
}
25 changes: 25 additions & 0 deletions include/eve/module/core/regular/impl/simd/ppc/is_less_equal.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
//==================================================================================================
/*
EVE - Expressive Vector Engine
Copyright : EVE Project Contributors
SPDX-License-Identifier: BSL-1.0
*/
//==================================================================================================
#pragma once

#include <eve/concept/value.hpp>
#include <eve/detail/abi.hpp>
#include <eve/detail/category.hpp>
#include <eve/forward.hpp>

namespace eve::detail
{
template<callable_options O, arithmetic_scalar_value T, typename N>
EVE_FORCEINLINE logical<wide<T, N>> is_less_equal_(EVE_REQUIRES(vmx_), O const& opts, wide<T, N> a, wide<T, N> b) noexcept
requires ppc_abi<abi_t<T, N>>
{
if constexpr (O::contains(almost)) return is_less_equal.behavior(cpu_{}, opts, a, b);
else if constexpr(std::is_floating_point_v<T>) return logical<wide<T, N>>(vec_cmple(a.storage(), b.storage()));
else return !(a > b);
}
}
Loading

0 comments on commit bd25bb6

Please sign in to comment.