Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
Automatically remove nodes from parents
[simgrid.git] / src / mc / api / State.cpp
index 8430f52..fb2a806 100644 (file)
@@ -120,6 +120,21 @@ std::pair<aid_t, int> State::next_transition_guided() const
   return strategy_->next_transition();
 }
 
+aid_t State::next_odpor_transition() const
+{
+  const auto first_single_process_branch =
+      std::find_if(wakeup_tree_.begin(), wakeup_tree_.end(),
+                   [=](const odpor::WakeupTreeNode* node) { return node->is_single_process(); });
+  if (first_single_process_branch != wakeup_tree_.end()) {
+    const auto* wakeup_tree_node = *first_single_process_branch;
+    xbt_assert(wakeup_tree_node->get_sequence().size() == 1, "We claimed that the selected branch "
+                                                             "contained only a single process, yet more "
+                                                             "than one process was actually contained in it :(");
+    return wakeup_tree_node->get_first_actor();
+  }
+  return -1;
+}
+
 // This should be done in GuidedState, or at least interact with it
 std::shared_ptr<Transition> State::execute_next(aid_t next, RemoteApp& app)
 {
@@ -132,7 +147,7 @@ std::shared_ptr<Transition> State::execute_next(aid_t next, RemoteApp& app)
   // when simcall_handle will be called on it
   auto& actor_state                        = strategy_->actors_to_run_.at(next);
   const unsigned times_considered          = actor_state.do_consider();
-  const auto* expected_executed_transition = actor_state.get_transition(times_considered);
+  const auto* expected_executed_transition = actor_state.get_transition(times_considered).get();
   xbt_assert(expected_executed_transition != nullptr,
              "Expected a transition with %u times considered to be noted in actor %ld", times_considered, next);
 
@@ -173,4 +188,47 @@ std::unordered_set<aid_t> State::get_backtrack_set() const
   return actors;
 }
 
+void State::seed_wakeup_tree_if_needed(const odpor::Execution& prior)
+{
+  // TODO: Note that the next action taken by the actor may be updated
+  // after it executes. But we will have already inserted it into the
+  // 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) {
+      wakeup_tree_.insert(prior, odpor::PartialExecution{strategy_->actors_to_run_.at(next).get_transition()});
+    }
+  }
+}
+
+void State::sprout_tree_from_parent_state()
+{
+  xbt_assert(parent_state_ != nullptr, "Attempting to construct a wakeup tree for the root state "
+                                       "(or what appears to be, rather for state without a parent defined)");
+  const auto p      = parent_state_->get_transition_out()->aid_;
+  const auto branch = std::find_if(
+      parent_state_->wakeup_tree_.begin(), parent_state_->wakeup_tree_.end(),
+      [=](const odpor::WakeupTreeNode* node) { return node->is_single_process() && node->get_first_actor() == p; });
+  xbt_assert(branch != parent_state_->wakeup_tree_.end(),
+             "Attempted to create a subtree from the wakeup tree of the parent "
+             "state using actor `%ld`, but no such subtree could be found. "
+             "This implies that the wakeup tree management is broken, "
+             "and more specifically that subtree formation is not working "
+             "as intended; for if this state was generated by the parent "
+             "having taken an action by actor `%ld`, this implies that "
+             "ODPOR found `%ld` as a candidate branch prior",
+             p, p, p);
+  this->wakeup_tree_ = odpor::WakeupTree::make_subtree_rooted_at(*branch);
+}
+
+void State::remove_subtree_starting_with(aid_t p)
+{
+  const auto branch = std::find_if(wakeup_tree_.begin(), wakeup_tree_.end(), [=](const odpor::WakeupTreeNode* node) {
+    return node->is_single_process() && node->get_first_actor() == p;
+  });
+  xbt_assert(branch != wakeup_tree_.end(), "Attempted to remove a subtree of this state's "
+                                           "wakeup tree that does not exist");
+  this->wakeup_tree_.remove_subtree_rooted_at(*branch);
+}
+
 } // namespace simgrid::mc