Skip to content

refactor: replace swizzle template recursion with C++17 constexpr - #1393

Open
DiamonDinoia wants to merge 2 commits into
xtensor-stack:masterfrom
DiamonDinoia:swizzle-constexpr-predicates
Open

refactor: replace swizzle template recursion with C++17 constexpr #1393
DiamonDinoia wants to merge 2 commits into
xtensor-stack:masterfrom
DiamonDinoia:swizzle-constexpr-predicates

Conversation

@DiamonDinoia

Copy link
Copy Markdown
Contributor

No description provided.

…dicates

The swizzle mask predicates were written as recursive class/function
templates for the C++14 era. The project moved to C++17 in ea590d5, so
they can be plain constexpr functions.

is_identity, is_only_from_lo and is_only_from_hi become one-line fold
expressions. is_dup_lo/is_dup_hi share a single is_dup_from_half loop --
a fold cannot express them because they compare v[i] against v[i+half].
Deletes get_at, identity_impl, dup_lo_impl, dup_hi_impl,
only_from_lo_impl, only_from_hi_impl, get_nth_value, cross_impl, the
forwarding wrappers, the unused is_cross_lane<uint32_t...> overload and
the now-unused <cstdint>. Public signatures are unchanged, so no call
site moves. Net -135/+28 lines.

Verified equivalent to the previous implementation by 27230
static_assert(old(...) == new(...)) checks over 5446 masks (exhaustive
for N=2 and N=4 including out-of-range indices, sampled plus structured
patterns for N=8/N=16; uint32_t, uint16_t, int8_t, int64_t) under both
g++ and clang++. The harness was mutation-tested: an off-by-one counter,
a flipped comparison and a dropped range check are caught by 15, 370 and
1266 assertions respectively. Generated asm for ~45 swizzle kernels is
byte-identical on sse2, avx2 and skylake-avx512.

Adds static_asserts for narrow and signed index types (uint16_t, uint8_t,
int8_t, int64_t) and for degenerate N=1/N=2 masks, which the previous
tests only covered for uint32_t.
XSIMD_INLINE constexpr bool is_dup_from_half() noexcept
{
constexpr std::size_t half = sizeof...(Vs) / 2;
constexpr T lo = Hi ? static_cast<T>(half) : T(0);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i think this would be much easier to understand if implemented with the Hi == true logic speerated from the Hi == false logic.

{
    if constexpr(Hi) { ...}
    else { ...}
}

esp. for this condition if (v[i] < lo || v[i] >= hi || v[i + half] != v[i]) which looks different from i<H but V>=H) or (i>=H but V<H)

Address review: the shared is_dup_from_half<Hi> helper hid the intent
behind 'v[i] < lo || v[i] >= hi || v[i + half] != v[i]'. Each direction
is now a conjunction of named properties (in-range, only-from-half,
equal-halves), differing by exactly one term.

Adds the negative-index dup_lo case previously covered by the explicit
lower bound.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants