diff --git a/.github/workflows/variant-wheels.yml b/.github/workflows/variant-wheels.yml new file mode 100644 index 000000000000..2f91cc354373 --- /dev/null +++ b/.github/workflows/variant-wheels.yml @@ -0,0 +1,55 @@ +# Workflow to build and test wheels. +# To work on the wheel building infrastructure on a fork, comment out: +# +# if: github.repository == 'numpy/numpy' +# +# in the get_commit_message job. Be sure to include [wheel build] in your commit +# message to trigger the build. All files related to wheel building are located +# at tools/wheels/ +# Alternatively, you can add labels to the pull request in order to trigger wheel +# builds. +# The labels that trigger builds are: +# 36 - Build(for changes to the building process, +# 14 - Release(ensure wheels build before release) +name: Wheel builder + +on: + push: + +permissions: + contents: read # to fetch code (actions/checkout) + +jobs: + build_wheels: + name: Build wheel ${{ matrix.python }}-${{ matrix.blas }}-x86_64-${{ matrix.x86_64 }} + runs-on: ${{ matrix.buildplat[0] }} + strategy: + # Ensure that a wheel builder finishes even if another fails + fail-fast: false + matrix: + blas: [openblas, mkl] + # Github Actions doesn't support pairing matrix values together, let's improvise + # https://github.com/github/feedback/discussions/7835#discussioncomment-1769026 + buildplat: + - [ubuntu-22.04, manylinux_x86_64, ""] + python: ["3.12"] + x86_64: [v1, v2, v3, v4] + + steps: + - name: Checkout numpy + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 + with: + submodules: true + persist-credentials: false + + - uses: prefix-dev/setup-pixi@v0.8.3 + + - name: Build wheels + run: pixi run -e ${{ matrix.blas }} build -Csetup-args=-Duse-ilp64=true -Cvariant=blas::variant::${{ matrix.blas }} -Cvariant=x86_64::level::${{ matrix.x86_64 }} -Ccompile-args=-v + + - uses: actions/upload-artifact@v4 + with: + name: wheel-${{ matrix.blas }}-x86-64-${{ matrix.x86_64 }} + path: dist/*.whl + if-no-files-found: error + compression-level: 0 diff --git a/meson.build b/meson.build index 141e662f40b0..80f90376e8a0 100644 --- a/meson.build +++ b/meson.build @@ -88,5 +88,25 @@ if host_machine.system() == 'darwin' and cc.has_link_argument('-Wl,-ld_classic') add_project_link_arguments('-Wl,-ld_classic', language : ['c', 'cpp']) endif +blas_variant = '' +x86_64_variant = '' + +foreach variant_meta : get_option('variant') + split_meta = variant_meta.split('::') + if split_meta.length() != 3 + error('Invalid variant key: ' + variant_meta) + endif + if split_meta[0].strip() == 'blas' and split_meta[1].strip() == 'variant' + blas_variant = split_meta[2].strip() + elif split_meta[0].strip() == 'x86_64' and split_meta[1].strip() == 'level' + if host_machine.cpu_family() != 'x86_64' + error('Variant valid only on x86_64: ' + variant_meta) + endif + x86_64_variant = split_meta[2].strip() + else + error('Unsupported variant key: ' + variant_meta) + endif +endforeach + subdir('meson_cpu') subdir('numpy') diff --git a/meson.options b/meson.options index 1be05d324756..e2d19a595df2 100644 --- a/meson.options +++ b/meson.options @@ -40,3 +40,5 @@ option('test-simd', type: 'array', description: 'Specify a list of CPU features to be tested against NumPy SIMD interface') option('test-simd-args', type: 'string', value: '', description: 'Extra args to be passed to the `_simd` module that is used for testing the NumPy SIMD interface') +option('variant', type: 'array', value: [], + description: 'Wheel variant keys') diff --git a/meson_cpu/x86/meson.build b/meson_cpu/x86/meson.build index 8c7a0fb59a57..10f9e5d16397 100644 --- a/meson_cpu/x86/meson.build +++ b/meson_cpu/x86/meson.build @@ -1,6 +1,23 @@ source_root = meson.project_source_root() mod_features = import('features') +if x86_64_variant != '' + if x86_64_variant == 'v1' + CPU_CONF_BASELINE = 'min' + CPU_CONF_DISPATCH = '' + elif x86_64_variant == 'v2' + CPU_CONF_BASELINE = 'SSE42' + CPU_CONF_DISPATCH = '' + elif x86_64_variant == 'v3' + CPU_CONF_BASELINE = 'AVX2' + CPU_CONF_DISPATCH = '' + elif x86_64_variant == 'v4' + CPU_CONF_BASELINE = 'AVX512_SKX' + else + error('Unknown x86_64 variant: ' + x86_64_variant) + endif +endif + SSE = mod_features.new( 'SSE', 1, args: '-msse', test_code: files(source_root + '/numpy/distutils/checks/cpu_sse.c')[0] diff --git a/numpy/meson.build b/numpy/meson.build index 7fcafa9c8184..3a5bf6e5bdbb 100644 --- a/numpy/meson.build +++ b/numpy/meson.build @@ -60,6 +60,13 @@ allow_noblas = get_option('allow-noblas') # (see cibuildwheel settings in pyproject.toml), but used by CI jobs already blas_symbol_suffix = get_option('blas-symbol-suffix') +# Variant overrides options directly specified +if blas_variant != '' + blas_name = blas_variant + lapack_name = blas_variant + allow_noblas = false +endif + use_ilp64 = get_option('use-ilp64') if use_ilp64 blas_interface = ['interface: ilp64'] @@ -67,7 +74,6 @@ else blas_interface = ['interface: lp64'] endif - blas_order = get_option('blas-order') if blas_order == ['auto'] blas_order = [] diff --git a/pixi.toml b/pixi.toml new file mode 100644 index 000000000000..9121ed504422 --- /dev/null +++ b/pixi.toml @@ -0,0 +1,28 @@ +[workspace] +channels = ["conda-forge"] +name = "numpy-wheel-build" +platforms = ["linux-64"] + +[tasks] +build = "python -m build -w" + +[dependencies] +c-compiler = "*" +cxx-compiler = "*" +fortran-compiler = "*" +pkg-config = "*" +pip = "*" +python = "*" + +[pypi-dependencies] +build = { git = "https://github.com/mgorny/build", branch = "variant-deps" } + +[feature.mkl.dependencies] +mkl-devel = "*" + +[feature.openblas.dependencies] +openblas = "*" + +[environments] +mkl = ["mkl"] +openblas = ["openblas"] diff --git a/pyproject.toml b/pyproject.toml index eb7015acc347..5ad6e202666d 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,8 +1,9 @@ [build-system] build-backend = "mesonpy" requires = [ - "meson-python>=0.15.0", + "meson-python @ https://github.com/mgorny/meson-python/archive/wheel-variants.tar.gz", "Cython>=3.0.6", # keep in sync with version check in meson.build + "variant_x86_64 @ https://github.com/wheelnext/variant_x86_64/archive/main.tar.gz ; 'x86_64' in variants" ] [project]