+ if (groups.first == 0)
+ throw std::invalid_argument("Dragonfly: Invalid number of groups, must be > 0");
+ if (groups.second == 0)
+ throw std::invalid_argument("Dragonfly: Invalid number of blue (groups) links, must be > 0");
+ if (chassis.first == 0)
+ throw std::invalid_argument("Dragonfly: Invalid number of chassis, must be > 0");
+ if (chassis.second == 0)
+ throw std::invalid_argument("Dragonfly: Invalid number of black (chassis) links, must be > 0");
+ if (routers.first == 0)
+ throw std::invalid_argument("Dragonfly: Invalid number of routers, must be > 0");
+ if (routers.second == 0)
+ throw std::invalid_argument("Dragonfly: Invalid number of green (routers) links, must be > 0");
+ if (nodes == 0)
+ throw std::invalid_argument("Dragonfly: Invalid number of nodes, must be > 0");
+}
+
+NetZone* create_dragonfly_zone(const std::string& name, const NetZone* parent, const DragonflyParams& params,
+ const ClusterCallbacks& set_callbacks, double bandwidth, double latency,
+ Link::SharingPolicy sharing_policy)
+{
+ /* initial checks */
+ if (bandwidth <= 0)
+ throw std::invalid_argument("DragonflyZone: incorrect bandwidth for internode communication, bw=" +
+ std::to_string(bandwidth));
+ if (latency < 0)
+ throw std::invalid_argument("DragonflyZone: incorrect latency for internode communication, lat=" +
+ std::to_string(latency));
+
+ /* creating zone */
+ auto* zone = new kernel::routing::DragonflyZone(name);
+ zone->set_topology(params.groups.first, params.groups.second, params.chassis.first, params.chassis.second,
+ params.routers.first, params.routers.second, params.nodes);
+ if (parent)
+ zone->set_parent(parent->get_impl());
+ zone->set_link_characteristics(bandwidth, latency, sharing_policy);
+
+ /* populating it */
+ std::vector<unsigned long> dimensions = {params.groups.first, params.chassis.first, params.routers.first,
+ params.nodes};
+ int tot_elements = std::accumulate(dimensions.begin(), dimensions.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, dimensions, set_callbacks, &netpoint, &loopback, &limiter);
+ }
+ zone->build_upper_levels(set_callbacks);
+ return zone->get_iface();