1 /* Copyright (c) 2009-2011, 2013-2015. The SimGrid Team.
2 * All rights reserved. */
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. */
7 #include "surf_routing.hpp"
8 #include "surf_routing_private.hpp"
9 #include "surf_routing_cluster.hpp"
11 #include "simgrid/platf_interface.h" // platform creation API internal interface
12 #include "simgrid/sg_config.h"
13 #include "storage_interface.hpp"
14 #include "src/surf/platform.hpp"
15 #include "surf/surfxml_parse_values.h"
24 simgrid::xbt::signal<void(simgrid::surf::NetCard*)> netcardCreatedCallbacks;
25 simgrid::xbt::signal<void(simgrid::surf::As*)> asCreatedCallbacks;
31 * @ingroup SURF_build_api
32 * @brief A library containing all known hosts
36 int COORD_HOST_LEVEL=0; //Coordinates level
38 int MSG_FILE_LEVEL; //Msg file level
40 int SIMIX_STORAGE_LEVEL; //Simix storage level
41 int MSG_STORAGE_LEVEL; //Msg storage level
43 xbt_lib_t as_router_lib;
44 int ROUTING_ASR_LEVEL; //Routing level
45 int COORD_ASR_LEVEL; //Coordinates level
46 int NS3_ASR_LEVEL; //host node for ns3
47 int ROUTING_PROP_ASR_LEVEL; //Where the properties are stored
49 /** @brief Retrieve a netcard from its name
51 * Netcards are the thing that connect host or routers to the network
53 simgrid::surf::NetCard *sg_netcard_by_name_or_null(const char *name)
55 sg_host_t h = sg_host_by_name(name);
56 simgrid::surf::NetCard *net_elm = h==NULL?NULL: h->pimpl_netcard;
58 net_elm = (simgrid::surf::NetCard*) xbt_lib_get_or_null(as_router_lib, name, ROUTING_ASR_LEVEL);
63 simgrid::surf::RoutingPlatf *routing_platf = NULL;
65 XBT_LOG_NEW_DEFAULT_SUBCATEGORY(surf_route, surf, "Routing part of surf");
67 /** The current AS in the parsing */
68 static simgrid::surf::As *current_routing = NULL;
69 simgrid::surf::As* routing_get_current()
71 return current_routing;
74 /* this lines are only for replace use like index in the model table */
79 SURF_MODEL_DIJKSTRACACHE,
83 SURF_MODEL_TORUS_CLUSTER,
84 SURF_MODEL_FAT_TREE_CLUSTER,
87 struct s_model_type routing_models[] = {
89 "Full routing data (fast, large memory requirements, fully expressive)",
92 "Floyd routing data (slow initialization, fast lookup, lesser memory requirements, shortest path routing only)",
95 "Dijkstra routing data (fast initialization, slow lookup, small memory requirements, shortest path routing only)",
96 model_dijkstra_create},
98 "Dijkstra routing data (fast initialization, fast lookup, small memory requirements, shortest path routing only)",
99 model_dijkstracache_create},
100 {"none", "No routing (Unless you know what you are doing, avoid using this mode in combination with a non Constant network model).",
102 {"Vivaldi", "Vivaldi routing", model_vivaldi_create},
103 {"Cluster", "Cluster routing", model_cluster_create},
104 {"TorusCluster", "Torus Cluster routing", model_torus_cluster_create},
105 {"FatTreeCluster", "Fat Tree Cluster routing", model_fat_tree_cluster_create},
110 * \brief Add a netcard connecting an host to the network element list
111 * FIXME: integrate into host constructor
113 void sg_platf_new_netcard(sg_platf_host_link_cbarg_t netcard)
115 simgrid::surf::NetCard *info = sg_host_by_name(netcard->id)->pimpl_netcard;
116 xbt_assert(info, "Host '%s' not found!", netcard->id);
117 xbt_assert(current_routing->p_modelDesc == &routing_models[SURF_MODEL_CLUSTER] ||
118 current_routing->p_modelDesc == &routing_models[SURF_MODEL_VIVALDI],
119 "You have to be in model Cluster to use tag host_link!");
121 s_surf_parsing_link_up_down_t link_up_down;
122 link_up_down.link_up = Link::byName(netcard->link_up);
123 link_up_down.link_down = Link::byName(netcard->link_down);
125 xbt_assert(link_up_down.link_up, "Link '%s' not found!",netcard->link_up);
126 xbt_assert(link_up_down.link_down, "Link '%s' not found!",netcard->link_down);
128 if(!current_routing->p_linkUpDownList)
129 current_routing->p_linkUpDownList = xbt_dynar_new(sizeof(s_surf_parsing_link_up_down_t),NULL);
131 // If dynar is is greater than netcard id and if the host_link is already defined
132 if((int)xbt_dynar_length(current_routing->p_linkUpDownList) > info->getId() &&
133 xbt_dynar_get_as(current_routing->p_linkUpDownList, info->getId(), void*))
134 surf_parse_error("Host_link for '%s' is already defined!",netcard->id);
136 XBT_DEBUG("Push Host_link for host '%s' to position %d", info->getName(), info->getId());
137 xbt_dynar_set_as(current_routing->p_linkUpDownList, info->getId(), s_surf_parsing_link_up_down_t, link_up_down);
140 void sg_platf_new_trace(sg_platf_trace_cbarg_t trace)
142 tmgr_trace_t tmgr_trace;
143 if (!trace->file || strcmp(trace->file, "") != 0) {
144 tmgr_trace = tmgr_trace_new_from_file(trace->file);
146 xbt_assert(strcmp(trace->pc_data, ""),
147 "Trace '%s' must have either a content, or point to a file on disk.",trace->id);
148 tmgr_trace = tmgr_trace_new_from_string(trace->id, trace->pc_data, trace->periodicity);
150 xbt_dict_set(traces_set_list, trace->id, (void *) tmgr_trace, NULL);
154 * \brief Make a new routing component to the platform
156 * Add a new autonomous system to the platform. Any elements (such as host,
157 * router or sub-AS) added after this call and before the corresponding call
158 * to sg_platf_new_AS_close() will be added to this AS.
160 * Once this function was called, the configuration concerning the used
161 * models cannot be changed anymore.
163 * @param AS_id name of this autonomous system. Must be unique in the platform
164 * @param wanted_routing_type one of Full, Floyd, Dijkstra or similar. Full list in the variable routing_models, in src/surf/surf_routing.c
166 void routing_AS_begin(sg_platf_AS_cbarg_t AS)
168 XBT_DEBUG("routing_AS_begin");
169 routing_model_description_t model = NULL;
171 xbt_assert(NULL == xbt_lib_get_or_null(as_router_lib, AS->id, ROUTING_ASR_LEVEL),
172 "Refusing to create a second AS called \"%s\".", AS->id);
174 _sg_cfg_init_status = 2; /* horrible hack: direct access to the global
175 * controlling the level of configuration to prevent
176 * any further config */
178 /* search the routing model */
180 case A_surfxml_AS_routing_Cluster: model = &routing_models[SURF_MODEL_CLUSTER];break;
181 case A_surfxml_AS_routing_ClusterTorus: model = &routing_models[SURF_MODEL_TORUS_CLUSTER];break;
182 case A_surfxml_AS_routing_ClusterFatTree: model = &routing_models[SURF_MODEL_FAT_TREE_CLUSTER];break;
183 case A_surfxml_AS_routing_Dijkstra: model = &routing_models[SURF_MODEL_DIJKSTRA];break;
184 case A_surfxml_AS_routing_DijkstraCache: model = &routing_models[SURF_MODEL_DIJKSTRACACHE];break;
185 case A_surfxml_AS_routing_Floyd: model = &routing_models[SURF_MODEL_FLOYD];break;
186 case A_surfxml_AS_routing_Full: model = &routing_models[SURF_MODEL_FULL];break;
187 case A_surfxml_AS_routing_None: model = &routing_models[SURF_MODEL_NONE];break;
188 case A_surfxml_AS_routing_Vivaldi: model = &routing_models[SURF_MODEL_VIVALDI];break;
189 default: xbt_die("Not a valid model!!!");
193 /* make a new routing component */
194 simgrid::surf::As *new_as = model->create();
196 new_as->p_modelDesc = model;
197 new_as->p_hierarchy = SURF_ROUTING_NULL;
198 new_as->p_name = xbt_strdup(AS->id);
200 simgrid::surf::NetCard *info = new simgrid::surf::NetCardImpl(new_as->p_name, SURF_NETWORK_ELEMENT_AS, current_routing);
201 if (current_routing == NULL && routing_platf->p_root == NULL) {
203 /* it is the first one */
204 new_as->p_routingFather = NULL;
205 routing_platf->p_root = new_as;
207 } else if (current_routing != NULL && routing_platf->p_root != NULL) {
209 xbt_assert(!xbt_dict_get_or_null
210 (current_routing->p_routingSons, AS->id),
211 "The AS \"%s\" already exists", AS->id);
212 /* it is a part of the tree */
213 new_as->p_routingFather = current_routing;
214 /* set the father behavior */
215 if (current_routing->p_hierarchy == SURF_ROUTING_NULL)
216 current_routing->p_hierarchy = SURF_ROUTING_RECURSIVE;
217 /* add to the sons dictionary */
218 xbt_dict_set(current_routing->p_routingSons, AS->id,
219 (void *) new_as, NULL);
220 /* add to the father element list */
221 info->setId(current_routing->parseAS(info));
223 THROWF(arg_error, 0, "All defined components must belong to a AS");
226 xbt_lib_set(as_router_lib, info->getName(), ROUTING_ASR_LEVEL,
228 XBT_DEBUG("Having set name '%s' id '%d'", new_as->p_name, info->getId());
230 /* set the new current component of the tree */
231 current_routing = new_as;
232 current_routing->p_netcard = info;
234 simgrid::surf::netcardCreatedCallbacks(info);
235 simgrid::surf::asCreatedCallbacks(new_as);
239 * \brief Specify that the current description of AS is finished
241 * Once you've declared all the content of your AS, you have to close
242 * it with this call. Your AS is not usable until you call this function.
244 * @fixme: this call is not as robust as wanted: bad things WILL happen
245 * if you call it twice for the same AS, or if you forget calling it, or
246 * even if you add stuff to a closed AS
249 void routing_AS_end()
251 xbt_assert(current_routing, "Cannot seal the current AS: none under construction");
252 current_routing->Seal();
253 current_routing = current_routing->p_routingFather;
256 /* Aux Business methods */
259 * \brief Get the AS father and the first elements of the chain
261 * \param src the source host name
262 * \param dst the destination host name
264 * Get the common father of the to processing units, and the first different
265 * father in the chain
267 static void elements_father(sg_netcard_t src, sg_netcard_t dst,
272 xbt_assert(src && dst, "bad parameters for \"elements_father\" method");
273 #define ELEMENTS_FATHER_MAXDEPTH 16 /* increase if it is not enough */
274 simgrid::surf::As *src_as, *dst_as;
275 simgrid::surf::As *path_src[ELEMENTS_FATHER_MAXDEPTH];
276 simgrid::surf::As *path_dst[ELEMENTS_FATHER_MAXDEPTH];
279 simgrid::surf::As *current;
280 simgrid::surf::As *current_src;
281 simgrid::surf::As *current_dst;
282 simgrid::surf::As *father;
284 /* (1) find the as where the src and dst are located */
285 sg_netcard_t src_data = src;
286 sg_netcard_t dst_data = dst;
287 src_as = src_data->getRcComponent();
288 dst_as = dst_data->getRcComponent();
290 char* src_name = src_data->getName();
291 char* dst_name = dst_data->getName();
294 xbt_assert(src_as && dst_as,
295 "Ask for route \"from\"(%s) or \"to\"(%s) no found", src_name, dst_name);
297 /* (2) find the path to the root routing component */
298 for (current = src_as; current != NULL; current = current->p_routingFather) {
299 if (index_src >= ELEMENTS_FATHER_MAXDEPTH)
300 xbt_die("ELEMENTS_FATHER_MAXDEPTH should be increased for path_src");
301 path_src[index_src++] = current;
303 for (current = dst_as; current != NULL; current = current->p_routingFather) {
304 if (index_dst >= ELEMENTS_FATHER_MAXDEPTH)
305 xbt_die("ELEMENTS_FATHER_MAXDEPTH should be increased for path_dst");
306 path_dst[index_dst++] = current;
309 /* (3) find the common father */
311 current_src = path_src[--index_src];
312 current_dst = path_dst[--index_dst];
313 } while (index_src > 0 && index_dst > 0 && current_src == current_dst);
315 /* (4) they are not in the same routing component, make the path */
316 if (current_src == current_dst)
317 father = current_src;
319 father = path_src[index_src + 1];
321 /* (5) result generation */
322 *res_father = father; /* first the common father of src and dst */
323 *res_src = current_src; /* second the first different father of src */
324 *res_dst = current_dst; /* three the first different father of dst */
326 #undef ELEMENTS_FATHER_MAXDEPTH
329 /* Global Business methods */
332 * \brief Recursive function for get_route_latency
334 * \param src the source host name
335 * \param dst the destination host name
336 * \param *route the route where the links are stored. It is either NULL or a ready to use dynar
337 * \param *latency the latency, if needed
339 * This function is called by "get_route" and "get_latency". It allows to walk
340 * recursively through the ASes tree.
342 static void _get_route_and_latency(
343 simgrid::surf::NetCard *src, simgrid::surf::NetCard *dst,
344 xbt_dynar_t * links, double *latency)
346 s_sg_platf_route_cbarg_t route = SG_PLATF_ROUTE_INITIALIZER;
347 memset(&route,0,sizeof(route));
349 xbt_assert(src && dst, "bad parameters for \"_get_route_latency\" method");
350 XBT_DEBUG("Solve route/latency \"%s\" to \"%s\"", src->getName(), dst->getName());
352 /* Find how src and dst are interconnected */
353 simgrid::surf::As *common_father, *src_father, *dst_father;
354 elements_father(src, dst, &common_father, &src_father, &dst_father);
355 XBT_DEBUG("elements_father: common father '%s' src_father '%s' dst_father '%s'",
356 common_father->p_name, src_father->p_name, dst_father->p_name);
358 /* Check whether a direct bypass is defined */
359 sg_platf_route_cbarg_t e_route_bypass = NULL;
360 //FIXME:REMOVE:if (common_father->get_bypass_route)
362 e_route_bypass = common_father->getBypassRoute(src, dst, latency);
364 /* Common ancestor is kind enough to declare a bypass route from src to dst -- use it and bail out */
365 if (e_route_bypass) {
366 xbt_dynar_merge(links, &e_route_bypass->link_list);
367 routing_route_free(e_route_bypass);
371 /* If src and dst are in the same AS, life is good */
372 if (src_father == dst_father) { /* SURF_ROUTING_BASE */
373 route.link_list = *links;
374 common_father->getRouteAndLatency(src, dst, &route, latency);
375 // if vivaldi latency+=vivaldi(src,dst)
379 /* Not in the same AS, no bypass. We'll have to find our path between the ASes recursively*/
381 route.link_list = xbt_dynar_new(sizeof(sg_routing_link_t), NULL);
382 // Find the net_card corresponding to father
383 simgrid::surf::NetCard *src_father_netcard = src_father->p_netcard;
384 simgrid::surf::NetCard *dst_father_netcard = dst_father->p_netcard;
386 common_father->getRouteAndLatency(src_father_netcard, dst_father_netcard,
389 xbt_assert((route.gw_src != NULL) && (route.gw_dst != NULL),
390 "bad gateways for route from \"%s\" to \"%s\"", src->getName(), dst->getName());
392 sg_netcard_t src_gateway_net_elm = route.gw_src;
393 sg_netcard_t dst_gateway_net_elm = route.gw_dst;
395 /* If source gateway is not our source, we have to recursively find our way up to this point */
396 if (src != src_gateway_net_elm)
397 _get_route_and_latency(src, src_gateway_net_elm, links, latency);
398 xbt_dynar_merge(links, &route.link_list);
400 /* If dest gateway is not our destination, we have to recursively find our way from this point */
401 if (dst_gateway_net_elm != dst)
402 _get_route_and_latency(dst_gateway_net_elm, dst, links, latency);
406 AS_t surf_platf_get_root(routing_platf_t platf){
407 return platf->p_root;
410 e_surf_network_element_type_t surf_routing_edge_get_rc_type(sg_netcard_t netcard){
411 return netcard->getRcType();
418 * \brief Find a route between hosts
420 * \param src the network_element_t for src host
421 * \param dst the network_element_t for dst host
422 * \param route where to store the list of links.
423 * If *route=NULL, create a short lived dynar. Else, fill the provided dynar
424 * \param latency where to store the latency experienced on the path (or NULL if not interested)
425 * It is the caller responsability to initialize latency to 0 (we add to provided route)
428 * walk through the routing components tree and find a route between hosts
429 * by calling each "get_route" function in each routing component.
431 void RoutingPlatf::getRouteAndLatency(NetCard *src, NetCard *dst, xbt_dynar_t* route, double *latency)
433 XBT_DEBUG("getRouteAndLatency from %s to %s", src->getName(), dst->getName());
434 if (NULL == *route) {
435 xbt_dynar_reset(routing_platf->p_lastRoute);
436 *route = routing_platf->p_lastRoute;
439 _get_route_and_latency(src, dst, route, latency);
441 xbt_assert(!latency || *latency >= 0.0,
442 "negative latency on route between \"%s\" and \"%s\"", src->getName(), dst->getName());
445 xbt_dynar_t RoutingPlatf::getOneLinkRoutes(){
446 return recursiveGetOneLinkRoutes(p_root);
449 xbt_dynar_t RoutingPlatf::recursiveGetOneLinkRoutes(As *rc)
451 xbt_dynar_t ret = xbt_dynar_new(sizeof(Onelink*), xbt_free_f);
453 //adding my one link routes
454 xbt_dynar_t onelink_mine = rc->getOneLinkRoutes();
456 xbt_dynar_merge(&ret,&onelink_mine);
460 xbt_dict_cursor_t cursor = NULL;
462 xbt_dict_foreach(rc->p_routingSons, cursor, key, rc_child) {
463 xbt_dynar_t onelink_child = recursiveGetOneLinkRoutes(rc_child);
465 xbt_dynar_merge(&ret,&onelink_child);
473 e_surf_network_element_type_t routing_get_network_element_type(const char *name)
475 simgrid::surf::NetCard *rc = sg_netcard_by_name_or_null(name);
477 return rc->getRcType();
479 return SURF_NETWORK_ELEMENT_NULL;
482 /** @brief create the root AS */
483 void routing_model_create( void *loopback)
485 routing_platf = new simgrid::surf::RoutingPlatf(loopback);
488 /* ************************************************************************** */
489 /* ************************* GENERIC PARSE FUNCTIONS ************************ */
491 void routing_cluster_add_backbone(void* bb) {
492 xbt_assert(current_routing->p_modelDesc == &routing_models[SURF_MODEL_CLUSTER],
493 "You have to be in model Cluster to use tag backbone!");
494 xbt_assert(!static_cast<simgrid::surf::AsCluster*>(current_routing)->p_backbone, "The backbone link is already defined!");
495 static_cast<simgrid::surf::AsCluster*>(current_routing)->p_backbone =
496 static_cast<simgrid::surf::Link*>(bb);
497 XBT_DEBUG("Add a backbone to AS '%s'", current_routing->p_name);
500 void sg_platf_new_cabinet(sg_platf_cabinet_cbarg_t cabinet)
503 char *groups , *host_id , *link_id = NULL;
505 xbt_dynar_t radical_elements;
506 xbt_dynar_t radical_ends;
509 radical_elements = xbt_str_split(cabinet->radical, ",");
510 xbt_dynar_foreach(radical_elements, iter, groups) {
512 radical_ends = xbt_str_split(groups, "-");
513 start = surf_parse_get_int(xbt_dynar_get_as(radical_ends, 0, char *));
515 switch (xbt_dynar_length(radical_ends)) {
520 end = surf_parse_get_int(xbt_dynar_get_as(radical_ends, 1, char *));
523 surf_parse_error("Malformed radical");
526 s_sg_platf_host_cbarg_t host = SG_PLATF_HOST_INITIALIZER;
527 memset(&host, 0, sizeof(host));
528 host.initiallyOn = 1;
530 host.speed_scale = 1.0;
531 host.core_amount = 1;
533 s_sg_platf_link_cbarg_t link = SG_PLATF_LINK_INITIALIZER;
534 memset(&link, 0, sizeof(link));
535 link.initiallyOn = 1;
536 link.policy = SURF_LINK_FULLDUPLEX;
537 link.latency = cabinet->lat;
538 link.bandwidth = cabinet->bw;
540 s_sg_platf_host_link_cbarg_t host_link = SG_PLATF_HOST_LINK_INITIALIZER;
541 memset(&host_link, 0, sizeof(host_link));
543 for (i = start; i <= end; i++) {
544 host_id = bprintf("%s%d%s",cabinet->prefix,i,cabinet->suffix);
545 link_id = bprintf("link_%s%d%s",cabinet->prefix,i,cabinet->suffix);
548 host.speed_peak = xbt_dynar_new(sizeof(double), NULL);
549 xbt_dynar_push(host.speed_peak,&cabinet->speed);
550 sg_platf_new_host(&host);
551 xbt_dynar_free(&host.speed_peak);
552 sg_platf_new_link(&link);
554 char* link_up = bprintf("%s_UP",link_id);
555 char* link_down = bprintf("%s_DOWN",link_id);
556 host_link.id = host_id;
557 host_link.link_up = link_up;
558 host_link.link_down = link_down;
559 sg_platf_new_netcard(&host_link);
567 xbt_dynar_free(&radical_ends);
569 xbt_dynar_free(&radical_elements);
572 void sg_platf_new_peer(sg_platf_peer_cbarg_t peer)
574 using simgrid::surf::NetCard;
575 using simgrid::surf::AsCluster;
577 char *host_id = NULL;
578 char *link_id = NULL;
579 char *router_id = NULL;
582 host_id = HOST_PEER(peer->id);
583 link_id = LINK_PEER(peer->id);
584 router_id = ROUTER_PEER(peer->id);
586 XBT_DEBUG("<AS id=\"%s\"\trouting=\"Cluster\">", peer->id);
587 s_sg_platf_AS_cbarg_t AS = SG_PLATF_AS_INITIALIZER;
589 AS.routing = A_surfxml_AS_routing_Cluster;
590 sg_platf_new_AS_begin(&AS);
592 current_routing->p_linkUpDownList = xbt_dynar_new(sizeof(s_surf_parsing_link_up_down_t),NULL);
594 XBT_DEBUG("<host\tid=\"%s\"\tpower=\"%f\"/>", host_id, peer->speed);
595 s_sg_platf_host_cbarg_t host = SG_PLATF_HOST_INITIALIZER;
596 memset(&host, 0, sizeof(host));
597 host.initiallyOn = 1;
600 host.speed_peak = xbt_dynar_new(sizeof(double), NULL);
601 xbt_dynar_push(host.speed_peak,&peer->speed);
603 //host.power_peak = peer->power;
604 host.speed_scale = 1.0;
605 host.speed_trace = peer->availability_trace;
606 host.state_trace = peer->state_trace;
607 host.core_amount = 1;
608 sg_platf_new_host(&host);
609 xbt_dynar_free(&host.speed_peak);
611 s_sg_platf_link_cbarg_t link = SG_PLATF_LINK_INITIALIZER;
612 memset(&link, 0, sizeof(link));
613 link.initiallyOn = 1;
614 link.policy = SURF_LINK_SHARED;
615 link.latency = peer->lat;
617 char* link_up = bprintf("%s_UP",link_id);
618 XBT_DEBUG("<link\tid=\"%s\"\tbw=\"%f\"\tlat=\"%f\"/>", link_up,
619 peer->bw_out, peer->lat);
621 link.bandwidth = peer->bw_out;
622 sg_platf_new_link(&link);
624 char* link_down = bprintf("%s_DOWN",link_id);
625 XBT_DEBUG("<link\tid=\"%s\"\tbw=\"%f\"\tlat=\"%f\"/>", link_down,
626 peer->bw_in, peer->lat);
628 link.bandwidth = peer->bw_in;
629 sg_platf_new_link(&link);
631 XBT_DEBUG("<host_link\tid=\"%s\"\tup=\"%s\"\tdown=\"%s\" />", host_id,link_up,link_down);
632 s_sg_platf_host_link_cbarg_t host_link = SG_PLATF_HOST_LINK_INITIALIZER;
633 memset(&host_link, 0, sizeof(host_link));
634 host_link.id = host_id;
635 host_link.link_up = link_up;
636 host_link.link_down = link_down;
637 sg_platf_new_netcard(&host_link);
639 XBT_DEBUG("<router id=\"%s\"/>", router_id);
640 s_sg_platf_router_cbarg_t router = SG_PLATF_ROUTER_INITIALIZER;
641 memset(&router, 0, sizeof(router));
642 router.id = router_id;
643 router.coord = peer->coord;
644 sg_platf_new_router(&router);
645 static_cast<AsCluster*>(current_routing)->p_router = static_cast<NetCard*>(xbt_lib_get_or_null(as_router_lib, router.id, ROUTING_ASR_LEVEL));
648 sg_platf_new_AS_end();
651 //xbt_dynar_free(&tab_elements_num);
659 // static void routing_parse_Srandom(void)
661 // double mean, std, min, max, seed;
662 // char *random_id = A_surfxml_random_id;
663 // char *random_radical = A_surfxml_random_radical;
664 // char *rd_name = NULL;
666 // mean = surf_parse_get_double(A_surfxml_random_mean);
667 // std = surf_parse_get_double(A_surfxml_random_std___deviation);
668 // min = surf_parse_get_double(A_surfxml_random_min);
669 // max = surf_parse_get_double(A_surfxml_random_max);
670 // seed = surf_parse_get_double(A_surfxml_random_seed);
674 // random_data_t random = xbt_new0(s_random_data_t, 1);
677 // xbt_dynar_t radical_elements;
678 // unsigned int iter;
681 // xbt_dynar_t radical_ends;
683 // switch (A_surfxml_random_generator) {
684 // case AU_surfxml_random_generator:
685 // case A_surfxml_random_generator_NONE:
686 // random->generator = NONE;
688 // case A_surfxml_random_generator_DRAND48:
689 // random->generator = DRAND48;
691 // case A_surfxml_random_generator_RAND:
692 // random->generator = RAND;
694 // case A_surfxml_random_generator_RNGSTREAM:
695 // random->generator = RNGSTREAM;
698 // surf_parse_error("Invalid random generator");
701 // random->seed = seed;
702 // random->min = min;
703 // random->max = max;
705 // /* Check user stupidities */
707 // THROWF(arg_error, 0, "random->max < random->min (%f < %f)", max, min);
709 // THROWF(arg_error, 0, "random->mean < random->min (%f < %f)", mean, min);
711 // THROWF(arg_error, 0, "random->mean > random->max (%f > %f)", mean, max);
713 // /* normalize the mean and standard deviation before storing */
714 // random->mean = (mean - min) / (max - min);
715 // random->std = std / (max - min);
717 // if (random->mean * (1 - random->mean) < random->std * random->std)
718 // THROWF(arg_error, 0, "Invalid mean and standard deviation (%f and %f)",
719 // random->mean, random->std);
722 // ("id = '%s' min = '%f' max = '%f' mean = '%f' std_deviatinon = '%f' generator = '%d' seed = '%ld' radical = '%s'",
723 // random_id, random->min, random->max, random->mean, random->std,
724 // (int)random->generator, random->seed, random_radical);
726 // if (!random_value)
727 // random_value = xbt_dict_new_homogeneous(free);
729 // if (!strcmp(random_radical, "")) {
730 // res = random_generate(random);
731 // rd_value = bprintf("%f", res);
732 // xbt_dict_set(random_value, random_id, rd_value, NULL);
734 // radical_elements = xbt_str_split(random_radical, ",");
735 // xbt_dynar_foreach(radical_elements, iter, groups) {
736 // radical_ends = xbt_str_split(groups, "-");
737 // switch (xbt_dynar_length(radical_ends)) {
739 // xbt_assert(!xbt_dict_get_or_null(random_value, random_id),
740 // "Custom Random '%s' already exists !", random_id);
741 // res = random_generate(random);
743 // bprintf("%s%d", random_id,
744 // atoi(xbt_dynar_getfirst_as(radical_ends, char *)));
745 // xbt_dict_set(random_value, tmpbuf, bprintf("%f", res), NULL);
750 // start = surf_parse_get_int(xbt_dynar_get_as(radical_ends, 0, char *));
751 // end = surf_parse_get_int(xbt_dynar_get_as(radical_ends, 1, char *));
752 // for (i = start; i <= end; i++) {
753 // xbt_assert(!xbt_dict_get_or_null(random_value, random_id),
754 // "Custom Random '%s' already exists !", bprintf("%s%d",
757 // res = random_generate(random);
758 // tmpbuf = bprintf("%s%d", random_id, i);
759 // xbt_dict_set(random_value, tmpbuf, bprintf("%f", res), NULL);
764 // XBT_CRITICAL("Malformed radical");
767 // res = random_generate(random);
768 // rd_name = bprintf("%s_router", random_id);
769 // rd_value = bprintf("%f", res);
770 // xbt_dict_set(random_value, rd_name, rd_value, NULL);
772 // xbt_dynar_free(&radical_ends);
775 // xbt_dynar_free(&radical_elements);
779 static void check_disk_attachment()
781 xbt_lib_cursor_t cursor;
784 simgrid::surf::NetCard *host_elm;
785 xbt_lib_foreach(storage_lib, cursor, key, data) {
786 if(xbt_lib_get_level(xbt_lib_get_elm_or_null(storage_lib, key), SURF_STORAGE_LEVEL) != NULL) {
787 simgrid::surf::Storage *storage = static_cast<simgrid::surf::Storage*>(xbt_lib_get_level(xbt_lib_get_elm_or_null(storage_lib, key), SURF_STORAGE_LEVEL));
788 host_elm = sg_netcard_by_name_or_null(storage->p_attach);
790 surf_parse_error("Unable to attach storage %s: host %s doesn't exist.", storage->getName(), storage->p_attach);
795 void routing_register_callbacks()
797 simgrid::surf::on_postparse.connect(check_disk_attachment);
799 instr_routing_define_callbacks();
803 * \brief Recursive function for finalize
805 * \param rc the source host name
807 * This fuction is call by "finalize". It allow to finalize the
808 * AS or routing components. It delete all the structures.
810 static void finalize_rec(simgrid::surf::As *as) {
811 xbt_dict_cursor_t cursor = NULL;
815 xbt_dict_foreach(as->p_routingSons, cursor, key, elem) {
822 /** \brief Frees all memory allocated by the routing module */
823 void routing_exit(void) {
824 delete routing_platf;
830 RoutingPlatf::RoutingPlatf(void *loopback)
831 : p_loopback(loopback)
834 RoutingPlatf::~RoutingPlatf()
836 xbt_dynar_free(&p_lastRoute);
837 finalize_rec(p_root);
843 AS_t surf_AS_get_routing_root() {
844 return routing_platf->p_root;
847 const char *surf_AS_get_name(simgrid::surf::As *as) {
851 static simgrid::surf::As *surf_AS_recursive_get_by_name(
852 simgrid::surf::As *current, const char * name)
854 xbt_dict_cursor_t cursor = NULL;
857 simgrid::surf::As *tmp = NULL;
859 if(!strcmp(current->p_name, name))
862 xbt_dict_foreach(current->p_routingSons, cursor, key, elem) {
863 tmp = surf_AS_recursive_get_by_name(elem, name);
871 simgrid::surf::As *surf_AS_get_by_name(const char * name)
873 simgrid::surf::As *as = surf_AS_recursive_get_by_name(routing_platf->p_root, name);
875 XBT_WARN("Impossible to find an AS with name %s, please check your input", name);
879 xbt_dict_t surf_AS_get_routing_sons(simgrid::surf::As *as)
881 return as->p_routingSons;
884 const char *surf_AS_get_model(simgrid::surf::As *as)
886 return as->p_modelDesc->name;
889 xbt_dynar_t surf_AS_get_hosts(simgrid::surf::As *as)
891 xbt_dynar_t elms = as->p_indexNetworkElm;
892 int count = xbt_dynar_length(elms);
893 xbt_dynar_t res = xbt_dynar_new(sizeof(sg_host_t), NULL);
894 for (int index = 0; index < count; index++) {
896 xbt_dynar_get_as(elms, index, simgrid::surf::NetCard*);
897 sg_host_t delm = simgrid::s4u::Host::by_name_or_null(relm->getName());
899 xbt_dynar_push(res, &delm);
905 void surf_AS_get_graph(AS_t as, xbt_graph_t graph, xbt_dict_t nodes, xbt_dict_t edges) {
906 as->getGraph(graph, nodes, edges);