diff --git a/src/backends/multicore/multi_event_stream.hpp b/src/backends/multicore/multi_event_stream.hpp index 9b3ce70511af37be5cd39ab0dcc92d52a1af1faf..06e334d40c1060b2750d6eae98cee6aac4d37906 100644 --- a/src/backends/multicore/multi_event_stream.hpp +++ b/src/backends/multicore/multi_event_stream.hpp @@ -129,6 +129,7 @@ public: } } + friend std::ostream& operator<<(std::ostream& out, const multi_event_stream& m); private: using span_type = std::pair<size_type, size_type>; @@ -138,6 +139,41 @@ private: size_type remaining_ = 0; }; + +inline std::ostream& operator<<(std::ostream& out, const multi_event_stream& m) { + auto n = m.n_streams(); + + out << "\n["; + unsigned i = 0; + for (unsigned ev_i = 0; ev_i<m.ev_.size(); ++ev_i) { + while (m.span_[i].second<=ev_i && i<n) ++i; + if (i<n) { + out << util::strprintf(" % 7d ", i); + } + else { + out << " ?"; + } + } + out << "\n["; + + i = 0; + for (unsigned ev_i = 0; ev_i<m.ev_.size(); ++ev_i) { + while (m.span_[i].second<=ev_i && i<n) ++i; + + bool discarded = i<n && m.span_[i].first>ev_i; + bool marked = i<n && m.mark_[i]>ev_i; + + if (discarded) { + out << " x"; + } + else { + out << util::strprintf(" % 7.3f%c", m.ev_[ev_i].time, marked?'*':' '); + } + } + out << "]\n"; + return out; +} + } // namespace multicore } // namespace nest } // namespace mc diff --git a/src/fvm_multicell.hpp b/src/fvm_multicell.hpp index 2a7bee9efef4b1cfc89c87e35073881c6d321ef0..571b600d409b75617e272fff1ca83e8cb7c58aef 100644 --- a/src/fvm_multicell.hpp +++ b/src/fvm_multicell.hpp @@ -106,7 +106,7 @@ public: // Query integration completion state. bool integration_complete() const { - return !integration_running_; + return min_remaining_steps_==0; } // Query per-cell time state. @@ -143,7 +143,7 @@ public: /// Add an event for processing in next integration stage. void add_event(value_type ev_time, target_handle h, value_type weight) { - EXPECTS(!integration_running_); + EXPECTS(integration_complete()); staged_events_.push_back(deliverable_event(ev_time, h, weight)); } @@ -265,22 +265,20 @@ private: /// max time step for integration [ms] value_type dt_max_ = 0; - /// flag: true after a call to `setup_integration()`; reset - /// once integration to `tfinal_` is complete. - bool integration_running_ = false; - /// minimum number of integration steps left in integration period. + // zero => integration complete. unsigned min_remaining_steps_ = 0; void compute_min_remaining() { auto tmin = min_time(); min_remaining_steps_ = tmin>=tfinal_? 0: 1 + (unsigned)((tfinal_-tmin)/dt_max_); - integration_running_ = min_remaining_steps_>0; } void decrement_min_remaining() { - if (min_remaining_steps_>0) --min_remaining_steps_; - integration_running_ = min_remaining_steps_>0; + EXPECTS(min_remaining_steps_>0); + if (!--min_remaining_steps_) { + compute_min_remaining(); + } } /// events staged for upcoming integration stage @@ -884,15 +882,18 @@ void fvm_multicell<Backend>::reset() { // Reset integration state. tfinal_ = 0; dt_max_ = 0; - integration_running_ = false; + min_remaining_steps_ = 0; staged_events_.clear(); events_->clear(); + + EXPECTS(integration_complete()); + EXPECTS(!has_pending_events()); } template <typename Backend> void fvm_multicell<Backend>::step_integration() { - EXPECTS(integration_running_); + EXPECTS(!integration_complete()); PE("current"); memory::fill(current_, 0.); @@ -945,14 +946,9 @@ void fvm_multicell<Backend>::step_integration() { threshold_watcher_.test(); // are we there yet? - if (!min_remaining_steps_) { - compute_min_remaining(); - } - else { - decrement_min_remaining(); - } + decrement_min_remaining(); - EXPECTS(integration_running_ || !has_pending_events()); + EXPECTS(!integration_complete() || !has_pending_events()); } } // namespace fvm