Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/clang_format.yml
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ jobs:
steps:
- uses: actions/checkout@v4
- name: Run clang-format style check
uses: jidicula/clang-format-action@v4.14.0
uses: jidicula/clang-format-action@v4.16.0
with:
clang-format-version: '18'
check-path: ${{ matrix.path }}
23 changes: 11 additions & 12 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -95,14 +95,14 @@ file(
"src/dsf/mdt/*.cpp")

include(FetchContent)
# Get rapidcsv
# Get csv-parser
FetchContent_Declare(
rapidcsv
GIT_REPOSITORY https://github.com/d99kris/rapidcsv
GIT_TAG v8.89)
FetchContent_GetProperties(rapidcsv)
if(NOT rapidcsv_POPULATED)
FetchContent_MakeAvailable(rapidcsv)
csv-parser
GIT_REPOSITORY https://github.com/vincentlaucsb/csv-parser
GIT_TAG 2.4.1)
FetchContent_GetProperties(csv-parser)
if(NOT csv-parser_POPULATED)
FetchContent_MakeAvailable(csv-parser)
endif()
# Get spdlog
set(SPDLOG_USE_STD_FORMAT
Expand Down Expand Up @@ -131,7 +131,7 @@ endif()
FetchContent_Declare(
simdjson
GIT_REPOSITORY https://github.com/simdjson/simdjson
GIT_TAG v4.2.3)
GIT_TAG v4.2.4)
FetchContent_GetProperties(simdjson)
if(NOT simdjson_POPULATED)
FetchContent_MakeAvailable(simdjson)
Expand Down Expand Up @@ -163,9 +163,9 @@ target_include_directories(
dsf PUBLIC $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/src>
$<INSTALL_INTERFACE:include>)

target_include_directories(dsf PRIVATE ${rapidcsv_SOURCE_DIR}/src)
target_include_directories(dsf PRIVATE ${csv-parser_SOURCE_DIR}/single_include)

# Link other libraries - no csv dependency needed now
# Link other libraries
target_link_libraries(dsf PUBLIC TBB::tbb SQLiteCpp PRIVATE simdjson::simdjson spdlog::spdlog)

# Install dsf library
Expand Down Expand Up @@ -243,8 +243,7 @@ if(DSF_TESTS)
target_include_directories(${testname}
PRIVATE ../src/ ../src/dsf/utility/TypeTraits/)
target_include_directories(
${testname} SYSTEM PRIVATE ${doctest_SOURCE_DIR}/doctest
${rapidcsv_SOURCE_DIR}/src)
${testname} SYSTEM PRIVATE ${doctest_SOURCE_DIR}/doctest)
target_compile_definitions(${testname} PRIVATE SPDLOG_USE_STD_FORMAT)
target_link_libraries(${testname} PRIVATE dsf TBB::tbb simdjson::simdjson spdlog::spdlog)
# Put test binaries under build/tests so they are easy to find. Use
Expand Down
6 changes: 3 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@
[![Standard](https://img.shields.io/badge/C%2B%2B-20/23-blue.svg)](https://en.wikipedia.org/wiki/C%2B%2B#Standardization)
[![TBB](https://img.shields.io/badge/TBB-2022.3.0-blue.svg)](https://github.com/oneapi-src/oneTBB)
[![SPDLOG](https://img.shields.io/badge/spdlog-1.17.0-blue.svg)](https://github.com/gabime/spdlog)
[![CSV](https://img.shields.io/badge/rapidcsv-8.89-blue.svg)](https://github.com/d99kris/rapidcsv)
[![JSON](https://img.shields.io/badge/simdjson-4.2.1-blue.svg)](https://github.com/simdjson/simdjson)
[![CSV](https://img.shields.io/badge/csv-parser-4.3.1-blue.svg)](https://github.com/vincentlaucsb/csv-parser)
[![JSON](https://img.shields.io/badge/simdjson-4.2.4-blue.svg)](https://github.com/simdjson/simdjson)
[![SQLite](https://img.shields.io/badge/SQLiteCpp-3.3.3-blue.svg)](https://github.com/SRombauts/SQLiteCpp)
[![codecov](https://codecov.io/gh/physycom/DynamicalSystemFramework/graph/badge.svg?token=JV53J6IUJ3)](https://codecov.io/gh/physycom/DynamicalSystemFramework)

Expand Down Expand Up @@ -36,7 +36,7 @@ print(dsf.__version__)
## Installation (from source)

### Requirements
The project requires `C++20` or greater, `cmake`, `tbb` `simdjson`, `spdlog`, `rapidcsv` and `SQLiteCpp`.
The project requires `C++20` or greater, `cmake`, `tbb` `simdjson`, `spdlog`, `csv-parser` and `SQLiteCpp`.
To install requirements on Ubuntu:
```shell
sudo apt install cmake libtbb-dev
Expand Down
18 changes: 9 additions & 9 deletions profiling/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -18,28 +18,28 @@ string(APPEND CMAKE_CXX_FLAGS "-Wall -Wextra -Os")
set(EXECUTABLE_OUTPUT_PATH ../)

include(FetchContent)
# Get rapidcsv
# Get csv-parser
FetchContent_Declare(
rapidcsv
GIT_REPOSITORY https://github.com/d99kris/rapidcsv
GIT_TAG v8.89)
FetchContent_GetProperties(rapidcsv)
if(NOT rapidcsv_POPULATED)
FetchContent_MakeAvailable(rapidcsv)
csv-parser
GIT_REPOSITORY https://github.com/vincentlaucsb/csv-parser
GIT_TAG 2.4.1)
FetchContent_GetProperties(csv-parser)
if(NOT csv-parser_POPULATED)
FetchContent_MakeAvailable(csv-parser)
endif()

file(GLOB SOURCES "../src/dsf/base/*.cpp" "../src/dsf/mobility/*.cpp"
"../src/dsf/utility/*.cpp" "../src/dsf/geometry/*.cpp")

# Define the executable
add_executable(prof.out main.cpp ${SOURCES})
target_include_directories(prof.out PRIVATE ../src/ ${rapidcsv_SOURCE_DIR}/src)
target_include_directories(prof.out PRIVATE ../src/ ${csv-parser_SOURCE_DIR}/single_include)
target_link_libraries(prof.out PRIVATE TBB::tbb fmt::fmt spdlog::spdlog
simdjson::simdjson)
target_compile_options(prof.out PRIVATE -pg)
target_link_options(prof.out PRIVATE -pg)
add_executable(mem.out main.cpp ${SOURCES})
target_include_directories(mem.out PRIVATE ../src/ ${rapidcsv_SOURCE_DIR}/src)
target_include_directories(mem.out PRIVATE ../src/ ${csv-parser_SOURCE_DIR}/single_include)
target_link_libraries(mem.out PRIVATE TBB::tbb fmt::fmt spdlog::spdlog
simdjson::simdjson)
add_executable(parse_massif.out parse_massif.cpp)
2 changes: 1 addition & 1 deletion src/dsf/dsf.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@

static constexpr uint8_t DSF_VERSION_MAJOR = 5;
static constexpr uint8_t DSF_VERSION_MINOR = 0;
static constexpr uint8_t DSF_VERSION_PATCH = 1;
static constexpr uint8_t DSF_VERSION_PATCH = 2;

static auto const DSF_VERSION =
std::format("{}.{}.{}", DSF_VERSION_MAJOR, DSF_VERSION_MINOR, DSF_VERSION_PATCH);
Expand Down
27 changes: 20 additions & 7 deletions src/dsf/mdt/TrajectoryCollection.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
#include <format>
#include <fstream>

#include <rapidcsv.h>
#include <csv.hpp>
#include <spdlog/spdlog.h>

#include <tbb/parallel_for_each.h>
Expand Down Expand Up @@ -58,8 +58,9 @@ namespace dsf::mdt {
std::unordered_map<std::string, std::string> const& column_mapping,
char const sep,
std::array<double, 4> const& bbox) {
rapidcsv::Document doc(
fileName, rapidcsv::LabelParams(0, -1), rapidcsv::SeparatorParams(sep));
csv::CSVFormat csvFormat;
csvFormat.delimiter(sep);
csv::CSVReader reader(fileName, csvFormat);

std::unordered_map<std::string, std::string> column_names = {
{"uid", "uid"}, {"timestamp", "timestamp"}, {"lat", "lat"}, {"lon", "lon"}};
Expand All @@ -71,14 +72,26 @@ namespace dsf::mdt {
column_names[key] = value;
}

std::vector<Id> uids;
std::vector<std::time_t> timestamps;
std::vector<double> lats;
std::vector<double> lons;
for (auto& row : reader) {
uids.push_back(static_cast<Id>(row[column_names.at("uid")].get<long long>()));
timestamps.push_back(
static_cast<std::time_t>(row[column_names.at("timestamp")].get<long long>()));
lats.push_back(row[column_names.at("lat")].get<double>());
lons.push_back(row[column_names.at("lon")].get<double>());
}

std::unordered_map<
std::string,
std::variant<std::vector<Id>, std::vector<std::time_t>, std::vector<double>>>
dataframe;
dataframe["uid"] = doc.GetColumn<Id>(column_names.at("uid"));
dataframe["timestamp"] = doc.GetColumn<std::time_t>(column_names.at("timestamp"));
dataframe["lat"] = doc.GetColumn<double>(column_names.at("lat"));
dataframe["lon"] = doc.GetColumn<double>(column_names.at("lon"));
dataframe["uid"] = std::move(uids);
dataframe["timestamp"] = std::move(timestamps);
dataframe["lat"] = std::move(lats);
dataframe["lon"] = std::move(lons);
*this = TrajectoryCollection(std::move(dataframe), bbox);
}

Expand Down
56 changes: 29 additions & 27 deletions src/dsf/mobility/RoadNetwork.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
#include <algorithm>
#include <ranges>

#include <rapidcsv.h>
#include <csv.hpp>
#include <simdjson.h>
#include <tbb/parallel_for_each.h>

Expand All @@ -20,10 +20,13 @@ namespace dsf::mobility {
}
}

void RoadNetwork::m_csvEdgesImporter(std::ifstream& file, const char separator) {
rapidcsv::Document csvReader(
file, rapidcsv::LabelParams(0, -1), rapidcsv::SeparatorParams(separator));
auto const& colNames = csvReader.GetColumnNames();
void RoadNetwork::m_csvEdgesImporter(const std::string& fileName,
const char separator) {
csv::CSVFormat format;
format.delimiter(separator);
csv::CSVReader reader(fileName, format);

auto const& colNames = reader.get_col_names();
bool const bHasGeometry =
(std::find(colNames.begin(), colNames.end(), "geometry") != colNames.end());
if (!bHasGeometry) {
Expand All @@ -37,29 +40,27 @@ namespace dsf::mobility {
(std::find(colNames.begin(), colNames.end(), "coilcode") != colNames.end());
bool const bHasCustomWeight =
(std::find(colNames.begin(), colNames.end(), "customWeight") != colNames.end());
// bool const bHasForbiddenTurns = (std::find(colNames.begin(), colNames.end(), "forbiddenTurns") != colNames.end());

auto const rowCount = csvReader.GetRowCount();
for (std::size_t i = 0; i < rowCount; ++i) {
auto const sourceId = csvReader.GetCell<Id>("source", i);
auto const targetId = csvReader.GetCell<Id>("target", i);
for (auto& row : reader) {
auto const sourceId = static_cast<Id>(row["source"].get<long long>());
auto const targetId = static_cast<Id>(row["target"].get<long long>());
if (sourceId == targetId) {
spdlog::warn("Skipping self-loop edge {}->{}", sourceId, targetId);
continue;
}
auto const streetId = csvReader.GetCell<Id>("id", i);
auto const dLength = csvReader.GetCell<double>("length", i);
auto const name = csvReader.GetCell<std::string>("name", i);
auto strType = csvReader.GetCell<std::string>("type", i);
auto const streetId = static_cast<Id>(row["id"].get<long long>());
auto const dLength = row["length"].get<double>();
auto const name = row["name"].get<std::string>();
auto strType = row["type"].get<std::string>();
geometry::PolyLine polyline;
if (bHasGeometry) {
polyline = geometry::PolyLine(csvReader.GetCell<std::string>("geometry", i));
polyline = geometry::PolyLine(row["geometry"].get<std::string>());
}

auto iLanes = 1;
if (bHasLanes) {
try {
iLanes = csvReader.GetCell<int>("nlanes", i);
iLanes = row["nlanes"].get<int>();
} catch (...) {
spdlog::warn("Invalid number of lanes for edge {}->{}. Defaulting to 1 lane.",
sourceId,
Expand All @@ -70,7 +71,7 @@ namespace dsf::mobility {

double dMaxSpeed = 30.; // Default to 30 km/h
try {
dMaxSpeed = csvReader.GetCell<double>("maxspeed", i);
dMaxSpeed = row["maxspeed"].get<double>();
} catch (...) {
spdlog::warn("Invalid maxspeed provided for edge {}->{}. Defaulting to 30 km/h.",
sourceId,
Expand Down Expand Up @@ -105,7 +106,7 @@ namespace dsf::mobility {
}

if (bHasCoilcode) {
auto strCoilCode = csvReader.GetCell<std::string>("coilcode", i);
auto strCoilCode = row["coilcode"].get<std::string>();
// Make this lowercase
std::transform(strCoilCode.begin(),
strCoilCode.end(),
Expand All @@ -118,7 +119,7 @@ namespace dsf::mobility {
}
if (bHasCustomWeight) {
try {
edge(streetId)->setWeight(csvReader.GetCell<double>("customWeight", i));
edge(streetId)->setWeight(row["customWeight"].get<double>());
} catch (...) {
spdlog::warn("Invalid custom weight for {}", *edge(streetId));
}
Expand Down Expand Up @@ -146,19 +147,20 @@ namespace dsf::mobility {
// }
// }
}
void RoadNetwork::m_csvNodePropertiesImporter(std::ifstream& file,
void RoadNetwork::m_csvNodePropertiesImporter(const std::string& fileName,
const char separator) {
rapidcsv::Document csvReader(
file, rapidcsv::LabelParams(0, -1), rapidcsv::SeparatorParams(separator));
auto const rowCount = csvReader.GetRowCount();
for (std::size_t i = 0; i < rowCount; ++i) {
auto const nodeId = csvReader.GetCell<Id>("id", i);
csv::CSVFormat format;
format.delimiter(separator);
csv::CSVReader reader(fileName, format);

for (auto& row : reader) {
auto const nodeId = static_cast<Id>(row["id"].get<long long>());
if (m_nodes.find(nodeId) == m_nodes.end()) {
spdlog::warn("Node {} not found in the network. Skipping properties import.",
nodeId);
continue;
}
auto strType = csvReader.GetCell<std::string>("type", i);
auto strType = row["type"].get<std::string>();
std::transform(
strType.begin(), strType.end(), strType.begin(), [](unsigned char c) {
return std::tolower(c);
Expand All @@ -168,7 +170,7 @@ namespace dsf::mobility {
} else if (strType.find("roundabout") != std::string::npos) {
makeRoundabout(nodeId);
}
auto const& strGeometry = csvReader.GetCell<std::string>("geometry", i);
auto const& strGeometry = row["geometry"].get<std::string>();
if (!strGeometry.empty()) {
auto const point = geometry::Point(strGeometry);
auto const& pNode{node(nodeId)};
Expand Down
9 changes: 5 additions & 4 deletions src/dsf/mobility/RoadNetwork.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -55,8 +55,9 @@ namespace dsf::mobility {

void m_updateMaxAgentCapacity();

void m_csvEdgesImporter(std::ifstream& file, const char separator = ';');
void m_csvNodePropertiesImporter(std::ifstream& file, const char separator = ';');
void m_csvEdgesImporter(const std::string& fileName, const char separator = ';');
void m_csvNodePropertiesImporter(const std::string& fileName,
const char separator = ';');

void m_jsonEdgesImporter(std::ifstream& file);

Expand Down Expand Up @@ -285,7 +286,7 @@ namespace dsf::mobility {
switch (fileExtMap.at(fileExt)) {
case FileExt::CSV:
spdlog::debug("Importing nodes from CSV file: {}", fileName);
this->m_csvEdgesImporter(file, std::forward<TArgs>(args)...);
this->m_csvEdgesImporter(fileName, std::forward<TArgs>(args)...);
break;
case FileExt::GEOJSON:
case FileExt::JSON:
Expand Down Expand Up @@ -318,7 +319,7 @@ namespace dsf::mobility {
switch (fileExtMap.at(fileExt)) {
case FileExt::CSV:
spdlog::debug("Importing node properties from CSV file: {}", fileName);
this->m_csvNodePropertiesImporter(file, std::forward<TArgs>(args)...);
this->m_csvNodePropertiesImporter(fileName, std::forward<TArgs>(args)...);
break;
case FileExt::JSON:
case FileExt::GEOJSON:
Expand Down
Loading