Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
Improve the generic routing for different network models, including GTNetS.
[simgrid.git] / src / surf / gtnets / gtnets_topology.cc
1 /* $ID$ */
2
3 /* Copyright (c) 2007 Kayo Fujiwara. All rights reserved.                  */
4
5 /* This program is free software; you can redistribute it and/or modify it
6  * under the terms of the license (GNU LGPL) which comes with this package. */
7
8 //GTNETS_Link, GTNETS_Node, GTNETS_Topology: 
9 //Temporary classes for generating GTNetS topology
10
11 #include "gtnets_topology.h"
12 #ifdef DEBUG0
13         #undef DEBUG0
14 #endif
15 #include "xbt/log.h"
16 #include "xbt/asserts.h"
17
18 XBT_LOG_NEW_DEFAULT_SUBCATEGORY(surf_network_gtnets_topology, surf_network_gtnets,
19                                 "Logging specific to the SURF network GTNetS simulator");
20
21 // 
22 //  GTNETS_Node
23 // 
24
25 // Constructor
26 GTNETS_Node::GTNETS_Node(int id):ID_(id),is_router_(false){}
27 // Copy constructor
28 GTNETS_Node::GTNETS_Node(const GTNETS_Node& node){
29   ID_ = node.ID_;
30   is_router_ = node.is_router_;
31   hosts_ = node.hosts_;
32 }
33
34 GTNETS_Node::~GTNETS_Node(){
35
36 }
37
38 // hostid = network_card_id
39 int GTNETS_Node::add_host(int hostid){
40   xbt_assert0(!(is_router_), "Cannot add a host to a router node");
41   hosts_.insert(hostid);
42   return 0;
43 }
44
45 // Add a router. If this node already has a router/host,
46 // return -1.
47 int GTNETS_Node::add_router(int routerid){
48   xbt_assert0(!(hosts_.size() > 1), "Router node should have only one router");
49   if (hosts_.size() == 1){
50           xbt_assert1((hosts_.find(routerid) != hosts_.end()), "Node %d is a different router", routerid);
51           return 0;
52   }
53   is_router_ = true;
54   hosts_.insert(routerid);
55   return 0;
56 }
57
58 bool GTNETS_Node::is_router(){
59   return is_router_;
60 }
61
62 bool GTNETS_Node::include(int hostid){
63   if (hosts_.find(hostid) == hosts_.end()) return false;
64   else return true;
65 }
66
67 void GTNETS_Node::print_hosts(){
68   set<int>::iterator it;
69   for (it = hosts_.begin(); it != hosts_.end(); it++){
70     DEBUG1("host id %d", *it);
71   }
72 }
73
74 //
75 //  GTNETS_Link
76 //
77
78 // Constructor
79 GTNETS_Link::GTNETS_Link(){
80   ID_=-1;
81   src_node_ = 0;
82   dst_node_ = 0;
83 }
84 GTNETS_Link::GTNETS_Link(int id):ID_(id), src_node_(0), dst_node_(0){}
85
86 // Copy constructor
87 GTNETS_Link::GTNETS_Link(const GTNETS_Link& link){
88   ID_ = link.ID_;
89   src_node_ = link.src_node_;
90   dst_node_ = link.dst_node_;
91 }
92
93 GTNETS_Link::~GTNETS_Link(){
94   
95 }
96
97 void GTNETS_Link::print_link_status(){
98   DEBUG1("link id: %d", ID_);
99   if (src_node_){
100     DEBUG2("[src] id: %d, is it router?: %d, host list: ",src_node_->id(), src_node_->is_router());
101     src_node_->print_hosts();
102   }
103
104   if (dst_node_){
105     DEBUG2("[dst] id: %d, is it router?: %d, host list: ",dst_node_->id(), dst_node_->is_router());
106     dst_node_->print_hosts();
107   }
108 }
109
110 GTNETS_Node* GTNETS_Link::src_node(){
111   return src_node_;
112 }
113
114 GTNETS_Node* GTNETS_Link::dst_node(){
115   return dst_node_;
116 }
117
118 bool GTNETS_Link::route_exists(){
119   if (src_node_ && dst_node_) return true;
120   else return false;
121 }
122
123 // return the peer node id
124 int GTNETS_Link::peer_node(int cur_id){
125   xbt_assert0(((cur_id ==  src_node_->id())||(cur_id == dst_node_->id())), "Node not found");
126
127   if (cur_id ==  src_node_->id()) return dst_node_->id();
128   else if (cur_id == dst_node_->id()) return src_node_->id();
129 }
130
131 int GTNETS_Link::add_src(GTNETS_Node* src){
132   src_node_ = src;
133 }
134
135 int GTNETS_Link::add_dst(GTNETS_Node* dst){
136   dst_node_ = dst;
137 }
138
139
140 //
141 //  GTNETS_Topology
142 //
143
144 // Constructor
145 GTNETS_Topology::GTNETS_Topology(){
146   nodeID_ = 0;
147 }
148
149 // Destructor
150 GTNETS_Topology::~GTNETS_Topology(){
151   map<int, GTNETS_Link*>::iterator it1;
152   for (it1 = links_.begin(); it1 != links_.end(); it1++){
153     delete it1->second;
154   }
155   vector<GTNETS_Node*>::iterator it2;
156   for (it2 = nodes_.begin(); it2 != nodes_.end(); it2++){
157     delete *it2;
158   }
159 }
160
161
162 int GTNETS_Topology::link_size(){
163   return links_.size();
164 }
165
166 int GTNETS_Topology::node_size(){
167   return nodes_.size();
168 }
169
170 int GTNETS_Topology::add_link(int id){
171   map<int,GTNETS_Link*>::iterator iter = links_.find(id);
172   xbt_assert1((iter == links_.end()), "Link %d already exists", id);
173
174   if(iter == links_.end()) {
175     GTNETS_Link* link= new GTNETS_Link(id);
176     links_[id] = link;
177   }
178   return 0;
179 }
180
181 int GTNETS_Topology::add_router(int id){
182   set<int>::iterator iter = routers_.find(id);
183   xbt_assert1((iter == routers_.end()), "Router %d already exists", id);
184   routers_.insert(id);
185   return 0;
186 }
187
188 bool GTNETS_Topology::is_router(int id){
189   set<int>::iterator iter = routers_.find(id);
190   if(iter == routers_.end()) return false;
191   else return true;
192 }
193
194 //return the node id of the peer of cur_id by linkid.
195 int GTNETS_Topology::peer_node_id(int linkid, int cur_id){
196   GTNETS_Link* link = links_[linkid];
197   xbt_assert1((link), "Link %d not found", linkid);
198   xbt_assert1(!((cur_id < 0) || (cur_id > nodes_.size()-1)), "Node %d not found", cur_id);
199
200   int peer  = link->peer_node(nodes_[cur_id]->id());
201   xbt_assert0(!(peer < 0), "Peer not found");
202
203   return peer;
204 }
205
206 int GTNETS_Topology::add_onehop_route(int src, int dst, int linkid){
207   GTNETS_Link* link;
208
209   map<int, GTNETS_Link*>::iterator iter = links_.find(linkid);
210
211   xbt_assert1(!(iter == links_.end()), "Link %d not found", linkid);
212   link = iter->second;
213
214   DEBUG4("Add onehop route, src: %d, dst: %d, linkid: %d, %d",src, dst, linkid, link->id());
215
216   GTNETS_Node *src_node, *dst_node;
217   src_node = link->src_node();
218   dst_node = link->dst_node();
219
220   if (XBT_LOG_ISENABLED(surf_network_gtnets_topology, xbt_log_priority_debug)) {
221     link->print_link_status();
222     src_node->print_hosts();
223     dst_node->print_hosts();
224   }
225
226
227   // If not exists a route, add one.
228   if (!link->route_exists()){
229     //check whether there exists a node for the src host/router.
230     int s_node_id = nodeid_from_hostid(src);
231     int node_id;
232
233     if (s_node_id < 0){//not exist, create one.
234       s_node_id = nodeID_;
235       GTNETS_Node* node1 = new GTNETS_Node(s_node_id);
236       nodes_.push_back(node1);
237       hosts_[src] = nodes_[s_node_id]->id();
238
239       nodeID_++;
240     }
241
242     if (is_router(src))
243       nodes_[s_node_id]->add_router(src);
244     else
245       nodes_[s_node_id]->add_host(src);
246
247     link->add_src(nodes_[s_node_id]);
248
249     //check whether there exists a node for the dst host/router.
250     int d_node_id = nodeid_from_hostid(dst);
251     if (d_node_id < 0){//not exist, create one.
252       d_node_id = nodeID_;
253       GTNETS_Node* node2 = new GTNETS_Node(d_node_id);
254       nodes_.push_back(node2);
255       hosts_[dst] = nodes_[d_node_id]->id();
256       nodeID_++;
257     }
258
259     if (is_router(dst))
260       nodes_[d_node_id]->add_router(dst);
261     else
262       nodes_[d_node_id]->add_host(dst);
263
264     link->add_dst(nodes_[d_node_id]);
265   }else if (src_node && dst_node){
266       xbt_assert0((src_node && dst_node), "Either src or dst is null");
267   }
268
269   // case 1: link has two routers
270   else if (src_node->is_router() && dst_node->is_router()){
271     int tmpsrc1 = src_node->id();
272     int tmpsrc2 = nodeid_from_hostid(src);
273     int tmpdst1 = dst_node->id();
274     int tmpdst2 = nodeid_from_hostid(dst);
275     xbt_assert0( (((tmpsrc1 == tmpsrc2) && (tmpdst1 == tmpdst2)) ||
276         ((tmpsrc1 == tmpdst2) && (tmpdst1 == tmpsrc2))), "Different one hop route defined");
277   }
278
279   // case 2: link has one router and one host
280   else if (src_node->is_router() && !dst_node->is_router()){
281     int newsrc, newdst;
282     xbt_assert0( ((is_router(src))||(is_router(dst))), "One of nodes should be a router");
283
284     if (is_router(src)){
285       newsrc = src;
286       newdst = dst;
287     }else if (is_router(dst)){
288       newsrc = dst;
289       newdst = src;
290     }
291
292     xbt_assert0(!(src_node->id() != nodeid_from_hostid(newsrc)), "The router should be identical");
293
294     //now, to add dst to dst_node, dst should be a host.
295     xbt_assert1(!(is_router(newdst)), "Dst %d is not an endpoint. cannot add it to dst_node", newdst);
296
297     if (!dst_node->include(newdst)){
298       dst_node->add_host(newdst);
299       hosts_[newdst] = dst_node->id();
300     }
301   }
302   else if (!src_node->is_router() && dst_node->is_router()){
303     int newsrc, newdst;
304     xbt_assert0(((is_router(src))||(is_router(dst))), "One of nodes should be a router");
305
306     if (is_router(src)){
307       newsrc = dst;
308       newdst = src;
309     }else if (is_router(dst)){
310       newsrc = src;
311       newdst = dst;
312     }
313
314     xbt_assert0(!(dst_node->id() != hosts_[newdst]), "The router should be identical");
315     //now, to add dst to src_node, dst should be a host.
316     xbt_assert1(!(is_router(newsrc)), "Src %d is not an endpoint. cannot add it to src_node", newsrc);
317
318     if (!src_node->include(newsrc)){
319       src_node->add_host(newsrc);
320       hosts_[newsrc] = src_node->id();
321     }
322   }
323
324   // case 3: link has two hosts
325   else if (!src_node->is_router() && !dst_node->is_router()){
326         xbt_assert0(!(is_router(src) || is_router(dst)), "Cannot add a router to host-host link");
327
328     //if both are hosts, the order doesn't matter.
329     if (src_node->include(src)){
330       if (dst_node->include(dst)){
331             //nothing
332       }else{
333             dst_node->add_host(dst);
334             hosts_[dst] = dst_node->id();
335       }
336     }else if (src_node->include(dst)){
337       if (dst_node->include(src)){
338             //nothing
339       }else{
340             dst_node->add_host(src);
341             hosts_[src] = dst_node->id();
342       }
343     }else if (dst_node->include(src)){
344       if (src_node->include(dst)){
345             //nothing
346       }else{
347             src_node->add_host(dst);
348             hosts_[dst] = src_node->id();
349       }
350     }else if (dst_node->include(dst)){
351       if (src_node->include(src)){
352             //nothing
353       }else{
354             src_node->add_host(src);
355             hosts_[src] = src_node->id();
356       }
357     }else{
358       src_node->add_host(src);
359       dst_node->add_host(dst);
360       hosts_[src] = src_node->id();
361       hosts_[dst] = dst_node->id();
362     }   
363       
364   }
365   else{
366     xbt_assert0(0, "Shouldn't be here");
367   }
368   return 0;
369 }
370
371 int GTNETS_Topology::nodeid_from_hostid(int hostid){
372   map<int,int>::iterator it = hosts_.find(hostid);
373   if (it == hosts_.end())
374     return -1;
375   else return it->second;
376 }
377
378 void GTNETS_Topology::print_topology(){
379   DEBUG0("<<<<<================================>>>>>");
380   DEBUG0("Dumping GTNETS topollogy information");
381   map<int, GTNETS_Link*>::iterator it;
382   for (it = links_.begin(); it != links_.end(); it++){
383     it->second->print_link_status();
384   }
385   DEBUG0(">>>>>================================<<<<<");
386   fflush(NULL);
387 }
388
389 const vector<GTNETS_Node*>& GTNETS_Topology::nodes(){
390   return nodes_;
391 }
392
393 const map<int, GTNETS_Link*>& GTNETS_Topology::links(){
394   return links_;
395 }
396