Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
fix build. no nullptr with std::string
[simgrid.git] / src / instr / instr_interface.cpp
1 /* Copyright (c) 2010-2022. 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 <simgrid/Exception.hpp>
7 #include <simgrid/kernel/routing/NetPoint.hpp>
8 #include <simgrid/s4u/Host.hpp>
9 #include <xbt/random.hpp>
10
11 #include "src/instr/instr_private.hpp"
12 #include "src/kernel/resource/StandardLinkImpl.hpp"
13 #include <algorithm>
14 #include <cmath>
15
16 enum class InstrUserVariable { DECLARE, SET, ADD, SUB };
17
18 XBT_LOG_NEW_DEFAULT_SUBCATEGORY (instr_api, instr, "API");
19
20 std::set<std::string, std::less<>> created_categories;
21 std::set<std::string, std::less<>> declared_marks;
22 std::set<std::string, std::less<>> user_host_variables;
23 std::set<std::string, std::less<>> user_vm_variables;
24 std::set<std::string, std::less<>> user_link_variables;
25
26 static void instr_user_variable(double time, const char* resource, const std::string& variable_name,
27                                 const std::string& parent_type, double value, InstrUserVariable what,
28                                 const std::string& color, std::set<std::string, std::less<>>* filter)
29 {
30   /* safe switches. tracing has to be activated and if platform is not traced, we don't allow user variables */
31   if (not TRACE_is_enabled() || not TRACE_needs_platform())
32     return;
33
34   // check if variable is already declared
35   auto created = filter->find(variable_name);
36   if (what == InstrUserVariable::DECLARE) {
37     if (created == filter->end()) { // not declared yet
38       filter->insert(variable_name);
39       instr_new_user_variable_type(parent_type, variable_name, color);
40     }
41   } else {
42     if (created != filter->end()) { // declared, let's work
43       simgrid::instr::VariableType* variable =
44           simgrid::instr::Container::by_name(resource)->get_variable(variable_name);
45       switch (what) {
46         case InstrUserVariable::SET:
47           variable->set_event(time, value);
48           break;
49         case InstrUserVariable::ADD:
50           variable->add_event(time, value);
51           break;
52         case InstrUserVariable::SUB:
53           variable->sub_event(time, value);
54           break;
55         default:
56           THROW_IMPOSSIBLE;
57       }
58     }
59   }
60 }
61
62 static void instr_user_srcdst_variable(double time, const char* src, const char* dst, const std::string& variable,
63                                        const std::string& parent_type, double value, InstrUserVariable what)
64 {
65   const simgrid::kernel::routing::NetPoint* src_elm = sg_netpoint_by_name_or_null(src);
66   xbt_assert(src_elm, "Element '%s' not found!", src);
67
68   const simgrid::kernel::routing::NetPoint* dst_elm = sg_netpoint_by_name_or_null(dst);
69   xbt_assert(dst_elm, "Element '%s' not found!", dst);
70
71   std::vector<simgrid::kernel::resource::StandardLinkImpl*> route;
72   simgrid::kernel::routing::NetZoneImpl::get_global_route(src_elm, dst_elm, route, nullptr);
73   for (auto const& link : route)
74     instr_user_variable(time, link->get_cname(), variable, parent_type, value, what, "", &user_link_variables);
75 }
76
77 namespace simgrid {
78 namespace instr {
79
80 void declare_host_variable(const std::string& variable, const std::string& color)
81 {
82   instr_user_variable(0, nullptr, variable, "HOST", 0, InstrUserVariable::DECLARE, color, &user_host_variables);
83 }
84
85 void set_host_variable(const s4u::Host* host, const std::string& variable, double value, double time)
86 {
87   instr_user_variable(time, host->get_cname(), variable, "HOST", value, InstrUserVariable::SET, "",
88                       &user_host_variables);
89 }
90
91 void add_host_variable(const s4u::Host* host, const std::string& variable, double value, double time)
92 {
93   instr_user_variable(time, host->get_cname(), variable, "HOST", value, InstrUserVariable::ADD, "",
94                       &user_host_variables);
95 }
96
97 void sub_host_variable(const s4u::Host* host, const std::string& variable, double value, double time)
98 {
99   instr_user_variable(time, host->get_cname(), variable, "HOST", value, InstrUserVariable::SUB, "",
100                       &user_host_variables);
101 }
102
103 const std::set<std::string, std::less<>>& get_host_variables()
104 {
105   return user_host_variables;
106 }
107
108 void declare_link_variable(const std::string& variable, const std::string& color)
109 {
110   instr_user_variable(0, nullptr, variable, "LINK", 0, InstrUserVariable::DECLARE, color, &user_link_variables);
111 }
112
113 void set_link_variable(const s4u::Link* link, const std::string& variable, double value, double time)
114 {
115   instr_user_variable(time, link->get_cname(), variable, "LINK", value, InstrUserVariable::SET, "",
116                       &user_link_variables);
117 }
118
119 void set_link_variable(const s4u::Host* src, const s4u::Host* dst, const std::string& variable, double value,
120                        double time)
121 {
122   instr_user_srcdst_variable(time, src->get_cname(), dst->get_cname(), variable, "LINK", value, InstrUserVariable::SET);
123 }
124
125 void add_link_variable(const s4u::Link* link, const std::string& variable, double value, double time)
126 {
127   instr_user_variable(time, link->get_cname(), variable, "LINK", value, InstrUserVariable::ADD, "",
128                       &user_link_variables);
129 }
130
131 void add_link_variable(const s4u::Host* src, const s4u::Host* dst, const std::string& variable, double value,
132                        double time)
133 {
134   instr_user_srcdst_variable(time, src->get_cname(), dst->get_cname(), variable, "LINK", value, InstrUserVariable::ADD);
135 }
136
137 void sub_link_variable(const s4u::Link* link, const std::string& variable, double value, double time)
138 {
139   instr_user_variable(time, link->get_cname(), variable, "LINK", value, InstrUserVariable::SUB, "",
140                       &user_link_variables);
141 }
142
143 void sub_link_variable(const s4u::Host* src, const s4u::Host* dst, const std::string& variable, double value,
144                        double time)
145 {
146   instr_user_srcdst_variable(time, src->get_cname(), dst->get_cname(), variable, "LINK", value, InstrUserVariable::SUB);
147 }
148
149 const std::set<std::string, std::less<>>& get_link_variables()
150 {
151   return user_link_variables;
152 }
153
154 void declare_mark(const std::string& mark_type)
155 {
156   /* safe switches. tracing has to be activated and if platform is not traced, we can't deal with marks */
157   if (not TRACE_is_enabled() || not TRACE_needs_platform())
158     return;
159
160   // check if mark_type is already declared
161   if (declared_marks.find(mark_type) != declared_marks.end()) {
162     throw TracingError(XBT_THROW_POINT,
163                        xbt::string_printf("mark_type with name (%s) is already declared", mark_type.c_str()));
164   }
165
166   XBT_DEBUG("MARK,declare %s", mark_type.c_str());
167   Container::get_root()->get_type()->by_name_or_create<EventType>(mark_type);
168   declared_marks.emplace(mark_type);
169 }
170
171 void declare_mark_value(const std::string& mark_type, const std::string& mark_value, const std::string& mark_color)
172 {
173   /* safe switches. tracing has to be activated and if platform is not traced, we can't deal with marks */
174   if (not TRACE_is_enabled() || not TRACE_needs_platform())
175     return;
176
177   auto* type = static_cast<EventType*>(Container::get_root()->get_type()->by_name(mark_type));
178   if (not type) {
179     throw TracingError(XBT_THROW_POINT,
180                        xbt::string_printf("mark_type with name (%s) is not declared", mark_type.c_str()));
181   } else {
182     XBT_DEBUG("MARK, declare_value %s %s %s", mark_type.c_str(), mark_value.c_str(), mark_color.c_str());
183     type->add_entity_value(mark_value, mark_color);
184   }
185 }
186
187 void mark(const std::string& mark_type, const std::string& mark_value)
188 {
189   /* safe switches. tracing has to be activated and if platform is not traced, we can't deal with marks */
190   if (not TRACE_is_enabled() || not TRACE_needs_platform())
191     return;
192
193   // check if mark_type is already declared
194   auto* type = static_cast<EventType*>(Container::get_root()->get_type()->by_name(mark_type));
195   if (not type) {
196     throw TracingError(XBT_THROW_POINT,
197                        xbt::string_printf("mark_type with name (%s) is not declared", mark_type.c_str()));
198   } else {
199     XBT_DEBUG("MARK %s %s", mark_type.c_str(), mark_value.c_str());
200     new NewEvent(simgrid_get_clock(), Container::get_root(), type, type->get_entity_value(mark_value));
201   }
202 }
203
204 const std::set<std::string, std::less<>>& get_marks()
205 {
206   return declared_marks;
207 }
208
209 void declare_tracing_category(const std::string& name, const std::string& color)
210 {
211   /* safe switches. tracing has to be activated and if platform is not traced, we can't deal with categories */
212   if (not TRACE_is_enabled() || not TRACE_needs_platform() || not TRACE_categorized())
213     return;
214
215   // check if category is already created
216   if (created_categories.find(name) != created_categories.end())
217     return;
218
219   created_categories.emplace(name);
220
221   // define final_color
222   std::string final_color;
223   if (color.empty()) {
224     // generate a random color
225     double red   = simgrid::xbt::random::uniform_real(0.0, std::nextafter(1.0, 2.0));
226     double green = simgrid::xbt::random::uniform_real(0.0, std::nextafter(1.0, 2.0));
227     double blue  = simgrid::xbt::random::uniform_real(0.0, std::nextafter(1.0, 2.0));
228     final_color  = std::to_string(red) + " " + std::to_string(green) + " " + std::to_string(blue);
229   } else {
230     final_color = std::string(color);
231   }
232
233   XBT_DEBUG("CAT,declare %s, \"%s\" \"%s\"", name.c_str(), color.c_str(), final_color.c_str());
234
235   // define the type of this category on top of hosts and links
236   instr_new_variable_type(name, final_color);
237 }
238
239 const std::set<std::string, std::less<>>& get_tracing_categories()
240 {
241   return created_categories;
242 }
243
244 } // namespace instr
245 } // namespace simgrid
246
247 static xbt_dynar_t instr_set_to_dynar(const std::set<std::string, std::less<>>& filter)
248 {
249   if (not TRACE_is_enabled() || not TRACE_needs_platform())
250     return nullptr;
251
252   xbt_dynar_t ret = xbt_dynar_new (sizeof(char*), &xbt_free_ref);
253   for (auto const& name : filter)
254     xbt_dynar_push_as(ret, char*, xbt_strdup(name.c_str()));
255
256   return ret;
257 }
258
259 /** @ingroup TRACE_category
260  *  @brief Declare a new category with a random color.
261  *
262  *  This function should be used to define a user category. The category can be used to differentiate the tasks that
263  *  are created during the simulation (for example, tasks from server1, server2, or request tasks, computation tasks,
264  *  communication tasks). All resource utilization (host power and link bandwidth) will be classified according to the
265  *  task category. Tasks that do not belong to a category are not traced. The color for the category that is being
266  *  declared is random. This function has no effect if a category with the same name has been already declared.
267  *
268  * See @ref outcomes_vizu for details on how to trace the (categorized) resource utilization.
269  *
270  *  @param category The name of the new tracing category to be created.
271  *
272  *  @see TRACE_category_with_color
273  */
274 void TRACE_category(const char *category)
275 {
276   simgrid::instr::declare_tracing_category(category);
277 }
278
279 /** @ingroup TRACE_category
280  *  @brief Declare a new category with a color.
281  *
282  *  Same as #TRACE_category, but let user specify a color encoded as an RGB-like string with three floats from 0 to 1.
283  *  So, to specify a red color, pass "1 0 0" as color parameter. A light-gray color can be specified using "0.7 0.7 0.7"
284  *   as color. This function has no effect if a category with the same name has been already declared.
285  *
286  * See @ref outcomes_vizu for details on how to trace the (categorized) resource utilization.
287  *
288  *  @param category The name of the new tracing category to be created.
289  *  @param color The color of the category (see @ref outcomes_vizu to
290  *  know how to correctly specify the color)
291  *
292  */
293 void TRACE_category_with_color (const char *category, const char *color)
294 {
295   simgrid::instr::declare_tracing_category(category, color);
296 }
297
298 /** @ingroup TRACE_category
299  *  @brief Get declared categories
300  *
301  * This function should be used to get categories that were already declared with #TRACE_category or with
302  * #TRACE_category_with_color.
303  *
304  * See @ref outcomes_vizu for details on how to trace the (categorized) resource utilization.
305  *
306  * @return A dynar with the declared categories, must be freed with xbt_dynar_free.
307  *
308  */
309 xbt_dynar_t TRACE_get_categories ()
310 {
311   if (not TRACE_is_enabled() || not TRACE_categorized())
312     return nullptr;
313   return instr_set_to_dynar(created_categories);
314 }
315
316 /** @ingroup TRACE_mark
317  * @brief Declare a new type for tracing mark.
318  *
319  * This function declares a new Paje event type in the trace file that can be used by simulators to declare
320  * application-level marks. This function is independent of which API is used in SimGrid.
321  *
322  * @param mark_type The name of the new type.
323  *
324  * @see TRACE_mark
325  */
326 void TRACE_declare_mark(const char *mark_type)
327 {
328   simgrid::instr::declare_mark(mark_type);
329 }
330
331 /** @ingroup TRACE_mark
332  * @brief Declare a new colored value for a previously declared mark type.
333  *
334  * This function declares a new colored value for a Paje event type in the trace file that can be used by simulators to
335  * declare application-level marks. This function is independent of which API is used in SimGrid. The color needs to be
336  * a string with three numbers separated by spaces in the range [0,1].
337  * A light-gray color can be specified using "0.7 0.7 0.7" as color. If a nullptr color is provided, the color used will
338  * be white ("1 1 1").
339  *
340  * @param mark_type The name of the new type.
341  * @param mark_value The name of the new value for this type.
342  * @param mark_color The color of the new value for this type.
343  *
344  * @see TRACE_mark
345  */
346 void TRACE_declare_mark_value_with_color (const char *mark_type, const char *mark_value, const char *mark_color)
347 {
348   simgrid::instr::declare_mark_value(mark_type, mark_value, mark_color);
349 }
350
351 /** @ingroup TRACE_mark
352  * @brief Declare a new value for a previously declared mark type.
353  *
354  * This function declares a new value for a Paje event type in the trace file that can be used by simulators to declare
355  * application-level marks. This function is independent of which API is used in SimGrid. Calling this function is the
356  * same as calling @ref TRACE_declare_mark_value_with_color with a nullptr color.
357  *
358  * @param mark_type The name of the new type.
359  * @param mark_value The name of the new value for this type.
360  *
361  * @see TRACE_mark
362  */
363 void TRACE_declare_mark_value (const char *mark_type, const char *mark_value)
364 {
365   simgrid::instr::declare_mark_value(mark_type, mark_value);
366 }
367
368 /**
369  * @ingroup TRACE_mark
370  * @brief Create a new instance of a tracing mark type.
371  *
372  * This function creates a mark in the trace file. The first parameter had to be previously declared using
373  * #TRACE_declare_mark, the second is the identifier for this mark instance. We recommend that the mark_value is a
374  * unique value for the whole simulation. Nevertheless, this is not a strong requirement: the trace will be valid even
375  * if there are multiple mark identifiers for the same trace.
376  *
377  * @param mark_type The name of the type for which the new instance will belong.
378  * @param mark_value The name of the new instance mark.
379  *
380  * @see TRACE_declare_mark
381  */
382 void TRACE_mark(const char *mark_type, const char *mark_value)
383 {
384   simgrid::instr::mark(mark_type, mark_value);
385 }
386
387 /** @ingroup TRACE_mark
388  *  @brief Get declared marks
389  *
390  * This function should be used to get marks that were already declared with #TRACE_declare_mark.
391  *
392  * @return A dynar with the declared marks, must be freed with xbt_dynar_free.
393  */
394 xbt_dynar_t TRACE_get_marks ()
395 {
396   if (not TRACE_is_enabled())
397     return nullptr;
398
399   return instr_set_to_dynar(declared_marks);
400 }
401
402 /** @ingroup TRACE_API
403  *  @brief Creates a file with the topology of the platform file used for the simulator.
404  *
405  *  The graph topology will have the following properties: all hosts, links and routers of the platform file are mapped
406  *  to graph nodes; routes are mapped to edges.
407  *  The platform's zones are not represented in the output.
408  *
409  *  @param filename The name of the file that will hold the graph.
410  *
411  *  @return 1 of successful, 0 otherwise.
412  */
413 int TRACE_platform_graph_export_graphviz (const char *filename)
414 {
415   simgrid::instr::platform_graph_export_graphviz(filename);
416   return 1;
417 }
418
419 /*
420  * Derived functions that use instr_user_variable and TRACE_user_srcdst_variable. They were previously defined as
421  * pre-processors directives, but were transformed into functions so the user can track them using gdb.
422  */
423
424 /* for VM variables */
425 /** @ingroup TRACE_user_variables
426  *  @brief Declare a new user variable associated to VMs.
427  *
428  *  Declare a user variable that will be associated to VMs. A user vm variable can be used to trace user variables
429  *  such as the number of tasks in a VM, the number of clients in an application (for VMs), and so on. The color
430  *  associated to this new variable will be random.
431  *
432  *  @param variable The name of the new variable to be declared.
433  *
434  *  @see TRACE_vm_variable_declare_with_color
435  */
436 void TRACE_vm_variable_declare (const char *variable)
437 {
438   instr_user_variable(0, nullptr, variable, "VM", 0, InstrUserVariable::DECLARE, "", &user_vm_variables);
439 }
440
441 /** @ingroup TRACE_user_variables
442  *  @brief Declare a new user variable associated to VMs with a color.
443  *
444  *  Same as #TRACE_vm_variable_declare, but associated a color to the newly created user host variable. The color needs
445  *  to be a string with three numbers separated by spaces in the range [0,1].
446  *  A light-gray color can be specified using "0.7 0.7 0.7" as color.
447  *
448  *  @param variable The name of the new variable to be declared.
449  *  @param color The color for the new variable.
450  */
451 void TRACE_vm_variable_declare_with_color (const char *variable, const char *color)
452 {
453   instr_user_variable(0, nullptr, variable, "VM", 0, InstrUserVariable::DECLARE, color, &user_vm_variables);
454 }
455
456 /** @ingroup TRACE_user_variables
457  *  @brief Set the value of a variable of a host.
458  *
459  *  @param vm The name of the VM to be considered.
460  *  @param variable The name of the variable to be considered.
461  *  @param value The new value of the variable.
462  *
463  *  @see TRACE_vm_variable_declare, TRACE_vm_variable_add, TRACE_vm_variable_sub
464  */
465 void TRACE_vm_variable_set (const char *vm, const char *variable, double value)
466 {
467   TRACE_vm_variable_set_with_time(simgrid_get_clock(), vm, variable, value);
468 }
469
470 /** @ingroup TRACE_user_variables
471  *  @brief Add a value to a variable of a VM.
472  *
473  *  @param vm The name of the VM to be considered.
474  *  @param variable The name of the variable to be considered.
475  *  @param value The value to be added to the variable.
476  *
477  *  @see TRACE_vm_variable_declare, TRACE_vm_variable_set, TRACE_vm_variable_sub
478  */
479 void TRACE_vm_variable_add (const char *vm, const char *variable, double value)
480 {
481   TRACE_vm_variable_add_with_time(simgrid_get_clock(), vm, variable, value);
482 }
483
484 /** @ingroup TRACE_user_variables
485  *  @brief Subtract a value from a variable of a VM.
486  *
487  *  @param vm The name of the vm to be considered.
488  *  @param variable The name of the variable to be considered.
489  *  @param value The value to be subtracted from the variable.
490  *
491  *  @see TRACE_vm_variable_declare, TRACE_vm_variable_set, TRACE_vm_variable_add
492  */
493 void TRACE_vm_variable_sub (const char *vm, const char *variable, double value)
494 {
495   TRACE_vm_variable_sub_with_time(simgrid_get_clock(), vm, variable, value);
496 }
497
498 /** @ingroup TRACE_user_variables
499  *  @brief Set the value of a variable of a VM at a given timestamp.
500  *
501  *  Same as #TRACE_vm_variable_set, but let user specify  the time used to trace it. Users can specify a time that
502  *  is not the simulated clock time as defined by the core  simulator. This allows a fine-grain control of time
503  *  definition, but should be used with caution since the trace can be inconsistent if resource utilization traces are
504  *  also traced.
505  *
506  *  @param time The timestamp to be used to tag this change of value.
507  *  @param vm The name of the VM to be considered.
508  *  @param variable The name of the variable to be considered.
509  *  @param value The new value of the variable.
510  *
511  *  @see TRACE_vm_variable_declare, TRACE_vm_variable_add_with_time, TRACE_vm_variable_sub_with_time
512  */
513 void TRACE_vm_variable_set_with_time (double time, const char *vm, const char *variable, double value)
514 {
515   instr_user_variable(time, vm, variable, "VM", value, InstrUserVariable::SET, "", &user_vm_variables);
516 }
517
518 /** @ingroup TRACE_user_variables
519  *  @brief Add a value to a variable of a VM at a given timestamp.
520  *
521  *  Same as #TRACE_vm_variable_add, but let user specify the time used to trace it. Users can specify a time that
522  *  is not the simulated clock time as defined by the core simulator. This allows a fine-grain control of time
523  *  definition, but should be used with caution since the trace can be inconsistent if resource utilization traces are
524  *  also traced.
525  *
526  *  @param time The timestamp to be used to tag this change of value.
527  *  @param vm The name of the VM to be considered.
528  *  @param variable The name of the variable to be considered.
529  *  @param value The value to be added to the variable.
530  *
531  *  @see TRACE_vm_variable_declare, TRACE_vm_variable_set_with_time, TRACE_vm_variable_sub_with_time
532  */
533 void TRACE_vm_variable_add_with_time (double time, const char *vm, const char *variable, double value)
534 {
535   instr_user_variable(time, vm, variable, "VM", value, InstrUserVariable::ADD, "", &user_vm_variables);
536 }
537
538 /** @ingroup TRACE_user_variables
539  *  @brief Subtract a value from a variable of a VM at a given timestamp.
540  *
541  *  Same as #TRACE_vm_variable_sub, but let user specify the time used to trace it. Users can specify a time that
542  *  is not the simulated clock time as defined by the core  simulator. This allows a fine-grain control of time
543  *  definition, but should be used with caution since the trace can be inconsistent if resource utilization traces are
544  *  also traced.
545  *
546  *  @param time The timestamp to be used to tag this change of value.
547  *  @param vm The name of the VM to be considered.
548  *  @param variable The name of the variable to be considered.
549  *  @param value The value to be subtracted from the variable.
550  *
551  *  @see TRACE_vm_variable_declare, TRACE_vm_variable_set_with_time, TRACE_vm_variable_add_with_time
552  */
553 void TRACE_vm_variable_sub_with_time (double time, const char *vm, const char *variable, double value)
554 {
555   instr_user_variable(time, vm, variable, "VM", value, InstrUserVariable::SUB, "", &user_vm_variables);
556 }
557
558 /* for host variables */
559 /** @ingroup TRACE_user_variables
560  *  @brief Declare a new user variable associated to hosts.
561  *
562  *  Declare a user variable that will be associated to hosts.
563  *  A user host variable can be used to trace user variables such as the number of tasks in a server, the number of
564  *  clients in an application (for hosts), and so on. The color associated to this new variable will be random.
565  *
566  *  @param variable The name of the new variable to be declared.
567  *
568  *  @see TRACE_host_variable_declare_with_color
569  */
570 void TRACE_host_variable_declare (const char *variable)
571 {
572   instr_user_variable(0, nullptr, variable, "HOST", 0, InstrUserVariable::DECLARE, "", &user_host_variables);
573 }
574
575 /** @ingroup TRACE_user_variables
576  *  @brief Declare a new user variable associated to hosts with a color.
577  *
578  *  Same as #TRACE_host_variable_declare, but associated a color to the newly created user host variable. The color
579  *  needs to be a string with three numbers separated by spaces in the range [0,1].
580  *  A light-gray color can be specified using "0.7 0.7 0.7" as color.
581  *
582  *  @param variable The name of the new variable to be declared.
583  *  @param color The color for the new variable.
584  */
585 void TRACE_host_variable_declare_with_color (const char *variable, const char *color)
586 {
587   instr_user_variable(0, nullptr, variable, "HOST", 0, InstrUserVariable::DECLARE, color, &user_host_variables);
588 }
589
590 /** @ingroup TRACE_user_variables
591  *  @brief Set the value of a variable of a host.
592  *
593  *  @param host The name of the host to be considered.
594  *  @param variable The name of the variable to be considered.
595  *  @param value The new value of the variable.
596  *
597  *  @see TRACE_host_variable_declare, TRACE_host_variable_add, TRACE_host_variable_sub
598  */
599 void TRACE_host_variable_set (const char *host, const char *variable, double value)
600 {
601   TRACE_host_variable_set_with_time(simgrid_get_clock(), host, variable, value);
602 }
603
604 /** @ingroup TRACE_user_variables
605  *  @brief Add a value to a variable of a host.
606  *
607  *  @param host The name of the host to be considered.
608  *  @param variable The name of the variable to be considered.
609  *  @param value The value to be added to the variable.
610  *
611  *  @see TRACE_host_variable_declare, TRACE_host_variable_set, TRACE_host_variable_sub
612  */
613 void TRACE_host_variable_add (const char *host, const char *variable, double value)
614 {
615   TRACE_host_variable_add_with_time(simgrid_get_clock(), host, variable, value);
616 }
617
618 /** @ingroup TRACE_user_variables
619  *  @brief Subtract a value from a variable of a host.
620  *
621  *  @param host The name of the host to be considered.
622  *  @param variable The name of the variable to be considered.
623  *  @param value The value to be subtracted from the variable.
624  *
625  *  @see TRACE_host_variable_declare, TRACE_host_variable_set, TRACE_host_variable_add
626  */
627 void TRACE_host_variable_sub (const char *host, const char *variable, double value)
628 {
629   TRACE_host_variable_sub_with_time(simgrid_get_clock(), host, variable, value);
630 }
631
632 /** @ingroup TRACE_user_variables
633  *  @brief Set the value of a variable of a host at a given timestamp.
634  *
635  *  Same as #TRACE_host_variable_set, but let user specify  the time used to trace it. Users can specify a time that
636  *  is not the simulated clock time as defined by the core  simulator. This allows a fine-grain control of time
637  *  definition, but should be used with caution since the trace  can be inconsistent if resource utilization traces are
638  *  also traced.
639  *
640  *  @param time The timestamp to be used to tag this change of value.
641  *  @param host The name of the host to be considered.
642  *  @param variable The name of the variable to be considered.
643  *  @param value The new value of the variable.
644  *
645  *  @see TRACE_host_variable_declare, TRACE_host_variable_add_with_time, TRACE_host_variable_sub_with_time
646  */
647 void TRACE_host_variable_set_with_time (double time, const char *host, const char *variable, double value)
648 {
649   instr_user_variable(time, host, variable, "HOST", value, InstrUserVariable::SET, "", &user_host_variables);
650 }
651
652 /** @ingroup TRACE_user_variables
653  *  @brief Add a value to a variable of a host at a given timestamp.
654  *
655  *  Same as #TRACE_host_variable_add, but let user specify the time used to trace it. Users can specify a time that
656  *  is not the simulated clock time as defined by the core  simulator. This allows a fine-grain control of time
657  *  definition, but should be used with caution since the trace can be inconsistent if resource utilization traces are
658  *  also traced.
659  *
660  *  @param time The timestamp to be used to tag this change of value.
661  *  @param host The name of the host to be considered.
662  *  @param variable The name of the variable to be considered.
663  *  @param value The value to be added to the variable.
664  *
665  *  @see TRACE_host_variable_declare, TRACE_host_variable_set_with_time, TRACE_host_variable_sub_with_time
666  */
667 void TRACE_host_variable_add_with_time (double time, const char *host, const char *variable, double value)
668 {
669   instr_user_variable(time, host, variable, "HOST", value, InstrUserVariable::ADD, "", &user_host_variables);
670 }
671
672 /** @ingroup TRACE_user_variables
673  *  @brief Subtract a value from a variable of a host at a given timestamp.
674  *
675  *  Same as #TRACE_host_variable_sub, but let user specify the time used to trace it. Users can specify a time that
676  *  is not the simulated clock time as defined by the core  simulator. This allows a fine-grain control of time
677  *  definition, but should be used with caution since the trace can be inconsistent if resource utilization traces are
678  *  also traced.
679  *
680  *  @param time The timestamp to be used to tag this change of value.
681  *  @param host The name of the host to be considered.
682  *  @param variable The name of the variable to be considered.
683  *  @param value The value to be subtracted from the variable.
684  *
685  *  @see TRACE_host_variable_declare, TRACE_host_variable_set_with_time, TRACE_host_variable_add_with_time
686  */
687 void TRACE_host_variable_sub_with_time (double time, const char *host, const char *variable, double value)
688 {
689   instr_user_variable(time, host, variable, "HOST", value, InstrUserVariable::SUB, "", &user_host_variables);
690 }
691
692 /** @ingroup TRACE_user_variables
693  *  @brief Get declared user host variables
694  *
695  * This function should be used to get host variables that were already declared with #TRACE_host_variable_declare or
696  * with #TRACE_host_variable_declare_with_color.
697  *
698  * @return A dynar with the declared host variables, must be freed with xbt_dynar_free.
699  */
700 xbt_dynar_t TRACE_get_host_variables ()
701 {
702   return instr_set_to_dynar(user_host_variables);
703 }
704
705 /* for link variables */
706 /** @ingroup TRACE_user_variables
707  *  @brief Declare a new user variable associated to links.
708  *
709  *  Declare a user variable that will be associated to links.
710  *  A user link variable can be used, for example, to trace user variables such as the number of messages being
711  *  transferred through network links. The color associated to this new variable will be random.
712  *
713  *  @param variable The name of the new variable to be declared.
714  *
715  *  @see TRACE_link_variable_declare_with_color
716  */
717 void TRACE_link_variable_declare (const char *variable)
718 {
719   instr_user_variable(0, nullptr, variable, "LINK", 0, InstrUserVariable::DECLARE, "", &user_link_variables);
720 }
721
722 /** @ingroup TRACE_user_variables
723  *  @brief Declare a new user variable associated to links with a color.
724  *
725  *  Same as #TRACE_link_variable_declare, but associated a color to the newly created user link variable. The color
726  *  needs to be a string with three numbers separated by spaces in the range [0,1].
727  *  A light-gray color can be specified using "0.7 0.7 0.7" as color.
728  *
729  *  @param variable The name of the new variable to be declared.
730  *  @param color The color for the new variable.
731  */
732 void TRACE_link_variable_declare_with_color (const char *variable, const char *color)
733 {
734   instr_user_variable(0, nullptr, variable, "LINK", 0, InstrUserVariable::DECLARE, color, &user_link_variables);
735 }
736
737 /** @ingroup TRACE_user_variables
738  *  @brief Set the value of a variable of a link.
739  *
740  *  @param link The name of the link to be considered.
741  *  @param variable The name of the variable to be considered.
742  *  @param value The new value of the variable.
743  *
744  *  @see TRACE_link_variable_declare, TRACE_link_variable_add, TRACE_link_variable_sub
745  */
746 void TRACE_link_variable_set (const char *link, const char *variable, double value)
747 {
748   TRACE_link_variable_set_with_time(simgrid_get_clock(), link, variable, value);
749 }
750
751 /** @ingroup TRACE_user_variables
752  *  @brief Add a value to a variable of a link.
753  *
754  *  @param link The name of the link to be considered.
755  *  @param variable The name of the variable to be considered.
756  *  @param value The value to be added to the variable.
757  *
758  *  @see TRACE_link_variable_declare, TRACE_link_variable_set, TRACE_link_variable_sub
759  */
760 void TRACE_link_variable_add (const char *link, const char *variable, double value)
761 {
762   TRACE_link_variable_add_with_time(simgrid_get_clock(), link, variable, value);
763 }
764
765 /** @ingroup TRACE_user_variables
766  *  @brief Subtract a value from a variable of a link.
767  *
768  *  @param link The name of the link to be considered.
769  *  @param variable The name of the variable to be considered.
770  *  @param value The value to be subtracted from the variable.
771  *
772  *  @see TRACE_link_variable_declare, TRACE_link_variable_set, TRACE_link_variable_add
773  */
774 void TRACE_link_variable_sub (const char *link, const char *variable, double value)
775 {
776   TRACE_link_variable_sub_with_time(simgrid_get_clock(), link, variable, value);
777 }
778
779 /** @ingroup TRACE_user_variables
780  *  @brief Set the value of a variable of a link at a given timestamp.
781  *
782  *  Same as #TRACE_link_variable_set, but let user specify the time used to trace it. Users can specify a time that
783  *  is not the simulated clock time as defined by the core simulator. This allows a fine-grain control of time
784  *  definition, but should be used with caution since the trace can be inconsistent if resource utilization traces are
785  *  also traced.
786  *
787  *  @param time The timestamp to be used to tag this change of value.
788  *  @param link The name of the link to be considered.
789  *  @param variable The name of the variable to be considered.
790  *  @param value The new value of the variable.
791  *
792  *  @see TRACE_link_variable_declare, TRACE_link_variable_add_with_time, TRACE_link_variable_sub_with_time
793  */
794 void TRACE_link_variable_set_with_time (double time, const char *link, const char *variable, double value)
795 {
796   instr_user_variable(time, link, variable, "LINK", value, InstrUserVariable::SET, "", &user_link_variables);
797 }
798
799 /** @ingroup TRACE_user_variables
800  *  @brief Add a value to a variable of a link at a given timestamp.
801  *
802  *  Same as #TRACE_link_variable_add, but let user specify the time used to trace it. Users can specify a time that
803  *  is not the simulated clock time as defined by the core simulator. This allows a fine-grain control of time
804  *  definition, but should be used with caution since the trace can be inconsistent if resource utilization traces are
805  *  also traced.
806  *
807  *  @param time The timestamp to be used to tag this change of value.
808  *  @param link The name of the link to be considered.
809  *  @param variable The name of the variable to be considered.
810  *  @param value The value to be added to the variable.
811  *
812  *  @see TRACE_link_variable_declare, TRACE_link_variable_set_with_time, TRACE_link_variable_sub_with_time
813  */
814 void TRACE_link_variable_add_with_time (double time, const char *link, const char *variable, double value)
815 {
816   instr_user_variable(time, link, variable, "LINK", value, InstrUserVariable::ADD, "", &user_link_variables);
817 }
818
819 /** @ingroup TRACE_user_variables
820  *  @brief Subtract a value from a variable of a link at a given timestamp.
821  *
822  *  Same as #TRACE_link_variable_sub, but let user specify the time used to trace it. Users can specify a time that
823  *  is not the simulated clock time as defined by the core simulator. This allows a fine-grain control of time
824  *  definition, but should be used with caution since the trace can be inconsistent if resource utilization traces are
825  *  also traced.
826  *
827  *  @param time The timestamp to be used to tag this change of value.
828  *  @param link The name of the link to be considered.
829  *  @param variable The name of the variable to be considered.
830  *  @param value The value to be subtracted from the variable.
831  *
832  *  @see TRACE_link_variable_declare, TRACE_link_variable_set_with_time, TRACE_link_variable_add_with_time
833  */
834 void TRACE_link_variable_sub_with_time (double time, const char *link, const char *variable, double value)
835 {
836   instr_user_variable(time, link, variable, "LINK", value, InstrUserVariable::SUB, "", &user_link_variables);
837 }
838
839 /* for link variables, but with src and dst used for get_route */
840 /** @ingroup TRACE_user_variables
841  *  @brief Set the value of the variable present in the links connecting source and destination.
842  *
843  *  Same as #TRACE_link_variable_set, but instead of providing the name of link to be considered, provide the source
844  *  and destination hosts. All links that are part of the route between source and destination will have the variable
845  *  set to the provided value.
846  *
847  *  @param src The name of the source host for get route.
848  *  @param dst The name of the destination host for get route.
849  *  @param variable The name of the variable to be considered.
850  *  @param value The new value of the variable.
851  *
852  *  @see TRACE_link_variable_declare, TRACE_link_srcdst_variable_add, TRACE_link_srcdst_variable_sub
853  */
854 void TRACE_link_srcdst_variable_set (const char *src, const char *dst, const char *variable, double value)
855 {
856   TRACE_link_srcdst_variable_set_with_time(simgrid_get_clock(), src, dst, variable, value);
857 }
858
859 /** @ingroup TRACE_user_variables
860  *  @brief Add a value to the variable present in the links connecting source and destination.
861  *
862  *  Same as #TRACE_link_variable_add, but instead of providing the name of link to be considered, provide the source
863  *  and destination hosts. All links that are part of the route between source and destination will have the value
864  *  passed as parameter added to the current value of the variable name to be considered.
865  *
866  *  @param src The name of the source host for get route.
867  *  @param dst The name of the destination host for get route.
868  *  @param variable The name of the variable to be considered.
869  *  @param value The value to be added to the variable.
870  *
871  *  @see TRACE_link_variable_declare, TRACE_link_srcdst_variable_set, TRACE_link_srcdst_variable_sub
872  */
873 void TRACE_link_srcdst_variable_add (const char *src, const char *dst, const char *variable, double value)
874 {
875   TRACE_link_srcdst_variable_add_with_time(simgrid_get_clock(), src, dst, variable, value);
876 }
877
878 /** @ingroup TRACE_user_variables
879  *  @brief Subtract a value from the variable present in the links connecting source and destination.
880  *
881  *  Same as #TRACE_link_variable_sub, but instead of providing the name of link to be considered, provide the source
882  *  and destination hosts. All links that are part of the route between source and destination will have the value
883  *  passed as parameter subtracted from the current value of the variable name to be considered.
884  *
885  *  @param src The name of the source host for get route.
886  *  @param dst The name of the destination host for get route.
887  *  @param variable The name of the variable to be considered.
888  *  @param value The value to be subtracted from the variable.
889  *
890  *  @see TRACE_link_variable_declare, TRACE_link_srcdst_variable_set, TRACE_link_srcdst_variable_add
891  */
892 void TRACE_link_srcdst_variable_sub (const char *src, const char *dst, const char *variable, double value)
893 {
894   TRACE_link_srcdst_variable_sub_with_time(simgrid_get_clock(), src, dst, variable, value);
895 }
896
897 /** @ingroup TRACE_user_variables
898  *  @brief Set the value of the variable present in the links connecting source and destination at a given timestamp.
899  *
900  *  Same as #TRACE_link_srcdst_variable_set, but let user specify the time used to trace it. Users can specify a time
901  *  that is not the simulated clock time as defined by the core simulator. This allows a fine-grain control of time
902  *  definition, but should be used with caution since the trace can be inconsistent if resource utilization traces are
903  *  also traced.
904  *
905  *  @param time The timestamp to be used to tag this change of value.
906  *  @param src The name of the source host for get route.
907  *  @param dst The name of the destination host for get route.
908  *  @param variable The name of the variable to be considered.
909  *  @param value The new value of the variable.
910  *
911  *  @see TRACE_link_variable_declare, TRACE_link_srcdst_variable_add_with_time, TRACE_link_srcdst_variable_sub_with_time
912  */
913 void TRACE_link_srcdst_variable_set_with_time (double time, const char *src, const char *dst, const char *variable,
914                                                double value)
915 {
916   instr_user_srcdst_variable(time, src, dst, variable, "LINK", value, InstrUserVariable::SET);
917 }
918
919 /** @ingroup TRACE_user_variables
920  *  @brief Add a value to the variable present in the links connecting source and destination at a given timestamp.
921  *
922  *  Same as #TRACE_link_srcdst_variable_add, but let user specify the time used to trace it. Users can specify a time
923  *  that is not the simulated clock time as defined by the core simulator. This allows a fine-grain control of time
924  *  definition, but should be used with caution since the trace can be inconsistent if resource utilization traces are
925  *  also traced.
926  *
927  *  @param time The timestamp to be used to tag this change of value.
928  *  @param src The name of the source host for get route.
929  *  @param dst The name of the destination host for get route.
930  *  @param variable The name of the variable to be considered.
931  *  @param value The value to be added to the variable.
932  *
933  *  @see TRACE_link_variable_declare, TRACE_link_srcdst_variable_set_with_time, TRACE_link_srcdst_variable_sub_with_time
934  */
935 void TRACE_link_srcdst_variable_add_with_time (double time, const char *src, const char *dst, const char *variable,
936                                                double value)
937 {
938   instr_user_srcdst_variable(time, src, dst, variable, "LINK", value, InstrUserVariable::ADD);
939 }
940
941 /** @ingroup TRACE_user_variables
942  *  @brief Subtract a value from the variable present in the links connecting source and dest. at a given timestamp.
943  *
944  *  Same as #TRACE_link_srcdst_variable_sub, but let user specify the time used to trace it. Users can specify a time
945  *  that is not the simulated clock time as defined by the core simulator. This allows a fine-grain control of time
946  *  definition, but should be used with caution since the trace can be inconsistent if resource utilization traces are
947  *  also traced.
948  *
949  *  @param time The timestamp to be used to tag this change of value.
950  *  @param src The name of the source host for get route.
951  *  @param dst The name of the destination host for get route.
952  *  @param variable The name of the variable to be considered.
953  *  @param value The value to be subtracted from the variable.
954  *
955  *  @see TRACE_link_variable_declare, TRACE_link_srcdst_variable_set_with_time, TRACE_link_srcdst_variable_add_with_time
956  */
957 void TRACE_link_srcdst_variable_sub_with_time (double time, const char *src, const char *dst, const char *variable,
958                                                double value)
959 {
960   instr_user_srcdst_variable(time, src, dst, variable, "LINK", value, InstrUserVariable::SUB);
961 }
962
963 /** @ingroup TRACE_user_variables
964  *  @brief Get declared user link variables
965  *
966  * This function should be used to get link variables that were already declared with #TRACE_link_variable_declare or
967  * with #TRACE_link_variable_declare_with_color.
968  *
969  * @return A dynar with the declared link variables, must be freed with xbt_dynar_free.
970  */
971 xbt_dynar_t TRACE_get_link_variables ()
972 {
973   return instr_set_to_dynar(user_link_variables);
974 }
975
976 /** @ingroup TRACE_user_variables
977  *  @brief Declare a new user state associated to hosts.
978  *
979  *  Declare a user state that will be associated to hosts.
980  *  A user host state can be used to trace application states.
981  *
982  *  @param state The name of the new state to be declared.
983  *
984  *  @see TRACE_host_state_declare_value
985  */
986 void TRACE_host_state_declare (const char *state)
987 {
988   instr_new_user_state_type("HOST", state);
989 }
990
991 /** @ingroup TRACE_user_variables
992  *  @brief Declare a new value for a user state associated to hosts.
993  *
994  *  Declare a value for a state. The color needs to be a string with 3 numbers separated by spaces in the range [0,1].
995  *  A light-gray color can be specified using "0.7 0.7 0.7" as color.
996  *
997  *  @param state The name of the new state to be declared.
998  *  @param value The name of the value
999  *  @param color The color of the value
1000  *
1001  *  @see TRACE_host_state_declare
1002  */
1003 void TRACE_host_state_declare_value (const char *state, const char *value, const char *color)
1004 {
1005   instr_new_value_for_user_state_type (state, value, color);
1006 }
1007
1008 /** @ingroup TRACE_user_variables
1009  *  @brief Set the user state to the given value.
1010  *
1011  *  Change a user state previously declared to the given value.
1012  *
1013  *  @param host The name of the host to be considered.
1014  *  @param state_name The name of the state previously declared.
1015  *  @param value_name The new value of the state.
1016  *
1017  *  @see TRACE_host_state_declare, TRACE_host_push_state, TRACE_host_pop_state, TRACE_host_reset_state
1018  */
1019 void TRACE_host_set_state(const char* host, const char* state_name, const char* value_name)
1020 {
1021   simgrid::instr::StateType* state = simgrid::instr::Container::by_name(host)->get_state(state_name);
1022   state->add_entity_value(value_name);
1023   state->set_event(value_name);
1024 }
1025
1026 /** @ingroup TRACE_user_variables
1027  *  @brief Push a new value for a state of a given host.
1028  *
1029  *  Change a user state previously declared by pushing the new value to the state.
1030  *
1031  *  @param host The name of the host to be considered.
1032  *  @param state_name The name of the state previously declared.
1033  *  @param value_name The value to be pushed.
1034  *
1035  *  @see TRACE_host_state_declare, TRACE_host_set_state, TRACE_host_pop_state, TRACE_host_reset_state
1036  */
1037 void TRACE_host_push_state(const char* host, const char* state_name, const char* value_name)
1038 {
1039   simgrid::instr::Container::by_name(host)->get_state(state_name)->push_event(value_name);
1040 }
1041
1042 /** @ingroup TRACE_user_variables
1043  *  @brief Pop the last value of a state of a given host.
1044  *
1045  *  Change a user state previously declared by removing the last value of the state.
1046  *
1047  *  @param host The name of the host to be considered.
1048  *  @param state_name The name of the state to be popped.
1049  *
1050  *  @see TRACE_host_state_declare, TRACE_host_set_state, TRACE_host_push_state, TRACE_host_reset_state
1051  */
1052 void TRACE_host_pop_state(const char* host, const char* state_name)
1053 {
1054   simgrid::instr::Container::by_name(host)->get_state(state_name)->pop_event();
1055 }