Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
Enhanced print_topology function.
[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
13 // 
14 //  GTNETS_Node
15 // 
16
17 // Constructor
18 GTNETS_Node::GTNETS_Node(int id):ID_(id),is_router_(false){}
19 // Copy constructor
20 GTNETS_Node::GTNETS_Node(const GTNETS_Node& node){
21   ID_ = node.ID_;
22   is_router_ = node.is_router_;
23   hosts_ = node.hosts_;
24 }
25
26 GTNETS_Node::~GTNETS_Node(){
27
28 }
29
30 // hostid = network_card_id
31 int GTNETS_Node::add_host(int hostid){
32   if (is_router_){
33     fprintf(stderr, "Cannot add a host to a router node.\n");
34     return -1;
35   }
36   hosts_.insert(hostid);
37   return 0;
38 }
39
40 // Add a router. If this node already has a router/host,
41 // return -1.
42 int GTNETS_Node::add_router(int routerid){
43   if (hosts_.size() > 1){
44     fprintf(stderr, "Router node should have only one router.\n");
45     return -1;
46   }else if (hosts_.size() == 1){
47     if (hosts_.find(routerid) != hosts_.end()){
48       //printf("the router already exists\n");
49       return 0;
50     }else{
51       fprintf(stderr, "Node %d is a different router.\n");
52       return -1;
53     }
54   }
55   is_router_ = true;
56   hosts_.insert(routerid);
57   return 0;
58 }
59
60 bool GTNETS_Node::is_router(){
61   return is_router_;
62 }
63
64 bool GTNETS_Node::include(int hostid){
65   if (hosts_.find(hostid) == hosts_.end()) return false;
66   else return true;
67 }
68
69 void GTNETS_Node::print_hosts(){
70   set<int>::iterator it;
71   printf("[");
72   for (it = hosts_.begin(); it != hosts_.end(); it++){
73     printf(" %d", *it);
74   }
75   printf("]");
76 }
77
78 //
79 //  GTNETS_Link
80 //
81
82 // Constructor
83 GTNETS_Link::GTNETS_Link(){
84   ID_=-1;
85   src_node_ = 0;
86   dst_node_ = 0;
87 }
88 GTNETS_Link::GTNETS_Link(int id):ID_(id), src_node_(0), dst_node_(0){}
89
90 // Copy constructor
91 GTNETS_Link::GTNETS_Link(const GTNETS_Link& link){
92   ID_ = link.ID_;
93   src_node_ = link.src_node_;
94   dst_node_ = link.dst_node_;
95 }
96
97 GTNETS_Link::~GTNETS_Link(){
98   
99 }
100
101 void GTNETS_Link::print_link_status(){
102   printf("== LINKID: %d\n", ID_);
103   if (src_node_){
104     printf("  [SRC] ID: %d, router?: %d, hosts[]: ",
105            src_node_->id(), src_node_->is_router());
106     src_node_->print_hosts();
107     printf("\n");
108   }
109
110   if (dst_node_){
111     printf("  [DST] ID: %d, router?: %d, hosts[]: ", 
112            dst_node_->id(), dst_node_->is_router());
113     dst_node_->print_hosts();
114     printf("\n");
115   }
116 }
117
118 GTNETS_Node* GTNETS_Link::src_node(){
119   return src_node_;
120 }
121
122 GTNETS_Node* GTNETS_Link::dst_node(){
123   return dst_node_;
124 }
125
126 bool GTNETS_Link::route_exists(){
127   if (src_node_ && dst_node_) return true;
128   else return false;
129 }
130
131 // return the peer node id
132 int GTNETS_Link::peer_node(int cur_id){
133   if (cur_id ==  src_node_->id()) return dst_node_->id();
134   else if (cur_id == dst_node_->id()) return src_node_->id();
135   else {
136     fprintf(stderr, "node not found\n");
137     return -1;
138   }
139 }
140
141 int GTNETS_Link::add_src(GTNETS_Node* src){
142   src_node_ = src;
143 }
144
145 int GTNETS_Link::add_dst(GTNETS_Node* dst){
146   dst_node_ = dst;
147 }
148
149
150 //
151 //  GTNETS_Topology
152 //
153
154 // Constructor
155 GTNETS_Topology::GTNETS_Topology(){
156   nodeID_ = 0;
157 }
158
159 // Destructor
160 GTNETS_Topology::~GTNETS_Topology(){
161   map<int, GTNETS_Link*>::iterator it1;
162   for (it1 = links_.begin(); it1 != links_.end(); it1++){
163     delete it1->second;
164   }
165   vector<GTNETS_Node*>::iterator it2;
166   for (it2 = nodes_.begin(); it2 != nodes_.end(); it2++){
167     delete *it2;
168   }
169 }
170
171
172 int GTNETS_Topology::link_size(){
173   return links_.size();
174 }
175
176 int GTNETS_Topology::node_size(){
177   return nodes_.size();
178 }
179
180 int GTNETS_Topology::add_link(int id){
181   map<int,GTNETS_Link*>::iterator iter = links_.find(id);
182
183   if(iter == links_.end()) {
184     GTNETS_Link* link= new GTNETS_Link(id);
185     //printf("link %d is added: %d\n", id, link->id());
186     //links_.insert(make_pair(id, link));
187     links_[id] = link;
188     return 0;
189   }else{
190     fprintf(stderr, "Link %d already exists.\n", id);
191     return -1;
192   }
193 }
194
195 int GTNETS_Topology::add_router(int id){
196   set<int>::iterator iter = routers_.find(id);
197
198   if(iter == routers_.end()) {
199     //printf("router %d is inserted\n", id);
200     routers_.insert(id);
201     return 0;
202   }else{
203     fprintf(stderr, "Router %d already exists.\n", id);
204     return -1;
205   }
206 }
207
208 bool GTNETS_Topology::is_router(int id){
209   set<int>::iterator iter = routers_.find(id);
210   if(iter == routers_.end()) return false;
211   else return true;
212 }
213
214 //return the node id of the peer of cur_id by linkid.
215 int GTNETS_Topology::peer_node_id(int linkid, int cur_id){
216   //printf("linkid: %d, cur_id: %d\n", linkid, cur_id);
217   GTNETS_Link* link = links_[linkid];
218   if (!link) {
219     fprintf(stderr, "link %d not found\n", linkid);
220     return -1;
221   }
222   if ((cur_id < 0) || (cur_id > nodes_.size()-1)){
223     fprintf(stderr, "node %d not found\n", cur_id);
224     return -1;
225   }
226   int peer  = link->peer_node(nodes_[cur_id]->id());
227   if (peer < 0){
228     fprintf(stderr, "peer not found\n");
229     return -1;
230   }
231   return peer;
232 }
233
234 int GTNETS_Topology::add_onehop_route(int src, int dst, int linkid){
235   GTNETS_Link* link;
236
237   map<int, GTNETS_Link*>::iterator iter = links_.find(linkid);
238
239   if(iter == links_.end()) {
240     fprintf(stderr, "Link %d not found.\n", linkid);
241     return -1;
242   }else{
243     link = iter->second;
244   }
245
246   //  printf("add_onehop_route: src: %d, dst: %d, linkid: %d, %d\n",
247   //     src, dst, linkid, link->id());
248
249   GTNETS_Node *src_node, *dst_node;
250   src_node = link->src_node();
251   dst_node = link->dst_node();
252
253
254   // If not exists a route, add one.
255   if (!link->route_exists()){
256     //check whether there exists a node for the src host/router.
257     int s_node_id = nodeid_from_hostid(src);
258     int node_id;
259
260     if (s_node_id < 0){//not exist, create one.
261       s_node_id = nodeID_;
262       GTNETS_Node* node1 = new GTNETS_Node(s_node_id);
263       nodes_.push_back(node1);
264       hosts_[src] = nodes_[s_node_id]->id();
265
266       nodeID_++;
267     }
268
269     if (is_router(src))
270       nodes_[s_node_id]->add_router(src);
271     else
272       nodes_[s_node_id]->add_host(src);
273
274     link->add_src(nodes_[s_node_id]);
275
276     //check whether there exists a node for the dst host/router.
277     int d_node_id = nodeid_from_hostid(dst);
278     if (d_node_id < 0){//not exist, create one.
279       d_node_id = nodeID_;
280       GTNETS_Node* node2 = new GTNETS_Node(d_node_id);
281       nodes_.push_back(node2);
282       hosts_[dst] = nodes_[d_node_id]->id();
283       nodeID_++;
284     }
285
286     if (is_router(dst))
287       nodes_[d_node_id]->add_router(dst);
288     else
289       nodes_[d_node_id]->add_host(dst);
290
291     link->add_dst(nodes_[d_node_id]);
292
293   // other: has either src or dst (error)
294   }else if (!src_node || !dst_node){
295     fprintf(stderr, "Either src or dst is null\n");
296     return -1;
297   }
298
299   // case 1: link has two routers
300   else if (src_node->is_router() && dst_node->is_router()){
301     int tmpsrc1 = src_node->id();
302     int tmpsrc2 = nodeid_from_hostid(src);
303     int tmpdst1 = dst_node->id();
304     int tmpdst2 = nodeid_from_hostid(dst);
305     if (((tmpsrc1 == tmpsrc2) && (tmpdst1 == tmpdst2)) ||
306         ((tmpsrc1 == tmpdst2) && (tmpdst1 == tmpsrc2))){
307       fprintf(stderr, "Route already exists\n");
308     }else{
309       fprintf(stderr, "Different one hop route defined\n");
310       return -1;
311     }
312   }
313   // case 2: link has one router and one host
314   else if (src_node->is_router() && !dst_node->is_router()){
315     int newsrc, newdst;
316     if (is_router(src)){
317       newsrc = src;
318       newdst = dst;
319     }else if (is_router(dst)){
320       newsrc = dst;
321       newdst = src;
322     }else{
323       fprintf(stderr, "one of nodes should be a router\n");
324       return -1;
325     }
326
327     if (src_node->id() != nodeid_from_hostid(newsrc)){
328       fprintf(stderr, "The router should be identical\n");
329       return -1;
330     }
331
332     //now, to add dst to dst_node, dst should be a host.
333
334     if (is_router(newdst)){
335       fprintf(stderr, "dst %d is not an endpoint. cannot add it to dst_node\n");
336       return -1;
337     }
338
339     if (!dst_node->include(newdst)){
340       dst_node->add_host(newdst);
341       hosts_[newdst] = dst_node->id();
342     }
343   }
344   else if (!src_node->is_router() && dst_node->is_router()){
345     int newsrc, newdst;
346     if (is_router(src)){
347       newsrc = dst;
348       newdst = src;
349     }else if (is_router(dst)){
350       newsrc = src;
351       newdst = dst;
352     }else{
353       fprintf(stderr, "one of nodes should be a router\n");
354       return -1;
355     }
356
357
358     if (dst_node->id() != hosts_[newdst]){
359       fprintf(stderr, "The router should be identical\n");
360       return -1;
361     }
362
363     //now, to add dst to src_node, dst should be a host.
364
365     if (is_router(newsrc)){
366       fprintf(stderr, "dst %d is not an endpoint. cannot add it to src_node\n");
367       return -1;
368     }
369
370     if (!src_node->include(newsrc)){
371       src_node->add_host(newsrc);
372       hosts_[newsrc] = src_node->id();
373     }
374   }
375
376   // case 3: link has two hosts
377   else if (!src_node->is_router() && !dst_node->is_router()){
378
379     if (is_router(src) || is_router(dst)){
380       fprintf(stderr, "Cannot add a router to host-host link\n");
381       return -1;
382     }
383
384     //if both are hosts, the order doesn't matter.
385     if (src_node->include(src)){
386       if (dst_node->include(dst)){
387         //nothing
388       }else{
389         dst_node->add_host(dst);
390         hosts_[dst] = dst_node->id();
391       }
392     }else if (src_node->include(dst)){
393       if (dst_node->include(src)){
394         //nothing
395       }else{
396         dst_node->add_host(src);
397         hosts_[src] = dst_node->id();
398       }
399     }else if (dst_node->include(src)){
400       if (src_node->include(dst)){
401         //nothing
402       }else{
403         src_node->add_host(dst);
404         hosts_[dst] = src_node->id();
405       }
406     }else if (dst_node->include(dst)){
407       if (src_node->include(src)){
408         //nothing
409       }else{
410         src_node->add_host(src);
411         hosts_[src] = src_node->id();
412       }
413     }else{
414       src_node->add_host(src);
415       dst_node->add_host(dst);
416       hosts_[src] = src_node->id();
417       hosts_[dst] = dst_node->id();
418     }   
419       
420   }
421   else{
422     fprintf(stderr, "Shouldn't be here\n");
423     return -1;
424   }
425   return 0;
426 }
427
428 int GTNETS_Topology::nodeid_from_hostid(int hostid){
429   map<int,int>::iterator it = hosts_.find(hostid);
430   if (it == hosts_.end())
431     return -1;
432   else return it->second;
433 }
434
435 void GTNETS_Topology::print_topology(){
436   printf("<<<<<================================>>>>>\n");
437   printf("Dumping GTNETS topollogy information\n");
438   map<int, GTNETS_Link*>::iterator it;
439   for (it = links_.begin(); it != links_.end(); it++){
440     it->second->print_link_status();
441   }
442   printf(">>>>>================================<<<<<\n");
443   fflush(NULL);
444 }
445
446 const vector<GTNETS_Node*>& GTNETS_Topology::nodes(){
447   return nodes_;
448 }
449
450 const map<int, GTNETS_Link*>& GTNETS_Topology::links(){
451   return links_;
452 }
453