[mathicgb] 360/393: Moved the implementation and even declaration of all reducers out of their header files. Registration of all the reduers now happens in a decentralized fashion in each reducer's .cpp file. Reducer.cpp no longer takes so long to compile.

Doug Torrance dtorrance-guest at moszumanska.debian.org
Fri Apr 3 15:59: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 6b7e094228251adc82a7da36d592c4d051d104a4
Author: Bjarke Hammersholt Roune <bjarkehr.code at gmail.com>
Date:   Fri Sep 6 12:41:41 2013 +0200

    Moved the implementation and even declaration of all reducers out of their header files. Registration of all the reduers now happens in a decentralized fashion in each reducer's .cpp file. Reducer.cpp no longer takes so long to compile.
---
 Makefile.am                                        |  21 +-
 build/vs12/mathicgb-lib/mathicgb-lib.vcxproj       |   5 +
 .../vs12/mathicgb-lib/mathicgb-lib.vcxproj.filters |  15 ++
 src/cli/GBAction.cpp                               |  11 +-
 src/mathicgb/F4Reducer.cpp                         |  97 +++++++
 src/mathicgb/F4Reducer.hpp                         |  78 ++----
 src/mathicgb/Reducer.cpp                           | 133 +--------
 .../{ReducerDedup.hpp => ReducerDedup.cpp}         |  32 ++-
 src/mathicgb/ReducerDedup.hpp                      | 181 +------------
 src/mathicgb/{ReducerHash.hpp => ReducerHash.cpp}  |  29 +-
 src/mathicgb/ReducerHash.hpp                       | 139 +---------
 .../{ReducerHashPack.hpp => ReducerHashPack.cpp}   |  30 ++-
 src/mathicgb/ReducerHashPack.hpp                   | 229 +---------------
 .../{ReducerNoDedup.hpp => ReducerNoDedup.cpp}     |  32 ++-
 src/mathicgb/ReducerNoDedup.hpp                    | 174 +-----------
 .../{ReducerPackDedup.hpp => ReducerPackDedup.cpp} |  31 ++-
 src/mathicgb/ReducerPackDedup.hpp                  | 297 +--------------------
 17 files changed, 320 insertions(+), 1214 deletions(-)

diff --git a/Makefile.am b/Makefile.am
index 688a88f..b402fe6 100755
--- a/Makefile.am
+++ b/Makefile.am
@@ -29,15 +29,18 @@ libmathicgb_la_SOURCES = src/mathicgb/ReducerPack.hpp				  \
   src/mathicgb/PolyHashTable.cpp src/mathicgb/PolyHashTable.hpp		  \
   src/mathicgb/PolyRing.cpp src/mathicgb/PolyRing.hpp				  \
   src/mathicgb/Reducer.cpp src/mathicgb/Reducer.hpp					  \
-  src/mathicgb/ReducerDedup.hpp src/mathicgb/ReducerHash.hpp		  \
-  src/mathicgb/ReducerHashPack.hpp src/mathicgb/ReducerHelper.hpp	  \
-  src/mathicgb/ReducerNoDedup.hpp src/mathicgb/ReducerPackDedup.hpp	  \
-  src/mathicgb/SignatureGB.cpp src/mathicgb/SignatureGB.hpp			  \
-  src/mathicgb/SigSPairs.cpp src/mathicgb/SigSPairs.hpp				  \
-  src/mathicgb/SPairs.cpp src/mathicgb/SPairs.hpp					  \
-  src/mathicgb/stdinc.h src/mathicgb/SigSPairQueue.hpp				  \
-  src/mathicgb/SigSPairQueue.cpp src/mathicgb/SparseMatrix.hpp		  \
-  src/mathicgb/SparseMatrix.cpp src/mathicgb/QuadMatrixBuilder.hpp	  \
+  src/mathicgb/ReducerDedup.hpp src/mathicgb/ReducerDedup.cpp		  \
+  src/mathicgb/ReducerHash.hpp src/mathicgb/ReducerHash.cpp			  \
+  src/mathicgb/ReducerHashPack.hpp src/mathicgb/ReducerHashPack.cpp	  \
+  src/mathicgb/ReducerHelper.hpp src/mathicgb/ReducerNoDedup.hpp	  \
+  src/mathicgb/ReducerNoDedup.cpp src/mathicgb/ReducerPackDedup.hpp	  \
+  src/mathicgb/ReducerPackDedup.cpp src/mathicgb/SignatureGB.cpp	  \
+  src/mathicgb/SignatureGB.hpp src/mathicgb/SigSPairs.cpp			  \
+  src/mathicgb/SigSPairs.hpp src/mathicgb/SPairs.cpp				  \
+  src/mathicgb/SPairs.hpp src/mathicgb/stdinc.h						  \
+  src/mathicgb/SigSPairQueue.hpp src/mathicgb/SigSPairQueue.cpp		  \
+  src/mathicgb/SparseMatrix.hpp src/mathicgb/SparseMatrix.cpp		  \
+  src/mathicgb/QuadMatrixBuilder.hpp								  \
   src/mathicgb/QuadMatrixBuilder.cpp src/mathicgb/TypicalReducer.cpp  \
   src/mathicgb/TypicalReducer.hpp src/mathicgb/F4Reducer.hpp		  \
   src/mathicgb/F4Reducer.cpp src/mathicgb/F4MatrixBuilder.hpp		  \
diff --git a/build/vs12/mathicgb-lib/mathicgb-lib.vcxproj b/build/vs12/mathicgb-lib/mathicgb-lib.vcxproj
index ec8b218..00fd5ad 100755
--- a/build/vs12/mathicgb-lib/mathicgb-lib.vcxproj
+++ b/build/vs12/mathicgb-lib/mathicgb-lib.vcxproj
@@ -463,7 +463,12 @@
     <ClCompile Include="..\..\..\src\mathicgb\QuadMatrix.cpp" />
     <ClCompile Include="..\..\..\src\mathicgb\QuadMatrixBuilder.cpp" />
     <ClCompile Include="..\..\..\src\mathicgb\Reducer.cpp" />
+    <ClCompile Include="..\..\..\src\mathicgb\ReducerDedup.cpp" />
+    <ClCompile Include="..\..\..\src\mathicgb\ReducerHash.cpp" />
+    <ClCompile Include="..\..\..\src\mathicgb\ReducerHashPack.cpp" />
+    <ClCompile Include="..\..\..\src\mathicgb\ReducerNoDedup.cpp" />
     <ClCompile Include="..\..\..\src\mathicgb\ReducerPack.cpp" />
+    <ClCompile Include="..\..\..\src\mathicgb\ReducerPackDedup.cpp" />
     <ClCompile Include="..\..\..\src\mathicgb\Scanner.cpp" />
     <ClCompile Include="..\..\..\src\mathicgb\SignatureGB.cpp" />
     <ClCompile Include="..\..\..\src\mathicgb\SigPolyBasis.cpp" />
diff --git a/build/vs12/mathicgb-lib/mathicgb-lib.vcxproj.filters b/build/vs12/mathicgb-lib/mathicgb-lib.vcxproj.filters
index b6797d1..33306c9 100755
--- a/build/vs12/mathicgb-lib/mathicgb-lib.vcxproj.filters
+++ b/build/vs12/mathicgb-lib/mathicgb-lib.vcxproj.filters
@@ -110,6 +110,21 @@
     <ClCompile Include="..\..\..\src\mathicgb\ReducerPack.cpp">
       <Filter>Source Files</Filter>
     </ClCompile>
+    <ClCompile Include="..\..\..\src\mathicgb\ReducerNoDedup.cpp">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\..\src\mathicgb\ReducerPackDedup.cpp">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\..\src\mathicgb\ReducerDedup.cpp">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\..\src\mathicgb\ReducerHash.cpp">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\..\src\mathicgb\ReducerHashPack.cpp">
+      <Filter>Source Files</Filter>
+    </ClCompile>
   </ItemGroup>
   <ItemGroup>
     <ClInclude Include="..\..\..\src\mathicgb\ChainedHashTable.hpp">
diff --git a/src/cli/GBAction.cpp b/src/cli/GBAction.cpp
index 8715d88..ee5a2b4 100755
--- a/src/cli/GBAction.cpp
+++ b/src/cli/GBAction.cpp
@@ -74,11 +74,12 @@ void GBAction::performAction() {
   ) {
     reducer = Reducer::makeReducer(reducerType, ring);
   } else {
-    const auto type = reducerType == Reducer::Reducer_F4_Old ?
-      F4Reducer::OldType : F4Reducer::NewType;
-    auto f4Reducer = make_unique<F4Reducer>(ring, type);
-    if (mMinMatrixToStore.value() > 0)
-      f4Reducer->writeMatricesTo(projectName, mMinMatrixToStore);
+    auto f4Reducer = makeF4Reducer(
+      ring,
+      reducerType == Reducer::Reducer_F4_Old,
+      mMinMatrixToStore.value() > 0 ? projectName : "",
+      mMinMatrixToStore
+    );     
     reducer = std::move(f4Reducer);
   }
 
diff --git a/src/mathicgb/F4Reducer.cpp b/src/mathicgb/F4Reducer.cpp
index bf26ef4..f73b464 100755
--- a/src/mathicgb/F4Reducer.cpp
+++ b/src/mathicgb/F4Reducer.cpp
@@ -43,8 +43,78 @@ MATHICGB_DEFINE_LOG_ALIAS(
   "F4MatReduceTop,F4RedBottomRight"
 );
 
+#include "Reducer.hpp"
+#include "PolyRing.hpp"
+#include <string>
+
 MATHICGB_NAMESPACE_BEGIN
 
+void f4ReducerDependency() {}
+
+class QuadMatrix;
+
+class F4Reducer : public Reducer {
+public:
+  enum Type {
+    OldType,
+    NewType
+  };
+
+  F4Reducer(const PolyRing& ring, Type type);
+
+  virtual unsigned int preferredSetSize() const;
+
+  /// Store all future matrices to file-1.mat, file-2.mat and so on.
+  /// Matrices with less than minEntries non-zero entries are not stored.
+  /// If file is an empty string then no matrices are stored. If this method
+  /// is never called then no matrices are stored.
+  void writeMatricesTo(std::string file, size_t minEntries);
+
+  virtual std::unique_ptr<Poly> classicReduce
+    (const Poly& poly, const PolyBasis& basis);
+
+  virtual std::unique_ptr<Poly> classicTailReduce
+    (const Poly& poly, const PolyBasis& basis);
+
+  virtual std::unique_ptr<Poly> classicReduceSPoly
+    (const Poly& a, const Poly& b, const PolyBasis& basis);
+
+  virtual void classicReduceSPolySet(
+    std::vector<std::pair<size_t, size_t> >& spairs,
+    const PolyBasis& basis,
+    std::vector<std::unique_ptr<Poly> >& reducedOut
+  );
+
+  virtual void classicReducePolySet(
+    const std::vector<std::unique_ptr<Poly> >& polys,
+    const PolyBasis& basis,
+    std::vector<std::unique_ptr<Poly> >& reducedOut
+  );
+
+  virtual std::unique_ptr<Poly> regularReduce(
+    const_monomial sig,
+    const_monomial multiple,
+    size_t basisElement,
+    const SigPolyBasis& basis
+  );
+
+  virtual void setMemoryQuantum(size_t quantum);
+
+  virtual std::string description() const;
+  virtual size_t getMemoryUse() const;
+
+private:
+  void saveMatrix(const QuadMatrix& matrix);
+
+  Type mType;
+  std::unique_ptr<Reducer> mFallback;
+  const PolyRing& mRing;
+  size_t mMemoryQuantum;
+  std::string mStoreToFile; /// stem of file names to save matrices to
+  size_t mMinEntryCountForStore; /// don't save matrices with fewer entries
+  size_t mMatrixSaveCount; // how many matrices have been saved
+};
+
 F4Reducer::F4Reducer(const PolyRing& ring, Type type):
   mType(type),
   mFallback(Reducer::makeReducer(Reducer::Reducer_Geobucket_Hashed, ring)),
@@ -268,4 +338,31 @@ void F4Reducer::saveMatrix(const QuadMatrix& matrix) {
   fclose(file);
 }
 
+std::unique_ptr<Reducer> makeF4Reducer(
+ const PolyRing& ring,
+ bool oldType,
+ std::string file,
+ size_t minEntries
+) {
+  auto reducer = oldType ?
+    make_unique<F4Reducer>(ring, F4Reducer::OldType) :
+    make_unique<F4Reducer>(ring, F4Reducer::NewType);
+  reducer->writeMatricesTo(file, minEntries);
+  return std::move(reducer);
+}
+
+Reducer::Registration r19(
+  "F4Old",
+  Reducer::Reducer_F4_Old,
+  [](const PolyRing& ring) -> std::unique_ptr<Reducer> {
+    return make_unique<F4Reducer>(ring, F4Reducer::OldType);
+  }
+);
+
+MATHICGB_REGISTER_REDUCER(
+  "F4New",
+  Reducer_F4_New,
+  (make_unique<F4Reducer>(ring, F4Reducer::NewType))
+);
+
 MATHICGB_NAMESPACE_END
diff --git a/src/mathicgb/F4Reducer.hpp b/src/mathicgb/F4Reducer.hpp
index 8915a6d..18d1c4c 100755
--- a/src/mathicgb/F4Reducer.hpp
+++ b/src/mathicgb/F4Reducer.hpp
@@ -3,75 +3,27 @@
 #ifndef MATHICGB_F4_REDUCER_GUARD
 #define MATHICGB_F4_REDUCER_GUARD
 
-#include "Reducer.hpp"
-#include "PolyRing.hpp"
 #include <string>
 
 MATHICGB_NAMESPACE_BEGIN
 
-class QuadMatrix;
+class Reducer;
+class PolyRing;
 
-class F4Reducer : public Reducer {
-public:
-  enum Type {
-    OldType,
-    NewType
-  };
+/// Create an F4 reducer with extra parameters for writing out the matrix.
+/// Set file to "" to disable writing of matrices.
+std::unique_ptr<Reducer> makeF4Reducer(
+ const PolyRing& ring,
+ bool oldType,
+ std::string file,
+ size_t minEntries
+);
 
-  F4Reducer(const PolyRing& ring, Type type);
-
-  virtual unsigned int preferredSetSize() const;
-
-  /// Store all future matrices to file-1.mat, file-2.mat and so on.
-  /// Matrices with less than minEntries non-zero entries are not stored.
-  /// If file is an empty string then no matrices are stored. If this method
-  /// is never called then no matrices are stored.
-  void writeMatricesTo(std::string file, size_t minEntries);
-
-  virtual std::unique_ptr<Poly> classicReduce
-    (const Poly& poly, const PolyBasis& basis);
-
-  virtual std::unique_ptr<Poly> classicTailReduce
-    (const Poly& poly, const PolyBasis& basis);
-
-  virtual std::unique_ptr<Poly> classicReduceSPoly
-    (const Poly& a, const Poly& b, const PolyBasis& basis);
-
-  virtual void classicReduceSPolySet(
-    std::vector<std::pair<size_t, size_t> >& spairs,
-    const PolyBasis& basis,
-    std::vector<std::unique_ptr<Poly> >& reducedOut
-  );
-
-  virtual void classicReducePolySet(
-    const std::vector<std::unique_ptr<Poly> >& polys,
-    const PolyBasis& basis,
-    std::vector<std::unique_ptr<Poly> >& reducedOut
-  );
-
-  virtual std::unique_ptr<Poly> regularReduce(
-    const_monomial sig,
-    const_monomial multiple,
-    size_t basisElement,
-    const SigPolyBasis& basis
-  );
-
-  virtual void setMemoryQuantum(size_t quantum);
-
-  virtual std::string description() const;
-  virtual size_t getMemoryUse() const;
-
-private:
-  void saveMatrix(const QuadMatrix& matrix);
-
-  Type mType;
-  std::unique_ptr<Reducer> mFallback;
-  const PolyRing& mRing;
-  size_t mMemoryQuantum;
-  std::string mStoreToFile; /// stem of file names to save matrices to
-  size_t mMinEntryCountForStore; /// don't save matrices with fewer entries
-  size_t mMatrixSaveCount; // how many matrices have been saved
-};
+// This translation unit has to expose something that is needed elsewhere.
+// Otherwise, the compiler will think it is not needed and exclude the
+// whole thing, despite there being important global objects in the .cpp file.
+void f4ReducerDependency();
 
 MATHICGB_NAMESPACE_END
+
 #endif
diff --git a/src/mathicgb/Reducer.cpp b/src/mathicgb/Reducer.cpp
index 6e336c7..4e2ee1e 100755
--- a/src/mathicgb/Reducer.cpp
+++ b/src/mathicgb/Reducer.cpp
@@ -4,8 +4,8 @@
 #include "Reducer.hpp"
 
 #include "ReducerPack.hpp"
-#include "ReducerPackDedup.hpp"
 #include "ReducerNoDedup.hpp"
+#include "ReducerPackDedup.hpp"
 #include "ReducerDedup.hpp"
 #include "ReducerHash.hpp"
 #include "ReducerHashPack.hpp"
@@ -25,6 +25,12 @@ MATHICGB_NAMESPACE_BEGIN
 // and then not include it in the library. This was wonderful to diagnose.
 void dummyLinkerFix() {
   reducerPackDependency();
+  reducerNoDedupDependency();
+  reducerPackDedupDependency();
+  reducerDedupDependency();
+  reducerHashDependency();
+  reducerHashPackDependency();
+  f4ReducerDependency();
 }
 
 Reducer::~Reducer() {
@@ -52,131 +58,6 @@ Reducer::Registration::Registration(
   reducerTypes().push_back(this);
 }
 
-Reducer::Registration r1(
-  "TourNoDedup",
-  Reducer::Reducer_TourTree_NoDedup,
-  [](const PolyRing& ring) -> std::unique_ptr<Reducer> {
-    return make_unique<ReducerNoDedup<mic::TourTree>>(ring);
-  }
-);
-
-Reducer::Registration r2(
-  "TourDedup",
-  Reducer::Reducer_TourTree_Dedup,
-  [](const PolyRing& ring) -> std::unique_ptr<Reducer> {
-    return make_unique<ReducerDedup<mic::TourTree>>(ring);
-  }
-);
-Reducer::Registration r3(
-  "TourHash",
-  Reducer::Reducer_TourTree_Hashed,
-  [](const PolyRing& ring) -> std::unique_ptr<Reducer> {
-    return make_unique<ReducerHash<mic::TourTree>>(ring);
-  }
-);
- 
- 
-Reducer::Registration r5(
-  "TourDedupPack",
-  Reducer::Reducer_TourTree_Dedup_Packed,
-  [](const PolyRing& ring) -> std::unique_ptr<Reducer> {
-    return make_unique<ReducerPackDedup<mic::TourTree>>(ring);
-  }
-);
-  
-Reducer::Registration r6(
-  "TourHashPack",
-  Reducer::Reducer_TourTree_Hashed_Packed,
-  [](const PolyRing& ring) -> std::unique_ptr<Reducer> {
-    return make_unique<ReducerHashPack<mic::TourTree>>(ring);
-  }
-);
-
-Reducer::Registration r7(
-  "HeapNoDedup",
-  Reducer::Reducer_Heap_NoDedup,
-  [](const PolyRing& ring) -> std::unique_ptr<Reducer> {
-    return make_unique<ReducerNoDedup<mic::Heap>>(ring);
-  }
-);
-Reducer::Registration r8(
-  "HeapDedup",
-  Reducer::Reducer_Heap_Dedup,
-  [](const PolyRing& ring) -> std::unique_ptr<Reducer> {
-    return make_unique<ReducerDedup<mic::Heap>>(ring);
-  }
-);
- 
-Reducer::Registration r9(
-  "HeapHash",
-  Reducer::Reducer_Heap_Hashed,
-  [](const PolyRing& ring) -> std::unique_ptr<Reducer> {
-    return make_unique<ReducerHash<mic::Heap>>(ring);
-  }
-);
-Reducer::Registration r11(
-  "HeapDedupPack",
-  Reducer::Reducer_Heap_Dedup_Packed,
-  [](const PolyRing& ring) -> std::unique_ptr<Reducer> {
-    return make_unique<ReducerPackDedup<mic::Heap>>(ring);
-  }
-);
-Reducer::Registration r12(
-  "HeapHashPack",
-  Reducer::Reducer_Heap_Hashed_Packed,
-  [](const PolyRing& ring) -> std::unique_ptr<Reducer> {
-    return make_unique<ReducerHashPack<mic::Heap>>(ring);
-  }
-);
-Reducer::Registration r13(
-  "GeoNoDedup",
-  Reducer::Reducer_Geobucket_NoDedup,
-  [](const PolyRing& ring) -> std::unique_ptr<Reducer> {
-    return make_unique<ReducerNoDedup<mic::Geobucket>>(ring);
-  }
-);
-Reducer::Registration r14(
-  "GeoDedup",
-  Reducer::Reducer_Geobucket_Dedup,
-  [](const PolyRing& ring) -> std::unique_ptr<Reducer> {
-    return make_unique<ReducerDedup<mic::Geobucket>>(ring);
-  }
-);
-Reducer::Registration r15(
-  "GeoHash",
-  Reducer::Reducer_Geobucket_Hashed,
-  [](const PolyRing& ring) -> std::unique_ptr<Reducer> {
-    return make_unique<ReducerHash<mic::Geobucket>>(ring);
-  }
-);
-Reducer::Registration r17(
-  "GeoDedupPack",
-  Reducer::Reducer_Geobucket_Dedup_Packed,
-  [](const PolyRing& ring) -> std::unique_ptr<Reducer> {
-    return make_unique<ReducerPackDedup<mic::Geobucket>>(ring);
-  }
-);
-Reducer::Registration r18(
-  "GeoHashPack",
-  Reducer::Reducer_Geobucket_Hashed_Packed,
-  [](const PolyRing& ring) -> std::unique_ptr<Reducer> {
-    return make_unique<ReducerHashPack<mic::Geobucket>>(ring);
-  }
-);
-Reducer::Registration r19(
-  "F4Old",
-  Reducer::Reducer_F4_Old,
-  [](const PolyRing& ring) -> std::unique_ptr<Reducer> {
-    return make_unique<F4Reducer>(ring, F4Reducer::OldType);
-  }
-);
-
-MATHICGB_REGISTER_REDUCER(
-  "F4New",
-  Reducer_F4_New,
-  (make_unique<F4Reducer>(ring, F4Reducer::NewType))
-);
-
 std::unique_ptr<Reducer> Reducer::makeReducer(
   ReducerType type,
   PolyRing const& ring
diff --git a/src/mathicgb/ReducerDedup.hpp b/src/mathicgb/ReducerDedup.cpp
old mode 100755
new mode 100644
similarity index 86%
copy from src/mathicgb/ReducerDedup.hpp
copy to src/mathicgb/ReducerDedup.cpp
index d194266..9c59ef2
--- a/src/mathicgb/ReducerDedup.hpp
+++ b/src/mathicgb/ReducerDedup.cpp
@@ -1,7 +1,7 @@
 // MathicGB copyright 2012 all rights reserved. MathicGB comes with ABSOLUTELY
 // NO WARRANTY and is licensed as GPL v2.0 or later - see LICENSE.txt.
-#ifndef MATHICGB_REDUCER_DEDUP_GUARD
-#define MATHICGB_REDUCER_DEDUP_GUARD
+#include "stdinc.h"
+#include "ReducerDedup.hpp"
 
 #include "TypicalReducer.hpp"
 #include "ReducerHelper.hpp"
@@ -10,6 +10,8 @@
 
 MATHICGB_NAMESPACE_BEGIN
 
+void reducerDedupDependency() {}
+
 template<template<typename ConfigType> class Queue> class ReducerDedup;
 
 template<template<typename> class Queue>
@@ -182,5 +184,29 @@ size_t ReducerDedup<Q>::getMemoryUse() const
   return TypicalReducer::getMemoryUse() + mQueue.getMemoryUse();
 }
 
+
+Reducer::Registration r2(
+  "TourDedup",
+  Reducer::Reducer_TourTree_Dedup,
+  [](const PolyRing& ring) -> std::unique_ptr<Reducer> {
+    return make_unique<ReducerDedup<mic::TourTree>>(ring);
+  }
+);
+
+Reducer::Registration r8(
+  "HeapDedup",
+  Reducer::Reducer_Heap_Dedup,
+  [](const PolyRing& ring) -> std::unique_ptr<Reducer> {
+    return make_unique<ReducerDedup<mic::Heap>>(ring);
+  }
+);
+
+Reducer::Registration r14(
+  "GeoDedup",
+  Reducer::Reducer_Geobucket_Dedup,
+  [](const PolyRing& ring) -> std::unique_ptr<Reducer> {
+    return make_unique<ReducerDedup<mic::Geobucket>>(ring);
+  }
+);
+
 MATHICGB_NAMESPACE_END
-#endif
diff --git a/src/mathicgb/ReducerDedup.hpp b/src/mathicgb/ReducerDedup.hpp
index d194266..77cf603 100755
--- a/src/mathicgb/ReducerDedup.hpp
+++ b/src/mathicgb/ReducerDedup.hpp
@@ -3,184 +3,13 @@
 #ifndef MATHICGB_REDUCER_DEDUP_GUARD
 #define MATHICGB_REDUCER_DEDUP_GUARD
 
-#include "TypicalReducer.hpp"
-#include "ReducerHelper.hpp"
-#include <memtailor.h>
-#include <mathic.h>
-
 MATHICGB_NAMESPACE_BEGIN
 
-template<template<typename ConfigType> class Queue> class ReducerDedup;
-
-template<template<typename> class Queue>
-class ReducerDedup : public TypicalReducer {
-public:
-  ReducerDedup(const PolyRing& R);
-  virtual ~ReducerDedup();
-
-  virtual std::string description() const { 
-    return mQueue.getName() + "-dedup"; 
-  }
-
-  virtual void insertTail(const_term multiplier, const Poly *f);
-  virtual void insert(monomial multiplier, const Poly *f);
-
-  virtual bool leadTerm(const_term &result);
-  virtual void removeLeadTerm();
-
-  virtual size_t getMemoryUse() const;
-
-protected:
-  virtual void resetReducer();
-
-public:
-  // This Configuration is designed to work with
-  // mathic::TourTree, mathic::Heap, and mathic::Geobucket
-
-  class Configuration : public ReducerHelper::DedupConfiguration {
-  public:
-    typedef term Entry;
-    Configuration(const PolyRing& ring): DedupConfiguration(ring) {}
-    CompareResult compare(const Entry& a, const Entry& b) const {
-      return ring().monomialCompare(a.monom, b.monom);
-    }
-    Entry deduplicate(Entry a, Entry b) const {
-      // change a.coeff, and free b.monom
-      ring().coefficientAddTo(a.coeff, b.coeff);
-      ring().freeMonomial(b.monom);
-      return a;
-    }
-  };
-
-private:
-  class MonomialFree;
-  
-  const PolyRing& mRing;
-  term mLeadTerm;
-  bool mLeadTermKnown;
-  Queue<Configuration> mQueue;
-};
-
-template<template<typename> class Q>
-ReducerDedup<Q>::ReducerDedup(const PolyRing& ring):
-  mRing(ring),
-  mLeadTerm(0, mRing.allocMonomial()),
-  mLeadTermKnown(false),
-  mQueue(Configuration(ring)) {
-}
-
-template<template<typename> class Q>
-class ReducerDedup<Q>::MonomialFree
-{
-public:
-  MonomialFree(const PolyRing& ring): mRing(ring) {}
-
-  bool proceed(term entry)
-  {
-    mRing.freeMonomial(entry.monom);
-    return true;
-  }
-private:
-  const PolyRing& mRing;
-};
-
-template<template<typename> class Q>
-ReducerDedup<Q>::~ReducerDedup()
-{
-  resetReducer();
-  mRing.freeMonomial(mLeadTerm.monom);
-}
-
-///////////////////////////////////////
-// External interface routines ////////
-///////////////////////////////////////
-template<template<typename> class Q>
-void ReducerDedup<Q>::insertTail(const_term multiple, const Poly* poly)
-{
-  if (poly->nTerms() <= 1)
-    return;
-  mLeadTermKnown = false;
-
-  Poly::const_iterator i = poly->begin();
-  for (++i; i != poly->end(); ++i)
-    {
-      term t;
-      t.monom = mRing.allocMonomial();
-      mRing.monomialMult(multiple.monom, i.getMonomial(), t.monom);
-      mRing.coefficientMult(multiple.coeff, i.getCoefficient(), t.coeff);
-      mQueue.push(t);
-    }
-}
-
-template<template<typename> class Q>
-void ReducerDedup<Q>::insert(monomial multiple, const Poly* poly)
-{
-  if (poly->isZero())
-    return;
-  mLeadTermKnown = false;
-
-  for (Poly::const_iterator i = poly->begin(); i != poly->end(); ++i) {
-    term t(i.getCoefficient(), mRing.allocMonomial());
-    mRing.monomialMult(multiple, i.getMonomial(), t.monom);
-    mQueue.push(t);
-  }
-}
-
-template<template<typename> class Q>
-bool ReducerDedup<Q>::leadTerm(const_term& result)
-{
-  if (mLeadTermKnown) {
-    result = mLeadTerm;
-    return true;
-  }
-
-  do {
-    if (mQueue.empty())
-      return false;
-    mLeadTerm = mQueue.top();
-    mQueue.pop();
-    
-    while (true) {
-      if (mQueue.empty())
-        break;
-      
-      term entry = mQueue.top();
-      if (!mRing.monomialEQ(entry.monom, mLeadTerm.monom))
-        break;
-      mRing.coefficientAddTo(mLeadTerm.coeff, entry.coeff);
-      mRing.freeMonomial(entry.monom);
-      mQueue.pop();
-    }
-  } while (mRing.coefficientIsZero(mLeadTerm.coeff));
-
-  result = mLeadTerm;
-  mLeadTermKnown = true;
-  return true;
-}
-
-template<template<typename> class Q>
-void ReducerDedup<Q>::removeLeadTerm()
-{
-  if (!mLeadTermKnown) {
-    const_term dummy;
-    leadTerm(dummy);
-  }
-  mLeadTermKnown = false;
-}
-
-template<template<typename> class Q>
-void ReducerDedup<Q>::resetReducer()
-{
-  MonomialFree freeer(mRing);
-  mQueue.forAll(freeer);
-  mQueue.clear();
-}
-
-template<template<typename> class Q>
-size_t ReducerDedup<Q>::getMemoryUse() const
-{
-  return TypicalReducer::getMemoryUse() + mQueue.getMemoryUse();
-}
+// This translation unit has to expose something that is needed elsewhere.
+// Otherwise, the compiler will think it is not needed and exclude the
+// whole thing, despite there being important global objects in the .cpp file.
+void reducerDedupDependency();
 
 MATHICGB_NAMESPACE_END
+
 #endif
diff --git a/src/mathicgb/ReducerHash.hpp b/src/mathicgb/ReducerHash.cpp
old mode 100755
new mode 100644
similarity index 84%
copy from src/mathicgb/ReducerHash.hpp
copy to src/mathicgb/ReducerHash.cpp
index 1244ead..5a5304f
--- a/src/mathicgb/ReducerHash.hpp
+++ b/src/mathicgb/ReducerHash.cpp
@@ -1,7 +1,7 @@
 // MathicGB copyright 2012 all rights reserved. MathicGB comes with ABSOLUTELY
 // NO WARRANTY and is licensed as GPL v2.0 or later - see LICENSE.txt.
-#ifndef MATHICGB_REDUCER_HASH_GUARD
-#define MATHICGB_REDUCER_HASH_GUARD
+#include "stdinc.h"
+#include "ReducerHash.hpp"
 
 #include "TypicalReducer.hpp"
 #include "ReducerHelper.hpp"
@@ -11,6 +11,8 @@
 
 MATHICGB_NAMESPACE_BEGIN
 
+void reducerHashDependency() {}
+
 template<template<typename ConfigType> class Queue> class ReducerHash;
 
 template<template<typename> class Queue>
@@ -140,5 +142,26 @@ size_t ReducerHash<Q>::getMemoryUse() const
   return result;
 }
 
+Reducer::Registration r3(
+  "TourHash",
+  Reducer::Reducer_TourTree_Hashed,
+  [](const PolyRing& ring) -> std::unique_ptr<Reducer> {
+    return make_unique<ReducerHash<mic::TourTree>>(ring);
+  }
+);
+Reducer::Registration r9(
+  "HeapHash",
+  Reducer::Reducer_Heap_Hashed,
+  [](const PolyRing& ring) -> std::unique_ptr<Reducer> {
+    return make_unique<ReducerHash<mic::Heap>>(ring);
+  }
+);
+Reducer::Registration r15(
+  "GeoHash",
+  Reducer::Reducer_Geobucket_Hashed,
+  [](const PolyRing& ring) -> std::unique_ptr<Reducer> {
+    return make_unique<ReducerHash<mic::Geobucket>>(ring);
+  }
+);
+
 MATHICGB_NAMESPACE_END
-#endif
diff --git a/src/mathicgb/ReducerHash.hpp b/src/mathicgb/ReducerHash.hpp
index 1244ead..2853ffd 100755
--- a/src/mathicgb/ReducerHash.hpp
+++ b/src/mathicgb/ReducerHash.hpp
@@ -3,142 +3,13 @@
 #ifndef MATHICGB_REDUCER_HASH_GUARD
 #define MATHICGB_REDUCER_HASH_GUARD
 
-#include "TypicalReducer.hpp"
-#include "ReducerHelper.hpp"
-#include "PolyHashTable.hpp"
-#include <memtailor.h>
-#include <mathic.h>
-
 MATHICGB_NAMESPACE_BEGIN
 
-template<template<typename ConfigType> class Queue> class ReducerHash;
-
-template<template<typename> class Queue>
-class ReducerHash : public TypicalReducer {
-public:
-  ReducerHash(const PolyRing &ring);
-
-  virtual std::string description() const { 
-    return mQueue.getName() + "-hashed";
-  }
-
-  void insertTail(const_term multiplier, const Poly *f);
-  void insert(monomial multiplier, const Poly *f);
-
-  virtual bool leadTerm(const_term& result);
-  void removeLeadTerm();
-
-  size_t getMemoryUse() const;
-
-protected:
-  void resetReducer();
-
-public:
-  class Configuration : public ReducerHelper::PlainConfiguration {
-  public:
-    typedef PolyHashTable::Node* Entry;
-
-    Configuration(const PolyRing& ring): PlainConfiguration(ring) {}
-
-    CompareResult compare(const Entry& a, const Entry& b) const {
-      return ring().monoid().lessThan(a->mono(), b->mono());
-    }
-  };
-  
-private:
-  mutable std::vector<PolyHashTable::Node*> mNodesTmp;
-  const PolyRing &mRing;
-  PolyHashTable mHashTable;
-  Queue<Configuration> mQueue;
-};
-
-template<template<typename> class Q>
-ReducerHash<Q>::ReducerHash(const PolyRing &ring):
-  mRing(ring),
-  mHashTable(ring),
-  mQueue(Configuration(ring))
-{}
-
-///////////////////////////////////////
-// External interface routines ////////
-///////////////////////////////////////
-
-template<template<typename> class Q>
-void ReducerHash<Q>::insertTail(const_term multiplier, const Poly *g1)
-{
-  if (g1->nTerms() <= 1) return;
-
-  mNodesTmp.clear();
-  auto it = g1->begin();
-  const auto end = g1->end();
-  for (++it; it != end; ++it) {
-    auto p = mHashTable.insertProduct(it.term(), multiplier);
-    if (p.second)
-      mNodesTmp.emplace_back(p.first);
-  }
-  if (!mNodesTmp.empty())
-    mQueue.push(mNodesTmp.begin(), mNodesTmp.end());
-}
-
-template<template<typename> class Q>
-void ReducerHash<Q>::insert(monomial multiplier, const Poly *g1)
-{
-  mNodesTmp.clear();
-  const auto end = g1->end();
-  for (auto it = g1->begin(); it != end; ++it) {
-    auto p = mHashTable.insertProduct
-      (it.getMonomial(), multiplier, it.getCoefficient());
-    if (p.second)
-      mNodesTmp.emplace_back(p.first);
-  }
-  if (!mNodesTmp.empty())
-    mQueue.push(mNodesTmp.begin(), mNodesTmp.end());
-}
-
-template<template<typename> class Q>
-bool ReducerHash<Q>::leadTerm(const_term& result)
-{
-  while (!mQueue.empty()) {
-    const auto top = mQueue.top();
-    if (!mRing.coefficientIsZero(top->value())) {
-      result.coeff = top->value();
-      result.monom = Monoid::toOld(top->mono());
-      return true;
-    }
-    mQueue.pop();
-    mHashTable.remove(top);
-  }
-  return false;
-}
-
-template<template<typename> class Q>
-void ReducerHash<Q>::removeLeadTerm()
-// returns true if there is a term to extract
-{
-  const auto top = mQueue.top();
-  mQueue.pop();
-  mHashTable.remove(top);
-}
-
-template<template<typename> class Q>
-void ReducerHash<Q>::resetReducer()
-{
-  while (!mQueue.empty()) {
-    const auto top = mQueue.top();
-    mQueue.pop();
-    mHashTable.remove(top);
-  }
-  mHashTable.clear();
-}
-
-template<template<typename> class Q>
-size_t ReducerHash<Q>::getMemoryUse() const
-{
-  size_t result = TypicalReducer::getMemoryUse();
-  result += mHashTable.getMemoryUse();
-  result += mQueue.getMemoryUse();
-  return result;
-}
+// This translation unit has to expose something that is needed elsewhere.
+// Otherwise, the compiler will think it is not needed and exclude the
+// whole thing, despite there being important global objects in the .cpp file.
+void reducerHashDependency();
 
 MATHICGB_NAMESPACE_END
+
 #endif
diff --git a/src/mathicgb/ReducerHashPack.hpp b/src/mathicgb/ReducerHashPack.cpp
old mode 100755
new mode 100644
similarity index 89%
copy from src/mathicgb/ReducerHashPack.hpp
copy to src/mathicgb/ReducerHashPack.cpp
index 4c90880..6c8d7af
--- a/src/mathicgb/ReducerHashPack.hpp
+++ b/src/mathicgb/ReducerHashPack.cpp
@@ -1,7 +1,7 @@
 // MathicGB copyright 2012 all rights reserved. MathicGB comes with ABSOLUTELY
 // NO WARRANTY and is licensed as GPL v2.0 or later - see LICENSE.txt.
-#ifndef MATHICGB_REDUCER_HASH_PACK_GUARD
-#define MATHICGB_REDUCER_HASH_PACK_GUARD
+#include "stdinc.h"
+#include "ReducerHashPack.hpp"
 
 #include "TypicalReducer.hpp"
 #include "ReducerHelper.hpp"
@@ -11,6 +11,8 @@
 
 MATHICGB_NAMESPACE_BEGIN
 
+void reducerHashPackDependency() {}
+
 template<template<typename ConfigType> class Queue> class ReducerHashPack;
 
 template<template<typename> class Queue>
@@ -230,5 +232,27 @@ size_t ReducerHashPack<Q>::getMemoryUse() const
     mHashTable.getMemoryUse();
 }
 
+Reducer::Registration r6(
+  "TourHashPack",
+  Reducer::Reducer_TourTree_Hashed_Packed,
+  [](const PolyRing& ring) -> std::unique_ptr<Reducer> {
+    return make_unique<ReducerHashPack<mic::TourTree>>(ring);
+  }
+);
+ 
+Reducer::Registration r12(
+  "HeapHashPack",
+  Reducer::Reducer_Heap_Hashed_Packed,
+  [](const PolyRing& ring) -> std::unique_ptr<Reducer> {
+    return make_unique<ReducerHashPack<mic::Heap>>(ring);
+  }
+);
+Reducer::Registration r18(
+  "GeoHashPack",
+  Reducer::Reducer_Geobucket_Hashed_Packed,
+  [](const PolyRing& ring) -> std::unique_ptr<Reducer> {
+    return make_unique<ReducerHashPack<mic::Geobucket>>(ring);
+  }
+);
+
 MATHICGB_NAMESPACE_END
-#endif
diff --git a/src/mathicgb/ReducerHashPack.hpp b/src/mathicgb/ReducerHashPack.hpp
index 4c90880..c7dd768 100755
--- a/src/mathicgb/ReducerHashPack.hpp
+++ b/src/mathicgb/ReducerHashPack.hpp
@@ -3,232 +3,13 @@
 #ifndef MATHICGB_REDUCER_HASH_PACK_GUARD
 #define MATHICGB_REDUCER_HASH_PACK_GUARD
 
-#include "TypicalReducer.hpp"
-#include "ReducerHelper.hpp"
-#include "PolyHashTable.hpp"
-#include <mathic.h>
-#include <memtailor.h>
-
 MATHICGB_NAMESPACE_BEGIN
 
-template<template<typename ConfigType> class Queue> class ReducerHashPack;
-
-template<template<typename> class Queue>
-class ReducerHashPack : public TypicalReducer {
-public:
-  ReducerHashPack(const PolyRing& R);
-  virtual ~ReducerHashPack();
-
-  virtual std::string description() const { 
-    return mQueue.getName() + "-hashed-packed";
-  }
-
-  virtual void insertTail(const_term multiplier, const Poly *f);
-  virtual void insert(monomial multiplier, const Poly *f);
-
-  virtual bool leadTerm(const_term &result);
-  virtual void removeLeadTerm();
-
-  virtual size_t getMemoryUse() const;
-
-protected:
-  virtual void resetReducer();
-
-private:
-  // Represents a term multiple of a polynomial, 
-  // together with a current term of the multiple.
-  struct MultipleWithPos {
-    MultipleWithPos(const Poly& poly, const_term multiple);
-
-    Poly::const_iterator pos;
-    Poly::const_iterator const end;
-    const_term const multiple;
-    PolyHashTable::Node* node;
-
-    void destroy(const PolyRing& ring);
-  };
-
-  class Configuration : public ReducerHelper::PlainConfiguration {
-  public:
-    typedef MultipleWithPos* Entry;
-    Configuration(const PolyRing& ring) : PlainConfiguration(ring) {}
-    CompareResult compare(const Entry& a, const Entry& b) const {
-      return ring().monoid().lessThan(a->node->mono(), b->node->mono());
-    }
-  };
-
-  class MonomialFree;
-
-  void insertEntry(MultipleWithPos* entry);
-
-  const PolyRing& mRing;
-  Queue<Configuration> mQueue;
-  PolyHashTable mHashTable;
-  memt::BufferPool mPool;
-};
-
-template<template<typename> class Q>
-ReducerHashPack<Q>::ReducerHashPack(const PolyRing& ring):
-  mRing(ring),
-  mQueue(Configuration(ring)),
-  mHashTable(ring),
-  mPool(sizeof(MultipleWithPos))
-{}
-
-template<template<typename> class Q>
-class ReducerHashPack<Q>::MonomialFree
-{
-public:
-  MonomialFree(const PolyRing& ring): mRing(ring) {}
-
-  bool proceed(MultipleWithPos* entry) {
-    entry->destroy(mRing);
-    return true;
-  }
-private:
-  const PolyRing& mRing;
-};
-
-template<template<typename> class Q>
-ReducerHashPack<Q>::~ReducerHashPack()
-{
-  resetReducer();
-}
-
-///////////////////////////////////////
-// External interface routines ////////
-///////////////////////////////////////
-template<template<typename> class Q>
-void ReducerHashPack<Q>::insertTail(const_term multiple, const Poly* poly)
-{
-  MATHICGB_ASSERT(poly != 0);
-  MATHICGB_ASSERT(&poly->ring() == &mRing);
-  if (poly->nTerms() < 2)
-    return;
-  MultipleWithPos* entry =
-    new (mPool.alloc()) MultipleWithPos(*poly, multiple);
-  ++entry->pos;
-  insertEntry(entry);
-}
-
-template<template<typename> class Q>
-void ReducerHashPack<Q>::insert(monomial multiple, const Poly* poly)
-{
-  MATHICGB_ASSERT(poly != 0);
-  MATHICGB_ASSERT(&poly->ring() == &mRing);
-  if (poly->isZero())
-    return;
-  term termMultiple(1, multiple);
-  insertEntry(new (mPool.alloc()) MultipleWithPos(*poly, termMultiple));
-}
-
-namespace {
-  const_term allocTerm(const PolyRing& ring, const_term term) {
-    monomial mono = ring.allocMonomial();
-    ring.monomialCopy(term.monom, mono);
-    return const_term(term.coeff, mono);
-  }
-}
-
-template<template<typename> class Q>
-ReducerHashPack<Q>::MultipleWithPos::MultipleWithPos
-(const Poly& poly, const_term multiple):
-  pos(poly.begin()),
-  end(poly.end()),
-  multiple(allocTerm(poly.ring(), multiple)),
-  node(0) {}
-
-template<template<typename> class Q>
-void ReducerHashPack<Q>::MultipleWithPos::destroy(const PolyRing& ring) {
-  ring.freeMonomial(const_cast<ConstMonomial&>(multiple.monom).castAwayConst());
-
-  // Call the destructor to destruct the iterators into std::vector.
-  // In debug mode MSVC puts those in a linked list and the destructor
-  // has to be called since it takes an iterator off the list. We had
-  // memory corruption problems before doing this.
-  this->~MultipleWithPos();
-}
-
-template<template<typename> class Q>
-bool ReducerHashPack<Q>::leadTerm(const_term& result) {
-  while (!mQueue.empty()) {
-    MultipleWithPos* entry = mQueue.top();
-    MATHICGB_ASSERT(entry != 0);
-
-    if (!mRing.coefficientIsZero(entry->node->value())) {
-      result.coeff = entry->node->value();
-      result.monom = Monoid::toOld(entry->node->mono());
-      return true;
-    }
-    removeLeadTerm();
-  }
-  return false;
-}
-
-template<template<typename> class Q>
-void ReducerHashPack<Q>::removeLeadTerm() {
-  MATHICGB_ASSERT(!mQueue.empty());
-
-  MultipleWithPos* entry = mQueue.top();
-  MATHICGB_ASSERT(entry != 0);
-
-  // remove node from hash table first since we are going to be changing
-  // the monomial after this, and if we do that before the hash value will
-  // change.
-  mHashTable.remove(entry->node);
-
-  MATHICGB_ASSERT(entry->pos != entry->end);
-  while (true) {
-    ++entry->pos;
-    if (entry->pos == entry->end) {
-      mQueue.pop();
-      entry->destroy(mRing);
-      mPool.free(entry);
-      break;
-    }
-   
-    const auto p = mHashTable.insertProduct
-      (entry->multiple, entry->pos.term());
-    if (p.second) {
-      entry->node = p.first;
-      mQueue.decreaseTop(entry);
-      break;
-    }
-  }
-}
-
-template<template<typename> class Q>
-void ReducerHashPack<Q>::insertEntry(MultipleWithPos* entry) {
-  MATHICGB_ASSERT(entry != 0);
-  for (; entry->pos != entry->end; ++entry->pos) {
-    const auto p = mHashTable.insertProduct
-      (entry->multiple, entry->pos.term());
-    if (p.second) {
-      entry->node = p.first;
-      mQueue.push(entry);
-      return;
-    }
-  }
-  entry->destroy(mRing);
-  mPool.free(entry);
-}
-
-template<template<typename> class Q>
-void ReducerHashPack<Q>::resetReducer()
-{
-  MonomialFree freeer(mRing);
-  mQueue.forAll(freeer);
-  mQueue.clear();
-  mHashTable.clear();
-}
-
-template<template<typename> class Q>
-size_t ReducerHashPack<Q>::getMemoryUse() const
-{
-  return mQueue.getMemoryUse() +
-    mPool.getMemoryUse() +
-    mHashTable.getMemoryUse();
-}
+// This translation unit has to expose something that is needed elsewhere.
+// Otherwise, the compiler will think it is not needed and exclude the
+// whole thing, despite there being important global objects in the .cpp file.
+void reducerHashPackDependency();
 
 MATHICGB_NAMESPACE_END
+
 #endif
diff --git a/src/mathicgb/ReducerNoDedup.hpp b/src/mathicgb/ReducerNoDedup.cpp
old mode 100755
new mode 100644
similarity index 85%
copy from src/mathicgb/ReducerNoDedup.hpp
copy to src/mathicgb/ReducerNoDedup.cpp
index e4634e6..78dd7b7
--- a/src/mathicgb/ReducerNoDedup.hpp
+++ b/src/mathicgb/ReducerNoDedup.cpp
@@ -1,7 +1,7 @@
 // MathicGB copyright 2012 all rights reserved. MathicGB comes with ABSOLUTELY
 // NO WARRANTY and is licensed as GPL v2.0 or later - see LICENSE.txt.
-#ifndef MATHICGB_REDUCER_NO_DEDUP_GUARD
-#define MATHICGB_REDUCER_NO_DEDUP_GUARD
+#include "stdinc.h"
+#include "ReducerNoDedup.hpp"
 
 #include "TypicalReducer.hpp"
 #include "ReducerHelper.hpp"
@@ -10,6 +10,8 @@
 
 MATHICGB_NAMESPACE_BEGIN
 
+void reducerNoDedupDependency() {}
+
 template<template<typename ConfigType> class Queue> class ReducerNoDedup;
 
 template<template<typename> class Queue>
@@ -176,5 +178,29 @@ size_t ReducerNoDedup<Q>::getMemoryUse() const
   return TypicalReducer::getMemoryUse() + mQueue.getMemoryUse();
 }
 
+Reducer::Registration r1(
+  "TourNoDedup",
+  Reducer::Reducer_TourTree_NoDedup,
+  [](const PolyRing& ring) -> std::unique_ptr<Reducer> {
+    return make_unique<ReducerNoDedup<mic::TourTree>>(ring);
+  }
+);
+
+Reducer::Registration r7(
+  "HeapNoDedup",
+  Reducer::Reducer_Heap_NoDedup,
+  [](const PolyRing& ring) -> std::unique_ptr<Reducer> {
+    return make_unique<ReducerNoDedup<mic::Heap>>(ring);
+  }
+);
+
+Reducer::Registration r13(
+  "GeoNoDedup",
+  Reducer::Reducer_Geobucket_NoDedup,
+  [](const PolyRing& ring) -> std::unique_ptr<Reducer> {
+    return make_unique<ReducerNoDedup<mic::Geobucket>>(ring);
+  }
+);
+
+
 MATHICGB_NAMESPACE_END
-#endif
diff --git a/src/mathicgb/ReducerNoDedup.hpp b/src/mathicgb/ReducerNoDedup.hpp
index e4634e6..c30bf7d 100755
--- a/src/mathicgb/ReducerNoDedup.hpp
+++ b/src/mathicgb/ReducerNoDedup.hpp
@@ -3,178 +3,12 @@
 #ifndef MATHICGB_REDUCER_NO_DEDUP_GUARD
 #define MATHICGB_REDUCER_NO_DEDUP_GUARD
 
-#include "TypicalReducer.hpp"
-#include "ReducerHelper.hpp"
-#include <memtailor.h>
-#include <mathic.h>
-
 MATHICGB_NAMESPACE_BEGIN
 
-template<template<typename ConfigType> class Queue> class ReducerNoDedup;
-
-template<template<typename> class Queue>
-class ReducerNoDedup : public TypicalReducer {
-public:
-  ReducerNoDedup(const PolyRing& R);
-  virtual ~ReducerNoDedup();
-
-  virtual std::string description() const { 
-    return mQueue.getName() + "-nodedup"; 
-  }
-
-  virtual void insertTail(const_term multiplier, const Poly *f);
-  virtual void insert(monomial multiplier, const Poly *f);
-
-  virtual bool leadTerm(const_term &result);
-  virtual void removeLeadTerm();
-
-  virtual size_t getMemoryUse() const;
-
-protected:
-  virtual void resetReducer();
-
-public:
-  // This Configuration is designed to work with
-  // mathic::TourTree, mathic::Heap, and mathic::Geobucket
-
-  class Configuration : public ReducerHelper::PlainConfiguration {
-  public:
-    typedef term Entry;
-    Configuration(const PolyRing& ring): PlainConfiguration(ring) {}
-    CompareResult compare(const Entry& a, const Entry& b) const {
-      return ring().monomialLT(a.monom, b.monom);
-    }
-  };
-
-private:
-  class MonomialFree;
-  
-  const PolyRing& mRing;
-  term mLeadTerm;
-  bool mLeadTermKnown;
-  Queue<Configuration> mQueue;
-};
-
-template<template<typename> class Q>
-ReducerNoDedup<Q>::ReducerNoDedup(const PolyRing& ring):
-  mRing(ring),
-  mLeadTerm(0, mRing.allocMonomial()),
-  mLeadTermKnown(false),
-  mQueue(Configuration(ring)) {
-}
-
-template<template<typename> class Q>
-class ReducerNoDedup<Q>::MonomialFree
-{
-public:
-  MonomialFree(const PolyRing& ring): mRing(ring) {}
-
-  bool proceed(term entry)
-  {
-    mRing.freeMonomial(entry.monom);
-    return true;
-  }
-private:
-  const PolyRing& mRing;
-};
-
-template<template<typename> class Q>
-ReducerNoDedup<Q>::~ReducerNoDedup()
-{
-  resetReducer();
-  mRing.freeMonomial(mLeadTerm.monom);
-}
-
-///////////////////////////////////////
-// External interface routines ////////
-///////////////////////////////////////
-template<template<typename> class Q>
-void ReducerNoDedup<Q>::insertTail(const_term multiple, const Poly* poly)
-{
-  if (poly->nTerms() <= 1)
-    return;
-  mLeadTermKnown = false;
-
-  Poly::const_iterator i = poly->begin();
-  for (++i; i != poly->end(); ++i)
-    {
-      term t;
-      t.monom = mRing.allocMonomial();
-      mRing.monomialMult(multiple.monom, i.getMonomial(), t.monom);
-      mRing.coefficientMult(multiple.coeff, i.getCoefficient(), t.coeff);
-      mQueue.push(t);
-    }
-}
-
-template<template<typename> class Q>
-void ReducerNoDedup<Q>::insert(monomial multiple, const Poly* poly)
-{
-  if (poly->isZero())
-    return;
-  mLeadTermKnown = false;
-
-  for (Poly::const_iterator i = poly->begin(); i != poly->end(); ++i) {
-    term t(i.getCoefficient(), mRing.allocMonomial());
-    mRing.monomialMult(multiple, i.getMonomial(), t.monom);
-    mQueue.push(t);
-  }
-}
-
-template<template<typename> class Q>
-bool ReducerNoDedup<Q>::leadTerm(const_term& result)
-{
-  if (mLeadTermKnown) {
-    result = mLeadTerm;
-    return true;
-  }
-
-  do {
-    if (mQueue.empty())
-      return false;
-    mLeadTerm = mQueue.top();
-    mQueue.pop();
-    
-    while (true) {
-      if (mQueue.empty())
-        break;
-      
-      term entry = mQueue.top();
-      if (!mRing.monomialEQ(entry.monom, mLeadTerm.monom))
-        break;
-      mRing.coefficientAddTo(mLeadTerm.coeff, entry.coeff);
-      mRing.freeMonomial(entry.monom);
-      mQueue.pop();
-    }
-  } while (mRing.coefficientIsZero(mLeadTerm.coeff));
-
-  result = mLeadTerm;
-  mLeadTermKnown = true;
-  return true;
-}
-
-template<template<typename> class Q>
-void ReducerNoDedup<Q>::removeLeadTerm()
-{
-  if (!mLeadTermKnown) {
-    const_term dummy;
-    leadTerm(dummy);
-  }
-  mLeadTermKnown = false;
-}
-
-template<template<typename> class Q>
-void ReducerNoDedup<Q>::resetReducer()
-{
-  MonomialFree freeer(mRing);
-  //mQueue.forAll(freeer);
-  //  mQueue.clear();
-}
-
-template<template<typename> class Q>
-size_t ReducerNoDedup<Q>::getMemoryUse() const
-{
-  return TypicalReducer::getMemoryUse() + mQueue.getMemoryUse();
-}
+// This translation unit has to expose something that is needed elsewhere.
+// Otherwise, the compiler will think it is not needed and exclude the
+// whole thing, despite there being important global objects in the .cpp file.
+void reducerNoDedupDependency();
 
 MATHICGB_NAMESPACE_END
 #endif
diff --git a/src/mathicgb/ReducerPackDedup.hpp b/src/mathicgb/ReducerPackDedup.cpp
old mode 100755
new mode 100644
similarity index 92%
copy from src/mathicgb/ReducerPackDedup.hpp
copy to src/mathicgb/ReducerPackDedup.cpp
index f27f78f..839959b
--- a/src/mathicgb/ReducerPackDedup.hpp
+++ b/src/mathicgb/ReducerPackDedup.cpp
@@ -1,7 +1,7 @@
 // MathicGB copyright 2012 all rights reserved. MathicGB comes with ABSOLUTELY
 // NO WARRANTY and is licensed as GPL v2.0 or later - see LICENSE.txt.
-#ifndef MATHICGB_REDUCER_PACK_DEDUP_GUARD
-#define MATHICGB_REDUCER_PACK_DEDUP_GUARD
+#include "stdinc.h"
+#include "ReducerPackDedup.hpp"
 
 #include "TypicalReducer.hpp"
 #include "ReducerHelper.hpp"
@@ -10,6 +10,8 @@
 
 MATHICGB_NAMESPACE_BEGIN
 
+void reducerPackDedupDependency() {}
+
 template<template<typename> class Queue>
 class ReducerPackDedup : public TypicalReducer {
 public:
@@ -298,5 +300,28 @@ size_t ReducerPackDedup<Q>::getMemoryUse() const
     mPool.getMemoryUse();
 }
 
+Reducer::Registration r5(
+  "TourDedupPack",
+  Reducer::Reducer_TourTree_Dedup_Packed,
+  [](const PolyRing& ring) -> std::unique_ptr<Reducer> {
+    return make_unique<ReducerPackDedup<mic::TourTree>>(ring);
+  }
+);
+
+Reducer::Registration r11(
+  "HeapDedupPack",
+  Reducer::Reducer_Heap_Dedup_Packed,
+  [](const PolyRing& ring) -> std::unique_ptr<Reducer> {
+    return make_unique<ReducerPackDedup<mic::Heap>>(ring);
+  }
+);
+
+Reducer::Registration r17(
+  "GeoDedupPack",
+  Reducer::Reducer_Geobucket_Dedup_Packed,
+  [](const PolyRing& ring) -> std::unique_ptr<Reducer> {
+    return make_unique<ReducerPackDedup<mic::Geobucket>>(ring);
+  }
+);
+
 MATHICGB_NAMESPACE_END
-#endif
diff --git a/src/mathicgb/ReducerPackDedup.hpp b/src/mathicgb/ReducerPackDedup.hpp
index f27f78f..298c79e 100755
--- a/src/mathicgb/ReducerPackDedup.hpp
+++ b/src/mathicgb/ReducerPackDedup.hpp
@@ -3,300 +3,13 @@
 #ifndef MATHICGB_REDUCER_PACK_DEDUP_GUARD
 #define MATHICGB_REDUCER_PACK_DEDUP_GUARD
 
-#include "TypicalReducer.hpp"
-#include "ReducerHelper.hpp"
-#include <memtailor.h>
-#include <mathic.h>
-
 MATHICGB_NAMESPACE_BEGIN
 
-template<template<typename> class Queue>
-class ReducerPackDedup : public TypicalReducer {
-public:
-  ReducerPackDedup(const PolyRing& ring);
-  virtual ~ReducerPackDedup();
-
-  virtual std::string description() const {
-    return mQueue.getName() + "-packed";
-  }
-
-  virtual void insertTail(const_term multiplier, const Poly* f);
-  virtual void insert(monomial multiplier, const Poly* f);
-
-  virtual bool leadTerm(const_term& result);
-  virtual void removeLeadTerm();
-
-  virtual size_t getMemoryUse() const;
-
-protected:
-  virtual void resetReducer();
-
-private:
-  // Represents a term multiple of a polynomial, 
-  // together with a current term of the multiple.
-public:
-  struct MultipleWithPos {
-    MultipleWithPos(const Poly& poly, const_term multiple);
-
-    Poly::const_iterator pos;
-    Poly::const_iterator const end;
-    const_term const multiple;
-
-    // invariant: current is the monomial product of multiple.monom 
-    // and pos.getMonomial().
-    monomial current;
-
-    // Ensures the invariant, so sets current to the product of
-    // multiple.monom and pos.getMonomial().
-    void computeCurrent(const PolyRing& ring);
-    void currentCoefficient(const PolyRing& ring, coefficient& coeff);
-    void addCurrentCoefficient(const PolyRing& ring, coefficient& coeff);
-    void destroy(const PolyRing& ring);
-
-    // Points to a circular list of entries that have the same current
-    // monomial. If no other such entries have been discovered, then
-    // chain points to this object itself. We use a circular linked list
-    // as those allow merging in O(1) time.
-    MultipleWithPos* chain;
-    void mergeChains(MultipleWithPos& entry) {
-      // This only works if *this and entry are not already in the
-      // same chain!
-      std::swap(chain, entry.chain);
-    }
-  };
-
-  class Configuration : public ReducerHelper::DedupConfiguration {
-  public:
-    typedef MultipleWithPos* Entry;
-    Configuration(const PolyRing& ring): DedupConfiguration(ring) {}
-    CompareResult compare(const Entry& a, const Entry& b) const {
-      return ring().monomialCompare(a->current, b->current);
-    }
-    Entry deduplicate(Entry a, Entry b) const {
-      a->mergeChains(*b);
-      return a;
-    }
-  };
-private:
-  class MonomialFree;
-  
-  const PolyRing& mRing;
-  term mLeadTerm;
-  bool mLeadTermKnown;
-  Queue<Configuration> mQueue;
-  memt::BufferPool mPool;
-};
-
-template<template<typename> class Q>
-ReducerPackDedup<Q>::ReducerPackDedup(const PolyRing& ring):
-  mRing(ring),
-  mLeadTerm(0, mRing.allocMonomial()),
-  mLeadTermKnown(false),
-  mQueue(Configuration(ring)),
-  mPool(sizeof(MultipleWithPos)) {
-}
-
-template<template<typename> class Q>
-class ReducerPackDedup<Q>::MonomialFree
-{
-public:
-  MonomialFree(const PolyRing& ring): mRing(ring) {}
-
-  bool proceed(MultipleWithPos* entry)
-  {
-    entry->destroy(mRing);
-    return true;
-  }
-private:
-  const PolyRing& mRing;
-};
-
-template<template<typename> class Q>
-ReducerPackDedup<Q>::~ReducerPackDedup()
-{
-  resetReducer();
-  mRing.freeMonomial(mLeadTerm.monom);
-}
-
-///////////////////////////////////////
-// External interface routines ////////
-///////////////////////////////////////
-template<template<typename> class Q>
-void ReducerPackDedup<Q>::insertTail(const_term multiple, const Poly* poly)
-{
-  if (poly->nTerms() <= 1)
-    return;
-  mLeadTermKnown = false;
-
-  MultipleWithPos* entry =
-    new (mPool.alloc()) MultipleWithPos(*poly, multiple);
-  ++entry->pos;
-  entry->computeCurrent(poly->ring());
-  mQueue.push(entry);
-}
-
-template<template<typename> class Q>
-void ReducerPackDedup<Q>::insert(monomial multiple, const Poly* poly)
-{
-  if (poly->isZero())
-    return;
-  mLeadTermKnown = false;
-
-  // todo: avoid multiplication by 1
-  term termMultiple(1, multiple);
-  MultipleWithPos* entry =
-    new (mPool.alloc()) MultipleWithPos(*poly, termMultiple);
-  entry->computeCurrent(poly->ring());
-  mQueue.push(entry);
-}
-
-template<template<typename> class Q>
-ReducerPackDedup<Q>::MultipleWithPos::MultipleWithPos
-(const Poly& poly, const_term multipleParam):
-  pos(poly.begin()),
-  end(poly.end()),
-  multiple(ReducerHelper::allocTermCopy(poly.ring(), multipleParam)),
-  current(poly.ring().allocMonomial()),
-  chain(this) {}
-
-template<template<typename> class Q>
-void ReducerPackDedup<Q>::MultipleWithPos::computeCurrent(const PolyRing& ring) {
-  ring.monomialMult(multiple.monom, pos.getMonomial(), current);  
-}
-
-template<template<typename> class Q>
-void ReducerPackDedup<Q>::MultipleWithPos::currentCoefficient
-(const PolyRing& ring, coefficient& coeff) {
-  ring.coefficientMult(multiple.coeff, pos.getCoefficient(), coeff);
-}
-
-template<template<typename> class Q>
-void ReducerPackDedup<Q>::MultipleWithPos::addCurrentCoefficient
-(const PolyRing& ring, coefficient& coeff) {
-  coefficient tmp;
-  ring.coefficientMult(multiple.coeff, pos.getCoefficient(), tmp);
-  ring.coefficientAddTo(coeff, tmp);
-}
-
-template<template<typename> class Q>
-void ReducerPackDedup<Q>::MultipleWithPos::destroy(const PolyRing& ring) {
-  MultipleWithPos* entry = this;
-  do {
-    ring.freeMonomial(entry->current);
-    ConstMonomial& monom = const_cast<ConstMonomial&>(entry->multiple.monom);
-    ring.freeMonomial(monom.castAwayConst());
-    MultipleWithPos* next = entry->chain;
-    MATHICGB_ASSERT(next != 0);
-
-    // Call the destructor to destruct the iterators into std::vector.
-    // In debug mode MSVC puts those in a linked list and the destructor
-    // has to be called since it takes an iterator off the list. We had
-    // memory corruption problems before doing this.
-    entry->~MultipleWithPos();
-
-    entry = next;
-  } while (entry != this);
-}
-
-template<template<typename> class Q>
-bool ReducerPackDedup<Q>::leadTerm(const_term& result)
-{
-  if (mLeadTermKnown) {
-    result = mLeadTerm;
-    return true;
-  }
-
-  do {
-    if (mQueue.empty())
-      return false;
-    MultipleWithPos* entry = mQueue.top();
-    entry->currentCoefficient(mRing, mLeadTerm.coeff);
-    while (true) {
-      // store the chained elements
-      MultipleWithPos* const chainBegin = entry->chain;
-      MultipleWithPos* const chainEnd = entry; // the list is circular
-      entry->chain = entry; // detach any chained elements
-
-      // handle the entry itself
-      mLeadTerm.monom.swap(entry->current);
-      ++entry->pos;
-      if (entry->pos == entry->end) {
-        mQueue.pop();
-        entry->destroy(mRing);
-        mPool.free(entry);
-      } else {
-        entry->computeCurrent(mRing);
-        // Inserted spans must be in descending order
-        MATHICGB_ASSERT(mQueue.getConfiguration().ring().
-          monomialLT(entry->current, mLeadTerm.monom));
-        mQueue.decreaseTop(entry);
-      }
-
-      // handle any chained elements
-      MultipleWithPos* chain = chainBegin;
-      while (chain != chainEnd) {
-        MATHICGB_ASSERT(chain != 0);
-        MATHICGB_ASSERT(mRing.monomialEQ(chain->current, mLeadTerm.monom));
-
-        MultipleWithPos* const next = chain->chain;
-        chain->chain = chain; // detach from remaining chained elements
-
-        chain->addCurrentCoefficient(mRing, mLeadTerm.coeff);
-        ++chain->pos;
-        if (chain->pos == chain->end) {
-          chain->destroy(mRing);
-          mPool.free(chain);
-        } else {
-          chain->computeCurrent(mRing);
-          // Inserted spans must be in descending order
-          MATHICGB_ASSERT(mQueue.getConfiguration().ring().
-            monomialLT(chain->current, mLeadTerm.monom));
-          mQueue.push(chain);
-        }
-        chain = next;
-      }
-      
-      if (mQueue.empty())
-        break;
-      
-      entry = mQueue.top();
-      if (!mRing.monomialEQ(entry->current, mLeadTerm.monom))
-        break;
-      entry->addCurrentCoefficient(mRing, mLeadTerm.coeff);
-    }
-  } while (mRing.coefficientIsZero(mLeadTerm.coeff));
-
-  result = mLeadTerm;
-  mLeadTermKnown = true;
-  return true;
-}
-
-template<template<typename> class Q>
-void ReducerPackDedup<Q>::removeLeadTerm()
-{
-  if (!mLeadTermKnown) {
-    const_term dummy;
-    leadTerm(dummy);
-  }
-  mLeadTermKnown = false;
-}
-
-template<template<typename> class Q>
-void ReducerPackDedup<Q>::resetReducer()
-{
-  MonomialFree freeer(mRing);
-  mQueue.forAll(freeer);
-  mQueue.clear();
-}
-
-template<template<typename> class Q>
-size_t ReducerPackDedup<Q>::getMemoryUse() const
-{
-  return
-    TypicalReducer::getMemoryUse() +
-    mQueue.getMemoryUse() +
-    mPool.getMemoryUse();
-}
+// This translation unit has to expose something that is needed elsewhere.
+// Otherwise, the compiler will think it is not needed and exclude the
+// whole thing, despite there being important global objects in the .cpp file.
+void reducerPackDedupDependency();
 
 MATHICGB_NAMESPACE_END
+
 #endif

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