Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
91fcf9250111780a641618df18e769168b83aa6f
[simgrid.git] / src / smpi / internals / instr_smpi.cpp
1 /* Copyright (c) 2010-2018. The SimGrid Team.
2  * All rights reserved.                                                     */
3
4 /* This program is free software; you can redistribute it and/or modify it
5  * under the terms of the license (GNU LGPL) which comes with this package. */
6
7 #include "private.hpp"
8 #include <boost/algorithm/string.hpp>
9 #include <cctype>
10 #include <cstdarg>
11 #include <cwchar>
12 #include <deque>
13 #include <simgrid/sg_config.hpp>
14 #include <string>
15
16 XBT_LOG_NEW_DEFAULT_SUBCATEGORY(instr_smpi, instr, "Tracing SMPI");
17
18 static std::unordered_map<std::string, std::deque<std::string>*> keys;
19
20 static const char* smpi_colors[] = {"recv",
21                                     "1 0 0",
22                                     "irecv",
23                                     "1 0.52 0.52",
24                                     "send",
25                                     "0 0 1",
26                                     "isend",
27                                     "0.52 0.52 1",
28                                     "sendrecv",
29                                     "0 1 1",
30                                     "wait",
31                                     "1 1 0",
32                                     "waitall",
33                                     "0.78 0.78 0",
34                                     "waitany",
35                                     "0.78 0.78 0.58",
36                                     "test",
37                                     "0.52 0.52 0",
38
39                                     "allgather",
40                                     "1 0 0",
41                                     "allgatherv",
42                                     "1 0.52 0.52",
43                                     "allreduce",
44                                     "1 0 1",
45                                     "alltoall",
46                                     "0.52 0 1",
47                                     "alltoallv",
48                                     "0.78 0.52 1",
49                                     "barrier",
50                                     "0 0.78 0.78",
51                                     "bcast",
52                                     "0 0.78 0.39",
53                                     "gather",
54                                     "1 1 0",
55                                     "gatherv",
56                                     "1 1 0.52",
57                                     "reduce",
58                                     "0 1 0",
59                                     "reducescatter",
60                                     "0.52 1 0.52",
61                                     "scan",
62                                     "1 0.58 0.23",
63                                     "exscan",
64                                     "1 0.54 0.25",
65                                     "scatterv",
66                                     "0.52 0 0.52",
67                                     "scatter",
68                                     "1 0.74 0.54",
69
70                                     "computing",
71                                     "0 1 1",
72                                     "sleeping",
73                                     "0 0.5 0.5",
74
75                                     "init",
76                                     "0 1 0",
77                                     "finalize",
78                                     "0 1 0",
79
80                                     "put",
81                                     "0.3 1 0",
82                                     "get",
83                                     "0 1 0.3",
84                                     "accumulate",
85                                     "1 0.3 0",
86                                     "rput",
87                                     "0.3 1 0",
88                                     "rget",
89                                     "0 1 0.3",
90                                     "raccumulate",
91                                     "1 0.3 0",
92                                     "compare_and_swap",
93                                     "0.3 1 0",
94                                     "get_accumulate",
95                                     "0 1 0.3",
96                                     "rget_accumulate",
97                                     "1 0.3 0",
98                                     "win_fence",
99                                     "1 0 0.3",
100                                     "win_post",
101                                     "1 0 0.8",
102                                     "win_wait",
103                                     "1 0.8 0",
104                                     "win_start",
105                                     "0.8 0 1",
106                                     "win_complete",
107                                     "0.8 1 0",
108                                     "win_lock",
109                                     "1 0 0.3",
110                                     "win_unlock",
111                                     "1 0 0.3",
112                                     "win_lock_all",
113                                     "1 0 0.8",
114                                     "win_unlock_all",
115                                     "1 0.8 0",
116                                     "win_flush",
117                                     "1 0 0.3",
118                                     "win_flush_local",
119                                     "1 0 0.8",
120                                     "win_flush_all",
121                                     "1 0.8 0",
122                                     "win_flush_local_all",
123                                     "1 0 0.3",
124                                     "",
125                                     ""};
126
127 static const char* instr_find_color(const char* state)
128 {
129   std::string target = std::string(state);
130   boost::algorithm::to_lower(target);
131   const char* ret     = nullptr;
132   unsigned int i      = 0;
133   const char* current = smpi_colors[i];
134   while (current != nullptr) {
135     if (target == current                          // exact match
136         || strstr(target.c_str(), current) != 0) { // as substring
137       ret = smpi_colors[i + 1];
138       break;
139     }
140     i+=2;
141     current = smpi_colors[i];
142   }
143   return ret;
144 }
145
146 XBT_PRIVATE container_t smpi_container(int rank)
147 {
148   return simgrid::instr::Container::byName(std::string("rank-") + std::to_string(rank));
149 }
150
151 static std::string TRACE_smpi_put_key(int src, int dst, int tag, int send)
152 {
153   // get the deque for src#dst
154   std::string aux =
155       std::to_string(src) + "#" + std::to_string(dst) + "#" + std::to_string(tag) + "#" + std::to_string(send);
156   auto it = keys.find(aux);
157   std::deque<std::string>* d;
158
159   if (it == keys.end()) {
160     d         = new std::deque<std::string>;
161     keys[aux] = d;
162   } else
163     d = it->second;
164
165   //generate the key
166   static unsigned long long counter = 0;
167   counter++;
168   std::string key =
169       std::to_string(src) + "_" + std::to_string(dst) + "_" + std::to_string(tag) + "_" + std::to_string(counter);
170
171   //push it
172   d->push_back(key);
173
174   return key;
175 }
176
177 static std::string TRACE_smpi_get_key(int src, int dst, int tag, int send)
178 {
179   std::string key;
180   std::string aux = std::to_string(src) + "#" + std::to_string(dst) + "#" + std::to_string(tag) + "#" +
181                     std::to_string(send == 1 ? 0 : 1);
182   auto it = keys.find(aux);
183   if (it == keys.end()) {
184     // first posted
185     key = TRACE_smpi_put_key(src, dst, tag, send);
186   } else {
187     key = it->second->front();
188     it->second->pop_front();
189   }
190   return key;
191 }
192
193 static std::unordered_map<smx_actor_t, std::string> process_category;
194
195 void TRACE_internal_smpi_set_category (const char *category)
196 {
197   if (not TRACE_smpi_is_enabled())
198     return;
199
200   //declare category
201   TRACE_category (category);
202
203   if (category != nullptr)
204     process_category[SIMIX_process_self()] = category;
205 }
206
207 const char *TRACE_internal_smpi_get_category ()
208 {
209   if (not TRACE_smpi_is_enabled())
210     return nullptr;
211
212   auto it = process_category.find(SIMIX_process_self());
213   return (it == process_category.end()) ? nullptr : it->second.c_str();
214 }
215
216 void TRACE_smpi_release()
217 {
218   for (auto const& elm : keys)
219     delete elm.second;
220 }
221
222 void TRACE_smpi_init(int rank)
223 {
224   if (not TRACE_smpi_is_enabled())
225     return;
226
227   std::string str = std::string("rank-") + std::to_string(rank);
228
229   container_t father;
230   if (TRACE_smpi_is_grouped()){
231     father = simgrid::instr::Container::byNameOrNull(sg_host_self_get_name());
232   }else{
233     father = simgrid::instr::Container::getRoot();
234   }
235   xbt_assert(father != nullptr, "Could not find a parent for mpi rank %s at function %s", str.c_str(), __func__);
236   father->createChild(str, "MPI");
237 #if HAVE_PAPI
238   container_t container   = simgrid::instr::Container::byName(str);
239   papi_counter_t counters = smpi_process()->papi_counters();
240
241   for (auto const& it : counters) {
242     /**
243      * Check whether this variable already exists or not. Otherwise, it will be created
244      * multiple times but only the last one would be used...
245      */
246     if (s_type::getOrNull(it.first.c_str(), container->type_) == nullptr) {
247       Type::variableNew(it.first.c_str(), "", container->type_);
248     }
249   }
250 #endif
251 }
252
253 void TRACE_smpi_finalize(int rank)
254 {
255   if (not TRACE_smpi_is_enabled())
256     return;
257
258   smpi_container(rank)->removeFromParent();
259 }
260
261 void TRACE_smpi_computing_init(int rank)
262 {
263  //first use, initialize the color in the trace
264  if (TRACE_smpi_is_enabled() && TRACE_smpi_is_computing())
265    smpi_container(rank)->getState("MPI_STATE")->addEntityValue("computing", instr_find_color("computing"));
266 }
267
268 void TRACE_smpi_computing_in(int rank, double amount)
269 {
270   if (TRACE_smpi_is_enabled() && TRACE_smpi_is_computing())
271     smpi_container(rank)
272         ->getState("MPI_STATE")
273         ->pushEvent("computing", new simgrid::instr::CpuTIData("compute", amount));
274 }
275
276 void TRACE_smpi_computing_out(int rank)
277 {
278   if (TRACE_smpi_is_enabled() && TRACE_smpi_is_computing())
279     smpi_container(rank)->getState("MPI_STATE")->popEvent();
280 }
281
282 void TRACE_smpi_sleeping_in(int rank, double duration)
283 {
284   if (TRACE_smpi_is_enabled() && TRACE_smpi_is_sleeping())
285     smpi_container(rank)
286         ->getState("MPI_STATE")
287         ->pushEvent("sleeping", new simgrid::instr::CpuTIData("sleep", duration));
288 }
289
290 void TRACE_smpi_sleeping_out(int rank)
291 {
292   if (TRACE_smpi_is_enabled() && not TRACE_smpi_is_sleeping())
293     smpi_container(rank)->getState("MPI_STATE")->popEvent();
294 }
295
296 void TRACE_smpi_testing_in(int rank)
297 {
298   //do not forget to set the color first, otherwise this will explode
299   if (not TRACE_smpi_is_enabled())
300     return;
301
302   simgrid::instr::StateType* state = smpi_container(rank)->getState("MPI_STATE");
303   state->addEntityValue("test");
304   state->pushEvent("test", new simgrid::instr::NoOpTIData("test"));
305 }
306
307 void TRACE_smpi_testing_out(int rank)
308 {
309   if (TRACE_smpi_is_enabled())
310     smpi_container(rank)->getState("MPI_STATE")->popEvent();
311 }
312
313 void TRACE_smpi_comm_in(int rank, const char* operation, simgrid::instr::TIData* extra)
314 {
315   if (not TRACE_smpi_is_enabled()) {
316     delete extra;
317     return;
318   }
319
320   simgrid::instr::StateType* state = smpi_container(rank)->getState("MPI_STATE");
321   state->addEntityValue(operation, instr_find_color(operation));
322   state->pushEvent(operation, extra);
323 }
324
325 void TRACE_smpi_comm_out(int rank)
326 {
327   if (TRACE_smpi_is_enabled())
328     smpi_container(rank)->getState("MPI_STATE")->popEvent();
329 }
330
331 void TRACE_smpi_send(int rank, int src, int dst, int tag, int size)
332 {
333   if (not TRACE_smpi_is_enabled())
334     return;
335
336   std::string key = TRACE_smpi_get_key(src, dst, tag, 1);
337
338   XBT_DEBUG("Send tracing from %d to %d, tag %d, with key %s", src, dst, tag, key.c_str());
339   simgrid::instr::Container::getRoot()->getLink("MPI_LINK")->startEvent(smpi_container(rank), "PTP", key, size);
340 }
341
342 void TRACE_smpi_recv(int src, int dst, int tag)
343 {
344   if (not TRACE_smpi_is_enabled())
345     return;
346
347   std::string key = TRACE_smpi_get_key(src, dst, tag, 0);
348
349   XBT_DEBUG("Recv tracing from %d to %d, tag %d, with key %s", src, dst, tag, key.c_str());
350   simgrid::instr::Container::getRoot()->getLink("MPI_LINK")->endEvent(smpi_container(dst), "PTP", key);
351 }