Implements the builder method for Fat Tree zones.
Similar signature and behavior of create_torus_zone.
include src/kernel/routing/DragonflyZone.cpp
include src/kernel/routing/EmptyZone.cpp
include src/kernel/routing/FatTreeZone.cpp
+include src/kernel/routing/FatTreeZone_test.cpp
include src/kernel/routing/FloydZone.cpp
include src/kernel/routing/FullZone.cpp
include src/kernel/routing/NetPoint.cpp
{
return node_pos_with_loopback(id) + (has_limiter_ ? 1 : 0);
}
+ /** Fill the leaf retriving netpoint from a user's callback */
+ void fill_leaf_from_cb(unsigned int position, const std::vector<unsigned int>& dimensions,
+ const std::function<s4u::ClusterNetPointCb>& set_netpoint_cb,
+ const std::function<s4u::ClusterLinkCb>& set_loopback_cb,
+ const std::function<s4u::ClusterLinkCb>& set_limiter_cb, NetPoint** node_netpoint,
+ s4u::Link** lb_link, s4u::Link** limiter_link);
};
} // namespace routing
} // namespace kernel
std::vector<FatTreeLink*> links_;
std::vector<unsigned int> nodes_by_level_;
- ClusterCreationArgs* cluster_ = nullptr;
+ s4u::Link::SharingPolicy link_sharing_policy_; //!< fat tree links: sharing policy
+ double link_bw_; //!< fat tree links: bandwidth
+ double link_lat_; //!< fat tree links: latency
void add_link(FatTreeNode* parent, unsigned int parent_port, FatTreeNode* child, unsigned int child_port);
int get_level_position(const unsigned int level);
~FatTreeZone() override;
void get_local_route(NetPoint* src, NetPoint* dst, RouteCreationArgs* into, double* latency) override;
- /** @brief Read the parameters in topo_parameters field.
- *
- * It will also store the cluster for future use.
- */
+ /** @brief Read the parameters in topo_parameters field. */
void parse_specific_arguments(ClusterCreationArgs* cluster) override;
+ /** @brief Checks topology parameters */
+ static void check_topology(unsigned int n_levels, const std::vector<unsigned int>& down_links,
+ const std::vector<unsigned int>& up_links, const std::vector<unsigned int>& link_count);
+ /** @brief Set FatTree topology */
+ void set_topology(unsigned int n_levels, const std::vector<unsigned int>& down_links,
+ const std::vector<unsigned int>& up_links, const std::vector<unsigned int>& link_count);
+ /** @brief Set the characteristics of links inside the Fat Tree zone */
+ void set_link_characteristics(double bw, double lat, s4u::Link::SharingPolicy sharing_policy);
void add_processing_node(int id, resource::LinkImpl* limiter, resource::LinkImpl* loopback);
void generate_dot_file(const std::string& filename = "fat_tree.dot") const;
};
XBT_PUBLIC NetZone* create_cluster_zone(const std::string& name);
XBT_PUBLIC NetZone* create_star_zone(const std::string& name);
XBT_PUBLIC NetZone* create_dijkstra_zone(const std::string& name, bool cache);
-XBT_PUBLIC NetZone* create_dragonfly_zone(const std::string& name);
XBT_PUBLIC NetZone* create_empty_zone(const std::string& name);
-XBT_PUBLIC NetZone* create_fatTree_zone(const std::string& name);
XBT_PUBLIC NetZone* create_floyd_zone(const std::string& name);
+XBT_PUBLIC NetZone* create_vivaldi_zone(const std::string& name);
+XBT_PUBLIC NetZone* create_wifi_zone(const std::string& name);
/**
- * @brief Callback used to set the netpoint and gateway located at some leaf of the torus
+ * @brief Callback used to set the netpoint and gateway located at some leaf of clusters (Torus, FatTree, etc)
*
* The netpoint can be either a host, router or another netzone.
* Gateway must be non-null if netpoint is a netzone
*
- * @param zone: The newly create Torus zone, needed for creating new resources (hosts, links)
- * @param coord: the coordinates of the element in the torus, eg. 0,1,1
+ * @param zone: The newly create zone, needed for creating new resources (hosts, links)
+ * @param coord: the coordinates of the element
* @param id: Internal identifier of the element
* @return pair<NetPoint*, NetPoint*>: returns a pair of netpoint and gateway.
*/
-using TorusNetPointCb = std::pair<kernel::routing::NetPoint*, kernel::routing::NetPoint*>(
+using ClusterNetPointCb = std::pair<kernel::routing::NetPoint*, kernel::routing::NetPoint*>(
NetZone* zone, const std::vector<unsigned int>& coord, int id);
/**
- * @brief Callback used to set the links for some leaf of the torus
+ * @brief Callback used to set the links for some leaf of the cluster (Torus, FatTree, etc)
*
- * @param zone: The newly create Torus zone, needed for creating new resources (hosts, links)
- * @param coord: the coordinates of the element in the torus, eg. 0,1,1
+ * @param zone: The newly create zone, needed for creating new resources (hosts, links)
+ * @param coord: the coordinates of the element
* @param id: Internal identifier of the element
* @return Pointer to the Link
*/
-using TorusLinkCb = Link*(NetZone* zone, const std::vector<unsigned int>& coord, int id);
+using ClusterLinkCb = Link*(NetZone* zone, const std::vector<unsigned int>& coord, int id);
/**
* @brief Create a torus zone
*
* @param set_limiter Callback to set the limiter
* @return Pointer to new netzone
*/
-NetZone* create_torus_zone(const std::string& name, const NetZone* parent, const std::vector<unsigned int>& dimensions,
- double bandwidth, double latency, Link::SharingPolicy sharing_policy,
- const std::function<TorusNetPointCb>& set_netpoint,
- const std::function<TorusLinkCb>& set_loopback = {},
- const std::function<TorusLinkCb>& set_limiter = {});
-XBT_PUBLIC NetZone* create_vivaldi_zone(const std::string& name);
-XBT_PUBLIC NetZone* create_wifi_zone(const std::string& name);
+XBT_PUBLIC NetZone* create_torus_zone(const std::string& name, const NetZone* parent,
+ const std::vector<unsigned int>& dimensions, double bandwidth, double latency,
+ Link::SharingPolicy sharing_policy,
+ const std::function<ClusterNetPointCb>& set_netpoint,
+ const std::function<ClusterLinkCb>& set_loopback = {},
+ const std::function<ClusterLinkCb>& set_limiter = {});
+struct FatTreeParams {
+ unsigned int levels;
+ std::vector<unsigned int> down;
+ std::vector<unsigned int> up;
+ std::vector<unsigned int> number;
+ FatTreeParams(unsigned int n_levels, const std::vector<unsigned int>& down_links,
+ const std::vector<unsigned int>& up_links, const std::vector<unsigned int>& links_number)
+ : levels(n_levels), down(down_links), up(up_links), number(links_number)
+ { /* nothing to do */
+ }
+};
+
+XBT_PUBLIC NetZone* create_fatTree_zone(const std::string& name, const NetZone* parent, const FatTreeParams& parameters,
+ double bandwidth, double latency, Link::SharingPolicy sharing_policy,
+ const std::function<ClusterNetPointCb>& set_netpoint,
+ const std::function<ClusterLinkCb>& set_loopback = {},
+ const std::function<ClusterLinkCb>& set_limiter = {});
+
+XBT_PUBLIC NetZone* create_dragonfly_zone(const std::string& name);
} // namespace s4u
} // namespace simgrid
return res;
}
+void ClusterZone::fill_leaf_from_cb(unsigned int position, const std::vector<unsigned int>& dimensions,
+ const std::function<s4u::ClusterNetPointCb>& set_netpoint_cb,
+ const std::function<s4u::ClusterLinkCb>& set_loopback_cb,
+ const std::function<s4u::ClusterLinkCb>& set_limiter_cb, NetPoint** node_netpoint,
+ s4u::Link** lb_link, s4u::Link** limiter_link)
+{
+ xbt_assert(node_netpoint, "Invalid node_netpoint parameter");
+ xbt_assert(lb_link, "Invalid lb_link parameter");
+ xbt_assert(limiter_link, "Invalid limiter_link paramater");
+ *lb_link = nullptr;
+ *limiter_link = nullptr;
+
+ // auxiliary function to get dims from index
+ auto index_to_dims = [&dimensions](int index) {
+ std::vector<unsigned int> dims_array(dimensions.size());
+ for (unsigned long i = dimensions.size() - 1; i != 0; --i) {
+ if (index <= 0) {
+ break;
+ }
+ unsigned int value = index % dimensions[i];
+ dims_array[i] = value;
+ index = (index / dimensions[i]);
+ }
+ return dims_array;
+ };
+
+ kernel::routing::NetPoint* netpoint = nullptr;
+ kernel::routing::NetPoint* gw = nullptr;
+ auto dims = index_to_dims(position);
+ std::tie(netpoint, gw) = set_netpoint_cb(get_iface(), dims, position);
+ xbt_assert(netpoint, "set_netpoint(elem=%u): Invalid netpoint (nullptr)", position);
+ if (netpoint->is_netzone()) {
+ xbt_assert(gw && not gw->is_netzone(),
+ "set_netpoint(elem=%u): Netpoint (%s) is a netzone, but gateway (%s) is invalid", position,
+ netpoint->get_cname(), gw ? gw->get_cname() : "nullptr");
+ } else {
+ xbt_assert(not gw, "set_netpoint: Netpoint (%s) isn't netzone, gateway must be nullptr", netpoint->get_cname());
+ }
+ // setting gateway
+ set_gateway(position, gw);
+
+ if (set_loopback_cb) {
+ s4u::Link* loopback = set_loopback_cb(get_iface(), dims, position);
+ xbt_assert(loopback, "set_loopback: Invalid loopback link (nullptr) for element %u", position);
+ set_loopback();
+ add_private_link_at(node_pos(netpoint->id()), {loopback->get_impl(), loopback->get_impl()});
+ *lb_link = loopback;
+ }
+
+ if (set_limiter_cb) {
+ s4u::Link* limiter = set_limiter_cb(get_iface(), dims, position);
+ xbt_assert(limiter, "set_limiter: Invalid limiter link (nullptr) for element %u", position);
+ set_limiter();
+ add_private_link_at(node_pos_with_loopback(netpoint->id()), {limiter->get_impl(), limiter->get_impl()});
+ *limiter_link = limiter;
+ }
+ *node_netpoint = netpoint;
+}
+
} // namespace routing
} // namespace kernel
* under the terms of the license (GNU LGPL) which comes with this package. */
#include <fstream>
+#include <numeric>
#include <sstream>
#include <string>
}
}
}
+ // set gateways (if any)
+ into->gw_src = get_gateway(src->id());
+ into->gw_dst = get_gateway(dst->id());
}
/* This function makes the assumption that parse_specific_arguments() and
std::string id =
"link_from_" + std::to_string(child->id) + "_" + std::to_string(parent->id) + "_" + std::to_string(uniqueId);
- if (cluster_->sharing_policy == s4u::Link::SharingPolicy::SPLITDUPLEX) {
- linkup = create_link(id + "_UP", std::vector<double>{cluster_->bw})->set_latency(cluster_->lat)->seal();
- linkdown = create_link(id + "_DOWN", std::vector<double>{cluster_->bw})->set_latency(cluster_->lat)->seal();
+ if (link_sharing_policy_ == s4u::Link::SharingPolicy::SPLITDUPLEX) {
+ linkup = create_link(id + "_UP", std::vector<double>{link_bw_})->set_latency(link_lat_)->seal();
+ linkdown = create_link(id + "_DOWN", std::vector<double>{link_bw_})->set_latency(link_lat_)->seal();
} else {
- linkup = create_link(id, std::vector<double>{cluster_->bw})->set_latency(cluster_->lat)->seal();
+ linkup = create_link(id, std::vector<double>{link_bw_})->set_latency(link_lat_)->seal();
linkdown = linkup;
}
uniqueId++;
this->links_.push_back(newLink);
}
+void FatTreeZone::check_topology(unsigned int n_levels, const std::vector<unsigned int>& down_links,
+ const std::vector<unsigned int>& up_links, const std::vector<unsigned int>& link_count)
+
+{
+ /* check number of levels */
+ if (n_levels <= 0)
+ throw std::invalid_argument("FatTreeZone: invalid number of levels, must be > 0");
+
+ auto check_vector = [&n_levels](const std::vector<unsigned int>& vector, const std::string& var_name) {
+ if (vector.size() != n_levels)
+ throw std::invalid_argument("FatTreeZone: invalid " + var_name + " parameter, vector has " +
+ std::to_string(vector.size()) + " elements, must have " + std::to_string(n_levels));
+
+ auto check_zero = [](unsigned int i) { return i == 0; };
+ if (std::any_of(vector.begin(), vector.end(), check_zero))
+ throw std::invalid_argument("FatTreeZone: invalid " + var_name + " parameter, all values must be greater than 0");
+ };
+
+ /* check remaining vectors */
+ check_vector(down_links, "down links");
+ check_vector(up_links, "up links");
+ check_vector(link_count, "link count");
+}
+
+void FatTreeZone::set_link_characteristics(double bw, double lat, s4u::Link::SharingPolicy sharing_policy)
+{
+ link_sharing_policy_ = sharing_policy;
+ link_bw_ = bw;
+ link_lat_ = lat;
+}
+
+void FatTreeZone::set_topology(unsigned int n_levels, const std::vector<unsigned int>& down_links,
+ const std::vector<unsigned int>& up_links, const std::vector<unsigned int>& link_count)
+{
+ levels_ = n_levels;
+ num_children_per_node_ = down_links;
+ num_parents_per_node_ = up_links;
+ num_port_lower_level_ = link_count;
+}
+
void FatTreeZone::parse_specific_arguments(ClusterCreationArgs* cluster)
{
std::vector<std::string> parameters;
std::vector<std::string> tmp;
+ unsigned int n_lev = 0;
+ std::vector<unsigned int> down;
+ std::vector<unsigned int> up;
+ std::vector<unsigned int> count;
boost::split(parameters, cluster->topo_parameters, boost::is_any_of(";"));
- // TODO : we have to check for zeros and negative numbers, or it might crash
surf_parse_assert(
parameters.size() == 4,
"Fat trees are defined by the levels number and 3 vectors, see the documentation for more information.");
// The first parts of topo_parameters should be the levels number
try {
- this->levels_ = std::stoi(parameters[0]);
+ n_lev = std::stoi(parameters[0]);
} catch (const std::invalid_argument&) {
surf_parse_error(std::string("First parameter is not the amount of levels: ") + parameters[0]);
}
// Then, a l-sized vector standing for the children number by level
boost::split(tmp, parameters[1], boost::is_any_of(","));
- surf_parse_assert(tmp.size() == this->levels_, std::string("You specified ") + std::to_string(this->levels_) +
- " levels but the child count vector (the first one) contains " +
- std::to_string(tmp.size()) + " levels.");
+ surf_parse_assert(tmp.size() == n_lev, std::string("You specified ") + std::to_string(n_lev) +
+ " levels but the child count vector (the first one) contains " +
+ std::to_string(tmp.size()) + " levels.");
for (std::string const& level : tmp) {
try {
- this->num_children_per_node_.push_back(std::stoi(level));
+ down.push_back(std::stoi(level));
} catch (const std::invalid_argument&) {
surf_parse_error(std::string("Invalid child count: ") + level);
}
// Then, a l-sized vector standing for the parents number by level
boost::split(tmp, parameters[2], boost::is_any_of(","));
- surf_parse_assert(tmp.size() == this->levels_, std::string("You specified ") + std::to_string(this->levels_) +
- " levels but the parent count vector (the second one) contains " +
- std::to_string(tmp.size()) + " levels.");
+ surf_parse_assert(tmp.size() == n_lev, std::string("You specified ") + std::to_string(n_lev) +
+ " levels but the parent count vector (the second one) contains " +
+ std::to_string(tmp.size()) + " levels.");
for (std::string const& parent : tmp) {
try {
- this->num_parents_per_node_.push_back(std::stoi(parent));
+ up.push_back(std::stoi(parent));
} catch (const std::invalid_argument&) {
surf_parse_error(std::string("Invalid parent count: ") + parent);
}
// Finally, a l-sized vector standing for the ports number with the lower level
boost::split(tmp, parameters[3], boost::is_any_of(","));
- surf_parse_assert(tmp.size() == this->levels_, std::string("You specified ") + std::to_string(this->levels_) +
- " levels but the port count vector (the third one) contains " +
- std::to_string(tmp.size()) + " levels.");
+ surf_parse_assert(tmp.size() == n_lev, std::string("You specified ") + std::to_string(n_lev) +
+ " levels but the port count vector (the third one) contains " +
+ std::to_string(tmp.size()) + " levels.");
for (std::string const& port : tmp) {
try {
- this->num_port_lower_level_.push_back(std::stoi(port));
+ count.push_back(std::stoi(port));
} catch (const std::invalid_argument&) {
throw std::invalid_argument(std::string("Invalid lower level port number:") + port);
}
}
- this->cluster_ = cluster;
+
+ /* set topology */
+ FatTreeZone::check_topology(n_lev, down, up, count);
+ set_topology(n_lev, down, up, count);
+ /* saving internal links properties */
+ set_link_characteristics(cluster->bw, cluster->lat, cluster->sharing_policy);
}
void FatTreeZone::generate_dot_file(const std::string& filename) const
} // namespace kernel
namespace s4u {
-NetZone* create_fatTree_zone(const std::string& name)
+NetZone* create_fatTree_zone(const std::string& name, const NetZone* parent, const FatTreeParams& params,
+ double bandwidth, double latency, Link::SharingPolicy sharing_policy,
+ const std::function<ClusterNetPointCb>& set_netpoint,
+ const std::function<ClusterLinkCb>& set_loopback,
+ const std::function<ClusterLinkCb>& set_limiter)
{
- return (new kernel::routing::FatTreeZone(name))->get_iface();
+ /* initial checks */
+ if (bandwidth <= 0)
+ throw std::invalid_argument("FatTreeZone: incorrect bandwidth for internode communication, bw=" +
+ std::to_string(bandwidth));
+ if (latency < 0)
+ throw std::invalid_argument("FatTreeZone: incorrect latency for internode communication, lat=" +
+ std::to_string(latency));
+ kernel::routing::FatTreeZone::check_topology(params.levels, params.down, params.up, params.number);
+
+ /* creating zone */
+ auto* zone = new kernel::routing::FatTreeZone(name);
+ zone->set_topology(params.levels, params.down, params.up, params.number);
+ if (parent)
+ zone->set_parent(parent->get_impl());
+ zone->set_link_characteristics(bandwidth, latency, sharing_policy);
+
+ /* populating it */
+ int tot_elements = std::accumulate(params.down.begin(), params.down.end(), 1, std::multiplies<>());
+ for (int i = 0; i < tot_elements; i++) {
+ kernel::routing::NetPoint* netpoint;
+ Link* limiter;
+ Link* loopback;
+ zone->fill_leaf_from_cb(i, params.down, set_netpoint, set_loopback, set_limiter, &netpoint, &loopback, &limiter);
+ zone->add_processing_node(i, limiter ? limiter->get_impl() : nullptr, loopback ? loopback->get_impl() : nullptr);
+ }
+
+ return zone->get_iface();
}
} // namespace s4u
--- /dev/null
+/* Copyright (c) 2017-2021. The SimGrid Team. All rights reserved. */
+
+/* This program is free software; you can redistribute it and/or modify it
+ * under the terms of the license (GNU LGPL) which comes with this package. */
+
+#include "catch.hpp"
+
+#include "simgrid/kernel/routing/FatTreeZone.hpp"
+#include "simgrid/kernel/routing/NetPoint.hpp"
+#include "simgrid/s4u/Engine.hpp"
+#include "simgrid/s4u/Host.hpp"
+#include "simgrid/s4u/NetZone.hpp"
+
+namespace {
+class EngineWrapper {
+public:
+ explicit EngineWrapper(std::string name) : argv(&name[0]), e(&argc, &argv) {}
+ int argc = 1;
+ char* argv;
+ simgrid::s4u::Engine e;
+};
+
+std::pair<simgrid::kernel::routing::NetPoint*, simgrid::kernel::routing::NetPoint*>
+create_host(simgrid::s4u::NetZone* zone, const std::vector<unsigned int>& coord, int id)
+{
+ const simgrid::s4u::Host* host = zone->create_host(std::to_string(id), 1e9)->seal();
+ return std::make_pair(host->get_netpoint(), nullptr);
+}
+} // namespace
+
+TEST_CASE("kernel::routing::FatTreeZone: Creating Zone", "")
+{
+ using namespace simgrid::s4u;
+ EngineWrapper e("test");
+ REQUIRE(create_fatTree_zone("test", e.e.get_netzone_root(), {2, {4, 4}, {1, 2}, {1, 2}}, 1e9, 10,
+ simgrid::s4u::Link::SharingPolicy::SHARED, create_host));
+}
+
+TEST_CASE("kernel::routing::FatTreeZone: Invalid params", "")
+{
+ using namespace simgrid::s4u;
+ EngineWrapper e("test");
+
+ SECTION("0 levels")
+ {
+ REQUIRE_THROWS_AS(create_fatTree_zone("test", e.e.get_netzone_root(), {0, {4, 4}, {1, 2}, {1, 2}}, 1e9, 10,
+ simgrid::s4u::Link::SharingPolicy::SHARED, create_host),
+ std::invalid_argument);
+ }
+
+ SECTION("Invalid down links")
+ {
+ REQUIRE_THROWS_AS(create_fatTree_zone("test", e.e.get_netzone_root(), {2, {4}, {1, 2}, {1, 2}}, 1e9, 10,
+ simgrid::s4u::Link::SharingPolicy::SHARED, create_host),
+ std::invalid_argument);
+ }
+
+ SECTION("Invalid up links")
+ {
+ REQUIRE_THROWS_AS(create_fatTree_zone("test", e.e.get_netzone_root(), {2, {4, 4}, {1}, {1, 2}}, 1e9, 10,
+ simgrid::s4u::Link::SharingPolicy::SHARED, create_host),
+ std::invalid_argument);
+ }
+
+ SECTION("Invalid link count")
+ {
+ REQUIRE_THROWS_AS(create_fatTree_zone("test", e.e.get_netzone_root(), {2, {4, 4}, {1, 2}, {1}}, 1e9, 10,
+ simgrid::s4u::Link::SharingPolicy::SHARED, create_host),
+ std::invalid_argument);
+ }
+
+ SECTION("Down links with zeroes")
+ {
+ REQUIRE_THROWS_AS(create_fatTree_zone("test", e.e.get_netzone_root(), {2, {4, 0}, {1, 2}, {1, 2}}, 1e9, 10,
+ simgrid::s4u::Link::SharingPolicy::SHARED, create_host),
+ std::invalid_argument);
+ }
+
+ SECTION("Up links with zeroes")
+ {
+ REQUIRE_THROWS_AS(create_fatTree_zone("test", e.e.get_netzone_root(), {2, {4, 4}, {0, 2}, {1, 2}}, 1e9, 10,
+ simgrid::s4u::Link::SharingPolicy::SHARED, create_host),
+ std::invalid_argument);
+ }
+
+ SECTION("Link count with zeroes")
+ {
+ REQUIRE_THROWS_AS(create_fatTree_zone("test", e.e.get_netzone_root(), {2, {4, 4}, {1, 2}, {1, 0}}, 1e9, 10,
+ simgrid::s4u::Link::SharingPolicy::SHARED, create_host),
+ std::invalid_argument);
+ }
+
+ SECTION("0 bandwidth")
+ {
+ REQUIRE_THROWS_AS(create_fatTree_zone("test", e.e.get_netzone_root(), {2, {4, 4}, {1, 2}, {1, 2}}, 0, 10,
+ simgrid::s4u::Link::SharingPolicy::SHARED, create_host),
+ std::invalid_argument);
+ }
+
+ SECTION("Negative latency")
+ {
+ REQUIRE_THROWS_AS(create_fatTree_zone("test", e.e.get_netzone_root(), {2, {4, 4}, {1, 2}, {1, 2}}, 1e9, -10,
+ simgrid::s4u::Link::SharingPolicy::SHARED, create_host),
+ std::invalid_argument);
+ }
+}
\ No newline at end of file
{
using namespace std::placeholders;
auto set_host = std::bind(create_torus_host, cluster, _1, _2, _3);
- std::function<s4u::TorusLinkCb> set_loopback{};
- std::function<s4u::TorusLinkCb> set_limiter{};
+ std::function<s4u::ClusterLinkCb> set_loopback{};
+ std::function<s4u::ClusterLinkCb> set_limiter{};
if (cluster->loopback_bw > 0 || cluster->loopback_lat > 0) {
set_loopback = std::bind(create_torus_loopback, cluster, _1, _2, _3);
NetZone* create_torus_zone(const std::string& name, const NetZone* parent, const std::vector<unsigned int>& dimensions,
double bandwidth, double latency, Link::SharingPolicy sharing_policy,
- const std::function<TorusNetPointCb>& set_netpoint,
- const std::function<TorusLinkCb>& set_loopback,
- const std::function<TorusLinkCb>& set_limiter)
+ const std::function<ClusterNetPointCb>& set_netpoint,
+ const std::function<ClusterLinkCb>& set_loopback,
+ const std::function<ClusterLinkCb>& set_limiter)
{
int tot_elements = std::accumulate(dimensions.begin(), dimensions.end(), 1, std::multiplies<>());
if (dimensions.empty() || tot_elements <= 0)
throw std::invalid_argument("TorusZone: incorrect latency for internode communication, lat=" +
std::to_string(latency));
- // auxiliary function to get dims from index
- auto index_to_dims = [&dimensions](int index) {
- std::vector<unsigned int> dims_array(dimensions.size());
- for (unsigned long i = dimensions.size() - 1; i != 0; --i) {
- if (index <= 0) {
- break;
- }
- unsigned int value = index % dimensions[i];
- dims_array[i] = value;
- index = (index / dimensions[i]);
- }
- return dims_array;
- };
-
auto* zone = new kernel::routing::TorusZone(name);
zone->set_topology(dimensions);
if (parent)
zone->set_parent(parent->get_impl());
for (int i = 0; i < tot_elements; i++) {
- kernel::routing::NetPoint* netpoint = nullptr;
- kernel::routing::NetPoint* gw = nullptr;
- auto dims = index_to_dims(i);
- std::tie(netpoint, gw) = set_netpoint(zone->get_iface(), dims, i);
- xbt_assert(netpoint, "TorusZone::set_netpoint(elem=%d): Invalid netpoint (nullptr)", i);
- if (netpoint->is_netzone()) {
- xbt_assert(gw && not gw->is_netzone(),
- "TorusZone::set_netpoint(elem=%d): Netpoint (%s) is a netzone, but gateway (%s) is invalid", i,
- netpoint->get_cname(), gw ? gw->get_cname() : "nullptr");
- } else {
- xbt_assert(not gw, "TorusZone: Netpoint (%s) isn't netzone, gateway must be nullptr", netpoint->get_cname());
- }
- // setting gateway
- zone->set_gateway(i, gw);
-
- if (set_loopback) {
- const Link* loopback = set_loopback(zone->get_iface(), dims, i);
- xbt_assert(loopback, "TorusZone::set_loopback: Invalid loopback link (nullptr) for element %d", i);
- zone->set_loopback();
- zone->add_private_link_at(zone->node_pos(netpoint->id()), {loopback->get_impl(), loopback->get_impl()});
- }
-
- if (set_limiter) {
- const Link* limiter = set_limiter(zone->get_iface(), dims, i);
- xbt_assert(limiter, "TorusZone::set_limiter: Invalid limiter link (nullptr) for element %d", i);
- zone->set_limiter();
- zone->add_private_link_at(zone->node_pos_with_loopback(netpoint->id()),
- {limiter->get_impl(), limiter->get_impl()});
- }
+ kernel::routing::NetPoint* netpoint;
+ Link* limiter;
+ Link* loopback;
+ zone->fill_leaf_from_cb(i, dimensions, set_netpoint, set_loopback, set_limiter, &netpoint, &loopback, &limiter);
kernel::routing::ClusterCreationArgs params;
params.id = name;
# New tests should use the Catch Framework
set(UNIT_TESTS src/xbt/unit-tests_main.cpp
src/kernel/resource/profile/Profile_test.cpp
+ src/kernel/routing/FatTreeZone_test.cpp
src/kernel/routing/StarZone_test.cpp
src/kernel/routing/TorusZone_test.cpp
src/xbt/config_test.cpp