Skip to content
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

Fpclass #1942

Merged
merged 25 commits into from
Sep 3, 2024
Merged

Fpclass #1942

Show file tree
Hide file tree
Changes from 24 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
5 changes: 5 additions & 0 deletions include/eve/detail/function/simd/x86/flags.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,11 @@ namespace eve::detail
return static_cast<std::int32_t>(a) | static_cast<std::int32_t>(b);
}

EVE_FORCEINLINE constexpr std::int32_t to_integer(fpclass a) noexcept
{
return static_cast<std::int32_t>(a);
}

enum class range_ctrl { min = 0b00
, max = 0b01
, absolute_min= 0b10
Expand Down
2 changes: 2 additions & 0 deletions include/eve/module/core/regular/add.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,8 @@ namespace eve
//!
//! // Semantic options
//! constexpr auto add[saturated](/*any of the above overloads*/) noexcept; // 4
//! 2. [The operation is performed conditionnaly](@ref conditional).
//!
//! }
//! @endcode
//!
Expand Down
6 changes: 6 additions & 0 deletions include/eve/module/core/regular/core.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -89,8 +89,11 @@
#include <eve/module/core/regular/inc.hpp>
#include <eve/module/core/regular/interleave.hpp>
#include <eve/module/core/regular/interleave_shuffle.hpp>
#include <eve/module/core/regular/is_bit_equal.hpp>
#include <eve/module/core/regular/is_denormal.hpp>
#include <eve/module/core/regular/is_equal.hpp>
#include <eve/module/core/regular/is_eqmz.hpp>
#include <eve/module/core/regular/is_eqpz.hpp>
#include <eve/module/core/regular/is_eqz.hpp>
#include <eve/module/core/regular/is_even.hpp>
#include <eve/module/core/regular/is_finite.hpp>
Expand All @@ -105,8 +108,11 @@
#include <eve/module/core/regular/is_lessgreater.hpp>
#include <eve/module/core/regular/is_lez.hpp>
#include <eve/module/core/regular/is_ltz.hpp>
#include <eve/module/core/regular/is_minf.hpp>
#include <eve/module/core/regular/is_nan.hpp>
#include <eve/module/core/regular/is_negative.hpp>
#include <eve/module/core/regular/is_nemz.hpp>
#include <eve/module/core/regular/is_nepz.hpp>
#include <eve/module/core/regular/is_ngez.hpp>
#include <eve/module/core/regular/is_ngtz.hpp>
#include <eve/module/core/regular/is_nlez.hpp>
Expand Down
67 changes: 67 additions & 0 deletions include/eve/module/core/regular/impl/simd/x86/is_denormal.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
//==================================================================================================
/*
EVE - Expressive Vector Engine
Copyright : EVE Project Contributors
SPDX-License-Identifier: BSL-1.0
*/
//==================================================================================================
#pragma once

#include <eve/concept/value.hpp>
#include <eve/detail/category.hpp>
#include <eve/detail/implementation.hpp>
#include <eve/module/core/constant/false.hpp>
#include <eve/detail/function/simd/x86/flags.hpp>

namespace eve::detail
{
template<floating_scalar_value T, typename N, callable_options O>
EVE_FORCEINLINE logical<wide<T, N>> is_denormal_(EVE_REQUIRES(avx512_),
O const &,
wide<T, N> const &a) noexcept
requires x86_abi<abi_t<T, N>>
{
using l_t = logical<wide<T, N>>;
constexpr auto c = categorize<wide<T, N>>();
constexpr auto f = to_integer(fpclass::denorm);

using s_t = typename l_t::storage_type;

if constexpr( c == category::float64x8 ) return s_t {_mm512_fpclass_pd_mask(a, f)};
else if constexpr( c == category::float64x4 ) return s_t {_mm256_fpclass_pd_mask(a, f)};
else if constexpr( c == category::float64x2 ) return s_t {_mm_fpclass_pd_mask(a, f)};
else if constexpr( c == category::float32x16 )return s_t {_mm512_fpclass_ps_mask(a, f)};
else if constexpr( c == category::float32x8 ) return s_t {_mm256_fpclass_ps_mask(a, f)};
else if constexpr( c == category::float32x4 ) return s_t {_mm_fpclass_ps_mask(a, f)};

}

// -----------------------------------------------------------------------------------------------
// masked implementation
template<conditional_expr C, floating_scalar_value T, typename N, callable_options O>
EVE_FORCEINLINE auto is_denormal_(EVE_REQUIRES(avx512_),
C const& cx,
O const& o,
wide<T, N> const& v) noexcept
requires x86_abi<abi_t<T, N>>
{
constexpr auto c = categorize<wide<T, N>>();

if constexpr( C::has_alternative || C::is_complete || abi_t<T, N>::is_wide_logical )
{
return is_denormal.behavior(cpu_{}, o, v, v);
}
else
{
auto m = expand_mask(cx, as<wide<T, N>> {}).storage().value;
constexpr auto f = to_integer(fpclass::denorm);

if constexpr( c == category::float32x16 ) return mask16 {_mm512_mask_fpclass_ps_mask(m, v, f)};
else if constexpr( c == category::float64x8 ) return mask8 {_mm512_mask_fpclass_pd_mask(m, v, f)};
else if constexpr( c == category::float32x8 ) return mask8 {_mm256_mask_fpclass_ps_mask(m, v, f)};
else if constexpr( c == category::float64x4 ) return mask8 {_mm256_mask_fpclass_pd_mask(m, v, f)};
else if constexpr( c == category::float32x4 ) return mask8 {_mm_mask_fpclass_ps_mask(m, v, f)};
else if constexpr( c == category::float64x2 ) return mask8 {_mm_mask_fpclass_pd_mask(m, v, f)};
}
}
}
66 changes: 66 additions & 0 deletions include/eve/module/core/regular/impl/simd/x86/is_eqmz.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
//==================================================================================================
/*
EVE - Expressive Vector Engine
Copyright : EVE Project Contributors
SPDX-License-Identifier: BSL-1.0
*/
//==================================================================================================
#pragma once

#include <eve/concept/value.hpp>
#include <eve/detail/category.hpp>
#include <eve/detail/implementation.hpp>
#include <eve/module/core/constant/false.hpp>

namespace eve::detail
{
template<floating_scalar_value T, typename N, callable_options O>
EVE_FORCEINLINE logical<wide<T, N>> is_eqmz_(EVE_REQUIRES(avx512_),
O const &,
wide<T, N> const &a) noexcept
requires x86_abi<abi_t<T, N>>
{
using l_t = logical<wide<T, N>>;
constexpr auto c = categorize<wide<T, N>>();
constexpr auto f = to_integer(fpclass::negzero);

using s_t = typename l_t::storage_type;

if constexpr( c == category::float64x8 ) return s_t {_mm512_fpclass_pd_mask(a, f)};
else if constexpr( c == category::float64x4 ) return s_t {_mm256_fpclass_pd_mask(a, f)};
else if constexpr( c == category::float64x2 ) return s_t {_mm_fpclass_pd_mask(a, f)};
else if constexpr( c == category::float32x16 )return s_t {_mm512_fpclass_ps_mask(a, f)};
else if constexpr( c == category::float32x8 ) return s_t {_mm256_fpclass_ps_mask(a, f)};
else if constexpr( c == category::float32x4 ) return s_t {_mm_fpclass_ps_mask(a, f)};

}

// -----------------------------------------------------------------------------------------------
// masked implementation
template<conditional_expr C, arithmetic_scalar_value T, typename N, callable_options O>
EVE_FORCEINLINE auto is_eqmz_(EVE_REQUIRES(avx512_),
C const& cx,
O const& o,
wide<T, N> const& v) noexcept
requires x86_abi<abi_t<T, N>>
{
constexpr auto c = categorize<wide<T, N>>();

if constexpr( C::has_alternative || C::is_complete || abi_t<T, N>::is_wide_logical )
{
return is_eqmz.behavior(cpu_{}, o, v, v);
}
else
{
auto m = expand_mask(cx, as<wide<T, N>> {}).storage().value;
constexpr auto f = to_integer(fpclass::negzero);

if constexpr( c == category::float32x16 ) return mask16 {_mm512_mask_fpclass_ps_mask(m, v, f)};
else if constexpr( c == category::float64x8 ) return mask8 {_mm512_mask_fpclass_pd_mask(m, v, f)};
else if constexpr( c == category::float32x8 ) return mask8 {_mm256_mask_fpclass_ps_mask(m, v, f)};
else if constexpr( c == category::float64x4 ) return mask8 {_mm256_mask_fpclass_pd_mask(m, v, f)};
else if constexpr( c == category::float32x4 ) return mask8 {_mm_mask_fpclass_ps_mask(m, v, f)};
else if constexpr( c == category::float64x2 ) return mask8 {_mm_mask_fpclass_pd_mask(m, v, f)};
}
}
}
66 changes: 66 additions & 0 deletions include/eve/module/core/regular/impl/simd/x86/is_eqpz.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
//==================================================================================================
/*
EVE - Expressive Vector Engine
Copyright : EVE Project Contributors
SPDX-License-Identifier: BSL-1.0
*/
//==================================================================================================
#pragma once

#include <eve/concept/value.hpp>
#include <eve/detail/category.hpp>
#include <eve/detail/implementation.hpp>
#include <eve/module/core/constant/false.hpp>

namespace eve::detail
{
template<floating_scalar_value T, typename N, callable_options O>
EVE_FORCEINLINE logical<wide<T, N>> is_eqpz_(EVE_REQUIRES(avx512_),
O const &,
wide<T, N> const &a) noexcept
requires x86_abi<abi_t<T, N>>
{
using l_t = logical<wide<T, N>>;
constexpr auto c = categorize<wide<T, N>>();
constexpr auto f = to_integer(fpclass::poszero);

using s_t = typename l_t::storage_type;

if constexpr( c == category::float64x8 ) return s_t {_mm512_fpclass_pd_mask(a, f)};
else if constexpr( c == category::float64x4 ) return s_t {_mm256_fpclass_pd_mask(a, f)};
else if constexpr( c == category::float64x2 ) return s_t {_mm_fpclass_pd_mask(a, f)};
else if constexpr( c == category::float32x16 )return s_t {_mm512_fpclass_ps_mask(a, f)};
else if constexpr( c == category::float32x8 ) return s_t {_mm256_fpclass_ps_mask(a, f)};
else if constexpr( c == category::float32x4 ) return s_t {_mm_fpclass_ps_mask(a, f)};

}

// -----------------------------------------------------------------------------------------------
// masked implementation
template<conditional_expr C, arithmetic_scalar_value T, typename N, callable_options O>
EVE_FORCEINLINE auto is_eqpz_(EVE_REQUIRES(avx512_),
C const& cx,
O const& o,
wide<T, N> const& v) noexcept
requires x86_abi<abi_t<T, N>>
{
constexpr auto c = categorize<wide<T, N>>();

if constexpr( C::has_alternative || C::is_complete || abi_t<T, N>::is_wide_logical )
{
return is_eqpz.behavior(cpu_{}, o, v, v);
}
else
{
auto m = expand_mask(cx, as<wide<T, N>> {}).storage().value;
constexpr auto f = to_integer(fpclass::poszero);

if constexpr( c == category::float32x16 ) return mask16 {_mm512_mask_fpclass_ps_mask(m, v, f)};
else if constexpr( c == category::float64x8 ) return mask8 {_mm512_mask_fpclass_pd_mask(m, v, f)};
else if constexpr( c == category::float32x8 ) return mask8 {_mm256_mask_fpclass_ps_mask(m, v, f)};
else if constexpr( c == category::float64x4 ) return mask8 {_mm256_mask_fpclass_pd_mask(m, v, f)};
else if constexpr( c == category::float32x4 ) return mask8 {_mm_mask_fpclass_ps_mask(m, v, f)};
else if constexpr( c == category::float64x2 ) return mask8 {_mm_mask_fpclass_pd_mask(m, v, f)};
}
}
}
66 changes: 66 additions & 0 deletions include/eve/module/core/regular/impl/simd/x86/is_eqz.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
//==================================================================================================
/*
EVE - Expressive Vector Engine
Copyright : EVE Project Contributors
SPDX-License-Identifier: BSL-1.0
*/
//==================================================================================================
#pragma once

#include <eve/detail/implementation.hpp>
#include <eve/module/core/regular/bit_cast.hpp>
#include <eve/traits/as_logical.hpp>

namespace eve::detail
{

template<floating_scalar_value T, typename N, callable_options O>
EVE_FORCEINLINE logical<wide<T, N>> is_eqz_(EVE_REQUIRES(avx512_),
O const &,
wide<T, N> const &a) noexcept
requires x86_abi<abi_t<T, N>>
{
using l_t = logical<wide<T, N>>;
constexpr auto c = categorize<wide<T, N>>();
constexpr auto f = fpclass::poszero | fpclass::negzero;

using s_t = typename l_t::storage_type;

if constexpr( c == category::float64x8 ) return s_t {_mm512_fpclass_pd_mask(a, f)};
else if constexpr( c == category::float64x4 ) return s_t {_mm256_fpclass_pd_mask(a, f)};
else if constexpr( c == category::float64x2 ) return s_t {_mm_fpclass_pd_mask(a, f)};
else if constexpr( c == category::float32x16) return s_t {_mm512_fpclass_ps_mask(a, f)};
else if constexpr( c == category::float32x8 ) return s_t {_mm256_fpclass_ps_mask(a, f)};
else if constexpr( c == category::float32x4 ) return s_t {_mm_fpclass_ps_mask(a, f)};
}


// -----------------------------------------------------------------------------------------------
// masked implementation
template<conditional_expr C, floating_scalar_value T, typename N, callable_options O>
EVE_FORCEINLINE auto is_eqz_(EVE_REQUIRES(avx512_),
C const& cx,
O const& o,
wide<T, N> const& v) noexcept
requires x86_abi<abi_t<T, N>>
{
constexpr auto c = categorize<wide<T, N>>();

if constexpr( C::has_alternative || C::is_complete || abi_t<T, N>::is_wide_logical )
{
return is_eqz.behavior(cpu_{}, o, v, v);
}
else
{
auto m = expand_mask(cx, as<wide<T, N>> {}).storage().value;
constexpr auto f = fpclass::poszero | fpclass::negzero;

if constexpr( c == category::float32x16 ) return mask16 {_mm512_mask_fpclass_ps_mask(m, v, f)};
else if constexpr( c == category::float64x8 ) return mask8 {_mm512_mask_fpclass_pd_mask(m, v, f)};
else if constexpr( c == category::float32x8 ) return mask8 {_mm256_mask_fpclass_ps_mask(m, v, f)};
else if constexpr( c == category::float64x4 ) return mask8 {_mm256_mask_fpclass_pd_mask(m, v, f)};
else if constexpr( c == category::float32x4 ) return mask8 {_mm_mask_fpclass_ps_mask(m, v, f)};
else if constexpr( c == category::float64x2 ) return mask8 {_mm_mask_fpclass_pd_mask(m, v, f)};
}
}
}
36 changes: 36 additions & 0 deletions include/eve/module/core/regular/impl/simd/x86/is_finite.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/concept/value.hpp>
#include <eve/detail/category.hpp>
#include <eve/detail/implementation.hpp>
#include <eve/module/core/constant/false.hpp>

namespace eve::detail
{
template<floating_scalar_value T, typename N, callable_options O>
EVE_FORCEINLINE logical<wide<T, N>> is_finite_(EVE_REQUIRES(avx512_),
O const &,
wide<T, N> const &a) noexcept
requires x86_abi<abi_t<T, N>>
{
using l_t = logical<wide<T, N>>;
constexpr auto c = categorize<wide<T, N>>();
constexpr auto f = fpclass::qnan | fpclass::snan | fpclass::neginf | fpclass::posinf;

using s_t = typename l_t::storage_type;

if constexpr( c == category::float64x8 ) return ~s_t {_mm512_fpclass_pd_mask(a, f)};
else if constexpr( c == category::float64x4 ) return ~s_t {_mm256_fpclass_pd_mask(a, f)};
else if constexpr( c == category::float64x2 ) return ~s_t {_mm_fpclass_pd_mask(a, f)};
else if constexpr( c == category::float32x16) return ~s_t {_mm512_fpclass_ps_mask(a, f)};
else if constexpr( c == category::float32x8 ) return ~s_t {_mm256_fpclass_ps_mask(a, f)};
else if constexpr( c == category::float32x4 ) return ~s_t {_mm_fpclass_ps_mask(a, f)};
}
}
36 changes: 36 additions & 0 deletions include/eve/module/core/regular/impl/simd/x86/is_gez.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/detail/implementation.hpp>
#include <eve/module/core/regular/bit_cast.hpp>
#include <eve/traits/as_logical.hpp>

namespace eve::detail
{

template<floating_scalar_value T, typename N, callable_options O>
EVE_FORCEINLINE logical<wide<T, N>> is_gez_(EVE_REQUIRES(avx512_),
O const &,
wide<T, N> const &a) noexcept
requires x86_abi<abi_t<T, N>>
{
using l_t = logical<wide<T, N>>;
constexpr auto c = categorize<wide<T, N>>();
constexpr auto f = fpclass::neg | fpclass::qnan| fpclass::neginf | fpclass::snan;

using s_t = typename l_t::storage_type;

if constexpr( c == category::float64x8 ) return ~s_t {_mm512_fpclass_pd_mask(a, f)};
else if constexpr( c == category::float64x4 ) return ~s_t {_mm256_fpclass_pd_mask(a, f)};
else if constexpr( c == category::float64x2 ) return ~s_t {_mm_fpclass_pd_mask(a, f)};
else if constexpr( c == category::float32x16) return ~s_t {_mm512_fpclass_ps_mask(a, f)};
else if constexpr( c == category::float32x8 ) return ~s_t {_mm256_fpclass_ps_mask(a, f)};
else if constexpr( c == category::float32x4 ) return ~s_t {_mm_fpclass_ps_mask(a, f)};
}
}
Loading