Skip to content

Commit

Permalink
Add wheel builds (#12096)
Browse files Browse the repository at this point in the history
This PR enables building wheels. It mostly leverages various build options that have already been added to the repository.

Authors:
  - Vyas Ramasubramani (https://github.com/vyasr)
  - Sevag H (https://github.com/sevagh)
  - Paul Taylor (https://github.com/trxcllnt)

Approvers:
  - Bradley Dice (https://github.com/bdice)
  - GALI PREM SAGAR (https://github.com/galipremsagar)
  - Sevag H (https://github.com/sevagh)

URL: #12096
  • Loading branch information
vyasr authored Nov 18, 2022
1 parent 3fb09d1 commit 6d2a4f0
Show file tree
Hide file tree
Showing 12 changed files with 364 additions and 162 deletions.
77 changes: 77 additions & 0 deletions .github/workflows/wheels.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
name: cuDF wheels

on:
workflow_call:
inputs:
versioneer-override:
type: string
default: ''
build-tag:
type: string
default: ''
branch:
required: true
type: string
date:
required: true
type: string
sha:
required: true
type: string
build-type:
type: string
default: nightly

concurrency:
group: "cudf-${{ github.workflow }}-${{ github.ref }}"
cancel-in-progress: true

jobs:
cudf-wheels:
uses: rapidsai/shared-action-workflows/.github/workflows/wheels-manylinux.yml@main
with:
repo: rapidsai/cudf

build-type: ${{ inputs.build-type }}
branch: ${{ inputs.branch }}
sha: ${{ inputs.sha }}
date: ${{ inputs.date }}

package-dir: python/cudf
package-name: cudf

python-package-versioneer-override: ${{ inputs.versioneer-override }}
python-package-build-tag: ${{ inputs.build-tag }}

skbuild-configure-options: "-DCUDF_BUILD_WHEELS=ON -DDETECT_CONDA_ENV=OFF"

test-extras: test

# Have to manually specify the cupy install location on arm.
# Have to also manually install tokenizers==0.10.2, which is the last tokenizers
# to have a binary aarch64 wheel available on PyPI
# Otherwise, the tokenizers sdist is used, which needs a Rust compiler
test-before-arm64: "pip install tokenizers==0.10.2 cupy-cuda11x -f https://pip.cupy.dev/aarch64"

test-unittest: "pytest -v -n 8 ./python/cudf/cudf/tests"
secrets: inherit
dask_cudf-wheel:
needs: cudf-wheels
uses: rapidsai/shared-action-workflows/.github/workflows/wheels-pure.yml@main
with:
repo: rapidsai/cudf

build-type: ${{ inputs.build-type }}
branch: ${{ inputs.branch }}
sha: ${{ inputs.sha }}
date: ${{ inputs.date }}

package-dir: python/dask_cudf
package-name: dask_cudf

python-package-versioneer-override: ${{ inputs.versioneer-override }}
python-package-build-tag: ${{ inputs.build-tag }}

test-extras: test
test-unittest: "pytest -v -n 8 ./python/dask_cudf/dask_cudf/tests"
secrets: inherit
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -167,3 +167,6 @@ docs/cudf/source/api_docs/generated/*
docs/cudf/source/api_docs/api/*
docs/cudf/source/user_guide/example_output/*
docs/cudf/source/user_guide/cudf.*Dtype.*.rst

# cibuildwheel
/wheelhouse
150 changes: 84 additions & 66 deletions cpp/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,8 @@ option(BUILD_TESTS "Configure CMake to build tests" ON)
option(BUILD_BENCHMARKS "Configure CMake to build (google & nvbench) benchmarks" OFF)
option(BUILD_SHARED_LIBS "Build cuDF shared libraries" ON)
option(JITIFY_USE_CACHE "Use a file cache for JIT compiled kernels" ON)
option(CUDF_BUILD_TESTUTIL "Whether to build the test utilities contained in libcudf" ON)
mark_as_advanced(CUDF_BUILD_TESTUTIL)
option(CUDF_USE_PROPRIETARY_NVCOMP "Download and use NVCOMP with proprietary extensions" ON)
option(CUDF_USE_ARROW_STATIC "Build and statically link Arrow libraries" OFF)
option(CUDF_ENABLE_ARROW_ORC "Build the Arrow ORC adapter" OFF)
Expand Down Expand Up @@ -94,6 +96,12 @@ message(VERBOSE "CUDF: Statically link the CUDA runtime: ${CUDA_STATIC_RUNTIME}"
rapids_cmake_build_type("Release")
set(CUDF_BUILD_TESTS ${BUILD_TESTS})
set(CUDF_BUILD_BENCHMARKS ${BUILD_BENCHMARKS})
if(BUILD_TESTS AND NOT CUDF_BUILD_TESTUTIL)
message(
FATAL_ERROR
"Tests cannot be built without building cudf test utils. Please set CUDF_BUILD_TESTUTIL=ON or BUILD_TESTS=OFF"
)
endif()

set(CUDF_CXX_FLAGS "")
set(CUDF_CUDA_FLAGS "")
Expand Down Expand Up @@ -133,12 +141,14 @@ include(cmake/Modules/ConfigureCUDA.cmake) # set other CUDA compilation flags
# find zlib
rapids_find_package(ZLIB REQUIRED)

# find Threads (needed by cudftestutil)
rapids_find_package(
Threads REQUIRED
BUILD_EXPORT_SET cudf-exports
INSTALL_EXPORT_SET cudf-exports
)
if(CUDF_BUILD_TESTUTIL)
# find Threads (needed by cudftestutil)
rapids_find_package(
Threads REQUIRED
BUILD_EXPORT_SET cudf-exports
INSTALL_EXPORT_SET cudf-exports
)
endif()

# add third party dependencies using CPM
rapids_cpm_init()
Expand All @@ -160,7 +170,9 @@ rapids_cpm_libcudacxx(BUILD_EXPORT_SET cudf-exports INSTALL_EXPORT_SET cudf-expo
# find cuCollections Should come after including thrust and libcudacxx
include(cmake/thirdparty/get_cucollections.cmake)
# find or install GoogleTest
include(cmake/thirdparty/get_gtest.cmake)
if(CUDF_BUILD_TESTUTIL)
include(cmake/thirdparty/get_gtest.cmake)
endif()
# preprocess jitify-able kernels
include(cmake/Modules/JitifyPreprocessKernels.cmake)
# find cuFile
Expand Down Expand Up @@ -694,46 +706,48 @@ add_library(cudf::cudf ALIAS cudf)
# ##################################################################################################
# * build cudftestutil ----------------------------------------------------------------------------

add_library(
cudftestutil STATIC
tests/io/metadata_utilities.cpp
tests/utilities/base_fixture.cpp
tests/utilities/column_utilities.cu
tests/utilities/table_utilities.cu
tests/utilities/tdigest_utilities.cu
)
if(CUDF_BUILD_TESTUTIL)
add_library(
cudftestutil STATIC
tests/io/metadata_utilities.cpp
tests/utilities/base_fixture.cpp
tests/utilities/column_utilities.cu
tests/utilities/table_utilities.cu
tests/utilities/tdigest_utilities.cu
)

set_target_properties(
cudftestutil
PROPERTIES BUILD_RPATH "\$ORIGIN"
INSTALL_RPATH "\$ORIGIN"
# set target compile options
CXX_STANDARD 17
CXX_STANDARD_REQUIRED ON
CUDA_STANDARD 17
CUDA_STANDARD_REQUIRED ON
POSITION_INDEPENDENT_CODE ON
INTERFACE_POSITION_INDEPENDENT_CODE ON
)
set_target_properties(
cudftestutil
PROPERTIES BUILD_RPATH "\$ORIGIN"
INSTALL_RPATH "\$ORIGIN"
# set target compile options
CXX_STANDARD 17
CXX_STANDARD_REQUIRED ON
CUDA_STANDARD 17
CUDA_STANDARD_REQUIRED ON
POSITION_INDEPENDENT_CODE ON
INTERFACE_POSITION_INDEPENDENT_CODE ON
)

target_compile_options(
cudftestutil PUBLIC "$<BUILD_INTERFACE:$<$<COMPILE_LANGUAGE:CXX>:${CUDF_CXX_FLAGS}>>"
"$<BUILD_INTERFACE:$<$<COMPILE_LANGUAGE:CUDA>:${CUDF_CUDA_FLAGS}>>"
)
target_compile_options(
cudftestutil PUBLIC "$<BUILD_INTERFACE:$<$<COMPILE_LANGUAGE:CXX>:${CUDF_CXX_FLAGS}>>"
"$<BUILD_INTERFACE:$<$<COMPILE_LANGUAGE:CUDA>:${CUDF_CUDA_FLAGS}>>"
)

target_link_libraries(
cudftestutil
PUBLIC GTest::gmock GTest::gtest Threads::Threads cudf
PRIVATE $<TARGET_NAME_IF_EXISTS:conda_env>
)
target_link_libraries(
cudftestutil
PUBLIC GTest::gmock GTest::gtest Threads::Threads cudf
PRIVATE $<TARGET_NAME_IF_EXISTS:conda_env>
)

target_include_directories(
cudftestutil PUBLIC "$<BUILD_INTERFACE:${CUDF_SOURCE_DIR}>"
"$<BUILD_INTERFACE:${CUDF_SOURCE_DIR}/src>"
)
target_include_directories(
cudftestutil PUBLIC "$<BUILD_INTERFACE:${CUDF_SOURCE_DIR}>"
"$<BUILD_INTERFACE:${CUDF_SOURCE_DIR}/src>"
)

add_library(cudf::cudftestutil ALIAS cudftestutil)
add_library(cudf::cudftestutil ALIAS cudftestutil)

endif()
# ##################################################################################################
# * add tests -------------------------------------------------------------------------------------

Expand Down Expand Up @@ -788,24 +802,26 @@ install(DIRECTORY ${CUDF_SOURCE_DIR}/include/cudf ${CUDF_SOURCE_DIR}/include/cud
${CUDF_SOURCE_DIR}/include/nvtext DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}
)

install(
TARGETS cudftestutil
DESTINATION ${lib_dir}
EXPORT cudf-testing-exports
)
if(CUDF_BUILD_TESTUTIL)
install(
TARGETS cudftestutil
DESTINATION ${lib_dir}
EXPORT cudf-testing-exports
)

install(
EXPORT cudf-testing-exports
FILE cudf-testing-targets.cmake
NAMESPACE cudf::
DESTINATION "${lib_dir}/cmake/cudf"
)
install(
EXPORT cudf-testing-exports
FILE cudf-testing-targets.cmake
NAMESPACE cudf::
DESTINATION "${lib_dir}/cmake/cudf"
)

include("${rapids-cmake-dir}/export/write_dependencies.cmake")
rapids_export_write_dependencies(
INSTALL cudf-testing-exports
"${PROJECT_BINARY_DIR}/rapids-cmake/cudf/export/cudf-testing-dependencies.cmake"
)
include("${rapids-cmake-dir}/export/write_dependencies.cmake")
rapids_export_write_dependencies(
INSTALL cudf-testing-exports
"${PROJECT_BINARY_DIR}/rapids-cmake/cudf/export/cudf-testing-dependencies.cmake"
)
endif()

set(doc_string
[=[
Expand Down Expand Up @@ -895,6 +911,7 @@ if(EXISTS "${CMAKE_CURRENT_LIST_DIR}/cudf-testing-targets.cmake")
endif()
]=]
)

string(APPEND build_code_string "${common_code_string}")

rapids_export(
Expand All @@ -906,15 +923,16 @@ rapids_export(
FINAL_CODE_BLOCK build_code_string
)

export(
EXPORT cudf-testing-exports
FILE ${CUDF_BINARY_DIR}/cudf-testing-targets.cmake
NAMESPACE cudf::
)
rapids_export_write_dependencies(
BUILD cudf-testing-exports "${CUDF_BINARY_DIR}/cudf-testing-dependencies.cmake"
)

if(CUDF_BUILD_TESTUTIL)
export(
EXPORT cudf-testing-exports
FILE ${CUDF_BINARY_DIR}/cudf-testing-targets.cmake
NAMESPACE cudf::
)
rapids_export_write_dependencies(
BUILD cudf-testing-exports "${CUDF_BINARY_DIR}/cudf-testing-dependencies.cmake"
)
endif()
# ##################################################################################################
# * make documentation ----------------------------------------------------------------------------

Expand Down
32 changes: 31 additions & 1 deletion python/cudf/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -31,9 +31,15 @@ project(
option(FIND_CUDF_CPP "Search for existing CUDF C++ installations before defaulting to local files"
OFF
)
option(CUDF_BUILD_WHEELS "Whether this build is generating a Python wheel." OFF)
option(USE_LIBARROW_FROM_PYARROW "Use the libarrow contained within pyarrow." OFF)
mark_as_advanced(USE_LIBARROW_FROM_PYARROW)

# Always build wheels against the pyarrow libarrow.
if(CUDF_BUILD_WHEELS)
set(USE_LIBARROW_FROM_PYARROW ON)
endif()

# If the user requested it we attempt to find CUDF.
if(FIND_CUDF_CPP)
if(USE_LIBARROW_FROM_PYARROW)
Expand Down Expand Up @@ -75,8 +81,32 @@ if(NOT cudf_FOUND)

set(BUILD_TESTS OFF)
set(BUILD_BENCHMARKS OFF)
add_subdirectory(../../cpp cudf-cpp)

set(_exclude_from_all "")
if(CUDF_BUILD_WHEELS)
# We don't build C++ tests when building wheels, so we can also omit the test util and shrink
# the wheel by avoiding embedding GTest.
set(CUDF_BUILD_TESTUTIL OFF)

# Statically link cudart if building wheels
set(CUDA_STATIC_RUNTIME ON)

# Need to set this so all the nvcomp targets are global, not only nvcomp::nvcomp
# https://cmake.org/cmake/help/latest/variable/CMAKE_FIND_PACKAGE_TARGETS_GLOBAL.html#variable:CMAKE_FIND_PACKAGE_TARGETS_GLOBAL
set(CMAKE_FIND_PACKAGE_TARGETS_GLOBAL ON)

# Don't install the cuDF C++ targets into wheels
set(_exclude_from_all EXCLUDE_FROM_ALL)
endif()

add_subdirectory(../../cpp cudf-cpp ${_exclude_from_all})

if(CUDF_BUILD_WHEELS)
include(cmake/Modules/WheelHelpers.cmake)
get_target_property(_nvcomp_link_libs nvcomp::nvcomp INTERFACE_LINK_LIBRARIES)
# Ensure all the shared objects we need at runtime are in the wheel
add_target_libs_to_wheel(LIB_DIR cudf TARGETS arrow_shared nvcomp::nvcomp ${_nvcomp_link_libs})
endif()
# Since there are multiple subpackages of cudf._lib that require access to libcudf, we place the
# library in the cudf directory as a single source of truth and modify the other rpaths
# appropriately.
Expand Down
1 change: 1 addition & 0 deletions python/cudf/LICENSE
37 changes: 37 additions & 0 deletions python/cudf/_custom_build/backend.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
# Copyright (c) 2022, NVIDIA CORPORATION.

"""Custom build backend for cudf to get versioned requirements.
Based on https://setuptools.pypa.io/en/latest/build_meta.html
"""
import os
from functools import wraps

from setuptools import build_meta as _orig

# Alias the required bits
build_wheel = _orig.build_wheel
build_sdist = _orig.build_sdist


def replace_requirements(func):
@wraps(func)
def wrapper(config_settings=None):
orig_list = getattr(_orig, func.__name__)(config_settings)
append_list = [
f"rmm{os.getenv('RAPIDS_PY_WHEEL_CUDA_SUFFIX', default='')}"
]
return orig_list + append_list

return wrapper


get_requires_for_build_wheel = replace_requirements(
_orig.get_requires_for_build_wheel
)
get_requires_for_build_sdist = replace_requirements(
_orig.get_requires_for_build_sdist
)
get_requires_for_build_editable = replace_requirements(
_orig.get_requires_for_build_editable
)
Loading

0 comments on commit 6d2a4f0

Please sign in to comment.