From b0d4e87e8429fbf4f558d7aea3082a7e876b9f0e Mon Sep 17 00:00:00 2001 From: James Mitchell Date: Wed, 19 Nov 2025 13:56:08 +0000 Subject: [PATCH 1/2] Fix is_partial_transformation --- include/hpcombi/epu8_impl.hpp | 30 +++++++++++++++++++++++++----- tests/test_perm16.cpp | 28 ++++++++++++++++++++++++++++ 2 files changed, 53 insertions(+), 5 deletions(-) diff --git a/include/hpcombi/epu8_impl.hpp b/include/hpcombi/epu8_impl.hpp index 702372c3..a5fefcca 100644 --- a/include/hpcombi/epu8_impl.hpp +++ b/include/hpcombi/epu8_impl.hpp @@ -52,6 +52,27 @@ namespace HPCombi { +static constexpr const std::array MASK = + { + Epu8(0), + {0xFF, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0xFF, 0xFF, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0xFF, 0xFF, 0xFF, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0xFF, 0xFF, 0xFF, 0xFF, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0, 0, 0, 0, 0, 0, 0, 0}, + {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0, 0, 0, 0, 0, 0, 0}, + {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0, 0, 0, 0, 0, 0}, + {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0, 0, 0, 0, 0}, + {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0, 0, 0, 0}, + {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0, 0, 0}, + {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0, 0}, + {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0}, + Epu8(0xFF) + }; + /////////////////////////////////////////////////////////////////////////////// // Implementation part for inline functions /////////////////////////////////////////////////////////////////////////////// @@ -483,12 +504,11 @@ inline epu8 popcount16(epu8 v) noexcept { permuted(Epu8.popcount(), v >> 4)); } + + inline bool is_partial_transformation(epu8 v, const size_t k) noexcept { - uint64_t diff = last_diff(v, Epu8.id(), 16); - // (forall x in v, x + 1 <= 16) and - // (v = Perm16::one() or last diff index < 16) - return (simde_mm_movemask_epi8(v + Epu8(1) <= Epu8(0x10)) == 0xffff) && - (diff == 16 || diff < k); + HPCOMBI_ASSERT(k <= 16); + return simde_mm_movemask_epi8((v & MASK[k]) + Epu8(1) <= Epu8(0x10)) == 0xffff; } inline bool is_transformation(epu8 v, const size_t k) noexcept { diff --git a/tests/test_perm16.cpp b/tests/test_perm16.cpp index c0f347e1..ac904b61 100644 --- a/tests/test_perm16.cpp +++ b/tests/test_perm16.cpp @@ -535,4 +535,32 @@ TEST_CASE_METHOD(Perm16Fixture, "Perm16::left_weak_leq", "[Perm16][044]") { } } } + +TEST_CASE("PTransf16::validate", "[PTransf16][045]") { + PTransf16 x({0, 1, 255}); + REQUIRE(x.validate(16)); + REQUIRE(x.validate(2)); + REQUIRE(x.validate(3)); + + x = PTransf16({0, 1}); + REQUIRE(x.validate(16)); + REQUIRE(x.validate(2)); + REQUIRE(x.validate(3)); + + x = PTransf16({1, 0}); + REQUIRE(x.validate(16)); + REQUIRE(x.validate(2)); + REQUIRE(x.validate(3)); + + x = PTransf16({0xFF, 0}); + REQUIRE(x.validate(16)); + REQUIRE(x.validate(1)); + REQUIRE(x.validate(2)); + REQUIRE(x.validate(3)); + + x = PTransf16({0, 1, 2, 17}); + REQUIRE(x.validate(3)); + REQUIRE(!x.validate(4)); + REQUIRE(!x.validate()); +} } // namespace HPCombi From 826446a8b126a5fbc9dc4f13aef1dec01b2cbf0b Mon Sep 17 00:00:00 2001 From: James Mitchell Date: Wed, 19 Nov 2025 16:13:34 +0000 Subject: [PATCH 2/2] Adjust is_partial_transformation tests in test_epu8 --- tests/test_epu8.cpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/tests/test_epu8.cpp b/tests/test_epu8.cpp index 2b35bb39..62c66b08 100644 --- a/tests/test_epu8.cpp +++ b/tests/test_epu8.cpp @@ -648,17 +648,17 @@ TEST_CASE_METHOD(Fix, "is_partial_transformation", "[Epu8][063]") { CHECK(is_partial_transformation(Epu8({}, 0xff))); CHECK(is_partial_transformation(Epu8({2, 0xff, 3}, 0))); - CHECK(!is_partial_transformation(zero, 15)); + CHECK(is_partial_transformation(zero, 15)); CHECK(is_partial_transformation(Pa)); CHECK(is_partial_transformation(Pa, 6)); CHECK(is_partial_transformation(Pa, 5)); - CHECK(!is_partial_transformation(Pa, 4)); - CHECK(!is_partial_transformation(Pa, 1)); - CHECK(!is_partial_transformation(Pa, 0)); + CHECK(is_partial_transformation(Pa, 4)); + CHECK(is_partial_transformation(Pa, 1)); + CHECK(is_partial_transformation(Pa, 0)); CHECK(is_partial_transformation(RP)); CHECK(is_partial_transformation(RP, 16)); - CHECK(!is_partial_transformation(RP, 15)); + CHECK(is_partial_transformation(RP, 15)); CHECK(is_partial_transformation(Epu8({1, 2, 1, 0xFF, 0, 5, 0xFF, 2}, 0))); CHECK(!is_partial_transformation(Epu8({1, 2, 1, 0xFF, 0, 16, 0xFF, 2}, 0))); }