diff --git a/build.sh b/build.sh index 429f949647..378248e649 100755 --- a/build.sh +++ b/build.sh @@ -280,13 +280,15 @@ fi # Build and (optionally) install the cuml Python package if (! hasArg --configure-only) && (completeBuild || hasArg cuml || hasArg pydocs); then + # Replace spaces with semicolons in SKBUILD_EXTRA_CMAKE_ARGS + SKBUILD_EXTRA_CMAKE_ARGS=$(echo ${SKBUILD_EXTRA_CMAKE_ARGS} | sed 's/ /;/g') + # Append `-DFIND_CUML_CPP=ON` to CUML_EXTRA_CMAKE_ARGS unless a user specified the option. - SKBUILD_EXTRA_CMAKE_ARGS="${CUML_EXTRA_CMAKE_ARGS}" - if [[ "${CUML_EXTRA_CMAKE_ARGS}" != *"DFIND_CUML_CPP"* ]]; then - SKBUILD_EXTRA_CMAKE_ARGS="${SKBUILD_EXTRA_CMAKE_ARGS} -DFIND_CUML_CPP=ON" + if [[ "${SKBUILD_EXTRA_CMAKE_ARGS}" != *"DFIND_CUML_CPP"* ]]; then + SKBUILD_EXTRA_CMAKE_ARGS="${SKBUILD_EXTRA_CMAKE_ARGS};-DFIND_CUML_CPP=ON" fi - SKBUILD_CONFIGURE_OPTIONS="-DCMAKE_MESSAGE_LOG_LEVEL=${CMAKE_LOG_LEVEL} ${SKBUILD_EXTRA_CMAKE_ARGS}" \ + SKBUILD_CMAKE_ARGS="-DCMAKE_MESSAGE_LOG_LEVEL=${CMAKE_LOG_LEVEL};${SKBUILD_EXTRA_CMAKE_ARGS}" \ SKBUILD_BUILD_OPTIONS="-j${PARALLEL_LEVEL}" \ python -m pip install --no-build-isolation --no-deps ${REPODIR}/python @@ -297,7 +299,6 @@ if (! hasArg --configure-only) && (completeBuild || hasArg cuml || hasArg pydocs fi if hasArg cuml-cpu; then - SKBUILD_CONFIGURE_OPTIONS="-DCUML_CPU=ON -DCMAKE_MESSAGE_LOG_LEVEL=VERBOSE" \ - SKBUILD_BUILD_OPTIONS="-j${PARALLEL_LEVEL}" \ + SKBUILD_CMAKE_ARGS="-DCUML_CPU=ON;-DCMAKE_MESSAGE_LOG_LEVEL=VERBOSE" \ python -m pip install --no-build-isolation --no-deps -v ${REPODIR}/python fi diff --git a/ci/build_wheel.sh b/ci/build_wheel.sh index 8b15323b33..d74acc744a 100755 --- a/ci/build_wheel.sh +++ b/ci/build_wheel.sh @@ -49,7 +49,7 @@ fi cd ${package_dir} -SKBUILD_CONFIGURE_OPTIONS="-DDETECT_CONDA_ENV=OFF -DDISABLE_DEPRECATION_WARNINGS=ON -DCPM_cumlprims_mg_SOURCE=${GITHUB_WORKSPACE}/cumlprims_mg/" \ +SKBUILD_CMAKE_ARGS="-DDETECT_CONDA_ENV=OFF;-DDISABLE_DEPRECATION_WARNINGS=ON;-DCPM_cumlprims_mg_SOURCE=${GITHUB_WORKSPACE}/cumlprims_mg/" \ python -m pip wheel . \ -w dist \ -vvv \ diff --git a/conda/environments/all_cuda-118_arch-x86_64.yaml b/conda/environments/all_cuda-118_arch-x86_64.yaml index 0211c1d7f7..0af9ec2184 100644 --- a/conda/environments/all_cuda-118_arch-x86_64.yaml +++ b/conda/environments/all_cuda-118_arch-x86_64.yaml @@ -63,7 +63,7 @@ dependencies: - rapids-dask-dependency==24.2.* - recommonmark - rmm==24.2.* -- scikit-build>=0.13.1 +- scikit-build-core>=0.7.0 - scikit-learn==1.2 - scipy>=1.8.0 - seaborn diff --git a/conda/environments/all_cuda-120_arch-x86_64.yaml b/conda/environments/all_cuda-120_arch-x86_64.yaml index e2768aa83f..cb2c047dc3 100644 --- a/conda/environments/all_cuda-120_arch-x86_64.yaml +++ b/conda/environments/all_cuda-120_arch-x86_64.yaml @@ -59,7 +59,7 @@ dependencies: - rapids-dask-dependency==24.2.* - recommonmark - rmm==24.2.* -- scikit-build>=0.13.1 +- scikit-build-core>=0.7.0 - scikit-learn==1.2 - scipy>=1.8.0 - seaborn diff --git a/conda/recipes/cuml-cpu/meta.yaml b/conda/recipes/cuml-cpu/meta.yaml index cb88ac22b7..efe9d6449d 100644 --- a/conda/recipes/cuml-cpu/meta.yaml +++ b/conda/recipes/cuml-cpu/meta.yaml @@ -29,7 +29,7 @@ requirements: host: - python x.x - setuptools - - scikit-build>=0.13.1 + - scikit-build-core >=0.7.0 - cython>=3.0.0 run: - python x.x diff --git a/conda/recipes/cuml/meta.yaml b/conda/recipes/cuml/meta.yaml index bcafb63bb6..e134dd1363 100644 --- a/conda/recipes/cuml/meta.yaml +++ b/conda/recipes/cuml/meta.yaml @@ -65,7 +65,7 @@ requirements: - pylibraft ={{ minor_version }} - python x.x - raft-dask ={{ minor_version }} - - scikit-build >=0.13.1 + - scikit-build-core >=0.7.0 - setuptools - treelite {{ treelite_version }} run: diff --git a/dependencies.yaml b/dependencies.yaml index dc579d48fa..c53387c04c 100644 --- a/dependencies.yaml +++ b/dependencies.yaml @@ -151,13 +151,13 @@ dependencies: common: - output_types: [conda, requirements, pyproject] packages: - - scikit-build>=0.13.1 - cython>=3.0.0 - &treelite treelite==3.9.1 - output_types: conda packages: - &pylibraft_conda pylibraft==24.2.* - &rmm_conda rmm==24.2.* + - scikit-build-core>=0.7.0 - output_types: requirements packages: # pip recognizes the index as a global option for the requirements.txt file @@ -166,8 +166,7 @@ dependencies: - --extra-index-url=https://pypi.anaconda.org/rapidsai-wheels-nightly/simple - output_types: [pyproject, requirements] packages: - - wheel - - setuptools + - scikit-build-core[pyproject]>=0.7.0 - &treelite_runtime treelite_runtime==3.9.1 specific: - output_types: [conda, requirements, pyproject] diff --git a/python/CMakeLists.txt b/python/CMakeLists.txt index 6bfa48ab11..d71e83a9e1 100644 --- a/python/CMakeLists.txt +++ b/python/CMakeLists.txt @@ -19,7 +19,7 @@ include(../fetch_rapids.cmake) set(CUML_VERSION 24.02.00) option(CUML_CPU "Build only cuML CPU Python components." OFF) -set(language_list "C;CXX") +set(language_list "CXX") if(NOT CUML_CPU) # We always need CUDA for cuML GPU because the raft dependency brings in a @@ -32,11 +32,7 @@ endif() project( cuml-python VERSION ${CUML_VERSION} - LANGUAGES # TODO: Building Python extension modules via the python_extension_module requires the C - # language to be enabled here. The test project that is built in scikit-build to verify - # various linking options for the python library is hardcoded to build with C, so until - # that is fixed we need to keep C. - ${language_list} + LANGUAGES ${language_list} ) ################################################################################ @@ -75,7 +71,7 @@ else() set(cuml_FOUND OFF) endif() -include(rapids-cython) +include(rapids-cython-core) set(CUML_PYTHON_TREELITE_TARGET treelite::treelite) diff --git a/python/pyproject.toml b/python/pyproject.toml index dd2a930e65..c7b5c03160 100644 --- a/python/pyproject.toml +++ b/python/pyproject.toml @@ -20,13 +20,11 @@ requires = [ "ninja", "pylibraft==24.2.*", "rmm==24.2.*", - "scikit-build>=0.13.1", - "setuptools", + "scikit-build-core[pyproject]>=0.7.0", "treelite==3.9.1", "treelite_runtime==3.9.1", - "wheel", ] # This list was generated by `rapids-dependency-file-generator`. To make changes, edit ../dependencies.yaml and run `rapids-dependency-file-generator`. -build-backend = "setuptools.build_meta" +build-backend = "scikit_build_core.build" [tool.pytest.ini_options] markers = [ @@ -102,12 +100,6 @@ test = [ Homepage = "https://github.com/rapidsai/cuml" Documentation = "https://docs.rapids.ai/api/cuml/stable/" -[tool.setuptools] -license-files = ["LICENSE"] - -[tool.setuptools.dynamic] -version = {file = "cuml/VERSION"} - [tool.black] line-length = 79 target-version = ["py39"] @@ -131,3 +123,16 @@ versioneer\.py | thirdparty )/ ''' + +[tool.scikit-build] +build-dir = "build/{wheel_tag}" +cmake.build-type = "Release" +cmake.minimum-version = "3.26.4" +ninja.make-fallback = true +sdist.reproducible = true +wheel.packages = ["cuml"] + +[tool.scikit-build.metadata.version] +provider = "scikit_build_core.metadata.regex" +input = "cuml/VERSION" +regex = "(?P.*)" diff --git a/python/setup.py b/python/setup.py deleted file mode 100644 index 5a30d78201..0000000000 --- a/python/setup.py +++ /dev/null @@ -1,114 +0,0 @@ -# -# Copyright (c) 2018-2023, NVIDIA CORPORATION. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -import glob -import os -import shutil -import sys -from pathlib import Path - -from setuptools import find_packages - -from skbuild import setup - - -############################################################################## -# - Helper functions -def get_cli_option(name): - if name in sys.argv: - print("-- Detected " + str(name) + " build option.") - return True - - else: - return False - - -def clean_folder(path): - """ - Function to clean all Cython and Python artifacts and cache folders. It - cleans the folder as well as its direct children recursively. - - Parameters - ---------- - path : String - Path to the folder to be cleaned. - """ - shutil.rmtree(path + "/__pycache__", ignore_errors=True) - - folders = glob.glob(path + "/*/") - for folder in folders: - shutil.rmtree(folder + "/__pycache__", ignore_errors=True) - - clean_folder(folder) - - cython_exts = glob.glob(folder + "/*.cpp") - cython_exts.extend(glob.glob(folder + "/*.cpython*")) - for file in cython_exts: - os.remove(file) - - -############################################################################## -# - Print of build options used by setup.py -------------------------------- - -clean_artifacts = get_cli_option("clean") - - -############################################################################## -# - Clean target ------------------------------------------------------------- - -if clean_artifacts: - print("-- Cleaning all Python and Cython build artifacts...") - - # Reset these paths since they may be deleted below - treelite_path = False - - try: - setup_file_path = str(Path(__file__).parent.absolute()) - shutil.rmtree(setup_file_path + "/.pytest_cache", ignore_errors=True) - shutil.rmtree( - setup_file_path + "/_external_repositories", ignore_errors=True - ) - shutil.rmtree(setup_file_path + "/cuml.egg-info", ignore_errors=True) - shutil.rmtree(setup_file_path + "/__pycache__", ignore_errors=True) - - clean_folder(setup_file_path + "/cuml") - shutil.rmtree(setup_file_path + "/build", ignore_errors=True) - shutil.rmtree(setup_file_path + "/_skbuild", ignore_errors=True) - shutil.rmtree(setup_file_path + "/dist", ignore_errors=True) - - except IOError: - pass - - # need to terminate script so cythonizing doesn't get triggered after - # cleanup unintendedly - sys.argv.remove("clean") - - if "--all" in sys.argv: - sys.argv.remove("--all") - - if len(sys.argv) == 1: - sys.exit(0) - - -############################################################################## -# - Python package generation ------------------------------------------------ - -packages = find_packages(include=["cuml*"]) -setup( - packages=packages, - package_data={key: ["VERSION", "*.pxd"] for key in packages}, - zip_safe=False, -)