Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[CI] Build Python wheels for MacOS (x86_64 and arm64) #7621

Merged
merged 7 commits into from
Feb 3, 2022
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 0 additions & 3 deletions .github/workflows/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -21,10 +21,7 @@ jobs:
submodules: 'true'
- name: Install system packages
run: |
# Use libomp 11.1.0: https://github.com/dmlc/xgboost/issues/7039
wget https://raw.githubusercontent.com/Homebrew/homebrew-core/679923b4eb48a8dc7ecc1f05d06063cd79b3fc00/Formula/libomp.rb -O $(find $(brew --repository) -name libomp.rb)
brew install ninja libomp
brew pin libomp
- name: Build gtest binary
run: |
mkdir build
Expand Down
34 changes: 6 additions & 28 deletions .github/workflows/python_tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,7 @@ jobs:
- name: Install osx system dependencies
if: matrix.os == 'macos-10.15'
run: |
# Use libomp 11.1.0: https://github.com/dmlc/xgboost/issues/7039
wget https://raw.githubusercontent.com/Homebrew/homebrew-core/679923b4eb48a8dc7ecc1f05d06063cd79b3fc00/Formula/libomp.rb -O $(find $(brew --repository) -name libomp.rb)
brew install ninja libomp
brew pin libomp
- name: Install Ubuntu system dependencies
if: matrix.os == 'ubuntu-latest'
run: |
Expand Down Expand Up @@ -119,14 +116,16 @@ jobs:
conda list

- name: Build XGBoost on macos
shell: bash -l {0}
run: |
wget https://raw.githubusercontent.com/Homebrew/homebrew-core/679923b4eb48a8dc7ecc1f05d06063cd79b3fc00/Formula/libomp.rb -O $(find $(brew --repository) -name libomp.rb)
brew install ninja libomp
brew pin libomp
brew install ninja

mkdir build
cd build
cmake .. -GNinja -DGOOGLE_TEST=ON -DUSE_DMLC_GTEST=ON
# Set prefix, to use OpenMP library from Conda env
# See https://github.com/dmlc/xgboost/issues/7039#issuecomment-1025038228
# to learn why we don't use libomp from Homebrew.
cmake .. -GNinja -DGOOGLE_TEST=ON -DUSE_DMLC_GTEST=ON -DCMAKE_PREFIX_PATH=$CONDA_PREFIX
ninja

- name: Install Python package
Expand All @@ -141,24 +140,3 @@ jobs:
shell: bash -l {0}
run: |
pytest -s -v ./tests/python

- name: Rename Python wheel
shell: bash -l {0}
run: |
TAG=macosx_10_15_x86_64.macosx_11_0_x86_64.macosx_12_0_x86_64
python tests/ci_build/rename_whl.py python-package/dist/*.whl ${{ github.sha }} ${TAG}

- name: Extract branch name
shell: bash
run: echo "##[set-output name=branch;]$(echo ${GITHUB_REF#refs/heads/})"
id: extract_branch
if: github.ref == 'refs/heads/master' || contains(github.ref, 'refs/heads/release_')

- name: Upload Python wheel
shell: bash -l {0}
if: github.ref == 'refs/heads/master' || contains(github.ref, 'refs/heads/release_')
run: |
python -m awscli s3 cp python-package/dist/*.whl s3://xgboost-nightly-builds/${{ steps.extract_branch.outputs.branch }}/ --acl public-read
env:
AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID_IAM_S3_UPLOADER }}
AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY_IAM_S3_UPLOADER }}
57 changes: 57 additions & 0 deletions .github/workflows/python_wheels.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
name: XGBoost-Python-Wheels

on: [push, pull_request]

jobs:
python-wheels:
name: Build wheel for ${{ matrix.platform_id }}
runs-on: ${{ matrix.os }}
strategy:
matrix:
include:
- os: macos-latest
python: 37
platform_id: macosx_x86_64
wheel_tag: macosx_10_15_x86_64.macosx_11_0_x86_64.macosx_12_0_x86_64
- os: macos-latest
python: 38
platform_id: macosx_arm64
wheel_tag: macosx_12_0_arm64
steps:
- uses: actions/checkout@v2
with:
submodules: 'true'
- name: Setup Python
uses: actions/setup-python@v2
with:
python-version: '3.9'
- name: Set env var for ARM64
shell: bash
run: echo "::set-output name=value::CIBW_TARGET_OSX_ARM64=1"
id: arm64_flag
if: matrix.platform_id == 'macosx_arm64'
- name: Build wheels
env:
CIBW_BUILD: cp${{ matrix.python }}-${{ matrix.platform_id }}
CIBW_ARCHS: all
CIBW_ENVIRONMENT: ${{ steps.arm64_flag.outputs.value }}
CIBW_TEST_SKIP: "*-macosx_arm64"
CIBW_BUILD_VERBOSITY: 3
run: bash tests/ci_build/build_python_wheels.sh

- name: Rename Python wheel
run: |
python tests/ci_build/rename_whl.py wheelhouse/*.whl ${{ github.sha }} ${{ matrix.wheel_tag }}
- name: Extract branch name
shell: bash
run: echo "##[set-output name=branch;]$(echo ${GITHUB_REF#refs/heads/})"
id: extract_branch
if: github.ref == 'refs/heads/master' || contains(github.ref, 'refs/heads/release_')
- name: Upload Python wheel
if: github.ref == 'refs/heads/master' || contains(github.ref, 'refs/heads/release_')
run: |
python -m pip install awscli
python -m awscli s3 cp wheelhouse/*.whl s3://xgboost-nightly-builds/${{ steps.extract_branch.outputs.branch }}/ --acl public-read
env:
AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID_IAM_S3_UPLOADER }}
AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY_IAM_S3_UPLOADER }}
3 changes: 3 additions & 0 deletions python-package/setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,9 @@ def build(
continue
cmake_cmd.append('-D' + arg + '=' + value)

if 'CIBW_TARGET_OSX_ARM64' in os.environ:
hcho3 marked this conversation as resolved.
Show resolved Hide resolved
cmake_cmd.append("-DCMAKE_OSX_ARCHITECTURES=arm64")

self.logger.info('Run CMake command: %s', str(cmake_cmd))
subprocess.check_call(cmake_cmd, cwd=build_dir)

Expand Down
34 changes: 34 additions & 0 deletions tests/ci_build/build_python_wheels.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
#!/bin/bash

set -e
set -x

# OpenMP is not present on macOS by default
if [[ "$RUNNER_OS" == "macOS" ]]; then
# Make sure to use a libomp version binary compatible with the oldest
# supported version of the macos SDK as libomp will be vendored into the
# XGBoost wheels for macos.

if [[ "$CIBW_BUILD" == *-macosx_arm64 ]]; then
# arm64 builds must cross compile because CI is on x64
export PYTHON_CROSSENV=1
export MACOSX_DEPLOYMENT_TARGET=12.0
OPENMP_URL="https://anaconda.org/conda-forge/llvm-openmp/11.1.0/download/osx-arm64/llvm-openmp-11.1.0-hf3c4609_1.tar.bz2"
else
export MACOSX_DEPLOYMENT_TARGET=10.13
OPENMP_URL="https://anaconda.org/conda-forge/llvm-openmp/11.1.0/download/osx-64/llvm-openmp-11.1.0-hda6cdc1_1.tar.bz2"
fi

sudo conda create -n build $OPENMP_URL
PREFIX="/usr/local/miniconda/envs/build"

export CC=/usr/bin/clang
export CXX=/usr/bin/clang++
export CPPFLAGS="$CPPFLAGS -Xpreprocessor -fopenmp"
export CFLAGS="$CFLAGS -I$PREFIX/include"
export CXXFLAGS="$CXXFLAGS -I$PREFIX/include"
export LDFLAGS="$LDFLAGS -Wl,-rpath,$PREFIX/lib -L$PREFIX/lib -lomp"
fi

python -m pip install cibuildwheel
python -m cibuildwheel python-package --output-dir wheelhouse
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This command calls python.py bdist_wheel to generate the wheel.

1 change: 1 addition & 0 deletions tests/ci_build/conda_env/macos_cpu_test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ dependencies:
- pylint
- numpy
- scipy
- llvm-openmp
- scikit-learn
- pandas
- matplotlib
Expand Down