Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
make mc::State extendable so that CommDet does not polute it in any case
[simgrid.git] / src / mc / checker / CommunicationDeterminismChecker.cpp
index a1a136b..8fc0415 100644 (file)
@@ -23,6 +23,48 @@ std::vector<std::vector<simgrid::mc::PatternCommunication*>> incomplete_communic
 
 /********** Static functions ***********/
 
+namespace simgrid {
+namespace mc {
+
+class StateCommDet {
+  // State* state_;
+
+public:
+  std::vector<std::vector<simgrid::mc::PatternCommunication>> incomplete_comm_pattern_;
+  std::vector<unsigned> communication_indices_;
+
+  static simgrid::xbt::Extension<simgrid::mc::State, StateCommDet> EXTENSION_ID;
+  explicit StateCommDet(State* /* ptr*/) //: state_(ptr)
+  {
+    copy_incomplete_comm_pattern();
+    copy_index_comm_pattern();
+  }
+
+  void copy_incomplete_comm_pattern()
+  {
+    incomplete_comm_pattern_.clear();
+    const unsigned long maxpid = api::get().get_maxpid();
+    for (unsigned long i = 0; i < maxpid; i++) {
+      std::vector<simgrid::mc::PatternCommunication> res;
+      for (auto const& comm : incomplete_communications_pattern[i])
+        res.push_back(comm->dup());
+      incomplete_comm_pattern_.push_back(std::move(res));
+    }
+  }
+
+  void copy_index_comm_pattern()
+  {
+    communication_indices_.clear();
+    for (auto const& list_process_comm : initial_communications_pattern)
+      this->communication_indices_.push_back(list_process_comm.index_comm);
+  }
+};
+
+simgrid::xbt::Extension<simgrid::mc::State, StateCommDet> StateCommDet::EXTENSION_ID;
+
+} // namespace mc
+} // namespace simgrid
+
 static simgrid::mc::CommPatternDifference compare_comm_pattern(const simgrid::mc::PatternCommunication* comm1,
                                                                const simgrid::mc::PatternCommunication* comm2)
 {
@@ -57,11 +99,13 @@ static void patterns_copy(std::vector<simgrid::mc::PatternCommunication*>& dest,
 static void restore_communications_pattern(simgrid::mc::State* state)
 {
   for (size_t i = 0; i < initial_communications_pattern.size(); i++)
-    initial_communications_pattern[i].index_comm = state->communication_indices_[i];
+    initial_communications_pattern[i].index_comm =
+        state->extension<simgrid::mc::StateCommDet>()->communication_indices_[i];
 
   const unsigned long maxpid = api::get().get_maxpid();
   for (unsigned long i = 0; i < maxpid; i++)
-    patterns_copy(incomplete_communications_pattern[i], state->incomplete_comm_pattern_[i]);
+    patterns_copy(incomplete_communications_pattern[i],
+                  state->extension<simgrid::mc::StateCommDet>()->incomplete_comm_pattern_[i]);
 }
 
 static char* print_determinism_result(simgrid::mc::CommPatternDifference diff, aid_t process,
@@ -113,8 +157,6 @@ static void update_comm_pattern(simgrid::mc::PatternCommunication* comm_pattern,
   auto dst_proc = api::get().get_dst_actor(comm_addr);
   comm_pattern->src_proc = src_proc->get_pid();
   comm_pattern->dst_proc = dst_proc->get_pid();
-  comm_pattern->src_host = &api::get().get_actor_host_name(src_proc);
-  comm_pattern->dst_host = &api::get().get_actor_host_name(dst_proc);
 
   if (comm_pattern->data.empty()) {
     comm_pattern->data = api::get().get_pattern_comm_data(comm_addr);
@@ -190,7 +232,6 @@ void CommunicationDeterminismChecker::get_comm_pattern(smx_simcall_t request, Ca
     pattern->comm_addr = api::get().get_comm_isend_raw_addr(request);
     pattern->rdv       = api::get().get_pattern_comm_rdv(pattern->comm_addr);
     pattern->src_proc  = api::get().get_pattern_comm_src_proc(pattern->comm_addr);
-    pattern->src_host  = &api::get().get_actor_host_name(issuer);
 
 #if HAVE_SMPI
     pattern->tag = api::get().get_smpi_request_tag(request, simgrid::simix::Simcall::COMM_ISEND);
@@ -220,7 +261,6 @@ void CommunicationDeterminismChecker::get_comm_pattern(smx_simcall_t request, Ca
 #endif
     pattern->rdv = api::get().get_pattern_comm_rdv(pattern->comm_addr);
     pattern->dst_proc = api::get().get_pattern_comm_dst_proc(pattern->comm_addr);
-    pattern->dst_host = &api::get().get_actor_host_name(issuer);
   } else
     xbt_die("Unexpected call_type %i", (int)call_type);
 
@@ -254,7 +294,10 @@ void CommunicationDeterminismChecker::complete_comm_pattern(RemotePtr<kernel::ac
   }
 }
 
-CommunicationDeterminismChecker::CommunicationDeterminismChecker(Session* session) : Checker(session) {}
+CommunicationDeterminismChecker::CommunicationDeterminismChecker(Session* session) : Checker(session)
+{
+  StateCommDet::EXTENSION_ID = simgrid::mc::State::extension_create<StateCommDet>();
+}
 
 CommunicationDeterminismChecker::~CommunicationDeterminismChecker() = default;
 
@@ -270,7 +313,7 @@ std::vector<std::string> CommunicationDeterminismChecker::get_textual_trace() //
 {
   std::vector<std::string> trace;
   for (auto const& state : stack_)
-    trace.push_back(state->transition_.to_string());
+    trace.push_back(state->get_transition()->to_string());
   return trace;
 }
 
@@ -290,7 +333,7 @@ void CommunicationDeterminismChecker::log_state() // override
       XBT_INFO("%s", this->send_diff);
     }
   }
-  XBT_INFO("Expanded states = %lu", expanded_states_count_);
+  XBT_INFO("Expanded states = %ld", State::get_expanded_states());
   XBT_INFO("Visited states = %lu", api::get().mc_get_visited_states());
   XBT_INFO("Executed transitions = %lu", Transition::get_executed_transitions());
   XBT_INFO("Send-deterministic : %s", this->send_deterministic ? "Yes" : "No");
@@ -305,8 +348,8 @@ void CommunicationDeterminismChecker::prepare()
   initial_communications_pattern.resize(maxpid);
   incomplete_communications_pattern.resize(maxpid);
 
-  ++expanded_states_count_;
-  auto initial_state = std::make_unique<State>(expanded_states_count_);
+  auto initial_state = std::make_unique<State>();
+  initial_state->extension_set(new StateCommDet(initial_state.get()));
 
   XBT_DEBUG("********* Start communication determinism verification *********");
 
@@ -357,7 +400,7 @@ void CommunicationDeterminismChecker::restoreState()
     if (state == stack_.back())
       break;
 
-    int req_num                    = state->transition_.times_considered_;
+    int req_num                    = state->get_transition()->times_considered_;
     const s_smx_simcall* saved_req = &state->executed_req_;
     xbt_assert(saved_req);
 
@@ -369,8 +412,8 @@ void CommunicationDeterminismChecker::restoreState()
 
     /* TODO : handle test and testany simcalls */
     CallType call = MC_get_call_type(req);
-    state->transition_.execute();
-    handle_comm_pattern(call, req, req_num, 1);
+    state->get_transition()->replay();
+    handle_comm_pattern(call, req, req_num, true);
 
     /* Update statistics */
     api::get().mc_inc_visited_states();
@@ -412,41 +455,38 @@ void CommunicationDeterminismChecker::real_run()
     State* cur_state = stack_.back().get();
 
     XBT_DEBUG("**************************************************");
-    XBT_DEBUG("Exploration depth = %zu (state = %d, interleaved processes = %zu)", stack_.size(), cur_state->num_,
+    XBT_DEBUG("Exploration depth = %zu (state = %ld, interleaved processes = %zu)", stack_.size(), cur_state->num_,
               cur_state->count_todo());
 
     /* Update statistics */
     api::get().mc_inc_visited_states();
 
-    bool found_transition = false;
+    int next_transition = -1;
     if (stack_.size() <= (std::size_t)_sg_mc_max_depth)
-      found_transition = api::get().mc_state_choose_request(cur_state);
+      next_transition = cur_state->next_transition();
 
-    if (found_transition && visited_state == nullptr) {
-      aid_t aid         = cur_state->transition_.aid_;
-      int req_num = cur_state->transition_.times_considered_;
+    if (next_transition >= 0 && visited_state == nullptr) {
+      cur_state->execute_next(next_transition);
+
+      int req_num       = cur_state->get_transition()->times_considered_;
       smx_simcall_t req = &cur_state->executed_req_;
 
-      XBT_DEBUG("Execute: %s", cur_state->transition_.to_string().c_str());
+      XBT_DEBUG("Execute: %s", cur_state->get_transition()->to_string().c_str());
 
       std::string req_str;
       if (dot_output != nullptr)
-        req_str = api::get().request_get_dot_output(aid, req_num);
+        req_str = api::get().request_get_dot_output(cur_state->get_transition());
 
       /* TODO : handle test and testany simcalls */
       CallType call = CallType::NONE;
       if (_sg_mc_comms_determinism || _sg_mc_send_determinism)
         call = MC_get_call_type(req);
 
-      /* Answer the request */
-      cur_state->transition_.execute();
-      /* After this call req is no longer useful */
-
-      handle_comm_pattern(call, req, req_num, 0);
+      handle_comm_pattern(call, req, req_num, false);
 
       /* Create the new expanded state */
-      ++expanded_states_count_;
-      auto next_state = std::make_unique<State>(expanded_states_count_);
+      auto next_state = std::make_unique<State>();
+      next_state->extension_set(new StateCommDet(next_state.get()));
 
       /* If comm determinism verification, we cannot stop the exploration if some communications are not finished (at
        * least, data are transferred). These communications  are incomplete and they cannot be analyzed and compared
@@ -454,7 +494,7 @@ void CommunicationDeterminismChecker::real_run()
       bool compare_snapshots = this->initial_communications_pattern_done && all_communications_are_finished();
 
       if (_sg_mc_max_visited_states != 0)
-        visited_state = visited_states_.addVisitedState(expanded_states_count_, next_state.get(), compare_snapshots);
+        visited_state = visited_states_.addVisitedState(next_state->num_, next_state.get(), compare_snapshots);
       else
         visited_state = nullptr;
 
@@ -467,10 +507,10 @@ void CommunicationDeterminismChecker::real_run()
         }
 
         if (dot_output != nullptr)
-          fprintf(dot_output, "\"%d\" -> \"%d\" [%s];\n", cur_state->num_, next_state->num_, req_str.c_str());
+          fprintf(dot_output, "\"%ld\" -> \"%ld\" [%s];\n", cur_state->num_, next_state->num_, req_str.c_str());
 
       } else if (dot_output != nullptr)
-        fprintf(dot_output, "\"%d\" -> \"%d\" [%s];\n", cur_state->num_,
+        fprintf(dot_output, "\"%ld\" -> \"%ld\" [%s];\n", cur_state->num_,
                 visited_state->original_num == -1 ? visited_state->num : visited_state->original_num, req_str.c_str());
 
       stack_.push_back(std::move(next_state));
@@ -478,7 +518,7 @@ void CommunicationDeterminismChecker::real_run()
       if (stack_.size() > (std::size_t)_sg_mc_max_depth)
         XBT_WARN("/!\\ Max depth reached! /!\\ ");
       else if (visited_state != nullptr)
-        XBT_DEBUG("State already visited (equal to state %d), exploration stopped on this path.",
+        XBT_DEBUG("State already visited (equal to state %ld), exploration stopped on this path.",
                   visited_state->original_num == -1 ? visited_state->num : visited_state->original_num);
       else
         XBT_DEBUG("There are no more processes to interleave. (depth %zu)", stack_.size());
@@ -486,7 +526,7 @@ void CommunicationDeterminismChecker::real_run()
       this->initial_communications_pattern_done = true;
 
       /* Trash the current state, no longer needed */
-      XBT_DEBUG("Delete state %d at depth %zu", cur_state->num_, stack_.size());
+      XBT_DEBUG("Delete state %ld at depth %zu", cur_state->num_, stack_.size());
       stack_.pop_back();
 
       visited_state = nullptr;
@@ -498,16 +538,16 @@ void CommunicationDeterminismChecker::real_run()
         stack_.pop_back();
         if (state->count_todo() && stack_.size() < (std::size_t)_sg_mc_max_depth) {
           /* We found a back-tracking point, let's loop */
-          XBT_DEBUG("Back-tracking to state %d at depth %zu", state->num_, stack_.size() + 1);
+          XBT_DEBUG("Back-tracking to state %ld at depth %zu", state->num_, stack_.size() + 1);
           stack_.push_back(std::move(state));
 
           this->restoreState();
 
-          XBT_DEBUG("Back-tracking to state %d at depth %zu done", stack_.back()->num_, stack_.size());
+          XBT_DEBUG("Back-tracking to state %ld at depth %zu done", stack_.back()->num_, stack_.size());
 
           break;
         } else {
-          XBT_DEBUG("Delete state %d at depth %zu", state->num_, stack_.size() + 1);
+          XBT_DEBUG("Delete state %ld at depth %zu", state->num_, stack_.size() + 1);
         }
       }
     }