Skip to content
Open
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
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 10 additions & 10 deletions .github/actions/setup_optimizers_linux/action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -48,17 +48,17 @@ runs:
shell: bash
name: Download X64 Installers
run: |
curl -L -o ~/installers/gurobi.tar.gz https://packages.gurobi.com/12.0/gurobi12.0.2_linux64.tar.gz
curl -L -o ~/installers/copt.tar.gz https://pub.shanshu.ai/download/copt/7.2.8/linux64/CardinalOptimizer-7.2.8-lnx64.tar.gz
curl -L -o ~/installers/gurobi.tar.gz https://packages.gurobi.com/13.0/gurobi13.0.0_linux64.tar.gz
curl -L -o ~/installers/copt.tar.gz https://pub.shanshu.ai/download/copt/8.0.2/linux64/CardinalOptimizer-8.0.2-lnx64.tar.gz
curl -L -o ~/installers/mosek.tar.bz2 https://download.mosek.com/stable/10.2.0/mosektoolslinux64x86.tar.bz2
curl -L -o ~/installers/idaes-solvers.tar.gz https://github.com/IDAES/idaes-ext/releases/download/3.4.2/idaes-solvers-ubuntu2204-x86_64.tar.gz

- if: ${{ (steps.cache-installers-linux.outputs.cache-hit != 'true') && (inputs.ARCH == 'ARM64') }}
shell: bash
name: Download ARM64 Installers
run: |
curl -L -o ~/installers/gurobi.tar.gz https://packages.gurobi.com/12.0/gurobi12.0.2_armlinux64.tar.gz
curl -L -o ~/installers/copt.tar.gz https://pub.shanshu.ai/download/copt/7.2.8/aarch64/CardinalOptimizer-7.2.8-aarch64_lnx.tar.gz
curl -L -o ~/installers/gurobi.tar.gz https://packages.gurobi.com/13.0/gurobi13.0.0_armlinux64.tar.gz
curl -L -o ~/installers/copt.tar.gz https://pub.shanshu.ai/download/copt/8.0.2/aarch64/CardinalOptimizer-8.0.2-aarch64_lnx.tar.gz
curl -L -o ~/installers/mosek.tar.bz2 https://download.mosek.com/stable/10.2.0/mosektoolslinuxaarch64.tar.bz2
curl -L -o ~/installers/idaes-solvers.tar.gz https://github.com/IDAES/idaes-ext/releases/download/3.4.2/idaes-solvers-ubuntu2204-aarch64.tar.gz

Expand All @@ -67,18 +67,18 @@ runs:
shell: bash
run: |
tar xfz ~/installers/gurobi.tar.gz -C ~/
ls ~/gurobi1202/linux64
ls ~/gurobi1300/linux64
# set environment variables
export GUROBI_HOME="${HOME}/gurobi1202/linux64"
export GUROBI_HOME="${HOME}/gurobi1300/linux64"
echo "GUROBI_HOME=${GUROBI_HOME}" >> $GITHUB_ENV
- name: Setup Gurobi Installation Home
if: ${{ inputs.ARCH == 'ARM64' }}
shell: bash
run: |
tar xfz ~/installers/gurobi.tar.gz -C ~/
ls ~/gurobi1202/armlinux64
ls ~/gurobi1300/armlinux64
# set environment variables
export GUROBI_HOME="${HOME}/gurobi1202/armlinux64"
export GUROBI_HOME="${HOME}/gurobi1300/armlinux64"
echo "GUROBI_HOME=${GUROBI_HOME}" >> $GITHUB_ENV
- name: Setup Gurobi Installation
shell: bash
Expand All @@ -104,9 +104,9 @@ runs:
COPT_CLIENT_INI: ${{ inputs.COPT_CLIENT_INI }}
run: |
tar xfz ~/installers/copt.tar.gz -C ~/
ls ~/copt72
ls ~/copt80
# set environment variables
export COPT_HOME="${HOME}/copt72"
export COPT_HOME="${HOME}/copt80"
echo "COPT_HOME=${COPT_HOME}" >> $GITHUB_ENV
echo "PATH=${PATH}:${COPT_HOME}/bin" >> $GITHUB_ENV
echo "LD_LIBRARY_PATH=${LD_LIBRARY_PATH}:${COPT_HOME}/lib" >> $GITHUB_ENV
Expand Down
10 changes: 5 additions & 5 deletions .github/actions/setup_optimizers_macos/action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -48,8 +48,8 @@ runs:
shell: bash
name: Download Universal Installers
run: |
curl -L -o ~/installers/gurobi.pkg https://packages.gurobi.com/12.0/gurobi12.0.2_macos_universal2.pkg
curl -L -o ~/installers/copt.tar.gz https://pub.shanshu.ai/download/copt/7.2.8/osx64/CardinalOptimizer-7.2.8-universal_mac.tar.gz
curl -L -o ~/installers/gurobi.pkg https://packages.gurobi.com/13.0/gurobi13.0.0_macos_universal2.pkg
curl -L -o ~/installers/copt.tar.gz https://pub.shanshu.ai/download/copt/8.0.2/osx64/CardinalOptimizer-8.0.2-universal_mac.tar.gz

- if: ${{ (steps.cache-installers-macos.outputs.cache-hit != 'true') && (inputs.ARCH == 'X64') }}
shell: bash
Expand All @@ -73,7 +73,7 @@ runs:
pkgutil --expand-full ~/installers/gurobi.pkg ~/gurobi
ls ~/gurobi
# set environment variables
export GUROBI_HOME="${HOME}/gurobi/gurobi12.0.2_macos_universal2.component.pkg/Payload/Library/gurobi1202/macos_universal2"
export GUROBI_HOME="${HOME}/gurobi/gurobi13.0.0_macos_universal2.component.pkg/Payload/Library/gurobi1300/macos_universal2"
echo "GUROBI_HOME=${GUROBI_HOME}" >> $GITHUB_ENV
echo "PATH=${PATH}:${GUROBI_HOME}/bin" >> $GITHUB_ENV
echo "DYLD_LIBRARY_PATH=${DYLD_LIBRARY_PATH}:${GUROBI_HOME}/lib" >> $GITHUB_ENV
Expand All @@ -95,9 +95,9 @@ runs:
COPT_CLIENT_INI: ${{ inputs.COPT_CLIENT_INI }}
run: |
tar xfz ~/installers/copt.tar.gz -C ~/
ls ~/copt72
ls ~/copt80
# set environment variables
export COPT_HOME="${HOME}/copt72"
export COPT_HOME="${HOME}/copt80"
echo "COPT_HOME=${COPT_HOME}" >> $GITHUB_ENV
echo "PATH=${PATH}:${COPT_HOME}/bin" >> $GITHUB_ENV
echo "DYLD_LIBRARY_PATH=${DYLD_LIBRARY_PATH}:${COPT_HOME}/lib" >> $GITHUB_ENV
Expand Down
18 changes: 9 additions & 9 deletions .github/actions/setup_optimizers_windows/action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -51,8 +51,8 @@ runs:
shell: pwsh
name: Download Installers
run: |
curl -L -o D:\installers\gurobi.msi https://packages.gurobi.com/12.0/Gurobi-12.0.2-win64.msi
curl -L -o D:\installers\copt.zip https://pub.shanshu.ai/download/copt/7.2.8/win64/CardinalOptimizer-7.2.8-win64.zip
curl -L -o D:\installers\gurobi.msi https://packages.gurobi.com/13.0/Gurobi-13.0.0-win64.msi
curl -L -o D:\installers\copt.zip https://pub.shanshu.ai/download/copt/8.0.2/win64/CardinalOptimizer-8.0.2-win64.zip
curl -L -o D:\installers\mosek.msi https://download.mosek.com/stable/10.2.0/moseksetupwin64x86.msi
curl -L -o D:\installers\idaes-solvers.tar.gz https://github.com/IDAES/idaes-ext/releases/download/3.4.2/idaes-solvers-windows-x86_64.tar.gz

Expand All @@ -67,12 +67,12 @@ runs:
GUROBI_WLS: ${{ inputs.GUROBI_WLS }}
run: |
lessmsi x D:\installers\gurobi.msi "D:\" gurobi_cl.exe
lessmsi x D:\installers\gurobi.msi "D:\" gurobi120.dll gurobi120.lib
lessmsi x D:\installers\gurobi.msi "D:\" gurobi130.dll gurobi130.lib
lessmsi x D:\installers\gurobi.msi "D:\" gurobi_c.h
ls D:\SourceDir\gurobi1202\win64
ls D:\SourceDir\gurobi1300\win64
# set environment variables
echo "GUROBI_HOME=D:\SourceDir\gurobi1202\win64" >> $env:GITHUB_ENV
echo "PATH=$env:PATH;D:\SourceDir\gurobi1202\win64\bin" >> $env:GITHUB_ENV
echo "GUROBI_HOME=D:\SourceDir\gurobi1300\win64" >> $env:GITHUB_ENV
echo "PATH=$env:PATH;D:\SourceDir\gurobi1300\win64\bin" >> $env:GITHUB_ENV
echo $env:GUROBI_HOME

# setup license using secrets
Expand All @@ -91,10 +91,10 @@ runs:
run: |
# unzip with 7zip
7z x D:\installers\copt.zip -oD:\
ls D:\copt72
ls D:\copt80
# set environment variables
echo "COPT_HOME=D:\copt72" >> $env:GITHUB_ENV
echo "PATH=$env:PATH;D:\copt72\bin" >> $env:GITHUB_ENV
echo "COPT_HOME=D:\copt80" >> $env:GITHUB_ENV
echo "PATH=$env:PATH;D:\copt80\bin" >> $env:GITHUB_ENV
echo $env:COPT_HOME

# Just use the size-limited license
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/doc-build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ jobs:
strategy:
fail-fast: true
matrix:
python-version: ["3.12"]
python-version: ["3.13"]

env:
PYTHON_VERSION: ${{ matrix.python-version }}
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/linux-build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ jobs:
matrix:
os: [ubuntu-latest, ubuntu-24.04-arm]
# python-version: ["3.9", "3.10", "3.11", "3.12"]
python-version: ["3.12"]
python-version: ["3.13"]

env:
PYTHON_VERSION: ${{ matrix.python-version }}
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/macos-build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ jobs:
matrix:
os: [macos-14]
# python-version: ["3.9", "3.10", "3.11", "3.12"]
python-version: ["3.11", "3.12"]
python-version: ["3.11", "3.13"]

env:
PYTHON_VERSION: ${{ matrix.python-version }}
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/windows-build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ jobs:
strategy:
fail-fast: false
matrix:
python-version: ["3.9", "3.12"]
python-version: ["3.9", "3.13"]

env:
PYTHON_VERSION: ${{ matrix.python-version }}
Expand Down
16 changes: 16 additions & 0 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
repos:
# C++ 格式化 - clang-format
- repo: https://github.com/pre-commit/mirrors-clang-format
rev: v21.1.7
hooks:
- id: clang-format
types_or: [c++, c]
files: \.(cpp|hpp|c|h|cc|cxx|hxx)$
exclude: ^thirdparty/

# Python 格式化 - black
- repo: https://github.com/psf/black
rev: 25.12.0
hooks:
- id: black
language_version: python3
32 changes: 32 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -239,6 +239,31 @@ nanobind_add_module(
target_link_libraries(ipopt_model_ext PUBLIC ipopt_model)
install(TARGETS ipopt_model_ext LIBRARY DESTINATION ${POI_INSTALL_DIR})

# XPRESS
add_library(xpress_model STATIC)
target_sources(xpress_model PRIVATE
include/pyoptinterface/xpress_model.hpp
lib/xpress_model.cpp
)
target_link_libraries(xpress_model PUBLIC core nlexpr nleval)

nanobind_add_module(
xpress_model_ext

STABLE_ABI NB_STATIC NB_DOMAIN pyoptinterface

lib/xpress_model_ext.cpp
lib/xpress_model_ext_constants.cpp
)
target_link_libraries(xpress_model_ext PUBLIC xpress_model)
install(TARGETS xpress_model_ext LIBRARY DESTINATION ${POI_INSTALL_DIR})

if(DEFINED ENV{XPRESSDIR})
message(STATUS "Detected Xpress header file: $ENV{XPRESSDIR}/include")
target_include_directories(xpress_model PRIVATE $ENV{XPRESSDIR}/include)
target_include_directories(xpress_model_ext PRIVATE $ENV{XPRESSDIR}/include)
endif()

# stub
nanobind_add_stub(
core_ext_stub
Expand Down Expand Up @@ -310,6 +335,13 @@ nanobind_add_stub(
OUTPUT ${POI_INSTALL_DIR}/ipopt_model_ext.pyi
)

nanobind_add_stub(
xpress_model_ext_stub
INSTALL_TIME
MODULE pyoptinterface._src.xpress_model_ext
OUTPUT ${POI_INSTALL_DIR}/xpress_model_ext.pyi
)

set(ENABLE_TEST_MAIN OFF BOOL "Enable test c++ function with a main.cpp")
if(ENABLE_TEST_MAIN)
add_executable(test_main lib/main.cpp)
Expand Down
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ It currently supports the following problem types:
It currently supports the following optimizers:
- [COPT](https://shanshu.ai/copt) ( Commercial )
- [Gurobi](https://www.gurobi.com/) ( Commercial )
- [Xpress](https://www.fico.com/en/products/fico-xpress-optimization) ( Commercial )
- [HiGHS](https://github.com/ERGO-Code/HiGHS) ( Open source )
- [Mosek](https://www.mosek.com/) ( Commercial )
- [Ipopt](https://github.com/coin-or/Ipopt) ( Open source )
Expand Down
1 change: 1 addition & 0 deletions docs/source/api/pyoptinterface.rst
Original file line number Diff line number Diff line change
Expand Up @@ -14,5 +14,6 @@ Submodules

pyoptinterface.gurobi.rst
pyoptinterface.copt.rst
pyoptinterface.xpress.rst
pyoptinterface.mosek.rst
pyoptinterface.highs.rst
8 changes: 8 additions & 0 deletions docs/source/api/pyoptinterface.xpress.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
pyoptinterface.xpress package
====================================

.. automodule:: pyoptinterface.xpress
:members:
:inherited-members:
:undoc-members:
:show-inheritance:
123 changes: 123 additions & 0 deletions docs/source/attribute/xpress.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,123 @@
### Supported [model attribute](#pyoptinterface.ModelAttribute)

:::{list-table}
:header-rows: 1

* - Attribute
- Get
- Set
* - Name
- ✅
- ✅
* - ObjectiveSense
- ✅
- ✅
* - DualStatus
- ✅
- ❌
* - PrimalStatus
- ✅
- ❌
* - RawStatusString
- ✅
- ❌
* - TerminationStatus
- ✅
- ❌
* - BarrierIterations
- ✅
- ❌
* - DualObjectiveValue
- ✅
- ❌
* - NodeCount
- ✅
- ❌
* - NumberOfThreads
- ✅
- ✅
* - ObjectiveBound
- ✅
- ❌
* - ObjectiveValue
- ✅
- ❌
* - RelativeGap
- ✅
- ✅
* - Silent
- ✅
- ✅
* - SimplexIterations
- ✅
- ❌
* - SolverName
- ✅
- ❌
* - SolverVersion
- ✅
- ❌
* - SolveTimeSec
- ✅
- ❌
* - TimeLimitSec
- ✅
- ✅
:::

### Supported [variable attribute](#pyoptinterface.VariableAttribute)

:::{list-table}
:header-rows: 1

* - Attribute
- Get
- Set
* - Value
- ✅
- ❌
* - LowerBound
- ✅
- ✅
* - UpperBound
- ✅
- ✅
* - Domain
- ✅
- ✅
* - PrimalStart
- ✅
- ✅
* - Name
- ✅
- ✅
* - IISLowerBound
- ✅
- ❌
* - IISUpperBound
- ✅
- ❌
:::

### Supported [constraint attribute](#pyoptinterface.ConstraintAttribute)

:::{list-table}
:header-rows: 1

* - Attribute
- Get
- Set
* - Name
- ✅
- ✅
* - Primal
- ✅
- ❌
* - Dual
- ✅
- ❌
* - IIS
- ✅
- ❌
:::

Loading