Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
[trace] recursive search for a type in the type hierarchy
[simgrid.git] / src / instr / instr_resource_utilization.c
1 /* Copyright (c) 2010. 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 "instr/instr_private.h"
8
9 #ifdef HAVE_TRACING
10
11 XBT_LOG_NEW_DEFAULT_SUBCATEGORY (instr_resource, instr, "tracing (un)-categorized resource utilization");
12
13 //to check if variables were previously set to 0, otherwise paje won't simulate them
14 static xbt_dict_t platform_variables;   /* host or link name -> array of categories */
15
16 //B
17 static xbt_dict_t method_b_dict;
18
19 //C
20 static xbt_dict_t method_c_dict;
21
22 //resource utilization tracing method
23 static void (*TRACE_method_alloc) (void) = NULL;
24 static void (*TRACE_method_release) (void) = NULL;
25 static void (*TRACE_method_start) (smx_action_t action) = NULL;
26 static void (*TRACE_method_event) (smx_action_t action, double now,
27                                    double delta, const char *variable,
28                                    const char *resource, double value) =
29     NULL;
30 static void (*TRACE_method_end) (smx_action_t action) = NULL;
31
32 //used by all methods
33 static void __TRACE_surf_check_variable_set_to_zero(double now,
34                                                     const char *variable,
35                                                     const char *resource)
36 {
37   /* check if we have to set it to 0 */
38   if (!xbt_dict_get_or_null(platform_variables, resource)) {
39     xbt_dynar_t array = xbt_dynar_new(sizeof(char *), xbt_free);
40     char *var_cpy = xbt_strdup(variable);
41     xbt_dynar_push(array, &var_cpy);
42     if (TRACE_categorized ())
43       pajeSetVariable(now, variable, resource, "0");
44     xbt_dict_set(platform_variables, resource, array,
45                  xbt_dynar_free_voidp);
46   } else {
47     xbt_dynar_t array = xbt_dict_get(platform_variables, resource);
48     unsigned int i;
49     char *cat;
50     int flag = 0;
51     xbt_dynar_foreach(array, i, cat) {
52       if (strcmp(variable, cat) == 0) {
53         flag = 1;
54       }
55     }
56     if (flag == 0) {
57       char *var_cpy = xbt_strdup(variable);
58       xbt_dynar_push(array, &var_cpy);
59       if (TRACE_categorized ())
60         pajeSetVariable(now, variable, resource, "0");
61     }
62   }
63   /* end of check */
64 }
65
66 #define A_METHOD
67 //A
68 static void __TRACE_A_alloc(void)
69 {
70 }
71
72 static void __TRACE_A_release(void)
73 {
74 }
75
76 static void __TRACE_A_start(smx_action_t action)
77 {
78 }
79
80 static void __TRACE_A_event(smx_action_t action, double now, double delta,
81                             const char *variable, const char *resource,
82                             double value)
83 {
84   char valuestr[100];
85   snprintf(valuestr, 100, "%f", value);
86
87   __TRACE_surf_check_variable_set_to_zero(now, variable, resource);
88   pajeAddVariable(now, variable, resource, valuestr);
89   pajeSubVariable(now + delta, variable, resource, valuestr);
90 }
91
92 static void __TRACE_A_end(smx_action_t action)
93 {
94 }
95
96 #define B_METHOD
97 //B
98
99 static void __TRACE_B_alloc(void)
100 {
101   method_b_dict = xbt_dict_new();
102 }
103
104 static void __TRACE_B_release(void)
105 {
106   char *key, *time;
107   xbt_dict_cursor_t cursor = NULL;
108   xbt_dict_foreach(method_b_dict, cursor, key, time) {
109     char resource[INSTR_DEFAULT_STR_SIZE];
110     char variable[INSTR_DEFAULT_STR_SIZE];
111     char what[INSTR_DEFAULT_STR_SIZE];
112     sscanf (key, "%s %s %s", resource, variable, what);
113     if (strcmp(what, "time")==0){
114       char key_value[INSTR_DEFAULT_STR_SIZE];
115       snprintf (key_value, INSTR_DEFAULT_STR_SIZE, "%s %s value", resource, variable);
116       char *value = xbt_dict_get_or_null (method_b_dict, key_value);
117       pajeSubVariable(atof(time), variable, resource, value);
118     }
119   }
120   xbt_dict_free(&method_b_dict);
121 }
122
123 static void __TRACE_B_start(smx_action_t action)
124 {
125 }
126
127 static void __TRACE_B_event(smx_action_t action, double now, double delta,
128                             const char *variable, const char *resource,
129                             double value)
130 {
131   char key_time[INSTR_DEFAULT_STR_SIZE];
132   char key_value[INSTR_DEFAULT_STR_SIZE];
133   char nowstr[INSTR_DEFAULT_STR_SIZE];
134   char valuestr[INSTR_DEFAULT_STR_SIZE];
135   char nowdeltastr[INSTR_DEFAULT_STR_SIZE];
136
137   snprintf (key_time, INSTR_DEFAULT_STR_SIZE, "%s %s time", resource, variable);
138   snprintf (key_value, INSTR_DEFAULT_STR_SIZE, "%s %s value", resource, variable);
139   snprintf (nowstr, INSTR_DEFAULT_STR_SIZE, "%f", now);
140   snprintf (valuestr, INSTR_DEFAULT_STR_SIZE, "%f", value);
141   snprintf (nowdeltastr, INSTR_DEFAULT_STR_SIZE, "%f", now+delta);
142
143   char *lasttimestr = xbt_dict_get_or_null(method_b_dict, key_time);
144   char *lastvaluestr = xbt_dict_get_or_null(method_b_dict, key_value);
145   if (lasttimestr == NULL){
146     __TRACE_surf_check_variable_set_to_zero(now, variable, resource);
147     pajeAddVariable(now, variable, resource, valuestr);
148     xbt_dict_set(method_b_dict, key_time, xbt_strdup(nowdeltastr), xbt_free);
149     xbt_dict_set(method_b_dict, key_value, xbt_strdup(valuestr), xbt_free);
150   }else{
151     double lasttime = atof (lasttimestr);
152     double lastvalue = atof (lastvaluestr);
153
154     if (lastvalue == value){
155       double dif = fabs(now - lasttime);
156       if (dif < 0.000001){
157         //perfect, just go on
158       }else{
159         //time changed, have to update
160         pajeSubVariable(lasttime, variable, resource, lastvaluestr);
161         pajeAddVariable(now, variable, resource, valuestr);
162       }
163     }else{
164       //value changed, have to update
165       pajeSubVariable(lasttime, variable, resource, lastvaluestr);
166       pajeAddVariable(now, variable, resource, valuestr);
167     }
168     xbt_dict_set(method_b_dict, key_time, xbt_strdup(nowdeltastr), xbt_free);
169     xbt_dict_set(method_b_dict, key_value, xbt_strdup(valuestr), xbt_free);
170   }
171   return;
172 }
173
174 static void __TRACE_B_end(smx_action_t action)
175 {
176 }
177
178 #define C_METHOD
179 //C
180 static void __TRACE_C_alloc(void)
181 {
182   method_c_dict = xbt_dict_new();
183 }
184
185 static void __TRACE_C_release(void)
186 {
187   xbt_dict_free(&method_c_dict);
188 }
189
190 static void __TRACE_C_start(smx_action_t action)
191 {
192   char key[100];
193   snprintf(key, 100, "%p", action);
194
195   //check if exists
196   if (xbt_dict_get_or_null(method_c_dict, key)) {
197     xbt_dict_remove(method_c_dict, key);        //should never execute here, but it does
198   }
199   xbt_dict_set(method_c_dict, key, xbt_dict_new(), xbt_free);
200 }
201
202 static void __TRACE_C_event(smx_action_t action, double now, double delta,
203                             const char *variable, const char *resource,
204                             double value)
205 {
206   char key[100];
207   snprintf(key, 100, "%p", action);
208
209   xbt_dict_t action_dict = xbt_dict_get(method_c_dict, key);
210   //setting start time
211   if (!xbt_dict_get_or_null(action_dict, "start")) {
212     char start_time[100];
213     snprintf(start_time, 100, "%f", now);
214     xbt_dict_set(action_dict, "start", xbt_strdup(start_time), xbt_free);
215   }
216   //updating end time
217   char end_time[100];
218   snprintf(end_time, 100, "%f", now + delta);
219   xbt_dict_set(action_dict, "end", xbt_strdup(end_time), xbt_free);
220
221   //accumulate the value resource-variable
222   char res_var[300];
223   snprintf(res_var, 300, "%s %s", resource, variable);
224   double current_value_f;
225   char *current_value = xbt_dict_get_or_null(action_dict, res_var);
226   if (current_value) {
227     current_value_f = atof(current_value);
228     current_value_f += value * delta;
229   } else {
230     current_value_f = value * delta;
231   }
232   char new_current_value[100];
233   snprintf(new_current_value, 100, "%f", current_value_f);
234   xbt_dict_set(action_dict, res_var, xbt_strdup(new_current_value),
235                xbt_free);
236 }
237
238 static void __TRACE_C_end(smx_action_t action)
239 {
240   char key[100];
241   snprintf(key, 100, "%p", action);
242
243   xbt_dict_t action_dict = xbt_dict_get(method_c_dict, key);
244   double start_time = atof(xbt_dict_get(action_dict, "start"));
245   double end_time = atof(xbt_dict_get(action_dict, "end"));
246
247   xbt_dict_cursor_t cursor = NULL;
248   char *action_dict_key, *action_dict_value;
249   xbt_dict_foreach(action_dict, cursor, action_dict_key, action_dict_value) {
250     char resource[100], variable[100];
251     if (sscanf(action_dict_key, "%s %s", resource, variable) != 2)
252       continue;
253     __TRACE_surf_check_variable_set_to_zero(start_time, variable,
254                                             resource);
255     char value_str[100];
256     if (end_time - start_time != 0) {
257       snprintf(value_str, 100, "%f",
258                atof(action_dict_value) / (end_time - start_time));
259       pajeAddVariable(start_time, variable, resource, value_str);
260       pajeSubVariable(end_time, variable, resource, value_str);
261     }
262   }
263   xbt_dict_remove(method_c_dict, key);
264 }
265
266 #define RESOURCE_UTILIZATION_INTERFACE
267 /*
268  * TRACE_surf_link_set_utilization: entry point from SimGrid
269  */
270 void TRACE_surf_link_set_utilization(const char *resource, smx_action_t smx_action,
271                                      surf_action_t surf_action,
272                                      double value, double now,
273                                      double delta)
274 {
275   if (!TRACE_is_active())
276     return;
277   if (!value)
278     return;
279   //only trace link utilization if link is known by tracing mechanism
280   if (!instr_link_is_traced(resource))
281     return;
282   if (!value)
283     return;
284
285   //trace uncategorized link utilization
286   if (TRACE_uncategorized()){
287     DEBUG4("UNCAT LINK [%f - %f] %s bandwidth_used %f", now, now+delta, resource, value);
288     char *variable_type = instr_variable_type ("bandwidth_used", resource);
289     char *resource_id = instr_resource_type (resource);
290     TRACE_surf_resource_utilization_event(smx_action, now, delta, variable_type, resource_id, value);
291   }
292
293   //trace categorized utilization
294   if (TRACE_categorized()){
295     if (!surf_action->category)
296       return;
297     DEBUG5("CAT LINK [%f - %f] %s %s %f", now, now+delta, resource, surf_action->category, value);
298     char *variable_type = instr_variable_type (surf_action->category, resource);
299     char *resource_id = instr_resource_type (resource);
300     TRACE_surf_resource_utilization_event(smx_action, now, delta, variable_type, resource_id, value);
301   }
302   return;
303 }
304
305 /*
306  * TRACE_surf_host_set_utilization: entry point from SimGrid
307  */
308 void TRACE_surf_host_set_utilization(const char *resource,
309                                      smx_action_t smx_action,
310                                      surf_action_t surf_action,
311                                      double value, double now,
312                                      double delta)
313 {
314   if (!TRACE_is_active())
315     return;
316   if (!value)
317     return;
318
319   //trace uncategorized host utilization
320   if (TRACE_uncategorized()){
321     DEBUG4("UNCAT HOST [%f - %f] %s power_used %f", now, now+delta, resource, value);
322     char *variable_type = instr_variable_type ("power_used", resource);
323     char *resource_id = instr_resource_type (resource);
324     TRACE_surf_resource_utilization_event(smx_action, now, delta, variable_type, resource_id, value);
325   }
326
327   //trace categorized utilization
328   if (TRACE_categorized()){
329     if (!surf_action->category)
330       return;
331     DEBUG5("CAT HOST [%f - %f] %s %s %f", now, now+delta, resource, surf_action->category, value);
332     char *variable_type = instr_variable_type (surf_action->category, resource);
333     char *resource_id = instr_resource_type (resource);
334     TRACE_surf_resource_utilization_event(smx_action, now, delta, variable_type, resource_id, value);
335   }
336   return;
337 }
338
339 /*
340  * __TRACE_surf_resource_utilization_*: entry points from tracing functions
341  */
342 void TRACE_surf_resource_utilization_start(smx_action_t action)
343 {
344   if (!TRACE_is_active())
345     return;
346   DEBUG1("START %p", action);
347   TRACE_method_start(action);
348 }
349
350 void TRACE_surf_resource_utilization_event(smx_action_t action, double now,
351                                            double delta,
352                                            const char *variable,
353                                            const char *resource,
354                                            double value)
355 {
356   if (!TRACE_is_active())
357     return;
358   DEBUG6("EVENT %p [%f - %f] %s %s %f", action, now, now+delta, resource, variable, value);
359   TRACE_method_event(action, now, delta, variable, resource, value);
360 }
361
362 void TRACE_surf_resource_utilization_end(smx_action_t action)
363 {
364   if (!TRACE_is_active())
365     return;
366   TRACE_method_end(action);
367   DEBUG1("END %p", action);
368 }
369
370 void TRACE_surf_resource_utilization_release()
371 {
372   if (!TRACE_is_active())
373     return;
374   TRACE_method_release();
375 }
376
377 static void __TRACE_define_method(char *method)
378 {
379   if (!strcmp(method, "a")) {
380     TRACE_method_alloc = __TRACE_A_alloc;
381     TRACE_method_release = __TRACE_A_release;
382     TRACE_method_start = __TRACE_A_start;
383     TRACE_method_event = __TRACE_A_event;
384     TRACE_method_end = __TRACE_A_end;
385   } else if (!strcmp(method, "c")) {
386     TRACE_method_alloc = __TRACE_C_alloc;
387     TRACE_method_release = __TRACE_C_release;
388     TRACE_method_start = __TRACE_C_start;
389     TRACE_method_event = __TRACE_C_event;
390     TRACE_method_end = __TRACE_C_end;
391   } else {                      //default is B
392     TRACE_method_alloc = __TRACE_B_alloc;
393     TRACE_method_release = __TRACE_B_release;
394     TRACE_method_start = __TRACE_B_start;
395     TRACE_method_event = __TRACE_B_event;
396     TRACE_method_end = __TRACE_B_end;
397   }
398 }
399
400 void TRACE_surf_resource_utilization_alloc()
401 {
402   platform_variables = xbt_dict_new();
403   __TRACE_define_method(TRACE_get_platform_method());
404   TRACE_method_alloc();
405 }
406 #endif /* HAVE_TRACING */