# HG changeset patch
# User Steve Reinhardt <steve.reinha...@amd.com>
# Date 1263536243 28800
# Node ID 66e2254601b93184d109026173b22beafed99693
# Parent  2d514a17d1f69f9b8302c82550a347be3034dd44
ruby: Add support for generating topologies in Python.

diff -r 2d514a17d1f6 -r 66e2254601b9 configs/example/memtest-ruby.py
--- a/configs/example/memtest-ruby.py   Thu Jan 14 22:17:23 2010 -0800
+++ b/configs/example/memtest-ruby.py   Thu Jan 14 22:17:23 2010 -0800
@@ -97,24 +97,35 @@
     latency = 15
     size = 1048576
 
-class CrossbarTopology(Topology):
-    connections="hi"
+# It would be nice to lump all the network nodes into a single list,
+# but for consistency with the old scripts I'm segregating them by
+# type.  I'm not sure if this is really necessary or not.
+ 
+# net_nodes = []
+l1_cntrl_nodes = []
+dir_cntrl_nodes = []
 
- for cpu in cpus:
+for cpu in cpus:
     l1_cntrl = L1Cache_Controller()
-    cpu_seq = RubySequencer(controller=l1_cntrl,
-                            icache=L1Cache(controller=l1_cntrl),
-                            dcache=L1Cache(controller=l1_cntrl))
+    cpu_seq = RubySequencer(controller = l1_cntrl,
+                            icache = L1Cache(controller = l1_cntrl),
+                            dcache = L1Cache(controller = l1_cntrl))
     cpu.controller = l1_cntrl
     cpu.sequencer = cpu_seq
     cpu.test = cpu_seq.port
     cpu_seq.funcmem_port = system.physmem.port
     cpu.functional = system.funcmem.port
     
-    dir_cntrl = Directory_Controller(directory=RubyDirectoryMemory(),
-                                     memory_control=RubyMemoryControl())
+    dir_cntrl = Directory_Controller(version = i,
+                                     directory = RubyDirectoryMemory(),
+                                     memory_control = RubyMemoryControl())
 
-network = SimpleNetwork(topology=CrossbarTopology())
+    # net_nodes += [l1_cntrl, dir_cntrl]
+    l1_cntrl_nodes.append(l1_cntrl)
+    dir_cntrl_nodes.append(dir_cntrl)
+
+network = SimpleNetwork(topology = makeCrossbar(l1_cntrl_nodes + \
+                                                dir_cntrl_nodes))
 
 system.ruby = RubySystem(network = network,
                          profiler = RubyProfiler(),
diff -r 2d514a17d1f6 -r 66e2254601b9 src/mem/ruby/network/Network.py
--- a/src/mem/ruby/network/Network.py   Thu Jan 14 22:17:23 2010 -0800
+++ b/src/mem/ruby/network/Network.py   Thu Jan 14 22:17:23 2010 -0800
@@ -1,12 +1,40 @@
 from m5.params import *
 from m5.SimObject import SimObject
 
+class Link(SimObject):
+    type = 'Link'
+    latency = Param.Int(1, "")
+    bw_multiplier = Param.Int("")
+    weight = Param.Int(1, "")
+
+class ExtLink(Link):
+    type = 'ExtLink'
+    ext_node = Param.RubyController("External node")
+    int_node = Param.Int("ID of internal node")
+    bw_multiplier = 64
+
+class IntLink(Link):
+    type = 'IntLink'
+    node_a = Param.Int("ID of internal node on one end")
+    node_b = Param.Int("ID of internal node on other end")
+    bw_multiplier = 16
+
 class Topology(SimObject):
     type = 'Topology'
-    connections = Param.String("")
+    ext_links = VectorParam.ExtLink("Links to external nodes")
+    int_links = VectorParam.IntLink("Links between internal nodes")
+    num_int_nodes = Param.Int("Nunber of internal nodes")
     print_config = Param.Bool(False,
         "display topology config in the stats file")
 
+def makeCrossbar(nodes):
+    ext_links = [ExtLink(ext_node=n, int_node=i)
+                 for (i, n) in enumerate(nodes)]
+    xbar = len(nodes) # node ID for crossbar switch
+    int_links = [IntLink(node_a=i, node_b=xbar) for i in range(len(nodes))]    
+    return Topology(ext_links=ext_links, int_links=int_links,
+                    num_int_nodes=len(nodes)+1)
+
 class RubyNetwork(SimObject):
     type = 'RubyNetwork'
     cxx_class = 'Network'
diff -r 2d514a17d1f6 -r 66e2254601b9 
src/mem/ruby/network/garnet-fixed-pipeline/GarnetNetwork_d.cc
--- a/src/mem/ruby/network/garnet-fixed-pipeline/GarnetNetwork_d.cc     Thu Jan 
14 22:17:23 2010 -0800
+++ b/src/mem/ruby/network/garnet-fixed-pipeline/GarnetNetwork_d.cc     Thu Jan 
14 22:17:23 2010 -0800
@@ -96,7 +96,7 @@
                 ni->addNode(m_toNetQueues[i], m_fromNetQueues[i]);
                 m_ni_ptr_vector.insertAtBottom(ni);
         }
-        m_topology_ptr->createLinks(false);  // false because this isn't a 
reconfiguration
+        m_topology_ptr->createLinks(this, false);  // false because this isn't 
a reconfiguration
         for(int i = 0; i < m_router_ptr_vector.size(); i++)
         {
                 m_router_ptr_vector[i]->init();
diff -r 2d514a17d1f6 -r 66e2254601b9 
src/mem/ruby/network/garnet-flexible-pipeline/GarnetNetwork.cc
--- a/src/mem/ruby/network/garnet-flexible-pipeline/GarnetNetwork.cc    Thu Jan 
14 22:17:23 2010 -0800
+++ b/src/mem/ruby/network/garnet-flexible-pipeline/GarnetNetwork.cc    Thu Jan 
14 22:17:23 2010 -0800
@@ -95,7 +95,7 @@
                 ni->addNode(m_toNetQueues[i], m_fromNetQueues[i]);
                 m_ni_ptr_vector.insertAtBottom(ni);
         }
-        m_topology_ptr->createLinks(false);  // false because this isn't a 
reconfiguration
+        m_topology_ptr->createLinks(this, false);  // false because this isn't 
a reconfiguration
 }
 
 GarnetNetwork::~GarnetNetwork()
diff -r 2d514a17d1f6 -r 66e2254601b9 
src/mem/ruby/network/simple/SimpleNetwork.cc
--- a/src/mem/ruby/network/simple/SimpleNetwork.cc      Thu Jan 14 22:17:23 
2010 -0800
+++ b/src/mem/ruby/network/simple/SimpleNetwork.cc      Thu Jan 14 22:17:23 
2010 -0800
@@ -62,8 +62,6 @@
 SimpleNetwork::SimpleNetwork(const Params *p)
     : Network(p)
 {
-  m_virtual_networks = 0;
-  m_topology_ptr = NULL;
 }
 
 void SimpleNetwork::init()
@@ -101,7 +99,7 @@
   for (int i=0; i<number_of_switches; i++) {
     m_switch_ptr_vector.insertAtBottom(new Switch(i, this));
   }
-  m_topology_ptr->createLinks(false);  // false because this isn't a 
reconfiguration
+  m_topology_ptr->createLinks(this, false);  // false because this isn't a 
reconfiguration
 }
 
 void SimpleNetwork::reset()
diff -r 2d514a17d1f6 -r 66e2254601b9 src/mem/ruby/network/simple/Topology.cc
--- a/src/mem/ruby/network/simple/Topology.cc   Thu Jan 14 22:17:23 2010 -0800
+++ b/src/mem/ruby/network/simple/Topology.cc   Thu Jan 14 22:17:23 2010 -0800
@@ -39,6 +39,7 @@
 #include "mem/ruby/network/simple/Topology.hh"
 #include "mem/ruby/common/NetDest.hh"
 #include "mem/ruby/network/Network.hh"
+#include "mem/ruby/slicc_interface/AbstractController.hh"
 #include "mem/protocol/TopologyType.hh"
 #include "mem/gems_common/util.hh"
 #include "mem/protocol/MachineType.hh"
@@ -65,19 +66,29 @@
 Topology::Topology(const Params *p)
     : SimObject(p)
 {
-//    m_network_ptr = p->network;
-    m_connections = p->connections;
     m_print_config = p->print_config;
-  m_nodes = MachineType_base_number(MachineType_NUM);
-  m_number_of_switches = 0;
+    m_number_of_switches = p->num_int_nodes;
+  // initialize component latencies record
+  m_component_latencies.setSize(0);
+  m_component_inter_switches.setSize(0);
 }
 
 void Topology::init()
 {
+    // need to defer this until init, to guarantee that constructors
+    // for all the controller objects have been called.
+    m_nodes = MachineType_base_number(MachineType_NUM);
 }
 
 void Topology::makeTopology()
 {
+    if (m_nodes != params()->ext_links.size()) {
+        fatal("m_nodes (%d) != ext_links vector length (%d)\n",
+              m_nodes != params()->ext_links.size());
+    }
+
+    
+
   /*
   if (m_nodes == 1) {
     SwitchID id = newSwitchID();
@@ -95,133 +106,33 @@
   Vector< SwitchID > int_network_switches;  // internal switches extracted 
from the file
   Vector<bool> endpointConnectionExist;  // used to ensure all endpoints are 
connected to the network
 
-  endpointConnectionExist.setSize(m_nodes);
+  for (vector<ExtLink*>::const_iterator i = params()->ext_links.begin();
+       i != params()->ext_links.end(); ++i)
+  {
+      const ExtLinkParams *p = (*i)->params();
+      AbstractController *c = p->ext_node;
+      int ext_idx1 =
+          MachineType_base_number(c->getMachineType()) + c->getVersion();
+      int ext_idx2 = ext_idx1 + m_nodes;
+      int int_idx = p->int_node + 2*m_nodes;
 
-  // initialize endpoint check vector
-  for (int k = 0; k < endpointConnectionExist.size(); k++) {
-    endpointConnectionExist[k] = false;
+      addLink(ext_idx1, int_idx, p->latency, p->bw_multiplier, p->weight);
+      addLink(int_idx, ext_idx2, p->latency, p->bw_multiplier, p->weight);
   }
 
-  stringstream networkFile( m_connections );
-
-  string line = "";
-
-  while (!networkFile.eof()) {
-
-    Vector < SwitchID > nodes;
-    nodes.setSize(2);
-    int latency = -1;  // null latency
-    int weight = -1;  // null weight
-    int bw_multiplier = DEFAULT_BW_MULTIPLIER;  // default multiplier incase 
the network file doesn't define it
-    int i = 0;  // node pair index
-    int varsFound = 0;  // number of varsFound on the line
-    int internalNodes = 0;  // used to determine if the link is between 2 
internal nodes
-    std::getline(networkFile, line, '\n');
-    string varStr = string_split(line, ' ');
-
-    // parse the current line in the file
-    while (varStr != "") {
-      string label = string_split(varStr, ':');
-
-      // valid node labels
-      if (label == "ext_node" || label == "int_node") {
-        ASSERT(i < 2); // one link between 2 switches per line
-        varsFound++;
-        bool isNewIntSwitch = true;
-        if (label == "ext_node") { // input link to node
-          MachineType machine = string_to_MachineType(string_split(varStr, 
':'));
-          string nodeStr = string_split(varStr, ':');
-          nodes[i] = MachineType_base_number(machine)
-            + atoi(nodeStr.c_str());
-
-          // in nodes should be numbered 0 to m_nodes-1
-          ASSERT(nodes[i] >= 0 && nodes[i] < m_nodes);
-          isNewIntSwitch = false;
-          endpointConnectionExist[nodes[i]] = true;
-        }
-        if (label == "int_node") { // interior node
-          nodes[i] = atoi((string_split(varStr, ':')).c_str())+m_nodes*2;
-          // in nodes should be numbered >= m_nodes*2
-          ASSERT(nodes[i] >= m_nodes*2);
-          for (int k = 0; k < int_network_switches.size(); k++) {
-            if (int_network_switches[k] == nodes[i]) {
-              isNewIntSwitch = false;
-            }
-          }
-          if (isNewIntSwitch) {  // if internal switch
-            m_number_of_switches++;
-            int_network_switches.insertAtBottom(nodes[i]);
-          }
-          internalNodes++;
-        }
-        i++;
-      } else if (label == "link_latency") {
-        latency = atoi((string_split(varStr, ':')).c_str());
-        varsFound++;
-      } else if (label == "bw_multiplier") {  // not necessary, defaults to 
DEFAULT_BW_MULTIPLIER
-        bw_multiplier = atoi((string_split(varStr, ':')).c_str());
-      } else if (label == "link_weight") {  // not necessary, defaults to 
link_latency
-        weight = atoi((string_split(varStr, ':')).c_str());
-      } else {
-        cerr << "Error: Unexpected Identifier: " << label << endl;
-        exit(1);
-      }
-      varStr = string_split(line, ' ');
-    }
-    if (varsFound == 3) { // all three necessary link variables where found so 
add the link
-      nodePairs.insertAtBottom(nodes);
-      latencies.insertAtBottom(latency);
-      if (weight != -1) {
-        weights.insertAtBottom(weight);
-      } else {
-        weights.insertAtBottom(latency);
-      }
-      bw_multis.insertAtBottom(bw_multiplier);
-      Vector < SwitchID > otherDirectionNodes;
-      otherDirectionNodes.setSize(2);
-      otherDirectionNodes[0] = nodes[1];
-      if (internalNodes == 2) {  // this is an internal link
-        otherDirectionNodes[1] = nodes[0];
-      } else {
-        otherDirectionNodes[1] = nodes[0]+m_nodes;
-      }
-      nodePairs.insertAtBottom(otherDirectionNodes);
-      latencies.insertAtBottom(latency);
-      if (weight != -1) {
-        weights.insertAtBottom(weight);
-      } else {
-        weights.insertAtBottom(latency);
-      }
-      bw_multis.insertAtBottom(bw_multiplier);
-    } else {
-      if (varsFound != 0) {  // if this is not a valid link, then no vars 
should have been found
-        cerr << "Error in line: " << line << endl;
-        exit(1);
-      }
-    }
-  } // end of file
-
-  // makes sure all enpoints are connected in the soon to be created network
-  for (int k = 0; k < endpointConnectionExist.size(); k++) {
-    if (endpointConnectionExist[k] == false) {
-      cerr << "Error: Unconnected Endpoint: " << k << endl;
-      exit(1);
-    }
+  for (vector<IntLink*>::const_iterator i = params()->int_links.begin();
+       i != params()->int_links.end(); ++i)
+  {
+      const IntLinkParams *p = (*i)->params();
+      int a = p->node_a + 2*m_nodes;
+      int b = p->node_b + 2*m_nodes;
+      addLink(a, b, p->latency, p->bw_multiplier, p->weight);
+      addLink(b, a, p->latency, p->bw_multiplier, p->weight);
   }
-
-  ASSERT(nodePairs.size() == latencies.size() && latencies.size() == 
bw_multis.size() && latencies.size() == weights.size())
-  for (int k = 0; k < nodePairs.size(); k++) {
-    ASSERT(nodePairs[k].size() == 2);
-    addLink(nodePairs[k][0], nodePairs[k][1], latencies[k], bw_multis[k], 
weights[k]);
-  }
-
-  // initialize component latencies record
-  m_component_latencies.setSize(0);
-  m_component_inter_switches.setSize(0);
 }
 
 
-void Topology::createLinks(bool isReconfiguration)
+void Topology::createLinks(Network *net, bool isReconfiguration)
 {
   // Find maximum switchID
 
@@ -279,7 +190,7 @@
       if (weight > 0 && weight != INFINITE_LATENCY) {
         NetDest destination_set = shortest_path_to_node(i, j, 
topology_weights, dist);
         assert(latency != -1);
-        makeLink(i, j, destination_set, latency, weight, bw_multiplier, 
isReconfiguration);
+        makeLink(net, i, j, destination_set, latency, weight, bw_multiplier, 
isReconfiguration);
       }
     }
   }
@@ -312,20 +223,20 @@
   m_bw_multiplier_vector.insertAtBottom(bw_multiplier);
 }
 
-void Topology::makeLink(SwitchID src, SwitchID dest, const NetDest& 
routing_table_entry, int link_latency, int link_weight, int bw_multiplier, bool 
isReconfiguration)
+void Topology::makeLink(Network *net, SwitchID src, SwitchID dest, const 
NetDest& routing_table_entry, int link_latency, int link_weight, int 
bw_multiplier, bool isReconfiguration)
 {
   // Make sure we're not trying to connect two end-point nodes directly 
together
   assert((src >= 2*m_nodes) || (dest >= 2*m_nodes));
 
   if (src < m_nodes) {
-    m_network_ptr->makeInLink(src, dest-(2*m_nodes), routing_table_entry, 
link_latency, bw_multiplier, isReconfiguration);
+    net->makeInLink(src, dest-(2*m_nodes), routing_table_entry, link_latency, 
bw_multiplier, isReconfiguration);
   } else if (dest < 2*m_nodes) {
     assert(dest >= m_nodes);
     NodeID node = dest-m_nodes;
-    m_network_ptr->makeOutLink(src-(2*m_nodes), node, routing_table_entry, 
link_latency, link_weight, bw_multiplier, isReconfiguration);
+    net->makeOutLink(src-(2*m_nodes), node, routing_table_entry, link_latency, 
link_weight, bw_multiplier, isReconfiguration);
   } else {
     assert((src >= 2*m_nodes) && (dest >= 2*m_nodes));
-    m_network_ptr->makeInternalLink(src-(2*m_nodes), dest-(2*m_nodes), 
routing_table_entry, link_latency, link_weight, bw_multiplier, 
isReconfiguration);
+    net->makeInternalLink(src-(2*m_nodes), dest-(2*m_nodes), 
routing_table_entry, link_latency, link_weight, bw_multiplier, 
isReconfiguration);
   }
 }
 
@@ -454,3 +365,21 @@
 {
     return new Topology(this);
 }
+
+Link *
+LinkParams::create()
+{
+    return new Link(this);
+}
+
+ExtLink *
+ExtLinkParams::create()
+{
+    return new ExtLink(this);
+}
+
+IntLink *
+IntLinkParams::create()
+{
+    return new IntLink(this);
+}
diff -r 2d514a17d1f6 -r 66e2254601b9 src/mem/ruby/network/simple/Topology.hh
--- a/src/mem/ruby/network/simple/Topology.hh   Thu Jan 14 22:17:23 2010 -0800
+++ b/src/mem/ruby/network/simple/Topology.hh   Thu Jan 14 22:17:23 2010 -0800
@@ -52,17 +52,45 @@
 #include "mem/ruby/system/NodeID.hh"
 #include "sim/sim_object.hh"
 #include "params/Topology.hh"
+#include "params/Link.hh"
+#include "params/ExtLink.hh"
+#include "params/IntLink.hh"
 
 class Network;
 class NetDest;
 
 typedef Vector < Vector <int> > Matrix;
 
+class Link : public SimObject {
+  public:
+    typedef LinkParams Params;
+    Link(const Params *p) : SimObject(p) {}
+    const Params *params() const { return (const Params *)_params; }
+};
+
+
+class ExtLink : public Link {
+  public:
+    typedef ExtLinkParams Params;
+    ExtLink(const Params *p) : Link(p) {}
+    const Params *params() const { return (const Params *)_params; }
+};
+
+
+class IntLink : public Link {
+  public:
+    typedef IntLinkParams Params;
+    IntLink(const Params *p) : Link(p) {}
+    const Params *params() const { return (const Params *)_params; }
+};
+
+
 class Topology : public SimObject {
 public:
   // Constructors
     typedef TopologyParams Params;
     Topology(const Params *p);
+    const Params *params() const { return (const Params *)_params; }
 
   // Destructor
   virtual ~Topology() {}
@@ -72,7 +100,7 @@
   // Public Methods
   void makeTopology();
   int numSwitches() const { return m_number_of_switches; }
-  void createLinks(bool isReconfiguration);
+  void createLinks(Network *net, bool isReconfiguration);
 
   const string getName() { return m_name; }
   void printStats(ostream& out) const {}
@@ -86,7 +114,7 @@
   void addLink(SwitchID src, SwitchID dest, int link_latency);
   void addLink(SwitchID src, SwitchID dest, int link_latency, int 
bw_multiplier);
   void addLink(SwitchID src, SwitchID dest, int link_latency, int 
bw_multiplier, int link_weight);
-  void makeLink(SwitchID src, SwitchID dest, const NetDest& 
routing_table_entry, int link_latency, int weight, int bw_multiplier, bool 
isReconfiguration);
+  void makeLink(Network *net, SwitchID src, SwitchID dest, const NetDest& 
routing_table_entry, int link_latency, int weight, int bw_multiplier, bool 
isReconfiguration);
 
   //  void makeSwitchesPerChip(Vector< Vector < SwitchID > > &nodePairs, 
Vector<int> &latencies, Vector<int> &bw_multis, int numberOfChips);
 
@@ -98,8 +126,6 @@
   // Data Members (m_ prefix)
   string m_name;
   bool m_print_config;
-  Network* m_network_ptr;
-  string m_connections;
   NodeID m_nodes;
   int m_number_of_switches;
 

_______________________________________________
m5-dev mailing list
m5-dev@m5sim.org
http://m5sim.org/mailman/listinfo/m5-dev

Reply via email to