Skip to content

Commit

Permalink
Cleanup for zip, write, lookup, bit_cast and broadcast
Browse files Browse the repository at this point in the history
  • Loading branch information
jfalcou committed May 30, 2024
1 parent 2cbe228 commit ec8c1f7
Show file tree
Hide file tree
Showing 27 changed files with 603 additions and 593 deletions.
17 changes: 15 additions & 2 deletions include/eve/detail/function/bit_cast.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,24 @@
#pragma once

#include <eve/arch.hpp>
#include <eve/detail/overload.hpp>
#include <eve/traits/overload.hpp>

namespace eve
{
EVE_MAKE_CALLABLE(bit_cast_, bit_cast);
template<typename Options>
struct bit_cast_t : callable<bit_cast_t, Options>
{
template<typename T, typename Target>
requires (sizeof(T) == sizeof(Target))
EVE_FORCEINLINE Target operator()(T const& a, as<Target> const& tgt) const noexcept
{
return EVE_DISPATCH_CALL(a,tgt);
}

EVE_CALLABLE_OBJECT(bit_cast_t, bit_cast_);
};

inline constexpr auto bit_cast = functor<bit_cast_t>;
}

#include <eve/detail/function/simd/common/bit_cast.hpp>
Expand Down
63 changes: 31 additions & 32 deletions include/eve/detail/function/simd/arm/sve/bit_cast.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,41 +13,40 @@

namespace eve::detail
{
template<scalar_value T, typename N, scalar_value U, typename M>
EVE_FORCEINLINE wide<U, M>
bit_cast_(EVE_SUPPORTS(sve_), wide<T, N> const& x, as<wide<U, M>> const&) noexcept
requires(sizeof(wide<T, N>) == sizeof(wide<U, M>) && (sve_abi<abi_t<T, N>>))
{
if constexpr( std::is_same_v<wide<T, N>, wide<U, M>> ) { return x; }
else
template<callable_options O, scalar_value T, typename N, scalar_value U, typename M>
requires( sve_abi<abi_t<T, N>> )
EVE_FORCEINLINE wide<U, M> bit_cast_(EVE_REQUIRES(sve_), O const&, wide<T,N> x, as<wide<U,M>> const&) noexcept
{
auto as_byte = [](auto v)
if constexpr( std::is_same_v<wide<T, N>, wide<U, M>> ) return x;
else
{
constexpr auto c = categorize<eve::wide<T,N>>();
if constexpr(match(c, category::float64)) return svreinterpret_u8_f64(v);
else if constexpr(match(c, category::float32)) return svreinterpret_u8_f32(v);
else if constexpr(match(c, category::int64) ) return svreinterpret_u8_s64(v);
else if constexpr(match(c, category::uint64) ) return svreinterpret_u8_u64(v);
else if constexpr(match(c, category::int32) ) return svreinterpret_u8_s32(v);
else if constexpr(match(c, category::uint32) ) return svreinterpret_u8_u32(v);
else if constexpr(match(c, category::int16) ) return svreinterpret_u8_s16(v);
else if constexpr(match(c, category::uint16) ) return svreinterpret_u8_u16(v);
else if constexpr(match(c, category::int8) ) return svreinterpret_u8_s8 (v);
else if constexpr(match(c, category::uint8) ) return v.storage();
}(x);
auto as_byte = [](auto v)
{
constexpr auto c = categorize<eve::wide<T,N>>();
if constexpr(match(c, category::float64)) return svreinterpret_u8_f64(v);
else if constexpr(match(c, category::float32)) return svreinterpret_u8_f32(v);
else if constexpr(match(c, category::int64) ) return svreinterpret_u8_s64(v);
else if constexpr(match(c, category::uint64) ) return svreinterpret_u8_u64(v);
else if constexpr(match(c, category::int32) ) return svreinterpret_u8_s32(v);
else if constexpr(match(c, category::uint32) ) return svreinterpret_u8_u32(v);
else if constexpr(match(c, category::int16) ) return svreinterpret_u8_s16(v);
else if constexpr(match(c, category::uint16) ) return svreinterpret_u8_u16(v);
else if constexpr(match(c, category::int8) ) return svreinterpret_u8_s8 (v);
else if constexpr(match(c, category::uint8) ) return v.storage();
}(x);

constexpr auto d = categorize<wide<U, M>>();
constexpr auto d = categorize<wide<U, M>>();

if constexpr(match(d, category::float64)) return svreinterpret_f64_u8(as_byte);
else if constexpr(match(d, category::float32)) return svreinterpret_f32_u8(as_byte);
else if constexpr(match(d, category::int64) ) return svreinterpret_s64_u8(as_byte);
else if constexpr(match(d, category::uint64) ) return svreinterpret_u64_u8(as_byte);
else if constexpr(match(d, category::int32) ) return svreinterpret_s32_u8(as_byte);
else if constexpr(match(d, category::uint32) ) return svreinterpret_u32_u8(as_byte);
else if constexpr(match(d, category::int16) ) return svreinterpret_s16_u8(as_byte);
else if constexpr(match(d, category::uint16) ) return svreinterpret_u16_u8(as_byte);
else if constexpr(match(d, category::int8) ) return svreinterpret_s8_u8 (as_byte);
else if constexpr(match(d, category::uint8) ) return as_byte;
if constexpr(match(d, category::float64)) return svreinterpret_f64_u8(as_byte);
else if constexpr(match(d, category::float32)) return svreinterpret_f32_u8(as_byte);
else if constexpr(match(d, category::int64) ) return svreinterpret_s64_u8(as_byte);
else if constexpr(match(d, category::uint64) ) return svreinterpret_u64_u8(as_byte);
else if constexpr(match(d, category::int32) ) return svreinterpret_s32_u8(as_byte);
else if constexpr(match(d, category::uint32) ) return svreinterpret_u32_u8(as_byte);
else if constexpr(match(d, category::int16) ) return svreinterpret_s16_u8(as_byte);
else if constexpr(match(d, category::uint16) ) return svreinterpret_u16_u8(as_byte);
else if constexpr(match(d, category::int8) ) return svreinterpret_s8_u8 (as_byte);
else if constexpr(match(d, category::uint8) ) return as_byte;
}
}
}
}
10 changes: 3 additions & 7 deletions include/eve/detail/function/simd/common/bit_cast.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,14 +19,10 @@

namespace eve::detail
{
template<typename T, typename Target>
EVE_FORCEINLINE auto bit_cast_(EVE_SUPPORTS(cpu_), T const &a, as<Target> const &) noexcept
requires (sizeof(T) == sizeof(Target))
template<callable_options O, typename T, typename Target>
EVE_FORCEINLINE auto bit_cast_(EVE_REQUIRES(cpu_), O const&, T const &a, as<Target> const &) noexcept
{
if constexpr(std::is_same_v<T, Target>)
{
return a;
}
if constexpr(std::is_same_v<T, Target>) return a;
else
{
[[maybe_unused]] Target that;
Expand Down
6 changes: 3 additions & 3 deletions include/eve/detail/function/simd/ppc/bit_compounds.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ namespace eve::detail

if constexpr( element_bit_compatible_to<U,type> )
{
auto bit_other = detail::bit_cast_(EVE_RETARGET(cpu_), other , as<T>{});
auto bit_other = bit_cast(other , as<T>{});
self = vec_and(self.storage(), type{bit_other}.storage());
}
else if constexpr( simd_value<U> && sizeof(self) == sizeof(other) )
Expand All @@ -94,7 +94,7 @@ namespace eve::detail

if constexpr( element_bit_compatible_to<U,type> )
{
auto bit_other = detail::bit_cast_(EVE_RETARGET(cpu_), other , as<T>{});
auto bit_other = bit_cast(other , as<T>{});
self = vec_or(self.storage(), type{bit_other}.storage());
}
else if constexpr( simd_value<U> && sizeof(self) == sizeof(other) )
Expand All @@ -116,7 +116,7 @@ namespace eve::detail

if constexpr( element_bit_compatible_to<U,type> )
{
auto bit_other = detail::bit_cast_(EVE_RETARGET(cpu_), other , as<T>{});
auto bit_other = bit_cast(other , as<T>{});
self = vec_xor(self.storage(), type{bit_other}.storage());
}
else if constexpr( simd_value<U> && sizeof(self) == sizeof(other) )
Expand Down
8 changes: 4 additions & 4 deletions include/eve/detail/function/simd/x86/bit_compounds.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -252,12 +252,12 @@ namespace eve::detail

if constexpr( scalar_value<U> )
{
auto bit_other = detail::bit_cast_(EVE_RETARGET(cpu_), other, as<T> {});
auto bit_other = bit_cast(other, as<T> {});
return self_bitor(self, type {bit_other});
}
else if constexpr( simd_value<U> && sizeof(self) == sizeof(other) )
{
auto bits = detail::bit_cast_(EVE_RETARGET(cpu_), other, as<type> {});
auto bits = bit_cast(other, as<type> {});
constexpr auto c = categorize<type>();
constexpr bool i = match(c, category::integer_);

Expand Down Expand Up @@ -294,12 +294,12 @@ namespace eve::detail

if constexpr( scalar_value<U> )
{
auto bit_other = detail::bit_cast_(EVE_RETARGET(cpu_), other, as<T> {});
auto bit_other = bit_cast(other, as<T> {});
return self_bitxor(self, type {bit_other});
}
else if constexpr( simd_value<U> && sizeof(self) == sizeof(other) )
{
auto bits = detail::bit_cast_(EVE_RETARGET(cpu_), other, as<type> {});
auto bits = bit_cast(other, as<type> {});
constexpr auto c = categorize<type>();
constexpr bool i = match(c, category::integer_);

Expand Down
5 changes: 1 addition & 4 deletions include/eve/module/algo/algo/views/backward.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -123,10 +123,7 @@ namespace eve::algo::views
return eve::read(unalign(self.base) - 1);
}

EVE_FORCEINLINE friend void tagged_dispatch(eve::tag::write_, value_type v, backward_iterator self)
{
return eve::write(v, unalign(self.base) - 1);
}
EVE_FORCEINLINE void write(value_type v) const noexcept { eve::write(v, unalign(base) - 1); }

template <relaxed_sentinel_for<I> I1>
EVE_FORCEINLINE bool operator==(backward_iterator<I1> y) const
Expand Down
4 changes: 2 additions & 2 deletions include/eve/module/algo/algo/views/convert.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -156,9 +156,9 @@ namespace eve::algo::views
return eve::convert(eve::read(self.base), eve::as<T>{});
}

EVE_FORCEINLINE friend void tagged_dispatch(eve::tag::write_, T v, converting_iterator self)
EVE_FORCEINLINE void write(T v) const noexcept
{
eve::write(eve::convert(v, eve::as<value_type_t<I>>{}),self.base);
eve::write(eve::convert(v, eve::as<value_type_t<I>>{}),base);
}

template <relaxed_sentinel_for<I> I1>
Expand Down
6 changes: 3 additions & 3 deletions include/eve/module/algo/algo/views/map.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -254,10 +254,10 @@ namespace eve::algo::views
return self.load_op(eve::read(self.base));
}

EVE_FORCEINLINE friend void tagged_dispatch(eve::tag::write_, auto v, map_iterator self)
requires (!std::same_as<StoreOp, nothing_t>)
EVE_FORCEINLINE void write(value_type v) const noexcept
requires (!std::same_as<StoreOp, nothing_t>)
{
eve::write(detail::bind_store_op<I>(self.store_op)(v),self.base);
eve::write(detail::bind_store_op<I>(store_op)(v),base);
}

template <relaxed_sentinel_for<I> I1>
Expand Down
5 changes: 1 addition & 4 deletions include/eve/module/algo/algo/views/reverse.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -115,10 +115,7 @@ namespace eve::algo::views
return eve::read(unalign(self.base) - 1);
}

EVE_FORCEINLINE friend void tagged_dispatch(eve::tag::write_, value_type v, reverse_iterator self)
{
return eve::write(v,unalign(self.base) - 1);
}
EVE_FORCEINLINE void write(value_type v) const noexcept { return eve::write(v,unalign(base) - 1); }

template <relaxed_sentinel_for<I> I1>
EVE_FORCEINLINE bool operator==(reverse_iterator<I1> y) const
Expand Down
5 changes: 1 addition & 4 deletions include/eve/module/algo/algo/views/zip_iterator.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -171,10 +171,7 @@ namespace eve::algo::views
return kumi::map(eve::read, self.storage);
}

EVE_FORCEINLINE friend auto tagged_dispatch(eve::tag::write_, value_type v, zip_iterator<Is...> self)
{
kumi::for_each(eve::write, v, self.storage);
}
EVE_FORCEINLINE void write(value_type v) const noexcept { kumi::for_each(eve::write, v, storage); }

EVE_FORCEINLINE operator zip_iterator<unaligned_t<Is>...>() const
{
Expand Down
104 changes: 52 additions & 52 deletions include/eve/module/core/regular/bit_cast.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,61 +7,61 @@
#pragma once

#if defined(EVE_DOXYGEN_INVOKED)
# include <eve/detail/overload.hpp>
#include <eve/traits/overload.hpp>

namespace eve
{
//================================================================================================
//! @addtogroup core_bitops
//! @{
//! @var bit_cast
//! @brief Computes a a bitwise reinterpretation of an object.
//!
//! **Defined in Header**
//!
//! @code
//! #include <eve/module/core.hpp>
//! @endcode
//!
//! @groupheader{Callable Signatures}
//!
//! @code
//! namespace eve
//! {
//! { template<value From, scalar_value To>
//! To bit_cast operator()(From x, as<To> t) noexcept;
//! }
//! @endcode
//!
//! **Parameters**
//!
//! * `x` : [argument](@ref eve::value).
//! * `t` : [Type wrapper](@ref eve::as) instance embedding the type of the result.
//!
//! **Template parameters**
//!
//! * To: scalar type to which each element of `x` is casted
//!
//! **Return value**
//!
//! The bits of x of type From reinterpreted as being those of a variable of type To
//! is returned.
//!
//! Every bit in the value representation of the returned To object is equal to the
//! corresponding bit in the object representation of from.
//! The values of padding bits in the returned To object are unspecified.
//!
//! If there is no value of type To corresponding to the value
//! representation produced, the behavior is undefined. If there are multiple
//! such values, which value is produced is unspecified.
//!
//! @groupheader{Example}
//!
//! @godbolt{doc/core/bit_cast.cpp}
//!
//! @}
//================================================================================================
EVE_MAKE_CALLABLE(bit_cast_, bit_cast);
//================================================================================================
//! @addtogroup core_bitops
//! @{
//! @var bit_cast
//! @brief Computes a a bitwise reinterpretation of an object.
//!
//! **Defined in Header**
//!
//! @code
//! #include <eve/module/core.hpp>
//! @endcode
//!
//! @groupheader{Callable Signatures}
//!
//! @code
//! namespace eve
//! {
//! { template<value From, scalar_value To>
//! To bit_cast operator()(From x, as<To> t) noexcept;
//! }
//! @endcode
//!
//! **Parameters**
//!
//! * `x` : [argument](@ref eve::value).
//! * `t` : [Type wrapper](@ref eve::as) instance embedding the type of the result.
//!
//! **Template parameters**
//!
//! * To: scalar type to which each element of `x` is casted
//!
//! **Return value**
//!
//! The bits of x of type From reinterpreted as being those of a variable of type To
//! is returned.
//!
//! Every bit in the value representation of the returned To object is equal to the
//! corresponding bit in the object representation of from.
//! The values of padding bits in the returned To object are unspecified.
//!
//! If there is no value of type To corresponding to the value
//! representation produced, the behavior is undefined. If there are multiple
//! such values, which value is produced is unspecified.
//!
//! @groupheader{Example}
//!
//! @godbolt{doc/core/bit_cast.cpp}
//!
//! @}
//================================================================================================
inline constexpr auto bit_cast = functor<bit_cast_t>;
}
#endif

Expand Down
Loading

0 comments on commit ec8c1f7

Please sign in to comment.