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 "base/stl_helpers.hh"
32 #include "mem/ruby/network/garnet/fixed-pipeline/GarnetNetwork_d.hh"
33 #include "mem/protocol/MachineType.hh"
34 #include "mem/ruby/network/garnet/fixed-pipeline/NetworkInterface_d.hh"
35 #include "mem/ruby/buffers/MessageBuffer.hh"
36 #include "mem/ruby/network/garnet/fixed-pipeline/Router_d.hh"
37 #include "mem/ruby/network/simple/Topology.hh"
38 #include "mem/ruby/network/garnet/fixed-pipeline/NetworkLink_d.hh"
39 #include "mem/ruby/network/garnet/fixed-pipeline/CreditLink_d.hh"
40 #include "mem/ruby/common/NetDest.hh"
43 using m5::stl_helpers::deletePointers
;
45 GarnetNetwork_d::GarnetNetwork_d(const Params
*p
)
46 : BaseGarnetNetwork(p
)
51 m_network_latency
= 0.0;
52 m_queueing_latency
= 0.0;
54 m_router_ptr_vector
.clear();
56 // Queues that are getting messages from protocol
57 m_toNetQueues
.resize(m_nodes
);
59 // Queues that are feeding the protocol
60 m_fromNetQueues
.resize(m_nodes
);
61 m_in_use
.resize(m_virtual_networks
);
62 m_ordered
.resize(m_virtual_networks
);
63 for (int i
= 0; i
< m_virtual_networks
; i
++) {
68 for (int node
= 0; node
< m_nodes
; node
++) {
69 // Setting how many vitual message buffers
70 // will there be per Network Queue
71 m_toNetQueues
[node
].resize(m_virtual_networks
);
72 m_fromNetQueues
[node
].resize(m_virtual_networks
);
74 // Instantiating the Message Buffers
75 // that interact with the coherence protocol
76 for (int j
= 0; j
< m_virtual_networks
; j
++) {
77 m_toNetQueues
[node
][j
] = new MessageBuffer();
78 m_fromNetQueues
[node
][j
] = new MessageBuffer();
84 GarnetNetwork_d::init()
86 BaseGarnetNetwork::init();
88 // The topology pointer should have already been initialized in the
89 // parent network constructor
90 assert(m_topology_ptr
!= NULL
);
92 int number_of_routers
= m_topology_ptr
->numSwitches();
93 for (int i
=0; i
<number_of_routers
; i
++) {
94 m_router_ptr_vector
.push_back(new Router_d(i
, this));
97 for (int i
=0; i
< m_nodes
; i
++) {
98 NetworkInterface_d
*ni
= new NetworkInterface_d(i
, m_virtual_networks
,
100 ni
->addNode(m_toNetQueues
[i
], m_fromNetQueues
[i
]);
101 m_ni_ptr_vector
.push_back(ni
);
103 // false because this isn't a reconfiguration
104 m_topology_ptr
->createLinks(this, false);
105 for (int i
= 0; i
< m_router_ptr_vector
.size(); i
++) {
106 m_router_ptr_vector
[i
]->init();
110 GarnetNetwork_d::~GarnetNetwork_d()
112 for (int i
= 0; i
< m_nodes
; i
++) {
113 deletePointers(m_toNetQueues
[i
]);
114 deletePointers(m_fromNetQueues
[i
]);
116 deletePointers(m_router_ptr_vector
);
117 deletePointers(m_ni_ptr_vector
);
118 deletePointers(m_link_ptr_vector
);
119 deletePointers(m_creditlink_ptr_vector
);
120 delete m_topology_ptr
;
124 GarnetNetwork_d::reset()
126 for (int node
= 0; node
< m_nodes
; node
++) {
127 for (int j
= 0; j
< m_virtual_networks
; j
++) {
128 m_toNetQueues
[node
][j
]->clear();
129 m_fromNetQueues
[node
][j
]->clear();
135 * This function creates a link from the Network Interface (NI)
137 * It creates a Network Link from the NI to a Router and a Credit Link from
138 * the Router to the NI
142 GarnetNetwork_d::makeInLink(NodeID src
, SwitchID dest
,
143 const NetDest
& routing_table_entry
, int link_latency
, int bw_multiplier
,
144 bool isReconfiguration
)
146 assert(src
< m_nodes
);
148 if (!isReconfiguration
) {
149 NetworkLink_d
*net_link
= new NetworkLink_d
150 (m_link_ptr_vector
.size(), link_latency
, this);
151 CreditLink_d
*credit_link
= new CreditLink_d
152 (m_creditlink_ptr_vector
.size(), link_latency
, this);
153 m_link_ptr_vector
.push_back(net_link
);
154 m_creditlink_ptr_vector
.push_back(credit_link
);
156 m_router_ptr_vector
[dest
]->addInPort(net_link
, credit_link
);
157 m_ni_ptr_vector
[src
]->addOutPort(net_link
, credit_link
);
159 ERROR_MSG("Fatal Error:: Reconfiguration not allowed here");
165 * This function creates a link from the Network to a NI.
166 * It creates a Network Link from a Router to the NI and
167 * a Credit Link from NI to the Router
171 GarnetNetwork_d::makeOutLink(SwitchID src
, NodeID dest
,
172 const NetDest
& routing_table_entry
, int link_latency
, int link_weight
,
173 int bw_multiplier
, bool isReconfiguration
)
175 assert(dest
< m_nodes
);
176 assert(src
< m_router_ptr_vector
.size());
177 assert(m_router_ptr_vector
[src
] != NULL
);
179 if (!isReconfiguration
) {
180 NetworkLink_d
*net_link
= new NetworkLink_d
181 (m_link_ptr_vector
.size(), link_latency
, this);
182 CreditLink_d
*credit_link
= new CreditLink_d
183 (m_creditlink_ptr_vector
.size(), link_latency
, this);
184 m_link_ptr_vector
.push_back(net_link
);
185 m_creditlink_ptr_vector
.push_back(credit_link
);
187 m_router_ptr_vector
[src
]->addOutPort(net_link
, routing_table_entry
,
188 link_weight
, credit_link
);
189 m_ni_ptr_vector
[dest
]->addInPort(net_link
, credit_link
);
191 ERROR_MSG("Fatal Error:: Reconfiguration not allowed here");
197 * This function creates an internal network link
201 GarnetNetwork_d::makeInternalLink(SwitchID src
, SwitchID dest
,
202 const NetDest
& routing_table_entry
, int link_latency
, int link_weight
,
203 int bw_multiplier
, bool isReconfiguration
)
205 if (!isReconfiguration
) {
206 NetworkLink_d
*net_link
= new NetworkLink_d
207 (m_link_ptr_vector
.size(), link_latency
, this);
208 CreditLink_d
*credit_link
= new CreditLink_d
209 (m_creditlink_ptr_vector
.size(), link_latency
, this);
210 m_link_ptr_vector
.push_back(net_link
);
211 m_creditlink_ptr_vector
.push_back(credit_link
);
213 m_router_ptr_vector
[dest
]->addInPort(net_link
, credit_link
);
214 m_router_ptr_vector
[src
]->addOutPort(net_link
, routing_table_entry
,
215 link_weight
, credit_link
);
217 ERROR_MSG("Fatal Error:: Reconfiguration not allowed here");
223 GarnetNetwork_d::checkNetworkAllocation(NodeID id
, bool ordered
,
226 ASSERT(id
< m_nodes
);
227 ASSERT(network_num
< m_virtual_networks
);
230 m_ordered
[network_num
] = true;
232 m_in_use
[network_num
] = true;
236 GarnetNetwork_d::getToNetQueue(NodeID id
, bool ordered
, int network_num
)
238 checkNetworkAllocation(id
, ordered
, network_num
);
239 return m_toNetQueues
[id
][network_num
];
243 GarnetNetwork_d::getFromNetQueue(NodeID id
, bool ordered
, int network_num
)
245 checkNetworkAllocation(id
, ordered
, network_num
);
246 return m_fromNetQueues
[id
][network_num
];
250 GarnetNetwork_d::clearStats()
252 m_ruby_start
= g_eventQueue_ptr
->getTime();
256 GarnetNetwork_d::getRubyStartTime()
262 GarnetNetwork_d::printStats(ostream
& out
) const
264 double average_link_utilization
= 0;
265 vector
<double> average_vc_load
;
266 average_vc_load
.resize(m_virtual_networks
*m_vcs_per_class
);
268 for (int i
= 0; i
< m_virtual_networks
*m_vcs_per_class
; i
++)
270 average_vc_load
[i
] = 0;
274 out
<< "Network Stats" << endl
;
275 out
<< "-------------" << endl
;
277 for (int i
= 0; i
< m_link_ptr_vector
.size(); i
++) {
278 average_link_utilization
+=
279 (double(m_link_ptr_vector
[i
]->getLinkUtilization())) /
280 (double(g_eventQueue_ptr
->getTime()-m_ruby_start
));
282 vector
<int> vc_load
= m_link_ptr_vector
[i
]->getVcLoad();
283 for (int j
= 0; j
< vc_load
.size(); j
++) {
284 assert(vc_load
.size() == m_vcs_per_class
*m_virtual_networks
);
285 average_vc_load
[j
] += vc_load
[j
];
288 average_link_utilization
=
289 average_link_utilization
/m_link_ptr_vector
.size();
290 out
<< "Average Link Utilization :: " << average_link_utilization
291 << " flits/cycle" << endl
;
292 out
<< "-------------" << endl
;
294 for (int i
= 0; i
< m_vcs_per_class
*m_virtual_networks
; i
++) {
295 average_vc_load
[i
] = (double(average_vc_load
[i
]) /
296 (double(g_eventQueue_ptr
->getTime()) - m_ruby_start
));
297 out
<< "Average VC Load [" << i
<< "] = " << average_vc_load
[i
]
298 << " flits/cycle " << endl
;
300 out
<< "-------------" << endl
;
302 // out << "Total flits injected = " << m_flits_injected << endl;
303 // out << "Total flits received = " << m_flits_received << endl;
304 out
<< "Average network latency = "
305 << ((double) m_network_latency
/ (double) m_flits_received
)<< endl
;
306 // out << "Average queueing latency = "
307 // << ((double) m_queueing_latency/ (double) m_flits_received)<< endl;
308 // out << "Average latency = "
309 // << ((double) (m_queueing_latency + m_network_latency) /
310 // (double) m_flits_received)<< endl;
311 out
<< "-------------" << endl
;
313 double m_total_link_power
= 0.0;
314 double m_total_router_power
= 0.0;
316 for (int i
= 0; i
< m_link_ptr_vector
.size(); i
++) {
317 m_total_link_power
+= m_link_ptr_vector
[i
]->calculate_power();
320 for (int i
= 0; i
< m_router_ptr_vector
.size(); i
++) {
321 m_total_router_power
+= m_router_ptr_vector
[i
]->calculate_power();
323 out
<< "Total Link Power = " << m_total_link_power
<< " W " << endl
;
324 out
<< "Total Router Power = " << m_total_router_power
<< " W " <<endl
;
325 out
<< "-------------" << endl
;
326 m_topology_ptr
->printStats(out
);
330 GarnetNetwork_d::printConfig(ostream
& out
) const
333 out
<< "Network Configuration" << endl
;
334 out
<< "---------------------" << endl
;
335 out
<< "network: GarnetNetwork_d" << endl
;
336 out
<< "topology: " << m_topology_ptr
->getName() << endl
;
339 for (int i
= 0; i
< m_virtual_networks
; i
++) {
340 out
<< "virtual_net_" << i
<< ": ";
344 out
<< "ordered" << endl
;
346 out
<< "unordered" << endl
;
349 out
<< "inactive" << endl
;
354 for (int i
= 0; i
< m_ni_ptr_vector
.size(); i
++) {
355 m_ni_ptr_vector
[i
]->printConfig(out
);
357 for (int i
= 0; i
< m_router_ptr_vector
.size(); i
++) {
358 m_router_ptr_vector
[i
]->printConfig(out
);
360 m_topology_ptr
->printConfig(out
);
364 GarnetNetwork_d::print(ostream
& out
) const
366 out
<< "[GarnetNetwork_d]";
370 GarnetNetwork_dParams::create()
372 return new GarnetNetwork_d(this);