[mathicgb] 128/393: Improved logging, now with timing support
Doug Torrance
dtorrance-guest at moszumanska.debian.org
Fri Apr 3 15:58:46 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 e597ebaa1598e50423b918325c67601a287c1d61
Author: Bjarke Hammersholt Roune <bjarkehr.code at gmail.com>
Date: Thu Dec 13 19:09:47 2012 +0100
Improved logging, now with timing support
---
src/cli/CommonParams.cpp | 2 -
src/mathicgb/F4MatrixReducer.cpp | 17 +-
src/mathicgb/F4Reducer.cpp | 416 +++++++++++++++++++--------------------
src/mathicgb/LogDomain.cpp | 70 ++++++-
src/mathicgb/LogDomain.hpp | 163 +++++++++++++--
src/mathicgb/QuadMatrix.cpp | 18 +-
src/mathicgb/SparseMatrix.cpp | 4 +-
7 files changed, 457 insertions(+), 233 deletions(-)
diff --git a/src/cli/CommonParams.cpp b/src/cli/CommonParams.cpp
index d3cf0b0..f5a9044 100644
--- a/src/cli/CommonParams.cpp
+++ b/src/cli/CommonParams.cpp
@@ -68,8 +68,6 @@ void CommonParams::perform() {
// delete the old init object first to make the new one take control.
mTbbInit.reset();
- std::unique_ptr<tbb::task_scheduler_init> mTbbInit;
-
mTbbInit = make_unique<tbb::task_scheduler_init>(
mThreadCount.value() == 0 ?
tbb::task_scheduler_init::automatic :
diff --git a/src/mathicgb/F4MatrixReducer.cpp b/src/mathicgb/F4MatrixReducer.cpp
index 41c33a9..829377c 100755
--- a/src/mathicgb/F4MatrixReducer.cpp
+++ b/src/mathicgb/F4MatrixReducer.cpp
@@ -10,7 +10,7 @@
#include <algorithm>
#include <vector>
#include <stdexcept>
-#include <map>
+#include <map>
#include <string>
#include <cstdio>
#include <iostream>
@@ -141,7 +141,8 @@ namespace {
const auto leftColCount = qm.computeLeftColCount();
// static_cast<SparseMatrix::ColIndex>(qm.leftColumnMonomials.size());
- const auto rightColCount = static_cast<SparseMatrix::ColIndex>(qm.computeRightColCount());
+ const auto rightColCount =
+ static_cast<SparseMatrix::ColIndex>(qm.computeRightColCount());
// static_cast<SparseMatrix::ColIndex>(qm.rightColumnMonomials.size());
MATHICGB_ASSERT(leftColCount == reduceByLeft.rowCount());
const auto pivotCount = leftColCount;
@@ -252,6 +253,11 @@ namespace {
const SparseMatrix& toReduce,
const SparseMatrix::Scalar modulus
) {
+ const char* p = STR(MATHICGB_IF_LOG(F4MatrixReduce));
+
+ MATHICGB_LOG_TIME(F4MatrixReduce) <<
+ "Reducing matrix to row echelon form\n";
+
const auto colCount = toReduce.computeColCount();
const auto rowCount = toReduce.rowCount();
@@ -375,10 +381,13 @@ namespace {
}
}
+#define STR(X) #X
SparseMatrix F4MatrixReducer::reduceToBottomRight(const QuadMatrix& matrix) {
MATHICGB_ASSERT(matrix.debugAssertValid());
- if (::logs::F4MatrixReduce.enabled())
- matrix.printSizes(::logs::F4MatrixReduce.stream());
+ const char* p = STR(MATHICGB_IF_LOG(F4MatrixReduce));
+ /*MATHICGB_IF_LOG(F4MatrixReduce) {
+ matrix.printSizes(log.stream();
+ };*/
return reduce(matrix, mModulus);
}
diff --git a/src/mathicgb/F4Reducer.cpp b/src/mathicgb/F4Reducer.cpp
index 8688d70..52b7e09 100755
--- a/src/mathicgb/F4Reducer.cpp
+++ b/src/mathicgb/F4Reducer.cpp
@@ -1,215 +1,215 @@
-#include "stdinc.h"
-#include "F4Reducer.hpp"
-
-#include "F4MatrixBuilder.hpp"
-#include "F4MatrixReducer.hpp"
-#include "QuadMatrix.hpp"
-#include <iostream>
-#include <limits>
-
-F4Reducer::F4Reducer(const PolyRing& ring):
- mFallback(Reducer::makeReducer(Reducer::Reducer_BjarkeGeo, ring)),
- mRing(ring),
- mMemoryQuantum(0),
+#include "stdinc.h"
+#include "F4Reducer.hpp"
+
+#include "F4MatrixBuilder.hpp"
+#include "F4MatrixReducer.hpp"
+#include "QuadMatrix.hpp"
+#include <iostream>
+#include <limits>
+
+F4Reducer::F4Reducer(const PolyRing& ring):
+ mFallback(Reducer::makeReducer(Reducer::Reducer_BjarkeGeo, ring)),
+ mRing(ring),
+ mMemoryQuantum(0),
mStoreToFile(""),
- mMinEntryCountForStore(0),
- mMatrixSaveCount(0) {
-}
+ mMinEntryCountForStore(0),
+ mMatrixSaveCount(0) {
+}
void F4Reducer::writeMatricesTo(std::string file, size_t minEntries) {
mStoreToFile = std::move(file);
mMinEntryCountForStore = minEntries;
mMatrixSaveCount = 0;
}
-
-std::unique_ptr<Poly> F4Reducer::classicReduce
-(const Poly& poly, const PolyBasis& basis) {
- if (tracingLevel >= 2)
- std::cerr <<
- "F4Reducer: Using fall-back reducer for single classic reduction\n";
-
- std::unique_ptr<Poly> p;
- p = mFallback->classicReduce(poly, basis);
- mSigStats = mFallback->sigStats();
- mClassicStats = mFallback->classicStats();
- return p;
-}
-
-std::unique_ptr<Poly> F4Reducer::classicTailReduce
-(const Poly& poly, const PolyBasis& basis) {
- std::unique_ptr<Poly> p;
- if (tracingLevel >= 2)
- std::cerr <<
- "F4Reducer: Using fall-back reducer for single classic tail reduction\n";
-
- p = mFallback->classicTailReduce(poly, basis);
- mSigStats = mFallback->sigStats();
- mClassicStats = mFallback->classicStats();
- return p;
-}
-
-std::unique_ptr<Poly> F4Reducer::classicReduceSPoly(
- const Poly& a,
- const Poly& b,
- const PolyBasis& basis
-) {
- if (tracingLevel >= 2)
- std::cerr << "F4Reducer: "
- "Using fall-back reducer for single classic S-pair reduction\n";
- return mFallback->classicReduceSPoly(a, b, basis);
-}
-
-void F4Reducer::classicReduceSPolySet(
- std::vector<std::pair<size_t, size_t> >& spairs,
- const PolyBasis& basis,
- std::vector<std::unique_ptr<Poly> >& reducedOut
-) {
- if (spairs.size() <= 1) {
- if (tracingLevel >= 2)
- std::cerr << "F4Reducer: Using fall-back reducer for "
- << spairs.size() << " S-pairs.\n";
- mFallback->classicReduceSPolySet(spairs, basis, reducedOut);
- return;
- }
- reducedOut.clear();
-
- MATHICGB_ASSERT(!spairs.empty());
- if (tracingLevel >= 2)
- std::cerr << "F4Reducer: Reducing " << spairs.size() << " S-polynomials.\n";
-
- SparseMatrix reduced;
- std::vector<monomial> monomials;
- {
- QuadMatrix qm;
- {
- F4MatrixBuilder builder(basis, mMemoryQuantum);
- for (auto it = spairs.begin(); it != spairs.end(); ++it) {
- builder.addSPolynomialToMatrix
- (basis.poly(it->first), basis.poly(it->second));
- }
- builder.buildMatrixAndClear(qm);
-
- // there has to be something to reduce
- MATHICGB_ASSERT(qm.bottomLeft.rowCount() > 0);
- }
- saveMatrix(qm);
- reduced = F4MatrixReducer(basis.ring().charac()).
- reducedRowEchelonFormBottomRight(qm);
- monomials = std::move(qm.rightColumnMonomials);
- const auto end = qm.leftColumnMonomials.end();
- for (auto it = qm.leftColumnMonomials.begin(); it != end; ++it)
- mRing.freeMonomial(*it);
- }
-
- if (tracingLevel >= 2)
- std::cerr << "F4Reducer: Extracted " << reduced.rowCount()
- << " non-zero rows\n";
-
- for (SparseMatrix::RowIndex row = 0; row < reduced.rowCount(); ++row) {
- auto p = make_unique<Poly>(basis.ring());
- reduced.rowToPolynomial(row, monomials, *p);
- reducedOut.push_back(std::move(p));
- }
- const auto end = monomials.end();
- for (auto it = monomials.begin(); it != end; ++it)
- mRing.freeMonomial(*it);
-}
-
-void F4Reducer::classicReducePolySet
-(const std::vector<std::unique_ptr<Poly> >& polys,
- const PolyBasis& basis,
- std::vector<std::unique_ptr<Poly> >& reducedOut)
-{
- if (polys.size() <= 1) {
- if (tracingLevel >= 2)
- std::cerr << "F4Reducer: Using fall-back reducer for "
- << polys.size() << " polynomials.\n";
- mFallback->classicReducePolySet(polys, basis, reducedOut);
- return;
- }
-
- reducedOut.clear();
-
- MATHICGB_ASSERT(!polys.empty());
- if (tracingLevel >= 2)
- std::cerr << "F4Reducer: Reducing " << polys.size() << " polynomials.\n";
-
- SparseMatrix reduced;
- std::vector<monomial> monomials;
- {
- QuadMatrix qm;
- {
- F4MatrixBuilder builder(basis, mMemoryQuantum);
- for (auto it = polys.begin(); it != polys.end(); ++it)
- builder.addPolynomialToMatrix(**it);
- builder.buildMatrixAndClear(qm);
-
- // there has to be something to reduce
- MATHICGB_ASSERT(qm.bottomLeft.rowCount() > 0);
- }
- saveMatrix(qm);
- reduced = F4MatrixReducer(basis.ring().charac()).
- reducedRowEchelonFormBottomRight(qm);
- monomials = std::move(qm.rightColumnMonomials);
- for (auto it = qm.leftColumnMonomials.begin();
- it != qm.leftColumnMonomials.end(); ++it)
- mRing.freeMonomial(*it);
- }
-
- if (tracingLevel >= 2)
- std::cerr << "F4Reducer: Extracted " << reduced.rowCount()
- << " non-zero rows\n";
-
- for (SparseMatrix::RowIndex row = 0; row < reduced.rowCount(); ++row) {
- auto p = make_unique<Poly>(basis.ring());
- reduced.rowToPolynomial(row, monomials, *p);
- reducedOut.push_back(std::move(p));
- }
- const auto end = monomials.end();
- for (auto it = monomials.begin(); it != end; ++it)
- mRing.freeMonomial(*it);
-}
-
-Poly* F4Reducer::regularReduce(
- const_monomial sig,
- const_monomial multiple,
- size_t basisElement,
- const GroebnerBasis& basis
-) {
- if (tracingLevel >= 2)
- std::cerr <<
- "F4Reducer: Using fall-back reducer for single regular reduction\n";
- Poly* p = mFallback->regularReduce(sig, multiple, basisElement, basis);
- mSigStats = mFallback->sigStats();
- mClassicStats = mFallback->classicStats();
- return p;
-}
-
-void F4Reducer::setMemoryQuantum(size_t quantum) {
- mMemoryQuantum = quantum;
-}
-
-std::string F4Reducer::description() const {
- return "F4 reducer";
-}
-
-size_t F4Reducer::getMemoryUse() const {
- return 0; // @todo: implement
-}
-
-void F4Reducer::saveMatrix(const QuadMatrix& matrix) {
- if (mStoreToFile.empty())
- return;
- const auto entryCount = matrix.entryCount();
- if (mMinEntryCountForStore > entryCount)
- return;
- ++mMatrixSaveCount;
- std::ostringstream fileName;
- fileName << mStoreToFile << '-' << mMatrixSaveCount << ".qmat";
- if (tracingLevel > 2)
- std::cerr << "F4Reducer: Saving matrix to " << fileName.str() << '\n';
- FILE* file = fopen(fileName.str().c_str(), "wb");
- // @todo: fix leak of file on exception
- matrix.write(static_cast<SparseMatrix::Scalar>(mRing.charac()), file);
- fclose(file);
-}
+
+std::unique_ptr<Poly> F4Reducer::classicReduce
+(const Poly& poly, const PolyBasis& basis) {
+ if (tracingLevel >= 2)
+ std::cerr <<
+ "F4Reducer: Using fall-back reducer for single classic reduction\n";
+
+ std::unique_ptr<Poly> p;
+ p = mFallback->classicReduce(poly, basis);
+ mSigStats = mFallback->sigStats();
+ mClassicStats = mFallback->classicStats();
+ return p;
+}
+
+std::unique_ptr<Poly> F4Reducer::classicTailReduce
+(const Poly& poly, const PolyBasis& basis) {
+ std::unique_ptr<Poly> p;
+ if (tracingLevel >= 2)
+ std::cerr <<
+ "F4Reducer: Using fall-back reducer for single classic tail reduction\n";
+
+ p = mFallback->classicTailReduce(poly, basis);
+ mSigStats = mFallback->sigStats();
+ mClassicStats = mFallback->classicStats();
+ return p;
+}
+
+std::unique_ptr<Poly> F4Reducer::classicReduceSPoly(
+ const Poly& a,
+ const Poly& b,
+ const PolyBasis& basis
+) {
+ if (tracingLevel >= 2)
+ std::cerr << "F4Reducer: "
+ "Using fall-back reducer for single classic S-pair reduction\n";
+ return mFallback->classicReduceSPoly(a, b, basis);
+}
+
+void F4Reducer::classicReduceSPolySet(
+ std::vector<std::pair<size_t, size_t> >& spairs,
+ const PolyBasis& basis,
+ std::vector<std::unique_ptr<Poly> >& reducedOut
+) {
+ if (spairs.size() <= 1) {
+ if (tracingLevel >= 2)
+ std::cerr << "F4Reducer: Using fall-back reducer for "
+ << spairs.size() << " S-pairs.\n";
+ mFallback->classicReduceSPolySet(spairs, basis, reducedOut);
+ return;
+ }
+ reducedOut.clear();
+
+ MATHICGB_ASSERT(!spairs.empty());
+ if (tracingLevel >= 2)
+ std::cerr << "F4Reducer: Reducing " << spairs.size() << " S-polynomials.\n";
+
+ SparseMatrix reduced;
+ std::vector<monomial> monomials;
+ {
+ QuadMatrix qm;
+ {
+ F4MatrixBuilder builder(basis, mMemoryQuantum);
+ for (auto it = spairs.begin(); it != spairs.end(); ++it) {
+ builder.addSPolynomialToMatrix
+ (basis.poly(it->first), basis.poly(it->second));
+ }
+ builder.buildMatrixAndClear(qm);
+
+ // there has to be something to reduce
+ MATHICGB_ASSERT(qm.bottomLeft.rowCount() > 0);
+ }
+ saveMatrix(qm);
+ reduced = F4MatrixReducer(basis.ring().charac()).
+ reducedRowEchelonFormBottomRight(qm);
+ monomials = std::move(qm.rightColumnMonomials);
+ const auto end = qm.leftColumnMonomials.end();
+ for (auto it = qm.leftColumnMonomials.begin(); it != end; ++it)
+ mRing.freeMonomial(*it);
+ }
+
+ if (tracingLevel >= 2)
+ std::cerr << "F4Reducer: Extracted " << reduced.rowCount()
+ << " non-zero rows\n";
+
+ for (SparseMatrix::RowIndex row = 0; row < reduced.rowCount(); ++row) {
+ auto p = make_unique<Poly>(basis.ring());
+ reduced.rowToPolynomial(row, monomials, *p);
+ reducedOut.push_back(std::move(p));
+ }
+ const auto end = monomials.end();
+ for (auto it = monomials.begin(); it != end; ++it)
+ mRing.freeMonomial(*it);
+}
+
+void F4Reducer::classicReducePolySet
+(const std::vector<std::unique_ptr<Poly> >& polys,
+ const PolyBasis& basis,
+ std::vector<std::unique_ptr<Poly> >& reducedOut)
+{
+ if (polys.size() <= 1) {
+ if (tracingLevel >= 2)
+ std::cerr << "F4Reducer: Using fall-back reducer for "
+ << polys.size() << " polynomials.\n";
+ mFallback->classicReducePolySet(polys, basis, reducedOut);
+ return;
+ }
+
+ reducedOut.clear();
+
+ MATHICGB_ASSERT(!polys.empty());
+ if (tracingLevel >= 2)
+ std::cerr << "F4Reducer: Reducing " << polys.size() << " polynomials.\n";
+
+ SparseMatrix reduced;
+ std::vector<monomial> monomials;
+ {
+ QuadMatrix qm;
+ {
+ F4MatrixBuilder builder(basis, mMemoryQuantum);
+ for (auto it = polys.begin(); it != polys.end(); ++it)
+ builder.addPolynomialToMatrix(**it);
+ builder.buildMatrixAndClear(qm);
+
+ // there has to be something to reduce
+ MATHICGB_ASSERT(qm.bottomLeft.rowCount() > 0);
+ }
+ saveMatrix(qm);
+ reduced = F4MatrixReducer(basis.ring().charac()).
+ reducedRowEchelonFormBottomRight(qm);
+ monomials = std::move(qm.rightColumnMonomials);
+ for (auto it = qm.leftColumnMonomials.begin();
+ it != qm.leftColumnMonomials.end(); ++it)
+ mRing.freeMonomial(*it);
+ }
+
+ if (tracingLevel >= 2)
+ std::cerr << "F4Reducer: Extracted " << reduced.rowCount()
+ << " non-zero rows\n";
+
+ for (SparseMatrix::RowIndex row = 0; row < reduced.rowCount(); ++row) {
+ auto p = make_unique<Poly>(basis.ring());
+ reduced.rowToPolynomial(row, monomials, *p);
+ reducedOut.push_back(std::move(p));
+ }
+ const auto end = monomials.end();
+ for (auto it = monomials.begin(); it != end; ++it)
+ mRing.freeMonomial(*it);
+}
+
+Poly* F4Reducer::regularReduce(
+ const_monomial sig,
+ const_monomial multiple,
+ size_t basisElement,
+ const GroebnerBasis& basis
+) {
+ if (tracingLevel >= 2)
+ std::cerr <<
+ "F4Reducer: Using fall-back reducer for single regular reduction\n";
+ Poly* p = mFallback->regularReduce(sig, multiple, basisElement, basis);
+ mSigStats = mFallback->sigStats();
+ mClassicStats = mFallback->classicStats();
+ return p;
+}
+
+void F4Reducer::setMemoryQuantum(size_t quantum) {
+ mMemoryQuantum = quantum;
+}
+
+std::string F4Reducer::description() const {
+ return "F4 reducer";
+}
+
+size_t F4Reducer::getMemoryUse() const {
+ return 0; // @todo: implement
+}
+
+void F4Reducer::saveMatrix(const QuadMatrix& matrix) {
+ if (mStoreToFile.empty())
+ return;
+ const auto entryCount = matrix.entryCount();
+ if (mMinEntryCountForStore > entryCount)
+ return;
+ ++mMatrixSaveCount;
+ std::ostringstream fileName;
+ fileName << mStoreToFile << '-' << mMatrixSaveCount << ".qmat";
+ if (tracingLevel > 2)
+ std::cerr << "F4Reducer: Saving matrix to " << fileName.str() << '\n';
+ FILE* file = fopen(fileName.str().c_str(), "wb");
+ // @todo: fix leak of file on exception
+ matrix.write(static_cast<SparseMatrix::Scalar>(mRing.charac()), file);
+ fclose(file);
+}
diff --git a/src/mathicgb/LogDomain.cpp b/src/mathicgb/LogDomain.cpp
index 235623a..fcf6007 100755
--- a/src/mathicgb/LogDomain.cpp
+++ b/src/mathicgb/LogDomain.cpp
@@ -9,13 +9,81 @@ LogDomain<true>::LogDomain(
const char* const description,
const bool enabled
):
+ mEnabled(enabled),
mName(name),
mDescription(description),
- mEnabled(enabled)
+ mInterval()
{
LogDomainSet::singleton().registerLogDomain(*this);
}
+LogDomain<true>::~LogDomain() {
+ if (enabled() && mHasTime) {
+ stream() << mName << " total time: ";
+ mInterval.print(stream());
+ stream() << '\n';
+ }
+}
+
std::ostream& LogDomain<true>::stream() {
return std::cerr;
}
+
+LogDomain<true>::Timer LogDomain<true>::timer() {
+ return Timer(*this);
+}
+
+void LogDomain<true>::TimeInterval::print(std::ostream& out) const {
+ const auto oldFlags = out.flags();
+ const auto oldPrecision = out.precision();
+ out.precision(3);
+ out << std::fixed << realSeconds << "s (real)";
+ // todo: restore the stream state using RAII, since the above code might
+ // throw an exception.
+ out.precision(oldPrecision);
+ out.flags(oldFlags);
+}
+
+void LogDomain<true>::recordTime(TimeInterval interval) {
+ if (!enabled())
+ return;
+ mInterval.realSeconds += interval.realSeconds;
+ mHasTime = true;
+
+ MATHICGB_ASSERT(mName != 0);
+ stream() << mName << " time recorded: ";
+ interval.print(stream());
+ stream() << std::endl;
+}
+
+LogDomain<true>::Timer::Timer(LogDomain<true>& logger):
+ mLogger(logger),
+ mTimerRunning(false),
+ mRealTicks()
+{
+ start();
+}
+
+LogDomain<true>::Timer::~Timer() {
+ stop();
+}
+
+void LogDomain<true>::Timer::stop() {
+ if (!running())
+ return;
+ mTimerRunning = false;
+ if (!mLogger.enabled())
+ return;
+ mTimerRunning = false;
+ TimeInterval interval;
+ interval.realSeconds = (tbb::tick_count::now() - mRealTicks).seconds();
+ mLogger.recordTime(interval);
+ return;
+}
+
+void LogDomain<true>::Timer::start() {
+ if (!mLogger.enabled() || mTimerRunning)
+ return;
+ mTimerRunning = true;
+ mRealTicks = tbb::tick_count::now();
+}
diff --git a/src/mathicgb/LogDomain.hpp b/src/mathicgb/LogDomain.hpp
index a47fd71..f3de139 100755
--- a/src/mathicgb/LogDomain.hpp
+++ b/src/mathicgb/LogDomain.hpp
@@ -1,9 +1,28 @@
#ifndef MATHICGB_LOG_DOMAIN_GUARD
#define MATHICGB_LOG_DOMAIN_GUARD
+#include <tbb/tbb.h>
#include <ostream>
-
-template<bool Enabled>
+#include <ctime>
+#include <sstream>
+
+/// A named area of logging that can be turned on or off at runtime and at
+/// compile time.
+///
+/// A logger that is turned off at compile time emits no code
+/// into the executable and all the code that writes to that logger is also
+/// removed by the optimizer if it is written in the correct way. Use the
+/// logging macroes to ensure proper use so that compile-time disabled
+/// LogDomains properly have zero overhead. LogDomains can be turned on
+/// and off at compile time and at runtime individually.
+///
+/// Compile-time enabled loggers automatically register themselves with
+/// LogDomainSet::singleton().
+///
+/// @todo: support turning all loggers off globally with a macro, regardless
+/// of their individual compile-time on/off setting.
+
+template<bool CompileTimeEnabled>
class LogDomain {};
template<>
@@ -16,6 +35,7 @@ public:
const char* const description,
const bool enabled
);
+ ~LogDomain();
const char* name() const {return mName;}
const char* description() const {return mDescription;}
@@ -25,12 +45,64 @@ public:
std::ostream& stream();
+ /// Class for recording time that is logged.
+ class Timer;
+
+ /// Returns a started timer that you can move from.
+ Timer timer();
+
private:
+ struct TimeInterval {
+ // todo: support user time too. clock() doesn't seem to sum the time
+ // for all threads, so that didn't work.
+ double realSeconds;
+
+ void print(std::ostream& out) const;
+ };
+ void recordTime(TimeInterval interval);
+
+ bool mEnabled;
const char* mName;
const char* mDescription;
- bool mEnabled;
+
+ TimeInterval mInterval; /// Total amount of time recorded on this log.
+
+ /// Indicates if any period of time has been recorded, even if that period
+ /// of time was recorded as 0 seconds.
+ bool mHasTime;
};
+class LogDomain<true>::Timer {
+public:
+ /// Start the timer running. The elapsed time will be logged to the logger
+ /// once the timer is stopped or destructed.
+ Timer(LogDomain<true>& logger);
+
+ /// Stops the timer.
+ ~Timer();
+
+ /// Returns true if the timer is currently recording time.
+ bool running() const {return mTimerRunning;}
+
+ /// Stops recording time and logs the elapsed time to the logger.
+ ///
+ /// This is a no-op if the timer is not running. If the logger
+ /// is disabled then no time is logged.
+ void stop();
+
+ /// Start recording time on a stopped timer.
+ ///
+ /// This is a no-op is the timer is already running or if the logger is
+ /// disabled.
+ void start();
+
+private:
+ LogDomain<true>& mLogger;
+ bool mTimerRunning;
+ tbb::tick_count mRealTicks; // high precision
+};
+
+/// This is a compile-time disabled logger.
template<>
class LogDomain<false> {
public:
@@ -40,6 +112,15 @@ public:
bool enabled() const {return false;}
+ class Timer {
+ public:
+ Timer(LogDomain<false>&) {}
+ bool running() const {return false;}
+ void stop() {}
+ void start() {}
+ };
+ Timer timer() {return Timer(*this);}
+
std::ostream& stream() {
MATHICGB_ASSERT(false);
return *static_cast<std::ostream*>(0);
@@ -47,6 +128,9 @@ public:
};
namespace LogDomainInternal {
+ // Support code for the logging macroes
+
+
template<class Tag, bool Default>
struct SelectValue {static const bool value = Default;};
@@ -59,6 +143,13 @@ namespace LogDomainInternal {
template<bool Default>
struct SelectValue<Tag_1<int>, Default> {static const bool value = true;};
+
+ template<class L>
+ struct LambdaRunner {L& log;};
+ template<class L>
+ LambdaRunner<L> lambdaRunner(L& log) {return LambdaRunner{log};}
+ template<class L, class T>
+ void operator+(LambdaRunner<L> runner, T& lambda) {lambda(runner.log);}
}
/// Defines LogDomainInternal::value_##NAME to be equal to the value of
@@ -73,10 +164,11 @@ namespace LogDomainInternal {
SelectValue<SelectedTag_##NAME, DEFAULT_VALUE>::value; \
}
-/// Defines logs::obj##NAME to be a LogDomain that is compile-time
-/// enabled depending on MATHICGB_LOG_##NAME (see MATHICGB_CAPTURE_LOG_ENABLED)
-/// and that is initially runtime enabled depending on the value of
-/// DEFAULT_RUNTIME_ENABLED.
+/// Defines a LogDomain with the given name and description.
+///
+/// The logger is default compile-time enabled depending on MATHICGB_LOG_##NAME
+/// (see MATHICGB_CAPTURE_LOG_ENABLED) and it is initially runtime
+/// enabled depending on the value of DEFAULT_RUNTIME_ENABLED.
#define MATHICGB_DEFINE_LOG_DOMAIN_WITH_DEFAULTS(NAME, DESCRIPTION, DEFAULT_RUNTIME_ENABLED, DEFAULT_COMPILE_TIME_ENABLED) \
MATHICGB_CAPTURE_LOG_ENABLED(NAME, DEFAULT_COMPILE_TIME_ENABLED); \
namespace logs { \
@@ -84,16 +176,59 @@ namespace LogDomainInternal {
Type##NAME NAME(#NAME, DESCRIPTION, DEFAULT_RUNTIME_ENABLED); \
}
-/// Defines logs::##NAME to be a LogDomain. It is compile-time enabled
-/// by default and runtime disabled by default.
+/// Defines a LogDomain with the given name and description.
+///
+/// By default, the logger is compile-time enabled and runtime disabled.
#define MATHICGB_DEFINE_LOG_DOMAIN(NAME, DESCRIPTION) \
MATHICGB_DEFINE_LOG_DOMAIN_WITH_DEFAULTS(NAME, DESCRIPTION, 0, 1);
-/// Have the code X in the program if and only if logging is not globally
-/// compile-time disabled.
-#define MATHICGB_IF_LOG(X) X
-
+/// This expression yields an l-value reference to the indicated logger.
+///
+/// Example:
+/// auto timer = MATHICGB_LOGGER(MyDomain).timer();
+#define MATHICGB_LOGGER(DOMAIN) ::logs::##DOMAIN
+
+/// This expression yields the type of the indicated logger.
+///
+/// Example:
+/// if (MATHICGB_LOGGER_TYPE(MyDomain)::compileTimeEnabled)
+/// std::ostream << "MyDomain is compiled time enabled";
+#define MATHICGB_LOGGER_TYPE(DOMAIN) ::logs::Type##DOMAIN
+
+/// Runs the code in the following scope delimited by braces {} if the indicated
+/// logger is enabled - otherwise does nothing. Within the following scope
+/// there is a local reference variable log that refers to the indicated
+/// logger.
+///
+/// Example:
+/// MATHICGB_IF_LOG(MyDomain) {
+/// std::string msg;
+/// expensiveFunction(msg);
+/// log << msg;
+/// }
+#define MATHICGB_IF_LOG(DOMAIN) \
+ if (MATHICGB_LOGGER(DOMAIN).enabled()) \
+ LogDomainInternal::lambdaRunner(MATHICGB_LOGGER(DOMAIN)) + \
+ [&](MATHICGB_LOGGER_TYPE(DOMAIN)& log)
+
+/// Display information to the log using <<.
+/// If domain is not enabled then the log message is not displayed and the
+/// code after << is not executed.
+///
+/// Example: (f() only called if logger is enabled)
+/// MATHICGB_LOG(domain) << "f() = " << f();
#define MATHICGB_LOG(DOMAIN) \
- if (::logs::##NAME.enabled()) ::logs::##NAME.stream()
+ if (MATHICGB_LOGGER(DOMAIN).enabled()) MATHICGB_LOGGER(DOMAIN).stream()
+
+/// Will log the time to execute the remaining code in the current scope
+/// to the indicated domain. Also supports printing a message using <<.
+/// The message is printed right away while the time is printed when
+/// the scope ends.
+///
+/// Example:
+/// MATHICGB_LOG_SCOPE_TIME(MyDomain) << "Starting timed task";
+#define MATHICGB_LOG_TIME(DOMAIN) \
+ auto MATHICGB_timer##DOMAIN##_##__LINE__##(MATHICGB_LOGGER(DOMAIN).timer()); \
+ MATHICGB_LOG(DOMAIN)
#endif
diff --git a/src/mathicgb/QuadMatrix.cpp b/src/mathicgb/QuadMatrix.cpp
index 3ec8bd7..68c3a19 100755
--- a/src/mathicgb/QuadMatrix.cpp
+++ b/src/mathicgb/QuadMatrix.cpp
@@ -67,10 +67,24 @@ size_t QuadMatrix::rowCount() const {
}
SparseMatrix::ColIndex QuadMatrix::computeLeftColCount() const {
+ if (!leftColumnMonomials.empty()) {
+ MATHICGB_ASSERT(
+ leftColumnMonomials.size() <=
+ std::numeric_limits<SparseMatrix::ColIndex>::max()
+ );
+ return static_cast<SparseMatrix::ColIndex>(leftColumnMonomials.size());
+ }
return std::max(topLeft.computeColCount(), bottomLeft.computeColCount());
}
SparseMatrix::ColIndex QuadMatrix::computeRightColCount() const {
+ if (!rightColumnMonomials.empty()) {
+ MATHICGB_ASSERT(
+ rightColumnMonomials.size() <=
+ std::numeric_limits<SparseMatrix::ColIndex>::max()
+ );
+ return static_cast<SparseMatrix::ColIndex>(rightColumnMonomials.size());
+ }
return std::max(topRight.computeColCount(), bottomRight.computeColCount());
}
@@ -106,8 +120,8 @@ void QuadMatrix::printSizes(std::ostream& out) const {
const char* const line = "----------";
pr[0] << '\n';
- pr[1] << ColPr::commafy(leftColumnMonomials.size()) << " \n";
- pr[2] << ColPr::commafy(rightColumnMonomials.size()) << " \n";
+ pr[1] << ColPr::commafy(computeLeftColCount()) << " \n";
+ pr[2] << ColPr::commafy(computeRightColCount()) << " \n";
pr[0] << "/\n";
pr[1] << line << "|\n";
diff --git a/src/mathicgb/SparseMatrix.cpp b/src/mathicgb/SparseMatrix.cpp
index 87f0e59..895247c 100755
--- a/src/mathicgb/SparseMatrix.cpp
+++ b/src/mathicgb/SparseMatrix.cpp
@@ -395,14 +395,14 @@ namespace {
void writeMany(const std::vector<T>& v, FILE* file) {
if (v.empty())
return;
- fwrite(&v[0], sizeof(T), v.size(), file);
+ fwrite(v.data(), sizeof(T), v.size(), file);
}
template<class T>
void readMany(FILE* file, size_t count, std::vector<T>& v) {
size_t const originalSize = v.size();
v.resize(originalSize + count);
- fread(&v[originalSize], sizeof(T), count, file);
+ fread(v.data() + originalSize, sizeof(T), count, file);
}
}
--
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