a88263c62e17b149b2e8ad882aaecba14f13c210
2 * Copyright (c) 2008 Princeton University
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are
7 * met: redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer;
9 * redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution;
12 * neither the name of the copyright holders nor the names of its
13 * contributors may be used to endorse or promote products derived from
14 * this software without specific prior written permission.
16 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 * Authors: Niket Agarwal
31 #include "mem/ruby/network/garnet/flexible-pipeline/GarnetNetwork.hh"
32 #include "mem/protocol/MachineType.hh"
33 #include "mem/ruby/network/garnet/flexible-pipeline/NetworkInterface.hh"
34 #include "mem/ruby/buffers/MessageBuffer.hh"
35 #include "mem/ruby/network/garnet/flexible-pipeline/Router.hh"
36 #include "mem/ruby/network/simple/Topology.hh"
37 #include "mem/ruby/network/simple/SimpleNetwork.hh"
38 #include "mem/ruby/network/garnet/fixed-pipeline/GarnetNetwork_d.hh"
39 #include "mem/ruby/network/garnet/flexible-pipeline/NetworkLink.hh"
40 #include "mem/ruby/common/NetDest.hh"
42 GarnetNetwork::GarnetNetwork(const string
& name
)
47 void GarnetNetwork::init()
52 // assert (m_topology_ptr!=NULL);
54 m_network_config_ptr
= new NetworkConfig
;
56 m_network_config_ptr
->init(argv
);
60 // Allocate to and from queues
61 m_toNetQueues
.setSize(m_nodes
); // Queues that are getting messages from protocol
62 m_fromNetQueues
.setSize(m_nodes
); // Queues that are feeding the protocol
63 m_in_use
.setSize(m_virtual_networks
);
64 m_ordered
.setSize(m_virtual_networks
);
65 for (int i
= 0; i
< m_virtual_networks
; i
++)
71 for (int node
= 0; node
< m_nodes
; node
++)
73 //Setting how many vitual message buffers will there be per Network Queue
74 m_toNetQueues
[node
].setSize(m_virtual_networks
);
75 m_fromNetQueues
[node
].setSize(m_virtual_networks
);
77 for (int j
= 0; j
< m_virtual_networks
; j
++)
79 m_toNetQueues
[node
][j
] = new MessageBuffer(); // Instantiating the Message Buffers that interact with the coherence protocol
80 m_fromNetQueues
[node
][j
] = new MessageBuffer();
84 // Setup the network switches
85 assert (m_topology_ptr
!=NULL
);
86 m_topology_ptr
->makeTopology();
88 int number_of_routers
= m_topology_ptr
->numSwitches();
89 for (int i
=0; i
<number_of_routers
; i
++) {
90 m_router_ptr_vector
.insertAtBottom(new Router(i
, this));
93 for (int i
=0; i
< m_nodes
; i
++) {
94 NetworkInterface
*ni
= new NetworkInterface(i
, m_virtual_networks
, this);
95 ni
->addNode(m_toNetQueues
[i
], m_fromNetQueues
[i
]);
96 m_ni_ptr_vector
.insertAtBottom(ni
);
98 m_topology_ptr
->createLinks(this, false); // false because this isn't a reconfiguration
101 GarnetNetwork::~GarnetNetwork()
103 for (int i
= 0; i
< m_nodes
; i
++)
105 m_toNetQueues
[i
].deletePointers();
106 m_fromNetQueues
[i
].deletePointers();
108 m_router_ptr_vector
.deletePointers();
109 m_ni_ptr_vector
.deletePointers();
110 m_link_ptr_vector
.deletePointers();
111 delete m_topology_ptr
;
114 void GarnetNetwork::reset()
116 for (int node
= 0; node
< m_nodes
; node
++)
118 for (int j
= 0; j
< m_virtual_networks
; j
++)
120 m_toNetQueues
[node
][j
]->clear();
121 m_fromNetQueues
[node
][j
]->clear();
126 void GarnetNetwork::makeInLink(NodeID src
, SwitchID dest
, const NetDest
& routing_table_entry
, int link_latency
, int bw_multiplier
, bool isReconfiguration
)
128 assert(src
< m_nodes
);
130 if(!isReconfiguration
)
132 NetworkLink
*net_link
= new NetworkLink(m_link_ptr_vector
.size(), link_latency
, this);
133 m_link_ptr_vector
.insertAtBottom(net_link
);
134 m_router_ptr_vector
[dest
]->addInPort(net_link
);
135 m_ni_ptr_vector
[src
]->addOutPort(net_link
);
139 ERROR_MSG("Fatal Error:: Reconfiguration not allowed here");
144 void GarnetNetwork::makeOutLink(SwitchID src
, NodeID dest
, const NetDest
& routing_table_entry
, int link_latency
, int link_weight
, int bw_multiplier
, bool isReconfiguration
)
146 assert(dest
< m_nodes
);
147 assert(src
< m_router_ptr_vector
.size());
148 assert(m_router_ptr_vector
[src
] != NULL
);
150 if(!isReconfiguration
)
152 NetworkLink
*net_link
= new NetworkLink(m_link_ptr_vector
.size(), link_latency
, this);
153 m_link_ptr_vector
.insertAtBottom(net_link
);
154 m_router_ptr_vector
[src
]->addOutPort(net_link
, routing_table_entry
, link_weight
);
155 m_ni_ptr_vector
[dest
]->addInPort(net_link
);
159 ERROR_MSG("Fatal Error:: Reconfiguration not allowed here");
164 void GarnetNetwork::makeInternalLink(SwitchID src
, SwitchID dest
, const NetDest
& routing_table_entry
, int link_latency
, int link_weight
, int bw_multiplier
, bool isReconfiguration
)
166 if(!isReconfiguration
)
168 NetworkLink
*net_link
= new NetworkLink(m_link_ptr_vector
.size(), link_latency
, this);
169 m_link_ptr_vector
.insertAtBottom(net_link
);
170 m_router_ptr_vector
[dest
]->addInPort(net_link
);
171 m_router_ptr_vector
[src
]->addOutPort(net_link
, routing_table_entry
, link_weight
);
175 ERROR_MSG("Fatal Error:: Reconfiguration not allowed here");
181 void GarnetNetwork::checkNetworkAllocation(NodeID id
, bool ordered
, int network_num
)
183 printf ("id = %i, m_nodes = %i \n", id
, m_nodes
);
184 ASSERT(id
< m_nodes
);
185 ASSERT(network_num
< m_virtual_networks
);
189 m_ordered
[network_num
] = true;
191 m_in_use
[network_num
] = true;
194 MessageBuffer
* GarnetNetwork::getToNetQueue(NodeID id
, bool ordered
, int network_num
)
196 checkNetworkAllocation(id
, ordered
, network_num
);
197 return m_toNetQueues
[id
][network_num
];
200 MessageBuffer
* GarnetNetwork::getFromNetQueue(NodeID id
, bool ordered
, int network_num
)
202 checkNetworkAllocation(id
, ordered
, network_num
);
203 return m_fromNetQueues
[id
][network_num
];
206 void GarnetNetwork::clearStats()
208 m_ruby_start
= g_eventQueue_ptr
->getTime();
211 Time
GarnetNetwork::getRubyStartTime()
216 void GarnetNetwork::printStats(ostream
& out
) const
217 { double average_link_utilization
= 0;
218 Vector
<double > average_vc_load
;
219 average_vc_load
.setSize(m_virtual_networks
*m_network_config_ptr
->getVCsPerClass());
221 for(int i
= 0; i
< m_virtual_networks
*m_network_config_ptr
->getVCsPerClass(); i
++)
223 average_vc_load
[i
] = 0;
227 out
<< "Network Stats" << endl
;
228 out
<< "-------------" << endl
;
230 for(int i
= 0; i
< m_link_ptr_vector
.size(); i
++)
232 average_link_utilization
+= m_link_ptr_vector
[i
]->getLinkUtilization();
233 Vector
<int > vc_load
= m_link_ptr_vector
[i
]->getVcLoad();
234 for(int j
= 0; j
< vc_load
.size(); j
++)
236 assert(vc_load
.size() == m_network_config_ptr
->getVCsPerClass()*m_virtual_networks
);
237 average_vc_load
[j
] += vc_load
[j
];
240 average_link_utilization
= average_link_utilization
/m_link_ptr_vector
.size();
241 out
<< "Average Link Utilization :: " << average_link_utilization
<< " flits/cycle" <<endl
;
242 out
<< "-------------" << endl
;
244 for(int i
= 0; i
< m_network_config_ptr
->getVCsPerClass()*m_virtual_networks
; i
++)
246 average_vc_load
[i
] = (double(average_vc_load
[i
]) / (double(g_eventQueue_ptr
->getTime()) - m_ruby_start
));
247 out
<< "Average VC Load [" << i
<< "] = " << average_vc_load
[i
] << " flits/cycle" << endl
;
249 out
<< "-------------" << endl
;
252 void GarnetNetwork::printConfig(ostream
& out
) const
255 out
<< "Network Configuration" << endl
;
256 out
<< "---------------------" << endl
;
257 out
<< "network: GARNET_NETWORK" << endl
;
258 out
<< "topology: " << m_topology_ptr
->getName() << endl
;
261 for (int i
= 0; i
< m_virtual_networks
; i
++)
263 out
<< "virtual_net_" << i
<< ": ";
269 out
<< "ordered" << endl
;
273 out
<< "unordered" << endl
;
278 out
<< "inactive" << endl
;
283 for(int i
= 0; i
< m_ni_ptr_vector
.size(); i
++)
285 m_ni_ptr_vector
[i
]->printConfig(out
);
287 for(int i
= 0; i
< m_router_ptr_vector
.size(); i
++)
289 m_router_ptr_vector
[i
]->printConfig(out
);
291 m_topology_ptr
->printConfig(out
);
294 void GarnetNetwork::print(ostream
& out
) const
296 out
<< "[GarnetNetwork]";