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();
112 GarnetNetwork_d::~GarnetNetwork_d()
114 for (int i
= 0; i
< m_nodes
; i
++) {
115 deletePointers(m_toNetQueues
[i
]);
116 deletePointers(m_fromNetQueues
[i
]);
118 deletePointers(m_router_ptr_vector
);
119 deletePointers(m_ni_ptr_vector
);
120 deletePointers(m_link_ptr_vector
);
121 deletePointers(m_creditlink_ptr_vector
);
122 delete m_topology_ptr
;
126 GarnetNetwork_d::reset()
128 for (int node
= 0; node
< m_nodes
; node
++) {
129 for (int j
= 0; j
< m_virtual_networks
; j
++) {
130 m_toNetQueues
[node
][j
]->clear();
131 m_fromNetQueues
[node
][j
]->clear();
137 * This function creates a link from the Network Interface (NI)
139 * It creates a Network Link from the NI to a Router and a Credit Link from
140 * the Router to the NI
144 GarnetNetwork_d::makeInLink(NodeID src
, SwitchID dest
,
145 const NetDest
& routing_table_entry
, int link_latency
, int bw_multiplier
,
146 bool isReconfiguration
)
148 assert(src
< m_nodes
);
150 if (!isReconfiguration
) {
151 NetworkLink_d
*net_link
= new NetworkLink_d
152 (m_link_ptr_vector
.size(), link_latency
, this);
153 CreditLink_d
*credit_link
= new CreditLink_d
154 (m_creditlink_ptr_vector
.size(), link_latency
, this);
155 m_link_ptr_vector
.push_back(net_link
);
156 m_creditlink_ptr_vector
.push_back(credit_link
);
158 m_router_ptr_vector
[dest
]->addInPort(net_link
, credit_link
);
159 m_ni_ptr_vector
[src
]->addOutPort(net_link
, credit_link
);
161 panic("Fatal Error:: Reconfiguration not allowed here");
167 * This function creates a link from the Network to a NI.
168 * It creates a Network Link from a Router to the NI and
169 * a Credit Link from NI to the Router
173 GarnetNetwork_d::makeOutLink(SwitchID src
, NodeID dest
,
174 const NetDest
& routing_table_entry
, int link_latency
, int link_weight
,
175 int bw_multiplier
, bool isReconfiguration
)
177 assert(dest
< m_nodes
);
178 assert(src
< m_router_ptr_vector
.size());
179 assert(m_router_ptr_vector
[src
] != NULL
);
181 if (!isReconfiguration
) {
182 NetworkLink_d
*net_link
= new NetworkLink_d
183 (m_link_ptr_vector
.size(), link_latency
, this);
184 CreditLink_d
*credit_link
= new CreditLink_d
185 (m_creditlink_ptr_vector
.size(), link_latency
, this);
186 m_link_ptr_vector
.push_back(net_link
);
187 m_creditlink_ptr_vector
.push_back(credit_link
);
189 m_router_ptr_vector
[src
]->addOutPort(net_link
, routing_table_entry
,
190 link_weight
, credit_link
);
191 m_ni_ptr_vector
[dest
]->addInPort(net_link
, credit_link
);
193 fatal("Fatal Error:: Reconfiguration not allowed here");
199 * This function creates an internal network link
203 GarnetNetwork_d::makeInternalLink(SwitchID src
, SwitchID dest
,
204 const NetDest
& routing_table_entry
, int link_latency
, int link_weight
,
205 int bw_multiplier
, bool isReconfiguration
)
207 if (!isReconfiguration
) {
208 NetworkLink_d
*net_link
= new NetworkLink_d
209 (m_link_ptr_vector
.size(), link_latency
, this);
210 CreditLink_d
*credit_link
= new CreditLink_d
211 (m_creditlink_ptr_vector
.size(), link_latency
, this);
212 m_link_ptr_vector
.push_back(net_link
);
213 m_creditlink_ptr_vector
.push_back(credit_link
);
215 m_router_ptr_vector
[dest
]->addInPort(net_link
, credit_link
);
216 m_router_ptr_vector
[src
]->addOutPort(net_link
, routing_table_entry
,
217 link_weight
, credit_link
);
219 fatal("Fatal Error:: Reconfiguration not allowed here");
225 GarnetNetwork_d::checkNetworkAllocation(NodeID id
, bool ordered
,
228 assert(id
< m_nodes
);
229 assert(network_num
< m_virtual_networks
);
232 m_ordered
[network_num
] = true;
234 m_in_use
[network_num
] = true;
238 GarnetNetwork_d::getToNetQueue(NodeID id
, bool ordered
, int network_num
)
240 checkNetworkAllocation(id
, ordered
, network_num
);
241 return m_toNetQueues
[id
][network_num
];
245 GarnetNetwork_d::getFromNetQueue(NodeID id
, bool ordered
, int network_num
)
247 checkNetworkAllocation(id
, ordered
, network_num
);
248 return m_fromNetQueues
[id
][network_num
];
252 GarnetNetwork_d::clearStats()
254 m_ruby_start
= g_eventQueue_ptr
->getTime();
258 GarnetNetwork_d::getRubyStartTime()
264 GarnetNetwork_d::printStats(ostream
& out
) const
266 double average_link_utilization
= 0;
267 vector
<double> average_vc_load
;
268 average_vc_load
.resize(m_virtual_networks
*m_vcs_per_class
);
270 for (int i
= 0; i
< m_virtual_networks
*m_vcs_per_class
; i
++)
272 average_vc_load
[i
] = 0;
276 out
<< "Network Stats" << endl
;
277 out
<< "-------------" << endl
;
279 for (int i
= 0; i
< m_link_ptr_vector
.size(); i
++) {
280 average_link_utilization
+=
281 (double(m_link_ptr_vector
[i
]->getLinkUtilization())) /
282 (double(g_eventQueue_ptr
->getTime()-m_ruby_start
));
284 vector
<int> vc_load
= m_link_ptr_vector
[i
]->getVcLoad();
285 for (int j
= 0; j
< vc_load
.size(); j
++) {
286 assert(vc_load
.size() == m_vcs_per_class
*m_virtual_networks
);
287 average_vc_load
[j
] += vc_load
[j
];
290 average_link_utilization
=
291 average_link_utilization
/m_link_ptr_vector
.size();
292 out
<< "Average Link Utilization :: " << average_link_utilization
293 << " flits/cycle" << endl
;
294 out
<< "-------------" << endl
;
296 for (int i
= 0; i
< m_vcs_per_class
*m_virtual_networks
; i
++) {
297 average_vc_load
[i
] = (double(average_vc_load
[i
]) /
298 (double(g_eventQueue_ptr
->getTime()) - m_ruby_start
));
299 out
<< "Average VC Load [" << i
<< "] = " << average_vc_load
[i
]
300 << " flits/cycle " << endl
;
302 out
<< "-------------" << endl
;
304 // out << "Total flits injected = " << m_flits_injected << endl;
305 // out << "Total flits received = " << m_flits_received << endl;
306 out
<< "Average network latency = "
307 << ((double) m_network_latency
/ (double) m_flits_received
)<< endl
;
308 // out << "Average queueing latency = "
309 // << ((double) m_queueing_latency/ (double) m_flits_received)<< endl;
310 // out << "Average latency = "
311 // << ((double) (m_queueing_latency + m_network_latency) /
312 // (double) m_flits_received)<< endl;
313 out
<< "-------------" << endl
;
315 double m_total_link_power
= 0.0;
316 double m_total_router_power
= 0.0;
318 for (int i
= 0; i
< m_link_ptr_vector
.size(); i
++) {
319 m_total_link_power
+= m_link_ptr_vector
[i
]->calculate_power();
322 for (int i
= 0; i
< m_router_ptr_vector
.size(); i
++) {
323 m_total_router_power
+= m_router_ptr_vector
[i
]->calculate_power();
325 out
<< "Total Link Power = " << m_total_link_power
<< " W " << endl
;
326 out
<< "Total Router Power = " << m_total_router_power
<< " W " <<endl
;
327 out
<< "-------------" << endl
;
328 m_topology_ptr
->printStats(out
);
332 GarnetNetwork_d::printConfig(ostream
& out
) const
335 out
<< "Network Configuration" << endl
;
336 out
<< "---------------------" << endl
;
337 out
<< "network: GarnetNetwork_d" << endl
;
338 out
<< "topology: " << m_topology_ptr
->getName() << endl
;
341 for (int i
= 0; i
< m_virtual_networks
; i
++) {
342 out
<< "virtual_net_" << i
<< ": ";
346 out
<< "ordered" << endl
;
348 out
<< "unordered" << endl
;
351 out
<< "inactive" << endl
;
356 for (int i
= 0; i
< m_ni_ptr_vector
.size(); i
++) {
357 m_ni_ptr_vector
[i
]->printConfig(out
);
359 for (int i
= 0; i
< m_router_ptr_vector
.size(); i
++) {
360 m_router_ptr_vector
[i
]->printConfig(out
);
362 m_topology_ptr
->printConfig(out
);
366 GarnetNetwork_d::print(ostream
& out
) const
368 out
<< "[GarnetNetwork_d]";
372 GarnetNetwork_dParams::create()
374 return new GarnetNetwork_d(this);