Topology.cc revision 7054
11689SN/A/*
28948Sandreas.hansson@arm.com * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
38707Sandreas.hansson@arm.com * All rights reserved.
48707Sandreas.hansson@arm.com *
58707Sandreas.hansson@arm.com * Redistribution and use in source and binary forms, with or without
68707Sandreas.hansson@arm.com * modification, are permitted provided that the following conditions are
78707Sandreas.hansson@arm.com * met: redistributions of source code must retain the above copyright
88707Sandreas.hansson@arm.com * notice, this list of conditions and the following disclaimer;
98707Sandreas.hansson@arm.com * redistributions in binary form must reproduce the above copyright
108707Sandreas.hansson@arm.com * notice, this list of conditions and the following disclaimer in the
118707Sandreas.hansson@arm.com * documentation and/or other materials provided with the distribution;
128707Sandreas.hansson@arm.com * neither the name of the copyright holders nor the names of its
138707Sandreas.hansson@arm.com * contributors may be used to endorse or promote products derived from
142325SN/A * this software without specific prior written permission.
157897Shestness@cs.utexas.edu *
161689SN/A * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
171689SN/A * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
181689SN/A * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
191689SN/A * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
201689SN/A * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
211689SN/A * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
221689SN/A * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
231689SN/A * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
241689SN/A * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
251689SN/A * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
261689SN/A * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
271689SN/A */
281689SN/A
291689SN/A#include "mem/gems_common/util.hh"
301689SN/A#include "mem/protocol/MachineType.hh"
311689SN/A#include "mem/protocol/Protocol.hh"
321689SN/A#include "mem/protocol/TopologyType.hh"
331689SN/A#include "mem/ruby/common/NetDest.hh"
341689SN/A#include "mem/ruby/network/Network.hh"
351689SN/A#include "mem/ruby/network/simple/Topology.hh"
361689SN/A#include "mem/ruby/slicc_interface/AbstractController.hh"
371689SN/A#include "mem/ruby/system/System.hh"
381689SN/A
391689SN/Aconst int INFINITE_LATENCY = 10000; // Yes, this is a big hack
402665Ssaidi@eecs.umich.educonst int DEFAULT_BW_MULTIPLIER = 1;  // Just to be consistent with above :)
412665Ssaidi@eecs.umich.edu
422756Sksewell@umich.edu// Note: In this file, we use the first 2*m_nodes SwitchIDs to
437897Shestness@cs.utexas.edu// represent the input and output endpoint links.  These really are
441689SN/A// not 'switches', as they will not have a Switch object allocated for
451689SN/A// them. The first m_nodes SwitchIDs are the links into the network,
468779Sgblack@eecs.umich.edu// the second m_nodes set of SwitchIDs represent the the output queues
476658Snate@binkert.org// of the network.
488887Sgeoffrey.blake@arm.com
498887Sgeoffrey.blake@arm.com// Helper functions based on chapter 29 of Cormen et al.
508229Snate@binkert.orgvoid extend_shortest_path(Matrix& current_dist, Matrix& latencies,
518229Snate@binkert.org    Matrix& inter_switches);
528229Snate@binkert.orgMatrix shortest_path(const Matrix& weights, Matrix& latencies,
534762Snate@binkert.org    Matrix& inter_switches);
548779Sgblack@eecs.umich.edubool link_is_shortest_path_to_node(SwitchID src, SwitchID next,
554762Snate@binkert.org    SwitchID final, const Matrix& weights, const Matrix& dist);
564762Snate@binkert.orgNetDest shortest_path_to_node(SwitchID src, SwitchID next,
578232Snate@binkert.org    const Matrix& weights, const Matrix& dist);
589152Satgutier@umich.edu
598232Snate@binkert.orgTopology::Topology(const Params *p)
608232Snate@binkert.org    : SimObject(p)
614762Snate@binkert.org{
624762Snate@binkert.org    m_print_config = p->print_config;
638793Sgblack@eecs.umich.edu    m_number_of_switches = p->num_int_nodes;
648779Sgblack@eecs.umich.edu    // initialize component latencies record
654762Snate@binkert.org    m_component_latencies.setSize(0);
668460SAli.Saidi@ARM.com    m_component_inter_switches.setSize(0);
674762Snate@binkert.org
685702Ssaidi@eecs.umich.edu    // Total nodes/controllers in network
695702Ssaidi@eecs.umich.edu    // Must make sure this is called after the State Machine constructors
708232Snate@binkert.org    m_nodes = MachineType_base_number(MachineType_NUM);
715702Ssaidi@eecs.umich.edu    assert(m_nodes > 1);
725702Ssaidi@eecs.umich.edu
738737Skoansin.tan@gmail.com    if (m_nodes != params()->ext_links.size() &&
745529Snate@binkert.org        m_nodes != params()->ext_links.size()) {
752669Sktlim@umich.edu        fatal("m_nodes (%d) != ext_links vector length (%d)\n",
766221Snate@binkert.org            m_nodes != params()->ext_links.size());
771060SN/A    }
785529Snate@binkert.org
795712Shsul@eecs.umich.edu    // First create the links between the endpoints (i.e. controllers)
801060SN/A    // and the network.
811060SN/A    for (vector<ExtLink*>::const_iterator i = params()->ext_links.begin();
821060SN/A         i != params()->ext_links.end(); ++i) {
832292SN/A        const ExtLinkParams *p = (*i)->params();
842733Sktlim@umich.edu        AbstractController *c = p->ext_node;
852292SN/A
862292SN/A        // Store the controller pointers for later
872292SN/A        m_controller_vector.insertAtBottom(c);
882292SN/A
898707Sandreas.hansson@arm.com        int ext_idx1 =
908707Sandreas.hansson@arm.com            MachineType_base_number(c->getMachineType()) + c->getVersion();
918975Sandreas.hansson@arm.com        int ext_idx2 = ext_idx1 + m_nodes;
928707Sandreas.hansson@arm.com        int int_idx = p->int_node + 2*m_nodes;
938707Sandreas.hansson@arm.com
948948Sandreas.hansson@arm.com        // create the links in both directions
958948Sandreas.hansson@arm.com        addLink(ext_idx1, int_idx, p->latency, p->bw_multiplier, p->weight);
968948Sandreas.hansson@arm.com        addLink(int_idx, ext_idx2, p->latency, p->bw_multiplier, p->weight);
978707Sandreas.hansson@arm.com    }
988707Sandreas.hansson@arm.com
998707Sandreas.hansson@arm.com    for (vector<IntLink*>::const_iterator i = params()->int_links.begin();
1008707Sandreas.hansson@arm.com         i != params()->int_links.end(); ++i) {
1018707Sandreas.hansson@arm.com        const IntLinkParams *p = (*i)->params();
1028707Sandreas.hansson@arm.com        int a = p->node_a + 2*m_nodes;
1038707Sandreas.hansson@arm.com        int b = p->node_b + 2*m_nodes;
1048707Sandreas.hansson@arm.com
1058707Sandreas.hansson@arm.com        // create the links in both directions
1068707Sandreas.hansson@arm.com        addLink(a, b, p->latency, p->bw_multiplier, p->weight);
1078707Sandreas.hansson@arm.com        addLink(b, a, p->latency, p->bw_multiplier, p->weight);
1088707Sandreas.hansson@arm.com    }
1098707Sandreas.hansson@arm.com}
1108975Sandreas.hansson@arm.com
1118707Sandreas.hansson@arm.com
1128975Sandreas.hansson@arm.comvoid
1138707Sandreas.hansson@arm.comTopology::initNetworkPtr(Network* net_ptr)
1148707Sandreas.hansson@arm.com{
1158707Sandreas.hansson@arm.com    for (int cntrl = 0; cntrl < m_controller_vector.size(); cntrl++) {
1168975Sandreas.hansson@arm.com        m_controller_vector[cntrl]->initNetworkPtr(net_ptr);
1178975Sandreas.hansson@arm.com    }
1188948Sandreas.hansson@arm.com}
1198975Sandreas.hansson@arm.com
1208948Sandreas.hansson@arm.comvoid
1218948Sandreas.hansson@arm.comTopology::createLinks(Network *net, bool isReconfiguration)
1228948Sandreas.hansson@arm.com{
1238707Sandreas.hansson@arm.com    // Find maximum switchID
1248707Sandreas.hansson@arm.com    SwitchID max_switch_id = 0;
1258707Sandreas.hansson@arm.com    for (int i = 0; i < m_links_src_vector.size(); i++) {
1268707Sandreas.hansson@arm.com        max_switch_id = max(max_switch_id, m_links_src_vector[i]);
1278707Sandreas.hansson@arm.com        max_switch_id = max(max_switch_id, m_links_dest_vector[i]);
1288707Sandreas.hansson@arm.com    }
1291060SN/A
1301755SN/A    // Initialize weight vector
1315606Snate@binkert.org    Matrix topology_weights;
1321060SN/A    Matrix topology_latency;
1331060SN/A    Matrix topology_bw_multis;
1341060SN/A    int num_switches = max_switch_id+1;
1351060SN/A    topology_weights.setSize(num_switches);
1361060SN/A    topology_latency.setSize(num_switches);
1371755SN/A    topology_bw_multis.setSize(num_switches);
1381060SN/A
1391060SN/A    // FIXME setting the size of a member variable here is a HACK!
1401060SN/A    m_component_latencies.setSize(num_switches);
1411060SN/A
1421060SN/A    // FIXME setting the size of a member variable here is a HACK!
1431060SN/A    m_component_inter_switches.setSize(num_switches);
1445336Shines@cs.fsu.edu
1451060SN/A    for (int i = 0; i < topology_weights.size(); i++) {
1464873Sstever@eecs.umich.edu        topology_weights[i].setSize(num_switches);
1471060SN/A        topology_latency[i].setSize(num_switches);
1481060SN/A        topology_bw_multis[i].setSize(num_switches);
1491060SN/A        m_component_latencies[i].setSize(num_switches);
1502829Sksewell@umich.edu
1515606Snate@binkert.org        // FIXME setting the size of a member variable here is a HACK!
1522829Sksewell@umich.edu        m_component_inter_switches[i].setSize(num_switches);
1532829Sksewell@umich.edu
1542829Sksewell@umich.edu        for (int j = 0; j < topology_weights[i].size(); j++) {
1552829Sksewell@umich.edu            topology_weights[i][j] = INFINITE_LATENCY;
1562829Sksewell@umich.edu
1572829Sksewell@umich.edu            // initialize to invalid values
1582829Sksewell@umich.edu            topology_latency[i][j] = -1;
1592829Sksewell@umich.edu            topology_bw_multis[i][j] = -1;
1602829Sksewell@umich.edu            m_component_latencies[i][j] = -1;
1612829Sksewell@umich.edu
1622829Sksewell@umich.edu            // initially assume direct connections / no intermediate
1632829Sksewell@umich.edu            // switches between components
1642829Sksewell@umich.edu            m_component_inter_switches[i][j] = 0;
1652829Sksewell@umich.edu        }
1662829Sksewell@umich.edu    }
1672829Sksewell@umich.edu
1682829Sksewell@umich.edu    // Set identity weights to zero
1692829Sksewell@umich.edu    for (int i = 0; i < topology_weights.size(); i++) {
1702829Sksewell@umich.edu        topology_weights[i][i] = 0;
1712829Sksewell@umich.edu    }
1722829Sksewell@umich.edu
1735336Shines@cs.fsu.edu    // Fill in the topology weights and bandwidth multipliers
1742829Sksewell@umich.edu    for (int i = 0; i < m_links_src_vector.size(); i++) {
1754873Sstever@eecs.umich.edu        int src = m_links_src_vector[i];
1762829Sksewell@umich.edu        int dst = m_links_dest_vector[i];
1772829Sksewell@umich.edu        topology_weights[src][dst] = m_links_weight_vector[i];
1782829Sksewell@umich.edu        topology_latency[src][dst] = m_links_latency_vector[i];
1792875Sksewell@umich.edu        m_component_latencies[src][dst] = m_links_latency_vector[i];
1805606Snate@binkert.org        topology_bw_multis[src][dst] = m_bw_multiplier_vector[i];
1812875Sksewell@umich.edu    }
1822875Sksewell@umich.edu
1832875Sksewell@umich.edu    // Walk topology and hookup the links
1842875Sksewell@umich.edu    Matrix dist = shortest_path(topology_weights, m_component_latencies,
1852875Sksewell@umich.edu        m_component_inter_switches);
1862875Sksewell@umich.edu    for (int i = 0; i < topology_weights.size(); i++) {
1873859Sbinkertn@umich.edu        for (int j = 0; j < topology_weights[i].size(); j++) {
1882875Sksewell@umich.edu            int weight = topology_weights[i][j];
1892875Sksewell@umich.edu            int bw_multiplier = topology_bw_multis[i][j];
1902875Sksewell@umich.edu            int latency = topology_latency[i][j];
1913859Sbinkertn@umich.edu            if (weight > 0 && weight != INFINITE_LATENCY) {
1922875Sksewell@umich.edu                NetDest destination_set = shortest_path_to_node(i, j,
1932875Sksewell@umich.edu                    topology_weights, dist);
1942875Sksewell@umich.edu                assert(latency != -1);
1952875Sksewell@umich.edu                makeLink(net, i, j, destination_set, latency, weight,
1962875Sksewell@umich.edu                    bw_multiplier, isReconfiguration);
1972875Sksewell@umich.edu            }
1982875Sksewell@umich.edu        }
1993221Sktlim@umich.edu    }
2003221Sktlim@umich.edu}
2012875Sksewell@umich.edu
2022875Sksewell@umich.eduSwitchID
2032875Sksewell@umich.eduTopology::newSwitchID()
2042875Sksewell@umich.edu{
2055336Shines@cs.fsu.edu    m_number_of_switches++;
2062875Sksewell@umich.edu    return m_number_of_switches-1+m_nodes+m_nodes;
2074873Sstever@eecs.umich.edu}
2082875Sksewell@umich.edu
2092875Sksewell@umich.eduvoid
2102875Sksewell@umich.eduTopology::addLink(SwitchID src, SwitchID dest, int link_latency)
2115595Sgblack@eecs.umich.edu{
2122733Sktlim@umich.edu    addLink(src, dest, link_latency, DEFAULT_BW_MULTIPLIER, link_latency);
2133781Sgblack@eecs.umich.edu}
2143781Sgblack@eecs.umich.edu
2151060SN/Avoid
2165737Scws3k@cs.virginia.eduTopology::addLink(SwitchID src, SwitchID dest, int link_latency,
2175737Scws3k@cs.virginia.edu    int bw_multiplier)
2185737Scws3k@cs.virginia.edu{
2192292SN/A    addLink(src, dest, link_latency, bw_multiplier, link_latency);
2205595Sgblack@eecs.umich.edu}
2215595Sgblack@eecs.umich.edu
2225595Sgblack@eecs.umich.eduvoid
2235595Sgblack@eecs.umich.eduTopology::addLink(SwitchID src, SwitchID dest, int link_latency,
2245595Sgblack@eecs.umich.edu    int bw_multiplier, int link_weight)
2251060SN/A{
2265595Sgblack@eecs.umich.edu    ASSERT(src <= m_number_of_switches+m_nodes+m_nodes);
2274329Sktlim@umich.edu    ASSERT(dest <= m_number_of_switches+m_nodes+m_nodes);
2281060SN/A    m_links_src_vector.insertAtBottom(src);
2295529Snate@binkert.org    m_links_dest_vector.insertAtBottom(dest);
2302292SN/A    m_links_latency_vector.insertAtBottom(link_latency);
2312292SN/A    m_links_weight_vector.insertAtBottom(link_weight);
2321060SN/A    m_bw_multiplier_vector.insertAtBottom(bw_multiplier);
2335595Sgblack@eecs.umich.edu}
2344329Sktlim@umich.edu
2352292SN/Avoid
2365529Snate@binkert.orgTopology::makeLink(Network *net, SwitchID src, SwitchID dest,
2371060SN/A    const NetDest& routing_table_entry, int link_latency, int link_weight,
2385529Snate@binkert.org    int bw_multiplier, bool isReconfiguration)
2392292SN/A{
2402292SN/A    // Make sure we're not trying to connect two end-point nodes
2416221Snate@binkert.org    // directly together
2422292SN/A    assert(src >= 2 * m_nodes || dest >= 2 * m_nodes);
2431060SN/A
2449384SAndreas.Sandberg@arm.com    if (src < m_nodes) {
2459384SAndreas.Sandberg@arm.com        net->makeInLink(src, dest-(2*m_nodes), routing_table_entry,
2468707Sandreas.hansson@arm.com            link_latency, bw_multiplier, isReconfiguration);
2478707Sandreas.hansson@arm.com    } else if (dest < 2*m_nodes) {
2488707Sandreas.hansson@arm.com        assert(dest >= m_nodes);
2492873Sktlim@umich.edu        NodeID node = dest-m_nodes;
2502873Sktlim@umich.edu        net->makeOutLink(src-(2*m_nodes), node, routing_table_entry,
2512873Sktlim@umich.edu            link_latency, link_weight, bw_multiplier, isReconfiguration);
2522873Sktlim@umich.edu    } else {
2532873Sktlim@umich.edu        assert((src >= 2*m_nodes) && (dest >= 2*m_nodes));
2545804Snate@binkert.org        net->makeInternalLink(src-(2*m_nodes), dest-(2*m_nodes),
2552873Sktlim@umich.edu            routing_table_entry, link_latency, link_weight, bw_multiplier,
2562873Sktlim@umich.edu            isReconfiguration);
2571060SN/A    }
2581060SN/A}
2592292SN/A
2602843Sktlim@umich.eduvoid
2619180Sandreas.hansson@arm.comTopology::printStats(std::ostream& out) const
2621060SN/A{
2639433SAndreas.Sandberg@ARM.com    for (int cntrl = 0; cntrl < m_controller_vector.size(); cntrl++) {
2643221Sktlim@umich.edu        m_controller_vector[cntrl]->printStats(out);
2653221Sktlim@umich.edu    }
2669152Satgutier@umich.edu}
2673221Sktlim@umich.edu
2681681SN/Avoid
2692794Sktlim@umich.eduTopology::clearStats()
2702316SN/A{
2718733Sgeoffrey.blake@arm.com    for (int cntrl = 0; cntrl < m_controller_vector.size(); cntrl++) {
2728707Sandreas.hansson@arm.com        m_controller_vector[cntrl]->clearStats();
2732316SN/A    }
2744598Sbinkertn@umich.edu}
2754598Sbinkertn@umich.edu
2764598Sbinkertn@umich.eduvoid
2772316SN/ATopology::printConfig(std::ostream& out) const
2788793Sgblack@eecs.umich.edu{
2798793Sgblack@eecs.umich.edu    using namespace std;
2808793Sgblack@eecs.umich.edu
2818793Sgblack@eecs.umich.edu    if (m_print_config == false)
2821681SN/A        return;
2832325SN/A
2842325SN/A    assert(m_component_latencies.size() > 0);
2852325SN/A
2861060SN/A    out << "--- Begin Topology Print ---" << endl
2872292SN/A        << endl
2882292SN/A        << "Topology print ONLY indicates the _NETWORK_ latency between two "
2892292SN/A        << "machines" << endl
2902292SN/A        << "It does NOT include the latency within the machines" << endl
2912292SN/A        << endl;
2922292SN/A
2931060SN/A    for (int m = 0; m < MachineType_NUM; m++) {
2941060SN/A        int i_end = MachineType_base_count((MachineType)m);
2951060SN/A        for (int i = 0; i < i_end; i++) {
2961060SN/A            MachineID cur_mach = {(MachineType)m, i};
2971060SN/A            out << cur_mach << " Network Latencies" << endl;
2981060SN/A            for (int n = 0; n < MachineType_NUM; n++) {
2991060SN/A                int j_end = MachineType_base_count((MachineType)n);
3001060SN/A                for (int j = 0; j < j_end; j++) {
3011060SN/A                    MachineID dest_mach = {(MachineType)n, j};
3021060SN/A                    if (cur_mach == dest_mach)
3031060SN/A                        continue;
3042292SN/A
3051060SN/A                    int src = MachineType_base_number((MachineType)m) + i;
3061060SN/A                    int dst = MachineType_base_number(MachineType_NUM) +
3071060SN/A                        MachineType_base_number((MachineType)n) + j;
3081060SN/A                    int link_latency = m_component_latencies[src][dst];
3091060SN/A                    int intermediate_switches =
3101060SN/A                        m_component_inter_switches[src][dst];
3111060SN/A
3121060SN/A                    // NOTE switches are assumed to have single
3132292SN/A                    // cycle latency
3142292SN/A                    out << "  " << cur_mach << " -> " << dest_mach
3152292SN/A                        << " net_lat: "
3162292SN/A                        << link_latency + intermediate_switches << endl;
3178793Sgblack@eecs.umich.edu                }
3188793Sgblack@eecs.umich.edu            }
3198793Sgblack@eecs.umich.edu            out << endl;
3208793Sgblack@eecs.umich.edu        }
3218793Sgblack@eecs.umich.edu    }
3222831Sksewell@umich.edu
3238793Sgblack@eecs.umich.edu    out << "--- End Topology Print ---" << endl;
3248793Sgblack@eecs.umich.edu}
3258793Sgblack@eecs.umich.edu
3268793Sgblack@eecs.umich.edu// The following all-pairs shortest path algorithm is based on the
3278793Sgblack@eecs.umich.edu// discussion from Cormen et al., Chapter 26.1.
3282831Sksewell@umich.eduvoid
3292292SN/Aextend_shortest_path(Matrix& current_dist, Matrix& latencies,
3302316SN/A    Matrix& inter_switches)
3312292SN/A{
3322292SN/A    bool change = true;
3332292SN/A    int nodes = current_dist.size();
3342292SN/A
3352292SN/A    while (change) {
3362292SN/A        change = false;
3371060SN/A        for (int i = 0; i < nodes; i++) {
3382292SN/A            for (int j = 0; j < nodes; j++) {
3392292SN/A                int minimum = current_dist[i][j];
3401060SN/A                int previous_minimum = minimum;
3416221Snate@binkert.org                int intermediate_switch = -1;
3422307SN/A                for (int k = 0; k < nodes; k++) {
3432292SN/A                    minimum = min(minimum,
3449384SAndreas.Sandberg@arm.com                        current_dist[i][k] + current_dist[k][j]);
3459384SAndreas.Sandberg@arm.com                    if (previous_minimum != minimum) {
3462292SN/A                        intermediate_switch = k;
3472292SN/A                        inter_switches[i][j] =
3482325SN/A                            inter_switches[i][k] +
3492292SN/A                            inter_switches[k][j] + 1;
3502292SN/A                    }
3512292SN/A                    previous_minimum = minimum;
3522325SN/A                }
3532292SN/A                if (current_dist[i][j] != minimum) {
3542292SN/A                    change = true;
3552292SN/A                    current_dist[i][j] = minimum;
3562292SN/A                    assert(intermediate_switch >= 0);
3572292SN/A                    assert(intermediate_switch < latencies[i].size());
3582292SN/A                    latencies[i][j] = latencies[i][intermediate_switch] +
3592292SN/A                        latencies[intermediate_switch][j];
3602292SN/A                }
3612292SN/A            }
3622292SN/A        }
3632292SN/A    }
3642325SN/A}
3652292SN/A
3662292SN/AMatrix
3672292SN/Ashortest_path(const Matrix& weights, Matrix& latencies, Matrix& inter_switches)
3682325SN/A{
3692292SN/A    Matrix dist = weights;
3702292SN/A    extend_shortest_path(dist, latencies, inter_switches);
3712292SN/A    return dist;
3722292SN/A}
3732292SN/A
3742292SN/Abool
3752292SN/Alink_is_shortest_path_to_node(SwitchID src, SwitchID next, SwitchID final,
3762292SN/A    const Matrix& weights, const Matrix& dist)
3773221Sktlim@umich.edu{
3783221Sktlim@umich.edu    return weights[src][next] + dist[next][final] == dist[src][final];
3793221Sktlim@umich.edu}
3802292SN/A
3812292SN/ANetDest
3822292SN/Ashortest_path_to_node(SwitchID src, SwitchID next, const Matrix& weights,
3832292SN/A    const Matrix& dist)
3842292SN/A{
3852292SN/A    NetDest result;
3866221Snate@binkert.org    int d = 0;
3876221Snate@binkert.org    int machines;
3881060SN/A    int max_machines;
3892292SN/A
3901060SN/A    machines = MachineType_NUM;
3911060SN/A    max_machines = MachineType_base_number(MachineType_NUM);
3922292SN/A
3939158Sandreas.hansson@arm.com    for (int m = 0; m < machines; m++) {
3946221Snate@binkert.org        for (int i = 0; i < MachineType_base_count((MachineType)m); i++) {
3953093Sksewell@umich.edu            // we use "d+max_machines" below since the "destination"
3966221Snate@binkert.org            // switches for the machines are numbered
3976221Snate@binkert.org            // [MachineType_base_number(MachineType_NUM)...
3986221Snate@binkert.org            //  2*MachineType_base_number(MachineType_NUM)-1] for the
3993093Sksewell@umich.edu            // component network
4002292SN/A            if (link_is_shortest_path_to_node(src, next, d + max_machines,
4015595Sgblack@eecs.umich.edu                    weights, dist)) {
4025595Sgblack@eecs.umich.edu                MachineID mach = {(MachineType)m, i};
4035595Sgblack@eecs.umich.edu                result.add(mach);
4045595Sgblack@eecs.umich.edu            }
4055595Sgblack@eecs.umich.edu            d++;
4066221Snate@binkert.org        }
4078793Sgblack@eecs.umich.edu    }
4088793Sgblack@eecs.umich.edu
4098793Sgblack@eecs.umich.edu    DEBUG_MSG(NETWORK_COMP, MedPrio, "returning shortest path");
4108793Sgblack@eecs.umich.edu    DEBUG_EXPR(NETWORK_COMP, MedPrio, (src-(2*max_machines)));
4118793Sgblack@eecs.umich.edu    DEBUG_EXPR(NETWORK_COMP, MedPrio, (next-(2*max_machines)));
4128793Sgblack@eecs.umich.edu    DEBUG_EXPR(NETWORK_COMP, MedPrio, src);
4138793Sgblack@eecs.umich.edu    DEBUG_EXPR(NETWORK_COMP, MedPrio, next);
4148793Sgblack@eecs.umich.edu    DEBUG_EXPR(NETWORK_COMP, MedPrio, result);
4158793Sgblack@eecs.umich.edu    DEBUG_NEWLINE(NETWORK_COMP, MedPrio);
4168793Sgblack@eecs.umich.edu
4178793Sgblack@eecs.umich.edu    return result;
4185595Sgblack@eecs.umich.edu}
4198793Sgblack@eecs.umich.edu
4208793Sgblack@eecs.umich.eduTopology *
4218793Sgblack@eecs.umich.eduTopologyParams::create()
4228793Sgblack@eecs.umich.edu{
4238793Sgblack@eecs.umich.edu    return new Topology(this);
4248793Sgblack@eecs.umich.edu}
4255595Sgblack@eecs.umich.edu
4268793Sgblack@eecs.umich.eduLink *
4278793Sgblack@eecs.umich.eduLinkParams::create()
4288793Sgblack@eecs.umich.edu{
4298793Sgblack@eecs.umich.edu    return new Link(this);
4308793Sgblack@eecs.umich.edu}
4315595Sgblack@eecs.umich.edu
4325595Sgblack@eecs.umich.eduExtLink *
4335595Sgblack@eecs.umich.eduExtLinkParams::create()
4345595Sgblack@eecs.umich.edu{
4355595Sgblack@eecs.umich.edu    return new ExtLink(this);
4365595Sgblack@eecs.umich.edu}
4375595Sgblack@eecs.umich.edu
4385595Sgblack@eecs.umich.eduIntLink *
4395595Sgblack@eecs.umich.eduIntLinkParams::create()
4405595Sgblack@eecs.umich.edu{
4415595Sgblack@eecs.umich.edu    return new IntLink(this);
4425595Sgblack@eecs.umich.edu}
4435595Sgblack@eecs.umich.edu