X-Git-Url: http://info.iut-bm.univ-fcomte.fr/pub/gitweb/simgrid.git/blobdiff_plain/34bbd19b02db1fb34e82247af7ed00c0fc10d41d..df3ae8662ba574c3eaab705922e941876b1900ae:/src/mc/checker/CommunicationDeterminismChecker.cpp diff --git a/src/mc/checker/CommunicationDeterminismChecker.cpp b/src/mc/checker/CommunicationDeterminismChecker.cpp index c47b508d06..68117addc8 100644 --- a/src/mc/checker/CommunicationDeterminismChecker.cpp +++ b/src/mc/checker/CommunicationDeterminismChecker.cpp @@ -46,11 +46,10 @@ public: // num? res.comm_addr = this->comm_addr; res.type = this->type; - // src_proc? - // dst_proc? + res.src_proc = this->src_proc; res.dst_proc = this->dst_proc; res.mbox = this->mbox; - // tag? + res.tag = this->tag; res.index = this->index; return res; } @@ -84,10 +83,10 @@ struct CommDetExtension { std::string recv_diff; void restore_communications_pattern(const simgrid::mc::State* state); - void deterministic_comm_pattern(aid_t process, const PatternCommunication* comm, bool backtracking); - void get_comm_pattern(const Transition* transition, bool backtracking); - void complete_comm_pattern(const CommWaitTransition* transition, bool backtracking); - void handle_comm_pattern(const Transition* transition, bool backtracking); + void enforce_deterministic_pattern(aid_t process, const PatternCommunication* comm); + void get_comm_pattern(const Transition* transition); + void complete_comm_pattern(const CommWaitTransition* transition); + void handle_comm_pattern(const Transition* transition); }; simgrid::xbt::Extension CommDetExtension::EXTENSION_ID; /********** State Extension ***********/ @@ -102,13 +101,6 @@ public: static simgrid::xbt::Extension EXTENSION_ID; explicit StateCommDet(CommDetExtension* checker) : checker_(checker) { - 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 res; @@ -116,11 +108,7 @@ public: 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 : checker_->initial_communications_pattern) this->communication_indices_.push_back(list_process_comm.index_comm); } @@ -200,45 +188,43 @@ static std::string print_determinism_result(simgrid::mc::CommPatternDifference d return res; } -void CommDetExtension::deterministic_comm_pattern(aid_t actor, const PatternCommunication* comm, bool backtracking) +void CommDetExtension::enforce_deterministic_pattern(aid_t actor, const PatternCommunication* comm) { - if (not backtracking) { - PatternCommunicationList& list = initial_communications_pattern[actor]; - CommPatternDifference diff = compare_comm_pattern(list.list[list.index_comm].get(), comm); - - if (diff != CommPatternDifference::NONE) { - if (comm->type == PatternCommunicationType::send) { - send_deterministic = false; - send_diff = print_determinism_result(diff, actor, comm, list.index_comm + 1); - } else { - recv_deterministic = false; - recv_diff = print_determinism_result(diff, actor, comm, list.index_comm + 1); - } - if (_sg_mc_send_determinism && not send_deterministic) { - XBT_INFO("*********************************************************"); - XBT_INFO("***** Non-send-deterministic communications pattern *****"); - XBT_INFO("*********************************************************"); + PatternCommunicationList& list = initial_communications_pattern[actor]; + CommPatternDifference diff = compare_comm_pattern(list.list[list.index_comm].get(), comm); + + if (diff != CommPatternDifference::NONE) { + if (comm->type == PatternCommunicationType::send) { + send_deterministic = false; + send_diff = print_determinism_result(diff, actor, comm, list.index_comm + 1); + } else { + recv_deterministic = false; + recv_diff = print_determinism_result(diff, actor, comm, list.index_comm + 1); + } + if (_sg_mc_send_determinism && not send_deterministic) { + XBT_INFO("*********************************************************"); + XBT_INFO("***** Non-send-deterministic communications pattern *****"); + XBT_INFO("*********************************************************"); + XBT_INFO("%s", send_diff.c_str()); + api::get().log_state(); + api::get().mc_exit(SIMGRID_MC_EXIT_NON_DETERMINISM); + } else if (_sg_mc_comms_determinism && (not send_deterministic && not recv_deterministic)) { + XBT_INFO("****************************************************"); + XBT_INFO("***** Non-deterministic communications pattern *****"); + XBT_INFO("****************************************************"); + if (not send_diff.empty()) XBT_INFO("%s", send_diff.c_str()); - api::get().log_state(); - api::get().mc_exit(SIMGRID_MC_EXIT_NON_DETERMINISM); - } else if (_sg_mc_comms_determinism && (not send_deterministic && not recv_deterministic)) { - XBT_INFO("****************************************************"); - XBT_INFO("***** Non-deterministic communications pattern *****"); - XBT_INFO("****************************************************"); - if (not send_diff.empty()) - XBT_INFO("%s", send_diff.c_str()); - if (not recv_diff.empty()) - XBT_INFO("%s", recv_diff.c_str()); - api::get().log_state(); - api::get().mc_exit(SIMGRID_MC_EXIT_NON_DETERMINISM); - } + if (not recv_diff.empty()) + XBT_INFO("%s", recv_diff.c_str()); + api::get().log_state(); + api::get().mc_exit(SIMGRID_MC_EXIT_NON_DETERMINISM); } } } /********** Non Static functions ***********/ -void CommDetExtension::get_comm_pattern(const Transition* transition, bool backtracking) +void CommDetExtension::get_comm_pattern(const Transition* transition) { const mc::PatternCommunicationList& initial_pattern = initial_communications_pattern[transition->aid_]; const std::vector& incomplete_pattern = incomplete_communications_pattern[transition->aid_]; @@ -247,50 +233,28 @@ void CommDetExtension::get_comm_pattern(const Transition* transition, bool backt pattern->index = initial_pattern.index_comm + incomplete_pattern.size(); if (transition->type_ == Transition::Type::COMM_SEND) { - auto* send = dynamic_cast(transition); - /* Create comm pattern */ + auto* send = static_cast(transition); + pattern->type = PatternCommunicationType::send; pattern->comm_addr = send->get_comm(); - pattern->mbox = send->get_mailbox(); - pattern->src_proc = send->aid_; - -#if HAVE_SMPI - pattern->tag = 0; // FIXME: replace it by the real tag from the observer -#endif - -#if HAVE_SMPI - // auto send_detached = api::get().check_send_request_detached(request); - if (false) { // send_detached) { - if (initial_communications_pattern_done) { - /* Evaluate comm determinism */ - deterministic_comm_pattern(pattern->src_proc, pattern.get(), backtracking); - initial_communications_pattern[pattern->src_proc].index_comm++; - } else { - /* Store comm pattern */ - initial_communications_pattern[pattern->src_proc].list.push_back(std::move(pattern)); - } - return; - } -#endif + pattern->tag = send->get_tag(); + + // FIXME: Detached sends should be enforced when the receive is waited + } else if (transition->type_ == Transition::Type::COMM_RECV) { auto* recv = static_cast(transition); pattern->type = PatternCommunicationType::receive; pattern->comm_addr = recv->get_comm(); - -#if HAVE_SMPI - pattern->tag = 0; // FIXME: replace it by the real tag from the observer -#endif - pattern->mbox = recv->get_mailbox(); - pattern->dst_proc = recv->aid_; + pattern->tag = recv->get_tag(); } - XBT_DEBUG("Insert incomplete comm pattern %p type:%d for process %ld (comm: %lx)", pattern.get(), (int)pattern->type, - transition->aid_, pattern->comm_addr); + XBT_DEBUG("Insert incomplete comm pattern %p type:%d for process %ld (comm: %" PRIxPTR ")", pattern.get(), + (int)pattern->type, transition->aid_, pattern->comm_addr); incomplete_communications_pattern[transition->aid_].push_back(pattern.release()); } -void CommDetExtension::complete_comm_pattern(const CommWaitTransition* transition, bool backtracking) +void CommDetExtension::complete_comm_pattern(const CommWaitTransition* transition) { /* Complete comm pattern */ std::vector& incomplete_pattern = incomplete_communications_pattern[transition->aid_]; @@ -303,6 +267,7 @@ void CommDetExtension::complete_comm_pattern(const CommWaitTransition* transitio comm_pattern->src_proc = transition->get_sender(); comm_pattern->dst_proc = transition->get_receiver(); + comm_pattern->mbox = transition->get_mailbox(); XBT_DEBUG("Remove incomplete comm pattern for actor %ld at cursor %zd", transition->aid_, std::distance(begin(incomplete_pattern), current_comm_pattern)); @@ -310,7 +275,7 @@ void CommDetExtension::complete_comm_pattern(const CommWaitTransition* transitio if (initial_communications_pattern_done) { /* Evaluate comm determinism */ - deterministic_comm_pattern(transition->aid_, comm_pattern.get(), backtracking); + enforce_deterministic_pattern(transition->aid_, comm_pattern.get()); initial_communications_pattern[transition->aid_].index_comm++; } else { /* Store comm pattern */ @@ -414,35 +379,34 @@ void CommunicationDeterminismChecker::restoreState() auto* transition = state->get_transition(); transition->replay(); - extension->handle_comm_pattern(transition, true); + extension->handle_comm_pattern(transition); /* Update statistics */ api::get().mc_inc_visited_states(); } } -void CommDetExtension::handle_comm_pattern(const Transition* transition, bool backtracking) +void CommDetExtension::handle_comm_pattern(const Transition* transition) { if (not _sg_mc_comms_determinism && not _sg_mc_send_determinism) return; switch (transition->type_) { case Transition::Type::COMM_SEND: - get_comm_pattern(transition, backtracking); + get_comm_pattern(transition); break; case Transition::Type::COMM_RECV: - get_comm_pattern(transition, backtracking); + get_comm_pattern(transition); break; - case Transition::Type::COMM_WAIT: { - complete_comm_pattern(static_cast(transition), backtracking); + case Transition::Type::COMM_WAIT: + complete_comm_pattern(static_cast(transition)); + break; + case Transition::Type::WAITANY: + // Ignore wait on non-comm + if (auto const* wait = dynamic_cast( + static_cast(transition)->get_current_transition())) + complete_comm_pattern(wait); break; - } - case Transition::Type::WAITANY: { - auto const* t = static_cast(transition)->get_current_transition(); - auto const* wait = dynamic_cast(t); - if (wait != nullptr) // Ignore wait on non-comm - complete_comm_pattern(wait, backtracking); - } break; default: /* Ignore unhandled transition types */ break; } @@ -480,7 +444,7 @@ void CommunicationDeterminismChecker::real_run() if (dot_output != nullptr) req_str = api::get().request_get_dot_output(transition); - extension->handle_comm_pattern(transition, false); + extension->handle_comm_pattern(transition); /* Create the new expanded state */ auto next_state = std::make_unique();