diff --git a/.devcontainer/Dockerfile b/.devcontainer/Dockerfile
index 190003dd7af..9ff575865e3 100644
--- a/.devcontainer/Dockerfile
+++ b/.devcontainer/Dockerfile
@@ -31,7 +31,7 @@ ENV PYTHONDONTWRITEBYTECODE="1"
ENV SCCACHE_REGION="us-east-2"
ENV SCCACHE_BUCKET="rapids-sccache-devs"
-ENV VAULT_HOST="https://vault.ops.k8s.rapids.ai"
+ENV AWS_ROLE_ARN="arn:aws:iam::279114543810:role/nv-gha-token-sccache-devs"
ENV HISTFILE="/home/coder/.cache/._bash_history"
# cugraph_pyg's setup.py needs this defined when building in a conda env
diff --git a/.github/workflows/build.yaml b/.github/workflows/build.yaml
index b272fb43e35..9a055d1dc51 100644
--- a/.github/workflows/build.yaml
+++ b/.github/workflows/build.yaml
@@ -113,66 +113,6 @@ jobs:
sha: ${{ inputs.sha }}
date: ${{ inputs.date }}
package-name: cugraph
- wheel-build-nx-cugraph:
- needs: wheel-publish-pylibcugraph
- secrets: inherit
- uses: rapidsai/shared-workflows/.github/workflows/wheels-build.yaml@branch-24.12
- with:
- build_type: ${{ inputs.build_type || 'branch' }}
- branch: ${{ inputs.branch }}
- sha: ${{ inputs.sha }}
- date: ${{ inputs.date }}
- script: ci/build_wheel_nx-cugraph.sh
- wheel-publish-nx-cugraph:
- needs: wheel-build-nx-cugraph
- secrets: inherit
- uses: rapidsai/shared-workflows/.github/workflows/wheels-publish.yaml@branch-24.12
- with:
- build_type: ${{ inputs.build_type || 'branch' }}
- branch: ${{ inputs.branch }}
- sha: ${{ inputs.sha }}
- date: ${{ inputs.date }}
- package-name: nx-cugraph
- wheel-build-cugraph-dgl:
- needs: wheel-publish-cugraph
- secrets: inherit
- uses: rapidsai/shared-workflows/.github/workflows/wheels-build.yaml@branch-24.12
- with:
- build_type: ${{ inputs.build_type || 'branch' }}
- branch: ${{ inputs.branch }}
- sha: ${{ inputs.sha }}
- date: ${{ inputs.date }}
- script: ci/build_wheel_cugraph-dgl.sh
- wheel-publish-cugraph-dgl:
- needs: wheel-build-cugraph-dgl
- secrets: inherit
- uses: rapidsai/shared-workflows/.github/workflows/wheels-publish.yaml@branch-24.12
- with:
- build_type: ${{ inputs.build_type || 'branch' }}
- branch: ${{ inputs.branch }}
- sha: ${{ inputs.sha }}
- date: ${{ inputs.date }}
- package-name: cugraph-dgl
- wheel-build-cugraph-pyg:
- needs: wheel-publish-cugraph
- secrets: inherit
- uses: rapidsai/shared-workflows/.github/workflows/wheels-build.yaml@branch-24.12
- with:
- build_type: ${{ inputs.build_type || 'branch' }}
- branch: ${{ inputs.branch }}
- sha: ${{ inputs.sha }}
- date: ${{ inputs.date }}
- script: ci/build_wheel_cugraph-pyg.sh
- wheel-publish-cugraph-pyg:
- needs: wheel-build-cugraph-pyg
- secrets: inherit
- uses: rapidsai/shared-workflows/.github/workflows/wheels-publish.yaml@branch-24.12
- with:
- build_type: ${{ inputs.build_type || 'branch' }}
- branch: ${{ inputs.branch }}
- sha: ${{ inputs.sha }}
- date: ${{ inputs.date }}
- package-name: cugraph-pyg
wheel-build-cugraph-equivariant:
secrets: inherit
uses: rapidsai/shared-workflows/.github/workflows/wheels-build.yaml@branch-24.12
diff --git a/.github/workflows/pr.yaml b/.github/workflows/pr.yaml
index b0a1308237e..bac56fec9f5 100644
--- a/.github/workflows/pr.yaml
+++ b/.github/workflows/pr.yaml
@@ -25,12 +25,6 @@ jobs:
- wheel-tests-pylibcugraph
- wheel-build-cugraph
- wheel-tests-cugraph
- - wheel-build-nx-cugraph
- - wheel-tests-nx-cugraph
- - wheel-build-cugraph-dgl
- - wheel-tests-cugraph-dgl
- - wheel-build-cugraph-pyg
- - wheel-tests-cugraph-pyg
- wheel-build-cugraph-equivariant
- wheel-tests-cugraph-equivariant
- devcontainer
@@ -55,16 +49,12 @@ jobs:
- '!notebooks/**'
- '!python/**'
- '!readme_pages/**'
- # TODO: Remove this before merging
- - '!.github/**'
test_notebooks:
- '**'
- '!.devcontainers/**'
- '!CONTRIBUTING.md'
- '!README.md'
- '!docs/**'
- # TODO: Remove this before merging
- - '!.github/**'
test_python:
- '**'
- '!.devcontainers/**'
@@ -73,8 +63,6 @@ jobs:
- '!docs/**'
- '!img/**'
- '!notebooks/**'
- # TODO: Remove this before merging
- - '!.github/**'
checks:
secrets: inherit
uses: rapidsai/shared-workflows/.github/workflows/checks.yaml@branch-24.12
@@ -173,53 +161,6 @@ jobs:
with:
build_type: pull-request
script: ci/test_wheel_cugraph.sh
- wheel-build-nx-cugraph:
- needs: wheel-tests-pylibcugraph
- secrets: inherit
- uses: rapidsai/shared-workflows/.github/workflows/wheels-build.yaml@branch-24.12
- with:
- build_type: pull-request
- script: ci/build_wheel_nx-cugraph.sh
- 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
- wheel-build-cugraph-dgl:
- needs: wheel-tests-cugraph
- secrets: inherit
- uses: rapidsai/shared-workflows/.github/workflows/wheels-build.yaml@branch-24.12
- with:
- build_type: pull-request
- script: ci/build_wheel_cugraph-dgl.sh
- wheel-tests-cugraph-dgl:
- needs: [wheel-build-cugraph-dgl, 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_cugraph-dgl.sh
- matrix_filter: map(select(.ARCH == "amd64"))
- wheel-build-cugraph-pyg:
- needs: wheel-tests-cugraph
- secrets: inherit
- uses: rapidsai/shared-workflows/.github/workflows/wheels-build.yaml@branch-24.12
- with:
- build_type: pull-request
- script: ci/build_wheel_cugraph-pyg.sh
- wheel-tests-cugraph-pyg:
- needs: [wheel-build-cugraph-pyg, 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_cugraph-pyg.sh
- matrix_filter: map(select(.ARCH == "amd64"))
wheel-build-cugraph-equivariant:
secrets: inherit
uses: rapidsai/shared-workflows/.github/workflows/wheels-build.yaml@branch-24.12
diff --git a/.github/workflows/test.yaml b/.github/workflows/test.yaml
index 5fbdd276bd6..245ac018cec 100644
--- a/.github/workflows/test.yaml
+++ b/.github/workflows/test.yaml
@@ -58,35 +58,6 @@ jobs:
date: ${{ inputs.date }}
sha: ${{ inputs.sha }}
script: ci/test_wheel_cugraph.sh
- wheel-tests-nx-cugraph:
- secrets: inherit
- uses: rapidsai/shared-workflows/.github/workflows/wheels-test.yaml@branch-24.12
- with:
- build_type: nightly
- branch: ${{ inputs.branch }}
- date: ${{ inputs.date }}
- sha: ${{ inputs.sha }}
- script: ci/test_wheel_nx-cugraph.sh
- wheel-tests-cugraph-dgl:
- secrets: inherit
- uses: rapidsai/shared-workflows/.github/workflows/wheels-test.yaml@branch-24.12
- with:
- build_type: nightly
- branch: ${{ inputs.branch }}
- date: ${{ inputs.date }}
- sha: ${{ inputs.sha }}
- script: ci/test_wheel_cugraph-dgl.sh
- matrix_filter: map(select(.ARCH == "amd64"))
- wheel-tests-cugraph-pyg:
- secrets: inherit
- uses: rapidsai/shared-workflows/.github/workflows/wheels-test.yaml@branch-24.12
- with:
- build_type: nightly
- branch: ${{ inputs.branch }}
- date: ${{ inputs.date }}
- sha: ${{ inputs.sha }}
- script: ci/test_wheel_cugraph-pyg.sh
- matrix_filter: map(select(.ARCH == "amd64"))
wheel-tests-cugraph-equivariant:
secrets: inherit
uses: rapidsai/shared-workflows/.github/workflows/wheels-test.yaml@branch-24.12
diff --git a/.gitignore b/.gitignore
index 2fea1022910..9480c2618bf 100644
--- a/.gitignore
+++ b/.gitignore
@@ -78,9 +78,6 @@ datasets/*
!datasets/karate-disjoint.csv
!datasets/netscience.csv
-# nx-cugraph side effects
-python/nx-cugraph/objects.inv
-
.pydevproject
# Jupyter Notebooks
diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml
index 3687562b48e..4bb037b5fda 100644
--- a/.pre-commit-config.yaml
+++ b/.pre-commit-config.yaml
@@ -19,7 +19,6 @@ repos:
language_version: python3
args: [--target-version=py310]
files: ^(python/.*|benchmarks/.*)$
- exclude: ^python/nx-cugraph/
- repo: https://github.com/PyCQA/flake8
rev: 7.1.1
hooks:
@@ -55,27 +54,7 @@ repos:
setup[.]cfg$
- id: verify-alpha-spec
- repo: https://github.com/rapidsai/dependency-file-generator
- rev: v1.13.11
+ rev: v1.16.0
hooks:
- id: rapids-dependency-file-generator
args: ["--clean"]
- - repo: local
- hooks:
- - id: nx-cugraph-meta-data-update
- name: nx-cugraph meta-data updater
- entry: bash -c "PYTHONPATH=./python/nx-cugraph python ./python/nx-cugraph/_nx_cugraph/__init__.py"
- files: ^python/nx-cugraph/
- types: [python]
- language: python
- pass_filenames: false
- additional_dependencies: ["networkx>=3.4"]
- - repo: local
- hooks:
- - id: nx-cugraph-readme-update
- name: nx-cugraph README updater
- entry: bash -c "PYTHONPATH=./python/nx-cugraph python ./python/nx-cugraph/scripts/update_readme.py ./python/nx-cugraph/README.md"
- files: ^python/nx-cugraph/
- types_or: [python, markdown]
- language: python
- pass_filenames: false
- additional_dependencies: ["networkx>=3.4"]
diff --git a/README.md b/README.md
index 8026e4feb64..e41caec17b0 100644
--- a/README.md
+++ b/README.md
@@ -37,7 +37,7 @@
-----
## News
-___NEW!___ _[nx-cugraph](./python/nx-cugraph/README.md)_, a NetworkX backend that provides GPU acceleration to NetworkX with zero code change.
+___NEW!___ _[nx-cugraph](https://rapids.ai/nx-cugraph/)_, a NetworkX backend that provides GPU acceleration to NetworkX with zero code change.
```
> pip install nx-cugraph-cu11 --extra-index-url https://pypi.nvidia.com
> export NETWORKX_AUTOMATIC_BACKENDS=cugraph
@@ -62,7 +62,7 @@ That's it. NetworkX now leverages cuGraph for accelerated graph algorithms.
- [External Data Types](./readme_pages/data_types.md)
- [pylibcugraph](./readme_pages/pylibcugraph.md)
- [libcugraph (C/C++/CUDA)](./readme_pages/libcugraph.md)
- - [nx-cugraph](./python/nx-cugraph/README.md)
+ - [nx-cugraph](https://rapids.ai/nx-cugraph/)
- [cugraph-service](./readme_pages/cugraph_service.md)
- [cugraph-dgl](./readme_pages/cugraph_dgl.md)
- [cugraph-ops](./readme_pages/cugraph_ops.md)
@@ -127,7 +127,7 @@ df_page.sort_values('pagerank', ascending=False).head(10)
* ArangoDB - a free and open-source native multi-model database system - https://www.arangodb.com/
* CuPy - "NumPy/SciPy-compatible Array Library for GPU-accelerated Computing with Python" - https://cupy.dev/
* Memgraph - In-memory Graph database - https://memgraph.com/
-* NetworkX (via [nx-cugraph](./python/nx-cugraph/README.md) backend) - an extremely popular, free and open-source package for the creation, manipulation, and study of the structure, dynamics, and functions of complex networks - https://networkx.org/
+* NetworkX (via [nx-cugraph](https://rapids.ai/nx-cugraph/) backend) - an extremely popular, free and open-source package for the creation, manipulation, and study of the structure, dynamics, and functions of complex networks - https://networkx.org/
* PyGraphistry - free and open-source GPU graph ETL, AI, and visualization, including native RAPIDS & cuGraph support - http://github.com/graphistry/pygraphistry
* ScanPy - a scalable toolkit for analyzing single-cell gene expression data - https://scanpy.readthedocs.io/en/stable/
diff --git a/benchmarks/nx-cugraph/pytest-based/README.md b/benchmarks/nx-cugraph/pytest-based/README.md
deleted file mode 100644
index 781550fa560..00000000000
--- a/benchmarks/nx-cugraph/pytest-based/README.md
+++ /dev/null
@@ -1,54 +0,0 @@
-## `nx-cugraph` Benchmarks
-
-### Overview
-
-This directory contains a set of scripts designed to benchmark NetworkX with the `nx-cugraph` backend and deliver a report that summarizes the speed-up and runtime deltas over default NetworkX.
-
-Our current benchmarks provide the following datasets:
-
-| Dataset | Nodes | Edges | Directed |
-| -------- | ------- | ------- | ------- |
-| netscience | 1,461 | 5,484 | Yes |
-| email-Eu-core | 1,005 | 25,571 | Yes |
-| cit-Patents | 3,774,768 | 16,518,948 | Yes |
-| hollywood | 1,139,905 | 57,515,616 | No |
-| soc-LiveJournal1 | 4,847,571 | 68,993,773 | Yes |
-
-
-
-### Scripts
-
-#### 1. `run-main-benchmarks.sh`
-This script allows users to run a small set of commonly-used algorithms across multiple datasets and backends. All results are stored inside a sub-directory (`logs/`) and output files are named based on the combination of parameters for that benchmark.
-
-NOTE: If running with all algorithms and datasets using NetworkX without an accelerated backend, this script may take a few hours to finish running.
-
-**Usage:**
- - Run with `--cpu-only`:
- ```bash
- ./run-main-benchmarks.sh --cpu-only
- ```
- - Run with `--gpu-only`:
- ```bash
- ./run-main-benchmarks.sh --gpu-only
- ```
- - Run without any arguments (all backends):
- ```bash
- ./run-main-benchmarks.sh
- ```
-
-#### 2. `get_graph_bench_dataset.py`
-This script downloads the specified dataset using `cugraph.datasets`.
-
-**Usage:**
- ```bash
- python get_graph_bench_dataset.py [dataset]
- ```
-
-#### 3. `create_results_summary_page.py`
-This script is designed to be run after `run-gap-benchmarks.sh` in order to generate an HTML page displaying a results table comparing default NetworkX to nx-cugraph. The script also provides information about the current system, so it should be run on the machine on which benchmarks were run.
-
-**Usage:**
- ```bash
- python create_results_summary_page.py > report.html
- ```
diff --git a/benchmarks/nx-cugraph/pytest-based/bench_algos.py b/benchmarks/nx-cugraph/pytest-based/bench_algos.py
deleted file mode 100644
index f88d93c3f17..00000000000
--- a/benchmarks/nx-cugraph/pytest-based/bench_algos.py
+++ /dev/null
@@ -1,962 +0,0 @@
-# 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 random
-
-import networkx as nx
-import pandas as pd
-import pytest
-from cugraph import datasets
-import nx_cugraph as nxcg
-
-# Attempt to import the NetworkX dispatching module, which is only needed when
-# testing with NX <3.2 in order to dynamically switch backends. NX >=3.2 allows
-# the backend to be specified directly in the API call.
-try:
- from networkx.classes import backends # NX <3.2
-except ImportError:
- backends = None
-
-
-################################################################################
-# Fixtures and params
-
-# See https://pytest-benchmark.readthedocs.io/en/latest/glossary.html for how
-# these variables are used.
-rounds = 1
-iterations = 1
-warmup_rounds = 1
-
-dataset_param_values = [
- # name: karate, nodes: 34, edges: 156
- pytest.param(datasets.karate, marks=[pytest.mark.small, pytest.mark.undirected]),
- # name: netscience, nodes: 1461, edges: 5484
- pytest.param(datasets.netscience, marks=[pytest.mark.small, pytest.mark.directed]),
- # name: email-Eu-core, nodes: 1005, edges: 25571
- pytest.param(
- datasets.email_Eu_core, marks=[pytest.mark.small, pytest.mark.directed]
- ),
- # name: cit-Patents, nodes: 3774768, edges: 16518948
- pytest.param(
- datasets.cit_patents, marks=[pytest.mark.medium, pytest.mark.directed]
- ),
- # name: hollywood, nodes: 1139905, edges: 57515616
- pytest.param(
- datasets.hollywood, marks=[pytest.mark.medium, pytest.mark.undirected]
- ),
- # name: soc-LiveJournal1, nodes: 4847571, edges: 68993773
- pytest.param(
- datasets.soc_livejournal, marks=[pytest.mark.medium, pytest.mark.directed]
- ),
- # name: europe_osm, nodes: 50912018, edges: 54054660
- pytest.param(
- datasets.europe_osm, marks=[pytest.mark.large, pytest.mark.undirected]
- ),
-]
-
-backend_param_values = ["cugraph", "cugraph-preconverted", None]
-
-
-def setup_module(module):
- """
- Trivial conversion call to force various one-time CUDA initialization
- operations to happen outside of benchmarks.
- """
- G = nx.karate_club_graph()
- nxcg.from_networkx(G)
-
-
-# Test IDs are generated using the lambda assigned to the ids arg to provide an
-# 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)}"
-)
-def graph_obj(request):
- """
- Returns a NX Graph or DiGraph obj from the dataset instance parameter.
- """
- dataset = request.param
- return nx_graph_from_dataset(dataset)
-
-
-@pytest.fixture(
- scope="module",
- params=backend_param_values,
- ids=lambda backend: f"backend={backend}",
-)
-def backend(request):
- """
- Returns the backend name to use. This is done as a fixture for consistency
- and simplicity when creating benchmarks (no need to mark the benchmark as
- parametrized).
- """
- return request.param
-
-
-################################################################################
-# Helpers
-def nx_graph_from_dataset(dataset_obj):
- """
- Read the dataset specified by the dataset_obj and create and return a
- nx.Graph or nx.DiGraph instance based on the dataset is_directed metadata.
- """
- create_using = nx.DiGraph if dataset_obj.metadata["is_directed"] else nx.Graph
- names = dataset_obj.metadata["col_names"]
- dtypes = dataset_obj.metadata["col_types"]
- if isinstance(dataset_obj.metadata["header"], int):
- header = dataset_obj.metadata["header"]
- else:
- header = None
-
- pandas_edgelist = pd.read_csv(
- dataset_obj.get_path(),
- delimiter=dataset_obj.metadata["delim"],
- names=names,
- dtype=dict(zip(names, dtypes)),
- header=header,
- )
- G = nx.from_pandas_edgelist(
- pandas_edgelist, source=names[0], target=names[1], create_using=create_using
- )
- return G
-
-
-def get_legacy_backend_wrapper(backend_name):
- """
- Returns a callable that wraps an algo function with either the default
- dispatcher (which dispatches based on input graph type), or the "testing"
- dispatcher (which autoconverts and unconditionally dispatches).
- This is only supported for NetworkX <3.2
- """
- backends.plugin_name = "cugraph"
- orig_dispatch = backends._dispatch
- testing_dispatch = backends.test_override_dispatch
-
- if backend_name == "cugraph":
- dispatch = testing_dispatch
- else:
- dispatch = orig_dispatch
-
- def wrap_callable_for_dispatch(func, exhaust_returned_iterator=False):
- # Networkx <3.2 registers functions when the dispatch decorator is
- # applied (called) and errors if re-registered, so clear bookkeeping to
- # allow it to be called repeatedly.
- backends._registered_algorithms = {}
- actual_func = dispatch(func) # returns the func the dispatcher picks
-
- def wrapper(*args, **kwargs):
- retval = actual_func(*args, **kwargs)
- if exhaust_returned_iterator:
- retval = list(retval)
- return retval
-
- return wrapper
-
- return wrap_callable_for_dispatch
-
-
-def get_backend_wrapper(backend_name):
- """
- Returns a callable that wraps an algo function in order to set the
- "backend" kwarg on it.
- This is only supported for NetworkX >= 3.2
- """
-
- def wrap_callable_for_dispatch(func, exhaust_returned_iterator=False):
- def wrapper(*args, **kwargs):
- kwargs["backend"] = backend_name
- retval = func(*args, **kwargs)
- if exhaust_returned_iterator:
- retval = list(retval)
- return retval
-
- return wrapper
-
- return wrap_callable_for_dispatch
-
-
-@pytest.fixture(
- scope="module",
- params=backend_param_values,
- ids=lambda backend: f"backend={backend}",
-)
-def backend_wrapper(request):
- """
- Returns a callable that takes a function algo and wraps it in another
- function that calls the algo using the appropriate backend.
-
- For example: if the backend to test is "cugraph", this will return a
- function that calls nx.pagerank(..., backend='cugraph')
- """
- backend_name = request.param
- actual_backend_name = backend_name
-
- # Special case: cugraph-preconverted may be specified as a backend but this
- # name is reserved to indicate a cugraph backend is to be used with a
- # preconverted graph obj (rather than having the backend do the
- # conversion).
- if backend_name == "cugraph-preconverted":
- actual_backend_name = "cugraph"
-
- # NX <3.2 does not support the backends= kwarg, so the backend must be
- # enabled differently
- if backends is not None:
- wrapper = get_legacy_backend_wrapper(actual_backend_name)
- else:
- wrapper = get_backend_wrapper(actual_backend_name)
-
- wrapper.backend_name = backend_name
- return wrapper
-
-
-def get_graph_obj_for_benchmark(graph_obj, backend_wrapper):
- """
- Given a Graph object and a backend name, return a converted Graph or the
- original Graph object based on the backend to use.
-
- This is needed because some backend names are actually used as descriptions
- for combinations of backends and converted/non-converted graphs. For
- example, a benchmark may specify the "cugraph-preconverted" backend, which
- is not an installed backend but instead refers to the "cugraph" backend
- passed a NX Graph that has been converted to a nx-cugraph Graph object.
- """
- G = graph_obj
- if backend_wrapper.backend_name == "cugraph-preconverted":
- G = nxcg.from_networkx(G, preserve_all_attrs=True)
- return G
-
-
-def get_highest_degree_node(graph_obj):
- degrees = graph_obj.degree() # list of tuples of (node, degree)
- return max(degrees, key=lambda t: t[1])[0]
-
-
-def build_personalization_dict(pagerank_dict):
- """
- Returns a dictionary that can be used as the personalization value for a
- call to nx.pagerank(). The pagerank_dict passed in is used as the initial
- source of values for each node, and this function simply treats the list of
- dict values as two halves (halves A and B) and swaps them so (most if not
- all) nodes/keys are assigned a different value from the dictionary.
- """
- num_half = len(pagerank_dict) // 2
- A_half_items = list(pagerank_dict.items())[:num_half]
- B_half_items = list(pagerank_dict.items())[num_half:]
-
- # Support an odd number of items by initializing with B_half_items, which
- # will always be one bigger if the number of items is odd. This will leave
- # the one remainder (in the case of an odd number) unchanged.
- pers_dict = dict(B_half_items)
- pers_dict.update({A_half_items[i][0]: B_half_items[i][1] for i in range(num_half)})
- pers_dict.update({B_half_items[i][0]: A_half_items[i][1] for i in range(num_half)})
-
- return pers_dict
-
-
-################################################################################
-# Benchmarks
-def bench_from_networkx(benchmark, graph_obj):
- benchmark(nxcg.from_networkx, graph_obj)
-
-
-# normalized_param_values = [True, False]
-normalized_param_values = [True]
-k_param_values = [10, 100, 1000]
-
-
-@pytest.mark.parametrize(
- "normalized", normalized_param_values, ids=lambda norm: f"{norm=}"
-)
-@pytest.mark.parametrize("k", k_param_values, ids=lambda k: f"{k=}")
-def bench_betweenness_centrality(benchmark, graph_obj, backend_wrapper, normalized, k):
- G = get_graph_obj_for_benchmark(graph_obj, backend_wrapper)
-
- if k > G.number_of_nodes():
- pytest.skip(reason=f"{k=} > {G.number_of_nodes()=}")
-
- result = benchmark.pedantic(
- target=backend_wrapper(nx.betweenness_centrality),
- args=(G,),
- kwargs=dict(
- weight=None,
- normalized=normalized,
- k=k,
- ),
- rounds=rounds,
- iterations=iterations,
- warmup_rounds=warmup_rounds,
- )
- assert type(result) is dict
-
-
-@pytest.mark.parametrize(
- "normalized", normalized_param_values, ids=lambda norm: f"{norm=}"
-)
-@pytest.mark.parametrize("k", k_param_values, ids=lambda k: f"{k=}")
-def bench_edge_betweenness_centrality(
- benchmark, graph_obj, backend_wrapper, normalized, k
-):
- G = get_graph_obj_for_benchmark(graph_obj, backend_wrapper)
-
- if k > G.number_of_nodes():
- pytest.skip(reason=f"{k=} > {G.number_of_nodes()=}")
-
- result = benchmark.pedantic(
- target=backend_wrapper(nx.edge_betweenness_centrality),
- args=(G,),
- kwargs=dict(
- weight=None,
- normalized=normalized,
- k=k,
- ),
- rounds=rounds,
- iterations=iterations,
- warmup_rounds=warmup_rounds,
- )
- assert type(result) is dict
-
-
-def bench_louvain_communities(benchmark, graph_obj, backend_wrapper):
- G = get_graph_obj_for_benchmark(graph_obj, backend_wrapper)
- # DiGraphs are not supported
- if G.is_directed():
- G = G.to_undirected()
- result = benchmark.pedantic(
- target=backend_wrapper(nx.community.louvain_communities),
- args=(G,),
- rounds=rounds,
- iterations=iterations,
- warmup_rounds=warmup_rounds,
- )
- assert type(result) is list
-
-
-def bench_degree_centrality(benchmark, graph_obj, backend_wrapper):
- G = get_graph_obj_for_benchmark(graph_obj, backend_wrapper)
- result = benchmark.pedantic(
- target=backend_wrapper(nx.degree_centrality),
- args=(G,),
- rounds=rounds,
- iterations=iterations,
- warmup_rounds=warmup_rounds,
- )
- assert type(result) is dict
-
-
-def bench_eigenvector_centrality(benchmark, graph_obj, backend_wrapper):
- G = get_graph_obj_for_benchmark(graph_obj, backend_wrapper)
- result = benchmark.pedantic(
- target=backend_wrapper(nx.eigenvector_centrality),
- args=(G,),
- rounds=rounds,
- iterations=iterations,
- warmup_rounds=warmup_rounds,
- )
- assert type(result) is dict
-
-
-@pytest.mark.parametrize(
- "normalized", normalized_param_values, ids=lambda norm: f"{norm=}"
-)
-def bench_hits(benchmark, graph_obj, backend_wrapper, normalized):
- G = get_graph_obj_for_benchmark(graph_obj, backend_wrapper)
- result = benchmark.pedantic(
- target=backend_wrapper(nx.hits),
- args=(G,),
- kwargs=dict(
- normalized=normalized,
- ),
- rounds=rounds,
- iterations=iterations,
- warmup_rounds=warmup_rounds,
- )
- assert type(result) is tuple
- assert len(result) == 2
- assert type(result[0]) is dict
- assert type(result[1]) is dict
-
-
-def bench_in_degree_centrality(benchmark, graph_obj, backend_wrapper):
- G = get_graph_obj_for_benchmark(graph_obj, backend_wrapper)
- result = benchmark.pedantic(
- target=backend_wrapper(nx.in_degree_centrality),
- args=(G,),
- rounds=rounds,
- iterations=iterations,
- warmup_rounds=warmup_rounds,
- )
- assert type(result) is dict
-
-
-@pytest.mark.parametrize(
- "normalized", normalized_param_values, ids=lambda norm: f"{norm=}"
-)
-def bench_katz_centrality(benchmark, graph_obj, backend_wrapper, normalized):
- G = get_graph_obj_for_benchmark(graph_obj, backend_wrapper)
- result = benchmark.pedantic(
- target=backend_wrapper(nx.katz_centrality),
- args=(G,),
- kwargs=dict(
- normalized=normalized,
- ),
- rounds=rounds,
- iterations=iterations,
- warmup_rounds=warmup_rounds,
- )
- assert type(result) is dict
-
-
-def bench_k_truss(benchmark, graph_obj, backend_wrapper):
- G = get_graph_obj_for_benchmark(graph_obj, backend_wrapper)
- # DiGraphs are not supported
- if G.is_directed():
- G = G.to_undirected()
- result = benchmark.pedantic(
- target=backend_wrapper(nx.k_truss),
- args=(G,),
- kwargs=dict(
- k=2,
- ),
- rounds=rounds,
- iterations=iterations,
- warmup_rounds=warmup_rounds,
- )
- # Check that this at least appears to be some kind of NX-like Graph
- assert hasattr(result, "has_node")
-
-
-def bench_out_degree_centrality(benchmark, graph_obj, backend_wrapper):
- G = get_graph_obj_for_benchmark(graph_obj, backend_wrapper)
- result = benchmark.pedantic(
- target=backend_wrapper(nx.out_degree_centrality),
- args=(G,),
- rounds=rounds,
- iterations=iterations,
- warmup_rounds=warmup_rounds,
- )
- assert type(result) is dict
-
-
-def bench_pagerank(benchmark, graph_obj, backend_wrapper):
- G = get_graph_obj_for_benchmark(graph_obj, backend_wrapper)
- result = benchmark.pedantic(
- target=backend_wrapper(nx.pagerank),
- args=(G,),
- rounds=rounds,
- iterations=iterations,
- warmup_rounds=warmup_rounds,
- )
- assert type(result) is dict
-
-
-def bench_pagerank_personalized(benchmark, graph_obj, backend_wrapper):
- G = get_graph_obj_for_benchmark(graph_obj, backend_wrapper)
-
- # FIXME: This will run for every combination of inputs, even if the
- # graph/dataset does not change. Ideally this is run once per
- # graph/dataset.
- pagerank_dict = nx.pagerank(G)
- personalization_dict = build_personalization_dict(pagerank_dict)
-
- result = benchmark.pedantic(
- target=backend_wrapper(nx.pagerank),
- args=(G,),
- kwargs={"personalization": personalization_dict},
- rounds=rounds,
- iterations=iterations,
- warmup_rounds=warmup_rounds,
- )
- assert type(result) is dict
-
-
-def bench_shortest_path(benchmark, graph_obj, backend_wrapper):
- """
- This passes in the source node with the highest degree, but no target.
- """
- G = get_graph_obj_for_benchmark(graph_obj, backend_wrapper)
- node = get_highest_degree_node(graph_obj)
-
- result = benchmark.pedantic(
- target=backend_wrapper(nx.shortest_path),
- args=(G,),
- kwargs=dict(
- source=node,
- ),
- rounds=rounds,
- iterations=iterations,
- warmup_rounds=warmup_rounds,
- )
- assert type(result) is dict
-
-
-def bench_single_source_shortest_path_length(benchmark, graph_obj, backend_wrapper):
- G = get_graph_obj_for_benchmark(graph_obj, backend_wrapper)
- node = get_highest_degree_node(graph_obj)
-
- result = benchmark.pedantic(
- target=backend_wrapper(nx.single_source_shortest_path_length),
- args=(G,),
- kwargs=dict(
- source=node,
- ),
- rounds=rounds,
- iterations=iterations,
- warmup_rounds=warmup_rounds,
- )
- assert type(result) is dict
-
-
-def bench_single_target_shortest_path_length(benchmark, graph_obj, backend_wrapper):
- G = get_graph_obj_for_benchmark(graph_obj, backend_wrapper)
- node = get_highest_degree_node(graph_obj)
- result = benchmark.pedantic(
- target=backend_wrapper(
- nx.single_target_shortest_path_length, exhaust_returned_iterator=True
- ),
- args=(G,),
- kwargs=dict(
- target=node,
- ),
- rounds=rounds,
- iterations=iterations,
- warmup_rounds=warmup_rounds,
- )
- # exhaust_returned_iterator=True forces the result to a list, but is not
- # needed for this algo in NX 3.3+ which returns a dict instead of an
- # iterator. Forcing to a list does not change the benchmark timing.
- assert type(result) is list
-
-
-def bench_ancestors(benchmark, graph_obj, backend_wrapper):
- G = get_graph_obj_for_benchmark(graph_obj, backend_wrapper)
- node = get_highest_degree_node(graph_obj)
- result = benchmark.pedantic(
- target=backend_wrapper(nx.ancestors),
- args=(G,),
- kwargs=dict(
- source=node,
- ),
- rounds=rounds,
- iterations=iterations,
- warmup_rounds=warmup_rounds,
- )
- assert type(result) is set
-
-
-def bench_average_clustering(benchmark, graph_obj, backend_wrapper):
- G = get_graph_obj_for_benchmark(graph_obj, backend_wrapper)
- # DiGraphs are not supported by nx-cugraph
- if G.is_directed():
- G = G.to_undirected()
- result = benchmark.pedantic(
- target=backend_wrapper(nx.average_clustering),
- args=(G,),
- rounds=rounds,
- iterations=iterations,
- warmup_rounds=warmup_rounds,
- )
- assert type(result) is float
-
-
-def bench_generic_bfs_edges(benchmark, graph_obj, backend_wrapper):
- G = get_graph_obj_for_benchmark(graph_obj, backend_wrapper)
- node = get_highest_degree_node(graph_obj)
- result = benchmark.pedantic(
- target=backend_wrapper(nx.generic_bfs_edges, exhaust_returned_iterator=True),
- args=(G,),
- kwargs=dict(
- source=node,
- ),
- rounds=rounds,
- iterations=iterations,
- warmup_rounds=warmup_rounds,
- )
- assert type(result) is list
-
-
-def bench_bfs_edges(benchmark, graph_obj, backend_wrapper):
- G = get_graph_obj_for_benchmark(graph_obj, backend_wrapper)
- node = get_highest_degree_node(graph_obj)
- result = benchmark.pedantic(
- target=backend_wrapper(nx.bfs_edges, exhaust_returned_iterator=True),
- args=(G,),
- kwargs=dict(
- source=node,
- ),
- rounds=rounds,
- iterations=iterations,
- warmup_rounds=warmup_rounds,
- )
- assert type(result) is list
-
-
-def bench_bfs_layers(benchmark, graph_obj, backend_wrapper):
- G = get_graph_obj_for_benchmark(graph_obj, backend_wrapper)
- node = get_highest_degree_node(graph_obj)
- result = benchmark.pedantic(
- target=backend_wrapper(nx.bfs_layers, exhaust_returned_iterator=True),
- args=(G,),
- kwargs=dict(
- sources=node,
- ),
- rounds=rounds,
- iterations=iterations,
- warmup_rounds=warmup_rounds,
- )
- assert type(result) is list
-
-
-def bench_bfs_predecessors(benchmark, graph_obj, backend_wrapper):
- G = get_graph_obj_for_benchmark(graph_obj, backend_wrapper)
- node = get_highest_degree_node(graph_obj)
- result = benchmark.pedantic(
- target=backend_wrapper(nx.bfs_predecessors, exhaust_returned_iterator=True),
- args=(G,),
- kwargs=dict(
- source=node,
- ),
- rounds=rounds,
- iterations=iterations,
- warmup_rounds=warmup_rounds,
- )
- assert type(result) is list
-
-
-def bench_bfs_successors(benchmark, graph_obj, backend_wrapper):
- G = get_graph_obj_for_benchmark(graph_obj, backend_wrapper)
- node = get_highest_degree_node(graph_obj)
- result = benchmark.pedantic(
- target=backend_wrapper(nx.bfs_successors, exhaust_returned_iterator=True),
- args=(G,),
- kwargs=dict(
- source=node,
- ),
- rounds=rounds,
- iterations=iterations,
- warmup_rounds=warmup_rounds,
- )
- assert type(result) is list
-
-
-def bench_bfs_tree(benchmark, graph_obj, backend_wrapper):
- G = get_graph_obj_for_benchmark(graph_obj, backend_wrapper)
- node = get_highest_degree_node(graph_obj)
- result = benchmark.pedantic(
- target=backend_wrapper(nx.bfs_tree),
- args=(G,),
- kwargs=dict(
- source=node,
- ),
- rounds=rounds,
- iterations=iterations,
- warmup_rounds=warmup_rounds,
- )
- # Check that this at least appears to be some kind of NX-like Graph
- assert hasattr(result, "has_node")
-
-
-def bench_clustering(benchmark, graph_obj, backend_wrapper):
- G = get_graph_obj_for_benchmark(graph_obj, backend_wrapper)
- # DiGraphs are not supported by nx-cugraph
- if G.is_directed():
- G = G.to_undirected()
- result = benchmark.pedantic(
- target=backend_wrapper(nx.clustering),
- args=(G,),
- rounds=rounds,
- iterations=iterations,
- warmup_rounds=warmup_rounds,
- )
- assert type(result) is dict
-
-
-def bench_core_number(benchmark, graph_obj, backend_wrapper):
- G = get_graph_obj_for_benchmark(graph_obj, backend_wrapper)
- # DiGraphs are not supported by nx-cugraph
- if G.is_directed():
- G = G.to_undirected()
- result = benchmark.pedantic(
- target=backend_wrapper(nx.core_number),
- args=(G,),
- rounds=rounds,
- iterations=iterations,
- warmup_rounds=warmup_rounds,
- )
- assert type(result) is dict
-
-
-def bench_descendants(benchmark, graph_obj, backend_wrapper):
- G = get_graph_obj_for_benchmark(graph_obj, backend_wrapper)
- node = get_highest_degree_node(graph_obj)
- result = benchmark.pedantic(
- target=backend_wrapper(nx.descendants),
- args=(G,),
- kwargs=dict(
- source=node,
- ),
- rounds=rounds,
- iterations=iterations,
- warmup_rounds=warmup_rounds,
- )
- assert type(result) is set
-
-
-def bench_descendants_at_distance(benchmark, graph_obj, backend_wrapper):
- G = get_graph_obj_for_benchmark(graph_obj, backend_wrapper)
- node = get_highest_degree_node(graph_obj)
- result = benchmark.pedantic(
- target=backend_wrapper(nx.descendants_at_distance),
- args=(G,),
- kwargs=dict(
- source=node,
- distance=1,
- ),
- rounds=rounds,
- iterations=iterations,
- warmup_rounds=warmup_rounds,
- )
- assert type(result) is set
-
-
-def bench_is_bipartite(benchmark, graph_obj, backend_wrapper):
- G = get_graph_obj_for_benchmark(graph_obj, backend_wrapper)
- result = benchmark.pedantic(
- target=backend_wrapper(nx.is_bipartite),
- args=(G,),
- rounds=rounds,
- iterations=iterations,
- warmup_rounds=warmup_rounds,
- )
- assert type(result) is bool
-
-
-def bench_is_strongly_connected(benchmark, graph_obj, backend_wrapper):
- G = get_graph_obj_for_benchmark(graph_obj, backend_wrapper)
- result = benchmark.pedantic(
- target=backend_wrapper(nx.is_strongly_connected),
- args=(G,),
- rounds=rounds,
- iterations=iterations,
- warmup_rounds=warmup_rounds,
- )
- assert type(result) is bool
-
-
-def bench_is_weakly_connected(benchmark, graph_obj, backend_wrapper):
- G = get_graph_obj_for_benchmark(graph_obj, backend_wrapper)
- result = benchmark.pedantic(
- target=backend_wrapper(nx.is_weakly_connected),
- args=(G,),
- rounds=rounds,
- iterations=iterations,
- warmup_rounds=warmup_rounds,
- )
- assert type(result) is bool
-
-
-def bench_number_strongly_connected_components(benchmark, graph_obj, backend_wrapper):
- G = get_graph_obj_for_benchmark(graph_obj, backend_wrapper)
- result = benchmark.pedantic(
- target=backend_wrapper(nx.number_strongly_connected_components),
- args=(G,),
- rounds=rounds,
- iterations=iterations,
- warmup_rounds=warmup_rounds,
- )
- assert type(result) is int
-
-
-def bench_number_weakly_connected_components(benchmark, graph_obj, backend_wrapper):
- G = get_graph_obj_for_benchmark(graph_obj, backend_wrapper)
- result = benchmark.pedantic(
- target=backend_wrapper(nx.number_weakly_connected_components),
- args=(G,),
- rounds=rounds,
- iterations=iterations,
- warmup_rounds=warmup_rounds,
- )
- assert type(result) is int
-
-
-def bench_overall_reciprocity(benchmark, graph_obj, backend_wrapper):
- G = get_graph_obj_for_benchmark(graph_obj, backend_wrapper)
- result = benchmark.pedantic(
- target=backend_wrapper(nx.overall_reciprocity),
- args=(G,),
- rounds=rounds,
- iterations=iterations,
- warmup_rounds=warmup_rounds,
- )
- assert type(result) is float
-
-
-def bench_reciprocity(benchmark, graph_obj, backend_wrapper):
- G = get_graph_obj_for_benchmark(graph_obj, backend_wrapper)
- node = get_highest_degree_node(graph_obj)
- result = benchmark.pedantic(
- target=backend_wrapper(nx.reciprocity),
- args=(G,),
- kwargs=dict(
- nodes=node,
- ),
- rounds=rounds,
- iterations=iterations,
- warmup_rounds=warmup_rounds,
- )
- assert type(result) is float
-
-
-def bench_strongly_connected_components(benchmark, graph_obj, backend_wrapper):
- G = get_graph_obj_for_benchmark(graph_obj, backend_wrapper)
- result = benchmark.pedantic(
- target=backend_wrapper(
- nx.strongly_connected_components, exhaust_returned_iterator=True
- ),
- args=(G,),
- rounds=rounds,
- iterations=iterations,
- warmup_rounds=warmup_rounds,
- )
- assert type(result) is list
-
-
-def bench_transitivity(benchmark, graph_obj, backend_wrapper):
- G = get_graph_obj_for_benchmark(graph_obj, backend_wrapper)
- # DiGraphs are not supported by nx-cugraph
- if G.is_directed():
- G = G.to_undirected()
- result = benchmark.pedantic(
- target=backend_wrapper(nx.transitivity),
- args=(G,),
- rounds=rounds,
- iterations=iterations,
- warmup_rounds=warmup_rounds,
- )
- assert type(result) is float
-
-
-def bench_triangles(benchmark, graph_obj, backend_wrapper):
- G = get_graph_obj_for_benchmark(graph_obj, backend_wrapper)
- # DiGraphs are not supported
- if G.is_directed():
- G = G.to_undirected()
- result = benchmark.pedantic(
- target=backend_wrapper(nx.triangles),
- args=(G,),
- rounds=rounds,
- iterations=iterations,
- warmup_rounds=warmup_rounds,
- )
- assert type(result) is dict
-
-
-def bench_weakly_connected_components(benchmark, graph_obj, backend_wrapper):
- G = get_graph_obj_for_benchmark(graph_obj, backend_wrapper)
- result = benchmark.pedantic(
- target=backend_wrapper(
- nx.weakly_connected_components, exhaust_returned_iterator=True
- ),
- args=(G,),
- rounds=rounds,
- iterations=iterations,
- warmup_rounds=warmup_rounds,
- )
- assert type(result) is list
-
-
-def bench_ego_graph(benchmark, graph_obj, backend_wrapper):
- G = get_graph_obj_for_benchmark(graph_obj, backend_wrapper)
- node = get_highest_degree_node(graph_obj)
- result = benchmark.pedantic(
- target=backend_wrapper(nx.ego_graph),
- args=(G,),
- kwargs=dict(
- n=node,
- radius=100,
- ),
- rounds=rounds,
- iterations=iterations,
- warmup_rounds=warmup_rounds,
- )
- assert isinstance(result, (nx.Graph, nxcg.Graph))
-
-
-@pytest.mark.skip(reason="benchmark not implemented")
-def bench_complete_bipartite_graph(benchmark, graph_obj, backend_wrapper):
- pass
-
-
-@pytest.mark.skip(reason="benchmark not implemented")
-def bench_connected_components(benchmark, graph_obj, backend_wrapper):
- pass
-
-
-@pytest.mark.skip(reason="benchmark not implemented")
-def bench_is_connected(benchmark, graph_obj, backend_wrapper):
- pass
-
-
-@pytest.mark.skip(reason="benchmark not implemented")
-def bench_node_connected_component(benchmark, graph_obj, backend_wrapper):
- pass
-
-
-@pytest.mark.skip(reason="benchmark not implemented")
-def bench_number_connected_components(benchmark, graph_obj, backend_wrapper):
- pass
-
-
-@pytest.mark.skip(reason="benchmark not implemented")
-def bench_is_isolate(benchmark, graph_obj, backend_wrapper):
- pass
-
-
-@pytest.mark.skip(reason="benchmark not implemented")
-def bench_isolates(benchmark, graph_obj, backend_wrapper):
- pass
-
-
-@pytest.mark.skip(reason="benchmark not implemented")
-def bench_number_of_isolates(benchmark, graph_obj, backend_wrapper):
- pass
-
-
-@pytest.mark.skip(reason="benchmark not implemented")
-def bench_complement(benchmark, graph_obj, backend_wrapper):
- pass
-
-
-@pytest.mark.skip(reason="benchmark not implemented")
-def bench_reverse(benchmark, graph_obj, backend_wrapper):
- pass
-
-
-@pytest.mark.skip(reason="benchmark not implemented")
-def bench_is_arborescence(benchmark, graph_obj, backend_wrapper):
- pass
-
-
-@pytest.mark.skip(reason="benchmark not implemented")
-def bench_is_branching(benchmark, graph_obj, backend_wrapper):
- pass
-
-
-@pytest.mark.skip(reason="benchmark not implemented")
-def bench_is_forest(benchmark, graph_obj, backend_wrapper):
- pass
-
-
-@pytest.mark.skip(reason="benchmark not implemented")
-def bench_is_tree(benchmark, graph_obj, backend_wrapper):
- pass
diff --git a/benchmarks/nx-cugraph/pytest-based/create_results_summary_page.py b/benchmarks/nx-cugraph/pytest-based/create_results_summary_page.py
deleted file mode 100644
index f1cc4b06ccc..00000000000
--- a/benchmarks/nx-cugraph/pytest-based/create_results_summary_page.py
+++ /dev/null
@@ -1,291 +0,0 @@
-# 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.
-
-
-import re
-import pathlib
-import json
-import platform
-import psutil
-import socket
-import subprocess
-
-
-def get_formatted_time_value(time):
- res = ""
- if time < 1:
- if time < 0.001:
- units = "us"
- time *= 1e6
- else:
- units = "ms"
- time *= 1e3
- else:
- units = "s"
- return f"{time:.3f}{units}"
-
-
-def get_all_benchmark_info():
- benchmarks = {}
- # Populate benchmarks dir from .json files
- for json_file in logs_dir.glob("*.json"):
- try:
- data = json.loads(open(json_file).read())
- except json.decoder.JSONDecodeError:
- continue
-
- for benchmark_run in data["benchmarks"]:
- # example name: "bench_triangles[ds=netscience-backend=cugraph-preconverted]"
- name = benchmark_run["name"]
-
- algo_name = name.split("[")[0]
- if algo_name.startswith("bench_"):
- algo_name = algo_name[6:]
- # special case for betweenness_centrality
- match = k_patt.match(name)
- if match is not None:
- algo_name += f", k={match.group(1)}"
-
- match = dataset_patt.match(name)
- if match is None:
- raise RuntimeError(
- f"benchmark name {name} in file {json_file} has an unexpected format"
- )
- dataset = match.group(1)
- if dataset.endswith("-backend"):
- dataset = dataset[:-8]
-
- match = backend_patt.match(name)
- if match is None:
- raise RuntimeError(
- f"benchmark name {name} in file {json_file} has an unexpected format"
- )
- backend = match.group(1)
- if backend == "None":
- backend = "networkx"
-
- runtime = benchmark_run["stats"]["mean"]
- benchmarks.setdefault(algo_name, {}).setdefault(backend, {})[
- dataset
- ] = runtime
- return benchmarks
-
-
-def compute_perf_vals(cugraph_runtime, networkx_runtime):
- speedup_string = f"{networkx_runtime / cugraph_runtime:.3f}X"
- delta = networkx_runtime - cugraph_runtime
- if abs(delta) < 1:
- if abs(delta) < 0.001:
- units = "us"
- delta *= 1e6
- else:
- units = "ms"
- delta *= 1e3
- else:
- units = "s"
- delta_string = f"{delta:.3f}{units}"
-
- return (speedup_string, delta_string)
-
-
-def get_mem_info():
- return round(psutil.virtual_memory().total / (1024**3), 2)
-
-
-def get_cuda_version():
- output = subprocess.check_output("nvidia-smi", shell=True).decode()
- try:
- return next(
- line.split("CUDA Version: ")[1].split()[0]
- for line in output.splitlines()
- if "CUDA Version" in line
- )
- except subprocess.CalledProcessError:
- return "Failed to get CUDA version."
-
-
-def get_first_gpu_info():
- try:
- gpu_info = (
- subprocess.check_output(
- "nvidia-smi --query-gpu=name,memory.total,memory.free,memory.used --format=csv,noheader",
- shell=True,
- )
- .decode()
- .strip()
- )
- if gpu_info:
- gpus = gpu_info.split("\n")
- num_gpus = len(gpus)
- 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.")
- except subprocess.CalledProcessError:
- print("Failed to execute nvidia-smi. No GPU information available.")
-
-
-def get_system_info():
- print('
')
- print(f"
Hostname: {socket.gethostname()}
")
- print(
- f'
Operating System: {platform.system()} {platform.release()}
'
- )
- print(f'
Kernel Version : {platform.version()}
')
- with open("/proc/cpuinfo") as f:
- print(
- f'
CPU: {next(line.strip().split(": ")[1] for line in f if "model name" in line)} ({psutil.cpu_count(logical=False)} cores)
'
- )
- print(f'
Memory: {get_mem_info()} GB
')
- print(f"
GPU: {get_first_gpu_info()}
")
- print(f"
CUDA Version: {get_cuda_version()}
")
-
-
-if __name__ == "__main__":
- logs_dir = pathlib.Path("logs")
-
- dataset_patt = re.compile(".*ds=([\w-]+).*")
- backend_patt = re.compile(".*backend=(\w+).*")
- k_patt = re.compile(".*k=(10*).*")
-
- # Organize all benchmark runs by the following hierarchy: algo -> backend -> dataset
- benchmarks = get_all_benchmark_info()
-
- # dump HTML table
- ordered_datasets = [
- "netscience",
- "email_Eu_core",
- "cit-patents",
- "hollywood",
- "soc-livejournal1",
- ]
- # dataset, # Node, # Edge, Directed info
- dataset_meta = {
- "netscience": ["1,461", "5,484", "Yes"],
- "email_Eu_core": ["1,005", "25,571", "Yes"],
- "cit-patents": ["3,774,768", "16,518,948", "Yes"],
- "hollywood": ["1,139,905", "57,515,616", "No"],
- "soc-livejournal1": ["4,847,571", "68,993,773", "Yes"],
- }
-
- print(
- """
-
-
-
-
-
-
-
- Dataset Nodes Edges Directed | """
- )
- for ds in ordered_datasets:
- print(
- f" {ds} {dataset_meta[ds][0]} {dataset_meta[ds][1]} {dataset_meta[ds][2]}
| "
- )
- print(
- """
-
-
- """
- )
- for algo_name in sorted(benchmarks):
- algo_runs = benchmarks[algo_name]
- print(" ")
- print(f" {algo_name} | ")
- # Proceed only if any results are present for both cugraph and NX
- if "cugraph" in algo_runs and "networkx" in algo_runs:
- cugraph_algo_runs = algo_runs["cugraph"]
- networkx_algo_runs = algo_runs["networkx"]
- datasets_in_both = set(cugraph_algo_runs).intersection(networkx_algo_runs)
-
- # populate the table with speedup results for each dataset in the order
- # specified in ordered_datasets. If results for a run using a dataset
- # are not present for both cugraph and NX, output an empty cell.
- for dataset in ordered_datasets:
- if dataset in datasets_in_both:
- cugraph_runtime = cugraph_algo_runs[dataset]
- networkx_runtime = networkx_algo_runs[dataset]
- (speedup, runtime_delta) = compute_perf_vals(
- cugraph_runtime=cugraph_runtime,
- networkx_runtime=networkx_runtime,
- )
- nx_formatted = get_formatted_time_value(networkx_runtime)
- cg_formatted = get_formatted_time_value(cugraph_runtime)
- print(
- f" {nx_formatted} / {cg_formatted} {speedup} {runtime_delta} | "
- )
- else:
- print(f" | ")
-
- # If a comparison between cugraph and NX cannot be made, output empty cells
- # for each dataset
- else:
- for _ in range(len(ordered_datasets)):
- print(" | ")
- print("
")
- print(
- """
- \n
-
-
-
Table Format:
-
- - NetworkX time / nx-cugraph time
- - Speed-up of using nx-cugraph
- - Time-delta
-
-
"""
- )
- get_system_info()
- print("""
\n
\n""")
diff --git a/benchmarks/nx-cugraph/pytest-based/get_graph_bench_dataset.py b/benchmarks/nx-cugraph/pytest-based/get_graph_bench_dataset.py
deleted file mode 100644
index 5a0a15da8ee..00000000000
--- a/benchmarks/nx-cugraph/pytest-based/get_graph_bench_dataset.py
+++ /dev/null
@@ -1,35 +0,0 @@
-# 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.
-
-"""
-Checks if a particular dataset has been downloaded inside the datasets dir
-(RAPIDS_DATAEST_ROOT_DIR). If not, the file will be downloaded using the
-datasets API.
-
-Positional Arguments:
- 1) dataset name (e.g. 'email_Eu_core', 'cit-patents')
- available datasets can be found here: `python/cugraph/cugraph/datasets/__init__.py`
-"""
-
-import sys
-
-import cugraph.datasets as cgds
-
-
-if __name__ == "__main__":
- # download and store dataset (csv) by using the Datasets API
- dataset = sys.argv[1].replace("-", "_")
- dataset_obj = getattr(cgds, dataset)
-
- if not dataset_obj.get_path().exists():
- dataset_obj.get_edgelist(download=True)
diff --git a/benchmarks/nx-cugraph/pytest-based/run-2402.sh b/benchmarks/nx-cugraph/pytest-based/run-2402.sh
deleted file mode 100755
index 44ed0bda43a..00000000000
--- a/benchmarks/nx-cugraph/pytest-based/run-2402.sh
+++ /dev/null
@@ -1,46 +0,0 @@
-#!/bin/bash
-#
-# Copyright (c) 2024, NVIDIA CORPORATION.
-#
-# Runs benchmarks for the 24.02 algos.
-# Pass either a or b or both. This is useful for separating batches of runs on different GPUs:
-# CUDA_VISIBLE_DEVICES=1 run-2402.sh b
-
-mkdir -p logs
-
-# benches="$benches ..." pattern is easy to comment out individual runs
-benches=
-
-while [[ $1 != "" ]]; do
- if [[ $1 == "a" ]]; then
- benches="$benches bench_ancestors"
- benches="$benches bench_average_clustering"
- benches="$benches bench_generic_bfs_edges"
- benches="$benches bench_bfs_edges"
- benches="$benches bench_bfs_layers"
- benches="$benches bench_bfs_predecessors"
- benches="$benches bench_bfs_successors"
- benches="$benches bench_bfs_tree"
- benches="$benches bench_clustering"
- benches="$benches bench_core_number"
- benches="$benches bench_descendants"
- elif [[ $1 == "b" ]]; then
- benches="$benches bench_descendants_at_distance"
- benches="$benches bench_is_bipartite"
- benches="$benches bench_is_strongly_connected"
- benches="$benches bench_is_weakly_connected"
- benches="$benches bench_number_strongly_connected_components"
- benches="$benches bench_number_weakly_connected_components"
- benches="$benches bench_overall_reciprocity"
- benches="$benches bench_reciprocity"
- benches="$benches bench_strongly_connected_components"
- benches="$benches bench_transitivity"
- benches="$benches bench_triangles"
- benches="$benches bench_weakly_connected_components"
- fi
- shift
-done
-
-for bench in $benches; do
- pytest -sv -k "soc-livejournal1" "bench_algos.py::$bench" 2>&1 | tee "logs/${bench}.log"
-done
diff --git a/benchmarks/nx-cugraph/pytest-based/run-main-benchmarks.sh b/benchmarks/nx-cugraph/pytest-based/run-main-benchmarks.sh
deleted file mode 100755
index 3059e3d4bdf..00000000000
--- a/benchmarks/nx-cugraph/pytest-based/run-main-benchmarks.sh
+++ /dev/null
@@ -1,74 +0,0 @@
-#!/bin/bash
-# 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.
-
-
-# location to store datasets used for benchmarking
-export RAPIDS_DATASET_ROOT_DIR=/datasets/cugraph
-mkdir -p logs
-
-# list of algos, datasets, and back-ends to use in combinations
-algos="
- pagerank
- betweenness_centrality
- louvain
- shortest_path
- weakly_connected_components
- triangles
- bfs_predecessors
-"
-datasets="
- netscience
- email_Eu_core
- cit-patents
- hollywood
- soc-livejournal
-"
-# None backend is default networkx
-# cugraph-preconvert backend is nx-cugraph
-backends="
- None
- cugraph-preconverted
-"
-# check for --cpu-only or --gpu-only args
-if [[ "$#" -eq 1 ]]; then
- case $1 in
- --cpu-only)
- backends="None"
- ;;
- --gpu-only)
- backends="cugraph-preconverted"
- ;;
- *)
- echo "Unknown option: $1"
- exit 1
- ;;
- esac
-fi
-
-for algo in $algos; do
- for dataset in $datasets; do
- # this script can be used to download benchmarking datasets by name via cugraph.datasets
- python get_graph_bench_dataset.py $dataset
- for backend in $backends; do
- name="${backend}__${algo}__${dataset}"
- echo "Running: $backend, $dataset, bench_$algo"
- # command to preproduce test
- # echo "RUNNING: \"pytest -sv -k \"$backend and $dataset and bench_$algo and not 1000\" --benchmark-json=\"logs/${name}.json\" bench_algos.py"
- pytest -sv \
- -k "$backend and $dataset and bench_$algo and not 1000" \
- --benchmark-json="logs/${name}.json" \
- bench_algos.py 2>&1 | tee "logs/${name}.out"
- done
- done
-done
diff --git a/build.sh b/build.sh
index 24ce8c08e8d..1ab98fe4378 100755
--- a/build.sh
+++ b/build.sh
@@ -32,7 +32,6 @@ VALIDARGS="
cugraph-pyg
cugraph-dgl
cugraph-equivariant
- nx-cugraph
cpp-mgtests
cpp-mtmgtests
docs
@@ -43,7 +42,6 @@ VALIDARGS="
--pydevelop
--allgpuarch
--skip_cpp_tests
- --without_cugraphops
--cmake_default_generator
--clean
-h
@@ -62,7 +60,6 @@ HELP="$0 [ ...] [ ...]
cugraph-pyg - build the cugraph-pyg Python package
cugraph-dgl - build the cugraph-dgl extensions for DGL
cugraph-equivariant - build the cugraph-equivariant Python package
- nx-cugraph - build the nx-cugraph Python package
cpp-mgtests - build libcugraph and libcugraph_etl MG tests. Builds MPI communicator, adding MPI as a dependency.
cpp-mtmgtests - build libcugraph MTMG tests. Adds UCX as a dependency (temporary).
docs - build the docs
@@ -74,7 +71,6 @@ HELP="$0 [ ...] [ ...]
--pydevelop - install the Python packages in editable mode
--allgpuarch - build for all supported GPU architectures
--skip_cpp_tests - do not build the SG test binaries as part of the libcugraph and libcugraph_etl targets
- --without_cugraphops - do not build algos that require cugraph-ops
--cmake_default_generator - use the default cmake generator instead of ninja
--clean - clean an individual target (note: to do a complete rebuild, use the clean target described above)
-h - print this text
@@ -107,7 +103,6 @@ BUILD_CPP_TESTS=ON
BUILD_CPP_MG_TESTS=OFF
BUILD_CPP_MTMG_TESTS=OFF
BUILD_ALL_GPU_ARCH=0
-BUILD_WITH_CUGRAPHOPS=ON
CMAKE_GENERATOR_OPTION="-G Ninja"
PYTHON_ARGS_FOR_INSTALL="-m pip install --no-build-isolation --no-deps --config-settings rapidsai.disable-cuda=true"
@@ -170,9 +165,6 @@ fi
if hasArg --skip_cpp_tests; then
BUILD_CPP_TESTS=OFF
fi
-if hasArg --without_cugraphops; then
- BUILD_WITH_CUGRAPHOPS=OFF
-fi
if hasArg cpp-mtmgtests; then
BUILD_CPP_MTMG_TESTS=ON
fi
@@ -218,7 +210,7 @@ if hasArg uninstall; then
# 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 pylibcugraph cugraph cugraph-service-client cugraph-service-server \
- cugraph-dgl cugraph-pyg cugraph-equivariant nx-cugraph
+ cugraph-dgl cugraph-pyg cugraph-equivariant
fi
if hasArg clean; then
@@ -268,7 +260,6 @@ if buildDefault || hasArg libcugraph || hasArg all; then
-DBUILD_TESTS=${BUILD_CPP_TESTS} \
-DBUILD_CUGRAPH_MG_TESTS=${BUILD_CPP_MG_TESTS} \
-DBUILD_CUGRAPH_MTMG_TESTS=${BUILD_CPP_MTMG_TESTS} \
- -DUSE_CUGRAPH_OPS=${BUILD_WITH_CUGRAPHOPS} \
${CMAKE_GENERATOR_OPTION} \
${CMAKE_VERBOSE_OPTION}
cmake --build "${LIBCUGRAPH_BUILD_DIR}" -j${PARALLEL_LEVEL} ${INSTALL_TARGET} ${VERBOSE_FLAG}
@@ -312,7 +303,7 @@ if buildDefault || hasArg pylibcugraph || hasArg all; then
if hasArg --clean; then
cleanPythonDir ${REPODIR}/python/pylibcugraph
else
- SKBUILD_CMAKE_ARGS="${SKBUILD_EXTRA_CMAKE_ARGS};-DUSE_CUGRAPH_OPS=${BUILD_WITH_CUGRAPHOPS}" \
+ SKBUILD_CMAKE_ARGS="${SKBUILD_EXTRA_CMAKE_ARGS}" \
python ${PYTHON_ARGS_FOR_INSTALL} ${REPODIR}/python/pylibcugraph
fi
fi
@@ -322,7 +313,7 @@ if buildDefault || hasArg cugraph || hasArg all; then
if hasArg --clean; then
cleanPythonDir ${REPODIR}/python/cugraph
else
- SKBUILD_CMAKE_ARGS="${SKBUILD_EXTRA_CMAKE_ARGS};-DUSE_CUGRAPH_OPS=${BUILD_WITH_CUGRAPHOPS}" \
+ SKBUILD_CMAKE_ARGS="${SKBUILD_EXTRA_CMAKE_ARGS}" \
python ${PYTHON_ARGS_FOR_INSTALL} ${REPODIR}/python/cugraph
fi
fi
@@ -364,15 +355,6 @@ if hasArg cugraph-equivariant || hasArg all; then
fi
fi
-# Build and install the nx-cugraph Python package
-if hasArg nx-cugraph || hasArg all; then
- if hasArg --clean; then
- cleanPythonDir ${REPODIR}/python/nx-cugraph
- else
- python ${PYTHON_ARGS_FOR_INSTALL} ${REPODIR}/python/nx-cugraph
- fi
-fi
-
# Build the docs
if hasArg docs || hasArg all; then
if [ ! -d ${LIBCUGRAPH_BUILD_DIR} ]; then
diff --git a/ci/build_cpp.sh b/ci/build_cpp.sh
index 859977d76d5..93e5c680d07 100755
--- a/ci/build_cpp.sh
+++ b/ci/build_cpp.sh
@@ -17,4 +17,6 @@ rapids-logger "Begin cpp build"
RAPIDS_PACKAGE_VERSION=$(rapids-generate-version) rapids-conda-retry mambabuild conda/recipes/libcugraph
+sccache --show-adv-stats
+
rapids-upload-conda-to-s3 cpp
diff --git a/ci/build_python.sh b/ci/build_python.sh
index c94cc2a0fce..9a8f1227488 100755
--- a/ci/build_python.sh
+++ b/ci/build_python.sh
@@ -20,6 +20,8 @@ export RAPIDS_PACKAGE_VERSION=$(head -1 ./VERSION)
rapids-logger "Begin py build"
+sccache --zero-stats
+
# TODO: Remove `--no-test` flags once importing on a CPU
# node works correctly
rapids-conda-retry mambabuild \
@@ -27,21 +29,16 @@ rapids-conda-retry mambabuild \
--channel "${CPP_CHANNEL}" \
conda/recipes/pylibcugraph
+sccache --show-adv-stats
+sccache --zero-stats
+
rapids-conda-retry mambabuild \
--no-test \
--channel "${CPP_CHANNEL}" \
--channel "${RAPIDS_CONDA_BLD_OUTPUT_DIR}" \
conda/recipes/cugraph
-# NOTE: nothing in nx-cugraph is CUDA-specific, but it is built on each CUDA
-# platform to ensure it is included in each set of artifacts, since test
-# scripts only install from one set of artifacts based on the CUDA version used
-# for the test run.
-rapids-conda-retry mambabuild \
- --no-test \
- --channel "${CPP_CHANNEL}" \
- --channel "${RAPIDS_CONDA_BLD_OUTPUT_DIR}" \
- conda/recipes/nx-cugraph
+sccache --show-adv-stats
# NOTE: nothing in the cugraph-service packages are CUDA-specific, but they are
# built on each CUDA platform to ensure they are included in each set of
@@ -53,29 +50,6 @@ rapids-conda-retry mambabuild \
--channel "${RAPIDS_CONDA_BLD_OUTPUT_DIR}" \
conda/recipes/cugraph-service
-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 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/label/th23_cu118 \
- --channel pytorch \
- --channel pytorch-nightly \
- conda/recipes/cugraph-dgl
-fi
-
rapids-conda-retry mambabuild \
--no-test \
--channel "${RAPIDS_CONDA_BLD_OUTPUT_DIR}" \
diff --git a/ci/build_wheel.sh b/ci/build_wheel.sh
index f3979ab3049..3c89d63538c 100755
--- a/ci/build_wheel.sh
+++ b/ci/build_wheel.sh
@@ -15,6 +15,10 @@ rapids-generate-version > ./VERSION
cd "${package_dir}"
+sccache --zero-stats
+
+rapids-logger "Building '${package_name}' wheel"
+
python -m pip wheel \
-w dist \
-v \
@@ -23,12 +27,11 @@ python -m pip wheel \
--extra-index-url https://pypi.nvidia.com \
.
+sccache --show-adv-stats
+
# pure-python packages should be marked as pure, and not have auditwheel run on them.
-if [[ ${package_name} == "nx-cugraph" ]] || \
- [[ ${package_name} == "cugraph-dgl" ]] || \
- [[ ${package_name} == "cugraph-pyg" ]] || \
- [[ ${package_name} == "cugraph-equivariant" ]]; then
- RAPIDS_PY_WHEEL_NAME="${package_name}_${RAPIDS_PY_CUDA_SUFFIX}" RAPIDS_PY_WHEEL_PURE="1" rapids-upload-wheels-to-s3 dist
+if [[ ${package_name} == "cugraph-equivariant" ]]; then
+ RAPIDS_PY_WHEEL_NAME="${package_name}_${RAPIDS_PY_CUDA_SUFFIX}" RAPIDS_PY_WHEEL_PURE="1" rapids-upload-wheels-to-s3 python dist
else
case "${RAPIDS_CUDA_VERSION}" in
12.*)
@@ -48,5 +51,5 @@ else
mkdir -p final_dist
python -m auditwheel repair -w final_dist "${EXCLUDE_ARGS[@]}" dist/*
- RAPIDS_PY_WHEEL_NAME="${package_name}_${RAPIDS_PY_CUDA_SUFFIX}" rapids-upload-wheels-to-s3 final_dist
+ RAPIDS_PY_WHEEL_NAME="${package_name}_${RAPIDS_PY_CUDA_SUFFIX}" rapids-upload-wheels-to-s3 python final_dist
fi
diff --git a/ci/build_wheel_cugraph-dgl.sh b/ci/build_wheel_cugraph-dgl.sh
deleted file mode 100755
index d62f810cba4..00000000000
--- a/ci/build_wheel_cugraph-dgl.sh
+++ /dev/null
@@ -1,6 +0,0 @@
-#!/bin/bash
-# Copyright (c) 2024, NVIDIA CORPORATION.
-
-set -euo pipefail
-
-./ci/build_wheel.sh cugraph-dgl python/cugraph-dgl
diff --git a/ci/build_wheel_cugraph-equivariant.sh b/ci/build_wheel_cugraph-equivariant.sh
index fcc8e0f774c..2f270422f84 100755
--- a/ci/build_wheel_cugraph-equivariant.sh
+++ b/ci/build_wheel_cugraph-equivariant.sh
@@ -3,4 +3,7 @@
set -euo pipefail
-./ci/build_wheel.sh cugraph-equivariant python/cugraph-equivariant
+package_dir="python/cugraph-equivariant"
+
+./ci/build_wheel.sh cugraph-equivariant ${package_dir}
+./ci/validate_wheel.sh ${package_dir} dist
diff --git a/ci/build_wheel_cugraph-pyg.sh b/ci/build_wheel_cugraph-pyg.sh
deleted file mode 100755
index 97baa243f73..00000000000
--- a/ci/build_wheel_cugraph-pyg.sh
+++ /dev/null
@@ -1,6 +0,0 @@
-#!/bin/bash
-# Copyright (c) 2024, NVIDIA CORPORATION.
-
-set -euo pipefail
-
-./ci/build_wheel.sh cugraph-pyg python/cugraph-pyg
diff --git a/ci/build_wheel_cugraph.sh b/ci/build_wheel_cugraph.sh
index 20d9bf47e3e..b937fd7f6d8 100755
--- a/ci/build_wheel_cugraph.sh
+++ b/ci/build_wheel_cugraph.sh
@@ -3,6 +3,8 @@
set -euo pipefail
+package_dir="python/cugraph"
+
RAPIDS_PY_CUDA_SUFFIX="$(rapids-wheel-ctk-name-gen ${RAPIDS_CUDA_VERSION})"
# Download the pylibcugraph wheel built in the previous step and make it
@@ -31,4 +33,5 @@ esac
export SKBUILD_CMAKE_ARGS="-DDETECT_CONDA_ENV=OFF;-DFIND_CUGRAPH_CPP=OFF;-DCPM_cugraph-ops_SOURCE=${GITHUB_WORKSPACE}/cugraph-ops/${EXTRA_CMAKE_ARGS}"
export SKBUILD_BUILD_TOOL_ARGS="-j${PARALLEL_LEVEL};-l${PARALLEL_LEVEL}"
-./ci/build_wheel.sh cugraph python/cugraph
+./ci/build_wheel.sh cugraph ${package_dir}
+./ci/validate_wheel.sh ${package_dir} final_dist
diff --git a/ci/build_wheel_nx-cugraph.sh b/ci/build_wheel_nx-cugraph.sh
deleted file mode 100755
index 4481de1283d..00000000000
--- a/ci/build_wheel_nx-cugraph.sh
+++ /dev/null
@@ -1,6 +0,0 @@
-#!/bin/bash
-# Copyright (c) 2023, NVIDIA CORPORATION.
-
-set -euo pipefail
-
-./ci/build_wheel.sh nx-cugraph python/nx-cugraph
diff --git a/ci/build_wheel_pylibcugraph.sh b/ci/build_wheel_pylibcugraph.sh
index fa967b0be29..928e12d2350 100755
--- a/ci/build_wheel_pylibcugraph.sh
+++ b/ci/build_wheel_pylibcugraph.sh
@@ -3,6 +3,8 @@
set -euo pipefail
+package_dir="python/pylibcugraph"
+
PARALLEL_LEVEL=$(python -c \
"from math import ceil; from multiprocessing import cpu_count; print(ceil(cpu_count()/4))")
@@ -18,4 +20,5 @@ esac
export SKBUILD_CMAKE_ARGS="-DDETECT_CONDA_ENV=OFF;-DFIND_CUGRAPH_CPP=OFF;-DCPM_cugraph-ops_SOURCE=${GITHUB_WORKSPACE}/cugraph-ops/${EXTRA_CMAKE_ARGS}"
export SKBUILD_BUILD_TOOL_ARGS="-j${PARALLEL_LEVEL};-l${PARALLEL_LEVEL}"
-./ci/build_wheel.sh pylibcugraph python/pylibcugraph
+./ci/build_wheel.sh pylibcugraph ${package_dir}
+./ci/validate_wheel.sh ${package_dir} final_dist
diff --git a/ci/release/update-version.sh b/ci/release/update-version.sh
index 5859ebde953..be1988e31dd 100755
--- a/ci/release/update-version.sh
+++ b/ci/release/update-version.sh
@@ -106,8 +106,6 @@ for FILE in .github/workflows/*.yaml; do
sed_runner "s/dask-cuda.git@branch-[0-9][0-9].[0-9][0-9]/dask-cuda.git@branch-${NEXT_SHORT_TAG}/g" "${FILE}"
done
-sed_runner "s/branch-.*/branch-${NEXT_SHORT_TAG}/g" python/nx-cugraph/README.md
-
# .devcontainer files
find .devcontainer/ -type f -name devcontainer.json -print0 | while IFS= read -r -d '' filename; do
sed_runner "s@rapidsai/devcontainers:[0-9.]*@rapidsai/devcontainers:${NEXT_SHORT_TAG}@g" "${filename}"
diff --git a/ci/run_nx_cugraph_pytests.sh b/ci/run_nx_cugraph_pytests.sh
deleted file mode 100755
index 0e309d1e2d4..00000000000
--- a/ci/run_nx_cugraph_pytests.sh
+++ /dev/null
@@ -1,10 +0,0 @@
-#!/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]}")")"/../python/nx-cugraph/nx_cugraph
-
-NX_CUGRAPH_USE_COMPAT_GRAPHS=False pytest --capture=no --cache-clear --benchmark-disable "$@" tests
-NX_CUGRAPH_USE_COMPAT_GRAPHS=True pytest --capture=no --cache-clear --benchmark-disable "$@" tests
diff --git a/ci/test_python.sh b/ci/test_python.sh
index 29b4c7be190..a3a177dcfc6 100755
--- a/ci/test_python.sh
+++ b/ci/test_python.sh
@@ -39,7 +39,6 @@ rapids-mamba-retry install \
"libcugraph=${RAPIDS_VERSION_MAJOR_MINOR}.*" \
"pylibcugraph=${RAPIDS_VERSION_MAJOR_MINOR}.*" \
"cugraph=${RAPIDS_VERSION_MAJOR_MINOR}.*" \
- "nx-cugraph=${RAPIDS_VERSION_MAJOR_MINOR}.*" \
"cugraph-service-server=${RAPIDS_VERSION_MAJOR_MINOR}.*" \
"cugraph-service-client=${RAPIDS_VERSION_MAJOR_MINOR}.*"
@@ -91,44 +90,6 @@ rapids-logger "pytest cugraph"
rapids-logger "pytest cugraph benchmarks (run as tests)"
./ci/run_cugraph_benchmark_pytests.sh --verbose
-rapids-logger "pytest nx-cugraph"
-./ci/run_nx_cugraph_pytests.sh \
- --verbose \
- --junitxml="${RAPIDS_TESTS_DIR}/junit-nx-cugraph.xml" \
- --cov-config=../../.coveragerc \
- --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 python/nx-cugraph/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 "pytest cugraph-service (single GPU)"
./ci/run_cugraph_service_pytests.sh \
--verbose \
@@ -139,109 +100,12 @@ rapids-logger "pytest cugraph-service (single GPU)"
--cov-report=xml:"${RAPIDS_COVERAGE_DIR}/cugraph-service-coverage.xml" \
--cov-report=term
-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/th23_cu118 \
- --channel nvidia \
- "libcugraph=${RAPIDS_VERSION_MAJOR_MINOR}.*" \
- "pylibcugraph=${RAPIDS_VERSION_MAJOR_MINOR}.*" \
- "pylibcugraphops=${RAPIDS_VERSION_MAJOR_MINOR}.*" \
- "cugraph=${RAPIDS_VERSION_MAJOR_MINOR}.*" \
- "cugraph-dgl=${RAPIDS_VERSION_MAJOR_MINOR}.*" \
- 'pytorch>=2.3,<2.4' \
- '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
-else
- rapids-logger "skipping cugraph_dgl pytest on CUDA!=11.8"
-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
-
- rapids-print-env
-
- # 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.3.0+cu118.html"
- #else
- # CONDA_CUDA_VERSION="12.1"
- # PYG_URL="https://data.pyg.org/whl/torch-2.3.0+cu121.html"
- #fi
-
- # Will automatically install built dependencies of cuGraph-PyG
- rapids-mamba-retry install \
- --channel "${CPP_CHANNEL}" \
- --channel "${PYTHON_CHANNEL}" \
- "cugraph-pyg=${RAPIDS_VERSION_MAJOR_MINOR}.*" \
- "pytorch>=2.3,<2.4" \
- "ogb"
-
- 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
-
# test cugraph-equivariant
if [[ "${RAPIDS_CUDA_VERSION}" == "11.8.0" ]]; then
if [[ "${RUNNER_ARCH}" != "ARM64" ]]; then
- # Reuse cugraph-dgl's test env for cugraph-equivariant
+ rapids-mamba-retry env create --yes -f env.yaml -n test_cugraph_equivariant
set +u
- conda activate test_cugraph_dgl
+ conda activate test_cugraph_equivariant
set -u
rapids-mamba-retry install \
--channel "${CPP_CHANNEL}" \
diff --git a/ci/test_wheel.sh b/ci/test_wheel.sh
index dfba25bbe1a..b5cd90996c7 100755
--- a/ci/test_wheel.sh
+++ b/ci/test_wheel.sh
@@ -10,12 +10,8 @@ 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
-if [[ "${package_name}" == "nx-cugraph" ]]; then
- RAPIDS_PY_WHEEL_NAME="${package_name}_${RAPIDS_PY_CUDA_SUFFIX}" RAPIDS_PY_WHEEL_PURE="1" rapids-download-wheels-from-s3 ./dist
-else
- RAPIDS_PY_WHEEL_NAME="${package_name}_${RAPIDS_PY_CUDA_SUFFIX}" rapids-download-wheels-from-s3 ./dist
-fi
+RAPIDS_PY_WHEEL_NAME="${package_name}_${RAPIDS_PY_CUDA_SUFFIX}" rapids-download-wheels-from-s3 ./dist
+
# use 'ls' to expand wildcard before adding `[extra]` requires for pip
# pip creates wheels using python package names
python -m pip install $(ls ./dist/${python_package_name}*.whl)[test]
@@ -36,7 +32,6 @@ else
DASK_DISTRIBUTED__SCHEDULER__WORKER_TTL="1000s" \
DASK_DISTRIBUTED__COMM__TIMEOUTS__CONNECT="1000s" \
DASK_CUDA_WAIT_WORKERS_MIN_TIMEOUT="1000s" \
- NX_CUGRAPH_USE_COMPAT_GRAPHS=False \
python -m pytest \
-v \
--import-mode=append \
diff --git a/ci/test_wheel_cugraph-dgl.sh b/ci/test_wheel_cugraph-dgl.sh
deleted file mode 100755
index d7558d43b6d..00000000000
--- a/ci/test_wheel_cugraph-dgl.sh
+++ /dev/null
@@ -1,38 +0,0 @@
-#!/bin/bash
-# Copyright (c) 2024, NVIDIA CORPORATION.
-
-set -eoxu pipefail
-
-package_name="cugraph-dgl"
-
-mkdir -p ./dist
-RAPIDS_PY_CUDA_SUFFIX="$(rapids-wheel-ctk-name-gen ${RAPIDS_CUDA_VERSION})"
-
-# Download the pylibcugraph, cugraph, and cugraph-dgl built in the previous step
-RAPIDS_PY_WHEEL_NAME="pylibcugraph_${RAPIDS_PY_CUDA_SUFFIX}" rapids-download-wheels-from-s3 ./local-deps
-RAPIDS_PY_WHEEL_NAME="cugraph_${RAPIDS_PY_CUDA_SUFFIX}" rapids-download-wheels-from-s3 ./local-deps
-RAPIDS_PY_WHEEL_NAME="${package_name}_${RAPIDS_PY_CUDA_SUFFIX}" RAPIDS_PY_WHEEL_PURE="1" rapids-download-wheels-from-s3 ./dist
-
-# determine pytorch and DGL sources
-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
- PYTORCH_CUDA_VER="121"
-else
- PYTORCH_CUDA_VER=$PKG_CUDA_VER
-fi
-PYTORCH_URL="https://download.pytorch.org/whl/cu${PYTORCH_CUDA_VER}"
-DGL_URL="https://data.dgl.ai/wheels/torch-2.3/cu${PYTORCH_CUDA_VER}/repo.html"
-
-# echo to expand wildcard before adding `[extra]` requires for pip
-python -m pip install \
- -v \
- --extra-index-url "${PYTORCH_URL}" \
- --find-links "${DGL_URL}" \
- "$(echo ./local-deps/pylibcugraph_${RAPIDS_PY_CUDA_SUFFIX}*.whl)" \
- "$(echo ./local-deps/cugraph_${RAPIDS_PY_CUDA_SUFFIX}*.whl)" \
- "$(echo ./dist/cugraph_dgl_${RAPIDS_PY_CUDA_SUFFIX}*.whl)[test]" \
- 'dgl==2.4.0' \
- 'torch>=2.3.0,<2.4'
-
-python -m pytest python/cugraph-dgl/tests
diff --git a/ci/test_wheel_cugraph-pyg.sh b/ci/test_wheel_cugraph-pyg.sh
deleted file mode 100755
index 2f508ee830b..00000000000
--- a/ci/test_wheel_cugraph-pyg.sh
+++ /dev/null
@@ -1,57 +0,0 @@
-#!/bin/bash
-# Copyright (c) 2024, NVIDIA CORPORATION.
-
-set -eoxu pipefail
-
-package_name="cugraph-pyg"
-
-mkdir -p ./dist
-RAPIDS_PY_CUDA_SUFFIX="$(rapids-wheel-ctk-name-gen ${RAPIDS_CUDA_VERSION})"
-
-# Download the pylibcugraph, cugraph, and cugraph-pyg built in the previous step
-RAPIDS_PY_WHEEL_NAME="pylibcugraph_${RAPIDS_PY_CUDA_SUFFIX}" rapids-download-wheels-from-s3 ./local-deps
-RAPIDS_PY_WHEEL_NAME="cugraph_${RAPIDS_PY_CUDA_SUFFIX}" rapids-download-wheels-from-s3 ./local-deps
-RAPIDS_PY_WHEEL_NAME="${package_name}_${RAPIDS_PY_CUDA_SUFFIX}" RAPIDS_PY_WHEEL_PURE="1" rapids-download-wheels-from-s3 ./dist
-
-# determine pytorch and pyg sources
-if [[ "${CUDA_VERSION}" == "11.8.0" ]]; then
- PYTORCH_URL="https://download.pytorch.org/whl/cu118"
- PYG_URL="https://data.pyg.org/whl/torch-2.3.0+cu118.html"
-else
- PYTORCH_URL="https://download.pytorch.org/whl/cu121"
- PYG_URL="https://data.pyg.org/whl/torch-2.3.0+cu121.html"
-fi
-
-# echo to expand wildcard before adding `[extra]` requires for pip
-python -m pip install \
- -v \
- --extra-index-url "${PYTORCH_URL}" \
- --find-links "${PYG_URL}" \
- "$(echo ./local-deps/pylibcugraph_${RAPIDS_PY_CUDA_SUFFIX}*.whl)" \
- "$(echo ./local-deps/cugraph_${RAPIDS_PY_CUDA_SUFFIX}*.whl)" \
- "$(echo ./dist/cugraph_pyg_${RAPIDS_PY_CUDA_SUFFIX}*.whl)[test]" \
- 'ogb' \
- 'pyg_lib' \
- 'torch>=2.3.0,<2.4' \
- 'torch-geometric>=2.5,<2.6' \
- 'torch_scatter' \
- 'torch_sparse'
-
-# RAPIDS_DATASET_ROOT_DIR is used by test scripts
-export RAPIDS_DATASET_ROOT_DIR="$(realpath datasets)"
-
-# Used to skip certain examples in CI due to memory limitations
-export CI_RUN=1
-
-rapids-logger "pytest cugraph-pyg (single GPU)"
-pushd python/cugraph-pyg/cugraph_pyg
-python -m pytest \
- --cache-clear \
- --benchmark-disable \
- tests
-# Test examples
-for e in "$(pwd)"/examples/*.py; do
- rapids-logger "running example $e"
- (yes || true) | python $e
-done
-popd
diff --git a/ci/test_wheel_nx-cugraph.sh b/ci/test_wheel_nx-cugraph.sh
deleted file mode 100755
index 024169ae698..00000000000
--- a/ci/test_wheel_nx-cugraph.sh
+++ /dev/null
@@ -1,11 +0,0 @@
-#!/bin/bash
-# Copyright (c) 2023-2024, NVIDIA CORPORATION.
-
-set -eoxu pipefail
-
-# Download wheels built during this job.
-RAPIDS_PY_CUDA_SUFFIX="$(rapids-wheel-ctk-name-gen ${RAPIDS_CUDA_VERSION})"
-RAPIDS_PY_WHEEL_NAME="pylibcugraph_${RAPIDS_PY_CUDA_SUFFIX}" rapids-download-wheels-from-s3 ./local-deps
-python -m pip install ./local-deps/*.whl
-
-./ci/test_wheel.sh nx-cugraph
diff --git a/ci/validate_wheel.sh b/ci/validate_wheel.sh
new file mode 100755
index 00000000000..5ebac95a3f9
--- /dev/null
+++ b/ci/validate_wheel.sh
@@ -0,0 +1,39 @@
+#!/bin/bash
+# Copyright (c) 2024, NVIDIA CORPORATION.
+
+set -euo pipefail
+
+package_dir=$1
+wheel_dir_relative_path=$2
+
+RAPIDS_CUDA_MAJOR="${RAPIDS_CUDA_VERSION%%.*}"
+
+# some packages are much larger on CUDA 11 than on CUDA 12
+if [[ "${package_dir}" == "python/cugraph" ]] || [[ "${package_dir}" == "python/pylibcugraph" ]]; then
+ if [[ "${RAPIDS_CUDA_MAJOR}" == "11" ]]; then
+ PYDISTCHECK_ARGS=(
+ --max-allowed-size-compressed '1.5G'
+ )
+ else
+ PYDISTCHECK_ARGS=(
+ --max-allowed-size-compressed '975M'
+ )
+ fi
+else
+ PYDISTCHECK_ARGS=()
+fi
+
+cd "${package_dir}"
+
+rapids-logger "validate packages with 'pydistcheck'"
+
+pydistcheck \
+ --inspect \
+ "${PYDISTCHECK_ARGS[@]}" \
+ "$(echo ${wheel_dir_relative_path}/*.whl)"
+
+rapids-logger "validate packages with 'twine'"
+
+twine check \
+ --strict \
+ "$(echo ${wheel_dir_relative_path}/*.whl)"
diff --git a/ci/wheel_smoke_test_nx-cugraph.py b/ci/wheel_smoke_test_nx-cugraph.py
deleted file mode 100644
index 10d26e3aac7..00000000000
--- a/ci/wheel_smoke_test_nx-cugraph.py
+++ /dev/null
@@ -1,38 +0,0 @@
-# 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.
-
-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/conda/environments/all_cuda-118_arch-x86_64.yaml b/conda/environments/all_cuda-118_arch-x86_64.yaml
index ec3f61d383f..e4269707168 100644
--- a/conda/environments/all_cuda-118_arch-x86_64.yaml
+++ b/conda/environments/all_cuda-118_arch-x86_64.yaml
@@ -34,7 +34,6 @@ dependencies:
- nbsphinx
- nccl>=2.19
- networkx>=2.5.1
-- networkx>=3.0
- ninja
- notebook>=0.5.0
- numba>=0.57
@@ -53,7 +52,6 @@ dependencies:
- pytest
- pytest-benchmark
- pytest-cov
-- pytest-mpl
- pytest-xdist
- python-louvain
- pytorch>=2.3,<2.4.0a0
diff --git a/conda/environments/all_cuda-125_arch-x86_64.yaml b/conda/environments/all_cuda-125_arch-x86_64.yaml
index ff42bbbc365..eb2625b9d50 100644
--- a/conda/environments/all_cuda-125_arch-x86_64.yaml
+++ b/conda/environments/all_cuda-125_arch-x86_64.yaml
@@ -40,7 +40,6 @@ dependencies:
- nbsphinx
- nccl>=2.19
- networkx>=2.5.1
-- networkx>=3.0
- ninja
- notebook>=0.5.0
- numba>=0.57
@@ -58,7 +57,6 @@ dependencies:
- pytest
- pytest-benchmark
- pytest-cov
-- pytest-mpl
- pytest-xdist
- python-louvain
- pytorch>=2.3,<2.4.0a0
diff --git a/conda/recipes/cugraph/meta.yaml b/conda/recipes/cugraph/meta.yaml
index 9f5a137faba..5a13ba30fd0 100644
--- a/conda/recipes/cugraph/meta.yaml
+++ b/conda/recipes/cugraph/meta.yaml
@@ -75,10 +75,10 @@ requirements:
- {{ pin_compatible('cuda-version', max_pin='x', min_pin='x') }}
{% if cuda_major == "11" %}
- cudatoolkit
- - cuda-python >=11.7.1,<12.0a0
+ - cuda-python >=11.7.1,<12.0a0,<=11.8.3
{% else %}
- cuda-cudart
- - cuda-python >=12.0,<13.0a0
+ - cuda-python >=12.0,<13.0a0,<=12.6.0
{% endif %}
- cudf ={{ minor_version }}
- cupy >=12.0.0
diff --git a/conda/recipes/nx-cugraph/build.sh b/conda/recipes/nx-cugraph/build.sh
deleted file mode 100644
index 26665c1e76a..00000000000
--- a/conda/recipes/nx-cugraph/build.sh
+++ /dev/null
@@ -1,7 +0,0 @@
-#!/usr/bin/env bash
-
-# Copyright (c) 2023, NVIDIA CORPORATION.
-
-# This assumes the script is executed from the root of the repo directory
-
-./build.sh nx-cugraph
diff --git a/conda/recipes/nx-cugraph/meta.yaml b/conda/recipes/nx-cugraph/meta.yaml
deleted file mode 100644
index 263f53d9a8f..00000000000
--- a/conda/recipes/nx-cugraph/meta.yaml
+++ /dev/null
@@ -1,43 +0,0 @@
-# Copyright (c) 2023-2024, NVIDIA CORPORATION.
-
-{% set version = environ['RAPIDS_PACKAGE_VERSION'].lstrip('v') + environ.get('VERSION_SUFFIX', '') %}
-{% set minor_version = version.split('.')[0] + '.' + version.split('.')[1] %}
-{% set py_version = environ['CONDA_PY'] %}
-{% set date_string = environ['RAPIDS_DATE_STRING'] %}
-
-package:
- name: nx-cugraph
- version: {{ version }}
-
-source:
- path: ../../..
-
-build:
- number: {{ GIT_DESCRIBE_NUMBER }}
- string: py{{ py_version }}_{{ date_string }}_{{ GIT_DESCRIBE_HASH }}_{{ GIT_DESCRIBE_NUMBER }}
-
-requirements:
- host:
- - python
- - rapids-build-backend>=0.3.1,<0.4.0.dev0
- - setuptools>=61.0.0
- run:
- - pylibcugraph ={{ version }}
- - networkx >=3.0
- - cupy >=12.0.0
- - python
-
-tests:
- imports:
- - nx_cugraph
- commands:
- - pip check
- requires:
- - pip
-
-about:
- home: https://rapids.ai/
- dev_url: https://github.com/rapidsai/cugraph
- license: Apache-2.0
- license_file: ../../../LICENSE
- summary: cuGraph backend for GPU-accelerated NetworkX
diff --git a/cpp/CMakeLists.txt b/cpp/CMakeLists.txt
index b8eaba9d575..27e1999cb75 100644
--- a/cpp/CMakeLists.txt
+++ b/cpp/CMakeLists.txt
@@ -54,17 +54,11 @@ option(BUILD_SHARED_LIBS "Build cuGraph shared libraries" ON)
option(BUILD_CUGRAPH_MG_TESTS "Build cuGraph multigpu algorithm tests" OFF)
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(USE_CUGRAPH_OPS "Enable all functions that call cugraph-ops" ON)
option(USE_RAFT_STATIC "Build raft as a static library" OFF)
option(CUGRAPH_COMPILE_RAFT_LIB "Compile the raft library instead of using it header-only" ON)
option(CUDA_STATIC_RUNTIME "Statically link the CUDA toolkit runtime and libraries" OFF)
-option(CUGRAPH_USE_CUGRAPH_OPS_STATIC "Build and statically link the cugraph-ops library" OFF)
-option(CUGRAPH_EXCLUDE_CUGRAPH_OPS_FROM_ALL "Exclude cugraph-ops targets from cuGraph's 'all' target" OFF)
-option(ALLOW_CLONE_CUGRAPH_OPS "Whether to attempt to clone cugraph-ops when a local version is not available" OFF)
message(VERBOSE "CUGRAPH: CUDA_STATIC_RUNTIME=${CUDA_STATIC_RUNTIME}")
-message(VERBOSE "CUGRAPH: CUGRAPH_USE_CUGRAPH_OPS_STATIC=${CUGRAPH_USE_CUGRAPH_OPS_STATIC}")
-message(VERBOSE "CUGRAPH: CUGRAPH_EXCLUDE_CUGRAPH_OPS_FROM_ALL=${CUGRAPH_EXCLUDE_CUGRAPH_OPS_FROM_ALL}")
################################################################################
# - compiler options -----------------------------------------------------------
@@ -115,13 +109,6 @@ if(CMAKE_BUILD_TYPE MATCHES Debug)
list(APPEND CUGRAPH_CUDA_FLAGS -G -Xcompiler=-rdynamic)
endif()
-if(NOT USE_CUGRAPH_OPS)
- message(STATUS "Disabling functions that reference cugraph-ops")
- list(APPEND CUGRAPH_C_FLAGS -DNO_CUGRAPH_OPS)
- list(APPEND CUGRAPH_CXX_FLAGS -DNO_CUGRAPH_OPS)
- list(APPEND CUGRAPH_CUDA_FLAGS -DNO_CUGRAPH_OPS)
-endif()
-
###################################################################################################
# - find CPM based dependencies ------------------------------------------------------------------
@@ -151,10 +138,6 @@ include(${rapids-cmake-dir}/cpm/cuco.cmake)
rapids_cpm_cuco(BUILD_EXPORT_SET cugraph-exports INSTALL_EXPORT_SET cugraph-exports)
include(cmake/thirdparty/get_raft.cmake)
-if(USE_CUGRAPH_OPS)
- include(cmake/thirdparty/get_libcugraphops.cmake)
-endif()
-
if(BUILD_TESTS)
include(${rapids-cmake-dir}/cpm/gtest.cmake)
rapids_cpm_gtest(BUILD_STATIC)
@@ -175,56 +158,41 @@ set(CUGRAPH_SOURCES
src/detail/permute_range_v32.cu
src/detail/permute_range_v64.cu
src/utilities/shuffle_vertex_pairs_mg_v32_e32.cu
- src/utilities/shuffle_vertex_pairs_mg_v32_e64.cu
src/utilities/shuffle_vertex_pairs_mg_v64_e64.cu
src/detail/collect_local_vertex_values_sg_v32_e32.cu
- src/detail/collect_local_vertex_values_sg_v32_e64.cu
src/detail/collect_local_vertex_values_sg_v64_e64.cu
src/detail/collect_local_vertex_values_mg_v32_e32.cu
- src/detail/collect_local_vertex_values_mg_v32_e64.cu
src/detail/collect_local_vertex_values_mg_v64_e64.cu
src/detail/groupby_and_count_mg_v32_e32.cu
- src/detail/groupby_and_count_mg_v32_e64.cu
src/detail/groupby_and_count_mg_v64_e64.cu
src/detail/collect_comm_wrapper_mg_v32_e32.cu
src/detail/collect_comm_wrapper_mg_v64_e64.cu
+ src/sampling/detail/conversion_utilities.cu
src/sampling/random_walks_mg_v64_e64.cu
src/sampling/random_walks_mg_v32_e32.cu
- src/sampling/random_walks_mg_v32_e64.cu
src/community/detail/common_methods_mg_v64_e64.cu
src/community/detail/common_methods_mg_v32_e32.cu
- src/community/detail/common_methods_mg_v32_e64.cu
src/community/detail/common_methods_sg_v64_e64.cu
src/community/detail/common_methods_sg_v32_e32.cu
- src/community/detail/common_methods_sg_v32_e64.cu
src/community/detail/refine_sg_v64_e64.cu
src/community/detail/refine_sg_v32_e32.cu
- src/community/detail/refine_sg_v32_e64.cu
src/community/detail/refine_mg_v64_e64.cu
src/community/detail/refine_mg_v32_e32.cu
- src/community/detail/refine_mg_v32_e64.cu
src/community/edge_triangle_count_sg_v64_e64.cu
src/community/edge_triangle_count_sg_v32_e32.cu
- src/community/edge_triangle_count_sg_v32_e64.cu
src/community/edge_triangle_count_mg_v64_e64.cu
src/community/edge_triangle_count_mg_v32_e32.cu
- src/community/edge_triangle_count_mg_v32_e64.cu
src/community/detail/maximal_independent_moves_sg_v64_e64.cu
src/community/detail/maximal_independent_moves_sg_v32_e32.cu
- src/community/detail/maximal_independent_moves_sg_v32_e64.cu
src/community/detail/maximal_independent_moves_mg_v64_e64.cu
src/community/detail/maximal_independent_moves_mg_v32_e32.cu
- src/community/detail/maximal_independent_moves_mg_v32_e64.cu
src/detail/utility_wrappers_32.cu
src/detail/utility_wrappers_64.cu
src/structure/graph_view_mg_v64_e64.cu
src/structure/graph_view_mg_v32_e32.cu
- src/structure/graph_view_mg_v32_e64.cu
src/structure/remove_self_loops_sg_v32_e32.cu
- src/structure/remove_self_loops_sg_v32_e64.cu
src/structure/remove_self_loops_sg_v64_e64.cu
src/structure/remove_multi_edges_sg_v32_e32.cu
- src/structure/remove_multi_edges_sg_v32_e64.cu
src/structure/remove_multi_edges_sg_v64_e64.cu
src/utilities/path_retrieval_sg_v32_e32.cu
src/utilities/path_retrieval_sg_v64_e64.cu
@@ -232,127 +200,89 @@ set(CUGRAPH_SOURCES
src/linear_assignment/legacy/hungarian.cu
src/link_prediction/jaccard_sg_v64_e64.cu
src/link_prediction/jaccard_sg_v32_e32.cu
- src/link_prediction/jaccard_sg_v32_e64.cu
src/link_prediction/sorensen_sg_v64_e64.cu
src/link_prediction/sorensen_sg_v32_e32.cu
- src/link_prediction/sorensen_sg_v32_e64.cu
src/link_prediction/overlap_sg_v64_e64.cu
src/link_prediction/overlap_sg_v32_e32.cu
- src/link_prediction/overlap_sg_v32_e64.cu
src/link_prediction/cosine_sg_v64_e64.cu
src/link_prediction/cosine_sg_v32_e32.cu
- src/link_prediction/cosine_sg_v32_e64.cu
src/link_prediction/jaccard_mg_v64_e64.cu
src/link_prediction/jaccard_mg_v32_e32.cu
- src/link_prediction/jaccard_mg_v32_e64.cu
src/link_prediction/sorensen_mg_v64_e64.cu
src/link_prediction/sorensen_mg_v32_e32.cu
- src/link_prediction/sorensen_mg_v32_e64.cu
src/link_prediction/overlap_mg_v64_e64.cu
src/link_prediction/overlap_mg_v32_e32.cu
- src/link_prediction/overlap_mg_v32_e64.cu
src/link_prediction/cosine_mg_v64_e64.cu
src/link_prediction/cosine_mg_v32_e32.cu
- src/link_prediction/cosine_mg_v32_e64.cu
src/layout/legacy/force_atlas2.cu
src/converters/legacy/COOtoCSR.cu
src/community/legacy/spectral_clustering.cu
src/community/louvain_sg_v64_e64.cu
src/community/louvain_sg_v32_e32.cu
- src/community/louvain_sg_v32_e64.cu
src/community/louvain_mg_v64_e64.cu
src/community/louvain_mg_v32_e32.cu
- src/community/louvain_mg_v32_e64.cu
src/community/leiden_sg_v64_e64.cu
src/community/leiden_sg_v32_e32.cu
- src/community/leiden_sg_v32_e64.cu
src/community/leiden_mg_v64_e64.cu
src/community/leiden_mg_v32_e32.cu
- src/community/leiden_mg_v32_e64.cu
src/community/ecg_sg_v64_e64.cu
src/community/ecg_sg_v32_e32.cu
- src/community/ecg_sg_v32_e64.cu
src/community/ecg_mg_v64_e64.cu
src/community/ecg_mg_v32_e32.cu
- src/community/ecg_mg_v32_e64.cu
src/community/egonet_sg_v64_e64.cu
src/community/egonet_sg_v32_e32.cu
- src/community/egonet_sg_v32_e64.cu
src/community/egonet_mg_v64_e64.cu
src/community/egonet_mg_v32_e32.cu
- src/community/egonet_mg_v32_e64.cu
src/community/k_truss_sg_v64_e64.cu
src/community/k_truss_sg_v32_e32.cu
- src/community/k_truss_sg_v32_e64.cu
src/community/k_truss_mg_v64_e64.cu
src/community/k_truss_mg_v32_e32.cu
- src/community/k_truss_mg_v32_e64.cu
src/lookup/lookup_src_dst_mg_v32_e32.cu
- src/lookup/lookup_src_dst_mg_v32_e64.cu
src/lookup/lookup_src_dst_mg_v64_e64.cu
src/lookup/lookup_src_dst_sg_v32_e32.cu
- src/lookup/lookup_src_dst_sg_v32_e64.cu
src/lookup/lookup_src_dst_sg_v64_e64.cu
src/sampling/random_walks_old_sg_v32_e32.cu
- src/sampling/random_walks_old_sg_v32_e64.cu
src/sampling/random_walks_old_sg_v64_e64.cu
src/sampling/random_walks_sg_v64_e64.cu
src/sampling/random_walks_sg_v32_e32.cu
- src/sampling/random_walks_sg_v32_e64.cu
src/sampling/detail/prepare_next_frontier_sg_v64_e64.cu
src/sampling/detail/prepare_next_frontier_sg_v32_e32.cu
src/sampling/detail/prepare_next_frontier_mg_v64_e64.cu
src/sampling/detail/prepare_next_frontier_mg_v32_e32.cu
src/sampling/detail/gather_one_hop_edgelist_sg_v64_e64.cu
src/sampling/detail/gather_one_hop_edgelist_sg_v32_e32.cu
- src/sampling/detail/gather_one_hop_edgelist_sg_v32_e64.cu
src/sampling/detail/gather_one_hop_edgelist_mg_v64_e64.cu
src/sampling/detail/gather_one_hop_edgelist_mg_v32_e32.cu
- src/sampling/detail/gather_one_hop_edgelist_mg_v32_e64.cu
src/sampling/detail/remove_visited_vertices_from_frontier_sg_v32_e32.cu
src/sampling/detail/remove_visited_vertices_from_frontier_sg_v64_e64.cu
src/sampling/detail/check_edge_bias_values_sg_v64_e64.cu
src/sampling/detail/check_edge_bias_values_sg_v32_e32.cu
- src/sampling/detail/check_edge_bias_values_sg_v32_e64.cu
src/sampling/detail/check_edge_bias_values_mg_v64_e64.cu
src/sampling/detail/check_edge_bias_values_mg_v32_e32.cu
- src/sampling/detail/check_edge_bias_values_mg_v32_e64.cu
src/sampling/detail/sample_edges_sg_v64_e64.cu
src/sampling/detail/sample_edges_sg_v32_e32.cu
- src/sampling/detail/sample_edges_sg_v32_e64.cu
src/sampling/detail/sample_edges_mg_v64_e64.cu
src/sampling/detail/sample_edges_mg_v32_e32.cu
- src/sampling/detail/sample_edges_mg_v32_e64.cu
src/sampling/detail/shuffle_and_organize_output_mg_v64_e64.cu
src/sampling/detail/shuffle_and_organize_output_mg_v32_e32.cu
- src/sampling/detail/shuffle_and_organize_output_mg_v32_e64.cu
- src/sampling/neighbor_sampling_mg_v32_e64.cpp
- src/sampling/neighbor_sampling_mg_v32_e32.cpp
- src/sampling/neighbor_sampling_mg_v64_e64.cpp
- src/sampling/neighbor_sampling_sg_v32_e64.cpp
- src/sampling/neighbor_sampling_sg_v32_e32.cpp
- src/sampling/neighbor_sampling_sg_v64_e64.cpp
- src/sampling/negative_sampling_sg_v32_e64.cu
+ src/sampling/neighbor_sampling_mg_v32_e32.cu
+ src/sampling/neighbor_sampling_mg_v64_e64.cu
+ src/sampling/neighbor_sampling_sg_v32_e32.cu
+ src/sampling/neighbor_sampling_sg_v64_e64.cu
src/sampling/negative_sampling_sg_v32_e32.cu
src/sampling/negative_sampling_sg_v64_e64.cu
- src/sampling/negative_sampling_mg_v32_e64.cu
src/sampling/negative_sampling_mg_v32_e32.cu
src/sampling/negative_sampling_mg_v64_e64.cu
src/sampling/sampling_post_processing_sg_v64_e64.cu
src/sampling/sampling_post_processing_sg_v32_e32.cu
- src/sampling/sampling_post_processing_sg_v32_e64.cu
src/cores/core_number_sg_v64_e64.cu
src/cores/core_number_sg_v32_e32.cu
- src/cores/core_number_sg_v32_e64.cu
src/cores/core_number_mg_v64_e64.cu
src/cores/core_number_mg_v32_e32.cu
- src/cores/core_number_mg_v32_e64.cu
src/cores/k_core_sg_v64_e64.cu
src/cores/k_core_sg_v32_e32.cu
- src/cores/k_core_sg_v32_e64.cu
src/cores/k_core_mg_v64_e64.cu
src/cores/k_core_mg_v32_e32.cu
- src/cores/k_core_mg_v32_e64.cu
src/components/legacy/connectivity.cu
src/generators/generate_rmat_edgelist_sg_v32_e32.cu
src/generators/generate_rmat_edgelist_sg_v64_e64.cu
@@ -366,55 +296,38 @@ set(CUGRAPH_SOURCES
src/generators/erdos_renyi_generator_sg_v64_e64.cu
src/structure/graph_sg_v64_e64.cu
src/structure/graph_sg_v32_e32.cu
- src/structure/graph_sg_v32_e64.cu
src/structure/graph_mg_v64_e64.cu
src/structure/graph_mg_v32_e32.cu
- src/structure/graph_mg_v32_e64.cu
src/structure/graph_view_sg_v64_e64.cu
src/structure/graph_view_sg_v32_e32.cu
- src/structure/graph_view_sg_v32_e64.cu
src/structure/decompress_to_edgelist_sg_v64_e64.cu
src/structure/decompress_to_edgelist_sg_v32_e32.cu
- src/structure/decompress_to_edgelist_sg_v32_e64.cu
src/structure/decompress_to_edgelist_mg_v64_e64.cu
src/structure/decompress_to_edgelist_mg_v32_e32.cu
- src/structure/decompress_to_edgelist_mg_v32_e64.cu
src/structure/symmetrize_graph_sg_v64_e64.cu
src/structure/symmetrize_graph_sg_v32_e32.cu
- src/structure/symmetrize_graph_sg_v32_e64.cu
src/structure/symmetrize_graph_mg_v64_e64.cu
src/structure/symmetrize_graph_mg_v32_e32.cu
- src/structure/symmetrize_graph_mg_v32_e64.cu
src/structure/transpose_graph_sg_v64_e64.cu
src/structure/transpose_graph_sg_v32_e32.cu
- src/structure/transpose_graph_sg_v32_e64.cu
src/structure/transpose_graph_mg_v64_e64.cu
src/structure/transpose_graph_mg_v32_e32.cu
- src/structure/transpose_graph_mg_v32_e64.cu
src/structure/transpose_graph_storage_sg_v64_e64.cu
src/structure/transpose_graph_storage_sg_v32_e32.cu
- src/structure/transpose_graph_storage_sg_v32_e64.cu
src/structure/transpose_graph_storage_mg_v64_e64.cu
src/structure/transpose_graph_storage_mg_v32_e32.cu
- src/structure/transpose_graph_storage_mg_v32_e64.cu
src/structure/coarsen_graph_sg_v64_e64.cu
src/structure/coarsen_graph_sg_v32_e32.cu
- src/structure/coarsen_graph_sg_v32_e64.cu
src/structure/coarsen_graph_mg_v64_e64.cu
src/structure/coarsen_graph_mg_v32_e32.cu
- src/structure/coarsen_graph_mg_v32_e64.cu
src/structure/graph_weight_utils_mg_v64_e64.cu
src/structure/graph_weight_utils_mg_v32_e32.cu
- src/structure/graph_weight_utils_mg_v32_e64.cu
src/structure/graph_weight_utils_sg_v64_e64.cu
src/structure/graph_weight_utils_sg_v32_e32.cu
- src/structure/graph_weight_utils_sg_v32_e64.cu
src/structure/renumber_edgelist_sg_v64_e64.cu
src/structure/renumber_edgelist_sg_v32_e32.cu
- src/structure/renumber_edgelist_sg_v32_e64.cu
src/structure/renumber_edgelist_mg_v64_e64.cu
src/structure/renumber_edgelist_mg_v32_e32.cu
- src/structure/renumber_edgelist_mg_v32_e64.cu
src/structure/renumber_utils_sg_v64_e64.cu
src/structure/renumber_utils_sg_v32_e32.cu
src/structure/renumber_utils_mg_v64_e64.cu
@@ -425,115 +338,80 @@ set(CUGRAPH_SOURCES
src/structure/relabel_mg_v32_e32.cu
src/structure/induced_subgraph_sg_v64_e64.cu
src/structure/induced_subgraph_sg_v32_e32.cu
- src/structure/induced_subgraph_sg_v32_e64.cu
src/structure/induced_subgraph_mg_v64_e64.cu
src/structure/induced_subgraph_mg_v32_e32.cu
- src/structure/induced_subgraph_mg_v32_e64.cu
src/structure/select_random_vertices_sg_v64_e64.cu
src/structure/select_random_vertices_sg_v32_e32.cu
- src/structure/select_random_vertices_sg_v32_e64.cu
src/structure/select_random_vertices_mg_v64_e64.cu
src/structure/select_random_vertices_mg_v32_e32.cu
- src/structure/select_random_vertices_mg_v32_e64.cu
src/traversal/extract_bfs_paths_sg_v64_e64.cu
src/traversal/extract_bfs_paths_sg_v32_e32.cu
- src/traversal/extract_bfs_paths_sg_v32_e64.cu
src/traversal/extract_bfs_paths_mg_v64_e64.cu
src/traversal/extract_bfs_paths_mg_v32_e32.cu
- src/traversal/extract_bfs_paths_mg_v32_e64.cu
src/traversal/bfs_sg_v64_e64.cu
src/traversal/bfs_sg_v32_e32.cu
- src/traversal/bfs_sg_v32_e64.cu
src/traversal/bfs_mg_v64_e64.cu
src/traversal/bfs_mg_v32_e32.cu
- src/traversal/bfs_mg_v32_e64.cu
src/traversal/sssp_sg_v64_e64.cu
src/traversal/sssp_sg_v32_e32.cu
- src/traversal/sssp_sg_v32_e64.cu
src/traversal/od_shortest_distances_sg_v64_e64.cu
src/traversal/od_shortest_distances_sg_v32_e32.cu
- src/traversal/od_shortest_distances_sg_v32_e64.cu
src/traversal/sssp_mg_v64_e64.cu
src/traversal/sssp_mg_v32_e32.cu
- src/traversal/sssp_mg_v32_e64.cu
src/link_analysis/hits_sg_v64_e64.cu
src/link_analysis/hits_sg_v32_e32.cu
- src/link_analysis/hits_sg_v32_e64.cu
src/link_analysis/hits_mg_v64_e64.cu
src/link_analysis/hits_mg_v32_e32.cu
- src/link_analysis/hits_mg_v32_e64.cu
src/link_analysis/pagerank_sg_v64_e64.cu
src/link_analysis/pagerank_sg_v32_e32.cu
- src/link_analysis/pagerank_sg_v32_e64.cu
src/link_analysis/pagerank_mg_v64_e64.cu
src/link_analysis/pagerank_mg_v32_e32.cu
- src/link_analysis/pagerank_mg_v32_e64.cu
src/centrality/katz_centrality_sg_v64_e64.cu
src/centrality/katz_centrality_sg_v32_e32.cu
- src/centrality/katz_centrality_sg_v32_e64.cu
src/centrality/katz_centrality_mg_v64_e64.cu
src/centrality/katz_centrality_mg_v32_e32.cu
- src/centrality/katz_centrality_mg_v32_e64.cu
src/centrality/eigenvector_centrality_sg_v64_e64.cu
src/centrality/eigenvector_centrality_sg_v32_e32.cu
- src/centrality/eigenvector_centrality_sg_v32_e64.cu
src/centrality/eigenvector_centrality_mg_v64_e64.cu
src/centrality/eigenvector_centrality_mg_v32_e32.cu
- src/centrality/eigenvector_centrality_mg_v32_e64.cu
src/centrality/betweenness_centrality_sg_v64_e64.cu
src/centrality/betweenness_centrality_sg_v32_e32.cu
- src/centrality/betweenness_centrality_sg_v32_e64.cu
src/centrality/betweenness_centrality_mg_v64_e64.cu
src/centrality/betweenness_centrality_mg_v32_e32.cu
- src/centrality/betweenness_centrality_mg_v32_e64.cu
src/tree/legacy/mst.cu
src/from_cugraph_ops/sampling_index.cu
src/components/weakly_connected_components_sg_v64_e64.cu
src/components/weakly_connected_components_sg_v32_e32.cu
- src/components/weakly_connected_components_sg_v32_e64.cu
src/components/weakly_connected_components_mg_v64_e64.cu
src/components/weakly_connected_components_mg_v32_e32.cu
- src/components/weakly_connected_components_mg_v32_e64.cu
src/components/mis_sg_v64_e64.cu
src/components/mis_sg_v32_e32.cu
- src/components/mis_sg_v32_e64.cu
src/components/mis_mg_v64_e64.cu
src/components/mis_mg_v32_e32.cu
- src/components/mis_mg_v32_e64.cu
src/components/vertex_coloring_sg_v64_e64.cu
src/components/vertex_coloring_sg_v32_e32.cu
- src/components/vertex_coloring_sg_v32_e64.cu
src/components/vertex_coloring_mg_v64_e64.cu
src/components/vertex_coloring_mg_v32_e32.cu
- src/components/vertex_coloring_mg_v32_e64.cu
src/structure/create_graph_from_edgelist_sg_v64_e64.cu
src/structure/create_graph_from_edgelist_sg_v32_e32.cu
- src/structure/create_graph_from_edgelist_sg_v32_e64.cu
src/structure/create_graph_from_edgelist_mg_v64_e64.cu
src/structure/create_graph_from_edgelist_mg_v32_e32.cu
- src/structure/create_graph_from_edgelist_mg_v32_e64.cu
src/structure/symmetrize_edgelist_sg_v64_e64.cu
src/structure/symmetrize_edgelist_sg_v32_e32.cu
src/structure/symmetrize_edgelist_mg_v64_e64.cu
src/structure/symmetrize_edgelist_mg_v32_e32.cu
src/community/triangle_count_sg_v64_e64.cu
src/community/triangle_count_sg_v32_e32.cu
- src/community/triangle_count_sg_v32_e64.cu
src/community/triangle_count_mg_v64_e64.cu
src/community/triangle_count_mg_v32_e32.cu
- src/community/triangle_count_mg_v32_e64.cu
src/community/approx_weighted_matching_sg_v64_e64.cu
src/community/approx_weighted_matching_sg_v32_e32.cu
- src/community/approx_weighted_matching_sg_v32_e64.cu
src/community/approx_weighted_matching_mg_v64_e64.cu
src/community/approx_weighted_matching_mg_v32_e32.cu
- src/community/approx_weighted_matching_mg_v32_e64.cu
src/traversal/k_hop_nbrs_sg_v64_e64.cu
src/traversal/k_hop_nbrs_sg_v32_e32.cu
- src/traversal/k_hop_nbrs_sg_v32_e64.cu
src/traversal/k_hop_nbrs_mg_v64_e64.cu
src/traversal/k_hop_nbrs_mg_v32_e32.cu
- src/traversal/k_hop_nbrs_mg_v32_e64.cu
src/mtmg/vertex_result_sg_v32_e32.cu
src/mtmg/vertex_result_sg_v64_e64.cu
src/mtmg/vertex_result_mg_v32_e32.cu
@@ -544,12 +422,6 @@ set(CUGRAPH_SOURCES
src/mtmg/vertex_pairs_result_mg_v64_e64.cu
)
-if(USE_CUGRAPH_OPS)
- list(APPEND CUGRAPH_SOURCES
- src/sampling/neighborhood.cu
- )
-endif()
-
add_library(cugraph ${CUGRAPH_SOURCES})
set_target_properties(cugraph
diff --git a/cpp/cmake/thirdparty/get_libcugraphops.cmake b/cpp/cmake/thirdparty/get_libcugraphops.cmake
deleted file mode 100644
index b10af300a98..00000000000
--- a/cpp/cmake/thirdparty/get_libcugraphops.cmake
+++ /dev/null
@@ -1,83 +0,0 @@
-#=============================================================================
-# Copyright (c) 2022, 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.
-#=============================================================================
-
-set(CUGRAPH_MIN_VERSION_cugraph_ops "${CUGRAPH_VERSION_MAJOR}.${CUGRAPH_VERSION_MINOR}.00")
-
-if(NOT DEFINED CUGRAPH_CUGRAPH_OPS_VERSION)
- set(CUGRAPH_CUGRAPH_OPS_VERSION "${CUGRAPH_VERSION_MAJOR}.${CUGRAPH_VERSION_MINOR}")
-endif()
-
-if(NOT DEFINED CUGRAPH_CUGRAPH_OPS_BRANCH)
- set(CUGRAPH_CUGRAPH_OPS_BRANCH "branch-${CUGRAPH_CUGRAPH_OPS_VERSION}")
-endif()
-
-if(NOT DEFINED CUGRAPH_CUGRAPH_OPS_REPOSITORY)
- set(CUGRAPH_CUGRAPH_OPS_REPOSITORY "git@github.com:rapidsai/cugraph-ops.git")
-endif()
-
-function(find_and_configure_cugraph_ops)
-
- set(oneValueArgs VERSION REPO PINNED_TAG BUILD_STATIC EXCLUDE_FROM_ALL ALLOW_CLONE_CUGRAPH_OPS)
- cmake_parse_arguments(PKG "" "${oneValueArgs}" "" ${ARGN})
-
- if(PKG_ALLOW_CLONE_CUGRAPH_OPS)
- if(NOT PKG_PINNED_TAG STREQUAL "branch-${CUGRAPH_CUGRAPH_OPS_VERSION}")
- message("Pinned tag found: ${PKG_PINNED_TAG}. Cloning cugraph-ops locally.")
- set(CPM_DOWNLOAD_cugraph-ops ON)
- elseif(PKG_BUILD_STATIC AND (NOT CPM_cugraph-ops_SOURCE))
- message(STATUS "CUGRAPH: Cloning cugraph-ops locally to build static libraries.")
- set(CPM_DOWNLOAD_cugraph-ops ON)
- endif()
- endif()
-
- set(CUGRAPH_OPS_BUILD_SHARED_LIBS ON)
- if(PKG_BUILD_STATIC)
- set(CUGRAPH_OPS_BUILD_SHARED_LIBS OFF)
- endif()
-
- rapids_cpm_find(cugraph-ops ${PKG_VERSION} REQUIRED
- GLOBAL_TARGETS cugraph-ops::cugraph-ops++
- BUILD_EXPORT_SET cugraph-exports
- INSTALL_EXPORT_SET cugraph-exports
- CPM_ARGS
- SOURCE_SUBDIR cpp
- GIT_REPOSITORY ${PKG_REPO}
- GIT_TAG ${PKG_PINNED_TAG}
- EXCLUDE_FROM_ALL ${PKG_EXCLUDE_FROM_ALL}
- OPTIONS
- "BUILD_CUGRAPH_OPS_CPP_TESTS OFF"
- "BUILD_SHARED_LIBS ${CUGRAPH_OPS_BUILD_SHARED_LIBS}"
- )
-endfunction()
-
-###
-# Change pinned tag and fork here to test a commit in CI
-#
-# To use a locally-built cugraph-ops package, set the CMake variable
-# `-D cugraph-ops_ROOT=/path/to/cugraph-ops/build`
-###
-find_and_configure_cugraph_ops(VERSION ${CUGRAPH_MIN_VERSION_cugraph_ops}
- REPO ${CUGRAPH_CUGRAPH_OPS_REPOSITORY}
- PINNED_TAG ${CUGRAPH_CUGRAPH_OPS_BRANCH}
- BUILD_STATIC ${CUGRAPH_USE_CUGRAPH_OPS_STATIC}
- EXCLUDE_FROM_ALL ${CUGRAPH_EXCLUDE_CUGRAPH_OPS_FROM_ALL}
- # Allow cloning cugraph-ops in cases when we
- # expect the local copy of cugraph-ops to not be
- # the one that we want. Cases include static
- # linking such that we need to compile a static
- # lib or during development when using a
- # different branch of cugraph-ops.
- ALLOW_CLONE_CUGRAPH_OPS ${ALLOW_CLONE_CUGRAPH_OPS})
diff --git a/cpp/include/cugraph/algorithms.hpp b/cpp/include/cugraph/algorithms.hpp
index 7e5af4ac686..60f4d21822f 100644
--- a/cpp/include/cugraph/algorithms.hpp
+++ b/cpp/include/cugraph/algorithms.hpp
@@ -23,16 +23,12 @@
#include
#include
-#include
-
-#ifndef NO_CUGRAPH_OPS
-#include
-#endif
-
#include
#include
#include
+#include
+
#include
#include
@@ -1678,72 +1674,6 @@ node2vec_random_walks(raft::handle_t const& handle,
weight_t p,
weight_t q);
-#ifndef NO_CUGRAPH_OPS
-/**
- * @brief generate sub-sampled graph as an adjacency list (CSR format) given input graph,
- * list of vertices and sample size per vertex. The output graph consists of the given
- * vertices with each vertex having at most `sample_size` neighbors from the original graph
- *
- * @deprecated This API will be deprecated. uniform_neighbor_sample can be used instead.
- *
- * @tparam graph_t Type of input graph/view (typically, graph_view_t, non-transposed and
- * single-gpu).
- * @param handle RAFT handle object to encapsulate resources (e.g. CUDA stream, communicator, and
- * handles to various CUDA libraries) to run graph algorithms.
- * @param rng_state The RngState instance holding pseudo-random number generator state.
- * @param graph Graph (view )object to sub-sample.
- * @param ptr_d_start Device pointer to set of starting vertex indices for the sub-sampling.
- * @param num_start_vertices = number(vertices) to use for sub-sampling.
- * @param sampling_size = max number of neighbors per output vertex.
- * @param sampling_algo = the sampling algorithm (algo R/algo L/etc.) used to produce outputs.
- * @return std::tuple,
- * rmm::device_uvector>
- * Tuple consisting of two arrays representing the offsets and indices of
- * the sub-sampled graph.
- */
-template
-std::tuple, rmm::device_uvector>
-sample_neighbors_adjacency_list(raft::handle_t const& handle,
- raft::random::RngState& rng_state,
- graph_view_t const& graph_view,
- vertex_t const* ptr_d_start,
- size_t num_start_vertices,
- size_t sampling_size,
- ops::graph::SamplingAlgoT sampling_algo);
-
-/**
- * @brief generate sub-sampled graph as an edge list (COO format) given input graph,
- * list of vertices and sample size per vertex. The output graph consists of the given
- * vertices with each vertex having at most `sample_size` neighbors from the original graph
- *
- * @deprecated This API will be deprecated. uniform_neighbor_sample can be used instead.
- *
- * @tparam graph_t Type of input graph/view (typically, graph_view_t, non-transposed and
- * single-gpu).
- * @param handle RAFT handle object to encapsulate resources (e.g. CUDA stream, communicator, and
- * handles to various CUDA libraries) to run graph algorithms.
- * @param rng_state The RngState instance holding pseudo-random number generator state.
- * @param graph Graph (view )object to sub-sample.
- * @param ptr_d_start Device pointer to set of starting vertex indices for the sub-sampling.
- * @param num_start_vertices = number(vertices) to use for sub-sampling.
- * @param sampling_size = max number of neighbors per output vertex.
- * @param sampling_algo = the sampling algorithm (algo R/algo L/etc.) used to produce outputs.
- * @return std::tuple,
- * rmm::device_uvector>
- * Tuple consisting of two arrays representing the source and destination nodes of
- * the sub-sampled graph.
- */
-template
-std::tuple, rmm::device_uvector> sample_neighbors_edgelist(
- raft::handle_t const& handle,
- raft::random::RngState& rng_state,
- graph_view_t const& graph_view,
- vertex_t const* ptr_d_start,
- size_t num_start_vertices,
- size_t sampling_size,
- ops::graph::SamplingAlgoT sampling_algo);
-#endif
-
/**
* @brief Finds (weakly-connected-)component IDs of each vertices in the input graph.
*
diff --git a/cpp/include/cugraph/detail/utility_wrappers.hpp b/cpp/include/cugraph/detail/utility_wrappers.hpp
index 3d99b85556b..b1afeafd66b 100644
--- a/cpp/include/cugraph/detail/utility_wrappers.hpp
+++ b/cpp/include/cugraph/detail/utility_wrappers.hpp
@@ -65,6 +65,48 @@ void uniform_random_fill(rmm::cuda_stream_view const& stream_view,
template
void scalar_fill(raft::handle_t const& handle, value_t* d_value, size_t size, value_t value);
+/**
+ * @brief Sort a device span
+ *
+ * @tparam value_t type of the value to operate on. Must be either int32_t or int64_t.
+ *
+ * @param [in] handle RAFT handle object to encapsulate resources (e.g. CUDA stream, communicator,
+ * and handles to various CUDA libraries) to run graph algorithms.
+ * @param[out] values device span to sort
+ *
+ */
+template
+void sort_ints(raft::handle_t const& handle, raft::device_span values);
+
+/**
+ * @brief Keep unique element from a device span
+ *
+ * @tparam value_t type of the value to operate on. Must be either int32_t or int64_t.
+ *
+ * @param [in] handle RAFT handle object to encapsulate resources (e.g. CUDA stream, communicator,
+ * and handles to various CUDA libraries) to run graph algorithms.
+ * @param[in] values device span of unique elements.
+ * @return the number of unique elements.
+ *
+ */
+template
+size_t unique_ints(raft::handle_t const& handle, raft::device_span values);
+
+/**
+ * @brief Increment the values of a device span by a constant value
+ *
+ * @tparam value_t type of the value to operate on. Must be either int32_t or int64_t.
+ *
+ * @param[out] values device span to update
+ * @param[in] value value to be added to each element of the buffer
+ * @param[in] stream_view stream view
+ *
+ */
+template
+void transform_increment_ints(raft::device_span values,
+ value_t value,
+ rmm::cuda_stream_view const& stream_view);
+
/**
* @brief Fill a buffer with a sequence of values
*
@@ -73,7 +115,7 @@ void scalar_fill(raft::handle_t const& handle, value_t* d_value, size_t size, va
*
* Similar to the function std::iota, wraps the function thrust::sequence
*
- * @tparam value_t type of the value to operate on
+ * @tparam value_t type of the value to operate on.
*
* @param[in] stream_view stream view
* @param[out] d_value device array to fill
diff --git a/cpp/include/cugraph/sampling_functions.hpp b/cpp/include/cugraph/sampling_functions.hpp
index 783cd3a7e2b..3d41e954416 100644
--- a/cpp/include/cugraph/sampling_functions.hpp
+++ b/cpp/include/cugraph/sampling_functions.hpp
@@ -43,6 +43,8 @@ enum class prior_sources_behavior_t { DEFAULT = 0, CARRY_OVER, EXCLUDE };
/**
* @brief Uniform Neighborhood Sampling.
*
+ * @deprecated Replaced with homogeneous_uniform_neighbor_sample
+ *
* This function traverses from a set of starting vertices, traversing outgoing edges and
* randomly selects from these outgoing neighbors to extract a subgraph.
*
@@ -53,19 +55,20 @@ enum class prior_sources_behavior_t { DEFAULT = 0, CARRY_OVER, EXCLUDE };
* encountered in. The label output (optional) identifes the vertex label. The offsets array
* (optional) will be described below and is dependent upon the input parameters.
*
- * If @p starting_vertex_labels is not specified then no organization is applied to the output, the
- * label and offsets values in the return set will be std::nullopt.
+ * If @p starting_vertex_label_offsets is not specified then no organization is applied to the
+ * output, the label and offsets values in the return set will be std::nullopt.
*
- * If @p starting_vertex_labels is specified and @p label_to_output_comm_rank is not specified then
- * the label output has values. This will also result in the output being sorted by vertex label.
- * The offsets array in the return will be a CSR-style offsets array to identify the beginning of
- * each label range in the data. `labels.size() == (offsets.size() - 1)`.
+ * If @p starting_vertex_label_offsets is specified and @p label_to_output_comm_rank is not
+ * specified then the label output has values. This will also result in the output being sorted by
+ * vertex label. The offsets array in the return will be a CSR-style offsets array to identify the
+ * beginning of each label range in the data. `labels.size() == (offsets.size() - 1)`.
*
- * If @p starting_vertex_labels is specified and @p label_to_output_comm_rank is specified then the
- * label output has values. This will also result in the output being sorted by vertex label. The
- * offsets array in the return will be a CSR-style offsets array to identify the beginning of each
- * label range in the data. `labels.size() == (offsets.size() - 1)`. Additionally, the data will
- * be shuffled so that all data with a particular label will be on the specified rank.
+ * If @p starting_vertex_label_offsets is specified and @p label_to_output_comm_rank is specified
+ * then the label output has values. This will also result in the output being sorted by vertex
+ * label. The offsets array in the return will be a CSR-style offsets array to identify the
+ * beginning of each label range in the data. `labels.size() == (offsets.size() - 1)`.
+ * Additionally, the data will be shuffled so that all data with a particular label will be on the
+ * specified rank.
*
* @tparam vertex_t Type of vertex identifiers. Needs to be an integral type.
* @tparam edge_t Type of edge identifiers. Needs to be an integral type.
@@ -83,8 +86,8 @@ enum class prior_sources_behavior_t { DEFAULT = 0, CARRY_OVER, EXCLUDE };
* @param edge_type_view Optional view object holding edge types for @p graph_view.
* @param starting_vertices Device span of starting vertex IDs for the sampling.
* In a multi-gpu context the starting vertices should be local to this GPU.
- * @param starting_vertex_labels Optional device span of labels associted with each starting vertex
- * for the sampling.
+ * @param starting_vertex_label_offsets Optional device span of labels associated with each starting
+ * vertex for the sampling.
* @param label_to_output_comm_rank Optional tuple of device spans mapping label to a particular
* output rank. Element 0 of the tuple identifes the label, Element 1 of the tuple identifies the
* output rank. The label span must be sorted in ascending order.
@@ -126,7 +129,7 @@ uniform_neighbor_sample(
std::optional> edge_id_view,
std::optional> edge_type_view,
raft::device_span starting_vertices,
- std::optional> starting_vertex_labels,
+ std::optional> starting_vertex_label_offsets,
std::optional, raft::device_span>>
label_to_output_comm_rank,
raft::host_span fan_out,
@@ -140,6 +143,8 @@ uniform_neighbor_sample(
/**
* @brief Biased Neighborhood Sampling.
*
+ * @deprecated Replaced with homogeneous_biased_neighbor_sample
+ *
* This function traverses from a set of starting vertices, traversing outgoing edges and
* randomly selects (with edge biases) from these outgoing neighbors to extract a subgraph.
*
@@ -150,24 +155,26 @@ uniform_neighbor_sample(
* encountered in. The label output (optional) identifes the vertex label. The offsets array
* (optional) will be described below and is dependent upon the input parameters.
*
- * If @p starting_vertex_labels is not specified then no organization is applied to the output, the
- * label and offsets values in the return set will be std::nullopt.
+ * If @p starting_vertex_label_offsets is not specified then no organization is applied to the
+ * output, the label and offsets values in the return set will be std::nullopt.
*
- * If @p starting_vertex_labels is specified and @p label_to_output_comm_rank is not specified then
- * the label output has values. This will also result in the output being sorted by vertex label.
- * The offsets array in the return will be a CSR-style offsets array to identify the beginning of
- * each label range in the data. `labels.size() == (offsets.size() - 1)`.
+ * If @p starting_vertex_label_offsets is specified and @p label_to_output_comm_rank is not
+ * specified then the label output has values. This will also result in the output being sorted by
+ * vertex label. The offsets array in the return will be a CSR-style offsets array to identify the
+ * beginning of each label range in the data. `labels.size() == (offsets.size() - 1)`.
*
- * If @p starting_vertex_labels is specified and @p label_to_output_comm_rank is specified then the
- * label output has values. This will also result in the output being sorted by vertex label. The
- * offsets array in the return will be a CSR-style offsets array to identify the beginning of each
- * label range in the data. `labels.size() == (offsets.size() - 1)`. Additionally, the data will
- * be shuffled so that all data with a particular label will be on the specified rank.
+ * If @p starting_vertex_label_offsets is specified and @p label_to_output_comm_rank is specified
+ * then the label output has values. This will also result in the output being sorted by vertex
+ * label. The offsets array in the return will be a CSR-style offsets array to identify the
+ * beginning of each label range in the data. `labels.size() == (offsets.size() - 1)`.
+ * Additionally, the data will be shuffled so that all data with a particular label will be on the
+ * specified rank.
*
* @tparam vertex_t Type of vertex identifiers. Needs to be an integral type.
* @tparam edge_t Type of edge identifiers. Needs to be an integral type.
* @tparam weight_t Type of edge weights. Needs to be a floating point type.
* @tparam edge_type_t Type of edge type. Needs to be an integral type.
+ * @tparam bias_t Type of bias. Needs to be an integral type.
* @tparam label_t Type of label. Needs to be an integral type.
* @tparam store_transposed Flag indicating whether sources (if false) or destinations (if
* true) are major indices
@@ -184,8 +191,8 @@ uniform_neighbor_sample(
* corresponding edge can never be selected.
* @param starting_vertices Device span of starting vertex IDs for the sampling.
* In a multi-gpu context the starting vertices should be local to this GPU.
- * @param starting_vertex_labels Optional device span of labels associted with each starting vertex
- * for the sampling.
+ * @param starting_vertex_label_offsets Optional device span of labels associated with each starting
+ * vertex for the sampling.
* @param label_to_output_comm_rank Optional tuple of device spans mapping label to a particular
* output rank. Element 0 of the tuple identifes the label, Element 1 of the tuple identifies the
* output rank. The label span must be sorted in ascending order.
@@ -229,7 +236,7 @@ biased_neighbor_sample(
std::optional> edge_type_view,
edge_property_view_t edge_bias_view,
raft::device_span starting_vertices,
- std::optional> starting_vertex_labels,
+ std::optional> starting_vertex_label_offsets,
std::optional, raft::device_span>>
label_to_output_comm_rank,
raft::host_span fan_out,
@@ -240,6 +247,349 @@ biased_neighbor_sample(
bool dedupe_sources = false,
bool do_expensive_check = false);
+struct sampling_flags_t {
+ /**
+ * Specifies how to handle prior sources. Default is DEFAULT.
+ */
+ prior_sources_behavior_t prior_sources_behavior{};
+
+ /**
+ * Specifies if the hop information should be returned. Default is false.
+ */
+ bool return_hops{false};
+
+ /**
+ * If true then if a vertex v appears as a destination in hop X multiple times
+ * with the same label, it will only be passed once (for each label) as a source
+ * for the next hop. Default is false.
+ */
+ bool dedupe_sources{false};
+
+ /**
+ * Specifies if random sampling is done with replacement
+ * (true) or without replacement (false). Default is true.
+ */
+ bool with_replacement{true};
+};
+
+/**
+ * @brief Homogeneous Uniform Neighborhood Sampling.
+ *
+ * This function traverses from a set of starting vertices, traversing outgoing edges and
+ * randomly selects (uniformly) from these outgoing neighbors to extract a subgraph.
+ * The branching out to select outgoing neighbors is performed with homogeneous fanouts
+ *
+ * Output from this function is a tuple of vectors (src, dst, weight, edge_id, edge_type, hop,
+ * offsets), identifying the randomly selected edges where the size of src, dst, weight, edge_id,
+ * edge_type and hop is the number of sampled edges while the size of the offsets vector is the
+ * number of labels + 1. src is the source vertex, dst is the destination vertex, weight
+ * (optional) is the edge weight, edge_id (optional) identifies the edge id, edge_type (optional)
+ * identifies the edge type, hop identifies which hop the edge was encountered in.
+ * The offsets array (optional) identifies the offset for each label.
+ *
+ * If @p label_to_output_comm_rank is specified then the data will be shuffled so that all entries
+ * for a particular label are returned on the specified rank.
+ *
+ * @tparam vertex_t Type of vertex identifiers. Needs to be an integral type.
+ * @tparam edge_t Type of edge identifiers. Needs to be an integral type.
+ * @tparam weight_t Type of edge weights. Needs to be a floating point type.
+ * @tparam edge_type_t Type of edge type. Needs to be an integral type.
+ * @tparam store_transposed Flag indicating whether sources (if false) or destinations (if
+ * true) are major indices
+ * @tparam multi_gpu Flag indicating whether template instantiation should target single-GPU (false)
+ * @param handle RAFT handle object to encapsulate resources (e.g. CUDA stream, communicator, and
+ * handles to various CUDA libraries) to run graph algorithms.
+ * @param rng_state A pre-initialized raft::RngState object for generating random numbers
+ * @param graph_view Graph View object to generate NBR Sampling on.
+ * @param edge_weight_view Optional view object holding edge weights for @p graph_view.
+ * @param edge_id_view Optional view object holding edge ids for @p graph_view.
+ * @param edge_type_view Optional view object holding edge types for @p graph_view.
+ * @param starting_vertices Device span of starting vertex IDs for the sampling.
+ * In a multi-gpu context the starting vertices should be local to this GPU.
+ * @param starting_vertex_label_offsets Optional device span of labels associated with each starting
+ * vertex for the sampling.
+ * @param label_to_output_comm_rank Optional device span identifying which rank should get sampling
+ * outputs of each vertex label. This should be the same on each rank.
+ * @param fan_out Host span defining branching out (fan-out) degree per source vertex for each
+ * level.
+ * @param flags A set of flags indicating which sampling features should be used.
+ * @param do_expensive_check A flag to run expensive checks for input arguments (if set to `true`).
+ * @return tuple device vectors (vertex_t source_vertex, vertex_t destination_vertex,
+ * optional weight_t weight, optional edge_t edge id, optional edge_type_t edge type,
+ * optional int32_t hop, optional label_t label, optional size_t offsets)
+ */
+
+template
+std::tuple,
+ rmm::device_uvector,
+ std::optional>,
+ std::optional>,
+ std::optional>,
+ std::optional>,
+ std::optional>>
+homogeneous_uniform_neighbor_sample(
+ raft::handle_t const& handle,
+ raft::random::RngState& rng_state,
+ graph_view_t const& graph_view,
+ std::optional> edge_weight_view,
+ std::optional> edge_id_view,
+ std::optional> edge_type_view,
+ raft::device_span starting_vertices,
+ std::optional> starting_vertex_label_offsets,
+ std::optional> label_to_output_comm_rank,
+ raft::host_span fan_out,
+ sampling_flags_t sampling_flags,
+ bool do_expensive_check = false);
+
+/**
+ * @brief Homogeneous Biased Neighborhood Sampling.
+ *
+ * This function traverses from a set of starting vertices, traversing outgoing edges and
+ * randomly selects (with edge biases) from these outgoing neighbors to extract a subgraph.
+ * The branching out to select outgoing neighbors is performed with homogeneous fanouts
+ *
+ * Output from this function is a tuple of vectors (src, dst, weight, edge_id, edge_type, hop,
+ * offsets), identifying the randomly selected edges where the size of src, dst, weight, edge_id,
+ * edge_type and hop is the number of sampled edges while the size of the offsets vector is the
+ * number of labels + 1. src is the source vertex, dst is the destination vertex, weight
+ * (optional) is the edge weight, edge_id (optional) identifies the edge id, edge_type (optional)
+ * identifies the edge type, hop identifies which hop the edge was encountered in.
+ * The offsets array (optional) identifies the offset for each label.
+ *
+ * If @p label_to_output_comm_rank is specified then the data will be shuffled so that all entries
+ * for a particular label are returned on the specified rank.
+ *
+ * @tparam vertex_t Type of vertex identifiers. Needs to be an integral type.
+ * @tparam edge_t Type of edge identifiers. Needs to be an integral type.
+ * @tparam weight_t Type of edge weights. Needs to be a floating point type.
+ * @tparam edge_type_t Type of edge type. Needs to be an integral type.
+ * @tparam bias_t Type of bias. Needs to be an integral type.
+ * @tparam store_transposed Flag indicating whether sources (if false) or destinations (if
+ * true) are major indices
+ * @tparam multi_gpu Flag indicating whether template instantiation should target single-GPU (false)
+ * @param handle RAFT handle object to encapsulate resources (e.g. CUDA stream, communicator, and
+ * handles to various CUDA libraries) to run graph algorithms.
+ * @param rng_state A pre-initialized raft::RngState object for generating random numbers
+ * @param graph_view Graph View object to generate NBR Sampling on.
+ * @param edge_weight_view Optional view object holding edge weights for @p graph_view.
+ * @param edge_id_view Optional view object holding edge ids for @p graph_view.
+ * @param edge_type_view Optional view object holding edge types for @p graph_view.
+ * @param edge_bias_view View object holding edge biases (to be used in biased sampling) for @p
+ * graph_view. Bias values should be non-negative and the sum of edge bias values from any vertex
+ * should not exceed std::numeric_limits::max(). 0 bias value indicates that the
+ * corresponding edge can never be selected.
+ * @param starting_vertices Device span of starting vertex IDs for the sampling.
+ * In a multi-gpu context the starting vertices should be local to this GPU.
+ * @param starting_vertex_label_offsets Optional device span of labels associated with each starting
+ * vertex for the sampling.
+ * @param label_to_output_comm_rank Optional device span identifying which rank should get sampling
+ * outputs of each vertex label. This should be the same on each rank.
+ * @param fan_out Host span defining branching out (fan-out) degree per source vertex for each
+ * level.
+ * @param flags A set of flags indicating which sampling features should be used.
+ * @param do_expensive_check A flag to run expensive checks for input arguments (if set to `true`).
+ * @return tuple device vectors (vertex_t source_vertex, vertex_t destination_vertex,
+ * optional weight_t weight, optional edge_t edge id, optional edge_type_t edge type,
+ * optional int32_t hop, optional label_t label, optional size_t offsets)
+ */
+
+template
+std::tuple,
+ rmm::device_uvector,
+ std::optional>,
+ std::optional>,
+ std::optional>,
+ std::optional>,
+ std::optional>>
+homogeneous_biased_neighbor_sample(
+ raft::handle_t const& handle,
+ raft::random::RngState& rng_state,
+ graph_view_t const& graph_view,
+ std::optional> edge_weight_view,
+ std::optional> edge_id_view,
+ std::optional> edge_type_view,
+ edge_property_view_t edge_bias_view,
+ raft::device_span starting_vertices,
+ std::optional> starting_vertex_label_offsets,
+ std::optional> label_to_output_comm_rank,
+ raft::host_span fan_out,
+ sampling_flags_t sampling_flags,
+ bool do_expensive_check = false);
+
+/**
+ * @brief Heterogeneous Uniform Neighborhood Sampling.
+ *
+ * This function traverses from a set of starting vertices, traversing outgoing edges and
+ * randomly selects (uniformly) from these outgoing neighbors to extract a subgraph.
+ * The branching out to select outgoing neighbors is performed with heterogeneous fanouts
+ * where the number of edge types is bigger than 1.
+ *
+ * Output from this function is a tuple of vectors (src, dst, weight, edge_id, edge_type, hop,
+ * offsets), identifying the randomly selected edges where the size of src, dst, weight, edge_id,
+ * edge_type and hop is the number of sampled edges while the size of the offsets vector is the
+ * number of labels + 1. src is the source vertex, dst is the destination vertex, weight
+ * (optional) is the edge weight, edge_id (optional) identifies the edge id, edge_type (optional)
+ * identifies the edge type, hop identifies which hop the edge was encountered in.
+ * The offsets array (optional) identifies the offset for each label.
+ *
+ * If @p label_to_output_comm_rank is specified then the data will be shuffled so that all entries
+ * for a particular label are returned on the specified rank.
+ *
+ * @tparam vertex_t Type of vertex identifiers. Needs to be an integral type.
+ * @tparam edge_t Type of edge identifiers. Needs to be an integral type.
+ * @tparam weight_t Type of edge weights. Needs to be a floating point type.
+ * @tparam edge_type_t Type of edge type. Needs to be an integral type.
+ * @tparam store_transposed Flag indicating whether sources (if false) or destinations (if
+ * true) are major indices
+ * @tparam multi_gpu Flag indicating whether template instantiation should target single-GPU (false)
+ * @param handle RAFT handle object to encapsulate resources (e.g. CUDA stream, communicator, and
+ * handles to various CUDA libraries) to run graph algorithms.
+ * @param rng_state A pre-initialized raft::RngState object for generating random numbers
+ * @param graph_view Graph View object to generate NBR Sampling on.
+ * @param edge_weight_view Optional view object holding edge weights for @p graph_view.
+ * @param edge_id_view Optional view object holding edge ids for @p graph_view.
+ * @param edge_type_view Optional view object holding edge types for @p graph_view.
+ * @param starting_vertices Device span of starting vertex IDs for the sampling.
+ * In a multi-gpu context the starting vertices should be local to this GPU.
+ * @param starting_vertex_label_offsets Optional device span of labels associated with each starting
+ * vertex for the sampling.
+ * @param label_to_output_comm_rank Optional device span identifying which rank should get sampling
+ * outputs of each vertex label. This should be the same on each rank.
+ * @param fan_out Host span defining branching out (fan-out) degree per source vertex for each
+ * level. The fanout value at hop x is given by the expression 'fanout[x*num_edge_types +
+ * edge_type_id]'
+ * @param num_edge_types Number of edge types where a value of 1 translates to homogeneous neighbor
+ * sample whereas a value greater than 1 translates to heterogeneous neighbor sample.
+ * @param flags A set of flags indicating which sampling features should be used.
+ * @param do_expensive_check A flag to run expensive checks for input arguments (if set to `true`).
+ * @return tuple device vectors (vertex_t source_vertex, vertex_t destination_vertex,
+ * optional weight_t weight, optional edge_t edge id, optional edge_type_t edge type,
+ * optional int32_t hop, optional label_t label, optional size_t offsets)
+ */
+template
+std::tuple,
+ rmm::device_uvector,
+ std::optional>,
+ std::optional>,
+ std::optional>,
+ std::optional>,
+ std::optional>>
+heterogeneous_uniform_neighbor_sample(
+ raft::handle_t const& handle,
+ raft::random::RngState& rng_state,
+ graph_view_t const& graph_view,
+ std::optional> edge_weight_view,
+ std::optional> edge_id_view,
+ std::optional> edge_type_view,
+ raft::device_span starting_vertices,
+ std::optional> starting_vertex_label_offsets,
+ std::optional> label_to_output_comm_rank,
+ raft::host_span fan_out,
+ edge_type_t num_edge_types,
+ sampling_flags_t sampling_flags,
+ bool do_expensive_check = false);
+
+/**
+ * @brief Heterogeneous Biased Neighborhood Sampling.
+ *
+ * This function traverses from a set of starting vertices, traversing outgoing edges and
+ * randomly selects (with edge biases) from these outgoing neighbors to extract a subgraph.
+ * The branching out to select outgoing neighbors is performed with heterogeneous fanouts
+ * where the number of edge types is bigger than 1.
+ *
+ * Output from this function is a tuple of vectors (src, dst, weight, edge_id, edge_type, hop,
+ * offsets), identifying the randomly selected edges where the size of src, dst, weight, edge_id,
+ * edge_type and hop is the number of sampled edges while the size of the offsets vector is the
+ * number of labels + 1. src is the source vertex, dst is the destination vertex, weight
+ * (optional) is the edge weight, edge_id (optional) identifies the edge id, edge_type (optional)
+ * identifies the edge type, hop identifies which hop the edge was encountered in.
+ * The offsets array (optional) identifies the offset for each label.
+ *
+ * If @p label_to_output_comm_rank is specified then the data will be shuffled so that all entries
+ * for a particular label are returned on the specified rank.
+ *
+ * @tparam vertex_t Type of vertex identifiers. Needs to be an integral type.
+ * @tparam edge_t Type of edge identifiers. Needs to be an integral type.
+ * @tparam weight_t Type of edge weights. Needs to be a floating point type.
+ * @tparam edge_type_t Type of edge type. Needs to be an integral type.
+ * @tparam bias_t Type of bias. Needs to be an integral type.
+ * @tparam store_transposed Flag indicating whether sources (if false) or destinations (if
+ * true) are major indices
+ * @tparam multi_gpu Flag indicating whether template instantiation should target single-GPU (false)
+ * @param handle RAFT handle object to encapsulate resources (e.g. CUDA stream, communicator, and
+ * handles to various CUDA libraries) to run graph algorithms.
+ * @param rng_state A pre-initialized raft::RngState object for generating random numbers
+ * @param graph_view Graph View object to generate NBR Sampling on.
+ * @param edge_weight_view Optional view object holding edge weights for @p graph_view.
+ * @param edge_id_view Optional view object holding edge ids for @p graph_view.
+ * @param edge_type_view Optional view object holding edge types for @p graph_view.
+ * @param edge_bias_view View object holding edge biases (to be used in biased sampling) for @p
+ * graph_view. Bias values should be non-negative and the sum of edge bias values from any vertex
+ * should not exceed std::numeric_limits::max(). 0 bias value indicates that the
+ * corresponding edge can never be selected.
+ * @param starting_vertices Device span of starting vertex IDs for the sampling.
+ * In a multi-gpu context the starting vertices should be local to this GPU.
+ * @param starting_vertex_label_offsets Optional device span of labels associated with each starting
+ * vertex for the sampling.
+ * @param label_to_output_comm_rank Optional device span identifying which rank should get sampling
+ * outputs of each vertex label. This should be the same on each rank.
+ * @param fan_out Host span defining branching out (fan-out) degree per source vertex for each
+ * level. The fanout value at hop x is given by the expression 'fanout[x*num_edge_types +
+ * edge_type_id]'
+ * @param num_edge_types Number of edge types where a value of 1 translates to homogeneous neighbor
+ * sample whereas a value greater than 1 translates to heterogeneous neighbor sample.
+ * @param flags A set of flags indicating which sampling features should be used.
+ * @param do_expensive_check A flag to run expensive checks for input arguments (if set to `true`).
+ * @return tuple device vectors (vertex_t source_vertex, vertex_t destination_vertex,
+ * optional weight_t weight, optional edge_t edge id, optional edge_type_t edge type,
+ * optional int32_t hop, optional label_t label, optional size_t offsets)
+ */
+template
+std::tuple,
+ rmm::device_uvector,
+ std::optional>,
+ std::optional>,
+ std::optional>,
+ std::optional>,
+ std::optional>>
+heterogeneous_biased_neighbor_sample(
+ raft::handle_t const& handle,
+ raft::random::RngState& rng_state,
+ graph_view_t const& graph_view,
+ std::optional> edge_weight_view,
+ std::optional> edge_id_view,
+ std::optional> edge_type_view,
+ edge_property_view_t edge_bias_view,
+ raft::device_span starting_vertices,
+ std::optional> starting_vertex_label_offsets,
+ std::optional> label_to_output_comm_rank,
+ raft::host_span fan_out,
+ edge_type_t num_edge_types,
+ sampling_flags_t sampling_flags,
+ bool do_expensive_check = false);
+
/*
* @brief renumber sampled edge list and compress to the (D)CSR|(D)CSC format.
*
diff --git a/cpp/include/cugraph/utilities/graph_traits.hpp b/cpp/include/cugraph/utilities/graph_traits.hpp
index bd46c9d4fc1..f0ae0b4279d 100644
--- a/cpp/include/cugraph/utilities/graph_traits.hpp
+++ b/cpp/include/cugraph/utilities/graph_traits.hpp
@@ -44,7 +44,7 @@ template
struct is_vertex_edge_combo {
static constexpr bool value = is_one_of::value &&
is_one_of::value &&
- (sizeof(vertex_t) <= sizeof(edge_t));
+ (sizeof(vertex_t) == sizeof(edge_t));
};
// meta-function that constrains
diff --git a/cpp/include/cugraph_c/lookup_src_dst.h b/cpp/include/cugraph_c/lookup_src_dst.h
index f4d63572e82..64051743981 100644
--- a/cpp/include/cugraph_c/lookup_src_dst.h
+++ b/cpp/include/cugraph_c/lookup_src_dst.h
@@ -136,6 +136,14 @@ cugraph_type_erased_device_array_view_t* cugraph_lookup_result_get_dsts(
*/
void cugraph_lookup_result_free(cugraph_lookup_result_t* result);
+/**
+ * @ingroup samplingC
+ * @brief Free a sampling lookup map
+ *
+ * @param [in] container The sampling lookup map (a.k.a. container).
+ */
+void cugraph_lookup_container_free(cugraph_lookup_container_t* container);
+
#ifdef __cplusplus
}
#endif
diff --git a/cpp/include/cugraph_c/resource_handle.h b/cpp/include/cugraph_c/resource_handle.h
index 0e45102aae2..402da451a6f 100644
--- a/cpp/include/cugraph_c/resource_handle.h
+++ b/cpp/include/cugraph_c/resource_handle.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2022-2023, NVIDIA CORPORATION.
+ * Copyright (c) 2022-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.
@@ -17,6 +17,7 @@
#pragma once
#include
+#include
#include
#include
@@ -25,20 +26,6 @@
extern "C" {
#endif
-typedef enum bool_ { FALSE = 0, TRUE = 1 } bool_t;
-
-typedef int8_t byte_t;
-
-/**
- * @deprecated - use cugraph_data_type_id_t;
- */
-typedef enum data_type_id_ { INT32 = 0, INT64, FLOAT32, FLOAT64, SIZE_T, NTYPES } data_type_id_t;
-
-/**
- * @brief - Enumeration of data types
- */
-typedef data_type_id_t cugraph_data_type_id_t;
-
typedef struct cugraph_resource_handle_ {
int32_t align_;
} cugraph_resource_handle_t;
diff --git a/cpp/include/cugraph_c/sampling_algorithms.h b/cpp/include/cugraph_c/sampling_algorithms.h
index bb26e577915..ef75e726d80 100644
--- a/cpp/include/cugraph_c/sampling_algorithms.h
+++ b/cpp/include/cugraph_c/sampling_algorithms.h
@@ -199,6 +199,13 @@ typedef struct {
int32_t align_;
} cugraph_sampling_options_t;
+/**
+ * @brief Opaque sampling options type
+ */
+typedef struct {
+ int32_t align_;
+} sampling_flags_t;
+
/**
* @brief Enumeration for prior sources behavior
*/
@@ -323,6 +330,8 @@ void cugraph_sampling_options_free(cugraph_sampling_options_t* options);
/**
* @brief Uniform Neighborhood Sampling
*
+ * @deprecated This API will be deleted, use cugraph_homogeneous_uniform_neighbor_sample
+ *
* Returns a sample of the neighborhood around specified start vertices. Optionally, each
* start vertex can be associated with a label, allowing the caller to specify multiple batches
* of sampling requests in the same function call - which should improve GPU utilization.
@@ -348,8 +357,8 @@ void cugraph_sampling_options_free(cugraph_sampling_options_t* options);
* label_to_comm_rank[i]. If not specified then the output data will not be shuffled between ranks.
* @param [in] label_offsets Device array of the offsets for each label in the seed list. This
* parameter is only used with the retain_seeds option.
- * @param [in] fanout Host array defining the fan out at each step in the sampling algorithm.
- * We only support fanout values of type INT32
+ * @param [in] fan_out Host array defining the fan out at each step in the sampling
+ * algorithm. We only support fan_out values of type INT32
* @param [in,out] rng_state State of the random number generator, updated with each call
* @param [in] sampling_options
* Opaque pointer defining the sampling options.
@@ -378,6 +387,8 @@ cugraph_error_code_t cugraph_uniform_neighbor_sample(
/**
* @brief Biased Neighborhood Sampling
*
+ * @deprecated This API will be deleted, use cugraph_homogeneous_biased_neighbor_sample.
+ *
* Returns a sample of the neighborhood around specified start vertices. Optionally, each
* start vertex can be associated with a label, allowing the caller to specify multiple batches
* of sampling requests in the same function call - which should improve GPU utilization.
@@ -406,8 +417,8 @@ cugraph_error_code_t cugraph_uniform_neighbor_sample(
* label_to_comm_rank[i]. If not specified then the output data will not be shuffled between ranks.
* @param [in] label_offsets Device array of the offsets for each label in the seed list. This
* parameter is only used with the retain_seeds option.
- * @param [in] fanout Host array defining the fan out at each step in the sampling algorithm.
- * We only support fanout values of type INT32
+ * @param [in] fan_out Host array defining the fan out at each step in the sampling
+ * algorithm. We only support fan_out values of type INT32
* @param [in,out] rng_state State of the random number generator, updated with each call
* @param [in] sampling_options
* Opaque pointer defining the sampling options.
@@ -434,6 +445,186 @@ cugraph_error_code_t cugraph_biased_neighbor_sample(
cugraph_sample_result_t** result,
cugraph_error_t** error);
+/**
+ * @brief Homogeneous Uniform Neighborhood Sampling
+ *
+ * Returns a sample of the neighborhood around specified start vertices and fan_out.
+ * The neighborhood is sampled uniformly.
+ * Optionally, each start vertex can be associated with a label, allowing the caller to specify
+ * multiple batches of sampling requests in the same function call - which should improve GPU
+ * utilization.
+ *
+ * If label is NULL then all start vertices will be considered part of the same batch and the
+ * return value will not have a label column.
+ *
+ * @param [in] handle Handle for accessing resources
+ * * @param [in,out] rng_state State of the random number generator, updated with each call
+ * @param [in] graph Pointer to graph. NOTE: Graph might be modified if the storage
+ * needs to be transposed
+ * @param [in] start_vertices Device array of start vertices for the sampling
+ * @param [in] starting_vertex_label_offsets Device array of the offsets for each label in
+ * the seed list. This parameter is only used with the retain_seeds option.
+ * @param [in] fan_out Host array defining the fan out at each step in the sampling
+ * algorithm. We only support fan_out values of type INT32
+ * @param [in] sampling_options
+ * Opaque pointer defining the sampling options.
+ * @param [in] do_expensive_check
+ * A flag to run expensive checks for input arguments (if set to true)
+ * @param [out] result Output from the uniform_neighbor_sample call
+ * @param [out] error Pointer to an error object storing details of any error. Will
+ * be populated if error code is not CUGRAPH_SUCCESS
+ * @return error code
+ */
+cugraph_error_code_t cugraph_homogeneous_uniform_neighbor_sample(
+ const cugraph_resource_handle_t* handle,
+ cugraph_rng_state_t* rng_state,
+ cugraph_graph_t* graph,
+ const cugraph_type_erased_device_array_view_t* start_vertices,
+ const cugraph_type_erased_device_array_view_t* starting_vertex_label_offsets,
+ const cugraph_type_erased_host_array_view_t* fan_out,
+ const cugraph_sampling_options_t* options,
+ bool_t do_expensive_check,
+ cugraph_sample_result_t** result,
+ cugraph_error_t** error);
+
+/**
+ * @brief Homogeneous Biased Neighborhood Sampling
+ *
+ * Returns a sample of the neighborhood around specified start vertices and fan_out.
+ * The neighborhood is sampled uniformly.
+ * Optionally, each start vertex can be associated with a label, allowing the caller to specify
+ * multiple batches of sampling requests in the same function call - which should improve GPU
+ * utilization.
+ *
+ * If label is NULL then all start vertices will be considered part of the same batch and the
+ * return value will not have a label column.
+ *
+ * @param [in] handle Handle for accessing resources
+ * * @param [in,out] rng_state State of the random number generator, updated with each call
+ * @param [in] graph Pointer to graph. NOTE: Graph might be modified if the storage
+ * needs to be transposed
+ * @param [in] edge_biases Device array of edge biases to use for sampling. If NULL
+ * use the edge weight as the bias. If set to NULL, edges will be sampled uniformly.
+ * @param [in] start_vertices Device array of start vertices for the sampling
+ * @param [in] starting_vertex_label_offsets Device array of the offsets for each label in
+ * the seed list. This parameter is only used with the retain_seeds option.
+ * @param [in] fan_out Host array defining the fan out at each step in the sampling
+ * algorithm. We only support fan_out values of type INT32
+ * @param [in] sampling_options
+ * Opaque pointer defining the sampling options.
+ * @param [in] do_expensive_check
+ * A flag to run expensive checks for input arguments (if set to true)
+ * @param [out] result Output from the uniform_neighbor_sample call
+ * @param [out] error Pointer to an error object storing details of any error. Will
+ * be populated if error code is not CUGRAPH_SUCCESS
+ * @return error code
+ */
+cugraph_error_code_t cugraph_homogeneous_biased_neighbor_sample(
+ const cugraph_resource_handle_t* handle,
+ cugraph_rng_state_t* rng_state,
+ cugraph_graph_t* graph,
+ const cugraph_edge_property_view_t* edge_biases,
+ const cugraph_type_erased_device_array_view_t* start_vertices,
+ const cugraph_type_erased_device_array_view_t* starting_vertex_label_offsets,
+ const cugraph_type_erased_host_array_view_t* fan_out,
+ const cugraph_sampling_options_t* options,
+ bool_t do_expensive_check,
+ cugraph_sample_result_t** result,
+ cugraph_error_t** error);
+
+/**
+ * @brief Heterogeneous Uniform Neighborhood Sampling
+ *
+ * Returns a sample of the neighborhood around specified start vertices and fan_out.
+ * The neighborhood is sampled uniformly.
+ * Optionally, each start vertex can be associated with a label, allowing the caller to specify
+ * multiple batches of sampling requests in the same function call - which should improve GPU
+ * utilization.
+ *
+ * If label is NULL then all start vertices will be considered part of the same batch and the
+ * return value will not have a label column.
+ *
+ * @param [in] handle Handle for accessing resources
+ * * @param [in,out] rng_state State of the random number generator, updated with each call
+ * @param [in] graph Pointer to graph. NOTE: Graph might be modified if the storage
+ * needs to be transposed
+ * @param [in] start_vertices Device array of start vertices for the sampling
+ * @param [in] starting_vertex_label_offsets Device array of the offsets for each label in
+ * the seed list. This parameter is only used with the retain_seeds option.
+ * @param [in] fan_out Host array defining the fan out at each step in the sampling
+ * algorithm. We only support fan_out values of type INT32
+ * @param [in] num_edge_types Number of edge types where a value of 1 translates to homogeneous
+ * neighbor sample whereas a value greater than 1 translates to heterogeneous neighbor sample.
+ * @param [in] sampling_options
+ * Opaque pointer defining the sampling options.
+ * @param [in] do_expensive_check
+ * A flag to run expensive checks for input arguments (if set to true)
+ * @param [out] result Output from the uniform_neighbor_sample call
+ * @param [out] error Pointer to an error object storing details of any error. Will
+ * be populated if error code is not CUGRAPH_SUCCESS
+ * @return error code
+ */
+cugraph_error_code_t cugraph_heterogeneous_uniform_neighbor_sample(
+ const cugraph_resource_handle_t* handle,
+ cugraph_rng_state_t* rng_state,
+ cugraph_graph_t* graph,
+ const cugraph_type_erased_device_array_view_t* start_vertices,
+ const cugraph_type_erased_device_array_view_t* starting_vertex_label_offsets,
+ const cugraph_type_erased_host_array_view_t* fan_out,
+ int num_edge_types,
+ const cugraph_sampling_options_t* options,
+ bool_t do_expensive_check,
+ cugraph_sample_result_t** result,
+ cugraph_error_t** error);
+
+/**
+ * @brief Heterogeneous Biased Neighborhood Sampling
+ *
+ * Returns a sample of the neighborhood around specified start vertices and fan_out.
+ * The neighborhood is sampled uniformly.
+ * Optionally, each start vertex can be associated with a label, allowing the caller to specify
+ * multiple batches of sampling requests in the same function call - which should improve GPU
+ * utilization.
+ *
+ * If label is NULL then all start vertices will be considered part of the same batch and the
+ * return value will not have a label column.
+ *
+ * @param [in] handle Handle for accessing resources
+ * * @param [in,out] rng_state State of the random number generator, updated with each call
+ * @param [in] graph Pointer to graph. NOTE: Graph might be modified if the storage
+ * needs to be transposed
+ * @param [in] edge_biases Device array of edge biases to use for sampling. If NULL
+ * use the edge weight as the bias. If set to NULL, edges will be sampled uniformly.
+ * @param [in] start_vertices Device array of start vertices for the sampling
+ * @param [in] starting_vertex_label_offsets Device array of the offsets for each label in
+ * the seed list. This parameter is only used with the retain_seeds option.
+ * @param [in] fan_out Host array defining the fan out at each step in the sampling
+ * algorithm. We only support fan_out values of type INT32
+ * @param [in] num_edge_types Number of edge types where a value of 1 translates to homogeneous
+ * neighbor sample whereas a value greater than 1 translates to heterogeneous neighbor sample.
+ * @param [in] sampling_options
+ * Opaque pointer defining the sampling options.
+ * @param [in] do_expensive_check
+ * A flag to run expensive checks for input arguments (if set to true)
+ * @param [out] result Output from the uniform_neighbor_sample call
+ * @param [out] error Pointer to an error object storing details of any error. Will
+ * be populated if error code is not CUGRAPH_SUCCESS
+ * @return error code
+ */
+cugraph_error_code_t cugraph_heterogeneous_biased_neighbor_sample(
+ const cugraph_resource_handle_t* handle,
+ cugraph_rng_state_t* rng_state,
+ cugraph_graph_t* graph,
+ const cugraph_edge_property_view_t* edge_biases,
+ const cugraph_type_erased_device_array_view_t* start_vertices,
+ const cugraph_type_erased_device_array_view_t* starting_vertex_label_offsets,
+ const cugraph_type_erased_host_array_view_t* fan_out,
+ int num_edge_types,
+ const cugraph_sampling_options_t* options,
+ bool_t do_expensive_check,
+ cugraph_sample_result_t** result,
+ cugraph_error_t** error);
+
/**
* @deprecated This call should be replaced with cugraph_sample_result_get_majors
* @brief Get the source vertices from the sampling algorithm result
@@ -584,6 +775,26 @@ cugraph_type_erased_device_array_view_t* cugraph_sample_result_get_renumber_map(
cugraph_type_erased_device_array_view_t* cugraph_sample_result_get_renumber_map_offsets(
const cugraph_sample_result_t* result);
+/**
+ * @ingroup samplingC
+ * @brief Get the edge renumber map
+ *
+ * @param [in] result The result from a sampling algorithm
+ * @return type erased array pointing to the renumber map
+ */
+cugraph_type_erased_device_array_view_t* cugraph_sample_result_get_edge_renumber_map(
+ const cugraph_sample_result_t* result);
+
+/**
+ * @ingroup samplingC
+ * @brief Get the edge renumber map offets
+ *
+ * @param [in] result The result from a sampling algorithm
+ * @return type erased array pointing to the renumber map
+ */
+cugraph_type_erased_device_array_view_t* cugraph_sample_result_get_edge_renumber_map_offsets(
+ const cugraph_sample_result_t* result);
+
/**
* @ingroup samplingC
* @brief Free a sampling result
diff --git a/cpp/src/traversal/k_hop_nbrs_mg_v32_e64.cu b/cpp/include/cugraph_c/types.h
similarity index 61%
rename from cpp/src/traversal/k_hop_nbrs_mg_v32_e64.cu
rename to cpp/include/cugraph_c/types.h
index 31049883166..dddb802b931 100644
--- a/cpp/src/traversal/k_hop_nbrs_mg_v32_e64.cu
+++ b/cpp/include/cugraph_c/types.h
@@ -13,17 +13,35 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-#include "traversal/k_hop_nbrs_impl.cuh"
-namespace cugraph {
+#pragma once
-// MG instantiation
+#include
-template std::tuple, rmm::device_uvector> k_hop_nbrs(
- raft::handle_t const& handle,
- graph_view_t const& graph_view,
- raft::device_span start_vertices,
- size_t k,
- bool do_expensive_check);
+#ifdef __cplusplus
+extern "C" {
+#endif
-} // namespace cugraph
+typedef enum bool_ { FALSE = 0, TRUE = 1 } bool_t;
+
+typedef int8_t byte_t;
+
+typedef enum data_type_id_ {
+ INT8 = 0,
+ INT16,
+ INT32,
+ INT64,
+ UINT8,
+ UINT16,
+ UINT32,
+ UINT64,
+ FLOAT32,
+ FLOAT64,
+ SIZE_T,
+ BOOL,
+ NTYPES
+} cugraph_data_type_id_t;
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/cpp/src/c_api/array.cpp b/cpp/src/c_api/array.cpp
index c9c8eaa78ac..5d760f1c1ec 100644
--- a/cpp/src/c_api/array.cpp
+++ b/cpp/src/c_api/array.cpp
@@ -22,7 +22,8 @@
namespace cugraph {
namespace c_api {
-size_t data_type_sz[] = {4, 8, 4, 8, 8};
+// FIXME: This is paired with type definition... better solution coming in 24.12 release.
+size_t data_type_sz[] = {1, 2, 4, 8, 1, 2, 4, 8, 4, 8, 8, 1};
} // namespace c_api
} // namespace cugraph
diff --git a/cpp/src/c_api/array.hpp b/cpp/src/c_api/array.hpp
index 048d2ee1cea..0ab30a1cb72 100644
--- a/cpp/src/c_api/array.hpp
+++ b/cpp/src/c_api/array.hpp
@@ -1,5 +1,5 @@
/*
- * 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.
@@ -125,6 +125,27 @@ struct cugraph_type_erased_host_array_t {
std::copy(vec.begin(), vec.end(), reinterpret_cast(data_.get()));
}
+ cugraph_type_erased_host_array_t(cugraph_type_erased_host_array_view_t const* view_p)
+ : data_(std::make_unique(view_p->num_bytes_)),
+ size_(view_p->size_),
+ num_bytes_(view_p->num_bytes_),
+ type_(view_p->type_)
+ {
+ std::copy(view_p->data_, view_p->data_ + num_bytes_, data_.get());
+ }
+
+ template
+ T* as_type()
+ {
+ return reinterpret_cast(data_.get());
+ }
+
+ template
+ T const* as_type() const
+ {
+ return reinterpret_cast(data_.get());
+ }
+
auto view()
{
return new cugraph_type_erased_host_array_view_t{data_.get(), size_, num_bytes_, type_};
diff --git a/cpp/src/c_api/core_number.cpp b/cpp/src/c_api/core_number.cpp
index b00a8d979e3..b6854dc73b4 100644
--- a/cpp/src/c_api/core_number.cpp
+++ b/cpp/src/c_api/core_number.cpp
@@ -76,7 +76,7 @@ struct core_number_functor : public cugraph::c_api::abstract_functor {
rmm::device_uvector core_numbers(graph_view.local_vertex_partition_range_size(),
handle_.get_stream());
- auto degree_type = reinterpret_cast(degree_type);
+ auto degree_type = reinterpret_cast(degree_type_);
cugraph::core_number(handle_,
graph_view,
diff --git a/cpp/src/c_api/graph_functions.cpp b/cpp/src/c_api/graph_functions.cpp
index df741a349d2..8778369dbe6 100644
--- a/cpp/src/c_api/graph_functions.cpp
+++ b/cpp/src/c_api/graph_functions.cpp
@@ -84,7 +84,7 @@ struct create_vertex_pairs_functor : public cugraph::c_api::abstract_functor {
std::nullopt,
std::nullopt);
}
-
+ // FIXME: use std::tuple (template) instead.
result_ = new cugraph::c_api::cugraph_vertex_pairs_t{
new cugraph::c_api::cugraph_type_erased_device_array_t(first_copy, graph_->vertex_type_),
new cugraph::c_api::cugraph_type_erased_device_array_t(second_copy, graph_->vertex_type_)};
diff --git a/cpp/src/c_api/graph_helper_mg.cu b/cpp/src/c_api/graph_helper_mg.cu
index 353d3d90de8..704968066ad 100644
--- a/cpp/src/c_api/graph_helper_mg.cu
+++ b/cpp/src/c_api/graph_helper_mg.cu
@@ -25,12 +25,6 @@ create_constant_edge_property(
cugraph::graph_view_t const& graph_view,
float constant_value);
-template edge_property_t, float>
-create_constant_edge_property(
- raft::handle_t const& handle,
- cugraph::graph_view_t const& graph_view,
- float constant_value);
-
template edge_property_t, float>
create_constant_edge_property(
raft::handle_t const& handle,
@@ -42,11 +36,6 @@ create_constant_edge_property(raft::handle_t const& handle,
cugraph::graph_view_t const& graph_view,
float constant_value);
-template edge_property_t, float>
-create_constant_edge_property(raft::handle_t const& handle,
- cugraph::graph_view_t const& graph_view,
- float constant_value);
-
template edge_property_t, float>
create_constant_edge_property(raft::handle_t const& handle,
cugraph::graph_view_t const& graph_view,
@@ -58,12 +47,6 @@ create_constant_edge_property(
cugraph::graph_view_t const& graph_view,
double constant_value);
-template edge_property_t, double>
-create_constant_edge_property(
- raft::handle_t const& handle,
- cugraph::graph_view_t const& graph_view,
- double constant_value);
-
template edge_property_t, double>
create_constant_edge_property(
raft::handle_t const& handle,
@@ -75,11 +58,6 @@ create_constant_edge_property(raft::handle_t const& handle,
cugraph::graph_view_t const& graph_view,
double constant_value);
-template edge_property_t, double>
-create_constant_edge_property(raft::handle_t const& handle,
- cugraph::graph_view_t const& graph_view,
- double constant_value);
-
template edge_property_t, double>
create_constant_edge_property(raft::handle_t const& handle,
cugraph::graph_view_t const& graph_view,
diff --git a/cpp/src/c_api/graph_helper_sg.cu b/cpp/src/c_api/graph_helper_sg.cu
index 86efa0d7bed..5426a2294e1 100644
--- a/cpp/src/c_api/graph_helper_sg.cu
+++ b/cpp/src/c_api/graph_helper_sg.cu
@@ -48,12 +48,6 @@ create_constant_edge_property(
cugraph::graph_view_t const& graph_view,
float constant_value);
-template edge_property_t, float>
-create_constant_edge_property(
- raft::handle_t const& handle,
- cugraph::graph_view_t const& graph_view,
- float constant_value);
-
template edge_property_t, float>
create_constant_edge_property(
raft::handle_t const& handle,
@@ -66,12 +60,6 @@ create_constant_edge_property(
cugraph::graph_view_t const& graph_view,
float constant_value);
-template edge_property_t, float>
-create_constant_edge_property(
- raft::handle_t const& handle,
- cugraph::graph_view_t const& graph_view,
- float constant_value);
-
template edge_property_t, float>
create_constant_edge_property(
raft::handle_t const& handle,
@@ -84,12 +72,6 @@ create_constant_edge_property(
cugraph::graph_view_t const& graph_view,
double constant_value);
-template edge_property_t, double>
-create_constant_edge_property(
- raft::handle_t const& handle,
- cugraph::graph_view_t const& graph_view,
- double constant_value);
-
template edge_property_t, double>
create_constant_edge_property(
raft::handle_t const& handle,
@@ -102,12 +84,6 @@ create_constant_edge_property(
cugraph::graph_view_t const& graph_view,
double constant_value);
-template edge_property_t, double>
-create_constant_edge_property(
- raft::handle_t const& handle,
- cugraph::graph_view_t const& graph_view,
- double constant_value);
-
template edge_property_t, double>
create_constant_edge_property(
raft::handle_t const& handle,
diff --git a/cpp/src/c_api/graph_mg.cpp b/cpp/src/c_api/graph_mg.cpp
index 2057448dbe5..c63528a9180 100644
--- a/cpp/src/c_api/graph_mg.cpp
+++ b/cpp/src/c_api/graph_mg.cpp
@@ -402,6 +402,14 @@ extern "C" cugraph_error_code_t cugraph_graph_create_mg(
raft::comms::op_t::SUM,
p_handle->handle_->get_stream());
+ cugraph_data_type_id_t edge_type{vertex_type};
+
+ if (vertex_type == cugraph_data_type_id_t::INT32)
+ CAPI_EXPECTS(num_edges < int32_threshold,
+ CUGRAPH_INVALID_INPUT,
+ "Number of edges won't fit in 32-bit integer, using 32-bit type",
+ *error);
+
auto vertex_types = cugraph::host_scalar_allgather(
p_handle->handle_->get_comms(), static_cast(vertex_type), p_handle->handle_->get_stream());
@@ -434,14 +442,6 @@ extern "C" cugraph_error_code_t cugraph_graph_create_mg(
"different weight type used on different GPUs",
*error);
- cugraph_data_type_id_t edge_type;
-
- if (num_edges < int32_threshold) {
- edge_type = static_cast(vertex_types[0]);
- } else {
- edge_type = cugraph_data_type_id_t::INT64;
- }
-
if (weight_type == cugraph_data_type_id_t::NTYPES) {
weight_type = cugraph_data_type_id_t::FLOAT32;
}
diff --git a/cpp/src/c_api/graph_sg.cpp b/cpp/src/c_api/graph_sg.cpp
index ea598b902ae..e57d6b5bb14 100644
--- a/cpp/src/c_api/graph_sg.cpp
+++ b/cpp/src/c_api/graph_sg.cpp
@@ -609,14 +609,14 @@ extern "C" cugraph_error_code_t cugraph_graph_create_sg(
"Invalid input arguments: src size != weights size.",
*error);
- cugraph_data_type_id_t edge_type;
- cugraph_data_type_id_t weight_type;
+ if (p_src->type_ == cugraph_data_type_id_t::INT32)
+ CAPI_EXPECTS(p_src->size_ < int32_threshold,
+ CUGRAPH_INVALID_INPUT,
+ "Number of edges won't fit in 32-bit integer, using 32-bit type",
+ *error);
- if (p_src->size_ < int32_threshold) {
- edge_type = p_src->type_;
- } else {
- edge_type = cugraph_data_type_id_t::INT64;
- }
+ cugraph_data_type_id_t edge_type = p_src->type_;
+ cugraph_data_type_id_t weight_type;
if (weights != nullptr) {
weight_type = p_weights->type_;
@@ -761,7 +761,7 @@ cugraph_error_code_t cugraph_graph_create_sg_from_csr(
p_edge_ids,
p_edge_type_ids,
renumber,
- FALSE, // symmetrize
+ symmetrize,
do_expensive_check);
try {
diff --git a/cpp/src/c_api/lookup_src_dst.cpp b/cpp/src/c_api/lookup_src_dst.cpp
index 1be2137ef2f..3b87791ac50 100644
--- a/cpp/src/c_api/lookup_src_dst.cpp
+++ b/cpp/src/c_api/lookup_src_dst.cpp
@@ -307,23 +307,26 @@ extern "C" cugraph_error_code_t cugraph_lookup_endpoints_from_edge_ids_and_types
{
CAPI_EXPECTS(
reinterpret_cast(graph)->vertex_type_ ==
- reinterpret_cast(lookup_container)->vertex_type_,
+ reinterpret_cast(lookup_container)
+ ->vertex_type_,
CUGRAPH_INVALID_INPUT,
"vertex type of graph and lookup_container must match",
*error);
CAPI_EXPECTS(
reinterpret_cast(graph)->edge_type_ ==
- reinterpret_cast(lookup_container)->edge_type_,
+ reinterpret_cast(lookup_container)
+ ->edge_type_,
CUGRAPH_INVALID_INPUT,
"edge type of graph and lookup_container must match",
*error);
- CAPI_EXPECTS(reinterpret_cast(graph)->edge_type_id_type_ ==
- reinterpret_cast(lookup_container)
- ->edge_type_id_type_,
- CUGRAPH_INVALID_INPUT,
- "edge type id type of graph and lookup_container must match",
- *error);
+ CAPI_EXPECTS(
+ reinterpret_cast(graph)->edge_type_id_type_ ==
+ reinterpret_cast(lookup_container)
+ ->edge_type_id_type_,
+ CUGRAPH_INVALID_INPUT,
+ "edge type id type of graph and lookup_container must match",
+ *error);
lookup_using_edge_ids_and_types_functor functor(
handle, graph, lookup_container, edge_ids_to_lookup, edge_types_to_lookup);
@@ -341,23 +344,26 @@ extern "C" cugraph_error_code_t cugraph_lookup_endpoints_from_edge_ids_and_singl
{
CAPI_EXPECTS(
reinterpret_cast(graph)->vertex_type_ ==
- reinterpret_cast(lookup_container)->vertex_type_,
+ reinterpret_cast(lookup_container)
+ ->vertex_type_,
CUGRAPH_INVALID_INPUT,
"vertex type of graph and lookup_container must match",
*error);
CAPI_EXPECTS(
reinterpret_cast(graph)->edge_type_ ==
- reinterpret_cast(lookup_container)->edge_type_,
+ reinterpret_cast(lookup_container)
+ ->edge_type_,
CUGRAPH_INVALID_INPUT,
"edge type of graph and lookup_container must match",
*error);
- CAPI_EXPECTS(reinterpret_cast(graph)->edge_type_id_type_ ==
- reinterpret_cast(lookup_container)
- ->edge_type_id_type_,
- CUGRAPH_INVALID_INPUT,
- "edge type id type of graph and lookup_container must match",
- *error);
+ CAPI_EXPECTS(
+ reinterpret_cast(graph)->edge_type_id_type_ ==
+ reinterpret_cast(lookup_container)
+ ->edge_type_id_type_,
+ CUGRAPH_INVALID_INPUT,
+ "edge type id type of graph and lookup_container must match",
+ *error);
lookup_using_edge_ids_of_single_type_functor functor(
handle, graph, lookup_container, edge_ids_to_lookup, edge_type_to_lookup);
@@ -387,3 +393,10 @@ extern "C" void cugraph_lookup_result_free(cugraph_lookup_result_t* result)
delete internal_pointer->dsts_;
delete internal_pointer;
}
+
+extern "C" void cugraph_lookup_container_free(cugraph_lookup_container_t* container)
+{
+ auto internal_ptr = reinterpret_cast(container);
+ // The graph should presumably own the other structures.
+ delete internal_ptr;
+}
diff --git a/cpp/src/c_api/neighbor_sampling.cpp b/cpp/src/c_api/neighbor_sampling.cpp
index 69306806030..be3a44d813a 100644
--- a/cpp/src/c_api/neighbor_sampling.cpp
+++ b/cpp/src/c_api/neighbor_sampling.cpp
@@ -16,12 +16,15 @@
#include "c_api/abstract_functor.hpp"
#include "c_api/graph.hpp"
+#include "c_api/graph_helper.hpp"
#include "c_api/properties.hpp"
#include "c_api/random.hpp"
#include "c_api/resource_handle.hpp"
#include "c_api/utils.hpp"
+#include "sampling/detail/sampling_utils.hpp"
#include
+#include
#include
#include
@@ -44,6 +47,13 @@ struct cugraph_sampling_options_t {
bool_t retain_seeds_{FALSE};
};
+struct sampling_flags_t {
+ prior_sources_behavior_t prior_sources_behavior_{prior_sources_behavior_t::DEFAULT};
+ bool_t return_hops_{FALSE};
+ bool_t dedupe_sources_{FALSE};
+ bool_t with_replacement_{FALSE};
+};
+
struct cugraph_sample_result_t {
cugraph_type_erased_device_array_t* major_offsets_{nullptr};
cugraph_type_erased_device_array_t* majors_{nullptr};
@@ -56,6 +66,8 @@ struct cugraph_sample_result_t {
cugraph_type_erased_device_array_t* label_{nullptr};
cugraph_type_erased_device_array_t* renumber_map_{nullptr};
cugraph_type_erased_device_array_t* renumber_map_offsets_{nullptr};
+ cugraph_type_erased_device_array_t* edge_renumber_map_{nullptr};
+ cugraph_type_erased_device_array_t* edge_renumber_map_offsets_{nullptr};
};
} // namespace c_api
@@ -63,6 +75,7 @@ struct cugraph_sample_result_t {
namespace {
+// Deprecated functor
struct uniform_neighbor_sampling_functor : public cugraph::c_api::abstract_functor {
raft::handle_t const& handle_;
cugraph::c_api::cugraph_graph_t* graph_{nullptr};
@@ -398,11 +411,14 @@ struct uniform_neighbor_sampling_functor : public cugraph::c_api::abstract_funct
: nullptr,
(renumber_map_offsets) ? new cugraph::c_api::cugraph_type_erased_device_array_t(
renumber_map_offsets.value(), SIZE_T)
- : nullptr};
+ : nullptr,
+ nullptr,
+ nullptr};
}
}
};
+// Deprecated functor
struct biased_neighbor_sampling_functor : public cugraph::c_api::abstract_functor {
raft::handle_t const& handle_;
cugraph::c_api::cugraph_graph_t* graph_{nullptr};
@@ -748,7 +764,598 @@ struct biased_neighbor_sampling_functor : public cugraph::c_api::abstract_functo
: nullptr,
(renumber_map_offsets) ? new cugraph::c_api::cugraph_type_erased_device_array_t(
renumber_map_offsets.value(), SIZE_T)
- : nullptr};
+ : nullptr,
+ nullptr,
+ nullptr};
+ }
+ }
+};
+
+struct neighbor_sampling_functor : public cugraph::c_api::abstract_functor {
+ raft::handle_t const& handle_;
+ cugraph::c_api::cugraph_rng_state_t* rng_state_{nullptr};
+ cugraph::c_api::cugraph_graph_t* graph_{nullptr};
+ cugraph::c_api::cugraph_edge_property_view_t const* edge_biases_{nullptr};
+ cugraph::c_api::cugraph_type_erased_device_array_view_t const* start_vertices_{nullptr};
+ cugraph::c_api::cugraph_type_erased_device_array_view_t const* start_vertex_offsets_{nullptr};
+ cugraph::c_api::cugraph_type_erased_host_array_view_t const* fan_out_{nullptr};
+ int num_edge_types_{};
+ cugraph::c_api::cugraph_sampling_options_t options_{};
+ bool is_biased_{false};
+ bool do_expensive_check_{false};
+ cugraph::c_api::cugraph_sample_result_t* result_{nullptr};
+
+ neighbor_sampling_functor(cugraph_resource_handle_t const* handle,
+ cugraph_rng_state_t* rng_state,
+ cugraph_graph_t* graph,
+ cugraph_edge_property_view_t const* edge_biases,
+ cugraph_type_erased_device_array_view_t const* start_vertices,
+ cugraph_type_erased_device_array_view_t const* start_vertex_offsets,
+ cugraph_type_erased_host_array_view_t const* fan_out,
+ int num_edge_types,
+ cugraph::c_api::cugraph_sampling_options_t options,
+ bool is_biased,
+ bool do_expensive_check)
+ : abstract_functor(),
+ handle_(*reinterpret_cast(handle)->handle_),
+ rng_state_(reinterpret_cast(rng_state)),
+ graph_(reinterpret_cast(graph)),
+ edge_biases_(
+ reinterpret_cast(edge_biases)),
+ start_vertices_(
+ reinterpret_cast(
+ start_vertices)),
+ start_vertex_offsets_(
+ reinterpret_cast(
+ start_vertex_offsets)),
+ fan_out_(
+ reinterpret_cast(fan_out)),
+ num_edge_types_(num_edge_types),
+ options_(options),
+ is_biased_(is_biased),
+ do_expensive_check_(do_expensive_check)
+ {
+ }
+
+ template
+ void operator()()
+ {
+ using label_t = int32_t;
+
+ // FIXME: Think about how to handle SG vice MG
+ if constexpr (!cugraph::is_candidate::value) {
+ unsupported();
+ } else {
+ // uniform_nbr_sample expects store_transposed == false
+ if constexpr (store_transposed) {
+ error_code_ = cugraph::c_api::
+ transpose_storage(
+ handle_, graph_, error_.get());
+ if (error_code_ != CUGRAPH_SUCCESS) return;
+ }
+
+ auto graph =
+ reinterpret_cast*>(graph_->graph_);
+
+ auto graph_view = graph->view();
+
+ auto edge_weights = reinterpret_cast<
+ cugraph::edge_property_t,
+ weight_t>*>(graph_->edge_weights_);
+
+ auto edge_ids = reinterpret_cast<
+ cugraph::edge_property_t,
+ edge_t>*>(graph_->edge_ids_);
+
+ auto edge_types = reinterpret_cast<
+ cugraph::edge_property_t,
+ edge_type_t>*>(graph_->edge_types_);
+
+ auto number_map = reinterpret_cast*>(graph_->number_map_);
+
+ auto edge_biases =
+ edge_biases_ ? reinterpret_cast*>(
+ edge_biases_->edge_property_)
+ : nullptr;
+
+ rmm::device_uvector start_vertices(start_vertices_->size_, handle_.get_stream());
+ raft::copy(start_vertices.data(),
+ start_vertices_->as_type(),
+ start_vertices.size(),
+ handle_.get_stream());
+
+ std::optional> start_vertex_labels{std::nullopt};
+ std::optional> local_label_to_comm_rank{std::nullopt};
+ std::optional> label_to_comm_rank{
+ std::nullopt}; // global after allgatherv
+
+ std::optional> renumbered_and_sorted_edge_id_renumber_map(
+ std::nullopt);
+ std::optional>
+ renumbered_and_sorted_edge_id_renumber_map_label_type_offsets(std::nullopt);
+
+ if (start_vertex_offsets_ != nullptr) {
+ // Retrieve the start_vertex_labels
+ start_vertex_labels = cugraph::detail::convert_starting_vertex_label_offsets_to_labels(
+ handle_,
+ raft::device_span{start_vertex_offsets_->as_type(),
+ start_vertex_offsets_->size_});
+
+ // Get the number of labels on each GPU
+
+ if constexpr (multi_gpu) {
+ auto num_local_labels = start_vertex_offsets_->size_ - 1;
+
+ auto global_labels = cugraph::host_scalar_allgather(
+ handle_.get_comms(), num_local_labels, handle_.get_stream());
+
+ std::exclusive_scan(
+ global_labels.begin(), global_labels.end(), global_labels.begin(), label_t{0});
+
+ // Compute the global start_vertex_label_offsets
+
+ cugraph::detail::transform_increment_ints(
+ raft::device_span{(*start_vertex_labels).data(),
+ (*start_vertex_labels).size()},
+ (label_t)global_labels[handle_.get_comms().get_rank()],
+ handle_.get_stream());
+
+ rmm::device_uvector unique_labels((*start_vertex_labels).size(),
+ handle_.get_stream());
+ raft::copy(unique_labels.data(),
+ (*start_vertex_labels).data(),
+ unique_labels.size(),
+ handle_.get_stream());
+
+ // Get unique labels
+ // sort the start_vertex_labels
+ cugraph::detail::sort_ints(
+ handle_.get_stream(),
+ raft::device_span{unique_labels.data(), unique_labels.size()});
+
+ auto num_unique_labels = cugraph::detail::unique_ints(
+ handle_.get_stream(),
+ raft::device_span{unique_labels.data(), unique_labels.size()});
+
+ (*local_label_to_comm_rank).resize(num_unique_labels, handle_.get_stream());
+
+ cugraph::detail::scalar_fill(
+ handle_.get_stream(),
+ (*local_label_to_comm_rank).begin(), // This should be rename to rank
+ (*local_label_to_comm_rank).size(),
+ label_t{handle_.get_comms().get_rank()});
+
+ // Perform allgather to get global_label_to_comm_rank_d_vector
+ auto recvcounts = cugraph::host_scalar_allgather(
+ handle_.get_comms(), num_unique_labels, handle_.get_stream());
+
+ std::vector displacements(recvcounts.size());
+ std::exclusive_scan(
+ recvcounts.begin(), recvcounts.end(), displacements.begin(), size_t{0});
+
+ (*label_to_comm_rank)
+ .resize(displacements.back() + recvcounts.back(), handle_.get_stream());
+
+ cugraph::device_allgatherv(handle_.get_comms(),
+ (*local_label_to_comm_rank).begin(),
+ (*label_to_comm_rank).begin(),
+ recvcounts,
+ displacements,
+ handle_.get_stream());
+
+ std::tie(start_vertices, *start_vertex_labels) =
+ cugraph::detail::shuffle_ext_vertex_value_pairs_to_local_gpu_by_vertex_partitioning(
+ handle_, std::move(start_vertices), std::move(*start_vertex_labels));
+ }
+ } else {
+ if constexpr (multi_gpu) {
+ start_vertices =
+ cugraph::detail::shuffle_ext_vertices_to_local_gpu_by_vertex_partitioning(
+ handle_, std::move(start_vertices));
+ }
+ }
+ //
+ // Need to renumber start_vertices
+ //
+ cugraph::renumber_local_ext_vertices(
+ handle_,
+ start_vertices.data(),
+ start_vertices.size(),
+ number_map->data(),
+ graph_view.local_vertex_partition_range_first(),
+ graph_view.local_vertex_partition_range_last(),
+ do_expensive_check_);
+
+ rmm::device_uvector src(0, handle_.get_stream());
+ rmm::device_uvector dst(0, handle_.get_stream());
+ std::optional> wgt{std::nullopt};
+ std::optional> edge_id{std::nullopt};
+ std::optional> edge_type{std::nullopt};
+ std::optional> hop{std::nullopt};
+ std::optional> edge_label{std::nullopt};
+ std::optional> offsets{std::nullopt};
+
+ // FIXME: For biased sampling, the user should pass either biases or edge weights,
+ // otherwised throw an error and suggest the user to call uniform neighbor sample instead
+
+ if (num_edge_types_ > 1) {
+ // call heterogeneous neighbor sample
+ if (is_biased_) {
+ std::tie(src, dst, wgt, edge_id, edge_type, hop, offsets) =
+ cugraph::heterogeneous_biased_neighbor_sample(
+ handle_,
+ rng_state_->rng_state_,
+ graph_view,
+ (edge_weights != nullptr) ? std::make_optional(edge_weights->view()) : std::nullopt,
+ (edge_ids != nullptr) ? std::make_optional(edge_ids->view()) : std::nullopt,
+ (edge_types != nullptr) ? std::make_optional(edge_types->view()) : std::nullopt,
+ (edge_biases != nullptr) ? *edge_biases : edge_weights->view(),
+ raft::device_span{start_vertices.data(), start_vertices.size()},
+ (start_vertex_offsets_ != nullptr)
+ ? std::make_optional>((*start_vertex_labels).data(),
+ (*start_vertex_labels).size())
+ : std::nullopt,
+ label_to_comm_rank ? std::make_optional(raft::device_span{
+ (*label_to_comm_rank).data(), (*label_to_comm_rank).size()})
+ : std::nullopt,
+ raft::host_span(fan_out_->as_type(), fan_out_->size_),
+ num_edge_types_,
+ cugraph::sampling_flags_t{options_.prior_sources_behavior_,
+ options_.return_hops_,
+ options_.dedupe_sources_,
+ options_.with_replacement_},
+ do_expensive_check_);
+ } else {
+ std::tie(src, dst, wgt, edge_id, edge_type, hop, offsets) =
+ cugraph::heterogeneous_uniform_neighbor_sample(
+ handle_,
+ rng_state_->rng_state_,
+ graph_view,
+ (edge_weights != nullptr) ? std::make_optional(edge_weights->view()) : std::nullopt,
+ (edge_ids != nullptr) ? std::make_optional(edge_ids->view()) : std::nullopt,
+ (edge_types != nullptr) ? std::make_optional(edge_types->view()) : std::nullopt,
+ raft::device_span{start_vertices.data(), start_vertices.size()},
+ (start_vertex_offsets_ != nullptr)
+ ? std::make_optional>((*start_vertex_labels).data(),
+ (*start_vertex_labels).size())
+ : std::nullopt,
+ label_to_comm_rank ? std::make_optional(raft::device_span{
+ (*label_to_comm_rank).data(), (*label_to_comm_rank).size()})
+ : std::nullopt,
+ raft::host_span(fan_out_->as_type(), fan_out_->size_),
+ num_edge_types_,
+ cugraph::sampling_flags_t{options_.prior_sources_behavior_,
+ options_.return_hops_,
+ options_.dedupe_sources_,
+ options_.with_replacement_},
+ do_expensive_check_);
+ }
+ } else {
+ // Call homogeneous neighbor sample
+ if (is_biased_) {
+ std::tie(src, dst, wgt, edge_id, edge_type, hop, offsets) =
+ cugraph::homogeneous_biased_neighbor_sample(
+ handle_,
+ rng_state_->rng_state_,
+ graph_view,
+ (edge_weights != nullptr) ? std::make_optional(edge_weights->view()) : std::nullopt,
+ (edge_ids != nullptr) ? std::make_optional(edge_ids->view()) : std::nullopt,
+ (edge_types != nullptr) ? std::make_optional(edge_types->view()) : std::nullopt,
+ (edge_biases != nullptr) ? *edge_biases : edge_weights->view(),
+ raft::device_span{start_vertices.data(), start_vertices.size()},
+ (start_vertex_offsets_ != nullptr)
+ ? std::make_optional>((*start_vertex_labels).data(),
+ (*start_vertex_labels).size())
+ : std::nullopt,
+ label_to_comm_rank ? std::make_optional(raft::device_span{
+ (*label_to_comm_rank).data(), (*label_to_comm_rank).size()})
+ : std::nullopt,
+ raft::host_span(fan_out_->as_type