260 lines
6.6 KiB
C++
260 lines
6.6 KiB
C++
|
|
/*
|
|
* Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
|
|
* All rights reserved.
|
|
*
|
|
* Redistribution and use in source and binary forms, with or without
|
|
* modification, are permitted provided that the following conditions are
|
|
* met: redistributions of source code must retain the above copyright
|
|
* notice, this list of conditions and the following disclaimer;
|
|
* redistributions in binary form must reproduce the above copyright
|
|
* notice, this list of conditions and the following disclaimer in the
|
|
* documentation and/or other materials provided with the distribution;
|
|
* neither the name of the copyright holders nor the names of its
|
|
* contributors may be used to endorse or promote products derived from
|
|
* this software without specific prior written permission.
|
|
*
|
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
|
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
|
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
|
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
|
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
|
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
|
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
|
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
|
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
|
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
*/
|
|
|
|
/*
|
|
* NetDest.C
|
|
*
|
|
* Description: See NetDest.hh
|
|
*
|
|
* $Id$
|
|
*
|
|
*/
|
|
|
|
#include "mem/ruby/common/NetDest.hh"
|
|
#include "mem/protocol/Protocol.hh"
|
|
|
|
NetDest::NetDest()
|
|
{
|
|
setSize();
|
|
}
|
|
|
|
void NetDest::add(MachineID newElement)
|
|
{
|
|
m_bits[vecIndex(newElement)].add(bitIndex(newElement.num));
|
|
}
|
|
|
|
void NetDest::addNetDest(const NetDest& netDest)
|
|
{
|
|
assert(m_bits.size() == netDest.getSize());
|
|
for (int i = 0; i < m_bits.size(); i++) {
|
|
m_bits[i].addSet(netDest.m_bits[i]);
|
|
}
|
|
}
|
|
|
|
void NetDest::addRandom()
|
|
{
|
|
int i = random()%m_bits.size();
|
|
m_bits[i].addRandom();
|
|
}
|
|
|
|
void NetDest::setNetDest(MachineType machine, const Set& set)
|
|
{
|
|
// assure that there is only one set of destinations for this machine
|
|
assert(MachineType_base_level((MachineType)(machine+1)) - MachineType_base_level(machine) == 1);
|
|
m_bits[MachineType_base_level(machine)] = set;
|
|
}
|
|
|
|
void NetDest::remove(MachineID oldElement)
|
|
{
|
|
m_bits[vecIndex(oldElement)].remove(bitIndex(oldElement.num));
|
|
}
|
|
|
|
void NetDest::removeNetDest(const NetDest& netDest)
|
|
{
|
|
assert(m_bits.size() == netDest.getSize());
|
|
for (int i = 0; i < m_bits.size(); i++) {
|
|
m_bits[i].removeSet(netDest.m_bits[i]);
|
|
|
|
}
|
|
}
|
|
|
|
void NetDest::clear()
|
|
{
|
|
for (int i = 0; i < m_bits.size(); i++) {
|
|
m_bits[i].clear();
|
|
}
|
|
}
|
|
|
|
void NetDest::broadcast()
|
|
{
|
|
for (MachineType machine = MachineType_FIRST; machine < MachineType_NUM; ++machine) {
|
|
broadcast(machine);
|
|
}
|
|
}
|
|
|
|
void NetDest::broadcast(MachineType machineType) {
|
|
|
|
for (int i = 0; i < MachineType_base_count(machineType); i++) {
|
|
MachineID mach = {machineType, i};
|
|
add(mach);
|
|
}
|
|
}
|
|
|
|
//For Princeton Network
|
|
Vector<NodeID> NetDest::getAllDest() {
|
|
Vector<NodeID> dest;
|
|
dest.clear();
|
|
for (int i=0; i<m_bits.size(); i++) {
|
|
for (int j=0; j<m_bits[i].getSize(); j++) {
|
|
if (m_bits[i].isElement(j)) {
|
|
dest.insertAtBottom((NodeID) (MachineType_base_number((MachineType) i) + j));
|
|
}
|
|
}
|
|
}
|
|
return dest;
|
|
}
|
|
|
|
int NetDest::count() const
|
|
{
|
|
int counter = 0;
|
|
for (int i=0; i<m_bits.size(); i++) {
|
|
counter += m_bits[i].count();
|
|
}
|
|
return counter;
|
|
}
|
|
|
|
NodeID NetDest::elementAt(MachineID index) {
|
|
return m_bits[vecIndex(index)].elementAt(bitIndex(index.num));
|
|
}
|
|
|
|
MachineID NetDest::smallestElement() const
|
|
{
|
|
assert(count() > 0);
|
|
for (int i=0; i<m_bits.size(); i++) {
|
|
for (int j=0; j<m_bits[i].getSize(); j++) {
|
|
if (m_bits[i].isElement(j)) {
|
|
MachineID mach = {MachineType_from_base_level(i), j};
|
|
return mach;
|
|
}
|
|
}
|
|
}
|
|
ERROR_MSG("No smallest element of an empty set.");
|
|
}
|
|
|
|
MachineID NetDest::smallestElement(MachineType machine) const
|
|
{
|
|
for (int j = 0; j < m_bits[MachineType_base_level(machine)].getSize(); j++) {
|
|
if (m_bits[MachineType_base_level(machine)].isElement(j)) {
|
|
MachineID mach = {machine, j};
|
|
return mach;
|
|
}
|
|
}
|
|
|
|
ERROR_MSG("No smallest element of given MachineType.");
|
|
}
|
|
|
|
|
|
// Returns true iff all bits are set
|
|
bool NetDest::isBroadcast() const
|
|
{
|
|
for (int i=0; i<m_bits.size(); i++) {
|
|
if (!m_bits[i].isBroadcast()) {
|
|
return false;
|
|
}
|
|
}
|
|
return true;
|
|
}
|
|
|
|
// Returns true iff no bits are set
|
|
bool NetDest::isEmpty() const
|
|
{
|
|
for (int i=0; i<m_bits.size(); i++) {
|
|
if (!m_bits[i].isEmpty()) {
|
|
return false;
|
|
}
|
|
}
|
|
return true;
|
|
}
|
|
|
|
// returns the logical OR of "this" set and orNetDest
|
|
NetDest NetDest::OR(const NetDest& orNetDest) const
|
|
{
|
|
assert(m_bits.size() == orNetDest.getSize());
|
|
NetDest result;
|
|
for (int i=0; i<m_bits.size(); i++) {
|
|
result.m_bits[i] = m_bits[i].OR(orNetDest.m_bits[i]);
|
|
}
|
|
return result;
|
|
}
|
|
|
|
|
|
// returns the logical AND of "this" set and andNetDest
|
|
NetDest NetDest::AND(const NetDest& andNetDest) const
|
|
{
|
|
assert(m_bits.size() == andNetDest.getSize());
|
|
NetDest result;
|
|
for (int i=0; i<m_bits.size(); i++) {
|
|
result.m_bits[i] = m_bits[i].AND(andNetDest.m_bits[i]);
|
|
}
|
|
return result;
|
|
}
|
|
|
|
// Returns true if the intersection of the two sets is non-empty
|
|
bool NetDest::intersectionIsNotEmpty(const NetDest& other_netDest) const
|
|
{
|
|
assert(m_bits.size() == other_netDest.getSize());
|
|
for (int i=0; i<m_bits.size(); i++) {
|
|
if (m_bits[i].intersectionIsNotEmpty(other_netDest.m_bits[i])) {
|
|
return true;
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
|
|
bool NetDest::isSuperset(const NetDest& test) const
|
|
{
|
|
assert(m_bits.size() == test.getSize());
|
|
|
|
for (int i=0; i<m_bits.size(); i++) {
|
|
if (!m_bits[i].isSuperset(test.m_bits[i])) {
|
|
return false;
|
|
}
|
|
}
|
|
return true;
|
|
}
|
|
|
|
bool NetDest::isElement(MachineID element) const
|
|
{
|
|
return ((m_bits[vecIndex(element)])).isElement(bitIndex(element.num));
|
|
}
|
|
|
|
void NetDest::setSize()
|
|
{
|
|
m_bits.setSize(MachineType_base_level(MachineType_NUM));
|
|
assert(m_bits.size() == MachineType_NUM);
|
|
|
|
for (int i = 0; i < m_bits.size(); i++) {
|
|
m_bits[i].setSize(MachineType_base_count((MachineType)i));
|
|
}
|
|
}
|
|
|
|
void NetDest::print(ostream& out) const
|
|
{
|
|
out << "[NetDest (" << m_bits.size() << ") ";
|
|
|
|
for (int i=0; i<m_bits.size(); i++) {
|
|
for (int j=0; j<m_bits[i].getSize(); j++) {
|
|
out << (bool) m_bits[i].isElement(j) << " ";
|
|
}
|
|
out << " - ";
|
|
}
|
|
out << "]";
|
|
}
|
|
|