diff --git a/.github/workflows/build.yaml b/.github/workflows/build.yaml index a5e65a76e..f4d06ef65 100644 --- a/.github/workflows/build.yaml +++ b/.github/workflows/build.yaml @@ -38,7 +38,7 @@ jobs: sha: ${{ inputs.sha }} date: ${{ inputs.date }} script: ci/build_wheel_nx-cugraph.sh - # This selects "ARCH=amd64 + the latest supported Python + CUDA". + # This selects "ARCH=amd64 + the latest supported Python, 1 job per major CUDA version". matrix_filter: map(select(.ARCH == "amd64")) | group_by(.CUDA_VER|split(".")|map(tonumber)|.[0]) | map(max_by([(.PY_VER|split(".")|map(tonumber)), (.CUDA_VER|split(".")|map(tonumber))])) wheel-publish-nx-cugraph: needs: wheel-build-nx-cugraph diff --git a/.github/workflows/pr.yaml b/.github/workflows/pr.yaml index dc2dddff9..e74ba55ec 100644 --- a/.github/workflows/pr.yaml +++ b/.github/workflows/pr.yaml @@ -15,7 +15,9 @@ jobs: - changed-files - checks - conda-python-build + - conda-python-tests - wheel-build-nx-cugraph + - wheel-tests-nx-cugraph secrets: inherit uses: rapidsai/shared-workflows/.github/workflows/pr-builder.yaml@branch-24.12 if: always() @@ -46,8 +48,14 @@ jobs: uses: rapidsai/shared-workflows/.github/workflows/conda-python-build.yaml@branch-24.12 with: build_type: pull-request - # This selects "ARCH=amd64 + the latest supported Python + CUDA". - matrix_filter: map(select(.ARCH == "amd64")) | group_by(.CUDA_VER|split(".")|map(tonumber)|.[0]) | map(max_by([(.PY_VER|split(".")|map(tonumber)), (.CUDA_VER|split(".")|map(tonumber))])) + 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 + run_codecov: false wheel-build-nx-cugraph: needs: [checks] secrets: inherit @@ -55,5 +63,15 @@ jobs: with: build_type: pull-request script: ci/build_wheel_nx-cugraph.sh - # This selects "ARCH=amd64 + the latest supported Python + CUDA". + # This selects "ARCH=amd64 + the latest supported Python, 1 job per major CUDA version". + matrix_filter: map(select(.ARCH == "amd64")) | group_by(.CUDA_VER|split(".")|map(tonumber)|.[0]) | map(max_by([(.PY_VER|split(".")|map(tonumber)), (.CUDA_VER|split(".")|map(tonumber))])) + wheel-tests-nx-cugraph: + needs: [wheel-build-nx-cugraph, 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_nx-cugraph.sh + # This selects "ARCH=amd64 + the latest supported Python, 1 job per major CUDA version". matrix_filter: map(select(.ARCH == "amd64")) | group_by(.CUDA_VER|split(".")|map(tonumber)|.[0]) | map(max_by([(.PY_VER|split(".")|map(tonumber)), (.CUDA_VER|split(".")|map(tonumber))])) diff --git a/.github/workflows/test.yaml b/.github/workflows/test.yaml index ffb46a702..508f4277b 100644 --- a/.github/workflows/test.yaml +++ b/.github/workflows/test.yaml @@ -22,6 +22,9 @@ jobs: branch: ${{ inputs.branch }} date: ${{ inputs.date }} sha: ${{ inputs.sha }} + # This selects "ARCH=amd64 + the latest supported Python, 1 job per major CUDA version". + matrix_filter: map(select(.ARCH == "amd64")) | group_by(.CUDA_VER|split(".")|map(tonumber)|.[0]) | map(max_by([(.PY_VER|split(".")|map(tonumber)), (.CUDA_VER|split(".")|map(tonumber))])) + run_codecov: false wheel-tests-nx-cugraph: secrets: inherit uses: rapidsai/shared-workflows/.github/workflows/wheels-test.yaml@branch-24.12 @@ -31,3 +34,5 @@ jobs: date: ${{ inputs.date }} sha: ${{ inputs.sha }} script: ci/test_wheel_nx-cugraph.sh + # This selects "ARCH=amd64 + the latest supported Python, 1 job per major CUDA version". + matrix_filter: map(select(.ARCH == "amd64")) | group_by(.CUDA_VER|split(".")|map(tonumber)|.[0]) | map(max_by([(.PY_VER|split(".")|map(tonumber)), (.CUDA_VER|split(".")|map(tonumber))])) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index d737f0259..d748cd92e 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -1,8 +1,8 @@ ## https://pre-commit.com/ # # Before first use: `pre-commit install` -# To run: `make lint` -# To update: `make lint-update` +# To run: `pre-commit run --all-files` +# To update: `pre-commit autoupdate` # - &flake8_dependencies below needs updated manually exclude: '^thirdparty' fail_fast: false @@ -20,28 +20,12 @@ repos: - id: check-toml - id: check-yaml exclude: '^conda/recipes/.*\.yaml$' + - id: check-executables-have-shebangs - id: debug-statements - id: end-of-file-fixer exclude_types: [svg] - id: mixed-line-ending - - id: no-commit-to-branch - args: [-p, "^branch-2....$"] - id: trailing-whitespace - - repo: https://github.com/PyCQA/flake8 - rev: 7.1.1 - hooks: - - id: flake8 - args: ["--config=.flake8"] # uses config - additional_dependencies: &flake8_dependencies - # These versions need updated manually - - flake8==7.1.1 - - flake8-bugbear==24.8.19 - - flake8-simplify==0.21.0 - - repo: https://github.com/asottile/yesqa - rev: v1.5.0 - hooks: - - id: yesqa - additional_dependencies: *flake8_dependencies - repo: https://github.com/abravalheri/validate-pyproject rev: v0.22 hooks: @@ -65,6 +49,26 @@ repos: rev: 24.10.0 hooks: - id: black + - repo: https://github.com/astral-sh/ruff-pre-commit + rev: v0.7.3 + hooks: + - id: ruff + args: [--fix-only, --show-fixes] # --unsafe-fixes] + - repo: https://github.com/PyCQA/flake8 + rev: 7.1.1 + hooks: + - id: flake8 + args: ["--config=.flake8"] # uses config + additional_dependencies: &flake8_dependencies + # These versions need updated manually + - flake8==7.1.1 + - flake8-bugbear==24.10.31 + - flake8-simplify==0.21.0 + - repo: https://github.com/asottile/yesqa + rev: v1.5.0 + hooks: + - id: yesqa + additional_dependencies: *flake8_dependencies - repo: https://github.com/codespell-project/codespell rev: v2.3.0 hooks: @@ -73,18 +77,12 @@ repos: additional_dependencies: [tomli] files: ^(nx_cugraph|docs)/ args: ["-L thirdparty,coo,COO,numer"] - - repo: https://github.com/rapidsai/pre-commit-hooks - rev: v0.4.0 + - repo: https://github.com/astral-sh/ruff-pre-commit + rev: v0.7.3 hooks: - - id: verify-copyright - files: | - (?x) - [.](sh|py)$| - [.]flake8[.]cython$| - meta[.]yaml$| - setup[.]cfg$ - - id: verify-alpha-spec - args: ["--fix"] + - id: ruff + # Don't have strict linting for miscellaneous code + args: [--extend-exclude, "benchmarks/,ci/,docs/,notebooks/"] - repo: https://github.com/rapidsai/dependency-file-generator rev: v1.16.0 hooks: @@ -95,7 +93,7 @@ repos: - id: nx-cugraph-meta-data-update name: nx-cugraph meta-data updater entry: bash -c "PYTHONPATH=. python _nx_cugraph/__init__.py" - files: ^nx_cugraph + files: ^(nx_cugraph|_nx_cugraph)/ types: [python] language: python pass_filenames: false @@ -105,8 +103,25 @@ repos: - id: nx-cugraph-readme-update name: nx-cugraph README updater entry: bash -c "PYTHONPATH=. python ./scripts/update_readme.py ./README.md" - files: ^nx_cugraph/ + files: ^(nx_cugraph|_nx_cugraph)/ types_or: [python, markdown] language: python pass_filenames: false - additional_dependencies: ["networkx>=3.3"] + additional_dependencies: ["networkx>=3.4"] + - repo: https://github.com/rapidsai/pre-commit-hooks + rev: v0.4.0 + hooks: + - id: verify-copyright + files: | + (?x) + [.](sh|py)$| + [.]flake8[.]cython$| + meta[.]yaml$| + setup[.]cfg$ + - id: verify-alpha-spec + args: ["--fix"] + - repo: https://github.com/pre-commit/pre-commit-hooks + rev: v5.0.0 + hooks: + - id: no-commit-to-branch + args: [-p, "^branch-2....$"] diff --git a/_nx_cugraph/__init__.py b/_nx_cugraph/__init__.py index 9feeda568..cbc22e033 100644 --- a/_nx_cugraph/__init__.py +++ b/_nx_cugraph/__init__.py @@ -343,14 +343,16 @@ def update_env_var(varname): return d -def _check_networkx_version() -> tuple[int, int]: +def _check_networkx_version() -> tuple[int, int] | tuple[int, int, int]: """Check the version of networkx and return ``(major, minor)`` version tuple.""" import re import warnings import networkx as nx - version_major, version_minor = nx.__version__.split(".")[:2] + version_major, version_minor, *version_bug = nx.__version__.split(".")[:3] + if has_bug := bool(version_bug): + version_bug = version_bug[0] if version_major != "3": warnings.warn( f"nx-cugraph version {__version__} is only known to work with networkx " @@ -363,15 +365,19 @@ def _check_networkx_version() -> tuple[int, int]: # Allow single-digit minor versions, e.g. 3.4 and release candidates, e.g. 3.4rc0 pattern = r"^\d(rc\d+)?$" - if not re.match(pattern, version_minor): + if not re.match(pattern, version_bug if has_bug else version_minor): raise RuntimeWarning( f"nx-cugraph version {__version__} does not work with networkx version " f"{nx.__version__}. Please upgrade (or fix) your Python environment." ) nxver_major = int(version_major) - nxver_minor = int(re.match(r"^\d+", version_minor).group()) - return (nxver_major, nxver_minor) + if not has_bug: + nxver_minor = int(re.match(r"^\d+", version_minor).group()) + return (nxver_major, nxver_minor) + nxver_minor = int(version_minor) + nxver_bug = int(re.match(r"^\d+", version_bug).group()) + return (nxver_major, nxver_minor, nxver_bug) if __name__ == "__main__": diff --git a/benchmarks/nx-cugraph/pytest-based/bench_algos.py b/benchmarks/nx-cugraph/pytest-based/bench_algos.py index 03f16fc1a..9615b43ea 100644 --- a/benchmarks/nx-cugraph/pytest-based/bench_algos.py +++ b/benchmarks/nx-cugraph/pytest-based/bench_algos.py @@ -79,7 +79,7 @@ def setup_module(module): # easier-to-read name. This is especially helpful for Dataset objs (see # https://docs.pytest.org/en/stable/reference/reference.html#pytest-fixture) @pytest.fixture( - scope="module", params=dataset_param_values, ids=lambda ds: f"ds={str(ds)}" + scope="module", params=dataset_param_values, ids=lambda ds: f"ds={ds!s}" ) def graph_obj(request): """ diff --git a/benchmarks/nx-cugraph/pytest-based/create_results_summary_page.py b/benchmarks/nx-cugraph/pytest-based/create_results_summary_page.py index bbe449c86..4651f5c4f 100644 --- a/benchmarks/nx-cugraph/pytest-based/create_results_summary_page.py +++ b/benchmarks/nx-cugraph/pytest-based/create_results_summary_page.py @@ -131,8 +131,7 @@ def get_first_gpu_info(): first_gpu = gpus[0] # Get the information for the first GPU gpu_name, mem_total, _, _ = first_gpu.split(",") return f"{num_gpus} x {gpu_name.strip()} ({round(int(mem_total.strip().split()[0]) / (1024), 2)} GB)" - else: - print("No GPU found or unable to query GPU details.") + print("No GPU found or unable to query GPU details.") except subprocess.CalledProcessError: print("Failed to execute nvidia-smi. No GPU information available.") diff --git a/ci/build_python.sh b/ci/build_python.sh index 2f42e8ef6..93b28c9a8 100755 --- a/ci/build_python.sh +++ b/ci/build_python.sh @@ -9,7 +9,11 @@ source rapids-date-string rapids-print-env -rapids-generate-version > ./VERSION +# TODO: revert this once we start publishing nightly packages from the +# 'nx-cugraph' repo and stop publishing them from the 'cugraph' repo +# rapids-generate-version > ./VERSION +echo "24.12.00a1000" > ./VERSION + rapids-logger "Begin py build" # TODO: Remove `--no-test` flags once importing on a CPU diff --git a/ci/run_nx_cugraph_pytests.sh b/ci/run_nx_cugraph_pytests.sh new file mode 100755 index 000000000..a18cebb49 --- /dev/null +++ b/ci/run_nx_cugraph_pytests.sh @@ -0,0 +1,11 @@ +#!/bin/bash +# Copyright (c) 2024, NVIDIA CORPORATION. + +set -euo pipefail + +# Support invoking run_nx_cugraph_pytests.sh outside the script directory +cd "$(dirname "$(realpath "${BASH_SOURCE[0]}")")"/.. + +# Only be verbose and display print information for the first pytest command here +NX_CUGRAPH_USE_COMPAT_GRAPHS=False pytest --capture=no --verbose --cache-clear --benchmark-disable "$@" ./nx_cugraph/tests +NX_CUGRAPH_USE_COMPAT_GRAPHS=True pytest --cache-clear --benchmark-disable "$@" ./nx_cugraph/tests diff --git a/ci/test_python.sh b/ci/test_python.sh new file mode 100755 index 000000000..3fc93c56c --- /dev/null +++ b/ci/test_python.sh @@ -0,0 +1,101 @@ +#!/bin/bash +# Copyright (c) 2022-2024, NVIDIA CORPORATION. + +set -euo pipefail + +# Support invoking test_python.sh outside the script directory +cd "$(dirname "$(realpath "${BASH_SOURCE[0]}")")"/../ + +. /opt/conda/etc/profile.d/conda.sh + +RAPIDS_VERSION="$(rapids-version)" + +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-logger "Downloading artifacts from previous jobs" +PYTHON_CHANNEL=$(rapids-download-conda-from-s3 python) + +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 + + # TODO: remove the '>=24.12.00a1000' once we start publishing nightly packages + # from the 'nx-cugraph' repo and stop publishing them from the 'cugraph' repo +rapids-mamba-retry install \ + --channel "${PYTHON_CHANNEL}" \ + "nx-cugraph=${RAPIDS_VERSION}.*,>=24.12.00a1000" + +rapids-logger "Check GPU usage" +nvidia-smi + +# export LD_PRELOAD="${CONDA_PREFIX}/lib/libgomp.so.1" + +# 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 + +rapids-logger "pytest nx-cugraph" +./ci/run_nx_cugraph_pytests.sh \ + --junitxml="${RAPIDS_TESTS_DIR}/junit-nx-cugraph.xml" \ + --cov=nx_cugraph \ + --cov-report=xml:"${RAPIDS_COVERAGE_DIR}/nx-cugraph-coverage.xml" \ + --cov-report=term + +rapids-logger "pytest networkx using nx-cugraph backend" + +pushd nx_cugraph +../run_nx_tests.sh + +# run_nx_tests.sh outputs coverage data, so check that total coverage is >0.0% +# in case nx-cugraph failed to load but fallback mode allowed the run to pass. +_coverage=$(coverage report | grep "^TOTAL") + +echo "nx-cugraph coverage from networkx tests: $_coverage" +echo $_coverage | awk '{ if ($NF == "0.0%") exit 1 }' + +# Ensure all algorithms were called by comparing covered lines to function lines. +# Run our tests again (they're fast enough) to add their coverage, then create coverage.json +NX_CUGRAPH_USE_COMPAT_GRAPHS=False pytest \ + --pyargs nx_cugraph \ + --config-file=../pyproject.toml \ + --cov-config=../pyproject.toml \ + --cov=nx_cugraph \ + --cov-append \ + --cov-report= + +coverage report \ + --include="*/nx_cugraph/algorithms/*" \ + --omit=__init__.py \ + --show-missing \ + --rcfile=../pyproject.toml + +coverage json --rcfile=../pyproject.toml + +python -m nx_cugraph.tests.ensure_algos_covered + +# Exercise (and show results of) scripts that show implemented networkx algorithms +python -m nx_cugraph.scripts.print_tree --dispatch-name --plc --incomplete --different +python -m nx_cugraph.scripts.print_table +popd + +rapids-logger "Test script exiting with value: $EXITCODE" +exit ${EXITCODE} diff --git a/ci/test_wheel_nx-cugraph.sh b/ci/test_wheel_nx-cugraph.sh new file mode 100755 index 000000000..5f0917fca --- /dev/null +++ b/ci/test_wheel_nx-cugraph.sh @@ -0,0 +1,36 @@ +#!/bin/bash +# Copyright (c) 2023-2024, NVIDIA CORPORATION. + +set -eoxu pipefail + +package_name="nx-cugraph" +python_package_name=$(echo ${package_name}|sed 's/-/_/g') + +mkdir -p ./dist +RAPIDS_PY_CUDA_SUFFIX="$(rapids-wheel-ctk-name-gen ${RAPIDS_CUDA_VERSION})" + +# nx-cugraph is a pure wheel, which is part of generating the download path +RAPIDS_PY_WHEEL_NAME="${package_name}_${RAPIDS_PY_CUDA_SUFFIX}" RAPIDS_PY_WHEEL_PURE="1" rapids-download-wheels-from-s3 ./dist + +# echo to expand wildcard before adding `[extra]` requires for pip +python -m pip install \ + "$(echo ./dist/${python_package_name}*.whl)[test]" + +# Run smoke tests for aarch64 pull requests +arch=$(uname -m) +if [[ "${arch}" == "aarch64" && ${RAPIDS_BUILD_TYPE} == "pull-request" ]]; then + python ./ci/wheel_smoke_test_${package_name}.py +else + # --import-mode=append. See test_python.sh for details. + # FIXME: Adding PY_IGNORE_IMPORTMISMATCH=1 to workaround conftest.py import + # mismatch error seen by nx-cugraph after using pytest 8 and + # --import-mode=append. + RAPIDS_DATASET_ROOT_DIR=`pwd`/datasets \ + PY_IGNORE_IMPORTMISMATCH=1 \ + NX_CUGRAPH_USE_COMPAT_GRAPHS=False \ + python -m pytest \ + -v \ + --import-mode=append \ + --benchmark-disable \ + ./${python_package_name}/tests +fi diff --git a/ci/wheel_smoke_test_nx-cugraph.py b/ci/wheel_smoke_test_nx-cugraph.py new file mode 100644 index 000000000..e252cc424 --- /dev/null +++ b/ci/wheel_smoke_test_nx-cugraph.py @@ -0,0 +1,39 @@ +# Copyright (c) 2023-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. + +import math + +import networkx as nx + +import nx_cugraph as nxcg + +if __name__ == "__main__": + G = nx.Graph() + G.add_edges_from([(0, 1), (1, 2), (2, 3)]) + + nx_result = nx.betweenness_centrality(G) + # nx_cugraph is intended to be called via the NetworkX dispatcher, like + # this: + # nxcu_result = nx.betweenness_centrality(G, backend="cugraph") + # + # but here it is being called directly since the NetworkX version that + # supports the "backend" kwarg may not be available in the testing env. + nxcu_result = nxcg.betweenness_centrality(G) + + nx_nodes, nxcu_nodes = nx_result.keys(), nxcu_result.keys() + assert nxcu_nodes == nx_nodes + for node_id in nx_nodes: + nx_bc, nxcu_bc = nx_result[node_id], nxcu_result[node_id] + assert math.isclose( + nx_bc, nxcu_bc, rel_tol=1e-6 + ), f"bc for {node_id=} exceeds tolerance: {nx_bc=}, {nxcu_bc=}" diff --git a/dependencies.yaml b/dependencies.yaml index e66b4c19a..dddfb027f 100644 --- a/dependencies.yaml +++ b/dependencies.yaml @@ -34,6 +34,14 @@ files: - cuda_version - py_version - test_notebook + test_python: + output: none + includes: + - cuda_version + - depends_on_cudf + - py_version + - test_python_common + - test_python_nx_cugraph py_build_nx_cugraph: output: pyproject pyproject_dir: . diff --git a/docs/nx-cugraph/source/sphinxext/github_link.py b/docs/nx-cugraph/source/sphinxext/github_link.py index c118c19cd..b9101a851 100644 --- a/docs/nx-cugraph/source/sphinxext/github_link.py +++ b/docs/nx-cugraph/source/sphinxext/github_link.py @@ -67,7 +67,6 @@ def _linkcode_resolve(domain, info, url_fmt, revision): ... revision='xxxx') 'http://hg.python.org/cpython/file/xxxx/Lib/tty/tty.py#L18' """ - if revision is None: return if domain != "py": diff --git a/notebooks/cugraph_benchmarks/nx_cugraph_benchmark.ipynb b/notebooks/cugraph_benchmarks/nx_cugraph_benchmark.ipynb index bc57947f2..1083ce128 100644 --- a/notebooks/cugraph_benchmarks/nx_cugraph_benchmark.ipynb +++ b/notebooks/cugraph_benchmarks/nx_cugraph_benchmark.ipynb @@ -68,10 +68,10 @@ "metadata": {}, "outputs": [], "source": [ - "try: \n", + "try:\n", " import nx_cugraph\n", "except ModuleNotFoundError:\n", - " os.system('conda install -c rapidsai -c conda-forge -c nvidia nx-cugraph')" + " os.system(\"conda install -c rapidsai -c conda-forge -c nvidia nx-cugraph\")" ] }, { diff --git a/nx_cugraph/__init__.py b/nx_cugraph/__init__.py index 4404e57f6..91132672f 100644 --- a/nx_cugraph/__init__.py +++ b/nx_cugraph/__init__.py @@ -15,7 +15,7 @@ from _nx_cugraph._version import __git_commit__, __version__ from _nx_cugraph import _check_networkx_version -_nxver: tuple[int, int] = _check_networkx_version() +_nxver: tuple[int, int] | tuple[int, int, int] = _check_networkx_version() from . import utils diff --git a/nx_cugraph/algorithms/bipartite/generators.py b/nx_cugraph/algorithms/bipartite/generators.py index 214970235..6f54383ba 100644 --- a/nx_cugraph/algorithms/bipartite/generators.py +++ b/nx_cugraph/algorithms/bipartite/generators.py @@ -49,7 +49,7 @@ def complete_bipartite_graph(n1, n2, create_using=None): nodes.extend(range(n2) if nodes2 is None else nodes2) if len(set(nodes)) != len(nodes): raise nx.NetworkXError("Inputs n1 and n2 must contain distinct nodes") - if _nxver <= (3, 3): + if _nxver < (3, 4): name = f"complete_bipartite_graph({orig_n1}, {orig_n2})" else: name = f"complete_bipartite_graph({n1}, {n2})" diff --git a/nx_cugraph/algorithms/community/louvain.py b/nx_cugraph/algorithms/community/louvain.py index 52c512c45..1d25a4300 100644 --- a/nx_cugraph/algorithms/community/louvain.py +++ b/nx_cugraph/algorithms/community/louvain.py @@ -27,7 +27,7 @@ __all__ = ["louvain_communities"] # max_level argument was added to NetworkX 3.3 -if _nxver <= (3, 2): +if _nxver < (3, 3): _max_level_param = { "max_level : int, optional": ( "Upper limit of the number of macro-iterations (max: 500)." diff --git a/nx_cugraph/algorithms/core.py b/nx_cugraph/algorithms/core.py index e69ee88a1..f152d0ad9 100644 --- a/nx_cugraph/algorithms/core.py +++ b/nx_cugraph/algorithms/core.py @@ -64,7 +64,7 @@ def k_truss(G, k): else: is_compat_graph = False if nxcg.number_of_selfloops(G) > 0: - if _nxver <= (3, 2): + if _nxver < (3, 3): exc_class = nx.NetworkXError else: exc_class = nx.NetworkXNotImplemented diff --git a/nx_cugraph/algorithms/link_analysis/hits_alg.py b/nx_cugraph/algorithms/link_analysis/hits_alg.py index cc59fd5eb..5de2aac6e 100644 --- a/nx_cugraph/algorithms/link_analysis/hits_alg.py +++ b/nx_cugraph/algorithms/link_analysis/hits_alg.py @@ -54,7 +54,7 @@ def hits( if nstart is not None: nstart = G._dict_to_nodearray(nstart, 0, dtype) if max_iter <= 0: - if _nxver <= (3, 2): + if _nxver < (3, 3): raise ValueError("`maxiter` must be a positive integer.") raise nx.PowerIterationFailedConvergence(max_iter) try: diff --git a/nx_cugraph/algorithms/shortest_paths/generic.py b/nx_cugraph/algorithms/shortest_paths/generic.py index ab3c72143..0f265095c 100644 --- a/nx_cugraph/algorithms/shortest_paths/generic.py +++ b/nx_cugraph/algorithms/shortest_paths/generic.py @@ -58,7 +58,7 @@ def shortest_path( paths = nxcg.all_pairs_dijkstra_path(G, weight=weight, dtype=dtype) else: # method == 'bellman-ford': paths = nxcg.all_pairs_bellman_ford_path(G, weight=weight, dtype=dtype) - if _nxver <= (3, 4): + if _nxver < (3, 5): paths = dict(paths) # To target elif method == "unweighted": @@ -130,7 +130,7 @@ def shortest_path_length( # To target elif method == "unweighted": lengths = nxcg.single_target_shortest_path_length(G, target) - if _nxver <= (3, 4): + if _nxver < (3, 5): lengths = dict(lengths) elif method == "dijkstra": lengths = nxcg.single_source_dijkstra_path_length( diff --git a/nx_cugraph/algorithms/shortest_paths/unweighted.py b/nx_cugraph/algorithms/shortest_paths/unweighted.py index e9c515632..a4a4474fa 100644 --- a/nx_cugraph/algorithms/shortest_paths/unweighted.py +++ b/nx_cugraph/algorithms/shortest_paths/unweighted.py @@ -44,7 +44,7 @@ def single_source_shortest_path_length(G, source, cutoff=None): def single_target_shortest_path_length(G, target, cutoff=None): G = _to_graph(G) rv = _bfs(G, target, cutoff, "Target", return_type="length") - if _nxver <= (3, 4): + if _nxver < (3, 5): return iter(rv.items()) return rv @@ -62,7 +62,7 @@ def bidirectional_shortest_path(G, source, target): # TODO PERF: do bidirectional traversal in core G = _to_graph(G) if source not in G or target not in G: - if _nxver <= (3, 3): + if _nxver < (3, 4): raise nx.NodeNotFound( f"Either source {source} or target {target} is not in G" ) diff --git a/nx_cugraph/algorithms/traversal/breadth_first_search.py b/nx_cugraph/algorithms/traversal/breadth_first_search.py index 72d0079cf..bd4432db5 100644 --- a/nx_cugraph/algorithms/traversal/breadth_first_search.py +++ b/nx_cugraph/algorithms/traversal/breadth_first_search.py @@ -58,7 +58,7 @@ def _bfs(G, source, *, depth_limit=None, reverse=False): return distances[mask], predecessors[mask], node_ids[mask] -if _nxver <= (3, 3): +if _nxver < (3, 4): @networkx_algorithm(is_incomplete=True, version_added="24.02", _plc="bfs") def generic_bfs_edges( diff --git a/nx_cugraph/convert_matrix.py b/nx_cugraph/convert_matrix.py index 549759028..096ddaf67 100644 --- a/nx_cugraph/convert_matrix.py +++ b/nx_cugraph/convert_matrix.py @@ -140,7 +140,7 @@ def from_pandas_edgelist( and ( # In nx <= 3.3, `edge_key` was ignored if `edge_attr` is None edge_attr is not None - or _nxver > (3, 3) + or _nxver >= (3, 4) ) ): try: diff --git a/nx_cugraph/interface.py b/nx_cugraph/interface.py index 1a3d08409..ff02de4cc 100644 --- a/nx_cugraph/interface.py +++ b/nx_cugraph/interface.py @@ -228,7 +228,7 @@ def key(testpath): } ) - if _nxver <= (3, 2): + if _nxver < (3, 3): xfail.update( { # NetworkX versions prior to 3.2.1 have tests written to @@ -265,7 +265,7 @@ def key(testpath): } ) - if _nxver <= (3, 1): + if _nxver < (3, 2): # MAINT: networkx 3.0, 3.1 # NetworkX 3.2 added the ability to "fallback to nx" if backend algorithms # raise NotImplementedError or `can_run` returns False. The tests below @@ -423,6 +423,9 @@ def key(testpath): } ) + if _nxver == (3, 4, 2): + xfail[key("test_pylab.py:test_return_types")] = "Ephemeral NetworkX bug" + too_slow = "Too slow to run" skip = { key("test_tree_isomorphism.py:test_positive"): too_slow, diff --git a/nx_cugraph/utils/decorators.py b/nx_cugraph/utils/decorators.py index 16486996b..15cb010e9 100644 --- a/nx_cugraph/utils/decorators.py +++ b/nx_cugraph/utils/decorators.py @@ -80,7 +80,7 @@ def __new__( _plc=_plc, ) instance = object.__new__(cls) - if nodes_or_number is not None and _nxver > (3, 2): + if nodes_or_number is not None and _nxver >= (3, 3): func = nx.utils.decorators.nodes_or_number(nodes_or_number)(func) # update_wrapper sets __wrapped__, which will be used for the signature update_wrapper(instance, func) @@ -121,7 +121,7 @@ def __new__( # Set methods so they are in __dict__ instance._can_run = instance._can_run instance._should_run = instance._should_run - if nodes_or_number is not None and _nxver <= (3, 2): + if nodes_or_number is not None and _nxver < (3, 3): instance = nx.utils.decorators.nodes_or_number(nodes_or_number)(instance) return instance diff --git a/pyproject.toml b/pyproject.toml index d5742dc4f..91a211461 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -85,7 +85,7 @@ include = [ [tool.rapids-build-backend] build-backend = "setuptools.build_meta" commit-files = ["_nx_cugraph/GIT_COMMIT"] -dependencies-file = "../../dependencies.yaml" +dependencies-file = "dependencies.yaml" matrix-entry = "cuda_suffixed=true" [tool.black]