From 3dcc7132b65520c67e71d667980192b6645c3379 Mon Sep 17 00:00:00 2001 From: Michael Krasnyk Date: Mon, 27 Mar 2017 12:17:01 +0200 Subject: [PATCH] Add max-cell-sizes option to partitioner --- features/options/partition/help.feature | 6 +- features/testbot/multi_level_routing.feature | 8 +-- include/partition/partition_config.hpp | 9 ++- src/partition/partitioner.cpp | 10 +--- src/tools/partition.cpp | 59 ++++++++++++++------ 5 files changed, 59 insertions(+), 33 deletions(-) diff --git a/features/options/partition/help.feature b/features/options/partition/help.feature index e757628f9..90bea6e88 100644 --- a/features/options/partition/help.feature +++ b/features/options/partition/help.feature @@ -10,11 +10,11 @@ Feature: osrm-partition command line options: help And stdout should contain "--help" And stdout should contain "Configuration:" And stdout should contain "--threads" - And stdout should contain "--min-cell-size" And stdout should contain "--balance" And stdout should contain "--boundary" And stdout should contain "--optimizing-cuts" And stdout should contain "--small-component-size" + And stdout should contain "--max-cell-sizes" And it should exit with an error Scenario: osrm-partition - Help, short @@ -26,11 +26,11 @@ Feature: osrm-partition command line options: help And stdout should contain "--help" And stdout should contain "Configuration:" And stdout should contain "--threads" - And stdout should contain "--min-cell-size" And stdout should contain "--balance" And stdout should contain "--boundary" And stdout should contain "--optimizing-cuts" And stdout should contain "--small-component-size" + And stdout should contain "--max-cell-sizes" And it should exit successfully Scenario: osrm-partition - Help, long @@ -42,9 +42,9 @@ Feature: osrm-partition command line options: help And stdout should contain "--help" And stdout should contain "Configuration:" And stdout should contain "--threads" - And stdout should contain "--min-cell-size" And stdout should contain "--balance" And stdout should contain "--boundary" And stdout should contain "--optimizing-cuts" And stdout should contain "--small-component-size" + And stdout should contain "--max-cell-sizes" And it should exit successfully diff --git a/features/testbot/multi_level_routing.feature b/features/testbot/multi_level_routing.feature index 30a643f81..f4a02a898 100644 --- a/features/testbot/multi_level_routing.feature +++ b/features/testbot/multi_level_routing.feature @@ -3,7 +3,7 @@ Feature: Multi level routing Background: Given the profile "testbot" - And the partition extra arguments "--min-cell-size 4 --small-component-size 1" + And the partition extra arguments "--small-component-size 1 --max-cell-sizes 4 16 64 --" Scenario: Testbot - Multi level routing check partition Given the node map @@ -31,7 +31,7 @@ Feature: Multi level routing | be | primary | And the data has been extracted - When I run "osrm-partition --min-cell-size 4 --small-component-size 1 {processed_file}" + When I run "osrm-partition --max-cell-sizes 4 16 --small-component-size 1 {processed_file}" Then it should exit successfully And stdout should not contain "level 1 #cells 1 bit size 1" @@ -57,7 +57,6 @@ Feature: Multi level routing | cm | primary | | hj | primary | | kp | primary | - And the partition extra arguments "--min-cell-size 4 --small-component-size 1" When I route I should get | from | to | route | time | @@ -88,7 +87,6 @@ Feature: Multi level routing | dim | primary | | glr | primary | | ot | secondary | - And the partition extra arguments "--min-cell-size 4 --small-component-size 1" When I route I should get | from | to | route | time | @@ -113,6 +111,7 @@ Feature: Multi level routing │ │ l───k """ + And the partition extra arguments "--small-component-size 1 --max-cell-sizes 4 16 --" And the ways | nodes | maxspeed | | abcda | 5 | @@ -124,7 +123,6 @@ Feature: Multi level routing | fi | 15 | | gi | 15 | | hf | 100 | - And the partition extra arguments "--min-cell-size 4 --small-component-size 1" When I route I should get | from | to | route | time | diff --git a/include/partition/partition_config.hpp b/include/partition/partition_config.hpp index 3a7d6246f..3031ec5b7 100644 --- a/include/partition/partition_config.hpp +++ b/include/partition/partition_config.hpp @@ -13,7 +13,12 @@ namespace partition struct PartitionConfig { - PartitionConfig() : requested_num_threads(0) {} + PartitionConfig() + : requested_num_threads(0), balance(1.2), boundary_factor(0.25), num_optimizing_cuts(10), + small_component_size(1000), + max_cell_sizes{128, 128 * 32, 128 * 32 * 16, 128 * 32 * 16 * 32} + { + } void UseDefaults() { @@ -49,11 +54,11 @@ struct PartitionConfig unsigned requested_num_threads; - std::size_t minimum_cell_size; double balance; double boundary_factor; std::size_t num_optimizing_cuts; std::size_t small_component_size; + std::vector max_cell_sizes; }; } } diff --git a/src/partition/partitioner.cpp b/src/partition/partitioner.cpp index f43047023..75eb4dccc 100644 --- a/src/partition/partitioner.cpp +++ b/src/partition/partitioner.cpp @@ -108,12 +108,12 @@ int Partitioner::Run(const PartitionConfig &config) makeBisectionGraph(compressed_node_based_graph.coordinates, adaptToBisectionEdge(std::move(compressed_node_based_graph.edges))); - util::Log() << " running partition: " << config.minimum_cell_size << " " << config.balance + util::Log() << " running partition: " << config.max_cell_sizes.front() << " " << config.balance << " " << config.boundary_factor << " " << config.num_optimizing_cuts << " " << config.small_component_size << " # max_cell_size balance boundary cuts small_component_size"; RecursiveBisection recursive_bisection(graph, - config.minimum_cell_size, + config.max_cell_sizes.front(), config.balance, config.boundary_factor, config.num_optimizing_cuts, @@ -161,11 +161,7 @@ int Partitioner::Run(const PartitionConfig &config) std::vector partitions; std::vector level_to_num_cells; std::tie(partitions, level_to_num_cells) = - bisectionToPartition(edge_based_partition_ids, - {config.minimum_cell_size, - config.minimum_cell_size * 32, - config.minimum_cell_size * 32 * 16, - config.minimum_cell_size * 32 * 16 * 32}); + bisectionToPartition(edge_based_partition_ids, config.max_cell_sizes); auto num_unconnected = removeUnconnectedBoundaryNodes(*edge_based_graph, partitions); util::Log() << "Fixed " << num_unconnected << " unconnected nodes"; diff --git a/src/tools/partition.cpp b/src/tools/partition.cpp index b3c80d05f..8dcd9df52 100644 --- a/src/tools/partition.cpp +++ b/src/tools/partition.cpp @@ -8,9 +8,11 @@ #include +#include #include #include #include +#include #include @@ -23,7 +25,7 @@ enum class return_code : unsigned exit }; -return_code parseArguments(int argc, char *argv[], partition::PartitionConfig &partition_config) +return_code parseArguments(int argc, char *argv[], partition::PartitionConfig &config) { // declare a group of options that will be allowed only on command line boost::program_options::options_description generic_options("Options"); @@ -34,40 +36,47 @@ return_code parseArguments(int argc, char *argv[], partition::PartitionConfig &p config_options.add_options() // ("threads,t", - boost::program_options::value(&partition_config.requested_num_threads) + boost::program_options::value(&config.requested_num_threads) ->default_value(tbb::task_scheduler_init::default_num_threads()), "Number of threads to use") // - ("min-cell-size", - boost::program_options::value(&partition_config.minimum_cell_size) - ->default_value(128), - "Bisection termination citerion based on cell size") - // ("balance", - boost::program_options::value(&partition_config.balance)->default_value(1.2), + boost::program_options::value(&config.balance)->default_value(config.balance), "Balance for left and right side in single bisection") // ("boundary", - boost::program_options::value(&partition_config.boundary_factor) - ->default_value(0.25), + boost::program_options::value(&config.boundary_factor) + ->default_value(config.boundary_factor), "Percentage of embedded nodes to contract as sources and sinks") // ("optimizing-cuts", - boost::program_options::value(&partition_config.num_optimizing_cuts) - ->default_value(10), + boost::program_options::value(&config.num_optimizing_cuts) + ->default_value(config.num_optimizing_cuts), "Number of cuts to use for optimizing a single bisection") // ("small-component-size", - boost::program_options::value(&partition_config.small_component_size) - ->default_value(1000), - "Size threshold for small components."); + boost::program_options::value(&config.small_component_size) + ->default_value(config.small_component_size), + "Size threshold for small components.") + // + ("max-cell-sizes", + boost::program_options::value>(&config.max_cell_sizes) + ->multitoken() + ->default_value(config.max_cell_sizes, + boost::algorithm::join( + config.max_cell_sizes | + boost::adaptors::transformed( + static_cast(std::to_string)), + " ")), + "Maximum cell sizes starting from the level 1. The first cell size value is a bisection " + "termination citerion"); // hidden options, will be allowed on command line, but will not be // shown to the user boost::program_options::options_description hidden_options("Hidden options"); hidden_options.add_options()( "input,i", - boost::program_options::value(&partition_config.base_path), + boost::program_options::value(&config.base_path), "Input file in .osrm format"); // positional option @@ -119,6 +128,24 @@ return_code parseArguments(int argc, char *argv[], partition::PartitionConfig &p return return_code::fail; } + if (config.max_cell_sizes.empty()) + { + util::Log(logERROR) << "The maximum cell sizes array must be non-empty"; + return return_code::fail; + } + + if (!std::is_sorted(config.max_cell_sizes.begin(), config.max_cell_sizes.end())) + { + util::Log(logERROR) << "The maximum cell sizes array must be sorted in non-descending order."; + return return_code::fail; + } + + if (config.max_cell_sizes.front() < 2) + { + util::Log(logERROR) << "Cells on the first level must have at least 2 nodes"; + return return_code::fail; + } + return return_code::ok; }