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