From b16f1266bcf249f424911462c12ba04f8eb399b0 Mon Sep 17 00:00:00 2001 From: Joel Falcou Date: Sat, 23 Sep 2023 10:59:36 +0200 Subject: [PATCH] Better support for non-Cayley types in if_else --- .github/workflows/unit.yml | 60 ++++--------------------- include/kyosu/types/impl/arithmetic.hpp | 28 ++++++------ test/unit/function/if_else.cpp | 24 +++++++++- 3 files changed, 46 insertions(+), 66 deletions(-) diff --git a/.github/workflows/unit.yml b/.github/workflows/unit.yml index 9ce6e577..10908378 100644 --- a/.github/workflows/unit.yml +++ b/.github/workflows/unit.yml @@ -14,44 +14,20 @@ concurrency: cancel-in-progress: true jobs: - - # windows: - # runs-on: [windows-2022] - # strategy: - # fail-fast: false - # matrix: - # cfg: - # - { tool: "-T ClangCL", config: Debug } - # - { tool: "-T ClangCL", config: Release } - # # - { tool: , config: Debug } - # # - { tool: , config: Release } - # steps: - # - name: Fetch current branch - # uses: actions/checkout@v3 - # - name: Running CMake for MSVC - # run: | - # mkdir build && cd build - # cmake -G "Visual Studio 17 2022" ${{ matrix.cfg.tool }} -A x64 .. - # - name: Compiling Unit Tests - # run: | - # cd build - # cmake --build . --target kyosu-test --config ${{ matrix.cfg.config }} --parallel 2 - # cmake --build . --target kyosu-test --config Release --parallel 2 - # - name: Running Tests - # run: | - # cd build - # ctest -C ${{ matrix.cfg.config }} --output-on-failure - linux: runs-on: [self-hosted] strategy: fail-fast: false matrix: cfg: - - { compiler: g++-12 , opts: "-O0 -DEVE_NO_FORCEINLINE" } - - { compiler: g++-12 , opts: "-O3 -DNDEBUG" } - - { compiler: clang++ , opts: "-O0 -DEVE_NO_FORCEINLINE" } - - { compiler: clang++ , opts: "-O3 -DNDEBUG" } + - { compiler: g++-12 , opts: "-O0 -DEVE_NO_FORCEINLINE" } + - { compiler: g++-12 , opts: "-O3 -DNDEBUG" } + - { compiler: clang++ , opts: "-O0 -DEVE_NO_FORCEINLINE" } + - { compiler: clang++ , opts: "-O3 -DNDEBUG" } + - { compiler: g++-12 , opts: "-O0 -DEVE_NO_FORCEINLINE -mavx2" } + - { compiler: g++-12 , opts: "-O3 -DNDEBUG -mavx2" } + - { compiler: clang++ , opts: "-O0 -DEVE_NO_FORCEINLINE -mavx2" } + - { compiler: clang++ , opts: "-O3 -DNDEBUG -mavx2" } steps: - name: Fetch current branch uses: actions/checkout@v3 @@ -68,7 +44,7 @@ jobs: fail-fast: false matrix: cfg: - - { compiler: g++-12 , opts: "-O0 -DEVE_NO_FORCEINLINE" , linker: } + - { compiler: g++-12 , opts: "-O0 -DEVE_NO_FORCEINLINE", linker: } # - { compiler: g++-12 , opts: "-O3 -DNDEBUG" , linker: } # - { compiler: clang++ , opts: "-O0" , linker: } # - { compiler: clang++ , opts: "-O3 -flto -DNDEBUG" , linker: } @@ -83,21 +59,3 @@ jobs: cmake .. -DCMAKE_CXX_COMPILER=${{ matrix.cfg.compiler }} -DCMAKE_CXX_FLAGS="${{ matrix.cfg.opts }}" -DCMAKE_EXE_LINKER_FLAGS=${{ matrix.cfg.linker }} - name: Running Unit Tests run: cd build && make kyosu-test -j 2 && ctest --output-on-failure -j 2 - - # android: - # runs-on: [macos-12] - # strategy: - # fail-fast: false - # matrix: - # cfg: - # - { opts: -O0 } - # - { opts: "-O3 -flto -DNDEBUG"} - # steps: - # - name: Fetch current branch - # uses: actions/checkout@v3 - # - name: Running CMake for ${{ matrix.cfg.compiler }} with ${{ matrix.cfg.opts }} - # run: | - # mkdir build && cd build - # cmake .. -DCMAKE_TOOLCHAIN_FILE=$ANDROID_NDK_ROOT/build/cmake/android.toolchain.cmake -DANDROID_ABI=arm64-v8a - # - name: Compiling Unit Tests - # run: cd build && make kyosu-test -j 2 diff --git a/include/kyosu/types/impl/arithmetic.hpp b/include/kyosu/types/impl/arithmetic.hpp index 7501fe8e..7854aab1 100644 --- a/include/kyosu/types/impl/arithmetic.hpp +++ b/include/kyosu/types/impl/arithmetic.hpp @@ -40,27 +40,27 @@ namespace kyosu::_ if constexpr(concepts::cayley_dickson && concepts::cayley_dickson) { using type = as_cayley_dickson_t; - using ret_t = std::conditional_t, eve::as_wide_as_t, type>; - constexpr eve::as> tgt = {}; + using ret_t = eve::as_wide_as_t; return ret_t{ kumi::map ( [&](auto const& v, auto const& w) { return eve::if_else(m, v, w); } - , kyosu::convert(t, tgt), kyosu::convert(f, tgt) + , kyosu::convert(t, eve::as_element{}) + , kyosu::convert(f, eve::as_element{}) ) }; } - else if constexpr(concepts::cayley_dickson && !concepts::cayley_dickson) - { - auto parts = kumi::map([&](auto const& v) { return eve::if_else(m, v, f); }, t); - - if constexpr(eve::simd_value) return eve::as_wide_as_t{parts}; - else return T{parts}; - } - else if constexpr(!concepts::cayley_dickson && concepts::cayley_dickson) + else { - auto parts = kumi::map([&](auto const& w) { return eve::if_else(m, t, w); }, f); + auto parts = [&]() + { + auto cst = [](auto x, I const&) { if constexpr(I::value == 0) return x; else return eve::zero; }; + if constexpr(!concepts::cayley_dickson) + return kumi::map_index([&](auto i, auto const& e) { return eve::if_else(m, e, cst(f, i)); }, t); + else if constexpr(!concepts::cayley_dickson) + return kumi::map_index([&](auto i, auto const& e) { return eve::if_else(m, cst(t, i), e); }, f); + }(); - if constexpr(eve::simd_value) return eve::as_wide_as_t{parts}; - else return U{parts}; + using type = eve::as_wide_as_t,T,U>,Mask>; + return type{parts}; } } diff --git a/test/unit/function/if_else.cpp b/test/unit/function/if_else.cpp index d121c712..fe5e5181 100644 --- a/test/unit/function/if_else.cpp +++ b/test/unit/function/if_else.cpp @@ -55,10 +55,32 @@ TTS_CASE_WITH ( "Check behavior of if_else on SIMD cayley-dickson" for(auto e : a0) { - auto m = eve::is_odd(e); + auto m = eve::is_lez(e); TTS_EQUAL(kyosu::if_else(m, wc_t(c_t(0,-e)) , wc_t(c_t(0,e))) , wc_t(c_t(0,m ? -e : e))); TTS_EQUAL(kyosu::if_else(m, wq_t(q_t(0,-e,1,-2)), wq_t(q_t(0,e,-1,2))), wq_t(q_t(0,m ? -e : e,m ? 1 : -1,m ? -2 : 2))); TTS_EQUAL(kyosu::if_else(m, wc_t(c_t(0,-e)) , wq_t(q_t(0,e,-1,2))), wq_t(q_t(0,m ? -e : e,m ? 0 : -1,m ? 0 : 2))); TTS_EQUAL(kyosu::if_else(m, wq_t(q_t(0,-e,1,-2)), wc_t(c_t(0, e))) , wq_t(q_t(0,m ? -e : e,m ? 1 : 0,m ? -2 : 0))); } }; + + +TTS_CASE_WITH ( "Check behavior of if_else on cayley-dickson/named constants" + , tts::bunch + , tts::generate(tts::randoms(-10,+10)) + ) +(T const& a0 ) +{ + using e_t = typename T::value_type; + using c_t = kyosu::complex_t; + using wc_t = eve::wide; + + for(auto e : a0) + { + auto m = eve::is_lez(e); + + TTS_EQUAL(kyosu::if_else(m, c_t(0,-e) , eve::one) , c_t(m ? 0 : 1, m ? -e : 0) ); + TTS_EQUAL(kyosu::if_else(m, wc_t(c_t(0,-e)), eve::one) , wc_t(c_t(m ? 0 : 1, m ? -e : 0)) ); + TTS_EQUAL(kyosu::if_else(m, eve::one, c_t(-2,-e) ), c_t(m ? 1 : -2, m ? 0 : -e) ); + TTS_EQUAL(kyosu::if_else(m, eve::one, wc_t(c_t(-2,-e))), wc_t(c_t(m ? 1 : -2, m ? 0 : -e)) ); + } +};