Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
change e_surf_link_sharing_policy_t into a proper enum class
[simgrid.git] / src / kernel / routing / ClusterZone.cpp
1 /* Copyright (c) 2009-2018. The SimGrid Team. All rights reserved.          */
2
3 /* This program is free software; you can redistribute it and/or modify it
4  * under the terms of the license (GNU LGPL) which comes with this package. */
5
6 #include "simgrid/kernel/routing/ClusterZone.hpp"
7 #include "simgrid/kernel/routing/NetPoint.hpp"
8 #include "simgrid/kernel/routing/RoutedZone.hpp"
9 #include "src/surf/network_interface.hpp"
10 #include "src/surf/xml/platf_private.hpp" // FIXME: RouteCreationArgs and friends
11
12 XBT_LOG_NEW_DEFAULT_SUBCATEGORY(surf_route_cluster, surf, "Routing part of surf");
13
14 /* This routing is specifically setup to represent clusters, aka homogeneous sets of machines
15  * Note that a router is created, easing the interconnexion with the rest of the world. */
16
17 namespace simgrid {
18 namespace kernel {
19 namespace routing {
20 ClusterZone::ClusterZone(NetZone* father, std::string name) : NetZoneImpl(father, name)
21 {
22 }
23
24 void ClusterZone::get_local_route(NetPoint* src, NetPoint* dst, RouteCreationArgs* route, double* lat)
25 {
26   XBT_VERB("cluster getLocalRoute from '%s'[%u] to '%s'[%u]", src->get_cname(), src->id(), dst->get_cname(), dst->id());
27   xbt_assert(not private_links_.empty(),
28              "Cluster routing: no links attached to the source node - did you use host_link tag?");
29
30   if ((src->id() == dst->id()) && has_loopback_) {
31     xbt_assert(not src->is_router(), "Routing from a cluster private router to itself is meaningless");
32
33     std::pair<resource::LinkImpl*, resource::LinkImpl*> info = private_links_.at(node_pos(src->id()));
34     route->link_list.push_back(info.first);
35     if (lat)
36       *lat += info.first->latency();
37     return;
38   }
39
40   if (not src->is_router()) { // No private link for the private router
41     if (has_limiter_) {      // limiter for sender
42       std::pair<resource::LinkImpl*, resource::LinkImpl*> info = private_links_.at(node_pos_with_loopback(src->id()));
43       route->link_list.push_back(info.first);
44     }
45
46     std::pair<resource::LinkImpl*, resource::LinkImpl*> info =
47         private_links_.at(node_pos_with_loopback_limiter(src->id()));
48     if (info.first) { // link up
49       route->link_list.push_back(info.first);
50       if (lat)
51         *lat += info.first->latency();
52     }
53   }
54
55   if (backbone_) {
56     route->link_list.push_back(backbone_);
57     if (lat)
58       *lat += backbone_->latency();
59   }
60
61   if (not dst->is_router()) { // No specific link for router
62
63     std::pair<resource::LinkImpl*, resource::LinkImpl*> info =
64         private_links_.at(node_pos_with_loopback_limiter(dst->id()));
65     if (info.second) { // link down
66       route->link_list.push_back(info.second);
67       if (lat)
68         *lat += info.second->latency();
69     }
70     if (has_limiter_) { // limiter for receiver
71       info = private_links_.at(node_pos_with_loopback(dst->id()));
72       route->link_list.push_back(info.first);
73     }
74   }
75 }
76
77 void ClusterZone::get_graph(xbt_graph_t graph, std::map<std::string, xbt_node_t>* nodes,
78                             std::map<std::string, xbt_edge_t>* edges)
79 {
80   xbt_assert(router_,
81              "Malformed cluster. This may be because your platform file is a hypergraph while it must be a graph.");
82
83   /* create the router */
84   xbt_node_t routerNode = new_xbt_graph_node(graph, router_->get_cname(), nodes);
85
86   xbt_node_t backboneNode = nullptr;
87   if (backbone_) {
88     backboneNode = new_xbt_graph_node(graph, backbone_->get_cname(), nodes);
89     new_xbt_graph_edge(graph, routerNode, backboneNode, edges);
90   }
91
92   for (auto const& src : getVertices()) {
93     if (not src->is_router()) {
94       xbt_node_t previous = new_xbt_graph_node(graph, src->get_cname(), nodes);
95
96       std::pair<resource::LinkImpl*, resource::LinkImpl*> info = private_links_.at(src->id());
97
98       if (info.first) { // link up
99         xbt_node_t current = new_xbt_graph_node(graph, info.first->get_cname(), nodes);
100         new_xbt_graph_edge(graph, previous, current, edges);
101
102         if (backbone_) {
103           new_xbt_graph_edge(graph, current, backboneNode, edges);
104         } else {
105           new_xbt_graph_edge(graph, current, routerNode, edges);
106         }
107       }
108
109       if (info.second) { // link down
110         xbt_node_t current = new_xbt_graph_node(graph, info.second->get_cname(), nodes);
111         new_xbt_graph_edge(graph, previous, current, edges);
112
113         if (backbone_) {
114           new_xbt_graph_edge(graph, current, backboneNode, edges);
115         } else {
116           new_xbt_graph_edge(graph, current, routerNode, edges);
117         }
118       }
119     }
120   }
121 }
122
123 void ClusterZone::create_links_for_node(ClusterCreationArgs* cluster, int id, int /*rank*/, unsigned int position)
124 {
125   std::string link_id = cluster->id + "_link_" + std::to_string(id);
126
127   LinkCreationArgs link;
128   link.id        = link_id;
129   link.bandwidth = cluster->bw;
130   link.latency   = cluster->lat;
131   link.policy    = cluster->sharing_policy;
132   sg_platf_new_link(&link);
133
134   resource::LinkImpl* linkUp;
135   resource::LinkImpl* linkDown;
136   if (link.policy == simgrid::s4u::Link::SharingPolicy::SPLITDUPLEX) {
137     linkUp   = resource::LinkImpl::byName(link_id + "_UP");
138     linkDown = resource::LinkImpl::byName(link_id + "_DOWN");
139   } else {
140     linkUp   = resource::LinkImpl::byName(link_id);
141     linkDown = linkUp;
142   }
143   private_links_.insert({position, {linkUp, linkDown}});
144 }
145 }
146 }
147 }