Skip to content

Commit

Permalink
Merge pull request #36 from naviqore/feature/NAV-177-implement-gtfsRa…
Browse files Browse the repository at this point in the history
…ptorConfig-layer

Feature/nav 177 implement gtfs raptor config layer
  • Loading branch information
munterfi authored Sep 22, 2024
2 parents b8e959a + 3fa9b88 commit 292e5eb
Show file tree
Hide file tree
Showing 128 changed files with 793,804 additions and 1,763 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -47,3 +47,4 @@
/Folder.DotSettings.user
/packages/*
/vcpkg_installed/*
/src/gtfsRaptorConfig/src/agencySubsetWriter/__pycache__
16 changes: 12 additions & 4 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,11 @@ if (CMAKE_CXX_STANDARD LESS 23)
endif ()

if (MSVC)
add_compile_options(/W3 /WX /wd4251 /experimental:module /std:c++latest) #/W4 /WX https://github.com/open-simulation-platform/libcosim/issues/307
if (CMAKE_BUILD_TYPE STREQUAL "Debug")
add_compile_options(/W3 /WX /wd4251 /experimental:module /std:c++latest /RTC1)
else()
add_compile_options(/W3 /WX /wd4251 /experimental:module /std:c++latest /O2)
endif()
elseif (CMAKE_CXX_COMPILER_ID STREQUAL "GNU" OR CMAKE_CXX_COMPILER_ID STREQUAL "Clang")
add_compile_options(-Wall -Wextra -pedantic -std=c++23) # -Werror => this is too strict for now - causes break when building CSV library
elseif (CMAKE_CXX_COMPILER_ID STREQUAL "AppleClang")
Expand Down Expand Up @@ -42,17 +46,21 @@ set(CMAKE_RUNTIME_OUTPUT_DIRECTORY_RELEASE ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/rel
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY_RELEASE ${CMAKE_LIBRARY_OUTPUT_DIRECTORY}/release)
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY_RELEASE ${CMAKE_LIBRARY_OUTPUT_DIRECTORY}/release)

# SOURCE
add_subdirectory(src/interfaces)
add_subdirectory(src/logging)
add_subdirectory(src/geometry)
add_subdirectory(src/schedule)
add_subdirectory(test/test_schedule)
add_subdirectory(src/schedule/benchmarks)
add_subdirectory(src/raptor)
add_subdirectory(src/gtfsRaptorConfig)
add_subdirectory(src/raptor)
# TESTS
add_subdirectory(test/test_raptor)
add_subdirectory(test/test_geometry)
add_subdirectory(test/test_schedule)
add_subdirectory(test/test_gtfsRaptorConfig)
# BECHMARKS
add_subdirectory(benchmark/benchmark_schedule)
add_subdirectory(benchmark/benchmark_gtfsRaptor)

include(CTest)
enable_testing()
27 changes: 23 additions & 4 deletions CMakePresets.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
{
"version": 3,
"version": 6,
"cmakeMinimumRequired": {
"major": 3,
"minor": 25,
"patch": 1
},
"configurePresets": [
{
"name": "windows-base",
Expand Down Expand Up @@ -28,14 +33,28 @@
"value": "x64",
"strategy": "external"
},
"cacheVariables": { "CMAKE_BUILD_TYPE": "Debug" }
"cacheVariables": {
"CMAKE_BUILD_TYPE": "Debug",
"CMAKE_CXX_FLAGS_DEBUG": "-DLOGGER"
}
},
{
"name": "x64-release",
"displayName": "x64 Release",
"description": "Target Windows (64-bit) with the Visual Studio development environment. (Release)",
"inherits": "x64-debug",
"cacheVariables": {
"CMAKE_BUILD_TYPE": "Release"
}
},
{
"name": "x64-relwithdebinfo",
"displayName": "x64 RelWithDebInfo",
"description": "Target Windows (64-bit) with the Visual Studio development environment. (RelWithDebInfo)",
"inherits": "x64-debug",
"cacheVariables": { "CMAKE_BUILD_TYPE": "Release" }
"cacheVariables": {
"CMAKE_BUILD_TYPE": "RelWithDebInfo"
}
}
]
}
}
47 changes: 47 additions & 0 deletions benchmark/benchmark_gtfsRaptor/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
project(benchmark_gtfsRaptor)

# file(GLOB CHAPTER_SRC_FILES "${CMAKE_CURRENT_SOURCE_DIR}/*.cpp" "${CMAKE_CURRENT_SOURCE_DIR}/*.h")

add_executable(${PROJECT_NAME}
gtfsRaptor_benchmark.cpp
)

add_executable(SimpleBenchmark
SimpleRaptorBenchmark.cpp
)

find_package(benchmark CONFIG REQUIRED)

set(EXECUTABLES
${PROJECT_NAME}
SimpleBenchmark
)

foreach(EXECUTABLE IN LISTS EXECUTABLES)
target_include_directories(${EXECUTABLE} PUBLIC
$<BUILD_INTERFACE:${CMAKE_CURRENT_BINARY_DIR}>
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}>
)

target_link_libraries(${EXECUTABLE} PRIVATE
benchmark::benchmark
benchmark::benchmark_main
raptor
schedule
logging
gtfsRaptorConfig
)

target_include_directories(${EXECUTABLE} PRIVATE ${CMAKE_SOURCE_DIR}/src/logging/include)
target_include_directories(${EXECUTABLE} PRIVATE ${CMAKE_SOURCE_DIR}/src/raptor/include)
target_include_directories(${EXECUTABLE} PRIVATE ${CMAKE_SOURCE_DIR}/src/raptor/include/config)
target_include_directories(${EXECUTABLE} PRIVATE ${CMAKE_SOURCE_DIR}/src/schedule/include)
target_include_directories(${EXECUTABLE} PRIVATE ${CMAKE_SOURCE_DIR}/src/gtfsRaptorConfig/include)
endforeach()

add_definitions(-DTEST_DATA_DIR="C:/Users/MichaelBrunner/Downloads/switzerland/")





104 changes: 104 additions & 0 deletions benchmark/benchmark_gtfsRaptor/SimpleRaptorBenchmark.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
//
// Created by MichaelBrunner on 21/09/2024.
//

#include "DataReader.h"
#include "GtfsData.h"
#include "GtfsReader.h"
#include "GtfsReaderStrategyFactory.h"
#include "GtfsToRaptorConverter.h"
#include "LocalDateTime.h"
#include <DataContainer.h>
#include <chrono>
#include <iostream>
#include <memory>
#include <string>
#include <vector>

class SimpleRaptorBenchmark {
protected:
static std::unique_ptr<schedule::DataReader<schedule::DataContainer<schedule::gtfs::GtfsData>>> reader;
static std::unique_ptr<schedule::gtfs::IGtfsReaderStrategyFactory> readerFactory;
static std::unique_ptr<raptor::RaptorRouter> raptorRouter;
static schedule::gtfs::GtfsData data;
static bool initialized;
static raptor::utils::LocalDateTime time;
static raptor::config::QueryConfig queryConfig;

public:
static void setUp()
{
if (!initialized) {
const std::string basePath = TEST_DATA_DIR;
readerFactory = schedule::gtfs::createGtfsReaderStrategyFactory(schedule::gtfs::ReaderType::CSV_PARALLEL, basePath);

const auto calendarStrategy = readerFactory->getStrategy(GtfsStrategyType::CALENDAR);
const auto calendarDatesStrategy = readerFactory->getStrategy(GtfsStrategyType::CALENDAR_DATE);
const auto routesStrategy = readerFactory->getStrategy(GtfsStrategyType::ROUTE);
const auto stopStrategy = readerFactory->getStrategy(GtfsStrategyType::STOP);
const auto stopTimeStrategy = readerFactory->getStrategy(GtfsStrategyType::STOP_TIME);
const auto transferStrategy = readerFactory->getStrategy(GtfsStrategyType::TRANSFER);
const auto tripStrategy = readerFactory->getStrategy(GtfsStrategyType::TRIP);

std::vector strategies = {calendarStrategy, calendarDatesStrategy, routesStrategy, stopStrategy, stopTimeStrategy, transferStrategy, tripStrategy};

reader = std::make_unique<schedule::gtfs::GtfsReader>(std::move(strategies));
reader->readData();
data = reader->getData().get();

const auto dateTime = raptor::utils::LocalDateTime{std::chrono::year{2024}, std::chrono::month{4}, std::chrono::day{26}, std::chrono::hours{8}, std::chrono::minutes{0}, std::chrono::seconds{0}};

auto timetableManager = std::make_unique<converter::TimetableManager>(std::move(data), dateTime);
auto mapper = converter::GtfsToRaptorConverter(120, std::move(timetableManager));
const auto raptor = mapper.convert();
raptorRouter = std::make_unique<raptor::RaptorRouter>(std::move(*raptor));
initialized = true;
}
}

static long long routeEarliestArrival(const std::string& fromStopId, const std::string& toStopId)
{
const auto startTime = std::chrono::high_resolution_clock::now();
std::ignore = raptorRouter->routeEarliestArrival(
{{fromStopId, static_cast<raptor::types::raptorInt>(time.secondsOfDay())}},
{{toStopId, static_cast<raptor::types::raptorInt>(0)}},
queryConfig);
const auto endTime = std::chrono::high_resolution_clock::now();
return std::chrono::duration_cast<std::chrono::milliseconds>(endTime - startTime).count();
}

static void benchmarkRoute(const std::string& fromStopId, const std::string& toStopId, const int iterations)
{
long long totalTime = 0;
for (int i = 0; i < iterations; ++i) {
totalTime += routeEarliestArrival(fromStopId, toStopId);
}
const long long averageTime = totalTime / iterations;
std::cout << "Average time for routing from " << fromStopId << " to " << toStopId << " over " << iterations << " iterations: " << averageTime << " ms\n";
}
};

bool SimpleRaptorBenchmark::initialized = false;
raptor::utils::LocalDateTime SimpleRaptorBenchmark::time{raptor::utils::LocalDateTime{std::chrono::year{2024}, std::chrono::month{1}, std::chrono::day{1}, std::chrono::hours{8}, std::chrono::minutes{0}, std::chrono::seconds{0}}};
std::unique_ptr<schedule::DataReader<schedule::DataContainer<schedule::gtfs::GtfsData>>> SimpleRaptorBenchmark::reader = nullptr;
std::unique_ptr<schedule::gtfs::IGtfsReaderStrategyFactory> SimpleRaptorBenchmark::readerFactory = nullptr;
std::unique_ptr<raptor::RaptorRouter> SimpleRaptorBenchmark::raptorRouter = nullptr;
schedule::gtfs::GtfsData SimpleRaptorBenchmark::data = {};
raptor::config::QueryConfig SimpleRaptorBenchmark::queryConfig = {};

int main(int argc, char** argv)
{
SimpleRaptorBenchmark::setUp();
// "8589640" "St. Gallen, Vonwil" to "8579885" "Mels, Bahnhof"
SimpleRaptorBenchmark::benchmarkRoute("8589640", "8579885", 100);
// "8574563","Maienfeld, Bahnhof" to "8587276" "Biel/Bienne, Taubenloch"
SimpleRaptorBenchmark::benchmarkRoute("8574563", "8587276", 100);
// "8588524","Sion, Hôpital Sud" to "8508896","Stans, Bahnhof"
SimpleRaptorBenchmark::benchmarkRoute("8588524", "8508896", 100);
// "8510709","Lugano, Via Domenico Fontana" to "8579255","Lausanne, Pont-de-Chailly"
SimpleRaptorBenchmark::benchmarkRoute("8510709", "8579255", 100);
// "8574848","Davos Dorf, Bahnhof" to "8576079","Rapperswil SG, Sonnenhof"
SimpleRaptorBenchmark::benchmarkRoute("8574848", "8576079", 100);

return 0;
}
108 changes: 108 additions & 0 deletions benchmark/benchmark_gtfsRaptor/gtfsRaptor_benchmark.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
//
// Created by MichaelBrunner on 09/09/2024.
//

#include <benchmark/benchmark.h>
#include "DataReader.h"
#include "GtfsData.h"
#include "GtfsReader.h"
#include "GtfsReaderStrategyFactory.h"
#include "GtfsToRaptorConverter.h"
#include "LocalDateTime.h"
#include "LoggerFactory.h"
#include <DataContainer.h>
#include <numeric>

class GtfsRaptorFixture : public benchmark::Fixture {
protected:
static std::unique_ptr<schedule::DataReader<schedule::DataContainer<schedule::gtfs::GtfsData>>> reader;
static std::unique_ptr<schedule::gtfs::IGtfsReaderStrategyFactory> readerFactory;
static std::unique_ptr<raptor::RaptorRouter> raptorRouter;
static schedule::gtfs::GtfsData data;
static bool initialized;
static raptor::utils::LocalDateTime time;
static raptor::config::QueryConfig queryConfig;

public:
void SetUp(::benchmark::State& state) override
{
if (!initialized) {
const std::string basePath = TEST_DATA_DIR;
readerFactory = schedule::gtfs::createGtfsReaderStrategyFactory(schedule::gtfs::ReaderType::CSV_PARALLEL, basePath);

const auto calendarStrategy = readerFactory->getStrategy(GtfsStrategyType::CALENDAR);
const auto calendarDatesStrategy = readerFactory->getStrategy(GtfsStrategyType::CALENDAR_DATE);
const auto routesStrategy = readerFactory->getStrategy(GtfsStrategyType::ROUTE);
const auto stopStrategy = readerFactory->getStrategy(GtfsStrategyType::STOP);
const auto stopTimeStrategy = readerFactory->getStrategy(GtfsStrategyType::STOP_TIME);
const auto transferStrategy = readerFactory->getStrategy(GtfsStrategyType::TRANSFER);
const auto tripStrategy = readerFactory->getStrategy(GtfsStrategyType::TRIP);

std::vector strategies = {calendarStrategy, calendarDatesStrategy, routesStrategy, stopStrategy, stopTimeStrategy, transferStrategy, tripStrategy};

reader = std::make_unique<schedule::gtfs::GtfsReader>(std::move(strategies));
reader->readData();
data = reader->getData().get();

const auto dateTime = raptor::utils::LocalDateTime{std::chrono::year{2024}, std::chrono::month{4}, std::chrono::day{26}, std::chrono::hours{8}, std::chrono::minutes{0}, std::chrono::seconds{0}};

auto timetableManager = std::make_unique<converter::TimetableManager>(std::move(data), dateTime);
auto mapper = converter::GtfsToRaptorConverter(120, std::move(timetableManager));
const auto raptor = mapper.convert();
raptorRouter = std::make_unique<raptor::RaptorRouter>(std::move(*raptor));
initialized = true;
}
}

void TearDown(::benchmark::State& state) override
{
reader.reset(nullptr);
}
};

bool GtfsRaptorFixture::initialized = false;
raptor::utils::LocalDateTime GtfsRaptorFixture::time{raptor::utils::LocalDateTime{std::chrono::year{2024}, std::chrono::month{1}, std::chrono::day{1}, std::chrono::hours{8}, std::chrono::minutes{0}, std::chrono::seconds{0}}};
std::unique_ptr<schedule::DataReader<schedule::DataContainer<schedule::gtfs::GtfsData>>> GtfsRaptorFixture::reader = nullptr;
std::unique_ptr<schedule::gtfs::IGtfsReaderStrategyFactory> GtfsRaptorFixture::readerFactory = nullptr;
std::unique_ptr<raptor::RaptorRouter> GtfsRaptorFixture::raptorRouter = nullptr;
schedule::gtfs::GtfsData GtfsRaptorFixture::data = {};
raptor::config::QueryConfig GtfsRaptorFixture::queryConfig = {};

void BenchmarkRoute(benchmark::State& state, const std::string& fromStop, const std::string& toStop, const long long departureTime, const long long arrivalTime, const raptor::RaptorRouter& raptorRouter, const raptor::config::QueryConfig& queryConfig)
{
state.SetLabel("From: " + fromStop + " To: " + toStop);

for (auto _ : state) {
std::ignore = raptorRouter.routeEarliestArrival(
{{fromStop, static_cast<raptor::types::raptorInt>(departureTime)}},
{{toStop, static_cast<raptor::types::raptorInt>(arrivalTime)}},
queryConfig);
}
}

// Benchmark function for route vonwilSG -> mels
BENCHMARK_F(GtfsRaptorFixture, BM_route_vonwilSG_mels)
(benchmark::State& state)
{
// Route 1: vonwilSG -> mels
BenchmarkRoute(state, "8589640", "8579885", time.secondsOfDay(), time.secondsOfDay() + 60 * 60 * 2, *raptorRouter, queryConfig);
}

BENCHMARK_F(GtfsRaptorFixture, BM_route_AbtwilDorf_Westcenter)
(benchmark::State& state)
{
BenchmarkRoute(state, "8588889", "8589644", time.secondsOfDay(), time.secondsOfDay() + 60 * 60 * 2, *raptorRouter, queryConfig);
}

BENCHMARK_REGISTER_F(GtfsRaptorFixture, BM_route_vonwilSG_mels)->Iterations(50);
BENCHMARK_REGISTER_F(GtfsRaptorFixture, BM_route_AbtwilDorf_Westcenter)->Iterations(50);

int main(int argc, char** argv)
{
::benchmark::Initialize(&argc, argv);
::benchmark::RunSpecifiedBenchmarks();

::benchmark::Shutdown();

return 0;
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
project(benchmarks)
project(benchmark_schedule)

file(GLOB CHAPTER_SRC_FILES "${CMAKE_CURRENT_SOURCE_DIR}/*.cpp" "${CMAKE_CURRENT_SOURCE_DIR}/*.h")

Expand All @@ -13,9 +13,10 @@ target_include_directories(${PROJECT_NAME} PUBLIC
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}>
)

target_include_directories(${PROJECT_NAME} PRIVATE ${CMAKE_BINARY_DIR})
target_include_directories(${PROJECT_NAME} PRIVATE ${CMAKE_SOURCE_DIR}/gtfs/src)
target_include_directories(${PROJECT_NAME} PRIVATE ${CMAKE_SOURCE_DIR}/geometry/include)

target_include_directories(${PROJECT_NAME} PRIVATE ${CMAKE_SOURCE_DIR}/src/schedule/include)
target_include_directories(${PROJECT_NAME} PRIVATE ${CMAKE_SOURCE_DIR}/src/schedule/include/model)
target_include_directories(${PROJECT_NAME} PRIVATE ${CMAKE_SOURCE_DIR}/src/geometry/include)

target_link_libraries(${PROJECT_NAME} PRIVATE
benchmark::benchmark
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@
#include "GtfsReaderStrategyFactory.h"

static void BM_pointer(benchmark::State& state) {
// auto ptr = std::make_shared<int>(12);
auto vec = std::vector<int*>();

vec.resize(10'000, new int(12));
Expand Down Expand Up @@ -51,7 +50,7 @@ class GtfsReaderFixture : public benchmark::Fixture {
public:
void SetUp(::benchmark::State& state) override {
readerFactory = schedule::gtfs::createGtfsReaderStrategyFactory(
schedule::gtfs::ReaderType::CSV_PARALLEL, TEST_DATA_DIR);
schedule::gtfs::ReaderType::CSV_PARALLEL, TEST_DATA_DIR);
}

void TearDown(::benchmark::State& state) override {}
Expand Down
Loading

0 comments on commit 292e5eb

Please sign in to comment.