diff --git a/.github/workflows/conda-package-cf.yml b/.github/workflows/conda-package-cf.yml index 907344a..b3a1da6 100644 --- a/.github/workflows/conda-package-cf.yml +++ b/.github/workflows/conda-package-cf.yml @@ -108,6 +108,14 @@ jobs: channels: conda-forge python-version: ${{ matrix.python }} + - name: Update conda + run: | + conda update -n base --all + + - name: Install conda build + run: | + conda install -n base -y conda-build + - name: Cache conda packages uses: actions/cache@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5.0.5 env: @@ -126,9 +134,12 @@ jobs: echo "CONDA_BLD=$CONDA\\conda-bld\\win-64\\" >> "$GITHUB_ENV" echo "WHEELS_OUTPUT_FOLDER=$GITHUB_WORKSPACE\\" >> "$GITHUB_ENV" - - name: Install conda build + - name: Show Conda info + run: | + conda info --all + + - name: List base environment packages run: | - conda install -n base -y conda-build conda list -n base - name: Build conda package @@ -301,3 +312,153 @@ jobs: run: | conda activate ${{ env.TEST_ENV_NAME }} pytest -v --pyargs ${{ env.MODULE_NAME }} + + build_osx: + runs-on: macos-26-intel + + strategy: + matrix: + python: ['3.10', '3.11', '3.12', '3.13', '3.14'] + + steps: + - name: Cancel Previous Runs + uses: styfle/cancel-workflow-action@d07a454dad7609a92316b57b23c9ccfd4f59af66 # 0.13.1 + with: + access_token: ${{ github.token }} + + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 + with: + fetch-depth: 0 + + - uses: conda-incubator/setup-miniconda@8ee1f361103df19b6f8c8655fd3967a8ecb162d5 # v4.0.1 + with: + miniforge-version: latest + activate-environment: build + channels: conda-forge + python-version: ${{ matrix.python }} + + - name: Cache conda packages + uses: actions/cache@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5.0.5 + env: + CACHE_NUMBER: 0 # Increase to reset cache + with: + path: /Users/runner/conda_pkgs_dir + key: + ${{ runner.os }}-conda-${{ env.CACHE_NUMBER }}-python-${{ matrix.python }}-${{hashFiles('**/meta.yaml') }} + restore-keys: | + ${{ runner.os }}-conda-${{ env.CACHE_NUMBER }}-python-${{ matrix.python }}- + ${{ runner.os }}-conda-${{ env.CACHE_NUMBER }}- + + - name: Install conda-build + shell: bash -el {0} + run: | + conda install -n base -y conda-build + conda list -n base + + - name: Store conda paths as envs + shell: bash -el {0} + run: | + echo "CONDA_BLD=$CONDA/conda-bld/osx-64/" >> "$GITHUB_ENV" + echo "WHEELS_OUTPUT_FOLDER=$GITHUB_WORKSPACE/" >> "$GITHUB_ENV" + + - name: Build conda package + shell: bash -el {0} + run: | + CHANNELS=(-c conda-forge -c conda-forge/label/python_rc --override-channels) + VERSIONS=(--python "${{ matrix.python }}") + TEST=(--no-test) + + conda build \ + "${TEST[@]}" \ + "${VERSIONS[@]}" \ + "${CHANNELS[@]}" \ + conda-recipe-cf + + - name: Upload artifact + uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 + with: + name: ${{ env.PACKAGE_NAME }} ${{ runner.os }} Python ${{ matrix.python }} + path: ${{ env.CONDA_BLD }}${{ env.PACKAGE_NAME }}-*.conda + + - name: Upload wheels artifact + uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 + with: + name: ${{ env.PACKAGE_NAME }} ${{ runner.os }} Wheels Python ${{ matrix.python }} + path: ${{ env.WHEELS_OUTPUT_FOLDER }}mkl_service-*.whl + + test_osx: + needs: build_osx + runs-on: ${{ matrix.runner }} + + strategy: + matrix: + python: ['3.10', '3.11', '3.12', '3.13', '3.14'] + experimental: [false] + runner: [macos-26-intel] + continue-on-error: ${{ matrix.experimental }} + env: + CHANNELS: -c conda-forge -c conda-forge/label/python_rc --override-channels + + steps: + - name: Download artifact + uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1 + with: + name: ${{ env.PACKAGE_NAME }} ${{ runner.os }} Python ${{ matrix.python }} + + - uses: conda-incubator/setup-miniconda@8ee1f361103df19b6f8c8655fd3967a8ecb162d5 # v4.0.1 + with: + miniforge-version: latest + channels: conda-forge + activate-environment: base + + - name: Install conda-index + shell: bash -el {0} + run: conda install -n base -y conda-index + + - name: Create conda channel + shell: bash -el {0} + run: | + mkdir -p "$GITHUB_WORKSPACE/channel/osx-64" + conda index "$GITHUB_WORKSPACE/channel" || exit 1 + mv "${PACKAGE_NAME}"-*.conda "$GITHUB_WORKSPACE/channel/osx-64" || exit 1 + conda index "$GITHUB_WORKSPACE/channel" || exit 1 + # Test channel + conda search "$PACKAGE_NAME" -c "$GITHUB_WORKSPACE/channel" --override-channels --info --json > "$GITHUB_WORKSPACE/ver.json" + cat ver.json + + - name: Collect dependencies + shell: bash -el {0} + run: | + CHANNELS=(-c "$GITHUB_WORKSPACE/channel" -c conda-forge -c conda-forge/label/python_rc --override-channels) + PACKAGE_VERSION="$(python -c "${VER_SCRIPT1} ${VER_SCRIPT2}")" + export PACKAGE_VERSION + conda create -n "${{ env.TEST_ENV_NAME }}" "$PACKAGE_NAME=$PACKAGE_VERSION" "python=${{ matrix.python }}" "${CHANNELS[@]}" --only-deps --dry-run > lockfile + cat lockfile + + - name: Cache conda packages + uses: actions/cache@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5.0.5 + env: + CACHE_NUMBER: 0 # Increase to reset cache + with: + path: /Users/runner/conda_pkgs_dir + key: + ${{ runner.os }}-conda-${{ env.CACHE_NUMBER }}-python-${{ matrix.python }}-${{hashFiles('lockfile') }} + restore-keys: | + ${{ runner.os }}-conda-${{ env.CACHE_NUMBER }}-python-${{ matrix.python }}- + ${{ runner.os }}-conda-${{ env.CACHE_NUMBER }}- + + - name: Install mkl-service + shell: bash -el {0} + run: | + CHANNELS=(-c "$GITHUB_WORKSPACE/channel" -c conda-forge -c conda-forge/label/python_rc --override-channels) + PACKAGE_VERSION="$(python -c "${VER_SCRIPT1} ${VER_SCRIPT2}")" + export PACKAGE_VERSION + conda create -n "${{ env.TEST_ENV_NAME }}" "$PACKAGE_NAME=$PACKAGE_VERSION" pytest "python=${{ matrix.python }}" "${CHANNELS[@]}" + # Test installed packages + conda list -n "${{ env.TEST_ENV_NAME }}" + + - name: Run tests + shell: bash -el {0} + run: | + conda activate ${{ env.TEST_ENV_NAME }} + pytest -vv --pyargs ${{ env.MODULE_NAME }} diff --git a/CHANGELOG.md b/CHANGELOG.md index 1aad224..67f622f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Added ### Changed +* Make `mkl-service` backward compatibility from MKL 2026.0 down to at least 2023.2 [gh-193](https://github.com/IntelPython/mkl-service/pull/193) ### Fixed * Changed insecure HTTP URLs to HTTPS in `pyproject.toml` and conda recipe files for improved security diff --git a/conda-recipe-cf/conda_build_config.yaml b/conda-recipe-cf/conda_build_config.yaml index d4b34a3..4f4ebfe 100644 --- a/conda-recipe-cf/conda_build_config.yaml +++ b/conda-recipe-cf/conda_build_config.yaml @@ -1,16 +1,14 @@ c_compiler: # [linux] - gcc # [linux] -cxx_compiler: # [linux] - - gxx # [linux] -cxx_compiler_version: # [linux] - - '14' # [linux] c_stdlib: # [linux] - sysroot # [linux] c_stdlib_version: # [linux] - '2.28' # [linux] +c_compiler: # [osx] + - clang # [osx] +c_stdlib: # [osx] + - macosx_deployment_target # [osx] c_stdlib: # [win] - vs # [win] -cxx_compiler: # [win] - - vs2022 # [win] c_compiler: # [win] - vs2022 # [win] diff --git a/conda-recipe-cf/meta.yaml b/conda-recipe-cf/meta.yaml index 1ccfc05..d1f237d 100644 --- a/conda-recipe-cf/meta.yaml +++ b/conda-recipe-cf/meta.yaml @@ -7,6 +7,7 @@ source: build: number: {{ GIT_DESCRIBE_NUMBER }} + skip: true # [osx and arm64] script_env: - WHEELS_OUTPUT_FOLDER ignore_run_exports: @@ -22,7 +23,8 @@ requirements: - python-gil # [py>=314] - pip >=25.0 - setuptools >=77 - - mkl-devel + - mkl-devel # [not osx] + - mkl-devel <2024 # [osx] - cython - wheel >=0.45.1 - python-build >=1.2.2 diff --git a/conda-recipe/conda_build_config.yaml b/conda-recipe/conda_build_config.yaml index d4b34a3..49c17b0 100644 --- a/conda-recipe/conda_build_config.yaml +++ b/conda-recipe/conda_build_config.yaml @@ -1,16 +1,10 @@ -c_compiler: # [linux] - - gcc # [linux] -cxx_compiler: # [linux] - - gxx # [linux] -cxx_compiler_version: # [linux] - - '14' # [linux] -c_stdlib: # [linux] - - sysroot # [linux] -c_stdlib_version: # [linux] - - '2.28' # [linux] -c_stdlib: # [win] - - vs # [win] -cxx_compiler: # [win] - - vs2022 # [win] -c_compiler: # [win] - - vs2022 # [win] +c_compiler: # [linux] + - gcc # [linux] +c_stdlib: # [linux] + - sysroot # [linux] +c_stdlib_version: # [linux] + - '2.28' # [linux] +c_stdlib: # [win] + - vs # [win] +c_compiler: # [win] + - vs2022 # [win] diff --git a/mkl/_mkl_service.pxd b/mkl/_mkl_service.pxd index 7319339..4cba157 100644 --- a/mkl/_mkl_service.pxd +++ b/mkl/_mkl_service.pxd @@ -59,7 +59,6 @@ cdef extern from "mkl.h": int MKL_CBWR_AVX2 int MKL_CBWR_AVX512 int MKL_CBWR_AVX512_E1 - int MKL_CBWR_AVX10 int MKL_CBWR_SUCCESS int MKL_CBWR_ERR_INVALID_SETTINGS @@ -74,12 +73,10 @@ cdef extern from "mkl.h": int MKL_ENABLE_AVX512_E3 int MKL_ENABLE_AVX512_E4 int MKL_ENABLE_AVX512_E1 - int MKL_ENABLE_AVX512_E5 int MKL_ENABLE_AVX512 int MKL_ENABLE_AVX2 int MKL_ENABLE_AVX2_E1 int MKL_ENABLE_SSE4_2 - int MKL_ENABLE_AVX10 # MPI Implementation Constants int MKL_BLACS_CUSTOM @@ -169,3 +166,62 @@ cdef extern from "mkl.h": int vmlSetErrStatus(const MKL_INT status) int vmlGetErrStatus() int vmlClearErrStatus() + +# version-compat shim +cdef extern from *: + """ + #include + + /* define constants removed in 2026.0 if undefined */ + #ifndef MKL_CBWR_SSSE3 + #define MKL_CBWR_SSSE3 -1 + #endif + #ifndef MKL_CBWR_SSE4_1 + #define MKL_CBWR_SSE4_1 -1 + #endif + #ifndef MKL_CBWR_AVX + #define MKL_CBWR_AVX -1 + #endif + #ifndef MKL_CBWR_AVX512_MIC + #define MKL_CBWR_AVX512_MIC -1 + #endif + #ifndef MKL_CBWR_AVX512_MIC_E1 + #define MKL_CBWR_AVX512_MIC_E1 -1 + #endif + + #ifndef MKL_ENABLE_AVX512_MIC_E1 + #define MKL_ENABLE_AVX512_MIC_E1 -1 + #endif + #ifndef MKL_ENABLE_AVX512_MIC + #define MKL_ENABLE_AVX512_MIC -1 + #endif + #ifndef MKL_ENABLE_AVX + #define MKL_ENABLE_AVX -1 + #endif + + /* define constants from 2026.0 if undefined */ + #ifndef MKL_CBWR_AVX10 + #define MKL_CBWR_AVX10 -2 + #endif + + #ifndef MKL_ENABLE_AVX512_E5 + #define MKL_ENABLE_AVX512_E5 -2 + #endif + #ifndef MKL_ENABLE_AVX10 + #define MKL_ENABLE_AVX10 -2 + #endif + """ + int MKL_CBWR_SSSE3 + int MKL_CBWR_SSE4_1 + int MKL_CBWR_AVX + int MKL_CBWR_AVX512_MIC + int MKL_CBWR_AVX512_MIC_E1 + + int MKL_ENABLE_AVX512_MIC_E1 + int MKL_ENABLE_AVX512_MIC + int MKL_ENABLE_AVX + + int MKL_CBWR_AVX10 + + int MKL_ENABLE_AVX512_E5 + int MKL_ENABLE_AVX10 diff --git a/mkl/_mkl_service.pyx b/mkl/_mkl_service.pyx index d46011d..975a454 100644 --- a/mkl/_mkl_service.pyx +++ b/mkl/_mkl_service.pyx @@ -684,8 +684,6 @@ cdef object __cbwr_set(branch=None): "avx512,strict": mkl.MKL_CBWR_AVX512 | mkl.MKL_CBWR_STRICT, "avx512_e1": mkl.MKL_CBWR_AVX512_E1, "avx512_e1,strict": mkl.MKL_CBWR_AVX512_E1 | mkl.MKL_CBWR_STRICT, - "avx10": mkl.MKL_CBWR_AVX10, - "avx10,strict": mkl.MKL_CBWR_AVX10 | mkl.MKL_CBWR_STRICT, }, "output": { mkl.MKL_CBWR_SUCCESS: "success", @@ -694,6 +692,27 @@ cdef object __cbwr_set(branch=None): mkl.MKL_CBWR_ERR_MODE_CHANGE_FAILURE: "err_mode_change_failure", }, } + # new CNR branches added in 2026.0 + if mkl.MKL_CBWR_AVX10 != -2: + __variables["input"]["avx10"] = mkl.MKL_CBWR_AVX10 + __variables["input"]["avx10,strict"] = mkl.MKL_CBWR_AVX10 | mkl.MKL_CBWR_STRICT + # legacy branches removed in 2026.0 + if mkl.MKL_CBWR_SSSE3 != -1: + __variables["input"]["ssse3"] = mkl.MKL_CBWR_SSSE3 + if mkl.MKL_CBWR_SSE4_1 != -1: + __variables["input"]["sse4_1"] = mkl.MKL_CBWR_SSE4_1 + if mkl.MKL_CBWR_AVX != -1: + __variables["input"]["avx"] = mkl.MKL_CBWR_AVX + if mkl.MKL_CBWR_AVX512_MIC != -1: + __variables["input"]["avx512_mic"] = mkl.MKL_CBWR_AVX512_MIC + __variables["input"][ + "avx512_mic,strict" + ] = mkl.MKL_CBWR_AVX512_MIC | mkl.MKL_CBWR_STRICT + if mkl.MKL_CBWR_AVX512_MIC_E1 != -1: + __variables["input"]["avx512_mic_e1"] = mkl.MKL_CBWR_AVX512_MIC_E1 + __variables["input"][ + "avx512_mic_e1,strict" + ] = mkl.MKL_CBWR_AVX512_MIC_E1 | mkl.MKL_CBWR_STRICT mkl_branch = __mkl_str_to_int(branch, __variables["input"]) mkl_status = mkl.mkl_cbwr_set(mkl_branch) @@ -723,11 +742,30 @@ cdef inline __cbwr_get(cnr_const=None): mkl.MKL_CBWR_AVX512 | mkl.MKL_CBWR_STRICT: "avx512,strict", mkl.MKL_CBWR_AVX512_E1: "avx512_e1", mkl.MKL_CBWR_AVX512_E1 | mkl.MKL_CBWR_STRICT: "avx512_e1,strict", - mkl.MKL_CBWR_AVX10: "avx10", - mkl.MKL_CBWR_AVX10 | mkl.MKL_CBWR_STRICT: "avx10,strict", mkl.MKL_CBWR_ERR_INVALID_INPUT: "err_invalid_input", }, } + # new CNR branches added in 2026.0 + if mkl.MKL_CBWR_AVX10 != -2: + __variables["output"][mkl.MKL_CBWR_AVX10] = "avx10" + __variables["output"][mkl.MKL_CBWR_AVX10 | mkl.MKL_CBWR_STRICT] = "avx10,strict" + # legacy branches removed in 2026.0 + if mkl.MKL_CBWR_SSSE3 != -1: + __variables["output"][mkl.MKL_CBWR_SSSE3] = "ssse3" + if mkl.MKL_CBWR_SSE4_1 != -1: + __variables["output"][mkl.MKL_CBWR_SSE4_1] = "sse4_1" + if mkl.MKL_CBWR_AVX != -1: + __variables["output"][mkl.MKL_CBWR_AVX] = "avx" + if mkl.MKL_CBWR_AVX512_MIC != -1: + __variables["output"][mkl.MKL_CBWR_AVX512_MIC] = "avx512_mic" + __variables["output"][ + mkl.MKL_CBWR_AVX512_MIC | mkl.MKL_CBWR_STRICT + ] = "avx512_mic,strict" + if mkl.MKL_CBWR_AVX512_MIC_E1 != -1: + __variables["output"][mkl.MKL_CBWR_AVX512_MIC_E1] = "avx512_mic_e1" + __variables["output"][ + mkl.MKL_CBWR_AVX512_MIC_E1 | mkl.MKL_CBWR_STRICT + ] = "avx512_mic_e1,strict" mkl_cnr_const = __mkl_str_to_int(cnr_const, __variables["input"]) mkl_status = mkl.mkl_cbwr_get(mkl_cnr_const) @@ -753,12 +791,31 @@ cdef object __cbwr_get_auto_branch(): mkl.MKL_CBWR_AVX512 | mkl.MKL_CBWR_STRICT: "avx512,strict", mkl.MKL_CBWR_AVX512_E1: "avx512_e1", mkl.MKL_CBWR_AVX512_E1 | mkl.MKL_CBWR_STRICT: "avx512_e1,strict", - mkl.MKL_CBWR_AVX10: "avx10", - mkl.MKL_CBWR_AVX10 | mkl.MKL_CBWR_STRICT: "avx10,strict", mkl.MKL_CBWR_SUCCESS: "success", mkl.MKL_CBWR_ERR_INVALID_INPUT: "err_invalid_input", }, } + # new CNR branch added in 2026.0 + if mkl.MKL_CBWR_AVX10 != -2: + __variables["output"][mkl.MKL_CBWR_AVX10] = "avx10" + __variables["output"][mkl.MKL_CBWR_AVX10 | mkl.MKL_CBWR_STRICT] = "avx10,strict" + # legacy CNR branches removed in 2026.0 + if mkl.MKL_CBWR_SSSE3 != -1: + __variables["output"][mkl.MKL_CBWR_SSSE3] = "ssse3" + if mkl.MKL_CBWR_SSE4_1 != -1: + __variables["output"][mkl.MKL_CBWR_SSE4_1] = "sse4_1" + if mkl.MKL_CBWR_AVX != -1: + __variables["output"][mkl.MKL_CBWR_AVX] = "avx" + if mkl.MKL_CBWR_AVX512_MIC != -1: + __variables["output"][mkl.MKL_CBWR_AVX512_MIC] = "avx512_mic" + __variables["output"][ + mkl.MKL_CBWR_AVX512_MIC | mkl.MKL_CBWR_STRICT + ] = "avx512_mic,strict" + if mkl.MKL_CBWR_AVX512_MIC_E1 != -1: + __variables["output"][mkl.MKL_CBWR_AVX512_MIC_E1] = "avx512_mic_e1" + __variables["output"][ + mkl.MKL_CBWR_AVX512_MIC_E1 | mkl.MKL_CBWR_STRICT + ] = "avx512_mic_e1,strict" mkl_status = mkl.mkl_cbwr_get_auto_branch() @@ -779,14 +836,24 @@ cdef object __enable_instructions(isa=None): "avx512_e3": mkl.MKL_ENABLE_AVX512_E3, "avx512_e2": mkl.MKL_ENABLE_AVX512_E2, "avx512_e1": mkl.MKL_ENABLE_AVX512_E1, - "avx512_e5": mkl.MKL_ENABLE_AVX512_E5, "avx512": mkl.MKL_ENABLE_AVX512, "avx2_e1": mkl.MKL_ENABLE_AVX2_E1, "avx2": mkl.MKL_ENABLE_AVX2, "sse4_2": mkl.MKL_ENABLE_SSE4_2, - "avx10": mkl.MKL_ENABLE_AVX10, }, } + # new constants added in 2026.0 + if mkl.MKL_ENABLE_AVX512_E5 != -2: + __variables["input"]["avx512_e5"] = mkl.MKL_ENABLE_AVX512_E5 + if mkl.MKL_ENABLE_AVX10 != -2: + __variables["input"]["avx10"] = mkl.MKL_ENABLE_AVX10 + # legacy constants removed in 2026.0 + if mkl.MKL_ENABLE_AVX != -1: + __variables["input"]["avx"] = mkl.MKL_ENABLE_AVX + if mkl.MKL_ENABLE_AVX512_MIC != -1: + __variables["input"]["avx512_mic"] = mkl.MKL_ENABLE_AVX512_MIC + if mkl.MKL_ENABLE_AVX512_MIC_E1 != -1: + __variables["input"]["avx512_mic_e1"] = mkl.MKL_ENABLE_AVX512_MIC_E1 cdef int c_mkl_isa = __mkl_str_to_int(isa, __variables["input"]) cdef int c_mkl_status = mkl.mkl_enable_instructions(c_mkl_isa) diff --git a/mkl/tests/test_mkl_service.py b/mkl/tests/test_mkl_service.py index 0080ae6..b84f0fc 100644 --- a/mkl/tests/test_mkl_service.py +++ b/mkl/tests/test_mkl_service.py @@ -213,6 +213,8 @@ def check_cbwr(branch, cnr_const): pytest.fail(status) +_mkl_major = mkl.get_version()["MajorVersion"] + branches = [ "off", "branch_off", @@ -223,15 +225,20 @@ def check_cbwr(branch, cnr_const): "avx2", "avx512", "avx512_e1", - "avx10", ] +# removed in MKL 2026.0 +legacy_cbwr_branches = ["ssse3", "sse4_1", "avx", "avx512_mic", "avx512_mic_e1"] +legacy_cbwr_strict = ["avx512_mic,strict", "avx512_mic_e1,strict"] + +# added in MKL 2026.0 +new_cbwr_branches = ["avx10"] +new_cbwr_strict = ["avx10,strict"] strict = [ "avx2,strict", "avx512,strict", "avx512_e1,strict", - "avx10,strict", ] @@ -249,26 +256,84 @@ def test_cbwr_get_auto_branch(): mkl.cbwr_get_auto_branch() +@pytest.mark.skipif( + _mkl_major >= 2026, + reason="Removed in MKL 2026.0", +) +@pytest.mark.parametrize("branch", legacy_cbwr_branches) +def test_cbwr_branch_legacy(branch): + check_cbwr(branch, "branch") + + +@pytest.mark.skipif( + _mkl_major >= 2026, + reason="Removed in MKL 2026.0", +) +@pytest.mark.parametrize("branch", legacy_cbwr_branches + legacy_cbwr_strict) +def test_cbwr_legacy(branch): + check_cbwr(branch, "all") + + +@pytest.mark.skipif( + _mkl_major < 2026, + reason="Added in MKL 2026.0", +) +@pytest.mark.parametrize("branch", new_cbwr_branches) +def test_cbwr_branch_new(branch): + check_cbwr(branch, "branch") + + +@pytest.mark.skipif( + _mkl_major < 2026, + reason="Added in MKL 2026.0", +) +@pytest.mark.parametrize("branch", new_cbwr_branches + new_cbwr_strict) +def test_cbwr_all_new(branch): + check_cbwr(branch, "all") + + instructions = [ "single_path", "avx512_e4", "avx512_e3", "avx512_e2", "avx512_e1", - "avx512_e5", "avx512", "avx2_e1", "avx2", "sse4_2", - "avx10", ] +# removed in MKL 2026.0 +legacy_instructions = ["avx", "avx512_mic", "avx512_mic_e1"] + +# added in MKL 2026.0 +new_instructions = ["avx512_e5", "avx10"] + @pytest.mark.parametrize("isa", instructions) def test_enable_instructions(isa): mkl.enable_instructions(isa) +@pytest.mark.skipif( + _mkl_major >= 2026, + reason="Removed in MKL 2026.0", +) +@pytest.mark.parametrize("isa", legacy_instructions) +def test_enable_instructions_legacy(isa): + mkl.enable_instructions(isa) + + +@pytest.mark.skipif( + _mkl_major < 2026, + reason="Added in MKL 2026.0", +) +@pytest.mark.parametrize("isa", new_instructions) +def test_enable_instructions_new(isa): + mkl.enable_instructions(isa) + + def test_set_env_mode(): mkl.set_env_mode()