Add FICO Xpress Optimizer backend support #62
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Hi!
This PR adds support for the FICO Xpress Optimizer to PyOptInterface. The implementation follows the established patterns from the Gurobi and COPT backends, adapting Xpress-specific features to fit the PyOptInterface design.
Supported Features
Implementation Notes
Xpress-Specific Adaptations:
Global Environment Management: Xpress requires global initialization/cleanup via
XPRSinit/XPRSfree. This is handled through a reference-countedXpressEnvclass to ensure proper lifecycle management across multiple model instances.Quadratic Term Scaling: Xpress uses different conventions for quadratic terms:
The implementation handles this transparently in
set_objectiveandadd_quadratic_constraint.Callback Threading: Xpress callbacks receive thread-local problem clones. The implementation uses a swap mechanism to ensure the user interacts with the correct problem instance, with proper GIL management. Callbacks are serialized via
XPRS_MUTEXCALLBACKS=1to avoid race conditions. Note: this implementation does not support Python's new free-threading feature (PEP 703). If you plan to add free-threading support to PyOptInterface, we can adapt the Xpress backend to enable parallel callbacks, which Xpress supports natively.Callback Interface: PyOptInterface's single callback with context enumeration is mapped to Xpress's native multi-callback interface internally, maintaining consistency with other backends. Xpress provides additional callback contexts and APIs that allow customization of other optimization aspects (e.g., branching rules). Let me know if you're interested in extending PyOptInterface to support these advanced features.
Parameter Access: The implementation preserves Xpress naming conventions: "controls" for read/write optimizer parameters, "attributes" for read-only model and optimization status information.
Testing
All existing PyOptInterface tests pass with the Xpress backend. Additionally, a TSP callback example demonstrates the integration of optimization callbacks with lazy constraint generation.
Documentation
User documentation has been added in
docs/source/xpress.md, covering installation, basic usage, and Xpress-specific considerations.Please let me know if any design choices need adjustment to better align with PyOptInterface conventions, or if you have questions about the implementation. Happy to discuss further details or make modifications as needed.
Thanks for the great library!
Best,
Francesco