Repository navigation
Conversation
…, from_hops, cost metadata) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…review artefacts Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…ow core Delete the old library (FlowState, the old FlowGraph and FlowPolicy, the backend, the old search entry points and their bindings: 411 symbols, 65 files) and build the first piece of the streamlined Core against APPROACH revision 25: - StrictMultiDiGraph(num_nodes, src, dst, capacity_units, cost, resolution): capacities as int64 units of an explicit resolution, costs >= 1, edges in the canonical (src, cost, dst, input) order so the forward CSR slot is the public EdgeId, input_index() as the only map, to_units (half up) and as_float, validation in the contract's order (resolution, unit values, shapes, costs, bounds) before any narrowing. - The flow core: successive shortest paths with potentials on reduced costs, Dinic phases per tier, forward and reverse arcs interleaved in ascending EdgeId at every node, virtual terminals, a fresh solve from zero on the view, the two-branch behaviour for an input cap of 0, the closure seeded at the real sources; exposed to the recorder through the private _place_global_units entry with the typed payload (placed, cost_distribution, edge_flows, min_cut, potentials with NEVER_REACHED = -1, six int64 counters). - 38 C++ tests (every validation error, B′ order, the review witnesses: attained value, update-before-drain, two Dinic phases in one tier, the legal maximum, the zero-view cap, masks and cost factors) and 154 Python tests. Gates (dev/design/2026-10-streamline/gates/1a/, uncommitted design tree): workspace check and sanitizers green; independent oracle population 3,821 pass / 0 fail; cross-check against the Python reference on 30,000 random graphs identical; the equivalence run against the G0 baseline 0 failures under the 1a manifest rules; inventory: 0 Core callers of any deleted symbol (NetGraph callers pending until Phase 2); construction and max-flow A/B/A rows 23 to 48 percent faster than df3b894. Reviewed adversarially (review-1a, review-1a-fixes): D1 to D4 fixed or settled in the contract. NetGraph is red from this commit until its migration converges (Phase 2), by decision of 2026-10-04. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…search Build the second piece of the streamlined Core on the 1a graph and flow core, against APPROACH revision 27: - FlowGraph: the integer ledger (records as snapshots in FlowId order, residual and allocated views, bottleneck over member edges, reset only unbound), the lifetime table (bound without flows, bound with flows, orphaned records; copy, move, destroy), epochs, ids never reused; a staged, exception-safe commit (every throwing step before one no-throw publication, an epoch-stamped touched set, all-or-nothing scratch growth) with fault-injection tests. - The three kernels in units: MaxFlow as a fresh minimum-cost solve on the view V_i = R0 + own_i with arcs in B' order; Weighted with membership by priority at creation, frozen weights and highest-averages apportionment; EqualBalanced with round robin on a fixed cohort; Admission.Lossy on EB and Weighted (per-call offers, transit drops, +inf injection); split-graph pruning; T_max by bisection with an exact bracket and a checked 62-probe bound. - PredDAG (from_csr with complete validation, predecessors in ascending via EdgeId), Path(g, hops) with to_dag(), Eligibility with intersect. - The internal search: the unique shortest-path DAG over the eligible member graph, anycast pruning, the staged canonical single path with PathSelection projection. - Bindings, _docs.py and stubs for the public classes; 100 C++ tests and 200 Python tests. Gates (dev/design/2026-10-streamline/gates/1b/, uncommitted design tree): workspace check and sanitizers green; oracle population 3,821 pass / 0 fail; check_spf 3,820/3,820; prototype cross-check identical on 45 fixtures and 16,172 random cases; 909 corpus Manual placements equal their references; the equivalence run 0 failures under the 1b rules (no observable change before the policies of 1c); inventory: 0 Core callers of any deleted symbol; A/B/A: construction and max-flow rows 22 to 47 percent faster than df3b894, the five kernel rows 5 to 36 percent faster after the one-pass PredDAG-native route and plan builder; a per-process bimodality of the proportional-grid row (an out-of-line NodeMap::add in the flow core's subset solve whose callee-saved register reloads stalled in some process layouts) fixed by an allocation-free, noexcept, inlined add with a guard test, both grid rows unimodal (-33 and -4 percent). Reviewed adversarially (review-1b, review-1b-fixes, review-1b-fixes2, review-1b-bimodality): D1 to D3, N1, N2 and R15 fixed; D3 settled in the contract (revision 26), R16 in revision 27. NetGraph stays red until its migration converges (Phase 2). Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…to 1c tree coherent and groomed Build the third piece of the streamlined Core on the 1a graph, the 1b ledger and kernels, against APPROACH revision 42, then make the whole 1a to 1c tree coherent and groom its public interface before 1d: - FlowPolicy with the four routing modes (CostOnly, CapacityAware, Global, Pinned), DiminishingReturns, the cost ceiling (Absolute, Stretch), explicit placement, admission and selection; place(volume, outputs) -> PlacementResult (placed, remaining, termination, local outcomes per roster source, the two event-accumulating flags, drops, the cumulative cost curve, edge flows, residual, bottleneck, min cut); remove(), records(), record(id), placed_demand(), usable_bundles(); the roster fixed at construction (9.1); the per-source transaction of 9.2 (cumulative round-robin offers, stages 1 to 4 on a per-thread working overlay, growth never repeating a route on a multipath DAG, T_max probes within the 62-probe bound); the termination reduction and the flag table of 9.4; the epoch law and lifetimes of section 8; Global as the cumulative minimum-cost flow on V = W + own with the canonical decomposition and per-source records; every output prepared before one atomic commit, including the Python result objects (all-or-nothing across worker threads and the binding, APPROACH 13, with its two stated limits: the pybind11 object machinery, and a supplied building DagCache as a memo). - Sparse record bundles over member nodes (R16): the public CSR shape on demand, unchanged supplied bundles shared, the builder's grouping by a stable counting sort. - DagCache in building mode: key (root set, direction, Eligibility uid), value the full static support, statistics (hits, misses, entries, bytes, live values), clear(). - Evaluators: capacity, batch_capacity (arguments first, then each pair completely in pair order; the lowest failing index; explicit per-pair sequences length-checked; Pinned rejected), sensitivity (Global positive-flow candidates, the other models every allowed edge of at least one unit, signed losses, unevaluable with a reason); workers with private caches allocated before any thread starts, noexcept worker bodies, every thread joined before the lowest-index failure is rethrown; the exact shortcuts (Global loss from the baseline's maximum flow, CostOnly off-route edges skipped). - One min-cost flow core with the deletion re-solve as a mode (APPROACH 2.2): the deletion state as a value, working potentials as published potentials plus the running sum of the deletion deltas, 128-bit working arithmetic within the stated bounds, the three fixed-origin repairs with the failed-search reuse; it replaces the separate warm solver and the 1b single-bundle driver (_PinnedFlow, src/pinned_flow.cpp); a one-bundle Pinned FlowPolicy stands in for the latter. - The coherence pass of the whole tree: no dead code, no wrong comment, no leaked abstraction, one implementation per rule; profiling removed; the test probes and trace behind the CMake option NETGRAPH_CORE_PRIVATE_HOOKS (OFF for wheels, ON for the development build and the tests; the OFF build exports no hook, probe or trace symbol); transactional copy assignment of the deletion state; validating constructors for every enumeration-typed option (std::invalid_argument naming the field). - The public interface groomed to one scheme: Graph (was StrictMultiDiGraph), FlowLedger (was FlowGraph) taken by FlowPolicy as ledger=, OutputOptions (was Outputs), DiminishingReturns (was Diminishing), MAX_FLOWS_PER_CALL in Python (kMaxFlowsPerCall in C++); the public headers split so each says what it holds (graph.hpp, eligibility.hpp, flow_record.hpp, flow_ledger.hpp, flow_policy.hpp, evaluators.hpp, dag_cache.hpp, options.hpp with the two placement enums, pred_dag.hpp, types.hpp); Counter128 self-contained, so no public header includes a detail/ header; the private headers and the test files on one naming scheme; the policy fixture data in tests/data/ with a maintained exporter; no alias, no re-export, no adapter of a retired spelling. - The kernel's round robin as one inline callback template (one implementation of the split; the span form a wrapper), so allocate and the Lossy step run in one pass: the coherence pass's two-pass form had cost kernel.eb.grid 11 percent against df3b894; results unchanged. - The kernel plan builder fills its arrays by index into pre-sized vectors instead of push_back: under Xcode 27's libc++ 22 the push_back form cost the kernel rows about ten percent (emplace_back's new fast-path and slow-path lambdas); results unchanged. - Bindings, _docs.py stubs and the Python package for every class and function (keyword-only configuration objects, keep-alive of ledger, Eligibility and cache, the GIL released in the evaluators); pytest collects tests/ only; 157 C++ tests (134 ordinary, 23 in the separate fault executable) and 266 Python tests, with fault-injection sweeps of every growth, publication and deletion path at 1, 2 and 4 workers and at every Python allocation position. Gates (dev/design/2026-10-streamline/gates/1c/, uncommitted design tree), on the final groomed build with the private hooks on and off: workspace check and sanitizers green; the fault executable under the sanitizers; the warning-set builds with 0 diagnostics; the literal equivalence run 0 failures (31,788 unchanged, 28,224 new-api, 14,778 rule, 13,701 new-only; the rest invalid-input, deferred to 1d or absent by rule); oracle population 13,901 pass / 0 fail (ksp and spf queries wait for 1d); every returned value checked and proven by mutation (114,222 corruptions of the accepted results, 0 undocumented survivors); inventory CHECK OK on 1,249 rows, 0 Core callers of any deleted symbol; prototype parity identical on the 1b and 1c drivers (45 and 59 fixtures, 8,412 random cases); every recorded result of the groomed build identical to the pre-grooming build's (20,960 of 20,960) and to the frozen 1c baseline; A/B/A against df3b894 on the final tree (both sides Apple clang 21 build 2100.3.34.2, Xcode 27), 15 of 15 rows: construction -43 and -52 percent, the kernels -3 to -28 (kernel.eb.grid -1.8 within tolerance), capacity -28 and -24, max-flow -13 and -14, sensitivity -8 (the deletion re-solve replacing the separate warm solver) and -92, the CapacityAware cohort rows -61 and -99.6; the new-model rows as target-versus-target A/A, 3 of 3. Reviewed adversarially (review-1c, review-1c-fixes, review-1c-r29, review-resolve 1 to 3, review-audit-1abc, review-coherence, review-coherence-rc, review-naming 1 to 4, review-grooming, review-timing-fixes): F1 to F5 fixed (a worker-thread allocation that escaped to std::terminate, Python publication after the commit, batch validation order, the explicit empty eligibility list, the Global zero call's cumulative curve); the coherence audits' findings fixed and RC1 to RC3 closed; the tooling's twelve gate holes (W11) closed by W12 before these gates ran. NetGraph stays red until its migration converges (Phase 2). Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
- Weighted quota division: a 64-bit division when the dividend fits (kernel.weighted.clos 6 to 8 percent faster). - Graph constructor: stop computing the GCD once it reaches 1 (construct.clos about 4 percent faster). Both measured A/B/A against the 1c build; every result byte-identical; a test for each. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
One traversal core now runs every search. The public spf searches from a set of roots, forward or reverse, optionally stopping at the nearest target. ksp lists the K shortest paths in the contract's order, and resolve_to_paths unfolds a DAG into paths. The DagCache gains a frozen mode that every worker of an evaluator can share. Hits are published when the call succeeds; a call ending in DagCacheMiss counts one miss. The Python bindings cover all of it, and the old search entry points are gone. CostOnly placement builds a new flow's route, record DAG and kernel plan in one pass over the cached support, with a few smaller cuts. NetGraph's MSD loop now takes about 3 % less time than 0.12 instead of 35 % more; results are unchanged. Evidence: after the independent review's fixes, the final gates pass with hooks on and off; the timed SPF rows take 9 to 82 % less time than 0.12. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The Graph constructor numbers the edges with stable counting passes instead of a full sort. Costs are ranked through a hash table that reuses the graph's own arrays; above 65,536 distinct costs, or when the table probes too long, the costs are sorted instead. Results are unchanged; construction takes 21 to 91 % less time than 0.12. An empty NumPy view from a graph accessor now also keeps its graph alive. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The bindings are split by subject, the type stub is generated from the module and checked, and docs/semantics.md states the API's rules, each with a test. A double free when a result object could not be wrapped is fixed, and inputs too large for the flow core are now refused. Dead code and the old research and timing material are gone. Results match accepted 1e with the private hooks on and off; only the field that names the producing build differs. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
One driver times the Core's rows as old build, new build, old build again on one machine, so drift shows, and checks that both builds give the same results. Its own tests run with make perf-tool-test and on one macOS CI job, so a library change that breaks the tool fails there. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- The private test hooks build on Python 3.11 (no PyErr_GetRaisedException before 3.12) and keep the exception object and its traceback. - The rank oracle uses += so the portable 128-bit test integer (MSVC) compiles. - The two large fault sweeps get a 600 s ctest timeout; they finish but run long under sanitizers on small CI machines. - The native allocation sweep accepts a failure that the standard library absorbs (GNU stable_partition's optional buffer) only with the exact reference result, state and live count; its discard control now compares a real reference result. Library code and results are unchanged. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- The few-allocations control plants a call that makes no native allocation on any platform; reset's count depends on the standard library. - The Python allocation sweep's controls advance at snapshot boundaries, so a tracer that fails before a call enters its body cannot shift them. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This branch has not been deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Draft: not to be merged yet. NetGraph still calls the 0.11 API; this merges after NetGraph's migration to it. Opened now to run CI on every platform and to keep the work off one machine.
Summary
A rebuilt Core (breaking, version 0.12.0): one numeric domain (capacities in integer units of an explicit resolution), one minimum-cost flow core, one placement engine. It replaces the 0.11 API;
CHANGELOG.md(Unreleased) lists every change.docs/semantics.mdstating the API's rules (each with a test), dead code and old experiments removed, defects found on the way fixed.dev/perf/: a minimal A/B/A timing tool with its own tests (one macOS CI job).Verification (local, Apple M4 Max)
Not yet run: CI on Linux, Windows and CentOS (this PR), NetGraph integration.
🤖 Generated with Claude Code