From 9d72d79f38e4bf7bb91a7af4c76fc5141e4ceaad Mon Sep 17 00:00:00 2001 From: Richard Murray Date: Thu, 22 Dec 2022 15:19:18 -0800 Subject: [PATCH 1/5] add OS/BLAS pip-based test matrix as GitHub workflow --- .github/scripts/set-pip-test-matrix.py | 28 ++++ .github/workflows/os-blas-test-matrix.yml | 176 ++++++++++++++++++++++ 2 files changed, 204 insertions(+) create mode 100644 .github/scripts/set-pip-test-matrix.py create mode 100644 .github/workflows/os-blas-test-matrix.yml diff --git a/.github/scripts/set-pip-test-matrix.py b/.github/scripts/set-pip-test-matrix.py new file mode 100644 index 000000000..ed18239d0 --- /dev/null +++ b/.github/scripts/set-pip-test-matrix.py @@ -0,0 +1,28 @@ +""" set-pip-test-matrix.py + +Create test matrix for pip wheels +""" +import json +from pathlib import Path + +system_opt_blas_libs = {'ubuntu': ['OpenBLAS'], + 'macos' : ['OpenBLAS', 'Apple']} + +wheel_jobs = [] +for wkey in Path("slycot-wheels").iterdir(): + wos, wpy, wbl = wkey.name.split("-") + wheel_jobs.append({'packagekey': wkey.name, + 'os': wos, + 'python': wpy, + 'blas_lib': wbl, + }) + if wbl == "Generic": + for bl in system_opt_blas_libs[wos]: + wheel_jobs.append({ 'packagekey': wkey.name, + 'os': wos, + 'python': wpy, + 'blas_lib': bl, + }) + +matrix = { 'include': wheel_jobs } +print(json.dumps(matrix)) \ No newline at end of file diff --git a/.github/workflows/os-blas-test-matrix.yml b/.github/workflows/os-blas-test-matrix.yml new file mode 100644 index 000000000..ff5b37744 --- /dev/null +++ b/.github/workflows/os-blas-test-matrix.yml @@ -0,0 +1,176 @@ +name: OS/BLAS test matrix + +on: push + +jobs: + build-pip: + name: Build pip Py${{ matrix.python }}, ${{ matrix.os }}, ${{ matrix.bla_vendor}} BLA_VENDOR + runs-on: ${{ matrix.os }}-latest + strategy: + fail-fast: false + matrix: + os: + - 'ubuntu' + - 'macos' + python: + - '3.8' + - '3.11' + bla_vendor: [ 'unset' ] + include: + - os: 'ubuntu' + python: '3.11' + bla_vendor: 'Generic' + - os: 'ubuntu' + python: '3.11' + bla_vendor: 'OpenBLAS' + - os: 'macos' + python: '3.11' + bla_vendor: 'Apple' + - os: 'macos' + python: '3.11' + bla_vendor: 'Generic' + - os: 'macos' + python: '3.11' + bla_vendor: 'OpenBLAS' + + steps: + - name: Set up Python + uses: actions/setup-python@v4 + with: + python-version: ${{ matrix.python }} + - name: Checkout Slycot + uses: actions/checkout@v3 + with: + repository: python-control/Slycot + fetch-depth: 0 + submodules: 'recursive' + - name: Setup Ubuntu + if: matrix.os == 'ubuntu' + run: | + sudo apt-get -y update + sudo apt-get -y install gfortran cmake --fix-missing + case ${{ matrix.bla_vendor }} in + unset | Generic ) sudo apt-get -y install libblas-dev liblapack-dev ;; + OpenBLAS ) sudo apt-get -y install libopenblas-dev ;; + *) + echo "bla_vendor option ${{ matrix.bla_vendor }} not supported" + exit 1 ;; + esac + - name: Setup macOS + if: matrix.os == 'macos' + run: | + case ${{ matrix.bla_vendor }} in + unset | Generic | Apple ) ;; # Found in system + OpenBLAS ) + brew install openblas + echo "BLAS_ROOT=/usr/local/opt/openblas/" >> $GITHUB_ENV + echo "LAPACK_ROOT=/usr/local/opt/openblas/" >> $GITHUB_ENV + ;; + *) + echo "bla_vendor option ${{ matrix.bla_vendor }} not supported" + exit 1 ;; + esac + echo "FC=gfortran-11" >> $GITHUB_ENV + - name: Build wheel + env: + BLA_VENDOR: ${{ matrix.bla_vendor }} + CMAKE_GENERATOR: Unix Makefiles + run: | + if [[ $BLA_VENDOR = unset ]]; then unset BLA_VENDOR; fi + python -m pip install --upgrade pip + pip wheel -v -w . . + wheeldir=slycot-wheels/${{ matrix.os }}-${{ matrix.python }}-${{ matrix.bla_vendor }} + mkdir -p ${wheeldir} + cp ./slycot*.whl ${wheeldir}/ + - name: Save wheel + uses: actions/upload-artifact@v3 + with: + name: slycot-wheels + path: slycot-wheels + + + create-wheel-test-matrix: + name: Create wheel test matrix + runs-on: ubuntu-latest + needs: build-pip + if: always() # run tests for all successful builds, even if others failed + outputs: + matrix: ${{ steps.set-matrix.outputs.matrix }} + steps: + - name: Checkout python-control + uses: actions/checkout@v3 + - name: Download wheels (if any) + uses: actions/download-artifact@v3 + with: + name: slycot-wheels + path: slycot-wheels + - id: set-matrix + run: echo "matrix=$(python3 .github/scripts/set-pip-test-matrix.py)" >> $GITHUB_OUTPUT + + + test-wheel: + name: Test wheel ${{ matrix.packagekey }}, ${{matrix.blas_lib}} BLAS lib ${{ matrix.failok }} + needs: create-wheel-test-matrix + runs-on: ${{ matrix.os }}-latest + continue-on-error: ${{ matrix.failok == 'FAILOK' }} + + strategy: + fail-fast: false + matrix: ${{ fromJSON(needs.create-wheel-test-matrix.outputs.matrix) }} + + steps: + - name: Checkout Slycot + uses: actions/checkout@v3 + with: + repository: 'python-control/Slycot' + path: slycot-src + - name: Checkout python-control + uses: actions/checkout@v3 + with: + repository: 'python-control/python-control' + - name: Setup Python + uses: actions/setup-python@v4 + with: + python-version: ${{ matrix.python }} + - name: Setup Ubuntu + if: matrix.os == 'ubuntu' + run: | + set -xe + sudo apt-get -y update + case ${{ matrix.blas_lib }} in + Generic ) sudo apt-get -y install libblas3 liblapack3 ;; + unset | OpenBLAS ) sudo apt-get -y install libopenblas-base ;; + *) + echo "BLAS ${{ matrix.blas_lib }} not supported for wheels on Ubuntu" + exit 1 ;; + esac + update-alternatives --display libblas.so.3-x86_64-linux-gnu + update-alternatives --display liblapack.so.3-x86_64-linux-gnu + - name: Setup macOS + if: matrix.os == 'macos' + run: | + set -xe + brew install coreutils + case ${{ matrix.blas_lib }} in + unset | Generic | Apple ) ;; # system provided (Uses Apple Accelerate Framework) + OpenBLAS ) + brew install openblas + echo "DYLIB_LIBRARY_PATH=/usr/local/opt/openblas/lib" >> $GITHUB_ENV + ;; + *) + echo "BLAS option ${{ matrix.blas_lib }} not supported for wheels on MacOS" + exit 1 ;; + esac + - name: Download wheels + uses: actions/download-artifact@v3 + with: + name: slycot-wheels + path: slycot-wheels + - name: Install Wheel + run: | + python -m pip install --upgrade pip + pip install matplotlib scipy pytest pytest-cov pytest-timeout coverage coveralls + pip install slycot-wheels/${{ matrix.packagekey }}/slycot*.whl + pip show slycot + - name: Test with pytest + run: pytest -v control/tests From 120120253a398c30a1cb0c28d590be6f6c7594e6 Mon Sep 17 00:00:00 2001 From: Richard Murray Date: Thu, 22 Dec 2022 22:12:53 -0800 Subject: [PATCH 2/5] add OS/BLAS conda-based test matrix as GitHub workflow --- .github/conda-env/build-env.yml | 4 + .github/conda-env/test-env.yml | 1 + .github/scripts/set-conda-test-matrix.py | 34 ++++++ .github/workflows/os-blas-test-matrix.yml | 139 ++++++++++++++++++++++ 4 files changed, 178 insertions(+) create mode 100644 .github/conda-env/build-env.yml create mode 100644 .github/scripts/set-conda-test-matrix.py diff --git a/.github/conda-env/build-env.yml b/.github/conda-env/build-env.yml new file mode 100644 index 000000000..f75973640 --- /dev/null +++ b/.github/conda-env/build-env.yml @@ -0,0 +1,4 @@ +name: build-env +dependencies: + - boa + - numpy !=1.23.0 diff --git a/.github/conda-env/test-env.yml b/.github/conda-env/test-env.yml index a4944f768..1c28589a4 100644 --- a/.github/conda-env/test-env.yml +++ b/.github/conda-env/test-env.yml @@ -1,5 +1,6 @@ name: test-env dependencies: + - conda-build # for conda index - pip - coverage - coveralls diff --git a/.github/scripts/set-conda-test-matrix.py b/.github/scripts/set-conda-test-matrix.py new file mode 100644 index 000000000..954480cb0 --- /dev/null +++ b/.github/scripts/set-conda-test-matrix.py @@ -0,0 +1,34 @@ +""" set-conda-test-matrix.py + +Create test matrix for conda packages +""" +import json, re +from pathlib import Path + +osmap = {'linux': 'ubuntu', + 'osx': 'macos', + 'win': 'windows', + } + +blas_implementations = ['unset', 'Generic', 'OpenBLAS', 'Intel10_64lp'] + +combinations = {'ubuntu': blas_implementations, + 'macos': blas_implementations, + 'windows': ['unset', 'Intel10_64lp'], + } + +conda_jobs = [] +for conda_pkg_file in Path("slycot-conda-pkgs").glob("*/*.tar.bz2"): + cos = osmap[conda_pkg_file.parent.name.split("-")[0]] + m = re.search(r'py(\d)(\d+)_', conda_pkg_file.name) + pymajor, pyminor = int(m[1]), int(m[2]) + cpy = f'{pymajor}.{pyminor}' + for cbl in combinations[cos]: + cjob = {'packagekey': f'{cos}-{cpy}', + 'os': cos, + 'python': cpy, + 'blas_lib': cbl} + conda_jobs.append(cjob) + +matrix = { 'include': conda_jobs } +print(json.dumps(matrix)) diff --git a/.github/workflows/os-blas-test-matrix.yml b/.github/workflows/os-blas-test-matrix.yml index ff5b37744..2a08da31e 100644 --- a/.github/workflows/os-blas-test-matrix.yml +++ b/.github/workflows/os-blas-test-matrix.yml @@ -89,6 +89,57 @@ jobs: path: slycot-wheels + build-conda: + name: Build conda Py${{ matrix.python }}, ${{ matrix.os }} + runs-on: ${{ matrix.os }}-latest + strategy: + fail-fast: false + matrix: + os: + - 'ubuntu' + - 'macos' + - 'windows' + python: + - '3.9' + - '3.11' + + steps: + - name: Checkout Slycot + uses: actions/checkout@v3 + with: + repository: python-control/Slycot + fetch-depth: 0 + submodules: 'recursive' + - name: Setup Conda + uses: conda-incubator/setup-miniconda@v2 + with: + python-version: ${{ matrix.python }} + activate-environment: build-env + environment-file: .github/conda-env/build-env.yml + miniforge-version: latest + miniforge-variant: Mambaforge + channel-priority: strict + auto-update-conda: false + auto-activate-base: false + - name: Conda build + shell: bash -l {0} + run: | + set -e + numpyversion=$(python -c 'import numpy; print(numpy.version.version)') + conda mambabuild --python "${{ matrix.python }}" --numpy $numpyversion conda-recipe + # preserve directory structure for custom conda channel + find "${CONDA_PREFIX}/conda-bld" -maxdepth 2 -name 'slycot*.tar.bz2' | while read -r conda_pkg; do + conda_platform=$(basename $(dirname "${conda_pkg}")) + mkdir -p "slycot-conda-pkgs/${conda_platform}" + cp "${conda_pkg}" "slycot-conda-pkgs/${conda_platform}/" + done + - name: Save to local conda pkg channel + uses: actions/upload-artifact@v3 + with: + name: slycot-conda-pkgs + path: slycot-conda-pkgs + + create-wheel-test-matrix: name: Create wheel test matrix runs-on: ubuntu-latest @@ -108,6 +159,25 @@ jobs: run: echo "matrix=$(python3 .github/scripts/set-pip-test-matrix.py)" >> $GITHUB_OUTPUT + create-conda-test-matrix: + name: Create conda test matrix + runs-on: ubuntu-latest + needs: build-conda + if: always() # run tests for all successful builds, even if others failed + outputs: + matrix: ${{ steps.set-matrix.outputs.matrix }} + steps: + - name: Checkout python-control + uses: actions/checkout@v3 + - name: Download conda packages + uses: actions/download-artifact@v3 + with: + name: slycot-conda-pkgs + path: slycot-conda-pkgs + - id: set-matrix + run: echo "matrix=$(python3 .github/scripts/set-conda-test-matrix.py)" >> $GITHUB_OUTPUT + + test-wheel: name: Test wheel ${{ matrix.packagekey }}, ${{matrix.blas_lib}} BLAS lib ${{ matrix.failok }} needs: create-wheel-test-matrix @@ -174,3 +244,72 @@ jobs: pip show slycot - name: Test with pytest run: pytest -v control/tests + + + test-conda: + name: Test conda ${{ matrix.packagekey }}, ${{matrix.blas_lib}} BLAS lib ${{ matrix.failok }} + needs: create-conda-test-matrix + runs-on: ${{ matrix.os }}-latest + continue-on-error: ${{ matrix.failok == 'FAILOK' }} + + strategy: + fail-fast: false + matrix: ${{ fromJSON(needs.create-conda-test-matrix.outputs.matrix) }} + + defaults: + run: + shell: bash -l {0} + + steps: + - name: Checkout Slycot + uses: actions/checkout@v3 + with: + repository: 'python-control/Slycot' + path: slycot-src + - name: Checkout python-control + uses: actions/checkout@v3 + - name: Setup macOS + if: matrix.os == 'macos' + run: brew install coreutils + - name: Setup Conda + uses: conda-incubator/setup-miniconda@v2 + with: + python-version: ${{ matrix.python }} + miniforge-version: latest + miniforge-variant: Mambaforge + activate-environment: test-env + environment-file: .github/conda-env/test-env.yml + channel-priority: strict + auto-activate-base: false + - name: Download conda packages + uses: actions/download-artifact@v3 + with: + name: slycot-conda-pkgs + path: slycot-conda-pkgs + - name: Install Conda package + run: | + set -e + case ${{ matrix.blas_lib }} in + unset ) # the conda-forge default (os dependent) + mamba install libblas libcblas liblapack + ;; + Generic ) + mamba install 'libblas=*=*netlib' 'libcblas=*=*netlib' 'liblapack=*=*netlib' + echo "libblas * *netlib" >> $CONDA_PREFIX/conda-meta/pinned + ;; + OpenBLAS ) + mamba install 'libblas=*=*openblas' openblas + echo "libblas * *openblas" >> $CONDA_PREFIX/conda-meta/pinned + ;; + Intel10_64lp ) + mamba install 'libblas=*=*mkl' mkl + echo "libblas * *mkl" >> $CONDA_PREFIX/conda-meta/pinned + ;; + esac + conda index --no-progress ./slycot-conda-pkgs + mamba install -c ./slycot-conda-pkgs slycot + conda list + - name: Test with pytest + run: JOBNAME=$JOBNAME pytest control/tests + env: + JOBNAME: ${{ matrix.packagekey }} ${{ matrix.blas_lib }} From f477c1336e983f2eafe5d79a4b9360b8d01d2464 Mon Sep 17 00:00:00 2001 From: Richard Murray Date: Fri, 23 Dec 2022 20:00:38 -0800 Subject: [PATCH 3/5] triger on pull_request --- .github/workflows/os-blas-test-matrix.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/os-blas-test-matrix.yml b/.github/workflows/os-blas-test-matrix.yml index 2a08da31e..fdd59763e 100644 --- a/.github/workflows/os-blas-test-matrix.yml +++ b/.github/workflows/os-blas-test-matrix.yml @@ -1,6 +1,6 @@ name: OS/BLAS test matrix -on: push +on: pull_request jobs: build-pip: From b8c4e5c9f961a17bab76d2395998a1f21882a61b Mon Sep 17 00:00:00 2001 From: Richard Murray Date: Fri, 23 Dec 2022 20:55:37 -0800 Subject: [PATCH 4/5] add flatsys xfails for platform=ubunto, BLAS=Generic, numpy=1.24.0 --- control/tests/flatsys_test.py | 23 +++++++++++++++++++++-- 1 file changed, 21 insertions(+), 2 deletions(-) diff --git a/control/tests/flatsys_test.py b/control/tests/flatsys_test.py index 5e3fe5d7c..4d4c8cf6b 100644 --- a/control/tests/flatsys_test.py +++ b/control/tests/flatsys_test.py @@ -13,6 +13,8 @@ import scipy as sp import re import warnings +import os +import platform import control as ct import control.flatsys as fs @@ -201,9 +203,26 @@ def test_kinematic_car_ocp( minimize_kwargs={'method': method}, ) xd, ud = traj_ocp.eval(timepts) + if not traj_ocp.success: - # If unsuccessful, make sure the error is just about precision - assert re.match(".*precision loss.*", traj_ocp.message) is not None + # Known failure cases + if re.match(".*precision loss.*", traj_ocp.message): + pytest.xfail("precision loss in some configurations") + + elif re.match("Iteration limit.*", traj_ocp.message) and \ + re.match("ubuntu-3.* Generic", os.getenv('JOBNAME')) and \ + np.__version__ == '1.24.0': + pytest.xfail("gh820: iteration limit exceeded") + + else: + # Dump out information to allow creation of an exception + print("Platform: ", platform.platform()) + print("Python: ", platform.python_version()) + np.show_config() + print("JOBNAME: ", os.getenv('JOBNAME')) + + pytest.fail( + "unknown failure; view output to identify configuration") # Make sure the constraints are satisfied if input_constraints: From 4d6a6bf7b53b8c4b074738a54f7696e5669f9acd Mon Sep 17 00:00:00 2001 From: Richard Murray Date: Sat, 24 Dec 2022 07:05:56 -0800 Subject: [PATCH 5/5] change trigger to workflow_dispatch or PR against relevant files --- .github/workflows/os-blas-test-matrix.yml | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/.github/workflows/os-blas-test-matrix.yml b/.github/workflows/os-blas-test-matrix.yml index fdd59763e..fede19025 100644 --- a/.github/workflows/os-blas-test-matrix.yml +++ b/.github/workflows/os-blas-test-matrix.yml @@ -1,7 +1,15 @@ name: OS/BLAS test matrix -on: pull_request - +on: + workflow_dispatch: + pull_request: + paths: + - .github/workflows/os-blas-test-matrix.yml + - .github/scripts/set-conda-test-matrix.py + - .github/scripts/set-conda-pip-matrix.py + - .github/conda-env/build-env.yml + - .github/conda-env/test-env.yml + jobs: build-pip: name: Build pip Py${{ matrix.python }}, ${{ matrix.os }}, ${{ matrix.bla_vendor}} BLA_VENDOR pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy