+ this->generateSwitches();
+
+
+ if(XBT_LOG_ISENABLED(surf_route_fat_tree, xbt_log_priority_debug)) {
+ std::stringstream msgBuffer;
+
+ msgBuffer << "We are creating a fat tree of " << this->levels << " levels "
+ << "with " << this->nodesByLevel[0] << " processing nodes";
+ for (unsigned int i = 1 ; i <= this->levels ; i++) {
+ msgBuffer << ", " << this->nodesByLevel[i] << " switches at level " << i;
+ }
+ XBT_DEBUG("%s", msgBuffer.str().c_str());
+ msgBuffer.str("");
+ msgBuffer << "Nodes are : ";
+
+ for (unsigned int i = 0 ; i < this->nodes.size() ; i++) {
+ msgBuffer << this->nodes[i]->id << "(" << this->nodes[i]->level << ","
+ << this->nodes[i]->position << ") ";
+ }
+ XBT_DEBUG("%s", msgBuffer.str().c_str());
+ }
+
+
+ this->generateLabels();
+
+ unsigned int k = 0;
+ // Nodes are totally ordered, by level and then by position, in this->nodes
+ for (unsigned int i = 0 ; i < this->levels ; i++) {
+ for (unsigned int j = 0 ; j < this->nodesByLevel[i] ; j++) {
+ this->connectNodeToParents(this->nodes[k]);
+ k++;
+ }
+ }
+
+ if(XBT_LOG_ISENABLED(surf_route_fat_tree, xbt_log_priority_debug)) {
+ std::stringstream msgBuffer;
+ msgBuffer << "Links are : ";
+ for (unsigned int i = 0 ; i < this->links.size() ; i++) {
+ msgBuffer << "(" << this->links[i]->upNode->id << ","
+ << this->links[i]->downNode->id << ") ";
+ }
+ XBT_DEBUG("%s", msgBuffer.str().c_str());
+ }
+
+
+}
+
+int AsClusterFatTree::connectNodeToParents(FatTreeNode *node) {
+ std::vector<FatTreeNode*>::iterator currentParentNode = this->nodes.begin();
+ int connectionsNumber = 0;
+ const int level = node->level;
+ XBT_DEBUG("We are connecting node %d(%u,%u) to his parents.",
+ node->id, node->level, node->position);
+ currentParentNode += this->getLevelPosition(level + 1);
+ for (unsigned int i = 0 ; i < this->nodesByLevel[level + 1] ; i++ ) {
+ if(this->areRelated(*currentParentNode, node)) {
+ XBT_DEBUG("%d(%u,%u) and %d(%u,%u) are related,"
+ " with %u links between them.", node->id,
+ node->level, node->position, (*currentParentNode)->id,
+ (*currentParentNode)->level, (*currentParentNode)->position, this->lowerLevelPortsNumber[level]);
+ for (unsigned int j = 0 ; j < this->lowerLevelPortsNumber[level] ; j++) {
+ this->addLink(*currentParentNode, node->label[level] +
+ j * this->lowerLevelNodesNumber[level], node,
+ (*currentParentNode)->label[level] +
+ j * this->upperLevelNodesNumber[level]);
+ }
+ connectionsNumber++;
+ }
+ ++currentParentNode;
+ }
+ return connectionsNumber;
+}
+
+
+bool AsClusterFatTree::areRelated(FatTreeNode *parent, FatTreeNode *child) {
+ std::stringstream msgBuffer;
+
+ if(XBT_LOG_ISENABLED(surf_route_fat_tree, xbt_log_priority_debug)) {
+ msgBuffer << "Are " << child->id << "(" << child->level << ","
+ << child->position << ") <";
+
+ for (unsigned int i = 0 ; i < this->levels ; i++) {
+ msgBuffer << child->label[i] << ",";
+ }
+ msgBuffer << ">";
+
+ msgBuffer << " and " << parent->id << "(" << parent->level
+ << "," << parent->position << ") <";
+ for (unsigned int i = 0 ; i < this->levels ; i++) {
+ msgBuffer << parent->label[i] << ",";
+ }
+ msgBuffer << ">";
+ msgBuffer << " related ? ";
+ XBT_DEBUG("%s", msgBuffer.str().c_str());
+
+ }
+ if (parent->level != child->level + 1) {
+ return false;
+ }
+
+ for (unsigned int i = 0 ; i < this->levels; i++) {
+ if (parent->label[i] != child->label[i] && i + 1 != parent->level) {
+ return false;
+ }
+ }
+ return true;
+}
+
+void AsClusterFatTree::generateSwitches() {
+ XBT_DEBUG("Generating switches.");
+ this->nodesByLevel.resize(this->levels + 1, 0);