+ 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);
+ 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;
+
+ for (unsigned int i = 0 ; i < level ; i++) {
+ tempPosition += this->nodesByLevel[i];
+ }
+ return tempPosition;
+}
+
+void AsClusterFatTree::addProcessingNode(int id) {
+ using std::make_pair;
+ static int position = 0;
+ FatTreeNode* newNode;
+ newNode = new FatTreeNode(this->cluster, id, 0, position++);
+ newNode->parents.resize(this->upperLevelNodesNumber[0] *
+ this->lowerLevelPortsNumber[0]);
+ newNode->label.resize(this->levels);
+ this->computeNodes.insert(make_pair(id,newNode));
+ this->nodes.push_back(newNode);
+}
+
+void AsClusterFatTree::addLink(FatTreeNode *parent, unsigned int parentPort,
+ FatTreeNode *child, unsigned int childPort) {
+ FatTreeLink *newLink;
+ newLink = new FatTreeLink(this->cluster, child, parent);
+ XBT_DEBUG("Creating a link between the parent (%d,%d,%u)"
+ " and the child (%d,%d,%u)", parent->level, parent->position,
+ parentPort, child->level, child->position, childPort);
+ parent->children[parentPort] = newLink;
+ child->parents[childPort] = newLink;
+
+ this->links.push_back(newLink);
+
+
+
+}