diff --git a/.github/workflows/build.yaml b/.github/workflows/build.yaml index 033865b9d..86d581d3e 100644 --- a/.github/workflows/build.yaml +++ b/.github/workflows/build.yaml @@ -65,3 +65,21 @@ jobs: branch: ${{ inputs.branch }} date: ${{ inputs.date }} sha: ${{ inputs.sha }} + wheel-build-pylibwholegraph: + secrets: inherit + uses: rapidsai/shared-action-workflows/.github/workflows/wheels-build.yaml@branch-23.08 + with: + build_type: ${{ inputs.build_type || 'branch' }} + branch: ${{ inputs.branch }} + sha: ${{ inputs.sha }} + date: ${{ inputs.date }} + wheel-publish-pylibwholegraph: + needs: wheel-build-pylibwholegraph + secrets: inherit + uses: rapidsai/shared-action-workflows/.github/workflows/wheels-publish.yaml@branch-23.08 + with: + build_type: ${{ inputs.build_type || 'branch' }} + branch: ${{ inputs.branch }} + sha: ${{ inputs.sha }} + date: ${{ inputs.date }} + package-name: pylibwholegraph diff --git a/.github/workflows/pr.yaml b/.github/workflows/pr.yaml index 146f5ac03..2109630b1 100644 --- a/.github/workflows/pr.yaml +++ b/.github/workflows/pr.yaml @@ -18,6 +18,8 @@ jobs: - conda-python-build - conda-python-tests - docs-build + - wheel-build-pylibwholegraph + - wheel-test-pylibwholegraph secrets: inherit uses: rapidsai/shared-action-workflows/.github/workflows/pr-builder.yaml@branch-23.08 checks: @@ -59,3 +61,18 @@ jobs: arch: "amd64" container_image: "rapidsai/ci:latest" run_script: "ci/build_docs.sh" + wheel-build-pylibwholegraph: + needs: checks + secrets: inherit + uses: rapidsai/shared-action-workflows/.github/workflows/wheels-build.yaml@branch-23.08 + with: + build_type: pull-request + script: ci/build_wheel.sh + wheel-test-pylibwholegraph: + needs: wheel-build-pylibwholegraph + secrets: inherit + uses: rapidsai/shared-action-workflows/.github/workflows/wheels-test.yaml@branch-23.08 + with: + build_type: pull-request + script: ci/test_wheel.sh + matrix_filter: map(select(.ARCH == "amd64")) diff --git a/.github/workflows/test.yaml b/.github/workflows/test.yaml index e7589d7b3..1abb5e881 100644 --- a/.github/workflows/test.yaml +++ b/.github/workflows/test.yaml @@ -30,3 +30,13 @@ jobs: branch: ${{ inputs.branch }} date: ${{ inputs.date }} sha: ${{ inputs.sha }} + wheel-tests-pylibwholegraph: + secrets: inherit + uses: rapidsai/shared-action-workflows/.github/workflows/wheels-test.yaml@branch-23.08 + with: + build_type: nightly + branch: ${{ inputs.branch }} + date: ${{ inputs.date }} + sha: ${{ inputs.sha }} + script: ci/test_wheel.sh + matrix_filter: map(select(.ARCH == "amd64")) diff --git a/ci/build_wheel.sh b/ci/build_wheel.sh new file mode 100755 index 000000000..5f6556734 --- /dev/null +++ b/ci/build_wheel.sh @@ -0,0 +1,26 @@ +#!/bin/bash +# Copyright (c) 2023, NVIDIA CORPORATION. + +source rapids-configure-sccache +source rapids-date-string + +# Use gha-tools rapids-pip-wheel-version to generate wheel version then +# update the necessary files +version_override="$(rapids-pip-wheel-version ${RAPIDS_DATE_STRING})" + +RAPIDS_PY_CUDA_SUFFIX="$(rapids-wheel-ctk-name-gen ${RAPIDS_CUDA_VERSION})" + +ci/release/apply_wheel_modifications.sh ${version_override} "-${RAPIDS_PY_CUDA_SUFFIX}" +echo "The package name and/or version was modified in the package source. The git diff is:" +git diff + +cd python/pylibwholegraph + +# Hardcode the output dir +SKBUILD_CONFIGURE_OPTIONS="-DDETECT_CONDA_ENV=OFF -DBUILD_SHARED_LIBS=OFF -DCMAKE_MESSAGE_LOG_LEVEL=VERBOSE -DCUDA_STATIC_RUNTIME=ON -DWHOLEGRAPH_BUILD_WHEELS=ON" \ + python -m pip wheel . -w dist -vvv --no-deps --disable-pip-version-check + +mkdir -p final_dist +python -m auditwheel repair --exclude libcuda.so.1 -w final_dist dist/* + +RAPIDS_PY_WHEEL_NAME="pylibwholegraph_${RAPIDS_PY_CUDA_SUFFIX}" rapids-upload-wheels-to-s3 final_dist diff --git a/ci/test_wheel.sh b/ci/test_wheel.sh new file mode 100755 index 000000000..010793c39 --- /dev/null +++ b/ci/test_wheel.sh @@ -0,0 +1,35 @@ +#!/bin/bash +# Copyright (c) 2022-2023, NVIDIA CORPORATION. + +set -e # abort the script on error +set -o pipefail # piped commands propagate their error +set -E # ERR traps are inherited by subcommands + +mkdir -p ./dist +RAPIDS_PY_CUDA_SUFFIX="$(rapids-wheel-ctk-name-gen ${RAPIDS_CUDA_VERSION})" +RAPIDS_PY_WHEEL_NAME="pylibwholegraph_${RAPIDS_PY_CUDA_SUFFIX}" rapids-download-wheels-from-s3 ./dist + +# echo to expand wildcard before adding `[extra]` requires for pip +python -m pip install $(echo ./dist/pylibwholegraph*.whl) + +PKG_CUDA_VER="$(echo ${CUDA_VERSION} | cut -d '.' -f1,2 | tr -d '.')" +PKG_CUDA_VER_MAJOR=${PKG_CUDA_VER:0:2} +if [[ "${PKG_CUDA_VER_MAJOR}" == "12" ]]; then + INDEX_URL="https://download.pytorch.org/whl/nightly/cu121" +else + INDEX_URL="https://download.pytorch.org/whl/cu${PKG_CUDA_VER}" +fi +RAPIDS_TESTS_DIR=${RAPIDS_TESTS_DIR:-"${PWD}/test-results"} +RAPIDS_COVERAGE_DIR=${RAPIDS_COVERAGE_DIR:-"${PWD}/coverage-results"} +mkdir -p "${RAPIDS_TESTS_DIR}" "${RAPIDS_COVERAGE_DIR}" + +rapids-logger "Installing PyTorch" +rapids-retry python -m pip install --pre torch --index-url ${INDEX_URL} +rapids-retry python -m pip install pytest pytest-forked numpy +rapids-logger "pytest pylibwholegraph" +PYLIBWHOLEGRAPH_INSTALL_PATH=`python -c 'import os; import pylibwholegraph; print(os.path.dirname(pylibwholegraph.__file__))'` +PYTEST_PATH=${PYLIBWHOLEGRAPH_INSTALL_PATH}/tests +python -m pytest \ + --cache-clear \ + --forked \ + ${PYTEST_PATH} diff --git a/conda/environments/all_cuda-115_arch-x86_64.yaml b/conda/environments/all_cuda-115_arch-x86_64.yaml new file mode 100644 index 000000000..bbadcc030 --- /dev/null +++ b/conda/environments/all_cuda-115_arch-x86_64.yaml @@ -0,0 +1,49 @@ +# This file is generated by `rapids-dependency-file-generator`. +# To make changes, edit ../../dependencies.yaml and run `rapids-dependency-file-generator`. +channels: +- rapidsai +- rapidsai-nightly +- pytorch +- conda-forge +- nvidia +dependencies: +- breathe +- c-compiler +- clang-tools=16.0.0 +- clangxx=16.0.0 +- cmake>=3.23.1,!=3.25.0 +- cuda-nvtx=11.5 +- cudatoolkit=11.5 +- cudnn=8.4 +- cxx-compiler +- cython +- doxygen=1.8.20 +- gcc_linux-64=11.* +- gitpython +- graphviz +- ipykernel +- ipython +- libraft-headers==23.08.* +- librmm==23.08.* +- nanobind>=0.2.0 +- nbsphinx +- nccl +- ninja +- numpy>=1.17 +- numpydoc +- nvcc_linux-64=11.5 +- pre-commit +- pydata-sphinx-theme +- pytest +- pytest-forked +- pytest-xdist +- python>=3.9,<3.11 +- pytorch=1.11.0=*cuda11.5* +- recommonmark +- scikit-build +- sphinx-copybutton +- sphinx-markdown-tables +- sphinx<6 +- sphinxcontrib-websupport +- sysroot_linux-64=2.17 +name: all_cuda-115_arch-x86_64 diff --git a/cpp/CMakeLists.txt b/cpp/CMakeLists.txt index b868ddb8e..a072f6d0b 100644 --- a/cpp/CMakeLists.txt +++ b/cpp/CMakeLists.txt @@ -51,11 +51,17 @@ rapids_cmake_write_version_file(include/wholegraph/version_config.hpp) ############################################################################## # - User Options ------------------------------------------------------------ +option(BUILD_SHARED_LIBS "Build libwholegraph shared libraries" ON) option(CMAKE_CUDA_LINEINFO "Enable the -lineinfo option for nvcc (useful for cuda-memcheck / profiler" OFF) option(BUILD_TESTS "Configure CMake to build tests" ON) +option(CUDA_STATIC_RUNTIME "Statically link the CUDA toolkit runtime and libraries" OFF) ############################################################################## # - Set options based on user defined one ----------------------------------- +set(_ctk_static_suffix "") +if(CUDA_STATIC_RUNTIME) + set(_ctk_static_suffix "_static") +endif() ############################################################################## # - Base rapids options ------------------------------------------------------ @@ -63,6 +69,9 @@ option(BUILD_TESTS "Configure CMake to build tests" ON) #rapids_cmake_build_type(Release) rapids_cmake_build_type(RelWithDebInfo) +# CUDA runtime +rapids_cuda_init_runtime(USE_STATIC ${CUDA_STATIC_RUNTIME}) + message("CMAKE_INSTALL_PREFIX=${CMAKE_INSTALL_PREFIX}") if(DETECT_CONDA_ENV) @@ -135,7 +144,7 @@ file(GLOB WHOLEGRAPH_SOURCES "src/graph_ops/*.cu" "src/graph_ops/*.cpp") -add_library(wholegraph SHARED "") +add_library(wholegraph) add_library(wholegraph::wholegraph ALIAS wholegraph) target_sources(wholegraph PRIVATE ${WHOLEGRAPH_SOURCES}) @@ -180,7 +189,7 @@ target_include_directories(wholegraph target_link_libraries(wholegraph PUBLIC CUDA::cuda_driver - CUDA::cudart + CUDA::cudart${_ctk_static_suffix} raft::raft PRIVATE NCCL::NCCL diff --git a/dependencies.yaml b/dependencies.yaml index 53fbe413f..280aae0ad 100644 --- a/dependencies.yaml +++ b/dependencies.yaml @@ -45,6 +45,13 @@ files: - run - pytorch_cpu - clang_tools + py_build_pylibwholegraph: + output: pyproject + pyproject_dir: python/pylibwholegraph + extras: + table: build-system + includes: + - python_build_wheel channels: - rapidsai - rapidsai-nightly @@ -270,3 +277,13 @@ dependencies: - clangxx=16.0.0 - clang-tools=16.0.0 - gitpython + python_build_wheel: + common: + - output_types: [pyproject] + packages: + - cmake>=3.26.4 + - cython>=0.29,<0.30 + - ninja + - setuptools + - scikit-build>=0.13.1 + - wheel diff --git a/python/pylibwholegraph/CMakeLists.txt b/python/pylibwholegraph/CMakeLists.txt index 68035dd79..e7193ef2c 100644 --- a/python/pylibwholegraph/CMakeLists.txt +++ b/python/pylibwholegraph/CMakeLists.txt @@ -42,6 +42,7 @@ project(PYLIBWHOLEGRAPH VERSION ${WHOLEGRAPH_VERSION} LANGUAGES C CXX CUDA) # - User Options ------------------------------------------------------------ option(DETECT_CONDA_ENV "Enable detection of conda environment for dependencies" ON) +option(WHOLEGRAPH_BUILD_WHEELS "Whether we're building a wheel for pypi" OFF) ############################################################################## # - Base Rapids Options ----------------------------------------------------- @@ -117,6 +118,10 @@ find_package(wholegraph "${RAPIDS_VERSION}.0" EXACT) message("WholeGraph") if (WHOLEGRAPH_FOUND) message(STATUS "PYLIBWHOLEGRAPH: using pre-built wholegraph C++ package") +elseif(WHOLEGRAPH_BUILD_WHEELS) + # statically link dependencies if building wheels + message(STATUS "PYLIBWHOLEGRAPH: build wheels") + add_subdirectory(../../cpp/ libwholegraph EXCLUDE_FROM_ALL) else() message(FATAL_ERROR "PYLIBWHOLEGRAPH: could not find wholegraph package in " "cmake prefix ${CMAKE_PREFIX_PATH} or user dir $ENV{LIBWHOLEGRAPH_DIR}") diff --git a/python/pylibwholegraph/pyproject.toml b/python/pylibwholegraph/pyproject.toml index e69de29bb..a49c5b789 100644 --- a/python/pylibwholegraph/pyproject.toml +++ b/python/pylibwholegraph/pyproject.toml @@ -0,0 +1,43 @@ +# Copyright (c) 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. + +[build-system] +requires = [ + "cmake>=3.26.4", + "cython>=0.29,<0.30", + "ninja", + "scikit-build>=0.13.1", + "setuptools", + "wheel", +] # This list was generated by `rapids-dependency-file-generator`. To make changes, edit ../../dependencies.yaml and run `rapids-dependency-file-generator`. + +[project] +name = "pylibwholegraph" +version = "23.08.00" +description = "pylibwholegraph - GPU Graph Storage for GNN feature and graph structure" +authors = [ + { name = "NVIDIA Corporation" }, +] +license = { text = "Apache 2.0" } +requires-python = ">=3.6" +classifiers = [ + "Intended Audience :: Developers", + "Programming Language :: Python", + "Programming Language :: Python :: 3.6", + "Programming Language :: Python :: 3.7", + "Programming Language :: Python :: 3.8", + "Programming Language :: Python :: 3.9", + "Programming Language :: Python :: 3.10", + "Programming Language :: Python :: 3.11", +]