Skip to content

Implement the public API audit#44

Merged
fpedd merged 1 commit into
mainfrom
refactor/api-audit
Jul 17, 2026
Merged

Implement the public API audit#44
fpedd merged 1 commit into
mainfrom
refactor/api-audit

Conversation

@fpedd

@fpedd fpedd commented Jul 17, 2026

Copy link
Copy Markdown
Owner

Land the rulings of research/api-audit.md across the Python and C++
surface: one vocabulary, flat functions at the boundary, noun-phrase
queries, flat allocator kwargs, renamed entry points, and omni as the
default allocator.

Vocabulary (R1): "conflict" names the happens-before constraint,
"overlap" stays reserved for realized rectangle collisions.
Allocation.overlaps_temporally becomes conflicts_with; the C++ tree
renames in lockstep (ConflictMap, conflict_degrees,
SortKey.CONFLICTS/DURATION/START/END); the conflict map is now total,
so the Python wrapper's .get() patching dissolves.

Binding surface (R4-R6, R14, R16, R17): the boundary carries data types
and flat functions only. The stateless *AllocatorCpp classes become
*_place functions with default-free parameters - Python owns every
policy default. Failures use builtin exceptions only: budget exhaustion
raises RuntimeError, a missing optional dependency raises ImportError -
BudgetExceededError, OptionalDependencyError, the Option unions, and
the Python-side patching all dissolve. try_solve_many binds the search
switches flat with max_nodes: int | None (None = unbounded); Solution
reshapes to .allocations/.peak; clique_cap and Allocation.with_kind
delete codebase-wide. FirstFitPlacer rejects repeated order indices
alongside out-of-range ones.

Query names (R2, R9, R13, R15): pure queries are noun phrases -
conflicts, conflict_degrees, pressure, closure_pressure,
placement_pressure, with *_per_allocation variants on both sides of the
boundary. The top level narrows to conflicts, pressure, and
try_linearize; the full family lives in omnimalloc.analysis.
greedy_base's duplicate peak/conflict sweeps dissolve into the analysis
queries; conflict_degrees counts scalar timelines in O(N log N) via two
binary searches, skipping the pairwise sweep; README and examples adopt
import omnimalloc as om.

Allocator ergonomics (R7, R8, R11, R14): flat keyword-only constructor
kwargs replace the four config dataclasses (scikit-learn style), with a
shared self-describing repr; common/validation.py and
common/parallel.py spell the numeric precondition checks and the
num_threads: int | None = None convention once; registry names strip
the class-role token as a suffix only ("greedy_by_size");
GeneticAllocator's num_generations becomes max_generations. The 8 *Cpp
greedy twin classes are removed - two spellings of one code path
measuring nothing. Flat plain-typed kwargs make every allocator
picklable, so allocate_parallel submits configured variants directly
instead of rejecting them.

Entry points (sections 5 and 6): run_allocation becomes
omnimalloc.allocate(pool); validate_allocation(entity) -> None is
raise-only; plot_allocation(entity, path=None) displays or saves, and
plot_benchmark(artifact, path=None) matches; dump_allocation becomes
save_allocation (module io.py) and round-trips placements through the
new offset column, written whenever any allocation is placed;
the minimalloc benchmark source loads through io.load_allocation;
Memory.size becomes capacity; BufferKind becomes AllocationKind, C++
enum included.

DEFAULT_ALLOCATOR becomes "omni": never worse than greedy_by_size on
any benchmarked case (geomean peak ratio 1.0972 vs 1.1675), certified
optimal on three of seven, vector-clock capable, and the same order of
runtime.

@fpedd fpedd changed the title refactor/api audit Implement the public API audit Jul 17, 2026
@fpedd
fpedd force-pushed the refactor/api-audit branch 4 times, most recently from e366074 to 369b56b Compare July 17, 2026 22:07
Land the rulings of research/api-audit.md across the Python and C++
surface: one vocabulary, flat functions at the boundary, noun-phrase
queries, flat allocator kwargs, renamed entry points, and omni as the
default allocator.

Vocabulary (R1): "conflict" names the happens-before constraint,
"overlap" stays reserved for realized rectangle collisions.
Allocation.overlaps_temporally becomes conflicts_with; the C++ tree
renames in lockstep (ConflictMap, conflict_degrees,
SortKey.CONFLICTS/DURATION/START/END); the conflict map is now total,
so the Python wrapper's .get() patching dissolves.

Binding surface (R4-R6, R14, R16, R17): the boundary carries data types
and flat functions only. The stateless *AllocatorCpp classes become
*_place functions with default-free parameters - Python owns every
policy default. Failures use builtin exceptions only: budget exhaustion
raises RuntimeError, a missing optional dependency raises ImportError -
BudgetExceededError, OptionalDependencyError, the Option unions, and
the Python-side patching all dissolve. try_solve_many binds the search
switches flat with max_nodes: int | None (None = unbounded); Solution
reshapes to .allocations/.peak; clique_cap and Allocation.with_kind
delete codebase-wide. FirstFitPlacer rejects repeated order indices
alongside out-of-range ones.

Query names (R2, R9, R13, R15): pure queries are noun phrases -
conflicts, conflict_degrees, pressure, closure_pressure,
placement_pressure, with *_per_allocation variants on both sides of the
boundary. The top level narrows to conflicts, pressure, and
try_linearize; the full family lives in omnimalloc.analysis.
greedy_base's duplicate peak/conflict sweeps dissolve into the analysis
queries; conflict_degrees counts scalar timelines in O(N log N) via two
binary searches, skipping the pairwise sweep; README and examples adopt
`import omnimalloc as om`.

Allocator ergonomics (R7, R8, R11, R14): flat keyword-only constructor
kwargs replace the four config dataclasses (scikit-learn style), with a
shared self-describing __repr__; common/validation.py and
common/parallel.py spell the numeric precondition checks and the
num_threads: int | None = None convention once; registry names strip
the class-role token as a suffix only ("greedy_by_size");
GeneticAllocator's num_generations becomes max_generations. The 8 *Cpp
greedy twin classes are removed - two spellings of one code path
measuring nothing. Flat plain-typed kwargs make every allocator
picklable, so allocate_parallel submits configured variants directly
instead of rejecting them.

Entry points (sections 5 and 6): run_allocation becomes
omnimalloc.allocate(pool); validate_allocation(entity) -> None is
raise-only; plot_allocation(entity, path=None) displays or saves, and
plot_benchmark(artifact, path=None) matches; dump_allocation becomes
save_allocation (module io.py) and round-trips placements through the
new offset column, written whenever any allocation is placed;
the minimalloc benchmark source loads through io.load_allocation;
Memory.size becomes capacity; BufferKind becomes AllocationKind, C++
enum included.

DEFAULT_ALLOCATOR becomes "omni": never worse than greedy_by_size on
any benchmarked case (geomean peak ratio 1.0972 vs 1.1675), certified
optimal on three of seven, vector-clock capable, and the same order of
runtime.
@fpedd
fpedd force-pushed the refactor/api-audit branch from 369b56b to 882a062 Compare July 17, 2026 23:03
@fpedd
fpedd merged commit a89aa4d into main Jul 17, 2026
12 checks passed
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