ruby: Add support for generating topologies in Python.

This commit is contained in:
Steve Reinhardt 2010-01-29 20:29:17 -08:00
parent 184cf4db5b
commit 0b54f1db8e
7 changed files with 140 additions and 148 deletions

View file

@ -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(),

View file

@ -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'

View file

@ -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();

View file

@ -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()

View file

@ -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; 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()

View file

@ -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<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 @@ 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);
}

View file

@ -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:
// 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<int> &latencies, Vector<int> &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;