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
11 changes: 6 additions & 5 deletions .github/workflows/coverage.yml
Original file line number Diff line number Diff line change
Expand Up @@ -19,13 +19,14 @@ jobs:
# https://github.blog/changelog/2021-02-08-github-actions-skip-pull-request-and-push-workflows-with-skip-ci/
if: "!contains(github.event.commits[0].message, '[skip cov]')"
runs-on: ubuntu-latest
container: ubuntu:24.04

# Steps represent a sequence of tasks that will be executed as part of the job
steps:
# Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it
- uses: actions/checkout@v4

- run: sudo apt-get update && sudo apt-get install -y gcc-11 g++-11 lcov cmake git
- run: apt-get update && apt-get install -y gcc-13 g++-13 lcov cmake git
shell: bash

- name: Configure cmake
Expand All @@ -34,8 +35,8 @@ jobs:
run: cmake -B ${{github.workspace}}/build -D ENABLE_COVERAGE=ON
shell: bash
env:
CC: gcc-11
CXX: g++-11
CC: gcc-13
CXX: g++-13

- name: Build all applications
run: cmake --build ${{github.workspace}}/build
Expand All @@ -48,12 +49,12 @@ jobs:
run: |
cd ${{github.workspace}}/build
lcov --no-external --capture --directory . --output-file coverage.info
lcov --remove coverage.info '/usr/include/*' '*/tests/*' --output-file coverage.info
lcov --ignore-errors unused --remove coverage.info '/usr/include/*' '*/tests/*' --output-file coverage.info
geninfo --rc geninfo_unexecuted_blocks=1 --ignore-errors gcov --output-filename coverage.info .
genhtml coverage.info --output-directory out

- name: Upload coverage reports to Codecov
uses: codecov/codecov-action@v4
uses: codecov/codecov-action@v5
with:
files: ${{github.workspace}}/build/out/index.html
token: ${{ secrets.CODECOV_TOKEN }}
11 changes: 7 additions & 4 deletions .github/workflows/macos.yml
Original file line number Diff line number Diff line change
Expand Up @@ -25,17 +25,20 @@ jobs:
# Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it
- uses: actions/checkout@v4

- name: Install GCC-12
run: brew install gcc@12
- name: Install GCC-13
run: brew install gcc@13

- name: Configure cmake
# Configure CMake in a 'build' subdirectory. `CMAKE_BUILD_TYPE` is only required if you are using a single-configuration generator such as make.
# See https://cmake.org/cmake/help/latest/variable/CMAKE_BUILD_TYPE.html?highlight=cmake_build_type
run: cmake -B ${{github.workspace}}/build -D CMAKE_BUILD_TYPE=Release
shell: bash
env:
CC: gcc-12
CXX: g++-12
CC: gcc-13
CXX: g++-13

- name: Build all applications
run: cmake --build ${{github.workspace}}/build

- name: Run tests
run: ctest --test-dir ${{github.workspace}}/build/tests
3 changes: 3 additions & 0 deletions .github/workflows/windows.yml
Original file line number Diff line number Diff line change
Expand Up @@ -32,3 +32,6 @@ jobs:

- name: Build all applications
run: cmake --build ${{github.workspace}}/build

- name: Run tests
run: ctest -C Debug --test-dir ${{github.workspace}}/build/tests
11 changes: 1 addition & 10 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -78,20 +78,11 @@ if (ENABLE_PCH)
endif()


# Add libraries. Order is important based on dependencies.
include(${PROJECT_SOURCE_DIR}/cmake/FetchFMT.cmake)
# Add thirdparty libraries
include(${PROJECT_SOURCE_DIR}/cmake/FetchCatch.cmake)
include(${PROJECT_SOURCE_DIR}/cmake/FetchDocopt.cmake)
include(${PROJECT_SOURCE_DIR}/cmake/FetchCSVParser.cmake)
#include(${PROJECT_SOURCE_DIR}/cmake/FetchRange.cmake)
#include(${PROJECT_SOURCE_DIR}/cmake/FetchSPDLog.cmake)
#include(${PROJECT_SOURCE_DIR}/cmake/FetchBoost.cmake)


add_library(graph INTERFACE)
target_include_directories(graph INTERFACE "${CMAKE_CURRENT_SOURCE_DIR}/include/")
target_link_libraries(graph INTERFACE fmt::fmt)
#target_link_libraries(graph INTERFACE Boost::cobalt) # for coroutine library

if(ENABLE_TESTING)
enable_testing()
Expand Down
6 changes: 3 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -43,15 +43,15 @@ Other releases or compilers may or may not work.

### Prerequesites
- C\+\+20 compliant compiler that fully supports concepts and ranges. (C\+\+23 is required for building the benchmarks.)
- CMake 26 or later (for CMake Presets)
- CMake 3.20 or later (for CMake Presets)

### Quick Start Guide (Linux, WSL, MacOS)
```bash
git clone https://github.com/stdgraph/graph-v2.git
cd graph-v2
mkdir build && cd build
cmake ..
make -j8
make
```

### Editor/IDE Configuration (Windows)
Expand Down Expand Up @@ -123,5 +123,5 @@ The following papers make up the current proposal for the Graph Library.
Committee ([WG21](https://isocpp.org/std/the-committee)).
- Bob Steagal for his [gcc-builder & clang-builder scripts](https://github.com/BobSteagall)
- Jason Turner for his [cpp_starter_project](https://github.com/lefticus/cpp_starter_project)
- Vincent La for his [cvs-parser](https://github.com/vincentlaucsb/csv-parser)
- Vincent La for his [cvs-parser](https://github.com/vincentlaucsb/csv-parser) (copied into tests).
- The ISO C++ Standards Committee (WG21) for [C++](http://eel.is/c++draft/)
2 changes: 1 addition & 1 deletion cmake/FetchCatch.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ message(STATUS "Cloning External Project: catch2")
FetchContent_Declare(
catch2
GIT_REPOSITORY https://github.com/catchorg/Catch2.git
GIT_TAG v3.5.2
GIT_TAG v3.7.1
)
FetchContent_MakeAvailable(catch2)
set(CATCH2_SOURCE_DIR "${catch2_SOURCE_DIR}")
Expand Down
2 changes: 1 addition & 1 deletion example/CppCon2021/examples/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ add_executable(bacon "bacon.cpp")
target_link_libraries(bacon PRIVATE cppcon21_headers project_warnings project_options graph)

add_executable(ospf "ospf.cpp")
target_link_libraries(ospf PRIVATE cppcon21_headers project_warnings project_options graph fmt::fmt)
target_link_libraries(ospf PRIVATE cppcon21_headers project_warnings project_options graph)

add_executable(imdb "imdb.cpp")
target_link_libraries(imdb PRIVATE cppcon21_headers project_warnings project_options graph)
133 changes: 131 additions & 2 deletions example/CppCon2021/examples/graphs.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@

#include <list>
#include <vector>
#include <iostream>
#include <iomanip>

//#include "bfs_edge_range.hpp"
#include "graph/graph.hpp"
Expand All @@ -30,8 +32,6 @@
#include "spice-graph.hpp"
#include "utilities.hpp"

#include <vector>

int main() {

/**
Expand All @@ -40,34 +40,150 @@ int main() {
std::vector<std::vector<size_t>> G(34);
push_back_plain_fill(karate_index_edge_list, G, false, 0);
static_assert(graph::adjacency_list<decltype(G)>);
std::cout << "Karate adjacency list:\n";
std::cout << "size = " << G.size() << std::endl;
for (size_t uid = 0; uid < G.size(); ++uid) {
std::cout << std::setw(3) << uid << ":";
for (auto&& vid : G[uid]) {
std::cout << " " << vid;
}
std::cout << std::endl;
}

std::vector<std::list<std::tuple<size_t>>> H(34);
push_back_plain_fill(karate_index_edge_list, H, false, 0);
std::cout << "\nKarate (edge_list plain fill):\n";
std::cout << "size = " << H.size() << std::endl;
for (size_t uid = 0; uid < H.size(); ++uid) {
std::cout << std::setw(3) << uid << ":";
for (auto&& [vid] : H[uid]) {
std::cout << " " << vid;
}
std::cout << std::endl;
}


push_back_fill(karate_index_edge_list, H, false, 0);
std::cout << "\nKarate (edge_list fill...adding more):\n";
std::cout << "size = " << H.size() << std::endl;
for (size_t uid = 0; uid < H.size(); ++uid) {
std::cout << std::setw(3) << uid << ":";
for (auto&& [vid] : H[uid]) {
std::cout << " " << vid;
}
std::cout << std::endl;
}

//----------------------------------------------------------------------------

/**
* Other graphs have vertices and edges tables
*/
auto a = make_plain_graph(ospf_vertices, ospf_edges);
std::cout << "\nOSPF plain graph:\n";
std::cout << "size = " << a.size() << std::endl;
for (size_t uid = 0; uid < a.size(); ++uid) {
std::cout << std::setw(3) << ospf_vertices[uid] << ":";
for (auto&& vid : a[uid]) {
std::cout << " " << ospf_vertices[vid];
}
std::cout << std::endl;
}

auto b = make_property_graph(ospf_vertices, ospf_edges);
std::cout << "\nOSPF property graph:\n";
std::cout << "size = " << b.size() << std::endl;
for (size_t uid = 0; uid < b.size(); ++uid) {
std::cout << std::setw(3) << ospf_vertices[uid] << ":";
for (auto&& [vid, val] : b[uid]) {
std::cout << " " << ospf_vertices[vid] << ":" << val;
}
std::cout << std::endl;
}

auto c = make_index_graph(ospf_vertices, ospf_edges);
std::cout << "\nOSPF index graph:\n";
std::cout << "size = " << c.size() << std::endl;
for (size_t uid = 0; uid < c.size(); ++uid) {
std::cout << std::setw(3) << ospf_vertices[uid] << ":";
for (auto&& [vid, val] : c[uid]) {
std::cout << " " << ospf_vertices[vid] << ":" << std::get<2>(ospf_edges[val]);
}
std::cout << std::endl;
}

auto d = make_plain_graph<decltype(ospf_vertices), decltype(ospf_edges), std::vector<std::list<size_t>>>(
ospf_vertices, ospf_edges, true);
std::cout << "\nOSPF plain graph (vector of lists):\n";
std::cout << "size = " << d.size() << std::endl;
for (size_t uid = 0; uid < d.size(); ++uid) {
std::cout << std::setw(3) << ospf_vertices[uid] << ":";
for (auto&& vid : d[uid]) {
std::cout << " " << ospf_vertices[vid];
}
std::cout << std::endl;
}

auto e = make_index_graph<decltype(ospf_vertices), decltype(ospf_edges),
std::vector<std::vector<std::tuple<size_t, size_t>>>>(ospf_vertices, ospf_edges, true);
std::cout << "\nOSPF index graph (vector of vector of tuples):\n";
std::cout << "size = " << e.size() << std::endl;
for (size_t uid = 0; uid < e.size(); ++uid) {
std::cout << std::setw(3) << ospf_vertices[uid] << ":";
for (auto&& [vid, val] : e[uid]) {
std::cout << " " << ospf_vertices[vid] << ":" << std::get<2>(ospf_edges[val]);
}
std::cout << std::endl;
}

//----------------------------------------------------------------------------

auto [f, g] = make_plain_bipartite_graphs<>(movies, actors, movies_actors);
auto h = make_plain_bipartite_graph(movies, actors, movies_actors, 0);
auto i = make_plain_bipartite_graph(movies, actors, movies_actors, 1);
std::cout << "\nMovies-actors plain bipartite graphs\n";
std::cout << "index 0: " << f.size() << "==" << h.size() << std::endl;
for (size_t uid = 0; uid < f.size(); ++uid) {
std::cout << std::setw(20) << movies[uid] << ": |";
for (auto&& vid : f[uid]) {
std::cout << actors[vid] << "|";
}
std::cout << std::endl;
}
std::cout << "index 1: " << g.size() << "==" << i.size() << std::endl;
for (size_t uid = 0; uid < g.size(); ++uid) {
std::cout << std::setw(20) << actors[uid] << ": |";
for (auto&& vid : g[uid]) {
std::cout << movies[vid] << "|";
}
std::cout << std::endl;
}

auto [j, k] = make_plain_bipartite_graphs<decltype(movies), decltype(actors), decltype(movies_actors),
std::vector<std::list<size_t>>>(movies, actors, movies_actors);
auto l = make_plain_bipartite_graph<decltype(movies), decltype(actors), decltype(movies_actors),
std::vector<std::list<size_t>>>(movies, actors, movies_actors, 0);
auto m = make_plain_bipartite_graph<decltype(movies), decltype(actors), decltype(movies_actors),
std::vector<std::list<size_t>>>(movies, actors, movies_actors, 1);
std::cout << "\nMovies-actors plain bipartite graphs (vector of lists)\n";
std::cout << "index 0: " << j.size() << "==" << l.size() << std::endl;
for (size_t uid = 0; uid < j.size(); ++uid) {
std::cout << std::setw(20) << movies[uid] << ": |";
for (auto&& vid : j[uid]) {
std::cout << actors[vid] << "|";
}
std::cout << std::endl;
}
std::cout << "index 1: " << k.size() << "==" << m.size() << std::endl;
for (size_t uid = 0; uid < k.size(); ++uid) {
std::cout << std::setw(20) << actors[uid] << ": |";
for (auto&& vid : k[uid]) {
std::cout << movies[vid] << "|";
}
std::cout << std::endl;
}

//----------------------------------------------------------------------------

auto n = make_plain_graph<decltype(spice_vertices), decltype(spice_edges), std::vector<std::list<int>>>(
spice_vertices, spice_edges);
Expand All @@ -78,6 +194,19 @@ int main() {
auto r = make_property_graph(spice_vertices, spice_edges);
auto s = make_property_graph(spice_vertices, spice_edges_values);

std::cout << "\nSpice property graph (using edges+values)\n";
std::cout << "Size: " << s.size() << std::endl;
for (size_t uid = 0; uid < s.size(); ++uid) {
std::cout << std::setw(4) << spice_vertices[uid] << ": |";
for (auto&& [vid, comp, val] : s[uid]) {
std::cout << std::setw(3) << spice_vertices[vid] << ":" << comp << "/" << val << "|";
}
std::cout << std::endl;
}




//bfs_edge_range(n, 1);
graph::views::edges_breadth_first_search(n, 1);

Expand Down
8 changes: 7 additions & 1 deletion example/CppCon2021/examples/ospf.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -50,9 +50,12 @@ int main() {
graph::init_shortest_paths(e, p);
graph::dijkstra_shortest_paths(G, 5UL, e, p, [](auto&& ee) { return std::get<1>(ee); });

bool pass = true;
for (size_t i = 0; i < size(ospf_vertices); ++i) {
std::cout << std::setw(6) << ospf_vertices[i] << std::setw(6) << e[i] << std::endl;
std::cout << std::setw(6) << ospf_vertices[i] << std::setw(6) << e[i] << std::endl;
if (e[i] != d[i]) pass = false;
}
std::cout << (pass ? "***PASS***" : "***FAIL***") << std::endl;

std::cout << "----------------" << std::endl;
std::cout << "Results from make_index_graph(osp_vertices)" << std::endl;
Expand All @@ -67,9 +70,12 @@ int main() {
graph::init_shortest_paths(f, p);
graph::dijkstra_shortest_paths(J, 5UL, f, p, [](auto&& ee) { return std::get<2>(ospf_edges[std::get<1>(ee)]); });

bool pass2 = true;
for (size_t i = 0; i < size(ospf_vertices); ++i) {
std::cout << std::setw(6) << ospf_vertices[i] << std::setw(6) << e[i] << std::endl;
if (e[i] != d[i]) pass2 = false;
}
std::cout << (pass2 ? "***PASS***" : "***FAIL***") << std::endl;

return 0;
}
2 changes: 1 addition & 1 deletion example/CppCon2021/include/utilities.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -233,7 +233,7 @@ auto make_plain_bipartite_graph(const V1& left_vertices, const V2& right_vertice
auto index_edges = data_to_graph_edge_list(left_vertices, right_vertices, edges);
auto graph_size = idx == 0 ? size(left_vertices) : size(right_vertices);

Graph G(size(left_vertices));
Graph G(graph_size);
push_back_plain_fill(index_edges, G, true, idx);

return G;
Expand Down
8 changes: 4 additions & 4 deletions include/graph/algorithm/bellman_ford_shortest_paths.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
#include <ranges>
#include <optional>
#include <stdexcept>
#include <fmt/format.h>
#include <format>

#ifndef GRAPH_BELLMAN_SHORTEST_PATHS_HPP
# define GRAPH_BELLMAN_SHORTEST_PATHS_HPP
Expand Down Expand Up @@ -139,14 +139,14 @@ requires convertible_to<range_value_t<Sources>, vertex_id_t<G>> && //

if (size(distances) < size(vertices(g))) {
throw std::out_of_range(
fmt::format("bellman_ford_shortest_paths: size of distances is {} is less than the number of vertices {}",
std::format("bellman_ford_shortest_paths: size of distances is {} is less than the number of vertices {}",
size(distances), size(vertices(g))));
}

if constexpr (!is_same_v<Predecessors, _null_range_type>) {
if (size(predecessor) < size(vertices(g))) {
throw std::out_of_range(
fmt::format("bellman_ford_shortest_paths: size of predecessor is {} is less than the number of vertices {}",
std::format("bellman_ford_shortest_paths: size of predecessor is {} is less than the number of vertices {}",
size(predecessor), size(vertices(g))));
}
}
Expand All @@ -160,7 +160,7 @@ requires convertible_to<range_value_t<Sources>, vertex_id_t<G>> && //
for (auto&& source : sources) {
if (source >= N || source < 0) {
throw std::out_of_range(
fmt::format("bellman_ford_shortest_paths: source vertex id '{}' is out of range", source));
std::format("bellman_ford_shortest_paths: source vertex id '{}' is out of range", source));
}
distances[static_cast<size_t>(source)] = zero; // mark source as discovered
if constexpr (has_on_discover_vertex<G, Visitor>) {
Expand Down
Loading
Loading