SimpleNetwork.cc revision 8255
11758SN/A/*
21762SN/A * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
31758SN/A * All rights reserved.
41758SN/A *
51758SN/A * Redistribution and use in source and binary forms, with or without
61758SN/A * modification, are permitted provided that the following conditions are
71758SN/A * met: redistributions of source code must retain the above copyright
81758SN/A * notice, this list of conditions and the following disclaimer;
91758SN/A * redistributions in binary form must reproduce the above copyright
101758SN/A * notice, this list of conditions and the following disclaimer in the
111758SN/A * documentation and/or other materials provided with the distribution;
121758SN/A * neither the name of the copyright holders nor the names of its
131758SN/A * contributors may be used to endorse or promote products derived from
141758SN/A * this software without specific prior written permission.
151758SN/A *
161758SN/A * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
171758SN/A * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
181758SN/A * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
191758SN/A * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
201758SN/A * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
211758SN/A * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
221758SN/A * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
231758SN/A * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
241758SN/A * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
251758SN/A * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
261758SN/A * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
272665Ssaidi@eecs.umich.edu */
282665Ssaidi@eecs.umich.edu
292665Ssaidi@eecs.umich.edu#include <cassert>
301758SN/A#include <numeric>
312SN/A
322984Sgblack@eecs.umich.edu#include "base/stl_helpers.hh"
33732SN/A#include "mem/protocol/MachineType.hh"
343565Sgblack@eecs.umich.edu#include "mem/protocol/Protocol.hh"
35732SN/A#include "mem/protocol/TopologyType.hh"
362984Sgblack@eecs.umich.edu#include "mem/ruby/buffers/MessageBuffer.hh"
373536Sgblack@eecs.umich.edu#include "mem/ruby/common/NetDest.hh"
38732SN/A#include "mem/ruby/network/simple/SimpleNetwork.hh"
39732SN/A#include "mem/ruby/network/simple/Switch.hh"
401858SN/A#include "mem/ruby/network/simple/Throttle.hh"
411717SN/A#include "mem/ruby/network/Topology.hh"
422683Sktlim@umich.edu#include "mem/ruby/profiler/Profiler.hh"
432680Sktlim@umich.edu#include "mem/ruby/system/System.hh"
44676SN/A
452710Sstever@eecs.umich.eduusing namespace std;
462SN/Ausing m5::stl_helpers::deletePointers;
475568Snate@binkert.org
485566Snate@binkert.org#if 0
491858SN/A// ***BIG HACK*** - This is actually code that _should_ be in Network.cc
502SN/A
512SN/A// Note: Moved to Princeton Network
522SN/A// calls new to abstract away from the network
532SN/ANetwork*
542SN/ANetwork::createNetwork(int nodes)
552SN/A{
565568Snate@binkert.org    return new SimpleNetwork(nodes);
572SN/A}
582680Sktlim@umich.edu#endif
59190SN/A
602680Sktlim@umich.eduSimpleNetwork::SimpleNetwork(const Params *p)
612680Sktlim@umich.edu    : Network(p)
622114SN/A{
635568Snate@binkert.org    // Note: the parent Network Object constructor is called before the
642700Sktlim@umich.edu    // SimpleNetwork child constructor.  Therefore, the member variables
654172Ssaidi@eecs.umich.edu    // used below should already be initialized.
662680Sktlim@umich.edu
672700Sktlim@umich.edu    m_endpoint_switches.resize(m_nodes);
682700Sktlim@umich.edu
692SN/A    m_in_use.resize(m_virtual_networks);
702SN/A    m_ordered.resize(m_virtual_networks);
712SN/A    for (int i = 0; i < m_virtual_networks; i++) {
721133SN/A        m_in_use[i] = false;
73716SN/A        m_ordered[i] = false;
745568Snate@binkert.org    }
75716SN/A
76716SN/A    // Allocate to and from queues
77716SN/A    m_toNetQueues.resize(m_nodes);
78716SN/A    m_fromNetQueues.resize(m_nodes);
79716SN/A    for (int node = 0; node < m_nodes; node++) {
80716SN/A        m_toNetQueues[node].resize(m_virtual_networks);
814172Ssaidi@eecs.umich.edu        m_fromNetQueues[node].resize(m_virtual_networks);
82716SN/A        for (int j = 0; j < m_virtual_networks; j++) {
83716SN/A            m_toNetQueues[node][j] =
844172Ssaidi@eecs.umich.edu                new MessageBuffer(csprintf("toNet node %d j %d", node, j));
85716SN/A            m_fromNetQueues[node][j] =
86716SN/A                new MessageBuffer(csprintf("fromNet node %d j %d", node, j));
874172Ssaidi@eecs.umich.edu        }
88716SN/A    }
89716SN/A}
90716SN/A
91716SN/Avoid
92716SN/ASimpleNetwork::init()
93716SN/A{
94716SN/A    Network::init();
951133SN/A
96716SN/A    // The topology pointer should have already been initialized in
97716SN/A    // the parent class network constructor.
98716SN/A    assert(m_topology_ptr != NULL);
99716SN/A    int number_of_switches = m_topology_ptr->numSwitches();
100716SN/A    for (int i = 0; i < number_of_switches; i++) {
101716SN/A        m_switch_ptr_vector.push_back(new Switch(i, this));
102716SN/A    }
103716SN/A
104716SN/A    // false because this isn't a reconfiguration
105716SN/A    m_topology_ptr->createLinks(this, false);
106716SN/A}
107716SN/A
1084172Ssaidi@eecs.umich.eduvoid
1094172Ssaidi@eecs.umich.eduSimpleNetwork::reset()
1104172Ssaidi@eecs.umich.edu{
1112147SN/A    for (int node = 0; node < m_nodes; node++) {
112716SN/A        for (int j = 0; j < m_virtual_networks; j++) {
1134172Ssaidi@eecs.umich.edu            m_toNetQueues[node][j]->clear();
114716SN/A            m_fromNetQueues[node][j]->clear();
115716SN/A        }
116716SN/A    }
117716SN/A
1181133SN/A    for(int i = 0; i < m_switch_ptr_vector.size(); i++){
119716SN/A        m_switch_ptr_vector[i]->clearBuffers();
1205568Snate@binkert.org    }
121716SN/A}
122716SN/A
123739SN/ASimpleNetwork::~SimpleNetwork()
124739SN/A{
1252683Sktlim@umich.edu    for (int i = 0; i < m_nodes; i++) {
1262683Sktlim@umich.edu        deletePointers(m_toNetQueues[i]);
127716SN/A        deletePointers(m_fromNetQueues[i]);
128716SN/A    }
1295568Snate@binkert.org    deletePointers(m_switch_ptr_vector);
1305568Snate@binkert.org    deletePointers(m_buffers_to_free);
1312SN/A    // delete m_topology_ptr;
1325568Snate@binkert.org}
1332SN/A
1342SN/A// From a switch to an endpoint node
1352245SN/Avoid
1365568Snate@binkert.orgSimpleNetwork::makeOutLink(SwitchID src, NodeID dest,
1372245SN/A    const NetDest& routing_table_entry, int link_latency, int link_weight,
1385568Snate@binkert.org    int bw_multiplier, bool isReconfiguration)
1392245SN/A{
1402245SN/A    assert(dest < m_nodes);
1414997Sgblack@eecs.umich.edu    assert(src < m_switch_ptr_vector.size());
1424997Sgblack@eecs.umich.edu    assert(m_switch_ptr_vector[src] != NULL);
1434997Sgblack@eecs.umich.edu
1444997Sgblack@eecs.umich.edu    if (isReconfiguration) {
1454997Sgblack@eecs.umich.edu        m_switch_ptr_vector[src]->reconfigureOutPort(routing_table_entry);
1464997Sgblack@eecs.umich.edu        return;
1474997Sgblack@eecs.umich.edu    }
1485568Snate@binkert.org
1494997Sgblack@eecs.umich.edu    m_switch_ptr_vector[src]->addOutPort(m_fromNetQueues[dest],
1504997Sgblack@eecs.umich.edu        routing_table_entry, link_latency, bw_multiplier);
1514997Sgblack@eecs.umich.edu    m_endpoint_switches[dest] = m_switch_ptr_vector[src];
1524997Sgblack@eecs.umich.edu}
1534997Sgblack@eecs.umich.edu
1545568Snate@binkert.org// From an endpoint node to a switch
1554997Sgblack@eecs.umich.eduvoid
1564997Sgblack@eecs.umich.eduSimpleNetwork::makeInLink(NodeID src, SwitchID dest,
1574997Sgblack@eecs.umich.edu    const NetDest& routing_table_entry, int link_latency, int bw_multiplier,
1584997Sgblack@eecs.umich.edu    bool isReconfiguration)
1595568Snate@binkert.org{
1605568Snate@binkert.org    assert(src < m_nodes);
1612159SN/A    if (isReconfiguration) {
1625543Ssaidi@eecs.umich.edu        // do nothing
1632SN/A        return;
1642SN/A    }
1655568Snate@binkert.org
1665568Snate@binkert.org    m_switch_ptr_vector[dest]->addInPort(m_toNetQueues[src]);
1675568Snate@binkert.org}
1685568Snate@binkert.org
1695568Snate@binkert.org// From a switch to a switch
1705568Snate@binkert.orgvoid
1715568Snate@binkert.orgSimpleNetwork::makeInternalLink(SwitchID src, SwitchID dest,
1725568Snate@binkert.org    const NetDest& routing_table_entry, int link_latency, int link_weight,
1735568Snate@binkert.org    int bw_multiplier, bool isReconfiguration)
1745568Snate@binkert.org{
1755568Snate@binkert.org    if (isReconfiguration) {
1765568Snate@binkert.org        m_switch_ptr_vector[src]->reconfigureOutPort(routing_table_entry);
1775568Snate@binkert.org        return;
1785568Snate@binkert.org    }
1795568Snate@binkert.org
1805568Snate@binkert.org    // Create a set of new MessageBuffers
1815568Snate@binkert.org    std::vector<MessageBuffer*> queues;
1825568Snate@binkert.org    for (int i = 0; i < m_virtual_networks; i++) {
1835568Snate@binkert.org        // allocate a buffer
1845568Snate@binkert.org        MessageBuffer* buffer_ptr = new MessageBuffer;
1855568Snate@binkert.org        buffer_ptr->setOrdering(true);
1865568Snate@binkert.org        if (m_buffer_size > 0) {
1875568Snate@binkert.org            buffer_ptr->resize(m_buffer_size);
1885568Snate@binkert.org        }
1895568Snate@binkert.org        queues.push_back(buffer_ptr);
1902SN/A        // remember to deallocate it
1915568Snate@binkert.org        m_buffers_to_free.push_back(buffer_ptr);
1925568Snate@binkert.org    }
1935568Snate@binkert.org    // Connect it to the two switches
1945568Snate@binkert.org    m_switch_ptr_vector[dest]->addInPort(queues);
1955568Snate@binkert.org    m_switch_ptr_vector[src]->addOutPort(queues, routing_table_entry,
1965568Snate@binkert.org        link_latency, bw_multiplier);
1975568Snate@binkert.org}
1985568Snate@binkert.org
1995568Snate@binkert.orgvoid
2005568Snate@binkert.orgSimpleNetwork::checkNetworkAllocation(NodeID id, bool ordered, int network_num)
2015568Snate@binkert.org{
2025568Snate@binkert.org    assert(id < m_nodes);
2035568Snate@binkert.org    assert(network_num < m_virtual_networks);
2045568Snate@binkert.org
2055568Snate@binkert.org    if (ordered) {
2065568Snate@binkert.org        m_ordered[network_num] = true;
2075568Snate@binkert.org    }
2082SN/A    m_in_use[network_num] = true;
2092SN/A}
2102SN/A
2112SN/AMessageBuffer*
2125568Snate@binkert.orgSimpleNetwork::getToNetQueue(NodeID id, bool ordered, int network_num)
213597SN/A{
2142680Sktlim@umich.edu    checkNetworkAllocation(id, ordered, network_num);
215597SN/A    return m_toNetQueues[id][network_num];
216597SN/A}
2175568Snate@binkert.org
2182SN/AMessageBuffer*
2192SN/ASimpleNetwork::getFromNetQueue(NodeID id, bool ordered, int network_num)
2202SN/A{
2215568Snate@binkert.org    checkNetworkAllocation(id, ordered, network_num);
2225568Snate@binkert.org    return m_fromNetQueues[id][network_num];
2235568Snate@binkert.org}
2245568Snate@binkert.org
2255568Snate@binkert.orgconst std::vector<Throttle*>*
2262SN/ASimpleNetwork::getThrottles(NodeID id) const
2272SN/A{
2282SN/A    assert(id >= 0);
2295568Snate@binkert.org    assert(id < m_nodes);
2302SN/A    assert(m_endpoint_switches[id] != NULL);
2315568Snate@binkert.org    return m_endpoint_switches[id]->getThrottles();
2325004Sgblack@eecs.umich.edu}
2332SN/A
2345004Sgblack@eecs.umich.eduvoid
2355004Sgblack@eecs.umich.eduSimpleNetwork::printStats(ostream& out) const
2365004Sgblack@eecs.umich.edu{
2375004Sgblack@eecs.umich.edu    out << endl;
2385004Sgblack@eecs.umich.edu    out << "Network Stats" << endl;
2395004Sgblack@eecs.umich.edu    out << "-------------" << endl;
2405004Sgblack@eecs.umich.edu    out << endl;
2412SN/A
2422SN/A    //
2432SN/A    // Determine total counts before printing out each switch's stats
2442SN/A    //
2455568Snate@binkert.org    std::vector<uint64> total_msg_counts;
2465568Snate@binkert.org    total_msg_counts.resize(MessageSizeType_NUM);
2475568Snate@binkert.org    for (MessageSizeType type = MessageSizeType_FIRST;
2485568Snate@binkert.org         type < MessageSizeType_NUM;
2495568Snate@binkert.org         ++type) {
2505568Snate@binkert.org        total_msg_counts[type] = 0;
2515568Snate@binkert.org    }
2525568Snate@binkert.org
2535568Snate@binkert.org    for (int i = 0; i < m_switch_ptr_vector.size(); i++) {
2543468Sgblack@eecs.umich.edu        const std::vector<Throttle*>* throttles =
2552SN/A            m_switch_ptr_vector[i]->getThrottles();
2562SN/A
2572SN/A        for (int p = 0; p < throttles->size(); p++) {
2582SN/A
2593468Sgblack@eecs.umich.edu            const std::vector<std::vector<int> >& message_counts =
2602SN/A                ((*throttles)[p])->getCounters();
2612SN/A
2622SN/A            for (MessageSizeType type = MessageSizeType_FIRST;
2632SN/A                 type < MessageSizeType_NUM;
2642SN/A                 ++type) {
2652SN/A
2662SN/A                const std::vector<int> &mct = message_counts[type];
2672SN/A                int sum = accumulate(mct.begin(), mct.end(), 0);
2682SN/A                total_msg_counts[type] += uint64(sum);
2692SN/A            }
2702SN/A        }
2713468Sgblack@eecs.umich.edu    }
2725568Snate@binkert.org    uint64 total_msgs = 0;
2732SN/A    uint64 total_bytes = 0;
274710SN/A    for (MessageSizeType type = MessageSizeType_FIRST;
2752SN/A         type < MessageSizeType_NUM;
2762680Sktlim@umich.edu         ++type) {
2773468Sgblack@eecs.umich.edu
2782SN/A        if (total_msg_counts[type] > 0) {
2792SN/A            out << "total_msg_count_" << type << ": " << total_msg_counts[type]
2805568Snate@binkert.org                << " " << total_msg_counts[type] *
2815568Snate@binkert.org                uint64(RubySystem::getNetwork()->MessageSizeType_to_int(type))
2825568Snate@binkert.org                << endl;
2835568Snate@binkert.org
2845568Snate@binkert.org            total_msgs += total_msg_counts[type];
2855568Snate@binkert.org
2865568Snate@binkert.org            total_bytes += total_msg_counts[type] *
2875568Snate@binkert.org                uint64(RubySystem::getNetwork()->MessageSizeType_to_int(type));
2885568Snate@binkert.org
2895568Snate@binkert.org        }
2905568Snate@binkert.org    }
2915568Snate@binkert.org
2925568Snate@binkert.org    out << "total_msgs: " << total_msgs
2935568Snate@binkert.org        << " total_bytes: " << total_bytes << endl;
2945568Snate@binkert.org
2955568Snate@binkert.org    out << endl;
2965568Snate@binkert.org    for (int i = 0; i < m_switch_ptr_vector.size(); i++) {
2975568Snate@binkert.org        m_switch_ptr_vector[i]->printStats(out);
2985568Snate@binkert.org    }
2995568Snate@binkert.org    m_topology_ptr->printStats(out);
3005568Snate@binkert.org}
3015568Snate@binkert.org
3025568Snate@binkert.orgvoid
3035568Snate@binkert.orgSimpleNetwork::clearStats()
3045568Snate@binkert.org{
3055568Snate@binkert.org    for (int i = 0; i < m_switch_ptr_vector.size(); i++) {
3065568Snate@binkert.org        m_switch_ptr_vector[i]->clearStats();
3072SN/A    }
3082SN/A    m_topology_ptr->clearStats();
3092SN/A}
3102SN/A
3115568Snate@binkert.orgvoid
312596SN/ASimpleNetwork::printConfig(ostream& out) const
313596SN/A{
314596SN/A    out << endl;
315596SN/A    out << "Network Configuration" << endl;
316596SN/A    out << "---------------------" << endl;
317596SN/A    out << "network: SIMPLE_NETWORK" << endl;
3185568Snate@binkert.org    out << "topology: " << m_topology_ptr->getName() << endl;
319596SN/A    out << endl;
320596SN/A
321596SN/A    for (int i = 0; i < m_virtual_networks; i++) {
322596SN/A        out << "virtual_net_" << i << ": ";
323596SN/A        if (m_in_use[i]) {
324596SN/A            out << "active, ";
3255568Snate@binkert.org            if (m_ordered[i]) {
3262SN/A                out << "ordered" << endl;
327710SN/A            } else {
3282SN/A                out << "unordered" << endl;
3294997Sgblack@eecs.umich.edu            }
3302680Sktlim@umich.edu        } else {
3312680Sktlim@umich.edu            out << "inactive" << endl;
3324997Sgblack@eecs.umich.edu        }
3332SN/A    }
3342SN/A    out << endl;
3355568Snate@binkert.org
3362SN/A    for(int i = 0; i < m_switch_ptr_vector.size(); i++) {
3372SN/A        m_switch_ptr_vector[i]->printConfig(out);
3382SN/A    }
3392SN/A
3405568Snate@binkert.org    m_topology_ptr->printConfig(out);
3412SN/A}
3422SN/A
3432SN/Avoid
3442SN/ASimpleNetwork::print(ostream& out) const
3455568Snate@binkert.org{
3465568Snate@binkert.org    out << "[SimpleNetwork]";
3472SN/A}
3482SN/A
3492SN/A
3502SN/ASimpleNetwork *
3515568Snate@binkert.orgSimpleNetworkParams::create()
3522SN/A{
3532SN/A    return new SimpleNetwork(this);
3542SN/A}
3552SN/A