Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
add wait guide and mofidication for the heuristic computation
authormlaurent <mathieu.laurent@ens-rennes.fr>
Mon, 20 Mar 2023 15:52:22 +0000 (16:52 +0100)
committermlaurent <mathieu.laurent@ens-rennes.fr>
Mon, 20 Mar 2023 15:52:22 +0000 (16:52 +0100)
src/mc/api/ActorState.hpp
src/mc/api/State.cpp
src/mc/api/guide/WaitGuide.hpp [new file with mode: 0644]
tools/cmake/DefinePackages.cmake

index 97cf05a..d407e5b 100644 (file)
@@ -114,7 +114,7 @@ public:
   }
   void mark_done() { this->state_ = InterleavingType::done; }
 
-  inline Transition* get_transition(unsigned times_considered)
+  inline Transition* get_transition(unsigned times_considered) const
   {
     xbt_assert(times_considered < this->pending_transitions_.size(),
                "Actor %ld does not have a state available transition with `times_considered = %u`,\n"
index a839b28..5247db3 100644 (file)
@@ -5,7 +5,7 @@
 
 #include "src/mc/api/State.hpp"
 #include "src/mc/api/guide/BasicGuide.hpp"
-//#include "src/mc/api/guide/WaitGuide.hpp"
+#include "src/mc/api/guide/WaitGuide.hpp"
 #include "src/mc/explo/Exploration.hpp"
 #include "src/mc/mc_config.hpp"
 
@@ -20,26 +20,26 @@ long State::expended_states_ = 0;
 State::State(RemoteApp& remote_app) : num_(++expended_states_)
 {
   remote_app.get_actors_status(guide_->actors_to_run_);
-  if (_sg_mc_guided == "none")  
-      guide_ = std::make_unique<BasicGuide>();
+  if (_sg_mc_guided == "none")
+    guide_ = std::make_unique<BasicGuide>();
   if (_sg_mc_guided == "nb_wait")
-      guide_ = std::make_unique<BasicGuide>();  
+    guide_ = std::make_unique<WaitGuide>();
   /* Stateful model checking */
   if ((_sg_mc_checkpoint > 0 && (num_ % _sg_mc_checkpoint == 0)) || _sg_mc_termination)
     system_state_ = std::make_shared<simgrid::mc::Snapshot>(num_, remote_app.get_page_store(),
                                                             remote_app.get_remote_process_memory());
 }
 
-State::State(RemoteApp& remote_app, const State* parent_state)
-    : num_(++expended_states_), parent_state_(parent_state)
+State::State(RemoteApp& remote_app, const State* parent_state) : num_(++expended_states_), parent_state_(parent_state)
 {
-    
-    remote_app.get_actors_status(guide_->actors_to_run_);
-    if (_sg_mc_guided == "none")  
-       guide_ = std::make_unique<BasicGuide>();
-    if (_sg_mc_guided == "nb_wait")
-       guide_ = std::make_unique<BasicGuide>();        
-    
+
+  remote_app.get_actors_status(guide_->actors_to_run_);
+  if (_sg_mc_guided == "none")
+    guide_ = std::make_unique<BasicGuide>();
+  if (_sg_mc_guided == "nb_wait")
+    guide_ = std::make_unique<WaitGuide>();
+  *guide_ = *(parent_state->guide_);
+
   /* Stateful model checking */
   if ((_sg_mc_checkpoint > 0 && (num_ % _sg_mc_checkpoint == 0)) || _sg_mc_termination)
     system_state_ = std::make_shared<simgrid::mc::Snapshot>(num_, remote_app.get_page_store(),
@@ -143,5 +143,8 @@ void State::execute_next(aid_t next, RemoteApp& app)
   actor_state.set_transition(std::move(executed_transition), times_considered);
 
   app.wait_for_requests();
+
+  // finally, also update informations in the guide, so it knows how to build a proper child state
+  guide_->execute_next(next, app);
 }
 } // namespace simgrid::mc
diff --git a/src/mc/api/guide/WaitGuide.hpp b/src/mc/api/guide/WaitGuide.hpp
new file mode 100644 (file)
index 0000000..a18f6e3
--- /dev/null
@@ -0,0 +1,80 @@
+/* Copyright (c) 2007-2023. The SimGrid Team. All rights reserved.          */
+
+/* This program is free software; you can redistribute it and/or modify it
+ * under the terms of the license (GNU LGPL) which comes with this package. */
+
+#ifndef SIMGRID_MC_WAITGUIDE_HPP
+#define SIMGRID_MC_WAITGUIDE_HPP
+
+#include "src/mc/transition/Transition.hpp"
+
+namespace simgrid::mc {
+
+/** Wait MC guiding class that aims at minimizing the number of in-fly communication.
+ *  When possible, it will try to take the wait transition. */
+class WaitGuide : public GuidedState {
+  double taken_wait_ = 0;
+  bool taking_wait_  = false;
+
+public:
+  void operator=(const WaitGuide& guide) { taken_wait_ = guide.taken_wait_; }
+
+  bool is_transition_wait(Transition::Type type) const
+  {
+    return type == Transition::Type::WAITANY or type == Transition::Type::BARRIER_WAIT or
+           type == Transition::Type::MUTEX_WAIT or type == Transition::Type::SEM_WAIT;
+  }
+
+  std::pair<aid_t, double> next_transition() const override
+  {
+    std::pair<aid_t, double> if_no_wait = std::make_pair(-1, 0.0);
+    for (auto const& [aid, actor] : actors_to_run_) {
+      if (not actor.is_todo() || not actor.is_enabled() || actor.is_done())
+        continue;
+      if (is_transition_wait(actor.get_transition(actor.get_times_considered())->type_))
+        return std::make_pair(aid, -(taken_wait_ + 1));
+      if_no_wait = std::make_pair(aid, -taken_wait_);
+    }
+    return if_no_wait;
+  }
+
+  /** If we are taking a wait transition, and last transition wasn't a wait, we need to increment the number
+   *  of wait taken. On the opposite, if we took a wait before, and now we are taking another transition, we need
+   *  to decrease the count. */
+  void execute_next(aid_t aid, RemoteApp& app) override
+  {
+    auto& actor = actors_to_run_.at(aid);
+    if ((not taking_wait_) and is_transition_wait(actor.get_transition(actor.get_times_considered())->type_)) {
+      taken_wait_++;
+      taking_wait_ = true;
+      return;
+    }
+    if (taking_wait_ and (not is_transition_wait(actor.get_transition(actor.get_times_considered())->type_))) {
+      taken_wait_--;
+      taking_wait_ = false;
+      return;
+    }
+  }
+
+  void consider_best() override
+  {
+    const auto& [aid, _] = this->next_transition();
+    auto actor           = actors_to_run_.find(aid);
+    if (actor != actors_to_run_.end()) {
+      actor->second.mark_todo();
+      return;
+    }
+    for (auto& [_, actor] : actors_to_run_) {
+      if (actor.is_todo())
+        return;
+      if (actor.is_enabled() and not actor.is_done()) {
+        actor.mark_todo();
+        return;
+      }
+    }
+  }
+};
+
+} // namespace simgrid::mc
+
+#endif
index 7f14976..be3a556 100644 (file)
@@ -614,6 +614,10 @@ set(MC_SRC
   src/mc/mc_private.hpp
   src/mc/mc_record.cpp
 
+  src/mc/api/guide/BasicGuide.hpp
+  src/mc/api/guide/GuidedState.hpp
+  src/mc/api/guide/WaitGuide.hpp
+  
   src/xbt/mmalloc/mm_interface.c
   )