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
33 #include "base/stl_helpers.hh"
34 #include "mem/ruby/network/garnet/fixed-pipeline/GarnetNetwork_d.hh"
35 #include "mem/protocol/MachineType.hh"
36 #include "mem/ruby/network/garnet/fixed-pipeline/NetworkInterface_d.hh"
37 #include "mem/ruby/buffers/MessageBuffer.hh"
38 #include "mem/ruby/network/garnet/fixed-pipeline/Router_d.hh"
39 #include "mem/ruby/network/simple/Topology.hh"
40 #include "mem/ruby/network/garnet/fixed-pipeline/NetworkLink_d.hh"
41 #include "mem/ruby/network/garnet/fixed-pipeline/CreditLink_d.hh"
42 #include "mem/ruby/common/NetDest.hh"
45 using m5::stl_helpers::deletePointers
;
47 GarnetNetwork_d::GarnetNetwork_d(const Params
*p
)
48 : BaseGarnetNetwork(p
)
53 m_network_latency
= 0.0;
54 m_queueing_latency
= 0.0;
56 m_router_ptr_vector
.clear();
58 // Queues that are getting messages from protocol
59 m_toNetQueues
.resize(m_nodes
);
61 // Queues that are feeding the protocol
62 m_fromNetQueues
.resize(m_nodes
);
63 m_in_use
.resize(m_virtual_networks
);
64 m_ordered
.resize(m_virtual_networks
);
65 for (int i
= 0; i
< m_virtual_networks
; i
++) {
70 for (int node
= 0; node
< m_nodes
; node
++) {
71 // Setting how many vitual message buffers
72 // will there be per Network Queue
73 m_toNetQueues
[node
].resize(m_virtual_networks
);
74 m_fromNetQueues
[node
].resize(m_virtual_networks
);
76 // Instantiating the Message Buffers
77 // that interact with the coherence protocol
78 for (int j
= 0; j
< m_virtual_networks
; j
++) {
79 m_toNetQueues
[node
][j
] = new MessageBuffer();
80 m_fromNetQueues
[node
][j
] = new MessageBuffer();
86 GarnetNetwork_d::init()
88 BaseGarnetNetwork::init();
90 // The topology pointer should have already been initialized in the
91 // parent network constructor
92 assert(m_topology_ptr
!= NULL
);
94 int number_of_routers
= m_topology_ptr
->numSwitches();
95 for (int i
=0; i
<number_of_routers
; i
++) {
96 m_router_ptr_vector
.push_back(new Router_d(i
, this));
99 for (int i
=0; i
< m_nodes
; i
++) {
100 NetworkInterface_d
*ni
= new NetworkInterface_d(i
, m_virtual_networks
,
102 ni
->addNode(m_toNetQueues
[i
], m_fromNetQueues
[i
]);
103 m_ni_ptr_vector
.push_back(ni
);
105 // false because this isn't a reconfiguration
106 m_topology_ptr
->createLinks(this, false);
107 for (int i
= 0; i
< m_router_ptr_vector
.size(); i
++) {
108 m_router_ptr_vector
[i
]->init();
111 m_vnet_type
.resize(m_virtual_networks
);
112 for (int i
= 0; i
< m_vnet_type
.size(); i
++) {
113 m_vnet_type
[i
] = CTRL_VNET_
;
114 // DATA_VNET_ updated later based on traffic
118 GarnetNetwork_d::~GarnetNetwork_d()
120 for (int i
= 0; i
< m_nodes
; i
++) {
121 deletePointers(m_toNetQueues
[i
]);
122 deletePointers(m_fromNetQueues
[i
]);
124 deletePointers(m_router_ptr_vector
);
125 deletePointers(m_ni_ptr_vector
);
126 deletePointers(m_link_ptr_vector
);
127 deletePointers(m_creditlink_ptr_vector
);
128 delete m_topology_ptr
;
132 GarnetNetwork_d::reset()
134 for (int node
= 0; node
< m_nodes
; node
++) {
135 for (int j
= 0; j
< m_virtual_networks
; j
++) {
136 m_toNetQueues
[node
][j
]->clear();
137 m_fromNetQueues
[node
][j
]->clear();
143 * This function creates a link from the Network Interface (NI)
145 * It creates a Network Link from the NI to a Router and a Credit Link from
146 * the Router to the NI
150 GarnetNetwork_d::makeInLink(NodeID src
, SwitchID dest
,
151 const NetDest
& routing_table_entry
, int link_latency
, int bw_multiplier
,
152 bool isReconfiguration
)
154 assert(src
< m_nodes
);
156 if (!isReconfiguration
) {
157 NetworkLink_d
*net_link
= new NetworkLink_d
158 (m_link_ptr_vector
.size(), link_latency
, this);
159 CreditLink_d
*credit_link
= new CreditLink_d
160 (m_creditlink_ptr_vector
.size(), link_latency
, this);
161 m_link_ptr_vector
.push_back(net_link
);
162 m_creditlink_ptr_vector
.push_back(credit_link
);
164 m_router_ptr_vector
[dest
]->addInPort(net_link
, credit_link
);
165 m_ni_ptr_vector
[src
]->addOutPort(net_link
, credit_link
);
167 panic("Fatal Error:: Reconfiguration not allowed here");
173 * This function creates a link from the Network to a NI.
174 * It creates a Network Link from a Router to the NI and
175 * a Credit Link from NI to the Router
179 GarnetNetwork_d::makeOutLink(SwitchID src
, NodeID dest
,
180 const NetDest
& routing_table_entry
, int link_latency
, int link_weight
,
181 int bw_multiplier
, bool isReconfiguration
)
183 assert(dest
< m_nodes
);
184 assert(src
< m_router_ptr_vector
.size());
185 assert(m_router_ptr_vector
[src
] != NULL
);
187 if (!isReconfiguration
) {
188 NetworkLink_d
*net_link
= new NetworkLink_d
189 (m_link_ptr_vector
.size(), link_latency
, this);
190 CreditLink_d
*credit_link
= new CreditLink_d
191 (m_creditlink_ptr_vector
.size(), link_latency
, this);
192 m_link_ptr_vector
.push_back(net_link
);
193 m_creditlink_ptr_vector
.push_back(credit_link
);
195 m_router_ptr_vector
[src
]->addOutPort(net_link
, routing_table_entry
,
196 link_weight
, credit_link
);
197 m_ni_ptr_vector
[dest
]->addInPort(net_link
, credit_link
);
199 fatal("Fatal Error:: Reconfiguration not allowed here");
205 * This function creates an internal network link
209 GarnetNetwork_d::makeInternalLink(SwitchID src
, SwitchID dest
,
210 const NetDest
& routing_table_entry
, int link_latency
, int link_weight
,
211 int bw_multiplier
, bool isReconfiguration
)
213 if (!isReconfiguration
) {
214 NetworkLink_d
*net_link
= new NetworkLink_d
215 (m_link_ptr_vector
.size(), link_latency
, this);
216 CreditLink_d
*credit_link
= new CreditLink_d
217 (m_creditlink_ptr_vector
.size(), link_latency
, this);
218 m_link_ptr_vector
.push_back(net_link
);
219 m_creditlink_ptr_vector
.push_back(credit_link
);
221 m_router_ptr_vector
[dest
]->addInPort(net_link
, credit_link
);
222 m_router_ptr_vector
[src
]->addOutPort(net_link
, routing_table_entry
,
223 link_weight
, credit_link
);
225 fatal("Fatal Error:: Reconfiguration not allowed here");
231 GarnetNetwork_d::checkNetworkAllocation(NodeID id
, bool ordered
,
234 assert(id
< m_nodes
);
235 assert(network_num
< m_virtual_networks
);
238 m_ordered
[network_num
] = true;
240 m_in_use
[network_num
] = true;
244 GarnetNetwork_d::getToNetQueue(NodeID id
, bool ordered
, int network_num
)
246 checkNetworkAllocation(id
, ordered
, network_num
);
247 return m_toNetQueues
[id
][network_num
];
251 GarnetNetwork_d::getFromNetQueue(NodeID id
, bool ordered
, int network_num
)
253 checkNetworkAllocation(id
, ordered
, network_num
);
254 return m_fromNetQueues
[id
][network_num
];
258 GarnetNetwork_d::clearStats()
260 m_ruby_start
= g_eventQueue_ptr
->getTime();
264 GarnetNetwork_d::getRubyStartTime()
270 GarnetNetwork_d::printStats(ostream
& out
) const
272 double average_link_utilization
= 0;
273 vector
<double> average_vc_load
;
274 average_vc_load
.resize(m_virtual_networks
*m_vcs_per_class
);
276 for (int i
= 0; i
< m_virtual_networks
*m_vcs_per_class
; i
++)
278 average_vc_load
[i
] = 0;
282 out
<< "Network Stats" << endl
;
283 out
<< "-------------" << endl
;
285 for (int i
= 0; i
< m_link_ptr_vector
.size(); i
++) {
286 average_link_utilization
+=
287 (double(m_link_ptr_vector
[i
]->getLinkUtilization())) /
288 (double(g_eventQueue_ptr
->getTime()-m_ruby_start
));
290 vector
<int> vc_load
= m_link_ptr_vector
[i
]->getVcLoad();
291 for (int j
= 0; j
< vc_load
.size(); j
++) {
292 assert(vc_load
.size() == m_vcs_per_class
*m_virtual_networks
);
293 average_vc_load
[j
] += vc_load
[j
];
296 average_link_utilization
=
297 average_link_utilization
/m_link_ptr_vector
.size();
298 out
<< "Average Link Utilization :: " << average_link_utilization
299 << " flits/cycle" << endl
;
300 out
<< "-------------" << endl
;
302 for (int i
= 0; i
< m_vcs_per_class
*m_virtual_networks
; i
++) {
303 average_vc_load
[i
] = (double(average_vc_load
[i
]) /
304 (double(g_eventQueue_ptr
->getTime()) - m_ruby_start
));
305 out
<< "Average VC Load [" << i
<< "] = " << average_vc_load
[i
]
306 << " flits/cycle " << endl
;
308 out
<< "-------------" << endl
;
310 // out << "Total flits injected = " << m_flits_injected << endl;
311 // out << "Total flits received = " << m_flits_received << endl;
312 out
<< "Average network latency = "
313 << ((double) m_network_latency
/ (double) m_flits_received
)<< endl
;
314 // out << "Average queueing latency = "
315 // << ((double) m_queueing_latency/ (double) m_flits_received)<< endl;
316 // out << "Average latency = "
317 // << ((double) (m_queueing_latency + m_network_latency) /
318 // (double) m_flits_received)<< endl;
319 out
<< "-------------" << endl
;
321 double m_total_link_power
= 0.0;
322 double m_total_router_power
= 0.0;
324 for (int i
= 0; i
< m_link_ptr_vector
.size(); i
++) {
325 m_total_link_power
+= m_link_ptr_vector
[i
]->calculate_power();
328 for (int i
= 0; i
< m_router_ptr_vector
.size(); i
++) {
329 m_total_router_power
+= m_router_ptr_vector
[i
]->calculate_power();
331 out
<< "Total Link Power = " << m_total_link_power
<< " W " << endl
;
332 out
<< "Total Router Power = " << m_total_router_power
<< " W " <<endl
;
333 out
<< "-------------" << endl
;
334 m_topology_ptr
->printStats(out
);
338 GarnetNetwork_d::printConfig(ostream
& out
) const
341 out
<< "Network Configuration" << endl
;
342 out
<< "---------------------" << endl
;
343 out
<< "network: GarnetNetwork_d" << endl
;
344 out
<< "topology: " << m_topology_ptr
->getName() << endl
;
347 for (int i
= 0; i
< m_virtual_networks
; i
++) {
348 out
<< "virtual_net_" << i
<< ": ";
352 out
<< "ordered" << endl
;
354 out
<< "unordered" << endl
;
357 out
<< "inactive" << endl
;
362 for (int i
= 0; i
< m_ni_ptr_vector
.size(); i
++) {
363 m_ni_ptr_vector
[i
]->printConfig(out
);
365 for (int i
= 0; i
< m_router_ptr_vector
.size(); i
++) {
366 m_router_ptr_vector
[i
]->printConfig(out
);
368 m_topology_ptr
->printConfig(out
);
372 GarnetNetwork_d::print(ostream
& out
) const
374 out
<< "[GarnetNetwork_d]";
378 GarnetNetwork_dParams::create()
380 return new GarnetNetwork_d(this);