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},
109 /** @brief Add a link connecting an host to the rest of its AS (which must be cluster or vivaldi) */
110 void sg_platf_new_hostlink(sg_platf_host_link_cbarg_t netcard_arg)
112 simgrid::surf::NetCard *netcard = sg_host_by_name(netcard_arg->id)->pimpl_netcard;
113 xbt_assert(netcard, "Host '%s' not found!", netcard_arg->id);
114 xbt_assert(current_routing->p_modelDesc == &routing_models[SURF_MODEL_CLUSTER] ||
115 current_routing->p_modelDesc == &routing_models[SURF_MODEL_VIVALDI],
116 "You have to be in model Cluster to use tag host_link!");
118 s_surf_parsing_link_up_down_t link_up_down;
119 link_up_down.link_up = Link::byName(netcard_arg->link_up);
120 link_up_down.link_down = Link::byName(netcard_arg->link_down);
122 xbt_assert(link_up_down.link_up, "Link '%s' not found!",netcard_arg->link_up);
123 xbt_assert(link_up_down.link_down, "Link '%s' not found!",netcard_arg->link_down);
125 // If dynar is is greater than netcard id and if the host_link is already defined
126 if((int)xbt_dynar_length(current_routing->p_linkUpDownList) > netcard->getId() &&
127 xbt_dynar_get_as(current_routing->p_linkUpDownList, netcard->getId(), void*))
128 surf_parse_error("Host_link for '%s' is already defined!",netcard_arg->id);
130 XBT_DEBUG("Push Host_link for host '%s' to position %d", netcard->getName(), netcard->getId());
131 xbt_dynar_set_as(current_routing->p_linkUpDownList, netcard->getId(), s_surf_parsing_link_up_down_t, link_up_down);
134 void sg_platf_new_trace(sg_platf_trace_cbarg_t trace)
136 tmgr_trace_t tmgr_trace;
137 if (!trace->file || strcmp(trace->file, "") != 0) {
138 tmgr_trace = tmgr_trace_new_from_file(trace->file);
140 xbt_assert(strcmp(trace->pc_data, ""),
141 "Trace '%s' must have either a content, or point to a file on disk.",trace->id);
142 tmgr_trace = tmgr_trace_new_from_string(trace->id, trace->pc_data, trace->periodicity);
144 xbt_dict_set(traces_set_list, trace->id, (void *) tmgr_trace, NULL);
148 * \brief Make a new routing component to the platform
150 * Add a new autonomous system to the platform. Any elements (such as host,
151 * router or sub-AS) added after this call and before the corresponding call
152 * to sg_platf_new_AS_close() will be added to this AS.
154 * Once this function was called, the configuration concerning the used
155 * models cannot be changed anymore.
157 * @param AS_id name of this autonomous system. Must be unique in the platform
158 * @param wanted_routing_type one of Full, Floyd, Dijkstra or similar. Full list in the variable routing_models, in src/surf/surf_routing.c
160 void routing_AS_begin(sg_platf_AS_cbarg_t AS)
162 XBT_DEBUG("routing_AS_begin");
163 routing_model_description_t model = NULL;
165 xbt_assert(NULL == xbt_lib_get_or_null(as_router_lib, AS->id, ROUTING_ASR_LEVEL),
166 "Refusing to create a second AS called \"%s\".", AS->id);
168 _sg_cfg_init_status = 2; /* horrible hack: direct access to the global
169 * controlling the level of configuration to prevent
170 * any further config */
172 /* search the routing model */
174 case A_surfxml_AS_routing_Cluster: model = &routing_models[SURF_MODEL_CLUSTER];break;
175 case A_surfxml_AS_routing_ClusterTorus: model = &routing_models[SURF_MODEL_TORUS_CLUSTER];break;
176 case A_surfxml_AS_routing_ClusterFatTree: model = &routing_models[SURF_MODEL_FAT_TREE_CLUSTER];break;
177 case A_surfxml_AS_routing_Dijkstra: model = &routing_models[SURF_MODEL_DIJKSTRA];break;
178 case A_surfxml_AS_routing_DijkstraCache: model = &routing_models[SURF_MODEL_DIJKSTRACACHE];break;
179 case A_surfxml_AS_routing_Floyd: model = &routing_models[SURF_MODEL_FLOYD];break;
180 case A_surfxml_AS_routing_Full: model = &routing_models[SURF_MODEL_FULL];break;
181 case A_surfxml_AS_routing_None: model = &routing_models[SURF_MODEL_NONE];break;
182 case A_surfxml_AS_routing_Vivaldi: model = &routing_models[SURF_MODEL_VIVALDI];break;
183 default: xbt_die("Not a valid model!!!");
187 /* make a new routing component */
188 simgrid::surf::As *new_as = model->create();
190 new_as->p_modelDesc = model;
191 new_as->p_hierarchy = SURF_ROUTING_NULL;
192 new_as->p_name = xbt_strdup(AS->id);
194 simgrid::surf::NetCard *netcard = new simgrid::surf::NetCardImpl(new_as->p_name, SURF_NETWORK_ELEMENT_AS, current_routing);
195 if (current_routing == NULL && routing_platf->p_root == NULL) {
197 /* it is the first one */
198 new_as->p_routingFather = NULL;
199 routing_platf->p_root = new_as;
201 } else if (current_routing != NULL && routing_platf->p_root != NULL) {
203 xbt_assert(!xbt_dict_get_or_null
204 (current_routing->p_routingSons, AS->id),
205 "The AS \"%s\" already exists", AS->id);
206 /* it is a part of the tree */
207 new_as->p_routingFather = current_routing;
208 /* set the father behavior */
209 if (current_routing->p_hierarchy == SURF_ROUTING_NULL)
210 current_routing->p_hierarchy = SURF_ROUTING_RECURSIVE;
211 /* add to the sons dictionary */
212 xbt_dict_set(current_routing->p_routingSons, AS->id,
213 (void *) new_as, NULL);
214 /* add to the father element list */
215 netcard->setId(current_routing->parseAS(netcard));
217 THROWF(arg_error, 0, "All defined components must belong to a AS");
220 xbt_lib_set(as_router_lib, netcard->getName(), ROUTING_ASR_LEVEL,
222 XBT_DEBUG("Having set name '%s' id '%d'", new_as->p_name, netcard->getId());
224 /* set the new current component of the tree */
225 current_routing = new_as;
226 current_routing->p_netcard = netcard;
228 simgrid::surf::netcardCreatedCallbacks(netcard);
229 simgrid::surf::asCreatedCallbacks(new_as);
233 * \brief Specify that the current description of AS is finished
235 * Once you've declared all the content of your AS, you have to close
236 * it with this call. Your AS is not usable until you call this function.
238 * @fixme: this call is not as robust as wanted: bad things WILL happen
239 * if you call it twice for the same AS, or if you forget calling it, or
240 * even if you add stuff to a closed AS
243 void routing_AS_end()
245 xbt_assert(current_routing, "Cannot seal the current AS: none under construction");
246 current_routing->Seal();
247 current_routing = current_routing->p_routingFather;
250 /* Aux Business methods */
253 * \brief Get the AS father and the first elements of the chain
255 * \param src the source host name
256 * \param dst the destination host name
258 * Get the common father of the to processing units, and the first different
259 * father in the chain
261 static void elements_father(sg_netcard_t src, sg_netcard_t dst,
266 xbt_assert(src && dst, "bad parameters for \"elements_father\" method");
267 #define ELEMENTS_FATHER_MAXDEPTH 16 /* increase if it is not enough */
268 simgrid::surf::As *src_as, *dst_as;
269 simgrid::surf::As *path_src[ELEMENTS_FATHER_MAXDEPTH];
270 simgrid::surf::As *path_dst[ELEMENTS_FATHER_MAXDEPTH];
273 simgrid::surf::As *current;
274 simgrid::surf::As *current_src;
275 simgrid::surf::As *current_dst;
276 simgrid::surf::As *father;
278 /* (1) find the as where the src and dst are located */
279 sg_netcard_t src_data = src;
280 sg_netcard_t dst_data = dst;
281 src_as = src_data->getRcComponent();
282 dst_as = dst_data->getRcComponent();
284 char* src_name = src_data->getName();
285 char* dst_name = dst_data->getName();
288 xbt_assert(src_as && dst_as,
289 "Ask for route \"from\"(%s) or \"to\"(%s) no found", src_name, dst_name);
291 /* (2) find the path to the root routing component */
292 for (current = src_as; current != NULL; current = current->p_routingFather) {
293 if (index_src >= ELEMENTS_FATHER_MAXDEPTH)
294 xbt_die("ELEMENTS_FATHER_MAXDEPTH should be increased for path_src");
295 path_src[index_src++] = current;
297 for (current = dst_as; current != NULL; current = current->p_routingFather) {
298 if (index_dst >= ELEMENTS_FATHER_MAXDEPTH)
299 xbt_die("ELEMENTS_FATHER_MAXDEPTH should be increased for path_dst");
300 path_dst[index_dst++] = current;
303 /* (3) find the common father */
305 current_src = path_src[--index_src];
306 current_dst = path_dst[--index_dst];
307 } while (index_src > 0 && index_dst > 0 && current_src == current_dst);
309 /* (4) they are not in the same routing component, make the path */
310 if (current_src == current_dst)
311 father = current_src;
313 father = path_src[index_src + 1];
315 /* (5) result generation */
316 *res_father = father; /* first the common father of src and dst */
317 *res_src = current_src; /* second the first different father of src */
318 *res_dst = current_dst; /* three the first different father of dst */
320 #undef ELEMENTS_FATHER_MAXDEPTH
323 /* Global Business methods */
326 * \brief Recursive function for get_route_latency
328 * \param src the source host name
329 * \param dst the destination host name
330 * \param *route the route where the links are stored. It is either NULL or a ready to use dynar
331 * \param *latency the latency, if needed
333 * This function is called by "get_route" and "get_latency". It allows to walk
334 * recursively through the ASes tree.
336 static void _get_route_and_latency(
337 simgrid::surf::NetCard *src, simgrid::surf::NetCard *dst,
338 xbt_dynar_t * links, double *latency)
340 s_sg_platf_route_cbarg_t route = SG_PLATF_ROUTE_INITIALIZER;
341 memset(&route,0,sizeof(route));
343 xbt_assert(src && dst, "bad parameters for \"_get_route_latency\" method");
344 XBT_DEBUG("Solve route/latency \"%s\" to \"%s\"", src->getName(), dst->getName());
346 /* Find how src and dst are interconnected */
347 simgrid::surf::As *common_father, *src_father, *dst_father;
348 elements_father(src, dst, &common_father, &src_father, &dst_father);
349 XBT_DEBUG("elements_father: common father '%s' src_father '%s' dst_father '%s'",
350 common_father->p_name, src_father->p_name, dst_father->p_name);
352 /* Check whether a direct bypass is defined */
353 sg_platf_route_cbarg_t e_route_bypass = NULL;
354 //FIXME:REMOVE:if (common_father->get_bypass_route)
356 e_route_bypass = common_father->getBypassRoute(src, dst, latency);
358 /* Common ancestor is kind enough to declare a bypass route from src to dst -- use it and bail out */
359 if (e_route_bypass) {
360 xbt_dynar_merge(links, &e_route_bypass->link_list);
361 routing_route_free(e_route_bypass);
365 /* If src and dst are in the same AS, life is good */
366 if (src_father == dst_father) { /* SURF_ROUTING_BASE */
367 route.link_list = *links;
368 common_father->getRouteAndLatency(src, dst, &route, latency);
369 // if vivaldi latency+=vivaldi(src,dst)
373 /* Not in the same AS, no bypass. We'll have to find our path between the ASes recursively*/
375 route.link_list = xbt_dynar_new(sizeof(sg_routing_link_t), NULL);
376 // Find the net_card corresponding to father
377 simgrid::surf::NetCard *src_father_netcard = src_father->p_netcard;
378 simgrid::surf::NetCard *dst_father_netcard = dst_father->p_netcard;
380 common_father->getRouteAndLatency(src_father_netcard, dst_father_netcard,
383 xbt_assert((route.gw_src != NULL) && (route.gw_dst != NULL),
384 "bad gateways for route from \"%s\" to \"%s\"", src->getName(), dst->getName());
386 sg_netcard_t src_gateway_net_elm = route.gw_src;
387 sg_netcard_t dst_gateway_net_elm = route.gw_dst;
389 /* If source gateway is not our source, we have to recursively find our way up to this point */
390 if (src != src_gateway_net_elm)
391 _get_route_and_latency(src, src_gateway_net_elm, links, latency);
392 xbt_dynar_merge(links, &route.link_list);
394 /* If dest gateway is not our destination, we have to recursively find our way from this point */
395 if (dst_gateway_net_elm != dst)
396 _get_route_and_latency(dst_gateway_net_elm, dst, links, latency);
400 AS_t surf_platf_get_root(routing_platf_t platf){
401 return platf->p_root;
404 e_surf_network_element_type_t surf_routing_edge_get_rc_type(sg_netcard_t netcard){
405 return netcard->getRcType();
412 * \brief Find a route between hosts
414 * \param src the network_element_t for src host
415 * \param dst the network_element_t for dst host
416 * \param route where to store the list of links.
417 * If *route=NULL, create a short lived dynar. Else, fill the provided dynar
418 * \param latency where to store the latency experienced on the path (or NULL if not interested)
419 * It is the caller responsability to initialize latency to 0 (we add to provided route)
422 * walk through the routing components tree and find a route between hosts
423 * by calling each "get_route" function in each routing component.
425 void RoutingPlatf::getRouteAndLatency(NetCard *src, NetCard *dst, xbt_dynar_t* route, double *latency)
427 XBT_DEBUG("getRouteAndLatency from %s to %s", src->getName(), dst->getName());
428 if (NULL == *route) {
429 xbt_dynar_reset(routing_platf->p_lastRoute);
430 *route = routing_platf->p_lastRoute;
433 _get_route_and_latency(src, dst, route, latency);
435 xbt_assert(!latency || *latency >= 0.0,
436 "negative latency on route between \"%s\" and \"%s\"", src->getName(), dst->getName());
439 xbt_dynar_t RoutingPlatf::getOneLinkRoutes(){
440 return recursiveGetOneLinkRoutes(p_root);
443 xbt_dynar_t RoutingPlatf::recursiveGetOneLinkRoutes(As *rc)
445 xbt_dynar_t ret = xbt_dynar_new(sizeof(Onelink*), xbt_free_f);
447 //adding my one link routes
448 xbt_dynar_t onelink_mine = rc->getOneLinkRoutes();
450 xbt_dynar_merge(&ret,&onelink_mine);
454 xbt_dict_cursor_t cursor = NULL;
456 xbt_dict_foreach(rc->p_routingSons, cursor, key, rc_child) {
457 xbt_dynar_t onelink_child = recursiveGetOneLinkRoutes(rc_child);
459 xbt_dynar_merge(&ret,&onelink_child);
467 e_surf_network_element_type_t routing_get_network_element_type(const char *name)
469 simgrid::surf::NetCard *rc = sg_netcard_by_name_or_null(name);
471 return rc->getRcType();
473 return SURF_NETWORK_ELEMENT_NULL;
476 /** @brief create the root AS */
477 void routing_model_create( void *loopback)
479 routing_platf = new simgrid::surf::RoutingPlatf(loopback);
482 /* ************************************************************************** */
483 /* ************************* GENERIC PARSE FUNCTIONS ************************ */
485 void routing_cluster_add_backbone(void* bb) {
486 xbt_assert(current_routing->p_modelDesc == &routing_models[SURF_MODEL_CLUSTER],
487 "You have to be in model Cluster to use tag backbone!");
488 xbt_assert(!static_cast<simgrid::surf::AsCluster*>(current_routing)->p_backbone, "The backbone link is already defined!");
489 static_cast<simgrid::surf::AsCluster*>(current_routing)->p_backbone =
490 static_cast<simgrid::surf::Link*>(bb);
491 XBT_DEBUG("Add a backbone to AS '%s'", current_routing->p_name);
494 void sg_platf_new_cabinet(sg_platf_cabinet_cbarg_t cabinet)
497 char *groups , *host_id , *link_id = NULL;
499 xbt_dynar_t radical_elements;
500 xbt_dynar_t radical_ends;
503 radical_elements = xbt_str_split(cabinet->radical, ",");
504 xbt_dynar_foreach(radical_elements, iter, groups) {
506 radical_ends = xbt_str_split(groups, "-");
507 start = surf_parse_get_int(xbt_dynar_get_as(radical_ends, 0, char *));
509 switch (xbt_dynar_length(radical_ends)) {
514 end = surf_parse_get_int(xbt_dynar_get_as(radical_ends, 1, char *));
517 surf_parse_error("Malformed radical");
520 s_sg_platf_host_cbarg_t host = SG_PLATF_HOST_INITIALIZER;
521 memset(&host, 0, sizeof(host));
522 host.initiallyOn = 1;
524 host.speed_scale = 1.0;
525 host.core_amount = 1;
527 s_sg_platf_link_cbarg_t link = SG_PLATF_LINK_INITIALIZER;
528 memset(&link, 0, sizeof(link));
529 link.initiallyOn = 1;
530 link.policy = SURF_LINK_FULLDUPLEX;
531 link.latency = cabinet->lat;
532 link.bandwidth = cabinet->bw;
534 s_sg_platf_host_link_cbarg_t host_link = SG_PLATF_HOST_LINK_INITIALIZER;
535 memset(&host_link, 0, sizeof(host_link));
537 for (i = start; i <= end; i++) {
538 host_id = bprintf("%s%d%s",cabinet->prefix,i,cabinet->suffix);
539 link_id = bprintf("link_%s%d%s",cabinet->prefix,i,cabinet->suffix);
542 host.speed_peak = xbt_dynar_new(sizeof(double), NULL);
543 xbt_dynar_push(host.speed_peak,&cabinet->speed);
544 sg_platf_new_host(&host);
545 xbt_dynar_free(&host.speed_peak);
546 sg_platf_new_link(&link);
548 char* link_up = bprintf("%s_UP",link_id);
549 char* link_down = bprintf("%s_DOWN",link_id);
550 host_link.id = host_id;
551 host_link.link_up = link_up;
552 host_link.link_down = link_down;
553 sg_platf_new_hostlink(&host_link);
561 xbt_dynar_free(&radical_ends);
563 xbt_dynar_free(&radical_elements);
566 void sg_platf_new_peer(sg_platf_peer_cbarg_t peer)
568 using simgrid::surf::NetCard;
569 using simgrid::surf::AsCluster;
571 char *host_id = NULL;
572 char *link_id = NULL;
573 char *router_id = NULL;
576 host_id = HOST_PEER(peer->id);
577 link_id = LINK_PEER(peer->id);
578 router_id = ROUTER_PEER(peer->id);
580 XBT_DEBUG("<AS id=\"%s\"\trouting=\"Cluster\">", peer->id);
581 s_sg_platf_AS_cbarg_t AS = SG_PLATF_AS_INITIALIZER;
583 AS.routing = A_surfxml_AS_routing_Cluster;
584 sg_platf_new_AS_begin(&AS);
586 XBT_DEBUG("<host\tid=\"%s\"\tpower=\"%f\"/>", host_id, peer->speed);
587 s_sg_platf_host_cbarg_t host = SG_PLATF_HOST_INITIALIZER;
588 memset(&host, 0, sizeof(host));
589 host.initiallyOn = 1;
592 host.speed_peak = xbt_dynar_new(sizeof(double), NULL);
593 xbt_dynar_push(host.speed_peak,&peer->speed);
595 //host.power_peak = peer->power;
596 host.speed_scale = 1.0;
597 host.speed_trace = peer->availability_trace;
598 host.state_trace = peer->state_trace;
599 host.core_amount = 1;
600 sg_platf_new_host(&host);
601 xbt_dynar_free(&host.speed_peak);
603 s_sg_platf_link_cbarg_t link = SG_PLATF_LINK_INITIALIZER;
604 memset(&link, 0, sizeof(link));
605 link.initiallyOn = 1;
606 link.policy = SURF_LINK_SHARED;
607 link.latency = peer->lat;
609 char* link_up = bprintf("%s_UP",link_id);
610 XBT_DEBUG("<link\tid=\"%s\"\tbw=\"%f\"\tlat=\"%f\"/>", link_up,
611 peer->bw_out, peer->lat);
613 link.bandwidth = peer->bw_out;
614 sg_platf_new_link(&link);
616 char* link_down = bprintf("%s_DOWN",link_id);
617 XBT_DEBUG("<link\tid=\"%s\"\tbw=\"%f\"\tlat=\"%f\"/>", link_down,
618 peer->bw_in, peer->lat);
620 link.bandwidth = peer->bw_in;
621 sg_platf_new_link(&link);
623 XBT_DEBUG("<host_link\tid=\"%s\"\tup=\"%s\"\tdown=\"%s\" />", host_id,link_up,link_down);
624 s_sg_platf_host_link_cbarg_t host_link = SG_PLATF_HOST_LINK_INITIALIZER;
625 memset(&host_link, 0, sizeof(host_link));
626 host_link.id = host_id;
627 host_link.link_up = link_up;
628 host_link.link_down = link_down;
629 sg_platf_new_hostlink(&host_link);
631 XBT_DEBUG("<router id=\"%s\"/>", router_id);
632 s_sg_platf_router_cbarg_t router = SG_PLATF_ROUTER_INITIALIZER;
633 memset(&router, 0, sizeof(router));
634 router.id = router_id;
635 router.coord = peer->coord;
636 sg_platf_new_router(&router);
637 static_cast<AsCluster*>(current_routing)->p_router = static_cast<NetCard*>(xbt_lib_get_or_null(as_router_lib, router.id, ROUTING_ASR_LEVEL));
640 sg_platf_new_AS_end();
643 //xbt_dynar_free(&tab_elements_num);
651 // static void routing_parse_Srandom(void)
653 // double mean, std, min, max, seed;
654 // char *random_id = A_surfxml_random_id;
655 // char *random_radical = A_surfxml_random_radical;
656 // char *rd_name = NULL;
658 // mean = surf_parse_get_double(A_surfxml_random_mean);
659 // std = surf_parse_get_double(A_surfxml_random_std___deviation);
660 // min = surf_parse_get_double(A_surfxml_random_min);
661 // max = surf_parse_get_double(A_surfxml_random_max);
662 // seed = surf_parse_get_double(A_surfxml_random_seed);
666 // random_data_t random = xbt_new0(s_random_data_t, 1);
669 // xbt_dynar_t radical_elements;
670 // unsigned int iter;
673 // xbt_dynar_t radical_ends;
675 // switch (A_surfxml_random_generator) {
676 // case AU_surfxml_random_generator:
677 // case A_surfxml_random_generator_NONE:
678 // random->generator = NONE;
680 // case A_surfxml_random_generator_DRAND48:
681 // random->generator = DRAND48;
683 // case A_surfxml_random_generator_RAND:
684 // random->generator = RAND;
686 // case A_surfxml_random_generator_RNGSTREAM:
687 // random->generator = RNGSTREAM;
690 // surf_parse_error("Invalid random generator");
693 // random->seed = seed;
694 // random->min = min;
695 // random->max = max;
697 // /* Check user stupidities */
699 // THROWF(arg_error, 0, "random->max < random->min (%f < %f)", max, min);
701 // THROWF(arg_error, 0, "random->mean < random->min (%f < %f)", mean, min);
703 // THROWF(arg_error, 0, "random->mean > random->max (%f > %f)", mean, max);
705 // /* normalize the mean and standard deviation before storing */
706 // random->mean = (mean - min) / (max - min);
707 // random->std = std / (max - min);
709 // if (random->mean * (1 - random->mean) < random->std * random->std)
710 // THROWF(arg_error, 0, "Invalid mean and standard deviation (%f and %f)",
711 // random->mean, random->std);
714 // ("id = '%s' min = '%f' max = '%f' mean = '%f' std_deviatinon = '%f' generator = '%d' seed = '%ld' radical = '%s'",
715 // random_id, random->min, random->max, random->mean, random->std,
716 // (int)random->generator, random->seed, random_radical);
718 // if (!random_value)
719 // random_value = xbt_dict_new_homogeneous(free);
721 // if (!strcmp(random_radical, "")) {
722 // res = random_generate(random);
723 // rd_value = bprintf("%f", res);
724 // xbt_dict_set(random_value, random_id, rd_value, NULL);
726 // radical_elements = xbt_str_split(random_radical, ",");
727 // xbt_dynar_foreach(radical_elements, iter, groups) {
728 // radical_ends = xbt_str_split(groups, "-");
729 // switch (xbt_dynar_length(radical_ends)) {
731 // xbt_assert(!xbt_dict_get_or_null(random_value, random_id),
732 // "Custom Random '%s' already exists !", random_id);
733 // res = random_generate(random);
735 // bprintf("%s%d", random_id,
736 // atoi(xbt_dynar_getfirst_as(radical_ends, char *)));
737 // xbt_dict_set(random_value, tmpbuf, bprintf("%f", res), NULL);
742 // start = surf_parse_get_int(xbt_dynar_get_as(radical_ends, 0, char *));
743 // end = surf_parse_get_int(xbt_dynar_get_as(radical_ends, 1, char *));
744 // for (i = start; i <= end; i++) {
745 // xbt_assert(!xbt_dict_get_or_null(random_value, random_id),
746 // "Custom Random '%s' already exists !", bprintf("%s%d",
749 // res = random_generate(random);
750 // tmpbuf = bprintf("%s%d", random_id, i);
751 // xbt_dict_set(random_value, tmpbuf, bprintf("%f", res), NULL);
756 // XBT_CRITICAL("Malformed radical");
759 // res = random_generate(random);
760 // rd_name = bprintf("%s_router", random_id);
761 // rd_value = bprintf("%f", res);
762 // xbt_dict_set(random_value, rd_name, rd_value, NULL);
764 // xbt_dynar_free(&radical_ends);
767 // xbt_dynar_free(&radical_elements);
771 static void check_disk_attachment()
773 xbt_lib_cursor_t cursor;
776 simgrid::surf::NetCard *host_elm;
777 xbt_lib_foreach(storage_lib, cursor, key, data) {
778 if(xbt_lib_get_level(xbt_lib_get_elm_or_null(storage_lib, key), SURF_STORAGE_LEVEL) != NULL) {
779 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));
780 host_elm = sg_netcard_by_name_or_null(storage->p_attach);
782 surf_parse_error("Unable to attach storage %s: host %s doesn't exist.", storage->getName(), storage->p_attach);
787 void routing_register_callbacks()
789 simgrid::surf::on_postparse.connect(check_disk_attachment);
791 instr_routing_define_callbacks();
795 * \brief Recursive function for finalize
797 * \param rc the source host name
799 * This fuction is call by "finalize". It allow to finalize the
800 * AS or routing components. It delete all the structures.
802 static void finalize_rec(simgrid::surf::As *as) {
803 xbt_dict_cursor_t cursor = NULL;
807 xbt_dict_foreach(as->p_routingSons, cursor, key, elem) {
814 /** \brief Frees all memory allocated by the routing module */
815 void routing_exit(void) {
816 delete routing_platf;
822 RoutingPlatf::RoutingPlatf(void *loopback)
823 : p_loopback(loopback)
826 RoutingPlatf::~RoutingPlatf()
828 xbt_dynar_free(&p_lastRoute);
829 finalize_rec(p_root);
835 AS_t surf_AS_get_routing_root() {
836 return routing_platf->p_root;
839 const char *surf_AS_get_name(simgrid::surf::As *as) {
843 static simgrid::surf::As *surf_AS_recursive_get_by_name(
844 simgrid::surf::As *current, const char * name)
846 xbt_dict_cursor_t cursor = NULL;
849 simgrid::surf::As *tmp = NULL;
851 if(!strcmp(current->p_name, name))
854 xbt_dict_foreach(current->p_routingSons, cursor, key, elem) {
855 tmp = surf_AS_recursive_get_by_name(elem, name);
863 simgrid::surf::As *surf_AS_get_by_name(const char * name)
865 simgrid::surf::As *as = surf_AS_recursive_get_by_name(routing_platf->p_root, name);
867 XBT_WARN("Impossible to find an AS with name %s, please check your input", name);
871 xbt_dict_t surf_AS_get_routing_sons(simgrid::surf::As *as)
873 return as->p_routingSons;
876 xbt_dynar_t surf_AS_get_hosts(simgrid::surf::As *as)
878 xbt_dynar_t elms = as->p_indexNetworkElm;
879 int count = xbt_dynar_length(elms);
880 xbt_dynar_t res = xbt_dynar_new(sizeof(sg_host_t), NULL);
881 for (int index = 0; index < count; index++) {
883 xbt_dynar_get_as(elms, index, simgrid::surf::NetCard*);
884 sg_host_t delm = simgrid::s4u::Host::by_name_or_null(relm->getName());
886 xbt_dynar_push(res, &delm);
892 void surf_AS_get_graph(AS_t as, xbt_graph_t graph, xbt_dict_t nodes, xbt_dict_t edges) {
893 as->getGraph(graph, nodes, edges);