summaryrefslogtreecommitdiff
path: root/src/mem/ruby/network
diff options
context:
space:
mode:
authorNathan Binkert <nate@binkert.org>2009-07-06 15:49:47 -0700
committerNathan Binkert <nate@binkert.org>2009-07-06 15:49:47 -0700
commit92de70b69aaf3f399a855057b556ed198139e5d8 (patch)
treef8e7d0d494df8810cc960be4c52d8b555471f157 /src/mem/ruby/network
parent05f6a4a6b92370162da17ef5cccb5a7e3ba508e5 (diff)
downloadgem5-92de70b69aaf3f399a855057b556ed198139e5d8.tar.xz
ruby: Import the latest ruby changes from gems.
This was done with an automated process, so there could be things that were done in this tree in the past that didn't make it. One known regression is that atomic memory operations do not seem to work properly anymore.
Diffstat (limited to 'src/mem/ruby/network')
-rw-r--r--src/mem/ruby/network/Network.cc34
-rw-r--r--src/mem/ruby/network/Network.hh26
-rw-r--r--src/mem/ruby/network/garnet-fixed-pipeline/CreditLink_d.hh2
-rw-r--r--src/mem/ruby/network/garnet-fixed-pipeline/GarnetNetwork_d.cc38
-rw-r--r--src/mem/ruby/network/garnet-fixed-pipeline/GarnetNetwork_d.hh15
-rw-r--r--src/mem/ruby/network/garnet-fixed-pipeline/NetworkInterface_d.cc10
-rw-r--r--src/mem/ruby/network/garnet-fixed-pipeline/NetworkLink_d.cc11
-rw-r--r--src/mem/ruby/network/garnet-fixed-pipeline/NetworkLink_d.hh2
-rw-r--r--src/mem/ruby/network/garnet-fixed-pipeline/OutVcState_d.cc7
-rw-r--r--src/mem/ruby/network/garnet-fixed-pipeline/OutVcState_d.hh4
-rw-r--r--src/mem/ruby/network/garnet-fixed-pipeline/OutputUnit_d.cc4
-rw-r--r--src/mem/ruby/network/garnet-fixed-pipeline/Router_d.cc6
-rw-r--r--src/mem/ruby/network/garnet-fixed-pipeline/SWallocator_d.cc2
-rw-r--r--src/mem/ruby/network/garnet-fixed-pipeline/VCallocator_d.cc2
-rw-r--r--src/mem/ruby/network/garnet-flexible-pipeline/GarnetNetwork.cc47
-rw-r--r--src/mem/ruby/network/garnet-flexible-pipeline/GarnetNetwork.hh16
-rw-r--r--src/mem/ruby/network/garnet-flexible-pipeline/NetworkConfig.hh79
-rw-r--r--src/mem/ruby/network/garnet-flexible-pipeline/NetworkInterface.cc8
-rw-r--r--src/mem/ruby/network/garnet-flexible-pipeline/NetworkLink.cc4
-rw-r--r--src/mem/ruby/network/garnet-flexible-pipeline/Router.cc16
-rw-r--r--src/mem/ruby/network/simple/CustomTopology.cc140
-rw-r--r--src/mem/ruby/network/simple/CustomTopology.hh17
-rw-r--r--src/mem/ruby/network/simple/HierarchicalSwitchTopology.cc66
-rw-r--r--src/mem/ruby/network/simple/HierarchicalSwitchTopology.hh17
-rw-r--r--src/mem/ruby/network/simple/PerfectSwitch.cc12
-rw-r--r--src/mem/ruby/network/simple/PtToPtTopology.cc82
-rw-r--r--src/mem/ruby/network/simple/PtToPtTopology.hh17
-rw-r--r--src/mem/ruby/network/simple/SimpleNetwork.cc58
-rw-r--r--src/mem/ruby/network/simple/SimpleNetwork.hh8
-rw-r--r--src/mem/ruby/network/simple/Switch.cc5
-rw-r--r--src/mem/ruby/network/simple/Switch.hh2
-rw-r--r--src/mem/ruby/network/simple/Throttle.cc13
-rw-r--r--src/mem/ruby/network/simple/Throttle.hh5
-rw-r--r--src/mem/ruby/network/simple/Topology.cc485
-rw-r--r--src/mem/ruby/network/simple/Topology.hh21
-rw-r--r--src/mem/ruby/network/simple/Torus2DTopology.cc84
-rw-r--r--src/mem/ruby/network/simple/Torus2DTopology.hh17
37 files changed, 851 insertions, 531 deletions
diff --git a/src/mem/ruby/network/Network.cc b/src/mem/ruby/network/Network.cc
new file mode 100644
index 000000000..cb3507471
--- /dev/null
+++ b/src/mem/ruby/network/Network.cc
@@ -0,0 +1,34 @@
+
+#include "mem/protocol/MachineType.hh"
+#include "mem/ruby/network/Network.hh"
+
+Network::Network(const string & name)
+ : m_name(name)
+{
+ m_virtual_networks = 0;
+ m_topology_ptr = NULL;
+}
+
+void Network::init(const vector<string> & argv)
+{
+ m_nodes = MachineType_base_number(MachineType_NUM); // Total nodes in network
+
+ for (size_t i=0; i<argv.size(); i+=2) {
+ if (argv[i] == "number_of_virtual_networks")
+ m_virtual_networks = atoi(argv[i+1].c_str());
+ else if (argv[i] == "topology")
+ m_topology_ptr = RubySystem::getTopology(argv[i+1]);
+ else if (argv[i] == "buffer_size")
+ m_buffer_size = atoi(argv[i+1].c_str());
+ else if (argv[i] == "endpoint_bandwidth")
+ m_endpoint_bandwidth = atoi(argv[i+1].c_str());
+ else if (argv[i] == "adaptive_routing")
+ m_adaptive_routing = (argv[i+1]=="true");
+ else if (argv[i] == "link_latency")
+ m_link_latency = atoi(argv[i+1].c_str());
+
+ }
+ assert(m_virtual_networks != 0);
+ assert(m_topology_ptr != NULL);
+// printf ("HERE \n");
+}
diff --git a/src/mem/ruby/network/Network.hh b/src/mem/ruby/network/Network.hh
index d3bfa59da..5730d6591 100644
--- a/src/mem/ruby/network/Network.hh
+++ b/src/mem/ruby/network/Network.hh
@@ -49,22 +49,29 @@
#include "mem/ruby/common/Global.hh"
#include "mem/ruby/system/NodeID.hh"
#include "mem/protocol/MessageSizeType.hh"
+#include "mem/ruby/system/System.hh"
+#include "mem/ruby/config/RubyConfig.hh"
class NetDest;
class MessageBuffer;
class Throttle;
+class Topology;
class Network {
public:
// Constructors
- Network() {}
+ Network(const string & name);
+ virtual void init(const vector<string> & argv);
// Destructor
virtual ~Network() {}
// Public Methods
-
- static Network* createNetwork(int nodes);
+ int getBufferSize() { return m_buffer_size; }
+ int getNumberOfVirtualNetworks() { return m_virtual_networks; }
+ int getEndpointBandwidth() { return m_endpoint_bandwidth; }
+ bool getAdaptiveRouting() {return m_adaptive_routing; }
+ int getLinkLatency() { return m_link_latency; }
// returns the queue requested for the given component
virtual MessageBuffer* getToNetQueue(NodeID id, bool ordered, int netNumber) = 0;
@@ -84,7 +91,7 @@ public:
virtual void printConfig(ostream& out) const = 0;
virtual void print(ostream& out) const = 0;
-private:
+protected:
// Private Methods
// Private copy constructor and assignment operator
@@ -92,6 +99,15 @@ private:
Network& operator=(const Network& obj);
// Data Members (m_ prefix)
+protected:
+ const string m_name;
+ int m_nodes;
+ int m_virtual_networks;
+ int m_buffer_size;
+ int m_endpoint_bandwidth;
+ Topology* m_topology_ptr;
+ bool m_adaptive_routing;
+ int m_link_latency;
};
// Output operator declaration
@@ -110,7 +126,7 @@ ostream& operator<<(ostream& out, const Network& obj)
// Code to map network message size types to an integer number of bytes
const int CONTROL_MESSAGE_SIZE = 8;
-const int DATA_MESSAGE_SIZE = (64+8);
+const int DATA_MESSAGE_SIZE = (RubySystem::getBlockSizeBytes()+8);
extern inline
int MessageSizeType_to_int(MessageSizeType size_type)
diff --git a/src/mem/ruby/network/garnet-fixed-pipeline/CreditLink_d.hh b/src/mem/ruby/network/garnet-fixed-pipeline/CreditLink_d.hh
index 5e68198cc..387ed0bc1 100644
--- a/src/mem/ruby/network/garnet-fixed-pipeline/CreditLink_d.hh
+++ b/src/mem/ruby/network/garnet-fixed-pipeline/CreditLink_d.hh
@@ -11,7 +11,7 @@
class CreditLink_d : public NetworkLink_d {
public:
- CreditLink_d(int id):NetworkLink_d(id) {}
+ CreditLink_d(int id, int link_latency, GarnetNetwork_d *net_ptr):NetworkLink_d(id, link_latency, net_ptr) {}
};
#endif
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 988b634ce..51393b576 100644
--- a/src/mem/ruby/network/garnet-fixed-pipeline/GarnetNetwork_d.cc
+++ b/src/mem/ruby/network/garnet-fixed-pipeline/GarnetNetwork_d.cc
@@ -43,10 +43,19 @@
#include "mem/ruby/network/garnet-fixed-pipeline/CreditLink_d.hh"
#include "mem/ruby/common/NetDest.hh"
-GarnetNetwork_d::GarnetNetwork_d(int nodes)
+GarnetNetwork_d::GarnetNetwork_d(const string & name)
+ : Network(name)
{
- m_nodes = MachineType_base_number(MachineType_NUM); // Total nodes in network
- m_virtual_networks = NUMBER_OF_VIRTUAL_NETWORKS; // Number of virtual networks = number of message classes in the coherence protocol
+}
+
+void GarnetNetwork_d::init(const vector<string> & argv)
+{
+ Network::init(argv);
+
+ //added by SS
+ m_network_config_ptr = new NetworkConfig;
+ m_network_config_ptr->init(argv);
+
m_ruby_start = 0;
m_flits_recieved = 0;
m_flits_injected = 0;
@@ -80,7 +89,7 @@ GarnetNetwork_d::GarnetNetwork_d(int nodes)
}
// Setup the network switches
- m_topology_ptr = new Topology(this, m_nodes);
+ m_topology_ptr->makeTopology();
int number_of_routers = m_topology_ptr->numSwitches();
for (int i=0; i<number_of_routers; i++) {
@@ -138,7 +147,7 @@ void GarnetNetwork_d::makeInLink(NodeID src, SwitchID dest, const NetDest& routi
if(!isReconfiguration)
{
NetworkLink_d *net_link = new NetworkLink_d(m_link_ptr_vector.size(), link_latency, this);
- CreditLink_d *credit_link = new CreditLink_d(m_creditlink_ptr_vector.size());
+ CreditLink_d *credit_link = new CreditLink_d(m_creditlink_ptr_vector.size(), link_latency, this);
m_link_ptr_vector.insertAtBottom(net_link);
m_creditlink_ptr_vector.insertAtBottom(credit_link);
@@ -167,7 +176,7 @@ void GarnetNetwork_d::makeOutLink(SwitchID src, NodeID dest, const NetDest& rout
if(!isReconfiguration)
{
NetworkLink_d *net_link = new NetworkLink_d(m_link_ptr_vector.size(), link_latency, this);
- CreditLink_d *credit_link = new CreditLink_d(m_creditlink_ptr_vector.size());
+ CreditLink_d *credit_link = new CreditLink_d(m_creditlink_ptr_vector.size(), link_latency, this);
m_link_ptr_vector.insertAtBottom(net_link);
m_creditlink_ptr_vector.insertAtBottom(credit_link);
@@ -190,7 +199,7 @@ void GarnetNetwork_d::makeInternalLink(SwitchID src, SwitchID dest, const NetDes
if(!isReconfiguration)
{
NetworkLink_d *net_link = new NetworkLink_d(m_link_ptr_vector.size(), link_latency, this);
- CreditLink_d *credit_link = new CreditLink_d(m_creditlink_ptr_vector.size());
+ CreditLink_d *credit_link = new CreditLink_d(m_creditlink_ptr_vector.size(), link_latency, this);
m_link_ptr_vector.insertAtBottom(net_link);
m_creditlink_ptr_vector.insertAtBottom(credit_link);
@@ -241,9 +250,9 @@ Time GarnetNetwork_d::getRubyStartTime()
void GarnetNetwork_d::printStats(ostream& out) const
{ double average_link_utilization = 0;
Vector<double > average_vc_load;
- average_vc_load.setSize(m_virtual_networks*NetworkConfig::getVCsPerClass());
+ average_vc_load.setSize(m_virtual_networks*m_network_config_ptr->getVCsPerClass());
- for(int i = 0; i < m_virtual_networks*NetworkConfig::getVCsPerClass(); i++)
+ for(int i = 0; i < m_virtual_networks*m_network_config_ptr->getVCsPerClass(); i++)
{
average_vc_load[i] = 0;
}
@@ -259,7 +268,7 @@ void GarnetNetwork_d::printStats(ostream& out) const
Vector<int > vc_load = m_link_ptr_vector[i]->getVcLoad();
for(int j = 0; j < vc_load.size(); j++)
{
- assert(vc_load.size() == NetworkConfig::getVCsPerClass()*m_virtual_networks);
+ assert(vc_load.size() == m_network_config_ptr->getVCsPerClass()*m_virtual_networks);
average_vc_load[j] += vc_load[j];
}
}
@@ -267,7 +276,7 @@ void GarnetNetwork_d::printStats(ostream& out) const
out << "Average Link Utilization :: " << average_link_utilization << " flits/cycle" << endl;
out << "-------------" << endl;
- for(int i = 0; i < NetworkConfig::getVCsPerClass()*NUMBER_OF_VIRTUAL_NETWORKS; i++)
+ for(int i = 0; i < m_network_config_ptr->getVCsPerClass()*m_virtual_networks; i++)
{
average_vc_load[i] = (double(average_vc_load[i]) / (double(g_eventQueue_ptr->getTime()) - m_ruby_start));
out << "Average VC Load [" << i << "] = " << average_vc_load[i] << " flits/cycle " << endl;
@@ -304,7 +313,7 @@ void GarnetNetwork_d::printConfig(ostream& out) const
out << "Network Configuration" << endl;
out << "---------------------" << endl;
out << "network: GarnetNetwork_d" << endl;
- out << "topology: " << g_NETWORK_TOPOLOGY << endl;
+ out << "topology: " << m_topology_ptr->getName() << endl;
out << endl;
for (int i = 0; i < m_virtual_networks; i++)
@@ -337,10 +346,7 @@ void GarnetNetwork_d::printConfig(ostream& out) const
{
m_router_ptr_vector[i]->printConfig(out);
}
- if (g_PRINT_TOPOLOGY)
- {
- m_topology_ptr->printConfig(out);
- }
+ m_topology_ptr->printConfig(out);
}
void GarnetNetwork_d::print(ostream& out) const
diff --git a/src/mem/ruby/network/garnet-fixed-pipeline/GarnetNetwork_d.hh b/src/mem/ruby/network/garnet-fixed-pipeline/GarnetNetwork_d.hh
index e0f7aebd9..f4b809443 100644
--- a/src/mem/ruby/network/garnet-fixed-pipeline/GarnetNetwork_d.hh
+++ b/src/mem/ruby/network/garnet-fixed-pipeline/GarnetNetwork_d.hh
@@ -51,10 +51,15 @@ class CreditLink_d;
class GarnetNetwork_d : public Network{
public:
- GarnetNetwork_d(int nodes);
+ GarnetNetwork_d(const string & name);
~GarnetNetwork_d();
+ void init(const vector<string> & argv);
+
+ //added by SS
+ NetworkConfig* getNetworkConfig() { return m_network_config_ptr; }
+
int getNumNodes(){ return m_nodes;}
// returns the queue requested for the given component
@@ -99,6 +104,8 @@ public:
void makeInternalLink(SwitchID src, NodeID dest, const NetDest& routing_table_entry, int link_latency, int link_weight, int bw_multiplier, bool isReconfiguration);
private:
+ NetworkConfig* m_network_config_ptr;
+
void checkNetworkAllocation(NodeID id, bool ordered, int network_num);
// Private copy constructor and assignment operator
@@ -106,8 +113,8 @@ private:
GarnetNetwork_d& operator=(const GarnetNetwork_d& obj);
/***********Data Members*************/
- int m_virtual_networks;
- int m_nodes;
+// int m_virtual_networks;
+// int m_nodes;
int m_flits_recieved, m_flits_injected;
double m_network_latency, m_queueing_latency;
@@ -122,7 +129,7 @@ private:
Vector<CreditLink_d *> m_creditlink_ptr_vector; // All links in the network
Vector<NetworkInterface_d *> m_ni_ptr_vector; // All NI's in Network
- Topology* m_topology_ptr;
+// Topology* m_topology_ptr;
Time m_ruby_start;
};
diff --git a/src/mem/ruby/network/garnet-fixed-pipeline/NetworkInterface_d.cc b/src/mem/ruby/network/garnet-fixed-pipeline/NetworkInterface_d.cc
index 77857b1f8..f75997757 100644
--- a/src/mem/ruby/network/garnet-fixed-pipeline/NetworkInterface_d.cc
+++ b/src/mem/ruby/network/garnet-fixed-pipeline/NetworkInterface_d.cc
@@ -43,7 +43,7 @@ NetworkInterface_d::NetworkInterface_d(int id, int virtual_networks, GarnetNetwo
m_id = id;
m_net_ptr = network_ptr;
m_virtual_networks = virtual_networks;
- m_vc_per_vnet = NetworkConfig::getVCsPerClass();
+ m_vc_per_vnet = m_net_ptr->getNetworkConfig()->getVCsPerClass();
m_num_vcs = m_vc_per_vnet*m_virtual_networks;
m_vc_round_robin = 0;
@@ -66,7 +66,7 @@ NetworkInterface_d::NetworkInterface_d(int id, int virtual_networks, GarnetNetwo
for(int i = 0; i < m_num_vcs; i++)
{
- m_out_vc_state.insertAtBottom(new OutVcState_d(i));
+ m_out_vc_state.insertAtBottom(new OutVcState_d(i, m_net_ptr));
m_out_vc_state[i]->setState(IDLE_, g_eventQueue_ptr->getTime());
}
}
@@ -114,7 +114,7 @@ bool NetworkInterface_d::flitisizeMessage(MsgPtr msg_ptr, int vnet)
NetDest net_msg_dest = net_msg_ptr->getInternalDestination();
Vector<NodeID> dest_nodes = net_msg_dest.getAllDest(); // gets all the destinations associated with this message.
- int num_flits = (int) ceil((double) MessageSizeType_to_int(net_msg_ptr->getMessageSize())/NetworkConfig::getFlitSize() ); // Number of flits is dependent on the link bandwidth available. This is expressed in terms of bytes/cycle or the flit size
+ int num_flits = (int) ceil((double) MessageSizeType_to_int(net_msg_ptr->getMessageSize())/m_net_ptr->getNetworkConfig()->getFlitSize() ); // Number of flits is dependent on the link bandwidth available. This is expressed in terms of bytes/cycle or the flit size
for(int ctr = 0; ctr < dest_nodes.size(); ctr++) // loop because we will be converting all multicast messages into unicast messages
{
@@ -221,7 +221,7 @@ void NetworkInterface_d::wakeup()
if(t_flit->get_type() == TAIL_ || t_flit->get_type() == HEAD_TAIL_)
{
free_signal = true;
- if(!NetworkConfig::isNetworkTesting()) // When we are doing network only testing, the messages do not have to be buffered into the message buffers
+ if(!m_net_ptr->getNetworkConfig()->isNetworkTesting()) // When we are doing network only testing, the messages do not have to be buffered into the message buffers
{
outNode_ptr[t_flit->get_vnet()]->enqueue(t_flit->get_msg_ptr(), 1); // enqueueing for protocol buffer. This is not required when doing network only testing
}
@@ -307,7 +307,7 @@ void NetworkInterface_d::scheduleOutputLink()
int NetworkInterface_d::get_vnet(int vc)
{
- for(int i = 0; i < NUMBER_OF_VIRTUAL_NETWORKS; i++)
+ for(int i = 0; i < m_net_ptr->getNumberOfVirtualNetworks(); i++)
{
if(vc >= (i*m_vc_per_vnet) && vc < ((i+1)*m_vc_per_vnet))
{
diff --git a/src/mem/ruby/network/garnet-fixed-pipeline/NetworkLink_d.cc b/src/mem/ruby/network/garnet-fixed-pipeline/NetworkLink_d.cc
index 94f721646..8382d331f 100644
--- a/src/mem/ruby/network/garnet-fixed-pipeline/NetworkLink_d.cc
+++ b/src/mem/ruby/network/garnet-fixed-pipeline/NetworkLink_d.cc
@@ -37,6 +37,7 @@
#include "mem/ruby/network/garnet-flexible-pipeline/NetworkConfig.hh"
#include "mem/ruby/network/garnet-fixed-pipeline/GarnetNetwork_d.hh"
+/*
NetworkLink_d::NetworkLink_d(int id)
{
m_id = id;
@@ -45,12 +46,12 @@ NetworkLink_d::NetworkLink_d(int id)
linkBuffer = new flitBuffer_d();
m_link_utilized = 0;
- m_vc_load.setSize(NetworkConfig::getVCsPerClass()*NUMBER_OF_VIRTUAL_NETWORKS);
+ m_vc_load.setSize(NetworkConfig::getVCsPerClass()*RubySystem::getNetwork()->getNumberOfVirtualNetworks());
- for(int i = 0; i < NetworkConfig::getVCsPerClass()*NUMBER_OF_VIRTUAL_NETWORKS; i++)
+ for(int i = 0; i < NetworkConfig::getVCsPerClass()*RubySystem::getNetwork()->getNumberOfVirtualNetworks(); i++)
m_vc_load[i] = 0;
}
-
+*/
NetworkLink_d::NetworkLink_d(int id, int link_latency, GarnetNetwork_d *net_ptr)
{
m_net_ptr = net_ptr;
@@ -58,9 +59,9 @@ NetworkLink_d::NetworkLink_d(int id, int link_latency, GarnetNetwork_d *net_ptr)
m_latency = link_latency;
linkBuffer = new flitBuffer_d();
m_link_utilized = 0;
- m_vc_load.setSize(NetworkConfig::getVCsPerClass()*NUMBER_OF_VIRTUAL_NETWORKS);
+ m_vc_load.setSize(m_net_ptr->getNetworkConfig()->getVCsPerClass()*net_ptr->getNumberOfVirtualNetworks());
- for(int i = 0; i < NetworkConfig::getVCsPerClass()*NUMBER_OF_VIRTUAL_NETWORKS; i++)
+ for(int i = 0; i < m_net_ptr->getNetworkConfig()->getVCsPerClass()*net_ptr->getNumberOfVirtualNetworks(); i++)
m_vc_load[i] = 0;
}
diff --git a/src/mem/ruby/network/garnet-fixed-pipeline/NetworkLink_d.hh b/src/mem/ruby/network/garnet-fixed-pipeline/NetworkLink_d.hh
index 1e81a565b..90fb9f6dc 100644
--- a/src/mem/ruby/network/garnet-fixed-pipeline/NetworkLink_d.hh
+++ b/src/mem/ruby/network/garnet-fixed-pipeline/NetworkLink_d.hh
@@ -46,7 +46,7 @@ class GarnetNetwork_d;
class NetworkLink_d : public Consumer {
public:
- NetworkLink_d(int id);
+ //NetworkLink_d(int id);
~NetworkLink_d();
NetworkLink_d(int id, int link_latency, GarnetNetwork_d *net_ptr);
diff --git a/src/mem/ruby/network/garnet-fixed-pipeline/OutVcState_d.cc b/src/mem/ruby/network/garnet-fixed-pipeline/OutVcState_d.cc
index 4fd040099..69e3ae377 100644
--- a/src/mem/ruby/network/garnet-fixed-pipeline/OutVcState_d.cc
+++ b/src/mem/ruby/network/garnet-fixed-pipeline/OutVcState_d.cc
@@ -27,7 +27,7 @@
*/
/*
- * OutVCState_d.C
+ * OutVCState_d.cc
*
* Niket Agarwal, Princeton University
*
@@ -37,10 +37,11 @@
#include "mem/ruby/network/garnet-flexible-pipeline/NetworkConfig.hh"
#include "mem/ruby/eventqueue/RubyEventQueue.hh"
-OutVcState_d::OutVcState_d(int id)
+OutVcState_d::OutVcState_d(int id, GarnetNetwork_d *network_ptr)
{
+ m_network_ptr = network_ptr;
m_id = id;
m_vc_state = IDLE_;
m_time = g_eventQueue_ptr->getTime();
- m_credit_count = NetworkConfig::getBufferSize();
+ m_credit_count = m_network_ptr->getNetworkConfig()->getBufferSize();
}
diff --git a/src/mem/ruby/network/garnet-fixed-pipeline/OutVcState_d.hh b/src/mem/ruby/network/garnet-fixed-pipeline/OutVcState_d.hh
index 959a3d643..dc64b8504 100644
--- a/src/mem/ruby/network/garnet-fixed-pipeline/OutVcState_d.hh
+++ b/src/mem/ruby/network/garnet-fixed-pipeline/OutVcState_d.hh
@@ -37,10 +37,11 @@
#define OUT_VC_STATE_D_H
#include "mem/ruby/network/garnet-fixed-pipeline/NetworkHeader.hh"
+#include "mem/ruby/network/garnet-fixed-pipeline/GarnetNetwork_d.hh"
class OutVcState_d {
public:
- OutVcState_d(int id);
+ OutVcState_d(int id, GarnetNetwork_d *network_ptr);
int get_inport() {return m_in_port; }
int get_invc() { return m_in_vc; }
@@ -75,6 +76,7 @@ public:
}
private:
+ GarnetNetwork_d *m_network_ptr;
int m_id ;
Time m_time;
VC_state_type m_vc_state;
diff --git a/src/mem/ruby/network/garnet-fixed-pipeline/OutputUnit_d.cc b/src/mem/ruby/network/garnet-fixed-pipeline/OutputUnit_d.cc
index 1b8b8097b..eb2450897 100644
--- a/src/mem/ruby/network/garnet-fixed-pipeline/OutputUnit_d.cc
+++ b/src/mem/ruby/network/garnet-fixed-pipeline/OutputUnit_d.cc
@@ -27,7 +27,7 @@
*/
/*
- * OutputUnit_d.C
+ * OutputUnit_d.cc
*
* Niket Agarwal, Princeton University
*
@@ -46,7 +46,7 @@ OutputUnit_d::OutputUnit_d(int id, Router_d *router)
for(int i = 0; i < m_num_vcs; i++)
{
- m_outvc_state.insertAtBottom(new OutVcState_d(i));
+ m_outvc_state.insertAtBottom(new OutVcState_d(i, m_router->get_net_ptr()));
}
}
diff --git a/src/mem/ruby/network/garnet-fixed-pipeline/Router_d.cc b/src/mem/ruby/network/garnet-fixed-pipeline/Router_d.cc
index c59805b48..161e6ecff 100644
--- a/src/mem/ruby/network/garnet-fixed-pipeline/Router_d.cc
+++ b/src/mem/ruby/network/garnet-fixed-pipeline/Router_d.cc
@@ -48,10 +48,10 @@ Router_d::Router_d(int id, GarnetNetwork_d *network_ptr)
{
m_id = id;
m_network_ptr = network_ptr;
- m_virtual_networks = NUMBER_OF_VIRTUAL_NETWORKS;
- m_vc_per_vnet = NetworkConfig::getVCsPerClass();
+ m_virtual_networks = network_ptr->getNumberOfVirtualNetworks();
+ m_vc_per_vnet = m_network_ptr->getNetworkConfig()->getVCsPerClass();
m_num_vcs = m_virtual_networks*m_vc_per_vnet;
- m_flit_width = NetworkConfig::getFlitSize();
+ m_flit_width = m_network_ptr->getNetworkConfig()->getFlitSize();
m_routing_unit = new RoutingUnit_d(this);
m_vc_alloc = new VCallocator_d(this);
diff --git a/src/mem/ruby/network/garnet-fixed-pipeline/SWallocator_d.cc b/src/mem/ruby/network/garnet-fixed-pipeline/SWallocator_d.cc
index 7ca74244e..dd0378305 100644
--- a/src/mem/ruby/network/garnet-fixed-pipeline/SWallocator_d.cc
+++ b/src/mem/ruby/network/garnet-fixed-pipeline/SWallocator_d.cc
@@ -207,7 +207,7 @@ void SWallocator_d::check_for_wakeup()
int SWallocator_d::get_vnet(int invc)
{
- for(int i = 0; i < NUMBER_OF_VIRTUAL_NETWORKS; i++)
+ for(int i = 0; i < RubySystem::getNetwork()->getNumberOfVirtualNetworks(); i++)
{
if(invc >= (i*m_vc_per_vnet) && invc < ((i+1)*m_vc_per_vnet))
{
diff --git a/src/mem/ruby/network/garnet-fixed-pipeline/VCallocator_d.cc b/src/mem/ruby/network/garnet-fixed-pipeline/VCallocator_d.cc
index 6f13ba14f..810aea175 100644
--- a/src/mem/ruby/network/garnet-fixed-pipeline/VCallocator_d.cc
+++ b/src/mem/ruby/network/garnet-fixed-pipeline/VCallocator_d.cc
@@ -244,7 +244,7 @@ void VCallocator_d::arbitrate_outvcs()
int VCallocator_d::get_vnet(int invc)
{
- for(int i = 0; i < NUMBER_OF_VIRTUAL_NETWORKS; i++)
+ for(int i = 0; i < RubySystem::getNetwork()->getNumberOfVirtualNetworks(); i++)
{
if(invc >= (i*m_vc_per_vnet) && invc < ((i+1)*m_vc_per_vnet))
{
diff --git a/src/mem/ruby/network/garnet-flexible-pipeline/GarnetNetwork.cc b/src/mem/ruby/network/garnet-flexible-pipeline/GarnetNetwork.cc
index 2496cd30f..e56f5b5e8 100644
--- a/src/mem/ruby/network/garnet-flexible-pipeline/GarnetNetwork.cc
+++ b/src/mem/ruby/network/garnet-flexible-pipeline/GarnetNetwork.cc
@@ -44,26 +44,22 @@
#include "mem/ruby/network/garnet-flexible-pipeline/NetworkLink.hh"
#include "mem/ruby/common/NetDest.hh"
-// calls new to abstract away from the network
-Network* Network::createNetwork(int nodes)
+GarnetNetwork::GarnetNetwork(const string & name)
+ : Network(name)
{
- NetworkConfig::readNetConfig();
- // Instantiate a network depending on what kind of network is requested
- if(NetworkConfig::isGarnetNetwork())
- {
- if(NetworkConfig::isDetailNetwork())
- return new GarnetNetwork_d(nodes);
- else
- return new GarnetNetwork(nodes);
- }
- else
- return new SimpleNetwork(nodes);
}
-GarnetNetwork::GarnetNetwork(int nodes)
+void GarnetNetwork::init(const vector<string> & argv)
{
- m_nodes = MachineType_base_number(MachineType_NUM); // Total nodes in network
- m_virtual_networks = NUMBER_OF_VIRTUAL_NETWORKS; // Number of virtual networks = number of message classes in the coherence protocol
+// printf("hello\n");
+ Network::init(argv);
+//added by SS
+// assert (m_topology_ptr!=NULL);
+
+ m_network_config_ptr = new NetworkConfig;
+
+ m_network_config_ptr->init(argv);
+
m_ruby_start = 0;
// Allocate to and from queues
@@ -91,7 +87,8 @@ GarnetNetwork::GarnetNetwork(int nodes)
}
// Setup the network switches
- m_topology_ptr = new Topology(this, m_nodes);
+ assert (m_topology_ptr!=NULL);
+ m_topology_ptr->makeTopology();
int number_of_routers = m_topology_ptr->numSwitches();
for (int i=0; i<number_of_routers; i++) {
@@ -188,6 +185,7 @@ void GarnetNetwork::makeInternalLink(SwitchID src, SwitchID dest, const NetDest&
void GarnetNetwork::checkNetworkAllocation(NodeID id, bool ordered, int network_num)
{
+ printf ("id = %i, m_nodes = %i \n", id, m_nodes);
ASSERT(id < m_nodes);
ASSERT(network_num < m_virtual_networks);
@@ -223,9 +221,9 @@ Time GarnetNetwork::getRubyStartTime()
void GarnetNetwork::printStats(ostream& out) const
{ double average_link_utilization = 0;
Vector<double > average_vc_load;
- average_vc_load.setSize(m_virtual_networks*NetworkConfig::getVCsPerClass());
+ average_vc_load.setSize(m_virtual_networks*m_network_config_ptr->getVCsPerClass());
- for(int i = 0; i < m_virtual_networks*NetworkConfig::getVCsPerClass(); i++)
+ for(int i = 0; i < m_virtual_networks*m_network_config_ptr->getVCsPerClass(); i++)
{
average_vc_load[i] = 0;
}
@@ -240,7 +238,7 @@ void GarnetNetwork::printStats(ostream& out) const
Vector<int > vc_load = m_link_ptr_vector[i]->getVcLoad();
for(int j = 0; j < vc_load.size(); j++)
{
- assert(vc_load.size() == NetworkConfig::getVCsPerClass()*m_virtual_networks);
+ assert(vc_load.size() == m_network_config_ptr->getVCsPerClass()*m_virtual_networks);
average_vc_load[j] += vc_load[j];
}
}
@@ -248,7 +246,7 @@ void GarnetNetwork::printStats(ostream& out) const
out << "Average Link Utilization :: " << average_link_utilization << " flits/cycle" <<endl;
out << "-------------" << endl;
- for(int i = 0; i < NetworkConfig::getVCsPerClass()*m_virtual_networks; i++)
+ for(int i = 0; i < m_network_config_ptr->getVCsPerClass()*m_virtual_networks; i++)
{
average_vc_load[i] = (double(average_vc_load[i]) / (double(g_eventQueue_ptr->getTime()) - m_ruby_start));
out << "Average VC Load [" << i << "] = " << average_vc_load[i] << " flits/cycle" << endl;
@@ -262,7 +260,7 @@ void GarnetNetwork::printConfig(ostream& out) const
out << "Network Configuration" << endl;
out << "---------------------" << endl;
out << "network: GARNET_NETWORK" << endl;
- out << "topology: " << g_NETWORK_TOPOLOGY << endl;
+ out << "topology: " << m_topology_ptr->getName() << endl;
out << endl;
for (int i = 0; i < m_virtual_networks; i++)
@@ -295,10 +293,7 @@ void GarnetNetwork::printConfig(ostream& out) const
{
m_router_ptr_vector[i]->printConfig(out);
}
- if (g_PRINT_TOPOLOGY)
- {
- m_topology_ptr->printConfig(out);
- }
+ m_topology_ptr->printConfig(out);
}
void GarnetNetwork::print(ostream& out) const
diff --git a/src/mem/ruby/network/garnet-flexible-pipeline/GarnetNetwork.hh b/src/mem/ruby/network/garnet-flexible-pipeline/GarnetNetwork.hh
index 27de3de07..194fef778 100644
--- a/src/mem/ruby/network/garnet-flexible-pipeline/GarnetNetwork.hh
+++ b/src/mem/ruby/network/garnet-flexible-pipeline/GarnetNetwork.hh
@@ -50,10 +50,15 @@ class NetworkLink;
class GarnetNetwork : public Network{
public:
- GarnetNetwork(int nodes);
+ GarnetNetwork(const string & name);
~GarnetNetwork();
+ void init(const vector<string> & argv);
+
+ //added by SS
+ NetworkConfig* getNetworkConfig() { return m_network_config_ptr; }
+
// returns the queue requested for the given component
MessageBuffer* getToNetQueue(NodeID id, bool ordered, int network_num);
MessageBuffer* getFromNetQueue(NodeID id, bool ordered, int network_num);
@@ -83,9 +88,10 @@ private:
GarnetNetwork(const GarnetNetwork& obj);
GarnetNetwork& operator=(const GarnetNetwork& obj);
+
/***********Data Members*************/
- int m_virtual_networks;
- int m_nodes;
+// int m_virtual_networks;
+// int m_nodes;
Vector<bool> m_in_use;
Vector<bool> m_ordered;
@@ -97,8 +103,10 @@ private:
Vector<NetworkLink *> m_link_ptr_vector; // All links in the network
Vector<NetworkInterface *> m_ni_ptr_vector; // All NI's in Network
- Topology* m_topology_ptr;
+// Topology* m_topology_ptr;
Time m_ruby_start;
+
+ NetworkConfig* m_network_config_ptr;
};
// Output operator declaration
diff --git a/src/mem/ruby/network/garnet-flexible-pipeline/NetworkConfig.hh b/src/mem/ruby/network/garnet-flexible-pipeline/NetworkConfig.hh
index 270fd6429..33af28a7e 100644
--- a/src/mem/ruby/network/garnet-flexible-pipeline/NetworkConfig.hh
+++ b/src/mem/ruby/network/garnet-flexible-pipeline/NetworkConfig.hh
@@ -43,14 +43,35 @@
#include "mem/ruby/config/RubyConfig.hh"
class NetworkConfig {
+ private:
+ int m_flit_size;
+ int m_number_of_pipe_stages;
+ int m_vcs_per_class;
+ int m_buffer_size;
+ bool m_using_network_testing;
public:
- static bool isGarnetNetwork() {return g_GARNET_NETWORK; }
- static bool isDetailNetwork() {return g_DETAIL_NETWORK; }
- static int isNetworkTesting() {return g_NETWORK_TESTING; }
- static int getFlitSize() {return g_FLIT_SIZE; }
- static int getNumPipeStages() {return g_NUM_PIPE_STAGES; }
- static int getVCsPerClass() {return g_VCS_PER_CLASS; }
- static int getBufferSize() {return g_BUFFER_SIZE; }
+ NetworkConfig(){}
+ void init(const vector<string> & argv) {
+ for (size_t i=0; i<argv.size(); i+=2) {
+ if (argv[i] == "flit_size")
+ m_flit_size = atoi(argv[i+1].c_str());
+ else if (argv[i] == "number_of_pipe_stages")
+ m_number_of_pipe_stages = atoi(argv[i+1].c_str());
+ else if (argv[i] == "vcs_per_class")
+ m_vcs_per_class = atoi(argv[i+1].c_str());
+ else if (argv[i] == "buffer_size")
+ m_buffer_size = atoi(argv[i+1].c_str());
+ else if (argv[i] == "using_network_testing")
+ m_using_network_testing = atoi(argv[i+1].c_str());
+ }
+ }
+// static bool isGarnetNetwork() {return RubyConfig::getUsingGarnetNetwork(); }
+// static bool isDetailNetwork() {return RubyConfig::getUsingDetailNetwork(); }
+ bool isNetworkTesting() {return m_using_network_testing; }
+ int getFlitSize() {return m_flit_size; }
+ int getNumPipeStages() {return m_number_of_pipe_stages; }
+ int getVCsPerClass() {return m_vcs_per_class; }
+ int getBufferSize() {return m_buffer_size; }
// This is no longer used. See config/rubyconfig.defaults to set Garnet parameters.
static void readNetConfig()
{
@@ -58,6 +79,9 @@ class NetworkConfig {
string filename = "network/garnet-flexible-pipeline/";
filename += NETCONFIG_DEFAULTS;
+ if (g_SIMICS) {
+ filename = "../../../ruby/"+filename;
+ }
ifstream NetconfigFile( filename.c_str(), ios::in);
if(!NetconfigFile.is_open())
{
@@ -73,19 +97,19 @@ class NetworkConfig {
getline(NetconfigFile, line, '\n');
string var = string_split(line, ':');
- if(!var.compare("g_GARNET_NETWORK"))
+ if(!var.compare("RubyConfig::getUsingGarnetNetwork()"))
{
if(!line.compare("true"))
- g_GARNET_NETWORK = true;
+ RubyConfig::getUsingGarnetNetwork() = true;
else
- g_GARNET_NETWORK = false;
+ RubyConfig::getUsingGarnetNetwork() = false;
}
- if(!var.compare("g_DETAIL_NETWORK"))
+ if(!var.compare("RubyConfig::getUsingDetailNetwork()"))
{
if(!line.compare("true"))
- g_DETAIL_NETWORK = true;
+ RubyConfig::getUsingDetailNetwork() = true;
else
- g_DETAIL_NETWORK = false;
+ RubyConfig::getUsingDetailNetwork() = false;
}
if(!var.compare("g_NETWORK_TESTING"))
{
@@ -94,27 +118,28 @@ class NetworkConfig {
else
g_NETWORK_TESTING = false;
}
- if(!var.compare("g_FLIT_SIZE"))
- g_FLIT_SIZE = atoi(line.c_str());
- if(!var.compare("g_NUM_PIPE_STAGES"))
- g_NUM_PIPE_STAGES = atoi(line.c_str());
- if(!var.compare("g_VCS_PER_CLASS"))
- g_VCS_PER_CLASS = atoi(line.c_str());
- if(!var.compare("g_BUFFER_SIZE"))
- g_BUFFER_SIZE = atoi(line.c_str());
+ if(!var.compare("RubyConfig::getFlitSize()"))
+ RubyConfig::getFlitSize() = atoi(line.c_str());
+ if(!var.compare("RubyConfig::getNumberOfPipeStages()"))
+ RubyConfig::getNumberOfPipeStages() = atoi(line.c_str());
+ if(!var.compare("RubyConfig::getVCSPerClass()"))
+ RubyConfig::getVCSPerClass() = atoi(line.c_str());
+ if(!var.compare("RubyConfig::getBufferSize()"))
+ RubyConfig::getBufferSize() = atoi(line.c_str());
}
NetconfigFile.close();
*/
/*
- cout << "g_GARNET_NETWORK = " << g_GARNET_NETWORK << endl;
- cout << "g_DETAIL_NETWORK = " << g_DETAIL_NETWORK << endl;
+ cout << "RubyConfig::getUsingGarnetNetwork() = " << RubyConfig::getUsingGarnetNetwork() << endl;
+ cout << "RubyConfig::getUsingDetailNetwork() = " << RubyConfig::getUsingDetailNetwork() << endl;
cout << "g_NETWORK_TESTING = " << g_NETWORK_TESTING << endl;
- cout << "g_FLIT_SIZE = " << g_FLIT_SIZE << endl;
- cout << "g_NUM_PIPE_STAGES = " << g_NUM_PIPE_STAGES << endl;
- cout << "g_VCS_PER_CLASS= " << g_VCS_PER_CLASS << endl;
- cout << "g_BUFFER_SIZE = " << g_BUFFER_SIZE << endl;
+ cout << "RubyConfig::getFlitSize() = " << RubyConfig::getFlitSize() << endl;
+ cout << "RubyConfig::getNumberOfPipeStages() = " << RubyConfig::getNumberOfPipeStages() << endl;
+ cout << "RubyConfig::getVCSPerClass()= " << RubyConfig::getVCSPerClass() << endl;
+ cout << "RubyConfig::getBufferSize() = " << RubyConfig::getBufferSize() << endl;
*/
}
};
+
#endif
diff --git a/src/mem/ruby/network/garnet-flexible-pipeline/NetworkInterface.cc b/src/mem/ruby/network/garnet-flexible-pipeline/NetworkInterface.cc
index b7bd2393c..119f064d3 100644
--- a/src/mem/ruby/network/garnet-flexible-pipeline/NetworkInterface.cc
+++ b/src/mem/ruby/network/garnet-flexible-pipeline/NetworkInterface.cc
@@ -27,7 +27,7 @@
*/
/*
- * NetworkInterface.C
+ * NetworkInterface.cc
*
* Niket Agarwal, Princeton University
*
@@ -43,7 +43,7 @@ NetworkInterface::NetworkInterface(int id, int virtual_networks, GarnetNetwork *
m_id = id;
m_net_ptr = network_ptr;
m_virtual_networks = virtual_networks;
- m_vc_per_vnet = NetworkConfig::getVCsPerClass();
+ m_vc_per_vnet = m_net_ptr->getNetworkConfig()->getVCsPerClass();
m_num_vcs = m_vc_per_vnet*m_virtual_networks;
m_vc_round_robin = 0;
@@ -109,7 +109,7 @@ bool NetworkInterface::flitisizeMessage(MsgPtr msg_ptr, int vnet)
NetworkMessage *net_msg_ptr = dynamic_cast<NetworkMessage*>(msg_ptr.ref());
NetDest net_msg_dest = net_msg_ptr->getInternalDestination();
Vector<NodeID> dest_nodes = net_msg_dest.getAllDest(); // gets all the destinations associated with this message.
- int num_flits = (int) ceil((double) MessageSizeType_to_int(net_msg_ptr->getMessageSize())/NetworkConfig::getFlitSize() ); // Number of flits is dependent on the link bandwidth available. This is expressed in terms of bytes/cycle or the flit size
+ int num_flits = (int) ceil((double) MessageSizeType_to_int(net_msg_ptr->getMessageSize())/m_net_ptr->getNetworkConfig()->getFlitSize() ); // Number of flits is dependent on the link bandwidth available. This is expressed in terms of bytes/cycle or the flit size
for(int ctr = 0; ctr < dest_nodes.size(); ctr++) // loop because we will be converting all multicast messages into unicast messages
{
@@ -236,7 +236,7 @@ void NetworkInterface::wakeup()
DEBUG_EXPR(NETWORK_COMP, HighPrio, m_id);
DEBUG_MSG(NETWORK_COMP, HighPrio, "Message got delivered");
DEBUG_EXPR(NETWORK_COMP, HighPrio, g_eventQueue_ptr->getTime());
- if(!NetworkConfig::isNetworkTesting()) // When we are doing network only testing, the messages do not have to be buffered into the message buffers
+ if(!m_net_ptr->getNetworkConfig()->isNetworkTesting()) // When we are doing network only testing, the messages do not have to be buffered into the message buffers
{
outNode_ptr[t_flit->get_vnet()]->enqueue(t_flit->get_msg_ptr(), 1); // enqueueing for protocol buffer. This is not required when doing network only testing
}
diff --git a/src/mem/ruby/network/garnet-flexible-pipeline/NetworkLink.cc b/src/mem/ruby/network/garnet-flexible-pipeline/NetworkLink.cc
index 90177cbec..ddc92d44c 100644
--- a/src/mem/ruby/network/garnet-flexible-pipeline/NetworkLink.cc
+++ b/src/mem/ruby/network/garnet-flexible-pipeline/NetworkLink.cc
@@ -46,8 +46,8 @@ NetworkLink::NetworkLink(int id, int latency, GarnetNetwork *net_ptr)
m_link_utilized = 0;
m_net_ptr = net_ptr;
m_latency = latency;
- int num_net = NUMBER_OF_VIRTUAL_NETWORKS;
- int num_vc = NetworkConfig::getVCsPerClass();
+ int num_net = net_ptr->getNumberOfVirtualNetworks();
+ int num_vc = m_net_ptr->getNetworkConfig()->getVCsPerClass();
m_vc_load.setSize(num_net*num_vc);
for(int i = 0; i < num_net*num_vc; i++)
diff --git a/src/mem/ruby/network/garnet-flexible-pipeline/Router.cc b/src/mem/ruby/network/garnet-flexible-pipeline/Router.cc
index 1def6f9c3..ea32e938d 100644
--- a/src/mem/ruby/network/garnet-flexible-pipeline/Router.cc
+++ b/src/mem/ruby/network/garnet-flexible-pipeline/Router.cc
@@ -43,8 +43,8 @@ Router::Router(int id, GarnetNetwork *network_ptr)
{
m_id = id;
m_net_ptr = network_ptr;
- m_virtual_networks = NUMBER_OF_VIRTUAL_NETWORKS;
- m_vc_per_vnet = NetworkConfig::getVCsPerClass();
+ m_virtual_networks = m_net_ptr->getNumberOfVirtualNetworks();
+ m_vc_per_vnet = m_net_ptr->getNetworkConfig()->getVCsPerClass();
m_round_robin_inport = 0;
m_round_robin_start = 0;
m_num_vcs = m_vc_per_vnet*m_virtual_networks;
@@ -103,7 +103,7 @@ void Router::addOutPort(NetworkLink *out_link, const NetDest& routing_table_entr
Vector<flitBuffer *> intermediateQueues;
for(int i = 0; i < m_num_vcs; i++)
{
- intermediateQueues.insertAtBottom(new flitBuffer(NetworkConfig::getBufferSize()));
+ intermediateQueues.insertAtBottom(new flitBuffer(m_net_ptr->getNetworkConfig()->getBufferSize()));
}
m_router_buffers.insertAtBottom(intermediateQueues);
@@ -246,17 +246,17 @@ void Router::routeCompute(flit *m_flit, int inport)
int outport = m_in_vc_state[inport][invc]->get_outport();
int outvc = m_in_vc_state[inport][invc]->get_outvc();
- assert(NetworkConfig::getNumPipeStages() >= 1);
- m_flit->set_time(g_eventQueue_ptr->getTime() + (NetworkConfig::getNumPipeStages() - 1)); // Becasuse 1 cycle will be consumed in scheduling the output link
+ assert(m_net_ptr->getNetworkConfig()->getNumPipeStages() >= 1);
+ m_flit->set_time(g_eventQueue_ptr->getTime() + (m_net_ptr->getNetworkConfig()->getNumPipeStages() - 1)); // Becasuse 1 cycle will be consumed in scheduling the output link
m_flit->set_vc(outvc);
m_router_buffers[outport][outvc]->insert(m_flit);
- if(NetworkConfig::getNumPipeStages() > 1)
- g_eventQueue_ptr->scheduleEvent(this, NetworkConfig::getNumPipeStages() -1 );
+ if(m_net_ptr->getNetworkConfig()->getNumPipeStages() > 1)
+ g_eventQueue_ptr->scheduleEvent(this, m_net_ptr->getNetworkConfig()->getNumPipeStages() -1 );
if((m_flit->get_type() == HEAD_) || (m_flit->get_type() == HEAD_TAIL_))
{
NetDest destination = dynamic_cast<NetworkMessage*>(m_flit->get_msg_ptr().ref())->getInternalDestination();
- if(NetworkConfig::getNumPipeStages() > 1)
+ if(m_net_ptr->getNetworkConfig()->getNumPipeStages() > 1)
{
m_out_vc_state[outport][outvc]->setState(VC_AB_, g_eventQueue_ptr->getTime() + 1);
m_out_link[outport]->request_vc_link(outvc, destination, g_eventQueue_ptr->getTime() + 1);
diff --git a/src/mem/ruby/network/simple/CustomTopology.cc b/src/mem/ruby/network/simple/CustomTopology.cc
new file mode 100644
index 000000000..829086f31
--- /dev/null
+++ b/src/mem/ruby/network/simple/CustomTopology.cc
@@ -0,0 +1,140 @@
+
+#include "mem/ruby/network/simple/CustomTopology.hh"
+#include "mem/protocol/MachineType.hh"
+
+static const int INFINITE_LATENCY = 10000; // Yes, this is a big hack
+static const int DEFAULT_BW_MULTIPLIER = 1; // Just to be consistent with above :)
+
+// make a network as described by the networkFile
+void CustomTopology::construct()
+{
+
+ Vector< Vector < SwitchID > > nodePairs; // node pairs extracted from the file
+ Vector<int> latencies; // link latencies for each link extracted
+ Vector<int> bw_multis; // bw multipliers for each link extracted
+ Vector<int> weights; // link weights used to enfore e-cube deadlock free routing
+ 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);
+
+ // initialize endpoint check vector
+ for (int k = 0; k < endpointConnectionExist.size(); k++) {
+ endpointConnectionExist[k] = false;
+ }
+
+ 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);
+ }
+ }
+
+ 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]);
+ }
+
+ // networkFile.close();
+}
diff --git a/src/mem/ruby/network/simple/CustomTopology.hh b/src/mem/ruby/network/simple/CustomTopology.hh
new file mode 100644
index 000000000..6c44eb049
--- /dev/null
+++ b/src/mem/ruby/network/simple/CustomTopology.hh
@@ -0,0 +1,17 @@
+
+#ifndef CUSTOMTOPOLOGY_H
+#define CUSTOMTOPOLOGY_H
+
+#include "mem/ruby/network/simple/Topology.hh"
+
+class CustomTopology : public Topology
+{
+public:
+ CustomTopology(const string & name);
+ void init(const vector<string> & argv);
+
+protected:
+ void construct();
+};
+
+#endif
diff --git a/src/mem/ruby/network/simple/HierarchicalSwitchTopology.cc b/src/mem/ruby/network/simple/HierarchicalSwitchTopology.cc
new file mode 100644
index 000000000..c0190e789
--- /dev/null
+++ b/src/mem/ruby/network/simple/HierarchicalSwitchTopology.cc
@@ -0,0 +1,66 @@
+
+#include "mem/ruby/network/simple/HierarchicalSwitchTopology.hh"
+
+// hierarchical switch topology
+void Topology::construct(int fan_out_degree)
+{
+ // Make a row of switches with only one input. This extra row makes
+ // sure the links out of the nodes have latency and limited
+ // bandwidth.
+
+ // number of inter-chip switches, i.e. the last row of switches
+ Vector<SwitchID> last_level;
+ for (int i=0; i<m_nodes; i++) {
+ SwitchID new_switch = newSwitchID(); // internal switch id #
+ addLink(i, new_switch, m_network_ptr->getLinkLatency());
+ last_level.insertAtBottom(new_switch);
+ }
+
+ // Create Hierarchical Switches
+
+ // start from the bottom level and work up to root
+ Vector<SwitchID> next_level;
+ while(last_level.size() > 1) {
+ for (int i=0; i<last_level.size(); i++) {
+ if ((i % fan_out_degree) == 0) {
+ next_level.insertAtBottom(newSwitchID());
+ }
+ // Add this link to the last switch we created
+ addLink(last_level[i], next_level[next_level.size()-1], m_network_ptr->getLinkLatency());
+ }
+
+ // Make the current level the last level to get ready for next
+ // iteration
+ last_level = next_level;
+ next_level.clear();
+ }
+
+ SwitchID root_switch = last_level[0];
+
+ Vector<SwitchID> out_level;
+ for (int i=0; i<m_nodes; i++) {
+ out_level.insertAtBottom(m_nodes+i);
+ }
+
+ // Build the down network from the endpoints to the root
+ while(out_level.size() != 1) {
+
+ // A level of switches
+ for (int i=0; i<out_level.size(); i++) {
+ if ((i % fan_out_degree) == 0) {
+ if (out_level.size() > fan_out_degree) {
+ next_level.insertAtBottom(newSwitchID());
+ } else {
+ next_level.insertAtBottom(root_switch);
+ }
+ }
+ // Add this link to the last switch we created
+ addLink(next_level[next_level.size()-1], out_level[i], m_network_ptr->getLinkLatency());
+ }
+
+ // Make the current level the last level to get ready for next
+ // iteration
+ out_level = next_level;
+ next_level.clear();
+ }
+}
diff --git a/src/mem/ruby/network/simple/HierarchicalSwitchTopology.hh b/src/mem/ruby/network/simple/HierarchicalSwitchTopology.hh
new file mode 100644
index 000000000..0c2c84ef8
--- /dev/null
+++ b/src/mem/ruby/network/simple/HierarchicalSwitchTopology.hh
@@ -0,0 +1,17 @@
+
+#ifndef HIERARCHICALSWITCHTOPOLOGY_H
+#define HIERARCHICALSWITCHTOPOLOGY_H
+
+#include "mem/ruby/network/simple/Topology.hh"
+
+class HierarchicalSwitchTopology : public Topology
+{
+public:
+ HierarchicalSwitchTopology(const string & name);
+ void init(const vector<string> & argv);
+
+protected:
+ void construct();
+};
+
+#endif
diff --git a/src/mem/ruby/network/simple/PerfectSwitch.cc b/src/mem/ruby/network/simple/PerfectSwitch.cc
index b561b69e2..4fd9af3eb 100644
--- a/src/mem/ruby/network/simple/PerfectSwitch.cc
+++ b/src/mem/ruby/network/simple/PerfectSwitch.cc
@@ -55,7 +55,7 @@ bool operator<(const LinkOrder& l1, const LinkOrder& l2) {
PerfectSwitch::PerfectSwitch(SwitchID sid, SimpleNetwork* network_ptr)
{
- m_virtual_networks = NUMBER_OF_VIRTUAL_NETWORKS; // FIXME - pass me as a parameter?
+ m_virtual_networks = network_ptr->getNumberOfVirtualNetworks();
m_switch_id = sid;
m_round_robin_start = 0;
m_network_ptr = network_ptr;
@@ -88,9 +88,9 @@ void PerfectSwitch::addOutPort(const Vector<MessageBuffer*>& out, const NetDest&
m_out.insertAtBottom(out);
m_routing_table.insertAtBottom(routing_table_entry);
- if (g_PRINT_TOPOLOGY) {
+ // if (RubyConfig::getPrintTopology()) {
m_out_link_vec.insertAtBottom(out);
- }
+ // }
}
void PerfectSwitch::clearRoutingTables()
@@ -134,6 +134,7 @@ void PerfectSwitch::wakeup()
int highest_prio_vnet = m_virtual_networks-1;
int lowest_prio_vnet = 0;
int decrementer = 1;
+ bool schedule_wakeup = false;
NetworkMessage* net_msg_ptr = NULL;
// invert priorities to avoid starvation seen in the component network
@@ -186,8 +187,9 @@ void PerfectSwitch::wakeup()
assert(m_link_order.size() == m_routing_table.size());
assert(m_link_order.size() == m_out.size());
-
- if (g_adaptive_routing) {
+//changed by SS
+// if (RubyConfig::getAdaptiveRouting()) {
+ if (m_network_ptr->getAdaptiveRouting()) {
if (m_network_ptr->isVNetOrdered(vnet)) {
// Don't adaptively route
for (int outlink=0; outlink<m_out.size(); outlink++) {
diff --git a/src/mem/ruby/network/simple/PtToPtTopology.cc b/src/mem/ruby/network/simple/PtToPtTopology.cc
new file mode 100644
index 000000000..9d178dbcc
--- /dev/null
+++ b/src/mem/ruby/network/simple/PtToPtTopology.cc
@@ -0,0 +1,82 @@
+
+#include "mem/protocol/MachineType.hh"
+#include "mem/ruby/network/simple/PtToPtTopology.hh"
+
+// one internal node per chip, point to point links between chips
+void PtToPtTopology::construct()
+{
+ Vector< Vector < SwitchID > > nodePairs; // node pairs extracted from the file
+ Vector<int> latencies; // link latencies for each link extracted
+ Vector<int> bw_multis; // bw multipliers for each link extracted
+
+ Vector < SwitchID > nodes;
+ nodes.setSize(2);
+
+ // number of inter-chip switches
+ int numberOfChipSwitches = m_nodes/MachineType_base_level(MachineType_NUM);
+ // two switches per machine node grouping
+ // one intra-chip switch and one inter-chip switch per chip
+ for(int i=0; i<numberOfChipSwitches; i++){
+ SwitchID new_switch = newSwitchID();
+ new_switch = newSwitchID();
+ }
+
+ makeSwitchesPerChip(nodePairs, latencies, bw_multis, numberOfChipSwitches);
+
+ // connect intra-chip switch to inter-chip switch
+ for (int chip = 0; chip < RubyConfig::getNumberOfChips(); chip++) {
+
+ int latency = m_network_ptr->getOnChipLinkLatency(); // internal link latency
+ int bw_multiplier = 10; // external link bw multiplier of the global bandwidth
+
+ nodes[0] = chip+m_nodes*2;
+ nodes[1] = chip+m_nodes*2+RubyConfig::getNumberOfChips();
+
+ // insert link
+ nodePairs.insertAtBottom(nodes);
+ latencies.insertAtBottom(latency);
+ bw_multis.insertAtBottom(bw_multiplier);
+
+ // opposite direction link
+ Vector < SwitchID > otherDirectionNodes;
+ otherDirectionNodes.setSize(2);
+ otherDirectionNodes[0] = nodes[1];
+ otherDirectionNodes[1] = nodes[0];
+ nodePairs.insertAtBottom(otherDirectionNodes);
+ latencies.insertAtBottom(latency);
+ bw_multis.insertAtBottom(bw_multiplier);
+ }
+
+ // point-to-point network between chips
+ for (int chip = 0; chip < RubyConfig::getNumberOfChips(); chip++) {
+ for (int other_chip = chip+1; other_chip < RubyConfig::getNumberOfChips(); other_chip++) {
+
+ int latency = m_network_ptr->getOffChipLinkLatency(); // external link latency
+ int bw_multiplier = 1; // external link bw multiplier of the global bandwidth
+
+ nodes[0] = chip+m_nodes*2+RubyConfig::getNumberOfChips();
+ nodes[1] = other_chip+m_nodes*2+RubyConfig::getNumberOfChips();
+
+ // insert link
+ nodePairs.insertAtBottom(nodes);
+ latencies.insertAtBottom(latency);
+ bw_multis.insertAtBottom(bw_multiplier);
+
+ // opposite direction link
+ Vector < SwitchID > otherDirectionNodes;
+ otherDirectionNodes.setSize(2);
+ otherDirectionNodes[0] = nodes[1];
+ otherDirectionNodes[1] = nodes[0];
+ nodePairs.insertAtBottom(otherDirectionNodes);
+ latencies.insertAtBottom(latency);
+ bw_multis.insertAtBottom(bw_multiplier);
+ }
+ }
+
+ // add links
+ ASSERT(nodePairs.size() == latencies.size() && latencies.size() == bw_multis.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]);
+ }
+}
diff --git a/src/mem/ruby/network/simple/PtToPtTopology.hh b/src/mem/ruby/network/simple/PtToPtTopology.hh
new file mode 100644
index 000000000..f15fa5956
--- /dev/null
+++ b/src/mem/ruby/network/simple/PtToPtTopology.hh
@@ -0,0 +1,17 @@
+
+#ifndef PTTOPTTOPOLOGY_H
+#define PTTOPTTOPOLOGY_H
+
+#include "mem/ruby/network/simple/Topology.hh"
+
+class PtToPtTopology : public Topology
+{
+public:
+ PtToPtTopology(const string & name);
+ void init(const vector<string> & argv);
+
+protected:
+ void construct();
+};
+
+#endif
diff --git a/src/mem/ruby/network/simple/SimpleNetwork.cc b/src/mem/ruby/network/simple/SimpleNetwork.cc
index 1d0567b6e..1a3b876bf 100644
--- a/src/mem/ruby/network/simple/SimpleNetwork.cc
+++ b/src/mem/ruby/network/simple/SimpleNetwork.cc
@@ -59,11 +59,55 @@ Network* Network::createNetwork(int nodes)
}
*/
+SimpleNetwork::SimpleNetwork(const string & name)
+ : Network(name)
+{
+ m_virtual_networks = 0;
+ m_topology_ptr = NULL;
+}
+
+void SimpleNetwork::init(const vector<string> & argv)
+{
+
+ Network::init(argv);
+
+ m_endpoint_switches.setSize(m_nodes);
+
+ m_in_use.setSize(m_virtual_networks);
+ m_ordered.setSize(m_virtual_networks);
+ for (int i = 0; i < m_virtual_networks; i++) {
+ m_in_use[i] = false;
+ m_ordered[i] = false;
+ }
+
+ // Allocate to and from queues
+ m_toNetQueues.setSize(m_nodes);
+ m_fromNetQueues.setSize(m_nodes);
+ for (int node = 0; node < m_nodes; node++) {
+ m_toNetQueues[node].setSize(m_virtual_networks);
+ m_fromNetQueues[node].setSize(m_virtual_networks);
+ for (int j = 0; j < m_virtual_networks; j++) {
+ cerr << "Creating new MessageBuffer for " << node << " " << j << endl;
+ m_toNetQueues[node][j] = new MessageBuffer;
+ m_fromNetQueues[node][j] = new MessageBuffer;
+ }
+ }
+
+ // Setup the network switches
+ // m_topology_ptr = new Topology(this, m_nodes);
+ m_topology_ptr->makeTopology();
+ int number_of_switches = m_topology_ptr->numSwitches();
+ 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
+}
+/*
SimpleNetwork::SimpleNetwork(int nodes)
{
m_nodes = MachineType_base_number(MachineType_NUM);
- m_virtual_networks = NUMBER_OF_VIRTUAL_NETWORKS;
+ m_virtual_networks = RubyConfig::getNumberOfVirtualNetworks();
m_endpoint_switches.setSize(m_nodes);
m_in_use.setSize(m_virtual_networks);
@@ -93,7 +137,7 @@ SimpleNetwork::SimpleNetwork(int nodes)
}
m_topology_ptr->createLinks(false); // false because this isn't a reconfiguration
}
-
+*/
void SimpleNetwork::reset()
{
for (int node = 0; node < m_nodes; node++) {
@@ -154,8 +198,8 @@ void SimpleNetwork::makeInternalLink(SwitchID src, SwitchID dest, const NetDest&
// allocate a buffer
MessageBuffer* buffer_ptr = new MessageBuffer;
buffer_ptr->setOrdering(true);
- if(FINITE_BUFFERING) {
- buffer_ptr->setSize(FINITE_BUFFER_SIZE);
+ if (m_buffer_size > 0) {
+ buffer_ptr->setSize(m_buffer_size);
}
queues.insertAtBottom(buffer_ptr);
// remember to deallocate it
@@ -225,7 +269,7 @@ void SimpleNetwork::printConfig(ostream& out) const
out << "Network Configuration" << endl;
out << "---------------------" << endl;
out << "network: SIMPLE_NETWORK" << endl;
- out << "topology: " << g_NETWORK_TOPOLOGY << endl;
+ out << "topology: " << m_topology_ptr->getName() << endl;
out << endl;
for (int i = 0; i < m_virtual_networks; i++) {
@@ -246,9 +290,7 @@ void SimpleNetwork::printConfig(ostream& out) const
m_switch_ptr_vector[i]->printConfig(out);
}
- if (g_PRINT_TOPOLOGY) {
- m_topology_ptr->printConfig(out);
- }
+ m_topology_ptr->printConfig(out);
}
void SimpleNetwork::print(ostream& out) const
diff --git a/src/mem/ruby/network/simple/SimpleNetwork.hh b/src/mem/ruby/network/simple/SimpleNetwork.hh
index 39ee2c095..9ffd862d3 100644
--- a/src/mem/ruby/network/simple/SimpleNetwork.hh
+++ b/src/mem/ruby/network/simple/SimpleNetwork.hh
@@ -83,11 +83,14 @@ class Topology;
class SimpleNetwork : public Network {
public:
// Constructors
- SimpleNetwork(int nodes);
+ // SimpleNetwork(int nodes);
+ SimpleNetwork(const string & name);
// Destructor
~SimpleNetwork();
+ void init(const vector<string> & argv);
+
// Public Methods
void printStats(ostream& out) const;
void clearStats();
@@ -130,14 +133,11 @@ private:
Vector<Vector<MessageBuffer*> > m_toNetQueues;
Vector<Vector<MessageBuffer*> > m_fromNetQueues;
- int m_nodes;
- int m_virtual_networks;
Vector<bool> m_in_use;
Vector<bool> m_ordered;
Vector<Switch*> m_switch_ptr_vector;
Vector<MessageBuffer*> m_buffers_to_free;
Vector<Switch*> m_endpoint_switches;
- Topology* m_topology_ptr;
};
// Output operator declaration
diff --git a/src/mem/ruby/network/simple/Switch.cc b/src/mem/ruby/network/simple/Switch.cc
index 192520e85..e3420ddae 100644
--- a/src/mem/ruby/network/simple/Switch.cc
+++ b/src/mem/ruby/network/simple/Switch.cc
@@ -82,8 +82,9 @@ void Switch::addOutPort(const Vector<MessageBuffer*>& out, const NetDest& routin
MessageBuffer* buffer_ptr = new MessageBuffer;
// Make these queues ordered
buffer_ptr->setOrdering(true);
- if(FINITE_BUFFERING) {
- buffer_ptr->setSize(FINITE_BUFFER_SIZE);
+ Network* net_ptr = RubySystem::getNetwork();
+ if(net_ptr->getBufferSize() > 0) {
+ buffer_ptr->setSize(net_ptr->getBufferSize());
}
intermediateBuffers.insertAtBottom(buffer_ptr);
m_buffers_to_free.insertAtBottom(buffer_ptr);
diff --git a/src/mem/ruby/network/simple/Switch.hh b/src/mem/ruby/network/simple/Switch.hh
index 58bde05ea..193898928 100644
--- a/src/mem/ruby/network/simple/Switch.hh
+++ b/src/mem/ruby/network/simple/Switch.hh
@@ -52,6 +52,7 @@ class PerfectSwitch;
class NetDest;
class SimpleNetwork;
class Throttle;
+class Network;
class Switch {
public:
@@ -83,6 +84,7 @@ private:
// Data Members (m_ prefix)
PerfectSwitch* m_perfect_switch_ptr;
+ Network* m_network_ptr;
Vector<Throttle*> m_throttles;
Vector<MessageBuffer*> m_buffers_to_free;
SwitchID m_switch_id;
diff --git a/src/mem/ruby/network/simple/Throttle.cc b/src/mem/ruby/network/simple/Throttle.cc
index f91bbdb30..1cfe88987 100644
--- a/src/mem/ruby/network/simple/Throttle.cc
+++ b/src/mem/ruby/network/simple/Throttle.cc
@@ -103,9 +103,9 @@ void Throttle::addLinks(const Vector<MessageBuffer*>& in_vec, const Vector<Messa
}
}
- if (g_PRINT_TOPOLOGY) {
+ // if (RubyConfig::getPrintTopology()) {
m_out_link_vec.insertAtBottom(out_vec);
- }
+ // }
}
void Throttle::addVirtualNetwork(MessageBuffer* in_ptr, MessageBuffer* out_ptr)
@@ -206,13 +206,8 @@ void Throttle::wakeup()
while ((current_time - m_last_bandwidth_sample) > ADJUST_INTERVAL) {
double utilization = m_bandwidth_since_sample/double(ADJUST_INTERVAL * getLinkBandwidth());
- if (utilization > g_bash_bandwidth_adaptive_threshold) {
- // Used more bandwidth
- m_bash_counter++;
- } else {
- // Used less bandwidth
- m_bash_counter--;
- }
+ // Used less bandwidth
+ m_bash_counter--;
// Make sure we don't overflow
m_bash_counter = min(HIGH_RANGE, m_bash_counter);
diff --git a/src/mem/ruby/network/simple/Throttle.hh b/src/mem/ruby/network/simple/Throttle.hh
index 067c7af5f..7b6d04353 100644
--- a/src/mem/ruby/network/simple/Throttle.hh
+++ b/src/mem/ruby/network/simple/Throttle.hh
@@ -46,7 +46,8 @@
#include "mem/gems_common/Vector.hh"
#include "mem/ruby/common/Consumer.hh"
#include "mem/ruby/system/NodeID.hh"
-#include "mem/ruby/config/RubyConfig.hh"
+#include "mem/ruby/system/System.hh"
+#include "mem/ruby/network/Network.hh"
class MessageBuffer;
@@ -68,7 +69,7 @@ public:
void clearStats();
void printConfig(ostream& out) const;
double getUtilization() const; // The average utilization (a percent) since last clearStats()
- int getLinkBandwidth() const { return g_endpoint_bandwidth * m_link_bandwidth_multiplier; }
+ int getLinkBandwidth() const { return RubySystem::getNetwork()->getEndpointBandwidth() * m_link_bandwidth_multiplier; }
int getLatency() const { return m_link_latency; }
const Vector<Vector<int> >& getCounters() const { return m_message_counters; }
diff --git a/src/mem/ruby/network/simple/Topology.cc b/src/mem/ruby/network/simple/Topology.cc
index f887f2a04..742bfe3cd 100644
--- a/src/mem/ruby/network/simple/Topology.cc
+++ b/src/mem/ruby/network/simple/Topology.cc
@@ -40,10 +40,11 @@
#include "mem/ruby/common/NetDest.hh"
#include "mem/ruby/network/Network.hh"
#include "mem/protocol/TopologyType.hh"
-#include "mem/ruby/config/RubyConfig.hh"
+//#include "mem/ruby/config/RubyConfig.hh"
#include "mem/gems_common/util.hh"
#include "mem/protocol/MachineType.hh"
#include "mem/protocol/Protocol.hh"
+#include "mem/ruby/system/System.hh"
#include <string>
static const int INFINITE_LATENCY = 10000; // Yes, this is a big hack
@@ -57,359 +58,45 @@ static const int DEFAULT_BW_MULTIPLIER = 1; // Just to be consistent with above
// of the network.
// Helper functions based on chapter 29 of Cormen et al.
-static void extend_shortest_path(Matrix& current_dist, Matrix& latencies, Matrix& inter_switches);
+static Matrix extend_shortest_path(const Matrix& current_dist, Matrix& latencies, Matrix& inter_switches);
static Matrix shortest_path(const Matrix& weights, Matrix& latencies, Matrix& inter_switches);
static bool link_is_shortest_path_to_node(SwitchID src, SwitchID next, SwitchID final, const Matrix& weights, const Matrix& dist);
static NetDest shortest_path_to_node(SwitchID src, SwitchID next, const Matrix& weights, const Matrix& dist);
-
-Topology::Topology(Network* network_ptr, int number_of_nodes)
+Topology::Topology(const string & name)
+ : m_name(name)
{
- m_network_ptr = network_ptr;
- m_nodes = number_of_nodes;
+ m_network_ptr = NULL;
+ m_nodes = MachineType_base_number(MachineType_NUM);
m_number_of_switches = 0;
- init();
-}
-
-void Topology::init()
-{
- if (m_nodes == 1) {
- SwitchID id = newSwitchID();
- addLink(0, id, NETWORK_LINK_LATENCY);
- addLink(id, 1, NETWORK_LINK_LATENCY);
- return;
- }
-
- // topology-specific set-up
- TopologyType topology = string_to_TopologyType(g_NETWORK_TOPOLOGY);
- switch (topology) {
- case TopologyType_TORUS_2D:
- make2DTorus();
- break;
- case TopologyType_HIERARCHICAL_SWITCH:
- makeHierarchicalSwitch(FAN_OUT_DEGREE);
- break;
- case TopologyType_CROSSBAR:
- makeHierarchicalSwitch(1024);
- break;
- case TopologyType_PT_TO_PT:
- makePtToPt();
- break;
- case TopologyType_FILE_SPECIFIED:
- makeFileSpecified();
- break;
- default:
- ERROR_MSG("Unexpected typology type")
- }
-
- // initialize component latencies record
- m_component_latencies.setSize(0);
- m_component_inter_switches.setSize(0);
-}
-
-void Topology::makeSwitchesPerChip(Vector< Vector < SwitchID > > &nodePairs, Vector<int> &latencies, Vector<int> &bw_multis, int numberOfChipSwitches)
-{
-
- Vector < SwitchID > nodes; // temporary buffer
- nodes.setSize(2);
-
- Vector<bool> endpointConnectionExist; // used to ensure all endpoints are connected to the network
- endpointConnectionExist.setSize(m_nodes);
- // initialize endpoint check vector
- for (int k = 0; k < endpointConnectionExist.size(); k++) {
- endpointConnectionExist[k] = false;
- }
-
- Vector<int> componentCount;
- componentCount.setSize(MachineType_NUM);
- for (MachineType mType = MachineType_FIRST; mType < MachineType_NUM; ++mType) {
- componentCount[mType] = 0;
- }
-
- // components to/from network links
- for (int chip = 0; chip < RubyConfig::numberOfChips(); chip++) {
- for (MachineType mType = MachineType_FIRST; mType < MachineType_NUM; ++mType) {
- for (int component = 0; component < MachineType_chip_count(mType, chip); component++) {
-
- int latency = -1;
- int bw_multiplier = -1; // internal link bw multiplier of the global bandwidth
- if (mType != MachineType_Directory) {
- latency = ON_CHIP_LINK_LATENCY; // internal link latency
- bw_multiplier = 10; // internal link bw multiplier of the global bandwidth
- } else {
- latency = NETWORK_LINK_LATENCY; // local memory latency
- bw_multiplier = 1; // local memory link bw multiplier of the global bandwidth
- }
- nodes[0] = MachineType_base_number(mType)+componentCount[mType];
- nodes[1] = chip+m_nodes*2; // this is the chip's internal switch id #
-
- // insert link
- nodePairs.insertAtBottom(nodes);
- latencies.insertAtBottom(latency);
- //bw_multis.insertAtBottom(bw_multiplier);
- bw_multis.insertAtBottom(componentCount[mType]+MachineType_base_number((MachineType)mType));
-
- // opposite direction link
- Vector < SwitchID > otherDirectionNodes;
- otherDirectionNodes.setSize(2);
- otherDirectionNodes[0] = nodes[1];
- otherDirectionNodes[1] = nodes[0]+m_nodes;
- nodePairs.insertAtBottom(otherDirectionNodes);
- latencies.insertAtBottom(latency);
- bw_multis.insertAtBottom(bw_multiplier);
-
- assert(!endpointConnectionExist[nodes[0]]);
- endpointConnectionExist[nodes[0]] = true;
- componentCount[mType]++;
- }
- }
- }
-
- // make 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);
- }
- }
-
- // secondary check to ensure we saw the correct machine counts
- for (MachineType mType = MachineType_FIRST; mType < MachineType_NUM; ++mType) {
- assert(componentCount[mType] == MachineType_base_count((MachineType)mType));
- }
-
-}
-
-// 2D torus topology
-
-void Topology::make2DTorus()
-{
- Vector< Vector < SwitchID > > nodePairs; // node pairs extracted from the file
- Vector<int> latencies; // link latencies for each link extracted
- Vector<int> bw_multis; // bw multipliers for each link extracted
-
- Vector < SwitchID > nodes; // temporary buffer
- nodes.setSize(2);
-
- // number of inter-chip switches
- int numberOfTorusSwitches = m_nodes/MachineType_base_level(MachineType_NUM);
- // one switch per machine node grouping
- Vector<SwitchID> torusSwitches;
- for(int i=0; i<numberOfTorusSwitches; i++){
- SwitchID new_switch = newSwitchID();
- torusSwitches.insertAtBottom(new_switch);
- }
-
- makeSwitchesPerChip(nodePairs, latencies, bw_multis, numberOfTorusSwitches);
-
- int lengthOfSide = (int)sqrt((double)numberOfTorusSwitches);
-
- // Now connect the inter-chip torus links
-
- int latency = NETWORK_LINK_LATENCY; // external link latency
- int bw_multiplier = 1; // external link bw multiplier of the global bandwidth
-
- for(int i=0; i<numberOfTorusSwitches; i++){
- nodes[0] = torusSwitches[i]; // current switch
-
- // left
- if(nodes[0]%lengthOfSide == 0){ // determine left neighbor
- nodes[1] = nodes[0] - 1 + lengthOfSide;
- } else {
- nodes[1] = nodes[0] - 1;
- }
- nodePairs.insertAtBottom(nodes);
- latencies.insertAtBottom(latency);
- bw_multis.insertAtBottom(bw_multiplier);
-
- // right
- if((nodes[0] + 1)%lengthOfSide == 0){ // determine right neighbor
- nodes[1] = nodes[0] + 1 - lengthOfSide;
- } else {
- nodes[1] = nodes[0] + 1;
- }
- nodePairs.insertAtBottom(nodes);
- latencies.insertAtBottom(latency);
- bw_multis.insertAtBottom(bw_multiplier);
-
- // top
- if(nodes[0] - lengthOfSide < 2*m_nodes){ // determine if node is on the top
- nodes[1] = nodes[0] - lengthOfSide + (lengthOfSide*lengthOfSide);
- } else {
- nodes[1] = nodes[0] - lengthOfSide;
- }
- nodePairs.insertAtBottom(nodes);
- latencies.insertAtBottom(latency);
- bw_multis.insertAtBottom(bw_multiplier);
-
- // bottom
- if(nodes[0] + lengthOfSide >= 2*m_nodes+numberOfTorusSwitches){ // determine if node is on the bottom
- // sorin: bad bug if this is a > instead of a >=
- nodes[1] = nodes[0] + lengthOfSide - (lengthOfSide*lengthOfSide);
- } else {
- nodes[1] = nodes[0] + lengthOfSide;
- }
- nodePairs.insertAtBottom(nodes);
- latencies.insertAtBottom(latency);
- bw_multis.insertAtBottom(bw_multiplier);
-
- }
-
- // add links
- ASSERT(nodePairs.size() == latencies.size() && latencies.size() == bw_multis.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]);
- }
-
}
-// hierarchical switch topology
-void Topology::makeHierarchicalSwitch(int fan_out_degree)
+void Topology::init(const vector<string> & argv)
{
- // Make a row of switches with only one input. This extra row makes
- // sure the links out of the nodes have latency and limited
- // bandwidth.
-
- // number of inter-chip switches, i.e. the last row of switches
- Vector<SwitchID> last_level;
- for (int i=0; i<m_nodes; i++) {
- SwitchID new_switch = newSwitchID(); // internal switch id #
- addLink(i, new_switch, NETWORK_LINK_LATENCY);
- last_level.insertAtBottom(new_switch);
- }
-
- // Create Hierarchical Switches
-
- // start from the bottom level and work up to root
- Vector<SwitchID> next_level;
- while(last_level.size() > 1) {
- for (int i=0; i<last_level.size(); i++) {
- if ((i % fan_out_degree) == 0) {
- next_level.insertAtBottom(newSwitchID());
- }
- // Add this link to the last switch we created
- addLink(last_level[i], next_level[next_level.size()-1], NETWORK_LINK_LATENCY);
- }
-
- // Make the current level the last level to get ready for next
- // iteration
- last_level = next_level;
- next_level.clear();
- }
-
- SwitchID root_switch = last_level[0];
-
- Vector<SwitchID> out_level;
- for (int i=0; i<m_nodes; i++) {
- out_level.insertAtBottom(m_nodes+i);
- }
-
- // Build the down network from the endpoints to the root
- while(out_level.size() != 1) {
-
- // A level of switches
- for (int i=0; i<out_level.size(); i++) {
- if ((i % fan_out_degree) == 0) {
- if (out_level.size() > fan_out_degree) {
- next_level.insertAtBottom(newSwitchID());
- } else {
- next_level.insertAtBottom(root_switch);
- }
- }
- // Add this link to the last switch we created
- addLink(next_level[next_level.size()-1], out_level[i], NETWORK_LINK_LATENCY);
+ for (size_t i=0; i<argv.size(); i+=2) {
+ if (argv[i] == "network")
+ m_network_ptr = RubySystem::getNetwork();
+ else if (argv[i] == "connections")
+ m_connections = argv[i+1];
+ else if (argv[i] == "print_config") {
+ m_print_config = string_to_bool(argv[i+1]);
+ cerr << "print config: " << m_print_config << endl;
}
-
- // Make the current level the last level to get ready for next
- // iteration
- out_level = next_level;
- next_level.clear();
}
+ assert(m_network_ptr != NULL);
}
-// one internal node per chip, point to point links between chips
-void Topology::makePtToPt()
+void Topology::makeTopology()
{
- Vector< Vector < SwitchID > > nodePairs; // node pairs extracted from the file
- Vector<int> latencies; // link latencies for each link extracted
- Vector<int> bw_multis; // bw multipliers for each link extracted
-
- Vector < SwitchID > nodes;
- nodes.setSize(2);
-
- // number of inter-chip switches
- int numberOfChipSwitches = m_nodes/MachineType_base_level(MachineType_NUM);
- // two switches per machine node grouping
- // one intra-chip switch and one inter-chip switch per chip
- for(int i=0; i<numberOfChipSwitches; i++){
- SwitchID new_switch = newSwitchID();
- new_switch = newSwitchID();
- }
-
- makeSwitchesPerChip(nodePairs, latencies, bw_multis, numberOfChipSwitches);
-
- // connect intra-chip switch to inter-chip switch
- for (int chip = 0; chip < RubyConfig::numberOfChips(); chip++) {
-
- int latency = ON_CHIP_LINK_LATENCY; // internal link latency
- int bw_multiplier = 10; // external link bw multiplier of the global bandwidth
-
- nodes[0] = chip+m_nodes*2;
- nodes[1] = chip+m_nodes*2+RubyConfig::numberOfChips();
-
- // insert link
- nodePairs.insertAtBottom(nodes);
- latencies.insertAtBottom(latency);
- bw_multis.insertAtBottom(bw_multiplier);
-
- // opposite direction link
- Vector < SwitchID > otherDirectionNodes;
- otherDirectionNodes.setSize(2);
- otherDirectionNodes[0] = nodes[1];
- otherDirectionNodes[1] = nodes[0];
- nodePairs.insertAtBottom(otherDirectionNodes);
- latencies.insertAtBottom(latency);
- bw_multis.insertAtBottom(bw_multiplier);
- }
-
- // point-to-point network between chips
- for (int chip = 0; chip < RubyConfig::numberOfChips(); chip++) {
- for (int other_chip = chip+1; other_chip < RubyConfig::numberOfChips(); other_chip++) {
-
- int latency = NETWORK_LINK_LATENCY; // external link latency
- int bw_multiplier = 1; // external link bw multiplier of the global bandwidth
-
- nodes[0] = chip+m_nodes*2+RubyConfig::numberOfChips();
- nodes[1] = other_chip+m_nodes*2+RubyConfig::numberOfChips();
-
- // insert link
- nodePairs.insertAtBottom(nodes);
- latencies.insertAtBottom(latency);
- bw_multis.insertAtBottom(bw_multiplier);
-
- // opposite direction link
- Vector < SwitchID > otherDirectionNodes;
- otherDirectionNodes.setSize(2);
- otherDirectionNodes[0] = nodes[1];
- otherDirectionNodes[1] = nodes[0];
- nodePairs.insertAtBottom(otherDirectionNodes);
- latencies.insertAtBottom(latency);
- bw_multis.insertAtBottom(bw_multiplier);
- }
- }
-
- // add links
- ASSERT(nodePairs.size() == latencies.size() && latencies.size() == bw_multis.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]);
+ /*
+ if (m_nodes == 1) {
+ SwitchID id = newSwitchID();
+ addLink(0, id, m_network_ptr->getOffChipLinkLatency());
+ addLink(id, 1, m_network_ptr->getOffChipLinkLatency());
+ return;
}
-}
-
-// make a network as described by the networkFile
-void Topology::makeFileSpecified()
-{
+ */
+ assert(m_nodes > 1);
Vector< Vector < SwitchID > > nodePairs; // node pairs extracted from the file
Vector<int> latencies; // link latencies for each link extracted
@@ -425,21 +112,7 @@ void Topology::makeFileSpecified()
endpointConnectionExist[k] = false;
}
- string filename = "network/simple/Network_Files/";
- filename = filename+g_CACHE_DESIGN
- +"_Procs-"+int_to_string(RubyConfig::numberOfProcessors())
- +"_ProcsPerChip-"+int_to_string(RubyConfig::numberOfProcsPerChip())
- +"_L2Banks-"+int_to_string(RubyConfig::numberOfL2Cache())
- +"_Memories-"+int_to_string(RubyConfig::numberOfMemories())
- +".txt";
-
- ifstream networkFile( filename.c_str() , ios::in);
- if (!networkFile.is_open()) {
- cerr << "Error: Could not open network file: " << filename << endl;
- cerr << "Probably no network file exists for " << RubyConfig::numberOfProcessors()
- << " processors and " << RubyConfig::numberOfProcsPerChip() << " procs per chip " << endl;
- exit(1);
- }
+ stringstream networkFile( m_connections );
string line = "";
@@ -468,14 +141,9 @@ void Topology::makeFileSpecified()
if (label == "ext_node") { // input link to node
MachineType machine = string_to_MachineType(string_split(varStr, ':'));
string nodeStr = string_split(varStr, ':');
- if (string_split(varStr, ':') == "bank") {
- nodes[i] = MachineType_base_number(machine)
- + atoi(nodeStr.c_str())
- + atoi((string_split(varStr, ':')).c_str())*RubyConfig::numberOfChips();
- } else {
- nodes[i] = MachineType_base_number(machine)
- + atoi(nodeStr.c_str());
- }
+ 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;
@@ -504,16 +172,6 @@ void Topology::makeFileSpecified()
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 if (label == "processors") {
- ASSERT(atoi((string_split(varStr, ':')).c_str()) == RubyConfig::numberOfProcessors());
- } else if (label == "bw_unit") {
- ASSERT(atoi((string_split(varStr, ':')).c_str()) == g_endpoint_bandwidth);
- } else if (label == "procs_per_chip") {
- ASSERT(atoi((string_split(varStr, ':')).c_str()) == RubyConfig::numberOfProcsPerChip());
- } else if (label == "L2banks") {
- ASSERT(atoi((string_split(varStr, ':')).c_str()) == RubyConfig::numberOfL2Cache());
- } else if (label == "memories") {
- ASSERT(atoi((string_split(varStr, ':')).c_str()) == RubyConfig::numberOfMemories());
} else {
cerr << "Error: Unexpected Identifier: " << label << endl;
exit(1);
@@ -567,9 +225,12 @@ void Topology::makeFileSpecified()
addLink(nodePairs[k][0], nodePairs[k][1], latencies[k], bw_multis[k], weights[k]);
}
- networkFile.close();
+ // initialize component latencies record
+ m_component_latencies.setSize(0);
+ m_component_inter_switches.setSize(0);
}
+
void Topology::createLinks(bool isReconfiguration)
{
// Find maximum switchID
@@ -633,6 +294,82 @@ void Topology::createLinks(bool isReconfiguration)
}
}
}
+/*
+void Topology::makeSwitchesPerChip(Vector< Vector < SwitchID > > &nodePairs, Vector<int> &latencies, Vector<int> &bw_multis, int numberOfChipSwitches)
+{
+
+ Vector < SwitchID > nodes; // temporary buffer
+ nodes.setSize(2);
+
+ Vector<bool> endpointConnectionExist; // used to ensure all endpoints are connected to the network
+ endpointConnectionExist.setSize(m_nodes);
+ // initialize endpoint check vector
+ for (int k = 0; k < endpointConnectionExist.size(); k++) {
+ endpointConnectionExist[k] = false;
+ }
+
+ Vector<int> componentCount;
+ componentCount.setSize(MachineType_NUM);
+ for (MachineType mType = MachineType_FIRST; mType < MachineType_NUM; ++mType) {
+ componentCount[mType] = 0;
+ }
+
+ // components to/from network links
+ // TODO: drh5: bring back chips!!!
+ for (int chip = 0; chip < RubyConfig::getNumberOfChips(); chip++) {
+ for (MachineType mType = MachineType_FIRST; mType < MachineType_NUM; ++mType) {
+ for (int component = 0; component < MachineType_base_count(mType); component++) {
+
+ int latency = -1;
+ int bw_multiplier = -1; // internal link bw multiplier of the global bandwidth
+ if (mType != MachineType_Directory) {
+ latency = RubyConfig::getOnChipLinkLatency(); // internal link latency
+ bw_multiplier = 10; // internal link bw multiplier of the global bandwidth
+ } else {
+ latency = RubyConfig::getNetworkLinkLatency(); // local memory latency
+ bw_multiplier = 1; // local memory link bw multiplier of the global bandwidth
+ }
+ nodes[0] = MachineType_base_number(mType)+componentCount[mType];
+ nodes[1] = chip+m_nodes*2; // this is the chip's internal switch id #
+
+ // insert link
+ nodePairs.insertAtBottom(nodes);
+ latencies.insertAtBottom(latency);
+ bw_multis.insertAtBottom(bw_multiplier);
+ //bw_multis.insertAtBottom(componentCount[mType]+MachineType_base_number((MachineType)mType));
+
+ // opposite direction link
+ Vector < SwitchID > otherDirectionNodes;
+ otherDirectionNodes.setSize(2);
+ otherDirectionNodes[0] = nodes[1];
+ otherDirectionNodes[1] = nodes[0]+m_nodes;
+ nodePairs.insertAtBottom(otherDirectionNodes);
+ latencies.insertAtBottom(latency);
+ bw_multis.insertAtBottom(bw_multiplier);
+
+ assert(!endpointConnectionExist[nodes[0]]);
+ endpointConnectionExist[nodes[0]] = true;
+ componentCount[mType]++;
+ }
+ }
+ }
+
+ // make 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);
+ }
+ }
+
+ // secondary check to ensure we saw the correct machine counts
+ for (MachineType mType = MachineType_FIRST; mType < MachineType_NUM; ++mType) {
+ assert(componentCount[mType] == MachineType_base_count((MachineType)mType));
+ }
+
+}
+*/
+
SwitchID Topology::newSwitchID()
{
@@ -680,6 +417,8 @@ void Topology::makeLink(SwitchID src, SwitchID dest, const NetDest& routing_tabl
void Topology::printConfig(ostream& out) const
{
+ if (m_print_config == false) return;
+
assert(m_component_latencies.size() > 0);
out << "--- Begin Topology Print ---" << endl;
diff --git a/src/mem/ruby/network/simple/Topology.hh b/src/mem/ruby/network/simple/Topology.hh
index cb6c36f17..0f8cdff3b 100644
--- a/src/mem/ruby/network/simple/Topology.hh
+++ b/src/mem/ruby/network/simple/Topology.hh
@@ -59,21 +59,26 @@ typedef Vector < Vector <int> > Matrix;
class Topology {
public:
// Constructors
- Topology(Network* network_ptr, int number_of_nodes);
+ // Topology(Network* network_ptr, int number_of_nodes);
+ Topology(const string & name);
// Destructor
- ~Topology() {}
+ virtual ~Topology() {}
+
+ virtual void init(const vector<string> & argv);
// Public Methods
+ void makeTopology();
int numSwitches() const { return m_number_of_switches; }
void createLinks(bool isReconfiguration);
+ const string getName() { return m_name; }
void printStats(ostream& out) const {}
void clearStats() {}
void printConfig(ostream& out) const;
void print(ostream& out) const { out << "[Topology]"; }
-private:
+protected:
// Private Methods
void init();
SwitchID newSwitchID();
@@ -82,12 +87,7 @@ private:
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 makeHierarchicalSwitch(int fan_out_degree);
- void make2DTorus();
- void makePtToPt();
- void makeFileSpecified();
-
- void makeSwitchesPerChip(Vector< Vector < SwitchID > > &nodePairs, Vector<int> &latencies, Vector<int> &bw_multis, int numberOfChips);
+ // void makeSwitchesPerChip(Vector< Vector < SwitchID > > &nodePairs, Vector<int> &latencies, Vector<int> &bw_multis, int numberOfChips);
string getDesignStr();
// Private copy constructor and assignment operator
@@ -95,7 +95,10 @@ private:
Topology& operator=(const Topology& obj);
// 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;
diff --git a/src/mem/ruby/network/simple/Torus2DTopology.cc b/src/mem/ruby/network/simple/Torus2DTopology.cc
new file mode 100644
index 000000000..e66c6dc0b
--- /dev/null
+++ b/src/mem/ruby/network/simple/Torus2DTopology.cc
@@ -0,0 +1,84 @@
+
+// 2D torus topology
+
+void Torus2DTopology::construct()
+{
+ Vector< Vector < SwitchID > > nodePairs; // node pairs extracted from the file
+ Vector<int> latencies; // link latencies for each link extracted
+ Vector<int> bw_multis; // bw multipliers for each link extracted
+
+ Vector < SwitchID > nodes; // temporary buffer
+ nodes.setSize(2);
+
+ // number of inter-chip switches
+ int numberOfTorusSwitches = m_nodes/MachineType_base_level(MachineType_NUM);
+ // one switch per machine node grouping
+ Vector<SwitchID> torusSwitches;
+ for(int i=0; i<numberOfTorusSwitches; i++){
+ SwitchID new_switch = newSwitchID();
+ torusSwitches.insertAtBottom(new_switch);
+ }
+
+ makeSwitchesPerChip(nodePairs, latencies, bw_multis, numberOfTorusSwitches);
+
+ int lengthOfSide = (int)sqrt((double)numberOfTorusSwitches);
+
+ // Now connect the inter-chip torus links
+
+ int latency = m_network_ptr->getLinkLatency(); // external link latency
+ int bw_multiplier = 1; // external link bw multiplier of the global bandwidth
+
+ for(int i=0; i<numberOfTorusSwitches; i++){
+ nodes[0] = torusSwitches[i]; // current switch
+
+ // left
+ if(nodes[0]%lengthOfSide == 0){ // determine left neighbor
+ nodes[1] = nodes[0] - 1 + lengthOfSide;
+ } else {
+ nodes[1] = nodes[0] - 1;
+ }
+ nodePairs.insertAtBottom(nodes);
+ latencies.insertAtBottom(latency);
+ bw_multis.insertAtBottom(bw_multiplier);
+
+ // right
+ if((nodes[0] + 1)%lengthOfSide == 0){ // determine right neighbor
+ nodes[1] = nodes[0] + 1 - lengthOfSide;
+ } else {
+ nodes[1] = nodes[0] + 1;
+ }
+ nodePairs.insertAtBottom(nodes);
+ latencies.insertAtBottom(latency);
+ bw_multis.insertAtBottom(bw_multiplier);
+
+ // top
+ if(nodes[0] - lengthOfSide < 2*m_nodes){ // determine if node is on the top
+ nodes[1] = nodes[0] - lengthOfSide + (lengthOfSide*lengthOfSide);
+ } else {
+ nodes[1] = nodes[0] - lengthOfSide;
+ }
+ nodePairs.insertAtBottom(nodes);
+ latencies.insertAtBottom(latency);
+ bw_multis.insertAtBottom(bw_multiplier);
+
+ // bottom
+ if(nodes[0] + lengthOfSide >= 2*m_nodes+numberOfTorusSwitches){ // determine if node is on the bottom
+ // sorin: bad bug if this is a > instead of a >=
+ nodes[1] = nodes[0] + lengthOfSide - (lengthOfSide*lengthOfSide);
+ } else {
+ nodes[1] = nodes[0] + lengthOfSide;
+ }
+ nodePairs.insertAtBottom(nodes);
+ latencies.insertAtBottom(latency);
+ bw_multis.insertAtBottom(bw_multiplier);
+
+ }
+
+ // add links
+ ASSERT(nodePairs.size() == latencies.size() && latencies.size() == bw_multis.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]);
+ }
+
+}
diff --git a/src/mem/ruby/network/simple/Torus2DTopology.hh b/src/mem/ruby/network/simple/Torus2DTopology.hh
new file mode 100644
index 000000000..83a314e94
--- /dev/null
+++ b/src/mem/ruby/network/simple/Torus2DTopology.hh
@@ -0,0 +1,17 @@
+
+#ifndef TORUS2DTOPOLOGY_H
+#define TORUS2DTOPOLOGY_H
+
+#include "mem/ruby/network/simple/Topology.hh"
+
+class Torus2DTopology : public Topology
+{
+public:
+ Torus2DTopology(const string & name);
+ void init(const vector<string> & argv);
+
+protected:
+ void construct();
+};
+
+#endif