Initial interation on writing out MLD partition/cell data
This commit is contained in:
parent
757e7ca936
commit
ff0a98196f
@ -16,10 +16,12 @@
|
|||||||
|
|
||||||
#include "engine/algorithm.hpp"
|
#include "engine/algorithm.hpp"
|
||||||
#include "engine/geospatial_query.hpp"
|
#include "engine/geospatial_query.hpp"
|
||||||
|
#include "util/cell_storage.hpp"
|
||||||
#include "util/exception.hpp"
|
#include "util/exception.hpp"
|
||||||
#include "util/exception_utils.hpp"
|
#include "util/exception_utils.hpp"
|
||||||
#include "util/guidance/turn_bearing.hpp"
|
#include "util/guidance/turn_bearing.hpp"
|
||||||
#include "util/log.hpp"
|
#include "util/log.hpp"
|
||||||
|
#include "util/multi_level_partition.hpp"
|
||||||
#include "util/name_table.hpp"
|
#include "util/name_table.hpp"
|
||||||
#include "util/packed_vector.hpp"
|
#include "util/packed_vector.hpp"
|
||||||
#include "util/range_table.hpp"
|
#include "util/range_table.hpp"
|
||||||
@ -249,6 +251,10 @@ class ContiguousInternalMemoryDataFacadeBase : public BaseDataFacade
|
|||||||
std::shared_ptr<util::RangeTable<16, true>> m_bearing_ranges_table;
|
std::shared_ptr<util::RangeTable<16, true>> m_bearing_ranges_table;
|
||||||
util::ShM<DiscreteBearing, true>::vector m_bearing_values_table;
|
util::ShM<DiscreteBearing, true>::vector m_bearing_values_table;
|
||||||
|
|
||||||
|
// MLD data
|
||||||
|
util::PackedMultiLevelPartition<true> mld_partition;
|
||||||
|
util::CellStorage<true> mld_cell_storage;
|
||||||
|
|
||||||
// allocator that keeps the allocation data
|
// allocator that keeps the allocation data
|
||||||
std::shared_ptr<ContiguousBlockAllocator> allocator;
|
std::shared_ptr<ContiguousBlockAllocator> allocator;
|
||||||
|
|
||||||
@ -534,6 +540,27 @@ class ContiguousInternalMemoryDataFacadeBase : public BaseDataFacade
|
|||||||
m_entry_class_table = std::move(entry_class_table);
|
m_entry_class_table = std::move(entry_class_table);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void InitializeMLDDataPointers(storage::DataLayout &data_layout, char *memory_block)
|
||||||
|
{
|
||||||
|
if (data_layout.GetBlockSize(storage::DataLayout::MLD_CELL_PARTITION) > 0)
|
||||||
|
{
|
||||||
|
auto mld_partition_ptr =
|
||||||
|
data_layout.GetBlockPtr<char>(memory_block, storage::DataLayout::MLD_CELL_PARTITION);
|
||||||
|
mld_partition.InitializePointers(
|
||||||
|
mld_partition_ptr,
|
||||||
|
mld_partition_ptr + data_layout.num_entries[storage::DataLayout::MLD_CELL_PARTITION]);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (data_layout.GetBlockSize(storage::DataLayout::MLD_CELL_STORAGE) > 0)
|
||||||
|
{
|
||||||
|
auto mld_cell_storage_ptr =
|
||||||
|
data_layout.GetBlockPtr<char>(memory_block, storage::DataLayout::MLD_CELL_STORAGE);
|
||||||
|
mld_cell_storage.InitializePointers(
|
||||||
|
mld_cell_storage_ptr,
|
||||||
|
mld_cell_storage_ptr + data_layout.num_entries[storage::DataLayout::MLD_CELL_STORAGE]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void InitializeInternalPointers(storage::DataLayout &data_layout, char *memory_block)
|
void InitializeInternalPointers(storage::DataLayout &data_layout, char *memory_block)
|
||||||
{
|
{
|
||||||
InitializeChecksumPointer(data_layout, memory_block);
|
InitializeChecksumPointer(data_layout, memory_block);
|
||||||
@ -547,6 +574,7 @@ class ContiguousInternalMemoryDataFacadeBase : public BaseDataFacade
|
|||||||
InitializeProfilePropertiesPointer(data_layout, memory_block);
|
InitializeProfilePropertiesPointer(data_layout, memory_block);
|
||||||
InitializeRTreePointers(data_layout, memory_block);
|
InitializeRTreePointers(data_layout, memory_block);
|
||||||
InitializeIntersectionClassPointers(data_layout, memory_block);
|
InitializeIntersectionClassPointers(data_layout, memory_block);
|
||||||
|
InitializeMLDDataPointers(data_layout, memory_block);
|
||||||
}
|
}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
@ -1049,6 +1077,13 @@ class ContiguousInternalMemoryDataFacadeBase : public BaseDataFacade
|
|||||||
m_lane_description_masks.begin() +
|
m_lane_description_masks.begin() +
|
||||||
m_lane_description_offsets[lane_description_id + 1]);
|
m_lane_description_offsets[lane_description_id + 1]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const util::PackedMultiLevelPartition<true> &GetMultiLevelPartition() const
|
||||||
|
{
|
||||||
|
return mld_partition;
|
||||||
|
}
|
||||||
|
|
||||||
|
const util::CellStorage<true> &GetCellStorage() const { return mld_cell_storage; }
|
||||||
};
|
};
|
||||||
|
|
||||||
template <typename AlgorithmT> class ContiguousInternalMemoryDataFacade;
|
template <typename AlgorithmT> class ContiguousInternalMemoryDataFacade;
|
||||||
|
@ -13,7 +13,10 @@ namespace partition
|
|||||||
|
|
||||||
struct PartitionConfig
|
struct PartitionConfig
|
||||||
{
|
{
|
||||||
PartitionConfig() : requested_num_threads(0) {}
|
PartitionConfig()
|
||||||
|
: requested_num_threads(0)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
void UseDefaults()
|
void UseDefaults()
|
||||||
{
|
{
|
||||||
@ -34,6 +37,8 @@ struct PartitionConfig
|
|||||||
compressed_node_based_graph_path = basepath + ".osrm.cnbg";
|
compressed_node_based_graph_path = basepath + ".osrm.cnbg";
|
||||||
cnbg_ebg_mapping_path = basepath + ".osrm.cnbg_to_ebg";
|
cnbg_ebg_mapping_path = basepath + ".osrm.cnbg_to_ebg";
|
||||||
partition_path = basepath + ".osrm.partition";
|
partition_path = basepath + ".osrm.partition";
|
||||||
|
mld_partition_path = basepath + ".osrm.mld_partition";
|
||||||
|
mld_storage_path = basepath + ".osrm.mld_storage";
|
||||||
}
|
}
|
||||||
|
|
||||||
// might be changed to the node based graph at some point
|
// might be changed to the node based graph at some point
|
||||||
@ -42,6 +47,8 @@ struct PartitionConfig
|
|||||||
boost::filesystem::path compressed_node_based_graph_path;
|
boost::filesystem::path compressed_node_based_graph_path;
|
||||||
boost::filesystem::path cnbg_ebg_mapping_path;
|
boost::filesystem::path cnbg_ebg_mapping_path;
|
||||||
boost::filesystem::path partition_path;
|
boost::filesystem::path partition_path;
|
||||||
|
boost::filesystem::path mld_partition_path;
|
||||||
|
boost::filesystem::path mld_storage_path;
|
||||||
|
|
||||||
unsigned requested_num_threads;
|
unsigned requested_num_threads;
|
||||||
|
|
||||||
|
@ -26,6 +26,8 @@ class RecursiveBisection
|
|||||||
|
|
||||||
const std::vector<BisectionID> &BisectionIDs() const;
|
const std::vector<BisectionID> &BisectionIDs() const;
|
||||||
|
|
||||||
|
std::uint32_t SCCDepth() const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
BisectionGraph &bisection_graph;
|
BisectionGraph &bisection_graph;
|
||||||
RecursiveBisectionState internal_state;
|
RecursiveBisectionState internal_state;
|
||||||
|
@ -134,6 +134,26 @@ class FileReader
|
|||||||
ReadInto(data.data(), count);
|
ReadInto(data.data(), count);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <typename T> std::size_t GetVectorMemorySize()
|
||||||
|
{
|
||||||
|
const auto count = ReadElementCount64();
|
||||||
|
Skip<T>(count);
|
||||||
|
return sizeof(count) + sizeof(T) * count;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T> void *DeserializeVector(void *begin, const void *end)
|
||||||
|
{
|
||||||
|
auto count = ReadElementCount64();
|
||||||
|
auto required = reinterpret_cast<char *>(begin) + sizeof(count) + sizeof(T) * count;
|
||||||
|
if (required > end)
|
||||||
|
throw util::exception("Not enough memory ");
|
||||||
|
|
||||||
|
*reinterpret_cast<decltype(count) *>(begin) = count;
|
||||||
|
ReadInto(reinterpret_cast<T *>(reinterpret_cast<char *>(begin) + sizeof(decltype(count))),
|
||||||
|
count);
|
||||||
|
return required;
|
||||||
|
}
|
||||||
|
|
||||||
bool ReadAndCheckFingerprint()
|
bool ReadAndCheckFingerprint()
|
||||||
{
|
{
|
||||||
auto loaded_fingerprint = ReadOne<util::FingerPrint>();
|
auto loaded_fingerprint = ReadOne<util::FingerPrint>();
|
||||||
|
@ -56,7 +56,9 @@ const constexpr char *block_id_to_name[] = {"NAME_CHAR_DATA",
|
|||||||
"LANE_DESCRIPTION_OFFSETS",
|
"LANE_DESCRIPTION_OFFSETS",
|
||||||
"LANE_DESCRIPTION_MASKS",
|
"LANE_DESCRIPTION_MASKS",
|
||||||
"TURN_WEIGHT_PENALTIES",
|
"TURN_WEIGHT_PENALTIES",
|
||||||
"TURN_DURATION_PENALTIES"};
|
"TURN_DURATION_PENALTIES",
|
||||||
|
"MLD_CELL_PARTITION",
|
||||||
|
"MLD_CELL_STORAGE"};
|
||||||
|
|
||||||
struct DataLayout
|
struct DataLayout
|
||||||
{
|
{
|
||||||
@ -101,6 +103,8 @@ struct DataLayout
|
|||||||
LANE_DESCRIPTION_MASKS,
|
LANE_DESCRIPTION_MASKS,
|
||||||
TURN_WEIGHT_PENALTIES,
|
TURN_WEIGHT_PENALTIES,
|
||||||
TURN_DURATION_PENALTIES,
|
TURN_DURATION_PENALTIES,
|
||||||
|
MLD_CELL_PARTITION,
|
||||||
|
MLD_CELL_STORAGE,
|
||||||
NUM_BLOCKS
|
NUM_BLOCKS
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -69,6 +69,8 @@ struct StorageConfig final
|
|||||||
boost::filesystem::path intersection_class_path;
|
boost::filesystem::path intersection_class_path;
|
||||||
boost::filesystem::path turn_lane_data_path;
|
boost::filesystem::path turn_lane_data_path;
|
||||||
boost::filesystem::path turn_lane_description_path;
|
boost::filesystem::path turn_lane_description_path;
|
||||||
|
boost::filesystem::path mld_partition_path;
|
||||||
|
boost::filesystem::path mld_storage_path;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3,9 +3,13 @@
|
|||||||
|
|
||||||
#include "util/assert.hpp"
|
#include "util/assert.hpp"
|
||||||
#include "util/for_each_range.hpp"
|
#include "util/for_each_range.hpp"
|
||||||
|
#include "util/log.hpp"
|
||||||
#include "util/multi_level_partition.hpp"
|
#include "util/multi_level_partition.hpp"
|
||||||
|
#include "util/shared_memory_vector_wrapper.hpp"
|
||||||
#include "util/typedefs.hpp"
|
#include "util/typedefs.hpp"
|
||||||
|
|
||||||
|
#include "storage/io.hpp"
|
||||||
|
|
||||||
#include <boost/range/iterator_range.hpp>
|
#include <boost/range/iterator_range.hpp>
|
||||||
#include <tbb/parallel_sort.h>
|
#include <tbb/parallel_sort.h>
|
||||||
|
|
||||||
@ -19,7 +23,7 @@ namespace osrm
|
|||||||
namespace util
|
namespace util
|
||||||
{
|
{
|
||||||
|
|
||||||
class CellStorage
|
template <bool UseShareMemory> class CellStorage
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
using WeightOffset = std::uint32_t;
|
using WeightOffset = std::uint32_t;
|
||||||
@ -161,6 +165,8 @@ class CellStorage
|
|||||||
using Cell = CellImpl<EdgeWeight>;
|
using Cell = CellImpl<EdgeWeight>;
|
||||||
using ConstCell = CellImpl<const EdgeWeight>;
|
using ConstCell = CellImpl<const EdgeWeight>;
|
||||||
|
|
||||||
|
CellStorage() {}
|
||||||
|
|
||||||
template <typename GraphT>
|
template <typename GraphT>
|
||||||
CellStorage(const MultiLevelPartition &partition, const GraphT &base_graph)
|
CellStorage(const MultiLevelPartition &partition, const GraphT &base_graph)
|
||||||
{
|
{
|
||||||
@ -286,6 +292,8 @@ class CellStorage
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
CellStorage(const boost::filesystem::path &path) { Read(path); }
|
||||||
|
|
||||||
ConstCell GetCell(LevelID level, CellID id) const
|
ConstCell GetCell(LevelID level, CellID id) const
|
||||||
{
|
{
|
||||||
const auto level_index = LevelIDToIndex(level);
|
const auto level_index = LevelIDToIndex(level);
|
||||||
@ -308,12 +316,100 @@ class CellStorage
|
|||||||
cells[cell_index], weights.data(), source_boundary.data(), destination_boundary.data()};
|
cells[cell_index], weights.data(), source_boundary.data(), destination_boundary.data()};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::size_t GetRequiredMemorySize(const boost::filesystem::path &path) const
|
||||||
|
{
|
||||||
|
const auto fingerprint = storage::io::FileReader::VerifyFingerprint;
|
||||||
|
storage::io::FileReader reader{path, fingerprint};
|
||||||
|
|
||||||
|
std::size_t memory_size = 0;
|
||||||
|
memory_size += reader.GetVectorMemorySize<decltype(weights[0])>();
|
||||||
|
memory_size += reader.GetVectorMemorySize<decltype(source_boundary[0])>();
|
||||||
|
memory_size += reader.GetVectorMemorySize<decltype(destination_boundary[0])>();
|
||||||
|
memory_size += reader.GetVectorMemorySize<decltype(cells[0])>();
|
||||||
|
memory_size += reader.GetVectorMemorySize<decltype(level_to_cell_offset[0])>();
|
||||||
|
return memory_size;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <bool Q = UseShareMemory>
|
||||||
|
typename std::enable_if<Q>::type
|
||||||
|
Read(const boost::filesystem::path &path, void *begin, const void *end) const
|
||||||
|
{
|
||||||
|
const auto fingerprint = storage::io::FileReader::VerifyFingerprint;
|
||||||
|
storage::io::FileReader reader{path, fingerprint};
|
||||||
|
|
||||||
|
begin = reader.DeserializeVector<typename decltype(weights)::value_type>(begin, end);
|
||||||
|
begin =
|
||||||
|
reader.DeserializeVector<typename decltype(source_boundary)::value_type>(begin, end);
|
||||||
|
begin = reader.DeserializeVector<typename decltype(destination_boundary)::value_type>(begin,
|
||||||
|
end);
|
||||||
|
begin = reader.DeserializeVector<typename decltype(cells)::value_type>(begin, end);
|
||||||
|
begin = reader.DeserializeVector<typename decltype(level_to_cell_offset)::value_type>(begin,
|
||||||
|
end);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <bool Q = UseShareMemory>
|
||||||
|
typename std::enable_if<Q>::type InitializePointers(char *begin, const char *end)
|
||||||
|
{
|
||||||
|
auto weights_size = *reinterpret_cast<std::uint64_t *>(begin);
|
||||||
|
begin += sizeof(weights_size);
|
||||||
|
weights.reset(reinterpret_cast<EdgeWeight *>(begin), weights_size);
|
||||||
|
begin += sizeof(decltype(weights[0])) * weights_size;
|
||||||
|
|
||||||
|
auto source_boundary_size = *reinterpret_cast<std::uint64_t *>(begin);
|
||||||
|
begin += sizeof(source_boundary_size);
|
||||||
|
source_boundary.reset(reinterpret_cast<NodeID *>(begin), source_boundary_size);
|
||||||
|
begin += sizeof(decltype(source_boundary[0])) * source_boundary_size;
|
||||||
|
|
||||||
|
auto destination_boundary_size = *reinterpret_cast<std::uint64_t *>(begin);
|
||||||
|
begin += sizeof(destination_boundary_size);
|
||||||
|
destination_boundary.reset(reinterpret_cast<NodeID *>(begin), destination_boundary_size);
|
||||||
|
begin += sizeof(decltype(destination_boundary[0])) * destination_boundary_size;
|
||||||
|
|
||||||
|
auto cells_size = *reinterpret_cast<std::uint64_t *>(begin);
|
||||||
|
begin += sizeof(cells_size);
|
||||||
|
cells.reset(reinterpret_cast<CellData *>(begin), cells_size);
|
||||||
|
begin += sizeof(decltype(cells[0])) * cells_size;
|
||||||
|
|
||||||
|
auto level_to_cell_offset_size = *reinterpret_cast<std::uint64_t *>(begin);
|
||||||
|
begin += sizeof(level_to_cell_offset_size);
|
||||||
|
level_to_cell_offset.reset(reinterpret_cast<std::size_t *>(begin),
|
||||||
|
level_to_cell_offset_size);
|
||||||
|
begin += sizeof(decltype(level_to_cell_offset[0])) * level_to_cell_offset_size;
|
||||||
|
|
||||||
|
BOOST_ASSERT(begin <= end);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <bool Q = UseShareMemory>
|
||||||
|
typename std::enable_if<!Q>::type Read(const boost::filesystem::path &path)
|
||||||
|
{
|
||||||
|
const auto fingerprint = storage::io::FileReader::VerifyFingerprint;
|
||||||
|
storage::io::FileReader reader{path, fingerprint};
|
||||||
|
|
||||||
|
reader.DeserializeVector(weights);
|
||||||
|
reader.DeserializeVector(source_boundary);
|
||||||
|
reader.DeserializeVector(destination_boundary);
|
||||||
|
reader.DeserializeVector(cells);
|
||||||
|
reader.DeserializeVector(level_to_cell_offset);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Write(const boost::filesystem::path &path) const
|
||||||
|
{
|
||||||
|
const auto fingerprint = storage::io::FileWriter::GenerateFingerprint;
|
||||||
|
storage::io::FileWriter writer{path, fingerprint};
|
||||||
|
|
||||||
|
writer.SerializeVector(weights);
|
||||||
|
writer.SerializeVector(source_boundary);
|
||||||
|
writer.SerializeVector(destination_boundary);
|
||||||
|
writer.SerializeVector(cells);
|
||||||
|
writer.SerializeVector(level_to_cell_offset);
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::vector<EdgeWeight> weights;
|
typename util::ShM<EdgeWeight, UseShareMemory>::vector weights;
|
||||||
std::vector<NodeID> source_boundary;
|
typename util::ShM<NodeID, UseShareMemory>::vector source_boundary;
|
||||||
std::vector<NodeID> destination_boundary;
|
typename util::ShM<NodeID, UseShareMemory>::vector destination_boundary;
|
||||||
std::vector<CellData> cells;
|
typename util::ShM<CellData, UseShareMemory>::vector cells;
|
||||||
std::vector<std::size_t> level_to_cell_offset;
|
typename util::ShM<std::size_t, UseShareMemory>::vector level_to_cell_offset;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3,8 +3,11 @@
|
|||||||
|
|
||||||
#include "util/exception.hpp"
|
#include "util/exception.hpp"
|
||||||
#include "util/for_each_pair.hpp"
|
#include "util/for_each_pair.hpp"
|
||||||
|
#include "util/shared_memory_vector_wrapper.hpp"
|
||||||
#include "util/typedefs.hpp"
|
#include "util/typedefs.hpp"
|
||||||
|
|
||||||
|
#include "storage/io.hpp"
|
||||||
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <array>
|
#include <array>
|
||||||
#include <climits>
|
#include <climits>
|
||||||
@ -73,12 +76,14 @@ class MultiLevelPartition
|
|||||||
virtual std::uint32_t GetNumberOfCells(LevelID level) const = 0;
|
virtual std::uint32_t GetNumberOfCells(LevelID level) const = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
class PackedMultiLevelPartition final : public MultiLevelPartition
|
template <bool UseShareMemory> class PackedMultiLevelPartition final : public MultiLevelPartition
|
||||||
{
|
{
|
||||||
using PartitionID = std::uint64_t;
|
using PartitionID = std::uint64_t;
|
||||||
static const constexpr std::uint8_t NUM_PARTITION_BITS = sizeof(PartitionID) * CHAR_BIT;
|
static const constexpr std::uint8_t NUM_PARTITION_BITS = sizeof(PartitionID) * CHAR_BIT;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
PackedMultiLevelPartition() {}
|
||||||
|
|
||||||
// cell_sizes is index by level (starting at 0, the base graph).
|
// cell_sizes is index by level (starting at 0, the base graph).
|
||||||
// However level 0 always needs to have cell size 1, since it is the
|
// However level 0 always needs to have cell size 1, since it is the
|
||||||
// basegraph.
|
// basegraph.
|
||||||
@ -90,6 +95,8 @@ class PackedMultiLevelPartition final : public MultiLevelPartition
|
|||||||
initializePartitionIDs(partitions);
|
initializePartitionIDs(partitions);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
PackedMultiLevelPartition(const boost::filesystem::path &file_name) { Read(file_name); }
|
||||||
|
|
||||||
// returns the index of the cell the vertex is contained at level l
|
// returns the index of the cell the vertex is contained at level l
|
||||||
CellID GetCell(LevelID l, NodeID node) const final override
|
CellID GetCell(LevelID l, NodeID node) const final override
|
||||||
{
|
{
|
||||||
@ -139,6 +146,89 @@ class PackedMultiLevelPartition final : public MultiLevelPartition
|
|||||||
return cell_to_children[offset + cell + 1];
|
return cell_to_children[offset + cell + 1];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::size_t GetRequiredMemorySize(const boost::filesystem::path &path) const
|
||||||
|
{
|
||||||
|
const auto fingerprint = storage::io::FileReader::VerifyFingerprint;
|
||||||
|
storage::io::FileReader reader{path, fingerprint};
|
||||||
|
|
||||||
|
std::size_t memory_size = 0;
|
||||||
|
memory_size += reader.GetVectorMemorySize<decltype(level_offsets[0])>();
|
||||||
|
memory_size += reader.GetVectorMemorySize<decltype(partition[0])>();
|
||||||
|
memory_size += reader.GetVectorMemorySize<decltype(level_to_children_offset[0])>();
|
||||||
|
memory_size += reader.GetVectorMemorySize<decltype(cell_to_children[0])>();
|
||||||
|
return memory_size;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <bool Q = UseShareMemory>
|
||||||
|
typename std::enable_if<Q>::type
|
||||||
|
Read(const boost::filesystem::path &path, void *begin, const void *end) const
|
||||||
|
{
|
||||||
|
const auto fingerprint = storage::io::FileReader::VerifyFingerprint;
|
||||||
|
storage::io::FileReader reader{path, fingerprint};
|
||||||
|
|
||||||
|
begin = reader.DeserializeVector<typename decltype(level_offsets)::value_type>(begin, end);
|
||||||
|
begin = reader.DeserializeVector<typename decltype(partition)::value_type>(begin, end);
|
||||||
|
begin = reader.DeserializeVector<typename decltype(level_to_children_offset)::value_type>(
|
||||||
|
begin, end);
|
||||||
|
begin =
|
||||||
|
reader.DeserializeVector<typename decltype(cell_to_children)::value_type>(begin, end);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <bool Q = UseShareMemory>
|
||||||
|
typename std::enable_if<Q>::type InitializePointers(char *begin, const char *end)
|
||||||
|
{
|
||||||
|
auto level_offsets_size = *reinterpret_cast<std::uint64_t *>(begin);
|
||||||
|
begin += sizeof(level_offsets_size);
|
||||||
|
level_offsets.reset(begin, level_offsets_size);
|
||||||
|
begin += sizeof(decltype(level_offsets[0])) * level_offsets_size;
|
||||||
|
|
||||||
|
auto partition_size = *reinterpret_cast<std::uint64_t *>(begin);
|
||||||
|
begin += sizeof(partition_size);
|
||||||
|
partition.reset(begin, partition_size);
|
||||||
|
begin += sizeof(decltype(partition[0])) * partition_size;
|
||||||
|
|
||||||
|
auto level_to_children_offset_size = *reinterpret_cast<std::uint64_t *>(begin);
|
||||||
|
begin += sizeof(level_to_children_offset_size);
|
||||||
|
level_to_children_offset.reset(begin, level_to_children_offset_size);
|
||||||
|
begin += sizeof(decltype(level_to_children_offset[0])) * level_to_children_offset_size;
|
||||||
|
|
||||||
|
auto cell_to_children_size = *reinterpret_cast<std::uint64_t *>(begin);
|
||||||
|
begin += sizeof(cell_to_children_size);
|
||||||
|
cell_to_children.reset(begin, cell_to_children_size);
|
||||||
|
begin += sizeof(decltype(cell_to_children[0])) * level_to_children_offset_size;
|
||||||
|
|
||||||
|
BOOST_ASSERT(begin <= end);
|
||||||
|
|
||||||
|
level_masks = makeLevelMasks();
|
||||||
|
bit_to_level = makeBitToLevel();
|
||||||
|
}
|
||||||
|
|
||||||
|
template <bool Q = UseShareMemory>
|
||||||
|
typename std::enable_if<!Q>::type Read(const boost::filesystem::path &path)
|
||||||
|
{
|
||||||
|
const auto fingerprint = storage::io::FileReader::VerifyFingerprint;
|
||||||
|
storage::io::FileReader reader{path, fingerprint};
|
||||||
|
|
||||||
|
reader.DeserializeVector(level_offsets);
|
||||||
|
reader.DeserializeVector(partition);
|
||||||
|
reader.DeserializeVector(level_to_children_offset);
|
||||||
|
reader.DeserializeVector(cell_to_children);
|
||||||
|
|
||||||
|
level_masks = makeLevelMasks();
|
||||||
|
bit_to_level = makeBitToLevel();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Write(const boost::filesystem::path &path) const
|
||||||
|
{
|
||||||
|
const auto fingerprint = storage::io::FileWriter::GenerateFingerprint;
|
||||||
|
storage::io::FileWriter writer{path, fingerprint};
|
||||||
|
|
||||||
|
writer.SerializeVector(level_offsets);
|
||||||
|
writer.SerializeVector(partition);
|
||||||
|
writer.SerializeVector(level_to_children_offset);
|
||||||
|
writer.SerializeVector(cell_to_children);
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
inline std::size_t LevelIDToIndex(LevelID l) const { return l - 1; }
|
inline std::size_t LevelIDToIndex(LevelID l) const { return l - 1; }
|
||||||
|
|
||||||
@ -306,11 +396,11 @@ class PackedMultiLevelPartition final : public MultiLevelPartition
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<PartitionID> partition;
|
typename util::ShM<std::uint8_t, UseShareMemory>::vector level_offsets;
|
||||||
std::vector<std::uint8_t> level_offsets;
|
typename util::ShM<PartitionID, UseShareMemory>::vector partition;
|
||||||
|
typename util::ShM<std::uint32_t, UseShareMemory>::vector level_to_children_offset;
|
||||||
|
typename util::ShM<CellID, UseShareMemory>::vector cell_to_children;
|
||||||
std::vector<PartitionID> level_masks;
|
std::vector<PartitionID> level_masks;
|
||||||
std::vector<std::uint32_t> level_to_children_offset;
|
|
||||||
std::vector<CellID> cell_to_children;
|
|
||||||
std::array<LevelID, NUM_PARTITION_BITS> bit_to_level;
|
std::array<LevelID, NUM_PARTITION_BITS> bit_to_level;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -58,6 +58,7 @@ template <typename DataT> class SharedMemoryWrapper
|
|||||||
std::size_t m_size;
|
std::size_t m_size;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
using value_type = DataT;
|
||||||
using iterator = ShMemIterator<DataT>;
|
using iterator = ShMemIterator<DataT>;
|
||||||
using reverse_iterator = boost::reverse_iterator<iterator>;
|
using reverse_iterator = boost::reverse_iterator<iterator>;
|
||||||
|
|
||||||
@ -71,6 +72,12 @@ template <typename DataT> class SharedMemoryWrapper
|
|||||||
m_size = size;
|
m_size = size;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void reset(void *ptr, std::size_t size)
|
||||||
|
{
|
||||||
|
m_ptr = reinterpret_cast<DataT *>(ptr);
|
||||||
|
m_size = size;
|
||||||
|
}
|
||||||
|
|
||||||
DataT &at(const std::size_t index) { return m_ptr[index]; }
|
DataT &at(const std::size_t index) { return m_ptr[index]; }
|
||||||
|
|
||||||
const DataT &at(const std::size_t index) const { return m_ptr[index]; }
|
const DataT &at(const std::size_t index) const { return m_ptr[index]; }
|
||||||
|
@ -6,18 +6,22 @@
|
|||||||
#include "partition/node_based_graph_to_edge_based_graph_mapping_reader.hpp"
|
#include "partition/node_based_graph_to_edge_based_graph_mapping_reader.hpp"
|
||||||
#include "partition/recursive_bisection.hpp"
|
#include "partition/recursive_bisection.hpp"
|
||||||
|
|
||||||
|
#include "util/cell_storage.hpp"
|
||||||
#include "util/coordinate.hpp"
|
#include "util/coordinate.hpp"
|
||||||
#include "util/geojson_debug_logger.hpp"
|
#include "util/geojson_debug_logger.hpp"
|
||||||
#include "util/geojson_debug_policies.hpp"
|
#include "util/geojson_debug_policies.hpp"
|
||||||
#include "util/integer_range.hpp"
|
#include "util/integer_range.hpp"
|
||||||
#include "util/json_container.hpp"
|
#include "util/json_container.hpp"
|
||||||
#include "util/log.hpp"
|
#include "util/log.hpp"
|
||||||
|
#include "util/multi_level_partition.hpp"
|
||||||
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <iterator>
|
#include <iterator>
|
||||||
|
#include <unordered_set>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
#include <boost/assert.hpp>
|
#include <boost/assert.hpp>
|
||||||
|
#include <boost/container/small_vector.hpp>
|
||||||
|
|
||||||
#include "util/geojson_debug_logger.hpp"
|
#include "util/geojson_debug_logger.hpp"
|
||||||
#include "util/geojson_debug_policies.hpp"
|
#include "util/geojson_debug_policies.hpp"
|
||||||
@ -181,6 +185,88 @@ int Partitioner::Run(const PartitionConfig &config)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// FIXME The CellID computation code need to be replaced by a more sophisticated method
|
||||||
|
{
|
||||||
|
BOOST_ASSERT(edge_based_partition_ids.size() == edge_based_graph->GetNumberOfNodes());
|
||||||
|
|
||||||
|
using namespace osrm::partition;
|
||||||
|
|
||||||
|
// find bit size of bisection ids
|
||||||
|
int first_nonzero_position = sizeof(BisectionID) * CHAR_BIT;
|
||||||
|
for (auto id : edge_based_partition_ids)
|
||||||
|
{
|
||||||
|
first_nonzero_position = id == 0 ? first_nonzero_position
|
||||||
|
: std::min(first_nonzero_position, __builtin_ctz(id));
|
||||||
|
}
|
||||||
|
BOOST_ASSERT(first_nonzero_position != sizeof(BisectionID) * CHAR_BIT);
|
||||||
|
|
||||||
|
// split bisection id bits into groups starting from SCC and stop at level 1
|
||||||
|
BOOST_ASSERT(recursive_bisection.SCCDepth() != 0);
|
||||||
|
int mask_from = sizeof(BisectionID) * CHAR_BIT - recursive_bisection.SCCDepth();
|
||||||
|
boost::container::small_vector<BisectionID, 8> level_masks;
|
||||||
|
for (int mask_to = sizeof(BisectionID) * CHAR_BIT; mask_to > first_nonzero_position;
|
||||||
|
mask_to = mask_from, mask_from -= 3) // TODO: find better grouping
|
||||||
|
{
|
||||||
|
auto bit = std::max(first_nonzero_position, mask_from);
|
||||||
|
level_masks.push_back(((1u << (sizeof(BisectionID) * CHAR_BIT - bit)) - 1) << bit);
|
||||||
|
}
|
||||||
|
|
||||||
|
util::Log() << "Bisection IDs split for SCC depth " << recursive_bisection.SCCDepth()
|
||||||
|
<< " and first non-zero bit position " << first_nonzero_position
|
||||||
|
<< " number of levels is " << level_masks.size();
|
||||||
|
for (auto x : level_masks)
|
||||||
|
std::cout << std::setw(8) << std::hex << x << std::dec << "\n";
|
||||||
|
|
||||||
|
// collect cell ids as masked bisection ids
|
||||||
|
std::vector<std::vector<osrm::util::CellID>> partitions(
|
||||||
|
level_masks.size(), std::vector<osrm::util::CellID>(edge_based_partition_ids.size()));
|
||||||
|
std::vector<std::unordered_set<osrm::util::CellID>> partition_sets(level_masks.size());
|
||||||
|
for (std::size_t index = 0; index < edge_based_partition_ids.size(); ++index)
|
||||||
|
{
|
||||||
|
auto bisection_id = edge_based_partition_ids[index];
|
||||||
|
for (std::size_t level = 0; level < level_masks.size(); ++level)
|
||||||
|
{
|
||||||
|
osrm::util::CellID cell_id =
|
||||||
|
bisection_id & level_masks[level_masks.size() - 1 - level];
|
||||||
|
partitions[level][index] = cell_id;
|
||||||
|
partition_sets[level].insert(cell_id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<std::uint32_t> level_to_num_cells;
|
||||||
|
std::transform(partition_sets.begin(),
|
||||||
|
partition_sets.end(),
|
||||||
|
std::back_inserter(level_to_num_cells),
|
||||||
|
[](const std::unordered_set<osrm::util::CellID> &partition_set) {
|
||||||
|
return partition_set.size();
|
||||||
|
});
|
||||||
|
std::cout << "# of cell on levels\n";
|
||||||
|
for (std::size_t level = 0; level < partition_sets.size(); ++level)
|
||||||
|
{
|
||||||
|
std::cout << level_to_num_cells[level] << ": ";
|
||||||
|
for (auto x : partition_sets[level])
|
||||||
|
std::cout << " " << x;
|
||||||
|
std::cout << "\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
TIMER_START(packed_mlp);
|
||||||
|
osrm::util::PackedMultiLevelPartition<false> mlp{partitions, level_to_num_cells};
|
||||||
|
TIMER_STOP(packed_mlp);
|
||||||
|
util::Log() << "PackedMultiLevelPartition constructed in " << TIMER_SEC(packed_mlp)
|
||||||
|
<< " seconds";
|
||||||
|
|
||||||
|
TIMER_START(cell_storage);
|
||||||
|
osrm::util::CellStorage<false> storage(mlp, *edge_based_graph);
|
||||||
|
TIMER_STOP(cell_storage);
|
||||||
|
util::Log() << "CellStorage constructed in " << TIMER_SEC(cell_storage) << " seconds";
|
||||||
|
|
||||||
|
TIMER_START(writing_mld_data);
|
||||||
|
mlp.Write(config.mld_partition_path);
|
||||||
|
storage.Write(config.mld_storage_path);
|
||||||
|
TIMER_STOP(writing_mld_data);
|
||||||
|
util::Log() << "MLD data writing took " << TIMER_SEC(writing_mld_data) << " seconds";
|
||||||
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -105,5 +105,7 @@ const std::vector<BisectionID> &RecursiveBisection::BisectionIDs() const
|
|||||||
return internal_state.BisectionIDs();
|
return internal_state.BisectionIDs();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::uint32_t RecursiveBisection::SCCDepth() const { return internal_state.SCCDepth(); }
|
||||||
|
|
||||||
} // namespace partition
|
} // namespace partition
|
||||||
} // namespace osrm
|
} // namespace osrm
|
||||||
|
@ -12,12 +12,14 @@
|
|||||||
#include "storage/shared_memory.hpp"
|
#include "storage/shared_memory.hpp"
|
||||||
#include "storage/shared_monitor.hpp"
|
#include "storage/shared_monitor.hpp"
|
||||||
#include "engine/datafacade/datafacade_base.hpp"
|
#include "engine/datafacade/datafacade_base.hpp"
|
||||||
|
#include "util/cell_storage.hpp"
|
||||||
#include "util/coordinate.hpp"
|
#include "util/coordinate.hpp"
|
||||||
#include "util/exception.hpp"
|
#include "util/exception.hpp"
|
||||||
#include "util/exception_utils.hpp"
|
#include "util/exception_utils.hpp"
|
||||||
#include "util/fingerprint.hpp"
|
#include "util/fingerprint.hpp"
|
||||||
#include "util/io.hpp"
|
#include "util/io.hpp"
|
||||||
#include "util/log.hpp"
|
#include "util/log.hpp"
|
||||||
|
#include "util/multi_level_partition.hpp"
|
||||||
#include "util/packed_vector.hpp"
|
#include "util/packed_vector.hpp"
|
||||||
#include "util/range_table.hpp"
|
#include "util/range_table.hpp"
|
||||||
#include "util/shared_memory_vector_wrapper.hpp"
|
#include "util/shared_memory_vector_wrapper.hpp"
|
||||||
@ -393,6 +395,27 @@ void Storage::PopulateLayout(DataLayout &layout)
|
|||||||
layout.SetBlockSize<util::guidance::LaneTupleIdPair>(DataLayout::TURN_LANE_DATA,
|
layout.SetBlockSize<util::guidance::LaneTupleIdPair>(DataLayout::TURN_LANE_DATA,
|
||||||
lane_tuple_count);
|
lane_tuple_count);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
// Loading MLD Data
|
||||||
|
if (boost::filesystem::exists(config.mld_partition_path))
|
||||||
|
{
|
||||||
|
auto mld_partition_size = util::PackedMultiLevelPartition<true>().GetRequiredMemorySize(
|
||||||
|
config.mld_partition_path);
|
||||||
|
layout.SetBlockSize<char>(DataLayout::MLD_CELL_PARTITION, mld_partition_size);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
layout.SetBlockSize<char>(DataLayout::MLD_CELL_PARTITION, 0);
|
||||||
|
|
||||||
|
if (boost::filesystem::exists(config.mld_storage_path))
|
||||||
|
{
|
||||||
|
auto mld_cell_storage_size =
|
||||||
|
util::CellStorage<true>().GetRequiredMemorySize(config.mld_storage_path);
|
||||||
|
layout.SetBlockSize<char>(DataLayout::MLD_CELL_STORAGE, mld_cell_storage_size);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
layout.SetBlockSize<char>(DataLayout::MLD_CELL_STORAGE, 0);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Storage::PopulateData(const DataLayout &layout, char *memory_ptr)
|
void Storage::PopulateData(const DataLayout &layout, char *memory_ptr)
|
||||||
@ -840,6 +863,28 @@ void Storage::PopulateData(const DataLayout &layout, char *memory_ptr)
|
|||||||
std::copy(entry_class_table.begin(), entry_class_table.end(), entry_class_ptr);
|
std::copy(entry_class_table.begin(), entry_class_table.end(), entry_class_ptr);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
// Loading MLD Data
|
||||||
|
const auto mld_partition_ptr =
|
||||||
|
layout.GetBlockPtr<char, true>(memory_ptr, DataLayout::MLD_CELL_PARTITION);
|
||||||
|
const auto mld_partition_size = layout.GetBlockSize(DataLayout::MLD_CELL_PARTITION);
|
||||||
|
if (boost::filesystem::exists(config.mld_partition_path))
|
||||||
|
{
|
||||||
|
util::PackedMultiLevelPartition<true>().Read(
|
||||||
|
config.mld_partition_path, mld_partition_ptr, mld_partition_ptr + mld_partition_size);
|
||||||
|
}
|
||||||
|
|
||||||
|
const auto mld_cell_storage_ptr =
|
||||||
|
layout.GetBlockPtr<char, true>(memory_ptr, DataLayout::MLD_CELL_STORAGE);
|
||||||
|
const auto mld_cell_storage_size = layout.GetBlockSize(DataLayout::MLD_CELL_STORAGE);
|
||||||
|
if (boost::filesystem::exists(config.mld_storage_path))
|
||||||
|
{
|
||||||
|
util::CellStorage<true>().Read(config.mld_storage_path,
|
||||||
|
mld_cell_storage_ptr,
|
||||||
|
mld_cell_storage_ptr + mld_cell_storage_size);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -19,7 +19,9 @@ StorageConfig::StorageConfig(const boost::filesystem::path &base)
|
|||||||
datasource_indexes_path{base.string() + ".datasource_indexes"},
|
datasource_indexes_path{base.string() + ".datasource_indexes"},
|
||||||
names_data_path{base.string() + ".names"}, properties_path{base.string() + ".properties"},
|
names_data_path{base.string() + ".names"}, properties_path{base.string() + ".properties"},
|
||||||
intersection_class_path{base.string() + ".icd"}, turn_lane_data_path{base.string() + ".tld"},
|
intersection_class_path{base.string() + ".icd"}, turn_lane_data_path{base.string() + ".tld"},
|
||||||
turn_lane_description_path{base.string() + ".tls"}
|
turn_lane_description_path{base.string() + ".tls"},
|
||||||
|
mld_partition_path{base.string() + ".mld_partition"},
|
||||||
|
mld_storage_path{base.string() + ".mld_storage"}
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -107,7 +107,7 @@ BOOST_AUTO_TEST_CASE(mutable_cell_storage)
|
|||||||
auto graph = makeGraph(edges);
|
auto graph = makeGraph(edges);
|
||||||
|
|
||||||
// test non-const storage
|
// test non-const storage
|
||||||
CellStorage storage(mlp, graph);
|
CellStorage<false> storage(mlp, graph);
|
||||||
|
|
||||||
// Level 1
|
// Level 1
|
||||||
auto cell_1_0 = storage.GetCell(1, 0);
|
auto cell_1_0 = storage.GetCell(1, 0);
|
||||||
@ -250,7 +250,7 @@ BOOST_AUTO_TEST_CASE(immutable_cell_storage)
|
|||||||
// 3/0: 3 : 1,0,1
|
// 3/0: 3 : 1,0,1
|
||||||
|
|
||||||
// test const storage
|
// test const storage
|
||||||
const CellStorage const_storage(mlp, graph);
|
const CellStorage<false> const_storage(mlp, graph);
|
||||||
|
|
||||||
auto const_cell_1_0 = const_storage.GetCell(1, 0);
|
auto const_cell_1_0 = const_storage.GetCell(1, 0);
|
||||||
auto const_cell_1_1 = const_storage.GetCell(1, 1);
|
auto const_cell_1_1 = const_storage.GetCell(1, 1);
|
||||||
|
@ -24,7 +24,7 @@ BOOST_AUTO_TEST_CASE(packed_mlp)
|
|||||||
std::vector<CellID> l2{{0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 3, 3}};
|
std::vector<CellID> l2{{0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 3, 3}};
|
||||||
std::vector<CellID> l3{{0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1}};
|
std::vector<CellID> l3{{0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1}};
|
||||||
std::vector<CellID> l4{{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}};
|
std::vector<CellID> l4{{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}};
|
||||||
PackedMultiLevelPartition mlp{{l1, l2, l3, l4}, {6, 4, 2, 1}};
|
PackedMultiLevelPartition<false> mlp{{l1, l2, l3, l4}, {6, 4, 2, 1}};
|
||||||
|
|
||||||
BOOST_CHECK_EQUAL(mlp.GetNumberOfCells(1), 6);
|
BOOST_CHECK_EQUAL(mlp.GetNumberOfCells(1), 6);
|
||||||
BOOST_CHECK_EQUAL(mlp.GetNumberOfCells(2), 4);
|
BOOST_CHECK_EQUAL(mlp.GetNumberOfCells(2), 4);
|
||||||
|
Loading…
Reference in New Issue
Block a user