diff --git a/.github/workflows/pr.yaml b/.github/workflows/pr.yaml index 7753f52d799..7f0b95e3573 100644 --- a/.github/workflows/pr.yaml +++ b/.github/workflows/pr.yaml @@ -162,7 +162,7 @@ jobs: with: build_type: pull-request script: ci/test_wheel_cugraph-pyg.sh - matrix_filter: map(select(.ARCH == "amd64" and .CUDA_VER == "11.8.0")) + matrix_filter: map(select(.ARCH == "amd64")) wheel-build-cugraph-equivariant: secrets: inherit uses: rapidsai/shared-workflows/.github/workflows/wheels-build.yaml@branch-24.04 diff --git a/.github/workflows/test.yaml b/.github/workflows/test.yaml index f6a04fcc776..32fb2d62b29 100644 --- a/.github/workflows/test.yaml +++ b/.github/workflows/test.yaml @@ -76,7 +76,7 @@ jobs: date: ${{ inputs.date }} sha: ${{ inputs.sha }} script: ci/test_wheel_cugraph-pyg.sh - matrix_filter: map(select(.ARCH == "amd64" and .CUDA_VER == "11.8.0")) + matrix_filter: map(select(.ARCH == "amd64")) wheel-tests-cugraph-equivariant: secrets: inherit uses: rapidsai/shared-workflows/.github/workflows/wheels-test.yaml@branch-24.04 diff --git a/ci/test_python.sh b/ci/test_python.sh index 9fa1de2e5e7..e05160239ab 100755 --- a/ci/test_python.sh +++ b/ci/test_python.sh @@ -166,7 +166,7 @@ if [[ "${RAPIDS_CUDA_VERSION}" == "11.8.0" ]]; then pylibcugraphops \ cugraph \ cugraph-dgl \ - 'dgl>=1.1.0.cu*' \ + 'dgl>=1.1.0.cu*,<=2.0.0.cu*' \ 'pytorch>=2.0' \ 'pytorch-cuda>=11.8' diff --git a/ci/test_wheel_cugraph-dgl.sh b/ci/test_wheel_cugraph-dgl.sh index 9ecaa75a86b..367b169bd13 100755 --- a/ci/test_wheel_cugraph-dgl.sh +++ b/ci/test_wheel_cugraph-dgl.sh @@ -34,6 +34,6 @@ DGL_URL="https://data.dgl.ai/wheels/cu${PYTORCH_CUDA_VER}/repo.html" rapids-logger "Installing PyTorch and DGL" rapids-retry python -m pip install torch --index-url ${PYTORCH_URL} -rapids-retry python -m pip install dgl --find-links ${DGL_URL} +rapids-retry python -m pip install dgl==2.0.0 --find-links ${DGL_URL} python -m pytest python/cugraph-dgl/tests diff --git a/python/cugraph/cugraph/structure/hypergraph.py b/python/cugraph/cugraph/structure/hypergraph.py index 4e9975e6b8a..4add74d6061 100644 --- a/python/cugraph/cugraph/structure/hypergraph.py +++ b/python/cugraph/cugraph/structure/hypergraph.py @@ -1,4 +1,4 @@ -# Copyright (c) 2020-2023, NVIDIA CORPORATION. +# Copyright (c) 2020-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 @@ -581,7 +581,7 @@ def _create_direct_edges( def _str_scalar_to_category(size, val): return cudf.core.column.build_categorical_column( categories=cudf.core.column.as_column([val], dtype="str"), - codes=cudf.core.column.column.full(size, 0, dtype=np.int32), + codes=cudf.core.column.as_column(0, length=size, dtype=np.int32), mask=None, size=size, offset=0, diff --git a/python/cugraph/cugraph/tests/data_store/test_property_graph.py b/python/cugraph/cugraph/tests/data_store/test_property_graph.py index a33d4f753db..da5608e0193 100644 --- a/python/cugraph/cugraph/tests/data_store/test_property_graph.py +++ b/python/cugraph/cugraph/tests/data_store/test_property_graph.py @@ -1,4 +1,4 @@ -# Copyright (c) 2021-2023, NVIDIA CORPORATION. +# Copyright (c) 2021-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 @@ -1424,6 +1424,10 @@ def test_extract_subgraph_graph_without_vert_props(as_pg_first): actual_edgelist = G.edgelist.edgelist_df assert G.is_directed() + expected_edgelist = expected_edgelist.sort_values( + by=["src", "dst"], ignore_index=True + ) + actual_edgelist = actual_edgelist.sort_values(by=["src", "dst"], ignore_index=True) assert_frame_equal(expected_edgelist, actual_edgelist, check_like=True) diff --git a/python/nx-cugraph/_nx_cugraph/__init__.py b/python/nx-cugraph/_nx_cugraph/__init__.py index c6c43110ac6..b2f13d25ff3 100644 --- a/python/nx-cugraph/_nx_cugraph/__init__.py +++ b/python/nx-cugraph/_nx_cugraph/__init__.py @@ -164,6 +164,7 @@ }, "louvain_communities": { "dtype : dtype or None, optional": "The data type (np.float32, np.float64, or None) to use for the edge weights in the algorithm. If None, then dtype is determined by the edge values.", + "max_level : int, optional": "Upper limit of the number of macro-iterations (max: 500).", }, "pagerank": { "dtype : dtype or None, optional": "The data type (np.float32, np.float64, or None) to use for the edge weights in the algorithm. If None, then dtype is determined by the edge values.", diff --git a/python/nx-cugraph/nx_cugraph/algorithms/community/louvain.py b/python/nx-cugraph/nx_cugraph/algorithms/community/louvain.py index f7638f47aad..ea1318060e0 100644 --- a/python/nx-cugraph/nx_cugraph/algorithms/community/louvain.py +++ b/python/nx-cugraph/nx_cugraph/algorithms/community/louvain.py @@ -37,18 +37,23 @@ _max_level_param = {} -@not_implemented_for("directed") -@networkx_algorithm( - extra_params={ - **_max_level_param, - **_dtype_param, - }, - is_incomplete=True, # seed not supported; self-loops not supported - is_different=True, # RNG different - version_added="23.10", - _plc="louvain", -) -def louvain_communities( +def _louvain_communities_nx32( + G, + weight="weight", + resolution=1, + threshold=0.0000001, + seed=None, + *, + max_level=None, + dtype=None, +): + """`seed` parameter is currently ignored, and self-loops are not yet supported.""" + return _louvain_communities( + G, weight, resolution, threshold, max_level, seed, dtype=dtype + ) + + +def _louvain_communities( G, weight="weight", resolution=1, @@ -85,16 +90,54 @@ def louvain_communities( return [set(G._nodearray_to_list(ids)) for ids in groups.values()] -@louvain_communities._can_run -def _( - G, - weight="weight", - resolution=1, - threshold=0.0000001, - max_level=None, - seed=None, - *, - dtype=None, -): - # NetworkX allows both directed and undirected, but cugraph only allows undirected. - return not G.is_directed() +_louvain_decorator = networkx_algorithm( + extra_params={ + **_max_level_param, + **_dtype_param, + }, + is_incomplete=True, # seed not supported; self-loops not supported + is_different=True, # RNG different + version_added="23.10", + _plc="louvain", + name="louvain_communities", +) + +if _max_level_param: # networkx <= 3.2 + _louvain_communities_nx32.__name__ = "louvain_communities" + louvain_communities = not_implemented_for("directed")( + _louvain_decorator(_louvain_communities_nx32) + ) + + @louvain_communities._can_run + def _( + G, + weight="weight", + resolution=1, + threshold=0.0000001, + seed=None, + *, + max_level=None, + dtype=None, + ): + # NetworkX allows both directed and undirected, but cugraph only undirected. + return not G.is_directed() + +else: # networkx >= 3.3 + _louvain_communities.__name__ = "louvain_communities" + louvain_communities = not_implemented_for("directed")( + _louvain_decorator(_louvain_communities) + ) + + @louvain_communities._can_run + def _( + G, + weight="weight", + resolution=1, + threshold=0.0000001, + max_level=None, + seed=None, + *, + dtype=None, + ): + # NetworkX allows both directed and undirected, but cugraph only undirected. + return not G.is_directed() diff --git a/python/nx-cugraph/nx_cugraph/tests/test_match_api.py b/python/nx-cugraph/nx_cugraph/tests/test_match_api.py index 595f7819ac1..bd6f20e84f0 100644 --- a/python/nx-cugraph/nx_cugraph/tests/test_match_api.py +++ b/python/nx-cugraph/nx_cugraph/tests/test_match_api.py @@ -44,11 +44,6 @@ def test_match_signature_and_names(): else: orig_func = dispatchable_func.orig_func - if nxver.major == 3 and nxver.minor <= 2 and name == "louvain_communities": - # The signature of louvain_communities changed in NetworkX 3.3, and - # we updated to match, so we skip this check in older versions. - continue - # Matching signatures? orig_sig = inspect.signature(orig_func) func_sig = inspect.signature(func)