Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
4 changes: 4 additions & 0 deletions .editorconfig
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,10 @@ charset = utf-8
indent_style = space
indent_size = 2

# Python sources and tools use the existing four-space convention.
[*.py]
indent_size = 4

# Makefiles need to use Tab indentation
[Makefile*]
indent_style = tab
28 changes: 28 additions & 0 deletions .github/pr/solver-parity-commit.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
Add optional optimization APIs and automatic native strategies

Introduce Gecode::Optimize owning sparse models, explicit result guarantees,
starts, exchange, sessions and reusable optimization workflows. Supply numerical
LP/MILP and bounded weighted-square continuous QP through HiGHS, plus an exact
native integer bridge retaining supported globals and documented C/Python APIs.

Select compatible checked LP, cover cuts and branching automatically. Compose
bounded exact presolve, independent components and identical-column symmetry.
Restore original witnesses, offsets and proofs under one shared solve budget.
Use rolling knapsack value rows and packed traceback with work/memory/time caps.

Add opt-in sequential strategy racing in C++, with configurable exploration.
Probe automatic and ordinary native search, select from checked incumbents and
bounds, and restart under the remaining shared time/node/cancellation budget.
Preserve the best probe result. Explicitly document increased CPU/solve-time
costs and the possibility of discovering a much better strategy for longer solves.
Do not expose the new racing option through MiniZinc yet; add no conflict learning.

Validation: complete isolated Release build and 75/75 CTest entries pass;
focused racing checks pass without checked LP and without native backends.
Exhaustive original-oracle, shared-budget and larger-generator checks pass.
Preserve historical observations and add the final three-cohort comparison:
original pre-algorithm native runtime, current automatic racing and frozen
family presets. Expand to observed failed upper inputs without study ceilings,
then refine and confirm sampled brackets. Charge exploration to the same ten
seconds and retain all witnesses, outcomes, settings and provenance. State
nonmonotonicity, backend-reported optimality and combined-policy attribution.
69 changes: 69 additions & 0 deletions .github/pr/solver-parity.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
# Add optional optimization APIs and automatic native strategies

Add `Gecode::Optimize` for applications that need owning optimization models,
explicit result guarantees and reusable solve workflows. Native integer solving
now chooses suitable strengthening automatically. An opt-in race can compare
that policy with ordinary Gecode search before committing the remaining budget.
Existing Gecode modeling, propagation and search interfaces remain available.

## Changes

- Add sparse models, starts, LP/MPS exchange, sessions, ordered objectives,
diagnostics, repair, pools, scenarios and documented C/Python bindings.
HiGHS supplies numerical LP/MILP and bounded weighted-square continuous QP;
the native bridge retains its exact integer subset and supported globals.
- Add checked LP deductions, verified cover cuts, frontier search, reliability
branching and bounded binary neighborhoods. Structural native selection uses
compatible mechanisms without problem-family labels or reference objectives.
- Compose bounded exact presolve, independent components and symmetry constraints
for identical columns. Restore original coordinates and objective offsets;
incomplete component solutions never become full-model incumbents or proofs.
- Strengthen eligible binary knapsack models with exact DP, rolling value rows
and packed traceback. Separate work, memory and local time caps provide a
fallback to native search, with independently checked original witnesses.
- Add `NativeRaceOptions` and `solve_native_race` in C++. Two bounded sequential
probes compare the automatic policy and ordinary BAB. Selection uses validated
incumbents and valid bounds; the chosen strategy restarts under the same global
time, node and cancellation budget. Keep the best original incumbent and bound
even if restarting makes no progress.

Racing is opt-in: the ordinary automatic dispatcher does not silently enable it.
Exploration and restarting can increase total CPU work or solve time. Configurable
trials of several seconds or longer may pay off by finding a much better strategy
for the remaining solve. Early progress is a heuristic, not a speedup guarantee.
The new racing option is not exposed through MiniZinc/FlatZinc yet. No conflict
learning or parallel racing is added.

## Validation and measured limits

The complete isolated Release build passes **75/75 CTest entries**, including
FAST. Focused racing checks also pass without checked LP and without native
backends. Exhaustive min/max oracle checks cover strategy selection, shared node
limits, retained exact results, starts and interruption. Generator checks preserve
every historical input's JSON and text bytes and independently validate larger
feasible witnesses. Earlier sanitizer validation remains separately documented;
this racing change does not claim a new sanitizer run.

The [final benchmark](../../docs/solver-parity/FINAL-BENCHMARK.md) compares the
preserved pre-algorithm Gecode runtime, current automatic racing and frozen
family presets. Ten seconds includes all exploration and restarting. Each
configuration expands until an observed failed upper size, then refines the
bracket to adjacent sizes or approximately 2% for larger inputs. Both repetitions
and every knapsack variant must pass at the reported lower size. All initial
observations remain in the amended, uncapped study.

These are seeded-instance brackets, not mathematical maximum-size guarantees.
Original witnesses are independently checked; large-instance exact optimality is
backend-reported. The same families informed development and preset selection.
The comparison measures combined policies, not an ablation establishing that
racing alone caused the gains. Historical studies remain separate.

General MIQP/QCP/nonlinear optimization and production learning remain outside
scope. Remote platform CI and a rebuild of the older wheel are still pending.

## Review base

Compare `codex/solver-parity-pr` with `codex/solver-parity-base` (`e10562fd9`), the
preserved pre-project source snapshot. The review branch contains the same final
tree as `codex/solver-parity` in one commit over that base. The prerequisite base
must be available in the target repository before opening the upstream PR.
49 changes: 49 additions & 0 deletions .github/workflows/fast-windows-containment.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
name: Pending Windows FAST containment

on:
workflow_dispatch:
pull_request:
paths:
- 'experiments/optimize/*containment*.py'
- 'experiments/optimize/*fast_regression.py'
- '.github/workflows/fast-windows-containment.yml'
push:
branches: [main, 'release/**']
paths:
- 'experiments/optimize/*containment*.py'
- 'experiments/optimize/*fast_regression.py'
- '.github/workflows/fast-windows-containment.yml'

permissions:
contents: read

defaults:
run:
shell: cmd

jobs:
containment:
name: Real Job Objects / Python ${{ matrix.architecture }}
runs-on: windows-2022
timeout-minutes: 5
strategy:
fail-fast: false
matrix:
architecture: [x64, x86]
steps:
- uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0
with:
persist-credentials: false
- uses: actions/setup-python@v5
with:
python-version: '3.12'
architecture: ${{ matrix.architecture }}
- name: Record runtime and verify architecture
run: >-
python -c "import os,platform,struct; print(platform.platform(),platform.python_version(),struct.calcsize('P')*8); assert os.name=='nt'; assert struct.calcsize('P')=={'x64':8,'x86':4}['${{ matrix.architecture }}']"
- name: Require actual Job Object and failure-path coverage
run: python experiments/optimize/test_process_containment.py --require-windows -v
- name: Exercise Windows runner limits and the production Unsupported gate
run: python experiments/optimize/test_fast_regression.py -v
# This workflow supplies containment evidence only. It deliberately cannot
# enable the production runner, and does not assert a 21-case timing result.
Loading
Loading