Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
Merge branch 'master' of https://framagit.org/simgrid/simgrid
[simgrid.git] / src / mc / transition / TransitionComm.cpp
1 /* Copyright (c) 2015-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 #include "src/mc/transition/TransitionComm.hpp"
7 #include "simgrid/config.h"
8 #include "xbt/asserts.h"
9 #include "xbt/string.hpp"
10 #if SIMGRID_HAVE_MC
11 #include "src/mc/api/RemoteApp.hpp"
12 #include "src/mc/api/State.hpp"
13 #endif
14
15 #include <sstream>
16
17 XBT_LOG_NEW_DEFAULT_SUBCATEGORY(mc_trans_comm, mc_transition,
18                                 "Logging specific to MC transitions about communications");
19
20 namespace simgrid::mc {
21
22 CommWaitTransition::CommWaitTransition(aid_t issuer, int times_considered, std::stringstream& stream)
23     : Transition(Type::COMM_WAIT, issuer, times_considered)
24 {
25   xbt_assert(stream >> timeout_ >> comm_ >> sender_ >> receiver_ >> mbox_ >> sbuff_ >> rbuff_ >> size_);
26   XBT_DEBUG("CommWaitTransition %s comm:%" PRIxPTR ", sender:%ld receiver:%ld mbox:%u sbuff:%" PRIxPTR
27             " rbuff:%" PRIxPTR " size:%zu",
28             (timeout_ ? "timeout" : "no-timeout"), comm_, sender_, receiver_, mbox_, sbuff_, rbuff_, size_);
29 }
30 std::string CommWaitTransition::to_string(bool verbose) const
31 {
32   auto res = xbt::string_printf("WaitComm(from %ld to %ld, mbox=%u, %s", sender_, receiver_, mbox_,
33                                 (timeout_ ? "timeout" : "no timeout"));
34   if (verbose) {
35     res += ", sbuff=" + xbt::string_printf("%" PRIxPTR, sbuff_) + ", size=" + std::to_string(size_);
36     res += ", rbuff=" + xbt::string_printf("%" PRIxPTR, rbuff_);
37   }
38   res += ")";
39   return res;
40 }
41 bool CommWaitTransition::depends(const Transition* other) const
42 {
43   if (other->type_ < type_)
44     return other->depends(this);
45
46   if (const auto* wait = dynamic_cast<const CommWaitTransition*>(other)) {
47     if (timeout_ || wait->timeout_)
48       return true; // Timeouts are not considered by the independence theorem, thus assumed dependent
49
50     if (sbuff_ == wait->sbuff_ && rbuff_ == wait->rbuff_)
51       return false;
52     if (sbuff_ != 0 && rbuff_ != 0 && wait->sbuff_ != 0 && wait->rbuff_ != 0 && rbuff_ != wait->sbuff_ &&
53         rbuff_ != wait->rbuff_ && rbuff_ != sbuff_)
54       return false;
55
56     return true;
57   }
58
59   return false; // Comm transitions are INDEP with non-comm transitions
60 }
61 CommTestTransition::CommTestTransition(aid_t issuer, int times_considered, std::stringstream& stream)
62     : Transition(Type::COMM_TEST, issuer, times_considered)
63 {
64   xbt_assert(stream >> comm_ >> sender_ >> receiver_ >> mbox_ >> sbuff_ >> rbuff_ >> size_);
65   XBT_DEBUG("CommTestTransition comm:%" PRIxPTR ", sender:%ld receiver:%ld mbox:%u sbuff:%" PRIxPTR " rbuff:%" PRIxPTR
66             " size:%zu",
67             comm_, sender_, receiver_, mbox_, sbuff_, rbuff_, size_);
68 }
69 std::string CommTestTransition::to_string(bool verbose) const
70 {
71   auto res = xbt::string_printf("TestComm(from %ld to %ld, mbox=%u", sender_, receiver_, mbox_);
72   if (verbose) {
73     res += ", sbuff=" + xbt::string_printf("%" PRIxPTR, sbuff_) + ", size=" + std::to_string(size_);
74     res += ", rbuff=" + xbt::string_printf("%" PRIxPTR, rbuff_);
75   }
76   res += ")";
77   return res;
78 }
79 bool CommTestTransition::depends(const Transition* other) const
80 {
81   if (other->type_ < type_)
82     return other->depends(this);
83
84   if (dynamic_cast<const CommTestTransition*>(other) != nullptr)
85     return false; // Test & Test are independent
86
87   if (const auto* wait = dynamic_cast<const CommWaitTransition*>(other)) {
88     if (wait->timeout_)
89       return true; // Timeouts are not considered by the independence theorem, thus assumed dependent
90
91     /* Wait & Test are independent */
92     return false;
93   }
94
95   return false; // Comm transitions are INDEP with non-comm transitions
96 }
97
98 CommRecvTransition::CommRecvTransition(aid_t issuer, int times_considered, std::stringstream& stream)
99     : Transition(Type::COMM_ASYNC_RECV, issuer, times_considered)
100 {
101   xbt_assert(stream >> comm_ >> mbox_ >> rbuff_ >> tag_);
102 }
103 std::string CommRecvTransition::to_string(bool verbose) const
104 {
105   auto res = xbt::string_printf("iRecv(mbox=%u", mbox_);
106   if (verbose)
107     res += ", rbuff=" + xbt::string_printf("%" PRIxPTR, rbuff_);
108   res += ")";
109   return res;
110 }
111 bool CommRecvTransition::depends(const Transition* other) const
112 {
113   if (other->type_ < type_)
114     return other->depends(this);
115
116   if (const auto* recv = dynamic_cast<const CommRecvTransition*>(other))
117     return mbox_ == recv->mbox_;
118
119   if (dynamic_cast<const CommSendTransition*>(other) != nullptr)
120     return false;
121
122   if (const auto* test = dynamic_cast<const CommTestTransition*>(other)) {
123     if (mbox_ != test->mbox_)
124       return false;
125
126     if ((aid_ != test->sender_) && (aid_ != test->receiver_) && (test->rbuff_ != rbuff_))
127       return false;
128
129     return true; // DEP with other send transitions
130   }
131
132   if (auto* wait = dynamic_cast<const CommWaitTransition*>(other)) {
133     if (wait->timeout_)
134       return true;
135
136     if (mbox_ != wait->mbox_)
137       return false;
138
139     if ((aid_ != wait->sender_) && (aid_ != wait->receiver_) && (wait->rbuff_ != rbuff_))
140       return false;
141
142     return true; // DEP with other wait transitions
143   }
144
145   return false; // Comm transitions are INDEP with non-comm transitions
146 }
147
148 CommSendTransition::CommSendTransition(aid_t issuer, int times_considered, std::stringstream& stream)
149     : Transition(Type::COMM_ASYNC_SEND, issuer, times_considered)
150 {
151   xbt_assert(stream >> comm_ >> mbox_ >> sbuff_ >> size_ >> tag_);
152   XBT_DEBUG("SendTransition comm:%" PRIxPTR " mbox:%u sbuff:%" PRIxPTR " size:%zu", comm_, mbox_, sbuff_, size_);
153 }
154 std::string CommSendTransition::to_string(bool verbose = false) const
155 {
156   auto res = xbt::string_printf("iSend(mbox=%u", mbox_);
157   if (verbose)
158     res += ", sbuff=" + xbt::string_printf("%" PRIxPTR, sbuff_) + ", size=" + std::to_string(size_);
159   res += ")";
160   return res;
161 }
162
163 bool CommSendTransition::depends(const Transition* other) const
164 {
165   if (other->type_ < type_)
166     return other->depends(this);
167
168   if (const auto* other_isend = dynamic_cast<const CommSendTransition*>(other))
169     return mbox_ == other_isend->mbox_;
170
171   if (dynamic_cast<const CommRecvTransition*>(other) != nullptr)
172     return false;
173
174   if (const auto* test = dynamic_cast<const CommTestTransition*>(other)) {
175     if (mbox_ != test->mbox_)
176       return false;
177
178     if ((aid_ != test->sender_) && (aid_ != test->receiver_) && (test->sbuff_ != sbuff_))
179       return false;
180
181     return true; // DEP with other test transitions
182   }
183
184   if (const auto* wait = dynamic_cast<const CommWaitTransition*>(other)) {
185     if (wait->timeout_)
186       return true;
187
188     if (mbox_ != wait->mbox_)
189       return false;
190
191     if ((aid_ != wait->sender_) && (aid_ != wait->receiver_) && (wait->sbuff_ != sbuff_))
192       return false;
193
194     return true; // DEP with other wait transitions
195   }
196
197   return false; // Comm transitions are INDEP with non-comm transitions
198 }
199
200 } // namespace simgrid::mc