gem5  v20.1.0.0
RoutingUnit.cc
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2008 Princeton University
3  * Copyright (c) 2016 Georgia Institute of Technology
4  * All rights reserved.
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions are
8  * met: redistributions of source code must retain the above copyright
9  * notice, this list of conditions and the following disclaimer;
10  * redistributions in binary form must reproduce the above copyright
11  * notice, this list of conditions and the following disclaimer in the
12  * documentation and/or other materials provided with the distribution;
13  * neither the name of the copyright holders nor the names of its
14  * contributors may be used to endorse or promote products derived from
15  * this software without specific prior written permission.
16  *
17  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
18  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
19  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
20  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
21  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
22  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
23  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
25  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
27  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28  */
29 
30 
32 
33 #include "base/cast.hh"
34 #include "debug/RubyNetwork.hh"
38 
40 {
41  m_router = router;
42  m_routing_table.clear();
43  m_weight_table.clear();
44 }
45 
46 void
48 {
49  if (routing_table_entry.size() > m_routing_table.size()) {
50  m_routing_table.resize(routing_table_entry.size());
51  }
52  for (int v = 0; v < routing_table_entry.size(); v++) {
53  m_routing_table[v].push_back(routing_table_entry[v]);
54  }
55 }
56 
57 void
58 RoutingUnit::addWeight(int link_weight)
59 {
60  m_weight_table.push_back(link_weight);
61 }
62 
63 bool
65 {
66  // If all vnets are supported, return true
67  if (sVnets.size() == 0) {
68  return true;
69  }
70 
71  // Find the vnet in the vector, return true
72  if (std::find(sVnets.begin(), sVnets.end(), vnet) != sVnets.end()) {
73  return true;
74  }
75 
76  // Not supported vnet
77  return false;
78 }
79 
80 /*
81  * This is the default routing algorithm in garnet.
82  * The routing table is populated during topology creation.
83  * Routes can be biased via weight assignments in the topology file.
84  * Correct weight assignments are critical to provide deadlock avoidance.
85  */
86 int
87 RoutingUnit::lookupRoutingTable(int vnet, NetDest msg_destination)
88 {
89  // First find all possible output link candidates
90  // For ordered vnet, just choose the first
91  // (to make sure different packets don't choose different routes)
92  // For unordered vnet, randomly choose any of the links
93  // To have a strict ordering between links, they should be given
94  // different weights in the topology file
95 
96  int output_link = -1;
97  int min_weight = INFINITE_;
98  std::vector<int> output_link_candidates;
99  int num_candidates = 0;
100 
101  // Identify the minimum weight among the candidate output links
102  for (int link = 0; link < m_routing_table[vnet].size(); link++) {
103  if (msg_destination.intersectionIsNotEmpty(
104  m_routing_table[vnet][link])) {
105 
106  if (m_weight_table[link] <= min_weight)
107  min_weight = m_weight_table[link];
108  }
109  }
110 
111  // Collect all candidate output links with this minimum weight
112  for (int link = 0; link < m_routing_table[vnet].size(); link++) {
113  if (msg_destination.intersectionIsNotEmpty(
114  m_routing_table[vnet][link])) {
115 
116  if (m_weight_table[link] == min_weight) {
117  num_candidates++;
118  output_link_candidates.push_back(link);
119  }
120  }
121  }
122 
123  if (output_link_candidates.size() == 0) {
124  fatal("Fatal Error:: No Route exists from this Router.");
125  exit(0);
126  }
127 
128  // Randomly select any candidate output link
129  int candidate = 0;
130  if (!(m_router->get_net_ptr())->isVNetOrdered(vnet))
131  candidate = rand() % num_candidates;
132 
133  output_link = output_link_candidates.at(candidate);
134  return output_link;
135 }
136 
137 
138 void
139 RoutingUnit::addInDirection(PortDirection inport_dirn, int inport_idx)
140 {
141  m_inports_dirn2idx[inport_dirn] = inport_idx;
142  m_inports_idx2dirn[inport_idx] = inport_dirn;
143 }
144 
145 void
146 RoutingUnit::addOutDirection(PortDirection outport_dirn, int outport_idx)
147 {
148  m_outports_dirn2idx[outport_dirn] = outport_idx;
149  m_outports_idx2dirn[outport_idx] = outport_dirn;
150 }
151 
152 // outportCompute() is called by the InputUnit
153 // It calls the routing table by default.
154 // A template for adaptive topology-specific routing algorithm
155 // implementations using port directions rather than a static routing
156 // table is provided here.
157 
158 int
160  PortDirection inport_dirn)
161 {
162  int outport = -1;
163 
164  if (route.dest_router == m_router->get_id()) {
165 
166  // Multiple NIs may be connected to this router,
167  // all with output port direction = "Local"
168  // Get exact outport id from table
169  outport = lookupRoutingTable(route.vnet, route.net_dest);
170  return outport;
171  }
172 
173  // Routing Algorithm set in GarnetNetwork.py
174  // Can be over-ridden from command line using --routing-algorithm = 1
175  RoutingAlgorithm routing_algorithm =
177 
178  switch (routing_algorithm) {
179  case TABLE_: outport =
180  lookupRoutingTable(route.vnet, route.net_dest); break;
181  case XY_: outport =
182  outportComputeXY(route, inport, inport_dirn); break;
183  // any custom algorithm
184  case CUSTOM_: outport =
185  outportComputeCustom(route, inport, inport_dirn); break;
186  default: outport =
187  lookupRoutingTable(route.vnet, route.net_dest); break;
188  }
189 
190  assert(outport != -1);
191  return outport;
192 }
193 
194 // XY routing implemented using port directions
195 // Only for reference purpose in a Mesh
196 // By default Garnet uses the routing table
197 int
199  int inport,
200  PortDirection inport_dirn)
201 {
202  PortDirection outport_dirn = "Unknown";
203 
204  int M5_VAR_USED num_rows = m_router->get_net_ptr()->getNumRows();
205  int num_cols = m_router->get_net_ptr()->getNumCols();
206  assert(num_rows > 0 && num_cols > 0);
207 
208  int my_id = m_router->get_id();
209  int my_x = my_id % num_cols;
210  int my_y = my_id / num_cols;
211 
212  int dest_id = route.dest_router;
213  int dest_x = dest_id % num_cols;
214  int dest_y = dest_id / num_cols;
215 
216  int x_hops = abs(dest_x - my_x);
217  int y_hops = abs(dest_y - my_y);
218 
219  bool x_dirn = (dest_x >= my_x);
220  bool y_dirn = (dest_y >= my_y);
221 
222  // already checked that in outportCompute() function
223  assert(!(x_hops == 0 && y_hops == 0));
224 
225  if (x_hops > 0) {
226  if (x_dirn) {
227  assert(inport_dirn == "Local" || inport_dirn == "West");
228  outport_dirn = "East";
229  } else {
230  assert(inport_dirn == "Local" || inport_dirn == "East");
231  outport_dirn = "West";
232  }
233  } else if (y_hops > 0) {
234  if (y_dirn) {
235  // "Local" or "South" or "West" or "East"
236  assert(inport_dirn != "North");
237  outport_dirn = "North";
238  } else {
239  // "Local" or "North" or "West" or "East"
240  assert(inport_dirn != "South");
241  outport_dirn = "South";
242  }
243  } else {
244  // x_hops == 0 and y_hops == 0
245  // this is not possible
246  // already checked that in outportCompute() function
247  panic("x_hops == y_hops == 0");
248  }
249 
250  return m_outports_dirn2idx[outport_dirn];
251 }
252 
253 // Template for implementing custom routing algorithm
254 // using port directions. (Example adaptive)
255 int
257  int inport,
258  PortDirection inport_dirn)
259 {
260  panic("%s placeholder executed", __FUNCTION__);
261 }
fatal
#define fatal(...)
This implements a cprintf based fatal() function.
Definition: logging.hh:183
Router::get_id
int get_id()
Definition: Router.hh:81
RoutingUnit::m_inports_idx2dirn
std::map< int, PortDirection > m_inports_idx2dirn
Definition: RoutingUnit.hh:86
RouteInfo
Definition: CommonTypes.hh:47
X86ISA::exit
Bitfield< 3 > exit
Definition: misc.hh:848
RoutingUnit::addRoute
void addRoute(std::vector< NetDest > &routing_table_entry)
Definition: RoutingUnit.cc:47
InputUnit.hh
TABLE_
@ TABLE_
Definition: CommonTypes.hh:44
RoutingUnit::outportComputeXY
int outportComputeXY(RouteInfo route, int inport, PortDirection inport_dirn)
Definition: RoutingUnit.cc:198
cast.hh
std::vector< NetDest >
XY_
@ XY_
Definition: CommonTypes.hh:44
RoutingUnit::supportsVnet
bool supportsVnet(int vnet, std::vector< int > sVnets)
Definition: RoutingUnit.cc:64
RoutingUnit::addWeight
void addWeight(int link_weight)
Definition: RoutingUnit.cc:58
RoutingUnit::m_routing_table
std::vector< std::vector< NetDest > > m_routing_table
Definition: RoutingUnit.hh:81
RoutingUnit::m_outports_idx2dirn
std::map< int, PortDirection > m_outports_idx2dirn
Definition: RoutingUnit.hh:87
RoutingUnit::m_inports_dirn2idx
std::map< PortDirection, int > m_inports_dirn2idx
Definition: RoutingUnit.hh:85
Router
Definition: Router.hh:56
CUSTOM_
@ CUSTOM_
Definition: CommonTypes.hh:44
RoutingAlgorithm
RoutingAlgorithm
Definition: CommonTypes.hh:44
RoutingUnit::addInDirection
void addInDirection(PortDirection inport_dirn, int inport)
Definition: RoutingUnit.cc:139
RoutingUnit::outportComputeCustom
int outportComputeCustom(RouteInfo route, int inport, PortDirection inport_dirn)
Definition: RoutingUnit.cc:256
GarnetNetwork::getRoutingAlgorithm
int getRoutingAlgorithm() const
Definition: GarnetNetwork.hh:71
RoutingUnit::lookupRoutingTable
int lookupRoutingTable(int vnet, NetDest net_dest)
Definition: RoutingUnit.cc:87
RouteInfo::net_dest
NetDest net_dest
Definition: CommonTypes.hh:56
RoutingUnit::RoutingUnit
RoutingUnit(Router *router)
Definition: RoutingUnit.cc:39
RouteInfo::dest_router
int dest_router
Definition: CommonTypes.hh:62
PortDirection
std::string PortDirection
Definition: Topology.hh:62
NetDest::intersectionIsNotEmpty
bool intersectionIsNotEmpty(const NetDest &other_netDest) const
Definition: NetDest.cc:216
RoutingUnit::m_weight_table
std::vector< int > m_weight_table
Definition: RoutingUnit.hh:82
RoutingUnit::addOutDirection
void addOutDirection(PortDirection outport_dirn, int outport)
Definition: RoutingUnit.cc:146
RoutingUnit::outportCompute
int outportCompute(RouteInfo route, int inport, PortDirection inport_dirn)
Definition: RoutingUnit.cc:159
Router::get_net_ptr
GarnetNetwork * get_net_ptr()
Definition: Router.hh:88
RouteInfo::vnet
int vnet
Definition: CommonTypes.hh:55
Message.hh
NetDest
Definition: NetDest.hh:39
ArmISA::v
Bitfield< 28 > v
Definition: miscregs_types.hh:51
RoutingUnit.hh
GarnetNetwork::getNumCols
int getNumCols()
Definition: GarnetNetwork.hh:65
INFINITE_
#define INFINITE_
Definition: CommonTypes.hh:66
panic
#define panic(...)
This implements a cprintf based panic() function.
Definition: logging.hh:171
RoutingUnit::m_outports_dirn2idx
std::map< PortDirection, int > m_outports_dirn2idx
Definition: RoutingUnit.hh:88
GarnetNetwork::getNumRows
int getNumRows() const
Definition: GarnetNetwork.hh:64
Router.hh
RoutingUnit::m_router
Router * m_router
Definition: RoutingUnit.hh:78

Generated on Wed Sep 30 2020 14:02:13 for gem5 by doxygen 1.8.17