[mathicgb] 157/393: F4-26 now has support for top/bottom split after left/right bottom, though the implementation is slow so it is not done by default.
Doug Torrance
dtorrance-guest at moszumanska.debian.org
Fri Apr 3 15:58:52 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 74b82b0d476a2ae6444365b6f0094958f7f5e3ee
Author: Bjarke Hammersholt Roune <bjarkehr.code at gmail.com>
Date: Tue Feb 5 16:47:07 2013 +0100
F4-26 now has support for top/bottom split after left/right bottom, though the implementation is slow so it is not done by default.
---
src/mathicgb/F4MatrixBuilder2.cpp | 185 +++++++++++++++++++++++++++-----------
1 file changed, 131 insertions(+), 54 deletions(-)
diff --git a/src/mathicgb/F4MatrixBuilder2.cpp b/src/mathicgb/F4MatrixBuilder2.cpp
index 3c0ad49..0d5fc0a 100755
--- a/src/mathicgb/F4MatrixBuilder2.cpp
+++ b/src/mathicgb/F4MatrixBuilder2.cpp
@@ -99,51 +99,6 @@ private:
std::vector<InternalRow> mRows;
};
-void toSparseMatrix(const F4MatrixBuilder2::F4PreBlock& block, SparseMatrix& matrix) {
- typedef F4MatrixBuilder2::F4PreBlock F4PreBlock;
- const auto rowCount = block.rowCount();
- for (F4PreBlock::RowIndex r = 0; r < rowCount; ++r) {
- const auto row = block.row(r);
- const auto entryCount = row.entryCount;
- const F4PreBlock::ColIndex* const indices = row.indices;
- MATHICGB_ASSERT(row.scalars == 0 || row.externalScalars == 0);
- if (row.scalars != 0) {
- const F4PreBlock::Scalar* const scalars = row.scalars;
- for (F4PreBlock::ColIndex col = 0; col < entryCount; ++col)
- matrix.appendEntry(indices[col], scalars[col]);
- } else if (row.externalScalars != 0) {
- const F4PreBlock::ExternalScalar* const scalars = row.externalScalars;
- for (F4PreBlock::ColIndex col = 0; col < entryCount; ++col) {
- const auto scalar = static_cast<F4PreBlock::Scalar>(scalars[col]);
- MATHICGB_ASSERT
- (static_cast<F4PreBlock::ExternalScalar>(scalar) == scalar);
- matrix.appendEntry(indices[col], scalar);
- }
- }
- matrix.rowDone();
- }
-}
-
-void splitTopBottom(
- const std::vector<SparseMatrix::RowIndex>& topRows,
- const std::vector<SparseMatrix::RowIndex>& bottomRows,
- SparseMatrix&& in,
- SparseMatrix& top,
- SparseMatrix& bottom
-) {
- top.clear();
- const auto rowCountTop = static_cast<SparseMatrix::RowIndex>(topRows.size());
- for (SparseMatrix::RowIndex toRow = 0; toRow < rowCountTop; ++toRow)
- top.appendRow(in, topRows[toRow]);
-
- bottom.clear();
- const auto rowCountBottom = static_cast<SparseMatrix::RowIndex>(bottomRows.size());
- for (SparseMatrix::RowIndex toRow = 0; toRow < rowCountBottom; ++toRow)
- top.appendRow(in, bottomRows[toRow]);
-
- in.clear();
-}
-
MATHICGB_NO_INLINE
std::pair<F4MatrixBuilder2::ColIndex, ConstMonomial>
F4MatrixBuilder2::findOrCreateColumn(
@@ -349,12 +304,24 @@ namespace {
}
void project(
- std::vector<F4MatrixBuilder2::F4PreBlock>&& preblocks,
+ const std::vector<F4MatrixBuilder2::F4PreBlock*>& preBlocks,
SparseMatrix& left,
SparseMatrix& right,
const PolyRing& ring
) const {
-
+ std::vector<std::pair<SparseMatrix::Scalar,F4MatrixBuilder2::F4PreBlock::Row>> from;
+ const auto end = preBlocks.end();
+ for (auto it = preBlocks.begin(); it != end; ++it) {
+ auto& block = **it;
+ const auto rowCount = block.rowCount();
+ for (SparseMatrix::RowIndex r = 0; r < rowCount; ++r) {
+ const auto row = block.row(r);
+ if (row.entryCount == 0)
+ continue;
+ from.emplace_back(std::make_pair(1, row));
+ }
+ }
+ project(from, left, right, ring);
}
void project(
@@ -432,6 +399,105 @@ namespace {
std::vector<monomial> mRightMonomials;
};
+ class TopBottomProjectionLate {
+ public:
+ TopBottomProjectionLate(
+ const SparseMatrix& left,
+ const SparseMatrix& right,
+ const SparseMatrix::ColIndex leftColCount,
+ const PolyRing& ring
+ ):
+ mModulus(static_cast<SparseMatrix::Scalar>(ring.charac()))
+ {
+ const auto noRow = std::numeric_limits<SparseMatrix::ColIndex>::max();
+ mTopRows.resize(leftColCount, std::make_pair(0, noRow));
+
+ MATHICGB_ASSERT(left.computeColCount() == leftColCount);
+ MATHICGB_ASSERT(left.rowCount() >= leftColCount);
+ MATHICGB_ASSERT(left.rowCount() == right.rowCount());
+
+ std::vector<SparseMatrix::ColIndex> topEntryCounts(leftColCount);
+
+ const auto rowCount = left.rowCount();
+ for (SparseMatrix::RowIndex row = 0; row < rowCount; ++row) {
+ const auto leftEntryCount = left.entryCountInRow(row);
+ const auto entryCount = leftEntryCount + right.entryCountInRow(row);
+ MATHICGB_ASSERT(entryCount >= leftEntryCount); // no overflow
+ if (entryCount == 0)
+ continue; // ignore zero rows
+ if (leftEntryCount == 0) {
+ mBottomRows.push_back(std::make_pair(1, row)); //can't be top/reducer
+ continue;
+ }
+ const auto lead = left.rowBegin(row).index();
+ if (mTopRows[lead].second != noRow && topEntryCounts[lead]<entryCount)
+ mBottomRows.push_back(std::make_pair(1, row)); //other reducer better
+ else {
+ if (mTopRows[lead].second != noRow)
+ mBottomRows.push_back(std::make_pair(1, mTopRows[lead].second));
+ topEntryCounts[lead] = entryCount;
+ mTopRows[lead].second = row; // do scalar .first later
+ }
+ }
+
+ const auto modulus = static_cast<SparseMatrix::Scalar>(ring.charac());
+ for (SparseMatrix::RowIndex r = 0; r < leftColCount; ++r) {
+ const auto row = mTopRows[r].second;
+ MATHICGB_ASSERT(row != noRow);
+ MATHICGB_ASSERT(left.entryCountInRow(row) > 0);
+ MATHICGB_ASSERT(left.rowBegin(row).index() == r);
+ MATHICGB_ASSERT(left.rowBegin(row).scalar() != 0);
+ MATHICGB_ASSERT(topEntryCounts[r] ==
+ left.entryCountInRow(row) + right.entryCountInRow(row));
+
+ const auto leadScalar = left.rowBegin(row).scalar();
+ mTopRows[r].first = leadScalar == 1 ? 1 : // 1 is the common case
+ modularInverse(leadScalar, modulus);
+ }
+
+#ifdef MATHICGB_DEBUG
+ for (SparseMatrix::RowIndex r = 0; r < mBottomRows.size(); ++r) {
+ const auto row = mBottomRows[r].second;
+ MATHICGB_ASSERT(
+ left.entryCountInRow(row) + right.entryCountInRow(row) > 0);
+ MATHICGB_ASSERT(mBottomRows[r].first == 1);
+ }
+#endif
+ }
+
+ void project(
+ SparseMatrix&& in,
+ SparseMatrix& top,
+ SparseMatrix& bottom
+ ) {
+ top.clear();
+ bottom.clear();
+
+ const auto rowCountTop =
+ static_cast<SparseMatrix::RowIndex>(mTopRows.size());
+ for (SparseMatrix::RowIndex toRow = 0; toRow < rowCountTop; ++toRow) {
+ top.appendRow(in, mTopRows[toRow].second);
+ if (mTopRows[toRow].first != 1)
+ top.multiplyRow(toRow, mTopRows[toRow].first, mModulus);
+ }
+
+ const auto rowCountBottom =
+ static_cast<SparseMatrix::RowIndex>(mBottomRows.size());
+ for (SparseMatrix::RowIndex toRow = 0; toRow < rowCountBottom; ++toRow) {
+ bottom.appendRow(in, mBottomRows[toRow].second);
+ if (mBottomRows[toRow].first != 1)
+ bottom.multiplyRow(toRow, mBottomRows[toRow].first, mModulus);
+ }
+
+ in.clear();
+ }
+
+ private:
+ const SparseMatrix::Scalar mModulus;
+ std::vector<std::pair<SparseMatrix::Scalar, SparseMatrix::RowIndex>> mTopRows;
+ std::vector<std::pair<SparseMatrix::Scalar, SparseMatrix::RowIndex>> mBottomRows;
+ };
+
class TopBottomProjection {
public:
TopBottomProjection(
@@ -478,9 +544,9 @@ namespace {
if (
reducer.entryCount != 0 && // already have a reducer and...
reducer.entryCount < row.entryCount // ...it is sparser/better
- ) {
+ )
mReduceeRows.push_back(std::make_pair(1, row));
- } else {
+ else {
if (reducer.entryCount != 0)
mReduceeRows.push_back(std::make_pair(1, reducer));
const auto leadScalar = row.scalars != 0 ? row.scalars[lead.first] :
@@ -612,15 +678,25 @@ void F4MatrixBuilder2::buildMatrixAndClear(QuadMatrix& quadMatrix) {
// Create projections
LeftRightProjection projection(mIsColumnToLeft, mMap);
mMap.clearNonConcurrent();
- TopBottomProjection topBottom(blocks, projection, ring());
- // Project the pre-blocks into the matrix
+ if (true) {
+ TopBottomProjection topBottom(blocks, projection, ring());
+
+ // Project the pre-blocks into the matrix
+ projection.project(topBottom.reducerRows(), quadMatrix.topLeft, quadMatrix.topRight, ring());
+ projection.project(topBottom.reduceeRows(), quadMatrix.bottomLeft, quadMatrix.bottomRight, ring());
+ } else {
+ SparseMatrix left;
+ SparseMatrix right;
+ projection.project(blocks, left, right, ring());
+ TopBottomProjectionLate topBottom(left, right, left.computeColCount(), ring());
+ topBottom.project(std::move(left), quadMatrix.topLeft, quadMatrix.bottomLeft);
+ topBottom.project(std::move(right), quadMatrix.topRight, quadMatrix.bottomRight);
+ }
+
quadMatrix.ring = &ring();
quadMatrix.leftColumnMonomials = projection.moveLeftMonomials();
quadMatrix.rightColumnMonomials = projection.moveRightMonomials();
- projection.project(topBottom.reducerRows(), quadMatrix.topLeft, quadMatrix.topRight, ring());
- projection.project(topBottom.reduceeRows(), quadMatrix.bottomLeft, quadMatrix.bottomRight, ring());
-
threadData.clear();
#ifdef MATHICGB_DEBUG
@@ -632,6 +708,7 @@ void F4MatrixBuilder2::buildMatrixAndClear(QuadMatrix& quadMatrix) {
}
}
for (RowIndex row = 0; row < quadMatrix.topLeft.rowCount(); ++row) {
+ MATHICGB_ASSERT(quadMatrix.topLeft.entryCountInRow(row) > 0);
MATHICGB_ASSERT(quadMatrix.topLeft.leadCol(row) == row);
}
MATHICGB_ASSERT(quadMatrix.debugAssertValid());
--
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