Skip to content

Xpress and OR-Tools integration in metrix-simulator#290

Open
lamoletoscar wants to merge 37 commits into
powsybl:mainfrom
lamoletoscar:ortools-xpress-integration
Open

Xpress and OR-Tools integration in metrix-simulator#290
lamoletoscar wants to merge 37 commits into
powsybl:mainfrom
lamoletoscar:ortools-xpress-integration

Conversation

@lamoletoscar

@lamoletoscar lamoletoscar commented May 19, 2026

Copy link
Copy Markdown
Contributor

Please check if the PR fulfills these requirements

  • The commit message follows our guidelines
  • Tests for the changes have been added (for bug fixes / features)
  • Docs have been added / updated (for bug fixes / features)
  • A PR or issue has been opened in all impacted repositories (if any)

Does this PR already have an issue describing the problem?

No.

What kind of change does this PR introduce?

Feature — integrates the OR-Tools abstraction layer and the Xpress backend into metrix-simulator, alongside the existing Sirius solver. Also includes related build changes, refactors and bug fixes.
Replaces #286. The previous branch was based on the legacy temporary_ortools work; this one is rebased on current main and reorganized into a clean commit chain.

What is the current behavior?

metrix-simulator solves LP/MIP problems exclusively through a direct call path to Sirius. No way to use other solvers (CBC, SCIP, GLOP, GUROBI, CPLEX, XPRESS) without modifying the source code.

What is the new behavior (if this is a feature change)?

  • The C++ code is restructured around a small ISolver abstraction with two implementations: compute::Solver (the existing direct Sirius path, untouched) and ortools::Solver (a new wrapper over MPSolver).
  • Two new configuration keys are introduced in fort.json:
    • SOLVERCH: solver used for the main optimization (MIP/LP).
    • PCSOLVERCH: solver used for the initial economic stacking phase.
      Both default to SIRIUS (value 5), which preserves the legacy behavior bit-for-bit. Other accepted values: GLPK, CBC, SCIP_GLOP, GUROBI, CPLEX, XPRESS.
  • A new optional SPECIFICSOLVERPARAMS string key passes solver-specific options through to the backend.
  • Selecting a backend that is unavailable at runtime (not compiled into OR-Tools, or missing license for dynamically-loaded solvers such as Xpress) raises a proper metrix error (ERRSolveurIndisponible, FR/EN dictionary entry) instead of an OR-Tools LOG(FATAL) abort. The availability check is memoized, as it involves a license probe for Xpress.
  • The OR-Tools wrapper strictly follows Sirius semantics, including VARIABLE_FIXE variables being valued at X on both the LP and MIP paths (matching Sirius behavior in spx_construire_probleme.c and pne_init_pne.c).
  • Build system: OR-Tools (v9.13, opt-in via USE_ORTOOLS) and Sirius are now built from source via ExternalProject_Add. New CMake options: USE_ORTOOLS (off by default) and USE_XPRESS (off by default; must reflect whether OR-Tools was built with the Xpress backend, which is itself enabled by setting XPRESS_ROOT when building external/), plus USE_SIRIUS_SHARED. Xpress is consumed transitively through ortools::ortools — no direct link from metrix-simulator.
  • A few bug fixes in the OR-Tools wrapper that existed in the legacy branch (slack basis test, time_limit unit, error throwing, accumulator reset), and the INFOIncident/INFOParade log-message separator moved from the dictionary into the code, so that dictionary whitespace is never significant.
  • Documentation updated in the README.md and in the Sphinx documentation (docs/simulator/build.md for the CMake options, docs/simulator/io_doc.md for the new fort.json keys).

Does this PR introduce a breaking change or deprecate an API?

  • Yes
  • No
    The default build (USE_ORTOOLS=OFF) is strictly equivalent to the previous behavior. The default values of SOLVERCH / PCSOLVERCH are SIRIUS, so existing input files keep producing identical results.

Other information:

Xpress test policy. The full Xpress TNR suite (110 tests, with reference files under tests/xpress_reference) is included in the repository but disabled by default: Xpress is a licensed solver and cannot run in the public CI. License holders can enable it locally with -D METRIX_RUN_XPRESS_TESTS=ON (in addition to USE_XPRESS=ON, see README.md). The full suite has been run this way on a licensed installation and passes, including the marginal-variation tests. CBC tests were removed since Xpress is the only target backend of this integration.

Solver-equivalent solutions. When using Xpress, the final simplex re-solve for marginal variations (metrix2assess.cpp) yields a different — but equally valid — optimal basis than Sirius: Xpress's presolve eliminates fixed columns (integer variables after fixerVariablesEntieres()) and degenerate curative variables, restoring them as non-basic at postsolve, while Sirius keeps them in its terminal basis. This only changes diagnostic log lines ("variation marginale sur …") and has no impact on results: duals and the R4/R4B/R7 outputs are identical (verified on the marginal-variations test set). On degenerate instances, alternative optimal solutions may still produce minor attribution differences between solvers in R2/R2B/R3B/R10 (equivalent-cost groups or remedial actions), which is inherent to comparing two LP/MIP engines.

Note on variantes_regroupees_complexe reference files. This test is declared metrix_test_no_check (random/equivalent solutions), so its reference files are never compared. They were regenerated on this branch and are now consistent with the actual code output (e.g. the R2B header), whereas the copies on main are stale — which explains the few remaining differences with main under tests/sirius_reference.

bongrainmat and others added 17 commits May 12, 2026 14:00
Signed-off-by: BONGRAIN Mathilde <mathilde.bongrain@rte-france.com>
Signed-off-by: BONGRAIN Mathilde <mathilde.bongrain@rte-france.com>
Signed-off-by: BONGRAIN Mathilde <mathilde.bongrain@rte-france.com>
* Minor fixes on metrix-simulator sources

* Sirius and ortools are now pulled from github releases

* Up ortools release

* Fix extractBasisStatus

* Throw ErrorI extractBasisStatus default

* Do not specify EN_BASE_BORNE_INF/SUP in extractBasisStatus

* Fix MPVariable bounds

* Fix VARIABLE_FIXE MPVariable bounds for LP resolutions

* Add xpress / cbc tnrs

* Add pcsolverchoice

* Add specificsolverparams

* Add CI with sirius / xpress / cbc tnrs

* Disable some xpress tests

* Fix ignored tests

Co-authored-by: Ulysse Prieto <uprieto@localsolver.com>
Signed-off-by: bongrainmat <63796216+bongrainmat@users.noreply.github.com>
Signed-off-by: arnaud <arnaud.rohmer@rte-france.com>
Signed-off-by: arnaud <arnaud.rohmer@rte-france.com>
Signed-off-by: arnaud <arnaud.rohmer@rte-france.com>
Signed-off-by: arnaud <arnaud.rohmer@rte-france.com>
Signed-off-by: lamoletoscar <lamoletoscar@proton.me>
Signed-off-by: lamoletoscar <lamoletoscar@proton.me>
Signed-off-by: lamoletoscar <lamoletoscar@proton.me>
Signed-off-by: lamoletoscar <lamoletoscar@proton.me>
…te::Solver, instrument MIP solves

Signed-off-by: lamoletoscar <lamoletoscar@proton.me>
… with Sirius semantics

Signed-off-by: lamoletoscar <lamoletoscar@proton.me>
…OLVERPARAMS

Signed-off-by: lamoletoscar <lamoletoscar@proton.me>
Signed-off-by: lamoletoscar <lamoletoscar@proton.me>
Signed-off-by: lamoletoscar <lamoletoscar@proton.me>
Signed-off-by: lamoletoscar <lamoletoscar@proton.me>
Signed-off-by: lamoletoscar <lamoletoscar@proton.me>
Signed-off-by: lamoletoscar <lamoletoscar@proton.me>
Signed-off-by: lamoletoscar <lamoletoscar@proton.me>
Signed-off-by: lamoletoscar <lamoletoscar@proton.me>
Signed-off-by: lamoletoscar <lamoletoscar@proton.me>
Signed-off-by: lamoletoscar <lamoletoscar@proton.me>
…vailable

Signed-off-by: lamoletoscar <lamoletoscar@proton.me>
… flags

Signed-off-by: lamoletoscar <lamoletoscar@proton.me>
Signed-off-by: lamoletoscar <lamoletoscar@proton.me>
@lamoletoscar lamoletoscar marked this pull request as ready for review June 12, 2026 15:24
Signed-off-by: lamoletoscar <lamoletoscar@proton.me>
…gration

Signed-off-by: lamoletoscar <lamoletoscar@proton.me>
Signed-off-by: lamoletoscar <lamoletoscar@proton.me>
Signed-off-by: lamoletoscar <lamoletoscar@proton.me>
Signed-off-by: lamoletoscar <lamoletoscar@proton.me>
Signed-off-by: lamoletoscar <lamoletoscar@proton.me>
Signed-off-by: lamoletoscar <lamoletoscar@proton.me>
@sonarqubecloud

sonarqubecloud Bot commented Jul 8, 2026

Copy link
Copy Markdown

@sonarqubecloud

sonarqubecloud Bot commented Jul 8, 2026

Copy link
Copy Markdown

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.

3 participants