Plan: the short roadmap#
This is the living plan of dynG in short form: what the library is, the decisions it rests on,
the milestones with their exit criteria, the risks and the open decisions. The full planning
record (the design of every module, the per-algorithm migration plans, the review history) is
the approved planning document of 2026-09-27, which is not published; as each milestone starts,
the part it needs moves into a design page under docs/developer/. Maintainer records (the
ADRs, the retrospectives, the repository-settings guide, comments in the workflows) cite it as
“PLAN Section N”; contributor documentation does not depend on it. Decisions that
change are recorded as ADRs (Architecture Decision Records), progress and re-estimates in the milestone
retrospectives (Milestone retrospectives). The public, user-facing version is
Roadmap.
Status: 2026-10-14. M1a, M1b (CUDA sssp), M2 (cycle_count), M3 (the framework, the
conformance kit and the 0.1 API freeze), M4 (this infrastructure) and M5 (the Python package, a
CPU wheel, the dyng command line and the documentation of 0.1; pull request #4, merged at
8842acf) are done and merged into main. 0.1.0 is released: the release preparation R010
made the release candidate 0.1.0rc1 (pull request #5, on TestPyPI; Retrospective: R010 (release preparation for 0.1.0rc1)),
and the final-release pull request R011 made 0.1.0 with the certificate carried over
(Retrospective: R011 (the final-release pull request for 0.1.0); the checklist: Release process); R012 set the release date to the tag
day, 2026-10-02, and recorded the author’s last decisions (Retrospective: R012 (the tag day of 0.1.0)). After
the release the author re-grouped the next releases into smaller steps (2026-10-02, recorded in
GOVERNANCE.md): 0.2.0 is M7 (mosp and the sssp operators engine; merged into main by
pull request #8) plus M6 (the hardening planned as 0.1.x), which runs as two parallel milestones,
M6a (the CUDA plugin wheels) and M6b (the tutorial algorithms, the documentation on GitHub Pages,
fuzzers, mutation checks, sanitizer jobs; Retrospective: M6b (hardening for 0.2.0)), merged by pull requests #9
and #10. 0.2.0 is released: the release preparation R020 made the release candidate
0.2.0rc1 (pull request #11, on TestPyPI; Retrospective: R020 (release preparation for 0.2.0rc1)), and the final-release pull
request R021 made 0.2.0 with the certificate carried over, after the smoke test of 0.2.0rc1 and
both CUDA plugins from TestPyPI (Retrospective: R021 (the final-release pull request for 0.2.0); the release date 2026-10-14, the
planned tag day); 0.3.0 is M8 and M9 (the hypergraph and
triad_count; M8 runs as M8a, the ESCHER CBST store, and M8b, the hypergraph container);
0.4.0 is M10 and M11 (label_propagation, hyper_sssp).
1. What dynG is#
dynG is one C++17/CUDA library, with Python bindings designed in, that keeps the results of graph and hypergraph algorithms up to date while the structure changes in batches, without recomputing from scratch. It unifies six research repositories of the author (S M Shovan, with Arindam Khanda, S M Ferdous, Sanjukta Bhowmick, Anurag Satpathy and Sajal K. Das) into one library:
Algorithm |
Origin (pinned commit) |
Paper |
|---|---|---|
|
MOSP-OpenMP@c352151, MOSP-CUDA@e220ee2 |
DynaMOSP (IPDPS 2025, TPDS 2025) |
|
CycleEnumeration-GPU@0a976ad |
TruCy / DynTruCy (IEEE TC, submitted) |
|
MOSP-CUDA, MOSP-OpenMP |
DynaMOSP |
|
ESCHER-GPU@abcf9b2, MOSP_ESCHER@4b86159 |
ESCHER (IPDPS 2026), ESCHER+ (TKDE 2026) |
|
LabelPropagation-CUDA@a276a3a |
DynLP (ICS 2026) |
|
MOSP_ESCHER@4b86159 |
H-SOSP (IA3 at SC 2026) |
The shape of the library in one paragraph: the public side is API-first in the RAPIDS style
(one resources handle, one graph type, one hypergraph type, one batch type per structure, and
the same compute / update verbs, options, result and stats types for every algorithm);
the inside is framework-first in the Gunrock style (every algorithm is an instance of the
thesis Chapter 3 update template, The update model; hand-fused paper kernels run
as fused engines inside the same pipeline); the process is contributor-first (a mandatory
sequential reference backend, a start-green scaffold, a conformance kit, maturity levels, ADRs).
The originals stay untouched; every port is proved byte-identical to its pinned commit.
Who it is for#
User |
What they need |
|---|---|
Researchers who use dynamic algorithms (Python, notebooks, PyTorch/CuPy) |
|
C++ / HPC developers who embed it |
|
Researchers who write update algorithms |
a template, a scaffold that is green on day one, a CPU path without a GPU, a documented framework, conformance tests |
Paper reviewers and readers |
reproducible benchmark suites, honest “paper vs code” notes, citable releases (DOI) |
What makes it one library#
One contract (the same five names per algorithm), one container and one batch type per
structure, one update pipeline, one shared engine where algorithms share one (the SSSP engine
serves sssp, mosp and hyper_sssp; the signed recount serves cycle_count and
triad_count), one vocabulary (errors, profiler stage names, statistics, CLI verbs, page
sections), one style and one test kit. Each is enforced by code, tests or review.
Non-goals for 0.x#
Distributed memory and multi-GPU; HIP or SYCL backends (the maintainers will not build these; a contributor-led proposal is welcome, see the end of Section 3); a general static analytics library (Gunrock and cuGraph exist); graph databases or persistence; floating-point weights for shortest paths; reproducing paper claims the code never implemented (the kappa-truncated TruCy search, incident-vertex and temporal triads, the insert-only MOSP of thesis Chapter 5, open h-motifs: these are roadmap items and the docs say plainly that they are missing); kNN graph construction (a Python recipe instead); a C API before 1.0.
Success criteria#
Every port matches its fixed original exactly (byte-identical outputs or bit-identical counts), or within a documented, calibrated tolerance where the original is non-deterministic; approximate algorithms are also checked against a converged reference.
Built with the
paritypreset on the reference GPU (RTX A5000, sm_86, CUDA 13.1), every port is within 5 % of the original on paper-timed regions of 10 ms or more, and within 10 % on shorter regions and end to end.pip install dyngworks without a GPU;pip install "dyng[cu13]"adds CUDA.The 1.0 criterion: an outside contributor adds an algorithm using only the documentation.
2. Decisions#
The decisions at a glance (D1-D17 of the plan), with the author’s decisions at approval (2026-09-27), which override the plan’s earlier defaults:
Topic |
Decision |
|---|---|
Name |
dynG; identifiers |
Home |
GitHub organization |
License |
Apache-2.0 + |
IP and consent |
the university IP office asked for the code to be public (cleared); no consent gating of ports: a port is published as soon as it passes its gates |
History |
fresh git history; provenance through file headers and |
PyPI |
|
Contact |
|
Toolkit |
C++17 (CI also C++20); CUDA >= 12.4 for source builds; CMake >= 3.30; GCC >= 11 / Clang >= 15; Python >= 3.12 |
Layout |
RAPIDS-style |
Naming |
snake_case, no |
Contract |
|
Several results |
|
Backends |
|
Framework |
the thesis template as a CRTP |
Performance |
straight port first, refactor commit by commit; fused engines allowed; gates 1.05x / 1.10x |
Python |
nanobind + scikit-build-core; CPU wheel |
Docs |
Doxygen XML -> Breathe -> Sphinx (MyST, pydata theme), Diataxis; hosted on GitHub Pages, https://dyng-dev.github.io/dyng/ (the author’s decision of 2026-10-02: the plan’s fallback to Read the Docs) |
Versioning |
SemVer from 0.1.0, one |
Contributions |
DCO sign-off for external contributors (no CLA; maintainers exempt, M4 retrospective), Contributor Covenant 3.0, private vulnerability reporting, per-algorithm CODEOWNERS |
Execution |
“execute entirely”: milestone by milestone; the author is asked only for account-level actions (GitHub, PyPI, Read the Docs, Zenodo) and real blockers |
The approval checkpoints (ADR 0014): A1 (create the GitHub home) and A2 (public) are approved;
A3 (PyPI name reservation) is approved and done; of A4, the documentation hosting is decided
(GitHub Pages, 2026-10-02; Read the Docs is not connected) and Zenodo is not connected for 0.1.0
(2026-10-01); Zenodo for later releases, conda-forge (0.4) and a domain are still to be asked;
A5 (per-port consent) is not needed. Every approval is
logged in GOVERNANCE.md.
3. Milestones#
M0 decisions ─► M1a CPU sssp ─┬─► M1b CUDA sssp ─┐
└─► M2 cycle_count ─┴─► M3 framework + 0.1 API freeze ─┐
A1 ─► M4 GitHub infrastructure (parallel with M1-M3) ─────────────────────────────────┴─► M5 Python, CLI, docs ─► 0.1.0
0.1.0 ─► M7 sssp operators + mosp │ M6a CUDA plugin wheels │ M6b hardening ─► 0.2.0
0.2.0 ─► M8a ESCHER store ─► M8b hypergraph container ─► M9 triad_count ─► 0.3.0
0.3.0 ─► M10 label_propagation │ M11 hyper_sssp ─► 0.4.0 ─► 0.5 ─► 0.6 (framework public) ─► 1.0
Milestone |
Deliverables |
Exit criteria |
Status |
|---|---|---|---|
M0 Decisions and drafts |
LICENSE, NOTICE, CITATION.cff, AUTHORS, README; the 0.0.1 package and its workflow; the provenance record |
drafts reviewed; A1 and A3 answered |
done (the provenance record, Provenance and copyright holders, was written in M4; the NOTICE wording confirmed as drafted by the author on 2026-10-01, O3) |
M1a Walking skeleton: CPU |
repository, presets, minimal core, |
byte-identical to MOSP-OpenMP@c352151 on the small corpus; updated CSR byte-equal to |
done (495/495 golden cases byte-identical on every CPU backend) |
M1b CUDA |
CUDA build, streams, CCCL-shaped memory resources, device buffers; resident device graph; the persistent cooperative kernel behind |
byte parity with MOSP-CUDA@e220ee2 and CUDA = OpenMP = sequential; the performance gate on roadNet-PA/CA, rgg_n_2_20_s0, road_usa |
done (495/495 golden cases byte-identical on the CUDA backend; gates recorded in the M1b parity certificate; ADR 0009 fixes |
M2 |
sorted-rows / set-semantics preset, the CycleEnum parser, static Johnson and the update on 3 backends, work queue, ported tests, randomized parity suites |
bit-identical histograms on the golden corpus; generator identity; performance gate (DD, GitHub, Twitch, COLLAB); two recorded mutations fail |
done (M2a, the CPU backends, and M2b, CUDA: bit-identical to CycleEnumeration-GPU@0a976ad’s OpenMP and CUDA backends on their golden corpora, cross-backend equal; every OpenMP gate met, every CUDA gate met in both scopes (the COLLAB update read at the base clock lock, ADR 0021, accepted 2026-09-29); device memory equal to the original’s; on the branch |
M3 Framework extraction + 0.1 API freeze |
|
both algorithms pass the kit on every backend with parity and performance unchanged; the scaffold is green on first build; the API review recorded |
done (merged into |
M4 GitHub repository and infrastructure (parallel) |
community files, issue forms, PR template, CODEOWNERS, labels, DCO; workflows |
hosted workflows green; a contributor goes from clone to green build with the documented commands |
done (merged into |
M5 Python CPU wheel, CLI, docs for 0.1 |
root |
pytest green against the goldens; |
done on |
0.1.0 |
the release preparation R010: the benchmark-suite records, the parity certificate, |
the release checklist, including the parity certificate |
done (R010, Retrospective: R010 (release preparation for 0.1.0rc1): 0.1.0rc1 with its certificate, on TestPyPI; R011, Retrospective: R011 (the final-release pull request for 0.1.0): |
M6 hardening (planned as 0.1.x; now part of 0.2.0), run as M6a and M6b |
CUDA plugin wheels; the tutorial algorithms |
|
see M6a and M6b |
M6a CUDA plugin wheels |
|
|
done (ADRs 0030-0032; merged by pull request #9, |
M6b hardening |
the tutorial algorithms and “Your first dynamic algorithm”; the documentation on GitHub Pages; reader fuzzers; the cycle_count and mosp mutation suites; the Hypothesis profile |
tutorials pass the kit on every backend; mutations fail as expected; sanitizer and fuzz jobs green |
done on |
M7 |
the multi-kernel engine as the non-cooperative fallback; composition over K x |
fused == operators byte-identical; byte parity of all MOSP CLI outputs; performance gate |
done on |
0.2.0 |
M7 + M6 (M6a, M6b); the release preparation R020 and the final-release pull request R021 |
release checklist |
done (R020, Retrospective: R020 (release preparation for 0.2.0rc1): the mosp API review and freeze, ADR 0035; the mosp benchmark suite; 0.2.0rc1 with its certificate, on TestPyPI; R021, Retrospective: R021 (the final-release pull request for 0.2.0): the smoke test of 0.2.0rc1 and both plugins from TestPyPI, |
M8 ESCHER store + hypergraph, run as M8a and M8b (a planning change of 2026-10-07, reported to the author: both stay in 0.3.0) |
see M8a and M8b; together they carry every item of PLAN 11.3’s M8 row |
see M8a and M8b |
see M8a and M8b |
M8a the ESCHER CBST store (internal) |
reference builds and additive link-time CBST trace recorders of ESCHER-GPU@abcf9b2 and MOSP_ESCHER@4b86159 (ADR 0036), the trace goldens and batch dumps of both originals’ suites, coauth-DBLP and DBLP; the CBST host model |
CBST trace replay identical for both originals’ policies after every merge step; the 9 CBST scenarios; kernel-path coverage; the host model agrees 100% with both originals; store memory <= 1.05x on coauth-DBLP |
done on |
M8b the hypergraph container |
|
container-level id parity with both originals; integrity after every batch; device memory <= 1.05x; the header freeze |
done on |
M9 |
wedge engine, h-motif patterns, reference backends, experimental |
exact counts and deltas on the golden batches; “baseline + deltas == recount”; performance gate; memory <= 1.05x |
|
0.3.0 |
M8a + M8b + M9 |
release checklist |
|
M10 |
slotted / slack row layouts, vertex batches, the DynLP pipeline, IrLP, the harmonic reference oracle |
generator byte identity; damped byte parity; calibrated in-place tolerances; performance gate 50K-5M |
|
M11 |
|
distances and parents by id; line-graph delta equality; the seven mutations fail; performance gate |
|
0.4.0 |
M10 + M11; conda-forge ( |
release checklist |
|
0.5.0 |
OpenMP incremental |
parity and performance for every new piece |
|
0.6.0 |
the framework promoted to |
three algorithms share each promoted piece without loss |
|
1.0.0 |
API freeze of core and stable algorithms; ABI checks; optionally a JOSS paper |
an outside contributor has added an algorithm using only the docs |
Later, open to contributors through the new_algorithm issue form: the kappa-truncated cycle
search (as an explicitly approximate mode); time-window and temporal cycle updates; the
insert-only MOSP of thesis Chapter 5; incident-vertex and temporal triads; open h-motifs; an
implicit line-graph policy; new dynamic algorithms (k-core, connected components, PageRank,
BFS); a HIP backend; multi-GPU only if a research need appears.
4. Estimate (re-estimated after M3; the releases after 0.1.0 after M6b)#
The plan estimated 0.1 at 12-17 working weeks. With the AI assistant doing the coding, each port of a good original (M1a, M1b, M2a, M2b) took about a day of wall-clock time including its gates, and M3 (the framework, both migrations, the kit, the scaffold and the API freeze) one long day for its five steps; each independent review found real defects (M1a 25, M1b 19, M2a 16) and took about half a day more to fix. What dominates now is measurement time on the one shared machine (the exclusive perf lock, other users’ jobs, the GPU’s power cap; a full M3 campaign is four to five hours of lock time), reviews and their fix steps, the author’s decisions and account actions, and merges of parallel branches (details: the M3 retrospective):
Milestone |
Plan (working weeks) |
Focused effort, incl. review and fix |
Calendar, incl. author gates |
Main risk |
|---|---|---|---|---|
M1a, M1b, M2, M3, M4 |
9-13 |
done (M3’s review and fix step: 0.5-1 day) |
||
M5 Python, CLI, docs |
2-3 |
done in 1 day (3 steps) |
the first hosted runs of |
|
0.1.0 |
12-17 |
the release steps only (R010; the RC tag, smoke installs, the final tag, pushed by the AI assistant on the author’s behalf) |
days, until the author approves the PyPI deployment |
the release approval |
0.2.0 (M7 |
6-9 |
M7 about 2 days, M6b about 1.5 days (three steps), M6a in parallel; then the merges, the hosted runs of the new workflows and the release steps |
1-2 weeks from 2026-10-06 |
the first hosted runs of the plugin wheels, |
0.3.0 (M8a ESCHER store: done, about 2 days of focused effort for its five steps; M8b hypergraph container: done, its five steps in about one day; M9 |
5-8 |
1.5-2 weeks (re-baselined after M8b: M9 about 3-5 days more, plus the review and fix steps of M8b and M9) |
3-4 weeks |
the container’s id parity with both originals; the line-graph merge (A’s H2H inputs are hash-only in the goldens); the nsys memory peak gated in M9; layout control in the parity preset |
0.4.0 (M10 |
8-12 |
1.5-2.5 weeks |
4-6 weeks |
DynLP’s calibrated float tolerances and slotted/slack layouts; conda-forge review time |
Up to 0.4.0 |
about 31-46 (0.1.0 included) |
about 3-4.5 weeks after 0.1.0 |
about 8-12 weeks after 0.1.0 |
The calendar column assumes the author reviews at each gate within a few days. The estimate is revisited in each milestone retrospective (the latest: Retrospective: M8b (the hypergraph container)).
5. Risks#
The risks that shape the plan (the planning record lists 23), with their mitigations:
Risk |
Mitigation |
|---|---|
Performance loss from layering (dispatch, templated hooks, resident apply, version checks, extra syncs) |
dispatch once per call; straight port first; fused engines (Tier B); per-commit gates; SASS and register diffs |
The framework is bent by later algorithms (DynLP, H-SOSP in 0.4) |
internal-stable until 0.6; extracted from two real, opposite algorithms; the rule of two; changes by ADR |
Public API designed before the ports turns out wrong |
only the 0.1 headers are frozen; the rest are reviewed sketches; 0.x allows breaks with migration notes |
The CBST merge (two diverged copies, two policies) |
trace replay against both originals before |
|
|
No GPU CI (shared lab machine) |
manual |
Paper-vs-code gaps |
a mandatory “Differences from the paper” section on every algorithm page; names say what is computed |
Maintainer bandwidth |
small tooling surface; release automation; maturity levels; Discussions for support; a 7-day review target, not a promise |
Scope creep |
the walking skeleton first; 0.1 is two algorithms and a CPU wheel; exit gates per release; retrospectives re-scope |
Parity evidence lost |
persistent |
6. Open decisions#
Each has a recommended default, so work proceeds; it is recorded as an ADR when taken.
# |
Decision |
Default |
Needed by |
|---|---|---|---|
O6 |
default |
decided by the M1b benchmark: int32 with checked construction if int64 costs > 3 % (ADR 0009) |
end of M1b |
O11 |
GPU CI |
manual |
after IT answers |
O24 |
|
0.2; in 0.1 a clear |
M1b |
O27 |
oracle of approximate algorithms |
a converged reference within a tolerance derived from the stopping rule |
M3 (kit), M10 |
O18 |
governance |
lead maintainer until three active maintainers |
M4 |
O15 |
changelog mechanics |
hand-edited |
M4 |
— |
milestone merges |
through pull requests (the review rules of |
M4 |
O23, O28, O7 |
Python floor, wheel scheme, CPU wheel |
Python 3.12; CPU |
M5 |
O14 |
docs hosting |
decided 2026-10-02: GitHub Pages (the plan’s fallback; Read the Docs not connected), deployed by |
M6 |
O8, O17 |
CUDA wheels, oldest GPU |
plugins |
M6a |
O21 |
0.2 if the CBST merge runs late |
settled by the re-grouping of 2026-10-02: |
M8 |
O16 |
hypergraph |
decided 2026-10-07 by the author: |
M8 |
O9, O10 |
DynLP default mode, kNN construction |
the published setup; a Python recipe |
M10 |
O12 |
H-SOSP engine |
the shared |
M11 |
Closed at approval: the name (O1), the license (O2), the GitHub home (O1′), the local path
(O19), history import (O22), privacy until IP clearance (O26: public now), the contact address
(O13), the algorithm names (O4: sssp, cycle_count, hyper_sssp), type-name style (O5), row
order and multigraph semantics (O25; ADR 0010), publishing before consent (O20: not needed).
Closed later: the NOTICE institution line and years (O3: confirmed as drafted, 2026-10-01,
GOVERNANCE.md).
7. How this plan changes#
This page is updated at the end of each milestone, from its retrospective. A changed decision gets an ADR (old ADRs are marked superseded, never rewritten); a scope change or re-estimate is made in the retrospective, not in the middle of a port. A version number only guarantees behaviour once it is released: before 0.1.0 anything can change; after it, SemVer applies.