diff --git a/.github/workflows/Clang.yml b/.github/workflows/Clang.yml index 21c8d77..45e79ff 100644 --- a/.github/workflows/Clang.yml +++ b/.github/workflows/Clang.yml @@ -25,7 +25,7 @@ jobs: strategy: fail-fast: false matrix: - version: [16, 17, 20] + version: [16, 17, 20, 23] runs-on: ubuntu-latest @@ -59,7 +59,7 @@ jobs: strategy: fail-fast: false matrix: - version: [14, 15, 17, 20] + version: [15, 17, 20, 23] runs-on: ubuntu-latest diff --git a/.github/workflows/GCC.yml b/.github/workflows/GCC.yml index bfcd096..c02da5b 100644 --- a/.github/workflows/GCC.yml +++ b/.github/workflows/GCC.yml @@ -25,7 +25,7 @@ jobs: strategy: fail-fast: false matrix: - version: [9, 10, 11, 12, 13, 14, 15] + version: [10, 11, 12, 13, 14, 15, 16] runs-on: ubuntu-latest diff --git a/CMakeLists.txt b/CMakeLists.txt index 6e17dc3..d9706b1 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,4 +1,4 @@ -# SPDX-License-Identifier: LGPL-3.0-or-later +# SPDX-License-Identifier: LGPL-3.0-or-later WITH LGPL-3.0-linking-exception # Copyright © 2024 GSI Helmholtzzentrum fuer Schwerionenforschung GmbH # Matthias Kretz # Copyright © 2023 Álvaro Fernández Sánchez diff --git a/LICENSE b/LICENSE index 0a04128..9cfc64b 100644 --- a/LICENSE +++ b/LICENSE @@ -163,3 +163,22 @@ whether future versions of the GNU Lesser General Public License shall apply, that proxy's public statement of acceptance of any version is permanent authorization for you to choose that version for the Library. + + + LGPL-3.0-linking-exception + + As a special exception to the GNU Lesser General Public License +version 3 ("LGPL3"), the copyright holders of this Library give you +permission to convey to a third party a Combined Work that links statically +or dynamically to this Library without providing any Minimal Corresponding +Source or Minimal Application Code as set out in section 4d or providing the +installation information set out in section 4e, provided that you comply with +the other provisions of LGPL3 and provided that you meet, for the Application +the terms and conditions of the license(s) which apply to the Application. + + Except as stated in this special exception, the provisions of LGPL3 will +continue to comply in full to this Library. If you modify this Library, you +may apply this exception to your version of this Library, but you are not +obliged to do so. If you do not wish to do so, delete this exception statement +from your version. This exception does not (and cannot) modify any license +terms which apply to the Application, with which you must still comply. diff --git a/LICENSES/LGPL-3.0-linking-exception.txt b/LICENSES/LGPL-3.0-linking-exception.txt new file mode 100644 index 0000000..186456f --- /dev/null +++ b/LICENSES/LGPL-3.0-linking-exception.txt @@ -0,0 +1,16 @@ +As a special exception to the GNU Lesser General Public License version 3 +("LGPL3"), the copyright holders of this Library give you permission to +convey to a third party a Combined Work that links statically or dynamically +to this Library without providing any Minimal Corresponding Source or +Minimal Application Code as set out in 4d or providing the installation +information set out in section 4e, provided that you comply with the other +provisions of LGPL3 and provided that you meet, for the Application the +terms and conditions of the license(s) which apply to the Application. + +Except as stated in this special exception, the provisions of LGPL3 will +continue to comply in full to this Library. If you modify this Library, you +may apply this exception to your version of this Library, but you are not +obliged to do so. If you do not wish to do so, delete this exception +statement from your version. This exception does not (and cannot) modify any +license terms which apply to the Application, with which you must still +comply. diff --git a/latest_std_flag.sh b/latest_std_flag.sh index e221436..2f955f3 100755 --- a/latest_std_flag.sh +++ b/latest_std_flag.sh @@ -3,7 +3,7 @@ # Copyright © 2023–2024 GSI Helmholtzzentrum fuer Schwerionenforschung GmbH # Matthias Kretz -for std in gnu++23 gnu++2b c++23 c++2b gnu++20 gnu++2a c++20 c++2a gnu++17 c++17; do +for std in gnu++26 c++26 gnu++23 gnu++2b c++23 c++2b gnu++20 gnu++2a c++20 c++2a gnu++17 c++17; do if $CXX -x c++ -c -std=$std /dev/null 2>/dev/null; then echo $std exit diff --git a/stdlibtest.cpp b/stdlibtest.cpp index 686df4e..ca3f6ad 100644 --- a/stdlibtest.cpp +++ b/stdlibtest.cpp @@ -1,4 +1,4 @@ -/* SPDX-License-Identifier: LGPL-3.0-or-later */ +/* SPDX-License-Identifier: LGPL-3.0-or-later WITH LGPL-3.0-linking-exception */ /* Copyright © 2025 GSI Helmholtzzentrum fuer Schwerionenforschung GmbH * Matthias Kretz */ diff --git a/vir/constexpr_wrapper.h b/vir/constexpr_wrapper.h index 2f1cfae..cf8cbce 100644 --- a/vir/constexpr_wrapper.h +++ b/vir/constexpr_wrapper.h @@ -1,4 +1,4 @@ -/* SPDX-License-Identifier: LGPL-3.0-or-later */ +/* SPDX-License-Identifier: LGPL-3.0-or-later WITH LGPL-3.0-linking-exception */ /* Copyright © 2023-2024 GSI Helmholtzzentrum fuer Schwerionenforschung GmbH * Matthias Kretz */ diff --git a/vir/detail.h b/vir/detail.h index 914fe42..fef45f0 100644 --- a/vir/detail.h +++ b/vir/detail.h @@ -1,4 +1,4 @@ -/* SPDX-License-Identifier: LGPL-3.0-or-later */ +/* SPDX-License-Identifier: LGPL-3.0-or-later WITH LGPL-3.0-linking-exception */ /* Copyright © 2022–2024 GSI Helmholtzzentrum fuer Schwerionenforschung GmbH * Matthias Kretz */ diff --git a/vir/simd.h b/vir/simd.h index 5f2d6a8..37e4db9 100644 --- a/vir/simd.h +++ b/vir/simd.h @@ -1,4 +1,4 @@ -/* SPDX-License-Identifier: LGPL-3.0-or-later */ +/* SPDX-License-Identifier: LGPL-3.0-or-later WITH LGPL-3.0-linking-exception */ /* Copyright © 2022–2024 GSI Helmholtzzentrum fuer Schwerionenforschung GmbH * Matthias Kretz */ diff --git a/vir/simd_benchmarking.h b/vir/simd_benchmarking.h index 2f66795..8cd609e 100644 --- a/vir/simd_benchmarking.h +++ b/vir/simd_benchmarking.h @@ -1,4 +1,4 @@ -/* SPDX-License-Identifier: LGPL-3.0-or-later */ +/* SPDX-License-Identifier: LGPL-3.0-or-later WITH LGPL-3.0-linking-exception */ /* Copyright © 2019–2024 GSI Helmholtzzentrum fuer Schwerionenforschung GmbH * Matthias Kretz */ diff --git a/vir/simd_bit.h b/vir/simd_bit.h index 3215af6..c9a2455 100644 --- a/vir/simd_bit.h +++ b/vir/simd_bit.h @@ -1,4 +1,4 @@ -/* SPDX-License-Identifier: LGPL-3.0-or-later */ +/* SPDX-License-Identifier: LGPL-3.0-or-later WITH LGPL-3.0-linking-exception */ /* Copyright © 2022–2024 GSI Helmholtzzentrum fuer Schwerionenforschung GmbH * Matthias Kretz */ diff --git a/vir/simd_bitset.h b/vir/simd_bitset.h index b1946e6..95df643 100644 --- a/vir/simd_bitset.h +++ b/vir/simd_bitset.h @@ -1,4 +1,4 @@ -/* SPDX-License-Identifier: LGPL-3.0-or-later */ +/* SPDX-License-Identifier: LGPL-3.0-or-later WITH LGPL-3.0-linking-exception */ /* Copyright © 2022–2024 GSI Helmholtzzentrum fuer Schwerionenforschung GmbH * Matthias Kretz */ diff --git a/vir/simd_cast.h b/vir/simd_cast.h index 9de1bfe..1377839 100644 --- a/vir/simd_cast.h +++ b/vir/simd_cast.h @@ -1,4 +1,4 @@ -/* SPDX-License-Identifier: LGPL-3.0-or-later */ +/* SPDX-License-Identifier: LGPL-3.0-or-later WITH LGPL-3.0-linking-exception */ /* Copyright © 2022–2024 GSI Helmholtzzentrum fuer Schwerionenforschung GmbH * Matthias Kretz */ diff --git a/vir/simd_concepts.h b/vir/simd_concepts.h index d73786b..ef129b1 100644 --- a/vir/simd_concepts.h +++ b/vir/simd_concepts.h @@ -1,4 +1,4 @@ -/* SPDX-License-Identifier: LGPL-3.0-or-later */ +/* SPDX-License-Identifier: LGPL-3.0-or-later WITH LGPL-3.0-linking-exception */ /* Copyright © 2023–2024 GSI Helmholtzzentrum fuer Schwerionenforschung GmbH * Matthias Kretz */ diff --git a/vir/simd_cvt.h b/vir/simd_cvt.h index 2cec574..22afa43 100644 --- a/vir/simd_cvt.h +++ b/vir/simd_cvt.h @@ -1,4 +1,4 @@ -/* SPDX-License-Identifier: LGPL-3.0-or-later */ +/* SPDX-License-Identifier: LGPL-3.0-or-later WITH LGPL-3.0-linking-exception */ /* Copyright © 2023–2024 GSI Helmholtzzentrum fuer Schwerionenforschung GmbH * Matthias Kretz */ diff --git a/vir/simd_execution.h b/vir/simd_execution.h index 0fb8f6e..f1e2032 100644 --- a/vir/simd_execution.h +++ b/vir/simd_execution.h @@ -1,4 +1,4 @@ -/* SPDX-License-Identifier: LGPL-3.0-or-later */ +/* SPDX-License-Identifier: LGPL-3.0-or-later WITH LGPL-3.0-linking-exception */ /* Copyright © 2023–2024 GSI Helmholtzzentrum fuer Schwerionenforschung GmbH * Matthias Kretz */ diff --git a/vir/simd_float_ops.h b/vir/simd_float_ops.h index f1c06ac..553cacd 100644 --- a/vir/simd_float_ops.h +++ b/vir/simd_float_ops.h @@ -1,4 +1,4 @@ -/* SPDX-License-Identifier: LGPL-3.0-or-later */ +/* SPDX-License-Identifier: LGPL-3.0-or-later WITH LGPL-3.0-linking-exception */ /* Copyright © 2022–2024 GSI Helmholtzzentrum fuer Schwerionenforschung GmbH * Matthias Kretz */ diff --git a/vir/simd_iota.h b/vir/simd_iota.h index 7ca08c0..fc0b762 100644 --- a/vir/simd_iota.h +++ b/vir/simd_iota.h @@ -1,4 +1,4 @@ -/* SPDX-License-Identifier: LGPL-3.0-or-later */ +/* SPDX-License-Identifier: LGPL-3.0-or-later WITH LGPL-3.0-linking-exception */ /* Copyright © 2023–2024 GSI Helmholtzzentrum fuer Schwerionenforschung GmbH * Matthias Kretz */ diff --git a/vir/simd_permute.h b/vir/simd_permute.h index 643264a..7e7ee48 100644 --- a/vir/simd_permute.h +++ b/vir/simd_permute.h @@ -1,4 +1,4 @@ -/* SPDX-License-Identifier: LGPL-3.0-or-later */ +/* SPDX-License-Identifier: LGPL-3.0-or-later WITH LGPL-3.0-linking-exception */ /* Copyright © 2023–2024 GSI Helmholtzzentrum fuer Schwerionenforschung GmbH * Matthias Kretz */ @@ -185,7 +185,7 @@ namespace vir #if defined __GNUC__ if (not std::is_constant_evaluated()) - if constexpr (std::has_single_bit(sizeof(V)) and V::size() <= stdx::native_simd::size()) + if constexpr (std::has_single_bit(sizeof(V)))// and V::size() <= stdx::native_simd::size()) { #if defined __AVX2__ using v4df [[gnu::vector_size(32)]] = double; @@ -330,6 +330,100 @@ namespace vir return a[w + j]; }); } + + template ... Vs> + VIR_ALWAYS_INLINE constexpr stdx::resize_simd_t + simd_interleave(V0 const& v0, Vs const&... vs) noexcept + { + using T = typename V0::value_type; + constexpr unsigned Bytes = sizeof(T) * std::bit_ceil(unsigned(V0::size())); + using VBuiltin [[gnu::vector_size(Bytes)]] = T; + if constexpr (V0::size() == 4 and sizeof...(Vs) == 1 and std::is_trivially_copyable_v) + { + return [](VBuiltin r0, VBuiltin r1) { +#if defined __SSE__ and defined __GNUC__ + return stdx::concat(V0(__builtin_ia32_unpcklps (r0, r1)), + V0(__builtin_ia32_unpckhps (r0, r1))); +#else + return stdx::concat( + std::bit_cast(__builtin_shufflevector(r0, r1, 0, 4, 1, 5)), + std::bit_cast(__builtin_shufflevector(r0, r1, 2, 6, 3, 7))); +#endif + }(std::bit_cast(v0), std::bit_cast(vs)...); + } +#if defined __SSE__ and defined __GNUC__ + else if constexpr (std::is_floating_point_v and sizeof(T) == sizeof(float) + and V0::size() == 4 and sizeof...(Vs) == 3) + { + return [](VBuiltin r0, VBuiltin r1, VBuiltin r2, VBuiltin r3) { + VBuiltin t0 = __builtin_ia32_unpcklps(r0, r1); + VBuiltin t1 = __builtin_ia32_unpcklps(r2, r3); + VBuiltin t2 = __builtin_ia32_unpckhps(r0, r1); + VBuiltin t3 = __builtin_ia32_unpckhps(r2, r3); + return stdx::concat(std::bit_cast(__builtin_ia32_movlhps(t0, t1)), + std::bit_cast(__builtin_ia32_movhlps(t1, t0)), + std::bit_cast(__builtin_ia32_movlhps(t2, t3)), + std::bit_cast(__builtin_ia32_movhlps(t3, t2))); + }(std::bit_cast(v0), std::bit_cast(vs)...); + } +#endif +#if defined __SSE2__ and defined __GNUC__ and __has_builtin(__builtin_ia32_punpckldq128) + else if constexpr (std::is_integral_v and sizeof(T) == sizeof(int) + and V0::size() == 4 and sizeof...(Vs) == 3) + { + using VInt [[gnu::vector_size(16)]] = int; + return [](VInt r0, VInt r1, VInt r2, VInt r3) { + VInt t0 = __builtin_ia32_punpckldq128(r0, r2); + VInt t1 = __builtin_ia32_punpckldq128(r1, r3); + VInt t2 = __builtin_ia32_punpckhdq128(r0, r2); + VInt t3 = __builtin_ia32_punpckhdq128(r1, r3); + return stdx::concat(std::bit_cast(__builtin_ia32_punpckldq128(t0, t1)), + std::bit_cast(__builtin_ia32_punpckhdq128(t0, t1)), + std::bit_cast(__builtin_ia32_punpckldq128(t2, t3)), + std::bit_cast(__builtin_ia32_punpckhdq128(t2, t3))); + }(std::bit_cast(v0), std::bit_cast(vs)...); + } +#endif + else if constexpr (std::is_floating_point_v and sizeof(T) == sizeof(double) + and V0::size() == 4 and sizeof...(Vs) == 3) + { +#if defined __AVX__ and defined __GNUC__ + return [](VBuiltin a, VBuiltin b, VBuiltin c, VBuiltin d) { + VBuiltin t0 = __builtin_ia32_unpcklpd256(a, b); // a0 b0 a2 b2 + VBuiltin t1 = __builtin_ia32_unpcklpd256(c, d); // c0 d0 c2 d2 + VBuiltin t2 = __builtin_ia32_unpckhpd256(a, b); // a1 b1 a3 b3 + VBuiltin t3 = __builtin_ia32_unpckhpd256(c, d); // c1 d1 c3 d3 + return stdx::concat(std::bit_cast(__builtin_ia32_vperm2f128_pd256(t0, t1, 0x20)), + std::bit_cast(__builtin_ia32_vperm2f128_pd256(t2, t3, 0x20)), + std::bit_cast(__builtin_ia32_vperm2f128_pd256(t0, t1, 0x31)), + std::bit_cast(__builtin_ia32_vperm2f128_pd256(t3, t2, 0x31))); + }(std::bit_cast(v0), std::bit_cast(vs)...); +#elif defined __SSE2__ and defined __GNUC__ and __has_builtin(__builtin_ia32_unpcklpd) + using v2df [[gnu::vector_size(16)]] = double; + using v4df = v2df[2]; + return [](auto a0, auto b0, auto c0, auto d0) { + v4df a, b, c, d; + std::memcpy(&a, &a0, sizeof(v4df)); + std::memcpy(&b, &b0, sizeof(v4df)); + std::memcpy(&c, &c0, sizeof(v4df)); + std::memcpy(&d, &d0, sizeof(v4df)); + stdx::fixed_size_simd ret; + v2df tmp[8] = { + __builtin_ia32_unpcklpd(a[0], b[0]), __builtin_ia32_unpcklpd(c[0], d[0]), + __builtin_ia32_unpckhpd(a[0], b[0]), __builtin_ia32_unpckhpd(c[0], d[0]), + __builtin_ia32_unpcklpd(a[1], b[1]), __builtin_ia32_unpcklpd(c[1], d[1]), + __builtin_ia32_unpckhpd(a[1], b[1]), __builtin_ia32_unpckhpd(c[1], d[1]) + }; + std::memcpy(&detail::internal_data_hack(ret, 0), tmp, sizeof(tmp)); + return ret; + }(detail::internal_data_hack(v0, 0), detail::internal_data_hack(vs, 0)...); +#endif + } + return simd_permute(stdx::concat(v0, vs...), [](int i) { + constexpr int N = 1 + sizeof...(vs); + return (i % N) * V0::size() + (i / N); + }); + } } #endif // has concepts diff --git a/vir/simd_resize.h b/vir/simd_resize.h index af5dee6..d494682 100644 --- a/vir/simd_resize.h +++ b/vir/simd_resize.h @@ -1,4 +1,4 @@ -/* SPDX-License-Identifier: LGPL-3.0-or-later */ +/* SPDX-License-Identifier: LGPL-3.0-or-later WITH LGPL-3.0-linking-exception */ /* Copyright © 2022–2024 GSI Helmholtzzentrum fuer Schwerionenforschung GmbH * Matthias Kretz */ diff --git a/vir/simd_version.h b/vir/simd_version.h index e6e4e7b..6389b36 100644 --- a/vir/simd_version.h +++ b/vir/simd_version.h @@ -1,4 +1,4 @@ -/* SPDX-License-Identifier: LGPL-3.0-or-later */ +/* SPDX-License-Identifier: LGPL-3.0-or-later WITH LGPL-3.0-linking-exception */ /* Copyright © 2024–2025 GSI Helmholtzzentrum fuer Schwerionenforschung GmbH * Matthias Kretz */ diff --git a/vir/simdize.h b/vir/simdize.h index a3b7ecd..ded6d3d 100644 --- a/vir/simdize.h +++ b/vir/simdize.h @@ -1,4 +1,4 @@ -/* SPDX-License-Identifier: LGPL-3.0-or-later */ +/* SPDX-License-Identifier: LGPL-3.0-or-later WITH LGPL-3.0-linking-exception */ /* Copyright © 2023–2024 GSI Helmholtzzentrum fuer Schwerionenforschung GmbH * Matthias Kretz */ diff --git a/vir/struct_reflect.h b/vir/struct_reflect.h index 6e5ed58..b6f23c8 100644 --- a/vir/struct_reflect.h +++ b/vir/struct_reflect.h @@ -1,4 +1,4 @@ -/* SPDX-License-Identifier: LGPL-3.0-or-later */ +/* SPDX-License-Identifier: LGPL-3.0-or-later WITH LGPL-3.0-linking-exception */ /* Copyright © 2018–2024 GSI Helmholtzzentrum fuer Schwerionenforschung GmbH * Matthias Kretz */ @@ -27,6 +27,19 @@ namespace vir using std::size_t; // struct_size implementation +#if __cpp_structured_bindings >= 202411L + + template + requires requires { T{}; } + consteval size_t + struct_size() + { + [[maybe_unused]] auto [...pack] = T{}; + return sizeof...(pack); + } + +#else + template struct anything_but_base_of { @@ -117,6 +130,8 @@ namespace vir } } +#endif + // struct_get implementation template struct struct_get; diff --git a/vir/test.cpp b/vir/test.cpp index 1d0cc07..9e77cf7 100644 --- a/vir/test.cpp +++ b/vir/test.cpp @@ -1,4 +1,4 @@ -/* SPDX-License-Identifier: LGPL-3.0-or-later */ +/* SPDX-License-Identifier: LGPL-3.0-or-later WITH LGPL-3.0-linking-exception */ /* Copyright © 2023–2024 GSI Helmholtzzentrum fuer Schwerionenforschung GmbH * Matthias Kretz */ @@ -209,7 +209,7 @@ namespace test_struct_reflect static_assert(vir::reflectable_struct>); static_assert(vir::reflectable_struct>); static_assert(vir::reflectable_struct>); - static_assert(not vir::reflectable_struct>); + static_assert(vir::reflectable_struct>); template struct A @@ -248,10 +248,14 @@ static_assert(std::same_as, void>); static_assert(std::same_as>, std::tuple<>>); -static_assert(std::same_as>, std::complex>); +static_assert(std::same_as>, + vir::vectorized_struct, V::size()>>); + +static_assert(std::is_base_of_v>, vir::simdize>>); static_assert(std::same_as>>, - std::tuple>>); + vir::vectorized_struct>, + V::size()>>); static_assert(std::same_as>, vir::vectorized_struct, V::size()>>); @@ -388,12 +392,10 @@ static_assert(vir::simdize_size_v> == stdx::native_simd::mask_type, typename V::mask_type>); -static_assert(not vir::vectorizable_struct>); -static_assert(not vir::vectorizable_struct>>); -static_assert(not vir::vectorizable_struct, - std::complex>>); -static_assert(not vir::vectorizable_struct>>); +static_assert(vir::vectorizable_struct>); +static_assert(vir::vectorizable_struct>>); +static_assert(vir::vectorizable_struct, std::complex>>); +static_assert(vir::vectorizable_struct>>); void f(typename vir::detail::simdize_template_arguments::type); static_assert(vir::vectorizable_struct_template); diff --git a/vir/test_constexpr_wrapper.cpp b/vir/test_constexpr_wrapper.cpp index 1f17a86..866a6b1 100644 --- a/vir/test_constexpr_wrapper.cpp +++ b/vir/test_constexpr_wrapper.cpp @@ -1,4 +1,4 @@ -/* SPDX-License-Identifier: LGPL-3.0-or-later */ +/* SPDX-License-Identifier: LGPL-3.0-or-later WITH LGPL-3.0-linking-exception */ /* Copyright © 2023–2024 GSI Helmholtzzentrum fuer Schwerionenforschung GmbH * Matthias Kretz */