diff --git a/.github/workflows/check-changelog.yml b/.github/workflows/check-changelog.yml deleted file mode 100644 index 7fe8a6ea7..000000000 --- a/.github/workflows/check-changelog.yml +++ /dev/null @@ -1,14 +0,0 @@ -name: Check-changelog -on: - pull_request: - types: [assigned, opened, synchronize, reopened, labeled, unlabeled] - branches: - - devel -jobs: - check-changelog: - name: Check changelog action - runs-on: ubuntu-latest - steps: - - uses: tarides/changelog-check-action@v4 - with: - changelog: CHANGELOG.md diff --git a/.github/workflows/ci-linux.yml b/.github/workflows/ci-linux.yml deleted file mode 100644 index a8a22f593..000000000 --- a/.github/workflows/ci-linux.yml +++ /dev/null @@ -1,93 +0,0 @@ -name: CI - Linux - -on: - push: - branches: - - devel - pull_request: - paths-ignore: - - CHANGELOG.md - -concurrency: - group: ${{ github.workflow }}-${{ github.ref }} - cancel-in-progress: true - -jobs: - ubuntu: - name: CI - Ubuntu ${{ matrix.ubuntu_version }} - ${{ matrix.build_type }} (APT) - runs-on: ubuntu-latest - container: - image: ubuntu:${{ matrix.ubuntu_version }} - strategy: - fail-fast: false - matrix: - ubuntu_version: ["22.04", "24.04"] - build_type: [Release, Debug] - env: - CCACHE_BASEDIR: ${{ github.workspace }} - CCACHE_DIR: ${{ github.workspace }}/.ccache - CCACHE_COMPRESS: true - CCACHE_COMPRESSLEVEL: 6 - CMAKE_C_COMPILER_LAUNCHER: ccache - CMAKE_CXX_COMPILER_LAUNCHER: ccache - DEBIAN_FRONTEND: noninteractive - steps: - - uses: actions/checkout@v6 - - name: Setup ccache - uses: actions/cache@v5 - with: - path: ${{ env.CCACHE_DIR }} - key: ccache-ubuntu-${{ matrix.ubuntu_version }}-${{ matrix.build_type }}-${{ github.sha }} - restore-keys: ccache-ubuntu-${{ matrix.ubuntu_version }}-${{ matrix.build_type }}- - - - name: Update APT repositories - run: apt-get update - - - name: Install dependencies via APT - run: apt-get install -y git cmake g++ ninja-build ccache graphviz libmatio-dev doxygen catch2 libeigen3-dev python3-numpy python3-dev python3-scipy libcereal-dev libsimde-dev - - - name: Clear ccache stats - run: ccache --show-stats --zero-stats --verbose - - - name: CMake Configure - run: cmake -G Ninja -S . -B build -DCMAKE_BUILD_TYPE=${{ matrix.build_type }} -DBUILD_PYTHON_INTERFACE=ON -DBUILD_TESTING=ON -DPROXSUITE_BUILD_EXAMPLES=ON -DBUILD_DOCUMENTATION=ON -DBUILD_BENCHMARK=ON - - - name: CMake Build - run: cmake --build build --verbose --parallel 2 - - - name: Show ccache stats - run: ccache --show-stats --verbose - - - name: CTest - run: ctest --test-dir build --output-on-failure - - - name: CMake Install - run: cmake --install build --prefix install - - archlinux: - name: CI - ArchLinux - runs-on: ubuntu-latest - container: - image: archlinux/archlinux:base-devel - steps: - - run: pacman -Syu --noconfirm cmake ninja catch2 git eigen cereal libmatio doxygen graphviz nanobind python-scipy simde - - uses: actions/checkout@v6 - - run: cmake -G Ninja -B build -S . -DBUILD_PYTHON_INTERFACE=ON -DBUILD_TESTING=ON -DPROXSUITE_BUILD_EXAMPLES=ON -DBUILD_DOCUMENTATION=ON -DBUILD_BENCHMARK=ON - - run: cmake --build build --verbose --parallel 2 - - run: ctest --test-dir build --output-on-failure - - check: - if: always() - name: check-linux - - needs: - - ubuntu - - archlinux - - runs-on: ubuntu-latest - - steps: - - name: Decide whether the needed jobs succeeded or failed - uses: re-actors/alls-green@release/v1 - with: - jobs: ${{ toJSON(needs) }} diff --git a/.github/workflows/ci-nix.yml b/.github/workflows/ci-nix.yml deleted file mode 100644 index bbc6403ea..000000000 --- a/.github/workflows/ci-nix.yml +++ /dev/null @@ -1,41 +0,0 @@ -name: CI - Nix - -on: - push: - branches: - - devel - pull_request: - branches: - - devel - -jobs: - nix: - runs-on: "${{ matrix.os }}" - strategy: - matrix: - os: ["ubuntu-24.04", "ubuntu-24.04-arm", "macos-15"] - extends: ["", "pkgs-eigen5"] - steps: - - uses: actions/checkout@v7 - - uses: cachix/install-nix-action@v31 - - uses: cachix/cachix-action@v17 - with: - name: gepetto - authToken: '${{ secrets.CACHIX_AUTH_TOKEN }}' - - run: nix flake check -L - - run: nix build -L ".#${{ matrix.extends }}" - - check: - if: always() - name: check-macos-linux-nix - - needs: - - nix - - runs-on: ubuntu-latest - - steps: - - name: Decide whether the needed jobs succeeded or failed - uses: re-actors/alls-green@release/v1 - with: - jobs: ${{ toJSON(needs) }} diff --git a/.github/workflows/ci-pixi.yml b/.github/workflows/ci-pixi.yml index 91f24a250..215624b09 100644 --- a/.github/workflows/ci-pixi.yml +++ b/.github/workflows/ci-pixi.yml @@ -26,13 +26,14 @@ jobs: CCACHE_COMPILERCHECK: content CMAKE_BUILD_TYPE: ${{ matrix.build_type }} PROXSUITE_CXX_STANDARD: ${{ matrix.cxx_std }} + PYTHONFAULTHANDLER: true strategy: fail-fast: false matrix: build_type: [Release, Debug] cxx_std: [17, 20] pixi_environment: [default] - os: [ubuntu-24.04, macos-15-intel, macos-26, windows-2022] + os: [windows-2022] steps: - uses: actions/checkout@v6 @@ -47,6 +48,15 @@ jobs: with: environments: ${{ matrix.pixi_environment }} + + - name: Enable User-Mode Dumps collecting + shell: powershell + run: | + New-Item '${{ github.workspace }}\CrashDumps' -Type Directory + Set-ItemProperty -Path 'HKLM:\SOFTWARE\Microsoft\Windows\Windows Error Reporting\LocalDumps' -Name 'DumpFolder' -Type ExpandString -Value '${{ github.workspace }}\CrashDumps' + Set-ItemProperty -Path 'HKLM:\SOFTWARE\Microsoft\Windows\Windows Error Reporting\LocalDumps' -Name 'DumpCount' -Type DWord -Value '10' + Set-ItemProperty -Path 'HKLM:\SOFTWARE\Microsoft\Windows\Windows Error Reporting\LocalDumps' -Name 'DumpType' -Type DWord -Value '2' + - name: Configure run: pixi run -e ${{ matrix.pixi_environment }} --skip-deps configure --fresh --log-level=DEBUG @@ -57,6 +67,13 @@ jobs: # if: ${{ !(startsWith(matrix.os, 'windows-') && matrix.build_type == 'Debug') }} run: pixi run -e ${{ matrix.pixi_environment }} --skip-deps test + - name: Artifact - Test + uses: actions/upload-artifact@v7 + if: ${{ always() }} + with: + name: CrashDumps-${{ matrix.pixi_environment }}-${{ matrix.os }}-${{ matrix.build_type }}-${{ matrix.cxx_std }} + path: '${{ github.workspace }}\build\bindings\python' + - name: Install run: pixi run -e ${{ matrix.pixi_environment }} --skip-deps install diff --git a/.github/workflows/ci-ros.yml b/.github/workflows/ci-ros.yml deleted file mode 100644 index 6e49a02ef..000000000 --- a/.github/workflows/ci-ros.yml +++ /dev/null @@ -1,69 +0,0 @@ -name: CI - ROS - Linux -on: - push: - branches: - - devel - pull_request: - paths-ignore: - - CHANGELOG.md - -concurrency: - group: ${{ github.workflow }}-${{ github.ref }} - cancel-in-progress: true - -jobs: - ros: - name: ROS ${{ matrix.ROS_DISTRO }} - ${{ matrix.os }} - strategy: - fail-fast: false - matrix: - include: - # ROS2 Humble Hawksbill (May 2022 - May 2027) - - ROS_DISTRO: humble - os: Ubuntu 22.04 (Jammy) - - # ROS2 Jazzy Jalisco (May 2024 - May 2029) - - ROS_DISTRO: jazzy - os: Ubuntu 24.04 (Noble) - - # ROS2 Kilted Kayu (May 2025 - December 2026) - - ROS_DISTRO: kilted - os: Ubuntu 24.04 (Noble) - - # ROS2 Rolling Ridley - - ROS_DISTRO: rolling - os: Ubuntu 26.04 (Resolute) - - # ROS2 Lyrical Luth (May 2026 - May 2031) - - ROS_DISTRO: lyrical - os: Ubuntu 26.04 (Resolute) - env: - CCACHE_DIR: ${{ github.workspace }}/.ccache - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v7 - - uses: actions/cache@v6 - with: - path: ${{ env.CCACHE_DIR }} - key: ccache-ci-ros-${{ matrix.ROS_DISTRO }}-${{github.run_id}} - restore-keys: ccache-ci-ros-${{ matrix.ROS_DISTRO }}- - - uses: ros-industrial/industrial_ci@125164b9f1883cdf1858897a7146d1bebf2be5c6 - env: - CMAKE_ARGS: -DBUILD_WITH_VECTORIZATION_SUPPORT=ON -DPROXSUITE_BUILD_WITH_SERIALIZATION=ON -DBUILD_PYTHON_INTERFACE=ON -DBUILD_TESTING=ON -DPROXSUITE_BUILD_EXAMPLES=ON -DBUILD_BENCHMARK=ON - VERBOSE_OUTPUT: true - VERBOSE_TESTS: true - ROS_DISTRO: ${{ matrix.ROS_DISTRO }} - - check: - if: always() - name: check-ci-linux-ros - - needs: - - ros - - runs-on: ubuntu-latest - steps: - - name: Decide whether the needed jobs succeeded or failed - uses: re-actors/alls-green@release/v1 - with: - jobs: ${{ toJSON(needs) }} diff --git a/.github/workflows/dockgen.yml b/.github/workflows/dockgen.yml deleted file mode 100644 index fd565ce92..000000000 --- a/.github/workflows/dockgen.yml +++ /dev/null @@ -1,53 +0,0 @@ -name: "Publish docker image" - -on: - push: - branches: - - devel - tags: - - "v*" - -jobs: - dockgen: - runs-on: "ubuntu-latest" - permissions: - contents: read - packages: write - attestations: write - id-token: write - steps: - - uses: actions/checkout@v7 - - - uses: astral-sh/setup-uv@v7 - - run: uvx dockgen - - # https://docs.github.com/en/packages/managing-github-packages-using-github-actions-workflows/publishing-and-installing-a-package-with-github-actions - - - name: Log in to the Container registry - uses: docker/login-action@v4 - with: - registry: ghcr.io - username: ${{ github.actor }} - password: ${{ secrets.GITHUB_TOKEN }} - - - name: Extract metadata (tags, labels) for Docker - id: meta - uses: docker/metadata-action@v6 - with: - images: ghcr.io/${{ github.repository }} - - - name: Build and push Docker image - id: push - uses: docker/build-push-action@v7 - with: - context: . - push: true - tags: ${{ steps.meta.outputs.tags }} - labels: ${{ steps.meta.outputs.labels }} - - - name: Generate artifact attestation - uses: actions/attest-build-provenance@v4 - with: - subject-name: ghcr.io/${{ github.repository }} - subject-digest: ${{ steps.push.outputs.digest }} - push-to-registry: true diff --git a/.github/workflows/gh-pages.yml b/.github/workflows/gh-pages.yml deleted file mode 100644 index bb403a9c2..000000000 --- a/.github/workflows/gh-pages.yml +++ /dev/null @@ -1,56 +0,0 @@ -name: Github Pages Deployment -on: - release: - types: - - published - -jobs: - build_doc: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v7 - - - name: Install Pixi - uses: prefix-dev/setup-pixi@v0.9.3 - - - name: Build documentation - run: pixi run build-documentation - - - name: Install documentation - run: pixi run install-documentation - - - name: Archive artifacts - uses: actions/upload-artifact@v7 - with: - name: site - path: build/doc/html - - deploy: - runs-on: ubuntu-latest - needs: [build_doc] - steps: - - name: Download artifacts - uses: actions/download-artifact@v8 - with: - name: site - path: site - - name: Deploy - uses: JamesIves/github-pages-deploy-action@v4.9.0 - with: - folder: site - - check: - if: always() - name: check-linux - - needs: - - build_doc - - deploy - - runs-on: ubuntu-latest - - steps: - - name: Decide whether the needed jobs succeeded or failed - uses: re-actors/alls-green@release/v1 - with: - jobs: ${{ toJSON(needs) }} \ No newline at end of file diff --git a/.github/workflows/update-flake-lock.yml b/.github/workflows/update-flake-lock.yml deleted file mode 100644 index 1c7939e10..000000000 --- a/.github/workflows/update-flake-lock.yml +++ /dev/null @@ -1,19 +0,0 @@ -name: update-flake-lock - -on: - workflow_dispatch: - schedule: - - cron: '0 9 9 * *' - -jobs: - lockfile: - runs-on: ubuntu-latest - steps: - - name: Checkout repository - uses: actions/checkout@v7 - - name: Install Nix - uses: DeterminateSystems/nix-installer-action@main - - name: Update flake.lock - uses: DeterminateSystems/update-flake-lock@main - with: - token: ${{ secrets.GH_TOKEN_FOR_UPDATES }} diff --git a/examples/python/init_with_default_options.py b/examples/python/init_with_default_options.py index 0633fec73..6e26ca1c6 100644 --- a/examples/python/init_with_default_options.py +++ b/examples/python/init_with_default_options.py @@ -10,9 +10,9 @@ H, g, A, b, C, u, l = generate_mixed_qp(n) # initialize the model of the problem to solve qp.init(H, g, A, b, C, l, u, rho=1.0e-7, mu_eq=1.0e-4) -qp.solve() +# qp.solve() # If we redo a solve, qp.settings.default_rho value = 1.e-7, hence qp.results.info.rho restarts at 1.e-7 # The same occurs for mu_eq. -qp.solve() +# qp.solve() # There might be a different result with WARM_START_WITH_PREVIOUS_RESULT initial guess option, as # by construction, it reuses the last proximal step sizes of the last solving method. diff --git a/examples/python/overview-simple.py b/examples/python/overview-simple.py index 2820b59b6..654db1ef5 100644 --- a/examples/python/overview-simple.py +++ b/examples/python/overview-simple.py @@ -1,17 +1,97 @@ +import sys import proxsuite from util import generate_mixed_qp +import numpy as np # generate a qp problem n = 10 H, g, A, b, C, u, l = generate_mixed_qp(n) +H = np.eye(10) +g = np.zeros(10) +A = np.zeros((2, 10)) +A[0] = 1.0 +b = np.zeros(2) +C = A[:] +l = np.ones(2) * -1 +u = np.ones(2) * 1 + +H = np.array( + [ + [1.35833528, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.05404331, 0.0], + [0.0, 1.35833528, 0.0, 0.0, 0.0, 0.0, 0.0, -1.11274754, -0.06365157, 0.0], + [0.0, 0.0, 1.35833528, 0.0, 0.0, 0.0, 0.0, 0.0, 0.69609101, 0.0], + [0.0, 0.0, 0.0, 2.31797205, 0.0, 0.0, -0.63411468, 0.0, 0.0, 0.34927708], + [0.0, 0.0, 0.0, 0.0, 1.35833528, 0.0, 0.0, 0.0, 0.50763146, 0.0], + [0.0, 0.0, 0.0, 0.0, 0.0, 1.35833528, 0.0, 0.0, 0.0, 0.0], + [0.0, 0.0, 0.0, -0.63411468, 0.0, 0.0, 1.35833528, 0.0, 0.0, 0.0], + [0.0, -1.11274754, 0.0, 0.0, 0.0, 0.0, 0.0, 1.35833528, 0.0, 0.0], + [ + 0.05404331, + -0.06365157, + 0.69609101, + 0.0, + 0.50763146, + 0.0, + 0.0, + 0.0, + 1.35833528, + 0.0, + ], + [0.0, 0.0, 0.0, 0.34927708, 0.0, 0.0, 0.0, 0.0, 0.0, 1.35833528], + ] +) +g = np.array( + [ + 1.92383191, + 0.99109127, + 0.3806108, + -0.74776636, + -1.3176775, + 1.33291008, + -0.68454025, + 1.25598233, + 0.49672635, + 0.3292758, + ] +) +# A = np.array( +# [ +# [0.0, 0.0, 0.11900865, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], +# [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], +# ] +# ) +# b = np.array([0.14268159, 0.0]) +A = np.zeros((0, 0)) +b = np.array([]) +C = np.array( + [ + [0.0, 0.0, 0.0, 0.41005165, 0.0, 0.0, 0.0, 0.37756379, 0.0, 0.0], + [0.19829972, 0.0, 0.18656139, 0.0, 0.0, 0.0, 0.0, 0.0, -0.67066229, 0.0], + ] +) +u = np.array([0.1051245, 0.4784386]) +l = np.array([-1.0e20, -1.0e20]) + + n_eq = A.shape[0] n_in = C.shape[0] + +print(f"{H=}", file=sys.stderr) +print(f"{g=}", file=sys.stderr) +print(f"{A=}", file=sys.stderr) +print(f"{b=}", file=sys.stderr) +print(f"{C=}", file=sys.stderr) +print(f"{u=}", file=sys.stderr) +print(f"{l=}", file=sys.stderr) +print(f"{A.shape}", file=sys.stderr) +print(f"{C.shape}", file=sys.stderr) + # solve it qp = proxsuite.proxqp.dense.QP(n, n_eq, n_in) qp.init(H, g, A, b, C, l, u) qp.solve() # print an optimal solution -print(f"optimal x: {qp.results.x}") -print(f"optimal y: {qp.results.y}") -print(f"optimal z: {qp.results.z}") +print(f"optimal x: {qp.results.x}", file=sys.stderr) +print(f"optimal y: {qp.results.y}", file=sys.stderr) +print(f"optimal z: {qp.results.z}", file=sys.stderr) diff --git a/include/proxsuite/proxqp/dense/workspace.hpp b/include/proxsuite/proxqp/dense/workspace.hpp index 6296af36b..75140c521 100644 --- a/include/proxsuite/proxqp/dense/workspace.hpp +++ b/include/proxsuite/proxqp/dense/workspace.hpp @@ -309,6 +309,7 @@ struct Workspace active_part_z.setZero(); active_set_up.setConstant(false); active_set_low.setConstant(false); + active_inequalities.setConstant(false); dw_aug.setZero(); rhs.setZero(); err.setZero();