SimpleNetwork.cc revision 7054:7d6862b80049
1/* 2 * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood 3 * All rights reserved. 4 * 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. 15 * 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. 27 */ 28 29#include "mem/gems_common/Map.hh" 30#include "mem/protocol/MachineType.hh" 31#include "mem/protocol/Protocol.hh" 32#include "mem/protocol/TopologyType.hh" 33#include "mem/ruby/buffers/MessageBuffer.hh" 34#include "mem/ruby/common/NetDest.hh" 35#include "mem/ruby/network/simple/SimpleNetwork.hh" 36#include "mem/ruby/network/simple/Switch.hh" 37#include "mem/ruby/network/simple/Topology.hh" 38#include "mem/ruby/profiler/Profiler.hh" 39#include "mem/ruby/system/System.hh" 40 41#if 0 42// ***BIG HACK*** - This is actually code that _should_ be in Network.cc 43 44// Note: Moved to Princeton Network 45// calls new to abstract away from the network 46Network* 47Network::createNetwork(int nodes) 48{ 49 return new SimpleNetwork(nodes); 50} 51#endif 52 53SimpleNetwork::SimpleNetwork(const Params *p) 54 : Network(p) 55{ 56 // Note: the parent Network Object constructor is called before the 57 // SimpleNetwork child constructor. Therefore, the member variables 58 // used below should already be initialized. 59 60 m_endpoint_switches.setSize(m_nodes); 61 62 m_in_use.setSize(m_virtual_networks); 63 m_ordered.setSize(m_virtual_networks); 64 for (int i = 0; i < m_virtual_networks; i++) { 65 m_in_use[i] = false; 66 m_ordered[i] = false; 67 } 68 69 // Allocate to and from queues 70 m_toNetQueues.setSize(m_nodes); 71 m_fromNetQueues.setSize(m_nodes); 72 for (int node = 0; node < m_nodes; node++) { 73 m_toNetQueues[node].setSize(m_virtual_networks); 74 m_fromNetQueues[node].setSize(m_virtual_networks); 75 for (int j = 0; j < m_virtual_networks; j++) { 76 m_toNetQueues[node][j] = new MessageBuffer( 77 "toNet node "+int_to_string(node)+" j "+int_to_string(j)); 78 m_fromNetQueues[node][j] = new MessageBuffer( 79 "fromNet node "+int_to_string(node)+" j "+int_to_string(j)); 80 } 81 } 82} 83 84void 85SimpleNetwork::init() 86{ 87 Network::init(); 88 89 // The topology pointer should have already been initialized in 90 // the parent class network constructor. 91 assert(m_topology_ptr != NULL); 92 int number_of_switches = m_topology_ptr->numSwitches(); 93 for (int i = 0; i < number_of_switches; i++) { 94 m_switch_ptr_vector.insertAtBottom(new Switch(i, this)); 95 } 96 97 // false because this isn't a reconfiguration 98 m_topology_ptr->createLinks(this, false); 99} 100 101void 102SimpleNetwork::reset() 103{ 104 for (int node = 0; node < m_nodes; node++) { 105 for (int j = 0; j < m_virtual_networks; j++) { 106 m_toNetQueues[node][j]->clear(); 107 m_fromNetQueues[node][j]->clear(); 108 } 109 } 110 111 for(int i = 0; i < m_switch_ptr_vector.size(); i++){ 112 m_switch_ptr_vector[i]->clearBuffers(); 113 } 114} 115 116SimpleNetwork::~SimpleNetwork() 117{ 118 for (int i = 0; i < m_nodes; i++) { 119 m_toNetQueues[i].deletePointers(); 120 m_fromNetQueues[i].deletePointers(); 121 } 122 m_switch_ptr_vector.deletePointers(); 123 m_buffers_to_free.deletePointers(); 124 // delete m_topology_ptr; 125} 126 127// From a switch to an endpoint node 128void 129SimpleNetwork::makeOutLink(SwitchID src, NodeID dest, 130 const NetDest& routing_table_entry, int link_latency, int link_weight, 131 int bw_multiplier, bool isReconfiguration) 132{ 133 assert(dest < m_nodes); 134 assert(src < m_switch_ptr_vector.size()); 135 assert(m_switch_ptr_vector[src] != NULL); 136 137 if (isReconfiguration) { 138 m_switch_ptr_vector[src]->reconfigureOutPort(routing_table_entry); 139 return; 140 } 141 142 m_switch_ptr_vector[src]->addOutPort(m_fromNetQueues[dest], 143 routing_table_entry, link_latency, bw_multiplier); 144 m_endpoint_switches[dest] = m_switch_ptr_vector[src]; 145} 146 147// From an endpoint node to a switch 148void 149SimpleNetwork::makeInLink(NodeID src, SwitchID dest, 150 const NetDest& routing_table_entry, int link_latency, int bw_multiplier, 151 bool isReconfiguration) 152{ 153 assert(src < m_nodes); 154 if (isReconfiguration) { 155 // do nothing 156 return; 157 } 158 159 m_switch_ptr_vector[dest]->addInPort(m_toNetQueues[src]); 160} 161 162// From a switch to a switch 163void 164SimpleNetwork::makeInternalLink(SwitchID src, SwitchID dest, 165 const NetDest& routing_table_entry, int link_latency, int link_weight, 166 int bw_multiplier, bool isReconfiguration) 167{ 168 if (isReconfiguration) { 169 m_switch_ptr_vector[src]->reconfigureOutPort(routing_table_entry); 170 return; 171 } 172 173 // Create a set of new MessageBuffers 174 Vector<MessageBuffer*> queues; 175 for (int i = 0; i < m_virtual_networks; i++) { 176 // allocate a buffer 177 MessageBuffer* buffer_ptr = new MessageBuffer; 178 buffer_ptr->setOrdering(true); 179 if (m_buffer_size > 0) { 180 buffer_ptr->setSize(m_buffer_size); 181 } 182 queues.insertAtBottom(buffer_ptr); 183 // remember to deallocate it 184 m_buffers_to_free.insertAtBottom(buffer_ptr); 185 } 186 // Connect it to the two switches 187 m_switch_ptr_vector[dest]->addInPort(queues); 188 m_switch_ptr_vector[src]->addOutPort(queues, routing_table_entry, 189 link_latency, bw_multiplier); 190} 191 192void 193SimpleNetwork::checkNetworkAllocation(NodeID id, bool ordered, int network_num) 194{ 195 ASSERT(id < m_nodes); 196 ASSERT(network_num < m_virtual_networks); 197 198 if (ordered) { 199 m_ordered[network_num] = true; 200 } 201 m_in_use[network_num] = true; 202} 203 204MessageBuffer* 205SimpleNetwork::getToNetQueue(NodeID id, bool ordered, int network_num) 206{ 207 checkNetworkAllocation(id, ordered, network_num); 208 return m_toNetQueues[id][network_num]; 209} 210 211MessageBuffer* 212SimpleNetwork::getFromNetQueue(NodeID id, bool ordered, int network_num) 213{ 214 checkNetworkAllocation(id, ordered, network_num); 215 return m_fromNetQueues[id][network_num]; 216} 217 218const Vector<Throttle*>* 219SimpleNetwork::getThrottles(NodeID id) const 220{ 221 assert(id >= 0); 222 assert(id < m_nodes); 223 assert(m_endpoint_switches[id] != NULL); 224 return m_endpoint_switches[id]->getThrottles(); 225} 226 227void 228SimpleNetwork::printStats(ostream& out) const 229{ 230 out << endl; 231 out << "Network Stats" << endl; 232 out << "-------------" << endl; 233 out << endl; 234 for (int i = 0; i < m_switch_ptr_vector.size(); i++) { 235 m_switch_ptr_vector[i]->printStats(out); 236 } 237 m_topology_ptr->printStats(out); 238} 239 240void 241SimpleNetwork::clearStats() 242{ 243 for (int i = 0; i < m_switch_ptr_vector.size(); i++) { 244 m_switch_ptr_vector[i]->clearStats(); 245 } 246 m_topology_ptr->clearStats(); 247} 248 249void 250SimpleNetwork::printConfig(ostream& out) const 251{ 252 out << endl; 253 out << "Network Configuration" << endl; 254 out << "---------------------" << endl; 255 out << "network: SIMPLE_NETWORK" << endl; 256 out << "topology: " << m_topology_ptr->getName() << endl; 257 out << endl; 258 259 for (int i = 0; i < m_virtual_networks; i++) { 260 out << "virtual_net_" << i << ": "; 261 if (m_in_use[i]) { 262 out << "active, "; 263 if (m_ordered[i]) { 264 out << "ordered" << endl; 265 } else { 266 out << "unordered" << endl; 267 } 268 } else { 269 out << "inactive" << endl; 270 } 271 } 272 out << endl; 273 274 for(int i = 0; i < m_switch_ptr_vector.size(); i++) { 275 m_switch_ptr_vector[i]->printConfig(out); 276 } 277 278 m_topology_ptr->printConfig(out); 279} 280 281void 282SimpleNetwork::print(ostream& out) const 283{ 284 out << "[SimpleNetwork]"; 285} 286 287 288SimpleNetwork * 289SimpleNetworkParams::create() 290{ 291 return new SimpleNetwork(this); 292} 293