Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
Typo found by lintian
[simgrid.git] / src / mc / api / strategy / MaxMatchComm.hpp
1 /* Copyright (c) 2007-2023. The SimGrid Team. All rights reserved.          */
2
3 /* This program is free software; you can redistribute it and/or modify it
4  * under the terms of the license (GNU LGPL) which comes with this package. */
5
6 #ifndef SIMGRID_MC_WAITSTRATEGY_HPP
7 #define SIMGRID_MC_WAITSTRATEGY_HPP
8
9 #include "src/mc/transition/TransitionComm.hpp"
10
11 namespace simgrid::mc {
12
13 /** Wait MC guiding class that aims at minimizing the number of in-fly communication.
14  *  When possible, it will try to match corresponding in-fly communications. */
15 class MaxMatchComm : public Strategy {
16   /** Stores for each mailbox what kind of transition is waiting on it.
17    *  Negative number means that much recv are waiting on that mailbox, while
18    *  a positiv number means that much send are waiting there. */
19   std::map<unsigned, int> mailbox_;
20     int value_of_state_ = 0; // used to valuate the state. Corresponds to the number of in-fly communications
21     // The two next values are used to save the operation we execute so the next strategy can update its field accordingly
22   Transition::Type last_transition_; 
23   unsigned last_mailbox_ = 0;
24
25 public:
26   void copy_from(const Strategy* strategy) override
27   {
28     const MaxMatchComm* cast_strategy = dynamic_cast<MaxMatchComm const*>(strategy);
29     xbt_assert(cast_strategy != nullptr);
30     for (auto& [id, val] : cast_strategy->mailbox_)
31       mailbox_[id] = val;
32     if (cast_strategy->last_transition_ == Transition::Type::COMM_ASYNC_RECV)
33       mailbox_[cast_strategy->last_mailbox_]--;
34     if (cast_strategy->last_transition_ == Transition::Type::COMM_ASYNC_SEND)
35       mailbox_[cast_strategy->last_mailbox_]++;
36
37     for (auto const& [_, val] : mailbox_)
38         value_of_state_ += std::abs(val);
39   }
40   MaxMatchComm()                     = default;
41   ~MaxMatchComm() override           = default;
42
43   std::pair<aid_t, int> best_transition(bool must_be_todo) const override
44   {
45           std::pair<aid_t, int> min_found = std::make_pair(-1, value_of_state_+2);
46     for (auto const& [aid, actor] : actors_to_run_) {
47         if ((not actor.is_todo() && must_be_todo) || not actor.is_enabled() || actor.is_done())
48             continue;
49
50       int aid_value = value_of_state_;
51       const Transition* transition = actor.get_transition(actor.get_times_considered()).get();
52      
53       const CommRecvTransition* cast_recv = dynamic_cast<CommRecvTransition const*>(transition);
54       if (cast_recv != nullptr) {
55           if (mailbox_.count(cast_recv->get_mailbox()) > 0 and
56               mailbox_.at(cast_recv->get_mailbox()) > 0) { 
57               aid_value--; // This means we have waiting recv corresponding to this recv
58           } else { 
59               aid_value++; 
60           }
61       }
62    
63       const CommSendTransition* cast_send = dynamic_cast<CommSendTransition const*>(transition);
64       if (cast_send != nullptr) {
65           if (mailbox_.count(cast_send->get_mailbox()) > 0 and
66               mailbox_.at(cast_send->get_mailbox()) < 0) {
67               aid_value--; // This means we have waiting recv corresponding to this send
68           }else {
69               aid_value++;
70           }
71       }
72    
73       if (aid_value < min_found.second)
74           min_found = std::make_pair(aid, aid_value);
75     }
76     return min_found;
77   }
78
79
80   void execute_next(aid_t aid, RemoteApp& app) override
81   {
82     const Transition* transition = actors_to_run_.at(aid).get_transition(actors_to_run_.at(aid).get_times_considered()).get();
83     last_transition_             = transition->type_;
84
85     const CommRecvTransition* cast_recv = dynamic_cast<CommRecvTransition const*>(transition);
86     if (cast_recv != nullptr)
87       last_mailbox_ = cast_recv->get_mailbox();
88
89     const CommSendTransition* cast_send = dynamic_cast<CommSendTransition const*>(transition);
90     if (cast_send != nullptr)
91       last_mailbox_ = cast_send->get_mailbox();
92   }
93 };
94
95 } // namespace simgrid::mc
96
97 #endif