From 447dfb0627552b18a1136aa1dc8b6f49157e8b7f Mon Sep 17 00:00:00 2001 From: Dirk Eddelbuettel Date: Thu, 4 Jun 2026 19:26:16 -0500 Subject: [PATCH 1/4] Synchronized with upstream 5.0.1 release (via git tag in 5.0 branch) --- inst/include/Eigen/CholmodSupport | 2 +- inst/include/Eigen/Core | 5 + inst/include/Eigen/Version | 4 +- .../Eigen/src/CholmodSupport/CholmodSupport.h | 64 ++++----- inst/include/Eigen/src/Core/Assign_MKL.h | 8 +- inst/include/Eigen/src/Core/CwiseNullaryOp.h | 8 +- inst/include/Eigen/src/Core/DenseStorage.h | 9 +- inst/include/Eigen/src/Core/Fill.h | 8 +- inst/include/Eigen/src/Core/InnerProduct.h | 8 +- inst/include/Eigen/src/Core/MathFunctions.h | 4 +- .../Eigen/src/Core/PermutationMatrix.h | 3 + .../Eigen/src/Core/arch/AVX/PacketMath.h | 4 +- .../Eigen/src/Core/arch/AVX/TypeCasting.h | 4 +- .../Eigen/src/Core/arch/NEON/Complex.h | 46 +++---- .../Eigen/src/Core/arch/NEON/PacketMath.h | 126 +++++++----------- .../Eigen/src/Core/arch/SSE/PacketMath.h | 6 +- .../src/Core/util/DisableStupidWarnings.h | 72 +++++----- inst/include/Eigen/src/Core/util/Macros.h | 20 +++ inst/include/Eigen/src/Core/util/Memory.h | 56 +++++--- .../Eigen/src/Householder/Householder.h | 3 +- .../include/Eigen/src/KLUSupport/KLUSupport.h | 2 +- .../Eigen/src/PardisoSupport/PardisoSupport.h | 3 +- inst/include/Eigen/src/SVD/JacobiSVD.h | 19 +++ .../src/SparseCholesky/SimplicialCholesky.h | 15 ++- .../src/SparseCore/SparseCompressedBase.h | 1 + .../Eigen/src/SparseCore/SparseVector.h | 8 +- .../Eigen/src/SuperLUSupport/SuperLUSupport.h | 6 +- .../Eigen/src/UmfPackSupport/UmfPackSupport.h | 2 +- .../ArpackSelfAdjointEigenSolver.h | 14 +- .../src/SparseExtra/MatrixMarketIterator.h | 2 - 30 files changed, 292 insertions(+), 240 deletions(-) diff --git a/inst/include/Eigen/CholmodSupport b/inst/include/Eigen/CholmodSupport index bff39e6..adc5f8d 100644 --- a/inst/include/Eigen/CholmodSupport +++ b/inst/include/Eigen/CholmodSupport @@ -12,7 +12,7 @@ #include "src/Core/util/DisableStupidWarnings.h" -#include +#include /** \ingroup Support_modules * \defgroup CholmodSupport_Module CholmodSupport module diff --git a/inst/include/Eigen/Core b/inst/include/Eigen/Core index 4ce2ed9..34838f5 100644 --- a/inst/include/Eigen/Core +++ b/inst/include/Eigen/Core @@ -106,6 +106,11 @@ #include #endif +// for __cpp_lib feature test macros +#if defined(__has_include) && __has_include() +#include +#endif + // for std::bit_cast() #if defined(__cpp_lib_bit_cast) && __cpp_lib_bit_cast >= 201806L #include diff --git a/inst/include/Eigen/Version b/inst/include/Eigen/Version index 91936c2..9cfd71f 100644 --- a/inst/include/Eigen/Version +++ b/inst/include/Eigen/Version @@ -6,9 +6,9 @@ // As of Eigen3 5.0.0, we have moved to Semantic Versioning (semver.org). #define EIGEN_MAJOR_VERSION 5 #define EIGEN_MINOR_VERSION 0 -#define EIGEN_PATCH_VERSION 0 +#define EIGEN_PATCH_VERSION 1 #define EIGEN_PRERELEASE_VERSION "" #define EIGEN_BUILD_VERSION "" -#define EIGEN_VERSION_STRING "5.0.0" +#define EIGEN_VERSION_STRING "5.0.1" #endif // EIGEN_VERSION_H diff --git a/inst/include/Eigen/src/CholmodSupport/CholmodSupport.h b/inst/include/Eigen/src/CholmodSupport/CholmodSupport.h index 758fb5a..7e3c881 100644 --- a/inst/include/Eigen/src/CholmodSupport/CholmodSupport.h +++ b/inst/include/Eigen/src/CholmodSupport/CholmodSupport.h @@ -13,10 +13,6 @@ // IWYU pragma: private #include "./InternalHeaderCheck.h" -#ifndef R_MATRIX_CHOLMOD -# define R_MATRIX_CHOLMOD(_NAME_) cholmod_ ## _NAME_ -#endif - namespace Eigen { namespace internal { @@ -88,8 +84,8 @@ cholmod_sparse viewAsCholmod(Ref if (internal::is_same::value) { res.itype = CHOLMOD_INT; - // } else if (internal::is_same::value) { - // res.itype = CHOLMOD_LONG; + } else if (internal::is_same::value) { + res.itype = CHOLMOD_LONG; } else { eigen_assert(false && "Index type not supported yet"); } @@ -176,14 +172,22 @@ namespace internal { #define EIGEN_CHOLMOD_SPECIALIZE0(ret, name) \ template \ inline ret cm_##name(cholmod_common& Common) { \ - return R_MATRIX_CHOLMOD(name)(&Common); \ - } + return cholmod_##name(&Common); \ + } \ + template <> \ + inline ret cm_##name(cholmod_common & Common) { \ + return cholmod_l_##name(&Common); \ + } -#define EIGEN_CHOLMOD_SPECIALIZE1(ret, name, t1, a1) \ - template \ - inline ret cm_##name(t1& a1, cholmod_common& Common) { \ - return R_MATRIX_CHOLMOD(name) (&a1, &Common); \ - } +#define EIGEN_CHOLMOD_SPECIALIZE1(ret, name, t1, a1) \ + template \ + inline ret cm_##name(t1& a1, cholmod_common& Common) { \ + return cholmod_##name(&a1, &Common); \ + } \ + template <> \ + inline ret cm_##name(t1 & a1, cholmod_common & Common) { \ + return cholmod_l_##name(&a1, &Common); \ + } EIGEN_CHOLMOD_SPECIALIZE0(int, start) EIGEN_CHOLMOD_SPECIALIZE0(int, finish) @@ -197,33 +201,33 @@ EIGEN_CHOLMOD_SPECIALIZE1(cholmod_sparse*, factor_to_sparse, cholmod_factor, L) template inline cholmod_dense* cm_solve(int sys, cholmod_factor& L, cholmod_dense& B, cholmod_common& Common) { - return R_MATRIX_CHOLMOD(solve) (sys, &L, &B, &Common); + return cholmod_solve(sys, &L, &B, &Common); +} +template <> +inline cholmod_dense* cm_solve(int sys, cholmod_factor& L, cholmod_dense& B, cholmod_common& Common) { + return cholmod_l_solve(sys, &L, &B, &Common); } -// template <> -// inline cholmod_dense* cm_solve(int sys, cholmod_factor& L, cholmod_dense& B, cholmod_common& Common) { -// return cholmod_l_solve(sys, &L, &B, &Common); -// } template inline cholmod_sparse* cm_spsolve(int sys, cholmod_factor& L, cholmod_sparse& B, cholmod_common& Common) { - return R_MATRIX_CHOLMOD(spsolve) (sys, &L, &B, &Common); + return cholmod_spsolve(sys, &L, &B, &Common); +} +template <> +inline cholmod_sparse* cm_spsolve(int sys, cholmod_factor& L, cholmod_sparse& B, + cholmod_common& Common) { + return cholmod_l_spsolve(sys, &L, &B, &Common); } -// template <> -// inline cholmod_sparse* cm_spsolve(int sys, cholmod_factor& L, cholmod_sparse& B, -// cholmod_common& Common) { -// return cholmod_l_spsolve(sys, &L, &B, &Common); -// } template inline int cm_factorize_p(cholmod_sparse* A, double beta[2], StorageIndex_* fset, std::size_t fsize, cholmod_factor* L, cholmod_common& Common) { - return R_MATRIX_CHOLMOD(factorize_p) (A, beta, fset, fsize, L, &Common); + return cholmod_factorize_p(A, beta, fset, fsize, L, &Common); +} +template <> +inline int cm_factorize_p(cholmod_sparse* A, double beta[2], SuiteSparse_long* fset, + std::size_t fsize, cholmod_factor* L, cholmod_common& Common) { + return cholmod_l_factorize_p(A, beta, fset, fsize, L, &Common); } -// template <> -// inline int cm_factorize_p(cholmod_sparse* A, double beta[2], SuiteSparse_long* fset, -// std::size_t fsize, cholmod_factor* L, cholmod_common& Common) { -// return cholmod_l_factorize_p(A, beta, fset, fsize, L, &Common); -// } #undef EIGEN_CHOLMOD_SPECIALIZE0 #undef EIGEN_CHOLMOD_SPECIALIZE1 diff --git a/inst/include/Eigen/src/Core/Assign_MKL.h b/inst/include/Eigen/src/Core/Assign_MKL.h index ad11220..7636445 100644 --- a/inst/include/Eigen/src/Core/Assign_MKL.h +++ b/inst/include/Eigen/src/Core/Assign_MKL.h @@ -56,11 +56,11 @@ class vml_assign_traits { : int(Dst::MaxRowsAtCompileTime), MaxSizeAtCompileTime = Dst::SizeAtCompileTime, - MightEnableVml = StorageOrdersAgree && DstHasDirectAccess && SrcHasDirectAccess && + MightEnableVml = bool(StorageOrdersAgree) && bool(DstHasDirectAccess) && bool(SrcHasDirectAccess) && Src::InnerStrideAtCompileTime == 1 && Dst::InnerStrideAtCompileTime == 1, - MightLinearize = MightEnableVml && (int(Dst::Flags) & int(Src::Flags) & LinearAccessBit), - VmlSize = MightLinearize ? MaxSizeAtCompileTime : InnerMaxSize, - LargeEnough = VmlSize == Dynamic || VmlSize >= EIGEN_MKL_VML_THRESHOLD + MightLinearize = bool(MightEnableVml) && (int(Dst::Flags) & int(Src::Flags) & LinearAccessBit), + VmlSize = bool(MightLinearize) ? MaxSizeAtCompileTime : InnerMaxSize, + LargeEnough = (VmlSize == Dynamic) || VmlSize >= EIGEN_MKL_VML_THRESHOLD }; public: diff --git a/inst/include/Eigen/src/Core/CwiseNullaryOp.h b/inst/include/Eigen/src/Core/CwiseNullaryOp.h index e4c5fed..084f503 100644 --- a/inst/include/Eigen/src/Core/CwiseNullaryOp.h +++ b/inst/include/Eigen/src/Core/CwiseNullaryOp.h @@ -94,7 +94,7 @@ class CwiseNullaryOp : public internal::dense_xpr_base::Constant(Index rows, Index cols, const Scalar& value) { * \only_for_vectors * * This variant is meant to be used for dynamic-size vector types. For fixed-size types, - * it is redundant to pass \a size as argument, so Zero() should be used + * it is redundant to pass \a size as argument, so Constant(const Scalar&) should be used * instead. * * The template parameter \a CustomNullaryOp is the type of the functor. diff --git a/inst/include/Eigen/src/Core/DenseStorage.h b/inst/include/Eigen/src/Core/DenseStorage.h index d62586c..45c8779 100644 --- a/inst/include/Eigen/src/Core/DenseStorage.h +++ b/inst/include/Eigen/src/Core/DenseStorage.h @@ -65,7 +65,8 @@ struct plain_array { template struct plain_array { - T array[Size]; + // on some 32-bit platforms, stack-allocated arrays are aligned to 4 bytes, not the preferred alignment of T + EIGEN_ALIGN_TO_BOUNDARY(alignof(T)) T array[Size]; #if defined(EIGEN_NO_DEBUG) || defined(EIGEN_TESTING_PLAINOBJECT_CTOR) EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE constexpr plain_array() = default; #else @@ -73,12 +74,6 @@ struct plain_array { #endif }; -template -struct plain_array { - T array[1]; - EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE constexpr plain_array() = default; -}; - template EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE constexpr void swap_plain_array(plain_array& a, plain_array& b, diff --git a/inst/include/Eigen/src/Core/Fill.h b/inst/include/Eigen/src/Core/Fill.h index f40d56d..779ef26 100644 --- a/inst/include/Eigen/src/Core/Fill.h +++ b/inst/include/Eigen/src/Core/Fill.h @@ -115,17 +115,15 @@ struct eigen_zero_impl { template struct eigen_zero_impl { using Scalar = typename Xpr::Scalar; - static constexpr size_t max_bytes = (std::numeric_limits::max)(); static EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE void run(Xpr& dst) { - const size_t num_bytes = dst.size() * sizeof(Scalar); - if (num_bytes == 0) return; + const std::ptrdiff_t num_bytes = dst.size() * static_cast(sizeof(Scalar)); + if (num_bytes <= 0) return; void* dst_ptr = static_cast(dst.data()); #ifndef EIGEN_NO_DEBUG - if (num_bytes > max_bytes) throw_std_bad_alloc(); eigen_assert((dst_ptr != nullptr) && "null pointer dereference error!"); #endif EIGEN_USING_STD(memset); - memset(dst_ptr, 0, num_bytes); + memset(dst_ptr, 0, static_cast(num_bytes)); } template static EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE void run(Xpr& dst, const SrcXpr& src) { diff --git a/inst/include/Eigen/src/Core/InnerProduct.h b/inst/include/Eigen/src/Core/InnerProduct.h index 9849d9b..686ad13 100644 --- a/inst/include/Eigen/src/Core/InnerProduct.h +++ b/inst/include/Eigen/src/Core/InnerProduct.h @@ -211,8 +211,14 @@ struct scalar_inner_product_op { static constexpr bool PacketAccess = false; }; +// Partial specialization for packet access if and only if +// LhsScalar == RhsScalar == ScalarBinaryOpTraits::ReturnType. template -struct scalar_inner_product_op { +struct scalar_inner_product_op< + Scalar, + typename std::enable_if::ReturnType, Scalar>::value, + Scalar>::type, + Conj> { using result_type = Scalar; using conj_helper = conditional_conj; EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Scalar coeff(const Scalar& a, const Scalar& b) const { diff --git a/inst/include/Eigen/src/Core/MathFunctions.h b/inst/include/Eigen/src/Core/MathFunctions.h index 155fdad..5e36ce8 100644 --- a/inst/include/Eigen/src/Core/MathFunctions.h +++ b/inst/include/Eigen/src/Core/MathFunctions.h @@ -1004,8 +1004,7 @@ struct madd_impl { } }; -// Use FMA if there is a single CPU instruction. -#ifdef EIGEN_VECTORIZE_FMA +#if EIGEN_SCALAR_MADD_USE_FMA template struct madd_impl::value>> { static EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Scalar run(const Scalar& x, const Scalar& y, const Scalar& z) { @@ -1927,7 +1926,6 @@ EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Scalar arithmetic_shift_right(const Scalar return bit_cast(bit_cast(a) >> n); } -// Otherwise, rely on template implementation. template EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Scalar fma(const Scalar& x, const Scalar& y, const Scalar& z) { return internal::fma_impl::run(x, y, z); diff --git a/inst/include/Eigen/src/Core/PermutationMatrix.h b/inst/include/Eigen/src/Core/PermutationMatrix.h index eb8e797..7713354 100644 --- a/inst/include/Eigen/src/Core/PermutationMatrix.h +++ b/inst/include/Eigen/src/Core/PermutationMatrix.h @@ -109,6 +109,9 @@ class PermutationBase : public EigenBase { */ DenseMatrixType toDenseMatrix() const { return derived(); } + /** \returns the plain matrix representation of the permutation. */ + DenseMatrixType eval() const { return toDenseMatrix(); } + /** const version of indices(). */ const IndicesType& indices() const { return derived().indices(); } /** \returns a reference to the stored array representing the permutation. */ diff --git a/inst/include/Eigen/src/Core/arch/AVX/PacketMath.h b/inst/include/Eigen/src/Core/arch/AVX/PacketMath.h index 0cd9e6c..b1dfb07 100644 --- a/inst/include/Eigen/src/Core/arch/AVX/PacketMath.h +++ b/inst/include/Eigen/src/Core/arch/AVX/PacketMath.h @@ -2831,7 +2831,7 @@ inline __m128i segment_mask_4x8(Index begin, Index count) { mask <<= CHAR_BIT * count; mask--; mask <<= CHAR_BIT * begin; -#if defined(_WIN32) && !defined(_WIN64) +#if !EIGEN_ARCH_x86_64 return _mm_loadl_epi64(reinterpret_cast(&mask)); #else return _mm_cvtsi64_si128(mask); @@ -2847,7 +2847,7 @@ inline __m128i segment_mask_8x8(Index begin, Index count) { mask <<= (CHAR_BIT / 2) * count; mask--; mask <<= CHAR_BIT * begin; -#if defined(_WIN32) && !defined(_WIN64) +#if !EIGEN_ARCH_x86_64 return _mm_loadl_epi64(reinterpret_cast(&mask)); #else return _mm_cvtsi64_si128(mask); diff --git a/inst/include/Eigen/src/Core/arch/AVX/TypeCasting.h b/inst/include/Eigen/src/Core/arch/AVX/TypeCasting.h index 5b73ffe..767e2d5 100644 --- a/inst/include/Eigen/src/Core/arch/AVX/TypeCasting.h +++ b/inst/include/Eigen/src/Core/arch/AVX/TypeCasting.h @@ -240,8 +240,8 @@ EIGEN_STRONG_INLINE Packet4d pcast(const Packet4l& a) { #if defined(EIGEN_VECTORIZE_AVX512DQ) && defined(EIGEN_VECTORIZE_AVS512VL) return _mm256_cvtepi64_pd(a); #else - EIGEN_ALIGN16 int64_t aux[4]; - pstore(aux, a); + int64_t aux[4]; + pstoreu(aux, a); return _mm256_set_pd(static_cast(aux[3]), static_cast(aux[2]), static_cast(aux[1]), static_cast(aux[0])); #endif diff --git a/inst/include/Eigen/src/Core/arch/NEON/Complex.h b/inst/include/Eigen/src/Core/arch/NEON/Complex.h index f3f6a1a..b8655c8 100644 --- a/inst/include/Eigen/src/Core/arch/NEON/Complex.h +++ b/inst/include/Eigen/src/Core/arch/NEON/Complex.h @@ -48,7 +48,7 @@ struct Packet2cf { }; template <> -struct packet_traits > : default_packet_traits { +struct packet_traits> : default_packet_traits { typedef Packet2cf type; typedef Packet1cf half; enum { @@ -280,13 +280,13 @@ EIGEN_STRONG_INLINE Packet2cf pandnot(const Packet2cf& a, const Packe template <> EIGEN_STRONG_INLINE Packet1cf pload(const std::complex* from) { - EIGEN_ASSUME_ALIGNED(from, unpacket_traits::alignment); - EIGEN_DEBUG_ALIGNED_LOAD return Packet1cf(pload((const float*)from)); + EIGEN_DEBUG_ALIGNED_LOAD return Packet1cf( + pload(assume_aligned::alignment>(reinterpret_cast(from)))); } template <> EIGEN_STRONG_INLINE Packet2cf pload(const std::complex* from) { - EIGEN_ASSUME_ALIGNED(from, unpacket_traits::alignment); - EIGEN_DEBUG_ALIGNED_LOAD return Packet2cf(pload(reinterpret_cast(from))); + EIGEN_DEBUG_ALIGNED_LOAD return Packet2cf( + pload(assume_aligned::alignment>(reinterpret_cast(from)))); } template <> @@ -308,22 +308,22 @@ EIGEN_STRONG_INLINE Packet2cf ploaddup(const std::complex* fro } template <> -EIGEN_STRONG_INLINE void pstore >(std::complex* to, const Packet1cf& from) { - EIGEN_ASSUME_ALIGNED(to, unpacket_traits::alignment); - EIGEN_DEBUG_ALIGNED_STORE pstore((float*)to, from.v); +EIGEN_STRONG_INLINE void pstore>(std::complex* to, const Packet1cf& from) { + EIGEN_DEBUG_ALIGNED_STORE pstore(assume_aligned::alignment>(reinterpret_cast(to)), + from.v); } template <> -EIGEN_STRONG_INLINE void pstore >(std::complex* to, const Packet2cf& from) { - EIGEN_ASSUME_ALIGNED(to, unpacket_traits::alignment); - EIGEN_DEBUG_ALIGNED_STORE pstore(reinterpret_cast(to), from.v); +EIGEN_STRONG_INLINE void pstore>(std::complex* to, const Packet2cf& from) { + EIGEN_DEBUG_ALIGNED_STORE pstore(assume_aligned::alignment>(reinterpret_cast(to)), + from.v); } template <> -EIGEN_STRONG_INLINE void pstoreu >(std::complex* to, const Packet1cf& from) { +EIGEN_STRONG_INLINE void pstoreu>(std::complex* to, const Packet1cf& from) { EIGEN_DEBUG_UNALIGNED_STORE pstoreu((float*)to, from.v); } template <> -EIGEN_STRONG_INLINE void pstoreu >(std::complex* to, const Packet2cf& from) { +EIGEN_STRONG_INLINE void pstoreu>(std::complex* to, const Packet2cf& from) { EIGEN_DEBUG_UNALIGNED_STORE pstoreu(reinterpret_cast(to), from.v); } @@ -356,7 +356,7 @@ EIGEN_DEVICE_FUNC inline void pscatter, Packet2cf>(std::comp } template <> -EIGEN_STRONG_INLINE void prefetch >(const std::complex* addr) { +EIGEN_STRONG_INLINE void prefetch>(const std::complex* addr) { EIGEN_ARM_PREFETCH(reinterpret_cast(addr)); } @@ -501,7 +501,7 @@ struct Packet1cd { }; template <> -struct packet_traits > : default_packet_traits { +struct packet_traits> : default_packet_traits { typedef Packet1cd type; typedef Packet1cd half; enum { @@ -531,8 +531,8 @@ struct unpacket_traits : neon_unpacket_default EIGEN_STRONG_INLINE Packet1cd pload(const std::complex* from) { - EIGEN_ASSUME_ALIGNED(from, unpacket_traits::alignment); - EIGEN_DEBUG_ALIGNED_LOAD return Packet1cd(pload(reinterpret_cast(from))); + EIGEN_DEBUG_ALIGNED_LOAD return Packet1cd( + pload(assume_aligned::alignment>(reinterpret_cast(from)))); } template <> @@ -644,18 +644,18 @@ EIGEN_STRONG_INLINE Packet1cd ploaddup(const std::complex* fr } template <> -EIGEN_STRONG_INLINE void pstore >(std::complex* to, const Packet1cd& from) { - EIGEN_ASSUME_ALIGNED(to, unpacket_traits::alignment); - EIGEN_DEBUG_ALIGNED_STORE pstore(reinterpret_cast(to), from.v); +EIGEN_STRONG_INLINE void pstore>(std::complex* to, const Packet1cd& from) { + EIGEN_DEBUG_ALIGNED_STORE pstore(assume_aligned::alignment>(reinterpret_cast(to)), + from.v); } template <> -EIGEN_STRONG_INLINE void pstoreu >(std::complex* to, const Packet1cd& from) { +EIGEN_STRONG_INLINE void pstoreu>(std::complex* to, const Packet1cd& from) { EIGEN_DEBUG_UNALIGNED_STORE pstoreu(reinterpret_cast(to), from.v); } template <> -EIGEN_STRONG_INLINE void prefetch >(const std::complex* addr) { +EIGEN_STRONG_INLINE void prefetch>(const std::complex* addr) { EIGEN_ARM_PREFETCH(reinterpret_cast(addr)); } @@ -677,7 +677,7 @@ EIGEN_DEVICE_FUNC inline void pscatter, Packet1cd>(std::com template <> EIGEN_STRONG_INLINE std::complex pfirst(const Packet1cd& a) { EIGEN_ALIGN16 std::complex res; - pstore >(&res, a); + pstore>(&res, a); return res; } diff --git a/inst/include/Eigen/src/Core/arch/NEON/PacketMath.h b/inst/include/Eigen/src/Core/arch/NEON/PacketMath.h index bea50a3..a66af83 100644 --- a/inst/include/Eigen/src/Core/arch/NEON/PacketMath.h +++ b/inst/include/Eigen/src/Core/arch/NEON/PacketMath.h @@ -2268,13 +2268,11 @@ EIGEN_STRONG_INLINE Packet2ul plogical_shift_left(Packet2ul a) { template <> EIGEN_STRONG_INLINE Packet2f pload(const float* from) { - EIGEN_ASSUME_ALIGNED(from, unpacket_traits::alignment); - EIGEN_DEBUG_ALIGNED_LOAD return vld1_f32(from); + EIGEN_DEBUG_ALIGNED_LOAD return vld1_f32(assume_aligned::alignment>(from)); } template <> EIGEN_STRONG_INLINE Packet4f pload(const float* from) { - EIGEN_ASSUME_ALIGNED(from, unpacket_traits::alignment); - EIGEN_DEBUG_ALIGNED_LOAD return vld1q_f32(from); + EIGEN_DEBUG_ALIGNED_LOAD return vld1q_f32(assume_aligned::alignment>(from)); } template <> EIGEN_STRONG_INLINE Packet4c pload(const int8_t* from) { @@ -2284,13 +2282,11 @@ EIGEN_STRONG_INLINE Packet4c pload(const int8_t* from) { } template <> EIGEN_STRONG_INLINE Packet8c pload(const int8_t* from) { - EIGEN_ASSUME_ALIGNED(from, unpacket_traits::alignment); - EIGEN_DEBUG_ALIGNED_LOAD return vld1_s8(from); + EIGEN_DEBUG_ALIGNED_LOAD return vld1_s8(assume_aligned::alignment>(from)); } template <> EIGEN_STRONG_INLINE Packet16c pload(const int8_t* from) { - EIGEN_ASSUME_ALIGNED(from, unpacket_traits::alignment); - EIGEN_DEBUG_ALIGNED_LOAD return vld1q_s8(from); + EIGEN_DEBUG_ALIGNED_LOAD return vld1q_s8(assume_aligned::alignment>(from)); } template <> EIGEN_STRONG_INLINE Packet4uc pload(const uint8_t* from) { @@ -2300,63 +2296,51 @@ EIGEN_STRONG_INLINE Packet4uc pload(const uint8_t* from) { } template <> EIGEN_STRONG_INLINE Packet8uc pload(const uint8_t* from) { - EIGEN_ASSUME_ALIGNED(from, unpacket_traits::alignment); - EIGEN_DEBUG_ALIGNED_LOAD return vld1_u8(from); + EIGEN_DEBUG_ALIGNED_LOAD return vld1_u8(assume_aligned::alignment>(from)); } template <> EIGEN_STRONG_INLINE Packet16uc pload(const uint8_t* from) { - EIGEN_ASSUME_ALIGNED(from, unpacket_traits::alignment); - EIGEN_DEBUG_ALIGNED_LOAD return vld1q_u8(from); + EIGEN_DEBUG_ALIGNED_LOAD return vld1q_u8(assume_aligned::alignment>(from)); } template <> EIGEN_STRONG_INLINE Packet4s pload(const int16_t* from) { - EIGEN_ASSUME_ALIGNED(from, unpacket_traits::alignment); - EIGEN_DEBUG_ALIGNED_LOAD return vld1_s16(from); + EIGEN_DEBUG_ALIGNED_LOAD return vld1_s16(assume_aligned::alignment>(from)); } template <> EIGEN_STRONG_INLINE Packet8s pload(const int16_t* from) { - EIGEN_ASSUME_ALIGNED(from, unpacket_traits::alignment); - EIGEN_DEBUG_ALIGNED_LOAD return vld1q_s16(from); + EIGEN_DEBUG_ALIGNED_LOAD return vld1q_s16(assume_aligned::alignment>(from)); } template <> EIGEN_STRONG_INLINE Packet4us pload(const uint16_t* from) { - EIGEN_ASSUME_ALIGNED(from, unpacket_traits::alignment); - EIGEN_DEBUG_ALIGNED_LOAD return vld1_u16(from); + EIGEN_DEBUG_ALIGNED_LOAD return vld1_u16(assume_aligned::alignment>(from)); } template <> EIGEN_STRONG_INLINE Packet8us pload(const uint16_t* from) { - EIGEN_ASSUME_ALIGNED(from, unpacket_traits::alignment); - EIGEN_DEBUG_ALIGNED_LOAD return vld1q_u16(from); + EIGEN_DEBUG_ALIGNED_LOAD return vld1q_u16(assume_aligned::alignment>(from)); } template <> EIGEN_STRONG_INLINE Packet2i pload(const int32_t* from) { - EIGEN_ASSUME_ALIGNED(from, unpacket_traits::alignment); - EIGEN_DEBUG_ALIGNED_LOAD return vld1_s32(from); + EIGEN_DEBUG_ALIGNED_LOAD return vld1_s32(assume_aligned::alignment>(from)); } template <> EIGEN_STRONG_INLINE Packet4i pload(const int32_t* from) { - EIGEN_ASSUME_ALIGNED(from, unpacket_traits::alignment); - EIGEN_DEBUG_ALIGNED_LOAD return vld1q_s32(from); + EIGEN_DEBUG_ALIGNED_LOAD return vld1q_s32(assume_aligned::alignment>(from)); } template <> EIGEN_STRONG_INLINE Packet2ui pload(const uint32_t* from) { - EIGEN_ASSUME_ALIGNED(from, unpacket_traits::alignment); - EIGEN_DEBUG_ALIGNED_LOAD return vld1_u32(from); + EIGEN_DEBUG_ALIGNED_LOAD return vld1_u32(assume_aligned::alignment>(from)); } template <> EIGEN_STRONG_INLINE Packet4ui pload(const uint32_t* from) { - EIGEN_ASSUME_ALIGNED(from, unpacket_traits::alignment); - EIGEN_DEBUG_ALIGNED_LOAD return vld1q_u32(from); + EIGEN_DEBUG_ALIGNED_LOAD return vld1q_u32(assume_aligned::alignment>(from)); } template <> EIGEN_STRONG_INLINE Packet2l pload(const int64_t* from) { - EIGEN_ASSUME_ALIGNED(from, unpacket_traits::alignment); - EIGEN_DEBUG_ALIGNED_LOAD return vld1q_s64(from); + EIGEN_DEBUG_ALIGNED_LOAD return vld1q_s64(assume_aligned::alignment>(from)); } template <> EIGEN_STRONG_INLINE Packet2ul pload(const uint64_t* from) { - EIGEN_ASSUME_ALIGNED(from, unpacket_traits::alignment); - EIGEN_DEBUG_ALIGNED_LOAD return vld1q_u64(from); + EIGEN_DEBUG_ALIGNED_LOAD return vld1q_u64(assume_aligned::alignment>(from)); } template <> @@ -2580,13 +2564,11 @@ EIGEN_STRONG_INLINE Packet4ui ploadquad(const uint32_t* from) { template <> EIGEN_STRONG_INLINE void pstore(float* to, const Packet2f& from) { - EIGEN_ASSUME_ALIGNED(to, unpacket_traits::alignment); - EIGEN_DEBUG_ALIGNED_STORE vst1_f32(to, from); + EIGEN_DEBUG_ALIGNED_STORE vst1_f32(assume_aligned::alignment>(to), from); } template <> EIGEN_STRONG_INLINE void pstore(float* to, const Packet4f& from) { - EIGEN_ASSUME_ALIGNED(to, unpacket_traits::alignment); - EIGEN_DEBUG_ALIGNED_STORE vst1q_f32(to, from); + EIGEN_DEBUG_ALIGNED_STORE vst1q_f32(assume_aligned::alignment>(to), from); } template <> EIGEN_STRONG_INLINE void pstore(int8_t* to, const Packet4c& from) { @@ -2594,13 +2576,11 @@ EIGEN_STRONG_INLINE void pstore(int8_t* to, const Packet4c& from) { } template <> EIGEN_STRONG_INLINE void pstore(int8_t* to, const Packet8c& from) { - EIGEN_ASSUME_ALIGNED(to, unpacket_traits::alignment); - EIGEN_DEBUG_ALIGNED_STORE vst1_s8(to, from); + EIGEN_DEBUG_ALIGNED_STORE vst1_s8(assume_aligned::alignment>(to), from); } template <> EIGEN_STRONG_INLINE void pstore(int8_t* to, const Packet16c& from) { - EIGEN_ASSUME_ALIGNED(to, unpacket_traits::alignment); - EIGEN_DEBUG_ALIGNED_STORE vst1q_s8(to, from); + EIGEN_DEBUG_ALIGNED_STORE vst1q_s8(assume_aligned::alignment>(to), from); } template <> EIGEN_STRONG_INLINE void pstore(uint8_t* to, const Packet4uc& from) { @@ -2608,63 +2588,51 @@ EIGEN_STRONG_INLINE void pstore(uint8_t* to, const Packet4uc& from) { } template <> EIGEN_STRONG_INLINE void pstore(uint8_t* to, const Packet8uc& from) { - EIGEN_ASSUME_ALIGNED(to, unpacket_traits::alignment); - EIGEN_DEBUG_ALIGNED_STORE vst1_u8(to, from); + EIGEN_DEBUG_ALIGNED_STORE vst1_u8(assume_aligned::alignment>(to), from); } template <> EIGEN_STRONG_INLINE void pstore(uint8_t* to, const Packet16uc& from) { - EIGEN_ASSUME_ALIGNED(to, unpacket_traits::alignment); - EIGEN_DEBUG_ALIGNED_STORE vst1q_u8(to, from); + EIGEN_DEBUG_ALIGNED_STORE vst1q_u8(assume_aligned::alignment>(to), from); } template <> EIGEN_STRONG_INLINE void pstore(int16_t* to, const Packet4s& from) { - EIGEN_ASSUME_ALIGNED(to, unpacket_traits::alignment); - EIGEN_DEBUG_ALIGNED_STORE vst1_s16(to, from); + EIGEN_DEBUG_ALIGNED_STORE vst1_s16(assume_aligned::alignment>(to), from); } template <> EIGEN_STRONG_INLINE void pstore(int16_t* to, const Packet8s& from) { - EIGEN_ASSUME_ALIGNED(to, unpacket_traits::alignment); - EIGEN_DEBUG_ALIGNED_STORE vst1q_s16(to, from); + EIGEN_DEBUG_ALIGNED_STORE vst1q_s16(assume_aligned::alignment>(to), from); } template <> EIGEN_STRONG_INLINE void pstore(uint16_t* to, const Packet4us& from) { - EIGEN_ASSUME_ALIGNED(to, unpacket_traits::alignment); - EIGEN_DEBUG_ALIGNED_STORE vst1_u16(to, from); + EIGEN_DEBUG_ALIGNED_STORE vst1_u16(assume_aligned::alignment>(to), from); } template <> EIGEN_STRONG_INLINE void pstore(uint16_t* to, const Packet8us& from) { - EIGEN_ASSUME_ALIGNED(to, unpacket_traits::alignment); - EIGEN_DEBUG_ALIGNED_STORE vst1q_u16(to, from); + EIGEN_DEBUG_ALIGNED_STORE vst1q_u16(assume_aligned::alignment>(to), from); } template <> EIGEN_STRONG_INLINE void pstore(int32_t* to, const Packet2i& from) { - EIGEN_ASSUME_ALIGNED(to, unpacket_traits::alignment); - EIGEN_DEBUG_ALIGNED_STORE vst1_s32(to, from); + EIGEN_DEBUG_ALIGNED_STORE vst1_s32(assume_aligned::alignment>(to), from); } template <> EIGEN_STRONG_INLINE void pstore(int32_t* to, const Packet4i& from) { - EIGEN_ASSUME_ALIGNED(to, unpacket_traits::alignment); - EIGEN_DEBUG_ALIGNED_STORE vst1q_s32(to, from); + EIGEN_DEBUG_ALIGNED_STORE vst1q_s32(assume_aligned::alignment>(to), from); } template <> EIGEN_STRONG_INLINE void pstore(uint32_t* to, const Packet2ui& from) { - EIGEN_ASSUME_ALIGNED(to, unpacket_traits::alignment); - EIGEN_DEBUG_ALIGNED_STORE vst1_u32(to, from); + EIGEN_DEBUG_ALIGNED_STORE vst1_u32(assume_aligned::alignment>(to), from); } template <> EIGEN_STRONG_INLINE void pstore(uint32_t* to, const Packet4ui& from) { - EIGEN_ASSUME_ALIGNED(to, unpacket_traits::alignment); - EIGEN_DEBUG_ALIGNED_STORE vst1q_u32(to, from); + EIGEN_DEBUG_ALIGNED_STORE vst1q_u32(assume_aligned::alignment>(to), from); } template <> EIGEN_STRONG_INLINE void pstore(int64_t* to, const Packet2l& from) { - EIGEN_ASSUME_ALIGNED(to, unpacket_traits::alignment); - EIGEN_DEBUG_ALIGNED_STORE vst1q_s64(to, from); + EIGEN_DEBUG_ALIGNED_STORE vst1q_s64(assume_aligned::alignment>(to), from); } template <> EIGEN_STRONG_INLINE void pstore(uint64_t* to, const Packet2ul& from) { - EIGEN_ASSUME_ALIGNED(to, unpacket_traits::alignment); - EIGEN_DEBUG_ALIGNED_STORE vst1q_u64(to, from); + EIGEN_DEBUG_ALIGNED_STORE vst1q_u64(assume_aligned::alignment>(to), from); } template <> @@ -4739,8 +4707,8 @@ EIGEN_STRONG_INLINE bfloat16 pfirst(const Packet4bf& from) { template <> EIGEN_STRONG_INLINE Packet4bf pload(const bfloat16* from) { - EIGEN_ASSUME_ALIGNED(from, unpacket_traits::alignment); - return Packet4bf(pload(reinterpret_cast(from))); + return Packet4bf( + pload(reinterpret_cast(assume_aligned::alignment>(from)))); } template <> @@ -4750,8 +4718,8 @@ EIGEN_STRONG_INLINE Packet4bf ploadu(const bfloat16* from) { template <> EIGEN_STRONG_INLINE void pstore(bfloat16* to, const Packet4bf& from) { - EIGEN_ASSUME_ALIGNED(to, unpacket_traits::alignment); - EIGEN_DEBUG_ALIGNED_STORE vst1_u16(reinterpret_cast(to), from); + EIGEN_DEBUG_ALIGNED_STORE vst1_u16( + reinterpret_cast(assume_aligned::alignment>(to)), from); } template <> @@ -5240,8 +5208,7 @@ EIGEN_STRONG_INLINE Packet2d pcmp_eq(const Packet2d& a, const Packet2d& b) { template <> EIGEN_STRONG_INLINE Packet2d pload(const double* from) { - EIGEN_ASSUME_ALIGNED(from, unpacket_traits::alignment); - EIGEN_DEBUG_ALIGNED_LOAD return vld1q_f64(from); + EIGEN_DEBUG_ALIGNED_LOAD return vld1q_f64(assume_aligned::alignment>(from)); } template <> @@ -5255,8 +5222,7 @@ EIGEN_STRONG_INLINE Packet2d ploaddup(const double* from) { } template <> EIGEN_STRONG_INLINE void pstore(double* to, const Packet2d& from) { - EIGEN_ASSUME_ALIGNED(to, unpacket_traits::alignment); - EIGEN_DEBUG_ALIGNED_STORE vst1q_f64(to, from); + EIGEN_DEBUG_ALIGNED_STORE vst1q_f64(assume_aligned::alignment>(to), from); } template <> @@ -5784,14 +5750,14 @@ EIGEN_STRONG_INLINE Packet4hf pandnot(const Packet4hf& a, const Packe template <> EIGEN_STRONG_INLINE Packet8hf pload(const Eigen::half* from) { - EIGEN_ASSUME_ALIGNED(from, unpacket_traits::alignment); - EIGEN_DEBUG_ALIGNED_LOAD return vld1q_f16(reinterpret_cast(from)); + EIGEN_DEBUG_ALIGNED_LOAD return vld1q_f16( + reinterpret_cast(assume_aligned::alignment>(from))); } template <> EIGEN_STRONG_INLINE Packet4hf pload(const Eigen::half* from) { - EIGEN_ASSUME_ALIGNED(from, unpacket_traits::alignment); - EIGEN_DEBUG_ALIGNED_LOAD return vld1_f16(reinterpret_cast(from)); + EIGEN_DEBUG_ALIGNED_LOAD return vld1_f16( + reinterpret_cast(assume_aligned::alignment>(from))); } template <> @@ -5866,14 +5832,14 @@ EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Packet4hf pinsertlast(const Packet4hf& a, template <> EIGEN_STRONG_INLINE void pstore(Eigen::half* to, const Packet8hf& from) { - EIGEN_ASSUME_ALIGNED(to, unpacket_traits::alignment); - EIGEN_DEBUG_ALIGNED_STORE vst1q_f16(reinterpret_cast(to), from); + EIGEN_DEBUG_ALIGNED_STORE vst1q_f16( + reinterpret_cast(assume_aligned::alignment>(to)), from); } template <> EIGEN_STRONG_INLINE void pstore(Eigen::half* to, const Packet4hf& from) { - EIGEN_ASSUME_ALIGNED(to, unpacket_traits::alignment); - EIGEN_DEBUG_ALIGNED_STORE vst1_f16(reinterpret_cast(to), from); + EIGEN_DEBUG_ALIGNED_STORE vst1_f16( + reinterpret_cast(assume_aligned::alignment>(to)), from); } template <> diff --git a/inst/include/Eigen/src/Core/arch/SSE/PacketMath.h b/inst/include/Eigen/src/Core/arch/SSE/PacketMath.h index e0119dd..a5e4902 100644 --- a/inst/include/Eigen/src/Core/arch/SSE/PacketMath.h +++ b/inst/include/Eigen/src/Core/arch/SSE/PacketMath.h @@ -1679,9 +1679,9 @@ EIGEN_STRONG_INLINE Packet16b pgather(const bool* from, Index s template <> EIGEN_STRONG_INLINE void pscatter(float* to, const Packet4f& from, Index stride) { to[stride * 0] = pfirst(from); - to[stride * 1] = pfirst(_mm_shuffle_ps(from, from, 1)); - to[stride * 2] = pfirst(_mm_shuffle_ps(from, from, 2)); - to[stride * 3] = pfirst(_mm_shuffle_ps(from, from, 3)); + to[stride * 1] = pfirst(Packet4f(_mm_shuffle_ps(from, from, 1))); + to[stride * 2] = pfirst(Packet4f(_mm_shuffle_ps(from, from, 2))); + to[stride * 3] = pfirst(Packet4f(_mm_shuffle_ps(from, from, 3))); } template <> EIGEN_STRONG_INLINE void pscatter(double* to, const Packet2d& from, Index stride) { diff --git a/inst/include/Eigen/src/Core/util/DisableStupidWarnings.h b/inst/include/Eigen/src/Core/util/DisableStupidWarnings.h index 8c27b14..ab0c542 100644 --- a/inst/include/Eigen/src/Core/util/DisableStupidWarnings.h +++ b/inst/include/Eigen/src/Core/util/DisableStupidWarnings.h @@ -42,45 +42,45 @@ #pragma warning disable 2196 279 1684 2259 #elif defined __clang__ -// #ifndef EIGEN_PERMANENTLY_DISABLE_STUPID_WARNINGS -// #pragma clang diagnostic push -// #endif -// #if defined(__has_warning) -// // -Wconstant-logical-operand - warning: use of logical && with constant operand; switch to bitwise & or remove constant -// // this is really a stupid warning as it warns on compile-time expressions involving enums -// #if __has_warning("-Wconstant-logical-operand") -// #pragma clang diagnostic ignored "-Wconstant-logical-operand" -// #endif -// #if __has_warning("-Wimplicit-int-float-conversion") -// #pragma clang diagnostic ignored "-Wimplicit-int-float-conversion" -// #endif -// #if (defined(__ALTIVEC__) || defined(__VSX__)) && (!defined(__STDC_VERSION__) || (__STDC_VERSION__ < 201112L)) -// // warning: generic selections are a C11-specific feature -// // ignoring warnings thrown at vec_ctf in Altivec/PacketMath.h -// #if __has_warning("-Wc11-extensions") -// #pragma clang diagnostic ignored "-Wc11-extensions" -// #endif -// #endif -// #endif +#ifndef EIGEN_PERMANENTLY_DISABLE_STUPID_WARNINGS +#pragma clang diagnostic push +#endif +#if defined(__has_warning) +// -Wconstant-logical-operand - warning: use of logical && with constant operand; switch to bitwise & or remove constant +// this is really a stupid warning as it warns on compile-time expressions involving enums +#if __has_warning("-Wconstant-logical-operand") +#pragma clang diagnostic ignored "-Wconstant-logical-operand" +#endif +#if __has_warning("-Wimplicit-int-float-conversion") +#pragma clang diagnostic ignored "-Wimplicit-int-float-conversion" +#endif +#if (defined(__ALTIVEC__) || defined(__VSX__)) && (!defined(__STDC_VERSION__) || (__STDC_VERSION__ < 201112L)) +// warning: generic selections are a C11-specific feature +// ignoring warnings thrown at vec_ctf in Altivec/PacketMath.h +#if __has_warning("-Wc11-extensions") +#pragma clang diagnostic ignored "-Wc11-extensions" +#endif +#endif +#endif #elif defined __GNUC__ && !defined(__FUJITSU) -// #if (!defined(EIGEN_PERMANENTLY_DISABLE_STUPID_WARNINGS)) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6)) -// #pragma GCC diagnostic push -// #endif -// // g++ warns about local variables shadowing member functions, which is too strict -// #pragma GCC diagnostic ignored "-Wshadow" -// #if __GNUC__ == 4 && __GNUC_MINOR__ < 8 -// // Until g++-4.7 there are warnings when comparing unsigned int vs 0, even in templated functions: -// #pragma GCC diagnostic ignored "-Wtype-limits" -// #endif -// #if __GNUC__ >= 6 -// #pragma GCC diagnostic ignored "-Wignored-attributes" -// #endif -// #if __GNUC__ == 7 -// // See: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=89325 -// #pragma GCC diagnostic ignored "-Wattributes" -// #endif +#if (!defined(EIGEN_PERMANENTLY_DISABLE_STUPID_WARNINGS)) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6)) +#pragma GCC diagnostic push +#endif +// g++ warns about local variables shadowing member functions, which is too strict +#pragma GCC diagnostic ignored "-Wshadow" +#if __GNUC__ == 4 && __GNUC_MINOR__ < 8 +// Until g++-4.7 there are warnings when comparing unsigned int vs 0, even in templated functions: +#pragma GCC diagnostic ignored "-Wtype-limits" +#endif +#if __GNUC__ >= 6 +#pragma GCC diagnostic ignored "-Wignored-attributes" +#endif +#if __GNUC__ == 7 +// See: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=89325 +#pragma GCC diagnostic ignored "-Wattributes" +#endif #endif #if defined __NVCC__ && defined __CUDACC__ diff --git a/inst/include/Eigen/src/Core/util/Macros.h b/inst/include/Eigen/src/Core/util/Macros.h index db4a630..dad3671 100644 --- a/inst/include/Eigen/src/Core/util/Macros.h +++ b/inst/include/Eigen/src/Core/util/Macros.h @@ -52,6 +52,26 @@ #define EIGEN_STACK_ALLOCATION_LIMIT 131072 #endif +/* Specify whether to use std::fma for scalar multiply-add instructions. + * + * On machines that have FMA as a single instruction, this will generally + * improve precision without significant performance implications. + * + * Without a single instruction, performance has been found to be reduced 2-3x + * on Intel CPUs, and up to 30x for WASM. + * + * If unspecified, defaults to using FMA if hardware support is available. + * The default should be used in most cases to ensure consistency between + * vectorized and non-vectorized paths. + */ +#ifndef EIGEN_SCALAR_MADD_USE_FMA +#ifdef EIGEN_VECTORIZE_FMA +#define EIGEN_SCALAR_MADD_USE_FMA 1 +#else +#define EIGEN_SCALAR_MADD_USE_FMA 0 +#endif +#endif + //------------------------------------------------------------------------------------------ // Compiler identification, EIGEN_COMP_* //------------------------------------------------------------------------------------------ diff --git a/inst/include/Eigen/src/Core/util/Memory.h b/inst/include/Eigen/src/Core/util/Memory.h index d6c09a3..1492f72 100644 --- a/inst/include/Eigen/src/Core/util/Memory.h +++ b/inst/include/Eigen/src/Core/util/Memory.h @@ -91,6 +91,9 @@ namespace internal { EIGEN_DEVICE_FUNC inline void check_that_malloc_is_allowed() { eigen_assert(false && "heap allocation is forbidden (EIGEN_NO_MALLOC is defined)"); } +EIGEN_DEVICE_FUNC inline void check_that_free_is_allowed() { + eigen_assert(false && "heap deallocation is forbidden (EIGEN_NO_MALLOC is defined)"); +} #elif defined EIGEN_RUNTIME_NO_MALLOC EIGEN_DEVICE_FUNC inline bool is_malloc_allowed_impl(bool update, bool new_value = false) { EIGEN_MALLOC_CHECK_THREAD_LOCAL static bool value = true; @@ -101,10 +104,22 @@ EIGEN_DEVICE_FUNC inline bool is_malloc_allowed() { return is_malloc_allowed_imp EIGEN_DEVICE_FUNC inline bool set_is_malloc_allowed(bool new_value) { return is_malloc_allowed_impl(true, new_value); } EIGEN_DEVICE_FUNC inline void check_that_malloc_is_allowed() { eigen_assert(is_malloc_allowed() && - "heap allocation is forbidden (EIGEN_RUNTIME_NO_MALLOC is defined and g_is_malloc_allowed is false)"); + "heap allocation is forbidden (EIGEN_RUNTIME_NO_MALLOC is defined and set_is_malloc_allowed is false)"); +} +EIGEN_DEVICE_FUNC inline bool is_free_allowed_impl(bool update, bool new_value = false) { + EIGEN_MALLOC_CHECK_THREAD_LOCAL static bool value = true; + if (update == 1) value = new_value; + return value; +} +EIGEN_DEVICE_FUNC inline bool is_free_allowed() { return is_free_allowed_impl(false); } +EIGEN_DEVICE_FUNC inline bool set_is_free_allowed(bool new_value) { return is_free_allowed_impl(true, new_value); } +EIGEN_DEVICE_FUNC inline void check_that_free_is_allowed() { + eigen_assert(is_malloc_allowed() && + "heap deallocation is forbidden (EIGEN_RUNTIME_NO_MALLOC is defined and set_is_free_allowed is false)"); } #else EIGEN_DEVICE_FUNC inline void check_that_malloc_is_allowed() {} +EIGEN_DEVICE_FUNC inline void check_that_free_is_allowed() {} #endif EIGEN_DEVICE_FUNC inline void throw_std_bad_alloc() { @@ -161,7 +176,7 @@ EIGEN_DEVICE_FUNC inline void handmade_aligned_free(void* ptr) { std::size_t offset = static_cast(*(static_cast(ptr) - 1)) + 1; void* original = static_cast(static_cast(ptr) - offset); - check_that_malloc_is_allowed(); + check_that_free_is_allowed(); EIGEN_USING_STD(free) free(original); } @@ -227,7 +242,7 @@ EIGEN_DEVICE_FUNC inline void aligned_free(void* ptr) { #if (EIGEN_DEFAULT_ALIGN_BYTES == 0) || EIGEN_MALLOC_ALREADY_ALIGNED if (ptr != nullptr) { - check_that_malloc_is_allowed(); + check_that_free_is_allowed(); EIGEN_USING_STD(free) free(ptr); } @@ -299,7 +314,7 @@ EIGEN_DEVICE_FUNC inline void conditional_aligned_free(void* ptr) { template <> EIGEN_DEVICE_FUNC inline void conditional_aligned_free(void* ptr) { if (ptr != nullptr) { - check_that_malloc_is_allowed(); + check_that_free_is_allowed(); EIGEN_USING_STD(free) free(ptr); } @@ -1339,19 +1354,28 @@ EIGEN_DEVICE_FUNC void destroy_at(T* p) { } #endif -/** \internal - * This informs the implementation that PTR is aligned to at least ALIGN_BYTES - */ -#ifndef EIGEN_ASSUME_ALIGNED -#if defined(__cpp_lib_assume_aligned) && (__cpp_lib_assume_aligned >= 201811L) -#define EIGEN_ASSUME_ALIGNED(PTR, ALIGN_BYTES) \ - { PTR = std::assume_aligned<8 * (ALIGN_BYTES)>(PTR); } -#elif EIGEN_HAS_BUILTIN(__builtin_assume_aligned) -#define EIGEN_ASSUME_ALIGNED(PTR, ALIGN_BYTES) \ - { PTR = static_cast(__builtin_assume_aligned(PTR, (ALIGN_BYTES))); } -#else -#define EIGEN_ASSUME_ALIGNED(PTR, ALIGN_BYTES) /* do nothing */ +// FIXME(rmlarsen): Work around missing linker symbol with msan on ARM. +#if !defined(EIGEN_DONT_ASSUME_ALIGNED) && __has_feature(memory_sanitizer) && \ + (EIGEN_ARCH_ARM || EIGEN_ARCH_ARM64) +#define EIGEN_DONT_ASSUME_ALIGNED #endif + + +#if !defined(EIGEN_DONT_ASSUME_ALIGNED) && defined(__cpp_lib_assume_aligned) && (__cpp_lib_assume_aligned >= 201811L) +template +EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC constexpr T* assume_aligned(T* ptr) { + return std::assume_aligned(ptr); +} +#elif !defined(EIGEN_DONT_ASSUME_ALIGNED) && EIGEN_HAS_BUILTIN(__builtin_assume_aligned) +template +EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC T* assume_aligned(T* ptr) { + return static_cast(__builtin_assume_aligned(ptr, N)); +} +#else +template +EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC constexpr T* assume_aligned(T* ptr) { + return ptr; +} #endif } // end namespace internal diff --git a/inst/include/Eigen/src/Householder/Householder.h b/inst/include/Eigen/src/Householder/Householder.h index 96b1daf..e5d2d4f 100644 --- a/inst/include/Eigen/src/Householder/Householder.h +++ b/inst/include/Eigen/src/Householder/Householder.h @@ -65,7 +65,6 @@ template EIGEN_DEVICE_FUNC void MatrixBase::makeHouseholder(EssentialPart& essential, Scalar& tau, RealScalar& beta) const { using numext::conj; - using numext::sqrt; EIGEN_STATIC_ASSERT_VECTOR_ONLY(EssentialPart) VectorBlock tail(derived(), 1, size() - 1); @@ -79,7 +78,7 @@ EIGEN_DEVICE_FUNC void MatrixBase::makeHouseholder(EssentialPart& essen beta = numext::real(c0); essential.setZero(); } else { - beta = sqrt(numext::abs2(c0) + tailSqNorm); + beta = numext::sqrt(numext::abs2(c0) + tailSqNorm); if (numext::real(c0) >= RealScalar(0)) beta = -beta; essential = tail / (c0 - beta); tau = conj((beta - c0) / beta); diff --git a/inst/include/Eigen/src/KLUSupport/KLUSupport.h b/inst/include/Eigen/src/KLUSupport/KLUSupport.h index 9196022..21324ab 100644 --- a/inst/include/Eigen/src/KLUSupport/KLUSupport.h +++ b/inst/include/Eigen/src/KLUSupport/KLUSupport.h @@ -182,7 +182,7 @@ class KLU : public SparseSolverBase > { /** Performs a numeric decomposition of \a matrix * - * The given matrix must has the same sparsity than the matrix on which the pattern anylysis has been performed. + * The given matrix must have the same sparsity than the matrix on which the pattern anylysis has been performed. * * \sa analyzePattern(), compute() */ diff --git a/inst/include/Eigen/src/PardisoSupport/PardisoSupport.h b/inst/include/Eigen/src/PardisoSupport/PardisoSupport.h index c4ca6d3..2f5d83e 100644 --- a/inst/include/Eigen/src/PardisoSupport/PardisoSupport.h +++ b/inst/include/Eigen/src/PardisoSupport/PardisoSupport.h @@ -157,7 +157,8 @@ class PardisoImpl : public SparseSolverBase { /** Performs a numeric decomposition of \a matrix * - * The given matrix must has the same sparsity than the matrix on which the symbolic decomposition has been performed. + * The given matrix must have the same sparsity than the matrix on which the symbolic decomposition has been + * performed. * * \sa analyzePattern() */ diff --git a/inst/include/Eigen/src/SVD/JacobiSVD.h b/inst/include/Eigen/src/SVD/JacobiSVD.h index da2f295..dfcb6df 100644 --- a/inst/include/Eigen/src/SVD/JacobiSVD.h +++ b/inst/include/Eigen/src/SVD/JacobiSVD.h @@ -571,6 +571,11 @@ class JacobiSVD : public SVDBase > { compute_impl(matrix, internal::get_computation_options(Options)); } + template + explicit JacobiSVD(const TriangularBase& matrix) { + compute_impl(matrix, internal::get_computation_options(Options)); + } + /** \brief Constructor performing the decomposition of given matrix using specified options * for computing unitaries. * @@ -601,6 +606,11 @@ class JacobiSVD : public SVDBase > { return compute_impl(matrix, m_computationOptions); } + template + JacobiSVD& compute(const TriangularBase& matrix) { + return compute_impl(matrix, m_computationOptions); + } + /** \brief Method performing the decomposition of given matrix, as specified by * the `computationOptions` parameter. * @@ -638,6 +648,8 @@ class JacobiSVD : public SVDBase > { } private: + template + JacobiSVD& compute_impl(const TriangularBase& matrix, unsigned int computationOptions); template JacobiSVD& compute_impl(const MatrixBase& matrix, unsigned int computationOptions); @@ -676,6 +688,13 @@ class JacobiSVD : public SVDBase > { WorkMatrixType m_workMatrix; }; +template +template +JacobiSVD& JacobiSVD::compute_impl(const TriangularBase& matrix, + unsigned int computationOptions) { + return compute_impl(matrix.toDenseMatrix(), computationOptions); +} + template template JacobiSVD& JacobiSVD::compute_impl(const MatrixBase& matrix, diff --git a/inst/include/Eigen/src/SparseCholesky/SimplicialCholesky.h b/inst/include/Eigen/src/SparseCholesky/SimplicialCholesky.h index d8e2944..1414794 100644 --- a/inst/include/Eigen/src/SparseCholesky/SimplicialCholesky.h +++ b/inst/include/Eigen/src/SparseCholesky/SimplicialCholesky.h @@ -416,7 +416,8 @@ class SimplicialLLT : public SimplicialCholeskyBase > { /** Performs a numeric decomposition of \a matrix * - * The given matrix must has the same sparsity than the matrix on which the symbolic decomposition has been performed. + * The given matrix must have the same sparsity than the matrix on which the symbolic decomposition has been + * performed. * * \sa analyzePattern() */ @@ -791,7 +792,8 @@ class SuperILU : public SuperLUBase > { /** Performs a numeric decomposition of \a matrix * - * The given matrix must has the same sparsity than the matrix on which the symbolic decomposition has been performed. + * The given matrix must have the same sparsity than the matrix on which the symbolic decomposition has been + * performed. * * \sa analyzePattern() */ diff --git a/inst/include/Eigen/src/UmfPackSupport/UmfPackSupport.h b/inst/include/Eigen/src/UmfPackSupport/UmfPackSupport.h index 1df8493..22c701b 100644 --- a/inst/include/Eigen/src/UmfPackSupport/UmfPackSupport.h +++ b/inst/include/Eigen/src/UmfPackSupport/UmfPackSupport.h @@ -425,7 +425,7 @@ class UmfPackLU : public SparseSolverBase > { /** Performs a numeric decomposition of \a matrix * - * The given matrix must has the same sparsity than the matrix on which the pattern anylysis has been performed. + * The given matrix must have the same sparsity than the matrix on which the pattern anylysis has been performed. * * \sa analyzePattern(), compute() */ diff --git a/inst/include/unsupported/Eigen/src/Eigenvalues/ArpackSelfAdjointEigenSolver.h b/inst/include/unsupported/Eigen/src/Eigenvalues/ArpackSelfAdjointEigenSolver.h index 54db9bf..bc21d94 100644 --- a/inst/include/unsupported/Eigen/src/Eigenvalues/ArpackSelfAdjointEigenSolver.h +++ b/inst/include/unsupported/Eigen/src/Eigenvalues/ArpackSelfAdjointEigenSolver.h @@ -454,8 +454,16 @@ ArpackGeneralizedSelfAdjointEigenSolver::compu } } - if (!(mode == 1 && isBempty) && !(mode == 2 && isBempty) && OP.info() != Success) - std::cout << "Error factoring matrix" << std::endl; + if (!(mode == 1 && isBempty) && !(mode == 2 && isBempty) && OP.info() != Success) { + m_info = OP.info() delete[] v; + delete[] iparam; + delete[] ipntr; + delete[] workd; + delete[] workl; + delete[] resid; + m_isInitialized = false; + return *this; + } do { internal::arpack_wrapper::saupd(&ido, bmat, &n, whch, &nev, &tol, resid, &ncv, v, &ldv, iparam, @@ -572,7 +580,7 @@ ArpackGeneralizedSelfAdjointEigenSolver::compu delete[] workl; delete[] resid; - m_isInitialized = true; + m_isInitialized = (m_info == Success); return *this; } diff --git a/inst/include/unsupported/Eigen/src/SparseExtra/MatrixMarketIterator.h b/inst/include/unsupported/Eigen/src/SparseExtra/MatrixMarketIterator.h index 0ccb566..15d7fb2 100644 --- a/inst/include/unsupported/Eigen/src/SparseExtra/MatrixMarketIterator.h +++ b/inst/include/unsupported/Eigen/src/SparseExtra/MatrixMarketIterator.h @@ -170,9 +170,7 @@ class MatrixMarketIterator { m_isvalid = false; std::string curfile; curfile = m_folder + "/" + m_curs_id->d_name; -#if !(defined(__sun) || defined(_AIX) || defined(__hpux) || defined(__sgi) || defined(__HAIKU__)) // Discard if it is a folder -#endif if (m_curs_id->d_type == DT_DIR) continue; // FIXME This may not be available on non BSD systems // struct stat st_buf; // stat (curfile.c_str(), &st_buf); From 08f8ea8a30fed1ae4e422a399d0acac26f349b93 Mon Sep 17 00:00:00 2001 From: Dirk Eddelbuettel Date: Thu, 4 Jun 2026 19:43:16 -0500 Subject: [PATCH 2/4] Applied (and documented) diff carried over from 5.0.0 --- ChangeLog | 10 + inst/include/Eigen/CholmodSupport | 2 +- .../Eigen/src/CholmodSupport/CholmodSupport.h | 60 +++-- .../src/Core/util/DisableStupidWarnings.h | 72 +++--- .../src/SparseExtra/MatrixMarketIterator.h | 2 + patches/eigen-5.0.1.diff | 210 ++++++++++++++++++ patches/howToDiff.md | 7 + 7 files changed, 294 insertions(+), 69 deletions(-) create mode 100644 patches/eigen-5.0.1.diff diff --git a/ChangeLog b/ChangeLog index bbbaed1..7cebcaa 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,13 @@ +2026-06-04 Dirk Eddelbuettel + + * inst/include/Eigen/: Sync with upstream Eigen 5.0.1 + * inst/include/unsupported/Eigen/: Idem + + * inst/include/Eigen/CholmodSupport: Apply previous patch + * inst/include/Eigen/src/CholmodSupport/CholmodSupport.h: Idem + * inst/include/Eigen/src/Core/util/DisableStupidWarnings.h: Idem + * inst/include/unsupported/Eigen/src/SparseExtra/MatrixMarketIterator.h: Idem + 2026-05-03 Dirk Eddelbuettel * vignettes/rnw/RcppEigen-Introduction.Rnw: Moved, also update three diff --git a/inst/include/Eigen/CholmodSupport b/inst/include/Eigen/CholmodSupport index adc5f8d..bff39e6 100644 --- a/inst/include/Eigen/CholmodSupport +++ b/inst/include/Eigen/CholmodSupport @@ -12,7 +12,7 @@ #include "src/Core/util/DisableStupidWarnings.h" -#include +#include /** \ingroup Support_modules * \defgroup CholmodSupport_Module CholmodSupport module diff --git a/inst/include/Eigen/src/CholmodSupport/CholmodSupport.h b/inst/include/Eigen/src/CholmodSupport/CholmodSupport.h index 7e3c881..d5c39a6 100644 --- a/inst/include/Eigen/src/CholmodSupport/CholmodSupport.h +++ b/inst/include/Eigen/src/CholmodSupport/CholmodSupport.h @@ -13,6 +13,10 @@ // IWYU pragma: private #include "./InternalHeaderCheck.h" +#ifndef R_MATRIX_CHOLMOD +# define R_MATRIX_CHOLMOD(_NAME_) cholmod_ ## _NAME_ +#endif + namespace Eigen { namespace internal { @@ -84,8 +88,8 @@ cholmod_sparse viewAsCholmod(Ref if (internal::is_same::value) { res.itype = CHOLMOD_INT; - } else if (internal::is_same::value) { - res.itype = CHOLMOD_LONG; + // } else if (internal::is_same::value) { + // res.itype = CHOLMOD_LONG; } else { eigen_assert(false && "Index type not supported yet"); } @@ -172,21 +176,13 @@ namespace internal { #define EIGEN_CHOLMOD_SPECIALIZE0(ret, name) \ template \ inline ret cm_##name(cholmod_common& Common) { \ - return cholmod_##name(&Common); \ - } \ - template <> \ - inline ret cm_##name(cholmod_common & Common) { \ - return cholmod_l_##name(&Common); \ + return R_MATRIX_CHOLMOD(name)(&Common); \ } -#define EIGEN_CHOLMOD_SPECIALIZE1(ret, name, t1, a1) \ - template \ - inline ret cm_##name(t1& a1, cholmod_common& Common) { \ - return cholmod_##name(&a1, &Common); \ - } \ - template <> \ - inline ret cm_##name(t1 & a1, cholmod_common & Common) { \ - return cholmod_l_##name(&a1, &Common); \ +#define EIGEN_CHOLMOD_SPECIALIZE1(ret, name, t1, a1) \ + template \ + inline ret cm_##name(t1& a1, cholmod_common& Common) { \ + return R_MATRIX_CHOLMOD(name) (&a1, &Common); \ } EIGEN_CHOLMOD_SPECIALIZE0(int, start) @@ -201,33 +197,33 @@ EIGEN_CHOLMOD_SPECIALIZE1(cholmod_sparse*, factor_to_sparse, cholmod_factor, L) template inline cholmod_dense* cm_solve(int sys, cholmod_factor& L, cholmod_dense& B, cholmod_common& Common) { - return cholmod_solve(sys, &L, &B, &Common); -} -template <> -inline cholmod_dense* cm_solve(int sys, cholmod_factor& L, cholmod_dense& B, cholmod_common& Common) { - return cholmod_l_solve(sys, &L, &B, &Common); + return R_MATRIX_CHOLMOD(solve) (sys, &L, &B, &Common); } +// template <> +// inline cholmod_dense* cm_solve(int sys, cholmod_factor& L, cholmod_dense& B, cholmod_common& Common) { +// return cholmod_l_solve(sys, &L, &B, &Common); +// } template inline cholmod_sparse* cm_spsolve(int sys, cholmod_factor& L, cholmod_sparse& B, cholmod_common& Common) { - return cholmod_spsolve(sys, &L, &B, &Common); -} -template <> -inline cholmod_sparse* cm_spsolve(int sys, cholmod_factor& L, cholmod_sparse& B, - cholmod_common& Common) { - return cholmod_l_spsolve(sys, &L, &B, &Common); + return R_MATRIX_CHOLMOD(spsolve) (sys, &L, &B, &Common); } +// template <> +// inline cholmod_sparse* cm_spsolve(int sys, cholmod_factor& L, cholmod_sparse& B, +// cholmod_common& Common) { +// return cholmod_l_spsolve(sys, &L, &B, &Common); +// } template inline int cm_factorize_p(cholmod_sparse* A, double beta[2], StorageIndex_* fset, std::size_t fsize, cholmod_factor* L, cholmod_common& Common) { - return cholmod_factorize_p(A, beta, fset, fsize, L, &Common); -} -template <> -inline int cm_factorize_p(cholmod_sparse* A, double beta[2], SuiteSparse_long* fset, - std::size_t fsize, cholmod_factor* L, cholmod_common& Common) { - return cholmod_l_factorize_p(A, beta, fset, fsize, L, &Common); + return R_MATRIX_CHOLMOD(factorize_p) (A, beta, fset, fsize, L, &Common); } +// template <> +// inline int cm_factorize_p(cholmod_sparse* A, double beta[2], SuiteSparse_long* fset, +// std::size_t fsize, cholmod_factor* L, cholmod_common& Common) { +// return cholmod_l_factorize_p(A, beta, fset, fsize, L, &Common); +// } #undef EIGEN_CHOLMOD_SPECIALIZE0 #undef EIGEN_CHOLMOD_SPECIALIZE1 diff --git a/inst/include/Eigen/src/Core/util/DisableStupidWarnings.h b/inst/include/Eigen/src/Core/util/DisableStupidWarnings.h index ab0c542..8c27b14 100644 --- a/inst/include/Eigen/src/Core/util/DisableStupidWarnings.h +++ b/inst/include/Eigen/src/Core/util/DisableStupidWarnings.h @@ -42,45 +42,45 @@ #pragma warning disable 2196 279 1684 2259 #elif defined __clang__ -#ifndef EIGEN_PERMANENTLY_DISABLE_STUPID_WARNINGS -#pragma clang diagnostic push -#endif -#if defined(__has_warning) -// -Wconstant-logical-operand - warning: use of logical && with constant operand; switch to bitwise & or remove constant -// this is really a stupid warning as it warns on compile-time expressions involving enums -#if __has_warning("-Wconstant-logical-operand") -#pragma clang diagnostic ignored "-Wconstant-logical-operand" -#endif -#if __has_warning("-Wimplicit-int-float-conversion") -#pragma clang diagnostic ignored "-Wimplicit-int-float-conversion" -#endif -#if (defined(__ALTIVEC__) || defined(__VSX__)) && (!defined(__STDC_VERSION__) || (__STDC_VERSION__ < 201112L)) -// warning: generic selections are a C11-specific feature -// ignoring warnings thrown at vec_ctf in Altivec/PacketMath.h -#if __has_warning("-Wc11-extensions") -#pragma clang diagnostic ignored "-Wc11-extensions" -#endif -#endif -#endif +// #ifndef EIGEN_PERMANENTLY_DISABLE_STUPID_WARNINGS +// #pragma clang diagnostic push +// #endif +// #if defined(__has_warning) +// // -Wconstant-logical-operand - warning: use of logical && with constant operand; switch to bitwise & or remove constant +// // this is really a stupid warning as it warns on compile-time expressions involving enums +// #if __has_warning("-Wconstant-logical-operand") +// #pragma clang diagnostic ignored "-Wconstant-logical-operand" +// #endif +// #if __has_warning("-Wimplicit-int-float-conversion") +// #pragma clang diagnostic ignored "-Wimplicit-int-float-conversion" +// #endif +// #if (defined(__ALTIVEC__) || defined(__VSX__)) && (!defined(__STDC_VERSION__) || (__STDC_VERSION__ < 201112L)) +// // warning: generic selections are a C11-specific feature +// // ignoring warnings thrown at vec_ctf in Altivec/PacketMath.h +// #if __has_warning("-Wc11-extensions") +// #pragma clang diagnostic ignored "-Wc11-extensions" +// #endif +// #endif +// #endif #elif defined __GNUC__ && !defined(__FUJITSU) -#if (!defined(EIGEN_PERMANENTLY_DISABLE_STUPID_WARNINGS)) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6)) -#pragma GCC diagnostic push -#endif -// g++ warns about local variables shadowing member functions, which is too strict -#pragma GCC diagnostic ignored "-Wshadow" -#if __GNUC__ == 4 && __GNUC_MINOR__ < 8 -// Until g++-4.7 there are warnings when comparing unsigned int vs 0, even in templated functions: -#pragma GCC diagnostic ignored "-Wtype-limits" -#endif -#if __GNUC__ >= 6 -#pragma GCC diagnostic ignored "-Wignored-attributes" -#endif -#if __GNUC__ == 7 -// See: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=89325 -#pragma GCC diagnostic ignored "-Wattributes" -#endif +// #if (!defined(EIGEN_PERMANENTLY_DISABLE_STUPID_WARNINGS)) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6)) +// #pragma GCC diagnostic push +// #endif +// // g++ warns about local variables shadowing member functions, which is too strict +// #pragma GCC diagnostic ignored "-Wshadow" +// #if __GNUC__ == 4 && __GNUC_MINOR__ < 8 +// // Until g++-4.7 there are warnings when comparing unsigned int vs 0, even in templated functions: +// #pragma GCC diagnostic ignored "-Wtype-limits" +// #endif +// #if __GNUC__ >= 6 +// #pragma GCC diagnostic ignored "-Wignored-attributes" +// #endif +// #if __GNUC__ == 7 +// // See: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=89325 +// #pragma GCC diagnostic ignored "-Wattributes" +// #endif #endif #if defined __NVCC__ && defined __CUDACC__ diff --git a/inst/include/unsupported/Eigen/src/SparseExtra/MatrixMarketIterator.h b/inst/include/unsupported/Eigen/src/SparseExtra/MatrixMarketIterator.h index 15d7fb2..21b62f6 100644 --- a/inst/include/unsupported/Eigen/src/SparseExtra/MatrixMarketIterator.h +++ b/inst/include/unsupported/Eigen/src/SparseExtra/MatrixMarketIterator.h @@ -171,7 +171,9 @@ class MatrixMarketIterator { std::string curfile; curfile = m_folder + "/" + m_curs_id->d_name; // Discard if it is a folder +#if !(defined(__sun) || defined(_AIX) || defined(__hpux) || defined(__sgi) || defined(__HAIKU__)) if (m_curs_id->d_type == DT_DIR) continue; // FIXME This may not be available on non BSD systems +#endif // struct stat st_buf; // stat (curfile.c_str(), &st_buf); // if (S_ISDIR(st_buf.st_mode)) continue; diff --git a/patches/eigen-5.0.1.diff b/patches/eigen-5.0.1.diff new file mode 100644 index 0000000..241ec98 --- /dev/null +++ b/patches/eigen-5.0.1.diff @@ -0,0 +1,210 @@ +diff '--exclude=CMakeLists.txt' -ruw ../eigen/Eigen/CholmodSupport inst/include/Eigen/CholmodSupport +--- ../eigen/Eigen/CholmodSupport 2026-06-04 19:21:16.915228190 -0500 ++++ inst/include/Eigen/CholmodSupport 2026-06-04 19:34:11.433660905 -0500 +@@ -12,7 +12,7 @@ + + #include "src/Core/util/DisableStupidWarnings.h" + +-#include ++#include + + /** \ingroup Support_modules + * \defgroup CholmodSupport_Module CholmodSupport module +diff '--exclude=CMakeLists.txt' -ruw ../eigen/Eigen/src/CholmodSupport/CholmodSupport.h inst/include/Eigen/src/CholmodSupport/CholmodSupport.h +--- ../eigen/Eigen/src/CholmodSupport/CholmodSupport.h 2026-06-04 19:21:16.916228218 -0500 ++++ inst/include/Eigen/src/CholmodSupport/CholmodSupport.h 2026-06-04 19:34:11.433726981 -0500 +@@ -13,6 +13,10 @@ + // IWYU pragma: private + #include "./InternalHeaderCheck.h" + ++#ifndef R_MATRIX_CHOLMOD ++# define R_MATRIX_CHOLMOD(_NAME_) cholmod_ ## _NAME_ ++#endif ++ + namespace Eigen { + + namespace internal { +@@ -84,8 +88,8 @@ + + if (internal::is_same::value) { + res.itype = CHOLMOD_INT; +- } else if (internal::is_same::value) { +- res.itype = CHOLMOD_LONG; ++ // } else if (internal::is_same::value) { ++ // res.itype = CHOLMOD_LONG; + } else { + eigen_assert(false && "Index type not supported yet"); + } +@@ -172,21 +176,13 @@ + #define EIGEN_CHOLMOD_SPECIALIZE0(ret, name) \ + template \ + inline ret cm_##name(cholmod_common& Common) { \ +- return cholmod_##name(&Common); \ +- } \ +- template <> \ +- inline ret cm_##name(cholmod_common & Common) { \ +- return cholmod_l_##name(&Common); \ ++ return R_MATRIX_CHOLMOD(name)(&Common); \ + } + + #define EIGEN_CHOLMOD_SPECIALIZE1(ret, name, t1, a1) \ + template \ + inline ret cm_##name(t1& a1, cholmod_common& Common) { \ +- return cholmod_##name(&a1, &Common); \ +- } \ +- template <> \ +- inline ret cm_##name(t1 & a1, cholmod_common & Common) { \ +- return cholmod_l_##name(&a1, &Common); \ ++ return R_MATRIX_CHOLMOD(name) (&a1, &Common); \ + } + + EIGEN_CHOLMOD_SPECIALIZE0(int, start) +@@ -201,33 +197,33 @@ + + template + inline cholmod_dense* cm_solve(int sys, cholmod_factor& L, cholmod_dense& B, cholmod_common& Common) { +- return cholmod_solve(sys, &L, &B, &Common); +-} +-template <> +-inline cholmod_dense* cm_solve(int sys, cholmod_factor& L, cholmod_dense& B, cholmod_common& Common) { +- return cholmod_l_solve(sys, &L, &B, &Common); ++ return R_MATRIX_CHOLMOD(solve) (sys, &L, &B, &Common); + } ++// template <> ++// inline cholmod_dense* cm_solve(int sys, cholmod_factor& L, cholmod_dense& B, cholmod_common& Common) { ++// return cholmod_l_solve(sys, &L, &B, &Common); ++// } + + template + inline cholmod_sparse* cm_spsolve(int sys, cholmod_factor& L, cholmod_sparse& B, cholmod_common& Common) { +- return cholmod_spsolve(sys, &L, &B, &Common); +-} +-template <> +-inline cholmod_sparse* cm_spsolve(int sys, cholmod_factor& L, cholmod_sparse& B, +- cholmod_common& Common) { +- return cholmod_l_spsolve(sys, &L, &B, &Common); ++ return R_MATRIX_CHOLMOD(spsolve) (sys, &L, &B, &Common); + } ++// template <> ++// inline cholmod_sparse* cm_spsolve(int sys, cholmod_factor& L, cholmod_sparse& B, ++// cholmod_common& Common) { ++// return cholmod_l_spsolve(sys, &L, &B, &Common); ++// } + + template + inline int cm_factorize_p(cholmod_sparse* A, double beta[2], StorageIndex_* fset, std::size_t fsize, cholmod_factor* L, + cholmod_common& Common) { +- return cholmod_factorize_p(A, beta, fset, fsize, L, &Common); +-} +-template <> +-inline int cm_factorize_p(cholmod_sparse* A, double beta[2], SuiteSparse_long* fset, +- std::size_t fsize, cholmod_factor* L, cholmod_common& Common) { +- return cholmod_l_factorize_p(A, beta, fset, fsize, L, &Common); ++ return R_MATRIX_CHOLMOD(factorize_p) (A, beta, fset, fsize, L, &Common); + } ++// template <> ++// inline int cm_factorize_p(cholmod_sparse* A, double beta[2], SuiteSparse_long* fset, ++// std::size_t fsize, cholmod_factor* L, cholmod_common& Common) { ++// return cholmod_l_factorize_p(A, beta, fset, fsize, L, &Common); ++// } + + #undef EIGEN_CHOLMOD_SPECIALIZE0 + #undef EIGEN_CHOLMOD_SPECIALIZE1 +diff '--exclude=CMakeLists.txt' -ruw ../eigen/Eigen/src/Core/util/DisableStupidWarnings.h inst/include/Eigen/src/Core/util/DisableStupidWarnings.h +--- ../eigen/Eigen/src/Core/util/DisableStupidWarnings.h 2026-06-04 19:21:16.930228615 -0500 ++++ inst/include/Eigen/src/Core/util/DisableStupidWarnings.h 2026-06-04 19:34:11.433784882 -0500 +@@ -42,45 +42,45 @@ + #pragma warning disable 2196 279 1684 2259 + + #elif defined __clang__ +-#ifndef EIGEN_PERMANENTLY_DISABLE_STUPID_WARNINGS +-#pragma clang diagnostic push +-#endif +-#if defined(__has_warning) +-// -Wconstant-logical-operand - warning: use of logical && with constant operand; switch to bitwise & or remove constant +-// this is really a stupid warning as it warns on compile-time expressions involving enums +-#if __has_warning("-Wconstant-logical-operand") +-#pragma clang diagnostic ignored "-Wconstant-logical-operand" +-#endif +-#if __has_warning("-Wimplicit-int-float-conversion") +-#pragma clang diagnostic ignored "-Wimplicit-int-float-conversion" +-#endif +-#if (defined(__ALTIVEC__) || defined(__VSX__)) && (!defined(__STDC_VERSION__) || (__STDC_VERSION__ < 201112L)) +-// warning: generic selections are a C11-specific feature +-// ignoring warnings thrown at vec_ctf in Altivec/PacketMath.h +-#if __has_warning("-Wc11-extensions") +-#pragma clang diagnostic ignored "-Wc11-extensions" +-#endif +-#endif +-#endif ++// #ifndef EIGEN_PERMANENTLY_DISABLE_STUPID_WARNINGS ++// #pragma clang diagnostic push ++// #endif ++// #if defined(__has_warning) ++// // -Wconstant-logical-operand - warning: use of logical && with constant operand; switch to bitwise & or remove constant ++// // this is really a stupid warning as it warns on compile-time expressions involving enums ++// #if __has_warning("-Wconstant-logical-operand") ++// #pragma clang diagnostic ignored "-Wconstant-logical-operand" ++// #endif ++// #if __has_warning("-Wimplicit-int-float-conversion") ++// #pragma clang diagnostic ignored "-Wimplicit-int-float-conversion" ++// #endif ++// #if (defined(__ALTIVEC__) || defined(__VSX__)) && (!defined(__STDC_VERSION__) || (__STDC_VERSION__ < 201112L)) ++// // warning: generic selections are a C11-specific feature ++// // ignoring warnings thrown at vec_ctf in Altivec/PacketMath.h ++// #if __has_warning("-Wc11-extensions") ++// #pragma clang diagnostic ignored "-Wc11-extensions" ++// #endif ++// #endif ++// #endif + + #elif defined __GNUC__ && !defined(__FUJITSU) + +-#if (!defined(EIGEN_PERMANENTLY_DISABLE_STUPID_WARNINGS)) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6)) +-#pragma GCC diagnostic push +-#endif +-// g++ warns about local variables shadowing member functions, which is too strict +-#pragma GCC diagnostic ignored "-Wshadow" +-#if __GNUC__ == 4 && __GNUC_MINOR__ < 8 +-// Until g++-4.7 there are warnings when comparing unsigned int vs 0, even in templated functions: +-#pragma GCC diagnostic ignored "-Wtype-limits" +-#endif +-#if __GNUC__ >= 6 +-#pragma GCC diagnostic ignored "-Wignored-attributes" +-#endif +-#if __GNUC__ == 7 +-// See: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=89325 +-#pragma GCC diagnostic ignored "-Wattributes" +-#endif ++// #if (!defined(EIGEN_PERMANENTLY_DISABLE_STUPID_WARNINGS)) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6)) ++// #pragma GCC diagnostic push ++// #endif ++// // g++ warns about local variables shadowing member functions, which is too strict ++// #pragma GCC diagnostic ignored "-Wshadow" ++// #if __GNUC__ == 4 && __GNUC_MINOR__ < 8 ++// // Until g++-4.7 there are warnings when comparing unsigned int vs 0, even in templated functions: ++// #pragma GCC diagnostic ignored "-Wtype-limits" ++// #endif ++// #if __GNUC__ >= 6 ++// #pragma GCC diagnostic ignored "-Wignored-attributes" ++// #endif ++// #if __GNUC__ == 7 ++// // See: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=89325 ++// #pragma GCC diagnostic ignored "-Wattributes" ++// #endif + #endif + + #if defined __NVCC__ && defined __CUDACC__ +diff '--exclude=CMakeLists.txt' -ruw ../eigen/unsupported/Eigen/src/SparseExtra/MatrixMarketIterator.h inst/include/unsupported/Eigen/src/SparseExtra/MatrixMarketIterator.h +--- ../eigen/unsupported/Eigen/src/SparseExtra/MatrixMarketIterator.h 2026-06-04 19:21:16.986230202 -0500 ++++ inst/include/unsupported/Eigen/src/SparseExtra/MatrixMarketIterator.h 2026-06-04 19:38:28.113063684 -0500 +@@ -171,7 +171,9 @@ + std::string curfile; + curfile = m_folder + "/" + m_curs_id->d_name; + // Discard if it is a folder ++#if !(defined(__sun) || defined(_AIX) || defined(__hpux) || defined(__sgi) || defined(__HAIKU__)) + if (m_curs_id->d_type == DT_DIR) continue; // FIXME This may not be available on non BSD systems ++#endif + // struct stat st_buf; + // stat (curfile.c_str(), &st_buf); + // if (S_ISDIR(st_buf.st_mode)) continue; diff --git a/patches/howToDiff.md b/patches/howToDiff.md index a1a4958..57e8086 100644 --- a/patches/howToDiff.md +++ b/patches/howToDiff.md @@ -5,3 +5,10 @@ diff --exclude=CMakeLists.txt -ruw eigen-3.4.0/Eigen/ inst/include/Eigen/ > patches/eigen-3.4.0.diff diff --exclude=CMakeLists.txt -ruw eigen-3.4.0/unsupported/Eigen/ inst/include/unsupported/Eigen/ >> patches/eigen-3.4.0.diff ``` + +or when using a git checkout of eigen (at the appropriate tag and branch) + +```sh +diff --exclude=CMakeLists.txt -ruw ../eigen/Eigen/ inst/include/Eigen > patches/eigen-5.0.1.diff +diff --exclude=CMakeLists.txt -ruw ../eigen/unsupported/Eigen/ inst/include/unsupported/Eigen/ >> patches/eigen-5.0.1.diff +``` From 5a821c270da861b7a3e31fe5b834e3eb39d7ffcb Mon Sep 17 00:00:00 2001 From: Dirk Eddelbuettel Date: Thu, 4 Jun 2026 19:52:07 -0500 Subject: [PATCH 3/4] Additional one-line change, added to diff as well --- ChangeLog | 1 + .../Eigen/src/Core/arch/AltiVec/PacketMath.h | 2 +- patches/eigen-5.0.1.diff | 44 ++++++++++++------- 3 files changed, 30 insertions(+), 17 deletions(-) diff --git a/ChangeLog b/ChangeLog index 7cebcaa..96656e3 100644 --- a/ChangeLog +++ b/ChangeLog @@ -7,6 +7,7 @@ * inst/include/Eigen/src/CholmodSupport/CholmodSupport.h: Idem * inst/include/Eigen/src/Core/util/DisableStupidWarnings.h: Idem * inst/include/unsupported/Eigen/src/SparseExtra/MatrixMarketIterator.h: Idem + * inst/include/Eigen/src/Core/arch/AltiVec/PacketMath.h: New one-line patch 2026-05-03 Dirk Eddelbuettel diff --git a/inst/include/Eigen/src/Core/arch/AltiVec/PacketMath.h b/inst/include/Eigen/src/Core/arch/AltiVec/PacketMath.h index eefe326..bb59cae 100644 --- a/inst/include/Eigen/src/Core/arch/AltiVec/PacketMath.h +++ b/inst/include/Eigen/src/Core/arch/AltiVec/PacketMath.h @@ -486,7 +486,7 @@ EIGEN_ALWAYS_INLINE Packet pload_ignore(const __UNPACK_TYPE__(Packet) * from) { // Ignore partial input memory initialized #if !EIGEN_COMP_LLVM #pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wmaybe-uninitialized" +//#pragma GCC diagnostic ignored "-Wmaybe-uninitialized" #endif #ifdef EIGEN_VECTORIZE_VSX return vec_xl(0, const_cast<__UNPACK_TYPE__(Packet)*>(from)); diff --git a/patches/eigen-5.0.1.diff b/patches/eigen-5.0.1.diff index 241ec98..18bf1d6 100644 --- a/patches/eigen-5.0.1.diff +++ b/patches/eigen-5.0.1.diff @@ -2,12 +2,12 @@ diff '--exclude=CMakeLists.txt' -ruw ../eigen/Eigen/CholmodSupport inst/include/ --- ../eigen/Eigen/CholmodSupport 2026-06-04 19:21:16.915228190 -0500 +++ inst/include/Eigen/CholmodSupport 2026-06-04 19:34:11.433660905 -0500 @@ -12,7 +12,7 @@ - + #include "src/Core/util/DisableStupidWarnings.h" - + -#include +#include - + /** \ingroup Support_modules * \defgroup CholmodSupport_Module CholmodSupport module diff '--exclude=CMakeLists.txt' -ruw ../eigen/Eigen/src/CholmodSupport/CholmodSupport.h inst/include/Eigen/src/CholmodSupport/CholmodSupport.h @@ -16,16 +16,16 @@ diff '--exclude=CMakeLists.txt' -ruw ../eigen/Eigen/src/CholmodSupport/CholmodSu @@ -13,6 +13,10 @@ // IWYU pragma: private #include "./InternalHeaderCheck.h" - + +#ifndef R_MATRIX_CHOLMOD +# define R_MATRIX_CHOLMOD(_NAME_) cholmod_ ## _NAME_ +#endif + namespace Eigen { - + namespace internal { @@ -84,8 +88,8 @@ - + if (internal::is_same::value) { res.itype = CHOLMOD_INT; - } else if (internal::is_same::value) { @@ -46,7 +46,7 @@ diff '--exclude=CMakeLists.txt' -ruw ../eigen/Eigen/src/CholmodSupport/CholmodSu - return cholmod_l_##name(&Common); \ + return R_MATRIX_CHOLMOD(name)(&Common); \ } - + #define EIGEN_CHOLMOD_SPECIALIZE1(ret, name, t1, a1) \ template \ inline ret cm_##name(t1& a1, cholmod_common& Common) { \ @@ -57,10 +57,10 @@ diff '--exclude=CMakeLists.txt' -ruw ../eigen/Eigen/src/CholmodSupport/CholmodSu - return cholmod_l_##name(&a1, &Common); \ + return R_MATRIX_CHOLMOD(name) (&a1, &Common); \ } - + EIGEN_CHOLMOD_SPECIALIZE0(int, start) @@ -201,33 +197,33 @@ - + template inline cholmod_dense* cm_solve(int sys, cholmod_factor& L, cholmod_dense& B, cholmod_common& Common) { - return cholmod_solve(sys, &L, &B, &Common); @@ -74,7 +74,7 @@ diff '--exclude=CMakeLists.txt' -ruw ../eigen/Eigen/src/CholmodSupport/CholmodSu +// inline cholmod_dense* cm_solve(int sys, cholmod_factor& L, cholmod_dense& B, cholmod_common& Common) { +// return cholmod_l_solve(sys, &L, &B, &Common); +// } - + template inline cholmod_sparse* cm_spsolve(int sys, cholmod_factor& L, cholmod_sparse& B, cholmod_common& Common) { - return cholmod_spsolve(sys, &L, &B, &Common); @@ -90,7 +90,7 @@ diff '--exclude=CMakeLists.txt' -ruw ../eigen/Eigen/src/CholmodSupport/CholmodSu +// cholmod_common& Common) { +// return cholmod_l_spsolve(sys, &L, &B, &Common); +// } - + template inline int cm_factorize_p(cholmod_sparse* A, double beta[2], StorageIndex_* fset, std::size_t fsize, cholmod_factor* L, cholmod_common& Common) { @@ -107,15 +107,27 @@ diff '--exclude=CMakeLists.txt' -ruw ../eigen/Eigen/src/CholmodSupport/CholmodSu +// std::size_t fsize, cholmod_factor* L, cholmod_common& Common) { +// return cholmod_l_factorize_p(A, beta, fset, fsize, L, &Common); +// } - + #undef EIGEN_CHOLMOD_SPECIALIZE0 #undef EIGEN_CHOLMOD_SPECIALIZE1 +diff '--exclude=CMakeLists.txt' -ruw ../eigen/Eigen/src/Core/arch/AltiVec/PacketMath.h inst/include/Eigen/src/Core/arch/AltiVec/PacketMath.h +--- ../eigen/Eigen/src/Core/arch/AltiVec/PacketMath.h 2026-06-04 19:21:16.924228445 -0500 ++++ inst/include/Eigen/src/Core/arch/AltiVec/PacketMath.h 2026-06-04 19:48:47.058195837 -0500 +@@ -486,7 +486,7 @@ + // Ignore partial input memory initialized + #if !EIGEN_COMP_LLVM + #pragma GCC diagnostic push +-#pragma GCC diagnostic ignored "-Wmaybe-uninitialized" ++//#pragma GCC diagnostic ignored "-Wmaybe-uninitialized" + #endif + #ifdef EIGEN_VECTORIZE_VSX + return vec_xl(0, const_cast<__UNPACK_TYPE__(Packet)*>(from)); diff '--exclude=CMakeLists.txt' -ruw ../eigen/Eigen/src/Core/util/DisableStupidWarnings.h inst/include/Eigen/src/Core/util/DisableStupidWarnings.h --- ../eigen/Eigen/src/Core/util/DisableStupidWarnings.h 2026-06-04 19:21:16.930228615 -0500 +++ inst/include/Eigen/src/Core/util/DisableStupidWarnings.h 2026-06-04 19:34:11.433784882 -0500 @@ -42,45 +42,45 @@ #pragma warning disable 2196 279 1684 2259 - + #elif defined __clang__ -#ifndef EIGEN_PERMANENTLY_DISABLE_STUPID_WARNINGS -#pragma clang diagnostic push @@ -157,9 +169,9 @@ diff '--exclude=CMakeLists.txt' -ruw ../eigen/Eigen/src/Core/util/DisableStupidW +// #endif +// #endif +// #endif - + #elif defined __GNUC__ && !defined(__FUJITSU) - + -#if (!defined(EIGEN_PERMANENTLY_DISABLE_STUPID_WARNINGS)) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6)) -#pragma GCC diagnostic push -#endif @@ -193,7 +205,7 @@ diff '--exclude=CMakeLists.txt' -ruw ../eigen/Eigen/src/Core/util/DisableStupidW +// #pragma GCC diagnostic ignored "-Wattributes" +// #endif #endif - + #if defined __NVCC__ && defined __CUDACC__ diff '--exclude=CMakeLists.txt' -ruw ../eigen/unsupported/Eigen/src/SparseExtra/MatrixMarketIterator.h inst/include/unsupported/Eigen/src/SparseExtra/MatrixMarketIterator.h --- ../eigen/unsupported/Eigen/src/SparseExtra/MatrixMarketIterator.h 2026-06-04 19:21:16.986230202 -0500 From 09ca6c9bcb2ca328d1ae9e4faf2d37208f0a2059 Mon Sep 17 00:00:00 2001 From: Dirk Eddelbuettel Date: Thu, 4 Jun 2026 19:52:35 -0500 Subject: [PATCH 4/4] Set release to 0.4.9.9-2 for upstream 5.0.1 --- .Rbuildignore | 1 + DESCRIPTION | 4 ++-- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/.Rbuildignore b/.Rbuildignore index f5b9fe6..5c2415d 100644 --- a/.Rbuildignore +++ b/.Rbuildignore @@ -13,3 +13,4 @@ debian ^\.github ^\.codecov.yml ^\.covrignore +^local diff --git a/DESCRIPTION b/DESCRIPTION index a4f09f7..cf12c93 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -1,8 +1,8 @@ Package: RcppEigen Type: Package Title: 'Rcpp' Integration for the 'Eigen' Templated Linear Algebra Library -Version: 0.4.9.9-1 -Date: 2025-12-29 +Version: 0.4.9.9-2 +Date: 2026-06-04 Authors@R: c(person("Doug", "Bates", role = "aut", comment = c(ORCID = "0000-0001-8316-9503")), person("Dirk", "Eddelbuettel", role = c("aut", "cre"), email = "edd@debian.org",