NetDest.cc revision 8229:78bf55f23338
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/protocol/Protocol.hh"
30#include "mem/ruby/common/NetDest.hh"
31
32NetDest::NetDest()
33{
34  resize();
35}
36
37void
38NetDest::add(MachineID newElement)
39{
40    m_bits[vecIndex(newElement)].add(bitIndex(newElement.num));
41}
42
43void
44NetDest::addNetDest(const NetDest& netDest)
45{
46    assert(m_bits.size() == netDest.getSize());
47    for (int i = 0; i < m_bits.size(); i++) {
48        m_bits[i].addSet(netDest.m_bits[i]);
49    }
50}
51
52void
53NetDest::addRandom()
54{
55    int i = random()%m_bits.size();
56    m_bits[i].addRandom();
57}
58
59void
60NetDest::setNetDest(MachineType machine, const Set& set)
61{
62    // assure that there is only one set of destinations for this machine
63    assert(MachineType_base_level((MachineType)(machine + 1)) -
64           MachineType_base_level(machine) == 1);
65    m_bits[MachineType_base_level(machine)] = set;
66}
67
68void
69NetDest::remove(MachineID oldElement)
70{
71    m_bits[vecIndex(oldElement)].remove(bitIndex(oldElement.num));
72}
73
74void
75NetDest::removeNetDest(const NetDest& netDest)
76{
77    assert(m_bits.size() == netDest.getSize());
78    for (int i = 0; i < m_bits.size(); i++) {
79        m_bits[i].removeSet(netDest.m_bits[i]);
80    }
81}
82
83void
84NetDest::clear()
85{
86    for (int i = 0; i < m_bits.size(); i++) {
87        m_bits[i].clear();
88    }
89}
90
91void
92NetDest::broadcast()
93{
94    for (MachineType machine = MachineType_FIRST;
95         machine < MachineType_NUM; ++machine) {
96        broadcast(machine);
97    }
98}
99
100void
101NetDest::broadcast(MachineType machineType)
102{
103    for (int i = 0; i < MachineType_base_count(machineType); i++) {
104        MachineID mach = {machineType, i};
105        add(mach);
106    }
107}
108
109//For Princeton Network
110std::vector<NodeID>
111NetDest::getAllDest()
112{
113    std::vector<NodeID> dest;
114    dest.clear();
115    for (int i = 0; i < m_bits.size(); i++) {
116        for (int j = 0; j < m_bits[i].getSize(); j++) {
117            if (m_bits[i].isElement(j)) {
118                int id = MachineType_base_number((MachineType)i) + j;
119                dest.push_back((NodeID)id);
120            }
121        }
122    }
123    return dest;
124}
125
126int
127NetDest::count() const
128{
129    int counter = 0;
130    for (int i = 0; i < m_bits.size(); i++) {
131        counter += m_bits[i].count();
132    }
133    return counter;
134}
135
136NodeID
137NetDest::elementAt(MachineID index)
138{
139    return m_bits[vecIndex(index)].elementAt(bitIndex(index.num));
140}
141
142MachineID
143NetDest::smallestElement() const
144{
145    assert(count() > 0);
146    for (int i = 0; i < m_bits.size(); i++) {
147        for (int j = 0; j < m_bits[i].getSize(); j++) {
148            if (m_bits[i].isElement(j)) {
149                MachineID mach = {MachineType_from_base_level(i), j};
150                return mach;
151            }
152        }
153    }
154    panic("No smallest element of an empty set.");
155}
156
157MachineID
158NetDest::smallestElement(MachineType machine) const
159{
160    int size = m_bits[MachineType_base_level(machine)].getSize();
161    for (int j = 0; j < size; j++) {
162        if (m_bits[MachineType_base_level(machine)].isElement(j)) {
163            MachineID mach = {machine, j};
164            return mach;
165        }
166    }
167
168    panic("No smallest element of given MachineType.");
169}
170
171// Returns true iff all bits are set
172bool
173NetDest::isBroadcast() const
174{
175    for (int i = 0; i < m_bits.size(); i++) {
176        if (!m_bits[i].isBroadcast()) {
177            return false;
178        }
179    }
180    return true;
181}
182
183// Returns true iff no bits are set
184bool
185NetDest::isEmpty() const
186{
187    for (int i = 0; i < m_bits.size(); i++) {
188        if (!m_bits[i].isEmpty()) {
189            return false;
190        }
191    }
192    return true;
193}
194
195// returns the logical OR of "this" set and orNetDest
196NetDest
197NetDest::OR(const NetDest& orNetDest) const
198{
199    assert(m_bits.size() == orNetDest.getSize());
200    NetDest result;
201    for (int i = 0; i < m_bits.size(); i++) {
202        result.m_bits[i] = m_bits[i].OR(orNetDest.m_bits[i]);
203    }
204    return result;
205}
206
207// returns the logical AND of "this" set and andNetDest
208NetDest
209NetDest::AND(const NetDest& andNetDest) const
210{
211    assert(m_bits.size() == andNetDest.getSize());
212    NetDest result;
213    for (int i = 0; i < m_bits.size(); i++) {
214        result.m_bits[i] = m_bits[i].AND(andNetDest.m_bits[i]);
215    }
216    return result;
217}
218
219// Returns true if the intersection of the two sets is non-empty
220bool
221NetDest::intersectionIsNotEmpty(const NetDest& other_netDest) const
222{
223    assert(m_bits.size() == other_netDest.getSize());
224    for (int i = 0; i < m_bits.size(); i++) {
225        if (!m_bits[i].intersectionIsEmpty(other_netDest.m_bits[i])) {
226            return true;
227        }
228    }
229    return false;
230}
231
232bool
233NetDest::isSuperset(const NetDest& test) const
234{
235    assert(m_bits.size() == test.getSize());
236
237    for (int i = 0; i < m_bits.size(); i++) {
238        if (!m_bits[i].isSuperset(test.m_bits[i])) {
239            return false;
240        }
241    }
242    return true;
243}
244
245bool
246NetDest::isElement(MachineID element) const
247{
248    return ((m_bits[vecIndex(element)])).isElement(bitIndex(element.num));
249}
250
251void
252NetDest::resize()
253{
254    m_bits.resize(MachineType_base_level(MachineType_NUM));
255    assert(m_bits.size() == MachineType_NUM);
256
257    for (int i = 0; i < m_bits.size(); i++) {
258        m_bits[i].setSize(MachineType_base_count((MachineType)i));
259    }
260}
261
262void
263NetDest::print(std::ostream& out) const
264{
265    out << "[NetDest (" << m_bits.size() << ") ";
266
267    for (int i = 0; i < m_bits.size(); i++) {
268        for (int j = 0; j < m_bits[i].getSize(); j++) {
269            out << (bool) m_bits[i].isElement(j) << " ";
270        }
271        out << " - ";
272    }
273    out << "]";
274}
275
276