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.
- netgraph_core-0.1.0/.coveragerc +11 -0
- netgraph_core-0.1.0/.gcovr.cfg +20 -0
- netgraph_core-0.1.0/.github/workflows/release.yml +77 -0
- netgraph_core-0.1.0/.github/workflows/tests.yml +51 -0
- netgraph_core-0.1.0/.gitignore +222 -0
- netgraph_core-0.1.0/.pre-commit-config.yaml +24 -0
- netgraph_core-0.1.0/CHANGELOG.md +31 -0
- netgraph_core-0.1.0/CMakeLists.txt +142 -0
- netgraph_core-0.1.0/CONTRIBUTING.md +77 -0
- netgraph_core-0.1.0/LICENSE +148 -0
- netgraph_core-0.1.0/Makefile +192 -0
- netgraph_core-0.1.0/PKG-INFO +135 -0
- netgraph_core-0.1.0/README.md +98 -0
- netgraph_core-0.1.0/bindings/python/module.cpp +615 -0
- netgraph_core-0.1.0/dev/coverage_summary.py +140 -0
- netgraph_core-0.1.0/dev/run-checks.sh +146 -0
- netgraph_core-0.1.0/include/netgraph/core/algorithms.hpp +56 -0
- netgraph_core-0.1.0/include/netgraph/core/backend.hpp +134 -0
- netgraph_core-0.1.0/include/netgraph/core/constants.hpp +13 -0
- netgraph_core-0.1.0/include/netgraph/core/flow.hpp +28 -0
- netgraph_core-0.1.0/include/netgraph/core/flow_graph.hpp +60 -0
- netgraph_core-0.1.0/include/netgraph/core/flow_policy.hpp +189 -0
- netgraph_core-0.1.0/include/netgraph/core/flow_state.hpp +98 -0
- netgraph_core-0.1.0/include/netgraph/core/k_shortest_paths.hpp +26 -0
- netgraph_core-0.1.0/include/netgraph/core/max_flow.hpp +56 -0
- netgraph_core-0.1.0/include/netgraph/core/options.hpp +39 -0
- netgraph_core-0.1.0/include/netgraph/core/shortest_paths.hpp +63 -0
- netgraph_core-0.1.0/include/netgraph/core/strict_multidigraph.hpp +69 -0
- netgraph_core-0.1.0/include/netgraph/core/types.hpp +80 -0
- netgraph_core-0.1.0/pyproject.toml +93 -0
- netgraph_core-0.1.0/python/netgraph_core/__init__.py +66 -0
- netgraph_core-0.1.0/python/netgraph_core/_docs.py +559 -0
- netgraph_core-0.1.0/python/netgraph_core/_version.py +5 -0
- netgraph_core-0.1.0/python/netgraph_core/py.typed +0 -0
- netgraph_core-0.1.0/src/cpu_backend.cpp +122 -0
- netgraph_core-0.1.0/src/flow_graph.cpp +136 -0
- netgraph_core-0.1.0/src/flow_policy.cpp +417 -0
- netgraph_core-0.1.0/src/flow_state.cpp +523 -0
- netgraph_core-0.1.0/src/k_shortest_paths.cpp +350 -0
- netgraph_core-0.1.0/src/max_flow.cpp +279 -0
- netgraph_core-0.1.0/src/shortest_paths.cpp +405 -0
- netgraph_core-0.1.0/src/strict_multidigraph.cpp +145 -0
- netgraph_core-0.1.0/tests/cpp/flow_graph_tests.cpp +266 -0
- netgraph_core-0.1.0/tests/cpp/flow_policy_tests.cpp +297 -0
- netgraph_core-0.1.0/tests/cpp/flow_state_tests.cpp +379 -0
- netgraph_core-0.1.0/tests/cpp/k_shortest_paths_tests.cpp +199 -0
- netgraph_core-0.1.0/tests/cpp/masking_tests.cpp +646 -0
- netgraph_core-0.1.0/tests/cpp/max_flow_tests.cpp +1169 -0
- netgraph_core-0.1.0/tests/cpp/shortest_paths_tests.cpp +300 -0
- netgraph_core-0.1.0/tests/cpp/smoke_test.cpp +36 -0
- netgraph_core-0.1.0/tests/cpp/strict_multidigraph_tests.cpp +318 -0
- netgraph_core-0.1.0/tests/cpp/test_utils.hpp +401 -0
- netgraph_core-0.1.0/tests/py/conftest.py +877 -0
- netgraph_core-0.1.0/tests/py/test_api_validation.py +139 -0
- netgraph_core-0.1.0/tests/py/test_batch_max_flow_consistency.py +72 -0
- netgraph_core-0.1.0/tests/py/test_batch_max_flow_masks.py +35 -0
- netgraph_core-0.1.0/tests/py/test_cross_validation.py +348 -0
- netgraph_core-0.1.0/tests/py/test_edge_cases.py +82 -0
- netgraph_core-0.1.0/tests/py/test_ext_edge_ids.py +164 -0
- netgraph_core-0.1.0/tests/py/test_flow_policy.py +285 -0
- netgraph_core-0.1.0/tests/py/test_flow_policy_configurations.py +513 -0
- netgraph_core-0.1.0/tests/py/test_flow_policy_edge_cases.py +408 -0
- netgraph_core-0.1.0/tests/py/test_flow_policy_lifecycle.py +76 -0
- netgraph_core-0.1.0/tests/py/test_flow_policy_masks.py +383 -0
- netgraph_core-0.1.0/tests/py/test_flow_policy_path_distribution.py +532 -0
- netgraph_core-0.1.0/tests/py/test_flow_policy_validation.py +391 -0
- netgraph_core-0.1.0/tests/py/test_graph_from_arrays.py +65 -0
- netgraph_core-0.1.0/tests/py/test_graph_structure.py +27 -0
- netgraph_core-0.1.0/tests/py/test_imports.py +8 -0
- netgraph_core-0.1.0/tests/py/test_ksp.py +89 -0
- netgraph_core-0.1.0/tests/py/test_ksp_variants.py +46 -0
- netgraph_core-0.1.0/tests/py/test_lifetime_safety.py +321 -0
- netgraph_core-0.1.0/tests/py/test_mask_semantics.py +172 -0
- netgraph_core-0.1.0/tests/py/test_mask_validation.py +222 -0
- netgraph_core-0.1.0/tests/py/test_masking_comprehensive.py +653 -0
- netgraph_core-0.1.0/tests/py/test_max_flow.py +299 -0
- netgraph_core-0.1.0/tests/py/test_max_flow_cost_distribution.py +166 -0
- netgraph_core-0.1.0/tests/py/test_max_flow_summary.py +53 -0
- netgraph_core-0.1.0/tests/py/test_paths_resolve.py +67 -0
- netgraph_core-0.1.0/tests/py/test_policy_vs_maxflow_equivalence.py +232 -0
- netgraph_core-0.1.0/tests/py/test_sensitivity.py +91 -0
- netgraph_core-0.1.0/tests/py/test_spf_basic.py +184 -0
- netgraph_core-0.1.0/tests/py/test_spf_edge_select.py +152 -0
- netgraph_core-0.1.0/tests/py/test_spf_masks.py +51 -0
- netgraph_core-0.1.0/tests/py/test_thread_safety.py +345 -0
|
@@ -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.
|