const Route* e_route = static_cast<Route*>(xbt_graph_edge_get_data(edge));
- for (auto const& link : e_route->link_list_) {
- route->link_list_.insert(route->link_list_.begin(), link);
- if (lat)
- *lat += link->get_latency();
- }
+ insert_link_latency(route->link_list_, e_route->link_list_, lat);
}
auto elm = route_cache_.emplace(src_id, std::vector<int>());
const NetPoint* gw_dst_net_elm = nullptr;
const NetPoint* prev_gw_src_net_elm = nullptr;
get_global_route(gw_dst_net_elm, prev_gw_src_net_elm, e_route_as_to_as, nullptr);
- for (auto pos = e_route_as_to_as.rbegin(); pos != e_route_as_to_as.rend(); pos++) {
- resource::LinkImpl* link = *pos;
- route->link_list_.insert(route->link_list_.begin(), link);
- if (lat)
- *lat += link->get_latency();
- }
+ std::reverse(begin(e_route_as_to_as), end(e_route_as_to_as));
+ insert_link_latency(route->link_list_, e_route_as_to_as, lat);
}
- for (auto const& link : e_route->link_list_) {
- route->link_list_.insert(route->link_list_.begin(), link);
- if (lat)
- *lat += link->get_latency();
- }
+ insert_link_latency(route->link_list_, e_route->link_list_, lat);
}
if (get_hierarchy() == RoutingMode::recursive) {
if ((src->id() == dst->id()) && has_loopback()) {
resource::LinkImpl* uplink = get_uplink_from(node_pos(src->id()));
- route->link_list_.push_back(uplink);
- if (latency)
- *latency += uplink->get_latency();
+ add_link_latency(route->link_list_, uplink, latency);
return;
}
}
// node->router local link
- route->link_list_.push_back(myRouter->my_nodes_[myCoords.node * num_links_per_link_]);
- if (latency)
- *latency += myRouter->my_nodes_[myCoords.node * num_links_per_link_]->get_latency();
+ add_link_latency(route->link_list_, myRouter->my_nodes_[myCoords.node * num_links_per_link_], latency);
if (targetRouter != myRouter) {
// are we on a different group ?
if (currentRouter->limiter_)
route->link_list_.push_back(currentRouter->limiter_);
// go to the nth router in our chassis
- route->link_list_.push_back(currentRouter->green_links_[targetCoords.group]);
- if (latency)
- *latency += currentRouter->green_links_[targetCoords.group]->get_latency();
+ add_link_latency(route->link_list_, currentRouter->green_links_[targetCoords.group], latency);
currentRouter = &routers_[myCoords.group * (num_chassis_per_group_ * num_blades_per_chassis_) +
myCoords.chassis * num_blades_per_chassis_ + targetCoords.group];
}
// go to the first chassis of our group
if (currentRouter->limiter_)
route->link_list_.push_back(currentRouter->limiter_);
- route->link_list_.push_back(currentRouter->black_links_[0]);
- if (latency)
- *latency += currentRouter->black_links_[0]->get_latency();
+ add_link_latency(route->link_list_, currentRouter->black_links_[0], latency);
currentRouter =
&routers_[myCoords.group * (num_chassis_per_group_ * num_blades_per_chassis_) + targetCoords.group];
}
// go to destination group - the only optical hop
- route->link_list_.push_back(currentRouter->blue_link_);
+ add_link_latency(route->link_list_, currentRouter->blue_link_, latency);
if (currentRouter->limiter_)
route->link_list_.push_back(currentRouter->limiter_);
- if (latency)
- *latency += currentRouter->blue_link_->get_latency();
currentRouter =
&routers_[targetCoords.group * (num_chassis_per_group_ * num_blades_per_chassis_) + myCoords.group];
}
if (targetRouter->blade_ != currentRouter->blade_) {
if (currentRouter->limiter_)
route->link_list_.push_back(currentRouter->limiter_);
- route->link_list_.push_back(currentRouter->green_links_[targetCoords.blade]);
- if (latency)
- *latency += currentRouter->green_links_[targetCoords.blade]->get_latency();
+ add_link_latency(route->link_list_, currentRouter->green_links_[targetCoords.blade], latency);
currentRouter =
&routers_[targetCoords.group * (num_chassis_per_group_ * num_blades_per_chassis_) + targetCoords.blade];
}
if (targetRouter->chassis_ != currentRouter->chassis_) {
if (currentRouter->limiter_)
route->link_list_.push_back(currentRouter->limiter_);
- route->link_list_.push_back(currentRouter->black_links_[targetCoords.chassis]);
- if (latency)
- *latency += currentRouter->black_links_[targetCoords.chassis]->get_latency();
+ add_link_latency(route->link_list_, currentRouter->black_links_[targetCoords.chassis], latency);
}
}
// router->node local link
if (targetRouter->limiter_)
route->link_list_.push_back(targetRouter->limiter_);
- route->link_list_.push_back(
- targetRouter->my_nodes_[targetCoords.node * num_links_per_link_ + num_links_per_link_ - 1]);
-
- if (latency)
- *latency +=
- targetRouter->my_nodes_[targetCoords.node * num_links_per_link_ + num_links_per_link_ - 1]->get_latency();
+ add_link_latency(route->link_list_,
+ targetRouter->my_nodes_[targetCoords.node * num_links_per_link_ + num_links_per_link_ - 1], latency);
if (has_limiter()) { // limiter for receiver
route->link_list_.push_back(get_downlink_to(node_pos_with_loopback(dst->id())));
/* In case destination is the source, and there is a loopback, let's use it instead of going up to a switch */
if (source->id == destination->id && has_loopback()) {
- into->link_list_.push_back(source->loopback_);
- if (latency)
- *latency += source->loopback_->get_latency();
+ add_link_latency(into->link_list_, source->loopback_, latency);
return;
}
if (currentNode->limiter_link_)
into->link_list_.push_back(currentNode->limiter_link_);
- into->link_list_.push_back(currentNode->parents[d]->up_link_);
-
- if (latency)
- *latency += currentNode->parents[d]->up_link_->get_latency();
+ add_link_latency(into->link_list_, currentNode->parents[d]->up_link_, latency);
currentNode = currentNode->parents[d]->up_node_;
}
while (currentNode != destination) {
for (unsigned int i = 0; i < currentNode->children.size(); i++) {
if (i % this->num_children_per_node_[currentNode->level - 1] == destination->label[currentNode->level - 1]) {
- into->link_list_.push_back(currentNode->children[i]->down_link_);
+ add_link_latency(into->link_list_, currentNode->children[i]->down_link_, latency);
if (currentNode->limiter_link_)
into->link_list_.push_back(currentNode->limiter_link_);
- if (latency)
- *latency += currentNode->children[i]->down_link_->get_latency();
currentNode = currentNode->children[i]->down_node_;
XBT_DEBUG("%d(%u,%u) is accessible through %d(%u,%u)", destination->id, destination->level,
destination->position, currentNode->id, currentNode->level, currentNode->position);
get_global_route(prev_dst_gw, e_route->gw_src_, route->link_list_, lat);
}
- for (auto const& link : e_route->link_list_) {
- route->link_list_.push_back(link);
- if (lat)
- *lat += link->get_latency();
- }
+ add_link_latency(route->link_list_, e_route->link_list_, lat);
prev_dst_gw = e_route->gw_dst_;
}
if (e_route != nullptr) {
res->gw_src_ = e_route->gw_src_;
res->gw_dst_ = e_route->gw_dst_;
- for (auto const& link : e_route->link_list_) {
- res->link_list_.push_back(link);
- if (lat)
- *lat += link->get_latency();
- }
+ add_link_latency(res->link_list_, e_route->link_list_, lat);
}
}
/* Build a copy that will be stored in the dict */
auto* newRoute = new BypassRoute(gw_src, gw_dst);
- for (auto const& link : link_list_)
- newRoute->links.push_back(link);
+ newRoute->links.insert(newRoute->links.end(), begin(link_list_), end(link_list_));
/* Store it */
bypass_routes_.insert({{src, dst}, newRoute});
if (dst->get_englobing_zone() == this && src->get_englobing_zone() == this) {
if (bypass_routes_.find({src, dst}) != bypass_routes_.end()) {
const BypassRoute* bypassedRoute = bypass_routes_.at({src, dst});
- for (resource::LinkImpl* const& link : bypassedRoute->links) {
- links.push_back(link);
- if (latency)
- *latency += link->get_latency();
- }
+ add_link_latency(links, bypassedRoute->links, latency);
XBT_DEBUG("Found a bypass route from '%s' to '%s' with %zu links", src->get_cname(), dst->get_cname(),
bypassedRoute->links.size());
return true;
src->get_cname(), dst->get_cname(), bypassedRoute->links.size());
if (src != key.first)
get_global_route_with_netzones(src, bypassedRoute->gw_src, links, latency, netzones);
- for (resource::LinkImpl* const& link : bypassedRoute->links) {
- links.push_back(link);
- if (latency)
- *latency += link->get_latency();
- }
+ add_link_latency(links, bypassedRoute->links, latency);
if (dst != key.second)
get_global_route_with_netzones(bypassedRoute->gw_dst, dst, links, latency, netzones);
return true;
/* do not add duplicated links in route->link_list_ */
if (not added_links.insert(link).second)
continue;
- if (latency)
- *latency += link->get_latency();
- route->link_list_.push_back(link);
+ add_link_latency(route->link_list_, link, latency);
}
}
if (src->id() == dst->id() && has_loopback()) {
resource::LinkImpl* uplink = get_uplink_from(node_pos(src->id()));
- route->link_list_.push_back(uplink);
- if (lat)
- *lat += uplink->get_latency();
+ add_link_latency(route->link_list_, uplink, lat);
return;
}
else
lnk = get_downlink_to(linkOffset);
- route->link_list_.push_back(lnk);
- if (lat)
- *lat += lnk->get_latency();
+ add_link_latency(route->link_list_, lnk, lat);
current_node = next_node;
}
if (src != access_point_) {
XBT_DEBUG("src %s is not our gateway", src->get_cname());
- res->link_list_.push_back(wifi_link_);
- if (lat)
- *lat += wifi_link_->get_latency();
+ add_link_latency(res->link_list_, wifi_link_, lat);
}
if (dst != access_point_) {
XBT_DEBUG("dst %s is not our gateway", dst->get_cname());
- res->link_list_.push_back(wifi_link_);
- if (lat)
- *lat += wifi_link_->get_latency();
+ add_link_latency(res->link_list_, wifi_link_, lat);
}
}
}
#include "src/surf/surf_interface.hpp"
#include "surf/surf.hpp"
+#include <numeric>
+
#ifndef NETWORK_INTERFACE_CPP_
#define NETWORK_INTERFACE_CPP_
return retlist;
}
+
+static void add_latency(const std::vector<LinkImpl*>& links, double* latency)
+{
+ if (latency)
+ *latency = std::accumulate(begin(links), end(links), *latency,
+ [](double lat, const auto* link) { return lat + link->get_latency(); });
+}
+
+void add_link_latency(std::vector<LinkImpl*>& result, LinkImpl* link, double* latency)
+{
+ result.push_back(link);
+ if (latency)
+ *latency += link->get_latency();
+}
+
+void add_link_latency(std::vector<LinkImpl*>& result, const std::vector<LinkImpl*>& links, double* latency)
+{
+ result.insert(result.end(), begin(links), end(links));
+ add_latency(links, latency);
+}
+
+void insert_link_latency(std::vector<LinkImpl*>& result, const std::vector<LinkImpl*>& links, double* latency)
+{
+ result.insert(result.begin(), rbegin(links), rend(links));
+ add_latency(links, latency);
+}
+
} // namespace resource
} // namespace kernel
} // namespace simgrid
s4u::Host& get_src() const { return src_; }
s4u::Host& get_dst() const { return dst_; }
};
+
+/* Insert link(s) at the end of vector `result' (at the beginning, and reversed, for insert_link_latency()), and add
+ * link->get_latency() to *latency when latency is not null
+ */
+void add_link_latency(std::vector<LinkImpl*>& result, LinkImpl* link, double* latency);
+void add_link_latency(std::vector<LinkImpl*>& result, const std::vector<LinkImpl*>& links, double* latency);
+void insert_link_latency(std::vector<LinkImpl*>& result, const std::vector<LinkImpl*>& links, double* latency);
+
} // namespace resource
} // namespace kernel
} // namespace simgrid