Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
Fix some memory leak.
[simgrid.git] / src / surf / network.c
1
2 /*
3  * Network with improved management of tasks, IM (Improved Management).
4  * Uses a heap to store actions so that the share_resources is faster.
5  * This model automatically sets the selective update flag to 1 and is
6  * highly dependent on the maxmin lmm module.
7  */
8
9 /* Copyright (c) 2009, 2010, 2011. The SimGrid Team.
10  * All rights reserved.                                                     */
11
12 /* This program is free software; you can redistribute it and/or modify it
13  * under the terms of the license (GNU LGPL) which comes with this package. */
14
15 #include "network_private.h"
16 #include "xbt/log.h"
17 #include "xbt/str.h"
18
19 #include "surf_private.h"
20 #include "xbt/dict.h"
21 #include "maxmin_private.h"
22 #include "surf/surfxml_parse_values.h"
23 #include "surf/surf_resource.h"
24 #include "surf/surf_resource_lmm.h"
25
26 #undef GENERIC_ACTION
27 #define GENERIC_ACTION(action) action->generic_action
28
29 XBT_LOG_NEW_DEFAULT_SUBCATEGORY(surf_network, surf,
30                                 "Logging specific to the SURF network module");
31
32 surf_model_t surf_network_model = NULL;
33 static lmm_system_t network_maxmin_system = NULL;
34 static void (*network_solve) (lmm_system_t) = NULL;
35
36 xbt_dynar_t smpi_bw_factor = NULL;
37 xbt_dynar_t smpi_lat_factor = NULL;
38
39 typedef struct s_smpi_factor *smpi_factor_t;
40 typedef struct s_smpi_factor {
41         long factor;
42         double value;
43 } s_smpi_factor_t;
44
45 double sg_sender_gap = 0.0;
46 double sg_latency_factor = 1.0; /* default value; can be set by model or from command line */
47 double sg_bandwidth_factor = 1.0;       /* default value; can be set by model or from command line */
48 double sg_weight_S_parameter = 0.0;     /* default value; can be set by model or from command line */
49
50 double sg_tcp_gamma = 0.0;
51 int sg_network_crosstraffic = 0;
52
53 xbt_dict_t gap_lookup = NULL;
54
55 e_UM_t network_update_mechanism = UM_UNDEFINED;
56 static int net_selective_update = 0;
57
58 static int net_action_is_suspended(surf_action_t action);
59 static void update_action_remaining(double now);
60
61 static xbt_swag_t net_modified_set = NULL;
62 static xbt_heap_t net_action_heap = NULL;
63 xbt_swag_t keep_track = NULL;
64
65 /* added to manage the communication action's heap */
66 static void net_action_update_index_heap(void *action, int i)
67 {
68   ((surf_action_network_CM02_t) action)->index_heap = i;
69 }
70
71 /* insert action on heap using a given key and a hat (heap_action_type)
72  * a hat can be of three types for communications:
73  *
74  * NORMAL = this is a normal heap entry stating the date to finish transmitting
75  * LATENCY = this is a heap entry to warn us when the latency is payed
76  * MAX_DURATION =this is a heap entry to warn us when the max_duration limit is reached
77  */
78 static void heap_insert(surf_action_network_CM02_t    action, double key, enum heap_action_type hat){
79   action->hat = hat;
80   xbt_heap_push(net_action_heap, action, key);
81 }
82
83 static void heap_remove(surf_action_network_CM02_t action){
84   action->hat = NONE;
85   if(((surf_action_network_CM02_t) action)->index_heap >= 0){
86       xbt_heap_remove(net_action_heap,action->index_heap);
87   }
88 }
89
90 /******************************************************************************/
91 /*                           Factors callbacks                                */
92 /******************************************************************************/
93 static double constant_latency_factor(double size)
94 {
95   return sg_latency_factor;
96 }
97
98 static double constant_bandwidth_factor(double size)
99 {
100   return sg_bandwidth_factor;
101 }
102
103 static double constant_bandwidth_constraint(double rate, double bound,
104                                             double size)
105 {
106   return rate;
107 }
108
109 /**********************/
110 /*   SMPI callbacks   */
111 /**********************/
112 static double smpi_bandwidth_factor(double size)
113 {
114         char *value = NULL;
115         unsigned int iter = 0;
116         smpi_factor_t fact = NULL;
117
118         if(!smpi_bw_factor){
119                 xbt_dynar_t radical_elements,radical_elements2 = NULL;
120
121                 char *smpi_coef_string = xbt_cfg_get_string(_surf_cfg_set,"smpi/bw_factor");
122                 smpi_bw_factor = xbt_dynar_new(sizeof(smpi_factor_t),free);
123                 radical_elements = xbt_str_split(smpi_coef_string, ";");
124                 xbt_dynar_foreach(radical_elements, iter, value) {
125
126                         radical_elements2 = xbt_str_split(value, ":");
127                         if(xbt_dynar_length(radical_elements2) != 2)
128                                 xbt_die("Malformed radical for smpi/bw_factor!");
129                         fact = xbt_new(s_smpi_factor_t,1);
130                         fact->factor = atol(xbt_dynar_get_as(radical_elements2,0,char*));
131                         fact->value = atof(xbt_dynar_get_as(radical_elements2,1,char*));
132                         xbt_dynar_push_as(smpi_bw_factor,smpi_factor_t,fact);
133                         XBT_DEBUG("smpi_bandwidth_factor:\t%ld : %f",fact->factor,fact->value);
134                         xbt_dynar_free(&radical_elements2);
135                 }
136                 xbt_dynar_free(&radical_elements);
137         }
138
139         xbt_dynar_foreach(smpi_bw_factor, iter, fact) {
140                 if(size >= fact->factor)
141                 {
142                         XBT_DEBUG("%lf >= %ld return %f",size,fact->factor,fact->value);
143                         return fact->value;
144                 }
145
146         }
147
148     return 1.0;
149 }
150
151 static double smpi_latency_factor(double size)
152 {
153         char *value = NULL;
154         unsigned int iter = 0;
155         smpi_factor_t fact = NULL;
156
157         if(!smpi_lat_factor){
158                 xbt_dynar_t radical_elements,radical_elements2 = NULL;
159
160                 char *smpi_coef_string = xbt_cfg_get_string(_surf_cfg_set,"smpi/lat_factor");
161                 smpi_lat_factor = xbt_dynar_new(sizeof(smpi_factor_t),free);
162                 radical_elements = xbt_str_split(smpi_coef_string, ";");
163                 xbt_dynar_foreach(radical_elements, iter, value) {
164
165                         radical_elements2 = xbt_str_split(value, ":");
166                         if(xbt_dynar_length(radical_elements2) != 2)
167                                 xbt_die("Malformed radical for smpi/lat_factor!");
168                         fact = xbt_new(s_smpi_factor_t,1);
169                         fact->factor = atol(xbt_dynar_get_as(radical_elements2,0,char*));
170                         fact->value = atof(xbt_dynar_get_as(radical_elements2,1,char*));
171                         xbt_dynar_push_as(smpi_lat_factor,smpi_factor_t,fact);
172                         XBT_DEBUG("smpi_latency_factor:\t%ld : %f",fact->factor,fact->value);
173                         xbt_dynar_free(&radical_elements2);
174                 }
175                 xbt_dynar_free(&radical_elements);
176         }
177
178         xbt_dynar_foreach(smpi_lat_factor, iter, fact) {
179                 if(size >= fact->factor)
180                 {
181                         XBT_DEBUG("%lf >= %ld return %f",size,fact->factor,fact->value);
182                         return fact->value;
183                 }
184         }
185
186     return 1.0;
187 }
188 /**--------- <copy/paste C code snippet in surf/network.c> -----------*/
189
190 static double smpi_bandwidth_constraint(double rate, double bound,
191                                         double size)
192 {
193   return rate < 0 ? bound : min(bound, rate * smpi_bandwidth_factor(size));
194 }
195
196 static double (*latency_factor_callback) (double) =
197     &constant_latency_factor;
198 static double (*bandwidth_factor_callback) (double) =
199     &constant_bandwidth_factor;
200 static double (*bandwidth_constraint_callback) (double, double, double) =
201     &constant_bandwidth_constraint;
202
203 static void (*gap_append) (double, const link_CM02_t, surf_action_network_CM02_t) = NULL;
204 static void (*gap_remove) (surf_action_network_CM02_t) = NULL;
205
206 static void* net_create_resource(const char *name,
207                                 double bw_initial,
208                                 tmgr_trace_t bw_trace,
209                                 double lat_initial,
210                                 tmgr_trace_t lat_trace,
211                                 e_surf_resource_state_t
212                                 state_initial,
213                                 tmgr_trace_t state_trace,
214                                 e_surf_link_sharing_policy_t
215                                 policy, xbt_dict_t properties)
216 {
217   link_CM02_t nw_link = (link_CM02_t)
218       surf_resource_lmm_new(sizeof(s_link_CM02_t),
219                             surf_network_model, name, properties,
220                             network_maxmin_system,
221                             sg_bandwidth_factor * bw_initial,
222                             history,
223                             state_initial, state_trace,
224                             bw_initial, bw_trace);
225
226   xbt_assert(!xbt_lib_get_or_null(link_lib, name, SURF_LINK_LEVEL),
227               "Link '%s' declared several times in the platform file.",
228               name);
229
230   nw_link->lat_current = lat_initial;
231   if (lat_trace)
232     nw_link->lat_event =
233         tmgr_history_add_trace(history, lat_trace, 0.0, 0, nw_link);
234
235   if (policy == SURF_LINK_FATPIPE)
236     lmm_constraint_shared(nw_link->lmm_resource.constraint);
237
238   xbt_lib_set(link_lib, name, SURF_LINK_LEVEL, nw_link);
239
240   return nw_link;
241 }
242
243 static void net_parse_link_init(sg_platf_link_cbarg_t link)
244 {
245   if(link->policy == SURF_LINK_FULLDUPLEX){
246     char *link_id;
247     link_id = bprintf("%s_UP", link->id);
248           net_create_resource(link_id,
249                            link->bandwidth,
250                            link->bandwidth_trace,
251                            link->latency,
252                            link->latency_trace,
253                            link->state,
254                            link->state_trace,
255                            link->policy,
256                            link->properties);
257           xbt_free(link_id);
258     link_id = bprintf("%s_DOWN", link->id);
259     net_create_resource(link_id,
260                         link->bandwidth,
261                         link->bandwidth_trace,
262                         link->latency,
263                         link->latency_trace,
264                         link->state,
265                         link->state_trace,
266                         link->policy,
267                         link->properties);
268     xbt_free(link_id);
269   }
270   else{
271     net_create_resource(link->id,
272                         link->bandwidth,
273                         link->bandwidth_trace,
274                         link->latency,
275                         link->latency_trace,
276                         link->state,
277                         link->state_trace,
278                         link->policy,
279                         link->properties);
280   }
281 }
282
283 static void net_add_traces(void)
284 {
285   xbt_dict_cursor_t cursor = NULL;
286   char *trace_name, *elm;
287
288   static int called = 0;
289   if (called)
290     return;
291   called = 1;
292
293   /* connect all traces relative to network */
294   xbt_dict_foreach(trace_connect_list_link_avail, cursor, trace_name, elm) {
295     tmgr_trace_t trace = xbt_dict_get_or_null(traces_set_list, trace_name);
296     link_CM02_t link =
297                 xbt_lib_get_or_null(link_lib, elm, SURF_LINK_LEVEL);
298
299     xbt_assert(link, "Cannot connect trace %s to link %s: link undefined",
300                 trace_name, elm);
301     xbt_assert(trace,
302                 "Cannot connect trace %s to link %s: trace undefined",
303                 trace_name, elm);
304
305     link->lmm_resource.state_event =
306         tmgr_history_add_trace(history, trace, 0.0, 0, link);
307   }
308
309   xbt_dict_foreach(trace_connect_list_bandwidth, cursor, trace_name, elm) {
310     tmgr_trace_t trace = xbt_dict_get_or_null(traces_set_list, trace_name);
311     link_CM02_t link =
312                 xbt_lib_get_or_null(link_lib, elm, SURF_LINK_LEVEL);
313
314     xbt_assert(link, "Cannot connect trace %s to link %s: link undefined",
315                 trace_name, elm);
316     xbt_assert(trace,
317                 "Cannot connect trace %s to link %s: trace undefined",
318                 trace_name, elm);
319
320     link->lmm_resource.power.event =
321         tmgr_history_add_trace(history, trace, 0.0, 0, link);
322   }
323
324   xbt_dict_foreach(trace_connect_list_latency, cursor, trace_name, elm) {
325     tmgr_trace_t trace = xbt_dict_get_or_null(traces_set_list, trace_name);
326     link_CM02_t link =
327                 xbt_lib_get_or_null(link_lib, elm, SURF_LINK_LEVEL);
328
329     xbt_assert(link, "Cannot connect trace %s to link %s: link undefined",
330                 trace_name, elm);
331     xbt_assert(trace,
332                 "Cannot connect trace %s to link %s: trace undefined",
333                 trace_name, elm);
334
335     link->lat_event = tmgr_history_add_trace(history, trace, 0.0, 0, link);
336   }
337 }
338
339 static void net_define_callbacks(void)
340 {
341   /* Figuring out the network links */
342   sg_platf_link_add_cb(net_parse_link_init);
343   sg_platf_postparse_add_cb(net_add_traces);
344 }
345
346 static int net_resource_used(void *resource_id)
347 {
348   return lmm_constraint_used(network_maxmin_system,
349                              ((surf_resource_lmm_t)
350                               resource_id)->constraint);
351 }
352
353 static int net_action_unref(surf_action_t action)
354 {
355   action->refcount--;
356   if (!action->refcount) {
357     xbt_swag_remove(action, action->state_set);
358     if (((surf_action_network_CM02_t) action)->variable){
359       lmm_variable_free(network_maxmin_system,
360                         ((surf_action_network_CM02_t) action)->variable);
361     }
362     if(network_update_mechanism == UM_LAZY){// remove action from the heap
363       heap_remove((surf_action_network_CM02_t) action);
364       xbt_swag_remove(action, net_modified_set);
365     }
366 #ifdef HAVE_TRACING
367     xbt_free(((surf_action_network_CM02_t) action)->src_name);
368     xbt_free(((surf_action_network_CM02_t) action)->dst_name);
369     xbt_free(action->category);
370 #endif
371     surf_action_free(&action);
372     return 1;
373   }
374   return 0;
375 }
376
377
378
379 static void net_action_cancel(surf_action_t action)
380 {
381         XBT_DEBUG("cancel action %p",action);
382   surf_network_model->action_state_set(action, SURF_ACTION_FAILED);
383   if(network_update_mechanism == UM_LAZY){// remove action from the heap
384     xbt_swag_remove(action, net_modified_set);
385     heap_remove((surf_action_network_CM02_t) action);
386   }
387 }
388
389 void net_action_recycle(surf_action_t action)
390 {
391   return;
392 }
393
394 #ifdef HAVE_LATENCY_BOUND_TRACKING
395 static int net_get_link_latency_limited(surf_action_t action)
396 {
397   return action->latency_limited;
398 }
399 #endif
400
401 double net_action_get_remains(surf_action_t action)
402 {
403   if(network_update_mechanism == UM_LAZY)/* update remains before return it */
404     update_action_remaining(surf_get_clock());
405   return action->remains;
406 }
407
408 static void update_action_remaining(double now){
409   surf_action_network_CM02_t action = NULL;
410   double delta = 0.0;
411
412   xbt_swag_foreach(action, net_modified_set) {
413
414     if(action->suspended != 0){
415         continue;
416     }
417
418     delta = now - action->last_update;
419
420     double_update(&(action->generic_action.remains),
421                   lmm_variable_getvalue(action->variable) * delta);
422
423     if (action->generic_action.max_duration != NO_MAX_DURATION)
424       double_update(&(action->generic_action.max_duration), delta);
425
426     if ((action->generic_action.remains <= 0) &&
427         (lmm_get_variable_weight(action->variable) > 0)) {
428       action->generic_action.finish = surf_get_clock();
429       surf_network_model->action_state_set((surf_action_t) action,
430                                            SURF_ACTION_DONE);
431       heap_remove(action);
432     } else if ((action->generic_action.max_duration != NO_MAX_DURATION)
433                && (action->generic_action.max_duration <= 0)) {
434       action->generic_action.finish = surf_get_clock();
435       surf_network_model->action_state_set((surf_action_t) action,
436                                            SURF_ACTION_DONE);
437       heap_remove(action);
438     }
439
440     action->last_update = now;
441   }
442 }
443
444 static double net_share_resources_full(double now)
445 {
446   s_surf_action_network_CM02_t s_action;
447   surf_action_network_CM02_t action = NULL;
448   xbt_swag_t running_actions =
449       surf_network_model->states.running_action_set;
450   double min;
451
452   min = generic_maxmin_share_resources(running_actions,
453                                        xbt_swag_offset(s_action,
454                                                        variable),
455                                        network_maxmin_system,
456                                        network_solve);
457
458 #define VARIABLE(action) (*((lmm_variable_t*)(((char *) (action)) + xbt_swag_offset(s_action, variable)  )))
459
460   xbt_swag_foreach(action, running_actions) {
461 #ifdef HAVE_LATENCY_BOUND_TRACKING
462     if (lmm_is_variable_limited_by_latency(action->variable)) {
463       (action->generic_action).latency_limited = 1;
464     } else {
465       (action->generic_action).latency_limited = 0;
466     }
467 #endif
468     if (action->latency > 0) {
469       min = (min<0)?action->latency:min(min,action->latency);
470     }
471   }
472
473   XBT_DEBUG("Min of share resources %f", min);
474
475   return min;
476 }
477
478 static double net_share_resources_lazy(double now)
479 {
480   surf_action_network_CM02_t action = NULL;
481   double min=-1;
482   double value;
483
484   XBT_DEBUG("Before share resources, the size of modified actions set is %d", xbt_swag_size(net_modified_set));
485   update_action_remaining(now);
486
487   keep_track = net_modified_set;
488   lmm_solve(network_maxmin_system);
489   keep_track = NULL;
490
491   XBT_DEBUG("After share resources, The size of modified actions set is %d", xbt_swag_size(net_modified_set));
492
493   xbt_swag_foreach(action, net_modified_set) {
494     int max_dur_flag = 0;
495
496     if (GENERIC_ACTION(action).state_set != surf_network_model->states.running_action_set){
497       continue;
498     }
499
500     /* bogus priority, skip it */
501     if (GENERIC_ACTION(action).priority <= 0){
502       continue;
503     }
504
505     min = -1;
506     value = lmm_variable_getvalue(action->variable);
507     if (value > 0) {
508       if (GENERIC_ACTION(action).remains > 0) {
509         value = GENERIC_ACTION(action).remains / value;
510         min = now + value;
511       } else {
512         value = 0.0;
513         min = now;
514       }
515     }
516
517     if ((GENERIC_ACTION(action).max_duration != NO_MAX_DURATION)
518         && (min == -1
519             || GENERIC_ACTION(action).start +
520             GENERIC_ACTION(action).max_duration < min)){
521       min =   GENERIC_ACTION(action).start +
522           GENERIC_ACTION(action).max_duration;
523       max_dur_flag = 1;
524     }
525
526     XBT_DEBUG("Action(%p) Start %lf Finish %lf Max_duration %lf", action,
527         GENERIC_ACTION(action).start, now + value,
528         GENERIC_ACTION(action).max_duration);
529
530     if (action->index_heap >= 0) {
531       heap_remove((surf_action_network_CM02_t) action);
532     }
533
534     if (min != -1) {
535       heap_insert((surf_action_network_CM02_t) action, min, max_dur_flag?MAX_DURATION:NORMAL);
536       XBT_DEBUG("Insert at heap action(%p) min %lf now %lf", action, min, now);
537     }
538   }
539
540   //hereafter must have already the min value for this resource model
541   if(xbt_heap_size(net_action_heap) > 0 ){
542     min = xbt_heap_maxkey(net_action_heap) - now ;
543   }else{
544     min = -1;
545   }
546
547   XBT_DEBUG("The minimum with the HEAP %lf", min);
548
549   return min;
550 }
551
552 static void net_update_actions_state_full(double now, double delta)
553 {
554   double deltap = 0.0;
555   surf_action_network_CM02_t action = NULL;
556   surf_action_network_CM02_t next_action = NULL;
557   xbt_swag_t running_actions =
558       surf_network_model->states.running_action_set;
559   /*
560      xbt_swag_t failed_actions =
561      surf_network_model->states.failed_action_set;
562    */
563
564   xbt_swag_foreach_safe(action, next_action, running_actions) {
565     deltap = delta;
566     if (action->latency > 0) {
567       if (action->latency > deltap) {
568         double_update(&(action->latency), deltap);
569         deltap = 0.0;
570       } else {
571         double_update(&(deltap), action->latency);
572         action->latency = 0.0;
573       }
574       if ((action->latency == 0.0) && !(action->suspended))
575         lmm_update_variable_weight(network_maxmin_system, action->variable,
576                                    action->weight);
577     }
578 #ifdef HAVE_TRACING
579     if (TRACE_is_enabled()) {
580       xbt_dynar_t route=NULL;
581       routing_get_route_and_latency(action->src_name, action->dst_name,&route,NULL);
582       link_CM02_t link;
583       unsigned int i;
584       xbt_dynar_foreach(route, i, link) {
585         TRACE_surf_link_set_utilization(link->lmm_resource.generic_resource.name,
586                                         action->generic_action.data,
587                                         (surf_action_t) action,
588                                         lmm_variable_getvalue
589                                         (action->variable), now - delta,
590                                         delta);
591       }
592     }
593 #endif
594     if(!lmm_get_number_of_cnst_from_var(network_maxmin_system, action->variable)) {
595         /* There is actually no link used, hence an infinite bandwidth.
596          * This happens often when using models like vivaldi.
597          * In such case, just make sure that the action completes immediately.
598          */
599       double_update(&(action->generic_action.remains),
600           action->generic_action.remains);
601     }
602     double_update(&(action->generic_action.remains),
603                   lmm_variable_getvalue(action->variable) * deltap);
604     if (action->generic_action.max_duration != NO_MAX_DURATION)
605       double_update(&(action->generic_action.max_duration), delta);
606
607     if ((action->generic_action.remains <= 0) &&
608         (lmm_get_variable_weight(action->variable) > 0)) {
609       action->generic_action.finish = surf_get_clock();
610       surf_network_model->action_state_set((surf_action_t) action,
611                                            SURF_ACTION_DONE);
612
613       if(gap_remove) gap_remove(action);
614     } else if ((action->generic_action.max_duration != NO_MAX_DURATION)
615                && (action->generic_action.max_duration <= 0)) {
616       action->generic_action.finish = surf_get_clock();
617       surf_network_model->action_state_set((surf_action_t) action,
618                                            SURF_ACTION_DONE);
619       if(gap_remove) gap_remove(action);
620     }
621   }
622
623   return;
624 }
625
626 static void net_update_actions_state_lazy(double now, double delta)
627 {
628   surf_action_network_CM02_t action = NULL;
629
630   while ((xbt_heap_size(net_action_heap) > 0)
631          && (double_equals(xbt_heap_maxkey(net_action_heap), now))) {
632     action = xbt_heap_pop(net_action_heap);
633     XBT_DEBUG("Action %p: finish", action);
634     GENERIC_ACTION(action).finish = surf_get_clock();
635
636     // if I am wearing a latency hat
637     if( action->hat ==  LATENCY){
638         lmm_update_variable_weight(network_maxmin_system, action->variable,
639                                            action->weight);
640         heap_remove(action);
641         action->last_update = surf_get_clock();
642
643     // if I am wearing a max_duration or normal hat
644     }else if( action->hat == MAX_DURATION || action->hat == NORMAL ){
645         // no need to communicate anymore
646         // assume that flows that reached max_duration have remaining of 0
647         GENERIC_ACTION(action).remains = 0;
648         action->generic_action.finish = surf_get_clock();
649               surf_network_model->action_state_set((surf_action_t) action,
650                                                    SURF_ACTION_DONE);
651         heap_remove(action);
652     }
653   }
654   return;
655 }
656
657 static void net_update_resource_state(void *id,
658                                       tmgr_trace_event_t event_type,
659                                       double value, double date)
660 {
661   link_CM02_t nw_link = id;
662   /*   printf("[" "%lg" "] Asking to update network card \"%s\" with value " */
663   /*     "%lg" " for event %p\n", surf_get_clock(), nw_link->name, */
664   /*     value, event_type); */
665
666   if (event_type == nw_link->lmm_resource.power.event) {
667     double delta =
668         sg_weight_S_parameter / value - sg_weight_S_parameter /
669         (nw_link->lmm_resource.power.peak *
670          nw_link->lmm_resource.power.scale);
671     lmm_variable_t var = NULL;
672     lmm_element_t elem = NULL;
673     surf_action_network_CM02_t action = NULL;
674
675     nw_link->lmm_resource.power.peak = value;
676     lmm_update_constraint_bound(network_maxmin_system,
677                                 nw_link->lmm_resource.constraint,
678                                 sg_bandwidth_factor *
679                                 (nw_link->lmm_resource.power.peak *
680                                  nw_link->lmm_resource.power.scale));
681 #ifdef HAVE_TRACING
682     TRACE_surf_link_set_bandwidth(date, (char *)(((nw_link->lmm_resource).generic_resource).name),
683                                   sg_bandwidth_factor *
684                                   (nw_link->lmm_resource.power.peak *
685                                    nw_link->lmm_resource.power.scale));
686 #endif
687     if (sg_weight_S_parameter > 0) {
688       while ((var = lmm_get_var_from_cnst
689               (network_maxmin_system, nw_link->lmm_resource.constraint,
690                &elem))) {
691         action = lmm_variable_id(var);
692         action->weight += delta;
693         if (!(action->suspended))
694           lmm_update_variable_weight(network_maxmin_system,
695                                      action->variable, action->weight);
696       }
697     }
698     if (tmgr_trace_event_free(event_type))
699       nw_link->lmm_resource.power.event = NULL;
700   } else if (event_type == nw_link->lat_event) {
701     double delta = value - nw_link->lat_current;
702     lmm_variable_t var = NULL;
703     lmm_element_t elem = NULL;
704     surf_action_network_CM02_t action = NULL;
705
706     nw_link->lat_current = value;
707     while ((var = lmm_get_var_from_cnst
708             (network_maxmin_system, nw_link->lmm_resource.constraint,
709              &elem))) {
710       action = lmm_variable_id(var);
711       action->lat_current += delta;
712       action->weight += delta;
713       if (action->rate < 0)
714         lmm_update_variable_bound(network_maxmin_system, action->variable,
715                                   sg_tcp_gamma / (2.0 *
716                                                   action->lat_current));
717       else {
718         lmm_update_variable_bound(network_maxmin_system, action->variable,
719                                   min(action->rate,
720                                       sg_tcp_gamma / (2.0 *
721                                                       action->lat_current)));
722
723         if (action->rate < sg_tcp_gamma / (2.0 * action->lat_current)) {
724           XBT_INFO("Flow is limited BYBANDWIDTH");
725         } else {
726           XBT_INFO("Flow is limited BYLATENCY, latency of flow is %f",
727                 action->lat_current);
728         }
729       }
730       if (!(action->suspended))
731         lmm_update_variable_weight(network_maxmin_system, action->variable,
732                                    action->weight);
733
734     }
735     if (tmgr_trace_event_free(event_type))
736       nw_link->lat_event = NULL;
737   } else if (event_type == nw_link->lmm_resource.state_event) {
738     if (value > 0)
739       nw_link->lmm_resource.state_current = SURF_RESOURCE_ON;
740     else {
741       lmm_constraint_t cnst = nw_link->lmm_resource.constraint;
742       lmm_variable_t var = NULL;
743       lmm_element_t elem = NULL;
744
745       nw_link->lmm_resource.state_current = SURF_RESOURCE_OFF;
746       while ((var = lmm_get_var_from_cnst
747               (network_maxmin_system, cnst, &elem))) {
748         surf_action_t action = lmm_variable_id(var);
749
750         if (surf_action_state_get(action) == SURF_ACTION_RUNNING ||
751             surf_action_state_get(action) == SURF_ACTION_READY) {
752           action->finish = date;
753           surf_network_model->action_state_set(action, SURF_ACTION_FAILED);
754         }
755       }
756     }
757     if (tmgr_trace_event_free(event_type))
758       nw_link->lmm_resource.state_event = NULL;
759   } else {
760     XBT_CRITICAL("Unknown event ! \n");
761     xbt_abort();
762   }
763
764   XBT_DEBUG("There were a resource state event, need to update actions related to the constraint (%p)", nw_link->lmm_resource.constraint);
765   return;
766 }
767
768
769 static surf_action_t net_communicate(const char *src_name,
770                                      const char *dst_name, double size,
771                                      double rate)
772 {
773   unsigned int i;
774   link_CM02_t link;
775   int failed = 0;
776   surf_action_network_CM02_t action = NULL;
777   double bandwidth_bound;
778   double latency=0.0;
779   xbt_dynar_t back_route = NULL;
780   int constraints_per_variable = 0;
781
782   xbt_dynar_t route=xbt_dynar_new(global_routing->size_of_link,NULL);
783
784   XBT_IN("(%s,%s,%g,%g)", src_name, dst_name, size, rate);
785
786   routing_get_route_and_latency(src_name, dst_name, &route, &latency);
787   xbt_assert(!xbt_dynar_is_empty(route) || latency,
788               "You're trying to send data from %s to %s but there is no connection at all between these two hosts.",
789               src_name, dst_name);
790
791   xbt_dynar_foreach(route, i, link) {
792     if (link->lmm_resource.state_current == SURF_RESOURCE_OFF) {
793       failed = 1;
794       break;
795     }
796   }
797   if (sg_network_crosstraffic == 1) {
798     routing_get_route_and_latency(dst_name, src_name, &back_route,NULL);
799     xbt_dynar_foreach(back_route, i, link) {
800       if (link->lmm_resource.state_current == SURF_RESOURCE_OFF) {
801         failed = 1;
802         break;
803       }
804     }
805   }
806
807   action =
808       surf_action_new(sizeof(s_surf_action_network_CM02_t), size,
809                       surf_network_model, failed);
810 #ifdef HAVE_LATENCY_BOUND_TRACKING
811   (action->generic_action).latency_limited = 0;
812 #endif
813   action->weight = action->latency = latency;
814
815   xbt_swag_insert(action, action->generic_action.state_set);
816   action->rate = rate;
817   if(network_update_mechanism == UM_LAZY){
818     action->index_heap = -1;
819     action->last_update = surf_get_clock();
820   }
821
822   bandwidth_bound = -1.0;
823   if(sg_weight_S_parameter>0) {
824     xbt_dynar_foreach(route, i, link) {
825       action->weight +=
826           sg_weight_S_parameter /
827           (link->lmm_resource.power.peak * link->lmm_resource.power.scale);
828     }
829   }
830   xbt_dynar_foreach(route, i, link) {
831     double bb = bandwidth_factor_callback(size) *
832         (link->lmm_resource.power.peak * link->lmm_resource.power.scale);
833     bandwidth_bound = (bandwidth_bound < 0.0)?bb:min(bandwidth_bound,bb);
834   }
835
836   action->lat_current = action->latency;
837   action->latency *= latency_factor_callback(size);
838   action->rate =
839       bandwidth_constraint_callback(action->rate, bandwidth_bound,
840                                         size);
841   if(gap_append) {
842     xbt_assert(!xbt_dynar_is_empty(route),"Using a model with a gap (e.g., SMPI) with a platform without links (e.g. vivaldi)!!!");
843
844     link = *(link_CM02_t*)xbt_dynar_get_ptr(route, 0);
845     gap_append(size, link, action);
846     XBT_DEBUG("Comm %p: %s -> %s gap=%f (lat=%f)",
847            action, src_name, dst_name, action->sender.gap, action->latency);
848   }
849
850   constraints_per_variable = xbt_dynar_length(route);
851   if (back_route != NULL)
852     constraints_per_variable += xbt_dynar_length(back_route);
853
854   if (action->latency > 0){
855       action->variable =
856         lmm_variable_new(network_maxmin_system, action, 0.0, -1.0,
857                          constraints_per_variable);
858     if(network_update_mechanism == UM_LAZY){
859       // add to the heap the event when the latency is payed
860       XBT_DEBUG("Added action (%p) one latency event at date %f", action, action->latency + action->last_update);
861       heap_insert(action, action->latency + action->last_update, xbt_dynar_is_empty(route)?NORMAL:LATENCY);
862     }
863   } else
864     action->variable =
865         lmm_variable_new(network_maxmin_system, action, 1.0, -1.0,
866                          constraints_per_variable);
867
868   if (action->rate < 0) {
869     lmm_update_variable_bound(network_maxmin_system, action->variable,
870         (action->lat_current > 0)?
871             sg_tcp_gamma / (2.0 * action->lat_current)  :-1.0);
872   } else {
873     lmm_update_variable_bound(network_maxmin_system, action->variable,
874         (action->lat_current > 0)?
875             min(action->rate, sg_tcp_gamma / (2.0 * action->lat_current))
876             :action->rate);
877   }
878
879   xbt_dynar_foreach(route, i, link) {
880     lmm_expand(network_maxmin_system, link->lmm_resource.constraint,
881                action->variable, 1.0);
882   }
883
884   if (sg_network_crosstraffic == 1) {
885     XBT_DEBUG("Fullduplex active adding backward flow using 5%%");
886     xbt_dynar_foreach(back_route, i, link) {
887       lmm_expand(network_maxmin_system, link->lmm_resource.constraint,
888                  action->variable, .05);
889     }
890   }
891
892 #ifdef HAVE_TRACING
893   if (TRACE_is_enabled()) {
894     action->src_name = xbt_strdup(src_name);
895     action->dst_name = xbt_strdup(dst_name);
896   } else {
897     action->src_name = action->dst_name = NULL;
898   }
899 #endif
900
901   xbt_dynar_free(&route);
902   XBT_OUT();
903
904   return (surf_action_t) action;
905 }
906
907 static xbt_dynar_t net_get_route(const char *src, const char *dst)
908 {
909   xbt_dynar_t route=NULL;
910   routing_get_route_and_latency(src, dst,&route,NULL);
911   return route;
912 }
913
914 static double net_get_link_bandwidth(const void *link)
915 {
916   surf_resource_lmm_t lmm = (surf_resource_lmm_t) link;
917   return lmm->power.peak * lmm->power.scale;
918 }
919
920 static double net_get_link_latency(const void *link)
921 {
922   return ((link_CM02_t) link)->lat_current;
923 }
924
925 static int net_link_shared(const void *link)
926 {
927   return
928       lmm_constraint_is_shared(((surf_resource_lmm_t) link)->constraint);
929 }
930
931 static void net_action_suspend(surf_action_t action)
932 {
933   ((surf_action_network_CM02_t) action)->suspended = 1;
934   lmm_update_variable_weight(network_maxmin_system,
935                              ((surf_action_network_CM02_t)
936                               action)->variable, 0.0);
937
938   if(network_update_mechanism == UM_LAZY)// remove action from the heap
939     heap_remove((surf_action_network_CM02_t) action);
940 }
941
942 static void net_action_resume(surf_action_t action)
943 {
944   if (((surf_action_network_CM02_t) action)->suspended) {
945     lmm_update_variable_weight(network_maxmin_system,
946                                ((surf_action_network_CM02_t)
947                                 action)->variable,
948                                ((surf_action_network_CM02_t)
949                                 action)->weight);
950     ((surf_action_network_CM02_t) action)->suspended = 0;
951     if(network_update_mechanism == UM_LAZY)// remove action from the heap
952       heap_remove((surf_action_network_CM02_t) action);
953   }
954 }
955
956 static int net_action_is_suspended(surf_action_t action)
957 {
958   return ((surf_action_network_CM02_t) action)->suspended;
959 }
960
961 void net_action_set_max_duration(surf_action_t action, double duration)
962 {
963   action->max_duration = duration;
964   if(network_update_mechanism == UM_LAZY)// remove action from the heap
965     heap_remove((surf_action_network_CM02_t) action);
966 }
967
968 #ifdef HAVE_TRACING
969 static void net_action_set_category(surf_action_t action, const char *category)
970 {
971   action->category = xbt_strdup (category);
972 }
973 #endif
974
975 static void net_finalize(void)
976 {
977   surf_model_exit(surf_network_model);
978   surf_network_model = NULL;
979
980   lmm_system_free(network_maxmin_system);
981   network_maxmin_system = NULL;
982
983   if(network_update_mechanism == UM_LAZY){
984     xbt_heap_free(net_action_heap);
985     xbt_swag_free(net_modified_set);
986   }
987 }
988
989 static void smpi_gap_append(double size, const link_CM02_t link, surf_action_network_CM02_t action) {
990    const char* src = link->lmm_resource.generic_resource.name;
991    xbt_fifo_t fifo;
992    surf_action_network_CM02_t last_action;
993    double bw;
994
995    if(sg_sender_gap > 0.0) {
996       if(!gap_lookup) {
997          gap_lookup = xbt_dict_new();
998       }
999       fifo = (xbt_fifo_t)xbt_dict_get_or_null(gap_lookup, src);
1000       action->sender.gap = 0.0;
1001       if(fifo && xbt_fifo_size(fifo) > 0) {
1002          /* Compute gap from last send */
1003          last_action = (surf_action_network_CM02_t)xbt_fifo_get_item_content(xbt_fifo_get_last_item(fifo));
1004          bw = net_get_link_bandwidth(link);
1005          action->sender.gap = last_action->sender.gap + max(sg_sender_gap, last_action->sender.size / bw);
1006          action->latency += action->sender.gap;
1007       }
1008       /* Append action as last send */
1009       action->sender.link_name = link->lmm_resource.generic_resource.name;
1010       fifo = (xbt_fifo_t)xbt_dict_get_or_null(gap_lookup, action->sender.link_name);
1011       if(!fifo) {
1012          fifo = xbt_fifo_new();
1013          xbt_dict_set(gap_lookup, action->sender.link_name, fifo, NULL);
1014       }
1015       action->sender.fifo_item = xbt_fifo_push(fifo, action);
1016       action->sender.size = size;
1017    }
1018 }
1019
1020 static void smpi_gap_remove(surf_action_network_CM02_t action) {
1021    xbt_fifo_t fifo;
1022    size_t size;
1023
1024    if(sg_sender_gap > 0.0 && action->sender.link_name && action->sender.fifo_item) {
1025       fifo = (xbt_fifo_t)xbt_dict_get_or_null(gap_lookup, action->sender.link_name);
1026       xbt_fifo_remove_item(fifo, action->sender.fifo_item);
1027       size = xbt_fifo_size(fifo);
1028       if(size == 0) {
1029          xbt_fifo_free(fifo);
1030          xbt_dict_remove(gap_lookup, action->sender.link_name);
1031          size = xbt_dict_length(gap_lookup);
1032          if(size == 0) {
1033             xbt_dict_free(&gap_lookup);
1034          }
1035       }
1036    }
1037 }
1038
1039 static void surf_network_model_init_internal(void)
1040 {
1041   s_surf_action_network_CM02_t comm;
1042   surf_network_model = surf_model_init();
1043
1044   surf_network_model->name = "network";
1045   surf_network_model->action_unref = net_action_unref;
1046   surf_network_model->action_cancel = net_action_cancel;
1047   surf_network_model->action_recycle = net_action_recycle;
1048   surf_network_model->get_remains = net_action_get_remains;
1049 #ifdef HAVE_LATENCY_BOUND_TRACKING
1050   surf_network_model->get_latency_limited = net_get_link_latency_limited;
1051 #endif
1052 #ifdef HAVE_TRACING
1053   surf_network_model->set_category = net_action_set_category;
1054 #endif
1055
1056   surf_network_model->model_private->resource_used = net_resource_used;
1057   if(network_update_mechanism == UM_LAZY) {
1058     surf_network_model->model_private->share_resources = net_share_resources_lazy;
1059     surf_network_model->model_private->update_actions_state = net_update_actions_state_lazy;
1060   } else if(network_update_mechanism == UM_FULL) {
1061     surf_network_model->model_private->share_resources = net_share_resources_full;
1062     surf_network_model->model_private->update_actions_state = net_update_actions_state_full;
1063   }
1064
1065   surf_network_model->model_private->update_resource_state =
1066                   net_update_resource_state;
1067   surf_network_model->model_private->finalize = net_finalize;
1068
1069   surf_network_model->suspend = net_action_suspend;
1070   surf_network_model->resume = net_action_resume;
1071   surf_network_model->is_suspended = net_action_is_suspended;
1072   surf_cpu_model->set_max_duration = net_action_set_max_duration;
1073
1074   surf_network_model->extension.network.communicate = net_communicate;
1075   surf_network_model->extension.network.get_route = net_get_route;
1076   surf_network_model->extension.network.get_link_bandwidth =
1077                   net_get_link_bandwidth;
1078   surf_network_model->extension.network.get_link_latency =
1079                   net_get_link_latency;
1080   surf_network_model->extension.network.link_shared = net_link_shared;
1081   surf_network_model->extension.network.add_traces = net_add_traces;
1082   surf_network_model->extension.network.create_resource =
1083                   net_create_resource;
1084
1085  if (!network_maxmin_system)
1086     network_maxmin_system = lmm_system_new(net_selective_update);
1087
1088  routing_model_create(sizeof(link_CM02_t),
1089       net_create_resource("__loopback__",
1090           498000000, NULL, 0.000015, NULL,
1091           SURF_RESOURCE_ON, NULL,
1092           SURF_LINK_FATPIPE, NULL));
1093
1094   if(network_update_mechanism == UM_LAZY){
1095     net_action_heap = xbt_heap_new(8,NULL);
1096     xbt_heap_set_update_callback(net_action_heap, net_action_update_index_heap);
1097     net_modified_set =
1098         xbt_swag_new(xbt_swag_offset(comm, action_list_hookup));
1099   }
1100 }
1101
1102 static void set_update_mechanism(void) {
1103 #ifdef HAVE_TRACING
1104   TRACE_set_network_update_mechanism ();
1105 #endif
1106
1107   char *optim = xbt_cfg_get_string(_surf_cfg_set, "network/optim");
1108   int select = xbt_cfg_get_int(_surf_cfg_set, "network/maxmin_selective_update");
1109
1110   if(!strcmp(optim,"Full")) {
1111     network_update_mechanism = UM_FULL;
1112     net_selective_update = select;
1113   } else if (!strcmp(optim,"Lazy")) {
1114     network_update_mechanism = UM_LAZY;
1115     net_selective_update = 1;
1116     xbt_assert((select==1) || (xbt_cfg_is_default_value(_surf_cfg_set,"network/maxmin_selective_update")),
1117         "Disabling selective update while using the lazy update mechanism is dumb!");
1118   } else {
1119     xbt_die("Unsupported optimization (%s) for this model",optim);
1120   }
1121 }
1122
1123 /************************************************************************/
1124 /* New model based on LV08 and experimental results of MPI ping-pongs   */
1125 /************************************************************************/
1126 /* @Inproceedings{smpi_ipdps, */
1127 /*  author={Pierre-Nicolas Clauss and Mark Stillwell and Stéphane Genaud and Frédéric Suter and Henri Casanova and Martin Quinson}, */
1128 /*  title={Single Node On-Line Simulation of {MPI} Applications with SMPI}, */
1129 /*  booktitle={25th IEEE International Parallel and Distributed Processing Symposium (IPDPS'11)}, */
1130 /*  address={Anchorage (Alaska) USA}, */
1131 /*  month=may, */
1132 /*  year={2011} */
1133 /*  } */
1134 void surf_network_model_init_SMPI(void)
1135 {
1136
1137   if (surf_network_model)
1138     return;
1139   set_update_mechanism();
1140
1141   surf_network_model_init_internal();
1142   latency_factor_callback = &smpi_latency_factor;
1143   bandwidth_factor_callback = &smpi_bandwidth_factor;
1144   bandwidth_constraint_callback = &smpi_bandwidth_constraint;
1145   gap_append = &smpi_gap_append;
1146   gap_remove = &smpi_gap_remove;
1147   net_define_callbacks();
1148   xbt_dynar_push(model_list, &surf_network_model);
1149   network_solve = lmm_solve;
1150
1151   xbt_cfg_setdefault_double(_surf_cfg_set, "network/sender_gap", 10e-6);
1152   xbt_cfg_setdefault_double(_surf_cfg_set, "network/weight_S", 8775);
1153 }
1154
1155 /************************************************************************/
1156 /* New model based on optimizations discussed during Pedro Velho's thesis*/
1157 /************************************************************************/
1158 /* @techreport{VELHO:2011:HAL-00646896:1, */
1159 /*      url = {http://hal.inria.fr/hal-00646896/en/}, */
1160 /*      title = {{Flow-level network models: have we reached the limits?}}, */
1161 /*      author = {Velho, Pedro and Schnorr, Lucas and Casanova, Henri and Legrand, Arnaud}, */
1162 /*      type = {Rapport de recherche}, */
1163 /*      institution = {INRIA}, */
1164 /*      number = {RR-7821}, */
1165 /*      year = {2011}, */
1166 /*      month = Nov, */
1167 /*      pdf = {http://hal.inria.fr/hal-00646896/PDF/rr-validity.pdf}, */
1168 /*  } */
1169 void surf_network_model_init_LegrandVelho(void)
1170 {
1171   if (surf_network_model)
1172     return;
1173
1174   set_update_mechanism();
1175
1176   surf_network_model_init_internal();
1177   net_define_callbacks();
1178   xbt_dynar_push(model_list, &surf_network_model);
1179   network_solve = lmm_solve;
1180
1181   xbt_cfg_setdefault_double(_surf_cfg_set, "network/latency_factor", 10.4); // 13.01 when callibration is done without phase effects
1182   xbt_cfg_setdefault_double(_surf_cfg_set, "network/bandwidth_factor",0.92);// 0.97 when callibration is done without phase effects
1183   xbt_cfg_setdefault_double(_surf_cfg_set, "network/weight_S", 8775);       // 20537 when callibration is done without phase effects
1184 }
1185
1186 /***************************************************************************/
1187 /* The nice TCP sharing model designed by Loris Marchal and Henri Casanova */
1188 /***************************************************************************/
1189 /* @TechReport{      rr-lip2002-40, */
1190 /*   author        = {Henri Casanova and Loris Marchal}, */
1191 /*   institution   = {LIP}, */
1192 /*   title         = {A Network Model for Simulation of Grid Application}, */
1193 /*   number        = {2002-40}, */
1194 /*   month         = {oct}, */
1195 /*   year          = {2002} */
1196 /* } */
1197 void surf_network_model_init_CM02(void)
1198 {
1199
1200   if (surf_network_model)
1201     return;
1202
1203   set_update_mechanism();
1204   surf_network_model_init_internal();
1205   net_define_callbacks();
1206   xbt_dynar_push(model_list, &surf_network_model);
1207   network_solve = lmm_solve;
1208
1209   xbt_cfg_setdefault_double(_surf_cfg_set, "network/latency_factor", 1.0);
1210   xbt_cfg_setdefault_double(_surf_cfg_set, "network/bandwidth_factor", 1.0);
1211   xbt_cfg_setdefault_double(_surf_cfg_set, "network/weight_S", 0.0);
1212 }
1213
1214 /***************************************************************************/
1215 /* The models from Steven H. Low                                           */
1216 /***************************************************************************/
1217 /* @article{Low03,                                                         */
1218 /*   author={Steven H. Low},                                               */
1219 /*   title={A Duality Model of {TCP} and Queue Management Algorithms},     */
1220 /*   year={2003},                                                          */
1221 /*   journal={{IEEE/ACM} Transactions on Networking},                      */
1222 /*    volume={11}, number={4},                                             */
1223 /*  }                                                                      */
1224 void surf_network_model_init_Reno(void)
1225 {
1226   if (surf_network_model)
1227     return;
1228
1229   set_update_mechanism();
1230   surf_network_model_init_internal();
1231   net_define_callbacks();
1232
1233   xbt_dynar_push(model_list, &surf_network_model);
1234   lmm_set_default_protocol_function(func_reno_f, func_reno_fp,
1235                                     func_reno_fpi);
1236   network_solve = lagrange_solve;
1237
1238   xbt_cfg_setdefault_double(_surf_cfg_set, "network/latency_factor", 10.4);
1239   xbt_cfg_setdefault_double(_surf_cfg_set, "network/bandwidth_factor",
1240                             0.92);
1241   xbt_cfg_setdefault_double(_surf_cfg_set, "network/weight_S", 8775);
1242 }
1243
1244
1245 void surf_network_model_init_Reno2(void)
1246 {
1247   if (surf_network_model)
1248     return;
1249
1250   set_update_mechanism();
1251   surf_network_model_init_internal();
1252   net_define_callbacks();
1253
1254   xbt_dynar_push(model_list, &surf_network_model);
1255   lmm_set_default_protocol_function(func_reno2_f, func_reno2_fp,
1256                                     func_reno2_fpi);
1257   network_solve = lagrange_solve;
1258
1259   xbt_cfg_setdefault_double(_surf_cfg_set, "network/latency_factor", 10.4);
1260   xbt_cfg_setdefault_double(_surf_cfg_set, "network/bandwidth_factor",
1261                             0.92);
1262   xbt_cfg_setdefault_double(_surf_cfg_set, "network/weight_S_parameter",
1263                             8775);
1264 }
1265
1266 void surf_network_model_init_Vegas(void)
1267 {
1268   if (surf_network_model)
1269     return;
1270
1271   set_update_mechanism();
1272   surf_network_model_init_internal();
1273   net_define_callbacks();
1274
1275   xbt_dynar_push(model_list, &surf_network_model);
1276   lmm_set_default_protocol_function(func_vegas_f, func_vegas_fp,
1277                                     func_vegas_fpi);
1278   network_solve = lagrange_solve;
1279
1280   xbt_cfg_setdefault_double(_surf_cfg_set, "network/latency_factor", 10.4);
1281   xbt_cfg_setdefault_double(_surf_cfg_set, "network/bandwidth_factor",
1282                             0.92);
1283   xbt_cfg_setdefault_double(_surf_cfg_set, "network/weight_S", 8775);
1284 }