Repetitive calls to reserveInnerVectors in SparseMatrix::insert
@ggael
Submitted by Gael GuennebaudAssigned to Nobody
Link to original bugzilla bug (#1443)
Version: 3.4 (development)
Description
This is an issue report by Emanuel Schmid:
The application code uses a SparseMatrix object several times with setZero() between calculations and matrices of different size (also a small one following a big one). After setZero, reserve is called with an estimate that is at least 50% too large. The coefficients are inserted in non-linear order (sadly).
Considering the end of SparseMatrix::insert():
if(m_data.size() != m_data.allocatedSize())
{
// make sure the matrix is compatible to random un-compressed insertion:
m_data.resize(m_data.allocatedSize());
this->reserveInnerVectors(Array<StorageIndex,Dynamic,1>::Constant(m_outerSize, 2));
}
}
return insertUncompressed(row,col);In the situation where a smaller matrix follows a big one, that code keeps calling reserveInnerVectors from insert, because m_data.size() is never equal to m_data.allocatedSize(). There is another m_data.resize call in reserveInnerVectors, which sets the size to what was reserved. If, however, there is more space allocated from a prior run, that is not equal to allocatedSize anymore (reserve never shrinks the allocated memory).
I added a matrix.data().squeeze() call after setZero now, what reduces the load of the algorithm by 50% (all caused by reserveInnerVectors copying data).
I'm not sure if that should be called bug or if the application is somewhat border case. But maybe someone could ponder over that if-clause above and the resize call in reserveInnerVectors, maybe they could be brought into agreement also if the matrix size is smaller that allocatedSize?