Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
Model using the proportional fairness to compute the bandwith achivied
[simgrid.git] / src / surf / network_gtnets.c
1 /*      $Id$     */
2
3 /* Copyright (c) 2005 Henri Casanova. All rights reserved.                  */
4
5 /* This program is free software; you can redistribute it and/or modify it
6  * under the terms of the license (GNU LGPL) which comes with this package. */
7
8 #include "network_gtnets_private.h"
9
10 XBT_LOG_EXTERNAL_DEFAULT_CATEGORY(surf_network_gtnets);
11
12 /* surf_network_resource_t surf_network_resource = NULL; */
13 static xbt_dict_t network_link_set = NULL;
14
15 /* xbt_dict_t network_card_set = NULL; */
16
17 #if 0
18 static int card_number = 0;
19 static network_link_GTNETS_t **routing_table = NULL;
20 static int *routing_table_size = NULL;
21
22 #define ROUTE(i,j) routing_table[(i)+(j)*card_number]
23 #define ROUTE_SIZE(i,j) routing_table_size[(i)+(j)*card_number]
24 #endif
25
26 /** QUESTIONS for GTNetS integration
27  **   1. Check that we did the right thing with name_service and get_resource_name
28  **   2. Right now there is no "kill flow" in our GTNetS implementation. Do we
29  **      need to do something about this?
30  **   3. We ignore the fact there is some max_duration on flows (see #2 above)
31  **   4. share_resources() returns a duration, not a date, right?
32  **   5. We don't suppoer "rates"
33  **   6. We don't update "remaining" for ongoing flows. Is it bad?
34  **/
35
36 /* Free memory for a network link */
37 static void network_link_free(void *nw_link)
38 {
39   free(((network_link_GTNETS_t)nw_link)->name);
40   free(nw_link);
41 }
42
43 /* Instantiate a new network link */
44 /* name: some name for the link, from the XML */
45 /* bw: The bandwidth value            */
46 /* lat: The latency value             */
47 static void network_link_new(char *name,
48                              double bw,
49                              double lat)
50 {
51   static int link_count=-1;
52   network_link_GTNETS_t gtnets_link;
53
54   /* KF: Check that the link wasn't added before */
55   if (xbt_dict_get_or_null(network_link_set, name)) {
56     return;
57   }
58
59   /* KF: Increment the link counter for GTNetS */
60   link_count++;
61
62 /*
63   nw_link->resource = (surf_resource_t) surf_network_resource;
64   nw_link->name = name;
65   nw_link->bw_current = bw_initial;
66   if (bw_trace)
67     nw_link->bw_event =
68         tmgr_history_add_trace(history, bw_trace, 0.0, 0, nw_link);
69   nw_link->lat_current = lat_initial;
70   if (lat_trace)
71     nw_link->lat_event =
72         tmgr_history_add_trace(history, lat_trace, 0.0, 0, nw_link);
73   nw_link->state_current = state_initial;
74   if (state_trace)
75     nw_link->state_event =
76         tmgr_history_add_trace(history, state_trace, 0.0, 0, nw_link);
77 */
78
79   /* KF: Add the link to the GTNetS simulation */
80   if (GTNetS_add_link(link_count, bw, lat)) {
81     xbt_assert0(0,"Cannot create GTNetS link");
82   }
83
84   /* KF: Insert entry in the dictionary */
85   gtnets_link = xbt_new0(s_network_link_GTNETS_t,1);
86   gtnets_link->name = strcpy(name);
87   gtnets_link->bw_current = bw;
88   gtnets_link->lat_current = lat;
89   gtnets_link->id = link_count;
90   xbt_dict_set(network_link_set, name, gtnets_link, network_link_free);
91
92   return;
93 }
94
95 /* free the network card */
96 static void network_card_free(void *nw_card)
97 {
98   free(((network_card_GTNETS_t)nw_card)->name);
99   free(nw_card);
100 }
101
102 /* Instantiate a new network card: MODIFYED BY KF */
103 static int network_card_new(const char *name)
104 {
105   static int card_count=-1;
106
107   /* KF: Check that we haven't seen the network card before */ 
108   if (xbt_dict_get_or_null(network_card_set, name)) 
109     return;
110
111   /* KF: Increment the card counter for GTNetS */
112   card_count++;
113
114   /* KF: just use the dictionary to map link names to link indices */
115   gtnets_network_card = xbt_new0(s_network_card_GTNETS_t,1);
116   gtnets_network_card->name = strcpy(name);
117   gtnets_network_card->id = card_count;
118   xbt_dict_set(network_card_set, name, gtnets_network_card, network_card_free);
119
120   /* KF: just return the GTNetS ID as the SURF ID */
121   return card_count;
122 }
123
124 /* Instantiate a new route: MODIFY BY KF */
125 static void route_new(int src_id, int dst_id, char **links, int nb_link)
126 {
127 #if 0
128   network_link_GTNETS_t *link_list = NULL;
129   int i;
130
131   ROUTE_SIZE(src_id, dst_id) = nb_link;
132   link_list = (ROUTE(src_id, dst_id) = xbt_new0(network_link_GTNETS_t, nb_link));
133   for (i = 0; i < nb_link; i++) {
134     link_list[i] = xbt_dict_get_or_null(network_link_set, links[i]);
135     free(links[i]);
136   }
137   free(links);
138 #endif
139   int i;
140   int *gtnets_links;
141  
142   /* KF: Build the list of gtnets link IDs */
143   gtnets_links = (int *)calloc(nb_link, sizeof(int));
144   for (i=0; i<nb_link; i++) {
145     gtnets_links[i]=(int)(xbt_dict_get(network_link_set, links[i]))
146   }
147
148   /* KF: Create the GTNets route */
149   if (GTNetS_add_route(src_id, dst_id, gtnets_links, nb_link)) {
150     xbt_assert0(0,"Cannot create GTNetS route");
151   }
152 }
153
154 /* Parse the XML for a network link */
155 static void parse_network_link(void)
156 {
157   char *name;
158   double bw;
159   double lat;
160   e_surf_network_link_state_t state;
161
162   name = xbt_strdup(A_surfxml_network_link_name);
163   surf_parse_get_double(&bw,A_surfxml_network_link_bandwidth);
164   surf_parse_get_double(&lat,A_surfxml_network_link_latency);
165   state = SURF_NETWORK_LINK_ON;
166
167   /* Print values when no traces are specified */
168   {
169     tmgr_trace_t bw_trace;
170     tmgr_trace_t state;
171     tmgr_trace_t lat_trace;
172
173     surf_parse_get_trace(&bw_trace, A_surfxml_network_link_bandwidth_file);
174     surf_parse_get_trace(&lat_trace, A_surfxml_network_link_latency_file);
175     surf_parse_get_trace(&state_trace,A_surfxml_network_link_state_file);
176   
177     if (bw_trace) 
178       WARNING0("The GTNetS network model doesn't support bandwidth state traces");
179     if (lat_trace)
180       WARNING0("The GTNetS network model doesn't support latency state traces");
181     if (state_trace)
182       WARNING0("The GTNetS network model doesn't support link state traces");
183   }
184
185   /* KF: remove several arguments to network_link_new */
186   network_link_new(name, bw, lat);
187 }
188
189 static int nb_link = 0;
190 static char **link_name = NULL;
191 static int src_id = -1;
192 static int dst_id = -1;
193
194 /* Parses a route from the XML: UNMODIFIED BY HC */
195 static void parse_route_set_endpoints(void)
196 {
197   src_id = network_card_new(A_surfxml_route_src);
198   dst_id = network_card_new(A_surfxml_route_dst);
199   nb_link = 0;
200   link_name = NULL;
201 }
202
203 /* Parses a route element from the XML: UNMODIFIED BY HC */
204 static void parse_route_elem(void)
205 {
206   nb_link++;
207   link_name = xbt_realloc(link_name, (nb_link) * sizeof(char *));
208   link_name[(nb_link) - 1] = xbt_strdup(A_surfxml_route_element_name);
209 }
210
211 /* Create the route: UNMODIFIED BY HC */
212 static void parse_route_set_route(void)
213 {
214   route_new(src_id, dst_id, link_name, nb_link);
215 }
216
217 /* Main XML parsing */
218 static void parse_file(const char *file)
219 {
220   /* Figuring out the network links */
221   surf_parse_reset_parser();
222   ETag_surfxml_network_link_fun=parse_network_link;
223   surf_parse_open(file);
224   xbt_assert1((!surf_parse()),"Parse error in %s",file);
225   surf_parse_close();
226
227   /* Figuring out the network cards used */
228   surf_parse_reset_parser();
229   STag_surfxml_route_fun=parse_route_set_endpoints;
230   surf_parse_open(file);
231   xbt_assert1((!surf_parse()),"Parse error in %s",file);
232   surf_parse_close();
233
234   /* Building the routes */
235   surf_parse_reset_parser();
236   STag_surfxml_route_fun=parse_route_set_endpoints;
237   ETag_surfxml_route_element_fun=parse_route_elem;
238   ETag_surfxml_route_fun=parse_route_set_route;
239   surf_parse_open(file);
240   xbt_assert1((!surf_parse()),"Parse error in %s",file);
241   surf_parse_close();
242 }
243
244 static void *name_service(const char *name)
245 {
246   return xbt_dict_get_or_null(network_card_set, name);
247 }
248
249 static const char *get_resource_name(void *resource_id)
250 {
251   return ((network_card_GTNETS_t) resource_id)->name;
252 }
253
254 /* We do not care about this: only used for traces */
255 static int resource_used(void *resource_id)
256 {
257   return 0; /* We don't care */
258 }
259
260 static int action_free(surf_action_t action)
261 {
262   action->using--;
263   if(!action->using) {
264     xbt_swag_remove(action, action->state_set);
265     /* KF: No explicit freeing needed for GTNeTS here */
266     free(action);
267   }
268   return 1;
269 }
270
271 static void action_use(surf_action_t action)
272 {
273   action->using++;
274 }
275
276 static void action_cancel(surf_action_t action)
277 {
278   xbt_assert0(0,"Cannot cancel GTNetS flow");
279   return;
280 }
281
282 static void action_recycle(surf_action_t action)
283 {
284   xbt_assert0(0,"Cannot recycle GTNetS flow");
285   return;
286 }
287
288 static void action_change_state(surf_action_t action,
289                                 e_surf_action_state_t state)
290 {
291 /*   if((state==SURF_ACTION_DONE) || (state==SURF_ACTION_FAILED)) */
292 /*     if(((surf_action_network_GTNETS_t)action)->variable) { */
293 /*       lmm_variable_disable(maxmin_system, ((surf_action_network_GTNETS_t)action)->variable); */
294 /*       ((surf_action_network_GTNETS_t)action)->variable = NULL; */
295 /*     } */
296
297   surf_action_change_state(action, state);
298   return;
299 }
300
301
302 /* share_resources() */
303 static double share_resources(double now)
304 {
305 #if 0
306   s_surf_action_network_GTNETS_t s_action;
307   surf_action_network_GTNETS_t action = NULL;
308   xbt_swag_t running_actions = surf_network_resource->common_public->states.running_action_set;
309 #endif
310
311   return GTNetS_get_time_to_next_flow_completion();
312 }
313
314 /* delta: by how many time units the simulation must advance */
315 /* In this function: change the state of actions that terminate */
316 /* The delta may not come from the network, and thus may be different (smaller) 
317    than the one returned by the function above */
318 /* If the delta is a network-caused min, then do not emulate any timer in the
319    network simulation, otherwise fake a timer somehow to advance the simulation of min seconds */
320
321 static void update_actions_state(double now, double delta)
322 {
323   surf_action_network_GTNETS_t action = NULL;
324   surf_action_network_GTNETS_t next_action = NULL;
325   xbt_swag_t running_actions =
326       surf_network_resource->common_public->states.running_action_set;
327
328   double time_to_next_flow_completion =  GTNetS_get_time_to_next_flow_completion();
329   
330   /* If there are no renning flows, just return */
331   if (time_to_next_flow_completion < 0.0) {
332     return;
333   }
334   
335   if (time_to_next_flow_completion < delta) { /* run until the first flow completes */
336     void **metadata; 
337     int i,num_flows;
338
339     if (GTNetS_run_until_next_flow_completion(&metadata, &num_flows)) {
340       xbt_assert0(0,"Cannot run GTNetS simulation until next flow completion");
341     }
342     if (num_flows < 1) {
343       xbt_assert0(0,"GTNetS simulation couldn't find a flow that would complete");
344     }
345
346     for (i=0; i<num_flows; i++) {
347       surf_action_t action = (surf_action_t)(metadata[i]);
348
349       action->generic_action.remains = 0;
350       action->generic_action.finish =  now + time_to_next_flow_completion;
351       action->generic_action.finish =  SURF_ACTION_DONE;
352       /* TODO: Anything else here? */
353     }
354   } else { /* run for a given number of seconds */
355     if (GTNetS_run(delta)) {
356       xbt_assert0(0,"Cannot run GTNetS simulation");
357     }
358   }
359   
360   return;
361 }
362
363 /* UNUSED HERE: no traces */
364 static void update_resource_state(void *id,
365                                   tmgr_trace_event_t event_type,
366                                   double value)
367 {
368   xbt_assert0(0,"Cannot update resource state for GTNetS simulation");
369   return;
370 }
371
372 /* KF: Rate not supported */
373 static surf_action_t communicate(void *src, void *dst, double size, double rate)
374 {
375   surf_action_network_GTNETS_t action = NULL;
376   network_card_GTNETS_t card_src = src;
377   network_card_GTNETS_t card_dst = dst;
378 /*
379   int route_size = ROUTE_SIZE(card_src->id, card_dst->id);
380   network_link_GTNETS_t *route = ROUTE(card_src->id, card_dst->id);
381 */
382   int i;
383
384 /*
385   xbt_assert2(route_size,"You're trying to send data from %s to %s but there is no connexion between these two cards.", card_src->name, card_dst->name);
386 */
387
388   action = xbt_new0(s_surf_action_network_GTNETS_t, 1);
389
390   action->generic_action.using = 1; 
391   action->generic_action.cost = size;
392   action->generic_action.remains = size;
393   /* Max durations are not supported */
394   action->generic_action.max_duration = NO_MAX_DURATION;
395   action->generic_action.start = surf_get_clock(); 
396   action->generic_action.finish = -1.0; 
397   action->generic_action.resource_type =
398       (surf_resource_t) surf_network_resource;
399
400   action->generic_action.state_set =
401       surf_network_resource->common_public->states.running_action_set;
402
403   xbt_swag_insert(action, action->generic_action.state_set);
404
405   /* KF: Add a flow to the GTNets Simulation, associated to this action */
406   if (GTNetS_create_flow(src->id, dst->id, size, (void *)action) < 0) {
407     xbt_assert2(0,"Not route between host %s and host %s", card_src->name, card_dst->name);
408   }
409
410   return (surf_action_t) action;
411 }
412
413 /* Suspend a flow() */
414 static void action_suspend(surf_action_t action)
415 {
416   xbt_assert0(0,"action_suspend() not supported for the GTNets network model");
417 }
418
419 /* Resume a flow() */
420 static void action_resume(surf_action_t action)
421 {
422   xbt_assert0(0,"action_resume() not supported for the GTNets network model");
423 }
424
425 /* Test whether a flow is suspended */
426 static int action_is_suspended(surf_action_t action)
427 {
428   return 0;
429 }
430
431 static void finalize(void)
432 {
433   int i,j;
434
435   xbt_dict_free(&network_card_set);
436   xbt_dict_free(&network_link_set);
437   xbt_swag_free(surf_network_resource->common_public->states.
438                 ready_action_set);
439   xbt_swag_free(surf_network_resource->common_public->states.
440                 running_action_set);
441   xbt_swag_free(surf_network_resource->common_public->states.
442                 failed_action_set);
443   xbt_swag_free(surf_network_resource->common_public->states.
444                 done_action_set);
445   free(surf_network_resource->common_public);
446   free(surf_network_resource->common_private);
447   free(surf_network_resource->extension_public);
448
449   free(surf_network_resource);
450   surf_network_resource = NULL;
451
452 #if 0
453   for (i = 0; i < card_number; i++) 
454     for (j = 0; j < card_number; j++) 
455       free(ROUTE(i,j));
456   free(routing_table);
457   routing_table = NULL;
458   free(routing_table_size);
459   routing_table_size = NULL;
460   card_number = 0;
461 #endif
462
463   /* ADDED BY KF */
464   GTNetS_finalize();
465   /* END ADDITION */
466 }
467
468 static void surf_network_resource_init_internal(void)
469 {
470   s_surf_action_t action;
471
472   surf_network_resource = xbt_new0(s_surf_network_resource_t, 1);
473
474   surf_network_resource->common_private =
475       xbt_new0(s_surf_resource_private_t, 1);
476   surf_network_resource->common_public =
477       xbt_new0(s_surf_resource_public_t, 1);
478   surf_network_resource->extension_public =
479       xbt_new0(s_surf_network_resource_extension_public_t, 1);
480
481   surf_network_resource->common_public->states.ready_action_set =
482       xbt_swag_new(xbt_swag_offset(action, state_hookup));
483   surf_network_resource->common_public->states.running_action_set =
484       xbt_swag_new(xbt_swag_offset(action, state_hookup));
485   surf_network_resource->common_public->states.failed_action_set =
486       xbt_swag_new(xbt_swag_offset(action, state_hookup));
487   surf_network_resource->common_public->states.done_action_set =
488       xbt_swag_new(xbt_swag_offset(action, state_hookup));
489
490   surf_network_resource->common_public->name_service = name_service;
491   surf_network_resource->common_public->get_resource_name =
492       get_resource_name;
493   surf_network_resource->common_public->action_get_state =
494       surf_action_get_state;
495   surf_network_resource->common_public->action_use = action_use;
496   surf_network_resource->common_public->action_free = action_free;
497   surf_network_resource->common_public->action_cancel = action_cancel;
498   surf_network_resource->common_public->action_recycle = action_recycle;
499   surf_network_resource->common_public->action_change_state =
500       action_change_state;
501   surf_network_resource->common_public->action_set_data = surf_action_set_data;
502   surf_network_resource->common_public->name = "network";
503
504   surf_network_resource->common_private->resource_used = resource_used;
505   surf_network_resource->common_private->share_resources = share_resources;
506   surf_network_resource->common_private->update_actions_state =
507       update_actions_state;
508   surf_network_resource->common_private->update_resource_state =
509       update_resource_state;
510   surf_network_resource->common_private->finalize = finalize;
511
512   surf_network_resource->common_public->suspend = action_suspend;
513   surf_network_resource->common_public->resume = action_resume;
514   surf_network_resource->common_public->is_suspended = action_is_suspended;
515
516   surf_network_resource->extension_public->communicate = communicate;
517
518   network_link_set = xbt_dict_new();
519   network_card_set = xbt_dict_new();
520
521   /* HC: I am assuming that this stays in for simulation of compute tasks */
522   xbt_assert0(maxmin_system, "surf_init has to be called first!");
523
524   /* KF: Added the initialization for GTNetS interface */
525   if (GTNetS_initialize()) {
526     xbt_assert0(0, "impossible to initialize GTNetS interface");
527   }
528 }
529
530 /* HC: I put this prototype here for now but it will have to go in 
531    src/include/surf.h when it is functionnal. */
532 void surf_network_resource_init_GTNETS(const char *filename);
533
534 void surf_network_resource_init_GTNETS(const char *filename)
535 {
536   if (surf_network_resource)
537     return;
538   surf_network_resource_init_internal();
539   parse_file(filename);
540   xbt_dynar_push(resource_list, &surf_network_resource);
541 }