diff --git a/configs/example/memtest-ruby.py b/configs/example/memtest-ruby.py index e6684fb5a..a520754fb 100644 --- a/configs/example/memtest-ruby.py +++ b/configs/example/memtest-ruby.py @@ -97,24 +97,35 @@ class L2Cache(RubyCache): 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 --git a/src/mem/ruby/network/Network.py b/src/mem/ruby/network/Network.py index 94115ebe8..8079032c6 100644 --- a/src/mem/ruby/network/Network.py +++ b/src/mem/ruby/network/Network.py @@ -30,12 +30,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 --git a/src/mem/ruby/network/garnet-fixed-pipeline/GarnetNetwork_d.cc b/src/mem/ruby/network/garnet-fixed-pipeline/GarnetNetwork_d.cc index 716cfb9ad..765dd1b29 100644 --- a/src/mem/ruby/network/garnet-fixed-pipeline/GarnetNetwork_d.cc +++ b/src/mem/ruby/network/garnet-fixed-pipeline/GarnetNetwork_d.cc @@ -96,7 +96,7 @@ void GarnetNetwork_d::init() 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 --git a/src/mem/ruby/network/garnet-flexible-pipeline/GarnetNetwork.cc b/src/mem/ruby/network/garnet-flexible-pipeline/GarnetNetwork.cc index b2a385843..d93d8ef48 100644 --- a/src/mem/ruby/network/garnet-flexible-pipeline/GarnetNetwork.cc +++ b/src/mem/ruby/network/garnet-flexible-pipeline/GarnetNetwork.cc @@ -95,7 +95,7 @@ void GarnetNetwork::init() 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 --git a/src/mem/ruby/network/simple/SimpleNetwork.cc b/src/mem/ruby/network/simple/SimpleNetwork.cc index bbc9cefdb..2f5ed798a 100644 --- a/src/mem/ruby/network/simple/SimpleNetwork.cc +++ b/src/mem/ruby/network/simple/SimpleNetwork.cc @@ -62,8 +62,6 @@ Network* Network::createNetwork(int nodes) SimpleNetwork::SimpleNetwork(const Params *p) : Network(p) { - m_virtual_networks = 0; - m_topology_ptr = NULL; } void SimpleNetwork::init() @@ -101,7 +99,7 @@ void SimpleNetwork::init() for (int i=0; icreateLinks(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 --git a/src/mem/ruby/network/simple/Topology.cc b/src/mem/ruby/network/simple/Topology.cc index 9d636df49..84185ef92 100644 --- a/src/mem/ruby/network/simple/Topology.cc +++ b/src/mem/ruby/network/simple/Topology.cc @@ -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 @@ static NetDest shortest_path_to_node(SwitchID src, SwitchID next, const Matrix& 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 @@ void Topology::makeTopology() Vector< SwitchID > int_network_switches; // internal switches extracted from the file Vector endpointConnectionExist; // used to ensure all endpoints are connected to the network - endpointConnectionExist.setSize(m_nodes); + for (vector::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::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 @@ void Topology::createLinks(bool isReconfiguration) 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 @@ void Topology::addLink(SwitchID src, SwitchID dest, int link_latency, int bw_mul 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 @@ TopologyParams::create() { 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 --git a/src/mem/ruby/network/simple/Topology.hh b/src/mem/ruby/network/simple/Topology.hh index 6562bdb70..18bacfd26 100644 --- a/src/mem/ruby/network/simple/Topology.hh +++ b/src/mem/ruby/network/simple/Topology.hh @@ -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 > 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: // 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 @@ protected: 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 &latencies, Vector &bw_multis, int numberOfChips); @@ -98,8 +126,6 @@ protected: // 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;