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/ChangeLog b/ChangeLog index bbbaed1..96656e3 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,14 @@ +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 + * inst/include/Eigen/src/Core/arch/AltiVec/PacketMath.h: New one-line patch + 2026-05-03 Dirk Eddelbuettel * vignettes/rnw/RcppEigen-Introduction.Rnw: Moved, also update three 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", 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..d5c39a6 100644 --- a/inst/include/Eigen/src/CholmodSupport/CholmodSupport.h +++ b/inst/include/Eigen/src/CholmodSupport/CholmodSupport.h @@ -177,13 +177,13 @@ namespace internal { template \ inline ret cm_##name(cholmod_common& 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 R_MATRIX_CHOLMOD(name) (&a1, &Common); \ - } + } EIGEN_CHOLMOD_SPECIALIZE0(int, start) EIGEN_CHOLMOD_SPECIALIZE0(int, finish) 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/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/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/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..21b62f6 100644 --- a/inst/include/unsupported/Eigen/src/SparseExtra/MatrixMarketIterator.h +++ b/inst/include/unsupported/Eigen/src/SparseExtra/MatrixMarketIterator.h @@ -170,10 +170,10 @@ 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 !(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..18bf1d6 --- /dev/null +++ b/patches/eigen-5.0.1.diff @@ -0,0 +1,222 @@ +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/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 +-#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 +```