diff --git a/benchmarks/module/core/plus/regular/plus.hpp b/benchmarks/module/core/plus/regular/plus.hpp deleted file mode 100644 index 956f8da006..0000000000 --- a/benchmarks/module/core/plus/regular/plus.hpp +++ /dev/null @@ -1,24 +0,0 @@ -//================================================================================================== -/* - EVE - Expressive Vector Engine - Copyright : EVE Project Contributors - SPDX-License-Identifier: BSL-1.0 -*/ -//================================================================================================== -#include -#include - -int main() -{ - auto lmin = eve::valmin(eve::as()); - auto lmax = eve::valmax(eve::as()); - - auto const std__plus = [](EVE_VALUE x) { return EVE_VALUE(-x); }; - - auto arg0 = eve::bench::random_(lmin,lmax); - - eve::bench::experiment xp; - run (EVE_NAME(std__plus) , xp, std__plus, arg0); - run (EVE_NAME(plus) , xp, eve::plus, arg0); - run (EVE_NAME(plus) , xp, eve::plus, arg0); -} diff --git a/include/eve/detail/function/operators.hpp b/include/eve/detail/function/operators.hpp index e211795ff7..d24a7bfe24 100644 --- a/include/eve/detail/function/operators.hpp +++ b/include/eve/detail/function/operators.hpp @@ -19,45 +19,6 @@ namespace eve::detail //================================================================================================ // Infix arithmetic operators //================================================================================================ - template - EVE_FORCEINLINE auto add_(EVE_SUPPORTS(cpu_), T a, T b) noexcept - { - return static_cast(a + b); - } - - template - EVE_FORCEINLINE auto - add_(EVE_SUPPORTS(cpu_), T const &a, U const &b) noexcept requires compatible_values - { - return a + b; - } - - template - EVE_FORCEINLINE auto sub_(EVE_SUPPORTS(cpu_), T a, T b) noexcept - { - return static_cast(a - b); - } - - template - EVE_FORCEINLINE auto - sub_(EVE_SUPPORTS(cpu_), T const &a, U const &b) noexcept requires compatible_values - { - return a - b; - } - - template - EVE_FORCEINLINE auto mul_(EVE_SUPPORTS(cpu_), T a, T b) noexcept - { - return static_cast(a * b); - } - - template - EVE_FORCEINLINE auto - mul_(EVE_SUPPORTS(cpu_), T const &a, U const &b) noexcept requires compatible_values - { - return a * b; - } - template EVE_FORCEINLINE auto div_(EVE_SUPPORTS(cpu_), T a, T b) noexcept { diff --git a/include/eve/module/algo/algo/inclusive_scan.hpp b/include/eve/module/algo/algo/inclusive_scan.hpp index e8b705ca83..c2818fd752 100644 --- a/include/eve/module/algo/algo/inclusive_scan.hpp +++ b/include/eve/module/algo/algo/inclusive_scan.hpp @@ -88,7 +88,7 @@ namespace eve::algo template EVE_FORCEINLINE void operator()(Rng&& rng, U init) const { - operator()(EVE_FWD(rng), std::pair{eve::plus, eve::zero}, init); + operator()(EVE_FWD(rng), std::pair{eve::add, eve::zero}, init); } }; @@ -107,7 +107,7 @@ namespace eve::algo template EVE_FORCEINLINE auto operator()(R r, U init) const { - operator()(r, std::pair{eve::plus, eve::zero}, init); + operator()(r, std::pair{eve::add, eve::zero}, init); } template diff --git a/include/eve/module/algo/algo/reduce.hpp b/include/eve/module/algo/algo/reduce.hpp index fa916b5e82..37907e0eca 100644 --- a/include/eve/module/algo/algo/reduce.hpp +++ b/include/eve/module/algo/algo/reduce.hpp @@ -137,7 +137,7 @@ namespace eve::algo //! * `rng`: Relaxed range input range to process //! * `init`: Initial value. Also type of init matches the result type //! * `op_zero`: Pair of reduction operation (commutative/associative) and an identity (zero) - //! for it. Default add_zero is `{eve::plus, eve::zero}`. + //! for it. Default add_zero is `{eve::add, eve::zero}`. //! //! **Return value** //! diff --git a/include/eve/module/algo/algo/transform_reduce.hpp b/include/eve/module/algo/algo/transform_reduce.hpp index 5d6a62e9f1..1d9432c83b 100644 --- a/include/eve/module/algo/algo/transform_reduce.hpp +++ b/include/eve/module/algo/algo/transform_reduce.hpp @@ -160,7 +160,7 @@ template struct transform_reduce_ : TraitsSupport //! * `init`: Initial value. Also type of init matches the result type //! * `map_op`: Transformation operation //! * `add_zero`: Pair of reduction operation (commutative/associative) and an identity (zero) -//! for it. Default add_zero is `{eve::plus, eve::zero}`. +//! for it. Default add_zero is `{eve::add, eve::zero}`. //! //! **Return value** //! diff --git a/include/eve/module/core/detail/core.hpp b/include/eve/module/core/detail/core.hpp index 8eb6f990e9..567190f906 100644 --- a/include/eve/module/core/detail/core.hpp +++ b/include/eve/module/core/detail/core.hpp @@ -19,6 +19,5 @@ //================================================================================================== #include #include -#include -#include #include +#include diff --git a/include/eve/module/core/detail/multi_div.hpp b/include/eve/module/core/detail/multi_div.hpp index a28535a779..9f67897c2c 100644 --- a/include/eve/module/core/detail/multi_div.hpp +++ b/include/eve/module/core/detail/multi_div.hpp @@ -23,7 +23,7 @@ namespace eve::detail { using r_t = common_value_t; r_t that(a1); - that = d(mul)(that, r_t(args)...); + that = mul[d](that, r_t(args)...); EVE_ASSERT(eve::all(is_nez(that)), "[eve] D()(div) - 0/0 is undefined"); return (D()(div))(r_t(a0), that); } diff --git a/include/eve/module/core/detail/multi_mul.hpp b/include/eve/module/core/detail/multi_mul.hpp deleted file mode 100644 index 94cda742b7..0000000000 --- a/include/eve/module/core/detail/multi_mul.hpp +++ /dev/null @@ -1,27 +0,0 @@ -//================================================================================================== -/* - EVE - Expressive Vector Engine - Copyright : EVE Project Contributors - SPDX-License-Identifier: BSL-1.0 -*/ -//================================================================================================== -#pragma once - -#include -#include -#include -#include - -namespace eve::detail -{ - template - auto - mul_(EVE_SUPPORTS(cpu_), D const& d, T0 a0, T1 a1, Ts... args) noexcept - -> common_value_t - { - using r_t = common_value_t; - r_t that(d(mul)(r_t(a0), r_t(a1))); - ((that = d(mul)(that, r_t(args))), ...); - return that; - } -} diff --git a/include/eve/module/core/regular/add.hpp b/include/eve/module/core/regular/add.hpp index 7faf44f38e..c9259d310e 100644 --- a/include/eve/module/core/regular/add.hpp +++ b/include/eve/module/core/regular/add.hpp @@ -7,10 +7,29 @@ //================================================================================================== #pragma once -#include +#include +#include +#include namespace eve { + template + struct add_t : tuple_callable + { + template + EVE_FORCEINLINE constexpr common_value_t operator()(T0 t0, T1 t1, Ts...ts) const noexcept + { + return EVE_DISPATCH_CALL(t0, t1, ts...); + } + + template + EVE_FORCEINLINE constexpr + kumi::apply_traits_t + operator()(Tup const& t) const noexcept requires(kumi::size_v >= 2) { return EVE_DISPATCH_CALL(t); } + + EVE_CALLABLE_OBJECT(add_t, add_); + }; + //================================================================================================ //! @addtogroup core_arithmetic //! @{ @@ -28,26 +47,25 @@ namespace eve //! @code //! namespace eve //! { -//! template< eve::value... Ts > +//! template //! eve::common_value_t add(Ts ... xs) noexcept; //! } //! @endcode //! //! **Parameters** //! -//! * `xs ...` : [real](@ref eve::value) arguments. +//! * `xs ...` : [Values](@ref eve::value) to sum. //! //! **Return value** //! -//! The value of the sum of the arguments is returned. +//! The value of the sum of the arguments. //! //! @note //! //! * Take care that for floating entries, the addition is only 'almost' associative. //! This call performs additions in reverse incoming order. //! -//! * Although the infix notation with `+` is supported for -//! two parameters, the `+` operator on +//! * Although the infix notation with `+` is supported for two parameters, the `+` operator on //! standard scalar types is the original one and so can lead to automatic promotion. //! //! @groupheader{Example} @@ -63,15 +81,16 @@ namespace eve //! //! * eve::saturated //! -//! The call `eve::saturated(eve::add)(...)` computes -//! a saturated version of `eve::add`. +//! The call `eve::add[eve::saturated](...)` computes a saturated version of `eve::add`. //! //! Take care that for signed integral entries this kind of addition is not associative at all. //! This call perform saturated additions in reverse incoming order. -//! //! @} //================================================================================================ -EVE_MAKE_CALLABLE(add_, add); + inline constexpr auto add = functor; + + // Required for optimisation detections + using callable_add_ = tag_t; } #include diff --git a/include/eve/module/core/regular/core.hpp b/include/eve/module/core/regular/core.hpp index 30554c1000..85f44c63ae 100644 --- a/include/eve/module/core/regular/core.hpp +++ b/include/eve/module/core/regular/core.hpp @@ -84,7 +84,6 @@ #include #include #include -#include #include #include #include @@ -169,7 +168,6 @@ #include #include #include -#include #include #include #include diff --git a/include/eve/module/core/regular/ifnot_else.hpp b/include/eve/module/core/regular/ifnot_else.hpp deleted file mode 100644 index a059eed007..0000000000 --- a/include/eve/module/core/regular/ifnot_else.hpp +++ /dev/null @@ -1,61 +0,0 @@ -//================================================================================================== -/* - EVE - Expressive Vector Engine - Copyright : EVE Project Contributors - SPDX-License-Identifier: BSL-1.0 -*/ -//================================================================================================== -#pragma once - -#include - -namespace eve -{ -//================================================================================================ -//! @addtogroup core_logical -//! @{ -//! @var ifnot_else -//! @brief `eve::ifnot_else``(x, y, z)`syntaxic sugar for `eve::if_else``(x, z, y)` -//! -//! **Defined in Header** -//! -//! @code -//! #include -//! @endcode -//! -//! @groupheader{Callable Signatures} -//! -//! @code -//! namespace eve -//! { -//! template< eve::value T, eve::value U, eve::value V > -//! auto ifnot_else(T x, U, y, V z ) noexcept; -//! } -//! @endcode -//! -//! **Parameters** -//! -//! * `x`: condition -//! * `y`, `z`: choice [arguments](@ref eve::value). -//! -//! **Return value** -//! -//! The call `eve::ifnot_else``(x, y, z)`is equivalent to `eve::if_else``(x, z, y)` -//! -//! @groupheader{Example} -//! -//! @godbolt{doc/core/ifnot_else.cpp} -//! -//! @} -//================================================================================================ -namespace tag -{ - struct ifnot_else_; -} -template<> struct supports_conditional : std::false_type -{}; - -EVE_MAKE_CALLABLE(ifnot_else_, ifnot_else); -} - -#include diff --git a/include/eve/module/core/regular/impl/add.hpp b/include/eve/module/core/regular/impl/add.hpp index 0f8aeb616e..4483c4ca35 100644 --- a/include/eve/module/core/regular/impl/add.hpp +++ b/include/eve/module/core/regular/impl/add.hpp @@ -7,63 +7,50 @@ //================================================================================================== #pragma once -#include -#include #include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include namespace eve::detail { -//================================================================================================ -// Masked case -//================================================================================================ -template -EVE_FORCEINLINE auto -add_(EVE_SUPPORTS(cpu_), - C const& cond, - U t, - Vs... fs) noexcept -{ - return mask_op(cond, eve::add, t, fs...); -} - -//================================================================================================ -// N parameters -//================================================================================================ -template -auto -add_(EVE_SUPPORTS(cpu_), D const& d, T0 a0, Ts... args) noexcept -{ - common_value_t that(a0); - ((that = d(add)(that, args)), ...); - return that; -} - -template -auto -add_(EVE_SUPPORTS(cpu_), T0 a0, Ts... args) noexcept --> common_value_t -{ - auto that((a0 + ... + args)); - return that; -} - -//================================================================================================ -// tuples -//================================================================================================ -template -auto -add_(EVE_SUPPORTS(cpu_), Ts tup) noexcept -{ - if constexpr( kumi::size_v == 1) return get<0>(tup); - else return kumi::apply( [&](auto... m) { return add(m...); }, tup); -} - -template -auto -add_(EVE_SUPPORTS(cpu_), D const & d, Ts tup) noexcept -{ - if constexpr( kumi::size_v == 1) return get<0>(tup); - else return kumi::apply( [&](auto... m) { return d(add)(m...); }, tup); -} + template + EVE_FORCEINLINE constexpr T add_(EVE_REQUIRES(cpu_), O const&, T a, T b) noexcept + { + if constexpr(O::contains(saturated2) && integral_value) + { + if constexpr( signed_integral_value ) + { + auto test = is_ltz(b); + auto pos = min(sub(valmax(as(a)), b), a); + auto neg = max(sub(valmin(as(a)), b), a); + return add(b, if_else(test, neg, pos)); + } + else + { + // Triggers conditional MOV that directly read the flag register + T r = a + b; + return bit_or(r, bit_mask(is_less(r, a))); + } + } + else + { + return a += b; + } + } + template... Ts, callable_options O> + EVE_FORCEINLINE constexpr T add_(EVE_REQUIRES(cpu_), O const & o, T r0, T r1, Ts... rs) noexcept + { + r0 = add[o](r0,r1); + ((r0 = add[o](r0,rs)),...); + return r0; + } } diff --git a/include/eve/module/core/regular/impl/div.hpp b/include/eve/module/core/regular/impl/div.hpp index 213f2518a4..378296c066 100644 --- a/include/eve/module/core/regular/impl/div.hpp +++ b/include/eve/module/core/regular/impl/div.hpp @@ -15,7 +15,6 @@ #include #include #include -#include #include #include #include diff --git a/include/eve/module/core/regular/impl/ifnot_else.hpp b/include/eve/module/core/regular/impl/ifnot_else.hpp deleted file mode 100644 index b93420964a..0000000000 --- a/include/eve/module/core/regular/impl/ifnot_else.hpp +++ /dev/null @@ -1,26 +0,0 @@ -//================================================================================================== -/* - 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 constexpr auto -ifnot_else_(EVE_SUPPORTS(cpu_), - T const& cond, - U const& t, - V const& f) noexcept --> decltype(if_else(cond, f, t)) -{ - return if_else(cond, f, t); -} -} diff --git a/include/eve/module/core/regular/impl/mul.hpp b/include/eve/module/core/regular/impl/mul.hpp index ea204a37ab..9c99048555 100644 --- a/include/eve/module/core/regular/impl/mul.hpp +++ b/include/eve/module/core/regular/impl/mul.hpp @@ -7,64 +7,129 @@ //================================================================================================== #pragma once -#include -#include -#include -#include - -namespace eve::detail -{ -//================================================================================================ -//== Masked case -//================================================================================================ -template -EVE_FORCEINLINE auto -mul_(EVE_SUPPORTS(cpu_), - C const& cond, - U t, - V... f) noexcept -{ - return mask_op(cond, eve::mul, t, f...); -} - -//================================================================================================ -//== regular N parameters -//================================================================================================ -template -auto -mul_(EVE_SUPPORTS(cpu_), D const& d, T0 a0, Ts... args) noexcept -{ - common_value_t that(a0); - ((that = d(mul)(that, args)), ...); - return that; -} -template -auto -mul_(EVE_SUPPORTS(cpu_), T0 a0, Ts... args) noexcept --> common_value_t -{ - auto that((a0 * ... * args)); - return that; -} -//================================================================================================ -// tuples -//================================================================================================ -template -auto -mul_(EVE_SUPPORTS(cpu_), Ts tup) noexcept -{ - if constexpr( kumi::size_v == 1) return get<0>(tup); - else return kumi::apply( [&](auto... m) { return mul(m...); }, tup); -} +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include -template -auto -mul_(EVE_SUPPORTS(cpu_), D const & d, Ts tup) noexcept +namespace eve::detail { - if constexpr( kumi::size_v == 1) return get<0>(tup); - else return kumi::apply( [&](auto... m) { return d(mul)(m...); }, tup); -} + template + EVE_FORCEINLINE constexpr T mul_(EVE_REQUIRES(cpu_), O const&, T a, T b) noexcept + { + if constexpr(O::contains(saturated2) && integral_value) + { + if constexpr( signed_integral_value ) + { + if constexpr(scalar_value) + { + if constexpr( sizeof(T) <= 4 ) + { + using up_t = upgrade_t; + return static_cast(saturate(static_cast(a) * static_cast(b), as())); + } + else if constexpr( sizeof(T) == 8 ) + { + using un_t = std::make_unsigned_t; + if( b == 0 || a == 0 ) return zero(eve::as()); + T sgn = bit_xor(bitofsign(a), bitofsign(b)); + if( b == valmin(eve::as()) || a == valmin(eve::as()) ) + return sgn ? valmin(eve::as()) : valmax(eve::as()); + un_t aa = eve::abs(a); + un_t bb = eve::abs(b); + auto aux = [sgn](const T& mini, const T& maxi, const un_t& amini, const un_t& amaxi) + { + un_t z = valmax(eve::as()) / amaxi; + return (z < amini) ? (sgn ? valmin(eve::as()) : valmax(eve::as())) : mini * maxi; + }; + if( bb >= aa ) return aux(a, b, aa, bb); + else return aux(b, a, bb, aa); + } + } + else // simd + { + using elt_t = element_type_t; + if constexpr( floating_value ) { return a * b; } + else if constexpr( integral_value ) + { + if constexpr( sizeof(elt_t) <= 4 ) + { + using sup_t = upgrade_t; + auto z = mul(convert(a, as()), convert(b, as())); + auto s = saturate(z, as()); + return convert(s, as()); + } + else + { + auto that = map(eve::mul[saturated], a, b); + return that; + } + } + } + } + else //unsigned + { + if constexpr(scalar_value) + { + if constexpr( sizeof(T) <= 4 ) + { + using up_t = upgrade_t; + up_t res = up_t(a) * up_t(b); + return (res > valmax(eve::as())) ? valmax(eve::as()) : static_cast(res); + } + else + { + auto aux = [](const T& mini, const T& maxi) + { + T z = valmax(eve::as()) / maxi; + return (z < mini) ? valmax(eve::as()) : mini * maxi; + }; + if( b == 0 || a == 0 ) return zero(eve::as()); + if( b >= a ) return aux(a, b); + else return aux(b, a); + } + } + else //simd + { + using elt_t = element_type_t; + if constexpr( sizeof(elt_t) <= 4 ) + { + using sup_t = upgrade_t; + auto z = mul(convert(a, as()), convert(b, as())); + auto s = saturate(z, as()); + return convert(s, as()); + } + else + { + auto that = map(eve::mul[saturated], a, b); + return that; + } + } + } + } + else + { + return a *= b; + } + } + template... Ts, callable_options O> + EVE_FORCEINLINE constexpr T mul_(EVE_REQUIRES(cpu_), O const & o, T r0, T r1, Ts... rs) noexcept + { + r0 = mul[o](r0,r1); + ((r0 = mul[o](r0,rs)),...); + return r0; + } } diff --git a/include/eve/module/core/regular/impl/plus.hpp b/include/eve/module/core/regular/impl/plus.hpp deleted file mode 100644 index f40228360d..0000000000 --- a/include/eve/module/core/regular/impl/plus.hpp +++ /dev/null @@ -1,46 +0,0 @@ -//================================================================================================== -/* - EVE - Expressive Vector Engine - Copyright : EVE Project Contributors - SPDX-License-Identifier: BSL-1.0 -*/ -//================================================================================================== -#pragma once - -#include -#include -#include -#include -#include -#include - -namespace eve::detail -{ -template -EVE_FORCEINLINE T -plus_(EVE_SUPPORTS(cpu_), T const& a) noexcept -{ - return a; -} - -template -EVE_FORCEINLINE auto -plus_(EVE_SUPPORTS(cpu_), T const& a, U const& b) noexcept --> common_value_t{ - return add(a, b); -} - -//================================================================================================ -// Masked case -//================================================================================================ -template -EVE_FORCEINLINE auto -plus_(EVE_SUPPORTS(cpu_), - C const& cond, - U ... t - ) noexcept -{ - return mask_op(cond, eve::add, t...); -} - -} diff --git a/include/eve/module/core/regular/impl/reduce.hpp b/include/eve/module/core/regular/impl/reduce.hpp index a8473d0c9b..73c806814f 100644 --- a/include/eve/module/core/regular/impl/reduce.hpp +++ b/include/eve/module/core/regular/impl/reduce.hpp @@ -18,7 +18,6 @@ #include #include #include -#include #include #include @@ -30,8 +29,7 @@ template EVE_FORCEINLINE auto find_reduction(Callable f, Option = 0) noexcept { - if constexpr( std::same_as ) return eve::detail::sum; - else if constexpr( std::same_as ) return eve::detail::sum; + if constexpr( std::same_as ) return eve::detail::sum; else if constexpr( std::same_as ) return eve::minimum; else if constexpr( std::same_as ) return eve::maximum; else if constexpr( std::same_as ) return eve::all; diff --git a/include/eve/module/core/regular/impl/scan.hpp b/include/eve/module/core/regular/impl/scan.hpp index 9b7b260e75..b193ad2e66 100644 --- a/include/eve/module/core/regular/impl/scan.hpp +++ b/include/eve/module/core/regular/impl/scan.hpp @@ -8,7 +8,7 @@ #pragma once #include -#include +#include #include namespace eve::detail @@ -65,7 +65,7 @@ template EVE_FORCEINLINE Wide scan_(EVE_SUPPORTS(cpu_), Wide v) noexcept { - return scan(v, plus, eve::zero); + return scan(v, add, eve::zero); } } diff --git a/include/eve/module/core/regular/impl/simd/arm/neon/mul.hpp b/include/eve/module/core/regular/impl/simd/arm/neon/mul.hpp deleted file mode 100644 index a43c9817e1..0000000000 --- a/include/eve/module/core/regular/impl/simd/arm/neon/mul.hpp +++ /dev/null @@ -1,37 +0,0 @@ -//================================================================================================== -/* - EVE - Expressive Vector Engine - Copyright : EVE Project Contributors - SPDX-License-Identifier: BSL-1.0 -*/ -//================================================================================================== -#pragma once - -#include -#include - -namespace eve::detail -{ -template -EVE_FORCEINLINE wide - mul_(EVE_SUPPORTS(neon128_), - wide v0, - wide const &v1) noexcept requires arm_abi> -{ - return v0 *= v1; -} - -template -EVE_FORCEINLINE wide -mul_(EVE_SUPPORTS(neon128_), wide v0, U const& v1) noexcept requires arm_abi> -{ - return v0 *= v1; -} - -template -EVE_FORCEINLINE wide -mul_(EVE_SUPPORTS(neon128_), U const& v0, wide v1) noexcept requires arm_abi> -{ - return v1 *= v0; -} -} diff --git a/include/eve/module/core/regular/impl/simd/arm/neon/sub.hpp b/include/eve/module/core/regular/impl/simd/arm/neon/sub.hpp deleted file mode 100644 index 222a77b59f..0000000000 --- a/include/eve/module/core/regular/impl/simd/arm/neon/sub.hpp +++ /dev/null @@ -1,23 +0,0 @@ -//================================================================================================== -/* - EVE - Expressive Vector Engine - Copyright : EVE Project Contributors - SPDX-License-Identifier: BSL-1.0 -*/ -//================================================================================================== -#pragma once - -#include -#include - -namespace eve::detail -{ -template -EVE_FORCEINLINE auto -sub_(EVE_SUPPORTS(neon128_), - wide v0, - wide const& v1) noexcept requires arm_abi> -{ - return v0 -= v1; -} -} diff --git a/include/eve/module/core/regular/impl/simd/arm/sve/add.hpp b/include/eve/module/core/regular/impl/simd/arm/sve/add.hpp index 142d7a1a5d..d126cea7c2 100644 --- a/include/eve/module/core/regular/impl/simd/arm/sve/add.hpp +++ b/include/eve/module/core/regular/impl/simd/arm/sve/add.hpp @@ -8,23 +8,45 @@ #pragma once #include -#include +#include +#include namespace eve::detail { -template -EVE_FORCEINLINE wide -add_(EVE_SUPPORTS(sve_), C const& cx, wide v, wide w) noexcept -requires sve_abi> -{ - if constexpr( C::is_complete ) { return add_(EVE_RETARGET(cpu_), cx, v, w); } - else + template + EVE_FORCEINLINE wide + add_(EVE_REQUIRES(sve_), C const& mask, O const& opts, wide v, wide w) noexcept + requires sve_abi> { - if constexpr( !C::has_alternative ) + auto const alt = alternative(mask, v, as(v)); + + // ignore all just return alternative + if constexpr( C::is_complete ) return alt; + else { - auto m = expand_mask(cx, as> {}); - return svadd_m(m,v,w); + // if saturated on integer, we don't have masked op so we delegate + if constexpr(O::contains(saturated2) && std::integral) return add.behavior(cpu_{},opts,v,w); + // If not, we can mask if there is no alterative value + else if constexpr( !C::has_alternative ) + { + auto m = expand_mask(mask, as(v)); + return svadd_m(m,v,w); + } + // If not, we delegate to the automasking + else + { + return add.behavior(cpu_{},opts,v,w); + } } - else return add_(EVE_RETARGET(cpu_), cx, v, w); } -} + } + + template + EVE_FORCEINLINE wide + add_(EVE_REQUIRES(sve_), O const& opts, wide v, wide w) noexcept + requires sve_abi> + { + // We call the saturated add if required or we just go to the common case of doing v+w + if constexpr(O::contains(saturated2) && std::integral) return svqadd(v, w); + else return add.behavior(cpu_{},opts,v,w); + } } diff --git a/include/eve/module/core/regular/impl/simd/arm/sve/minus.hpp b/include/eve/module/core/regular/impl/simd/arm/sve/minus.hpp index f7b258e9d6..ab93c0c721 100644 --- a/include/eve/module/core/regular/impl/simd/arm/sve/minus.hpp +++ b/include/eve/module/core/regular/impl/simd/arm/sve/minus.hpp @@ -13,19 +13,28 @@ namespace eve::detail { -template -EVE_FORCEINLINE wide -minus_(EVE_SUPPORTS(sve_), wide const& v) noexcept requires sve_abi> -{ - return -v; -} + template + requires sve_abi> + EVE_FORCEINLINE wide minus_(EVE_REQUIRES(sve_), O const& o, wide v) noexcept + { + // saturated integer has no intrinsic and floating is better by default + if constexpr((O::contains(saturated2) && std::integral) || floating_value) return minus.behavior(cpu_{},o,v); + else return svneg_x(sve_true(),v); + } -template -EVE_FORCEINLINE auto -minus_(EVE_SUPPORTS(sve_), C const& cond, wide v) noexcept -> wide -requires sve_abi> -{ - if constexpr( C::is_complete && C::is_inverted ) return -v; - else return svneg_m(alternative(cond, v, as(v)), expand_mask(cond, as(v)), v); -} + template + requires sve_abi> + EVE_FORCEINLINE wide minus_(EVE_REQUIRES(sve_), C const& mask, O const& o, wide v) noexcept + { + auto const alt = alternative(mask, v, as(v)); + + // ignore all just return alternative + if constexpr( C::is_complete ) return alt; + else + { + // if saturated on integer, we don't have masked op so we delegate + if constexpr(O::contains(saturated2) && std::integral) return minus.behavior(cpu_{},o,v); + else return svneg_m(alt,expand_mask(mask, as(v)),v); + } + } } diff --git a/include/eve/module/core/regular/impl/simd/arm/sve/mul.hpp b/include/eve/module/core/regular/impl/simd/arm/sve/mul.hpp index c28b8245d4..262d7d85fd 100644 --- a/include/eve/module/core/regular/impl/simd/arm/sve/mul.hpp +++ b/include/eve/module/core/regular/impl/simd/arm/sve/mul.hpp @@ -12,19 +12,34 @@ namespace eve::detail { -template -EVE_FORCEINLINE wide -mul_(EVE_SUPPORTS(sve_), C const& cx, wide const& v, wide const& w) noexcept -requires sve_abi> -{ - if constexpr( C::is_complete ) { return mul_(EVE_RETARGET(cpu_), cx, v, w); } - else + template + EVE_FORCEINLINE wide mul_(EVE_REQUIRES(sve_), + C const& mask, + O const& opts, + wide const& v, + wide const& w) noexcept + requires sve_abi> { - if constexpr( !C::has_alternative ) + auto const alt = alternative(mask, v, as(v)); + + // ignore all just return alternative + if constexpr( C::is_complete ) return alt; + else { - auto m = expand_mask(cx, as> {}); - return svmul_m(m,v,w); + // if saturated on integer, we don't have masked op so we delegate + if constexpr(O::contains(saturated2) && std::integral) return mul.behavior(cpu_{},opts,v,w); + // If not, we can mask if there is no alterative value + else if constexpr( !C::has_alternative && sizeof(T) > 1) + { + auto m = expand_mask(mask, as(v)); + return svmul_m(m,v,w); + } + // If not, we delegate to the automasking + else + { + return mul.behavior(cpu_{},opts,v,w); + } + } - else return mul_(EVE_RETARGET(cpu_), cx, v, w); } -} + } } diff --git a/include/eve/module/core/regular/impl/simd/arm/sve/sub.hpp b/include/eve/module/core/regular/impl/simd/arm/sve/sub.hpp index 39974bac60..abc29b78b7 100644 --- a/include/eve/module/core/regular/impl/simd/arm/sve/sub.hpp +++ b/include/eve/module/core/regular/impl/simd/arm/sve/sub.hpp @@ -12,19 +12,42 @@ namespace eve::detail { -template -EVE_FORCEINLINE wide -sub_(EVE_SUPPORTS(sve_), C const& cx, wide const& v, wide const& w) noexcept -requires sve_abi> -{ - if constexpr( C::is_complete ) { return sub_(EVE_RETARGET(cpu_), cx, v, w); } - else + + template + EVE_FORCEINLINE wide + sub_(EVE_REQUIRES(sve_), C const& mask, O const& opts, wide v, wide w) noexcept + requires sve_abi> { - if constexpr( !C::has_alternative ) + auto const alt = alternative(mask, v, as(v)); + + // ignore all just return alternative + if constexpr( C::is_complete ) return alt; + else { - auto m = expand_mask(cx, as> {}); - return svsub_m(m,v,w); + // if saturated on integer, we don't have masked op so we delegate + if constexpr(O::contains(saturated2) && std::integral) return sub.behavior(cpu_{},opts,v,w); + // If not, we can mask if there is no alterative value + else if constexpr( !C::has_alternative ) + { + auto m = expand_mask(mask, as(v)); + return svsub_m(m,v,w); + } + // If not, we delegate to the automasking + else + { + return sub.behavior(cpu_{},opts,v,w); + } } - else return sub_(EVE_RETARGET(cpu_), cx, v, w); } -} + } + + template + EVE_FORCEINLINE wide + sub_(EVE_REQUIRES(sve_), O const& opts, wide v, wide w) noexcept + requires sve_abi> + { + // We call the saturated sub if required or we just go to the common case of doing v+w + if constexpr(O::contains(saturated2) && std::integral) return svqsub(v, w); + else return sub.behavior(cpu_{},opts,v,w); + } } + diff --git a/include/eve/module/core/regular/impl/simd/ppc/mul.hpp b/include/eve/module/core/regular/impl/simd/ppc/mul.hpp deleted file mode 100644 index 3f3b3a6792..0000000000 --- a/include/eve/module/core/regular/impl/simd/ppc/mul.hpp +++ /dev/null @@ -1,21 +0,0 @@ -//================================================================================================== -/* - EVE - Expressive Vector Engine - Copyright : EVE Project Contributors - SPDX-License-Identifier: BSL-1.0 -*/ -//================================================================================================== -#pragma once - -#include -#include - -namespace eve::detail -{ -template -EVE_FORCEINLINE wide -mul_(EVE_SUPPORTS(vmx_), wide v0, wide const& v1) noexcept requires ppc_abi> -{ - return v0 *= v1; -} -} diff --git a/include/eve/module/core/regular/impl/simd/ppc/sub.hpp b/include/eve/module/core/regular/impl/simd/ppc/sub.hpp deleted file mode 100644 index b93e6640ab..0000000000 --- a/include/eve/module/core/regular/impl/simd/ppc/sub.hpp +++ /dev/null @@ -1,20 +0,0 @@ -//================================================================================================== -/* - EVE - Expressive Vector Engine - Copyright : EVE Project Contributors - SPDX-License-Identifier: BSL-1.0 -*/ -//================================================================================================== -#pragma once - -#include - -namespace eve::detail -{ -template -EVE_FORCEINLINE wide -sub_(EVE_SUPPORTS(vmx_), wide v0, wide const& v1) noexcept requires ppc_abi> -{ - return v0 -= v1; -} -} diff --git a/include/eve/module/core/regular/impl/simd/x86/add.hpp b/include/eve/module/core/regular/impl/simd/x86/add.hpp index cb56944712..e7f6dc4b68 100644 --- a/include/eve/module/core/regular/impl/simd/x86/add.hpp +++ b/include/eve/module/core/regular/impl/simd/x86/add.hpp @@ -8,47 +8,94 @@ #pragma once #include -#include - -#include +#include +#include +#include namespace eve::detail { -// ----------------------------------------------------------------------------------------------- -// Masked case -template -EVE_FORCEINLINE wide - add_(EVE_SUPPORTS(sse2_), - C const &cx, - wide const &v, - wide const &w) noexcept requires x86_abi> +template< typename T, typename N, callable_options O> +EVE_FORCEINLINE +wide add_(EVE_REQUIRES(sse2_), O const& opts, wide v, wide w) noexcept +requires x86_abi> +{ + constexpr auto c = categorize>(); + + if constexpr(O::contains(saturated2)) + { + constexpr auto sup_avx2 = current_api >= avx2; + + if constexpr( c == category::int16x32 ) return _mm512_adds_epi16(v, w); + else if constexpr( c == category::uint16x32 ) return _mm512_adds_epu16(v, w); + else if constexpr( c == category::int8x64 ) return _mm512_adds_epi8 (v, w); + else if constexpr( c == category::uint8x64 ) return _mm512_adds_epu8 (v, w); + else if constexpr( sup_avx2 && c == category::int16x16 ) return _mm256_adds_epi16(v, w); + else if constexpr( sup_avx2 && c == category::uint16x16 ) return _mm256_adds_epu16(v, w); + else if constexpr( sup_avx2 && c == category::int8x32 ) return _mm256_adds_epi8 (v, w); + else if constexpr( sup_avx2 && c == category::uint8x32 ) return _mm256_adds_epu8 (v, w); + else if constexpr( c == category::int16x8 ) return _mm_adds_epi16 (v, w); + else if constexpr( c == category::uint16x8 ) return _mm_adds_epu16 (v, w); + else if constexpr( c == category::int8x16 ) return _mm_adds_epi8 (v, w); + else if constexpr( c == category::uint8x16 ) return _mm_adds_epu8 (v, w); + else return add.behavior(cpu_{}, opts, v, w); + } + else + { + return add.behavior(cpu_{}, opts, v, w); + } +} + +template +EVE_FORCEINLINE +wide add_(EVE_REQUIRES(avx512_), C cx, O const& opts, wide v, wide w) noexcept +requires x86_abi> { constexpr auto c = categorize>(); - if constexpr( C::is_complete || abi_t::is_wide_logical ) + auto src = alternative(cx, v, as> {}); + auto m = expand_mask(cx, as> {}).storage().value; + + if constexpr(O::contains(saturated2)) { - return add_(EVE_RETARGET(cpu_), cx, v, w); + constexpr auto sup_avx2 = current_api >= avx2; + + if constexpr( floating_value ) return add[cx](v, w); + else if constexpr( c == category::int16x32 ) return _mm512_mask_adds_epi16(src, m, v, w); + else if constexpr( c == category::uint16x32 ) return _mm512_mask_adds_epu16(src, m, v, w); + else if constexpr( c == category::int8x64 ) return _mm512_mask_adds_epi8(src, m, v, w); + else if constexpr( c == category::uint8x64 ) return _mm512_mask_adds_epu8(src, m, v, w); + else if constexpr( sup_avx2 && c == category::int16x16 ) return _mm256_mask_adds_epi16(src, m, v, w); + else if constexpr( sup_avx2 && c == category::uint16x16 ) return _mm256_mask_adds_epu16(src, m, v, w); + else if constexpr( sup_avx2 && c == category::int8x32 ) return _mm256_mask_adds_epi8(src, m, v, w); + else if constexpr( sup_avx2 && c == category::uint8x32 ) return _mm256_mask_adds_epu8(src, m, v, w); + else if constexpr( c == category::int16x8 ) return _mm_mask_adds_epi16(src, m, v, w); + else if constexpr( c == category::uint16x8 ) return _mm_mask_adds_epu16(src, m, v, w); + else if constexpr( c == category::int8x16 ) return _mm_mask_adds_epi8(src, m, v, w); + else if constexpr( c == category::uint8x16 ) return _mm_mask_adds_epu8(src, m, v, w); + else return add.behavior(cpu_{}, opts, v, w); } else { - auto src = alternative(cx, v, as> {}); - auto m = expand_mask(cx, as> {}).storage().value; - - if constexpr( c == category::float32x16 ) return _mm512_mask_add_ps(src, m, v, w); - else if constexpr( c == category::float64x8 ) return _mm512_mask_add_pd(src, m, v, w); - else if constexpr( c == category::int8x64 ) return _mm512_mask_add_epi8(src, m, v, w); - else if constexpr( c == category::int8x32 ) return _mm256_mask_add_epi8(src, m, v, w); - else if constexpr( c == category::int8x16 ) return _mm_mask_add_epi8(src, m, v, w); - else if constexpr( c == category::int16x32 ) return _mm512_mask_add_epi16(src, m, v, w); - else if constexpr( c == category::int16x16 ) return _mm256_mask_add_epi16(src, m, v, w); - else if constexpr( c == category::int16x8 ) return _mm_mask_add_epi16(src, m, v, w); - else if constexpr( c == category::int32x16 ) return _mm512_mask_add_epi32(src, m, v, w); - else if constexpr( c == category::int32x8 ) return _mm256_mask_add_epi32(src, m, v, w); - else if constexpr( c == category::int32x4 ) return _mm_mask_add_epi32(src, m, v, w); - else if constexpr( c == category::int64x8 ) return _mm512_mask_add_epi64(src, m, v, w); - else if constexpr( c == category::int64x4 ) return _mm256_mask_add_epi64(src, m, v, w); - else if constexpr( c == category::int64x2 ) return _mm_mask_add_epi64(src, m, v, w); - else return add_(EVE_RETARGET(cpu_), cx, v, w); + if constexpr( c == category::float32x16) return _mm512_mask_add_ps (src, m, v, w); + else if constexpr( c == category::float32x8 ) return _mm256_mask_add_ps (src, m, v, w); + else if constexpr( c == category::float32x4 ) return _mm_mask_add_ps (src, m, v, w); + else if constexpr( c == category::float64x8 ) return _mm512_mask_add_pd (src, m, v, w); + else if constexpr( c == category::float64x4 ) return _mm256_mask_add_pd (src, m, v, w); + else if constexpr( c == category::float64x2 ) return _mm_mask_add_pd (src, m, v, w); + else if constexpr( match(c,category::int64x8 , category::uint64x8) ) return _mm512_mask_add_epi64(src, m, v, w); + else if constexpr( match(c,category::int64x4 , category::uint64x4) ) return _mm256_mask_add_epi64(src, m, v, w); + else if constexpr( match(c,category::int64x2 , category::uint64x2) ) return _mm_mask_add_epi64 (src, m, v, w); + else if constexpr( match(c,category::int32x16, category::uint32x16) ) return _mm512_mask_add_epi32(src, m, v, w); + else if constexpr( match(c,category::int32x8 , category::uint32x8 ) ) return _mm256_mask_add_epi32(src, m, v, w); + else if constexpr( match(c,category::int32x4 , category::uint32x4 ) ) return _mm_mask_add_epi32 (src, m, v, w); + else if constexpr( match(c,category::int64x2 , category::uint64x2) ) return _mm_mask_add_epi64 (src, m, v, w); + else if constexpr( match(c,category::int16x32, category::uint16x32) ) return _mm512_mask_add_epi16(src, m, v, w); + else if constexpr( match(c,category::int16x16, category::uint16x16) ) return _mm256_mask_add_epi16(src, m, v, w); + else if constexpr( match(c,category::int16x8 , category::uint16x8 ) ) return _mm_mask_add_epi16 (src, m, v, w); + else if constexpr( match(c,category::int8x64 , category::uint8x64 ) ) return _mm512_mask_add_epi8 (src, m, v, w); + else if constexpr( match(c,category::int8x32 , category::uint8x32 ) ) return _mm256_mask_add_epi8 (src, m, v, w); + else if constexpr( match(c,category::int8x16 , category::uint8x16 ) ) return _mm_mask_add_epi8 (src, m, v, w); + else return add.behavior(cpu_{}, opts, v, w); } } diff --git a/include/eve/module/core/regular/impl/simd/x86/mul.hpp b/include/eve/module/core/regular/impl/simd/x86/mul.hpp index 4695cf089e..80e6963fa1 100644 --- a/include/eve/module/core/regular/impl/simd/x86/mul.hpp +++ b/include/eve/module/core/regular/impl/simd/x86/mul.hpp @@ -9,29 +9,29 @@ namespace eve::detail { -// ----------------------------------------------------------------------------------------------- -// Masked case -template -EVE_FORCEINLINE wide - mul_(EVE_SUPPORTS(sse2_), - C const &cx, - wide const &v, - wide const &w) noexcept requires x86_abi> -{ - constexpr auto c = categorize>(); - - if constexpr( C::is_complete || abi_t::is_wide_logical ) - { - return mul_(EVE_RETARGET(cpu_), cx, v, w); - } - else + template + EVE_FORCEINLINE + wide mul_(EVE_REQUIRES(avx512_), C cx, O const& opts, wide v, wide w) noexcept + requires x86_abi> { + constexpr auto c = categorize>(); + auto src = alternative(cx, v, as> {}); auto m = expand_mask(cx, as> {}).storage().value; - if constexpr( c == category::float32x16 ) return _mm512_mask_mul_ps(src, m, v, w); - else if constexpr( c == category::float64x8 ) return _mm512_mask_mul_pd(src, m, v, w); - else return mul_(EVE_RETARGET(cpu_), cx, v, w); + if constexpr(O::contains(saturated2) && integral_value) + { + return mul.behavior(cpu_{}, opts, v, w); + } + else + { + if constexpr( c == category::float32x16) return _mm512_mask_mul_ps (src, m, v, w); + else if constexpr( c == category::float32x8 ) return _mm256_mask_mul_ps (src, m, v, w); + else if constexpr( c == category::float32x4 ) return _mm_mask_mul_ps (src, m, v, w); + else if constexpr( c == category::float64x8 ) return _mm512_mask_mul_pd (src, m, v, w); + else if constexpr( c == category::float64x4 ) return _mm256_mask_mul_pd (src, m, v, w); + else if constexpr( c == category::float64x2 ) return _mm_mask_mul_pd (src, m, v, w); + else return mul.behavior(cpu_{}, opts, v, w); + } } } -} diff --git a/include/eve/module/core/regular/impl/simd/x86/sub.hpp b/include/eve/module/core/regular/impl/simd/x86/sub.hpp index ecdaae5c8e..4de1ca2324 100644 --- a/include/eve/module/core/regular/impl/simd/x86/sub.hpp +++ b/include/eve/module/core/regular/impl/simd/x86/sub.hpp @@ -8,48 +8,94 @@ #pragma once #include -#include - -#include +#include +#include +#include namespace eve::detail { -// ----------------------------------------------------------------------------------------------- -// Masked case -template -EVE_FORCEINLINE wide - sub_(EVE_SUPPORTS(sse2_), - C const &cx, - wide const &v, - wide const &w) noexcept requires x86_abi> -{ - constexpr auto c = categorize>(); - - if constexpr( C::is_complete || abi_t::is_wide_logical ) + template< typename T, typename N, callable_options O> + EVE_FORCEINLINE + wide sub_(EVE_REQUIRES(sse2_), O const& opts, wide v, wide w) noexcept + requires x86_abi> { - return sub_(EVE_RETARGET(cpu_), cx, v, w); + constexpr auto c = categorize>(); + + if constexpr(O::contains(saturated2)) + { + constexpr auto sup_avx2 = current_api >= avx2; + + if constexpr( c == category::int16x32 ) return _mm512_subs_epi16(v, w); + else if constexpr( c == category::uint16x32 ) return _mm512_subs_epu16(v, w); + else if constexpr( c == category::int8x64 ) return _mm512_subs_epi8 (v, w); + else if constexpr( c == category::uint8x64 ) return _mm512_subs_epu8 (v, w); + else if constexpr( sup_avx2 && c == category::int16x16 ) return _mm256_subs_epi16(v, w); + else if constexpr( sup_avx2 && c == category::uint16x16 ) return _mm256_subs_epu16(v, w); + else if constexpr( sup_avx2 && c == category::int8x32 ) return _mm256_subs_epi8 (v, w); + else if constexpr( sup_avx2 && c == category::uint8x32 ) return _mm256_subs_epu8 (v, w); + else if constexpr( c == category::int16x8 ) return _mm_subs_epi16 (v, w); + else if constexpr( c == category::uint16x8 ) return _mm_subs_epu16 (v, w); + else if constexpr( c == category::int8x16 ) return _mm_subs_epi8 (v, w); + else if constexpr( c == category::uint8x16 ) return _mm_subs_epu8 (v, w); + else return sub.behavior(cpu_{}, opts, v, w); + } + else + { + return sub.behavior(cpu_{}, opts, v, w); + } } - else + + template + EVE_FORCEINLINE + wide sub_(EVE_REQUIRES(avx512_), C cx, O const& opts, wide v, wide w) noexcept + requires x86_abi> { + constexpr auto c = categorize>(); + auto src = alternative(cx, v, as> {}); auto m = expand_mask(cx, as> {}).storage().value; - if constexpr( c == category::float32x16 ) return _mm512_mask_sub_ps(src, m, v, w); - else if constexpr( c == category::float64x8 ) return _mm512_mask_sub_pd(src, m, v, w); - else if constexpr( c == category::int8x64 ) return _mm512_mask_sub_epi8(src, m, v, w); - else if constexpr( c == category::int8x32 ) return _mm256_mask_sub_epi8(src, m, v, w); - else if constexpr( c == category::int8x16 ) return _mm_mask_sub_epi8(src, m, v, w); - else if constexpr( c == category::int16x32 ) return _mm512_mask_sub_epi16(src, m, v, w); - else if constexpr( c == category::int16x16 ) return _mm256_mask_sub_epi16(src, m, v, w); - else if constexpr( c == category::int16x8 ) return _mm_mask_sub_epi16(src, m, v, w); - else if constexpr( c == category::int32x16 ) return _mm512_mask_sub_epi32(src, m, v, w); - else if constexpr( c == category::int32x8 ) return _mm256_mask_sub_epi32(src, m, v, w); - else if constexpr( c == category::int32x4 ) return _mm_mask_sub_epi32(src, m, v, w); - else if constexpr( c == category::int64x8 ) return _mm512_mask_sub_epi64(src, m, v, w); - else if constexpr( c == category::int64x4 ) return _mm256_mask_sub_epi64(src, m, v, w); - else if constexpr( c == category::int64x2 ) return _mm_mask_sub_epi64(src, m, v, w); - else return sub_(EVE_RETARGET(cpu_), cx, v, w); - } -} + if constexpr(O::contains(saturated2)) + { + constexpr auto sup_avx2 = current_api >= avx2; + if constexpr( floating_value ) return sub[cx](v, w); + else if constexpr( c == category::int16x32 ) return _mm512_mask_subs_epi16(src, m, v, w); + else if constexpr( c == category::uint16x32 ) return _mm512_mask_subs_epu16(src, m, v, w); + else if constexpr( c == category::int8x64 ) return _mm512_mask_subs_epi8(src, m, v, w); + else if constexpr( c == category::uint8x64 ) return _mm512_mask_subs_epu8(src, m, v, w); + else if constexpr( sup_avx2 && c == category::int16x16 ) return _mm256_mask_subs_epi16(src, m, v, w); + else if constexpr( sup_avx2 && c == category::uint16x16 ) return _mm256_mask_subs_epu16(src, m, v, w); + else if constexpr( sup_avx2 && c == category::int8x32 ) return _mm256_mask_subs_epi8(src, m, v, w); + else if constexpr( sup_avx2 && c == category::uint8x32 ) return _mm256_mask_subs_epu8(src, m, v, w); + else if constexpr( c == category::int16x8 ) return _mm_mask_subs_epi16(src, m, v, w); + else if constexpr( c == category::uint16x8 ) return _mm_mask_subs_epu16(src, m, v, w); + else if constexpr( c == category::int8x16 ) return _mm_mask_subs_epi8(src, m, v, w); + else if constexpr( c == category::uint8x16 ) return _mm_mask_subs_epu8(src, m, v, w); + else return sub.behavior(cpu_{}, opts, v, w); + } + else + { + if constexpr( c == category::float32x16) return _mm512_mask_sub_ps (src, m, v, w); + else if constexpr( c == category::float32x8 ) return _mm256_mask_sub_ps (src, m, v, w); + else if constexpr( c == category::float32x4 ) return _mm_mask_sub_ps (src, m, v, w); + else if constexpr( c == category::float64x8 ) return _mm512_mask_sub_pd (src, m, v, w); + else if constexpr( c == category::float64x4 ) return _mm256_mask_sub_pd (src, m, v, w); + else if constexpr( c == category::float64x2 ) return _mm_mask_sub_pd (src, m, v, w); + else if constexpr( match(c,category::int64x8 , category::uint64x8) ) return _mm512_mask_sub_epi64(src, m, v, w); + else if constexpr( match(c,category::int64x4 , category::uint64x4) ) return _mm256_mask_sub_epi64(src, m, v, w); + else if constexpr( match(c,category::int64x2 , category::uint64x2) ) return _mm_mask_sub_epi64 (src, m, v, w); + else if constexpr( match(c,category::int32x16, category::uint32x16) ) return _mm512_mask_sub_epi32(src, m, v, w); + else if constexpr( match(c,category::int32x8 , category::uint32x8 ) ) return _mm256_mask_sub_epi32(src, m, v, w); + else if constexpr( match(c,category::int32x4 , category::uint32x4 ) ) return _mm_mask_sub_epi32 (src, m, v, w); + else if constexpr( match(c,category::int64x2 , category::uint64x2) ) return _mm_mask_sub_epi64 (src, m, v, w); + else if constexpr( match(c,category::int16x32, category::uint16x32) ) return _mm512_mask_sub_epi16(src, m, v, w); + else if constexpr( match(c,category::int16x16, category::uint16x16) ) return _mm256_mask_sub_epi16(src, m, v, w); + else if constexpr( match(c,category::int16x8 , category::uint16x8 ) ) return _mm_mask_sub_epi16 (src, m, v, w); + else if constexpr( match(c,category::int8x64 , category::uint8x64 ) ) return _mm512_mask_sub_epi8 (src, m, v, w); + else if constexpr( match(c,category::int8x32 , category::uint8x32 ) ) return _mm256_mask_sub_epi8 (src, m, v, w); + else if constexpr( match(c,category::int8x16 , category::uint8x16 ) ) return _mm_mask_sub_epi8 (src, m, v, w); + else return sub.behavior(cpu_{}, opts, v, w); + } + } } diff --git a/include/eve/module/core/regular/impl/sub.hpp b/include/eve/module/core/regular/impl/sub.hpp index d69eaa1cbd..7ad57b2e17 100644 --- a/include/eve/module/core/regular/impl/sub.hpp +++ b/include/eve/module/core/regular/impl/sub.hpp @@ -7,66 +7,82 @@ //================================================================================================== #pragma once -#include -#include #include -#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include namespace eve::detail { + template + EVE_FORCEINLINE constexpr T sub_(EVE_REQUIRES(cpu_), O const&, T a, T b) noexcept + { + if constexpr(O::contains(saturated2) && integral_value) + { + if constexpr(scalar_value) + { + if constexpr( signed_integral_value ) + { + if constexpr( sizeof(T) >= 4 ) + { + auto test = is_ltz(b); + auto pos = min(add(valmax(as(a)), b), a); + auto neg = max(add(valmin(as(a)), b), a); + return sub(if_else(test, pos, neg), b); + } + else + { + // small scalar signed integral case uses C++ promotion + auto r = a - b; + return static_cast(saturate(r, as())); + } + } + else //unsigned + { + T r = a - b; + return static_cast(r & -(r <= a)); + } + } + else //simd + { + if constexpr( signed_integral_value ) + { + auto test = is_lez(b); + auto pos = min(add(valmax(as(a)), b), a); + auto neg = max(add(valmin(as(a)), b), a); + return sub(if_else(test, pos, neg), b); + } + else //unsigned + { + T r = a - b; + return bit_and(r, bit_mask(r <= a)); + } + } + } + else + { + return a -= b; + } + } -//================================================================================================ -// Masked case -//================================================================================================ -template -EVE_FORCEINLINE auto -sub_(EVE_SUPPORTS(cpu_), - C const& cond, - U t, - Vs ... fs) noexcept -{ - return mask_op(cond, eve::sub, t, fs...); -} - -//================================================================================================ -// N parameters -//================================================================================================ -template -auto -sub_(EVE_SUPPORTS(cpu_), D const&, T0 a0, Ts... args) noexcept -{ - common_value_t that(a0); - ((that = D()(sub)(that, args)), ...); - return that; -} - -template -auto -sub_(EVE_SUPPORTS(cpu_), T0 a0, Ts... args) noexcept --> common_value_t -{ - auto that((a0 - ... - args)); - return that; - -} - -//================================================================================================ -// tuples -//================================================================================================ -template -auto -sub_(EVE_SUPPORTS(cpu_), Ts tup) noexcept -{ - if constexpr( kumi::size_v == 1) return get<0>(tup); - else return kumi::apply( [&](auto... m) { return sub(m...); }, tup); -} - -template -auto -sub_(EVE_SUPPORTS(cpu_), D const & d, Ts tup) noexcept -{ - if constexpr( kumi::size_v == 1) return get<0>(tup); - else return kumi::apply( [&](auto... m) { return d(sub)(m...); }, tup); -} - + template... Ts, callable_options O> + EVE_FORCEINLINE constexpr T sub_(EVE_REQUIRES(cpu_), O const & o, T r0, T r1, Ts... rs) noexcept + { + r0 = sub[o](r0,r1); + ((r0 = sub[o](r0,rs)),...); + return r0; + } } diff --git a/include/eve/module/core/regular/manhattan.hpp b/include/eve/module/core/regular/manhattan.hpp index cf488bd6e1..bf6efe5b65 100644 --- a/include/eve/module/core/regular/manhattan.hpp +++ b/include/eve/module/core/regular/manhattan.hpp @@ -90,10 +90,10 @@ namespace eve { template EVE_FORCEINLINE constexpr common_value_t - manhattan_(EVE_REQUIRES(cpu_), O const & , T0 a0, T1 a1, Ts... args) noexcept + manhattan_(EVE_REQUIRES(cpu_), O const & o , T0 a0, T1 a1, Ts... args) noexcept { using r_t = common_value_t; - auto r = eve::add/*TODO[o]*/(abs(r_t(a0)), abs(r_t(a1)), abs(r_t(args))...); + auto r = eve::add[o](abs(r_t(a0)), abs(r_t(a1)), abs(r_t(args))...); if constexpr(O::contains(pedantic2)) { auto inf_found = is_infinite(r_t(a0)) || is_infinite(r_t(a1)); diff --git a/include/eve/module/core/regular/minus.hpp b/include/eve/module/core/regular/minus.hpp index d8e5aea555..d5a969d205 100644 --- a/include/eve/module/core/regular/minus.hpp +++ b/include/eve/module/core/regular/minus.hpp @@ -21,8 +21,7 @@ namespace eve struct minus_t : elementwise_callable { template - constexpr EVE_FORCEINLINE T operator()(T a) const - { return EVE_DISPATCH_CALL(a); } + constexpr EVE_FORCEINLINE T operator()(T a) const { return EVE_DISPATCH_CALL(a); } EVE_CALLABLE_OBJECT(minus_t, minus_); }; @@ -90,11 +89,9 @@ namespace eve namespace detail { template - EVE_FORCEINLINE constexpr T - minus_(EVE_REQUIRES(cpu_), O const &, T v) noexcept + EVE_FORCEINLINE constexpr T minus_(EVE_REQUIRES(cpu_), O const &, T v) noexcept { - if constexpr( floating_value ) - return bit_xor(v, signmask(eve::as(v))); + if constexpr( floating_value ) return bit_xor(v, signmask(eve::as(v))); else if constexpr(O::contains(saturated2)) { return if_else(v == valmin(as()), valmax(as()), minus(v)); @@ -102,7 +99,7 @@ namespace eve else { if constexpr( simd_value ) return -v; - else return T{0} - v; + else return T{0} - v; } } } diff --git a/include/eve/module/core/regular/mul.hpp b/include/eve/module/core/regular/mul.hpp index e805b3486c..7301e3f819 100644 --- a/include/eve/module/core/regular/mul.hpp +++ b/include/eve/module/core/regular/mul.hpp @@ -8,10 +8,28 @@ #pragma once #include -#include +#include +#include namespace eve { + template + struct mul_t : tuple_callable + { + template + EVE_FORCEINLINE constexpr common_value_t operator()(T0 t0, T1 t1, Ts...ts) const noexcept + { + return EVE_DISPATCH_CALL(t0, t1, ts...); + } + + template + EVE_FORCEINLINE constexpr + kumi::apply_traits_t + operator()(Tup const& t) const noexcept requires(kumi::size_v >= 2) { return EVE_DISPATCH_CALL(t); } + + EVE_CALLABLE_OBJECT(mul_t, mul_); + }; + //================================================================================================ //! @addtogroup core_arithmetic //! @{ @@ -60,7 +78,7 @@ namespace eve //! //! * eve::saturated //! -//! The call `saturated(mul)(args...)` computes the saturated multiplication `of the arguments. +//! The call `mul[saturated](args...)` computes the saturated multiplication `of the arguments. //! The saturation is obtained in the [common value](@ref common_value_t) //! of the N parameters. The computation is done as if all arguments were //! converted to this type and the saturated multiplication applied recursively on all @@ -68,7 +86,10 @@ namespace eve //! //! @} //================================================================================================ -EVE_MAKE_CALLABLE(mul_, mul); + inline constexpr auto mul = functor; + + // Required for optimisation detections + using callable_mul_ = tag_t; } #include @@ -77,13 +98,6 @@ EVE_MAKE_CALLABLE(mul_, mul); # include #endif -#if defined(EVE_INCLUDE_POWERPC_HEADER) -# include -#endif - -#if defined(EVE_INCLUDE_ARM_HEADER) -# include -#endif #if defined(EVE_INCLUDE_SVE_HEADER) # include diff --git a/include/eve/module/core/regular/next.hpp b/include/eve/module/core/regular/next.hpp index 6b435ae6a8..ec25e56e88 100644 --- a/include/eve/module/core/regular/next.hpp +++ b/include/eve/module/core/regular/next.hpp @@ -16,11 +16,10 @@ #include #include #include -#include #include #include #include -#include +#include #include namespace eve @@ -35,7 +34,7 @@ namespace eve template constexpr EVE_FORCEINLINE as_wide_as_t operator()(T v, N n) const noexcept { - EVE_ASSERT(eve::all(is_gez(n)), "[eve::next] : second parameter must be positive"); + EVE_ASSERT(eve::all(n >= 0), "[eve::next] : second parameter must be positive"); return EVE_DISPATCH_CALL(v, n); } diff --git a/include/eve/module/core/regular/plus.hpp b/include/eve/module/core/regular/plus.hpp deleted file mode 100644 index d77fdc369e..0000000000 --- a/include/eve/module/core/regular/plus.hpp +++ /dev/null @@ -1,57 +0,0 @@ -//================================================================================================== -/* - EVE - Expressive Vector Engine - Copyright : EVE Project Contributors - SPDX-License-Identifier: BSL-1.0 -*/ -//================================================================================================== -#pragma once - -#include - -namespace eve -{ -//================================================================================================ -//! @addtogroup core_arithmetic -//! @{ -//! @var plus -//! @brief Computes the opposite of the parameter that must be signed. -//! -//! **Defined in Header** -//! -//! @code -//! #include -//! @endcode -//! -//! @groupheader{Callable Signatures} -//! -//! @code -//! namespace eve -//! { -//! template< eve::value T > -//! T plus(T x) noexcept; -//! } -//! @endcode -//! -//! **Parameters** -//! -//! * `x` : [real](@ref eve::value) argument. -//! -//! **Return value** -//! -//! Returns x -//! -//! @note -//! Although the operator notation with `+` is supported, the `+` operator on -//! standard scalar type is the original one and so can lead to automatic promotion. -//! -//! @groupheader{Example} -//! -//! @godbolt{doc/core/plus.cpp} -//! -//! @} -//================================================================================================ -EVE_MAKE_CALLABLE(plus_, plus); -} - -#include diff --git a/include/eve/module/core/regular/sqr.hpp b/include/eve/module/core/regular/sqr.hpp index 0bce8f1f98..00635e953f 100644 --- a/include/eve/module/core/regular/sqr.hpp +++ b/include/eve/module/core/regular/sqr.hpp @@ -12,6 +12,10 @@ #include #include #include +#include +#include +#include + namespace eve { diff --git a/include/eve/module/core/regular/sub.hpp b/include/eve/module/core/regular/sub.hpp index c219365147..246664bd0f 100644 --- a/include/eve/module/core/regular/sub.hpp +++ b/include/eve/module/core/regular/sub.hpp @@ -8,10 +8,28 @@ #pragma once #include -#include +#include +#include namespace eve { + template + struct sub_t : tuple_callable + { + template + EVE_FORCEINLINE constexpr common_value_t operator()(T0 t0, T1 t1, Ts...ts) const noexcept + { + return EVE_DISPATCH_CALL(t0, t1, ts...); + } + + template + EVE_FORCEINLINE constexpr + kumi::apply_traits_t + operator()(Tup const& t) const noexcept requires(kumi::size_v >= 2) { return EVE_DISPATCH_CALL(t); } + + EVE_CALLABLE_OBJECT(sub_t, sub_); + }; + //================================================================================================ //! @addtogroup core_arithmetic //! @{ @@ -66,7 +84,8 @@ namespace eve //! //! @} //================================================================================================ -EVE_MAKE_CALLABLE(sub_, sub); + inline constexpr auto sub = functor; + } #include @@ -75,14 +94,6 @@ EVE_MAKE_CALLABLE(sub_, sub); # include #endif -#if defined(EVE_INCLUDE_POWERPC_HEADER) -# include -#endif - -#if defined(EVE_INCLUDE_ARM_HEADER) -# include -#endif - #if defined(EVE_INCLUDE_SVE_HEADER) # include #endif diff --git a/include/eve/module/core/saturated/add.hpp b/include/eve/module/core/saturated/add.hpp deleted file mode 100644 index 8b9948d8da..0000000000 --- a/include/eve/module/core/saturated/add.hpp +++ /dev/null @@ -1,19 +0,0 @@ -//================================================================================================== -/* - EVE - Expressive Vector Engine - Copyright : EVE Project Contributors - SPDX-License-Identifier: BSL-1.0 -*/ -//================================================================================================== -#pragma once - -#include -#include - -#if defined(EVE_INCLUDE_X86_HEADER) -# include -#endif - -#if defined(EVE_INCLUDE_SVE_HEADER) -# include -#endif diff --git a/include/eve/module/core/saturated/core.hpp b/include/eve/module/core/saturated/core.hpp index b7217ae15b..8e526af09a 100644 --- a/include/eve/module/core/saturated/core.hpp +++ b/include/eve/module/core/saturated/core.hpp @@ -7,10 +7,5 @@ //================================================================================================== #pragma once - -#include #include #include -#include -#include -#include diff --git a/include/eve/module/core/saturated/impl/add.hpp b/include/eve/module/core/saturated/impl/add.hpp deleted file mode 100644 index b97e0ef552..0000000000 --- a/include/eve/module/core/saturated/impl/add.hpp +++ /dev/null @@ -1,123 +0,0 @@ -//================================================================================================== -/* - EVE - Expressive Vector Engine - Copyright : EVE Project Contributors - SPDX-License-Identifier: BSL-1.0 -*/ -//================================================================================================== -#pragma once - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -namespace eve::detail -{ -//================================================================================================ -// saturated case -//================================================================================================ -template -EVE_FORCEINLINE auto -add_(EVE_SUPPORTS(cpu_), - saturated_type const&, - T const& a, - U const& b) noexcept --> decltype(add(a, b)) -{ - return arithmetic_call(saturated(add), a, b); -} - -template -EVE_FORCEINLINE auto -add_(EVE_SUPPORTS(cpu_), saturated_type const&, T const& a, T const& b) noexcept -{ - if constexpr(scalar_value) - { - if constexpr( floating_value ) { return a + b; } - else if constexpr( signed_integral_value ) - { - auto test = is_ltz(b); - auto pos = min(sub(valmax(as(a)), b), a); - auto neg = max(sub(valmin(as(a)), b), a); - return add(b, if_else(test, neg, pos)); - } - else // if constexpr( std::is_unsigned_v ) - { - if constexpr( sizeof(T) >= 4 ) - { - // large unsigned integral case - T r = a + b; - return r | -(r < a); - } - else - { - // small unsigned integral case - use C promotion then clamp - auto r = a + b; - decltype(r) mx = std::numeric_limits::max(); - return static_cast(std::min(mx, r)); - } - } - } - else //simd case - { - if constexpr(has_native_abi_v) - { - if constexpr( floating_value ) { return a + b; } - else if constexpr( integral_value ) - { - if constexpr( signed_integral_value ) - { - auto test = is_ltz(b); - auto pos = min(sub(valmax(as(a)), b), a); - auto neg = max(sub(valmin(as(a)), b), a); - return add(b, if_else(test, neg, pos)); - } - else if constexpr( unsigned_value ) - { - T r = a + b; - return bit_or(r, bit_mask(is_less(r, a))); - } - } - } - else return apply_over(saturated(add), a, b); - } -} - -//================================================================================================ -// Masked case -//================================================================================================ -template -EVE_FORCEINLINE auto -add_(EVE_SUPPORTS(cpu_), - C const& cond, - saturated_type const&, - U const& t, - V const& f) noexcept --> decltype(if_else(cond, saturated(add)(t, f), t)) -{ - return mask_op(cond, saturated(add), t, f); -} - -} diff --git a/include/eve/module/core/saturated/impl/div.hpp b/include/eve/module/core/saturated/impl/div.hpp index e496aa1b89..5fbd118528 100644 --- a/include/eve/module/core/saturated/impl/div.hpp +++ b/include/eve/module/core/saturated/impl/div.hpp @@ -23,7 +23,7 @@ #include #include #include -#include +#include #ifdef EVE_COMP_IS_MSVC # pragma warning(push) diff --git a/include/eve/module/core/saturated/impl/mul.hpp b/include/eve/module/core/saturated/impl/mul.hpp deleted file mode 100644 index 3188542e7d..0000000000 --- a/include/eve/module/core/saturated/impl/mul.hpp +++ /dev/null @@ -1,160 +0,0 @@ -//================================================================================================== -/* - EVE - Expressive Vector Engine - Copyright : EVE Project Contributors - SPDX-License-Identifier: BSL-1.0 -*/ -//================================================================================================== -#pragma once - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -namespace eve::detail -{ -//================================================================================================ -// saturated case -//================================================================================================ -template -EVE_FORCEINLINE auto -mul_(EVE_SUPPORTS(cpu_), - saturated_type const&, - T const& a, - U const& b) noexcept --> decltype(mul(a, b)) -{ - return arithmetic_call(saturated(mul), a, b); -} - -template -EVE_FORCEINLINE auto -mul_(EVE_SUPPORTS(cpu_), saturated_type const&, T const& a, T const& b) noexcept -{ - if constexpr(scalar_value) - { - if constexpr( floating_value ) { return static_cast(a * b); } - else if constexpr( std::is_signed_v ) - { - if constexpr( sizeof(T) <= 2 ) - { - using up_t = upgrade_t; - return static_cast(saturate(static_cast(a) * static_cast(b), as())); - } - else if constexpr( sizeof(T) == 4 ) - { - using un_t = std::make_unsigned_t; - using up_t = int64_t; - enum Sizee { value = sizeof(T) * 8 - 1 }; - - up_t res = up_t(a) * up_t(b); - un_t res2 = (un_t(a ^ b) >> Sizee::value) + valmax(eve::as()); - T hi = (res >> (Sizee::value + 1)); - T lo = res; - if( hi != (lo >> Sizee::value) ) res = res2; - return static_cast(res); - } - else if constexpr( sizeof(T) == 8 ) - { - using un_t = std::make_unsigned_t; - if( b == 0 || a == 0 ) return zero(eve::as()); - T sgn = bit_xor(bitofsign(a), bitofsign(b)); - if( b == valmin(eve::as()) || a == valmin(eve::as()) ) - return sgn ? valmin(eve::as()) : valmax(eve::as()); - un_t aa = eve::abs(a); - un_t bb = eve::abs(b); - auto aux = [sgn](const T& mini, const T& maxi, const un_t& amini, const un_t& amaxi) - { - un_t z = valmax(eve::as()) / amaxi; - return (z < amini) ? (sgn ? valmin(eve::as()) : valmax(eve::as())) : mini * maxi; - }; - if( bb >= aa ) return aux(a, b, aa, bb); - else return aux(b, a, bb, aa); - } - } - else if constexpr( std::is_unsigned_v ) - { - if constexpr( sizeof(T) <= 4 ) - { - using up_t = upgrade_t; - up_t res = up_t(a) * up_t(b); - return (res > valmax(eve::as())) ? valmax(eve::as()) : static_cast(res); - } - else - { - auto aux = [](const T& mini, const T& maxi) - { - T z = valmax(eve::as()) / maxi; - return (z < mini) ? valmax(eve::as()) : mini * maxi; - }; - if( b == 0 || a == 0 ) return zero(eve::as()); - if( b >= a ) return aux(a, b); - else return aux(b, a); - } - } - } - else //simd case - { - using elt_t = element_type_t; - if constexpr( floating_value ) { return a * b; } - else if constexpr( integral_value ) - { - if constexpr( sizeof(elt_t) <= 4 ) - { - using sup_t = upgrade_t; - auto z = mul(convert(a, as()), convert(b, as())); - auto s = saturate(z, as()); - return convert(s, as()); - } - else - { - auto that = map(saturated(eve::mul), a, b); - return that; - } - } - } -} - -//================================================================================================ -// N parameters -//================================================================================================ -template -auto -mul_(EVE_SUPPORTS(cpu_), saturated_type const&, T0 a0, T1 a1, Ts... args) noexcept --> decltype(mul(a0, a1, args...)) -{ - using r_t = decltype(mul(a0, a1, args...)); - r_t that(saturated(mul)(r_t(a0), r_t(a1))); - ((that = saturated(mul)(that, r_t(args))), ...); - return that; -} - -//================================================================================================ -// Masked case -//================================================================================================ -template -EVE_FORCEINLINE auto -mul_(EVE_SUPPORTS(cpu_), - C const& cond, - saturated_type const&, - U const& t, - V const& f) noexcept -->decltype(if_else(cond, mul(t, f), t)) -{ - return mask_op(cond, saturated(mul), t, f); -} -} diff --git a/include/eve/module/core/saturated/impl/plus.hpp b/include/eve/module/core/saturated/impl/plus.hpp deleted file mode 100644 index 048fdf959d..0000000000 --- a/include/eve/module/core/saturated/impl/plus.hpp +++ /dev/null @@ -1,43 +0,0 @@ -//================================================================================================== -/* - 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 auto -plus_(EVE_SUPPORTS(cpu_), - saturated_type const&, - T const& a, - U const& b) noexcept --> decltype(plus(a, b)) -{ - return saturated(add)(a, b); -} - -//================================================================================================ -// Masked case -//================================================================================================ -template -EVE_FORCEINLINE auto -plus_(EVE_SUPPORTS(cpu_), - C const& cond, - saturated_type const&, - U const& t, - V const& f) noexcept -->decltype(add(t, f)) -{ - return mask_op(cond, saturated(add), t, f); -} -} diff --git a/include/eve/module/core/saturated/impl/simd/arm/sve/add.hpp b/include/eve/module/core/saturated/impl/simd/arm/sve/add.hpp deleted file mode 100644 index 2eb218639c..0000000000 --- a/include/eve/module/core/saturated/impl/simd/arm/sve/add.hpp +++ /dev/null @@ -1,25 +0,0 @@ -//================================================================================================== -/* - 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 wide -add_(EVE_SUPPORTS(sve_), saturated_type const&, wide const& a, wide const& b) noexcept -requires sve_abi> -{ - if constexpr( std::integral ) return svqadd(a, b); - else return add(a, b); -} -} diff --git a/include/eve/module/core/saturated/impl/simd/arm/sve/sub.hpp b/include/eve/module/core/saturated/impl/simd/arm/sve/sub.hpp deleted file mode 100644 index 4ffe60ae56..0000000000 --- a/include/eve/module/core/saturated/impl/simd/arm/sve/sub.hpp +++ /dev/null @@ -1,25 +0,0 @@ -//================================================================================================== -/* - 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 wide -sub_(EVE_SUPPORTS(sve_), saturated_type const&, wide const& a, wide const& b) noexcept -requires sve_abi> -{ - if constexpr( std::integral ) return svqsub(a, b); - else return sub(a, b); -} -} diff --git a/include/eve/module/core/saturated/impl/simd/x86/add.hpp b/include/eve/module/core/saturated/impl/simd/x86/add.hpp deleted file mode 100644 index 9197a39fc5..0000000000 --- a/include/eve/module/core/saturated/impl/simd/x86/add.hpp +++ /dev/null @@ -1,97 +0,0 @@ -//================================================================================================== -/* - 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 wide - add_(EVE_SUPPORTS(sse2_), - saturated_type const &st, - wide v0, - wide v1) noexcept requires x86_abi> -{ - if constexpr( std::floating_point ) return add(v0, v1); - else if constexpr( sizeof(T) > 2 ) return add_(EVE_RETARGET(cpu_), st, v0, v1); - else if constexpr( std::same_as, x86_256_> && current_api == avx ) - return add_(EVE_RETARGET(cpu_), st, v0, v1); - else if constexpr( std::signed_integral && sizeof(T) == 1 ) - { - if constexpr( std::same_as, x86_512_> ) return _mm512_adds_epi8(v0, v1); - else if constexpr( std::same_as, x86_256_> ) return _mm256_adds_epi8(v0, v1); - else if constexpr( std::same_as, x86_128_> ) return _mm_adds_epi8(v0, v1); - } - else if constexpr( std::signed_integral && sizeof(T) == 2 ) - { - if constexpr( std::same_as, x86_512_> ) return _mm512_adds_epi16(v0, v1); - else if constexpr( std::same_as, x86_256_> ) return _mm256_adds_epi16(v0, v1); - else if constexpr( std::same_as, x86_128_> ) return _mm_adds_epi16(v0, v1); - } - else if constexpr( std::unsigned_integral && sizeof(T) == 1 ) - { - if constexpr( std::same_as, x86_512_> ) return _mm512_adds_epu8(v0, v1); - else if constexpr( std::same_as, x86_256_> ) return _mm256_adds_epu8(v0, v1); - else if constexpr( std::same_as, x86_128_> ) return _mm_adds_epu8(v0, v1); - } - else if constexpr( std::unsigned_integral && sizeof(T) == 2 ) - { - if constexpr( std::same_as, x86_512_> ) return _mm512_adds_epu16(v0, v1); - else if constexpr( std::same_as, x86_256_> ) return _mm256_adds_epu16(v0, v1); - else if constexpr( std::same_as, x86_128_> ) return _mm_adds_epu16(v0, v1); - } -} - -// ----------------------------------------------------------------------------------------------- -// Masked case -template -EVE_FORCEINLINE wide - add_(EVE_SUPPORTS(sse2_), - C const &cx, - saturated_type st, - wide const &v, - wide const &w) noexcept requires x86_abi> -{ - constexpr auto c = categorize>(); - - if constexpr( C::is_complete || abi_t::is_wide_logical ) - { - return add_(EVE_RETARGET(cpu_), cx, st, v, w); - } - else - { - auto src = alternative(cx, v, as> {}); - auto m = expand_mask(cx, as> {}).storage().value; - - if constexpr( std::is_floating_point_v ) return add[cx](v, w); - else if constexpr( c == category::int16x32 ) return _mm512_mask_adds_epi16(src, m, v, w); - else if constexpr( c == category::uint16x32 ) return _mm512_mask_adds_epu16(src, m, v, w); - else if constexpr( c == category::int8x64 ) return _mm512_mask_adds_epi8(src, m, v, w); - else if constexpr( c == category::uint8x64 ) return _mm512_mask_adds_epu8(src, m, v, w); - else if constexpr( current_api >= avx2 && c == category::int16x16 ) - return _mm256_mask_adds_epi16(src, m, v, w); - else if constexpr( current_api >= avx2 && c == category::uint16x16 ) - return _mm256_mask_adds_epu16(src, m, v, w); - else if constexpr( current_api >= avx2 && c == category::int8x32 ) - return _mm256_mask_adds_epi8(src, m, v, w); - else if constexpr( current_api >= avx2 && c == category::uint8x32 ) - return _mm256_mask_adds_epu8(src, m, v, w); - else if constexpr( c == category::int16x8 ) return _mm_mask_adds_epi16(src, m, v, w); - else if constexpr( c == category::uint16x8 ) return _mm_mask_adds_epu16(src, m, v, w); - else if constexpr( c == category::int8x16 ) return _mm_mask_adds_epi8(src, m, v, w); - else if constexpr( c == category::uint8x16 ) return _mm_mask_adds_epu8(src, m, v, w); - else return if_else(cx, eve::add(st, v, w), src); - } -} - -} diff --git a/include/eve/module/core/saturated/impl/simd/x86/sub.hpp b/include/eve/module/core/saturated/impl/simd/x86/sub.hpp deleted file mode 100644 index adca5daa6a..0000000000 --- a/include/eve/module/core/saturated/impl/simd/x86/sub.hpp +++ /dev/null @@ -1,90 +0,0 @@ -//================================================================================================== -/* - 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 wide - sub_(EVE_SUPPORTS(sse2_), - saturated_type st, - wide v0, - wide v1) noexcept requires x86_abi> -{ - constexpr auto c = categorize>(); - - if constexpr( std::is_floating_point_v ) return sub(v0, v1); - else if constexpr( c == category::int16x32 ) return _mm512_subs_epi16(v0, v1); - else if constexpr( c == category::uint16x32 ) return _mm512_subs_epu16(v0, v1); - else if constexpr( c == category::int8x64 ) return _mm512_subs_epi8(v0, v1); - else if constexpr( c == category::uint8x64 ) return _mm512_subs_epu8(v0, v1); - else if constexpr( current_api >= avx2 && c == category::int16x16 ) - return _mm256_subs_epi16(v0, v1); - else if constexpr( current_api >= avx2 && c == category::uint16x16 ) - return _mm256_subs_epu16(v0, v1); - else if constexpr( current_api >= avx2 && c == category::int8x32 ) - return _mm256_subs_epi8(v0, v1); - else if constexpr( current_api >= avx2 && c == category::uint8x32 ) - return _mm256_subs_epu8(v0, v1); - else if constexpr( c == category::int16x8 ) return _mm_subs_epi16(v0, v1); - else if constexpr( c == category::uint16x8 ) return _mm_subs_epu16(v0, v1); - else if constexpr( c == category::int8x16 ) return _mm_subs_epi8(v0, v1); - else if constexpr( c == category::uint8x16 ) return _mm_subs_epu8(v0, v1); - else return sub_(EVE_RETARGET(cpu_), st, v0, v1); -} - -// ----------------------------------------------------------------------------------------------- -// Masked case -template -EVE_FORCEINLINE wide - sub_(EVE_SUPPORTS(sse2_), - C const &cx, - saturated_type st, - wide const &v, - wide const &w) noexcept requires x86_abi> -{ - constexpr auto c = categorize>(); - - if constexpr( C::is_complete || abi_t::is_wide_logical ) - { - return sub_(EVE_RETARGET(cpu_), cx, st, v, w); - } - else - { - auto src = alternative(cx, v, as> {}); - auto m = expand_mask(cx, as> {}).storage().value; - - if constexpr( std::is_floating_point_v ) return sub[cx](v, w); - else if constexpr( c == category::int16x32 ) return _mm512_mask_subs_epi16(src, m, v, w); - else if constexpr( c == category::uint16x32 ) return _mm512_mask_subs_epu16(src, m, v, w); - else if constexpr( c == category::int8x64 ) return _mm512_mask_subs_epi8(src, m, v, w); - else if constexpr( c == category::uint8x64 ) return _mm512_mask_subs_epu8(src, m, v, w); - else if constexpr( current_api >= avx2 && c == category::int16x16 ) - return _mm256_mask_subs_epi16(src, m, v, w); - else if constexpr( current_api >= avx2 && c == category::uint16x16 ) - return _mm256_mask_subs_epu16(src, m, v, w); - else if constexpr( current_api >= avx2 && c == category::int8x32 ) - return _mm256_mask_subs_epi8(src, m, v, w); - else if constexpr( current_api >= avx2 && c == category::uint8x32 ) - return _mm256_mask_subs_epu8(src, m, v, w); - else if constexpr( c == category::int16x8 ) return _mm_mask_subs_epi16(src, m, v, w); - else if constexpr( c == category::uint16x8 ) return _mm_mask_subs_epu16(src, m, v, w); - else if constexpr( c == category::int8x16 ) return _mm_mask_subs_epi8(src, m, v, w); - else if constexpr( c == category::uint8x16 ) return _mm_mask_subs_epu8(src, m, v, w); - else return if_else(cx, eve::sub(st, v, w), src); - } -} - -} diff --git a/include/eve/module/core/saturated/impl/sub.hpp b/include/eve/module/core/saturated/impl/sub.hpp deleted file mode 100644 index caeb701141..0000000000 --- a/include/eve/module/core/saturated/impl/sub.hpp +++ /dev/null @@ -1,121 +0,0 @@ -//================================================================================================== -/* - EVE - Expressive Vector Engine - Copyright : EVE Project Contributors - SPDX-License-Identifier: BSL-1.0 -*/ -//================================================================================================== -#pragma once - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -namespace eve::detail -{ -//================================================================================================ -// saturated case -//================================================================================================ -template -EVE_FORCEINLINE auto -sub_(EVE_SUPPORTS(cpu_), - saturated_type const&, - T const& a, - U const& b) noexcept --> decltype(sub(a, b)) -{ - return arithmetic_call(saturated(sub), a, b); -} - -template -EVE_FORCEINLINE auto -sub_(EVE_SUPPORTS(cpu_), saturated_type const&, T const& a, T const& b) noexcept -{ - if constexpr(scalar_value) - { - if constexpr( floating_value ) { return a - b; } - else if constexpr( signed_integral_value ) - { - if constexpr( sizeof(T) >= 4 ) - { - auto test = is_ltz(b); - auto pos = min(add(valmax(as(a)), b), a); - auto neg = max(add(valmin(as(a)), b), a); - return sub(if_else(test, pos, neg), b); - } - else - { - // small signed integral case - auto r = a - b; - return static_cast(saturate(r, as())); - } - } - else if constexpr( unsigned_value ) - { - T r = a - b; - return static_cast(r & -(r <= a)); - } - } - else - { - if constexpr (has_native_abi_v) - { - if constexpr( floating_value ) { return a - b; } - else if constexpr( integral_value ) - { - if constexpr( signed_integral_value ) - { - auto test = is_lez(b); - auto pos = min(add(valmax(as(a)), b), a); - auto neg = max(add(valmin(as(a)), b), a); - return sub(if_else(test, pos, neg), b); - } - else if constexpr( unsigned_value ) - { - T r = a - b; - return bit_and(r, bit_mask(is_less_equal(r, a))); - } - } - } - else - return apply_over(saturated(sub), a, b); - } -} - -//================================================================================================ -// Masked case -//================================================================================================ -template -EVE_FORCEINLINE auto -sub_(EVE_SUPPORTS(cpu_), - C const& cond, - saturated_type const&, - U const& t, - V const& f) noexcept --> decltype(if_else(cond, sub(t, f), t)) -{ - return mask_op(cond, saturated(sub), t, f); -} -} diff --git a/include/eve/module/core/saturated/mul.hpp b/include/eve/module/core/saturated/mul.hpp deleted file mode 100644 index abe7483988..0000000000 --- a/include/eve/module/core/saturated/mul.hpp +++ /dev/null @@ -1,11 +0,0 @@ -//================================================================================================== -/* - EVE - Expressive Vector Engine - Copyright : EVE Project Contributors - SPDX-License-Identifier: BSL-1.0 -*/ -//================================================================================================== -#pragma once - -#include -#include diff --git a/include/eve/module/core/saturated/plus.hpp b/include/eve/module/core/saturated/plus.hpp deleted file mode 100644 index 62d299b877..0000000000 --- a/include/eve/module/core/saturated/plus.hpp +++ /dev/null @@ -1,11 +0,0 @@ -//================================================================================================== -/* - EVE - Expressive Vector Engine - Copyright : EVE Project Contributors - SPDX-License-Identifier: BSL-1.0 -*/ -//================================================================================================== -#pragma once - -#include -#include diff --git a/include/eve/module/core/saturated/sub.hpp b/include/eve/module/core/saturated/sub.hpp deleted file mode 100644 index 183a41e494..0000000000 --- a/include/eve/module/core/saturated/sub.hpp +++ /dev/null @@ -1,20 +0,0 @@ -//================================================================================================== -/* - EVE - Expressive Vector Engine - Copyright : EVE Project Contributors - SPDX-License-Identifier: BSL-1.0 -*/ -//================================================================================================== -#pragma once - -#include -#include - -#if defined(EVE_INCLUDE_X86_HEADER) -# include -#endif - -#if defined(EVE_INCLUDE_SVE_HEADER) -# include -#endif - diff --git a/include/eve/module/math/regular/nthroot.hpp b/include/eve/module/math/regular/nthroot.hpp index 3ee2b45121..d0b924e02f 100644 --- a/include/eve/module/math/regular/nthroot.hpp +++ b/include/eve/module/math/regular/nthroot.hpp @@ -84,7 +84,6 @@ namespace eve return nthroot[o](x,convert(n, as())); } - template EVE_FORCEINLINE constexpr common_value_t nthroot_(EVE_REQUIRES(cpu_), O const &, T xx, U nn) noexcept diff --git a/include/eve/traits/overload/default_behaviors.hpp b/include/eve/traits/overload/default_behaviors.hpp index 0477856f40..1c0a5c8d91 100644 --- a/include/eve/traits/overload/default_behaviors.hpp +++ b/include/eve/traits/overload/default_behaviors.hpp @@ -233,13 +233,13 @@ namespace eve using base_t = strict_elementwise_callable; template - constexpr auto behavior(auto arch, O const& opts, T const& x) const + constexpr EVE_FORCEINLINE auto behavior(auto arch, O const& opts, T const& x) const { return kumi::apply( [&](auto... a) { return static_cast(*this).behavior(arch,opts,a...); }, x); } template - constexpr auto behavior(auto arch, O const& opts, T const& x0, Ts const&... xs) const + constexpr EVE_FORCEINLINE auto behavior(auto arch, O const& opts, T const& x0, Ts const&... xs) const { return base_t::behavior(arch,opts,x0,xs...); } @@ -256,13 +256,13 @@ namespace eve using base_t = elementwise_callable; template - constexpr auto behavior(auto arch, O const& opts, T const& x) const + constexpr EVE_FORCEINLINE auto behavior(auto arch, O const& opts, T const& x) const { return kumi::apply( [&](auto... a) { return static_cast(*this).behavior(arch,opts,a...); }, x); } template - constexpr auto behavior(auto arch, O const& opts, T const& x0, Ts const&... xs) const + constexpr EVE_FORCEINLINE auto behavior(auto arch, O const& opts, T const& x0, Ts const&... xs) const { return base_t::behavior(arch,opts,x0,xs...); } diff --git a/test/doc/core/add.cpp b/test/doc/core/add.cpp index a5fbf9663a..6980b5a628 100644 --- a/test/doc/core/add.cpp +++ b/test/doc/core/add.cpp @@ -15,7 +15,7 @@ int main() << " -> add(pi, qi) = " << eve::add(pi, qi) << '\n' << " -> pi + qi = " << pi + qi << '\n' << " -> add[pi < qi](pi, qi) = " << eve::add[pi < qi](pi, qi) << '\n' - << " -> saturated(add)(pi, qi) = " << eve::saturated(eve::add)(pi, qi) << '\n' + << " -> add[saturated](pi, qi) = " << eve::add[eve::saturated](pi, qi) << '\n' << " -> pf + qf = " << pf + qf << '\n'; std::int16_t xi = 100, yi = 32700; @@ -33,6 +33,6 @@ int main() << " -> add(kumi::tuple{pf, pf}) = " << eve::add( kumi::tuple{pf, pf}) << '\n' << " -> add(kumi::tuple{pf, 1.0f) = " << eve::add( kumi::tuple{pf, 1.0f}) << '\n' << " -> add(kumi::tuple{1.0f, pf) = " << eve::add( kumi::tuple{1.0f, pf}) << '\n' - << " -> saturated(add)(pi,12,pi,pi) = " << eve::saturated(eve::add)(pi, 12, pi,pi) << '\n'; + << " -> add[saturated](pi,12,pi,pi) = " << eve::add[eve::saturated](pi, 12, pi,pi) << '\n'; return 0; } diff --git a/test/doc/core/ifnot_else.cpp b/test/doc/core/ifnot_else.cpp deleted file mode 100644 index 02e0e60bc8..0000000000 --- a/test/doc/core/ifnot_else.cpp +++ /dev/null @@ -1,41 +0,0 @@ -#include -#include -#include - -using iT = std::int32_t; -using wide_it = eve::wide>; -using wide_lt = eve::as_logical_t; - -int main() -{ - wide_it pi = {3, -2, -10, 0}; - wide_it qi = {4, -1, 0, 5}; - wide_it si = {2, -3, 0, 4}; - wide_lt lsi = {true, false, false, true}; - - std::cout << "---- simd" << '\n' - << " <- si = " << si << '\n' - << " <- lsi = " << lsi << '\n' - << " <- pi = " << pi << '\n' - << " <- qi = " << qi << '\n' - << " -> eve::ifnot_else(si, pi, qi) = " << eve::ifnot_else(si, pi, qi) << '\n' - << " -> eve::ifnot_else(lsi, pi, qi) = " << eve::ifnot_else(lsi, pi, qi) << '\n'; -// TODO or suppress ifnot_else -// << " -> eve::ifnot_else(lsi, pi, allbits) = " << eve::ifnot_else(lsi, pi, eve::allbits) << '\n' -// << " -> eve::ifnot_else(lsi, pi, one) = " << eve::ifnot_else(lsi, pi, eve::one) << '\n' -// << " -> eve::ifnot_else(lsi, pi, mone) = " << eve::ifnot_else(lsi, pi, eve::mone) << '\n' -// << " -> eve::ifnot_else(lsi, pi, zero) = " << eve::ifnot_else(lsi, pi, eve::zero) << '\n'; - - - iT ssi = 3, xi = 3, yi = 4; - eve::logical lssi = false; - - std::cout << "---- scalar" << '\n' - << " ssi = = " << ssi << '\n' - << " lssi = = " << lssi << '\n' - << " xi = = " << xi << '\n' - << " yi = = " << yi << '\n' - << " -> eve::ifnot_else(ssi, xi, yi) = " << eve::ifnot_else(ssi, xi, yi) << '\n' - << " -> eve::ifnot_else(lssi, xi, yi) = " << eve::ifnot_else(lssi, xi, yi) << '\n'; - return 0; -} diff --git a/test/doc/core/minus.cpp b/test/doc/core/minus.cpp index f188e68192..943948536a 100644 --- a/test/doc/core/minus.cpp +++ b/test/doc/core/minus.cpp @@ -16,7 +16,7 @@ int main() << "<- pi = " << pi << '\n' << "-> minus(pi) = " << eve::minus(pi) << '\n' - << "-> minus[saturated(](pi) = " << eve::minus[eve::saturated](pf) << '\n' + << "-> minus[saturated](pi) = " << eve::minus[eve::saturated](pf) << '\n' << "-> minus[pf > -2](pf) = " << eve::minus[pf > -2](pf) << '\n'; float xf = -32768.0f; diff --git a/test/doc/core/mul.cpp b/test/doc/core/mul.cpp index a873f7bf2b..5e9fcd34db 100644 --- a/test/doc/core/mul.cpp +++ b/test/doc/core/mul.cpp @@ -14,13 +14,13 @@ int main() << " <- qi = " << qi << '\n' << " -> mul(pi, qi) = " << eve::mul(pi, qi) << '\n' << " -> pi * qi = " << pi * qi << '\n' - << " -> saturated(mul)((pi, qi) = " << eve::saturated(eve::mul)(pi, qi) << '\n' + << " -> mul[saturated]((pi, qi) = " << eve::mul[eve::saturated](pi, qi) << '\n' << " <- pf = " << pf << '\n' << " <- qf = " << qf << '\n' << " -> mul(pf, qf) = " << eve::mul(pf, qf) << '\n' << " -> pf * qf = " << pf * qf << '\n' << " -> mul[qi > 0](pi, qi) = " << eve::mul[qi > 0](pi, qi) << '\n'; - + std::int16_t xi = 100, yi = 32700; std::cout << "---- scalar" << '\n' @@ -36,6 +36,6 @@ int main() << " -> mul(kumi::tuple{pf, pf}) = " << eve::mul( kumi::tuple{pf, pf}) << '\n' << " -> mul(kumi::tuple{pf, 1.0f) = " << eve::mul( kumi::tuple{pf, 1.0f}) << '\n' << " -> mul(kumi::tuple{1.0f, pf) = " << eve::mul( kumi::tuple{1.0f, pf}) << '\n' - << " -> saturated(mul)(pi,12,pi,pi) = " << eve::saturated(eve::mul)(pi, 12, pi,pi) << '\n'; + << " -> mul[saturated](pi,12,pi,pi) = " << eve::mul[eve::saturated](pi, 12, pi,pi) << '\n'; return 0; } diff --git a/test/doc/core/plus.cpp b/test/doc/core/plus.cpp deleted file mode 100644 index 8a78b8d96c..0000000000 --- a/test/doc/core/plus.cpp +++ /dev/null @@ -1,28 +0,0 @@ -#include -#include -#include - -using wide_ft = eve::wide>; -using wide_it = eve::wide>; - -int main() -{ - wide_ft pf = {-1.0f, 2.0f, -3.0f, -32768.0f}; - wide_it pi = {-1, 2, -3, -32768}; - - std::cout << "---- simd" << '\n' - << "<- pf = " << pf << '\n' - << "-> plus(pf) = " << eve::plus(pf) << '\n' - << "<- pi = " << pi << '\n' - << "-> plus(pi) = " << eve::plus(pi) << '\n'; - - float xf = -32768.0f; - std::int16_t xi = -32768; - - std::cout << "---- scalar" << '\n' - << "<- xf = " << xf << '\n' - << "-> plus(xf) = " << eve::plus(xf) << '\n' - << "<- xi = " << xi << '\n' - << "-> plus(xi) = " << eve::plus(xi) << '\n'; - return 0; -} diff --git a/test/doc/core/sub.cpp b/test/doc/core/sub.cpp index e20cafeb3e..00832bda04 100644 --- a/test/doc/core/sub.cpp +++ b/test/doc/core/sub.cpp @@ -16,7 +16,7 @@ int main() << " -> pi - qi = " << pi - qi << '\n' << " -> pf - qf = " << pf - qf << '\n' << " -> sub[pi > qi](pi, qi) = " << eve::sub[pi > qi](pi, qi) << '\n' - << " -> saturated(sub)(pi, qi) = " << eve::saturated(eve::sub)(pi, qi) << '\n'; + << " -> sub[saturated](pi, qi) = " < sub(kumi::tuple{pf, pf}) = " << eve::sub( kumi::tuple{pf, pf}) << '\n' << " -> sub(kumi::tuple{pf, 1.0f) = " << eve::sub( kumi::tuple{pf, 1.0f}) << '\n' << " -> sub(kumi::tuple{1.0f, pf) = " << eve::sub( kumi::tuple{1.0f, pf}) << '\n' - << " -> saturated(sub)(pi,12,pi,pi) = " << eve::saturated(eve::sub)(pi, 12, pi,pi) << '\n'; + << " -> sub[saturated](pi,12,pi,pi) = " << eve::sub[eve::saturated](pi, 12, pi, pi) << '\n'; return 0; } diff --git a/test/exhaustive/module/real/core/plus/regular/plus.hpp b/test/exhaustive/module/real/core/plus/regular/plus.hpp deleted file mode 100644 index 5995a76cf9..0000000000 --- a/test/exhaustive/module/real/core/plus/regular/plus.hpp +++ /dev/null @@ -1,20 +0,0 @@ -//================================================================================================== -/* - EVE - Expressive Vector Engine - Copyright : EVE Project Contributors - SPDX-License-Identifier: BSL-1.0 -*/ -//================================================================================================== -#include -#include -#include "measures.hpp" -#include "producers.hpp" - -TTS_CASE_TPL("wide random check on plus", EVE_TYPE) -{ - using v_t = eve::element_type_t; - auto std_plus = tts::vectorize( [](auto e) { return e; } ); - - eve::exhaustive_producer p(eve::valmin(eve::as())+1, eve::valmax(eve::as())); - TTS_RANGE_CHECK(p, std_plus, eve::plus); -} diff --git a/test/random/module/core/plus.cpp b/test/random/module/core/plus.cpp deleted file mode 100644 index e4197c17d4..0000000000 --- a/test/random/module/core/plus.cpp +++ /dev/null @@ -1,21 +0,0 @@ -//================================================================================================== -/* - 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::plus", eve::test::simd::signed_types) -(tts::type) -{ - using e_t = eve::element_type_t; - auto vmin = eve::valmin(eve::as()); - auto vmax = eve::valmax(eve::as()); - auto std_plus = [](auto e) -> e_t { return e; }; - EVE_ULP_RANGE_CHECK( T, eve::uniform_prng(vmin, vmax), std_plus, eve::plus ); - }; diff --git a/test/unit/api/tuple/algorithm/scan.cpp b/test/unit/api/tuple/algorithm/scan.cpp index e0c567e391..2b5e5aaad5 100644 --- a/test/unit/api/tuple/algorithm/scan.cpp +++ b/test/unit/api/tuple/algorithm/scan.cpp @@ -25,7 +25,7 @@ TTS_CASE_TPL( "Check behavior of scan", eve::test::scalar::all_types) w_t expected = kumi::map(eve::scan, x); auto plus = [](auto a, auto b) { - return kumi::map(eve::plus, a, b); + return kumi::map(eve::add, a, b); }; w_t actual_1 = eve::scan(x, plus, eve::zero); @@ -54,7 +54,7 @@ TTS_CASE_TPL( "Check behavior of scan, same type", eve::test::scalar::all_types) w_t expected = kumi::map(eve::scan, x); auto plus = [](auto a, auto b) { - return kumi::map(eve::plus, a, b); + return kumi::map(eve::add, a, b); }; w_t actual_1 = eve::scan(x, plus, eve::zero); diff --git a/test/unit/module/core/add.cpp b/test/unit/module/core/add.cpp index 2c533bc01d..5c7ea29ef6 100644 --- a/test/unit/module/core/add.cpp +++ b/test/unit/module/core/add.cpp @@ -24,10 +24,10 @@ TTS_CASE_TPL("Check return types of add", eve::test::simd::all_types) TTS_EXPR_IS(eve::add(v_t(), v_t()), v_t); // saturated - TTS_EXPR_IS(eve::saturated(eve::add)(T(), T()), T); - TTS_EXPR_IS(eve::saturated(eve::add)(T(), v_t()), T); - TTS_EXPR_IS(eve::saturated(eve::add)(v_t(), T()), T); - TTS_EXPR_IS(eve::saturated(eve::add)(v_t(), v_t()), v_t); + TTS_EXPR_IS(eve::add[eve::saturated](T(), T()), T); + TTS_EXPR_IS(eve::add[eve::saturated](T(), v_t()), T); + TTS_EXPR_IS(eve::add[eve::saturated](v_t(), T()), T); + TTS_EXPR_IS(eve::add[eve::saturated](v_t(), v_t()), v_t); // conditionnal TTS_EXPR_IS(eve::add[eve::logical()](T(), T()), T); @@ -36,13 +36,12 @@ TTS_CASE_TPL("Check return types of add", eve::test::simd::all_types) TTS_EXPR_IS(eve::add[eve::logical()](T(), T()), T); TTS_EXPR_IS(eve::add[eve::logical()](T(), v_t()), T); TTS_EXPR_IS(eve::add[eve::logical()](v_t(), T()), T); - TTS_EXPR_IS(eve::add[eve::logical()](v_t(), v_t()), T); - TTS_EXPR_IS(eve::saturated(eve::add[eve::logical()])(T(), T()), T); - TTS_EXPR_IS(eve::saturated(eve::add[eve::logical()])(T(), v_t()), T); - TTS_EXPR_IS(eve::saturated(eve::add[eve::logical()])(T(), T()), T); - TTS_EXPR_IS(eve::saturated(eve::add[eve::logical()])(T(), v_t()), T); - TTS_EXPR_IS(eve::saturated(eve::add[eve::logical()])(v_t(), T()), T); - TTS_EXPR_IS(eve::saturated(eve::add[eve::logical()])(v_t(), v_t()), v_t); + TTS_EXPR_IS(eve::add[eve::saturated][eve::logical()](T(), T()), T); + TTS_EXPR_IS(eve::add[eve::saturated][eve::logical()](T(), v_t()), T); + TTS_EXPR_IS(eve::add[eve::saturated][eve::logical()](T(), T()), T); + TTS_EXPR_IS(eve::add[eve::saturated][eve::logical()](T(), v_t()), T); + TTS_EXPR_IS(eve::add[eve::saturated][eve::logical()](v_t(), T()), T); + TTS_EXPR_IS(eve::add[eve::saturated][eve::logical()](v_t(), v_t()), v_t); // multi TTS_EXPR_IS(eve::add(T(), T(), T()), T); @@ -55,13 +54,13 @@ TTS_CASE_TPL("Check return types of add", eve::test::simd::all_types) TTS_EXPR_IS(eve::add(int(), std::int8_t(), T()), T); TTS_EXPR_IS(eve::add(int(), T(), int()), T); - TTS_EXPR_IS(eve::saturated(eve::add)(T(), T(), T()), T); - TTS_EXPR_IS(eve::saturated(eve::add)(T(), v_t(), T()), T); - TTS_EXPR_IS(eve::saturated(eve::add)(v_t(), T(), T()), T); - TTS_EXPR_IS(eve::saturated(eve::add)(T(), T(), v_t()), T); - TTS_EXPR_IS(eve::saturated(eve::add)(v_t(), v_t(), T()), T); - TTS_EXPR_IS(eve::saturated(eve::add)(v_t(), T(), v_t()), T); - TTS_EXPR_IS(eve::saturated(eve::add)(v_t(), v_t(), v_t()), v_t); + TTS_EXPR_IS(eve::add[eve::saturated](T(), T(), T()), T); + TTS_EXPR_IS(eve::add[eve::saturated](T(), v_t(), T()), T); + TTS_EXPR_IS(eve::add[eve::saturated](v_t(), T(), T()), T); + TTS_EXPR_IS(eve::add[eve::saturated](T(), T(), v_t()), T); + TTS_EXPR_IS(eve::add[eve::saturated](v_t(), v_t(), T()), T); + TTS_EXPR_IS(eve::add[eve::saturated](v_t(), T(), v_t()), T); + TTS_EXPR_IS(eve::add[eve::saturated](v_t(), v_t(), v_t()), v_t); }; //================================================================================================== @@ -80,13 +79,13 @@ TTS_CASE_WITH("Check behavior of add on wide", using eve::detail::map; TTS_ULP_EQUAL( add(a0, a2), map([](auto e, auto f) { return add(e, f); }, a0, a2), 0.5); - TTS_ULP_EQUAL( saturated(add)(a0, a2), map([&](auto e, auto f) { return saturated(add)(e, f); }, a0, a2), 0.5); + TTS_ULP_EQUAL( add[saturated](a0, a2), map([&](auto e, auto f) { return add[saturated](e, f); }, a0, a2), 0.5); TTS_ULP_EQUAL( add(a0, a1, a2), map([&](auto e, auto f, auto g) { return add(add(e, f), g); }, a0, a1, a2), 0.5); - TTS_ULP_EQUAL( saturated(add)(a0, a1, a2), map([&](auto e, auto f, auto g) { return saturated(add)(saturated(add)(e, f), g); }, a0, a1, a2), 0.5); + TTS_ULP_EQUAL( add[saturated](a0, a1, a2), map([&](auto e, auto f, auto g) { return add[saturated](add[saturated](e, f), g); }, a0, a1, a2), 0.5); TTS_ULP_EQUAL( add(kumi::tuple{a0, a2}), map([](auto e, auto f) { return add(e, f); }, a0, a2), 0.5); - TTS_ULP_EQUAL( saturated(add)(kumi::tuple{a0, a2}), map([&](auto e, auto f) { return saturated(add)(e, f); }, a0, a2), 0.5); + TTS_ULP_EQUAL( add[saturated](kumi::tuple{a0, a2}), map([&](auto e, auto f) { return add[saturated](e, f); }, a0, a2), 0.5); TTS_ULP_EQUAL( add(kumi::tuple{a0, a1, a2}), map([&](auto e, auto f, auto g) { return add(add(e, f), g); }, a0, a1, a2), 0.5); - TTS_ULP_EQUAL( saturated(add)(kumi::tuple{a0, a1, a2}), map([&](auto e, auto f, auto g) { return saturated(add)(saturated(add)(e, f), g); }, a0, a1, a2), 0.5); + TTS_ULP_EQUAL( add[saturated](kumi::tuple{a0, a1, a2}), map([&](auto e, auto f, auto g) { return add[saturated](add[saturated](e, f), g); }, a0, a1, a2), 0.5); }; //================================================================================================== @@ -108,8 +107,8 @@ TTS_CASE_WITH("Check behavior of add on signed types", TTS_EQUAL(add[a2 > T(64)](a0, a1), map([](auto e, auto f, auto g) { return g > 64 ? add(e, f) : e; }, a0, a1, a2)); TTS_EQUAL( - saturated(add[a2 > T(64)])(a0, a1), - map([](auto e, auto f, auto g) { return g > 64 ? saturated(add)(e, f) : e; }, a0, a1, a2)); + add[saturated][a2 > T(64)](a0, a1), + map([](auto e, auto f, auto g) { return g > 64 ? add[saturated](e, f) : e; }, a0, a1, a2)); }; diff --git a/test/unit/module/core/div.cpp b/test/unit/module/core/div.cpp index 20efb7f3ba..37ca268479 100644 --- a/test/unit/module/core/div.cpp +++ b/test/unit/module/core/div.cpp @@ -83,7 +83,7 @@ TTS_CASE_WITH("Check behavior of div on wide", map([&](auto e, auto f, auto g) { return div(e, mul(f, g)); }, a0, a1, a2), 1); TTS_ULP_EQUAL(saturated(div)(a0, a1, a2), - map([&](auto e, auto f, auto g) { return saturated(div)(e, saturated(mul)(f, g)); }, + map([&](auto e, auto f, auto g) { return saturated(div)(e, mul[saturated](f, g)); }, a0, a1, a2), @@ -95,7 +95,7 @@ TTS_CASE_WITH("Check behavior of div on wide", map([&](auto e, auto f, auto g) { return div(e, mul(f, g)); }, a0, a1, a2), 1); TTS_ULP_EQUAL(saturated(div)(kumi::tuple{a0, a1, a2}), - map([&](auto e, auto f, auto g) { return saturated(div)(e, saturated(mul)(f, g)); }, + map([&](auto e, auto f, auto g) { return saturated(div)(e, mul[saturated](f, g)); }, a0, a1, a2), diff --git a/test/unit/module/core/minus.cpp b/test/unit/module/core/minus.cpp index 2cf243903c..4316293393 100644 --- a/test/unit/module/core/minus.cpp +++ b/test/unit/module/core/minus.cpp @@ -52,6 +52,9 @@ TTS_CASE_WITH("Check behavior of eve::minus(eve::wide)", TTS_EQUAL(eve::minus(a0), map([](auto e) -> v_t { return -e; }, a0)); TTS_EQUAL(eve::minus[mask](a0), eve::if_else(mask, eve::minus(a0), a0)); + TTS_EQUAL(eve::minus[eve::if_(mask).else_(99)](a0), eve::if_else(mask, eve::minus(a0), T{99})); + TTS_EQUAL(eve::minus[eve::ignore_all](a0), a0); + TTS_EQUAL(eve::minus[eve::ignore_all.else_(42)](a0), T{42}); }; //================================================================================================== diff --git a/test/unit/module/core/mul.cpp b/test/unit/module/core/mul.cpp index 70c0fa14d7..64a97bd608 100644 --- a/test/unit/module/core/mul.cpp +++ b/test/unit/module/core/mul.cpp @@ -24,10 +24,10 @@ TTS_CASE_TPL("Check return types of mul", eve::test::simd::all_types) TTS_EXPR_IS(eve::mul(v_t(), v_t()), v_t); // saturated - TTS_EXPR_IS(eve::saturated(eve::mul)(T(), T()), T); - TTS_EXPR_IS(eve::saturated(eve::mul)(T(), v_t()), T); - TTS_EXPR_IS(eve::saturated(eve::mul)(v_t(), T()), T); - TTS_EXPR_IS(eve::saturated(eve::mul)(v_t(), v_t()), v_t); + TTS_EXPR_IS(eve::mul[eve::saturated](T(), T()), T); + TTS_EXPR_IS(eve::mul[eve::saturated](T(), v_t()), T); + TTS_EXPR_IS(eve::mul[eve::saturated](v_t(), T()), T); + TTS_EXPR_IS(eve::mul[eve::saturated](v_t(), v_t()), v_t); // conditionnal TTS_EXPR_IS(eve::mul[eve::logical()](T(), T()), T); @@ -36,12 +36,12 @@ TTS_CASE_TPL("Check return types of mul", eve::test::simd::all_types) TTS_EXPR_IS(eve::mul[eve::logical()](T(), v_t()), T); TTS_EXPR_IS(eve::mul[eve::logical()](v_t(), T()), T); TTS_EXPR_IS(eve::mul[eve::logical()](v_t(), v_t()), v_t); - TTS_EXPR_IS(eve::saturated(eve::mul[eve::logical()])(T(), T()), T); - TTS_EXPR_IS(eve::saturated(eve::mul[eve::logical()])(T(), v_t()), T); - TTS_EXPR_IS(eve::saturated(eve::mul[eve::logical()])(T(), T()), T); - TTS_EXPR_IS(eve::saturated(eve::mul[eve::logical()])(T(), v_t()), T); - TTS_EXPR_IS(eve::saturated(eve::mul[eve::logical()])(v_t(), T()), T); - TTS_EXPR_IS(eve::saturated(eve::mul[eve::logical()])(v_t(), v_t()), v_t); + TTS_EXPR_IS(eve::mul[eve::saturated][eve::logical()](T(), T()), T); + TTS_EXPR_IS(eve::mul[eve::saturated][eve::logical()](T(), v_t()), T); + TTS_EXPR_IS(eve::mul[eve::saturated][eve::logical()](T(), T()), T); + TTS_EXPR_IS(eve::mul[eve::saturated][eve::logical()](T(), v_t()), T); + TTS_EXPR_IS(eve::mul[eve::saturated][eve::logical()](v_t(), T()), T); + TTS_EXPR_IS(eve::mul[eve::saturated][eve::logical()](v_t(), v_t()), v_t); // multi TTS_EXPR_IS(eve::mul(T(), T(), T()), T); @@ -52,13 +52,13 @@ TTS_CASE_TPL("Check return types of mul", eve::test::simd::all_types) TTS_EXPR_IS(eve::mul(v_t(), T(), v_t()), T); TTS_EXPR_IS(eve::mul(v_t(), v_t(), v_t()), v_t); - TTS_EXPR_IS(eve::saturated(eve::mul)(T(), T(), T()), T); - TTS_EXPR_IS(eve::saturated(eve::mul)(T(), v_t(), T()), T); - TTS_EXPR_IS(eve::saturated(eve::mul)(v_t(), T(), T()), T); - TTS_EXPR_IS(eve::saturated(eve::mul)(T(), T(), v_t()), T); - TTS_EXPR_IS(eve::saturated(eve::mul)(v_t(), v_t(), T()), T); - TTS_EXPR_IS(eve::saturated(eve::mul)(v_t(), T(), v_t()), T); - TTS_EXPR_IS(eve::saturated(eve::mul)(v_t(), v_t(), v_t()), v_t); + TTS_EXPR_IS(eve::mul[eve::saturated](T(), T(), T()), T); + TTS_EXPR_IS(eve::mul[eve::saturated](T(), v_t(), T()), T); + TTS_EXPR_IS(eve::mul[eve::saturated](v_t(), T(), T()), T); + TTS_EXPR_IS(eve::mul[eve::saturated](T(), T(), v_t()), T); + TTS_EXPR_IS(eve::mul[eve::saturated](v_t(), v_t(), T()), T); + TTS_EXPR_IS(eve::mul[eve::saturated](v_t(), T(), v_t()), T); + TTS_EXPR_IS(eve::mul[eve::saturated](v_t(), v_t(), v_t()), v_t); if constexpr( eve::floating_value ) {} }; @@ -77,22 +77,22 @@ TTS_CASE_WITH("Check behavior of mul on wide", using eve::saturated; using eve::detail::map; TTS_EQUAL(mul(a0, a2), map([](auto e, auto f) { return mul(e, f); }, a0, a2)); - TTS_EQUAL(saturated(mul)(a0, a2), - map([&](auto e, auto f) { return saturated(mul)(e, f); }, a0, a2)); + TTS_EQUAL(mul[saturated](a0, a2), + map([&](auto e, auto f) { return mul[saturated](e, f); }, a0, a2)); TTS_EQUAL(mul(a0, a1, a2), map([&](auto e, auto f, auto g) { return mul(mul(e, f), g); }, a0, a1, a2)); - TTS_EQUAL(saturated(mul)(a0, a1, a2), - map([&](auto e, auto f, auto g) { return saturated(mul)(saturated(mul)(e, f), g); }, + TTS_EQUAL(mul[saturated](a0, a1, a2), + map([&](auto e, auto f, auto g) { return mul[saturated](mul[saturated](e, f), g); }, a0, a1, a2)); TTS_EQUAL(mul(kumi::tuple{a0, a2}), map([](auto e, auto f) { return mul(e, f); }, a0, a2)); - TTS_EQUAL(saturated(mul)(kumi::tuple{a0, a2}), - map([&](auto e, auto f) { return saturated(mul)(e, f); }, a0, a2)); + TTS_EQUAL(mul[saturated](kumi::tuple{a0, a2}), + map([&](auto e, auto f) { return mul[saturated](e, f); }, a0, a2)); TTS_EQUAL(mul(kumi::tuple{a0, a1, a2}), map([&](auto e, auto f, auto g) { return mul(mul(e, f), g); }, a0, a1, a2)); - TTS_EQUAL(saturated(mul)(kumi::tuple{a0, a1, a2}), - map([&](auto e, auto f, auto g) { return saturated(mul)(saturated(mul)(e, f), g); }, + TTS_EQUAL(mul[saturated](kumi::tuple{a0, a1, a2}), + map([&](auto e, auto f, auto g) { return mul[saturated](mul[saturated](e, f), g); }, a0, a1, a2)); @@ -117,8 +117,8 @@ TTS_CASE_WITH("Check behavior of mul on signed types", TTS_EQUAL(mul[a2 > T(64)](a0, a1), map([](auto e, auto f, auto g) { return g > 64 ? mul(e, f) : e; }, a0, a1, a2)); TTS_EQUAL( - saturated(mul[a2 > T(64)])(a0, a1), - map([](auto e, auto f, auto g) { return g > 64 ? saturated(mul)(e, f) : e; }, a0, a1, a2)); + mul[saturated][a2 > T(64)](a0, a1), + map([](auto e, auto f, auto g) { return g > 64 ? mul[saturated](e, f) : e; }, a0, a1, a2)); }; diff --git a/test/unit/module/core/plus.cpp b/test/unit/module/core/plus.cpp deleted file mode 100644 index 5e5696232e..0000000000 --- a/test/unit/module/core/plus.cpp +++ /dev/null @@ -1,40 +0,0 @@ -//================================================================================================== -/** - EVE - Expressive Vector Engine - Copyright : EVE Project Contributors - SPDX-License-Identifier: BSL-1.0 -**/ -//================================================================================================== -#include "test.hpp" - -#include - -#include - -//================================================================================================== -// Types tests -//================================================================================================== -TTS_CASE_TPL("Check return types of eve::plus", eve::test::simd::signed_types) -(tts::type) -{ - using v_t = eve::element_type_t; - - TTS_EXPR_IS(eve::plus(T()), T); - TTS_EXPR_IS(eve::plus(v_t()), v_t); - if constexpr( eve::floating_value ) {} -}; - - -//================================================================================================== -// Tests for masked plus -//================================================================================================== -TTS_CASE_WITH("Check behavior of eve::masked(eve::plus)(eve::wide)", - eve::test::simd::ieee_reals, - tts::generate(tts::randoms(eve::valmin, eve::valmax), - tts::logicals(0, 3))) -(T const& a0, - M const& mask) -{ - TTS_IEEE_EQUAL(eve::plus[mask](a0), - eve::if_else(mask, eve::plus(a0), a0)); -}; diff --git a/test/unit/module/core/reduce.cpp b/test/unit/module/core/reduce.cpp index 25f72731d5..e67032c279 100644 --- a/test/unit/module/core/reduce.cpp +++ b/test/unit/module/core/reduce.cpp @@ -17,9 +17,9 @@ TTS_CASE_TPL("Check return types of eve::reduce(wide)", eve::test::simd::all_typ { using v_t = eve::element_type_t; TTS_EXPR_IS((eve::reduce(T {})), v_t); - TTS_EXPR_IS((eve::reduce(T {}, eve::plus)), v_t); + TTS_EXPR_IS((eve::reduce(T {}, eve::add)), v_t); TTS_EXPR_IS((eve::splat(eve::reduce)(T {})), T); - TTS_EXPR_IS((eve::splat(eve::reduce)(T {}, eve::plus)), T); + TTS_EXPR_IS((eve::splat(eve::reduce)(T {}, eve::add)), T); }; //================================================================================================== @@ -35,12 +35,10 @@ TTS_CASE_TPL("Check behavior of eve::reduce(eve::wide)", eve::test::simd::all_ty for( std::ptrdiff_t i = 0; i < T::size(); ++i ) ref += data.get(i); TTS_EQUAL(eve::reduce(data, [](auto a, auto b) { return a + b; }), ref); - TTS_EQUAL(eve::reduce(data, eve::plus), ref); TTS_EQUAL(eve::reduce(data, eve::add), ref); TTS_EQUAL(eve::reduce(data), ref); TTS_EQUAL(eve::splat(eve::reduce)(data, [](auto a, auto b) { return a + b; }), T(ref)); - TTS_EQUAL(eve::splat(eve::reduce)(data, eve::plus), T(ref)); TTS_EQUAL(eve::splat(eve::reduce)(data, eve::add), T(ref)); TTS_EQUAL(eve::splat(eve::reduce)(data), T(ref)); }; diff --git a/test/unit/module/core/scan.cpp b/test/unit/module/core/scan.cpp index 050229e639..160b78830e 100644 --- a/test/unit/module/core/scan.cpp +++ b/test/unit/module/core/scan.cpp @@ -31,7 +31,7 @@ TTS_CASE_WITH("Check behavior of default scan", tts::generate(tts::randoms(-50, 50))) (T simd) { - T expected = std_scan(simd, eve::plus); + T expected = std_scan(simd, eve::add); T actual = eve::scan(simd); TTS_RELATIVE_EQUAL(expected, actual, 0.0005); diff --git a/test/unit/module/core/sub.cpp b/test/unit/module/core/sub.cpp index 4062e64e51..0a1c2fb2a5 100644 --- a/test/unit/module/core/sub.cpp +++ b/test/unit/module/core/sub.cpp @@ -24,10 +24,10 @@ TTS_CASE_TPL("Check return types of sub", eve::test::simd::all_types) TTS_EXPR_IS(eve::sub(v_t(), v_t()), v_t); // saturated - TTS_EXPR_IS(eve::saturated(eve::sub)(T(), T()), T); - TTS_EXPR_IS(eve::saturated(eve::sub)(T(), v_t()), T); - TTS_EXPR_IS(eve::saturated(eve::sub)(v_t(), T()), T); - TTS_EXPR_IS(eve::saturated(eve::sub)(v_t(), v_t()), v_t); + TTS_EXPR_IS(eve::sub[eve::saturated](T(), T()), T); + TTS_EXPR_IS(eve::sub[eve::saturated](T(), v_t()), T); + TTS_EXPR_IS(eve::sub[eve::saturated](v_t(), T()), T); + TTS_EXPR_IS(eve::sub[eve::saturated](v_t(), v_t()), v_t); // conditionnal TTS_EXPR_IS(eve::sub[eve::logical()](T(), T()), T); @@ -36,12 +36,12 @@ TTS_CASE_TPL("Check return types of sub", eve::test::simd::all_types) TTS_EXPR_IS(eve::sub[eve::logical()](T(), v_t()), T); TTS_EXPR_IS(eve::sub[eve::logical()](v_t(), T()), T); TTS_EXPR_IS(eve::sub[eve::logical()](v_t(), v_t()), v_t); - TTS_EXPR_IS(eve::saturated(eve::sub[eve::logical()])(T(), T()), T); - TTS_EXPR_IS(eve::saturated(eve::sub[eve::logical()])(T(), v_t()), T); - TTS_EXPR_IS(eve::saturated(eve::sub[eve::logical()])(T(), T()), T); - TTS_EXPR_IS(eve::saturated(eve::sub[eve::logical()])(T(), v_t()), T); - TTS_EXPR_IS(eve::saturated(eve::sub[eve::logical()])(v_t(), T()), T); - TTS_EXPR_IS(eve::saturated(eve::sub[eve::logical()])(v_t(), v_t()), v_t); + TTS_EXPR_IS(eve::sub[eve::saturated][eve::logical()](T(), T()), T); + TTS_EXPR_IS(eve::sub[eve::saturated][eve::logical()](T(), v_t()), T); + TTS_EXPR_IS(eve::sub[eve::saturated][eve::logical()](T(), T()), T); + TTS_EXPR_IS(eve::sub[eve::saturated][eve::logical()](T(), v_t()), T); + TTS_EXPR_IS(eve::sub[eve::saturated][eve::logical()](v_t(), T()), T); + TTS_EXPR_IS(eve::sub[eve::saturated][eve::logical()](v_t(), v_t()), v_t); // multi TTS_EXPR_IS(eve::sub(T(), T(), T()), T); @@ -52,13 +52,13 @@ TTS_CASE_TPL("Check return types of sub", eve::test::simd::all_types) TTS_EXPR_IS(eve::sub(v_t(), T(), v_t()), T); TTS_EXPR_IS(eve::sub(v_t(), v_t(), v_t()), v_t); - TTS_EXPR_IS(eve::saturated(eve::sub)(T(), T(), T()), T); - TTS_EXPR_IS(eve::saturated(eve::sub)(T(), v_t(), T()), T); - TTS_EXPR_IS(eve::saturated(eve::sub)(v_t(), T(), T()), T); - TTS_EXPR_IS(eve::saturated(eve::sub)(T(), T(), v_t()), T); - TTS_EXPR_IS(eve::saturated(eve::sub)(v_t(), v_t(), T()), T); - TTS_EXPR_IS(eve::saturated(eve::sub)(v_t(), T(), v_t()), T); - TTS_EXPR_IS(eve::saturated(eve::sub)(v_t(), v_t(), v_t()), v_t); + TTS_EXPR_IS(eve::sub[eve::saturated](T(), T(), T()), T); + TTS_EXPR_IS(eve::sub[eve::saturated](T(), v_t(), T()), T); + TTS_EXPR_IS(eve::sub[eve::saturated](v_t(), T(), T()), T); + TTS_EXPR_IS(eve::sub[eve::saturated](T(), T(), v_t()), T); + TTS_EXPR_IS(eve::sub[eve::saturated](v_t(), v_t(), T()), T); + TTS_EXPR_IS(eve::sub[eve::saturated](v_t(), T(), v_t()), T); + TTS_EXPR_IS(eve::sub[eve::saturated](v_t(), v_t(), v_t()), v_t); }; //================================================================================================== @@ -76,21 +76,21 @@ TTS_CASE_WITH("Check behavior of sub on wide", using eve::detail::map; TTS_EQUAL(sub(a0, a2), map([](auto e, auto f) { return sub(e, f); }, a0, a2)); - TTS_EQUAL(saturated(sub)(a0, a2), - map([&](auto e, auto f) { return saturated(sub)(e, f); }, a0, a2)); + TTS_EQUAL(sub[saturated](a0, a2), + map([&](auto e, auto f) { return sub[saturated](e, f); }, a0, a2)); TTS_EQUAL(sub(a0, a1, a2), map([&](auto e, auto f, auto g) { return sub(sub(e, f), g); }, a0, a1, a2)); - TTS_EQUAL(saturated(sub)(a0, a1, a2), - map([&](auto e, auto f, auto g) { return saturated(sub)(saturated(sub)(e, f), g); }, + TTS_EQUAL(sub[saturated](a0, a1, a2), + map([&](auto e, auto f, auto g) { return sub[saturated](sub[saturated](e, f), g); }, a0,a1,a2) ); TTS_EQUAL(sub(kumi::tuple{a0, a2}), map([](auto e, auto f) { return sub(e, f); }, a0, a2)); - TTS_EQUAL(saturated(sub)(kumi::tuple{a0, a2}), - map([&](auto e, auto f) { return saturated(sub)(e, f); }, a0, a2)); + TTS_EQUAL(sub[saturated](kumi::tuple{a0, a2}), + map([&](auto e, auto f) { return sub[saturated](e, f); }, a0, a2)); TTS_EQUAL(sub(kumi::tuple{a0, a1, a2}), map([&](auto e, auto f, auto g) { return sub(sub(e, f), g); }, a0, a1, a2)); - TTS_EQUAL(saturated(sub)(kumi::tuple{a0, a1, a2}), - map([&](auto e, auto f, auto g) { return saturated(sub)(saturated(sub)(e, f), g); }, + TTS_EQUAL(sub[saturated](kumi::tuple{a0, a1, a2}), + map([&](auto e, auto f, auto g) { return sub[saturated](sub[saturated](e, f), g); }, a0,a1,a2) ); }; @@ -113,9 +113,8 @@ TTS_CASE_WITH("Check behavior of sub on signed types", using eve::detail::map; TTS_EQUAL(sub[a2 > T(64)](a0, a1), map([](auto e, auto f, auto g) { return g > 64 ? sub(e, f) : e; }, a0, a1, a2)); - TTS_EQUAL( - saturated(sub[a2 > T(64)])(a0, a1), - map([](auto e, auto f, auto g) { return g > 64 ? saturated(sub)(e, f) : e; }, a0, a1, a2)); + TTS_EQUAL(sub[saturated][a2 > T(64)](a0, a1) + , map([](auto e, auto f, auto g) { return g > 64 ? sub[saturated](e, f) : e; }, a0, a1, a2)); }; /// TODO waiting for interface simplifications to add scalar tests diff --git a/test/unit/module/math/nthroot.cpp b/test/unit/module/math/nthroot.cpp index 6be401a78d..00ebc925cd 100644 --- a/test/unit/module/math/nthroot.cpp +++ b/test/unit/module/math/nthroot.cpp @@ -70,10 +70,8 @@ TTS_CASE_TPL("Check special cases of nthroot", eve::test::simd::ieee_reals) TTS_EQUAL(eve::nthroot(T(8), 3), T(2)); TTS_EQUAL(eve::nthroot(T(8), 3u), T(2)); TTS_IEEE_EQUAL(eve::nthroot(T(-64), 4), eve::nan(eve::as())); - }; - //================================================================================================== //=== Tests for masked nthroot //==================================================================================================