SST/macro
structured_topology.h
Go to the documentation of this file.
1 /*
2  * This file is part of SST/macroscale:
3  * The macroscale architecture simulator from the SST suite.
4  * Copyright (c) 2009 Sandia Corporation.
5  * This software is distributed under the BSD License.
6  * Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
7  * the U.S. Government retains certain rights in this software.
8  * For more information, see the LICENSE file in the top
9  * SST/macroscale directory.
10  */
11 
12 #ifndef SSTMAC_HARDWARE_NETWORK_SWITCHES_REGULAR_TOPOLOGY_H_INCLUDED
13 #define SSTMAC_HARDWARE_NETWORK_SWITCHES_REGULAR_TOPOLOGY_H_INCLUDED
14 
16 
17 namespace sstmac {
18 namespace hw {
19 
20 /**
21 Encapsulates a topology like torus, fat tree, butterfly which
22 has a regular, well-defined structure. Routing on these topologies
23 is regular enough to be done with simple math computations without
24 resorting to a large routing table. This contrasts with unstructured
25 topologies like #top_from_file where there is no regular structure
26 and routing must be done via lookup table.
27 
28 The major defining characteristic of a structured topology is
29 being able to define a coordinate system. Each switch in the
30 topology has a unique number and that number can be mapped
31 to a unique set of coordinates. A torus has an obvious
32 mapping of index to X,Y,Z coordinates. A butterfly or fat tree
33 also has a well-defined coordinate system, but is slightly less intuitive.
34 @class structured_topology
35 */
37 {
38 
39  public:
40  virtual ~structured_topology() {}
41 
42  /**** BEGIN PURE VIRTUAL INTERFACE *****/
43  /**
44  Structured topologies can be direct (torus) or indirect (fat tree).
45  We therefore need to distinguish the total number of switches and
46  the number of leaf switches - i.e. those directly connected to nodes.
47  For direct topologies, num_switches and num_leaf_switches are the same.
48  For indirect, num_leaf_switches < num_switches.
49  @return The number of leaf switches directly connected to compute nodes
50  */
51  virtual int
52  num_leaf_switches() const = 0;
53 
54  /**
55  * @brief Given a set of connectables, connect them appropriately
56  * @param objects The set of objects to connect
57  * @param cloner If in parallel mode, not all objects may exist.
58  * The factory creates missing objects.
59  * @throws value_error If invalid switchid is passed to cloner
60  */
61  virtual void
62  connect_objects(internal_connectable_map& objects) = 0;
63 
64  virtual void
66  internal_connectable_map& connectables,
68  partition *part,
69  int my_rank,
70  sprockit::sim_parameters *params,
71  connectable* dummy);
72 
73  virtual void
75  end_point_connectable_map& connectables,
77  partition *part,
78  int my_rank,
79  sprockit::sim_parameters *params);
80 
81  virtual void
83  int conc,
84  end_point_connectable_map& connectables,
86  partition *part,
87  int my_rank,
88  sprockit::sim_parameters* params,
89  sprockit::factory_type* interconnect);
90 
91  /**
92  Workhorse function for implementing #minimal_route_to_switch
93  and #minimal_route_to_node.
94  Given source/dest coordinates, find the minimal path.
95  @param current_sw_addr The addr of the current switch
96  @param dest_sw_addr The addr of the destination switch
97  @param path [inout] A complete path descriptor to the destination switch
98  */
99  virtual void
101  const coordinates& src_coords,
102  const coordinates& dest_coords,
103  structured_routable::path& path) const = 0;
104 
105  virtual void
107  const coordinates& src_coords,
108  const coordinates& dest_coords,
109  structured_routable::path& current_path,
110  structured_routable::path_set& paths) const {
111  //by default, most things only have one path
112  paths.resize(1);
113  minimal_route_to_coords(src_coords, dest_coords, paths[0]);
114  }
115 
116  /**
117  The function accepts either source or node coordinates.
118  This gives the minimal distance counting the number of hops between switches.
119  If node coordinates are given, the last coordinate is just ignored.
120  @param src_coords. The source coordinates. This can be either switch or node coordinates.
121  @param dest_coords. The destination coordinates. This can be either switch or node coordinates.
122  @return The number of hops to final destination
123  */
124  virtual int
126  const coordinates& src_coords,
127  const coordinates& dest_coords) const = 0;
128 
129  /**
130  The number of distinct 'dimensions'
131  in the topology. This can correspond directly to standard
132  X,Y,Z dimensions or the the number of levels in a fat tree.
133  The keyword topology_redundant vector should have this many
134  entries.
135  */
136  virtual int
137  ndimensions() const = 0;
138 
139  virtual int
140  diameter() const = 0;
141 
142  virtual switch_id
143  switch_number(const coordinates& coords) const = 0;
144 
145  /**
146  @param dim The dimension you want to move in.
147  You might need to traverse other dimensions FIRST
148  before you make progress on this dimension.
149  @param src The coordinates of the source switch
150  @param dst The coordinates of the dest switch
151  @param path [inout] The path configuration for making progress on dim
152  */
153  virtual void
155  int dim,
156  const coordinates& src,
157  const coordinates& dst,
158  structured_routable::path& path) const = 0;
159  /**** END PURE VIRTUAL INTERFACE *****/
160 
161  virtual void
162  init_factory_params(sprockit::sim_parameters* params);
163 
164  /**
165  * Given a switch address, return number of nodes connected to it
166  */
167  virtual int
169  return endpoints_per_switch_;
170  }
171 
172  virtual int
173  num_nodes() const {
174  return endpoints_per_switch_ * num_leaf_switches() * num_nodes_per_netlink_;
175  }
176 
177  virtual int
178  num_endpoints() const {
179  return endpoints_per_switch_ * num_leaf_switches();
180  }
181 
182  /**
183  Compute coordinates (e.g. X,Y,Z for 3D torus)
184  @param swid The unique index defining a switch location
185  @return The unique coordinates of the switch
186  */
188  switch_coords(switch_id swid) const;
189 
190  /**
191  Compute coordinates (e.g. X,Y,Z for 3D torus).
192  In many cases, this will just be the switch coordinates
193  if #nps_ = 1, one node per switch. If there are multiple
194  nodes per switch, this will usually be the coordinates of
195  the connected injection switch PLUS an extra index
196  describing if it is the 0th, 1st, 2nd node
197  on that switch.
198  e.g. nps = 1, inj_sw = <0,2,1>, node = <0,2,1>
199  e.g. nps = 3, inj_sw = <0,2,1>, node = <0,2,1,1>
200  @param nid The unique index defining a node location
201  @return The unique coordinates of the node
202  */
203  virtual coordinates
204  node_coords(node_id nid) const;
205 
207  endpoint_coords(node_id nid) const;
208 
209  virtual switch_id
210  endpoint_to_ejection_switch(node_id nodeaddr, int& switch_port) const;
211 
212  virtual switch_id
213  endpoint_to_injection_switch(node_id nodeaddr, int& switch_port) const;
214 
215  virtual int
217 
218  virtual int
220 
221  virtual int
223  return nid % endpoints_per_switch_;
224  }
225 
226  void
227  finalize_init();
228 
229  virtual void
232  const coordinates &current,
233  const coordinates &dst);
234 
235  std::string
236  label(node_id nid) const;
237 
238  std::string
239  label(switch_id sid) const;
240 
241  /**
242  Implementation of topology::minimal_route_to_switch.
243  For structured topologies, this basically just computes
244  the coordinates of source, dest switch and calls
245  #minimal_route_to_coords.
246  @param current_sw_addr The addr of the current switch
247  @param dest_sw_addr The addr of the destination switch
248  @param path [inout] A complete path descriptor to the destination switch
249  */
250  virtual void
252  switch_id current_sw_addr,
253  switch_id dest_sw_addr,
255  ) const;
256 
257  virtual void
259  switch_id current_sw_addr,
260  switch_id dest_sw_addr,
261  structured_routable::path& current_path,
262  structured_routable::path_set& paths) const {
263  paths.resize(1);
264  minimal_route_to_switch(current_sw_addr, dest_sw_addr, paths[0]);
265  }
266 
267  virtual void
269  node_id dest_addr,
270  switch_id sw_addr,
271  structured_routable::path_set& paths) const;
272 
273  virtual int
274  num_hops_to_node(node_id src, node_id dst) const;
275 
276  virtual std::vector<node_id>
278  return nodes_connected_to_switch(swaddr);
279  }
280 
281  virtual std::vector<node_id>
283  return nodes_connected_to_switch(swid);
284  }
285 
286  virtual coordinates
287  neighbor_at_port(switch_id sid, int port) const;
288 
289  virtual node_id
290  node_addr(const coordinates& coords) const;
291 
292  virtual node_id
293  node_addr(const coordinates& sw_coords, int port) const;
294 
295  virtual void
298  node_id src_node,
299  std::vector<node_id>& partners) const;
300 
301  virtual void
304  node_id src_node,
305  std::vector<node_id>& partners) const;
306 
307  protected:
308  void
309  configure_injection_geometry(std::vector<int>& redundancies);
310 
311  virtual std::vector<node_id>
312  nodes_connected_to_switch(switch_id swaddr) const;
313 
315 
316  /**
317  Compute coordinates (e.g. X,Y,Z for 3D torus)
318  @param swid The unique index defining a switch location
319  @param coords [inout] The unique coordinates of the switch
320  */
321  public:
322  virtual void
323  compute_switch_coords(switch_id swid, coordinates& coords) const = 0;
324 
325  protected:
326  void
327  partners(
328  bool get_send_partner,
330  node_id src,
331  std::vector<node_id>& partner_list) const;
332 
333  virtual void
335  const coordinates& src_sw_coords,
336  int port,
337  std::vector<node_id>& partners) const;
338 
339  virtual void
341  const coordinates& src_sw_coords,
342  int port,
343  std::vector<node_id>& partners) const;
344 
345  virtual void
347  const coordinates& src_sw_coords,
348  int port,
349  std::vector<node_id>& partners) const;
350 
351  virtual void
353  const coordinates& src_sw_coords,
354  int port,
355  std::vector<node_id>& partners) const;
356 
357  protected:
361 
362 };
363 }
364 }
365 
366 #endif
coordinates switch_coords(switch_id swid) const
Compute coordinates (e.g.
virtual node_id node_addr(const coordinates &coords) const
virtual int minimal_distance(const coordinates &src_coords, const coordinates &dest_coords) const =0
The function accepts either source or node coordinates.
void configure_injection_geometry(std::vector< int > &redundancies)
virtual int endpoint_to_ejection_port(node_id addr) const
virtual void tornado_send_partners(const coordinates &src_sw_coords, int port, std::vector< node_id > &partners) const
virtual void connect_objects(internal_connectable_map &objects)=0
Given a set of connectables, connect them appropriately.
virtual void send_partners(traffic_pattern::type_t ty, node_id src_node, std::vector< node_id > &partners) const
virtual void build_interface_connectables(int conc, end_point_connectable_map &connectables, sprockit::factory2< connectable > *nic_factory, partition *part, int my_rank, sprockit::sim_parameters *params, sprockit::factory_type *interconnect)
virtual int diameter() const =0
virtual std::vector< node_id > nodes_connected_to_injection_switch(switch_id swaddr) const
virtual std::vector< node_id > nodes_connected_to_switch(switch_id swaddr) const
virtual switch_id endpoint_to_ejection_switch(node_id nodeaddr, int &switch_port) const
virtual void compute_switch_coords(switch_id swid, coordinates &coords) const =0
Compute coordinates (e.g.
virtual int endpoint_to_switch_port(node_id nid) const
virtual coordinates node_coords(node_id nid) const
Compute coordinates (e.g.
virtual void minimal_route_to_switch(switch_id current_sw_addr, switch_id dest_sw_addr, structured_routable::path &path) const
Implementation of topology::minimal_route_to_switch.
virtual void recv_partners(traffic_pattern::type_t ty, node_id src_node, std::vector< node_id > &partners) const
virtual int num_leaf_switches() const =0
Structured topologies can be direct (torus) or indirect (fat tree).
virtual void minimal_routes_to_switch(switch_id current_sw_addr, switch_id dest_sw_addr, structured_routable::path &current_path, structured_routable::path_set &paths) const
virtual void tornado_recv_partners(const coordinates &src_sw_coords, int port, std::vector< node_id > &partners) const
virtual void build_endpoint_connectables(end_point_connectable_map &connectables, sprockit::factory< connectable > *factory, partition *part, int my_rank, sprockit::sim_parameters *params)
virtual int ndimensions() const =0
The number of distinct &#39;dimensions&#39; in the topology.
topology_id switch_id
Definition: node_address.h:23
SUMI = Simulator unified messagine interface It is also the name for a solid ink in Japanese - i...
virtual int endpoint_to_injection_port(node_id addr) const
virtual void init_factory_params(sprockit::sim_parameters *params)
virtual void nearest_neighbor_partners(const coordinates &src_sw_coords, int port, std::vector< node_id > &partners) const
virtual int num_hops_to_node(node_id src, node_id dst) const
virtual void bit_complement_partners(const coordinates &src_sw_coords, int port, std::vector< node_id > &partners) const
virtual coordinates neighbor_at_port(switch_id sid, int port) const
void partners(bool get_send_partner, traffic_pattern::type_t ty, node_id src, std::vector< node_id > &partner_list) const
virtual std::vector< node_id > nodes_connected_to_ejection_switch(switch_id swid) const
std::string label(node_id nid) const
virtual switch_id endpoint_to_injection_switch(node_id nodeaddr, int &switch_port) const
virtual void minimal_route_to_coords(const coordinates &src_coords, const coordinates &dest_coords, structured_routable::path &path) const =0
Workhorse function for implementing minimal_route_to_switch and #minimal_route_to_node.
virtual void productive_paths(structured_routable::path_set &paths, const coordinates &current, const coordinates &dst)
virtual void minimal_routes_to_coords(const coordinates &src_coords, const coordinates &dest_coords, structured_routable::path &current_path, structured_routable::path_set &paths) const
Encapsulates a topology like torus, fat tree, butterfly which has a regular, well-defined structure...
virtual void build_internal_connectables(internal_connectable_map &connectables, sprockit::factory< connectable > *factory, partition *part, int my_rank, sprockit::sim_parameters *params, connectable *dummy)
virtual void eject_paths_on_switch(node_id dest_addr, switch_id sw_addr, structured_routable::path_set &paths) const
endpoint_id node_id
Definition: node_address.h:20
virtual switch_id switch_number(const coordinates &coords) const =0
Class for storing all the partitions given to us by METIS.
Definition: sim_partition.h:35
coordinates endpoint_coords(node_id nid) const
virtual int endpoints_per_switch(switch_id addr) const
Given a switch address, return number of nodes connected to it.
virtual void productive_path(int dim, const coordinates &src, const coordinates &dst, structured_routable::path &path) const =0