Add customizer::MultiLevelGraph

This commit is contained in:
Michael Krasnyk 2018-04-21 09:41:40 +03:00 committed by Patrick Niklaus
parent cdc7e5f021
commit 9b4a4fdd82
10 changed files with 194 additions and 81 deletions

View File

@ -16,28 +16,82 @@ namespace osrm
namespace customizer namespace customizer
{ {
// TODO: Change to turn_id only
using EdgeBasedGraphEdgeData = partitioner::EdgeBasedGraphEdgeData; using EdgeBasedGraphEdgeData = partitioner::EdgeBasedGraphEdgeData;
struct MultiLevelEdgeBasedGraph template <typename EdgeDataT, storage::Ownership Ownership> class MultiLevelGraph;
: public partitioner::MultiLevelGraph<EdgeBasedGraphEdgeData, storage::Ownership::Container>
namespace serialization
{ {
using Base = template <typename EdgeDataT, storage::Ownership Ownership>
partitioner::MultiLevelGraph<EdgeBasedGraphEdgeData, storage::Ownership::Container>; void read(storage::tar::FileReader &reader,
using Base::Base; const std::string &name,
MultiLevelGraph<EdgeDataT, Ownership> &graph);
template <typename EdgeDataT, storage::Ownership Ownership>
void write(storage::tar::FileWriter &writer,
const std::string &name,
const MultiLevelGraph<EdgeDataT, Ownership> &graph);
}
template <typename EdgeDataT, storage::Ownership Ownership>
class MultiLevelGraph : public partitioner::MultiLevelGraph<EdgeDataT, Ownership>
{
private:
using SuperT = partitioner::MultiLevelGraph<EdgeDataT, Ownership>;
using SuperC = partitioner::MultiLevelGraph<partitioner::EdgeBasedGraphEdgeData,
storage::Ownership::Container>;
template <typename T> using Vector = util::ViewOrVector<T, Ownership>;
public:
MultiLevelGraph() = default;
MultiLevelGraph(MultiLevelGraph &&) = default;
MultiLevelGraph(const MultiLevelGraph &) = default;
MultiLevelGraph &operator=(MultiLevelGraph &&) = default;
MultiLevelGraph &operator=(const MultiLevelGraph &) = default;
// TODO: add constructor for EdgeBasedGraphEdgeData
MultiLevelGraph(SuperC &&graph,
Vector<EdgeWeight> node_weights_,
Vector<EdgeDuration> node_durations_)
: node_weights(std::move(node_weights_)), node_durations(std::move(node_durations_))
{
std::tie(SuperT::node_array,
SuperT::edge_array,
SuperT::node_to_edge_offset,
SuperT::connectivity_checksum) = std::move(graph).data();
// TODO: add EdgeArrayEntry shaving
}
MultiLevelGraph(Vector<typename SuperT::NodeArrayEntry> node_array_,
Vector<typename SuperT::EdgeArrayEntry> edge_array_,
Vector<typename SuperT::EdgeOffset> node_to_edge_offset_,
Vector<EdgeWeight> node_weights_,
Vector<EdgeDuration> node_durations_)
: SuperT(std::move(node_array_), std::move(edge_array_), std::move(node_to_edge_offset_)),
node_weights(std::move(node_weights_)), node_durations(std::move(node_durations_))
{
// TODO: add EdgeArrayEntry shaving
}
friend void
serialization::read<EdgeDataT, Ownership>(storage::tar::FileReader &reader,
const std::string &name,
MultiLevelGraph<EdgeDataT, Ownership> &graph);
friend void
serialization::write<EdgeDataT, Ownership>(storage::tar::FileWriter &writer,
const std::string &name,
const MultiLevelGraph<EdgeDataT, Ownership> &graph);
protected:
Vector<EdgeWeight> node_weights;
Vector<EdgeDuration> node_durations;
}; };
struct MultiLevelEdgeBasedGraphView using MultiLevelEdgeBasedGraph =
: public partitioner::MultiLevelGraph<EdgeBasedGraphEdgeData, storage::Ownership::View> MultiLevelGraph<EdgeBasedGraphEdgeData, storage::Ownership::Container>;
{ using MultiLevelEdgeBasedGraphView =
using Base = partitioner::MultiLevelGraph<EdgeBasedGraphEdgeData, storage::Ownership::View>; MultiLevelGraph<EdgeBasedGraphEdgeData, storage::Ownership::View>;
using Base::Base;
};
struct StaticEdgeBasedGraphEdge : MultiLevelEdgeBasedGraph::InputEdge
{
using Base = MultiLevelEdgeBasedGraph::InputEdge;
using Base::Base;
};
} }
} }

View File

@ -73,6 +73,39 @@ writeCellMetrics(const boost::filesystem::path &path,
} }
} }
} }
// reads .osrm.mldgr file
template <typename MultiLevelGraphT>
inline void readGraph(const boost::filesystem::path &path,
MultiLevelGraphT &graph,
std::uint32_t &connectivity_checksum)
{
static_assert(std::is_same<customizer::MultiLevelEdgeBasedGraphView, MultiLevelGraphT>::value ||
std::is_same<customizer::MultiLevelEdgeBasedGraph, MultiLevelGraphT>::value,
"");
storage::tar::FileReader reader{path, storage::tar::FileReader::VerifyFingerprint};
reader.ReadInto("/mld/connectivity_checksum", connectivity_checksum);
serialization::read(reader, "/mld/multilevelgraph", graph);
}
// writes .osrm.mldgr file
template <typename MultiLevelGraphT>
inline void writeGraph(const boost::filesystem::path &path,
const MultiLevelGraphT &graph,
const std::uint32_t connectivity_checksum)
{
static_assert(std::is_same<customizer::MultiLevelEdgeBasedGraphView, MultiLevelGraphT>::value ||
std::is_same<customizer::MultiLevelEdgeBasedGraph, MultiLevelGraphT>::value,
"");
storage::tar::FileWriter writer{path, storage::tar::FileWriter::GenerateFingerprint};
writer.WriteElementCount64("/mld/connectivity_checksum", 1);
writer.WriteFrom("/mld/connectivity_checksum", connectivity_checksum);
serialization::write(writer, "/mld/multilevelgraph", graph);
}
} }
} }
} }

View File

@ -1,6 +1,8 @@
#ifndef OSRM_CUSTOMIZER_SERIALIZATION_HPP #ifndef OSRM_CUSTOMIZER_SERIALIZATION_HPP
#define OSRM_CUSTOMIZER_SERIALIZATION_HPP #define OSRM_CUSTOMIZER_SERIALIZATION_HPP
#include "customizer/edge_based_graph.hpp"
#include "partitioner/cell_storage.hpp" #include "partitioner/cell_storage.hpp"
#include "storage/serialization.hpp" #include "storage/serialization.hpp"
@ -31,6 +33,30 @@ inline void write(storage::tar::FileWriter &writer,
storage::serialization::write(writer, name + "/weights", metric.weights); storage::serialization::write(writer, name + "/weights", metric.weights);
storage::serialization::write(writer, name + "/durations", metric.durations); storage::serialization::write(writer, name + "/durations", metric.durations);
} }
template <typename EdgeDataT, storage::Ownership Ownership>
inline void read(storage::tar::FileReader &reader,
const std::string &name,
MultiLevelGraph<EdgeDataT, Ownership> &graph)
{
storage::serialization::read(reader, name + "/node_array", graph.node_array);
storage::serialization::read(reader, name + "/node_weights", graph.node_weights);
storage::serialization::read(reader, name + "/node_durations", graph.node_durations);
storage::serialization::read(reader, name + "/edge_array", graph.edge_array);
storage::serialization::read(reader, name + "/node_to_edge_offset", graph.node_to_edge_offset);
}
template <typename EdgeDataT, storage::Ownership Ownership>
inline void write(storage::tar::FileWriter &writer,
const std::string &name,
const MultiLevelGraph<EdgeDataT, Ownership> &graph)
{
storage::serialization::write(writer, name + "/node_array", graph.node_array);
storage::serialization::write(writer, name + "/node_weights", graph.node_weights);
storage::serialization::write(writer, name + "/node_durations", graph.node_durations);
storage::serialization::write(writer, name + "/edge_array", graph.edge_array);
storage::serialization::write(writer, name + "/node_to_edge_offset", graph.node_to_edge_offset);
}
} }
} }
} }

View File

@ -1,8 +1,6 @@
#ifndef OSRM_PARTITIONER_SERILIZATION_HPP #ifndef OSRM_PARTITIONER_SERILIZATION_HPP
#define OSRM_PARTITIONER_SERILIZATION_HPP #define OSRM_PARTITIONER_SERILIZATION_HPP
#include "customizer/edge_based_graph.hpp"
#include "partitioner/serialization.hpp" #include "partitioner/serialization.hpp"
#include "storage/io.hpp" #include "storage/io.hpp"
@ -14,39 +12,6 @@ namespace partitioner
namespace files namespace files
{ {
// reads .osrm.mldgr file
template <typename MultiLevelGraphT>
inline void readGraph(const boost::filesystem::path &path,
MultiLevelGraphT &graph,
std::uint32_t &connectivity_checksum)
{
static_assert(std::is_same<customizer::MultiLevelEdgeBasedGraphView, MultiLevelGraphT>::value ||
std::is_same<customizer::MultiLevelEdgeBasedGraph, MultiLevelGraphT>::value,
"");
storage::tar::FileReader reader{path, storage::tar::FileReader::VerifyFingerprint};
reader.ReadInto("/mld/connectivity_checksum", connectivity_checksum);
serialization::read(reader, "/mld/multilevelgraph", graph);
}
// writes .osrm.mldgr file
template <typename MultiLevelGraphT>
inline void writeGraph(const boost::filesystem::path &path,
const MultiLevelGraphT &graph,
const std::uint32_t connectivity_checksum)
{
static_assert(std::is_same<customizer::MultiLevelEdgeBasedGraphView, MultiLevelGraphT>::value ||
std::is_same<customizer::MultiLevelEdgeBasedGraph, MultiLevelGraphT>::value,
"");
storage::tar::FileWriter writer{path, storage::tar::FileWriter::GenerateFingerprint};
writer.WriteElementCount64("/mld/connectivity_checksum", 1);
writer.WriteFrom("/mld/connectivity_checksum", connectivity_checksum);
serialization::write(writer, "/mld/multilevelgraph", graph);
}
// read .osrm.partition file // read .osrm.partition file
template <typename MultiLevelPartitionT> template <typename MultiLevelPartitionT>
inline void readPartition(const boost::filesystem::path &path, MultiLevelPartitionT &mlp) inline void readPartition(const boost::filesystem::path &path, MultiLevelPartitionT &mlp)
@ -102,6 +67,35 @@ inline void writeCells(const boost::filesystem::path &path, CellStorageT &storag
serialization::write(writer, "/mld/cellstorage", storage); serialization::write(writer, "/mld/cellstorage", storage);
} }
// reads .osrm.mldgr file
template <typename MultiLevelGraphT>
inline void readGraph(const boost::filesystem::path &path,
MultiLevelGraphT &graph,
std::uint32_t &connectivity_checksum)
{
static_assert(std::is_same<partitioner::MultiLevelEdgeBasedGraph, MultiLevelGraphT>::value, "");
storage::tar::FileReader reader{path, storage::tar::FileReader::VerifyFingerprint};
reader.ReadInto("/mld/connectivity_checksum", connectivity_checksum);
serialization::read(reader, "/mld/multilevelgraph", graph);
}
// writes .osrm.mldgr file
template <typename MultiLevelGraphT>
inline void writeGraph(const boost::filesystem::path &path,
const MultiLevelGraphT &graph,
const std::uint32_t connectivity_checksum)
{
static_assert(std::is_same<partitioner::MultiLevelEdgeBasedGraph, MultiLevelGraphT>::value, "");
storage::tar::FileWriter writer{path, storage::tar::FileWriter::GenerateFingerprint};
writer.WriteElementCount64("/mld/connectivity_checksum", 1);
writer.WriteFrom("/mld/connectivity_checksum", connectivity_checksum);
serialization::write(writer, "/mld/multilevelgraph", graph);
}
} }
} }
} }

View File

@ -1,6 +1,7 @@
#ifndef OSRM_PARTITIONER_MULTI_LEVEL_GRAPH_HPP #ifndef OSRM_PARTITIONER_MULTI_LEVEL_GRAPH_HPP
#define OSRM_PARTITIONER_MULTI_LEVEL_GRAPH_HPP #define OSRM_PARTITIONER_MULTI_LEVEL_GRAPH_HPP
#include "partitioner/edge_based_graph.hpp"
#include "partitioner/multi_level_partition.hpp" #include "partitioner/multi_level_partition.hpp"
#include "storage/shared_memory_ownership.hpp" #include "storage/shared_memory_ownership.hpp"
@ -42,6 +43,8 @@ class MultiLevelGraph : public util::StaticGraph<EdgeDataT, Ownership>
template <typename T> using Vector = util::ViewOrVector<T, Ownership>; template <typename T> using Vector = util::ViewOrVector<T, Ownership>;
public: public:
using SuperT::SuperT;
// We limit each node to have 255 edges // We limit each node to have 255 edges
// this is very generous, we could probably pack this // this is very generous, we could probably pack this
using EdgeOffset = std::uint8_t; using EdgeOffset = std::uint8_t;
@ -146,6 +149,14 @@ class MultiLevelGraph : public util::StaticGraph<EdgeDataT, Ownership>
return max_border_node_id; return max_border_node_id;
} }
auto data() &&
{
return std::make_tuple(std::move(SuperT::node_array),
std::move(SuperT::edge_array),
std::move(node_to_edge_offset),
connectivity_checksum);
}
private: private:
template <typename ContainerT> template <typename ContainerT>
auto GetHighestBorderLevel(const MultiLevelPartition &mlp, const ContainerT &edges) const auto GetHighestBorderLevel(const MultiLevelPartition &mlp, const ContainerT &edges) const
@ -218,9 +229,13 @@ class MultiLevelGraph : public util::StaticGraph<EdgeDataT, Ownership>
const std::string &name, const std::string &name,
const MultiLevelGraph<EdgeDataT, Ownership> &graph); const MultiLevelGraph<EdgeDataT, Ownership> &graph);
protected:
Vector<EdgeOffset> node_to_edge_offset; Vector<EdgeOffset> node_to_edge_offset;
std::uint32_t connectivity_checksum; std::uint32_t connectivity_checksum;
}; };
using MultiLevelEdgeBasedGraph =
MultiLevelGraph<EdgeBasedGraphEdgeData, storage::Ownership::Container>;
} }
} }

View File

@ -19,26 +19,6 @@ namespace partitioner
namespace serialization namespace serialization
{ {
template <typename EdgeDataT, storage::Ownership Ownership>
inline void read(storage::tar::FileReader &reader,
const std::string &name,
MultiLevelGraph<EdgeDataT, Ownership> &graph)
{
storage::serialization::read(reader, name + "/node_array", graph.node_array);
storage::serialization::read(reader, name + "/edge_array", graph.edge_array);
storage::serialization::read(reader, name + "/node_to_edge_offset", graph.node_to_edge_offset);
}
template <typename EdgeDataT, storage::Ownership Ownership>
inline void write(storage::tar::FileWriter &writer,
const std::string &name,
const MultiLevelGraph<EdgeDataT, Ownership> &graph)
{
storage::serialization::write(writer, name + "/node_array", graph.node_array);
storage::serialization::write(writer, name + "/edge_array", graph.edge_array);
storage::serialization::write(writer, name + "/node_to_edge_offset", graph.node_to_edge_offset);
}
template <storage::Ownership Ownership> template <storage::Ownership Ownership>
inline void read(storage::tar::FileReader &reader, inline void read(storage::tar::FileReader &reader,
const std::string &name, const std::string &name,

View File

@ -330,9 +330,14 @@ inline auto make_multi_level_graph_view(const SharedDataIndex &index, const std:
index, name + "/edge_array"); index, name + "/edge_array");
auto node_to_offset = make_vector_view<customizer::MultiLevelEdgeBasedGraphView::EdgeOffset>( auto node_to_offset = make_vector_view<customizer::MultiLevelEdgeBasedGraphView::EdgeOffset>(
index, name + "/node_to_edge_offset"); index, name + "/node_to_edge_offset");
auto node_weights = make_vector_view<EdgeWeight>(index, name + "/node_weights");
auto node_durations = make_vector_view<EdgeDuration>(index, name + "/node_durations");
return customizer::MultiLevelEdgeBasedGraphView( return customizer::MultiLevelEdgeBasedGraphView(std::move(node_list),
std::move(node_list), std::move(edge_list), std::move(node_to_offset)); std::move(edge_list),
std::move(node_to_offset),
std::move(node_weights),
std::move(node_durations));
} }
inline auto make_maneuver_overrides_views(const SharedDataIndex &index, const std::string &name) inline auto make_maneuver_overrides_views(const SharedDataIndex &index, const std::string &name)

View File

@ -312,7 +312,7 @@ class StaticGraph
}); });
} }
// private: protected:
NodeIterator number_of_nodes; NodeIterator number_of_nodes;
EdgeIterator number_of_edges; EdgeIterator number_of_edges;

View File

@ -84,14 +84,15 @@ auto LoadAndUpdateEdgeExpandedGraph(const CustomizationConfig &config,
updater.LoadAndUpdateEdgeExpandedGraph(); updater.LoadAndUpdateEdgeExpandedGraph();
auto directed = partitioner::splitBidirectionalEdges(edge_based_edge_list); auto directed = partitioner::splitBidirectionalEdges(edge_based_edge_list);
auto tidied = auto tidied = partitioner::prepareEdgesForUsageInGraph<
partitioner::prepareEdgesForUsageInGraph<StaticEdgeBasedGraphEdge>(std::move(directed)); typename partitioner::MultiLevelEdgeBasedGraph::InputEdge>(std::move(directed));
auto edge_based_graph = customizer::MultiLevelEdgeBasedGraph(mlp, num_nodes, std::move(tidied)); auto edge_based_graph =
partitioner::MultiLevelEdgeBasedGraph(mlp, num_nodes, std::move(tidied));
return edge_based_graph; return edge_based_graph;
} }
std::vector<CellMetric> customizeFilteredMetrics(const MultiLevelEdgeBasedGraph &graph, std::vector<CellMetric> customizeFilteredMetrics(const partitioner::MultiLevelEdgeBasedGraph &graph,
const partitioner::CellStorage &storage, const partitioner::CellStorage &storage,
const CellCustomizer &customizer, const CellCustomizer &customizer,
const std::vector<std::vector<bool>> &node_filters) const std::vector<std::vector<bool>> &node_filters)
@ -157,7 +158,12 @@ int Customizer::Run(const CustomizationConfig &config)
util::Log() << "MLD customization writing took " << TIMER_SEC(writing_mld_data) << " seconds"; util::Log() << "MLD customization writing took " << TIMER_SEC(writing_mld_data) << " seconds";
TIMER_START(writing_graph); TIMER_START(writing_graph);
partitioner::files::writeGraph(config.GetPath(".osrm.mldgr"), graph, connectivity_checksum); std::vector<EdgeWeight> node_weights;
std::vector<EdgeDuration> node_durations;
MultiLevelEdgeBasedGraph shaved_graph{
std::move(graph), std::move(node_weights), std::move(node_durations)};
customizer::files::writeGraph(
config.GetPath(".osrm.mldgr"), shaved_graph, connectivity_checksum);
TIMER_STOP(writing_graph); TIMER_STOP(writing_graph);
util::Log() << "Graph writing took " << TIMER_SEC(writing_graph) << " seconds"; util::Log() << "Graph writing took " << TIMER_SEC(writing_graph) << " seconds";

View File

@ -554,7 +554,7 @@ void Storage::PopulateUpdatableData(const SharedDataIndex &index)
{ {
auto graph_view = make_multi_level_graph_view(index, "/mld/multilevelgraph"); auto graph_view = make_multi_level_graph_view(index, "/mld/multilevelgraph");
std::uint32_t graph_connectivity_checksum = 0; std::uint32_t graph_connectivity_checksum = 0;
partitioner::files::readGraph( customizer::files::readGraph(
config.GetPath(".osrm.mldgr"), graph_view, graph_connectivity_checksum); config.GetPath(".osrm.mldgr"), graph_view, graph_connectivity_checksum);
auto turns_connectivity_checksum = auto turns_connectivity_checksum =