[mathicgb] 110/393: Matrix construction now uses parallel_do instead of parallel_for, which allows to dynamically add new work items.

Doug Torrance dtorrance-guest at moszumanska.debian.org
Fri Apr 3 15:58:42 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 fb8ba47a2124b323f1011e6fff306f942f5df0f1
Author: Bjarke Hammersholt Roune <bjarkehr.code at gmail.com>
Date:   Tue Nov 13 21:17:45 2012 +0100

    Matrix construction now uses parallel_do instead of parallel_for, which allows to dynamically add new work items.
---
 src/mathicgb/F4MatrixBuilder.cpp | 119 ++++++++++++++++++++++-----------------
 src/mathicgb/F4MatrixBuilder.hpp |  44 ++++++++++-----
 2 files changed, 97 insertions(+), 66 deletions(-)

diff --git a/src/mathicgb/F4MatrixBuilder.cpp b/src/mathicgb/F4MatrixBuilder.cpp
index 53b8aeb..21282db 100755
--- a/src/mathicgb/F4MatrixBuilder.cpp
+++ b/src/mathicgb/F4MatrixBuilder.cpp
@@ -7,14 +7,15 @@ MATHICGB_NO_INLINE
 std::pair<QuadMatrixBuilder::LeftRightColIndex, ConstMonomial>
 F4MatrixBuilder::findOrCreateColumn(
   const const_monomial monoA,
-  const const_monomial monoB
+  const const_monomial monoB,
+  TaskFeeder& feeder
 ) {
   MATHICGB_ASSERT(!monoA.isNull());
   MATHICGB_ASSERT(!monoB.isNull());
   const auto col = ColReader(mMap).findProduct(monoA, monoB);
   if (col.first != 0)
     return std::make_pair(*col.first, col.second);
-  return createColumn(monoA, monoB);
+  return createColumn(monoA, monoB, feeder);
 }
 
 MATHICGB_INLINE
@@ -22,13 +23,14 @@ std::pair<QuadMatrixBuilder::LeftRightColIndex, ConstMonomial>
 F4MatrixBuilder::findOrCreateColumn(
   const const_monomial monoA,
   const const_monomial monoB,
-  const ColReader& colMap
+  const ColReader& colMap,
+  TaskFeeder& feeder
 ) {
   MATHICGB_ASSERT(!monoA.isNull());
   MATHICGB_ASSERT(!monoB.isNull());
   const auto col = colMap.findProduct(monoA, monoB);
   if (col.first == 0)
-    return findOrCreateColumn(monoA, monoB);
+    return findOrCreateColumn(monoA, monoB, feeder);
   return std::make_pair(*col.first, col.second);
 }
 
@@ -36,10 +38,11 @@ MATHICGB_NO_INLINE
 void F4MatrixBuilder::createTwoColumns(
   const const_monomial monoA1,
   const const_monomial monoA2,
-  const const_monomial monoB
+  const const_monomial monoB,
+  TaskFeeder& feeder
 ) {
-  createColumn(monoA1, monoB);
-  createColumn(monoA2, monoB);
+  createColumn(monoA1, monoB, feeder);
+  createColumn(monoA2, monoB, feeder);
 }
 
 F4MatrixBuilder::F4MatrixBuilder(
@@ -67,8 +70,10 @@ F4MatrixBuilder::F4MatrixBuilder(
     mathic::reportInternalError("F4MatrixBuilder: too large characteristic.");
 }
 
-void F4MatrixBuilder::addSPolynomialToMatrix
-(const Poly& polyA, const Poly& polyB) {
+void F4MatrixBuilder::addSPolynomialToMatrix(
+  const Poly& polyA,
+  const Poly& polyB
+) {
   MATHICGB_ASSERT(!polyA.isZero());
   MATHICGB_ASSERT(polyA.isMonic());
   MATHICGB_ASSERT(!polyB.isZero());
@@ -139,39 +144,39 @@ void F4MatrixBuilder::buildMatrixAndClear(QuadMatrix& matrix) {
     return make_unique<QuadMatrixBuilder>(
       ring(), mMap, mMonomialsLeft, mMonomialsRight, mBuilder.memoryQuantum()
     );
-  }); 
-
-  decltype(mTodo) currentTasks;
-  while (!mTodo.empty()) {
-    for (auto it = currentTasks.begin(); it != currentTasks.end(); ++it) {
-      MATHICGB_ASSERT(!it->multiply.isNull());
-      ring().freeMonomial(it->multiply);
-      MATHICGB_ASSERT(it->sPairMultiply.isNull() == (it->sPairPoly == 0));
-      if (!it->sPairMultiply.isNull())
-        ring().freeMonomial(it->sPairMultiply);
-    }
-    currentTasks.clear();
-    mTodo.swap(currentTasks);
+  });
+
+  tbb::parallel_do(mTodo.begin(), mTodo.end(),
+    [&](const RowTask& task, tbb::parallel_do_feeder<RowTask>& feeder)
+  {
+    QuadMatrixBuilder& builder = *builders.local();
+    MATHICGB_ASSERT(&builder != 0);
+    MATHICGB_ASSERT(ring().hashValid(task.multiply));
 
-    tbb::parallel_for(tbb::blocked_range<size_t>(0, currentTasks.size(), 1),
-      [&](const tbb::blocked_range<size_t>& range)
-      {for (auto it = range.begin(); it != range.end(); ++it)
+    if (task.addToTop) {
+      MATHICGB_ASSERT(task.sPairPoly == 0);
+      appendRowTop(task.multiply, *task.poly, builder, feeder);
+    } else
+      appendRowBottom(task, builder, feeder);
     {
-      const size_t taskIndex = it;
-      QuadMatrixBuilder& builder = *builders.local();
-      MATHICGB_ASSERT(&builder != 0);
-
-      const RowTask task = currentTasks[taskIndex];
-      MATHICGB_ASSERT(ring().hashValid(task.multiply));
-
-      if (task.addToTop) {
-        MATHICGB_ASSERT(task.sPairPoly == 0);
-        appendRowTop(task.multiply, *task.poly, builder);
-      } else
-        appendRowBottom(task, builder);
-    }});
+      tbb::mutex::scoped_lock guard(mCreateColumnLock);
+      ring().freeMonomial(task.multiply);
+      if (!task.sPairMultiply.isNull())
+        ring().freeMonomial(task.sPairMultiply);
+    }
+  });
+  mTodo.clear();
+  /*
+  // Free the monomials from all the tasks
+  const auto todoEnd = mTodo.end();
+  for (auto it = mTodo.begin(); it != todoEnd; ++it) {
+    MATHICGB_ASSERT(!it->multiply.isNull());
+    ring().freeMonomial(it->multiply);
+    MATHICGB_ASSERT(it->sPairMultiply.isNull() == (it->sPairPoly == 0));
+    if (!it->sPairMultiply.isNull())
+      ring().freeMonomial(it->sPairMultiply);
   }
-
+*/
   if (builders.empty()) {
     matrix = QuadMatrix();
     matrix.ring = &ring();
@@ -219,7 +224,8 @@ void F4MatrixBuilder::buildMatrixAndClear(QuadMatrix& matrix) {
 std::pair<F4MatrixBuilder::LeftRightColIndex, ConstMonomial>
 F4MatrixBuilder::createColumn(
   const const_monomial monoA,
-  const const_monomial monoB
+  const const_monomial monoB,
+  TaskFeeder& feeder
 ) {
   MATHICGB_ASSERT(!monoA.isNull());
   MATHICGB_ASSERT(!monoB.isNull());
@@ -247,7 +253,7 @@ F4MatrixBuilder::createColumn(
     ring().monomialDivideToNegative
       (mTmp, task.poly->getLeadMonomial(), task.multiply);
     MATHICGB_ASSERT(ring().hashValid(task.multiply));
-    mTodo.push_back(task);
+    feeder.add(task);
   }
 
   // Create the new left or right column
@@ -267,7 +273,8 @@ void F4MatrixBuilder::appendRowBottom(
   const bool negate,
   const Poly::const_iterator begin,
   const Poly::const_iterator end,
-  QuadMatrixBuilder& builder
+  QuadMatrixBuilder& builder,
+  TaskFeeder& feeder
 ) {
   // todo: eliminate the code-duplication between here and appendRowTop.
   MATHICGB_ASSERT(!multiple.isNull());
@@ -282,7 +289,7 @@ updateReader:
   for (; it != end; ++it) {
     const auto col = reader.findProduct(it.getMonomial(), multiple);
     if (col.first == 0) {
-      createColumn(it.getMonomial(), multiple);
+      createColumn(it.getMonomial(), multiple, feeder);
       goto updateReader;
     }
 
@@ -299,7 +306,8 @@ updateReader:
 void F4MatrixBuilder::appendRowTop(
   const const_monomial multiple,
   const Poly& poly,
-  QuadMatrixBuilder& builder
+  QuadMatrixBuilder& builder,
+  TaskFeeder& feeder
 ) {
   MATHICGB_ASSERT(!multiple.isNull());
   MATHICGB_ASSERT(&poly != 0);
@@ -309,10 +317,12 @@ void F4MatrixBuilder::appendRowTop(
   const auto end = poly.end();
   if ((std::distance(it, end) % 2) == 1) {
     ColReader reader(mMap);
-    const auto col = findOrCreateColumn(it.getMonomial(), multiple, reader);
+    const auto col = findOrCreateColumn
+      (it.getMonomial(), multiple, reader, feeder);
 	MATHICGB_ASSERT(it.getCoefficient() < std::numeric_limits<Scalar>::max());
     MATHICGB_ASSERT(it.getCoefficient());
-    builder.appendEntryTop(col.first, static_cast<Scalar>(it.getCoefficient()));
+    builder.appendEntryTop
+      (col.first, static_cast<Scalar>(it.getCoefficient()));
     ++it;
   }
 updateReader:
@@ -333,7 +343,7 @@ updateReader:
 
     const auto colPair = colMap.findTwoProducts(mono1, mono2, multiple);
     if (colPair.first == 0 || colPair.second == 0) {
-      createTwoColumns(mono1, mono2, multiple);
+      createTwoColumns(mono1, mono2, multiple, feeder);
       goto updateReader;
     }
 
@@ -346,7 +356,8 @@ updateReader:
 
 void F4MatrixBuilder::appendRowBottom(
   const RowTask& task,
-  QuadMatrixBuilder& builder
+  QuadMatrixBuilder& builder,
+  TaskFeeder& feeder
 ) {
   MATHICGB_ASSERT(!task.addToTop);
   MATHICGB_ASSERT(!task.poly->isZero());
@@ -356,7 +367,7 @@ void F4MatrixBuilder::appendRowBottom(
   const Poly::const_iterator endA = task.poly->end();
 
   if (task.sPairPoly == 0) {
-    appendRowBottom(task.multiply, false, itA, endA, builder);
+    appendRowBottom(task.multiply, false, itA, endA, builder, feeder);
     return;
   }
 
@@ -380,18 +391,20 @@ void F4MatrixBuilder::appendRowBottom(
     // if you decide not to call that function in case
     // (itA == itA && itB == endB) then you need to do that yourself.
     if (itB == endB) {
-      appendRowBottom(mulA, false, itA, endA, builder);
+      appendRowBottom(mulA, false, itA, endA, builder, feeder);
       break;
     }
     if (itA == endA) {
-      appendRowBottom(mulB, true, itB, endB, builder);
+      appendRowBottom(mulB, true, itB, endB, builder, feeder);
       break;
     }
 
     coefficient coeff = 0;
     LeftRightColIndex col;
-    const auto colA = findOrCreateColumn(itA.getMonomial(), mulA, colMap);
-    const auto colB = findOrCreateColumn(itB.getMonomial(), mulB, colMap);
+    const auto colA = findOrCreateColumn
+      (itA.getMonomial(), mulA, colMap, feeder);
+    const auto colB = findOrCreateColumn
+      (itB.getMonomial(), mulB, colMap, feeder);
     const auto cmp = ring().monomialCompare(colA.second, colB.second);
     //const auto cmp = ring().monomialCompare
     //  (builder.monomialOfCol(colA), builder.monomialOfCol(colB));
diff --git a/src/mathicgb/F4MatrixBuilder.hpp b/src/mathicgb/F4MatrixBuilder.hpp
index ff77187..dc2c65f 100755
--- a/src/mathicgb/F4MatrixBuilder.hpp
+++ b/src/mathicgb/F4MatrixBuilder.hpp
@@ -71,13 +71,6 @@ public:
 private:
   typedef const MonomialMap<LeftRightColIndex>::Reader ColReader;
 
-  /** Creates a column with monomial label x and schedules a new row to
-    reduce that column if possible. Here x is monoA if monoB is
-    null and otherwise x is the product of monoA and monoB. */
-  MATHICGB_NO_INLINE
-  std::pair<LeftRightColIndex, ConstMonomial>
-  createColumn(const_monomial monoA, const_monomial monoB);
-
   /// Represents the task of adding a row to the matrix. If sPairPoly is null
   /// then the row to add is multiply * poly. Otherwise, the row to add is
   ///   multiply * poly - sPairMultiply * sPairPoly
@@ -89,37 +82,62 @@ private:
     const Poly* sPairPoly;
     monomial sPairMultiply;
   };
+  typedef tbb::parallel_do_feeder<RowTask> TaskFeeder;
+
+  /// Creates a column with monomial label x and schedules a new row to
+  /// reduce that column if possible. Here x is monoA if monoB is
+  /// null and otherwise x is the product of monoA and monoB.
+  MATHICGB_NO_INLINE
+  std::pair<LeftRightColIndex, ConstMonomial>
+  createColumn(
+    const_monomial monoA,
+    const_monomial monoB,
+    TaskFeeder& feeder
+  );
 
   void appendRowTop(
     const_monomial multiple,
     const Poly& poly,
-    QuadMatrixBuilder& builder);
-  void appendRowBottom(const RowTask& task, QuadMatrixBuilder& builder);
+    QuadMatrixBuilder& builder,
+    TaskFeeder& feeder
+  );
+  void appendRowBottom(
+    const RowTask& task,
+    QuadMatrixBuilder& builder,
+    TaskFeeder& feeder
+  );
   void appendRowBottom(
     const_monomial multiple,
     bool negate,
     Poly::const_iterator begin,
     Poly::const_iterator end,
-    QuadMatrixBuilder& builder
+    QuadMatrixBuilder& builder,
+    TaskFeeder& feeder
   );
 
   MATHICGB_NO_INLINE
   std::pair<QuadMatrixBuilder::LeftRightColIndex, ConstMonomial>
-  findOrCreateColumn(const_monomial monoA, const_monomial monoB);
+  findOrCreateColumn(
+    const_monomial monoA,
+    const_monomial monoB,
+    TaskFeeder& feeder
+  );
   
   MATHICGB_INLINE
   std::pair<QuadMatrixBuilder::LeftRightColIndex, ConstMonomial>
   findOrCreateColumn(
     const_monomial monoA,
     const_monomial monoB,
-    const ColReader& colMap
+    const ColReader& colMap,
+    TaskFeeder& feeder
   );
 
   MATHICGB_NO_INLINE
   void createTwoColumns(
     const const_monomial monoA1,
     const const_monomial monoA2,
-    const const_monomial monoB
+    const const_monomial monoB,
+    TaskFeeder& feeder
   );
 
   tbb::mutex mCreateColumnLock;

-- 
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