Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
new configuration option tracing/platform/method
[simgrid.git] / src / 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/private.h"
8
9 #ifdef HAVE_TRACING
10
11 #define VARIABLE_SEPARATOR '#'
12
13 //B
14 static xbt_dict_t last_platform_variables; /* to control the amount of add/sub variables events:
15    dict with key {RESOURCE_NAME}#Time or {RESOURCE_NAME}#Value of dict with variables types == string */
16
17 //C
18 static xbt_dict_t method_c_dict;
19
20 /* auxiliary function for resource utilization tracing */
21 static char *strsplit (char *input, int field, char del) //caller should free the returned string
22 {
23   char *ret = NULL;
24   int length = strlen(input), i;
25   int s = 0, e = length+1;
26   int current_field = 0;
27   for (i = 0; i < length; i++){
28      if (input[i] == del){
29        if (current_field == field){
30          e = i-1;
31          break;
32        }else{
33          s = i+1;
34          current_field++;
35        }
36      }
37   }
38   //copy string from s to e (with length equal to e-s) and return
39   ret = malloc ((e-s+2)*sizeof(char));
40   strncpy (ret, input+s, e-s+1);
41   ret[e-s+1] = '\0';
42   return ret;
43 }
44
45 //resource utilization tracing method
46 typedef enum {methodA,methodB,methodC} TracingMethod;
47 static TracingMethod currentMethod;
48
49 static void __TRACE_define_method (char *method)
50 {
51   if (!strcmp(method, "a")){
52     currentMethod = methodA;
53   }else if (!strcmp(method, "b")){
54     currentMethod = methodB;
55   }else if (!strcmp(method, "c")){
56     currentMethod = methodC;
57   }else{
58     currentMethod = methodB; //default
59   }
60 }
61
62 //A
63 static void __TRACE_surf_resource_utilization_A (double now, double delta, const char *variable, const char *resource, double value)
64 {
65   if (!IS_TRACING_PLATFORM) return;
66
67   char valuestr[100];
68   snprintf (valuestr, 100, "%f", value);
69
70   __TRACE_surf_check_variable_set_to_zero (now, variable, resource);
71   pajeAddVariable (now, variable, resource, valuestr);
72   pajeSubVariable (now+delta, variable, resource, valuestr);
73   return;
74 }
75
76 //B
77 static void __TRACE_surf_resource_utilization_initialize_B ()
78 {
79   last_platform_variables =  xbt_dict_new();
80 }
81
82 static void __TRACE_surf_resource_utilization_B (double now, double delta, const char *variable, const char *resource, double value)
83 {
84   if (!IS_TRACING_PLATFORM) return;
85
86   char valuestr[100];
87   char nowstr[100], nowdeltastr[100];
88   char timekey[100], valuekey[100], variablekey[100];
89   char *lastvariable = NULL;
90   char *lasttime = NULL;
91   char *lastvalue = NULL;
92   char *nowdeltastr_cpy = NULL;
93   char *valuestr_cpy = NULL;
94   char *variable_cpy = NULL;
95
96   /*
97    * The following code replaces the code above with the objective
98    * to decrease the size of file because of unnecessary add/sub on
99    * variables. It should be re-checked before put in production.
100    */
101
102   snprintf (valuestr, 100, "%f", value);
103   snprintf (nowstr, 100, "%f", now);
104   snprintf (nowdeltastr, 100, "%f", now+delta);
105   snprintf (timekey, 100, "%s%cTime", resource, VARIABLE_SEPARATOR);
106   snprintf (valuekey, 100, "%s%cValue", resource, VARIABLE_SEPARATOR);
107   snprintf (variablekey, 100, "%s%cVariable", resource, VARIABLE_SEPARATOR);
108
109   lastvariable = xbt_dict_get_or_null (last_platform_variables, variablekey);
110   if (lastvariable == NULL){
111     __TRACE_surf_check_variable_set_to_zero (now, variable, resource);
112     pajeAddVariable (now, variable, resource, valuestr);
113     nowdeltastr_cpy = xbt_strdup (nowdeltastr);
114     valuestr_cpy = xbt_strdup (valuestr);
115     variable_cpy = xbt_strdup (variable);
116     xbt_dict_set (last_platform_variables, timekey, nowdeltastr_cpy, xbt_free);
117     xbt_dict_set (last_platform_variables, valuekey, valuestr_cpy, xbt_free);
118     xbt_dict_set (last_platform_variables, variablekey, variable_cpy, xbt_free);
119   }else{
120     lasttime = xbt_dict_get_or_null (last_platform_variables, timekey);
121     lastvalue = xbt_dict_get_or_null (last_platform_variables, valuekey);
122
123     /* check if it is the same variable */
124     if (strcmp(lastvariable, variable) == 0){ /* same variable */
125       /* check if lasttime equals now */
126       if (atof(lasttime) == now){ /* lastime == now */
127         /* check if lastvalue equals valuestr */
128         if (atof(lastvalue) == value){ /* lastvalue == value (good, just advance time) */
129           char *nowdeltastr_cpy = xbt_strdup (nowdeltastr);
130           xbt_dict_set (last_platform_variables, timekey, nowdeltastr_cpy, xbt_free);
131         }else{ /* value has changed */
132           /* value has changed, subtract previous value, add new one */
133           pajeSubVariable (atof(lasttime), variable, resource, lastvalue);
134           pajeAddVariable (atof(nowstr), variable, resource, valuestr);
135           nowdeltastr_cpy = xbt_strdup (nowdeltastr);
136           valuestr_cpy = xbt_strdup (valuestr);
137           xbt_dict_set (last_platform_variables, timekey, nowdeltastr_cpy, xbt_free);
138           xbt_dict_set (last_platform_variables, valuekey, valuestr_cpy, xbt_free);
139         }
140       }else{ /* lasttime != now */
141         /* the last time is different from new starting time, subtract to lasttime and add from nowstr */
142         pajeSubVariable (atof(lasttime), variable, resource, lastvalue);
143         pajeAddVariable (atof(nowstr), variable, resource, valuestr);
144         nowdeltastr_cpy = xbt_strdup (nowdeltastr);
145         valuestr_cpy = xbt_strdup (valuestr);
146         xbt_dict_set (last_platform_variables, timekey, nowdeltastr_cpy, xbt_free);
147         xbt_dict_set (last_platform_variables, valuekey, valuestr_cpy, xbt_free);
148       }
149     }else{ /* variable has changed */
150       pajeSubVariable (atof(lasttime), lastvariable, resource, lastvalue);
151       __TRACE_surf_check_variable_set_to_zero (now, variable, resource);
152       pajeAddVariable (now, variable, resource, valuestr);
153       nowdeltastr_cpy = xbt_strdup (nowdeltastr);
154       valuestr_cpy = xbt_strdup (valuestr);
155       variable_cpy = xbt_strdup (variable);
156       xbt_dict_set (last_platform_variables, timekey, nowdeltastr_cpy, xbt_free);
157       xbt_dict_set (last_platform_variables, valuekey, valuestr_cpy, xbt_free);
158       xbt_dict_set (last_platform_variables, variablekey, variable_cpy, xbt_free);
159     }
160   }
161   return;
162 }
163
164 static void __TRACE_surf_resource_utilization_finalize_B ()
165 {
166   xbt_dict_cursor_t cursor = NULL;
167   unsigned int cursor_ar = 0;
168     char *key, *value, *res;
169     char *resource;
170     char *aux = NULL;
171     char *var_cpy = NULL;
172     xbt_dynar_t resources = NULL;
173   if (!IS_TRACING_PLATFORM) return;
174   if (!xbt_dict_length(last_platform_variables)){
175     return;
176   }else{
177     /* get all resources from last_platform_variables */
178     resources = xbt_dynar_new(sizeof(char*), xbt_free);
179     xbt_dict_foreach(last_platform_variables, cursor, key, value) {
180       res = strsplit (key, 0, VARIABLE_SEPARATOR);
181       aux = strsplit (key, 1, VARIABLE_SEPARATOR);
182       if (strcmp (aux, "Time") == 0){ //only need to add one of three
183         var_cpy = xbt_strdup (res);
184         xbt_dynar_push (resources, &var_cpy);
185       }
186       free (aux);
187       free (res);
188     }
189
190     /* iterate through resources array */
191     xbt_dynar_foreach (resources, cursor_ar, resource) {
192       char timekey[100], valuekey[100], variablekey[100];
193       char *time = NULL;
194       char *value = NULL;
195       char *variable = NULL;
196       snprintf (timekey, 100, "%s%cTime", resource, VARIABLE_SEPARATOR);
197       snprintf (valuekey, 100, "%s%cValue", resource, VARIABLE_SEPARATOR);
198       snprintf (variablekey, 100, "%s%cVariable", resource, VARIABLE_SEPARATOR);
199
200       time = xbt_dict_get_or_null (last_platform_variables, timekey);
201       if (!time) continue;
202       value = xbt_dict_get (last_platform_variables, valuekey);
203       variable = xbt_dict_get (last_platform_variables, variablekey);
204       pajeSubVariable (atof(time), variable, resource, value);
205
206       xbt_dict_remove (last_platform_variables, timekey);
207       xbt_dict_remove (last_platform_variables, valuekey);
208       xbt_dict_remove (last_platform_variables, variablekey);
209     }
210   }
211 }
212
213 //C
214 static void __TRACE_surf_resource_utilization_start_C (smx_action_t action)
215 {
216   char key[100];
217   snprintf (key, 100, "%p", action);
218
219   //check if exists
220   if (xbt_dict_get_or_null (method_c_dict, key)){
221     xbt_dict_remove (method_c_dict, key); //should never execute here, but it does
222   }
223   xbt_dict_set (method_c_dict, key, xbt_dict_new(), xbt_free);
224
225   //fprintf (stderr, "start %p\n", action);
226   /*
227
228   if (xbt_dict_get_or_null (start_time, key)){
229     xbt_dict_remove (start_time, key);
230   }
231   */
232 }
233
234 static void __TRACE_surf_resource_utilization_end_C (smx_action_t action)
235 {
236   char key[100];
237   snprintf (key, 100, "%p", action);
238
239   xbt_dict_t action_dict = xbt_dict_get (method_c_dict, key);
240 //  fprintf (stderr, "end %p (%f - %f)\n", action, atof(xbt_dict_get_or_null(action_dict, "start")),
241 //                                                 atof(xbt_dict_get_or_null(action_dict, "end")));
242
243   double start_time = atof(xbt_dict_get (action_dict, "start"));
244   double end_time = atof(xbt_dict_get (action_dict, "end"));
245
246   xbt_dict_cursor_t cursor=NULL;
247   char *action_dict_key, *action_dict_value;
248   xbt_dict_foreach(action_dict,cursor,action_dict_key,action_dict_value) {
249     char resource[100], variable[100];
250     if (sscanf (action_dict_key, "%s %s", resource, variable) != 2) continue;
251     __TRACE_surf_check_variable_set_to_zero (start_time, variable, resource);
252     char value_str[100];
253     if(end_time-start_time != 0){
254       snprintf (value_str, 100, "%f", atof(action_dict_value)/(end_time-start_time));
255       pajeAddVariable (start_time, variable, resource, value_str);
256       pajeSubVariable (end_time, variable, resource, value_str);
257     }
258
259     //fprintf(stderr, "\t%p (key=%s) %s %s = %s\n",action, action_dict_key, resource, variable, action_dict_value);
260     //fprintf(stderr, "\t%f %f\n", start_time, end_time);
261   }
262   //fprintf (stderr, "\n");
263
264   xbt_dict_remove (method_c_dict, key);
265   /*
266
267   if (xbt_dict_get_or_null (start_time_dict, key)){
268     xbt_dict_remove (start_time_dict, key);
269   }
270   if (xbt_dict_get_or_null (end_time_dict, key)){
271     xbt_dict_remove (end_time_dict, key);
272   }
273   */
274
275 }
276
277 static void __TRACE_surf_resource_utilization_C (smx_action_t action, double now, double delta, const char *variable, const char *resource, double value)
278 {
279   char key[100];
280   snprintf (key, 100, "%p", action);
281
282   xbt_dict_t action_dict = xbt_dict_get (method_c_dict, key);
283   //setting start time
284   if (!xbt_dict_get_or_null (action_dict, "start")){
285     char start_time[100];
286     snprintf (start_time, 100, "%f", now);
287     xbt_dict_set (action_dict, "start", xbt_strdup (start_time), xbt_free);
288   }
289   //updating end time
290   char end_time[100];
291   snprintf (end_time, 100, "%f", now+delta);
292   xbt_dict_set (action_dict, "end", xbt_strdup (end_time), xbt_free);
293
294   //accumulate the value resource-variable
295   char res_var[300];
296   snprintf (res_var, 300, "%s %s", resource, variable);
297   double current_value_f;
298   char *current_value = xbt_dict_get_or_null (action_dict, res_var);
299   if (current_value){
300     current_value_f = atof (current_value);
301     current_value_f += value*delta;
302   }else{
303     current_value_f = value*delta;
304   }
305   char new_current_value[100];
306   snprintf (new_current_value, 100, "%f", current_value_f);
307   xbt_dict_set (action_dict, res_var, xbt_strdup (new_current_value), xbt_free);
308
309   //fprintf (stderr, "event act=%p, now=%f, delta=%f, %s - %s %f\n", action, now, delta, resource, variable, value);
310 }
311
312 static void __TRACE_surf_resource_utilization_initialize_C ()
313 {
314   //start_time_dict = xbt_dict_new();
315   //end_time_dict = xbt_dict_new();
316   method_c_dict = xbt_dict_new();
317 }
318
319 static void __TRACE_surf_resource_utilization_finalize_C ()
320 {
321   xbt_dict_free (&method_c_dict);
322 }
323
324 /*
325  * TRACE_surf_link_set_utilization: entry point from SimGrid
326  */
327 void TRACE_surf_link_set_utilization (const char *name, smx_action_t smx_action, double value, double now, double delta)
328 {
329   char type[100];
330   if (!IS_TRACING || !IS_TRACED(smx_action)) return;
331
332   if (strcmp (name, "__loopback__")==0 ||
333       strcmp (name, "loopback")==0){ //ignore loopback updates
334     return;
335   }
336
337   if (value == 0) return;
338
339   //if (!xbt_dict_get_or_null (created_links, name)){
340 //    TRACE_surf_link_missing ();
341     //return;
342   //}
343
344   snprintf (type, 100, "b%s", smx_action->category);
345   __TRACE_surf_resource_utilization_event (smx_action, now, delta, type, name, value);
346 //fprintf (stderr, "%p - (%f - %f = %f) %s %f metric = %f\n", smx_action, now, now+delta, delta, name, value, value*delta);
347 //  __TRACE_surf_update_action_state_resource (now, delta, type, name, value);
348   return;
349 }
350
351 /*
352  * TRACE_surf_host_set_utilization: entry point from SimGrid
353  */
354 void TRACE_surf_host_set_utilization (const char *name, smx_action_t smx_action, double value, double now, double delta)
355 {
356   char type[100];
357   if (!IS_TRACING || !IS_TRACED(smx_action)) return;
358
359   if (value==0){
360     return;
361   }
362   snprintf (type, 100, "p%s", smx_action->category);
363   __TRACE_surf_resource_utilization_event (smx_action, now, delta, type, name, value);
364 //fprintf (stderr, "%p - (%f - %f = %f) %s %f metric = %f\n", smx_action, now, now+delta, delta, name, value, value*delta);
365 //  __TRACE_surf_update_action_state_resource (now, delta, type, name, value);
366   return;
367 }
368
369 /*
370  * __TRACE_surf_resource_utilization_*: entry points from tracing functions
371  */
372 void __TRACE_surf_resource_utilization_start (smx_action_t action)
373 {
374   if (currentMethod == methodC){
375     __TRACE_surf_resource_utilization_start_C (action);
376   }
377 }
378
379 void __TRACE_surf_resource_utilization_end (smx_action_t action)
380 {
381   if (currentMethod == methodC){
382     __TRACE_surf_resource_utilization_end_C (action);
383   }
384 }
385
386 void __TRACE_surf_resource_utilization_event (smx_action_t action, double now, double delta, const char *variable, const char *resource, double value)
387 {
388   if (currentMethod == methodA){
389     __TRACE_surf_resource_utilization_A (now, delta, variable, resource, value);
390   }else if (currentMethod == methodB){
391     __TRACE_surf_resource_utilization_B (now, delta, variable, resource, value);
392   }else if (currentMethod == methodC){
393     __TRACE_surf_resource_utilization_C (action, now, delta, variable, resource, value);
394   }
395 }
396
397 void __TRACE_surf_resource_utilization_initialize ()
398 {
399   __TRACE_define_method (_TRACE_platform_method());
400
401   if (currentMethod == methodA){
402   }else if (currentMethod == methodB){
403     __TRACE_surf_resource_utilization_initialize_B();
404   }else if (currentMethod == methodC){
405     __TRACE_surf_resource_utilization_initialize_C();
406   }
407 }
408
409 void __TRACE_surf_resource_utilization_finalize ()
410 {
411   if (currentMethod == methodA){
412   }else if (currentMethod == methodB){
413     __TRACE_surf_resource_utilization_finalize_B();
414   }else if (currentMethod == methodC){
415     __TRACE_surf_resource_utilization_finalize_C();
416   }
417 }
418 #endif