diff --git a/.github/workflows/pr.yaml b/.github/workflows/pr.yaml index d4ba8954..8628d460 100644 --- a/.github/workflows/pr.yaml +++ b/.github/workflows/pr.yaml @@ -14,6 +14,12 @@ jobs: needs: - changed-files - checks + - conda-cpp-build + - conda-cpp-tests + - conda-python-build + - conda-python-tests + - wheel-build-pylibwholegraph + - wheel-tests-pylibwholegraph secrets: inherit uses: rapidsai/shared-workflows/.github/workflows/pr-builder.yaml@branch-24.12 if: always() @@ -54,3 +60,47 @@ jobs: uses: rapidsai/shared-workflows/.github/workflows/checks.yaml@branch-24.12 with: enable_check_generated_files: false + conda-cpp-build: + needs: checks + secrets: inherit + uses: rapidsai/shared-workflows/.github/workflows/conda-cpp-build.yaml@branch-24.12 + with: + build_type: pull-request + node_type: cpu32 + conda-cpp-tests: + needs: [conda-cpp-build, changed-files] + secrets: inherit + uses: rapidsai/shared-workflows/.github/workflows/conda-cpp-tests.yaml@branch-24.12 + if: fromJSON(needs.changed-files.outputs.changed_file_groups).test_cpp + with: + build_type: pull-request + conda-python-build: + needs: conda-cpp-build + secrets: inherit + uses: rapidsai/shared-workflows/.github/workflows/conda-python-build.yaml@branch-24.12 + with: + build_type: pull-request + conda-python-tests: + needs: [conda-python-build, changed-files] + secrets: inherit + uses: rapidsai/shared-workflows/.github/workflows/conda-python-tests.yaml@branch-24.12 + if: fromJSON(needs.changed-files.outputs.changed_file_groups).test_python + with: + build_type: pull-request + wheel-build-pylibwholegraph: + needs: checks + secrets: inherit + uses: rapidsai/shared-workflows/.github/workflows/wheels-build.yaml@branch-24.12 + with: + build_type: pull-request + script: ci/build_wheel_pylibwholegraph.sh + node_type: cpu32 + wheel-tests-pylibwholegraph: + needs: [wheel-build-pylibwholegraph, changed-files] + secrets: inherit + uses: rapidsai/shared-workflows/.github/workflows/wheels-test.yaml@branch-24.12 + if: fromJSON(needs.changed-files.outputs.changed_file_groups).test_python + with: + build_type: pull-request + script: ci/test_wheel_pylibwholegraph.sh + matrix_filter: map(select(.ARCH == "amd64")) diff --git a/build.sh b/build.sh index 44c4740e..16c68f56 100755 --- a/build.sh +++ b/build.sh @@ -26,6 +26,9 @@ VALIDARGS=" uninstall cugraph-pyg cugraph-dgl + pylibwholegraph + libwholegraph + tests docs all -v @@ -44,6 +47,9 @@ HELP="$0 [ ...] [ ...] uninstall - uninstall libcugraph and cugraph from a prior build/install (see also -n) cugraph-pyg - build the cugraph-pyg Python package cugraph-dgl - build the cugraph-dgl extensions for DGL + pylibwholegraph - build the pylibwholegraph Python package + libwholegraph - build the libwholegraph library + tests - build the C++ tests docs - build the docs all - build everything and is: @@ -55,15 +61,19 @@ HELP="$0 [ ...] [ ...] --clean - clean an individual target (note: to do a complete rebuild, use the clean target described above) -h - print this text - default action (no args) is to build and install 'cugraph-pyg' then 'cugraph-dgl' then 'wholegraph' targets + default action (no args) is to build and install 'libwholegraph' then 'pylibwholegraph' then 'cugraph-pyg' then 'cugraph-dgl' " CUGRAPH_PYG_BUILD_DIR=${REPODIR}/python/cugraph-pyg/build CUGRAPH_DGL_BUILD_DIR=${REPODIR}/python/cugraph-dgl/build +PYLIBWHOLEGRAPH_BUILD_DIR=${REPODIR}/python/pylibwholegraph/build +LIBWHOLEGRAPH_BUILD_DIR=${REPODIR}/cpp/build BUILD_DIRS="${CUGRAPH_PYG_BUILD_DIR} ${CUGRAPH_DGL_BUILD_DIR} + ${PYLIBWHOLEGRAPH_BUILD_DIR} + ${LIBWHOLEGRAPH_BUILD_DIR} " # Set defaults for vars modified by flags to this script @@ -71,7 +81,7 @@ VERBOSE_FLAG="" BUILD_TYPE=Release INSTALL_TARGET="--target install" BUILD_ALL_GPU_ARCH=0 -PYTHON_ARGS_FOR_INSTALL="-m pip install --no-build-isolation --no-deps" +PYTHON_ARGS_FOR_INSTALL="-m pip install --no-build-isolation --no-deps --config-settings rapidsai.disable-cuda=true" # Set defaults for vars that may not have been defined externally # FIXME: if PREFIX is not set, check CONDA_PREFIX, but there is no fallback @@ -132,13 +142,30 @@ if hasArg --pydevelop; then PYTHON_ARGS_FOR_INSTALL="${PYTHON_ARGS_FOR_INSTALL} -e" fi +if hasArg tests; then + BUILD_TESTS=ON +else + BUILD_TESTS=OFF +fi + # If clean or uninstall targets given, run them prior to any other steps if hasArg uninstall; then - # uninstall cugraph and pylibcugraph installed from a prior install + if [[ "$INSTALL_PREFIX" != "" ]]; then + rm -rf ${INSTALL_PREFIX}/include/wholememory + rm -f ${INSTALL_PREFIX}/lib/libwholegraph.so + rm -rf ${INSTALL_PREFIX}/lib/cmake/wholegraph + fi + # This may be redundant given the above, but can also be used in case + # there are other installed files outside of the locations above. + if [ -e ${LIBWHOLEGRAPH_BUILD_DIR}/install_manifest.txt ]; then + xargs rm -f < ${LIBWHOLEGRAPH_BUILD_DIR}/install_manifest.txt > /dev/null 2>&1 + fi + + # uninstall cugraph-dgl/cugraph-pyg/wholegraph installed from a prior install # FIXME: if multiple versions of these packages are installed, this only # removes the latest one and leaves the others installed. build.sh uninstall # can be run multiple times to remove all of them, but that is not obvious. - pip uninstall -y cugraph-dgl cugraph-pyg + pip uninstall -y cugraph-dgl cugraph-pyg pylibwholegraph libwholegraph fi if hasArg clean; then @@ -164,6 +191,58 @@ if hasArg clean; then fi ################################################################################ +# Build and install the libwholegraph library +if hasArg libwholegraph || buildDefault || hasArg all ; then + + # set values based on flags + if (( ${BUILD_ALL_GPU_ARCH} == 0 )); then + WHOLEGRAPH_CMAKE_CUDA_ARCHITECTURES="${WHOLEGRAPH_CMAKE_CUDA_ARCHITECTURES:=NATIVE}" + echo "Building for the architecture of the GPU in the system..." + else + WHOLEGRAPH_CMAKE_CUDA_ARCHITECTURES="70-real;75-real;80-real;86-real;90" + echo "Building for *ALL* supported GPU architectures..." + fi + + cmake -S ${REPODIR}/cpp -B ${LIBWHOLEGRAPH_BUILD_DIR} \ + -DCMAKE_INSTALL_PREFIX=${INSTALL_PREFIX} \ + -DCMAKE_CUDA_ARCHITECTURES=${WHOLEGRAPH_CMAKE_CUDA_ARCHITECTURES} \ + -DCMAKE_BUILD_TYPE=${BUILD_TYPE} \ + -DCMAKE_PREFIX_PATH=${INSTALL_PREFIX} \ + -DCMAKE_MESSAGE_LOG_LEVEL=VERBOSE \ + -DBUILD_TESTS=${BUILD_TESTS} \ + -DBUILD_WITH_NVSHMEM=${BUILD_WITH_NVSHMEM} + + cd ${LIBWHOLEGRAPH_BUILD_DIR} + + if ! hasArg --compile-cmd; then + ## Build and (optionally) install library + tests + cmake --build . -j${PARALLEL_LEVEL} ${INSTALL_TARGET} ${VERBOSE_FLAG} + fi +fi + +# Build and install the pylibwholegraph Python package +if hasArg pylibwholegraph || buildDefault || hasArg all; then + if hasArg --clean; then + cleanPythonDir ${REPODIR}/python/pylibwholegraph + fi + + # setup.py and cmake reference an env var LIBWHOLEGRAPH_DIR to find the + # libwholegraph package (cmake). + # If not set by the user, set it to LIBWHOLEGRAPH_BUILD_DIR + LIBWHOLEGRAPH_DIR=${LIBWHOLEGRAPH_DIR:=${LIBWHOLEGRAPH_BUILD_DIR}} + if ! hasArg --compile-cmd; then + cd ${REPODIR}/python/pylibwholegraph + env LIBWHOLEGRAPH_DIR=${LIBWHOLEGRAPH_DIR} \ + SKBUILD_CMAKE_ARGS="-DCMAKE_BUILD_TYPE=${BUILD_TYPE}" python ${PYTHON_ARGS_FOR_INSTALL} \ + . + else + # just invoke cmake without going through scikit-build-core + env LIBWHOLEGRAPH_DIR=${LIBWHOLEGRAPH_DIR} \ + cmake -S ${REPODIR}/python/pylibwholegraph -B ${REPODIR}/python/pylibwholegraph/build \ + -DCMAKE_BUILD_TYPE=${BUILD_TYPE} + fi +fi + # Build and install the cugraph-pyg Python package if hasArg cugraph-pyg || buildDefault || hasArg all; then if hasArg --clean; then diff --git a/ci/build_cpp.sh b/ci/build_cpp.sh new file mode 100755 index 00000000..5049639a --- /dev/null +++ b/ci/build_cpp.sh @@ -0,0 +1,22 @@ +#!/bin/bash +# Copyright (c) 2022-2024, NVIDIA CORPORATION. + +set -euo pipefail + +rapids-configure-conda-channels + +source rapids-configure-sccache + +source rapids-date-string + +export CMAKE_GENERATOR=Ninja + +rapids-print-env + +version=$(rapids-generate-version) + +rapids-logger "Begin cpp build" + +RAPIDS_PACKAGE_VERSION=${version} rapids-conda-retry mambabuild conda/recipes/libwholegraph + +rapids-upload-conda-to-s3 cpp diff --git a/ci/build_python.sh b/ci/build_python.sh index 9a024365..49d3c126 100755 --- a/ci/build_python.sh +++ b/ci/build_python.sh @@ -15,41 +15,14 @@ rapids-print-env CPP_CHANNEL=$(rapids-download-conda-from-s3 cpp) -version=$(rapids-generate-version) -git_commit=$(git rev-parse HEAD) -export RAPIDS_PACKAGE_VERSION=${version} -echo "${version}" > VERSION - -rapids-logger "Begin py build" - -package_dir="python" -for package_name in cugraph-pyg cugraph-dgl; do - underscore_package_name=$(echo "${package_name}" | tr "-" "_") - sed -i "/^__git_commit__/ s/= .*/= \"${git_commit}\"/g" "${package_dir}/${package_name}/${underscore_package_name}/_version.py" -done - -RAPIDS_CUDA_MAJOR="${RAPIDS_CUDA_VERSION%%.*}" - -if [[ ${RAPIDS_CUDA_MAJOR} == "11" ]]; then - # Only CUDA 11 is supported right now due to PyTorch requirement. - rapids-conda-retry mambabuild \ - --no-test \ - --channel "${CPP_CHANNEL}" \ - --channel "${RAPIDS_CONDA_BLD_OUTPUT_DIR}" \ - --channel pyg \ - --channel pytorch \ - --channel pytorch-nightly \ - conda/recipes/cugraph-pyg - - # Only CUDA 11 is supported right now due to PyTorch requirement. - rapids-conda-retry mambabuild \ - --no-test \ - --channel "${CPP_CHANNEL}" \ - --channel "${RAPIDS_CONDA_BLD_OUTPUT_DIR}" \ - --channel dglteam \ - --channel pytorch \ - --channel pytorch-nightly \ - conda/recipes/cugraph-dgl -fi +rapids-generate-version > ./VERSION + +# TODO: Remove `--no-test` flags once importing on a CPU +# node works correctly +rapids-logger "Begin pylibwholegraph build" +RAPIDS_PACKAGE_VERSION=$(head -1 ./VERSION) rapids-conda-retry mambabuild \ + --no-test \ + --channel "${CPP_CHANNEL}" \ + conda/recipes/pylibwholegraph rapids-upload-conda-to-s3 python diff --git a/ci/build_wheel.sh b/ci/build_wheel.sh index a1438300..fc98035a 100755 --- a/ci/build_wheel.sh +++ b/ci/build_wheel.sh @@ -7,62 +7,52 @@ package_name=$1 package_dir=$2 underscore_package_name=$(echo "${package_name}" | tr "-" "_") +# The set of shared libraries that should be packaged differs by project. +# +# Capturing that here in argument-parsing to allow this build_wheel.sh +# script to be re-used by all wheel builds in the project. +case "${package_dir}" in + python/pylibwholegraph) + EXCLUDE_ARGS=( + --exclude libcuda.so.1 + --exclude libnvidia-ml.so.1 + ) + ;; + *) + EXCLUDE_ARGS=() + ;; +esac + source rapids-configure-sccache source rapids-date-string -version=$(rapids-generate-version) -git_commit=$(git rev-parse HEAD) +rapids-generate-version > ./VERSION RAPIDS_PY_CUDA_SUFFIX="$(rapids-wheel-ctk-name-gen ${RAPIDS_CUDA_VERSION})" -# This is the version of the suffix with a preceding hyphen. It's used -# everywhere except in the final wheel name. -PACKAGE_CUDA_SUFFIX="-${RAPIDS_PY_CUDA_SUFFIX}" - -# Patch project metadata files to include the CUDA version suffix and version override. -version_package_name="$underscore_package_name" - -pyproject_file="${package_dir}/pyproject.toml" -version_file="${package_dir}/${version_package_name}/_version.py" - -sed -i "s/name = \"${package_name}\"/name = \"${package_name}${PACKAGE_CUDA_SUFFIX}\"/g" ${pyproject_file} -echo "${version}" > VERSION -sed -i "/^__git_commit__ / s/= .*/= \"${git_commit}\"/g" ${version_file} - -# For nightlies we want to ensure that we're pulling in alphas as well. The -# easiest way to do so is to augment the spec with a constraint containing a -# min alpha version that doesn't affect the version bounds but does allow usage -# of alpha versions for that dependency without --pre -alpha_spec='' -if ! rapids-is-release-build; then - alpha_spec=',>=0.0.0a0' -fi - -for dep in rmm cudf cugraph raft-dask pylibcugraph pylibcugraphops pylibwholegraph pylibraft ucx-py; do - sed -r -i "s/${dep}==(.*)\"/${dep}${PACKAGE_CUDA_SUFFIX}==\1${alpha_spec}\"/g" ${pyproject_file} -done - -# dask-cuda & rapids-dask-dependency doesn't get a suffix, but it does get an alpha spec. -for dep in dask-cuda rapids-dask-dependency; do - sed -r -i "s/${dep}==(.*)\"/${dep}==\1${alpha_spec}\"/g" ${pyproject_file} -done - - -if [[ $PACKAGE_CUDA_SUFFIX == "-cu12" ]]; then - sed -i "s/cupy-cuda11x/cupy-cuda12x/g" ${pyproject_file} -fi - cd "${package_dir}" -python -m pip wheel . -w dist -vvv --no-deps --disable-pip-version-check +rapids-logger "Building '${package_name}' wheel" +python -m pip wheel \ + -w dist \ + -v \ + --no-deps \ + --disable-pip-version-check \ + . + +sccache --show-adv-stats # pure-python packages should be marked as pure, and not have auditwheel run on them. if [[ ${package_name} == "cugraph-dgl" ]] || \ [[ ${package_name} == "cugraph-pyg" ]]; then - RAPIDS_PY_WHEEL_NAME="${package_name}_${RAPIDS_PY_CUDA_SUFFIX}" RAPIDS_PY_WHEEL_PURE="1" rapids-upload-wheels-to-s3 dist + RAPIDS_PY_WHEEL_NAME="${package_name}_${RAPIDS_PY_CUDA_SUFFIX}" RAPIDS_PY_WHEEL_PURE="1" rapids-upload-wheels-to-s3 python dist else - # presumably WholeGraph when we add it + mkdir -p final_dist - python -m auditwheel repair -w final_dist dist/* + python -m auditwheel repair \ + "${EXCLUDE_ARGS[@]}" \ + -w final_dist \ + dist/* + RAPIDS_PY_WHEEL_NAME="${package_name}_${RAPIDS_PY_CUDA_SUFFIX}" rapids-upload-wheels-to-s3 final_dist fi diff --git a/ci/build_wheel_pylibwholegraph.sh b/ci/build_wheel_pylibwholegraph.sh new file mode 100755 index 00000000..c9c6b591 --- /dev/null +++ b/ci/build_wheel_pylibwholegraph.sh @@ -0,0 +1,9 @@ + +#!/bin/bash +# Copyright (c) 2024, NVIDIA CORPORATION. + +set -euo pipefail + +export SKBUILD_CMAKE_ARGS="-DDETECT_CONDA_ENV=OFF;-DBUILD_SHARED_LIBS=OFF;-DCMAKE_MESSAGE_LOG_LEVEL=VERBOSE;-DCUDA_STATIC_RUNTIME=ON;-DWHOLEGRAPH_BUILD_WHEELS=ON" + +./ci/build_wheel.sh pylibwholegraph python/pylibwholegraph diff --git a/ci/run_ctests.sh b/ci/run_ctests.sh new file mode 100755 index 00000000..1ebbf4c5 --- /dev/null +++ b/ci/run_ctests.sh @@ -0,0 +1,9 @@ +#!/bin/bash +# Copyright (c) 2024, NVIDIA CORPORATION. + +set -euo pipefail + +# Support customizing the ctests' install location +cd "${INSTALL_PREFIX:-${CONDA_PREFIX:-/usr}}/bin/gtests/libwholegraph/" + +find . -type f -executable -print0 | xargs -0 -r -t -n1 -P1 sh -c 'exec "$0"'; diff --git a/ci/run_pylibwholegraph_pytests.sh b/ci/run_pylibwholegraph_pytests.sh new file mode 100755 index 00000000..b21cbf91 --- /dev/null +++ b/ci/run_pylibwholegraph_pytests.sh @@ -0,0 +1,9 @@ +#!/bin/bash +# Copyright (c) 2024, NVIDIA CORPORATION. + +set -euo pipefail + +# Support invoking run_pytests.sh outside the script directory +cd "$(dirname "$(realpath "${BASH_SOURCE[0]}")")"/../python/pylibwholegraph/pylibwholegraph/ + +pytest --cache-clear --forked --import-mode=append "$@" tests diff --git a/ci/test_cpp.sh b/ci/test_cpp.sh index a5f7feed..c61fb1ad 100755 --- a/ci/test_cpp.sh +++ b/ci/test_cpp.sh @@ -8,11 +8,17 @@ cd "$(dirname "$(realpath "${BASH_SOURCE[0]}")")"/../ . /opt/conda/etc/profile.d/conda.sh +RAPIDS_VERSION="$(rapids-version)" + +CPP_CHANNEL=$(rapids-download-conda-from-s3 cpp) + rapids-logger "Generate C++ testing dependencies" rapids-dependency-file-generator \ --output conda \ --file-key test_cpp \ - --matrix "cuda=${RAPIDS_CUDA_VERSION%.*};arch=$(arch)" | tee env.yaml + --matrix "cuda=${RAPIDS_CUDA_VERSION%.*};arch=$(arch)" \ + --prepend-channel "${CPP_CHANNEL}" \ +| tee env.yaml rapids-mamba-retry env create --yes -f env.yaml -n test @@ -21,8 +27,6 @@ set +u conda activate test set -u -CPP_CHANNEL=$(rapids-download-conda-from-s3 cpp) - RAPIDS_TESTS_DIR=${RAPIDS_TESTS_DIR:-"${PWD}/test-results"}/ mkdir -p "${RAPIDS_TESTS_DIR}" @@ -30,22 +34,15 @@ rapids-print-env rapids-mamba-retry install \ --channel "${CPP_CHANNEL}" \ - libcugraph libcugraph_etl libcugraph-tests + "libwholegraph=${RAPIDS_VERSION}" \ + "libwholegraph-tests=${RAPIDS_VERSION}" rapids-logger "Check GPU usage" nvidia-smi -# RAPIDS_DATASET_ROOT_DIR is used by test scripts -export RAPIDS_DATASET_ROOT_DIR="$(realpath datasets)" -pushd "${RAPIDS_DATASET_ROOT_DIR}" -./get_test_data.sh --subset -popd - -export GTEST_OUTPUT=xml:${RAPIDS_TESTS_DIR}/ - -# Run libcugraph gtests from libcugraph-tests package -rapids-logger "Run gtests" -./ci/run_ctests.sh -j10 && EXITCODE=$? || EXITCODE=$?; +# Run libwholegraph tests from libwholegraph-tests package +rapids-logger "Run tests" +./ci/run_ctests.sh && EXITCODE=$? || EXITCODE=$? rapids-logger "Test script exiting with value: $EXITCODE" exit ${EXITCODE} diff --git a/ci/test_python.sh b/ci/test_python.sh index d9f64e4e..dd5f539e 100755 --- a/ci/test_python.sh +++ b/ci/test_python.sh @@ -8,174 +8,68 @@ cd "$(dirname "$(realpath "${BASH_SOURCE[0]}")")"/../ . /opt/conda/etc/profile.d/conda.sh -rapids-logger "Generate Python testing dependencies" -rapids-dependency-file-generator \ - --output conda \ - --file-key test_python \ - --matrix "cuda=${RAPIDS_CUDA_VERSION%.*};arch=$(arch);py=${RAPIDS_PY_VERSION}" | tee env.yaml - -rapids-mamba-retry env create --yes -f env.yaml -n test - -# Temporarily allow unbound variables for conda activation. -set +u -conda activate test -set -u +RAPIDS_VERSION="$(rapids-version)" rapids-logger "Downloading artifacts from previous jobs" CPP_CHANNEL=$(rapids-download-conda-from-s3 cpp) PYTHON_CHANNEL=$(rapids-download-conda-from-s3 python) +rapids-logger "Generate Python testing dependencies" +rapids-dependency-file-generator \ + --output conda \ + --file-key test_python \ + --matrix "cuda=${RAPIDS_CUDA_VERSION%.*};arch=$(arch);py=${RAPIDS_PY_VERSION}" \ + --prepend-channel "${CPP_CHANNEL}" \ + --prepend-channel "${PYTHON_CHANNEL}" \ +| tee env.yaml + 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-print-env - -rapids-mamba-retry install \ - --channel "${CPP_CHANNEL}" \ - --channel "${PYTHON_CHANNEL}" \ - libcugraph \ - pylibcugraph \ - cugraph \ - nx-cugraph \ - cugraph-service-server \ - cugraph-service-client - -rapids-logger "Check GPU usage" -nvidia-smi - -# RAPIDS_DATASET_ROOT_DIR is used by test scripts -export RAPIDS_DATASET_ROOT_DIR="$(realpath datasets)" -pushd "${RAPIDS_DATASET_ROOT_DIR}" -./get_test_data.sh --benchmark -popd - EXITCODE=0 trap "EXITCODE=1" ERR set +e - -# Test runs that include tests that use dask require -# --import-mode=append. Those tests start a LocalCUDACluster that inherits -# changes from pytest's modifications to PYTHONPATH (which defaults to -# prepending source tree paths to PYTHONPATH). This causes the -# LocalCUDACluster subprocess to import cugraph from the source tree instead of -# the install location, and in most cases, the source tree does not have -# extensions built in-place and will result in ImportErrors. -# -# FIXME: TEMPORARILY disable MG PropertyGraph tests (experimental) tests and -# bulk sampler IO tests (hangs in CI) -if [[ "${RAPIDS_CUDA_VERSION}" == "11.8.0" ]]; then - if [[ "${RUNNER_ARCH}" != "ARM64" ]]; then - # we are only testing in a single cuda version - # because of pytorch and rapids compatibilty problems - rapids-mamba-retry env create --yes -f env.yaml -n test_cugraph_dgl - - # activate test_cugraph_dgl environment for dgl - set +u - conda activate test_cugraph_dgl - set -u - rapids-mamba-retry install \ - --channel "${CPP_CHANNEL}" \ - --channel "${PYTHON_CHANNEL}" \ - --channel conda-forge \ - --channel dglteam/label/cu118 \ - --channel nvidia \ - libcugraph \ - pylibcugraph \ - pylibcugraphops \ - cugraph \ - cugraph-dgl \ - 'dgl>=1.1.0.cu*,<=2.0.0.cu*' \ - 'pytorch>=2.0' \ - 'cuda-version=11.8' - - rapids-print-env - - rapids-logger "pytest cugraph_dgl (single GPU)" - ./ci/run_cugraph_dgl_pytests.sh \ - --junitxml="${RAPIDS_TESTS_DIR}/junit-cugraph-dgl.xml" \ - --cov-config=../../.coveragerc \ - --cov=cugraph_dgl \ - --cov-report=xml:"${RAPIDS_COVERAGE_DIR}/cugraph-dgl-coverage.xml" \ - --cov-report=term - - # Reactivate the test environment back - set +u - conda deactivate - conda activate test - set -u - else - rapids-logger "skipping cugraph_dgl pytest on ARM64" - fi +if [[ "${RUNNER_ARCH}" != "ARM64" ]]; then + rapids-mamba-retry env create --yes -f env.yaml -n test_pylibwholegraph + + # Temporarily allow unbound variables for conda activation. + set +u + conda activate test_pylibwholegraph + set -u + + # Will automatically install built dependencies of pylibwholegraph + rapids-mamba-retry install \ + --channel "${CPP_CHANNEL}" \ + --channel "${PYTHON_CHANNEL}" \ + --channel pytorch \ + 'mkl<2024.1.0' \ + "pylibwholegraph=${RAPIDS_VERSION}" \ + 'pytorch::pytorch>=2.3,<2.4' \ + 'pytest-forked' \ + 'ogb' + + rapids-print-env + + rapids-logger "Check GPU usage" + nvidia-smi + + rapids-logger "pytest pylibwholegraph (single GPU)" + ./ci/run_pylibwholegraph_pytests.sh \ + --junitxml="${RAPIDS_TESTS_DIR}/junit-pylibwholegraph.xml" \ + --cov-config=../../.coveragerc \ + --cov=pylibwholegraph \ + --cov-report=xml:"${RAPIDS_COVERAGE_DIR}/pylibwholegraph-coverage.xml" \ + --cov-report=term + + # Reactivate the test environment back + set +u + conda deactivate + set -u else - rapids-logger "skipping cugraph_dgl pytest on CUDA!=11.8" + rapids-logger "skipping pylibwholegraph pytest on ARM64" fi -if [[ "${RAPIDS_CUDA_VERSION}" == "11.8.0" ]]; then - if [[ "${RUNNER_ARCH}" != "ARM64" ]]; then - rapids-mamba-retry env create --yes -f env.yaml -n test_cugraph_pyg - - # Temporarily allow unbound variables for conda activation. - set +u - conda activate test_cugraph_pyg - set -u - - # TODO re-enable logic once CUDA 12 is testable - #if [[ "${RAPIDS_CUDA_VERSION}" == "11.8.0" ]]; then - CONDA_CUDA_VERSION="11.8" - PYG_URL="https://data.pyg.org/whl/torch-2.1.0+cu118.html" - #else - # CONDA_CUDA_VERSION="12.1" - # PYG_URL="https://data.pyg.org/whl/torch-2.1.0+cu121.html" - #fi - - # Will automatically install built dependencies of cuGraph-PyG - rapids-mamba-retry install \ - --channel "${CPP_CHANNEL}" \ - --channel "${PYTHON_CHANNEL}" \ - --channel pytorch \ - --channel pyg \ - --channel nvidia \ - "cugraph-pyg" \ - "pytorch=2.1.0" \ - "pytorch-cuda=${CONDA_CUDA_VERSION}" - - # Install pyg dependencies (which requires pip) - - pip install \ - ogb \ - tensordict - - pip install \ - pyg_lib \ - torch_scatter \ - torch_sparse \ - -f ${PYG_URL} - - rapids-print-env - - rapids-logger "pytest cugraph_pyg (single GPU)" - # rmat is not tested because of multi-GPU testing - ./ci/run_cugraph_pyg_pytests.sh \ - --junitxml="${RAPIDS_TESTS_DIR}/junit-cugraph-pyg.xml" \ - --cov-config=../../.coveragerc \ - --cov=cugraph_pyg \ - --cov-report=xml:"${RAPIDS_COVERAGE_DIR}/cugraph-pyg-coverage.xml" \ - --cov-report=term - - # Reactivate the test environment back - set +u - conda deactivate - conda activate test - set -u - else - rapids-logger "skipping cugraph_pyg pytest on ARM64" - fi -else - rapids-logger "skipping cugraph_pyg pytest on CUDA!=11.8" -fi - - rapids-logger "Test script exiting with value: $EXITCODE" exit ${EXITCODE} diff --git a/ci/test_wheel_pylibwholegraph.sh b/ci/test_wheel_pylibwholegraph.sh new file mode 100755 index 00000000..823ae186 --- /dev/null +++ b/ci/test_wheel_pylibwholegraph.sh @@ -0,0 +1,42 @@ +#!/bin/bash +# Copyright (c) 2023-2024, 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 + +# determine pytorch source +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/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}" + +# echo to expand wildcard before adding `[extra]` requires for pip +rapids-logger "Installing Packages" +rapids-retry python -m pip install \ + --extra-index-url ${INDEX_URL} \ + "$(echo ./dist/pylibwholegraph*.whl)[test]" + +# install torch separately, to be sure we get a CUDA build +python -m pip install \ + --index-url "${INDEX_URL}" \ + -v \ + 'torch>=2.0,<2.4.0a0' + +rapids-logger "pytest pylibwholegraph" +cd python/pylibwholegraph/pylibwholegraph/tests +python -m pytest \ + --cache-clear \ + --forked \ + --import-mode=append \ + . diff --git a/conda/environments/all_cuda-118_arch-x86_64.yaml b/conda/environments/all_cuda-118_arch-x86_64.yaml index 213e9e35..6383b574 100644 --- a/conda/environments/all_cuda-118_arch-x86_64.yaml +++ b/conda/environments/all_cuda-118_arch-x86_64.yaml @@ -23,6 +23,7 @@ dependencies: - graphviz - ipython - nbsphinx +- nccl>=2.19 - ninja - notebook>=0.5.0 - numba>=0.57 @@ -35,24 +36,22 @@ dependencies: - pyg::pyg - pylibcugraphops==24.12.*,>=0.0.0a0 - pylibraft==24.12.*,>=0.0.0a0 -- pylibwholegraph==24.12.*,>=0.0.0a0 - pytest - pytest-benchmark - pytest-cov +- pytest-forked - pytest-xdist - pytorch-cuda=11.8 -- pytorch::pytorch>=2.0,<2.2.0a0 +- pytorch::pytorch>=2.0,<2.4.0a0 - raft-dask==24.12.*,>=0.0.0a0 - recommonmark - rmm==24.12.*,>=0.0.0a0 - scikit-build-core>=0.10.0 - scipy -- setuptools>=61.0.0 - sphinx-copybutton - sphinx-markdown-tables - sphinx<6 - sphinxcontrib-websupport - torchdata - wget -- wheel name: all_cuda-118_arch-x86_64 diff --git a/conda/environments/all_cuda-121_arch-x86_64.yaml b/conda/environments/all_cuda-121_arch-x86_64.yaml index 2ca88f8e..7429b0d6 100644 --- a/conda/environments/all_cuda-121_arch-x86_64.yaml +++ b/conda/environments/all_cuda-121_arch-x86_64.yaml @@ -28,6 +28,7 @@ dependencies: - libcusolver-dev - libcusparse-dev - nbsphinx +- nccl>=2.19 - ninja - notebook>=0.5.0 - numba>=0.57 @@ -40,24 +41,22 @@ dependencies: - pyg::pyg - pylibcugraphops==24.12.*,>=0.0.0a0 - pylibraft==24.12.*,>=0.0.0a0 -- pylibwholegraph==24.12.*,>=0.0.0a0 - pytest - pytest-benchmark - pytest-cov +- pytest-forked - pytest-xdist - pytorch-cuda=12.1 -- pytorch::pytorch>=2.0,<2.2.0a0 +- pytorch::pytorch>=2.0,<2.4.0a0 - raft-dask==24.12.*,>=0.0.0a0 - recommonmark - rmm==24.12.*,>=0.0.0a0 - scikit-build-core>=0.10.0 - scipy -- setuptools>=61.0.0 - sphinx-copybutton - sphinx-markdown-tables - sphinx<6 - sphinxcontrib-websupport - torchdata - wget -- wheel name: all_cuda-121_arch-x86_64 diff --git a/conda/environments/all_cuda-124_arch-x86_64.yaml b/conda/environments/all_cuda-124_arch-x86_64.yaml index b88c0db7..08c0ee6d 100644 --- a/conda/environments/all_cuda-124_arch-x86_64.yaml +++ b/conda/environments/all_cuda-124_arch-x86_64.yaml @@ -28,6 +28,7 @@ dependencies: - libcusolver-dev - libcusparse-dev - nbsphinx +- nccl>=2.19 - ninja - notebook>=0.5.0 - numba>=0.57 @@ -40,24 +41,22 @@ dependencies: - pyg::pyg - pylibcugraphops==24.12.*,>=0.0.0a0 - pylibraft==24.12.*,>=0.0.0a0 -- pylibwholegraph==24.12.*,>=0.0.0a0 - pytest - pytest-benchmark - pytest-cov +- pytest-forked - pytest-xdist - pytorch-cuda=12.1 -- pytorch::pytorch>=2.0,<2.2.0a0 +- pytorch::pytorch>=2.0,<2.4.0a0 - raft-dask==24.12.*,>=0.0.0a0 - recommonmark - rmm==24.12.*,>=0.0.0a0 - scikit-build-core>=0.10.0 - scipy -- setuptools>=61.0.0 - sphinx-copybutton - sphinx-markdown-tables - sphinx<6 - sphinxcontrib-websupport - torchdata - wget -- wheel name: all_cuda-124_arch-x86_64 diff --git a/conda/recipes/libwholegraph/conda_build_config.yaml b/conda/recipes/libwholegraph/conda_build_config.yaml index 35b1d6b6..ebb154c2 100644 --- a/conda/recipes/libwholegraph/conda_build_config.yaml +++ b/conda/recipes/libwholegraph/conda_build_config.yaml @@ -17,7 +17,7 @@ doxygen_version: - ">=1.8.11" nccl_version: - - ">=2.9.9" + - ">=2.19" c_stdlib: - sysroot diff --git a/conda/recipes/pylibwholegraph/build.sh b/conda/recipes/pylibwholegraph/build.sh index cd61f906..3a7eb7c3 100644 --- a/conda/recipes/pylibwholegraph/build.sh +++ b/conda/recipes/pylibwholegraph/build.sh @@ -1,6 +1,4 @@ #!/usr/bin/env bash # Copyright (c) 2022-2024, NVIDIA CORPORATION. -CMAKE_EXTRA_ARGS="--cmake-args=\"-DBUILD_OPS_WITH_TORCH_C10_API=OFF\"" - -./build.sh pylibwholegraph --allgpuarch -v ${CMAKE_EXTRA_ARGS} +./build.sh pylibwholegraph --allgpuarch -v diff --git a/conda/recipes/pylibwholegraph/meta.yaml b/conda/recipes/pylibwholegraph/meta.yaml index d3f9a49b..19840fa6 100644 --- a/conda/recipes/pylibwholegraph/meta.yaml +++ b/conda/recipes/pylibwholegraph/meta.yaml @@ -71,8 +71,11 @@ requirements: - cudatoolkit {% endif %} - libwholegraph ={{ version }} + - numpy >=1.23,<3.0a0 - python about: home: https://rapids.ai/ + license: Apache-2.0 + license_file: ../../../LICENSE summary: pylibwholegraph library diff --git a/cpp/cmake/thirdparty/get_raft.cmake b/cpp/cmake/thirdparty/get_raft.cmake index e542e7f2..78556035 100644 --- a/cpp/cmake/thirdparty/get_raft.cmake +++ b/cpp/cmake/thirdparty/get_raft.cmake @@ -14,8 +14,8 @@ # limitations under the License. #============================================================================= -set(WHOLEGRAPH_MIN_VERSION_raft "${RAPIDS_VERSION}.00") -set(WHOLEGRAPH_BRANCH_VERSION_raft "${RAPIDS_VERSION}") +set(WHOLEGRAPH_MIN_VERSION_raft "${RAPIDS_VERSION_MAJOR}.${RAPIDS_VERSION_MINOR}.00") +set(WHOLEGRAPH_BRANCH_VERSION_raft "${RAPIDS_VERSION_MAJOR}.${RAPIDS_VERSION_MINOR}") function(find_and_configure_raft) diff --git a/dependencies.yaml b/dependencies.yaml index a25f04ff..e0e74d22 100644 --- a/dependencies.yaml +++ b/dependencies.yaml @@ -22,15 +22,18 @@ files: - depends_on_pylibraft - depends_on_raft_dask - depends_on_pylibcugraphops - - depends_on_pylibwholegraph - depends_on_cupy - depends_on_pytorch - depends_on_dgl - depends_on_pyg - python_run_cugraph_dgl - python_run_cugraph_pyg + - test_cpp - test_notebook - test_python_common + - test_python_cugraph_dgl + - test_python_cugraph_pyg + - test_python_pylibwholegraph checks: output: none @@ -62,10 +65,41 @@ files: - cuda_version - depends_on_cugraph - depends_on_cudf - - depends_on_pylibwholegraph + - depends_on_pytorch - py_version - test_python_common - - test_python_pylibcugraph + + py_build_pylibwholegraph: + output: pyproject + pyproject_dir: python/pylibwholegraph + extras: + table: build-system + includes: + - rapids_build_skbuild + py_rapids_build_pylibwholegraph: + output: pyproject + pyproject_dir: python/pylibwholegraph + extras: + table: tool.rapids-build-backend + key: requires + includes: + - python_build_wheel + py_run_pylibwholegraph: + output: pyproject + pyproject_dir: python/pylibwholegraph + extras: + table: project + includes: + - python_run_pylibwholegraph + py_test_pylibwholegraph: + output: pyproject + pyproject_dir: python/pylibwholegraph + extras: + table: project.optional-dependencies + key: test + includes: + - test_python_common + - test_python_pylibwholegraph py_build_cugraph_dgl: output: pyproject @@ -90,6 +124,7 @@ files: key: test includes: - test_python_common + - test_python_cugraph_dgl - depends_on_pylibwholegraph py_build_cugraph_pyg: output: pyproject @@ -114,6 +149,7 @@ files: key: test includes: - test_python_common + - test_python_cugraph_pyg - depends_on_pylibwholegraph @@ -130,6 +166,7 @@ files: - depends_on_pytorch - cugraph_dgl_dev - test_python_common + - test_python_cugraph_dgl cugraph_pyg_dev: matrix: cuda: ["11.8"] @@ -142,6 +179,7 @@ files: - depends_on_pytorch - cugraph_pyg_dev - test_python_common + - test_python_cugraph_pyg channels: - rapidsai - rapidsai-nightly @@ -260,8 +298,9 @@ dependencies: common: - output_types: [conda, pyproject, requirements] packages: - - setuptools>=61.0.0 - - wheel + - cmake>=3.26.4,!=3.30.0 + - cython>=3.0.0 + - ninja python_build_cythonize: common: - output_types: [conda, pyproject, requirements] @@ -273,12 +312,17 @@ dependencies: - output_types: [pyproject, requirements] packages: - scikit-build-core[pyproject]>=0.10.0 + python_run_pylibwholegraph: + common: + - output_types: [conda, pyproject, requirements] + packages: + - &numpy numpy>=1.23,<3.0a0 python_run_cugraph_dgl: common: - output_types: [conda, pyproject] packages: - &numba numba>=0.57 - - &numpy numpy>=1.23,<3.0a0 + - *numpy - output_types: [pyproject] packages: - &cugraph cugraph==24.12.*,>=0.0.0a0 @@ -291,6 +335,23 @@ dependencies: - output_types: [pyproject] packages: - *cugraph + rapids_build_skbuild: + common: + - output_types: [conda, requirements, pyproject] + packages: + - rapids-build-backend>=0.3.0,<0.4.0.dev0 + - output_types: conda + packages: + - scikit-build-core>=0.10.0 + - output_types: [requirements, pyproject] + packages: + - scikit-build-core[pyproject]>=0.10.0 + test_cpp: + common: + - output_types: conda + packages: + - *cmake_ver + - nccl>=2.19 test_notebook: common: - output_types: [conda, requirements] @@ -304,11 +365,25 @@ dependencies: common: - output_types: [conda, pyproject] packages: - - pandas - pytest - pytest-benchmark - pytest-cov - pytest-xdist + test_python_cugraph_dgl: + common: + - output_types: [conda, pyproject, requirements] + packages: + - &pandas pandas + test_python_cugraph_pyg: + common: + - output_types: [conda, pyproject, requirements] + packages: + - *pandas + test_python_pylibwholegraph: + common: + - output_types: [conda, pyproject, requirements] + packages: + - pytest-forked - scipy cugraph_dgl_dev: common: @@ -331,7 +406,7 @@ dependencies: common: - output_types: [conda] packages: - - pytorch::pytorch>=2.0,<2.2.0a0 + - pytorch::pytorch>=2.0,<2.4.0a0 - torchdata - pydantic specific: @@ -348,7 +423,7 @@ dependencies: matrices: - matrix: {cuda: "12.*"} packages: - - &pytorch_pip torch>=2.0,<2.2.0a0 + - &pytorch_pip torch>=2.0,<2.4.0a0 - *tensordict - matrix: {cuda: "11.*"} packages: diff --git a/python/.coveragerc b/python/.coveragerc new file mode 100644 index 00000000..d24d6341 --- /dev/null +++ b/python/.coveragerc @@ -0,0 +1,21 @@ +# Copyright (c) 2024, 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. + +# Configuration file for Python coverage tests +[run] +include = cugraph-dgl/cugraph_dgl/* + cugraph-pyg/cugraph_pyg/* + pylibwholegraph/pylibwholegraph/* +omit = cugraph-dgl/cugraph_dgl/tests/* + cugraph-pyg/cugraph_pyg/tests/* + pylibwholegraph/pylibwholegraph/tests/* diff --git a/python/cugraph-dgl/conda/cugraph_dgl_dev_cuda-118.yaml b/python/cugraph-dgl/conda/cugraph_dgl_dev_cuda-118.yaml index e1075c21..9f0070f8 100644 --- a/python/cugraph-dgl/conda/cugraph_dgl_dev_cuda-118.yaml +++ b/python/cugraph-dgl/conda/cugraph_dgl_dev_cuda-118.yaml @@ -21,8 +21,7 @@ dependencies: - pytest-xdist - pytorch-cuda=11.8 - pytorch::pytorch>=2.0 -- pytorch::pytorch>=2.0,<2.2.0a0 -- scipy +- pytorch::pytorch>=2.0,<2.4.0a0 - tensordict>=0.1.2 - torchdata name: cugraph_dgl_dev_cuda-118 diff --git a/python/cugraph-dgl/pyproject.toml b/python/cugraph-dgl/pyproject.toml index 0e625f39..0ca636d1 100644 --- a/python/cugraph-dgl/pyproject.toml +++ b/python/cugraph-dgl/pyproject.toml @@ -3,8 +3,9 @@ [build-system] requires = [ - "setuptools>=61.0.0", - "wheel", + "cmake>=3.26.4,!=3.30.0", + "cython>=3.0.0", + "ninja", ] # 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" @@ -37,7 +38,6 @@ test = [ "pytest-benchmark", "pytest-cov", "pytest-xdist", - "scipy", ] # This list was generated by `rapids-dependency-file-generator`. To make changes, edit ../../dependencies.yaml and run `rapids-dependency-file-generator`. [project.urls] diff --git a/python/cugraph-pyg/conda/cugraph_pyg_dev_cuda-118.yaml b/python/cugraph-pyg/conda/cugraph_pyg_dev_cuda-118.yaml index 63414a67..a9f520c8 100644 --- a/python/cugraph-pyg/conda/cugraph_pyg_dev_cuda-118.yaml +++ b/python/cugraph-pyg/conda/cugraph_pyg_dev_cuda-118.yaml @@ -20,8 +20,7 @@ dependencies: - pytest-xdist - pytorch-cuda=11.8 - pytorch::pytorch>=2.0 -- pytorch::pytorch>=2.0,<2.2.0a0 -- scipy +- pytorch::pytorch>=2.0,<2.4.0a0 - tensordict>=0.1.2 - torchdata name: cugraph_pyg_dev_cuda-118 diff --git a/python/cugraph-pyg/pyproject.toml b/python/cugraph-pyg/pyproject.toml index a251635c..d0bfe58f 100644 --- a/python/cugraph-pyg/pyproject.toml +++ b/python/cugraph-pyg/pyproject.toml @@ -3,8 +3,9 @@ [build-system] requires = [ - "setuptools>=61.0.0", - "wheel", + "cmake>=3.26.4,!=3.30.0", + "cython>=3.0.0", + "ninja", ] # This list was generated by `rapids-dependency-file-generator`. To make changes, edit ../../dependencies.yaml and run `rapids-dependency-file-generator`. [tool.pytest.ini_options] @@ -45,7 +46,6 @@ test = [ "pytest-benchmark", "pytest-cov", "pytest-xdist", - "scipy", ] # This list was generated by `rapids-dependency-file-generator`. To make changes, edit ../../dependencies.yaml and run `rapids-dependency-file-generator`. [tool.setuptools] diff --git a/python/pylibwholegraph/pylibwholegraph/binding/wholememory_binding.pyx b/python/pylibwholegraph/pylibwholegraph/binding/wholememory_binding.pyx index dc72eb32..44728f40 100644 --- a/python/pylibwholegraph/pylibwholegraph/binding/wholememory_binding.pyx +++ b/python/pylibwholegraph/pylibwholegraph/binding/wholememory_binding.pyx @@ -27,7 +27,6 @@ from libcpp cimport bool from cpython cimport Py_buffer from cpython cimport array import array -import numpy as np from cpython.ref cimport PyObject, Py_INCREF, Py_DECREF from cpython.object cimport Py_TYPE, PyObject_CallObject from cpython.tuple cimport * diff --git a/python/pylibwholegraph/pyproject.toml b/python/pylibwholegraph/pyproject.toml index 0c423352..3eed9dc8 100644 --- a/python/pylibwholegraph/pyproject.toml +++ b/python/pylibwholegraph/pyproject.toml @@ -36,6 +36,20 @@ classifiers = [ "Programming Language :: Python :: 3.11", "Programming Language :: Python :: 3.12", ] +dependencies = [ + "numpy>=1.23,<3.0a0", +] # This list was generated by `rapids-dependency-file-generator`. To make changes, edit ../../dependencies.yaml and run `rapids-dependency-file-generator`. + + +[project.optional-dependencies] +test = [ + "pytest", + "pytest-benchmark", + "pytest-cov", + "pytest-forked", + "pytest-xdist", + "scipy", +] # This list was generated by `rapids-dependency-file-generator`. To make changes, edit ../../dependencies.yaml and run `rapids-dependency-file-generator`. [tool.rapids-build-backend] build-backend = "scikit_build_core.build"