diff --git a/benchmark/bench_epu8.cpp b/benchmark/bench_epu8.cpp index 91ae319c..1fc50b92 100644 --- a/benchmark/bench_epu8.cpp +++ b/benchmark/bench_epu8.cpp @@ -255,4 +255,15 @@ TEST_CASE_METHOD(Fix_epu8, "last diff", "[Epu8][000]") { #endif BENCHMARK_LAMBDA2("| lambda", last_diff_mask, Fix_epu8::pairs); } + +TEST_CASE_METHOD(Fix_epu8, "is_permutation", "[Epu8][000]") { + BENCHMARK_FREE_FN("| no lambda", is_permutation_sort, Fix_epu8::perms); + BENCHMARK_FREE_FN("| no lambda", is_permutation_eval, Fix_epu8::perms); + BENCHMARK_FREE_FN("| no lambda", is_permutation, Fix_epu8::perms); + + BENCHMARK_LAMBDA("| lambda", is_permutation_sort, Fix_epu8::perms); + BENCHMARK_LAMBDA("| lambda", is_permutation_eval, Fix_epu8::perms); + BENCHMARK_LAMBDA("| lambda", is_permutation, Fix_epu8::perms); +} + } // namespace HPCombi diff --git a/include/hpcombi/epu.hpp b/include/hpcombi/epu.hpp index 5f1fbe88..1c6e393a 100644 --- a/include/hpcombi/epu.hpp +++ b/include/hpcombi/epu.hpp @@ -689,6 +689,10 @@ inline bool is_permutation_cpmestri(epu8 v, const size_t k = 16) noexcept; @par Algorithm: sort the vector and compare to identity */ inline bool is_permutation_sort(epu8 v, const size_t k = 16) noexcept; +/** @copydoc common_is_permutation + @par Algorithm: uses evaluation + */ +inline bool is_permutation_eval(epu8 v, const size_t k = 16) noexcept; /** @copydoc common_is_permutation @par Algorithm: architecture dependent */ diff --git a/include/hpcombi/epu_impl.hpp b/include/hpcombi/epu_impl.hpp index 70d5d140..dcf436f9 100644 --- a/include/hpcombi/epu_impl.hpp +++ b/include/hpcombi/epu_impl.hpp @@ -489,6 +489,10 @@ inline bool is_permutation_sort(epu8 v, const size_t k) noexcept { uint64_t diff = last_diff(v, epu8id, 16); return equal(sorted(v), epu8id) && (diff == 16 || diff < k); } +inline bool is_permutation_eval(epu8 v, const size_t k) noexcept { + uint64_t diff = last_diff(v, epu8id, 16); + return equal(eval16(v), Epu8({}, 1)) && (diff == 16 || diff < k); +} inline bool is_permutation(epu8 v, const size_t k) noexcept { #ifdef SIMDE_X86_SSE4_2_NATIVE diff --git a/tests/test_epu.cpp b/tests/test_epu.cpp index ac165b6d..f2181625 100644 --- a/tests/test_epu.cpp +++ b/tests/test_epu.cpp @@ -695,7 +695,7 @@ TEST_CASE_METHOD(Fix, "is_permutation", "[Epu8][054]") { TEST_CASE_METHOD(Fix, "is_permutation_cmpestri", "[Epu8][070]") { for (auto x : v) { for (size_t i = 0; i < 16; i++) { - CHECK(is_permutation(x, i) == is_permutation_cmpestri(x, i)); + CHECK(is_permutation_cmpestri(x, i) == is_permutation(x, i)); } } } @@ -704,7 +704,15 @@ TEST_CASE_METHOD(Fix, "is_permutation_cmpestri", "[Epu8][070]") { TEST_CASE_METHOD(Fix, "is_permutation_sort", "[Epu8][080]") { for (auto x : v) { for (size_t i = 0; i < 16; i++) { - CHECK(is_permutation(x, i) == is_permutation_sort(x, i)); + CHECK(is_permutation_sort(x, i) == is_permutation(x, i)); + } + } +} + +TEST_CASE_METHOD(Fix, "is_permutation_eval", "[Epu8][080]") { + for (auto x : v) { + for (size_t i = 0; i < 16; i++) { + CHECK(is_permutation_eval(x, i) == is_permutation(x, i)); } } }