Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
f852c3682bcd06b1772312fcfd795c9b3d08e60b
[simgrid.git] / src / surf / surf_routing_cluster_fat_tree.cpp
1 #include "surf_routing_cluster_fat_tree.hpp"
2
3 #include <boost/algorithm/string/split.hpp>
4 #include <boost/algorithm/string/classification.hpp>
5
6 #include <iostream>
7 #include <fstream>
8
9
10 AsClusterFatTree::AsClusterFatTree() : levels(0) {}
11
12 AsClusterFatTree::~AsClusterFatTree() {
13   for (int i = 0 ; i < this->nodes.size() ; i++) {
14     delete this->nodes[i];
15   }
16 }
17
18 void AsClusterFatTree::getRouteAndLatency(RoutingEdgePtr src,
19                                           RoutingEdgePtr dst,
20                                           sg_platf_route_cbarg_t into,
21                                           double *latency) const{
22   // TODO
23 }
24
25 /* This function makes the assumption that parse_specific_arguments() and
26  * addNodes() have already been called
27  */
28 void AsClusterFatTree::create_links(sg_platf_cluster_cbarg_t cluster) {
29
30   if(this->levels == 0) {
31     return;
32   }
33   std::vector<int> nodesByLevel(this->levels); 
34   int nodesRequired = 0;
35
36
37     for (int i = 0 ; i < this->levels ; i++) {
38       int nodesInThisLevel = 1;
39       
40       for (int j = 0 ;  j < i ; j++) {
41         nodesInThisLevel *= this->upperLevelNodesNumber[j];
42       }
43       
44       for (int j = i+1 ; j < this->levels ; j++) {
45         nodesInThisLevel *= this->lowerLevelNodesNumber[j];
46       }
47
48       nodesByLevel[i] = nodesInThisLevel;
49       nodesRequired += nodesInThisLevel;
50     }
51    
52     if(nodesRequired > this->nodes.size()) {
53       surf_parse_error("There is not enough nodes to fit to the described topology. Please check your platform description (We need %d nodes, we only got %lu)", nodesRequired, this->nodes.size());
54       return;
55     }
56
57     // Nodes are totally ordered, by level and then by position, in this->nodes
58     int k = 0;
59     for (int i = 0 ; i < this->levels ; i++) {
60       for (int j = 0 ; j < nodesByLevel[i] ; j++) {
61         this->nodes[k]->level = i;
62         this->nodes[k]->position = j;
63
64         if (i == 0) {
65           
66         }
67         else if (i == this->levels - 1) {
68           
69         }
70         else {
71           
72         }
73       }
74     }
75 }
76
77
78 void AsClusterFatTree::addNodes(std::vector<int> const& id) {
79   for (int i = 0 ; i < id.size() ; i++) {
80     this->nodes.push_back(new FatTreeNode(id[i]));
81   }
82 }
83
84 void AsClusterFatTree::parse_specific_arguments(sg_platf_cluster_cbarg_t 
85                                                 cluster) {
86   std::vector<string> parameters;
87   std::vector<string> tmp;
88   boost::split(parameters, cluster->topo_parameters, boost::is_any_of(";"));
89  
90
91   // TODO : we have to check for zeros and negative numbers, or it might crash
92   if (parameters.size() != 4){
93     surf_parse_error("Fat trees are defined by the levels number and 3 vectors" 
94                      ", see the documentation for more informations");
95     // Well, there's no doc, yet
96   }
97
98   // The first parts of topo_parameters should be the levels number
99   this->levels = std::atoi(tmp[0].c_str()); // stoi() only in C++11...
100
101   // Then, a l-sized vector standing for the childs number by level
102   boost::split(tmp, parameters[1], boost::is_any_of(","));
103   if(tmp.size() != this->levels) {
104     surf_parse_error("Fat trees are defined by the levels number and 3 vectors" 
105                      ", see the documentation for more informations"); 
106   }
107   for(unsigned int i = 0 ; i < tmp.size() ; i++){
108     this->lowerLevelNodesNumber.push_back(std::atoi(tmp[i].c_str())); 
109   }
110   
111   // Then, a l-sized vector standing for the parents number by level
112   boost::split(tmp, parameters[2], boost::is_any_of(","));
113   if(tmp.size() != this->levels) {
114     surf_parse_error("Fat trees are defined by the levels number and 3 vectors" 
115                      ", see the documentation for more informations"); 
116   }
117   for(unsigned int i = 0 ; i < tmp.size() ; i++){
118     this->upperLevelNodesNumber.push_back(std::atoi(tmp[i].c_str())); 
119   }
120   
121   // Finally, a l-sized vector standing for the ports number with the lower level
122   boost::split(tmp, parameters[3], boost::is_any_of(","));
123   if(tmp.size() != this->levels) {
124     surf_parse_error("Fat trees are defined by the levels number and 3 vectors" 
125                      ", see the documentation for more informations"); 
126     
127   }
128   for(unsigned int i = 0 ; i < tmp.size() ; i++){
129     this->lowerLevelPortsNumber.push_back(std::atoi(tmp[i].c_str())); 
130   }
131 }
132
133
134 void AsClusterFatTree::generateDotFile(string filename) {
135   ofstream file;
136   /* Maybe should we get directly a char*, as open takes strings only beginning
137    * with c++11...
138    */
139   file.open(filename.c_str(), ios::out | ios::trunc); 
140   
141   if(file.is_open()) {
142     /* TODO : Iterate through a map takes 10 chars with c++11, 100 with c++98.
143      * All I have to do is write it down...
144      */
145
146     // file << "graph AsClusterFatTree {\n";
147     // for (std::map<std::pair<int,int>, FatTreeLink*>::iterator link = this->links.begin() ; link != this->links.end() ; link++ ) {
148     //   for (int j = 0 ; j < link->ports ; j++) {
149     //   file << this->links[i]->source.id 
150     //        << " -- " this->links[i]->destination.id
151     //        << ";\n";
152     //   }
153     // }
154     // file << "}";
155     // file.close();
156   }
157   else {
158     std::cerr << "Unable to open file " << filename << std::endl;
159     return;
160   }
161 }
162
163 FatTreeNode::FatTreeNode(int id, int level, int position) : id(id),
164                                                             level(level),
165                                                             position(position){}