Logo AND Algorithmique Numérique Distribuée

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