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