Commit 11d41ac6 authored by Jonathon Duerig's avatar Jonathon Duerig

Added support for disconnected graphs

parent 9404b235
......@@ -3,9 +3,9 @@
export EXTRA_LIB_PATH=/home/duerig/metis/metis-4.0
export EXTRA_INCLUDE_PATH=/home/duerig/metis/metis-4.0/Lib/
g++ -O3 -c -o tmp/ipassign.o -I${EXTRA_INCLUDE_PATH} -DROUTECALC=\"bin/routecalc\" src/ipassign.cc
g++ -O3 -c -o tmp/bitmath.o -I${EXTRA_INCLUDE_PATH} -DROUTECALC=\"bin/routecalc\" src/bitmath.cc
g++ -O3 -c -o tmp/Assigner.o -I${EXTRA_INCLUDE_PATH} -DROUTECALC=\"bin/routecalc\" src/Assigner.cc
#g++ -O3 -c -o tmp/ipassign.o -I${EXTRA_INCLUDE_PATH} -DROUTECALC=\"bin/routecalc\" src/ipassign.cc
#g++ -O3 -c -o tmp/bitmath.o -I${EXTRA_INCLUDE_PATH} -DROUTECALC=\"bin/routecalc\" src/bitmath.cc
#g++ -O3 -c -o tmp/Assigner.o -I${EXTRA_INCLUDE_PATH} -DROUTECALC=\"bin/routecalc\" src/Assigner.cc
g++ -O3 -c -o tmp/ConservativeAssigner.o -I${EXTRA_INCLUDE_PATH} -DROUTECALC=\"bin/routecalc\" src/ConservativeAssigner.cc
g++ -O3 -c -o tmp/Framework.o -I${EXTRA_INCLUDE_PATH} -DROUTECALC=\"bin/routecalc\" src/Framework.cc
g++ -O3 -c -o tmp/HostRouter.o -I${EXTRA_INCLUDE_PATH} -DROUTECALC=\"bin/routecalc\" src/HostRouter.cc
......
1 0 1
1 0 2
1 0 3
1 1 4
1 4 5 6
1 1 7
1 7 8 9
1 1 10
1 10 11 12
1 2 13
1 2 14
1 2 15
1 13 16 17
1 14 18 19
1 15 20 21
1 3 22
1 3 23
1 3 24
1 22 25 26
1 23 27 28
1 24 29 30
8 1 0 1
8 1 0 2
8 1 0 3
8 1 1 4
8 1 4 5 6
8 1 1 7
8 1 7 8 9
8 1 1 10
8 1 10 11 12
8 1 2 13
8 1 2 14
8 1 2 15
8 1 13 16 17
8 1 14 18 19
8 1 15 20 21
8 1 3 22
8 1 3 23
8 1 3 24
8 1 22 25 26
8 1 23 27 28
8 1 24 29 30
......@@ -64,16 +64,6 @@ void ConservativeAssigner::addLan(int bits, int weight, vector<size_t> nodes)
void ConservativeAssigner::ipAssign(void)
{
// TODO: When I fix the disconnected graphs problem, remove this.
// The reason that this is here is that disconnected graphs don't
// cause an error until route calculation. The error that is caused
// is not obviously due to the graph not being connected. Therefore,
// this is provided as a hint until that is fixed.
if (!(isConnected(0)))
{
cerr << "Graph is not connected" << endl;
}
// These hold a METIS-ready conversion of the LAN-graph data.
std::vector<int> partitionArray;
std::vector<int> graphIndexArray;
......@@ -142,6 +132,11 @@ void ConservativeAssigner::ipAssign(void)
++loop;
}
// Calculate the list of super-partitions. These are the
// fully-connected subgraphs in the possibly disconnected
// super-graph. There should usually only be one super-partition.
calculateSuperPartitions();
//////////////////////////////////////////////////////
// find out which bits go to which subnet
//////////////////////////////////////////////////////
......@@ -271,12 +266,10 @@ void ConservativeAssigner::graph(vector<Assigner::NodeLookup> & nodeToLevel,
(levelMakeup.back())[m_lanList[i].partition].push_back(i);
}
levelMakeup.push_back(LevelLookup());
levelMakeup.back().resize(1);
for (i = 0; i < levelMakeup[1].size(); ++i)
{
levelMakeup.back().back().push_back(i);
}
// Add our super-partitions to the hierarchy. Each super-partition
// is a fully-connected sub-graph in a possibly disconnected
// graph.
levelMakeup.push_back(m_superPartitionList);
// set up the lan weights.
lanWeights.resize(m_lanList.size());
......@@ -491,7 +484,7 @@ bool ConservativeAssigner::isConnected(int whichPartition)
void ConservativeAssigner::makeConnected(int whichPartition)
{
// breadth first search. This is very similar to isConnected()
// breadth first search.
queue<size_t> nextConnection;
size_t first = 0;
size_t numInPartition = 0;
......@@ -558,5 +551,93 @@ void ConservativeAssigner::makeConnected(int whichPartition)
++m_partitionCount;
}
}
namespace
{
enum TouchedT
{
NotTouched,
Touched,
OldTouched
};
}
void ConservativeAssigner::calculateSuperPartitions(void)
{
vector<TouchedT> touch;
queue<size_t> nextConnection;
set<size_t> currentResult;
touch.resize(m_lanList.size());
fill(touch.begin(), touch.end(), NotTouched);
// Initialize first. 'first' is the arbitrary initial node in the
// breadth-first search.
size_t first = 0;
while (first < touch.size()
&& (touch[first] == Touched || touch[first] == OldTouched))
{
++first;
}
while (first < touch.size())
{
// Run a breadth-first search through the graph, marking the
// LANs we find as Touched. The partition of each LAN is added
// to the list of partitions in the super-partition we are
// constructing.
touch[first] = Touched;
nextConnection.push(first);
currentResult.clear();
while (!(nextConnection.empty()))
{
size_t current = nextConnection.front();
nextConnection.pop();
for (size_t i = 0; i < m_lanList[current].nodes.size(); ++i)
{
size_t currentNode = m_lanList[current].nodes[i];
for (size_t j = 0; j < m_nodeToLan[currentNode].size(); ++j)
{
size_t destLan = m_nodeToLan[currentNode][j];
if (touch[destLan] == NotTouched)
{
touch[destLan] = Touched;
nextConnection.push(destLan);
currentResult.insert(m_lanList[destLan].partition);
}
}
}
}
// The currentResult holds all of the partitions in the fully
// connected super-partition. So we add the list to the
// super-partition list.
if (!(currentResult.empty()))
{
m_superPartitionList.push_back(vector<size_t>());
m_superPartitionList.back().reserve(currentResult.size());
set<size_t>::iterator pos = currentResult.begin();
set<size_t>::iterator limit = currentResult.end();
for ( ; pos != limit; ++pos)
{
m_superPartitionList.back().push_back(*pos);
}
}
// We change all of the elements that were 'Touched' into
// 'OldTouched' to distinguish between the current iteration
// of the graph and previous ones.
for (size_t i = 0; i < touch.size(); ++i)
{
if (touch[i] == Touched)
{
touch[i] = OldTouched;
}
}
// get next first
while (first < touch.size()
&& (touch[first] == Touched || touch[first] == OldTouched))
{
++first;
}
}
}
......@@ -88,6 +88,8 @@ private:
// If a particular partition is disconnected, seperate it into two
// partitions.
void makeConnected(int whichPartition);
void calculateSuperPartitions(void);
private:
// Information about each LAN, indexed by the number assigned to each
// LAN.
......@@ -109,6 +111,11 @@ private:
// This pointer is used polymorphically to determine which partitioning
// method to use.
Partition * m_partition;
// The super-partition table. Each vector contains all of the
// partitions inside the super-partition. The number of
// super-partitions is the number of internally connected
// sub-graphs in the (possibly disconnected) graph.
std::vector< std::vector<size_t> > m_superPartitionList;
};
#endif
......
......@@ -131,17 +131,5 @@ public:
}
};
// TODO:
// Can be thrown during route calculation. This should be removed once
// the disconnected graph problem is fixed.
class NoTopLevelException : public StringException
{
public:
explicit NoTopLevelException(std::string const & error)
: StringException("Routing Graph had no top level: " + error)
{
}
};
#endif
......@@ -94,39 +94,11 @@ void NetRouter::setup(void)
throw NoGraphToRouteException("");
}
// the top level should contain only a single partition
if (m_levelMakeup.back().size() > 1)
{
throw NoTopLevelException("");
}
size_t total = 0;
for (i = 0; i < m_levelMakeup[0].size(); ++i)
{
for (j = 0; j < m_levelMakeup[0][i].size(); ++j)
{
size_t node = m_levelMakeup[0][i][j];
total += m_nodeToLevel[0][node].size() - 1;
}
}
double result = static_cast<double>(total) / m_levelMakeup[0].size();
cerr << "Average degree: " << result << endl;
/* if (m_nodeToLevel[1][859].size() == 2)
{
cerr << "859 partitions: " << m_nodeToLevel[1][859][0] << " " << m_nodeToLevel[1][859][1] << endl;
for (size_t i = 0; i < 2; ++i)
{
size_t currentPartition = m_nodeToLevel[1][859][i];
cerr << "Lans in " << i << ": ";
for (size_t j = 0; j < m_levelMakeup[1][currentPartition].size(); ++j)
{
cerr << m_levelMakeup[1][currentPartition][j] << " ";
}
cerr << endl;
}
}*/
// The top level may contain more than one single partition. If it
// does, that represents a disconnected graph and routes are
// calculated only within each partition.
// Remove any pre-existing connections between hosts.
borderConnections.clear();
reverseBorderConnections.clear();
......
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