Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
Add ODPOR "backtracking" logic
authorMaxwell Pirtle <maxwellpirtle@gmail.com>
Mon, 15 May 2023 08:50:25 +0000 (10:50 +0200)
committerMaxwell Pirtle <maxwellpirtle@gmail.com>
Tue, 16 May 2023 07:51:21 +0000 (09:51 +0200)
src/mc/api/State.cpp
src/mc/api/State.hpp
src/mc/explo/DFSExplorer.cpp
src/mc/explo/odpor/WakeupTree.cpp
src/mc/transition/TransitionRandom.hpp

index 2488c33..1c40e31 100644 (file)
@@ -219,7 +219,8 @@ void State::seed_wakeup_tree_if_needed(const odpor::Execution& prior)
   // tree and decided upon "happens-before" at that point for different
   // executions :(
   if (wakeup_tree_.empty()) {
-    if (const aid_t next = std::get<0>(next_transition_guided()); next >= 0) {
+    strategy_->consider_best();
+    if (const aid_t next = std::get<0>(strategy_->next_transition()); next >= 0) {
       wakeup_tree_.insert(prior, odpor::PartialExecution{strategy_->actors_to_run_.at(next).get_transition()});
     }
   }
index 4b6b123..d951ed9 100644 (file)
@@ -152,6 +152,8 @@ public:
    */
   void remove_subtree_starting_with(aid_t p);
 
+  bool has_empty_tree() const { return this->wakeup_tree_.empty(); }
+
   /**
    * @brief
    */
index 4b2d631..27df977 100644 (file)
@@ -173,6 +173,11 @@ void DFSExplorer::run()
       // (rather than following the partial execution of a
       // wakeup tree). This corresponds to lines 9 to 13 of
       // the ODPOR pseudocode
+      //
+      // INVARIANT: The execution sequence should be consistent
+      // with the state when seeding the tree. If the sequence
+      // gets out of sync with the state, selection will not
+      // work as we intend
       state->seed_wakeup_tree_if_needed(execution_seq_);
     }
 
@@ -375,6 +380,12 @@ void DFSExplorer::run()
 
 std::shared_ptr<State> DFSExplorer::best_opened_state()
 {
+  if (reduction_mode_ == ReductionMode::odpor) {
+    const auto first =
+        std::find_if(stack_.rbegin(), stack_.rend(), [](const auto& state) { return !state->has_empty_tree(); });
+    return *first;
+  }
+
   int best_prio = 0; // cache the value for the best priority found so far (initialized to silence gcc)
   auto best     = end(opened_states_);   // iterator to the state to explore having the best priority
   auto valid    = begin(opened_states_); // iterator marking the limit between states still to explore, and already
index 33a0fb6..5e967eb 100644 (file)
@@ -162,6 +162,10 @@ void WakeupTree::insert(const Execution& E, const PartialExecution& w)
       return;
     }
   }
+  xbt_die("Insertion should always succeed with the root node (which contains no "
+          "prior execution). If we've reached this point, this implies either that "
+          "the wakeup tree traversal is broken or that computation of the shortest "
+          "sequence to insert into the tree is broken");
 }
 
 } // namespace simgrid::mc::odpor
\ No newline at end of file
index ba00821..374d69d 100644 (file)
@@ -17,7 +17,13 @@ class RandomTransition : public Transition {
 public:
   std::string to_string(bool verbose) const override;
   RandomTransition(aid_t issuer, int times_considered, std::stringstream& stream);
-  bool depends(const Transition* other) const override { return aid_ == other->aid_; } // Independent with any other transition
+  bool depends(const Transition* other) const override
+  {
+    if (other->type_ < type_)
+      return other->depends(this);
+
+    return aid_ == other->aid_;
+  } // Independent with any other transition
 };
 
 } // namespace simgrid::mc