Fix sanitizer regressions in sparse serializer and packet tests

libeigen/eigen!2319

Co-authored-by: Rasmus Munk Larsen <rmlarsen@gmail.com>
This commit is contained in:
Rasmus Munk Larsen
2026-03-22 09:10:16 -07:00
parent 835e5615a9
commit 6490b17e6f
7 changed files with 129 additions and 52 deletions

View File

@@ -821,10 +821,24 @@ EIGEN_DEVICE_FUNC inline Packet pset1(const typename unpacket_traits<Packet>::ty
template <typename Packet, typename BitsType>
EIGEN_DEVICE_FUNC inline Packet pset1frombits(BitsType a);
template <typename Scalar, std::enable_if_t<std::is_trivially_copyable<Scalar>::value, int> = 0>
EIGEN_DEVICE_FUNC inline Scalar pload1_scalar(const Scalar* a) {
Scalar scalar;
EIGEN_USING_STD(memcpy)
memcpy(&scalar, a, sizeof(Scalar));
return scalar;
}
template <typename Scalar, std::enable_if_t<!std::is_trivially_copyable<Scalar>::value, int> = 0>
EIGEN_DEVICE_FUNC inline Scalar pload1_scalar(const Scalar* a) {
return Scalar(*a);
}
/** \internal \returns a packet with constant coefficients \a a[0], e.g.: (a[0],a[0],a[0],a[0]) */
template <typename Packet>
EIGEN_DEVICE_FUNC inline Packet pload1(const typename unpacket_traits<Packet>::type* a) {
return pset1<Packet>(*a);
using Scalar = typename unpacket_traits<Packet>::type;
return pset1<Packet>(pload1_scalar<Scalar>(a));
}
/** \internal \returns a packet with elements of \a *from duplicated.
@@ -834,7 +848,7 @@ EIGEN_DEVICE_FUNC inline Packet pload1(const typename unpacket_traits<Packet>::t
*/
template <typename Packet>
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Packet ploaddup(const typename unpacket_traits<Packet>::type* from) {
return *from;
return pload1<Packet>(from);
}
/** \internal \returns a packet with elements of \a *from quadrupled.

View File

@@ -245,7 +245,8 @@ EIGEN_STRONG_INLINE VectorT load_vector_unaligned(const scalar_type_of_vector_t<
template <typename VectorT>
EIGEN_STRONG_INLINE VectorT load_vector_aligned(const scalar_type_of_vector_t<VectorT>* from) {
return *reinterpret_cast<const VectorT*>(assume_aligned<EIGEN_GENERIC_VECTOR_SIZE_BYTES>(from));
eigen_assert((std::uintptr_t(from) % alignof(VectorT) == 0) && "load_vector_aligned");
return *reinterpret_cast<const VectorT*>(assume_aligned<alignof(VectorT)>(from));
}
template <typename VectorT>
@@ -255,7 +256,8 @@ EIGEN_STRONG_INLINE void store_vector_unaligned(scalar_type_of_vector_t<VectorT>
template <typename VectorT>
EIGEN_STRONG_INLINE void store_vector_aligned(scalar_type_of_vector_t<VectorT>* to, const VectorT& from) {
*reinterpret_cast<VectorT*>(assume_aligned<EIGEN_GENERIC_VECTOR_SIZE_BYTES>(to)) = from;
eigen_assert((std::uintptr_t(to) % alignof(VectorT) == 0) && "store_vector_aligned");
*reinterpret_cast<VectorT*>(assume_aligned<alignof(VectorT)>(to)) = from;
}
} // namespace detail

View File

@@ -1846,26 +1846,34 @@ class Serializer<SparseMatrix<Scalar, Options, StorageIndex>, void> {
// Inner non-zero counts.
std::size_t data_bytes = sizeof(StorageIndex) * header.outer_size;
if (EIGEN_PREDICT_FALSE(src + data_bytes > end)) return nullptr;
memcpy(value.innerNonZeroPtr(), src, data_bytes);
if (data_bytes != 0) {
memcpy(value.innerNonZeroPtr(), src, data_bytes);
}
src += data_bytes;
}
// Outer indices.
std::size_t data_bytes = sizeof(StorageIndex) * (header.outer_size + 1);
if (EIGEN_PREDICT_FALSE(src + data_bytes > end)) return nullptr;
memcpy(value.outerIndexPtr(), src, data_bytes);
if (data_bytes != 0) {
memcpy(value.outerIndexPtr(), src, data_bytes);
}
src += data_bytes;
// Inner indices.
data_bytes = sizeof(StorageIndex) * header.inner_buffer_size;
if (EIGEN_PREDICT_FALSE(src + data_bytes > end)) return nullptr;
memcpy(value.innerIndexPtr(), src, data_bytes);
if (data_bytes != 0) {
memcpy(value.innerIndexPtr(), src, data_bytes);
}
src += data_bytes;
// Values.
data_bytes = sizeof(Scalar) * header.inner_buffer_size;
if (EIGEN_PREDICT_FALSE(src + data_bytes > end)) return nullptr;
memcpy(value.valuePtr(), src, data_bytes);
if (data_bytes != 0) {
memcpy(value.valuePtr(), src, data_bytes);
}
src += data_bytes;
return src;
}

View File

@@ -487,12 +487,16 @@ class Serializer<SparseVector<Scalar, Options, StorageIndex>, void> {
// Inner indices.
std::size_t data_bytes = sizeof(StorageIndex) * header.num_non_zeros;
memcpy(dest, value.innerIndexPtr(), data_bytes);
if (data_bytes != 0) {
memcpy(dest, value.innerIndexPtr(), data_bytes);
}
dest += data_bytes;
// Values.
data_bytes = sizeof(Scalar) * header.num_non_zeros;
memcpy(dest, value.valuePtr(), data_bytes);
if (data_bytes != 0) {
memcpy(dest, value.valuePtr(), data_bytes);
}
dest += data_bytes;
return dest;
@@ -515,13 +519,17 @@ class Serializer<SparseVector<Scalar, Options, StorageIndex>, void> {
// Inner indices.
std::size_t data_bytes = sizeof(StorageIndex) * header.num_non_zeros;
if (EIGEN_PREDICT_FALSE(src + data_bytes > end)) return nullptr;
memcpy(value.innerIndexPtr(), src, data_bytes);
if (data_bytes != 0) {
memcpy(value.innerIndexPtr(), src, data_bytes);
}
src += data_bytes;
// Values.
data_bytes = sizeof(Scalar) * header.num_non_zeros;
if (EIGEN_PREDICT_FALSE(src + data_bytes > end)) return nullptr;
memcpy(value.valuePtr(), src, data_bytes);
if (data_bytes != 0) {
memcpy(value.valuePtr(), src, data_bytes);
}
src += data_bytes;
return src;
}