#include "mem/ruby/network/simple/CustomTopology.hh" #include "mem/protocol/MachineType.hh" static const int INFINITE_LATENCY = 10000; // Yes, this is a big hack static const int DEFAULT_BW_MULTIPLIER = 1; // Just to be consistent with above :) // make a network as described by the networkFile void CustomTopology::construct() { Vector< Vector < SwitchID > > nodePairs; // node pairs extracted from the file Vector latencies; // link latencies for each link extracted Vector bw_multis; // bw multipliers for each link extracted Vector weights; // link weights used to enfore e-cube deadlock free routing Vector< SwitchID > int_network_switches; // internal switches extracted from the file Vector endpointConnectionExist; // used to ensure all endpoints are connected to the network endpointConnectionExist.setSize(m_nodes); // initialize endpoint check vector for (int k = 0; k < endpointConnectionExist.size(); k++) { endpointConnectionExist[k] = false; } stringstream networkFile( m_connections ); string line = ""; while (!networkFile.eof()) { Vector < SwitchID > nodes; nodes.setSize(2); int latency = -1; // null latency int weight = -1; // null weight int bw_multiplier = DEFAULT_BW_MULTIPLIER; // default multiplier incase the network file doesn't define it int i = 0; // node pair index int varsFound = 0; // number of varsFound on the line int internalNodes = 0; // used to determine if the link is between 2 internal nodes std::getline(networkFile, line, '\n'); string varStr = string_split(line, ' '); // parse the current line in the file while (varStr != "") { string label = string_split(varStr, ':'); // valid node labels if (label == "ext_node" || label == "int_node") { ASSERT(i < 2); // one link between 2 switches per line varsFound++; bool isNewIntSwitch = true; if (label == "ext_node") { // input link to node MachineType machine = string_to_MachineType(string_split(varStr, ':')); string nodeStr = string_split(varStr, ':'); nodes[i] = MachineType_base_number(machine) + atoi(nodeStr.c_str()); // in nodes should be numbered 0 to m_nodes-1 ASSERT(nodes[i] >= 0 && nodes[i] < m_nodes); isNewIntSwitch = false; endpointConnectionExist[nodes[i]] = true; } if (label == "int_node") { // interior node nodes[i] = atoi((string_split(varStr, ':')).c_str())+m_nodes*2; // in nodes should be numbered >= m_nodes*2 ASSERT(nodes[i] >= m_nodes*2); for (int k = 0; k < int_network_switches.size(); k++) { if (int_network_switches[k] == nodes[i]) { isNewIntSwitch = false; } } if (isNewIntSwitch) { // if internal switch m_number_of_switches++; int_network_switches.insertAtBottom(nodes[i]); } internalNodes++; } i++; } else if (label == "link_latency") { latency = atoi((string_split(varStr, ':')).c_str()); varsFound++; } else if (label == "bw_multiplier") { // not necessary, defaults to DEFAULT_BW_MULTIPLIER bw_multiplier = atoi((string_split(varStr, ':')).c_str()); } else if (label == "link_weight") { // not necessary, defaults to link_latency weight = atoi((string_split(varStr, ':')).c_str()); } else { cerr << "Error: Unexpected Identifier: " << label << endl; exit(1); } varStr = string_split(line, ' '); } if (varsFound == 3) { // all three necessary link variables where found so add the link nodePairs.insertAtBottom(nodes); latencies.insertAtBottom(latency); if (weight != -1) { weights.insertAtBottom(weight); } else { weights.insertAtBottom(latency); } bw_multis.insertAtBottom(bw_multiplier); Vector < SwitchID > otherDirectionNodes; otherDirectionNodes.setSize(2); otherDirectionNodes[0] = nodes[1]; if (internalNodes == 2) { // this is an internal link otherDirectionNodes[1] = nodes[0]; } else { otherDirectionNodes[1] = nodes[0]+m_nodes; } nodePairs.insertAtBottom(otherDirectionNodes); latencies.insertAtBottom(latency); if (weight != -1) { weights.insertAtBottom(weight); } else { weights.insertAtBottom(latency); } bw_multis.insertAtBottom(bw_multiplier); } else { if (varsFound != 0) { // if this is not a valid link, then no vars should have been found cerr << "Error in line: " << line << endl; exit(1); } } } // end of file // makes sure all enpoints are connected in the soon to be created network for (int k = 0; k < endpointConnectionExist.size(); k++) { if (endpointConnectionExist[k] == false) { cerr << "Error: Unconnected Endpoint: " << k << endl; exit(1); } } ASSERT(nodePairs.size() == latencies.size() && latencies.size() == bw_multis.size() && latencies.size() == weights.size()) for (int k = 0; k < nodePairs.size(); k++) { ASSERT(nodePairs[k].size() == 2); addLink(nodePairs[k][0], nodePairs[k][1], latencies[k], bw_multis[k], weights[k]); } // networkFile.close(); }