+ using simgrid::kernel::routing::ClusterZone;
+ using simgrid::kernel::routing::DragonflyZone;
+ using simgrid::kernel::routing::FatTreeZone;
+ using simgrid::kernel::routing::TorusZone;
+
+ int rankId=0;
+
+ // What an inventive way of initializing the AS that I have as ancestor :-(
+ s_sg_platf_AS_cbarg_t AS;
+ AS.id = cluster->id;
+ switch (cluster->topology) {
+ case SURF_CLUSTER_TORUS:
+ AS.routing = A_surfxml_AS_routing_ClusterTorus;
+ break;
+ case SURF_CLUSTER_DRAGONFLY:
+ AS.routing = A_surfxml_AS_routing_ClusterDragonfly;
+ break;
+ case SURF_CLUSTER_FAT_TREE:
+ AS.routing = A_surfxml_AS_routing_ClusterFatTree;
+ break;
+ default:
+ AS.routing = A_surfxml_AS_routing_Cluster;
+ break;
+ }
+ sg_platf_new_AS_begin(&AS);
+ simgrid::kernel::routing::ClusterZone* current_as = static_cast<ClusterZone*>(routing_get_current());
+ current_as->parse_specific_arguments(cluster);
+
+ if(cluster->loopback_bw > 0 || cluster->loopback_lat > 0){
+ current_as->linkCountPerNode_++;
+ current_as->hasLoopback_ = 1;
+ }
+
+ if(cluster->limiter_link > 0){
+ current_as->linkCountPerNode_++;
+ current_as->hasLimiter_ = 1;
+ }
+
+ for (int i : *cluster->radicals) {
+ char * host_id = bprintf("%s%d%s", cluster->prefix, i, cluster->suffix);
+ char * link_id = bprintf("%s_link_%d", cluster->id, i);
+
+ XBT_DEBUG("<host\tid=\"%s\"\tpower=\"%f\">", host_id, cluster->speeds.front());
+
+ s_sg_platf_host_cbarg_t host;
+ memset(&host, 0, sizeof(host));
+ host.id = host_id;
+ if ((cluster->properties != nullptr) && (not xbt_dict_is_empty(cluster->properties))) {
+ xbt_dict_cursor_t cursor=nullptr;
+ char *key;
+ char* data;
+ host.properties = xbt_dict_new_homogeneous(free);
+
+ xbt_dict_foreach(cluster->properties,cursor,key,data) {
+ xbt_dict_set(host.properties, key, xbt_strdup(data), nullptr);
+ }
+ }
+
+ host.speed_per_pstate = cluster->speeds;
+ host.pstate = 0;
+ host.core_amount = cluster->core_amount;
+ host.coord = "";
+ sg_platf_new_host(&host);
+ XBT_DEBUG("</host>");
+
+ XBT_DEBUG("<link\tid=\"%s\"\tbw=\"%f\"\tlat=\"%f\"/>", link_id, cluster->bw, cluster->lat);
+
+ // 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 for the node
+
+ //add a loopback link
+ simgrid::surf::LinkImpl* linkUp = nullptr;
+ simgrid::surf::LinkImpl* linkDown = nullptr;
+ if(cluster->loopback_bw > 0 || cluster->loopback_lat > 0){
+ char *tmp_link = bprintf("%s_loopback", link_id);
+ XBT_DEBUG("<loopback\tid=\"%s\"\tbw=\"%f\"/>", tmp_link, cluster->loopback_bw);
+
+ LinkCreationArgs link;
+ link.id = tmp_link;
+ link.bandwidth = cluster->loopback_bw;
+ link.latency = cluster->loopback_lat;
+ link.policy = SURF_LINK_FATPIPE;
+ sg_platf_new_link(&link);
+ linkUp = simgrid::surf::LinkImpl::byName(tmp_link);
+ linkDown = simgrid::surf::LinkImpl::byName(tmp_link);
+ free(tmp_link);
+
+ auto as_cluster = static_cast<ClusterZone*>(current_as);
+ as_cluster->privateLinks_.insert({rankId * as_cluster->linkCountPerNode_, {linkUp, linkDown}});
+ }
+
+ //add a limiter link (shared link to account for maximal bandwidth of the node)
+ linkUp = nullptr;
+ linkDown = nullptr;
+ if(cluster->limiter_link > 0){
+ char *tmp_link = bprintf("%s_limiter", link_id);
+ XBT_DEBUG("<limiter\tid=\"%s\"\tbw=\"%f\"/>", tmp_link, cluster->limiter_link);
+
+ LinkCreationArgs link;
+ link.id = tmp_link;
+ link.bandwidth = cluster->limiter_link;
+ link.latency = 0;
+ link.policy = SURF_LINK_SHARED;
+ sg_platf_new_link(&link);
+ linkDown = simgrid::surf::LinkImpl::byName(tmp_link);
+ linkUp = linkDown;
+ free(tmp_link);
+ current_as->privateLinks_.insert(
+ {rankId * current_as->linkCountPerNode_ + current_as->hasLoopback_, {linkUp, linkDown}});
+ }
+
+ //call the cluster function that adds the others links
+ if (cluster->topology == SURF_CLUSTER_FAT_TREE) {
+ static_cast<FatTreeZone*>(current_as)->addProcessingNode(i);
+ } else {
+ current_as->create_links_for_node(cluster, i, rankId,
+ rankId*current_as->linkCountPerNode_ + current_as->hasLoopback_ + current_as->hasLimiter_ );
+ }
+ xbt_free(link_id);
+ xbt_free(host_id);
+ rankId++;
+ }
+ xbt_dict_free(&cluster->properties);
+
+ // Add a router.
+ XBT_DEBUG(" ");
+ XBT_DEBUG("<router id=\"%s\"/>", cluster->router_id);
+ if (not cluster->router_id || not strcmp(cluster->router_id, "")) {
+ char* newid = bprintf("%s%s_router%s", cluster->prefix, cluster->id, cluster->suffix);
+ current_as->router_ = sg_platf_new_router(newid, NULL);
+ free(newid);
+ } else {
+ current_as->router_ = sg_platf_new_router(cluster->router_id, NULL);
+ }
+
+ //Make the backbone
+ if ((cluster->bb_bw > 0) || (cluster->bb_lat > 0)) {
+
+ LinkCreationArgs link;
+ link.id = std::string(cluster->id)+ "_backbone";
+ link.bandwidth = cluster->bb_bw;
+ link.latency = cluster->bb_lat;
+ link.policy = cluster->bb_sharing_policy;
+
+ XBT_DEBUG("<link\tid=\"%s\" bw=\"%f\" lat=\"%f\"/>", link.id.c_str(), cluster->bb_bw, cluster->bb_lat);
+ sg_platf_new_link(&link);
+
+ routing_cluster_add_backbone(simgrid::surf::LinkImpl::byName(link.id.c_str()));
+ }
+
+ XBT_DEBUG("</AS>");
+ sg_platf_new_AS_seal();
+
+ simgrid::surf::on_cluster(cluster);
+ delete cluster->radicals;
+}
+
+void routing_cluster_add_backbone(simgrid::surf::LinkImpl* bb)
+{
+ simgrid::kernel::routing::ClusterZone* cluster =
+ dynamic_cast<simgrid::kernel::routing::ClusterZone*>(current_routing);
+
+ xbt_assert(cluster, "Only hosts from Cluster can get a backbone.");
+ xbt_assert(nullptr == cluster->backbone_, "Cluster %s already has a backbone link!", cluster->name());
+
+ cluster->backbone_ = bb;
+ XBT_DEBUG("Add a backbone to AS '%s'", current_routing->name());
+}