Adds a special graph for MLD with effcient boundary scan

This graph enables efficient boundary edge scans at each level.
Currenly this needs about |V|*|L| bytes of storage.
We can optimize this when the highest boundary nodes ID is << |V|.
This commit is contained in:
Patrick Niklaus
2017-03-07 03:59:28 +00:00
committed by Patrick Niklaus
parent 58681fa7ea
commit 655ca803d8
12 changed files with 518 additions and 131 deletions
@@ -90,6 +90,8 @@ template <> class AlgorithmDataFacade<algorithm::MLD>
virtual const partition::CellStorageView &GetCellStorage() const = 0;
virtual EdgeRange GetBorderEdgeRange(const LevelID level, const NodeID node) const = 0;
// searches for a specific edge
virtual EdgeID FindEdge(const NodeID from, const NodeID to) const = 0;
};
@@ -902,10 +902,16 @@ class ContiguousInternalMemoryAlgorithmDataFacade<algorithm::MLD>
// MLD data
partition::MultiLevelPartitionView mld_partition;
partition::CellStorageView mld_cell_storage;
using QueryGraph = customizer::MultiLevelEdgeBasedGraphView;
using GraphNode = QueryGraph::NodeArrayEntry;
using GraphEdge = QueryGraph::EdgeArrayEntry;
QueryGraph query_graph;
void InitializeInternalPointers(storage::DataLayout &data_layout, char *memory_block)
{
InitializeMLDDataPointers(data_layout, memory_block);
InitializeGraphPointer(data_layout, memory_block);
}
void InitializeMLDDataPointers(storage::DataLayout &data_layout, char *memory_block)
@@ -980,6 +986,28 @@ class ContiguousInternalMemoryAlgorithmDataFacade<algorithm::MLD>
std::move(level_offsets)};
}
}
void InitializeGraphPointer(storage::DataLayout &data_layout, char *memory_block)
{
auto graph_nodes_ptr = data_layout.GetBlockPtr<GraphNode>(
memory_block, storage::DataLayout::MLD_GRAPH_NODE_LIST);
auto graph_edges_ptr = data_layout.GetBlockPtr<GraphEdge>(
memory_block, storage::DataLayout::MLD_GRAPH_EDGE_LIST);
auto graph_node_to_offset_ptr = data_layout.GetBlockPtr<QueryGraph::EdgeOffset>(
memory_block, storage::DataLayout::MLD_GRAPH_NODE_TO_OFFSET);
util::ShM<GraphNode, true>::vector node_list(
graph_nodes_ptr, data_layout.num_entries[storage::DataLayout::MLD_GRAPH_NODE_LIST]);
util::ShM<GraphEdge, true>::vector edge_list(
graph_edges_ptr, data_layout.num_entries[storage::DataLayout::MLD_GRAPH_EDGE_LIST]);
util::ShM<QueryGraph::EdgeOffset, true>::vector node_to_offset(
graph_node_to_offset_ptr,
data_layout.num_entries[storage::DataLayout::MLD_GRAPH_NODE_TO_OFFSET]);
query_graph =
QueryGraph(std::move(node_list), std::move(edge_list), std::move(node_to_offset));
}
// allocator that keeps the allocation data
std::shared_ptr<ContiguousBlockAllocator> allocator;
@@ -992,86 +1020,63 @@ class ContiguousInternalMemoryAlgorithmDataFacade<algorithm::MLD>
InitializeInternalPointers(allocator->GetLayout(), allocator->GetMemory());
}
const partition::MultiLevelPartitionView &GetMultiLevelPartition() const
const partition::MultiLevelPartitionView &GetMultiLevelPartition() const override
{
return mld_partition;
}
const partition::CellStorageView &GetCellStorage() const { return mld_cell_storage; }
const partition::CellStorageView &GetCellStorage() const override { return mld_cell_storage; }
// search graph access
unsigned GetNumberOfNodes() const override final { return query_graph.GetNumberOfNodes(); }
unsigned GetNumberOfEdges() const override final { return query_graph.GetNumberOfEdges(); }
unsigned GetOutDegree(const NodeID n) const override final
{
return query_graph.GetOutDegree(n);
}
NodeID GetTarget(const EdgeID e) const override final { return query_graph.GetTarget(e); }
const EdgeData &GetEdgeData(const EdgeID e) const override final
{
return query_graph.GetEdgeData(e);
}
EdgeID BeginEdges(const NodeID n) const override final { return query_graph.BeginEdges(n); }
EdgeID EndEdges(const NodeID n) const override final { return query_graph.EndEdges(n); }
EdgeRange GetAdjacentEdgeRange(const NodeID node) const override final
{
return query_graph.GetAdjacentEdgeRange(node);
}
EdgeRange GetBorderEdgeRange(const LevelID level, const NodeID node) const override final
{
return query_graph.GetBorderEdgeRange(level, node);
}
// searches for a specific edge
EdgeID FindEdge(const NodeID from, const NodeID to) const override final
{
return query_graph.FindEdge(from, to);
}
};
template <>
class ContiguousInternalMemoryDataFacade<algorithm::MLD>
class ContiguousInternalMemoryDataFacade<algorithm::MLD> final
: public ContiguousInternalMemoryDataFacadeBase,
public ContiguousInternalMemoryAlgorithmDataFacade<algorithm::MLD>
{
private:
using QueryGraph = customizer::StaticEdgeBasedGraphView;
using GraphNode = QueryGraph::NodeArrayEntry;
using GraphEdge = QueryGraph::EdgeArrayEntry;
std::unique_ptr<QueryGraph> m_query_graph;
void InitializeGraphPointer(storage::DataLayout &data_layout, char *memory_block)
{
auto graph_nodes_ptr = data_layout.GetBlockPtr<GraphNode>(
memory_block, storage::DataLayout::MLD_GRAPH_NODE_LIST);
auto graph_edges_ptr = data_layout.GetBlockPtr<GraphEdge>(
memory_block, storage::DataLayout::MLD_GRAPH_EDGE_LIST);
util::ShM<GraphNode, true>::vector node_list(
graph_nodes_ptr, data_layout.num_entries[storage::DataLayout::MLD_GRAPH_NODE_LIST]);
util::ShM<GraphEdge, true>::vector edge_list(
graph_edges_ptr, data_layout.num_entries[storage::DataLayout::MLD_GRAPH_EDGE_LIST]);
m_query_graph.reset(new QueryGraph(node_list, edge_list));
}
public:
ContiguousInternalMemoryDataFacade(std::shared_ptr<ContiguousBlockAllocator> allocator)
: ContiguousInternalMemoryDataFacadeBase(allocator),
ContiguousInternalMemoryAlgorithmDataFacade<algorithm::MLD>(allocator)
{
InitializeInternalPointers(allocator->GetLayout(), allocator->GetMemory());
}
void InitializeInternalPointers(storage::DataLayout &data_layout, char *memory_block)
{
InitializeGraphPointer(data_layout, memory_block);
}
// search graph access
unsigned GetNumberOfNodes() const override final { return m_query_graph->GetNumberOfNodes(); }
unsigned GetNumberOfEdges() const override final { return m_query_graph->GetNumberOfEdges(); }
unsigned GetOutDegree(const NodeID n) const override final
{
return m_query_graph->GetOutDegree(n);
}
NodeID GetTarget(const EdgeID e) const override final { return m_query_graph->GetTarget(e); }
EdgeData &GetEdgeData(const EdgeID e) const override final
{
return m_query_graph->GetEdgeData(e);
}
EdgeID BeginEdges(const NodeID n) const override final { return m_query_graph->BeginEdges(n); }
EdgeID EndEdges(const NodeID n) const override final { return m_query_graph->EndEdges(n); }
EdgeRange GetAdjacentEdgeRange(const NodeID node) const override final
{
return m_query_graph->GetAdjacentEdgeRange(node);
}
// searches for a specific edge
EdgeID FindEdge(const NodeID from, const NodeID to) const override final
{
return m_query_graph->FindEdge(from, to);
}
};
}
@@ -143,15 +143,14 @@ void routingStep(const datafacade::ContiguousInternalMemoryDataFacade<algorithm:
}
// Boundary edges
for (const auto edge : facade.GetAdjacentEdgeRange(node))
for (const auto edge : facade.GetBorderEdgeRange(level, node))
{
const auto &edge_data = facade.GetEdgeData(edge);
if (DIRECTION == FORWARD_DIRECTION ? edge_data.forward : edge_data.backward)
{
const NodeID to = facade.GetTarget(edge);
if (checkParentCellRestriction(partition.GetCell(level + 1, to), args...) &&
partition.GetHighestDifferentLevel(node, to) >= level)
if (checkParentCellRestriction(partition.GetCell(level + 1, to), args...))
{
BOOST_ASSERT_MSG(edge_data.weight > 0, "edge_weight invalid");
const EdgeWeight to_weight = weight + edge_data.weight;