diff --git a/.github/workflows/build-python-package-hipo.yml b/.github/workflows/build-python-package-hipo.yml new file mode 100644 index 0000000000..d58d814555 --- /dev/null +++ b/.github/workflows/build-python-package-hipo.yml @@ -0,0 +1,269 @@ +name: build-python-package-hipo + +on: [push, pull_request] + +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + +jobs: + build_sdist: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - uses: seanmiddleditch/gha-setup-ninja@master + + - name: Build sdist + run: | + python3 -m pip install build + python3 -m build --sdist + + - name: Install sdist + run: | + ls dist + python3 -m pip install dist/*.tar.gz \ + --config-settings=cmake.define.HIPO=ON \ + --config-settings=cmake.define.BUILD_OPENBLAS=ON + + - name: Test highspy + run: | + python3 -m pip install pytest + python3 -m pytest $GITHUB_WORKSPACE + python3 -m pytest $GITHUB_WORKSPACE/check/test_highspy_hipo.py + + build_sdist_mac: + runs-on: macos-latest + steps: + - uses: actions/checkout@v4 + + - name: Build sdist + run: | + python3 -m pip install build --break-system-packages + python3 -m build --sdist + + - name: Install sdist + run: | + ls dist + python3 -m pip install dist/*.tar.gz \ + --config-settings=cmake.define.HIPO=ON \ + --break-system-packages + + - name: Test highspy + run: | + python3 -m pip install pytest --break-system-packages + python3 -m pytest $GITHUB_WORKSPACE + python3 -m pytest $GITHUB_WORKSPACE/check/test_highspy_hipo.py + + build_sdist_win: + runs-on: windows-2022 + steps: + - uses: actions/checkout@v4 + + - name: Install correct python version + uses: actions/setup-python@v5 + with: + python-version: 3.9 + + - name: Build sdist + run: | + python -m pip install build + python -m build --sdist + + - name: Install sdist + run: | + $item = Get-ChildItem dist + python -m pip install "$item" ` + --config-settings=cmake.define.HIPO=ON ` + --config-settings=cmake.define.BUILD_OPENBLAS=ON + python -c "import highspy; print(dir(highspy))" + + - name: Test highspy + run: | + python -m pip install pytest + python -m pytest + python -m pytest $env:GITHUB_WORKSPACE/check/test_highspy_hipo.py + + build_wheel_linux: + runs-on: ubuntu-24.04 + strategy: + matrix: + python: [3.11] + steps: + - uses: actions/checkout@v4 + + - name: Install correct python version + uses: actions/setup-python@v5 + with: + python-version: ${{ matrix.python }} + + - name: Build wheel + run: | + python3 --version + python3 -m pip install cibuildwheel + export CIBW_CONFIG_SETTINGS="cmake.define.HIPO=ON cmake.define.BUILD_OPENBLAS=ON" + python3 -m cibuildwheel --only cp311-manylinux_x86_64 $GITHUB_WORKSPACE + + - name: Install wheel + run: | + ls wheelhouse + python3 -m pip install wheelhouse/*.whl + + - name: Test highspy + run: | + python3 -m pip install pytest + python3 -m pytest $GITHUB_WORKSPACE + python3 -m pytest $GITHUB_WORKSPACE/check/test_highspy_hipo.py + + build_wheel_linux_arm: + runs-on: ubuntu-24.04-arm + strategy: + matrix: + python: [3.11] + steps: + - uses: actions/checkout@v4 + + - name: Install python + uses: actions/setup-python@v5 + with: + python-version: ${{ matrix.python }} + + - name: Build wheel + run: | + python3 --version + python3 -m pip install cibuildwheel + export CIBW_CONFIG_SETTINGS="cmake.define.HIPO=ON cmake.define.BUILD_OPENBLAS=ON" + python3 -m cibuildwheel --only cp311-manylinux_aarch64 $GITHUB_WORKSPACE + + - name: Install wheel + run: | + ls wheelhouse + python3 -m pip install wheelhouse/*.whl + + - name: Test highspy + run: | + python3 -m pip install pytest + python3 -m pytest $GITHUB_WORKSPACE + python3 -m pytest $GITHUB_WORKSPACE/check/test_highspy_hipo.py + + build_wheel_macos_intel: + runs-on: macos-15-intel + strategy: + matrix: + python: [3.11] + steps: + - uses: actions/checkout@v4 + + - name: Install correct python version + uses: actions/setup-python@v5 + with: + python-version: ${{ matrix.python }} + + - name: Build wheel + run: | + python3 -m pip install cibuildwheel + export CIBW_CONFIG_SETTINGS="cmake.define.HIPO=ON" + python3 -m cibuildwheel --only cp311-macosx_x86_64 $GITHUB_WORKSPACE + + - name: Install wheel + run: | + ls wheelhouse + python3 --version + python3 -m pip install wheelhouse/*.whl + python3 -c "import highspy; print(dir(highspy))" + + - name: Test highspy + run: | + python3 -m pip install pytest + python3 -m pytest $GITHUB_WORKSPACE + python3 -m pytest $GITHUB_WORKSPACE/check/test_highspy_hipo.py + + build_wheel_macos_arm: + runs-on: macos-14 # macos-14 is arm64 + strategy: + matrix: + python: [3.11] + steps: + - uses: actions/checkout@v4 + + - name: Install correct python version + uses: actions/setup-python@v5 + with: + python-version: ${{ matrix.python }} + + - name: Build wheel + run: | + python3 -m pip install cibuildwheel + export CIBW_CONFIG_SETTINGS="cmake.define.HIPO=ON" + python3 -m cibuildwheel --only cp311-macosx_arm64 $GITHUB_WORKSPACE + + - name: Install wheel + run: | + ls wheelhouse + python3 --version + python3 -m pip install wheelhouse/*.whl + python3 -c "import highspy; print(dir(highspy))" + + - name: Test highspy + run: | + python3 -m pip install pytest + python3 -m pytest $GITHUB_WORKSPACE + python3 -m pytest $GITHUB_WORKSPACE/check/test_highspy_hipo.py + + build_wheel_windows: + runs-on: windows-2022 + steps: + - uses: actions/checkout@v4 + + - name: Install correct python version + uses: actions/setup-python@v5 + with: + python-version: 3.9 + + - name: Build wheel + run: | + python -m pip install cibuildwheel + $env:CIBW_CONFIG_SETTINGS="cmake.define.HIPO=ON cmake.define.BUILD_OPENBLAS=ON" + python -m cibuildwheel --only cp39-win_amd64 $GITHUB_WORKSPACE + + - name: Install wheel + run: | + ls wheelhouse + $item = Get-ChildItem wheelhouse + python -m pip install "$item" + python -c "import highspy; print(dir(highspy))" + + - name: Test highspy + run: | + python -m pip install pytest + python -m pytest + python -m pytest $env:GITHUB_WORKSPACE/check/test_highspy_hipo.py + + build_wheel_windows_313: + runs-on: windows-2022 + steps: + - uses: actions/checkout@v4 + + - name: Install correct python version + uses: actions/setup-python@v5 + with: + python-version: 3.13 + + - name: Build wheel + run: | + python -m pip install cibuildwheel + $env:CIBW_CONFIG_SETTINGS="cmake.define.HIPO=ON cmake.define.BUILD_OPENBLAS=ON" + python -m cibuildwheel --only cp313-win_amd64 $GITHUB_WORKSPACE + + - name: Install wheel + run: | + ls wheelhouse + $item = Get-ChildItem wheelhouse + python -m pip install "$item" + python -c "import highspy; print(dir(highspy))" + + - name: Test highspy + run: | + python -m pip install pytest + python -m pytest + python -m pytest $env:GITHUB_WORKSPACE/check/test_highspy_hipo.py + \ No newline at end of file diff --git a/.github/workflows/build-python-package.yml b/.github/workflows/build-python-package.yml index 7b9a4b5532..0afac38d85 100644 --- a/.github/workflows/build-python-package.yml +++ b/.github/workflows/build-python-package.yml @@ -15,7 +15,7 @@ jobs: - name: Build sdist run: | - python3 -m pip install build + python3 -m pip install build python3 -m build --sdist - name: Install sdist @@ -26,8 +26,8 @@ jobs: - name: Test highspy run: | python3 -m pip install pytest - python3 -m pytest $GITHUB_WORKSPACE - + python3 -m pytest + build_sdist_mac: runs-on: macos-latest steps: @@ -46,7 +46,7 @@ jobs: - name: Test highspy run: | python3 -m pip install pytest --break-system-packages - python3 -m pytest $GITHUB_WORKSPACE + python3 -m pytest build_sdist_win: runs-on: windows-2022 @@ -72,8 +72,8 @@ jobs: - name: Test highspy run: | python -m pip install pytest - python -m pytest - + python -m pytest + build_wheel_linux: runs-on: ubuntu-24.04 strategy: @@ -101,7 +101,7 @@ jobs: - name: Test highspy run: | python3 -m pip install pytest - python3 -m pytest $GITHUB_WORKSPACE + python3 -m pytest build_wheel_linux_arm: runs-on: ubuntu-24.04-arm @@ -130,13 +130,13 @@ jobs: - name: Test highspy run: | python3 -m pip install pytest - python3 -m pytest $GITHUB_WORKSPACE + python3 -m pytest build_wheel_macos_intel: runs-on: macos-15-intel strategy: matrix: - python: [3.11] + python: [3.11] steps: - uses: actions/checkout@v4 @@ -160,13 +160,13 @@ jobs: - name: Test highspy run: | python3 -m pip install pytest - python3 -m pytest $GITHUB_WORKSPACE - + python3 -m pytest + build_wheel_macos_arm: runs-on: macos-14 # macos-14 is arm64 strategy: matrix: - python: [3.11] + python: [3.11] steps: - uses: actions/checkout@v4 @@ -190,7 +190,7 @@ jobs: - name: Test highspy run: | python3 -m pip install pytest - python3 -m pytest $GITHUB_WORKSPACE + python3 -m pytest build_wheel_windows: runs-on: windows-2022 @@ -217,8 +217,8 @@ jobs: - name: Test highspy run: | python -m pip install pytest - python -m pytest - + python -m pytest + build_wheel_windows_313: runs-on: windows-2022 steps: @@ -244,5 +244,4 @@ jobs: - name: Test highspy run: | python -m pip install pytest - python -m pytest - \ No newline at end of file + python -m pytest diff --git a/.github/workflows/build-python-sdist-hipo.yml b/.github/workflows/build-python-sdist-hipo.yml new file mode 100644 index 0000000000..e362b23ffc --- /dev/null +++ b/.github/workflows/build-python-sdist-hipo.yml @@ -0,0 +1,111 @@ +name: build-python-sdist-hipo + +on: [push, pull_request] + +jobs: + build_sdist_ubuntu: + runs-on: ${{ matrix.os }} + strategy: + matrix: + os: [ubuntu-latest] + + steps: + - uses: actions/checkout@v4 + - uses: seanmiddleditch/gha-setup-ninja@master + + - name: Build sdist + shell: bash + run: pipx run build --sdist + + - name: check metadata + run: pipx run twine check dist/* + + - name: install highspy + run: | + python3 -m pip install dist/*.tar.gz --user \ + --config-settings=cmake.define.HIPO=ON \ + --config-settings=cmake.define.BUILD_OPENBLAS=ON + + - name: Test Python Examples + run: | + python3 ./examples/call_highs_from_python_highspy.py + python3 ./examples/call_highs_from_python_mps.py + python3 ./examples/call_highs_from_python.py + python3 ./examples/minimal.py + + - name: Test highspy + run: | + python3 -m pip install pytest + python3 -m pytest $GITHUB_WORKSPACE + python3 -m pytest $GITHUB_WORKSPACE/check/test_highspy_hipo.py + + build_sdist_mac: + runs-on: ${{ matrix.os }} + strategy: + matrix: + os: [macos-latest] + + steps: + - uses: actions/checkout@v4 + - uses: seanmiddleditch/gha-setup-ninja@master + + - name: Build sdist + shell: bash + run: pipx run build --sdist + + - name: check metadata + run: pipx run twine check dist/* + + - name: install highspy + run: | + python3 -m venv path/to/venv + source path/to/venv/bin/activate + python3 -m pip install dist/*.tar.gz \ + --config-settings=cmake.define.HIPO=ON + + - name: Test Python Examples + run: | + source path/to/venv/bin/activate + python3 ./examples/call_highs_from_python_highspy.py + python3 ./examples/call_highs_from_python_mps.py + python3 ./examples/call_highs_from_python.py + python3 ./examples/minimal.py + + - name: Test highspy + run: | + python3 -m pip install pytest --user + python3 -m pytest $GITHUB_WORKSPACE + python3 -m pytest $GITHUB_WORKSPACE/check/test_highspy_hipo.py + + build_sdist_win: + runs-on: windows-latest + + steps: + - uses: actions/checkout@v4 + + - name: Build sdist + shell: bash + run: pipx run build --sdist + + - name: check metadata + run: pipx run twine check dist/* + + - name: install highspy + run: | + $item = Get-ChildItem dist + python -m pip install "$item" ` + --config-settings=cmake.define.HIPO=ON ` + --config-settings=cmake.define.BUILD_OPENBLAS=ON + + - name: Test Python Examples + run: | + python ./examples/call_highs_from_python_highspy.py + python ./examples/call_highs_from_python_mps.py + python ./examples/call_highs_from_python.py + python ./examples/minimal.py + + - name: Test highspy + run: | + python -m pip install pytest + python -m pytest + python -m pytest $env:GITHUB_WORKSPACE/check/test_highspy_hipo.py \ No newline at end of file diff --git a/.github/workflows/build-python-sdist.yml b/.github/workflows/build-python-sdist.yml index 914f46fe1c..f7fb1e7988 100644 --- a/.github/workflows/build-python-sdist.yml +++ b/.github/workflows/build-python-sdist.yml @@ -52,7 +52,7 @@ jobs: run: | python3 -m venv path/to/venv source path/to/venv/bin/activate - python3 -m pip install dist/*.tar.gz + python3 -m pip install dist/*.tar.gz - name: Test Python Examples run: | diff --git a/.github/workflows/build-wheels-hipo.yml b/.github/workflows/build-wheels-hipo.yml new file mode 100644 index 0000000000..383d08ff72 --- /dev/null +++ b/.github/workflows/build-wheels-hipo.yml @@ -0,0 +1,100 @@ +name: build-wheels-hipo + +on: [push] +# on: [pull_request] + +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + +jobs: + build_sdist: + name: Build source distribution + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + + - name: Build sdist + shell: bash + run: pipx run build --sdist + + - name: check metadata + run: pipx run twine check dist/* + + build_wheels: + name: Build HiPO wheel for ${{ matrix.python }}-${{ matrix.buildplat[1] }} + runs-on: ${{ matrix.buildplat[0] }} + strategy: + # Ensure that a wheel builder finishes even if another fails + fail-fast: false + matrix: + # From NumPy + # Github Actions doesn't support pairing matrix values together, let's improvise + # https://github.com/github/feedback/discussions/7835#discussioncomment-1769026 + buildplat: + - [ubuntu-24.04, manylinux_x86_64] + - [ubuntu-24.04, manylinux_i686] + - [ubuntu-24.04-arm, manylinux_aarch64] + - [ubuntu-24.04, musllinux_x86_64] # No OpenBlas, no test + - [ubuntu-24.04, musllinux_i686] + - [ubuntu-24.04-arm, musllinux_aarch64] + - [macos-15-intel, macosx_x86_64] + - [macos-14, macosx_arm64] + - [windows-2022, win_amd64] + - [windows-2022, win32] + python: ["cp38", "cp39","cp310", "cp311","cp312", "cp313"] + + steps: + - uses: actions/checkout@v4 + + # - name: Edit pyproject.toml (macOS) + # if: runner.os == 'macOS' + # shell: bash + # run: | + # # macOS sed requires a backup extension (here, an empty string '') + # sed -i '' '/cmake\.args = \[/,/\]/{ + # s|"-DPYTHON_BUILD_SETUP=ON"|"-DPYTHON_BUILD_SETUP=ON",\ + # "-DHIPO=ON"| + # }' pyproject.toml + # echo "--- pyproject.toml content after macOS edit ---" + # cat pyproject.toml + + # - name: Edit pyproject.toml (Linux) + # if: runner.os == 'Linux' + # shell: bash + # run: | + # # Linux sed does NOT require a backup extension + # sed -i '/cmake\.args = \[/,/\]/{ + # s|"-DPYTHON_BUILD_SETUP=ON"|"-DPYTHON_BUILD_SETUP=ON",\ + # "-DHIPO=ON",\ + # "-DBUILD_OPENBLAS=ON"| + # }' pyproject.toml + # echo "--- pyproject.toml content after Linux edit ---" + # cat pyproject.toml + + # - name: Edit pyproject.toml (Windows) + # if: runner.os == 'Windows' + # shell: pwsh + # run: | + # $content = Get-Content pyproject.toml -Raw + # $newContent = $content -replace 'cmake\.args = \[\s*"-DPYTHON_BUILD_SETUP=ON"\s*\]', @" + # cmake.args = [ + # "-DPYTHON_BUILD_SETUP=ON", + # "-DHIPO=ON", + # "-DBUILD_OPENBLAS=ON" + # ] + # "@ + # $newContent | Set-Content pyproject.toml + # cat pyproject.toml + + - name: Build wheels + uses: pypa/cibuildwheel@v3.0 + env: + CIBW_BUILD: ${{ matrix.python }}-${{ matrix.buildplat[1] }} + CIBW_TEST_COMMAND: "pytest {project}/tests {project}/check/test_highspy_hipo.py" + CIBW_TEST_REQUIRES: "pytest" + CIBW_BUILD_TAG: "apache" + CIBW_CONFIG_SETTINGS_LINUX: "cmake.define.HIPO=ON cmake.define.BUILD_OPENBLAS=ON" + CIBW_CONFIG_SETTINGS_MACOS: "cmake.define.HIPO=ON" + CIBW_CONFIG_SETTINGS_WINDOWS: "cmake.define.HIPO=ON cmake.define.BUILD_OPENBLAS=ON" + diff --git a/.github/workflows/test-python-macos.yml b/.github/workflows/test-python-macos.yml index d6ddd5eef5..1f7aded22a 100644 --- a/.github/workflows/test-python-macos.yml +++ b/.github/workflows/test-python-macos.yml @@ -8,7 +8,7 @@ jobs: strategy: matrix: os: [macos-latest] - python: [3.11] + python: [3.12] steps: - uses: actions/checkout@v4 - name: Install correct python version @@ -16,13 +16,13 @@ jobs: with: python-version: ${{ matrix.python }} - - name: Install build dependencies - run: python3 -m pip install numpy setuptools wheel pytest - + - name: Install test dependencies + run: python3 -m pip install pytest + - name: Test Python Interface run: | python3 -m pip install . - pytest -v + pytest -v - name: Test Python Examples run: | @@ -30,3 +30,42 @@ jobs: python3 ./examples/call_highs_from_python_mps.py python3 ./examples/call_highs_from_python.py python3 ./examples/minimal.py + + build_hipo: + runs-on: ${{ matrix.os }} + strategy: + matrix: + os: [macos-latest] + python: [3.12] + steps: + - uses: actions/checkout@v4 + - name: Install correct python version + uses: actions/setup-python@v5 + with: + python-version: ${{ matrix.python }} + + # - name: Edit pyproject + # run: | + # ls + # sed -i '' '/cmake\.args = \[/,/\]/{ + # s|"-DPYTHON_BUILD_SETUP=ON"|"-DPYTHON_BUILD_SETUP=ON",\ + # "-DHIPO=ON"| + # }' pyproject.toml + # cat pyproject.toml + + - name: Install test dependencies + run: python3 -m pip install pytest + + - name: Test Python Interface + run: | + python3 -m pip install . \ + --config-settings=cmake.define.HIPO=ON + pytest + pytest check/test_highspy_hipo.py + + - name: Test Python Examples + run: | + python3 ./examples/call_highs_from_python_highspy.py + python3 ./examples/call_highs_from_python_mps.py + python3 ./examples/call_highs_from_python.py + python3 ./examples/minimal.py \ No newline at end of file diff --git a/.github/workflows/test-python-ubuntu.yml b/.github/workflows/test-python-ubuntu.yml index f9345050bd..e0e69d7d6a 100644 --- a/.github/workflows/test-python-ubuntu.yml +++ b/.github/workflows/test-python-ubuntu.yml @@ -8,7 +8,7 @@ jobs: strategy: matrix: os: [ubuntu-latest] - python: [3.11] + python: [3.12] steps: - uses: actions/checkout@v4 - name: Install correct python version @@ -16,13 +16,53 @@ jobs: with: python-version: ${{ matrix.python }} - - name: Install build dependencies - run: python3 -m pip install numpy setuptools wheel pytest - + - name: Install test dependencies + run: python3 -m pip install pytest + - name: Test Python Interface run: | python3 -m pip install . - pytest -v + pytest -v + + - name: Test Python Examples + run: | + python3 ./examples/call_highs_from_python_highspy.py + python3 ./examples/call_highs_from_python_mps.py + python3 ./examples/call_highs_from_python.py + + build_hipo: + runs-on: ${{ matrix.os }} + strategy: + matrix: + os: [ubuntu-latest] + python: [3.12] + steps: + - uses: actions/checkout@v4 + - name: Install correct python version + uses: actions/setup-python@v5 + with: + python-version: ${{ matrix.python }} + + # - name: Edit pyproject + # run: | + # ls + # sed -i '/cmake\.args = \[/,/\]/{ + # s|"-DPYTHON_BUILD_SETUP=ON"|"-DPYTHON_BUILD_SETUP=ON",\ + # "-DHIPO=ON",\ + # "-DBUILD_OPENBLAS=ON"| + # }' pyproject.toml + # cat pyproject.toml + + - name: Install test dependencies + run: python3 -m pip install pytest + + - name: Test Python Interface + run: | + python3 -m pip install . \ + --config-settings=cmake.define.HIPO=ON \ + --config-settings=cmake.define.BUILD_OPENBLAS=ON + pytest -v + pytest check/test_highspy_hipo.py - name: Test Python Examples run: | diff --git a/.github/workflows/test-python-win.yml b/.github/workflows/test-python-win.yml index 528b94a2d7..b11acbb103 100644 --- a/.github/workflows/test-python-win.yml +++ b/.github/workflows/test-python-win.yml @@ -17,13 +17,59 @@ jobs: with: python-version: ${{ matrix.python }} - - name: Install build dependencies - run: python -m pip install numpy setuptools wheel pytest - + - name: Install test dependencies + run: python -m pip install pytest + - name: Test python install run: | python -m pip install . - pytest + pytest + + - name: Test Python Examples + run: | + python ./examples/call_highs_from_python_highspy.py + python ./examples/call_highs_from_python_mps.py + python ./examples/minimal.py + + build_hipo: + runs-on: ${{ matrix.os }} + strategy: + matrix: + # os: [self-hosted] + os: [windows-2022] + python: [3.12] + steps: + - uses: actions/checkout@v4 + - name: Install correct python version + uses: actions/setup-python@v5 + with: + python-version: ${{ matrix.python }} + + # - name: Edit pyproject + # run: | + # ls + # $content = Get-Content pyproject.toml -Raw + # $newContent = $content -replace 'cmake\.args = \[\s*"-DPYTHON_BUILD_SETUP=ON"\s*\]', @" + # cmake.args = [ + # "-DPYTHON_BUILD_SETUP=ON", + # "-DHIPO=ON", + # "-DBUILD_OPENBLAS=ON" + # ] + # "@ + # $newContent | Set-Content pyproject.toml + # cat pyproject.toml + + # check if automatic + - name: Install test dependencies + run: python -m pip install pytest + + - name: Test python install + run: | + python -m pip install . ` + --config-settings=cmake.define.HIPO=ON ` + --config-settings=cmake.define.BUILD_OPENBLAS=ON + pytest + pytest check/test_highspy_hipo.py - name: Test Python Examples run: | diff --git a/CMakeLists.txt b/CMakeLists.txt index 19ee58fd8d..db76f77c11 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -158,7 +158,7 @@ if (HIPO AND FORTRAN) message(ERROR "HIPO is only available in C++. Not yet supported in FORTRAN") endif() if (HIPO AND PYTHON_BUILD_SETUP) - message(ERROR "HIPO is only available in C++. Not yet supported in Python.") + message(STATUS "HIPO in Python: ON.") endif() if (HIPO AND NOT FAST_BUILD) message(ERROR "HIPO is only available with FAST_BUILD=ON.") diff --git a/check/test_highspy_hipo.py b/check/test_highspy_hipo.py new file mode 100644 index 0000000000..a30d8c5347 --- /dev/null +++ b/check/test_highspy_hipo.py @@ -0,0 +1,77 @@ +import tempfile +import unittest +import highspy +from highspy.highs import highs_linear_expression, qsum +import numpy as np +from sys import platform +import signal + + +class TestHighsPy(unittest.TestCase): + def get_example_model(self): + """ + minimize f = x0 + x1 + subject to x1 <= 7 + 5 <= x0 + 2x1 <= 15 + 6 <= 3x0 + 2x1 + 0 <= x0 <= 4; 1 <= x1 + """ + inf = highspy.kHighsInf + h = highspy.Highs() + # Define a HighsLp instance + lp = highspy.HighsLp() + lp.num_col_ = 2 + lp.num_row_ = 3 + lp.col_cost_ = np.array([1, 1], dtype=np.double) + lp.col_lower_ = np.array([0, 1], dtype=np.double) + lp.col_upper_ = np.array([4, inf], dtype=np.double) + lp.row_lower_ = np.array([-inf, 5, 6], dtype=np.double) + lp.row_upper_ = np.array([7, 15, inf], dtype=np.double) + lp.a_matrix_.start_ = np.array([0, 2, 5]) + lp.a_matrix_.index_ = np.array([1, 2, 0, 1, 2]) + lp.a_matrix_.value_ = np.array([1, 3, 1, 2, 2], dtype=np.double) + h.passModel(lp) + return h + + def test_example_model_builder(self): + """ + minimize f = x0 + x1 + subject to x1 <= 7 + 5 <= x0 + 2x1 <= 15 + 6 <= 3x0 + 2x1 + 0 <= x0 <= 4; 1 <= x1 + """ + h = highspy.Highs() + + x0 = h.addVariable(lb=0, ub=4, obj=1) + x1 = h.addVariable(lb=1, ub=7, obj=1) + + h.addConstr(5 <= x0 + 2 * x1 <= 15) + h.addConstr(6 <= 3 * x0 + 2 * x1) + + lp = h.getLp() + + self.assertEqual(lp.num_col_, 2) + self.assertEqual(lp.num_row_, 2) + self.assertAlmostEqual(lp.col_cost_[0], 1) + self.assertAlmostEqual(lp.col_lower_[0], 0) + self.assertAlmostEqual(lp.col_upper_[0], 4) + self.assertAlmostEqual(lp.row_lower_[0], 5) + self.assertAlmostEqual(lp.row_upper_[0], 15) + self.assertAlmostEqual(lp.row_lower_[1], 6) + self.assertAlmostEqual(lp.row_upper_[1], highspy.kHighsInf) + + def test_hipo(self): + print("running hipo test") + h = self.get_example_model() + h.setOptionValue("solver", "hipo") + h.setOptionValue("output_flag", True) + + [status, output_flag] = h.getOptionValue("solver") + self.assertEqual(output_flag, "hipo") + + h.run() + self.assertEqual(status, highspy.HighsStatus.kOk) + + status = h.getModelStatus() + self.assertEqual(status, highspy.HighsModelStatus.kOptimal) \ No newline at end of file diff --git a/cmake/python-highs.cmake b/cmake/python-highs.cmake index 8c3bd15356..ff8ae72459 100644 --- a/cmake/python-highs.cmake +++ b/cmake/python-highs.cmake @@ -6,16 +6,31 @@ endif() include(sources-python) -set(sources_python ${highs_sources_python} - ${cupdlp_sources_python} - ${ipx_sources_python} +set(sources_python ${highs_sources_python} + ${cupdlp_sources_python} + ${ipx_sources_python} ${basiclu_sources_python}) -set(headers_python ${highs_headers_python} - ${cupdlp_headers_python} - ${ipx_headers_python} +set(headers_python ${highs_headers_python} + ${cupdlp_headers_python} + ${ipx_headers_python} ${basiclu_headers_python}) +if(HIPO) + set(sources_python ${sources_python} + ${hipo_sources_python} + ${factor_highs_sources_python} + ${hipo_util_sources_python} + ${hipo_orderings_sources_python}) + + set(headers_python ${headers_python} + ${hipo_headers_python} + ${factor_highs_headers_python} + ${hipo_util_headers_python} + ${hipo_orderings_headers_python}) + +endif() + # Find Python 3 find_package(Python COMPONENTS Interpreter Development.Module REQUIRED) find_package(pybind11 CONFIG) @@ -42,10 +57,20 @@ python_add_library(_core MODULE highs/highs_bindings.cpp WITH_SOABI) target_link_libraries(_core PRIVATE pybind11::headers) -# sources for python +if (HIPO) + if (WIN32 OR LINUX) + target_link_libraries(_core PRIVATE openblas) + target_compile_definitions(_core PRIVATE HIPO_USES_OPENBLAS) + else() # APPLE + target_compile_definitions(_core PRIVATE HIPO_USES_APPLE_BLAS) + endif() + +endif() + +# sources for python target_sources(_core PUBLIC ${sources_python} ${headers_python}) -# include directories for python +# include directories for python target_include_directories(_core PUBLIC ${include_dirs_python}) # This is passing in the version as a define just as an example @@ -55,12 +80,12 @@ if(MSVC) target_compile_options(_core PRIVATE "/bigobj") endif() -if (NOT MSVC) +if (NOT MSVC) target_compile_options(_core PRIVATE "-ftemplate-depth=2048") endif() # if(MSVC) -# # Try to split large pdb files into objects. +# # Try to split large pdb files into objects. # # https://github.com/tensorflow/tensorflow/issues/31610 # add_compile_options("/Z7") # add_link_options("/DEBUG:FASTLINK") diff --git a/cmake/sources-python.cmake b/cmake/sources-python.cmake index b89ee37586..e412520cb6 100644 --- a/cmake/sources-python.cmake +++ b/cmake/sources-python.cmake @@ -1,7 +1,10 @@ set(include_dirs_python $ + $ $ + $ $ + $ $ $ $ @@ -134,7 +137,7 @@ set(ipx_sources_python highs/ipm/ipx/symbolic_invert.cc highs/ipm/ipx/timer.cc highs/ipm/ipx/utils.cc) - + set(ipx_headers_python highs/ipm/ipx/basiclu_kernel.h highs/ipm/ipx/basiclu_wrapper.h @@ -175,6 +178,154 @@ set(ipx_sources_python highs/ipm/ipx/timer.h highs/ipm/ipx/utils.h) +set(hipo_sources_python + highs/ipm/hipo/ipm/CurtisReidScaling.cpp + highs/ipm/hipo/ipm/IpmData.cpp + highs/ipm/hipo/ipm/FactorHiGHSSolver.cpp + highs/ipm/hipo/ipm/Control.cpp + highs/ipm/hipo/ipm/Iterate.cpp + highs/ipm/hipo/ipm/LogHighs.cpp + highs/ipm/hipo/ipm/Model.cpp + highs/ipm/hipo/ipm/Refine.cpp + highs/ipm/hipo/ipm/Solver.cpp) + +set(hipo_headers_python + highs/ipm/hipo/ipm/CurtisReidScaling.h + highs/ipm/hipo/ipm/IpmData.h + highs/ipm/hipo/ipm/FactorHiGHSSolver.h + highs/ipm/hipo/ipm/Parameters.h + highs/ipm/hipo/ipm/Control.h + highs/ipm/hipo/ipm/Info.h + highs/ipm/hipo/ipm/Iterate.h + highs/ipm/hipo/ipm/LinearSolver.h + highs/ipm/hipo/ipm/LogHighs.h + highs/ipm/hipo/ipm/Model.h + highs/ipm/hipo/ipm/Options.h + highs/ipm/hipo/ipm/Solver.h + highs/ipm/hipo/ipm/Status.h) + +set(factor_highs_sources_python + highs/ipm/hipo/factorhighs/Analyse.cpp + highs/ipm/hipo/factorhighs/CallAndTimeBlas.cpp + highs/ipm/hipo/factorhighs/CliqueStack.cpp + highs/ipm/hipo/factorhighs/DataCollector.cpp + highs/ipm/hipo/factorhighs/DenseFactHybrid.cpp + highs/ipm/hipo/factorhighs/DenseFactKernel.cpp + highs/ipm/hipo/factorhighs/DgemmParallel.cpp + highs/ipm/hipo/factorhighs/FactorHiGHS.cpp + highs/ipm/hipo/factorhighs/Factorise.cpp + highs/ipm/hipo/factorhighs/FormatHandler.cpp + highs/ipm/hipo/factorhighs/HybridHybridFormatHandler.cpp + highs/ipm/hipo/factorhighs/HybridSolveHandler.cpp + highs/ipm/hipo/factorhighs/KrylovMethodsIpm.cpp + highs/ipm/hipo/factorhighs/Numeric.cpp + highs/ipm/hipo/factorhighs/SolveHandler.cpp + highs/ipm/hipo/factorhighs/Swaps.cpp + highs/ipm/hipo/factorhighs/Symbolic.cpp) + +set(factor_highs_headers_python + highs/ipm/hipo/factorhighs/Analyse.h + highs/ipm/hipo/factorhighs/CallAndTimeBlas.h + highs/ipm/hipo/factorhighs/CliqueStack.h + highs/ipm/hipo/factorhighs/DataCollector.h + highs/ipm/hipo/factorhighs/DenseFact.h + highs/ipm/hipo/factorhighs/DgemmParallel.h + highs/ipm/hipo/factorhighs/FactorHiGHS.h + highs/ipm/hipo/factorhighs/FactorHiGHSSettings.h + highs/ipm/hipo/factorhighs/Factorise.h + highs/ipm/hipo/factorhighs/FormatHandler.h + highs/ipm/hipo/factorhighs/HybridHybridFormatHandler.h + highs/ipm/hipo/factorhighs/HybridSolveHandler.h + highs/ipm/hipo/factorhighs/KrylovMethodsIpm.h + highs/ipm/hipo/factorhighs/Numeric.h + highs/ipm/hipo/factorhighs/ReturnValues.h + highs/ipm/hipo/factorhighs/SolveHandler.h + highs/ipm/hipo/factorhighs/Swaps.h + highs/ipm/hipo/factorhighs/Symbolic.h + highs/ipm/hipo/factorhighs/Timing.h) + +set(hipo_util_sources_python + highs/ipm/hipo/auxiliary/Auxiliary.cpp + highs/ipm/hipo/auxiliary/KrylovMethods.cpp + highs/ipm/hipo/auxiliary/Log.cpp + highs/ipm/hipo/auxiliary/VectorOperations.cpp) + +set(hipo_util_headers_python + highs/ipm/hipo/auxiliary/Auxiliary.h + highs/ipm/hipo/auxiliary/IntConfig.h + highs/ipm/hipo/auxiliary/KrylovMethods.h + highs/ipm/hipo/auxiliary/Log.h + highs/ipm/hipo/auxiliary/mycblas.h + highs/ipm/hipo/auxiliary/VectorOperations.h) + +set(hipo_orderings_sources_python + extern/amd/amd_1.c + extern/amd/amd_2.c + extern/amd/amd_aat.c + extern/amd/amd_control.c + extern/amd/amd_defaults.c + extern/amd/amd_info.c + extern/amd/amd_order.c + extern/amd/amd_post_tree.c + extern/amd/amd_postorder.c + extern/amd/amd_preprocess.c + extern/amd/amd_valid.c + extern/amd/SuiteSparse_config.c + extern/metis/GKlib/error.c + extern/metis/GKlib/mcore.c + extern/metis/GKlib/memory.c + extern/metis/GKlib/random.c + extern/metis/libmetis/auxapi.c + extern/metis/libmetis/balance.c + extern/metis/libmetis/bucketsort.c + extern/metis/libmetis/coarsen.c + extern/metis/libmetis/compress.c + extern/metis/libmetis/contig.c + extern/metis/libmetis/fm.c + extern/metis/libmetis/gklib.c + extern/metis/libmetis/graph.c + extern/metis/libmetis/initpart.c + extern/metis/libmetis/mcutil.c + extern/metis/libmetis/mmd.c + extern/metis/libmetis/ometis.c + extern/metis/libmetis/options.c + extern/metis/libmetis/refine.c + extern/metis/libmetis/separator.c + extern/metis/libmetis/sfm.c + extern/metis/libmetis/srefine.c + extern/metis/libmetis/util.c + extern/metis/libmetis/wspace.c + extern/rcm/rcm.cpp) + +set(hipo_orderings_headers + extern/amd/amd_internal.h + extern/amd/amd.h + extern/amd/SuiteSparse_config.h + extern/metis/GKlib/gk_arch.h + extern/metis/GKlib/gk_defs.h + extern/metis/GKlib/gk_macros.h + extern/metis/GKlib/gk_mkblas.h + extern/metis/GKlib/gk_mkmemory.h + extern/metis/GKlib/gk_mkpqueue.h + extern/metis/GKlib/gk_mkrandom.h + extern/metis/GKlib/gk_mksort.h + extern/metis/GKlib/gk_ms_inttypes.h + extern/metis/GKlib/gk_ms_stat.h + extern/metis/GKlib/gk_ms_stdint.h + extern/metis/GKlib/gk_proto.h + extern/metis/GKlib/gk_struct.h + extern/metis/GKlib/gk_types.h + extern/metis/GKlib/GKlib.h + extern/metis/libmetis/defs.h + extern/metis/libmetis/gklib_defs.h + extern/metis/libmetis/macros.h + extern/metis/libmetis/metislib.h + extern/metis/libmetis/proto.h + extern/metis/libmetis/stdheaders.h + extern/metis/libmetis/struct.h + extern/metis/metis.h + extern/rcm/rcm.h) + set(highs_sources_python extern/filereaderlp/reader.cpp highs/interfaces/highs_c_api.cpp diff --git a/cmake/sources.cmake b/cmake/sources.cmake index 0167c8075d..5ba766c410 100644 --- a/cmake/sources.cmake +++ b/cmake/sources.cmake @@ -1,7 +1,10 @@ set(include_dirs $ + $ $ + $ $ + $ $ $ $ diff --git a/pyproject.toml b/pyproject.toml index 4c2b1d88f5..7da58bf824 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -3,12 +3,12 @@ "Bug Tracker" = "https://github.com/ERGO-Code/HiGHS/issues" [build-system] -requires = ["scikit-build-core>=0.3.3", "pybind11", "numpy"] +requires = ["scikit-build-core", "pybind11", "numpy"] build-backend = "scikit_build_core.build" [project] name = "highspy" -version = "1.12.0" +version = "1.12.0.dev4" description = "A thin set of pybind11 wrappers to HiGHS" authors = [{ name = "HiGHS developers", email = "highsopt@gmail.com" }] readme = "README.md" @@ -33,7 +33,16 @@ classifiers = [ test = ["pytest", "numpy"] [tool.scikit-build] -cmake.args = ["-DPYTHON_BUILD_SETUP=ON"] + +# cmake.args = [ +# "-DPYTHON_BUILD_SETUP=ON", +# ] + +# To build locally, specify +# "-DHIPO=ON" +# On Windows and macOS also +# "-DBUILD_OPENBLAS=ON" + wheel.expand-macos-universal-tags = true # A list of packages to auto-copy into the wheel. If this is not set, it will @@ -50,6 +59,7 @@ sdist.include = [ "highs/highspy/__init__.pyi", "highs/highspy/_core/*.pyi", "tests/test_highspy.py", + "check/test_highspy_hipo.py", "Version.txt", "LICENSE", "README.md", @@ -66,8 +76,8 @@ sdist.exclude = [ ".github", "app", "build", - "check", - "docs", + "check/*", + "!check/test_highspy_hipo.py", # Re-include this specific file", "subprojects", ".coin-or", "build_webdemo.sh", @@ -191,6 +201,8 @@ sdist.exclude = [ # # The build directory. Defaults to a temporary directory, but can be set. # # build-dir = "" +[tool.scikit-build.cmake.define] +PYTHON_BUILD_SETUP = "ON" [tool.pytest.ini_options] minversion = "6.0"