Skip to content

Revive block export and add PIPS-IPM++ solving#862

Open
FabianHofmann wants to merge 9 commits into
masterfrom
revive-to-block-files
Open

Revive block export and add PIPS-IPM++ solving#862
FabianHofmann wants to merge 9 commits into
masterfrom
revive-to-block-files

Conversation

@FabianHofmann

Copy link
Copy Markdown
Collaborator

This revives to_block_files under current linopy conventions and builds out the missing consumer half — a full, tested export-and-solve path to the distributed block solver PIPS-IPM++.

Note

The following content was generated by AI.

Changes proposed in this Pull Request

Block export

  • Revived to_block_files under current linopy conventions; it stays as the COO debug/visualization writer.
  • Vectorized Constraints.set_blocks so block assignment no longer scales with the number of blocks (it previously looped per block).

PIPS-IPM++ export / import

  • New Model.to_pips_files exports a block-structured model (assigned via Model.blocks) into PIPS's doubly-bordered block-diagonal ("arrowhead") format, deriving the A/B/C/D/BL/DL submatrices from linopy's internal CSR (so duplicate terms are already summed) and encoding ±inf bounds as PIPS indicator flags.
  • linopy.io.read_pips_files reconstructs an equivalent flat model straight from the export, and read_pips_solution reads the solver output back. The reconstruction makes the export verifiable with any solver and no PIPS build.

Solver integration

  • An env-gated pips solver runs the export through PIPS under mpirun and maps the primal, duals and objective back onto the model (m.solve(solver_name="pips")). It stays absent from available_solvers unless PIPS_BINARY is set, so ordinary installs are unaffected.
  • Fixed model-solve cleanup to remove directory problem files (shutil.rmtree), which the PIPS export produces.

Tests

  • Block-structure test that independently reassembles the exported per-block matrices by label and checks them against Model.matrices (matrix, rhs and sense), sharing no code with the reader.
  • PIPS-free round-trip test (export → read_pips_files → solve with HiGHS → equal objective).
  • A gated end-to-end test that runs the real mpirun PIPS solve, skipped unless PIPS_BINARY is set.

Docs

  • New installation and usage guide (doc/pips-installation.rst), added to the Solving section, leading with the one-line m.solve(solver_name="pips") usage.
  • Release note for the new feature.

The external C++ callback driver that PIPS itself needs is kept under dev-scripts/pips/ (not shipped) and is documented in the guide. The full pipeline — export → MUMPS-backed PIPS solve → read-back — was validated end to end against HiGHS (primal, objective and duals). This path is experimental and not run in CI.

Checklist

  • AI-generated content is marked (see AGENTS.md).
  • Code changes are sufficiently documented; i.e. new functions contain docstrings and further explanations may be given in doc.
  • Unit tests for new features were added (if applicable).
  • A note for the release notes doc/release_notes.rst of the upcoming release is included.
  • I consent to the release of this PR's code under the MIT license.

FabianHofmann and others added 9 commits July 22, 2026 12:25
Reimplement the block-structured PIPS export against the current flat/blockmap
API and cover it with an output-verifying test. Replace the per-block Python
loop in Constraints.set_blocks with vectorized term-dim reductions, making the
block calculation O(entries) instead of O(N_blocks * entries).
Add to_pips_files (CSR + indicator-flag exporter built on the internal
matrix), read_pips_files/read_pips_problem/read_pips_solution, and expose
to_pips_files as a Model method alongside the legacy COO to_block_files.
Wire an env-gated PIPS solver (PIPS_BINARY/PIPS_MPI_RANKS via mpirun) and
add a HiGHS round-trip test validating the reconstructed LP.
Independently reassemble the exported per-block CSR files, keying each
nonzero to its (constraint, variable) label via the on-disk *_labels files,
and assert equality against m.matrices.A plus the rhs/sense carve. Shares no
code with read_pips_files, so a writer bug cannot be masked by the reader.
Document the external MUMPS-backed PIPS build (verified apt line, mainline
clone, gams/gmspips disable, CMake install), the export/solve flow
(m.to_pips_files, mpirun -np <=N, read_pips_solution), the PIPS-free
round-trip validation, and the env-gated pips solver. Link it into the
Solving toctree.
Clean up directory problem files (to_pips_files writes a block dir) with
shutil.rmtree instead of os.remove, so m.solve(solver_name="pips") completes
its finally-block. Add test_pips_end_to_end_solve: runs the real mpirun PIPS
solve and checks the objective against HiGHS, skipped unless PIPS_BINARY is
set (CI-safe).
Add an early 'Using the pips solver' section showing m.solve(solver_name=
"pips") plus the PIPS_BINARY/PIPS_MPI_RANKS env vars, cross-referencing the
installation steps as a prerequisite. Fold in and drop the redundant later
'Solver integration' section.
@codspeed-hq

codspeed-hq Bot commented Jul 23, 2026

Copy link
Copy Markdown

Merging this PR will not alter performance

✅ 173 untouched benchmarks
⏩ 173 skipped benchmarks1


Comparing revive-to-block-files (f92339c) with master (4711206)

Open in CodSpeed

Footnotes

  1. 173 benchmarks were skipped, so the baseline results were used instead. If they were deleted from the codebase, click here and archive them to remove them from the performance reports.

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