netgraph-core 0.1.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (85) hide show
  1. netgraph_core-0.1.0/.coveragerc +11 -0
  2. netgraph_core-0.1.0/.gcovr.cfg +20 -0
  3. netgraph_core-0.1.0/.github/workflows/release.yml +77 -0
  4. netgraph_core-0.1.0/.github/workflows/tests.yml +51 -0
  5. netgraph_core-0.1.0/.gitignore +222 -0
  6. netgraph_core-0.1.0/.pre-commit-config.yaml +24 -0
  7. netgraph_core-0.1.0/CHANGELOG.md +31 -0
  8. netgraph_core-0.1.0/CMakeLists.txt +142 -0
  9. netgraph_core-0.1.0/CONTRIBUTING.md +77 -0
  10. netgraph_core-0.1.0/LICENSE +148 -0
  11. netgraph_core-0.1.0/Makefile +192 -0
  12. netgraph_core-0.1.0/PKG-INFO +135 -0
  13. netgraph_core-0.1.0/README.md +98 -0
  14. netgraph_core-0.1.0/bindings/python/module.cpp +615 -0
  15. netgraph_core-0.1.0/dev/coverage_summary.py +140 -0
  16. netgraph_core-0.1.0/dev/run-checks.sh +146 -0
  17. netgraph_core-0.1.0/include/netgraph/core/algorithms.hpp +56 -0
  18. netgraph_core-0.1.0/include/netgraph/core/backend.hpp +134 -0
  19. netgraph_core-0.1.0/include/netgraph/core/constants.hpp +13 -0
  20. netgraph_core-0.1.0/include/netgraph/core/flow.hpp +28 -0
  21. netgraph_core-0.1.0/include/netgraph/core/flow_graph.hpp +60 -0
  22. netgraph_core-0.1.0/include/netgraph/core/flow_policy.hpp +189 -0
  23. netgraph_core-0.1.0/include/netgraph/core/flow_state.hpp +98 -0
  24. netgraph_core-0.1.0/include/netgraph/core/k_shortest_paths.hpp +26 -0
  25. netgraph_core-0.1.0/include/netgraph/core/max_flow.hpp +56 -0
  26. netgraph_core-0.1.0/include/netgraph/core/options.hpp +39 -0
  27. netgraph_core-0.1.0/include/netgraph/core/shortest_paths.hpp +63 -0
  28. netgraph_core-0.1.0/include/netgraph/core/strict_multidigraph.hpp +69 -0
  29. netgraph_core-0.1.0/include/netgraph/core/types.hpp +80 -0
  30. netgraph_core-0.1.0/pyproject.toml +93 -0
  31. netgraph_core-0.1.0/python/netgraph_core/__init__.py +66 -0
  32. netgraph_core-0.1.0/python/netgraph_core/_docs.py +559 -0
  33. netgraph_core-0.1.0/python/netgraph_core/_version.py +5 -0
  34. netgraph_core-0.1.0/python/netgraph_core/py.typed +0 -0
  35. netgraph_core-0.1.0/src/cpu_backend.cpp +122 -0
  36. netgraph_core-0.1.0/src/flow_graph.cpp +136 -0
  37. netgraph_core-0.1.0/src/flow_policy.cpp +417 -0
  38. netgraph_core-0.1.0/src/flow_state.cpp +523 -0
  39. netgraph_core-0.1.0/src/k_shortest_paths.cpp +350 -0
  40. netgraph_core-0.1.0/src/max_flow.cpp +279 -0
  41. netgraph_core-0.1.0/src/shortest_paths.cpp +405 -0
  42. netgraph_core-0.1.0/src/strict_multidigraph.cpp +145 -0
  43. netgraph_core-0.1.0/tests/cpp/flow_graph_tests.cpp +266 -0
  44. netgraph_core-0.1.0/tests/cpp/flow_policy_tests.cpp +297 -0
  45. netgraph_core-0.1.0/tests/cpp/flow_state_tests.cpp +379 -0
  46. netgraph_core-0.1.0/tests/cpp/k_shortest_paths_tests.cpp +199 -0
  47. netgraph_core-0.1.0/tests/cpp/masking_tests.cpp +646 -0
  48. netgraph_core-0.1.0/tests/cpp/max_flow_tests.cpp +1169 -0
  49. netgraph_core-0.1.0/tests/cpp/shortest_paths_tests.cpp +300 -0
  50. netgraph_core-0.1.0/tests/cpp/smoke_test.cpp +36 -0
  51. netgraph_core-0.1.0/tests/cpp/strict_multidigraph_tests.cpp +318 -0
  52. netgraph_core-0.1.0/tests/cpp/test_utils.hpp +401 -0
  53. netgraph_core-0.1.0/tests/py/conftest.py +877 -0
  54. netgraph_core-0.1.0/tests/py/test_api_validation.py +139 -0
  55. netgraph_core-0.1.0/tests/py/test_batch_max_flow_consistency.py +72 -0
  56. netgraph_core-0.1.0/tests/py/test_batch_max_flow_masks.py +35 -0
  57. netgraph_core-0.1.0/tests/py/test_cross_validation.py +348 -0
  58. netgraph_core-0.1.0/tests/py/test_edge_cases.py +82 -0
  59. netgraph_core-0.1.0/tests/py/test_ext_edge_ids.py +164 -0
  60. netgraph_core-0.1.0/tests/py/test_flow_policy.py +285 -0
  61. netgraph_core-0.1.0/tests/py/test_flow_policy_configurations.py +513 -0
  62. netgraph_core-0.1.0/tests/py/test_flow_policy_edge_cases.py +408 -0
  63. netgraph_core-0.1.0/tests/py/test_flow_policy_lifecycle.py +76 -0
  64. netgraph_core-0.1.0/tests/py/test_flow_policy_masks.py +383 -0
  65. netgraph_core-0.1.0/tests/py/test_flow_policy_path_distribution.py +532 -0
  66. netgraph_core-0.1.0/tests/py/test_flow_policy_validation.py +391 -0
  67. netgraph_core-0.1.0/tests/py/test_graph_from_arrays.py +65 -0
  68. netgraph_core-0.1.0/tests/py/test_graph_structure.py +27 -0
  69. netgraph_core-0.1.0/tests/py/test_imports.py +8 -0
  70. netgraph_core-0.1.0/tests/py/test_ksp.py +89 -0
  71. netgraph_core-0.1.0/tests/py/test_ksp_variants.py +46 -0
  72. netgraph_core-0.1.0/tests/py/test_lifetime_safety.py +321 -0
  73. netgraph_core-0.1.0/tests/py/test_mask_semantics.py +172 -0
  74. netgraph_core-0.1.0/tests/py/test_mask_validation.py +222 -0
  75. netgraph_core-0.1.0/tests/py/test_masking_comprehensive.py +653 -0
  76. netgraph_core-0.1.0/tests/py/test_max_flow.py +299 -0
  77. netgraph_core-0.1.0/tests/py/test_max_flow_cost_distribution.py +166 -0
  78. netgraph_core-0.1.0/tests/py/test_max_flow_summary.py +53 -0
  79. netgraph_core-0.1.0/tests/py/test_paths_resolve.py +67 -0
  80. netgraph_core-0.1.0/tests/py/test_policy_vs_maxflow_equivalence.py +232 -0
  81. netgraph_core-0.1.0/tests/py/test_sensitivity.py +91 -0
  82. netgraph_core-0.1.0/tests/py/test_spf_basic.py +184 -0
  83. netgraph_core-0.1.0/tests/py/test_spf_edge_select.py +152 -0
  84. netgraph_core-0.1.0/tests/py/test_spf_masks.py +51 -0
  85. netgraph_core-0.1.0/tests/py/test_thread_safety.py +345 -0
@@ -0,0 +1,11 @@
1
+ [run]
2
+ branch = True
3
+ data_file = build/coverage/.coverage
4
+ source =
5
+ netgraph_core
6
+ omit =
7
+ python/netgraph_core/_docs.py
8
+
9
+ [report]
10
+ show_missing = True
11
+ skip_covered = True
@@ -0,0 +1,20 @@
1
+ [gcovr]
2
+ root = .
3
+
4
+ # Object dirs for Python extension and standalone C++ test builds
5
+ object-directory = build
6
+ object-directory = build/cpp-tests-cov
7
+
8
+ # Only include our sources
9
+ filter = include/netgraph
10
+ filter = src
11
+
12
+ # Exclude tests and third-party deps
13
+ exclude = tests
14
+ exclude = bindings/.*
15
+ exclude-directories = .*/_deps/.*
16
+ exclude-directories = .*/venv/.*
17
+ exclude-directories = .*/site-packages/.*
18
+
19
+ # Work around odd temp working dirs on macOS/pybind11
20
+ gcov-ignore-errors = all
@@ -0,0 +1,77 @@
1
+ name: Release
2
+
3
+ on:
4
+ push:
5
+ tags: ["v*"]
6
+ pull_request:
7
+ paths-ignore:
8
+ - "docs/**"
9
+ - "**.md"
10
+ workflow_dispatch:
11
+
12
+ jobs:
13
+ build_wheels:
14
+ name: Wheel (${{ matrix.os }})
15
+ runs-on: ${{ matrix.os }}
16
+ strategy:
17
+ fail-fast: false
18
+ matrix:
19
+ os: [ubuntu-22.04, macos-13]
20
+
21
+ steps:
22
+ - uses: actions/checkout@v4
23
+
24
+ # Build wheels using cibuildwheel
25
+ # ENV variables control the build (architectures, python versions)
26
+ - name: Build wheels
27
+ uses: pypa/cibuildwheel@v2.21.3
28
+ env:
29
+ # Build for Python 3.9+
30
+ CIBW_BUILD: "cp39-* cp310-* cp311-* cp312-* cp313-*"
31
+ # Skip PyPy and musllinux for now (unless desired)
32
+ CIBW_SKIP: "pp* *-musllinux_*"
33
+
34
+ # macOS: Build Universal2 wheels on Intel runner (macos-13)
35
+ CIBW_ARCHS_MACOS: "universal2"
36
+ CIBW_TEST_COMMAND: 'python -c "import netgraph_core; print(netgraph_core.__version__)"'
37
+ CIBW_BEFORE_ALL_LINUX: "yum install -y libatomic || (apt-get update && apt-get install -y libatomic1) || apk add libatomic"
38
+
39
+ - uses: actions/upload-artifact@v4
40
+ with:
41
+ name: cibw-wheels-${{ matrix.os }}-${{ strategy.job-index }}
42
+ path: ./wheelhouse/*.whl
43
+
44
+ build_sdist:
45
+ name: Build SDist
46
+ runs-on: ubuntu-latest
47
+ steps:
48
+ - uses: actions/checkout@v4
49
+
50
+ - name: Build SDist
51
+ run: pipx run build --sdist
52
+
53
+ - uses: actions/upload-artifact@v4
54
+ with:
55
+ name: cibw-sdist
56
+ path: dist/*.tar.gz
57
+
58
+ publish_pypi:
59
+ name: Publish to PyPI
60
+ needs: [build_wheels, build_sdist]
61
+ runs-on: ubuntu-latest
62
+ environment: pypi
63
+ permissions:
64
+ id-token: write # Required for Trusted Publishing (OIDC)
65
+
66
+ # Only publish on tag pushes
67
+ if: github.event_name == 'push' && startsWith(github.ref, 'refs/tags/v')
68
+
69
+ steps:
70
+ - uses: actions/download-artifact@v4
71
+ with:
72
+ pattern: cibw-*
73
+ path: dist
74
+ merge-multiple: true
75
+
76
+ - name: Publish to PyPI
77
+ uses: pypa/gh-action-pypi-publish@release/v1
@@ -0,0 +1,51 @@
1
+ name: Tests
2
+
3
+ on:
4
+ push:
5
+ branches: [ main, master ]
6
+ pull_request:
7
+ workflow_dispatch:
8
+
9
+ jobs:
10
+ test:
11
+ name: Unit tests (${{ matrix.os }}, py${{ matrix.python-version }})
12
+ runs-on: ${{ matrix.os }}
13
+ strategy:
14
+ fail-fast: false
15
+ matrix:
16
+ os: [ubuntu-22.04, macos-13]
17
+ python-version: ["3.9", "3.10", "3.11", "3.12", "3.13"]
18
+ steps:
19
+ - uses: actions/checkout@v4
20
+ - uses: actions/setup-python@v5
21
+ with:
22
+ python-version: ${{ matrix.python-version }}
23
+ - name: Install deps
24
+ run: |
25
+ python -m pip install -U pip wheel
26
+ python -m pip install -e .[dev]
27
+ - name: Run CI checks (lint + C++/Python tests)
28
+ run: make check-ci
29
+
30
+ coverage:
31
+ name: Coverage (ubuntu, py3.11)
32
+ runs-on: ubuntu-22.04
33
+ steps:
34
+ - uses: actions/checkout@v4
35
+ - uses: actions/setup-python@v5
36
+ with:
37
+ python-version: "3.11"
38
+ - name: Install deps
39
+ run: |
40
+ python -m pip install -U pip wheel
41
+ python -m pip install -e .[dev]
42
+ - name: Generate coverage (Python + C++)
43
+ run: make cov
44
+ - name: Upload coverage artifacts
45
+ uses: actions/upload-artifact@v4
46
+ with:
47
+ name: coverage-reports
48
+ path: |
49
+ build/coverage/coverage-python.xml
50
+ build/coverage/coverage-cpp.xml
51
+ build/coverage/coverage-combined.html
@@ -0,0 +1,222 @@
1
+ # Byte-compiled / optimized / DLL files
2
+ __pycache__/
3
+ *.py[codz]
4
+ *$py.class
5
+
6
+ # C extensions
7
+ *.so
8
+
9
+ # Distribution / packaging
10
+ .Python
11
+ build/
12
+ develop-eggs/
13
+ dist/
14
+ downloads/
15
+ eggs/
16
+ .eggs/
17
+ lib/
18
+ lib64/
19
+ parts/
20
+ sdist/
21
+ var/
22
+ wheels/
23
+ share/python-wheels/
24
+ *.egg-info/
25
+ .installed.cfg
26
+ *.egg
27
+ MANIFEST
28
+
29
+ # PyInstaller
30
+ # Usually these files are written by a python script from a template
31
+ # before PyInstaller builds the exe, so as to inject date/other infos into it.
32
+ *.manifest
33
+ *.spec
34
+
35
+ # Installer logs
36
+ pip-log.txt
37
+ pip-delete-this-directory.txt
38
+
39
+ # Unit test / coverage reports
40
+ htmlcov/
41
+ .tox/
42
+ .nox/
43
+ .coverage
44
+ .coverage.*
45
+ .cache
46
+ nosetests.xml
47
+ coverage.xml
48
+ *.cover
49
+ *.py.cover
50
+ .hypothesis/
51
+ .pytest_cache/
52
+ .benchmarks/
53
+ cover/
54
+
55
+ # Consolidated coverage artifacts
56
+ build/coverage/
57
+
58
+ # CTest output if created in project root
59
+ Testing/
60
+ CTestTestfile.cmake
61
+
62
+ # Translations
63
+ *.mo
64
+ *.pot
65
+
66
+ # Django stuff:
67
+ *.log
68
+ local_settings.py
69
+ db.sqlite3
70
+ db.sqlite3-journal
71
+
72
+ # Flask stuff:
73
+ instance/
74
+ .webassets-cache
75
+
76
+ # Scrapy stuff:
77
+ .scrapy
78
+
79
+ # Sphinx documentation
80
+ docs/_build/
81
+
82
+ # PyBuilder
83
+ .pybuilder/
84
+ target/
85
+
86
+ # Jupyter Notebook
87
+ .ipynb_checkpoints
88
+
89
+ # IPython
90
+ profile_default/
91
+ ipython_config.py
92
+
93
+ # pyenv
94
+ # For a library or package, you might want to ignore these files since the code is
95
+ # intended to run in multiple environments; otherwise, check them in:
96
+ # .python-version
97
+
98
+ # pipenv
99
+ # According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
100
+ # However, in case of collaboration, if having platform-specific dependencies or dependencies
101
+ # having no cross-platform support, pipenv may install dependencies that don't work, or not
102
+ # install all needed dependencies.
103
+ #Pipfile.lock
104
+
105
+ # UV
106
+ # Similar to Pipfile.lock, it is generally recommended to include uv.lock in version control.
107
+ # This is especially recommended for binary packages to ensure reproducibility, and is more
108
+ # commonly ignored for libraries.
109
+ #uv.lock
110
+
111
+ # poetry
112
+ # Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control.
113
+ # This is especially recommended for binary packages to ensure reproducibility, and is more
114
+ # commonly ignored for libraries.
115
+ # https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control
116
+ #poetry.lock
117
+ #poetry.toml
118
+
119
+ # pdm
120
+ # Similar to Pipfile.lock, it is generally recommended to include pdm.lock in version control.
121
+ # pdm recommends including project-wide configuration in pdm.toml, but excluding .pdm-python.
122
+ # https://pdm-project.org/en/latest/usage/project/#working-with-version-control
123
+ #pdm.lock
124
+ #pdm.toml
125
+ .pdm-python
126
+ .pdm-build/
127
+
128
+ # pixi
129
+ # Similar to Pipfile.lock, it is generally recommended to include pixi.lock in version control.
130
+ #pixi.lock
131
+ # Pixi creates a virtual environment in the .pixi directory, just like venv module creates one
132
+ # in the .venv directory. It is recommended not to include this directory in version control.
133
+ .pixi
134
+
135
+ # PEP 582; used by e.g. github.com/David-OConnor/pyflow and github.com/pdm-project/pdm
136
+ __pypackages__/
137
+
138
+ # Celery stuff
139
+ celerybeat-schedule
140
+ celerybeat.pid
141
+
142
+ # SageMath parsed files
143
+ *.sage.py
144
+
145
+ # Environments
146
+ .env
147
+ .envrc
148
+ .venv
149
+ env/
150
+ venv/
151
+ ENV/
152
+ env.bak/
153
+ venv.bak/
154
+
155
+ # Spyder project settings
156
+ .spyderproject
157
+ .spyproject
158
+
159
+ # Rope project settings
160
+ .ropeproject
161
+
162
+ # mkdocs documentation
163
+ /site
164
+
165
+ # mypy
166
+ .mypy_cache/
167
+ .dmypy.json
168
+ dmypy.json
169
+
170
+ # Pyre type checker
171
+ .pyre/
172
+
173
+ # pytype static type analyzer
174
+ .pytype/
175
+
176
+ # Cython debug symbols
177
+ cython_debug/
178
+
179
+ # PyCharm
180
+ # JetBrains specific template is maintained in a separate JetBrains.gitignore that can
181
+ # be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore
182
+ # and can be added to the global gitignore or merged into this file. For a more nuclear
183
+ # option (not recommended) you can uncomment the following to ignore the entire idea folder.
184
+ #.idea/
185
+
186
+ # Abstra
187
+ # Abstra is an AI-powered process automation framework.
188
+ # Ignore directories containing user credentials, local state, and settings.
189
+ # Learn more at https://abstra.io/docs
190
+ .abstra/
191
+
192
+ # Visual Studio Code
193
+ # Visual Studio Code specific template is maintained in a separate VisualStudioCode.gitignore
194
+ # that can be found at https://github.com/github/gitignore/blob/main/Global/VisualStudioCode.gitignore
195
+ # and can be added to the global gitignore or merged into this file. However, if you prefer,
196
+ # you could uncomment the following to ignore the entire vscode folder
197
+ .vscode/
198
+
199
+ # Ruff stuff:
200
+ .ruff_cache/
201
+
202
+ # PyPI configuration file
203
+ .pypirc
204
+
205
+ # Cursor
206
+ # Cursor is an AI-powered code editor. `.cursorignore` specifies files/directories to
207
+ # exclude from AI features like autocomplete and code analysis. Recommended for sensitive data
208
+ # refer to https://docs.cursor.com/context/ignore-files
209
+ .cursorignore
210
+ .cursorindexingignore
211
+
212
+ # OS-specific
213
+ .DS_Store
214
+
215
+ # IDEs
216
+ .idea/
217
+ *.code-workspace
218
+
219
+ # Marimo
220
+ marimo/_static/
221
+ marimo/_lsp/
222
+ __marimo__/
@@ -0,0 +1,24 @@
1
+ repos:
2
+ - repo: https://github.com/pre-commit/pre-commit-hooks
3
+ rev: v5.0.0
4
+ hooks:
5
+ - id: check-merge-conflict
6
+ - id: check-yaml
7
+ - id: end-of-file-fixer
8
+ - id: trailing-whitespace
9
+ - id: mixed-line-ending
10
+ - id: debug-statements
11
+
12
+ - repo: https://github.com/astral-sh/ruff-pre-commit
13
+ rev: v0.11.13
14
+ hooks:
15
+ - id: ruff
16
+ args: ["--fix"]
17
+ - id: ruff-format
18
+
19
+ - repo: https://github.com/RobertCraigie/pyright-python
20
+ rev: v1.1.401
21
+ hooks:
22
+ - id: pyright
23
+ additional_dependencies: ["numpy>=1.22"]
24
+ # Pyright reads configuration from pyproject.toml
@@ -0,0 +1,31 @@
1
+ # Changelog
2
+
3
+ All notable changes to this project will be documented in this file.
4
+
5
+ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
6
+ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
+
8
+ ## [0.1.0] - 2025-11-23
9
+
10
+ ### Added
11
+
12
+ - **Core Library**: Initial release of C++ implementation for graph algorithms and flow tracking.
13
+ - **Graph Structures**:
14
+ - `StrictMultiDiGraph`: Immutable directed multigraph using CSR (Compressed Sparse Row) adjacency.
15
+ - `FlowGraph`: Manages flow state, per-flow edge allocations, and residual capacities.
16
+ - **Algorithms**:
17
+ - Shortest paths (Dijkstra variant returning a DAG for ECMP; supports node/edge masking and residual-aware tie-breaking).
18
+ - K-Shortest paths (Yen's algorithm).
19
+ - Max-flow (Successive Shortest Path with ECMP/WCMP placement; supports capacity-aware (TE) and cost-only (IP) routing modes).
20
+ - Sensitivity analysis (identifies bottlenecks).
21
+ - **Flow Policy**:
22
+ - **Modeling**: Unified configuration for IP routing (cost-based ECMP) and Traffic Engineering (capacity-aware TE).
23
+ - **Placement**: `Proportional` (WCMP) and `EqualBalanced` (ECMP) strategies.
24
+ - **Lifecycle**: Manages demand placement, static/dynamic path selection, and re-optimization.
25
+ - **Constraints**: Enforces limits on path cost, stretch factor, and flow counts.
26
+ - **Python Bindings**:
27
+ - Python 3.9+ support via pybind11.
28
+ - NumPy integration using zero-copy views where applicable.
29
+ - Releases GIL during long-running graph algorithms.
30
+ - **Testing**:
31
+ - Python and C++ test suites.
@@ -0,0 +1,142 @@
1
+ cmake_minimum_required(VERSION 3.23)
2
+ project(netgraph_core LANGUAGES CXX)
3
+ # Silence pybind11 FindPython compatibility warning by selecting the modern mode
4
+ set(PYBIND11_FINDPYTHON NEW CACHE STRING "Use modern FindPython in pybind11")
5
+ # Optional C++ tests
6
+ option(NETGRAPH_CORE_BUILD_TESTS "Build C++ unit tests" OFF)
7
+ if(NETGRAPH_CORE_BUILD_TESTS)
8
+ include(FetchContent)
9
+ FetchContent_Declare(
10
+ googletest
11
+ URL https://github.com/google/googletest/archive/refs/tags/v1.14.0.zip
12
+ DOWNLOAD_EXTRACT_TIMESTAMP TRUE
13
+ )
14
+ FetchContent_MakeAvailable(googletest)
15
+ enable_testing()
16
+ add_executable(netgraph_core_tests
17
+ tests/cpp/smoke_test.cpp
18
+ tests/cpp/flow_policy_tests.cpp
19
+ tests/cpp/strict_multidigraph_tests.cpp
20
+ tests/cpp/shortest_paths_tests.cpp
21
+ tests/cpp/flow_state_tests.cpp
22
+ tests/cpp/flow_graph_tests.cpp
23
+ tests/cpp/max_flow_tests.cpp
24
+ tests/cpp/k_shortest_paths_tests.cpp
25
+ tests/cpp/masking_tests.cpp
26
+ )
27
+ target_link_libraries(netgraph_core_tests PRIVATE netgraph_core GTest::gtest_main)
28
+ target_include_directories(netgraph_core_tests PRIVATE tests/cpp)
29
+ if(NETGRAPH_CORE_COVERAGE AND (CMAKE_CXX_COMPILER_ID MATCHES "GNU|Clang"))
30
+ target_compile_options(netgraph_core_tests PRIVATE -O0 -g --coverage)
31
+ target_link_options(netgraph_core_tests PRIVATE --coverage)
32
+ endif()
33
+ include(GoogleTest)
34
+ gtest_discover_tests(netgraph_core_tests)
35
+ endif()
36
+
37
+ set(CMAKE_CXX_STANDARD 20)
38
+ set(CMAKE_CXX_STANDARD_REQUIRED ON)
39
+ set(CMAKE_CXX_EXTENSIONS OFF)
40
+ set(CMAKE_POSITION_INDEPENDENT_CODE ON)
41
+
42
+ # macOS: enforce consistent deployment target and architecture for wheels/builds
43
+ if(APPLE)
44
+ # Allow environment to override, otherwise choose a sensible default
45
+ if(DEFINED ENV{MACOSX_DEPLOYMENT_TARGET})
46
+ set(CMAKE_OSX_DEPLOYMENT_TARGET "$ENV{MACOSX_DEPLOYMENT_TARGET}" CACHE STRING "" FORCE)
47
+ elseif(NOT DEFINED CMAKE_OSX_DEPLOYMENT_TARGET)
48
+ set(CMAKE_OSX_DEPLOYMENT_TARGET "15.0" CACHE STRING "" FORCE)
49
+ endif()
50
+ if(NOT DEFINED CMAKE_OSX_ARCHITECTURES)
51
+ # Default to arm64 on Apple Silicon hosts
52
+ if(CMAKE_SYSTEM_PROCESSOR MATCHES "arm64|aarch64")
53
+ set(CMAKE_OSX_ARCHITECTURES "arm64" CACHE STRING "" FORCE)
54
+ endif()
55
+ endif()
56
+ endif()
57
+
58
+ # Dependencies
59
+ find_package(pybind11 3 CONFIG QUIET)
60
+ if(NOT pybind11_FOUND)
61
+ message(STATUS "pybind11 not found via config; using FetchContent")
62
+ include(FetchContent)
63
+ FetchContent_Declare(
64
+ pybind11
65
+ GIT_REPOSITORY https://github.com/pybind/pybind11.git
66
+ GIT_TAG v3.0.0
67
+ DOWNLOAD_EXTRACT_TIMESTAMP TRUE
68
+ )
69
+ FetchContent_MakeAvailable(pybind11)
70
+ endif()
71
+
72
+
73
+ add_library(netgraph_core STATIC
74
+ src/strict_multidigraph.cpp
75
+ src/shortest_paths.cpp
76
+ src/k_shortest_paths.cpp
77
+ src/max_flow.cpp
78
+ src/flow_state.cpp
79
+ src/flow_graph.cpp
80
+ src/flow_policy.cpp
81
+ src/cpu_backend.cpp
82
+ )
83
+ target_include_directories(netgraph_core PUBLIC
84
+ $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>
85
+ $<INSTALL_INTERFACE:include>
86
+ )
87
+ target_compile_definitions(netgraph_core PRIVATE _USE_MATH_DEFINES)
88
+ ## C++ standard is set globally above.
89
+ target_compile_features(netgraph_core PUBLIC cxx_std_20)
90
+
91
+ # Warnings
92
+ if(MSVC)
93
+ target_compile_options(netgraph_core PRIVATE /W4 /permissive-)
94
+ else()
95
+ target_compile_options(netgraph_core PRIVATE -Wall -Wextra -Wpedantic)
96
+ endif()
97
+
98
+ # Python extension
99
+ pybind11_add_module(_netgraph_core bindings/python/module.cpp)
100
+ target_link_libraries(_netgraph_core PRIVATE netgraph_core)
101
+ target_compile_features(_netgraph_core PRIVATE cxx_std_20)
102
+ if(APPLE)
103
+ # Prefer maximum runtime compatibility for libc++ on macOS
104
+ target_compile_definitions(netgraph_core PUBLIC _LIBCPP_DISABLE_AVAILABILITY=1 _LIBCPP_ABI_VERSION=1)
105
+ target_compile_definitions(_netgraph_core PRIVATE _LIBCPP_DISABLE_AVAILABILITY=1 _LIBCPP_ABI_VERSION=1)
106
+ endif()
107
+
108
+ # Optional coverage instrumentation for GCC/Clang
109
+ option(NETGRAPH_CORE_COVERAGE "Enable C++ coverage instrumentation" OFF)
110
+ if(NETGRAPH_CORE_COVERAGE)
111
+ message(STATUS "Enabling coverage instrumentation for C++ targets")
112
+ if(CMAKE_CXX_COMPILER_ID MATCHES "GNU|Clang")
113
+ foreach(tgt netgraph_core _netgraph_core)
114
+ # Use no optimizations and include debug info for accurate line mapping
115
+ target_compile_options(${tgt} PRIVATE -O0 -g --coverage)
116
+ # Link coverage runtime
117
+ target_link_options(${tgt} PRIVATE --coverage)
118
+ endforeach()
119
+ else()
120
+ message(WARNING "NETGRAPH_CORE_COVERAGE is set but compiler '${CMAKE_CXX_COMPILER_ID}' is not supported")
121
+ endif()
122
+ endif()
123
+
124
+ # Optional sanitizers for debug testing
125
+ option(NETGRAPH_CORE_SANITIZE "Enable Address/Undefined sanitizers" OFF)
126
+ if(NETGRAPH_CORE_SANITIZE)
127
+ if(CMAKE_CXX_COMPILER_ID MATCHES "GNU|Clang")
128
+ set(SAN_FLAGS "-fsanitize=address,undefined -fno-omit-frame-pointer")
129
+ foreach(tgt netgraph_core _netgraph_core)
130
+ target_compile_options(${tgt} PRIVATE ${SAN_FLAGS})
131
+ target_link_options(${tgt} PRIVATE ${SAN_FLAGS})
132
+ endforeach()
133
+ else()
134
+ message(WARNING "NETGRAPH_CORE_SANITIZE is set but compiler '${CMAKE_CXX_COMPILER_ID}' is not supported")
135
+ endif()
136
+ endif()
137
+
138
+ # Install
139
+ install(TARGETS _netgraph_core
140
+ LIBRARY DESTINATION .
141
+ RUNTIME DESTINATION .
142
+ )
@@ -0,0 +1,77 @@
1
+ # Contributing to NetGraph-Core
2
+
3
+ This document provides guidelines for setting up your development environment and submitting contributions.
4
+
5
+ ## Development Setup
6
+
7
+ NetGraph-Core is a hybrid C++/Python project. You will need:
8
+
9
+ - Python 3.9+
10
+ - C++20 compatible compiler (GCC 10+, Clang 12+, MSVC 2019+)
11
+ - CMake 3.23+
12
+ - Ninja (recommended)
13
+
14
+ ### 1. Clone the repository
15
+
16
+ ```bash
17
+ git clone https://github.com/networmix/NetGraph-Core.git
18
+ cd NetGraph-Core
19
+ ```
20
+
21
+ ### 2. Create a virtual environment and install dependencies
22
+
23
+ We use a `Makefile` to simplify development tasks.
24
+
25
+ ```bash
26
+ make dev
27
+ source venv/bin/activate
28
+ ```
29
+
30
+ This will:
31
+
32
+ - Create a virtual environment in `./venv`
33
+ - Install all development dependencies
34
+ - Install pre-commit hooks
35
+
36
+ ## Workflow
37
+
38
+ ### Running Tests
39
+
40
+ Run all checks (linting + C++ tests + Python tests):
41
+
42
+ ```bash
43
+ make check
44
+ ```
45
+
46
+ Run specific test suites:
47
+
48
+ ```bash
49
+ make cpp-test # C++ tests (GoogleTest)
50
+ make py-test # Python tests (pytest)
51
+ ```
52
+
53
+ ### Code Style
54
+
55
+ - **Python**: We use `ruff` for linting and formatting, and `pyright` for static type checking.
56
+ - **C++**: We follow standard C++20 practices.
57
+
58
+ Auto-fix Python formatting:
59
+
60
+ ```bash
61
+ make format
62
+ ```
63
+
64
+ ## Release Process
65
+
66
+ Releases are automated via GitHub Actions when a new tag is pushed.
67
+
68
+ 1. Bump version in `pyproject.toml` and `python/netgraph_core/_version.py`.
69
+ 2. Commit and push.
70
+ 3. Create and push a tag:
71
+
72
+ ```bash
73
+ git tag v0.1.0
74
+ git push origin v0.1.0
75
+ ```
76
+
77
+ 4. The CI pipeline will build wheels, sdist, and publish to PyPI.