// 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;
}
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<simgrid::mc::Checker, CommDetExtension> CommDetExtension::EXTENSION_ID;
/********** State Extension ***********/
static simgrid::xbt::Extension<simgrid::mc::State, StateCommDet> 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<simgrid::mc::PatternCommunication> res;
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);
}
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<PatternCommunication*>& incomplete_pattern = incomplete_communications_pattern[transition->aid_];
pattern->index = initial_pattern.index_comm + incomplete_pattern.size();
if (transition->type_ == Transition::Type::COMM_SEND) {
- auto* send = dynamic_cast<const CommSendTransition*>(transition);
- /* Create comm pattern */
+ auto* send = static_cast<const CommSendTransition*>(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<const CommRecvTransition*>(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<PatternCommunication*>& incomplete_pattern = incomplete_communications_pattern[transition->aid_];
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));
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 */
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<const CommWaitTransition*>(transition), backtracking);
+ case Transition::Type::COMM_WAIT:
+ complete_comm_pattern(static_cast<const CommWaitTransition*>(transition));
+ break;
+ case Transition::Type::WAITANY:
+ // Ignore wait on non-comm
+ if (auto const* wait = dynamic_cast<const CommWaitTransition*>(
+ static_cast<const WaitAnyTransition*>(transition)->get_current_transition()))
+ complete_comm_pattern(wait);
break;
- }
- case Transition::Type::WAITANY: {
- auto const* t = static_cast<const WaitAnyTransition*>(transition)->get_current_transition();
- auto const* wait = dynamic_cast<const CommWaitTransition*>(t);
- if (wait != nullptr) // Ignore wait on non-comm
- complete_comm_pattern(wait, backtracking);
- } break;
default: /* Ignore unhandled transition types */
break;
}
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<State>();