The FastPart hypergraph partitioner: a fixed-budget portfolio controller over a pinned, unpatched upstream Mt-KaHyPar, with optional refinement stages.
bash scripts/setup_mtkahypar.sh # clones + builds the pinned engine (6271a58) with its Python module
python3 -m fastpart.cli design.hgr K --eps 2 --time 300 # default mode
python3 -m fastpart.cli design.hgr K --eps 2 --time 600 --kep # with refinement stages--eps is the absolute two-sided imbalance in percent (K=4, ε=2 → every block
holds 23–27 % of the total weight). All vCPUs are used by default
(--threads N to limit). Requires Python 3.10+, numpy, scipy.
The recombination stage (--kep) needs an ILP solver; either of two is
enough, and neither is required to run the solver.
--ilp-backend auto (the default) prefers CPLEX and falls back to OR-Tools
CP-SAT (pip install ortools) when CPLEX is missing or fails at solve
time. That second case is the common one: pip install cplex gives the
Community Edition, whose 1000-variable limit is exceeded by every real border
window, so a pip-CPLEX machine ends up on CP-SAT. A full CPLEX installation
solves the stage directly. Pass cplex or ortools to pin one backend — a
pinned backend never silently switches, and an unavailable one is reported at
startup. With neither installed the stage returns the better original
candidate and everything else runs unchanged.
| Mode | What runs | Suggested --time |
|---|---|---|
| default | the portfolio controller: engine templates, warm follow-ons, feasible-only pool | 300 s |
--kep |
the controller plus the AL-FM and Consensus-and-Clean refinement stages in the tail | 600 s (≈2× default) |
--kep reserves a slice of the budget for the refinement stages rather than
extending the run, so wall time tracks --time in both modes; give it the
larger budget above so the stages are not paid for out of exploration. Every
run reports what actually happened under "stages" in its JSON — whether each
stage ran, how long it took, which ILP backend solved, the disagreement
frontier it worked on, and whether it improved the incumbent.
The refinement stages need room to work: at the default budget they often only
reproduce the controller's incumbent, while at roughly twice the budget they
have produced the best result on some cells. Use the default mode for
budget-bound runs and --kep when quality per instance matters more than
wall-clock.
Titan23, ε = 2 %, K = 2/3/4, default mode, 300 s runs on 112 vCPUs, a median of 3 seeds per cell, against the published FastPart table (best of 20 seeds): 52 of 66 cells at or below the published cut, geometric-mean ratio 1.0027. Every cut is re-scored from the written partition by the independent evaluator (cut-net objective, two-sided absolute balance).
fastpart/controller.py roster, scheduler, pool, three stages
fastpart/engine_runner.py one engine run per subprocess
fastpart/spectral*.py spectral-seed template
fastpart/cnc.py recombination stage
fastpart/alfm.py AL-FM refinement stage
fastpart/repair.py, evaluator.py, hgr.py
presets/ engine presets (stock upstream + mode/rebalancer variants)
scripts/setup_mtkahypar.sh pinned upstream engine build