diff --git a/include/eve/detail/function/simd/x86/flags.hpp b/include/eve/detail/function/simd/x86/flags.hpp index 69b3caa551..5fff3d38af 100644 --- a/include/eve/detail/function/simd/x86/flags.hpp +++ b/include/eve/detail/function/simd/x86/flags.hpp @@ -28,6 +28,11 @@ namespace eve::detail return static_cast(a) | static_cast(b); } + EVE_FORCEINLINE constexpr std::int32_t to_integer(fpclass a) noexcept + { + return static_cast(a); + } + enum class range_ctrl { min = 0b00 , max = 0b01 , absolute_min= 0b10 diff --git a/include/eve/module/core/regular/add.hpp b/include/eve/module/core/regular/add.hpp index f3962c94fe..e2e5d0b477 100644 --- a/include/eve/module/core/regular/add.hpp +++ b/include/eve/module/core/regular/add.hpp @@ -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 //! diff --git a/include/eve/module/core/regular/core.hpp b/include/eve/module/core/regular/core.hpp index 2f842d38f4..92ec7a9ca2 100644 --- a/include/eve/module/core/regular/core.hpp +++ b/include/eve/module/core/regular/core.hpp @@ -89,8 +89,11 @@ #include #include #include +#include #include #include +#include +#include #include #include #include @@ -105,8 +108,11 @@ #include #include #include +#include #include #include +#include +#include #include #include #include diff --git a/include/eve/module/core/regular/impl/simd/x86/is_denormal.hpp b/include/eve/module/core/regular/impl/simd/x86/is_denormal.hpp new file mode 100644 index 0000000000..a521bf858b --- /dev/null +++ b/include/eve/module/core/regular/impl/simd/x86/is_denormal.hpp @@ -0,0 +1,67 @@ +//================================================================================================== +/* + EVE - Expressive Vector Engine + Copyright : EVE Project Contributors + SPDX-License-Identifier: BSL-1.0 +*/ +//================================================================================================== +#pragma once + +#include +#include +#include +#include +#include + +namespace eve::detail +{ + template + EVE_FORCEINLINE logical> is_denormal_(EVE_REQUIRES(avx512_), + O const &, + wide const &a) noexcept + requires x86_abi> + { + using l_t = logical>; + constexpr auto c = categorize>(); + 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 + EVE_FORCEINLINE auto is_denormal_(EVE_REQUIRES(avx512_), + C const& cx, + O const& o, + wide const& v) noexcept + requires x86_abi> + { + constexpr auto c = categorize>(); + + if constexpr( C::has_alternative || C::is_complete || abi_t::is_wide_logical ) + { + return is_denormal.behavior(cpu_{}, o, v, v); + } + else + { + auto m = expand_mask(cx, as> {}).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)}; + } + } +} diff --git a/include/eve/module/core/regular/impl/simd/x86/is_eqmz.hpp b/include/eve/module/core/regular/impl/simd/x86/is_eqmz.hpp new file mode 100644 index 0000000000..655c41902f --- /dev/null +++ b/include/eve/module/core/regular/impl/simd/x86/is_eqmz.hpp @@ -0,0 +1,66 @@ +//================================================================================================== +/* + EVE - Expressive Vector Engine + Copyright : EVE Project Contributors + SPDX-License-Identifier: BSL-1.0 +*/ +//================================================================================================== +#pragma once + +#include +#include +#include +#include + +namespace eve::detail +{ + template + EVE_FORCEINLINE logical> is_eqmz_(EVE_REQUIRES(avx512_), + O const &, + wide const &a) noexcept + requires x86_abi> + { + using l_t = logical>; + constexpr auto c = categorize>(); + 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 + EVE_FORCEINLINE auto is_eqmz_(EVE_REQUIRES(avx512_), + C const& cx, + O const& o, + wide const& v) noexcept + requires x86_abi> + { + constexpr auto c = categorize>(); + + if constexpr( C::has_alternative || C::is_complete || abi_t::is_wide_logical ) + { + return is_eqmz.behavior(cpu_{}, o, v, v); + } + else + { + auto m = expand_mask(cx, as> {}).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)}; + } + } +} diff --git a/include/eve/module/core/regular/impl/simd/x86/is_eqpz.hpp b/include/eve/module/core/regular/impl/simd/x86/is_eqpz.hpp new file mode 100644 index 0000000000..92bd20d7b9 --- /dev/null +++ b/include/eve/module/core/regular/impl/simd/x86/is_eqpz.hpp @@ -0,0 +1,66 @@ +//================================================================================================== +/* + EVE - Expressive Vector Engine + Copyright : EVE Project Contributors + SPDX-License-Identifier: BSL-1.0 +*/ +//================================================================================================== +#pragma once + +#include +#include +#include +#include + +namespace eve::detail +{ + template + EVE_FORCEINLINE logical> is_eqpz_(EVE_REQUIRES(avx512_), + O const &, + wide const &a) noexcept + requires x86_abi> + { + using l_t = logical>; + constexpr auto c = categorize>(); + 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 + EVE_FORCEINLINE auto is_eqpz_(EVE_REQUIRES(avx512_), + C const& cx, + O const& o, + wide const& v) noexcept + requires x86_abi> + { + constexpr auto c = categorize>(); + + if constexpr( C::has_alternative || C::is_complete || abi_t::is_wide_logical ) + { + return is_eqpz.behavior(cpu_{}, o, v, v); + } + else + { + auto m = expand_mask(cx, as> {}).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)}; + } + } +} diff --git a/include/eve/module/core/regular/impl/simd/x86/is_eqz.hpp b/include/eve/module/core/regular/impl/simd/x86/is_eqz.hpp new file mode 100644 index 0000000000..236c0b4e9d --- /dev/null +++ b/include/eve/module/core/regular/impl/simd/x86/is_eqz.hpp @@ -0,0 +1,66 @@ +//================================================================================================== +/* + EVE - Expressive Vector Engine + Copyright : EVE Project Contributors + SPDX-License-Identifier: BSL-1.0 +*/ +//================================================================================================== +#pragma once + +#include +#include +#include + +namespace eve::detail +{ + + template + EVE_FORCEINLINE logical> is_eqz_(EVE_REQUIRES(avx512_), + O const &, + wide const &a) noexcept + requires x86_abi> + { + using l_t = logical>; + constexpr auto c = categorize>(); + 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 + EVE_FORCEINLINE auto is_eqz_(EVE_REQUIRES(avx512_), + C const& cx, + O const& o, + wide const& v) noexcept + requires x86_abi> + { + constexpr auto c = categorize>(); + + if constexpr( C::has_alternative || C::is_complete || abi_t::is_wide_logical ) + { + return is_eqz.behavior(cpu_{}, o, v, v); + } + else + { + auto m = expand_mask(cx, as> {}).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)}; + } + } +} diff --git a/include/eve/module/core/regular/impl/simd/x86/is_finite.hpp b/include/eve/module/core/regular/impl/simd/x86/is_finite.hpp new file mode 100644 index 0000000000..d171961b2c --- /dev/null +++ b/include/eve/module/core/regular/impl/simd/x86/is_finite.hpp @@ -0,0 +1,36 @@ +//================================================================================================== +/* + EVE - Expressive Vector Engine + Copyright : EVE Project Contributors + SPDX-License-Identifier: BSL-1.0 +*/ +//================================================================================================== +#pragma once + +#include +#include +#include +#include + +namespace eve::detail +{ + template + EVE_FORCEINLINE logical> is_finite_(EVE_REQUIRES(avx512_), + O const &, + wide const &a) noexcept + requires x86_abi> + { + using l_t = logical>; + constexpr auto c = categorize>(); + 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)}; + } +} diff --git a/include/eve/module/core/regular/impl/simd/x86/is_gez.hpp b/include/eve/module/core/regular/impl/simd/x86/is_gez.hpp new file mode 100644 index 0000000000..8585c1e464 --- /dev/null +++ b/include/eve/module/core/regular/impl/simd/x86/is_gez.hpp @@ -0,0 +1,36 @@ +//================================================================================================== +/* + EVE - Expressive Vector Engine + Copyright : EVE Project Contributors + SPDX-License-Identifier: BSL-1.0 +*/ +//================================================================================================== +#pragma once + +#include +#include +#include + +namespace eve::detail +{ + + template + EVE_FORCEINLINE logical> is_gez_(EVE_REQUIRES(avx512_), + O const &, + wide const &a) noexcept + requires x86_abi> + { + using l_t = logical>; + constexpr auto c = categorize>(); + 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)}; + } +} diff --git a/include/eve/module/core/regular/impl/simd/x86/is_gtz.hpp b/include/eve/module/core/regular/impl/simd/x86/is_gtz.hpp new file mode 100644 index 0000000000..254128b674 --- /dev/null +++ b/include/eve/module/core/regular/impl/simd/x86/is_gtz.hpp @@ -0,0 +1,35 @@ +//================================================================================================== +/* + EVE - Expressive Vector Engine + Copyright : EVE Project Contributors + SPDX-License-Identifier: BSL-1.0 +*/ +//================================================================================================== +#pragma once + +#include +#include +#include + +namespace eve::detail +{ + template + EVE_FORCEINLINE logical> is_gtz_(EVE_REQUIRES(avx512_), + O const &, + wide const &a) noexcept + requires x86_abi> + { + using l_t = logical>; + constexpr auto c = categorize>(); + constexpr auto f = fpclass::neg | fpclass::negzero | fpclass::poszero | fpclass::neginf | fpclass::qnan | 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)}; + } +} diff --git a/include/eve/module/core/regular/impl/simd/x86/is_infinite.hpp b/include/eve/module/core/regular/impl/simd/x86/is_infinite.hpp new file mode 100644 index 0000000000..8f55bdb7d9 --- /dev/null +++ b/include/eve/module/core/regular/impl/simd/x86/is_infinite.hpp @@ -0,0 +1,66 @@ +//================================================================================================== +/* + EVE - Expressive Vector Engine + Copyright : EVE Project Contributors + SPDX-License-Identifier: BSL-1.0 +*/ +//================================================================================================== +#pragma once + +#include +#include +#include +#include + +namespace eve::detail +{ + template + EVE_FORCEINLINE logical> is_infinite_(EVE_REQUIRES(avx512_), + O const &, + wide const &a) noexcept + requires x86_abi> + { + using l_t = logical>; + constexpr auto c = categorize>(); + constexpr auto f = 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)}; + + } + +// ----------------------------------------------------------------------------------------------- +// masked implementation + template + EVE_FORCEINLINE auto is_infinite_(EVE_REQUIRES(avx512_), + C const& cx, + O const& o, + wide const& v) noexcept + requires x86_abi> + { + constexpr auto c = categorize>(); + + if constexpr( C::has_alternative || C::is_complete || abi_t::is_wide_logical ) + { + return is_infinite.behavior(cpu_{}, o, v, v); + } + else + { + auto m = expand_mask(cx, as> {}).storage().value; + constexpr auto f = fpclass::neginf|fpclass::posinf; + + 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)}; + } + } +} diff --git a/include/eve/module/core/regular/impl/simd/x86/is_lez.hpp b/include/eve/module/core/regular/impl/simd/x86/is_lez.hpp new file mode 100644 index 0000000000..fb6781ecd4 --- /dev/null +++ b/include/eve/module/core/regular/impl/simd/x86/is_lez.hpp @@ -0,0 +1,66 @@ +//================================================================================================== +/* + EVE - Expressive Vector Engine + Copyright : EVE Project Contributors + SPDX-License-Identifier: BSL-1.0 +*/ +//================================================================================================== +#pragma once + +#include +#include +#include + +namespace eve::detail +{ + template + EVE_FORCEINLINE logical> is_lez_(EVE_REQUIRES(avx512_), + O const &, + wide const &a) noexcept + requires x86_abi> + { + using l_t = logical>; + constexpr auto c = categorize>(); + constexpr auto f = fpclass::neg | fpclass::negzero | fpclass::poszero | fpclass::neginf; + + 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 + EVE_FORCEINLINE auto is_lez_(EVE_REQUIRES(avx512_), + C const& cx, + O const& o, + wide const& v) noexcept + requires x86_abi> + { + constexpr auto c = categorize>(); + + if constexpr( C::has_alternative || C::is_complete || abi_t::is_wide_logical ) + { + return is_lez.behavior(cpu_{}, o, v, v); + } + else + { + auto m = expand_mask(cx, as> {}).storage().value; + constexpr auto f = fpclass::neg | fpclass::negzero | fpclass::poszero | fpclass::neginf; + + + 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)}; + } + } +} diff --git a/include/eve/module/core/regular/impl/simd/x86/is_ltz.hpp b/include/eve/module/core/regular/impl/simd/x86/is_ltz.hpp index acbf7a0f21..be89d49e34 100644 --- a/include/eve/module/core/regular/impl/simd/x86/is_ltz.hpp +++ b/include/eve/module/core/regular/impl/simd/x86/is_ltz.hpp @@ -23,4 +23,54 @@ namespace eve::detail constexpr auto shift = 8 * sizeof(T) - 1; return bit_cast(v >> shift, as {}); } + + template + EVE_FORCEINLINE logical> is_ltz_(EVE_REQUIRES(avx512_), + O const &, + wide const &a) noexcept + requires x86_abi> + { + using l_t = logical>; + constexpr auto c = categorize>(); + constexpr auto f = fpclass::neg | fpclass::neginf; + + 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 + EVE_FORCEINLINE auto is_ltz_(EVE_REQUIRES(avx512_), + C const& cx, + O const& o, + wide const& v) noexcept + requires x86_abi> + { + constexpr auto c = categorize>(); + + if constexpr( C::has_alternative || C::is_complete || abi_t::is_wide_logical ) + { + return is_ltz.behavior(cpu_{}, o, v, v); + } + else + { + auto m = expand_mask(cx, as> {}).storage().value; + constexpr auto f = fpclass::neg | fpclass::neginf; + + 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)}; + } + } } diff --git a/include/eve/module/core/regular/impl/simd/x86/is_minf.hpp b/include/eve/module/core/regular/impl/simd/x86/is_minf.hpp new file mode 100644 index 0000000000..c5160b74bd --- /dev/null +++ b/include/eve/module/core/regular/impl/simd/x86/is_minf.hpp @@ -0,0 +1,66 @@ +//================================================================================================== +/* + EVE - Expressive Vector Engine + Copyright : EVE Project Contributors + SPDX-License-Identifier: BSL-1.0 +*/ +//================================================================================================== +#pragma once + +#include +#include +#include +#include + +namespace eve::detail +{ + template + EVE_FORCEINLINE logical> is_minf_(EVE_REQUIRES(avx512_), + O const &, + wide const &a) noexcept + requires x86_abi> + { + using l_t = logical>; + constexpr auto c = categorize>(); + constexpr auto f = fpclass::neginf; + + 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 + EVE_FORCEINLINE auto is_minf_(EVE_REQUIRES(avx512_), + C const& cx, + O const& o, + wide const& v) noexcept + requires x86_abi> + { + constexpr auto c = categorize>(); + + if constexpr( C::has_alternative || C::is_complete || abi_t::is_wide_logical ) + { + return is_minf.behavior(cpu_{}, o, v, v); + } + else + { + auto m = expand_mask(cx, as> {}).storage().value; + constexpr auto f = fpclass::neginf; + + 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)}; + } + } +} diff --git a/include/eve/module/core/regular/impl/simd/x86/is_nan.hpp b/include/eve/module/core/regular/impl/simd/x86/is_nan.hpp new file mode 100644 index 0000000000..bbd005144c --- /dev/null +++ b/include/eve/module/core/regular/impl/simd/x86/is_nan.hpp @@ -0,0 +1,74 @@ +//================================================================================================== +/* + EVE - Expressive Vector Engine + Copyright : EVE Project Contributors + SPDX-License-Identifier: BSL-1.0 +*/ +//================================================================================================== +#pragma once + +#include +#include +#include +#include + +namespace eve::detail +{ + template + EVE_FORCEINLINE logical> is_nan_(EVE_REQUIRES(sse2_), + O const &, + wide const &a) noexcept + requires x86_abi> + { + using l_t = logical>; + constexpr auto c = categorize>(); + constexpr auto m = _CMP_UNORD_Q; + + if constexpr( match(c, category::integer_) ) return false_(eve::as()); + else if constexpr( current_api >= eve::avx512 ) + { + using s_t = typename l_t::storage_type; + + if constexpr( c == category::float64x8 ) return s_t {_mm512_cmp_pd_mask(a, a, m)}; + else if constexpr( c == category::float64x4 ) return s_t {_mm256_cmp_pd_mask(a, a, m)}; + else if constexpr( c == category::float64x2 ) return s_t {_mm_cmp_pd_mask(a, a, m)}; + else if constexpr( c == category::float32x16 ) return s_t {_mm512_cmp_ps_mask(a, a, m)}; + else if constexpr( c == category::float32x8 ) return s_t {_mm256_cmp_ps_mask(a, a, m)}; + else if constexpr( c == category::float32x4 ) return s_t {_mm_cmp_ps_mask(a, a, m)}; + } + else if constexpr( c == category::float64x4 ) return l_t(_mm256_cmp_pd(a, a, m)); + else if constexpr( c == category::float64x2 ) return l_t(_mm_cmpunord_pd(a, a)); + else if constexpr( c == category::float32x8 ) return l_t(_mm256_cmp_ps(a, a, m)); + else if constexpr( c == category::float32x4 ) return l_t(_mm_cmpunord_ps(a, a)); + } + +// ----------------------------------------------------------------------------------------------- +// masked implementation + template + EVE_FORCEINLINE auto is_nan_(EVE_REQUIRES(avx512_), + C const& cx, + O const& o, + wide const& v) noexcept + -> decltype(is_not_less_equal(v, v)) + requires x86_abi> + { + constexpr auto c = categorize>(); + + if constexpr( C::has_alternative || C::is_complete || abi_t::is_wide_logical ) + { + return is_nan.behavior(cpu_{}, o, v, v); + } + else + { + auto m = expand_mask(cx, as> {}).storage().value; + constexpr auto f = to_integer(cmp_flt::unord_q); + + if constexpr( c == category::float32x16 ) return mask16 {_mm512_mask_cmp_ps_mask(m, v, v, f)}; + else if constexpr( c == category::float64x8 ) return mask8 {_mm512_mask_cmp_pd_mask(m, v, v, f)}; + else if constexpr( c == category::float32x8 ) return mask8 {_mm256_mask_cmp_ps_mask(m, v, v, f)}; + else if constexpr( c == category::float64x4 ) return mask8 {_mm256_mask_cmp_pd_mask(m, v, v, f)}; + else if constexpr( c == category::float32x4 ) return mask8 {_mm_mask_cmp_ps_mask(m, v, v, f)}; + else if constexpr( c == category::float64x2 ) return mask8 {_mm_mask_cmp_pd_mask(m, v, v, f)}; + } + } +} diff --git a/include/eve/module/core/regular/impl/simd/x86/is_negative.hpp b/include/eve/module/core/regular/impl/simd/x86/is_negative.hpp new file mode 100644 index 0000000000..9eba938f0a --- /dev/null +++ b/include/eve/module/core/regular/impl/simd/x86/is_negative.hpp @@ -0,0 +1,70 @@ +//================================================================================================== +/* + EVE - Expressive Vector Engine + Copyright : EVE Project Contributors + SPDX-License-Identifier: BSL-1.0 +*/ +//================================================================================================== +#pragma once + +#include +#include +#include +#include + +namespace eve::detail +{ + template + EVE_FORCEINLINE logical> is_negative_(EVE_REQUIRES(avx512_), + O const & o, + wide const &a) noexcept + requires x86_abi> + { + if constexpr(O::contains(pedantic)) + { + using l_t = logical>; + constexpr auto c = categorize>(); + constexpr auto f = fpclass::neg|fpclass::negzero|fpclass::neginf; + + 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)}; + } + else + return is_negative.behavior(cpu_{}, o, a); + } + +// ----------------------------------------------------------------------------------------------- +// masked implementation + template + EVE_FORCEINLINE auto is_negative_(EVE_REQUIRES(avx512_), + C const& cx, + O const& o, + wide const& v) noexcept + requires x86_abi> + { + constexpr auto c = categorize>(); + + if constexpr( C::has_alternative || C::is_complete || abi_t::is_wide_logical || !O::contains(pedantic)) + { + return is_negative.behavior(cpu_{}, o, v); + } + else + { + auto m = expand_mask(cx, as> {}).storage().value; + constexpr auto f = fpclass::neg|fpclass::negzero|fpclass::neginf; + + 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)}; + } + } +} diff --git a/include/eve/module/core/regular/impl/simd/x86/is_nemz.hpp b/include/eve/module/core/regular/impl/simd/x86/is_nemz.hpp new file mode 100644 index 0000000000..7ded91da6e --- /dev/null +++ b/include/eve/module/core/regular/impl/simd/x86/is_nemz.hpp @@ -0,0 +1,36 @@ +//================================================================================================== +/* + EVE - Expressive Vector Engine + Copyright : EVE Project Contributors + SPDX-License-Identifier: BSL-1.0 +*/ +//================================================================================================== +#pragma once + +#include +#include +#include +#include + +namespace eve::detail +{ + template + EVE_FORCEINLINE logical> is_nemz_(EVE_REQUIRES(avx512_), + O const &, + wide const &a) noexcept + requires x86_abi> + { + using l_t = logical>; + constexpr auto c = categorize>(); + constexpr auto f = 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)}; + } +} diff --git a/include/eve/module/core/regular/impl/simd/x86/is_nepz.hpp b/include/eve/module/core/regular/impl/simd/x86/is_nepz.hpp new file mode 100644 index 0000000000..f026a50067 --- /dev/null +++ b/include/eve/module/core/regular/impl/simd/x86/is_nepz.hpp @@ -0,0 +1,36 @@ +//================================================================================================== +/* + EVE - Expressive Vector Engine + Copyright : EVE Project Contributors + SPDX-License-Identifier: BSL-1.0 +*/ +//================================================================================================== +#pragma once + +#include +#include +#include +#include + +namespace eve::detail +{ + template + EVE_FORCEINLINE logical> is_nepz_(EVE_REQUIRES(avx512_), + O const &, + wide const &a) noexcept + requires x86_abi> + { + using l_t = logical>; + constexpr auto c = categorize>(); + constexpr auto f = 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)}; + } +} diff --git a/include/eve/module/core/regular/impl/simd/x86/is_nez.hpp b/include/eve/module/core/regular/impl/simd/x86/is_nez.hpp new file mode 100644 index 0000000000..4023580555 --- /dev/null +++ b/include/eve/module/core/regular/impl/simd/x86/is_nez.hpp @@ -0,0 +1,36 @@ +//================================================================================================== +/* + EVE - Expressive Vector Engine + Copyright : EVE Project Contributors + SPDX-License-Identifier: BSL-1.0 +*/ +//================================================================================================== +#pragma once + +#include +#include +#include +#include + +namespace eve::detail +{ + template + EVE_FORCEINLINE logical> is_nez_(EVE_REQUIRES(avx512_), + O const &, + wide const &a) noexcept + requires x86_abi> + { + using l_t = logical>; + constexpr auto c = categorize>(); + 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)}; + } +} diff --git a/include/eve/module/core/regular/impl/simd/x86/is_ngez.hpp b/include/eve/module/core/regular/impl/simd/x86/is_ngez.hpp new file mode 100644 index 0000000000..b86bc53433 --- /dev/null +++ b/include/eve/module/core/regular/impl/simd/x86/is_ngez.hpp @@ -0,0 +1,65 @@ +//================================================================================================== +/* + EVE - Expressive Vector Engine + Copyright : EVE Project Contributors + SPDX-License-Identifier: BSL-1.0 +*/ +//================================================================================================== +#pragma once + +#include +#include +#include + +namespace eve::detail +{ + template + EVE_FORCEINLINE logical> is_ngez_(EVE_REQUIRES(avx512_), + O const &, + wide const &a) noexcept + requires x86_abi> + { + using l_t = logical>; + constexpr auto c = categorize>(); + constexpr auto f = fpclass::neg | fpclass::neginf | fpclass::qnan | 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)}; + } + + +// ----------------------------------------------------------------------------------------------- +// masked implementation + template + EVE_FORCEINLINE auto is_ngez_(EVE_REQUIRES(avx512_), + C const& cx, + O const& o, + wide const& v) noexcept + requires x86_abi> + { + constexpr auto c = categorize>(); + + if constexpr( C::has_alternative || C::is_complete || abi_t::is_wide_logical ) + { + return is_ngez.behavior(cpu_{}, o, v, v); + } + else + { + auto m = expand_mask(cx, as> {}).storage().value; + constexpr auto f = fpclass::neg | fpclass::neginf | fpclass::qnan | fpclass::snan; + + 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)}; + } + } +} diff --git a/include/eve/module/core/regular/impl/simd/x86/is_ngtz.hpp b/include/eve/module/core/regular/impl/simd/x86/is_ngtz.hpp new file mode 100644 index 0000000000..49e756d416 --- /dev/null +++ b/include/eve/module/core/regular/impl/simd/x86/is_ngtz.hpp @@ -0,0 +1,65 @@ +//================================================================================================== +/* + EVE - Expressive Vector Engine + Copyright : EVE Project Contributors + SPDX-License-Identifier: BSL-1.0 +*/ +//================================================================================================== +#pragma once + +#include +#include +#include + +namespace eve::detail +{ + template + EVE_FORCEINLINE logical> is_ngtz_(EVE_REQUIRES(avx512_), + O const &, + wide const &a) noexcept + requires x86_abi> + { + using l_t = logical>; + constexpr auto c = categorize>(); + constexpr auto f = fpclass::neg | fpclass::neginf | fpclass::qnan | fpclass::snan | 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 + EVE_FORCEINLINE auto is_ngtz_(EVE_REQUIRES(avx512_), + C const& cx, + O const& o, + wide const& v) noexcept + requires x86_abi> + { + constexpr auto c = categorize>(); + + if constexpr( C::has_alternative || C::is_complete || abi_t::is_wide_logical ) + { + return is_ngtz.behavior(cpu_{}, o, v, v); + } + else + { + auto m = expand_mask(cx, as> {}).storage().value; + constexpr auto f = fpclass::neg | fpclass::neginf | fpclass::qnan | fpclass::snan | 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)}; + } + } +} diff --git a/include/eve/module/core/regular/is_bit_equal.hpp b/include/eve/module/core/regular/is_bit_equal.hpp new file mode 100644 index 0000000000..4929f4d874 --- /dev/null +++ b/include/eve/module/core/regular/is_bit_equal.hpp @@ -0,0 +1,107 @@ +//================================================================================================== +/* + EVE - Expressive Vector Engine + Copyright : EVE Project Contributors + SPDX-License-Identifier: BSL-1.0 +*/ +//================================================================================================== +#pragma once + + +#include +#include +#include +#include + + +namespace eve +{ + template + struct is_bit_equal_t : strict_elementwise_callable + { + template using b_t = bit_value_t; + template using ui_t = as_integer_t, unsigned>; + + template + constexpr EVE_FORCEINLINE auto operator()(T a, U b) const + -> decltype(is_equal(bit_cast(b_t(a), as>()), bit_cast(b_t(b), as>()))) + { + return EVE_DISPATCH_CALL(a, b); + } + + template + constexpr EVE_FORCEINLINE auto operator()(logical a, logical b) const + -> decltype(is_equal(a, b)) + { + return EVE_DISPATCH_CALL(a, b); + } + + EVE_CALLABLE_OBJECT(is_bit_equal_t, is_bit_equal_); + }; + +//================================================================================================ +//! @addtogroup core_predicates +//! @{ +//! @var is_bit_equal +//! @brief `elementwise callable` returning a logical true if and only if the element bits +//! are all equal. +//! +//! @groupheader{Header file} +//! +//! @code +//! #include +//! @endcode +//! +//! @groupheader{Callable Signatures} +//! +//! @code +//! namespace eve +//! { +//! // Regular overload +//! constexpr auto is_bit_equal(value auto x, value auto y) noexcept; // 1 +//! +//! // Lanes masking +//! constexpr auto is_bit_equal[conditional_expr auto c](value auto x, value auto y) noexcept; // 2 +//! constexpr auto is_bit_equal[logical_value auto m](value auto x, value auto y) noexcept; // 2 +//! } +//! @endcode +//! +//! **Parameters** +//! +//! * `x`, `y`: [arguments](@ref eve::value). +//! * `c`: [Conditional expression](@ref conditional_expr) masking the operation. +//! * `m`: [Logical value](@ref logical) masking the operation. +//! +//! **Return value** +//! +//! 1. Returns the logical value containing the [elementwise](@ref glossary_elementwise) bit equality +//! test result between `x` and `y`. +//! 2. [The operation is performed conditionnaly](@ref conditional). +//! +//! @groupheader{Example} +//! @godbolt{doc/core/is_bit_equal.cpp} +//================================================================================================ + inline constexpr auto is_bit_equal = functor; +//================================================================================================ +//! @} +//================================================================================================ + + namespace detail + { + template + EVE_FORCEINLINE constexpr auto + is_bit_equal_(EVE_REQUIRES(cpu_),O const &, T const& a, U const& b) noexcept + { + using b_t = bit_value_t; + using ui_t = as_integer_t; + return is_equal(bit_cast(b_t(a), as()), bit_cast(b_t(b), as())); + } + + template + EVE_FORCEINLINE constexpr auto + is_bit_equal_(EVE_REQUIRES(cpu_),O const &, logical const& a, logical const& b) noexcept + { + return is_equal(a, b); + } + } +} diff --git a/include/eve/module/core/regular/is_denormal.hpp b/include/eve/module/core/regular/is_denormal.hpp index 70e03d4956..d2fd16c368 100644 --- a/include/eve/module/core/regular/is_denormal.hpp +++ b/include/eve/module/core/regular/is_denormal.hpp @@ -94,3 +94,7 @@ namespace eve } } } + +#if defined(EVE_INCLUDE_X86_HEADER) +# include +#endif diff --git a/include/eve/module/core/regular/is_eqmz.hpp b/include/eve/module/core/regular/is_eqmz.hpp new file mode 100644 index 0000000000..34005d39c6 --- /dev/null +++ b/include/eve/module/core/regular/is_eqmz.hpp @@ -0,0 +1,94 @@ +//================================================================================================== +/* + EVE - Expressive Vector Engine + Copyright : EVE Project Contributors + SPDX-License-Identifier: BSL-1.0 +*/ +//================================================================================================== +#pragma once +#include +#include +#include +#include +#include +#include +#include + +namespace eve +{ + template + struct is_eqmz_t : elementwise_callable + { + template + EVE_FORCEINLINE constexpr as_logical_t + operator()(T t) const noexcept + { + return EVE_DISPATCH_CALL(t); + } + + EVE_CALLABLE_OBJECT(is_eqmz_t, is_eqmz_); + }; + +//================================================================================================ +//! @addtogroup core_predicates +//! @{ +//! @var is_eqmz +//! @brief `elementwise callable` returning a logical true if and only if the element +//! value is a floating zero with sign bit set. +//! +//! @groupheader{Header file} +//! +//! @code +//! #include +//! @endcode +//! +//! @groupheader{Callable Signatures} +//! +//! @code +//! namespace eve +//! { +//! // Regular overload +//! constexpr auto is_eqmz(value auto x) noexcept; // 1 +//! +//! // Lanes masking +//! constexpr auto is_eqmz[conditional_expr auto c](value auto x) noexcept; // 2 +//! constexpr auto is_eqmz[logical_value auto m](value auto x) noexcept; // 2 +//! } +//! @endcode +//! +//! **Parameters** +//! +//! * `x`: [floating argument](@ref eve::floating_value). +//! * `c`: [Conditional expression](@ref conditional_expr) masking the operation. +//! * `m`: [Logical value](@ref logical) masking the operation. +//! +//! **Return value** +//! +//! 1. returns [elementwise](@ref glossary_elementwise) true if and only +//! if the element value is a floating zero with sign bit set (`mzero`). +//! 2. [The operation is performed conditionnaly](@ref conditional). +//! +//! @note This function is not defined for integral typed entries to avoid misuse. +//! +//! @groupheader{Example} +//! @godbolt{doc/core/is_eqmz.cpp} +//================================================================================================ + inline constexpr auto is_eqmz = functor; +//================================================================================================ +//! @} +//================================================================================================ + + namespace detail + { + template + EVE_FORCEINLINE constexpr as_logical_t + is_eqmz_(EVE_REQUIRES(cpu_), O const &, T const& a) noexcept + { + return logical_andnot(is_eqz(a), is_eqpz(a)); + } + } +} + +#if defined(EVE_INCLUDE_X86_HEADER) +# include +#endif diff --git a/include/eve/module/core/regular/is_eqpz.hpp b/include/eve/module/core/regular/is_eqpz.hpp new file mode 100644 index 0000000000..ed6cbe843c --- /dev/null +++ b/include/eve/module/core/regular/is_eqpz.hpp @@ -0,0 +1,93 @@ +//================================================================================================== +/* + EVE - Expressive Vector Engine + Copyright : EVE Project Contributors + SPDX-License-Identifier: BSL-1.0 +*/ +//================================================================================================== +#pragma once +#include +#include +#include +#include +#include +#include +#include +#include + +namespace eve +{ + template + struct is_eqpz_t : elementwise_callable + { + template + EVE_FORCEINLINE constexpr as_logical_t + operator()(T t) const noexcept + { + return EVE_DISPATCH_CALL(t); + } + + EVE_CALLABLE_OBJECT(is_eqpz_t, is_eqpz_); + }; + +//================================================================================================ +//! @addtogroup core_predicates +//! @{ +//! @var is_eqpz +//! @brief `elementwise callable` returning a logical true if and only if the element value +//! is a floating zero with signbit unset. +//! +//! @groupheader{Header file} +//! +//! @code +//! #include +//! @endcode +//! +//! @groupheader{Callable Signatures} +//! +//! @code +//! namespace eve +//! { +//! // Regular overload +//! constexpr auto is_eqpz(value auto x) noexcept; // 1 +//! +//! // Lanes masking +//! constexpr auto is_eqpz[conditional_expr auto c](value auto x) noexcept; // 2 +//! constexpr auto is_eqpz[logical_value auto m](value auto x) noexcept; // 2 +//! } +//! @endcode +//! +//! **Parameters** +//! +//! * `x`: [floating argument](@ref eve::floting_value). +//! * `c`: [Conditional expression](@ref conditional_expr) masking the operation. +//! * `m`: [Logical value](@ref logical) masking the operation. +//! +//! **Return value** +//! +//! 1. returns [elementwise](@ref glossary_elementwise) true if and only +//! if the element value is zero with sign bit unset. +//! 2. [The operation is performed conditionnaly](@ref conditional). +//! +//! @groupheader{Example} +//! @godbolt{doc/core/is_eqpz.cpp} +//================================================================================================ + inline constexpr auto is_eqpz = functor; +//================================================================================================ +//! @} +//================================================================================================ + + namespace detail + { + template + EVE_FORCEINLINE constexpr as_logical_t + is_eqpz_(EVE_REQUIRES(cpu_), O const &, T const& a) noexcept + { + return bit_cast(is_eqz(bit_cast(a, as>())),as>()) ; + } + } +} + +#if defined(EVE_INCLUDE_X86_HEADER) +# include +#endif diff --git a/include/eve/module/core/regular/is_eqz.hpp b/include/eve/module/core/regular/is_eqz.hpp index a8a493feb9..9e51a191cd 100644 --- a/include/eve/module/core/regular/is_eqz.hpp +++ b/include/eve/module/core/regular/is_eqz.hpp @@ -87,3 +87,7 @@ namespace eve } } } + +#if defined(EVE_INCLUDE_X86_HEADER) +# include +#endif diff --git a/include/eve/module/core/regular/is_finite.hpp b/include/eve/module/core/regular/is_finite.hpp index c61b76fc7d..2aa203affe 100644 --- a/include/eve/module/core/regular/is_finite.hpp +++ b/include/eve/module/core/regular/is_finite.hpp @@ -88,3 +88,7 @@ namespace eve } } } + +#if defined(EVE_INCLUDE_X86_HEADER) +# include +#endif diff --git a/include/eve/module/core/regular/is_gez.hpp b/include/eve/module/core/regular/is_gez.hpp index 9bf27c332e..ec4feaa68e 100644 --- a/include/eve/module/core/regular/is_gez.hpp +++ b/include/eve/module/core/regular/is_gez.hpp @@ -86,3 +86,7 @@ namespace eve } } } + +#if defined(EVE_INCLUDE_X86_HEADER) +# include +#endif diff --git a/include/eve/module/core/regular/is_gtz.hpp b/include/eve/module/core/regular/is_gtz.hpp index 1ea518e863..8212ffe20a 100644 --- a/include/eve/module/core/regular/is_gtz.hpp +++ b/include/eve/module/core/regular/is_gtz.hpp @@ -88,3 +88,7 @@ namespace eve } } } + +#if defined(EVE_INCLUDE_X86_HEADER) +# include +#endif diff --git a/include/eve/module/core/regular/is_infinite.hpp b/include/eve/module/core/regular/is_infinite.hpp index bdfcbf45fa..ffc99a73f9 100644 --- a/include/eve/module/core/regular/is_infinite.hpp +++ b/include/eve/module/core/regular/is_infinite.hpp @@ -88,3 +88,7 @@ namespace eve } } } + +#if defined(EVE_INCLUDE_X86_HEADER) +# include +#endif diff --git a/include/eve/module/core/regular/is_minf.hpp b/include/eve/module/core/regular/is_minf.hpp new file mode 100644 index 0000000000..8bb57af6c4 --- /dev/null +++ b/include/eve/module/core/regular/is_minf.hpp @@ -0,0 +1,94 @@ +//================================================================================================== +/* + EVE - Expressive Vector Engine + Copyright : EVE Project Contributors + SPDX-License-Identifier: BSL-1.0 +*/ +//================================================================================================== +#pragma once + +#include +#include +#include +#include +#include +#include + +namespace eve +{ + template + struct is_minf_t : elementwise_callable + { + template + EVE_FORCEINLINE constexpr as_logical_t + operator()(T t) const noexcept + { + return EVE_DISPATCH_CALL(t); + } + + EVE_CALLABLE_OBJECT(is_minf_t, is_minf_); + }; + +//================================================================================================ +//! @addtogroup core_predicates +//! @{ +//! @var is_minf +//! @brief `elementwise callable` returning a logical true if and only if the element is a negative infinite value +//! +//! @groupheader{Header file} +//! +//! @code +//! #include +//! @endcode +//! +//! @groupheader{Callable Signatures} +//! +//! @code +//! namespace eve +//! { +//! // Regular overload +//! constexpr auto is_minf(value auto x) noexcept; // 1 +//! +//! // Lanes masking +//! constexpr auto is_minf[conditional_expr auto c](value auto x) noexcept; // 2 +//! constexpr auto is_minf[logical_value auto m](value auto x) noexcept; // 2 +//! } +//! @endcode +//! +//! **Parameters** +//! +//! * `x`: [argument](@ref eve::value). +//! * `c`: [Conditional expression](@ref conditional_expr) masking the operation. +//! * `m`: [Logical value](@ref logical) masking the operation. +//! +//! **Return value** +//! +//! 1. For floating entries returns true if x is equals to `eve::minf(as(x))`, +//! and is always false for integral types. +//! 2. [The operation is performed conditionnaly](@ref conditional). +//! +//! @groupheader{Example} +//! @godbolt{doc/core/is_minf.cpp} +//================================================================================================ + inline constexpr auto is_minf = functor; +//================================================================================================ +//! @} +//================================================================================================ + + namespace detail + { + template + EVE_FORCEINLINE constexpr as_logical_t + is_minf_(EVE_REQUIRES(cpu_), O const &, T const& a) noexcept + { + if constexpr( integral_value ) + return false_(eve::as(a)); + else + return (a == minf(eve::as(a))); + } + } +} + +#if defined(EVE_INCLUDE_X86_HEADER) +# include +#endif diff --git a/include/eve/module/core/regular/is_negative.hpp b/include/eve/module/core/regular/is_negative.hpp index 7d1678b806..8fe2273118 100644 --- a/include/eve/module/core/regular/is_negative.hpp +++ b/include/eve/module/core/regular/is_negative.hpp @@ -10,12 +10,13 @@ #include #include #include +#include #include namespace eve { template - struct is_negative_t : elementwise_callable + struct is_negative_t : elementwise_callable { template EVE_FORCEINLINE constexpr as_logical_t @@ -51,6 +52,9 @@ namespace eve //! // Lanes masking //! constexpr auto is_negative[conditional_expr auto c](value auto x) noexcept; // 2 //! constexpr auto is_negative[logical_value auto m](value auto x) noexcept; // 2 +//! +//! // Semantic options +//! constexpr auto is_negative[pedantic](value auto x)noexcept; // 3 //! } //! @endcode //! @@ -63,8 +67,10 @@ namespace eve //! **Return value** //! //! 1. For signed types The call `is_negative(x)` returns true -//! if and only if the bit of sign (most significant bit) is set. +//! if and only if the bit of sign (most significant bit) is set. Of course the result on a NaN input +//! is generally out of control. //! 2. [The operation is performed conditionnaly](@ref conditional). +//! 3. with this option a NaN input always return false. //! //! @note //! this function coincides with `is_ltz` on [integral real values](@ref eve::value), @@ -88,6 +94,10 @@ namespace eve { if constexpr( unsigned_value ) return false_(eve::as(v)); + else if constexpr(O::contains(pedantic)) + { + return is_negative(v) && is_not_nan(v); + } else { if constexpr( signed_integral_value ) @@ -108,3 +118,7 @@ namespace eve } } } + +#if defined(EVE_INCLUDE_X86_HEADER) +# include +#endif diff --git a/include/eve/module/core/regular/is_nemz.hpp b/include/eve/module/core/regular/is_nemz.hpp new file mode 100644 index 0000000000..2295ecd85b --- /dev/null +++ b/include/eve/module/core/regular/is_nemz.hpp @@ -0,0 +1,92 @@ +/* + EVE - Expressive Vector Engine + Copyright : EVE Project Contributors + SPDX-License-Identifier: BSL-1.0 +*/ +//================================================================================================== +#pragma once + +#include +#include +#include +#include +#include +#include + +namespace eve +{ + template + struct is_nemz_t : elementwise_callable + { + template + EVE_FORCEINLINE constexpr as_logical_t + operator()(T t) const noexcept + { + return EVE_DISPATCH_CALL(t); + } + + EVE_CALLABLE_OBJECT(is_nemz_t, is_nemz_); + }; + +//================================================================================================ +//! @addtogroup core_predicates +//! @{ +//! @var is_nemz +//! @brief `elementwise callable` returning a logical true if and only if a "negative" zero. +//! +//! @groupheader{Header file} +//! +//! @code +//! #include +//! @endcode +//! +//! @groupheader{Callable Signatures} +//! +//! @code +//! namespace eve +//! { +//! // Regular overload +//! constexpr auto is_nemz(floating_value auto x) noexcept; // 1 +//! +//! // Lanes masking +//! constexpr auto is_nemz[conditional_expr auto c](floating_value auto x) noexcept; // 2 +//! constexpr auto is_nemz[logical_value auto m](floating_value auto x) noexcept; // 2 +//! } +//! @endcode +//! +//! **Parameters** +//! +//! * `x`: [floating argument](@ref eve::floating_value). +//! * `c`: [Conditional expression](@ref conditional_expr) masking the operation. +//! * `m`: [Logical value](@ref logical) masking the operation. +//! +//! **Return value** +//! +//! 1. `is_nemz(x)` is semantically equivalent to bitwise equality to `mzero(as(x))`. +//! 2. [The operation is performed conditionnaly](@ref conditional). +//! +//! @groupheader{Example} +//! @godbolt{doc/core/is_nemz.cpp} +//================================================================================================ + inline constexpr auto is_nemz = functor; +//================================================================================================ +//! @} +//================================================================================================ + + namespace detail + { + template + EVE_FORCEINLINE constexpr as_logical_t + is_nemz_(EVE_REQUIRES(cpu_), O const &, T const& a) noexcept + { + if constexpr(integral_value) + return false_(as()); + else + return logical_or(is_positive(a), is_ltz(a)); + } + } +} + +#if defined(EVE_INCLUDE_X86_HEADER) +# include +#endif diff --git a/include/eve/module/core/regular/is_nepz.hpp b/include/eve/module/core/regular/is_nepz.hpp new file mode 100644 index 0000000000..2ebd570c2b --- /dev/null +++ b/include/eve/module/core/regular/is_nepz.hpp @@ -0,0 +1,87 @@ +/* + EVE - Expressive Vector Engine + Copyright : EVE Project Contributors + SPDX-License-Identifier: BSL-1.0 +*/ +//================================================================================================== +#pragma once + +#include +#include +#include +#include + +namespace eve +{ + template + struct is_nepz_t : elementwise_callable + { + template + EVE_FORCEINLINE constexpr as_logical_t + operator()(T t) const noexcept + { + return EVE_DISPATCH_CALL(t); + } + + EVE_CALLABLE_OBJECT(is_nepz_t, is_nepz_); + }; + +//================================================================================================ +//! @addtogroup core_predicates +//! @{ +//! @var is_nepz +//! @brief `elementwise callable` returning a logical true if and only if "positive" zero. +//! +//! @groupheader{Header file} +//! +//! @code +//! #include +//! @endcode +//! +//! @groupheader{Callable Signatures} +//! +//! @code +//! namespace eve +//! { +//! // Regular overload +//! constexpr auto is_nepz(value auto x) noexcept; // 1 +//! +//! // Lanes masking +//! constexpr auto is_nepz[conditional_expr auto c](value auto x) noexcept; // 2 +//! constexpr auto is_nepz[logical_value auto m](value auto x) noexcept; // 2 +//! } +//! @endcode +//! +//! **Parameters** +//! +//! * `x`: [floating argument](@ref eve::value). +//! * `c`: [Conditional expression](@ref conditional_expr) masking the operation. +//! * `m`: [Logical value](@ref logical) masking the operation. +//! +//! **Return value** +//! +//! 1. `is_nepz(x)` is true if and only if all bits of the representation of `x` are zero. +//! 2. [The operation is performed conditionnaly](@ref conditional). +//! +//! @groupheader{Example} +//! @godbolt{doc/core/is_nepz.cpp} +//================================================================================================ + inline constexpr auto is_nepz = functor; +//================================================================================================ +//! @} +//================================================================================================ + + namespace detail + { + template + EVE_FORCEINLINE constexpr as_logical_t + is_nepz_(EVE_REQUIRES(cpu_), O const &, T const& a) noexcept + { + return !is_eqpz(a); + } + } +} + +#if defined(EVE_INCLUDE_X86_HEADER) +# include +#endif diff --git a/include/eve/module/core/regular/is_nez.hpp b/include/eve/module/core/regular/is_nez.hpp index 2a30322179..ba0cba566c 100644 --- a/include/eve/module/core/regular/is_nez.hpp +++ b/include/eve/module/core/regular/is_nez.hpp @@ -81,3 +81,7 @@ namespace eve } } } + +#if defined(EVE_INCLUDE_X86_HEADER) +# include +#endif diff --git a/include/eve/module/core/regular/is_ngez.hpp b/include/eve/module/core/regular/is_ngez.hpp index 2fe56a1391..920bee5c03 100644 --- a/include/eve/module/core/regular/is_ngez.hpp +++ b/include/eve/module/core/regular/is_ngez.hpp @@ -95,3 +95,7 @@ namespace eve } } } + +#if defined(EVE_INCLUDE_X86_HEADER) +# include +#endif diff --git a/test/doc/core/is_bit_equal.cpp b/test/doc/core/is_bit_equal.cpp new file mode 100644 index 0000000000..523f622169 --- /dev/null +++ b/test/doc/core/is_bit_equal.cpp @@ -0,0 +1,28 @@ +// revision 0 +#include +#include + +int main() +{ + eve::wide wf0{0.0, 1.0, 2.0, 3.0, -1.0, -2.0, -3.0, -0.0}; + eve::wide wf1{0.0, -4.0, 1.0, -1.0, 2.0, -2.0, 3.0, 0.0}; + eve::wide wi0{0, 1, 2, 3, -1, -2, -3, -4}; + eve::wide wi1{0, -4, 1, 3, 2, -2, 3, -3}; + eve::wide wu0{0u, 1u, 2u, 3u, 4u, 5u, 6u, 7u}; + eve::wide wu1{7u, 6u, 5u, 4u, 4u, 2u, 1u, 0u}; + + std::cout << "<- wf0 = " << wf0 << "\n"; + std::cout << "<- wf1 = " << wf1 << "\n"; + std::cout << "<- wi0 = " << wi0 << "\n"; + std::cout << "<- wi1 = " << wi1 << "\n"; + std::cout << "<- wu0 = " << wu0 << "\n"; + std::cout << "<- wu1 = " << wu1 << "\n"; + + std::cout << "-> is_bit_equal(wf0, wf1) = " << eve::is_bit_equal(wf0, wf1) << "\n"; + std::cout << "-> is_bit_equal[ignore_last(2)](wf0, wf1) = " << eve::is_bit_equal[eve::ignore_last(2)](wf0, wf1) << "\n"; + std::cout << "-> is_bit_equal[wf0 != 0](wf0, wf1) = " << eve::is_bit_equal[wf0 != 0](wf0, wf1) << "\n"; + std::cout << "-> is_bit_equal[wu0 != 0](wu0, wu1) = " << eve::is_bit_equal[wu0 != 0](wu0, wu1) << "\n"; + std::cout << "-> is_bit_equal(wi0, wi1) = " << eve::is_bit_equal(wi0, wi1) << "\n"; + std::cout << "-> is_bit_equal[ignore_last(2)](wi0, wi1) = " << eve::is_bit_equal[eve::ignore_last(2)](wi0, wi1) << "\n"; + std::cout << "-> is_bit_equal[wi0 != 0](wi0, wi1) = " << eve::is_bit_equal[wi0 != 0](wi0, wi1) << "\n"; +} diff --git a/test/doc/core/is_eqmz.cpp b/test/doc/core/is_eqmz.cpp new file mode 100644 index 0000000000..cd18556d50 --- /dev/null +++ b/test/doc/core/is_eqmz.cpp @@ -0,0 +1,16 @@ +// revision 0 +#include +#include + +int main() +{ + eve::wide wf0{0.0, 1.0, 2.0, 3.0, -1.0, -2.0, -3.0, -0.0}; + eve::wide wi0{0, 1, 2, 3, -1, -2, -3, -4}; + eve::wide wu0{0u, 1u, 2u, 3u, 4u, 5u, 6u, 7u}; + + std::cout << "<- wf0 = " << wf0 << "\n"; + + std::cout << "-> is_eqmz(wf0) = " << eve::is_eqmz(wf0) << "\n"; + std::cout << "-> is_eqmz[ignore_last(2)](wf0) = " << eve::is_eqmz[eve::ignore_last(2)](wf0) << "\n"; + std::cout << "-> is_eqmz[wf0 != 0](wf0) = " << eve::is_eqmz[wf0 != 0](wf0) << "\n"; +} diff --git a/test/doc/core/is_eqpz.cpp b/test/doc/core/is_eqpz.cpp new file mode 100644 index 0000000000..375fd52c1a --- /dev/null +++ b/test/doc/core/is_eqpz.cpp @@ -0,0 +1,16 @@ +// revision 0 +#include +#include + +int main() +{ + eve::wide wf0{0.0, 1.0, 2.0, 3.0, -1.0, -2.0, -3.0, -0.0}; + eve::wide wi0{0, 1, 2, 3, -1, -2, -3, -4}; + eve::wide wu0{0u, 1u, 2u, 3u, 4u, 5u, 6u, 7u}; + + std::cout << "<- wf0 = " << wf0 << "\n"; + + std::cout << "-> is_eqpz(wf0) = " << eve::is_eqpz(wf0) << "\n"; + std::cout << "-> is_eqpz[ignore_last(2)](wf0) = " << eve::is_eqpz[eve::ignore_last(2)](wf0) << "\n"; + std::cout << "-> is_eqpz[wf0 != 0](wf0) = " << eve::is_eqpz[wf0 != 0](wf0) << "\n"; +} diff --git a/test/doc/core/is_eqz.cpp b/test/doc/core/is_eqz.cpp index 18a53a58b1..0a49354526 100644 --- a/test/doc/core/is_eqz.cpp +++ b/test/doc/core/is_eqz.cpp @@ -4,14 +4,14 @@ int main() { - eve::wide wf0{0.0, 1.0, 2.0, 3.0, -1.0, -2.0, -3.0, -4.0}; + eve::wide wf0{0.0, 1.0, 2.0, 3.0, -1.0, -2.0, -3.0, -0.0}; eve::wide wi0{0, 1, 2, 3, -1, -2, -3, -4}; eve::wide wu0{0u, 1u, 2u, 3u, 4u, 5u, 6u, 7u}; std::cout << "<- wf0 = " << wf0 << "\n"; std::cout << "<- wi0 = " << wi0 << "\n"; std::cout << "<- wu0 = " << wu0 << "\n"; - + std::cout << "-> is_eqz(wf0) = " << eve::is_eqz(wf0) << "\n"; std::cout << "-> is_eqz[ignore_last(2)](wf0) = " << eve::is_eqz[eve::ignore_last(2)](wf0) << "\n"; std::cout << "-> is_eqz[wf0 != 0](wf0) = " << eve::is_eqz[wf0 != 0](wf0) << "\n"; diff --git a/test/doc/core/is_gez.cpp b/test/doc/core/is_gez.cpp index e120b48944..33290ddc5c 100644 --- a/test/doc/core/is_gez.cpp +++ b/test/doc/core/is_gez.cpp @@ -4,14 +4,14 @@ int main() { - eve::wide wf0{0.0, 1.0, 2.0, 3.0, -1.0, -2.0, -3.0, -4.0}; + eve::wide wf0{0.0, 1.0, 2.0, 3.0, -1.0, -2.0, -3.0, eve::minf(eve::as())}; eve::wide wi0{0, 1, 2, 3, -1, -2, -3, -4}; eve::wide wu0{0u, 1u, 2u, 3u, 4u, 5u, 6u, 7u}; std::cout << "<- wf0 = " << wf0 << "\n"; std::cout << "<- wi0 = " << wi0 << "\n"; std::cout << "<- wu0 = " << wu0 << "\n"; - + std::cout << "-> is_gez(wf0) = " << eve::is_gez(wf0) << "\n"; std::cout << "-> is_gez[ignore_last(2)](wf0) = " << eve::is_gez[eve::ignore_last(2)](wf0) << "\n"; std::cout << "-> is_gez[wf0 != 0](wf0) = " << eve::is_gez[wf0 != 0](wf0) << "\n"; diff --git a/test/doc/core/is_minf.cpp b/test/doc/core/is_minf.cpp new file mode 100644 index 0000000000..494819b573 --- /dev/null +++ b/test/doc/core/is_minf.cpp @@ -0,0 +1,24 @@ +// revision 0 +#include +#include + +int main() +{ + eve::wide wf0{0.0, 1.0, 2.0, eve::minf(eve::as()), -1.0, -2.0, eve::inf(eve::as()), -0.0}; + eve::wide wi0{0, 1, 2, 3, -1, -2, -3, -4}; + eve::wide wu0{0u, 1u, 2u, 3u, 4u, 5u, 6u, 7u}; + + std::cout << "<- wf0 = " << wf0 << "\n"; + std::cout << "<- wi0 = " << wi0 << "\n"; + std::cout << "<- wu0 = " << wu0 << "\n"; + + std::cout << "-> is_minf(wf0) = " << eve::is_minf(wf0) << "\n"; + std::cout << "-> is_minf[ignore_last(2)](wf0) = " << eve::is_minf[eve::ignore_last(2)](wf0) << "\n"; + std::cout << "-> is_minf[wf0 != 0](wf0) = " << eve::is_minf[wf0 != 0](wf0) << "\n"; + std::cout << "-> is_minf(wu0) = " << eve::is_minf(wu0) << "\n"; + std::cout << "-> is_minf[ignore_last(2)](wu0) = " << eve::is_minf[eve::ignore_last(2)](wu0) << "\n"; + std::cout << "-> is_minf[wu0 != 0](wu0) = " << eve::is_minf[wu0 != 0](wu0) << "\n"; + std::cout << "-> is_minf(wi0) = " << eve::is_minf(wi0) << "\n"; + std::cout << "-> is_minf[ignore_last(2)](wi0) = " << eve::is_minf[eve::ignore_last(2)](wi0) << "\n"; + std::cout << "-> is_minf[wi0 != 0](wi0) = " << eve::is_minf[wi0 != 0](wi0) << "\n"; +} diff --git a/test/doc/core/is_negative.cpp b/test/doc/core/is_negative.cpp index 4578c88ac1..5ecc620f03 100644 --- a/test/doc/core/is_negative.cpp +++ b/test/doc/core/is_negative.cpp @@ -4,15 +4,17 @@ int main() { - eve::wide wf0{0.0, 1.0, 2.0, 3.0, -1.0, -2.0, -3.0, -4.0}; + auto nan = eve::nan(eve::as()); + eve::wide wf0{0.0, 1.0, 2.0, 3.0, -1.0, -2.0, -nan, nan}; eve::wide wi0{0, 1, 2, 3, -1, -2, -3, -4}; eve::wide wu0{0u, 1u, 2u, 3u, 4u, 5u, 6u, 7u}; std::cout << "<- wf0 = " << wf0 << "\n"; std::cout << "<- wi0 = " << wi0 << "\n"; std::cout << "<- wu0 = " << wu0 << "\n"; - + std::cout << "-> is_negative(wf0) = " << eve::is_negative(wf0) << "\n"; + std::cout << "-> is_negative[pedantic](wf0) = " << eve::is_negative[eve::pedantic](wf0) << "\n"; std::cout << "-> is_negative[ignore_last(2)](wf0) = " << eve::is_negative[eve::ignore_last(2)](wf0) << "\n"; std::cout << "-> is_negative[wf0 != 0](wf0) = " << eve::is_negative[wf0 != 0](wf0) << "\n"; std::cout << "-> is_negative(wu0) = " << eve::is_negative(wu0) << "\n"; diff --git a/test/doc/core/is_nemz.cpp b/test/doc/core/is_nemz.cpp new file mode 100644 index 0000000000..63f59e455d --- /dev/null +++ b/test/doc/core/is_nemz.cpp @@ -0,0 +1,16 @@ +// revision 0 +#include +#include + +int main() +{ + eve::wide wf0{0.0, 1.0, 2.0, 3.0, -1.0, -2.0, -3.0, -0.0}; + eve::wide wi0{0, 1, 2, 3, -1, -2, -3, -4}; + eve::wide wu0{0u, 1u, 2u, 3u, 4u, 5u, 6u, 7u}; + + std::cout << "<- wf0 = " << wf0 << "\n"; + + std::cout << "-> is_nemz(wf0) = " << eve::is_nemz(wf0) << "\n"; + std::cout << "-> is_nemz[ignore_last(2)](wf0) = " << eve::is_nemz[eve::ignore_last(2)](wf0) << "\n"; + std::cout << "-> is_nemz[wf0 != 0](wf0) = " << eve::is_nemz[wf0 != 0](wf0) << "\n"; +} diff --git a/test/doc/core/is_nepz.cpp b/test/doc/core/is_nepz.cpp new file mode 100644 index 0000000000..a179118226 --- /dev/null +++ b/test/doc/core/is_nepz.cpp @@ -0,0 +1,16 @@ +// revision 0 +#include +#include + +int main() +{ + eve::wide wf0{0.0, 1.0, 2.0, 3.0, -1.0, -2.0, -3.0, -0.0}; + eve::wide wi0{0, 1, 2, 3, -1, -2, -3, -4}; + eve::wide wu0{0u, 1u, 2u, 3u, 4u, 5u, 6u, 7u}; + + std::cout << "<- wf0 = " << wf0 << "\n"; + + std::cout << "-> is_nepz(wf0) = " << eve::is_nepz(wf0) << "\n"; + std::cout << "-> is_nepz[ignore_last(2)](wf0) = " << eve::is_nepz[eve::ignore_last(2)](wf0) << "\n"; + std::cout << "-> is_nepz[wf0 != 0](wf0) = " << eve::is_nepz[wf0 != 0](wf0) << "\n"; +} diff --git a/test/doc/math/pow.cpp b/test/doc/math/pow.cpp index de0f6bec5b..70b247ca5a 100644 --- a/test/doc/math/pow.cpp +++ b/test/doc/math/pow.cpp @@ -1,18 +1,19 @@ // revision 1 #include #include +#include int main() { - eve::wide pf = {2.0f, 3.0f, -4.0f, 2.0f, 2.0f, + eve::wide qf = {0.0f, 3.0f, -4.0f, 2.0f, 2.0f, eve::inf(eve::as()), eve::minf(eve::as()), eve::nan(eve::as())}; - eve::wide qf = {4.0f, 1.0f, -1.0f, 0.5f, 0.0f, 2.0f, -3.0f, 2.5f}; + eve::wide pf = {4.0f, 1.0f, -1.0f, 0.5f, 0.0f, 0.0f, -0.0f, 2.5f}; - std::cout << "<- pf = " << pf << "\n"; - std::cout << "<- qf = " << qf << "\n"; + std::cout << "<- pf = " << pf << "\n"; + std::cout << "<- qf = " << qf << "\n"; - std::cout << "-> pow(pf, qf) = " << eve::pow(pf, qf) << "\n"; - std::cout << "-> pow[ignore_last(2)](pf, qf)= " << eve::pow[eve::ignore_last(2)](pf, qf) << "\n"; - std::cout << "-> pow[qf > 0.0f](pf, qf) = " << eve::pow[qf > 0.0f](pf, qf) << "\n"; - std::cout << "-> pow[raw](pf, qf) = " << eve::pow[eve::raw](pf, qf) << "\n"; + std::cout << "-> pow(pf, qf) = " << eve::pow(pf, qf) << "\n"; + std::cout << "-> pow[ignore_last(2)](pf, qf)= " << eve::pow[eve::ignore_last(2)](pf, qf) << "\n"; + std::cout << "-> pow[qf > 0.0f](pf, qf) = " << eve::pow[qf > 0.0f](pf, qf) << "\n"; + std::cout << "-> pow[raw](pf, qf) = " << eve::pow[eve::raw](pf, qf) << "\n"; } diff --git a/test/random/module/core/is_eqmz.cpp b/test/random/module/core/is_eqmz.cpp new file mode 100644 index 0000000000..6b384bff4a --- /dev/null +++ b/test/random/module/core/is_eqmz.cpp @@ -0,0 +1,21 @@ +//================================================================================================== +/* + EVE - Expressive Vector Engine + Copyright : EVE Project Contributors + SPDX-License-Identifier: BSL-1.0 +*/ +//================================================================================================== +#include +#include "producers.hpp" + +#include + +TTS_CASE_TPL("Random check for eve::is_eqmz", eve::test::simd::ieee_reals) +(tts::type) +{ + using e_t = eve::element_type_t; + auto vmin = eve::valmin(eve::as()); + auto vmax = eve::valmax(eve::as()); + auto std_is_eqmz = [](auto e) -> eve::logical{ return e == 0 && eve::is_negative(e); }; + EVE_ULP_RANGE_CHECK( T, eve::uniform_prng(vmin, vmax), std_is_eqmz, eve::is_eqmz ); + }; diff --git a/test/random/module/core/is_eqpz.cpp b/test/random/module/core/is_eqpz.cpp new file mode 100644 index 0000000000..55f9a47d27 --- /dev/null +++ b/test/random/module/core/is_eqpz.cpp @@ -0,0 +1,21 @@ +//================================================================================================== +/* + EVE - Expressive Vector Engine + Copyright : EVE Project Contributors + SPDX-License-Identifier: BSL-1.0 +*/ +//================================================================================================== +#include +#include "producers.hpp" + +#include + +TTS_CASE_TPL("Random check for eve::is_eqz", eve::test::simd::ieee_reals) +(tts::type) +{ + using e_t = eve::element_type_t; + auto vmin = eve::valmin(eve::as()); + auto vmax = eve::valmax(eve::as()); + auto std_is_eqz = [](auto e) -> eve::logical{ return e == 0 && eve::is_positive(e); }; + EVE_ULP_RANGE_CHECK( T, eve::uniform_prng(vmin, vmax), std_is_eqz, eve::is_eqz ); + }; diff --git a/test/random/module/core/is_finite.cpp b/test/random/module/core/is_finite.cpp new file mode 100644 index 0000000000..aadb7f26b1 --- /dev/null +++ b/test/random/module/core/is_finite.cpp @@ -0,0 +1,25 @@ +//================================================================================================== +/* + EVE - Expressive Vector Engine + Copyright : EVE Project Contributors + SPDX-License-Identifier: BSL-1.0 +*/ +//================================================================================================== +#include +#include "producers.hpp" + +#include + +TTS_CASE_TPL("Random check for eve::is_finite", eve::test::simd::all_types) +(tts::type) +{ + using e_t = eve::element_type_t; + auto vmin = eve::valmin(eve::as()); + auto vmax = eve::valmax(eve::as()); + auto std_is_finite = [](auto e) -> eve::logical { + if constexpr(eve::floating_value) + return std::isfinite(e); + else return eve::true_(eve::as(e)); + }; + EVE_ULP_RANGE_CHECK( T, eve::uniform_prng(vmin, vmax), std_is_finite, eve::is_finite ); +}; diff --git a/test/random/module/core/is_gtz.cpp b/test/random/module/core/is_gtz.cpp index d186197e07..f33fb96f9b 100644 --- a/test/random/module/core/is_gtz.cpp +++ b/test/random/module/core/is_gtz.cpp @@ -10,12 +10,12 @@ #include -TTS_CASE_TPL("Random check for eve::is_ltz", eve::test::simd::all_types) +TTS_CASE_TPL("Random check for eve::is_gtz", eve::test::simd::all_types) (tts::type) { using e_t = eve::element_type_t; auto vmin = eve::valmin(eve::as()); auto vmax = eve::valmax(eve::as()); - auto std_is_ltz = [](auto e) -> eve::logical{ return e < 0; }; - EVE_ULP_RANGE_CHECK( T, eve::uniform_prng(vmin, vmax), std_is_ltz, eve::is_ltz ); + auto std_is_gtz = [](auto e) -> eve::logical{ return e > 0; }; + EVE_ULP_RANGE_CHECK( T, eve::uniform_prng(vmin, vmax), std_is_gtz, eve::is_gtz ); }; diff --git a/test/random/module/core/is_minf.cpp b/test/random/module/core/is_minf.cpp new file mode 100644 index 0000000000..fd941e5cb9 --- /dev/null +++ b/test/random/module/core/is_minf.cpp @@ -0,0 +1,21 @@ +//================================================================================================== +/* + EVE - Expressive Vector Engine + Copyright : EVE Project Contributors + SPDX-License-Identifier: BSL-1.0 +*/ +//================================================================================================== +#include +#include "producers.hpp" + +#include + +TTS_CASE_TPL("Random check for eve::is_minf", eve::test::simd::all_types) +(tts::type) +{ + using e_t = eve::element_type_t; + auto vmin = eve::valmin(eve::as()); + auto vmax = eve::valmax(eve::as()); + auto std_is_minf = [](auto e) -> eve::logical{ return e < 0 && e-e != 0; }; + EVE_ULP_RANGE_CHECK( T, eve::uniform_prng(vmin, vmax), std_is_minf, eve::is_minf ); + }; diff --git a/test/random/module/core/is_nemz.cpp b/test/random/module/core/is_nemz.cpp new file mode 100644 index 0000000000..1aca799914 --- /dev/null +++ b/test/random/module/core/is_nemz.cpp @@ -0,0 +1,21 @@ +//================================================================================================== +/* + EVE - Expressive Vector Engine + Copyright : EVE Project Contributors + SPDX-License-Identifier: BSL-1.0 +*/ +//================================================================================================== +#include +#include "producers.hpp" + +#include + +TTS_CASE_TPL("Random check for eve::is_nemz", eve::test::simd::ieee_reals) +(tts::type) +{ + using e_t = eve::element_type_t; + auto vmin = eve::valmin(eve::as()); + auto vmax = eve::valmax(eve::as()); + auto std_is_nemz = [](auto e) -> eve::logical{ return !eve::is_eqmz(e) || eve::is_nan(e); }; + EVE_ULP_RANGE_CHECK( T, eve::uniform_prng(vmin, vmax), std_is_nemz, eve::is_nemz ); + }; diff --git a/test/random/module/core/is_nepz.cpp b/test/random/module/core/is_nepz.cpp new file mode 100644 index 0000000000..1358013e87 --- /dev/null +++ b/test/random/module/core/is_nepz.cpp @@ -0,0 +1,21 @@ +//================================================================================================== +/* + EVE - Expressive Vector Engine + Copyright : EVE Project Contributors + SPDX-License-Identifier: BSL-1.0 +*/ +//================================================================================================== +#include +#include "producers.hpp" + +#include + +TTS_CASE_TPL("Random check for eve::is_nepz", eve::test::simd::ieee_reals) +(tts::type) +{ + using e_t = eve::element_type_t; + auto vmin = eve::valmin(eve::as()); + auto vmax = eve::valmax(eve::as()); + auto std_is_nepz = [](auto e) -> eve::logical{ return !eve::is_eqpz(e) || eve::is_nan(e); }; + EVE_ULP_RANGE_CHECK( T, eve::uniform_prng(vmin, vmax), std_is_nepz, eve::is_nepz ); + }; diff --git a/test/unit/module/core/is_bit_equal.cpp b/test/unit/module/core/is_bit_equal.cpp new file mode 100644 index 0000000000..768481f2c9 --- /dev/null +++ b/test/unit/module/core/is_bit_equal.cpp @@ -0,0 +1,68 @@ +//================================================================================================== +/** + EVE - Expressive Vector Engine + Copyright : EVE Project Contributors + SPDX-License-Identifier: BSL-1.0 +**/ +//================================================================================================== +#include "test.hpp" + +#include + +//================================================================================================== +//== Types tests +//================================================================================================== +TTS_CASE_TPL("Check return types of eve::is_bit_equal(simd)", eve::test::simd::all_types) +(tts::type) +{ + using eve::logical; + using v_t = eve::element_type_t; + using ui_t= eve::as_integer_t; + using vi_t= eve::as_integer_t; + TTS_EXPR_IS(eve::is_bit_equal(T(), T()), logical); + TTS_EXPR_IS(eve::is_bit_equal(v_t(), v_t()), logical); + TTS_EXPR_IS(eve::is_bit_equal(T(), v_t()), logical); + TTS_EXPR_IS(eve::is_bit_equal(v_t(), T()), logical); + TTS_EXPR_IS(eve::is_bit_equal(logical(), logical()), logical); + TTS_EXPR_IS(eve::is_bit_equal(logical(), logical()), logical); +}; + +//================================================================================================== +//== Tests for eve::is_bit_equal +//================================================================================================== +TTS_CASE_WITH( + "Check behavior of eve::is_bit_equal(simd)", + eve::test::simd::all_types, + tts::generate(tts::ramp(0), tts::reverse_ramp(4, 2), tts::logicals(0, 3), tts::logicals(1, 2))) +(T const& a0, T const& a1, M const& l0, M const& l1) +{ + using eve::detail::map; + using eve::as; + using eve::bit_cast; + using v_t = eve::element_type_t; + using vi_t= eve::as_integer_t; + using bi_t= eve::as_integer_t; + TTS_EQUAL(eve::is_bit_equal(a0, a1), + map([](auto e, auto f) -> eve::logical { return bit_cast(e, as())== bit_cast(f, as()); }, a0, a1)); + TTS_EQUAL(eve::is_bit_equal(a0, a0), + map([](auto e, auto f) -> eve::logical { return bit_cast(e, as())== bit_cast(f, as()); }, a0, a0)); + TTS_EQUAL(eve::is_bit_equal(l0, l1), + map([](auto e, auto f) { return e == f; }, l0, l1)); + TTS_EQUAL(eve::is_bit_equal[l0](a0, a1), + eve::if_else(l0, eve::is_bit_equal(a0, a1), eve::false_(eve::as()))); +}; + +//================================================================================================== +//== Tests for eve::is_bit_equal corner cases for floating +//================================================================================================== +TTS_CASE_TPL("Check behavior of eve::is_bit_equal(simd)", eve::test::simd::ieee_reals) +(tts::type const& tgt) +{ + + using bi_t= eve::as_integer_t; + auto cases = tts::limits(tgt); + TTS_EQUAL(eve::is_bit_equal(cases.nan, cases.nan), eve::true_(eve::as())); + TTS_EQUAL(eve::is_bit_equal(cases.mzero, cases.mzero), eve::true_(eve::as())); + TTS_EQUAL(eve::is_bit_equal(cases.mzero, cases.zero), eve::false_(eve::as())); + +}; diff --git a/test/unit/module/core/is_eqmz.cpp b/test/unit/module/core/is_eqmz.cpp new file mode 100644 index 0000000000..8939a1d4d8 --- /dev/null +++ b/test/unit/module/core/is_eqmz.cpp @@ -0,0 +1,38 @@ +//================================================================================================== +/** + EVE - Expressive Vector Engine + Copyright : EVE Project Contributors + SPDX-License-Identifier: BSL-1.0 +**/ +//================================================================================================== +#include "test.hpp" + +#include + +//================================================================================================== +// Types tests +//================================================================================================== +TTS_CASE_TPL("Check return types of eve::is_eqmz(simd)", eve::test::simd::ieee_reals) +(tts::type) +{ + using eve::logical; + using v_t = eve::element_type_t; + TTS_EXPR_IS(eve::is_eqmz(T()), logical); + TTS_EXPR_IS(eve::is_eqmz(v_t()), logical); +}; + +//================================================================================================== +// Tests for eve::is_eqmz +//================================================================================================== + +TTS_CASE_WITH("Check behavior of eve::is_eqmz(simd)", + eve::test::simd::ieee_reals, + tts::generate(tts::ramp(0), tts::logicals(0, 3))) +(T const& a0, M const& t) +{ + using eve::detail::map; + using v_t = eve::element_type_t; + + TTS_EQUAL(eve::is_eqmz(a0), map([](auto e) -> eve::logical { return e == 0 && eve::is_negative(e); }, a0)); + TTS_EQUAL(eve::is_eqmz[t](a0), eve::if_else(t, eve::is_eqmz(a0), eve::false_(eve::as(a0)))); +}; diff --git a/test/unit/module/core/is_eqpz.cpp b/test/unit/module/core/is_eqpz.cpp new file mode 100644 index 0000000000..e3b38c6918 --- /dev/null +++ b/test/unit/module/core/is_eqpz.cpp @@ -0,0 +1,38 @@ +//================================================================================================== +/** + EVE - Expressive Vector Engine + Copyright : EVE Project Contributors + SPDX-License-Identifier: BSL-1.0 +**/ +//================================================================================================== +#include "test.hpp" + +#include + +//================================================================================================== +// Types tests +//================================================================================================== +TTS_CASE_TPL("Check return types of eve::is_eqpz(simd)", eve::test::simd::ieee_reals) +(tts::type) +{ + using eve::logical; + using v_t = eve::element_type_t; + TTS_EXPR_IS(eve::is_eqpz(T()), logical); + TTS_EXPR_IS(eve::is_eqpz(v_t()), logical); +}; + +//================================================================================================== +// Tests for eve::is_eqpz +//================================================================================================== + +TTS_CASE_WITH("Check behavior of eve::is_eqpz(simd)", + eve::test::simd::ieee_reals, + tts::generate(tts::ramp(0), tts::logicals(0, 3))) +(T const& a0, M const& t) +{ + using eve::detail::map; + using v_t = eve::element_type_t; + + TTS_EQUAL(eve::is_eqpz(a0), map([](auto e) -> eve::logical { return e == 0 && eve::is_positive(e); }, a0)); + TTS_EQUAL(eve::is_eqpz[t](a0), eve::if_else(t, eve::is_eqpz(a0), eve::false_(eve::as(a0)))); +}; diff --git a/test/unit/module/core/is_minf.cpp b/test/unit/module/core/is_minf.cpp new file mode 100644 index 0000000000..e70e837dff --- /dev/null +++ b/test/unit/module/core/is_minf.cpp @@ -0,0 +1,69 @@ +//================================================================================================== +/** + EVE - Expressive Vector Engine + Copyright : EVE Project Contributors + SPDX-License-Identifier: BSL-1.0 +**/ +//================================================================================================== +#include "test.hpp" + +#include + +//================================================================================================== +// Types tests +//================================================================================================== +TTS_CASE_TPL("Check return types of eve::is_minf(simd)", eve::test::simd::all_types) +(tts::type) +{ + using eve::logical; + using v_t = eve::element_type_t; + TTS_EXPR_IS(eve::is_minf(T()), logical); + TTS_EXPR_IS(eve::is_minf(v_t()), logical); +}; + +//================================================================================================== +// Tests for eve::is_minf +//================================================================================================== +TTS_CASE_WITH("Check behavior of eve::is_minf(simd) integrals", + eve::test::simd::integers, + tts::generate(tts::ramp(0), tts::logicals(0, 3))) +(T a0, M const& t) +{ + using eve::detail::map; + TTS_EQUAL(eve::is_minf(a0), eve::false_(eve::as(a0))); + TTS_EQUAL(eve::is_minf[t](a0), + eve::if_else(t, eve::is_minf(a0), eve::false_(eve::as(a0)))); +}; + +TTS_CASE_WITH("Check behavior of eve::is_minf(simd) IEEE", + eve::test::simd::ieee_reals, + tts::generate(tts::ramp(0), tts::logicals(0, 3))) +(T a0, M const& t) +{ + using eve::detail::map; + using v_t = eve::element_type_t; + a0 = eve::if_else(eve::is_eqz(a0), eve::inf(eve::as()), eve::zero); + TTS_EQUAL(eve::is_minf(a0), + map([](auto e) -> eve::logical { return e - e != 0 && e < 0; }, a0)); + TTS_EQUAL(eve::is_minf[t](a0), + eve::if_else(t, eve::is_minf(a0), eve::false_(eve::as(a0)))); +}; + +//================================================================================================== +// Test cases values +//================================================================================================== +TTS_CASE_TPL("Check corner-cases behavior of eve::is_minf on wide",eve::test::simd::ieee_reals) +(tts::type tgt) +{ + using eve::as; + + auto cases = tts::limits(tgt); + TTS_EQUAL(eve::is_minf(cases.nan), eve::false_(as())); + TTS_EQUAL(eve::is_minf(-cases.nan), eve::false_(as())); + TTS_EQUAL(eve::is_minf(cases.minf), eve::true_(as())); + TTS_EQUAL(eve::is_minf(cases.inf), eve::false_(as())); + TTS_EQUAL(eve::is_minf(cases.zero), eve::false_(as())); + TTS_EQUAL(eve::is_minf(cases.mzero), eve::false_(as())); + TTS_EQUAL(eve::is_minf(cases.valmin), eve::false_(as())); + TTS_EQUAL(eve::is_minf(cases.valmax), eve::false_(as())); +}; diff --git a/test/unit/module/core/is_negative.cpp b/test/unit/module/core/is_negative.cpp index 9e4cb7db25..b18d820553 100644 --- a/test/unit/module/core/is_negative.cpp +++ b/test/unit/module/core/is_negative.cpp @@ -58,8 +58,8 @@ TTS_CASE_TPL("Check corner-cases behavior of eve::is_negative on wide", eve::tes using eve::as; auto cases = tts::limits(tgt); - TTS_EQUAL(eve::is_negative(cases.nan), eve::true_(as())); - TTS_EQUAL(eve::is_negative(-cases.nan), eve::false_(as())); + TTS_EQUAL(eve::is_negative[eve::pedantic](cases.nan), eve::false_(as())); + TTS_EQUAL(eve::is_negative[eve::pedantic](-cases.nan), eve::false_(as())); TTS_EQUAL(eve::is_negative(cases.minf), eve::true_(as())); TTS_EQUAL(eve::is_negative(cases.inf), eve::false_(as())); TTS_EQUAL(eve::is_negative(cases.zero), eve::false_(as())); diff --git a/test/unit/module/core/is_nemz.cpp b/test/unit/module/core/is_nemz.cpp new file mode 100644 index 0000000000..9ff6c695ca --- /dev/null +++ b/test/unit/module/core/is_nemz.cpp @@ -0,0 +1,38 @@ +//================================================================================================== +/** + EVE - Expressive Vector Engine + Copyright : EVE Project Contributors + SPDX-License-Identifier: BSL-1.0 +**/ +//================================================================================================== +#include "test.hpp" + +#include + +//================================================================================================== +// Types tests +//================================================================================================== +TTS_CASE_TPL("Check return types of eve::is_nemz(simd)", eve::test::simd::ieee_reals) +(tts::type) +{ + using eve::logical; + using v_t = eve::element_type_t; + TTS_EXPR_IS(eve::is_nemz(T()), logical); + TTS_EXPR_IS(eve::is_nemz(v_t()), logical); +}; + +//================================================================================================== +// Tests for eve::is_nemz +//================================================================================================== + +TTS_CASE_WITH("Check behavior of eve::is_nemz(simd)", + eve::test::simd::ieee_reals, + tts::generate(tts::ramp(0), tts::logicals(0, 3))) +(T const& a0, M const& t) +{ + using eve::detail::map; + using v_t = eve::element_type_t; + + TTS_EQUAL(eve::is_nemz(a0), map([](auto e) -> eve::logical { return eve::is_ltz(e) || eve::is_positive(e); }, a0)); + TTS_EQUAL(eve::is_nemz[t](a0), eve::if_else(t, eve::is_nemz(a0), eve::false_(eve::as(a0)))); +}; diff --git a/test/unit/module/core/is_nepz.cpp b/test/unit/module/core/is_nepz.cpp new file mode 100644 index 0000000000..6317d39a50 --- /dev/null +++ b/test/unit/module/core/is_nepz.cpp @@ -0,0 +1,38 @@ +//================================================================================================== +/** + EVE - Expressive Vector Engine + Copyright : EVE Project Contributors + SPDX-License-Identifier: BSL-1.0 +**/ +//================================================================================================== +#include "test.hpp" + +#include + +//================================================================================================== +// Types tests +//================================================================================================== +TTS_CASE_TPL("Check return types of eve::is_nepz(simd)", eve::test::simd::ieee_reals) +(tts::type) +{ + using eve::logical; + using v_t = eve::element_type_t; + TTS_EXPR_IS(eve::is_nepz(T()), logical); + TTS_EXPR_IS(eve::is_nepz(v_t()), logical); +}; + +//================================================================================================== +// Tests for eve::is_nepz +//================================================================================================== + +TTS_CASE_WITH("Check behavior of eve::is_nepz(simd)", + eve::test::simd::ieee_reals, + tts::generate(tts::ramp(0), tts::logicals(0, 3))) +(T const& a0, M const& t) +{ + using eve::detail::map; + using v_t = eve::element_type_t; + + TTS_EQUAL(eve::is_nepz(a0), map([](auto e) -> eve::logical { return eve::is_gtz(e) || eve::is_negative(e); }, a0)); + TTS_EQUAL(eve::is_nepz[t](a0), eve::if_else(t, eve::is_nepz(a0), eve::false_(eve::as(a0)))); +};