Fix <version> inclusion and ambiguous constructors/assignments libeigen/eigen!2945
diff --git a/Eigen/src/Core/Array.h b/Eigen/src/Core/Array.h index aaea6bb..1be77aa 100644 --- a/Eigen/src/Core/Array.h +++ b/Eigen/src/Core/Array.h
@@ -95,7 +95,7 @@ * * \callgraph */ - EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Array& operator=(const Array& other) { return Base::_set(other); } + EIGEN_DEVICE_FUNC constexpr EIGEN_STRONG_INLINE Array& operator=(const Array& other) { return Base::_set(other); } /** Default constructor. * @@ -113,8 +113,8 @@ #endif /** \brief Move constructor */ EIGEN_DEVICE_FUNC constexpr Array(Array&&) = default; - EIGEN_DEVICE_FUNC Array& operator=(Array&& other) noexcept(std::is_nothrow_move_assignable<Scalar>::value) { - Base::operator=(std::move(other)); + EIGEN_DEVICE_FUNC constexpr Array& operator=(Array&& other) noexcept(std::is_nothrow_move_assignable<Scalar>::value) { + this->m_storage = std::move(other.m_storage); return *this; } @@ -244,9 +244,15 @@ #ifdef EIGEN_ARRAY_PLUGIN #include EIGEN_ARRAY_PLUGIN #endif + template <typename OtherDerived> + EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Array& operator=(const EigenBase<OtherDerived>& other) { + return Base::operator=(other); + } - // NVHPC requires inherited assignment operators to be introduced after the local overloads. - using Base::operator=; + template <typename OtherDerived> + EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Array& operator=(const ReturnByValue<OtherDerived>& func) { + return Base::operator=(func); + } private: template <typename MatrixType, typename OtherDerived, bool SwapPointers>
diff --git a/Eigen/src/Core/Matrix.h b/Eigen/src/Core/Matrix.h index 09d0668..ee3f328 100644 --- a/Eigen/src/Core/Matrix.h +++ b/Eigen/src/Core/Matrix.h
@@ -261,7 +261,7 @@ */ EIGEN_DEVICE_FUNC constexpr Matrix& operator=(Matrix&& other) noexcept( std::is_nothrow_move_assignable<Scalar>::value) { - Base::operator=(std::move(other)); + this->m_storage = std::move(other.m_storage); return *this; }
diff --git a/Eigen/src/Core/util/ConfigureVectorization.h b/Eigen/src/Core/util/ConfigureVectorization.h index f3b1fab..3f7612e 100644 --- a/Eigen/src/Core/util/ConfigureVectorization.h +++ b/Eigen/src/Core/util/ConfigureVectorization.h
@@ -52,15 +52,9 @@ #endif // Align to the boundary that avoids false sharing. -// https://en.cppreference.com/w/cpp/thread/hardware_destructive_interference_size -// There is a bug in android NDK < r26 where the macro is defined but std::hardware_destructive_interference_size -// still does not exist. -#if defined(__cpp_lib_hardware_interference_size) && __cpp_lib_hardware_interference_size >= 201603 && \ - (!EIGEN_OS_ANDROID || __NDK_MAJOR__ + 0 >= 26) -#include <new> -#define EIGEN_ALIGN_TO_AVOID_FALSE_SHARING EIGEN_ALIGN_TO_BOUNDARY(std::hardware_destructive_interference_size) -#else -// Overalign for the cache line size of 128 bytes (Apple M1) +// Pinned to 128 bytes to preserve a stable ABI across architectures and standard libraries +// and avoid GCC -Winterference-size warnings. +#ifndef EIGEN_ALIGN_TO_AVOID_FALSE_SHARING #define EIGEN_ALIGN_TO_AVOID_FALSE_SHARING EIGEN_ALIGN_TO_BOUNDARY(128) #endif
diff --git a/Eigen/src/Core/util/Macros.h b/Eigen/src/Core/util/Macros.h index da0e157..d4a41c0 100644 --- a/Eigen/src/Core/util/Macros.h +++ b/Eigen/src/Core/util/Macros.h
@@ -14,6 +14,11 @@ // IWYU pragma: private #include "../InternalHeaderCheck.h" +// for __cpp_lib feature test macros +#if defined(__has_include) && __has_include(<version>) +#include <version> +#endif + //------------------------------------------------------------------------------------------ // Eigen version and basic defaults //------------------------------------------------------------------------------------------
diff --git a/test/constexpr.cpp b/test/constexpr.cpp index 8a0a90c..98687aa 100644 --- a/test/constexpr.cpp +++ b/test/constexpr.cpp
@@ -18,6 +18,20 @@ Matrix<Scalar, Rows, Rows> A; }; +template <typename Scalar, int Rows> +struct ConstexprArrayTest { + constexpr ConstexprArrayTest(const Array<Scalar, Rows, Rows>& B) { A = B; } + + Array<Scalar, Rows, Rows> A; +}; + +template <typename Scalar, int Rows> +struct ConstexprArrayMoveTest { + constexpr ConstexprArrayMoveTest(Array<Scalar, Rows, Rows> B) { A = std::move(B); } + + Array<Scalar, Rows, Rows> A; +}; + EIGEN_DECLARE_TEST(constexpr) { // Clang accepts (some of) this code when using C++14/C++17, but GCC does not like // the fact that `T array[Size]` inside Eigen::internal::plain_array is not initialized @@ -53,6 +67,16 @@ static_assert(obj2.A(0) == 1); static_assert(obj2.A.coeff(0, 1) == 2); + constexpr ConstexprArrayTest<double, 2> arr_obj1(Array22d({{1, 2}, {3, 4}})); + VERIFY_IS_EQUAL(arr_obj1.A.size(), 4); + static_assert(arr_obj1.A(0, 0) == 1); + static_assert(arr_obj1.A(0) == 1); + static_assert(arr_obj1.A.coeff(0, 1) == 2); + + constexpr ConstexprArrayMoveTest<double, 2> arr_move_obj(Array22d({{1, 2}, {3, 4}})); + static_assert(arr_move_obj.A(0, 0) == 1); + static_assert(arr_move_obj.A.coeff(0, 1) == 2); + // Also check dynamic size arrays/matrices with fixed-size storage (currently // only works if all elements are initialized, since otherwise the compiler // complains about uninitialized trailing elements.
diff --git a/test/initializer_list_construction.cpp b/test/initializer_list_construction.cpp index cbc8451..54b9d42 100644 --- a/test/initializer_list_construction.cpp +++ b/test/initializer_list_construction.cpp
@@ -227,6 +227,23 @@ } VERIFY_IS_EQUAL(m, m2); } + // Test braced-init-list assignment. + { + Matrix<Scalar, 4, 1> m; + m = {Scalar(11), Scalar(12), Scalar(13), Scalar(14)}; + VERIFY_IS_EQUAL(m(0), Scalar(11)); + VERIFY_IS_EQUAL(m(1), Scalar(12)); + VERIFY_IS_EQUAL(m(2), Scalar(13)); + VERIFY_IS_EQUAL(m(3), Scalar(14)); + } + { + Matrix<Scalar, 1, 4> m; + m = {Scalar(11), Scalar(12), Scalar(13), Scalar(14)}; + VERIFY_IS_EQUAL(m(0), Scalar(11)); + VERIFY_IS_EQUAL(m(1), Scalar(12)); + VERIFY_IS_EQUAL(m(2), Scalar(13)); + VERIFY_IS_EQUAL(m(3), Scalar(14)); + } } template <typename Scalar> @@ -291,6 +308,23 @@ } VERIFY_IS_APPROX(m, m2); } + // Test braced-init-list assignment. + { + Array<Scalar, 4, 1> a; + a = {Scalar(11), Scalar(12), Scalar(13), Scalar(14)}; + VERIFY_IS_EQUAL(a(0), Scalar(11)); + VERIFY_IS_EQUAL(a(1), Scalar(12)); + VERIFY_IS_EQUAL(a(2), Scalar(13)); + VERIFY_IS_EQUAL(a(3), Scalar(14)); + } + { + Array<Scalar, 1, 4> a; + a = {Scalar(11), Scalar(12), Scalar(13), Scalar(14)}; + VERIFY_IS_EQUAL(a(0), Scalar(11)); + VERIFY_IS_EQUAL(a(1), Scalar(12)); + VERIFY_IS_EQUAL(a(2), Scalar(13)); + VERIFY_IS_EQUAL(a(3), Scalar(14)); + } } template <typename Scalar>
diff --git a/test/preprocessor_directives.cpp b/test/preprocessor_directives.cpp index d361457..3204187 100644 --- a/test/preprocessor_directives.cpp +++ b/test/preprocessor_directives.cpp
@@ -21,6 +21,8 @@ #define EIGEN_DEFAULT_DENSE_INDEX_TYPE int #elif defined(EIGEN_TEST_PART_3) #define EIGEN_64BIT_BLAS +#elif defined(EIGEN_TEST_PART_4) +#define EIGEN_ALIGN_TO_AVOID_FALSE_SHARING EIGEN_ALIGN_TO_BOUNDARY(256) #endif #include "main.h" @@ -45,6 +47,19 @@ EIGEN_DEFAULT_ALIGN_BYTES, "local_nested_eval_wrapper no longer follows EIGEN_DEFAULT_ALIGN_BYTES"); +// EIGEN_ALIGN_TO_AVOID_FALSE_SHARING must honor pre-existing definitions and stay pinned to 128 by default. +struct AvoidFalseSharingAligned { + EIGEN_ALIGN_TO_AVOID_FALSE_SHARING char c; +}; + +#if defined(EIGEN_TEST_PART_4) +static_assert(alignof(AvoidFalseSharingAligned) == 256, + "Pre-existing EIGEN_ALIGN_TO_AVOID_FALSE_SHARING definition was not preserved"); +#else +static_assert(alignof(AvoidFalseSharingAligned) == 128, + "EIGEN_ALIGN_TO_AVOID_FALSE_SHARING should be pinned to 128 bytes by default"); +#endif + // Per-part checks that the override actually took effect. #if defined(EIGEN_TEST_PART_2) static_assert(std::is_same<Eigen::Index, int>::value, "EIGEN_DEFAULT_DENSE_INDEX_TYPE was ignored"); @@ -67,8 +82,18 @@ #endif } +void check_false_sharing_alignment() { +#if defined(EIGEN_TEST_PART_4) + VERIFY_IS_EQUAL(std::size_t(alignof(AvoidFalseSharingAligned)), std::size_t(256)); +#else + VERIFY_IS_EQUAL(std::size_t(alignof(AvoidFalseSharingAligned)), std::size_t(128)); +#endif +} + EIGEN_DECLARE_TEST(preprocessor_directives) { CALL_SUBTEST_1(check_index_type()); + CALL_SUBTEST_1(check_false_sharing_alignment()); CALL_SUBTEST_2(check_index_type()); CALL_SUBTEST_3(check_blas_index()); + CALL_SUBTEST_4(check_false_sharing_alignment()); }