[mathicgb] 76/393: Fixed a memory leak in SparseMatrix. Also miscellaneous code cleanup in SparseMatrix.
Doug Torrance
dtorrance-guest at moszumanska.debian.org
Fri Apr 3 15:58:34 UTC 2015
This is an automated email from the git hooks/post-receive script.
dtorrance-guest pushed a commit to branch upstream
in repository mathicgb.
commit 980501cc0fa7665fcb67137b26119c7e7190eb49
Author: Bjarke Hammersholt Roune <bjarkehr.code at gmail.com>
Date: Wed Oct 24 15:40:19 2012 +0200
Fixed a memory leak in SparseMatrix. Also miscellaneous code cleanup in SparseMatrix.
---
src/mathicgb/SparseMatrix.cpp | 54 +++++++++
src/mathicgb/SparseMatrix.hpp | 266 +++++++++++++++---------------------------
2 files changed, 149 insertions(+), 171 deletions(-)
diff --git a/src/mathicgb/SparseMatrix.cpp b/src/mathicgb/SparseMatrix.cpp
index 4c1b98c..bc205bf 100755
--- a/src/mathicgb/SparseMatrix.cpp
+++ b/src/mathicgb/SparseMatrix.cpp
@@ -186,3 +186,57 @@ bool SparseMatrix::appendRowWithModulusIfNonZero(std::vector<uint64> const& v, S
} else
return true;
}
+
+void SparseMatrix::trimLeadingZeroColumns(ColIndex trimThisMany) {
+ MATHICGB_ASSERT(trimThisMany <= colCount());
+ const auto end = mColIndices.end();
+ for (auto it = mColIndices.begin(); it != end; ++it) {
+ MATHICGB_ASSERT(*it >= trimThisMany);
+ *it -= trimThisMany;
+ }
+ mColCount -= trimThisMany;
+}
+
+void SparseMatrix::reserveEntries(size_t count) {
+ if (count < mEntries.capacity())
+ return;
+
+ ptrdiff_t scalarPtrDelta;
+ {
+ const auto begin = new Scalar[count];
+ const auto capacityEnd = begin + count;
+ scalarPtrDelta = begin - mEntries.begin();
+ delete[] mEntries.setMemoryAndCopy(begin, capacityEnd);
+ }
+
+ ptrdiff_t entryPtrDelta;
+ {
+ const auto begin = new ColIndex[count];
+ const auto capacityEnd = begin + count;
+ entryPtrDelta = begin - mColIndices.begin();
+ delete[] mColIndices.setMemoryAndCopy(begin, capacityEnd);
+ }
+
+ const auto rowEnd = mRows.end();
+ for (auto it = mRows.begin(); it != rowEnd; ++it) {
+ it->mIndicesBegin += entryPtrDelta;
+ it->mIndicesEnd += entryPtrDelta;
+ it->mScalarsBegin += scalarPtrDelta;
+ it->mScalarsEnd += scalarPtrDelta;
+ }
+}
+
+void SparseMatrix::growEntryCapacity() {
+ MATHICGB_ASSERT(mColIndices.size() == mEntries.size());
+ MATHICGB_ASSERT(mColIndices.capacity() == mEntries.capacity());
+
+ const size_t initialCapacity = 1 << 16;
+ const size_t growthFactor = 2;
+ const size_t newCapacity =
+ mEntries.empty() ? initialCapacity : mEntries.capacity() * growthFactor;
+ reserveEntries(newCapacity);
+
+ MATHICGB_ASSERT(mColIndices.size() == mEntries.size());
+ MATHICGB_ASSERT(mColIndices.capacity() == newCapacity);
+ MATHICGB_ASSERT(mEntries.capacity() == newCapacity);
+}
diff --git a/src/mathicgb/SparseMatrix.hpp b/src/mathicgb/SparseMatrix.hpp
index b4cf4f2..4bc1f30 100755
--- a/src/mathicgb/SparseMatrix.hpp
+++ b/src/mathicgb/SparseMatrix.hpp
@@ -45,6 +45,10 @@ public:
typedef size_t RowIndex;
typedef uint32 ColIndex;
typedef uint16 Scalar;
+ class ConstRowIterator;
+
+ /// Construct a matrix with no rows.
+ SparseMatrix(ColIndex colCount = 0): mColCount(colCount) {}
SparseMatrix(SparseMatrix&& matrix):
mColIndices(std::move(matrix.mColIndices)),
@@ -61,103 +65,75 @@ public:
}
~SparseMatrix() {
-#ifdef MATHICGB_DEBUG
- for (auto it = mRows.begin(); it != mRows.end(); ++it) {
- MATHICGB_ASSERT(it->debugValid());
- }
-#endif
-
+ delete[] mColIndices.releaseMemory();
delete[] mEntries.releaseMemory();
}
- /** Preallocate space for at least count entries. */
- void reserveEntries(size_t count) {
- if (count < mEntries.capacity())
- return;
-
- ptrdiff_t scalarPtrDelta;
- {
- const auto begin = new Scalar[count];
- const auto capacityEnd = begin + count;
- scalarPtrDelta = begin - mEntries.begin();
- delete[] mEntries.setMemoryAndCopy(begin, capacityEnd);
- }
+ void swap(SparseMatrix& matrix);
- ptrdiff_t entryPtrDelta;
- {
- const auto begin = new ColIndex[count];
- const auto capacityEnd = begin + count;
- entryPtrDelta = begin - mColIndices.begin();
- delete[] mColIndices.setMemoryAndCopy(begin, capacityEnd);
- }
+ void clear(ColIndex newColCount = 0);
- const auto rowEnd = mRows.end();
- for (auto it = mRows.begin(); it != rowEnd; ++it) {
- it->mIndicesBegin += entryPtrDelta;
- it->mIndicesEnd += entryPtrDelta;
- it->mScalarsBegin += scalarPtrDelta;
- it->mScalarsEnd += scalarPtrDelta;
- MATHICGB_ASSERT(it->debugValid());
- }
- }
+ RowIndex rowCount() const {return mRows.size();}
+ ColIndex colCount() const {return mColCount;}
- /** Preallocate space for at least count rows. */
- void reserveRows(size_t count) {
- mRows.reserve(count);
- }
+ /// Returns the number of entries in the whole matrix.
+ size_t entryCount() const {return mEntries.size();}
- /** Returns the index of the first entry in the given row. This is
- the first entry that you added to the row - so not necessarily the
- minimum column index in that row. The row in question must have at
- least one entry. */
- ColIndex leadCol(RowIndex row) const {
+ /// Returns the number of entries in the given row.
+ ColIndex entryCountInRow(RowIndex row) const {
MATHICGB_ASSERT(row < rowCount());
- MATHICGB_ASSERT(!emptyRow(row));
- return *mRows[row].mIndicesBegin;
+ return mRows[row].size();
}
- /** Returns true if the given row has no entries. */
+ /// Returns true if the given row has no entries.
bool emptyRow(RowIndex row) const {
MATHICGB_ASSERT(row < rowCount());
return mRows[row].empty();
}
- /** Removes the leading trimThisMany columns. The columns are
- removed by replacing all column indices col by col -
- trimThisMany. No entry can have a column index less than
- trimThisMany, even if the scalar of that entry is set to zero. */
- void trimLeadingZeroColumns(ColIndex trimThisMany) {
- MATHICGB_ASSERT(trimThisMany <= colCount());
- const auto end = mColIndices.end();
- for (auto it = mColIndices.begin(); it != end; ++it) {
- MATHICGB_ASSERT(*it >= trimThisMany);
- *it -= trimThisMany;
- }
- mColCount -= trimThisMany;
+ ConstRowIterator rowBegin(RowIndex row) const {
+ MATHICGB_ASSERT(row < rowCount());
+ const Row& r = mRows[row];
+ return ConstRowIterator(r.mIndicesBegin, r.mScalarsBegin);
}
- /** Construct a matrix with no rows and colCount columns. */
- SparseMatrix(ColIndex colCount = 0):
- mColCount(colCount)
- {
+ ConstRowIterator rowEnd(RowIndex row) const {
+ MATHICGB_ASSERT(row < rowCount());
+ const Row& r = mRows[row];
+ return ConstRowIterator(r.mIndicesEnd, r.mScalarsEnd);
}
- /** Returns the number of entries in the given row. */
- ColIndex entryCountInRow(RowIndex row) const {
+ /// Returns the index of the first entry in the given row. This is
+ /// the first entry that you added to the row - so not necessarily the
+ /// minimum column index in that row. The row in question must have at
+ /// least one entry.
+ ColIndex leadCol(RowIndex row) const {
MATHICGB_ASSERT(row < rowCount());
- return mRows[row].size();
+ MATHICGB_ASSERT(!emptyRow(row));
+ return *mRows[row].mIndicesBegin;
}
- /** Returns the number of entries in the whole matrix. */
- size_t entryCount() const {return mEntries.size();}
-
- /** Prints the matrix in a human readable format to out. */
+ /// Prints the matrix in a human readable format to out.
void print(std::ostream& out) const;
std::string toString() const;
- /** Adds a new row that contains all terms that have been appended
- since the last time a row was added or the matrix was created. */
+
+
+ /// Removes the leading trimThisMany columns. The columns are
+ /// removed by replacing all column indices col by col -
+ /// trimThisMany. No entry can have a column index less than
+ /// trimThisMany, even if the scalar of that entry is set to zero.
+ void trimLeadingZeroColumns(ColIndex trimThisMany);
+
+ /// Preallocate space for at least count entries.
+ void reserveEntries(size_t count);
+
+ /// Preallocate space for at least count rows.
+ void reserveRows(size_t count) {mRows.reserve(count);}
+
+ /// Adds a new row that contains all terms that have been appended
+ /// since the last time a row was added or the matrix was created.
void rowDone() {
MATHICGB_ASSERT(mColIndices.size() == entryCount());
Row row;
@@ -173,9 +149,9 @@ public:
mRows.push_back(row);
}
- /** Appends an entry to the matrix. Will not appear in the matrix
- until rowDone is called. Do not call other methods that add rows
- after calling this method until rowDone has been called. */
+ /// Appends an entry to the matrix. Will not appear in the matrix
+ /// until rowDone is called. Do not call other methods that add rows
+ /// after calling this method until rowDone has been called.
void appendEntry(ColIndex colIndex, Scalar scalar) {
MATHICGB_ASSERT(mColIndices.size() == entryCount());
MATHICGB_ASSERT(colIndex < colCount());
@@ -195,35 +171,44 @@ public:
void appendRowAndNormalize(const SparseMatrix& matrix, RowIndex row, Scalar modulus);
void appendRow(const SparseMatrix& matrix, RowIndex row);
- void swap(SparseMatrix& matrix);
- void clear(ColIndex newColCount = 0);
+
+ void ensureAtLeastThisManyColumns(ColIndex count) {
+ if (count > colCount())
+ mColCount = count;
+ }
+
+ /// Adds one more column to the matrix and returns the index of the new
+ /// column.
+ ColIndex appendColumn() {
+ if (colCount() == std::numeric_limits<ColIndex>::max())
+ mathic::reportError("Too many columns in SparseMatrix.");
+ ++mColCount;
+ return mColCount - 1;
+ }
+
+ void appendRowWithModulus(std::vector<uint64> const& v, Scalar modulus);
- private:
- struct Row {
- Row(): mScalarsBegin(0), mScalarsEnd(0), mIndicesBegin(0), mIndicesEnd(0) {}
+ void appendRow(std::vector<uint64> const& v, ColIndex leadCol = 0);
- bool debugValid() {
- const size_t scalarCount = std::distance(mScalarsBegin, mScalarsEnd);
- const size_t indexCount = std::distance(mIndicesBegin, mIndicesEnd);
- MATHICGB_ASSERT(scalarCount == indexCount);
- return true;
- }
+ void appendRowWithModulusNormalized(std::vector<uint64> const& v, Scalar modulus);
- Scalar* mScalarsBegin;
- Scalar* mScalarsEnd;
- ColIndex* mIndicesBegin;
- ColIndex* mIndicesEnd;
+ // Returns true if the row was non-zero. Otherwise the row was not
+ // appended.
+ bool appendRowWithModulusIfNonZero(std::vector<uint64> const& v, Scalar modulus);
- bool empty() const {return mIndicesBegin == mIndicesEnd;}
- ColIndex size() const {
- return static_cast<ColIndex>(std::distance(mIndicesBegin, mIndicesEnd));
- }
+ /// Replaces all column indices i with colMap[i].
+ void applyColumnMap(std::vector<ColIndex> colMap);
- private:
- void operator==(const Row&) const; // not available
- };
-public:
+ /// Let poly be the dot product of colMonomials and the given row.
+ void rowToPolynomial
+ (RowIndex row, std::vector<monomial> colMonomials, Poly& poly);
+ /// Reorders the rows so that the index of the leading column in
+ /// each row is weakly increasing going from top to bottom. Quite
+ /// slow and it makes a copy internally.
+ void sortRowsByIncreasingPivots();
+
+ /// Iterates through the entries in a row.
class ConstRowIterator {
public:
typedef const std::pair<ColIndex, Scalar> value_type;
@@ -272,86 +257,26 @@ public:
const Scalar* mScalarIt;
};
- RowIndex rowCount() const {
- return mRows.size();
- }
-
- ColIndex colCount() const {return mColCount;}
-
- ConstRowIterator rowBegin(RowIndex row) const {
- MATHICGB_ASSERT(row < rowCount());
- const Row& r = mRows[row];
- return ConstRowIterator(r.mIndicesBegin, r.mScalarsBegin);
- }
-
- ConstRowIterator rowEnd(RowIndex row) const {
- MATHICGB_ASSERT(row < rowCount());
- const Row& r = mRows[row];
- return ConstRowIterator(r.mIndicesEnd, r.mScalarsEnd);
- }
-
- void ensureAtLeastThisManyColumns(ColIndex count) {
- if (count > colCount())
- mColCount = count;
- }
-
- /** Adds one more column to the matrix and returns the index of the new
- column. */
- ColIndex appendColumn() {
- if (colCount() == std::numeric_limits<ColIndex>::max())
- mathic::reportError("Too many columns in SparseMatrix.");
- ++mColCount;
- return mColCount - 1;
- }
-
- void appendRowWithModulus(std::vector<uint64> const& v, Scalar modulus);
-
- void appendRow(std::vector<uint64> const& v, ColIndex leadCol = 0);
-
- void appendRowWithModulusNormalized(std::vector<uint64> const& v, Scalar modulus);
-
- // Returns true if the row was non-zero. Otherwise the row was not
- // appended.
- bool appendRowWithModulusIfNonZero(std::vector<uint64> const& v, Scalar modulus);
-
-
- /// Replaces all column indices i with colMap[i].
- void applyColumnMap(std::vector<ColIndex> colMap);
-
- /// Let poly be the dot product of colMonomials and the given row.
- void rowToPolynomial
- (RowIndex row, std::vector<monomial> colMonomials, Poly& poly);
-
- /// Reorders the rows so that the index of the leading column in
- /// each row is weakly increasing going from top to bottom. Quite
- /// slow and it makes a copy internally.
- void sortRowsByIncreasingPivots();
-
private:
- void operator==(const SparseMatrix&); // not available
- friend class ConstRowIterator;
-
-
SparseMatrix(const SparseMatrix&); // not available
void operator=(const SparseMatrix&); // not available
- ColIndex indexAtOffset(size_t offset) const {return mColIndices[offset];}
- Scalar scalarAtOffset(size_t offset) const {return mEntries[offset];}
+ void growEntryCapacity();
- void growEntryCapacity() {
- MATHICGB_ASSERT(mColIndices.size() == mEntries.size());
- MATHICGB_ASSERT(mColIndices.capacity() == mEntries.capacity());
+ /// Contains information about a row in the matrix.
+ struct Row {
+ Row(): mScalarsBegin(0), mScalarsEnd(0), mIndicesBegin(0), mIndicesEnd(0) {}
- const size_t initialCapacity = 1 << 16;
- const size_t growthFactor = 2;
- const size_t newCapacity =
- mEntries.empty() ? initialCapacity : mEntries.capacity() * growthFactor;
- reserveEntries(newCapacity);
+ Scalar* mScalarsBegin;
+ Scalar* mScalarsEnd;
+ ColIndex* mIndicesBegin;
+ ColIndex* mIndicesEnd;
- MATHICGB_ASSERT(mColIndices.size() == mEntries.size());
- MATHICGB_ASSERT(mColIndices.capacity() == newCapacity);
- MATHICGB_ASSERT(mEntries.capacity() == newCapacity);
- }
+ bool empty() const {return mIndicesBegin == mIndicesEnd;}
+ ColIndex size() const {
+ return static_cast<ColIndex>(std::distance(mIndicesBegin, mIndicesEnd));
+ }
+ };
/// We need a RawVector here to tie the checks for the need to reallocate
/// together between mColIndices and mEntries. We only need to check
@@ -360,7 +285,6 @@ private:
/// causes different compiler inlining decisions.
RawVector<Scalar> mEntries;
RawVector<ColIndex> mColIndices;
-
std::vector<Row> mRows;
ColIndex mColCount;
--
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/debian-science/packages/mathicgb.git
More information about the debian-science-commits
mailing list