mirror of
https://gitlab.com/libeigen/eigen.git
synced 2025-07-08 06:01:48 +08:00
Fix serialization for non-compressed matrices.
This commit is contained in:
parent
2260e11eb0
commit
dcb042a87d
@ -694,6 +694,11 @@ class SparseMatrix
|
|||||||
Base::operator=(other);
|
Base::operator=(other);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline SparseMatrix(SparseMatrix&& other) : Base(), m_outerSize(0), m_innerSize(0), m_outerIndex(0), m_innerNonZeros(0)
|
||||||
|
{
|
||||||
|
*this = other.derived().markAsRValue();
|
||||||
|
}
|
||||||
|
|
||||||
/** Copy constructor (it performs a deep copy) */
|
/** Copy constructor (it performs a deep copy) */
|
||||||
inline SparseMatrix(const SparseMatrix& other)
|
inline SparseMatrix(const SparseMatrix& other)
|
||||||
: Base(), m_outerSize(0), m_innerSize(0), m_outerIndex(0), m_innerNonZeros(0)
|
: Base(), m_outerSize(0), m_innerSize(0), m_outerIndex(0), m_innerNonZeros(0)
|
||||||
@ -742,6 +747,7 @@ class SparseMatrix
|
|||||||
internal::conditional_aligned_delete_auto<StorageIndex, true>(m_innerNonZeros, m_outerSize);
|
internal::conditional_aligned_delete_auto<StorageIndex, true>(m_innerNonZeros, m_outerSize);
|
||||||
m_innerNonZeros = 0;
|
m_innerNonZeros = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline SparseMatrix& operator=(const SparseMatrix& other)
|
inline SparseMatrix& operator=(const SparseMatrix& other)
|
||||||
{
|
{
|
||||||
if (other.isRValue())
|
if (other.isRValue())
|
||||||
@ -767,6 +773,10 @@ class SparseMatrix
|
|||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline SparseMatrix& operator=(SparseMatrix&& other) {
|
||||||
|
return *this = other.derived().markAsRValue();
|
||||||
|
}
|
||||||
|
|
||||||
#ifndef EIGEN_PARSED_BY_DOXYGEN
|
#ifndef EIGEN_PARSED_BY_DOXYGEN
|
||||||
template<typename OtherDerived>
|
template<typename OtherDerived>
|
||||||
inline SparseMatrix& operator=(const EigenBase<OtherDerived>& other)
|
inline SparseMatrix& operator=(const EigenBase<OtherDerived>& other)
|
||||||
@ -1497,8 +1507,8 @@ struct evaluator<SparseMatrix<Scalar_,Options_,StorageIndex_> >
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Specialization for SparseMatrix.
|
// Specialization for SparseMatrix.
|
||||||
// Serializes [rows, cols, isCompressed, outerSize, numNonZeros, innerNonZeros,
|
// Serializes [rows, cols, isCompressed, outerSize, innerBufferSize,
|
||||||
// outerIndices, innerIndices, values].
|
// innerNonZeros, outerIndices, innerIndices, values].
|
||||||
template <typename Scalar, int Options, typename StorageIndex>
|
template <typename Scalar, int Options, typename StorageIndex>
|
||||||
class Serializer<SparseMatrix<Scalar, Options, StorageIndex>, void> {
|
class Serializer<SparseMatrix<Scalar, Options, StorageIndex>, void> {
|
||||||
public:
|
public:
|
||||||
@ -1509,19 +1519,19 @@ class Serializer<SparseMatrix<Scalar, Options, StorageIndex>, void> {
|
|||||||
typename SparseMat::Index cols;
|
typename SparseMat::Index cols;
|
||||||
bool compressed;
|
bool compressed;
|
||||||
Index outer_size;
|
Index outer_size;
|
||||||
Index num_non_zeros;
|
Index inner_buffer_size;
|
||||||
};
|
};
|
||||||
|
|
||||||
EIGEN_DEVICE_FUNC size_t size(const SparseMat& value) const {
|
EIGEN_DEVICE_FUNC size_t size(const SparseMat& value) const {
|
||||||
// innerNonZeros.
|
// innerNonZeros.
|
||||||
std::size_t num_storage_indices =
|
std::size_t num_storage_indices = value.isCompressed() ? 0 : value.outerSize();
|
||||||
value.isCompressed() ? 0 : value.outerSize();
|
|
||||||
// Outer indices.
|
// Outer indices.
|
||||||
num_storage_indices += value.outerSize() + 1;
|
num_storage_indices += value.outerSize() + 1;
|
||||||
// Inner indices.
|
// Inner indices.
|
||||||
num_storage_indices += value.nonZeros();
|
const StorageIndex inner_buffer_size = value.outerIndexPtr()[value.outerSize()];
|
||||||
|
num_storage_indices += inner_buffer_size;
|
||||||
// Values.
|
// Values.
|
||||||
std::size_t num_values = value.nonZeros();
|
std::size_t num_values = inner_buffer_size;
|
||||||
return sizeof(Header) + sizeof(Scalar) * num_values +
|
return sizeof(Header) + sizeof(Scalar) * num_values +
|
||||||
sizeof(StorageIndex) * num_storage_indices;
|
sizeof(StorageIndex) * num_storage_indices;
|
||||||
}
|
}
|
||||||
@ -1533,30 +1543,30 @@ class Serializer<SparseMatrix<Scalar, Options, StorageIndex>, void> {
|
|||||||
|
|
||||||
const size_t header_bytes = sizeof(Header);
|
const size_t header_bytes = sizeof(Header);
|
||||||
Header header = {value.rows(), value.cols(), value.isCompressed(),
|
Header header = {value.rows(), value.cols(), value.isCompressed(),
|
||||||
value.outerSize(), value.nonZeros()};
|
value.outerSize(), value.outerIndexPtr()[value.outerSize()]};
|
||||||
EIGEN_USING_STD(memcpy)
|
EIGEN_USING_STD(memcpy)
|
||||||
memcpy(dest, &header, header_bytes);
|
memcpy(dest, &header, header_bytes);
|
||||||
dest += header_bytes;
|
dest += header_bytes;
|
||||||
|
|
||||||
// innerNonZeros.
|
// innerNonZeros.
|
||||||
size_t data_bytes = sizeof(StorageIndex) * header.outer_size;
|
|
||||||
if (!header.compressed) {
|
if (!header.compressed) {
|
||||||
|
std:size_t data_bytes = sizeof(StorageIndex) * header.outer_size;
|
||||||
memcpy(dest, value.innerNonZeroPtr(), data_bytes);
|
memcpy(dest, value.innerNonZeroPtr(), data_bytes);
|
||||||
dest += data_bytes;
|
dest += data_bytes;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Outer indices.
|
// Outer indices.
|
||||||
data_bytes = sizeof(StorageIndex) * (header.outer_size + 1);
|
std::size_t data_bytes = sizeof(StorageIndex) * (header.outer_size + 1);
|
||||||
memcpy(dest, value.outerIndexPtr(), data_bytes);
|
memcpy(dest, value.outerIndexPtr(), data_bytes);
|
||||||
dest += data_bytes;
|
dest += data_bytes;
|
||||||
|
|
||||||
// Inner indices.
|
// Inner indices.
|
||||||
data_bytes = sizeof(StorageIndex) * header.num_non_zeros;
|
data_bytes = sizeof(StorageIndex) * header.inner_buffer_size;
|
||||||
memcpy(dest, value.innerIndexPtr(), data_bytes);
|
memcpy(dest, value.innerIndexPtr(), data_bytes);
|
||||||
dest += data_bytes;
|
dest += data_bytes;
|
||||||
|
|
||||||
// Values.
|
// Values.
|
||||||
data_bytes = sizeof(Scalar) * header.num_non_zeros;
|
data_bytes = sizeof(Scalar) * header.inner_buffer_size;
|
||||||
memcpy(dest, value.valuePtr(), data_bytes);
|
memcpy(dest, value.valuePtr(), data_bytes);
|
||||||
dest += data_bytes;
|
dest += data_bytes;
|
||||||
|
|
||||||
@ -1577,37 +1587,38 @@ class Serializer<SparseMatrix<Scalar, Options, StorageIndex>, void> {
|
|||||||
|
|
||||||
value.setZero();
|
value.setZero();
|
||||||
value.resize(header.rows, header.cols);
|
value.resize(header.rows, header.cols);
|
||||||
|
|
||||||
// Initialize compressed state and inner non-zeros.
|
|
||||||
size_t data_bytes = sizeof(StorageIndex) * header.outer_size;
|
|
||||||
if (EIGEN_PREDICT_FALSE(src + data_bytes > end)) return nullptr;
|
|
||||||
if (header.compressed) {
|
if (header.compressed) {
|
||||||
value.makeCompressed();
|
value.makeCompressed();
|
||||||
value.resizeNonZeros(header.num_non_zeros);
|
|
||||||
} else {
|
} else {
|
||||||
// Temporarily load inner sizes, then reserve.
|
|
||||||
std::vector<StorageIndex> inner_sizes(header.outer_size);
|
|
||||||
memcpy(inner_sizes.data(), src, data_bytes);
|
|
||||||
src += data_bytes;
|
|
||||||
|
|
||||||
value.uncompress();
|
value.uncompress();
|
||||||
value.reserve(inner_sizes);
|
}
|
||||||
memcpy(value.innerNonZeroPtr(), inner_sizes.data(), data_bytes);
|
|
||||||
|
// Adjust value ptr size.
|
||||||
|
value.data().resize(header.inner_buffer_size);
|
||||||
|
|
||||||
|
// Initialize compressed state and inner non-zeros.
|
||||||
|
if (!header.compressed) {
|
||||||
|
// 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);
|
||||||
|
src += data_bytes;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Outer indices.
|
// Outer indices.
|
||||||
data_bytes = sizeof(StorageIndex) * (header.outer_size + 1);
|
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);
|
memcpy(value.outerIndexPtr(), src, data_bytes);
|
||||||
src += data_bytes;
|
src += data_bytes;
|
||||||
|
|
||||||
// Inner indices.
|
// Inner indices.
|
||||||
data_bytes = sizeof(StorageIndex) * header.num_non_zeros;
|
data_bytes = sizeof(StorageIndex) * header.inner_buffer_size;
|
||||||
if (EIGEN_PREDICT_FALSE(src + data_bytes > end)) return nullptr;
|
if (EIGEN_PREDICT_FALSE(src + data_bytes > end)) return nullptr;
|
||||||
memcpy(value.innerIndexPtr(), src, data_bytes);
|
memcpy(value.innerIndexPtr(), src, data_bytes);
|
||||||
src += data_bytes;
|
src += data_bytes;
|
||||||
|
|
||||||
// Values.
|
// Values.
|
||||||
data_bytes = sizeof(Scalar) * header.num_non_zeros;
|
data_bytes = sizeof(Scalar) * header.inner_buffer_size;
|
||||||
if (EIGEN_PREDICT_FALSE(src + data_bytes > end)) return nullptr;
|
if (EIGEN_PREDICT_FALSE(src + data_bytes > end)) return nullptr;
|
||||||
memcpy(value.valuePtr(), src, data_bytes);
|
memcpy(value.valuePtr(), src, data_bytes);
|
||||||
src += data_bytes;
|
src += data_bytes;
|
||||||
|
@ -30,7 +30,7 @@ struct RandomImpl<Eigen::SparseMatrix<Scalar, Options, DenseIndex>> {
|
|||||||
double density = 0.1;
|
double density = 0.1;
|
||||||
|
|
||||||
// Reserve some space along each inner dim.
|
// Reserve some space along each inner dim.
|
||||||
int nnz = static_cast<int>(density * 1.5 * M.innerSize());
|
int nnz = static_cast<int>(std::ceil(density * 1.5 * M.innerSize()));
|
||||||
M.reserve(Eigen::VectorXi::Constant(M.outerSize(), nnz));
|
M.reserve(Eigen::VectorXi::Constant(M.outerSize(), nnz));
|
||||||
|
|
||||||
for (int j = 0; j < M.outerSize(); j++) {
|
for (int j = 0; j < M.outerSize(); j++) {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user