Skip to content

Commit

Permalink
#1749 - Implements same_lanes and same_lanes_or_scalar
Browse files Browse the repository at this point in the history
  • Loading branch information
jfalcou authored May 14, 2024
1 parent b5252c2 commit d2ec2f6
Show file tree
Hide file tree
Showing 2 changed files with 120 additions and 0 deletions.
66 changes: 66 additions & 0 deletions include/eve/traits/same_lanes.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
//==================================================================================================
/*
EVE - Expressive Vector Engine
Copyright : EVE Project Contributors
SPDX-License-Identifier: BSL-1.0
*/
//==================================================================================================
#pragma once

#include <eve/traits/cardinal.hpp>
#include <eve/concept/vectorized.hpp>

namespace eve
{
namespace detail
{
template<typename... Ts>
consteval auto lanes_check()
{
// Find largest lanes as a reference
std::ptrdiff_t cards[] = { cardinal_v<Ts>... };

auto max_card = cards[0];
for(auto c : cards) max_card = max_card < c ? c : max_card;

// Check all lanes is either 1 or equal to max_card
for(auto c : cards)
{
if(c != 1 && c != max_card)
return false;
}
return true;
}
}

//================================================================================================
//! @addtogroup traits
//! @{
//! @var same_lanes_or_scalar
//!
//! @tparam Ts Type to process
//!
//! @brief Checks that all types `Ts` are either scalar or share a common number of lanes.
//!
//! **Required header:** `#include <eve/traits.hpp>`
//! @}
//================================================================================================
template<typename... Ts>
inline constexpr bool same_lanes_or_scalar = detail::lanes_check<Ts...>();

//================================================================================================
//! @addtogroup traits
//! @{
//! @var same_lanes
//!
//! @tparam T0 [SIMD Type](@ref eve::simd_value) to process.
//! @tparam Ts [SIMD Types](@ref eve::simd_value) to process.
//!
//! @brief Checks that all SIMD types `Ts` share a common number of lanes.
//!
//! **Required header:** `#include <eve/traits.hpp>`
//! @}
//================================================================================================
template<simd_value T0, simd_value... Ts>
inline constexpr bool same_lanes = ((cardinal_v<T0> == cardinal_v<Ts>) && ... && true);
}
54 changes: 54 additions & 0 deletions test/unit/meta/traits/same_lanes_or_scalar.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
//==================================================================================================
/**
EVE - Expressive Vector Engine
Copyright : EVE Project Contributors
SPDX-License-Identifier: BSL-1.0
**/
//==================================================================================================
#include "test.hpp"
#include <eve/traits/same_lanes.hpp>
#include <eve/wide.hpp>

TTS_CASE( "Check same_lanes on simd types" )
{
using eve::wide;
using eve::fixed;

TTS_CONSTEXPR_EXPECT((eve::same_lanes<wide<int>>));
TTS_CONSTEXPR_EXPECT((eve::same_lanes<wide<int>,wide<float>>));
TTS_CONSTEXPR_EXPECT((eve::same_lanes<wide<int,fixed<8>>,wide<char,fixed<8>>>));
TTS_CONSTEXPR_EXPECT_NOT((eve::same_lanes<wide<int>,wide<char>>));
};

TTS_CASE( "Check same_lanes_or_scalar on scalar types" )
{
TTS_CONSTEXPR_EXPECT((eve::same_lanes_or_scalar<int>));
TTS_CONSTEXPR_EXPECT((eve::same_lanes_or_scalar<int,char>));
TTS_CONSTEXPR_EXPECT((eve::same_lanes_or_scalar<int,float>));
TTS_CONSTEXPR_EXPECT((eve::same_lanes_or_scalar<double,int,float>));
TTS_CONSTEXPR_EXPECT((eve::same_lanes_or_scalar<kumi::tuple<double,int,float>>));
TTS_CONSTEXPR_EXPECT((eve::same_lanes_or_scalar<kumi::tuple<double,int,float>, int>));
};

TTS_CASE( "Check same_lanes_or_scalar on simd types" )
{
using eve::wide;
using eve::fixed;

TTS_CONSTEXPR_EXPECT((eve::same_lanes_or_scalar<wide<int>>));
TTS_CONSTEXPR_EXPECT((eve::same_lanes_or_scalar<wide<int>,wide<float>>));
TTS_CONSTEXPR_EXPECT((eve::same_lanes_or_scalar<wide<int,fixed<8>>,wide<char,fixed<8>>>));
TTS_CONSTEXPR_EXPECT_NOT((eve::same_lanes_or_scalar<wide<int>,wide<char>>));
};

TTS_CASE( "Check same_lanes_or_scalar on mixed types" )
{
using eve::wide;
using eve::fixed;

TTS_CONSTEXPR_EXPECT((eve::same_lanes_or_scalar<float,wide<int>>));
TTS_CONSTEXPR_EXPECT((eve::same_lanes_or_scalar<wide<int>,double,wide<float>>));
TTS_CONSTEXPR_EXPECT((eve::same_lanes_or_scalar<wide<int,fixed<8>>,short,wide<char,fixed<8>>>));
TTS_CONSTEXPR_EXPECT_NOT((eve::same_lanes_or_scalar<wide<int,fixed<8>>,short,wide<char,fixed<2>>>));
TTS_CONSTEXPR_EXPECT_NOT((eve::same_lanes_or_scalar<double,wide<int>,wide<char>>));
};

0 comments on commit d2ec2f6

Please sign in to comment.