Skip to content

SPF: ordered bucket queue, reusable workspace, fixed-routing reuse (0.11.0) - #11

Merged
networmix merged 1 commit into
mainfrom
perf/spf-bucket-queue
Oct 2, 2026
Merged

networmix merged 1 commit into
mainfrom
perf/spf-bucket-queue

Conversation

@networmix

Copy link
Copy Markdown
Owner

Summary

Dijkstra in shortest_paths / shortest_paths_to now runs on a monotone bucket queue whenever the graph's edge costs fit 65,536 buckets (max_cost / gcd(costs) + 1), which covers unit, uniform and small-integer cost graphs including zero-cost pseudo attachments; wider or int64-offset costs keep the binary heap. The active bucket is ordered by the same (-bottleneck, node) key as the heap, so the pop order and every output (distances, predecessor order, single-path capacity ties, early exit) are bit-identical. Scratch arrays live in a thread-local workspace reset per search (only the touched nodes when few were touched), removing the O(N) initialisation that dominated small destination-limited searches on large graphs.

Adopted from an independent review of the first version: settled neighbours are skipped before their parallel edges are scanned, the predecessor output is sized from live per-node counts, a frontier of one node is held inline, bucket storage retention is bounded, an exception-path ordering bug was fixed, calc_max_flow / place_max_flow with require_capacity=false compute their cost-only search once per call, and two redundant DAG copies were removed.

Also: StrictMultiDiGraph::max_cost() / cost_gcd(), a trailing SpfQueue parameter on the C++ search functions for tests and benchmarks, NGRAPH_CORE_SPF_QUEUE=heap|bucket, and the developer tooling behind the change under dev/perf/spf_queue/ (plan, parity harness, old-versus-new bit-gate, NetGraph-level benchmark, recorded A/B/A results, review record) plus the preceding Metal GPU research under dev/research/. dev/ is excluded from the sdist. Version 0.11.0.

Measured (old / new / old, fresh processes, Apple M4 Max shared with other sessions)

Class Core level Through NetGraph
Weighted graphs (W 32 to 32,768), forward and reverse 1.4–1.8x 1.16–1.22x
Unit-cost fabrics, pseudo source/sink max-flow 1.2–1.35x SPF 1.3x, max-flow 1.06–1.12x, KSP 1.15x
Near-destination searches 2.7–3.0x —
Heap fallback (W > 65,536), full source 0.94–1.0x —
Path graphs 0.77x (+6 µs on 21 µs) —

Every NetGraph workload digest was identical across old, new and the forced heap route. Details, raw samples and the independent review are in dev/perf/spf_queue/PLAN.md.

Verification

  • Old-versus-new bit-gate over forward/reverse SPF with fanout, calc_max_flow in every placement mode, batch_max_flow, sensitivity_analysis, FlowPolicy sequences and KSP: identical SHA-256 (6,226 output lines), also with the new build forced onto the heap.
  • Harness parity against copies of the previous search loop: 1,351,168 bit-exact comparisons on both routes; the checker rejects a permuted predecessor order.
  • bash .superset/workspace.sh check (lint, types, 177 C++ tests, 466 Python tests), make sanitize-test (ASan/UBSan), NetGraph dev/check_core_integration.sh against this tree (1,278 tests).

🤖 Generated with Claude Code

….11.0)

Dijkstra in shortest_paths / shortest_paths_to runs on a monotone bucket
queue whenever max_cost / gcd(costs) + 1 <= 65536, with the active bucket
ordered by the heap's (-bottleneck, node) key so every output is
bit-identical; wider costs keep the binary heap. Scratch state is a
thread-local workspace reset per search (touched nodes only when few were
touched). Settled neighbours are skipped before their parallel edges are
scanned, the predecessor output is sized from live per-node counts, a
frontier of one node is held inline, and bucket storage retention is bounded.

calc_max_flow / place_max_flow with require_capacity=false compute their
cost-only search once per call; FlowPolicy and the spf bindings move the DAG
instead of copying it. StrictMultiDiGraph gains max_cost() / cost_gcd(); the
C++ search functions take a trailing SpfQueue for tests and benchmarks, and
NGRAPH_CORE_SPF_QUEUE=heap|bucket overrides the choice process-wide.

Verified by an old-versus-new bit-gate (identical SHA-256 over SPF, max-flow,
batch, sensitivity, FlowPolicy and KSP outputs), 1,351,168 bit-exact harness
comparisons on both routes, the C++ differential tests, lint/types, 177 C++
and 466 Python tests, ASan/UBSan, and NetGraph's integration suite (1,278
tests). Measured old/new/old: 1.4-1.8x on weighted graphs, 1.2-1.35x on
unit-cost fabrics, 2.7-3x on near-destination searches at the Core level;
1.06-1.3x through NetGraph. Plan, harness, bit-gate, benchmark, recorded
results and the independent review live under dev/perf/spf_queue; the
preceding Metal GPU research under dev/research. dev/ is excluded from the
sdist.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Oct 2, 2026 •

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review ✅ Completed 2026-10-02T02:41:17.626808Z ed00980 PR opened
ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

@networmix
networmix merged commit d5717cc into main Oct 2, 2026
29 of 32 checks passed
@networmix
networmix deleted the perf/spf-bucket-queue branch October 2, 2026 03:23
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant