Merge pull request #1028 from TheMarex/tbb-port
Port from OpenMP to TBB
This commit is contained in:
commit
885dbe1e65
@ -7,7 +7,7 @@ install:
|
|||||||
- sudo apt-add-repository -y ppa:ubuntu-toolchain-r/test
|
- sudo apt-add-repository -y ppa:ubuntu-toolchain-r/test
|
||||||
- sudo add-apt-repository -y ppa:boost-latest/ppa
|
- sudo add-apt-repository -y ppa:boost-latest/ppa
|
||||||
- sudo apt-get update >/dev/null
|
- sudo apt-get update >/dev/null
|
||||||
- sudo apt-get -q install libprotoc-dev libprotobuf7 libprotobuf-dev libosmpbf-dev libbz2-dev libstxxl-dev libstxxl1 libxml2-dev libzip-dev lua5.1 liblua5.1-0-dev rubygems
|
- sudo apt-get -q install libprotoc-dev libprotobuf7 libprotobuf-dev libosmpbf-dev libbz2-dev libstxxl-dev libstxxl1 libxml2-dev libzip-dev lua5.1 liblua5.1-0-dev rubygems libtbb-dev
|
||||||
- sudo apt-get -q install g++-4.7
|
- sudo apt-get -q install g++-4.7
|
||||||
- sudo apt-get install libboost1.54-all-dev
|
- sudo apt-get install libboost1.54-all-dev
|
||||||
#luabind
|
#luabind
|
||||||
|
@ -177,6 +177,11 @@ target_link_libraries(osrm-datastore ${Boost_LIBRARIES} UUID GITDESCRIPTION COOR
|
|||||||
find_package(Threads REQUIRED)
|
find_package(Threads REQUIRED)
|
||||||
target_link_libraries(osrm-extract ${CMAKE_THREAD_LIBS_INIT})
|
target_link_libraries(osrm-extract ${CMAKE_THREAD_LIBS_INIT})
|
||||||
|
|
||||||
|
find_package(TBB REQUIRED)
|
||||||
|
target_link_libraries(osrm-extract ${TBB_LIBRARIES})
|
||||||
|
target_link_libraries(osrm-prepare ${TBB_LIBRARIES})
|
||||||
|
include_directories(${TBB_INCLUDE_DIR})
|
||||||
|
|
||||||
find_package(Lua52)
|
find_package(Lua52)
|
||||||
if(NOT LUA52_FOUND)
|
if(NOT LUA52_FOUND)
|
||||||
find_package(Lua51 REQUIRED)
|
find_package(Lua51 REQUIRED)
|
||||||
|
@ -38,9 +38,13 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||||||
#include "../Util/OpenMPWrapper.h"
|
#include "../Util/OpenMPWrapper.h"
|
||||||
#include "../Util/SimpleLogger.h"
|
#include "../Util/SimpleLogger.h"
|
||||||
#include "../Util/StringUtil.h"
|
#include "../Util/StringUtil.h"
|
||||||
|
#include "../Util/TimingUtil.h"
|
||||||
|
|
||||||
#include <boost/assert.hpp>
|
#include <boost/assert.hpp>
|
||||||
|
|
||||||
|
#include <tbb/enumerable_thread_specific.h>
|
||||||
|
#include <tbb/parallel_for.h>
|
||||||
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <limits>
|
#include <limits>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
@ -125,6 +129,28 @@ class Contractor
|
|||||||
bool is_independent : 1;
|
bool is_independent : 1;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
struct ThreadDataContainer
|
||||||
|
{
|
||||||
|
ThreadDataContainer(int number_of_nodes) : number_of_nodes(number_of_nodes) {}
|
||||||
|
|
||||||
|
inline ContractorThreadData* getThreadData()
|
||||||
|
{
|
||||||
|
bool exists = false;
|
||||||
|
auto& ref = data.local(exists);
|
||||||
|
if (!exists)
|
||||||
|
{
|
||||||
|
ref = std::make_shared<ContractorThreadData>(number_of_nodes);
|
||||||
|
}
|
||||||
|
|
||||||
|
return ref.get();
|
||||||
|
}
|
||||||
|
|
||||||
|
int number_of_nodes;
|
||||||
|
typedef tbb::enumerable_thread_specific<std::shared_ptr<ContractorThreadData>> EnumerableThreadData;
|
||||||
|
EnumerableThreadData data;
|
||||||
|
};
|
||||||
|
|
||||||
public:
|
public:
|
||||||
template <class ContainerT> Contractor(int nodes, ContainerT &input_edge_list)
|
template <class ContainerT> Contractor(int nodes, ContainerT &input_edge_list)
|
||||||
{
|
{
|
||||||
@ -262,39 +288,51 @@ class Contractor
|
|||||||
|
|
||||||
void Run()
|
void Run()
|
||||||
{
|
{
|
||||||
|
// for the preperation we can use a big grain size, which is much faster (probably cache)
|
||||||
|
constexpr size_t InitGrainSize = 100000;
|
||||||
|
constexpr size_t PQGrainSize = 100000;
|
||||||
|
// auto_partitioner will automatically increase the blocksize if we have
|
||||||
|
// a lot of data. It is *important* for the last loop iterations
|
||||||
|
// (which have a very small dataset) that it is devisible.
|
||||||
|
constexpr size_t IndependentGrainSize = 1;
|
||||||
|
constexpr size_t ContractGrainSize = 1;
|
||||||
|
constexpr size_t NeighboursGrainSize = 1;
|
||||||
|
constexpr size_t DeleteGrainSize = 1;
|
||||||
|
|
||||||
const NodeID number_of_nodes = contractor_graph->GetNumberOfNodes();
|
const NodeID number_of_nodes = contractor_graph->GetNumberOfNodes();
|
||||||
Percent p(number_of_nodes);
|
Percent p(number_of_nodes);
|
||||||
|
|
||||||
const unsigned thread_count = omp_get_max_threads();
|
ThreadDataContainer thread_data_list(number_of_nodes);
|
||||||
std::vector<ContractorThreadData *> thread_data_list;
|
|
||||||
for (unsigned thread_id = 0; thread_id < thread_count; ++thread_id)
|
|
||||||
{
|
|
||||||
thread_data_list.push_back(new ContractorThreadData(number_of_nodes));
|
|
||||||
}
|
|
||||||
std::cout << "Contractor is using " << thread_count << " threads" << std::endl;
|
|
||||||
|
|
||||||
NodeID number_of_contracted_nodes = 0;
|
NodeID number_of_contracted_nodes = 0;
|
||||||
std::vector<RemainingNodeData> remaining_nodes(number_of_nodes);
|
std::vector<RemainingNodeData> remaining_nodes(number_of_nodes);
|
||||||
std::vector<float> node_priorities(number_of_nodes);
|
std::vector<float> node_priorities(number_of_nodes);
|
||||||
std::vector<NodePriorityData> node_data(number_of_nodes);
|
std::vector<NodePriorityData> node_data(number_of_nodes);
|
||||||
|
|
||||||
// initialize priorities in parallel
|
|
||||||
#pragma omp parallel for schedule(guided)
|
// initialize priorities in parallel
|
||||||
for (int x = 0; x < (int)number_of_nodes; ++x)
|
tbb::parallel_for(tbb::blocked_range<int>(0, number_of_nodes, InitGrainSize),
|
||||||
{
|
[&remaining_nodes](const tbb::blocked_range<int>& range)
|
||||||
remaining_nodes[x].id = x;
|
{
|
||||||
}
|
for (int x = range.begin(); x != range.end(); ++x)
|
||||||
|
{
|
||||||
|
remaining_nodes[x].id = x;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
std::cout << "initializing elimination PQ ..." << std::flush;
|
std::cout << "initializing elimination PQ ..." << std::flush;
|
||||||
#pragma omp parallel
|
tbb::parallel_for(tbb::blocked_range<int>(0, number_of_nodes, PQGrainSize),
|
||||||
{
|
[this, &node_priorities, &node_data, &thread_data_list](const tbb::blocked_range<int>& range)
|
||||||
ContractorThreadData *data = thread_data_list[omp_get_thread_num()];
|
|
||||||
#pragma omp parallel for schedule(guided)
|
|
||||||
for (int x = 0; x < (int)number_of_nodes; ++x)
|
|
||||||
{
|
{
|
||||||
node_priorities[x] = EvaluateNodePriority(data, &node_data[x], x);
|
ContractorThreadData *data = thread_data_list.getThreadData();
|
||||||
|
for (int x = range.begin(); x != range.end(); ++x)
|
||||||
|
{
|
||||||
|
node_priorities[x] = this->EvaluateNodePriority(data, &node_data[x], x);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
);
|
||||||
std::cout << "ok" << std::endl << "preprocessing " << number_of_nodes << " nodes ..."
|
std::cout << "ok" << std::endl << "preprocessing " << number_of_nodes << " nodes ..."
|
||||||
<< std::flush;
|
<< std::flush;
|
||||||
|
|
||||||
@ -309,11 +347,7 @@ class Contractor
|
|||||||
std::cout << " [flush " << number_of_contracted_nodes << " nodes] " << std::flush;
|
std::cout << " [flush " << number_of_contracted_nodes << " nodes] " << std::flush;
|
||||||
|
|
||||||
// Delete old heap data to free memory that we need for the coming operations
|
// Delete old heap data to free memory that we need for the coming operations
|
||||||
for (ContractorThreadData *data : thread_data_list)
|
thread_data_list.data.clear();
|
||||||
{
|
|
||||||
delete data;
|
|
||||||
}
|
|
||||||
thread_data_list.clear();
|
|
||||||
|
|
||||||
// Create new priority array
|
// Create new priority array
|
||||||
std::vector<float> new_node_priority(remaining_nodes.size());
|
std::vector<float> new_node_priority(remaining_nodes.size());
|
||||||
@ -396,61 +430,69 @@ class Contractor
|
|||||||
|
|
||||||
// INFO: MAKE SURE THIS IS THE LAST OPERATION OF THE FLUSH!
|
// INFO: MAKE SURE THIS IS THE LAST OPERATION OF THE FLUSH!
|
||||||
// reinitialize heaps and ThreadData objects with appropriate size
|
// reinitialize heaps and ThreadData objects with appropriate size
|
||||||
for (unsigned thread_id = 0; thread_id < thread_count; ++thread_id)
|
thread_data_list.number_of_nodes = contractor_graph->GetNumberOfNodes();
|
||||||
{
|
|
||||||
thread_data_list.push_back(
|
|
||||||
new ContractorThreadData(contractor_graph->GetNumberOfNodes()));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const int last = (int)remaining_nodes.size();
|
const int last = (int)remaining_nodes.size();
|
||||||
#pragma omp parallel
|
tbb::parallel_for(tbb::blocked_range<int>(0, last, IndependentGrainSize),
|
||||||
{
|
[this, &node_priorities, &remaining_nodes, &thread_data_list](const tbb::blocked_range<int>& range)
|
||||||
// determine independent node set
|
|
||||||
ContractorThreadData *const data = thread_data_list[omp_get_thread_num()];
|
|
||||||
#pragma omp for schedule(guided)
|
|
||||||
for (int i = 0; i < last; ++i)
|
|
||||||
{
|
{
|
||||||
const NodeID node = remaining_nodes[i].id;
|
ContractorThreadData *data = thread_data_list.getThreadData();
|
||||||
remaining_nodes[i].is_independent =
|
// determine independent node set
|
||||||
IsNodeIndependent(node_priorities, data, node);
|
for (int i = range.begin(); i != range.end(); ++i)
|
||||||
|
{
|
||||||
|
const NodeID node = remaining_nodes[i].id;
|
||||||
|
remaining_nodes[i].is_independent =
|
||||||
|
this->IsNodeIndependent(node_priorities, data, node);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
);
|
||||||
|
|
||||||
const auto first = stable_partition(remaining_nodes.begin(),
|
const auto first = stable_partition(remaining_nodes.begin(),
|
||||||
remaining_nodes.end(),
|
remaining_nodes.end(),
|
||||||
[](RemainingNodeData node_data)
|
[](RemainingNodeData node_data)
|
||||||
{ return !node_data.is_independent; });
|
{ return !node_data.is_independent; });
|
||||||
const int first_independent_node = first - remaining_nodes.begin();
|
const int first_independent_node = first - remaining_nodes.begin();
|
||||||
// contract independent nodes
|
|
||||||
#pragma omp parallel
|
|
||||||
{
|
|
||||||
ContractorThreadData *data = thread_data_list[omp_get_thread_num()];
|
|
||||||
#pragma omp for schedule(guided) nowait
|
|
||||||
for (int position = first_independent_node; position < last; ++position)
|
|
||||||
{
|
|
||||||
NodeID x = remaining_nodes[position].id;
|
|
||||||
ContractNode<false>(data, x);
|
|
||||||
}
|
|
||||||
|
|
||||||
std::sort(data->inserted_edges.begin(), data->inserted_edges.end());
|
// contract independent nodes
|
||||||
}
|
tbb::parallel_for(tbb::blocked_range<int>(first_independent_node, last, ContractGrainSize),
|
||||||
#pragma omp parallel
|
[this, &remaining_nodes, &thread_data_list](const tbb::blocked_range<int>& range)
|
||||||
{
|
|
||||||
ContractorThreadData *data = thread_data_list[omp_get_thread_num()];
|
|
||||||
#pragma omp for schedule(guided) nowait
|
|
||||||
for (int position = first_independent_node; position < last; ++position)
|
|
||||||
{
|
{
|
||||||
NodeID x = remaining_nodes[position].id;
|
ContractorThreadData *data = thread_data_list.getThreadData();
|
||||||
DeleteIncomingEdges(data, x);
|
for (int position = range.begin(); position != range.end(); ++position)
|
||||||
|
{
|
||||||
|
const NodeID x = remaining_nodes[position].id;
|
||||||
|
this->ContractNode<false>(data, x);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
);
|
||||||
// insert new edges
|
// make sure we really sort each block
|
||||||
for (unsigned thread_id = 0; thread_id < thread_count; ++thread_id)
|
tbb::parallel_for(thread_data_list.data.range(),
|
||||||
{
|
[&](const ThreadDataContainer::EnumerableThreadData::range_type& range)
|
||||||
ContractorThreadData &data = *thread_data_list[thread_id];
|
|
||||||
for (const ContractorEdge &edge : data.inserted_edges)
|
|
||||||
{
|
{
|
||||||
auto current_edge_ID = contractor_graph->FindEdge(edge.source, edge.target);
|
for (auto& data : range)
|
||||||
|
std::sort(data->inserted_edges.begin(),
|
||||||
|
data->inserted_edges.end());
|
||||||
|
}
|
||||||
|
);
|
||||||
|
tbb::parallel_for(tbb::blocked_range<int>(first_independent_node, last, DeleteGrainSize),
|
||||||
|
[this, &remaining_nodes, &thread_data_list](const tbb::blocked_range<int>& range)
|
||||||
|
{
|
||||||
|
ContractorThreadData *data = thread_data_list.getThreadData();
|
||||||
|
for (int position = range.begin(); position != range.end(); ++position)
|
||||||
|
{
|
||||||
|
const NodeID x = remaining_nodes[position].id;
|
||||||
|
this->DeleteIncomingEdges(data, x);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
// insert new edges
|
||||||
|
for (auto& data : thread_data_list.data)
|
||||||
|
{
|
||||||
|
for (const ContractorEdge &edge : data->inserted_edges)
|
||||||
|
{
|
||||||
|
const EdgeID current_edge_ID = contractor_graph->FindEdge(edge.source, edge.target);
|
||||||
if (current_edge_ID < contractor_graph->EndEdges(edge.source))
|
if (current_edge_ID < contractor_graph->EndEdges(edge.source))
|
||||||
{
|
{
|
||||||
ContractorGraph::EdgeData ¤t_data =
|
ContractorGraph::EdgeData ¤t_data =
|
||||||
@ -466,19 +508,21 @@ class Contractor
|
|||||||
}
|
}
|
||||||
contractor_graph->InsertEdge(edge.source, edge.target, edge.data);
|
contractor_graph->InsertEdge(edge.source, edge.target, edge.data);
|
||||||
}
|
}
|
||||||
data.inserted_edges.clear();
|
data->inserted_edges.clear();
|
||||||
}
|
}
|
||||||
// update priorities
|
|
||||||
#pragma omp parallel
|
tbb::parallel_for(tbb::blocked_range<int>(first_independent_node, last, NeighboursGrainSize),
|
||||||
{
|
[this, &remaining_nodes, &node_priorities, &node_data, &thread_data_list](const tbb::blocked_range<int>& range)
|
||||||
ContractorThreadData *data = thread_data_list[omp_get_thread_num()];
|
|
||||||
#pragma omp for schedule(guided) nowait
|
|
||||||
for (int position = first_independent_node; position < last; ++position)
|
|
||||||
{
|
{
|
||||||
NodeID x = remaining_nodes[position].id;
|
ContractorThreadData *data = thread_data_list.getThreadData();
|
||||||
UpdateNodeNeighbours(node_priorities, node_data, data, x);
|
for (int position = range.begin(); position != range.end(); ++position)
|
||||||
|
{
|
||||||
|
NodeID x = remaining_nodes[position].id;
|
||||||
|
this->UpdateNodeNeighbours(node_priorities, node_data, data, x);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
);
|
||||||
|
|
||||||
// remove contracted nodes from the pool
|
// remove contracted nodes from the pool
|
||||||
number_of_contracted_nodes += last - first_independent_node;
|
number_of_contracted_nodes += last - first_independent_node;
|
||||||
remaining_nodes.resize(first_independent_node);
|
remaining_nodes.resize(first_independent_node);
|
||||||
@ -510,11 +554,8 @@ class Contractor
|
|||||||
|
|
||||||
p.printStatus(number_of_contracted_nodes);
|
p.printStatus(number_of_contracted_nodes);
|
||||||
}
|
}
|
||||||
for (ContractorThreadData *data : thread_data_list)
|
|
||||||
{
|
thread_data_list.data.clear();
|
||||||
delete data;
|
|
||||||
}
|
|
||||||
thread_data_list.clear();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class Edge> inline void GetEdges(DeallocatingVector<Edge> &edges)
|
template <class Edge> inline void GetEdges(DeallocatingVector<Edge> &edges)
|
||||||
@ -769,7 +810,6 @@ class Contractor
|
|||||||
true,
|
true,
|
||||||
true,
|
true,
|
||||||
false);
|
false);
|
||||||
;
|
|
||||||
inserted_edges.push_back(new_edge);
|
inserted_edges.push_back(new_edge);
|
||||||
std::swap(new_edge.source, new_edge.target);
|
std::swap(new_edge.source, new_edge.target);
|
||||||
new_edge.data.forward = false;
|
new_edge.data.forward = false;
|
||||||
|
@ -28,8 +28,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||||||
#include "TemporaryStorage.h"
|
#include "TemporaryStorage.h"
|
||||||
|
|
||||||
StreamData::StreamData()
|
StreamData::StreamData()
|
||||||
: write_mode(true), temp_path(boost::filesystem::unique_path(temp_directory.append(
|
: write_mode(true), temp_path(boost::filesystem::unique_path(temp_directory / TemporaryFilePattern)),
|
||||||
TemporaryFilePattern.begin(), TemporaryFilePattern.end()))),
|
|
||||||
temp_file(new boost::filesystem::fstream(
|
temp_file(new boost::filesystem::fstream(
|
||||||
temp_path, std::ios::in | std::ios::out | std::ios::trunc | std::ios::binary)),
|
temp_path, std::ios::in | std::ios::out | std::ios::trunc | std::ios::binary)),
|
||||||
readWriteMutex(std::make_shared<boost::mutex>())
|
readWriteMutex(std::make_shared<boost::mutex>())
|
||||||
|
@ -38,6 +38,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <limits>
|
#include <limits>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
#include <atomic>
|
||||||
|
|
||||||
template <typename EdgeDataT> class DynamicGraph
|
template <typename EdgeDataT> class DynamicGraph
|
||||||
{
|
{
|
||||||
@ -198,7 +199,6 @@ template <typename EdgeDataT> class DynamicGraph
|
|||||||
void DeleteEdge(const NodeIterator source, const EdgeIterator e)
|
void DeleteEdge(const NodeIterator source, const EdgeIterator e)
|
||||||
{
|
{
|
||||||
Node &node = m_nodes[source];
|
Node &node = m_nodes[source];
|
||||||
#pragma omp atomic
|
|
||||||
--m_numEdges;
|
--m_numEdges;
|
||||||
--node.edges;
|
--node.edges;
|
||||||
BOOST_ASSERT(std::numeric_limits<unsigned>::max() != node.edges);
|
BOOST_ASSERT(std::numeric_limits<unsigned>::max() != node.edges);
|
||||||
@ -226,7 +226,6 @@ template <typename EdgeDataT> class DynamicGraph
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#pragma omp atomic
|
|
||||||
m_numEdges -= deleted;
|
m_numEdges -= deleted;
|
||||||
m_nodes[source].edges -= deleted;
|
m_nodes[source].edges -= deleted;
|
||||||
|
|
||||||
@ -272,7 +271,7 @@ template <typename EdgeDataT> class DynamicGraph
|
|||||||
};
|
};
|
||||||
|
|
||||||
NodeIterator m_numNodes;
|
NodeIterator m_numNodes;
|
||||||
EdgeIterator m_numEdges;
|
std::atomic_uint m_numEdges;
|
||||||
|
|
||||||
std::vector<Node> m_nodes;
|
std::vector<Node> m_nodes;
|
||||||
DeallocatingVector<Edge> m_edges;
|
DeallocatingVector<Edge> m_edges;
|
||||||
|
@ -30,6 +30,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||||||
|
|
||||||
#include "../Util/OpenMPWrapper.h"
|
#include "../Util/OpenMPWrapper.h"
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
#include <atomic>
|
||||||
|
|
||||||
class Percent
|
class Percent
|
||||||
{
|
{
|
||||||
@ -61,20 +62,18 @@ class Percent
|
|||||||
|
|
||||||
void printIncrement()
|
void printIncrement()
|
||||||
{
|
{
|
||||||
#pragma omp atomic
|
|
||||||
++m_current_value;
|
++m_current_value;
|
||||||
printStatus(m_current_value);
|
printStatus(m_current_value);
|
||||||
}
|
}
|
||||||
|
|
||||||
void printAddition(const unsigned addition)
|
void printAddition(const unsigned addition)
|
||||||
{
|
{
|
||||||
#pragma omp atomic
|
|
||||||
m_current_value += addition;
|
m_current_value += addition;
|
||||||
printStatus(m_current_value);
|
printStatus(m_current_value);
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
unsigned m_current_value;
|
std::atomic_uint m_current_value;
|
||||||
unsigned m_max_value;
|
unsigned m_max_value;
|
||||||
unsigned m_percent_interval;
|
unsigned m_percent_interval;
|
||||||
unsigned m_next_threshold;
|
unsigned m_next_threshold;
|
||||||
|
@ -48,6 +48,8 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||||||
|
|
||||||
#include <boost/thread.hpp>
|
#include <boost/thread.hpp>
|
||||||
|
|
||||||
|
#include <tbb/parallel_for.h>
|
||||||
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <array>
|
#include <array>
|
||||||
#include <chrono>
|
#include <chrono>
|
||||||
@ -278,24 +280,33 @@ class StaticRTree
|
|||||||
|
|
||||||
HilbertCode get_hilbert_number;
|
HilbertCode get_hilbert_number;
|
||||||
|
|
||||||
// generate auxiliary vector of hilbert-values
|
// generate auxiliary vector of hilbert-values
|
||||||
#pragma omp parallel for schedule(guided)
|
tbb::parallel_for(tbb::blocked_range<uint64_t>(0, m_element_count),
|
||||||
for (uint64_t element_counter = 0; element_counter < m_element_count; ++element_counter)
|
[&input_data_vector,
|
||||||
{
|
&input_wrapper_vector,
|
||||||
input_wrapper_vector[element_counter].m_array_index = element_counter;
|
&get_hilbert_number,
|
||||||
// Get Hilbert-Value for centroid in mercartor projection
|
&coordinate_list](const tbb::blocked_range<uint64_t>& range)
|
||||||
DataT const ¤t_element = input_data_vector[element_counter];
|
{
|
||||||
FixedPointCoordinate current_centroid =
|
for (uint64_t element_counter = range.begin(); element_counter != range.end(); ++element_counter)
|
||||||
DataT::Centroid(FixedPointCoordinate(coordinate_list.at(current_element.u).lat,
|
{
|
||||||
coordinate_list.at(current_element.u).lon),
|
WrappedInputElement ¤t_wrapper = input_wrapper_vector[element_counter];
|
||||||
FixedPointCoordinate(coordinate_list.at(current_element.v).lat,
|
current_wrapper.m_array_index = element_counter;
|
||||||
coordinate_list.at(current_element.v).lon));
|
|
||||||
current_centroid.lat =
|
|
||||||
COORDINATE_PRECISION * lat2y(current_centroid.lat / COORDINATE_PRECISION);
|
|
||||||
|
|
||||||
uint64_t current_hilbert_value = get_hilbert_number(current_centroid);
|
DataT const ¤t_element = input_data_vector[element_counter];
|
||||||
input_wrapper_vector[element_counter].m_hilbert_value = current_hilbert_value;
|
|
||||||
}
|
// Get Hilbert-Value for centroid in mercartor projection
|
||||||
|
FixedPointCoordinate current_centroid =
|
||||||
|
DataT::Centroid(FixedPointCoordinate(coordinate_list.at(current_element.u).lat,
|
||||||
|
coordinate_list.at(current_element.u).lon),
|
||||||
|
FixedPointCoordinate(coordinate_list.at(current_element.v).lat,
|
||||||
|
coordinate_list.at(current_element.v).lon));
|
||||||
|
current_centroid.lat =
|
||||||
|
COORDINATE_PRECISION * lat2y(current_centroid.lat / COORDINATE_PRECISION);
|
||||||
|
|
||||||
|
current_wrapper.m_hilbert_value = get_hilbert_number(current_centroid);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
// open leaf file
|
// open leaf file
|
||||||
boost::filesystem::ofstream leaf_node_file(leaf_node_filename, std::ios::binary);
|
boost::filesystem::ofstream leaf_node_file(leaf_node_filename, std::ios::binary);
|
||||||
@ -383,17 +394,22 @@ class StaticRTree
|
|||||||
// reverse and renumber tree to have root at index 0
|
// reverse and renumber tree to have root at index 0
|
||||||
std::reverse(m_search_tree.begin(), m_search_tree.end());
|
std::reverse(m_search_tree.begin(), m_search_tree.end());
|
||||||
|
|
||||||
#pragma omp parallel for schedule(guided)
|
uint32_t search_tree_size = m_search_tree.size();
|
||||||
for (uint32_t i = 0; i < m_search_tree.size(); ++i)
|
tbb::parallel_for(tbb::blocked_range<uint32_t>(0, search_tree_size),
|
||||||
{
|
[this, &search_tree_size](const tbb::blocked_range<uint32_t>& range)
|
||||||
TreeNode ¤t_tree_node = m_search_tree[i];
|
|
||||||
for (uint32_t j = 0; j < current_tree_node.child_count; ++j)
|
|
||||||
{
|
{
|
||||||
const uint32_t old_id = current_tree_node.children[j];
|
for (uint32_t i = range.begin(); i != range.end(); ++i)
|
||||||
const uint32_t new_id = m_search_tree.size() - old_id - 1;
|
{
|
||||||
current_tree_node.children[j] = new_id;
|
TreeNode ¤t_tree_node = this->m_search_tree[i];
|
||||||
|
for (uint32_t j = 0; j < current_tree_node.child_count; ++j)
|
||||||
|
{
|
||||||
|
const uint32_t old_id = current_tree_node.children[j];
|
||||||
|
const uint32_t new_id = search_tree_size - old_id - 1;
|
||||||
|
current_tree_node.children[j] = new_id;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
);
|
||||||
|
|
||||||
// open tree file
|
// open tree file
|
||||||
boost::filesystem::ofstream tree_node_file(tree_node_filename, std::ios::binary);
|
boost::filesystem::ofstream tree_node_file(tree_node_filename, std::ios::binary);
|
||||||
|
@ -42,7 +42,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||||||
BaseParser::BaseParser(ExtractorCallbacks *extractor_callbacks,
|
BaseParser::BaseParser(ExtractorCallbacks *extractor_callbacks,
|
||||||
ScriptingEnvironment &scripting_environment)
|
ScriptingEnvironment &scripting_environment)
|
||||||
: extractor_callbacks(extractor_callbacks),
|
: extractor_callbacks(extractor_callbacks),
|
||||||
lua_state(scripting_environment.getLuaStateForThreadID(0)),
|
lua_state(scripting_environment.getLuaState()),
|
||||||
scripting_environment(scripting_environment), use_turn_restrictions(true)
|
scripting_environment(scripting_environment), use_turn_restrictions(true)
|
||||||
{
|
{
|
||||||
ReadUseRestrictionsSetting();
|
ReadUseRestrictionsSetting();
|
||||||
|
@ -40,6 +40,8 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||||||
#include "../Util/SimpleLogger.h"
|
#include "../Util/SimpleLogger.h"
|
||||||
#include "../typedefs.h"
|
#include "../typedefs.h"
|
||||||
|
|
||||||
|
#include <tbb/parallel_for.h>
|
||||||
|
|
||||||
#include <osrm/Coordinate.h>
|
#include <osrm/Coordinate.h>
|
||||||
|
|
||||||
#include <zlib.h>
|
#include <zlib.h>
|
||||||
@ -257,16 +259,18 @@ inline void PBFParser::parseDenseNode(ParserThreadData *thread_data)
|
|||||||
denseTagIndex += 2;
|
denseTagIndex += 2;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#pragma omp parallel
|
|
||||||
{
|
tbb::parallel_for(tbb::blocked_range<size_t>(0, extracted_nodes_vector.size()),
|
||||||
const int thread_num = omp_get_thread_num();
|
[this, &extracted_nodes_vector](const tbb::blocked_range<size_t>& range)
|
||||||
#pragma omp parallel for schedule(guided)
|
|
||||||
for (int i = 0; i < number_of_nodes; ++i)
|
|
||||||
{
|
{
|
||||||
ImportNode &import_node = extracted_nodes_vector[i];
|
lua_State* lua_state = this->scripting_environment.getLuaState();
|
||||||
ParseNodeInLua(import_node, scripting_environment.getLuaStateForThreadID(thread_num));
|
for (size_t i = range.begin(); i != range.end(); i++)
|
||||||
|
{
|
||||||
|
ImportNode &import_node = extracted_nodes_vector[i];
|
||||||
|
ParseNodeInLua(import_node, lua_state);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
);
|
||||||
|
|
||||||
for (const ImportNode &import_node : extracted_nodes_vector)
|
for (const ImportNode &import_node : extracted_nodes_vector)
|
||||||
{
|
{
|
||||||
@ -424,16 +428,21 @@ inline void PBFParser::parseWay(ParserThreadData *thread_data)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#pragma omp parallel for schedule(guided)
|
// TODO: investigate if schedule guided will be handled by tbb automatically
|
||||||
for (int i = 0; i < number_of_ways; ++i)
|
tbb::parallel_for(tbb::blocked_range<size_t>(0, parsed_way_vector.size()),
|
||||||
{
|
[this, &parsed_way_vector](const tbb::blocked_range<size_t>& range)
|
||||||
ExtractionWay &extraction_way = parsed_way_vector[i];
|
|
||||||
if (2 <= extraction_way.path.size())
|
|
||||||
{
|
{
|
||||||
ParseWayInLua(extraction_way,
|
lua_State* lua_state = this->scripting_environment.getLuaState();
|
||||||
scripting_environment.getLuaStateForThreadID(omp_get_thread_num()));
|
for (size_t i = range.begin(); i != range.end(); i++)
|
||||||
|
{
|
||||||
|
ExtractionWay &extraction_way = parsed_way_vector[i];
|
||||||
|
if (2 <= extraction_way.path.size())
|
||||||
|
{
|
||||||
|
ParseWayInLua(extraction_way, lua_state);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
);
|
||||||
|
|
||||||
for (ExtractionWay &extraction_way : parsed_way_vector)
|
for (ExtractionWay &extraction_way : parsed_way_vector)
|
||||||
{
|
{
|
||||||
|
@ -38,87 +38,85 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||||||
|
|
||||||
ScriptingEnvironment::ScriptingEnvironment() {}
|
ScriptingEnvironment::ScriptingEnvironment() {}
|
||||||
ScriptingEnvironment::ScriptingEnvironment(const char *file_name)
|
ScriptingEnvironment::ScriptingEnvironment(const char *file_name)
|
||||||
|
: file_name(file_name)
|
||||||
{
|
{
|
||||||
SimpleLogger().Write() << "Using script " << file_name;
|
SimpleLogger().Write() << "Using script " << file_name;
|
||||||
|
|
||||||
// Create a new lua state
|
|
||||||
for (int i = 0; i < omp_get_max_threads(); ++i)
|
|
||||||
{
|
|
||||||
lua_state_vector.push_back(luaL_newstate());
|
|
||||||
}
|
|
||||||
|
|
||||||
// Connect LuaBind to this lua state for all threads
|
|
||||||
#pragma omp parallel
|
|
||||||
{
|
|
||||||
lua_State *lua_state = getLuaStateForThreadID(omp_get_thread_num());
|
|
||||||
luabind::open(lua_state);
|
|
||||||
// open utility libraries string library;
|
|
||||||
luaL_openlibs(lua_state);
|
|
||||||
|
|
||||||
luaAddScriptFolderToLoadPath(lua_state, file_name);
|
|
||||||
|
|
||||||
// Add our function to the state's global scope
|
|
||||||
luabind::module(lua_state)[
|
|
||||||
luabind::def("print", LUA_print<std::string>),
|
|
||||||
luabind::def("durationIsValid", durationIsValid),
|
|
||||||
luabind::def("parseDuration", parseDuration)
|
|
||||||
];
|
|
||||||
|
|
||||||
luabind::module(lua_state)[luabind::class_<HashTable<std::string, std::string>>("keyVals")
|
|
||||||
.def("Add", &HashTable<std::string, std::string>::Add)
|
|
||||||
.def("Find", &HashTable<std::string, std::string>::Find)
|
|
||||||
.def("Holds", &HashTable<std::string, std::string>::Holds)];
|
|
||||||
|
|
||||||
luabind::module(lua_state)[luabind::class_<ImportNode>("Node")
|
|
||||||
.def(luabind::constructor<>())
|
|
||||||
.def_readwrite("lat", &ImportNode::lat)
|
|
||||||
.def_readwrite("lon", &ImportNode::lon)
|
|
||||||
.def_readonly("id", &ImportNode::id)
|
|
||||||
.def_readwrite("bollard", &ImportNode::bollard)
|
|
||||||
.def_readwrite("traffic_light", &ImportNode::trafficLight)
|
|
||||||
.def_readwrite("tags", &ImportNode::keyVals)];
|
|
||||||
|
|
||||||
luabind::module(lua_state)
|
|
||||||
[luabind::class_<ExtractionWay>("Way")
|
|
||||||
.def(luabind::constructor<>())
|
|
||||||
.def_readonly("id", &ExtractionWay::id)
|
|
||||||
.def_readwrite("name", &ExtractionWay::name)
|
|
||||||
.def_readwrite("speed", &ExtractionWay::speed)
|
|
||||||
.def_readwrite("backward_speed", &ExtractionWay::backward_speed)
|
|
||||||
.def_readwrite("duration", &ExtractionWay::duration)
|
|
||||||
.def_readwrite("type", &ExtractionWay::type)
|
|
||||||
.def_readwrite("access", &ExtractionWay::access)
|
|
||||||
.def_readwrite("roundabout", &ExtractionWay::roundabout)
|
|
||||||
.def_readwrite("is_access_restricted", &ExtractionWay::isAccessRestricted)
|
|
||||||
.def_readwrite("ignore_in_grid", &ExtractionWay::ignoreInGrid)
|
|
||||||
.def_readwrite("tags", &ExtractionWay::keyVals)
|
|
||||||
.def_readwrite("direction", &ExtractionWay::direction)
|
|
||||||
.enum_("constants")[
|
|
||||||
luabind::value("notSure", 0),
|
|
||||||
luabind::value("oneway", 1),
|
|
||||||
luabind::value("bidirectional", 2),
|
|
||||||
luabind::value("opposite", 3)
|
|
||||||
]];
|
|
||||||
|
|
||||||
// fails on c++11/OS X 10.9
|
|
||||||
luabind::module(lua_state)[luabind::class_<std::vector<std::string>>("vector").def(
|
|
||||||
"Add",
|
|
||||||
static_cast<void (std::vector<std::string>::*)(const std::string &)>(
|
|
||||||
&std::vector<std::string>::push_back))];
|
|
||||||
|
|
||||||
if (0 != luaL_dofile(lua_state, file_name))
|
|
||||||
{
|
|
||||||
throw OSRMException("ERROR occured in scripting block");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ScriptingEnvironment::~ScriptingEnvironment()
|
void ScriptingEnvironment::initLuaState(lua_State* lua_state)
|
||||||
{
|
{
|
||||||
for (unsigned i = 0; i < lua_state_vector.size(); ++i)
|
luabind::open(lua_state);
|
||||||
|
// open utility libraries string library;
|
||||||
|
luaL_openlibs(lua_state);
|
||||||
|
|
||||||
|
luaAddScriptFolderToLoadPath(lua_state, file_name.c_str());
|
||||||
|
|
||||||
|
// Add our function to the state's global scope
|
||||||
|
luabind::module(lua_state)[
|
||||||
|
luabind::def("print", LUA_print<std::string>),
|
||||||
|
luabind::def("durationIsValid", durationIsValid),
|
||||||
|
luabind::def("parseDuration", parseDuration)
|
||||||
|
];
|
||||||
|
|
||||||
|
luabind::module(lua_state)[luabind::class_<HashTable<std::string, std::string>>("keyVals")
|
||||||
|
.def("Add", &HashTable<std::string, std::string>::Add)
|
||||||
|
.def("Find", &HashTable<std::string, std::string>::Find)
|
||||||
|
.def("Holds", &HashTable<std::string, std::string>::Holds)];
|
||||||
|
|
||||||
|
luabind::module(lua_state)[luabind::class_<ImportNode>("Node")
|
||||||
|
.def(luabind::constructor<>())
|
||||||
|
.def_readwrite("lat", &ImportNode::lat)
|
||||||
|
.def_readwrite("lon", &ImportNode::lon)
|
||||||
|
.def_readonly("id", &ImportNode::id)
|
||||||
|
.def_readwrite("bollard", &ImportNode::bollard)
|
||||||
|
.def_readwrite("traffic_light", &ImportNode::trafficLight)
|
||||||
|
.def_readwrite("tags", &ImportNode::keyVals)];
|
||||||
|
|
||||||
|
luabind::module(lua_state)
|
||||||
|
[luabind::class_<ExtractionWay>("Way")
|
||||||
|
.def(luabind::constructor<>())
|
||||||
|
.def_readonly("id", &ExtractionWay::id)
|
||||||
|
.def_readwrite("name", &ExtractionWay::name)
|
||||||
|
.def_readwrite("speed", &ExtractionWay::speed)
|
||||||
|
.def_readwrite("backward_speed", &ExtractionWay::backward_speed)
|
||||||
|
.def_readwrite("duration", &ExtractionWay::duration)
|
||||||
|
.def_readwrite("type", &ExtractionWay::type)
|
||||||
|
.def_readwrite("access", &ExtractionWay::access)
|
||||||
|
.def_readwrite("roundabout", &ExtractionWay::roundabout)
|
||||||
|
.def_readwrite("is_access_restricted", &ExtractionWay::isAccessRestricted)
|
||||||
|
.def_readwrite("ignore_in_grid", &ExtractionWay::ignoreInGrid)
|
||||||
|
.def_readwrite("tags", &ExtractionWay::keyVals)
|
||||||
|
.def_readwrite("direction", &ExtractionWay::direction)
|
||||||
|
.enum_("constants")[
|
||||||
|
luabind::value("notSure", 0),
|
||||||
|
luabind::value("oneway", 1),
|
||||||
|
luabind::value("bidirectional", 2),
|
||||||
|
luabind::value("opposite", 3)
|
||||||
|
]];
|
||||||
|
|
||||||
|
// fails on c++11/OS X 10.9
|
||||||
|
luabind::module(lua_state)[luabind::class_<std::vector<std::string>>("vector").def(
|
||||||
|
"Add",
|
||||||
|
static_cast<void (std::vector<std::string>::*)(const std::string &)>(
|
||||||
|
&std::vector<std::string>::push_back))];
|
||||||
|
|
||||||
|
if (0 != luaL_dofile(lua_state, file_name.c_str()))
|
||||||
{
|
{
|
||||||
// lua_state_vector[i];
|
throw OSRMException("ERROR occured in scripting block");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
lua_State *ScriptingEnvironment::getLuaStateForThreadID(const int id) { return lua_state_vector[id]; }
|
lua_State *ScriptingEnvironment::getLuaState()
|
||||||
|
{
|
||||||
|
bool initialized = false;
|
||||||
|
auto& ref = script_contexts.local(initialized);
|
||||||
|
if (!initialized)
|
||||||
|
{
|
||||||
|
std::shared_ptr<lua_State> state(luaL_newstate(), lua_close);
|
||||||
|
ref = state;
|
||||||
|
initLuaState(ref.get());
|
||||||
|
}
|
||||||
|
|
||||||
|
return ref.get();
|
||||||
|
}
|
||||||
|
|
||||||
|
@ -28,7 +28,9 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||||||
#ifndef SCRIPTINGENVIRONMENT_H_
|
#ifndef SCRIPTINGENVIRONMENT_H_
|
||||||
#define SCRIPTINGENVIRONMENT_H_
|
#define SCRIPTINGENVIRONMENT_H_
|
||||||
|
|
||||||
#include <vector>
|
#include <string>
|
||||||
|
#include <memory>
|
||||||
|
#include <tbb/enumerable_thread_specific.h>
|
||||||
|
|
||||||
struct lua_State;
|
struct lua_State;
|
||||||
|
|
||||||
@ -37,11 +39,14 @@ class ScriptingEnvironment
|
|||||||
public:
|
public:
|
||||||
ScriptingEnvironment();
|
ScriptingEnvironment();
|
||||||
explicit ScriptingEnvironment(const char *file_name);
|
explicit ScriptingEnvironment(const char *file_name);
|
||||||
virtual ~ScriptingEnvironment();
|
|
||||||
|
|
||||||
lua_State *getLuaStateForThreadID(const int);
|
lua_State *getLuaState();
|
||||||
|
|
||||||
std::vector<lua_State *> lua_state_vector;
|
private:
|
||||||
|
void initLuaState(lua_State* lua_state);
|
||||||
|
|
||||||
|
std::string file_name;
|
||||||
|
tbb::enumerable_thread_specific<std::shared_ptr<lua_State>> script_contexts;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif /* SCRIPTINGENVIRONMENT_H_ */
|
#endif /* SCRIPTINGENVIRONMENT_H_ */
|
||||||
|
283
cmake/FindTBB.cmake
Normal file
283
cmake/FindTBB.cmake
Normal file
@ -0,0 +1,283 @@
|
|||||||
|
# Locate Intel Threading Building Blocks include paths and libraries
|
||||||
|
# FindTBB.cmake can be found at https://code.google.com/p/findtbb/
|
||||||
|
# Written by Hannes Hofmann <hannes.hofmann _at_ informatik.uni-erlangen.de>
|
||||||
|
# Improvements by Gino van den Bergen <gino _at_ dtecta.com>,
|
||||||
|
# Florian Uhlig <F.Uhlig _at_ gsi.de>,
|
||||||
|
# Jiri Marsik <jiri.marsik89 _at_ gmail.com>
|
||||||
|
|
||||||
|
# The MIT License
|
||||||
|
#
|
||||||
|
# Copyright (c) 2011 Hannes Hofmann
|
||||||
|
#
|
||||||
|
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
# of this software and associated documentation files (the "Software"), to deal
|
||||||
|
# in the Software without restriction, including without limitation the rights
|
||||||
|
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
# copies of the Software, and to permit persons to whom the Software is
|
||||||
|
# furnished to do so, subject to the following conditions:
|
||||||
|
#
|
||||||
|
# The above copyright notice and this permission notice shall be included in
|
||||||
|
# all copies or substantial portions of the Software.
|
||||||
|
#
|
||||||
|
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
# THE SOFTWARE.
|
||||||
|
|
||||||
|
# GvdB: This module uses the environment variable TBB_ARCH_PLATFORM which defines architecture and compiler.
|
||||||
|
# e.g. "ia32/vc8" or "em64t/cc4.1.0_libc2.4_kernel2.6.16.21"
|
||||||
|
# TBB_ARCH_PLATFORM is set by the build script tbbvars[.bat|.sh|.csh], which can be found
|
||||||
|
# in the TBB installation directory (TBB_INSTALL_DIR).
|
||||||
|
#
|
||||||
|
# GvdB: Mac OS X distribution places libraries directly in lib directory.
|
||||||
|
#
|
||||||
|
# For backwards compatibility, you may explicitely set the CMake variables TBB_ARCHITECTURE and TBB_COMPILER.
|
||||||
|
# TBB_ARCHITECTURE [ ia32 | em64t | itanium ]
|
||||||
|
# which architecture to use
|
||||||
|
# TBB_COMPILER e.g. vc9 or cc3.2.3_libc2.3.2_kernel2.4.21 or cc4.0.1_os10.4.9
|
||||||
|
# which compiler to use (detected automatically on Windows)
|
||||||
|
|
||||||
|
# This module respects
|
||||||
|
# TBB_INSTALL_DIR or $ENV{TBB21_INSTALL_DIR} or $ENV{TBB_INSTALL_DIR}
|
||||||
|
|
||||||
|
# This module defines
|
||||||
|
# TBB_INCLUDE_DIRS, where to find task_scheduler_init.h, etc.
|
||||||
|
# TBB_LIBRARY_DIRS, where to find libtbb, libtbbmalloc
|
||||||
|
# TBB_DEBUG_LIBRARY_DIRS, where to find libtbb_debug, libtbbmalloc_debug
|
||||||
|
# TBB_INSTALL_DIR, the base TBB install directory
|
||||||
|
# TBB_LIBRARIES, the libraries to link against to use TBB.
|
||||||
|
# TBB_DEBUG_LIBRARIES, the libraries to link against to use TBB with debug symbols.
|
||||||
|
# TBB_FOUND, If false, don't try to use TBB.
|
||||||
|
# TBB_INTERFACE_VERSION, as defined in tbb/tbb_stddef.h
|
||||||
|
|
||||||
|
|
||||||
|
if (WIN32)
|
||||||
|
# has em64t/vc8 em64t/vc9
|
||||||
|
# has ia32/vc7.1 ia32/vc8 ia32/vc9
|
||||||
|
set(_TBB_DEFAULT_INSTALL_DIR "C:/Program Files/Intel/TBB" "C:/Program Files (x86)/Intel/TBB")
|
||||||
|
set(_TBB_LIB_NAME "tbb")
|
||||||
|
set(_TBB_LIB_MALLOC_NAME "${_TBB_LIB_NAME}malloc")
|
||||||
|
set(_TBB_LIB_DEBUG_NAME "${_TBB_LIB_NAME}_debug")
|
||||||
|
set(_TBB_LIB_MALLOC_DEBUG_NAME "${_TBB_LIB_MALLOC_NAME}_debug")
|
||||||
|
if (MSVC71)
|
||||||
|
set (_TBB_COMPILER "vc7.1")
|
||||||
|
endif(MSVC71)
|
||||||
|
if (MSVC80)
|
||||||
|
set(_TBB_COMPILER "vc8")
|
||||||
|
endif(MSVC80)
|
||||||
|
if (MSVC90)
|
||||||
|
set(_TBB_COMPILER "vc9")
|
||||||
|
endif(MSVC90)
|
||||||
|
if(MSVC10)
|
||||||
|
set(_TBB_COMPILER "vc10")
|
||||||
|
endif(MSVC10)
|
||||||
|
# Todo: add other Windows compilers such as ICL.
|
||||||
|
set(_TBB_ARCHITECTURE ${TBB_ARCHITECTURE})
|
||||||
|
endif (WIN32)
|
||||||
|
|
||||||
|
if (UNIX)
|
||||||
|
if (APPLE)
|
||||||
|
# MAC
|
||||||
|
set(_TBB_DEFAULT_INSTALL_DIR "/Library/Frameworks/Intel_TBB.framework/Versions")
|
||||||
|
# libs: libtbb.dylib, libtbbmalloc.dylib, *_debug
|
||||||
|
set(_TBB_LIB_NAME "tbb")
|
||||||
|
set(_TBB_LIB_MALLOC_NAME "${_TBB_LIB_NAME}malloc")
|
||||||
|
set(_TBB_LIB_DEBUG_NAME "${_TBB_LIB_NAME}_debug")
|
||||||
|
set(_TBB_LIB_MALLOC_DEBUG_NAME "${_TBB_LIB_MALLOC_NAME}_debug")
|
||||||
|
# default flavor on apple: ia32/cc4.0.1_os10.4.9
|
||||||
|
# Jiri: There is no reason to presume there is only one flavor and
|
||||||
|
# that user's setting of variables should be ignored.
|
||||||
|
if(NOT TBB_COMPILER)
|
||||||
|
set(_TBB_COMPILER "cc4.0.1_os10.4.9")
|
||||||
|
elseif (NOT TBB_COMPILER)
|
||||||
|
set(_TBB_COMPILER ${TBB_COMPILER})
|
||||||
|
endif(NOT TBB_COMPILER)
|
||||||
|
if(NOT TBB_ARCHITECTURE)
|
||||||
|
set(_TBB_ARCHITECTURE "ia32")
|
||||||
|
elseif(NOT TBB_ARCHITECTURE)
|
||||||
|
set(_TBB_ARCHITECTURE ${TBB_ARCHITECTURE})
|
||||||
|
endif(NOT TBB_ARCHITECTURE)
|
||||||
|
else (APPLE)
|
||||||
|
# LINUX
|
||||||
|
set(_TBB_DEFAULT_INSTALL_DIR "/opt/intel/tbb" "/usr/local/include" "/usr/include")
|
||||||
|
set(_TBB_LIB_NAME "tbb")
|
||||||
|
set(_TBB_LIB_MALLOC_NAME "${_TBB_LIB_NAME}malloc")
|
||||||
|
set(_TBB_LIB_DEBUG_NAME "${_TBB_LIB_NAME}_debug")
|
||||||
|
set(_TBB_LIB_MALLOC_DEBUG_NAME "${_TBB_LIB_MALLOC_NAME}_debug")
|
||||||
|
# has em64t/cc3.2.3_libc2.3.2_kernel2.4.21 em64t/cc3.3.3_libc2.3.3_kernel2.6.5 em64t/cc3.4.3_libc2.3.4_kernel2.6.9 em64t/cc4.1.0_libc2.4_kernel2.6.16.21
|
||||||
|
# has ia32/*
|
||||||
|
# has itanium/*
|
||||||
|
set(_TBB_COMPILER ${TBB_COMPILER})
|
||||||
|
set(_TBB_ARCHITECTURE ${TBB_ARCHITECTURE})
|
||||||
|
endif (APPLE)
|
||||||
|
endif (UNIX)
|
||||||
|
|
||||||
|
if (CMAKE_SYSTEM MATCHES "SunOS.*")
|
||||||
|
# SUN
|
||||||
|
# not yet supported
|
||||||
|
# has em64t/cc3.4.3_kernel5.10
|
||||||
|
# has ia32/*
|
||||||
|
endif (CMAKE_SYSTEM MATCHES "SunOS.*")
|
||||||
|
|
||||||
|
|
||||||
|
#-- Clear the public variables
|
||||||
|
set (TBB_FOUND "NO")
|
||||||
|
|
||||||
|
|
||||||
|
#-- Find TBB install dir and set ${_TBB_INSTALL_DIR} and cached ${TBB_INSTALL_DIR}
|
||||||
|
# first: use CMake variable TBB_INSTALL_DIR
|
||||||
|
if (TBB_INSTALL_DIR)
|
||||||
|
set (_TBB_INSTALL_DIR ${TBB_INSTALL_DIR})
|
||||||
|
endif (TBB_INSTALL_DIR)
|
||||||
|
# second: use environment variable
|
||||||
|
if (NOT _TBB_INSTALL_DIR)
|
||||||
|
if (NOT "$ENV{TBB_INSTALL_DIR}" STREQUAL "")
|
||||||
|
set (_TBB_INSTALL_DIR $ENV{TBB_INSTALL_DIR})
|
||||||
|
endif (NOT "$ENV{TBB_INSTALL_DIR}" STREQUAL "")
|
||||||
|
# Intel recommends setting TBB21_INSTALL_DIR
|
||||||
|
if (NOT "$ENV{TBB21_INSTALL_DIR}" STREQUAL "")
|
||||||
|
set (_TBB_INSTALL_DIR $ENV{TBB21_INSTALL_DIR})
|
||||||
|
endif (NOT "$ENV{TBB21_INSTALL_DIR}" STREQUAL "")
|
||||||
|
if (NOT "$ENV{TBB22_INSTALL_DIR}" STREQUAL "")
|
||||||
|
set (_TBB_INSTALL_DIR $ENV{TBB22_INSTALL_DIR})
|
||||||
|
endif (NOT "$ENV{TBB22_INSTALL_DIR}" STREQUAL "")
|
||||||
|
if (NOT "$ENV{TBB30_INSTALL_DIR}" STREQUAL "")
|
||||||
|
set (_TBB_INSTALL_DIR $ENV{TBB30_INSTALL_DIR})
|
||||||
|
endif (NOT "$ENV{TBB30_INSTALL_DIR}" STREQUAL "")
|
||||||
|
endif (NOT _TBB_INSTALL_DIR)
|
||||||
|
# third: try to find path automatically
|
||||||
|
if (NOT _TBB_INSTALL_DIR)
|
||||||
|
if (_TBB_DEFAULT_INSTALL_DIR)
|
||||||
|
set (_TBB_INSTALL_DIR ${_TBB_DEFAULT_INSTALL_DIR})
|
||||||
|
endif (_TBB_DEFAULT_INSTALL_DIR)
|
||||||
|
endif (NOT _TBB_INSTALL_DIR)
|
||||||
|
# sanity check
|
||||||
|
if (NOT _TBB_INSTALL_DIR)
|
||||||
|
message ("ERROR: Unable to find Intel TBB install directory. ${_TBB_INSTALL_DIR}")
|
||||||
|
else (NOT _TBB_INSTALL_DIR)
|
||||||
|
# finally: set the cached CMake variable TBB_INSTALL_DIR
|
||||||
|
if (NOT TBB_INSTALL_DIR)
|
||||||
|
set (TBB_INSTALL_DIR ${_TBB_INSTALL_DIR} CACHE PATH "Intel TBB install directory")
|
||||||
|
mark_as_advanced(TBB_INSTALL_DIR)
|
||||||
|
endif (NOT TBB_INSTALL_DIR)
|
||||||
|
|
||||||
|
|
||||||
|
#-- A macro to rewrite the paths of the library. This is necessary, because
|
||||||
|
# find_library() always found the em64t/vc9 version of the TBB libs
|
||||||
|
macro(TBB_CORRECT_LIB_DIR var_name)
|
||||||
|
# if (NOT "${_TBB_ARCHITECTURE}" STREQUAL "em64t")
|
||||||
|
string(REPLACE em64t "${_TBB_ARCHITECTURE}" ${var_name} ${${var_name}})
|
||||||
|
# endif (NOT "${_TBB_ARCHITECTURE}" STREQUAL "em64t")
|
||||||
|
string(REPLACE ia32 "${_TBB_ARCHITECTURE}" ${var_name} ${${var_name}})
|
||||||
|
string(REPLACE vc7.1 "${_TBB_COMPILER}" ${var_name} ${${var_name}})
|
||||||
|
string(REPLACE vc8 "${_TBB_COMPILER}" ${var_name} ${${var_name}})
|
||||||
|
string(REPLACE vc9 "${_TBB_COMPILER}" ${var_name} ${${var_name}})
|
||||||
|
string(REPLACE vc10 "${_TBB_COMPILER}" ${var_name} ${${var_name}})
|
||||||
|
endmacro(TBB_CORRECT_LIB_DIR var_content)
|
||||||
|
|
||||||
|
|
||||||
|
#-- Look for include directory and set ${TBB_INCLUDE_DIR}
|
||||||
|
set (TBB_INC_SEARCH_DIR ${_TBB_INSTALL_DIR}/include)
|
||||||
|
# Jiri: tbbvars now sets the CPATH environment variable to the directory
|
||||||
|
# containing the headers.
|
||||||
|
find_path(TBB_INCLUDE_DIR
|
||||||
|
tbb/task_scheduler_init.h
|
||||||
|
PATHS ${TBB_INC_SEARCH_DIR} ENV CPATH
|
||||||
|
)
|
||||||
|
mark_as_advanced(TBB_INCLUDE_DIR)
|
||||||
|
|
||||||
|
|
||||||
|
#-- Look for libraries
|
||||||
|
# GvdB: $ENV{TBB_ARCH_PLATFORM} is set by the build script tbbvars[.bat|.sh|.csh]
|
||||||
|
if (NOT $ENV{TBB_ARCH_PLATFORM} STREQUAL "")
|
||||||
|
set (_TBB_LIBRARY_DIR
|
||||||
|
${_TBB_INSTALL_DIR}/lib/$ENV{TBB_ARCH_PLATFORM}
|
||||||
|
${_TBB_INSTALL_DIR}/$ENV{TBB_ARCH_PLATFORM}/lib
|
||||||
|
)
|
||||||
|
endif (NOT $ENV{TBB_ARCH_PLATFORM} STREQUAL "")
|
||||||
|
# Jiri: This block isn't mutually exclusive with the previous one
|
||||||
|
# (hence no else), instead I test if the user really specified
|
||||||
|
# the variables in question.
|
||||||
|
if ((NOT ${TBB_ARCHITECTURE} STREQUAL "") AND (NOT ${TBB_COMPILER} STREQUAL ""))
|
||||||
|
# HH: deprecated
|
||||||
|
message(STATUS "[Warning] FindTBB.cmake: The use of TBB_ARCHITECTURE and TBB_COMPILER is deprecated and may not be supported in future versions. Please set \$ENV{TBB_ARCH_PLATFORM} (using tbbvars.[bat|csh|sh]).")
|
||||||
|
# Jiri: It doesn't hurt to look in more places, so I store the hints from
|
||||||
|
# ENV{TBB_ARCH_PLATFORM} and the TBB_ARCHITECTURE and TBB_COMPILER
|
||||||
|
# variables and search them both.
|
||||||
|
set (_TBB_LIBRARY_DIR "${_TBB_INSTALL_DIR}/${_TBB_ARCHITECTURE}/${_TBB_COMPILER}/lib" ${_TBB_LIBRARY_DIR})
|
||||||
|
endif ((NOT ${TBB_ARCHITECTURE} STREQUAL "") AND (NOT ${TBB_COMPILER} STREQUAL ""))
|
||||||
|
|
||||||
|
# GvdB: Mac OS X distribution places libraries directly in lib directory.
|
||||||
|
list(APPEND _TBB_LIBRARY_DIR ${_TBB_INSTALL_DIR}/lib)
|
||||||
|
|
||||||
|
# Jiri: No reason not to check the default paths. From recent versions,
|
||||||
|
# tbbvars has started exporting the LIBRARY_PATH and LD_LIBRARY_PATH
|
||||||
|
# variables, which now point to the directories of the lib files.
|
||||||
|
# It all makes more sense to use the ${_TBB_LIBRARY_DIR} as a HINTS
|
||||||
|
# argument instead of the implicit PATHS as it isn't hard-coded
|
||||||
|
# but computed by system introspection. Searching the LIBRARY_PATH
|
||||||
|
# and LD_LIBRARY_PATH environment variables is now even more important
|
||||||
|
# that tbbvars doesn't export TBB_ARCH_PLATFORM and it facilitates
|
||||||
|
# the use of TBB built from sources.
|
||||||
|
find_library(TBB_LIBRARY ${_TBB_LIB_NAME} HINTS ${_TBB_LIBRARY_DIR}
|
||||||
|
PATHS ENV LIBRARY_PATH ENV LD_LIBRARY_PATH)
|
||||||
|
find_library(TBB_MALLOC_LIBRARY ${_TBB_LIB_MALLOC_NAME} HINTS ${_TBB_LIBRARY_DIR}
|
||||||
|
PATHS ENV LIBRARY_PATH ENV LD_LIBRARY_PATH)
|
||||||
|
|
||||||
|
#Extract path from TBB_LIBRARY name
|
||||||
|
get_filename_component(TBB_LIBRARY_DIR ${TBB_LIBRARY} PATH)
|
||||||
|
|
||||||
|
#TBB_CORRECT_LIB_DIR(TBB_LIBRARY)
|
||||||
|
#TBB_CORRECT_LIB_DIR(TBB_MALLOC_LIBRARY)
|
||||||
|
mark_as_advanced(TBB_LIBRARY TBB_MALLOC_LIBRARY)
|
||||||
|
|
||||||
|
#-- Look for debug libraries
|
||||||
|
# Jiri: Changed the same way as for the release libraries.
|
||||||
|
find_library(TBB_LIBRARY_DEBUG ${_TBB_LIB_DEBUG_NAME} HINTS ${_TBB_LIBRARY_DIR}
|
||||||
|
PATHS ENV LIBRARY_PATH ENV LD_LIBRARY_PATH)
|
||||||
|
find_library(TBB_MALLOC_LIBRARY_DEBUG ${_TBB_LIB_MALLOC_DEBUG_NAME} HINTS ${_TBB_LIBRARY_DIR}
|
||||||
|
PATHS ENV LIBRARY_PATH ENV LD_LIBRARY_PATH)
|
||||||
|
|
||||||
|
# Jiri: Self-built TBB stores the debug libraries in a separate directory.
|
||||||
|
# Extract path from TBB_LIBRARY_DEBUG name
|
||||||
|
get_filename_component(TBB_LIBRARY_DEBUG_DIR ${TBB_LIBRARY_DEBUG} PATH)
|
||||||
|
|
||||||
|
#TBB_CORRECT_LIB_DIR(TBB_LIBRARY_DEBUG)
|
||||||
|
#TBB_CORRECT_LIB_DIR(TBB_MALLOC_LIBRARY_DEBUG)
|
||||||
|
mark_as_advanced(TBB_LIBRARY_DEBUG TBB_MALLOC_LIBRARY_DEBUG)
|
||||||
|
|
||||||
|
|
||||||
|
if (TBB_INCLUDE_DIR)
|
||||||
|
if (TBB_LIBRARY)
|
||||||
|
set (TBB_FOUND "YES")
|
||||||
|
set (TBB_LIBRARIES ${TBB_LIBRARY} ${TBB_MALLOC_LIBRARY} ${TBB_LIBRARIES})
|
||||||
|
set (TBB_DEBUG_LIBRARIES ${TBB_LIBRARY_DEBUG} ${TBB_MALLOC_LIBRARY_DEBUG} ${TBB_DEBUG_LIBRARIES})
|
||||||
|
set (TBB_INCLUDE_DIRS ${TBB_INCLUDE_DIR} CACHE PATH "TBB include directory" FORCE)
|
||||||
|
set (TBB_LIBRARY_DIRS ${TBB_LIBRARY_DIR} CACHE PATH "TBB library directory" FORCE)
|
||||||
|
# Jiri: Self-built TBB stores the debug libraries in a separate directory.
|
||||||
|
set (TBB_DEBUG_LIBRARY_DIRS ${TBB_LIBRARY_DEBUG_DIR} CACHE PATH "TBB debug library directory" FORCE)
|
||||||
|
mark_as_advanced(TBB_INCLUDE_DIRS TBB_LIBRARY_DIRS TBB_DEBUG_LIBRARY_DIRS TBB_LIBRARIES TBB_DEBUG_LIBRARIES)
|
||||||
|
message(STATUS "Found Intel TBB")
|
||||||
|
endif (TBB_LIBRARY)
|
||||||
|
endif (TBB_INCLUDE_DIR)
|
||||||
|
|
||||||
|
if (NOT TBB_FOUND)
|
||||||
|
message("ERROR: Intel TBB NOT found!")
|
||||||
|
message(STATUS "Looked for Threading Building Blocks in ${_TBB_INSTALL_DIR}")
|
||||||
|
# do only throw fatal, if this pkg is REQUIRED
|
||||||
|
if (TBB_FIND_REQUIRED)
|
||||||
|
message(FATAL_ERROR "Could NOT find TBB library.")
|
||||||
|
endif (TBB_FIND_REQUIRED)
|
||||||
|
endif (NOT TBB_FOUND)
|
||||||
|
|
||||||
|
endif (NOT _TBB_INSTALL_DIR)
|
||||||
|
|
||||||
|
if (TBB_FOUND)
|
||||||
|
set(TBB_INTERFACE_VERSION 0)
|
||||||
|
FILE(READ "${TBB_INCLUDE_DIRS}/tbb/tbb_stddef.h" _TBB_VERSION_CONTENTS)
|
||||||
|
STRING(REGEX REPLACE ".*#define TBB_INTERFACE_VERSION ([0-9]+).*" "\\1" TBB_INTERFACE_VERSION "${_TBB_VERSION_CONTENTS}")
|
||||||
|
set(TBB_INTERFACE_VERSION "${TBB_INTERFACE_VERSION}")
|
||||||
|
endif (TBB_FOUND)
|
@ -42,12 +42,15 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||||||
|
|
||||||
#include <cstdlib>
|
#include <cstdlib>
|
||||||
|
|
||||||
|
#include <thread>
|
||||||
#include <chrono>
|
#include <chrono>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <unordered_map>
|
#include <unordered_map>
|
||||||
|
|
||||||
|
#include <tbb/task_scheduler_init.h>
|
||||||
|
|
||||||
ExtractorCallbacks *extractor_callbacks;
|
ExtractorCallbacks *extractor_callbacks;
|
||||||
UUID uuid;
|
UUID uuid;
|
||||||
|
|
||||||
@ -60,7 +63,7 @@ int main(int argc, char *argv[])
|
|||||||
std::chrono::steady_clock::now();
|
std::chrono::steady_clock::now();
|
||||||
|
|
||||||
boost::filesystem::path config_file_path, input_path, profile_path;
|
boost::filesystem::path config_file_path, input_path, profile_path;
|
||||||
int requested_num_threads;
|
unsigned int requested_num_threads;
|
||||||
|
|
||||||
// declare a group of options that will be allowed only on command line
|
// declare a group of options that will be allowed only on command line
|
||||||
boost::program_options::options_description generic_options("Options");
|
boost::program_options::options_description generic_options("Options");
|
||||||
@ -78,7 +81,7 @@ int main(int argc, char *argv[])
|
|||||||
&profile_path)->default_value("profile.lua"),
|
&profile_path)->default_value("profile.lua"),
|
||||||
"Path to LUA routing profile")(
|
"Path to LUA routing profile")(
|
||||||
"threads,t",
|
"threads,t",
|
||||||
boost::program_options::value<int>(&requested_num_threads)->default_value(8),
|
boost::program_options::value<unsigned int>(&requested_num_threads)->default_value(8),
|
||||||
"Number of threads to use");
|
"Number of threads to use");
|
||||||
|
|
||||||
// hidden options, will be allowed both on command line and in config file, but will not be
|
// hidden options, will be allowed both on command line and in config file, but will not be
|
||||||
@ -163,18 +166,19 @@ int main(int argc, char *argv[])
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
int real_num_threads = std::min(omp_get_num_procs(), requested_num_threads);
|
unsigned int hardware_threads = std::max((unsigned int) 1, std::thread::hardware_concurrency());
|
||||||
|
unsigned int real_num_threads = std::min(hardware_threads, requested_num_threads);
|
||||||
|
|
||||||
SimpleLogger().Write() << "Input file: " << input_path.filename().string();
|
SimpleLogger().Write() << "Input file: " << input_path.filename().string();
|
||||||
SimpleLogger().Write() << "Profile: " << profile_path.filename().string();
|
SimpleLogger().Write() << "Profile: " << profile_path.filename().string();
|
||||||
SimpleLogger().Write() << "Threads: " << real_num_threads << " (requested "
|
SimpleLogger().Write() << "Threads: " << real_num_threads << " (requested "
|
||||||
<< requested_num_threads << ")";
|
<< requested_num_threads << ")";
|
||||||
|
|
||||||
|
tbb::task_scheduler_init init(real_num_threads);
|
||||||
|
|
||||||
/*** Setup Scripting Environment ***/
|
/*** Setup Scripting Environment ***/
|
||||||
ScriptingEnvironment scripting_environment(profile_path.c_str());
|
ScriptingEnvironment scripting_environment(profile_path.c_str());
|
||||||
|
|
||||||
omp_set_num_threads(real_num_threads);
|
|
||||||
|
|
||||||
bool file_has_pbf_format(false);
|
bool file_has_pbf_format(false);
|
||||||
std::string output_file_name = input_path.string();
|
std::string output_file_name = input_path.string();
|
||||||
std::string restriction_fileName = input_path.string();
|
std::string restriction_fileName = input_path.string();
|
||||||
|
15
prepare.cpp
15
prepare.cpp
@ -49,11 +49,14 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||||||
|
|
||||||
#include <luabind/luabind.hpp>
|
#include <luabind/luabind.hpp>
|
||||||
|
|
||||||
|
#include <thread>
|
||||||
#include <chrono>
|
#include <chrono>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
|
#include <tbb/task_scheduler_init.h>
|
||||||
|
|
||||||
typedef QueryEdge::EdgeData EdgeData;
|
typedef QueryEdge::EdgeData EdgeData;
|
||||||
typedef DynamicGraph<EdgeData>::InputEdge InputEdge;
|
typedef DynamicGraph<EdgeData>::InputEdge InputEdge;
|
||||||
typedef StaticGraph<EdgeData>::InputEdge StaticEdge;
|
typedef StaticGraph<EdgeData>::InputEdge StaticEdge;
|
||||||
@ -66,6 +69,8 @@ std::vector<ImportEdge> edge_list;
|
|||||||
|
|
||||||
int main(int argc, char *argv[])
|
int main(int argc, char *argv[])
|
||||||
{
|
{
|
||||||
|
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
LogPolicy::GetInstance().Unmute();
|
LogPolicy::GetInstance().Unmute();
|
||||||
@ -73,7 +78,7 @@ int main(int argc, char *argv[])
|
|||||||
std::chrono::steady_clock::now();
|
std::chrono::steady_clock::now();
|
||||||
|
|
||||||
boost::filesystem::path config_file_path, input_path, restrictions_path, profile_path;
|
boost::filesystem::path config_file_path, input_path, restrictions_path, profile_path;
|
||||||
int requested_num_threads;
|
unsigned int requested_num_threads;
|
||||||
|
|
||||||
// declare a group of options that will be allowed only on command line
|
// declare a group of options that will be allowed only on command line
|
||||||
boost::program_options::options_description generic_options("Options");
|
boost::program_options::options_description generic_options("Options");
|
||||||
@ -95,7 +100,7 @@ int main(int argc, char *argv[])
|
|||||||
->default_value("profile.lua"),
|
->default_value("profile.lua"),
|
||||||
"Path to LUA routing profile")(
|
"Path to LUA routing profile")(
|
||||||
"threads,t",
|
"threads,t",
|
||||||
boost::program_options::value<int>(&requested_num_threads)->default_value(8),
|
boost::program_options::value<unsigned int>(&requested_num_threads)->default_value(8),
|
||||||
"Number of threads to use");
|
"Number of threads to use");
|
||||||
|
|
||||||
// hidden options, will be allowed both on command line and in config file, but will not be
|
// hidden options, will be allowed both on command line and in config file, but will not be
|
||||||
@ -174,7 +179,8 @@ int main(int argc, char *argv[])
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
int real_num_threads = std::min(omp_get_num_procs(), requested_num_threads);
|
unsigned int hardware_threads = std::max((unsigned int) 1, std::thread::hardware_concurrency());
|
||||||
|
unsigned int real_num_threads = std::min(hardware_threads, requested_num_threads);
|
||||||
|
|
||||||
SimpleLogger().Write() << "Input file: " << input_path.filename().string();
|
SimpleLogger().Write() << "Input file: " << input_path.filename().string();
|
||||||
SimpleLogger().Write() << "Restrictions file: " << restrictions_path.filename().string();
|
SimpleLogger().Write() << "Restrictions file: " << restrictions_path.filename().string();
|
||||||
@ -182,7 +188,8 @@ int main(int argc, char *argv[])
|
|||||||
SimpleLogger().Write() << "Threads: " << real_num_threads << " (requested "
|
SimpleLogger().Write() << "Threads: " << real_num_threads << " (requested "
|
||||||
<< requested_num_threads << ")";
|
<< requested_num_threads << ")";
|
||||||
|
|
||||||
omp_set_num_threads(real_num_threads);
|
tbb::task_scheduler_init init(real_num_threads);
|
||||||
|
|
||||||
LogPolicy::GetInstance().Unmute();
|
LogPolicy::GetInstance().Unmute();
|
||||||
boost::filesystem::ifstream restriction_stream(restrictions_path, std::ios::binary);
|
boost::filesystem::ifstream restriction_stream(restrictions_path, std::ios::binary);
|
||||||
TurnRestriction restriction;
|
TurnRestriction restriction;
|
||||||
|
Loading…
Reference in New Issue
Block a user