Commit c7498dfa authored by Jonathon Duerig's avatar Jonathon Duerig
Browse files

Added new ratio-cut partitioning scheme and a METIS search-for-ratio-cut

partitioning scheme. They seem to perform about the same, which is not what was expected. Further tests and tweaks may uncover the cause.
parent 66a2c7db
// CutSearchPartition.h
#ifndef CUT_SEARCH_PARTITION_H_IP_ASSIGN_2
#define CUT_SEARCH_PARTITION_H_IP_ASSIGN_2
#include "Partition.h"
class CutSearchPartition : public Partition
{
public:
CutSearchPartition()
: m_lanCount(0)
, m_finalCount(0)
{
}
std::auto_ptr<Partition> CutSearchPartition::clone()
{
return std::auto_ptr<Partition>(new CutSearchPartition(*this));
}
virtual void addLan()
{
}
virtual void partition(std::vector<int> & indexes,
std::vector<int> & neighbors,
std::vector<int> & weights,
std::vector<int> & partitions)
{
m_lanCount = static_cast<int>(indexes.size() - 1);
partitions.resize(indexes.size() - 1);
fill(partitions.begin(), partitions.end(), 0);
int limit = static_cast<int>(sqrt(m_lanCount));
double bestScore = 1e37;
int bestCount = 1;
std::vector<int> current;
current.resize(partitions.size());
double currentScore = 0;
for (int i = 2; i < limit; ++i)
{
int partitionCount = i;
int temp = Partition::partitionN(partitionCount, indexes,
neighbors, weights,
current);
partitionCount = Partition::makeConnectedGraph(partitionCount,
indexes, neighbors,
weights,
current);
currentScore = static_cast<double>(temp) / partitionCount;
if (currentScore < bestScore)
{
bestCount = partitionCount;
bestScore = currentScore;
partitions = current;
cerr << "NewBest: " << i << ":" << partitionCount << endl;
}
}
m_finalCount = bestCount;
}
virtual int getPartitionCount(void)
{
return m_finalCount;
}
private:
int m_lanCount;
int m_finalCount;
};
#endif
......@@ -13,13 +13,15 @@
#include "ConservativeAssigner.h"
#include "HierarchicalAssigner.h"
#include "Router.h"
//#include "HostRouter.h"
#include "HostRouter.h"
//#include "LanRouter.h"
#include "NetRouter.h"
#include "Partition.h"
#include "FixedPartition.h"
#include "SearchPartition.h"
#include "SquareRootPartition.h"
#include "RatioCutPartition.h"
#include "CutSearchPartition.h"
using namespace std;
......@@ -202,7 +204,7 @@ void Framework::parseCommandLine(int argCount, char ** argArray)
switch (routeChoice)
{
case HostHost:
// m_route.reset(new HostRouter());
m_route.reset(new HostRouter());
break;
case HostLan:
// m_route.reset(new LanRouter());
......@@ -228,7 +230,7 @@ void Framework::parseArgument(string const & arg,
{
// p means this argument group is about partitions. It must be
// followed by a number (Fixed), a 'q' (SquareRoot),
// or an 's' (Search)
// an 's' (Search), or an 'r' (RatioCut)
case 'p':
// if there is a 'p', it must go in its own -group
// for example -p11 is legal but -p11h is not legal
......@@ -257,6 +259,16 @@ void Framework::parseArgument(string const & arg,
m_partition.reset(new SearchPartition);
done = true;
}
else if (arg[2] == 'r')
{
m_partition.reset(new RatioCutPartition);
done = true;
}
else if (arg[2] == 'c')
{
m_partition.reset(new CutSearchPartition);
done = true;
}
else
{
throw InvalidArgumentException(arg);
......
......@@ -50,7 +50,7 @@ private:
};
enum PartitionType
{
Fixed, SquareRoot, Search
Fixed, SquareRoot, Search, RatioCut
};
enum RouteType
{
......
......@@ -89,10 +89,11 @@ void HierarchicalAssigner::divideAndConquer(auto_ptr<ptree::Branch> & parent,
bool goodPartition = partitionPartition(parent.get(), blockBits,
partitionList, components);
auto_ptr<ptree::Branch> current(new ptree::Branch());
current->setNetworkEntry(subnet, totalBits - blockBits);
if (goodPartition)
{
int newBits = blockBits - countToBlockBit(components.size());
int newBits = blockBits - max(1, countToBlockBit(components.size() - 1));
// For each component
for (size_t i = 0; i < components.size(); ++i)
{
......@@ -174,10 +175,12 @@ bool HierarchicalAssigner::partitionPartition(ptree::Node * parent,
// Ensure that all sub-partitions fit in the blockspace.
bool goodPartition = partitioningIsOk(blockBits, partitioning,
partitionList);
if (goodPartition)
{
// divide up partitionList amongst the children.
components.resize(m_partition->getPartitionCount());
list<size_t>::iterator dividePos = partitionList.begin();
list<size_t>::iterator divideLimit = partitionList.end();
list<size_t>::iterator divideNext = dividePos;
......@@ -187,8 +190,10 @@ bool HierarchicalAssigner::partitionPartition(ptree::Node * parent,
// init
++divideNext;
components[*partPos].splice(components[*partPos].end(),
partitionList, dividePos);
components[*partPos].push_back(*dividePos);
// components[*partPos].splice(components[*partPos].end(),
// partitionList, dividePos);
// get ready for next iteration
dividePos = divideNext;
......
......@@ -25,33 +25,32 @@ HostRouter::~HostRouter()
auto_ptr<Router> HostRouter::clone(void) const
{
return auto_ptr<Router>(new HostRouter(*this));
// return auto_ptr<Router>(new HostRouter(*this));
return auto_ptr<Router>(NULL);
}
void HostRouter::calculateRoutes(void)
{
if (m_nodeToLevel.size() != 0 && m_levelMaskSize.size() != 0
&& m_levelPrefix.size() != 0 && m_levelMakeup.size() != 0
&& m_lanWeights.size() != 0)
if (hosts.size() != 0 && lans.size() != 0)
{
FileWrapper file(coprocess(ROUTECALC).release());
m_tableList.clear();
m_tableList.resize(m_nodeToLevel[0].size());
for (size_t i = 0; i < m_nodeToLevel[0].size(); ++i)
m_tableList.resize(hosts.size());
for (size_t i = 0; i < hosts.size(); ++i)
{
if (isValidNode(i))
{
m_tableList[i].resize(m_nodeToLevel[0].size());
for (size_t j = 0; j < m_nodeToLevel[0][i].size(); ++j)
m_tableList[i].resize(hosts.size());
for (size_t j = 0; j < hosts[i].size(); ++j)
{
size_t lan = m_nodeToLevel[0][i][j];
for (size_t k = 0; k < m_levelMakeup[0][lan].size(); ++k)
size_t lan = hosts[i][j];
for (size_t k = 0; k < lans[lan].hosts.size(); ++k)
{
size_t node = m_levelMakeup[0][lan][k];
size_t node = lans[lan].hosts[k];
if (i != node)
{
write(file, 'i', i, node,
static_cast<float>(m_lanWeights[lan]));
static_cast<float>(lans[lan].weight));
}
}
}
......@@ -101,11 +100,11 @@ void HostRouter::findAdjascentInterfaces(size_t node,
{
nodeToIP.clear();
// in every LAN that we're connected to
vector<size_t>::const_iterator lanPos = m_nodeToLevel[0][node].begin();
for (; lanPos != m_nodeToLevel[0][node].end(); ++lanPos)
vector<size_t>::const_iterator lanPos = hosts[node].begin();
for (; lanPos != hosts[node].end(); ++lanPos)
{
// in every node that is in one of those LANs
vector<size_t> const & firstHopList = m_levelMakeup[0][*lanPos];
vector<size_t> const & firstHopList = hosts[*lanPos];
vector<size_t>::const_iterator pos = firstHopList.begin();
for (; pos != firstHopList.end(); ++pos)
{
......@@ -113,7 +112,7 @@ void HostRouter::findAdjascentInterfaces(size_t node,
// the current node. But that is ok since the current node is
// never used as a firstHop.
// If this becomes an issue, put a conditional here.
nodeToIP[*pos] = m_levelPrefix[0][*lanPos] + *pos + 1;
nodeToIP[*pos] = lans[*lanPos].partition->getPrefix() + *pos + 1;
}
}
}
......@@ -122,25 +121,25 @@ void HostRouter::findAdjascentInterfaces(size_t node,
void HostRouter::printTable(ostream & output, size_t node,
map<size_t, IPAddress> & nodeToIP) const
{
size_t lanCount = m_levelMakeup[0].size();
size_t lanCount = lans.size();
// Print the routing table itself
output << "Routing table for node: " << node << endl;
for (size_t destLan = 0; destLan < lanCount; ++destLan)
{
for (size_t destNodeIndex = 0;
destNodeIndex < m_levelMakeup[0][destLan].size();
destNodeIndex < lans[destLan].hosts.size();
++destNodeIndex)
{
size_t destNode = m_levelMakeup[0][destLan][destNodeIndex];
size_t destNode = lans[destLan].hosts[destNodeIndex];
// if the destination LAN is not connected to the current node.
if (find(m_nodeToLevel[0][node].begin(),
m_nodeToLevel[0][node].end(), destLan)
== m_nodeToLevel[0][node].end())
if (find(hosts[node].begin(),
hosts[node].end(), destLan)
== hosts[node].end())
{
output << "Destination: "
<< ipToString(m_levelPrefix[0][destLan] + destNodeIndex
+ 1)
<< ipToString(lans[destLan].partition->getPrefix()
+ destNodeIndex + 1)
<< "/32" // host routing means no subnets
<< " FirstHop: "
<< ipToString(
......
......@@ -21,10 +21,34 @@ class HostRouter : public Router
public:
HostRouter();
virtual ~HostRouter();
virtual void visitBranch(ptree::Branch &)
{
}
virtual void visitLeaf(ptree::Leaf &)
{
}
virtual std::auto_ptr<Router> clone(void) const;
virtual void calculateRoutes(void);
virtual void print(std::ostream & output) const;
virtual std::auto_ptr<ptree::Node> & getTree(void)
{
return tree;
}
virtual std::vector<ptree::LeafLan> & getLans(void)
{
return lans;
}
virtual void setHosts(Assigner::NodeLookup & source)
{
hosts = source;
}
private:
// pre-processing for print. Each host has adjascent interfaces.
// The first hop information in m_tableList provides hops in terms of
......@@ -44,6 +68,9 @@ private:
// table. The second index is the destination. The result is the next
// hop.
std::vector<RouteTable> m_tableList;
std::auto_ptr<ptree::Node> tree;
std::vector<ptree::LeafLan> lans;
Assigner::NodeLookup hosts;
};
#endif
......
......@@ -34,7 +34,7 @@ public:
public:
// Most partitioning schemes (at least in the near future) will presumably
// use METIS. This is the common code to use METIS in the standard fashion.
static void partitionN(int partitionCount,
static int partitionN(int partitionCount,
std::vector<int> & indexes,
std::vector<int> & neighbors,
std::vector<int> & weights,
......@@ -96,6 +96,7 @@ public:
{
fill(partitions.begin(), partitions.end(), 0);
}
return edgesCut;
}
// Goes through every partition in the graph and checks to see if
......
This diff is collapsed.
......@@ -76,9 +76,12 @@ unsigned int countToBlock(unsigned int count)
int countToBlockBit(unsigned int count)
{
int size = 0;
for( ; count != 0; count >>= 1)
if (count >= 0)
{
++size;
for( ; count != 0; count >>= 1)
{
++size;
}
}
return size;
}
......
......@@ -25,6 +25,7 @@
#include <memory>
#include <climits>
#include <queue>
#include <iterator>
extern "C"
{
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment