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