From d517cf91e481dbf13366f01c19d930e9bb759f57 Mon Sep 17 00:00:00 2001 From: Nikita Grigorian Date: Thu, 7 May 2026 17:41:54 -0700 Subject: [PATCH 1/7] add a shim for new and old MKL constants allows mkl-service to work with both old and new versions --- conda-recipe/meta.yaml | 3 +- mkl/_mkl_service.pxd | 62 ++++++++++++++++++++++++-- mkl/_mkl_service.pyx | 83 +++++++++++++++++++++++++++++++---- mkl/tests/test_mkl_service.py | 73 ++++++++++++++++++++++++++++-- 4 files changed, 205 insertions(+), 16 deletions(-) diff --git a/conda-recipe/meta.yaml b/conda-recipe/meta.yaml index c6653f5..d0bc4ac 100644 --- a/conda-recipe/meta.yaml +++ b/conda-recipe/meta.yaml @@ -22,7 +22,8 @@ requirements: - python-gil # [py>=314] - pip >=25.0 - setuptools >=77 - - mkl-devel + - mkl-devel <2024 # [osx] + - mkl-devel # [not osx] - cython - wheel >=0.45.1 - python-build >=1.2.2 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() From 6739b1e68b3070d1f33e911b588a932b2de4ea49 Mon Sep 17 00:00:00 2001 From: Nikita Grigorian Date: Thu, 7 May 2026 18:15:50 -0700 Subject: [PATCH 2/7] add osx workflow --- .github/workflows/conda-package-cf-osx.yml | 167 +++++++++++++++++++++ conda-recipe/meta.yaml | 3 +- 2 files changed, 168 insertions(+), 2 deletions(-) create mode 100644 .github/workflows/conda-package-cf-osx.yml diff --git a/.github/workflows/conda-package-cf-osx.yml b/.github/workflows/conda-package-cf-osx.yml new file mode 100644 index 0000000..9ee65dc --- /dev/null +++ b/.github/workflows/conda-package-cf-osx.yml @@ -0,0 +1,167 @@ +name: Conda package for osx using conda-forge + +on: + push: + branches: + - master + pull_request: + +permissions: read-all + +env: + PACKAGE_NAME: mkl-service + MODULE_NAME: mkl + TEST_ENV_NAME: test_mkl_service + VER_SCRIPT1: "import json; f = open('ver.json', 'r'); j = json.load(f); f.close(); " + VER_SCRIPT2: "d = j['mkl-service'][0]; print('='.join((d[s] for s in ('version', 'build'))))" + +jobs: + build_osx: + runs-on: macos-latest + + 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-latest] + 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/conda-recipe/meta.yaml b/conda-recipe/meta.yaml index d0bc4ac..c6653f5 100644 --- a/conda-recipe/meta.yaml +++ b/conda-recipe/meta.yaml @@ -22,8 +22,7 @@ requirements: - python-gil # [py>=314] - pip >=25.0 - setuptools >=77 - - mkl-devel <2024 # [osx] - - mkl-devel # [not osx] + - mkl-devel - cython - wheel >=0.45.1 - python-build >=1.2.2 From dde27d41a03a2e9a5cb888fc83a5d7796c2ed7ce Mon Sep 17 00:00:00 2001 From: Nikita Grigorian Date: Thu, 7 May 2026 18:28:19 -0700 Subject: [PATCH 3/7] skip for osx and arm64 (aligns with conda-forge) --- conda-recipe-cf/meta.yaml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/conda-recipe-cf/meta.yaml b/conda-recipe-cf/meta.yaml index c6653f5..253d888 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 From 9a71403458df5b5933f785eff4011cbc37ca2d2d Mon Sep 17 00:00:00 2001 From: Nikita Grigorian Date: Thu, 7 May 2026 18:37:34 -0700 Subject: [PATCH 4/7] use macos-26-intel runners --- .github/workflows/conda-package-cf-osx.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/conda-package-cf-osx.yml b/.github/workflows/conda-package-cf-osx.yml index 9ee65dc..a9c235d 100644 --- a/.github/workflows/conda-package-cf-osx.yml +++ b/.github/workflows/conda-package-cf-osx.yml @@ -17,7 +17,7 @@ env: jobs: build_osx: - runs-on: macos-latest + runs-on: macos-26-intel strategy: matrix: @@ -97,7 +97,7 @@ jobs: matrix: python: ['3.10', '3.11', '3.12', '3.13', '3.14'] experimental: [false] - runner: [macos-latest] + runner: [macos-26-intel] continue-on-error: ${{ matrix.experimental }} env: CHANNELS: -c conda-forge -c conda-forge/label/python_rc --override-channels From 060ddd5e53204d764d795720e9da12197245c2b8 Mon Sep 17 00:00:00 2001 From: Nikita Grigorian Date: Thu, 7 May 2026 18:47:12 -0700 Subject: [PATCH 5/7] add osx to build config also remove unnecessary cxx compiler settings --- conda-recipe-cf/conda_build_config.yaml | 10 ++++------ conda-recipe/conda_build_config.yaml | 26 ++++++++++--------------- 2 files changed, 14 insertions(+), 22 deletions(-) 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/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] From 2a08c7b2972bc48a608ab4c69a106f4869f74c8a Mon Sep 17 00:00:00 2001 From: Nikita Grigorian Date: Thu, 7 May 2026 22:40:26 -0700 Subject: [PATCH 6/7] merge osx conda workflow with other platforms --- .github/workflows/conda-package-cf-osx.yml | 167 --------------------- .github/workflows/conda-package-cf.yml | 150 ++++++++++++++++++ 2 files changed, 150 insertions(+), 167 deletions(-) delete mode 100644 .github/workflows/conda-package-cf-osx.yml diff --git a/.github/workflows/conda-package-cf-osx.yml b/.github/workflows/conda-package-cf-osx.yml deleted file mode 100644 index a9c235d..0000000 --- a/.github/workflows/conda-package-cf-osx.yml +++ /dev/null @@ -1,167 +0,0 @@ -name: Conda package for osx using conda-forge - -on: - push: - branches: - - master - pull_request: - -permissions: read-all - -env: - PACKAGE_NAME: mkl-service - MODULE_NAME: mkl - TEST_ENV_NAME: test_mkl_service - VER_SCRIPT1: "import json; f = open('ver.json', 'r'); j = json.load(f); f.close(); " - VER_SCRIPT2: "d = j['mkl-service'][0]; print('='.join((d[s] for s in ('version', 'build'))))" - -jobs: - 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/.github/workflows/conda-package-cf.yml b/.github/workflows/conda-package-cf.yml index 3f7f8c9..6dc3ee0 100644 --- a/.github/workflows/conda-package-cf.yml +++ b/.github/workflows/conda-package-cf.yml @@ -301,3 +301,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 }} From cb841ccc184fc064b361f890c6389eebbf6c1384 Mon Sep 17 00:00:00 2001 From: Nikita Grigorian Date: Thu, 7 May 2026 22:43:49 -0700 Subject: [PATCH 7/7] show conda info on Windows --- .github/workflows/conda-package-cf.yml | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/.github/workflows/conda-package-cf.yml b/.github/workflows/conda-package-cf.yml index 6dc3ee0..096f9d0 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@668228422ae6a00e4ad889ee87cd7109ec5666a7 # v5.0.4 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