From: Augustin Degomme Date: Wed, 22 Jan 2014 10:06:17 +0000 (+0100) Subject: make cluster routing a bit more flexible, to allow adding other kinds of clusters X-Git-Tag: v3_11_beta~128^2~1 X-Git-Url: http://info.iut-bm.univ-fcomte.fr/pub/gitweb/simgrid.git/commitdiff_plain/e6b55b12b9633959a3dc6c68ac7cf91c2228ac16 make cluster routing a bit more flexible, to allow adding other kinds of clusters for each node, link creation is made inside the specific routing file, except for loopback and backbone which are done in surf_routing if they are needed --- diff --git a/buildtools/Cmake/DefinePackages.cmake b/buildtools/Cmake/DefinePackages.cmake index d5f6c7feb8..108d9fe2c6 100644 --- a/buildtools/Cmake/DefinePackages.cmake +++ b/buildtools/Cmake/DefinePackages.cmake @@ -67,6 +67,7 @@ set(EXTRA_DIST src/surf/surf_routing_private.hpp src/surf/surf_routing.hpp src/surf/surf_routing_cluster.hpp + src/surf/surf_routing_cluster_torus.hpp src/surf/surf_routing_dijkstra.hpp src/surf/surf_routing_floyd.hpp src/surf/surf_routing_full.hpp @@ -320,6 +321,7 @@ set(SURF_SRC src/surf/surf_c_bindings.cpp src/surf/surf_routing.cpp src/surf/surf_routing_cluster.cpp + src/surf/surf_routing_cluster_torus.cpp src/surf/surf_routing_dijkstra.cpp src/surf/surf_routing_floyd.cpp src/surf/surf_routing_full.cpp diff --git a/include/simgrid/platf.h b/include/simgrid/platf.h index 07c0ec7b2a..f5f37fa117 100644 --- a/include/simgrid/platf.h +++ b/include/simgrid/platf.h @@ -43,6 +43,11 @@ typedef enum { SURF_PROCESS_ON_FAILURE_RESTART = 0 } e_surf_process_on_failure_t; +typedef enum { + SURF_CLUSTER_FLAT = 1, + SURF_CLUSTER_TORUS = 0 +} e_surf_cluster_topology_t; + typedef struct tmgr_trace *tmgr_trace_t; /**< Opaque structure defining an availability trace */ @@ -201,7 +206,8 @@ typedef struct s_sg_platf_cluster_cbarg { double loopback_bw; double loopback_lat; double limiter_link; - const char* torus_dimensions; + e_surf_cluster_topology_t topology; + const char* topo_parameters; xbt_dict_t properties; const char* router_id; e_surf_link_sharing_policy_t sharing_policy; diff --git a/src/surf/surf_routing.cpp b/src/surf/surf_routing.cpp index 60fcd0fc8f..471d83619c 100644 --- a/src/surf/surf_routing.cpp +++ b/src/surf/surf_routing.cpp @@ -7,6 +7,8 @@ #include "surf_routing.hpp" #include "surf_routing_private.hpp" #include "surf_routing_cluster.hpp" +#include "surf_routing_cluster_torus.hpp" + #include "simgrid/platf_interface.h" // platform creation API internal interface #include "simgrid/sg_config.h" @@ -82,7 +84,9 @@ typedef enum { SURF_MODEL_DIJKSTRACACHE, SURF_MODEL_NONE, SURF_MODEL_VIVALDI, - SURF_MODEL_CLUSTER + SURF_MODEL_CLUSTER, + SURF_MODEL_TORUS_CLUSTER, + } e_routing_types; struct s_model_type routing_models[] = { @@ -104,6 +108,8 @@ struct s_model_type routing_models[] = { model_vivaldi_create, NULL}, {"Cluster", "Cluster routing", model_cluster_create, NULL}, + {"Torus_Cluster", "Torus Cluster routing", + model_torus_cluster_create, NULL}, {NULL, NULL, NULL, NULL} }; @@ -347,13 +353,14 @@ void routing_AS_begin(sg_platf_AS_cbarg_t AS) /* search the routing model */ switch(AS->routing){ - case A_surfxml_AS_routing_Cluster: model = &routing_models[SURF_MODEL_CLUSTER];break; - case A_surfxml_AS_routing_Dijkstra: model = &routing_models[SURF_MODEL_DIJKSTRA];break; - case A_surfxml_AS_routing_DijkstraCache: model = &routing_models[SURF_MODEL_DIJKSTRACACHE];break; - case A_surfxml_AS_routing_Floyd: model = &routing_models[SURF_MODEL_FLOYD];break; - case A_surfxml_AS_routing_Full: model = &routing_models[SURF_MODEL_FULL];break; - case A_surfxml_AS_routing_None: model = &routing_models[SURF_MODEL_NONE];break; - case A_surfxml_AS_routing_Vivaldi: model = &routing_models[SURF_MODEL_VIVALDI];break; + case A_surfxml_AS_routing_Cluster: model = &routing_models[SURF_MODEL_CLUSTER];break; + case A_surfxml_AS_routing_Cluster___torus: model = &routing_models[SURF_MODEL_TORUS_CLUSTER];break; + case A_surfxml_AS_routing_Dijkstra: model = &routing_models[SURF_MODEL_DIJKSTRA];break; + case A_surfxml_AS_routing_DijkstraCache: model = &routing_models[SURF_MODEL_DIJKSTRACACHE];break; + case A_surfxml_AS_routing_Floyd: model = &routing_models[SURF_MODEL_FLOYD];break; + case A_surfxml_AS_routing_Full: model = &routing_models[SURF_MODEL_FULL];break; + case A_surfxml_AS_routing_None: model = &routing_models[SURF_MODEL_NONE];break; + case A_surfxml_AS_routing_Vivaldi: model = &routing_models[SURF_MODEL_VIVALDI];break; default: xbt_die("Not a valid model!!!"); break; } @@ -798,13 +805,12 @@ static void routing_parse_cluster(sg_platf_cluster_cbarg_t cluster) { char *host_id, *groups, *link_id = NULL; xbt_dict_t patterns = NULL; - xbt_dynar_t dimensions; int rankId=0; s_sg_platf_host_cbarg_t host; s_sg_platf_link_cbarg_t link; - unsigned int iter, totalRanks=0; + unsigned int iter; int start, end, i; xbt_dynar_t radical_elements; xbt_dynar_t radical_ends; @@ -817,48 +823,36 @@ static void routing_parse_cluster(sg_platf_cluster_cbarg_t cluster) xbt_dict_set(patterns, "suffix", xbt_strdup(cluster->suffix), NULL); } - dimensions = xbt_str_split(cluster->torus_dimensions, ","); - - - int nb_links_per_node = 1; - - if (!xbt_dynar_is_empty(dimensions)) { - /** - * We are in a torus cluster - * Parse attribute dimensions="dim1,dim2,dim3,...,dimN" - * and safe it in a dynarray. - * Additionally, we need to know how many ranks we have in total - */ - xbt_dynar_foreach(dimensions, iter, groups) { - int tmp = surf_parse_get_int(xbt_dynar_get_as(dimensions, iter, char *)); - xbt_dynar_set_as(dimensions, iter, int, tmp); - - if (totalRanks == 0) - totalRanks = tmp; - else - totalRanks *= tmp; - } - - nb_links_per_node = xbt_dynar_length(dimensions); - ((AsClusterPtr)current_routing)-> p_dimensions = dimensions; + /* parse the topology attribute. If we are not in a flat cluster, + * switch to the right mode and initialize the routing with + * the parameters in topo_parameters attribute + */ + s_sg_platf_AS_cbarg_t AS = SG_PLATF_AS_INITIALIZER; + AS.id = cluster->id; + if(cluster->topology == SURF_CLUSTER_TORUS){ + XBT_DEBUG("", cluster->id); + AS.routing = A_surfxml_AS_routing_Cluster___torus; + sg_platf_new_AS_begin(&AS); + ((AsClusterTorusPtr)current_routing)->parse_specific_arguments(cluster); + }else{ + XBT_DEBUG("", cluster->id); + AS.routing = A_surfxml_AS_routing_Cluster; + sg_platf_new_AS_begin(&AS); + ((AsClusterPtr)current_routing)->p_nb_links_per_node = 1; } if(cluster->loopback_bw!=0 || cluster->loopback_lat!=0){ - nb_links_per_node++; + ((AsClusterPtr)current_routing)->p_nb_links_per_node++; ((AsClusterPtr)current_routing)->p_has_loopback=1; } if(cluster->limiter_link!=0){ - nb_links_per_node++; + ((AsClusterPtr)current_routing)->p_nb_links_per_node++; ((AsClusterPtr)current_routing)->p_has_limiter=1; } - XBT_DEBUG("", cluster->id); - s_sg_platf_AS_cbarg_t AS = SG_PLATF_AS_INITIALIZER; - AS.id = cluster->id; - AS.routing = A_surfxml_AS_routing_Cluster; - sg_platf_new_AS_begin(&AS); + current_routing->p_linkUpDownList = xbt_dynar_new(sizeof(s_surf_parsing_link_up_down_t),NULL); @@ -926,13 +920,13 @@ static void routing_parse_cluster(sg_platf_cluster_cbarg_t cluster) cluster->bw, cluster->lat); - s_surf_parsing_link_up_down_t info, info_lim, info_loop; + s_surf_parsing_link_up_down_t info_lim, info_loop; // All links are saved in a matrix; // every row describes a single node; every node // may have multiple links. // the first column may store a link from x to x if p_has_loopback is set // the second column may store a limiter link if p_has_limiter is set - // other columns are to store one or more link, if we are in a torus + // other columns are to store one or more link for the node //add a loopback link if(cluster->loopback_bw!=0 || cluster->loopback_lat!=0){ @@ -950,9 +944,9 @@ static void routing_parse_cluster(sg_platf_cluster_cbarg_t cluster) sg_platf_new_link(&link); info_loop.link_up = xbt_lib_get_or_null(link_lib, tmp_link, SURF_LINK_LEVEL); - info_loop.link_down = info.link_up; + info_loop.link_down = info_loop.link_up; free(tmp_link); - xbt_dynar_set(current_routing->p_linkUpDownList, rankId*nb_links_per_node, &info_loop); + xbt_dynar_set(current_routing->p_linkUpDownList, rankId*((AsClusterPtr)current_routing)->p_nb_links_per_node, &info_loop); } //add a limiter link (shared link to account for maximal bandwidth of the node) @@ -971,99 +965,22 @@ static void routing_parse_cluster(sg_platf_cluster_cbarg_t cluster) sg_platf_new_link(&link); info_lim.link_up = xbt_lib_get_or_null(link_lib, tmp_link, SURF_LINK_LEVEL); - info_lim.link_down = info.link_up; + info_lim.link_down = info_lim.link_up; free(tmp_link); xbt_dynar_set(current_routing->p_linkUpDownList, - rankId*nb_links_per_node + ((AsClusterPtr)current_routing)->p_has_loopback , + rankId*((AsClusterPtr)current_routing)->p_nb_links_per_node + ((AsClusterPtr)current_routing)->p_has_loopback , &info_lim); } + //call the cluster function that adds the others links - if(xbt_dynar_length(dimensions) == 0 ) { - /** - * If torus is not specified, generate one link by node - */ + ((AsClusterPtr)current_routing)->create_links_for_node(cluster, i, rankId, rankId* + ((AsClusterPtr)current_routing)->p_nb_links_per_node + + ((AsClusterPtr)current_routing)->p_has_loopback + + ((AsClusterPtr)current_routing)->p_has_limiter ); - memset(&link, 0, sizeof(link)); - link.id = link_id; - link.bandwidth = cluster->bw; - link.latency = cluster->lat; - link.state = SURF_RESOURCE_ON; - link.policy = cluster->sharing_policy; - sg_platf_new_link(&link); - - if (link.policy == SURF_LINK_FULLDUPLEX) { - char *tmp_link = bprintf("%s_UP", link_id); - info.link_up = - xbt_lib_get_or_null(link_lib, tmp_link, SURF_LINK_LEVEL); - free(tmp_link); - tmp_link = bprintf("%s_DOWN", link_id); - info.link_down = - xbt_lib_get_or_null(link_lib, tmp_link, SURF_LINK_LEVEL); - free(tmp_link); - } else { - info.link_up = xbt_lib_get_or_null(link_lib, link_id, SURF_LINK_LEVEL); - info.link_down = info.link_up; - } - xbt_dynar_set(current_routing->p_linkUpDownList, rankId*nb_links_per_node - + ((AsClusterPtr)current_routing)->p_has_loopback - + ((AsClusterPtr)current_routing)->p_has_limiter, - &info); - }else{ - - unsigned int j = 0; - /** - * Create all links that exist in the torus. - * Each rank creates #dimensions-1 links - */ - int neighbour_rank_id = 0; // The other node the link connects - int current_dimension = 0, // which dimension are we currently in? - // we need to iterate over all dimensions - // and create all links there - dim_product = 1; // Needed to calculate the next neighbour_id - for (j = 0; j < xbt_dynar_length(dimensions); j++) { - - memset(&link, 0, sizeof(link)); - current_dimension = xbt_dynar_get_as(dimensions, j, int); - neighbour_rank_id = ( ((int) i / dim_product) % current_dimension == current_dimension-1) ? i - (current_dimension-1)*dim_product : i + dim_product; - link_id = bprintf("link_from_%i_to_%i", i, neighbour_rank_id); - link.id = link_id; - link.bandwidth = cluster->bw; - link.latency = cluster->lat; - link.state = SURF_RESOURCE_ON; - link.policy = cluster->sharing_policy; - sg_platf_new_link(&link); - s_surf_parsing_link_up_down_t info; - if (link.policy == SURF_LINK_FULLDUPLEX) { - char *tmp_link = bprintf("%s_UP", link_id); - info.link_up = - xbt_lib_get_or_null(link_lib, tmp_link, SURF_LINK_LEVEL); - free(tmp_link); - tmp_link = bprintf("%s_DOWN", link_id); - info.link_down = - xbt_lib_get_or_null(link_lib, tmp_link, SURF_LINK_LEVEL); - free(tmp_link); - } else { - info.link_up = xbt_lib_get_or_null(link_lib, link_id, SURF_LINK_LEVEL); - info.link_down = info.link_up; - } - /** - * Add the link to its appropriate position; - * note that position rankId*(xbt_dynar_length(dimensions)+has_loopack?+has_limiter?) - * holds the link "rankId->rankId" - */ - xbt_dynar_set(current_routing->p_linkUpDownList, rankId*nb_links_per_node - + ((AsClusterPtr)current_routing)->p_has_loopback - + ((AsClusterPtr)current_routing)->p_has_limiter - + j, - &info); - dim_product *= current_dimension; - xbt_free(link_id); - - } - } xbt_free(link_id); xbt_free(host_id); rankId++; diff --git a/src/surf/surf_routing_cluster.cpp b/src/surf/surf_routing_cluster.cpp index 93503a1026..36794d8356 100644 --- a/src/surf/surf_routing_cluster.cpp +++ b/src/surf/surf_routing_cluster.cpp @@ -23,9 +23,9 @@ AsCluster::AsCluster() : AsNone() p_backbone = 0; p_loopback = 0; p_router = 0; - p_dimensions = NULL; p_has_limiter = 0; p_has_loopback = 0; + p_nb_links_per_node =0; } /* Business methods */ @@ -145,6 +145,37 @@ void AsCluster::getGraph(xbt_graph_t graph, xbt_dict_t nodes, xbt_dict_t edges) } } +void AsCluster::create_links_for_node(sg_platf_cluster_cbarg_t cluster, int id, int , int position){ + s_sg_platf_link_cbarg_t link; + s_surf_parsing_link_up_down_t info; + char* link_id = bprintf("%s_link_%d", cluster->id, id); + + memset(&link, 0, sizeof(link)); + link.id = link_id; + link.bandwidth = cluster->bw; + link.latency = cluster->lat; + link.state = SURF_RESOURCE_ON; + link.policy = cluster->sharing_policy; + sg_platf_new_link(&link); + + if (link.policy == SURF_LINK_FULLDUPLEX) { + char *tmp_link = bprintf("%s_UP", link_id); + info.link_up = + xbt_lib_get_or_null(link_lib, tmp_link, SURF_LINK_LEVEL); + free(tmp_link); + tmp_link = bprintf("%s_DOWN", link_id); + info.link_down = + xbt_lib_get_or_null(link_lib, tmp_link, SURF_LINK_LEVEL); + free(tmp_link); + } else { + info.link_up = xbt_lib_get_or_null(link_lib, link_id, SURF_LINK_LEVEL); + info.link_down = info.link_up; + } + xbt_dynar_set(p_linkUpDownList, position, + &info); + +} + int AsCluster::parsePU(RoutingEdgePtr elm) { XBT_DEBUG("Load process unit \"%s\"", elm->p_name); xbt_dynar_push_as(p_indexNetworkElm, RoutingEdgePtr, elm); @@ -157,4 +188,3 @@ int AsCluster::parseAS(RoutingEdgePtr elm) { return xbt_dynar_length(p_indexNetworkElm)-1; } - diff --git a/src/surf/surf_routing_cluster.hpp b/src/surf/surf_routing_cluster.hpp index 6300c8e8f1..4219d1dc8d 100644 --- a/src/surf/surf_routing_cluster.hpp +++ b/src/surf/surf_routing_cluster.hpp @@ -18,7 +18,7 @@ class AsCluster: public AsNone { public: AsCluster(); - void getRouteAndLatency(RoutingEdgePtr src, RoutingEdgePtr dst, sg_platf_route_cbarg_t into, double *latency); + virtual void getRouteAndLatency(RoutingEdgePtr src, RoutingEdgePtr dst, sg_platf_route_cbarg_t into, double *latency); //xbt_dynar_t getOneLinkRoutes(); //void parseRoute(sg_platf_route_cbarg_t route); //void parseASroute(sg_platf_route_cbarg_t route); @@ -32,13 +32,14 @@ public: * Of course, only the routing model of this AS is informed, not every ones */ int parsePU(RoutingEdgePtr elm); /* A host or a router, whatever */ int parseAS(RoutingEdgePtr elm); - + virtual void create_links_for_node(sg_platf_cluster_cbarg_t cluster, int id, int rank, int position); NetworkLinkPtr p_backbone; void *p_loopback; RoutingEdgePtr p_router; xbt_dynar_t p_dimensions; int p_has_limiter; int p_has_loopback; + int p_nb_links_per_node; }; diff --git a/src/surf/surf_routing_cluster_torus.cpp b/src/surf/surf_routing_cluster_torus.cpp new file mode 100644 index 0000000000..c16646dfa4 --- /dev/null +++ b/src/surf/surf_routing_cluster_torus.cpp @@ -0,0 +1,222 @@ +#include "surf_routing_cluster_torus.hpp" + +XBT_LOG_NEW_DEFAULT_SUBCATEGORY(surf_route_cluster_torus, surf_route_cluster, "Torus Routing part of surf"); + + +inline unsigned int* rankId_to_coords(int rankId, xbt_dynar_t dimensions) { + + unsigned int i = 0, cur_dim_size = 1, dim_size_product = 1; + unsigned int* coords = (unsigned int*)malloc(xbt_dynar_length(dimensions)*sizeof(unsigned int)); + for (i = 0; i < xbt_dynar_length(dimensions); i++) { + cur_dim_size = xbt_dynar_get_as(dimensions, i, int); + coords[i] = (rankId / dim_size_product) % cur_dim_size; + dim_size_product *= cur_dim_size; + } + + return coords; +} + + +AS_t model_torus_cluster_create(void) +{ + return new AsClusterTorus(); +} + +/* Creation routing model functions */ +AsClusterTorus::AsClusterTorus() : AsCluster() +{ + p_dimensions = NULL; +} + + + +void AsClusterTorus::create_links_for_node(sg_platf_cluster_cbarg_t cluster, int id, int rank, int position){ + s_sg_platf_link_cbarg_t link; + char* link_id; + unsigned int j = 0; + /** + * Create all links that exist in the torus. + * Each rank creates #dimensions-1 links + */ + int neighbour_rank_id = 0; // The other node the link connects + int current_dimension = 0, // which dimension are we currently in? + // we need to iterate over all dimensions + // and create all links there + dim_product = 1; // Needed to calculate the next neighbour_id + for (j = 0; j < xbt_dynar_length(p_dimensions); j++) { + + memset(&link, 0, sizeof(link)); + current_dimension = xbt_dynar_get_as(p_dimensions, j, int); + neighbour_rank_id = ( ((int) rank / dim_product) % current_dimension == current_dimension-1) ? rank - (current_dimension-1)*dim_product : rank + dim_product; + //name of neighbour is not right for non contiguous cluster radicals (as id != rank in this case) + link_id = bprintf("%s_link_from_%i_to_%i", cluster->id, id, neighbour_rank_id); + link.id = link_id; + link.bandwidth = cluster->bw; + link.latency = cluster->lat; + link.state = SURF_RESOURCE_ON; + link.policy = cluster->sharing_policy; + sg_platf_new_link(&link); + s_surf_parsing_link_up_down_t info; + if (link.policy == SURF_LINK_FULLDUPLEX) { + char *tmp_link = bprintf("%s_UP", link_id); + info.link_up = + xbt_lib_get_or_null(link_lib, tmp_link, SURF_LINK_LEVEL); + free(tmp_link); + tmp_link = bprintf("%s_DOWN", link_id); + info.link_down = + xbt_lib_get_or_null(link_lib, tmp_link, SURF_LINK_LEVEL); + free(tmp_link); + } else { + info.link_up = xbt_lib_get_or_null(link_lib, link_id, SURF_LINK_LEVEL); + info.link_down = info.link_up; + } + /** + * Add the link to its appropriate position; + * note that position rankId*(xbt_dynar_length(dimensions)+has_loopack?+has_limiter?) + * holds the link "rankId->rankId" + */ + xbt_dynar_set(p_linkUpDownList, position + + j, + &info); + dim_product *= current_dimension; + xbt_free(link_id); + } + rank++; +} + +void AsClusterTorus::parse_specific_arguments(sg_platf_cluster_cbarg_t cluster){ + + unsigned int iter; + char *groups; + p_dimensions = xbt_str_split(cluster->topo_parameters, ","); + + if (!xbt_dynar_is_empty(p_dimensions)) { + /** + * We are in a torus cluster + * Parse attribute dimensions="dim1,dim2,dim3,...,dimN" + * and safe it in a dynarray. + * Additionally, we need to know how many ranks we have in total + */ + xbt_dynar_foreach(p_dimensions, iter, groups) { + int tmp = surf_parse_get_int(xbt_dynar_get_as(p_dimensions, iter, char *)); + xbt_dynar_set_as(p_dimensions, iter, int, tmp); + } + + p_nb_links_per_node = xbt_dynar_length(p_dimensions); + + } +} + +void AsClusterTorus::getRouteAndLatency(RoutingEdgePtr src, RoutingEdgePtr dst, sg_platf_route_cbarg_t route, double *lat){ + + XBT_INFO("torus_get_route_and_latency from '%s'[%d] to '%s'[%d]", + src->p_name,src->m_id, + dst->p_name,dst->m_id); + + if (dst->p_rcType == SURF_NETWORK_ELEMENT_ROUTER || src->p_rcType == SURF_NETWORK_ELEMENT_ROUTER) return; + + if((src->m_id == dst->m_id) && p_has_loopback ){ + s_surf_parsing_link_up_down_t info = xbt_dynar_get_as(p_linkUpDownList, src->m_id * p_nb_links_per_node, s_surf_parsing_link_up_down_t); + xbt_dynar_push_as(route->link_list, void *, info.link_up); + + if (lat) + *lat += static_cast(info.link_up)->getLatency(); + return; + } + + + /** + * Dimension based routing routes through each dimension consecutively + * TODO Change to dynamic assignment + */ + unsigned int j, cur_dim, dim_product = 1; + long current_node = src->m_id; + long unsigned next_node = 0; + /** + * Arrays that hold the coordinates of the current node and + * the target; comparing the values at the i-th position of + * both arrays, we can easily assess whether we need to route + * into this dimension or not. + */ + unsigned int* myCoords, *targetCoords; + myCoords = rankId_to_coords(src->m_id, p_dimensions); + targetCoords = rankId_to_coords(dst->m_id, p_dimensions); + /** + * linkOffset describes the offset where the link + * we want to use is stored + * (+1 is added because each node has a link from itself to itself, + * which can only be the case if src->m_id == dst->m_id -- see above + * for this special case) + */ + long nodeOffset = (xbt_dynar_length(p_dimensions)+1)*src->m_id; + + long linkOffset = nodeOffset; + bool use_lnk_up = false; // Is this link of the form "cur -> next" or "next -> cur"? + // false means: next -> cur + while (current_node != dst->m_id) { + dim_product = 1; // First, we will route in x-dimension + for (j = 0; j < xbt_dynar_length(p_dimensions); j++) { + cur_dim = xbt_dynar_get_as(p_dimensions, j, int); + + // current_node/dim_product = position in current dimension + if ((current_node/dim_product) % cur_dim != (dst->m_id/dim_product) % cur_dim) { + + if (( targetCoords[j] > myCoords[j] && targetCoords[j] <= myCoords[j]+cur_dim/2) // Is the target node on the right, without the wrap-around? + || ( myCoords[j] > cur_dim/2 && (myCoords[j]+cur_dim/2)%cur_dim >= targetCoords[j] )) { // Or do we need to use the wrap around to reach it? + if ((current_node / dim_product) % cur_dim == cur_dim-1) + next_node = (current_node+dim_product-dim_product*cur_dim); + else + next_node = (current_node+dim_product); + + // HERE: We use *CURRENT* node for calculation (as opposed to next_node) + nodeOffset = current_node*(p_nb_links_per_node); + linkOffset = nodeOffset+p_has_loopback+p_has_limiter+j; + use_lnk_up = true; + assert(linkOffset >= 0); + } + else { // Route to the left + if ((current_node / dim_product) % cur_dim == 0) + next_node = (current_node-dim_product+dim_product*cur_dim); + else + next_node = (current_node-dim_product); + + // HERE: We use *next* node for calculation (as opposed to current_node!) + nodeOffset = next_node*(p_nb_links_per_node); + linkOffset = nodeOffset+j+p_has_loopback+p_has_limiter; + use_lnk_up = false; + + assert(linkOffset >= 0); + } + XBT_DEBUG("torus_get_route_and_latency - current_node: %lu, next_node: %lu, linkOffset is %lu", + current_node, next_node, linkOffset); + + break; + } + + dim_product *= cur_dim; + } + + s_surf_parsing_link_up_down_t info; + + if (p_has_limiter){ // limiter for sender + info = xbt_dynar_get_as(p_linkUpDownList, nodeOffset + p_has_loopback, s_surf_parsing_link_up_down_t); + xbt_dynar_push_as(route->link_list, void *, info.link_up); + } + + info = xbt_dynar_get_as(p_linkUpDownList,linkOffset, s_surf_parsing_link_up_down_t); + + if (use_lnk_up == false) + xbt_dynar_push_as(route->link_list,void*,info.link_down); + else + xbt_dynar_push_as(route->link_list,void*,info.link_up); + + current_node = next_node; + next_node = 0; + } + free(myCoords); + free(targetCoords); + + + + return; +} diff --git a/src/surf/surf_routing_cluster_torus.hpp b/src/surf/surf_routing_cluster_torus.hpp new file mode 100644 index 0000000000..995700fdec --- /dev/null +++ b/src/surf/surf_routing_cluster_torus.hpp @@ -0,0 +1,26 @@ +#include "surf_routing_none.hpp" +#include "network_interface.hpp" +#include "surf_routing_cluster.hpp" + + +#ifndef SURF_ROUTING_CLUSTER_TORUS_HPP_ +#define SURF_ROUTING_CLUSTER_TORUS_HPP_ + +class AsClusterTorus; +typedef AsClusterTorus *AsClusterTorusPtr; + + +class AsClusterTorus: public AsCluster { +public: + AsClusterTorus(); + virtual void create_links_for_node(sg_platf_cluster_cbarg_t cluster, int id, int rank, int position); + virtual void getRouteAndLatency(RoutingEdgePtr src, RoutingEdgePtr dst, sg_platf_route_cbarg_t into, double *latency); + void parse_specific_arguments(sg_platf_cluster_cbarg_t cluster); + + + xbt_dynar_t p_dimensions; + +}; + + +#endif diff --git a/src/surf/surf_routing_private.hpp b/src/surf/surf_routing_private.hpp index 5528943477..54c50b79b1 100644 --- a/src/surf/surf_routing_private.hpp +++ b/src/surf/surf_routing_private.hpp @@ -67,6 +67,8 @@ void model_floyd_parse_route(AS_t rc, sg_platf_route_cbarg_t route); /* ************** Cluster ROUTING **************** */ AsPtr model_cluster_create(void); /* create structures for cluster routing model */ +AsPtr model_torus_cluster_create(void); /* create structures for cluster routing model */ + /* ************************************************** */ /* ************** Vivaldi ROUTING **************** */ diff --git a/src/surf/surfxml_parse.c b/src/surf/surfxml_parse.c index f4439bb83a..86635a106f 100644 --- a/src/surf/surfxml_parse.c +++ b/src/surf/surfxml_parse.c @@ -520,7 +520,20 @@ void ETag_surfxml_cluster(void){ cluster.loopback_bw = surf_parse_get_bandwidth(A_surfxml_cluster_loopback___bw); if(strcmp(A_surfxml_cluster_loopback___lat,"")) cluster.loopback_lat = surf_parse_get_time(A_surfxml_cluster_loopback___lat); - cluster.torus_dimensions = A_surfxml_cluster_torus___dimensions; + + switch(AX_surfxml_cluster_topology){ + case A_surfxml_cluster_topology_FLAT: + cluster.topology= SURF_CLUSTER_FLAT ; + break; + case A_surfxml_cluster_topology_TORUS: + cluster.topology= SURF_CLUSTER_TORUS ; + break; + default: + surf_parse_error("Invalid cluster topology for cluster %s", + cluster.id); + break; + } + cluster.topo_parameters = A_surfxml_cluster_topo___parameters; cluster.router_id = A_surfxml_cluster_router___id; switch (AX_surfxml_cluster_sharing___policy) {