diff --git a/.cirrus.star b/.cirrus.star new file mode 100644 index 0000000000000..0c1d2089944ce --- /dev/null +++ b/.cirrus.star @@ -0,0 +1,31 @@ +# This script uses starlark for configuring when a cirrus CI job runs: +# https://cirrus-ci.org/guide/programming-tasks/ + +load("cirrus", "env", "fs", "http") + +def main(ctx): + # Only run for scikit-learn/scikit-learn. For debugging on a fork, you can + # comment out the following condition. + # if env.get("CIRRUS_REPO_FULL_NAME") != "scikit-learn/scikit-learn": + # return [] + + arm_wheel_yaml = "build_tools/cirrus/arm_wheel.yml" + + # Nightly jobs always run + if env.get("CIRRUS_CRON", "") == "nightly": + return fs.read(arm_wheel_yaml) + + # Get commit message for event. We can not use `git` here because there is + # no command line access in starlark. Thus we need to query the GitHub API + # for the commit message. Note that `CIRRUS_CHANGE_MESSAGE` can not be used + # because it is set to the PR's title and not the latest commit message. + SHA = env.get("CIRRUS_CHANGE_IN_REPO") + REPO = env.get("CIRRUS_REPO_FULL_NAME") + url = "https://api.github.com/repos/" + REPO + "/git/commits/" + SHA + response = http.get(url).json() + commit_msg = response["message"] + + if "[skip ci]" in commit_msg or ("[cd build]" not in commit_msg and "[cd build cirrus]" not in commit_msg): + return [] + + return fs.read(arm_wheel_yaml) diff --git a/.github/workflows/wheels.yml b/.github/workflows/wheels.yml index 49da927d67178..59bd514b75fd4 100644 --- a/.github/workflows/wheels.yml +++ b/.github/workflows/wheels.yml @@ -145,6 +145,7 @@ jobs: CIBW_TEST_COMMAND: bash {project}/build_tools/github/test_wheels.sh CIBW_TEST_COMMAND_WINDOWS: bash {project}/build_tools/github/test_windows_wheels.sh ${{ matrix.python }} CIBW_BUILD_VERBOSITY: 1 + CONDA_HOME: /usr/local/miniconda run: bash build_tools/github/build_wheels.sh diff --git a/build_tools/cirrus/arm_wheel.yml b/build_tools/cirrus/arm_wheel.yml new file mode 100644 index 0000000000000..cc560aba719f2 --- /dev/null +++ b/build_tools/cirrus/arm_wheel.yml @@ -0,0 +1,38 @@ +macos_arm64_wheel_task: + macos_instance: + image: ghcr.io/cirruslabs/macos-monterey-xcode + env: + CONFTEST_PATH: ${CIRRUS_WORKING_DIR}/conftest.py + CONFTEST_NAME: conftest.py + CIBW_ENVIRONMENT: OMP_NUM_THREADS=2 + OPENBLAS_NUM_THREADS=2 + SKLEARN_SKIP_NETWORK_TESTS=1 + SKLEARN_BUILD_PARALLEL=5 + CPU_COUNT=2 + CIBW_TEST_COMMAND: bash {project}/build_tools/github/test_wheels.sh + CIBW_TEST_REQUIRES: pytest pandas threadpoolctl pytest-xdist + CIBW_BUILD_VERBOSITY: 1 + PATH: $HOME/mambaforge/bin/:$PATH + CONDA_HOME: $HOME/mambaforge + matrix: + - env: + # cibuildwheel can not test on Python 3.8 even on a Apple Silicon machine. + # For details see: https://github.com/pypa/cibuildwheel/pull/1169 + CIBW_BUILD: cp38-macosx_arm64 + CIBW_TEST_SKIP: "*" + - env: + CIBW_BUILD: cp39-macosx_arm64 + - env: + CIBW_BUILD: cp310-macosx_arm64 + - env: + CIBW_BUILD: cp311-macosx_arm64 + + conda_script: + - curl -L -o ~/mambaforge.sh https://github.com/conda-forge/miniforge/releases/latest/download/Miniforge3-MacOSX-arm64.sh + - bash ~/mambaforge.sh -b -p ~/mambaforge + + cibuildwheel_script: + - bash build_tools/github/build_wheels.sh + + wheels_artifacts: + path: "wheelhouse/*" diff --git a/build_tools/github/build_wheels.sh b/build_tools/github/build_wheels.sh index 647b47492774b..faa278714b2fd 100755 --- a/build_tools/github/build_wheels.sh +++ b/build_tools/github/build_wheels.sh @@ -4,14 +4,18 @@ set -e set -x # OpenMP is not present on macOS by default -if [[ "$RUNNER_OS" == "macOS" ]]; then +if [[ $(uname) == "Darwin" ]]; 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 # scikit-learn wheels for macos. if [[ "$CIBW_BUILD" == *-macosx_arm64 ]]; then - # arm64 builds must cross compile because CI is on x64 - export PYTHON_CROSSENV=1 + if [[ $(uname -m) == "x86_64" ]]; then + # arm64 builds must cross compile because the CI instance is x86 + # This turns off the computation of the test program in + # sklearn/_build_utils/pre_build_helpers.py + export PYTHON_CROSSENV=1 + fi # SciPy requires 12.0 on arm to prevent kernel panics # https://github.com/scipy/scipy/issues/14688 # We use the same deployment target to match SciPy. @@ -23,7 +27,7 @@ if [[ "$RUNNER_OS" == "macOS" ]]; then fi sudo conda create -n build $OPENMP_URL - PREFIX="/usr/local/miniconda/envs/build" + PREFIX="$CONDA_HOME/envs/build" export CC=/usr/bin/clang export CXX=/usr/bin/clang++ diff --git a/build_tools/github/test_wheels.sh b/build_tools/github/test_wheels.sh index 1a984bc91dba8..216ffaab85859 100755 --- a/build_tools/github/test_wheels.sh +++ b/build_tools/github/test_wheels.sh @@ -3,7 +3,9 @@ set -e set -x -if [[ "$OSTYPE" != "linux-gnu" ]]; then +UNAME=$(uname) + +if [[ "$UNAME" != "Linux" ]]; then # The Linux test environment is run in a Docker container and # it is not possible to copy the test configuration file (yet) cp $CONFTEST_PATH $CONFTEST_NAME @@ -12,4 +14,9 @@ fi # Test that there are no links to system libraries in the # threadpoolctl output section of the show_versions output: python -c "import sklearn; sklearn.show_versions()" -pytest --pyargs sklearn + +if [ ! -z "$CPU_COUNT" ]; then + pytest --pyargs sklearn -n $CPU_COUNT +else + pytest --pyargs sklearn +fi diff --git a/doc/developers/contributing.rst b/doc/developers/contributing.rst index efaa06965500f..3a45cbdae195d 100644 --- a/doc/developers/contributing.rst +++ b/doc/developers/contributing.rst @@ -546,6 +546,7 @@ message, the following actions are taken. [ci skip] CI is skipped completely [cd build] CD is run (wheels and source distribution are built) [cd build gh] CD is run only for GitHub Actions + [cd build cirrus] CD is run only for Cirrus CI [lint skip] Azure pipeline skips linting [scipy-dev] Build & test with our dependencies (numpy, scipy, etc ...) development builds [nogil] Build & test with the nogil experimental branches of CPython, Cython, NumPy, SciPy...