+ 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);
+ unsigned int nodesRequired = 0;
+
+ // We take care of the number of nodes by level
+ this->nodesByLevel[0] = 1;
+ for (unsigned int i = 0 ; i < this->levels ; i++) {
+ this->nodesByLevel[0] *= this->lowerLevelNodesNumber[i];
+ }
+
+
+ if(this->nodesByLevel[0] != this->nodes.size()) {
+ surf_parse_error("The number of provided nodes does not fit with the wanted topology."
+ " Please check your platform description (We need %d nodes, we got %zu)",
+ this->nodesByLevel[0], this->nodes.size());
+ return;
+ }
+
+
+ for (unsigned int i = 0 ; i < this->levels ; i++) {
+ int nodesInThisLevel = 1;
+
+ for (unsigned int j = 0 ; j <= i ; j++) {
+ nodesInThisLevel *= this->upperLevelNodesNumber[j];
+ }
+
+ for (unsigned int j = i+1 ; j < this->levels ; j++) {
+ nodesInThisLevel *= this->lowerLevelNodesNumber[j];
+ }
+
+ this->nodesByLevel[i+1] = nodesInThisLevel;
+ nodesRequired += nodesInThisLevel;
+ }
+
+
+ // We create the switches
+ int k = 0;
+ for (unsigned int i = 0 ; i < this->levels ; i++) {
+ for (unsigned int j = 0 ; j < this->nodesByLevel[i + 1] ; j++) {
+ FatTreeNode* newNode;
+ newNode = new FatTreeNode(this->cluster, --k, i + 1, j);
+ XBT_DEBUG("We create the switch %d(%d,%d)", newNode->id, newNode->level,
+ newNode->position);
+ newNode->children.resize(this->lowerLevelNodesNumber[i] *
+ this->lowerLevelPortsNumber[i]);
+ if (i != this->levels - 1) {
+ newNode->parents.resize(this->upperLevelNodesNumber[i + 1] *
+ this->lowerLevelPortsNumber[i + 1]);
+ }
+ newNode->label.resize(this->levels);
+ this->nodes.push_back(newNode);
+ }
+ }
+}
+
+void AsClusterFatTree::generateLabels() {
+ XBT_DEBUG("Generating labels.");
+ // TODO : check if nodesByLevel and nodes are filled
+ std::vector<int> maxLabel(this->levels);
+ std::vector<int> currentLabel(this->levels);
+ unsigned int k = 0;
+ for (unsigned int i = 0 ; i <= this->levels ; i++) {
+ currentLabel.assign(this->levels, 0);
+ for (unsigned int j = 0 ; j < this->levels ; j++) {
+ maxLabel[j] = j + 1 > i ?
+ this->lowerLevelNodesNumber[j] : this->upperLevelNodesNumber[j];
+ }
+
+ for (unsigned int j = 0 ; j < this->nodesByLevel[i] ; j++) {
+
+ if(XBT_LOG_ISENABLED(surf_route_fat_tree, xbt_log_priority_debug )) {
+ std::stringstream msgBuffer;
+
+ msgBuffer << "Assigning label <";
+ for (unsigned int l = 0 ; l < this->levels ; l++) {
+ msgBuffer << currentLabel[l] << ",";
+ }
+ msgBuffer << "> to " << k << " (" << i << "," << j <<")";
+
+ XBT_DEBUG("%s", msgBuffer.str().c_str());
+ }
+ this->nodes[k]->label.assign(currentLabel.begin(), currentLabel.end());
+
+ bool remainder = true;
+
+ unsigned int pos = 0;
+ do {
+ std::stringstream msgBuffer;
+
+ ++currentLabel[pos];
+ if (currentLabel[pos] >= maxLabel[pos]) {
+ currentLabel[pos] = 0;
+ remainder = true;
+ }
+ else {
+ remainder = false;
+ }
+ if (!remainder) {
+ pos = 0;
+ }
+ else {
+ ++pos;
+ }
+ }
+ while(remainder && pos < this->levels);
+ k++;
+ }
+ }
+}
+
+
+int AsClusterFatTree::getLevelPosition(const unsigned int level) {
+ if (level > this->levels) {
+ // Well, that should never happen. Maybe should we throw instead.
+ return -1;
+ }
+ int tempPosition = 0;