-
Notifications
You must be signed in to change notification settings - Fork 16
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add interface for defining external statistics. #23
Changes from 2 commits
e916db3
ac6941d
58748a4
6865b14
8f57a3f
4a72e0f
4743d55
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -555,7 +555,10 @@ double _getResult(const SolveResult* r) { return static_cast<double>(r->operator | |
double _getSignal(const SolveResult* r) { return static_cast<double>(r->signal); } | ||
double _getExhausted(const SolveResult* r) { return static_cast<double>(r->exhausted()); } | ||
} | ||
|
||
struct ClaspFacade::Statistics { | ||
typedef std::pair<StatsCallback, void*> UserCallback; | ||
|
||
Statistics(ClaspFacade& f) : self_(&f), tester_(0), level_(0), clingo_(0) {} | ||
~Statistics() { delete clingo_; delete solvers_.multi; } | ||
void start(uint32 level); | ||
|
@@ -564,17 +567,24 @@ struct ClaspFacade::Statistics { | |
void addTo(StatsMap& solving, StatsMap* accu) const; | ||
void accept(StatsVisitor& out, bool final) const; | ||
bool incremental() const { return self_->incremental(); } | ||
void addExternal(StatsCallback, void*); | ||
Potassco::Span<UserCallback> getExternal() const; | ||
|
||
Potassco::AbstractStatistics* getClingo(); | ||
typedef StatsVec<SolverStats> SolverVec; | ||
typedef SingleOwnerPtr<Asp::LpStats> LpStatsPtr; | ||
typedef PrgDepGraph::NonHcfStats TesterStats; | ||
typedef StatsVec<SolverStats> SolverVec; | ||
typedef SingleOwnerPtr<Asp::LpStats> LpStatsPtr; | ||
typedef PrgDepGraph::NonHcfStats TesterStats; | ||
typedef PodVector<UserCallback>::type UserStatsVec; | ||
typedef SingleOwnerPtr<ExternalStatistics> UserStatsPtr; | ||
ClaspFacade* self_; | ||
LpStatsPtr lp_; // level 0 and asp | ||
SolverStats solvers_; // level 0 | ||
SolverVec solver_; // level > 1 | ||
SolverVec accu_; // level > 1 and incremental | ||
TesterStats* tester_; // level > 0 and nonhcfs | ||
uint32 level_; // active stats level | ||
LpStatsPtr lp_; // level 0 and asp | ||
SolverStats solvers_; // level 0 | ||
SolverVec solver_; // level > 1 | ||
SolverVec accu_; // level > 1 and incremental | ||
TesterStats* tester_; // level > 0 and nonhcfs | ||
UserStatsPtr userStats_; // user statistics: only if requested | ||
UserStatsVec userCbs_; // callbacks for user-defined stats | ||
uint32 level_; // active stats level | ||
// For clingo stats interface | ||
class ClingoView : public ClaspStatistics { | ||
public: | ||
|
@@ -614,6 +624,16 @@ void ClaspFacade::Statistics::initLevel(uint32 level) { | |
tester_ = self_->ctx.sccGraph->nonHcfStats(); | ||
} | ||
} | ||
void ClaspFacade::Statistics::addExternal(StatsCallback cb, void* data) { | ||
if (!userStats_.get()) { | ||
userStats_ = new ExternalStatistics(); | ||
} | ||
userCbs_.push_back(UserCallback(cb, data)); | ||
} | ||
|
||
Potassco::Span<ClaspFacade::Statistics::UserCallback> ClaspFacade::Statistics::getExternal() const { | ||
return Potassco::toSpan(userCbs_); | ||
} | ||
void ClaspFacade::Statistics::start(uint32 level) { | ||
// cleanup previous state | ||
solvers_.reset(); | ||
|
@@ -633,6 +653,9 @@ void ClaspFacade::Statistics::start(uint32 level) { | |
} | ||
if (!incremental()) { solver_.release(); } | ||
} | ||
for (UserStatsVec::const_iterator it = userCbs_.begin(), end = userCbs_.end(); it != end; ++it) { | ||
it->first(userStats_.get(), it->second); | ||
} | ||
} | ||
void ClaspFacade::Statistics::end() { | ||
self_->ctx.accuStats(solvers_); // compute solvers = sum(solver[1], ... , solver[n]) | ||
|
@@ -641,6 +664,9 @@ void ClaspFacade::Statistics::end() { | |
solver_[i]->accu(self_->ctx.solverStats(i), true); | ||
solver_[i]->flush(); | ||
} | ||
for (UserStatsVec::const_iterator it = userCbs_.begin(), end = userCbs_.end(); it != end; ++it) { | ||
it->first(userStats_.get(), it->second); | ||
} | ||
if (tester_) { tester_->endStep(); } | ||
if (clingo_) { clingo_->update(*this); } | ||
} | ||
|
@@ -658,6 +684,9 @@ void ClaspFacade::Statistics::accept(StatsVisitor& out, bool final) const { | |
const SolverVec& solver = final ? accu_ : solver_; | ||
const uint32 nThreads = final ? (uint32)accu_.size() : self_->ctx.concurrency(); | ||
const uint32 nSolver = (uint32)solver.size(); | ||
if (userStats_.get() && !userStats_->empty()) { | ||
out.visitExternalStats(userStats_->toStats()); | ||
} | ||
if (nThreads > 1 && nSolver > 1 && out.visitThreads(StatsVisitor::Enter)) { | ||
for (uint32 i = 0, end = std::min(nSolver, nThreads); i != end; ++i) { | ||
out.visitThread(i, *solver[i]); | ||
|
@@ -696,13 +725,17 @@ ClaspFacade::Statistics::ClingoView::ClingoView(const ClaspFacade& f) { | |
keys_.add("problem", problem_.toStats()); | ||
keys_.add("solving", solving_.toStats()); | ||
keys_.add("summary", summary_.toStats()); | ||
|
||
if (f.incremental()) { | ||
accu_ = new Accu(); | ||
accu_->step.bind(*f.accu_.get()); | ||
} | ||
setRoot(keys_.toStats()); | ||
} | ||
void ClaspFacade::Statistics::ClingoView::update(const ClaspFacade::Statistics& stats) { | ||
if (stats.userStats_.get() && !stats.userStats_->empty()) { | ||
keys_.add("userdefined", stats.userStats_->toStats()); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Is there a reason why There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. For consistency, this should be There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Okay. I was just referring to the fact that “user-defined” is a compound adjective and should be written with a hyphen, but if hyphens are not allowed within keys, that’s just how it is 🙂. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Sorry, I forgot to add the "Yep, you are right". I just wanted to express that our keys typically use underscores (and unfortunately sometimes camel-case) instead of hyphens. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I totally understand, thanks for the info … and sorry about the fuss and my pedantry anyway 😄! |
||
} | ||
if (stats.level_ > 0 && accu_.get() && keys_.add("accu", accu_->toStats())) { | ||
accu_->step.addTo(*accu_); | ||
accu_->add("solving", accu_->solving_.toStats()); | ||
|
@@ -914,6 +947,16 @@ bool ClaspFacade::read() { | |
if (!p.more()) { p.reset(); } | ||
return true; | ||
} | ||
|
||
void ClaspFacade::addStatisticsCallback(StatsCallback cb, void* data) { | ||
POTASSCO_REQUIRE(stats_.get(), "Statistics not yet available"); | ||
stats_->addExternal(cb, data); | ||
} | ||
|
||
Potassco::Span<std::pair<ClaspFacade::StatsCallback, void*> > ClaspFacade::getStatisticsCallbacks() const { | ||
return stats_.get() ? stats_->getExternal() : Potassco::toSpan<std::pair<StatsCallback, void*> >(); | ||
} | ||
|
||
void ClaspFacade::prepare(EnumMode enumMode) { | ||
POTASSCO_REQUIRE(solve_.get() && !solving()); | ||
EnumOptions& en = config_->solve; | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For consistency, I’d write “user-defined“ with a hyphen here as well.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yep. Thanks.