diff --git a/.devcontainer/cuda11.8-conda/devcontainer.json b/.devcontainer/cuda11.8-conda/devcontainer.json index 9c83535b771..f5886540252 100644 --- a/.devcontainer/cuda11.8-conda/devcontainer.json +++ b/.devcontainer/cuda11.8-conda/devcontainer.json @@ -5,17 +5,17 @@ "args": { "CUDA": "11.8", "PYTHON_PACKAGE_MANAGER": "conda", - "BASE": "rapidsai/devcontainers:24.10-cpp-cuda11.8-mambaforge-ubuntu22.04" + "BASE": "rapidsai/devcontainers:24.12-cpp-cuda11.8-mambaforge-ubuntu22.04" } }, "runArgs": [ "--rm", "--name", - "${localEnv:USER:anon}-rapids-${localWorkspaceFolderBasename}-24.10-cuda11.8-conda" + "${localEnv:USER:anon}-rapids-${localWorkspaceFolderBasename}-24.12-cuda11.8-conda" ], "hostRequirements": {"gpu": "optional"}, "features": { - "ghcr.io/rapidsai/devcontainers/features/rapids-build-utils:24.10": {} + "ghcr.io/rapidsai/devcontainers/features/rapids-build-utils:24.12": {} }, "overrideFeatureInstallOrder": [ "ghcr.io/rapidsai/devcontainers/features/rapids-build-utils" diff --git a/.devcontainer/cuda11.8-pip/devcontainer.json b/.devcontainer/cuda11.8-pip/devcontainer.json index a559be18077..270bfa239ad 100644 --- a/.devcontainer/cuda11.8-pip/devcontainer.json +++ b/.devcontainer/cuda11.8-pip/devcontainer.json @@ -5,24 +5,24 @@ "args": { "CUDA": "11.8", "PYTHON_PACKAGE_MANAGER": "pip", - "BASE": "rapidsai/devcontainers:24.10-cpp-cuda11.8-ucx1.15.0-openmpi-ubuntu22.04" + "BASE": "rapidsai/devcontainers:24.12-cpp-cuda11.8-ucx1.15.0-openmpi-ubuntu22.04" } }, "runArgs": [ "--rm", "--name", - "${localEnv:USER:anon}-rapids-${localWorkspaceFolderBasename}-24.10-cuda11.8-pip" + "${localEnv:USER:anon}-rapids-${localWorkspaceFolderBasename}-24.12-cuda11.8-pip" ], "hostRequirements": {"gpu": "optional"}, "features": { - "ghcr.io/rapidsai/devcontainers/features/cuda:24.10": { + "ghcr.io/rapidsai/devcontainers/features/cuda:24.12": { "version": "11.8", "installcuBLAS": true, "installcuSOLVER": true, "installcuRAND": true, "installcuSPARSE": true }, - "ghcr.io/rapidsai/devcontainers/features/rapids-build-utils:24.10": {} + "ghcr.io/rapidsai/devcontainers/features/rapids-build-utils:24.12": {} }, "overrideFeatureInstallOrder": [ "ghcr.io/rapidsai/devcontainers/features/cuda", diff --git a/.devcontainer/cuda12.5-conda/devcontainer.json b/.devcontainer/cuda12.5-conda/devcontainer.json index ca10c04edee..e31428e4b0c 100644 --- a/.devcontainer/cuda12.5-conda/devcontainer.json +++ b/.devcontainer/cuda12.5-conda/devcontainer.json @@ -5,17 +5,17 @@ "args": { "CUDA": "12.5", "PYTHON_PACKAGE_MANAGER": "conda", - "BASE": "rapidsai/devcontainers:24.10-cpp-mambaforge-ubuntu22.04" + "BASE": "rapidsai/devcontainers:24.12-cpp-mambaforge-ubuntu22.04" } }, "runArgs": [ "--rm", "--name", - "${localEnv:USER:anon}-rapids-${localWorkspaceFolderBasename}-24.10-cuda12.5-conda" + "${localEnv:USER:anon}-rapids-${localWorkspaceFolderBasename}-24.12-cuda12.5-conda" ], "hostRequirements": {"gpu": "optional"}, "features": { - "ghcr.io/rapidsai/devcontainers/features/rapids-build-utils:24.10": {} + "ghcr.io/rapidsai/devcontainers/features/rapids-build-utils:24.12": {} }, "overrideFeatureInstallOrder": [ "ghcr.io/rapidsai/devcontainers/features/rapids-build-utils" diff --git a/.devcontainer/cuda12.5-pip/devcontainer.json b/.devcontainer/cuda12.5-pip/devcontainer.json index 6e2bf45700a..835274999ba 100644 --- a/.devcontainer/cuda12.5-pip/devcontainer.json +++ b/.devcontainer/cuda12.5-pip/devcontainer.json @@ -5,24 +5,24 @@ "args": { "CUDA": "12.5", "PYTHON_PACKAGE_MANAGER": "pip", - "BASE": "rapidsai/devcontainers:24.10-cpp-cuda12.5-ucx1.17.0-openmpi-ubuntu22.04" + "BASE": "rapidsai/devcontainers:24.12-cpp-cuda12.5-ucx1.17.0-openmpi-ubuntu22.04" } }, "runArgs": [ "--rm", "--name", - "${localEnv:USER:anon}-rapids-${localWorkspaceFolderBasename}-24.10-cuda12.5-pip" + "${localEnv:USER:anon}-rapids-${localWorkspaceFolderBasename}-24.12-cuda12.5-pip" ], "hostRequirements": {"gpu": "optional"}, "features": { - "ghcr.io/rapidsai/devcontainers/features/cuda:24.10": { + "ghcr.io/rapidsai/devcontainers/features/cuda:24.12": { "version": "12.5", "installcuBLAS": true, "installcuSOLVER": true, "installcuRAND": true, "installcuSPARSE": true }, - "ghcr.io/rapidsai/devcontainers/features/rapids-build-utils:24.10": {} + "ghcr.io/rapidsai/devcontainers/features/rapids-build-utils:24.12": {} }, "overrideFeatureInstallOrder": [ "ghcr.io/rapidsai/devcontainers/features/cuda", diff --git a/.github/workflows/build.yaml b/.github/workflows/build.yaml index 3ad8aef5820..b272fb43e35 100644 --- a/.github/workflows/build.yaml +++ b/.github/workflows/build.yaml @@ -28,7 +28,7 @@ concurrency: jobs: cpp-build: secrets: inherit - uses: rapidsai/shared-workflows/.github/workflows/conda-cpp-build.yaml@python-3.12 + uses: rapidsai/shared-workflows/.github/workflows/conda-cpp-build.yaml@branch-24.12 with: build_type: ${{ inputs.build_type || 'branch' }} branch: ${{ inputs.branch }} @@ -38,7 +38,7 @@ jobs: python-build: needs: [cpp-build] secrets: inherit - uses: rapidsai/shared-workflows/.github/workflows/conda-python-build.yaml@python-3.12 + uses: rapidsai/shared-workflows/.github/workflows/conda-python-build.yaml@branch-24.12 with: build_type: ${{ inputs.build_type || 'branch' }} branch: ${{ inputs.branch }} @@ -47,7 +47,7 @@ jobs: upload-conda: needs: [cpp-build, python-build] secrets: inherit - uses: rapidsai/shared-workflows/.github/workflows/conda-upload-packages.yaml@python-3.12 + uses: rapidsai/shared-workflows/.github/workflows/conda-upload-packages.yaml@branch-24.12 with: build_type: ${{ inputs.build_type || 'branch' }} branch: ${{ inputs.branch }} @@ -57,7 +57,7 @@ jobs: if: github.ref_type == 'branch' needs: python-build secrets: inherit - uses: rapidsai/shared-workflows/.github/workflows/custom-job.yaml@python-3.12 + uses: rapidsai/shared-workflows/.github/workflows/custom-job.yaml@branch-24.12 with: arch: "amd64" branch: ${{ inputs.branch }} @@ -69,7 +69,7 @@ jobs: sha: ${{ inputs.sha }} wheel-build-pylibcugraph: secrets: inherit - uses: rapidsai/shared-workflows/.github/workflows/wheels-build.yaml@python-3.12 + uses: rapidsai/shared-workflows/.github/workflows/wheels-build.yaml@branch-24.12 with: build_type: ${{ inputs.build_type || 'branch' }} branch: ${{ inputs.branch }} @@ -77,13 +77,13 @@ jobs: date: ${{ inputs.date }} script: ci/build_wheel_pylibcugraph.sh extra-repo: rapidsai/cugraph-ops - extra-repo-sha: branch-24.10 + extra-repo-sha: branch-24.12 extra-repo-deploy-key: CUGRAPH_OPS_SSH_PRIVATE_DEPLOY_KEY node_type: cpu32 wheel-publish-pylibcugraph: needs: wheel-build-pylibcugraph secrets: inherit - uses: rapidsai/shared-workflows/.github/workflows/wheels-publish.yaml@python-3.12 + uses: rapidsai/shared-workflows/.github/workflows/wheels-publish.yaml@branch-24.12 with: build_type: ${{ inputs.build_type || 'branch' }} branch: ${{ inputs.branch }} @@ -93,7 +93,7 @@ jobs: wheel-build-cugraph: needs: wheel-publish-pylibcugraph secrets: inherit - uses: rapidsai/shared-workflows/.github/workflows/wheels-build.yaml@python-3.12 + uses: rapidsai/shared-workflows/.github/workflows/wheels-build.yaml@branch-24.12 with: build_type: ${{ inputs.build_type || 'branch' }} branch: ${{ inputs.branch }} @@ -101,12 +101,12 @@ jobs: date: ${{ inputs.date }} script: ci/build_wheel_cugraph.sh extra-repo: rapidsai/cugraph-ops - extra-repo-sha: branch-24.10 + extra-repo-sha: branch-24.12 extra-repo-deploy-key: CUGRAPH_OPS_SSH_PRIVATE_DEPLOY_KEY wheel-publish-cugraph: needs: wheel-build-cugraph secrets: inherit - uses: rapidsai/shared-workflows/.github/workflows/wheels-publish.yaml@python-3.12 + uses: rapidsai/shared-workflows/.github/workflows/wheels-publish.yaml@branch-24.12 with: build_type: ${{ inputs.build_type || 'branch' }} branch: ${{ inputs.branch }} @@ -116,7 +116,7 @@ jobs: wheel-build-nx-cugraph: needs: wheel-publish-pylibcugraph secrets: inherit - uses: rapidsai/shared-workflows/.github/workflows/wheels-build.yaml@python-3.12 + uses: rapidsai/shared-workflows/.github/workflows/wheels-build.yaml@branch-24.12 with: build_type: ${{ inputs.build_type || 'branch' }} branch: ${{ inputs.branch }} @@ -126,7 +126,7 @@ jobs: wheel-publish-nx-cugraph: needs: wheel-build-nx-cugraph secrets: inherit - uses: rapidsai/shared-workflows/.github/workflows/wheels-publish.yaml@python-3.12 + uses: rapidsai/shared-workflows/.github/workflows/wheels-publish.yaml@branch-24.12 with: build_type: ${{ inputs.build_type || 'branch' }} branch: ${{ inputs.branch }} @@ -136,7 +136,7 @@ jobs: wheel-build-cugraph-dgl: needs: wheel-publish-cugraph secrets: inherit - uses: rapidsai/shared-workflows/.github/workflows/wheels-build.yaml@python-3.12 + uses: rapidsai/shared-workflows/.github/workflows/wheels-build.yaml@branch-24.12 with: build_type: ${{ inputs.build_type || 'branch' }} branch: ${{ inputs.branch }} @@ -146,7 +146,7 @@ jobs: wheel-publish-cugraph-dgl: needs: wheel-build-cugraph-dgl secrets: inherit - uses: rapidsai/shared-workflows/.github/workflows/wheels-publish.yaml@python-3.12 + uses: rapidsai/shared-workflows/.github/workflows/wheels-publish.yaml@branch-24.12 with: build_type: ${{ inputs.build_type || 'branch' }} branch: ${{ inputs.branch }} @@ -156,7 +156,7 @@ jobs: wheel-build-cugraph-pyg: needs: wheel-publish-cugraph secrets: inherit - uses: rapidsai/shared-workflows/.github/workflows/wheels-build.yaml@python-3.12 + uses: rapidsai/shared-workflows/.github/workflows/wheels-build.yaml@branch-24.12 with: build_type: ${{ inputs.build_type || 'branch' }} branch: ${{ inputs.branch }} @@ -166,7 +166,7 @@ jobs: wheel-publish-cugraph-pyg: needs: wheel-build-cugraph-pyg secrets: inherit - uses: rapidsai/shared-workflows/.github/workflows/wheels-publish.yaml@python-3.12 + uses: rapidsai/shared-workflows/.github/workflows/wheels-publish.yaml@branch-24.12 with: build_type: ${{ inputs.build_type || 'branch' }} branch: ${{ inputs.branch }} @@ -175,7 +175,7 @@ jobs: package-name: cugraph-pyg wheel-build-cugraph-equivariant: secrets: inherit - uses: rapidsai/shared-workflows/.github/workflows/wheels-build.yaml@python-3.12 + uses: rapidsai/shared-workflows/.github/workflows/wheels-build.yaml@branch-24.12 with: build_type: ${{ inputs.build_type || 'branch' }} branch: ${{ inputs.branch }} @@ -185,7 +185,7 @@ jobs: wheel-publish-cugraph-equivariant: needs: wheel-build-cugraph-equivariant secrets: inherit - uses: rapidsai/shared-workflows/.github/workflows/wheels-publish.yaml@python-3.12 + uses: rapidsai/shared-workflows/.github/workflows/wheels-publish.yaml@branch-24.12 with: build_type: ${{ inputs.build_type || 'branch' }} branch: ${{ inputs.branch }} diff --git a/.github/workflows/pr.yaml b/.github/workflows/pr.yaml index d25a0b81b13..b0a1308237e 100644 --- a/.github/workflows/pr.yaml +++ b/.github/workflows/pr.yaml @@ -12,6 +12,7 @@ concurrency: jobs: pr-builder: needs: + - changed-files - checks - conda-cpp-build - conda-cpp-tests @@ -34,29 +35,69 @@ jobs: - wheel-tests-cugraph-equivariant - devcontainer secrets: inherit - uses: rapidsai/shared-workflows/.github/workflows/pr-builder.yaml@python-3.12 + uses: rapidsai/shared-workflows/.github/workflows/pr-builder.yaml@branch-24.12 + if: always() + with: + needs: ${{ toJSON(needs) }} + changed-files: + secrets: inherit + uses: rapidsai/shared-workflows/.github/workflows/changed-files.yaml@branch-24.12 + with: + files_yaml: | + test_cpp: + - '**' + - '!.devcontainers/**' + - '!CONTRIBUTING.md' + - '!README.md' + - '!docs/**' + - '!img/**' + - '!mg_utils/**' + - '!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/**' + - '!CONTRIBUTING.md' + - '!README.md' + - '!docs/**' + - '!img/**' + - '!notebooks/**' + # TODO: Remove this before merging + - '!.github/**' checks: secrets: inherit - uses: rapidsai/shared-workflows/.github/workflows/checks.yaml@python-3.12 + uses: rapidsai/shared-workflows/.github/workflows/checks.yaml@branch-24.12 with: enable_check_generated_files: false conda-cpp-build: needs: checks secrets: inherit - uses: rapidsai/shared-workflows/.github/workflows/conda-cpp-build.yaml@python-3.12 + uses: rapidsai/shared-workflows/.github/workflows/conda-cpp-build.yaml@branch-24.12 with: build_type: pull-request node_type: cpu32 conda-cpp-tests: - needs: conda-cpp-build + needs: [conda-cpp-build, changed-files] secrets: inherit - uses: rapidsai/shared-workflows/.github/workflows/conda-cpp-tests.yaml@python-3.12 + uses: rapidsai/shared-workflows/.github/workflows/conda-cpp-tests.yaml@branch-24.12 + if: fromJSON(needs.changed-files.outputs.changed_file_groups).test_cpp with: build_type: pull-request conda-cpp-checks: needs: conda-cpp-build secrets: inherit - uses: rapidsai/shared-workflows/.github/workflows/conda-cpp-post-build-checks.yaml@python-3.12 + uses: rapidsai/shared-workflows/.github/workflows/conda-cpp-post-build-checks.yaml@branch-24.12 with: build_type: pull-request enable_check_symbols: true @@ -64,19 +105,21 @@ jobs: conda-python-build: needs: conda-cpp-build secrets: inherit - uses: rapidsai/shared-workflows/.github/workflows/conda-python-build.yaml@python-3.12 + uses: rapidsai/shared-workflows/.github/workflows/conda-python-build.yaml@branch-24.12 with: build_type: pull-request conda-python-tests: - needs: conda-python-build + needs: [conda-python-build, changed-files] secrets: inherit - uses: rapidsai/shared-workflows/.github/workflows/conda-python-tests.yaml@python-3.12 + uses: rapidsai/shared-workflows/.github/workflows/conda-python-tests.yaml@branch-24.12 + if: fromJSON(needs.changed-files.outputs.changed_file_groups).test_python with: build_type: pull-request conda-notebook-tests: - needs: conda-python-build + needs: [conda-python-build, changed-files] secrets: inherit - uses: rapidsai/shared-workflows/.github/workflows/custom-job.yaml@python-3.12 + uses: rapidsai/shared-workflows/.github/workflows/custom-job.yaml@branch-24.12 + if: fromJSON(needs.changed-files.outputs.changed_file_groups).test_notebooks with: build_type: pull-request node_type: "gpu-v100-latest-1" @@ -86,7 +129,7 @@ jobs: docs-build: needs: conda-python-build secrets: inherit - uses: rapidsai/shared-workflows/.github/workflows/custom-job.yaml@python-3.12 + uses: rapidsai/shared-workflows/.github/workflows/custom-job.yaml@branch-24.12 with: build_type: pull-request node_type: "gpu-v100-latest-1" @@ -96,63 +139,67 @@ jobs: wheel-build-pylibcugraph: needs: checks secrets: inherit - uses: rapidsai/shared-workflows/.github/workflows/wheels-build.yaml@python-3.12 + uses: rapidsai/shared-workflows/.github/workflows/wheels-build.yaml@branch-24.12 with: build_type: pull-request script: ci/build_wheel_pylibcugraph.sh extra-repo: rapidsai/cugraph-ops - extra-repo-sha: branch-24.10 + extra-repo-sha: branch-24.12 extra-repo-deploy-key: CUGRAPH_OPS_SSH_PRIVATE_DEPLOY_KEY node_type: cpu32 wheel-tests-pylibcugraph: - needs: wheel-build-pylibcugraph + needs: [wheel-build-pylibcugraph, changed-files] secrets: inherit - uses: rapidsai/shared-workflows/.github/workflows/wheels-test.yaml@python-3.12 + 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_pylibcugraph.sh wheel-build-cugraph: needs: wheel-tests-pylibcugraph secrets: inherit - uses: rapidsai/shared-workflows/.github/workflows/wheels-build.yaml@python-3.12 + uses: rapidsai/shared-workflows/.github/workflows/wheels-build.yaml@branch-24.12 with: build_type: pull-request script: ci/build_wheel_cugraph.sh extra-repo: rapidsai/cugraph-ops - extra-repo-sha: branch-24.10 + extra-repo-sha: branch-24.12 extra-repo-deploy-key: CUGRAPH_OPS_SSH_PRIVATE_DEPLOY_KEY wheel-tests-cugraph: - needs: wheel-build-cugraph + needs: [wheel-build-cugraph, changed-files] secrets: inherit - uses: rapidsai/shared-workflows/.github/workflows/wheels-test.yaml@python-3.12 + 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.sh wheel-build-nx-cugraph: needs: wheel-tests-pylibcugraph secrets: inherit - uses: rapidsai/shared-workflows/.github/workflows/wheels-build.yaml@python-3.12 + 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 + needs: [wheel-build-nx-cugraph, changed-files] secrets: inherit - uses: rapidsai/shared-workflows/.github/workflows/wheels-test.yaml@python-3.12 + 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@python-3.12 + 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 + needs: [wheel-build-cugraph-dgl, changed-files] secrets: inherit - uses: rapidsai/shared-workflows/.github/workflows/wheels-test.yaml@python-3.12 + 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 @@ -160,35 +207,37 @@ jobs: wheel-build-cugraph-pyg: needs: wheel-tests-cugraph secrets: inherit - uses: rapidsai/shared-workflows/.github/workflows/wheels-build.yaml@python-3.12 + 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 + needs: [wheel-build-cugraph-pyg, changed-files] secrets: inherit - uses: rapidsai/shared-workflows/.github/workflows/wheels-test.yaml@python-3.12 + 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@python-3.12 + uses: rapidsai/shared-workflows/.github/workflows/wheels-build.yaml@branch-24.12 with: build_type: pull-request script: ci/build_wheel_cugraph-equivariant.sh wheel-tests-cugraph-equivariant: - needs: wheel-build-cugraph-equivariant + needs: [wheel-build-cugraph-equivariant, changed-files] secrets: inherit - uses: rapidsai/shared-workflows/.github/workflows/wheels-test.yaml@python-3.12 + 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-equivariant.sh matrix_filter: map(select(.ARCH == "amd64")) devcontainer: secrets: inherit - uses: rapidsai/shared-workflows/.github/workflows/build-in-devcontainer.yaml@python-3.12 + uses: rapidsai/shared-workflows/.github/workflows/build-in-devcontainer.yaml@branch-24.12 with: arch: '["amd64"]' cuda: '["12.5"]' diff --git a/.github/workflows/test.yaml b/.github/workflows/test.yaml index 32447711811..5fbdd276bd6 100644 --- a/.github/workflows/test.yaml +++ b/.github/workflows/test.yaml @@ -16,7 +16,7 @@ on: jobs: conda-cpp-checks: secrets: inherit - uses: rapidsai/shared-workflows/.github/workflows/conda-cpp-post-build-checks.yaml@python-3.12 + uses: rapidsai/shared-workflows/.github/workflows/conda-cpp-post-build-checks.yaml@branch-24.12 with: build_type: nightly branch: ${{ inputs.branch }} @@ -26,7 +26,7 @@ jobs: symbol_exclusions: (cugraph::ops|hornet|void writeEdgeCountsKernel|void markUniqueOffsetsKernel) conda-cpp-tests: secrets: inherit - uses: rapidsai/shared-workflows/.github/workflows/conda-cpp-tests.yaml@python-3.12 + uses: rapidsai/shared-workflows/.github/workflows/conda-cpp-tests.yaml@branch-24.12 with: build_type: nightly branch: ${{ inputs.branch }} @@ -34,7 +34,7 @@ jobs: sha: ${{ inputs.sha }} conda-python-tests: secrets: inherit - uses: rapidsai/shared-workflows/.github/workflows/conda-python-tests.yaml@python-3.12 + uses: rapidsai/shared-workflows/.github/workflows/conda-python-tests.yaml@branch-24.12 with: build_type: nightly branch: ${{ inputs.branch }} @@ -42,7 +42,7 @@ jobs: sha: ${{ inputs.sha }} wheel-tests-pylibcugraph: secrets: inherit - uses: rapidsai/shared-workflows/.github/workflows/wheels-test.yaml@python-3.12 + uses: rapidsai/shared-workflows/.github/workflows/wheels-test.yaml@branch-24.12 with: build_type: nightly branch: ${{ inputs.branch }} @@ -51,7 +51,7 @@ jobs: script: ci/test_wheel_pylibcugraph.sh wheel-tests-cugraph: secrets: inherit - uses: rapidsai/shared-workflows/.github/workflows/wheels-test.yaml@python-3.12 + uses: rapidsai/shared-workflows/.github/workflows/wheels-test.yaml@branch-24.12 with: build_type: nightly branch: ${{ inputs.branch }} @@ -60,7 +60,7 @@ jobs: script: ci/test_wheel_cugraph.sh wheel-tests-nx-cugraph: secrets: inherit - uses: rapidsai/shared-workflows/.github/workflows/wheels-test.yaml@python-3.12 + uses: rapidsai/shared-workflows/.github/workflows/wheels-test.yaml@branch-24.12 with: build_type: nightly branch: ${{ inputs.branch }} @@ -69,7 +69,7 @@ jobs: script: ci/test_wheel_nx-cugraph.sh wheel-tests-cugraph-dgl: secrets: inherit - uses: rapidsai/shared-workflows/.github/workflows/wheels-test.yaml@python-3.12 + uses: rapidsai/shared-workflows/.github/workflows/wheels-test.yaml@branch-24.12 with: build_type: nightly branch: ${{ inputs.branch }} @@ -79,7 +79,7 @@ jobs: matrix_filter: map(select(.ARCH == "amd64")) wheel-tests-cugraph-pyg: secrets: inherit - uses: rapidsai/shared-workflows/.github/workflows/wheels-test.yaml@python-3.12 + uses: rapidsai/shared-workflows/.github/workflows/wheels-test.yaml@branch-24.12 with: build_type: nightly branch: ${{ inputs.branch }} @@ -89,7 +89,7 @@ jobs: matrix_filter: map(select(.ARCH == "amd64")) wheel-tests-cugraph-equivariant: secrets: inherit - uses: rapidsai/shared-workflows/.github/workflows/wheels-test.yaml@python-3.12 + uses: rapidsai/shared-workflows/.github/workflows/wheels-test.yaml@branch-24.12 with: build_type: nightly branch: ${{ inputs.branch }} diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 5b351478fa9..3687562b48e 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -21,7 +21,7 @@ repos: files: ^(python/.*|benchmarks/.*)$ exclude: ^python/nx-cugraph/ - repo: https://github.com/PyCQA/flake8 - rev: 6.0.0 + rev: 7.1.1 hooks: - id: flake8 args: ["--config=.flake8"] @@ -34,7 +34,7 @@ repos: hooks: - id: yesqa additional_dependencies: - - flake8==6.0.0 + - flake8==7.1.1 - repo: https://github.com/pre-commit/mirrors-clang-format rev: v16.0.6 hooks: @@ -68,7 +68,7 @@ repos: types: [python] language: python pass_filenames: false - additional_dependencies: ["networkx>=3.3"] + additional_dependencies: ["networkx>=3.4"] - repo: local hooks: - id: nx-cugraph-readme-update @@ -78,4 +78,4 @@ repos: types_or: [python, markdown] language: python pass_filenames: false - additional_dependencies: ["networkx>=3.3"] + additional_dependencies: ["networkx>=3.4"] diff --git a/CHANGELOG.md b/CHANGELOG.md index 689a214751f..d934273d0a7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,80 @@ +# cugraph 24.10.00 (9 Oct 2024) + +## 🚨 Breaking Changes + +- Add Additional Check for `NetworkX` Release Candidate Versions ([#4613](https://github.com/rapidsai/cugraph/pull/4613)) [@nv-rliu](https://github.com/nv-rliu) +- Updates to `cugraph.hypergraph` (Duplicate Col Labels Bug) ([#4610](https://github.com/rapidsai/cugraph/pull/4610)) [@nv-rliu](https://github.com/nv-rliu) +- Heterogeneous renumbering implementation ([#4602](https://github.com/rapidsai/cugraph/pull/4602)) [@seunghwak](https://github.com/seunghwak) +- [FEA] DGL Examples ([#4583](https://github.com/rapidsai/cugraph/pull/4583)) [@alexbarghi-nv](https://github.com/alexbarghi-nv) + +## 🐛 Bug Fixes + +- Updates docs to describe nx-cugraph based on latest updates for 24.10 ([#4694](https://github.com/rapidsai/cugraph/pull/4694)) [@nv-rliu](https://github.com/nv-rliu) +- Constrain versions of PyTorch and CI artifacts in CI Runs, upgrade to dgl 2.4 ([#4690](https://github.com/rapidsai/cugraph/pull/4690)) [@alexbarghi-nv](https://github.com/alexbarghi-nv) +- Drops duplicate edges in non-MultiGraph PLC `SGGraph` instances ([#4658](https://github.com/rapidsai/cugraph/pull/4658)) [@rlratzel](https://github.com/rlratzel) +- Install mg test executables ([#4656](https://github.com/rapidsai/cugraph/pull/4656)) [@KyleFromNVIDIA](https://github.com/KyleFromNVIDIA) +- Fix build strings in nx-cugraph ([#4639](https://github.com/rapidsai/cugraph/pull/4639)) [@bdice](https://github.com/bdice) +- Set CUDA_STATIC_MATH_LIBRARIES in Python builds ([#4612](https://github.com/rapidsai/cugraph/pull/4612)) [@KyleFromNVIDIA](https://github.com/KyleFromNVIDIA) +- Updates to `cugraph.hypergraph` (Duplicate Col Labels Bug) ([#4610](https://github.com/rapidsai/cugraph/pull/4610)) [@nv-rliu](https://github.com/nv-rliu) +- Biased sampling primitive bug fix ([#4607](https://github.com/rapidsai/cugraph/pull/4607)) [@seunghwak](https://github.com/seunghwak) +- Fix `test_property_graph_mg` Usage of Util Function ([#4600](https://github.com/rapidsai/cugraph/pull/4600)) [@nv-rliu](https://github.com/nv-rliu) +- Re-configure benchmarking devices & add markers to `bench_cugraph_uniform_neighbor_sample` ([#4561](https://github.com/rapidsai/cugraph/pull/4561)) [@nv-rliu](https://github.com/nv-rliu) + +## 📖 Documentation + +- Implementing some of the VDR feedback ([#4674](https://github.com/rapidsai/cugraph/pull/4674)) [@acostadon](https://github.com/acostadon) +- Add `nx-cugraph` Docs Pages ([#4669](https://github.com/rapidsai/cugraph/pull/4669)) [@nv-rliu](https://github.com/nv-rliu) +- Recommending `miniforge` for conda install ([#4650](https://github.com/rapidsai/cugraph/pull/4650)) [@mmccarty](https://github.com/mmccarty) + +## 🚀 New Features + +- Add `nx-cugraph` introduction notebook to repo ([#4677](https://github.com/rapidsai/cugraph/pull/4677)) [@nv-rliu](https://github.com/nv-rliu) +- Support Negative Sampling in pylibcugraph and cuGraph-PyG ([#4660](https://github.com/rapidsai/cugraph/pull/4660)) [@alexbarghi-nv](https://github.com/alexbarghi-nv) +- Heterogeneous renumbering implementation ([#4602](https://github.com/rapidsai/cugraph/pull/4602)) [@seunghwak](https://github.com/seunghwak) +- [FEA] Biased Sampling in cuGraph-DGL ([#4595](https://github.com/rapidsai/cugraph/pull/4595)) [@alexbarghi-nv](https://github.com/alexbarghi-nv) +- [FEA] Biased Sampling in cuGraph-PyG ([#4586](https://github.com/rapidsai/cugraph/pull/4586)) [@alexbarghi-nv](https://github.com/alexbarghi-nv) +- [FEA] DGL Examples ([#4583](https://github.com/rapidsai/cugraph/pull/4583)) [@alexbarghi-nv](https://github.com/alexbarghi-nv) + +## 🛠️ Improvements + +- `nx-cugraph`: add `NX_CUGRAPH_AUTOCONFIG=True` env var to enable full zero-code change ([#4685](https://github.com/rapidsai/cugraph/pull/4685)) [@eriknw](https://github.com/eriknw) +- Fix `cit-patents` Dataset for `nx-cugraph` Benchmark ([#4666](https://github.com/rapidsai/cugraph/pull/4666)) [@nv-rliu](https://github.com/nv-rliu) +- Update update-version.sh to use packaging lib ([#4664](https://github.com/rapidsai/cugraph/pull/4664)) [@AyodeAwe](https://github.com/AyodeAwe) +- Swtch traceback to `--native` in `cugraph` ([#4663](https://github.com/rapidsai/cugraph/pull/4663)) [@galipremsagar](https://github.com/galipremsagar) +- bump NCCL floor to 2.18.1.1, include nccl.h where it's needed ([#4661](https://github.com/rapidsai/cugraph/pull/4661)) [@jameslamb](https://github.com/jameslamb) +- Use CI workflow branch 'branch-24.10' again ([#4654](https://github.com/rapidsai/cugraph/pull/4654)) [@jameslamb](https://github.com/jameslamb) +- Update flake8 to 7.1.1. ([#4652](https://github.com/rapidsai/cugraph/pull/4652)) [@bdice](https://github.com/bdice) +- reduce pip verbosity in wheel builds ([#4651](https://github.com/rapidsai/cugraph/pull/4651)) [@jameslamb](https://github.com/jameslamb) +- Refactor the python function symmetrizing the edgelist ([#4649](https://github.com/rapidsai/cugraph/pull/4649)) [@jnke2016](https://github.com/jnke2016) +- Add `--cpu-only` or `--gpu-only` Arguments to `nx-cugraph` Benchmark ([#4648](https://github.com/rapidsai/cugraph/pull/4648)) [@nv-rliu](https://github.com/nv-rliu) +- Add support for Python 3.12 ([#4647](https://github.com/rapidsai/cugraph/pull/4647)) [@jameslamb](https://github.com/jameslamb) +- Biased Random Walks and Node2Vec implementation ([#4645](https://github.com/rapidsai/cugraph/pull/4645)) [@ChuckHastings](https://github.com/ChuckHastings) +- update a few more Python references to Python 3.10 ([#4637](https://github.com/rapidsai/cugraph/pull/4637)) [@jameslamb](https://github.com/jameslamb) +- Negative Sampling test needs whole GPU ([#4636](https://github.com/rapidsai/cugraph/pull/4636)) [@ChuckHastings](https://github.com/ChuckHastings) +- Update rapidsai/pre-commit-hooks ([#4633](https://github.com/rapidsai/cugraph/pull/4633)) [@KyleFromNVIDIA](https://github.com/KyleFromNVIDIA) +- Update examples to build with latest changes to cugraph ([#4632](https://github.com/rapidsai/cugraph/pull/4632)) [@ChuckHastings](https://github.com/ChuckHastings) +- Remove Warnings and Timeout from `bench_cugraph_uniform_neighbor_sample.py` ([#4631](https://github.com/rapidsai/cugraph/pull/4631)) [@nv-rliu](https://github.com/nv-rliu) +- Update edge triangle count to call a non detail primitive ([#4630](https://github.com/rapidsai/cugraph/pull/4630)) [@jnke2016](https://github.com/jnke2016) +- nx-cugraph: Updates nxcg.Graph classes for API-compatibility with NetworkX Graph classes, needed for zero code change graph generators ([#4629](https://github.com/rapidsai/cugraph/pull/4629)) [@eriknw](https://github.com/eriknw) +- Drop Python 3.9 support ([#4625](https://github.com/rapidsai/cugraph/pull/4625)) [@jameslamb](https://github.com/jameslamb) +- Download fewer datasets for C/C++ unit tests ([#4624](https://github.com/rapidsai/cugraph/pull/4624)) [@ChuckHastings](https://github.com/ChuckHastings) +- Use CUDA math wheels ([#4621](https://github.com/rapidsai/cugraph/pull/4621)) [@KyleFromNVIDIA](https://github.com/KyleFromNVIDIA) +- Fix ListColumn constructor argument ([#4620](https://github.com/rapidsai/cugraph/pull/4620)) [@mroeschke](https://github.com/mroeschke) +- Use CategoricalColumn instead of build_categorical_column ([#4618](https://github.com/rapidsai/cugraph/pull/4618)) [@mroeschke](https://github.com/mroeschke) +- Add `nx-cugraph` Benchmarking Scripts ([#4616](https://github.com/rapidsai/cugraph/pull/4616)) [@nv-rliu](https://github.com/nv-rliu) +- Remove NumPy <2 pin ([#4615](https://github.com/rapidsai/cugraph/pull/4615)) [@seberg](https://github.com/seberg) +- Add Additional Check for `NetworkX` Release Candidate Versions ([#4613](https://github.com/rapidsai/cugraph/pull/4613)) [@nv-rliu](https://github.com/nv-rliu) +- Remove a bunch of legacy code that's no longer used ([#4609](https://github.com/rapidsai/cugraph/pull/4609)) [@ChuckHastings](https://github.com/ChuckHastings) +- Update pre-commit hooks ([#4605](https://github.com/rapidsai/cugraph/pull/4605)) [@KyleFromNVIDIA](https://github.com/KyleFromNVIDIA) +- Improve update-version.sh ([#4599](https://github.com/rapidsai/cugraph/pull/4599)) [@bdice](https://github.com/bdice) +- Use tool.scikit-build.cmake.version, set scikit-build-core minimum-version ([#4597](https://github.com/rapidsai/cugraph/pull/4597)) [@jameslamb](https://github.com/jameslamb) +- Migrate get_sampling_index function from cugraph-ops to cugraph ([#4594](https://github.com/rapidsai/cugraph/pull/4594)) [@ChuckHastings](https://github.com/ChuckHastings) +- Merge branch-24.08 into branch-24.10 ([#4565](https://github.com/rapidsai/cugraph/pull/4565)) [@jameslamb](https://github.com/jameslamb) +- Fix ucx-py version, use UCX 1.17.0 in pip devcontainers ([#4562](https://github.com/rapidsai/cugraph/pull/4562)) [@bdice](https://github.com/bdice) +- Use stream_allocator_adaptor constructor instead of factory. ([#4557](https://github.com/rapidsai/cugraph/pull/4557)) [@bdice](https://github.com/bdice) +- Add an Explanatory Error Message for uint Types ([#4556](https://github.com/rapidsai/cugraph/pull/4556)) [@alexbarghi-nv](https://github.com/alexbarghi-nv) +- Define and Implement C++ API for negative sampling ([#4523](https://github.com/rapidsai/cugraph/pull/4523)) [@ChuckHastings](https://github.com/ChuckHastings) + # cugraph 24.08.00 (7 Aug 2024) ## 🚨 Breaking Changes diff --git a/VERSION b/VERSION index 7c7ba04436f..af28c42b528 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -24.10.00 +24.12.00 diff --git a/benchmarks/cugraph-dgl/notebooks/get_node_storage.ipynb b/benchmarks/cugraph-dgl/notebooks/get_node_storage.ipynb index 95b456c7812..4681c8ec825 100644 --- a/benchmarks/cugraph-dgl/notebooks/get_node_storage.ipynb +++ b/benchmarks/cugraph-dgl/notebooks/get_node_storage.ipynb @@ -18,7 +18,7 @@ "name": "stderr", "output_type": "stream", "text": [ - "/datasets/vjawa/miniconda3/envs/all_cuda-115_arch-x86_64/lib/python3.9/site-packages/tqdm/auto.py:22: TqdmWarning: IProgress not found. Please update jupyter and ipywidgets. See https://ipywidgets.readthedocs.io/en/stable/user_install.html\n", + "/datasets/vjawa/miniforge/envs/all_cuda-115_arch-x86_64/lib/python3.9/site-packages/tqdm/auto.py:22: TqdmWarning: IProgress not found. Please update jupyter and ipywidgets. See https://ipywidgets.readthedocs.io/en/stable/user_install.html\n", " from .autonotebook import tqdm as notebook_tqdm\n" ] } diff --git a/benchmarks/cugraph-dgl/notebooks/heterogeneous_dataloader_benchmark.ipynb b/benchmarks/cugraph-dgl/notebooks/heterogeneous_dataloader_benchmark.ipynb index d3b054bb0ee..2c4a934827a 100644 --- a/benchmarks/cugraph-dgl/notebooks/heterogeneous_dataloader_benchmark.ipynb +++ b/benchmarks/cugraph-dgl/notebooks/heterogeneous_dataloader_benchmark.ipynb @@ -176,7 +176,7 @@ "name": "stderr", "output_type": "stream", "text": [ - "/datasets/vjawa/miniconda3/envs/all_cuda-115_arch-x86_64/lib/python3.9/site-packages/dgl/dataloading/dataloader.py:859: DGLWarning: Dataloader CPU affinity opt is not enabled, consider switching it on (see enable_cpu_affinity() or CPU best practices for DGL [https://docs.dgl.ai/tutorials/cpu/cpu_best_practises.html])\n", + "/datasets/vjawa/miniforge/envs/all_cuda-115_arch-x86_64/lib/python3.9/site-packages/dgl/dataloading/dataloader.py:859: DGLWarning: Dataloader CPU affinity opt is not enabled, consider switching it on (see enable_cpu_affinity() or CPU best practices for DGL [https://docs.dgl.ai/tutorials/cpu/cpu_best_practises.html])\n", " dgl_warning(f'Dataloader CPU affinity opt is not enabled, consider switching it on '\n" ] }, diff --git a/benchmarks/cugraph-dgl/notebooks/homogenous_dataloader_benchmark.ipynb b/benchmarks/cugraph-dgl/notebooks/homogenous_dataloader_benchmark.ipynb index ea1e9b34965..ecd111dabdf 100644 --- a/benchmarks/cugraph-dgl/notebooks/homogenous_dataloader_benchmark.ipynb +++ b/benchmarks/cugraph-dgl/notebooks/homogenous_dataloader_benchmark.ipynb @@ -26,7 +26,7 @@ "name": "stderr", "output_type": "stream", "text": [ - "/datasets/vjawa/miniconda3/envs/all_cuda-115_arch-x86_64/lib/python3.9/site-packages/tqdm/auto.py:22: TqdmWarning: IProgress not found. Please update jupyter and ipywidgets. See https://ipywidgets.readthedocs.io/en/stable/user_install.html\n", + "/datasets/vjawa/miniforge/envs/all_cuda-115_arch-x86_64/lib/python3.9/site-packages/tqdm/auto.py:22: TqdmWarning: IProgress not found. Please update jupyter and ipywidgets. See https://ipywidgets.readthedocs.io/en/stable/user_install.html\n", " from .autonotebook import tqdm as notebook_tqdm\n" ] } @@ -190,7 +190,7 @@ "name": "stderr", "output_type": "stream", "text": [ - "/datasets/vjawa/miniconda3/envs/all_cuda-115_arch-x86_64/lib/python3.9/site-packages/dgl/dataloading/dataloader.py:859: DGLWarning: Dataloader CPU affinity opt is not enabled, consider switching it on (see enable_cpu_affinity() or CPU best practices for DGL [https://docs.dgl.ai/tutorials/cpu/cpu_best_practises.html])\n", + "/datasets/vjawa/miniforge/envs/all_cuda-115_arch-x86_64/lib/python3.9/site-packages/dgl/dataloading/dataloader.py:859: DGLWarning: Dataloader CPU affinity opt is not enabled, consider switching it on (see enable_cpu_affinity() or CPU best practices for DGL [https://docs.dgl.ai/tutorials/cpu/cpu_best_practises.html])\n", " dgl_warning(f'Dataloader CPU affinity opt is not enabled, consider switching it on '\n" ] }, @@ -278,7 +278,7 @@ "name": "stderr", "output_type": "stream", "text": [ - "/datasets/vjawa/miniconda3/envs/all_cuda-115_arch-x86_64/lib/python3.9/site-packages/distributed/worker.py:2988: UserWarning: Large object of size 1.42 MiB detected in task graph: \n", + "/datasets/vjawa/miniforge/envs/all_cuda-115_arch-x86_64/lib/python3.9/site-packages/distributed/worker.py:2988: UserWarning: Large object of size 1.42 MiB detected in task graph: \n", " [b'\\xad\\xd1\\xe3\\x9c\\x96\\x83O\\xb3\\xba1\\x86\\x94\\xb6\\ ... =int32), False]\n", "Consider scattering large objects ahead of time\n", "with client.scatter to reduce scheduler burden and \n", diff --git a/benchmarks/cugraph-dgl/python-script/ogbn_mag_benchmark.py b/benchmarks/cugraph-dgl/python-script/ogbn_mag_benchmark.py index 539fe333b1e..55ff0043e30 100644 --- a/benchmarks/cugraph-dgl/python-script/ogbn_mag_benchmark.py +++ b/benchmarks/cugraph-dgl/python-script/ogbn_mag_benchmark.py @@ -1,4 +1,4 @@ -# 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. # You may obtain a copy of the License at @@ -126,4 +126,4 @@ def sampling_func(g, seed_nodes, labels, train_loader): st = time.time() sampling_func(g, subset_split_idx["train"], labels, train_loader) et = time.time() - print(f"Sampling time taken = {et-st} s") + print(f"Sampling time taken = {et - st} s") diff --git a/benchmarks/cugraph/notebooks/feature_storage.ipynb b/benchmarks/cugraph/notebooks/feature_storage.ipynb index 7413ac00cde..440d76fbdb4 100644 --- a/benchmarks/cugraph/notebooks/feature_storage.ipynb +++ b/benchmarks/cugraph/notebooks/feature_storage.ipynb @@ -18,7 +18,7 @@ "name": "stderr", "output_type": "stream", "text": [ - "/datasets/vjawa/miniconda3/envs/all_cuda-115_arch-x86_64/lib/python3.9/site-packages/tqdm/auto.py:22: TqdmWarning: IProgress not found. Please update jupyter and ipywidgets. See https://ipywidgets.readthedocs.io/en/stable/user_install.html\n", + "/datasets/vjawa/miniforge/envs/all_cuda-115_arch-x86_64/lib/python3.9/site-packages/tqdm/auto.py:22: TqdmWarning: IProgress not found. Please update jupyter and ipywidgets. See https://ipywidgets.readthedocs.io/en/stable/user_install.html\n", " from .autonotebook import tqdm as notebook_tqdm\n" ] } diff --git a/benchmarks/nx-cugraph/pytest-based/README.md b/benchmarks/nx-cugraph/pytest-based/README.md index 781550fa560..5d2406bfcd5 100644 --- a/benchmarks/nx-cugraph/pytest-based/README.md +++ b/benchmarks/nx-cugraph/pytest-based/README.md @@ -21,7 +21,9 @@ Our current benchmarks provide the following datasets: #### 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. +NOTE: + - If running with all algorithms and datasets using NetworkX without an accelerated backend, this script may take a few hours to finish running. + - The `betweenness_centrality` benchmark will run with values `[10, 20, 50, 100, 500, 1000]` by default. You can specify only specific k-values to be run by editing `bc_k_values` (line 46) to be passed as a [pytest keyword object](https://docs.pytest.org/en/6.2.x/usage.html#specifying-tests-selecting-tests). **Usage:** - Run with `--cpu-only`: diff --git a/benchmarks/nx-cugraph/pytest-based/bench_algos.py b/benchmarks/nx-cugraph/pytest-based/bench_algos.py index f88d93c3f17..8852ed2a875 100644 --- a/benchmarks/nx-cugraph/pytest-based/bench_algos.py +++ b/benchmarks/nx-cugraph/pytest-based/bench_algos.py @@ -37,6 +37,40 @@ iterations = 1 warmup_rounds = 1 +# FIXME: Add this to cugraph.datasets. This is done here so these benchmarks +# can be run without requiring an updated cugraph install. This temporarily +# adds a dataset based on an Amazon product co-purchasing network. +amazon0302_metadata = """ +name: amazon0302 +description: + Network was collected by crawling Amazon website. It is based on Customers Who Bought This Item Also Bought feature of the Amazon website. If a product i is frequently co-purchased with product j, the graph contains a directed edge from i to j. The data was collected in March 02 2003. +author: J. Leskovec, L. Adamic and B. Adamic +refs: J. Leskovec, L. Adamic and B. Adamic. The Dynamics of Viral Marketing. ACM Transactions on the Web (ACM TWEB), 1(1), 2007. +delim: "\t" +header: 3 +col_names: + - FromNodeId + - ToNodeId +col_types: + - int32 + - int32 +has_loop: false +is_directed: true +is_multigraph: false +is_symmetric: false +number_of_edges: 1234877 +number_of_nodes: 262111 +url: https://snap.stanford.edu/data/amazon0302.txt.gz +""" +amazon0302_metadata_file_name = datasets.default_download_dir.path / "amazon0302.yaml" +if not amazon0302_metadata_file_name.exists(): + amazon0302_metadata_file_name.parent.mkdir(parents=True, exist_ok=True) + with open(amazon0302_metadata_file_name, "w") as f: + f.write(amazon0302_metadata) + +amazon0302_dataset = datasets.Dataset(amazon0302_metadata_file_name) +amazon0302_dataset.metadata["file_type"] = ".gz" + dataset_param_values = [ # name: karate, nodes: 34, edges: 156 pytest.param(datasets.karate, marks=[pytest.mark.small, pytest.mark.undirected]), @@ -46,6 +80,8 @@ pytest.param( datasets.email_Eu_core, marks=[pytest.mark.small, pytest.mark.directed] ), + # name: amazon0302, nodes: 262111, edges: 1234877 + pytest.param(amazon0302_dataset, marks=[pytest.mark.medium, pytest.mark.directed]), # name: cit-Patents, nodes: 3774768, edges: 16518948 pytest.param( datasets.cit_patents, marks=[pytest.mark.medium, pytest.mark.directed] @@ -113,19 +149,7 @@ def nx_graph_from_dataset(dataset_obj): """ 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, - ) + pandas_edgelist = dataset_obj.get_edgelist(download=True, reader="pandas") G = nx.from_pandas_edgelist( pandas_edgelist, source=names[0], target=names[1], create_using=create_using ) @@ -272,7 +296,7 @@ def bench_from_networkx(benchmark, graph_obj): # normalized_param_values = [True, False] normalized_param_values = [True] -k_param_values = [10, 100, 1000] +k_param_values = [10, 20, 50, 100, 500, 1000] @pytest.mark.parametrize( @@ -281,7 +305,6 @@ def bench_from_networkx(benchmark, graph_obj): @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()=}") diff --git a/benchmarks/nx-cugraph/pytest-based/create_results_summary_page.py b/benchmarks/nx-cugraph/pytest-based/create_results_summary_page.py index f1cc4b06ccc..e4aff10f0a5 100644 --- a/benchmarks/nx-cugraph/pytest-based/create_results_summary_page.py +++ b/benchmarks/nx-cugraph/pytest-based/create_results_summary_page.py @@ -157,7 +157,7 @@ def get_system_info(): dataset_patt = re.compile(".*ds=([\w-]+).*") backend_patt = re.compile(".*backend=(\w+).*") - k_patt = re.compile(".*k=(10*).*") + k_patt = re.compile(".*k=(\d+).*") # Organize all benchmark runs by the following hierarchy: algo -> backend -> dataset benchmarks = get_all_benchmark_info() @@ -166,6 +166,7 @@ def get_system_info(): ordered_datasets = [ "netscience", "email_Eu_core", + "amazon0302", "cit-patents", "hollywood", "soc-livejournal1", @@ -174,6 +175,7 @@ def get_system_info(): dataset_meta = { "netscience": ["1,461", "5,484", "Yes"], "email_Eu_core": ["1,005", "25,571", "Yes"], + "amazon0302": ["262,111", "1,234,877", "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"], 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-main-benchmarks.sh b/benchmarks/nx-cugraph/pytest-based/run-main-benchmarks.sh index a1d32474e5f..73c85000b0f 100755 --- a/benchmarks/nx-cugraph/pytest-based/run-main-benchmarks.sh +++ b/benchmarks/nx-cugraph/pytest-based/run-main-benchmarks.sh @@ -14,7 +14,7 @@ # location to store datasets used for benchmarking -export RAPIDS_DATASET_ROOT_DIR=/datasets/cugraph +export RAPIDS_DATASET_ROOT_DIR=${RAPIDS_DATASET_ROOT_DIR:-/datasets/cugraph} mkdir -p logs # list of algos, datasets, and back-ends to use in combinations @@ -30,7 +30,8 @@ algos=" datasets=" netscience email_Eu_core - cit_patents + amazon0302 + cit-patents hollywood soc-livejournal " @@ -40,6 +41,11 @@ backends=" None cugraph-preconverted " + +# edit this directly to for pytest +# e.g. -k "and not 100 and not 1000" +bc_k_values="" + # check for --cpu-only or --gpu-only args if [[ "$#" -eq 1 ]]; then case $1 in @@ -58,15 +64,15 @@ 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" + + # uncomment to get command for reproducing test + # echo "RUNNING: \"pytest -sv -k \"$backend and $dataset and bench_$algo $bc_k_values\" --benchmark-json=\"logs/${name}.json\" bench_algos.py" + pytest -sv \ - -k "$backend and $dataset and bench_$algo and not 1000" \ + -k "$backend and $dataset and bench_$algo $bc_k_values" \ --benchmark-json="logs/${name}.json" \ bench_algos.py 2>&1 | tee "logs/${name}.out" done diff --git a/benchmarks/pytest.ini b/benchmarks/pytest.ini index fe7fc31b6d6..d692b78de37 100644 --- a/benchmarks/pytest.ini +++ b/benchmarks/pytest.ini @@ -8,6 +8,7 @@ testpaths = addopts = --benchmark-columns="min, max, mean, stddev, outliers" + --tb=native markers = managedmem_on: RMM managed memory enabled diff --git a/ci/build_docs.sh b/ci/build_docs.sh index 55235c6ebb9..01c573c96ca 100755 --- a/ci/build_docs.sh +++ b/ci/build_docs.sh @@ -6,6 +6,10 @@ set -euo pipefail rapids-logger "Create test conda environment" . /opt/conda/etc/profile.d/conda.sh +export RAPIDS_VERSION="$(rapids-version)" +export RAPIDS_VERSION_MAJOR_MINOR="$(rapids-version-major-minor)" +export RAPIDS_VERSION_NUMBER="$RAPIDS_VERSION_MAJOR_MINOR" + rapids-dependency-file-generator \ --output conda \ --file-key docs \ @@ -22,35 +26,31 @@ PYTHON_CHANNEL=$(rapids-download-conda-from-s3 python) if [[ "${RAPIDS_CUDA_VERSION}" == "11.8.0" ]]; then CONDA_CUDA_VERSION="11.8" - DGL_CHANNEL="dglteam/label/cu118" + DGL_CHANNEL="dglteam/label/th23_cu118" else CONDA_CUDA_VERSION="12.1" - DGL_CHANNEL="dglteam/label/cu121" + DGL_CHANNEL="dglteam/label/th23_cu121" fi rapids-mamba-retry install \ --channel "${CPP_CHANNEL}" \ --channel "${PYTHON_CHANNEL}" \ --channel conda-forge \ - --channel pyg \ --channel nvidia \ --channel "${DGL_CHANNEL}" \ - libcugraph \ - pylibcugraph \ - cugraph \ - cugraph-pyg \ - cugraph-dgl \ - cugraph-service-server \ - cugraph-service-client \ - libcugraph_etl \ - pylibcugraphops \ - pylibwholegraph \ - pytorch \ + "libcugraph=${RAPIDS_VERSION_MAJOR_MINOR}.*" \ + "pylibcugraph=${RAPIDS_VERSION_MAJOR_MINOR}.*" \ + "cugraph=${RAPIDS_VERSION_MAJOR_MINOR}.*" \ + "cugraph-pyg=${RAPIDS_VERSION_MAJOR_MINOR}.*" \ + "cugraph-dgl=${RAPIDS_VERSION_MAJOR_MINOR}.*" \ + "cugraph-service-server=${RAPIDS_VERSION_MAJOR_MINOR}.*" \ + "cugraph-service-client=${RAPIDS_VERSION_MAJOR_MINOR}.*" \ + "libcugraph_etl=${RAPIDS_VERSION_MAJOR_MINOR}.*" \ + "pylibcugraphops=${RAPIDS_VERSION_MAJOR_MINOR}.*" \ + "pylibwholegraph=${RAPIDS_VERSION_MAJOR_MINOR}.*" \ + "pytorch>=2.3,<2.4" \ "cuda-version=${CONDA_CUDA_VERSION}" -export RAPIDS_VERSION="$(rapids-version)" -export RAPIDS_VERSION_MAJOR_MINOR="$(rapids-version-major-minor)" -export RAPIDS_VERSION_NUMBER="$RAPIDS_VERSION_MAJOR_MINOR" export RAPIDS_DOCS_DIR="$(mktemp -d)" for PROJECT in libcugraphops libwholegraph; do diff --git a/ci/build_python.sh b/ci/build_python.sh index 1ebc38b058b..c94cc2a0fce 100755 --- a/ci/build_python.sh +++ b/ci/build_python.sh @@ -61,7 +61,6 @@ if [[ ${RAPIDS_CUDA_MAJOR} == "11" ]]; then --no-test \ --channel "${CPP_CHANNEL}" \ --channel "${RAPIDS_CONDA_BLD_OUTPUT_DIR}" \ - --channel pyg \ --channel pytorch \ --channel pytorch-nightly \ conda/recipes/cugraph-pyg @@ -71,7 +70,7 @@ if [[ ${RAPIDS_CUDA_MAJOR} == "11" ]]; then --no-test \ --channel "${CPP_CHANNEL}" \ --channel "${RAPIDS_CONDA_BLD_OUTPUT_DIR}" \ - --channel dglteam \ + --channel dglteam/label/th23_cu118 \ --channel pytorch \ --channel pytorch-nightly \ conda/recipes/cugraph-dgl diff --git a/ci/build_wheel.sh b/ci/build_wheel.sh index 1976d8ff46f..f3979ab3049 100755 --- a/ci/build_wheel.sh +++ b/ci/build_wheel.sh @@ -17,7 +17,7 @@ cd "${package_dir}" python -m pip wheel \ -w dist \ - -vvv \ + -v \ --no-deps \ --disable-pip-version-check \ --extra-index-url https://pypi.nvidia.com \ diff --git a/ci/release/update-version.sh b/ci/release/update-version.sh index 36ab7252117..5859ebde953 100755 --- a/ci/release/update-version.sh +++ b/ci/release/update-version.sh @@ -45,8 +45,8 @@ function sed_runner() { echo "${NEXT_FULL_TAG}" > VERSION # Need to distutils-normalize the original version -NEXT_SHORT_TAG_PEP440=$(python -c "from setuptools.extern import packaging; print(packaging.version.Version('${NEXT_SHORT_TAG}'))") -NEXT_UCXX_SHORT_TAG_PEP440=$(python -c "from setuptools.extern import packaging; print(packaging.version.Version('${NEXT_UCXX_SHORT_TAG}'))") +NEXT_SHORT_TAG_PEP440=$(python -c "from packaging.version import Version; print(Version('${NEXT_SHORT_TAG}'))") +NEXT_UCXX_SHORT_TAG_PEP440=$(python -c "from packaging.version import Version; print(Version('${NEXT_UCXX_SHORT_TAG}'))") DEPENDENCIES=( cudf diff --git a/ci/run_nx_cugraph_pytests.sh b/ci/run_nx_cugraph_pytests.sh index b0caffd0a0f..0e309d1e2d4 100755 --- a/ci/run_nx_cugraph_pytests.sh +++ b/ci/run_nx_cugraph_pytests.sh @@ -6,4 +6,5 @@ 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 -pytest --capture=no --cache-clear --benchmark-disable "$@" tests +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_cpp.sh b/ci/test_cpp.sh index 6c14870164e..fb9ab1f5e4e 100755 --- a/ci/test_cpp.sh +++ b/ci/test_cpp.sh @@ -8,6 +8,8 @@ cd "$(dirname "$(realpath "${BASH_SOURCE[0]}")")"/../ . /opt/conda/etc/profile.d/conda.sh +RAPIDS_VERSION_MAJOR_MINOR="$(rapids-version-major-minor)" + rapids-logger "Generate C++ testing dependencies" rapids-dependency-file-generator \ --output conda \ @@ -30,7 +32,9 @@ rapids-print-env rapids-mamba-retry install \ --channel "${CPP_CHANNEL}" \ - libcugraph libcugraph_etl libcugraph-tests + "libcugraph=${RAPIDS_VERSION_MAJOR_MINOR}.*" \ + "libcugraph_etl=${RAPIDS_VERSION_MAJOR_MINOR}.*" \ + "libcugraph-tests=${RAPIDS_VERSION_MAJOR_MINOR}.*" rapids-logger "Check GPU usage" nvidia-smi diff --git a/ci/test_notebooks.sh b/ci/test_notebooks.sh index 31ec56074f0..b22671b48dc 100755 --- a/ci/test_notebooks.sh +++ b/ci/test_notebooks.sh @@ -5,6 +5,8 @@ set -Eeuo pipefail . /opt/conda/etc/profile.d/conda.sh +RAPIDS_VERSION_MAJOR_MINOR="$(rapids-version-major-minor)" + rapids-logger "Generate notebook testing dependencies" rapids-dependency-file-generator \ --output conda \ @@ -27,7 +29,9 @@ PYTHON_CHANNEL=$(rapids-download-conda-from-s3 python) rapids-mamba-retry install \ --channel "${CPP_CHANNEL}" \ --channel "${PYTHON_CHANNEL}" \ - libcugraph pylibcugraph cugraph + "libcugraph=${RAPIDS_VERSION_MAJOR_MINOR}.*" \ + "pylibcugraph=${RAPIDS_VERSION_MAJOR_MINOR}.*" \ + "cugraph=${RAPIDS_VERSION_MAJOR_MINOR}.*" NBTEST="$(realpath "$(dirname "$0")/utils/nbtest.sh")" NOTEBOOK_LIST="$(realpath "$(dirname "$0")/notebook_list.py")" diff --git a/ci/test_python.sh b/ci/test_python.sh index e8c8272e8d6..29b4c7be190 100755 --- a/ci/test_python.sh +++ b/ci/test_python.sh @@ -8,6 +8,8 @@ cd "$(dirname "$(realpath "${BASH_SOURCE[0]}")")"/../ . /opt/conda/etc/profile.d/conda.sh +RAPIDS_VERSION_MAJOR_MINOR="$(rapids-version-major-minor)" + rapids-logger "Generate Python testing dependencies" rapids-dependency-file-generator \ --output conda \ @@ -34,12 +36,12 @@ rapids-print-env rapids-mamba-retry install \ --channel "${CPP_CHANNEL}" \ --channel "${PYTHON_CHANNEL}" \ - libcugraph \ - pylibcugraph \ - cugraph \ - nx-cugraph \ - cugraph-service-server \ - cugraph-service-client + "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}.*" rapids-logger "Check GPU usage" nvidia-smi @@ -108,7 +110,7 @@ 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 -pytest \ +NX_CUGRAPH_USE_COMPAT_GRAPHS=False pytest \ --pyargs nx_cugraph \ --config-file=../pyproject.toml \ --cov-config=../pyproject.toml \ @@ -151,15 +153,14 @@ if [[ "${RAPIDS_CUDA_VERSION}" == "11.8.0" ]]; then --channel "${CPP_CHANNEL}" \ --channel "${PYTHON_CHANNEL}" \ --channel conda-forge \ - --channel dglteam/label/cu118 \ + --channel dglteam/label/th23_cu118 \ --channel nvidia \ - libcugraph \ - pylibcugraph \ - pylibcugraphops \ - cugraph \ - cugraph-dgl \ - 'dgl>=1.1.0.cu*,<=2.0.0.cu*' \ - 'pytorch>=2.0' \ + "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 @@ -198,26 +199,20 @@ if [[ "${RAPIDS_CUDA_VERSION}" == "11.8.0" ]]; then # TODO re-enable logic once CUDA 12 is testable #if [[ "${RAPIDS_CUDA_VERSION}" == "11.8.0" ]]; then CONDA_CUDA_VERSION="11.8" - PYG_URL="https://data.pyg.org/whl/torch-2.1.0+cu118.html" + 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.1.0+cu121.html" + # 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}" \ - --channel pyg \ - "cugraph-pyg" \ + "cugraph-pyg=${RAPIDS_VERSION_MAJOR_MINOR}.*" \ + "pytorch>=2.3,<2.4" \ "ogb" - pip install \ - pyg_lib \ - torch_scatter \ - torch_sparse \ - -f ${PYG_URL} - rapids-print-env rapids-logger "pytest cugraph_pyg (single GPU)" @@ -253,7 +248,7 @@ if [[ "${RAPIDS_CUDA_VERSION}" == "11.8.0" ]]; then --channel "${PYTHON_CHANNEL}" \ --channel conda-forge \ --channel nvidia \ - cugraph-equivariant + "cugraph-equivariant=${RAPIDS_VERSION_MAJOR_MINOR}.*" pip install e3nn==0.5.1 rapids-print-env diff --git a/ci/test_wheel.sh b/ci/test_wheel.sh index 158704e08d1..dfba25bbe1a 100755 --- a/ci/test_wheel.sh +++ b/ci/test_wheel.sh @@ -4,7 +4,6 @@ set -eoxu pipefail package_name=$1 -package_dir=$2 python_package_name=$(echo ${package_name}|sed 's/-/_/g') @@ -37,6 +36,7 @@ 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 index 564b46cb07e..d7558d43b6d 100755 --- a/ci/test_wheel_cugraph-dgl.sh +++ b/ci/test_wheel_cugraph-dgl.sh @@ -4,24 +4,16 @@ set -eoxu pipefail package_name="cugraph-dgl" -package_dir="python/cugraph-dgl" - -python_package_name=$(echo ${package_name}|sed 's/-/_/g') mkdir -p ./dist RAPIDS_PY_CUDA_SUFFIX="$(rapids-wheel-ctk-name-gen ${RAPIDS_CUDA_VERSION})" -# Download wheels built during this job. +# 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 -python -m pip install ./local-deps/*.whl - -# use 'ls' to expand wildcard before adding `[extra]` requires for pip RAPIDS_PY_WHEEL_NAME="${package_name}_${RAPIDS_PY_CUDA_SUFFIX}" RAPIDS_PY_WHEEL_PURE="1" rapids-download-wheels-from-s3 ./dist -# pip creates wheels using python package names -python -m pip install $(ls ./dist/${python_package_name}*.whl)[test] - +# 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 @@ -30,20 +22,17 @@ 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/cu${PYTORCH_CUDA_VER}/repo.html" - -# Starting from 2.2, PyTorch wheels depend on nvidia-nccl-cuxx>=2.19 wheel and -# dynamically link to NCCL. RAPIDS CUDA 11 CI images have an older NCCL version that -# might shadow the newer NCCL required by PyTorch during import (when importing -# `cupy` before `torch`). -if [[ "${NCCL_VERSION}" < "2.19" ]]; then - PYTORCH_VER="2.1.0" -else - PYTORCH_VER="2.3.0" -fi - -rapids-logger "Installing PyTorch and DGL" -rapids-retry python -m pip install "torch==${PYTORCH_VER}" --index-url ${PYTORCH_URL} -rapids-retry python -m pip install dgl==2.0.0 --find-links ${DGL_URL} +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-equivariant.sh b/ci/test_wheel_cugraph-equivariant.sh index cb952055f06..3be1d578964 100755 --- a/ci/test_wheel_cugraph-equivariant.sh +++ b/ci/test_wheel_cugraph-equivariant.sh @@ -4,19 +4,14 @@ set -eoxu pipefail package_name="cugraph-equivariant" -package_dir="python/cugraph-equivariant" - -python_package_name=$(echo ${package_name}|sed 's/-/_/g') mkdir -p ./dist RAPIDS_PY_CUDA_SUFFIX="$(rapids-wheel-ctk-name-gen ${RAPIDS_CUDA_VERSION})" -# use 'ls' to expand wildcard before adding `[extra]` requires for pip +# Download the cugraph-equivariant built in the previous step RAPIDS_PY_WHEEL_NAME="${package_name}_${RAPIDS_PY_CUDA_SUFFIX}" RAPIDS_PY_WHEEL_PURE="1" rapids-download-wheels-from-s3 ./dist -# pip creates wheels using python package names -python -m pip install $(ls ./dist/${python_package_name}*.whl)[test] - +# determine pytorch source PKG_CUDA_VER="$(echo ${CUDA_VERSION} | cut -d '.' -f1,2 | tr -d '.')" PKG_CUDA_VER_MAJOR=${PKG_CUDA_VER:0:2} if [[ "${PKG_CUDA_VER_MAJOR}" == "12" ]]; then @@ -26,8 +21,12 @@ else fi PYTORCH_URL="https://download.pytorch.org/whl/cu${PYTORCH_CUDA_VER}" -rapids-logger "Installing PyTorch and e3nn" -rapids-retry python -m pip install torch --index-url ${PYTORCH_URL} -rapids-retry python -m pip install e3nn +# echo to expand wildcard before adding `[extra]` requires for pip +python -m pip install \ + -v \ + --extra-index-url "${PYTORCH_URL}" \ + "$(echo ./dist/cugraph_equivariant_${RAPIDS_PY_CUDA_SUFFIX}*.whl)[test]" \ + 'e3nn' \ + 'torch>=2.3.0,<2.4' python -m pytest python/cugraph-equivariant/cugraph_equivariant/tests diff --git a/ci/test_wheel_cugraph-pyg.sh b/ci/test_wheel_cugraph-pyg.sh index c55ae033344..2f508ee830b 100755 --- a/ci/test_wheel_cugraph-pyg.sh +++ b/ci/test_wheel_cugraph-pyg.sh @@ -4,45 +4,44 @@ set -eoxu pipefail package_name="cugraph-pyg" -package_dir="python/cugraph-pyg" - -python_package_name=$(echo ${package_name}|sed 's/-/_/g') mkdir -p ./dist RAPIDS_PY_CUDA_SUFFIX="$(rapids-wheel-ctk-name-gen ${RAPIDS_CUDA_VERSION})" -# Download wheels built during this job. +# 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 -python -m pip install ./local-deps/*.whl - -# use 'ls' to expand wildcard before adding `[extra]` requires for pip RAPIDS_PY_WHEEL_NAME="${package_name}_${RAPIDS_PY_CUDA_SUFFIX}" RAPIDS_PY_WHEEL_PURE="1" rapids-download-wheels-from-s3 ./dist -# pip creates wheels using python package names -python -m pip install $(ls ./dist/${python_package_name}*.whl)[test] - -# 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 +# 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.1.0+cu118.html" + 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.1.0+cu121.html" + PYG_URL="https://data.pyg.org/whl/torch-2.3.0+cu121.html" fi -rapids-logger "Installing PyTorch and PyG dependencies" -rapids-retry python -m pip install torch==2.1.0 --index-url ${PYTORCH_URL} -rapids-retry python -m pip install "torch-geometric>=2.5,<2.6" -rapids-retry python -m pip install \ - ogb \ - pyg_lib \ - torch_scatter \ - torch_sparse \ - -f ${PYG_URL} + +# 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 diff --git a/ci/test_wheel_cugraph.sh b/ci/test_wheel_cugraph.sh index d351ea21624..295cec7cb10 100755 --- a/ci/test_wheel_cugraph.sh +++ b/ci/test_wheel_cugraph.sh @@ -1,5 +1,5 @@ #!/bin/bash -# Copyright (c) 2023, NVIDIA CORPORATION. +# Copyright (c) 2023-2024, NVIDIA CORPORATION. set -eoxu pipefail @@ -8,4 +8,4 @@ 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-pylibcugraph-dep python -m pip install --no-deps ./local-pylibcugraph-dep/pylibcugraph*.whl -./ci/test_wheel.sh cugraph python/cugraph +./ci/test_wheel.sh cugraph diff --git a/ci/test_wheel_nx-cugraph.sh b/ci/test_wheel_nx-cugraph.sh index b5adfbcb9d3..024169ae698 100755 --- a/ci/test_wheel_nx-cugraph.sh +++ b/ci/test_wheel_nx-cugraph.sh @@ -8,4 +8,4 @@ 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 python/nx-cugraph +./ci/test_wheel.sh nx-cugraph diff --git a/ci/test_wheel_pylibcugraph.sh b/ci/test_wheel_pylibcugraph.sh index d04cb358d21..ddc9976308b 100755 --- a/ci/test_wheel_pylibcugraph.sh +++ b/ci/test_wheel_pylibcugraph.sh @@ -1,6 +1,6 @@ #!/bin/bash -# Copyright (c) 2023, NVIDIA CORPORATION. +# Copyright (c) 2023-2024, NVIDIA CORPORATION. set -eoxu pipefail -./ci/test_wheel.sh pylibcugraph python/pylibcugraph +./ci/test_wheel.sh pylibcugraph diff --git a/conda/environments/all_cuda-118_arch-x86_64.yaml b/conda/environments/all_cuda-118_arch-x86_64.yaml index 18cca40c320..ec3f61d383f 100644 --- a/conda/environments/all_cuda-118_arch-x86_64.yaml +++ b/conda/environments/all_cuda-118_arch-x86_64.yaml @@ -4,8 +4,7 @@ channels: - rapidsai - rapidsai-nightly - dask/label/dev -- pyg -- dglteam/label/cu118 +- dglteam/label/th23_cu118 - conda-forge - nvidia dependencies: @@ -16,55 +15,54 @@ dependencies: - cuda-nvtx - cuda-version=11.8 - cudatoolkit -- cudf==24.10.*,>=0.0.0a0 +- cudf==24.12.*,>=0.0.0a0 - cupy>=12.0.0 - cxx-compiler - cython>=3.0.0 -- dask-cuda==24.10.*,>=0.0.0a0 -- dask-cudf==24.10.*,>=0.0.0a0 +- dask-cuda==24.12.*,>=0.0.0a0 +- dask-cudf==24.12.*,>=0.0.0a0 - doxygen - fsspec>=0.6.0 - gcc_linux-64=11.* - graphviz - ipython -- libcudf==24.10.*,>=0.0.0a0 -- libcugraphops==24.10.*,>=0.0.0a0 -- libraft-headers==24.10.*,>=0.0.0a0 -- libraft==24.10.*,>=0.0.0a0 -- librmm==24.10.*,>=0.0.0a0 +- libcudf==24.12.*,>=0.0.0a0 +- libcugraphops==24.12.*,>=0.0.0a0 +- libraft-headers==24.12.*,>=0.0.0a0 +- libraft==24.12.*,>=0.0.0a0 +- librmm==24.12.*,>=0.0.0a0 - nbsphinx -- nccl>=2.9.9 +- nccl>=2.19 - networkx>=2.5.1 - networkx>=3.0 - ninja - notebook>=0.5.0 - numba>=0.57 -- numpy>=1.23,<2.0a0 +- numpy>=1.23,<3.0a0 - numpydoc - nvcc_linux-64=11.8 - ogb - openmpi -- packaging>=21 - pandas - pre-commit - pydantic - pydata-sphinx-theme -- pylibcugraphops==24.10.*,>=0.0.0a0 -- pylibraft==24.10.*,>=0.0.0a0 -- pylibwholegraph==24.10.*,>=0.0.0a0 +- pylibcugraphops==24.12.*,>=0.0.0a0 +- pylibraft==24.12.*,>=0.0.0a0 +- pylibwholegraph==24.12.*,>=0.0.0a0 - pytest - pytest-benchmark - pytest-cov - pytest-mpl - pytest-xdist - python-louvain -- pytorch>=2.0,<2.2.0a0 -- raft-dask==24.10.*,>=0.0.0a0 +- pytorch>=2.3,<2.4.0a0 +- raft-dask==24.12.*,>=0.0.0a0 - rapids-build-backend>=0.3.1,<0.4.0.dev0 -- rapids-dask-dependency==24.10.*,>=0.0.0a0 +- rapids-dask-dependency==24.12.*,>=0.0.0a0 - recommonmark - requests -- rmm==24.10.*,>=0.0.0a0 +- rmm==24.12.*,>=0.0.0a0 - scikit-build-core>=0.10.0 - scikit-learn>=0.23.1 - scipy @@ -77,7 +75,7 @@ dependencies: - torchdata - torchmetrics - ucx-proc=*=gpu -- ucx-py==0.40.*,>=0.0.0a0 +- ucx-py==0.41.*,>=0.0.0a0 - wget - wheel name: all_cuda-118_arch-x86_64 diff --git a/conda/environments/all_cuda-125_arch-x86_64.yaml b/conda/environments/all_cuda-125_arch-x86_64.yaml index ef20371e0f5..ff42bbbc365 100644 --- a/conda/environments/all_cuda-125_arch-x86_64.yaml +++ b/conda/environments/all_cuda-125_arch-x86_64.yaml @@ -4,8 +4,7 @@ channels: - rapidsai - rapidsai-nightly - dask/label/dev -- pyg -- dglteam/label/cu118 +- dglteam/label/th23_cu118 - conda-forge - nvidia dependencies: @@ -18,58 +17,57 @@ dependencies: - cuda-nvtx-dev - cuda-profiler-api - cuda-version=12.5 -- cudf==24.10.*,>=0.0.0a0 +- cudf==24.12.*,>=0.0.0a0 - cupy>=12.0.0 - cxx-compiler - cython>=3.0.0 -- dask-cuda==24.10.*,>=0.0.0a0 -- dask-cudf==24.10.*,>=0.0.0a0 +- dask-cuda==24.12.*,>=0.0.0a0 +- dask-cudf==24.12.*,>=0.0.0a0 - doxygen - fsspec>=0.6.0 - gcc_linux-64=11.* - graphviz - ipython - libcublas-dev -- libcudf==24.10.*,>=0.0.0a0 -- libcugraphops==24.10.*,>=0.0.0a0 +- libcudf==24.12.*,>=0.0.0a0 +- libcugraphops==24.12.*,>=0.0.0a0 - libcurand-dev - libcusolver-dev - libcusparse-dev -- libraft-headers==24.10.*,>=0.0.0a0 -- libraft==24.10.*,>=0.0.0a0 -- librmm==24.10.*,>=0.0.0a0 +- libraft-headers==24.12.*,>=0.0.0a0 +- libraft==24.12.*,>=0.0.0a0 +- librmm==24.12.*,>=0.0.0a0 - nbsphinx -- nccl>=2.9.9 +- nccl>=2.19 - networkx>=2.5.1 - networkx>=3.0 - ninja - notebook>=0.5.0 - numba>=0.57 -- numpy>=1.23,<2.0a0 +- numpy>=1.23,<3.0a0 - numpydoc - ogb - openmpi -- packaging>=21 - pandas - pre-commit - pydantic - pydata-sphinx-theme -- pylibcugraphops==24.10.*,>=0.0.0a0 -- pylibraft==24.10.*,>=0.0.0a0 -- pylibwholegraph==24.10.*,>=0.0.0a0 +- pylibcugraphops==24.12.*,>=0.0.0a0 +- pylibraft==24.12.*,>=0.0.0a0 +- pylibwholegraph==24.12.*,>=0.0.0a0 - pytest - pytest-benchmark - pytest-cov - pytest-mpl - pytest-xdist - python-louvain -- pytorch>=2.0,<2.2.0a0 -- raft-dask==24.10.*,>=0.0.0a0 +- pytorch>=2.3,<2.4.0a0 +- raft-dask==24.12.*,>=0.0.0a0 - rapids-build-backend>=0.3.1,<0.4.0.dev0 -- rapids-dask-dependency==24.10.*,>=0.0.0a0 +- rapids-dask-dependency==24.12.*,>=0.0.0a0 - recommonmark - requests -- rmm==24.10.*,>=0.0.0a0 +- rmm==24.12.*,>=0.0.0a0 - scikit-build-core>=0.10.0 - scikit-learn>=0.23.1 - scipy @@ -82,7 +80,7 @@ dependencies: - torchdata - torchmetrics - ucx-proc=*=gpu -- ucx-py==0.40.*,>=0.0.0a0 +- ucx-py==0.41.*,>=0.0.0a0 - wget - wheel name: all_cuda-125_arch-x86_64 diff --git a/conda/recipes/cugraph-dgl/meta.yaml b/conda/recipes/cugraph-dgl/meta.yaml index d1cf6fcd9e9..0383fc8adf8 100644 --- a/conda/recipes/cugraph-dgl/meta.yaml +++ b/conda/recipes/cugraph-dgl/meta.yaml @@ -25,13 +25,13 @@ requirements: - setuptools>=61.0.0 run: - cugraph ={{ version }} - - dgl >=1.1.0.cu* + - dgl >=2.4.0.th23.cu* - numba >=0.57 - - numpy >=1.23,<2.0a0 + - numpy >=1.23,<3.0a0 - pylibcugraphops ={{ minor_version }} - tensordict >=0.1.2 - python - - pytorch >=2.0 + - pytorch >=2.3,<2.4.0a0 - cupy >=12.0.0 tests: diff --git a/conda/recipes/cugraph-pyg/meta.yaml b/conda/recipes/cugraph-pyg/meta.yaml index 2e1788ac0c6..7d3e503e23a 100644 --- a/conda/recipes/cugraph-pyg/meta.yaml +++ b/conda/recipes/cugraph-pyg/meta.yaml @@ -29,14 +29,14 @@ requirements: run: - rapids-dask-dependency ={{ minor_version }} - numba >=0.57 - - numpy >=1.23,<2.0a0 + - numpy >=1.23,<3.0a0 - python - - pytorch >=2.0 + - pytorch >=2.3,<2.4.0a0 - cupy >=12.0.0 - cugraph ={{ version }} - pylibcugraphops ={{ minor_version }} - tensordict >=0.1.2 - - pyg >=2.5,<2.6 + - pytorch_geometric >=2.5,<2.6 tests: imports: diff --git a/conda/recipes/cugraph-service/conda_build_config.yaml b/conda/recipes/cugraph-service/conda_build_config.yaml index 2ac251ab10a..67ed3e26b0e 100644 --- a/conda/recipes/cugraph-service/conda_build_config.yaml +++ b/conda/recipes/cugraph-service/conda_build_config.yaml @@ -1,2 +1,2 @@ ucx_py_version: - - "0.40.*" + - "0.41.*" diff --git a/conda/recipes/cugraph-service/meta.yaml b/conda/recipes/cugraph-service/meta.yaml index c1027582c78..7df7573e2d0 100644 --- a/conda/recipes/cugraph-service/meta.yaml +++ b/conda/recipes/cugraph-service/meta.yaml @@ -63,7 +63,7 @@ outputs: - dask-cuda ={{ minor_version }} - dask-cudf ={{ minor_version }} - numba >=0.57 - - numpy >=1.23,<2.0a0 + - numpy >=1.23,<3.0a0 - python - rapids-dask-dependency ={{ minor_version }} - thriftpy2 >=0.4.15,!=0.5.0,!=0.5.1 diff --git a/conda/recipes/cugraph/conda_build_config.yaml b/conda/recipes/cugraph/conda_build_config.yaml index 2525441f92d..10f2e15c550 100644 --- a/conda/recipes/cugraph/conda_build_config.yaml +++ b/conda/recipes/cugraph/conda_build_config.yaml @@ -20,4 +20,4 @@ c_stdlib_version: - "2.17" ucx_py_version: - - "0.40.*" + - "0.41.*" diff --git a/conda/recipes/libcugraph/conda_build_config.yaml b/conda/recipes/libcugraph/conda_build_config.yaml index 26aa428d7f5..55bd635c330 100644 --- a/conda/recipes/libcugraph/conda_build_config.yaml +++ b/conda/recipes/libcugraph/conda_build_config.yaml @@ -17,7 +17,7 @@ doxygen_version: - ">=1.8.11" nccl_version: - - ">=2.9.9" + - ">=2.19" c_stdlib: - sysroot diff --git a/conda/recipes/pylibcugraph/conda_build_config.yaml b/conda/recipes/pylibcugraph/conda_build_config.yaml index 2525441f92d..10f2e15c550 100644 --- a/conda/recipes/pylibcugraph/conda_build_config.yaml +++ b/conda/recipes/pylibcugraph/conda_build_config.yaml @@ -20,4 +20,4 @@ c_stdlib_version: - "2.17" ucx_py_version: - - "0.40.*" + - "0.41.*" diff --git a/cpp/CMakeLists.txt b/cpp/CMakeLists.txt index cf4307b3894..f23d9db9b8c 100644 --- a/cpp/CMakeLists.txt +++ b/cpp/CMakeLists.txt @@ -175,57 +175,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 @@ -233,127 +217,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.cu - src/sampling/neighbor_sampling_mg_v32_e32.cu - src/sampling/neighbor_sampling_mg_v64_e64.cu - src/sampling/neighbor_sampling_sg_v32_e64.cu - src/sampling/neighbor_sampling_sg_v32_e32.cu - src/sampling/neighbor_sampling_sg_v64_e64.cu - src/sampling/negative_sampling_sg_v32_e64.cu + src/sampling/neighbor_sampling_mg_v32_e32.cpp + src/sampling/neighbor_sampling_mg_v64_e64.cpp + src/sampling/neighbor_sampling_sg_v32_e32.cpp + src/sampling/neighbor_sampling_sg_v64_e64.cpp 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 @@ -367,55 +313,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 @@ -426,115 +355,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 diff --git a/cpp/include/cugraph/algorithms.hpp b/cpp/include/cugraph/algorithms.hpp index ed42460ed8e..7e5af4ac686 100644 --- a/cpp/include/cugraph/algorithms.hpp +++ b/cpp/include/cugraph/algorithms.hpp @@ -1579,11 +1579,11 @@ std:: template std::tuple, std::optional>> uniform_random_walks(raft::handle_t const& handle, + raft::random::RngState& rng_state, graph_view_t const& graph_view, std::optional> edge_weight_view, raft::device_span start_vertices, - size_t max_length, - uint64_t seed = std::numeric_limits::max()); + size_t max_length); /** * @brief returns biased random walks from starting sources, where each path is of given @@ -1623,11 +1623,11 @@ uniform_random_walks(raft::handle_t const& handle, template std::tuple, std::optional>> biased_random_walks(raft::handle_t const& handle, + raft::random::RngState& rng_state, graph_view_t const& graph_view, edge_property_view_t edge_weight_view, raft::device_span start_vertices, - size_t max_length, - uint64_t seed = std::numeric_limits::max()); + size_t max_length); /** * @brief returns biased random walks with node2vec biases from starting sources, @@ -1670,13 +1670,13 @@ biased_random_walks(raft::handle_t const& handle, template std::tuple, std::optional>> node2vec_random_walks(raft::handle_t const& handle, + raft::random::RngState& rng_state, graph_view_t const& graph_view, std::optional> edge_weight_view, raft::device_span start_vertices, size_t max_length, weight_t p, - weight_t q, - uint64_t seed = std::numeric_limits::max()); + weight_t q); #ifndef NO_CUGRAPH_OPS /** diff --git a/cpp/include/cugraph/mtmg/instance_manager.hpp b/cpp/include/cugraph/mtmg/instance_manager.hpp index a2111804997..759635b4a34 100644 --- a/cpp/include/cugraph/mtmg/instance_manager.hpp +++ b/cpp/include/cugraph/mtmg/instance_manager.hpp @@ -20,6 +20,8 @@ #include +#include + #include namespace cugraph { diff --git a/cpp/include/cugraph/mtmg/resource_manager.hpp b/cpp/include/cugraph/mtmg/resource_manager.hpp index a9e4b81f894..e9d25c4576b 100644 --- a/cpp/include/cugraph/mtmg/resource_manager.hpp +++ b/cpp/include/cugraph/mtmg/resource_manager.hpp @@ -27,6 +27,8 @@ #include #include +#include + #include namespace cugraph { 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/graph.h b/cpp/include/cugraph_c/graph.h index 00fce0493a3..c5ce9c9fbeb 100644 --- a/cpp/include/cugraph_c/graph.h +++ b/cpp/include/cugraph_c/graph.h @@ -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. @@ -35,48 +35,6 @@ typedef struct { bool_t is_multigraph; } cugraph_graph_properties_t; -/** - * @brief Construct an SG graph - * - * @deprecated This API will be deleted, use cugraph_graph_create_sg instead - * - * @param [in] handle Handle for accessing resources - * @param [in] properties Properties of the constructed graph - * @param [in] src Device array containing the source vertex ids. - * @param [in] dst Device array containing the destination vertex ids - * @param [in] weights Device array containing the edge weights. Note that an unweighted - * graph can be created by passing weights == NULL. - * @param [in] edge_ids Device array containing the edge ids for each edge. Optional - argument that can be NULL if edge ids are not used. - * @param [in] edge_type_ids Device array containing the edge types for each edge. Optional - argument that can be NULL if edge types are not used. - * @param [in] store_transposed If true create the graph initially in transposed format - * @param [in] renumber If true, renumber vertices to make an efficient data structure. - * If false, do not renumber. Renumbering enables some significant optimizations within - * the graph primitives library, so it is strongly encouraged. Renumbering is required if - * the vertices are not sequential integer values from 0 to num_vertices. - * @param [in] do_expensive_check If true, do expensive checks to validate the input data - * is consistent with software assumptions. If false bypass these checks. - * @param [out] graph A pointer to the graph object - * @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_sg_graph_create( - const cugraph_resource_handle_t* handle, - const cugraph_graph_properties_t* properties, - const cugraph_type_erased_device_array_view_t* src, - const cugraph_type_erased_device_array_view_t* dst, - const cugraph_type_erased_device_array_view_t* weights, - const cugraph_type_erased_device_array_view_t* edge_ids, - const cugraph_type_erased_device_array_view_t* edge_type_ids, - bool_t store_transposed, - bool_t renumber, - bool_t do_expensive_check, - cugraph_graph_t** graph, - cugraph_error_t** error); - /** * @brief Construct an SG graph * @@ -105,6 +63,8 @@ cugraph_error_code_t cugraph_sg_graph_create( weights, * or take the maximum weight), the caller should remove specific edges themselves and not rely * on this flag. + * @param [in] symmetrize If true, symmetrize the edgelist. The symmetrization of edges + * with edge_ids and/or edge_type_ids is currently not supported. * @param [in] do_expensive_check If true, do expensive checks to validate the input data * is consistent with software assumptions. If false bypass these checks. * @param [out] graph A pointer to the graph object @@ -126,48 +86,7 @@ cugraph_error_code_t cugraph_graph_create_sg( bool_t renumber, bool_t drop_self_loops, bool_t drop_multi_edges, - bool_t do_expensive_check, - cugraph_graph_t** graph, - cugraph_error_t** error); - -/** - * @brief Construct an SG graph from a CSR input - * - * @deprecated This API will be deleted, use cugraph_graph_create_sg_from_csr instead - * - * @param [in] handle Handle for accessing resources - * @param [in] properties Properties of the constructed graph - * @param [in] offsets Device array containing the CSR offsets array - * @param [in] indices Device array containing the destination vertex ids - * @param [in] weights Device array containing the edge weights. Note that an unweighted - * graph can be created by passing weights == NULL. - * @param [in] edge_ids Device array containing the edge ids for each edge. Optional - argument that can be NULL if edge ids are not used. - * @param [in] edge_type_ids Device array containing the edge types for each edge. Optional - argument that can be NULL if edge types are not used. - * @param [in] store_transposed If true create the graph initially in transposed format - * @param [in] renumber If true, renumber vertices to make an efficient data structure. - * If false, do not renumber. Renumbering enables some significant optimizations within - * the graph primitives library, so it is strongly encouraged. Renumbering is required if - * the vertices are not sequential integer values from 0 to num_vertices. - * @param [in] do_expensive_check If true, do expensive checks to validate the input data - * is consistent with software assumptions. If false bypass these checks. - * @param [out] graph A pointer to the graph object - * @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_sg_graph_create_from_csr( - const cugraph_resource_handle_t* handle, - const cugraph_graph_properties_t* properties, - const cugraph_type_erased_device_array_view_t* offsets, - const cugraph_type_erased_device_array_view_t* indices, - const cugraph_type_erased_device_array_view_t* weights, - const cugraph_type_erased_device_array_view_t* edge_ids, - const cugraph_type_erased_device_array_view_t* edge_type_ids, - bool_t store_transposed, - bool_t renumber, + bool_t symmetrize, bool_t do_expensive_check, cugraph_graph_t** graph, cugraph_error_t** error); @@ -190,6 +109,8 @@ cugraph_error_code_t cugraph_sg_graph_create_from_csr( * If false, do not renumber. Renumbering enables some significant optimizations within * the graph primitives library, so it is strongly encouraged. Renumbering is required if * the vertices are not sequential integer values from 0 to num_vertices. + * @param [in] symmetrize If true, symmetrize the edgelist. The symmetrization of edges + * with edge_ids and/or edge_type_ids is currently not supported. * @param [in] do_expensive_check If true, do expensive checks to validate the input data * is consistent with software assumptions. If false bypass these checks. * @param [out] graph A pointer to the graph object @@ -208,47 +129,7 @@ cugraph_error_code_t cugraph_graph_create_sg_from_csr( const cugraph_type_erased_device_array_view_t* edge_type_ids, bool_t store_transposed, bool_t renumber, - bool_t do_expensive_check, - cugraph_graph_t** graph, - cugraph_error_t** error); - -/** - * @brief Construct an MG graph - * - * @deprecated This API will be deleted, use cugraph_graph_create_mg instead - * - * @param [in] handle Handle for accessing resources - * @param [in] properties Properties of the constructed graph - * @param [in] src Device array containing the source vertex ids - * @param [in] dst Device array containing the destination vertex ids - * @param [in] weights Device array containing the edge weights. Note that an unweighted - * graph can be created by passing weights == NULL. If a weighted - * graph is to be created, the weights device array should be created - * on each rank, but the pointer can be NULL and the size 0 - * if there are no inputs provided by this rank - * @param [in] edge_ids Device array containing the edge ids for each edge. Optional - argument that can be NULL if edge ids are not used. - * @param [in] edge_type_ids Device array containing the edge types for each edge. Optional - argument that can be NULL if edge types are not used. - * @param [in] store_transposed If true create the graph initially in transposed format - * @param [in] num_edges Number of edges - * @param [in] do_expensive_check If true, do expensive checks to validate the input data - * is consistent with software assumptions. If false bypass these checks. - * @param [out] graph A pointer to the graph object - * @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_mg_graph_create( - const cugraph_resource_handle_t* handle, - const cugraph_graph_properties_t* properties, - const cugraph_type_erased_device_array_view_t* src, - const cugraph_type_erased_device_array_view_t* dst, - const cugraph_type_erased_device_array_view_t* weights, - const cugraph_type_erased_device_array_view_t* edge_ids, - const cugraph_type_erased_device_array_view_t* edge_type_ids, - bool_t store_transposed, - size_t num_edges, + bool_t symmetrize, bool_t do_expensive_check, cugraph_graph_t** graph, cugraph_error_t** error); @@ -289,6 +170,8 @@ cugraph_error_code_t cugraph_mg_graph_create( * Note that setting this flag will arbitrarily select one instance of a multi edge to be the * edge that survives. If the edges have properties that should be honored (e.g. sum the * weights, or take the maximum weight), the caller should do that on not rely on this flag. + * @param [in] symmetrize If true, symmetrize the edgelist. The symmetrization of edges + * with edge_ids and/or edge_type_ids is currently not supported. * @param [in] do_expensive_check If true, do expensive checks to validate the input data * is consistent with software assumptions. If false bypass these checks. * @param [out] graph A pointer to the graph object @@ -309,6 +192,7 @@ cugraph_error_code_t cugraph_graph_create_mg( size_t num_arrays, bool_t drop_self_loops, bool_t drop_multi_edges, + bool_t symmetrize, bool_t do_expensive_check, cugraph_graph_t** graph, cugraph_error_t** error); @@ -320,24 +204,6 @@ cugraph_error_code_t cugraph_graph_create_mg( */ void cugraph_graph_free(cugraph_graph_t* graph); -/** - * @brief Destroy an SG graph - * - * @deprecated This API will be deleted, use cugraph_graph_free instead - * - * @param [in] graph A pointer to the graph object to destroy - */ -void cugraph_sg_graph_free(cugraph_graph_t* graph); - -/** - * @brief Destroy an MG graph - * - * @deprecated This API will be deleted, use cugraph_graph_free instead - * - * @param [in] graph A pointer to the graph object to destroy - */ -void cugraph_mg_graph_free(cugraph_graph_t* graph); - /** * @brief Create a data mask * 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/src/c_api/graph_generators.cpp b/cpp/src/c_api/graph_generators.cpp index 7601f1508f9..a58a4d5db35 100644 --- a/cpp/src/c_api/graph_generators.cpp +++ b/cpp/src/c_api/graph_generators.cpp @@ -124,32 +124,41 @@ cugraph_error_code_t cugraph_generate_rmat_edgelists( extern "C" cugraph_type_erased_device_array_view_t* cugraph_coo_get_sources(cugraph_coo_t* coo) { auto internal_pointer = reinterpret_cast(coo); - return reinterpret_cast(internal_pointer->src_->view()); + return (internal_pointer->src_) ? reinterpret_cast( + internal_pointer->src_->view()) + : nullptr; } extern "C" cugraph_type_erased_device_array_view_t* cugraph_coo_get_destinations(cugraph_coo_t* coo) { auto internal_pointer = reinterpret_cast(coo); - return reinterpret_cast(internal_pointer->dst_->view()); + return (internal_pointer->dst_) ? reinterpret_cast( + internal_pointer->dst_->view()) + : nullptr; } extern "C" cugraph_type_erased_device_array_view_t* cugraph_coo_get_edge_weights(cugraph_coo_t* coo) { auto internal_pointer = reinterpret_cast(coo); - return reinterpret_cast(internal_pointer->wgt_->view()); + return (internal_pointer->wgt_) ? reinterpret_cast( + internal_pointer->wgt_->view()) + : nullptr; } extern "C" cugraph_type_erased_device_array_view_t* cugraph_coo_get_edge_id(cugraph_coo_t* coo) { auto internal_pointer = reinterpret_cast(coo); - return reinterpret_cast(internal_pointer->id_->view()); + return (internal_pointer->id_) ? reinterpret_cast( + internal_pointer->id_->view()) + : nullptr; } extern "C" cugraph_type_erased_device_array_view_t* cugraph_coo_get_edge_type(cugraph_coo_t* coo) { auto internal_pointer = reinterpret_cast(coo); - return reinterpret_cast( - internal_pointer->type_->view()); + return (internal_pointer->type_) ? reinterpret_cast( + internal_pointer->type_->view()) + : nullptr; } extern "C" size_t cugraph_coo_list_size(const cugraph_coo_list_t* coo_list) 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 cc4acd31743..c63528a9180 100644 --- a/cpp/src/c_api/graph_mg.cpp +++ b/cpp/src/c_api/graph_mg.cpp @@ -71,6 +71,7 @@ struct create_graph_functor : public cugraph::c_api::abstract_functor { bool_t renumber_; bool_t drop_self_loops_; bool_t drop_multi_edges_; + bool_t symmetrize_; bool_t do_expensive_check_; cugraph::c_api::cugraph_graph_t* result_{}; @@ -91,6 +92,7 @@ struct create_graph_functor : public cugraph::c_api::abstract_functor { bool_t renumber, bool_t drop_self_loops, bool_t drop_multi_edges, + bool_t symmetrize, bool_t do_expensive_check) : abstract_functor(), properties_(properties), @@ -109,6 +111,7 @@ struct create_graph_functor : public cugraph::c_api::abstract_functor { renumber_(renumber), drop_self_loops_(drop_self_loops), drop_multi_edges_(drop_multi_edges), + symmetrize_(symmetrize), do_expensive_check_(do_expensive_check) { } @@ -224,6 +227,22 @@ struct create_graph_functor : public cugraph::c_api::abstract_functor { : false); } + if (symmetrize_) { + if (edgelist_edge_ids || edgelist_edge_types) { + // Currently doesn't support the symmetrization of edgelist with edge_ids and edge_types + unsupported(); + } + + // Symmetrize the edgelist + std::tie(edgelist_srcs, edgelist_dsts, edgelist_weights) = + cugraph::symmetrize_edgelist( + handle_, + std::move(edgelist_srcs), + std::move(edgelist_dsts), + std::move(edgelist_weights), + false); + } + std::tie(*graph, new_edge_weights, new_edge_ids, new_edge_types, new_number_map) = cugraph::create_graph_from_edgelisttype_; } + if (symmetrize == TRUE) { + CAPI_EXPECTS((properties->is_symmetric == TRUE), + CUGRAPH_INVALID_INPUT, + "Invalid input arguments: The graph property must be symmetric if 'symmetrize' " + "is set to True.", + *error); + } + CAPI_EXPECTS(p_src[i]->type_ == vertex_type, CUGRAPH_INVALID_INPUT, "Invalid input arguments: all vertex types must match", @@ -374,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()); @@ -406,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; } @@ -488,6 +516,7 @@ extern "C" cugraph_error_code_t cugraph_graph_create_mg( bool_t::TRUE, drop_self_loops, drop_multi_edges, + symmetrize, do_expensive_check); try { @@ -507,39 +536,3 @@ extern "C" cugraph_error_code_t cugraph_graph_create_mg( return CUGRAPH_SUCCESS; } - -extern "C" cugraph_error_code_t cugraph_mg_graph_create( - cugraph_resource_handle_t const* handle, - cugraph_graph_properties_t const* properties, - cugraph_type_erased_device_array_view_t const* src, - cugraph_type_erased_device_array_view_t const* dst, - cugraph_type_erased_device_array_view_t const* weights, - cugraph_type_erased_device_array_view_t const* edge_ids, - cugraph_type_erased_device_array_view_t const* edge_type_ids, - bool_t store_transposed, - size_t num_edges, - bool_t do_expensive_check, - cugraph_graph_t** graph, - cugraph_error_t** error) -{ - return cugraph_graph_create_mg(handle, - properties, - NULL, - &src, - &dst, - (weights == nullptr) ? nullptr : &weights, - (edge_ids == nullptr) ? nullptr : &edge_ids, - (edge_type_ids == nullptr) ? nullptr : &edge_type_ids, - store_transposed, - 1, - FALSE, - FALSE, - do_expensive_check, - graph, - error); -} - -extern "C" void cugraph_mg_graph_free(cugraph_graph_t* ptr_graph) -{ - if (ptr_graph != NULL) { cugraph_graph_free(ptr_graph); } -} diff --git a/cpp/src/c_api/graph_sg.cpp b/cpp/src/c_api/graph_sg.cpp index ff71471a8d0..e57d6b5bb14 100644 --- a/cpp/src/c_api/graph_sg.cpp +++ b/cpp/src/c_api/graph_sg.cpp @@ -43,6 +43,7 @@ struct create_graph_functor : public cugraph::c_api::abstract_functor { bool_t renumber_; bool_t drop_self_loops_; bool_t drop_multi_edges_; + bool_t symmetrize_; bool_t do_expensive_check_; cugraph_data_type_id_t edge_type_; cugraph::c_api::cugraph_graph_t* result_{}; @@ -58,6 +59,7 @@ struct create_graph_functor : public cugraph::c_api::abstract_functor { bool_t renumber, bool_t drop_self_loops, bool_t drop_multi_edges, + bool_t symmetrize, bool_t do_expensive_check, cugraph_data_type_id_t edge_type) : abstract_functor(), @@ -72,6 +74,7 @@ struct create_graph_functor : public cugraph::c_api::abstract_functor { renumber_(renumber), drop_self_loops_(drop_self_loops), drop_multi_edges_(drop_multi_edges), + symmetrize_(symmetrize), do_expensive_check_(do_expensive_check), edge_type_(edge_type) { @@ -207,6 +210,22 @@ struct create_graph_functor : public cugraph::c_api::abstract_functor { : false); } + if (symmetrize_) { + if (edgelist_edge_ids || edgelist_edge_types) { + // Currently doesn't support the symmetrization with edge_ids and edge_types + unsupported(); + } + + // Symmetrize the edgelist + std::tie(edgelist_srcs, edgelist_dsts, edgelist_weights) = + cugraph::symmetrize_edgelist( + handle_, + std::move(edgelist_srcs), + std::move(edgelist_dsts), + std::move(edgelist_weights), + false); + } + std::tie(*graph, new_edge_weights, new_edge_ids, new_edge_types, new_number_map) = cugraph::create_graph_from_edgelist, edge_type_id_t>(handle_); + if (symmetrize_) { + if (edgelist_edge_ids || edgelist_edge_types) { + // Currently doesn't support the symmetrization with edge_ids and edge_types + unsupported(); + } + + // Symmetrize the edgelist + std::tie(edgelist_srcs, edgelist_dsts, edgelist_weights) = + cugraph::symmetrize_edgelist( + handle_, + std::move(edgelist_srcs), + std::move(edgelist_dsts), + std::move(edgelist_weights), + false); + } + std::tie(*graph, new_edge_weights, new_edge_ids, new_edge_types, new_number_map) = cugraph::create_graph_from_edgelist(edge_type_ids); + if (symmetrize == TRUE) { + CAPI_EXPECTS((properties->is_symmetric == TRUE), + CUGRAPH_INVALID_INPUT, + "Invalid input arguments: The graph property must be symmetric if 'symmetrize' is " + "set to True.", + *error); + } + CAPI_EXPECTS(p_src->size_ == p_dst->size_, CUGRAPH_INVALID_INPUT, "Invalid input arguments: src size != dst size.", @@ -562,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_; @@ -606,6 +653,7 @@ extern "C" cugraph_error_code_t cugraph_graph_create_sg( renumber, drop_self_loops, drop_multi_edges, + symmetrize, do_expensive_check, edge_type); @@ -632,37 +680,6 @@ extern "C" cugraph_error_code_t cugraph_graph_create_sg( return CUGRAPH_SUCCESS; } -extern "C" cugraph_error_code_t cugraph_sg_graph_create( - const cugraph_resource_handle_t* handle, - const cugraph_graph_properties_t* properties, - const cugraph_type_erased_device_array_view_t* src, - const cugraph_type_erased_device_array_view_t* dst, - const cugraph_type_erased_device_array_view_t* weights, - const cugraph_type_erased_device_array_view_t* edge_ids, - const cugraph_type_erased_device_array_view_t* edge_type_ids, - bool_t store_transposed, - bool_t renumber, - bool_t do_expensive_check, - cugraph_graph_t** graph, - cugraph_error_t** error) -{ - return cugraph_graph_create_sg(handle, - properties, - NULL, - src, - dst, - weights, - edge_ids, - edge_type_ids, - store_transposed, - renumber, - FALSE, - FALSE, - do_expensive_check, - graph, - error); -} - cugraph_error_code_t cugraph_graph_create_sg_from_csr( const cugraph_resource_handle_t* handle, const cugraph_graph_properties_t* properties, @@ -673,6 +690,7 @@ cugraph_error_code_t cugraph_graph_create_sg_from_csr( const cugraph_type_erased_device_array_view_t* edge_type_ids, bool_t store_transposed, bool_t renumber, + bool_t symmetrize, bool_t do_expensive_check, cugraph_graph_t** graph, cugraph_error_t** error) @@ -707,6 +725,14 @@ cugraph_error_code_t cugraph_graph_create_sg_from_csr( weight_type = cugraph_data_type_id_t::FLOAT32; } + if (symmetrize == TRUE) { + CAPI_EXPECTS((properties->is_symmetric == TRUE), + CUGRAPH_INVALID_INPUT, + "Invalid input arguments: The graph property must be symmetric if 'symmetrize' is " + "set to True.", + *error); + } + CAPI_EXPECTS( (edge_type_ids == nullptr && edge_ids == nullptr) || (edge_type_ids != nullptr && edge_ids != nullptr), @@ -735,6 +761,7 @@ cugraph_error_code_t cugraph_graph_create_sg_from_csr( p_edge_ids, p_edge_type_ids, renumber, + symmetrize, do_expensive_check); try { @@ -760,34 +787,6 @@ cugraph_error_code_t cugraph_graph_create_sg_from_csr( return CUGRAPH_SUCCESS; } -cugraph_error_code_t cugraph_sg_graph_create_from_csr( - const cugraph_resource_handle_t* handle, - const cugraph_graph_properties_t* properties, - const cugraph_type_erased_device_array_view_t* offsets, - const cugraph_type_erased_device_array_view_t* indices, - const cugraph_type_erased_device_array_view_t* weights, - const cugraph_type_erased_device_array_view_t* edge_ids, - const cugraph_type_erased_device_array_view_t* edge_type_ids, - bool_t store_transposed, - bool_t renumber, - bool_t do_expensive_check, - cugraph_graph_t** graph, - cugraph_error_t** error) -{ - return cugraph_graph_create_sg_from_csr(handle, - properties, - offsets, - indices, - weights, - edge_ids, - edge_type_ids, - store_transposed, - renumber, - do_expensive_check, - graph, - error); -} - extern "C" void cugraph_graph_free(cugraph_graph_t* ptr_graph) { if (ptr_graph != NULL) { @@ -810,5 +809,3 @@ extern "C" void cugraph_graph_free(cugraph_graph_t* ptr_graph) delete internal_pointer; } } - -extern "C" void cugraph_sg_graph_free(cugraph_graph_t* ptr_graph) { cugraph_graph_free(ptr_graph); } 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/random_walks.cpp b/cpp/src/c_api/random_walks.cpp index b9a2c8e4f60..705d2108437 100644 --- a/cpp/src/c_api/random_walks.cpp +++ b/cpp/src/c_api/random_walks.cpp @@ -16,6 +16,7 @@ #include "c_api/abstract_functor.hpp" #include "c_api/graph.hpp" +#include "c_api/random.hpp" #include "c_api/resource_handle.hpp" #include "c_api/utils.hpp" @@ -153,10 +154,11 @@ namespace { struct uniform_random_walks_functor : public cugraph::c_api::abstract_functor { raft::handle_t const& handle_; + // FIXME: rng_state_ should be passed as a parameter + cugraph::c_api::cugraph_rng_state_t* rng_state_{nullptr}; cugraph::c_api::cugraph_graph_t* graph_{nullptr}; cugraph::c_api::cugraph_type_erased_device_array_view_t const* start_vertices_{nullptr}; size_t max_length_{0}; - size_t seed_{0}; cugraph::c_api::cugraph_random_walk_result_t* result_{nullptr}; uniform_random_walks_functor(cugraph_resource_handle_t const* handle, @@ -222,13 +224,17 @@ struct uniform_random_walks_functor : public cugraph::c_api::abstract_functor { graph_view.local_vertex_partition_range_last(), false); + // FIXME: remove once rng_state passed as parameter + rng_state_ = reinterpret_cast( + new cugraph::c_api::cugraph_rng_state_t{raft::random::RngState{0}}); + auto [paths, weights] = cugraph::uniform_random_walks( handle_, + rng_state_->rng_state_, graph_view, (edge_weights != nullptr) ? std::make_optional(edge_weights->view()) : std::nullopt, raft::device_span{start_vertices.data(), start_vertices.size()}, - max_length_, - seed_); + max_length_); // // Need to unrenumber the vertices in the resulting paths @@ -255,11 +261,12 @@ struct uniform_random_walks_functor : public cugraph::c_api::abstract_functor { struct biased_random_walks_functor : public cugraph::c_api::abstract_functor { raft::handle_t const& handle_; + // FIXME: rng_state_ should be passed as a parameter + cugraph::c_api::cugraph_rng_state_t* rng_state_{nullptr}; cugraph::c_api::cugraph_graph_t* graph_{nullptr}; cugraph::c_api::cugraph_type_erased_device_array_view_t const* start_vertices_{nullptr}; size_t max_length_{0}; cugraph::c_api::cugraph_random_walk_result_t* result_{nullptr}; - uint64_t seed_{0}; biased_random_walks_functor(cugraph_resource_handle_t const* handle, cugraph_graph_t* graph, @@ -326,13 +333,17 @@ struct biased_random_walks_functor : public cugraph::c_api::abstract_functor { graph_view.local_vertex_partition_range_last(), false); + // FIXME: remove once rng_state passed as parameter + rng_state_ = reinterpret_cast( + new cugraph::c_api::cugraph_rng_state_t{raft::random::RngState{0}}); + auto [paths, weights] = cugraph::biased_random_walks( handle_, + rng_state_->rng_state_, graph_view, edge_weights->view(), raft::device_span{start_vertices.data(), start_vertices.size()}, - max_length_, - seed_); + max_length_); // // Need to unrenumber the vertices in the resulting paths @@ -354,12 +365,13 @@ struct biased_random_walks_functor : public cugraph::c_api::abstract_functor { struct node2vec_random_walks_functor : public cugraph::c_api::abstract_functor { raft::handle_t const& handle_; + // FIXME: rng_state_ should be passed as a parameter + cugraph::c_api::cugraph_rng_state_t* rng_state_{nullptr}; cugraph::c_api::cugraph_graph_t* graph_{nullptr}; cugraph::c_api::cugraph_type_erased_device_array_view_t const* start_vertices_{nullptr}; size_t max_length_{0}; double p_{0}; double q_{0}; - uint64_t seed_{0}; cugraph::c_api::cugraph_random_walk_result_t* result_{nullptr}; node2vec_random_walks_functor(cugraph_resource_handle_t const* handle, @@ -431,15 +443,19 @@ struct node2vec_random_walks_functor : public cugraph::c_api::abstract_functor { graph_view.local_vertex_partition_range_last(), false); + // FIXME: remove once rng_state passed as parameter + rng_state_ = reinterpret_cast( + new cugraph::c_api::cugraph_rng_state_t{raft::random::RngState{0}}); + auto [paths, weights] = cugraph::node2vec_random_walks( handle_, + rng_state_->rng_state_, graph_view, (edge_weights != nullptr) ? std::make_optional(edge_weights->view()) : std::nullopt, raft::device_span{start_vertices.data(), start_vertices.size()}, max_length_, static_cast(p_), - static_cast(q_), - seed_); + static_cast(q_)); // FIXME: Need to fix invalid_vtx issue here. We can't unrenumber max_vertex_id+1 // properly... diff --git a/cpp/src/centrality/betweenness_centrality_mg_v32_e64.cu b/cpp/src/centrality/betweenness_centrality_mg_v32_e64.cu deleted file mode 100644 index e90ae93b407..00000000000 --- a/cpp/src/centrality/betweenness_centrality_mg_v32_e64.cu +++ /dev/null @@ -1,58 +0,0 @@ -/* - * 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. - * 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. - */ -#include "centrality/betweenness_centrality_impl.cuh" - -namespace cugraph { - -// MG instantiation - -template rmm::device_uvector betweenness_centrality( - raft::handle_t const& handle, - graph_view_t const& graph_view, - std::optional> edge_weight_view, - std::optional> vertices, - bool const normalized, - bool const include_endpoints, - bool do_expensive_check); - -template rmm::device_uvector betweenness_centrality( - raft::handle_t const& handle, - graph_view_t const& graph_view, - std::optional> edge_weight_view, - std::optional> vertices, - bool const normalized, - bool const include_endpoints, - bool do_expensive_check); - -template edge_property_t, float> -edge_betweenness_centrality( - const raft::handle_t& handle, - graph_view_t const& graph_view, - std::optional> edge_weight_view, - std::optional> vertices, - bool const normalized, - bool const do_expensive_check); - -template edge_property_t, double> -edge_betweenness_centrality( - const raft::handle_t& handle, - graph_view_t const& graph_view, - std::optional> edge_weight_view, - std::optional> vertices, - bool const normalized, - bool const do_expensive_check); - -} // namespace cugraph diff --git a/cpp/src/centrality/betweenness_centrality_sg_v32_e64.cu b/cpp/src/centrality/betweenness_centrality_sg_v32_e64.cu deleted file mode 100644 index 21175047fe9..00000000000 --- a/cpp/src/centrality/betweenness_centrality_sg_v32_e64.cu +++ /dev/null @@ -1,58 +0,0 @@ -/* - * 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. - * 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. - */ -#include "centrality/betweenness_centrality_impl.cuh" - -namespace cugraph { - -// SG instantiation - -template rmm::device_uvector betweenness_centrality( - raft::handle_t const& handle, - graph_view_t const& graph_view, - std::optional> edge_weight_view, - std::optional> vertices, - bool const normalized, - bool const include_endpoints, - bool do_expensive_check); - -template rmm::device_uvector betweenness_centrality( - raft::handle_t const& handle, - graph_view_t const& graph_view, - std::optional> edge_weight_view, - std::optional> vertices, - bool const normalized, - bool const include_endpoints, - bool do_expensive_check); - -template edge_property_t, float> -edge_betweenness_centrality( - const raft::handle_t& handle, - graph_view_t const& graph_view, - std::optional> edge_weight_view, - std::optional> vertices, - bool const normalized, - bool const do_expensive_check); - -template edge_property_t, double> -edge_betweenness_centrality( - const raft::handle_t& handle, - graph_view_t const& graph_view, - std::optional> edge_weight_view, - std::optional> vertices, - bool const normalized, - bool const do_expensive_check); - -} // namespace cugraph diff --git a/cpp/src/centrality/eigenvector_centrality_mg_v32_e64.cu b/cpp/src/centrality/eigenvector_centrality_mg_v32_e64.cu deleted file mode 100644 index 77d74310c8e..00000000000 --- a/cpp/src/centrality/eigenvector_centrality_mg_v32_e64.cu +++ /dev/null @@ -1,40 +0,0 @@ -/* - * 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. - * 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. - */ -#include "centrality/eigenvector_centrality_impl.cuh" - -namespace cugraph { - -// MG instantiation - -template rmm::device_uvector eigenvector_centrality( - raft::handle_t const& handle, - graph_view_t const& graph_view, - std::optional> edge_weight_view, - std::optional> initial_centralities, - float epsilon, - size_t max_iterations, - bool do_expensive_check); - -template rmm::device_uvector eigenvector_centrality( - raft::handle_t const& handle, - graph_view_t const& graph_view, - std::optional> edge_weight_view, - std::optional> initial_centralities, - double epsilon, - size_t max_iterations, - bool do_expensive_check); - -} // namespace cugraph diff --git a/cpp/src/centrality/eigenvector_centrality_sg_v32_e64.cu b/cpp/src/centrality/eigenvector_centrality_sg_v32_e64.cu deleted file mode 100644 index c0efa7a59c1..00000000000 --- a/cpp/src/centrality/eigenvector_centrality_sg_v32_e64.cu +++ /dev/null @@ -1,40 +0,0 @@ -/* - * 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. - * 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. - */ -#include "centrality/eigenvector_centrality_impl.cuh" - -namespace cugraph { - -// SG instantiation - -template rmm::device_uvector eigenvector_centrality( - raft::handle_t const& handle, - graph_view_t const& graph_view, - std::optional> edge_weight_view, - std::optional> initial_centralities, - float epsilon, - size_t max_iterations, - bool do_expensive_check); - -template rmm::device_uvector eigenvector_centrality( - raft::handle_t const& handle, - graph_view_t const& graph_view, - std::optional> edge_weight_view, - std::optional> initial_centralities, - double epsilon, - size_t max_iterations, - bool do_expensive_check); - -} // namespace cugraph diff --git a/cpp/src/centrality/katz_centrality_mg_v32_e64.cu b/cpp/src/centrality/katz_centrality_mg_v32_e64.cu deleted file mode 100644 index 22efe9b5606..00000000000 --- a/cpp/src/centrality/katz_centrality_mg_v32_e64.cu +++ /dev/null @@ -1,50 +0,0 @@ -/* - * Copyright (c) 2021-2024, NVIDIA CORPORATION. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * 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. - */ -#include "centrality/katz_centrality_impl.cuh" - -namespace cugraph { - -// MG instantiation - -template void katz_centrality( - raft::handle_t const& handle, - graph_view_t const& graph_view, - std::optional> edge_weight_view, - float const* betas, - float* katz_centralities, - float alpha, - float beta, - float epsilon, - size_t max_iterations, - bool has_initial_guess, - bool normalize, - bool do_expensive_check); - -template void katz_centrality( - raft::handle_t const& handle, - graph_view_t const& graph_view, - std::optional> edge_weight_view, - double const* betas, - double* katz_centralities, - double alpha, - double beta, - double epsilon, - size_t max_iterations, - bool has_initial_guess, - bool normalize, - bool do_expensive_check); - -} // namespace cugraph diff --git a/cpp/src/centrality/katz_centrality_sg_v32_e64.cu b/cpp/src/centrality/katz_centrality_sg_v32_e64.cu deleted file mode 100644 index 6d977c14825..00000000000 --- a/cpp/src/centrality/katz_centrality_sg_v32_e64.cu +++ /dev/null @@ -1,50 +0,0 @@ -/* - * Copyright (c) 2021-2024, NVIDIA CORPORATION. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * 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. - */ -#include "centrality/katz_centrality_impl.cuh" - -namespace cugraph { - -// SG instantiation - -template void katz_centrality( - raft::handle_t const& handle, - graph_view_t const& graph_view, - std::optional> edge_weight_view, - float const* betas, - float* katz_centralities, - float alpha, - float beta, - float epsilon, - size_t max_iterations, - bool has_initial_guess, - bool normalize, - bool do_expensive_check); - -template void katz_centrality( - raft::handle_t const& handle, - graph_view_t const& graph_view, - std::optional> edge_weight_view, - double const* betas, - double* katz_centralities, - double alpha, - double beta, - double epsilon, - size_t max_iterations, - bool has_initial_guess, - bool normalize, - bool do_expensive_check); - -} // namespace cugraph diff --git a/cpp/src/community/approx_weighted_matching_mg_v32_e64.cu b/cpp/src/community/approx_weighted_matching_mg_v32_e64.cu deleted file mode 100644 index 431634ab18a..00000000000 --- a/cpp/src/community/approx_weighted_matching_mg_v32_e64.cu +++ /dev/null @@ -1,30 +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. - */ -#include "approx_weighted_matching_impl.cuh" - -namespace cugraph { - -template std::tuple, float> approximate_weighted_matching( - raft::handle_t const& handle, - graph_view_t const& graph_view, - edge_property_view_t edge_weight_view); - -template std::tuple, double> approximate_weighted_matching( - raft::handle_t const& handle, - graph_view_t const& graph_view, - edge_property_view_t edge_weight_view); - -} // namespace cugraph diff --git a/cpp/src/community/approx_weighted_matching_sg_v32_e64.cu b/cpp/src/community/approx_weighted_matching_sg_v32_e64.cu deleted file mode 100644 index f9bab14c29f..00000000000 --- a/cpp/src/community/approx_weighted_matching_sg_v32_e64.cu +++ /dev/null @@ -1,30 +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. - */ -#include "approx_weighted_matching_impl.cuh" - -namespace cugraph { - -template std::tuple, float> approximate_weighted_matching( - raft::handle_t const& handle, - graph_view_t const& graph_view, - edge_property_view_t edge_weight_view); - -template std::tuple, double> approximate_weighted_matching( - raft::handle_t const& handle, - graph_view_t const& graph_view, - edge_property_view_t edge_weight_view); - -} // namespace cugraph diff --git a/cpp/src/community/detail/common_methods_mg_v32_e64.cu b/cpp/src/community/detail/common_methods_mg_v32_e64.cu deleted file mode 100644 index 3958683b4ad..00000000000 --- a/cpp/src/community/detail/common_methods_mg_v32_e64.cu +++ /dev/null @@ -1,118 +0,0 @@ -/* - * 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. - * 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. - */ -#include "community/detail/common_methods.cuh" - -namespace cugraph { -namespace detail { - -template float compute_modularity( - raft::handle_t const& handle, - cugraph::graph_view_t const& graph_view, - std::optional> edge_weight_view, - edge_src_property_t, int32_t> const& - src_clusters_cache, - edge_dst_property_t, int32_t> const& - dst_clusters_cache, - rmm::device_uvector const& next_clusters, - rmm::device_uvector const& cluster_weights, - float total_edge_weight, - float resolution); - -template double compute_modularity( - raft::handle_t const& handle, - cugraph::graph_view_t const& graph_view, - std::optional> edge_weight_view, - edge_src_property_t, int32_t> const& - src_clusters_cache, - edge_dst_property_t, int32_t> const& - dst_clusters_cache, - rmm::device_uvector const& next_clusters, - rmm::device_uvector const& cluster_weights, - double total_edge_weight, - double resolution); - -template std::tuple< - cugraph::graph_t, - std::optional, float>>> -graph_contraction(raft::handle_t const& handle, - cugraph::graph_view_t const& graph_view, - std::optional> edge_weights, - raft::device_span labels); - -template std::tuple< - cugraph::graph_t, - std::optional, double>>> -graph_contraction(raft::handle_t const& handle, - cugraph::graph_view_t const& graph_view, - std::optional> edge_weights, - raft::device_span labels); - -template rmm::device_uvector update_clustering_by_delta_modularity( - raft::handle_t const& handle, - cugraph::graph_view_t const& graph_view, - std::optional> edge_weight_view, - float total_edge_weight, - float resolution, - rmm::device_uvector const& vertex_weights_v, - rmm::device_uvector&& cluster_keys_v, - rmm::device_uvector&& cluster_weights_v, - rmm::device_uvector&& next_clusters_v, - edge_src_property_t, float> const& - src_vertex_weights_cache, - edge_src_property_t, int32_t> const& - src_clusters_cache, - edge_dst_property_t, int32_t> const& - dst_clusters_cache, - bool up_down); - -template rmm::device_uvector update_clustering_by_delta_modularity( - raft::handle_t const& handle, - cugraph::graph_view_t const& graph_view, - std::optional> edge_weight_view, - double total_edge_weight, - double resolution, - rmm::device_uvector const& vertex_weights_v, - rmm::device_uvector&& cluster_keys_v, - rmm::device_uvector&& cluster_weights_v, - rmm::device_uvector&& next_clusters_v, - edge_src_property_t, double> const& - src_vertex_weights_cache, - edge_src_property_t, int32_t> const& - src_clusters_cache, - edge_dst_property_t, int32_t> const& - dst_clusters_cache, - bool up_down); - -template std::tuple, rmm::device_uvector> -compute_cluster_keys_and_values( - raft::handle_t const& handle, - cugraph::graph_view_t const& graph_view, - std::optional> edge_weight_view, - rmm::device_uvector const& next_clusters_v, - edge_src_property_t, int32_t> const& - src_clusters_cache); - -template std::tuple, rmm::device_uvector> -compute_cluster_keys_and_values( - raft::handle_t const& handle, - cugraph::graph_view_t const& graph_view, - std::optional> edge_weight_view, - rmm::device_uvector const& next_clusters_v, - edge_src_property_t, int32_t> const& - src_clusters_cache); - -} // namespace detail -} // namespace cugraph diff --git a/cpp/src/community/detail/common_methods_sg_v32_e64.cu b/cpp/src/community/detail/common_methods_sg_v32_e64.cu deleted file mode 100644 index 7be4b179fa4..00000000000 --- a/cpp/src/community/detail/common_methods_sg_v32_e64.cu +++ /dev/null @@ -1,118 +0,0 @@ -/* - * 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. - * 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. - */ -#include "community/detail/common_methods.cuh" - -namespace cugraph { -namespace detail { - -template float compute_modularity( - raft::handle_t const& handle, - cugraph::graph_view_t const& graph_view, - std::optional> edge_weight_view, - edge_src_property_t, int32_t> const& - src_clusters_cache, - edge_dst_property_t, int32_t> const& - dst_clusters_cache, - rmm::device_uvector const& next_clusters, - rmm::device_uvector const& cluster_weights, - float total_edge_weight, - float resolution); - -template double compute_modularity( - raft::handle_t const& handle, - cugraph::graph_view_t const& graph_view, - std::optional> edge_weight_view, - edge_src_property_t, int32_t> const& - src_clusters_cache, - edge_dst_property_t, int32_t> const& - dst_clusters_cache, - rmm::device_uvector const& next_clusters, - rmm::device_uvector const& cluster_weights, - double total_edge_weight, - double resolution); - -template std::tuple< - cugraph::graph_t, - std::optional, float>>> -graph_contraction(raft::handle_t const& handle, - cugraph::graph_view_t const& graph_view, - std::optional> edge_weights, - raft::device_span labels); - -template std::tuple< - cugraph::graph_t, - std::optional, double>>> -graph_contraction(raft::handle_t const& handle, - cugraph::graph_view_t const& graph_view, - std::optional> edge_weights, - raft::device_span labels); - -template rmm::device_uvector update_clustering_by_delta_modularity( - raft::handle_t const& handle, - cugraph::graph_view_t const& graph_view, - std::optional> edge_weight_view, - float total_edge_weight, - float resolution, - rmm::device_uvector const& vertex_weights_v, - rmm::device_uvector&& cluster_keys_v, - rmm::device_uvector&& cluster_weights_v, - rmm::device_uvector&& next_clusters_v, - edge_src_property_t, float> const& - src_vertex_weights_cache, - edge_src_property_t, int32_t> const& - src_clusters_cache, - edge_dst_property_t, int32_t> const& - dst_clusters_cache, - bool up_down); - -template rmm::device_uvector update_clustering_by_delta_modularity( - raft::handle_t const& handle, - cugraph::graph_view_t const& graph_view, - std::optional> edge_weight_view, - double total_edge_weight, - double resolution, - rmm::device_uvector const& vertex_weights_v, - rmm::device_uvector&& cluster_keys_v, - rmm::device_uvector&& cluster_weights_v, - rmm::device_uvector&& next_clusters_v, - edge_src_property_t, double> const& - src_vertex_weights_cache, - edge_src_property_t, int32_t> const& - src_clusters_cache, - edge_dst_property_t, int32_t> const& - dst_clusters_cache, - bool up_down); - -template std::tuple, rmm::device_uvector> -compute_cluster_keys_and_values( - raft::handle_t const& handle, - cugraph::graph_view_t const& graph_view, - std::optional> edge_weight_view, - rmm::device_uvector const& next_clusters_v, - edge_src_property_t, int32_t> const& - src_clusters_cache); - -template std::tuple, rmm::device_uvector> -compute_cluster_keys_and_values( - raft::handle_t const& handle, - cugraph::graph_view_t const& graph_view, - std::optional> edge_weight_view, - rmm::device_uvector const& next_clusters_v, - edge_src_property_t, int32_t> const& - src_clusters_cache); - -} // namespace detail -} // namespace cugraph diff --git a/cpp/src/community/detail/maximal_independent_moves_mg_v32_e64.cu b/cpp/src/community/detail/maximal_independent_moves_mg_v32_e64.cu deleted file mode 100644 index 596f7fa0a11..00000000000 --- a/cpp/src/community/detail/maximal_independent_moves_mg_v32_e64.cu +++ /dev/null @@ -1,28 +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. - */ -#include "maximal_independent_moves.cuh" - -namespace cugraph { -namespace detail { - -template rmm::device_uvector maximal_independent_moves( - raft::handle_t const& handle, - graph_view_t const& decision_graph_view, - raft::random::RngState& rng_state); - -} // namespace detail - -} // namespace cugraph diff --git a/cpp/src/community/detail/maximal_independent_moves_sg_v32_e64.cu b/cpp/src/community/detail/maximal_independent_moves_sg_v32_e64.cu deleted file mode 100644 index 2ae195faf01..00000000000 --- a/cpp/src/community/detail/maximal_independent_moves_sg_v32_e64.cu +++ /dev/null @@ -1,27 +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. - */ -#include "maximal_independent_moves.cuh" - -namespace cugraph { -namespace detail { - -template rmm::device_uvector maximal_independent_moves( - raft::handle_t const& handle, - graph_view_t const& decision_graph_view, - raft::random::RngState& rng_state); - -} // namespace detail -} // namespace cugraph diff --git a/cpp/src/community/detail/refine_mg_v32_e64.cu b/cpp/src/community/detail/refine_mg_v32_e64.cu deleted file mode 100644 index 16c0fde2991..00000000000 --- a/cpp/src/community/detail/refine_mg_v32_e64.cu +++ /dev/null @@ -1,66 +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. - */ -#include "community/detail/refine_impl.cuh" - -namespace cugraph { -namespace detail { - -template std::tuple, - std::pair, rmm::device_uvector>> -refine_clustering( - raft::handle_t const& handle, - raft::random::RngState& rng_state, - cugraph::graph_view_t const& graph_view, - std::optional> edge_weight_view, - float total_edge_weight, - float resolution, - float theta, - rmm::device_uvector const& vertex_weights_v, - rmm::device_uvector&& cluster_keys_v, - rmm::device_uvector&& cluster_weights_v, - rmm::device_uvector&& next_clusters_v, - edge_src_property_t, float> const& - src_vertex_weights_cache, - edge_src_property_t, int32_t> const& - src_clusters_cache, - edge_dst_property_t, int32_t> const& - dst_clusters_cache, - bool up_down); - -template std::tuple, - std::pair, rmm::device_uvector>> -refine_clustering( - raft::handle_t const& handle, - raft::random::RngState& rng_state, - cugraph::graph_view_t const& graph_view, - std::optional> edge_weight_view, - double total_edge_weight, - double resolution, - double theta, - rmm::device_uvector const& vertex_weights_v, - rmm::device_uvector&& cluster_keys_v, - rmm::device_uvector&& cluster_weights_v, - rmm::device_uvector&& next_clusters_v, - edge_src_property_t, double> const& - src_vertex_weights_cache, - edge_src_property_t, int32_t> const& - src_clusters_cache, - edge_dst_property_t, int32_t> const& - dst_clusters_cache, - bool up_down); - -} // namespace detail -} // namespace cugraph diff --git a/cpp/src/community/detail/refine_sg_v32_e64.cu b/cpp/src/community/detail/refine_sg_v32_e64.cu deleted file mode 100644 index f011bb2ebe0..00000000000 --- a/cpp/src/community/detail/refine_sg_v32_e64.cu +++ /dev/null @@ -1,66 +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. - */ -#include "community/detail/refine_impl.cuh" - -namespace cugraph { -namespace detail { - -template std::tuple, - std::pair, rmm::device_uvector>> -refine_clustering( - raft::handle_t const& handle, - raft::random::RngState& rng_state, - cugraph::graph_view_t const& graph_view, - std::optional> edge_weight_view, - float total_edge_weight, - float resolution, - float theta, - rmm::device_uvector const& vertex_weights_v, - rmm::device_uvector&& cluster_keys_v, - rmm::device_uvector&& cluster_weights_v, - rmm::device_uvector&& next_clusters_v, - edge_src_property_t, float> const& - src_vertex_weights_cache, - edge_src_property_t, int32_t> const& - src_clusters_cache, - edge_dst_property_t, int32_t> const& - dst_clusters_cache, - bool up_down); - -template std::tuple, - std::pair, rmm::device_uvector>> -refine_clustering( - raft::handle_t const& handle, - raft::random::RngState& rng_state, - cugraph::graph_view_t const& graph_view, - std::optional> edge_weight_view, - double total_edge_weight, - double resolution, - double theta, - rmm::device_uvector const& vertex_weights_v, - rmm::device_uvector&& cluster_keys_v, - rmm::device_uvector&& cluster_weights_v, - rmm::device_uvector&& next_clusters_v, - edge_src_property_t, double> const& - src_vertex_weights_cache, - edge_src_property_t, int32_t> const& - src_clusters_cache, - edge_dst_property_t, int32_t> const& - dst_clusters_cache, - bool up_down); - -} // namespace detail -} // namespace cugraph diff --git a/cpp/src/community/ecg_mg_v32_e64.cu b/cpp/src/community/ecg_mg_v32_e64.cu deleted file mode 100644 index 6e9dde68dea..00000000000 --- a/cpp/src/community/ecg_mg_v32_e64.cu +++ /dev/null @@ -1,44 +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. - */ - -#include "community/ecg_impl.cuh" - -namespace cugraph { -template std::tuple, size_t, float> ecg( - raft::handle_t const& handle, - raft::random::RngState& rng_state, - graph_view_t const& graph_view, - std::optional> edge_weight_view, - - float min_weight, - size_t ensemble_size, - size_t max_level, - float threshold, - float resolution); - -template std::tuple, size_t, double> ecg( - raft::handle_t const& handle, - raft::random::RngState& rng_state, - graph_view_t const& graph_view, - std::optional> edge_weight_view, - - double min_weight, - size_t ensemble_size, - size_t max_level, - double threshold, - double resolution); - -} // namespace cugraph diff --git a/cpp/src/community/ecg_sg_v32_e64.cu b/cpp/src/community/ecg_sg_v32_e64.cu deleted file mode 100644 index 9fa1a2429f1..00000000000 --- a/cpp/src/community/ecg_sg_v32_e64.cu +++ /dev/null @@ -1,44 +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. - */ - -#include "community/ecg_impl.cuh" - -namespace cugraph { -template std::tuple, size_t, float> ecg( - raft::handle_t const& handle, - raft::random::RngState& rng_state, - graph_view_t const& graph_view, - std::optional> edge_weight_view, - - float min_weight, - size_t ensemble_size, - size_t max_level, - float threshold, - float resolution); - -template std::tuple, size_t, double> ecg( - raft::handle_t const& handle, - raft::random::RngState& rng_state, - graph_view_t const& graph_view, - std::optional> edge_weight_view, - - double min_weight, - size_t ensemble_size, - size_t max_level, - double threshold, - double resolution); - -} // namespace cugraph diff --git a/cpp/src/community/edge_triangle_count_mg_v32_e64.cu b/cpp/src/community/edge_triangle_count_mg_v32_e64.cu deleted file mode 100644 index adab2d1fede..00000000000 --- a/cpp/src/community/edge_triangle_count_mg_v32_e64.cu +++ /dev/null @@ -1,26 +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. - */ -#include "community/edge_triangle_count_impl.cuh" - -namespace cugraph { - -// SG instantiation -template edge_property_t, int64_t> edge_triangle_count( - raft::handle_t const& handle, - cugraph::graph_view_t const& graph_view, - bool do_expensive_check); - -} // namespace cugraph diff --git a/cpp/src/community/edge_triangle_count_sg_v32_e64.cu b/cpp/src/community/edge_triangle_count_sg_v32_e64.cu deleted file mode 100644 index 24a8de868e0..00000000000 --- a/cpp/src/community/edge_triangle_count_sg_v32_e64.cu +++ /dev/null @@ -1,26 +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. - */ -#include "community/edge_triangle_count_impl.cuh" - -namespace cugraph { - -// SG instantiation -template edge_property_t, int64_t> edge_triangle_count( - raft::handle_t const& handle, - cugraph::graph_view_t const& graph_view, - bool do_expensive_check); - -} // namespace cugraph diff --git a/cpp/src/community/egonet_mg_v32_e64.cu b/cpp/src/community/egonet_mg_v32_e64.cu deleted file mode 100644 index f9e27b6cf26..00000000000 --- a/cpp/src/community/egonet_mg_v32_e64.cu +++ /dev/null @@ -1,66 +0,0 @@ -/* - * Copyright (c) 2021-2024, NVIDIA CORPORATION. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * 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. - */ -#include "community/egonet_impl.cuh" - -namespace cugraph { - -// MG FP32 - -template std::tuple, - rmm::device_uvector, - std::optional>, - rmm::device_uvector> - -extract_ego(raft::handle_t const&, - graph_view_t const&, - std::optional>, - int32_t*, - int32_t, - int32_t); -template std::tuple, - rmm::device_uvector, - std::optional>, - rmm::device_uvector> -extract_ego(raft::handle_t const& handle, - graph_view_t const& graph_view, - std::optional>, - raft::device_span source_vertex, - int32_t radius, - bool do_expensive_check); - -template std::tuple, - rmm::device_uvector, - std::optional>, - rmm::device_uvector> -extract_ego(raft::handle_t const&, - graph_view_t const&, - std::optional>, - int32_t*, - int32_t, - int32_t); - -template std::tuple, - rmm::device_uvector, - std::optional>, - rmm::device_uvector> -extract_ego(raft::handle_t const& handle, - graph_view_t const& graph_view, - std::optional>, - raft::device_span source_vertex, - int32_t radius, - bool do_expensive_check); - -} // namespace cugraph diff --git a/cpp/src/community/egonet_sg_v32_e64.cu b/cpp/src/community/egonet_sg_v32_e64.cu deleted file mode 100644 index 4bb79120445..00000000000 --- a/cpp/src/community/egonet_sg_v32_e64.cu +++ /dev/null @@ -1,66 +0,0 @@ -/* - * Copyright (c) 2021-2024, NVIDIA CORPORATION. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * 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. - */ -#include "community/egonet_impl.cuh" - -namespace cugraph { - -// SG FP32 - -template std::tuple, - rmm::device_uvector, - std::optional>, - rmm::device_uvector> -extract_ego(raft::handle_t const& handle, - graph_view_t const& graph_view, - std::optional>, - int32_t* source_vertex, - int32_t n_subgraphs, - int32_t radius); - -template std::tuple, - rmm::device_uvector, - std::optional>, - rmm::device_uvector> -extract_ego(raft::handle_t const& handle, - graph_view_t const& graph_view, - std::optional>, - raft::device_span source_vertex, - int32_t radius, - bool do_expensive_check); - -template std::tuple, - rmm::device_uvector, - std::optional>, - rmm::device_uvector> -extract_ego(raft::handle_t const& handle, - graph_view_t const& graph_view, - std::optional>, - int32_t* source_vertex, - int32_t n_subgraphs, - int32_t radius); - -template std::tuple, - rmm::device_uvector, - std::optional>, - rmm::device_uvector> -extract_ego(raft::handle_t const& handle, - graph_view_t const& graph_view, - std::optional>, - raft::device_span source_vertex, - int32_t radius, - bool do_expensive_check); - -} // namespace cugraph diff --git a/cpp/src/community/k_truss_mg_v32_e64.cu b/cpp/src/community/k_truss_mg_v32_e64.cu deleted file mode 100644 index b07f9382612..00000000000 --- a/cpp/src/community/k_truss_mg_v32_e64.cu +++ /dev/null @@ -1,41 +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. - */ - -#include "community/k_truss_impl.cuh" - -namespace cugraph { - -// MG instantiation - -template std::tuple, - rmm::device_uvector, - std::optional>> -k_truss(raft::handle_t const& handle, - graph_view_t const& graph_view, - std::optional> edge_weight_view, - int64_t k, - bool do_expensive_check); - -template std::tuple, - rmm::device_uvector, - std::optional>> -k_truss(raft::handle_t const& handle, - graph_view_t const& graph_view, - std::optional> edge_weight_view, - int64_t k, - bool do_expensive_check); - -} // namespace cugraph diff --git a/cpp/src/community/k_truss_sg_v32_e64.cu b/cpp/src/community/k_truss_sg_v32_e64.cu deleted file mode 100644 index 87a86d3f95d..00000000000 --- a/cpp/src/community/k_truss_sg_v32_e64.cu +++ /dev/null @@ -1,41 +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. - */ - -#include "community/k_truss_impl.cuh" - -namespace cugraph { - -// SG instantiation - -template std::tuple, - rmm::device_uvector, - std::optional>> -k_truss(raft::handle_t const& handle, - graph_view_t const& graph_view, - std::optional> edge_weight_view, - int64_t k, - bool do_expensive_check); - -template std::tuple, - rmm::device_uvector, - std::optional>> -k_truss(raft::handle_t const& handle, - graph_view_t const& graph_view, - std::optional> edge_weight_view, - int64_t k, - bool do_expensive_check); - -} // namespace cugraph diff --git a/cpp/src/community/leiden_mg_v32_e64.cu b/cpp/src/community/leiden_mg_v32_e64.cu deleted file mode 100644 index bce08617feb..00000000000 --- a/cpp/src/community/leiden_mg_v32_e64.cu +++ /dev/null @@ -1,58 +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. - */ - -#include "community/leiden_impl.cuh" - -namespace cugraph { - -// SG instantiation - -template std::pair>, float> leiden( - raft::handle_t const& handle, - raft::random::RngState& rng_state, - graph_view_t const& graph_view, - std::optional> edge_weight_view, - size_t max_level, - float resolution, - float theta); - -template std::pair>, double> leiden( - raft::handle_t const& handle, - raft::random::RngState& rng_state, - graph_view_t const& graph_view, - std::optional> edge_weight_view, - size_t max_level, - double resolution, - double theta); - -template std::pair leiden(raft::handle_t const&, - raft::random::RngState&, - graph_view_t const&, - std::optional>, - int32_t*, - size_t, - float, - float); -template std::pair leiden( - raft::handle_t const&, - raft::random::RngState&, - graph_view_t const&, - std::optional>, - int32_t*, - size_t, - double, - double); -} // namespace cugraph diff --git a/cpp/src/community/leiden_sg_v32_e64.cu b/cpp/src/community/leiden_sg_v32_e64.cu deleted file mode 100644 index 518b2c0b0e0..00000000000 --- a/cpp/src/community/leiden_sg_v32_e64.cu +++ /dev/null @@ -1,58 +0,0 @@ -/* - * 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. - * 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. - */ - -#include "community/leiden_impl.cuh" - -namespace cugraph { - -// SG instantiation - -template std::pair>, float> leiden( - raft::handle_t const& handle, - raft::random::RngState& rng_state, - graph_view_t const& graph_view, - std::optional> edge_weight_view, - size_t max_level, - float resolution, - float theta); - -template std::pair>, double> leiden( - raft::handle_t const& handle, - raft::random::RngState& rng_state, - graph_view_t const& graph_view, - std::optional> edge_weight_view, - size_t max_level, - double resolution, - double theta); - -template std::pair leiden(raft::handle_t const&, - raft::random::RngState&, - graph_view_t const&, - std::optional>, - int32_t*, - size_t, - float, - float); -template std::pair leiden( - raft::handle_t const&, - raft::random::RngState&, - graph_view_t const&, - std::optional>, - int32_t*, - size_t, - double, - double); -} // namespace cugraph diff --git a/cpp/src/community/louvain_mg_v32_e64.cu b/cpp/src/community/louvain_mg_v32_e64.cu deleted file mode 100644 index f25102af2a2..00000000000 --- a/cpp/src/community/louvain_mg_v32_e64.cu +++ /dev/null @@ -1,57 +0,0 @@ -/* - * Copyright (c) 2020-2024, NVIDIA CORPORATION. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * 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. - */ - -#include "community/louvain_impl.cuh" - -namespace cugraph { - -// Explicit template instantations - -template std::pair>, float> louvain( - raft::handle_t const&, - std::optional>, - graph_view_t const&, - std::optional>, - size_t, - float, - float); -template std::pair>, double> louvain( - raft::handle_t const&, - std::optional>, - graph_view_t const&, - std::optional>, - size_t, - double, - double); -template std::pair louvain( - raft::handle_t const&, - std::optional>, - graph_view_t const&, - std::optional>, - int32_t*, - size_t, - float, - float); -template std::pair louvain( - raft::handle_t const&, - std::optional>, - graph_view_t const&, - std::optional>, - int32_t*, - size_t, - double, - double); -} // namespace cugraph diff --git a/cpp/src/community/louvain_sg_v32_e64.cu b/cpp/src/community/louvain_sg_v32_e64.cu deleted file mode 100644 index fc972bdee61..00000000000 --- a/cpp/src/community/louvain_sg_v32_e64.cu +++ /dev/null @@ -1,57 +0,0 @@ -/* - * Copyright (c) 2020-2024, NVIDIA CORPORATION. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * 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. - */ - -#include "community/louvain_impl.cuh" - -namespace cugraph { - -// Explicit template instantations - -template std::pair>, float> louvain( - raft::handle_t const&, - std::optional>, - graph_view_t const&, - std::optional>, - size_t, - float, - float); -template std::pair>, double> louvain( - raft::handle_t const&, - std::optional>, - graph_view_t const&, - std::optional>, - size_t, - double, - double); -template std::pair louvain( - raft::handle_t const&, - std::optional>, - graph_view_t const&, - std::optional>, - int32_t*, - size_t, - float, - float); -template std::pair louvain( - raft::handle_t const&, - std::optional>, - graph_view_t const&, - std::optional>, - int32_t*, - size_t, - double, - double); -} // namespace cugraph diff --git a/cpp/src/community/triangle_count_mg_v32_e64.cu b/cpp/src/community/triangle_count_mg_v32_e64.cu deleted file mode 100644 index 50ccc074f63..00000000000 --- a/cpp/src/community/triangle_count_mg_v32_e64.cu +++ /dev/null @@ -1,27 +0,0 @@ -/* - * 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. - * 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. - */ - -#include "community/triangle_count_impl.cuh" - -namespace cugraph { - -template void triangle_count(raft::handle_t const& handle, - graph_view_t const& graph_view, - std::optional> vertices, - raft::device_span counts, - bool do_expensive_check); - -} // namespace cugraph diff --git a/cpp/src/community/triangle_count_sg_v32_e64.cu b/cpp/src/community/triangle_count_sg_v32_e64.cu deleted file mode 100644 index 6f7c3a87298..00000000000 --- a/cpp/src/community/triangle_count_sg_v32_e64.cu +++ /dev/null @@ -1,27 +0,0 @@ -/* - * 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. - * 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. - */ - -#include "community/triangle_count_impl.cuh" - -namespace cugraph { - -template void triangle_count(raft::handle_t const& handle, - graph_view_t const& graph_view, - std::optional> vertices, - raft::device_span counts, - bool do_expensive_check); - -} // namespace cugraph diff --git a/cpp/src/components/mis_mg_v32_e64.cu b/cpp/src/components/mis_mg_v32_e64.cu deleted file mode 100644 index 793d170b433..00000000000 --- a/cpp/src/components/mis_mg_v32_e64.cu +++ /dev/null @@ -1,24 +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. - */ -#include "mis_impl.cuh" -namespace cugraph { - -template rmm::device_uvector maximal_independent_set( - raft::handle_t const& handle, - graph_view_t const& graph_view, - raft::random::RngState& rng_state); - -} // namespace cugraph diff --git a/cpp/src/components/mis_sg_v32_e64.cu b/cpp/src/components/mis_sg_v32_e64.cu deleted file mode 100644 index a3a29cb751b..00000000000 --- a/cpp/src/components/mis_sg_v32_e64.cu +++ /dev/null @@ -1,25 +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. - */ -#include "mis_impl.cuh" - -namespace cugraph { - -template rmm::device_uvector maximal_independent_set( - raft::handle_t const& handle, - graph_view_t const& graph_view, - raft::random::RngState& rng_state); - -} // namespace cugraph diff --git a/cpp/src/components/vertex_coloring_mg_v32_e64.cu b/cpp/src/components/vertex_coloring_mg_v32_e64.cu deleted file mode 100644 index 04facb7cda8..00000000000 --- a/cpp/src/components/vertex_coloring_mg_v32_e64.cu +++ /dev/null @@ -1,25 +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. - */ -#include "vertex_coloring_impl.cuh" - -namespace cugraph { - -template rmm::device_uvector vertex_coloring( - raft::handle_t const& handle, - graph_view_t const& graph_view, - raft::random::RngState& rng_state); - -} // namespace cugraph diff --git a/cpp/src/components/vertex_coloring_sg_v32_e64.cu b/cpp/src/components/vertex_coloring_sg_v32_e64.cu deleted file mode 100644 index bf510a1f571..00000000000 --- a/cpp/src/components/vertex_coloring_sg_v32_e64.cu +++ /dev/null @@ -1,25 +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. - */ -#include "vertex_coloring_impl.cuh" - -namespace cugraph { - -template rmm::device_uvector vertex_coloring( - raft::handle_t const& handle, - graph_view_t const& graph_view, - raft::random::RngState& rng_state); - -} // namespace cugraph diff --git a/cpp/src/components/weakly_connected_components_mg_v32_e64.cu b/cpp/src/components/weakly_connected_components_mg_v32_e64.cu deleted file mode 100644 index edbc8cc5eb5..00000000000 --- a/cpp/src/components/weakly_connected_components_mg_v32_e64.cu +++ /dev/null @@ -1,29 +0,0 @@ -/* - * Copyright (c) 2021-2024, NVIDIA CORPORATION. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * 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. - */ - -#include "components/weakly_connected_components_impl.cuh" - -namespace cugraph { - -// MG instantiations - -template void weakly_connected_components( - raft::handle_t const& handle, - graph_view_t const& graph_view, - int32_t* components, - bool do_expensive_check); - -} // namespace cugraph diff --git a/cpp/src/components/weakly_connected_components_sg_v32_e64.cu b/cpp/src/components/weakly_connected_components_sg_v32_e64.cu deleted file mode 100644 index 813d2711674..00000000000 --- a/cpp/src/components/weakly_connected_components_sg_v32_e64.cu +++ /dev/null @@ -1,29 +0,0 @@ -/* - * Copyright (c) 2021-2024, NVIDIA CORPORATION. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * 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. - */ - -#include "components/weakly_connected_components_impl.cuh" - -namespace cugraph { - -// SG instantiations - -template void weakly_connected_components( - raft::handle_t const& handle, - graph_view_t const& graph_view, - int32_t* components, - bool do_expensive_check); - -} // namespace cugraph diff --git a/cpp/src/cores/core_number_mg_v32_e64.cu b/cpp/src/cores/core_number_mg_v32_e64.cu deleted file mode 100644 index f41f9cd8a17..00000000000 --- a/cpp/src/cores/core_number_mg_v32_e64.cu +++ /dev/null @@ -1,31 +0,0 @@ -/* - * Copyright (c) 2021-2024, NVIDIA CORPORATION. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * 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. - */ - -#include "cores/core_number_impl.cuh" - -namespace cugraph { - -// MG instantiation - -template void core_number(raft::handle_t const& handle, - graph_view_t const& graph_view, - int64_t* core_numbers, - k_core_degree_type_t degree_type, - size_t k_first, - size_t k_last, - bool do_expensive_check); - -} // namespace cugraph diff --git a/cpp/src/cores/core_number_sg_v32_e64.cu b/cpp/src/cores/core_number_sg_v32_e64.cu deleted file mode 100644 index 63a6d0069a3..00000000000 --- a/cpp/src/cores/core_number_sg_v32_e64.cu +++ /dev/null @@ -1,31 +0,0 @@ -/* - * Copyright (c) 2021-2024, NVIDIA CORPORATION. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * 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. - */ - -#include "cores/core_number_impl.cuh" - -namespace cugraph { - -// MG instantiation - -template void core_number(raft::handle_t const& handle, - graph_view_t const& graph_view, - int64_t* core_numbers, - k_core_degree_type_t degree_type, - size_t k_first, - size_t k_last, - bool do_expensive_check); - -} // namespace cugraph diff --git a/cpp/src/cores/k_core_mg_v32_e64.cu b/cpp/src/cores/k_core_mg_v32_e64.cu deleted file mode 100644 index b2329997cb6..00000000000 --- a/cpp/src/cores/k_core_mg_v32_e64.cu +++ /dev/null @@ -1,45 +0,0 @@ -/* - * 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. - * 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. - */ - -#include "cores/k_core_impl.cuh" - -namespace cugraph { - -// MG instantiation - -template std::tuple, - rmm::device_uvector, - std::optional>> -k_core(raft::handle_t const& handle, - graph_view_t const& graph_view, - std::optional> edge_weight_view, - size_t k, - std::optional degree_type, - std::optional> core_numbers, - bool do_expensive_check); - -template std::tuple, - rmm::device_uvector, - std::optional>> -k_core(raft::handle_t const& handle, - graph_view_t const& graph_view, - std::optional> edge_weight_view, - size_t k, - std::optional degree_type, - std::optional> core_numbers, - bool do_expensive_check); - -} // namespace cugraph diff --git a/cpp/src/cores/k_core_sg_v32_e64.cu b/cpp/src/cores/k_core_sg_v32_e64.cu deleted file mode 100644 index 642f6673168..00000000000 --- a/cpp/src/cores/k_core_sg_v32_e64.cu +++ /dev/null @@ -1,45 +0,0 @@ -/* - * 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. - * 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. - */ - -#include "cores/k_core_impl.cuh" - -namespace cugraph { - -// SG instantiation - -template std::tuple, - rmm::device_uvector, - std::optional>> -k_core(raft::handle_t const& handle, - graph_view_t const& graph_view, - std::optional> edge_weight_view, - size_t k, - std::optional degree_type, - std::optional> core_numbers, - bool do_expensive_check); - -template std::tuple, - rmm::device_uvector, - std::optional>> -k_core(raft::handle_t const& handle, - graph_view_t const& graph_view, - std::optional> edge_weight_view, - size_t k, - std::optional degree_type, - std::optional> core_numbers, - bool do_expensive_check); - -} // namespace cugraph diff --git a/cpp/src/detail/collect_local_vertex_values_mg_v32_e32.cu b/cpp/src/detail/collect_local_vertex_values_mg_v32_e32.cu index 3b6059a0ce8..c0c186e867e 100644 --- a/cpp/src/detail/collect_local_vertex_values_mg_v32_e32.cu +++ b/cpp/src/detail/collect_local_vertex_values_mg_v32_e32.cu @@ -15,7 +15,6 @@ */ #include "detail/collect_local_vertex_values.cuh" -#include "detail/graph_partition_utils.cuh" #include #include @@ -47,5 +46,16 @@ collect_local_vertex_values_from_ext_vertex_value_pairs( int32_t default_value, bool do_expensive_check); +template rmm::device_uvector +collect_local_vertex_values_from_ext_vertex_value_pairs( + raft::handle_t const& handle, + rmm::device_uvector&& d_vertices, + rmm::device_uvector&& d_values, + rmm::device_uvector const& number_map, + int32_t local_vertex_first, + int32_t local_vertex_last, + double default_value, + bool do_expensive_check); + } // namespace detail } // namespace cugraph diff --git a/cpp/src/detail/collect_local_vertex_values_mg_v32_e64.cu b/cpp/src/detail/collect_local_vertex_values_mg_v32_e64.cu deleted file mode 100644 index e33b6fe7a68..00000000000 --- a/cpp/src/detail/collect_local_vertex_values_mg_v32_e64.cu +++ /dev/null @@ -1,51 +0,0 @@ -/* - * Copyright (c) 2021-2024, NVIDIA CORPORATION. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * 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. - */ - -#include "detail/collect_local_vertex_values.cuh" -#include "detail/graph_partition_utils.cuh" - -#include -#include - -#include - -namespace cugraph { -namespace detail { - -template rmm::device_uvector -collect_local_vertex_values_from_ext_vertex_value_pairs( - raft::handle_t const& handle, - rmm::device_uvector&& d_vertices, - rmm::device_uvector&& d_values, - rmm::device_uvector const& number_map, - int32_t local_vertex_first, - int32_t local_vertex_last, - double default_value, - bool do_expensive_check); - -template rmm::device_uvector -collect_local_vertex_values_from_ext_vertex_value_pairs( - raft::handle_t const& handle, - rmm::device_uvector&& d_vertices, - rmm::device_uvector&& d_values, - rmm::device_uvector const& number_map, - int32_t local_vertex_first, - int32_t local_vertex_last, - int64_t default_value, - bool do_expensive_check); - -} // namespace detail -} // namespace cugraph diff --git a/cpp/src/detail/collect_local_vertex_values_sg_v32_e32.cu b/cpp/src/detail/collect_local_vertex_values_sg_v32_e32.cu index c544d009aef..ac4c612b74a 100644 --- a/cpp/src/detail/collect_local_vertex_values_sg_v32_e32.cu +++ b/cpp/src/detail/collect_local_vertex_values_sg_v32_e32.cu @@ -15,7 +15,6 @@ */ #include "detail/collect_local_vertex_values.cuh" -#include "detail/graph_partition_utils.cuh" #include #include @@ -47,5 +46,16 @@ collect_local_vertex_values_from_ext_vertex_value_pairs int32_t default_value, bool do_expensive_check); +template rmm::device_uvector +collect_local_vertex_values_from_ext_vertex_value_pairs( + raft::handle_t const& handle, + rmm::device_uvector&& d_vertices, + rmm::device_uvector&& d_values, + rmm::device_uvector const& number_map, + int32_t local_vertex_first, + int32_t local_vertex_last, + double default_value, + bool do_expensive_check); + } // namespace detail } // namespace cugraph diff --git a/cpp/src/detail/collect_local_vertex_values_sg_v32_e64.cu b/cpp/src/detail/collect_local_vertex_values_sg_v32_e64.cu deleted file mode 100644 index 99817a70e61..00000000000 --- a/cpp/src/detail/collect_local_vertex_values_sg_v32_e64.cu +++ /dev/null @@ -1,51 +0,0 @@ -/* - * Copyright (c) 2021-2024, NVIDIA CORPORATION. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * 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. - */ - -#include "detail/collect_local_vertex_values.cuh" -#include "detail/graph_partition_utils.cuh" - -#include -#include - -#include - -namespace cugraph { -namespace detail { - -template rmm::device_uvector -collect_local_vertex_values_from_ext_vertex_value_pairs( - raft::handle_t const& handle, - rmm::device_uvector&& d_vertices, - rmm::device_uvector&& d_values, - rmm::device_uvector const& number_map, - int32_t local_vertex_first, - int32_t local_vertex_last, - double default_value, - bool do_expensive_check); - -template rmm::device_uvector -collect_local_vertex_values_from_ext_vertex_value_pairs( - raft::handle_t const& handle, - rmm::device_uvector&& d_vertices, - rmm::device_uvector&& d_values, - rmm::device_uvector const& number_map, - int32_t local_vertex_first, - int32_t local_vertex_last, - int64_t default_value, - bool do_expensive_check); - -} // namespace detail -} // namespace cugraph diff --git a/cpp/src/detail/graph_partition_utils.cuh b/cpp/src/detail/graph_partition_utils.cuh index 00931780266..b10d2e788f4 100644 --- a/cpp/src/detail/graph_partition_utils.cuh +++ b/cpp/src/detail/graph_partition_utils.cuh @@ -43,7 +43,7 @@ struct compute_gpu_id_from_ext_vertex_t { __host__ __device__ int operator()(vertex_t v) const { - cuco::detail::MurmurHash3_32 hash_func{}; + cuco::murmurhash3_32 hash_func{}; auto vertex_partition_id = static_cast(hash_func(v) % comm_size); return partition_manager::compute_global_comm_rank_from_vertex_partition_id( major_comm_size, minor_comm_size, vertex_partition_id); @@ -58,7 +58,7 @@ struct compute_gpu_id_from_ext_edge_id_t { __host__ __device__ int operator()(edge_t e) const { - cuco::detail::MurmurHash3_32 hash_func{}; + cuco::murmurhash3_32 hash_func{}; auto vertex_partition_id = static_cast(hash_func(e) % comm_size); return partition_manager::compute_global_comm_rank_from_vertex_partition_id( major_comm_size, minor_comm_size, vertex_partition_id); @@ -88,7 +88,7 @@ struct compute_vertex_partition_id_from_ext_vertex_t { __host__ __device__ int operator()(vertex_t v) const { - cuco::detail::MurmurHash3_32 hash_func{}; + cuco::murmurhash3_32 hash_func{}; return hash_func(v) % comm_size; } }; @@ -114,7 +114,7 @@ struct compute_gpu_id_from_ext_edge_endpoints_t { __host__ __device__ int operator()(vertex_t major, vertex_t minor) const { - cuco::detail::MurmurHash3_32 hash_func{}; + cuco::murmurhash3_32 hash_func{}; auto major_vertex_partition_id = static_cast(hash_func(major) % comm_size); auto minor_vertex_partition_id = static_cast(hash_func(minor) % comm_size); auto major_comm_rank = major_vertex_partition_id % major_comm_size; @@ -126,7 +126,7 @@ struct compute_gpu_id_from_ext_edge_endpoints_t { __host__ __device__ int operator()( thrust::tuple pair /* major, minor */) const { - cuco::detail::MurmurHash3_32 hash_func{}; + cuco::murmurhash3_32 hash_func{}; auto major_vertex_partition_id = static_cast(hash_func(thrust::get<0>(pair)) % comm_size); auto minor_vertex_partition_id = static_cast(hash_func(thrust::get<1>(pair)) % comm_size); auto major_comm_rank = major_vertex_partition_id % major_comm_size; @@ -192,7 +192,7 @@ struct compute_edge_partition_id_from_ext_edge_endpoints_t { __host__ __device__ int operator()(vertex_t major, vertex_t minor) const { - cuco::detail::MurmurHash3_32 hash_func{}; + cuco::murmurhash3_32 hash_func{}; return (hash_func(major) % comm_size) * minor_comm_size + (hash_func(minor) % comm_size) / major_comm_size; } @@ -200,7 +200,7 @@ struct compute_edge_partition_id_from_ext_edge_endpoints_t { __host__ __device__ int operator()( thrust::tuple pair /* major, minor */) const { - cuco::detail::MurmurHash3_32 hash_func{}; + cuco::murmurhash3_32 hash_func{}; return (hash_func(thrust::get<0>(pair)) % comm_size) * minor_comm_size + (hash_func(thrust::get<1>(pair)) % comm_size) / major_comm_size; } diff --git a/cpp/src/detail/groupby_and_count_mg_v32_e64.cu b/cpp/src/detail/groupby_and_count_mg_v32_e64.cu deleted file mode 100644 index ec9cbc89aa2..00000000000 --- a/cpp/src/detail/groupby_and_count_mg_v32_e64.cu +++ /dev/null @@ -1,56 +0,0 @@ -/* - * Copyright (c) 2021-2024, NVIDIA CORPORATION. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * 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. - */ -#include "detail/graph_partition_utils.cuh" -#include "detail/groupby_and_count.cuh" - -#include -#include -#include -#include -#include - -#include - -#include -#include -#include -#include -#include - -#include - -namespace cugraph { -namespace detail { -template rmm::device_uvector groupby_and_count_edgelist_by_local_partition_id( - raft::handle_t const& handle, - rmm::device_uvector& d_edgelist_majors, - rmm::device_uvector& d_edgelist_minors, - std::optional>& d_edgelist_weights, - std::optional>& d_edgelist_edge_ids, - std::optional>& d_edgelist_edge_types, - bool groupby_and_counts_local_partition); - -template rmm::device_uvector groupby_and_count_edgelist_by_local_partition_id( - raft::handle_t const& handle, - rmm::device_uvector& d_edgelist_majors, - rmm::device_uvector& d_edgelist_minors, - std::optional>& d_edgelist_weights, - std::optional>& d_edgelist_edge_ids, - std::optional>& d_edgelist_edge_types, - bool groupby_and_counts_local_partition); - -} // namespace detail -} // namespace cugraph diff --git a/cpp/src/link_analysis/hits_mg_v32_e64.cu b/cpp/src/link_analysis/hits_mg_v32_e64.cu deleted file mode 100644 index a0a99f61822..00000000000 --- a/cpp/src/link_analysis/hits_mg_v32_e64.cu +++ /dev/null @@ -1,44 +0,0 @@ -/* - * Copyright (c) 2021-2024, NVIDIA CORPORATION. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * 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. - */ - -#include "link_analysis/hits_impl.cuh" - -namespace cugraph { - -// MG instantiation -template std::tuple hits( - raft::handle_t const& handle, - graph_view_t const& graph_view, - float* const hubs, - float* const authorities, - float epsilon, - size_t max_iterations, - bool has_initial_hubs_guess, - bool normalize, - bool do_expensive_check); - -template std::tuple hits( - raft::handle_t const& handle, - graph_view_t const& graph_view, - double* const hubs, - double* const authorities, - double epsilon, - size_t max_iterations, - bool has_initial_hubs_guess, - bool normalize, - bool do_expensive_check); - -} // namespace cugraph diff --git a/cpp/src/link_analysis/hits_sg_v32_e64.cu b/cpp/src/link_analysis/hits_sg_v32_e64.cu deleted file mode 100644 index 10eb4579f15..00000000000 --- a/cpp/src/link_analysis/hits_sg_v32_e64.cu +++ /dev/null @@ -1,44 +0,0 @@ -/* - * Copyright (c) 2021-2024, NVIDIA CORPORATION. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * 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. - */ - -#include "link_analysis/hits_impl.cuh" - -namespace cugraph { - -// SG instantiation -template std::tuple hits( - raft::handle_t const& handle, - graph_view_t const& graph_view, - float* const hubs, - float* const authorities, - float epsilon, - size_t max_iterations, - bool has_initial_hubs_guess, - bool normalize, - bool do_expensive_check); - -template std::tuple hits( - raft::handle_t const& handle, - graph_view_t const& graph_view, - double* const hubs, - double* const authorities, - double epsilon, - size_t max_iterations, - bool has_initial_hubs_guess, - bool normalize, - bool do_expensive_check); - -} // namespace cugraph diff --git a/cpp/src/link_analysis/pagerank_mg_v32_e64.cu b/cpp/src/link_analysis/pagerank_mg_v32_e64.cu deleted file mode 100644 index c3a3b1b6f52..00000000000 --- a/cpp/src/link_analysis/pagerank_mg_v32_e64.cu +++ /dev/null @@ -1,75 +0,0 @@ -/* - * Copyright (c) 2021-2024, NVIDIA CORPORATION. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * 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. - */ -#include "link_analysis/pagerank_impl.cuh" - -namespace cugraph { - -// MG instantiation -template void pagerank(raft::handle_t const& handle, - graph_view_t const& graph_view, - std::optional> edge_weight_view, - std::optional precomputed_vertex_out_weight_sums, - std::optional personalization_vertices, - std::optional personalization_values, - std::optional personalization_vector_size, - float* pageranks, - float alpha, - float epsilon, - size_t max_iterations, - bool has_initial_guess, - bool do_expensive_check); - -template void pagerank(raft::handle_t const& handle, - graph_view_t const& graph_view, - std::optional> edge_weight_view, - std::optional precomputed_vertex_out_weight_sums, - std::optional personalization_vertices, - std::optional personalization_values, - std::optional personalization_vector_size, - double* pageranks, - double alpha, - double epsilon, - size_t max_iterations, - bool has_initial_guess, - bool do_expensive_check); - -template std::tuple, centrality_algorithm_metadata_t> pagerank( - raft::handle_t const& handle, - graph_view_t const& graph_view, - std::optional> edge_weight_view, - std::optional> precomputed_vertex_out_weight_sums, - std::optional, raft::device_span>> - personalization, - std::optional> initial_pageranks, - float alpha, - float epsilon, - size_t max_iterations, - bool do_expensive_check); - -template std::tuple, centrality_algorithm_metadata_t> pagerank( - raft::handle_t const& handle, - graph_view_t const& graph_view, - std::optional> edge_weight_view, - std::optional> precomputed_vertex_out_weight_sums, - std::optional, raft::device_span>> - personalization, - std::optional> initial_pageranks, - double alpha, - double epsilon, - size_t max_iterations, - bool do_expensive_check); - -} // namespace cugraph diff --git a/cpp/src/link_analysis/pagerank_sg_v32_e64.cu b/cpp/src/link_analysis/pagerank_sg_v32_e64.cu deleted file mode 100644 index 0e515a55024..00000000000 --- a/cpp/src/link_analysis/pagerank_sg_v32_e64.cu +++ /dev/null @@ -1,75 +0,0 @@ -/* - * Copyright (c) 2021-2024, NVIDIA CORPORATION. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * 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. - */ -#include "link_analysis/pagerank_impl.cuh" - -namespace cugraph { - -// SG instantiation -template void pagerank(raft::handle_t const& handle, - graph_view_t const& graph_view, - std::optional> edge_weight_view, - std::optional precomputed_vertex_out_weight_sums, - std::optional personalization_vertices, - std::optional personalization_values, - std::optional personalization_vector_size, - float* pageranks, - float alpha, - float epsilon, - size_t max_iterations, - bool has_initial_guess, - bool do_expensive_check); - -template void pagerank(raft::handle_t const& handle, - graph_view_t const& graph_view, - std::optional> edge_weight_view, - std::optional precomputed_vertex_out_weight_sums, - std::optional personalization_vertices, - std::optional personalization_values, - std::optional personalization_vector_size, - double* pageranks, - double alpha, - double epsilon, - size_t max_iterations, - bool has_initial_guess, - bool do_expensive_check); - -template std::tuple, centrality_algorithm_metadata_t> pagerank( - raft::handle_t const& handle, - graph_view_t const& graph_view, - std::optional> edge_weight_view, - std::optional> precomputed_vertex_out_weight_sums, - std::optional, raft::device_span>> - personalization, - std::optional> initial_pageranks, - float alpha, - float epsilon, - size_t max_iterations, - bool do_expensive_check); - -template std::tuple, centrality_algorithm_metadata_t> pagerank( - raft::handle_t const& handle, - graph_view_t const& graph_view, - std::optional> edge_weight_view, - std::optional> precomputed_vertex_out_weight_sums, - std::optional, raft::device_span>> - personalization, - std::optional> initial_pageranks, - double alpha, - double epsilon, - size_t max_iterations, - bool do_expensive_check); - -} // namespace cugraph diff --git a/cpp/src/link_prediction/cosine_mg_v32_e64.cu b/cpp/src/link_prediction/cosine_mg_v32_e64.cu deleted file mode 100644 index c6efa6b8c30..00000000000 --- a/cpp/src/link_prediction/cosine_mg_v32_e64.cu +++ /dev/null @@ -1,54 +0,0 @@ -/* - * 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. - * 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. - */ -#include "link_prediction/cosine_similarity_impl.cuh" - -namespace cugraph { - -template rmm::device_uvector cosine_similarity_coefficients( - raft::handle_t const& handle, - graph_view_t const& graph_view, - std::optional> edge_weight_view, - std::tuple, raft::device_span> vertex_pairs, - bool do_expensive_check); - -template rmm::device_uvector cosine_similarity_coefficients( - raft::handle_t const& handle, - graph_view_t const& graph_view, - std::optional> edge_weight_view, - std::tuple, raft::device_span> vertex_pairs, - bool do_expensive_check); - -template std:: - tuple, rmm::device_uvector, rmm::device_uvector> - cosine_similarity_all_pairs_coefficients( - raft::handle_t const& handle, - graph_view_t const& graph_view, - std::optional> edge_weight_view, - std::optional> vertices, - std::optional topk, - bool do_expensive_check); - -template std:: - tuple, rmm::device_uvector, rmm::device_uvector> - cosine_similarity_all_pairs_coefficients( - raft::handle_t const& handle, - graph_view_t const& graph_view, - std::optional> edge_weight_view, - std::optional> vertices, - std::optional topk, - bool do_expensive_check); - -} // namespace cugraph diff --git a/cpp/src/link_prediction/cosine_sg_v32_e64.cu b/cpp/src/link_prediction/cosine_sg_v32_e64.cu deleted file mode 100644 index 80a3b31faab..00000000000 --- a/cpp/src/link_prediction/cosine_sg_v32_e64.cu +++ /dev/null @@ -1,54 +0,0 @@ -/* - * 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. - * 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. - */ -#include "link_prediction/cosine_similarity_impl.cuh" - -namespace cugraph { - -template rmm::device_uvector cosine_similarity_coefficients( - raft::handle_t const& handle, - graph_view_t const& graph_view, - std::optional> edge_weight_view, - std::tuple, raft::device_span> vertex_pairs, - bool do_expensive_check); - -template rmm::device_uvector cosine_similarity_coefficients( - raft::handle_t const& handle, - graph_view_t const& graph_view, - std::optional> edge_weight_view, - std::tuple, raft::device_span> vertex_pairs, - bool do_expensive_check); - -template std:: - tuple, rmm::device_uvector, rmm::device_uvector> - cosine_similarity_all_pairs_coefficients( - raft::handle_t const& handle, - graph_view_t const& graph_view, - std::optional> edge_weight_view, - std::optional> vertices, - std::optional topk, - bool do_expensive_check); - -template std:: - tuple, rmm::device_uvector, rmm::device_uvector> - cosine_similarity_all_pairs_coefficients( - raft::handle_t const& handle, - graph_view_t const& graph_view, - std::optional> edge_weight_view, - std::optional> vertices, - std::optional topk, - bool do_expensive_check); - -} // namespace cugraph diff --git a/cpp/src/link_prediction/jaccard_mg_v32_e64.cu b/cpp/src/link_prediction/jaccard_mg_v32_e64.cu deleted file mode 100644 index a359458a3c0..00000000000 --- a/cpp/src/link_prediction/jaccard_mg_v32_e64.cu +++ /dev/null @@ -1,54 +0,0 @@ -/* - * 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. - * 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. - */ -#include "link_prediction/jaccard_impl.cuh" - -namespace cugraph { - -template rmm::device_uvector jaccard_coefficients( - raft::handle_t const& handle, - graph_view_t const& graph_view, - std::optional> edge_weight_view, - std::tuple, raft::device_span> vertex_pairs, - bool do_expensive_check); - -template rmm::device_uvector jaccard_coefficients( - raft::handle_t const& handle, - graph_view_t const& graph_view, - std::optional> edge_weight_view, - std::tuple, raft::device_span> vertex_pairs, - bool do_expensive_check); - -template std:: - tuple, rmm::device_uvector, rmm::device_uvector> - jaccard_all_pairs_coefficients( - raft::handle_t const& handle, - graph_view_t const& graph_view, - std::optional> edge_weight_view, - std::optional> vertices, - std::optional topk, - bool do_expensive_check); - -template std:: - tuple, rmm::device_uvector, rmm::device_uvector> - jaccard_all_pairs_coefficients( - raft::handle_t const& handle, - graph_view_t const& graph_view, - std::optional> edge_weight_view, - std::optional> vertices, - std::optional topk, - bool do_expensive_check); - -} // namespace cugraph diff --git a/cpp/src/link_prediction/jaccard_sg_v32_e64.cu b/cpp/src/link_prediction/jaccard_sg_v32_e64.cu deleted file mode 100644 index eaa01f13c5e..00000000000 --- a/cpp/src/link_prediction/jaccard_sg_v32_e64.cu +++ /dev/null @@ -1,54 +0,0 @@ -/* - * 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. - * 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. - */ -#include "link_prediction/jaccard_impl.cuh" - -namespace cugraph { - -template rmm::device_uvector jaccard_coefficients( - raft::handle_t const& handle, - graph_view_t const& graph_view, - std::optional> edge_weight_view, - std::tuple, raft::device_span> vertex_pairs, - bool do_expensive_check); - -template rmm::device_uvector jaccard_coefficients( - raft::handle_t const& handle, - graph_view_t const& graph_view, - std::optional> edge_weight_view, - std::tuple, raft::device_span> vertex_pairs, - bool do_expensive_check); - -template std:: - tuple, rmm::device_uvector, rmm::device_uvector> - jaccard_all_pairs_coefficients( - raft::handle_t const& handle, - graph_view_t const& graph_view, - std::optional> edge_weight_view, - std::optional> vertices, - std::optional topk, - bool do_expensive_check); - -template std:: - tuple, rmm::device_uvector, rmm::device_uvector> - jaccard_all_pairs_coefficients( - raft::handle_t const& handle, - graph_view_t const& graph_view, - std::optional> edge_weight_view, - std::optional> vertices, - std::optional topk, - bool do_expensive_check); - -} // namespace cugraph diff --git a/cpp/src/link_prediction/overlap_mg_v32_e64.cu b/cpp/src/link_prediction/overlap_mg_v32_e64.cu deleted file mode 100644 index c493a50a5db..00000000000 --- a/cpp/src/link_prediction/overlap_mg_v32_e64.cu +++ /dev/null @@ -1,54 +0,0 @@ -/* - * 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. - * 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. - */ -#include "link_prediction/overlap_impl.cuh" - -namespace cugraph { - -template rmm::device_uvector overlap_coefficients( - raft::handle_t const& handle, - graph_view_t const& graph_view, - std::optional> edge_weight_view, - std::tuple, raft::device_span> vertex_pairs, - bool do_expensive_check); - -template rmm::device_uvector overlap_coefficients( - raft::handle_t const& handle, - graph_view_t const& graph_view, - std::optional> edge_weight_view, - std::tuple, raft::device_span> vertex_pairs, - bool do_expensive_check); - -template std:: - tuple, rmm::device_uvector, rmm::device_uvector> - overlap_all_pairs_coefficients( - raft::handle_t const& handle, - graph_view_t const& graph_view, - std::optional> edge_weight_view, - std::optional> vertices, - std::optional topk, - bool do_expensive_check); - -template std:: - tuple, rmm::device_uvector, rmm::device_uvector> - overlap_all_pairs_coefficients( - raft::handle_t const& handle, - graph_view_t const& graph_view, - std::optional> edge_weight_view, - std::optional> vertices, - std::optional topk, - bool do_expensive_check); - -} // namespace cugraph diff --git a/cpp/src/link_prediction/overlap_sg_v32_e64.cu b/cpp/src/link_prediction/overlap_sg_v32_e64.cu deleted file mode 100644 index 31adbcf0238..00000000000 --- a/cpp/src/link_prediction/overlap_sg_v32_e64.cu +++ /dev/null @@ -1,54 +0,0 @@ -/* - * 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. - * 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. - */ -#include "link_prediction/overlap_impl.cuh" - -namespace cugraph { - -template rmm::device_uvector overlap_coefficients( - raft::handle_t const& handle, - graph_view_t const& graph_view, - std::optional> edge_weight_view, - std::tuple, raft::device_span> vertex_pairs, - bool do_expensive_check); - -template rmm::device_uvector overlap_coefficients( - raft::handle_t const& handle, - graph_view_t const& graph_view, - std::optional> edge_weight_view, - std::tuple, raft::device_span> vertex_pairs, - bool do_expensive_check); - -template std:: - tuple, rmm::device_uvector, rmm::device_uvector> - overlap_all_pairs_coefficients( - raft::handle_t const& handle, - graph_view_t const& graph_view, - std::optional> edge_weight_view, - std::optional> vertices, - std::optional topk, - bool do_expensive_check); - -template std:: - tuple, rmm::device_uvector, rmm::device_uvector> - overlap_all_pairs_coefficients( - raft::handle_t const& handle, - graph_view_t const& graph_view, - std::optional> edge_weight_view, - std::optional> vertices, - std::optional topk, - bool do_expensive_check); - -} // namespace cugraph diff --git a/cpp/src/link_prediction/sorensen_mg_v32_e64.cu b/cpp/src/link_prediction/sorensen_mg_v32_e64.cu deleted file mode 100644 index 9c5f5cc9716..00000000000 --- a/cpp/src/link_prediction/sorensen_mg_v32_e64.cu +++ /dev/null @@ -1,54 +0,0 @@ -/* - * 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. - * 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. - */ -#include "link_prediction/sorensen_impl.cuh" - -namespace cugraph { - -template rmm::device_uvector sorensen_coefficients( - raft::handle_t const& handle, - graph_view_t const& graph_view, - std::optional> edge_weight_view, - std::tuple, raft::device_span> vertex_pairs, - bool do_expensive_check); - -template rmm::device_uvector sorensen_coefficients( - raft::handle_t const& handle, - graph_view_t const& graph_view, - std::optional> edge_weight_view, - std::tuple, raft::device_span> vertex_pairs, - bool do_expensive_check); - -template std:: - tuple, rmm::device_uvector, rmm::device_uvector> - sorensen_all_pairs_coefficients( - raft::handle_t const& handle, - graph_view_t const& graph_view, - std::optional> edge_weight_view, - std::optional> vertices, - std::optional topk, - bool do_expensive_check); - -template std:: - tuple, rmm::device_uvector, rmm::device_uvector> - sorensen_all_pairs_coefficients( - raft::handle_t const& handle, - graph_view_t const& graph_view, - std::optional> edge_weight_view, - std::optional> vertices, - std::optional topk, - bool do_expensive_check); - -} // namespace cugraph diff --git a/cpp/src/link_prediction/sorensen_sg_v32_e64.cu b/cpp/src/link_prediction/sorensen_sg_v32_e64.cu deleted file mode 100644 index 20cd5e621e2..00000000000 --- a/cpp/src/link_prediction/sorensen_sg_v32_e64.cu +++ /dev/null @@ -1,54 +0,0 @@ -/* - * 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. - * 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. - */ -#include "link_prediction/sorensen_impl.cuh" - -namespace cugraph { - -template rmm::device_uvector sorensen_coefficients( - raft::handle_t const& handle, - graph_view_t const& graph_view, - std::optional> edge_weight_view, - std::tuple, raft::device_span> vertex_pairs, - bool do_expensive_check); - -template rmm::device_uvector sorensen_coefficients( - raft::handle_t const& handle, - graph_view_t const& graph_view, - std::optional> edge_weight_view, - std::tuple, raft::device_span> vertex_pairs, - bool do_expensive_check); - -template std:: - tuple, rmm::device_uvector, rmm::device_uvector> - sorensen_all_pairs_coefficients( - raft::handle_t const& handle, - graph_view_t const& graph_view, - std::optional> edge_weight_view, - std::optional> vertices, - std::optional topk, - bool do_expensive_check); - -template std:: - tuple, rmm::device_uvector, rmm::device_uvector> - sorensen_all_pairs_coefficients( - raft::handle_t const& handle, - graph_view_t const& graph_view, - std::optional> edge_weight_view, - std::optional> vertices, - std::optional topk, - bool do_expensive_check); - -} // namespace cugraph diff --git a/cpp/src/lookup/lookup_src_dst_mg_v32_e64.cu b/cpp/src/lookup/lookup_src_dst_mg_v32_e64.cu deleted file mode 100644 index 4e120f49f10..00000000000 --- a/cpp/src/lookup/lookup_src_dst_mg_v32_e64.cu +++ /dev/null @@ -1,43 +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. - */ - -#include "lookup/lookup_src_dst_impl.cuh" - -namespace cugraph { - -template class lookup_container_t; - -template lookup_container_t build_edge_id_and_type_to_src_dst_lookup_map( - raft::handle_t const& handle, - graph_view_t const& graph_view, - edge_property_view_t edge_id_view, - edge_property_view_t edge_type_view); - -template std::tuple, rmm::device_uvector> -lookup_endpoints_from_edge_ids_and_single_type( - raft::handle_t const& handle, - lookup_container_t const& search_container, - raft::device_span edge_ids_to_lookup, - int32_t edge_type_to_lookup); - -template std::tuple, rmm::device_uvector> -lookup_endpoints_from_edge_ids_and_types( - raft::handle_t const& handle, - lookup_container_t const& search_container, - raft::device_span edge_ids_to_lookup, - raft::device_span edge_types_to_lookup); - -} // namespace cugraph diff --git a/cpp/src/lookup/lookup_src_dst_sg_v32_e64.cu b/cpp/src/lookup/lookup_src_dst_sg_v32_e64.cu deleted file mode 100644 index 46b62e05ed8..00000000000 --- a/cpp/src/lookup/lookup_src_dst_sg_v32_e64.cu +++ /dev/null @@ -1,43 +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. - */ - -#include "lookup/lookup_src_dst_impl.cuh" - -namespace cugraph { - -template class lookup_container_t; - -template lookup_container_t build_edge_id_and_type_to_src_dst_lookup_map( - raft::handle_t const& handle, - graph_view_t const& graph_view, - edge_property_view_t edge_id_view, - edge_property_view_t edge_type_view); - -template std::tuple, rmm::device_uvector> -lookup_endpoints_from_edge_ids_and_single_type( - raft::handle_t const& handle, - lookup_container_t const& search_container, - raft::device_span edge_ids_to_lookup, - int32_t edge_type_to_lookup); - -template std::tuple, rmm::device_uvector> -lookup_endpoints_from_edge_ids_and_types( - raft::handle_t const& handle, - lookup_container_t const& search_container, - raft::device_span edge_ids_to_lookup, - raft::device_span edge_types_to_lookup); - -} // namespace cugraph diff --git a/cpp/src/prims/detail/sample_and_compute_local_nbr_indices.cuh b/cpp/src/prims/detail/sample_and_compute_local_nbr_indices.cuh index 7d4750c0554..a6a164d36c1 100644 --- a/cpp/src/prims/detail/sample_and_compute_local_nbr_indices.cuh +++ b/cpp/src/prims/detail/sample_and_compute_local_nbr_indices.cuh @@ -392,11 +392,11 @@ compute_unique_keys(raft::handle_t const& handle, cuda::proclaim_return_type( [unique_key_first = get_dataframe_buffer_begin(aggregate_local_frontier_unique_keys) + local_frontier_unique_key_displacements[i], - num_unique_keys = local_frontier_unique_key_sizes[i]] __device__(key_t key) { + unique_key_last = get_dataframe_buffer_begin(aggregate_local_frontier_unique_keys) + + local_frontier_unique_key_displacements[i] + + local_frontier_unique_key_sizes[i]] __device__(key_t key) { return static_cast(thrust::distance( - unique_key_first, - thrust::lower_bound( - thrust::seq, unique_key_first, unique_key_first + num_unique_keys, key))); + unique_key_first, thrust::find(thrust::seq, unique_key_first, unique_key_last, key))); })); } @@ -1759,8 +1759,7 @@ biased_sample_and_compute_local_nbr_indices( std::optional> key_indices{std::nullopt}; std::vector local_frontier_sample_offsets{}; if (with_replacement) { - // computet segmented inclusive sums (one segment per seed) - + // compute segmented inclusive sums (one segment per seed) auto unique_key_first = thrust::make_transform_iterator( thrust::make_counting_iterator(size_t{0}), cuda::proclaim_return_type( diff --git a/cpp/src/prims/per_v_random_select_transform_outgoing_e.cuh b/cpp/src/prims/per_v_random_select_transform_outgoing_e.cuh index 03514e52e6e..9d0f711d106 100644 --- a/cpp/src/prims/per_v_random_select_transform_outgoing_e.cuh +++ b/cpp/src/prims/per_v_random_select_transform_outgoing_e.cuh @@ -351,7 +351,7 @@ per_v_random_select_transform_e(raft::handle_t const& handle, uniform_sample_and_compute_local_nbr_indices( handle, graph_view, - (minor_comm_size > 1) ? get_dataframe_buffer_begin(*aggregate_local_frontier) + (minor_comm_size > 1) ? get_dataframe_buffer_cbegin(*aggregate_local_frontier) : frontier.begin(), local_frontier_displacements, local_frontier_sizes, @@ -363,7 +363,7 @@ per_v_random_select_transform_e(raft::handle_t const& handle, biased_sample_and_compute_local_nbr_indices( handle, graph_view, - (minor_comm_size > 1) ? get_dataframe_buffer_begin(*aggregate_local_frontier) + (minor_comm_size > 1) ? get_dataframe_buffer_cbegin(*aggregate_local_frontier) : frontier.begin(), edge_bias_src_value_input, edge_bias_dst_value_input, @@ -392,7 +392,7 @@ per_v_random_select_transform_e(raft::handle_t const& handle, graph_view.local_edge_partition_view(i)); auto edge_partition_frontier_key_first = - ((minor_comm_size > 1) ? get_dataframe_buffer_begin(*aggregate_local_frontier) + ((minor_comm_size > 1) ? get_dataframe_buffer_cbegin(*aggregate_local_frontier) : frontier.begin()) + local_frontier_displacements[i]; auto edge_partition_sample_local_nbr_index_first = diff --git a/cpp/src/sampling/detail/check_edge_bias_values_mg_v32_e64.cu b/cpp/src/sampling/detail/check_edge_bias_values_mg_v32_e64.cu deleted file mode 100644 index b8b3564fee7..00000000000 --- a/cpp/src/sampling/detail/check_edge_bias_values_mg_v32_e64.cu +++ /dev/null @@ -1,33 +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. - */ - -#include "sampling/detail/check_edge_bias_values.cuh" - -namespace cugraph { -namespace detail { - -template std::tuple check_edge_bias_values( - raft::handle_t const& handle, - graph_view_t const& graph_view, - edge_property_view_t edge_bias_view); - -template std::tuple check_edge_bias_values( - raft::handle_t const& handle, - graph_view_t const& graph_view, - edge_property_view_t edge_bias_view); - -} // namespace detail -} // namespace cugraph diff --git a/cpp/src/sampling/detail/check_edge_bias_values_sg_v32_e64.cu b/cpp/src/sampling/detail/check_edge_bias_values_sg_v32_e64.cu deleted file mode 100644 index c8c28a5ad04..00000000000 --- a/cpp/src/sampling/detail/check_edge_bias_values_sg_v32_e64.cu +++ /dev/null @@ -1,33 +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. - */ - -#include "sampling/detail/check_edge_bias_values.cuh" - -namespace cugraph { -namespace detail { - -template std::tuple check_edge_bias_values( - raft::handle_t const& handle, - graph_view_t const& graph_view, - edge_property_view_t edge_bias_view); - -template std::tuple check_edge_bias_values( - raft::handle_t const& handle, - graph_view_t const& graph_view, - edge_property_view_t edge_bias_view); - -} // namespace detail -} // namespace cugraph diff --git a/cpp/src/sampling/detail/gather_one_hop_edgelist_mg_v32_e64.cu b/cpp/src/sampling/detail/gather_one_hop_edgelist_mg_v32_e64.cu deleted file mode 100644 index d7dd08b4cd5..00000000000 --- a/cpp/src/sampling/detail/gather_one_hop_edgelist_mg_v32_e64.cu +++ /dev/null @@ -1,55 +0,0 @@ -/* - * 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. - * 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. - */ - -#include "sampling/detail/gather_one_hop_edgelist_impl.cuh" - -namespace cugraph { -namespace detail { - -template std::tuple, - rmm::device_uvector, - std::optional>, - std::optional>, - std::optional>, - std::optional>> -gather_one_hop_edgelist( - raft::handle_t const& handle, - graph_view_t const& graph_view, - std::optional> edge_weight_view, - std::optional> edge_id_view, - std::optional> edge_edge_type_view, - raft::device_span active_majors, - std::optional> active_major_labels, - bool do_expensive_check); - -template std::tuple, - rmm::device_uvector, - std::optional>, - std::optional>, - std::optional>, - std::optional>> -gather_one_hop_edgelist( - raft::handle_t const& handle, - graph_view_t const& graph_view, - std::optional> edge_weight_view, - std::optional> edge_id_view, - std::optional> edge_edge_type_view, - raft::device_span active_majors, - std::optional> active_major_labels, - bool do_expensive_check); - -} // namespace detail -} // namespace cugraph diff --git a/cpp/src/sampling/detail/gather_one_hop_edgelist_sg_v32_e64.cu b/cpp/src/sampling/detail/gather_one_hop_edgelist_sg_v32_e64.cu deleted file mode 100644 index 2a151b4d4e6..00000000000 --- a/cpp/src/sampling/detail/gather_one_hop_edgelist_sg_v32_e64.cu +++ /dev/null @@ -1,55 +0,0 @@ -/* - * 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. - * 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. - */ - -#include "sampling/detail/gather_one_hop_edgelist_impl.cuh" - -namespace cugraph { -namespace detail { - -template std::tuple, - rmm::device_uvector, - std::optional>, - std::optional>, - std::optional>, - std::optional>> -gather_one_hop_edgelist( - raft::handle_t const& handle, - graph_view_t const& graph_view, - std::optional> edge_weight_view, - std::optional> edge_id_view, - std::optional> edge_edge_type_view, - raft::device_span active_majors, - std::optional> active_major_labels, - bool do_expensive_check); - -template std::tuple, - rmm::device_uvector, - std::optional>, - std::optional>, - std::optional>, - std::optional>> -gather_one_hop_edgelist( - raft::handle_t const& handle, - graph_view_t const& graph_view, - std::optional> edge_weight_view, - std::optional> edge_id_view, - std::optional> edge_edge_type_view, - raft::device_span active_majors, - std::optional> active_major_labels, - bool do_expensive_check); - -} // namespace detail -} // namespace cugraph diff --git a/cpp/src/sampling/detail/sample_edges_mg_v32_e64.cu b/cpp/src/sampling/detail/sample_edges_mg_v32_e64.cu deleted file mode 100644 index 4628840499f..00000000000 --- a/cpp/src/sampling/detail/sample_edges_mg_v32_e64.cu +++ /dev/null @@ -1,59 +0,0 @@ -/* - * 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. - * 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. - */ - -#include "sampling/detail/sample_edges.cuh" - -namespace cugraph { -namespace detail { - -template std::tuple, - rmm::device_uvector, - std::optional>, - std::optional>, - std::optional>, - std::optional>> -sample_edges(raft::handle_t const& handle, - graph_view_t const& graph_view, - std::optional> edge_weight_view, - std::optional> edge_id_view, - std::optional> edge_edge_type_view, - std::optional> edge_bias_view, - raft::random::RngState& rng_state, - raft::device_span active_majors, - std::optional> active_major_labels, - size_t fanout, - bool with_replacement); - -template std::tuple, - rmm::device_uvector, - std::optional>, - std::optional>, - std::optional>, - std::optional>> -sample_edges(raft::handle_t const& handle, - graph_view_t const& graph_view, - std::optional> edge_weight_view, - std::optional> edge_id_view, - std::optional> edge_edge_type_view, - std::optional> edge_bias_view, - raft::random::RngState& rng_state, - raft::device_span active_majors, - std::optional> active_major_labels, - size_t fanout, - bool with_replacement); - -} // namespace detail -} // namespace cugraph diff --git a/cpp/src/sampling/detail/sample_edges_sg_v32_e64.cu b/cpp/src/sampling/detail/sample_edges_sg_v32_e64.cu deleted file mode 100644 index b1d664782f2..00000000000 --- a/cpp/src/sampling/detail/sample_edges_sg_v32_e64.cu +++ /dev/null @@ -1,59 +0,0 @@ -/* - * 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. - * 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. - */ - -#include "sampling/detail/sample_edges.cuh" - -namespace cugraph { -namespace detail { - -template std::tuple, - rmm::device_uvector, - std::optional>, - std::optional>, - std::optional>, - std::optional>> -sample_edges(raft::handle_t const& handle, - graph_view_t const& graph_view, - std::optional> edge_weight_view, - std::optional> edge_id_view, - std::optional> edge_edge_type_view, - std::optional> edge_bias_view, - raft::random::RngState& rng_state, - raft::device_span active_majors, - std::optional> active_major_labels, - size_t fanout, - bool with_replacement); - -template std::tuple, - rmm::device_uvector, - std::optional>, - std::optional>, - std::optional>, - std::optional>> -sample_edges(raft::handle_t const& handle, - graph_view_t const& graph_view, - std::optional> edge_weight_view, - std::optional> edge_id_view, - std::optional> edge_edge_type_view, - std::optional> edge_bias_view, - raft::random::RngState& rng_state, - raft::device_span active_majors, - std::optional> active_major_labels, - size_t fanout, - bool with_replacement); - -} // namespace detail -} // namespace cugraph diff --git a/cpp/src/sampling/detail/shuffle_and_organize_output_mg_v32_e64.cu b/cpp/src/sampling/detail/shuffle_and_organize_output_mg_v32_e64.cu deleted file mode 100644 index ef760844b51..00000000000 --- a/cpp/src/sampling/detail/shuffle_and_organize_output_mg_v32_e64.cu +++ /dev/null @@ -1,61 +0,0 @@ -/* - * 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. - * 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. - */ - -#include "sampling/detail/shuffle_and_organize_output_impl.cuh" - -namespace cugraph { -namespace detail { - -template std::tuple, - rmm::device_uvector, - std::optional>, - std::optional>, - std::optional>, - std::optional>, - std::optional>, - std::optional>> -shuffle_and_organize_output( - raft::handle_t const& handle, - rmm::device_uvector&& majors, - rmm::device_uvector&& minors, - std::optional>&& weights, - std::optional>&& edge_ids, - std::optional>&& edge_types, - std::optional>&& hops, - std::optional>&& labels, - std::optional> label_to_output_comm_rank); - -template std::tuple, - rmm::device_uvector, - std::optional>, - std::optional>, - std::optional>, - std::optional>, - std::optional>, - std::optional>> -shuffle_and_organize_output( - raft::handle_t const& handle, - rmm::device_uvector&& majors, - rmm::device_uvector&& minors, - std::optional>&& weights, - std::optional>&& edge_ids, - std::optional>&& edge_types, - std::optional>&& hops, - std::optional>&& labels, - std::optional> label_to_output_comm_rank); - -} // namespace detail -} // namespace cugraph diff --git a/cpp/src/sampling/negative_sampling_mg_v32_e64.cu b/cpp/src/sampling/negative_sampling_mg_v32_e64.cu deleted file mode 100644 index af4c28c0f1a..00000000000 --- a/cpp/src/sampling/negative_sampling_mg_v32_e64.cu +++ /dev/null @@ -1,48 +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. - */ - -#include "negative_sampling_impl.cuh" - -#include -#include - -namespace cugraph { - -template std::tuple, rmm::device_uvector> negative_sampling( - raft::handle_t const& handle, - raft::random::RngState& rng_state, - graph_view_t const& graph_view, - std::optional> src_bias, - std::optional> dst_bias, - size_t num_samples, - bool remove_duplicates, - bool remove_existing_edges, - bool exact_number_of_samples, - bool do_expensive_check); - -template std::tuple, rmm::device_uvector> negative_sampling( - raft::handle_t const& handle, - raft::random::RngState& rng_state, - graph_view_t const& graph_view, - std::optional> src_bias, - std::optional> dst_bias, - size_t num_samples, - bool remove_duplicates, - bool remove_existing_edges, - bool exact_number_of_samples, - bool do_expensive_check); - -} // namespace cugraph diff --git a/cpp/src/sampling/negative_sampling_sg_v32_e64.cu b/cpp/src/sampling/negative_sampling_sg_v32_e64.cu deleted file mode 100644 index c66c31a4258..00000000000 --- a/cpp/src/sampling/negative_sampling_sg_v32_e64.cu +++ /dev/null @@ -1,48 +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. - */ - -#include "negative_sampling_impl.cuh" - -#include -#include - -namespace cugraph { - -template std::tuple, rmm::device_uvector> negative_sampling( - raft::handle_t const& handle, - raft::random::RngState& rng_state, - graph_view_t const& graph_view, - std::optional> src_bias, - std::optional> dst_bias, - size_t num_samples, - bool remove_duplicates, - bool remove_existing_edges, - bool exact_number_of_samples, - bool do_expensive_check); - -template std::tuple, rmm::device_uvector> negative_sampling( - raft::handle_t const& handle, - raft::random::RngState& rng_state, - graph_view_t const& graph_view, - std::optional> src_bias, - std::optional> dst_bias, - size_t num_samples, - bool remove_duplicates, - bool remove_existing_edges, - bool exact_number_of_samples, - bool do_expensive_check); - -} // namespace cugraph diff --git a/cpp/src/sampling/random_walks_impl.cuh b/cpp/src/sampling/random_walks_impl.cuh index d582893d756..6c10fc473f3 100644 --- a/cpp/src/sampling/random_walks_impl.cuh +++ b/cpp/src/sampling/random_walks_impl.cuh @@ -17,7 +17,10 @@ #pragma once #include "detail/graph_partition_utils.cuh" +#include "prims/detail/nbr_intersection.cuh" #include "prims/per_v_random_select_transform_outgoing_e.cuh" +#include "prims/property_op_utils.cuh" +#include "prims/update_edge_src_dst_property.cuh" #include "prims/vertex_frontier.cuh" #include @@ -25,6 +28,7 @@ #include #include #include +#include #include #include #include @@ -46,13 +50,6 @@ namespace cugraph { namespace detail { -inline uint64_t get_current_time_nanoseconds() -{ - auto cur = std::chrono::steady_clock::now(); - return static_cast( - std::chrono::duration_cast(cur.time_since_epoch()).count()); -} - template struct sample_edges_op_t { template @@ -70,21 +67,129 @@ struct sample_edges_op_t { } }; +template +struct biased_random_walk_e_bias_op_t { + __device__ bias_t + operator()(vertex_t, vertex_t, bias_t src_out_weight_sum, thrust::nullopt_t, bias_t weight) const + { + return weight / src_out_weight_sum; + } +}; + +template +struct biased_sample_edges_op_t { + __device__ thrust::tuple operator()( + vertex_t, vertex_t dst, weight_t, thrust::nullopt_t, weight_t weight) const + { + return thrust::make_tuple(dst, weight); + } +}; + +template +struct node2vec_random_walk_e_bias_op_t { + bias_t p_{}; + bias_t q_{}; + raft::device_span intersection_offsets_{}; + raft::device_span intersection_indices_{}; + raft::device_span current_vertices_{}; + raft::device_span prev_vertices_{}; + + // Unweighted Bias Operator + template + __device__ std::enable_if_t, bias_t> operator()( + thrust::tuple tagged_src, + vertex_t dst, + thrust::nullopt_t, + thrust::nullopt_t, + thrust::nullopt_t) const + { + // Check tag (prev vert) for destination + if (dst == thrust::get<1>(tagged_src)) { return 1.0 / p_; } + // Search zipped vertices for tagged src + auto lower_itr = thrust::lower_bound( + thrust::seq, + thrust::make_zip_iterator(current_vertices_.begin(), prev_vertices_.begin()), + thrust::make_zip_iterator(current_vertices_.end(), prev_vertices_.end()), + tagged_src); + auto low_idx = thrust::distance( + thrust::make_zip_iterator(current_vertices_.begin(), prev_vertices_.begin()), lower_itr); + auto intersection_index_first = intersection_indices_.begin() + intersection_offsets_[low_idx]; + auto intersection_index_last = + intersection_indices_.begin() + intersection_offsets_[low_idx + 1]; + auto itr = + thrust::lower_bound(thrust::seq, intersection_index_first, intersection_index_last, dst); + return (itr != intersection_index_last && *itr == dst) ? 1.0 : 1.0 / q_; + } + + // Weighted Bias Operator + template + __device__ std::enable_if_t, bias_t> operator()( + thrust::tuple tagged_src, + vertex_t dst, + thrust::nullopt_t, + thrust::nullopt_t, + W) const + { + // Check tag (prev vert) for destination + if (dst == thrust::get<1>(tagged_src)) { return 1.0 / p_; } + // Search zipped vertices for tagged src + auto lower_itr = thrust::lower_bound( + thrust::seq, + thrust::make_zip_iterator(current_vertices_.begin(), prev_vertices_.begin()), + thrust::make_zip_iterator(current_vertices_.end(), prev_vertices_.end()), + tagged_src); + auto low_idx = thrust::distance( + thrust::make_zip_iterator(current_vertices_.begin(), prev_vertices_.begin()), lower_itr); + auto intersection_index_first = intersection_indices_.begin() + intersection_offsets_[low_idx]; + auto intersection_index_last = + intersection_indices_.begin() + intersection_offsets_[low_idx + 1]; + auto itr = + thrust::lower_bound(thrust::seq, intersection_index_first, intersection_index_last, dst); + return (itr != intersection_index_last && *itr == dst) ? 1.0 : 1.0 / q_; + } +}; + +template +struct node2vec_sample_edges_op_t { + template + __device__ std::enable_if_t, vertex_t> operator()( + thrust::tuple tagged_src, + vertex_t dst, + thrust::nullopt_t, + thrust::nullopt_t, + thrust::nullopt_t) const + { + return dst; + } + + template + __device__ std::enable_if_t, thrust::tuple> operator()( + thrust::tuple tagged_src, + vertex_t dst, + thrust::nullopt_t, + thrust::nullopt_t, + W w) const + { + return thrust::make_tuple(dst, w); + } +}; + template struct uniform_selector { - raft::random::RngState rng_state_; - - uniform_selector(uint64_t seed) : rng_state_(seed) {} + raft::random::RngState& rng_state_; + static constexpr bool is_second_order_ = false; template std::tuple, + std::optional>, std::optional>> follow_random_edge( raft::handle_t const& handle, GraphViewType const& graph_view, std::optional> edge_weight_view, - rmm::device_uvector const& current_vertices) + rmm::device_uvector&& current_vertices, + std::optional>&& previous_vertices) { using vertex_t = typename GraphViewType::vertex_type; @@ -133,30 +238,67 @@ struct uniform_selector { minors = std::move(sample_e_op_results); } - return std::make_tuple(std::move(minors), std::move(weights)); + return std::make_tuple(std::move(minors), std::move(previous_vertices), std::move(weights)); } }; template struct biased_selector { - uint64_t seed_{0}; + raft::random::RngState& rng_state_; + static constexpr bool is_second_order_ = false; template std::tuple, + std::optional>, std::optional>> follow_random_edge( raft::handle_t const& handle, GraphViewType const& graph_view, std::optional> edge_weight_view, - rmm::device_uvector const& current_vertices) + rmm::device_uvector&& current_vertices, + std::optional>&& previous_vertices) { - // To do biased sampling, I need out_weights instead of out_degrees. - // Then I generate a random float between [0, out_weights[v]). Then - // instead of making a decision based on the index I need to find - // upper_bound (or is it lower_bound) of the random number and - // the cumulative weight. - CUGRAPH_FAIL("biased sampling not implemented"); + // Create vertex frontier + using vertex_t = typename GraphViewType::vertex_type; + + using tag_t = void; + + cugraph::vertex_frontier_t vertex_frontier( + handle, 1); + + vertex_frontier.bucket(0).insert(current_vertices.begin(), current_vertices.end()); + + auto vertex_weight_sum = compute_out_weight_sums(handle, graph_view, *edge_weight_view); + edge_src_property_t edge_src_out_weight_sums(handle, graph_view); + update_edge_src_property(handle, + graph_view, + vertex_frontier.bucket(0).begin(), + vertex_frontier.bucket(0).end(), + vertex_weight_sum.data(), + edge_src_out_weight_sums.mutable_view()); + auto [sample_offsets, sample_e_op_results] = cugraph::per_v_random_select_transform_outgoing_e( + handle, + graph_view, + vertex_frontier.bucket(0), + edge_src_out_weight_sums.view(), + cugraph::edge_dst_dummy_property_t{}.view(), + *edge_weight_view, + biased_random_walk_e_bias_op_t{}, + edge_src_out_weight_sums.view(), + cugraph::edge_dst_dummy_property_t{}.view(), + *edge_weight_view, + biased_sample_edges_op_t{}, + rng_state_, + size_t{1}, + true, + std::make_optional( + thrust::make_tuple(vertex_t{cugraph::invalid_vertex_id::value}, weight_t{0.0}))); + + // Return results + return std::make_tuple(std::move(std::get<0>(sample_e_op_results)), + std::move(previous_vertices), + std::move(std::get<1>(sample_e_op_results))); } }; @@ -164,26 +306,232 @@ template struct node2vec_selector { weight_t p_; weight_t q_; - uint64_t seed_{0}; + raft::random::RngState& rng_state_; + static constexpr bool is_second_order_ = true; template std::tuple, + std::optional>, std::optional>> follow_random_edge( raft::handle_t const& handle, GraphViewType const& graph_view, std::optional> edge_weight_view, - rmm::device_uvector const& current_vertices) + rmm::device_uvector&& current_vertices, + std::optional>&& previous_vertices) { - // To do node2vec, I need the following: - // 1) transform_reduce_dst_nbr_intersection_of_e_endpoints_by_v to compute the sum of the - // node2vec style weights - // 2) Generate a random number between [0, output_from_trdnioeebv[v]) - // 3) a sampling value that lets me pick the correct edge based on the same computation - // (essentially weighted sampling, but with a function that computes the weight rather - // than just using the edge weights) - CUGRAPH_FAIL("node2vec not implemented"); + // Create vertex frontier + using vertex_t = typename GraphViewType::vertex_type; + + using tag_t = vertex_t; + + // Zip previous and current vertices for nbr_intersection() + auto intersection_pairs = + thrust::make_zip_iterator(current_vertices.begin(), (*previous_vertices).begin()); + + auto [intersection_offsets, intersection_indices] = + detail::nbr_intersection(handle, + graph_view, + cugraph::edge_dummy_property_t{}.view(), + intersection_pairs, + intersection_pairs + current_vertices.size(), + std::array{true, true}, + false); + + rmm::device_uvector intersection_counts(size_t{0}, handle.get_stream()); + rmm::device_uvector aggregate_offsets(size_t{0}, handle.get_stream()); + rmm::device_uvector aggregate_currents(size_t{0}, handle.get_stream()); + rmm::device_uvector aggregate_previous(size_t{0}, handle.get_stream()); + rmm::device_uvector aggregate_indices(size_t{0}, handle.get_stream()); + + // Aggregate intersection data across minor comm + if constexpr (GraphViewType::is_multi_gpu) { + intersection_counts.resize(intersection_offsets.size(), handle.get_stream()); + thrust::adjacent_difference(handle.get_thrust_policy(), + intersection_offsets.begin(), + intersection_offsets.end(), + intersection_counts.begin()); + + auto recv_counts = cugraph::host_scalar_allgather( + handle.get_subcomm(cugraph::partition_manager::minor_comm_name()), + current_vertices.size(), + handle.get_stream()); + + std::vector displacements(recv_counts.size()); + std::exclusive_scan(recv_counts.begin(), recv_counts.end(), displacements.begin(), size_t{0}); + + aggregate_offsets.resize(displacements.back() + recv_counts.back() + 1, handle.get_stream()); + aggregate_offsets.set_element_to_zero_async(aggregate_offsets.size() - 1, + handle.get_stream()); + + cugraph::device_allgatherv(handle.get_subcomm(cugraph::partition_manager::minor_comm_name()), + intersection_counts.begin() + 1, + aggregate_offsets.begin(), + recv_counts, + displacements, + handle.get_stream()); + + thrust::exclusive_scan(handle.get_thrust_policy(), + aggregate_offsets.begin(), + aggregate_offsets.end(), + aggregate_offsets.begin()); + + aggregate_currents.resize(displacements.back() + recv_counts.back(), handle.get_stream()); + + cugraph::device_allgatherv(handle.get_subcomm(cugraph::partition_manager::minor_comm_name()), + current_vertices.begin(), + aggregate_currents.begin(), + recv_counts, + displacements, + handle.get_stream()); + + aggregate_previous.resize(displacements.back() + recv_counts.back(), handle.get_stream()); + + cugraph::device_allgatherv(handle.get_subcomm(cugraph::partition_manager::minor_comm_name()), + (*previous_vertices).begin(), + aggregate_previous.begin(), + recv_counts, + displacements, + handle.get_stream()); + + recv_counts = cugraph::host_scalar_allgather( + handle.get_subcomm(cugraph::partition_manager::minor_comm_name()), + intersection_offsets.back_element(handle.get_stream()), + handle.get_stream()); + + displacements.resize(recv_counts.size()); + std::exclusive_scan(recv_counts.begin(), recv_counts.end(), displacements.begin(), size_t{0}); + + aggregate_indices.resize(displacements.back() + recv_counts.back(), handle.get_stream()); + + cugraph::device_allgatherv(handle.get_subcomm(cugraph::partition_manager::minor_comm_name()), + intersection_indices.begin(), + aggregate_indices.begin(), + recv_counts, + displacements, + handle.get_stream()); + } + + cugraph::vertex_frontier_t vertex_frontier( + handle, 1); + vertex_frontier.bucket(0).insert( + thrust::make_zip_iterator(current_vertices.begin(), (*previous_vertices).begin()), + thrust::make_zip_iterator(current_vertices.end(), (*previous_vertices).end())); + + // Create data structs for results + rmm::device_uvector minors(0, handle.get_stream()); + std::optional> weights{std::nullopt}; + + if (edge_weight_view) { + auto [sample_offsets, sample_e_op_results] = + cugraph::per_v_random_select_transform_outgoing_e( + handle, + graph_view, + vertex_frontier.bucket(0), + cugraph::edge_src_dummy_property_t{}.view(), + cugraph::edge_dst_dummy_property_t{}.view(), + *edge_weight_view, + GraphViewType::is_multi_gpu + ? node2vec_random_walk_e_bias_op_t{p_, + q_, + raft::device_span( + aggregate_offsets.data(), + aggregate_offsets.size()), + raft::device_span( + aggregate_indices.data(), + aggregate_indices.size()), + raft::device_span( + aggregate_currents.data(), + aggregate_currents.size()), + raft::device_span( + aggregate_previous.data(), + aggregate_previous.size())} + : node2vec_random_walk_e_bias_op_t{p_, + q_, + raft::device_span( + intersection_offsets.data(), + intersection_offsets.size()), + raft::device_span( + intersection_indices.data(), + intersection_indices.size()), + raft::device_span< + vertex_t const>(current_vertices.data(), + current_vertices.size()), + raft::device_span( + (*previous_vertices).data(), + (*previous_vertices).size())}, + cugraph::edge_src_dummy_property_t{}.view(), + cugraph::edge_dst_dummy_property_t{}.view(), + *edge_weight_view, + node2vec_sample_edges_op_t{}, + rng_state_, + size_t{1}, + true, + std::make_optional(thrust::make_tuple( + vertex_t{cugraph::invalid_vertex_id::value}, weight_t{0.0}))); + minors = std::move(std::get<0>(sample_e_op_results)); + weights = std::move(std::get<1>(sample_e_op_results)); + } else { + auto [sample_offsets, sample_e_op_results] = + cugraph::per_v_random_select_transform_outgoing_e( + handle, + graph_view, + vertex_frontier.bucket(0), + cugraph::edge_src_dummy_property_t{}.view(), + cugraph::edge_dst_dummy_property_t{}.view(), + cugraph::edge_dummy_property_t{}.view(), + GraphViewType::is_multi_gpu + ? node2vec_random_walk_e_bias_op_t{p_, + q_, + raft::device_span( + aggregate_offsets.data(), + aggregate_offsets.size()), + raft::device_span( + aggregate_indices.data(), + aggregate_indices.size()), + raft::device_span( + aggregate_currents.data(), + aggregate_currents.size()), + raft::device_span( + aggregate_previous.data(), + aggregate_previous.size())} + : node2vec_random_walk_e_bias_op_t{p_, + q_, + raft::device_span( + intersection_offsets.data(), + intersection_offsets.size()), + raft::device_span( + intersection_indices.data(), + intersection_indices.size()), + raft::device_span< + vertex_t const>(current_vertices.data(), + current_vertices.size()), + raft::device_span( + (*previous_vertices).data(), + (*previous_vertices).size())}, + cugraph::edge_src_dummy_property_t{}.view(), + cugraph::edge_dst_dummy_property_t{}.view(), + cugraph::edge_dummy_property_t{}.view(), + node2vec_sample_edges_op_t{}, + rng_state_, + size_t{1}, + true, + std::make_optional(vertex_t{cugraph::invalid_vertex_id::value})); + minors = std::move(sample_e_op_results); + } + + *previous_vertices = std::move(current_vertices); + + return std::make_tuple(std::move(minors), std::move(previous_vertices), std::move(weights)); } }; @@ -221,6 +569,16 @@ random_walk_impl(raft::handle_t const& handle, ? std::make_optional>(0, handle.get_stream()) : std::nullopt; + auto previous_vertices = (random_selector.is_second_order_) + ? std::make_optional>( + current_vertices.size(), handle.get_stream()) + : std::nullopt; + if (previous_vertices) { + raft::copy((*previous_vertices).data(), + start_vertices.data(), + start_vertices.size(), + handle.get_stream()); + } raft::copy( current_vertices.data(), start_vertices.data(), start_vertices.size(), handle.get_stream()); detail::sequence_fill( @@ -255,25 +613,73 @@ random_walk_impl(raft::handle_t const& handle, auto& minor_comm = handle.get_subcomm(cugraph::partition_manager::minor_comm_name()); auto const minor_comm_size = minor_comm.get_size(); - // Shuffle vertices to correct GPU to compute random indices - std::forward_as_tuple(std::tie(current_vertices, current_gpu, current_position), - std::ignore) = - cugraph::groupby_gpu_id_and_shuffle_values( - handle.get_comms(), + if (previous_vertices) { + std::forward_as_tuple( + std::tie(current_vertices, current_gpu, current_position, previous_vertices), + std::ignore) = + cugraph::groupby_gpu_id_and_shuffle_values( + handle.get_comms(), + thrust::make_zip_iterator(current_vertices.begin(), + current_gpu.begin(), + current_position.begin(), + previous_vertices->begin()), + thrust::make_zip_iterator(current_vertices.end(), + current_gpu.end(), + current_position.end(), + previous_vertices->end()), + [key_func = + cugraph::detail::compute_gpu_id_from_int_vertex_t{ + {vertex_partition_range_lasts.begin(), vertex_partition_range_lasts.size()}, + major_comm_size, + minor_comm_size}] __device__(auto val) { return key_func(thrust::get<0>(val)); }, + handle.get_stream()); + } else { + // Shuffle vertices to correct GPU to compute random indices + std::forward_as_tuple(std::tie(current_vertices, current_gpu, current_position), + std::ignore) = + cugraph::groupby_gpu_id_and_shuffle_values( + handle.get_comms(), + thrust::make_zip_iterator( + current_vertices.begin(), current_gpu.begin(), current_position.begin()), + thrust::make_zip_iterator( + current_vertices.end(), current_gpu.end(), current_position.end()), + [key_func = + cugraph::detail::compute_gpu_id_from_int_vertex_t{ + {vertex_partition_range_lasts.begin(), vertex_partition_range_lasts.size()}, + major_comm_size, + minor_comm_size}] __device__(auto val) { return key_func(thrust::get<0>(val)); }, + handle.get_stream()); + } + } + + // Sort for nbr_intersection, must sort all together + if (previous_vertices) { + if constexpr (multi_gpu) { + thrust::sort(handle.get_thrust_policy(), + thrust::make_zip_iterator(current_vertices.begin(), + (*previous_vertices).begin(), + current_position.begin(), + current_gpu.begin()), + thrust::make_zip_iterator(current_vertices.end(), + (*previous_vertices).end(), + current_position.end(), + current_gpu.end())); + } else { + thrust::sort( + handle.get_thrust_policy(), thrust::make_zip_iterator( - current_vertices.begin(), current_gpu.begin(), current_position.begin()), + current_vertices.begin(), (*previous_vertices).begin(), current_position.begin()), thrust::make_zip_iterator( - current_vertices.end(), current_gpu.end(), current_position.end()), - [key_func = - cugraph::detail::compute_gpu_id_from_int_vertex_t{ - {vertex_partition_range_lasts.begin(), vertex_partition_range_lasts.size()}, - major_comm_size, - minor_comm_size}] __device__(auto val) { return key_func(thrust::get<0>(val)); }, - handle.get_stream()); + current_vertices.end(), (*previous_vertices).end(), current_position.end())); + } } - std::tie(current_vertices, new_weights) = - random_selector.follow_random_edge(handle, graph_view, edge_weight_view, current_vertices); + std::tie(current_vertices, previous_vertices, new_weights) = + random_selector.follow_random_edge(handle, + graph_view, + edge_weight_view, + std::move(current_vertices), + std::move(previous_vertices)); // FIXME: remove_if has a 32-bit overflow issue // (https://github.com/NVIDIA/thrust/issues/1302) Seems unlikely here (the goal of @@ -281,164 +687,244 @@ random_walk_impl(raft::handle_t const& handle, CUGRAPH_EXPECTS( current_vertices.size() < static_cast(std::numeric_limits::max()), "remove_if will fail, current_vertices.size() is too large"); - + size_t compacted_length{0}; if constexpr (multi_gpu) { if (result_weights) { - auto input_iter = thrust::make_zip_iterator(current_vertices.begin(), - new_weights->begin(), - current_gpu.begin(), - current_position.begin()); - - auto compacted_length = thrust::distance( - input_iter, - thrust::remove_if(handle.get_thrust_policy(), - input_iter, - input_iter + current_vertices.size(), - current_vertices.begin(), - [] __device__(auto dst) { - return (dst == cugraph::invalid_vertex_id::value); - })); - - current_vertices.resize(compacted_length, handle.get_stream()); - new_weights->resize(compacted_length, handle.get_stream()); - current_gpu.resize(compacted_length, handle.get_stream()); - current_position.resize(compacted_length, handle.get_stream()); - - // Shuffle back to original GPU - auto current_iter = thrust::make_zip_iterator(current_vertices.begin(), + if (previous_vertices) { + auto input_iter = thrust::make_zip_iterator(current_vertices.begin(), + new_weights->begin(), + current_gpu.begin(), + current_position.begin(), + previous_vertices->begin()); + + compacted_length = thrust::distance( + input_iter, + thrust::remove_if(handle.get_thrust_policy(), + input_iter, + input_iter + current_vertices.size(), + current_vertices.begin(), + [] __device__(auto dst) { + return (dst == cugraph::invalid_vertex_id::value); + })); + } else { + auto input_iter = thrust::make_zip_iterator(current_vertices.begin(), new_weights->begin(), current_gpu.begin(), current_position.begin()); - std::forward_as_tuple( - std::tie(current_vertices, *new_weights, current_gpu, current_position), std::ignore) = - cugraph::groupby_gpu_id_and_shuffle_values( - handle.get_comms(), - current_iter, - current_iter + current_vertices.size(), - [] __device__(auto val) { return thrust::get<2>(val); }, - handle.get_stream()); - - thrust::for_each( - handle.get_thrust_policy(), - thrust::make_zip_iterator( - current_vertices.begin(), new_weights->begin(), current_position.begin()), - thrust::make_zip_iterator( - current_vertices.end(), new_weights->end(), current_position.end()), - [result_verts = result_vertices.data(), - result_wgts = result_weights->data(), - level, - max_length] __device__(auto tuple) { - vertex_t v = thrust::get<0>(tuple); - weight_t w = thrust::get<1>(tuple); - size_t pos = thrust::get<2>(tuple); - result_verts[pos * (max_length + 1) + level + 1] = v; - result_wgts[pos * max_length + level] = w; - }); + compacted_length = thrust::distance( + input_iter, + thrust::remove_if(handle.get_thrust_policy(), + input_iter, + input_iter + current_vertices.size(), + current_vertices.begin(), + [] __device__(auto dst) { + return (dst == cugraph::invalid_vertex_id::value); + })); + } } else { - auto input_iter = thrust::make_zip_iterator( - current_vertices.begin(), current_gpu.begin(), current_position.begin()); - - auto compacted_length = thrust::distance( - input_iter, - thrust::remove_if(handle.get_thrust_policy(), - input_iter, - input_iter + current_vertices.size(), - current_vertices.begin(), - [] __device__(auto dst) { - return (dst == cugraph::invalid_vertex_id::value); - })); - - current_vertices.resize(compacted_length, handle.get_stream()); - current_gpu.resize(compacted_length, handle.get_stream()); - current_position.resize(compacted_length, handle.get_stream()); - - // Shuffle back to original GPU - auto current_iter = thrust::make_zip_iterator( - current_vertices.begin(), current_gpu.begin(), current_position.begin()); - - std::forward_as_tuple(std::tie(current_vertices, current_gpu, current_position), - std::ignore) = - cugraph::groupby_gpu_id_and_shuffle_values( - handle.get_comms(), - current_iter, - current_iter + current_vertices.size(), - [] __device__(auto val) { return thrust::get<1>(val); }, - handle.get_stream()); - - thrust::for_each( - handle.get_thrust_policy(), - thrust::make_zip_iterator(current_vertices.begin(), current_position.begin()), - thrust::make_zip_iterator(current_vertices.end(), current_position.end()), - [result_verts = result_vertices.data(), level, max_length] __device__(auto tuple) { - vertex_t v = thrust::get<0>(tuple); - size_t pos = thrust::get<1>(tuple); - result_verts[pos * (max_length + 1) + level + 1] = v; - }); + if (previous_vertices) { + auto input_iter = thrust::make_zip_iterator(current_vertices.begin(), + current_gpu.begin(), + current_position.begin(), + previous_vertices->begin()); + + compacted_length = thrust::distance( + input_iter, + thrust::remove_if(handle.get_thrust_policy(), + input_iter, + input_iter + current_vertices.size(), + current_vertices.begin(), + [] __device__(auto dst) { + return (dst == cugraph::invalid_vertex_id::value); + })); + } else { + auto input_iter = thrust::make_zip_iterator( + current_vertices.begin(), current_gpu.begin(), current_position.begin()); + + compacted_length = thrust::distance( + input_iter, + thrust::remove_if(handle.get_thrust_policy(), + input_iter, + input_iter + current_vertices.size(), + current_vertices.begin(), + [] __device__(auto dst) { + return (dst == cugraph::invalid_vertex_id::value); + })); + } } } else { if (result_weights) { - auto input_iter = thrust::make_zip_iterator( - current_vertices.begin(), new_weights->begin(), current_position.begin()); - - auto compacted_length = thrust::distance( - input_iter, - thrust::remove_if(handle.get_thrust_policy(), - input_iter, - input_iter + current_vertices.size(), - current_vertices.begin(), - [] __device__(auto dst) { - return (dst == cugraph::invalid_vertex_id::value); - })); - - current_vertices.resize(compacted_length, handle.get_stream()); - new_weights->resize(compacted_length, handle.get_stream()); - current_position.resize(compacted_length, handle.get_stream()); - - thrust::for_each( - handle.get_thrust_policy(), - thrust::make_zip_iterator( - current_vertices.begin(), new_weights->begin(), current_position.begin()), - thrust::make_zip_iterator( - current_vertices.end(), new_weights->end(), current_position.end()), - [result_verts = result_vertices.data(), - result_wgts = result_weights->data(), - level, - max_length] __device__(auto tuple) { - vertex_t v = thrust::get<0>(tuple); - weight_t w = thrust::get<1>(tuple); - size_t pos = thrust::get<2>(tuple); - result_verts[pos * (max_length + 1) + level + 1] = v; - result_wgts[pos * max_length + level] = w; - }); + if (previous_vertices) { + auto input_iter = thrust::make_zip_iterator(current_vertices.begin(), + new_weights->begin(), + current_position.begin(), + previous_vertices->begin()); + + compacted_length = thrust::distance( + input_iter, + thrust::remove_if(handle.get_thrust_policy(), + input_iter, + input_iter + current_vertices.size(), + current_vertices.begin(), + [] __device__(auto dst) { + return (dst == cugraph::invalid_vertex_id::value); + })); + } else { + auto input_iter = thrust::make_zip_iterator( + current_vertices.begin(), new_weights->begin(), current_position.begin()); + + compacted_length = thrust::distance( + input_iter, + thrust::remove_if(handle.get_thrust_policy(), + input_iter, + input_iter + current_vertices.size(), + current_vertices.begin(), + [] __device__(auto dst) { + return (dst == cugraph::invalid_vertex_id::value); + })); + } } else { - auto input_iter = - thrust::make_zip_iterator(current_vertices.begin(), current_position.begin()); - - auto compacted_length = thrust::distance( - input_iter, - thrust::remove_if(handle.get_thrust_policy(), - input_iter, - input_iter + current_vertices.size(), - current_vertices.begin(), - [] __device__(auto dst) { - return (dst == cugraph::invalid_vertex_id::value); - })); - - current_vertices.resize(compacted_length, handle.get_stream()); - current_position.resize(compacted_length, handle.get_stream()); - - thrust::for_each( - handle.get_thrust_policy(), - thrust::make_zip_iterator(current_vertices.begin(), current_position.begin()), - thrust::make_zip_iterator(current_vertices.end(), current_position.end()), - [result_verts = result_vertices.data(), level, max_length] __device__(auto tuple) { - vertex_t v = thrust::get<0>(tuple); - size_t pos = thrust::get<1>(tuple); - result_verts[pos * (max_length + 1) + level + 1] = v; - }); + if (previous_vertices) { + auto input_iter = thrust::make_zip_iterator( + current_vertices.begin(), current_position.begin(), previous_vertices->begin()); + + compacted_length = thrust::distance( + input_iter, + thrust::remove_if(handle.get_thrust_policy(), + input_iter, + input_iter + current_vertices.size(), + current_vertices.begin(), + [] __device__(auto dst) { + return (dst == cugraph::invalid_vertex_id::value); + })); + } else { + auto input_iter = + thrust::make_zip_iterator(current_vertices.begin(), current_position.begin()); + + compacted_length = thrust::distance( + input_iter, + thrust::remove_if(handle.get_thrust_policy(), + input_iter, + input_iter + current_vertices.size(), + current_vertices.begin(), + [] __device__(auto dst) { + return (dst == cugraph::invalid_vertex_id::value); + })); + } + } + } + + // Moved out of if statements to cut down on code duplication + current_vertices.resize(compacted_length, handle.get_stream()); + current_vertices.shrink_to_fit(handle.get_stream()); + current_position.resize(compacted_length, handle.get_stream()); + current_position.shrink_to_fit(handle.get_stream()); + if (result_weights) { + new_weights->resize(compacted_length, handle.get_stream()); + new_weights->shrink_to_fit(handle.get_stream()); + } + if (previous_vertices) { + previous_vertices->resize(compacted_length, handle.get_stream()); + previous_vertices->shrink_to_fit(handle.get_stream()); + } + if constexpr (multi_gpu) { + current_gpu.resize(compacted_length, handle.get_stream()); + current_gpu.shrink_to_fit(handle.get_stream()); + + // Shuffle back to original GPU + if (previous_vertices) { + if (result_weights) { + auto current_iter = thrust::make_zip_iterator(current_vertices.begin(), + new_weights->begin(), + current_gpu.begin(), + current_position.begin(), + previous_vertices->begin()); + + std::forward_as_tuple( + std::tie( + current_vertices, *new_weights, current_gpu, current_position, *previous_vertices), + std::ignore) = + cugraph::groupby_gpu_id_and_shuffle_values( + handle.get_comms(), + current_iter, + current_iter + current_vertices.size(), + [] __device__(auto val) { return thrust::get<2>(val); }, + handle.get_stream()); + } else { + auto current_iter = thrust::make_zip_iterator(current_vertices.begin(), + current_gpu.begin(), + current_position.begin(), + previous_vertices->begin()); + + std::forward_as_tuple( + std::tie(current_vertices, current_gpu, current_position, *previous_vertices), + std::ignore) = + cugraph::groupby_gpu_id_and_shuffle_values( + handle.get_comms(), + current_iter, + current_iter + current_vertices.size(), + [] __device__(auto val) { return thrust::get<1>(val); }, + handle.get_stream()); + } + } else { + if (result_weights) { + auto current_iter = thrust::make_zip_iterator(current_vertices.begin(), + new_weights->begin(), + current_gpu.begin(), + current_position.begin()); + + std::forward_as_tuple( + std::tie(current_vertices, *new_weights, current_gpu, current_position), std::ignore) = + cugraph::groupby_gpu_id_and_shuffle_values( + handle.get_comms(), + current_iter, + current_iter + current_vertices.size(), + [] __device__(auto val) { return thrust::get<2>(val); }, + handle.get_stream()); + } else { + auto current_iter = thrust::make_zip_iterator( + current_vertices.begin(), current_gpu.begin(), current_position.begin()); + + std::forward_as_tuple(std::tie(current_vertices, current_gpu, current_position), + std::ignore) = + cugraph::groupby_gpu_id_and_shuffle_values( + handle.get_comms(), + current_iter, + current_iter + current_vertices.size(), + [] __device__(auto val) { return thrust::get<1>(val); }, + handle.get_stream()); + } } } + + if (result_weights) { + thrust::for_each(handle.get_thrust_policy(), + thrust::make_zip_iterator( + current_vertices.begin(), new_weights->begin(), current_position.begin()), + thrust::make_zip_iterator( + current_vertices.end(), new_weights->end(), current_position.end()), + [result_verts = result_vertices.data(), + result_wgts = result_weights->data(), + level, + max_length] __device__(auto tuple) { + vertex_t v = thrust::get<0>(tuple); + weight_t w = thrust::get<1>(tuple); + size_t pos = thrust::get<2>(tuple); + result_verts[pos * (max_length + 1) + level + 1] = v; + result_wgts[pos * max_length + level] = w; + }); + } else { + thrust::for_each( + handle.get_thrust_policy(), + thrust::make_zip_iterator(current_vertices.begin(), current_position.begin()), + thrust::make_zip_iterator(current_vertices.end(), current_position.end()), + [result_verts = result_vertices.data(), level, max_length] __device__(auto tuple) { + vertex_t v = thrust::get<0>(tuple); + size_t pos = thrust::get<1>(tuple); + result_verts[pos * (max_length + 1) + level + 1] = v; + }); + } } return std::make_tuple(std::move(result_vertices), std::move(result_weights)); @@ -449,11 +935,11 @@ random_walk_impl(raft::handle_t const& handle, template std::tuple, std::optional>> uniform_random_walks(raft::handle_t const& handle, + raft::random::RngState& rng_state, graph_view_t const& graph_view, std::optional> edge_weight_view, raft::device_span start_vertices, - size_t max_length, - uint64_t seed) + size_t max_length) { CUGRAPH_EXPECTS(!graph_view.has_edge_mask(), "unimplemented."); @@ -462,18 +948,17 @@ uniform_random_walks(raft::handle_t const& handle, edge_weight_view, start_vertices, max_length, - detail::uniform_selector( - (seed == 0 ? detail::get_current_time_nanoseconds() : seed))); + detail::uniform_selector{rng_state}); } template std::tuple, std::optional>> biased_random_walks(raft::handle_t const& handle, + raft::random::RngState& rng_state, graph_view_t const& graph_view, edge_property_view_t edge_weight_view, raft::device_span start_vertices, - size_t max_length, - uint64_t seed) + size_t max_length) { CUGRAPH_EXPECTS(!graph_view.has_edge_mask(), "unimplemented."); @@ -483,30 +968,28 @@ biased_random_walks(raft::handle_t const& handle, std::optional>{edge_weight_view}, start_vertices, max_length, - detail::biased_selector{(seed == 0 ? detail::get_current_time_nanoseconds() : seed)}); + detail::biased_selector{rng_state}); } template std::tuple, std::optional>> node2vec_random_walks(raft::handle_t const& handle, + raft::random::RngState& rng_state, graph_view_t const& graph_view, std::optional> edge_weight_view, raft::device_span start_vertices, size_t max_length, weight_t p, - weight_t q, - uint64_t seed) + weight_t q) { CUGRAPH_EXPECTS(!graph_view.has_edge_mask(), "unimplemented."); - return detail::random_walk_impl( - handle, - graph_view, - edge_weight_view, - start_vertices, - max_length, - detail::node2vec_selector{ - p, q, (seed == 0 ? detail::get_current_time_nanoseconds() : seed)}); + return detail::random_walk_impl(handle, + graph_view, + edge_weight_view, + start_vertices, + max_length, + detail::node2vec_selector{p, q, rng_state}); } } // namespace cugraph diff --git a/cpp/src/sampling/random_walks_mg_v32_e32.cu b/cpp/src/sampling/random_walks_mg_v32_e32.cu index 421d3e9c818..abe5386da1c 100644 --- a/cpp/src/sampling/random_walks_mg_v32_e32.cu +++ b/cpp/src/sampling/random_walks_mg_v32_e32.cu @@ -22,54 +22,54 @@ namespace cugraph { template std::tuple, std::optional>> uniform_random_walks(raft::handle_t const& handle, + raft::random::RngState& rng_state, graph_view_t const& graph_view, std::optional> edge_weight_view, raft::device_span start_vertices, - size_t max_length, - uint64_t seed); + size_t max_length); template std::tuple, std::optional>> uniform_random_walks(raft::handle_t const& handle, + raft::random::RngState& rng_state, graph_view_t const& graph_view, std::optional> edge_weight_view, raft::device_span start_vertices, - size_t max_length, - uint64_t seed); + size_t max_length); template std::tuple, std::optional>> biased_random_walks(raft::handle_t const& handle, + raft::random::RngState& rng_state, graph_view_t const& graph_view, edge_property_view_t edge_weight_view, raft::device_span start_vertices, - size_t max_length, - uint64_t seed); + size_t max_length); template std::tuple, std::optional>> biased_random_walks(raft::handle_t const& handle, + raft::random::RngState& rng_state, graph_view_t const& graph_view, edge_property_view_t edge_weight_view, raft::device_span start_vertices, - size_t max_length, - uint64_t seed); + size_t max_length); template std::tuple, std::optional>> node2vec_random_walks(raft::handle_t const& handle, + raft::random::RngState& rng_state, graph_view_t const& graph_view, std::optional> edge_weight_view, raft::device_span start_vertices, size_t max_length, float p, - float q, - uint64_t seed); + float q); template std::tuple, std::optional>> node2vec_random_walks(raft::handle_t const& handle, + raft::random::RngState& rng_state, graph_view_t const& graph_view, std::optional> edge_weight_view, raft::device_span start_vertices, size_t max_length, double p, - double q, - uint64_t seed); + double q); } // namespace cugraph diff --git a/cpp/src/sampling/random_walks_mg_v32_e64.cu b/cpp/src/sampling/random_walks_mg_v32_e64.cu deleted file mode 100644 index d38af65a505..00000000000 --- a/cpp/src/sampling/random_walks_mg_v32_e64.cu +++ /dev/null @@ -1,75 +0,0 @@ -/* - * 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. - * 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. - */ - -#include "sampling/random_walks_impl.cuh" - -#include - -namespace cugraph { - -template std::tuple, std::optional>> -uniform_random_walks(raft::handle_t const& handle, - graph_view_t const& graph_view, - std::optional> edge_weight_view, - raft::device_span start_vertices, - size_t max_length, - uint64_t seed); - -template std::tuple, std::optional>> -uniform_random_walks(raft::handle_t const& handle, - graph_view_t const& graph_view, - std::optional> edge_weight_view, - raft::device_span start_vertices, - size_t max_length, - uint64_t seed); - -template std::tuple, std::optional>> -biased_random_walks(raft::handle_t const& handle, - graph_view_t const& graph_view, - edge_property_view_t edge_weight_view, - raft::device_span start_vertices, - size_t max_length, - uint64_t seed); - -template std::tuple, std::optional>> -biased_random_walks(raft::handle_t const& handle, - graph_view_t const& graph_view, - edge_property_view_t edge_weight_view, - raft::device_span start_vertices, - size_t max_length, - uint64_t seed); - -template std::tuple, std::optional>> -node2vec_random_walks(raft::handle_t const& handle, - graph_view_t const& graph_view, - std::optional> edge_weight_view, - raft::device_span start_vertices, - size_t max_length, - float p, - float q, - uint64_t seed); - -template std::tuple, std::optional>> -node2vec_random_walks(raft::handle_t const& handle, - graph_view_t const& graph_view, - std::optional> edge_weight_view, - raft::device_span start_vertices, - size_t max_length, - double p, - double q, - uint64_t seed); - -} // namespace cugraph diff --git a/cpp/src/sampling/random_walks_mg_v64_e64.cu b/cpp/src/sampling/random_walks_mg_v64_e64.cu index 9dedc893242..13cc899e50d 100644 --- a/cpp/src/sampling/random_walks_mg_v64_e64.cu +++ b/cpp/src/sampling/random_walks_mg_v64_e64.cu @@ -22,54 +22,54 @@ namespace cugraph { template std::tuple, std::optional>> uniform_random_walks(raft::handle_t const& handle, + raft::random::RngState& rng_state, graph_view_t const& graph_view, std::optional> edge_weight_view, raft::device_span start_vertices, - size_t max_length, - uint64_t seed); + size_t max_length); template std::tuple, std::optional>> uniform_random_walks(raft::handle_t const& handle, + raft::random::RngState& rng_state, graph_view_t const& graph_view, std::optional> edge_weight_view, raft::device_span start_vertices, - size_t max_length, - uint64_t seed); + size_t max_length); template std::tuple, std::optional>> biased_random_walks(raft::handle_t const& handle, + raft::random::RngState& rng_state, graph_view_t const& graph_view, edge_property_view_t edge_weight_view, raft::device_span start_vertices, - size_t max_length, - uint64_t seed); + size_t max_length); template std::tuple, std::optional>> biased_random_walks(raft::handle_t const& handle, + raft::random::RngState& rng_state, graph_view_t const& graph_view, edge_property_view_t edge_weight_view, raft::device_span start_vertices, - size_t max_length, - uint64_t seed); + size_t max_length); template std::tuple, std::optional>> node2vec_random_walks(raft::handle_t const& handle, + raft::random::RngState& rng_state, graph_view_t const& graph_view, std::optional> edge_weight_view, raft::device_span start_vertices, size_t max_length, float p, - float q, - uint64_t seed); + float q); template std::tuple, std::optional>> node2vec_random_walks(raft::handle_t const& handle, + raft::random::RngState& rng_state, graph_view_t const& graph_view, std::optional> edge_weight_view, raft::device_span start_vertices, size_t max_length, double p, - double q, - uint64_t seed); + double q); } // namespace cugraph diff --git a/cpp/src/sampling/random_walks_old_sg.cu b/cpp/src/sampling/random_walks_old_sg.cu index 0e612163715..d5079231f51 100644 --- a/cpp/src/sampling/random_walks_old_sg.cu +++ b/cpp/src/sampling/random_walks_old_sg.cu @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021-2022, 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. @@ -33,17 +33,6 @@ template std:: bool use_padding, std::unique_ptr sampling_strategy); -template std:: - tuple, rmm::device_uvector, rmm::device_uvector> - random_walks(raft::handle_t const& handle, - graph_view_t const& gview, - std::optional> edge_weight_view, - int32_t const* ptr_d_start, - int64_t num_paths, - int64_t max_depth, - bool use_padding, - std::unique_ptr sampling_strategy); - template std:: tuple, rmm::device_uvector, rmm::device_uvector> random_walks(raft::handle_t const& handle, @@ -68,17 +57,6 @@ template std:: bool use_padding, std::unique_ptr sampling_strategy); -template std:: - tuple, rmm::device_uvector, rmm::device_uvector> - random_walks(raft::handle_t const& handle, - graph_view_t const& gview, - std::optional> edge_weight_view, - int32_t const* ptr_d_start, - int64_t num_paths, - int64_t max_depth, - bool use_padding, - std::unique_ptr sampling_strategy); - template std:: tuple, rmm::device_uvector, rmm::device_uvector> random_walks(raft::handle_t const& handle, diff --git a/cpp/src/sampling/random_walks_old_sg_v32_e64.cu b/cpp/src/sampling/random_walks_old_sg_v32_e64.cu deleted file mode 100644 index 7dfbf964587..00000000000 --- a/cpp/src/sampling/random_walks_old_sg_v32_e64.cu +++ /dev/null @@ -1,54 +0,0 @@ -/* - * Copyright (c) 2021-2024, NVIDIA CORPORATION. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * 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. - */ - -// Andrei Schaffer, aschaffer@nvidia.com -// -#include "random_walks.cuh" - -namespace cugraph { -// template explicit instantiation directives (EIDir's): - -template std:: - tuple, rmm::device_uvector, rmm::device_uvector> - random_walks(raft::handle_t const& handle, - graph_view_t const& gview, - std::optional> edge_weight_view, - int32_t const* ptr_d_start, - int64_t num_paths, - int64_t max_depth, - bool use_padding, - std::unique_ptr sampling_strategy); - -template std:: - tuple, rmm::device_uvector, rmm::device_uvector> - random_walks(raft::handle_t const& handle, - graph_view_t const& gview, - std::optional> edge_weight_view, - int32_t const* ptr_d_start, - int64_t num_paths, - int64_t max_depth, - bool use_padding, - std::unique_ptr sampling_strategy); - -template std:: - tuple, rmm::device_uvector, rmm::device_uvector> - convert_paths_to_coo(raft::handle_t const& handle, - int64_t coalesced_sz_v, - int64_t num_paths, - rmm::device_buffer&& d_coalesced_v, - rmm::device_buffer&& d_sizes); - -} // namespace cugraph diff --git a/cpp/src/sampling/random_walks_sg_v32_e32.cu b/cpp/src/sampling/random_walks_sg_v32_e32.cu index 7b64d107250..383917c0248 100644 --- a/cpp/src/sampling/random_walks_sg_v32_e32.cu +++ b/cpp/src/sampling/random_walks_sg_v32_e32.cu @@ -22,54 +22,54 @@ namespace cugraph { template std::tuple, std::optional>> uniform_random_walks(raft::handle_t const& handle, + raft::random::RngState& rng_state, graph_view_t const& graph_view, std::optional> edge_weight_view, raft::device_span start_vertices, - size_t max_length, - uint64_t seed); + size_t max_length); template std::tuple, std::optional>> uniform_random_walks(raft::handle_t const& handle, + raft::random::RngState& rng_state, graph_view_t const& graph_view, std::optional> edge_weight_view, raft::device_span start_vertices, - size_t max_length, - uint64_t seed); + size_t max_length); template std::tuple, std::optional>> biased_random_walks(raft::handle_t const& handle, + raft::random::RngState& rng_state, graph_view_t const& graph_view, edge_property_view_t edge_weight_view, raft::device_span start_vertices, - size_t max_length, - uint64_t seed); + size_t max_length); template std::tuple, std::optional>> biased_random_walks(raft::handle_t const& handle, + raft::random::RngState& rng_state, graph_view_t const& graph_view, edge_property_view_t edge_weight_view, raft::device_span start_vertices, - size_t max_length, - uint64_t seed); + size_t max_length); template std::tuple, std::optional>> node2vec_random_walks(raft::handle_t const& handle, + raft::random::RngState& rng_state, graph_view_t const& graph_view, std::optional> edge_weight_view, raft::device_span start_vertices, size_t max_length, float p, - float q, - uint64_t seed); + float q); template std::tuple, std::optional>> node2vec_random_walks(raft::handle_t const& handle, + raft::random::RngState& rng_state, graph_view_t const& graph_view, std::optional> edge_weight_view, raft::device_span start_vertices, size_t max_length, double p, - double q, - uint64_t seed); + double q); } // namespace cugraph diff --git a/cpp/src/sampling/random_walks_sg_v32_e64.cu b/cpp/src/sampling/random_walks_sg_v32_e64.cu deleted file mode 100644 index d9ea09f36ef..00000000000 --- a/cpp/src/sampling/random_walks_sg_v32_e64.cu +++ /dev/null @@ -1,75 +0,0 @@ -/* - * 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. - * 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. - */ - -#include "sampling/random_walks_impl.cuh" - -#include - -namespace cugraph { - -template std::tuple, std::optional>> -uniform_random_walks(raft::handle_t const& handle, - graph_view_t const& graph_view, - std::optional> edge_weight_view, - raft::device_span start_vertices, - size_t max_length, - uint64_t seed); - -template std::tuple, std::optional>> -uniform_random_walks(raft::handle_t const& handle, - graph_view_t const& graph_view, - std::optional> edge_weight_view, - raft::device_span start_vertices, - size_t max_length, - uint64_t seed); - -template std::tuple, std::optional>> -biased_random_walks(raft::handle_t const& handle, - graph_view_t const& graph_view, - edge_property_view_t edge_weight_view, - raft::device_span start_vertices, - size_t max_length, - uint64_t seed); - -template std::tuple, std::optional>> -biased_random_walks(raft::handle_t const& handle, - graph_view_t const& graph_view, - edge_property_view_t edge_weight_view, - raft::device_span start_vertices, - size_t max_length, - uint64_t seed); - -template std::tuple, std::optional>> -node2vec_random_walks(raft::handle_t const& handle, - graph_view_t const& graph_view, - std::optional> edge_weight_view, - raft::device_span start_vertices, - size_t max_length, - float p, - float q, - uint64_t seed); - -template std::tuple, std::optional>> -node2vec_random_walks(raft::handle_t const& handle, - graph_view_t const& graph_view, - std::optional> edge_weight_view, - raft::device_span start_vertices, - size_t max_length, - double p, - double q, - uint64_t seed); - -} // namespace cugraph diff --git a/cpp/src/sampling/random_walks_sg_v64_e64.cu b/cpp/src/sampling/random_walks_sg_v64_e64.cu index 0b9be107276..c139acec4b7 100644 --- a/cpp/src/sampling/random_walks_sg_v64_e64.cu +++ b/cpp/src/sampling/random_walks_sg_v64_e64.cu @@ -22,54 +22,54 @@ namespace cugraph { template std::tuple, std::optional>> uniform_random_walks(raft::handle_t const& handle, + raft::random::RngState& rng_state, graph_view_t const& graph_view, std::optional> edge_weight_view, raft::device_span start_vertices, - size_t max_length, - uint64_t seed); + size_t max_length); template std::tuple, std::optional>> uniform_random_walks(raft::handle_t const& handle, + raft::random::RngState& rng_state, graph_view_t const& graph_view, std::optional> edge_weight_view, raft::device_span start_vertices, - size_t max_length, - uint64_t seed); + size_t max_length); template std::tuple, std::optional>> biased_random_walks(raft::handle_t const& handle, + raft::random::RngState& rng_state, graph_view_t const& graph_view, edge_property_view_t edge_weight_view, raft::device_span start_vertices, - size_t max_length, - uint64_t seed); + size_t max_length); template std::tuple, std::optional>> biased_random_walks(raft::handle_t const& handle, + raft::random::RngState& rng_state, graph_view_t const& graph_view, edge_property_view_t edge_weight_view, raft::device_span start_vertices, - size_t max_length, - uint64_t seed); + size_t max_length); template std::tuple, std::optional>> node2vec_random_walks(raft::handle_t const& handle, + raft::random::RngState& rng_state, graph_view_t const& graph_view, std::optional> edge_weight_view, raft::device_span start_vertices, size_t max_length, float p, - float q, - uint64_t seed); + float q); template std::tuple, std::optional>> node2vec_random_walks(raft::handle_t const& handle, + raft::random::RngState& rng_state, graph_view_t const& graph_view, std::optional> edge_weight_view, raft::device_span start_vertices, size_t max_length, double p, - double q, - uint64_t seed); + double q); } // namespace cugraph diff --git a/cpp/src/sampling/sampling_post_processing_sg_v32_e64.cu b/cpp/src/sampling/sampling_post_processing_sg_v32_e64.cu deleted file mode 100644 index 7001dcfdaf3..00000000000 --- a/cpp/src/sampling/sampling_post_processing_sg_v32_e64.cu +++ /dev/null @@ -1,219 +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. - */ - -#include "sampling_post_processing_impl.cuh" - -#include - -namespace cugraph { - -template std::tuple>, - rmm::device_uvector, - rmm::device_uvector, - std::optional>, - std::optional>, - std::optional>, - std::optional>, - rmm::device_uvector, - std::optional>> -renumber_and_compress_sampled_edgelist( - raft::handle_t const& handle, - rmm::device_uvector&& edgelist_srcs, - rmm::device_uvector&& edgelist_dsts, - std::optional>&& edgelist_weights, - std::optional>&& edgelist_edge_ids, - std::optional>&& edgelist_edge_types, - std::optional>&& edgelist_hops, - std::optional> seed_vertices, - std::optional> seed_vertex_label_offsets, - std::optional> edgelist_label_offsets, - size_t num_labels, - size_t num_hops, - bool src_is_major, - bool compress_per_hop, - bool doubly_compress, - bool do_expensive_check); - -template std::tuple>, - rmm::device_uvector, - rmm::device_uvector, - std::optional>, - std::optional>, - std::optional>, - std::optional>, - rmm::device_uvector, - std::optional>> -renumber_and_compress_sampled_edgelist( - raft::handle_t const& handle, - rmm::device_uvector&& edgelist_srcs, - rmm::device_uvector&& edgelist_dsts, - std::optional>&& edgelist_weights, - std::optional>&& edgelist_edge_ids, - std::optional>&& edgelist_edge_types, - std::optional>&& edgelist_hops, - std::optional> seed_vertices, - std::optional> seed_vertex_label_offsets, - std::optional> edgelist_label_offsets, - size_t num_labels, - size_t num_hops, - bool src_is_major, - bool compress_per_hop, - bool doubly_compress, - bool do_expensive_check); - -template std::tuple, - rmm::device_uvector, - std::optional>, - std::optional>, - std::optional>, - std::optional>, - rmm::device_uvector, - std::optional>> -renumber_and_sort_sampled_edgelist( - raft::handle_t const& handle, - rmm::device_uvector&& edgelist_srcs, - rmm::device_uvector&& edgelist_dsts, - std::optional>&& edgelist_weights, - std::optional>&& edgelist_edge_ids, - std::optional>&& edgelist_edge_types, - std::optional>&& edgelist_hops, - std::optional> seed_vertices, - std::optional> seed_vertex_label_offsets, - std::optional> edgelist_label_offsets, - size_t num_labels, - size_t num_hops, - bool src_is_major, - bool do_expensive_check); - -template std::tuple, - rmm::device_uvector, - std::optional>, - std::optional>, - std::optional>, - std::optional>, - rmm::device_uvector, - std::optional>> -renumber_and_sort_sampled_edgelist( - raft::handle_t const& handle, - rmm::device_uvector&& edgelist_srcs, - rmm::device_uvector&& edgelist_dsts, - std::optional>&& edgelist_weights, - std::optional>&& edgelist_edge_ids, - std::optional>&& edgelist_edge_types, - std::optional>&& edgelist_hops, - std::optional> seed_vertices, - std::optional> seed_vertex_label_offsets, - std::optional> edgelist_label_offsets, - size_t num_labels, - size_t num_hops, - bool src_is_major, - bool do_expensive_check); - -template std::tuple, - rmm::device_uvector, - std::optional>, - std::optional>, - std::optional>, - rmm::device_uvector, - rmm::device_uvector, - std::optional>, - std::optional>> -heterogeneous_renumber_and_sort_sampled_edgelist( - raft::handle_t const& handle, - rmm::device_uvector&& edgelist_srcs, - rmm::device_uvector&& edgelist_dsts, - std::optional>&& edgelist_weights, - std::optional>&& edgelist_edge_ids, - std::optional>&& edgelist_edge_types, - std::optional>&& edgelist_hops, - std::optional> seed_vertices, - std::optional> seed_vertex_label_offsets, - std::optional> edgelist_label_offsets, - raft::device_span vertex_type_offsets, - size_t num_labels, - size_t num_hops, - size_t num_vertex_types, - size_t num_edge_types, - bool src_is_major, - bool do_expensive_check); - -template std::tuple, - rmm::device_uvector, - std::optional>, - std::optional>, - std::optional>, - rmm::device_uvector, - rmm::device_uvector, - std::optional>, - std::optional>> -heterogeneous_renumber_and_sort_sampled_edgelist( - raft::handle_t const& handle, - rmm::device_uvector&& edgelist_srcs, - rmm::device_uvector&& edgelist_dsts, - std::optional>&& edgelist_weights, - std::optional>&& edgelist_edge_ids, - std::optional>&& edgelist_edge_types, - std::optional>&& edgelist_hops, - std::optional> seed_vertices, - std::optional> seed_vertex_label_offsets, - std::optional> edgelist_label_offsets, - raft::device_span vertex_type_offsets, - size_t num_labels, - size_t num_hops, - size_t num_vertex_types, - size_t num_edge_types, - bool src_is_major, - bool do_expensive_check); - -template std::tuple, - rmm::device_uvector, - std::optional>, - std::optional>, - std::optional>, - std::optional>> -sort_sampled_edgelist(raft::handle_t const& handle, - rmm::device_uvector&& edgelist_srcs, - rmm::device_uvector&& edgelist_dsts, - std::optional>&& edgelist_weights, - std::optional>&& edgelist_edge_ids, - std::optional>&& edgelist_edge_types, - std::optional>&& edgelist_hops, - std::optional> edgelist_label_offsets, - size_t num_labels, - size_t num_hops, - bool src_is_major, - bool do_expensive_check); - -template std::tuple, - rmm::device_uvector, - std::optional>, - std::optional>, - std::optional>, - std::optional>> -sort_sampled_edgelist(raft::handle_t const& handle, - rmm::device_uvector&& edgelist_srcs, - rmm::device_uvector&& edgelist_dsts, - std::optional>&& edgelist_weights, - std::optional>&& edgelist_edge_ids, - std::optional>&& edgelist_edge_types, - std::optional>&& edgelist_hops, - std::optional> edgelist_label_offsets, - size_t num_labels, - size_t num_hops, - bool src_is_major, - bool do_expensive_check); - -} // namespace cugraph diff --git a/cpp/src/structure/coarsen_graph_mg_v32_e64.cu b/cpp/src/structure/coarsen_graph_mg_v32_e64.cu deleted file mode 100644 index c41d1071304..00000000000 --- a/cpp/src/structure/coarsen_graph_mg_v32_e64.cu +++ /dev/null @@ -1,66 +0,0 @@ -/* - * Copyright (c) 2021-2024, NVIDIA CORPORATION. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * 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. - */ -#include "structure/coarsen_graph_impl.cuh" - -namespace cugraph { - -// MG instantiation - -template std::tuple< - graph_t, - std::optional, float>>, - std::optional>> -coarsen_graph(raft::handle_t const& handle, - graph_view_t const& graph_view, - std::optional> edge_weight_view, - int32_t const* labels, - bool renumber, - bool do_expensive_check); - -template std::tuple< - graph_t, - std::optional, float>>, - std::optional>> -coarsen_graph(raft::handle_t const& handle, - graph_view_t const& graph_view, - std::optional> edge_weight_view, - int32_t const* labels, - bool renumber, - bool do_expensive_check); - -template std::tuple< - graph_t, - std::optional, double>>, - std::optional>> -coarsen_graph(raft::handle_t const& handle, - graph_view_t const& graph_view, - std::optional> edge_weight_view, - int32_t const* labels, - bool renumber, - bool do_expensive_check); - -template std::tuple< - graph_t, - std::optional, double>>, - std::optional>> -coarsen_graph(raft::handle_t const& handle, - graph_view_t const& graph_view, - std::optional> edge_weight_view, - int32_t const* labels, - bool renumber, - bool do_expensive_check); - -} // namespace cugraph diff --git a/cpp/src/structure/coarsen_graph_sg_v32_e64.cu b/cpp/src/structure/coarsen_graph_sg_v32_e64.cu deleted file mode 100644 index 317bd5a3588..00000000000 --- a/cpp/src/structure/coarsen_graph_sg_v32_e64.cu +++ /dev/null @@ -1,66 +0,0 @@ -/* - * Copyright (c) 2021-2024, NVIDIA CORPORATION. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * 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. - */ -#include "structure/coarsen_graph_impl.cuh" - -namespace cugraph { - -// SG instantiation - -template std::tuple< - graph_t, - std::optional, float>>, - std::optional>> -coarsen_graph(raft::handle_t const& handle, - graph_view_t const& graph_view, - std::optional> edge_weight_view, - int32_t const* labels, - bool renumber, - bool do_expensive_check); - -template std::tuple< - graph_t, - std::optional, float>>, - std::optional>> -coarsen_graph(raft::handle_t const& handle, - graph_view_t const& graph_view, - std::optional> edge_weight_view, - int32_t const* labels, - bool renumber, - bool do_expensive_check); - -template std::tuple< - graph_t, - std::optional, double>>, - std::optional>> -coarsen_graph(raft::handle_t const& handle, - graph_view_t const& graph_view, - std::optional> edge_weight_view, - int32_t const* labels, - bool renumber, - bool do_expensive_check); - -template std::tuple< - graph_t, - std::optional, double>>, - std::optional>> -coarsen_graph(raft::handle_t const& handle, - graph_view_t const& graph_view, - std::optional> edge_weight_view, - int32_t const* labels, - bool renumber, - bool do_expensive_check); - -} // namespace cugraph diff --git a/cpp/src/structure/create_graph_from_edgelist_mg_v32_e64.cu b/cpp/src/structure/create_graph_from_edgelist_mg_v32_e64.cu deleted file mode 100644 index 380d3474292..00000000000 --- a/cpp/src/structure/create_graph_from_edgelist_mg_v32_e64.cu +++ /dev/null @@ -1,189 +0,0 @@ -/* - * Copyright (c) 2021-2024, NVIDIA CORPORATION. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * 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. - */ -#include "structure/create_graph_from_edgelist_impl.cuh" - -namespace cugraph { - -// explicit instantiations - -template std::tuple< - cugraph::graph_t, - std::optional< - cugraph::edge_property_t, float>>, - std::optional< - cugraph::edge_property_t, int64_t>>, - std::optional< - cugraph::edge_property_t, int32_t>>, - std::optional>> -create_graph_from_edgelist( - raft::handle_t const& handle, - std::optional>&& vertices, - rmm::device_uvector&& edgelist_srcs, - rmm::device_uvector&& edgelist_dsts, - std::optional>&& edgelist_weights, - std::optional>&& edgelist_edge_ids, - std::optional>&& edgelist_edge_types, - graph_properties_t graph_properties, - bool renumber, - bool do_expensive_check); - -template std::tuple< - cugraph::graph_t, - std::optional< - cugraph::edge_property_t, float>>, - std::optional< - cugraph::edge_property_t, int64_t>>, - std::optional< - cugraph::edge_property_t, int32_t>>, - std::optional>> -create_graph_from_edgelist( - raft::handle_t const& handle, - std::optional>&& vertices, - rmm::device_uvector&& edgelist_srcs, - rmm::device_uvector&& edgelist_dsts, - std::optional>&& edgelist_weights, - std::optional>&& edgelist_edge_ids, - std::optional>&& edgelist_edge_types, - graph_properties_t graph_properties, - bool renumber, - bool do_expensive_check); - -template std::tuple< - cugraph::graph_t, - std::optional< - cugraph::edge_property_t, double>>, - std::optional< - cugraph::edge_property_t, int64_t>>, - std::optional< - cugraph::edge_property_t, int32_t>>, - std::optional>> -create_graph_from_edgelist( - raft::handle_t const& handle, - std::optional>&& vertices, - rmm::device_uvector&& edgelist_srcs, - rmm::device_uvector&& edgelist_dsts, - std::optional>&& edgelist_weights, - std::optional>&& edgelist_edge_ids, - std::optional>&& edgelist_edge_types, - graph_properties_t graph_properties, - bool renumber, - bool do_expensive_check); - -template std::tuple< - cugraph::graph_t, - std::optional< - cugraph::edge_property_t, double>>, - std::optional< - cugraph::edge_property_t, int64_t>>, - std::optional< - cugraph::edge_property_t, int32_t>>, - std::optional>> -create_graph_from_edgelist( - raft::handle_t const& handle, - std::optional>&& vertices, - rmm::device_uvector&& edgelist_srcs, - rmm::device_uvector&& edgelist_dsts, - std::optional>&& edgelist_weights, - std::optional>&& edgelist_edge_ids, - std::optional>&& edgelist_edge_types, - graph_properties_t graph_properties, - bool renumber, - bool do_expensive_check); - -template std::tuple< - cugraph::graph_t, - std::optional< - cugraph::edge_property_t, float>>, - std::optional< - cugraph::edge_property_t, int64_t>>, - std::optional< - cugraph::edge_property_t, int32_t>>, - std::optional>> -create_graph_from_edgelist( - raft::handle_t const& handle, - std::optional>&& vertices, - std::vector>&& edgelist_srcs, - std::vector>&& edgelist_dsts, - std::optional>>&& edgelist_weights, - std::optional>>&& edgelist_edge_ids, - std::optional>>&& edgelist_edge_types, - graph_properties_t graph_properties, - bool renumber, - bool do_expensive_check); - -template std::tuple< - cugraph::graph_t, - std::optional< - cugraph::edge_property_t, float>>, - std::optional< - cugraph::edge_property_t, int64_t>>, - std::optional< - cugraph::edge_property_t, int32_t>>, - std::optional>> -create_graph_from_edgelist( - raft::handle_t const& handle, - std::optional>&& vertices, - std::vector>&& edgelist_srcs, - std::vector>&& edgelist_dsts, - std::optional>>&& edgelist_weights, - std::optional>>&& edgelist_edge_ids, - std::optional>>&& edgelist_edge_types, - graph_properties_t graph_properties, - bool renumber, - bool do_expensive_check); - -template std::tuple< - cugraph::graph_t, - std::optional< - cugraph::edge_property_t, double>>, - std::optional< - cugraph::edge_property_t, int64_t>>, - std::optional< - cugraph::edge_property_t, int32_t>>, - std::optional>> -create_graph_from_edgelist( - raft::handle_t const& handle, - std::optional>&& vertices, - std::vector>&& edgelist_srcs, - std::vector>&& edgelist_dsts, - std::optional>>&& edgelist_weights, - std::optional>>&& edgelist_edge_ids, - std::optional>>&& edgelist_edge_types, - graph_properties_t graph_properties, - bool renumber, - bool do_expensive_check); - -template std::tuple< - cugraph::graph_t, - std::optional< - cugraph::edge_property_t, double>>, - std::optional< - cugraph::edge_property_t, int64_t>>, - std::optional< - cugraph::edge_property_t, int32_t>>, - std::optional>> -create_graph_from_edgelist( - raft::handle_t const& handle, - std::optional>&& vertices, - std::vector>&& edgelist_srcs, - std::vector>&& edgelist_dsts, - std::optional>>&& edgelist_weights, - std::optional>>&& edgelist_edge_ids, - std::optional>>&& edgelist_edge_types, - graph_properties_t graph_properties, - bool renumber, - bool do_expensive_check); -} // namespace cugraph diff --git a/cpp/src/structure/create_graph_from_edgelist_sg_v32_e64.cu b/cpp/src/structure/create_graph_from_edgelist_sg_v32_e64.cu deleted file mode 100644 index 71bd74c1a44..00000000000 --- a/cpp/src/structure/create_graph_from_edgelist_sg_v32_e64.cu +++ /dev/null @@ -1,190 +0,0 @@ -/* - * Copyright (c) 2021-2024, NVIDIA CORPORATION. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * 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. - */ -#include "structure/create_graph_from_edgelist_impl.cuh" - -namespace cugraph { - -// explicit instantiations - -template std::tuple< - cugraph::graph_t, - std::optional< - cugraph::edge_property_t, float>>, - std::optional< - cugraph::edge_property_t, int64_t>>, - std::optional< - cugraph::edge_property_t, int32_t>>, - std::optional>> -create_graph_from_edgelist( - raft::handle_t const& handle, - std::optional>&& vertices, - rmm::device_uvector&& edgelist_srcs, - rmm::device_uvector&& edgelist_dsts, - std::optional>&& edgelist_weights, - std::optional>&& edgelist_edge_ids, - std::optional>&& edgelist_edge_types, - graph_properties_t graph_properties, - bool renumber, - bool do_expensive_check); - -template std::tuple< - cugraph::graph_t, - std::optional< - cugraph::edge_property_t, float>>, - std::optional< - cugraph::edge_property_t, int64_t>>, - std::optional< - cugraph::edge_property_t, int32_t>>, - std::optional>> -create_graph_from_edgelist( - raft::handle_t const& handle, - std::optional>&& vertices, - rmm::device_uvector&& edgelist_srcs, - rmm::device_uvector&& edgelist_dsts, - std::optional>&& edgelist_weights, - std::optional>&& edgelist_edge_ids, - std::optional>&& edgelist_edge_types, - graph_properties_t graph_properties, - bool renumber, - bool do_expensive_check); - -template std::tuple< - cugraph::graph_t, - std::optional< - cugraph::edge_property_t, double>>, - std::optional< - cugraph::edge_property_t, int64_t>>, - std::optional< - cugraph::edge_property_t, int32_t>>, - std::optional>> -create_graph_from_edgelist( - raft::handle_t const& handle, - std::optional>&& vertices, - rmm::device_uvector&& edgelist_srcs, - rmm::device_uvector&& edgelist_dsts, - std::optional>&& edgelist_weights, - std::optional>&& edgelist_edge_ids, - std::optional>&& edgelist_edge_types, - graph_properties_t graph_properties, - bool renumber, - bool do_expensive_check); - -template std::tuple< - cugraph::graph_t, - std::optional< - cugraph::edge_property_t, double>>, - std::optional< - cugraph::edge_property_t, int64_t>>, - std::optional< - cugraph::edge_property_t, int32_t>>, - std::optional>> -create_graph_from_edgelist( - raft::handle_t const& handle, - std::optional>&& vertices, - rmm::device_uvector&& edgelist_srcs, - rmm::device_uvector&& edgelist_dsts, - std::optional>&& edgelist_weights, - std::optional>&& edgelist_edge_ids, - std::optional>&& edgelist_edge_types, - graph_properties_t graph_properties, - bool renumber, - bool do_expensive_check); - -template std::tuple< - cugraph::graph_t, - std::optional< - cugraph::edge_property_t, float>>, - std::optional< - cugraph::edge_property_t, int64_t>>, - std::optional< - cugraph::edge_property_t, int32_t>>, - std::optional>> -create_graph_from_edgelist( - raft::handle_t const& handle, - std::optional>&& vertices, - std::vector>&& edgelist_srcs, - std::vector>&& edgelist_dsts, - std::optional>>&& edgelist_weights, - std::optional>>&& edgelist_edge_ids, - std::optional>>&& edgelist_edge_types, - graph_properties_t graph_properties, - bool renumber, - bool do_expensive_check); - -template std::tuple< - cugraph::graph_t, - std::optional< - cugraph::edge_property_t, float>>, - std::optional< - cugraph::edge_property_t, int64_t>>, - std::optional< - cugraph::edge_property_t, int32_t>>, - std::optional>> -create_graph_from_edgelist( - raft::handle_t const& handle, - std::optional>&& vertices, - std::vector>&& edgelist_srcs, - std::vector>&& edgelist_dsts, - std::optional>>&& edgelist_weights, - std::optional>>&& edgelist_edge_ids, - std::optional>>&& edgelist_edge_types, - graph_properties_t graph_properties, - bool renumber, - bool do_expensive_check); - -template std::tuple< - cugraph::graph_t, - std::optional< - cugraph::edge_property_t, double>>, - std::optional< - cugraph::edge_property_t, int64_t>>, - std::optional< - cugraph::edge_property_t, int32_t>>, - std::optional>> -create_graph_from_edgelist( - raft::handle_t const& handle, - std::optional>&& vertices, - std::vector>&& edgelist_srcs, - std::vector>&& edgelist_dsts, - std::optional>>&& edgelist_weights, - std::optional>>&& edgelist_edge_ids, - std::optional>>&& edgelist_edge_types, - graph_properties_t graph_properties, - bool renumber, - bool do_expensive_check); - -template std::tuple< - cugraph::graph_t, - std::optional< - cugraph::edge_property_t, double>>, - std::optional< - cugraph::edge_property_t, int64_t>>, - std::optional< - cugraph::edge_property_t, int32_t>>, - std::optional>> -create_graph_from_edgelist( - raft::handle_t const& handle, - std::optional>&& vertices, - std::vector>&& edgelist_srcs, - std::vector>&& edgelist_dsts, - std::optional>>&& edgelist_weights, - std::optional>>&& edgelist_edge_ids, - std::optional>>&& edgelist_edge_types, - graph_properties_t graph_properties, - bool renumber, - bool do_expensive_check); - -} // namespace cugraph diff --git a/cpp/src/structure/decompress_to_edgelist_mg_v32_e64.cu b/cpp/src/structure/decompress_to_edgelist_mg_v32_e64.cu deleted file mode 100644 index 082b058c3ae..00000000000 --- a/cpp/src/structure/decompress_to_edgelist_mg_v32_e64.cu +++ /dev/null @@ -1,78 +0,0 @@ -/* - * Copyright (c) 2021-2024, NVIDIA CORPORATION. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * 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. - */ -#include "structure/decompress_to_edgelist_impl.cuh" - -namespace cugraph { - -// MG instantiation - -template std::tuple, - rmm::device_uvector, - std::optional>, - std::optional>, - std::optional>> -decompress_to_edgelist( - raft::handle_t const& handle, - graph_view_t const& graph_view, - std::optional> edge_weight_view, - std::optional> edge_id_view, - std::optional> edge_type_view, - std::optional> renumber_map, - bool do_expensive_check); - -template std::tuple, - rmm::device_uvector, - std::optional>, - std::optional>, - std::optional>> -decompress_to_edgelist( - raft::handle_t const& handle, - graph_view_t const& graph_view, - std::optional> edge_weight_view, - std::optional> edge_id_view, - std::optional> edge_type_view, - std::optional> renumber_map, - bool do_expensive_check); - -template std::tuple, - rmm::device_uvector, - std::optional>, - std::optional>, - std::optional>> -decompress_to_edgelist( - raft::handle_t const& handle, - graph_view_t const& graph_view, - std::optional> edge_weight_view, - std::optional> edge_id_view, - std::optional> edge_type_view, - std::optional> renumber_map, - bool do_expensive_check); - -template std::tuple, - rmm::device_uvector, - std::optional>, - std::optional>, - std::optional>> -decompress_to_edgelist( - raft::handle_t const& handle, - graph_view_t const& graph_view, - std::optional> edge_weight_view, - std::optional> edge_id_view, - std::optional> edge_type_view, - std::optional> renumber_map, - bool do_expensive_check); - -} // namespace cugraph diff --git a/cpp/src/structure/decompress_to_edgelist_sg_v32_e64.cu b/cpp/src/structure/decompress_to_edgelist_sg_v32_e64.cu deleted file mode 100644 index 035bea15e1c..00000000000 --- a/cpp/src/structure/decompress_to_edgelist_sg_v32_e64.cu +++ /dev/null @@ -1,78 +0,0 @@ -/* - * Copyright (c) 2021-2024, NVIDIA CORPORATION. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * 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. - */ -#include "structure/decompress_to_edgelist_impl.cuh" - -namespace cugraph { - -// SG instantiation - -template std::tuple, - rmm::device_uvector, - std::optional>, - std::optional>, - std::optional>> -decompress_to_edgelist( - raft::handle_t const& handle, - graph_view_t const& graph_view, - std::optional> edge_weight_view, - std::optional> edge_id_view, - std::optional> edge_type_view, - std::optional> renumber_map, - bool do_expensive_check); - -template std::tuple, - rmm::device_uvector, - std::optional>, - std::optional>, - std::optional>> -decompress_to_edgelist( - raft::handle_t const& handle, - graph_view_t const& graph_view, - std::optional> edge_weight_view, - std::optional> edge_id_view, - std::optional> edge_type_view, - std::optional> renumber_map, - bool do_expensive_check); - -template std::tuple, - rmm::device_uvector, - std::optional>, - std::optional>, - std::optional>> -decompress_to_edgelist( - raft::handle_t const& handle, - graph_view_t const& graph_view, - std::optional> edge_weight_view, - std::optional> edge_id_view, - std::optional> edge_type_view, - std::optional> renumber_map, - bool do_expensive_check); - -template std::tuple, - rmm::device_uvector, - std::optional>, - std::optional>, - std::optional>> -decompress_to_edgelist( - raft::handle_t const& handle, - graph_view_t const& graph_view, - std::optional> edge_weight_view, - std::optional> edge_id_view, - std::optional> edge_type_view, - std::optional> renumber_map, - bool do_expensive_check); - -} // namespace cugraph diff --git a/cpp/src/structure/graph_mg_v32_e64.cu b/cpp/src/structure/graph_mg_v32_e64.cu deleted file mode 100644 index 154ae2971dc..00000000000 --- a/cpp/src/structure/graph_mg_v32_e64.cu +++ /dev/null @@ -1,25 +0,0 @@ -/* - * Copyright (c) 2021-2024, NVIDIA CORPORATION. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * 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. - */ -#include "structure/graph_impl.cuh" - -namespace cugraph { - -// MG instantiation - -template class graph_t; -template class graph_t; - -} // namespace cugraph diff --git a/cpp/src/structure/graph_sg_v32_e64.cu b/cpp/src/structure/graph_sg_v32_e64.cu deleted file mode 100644 index 51f19cfc910..00000000000 --- a/cpp/src/structure/graph_sg_v32_e64.cu +++ /dev/null @@ -1,25 +0,0 @@ -/* - * Copyright (c) 2021-2024, NVIDIA CORPORATION. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * 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. - */ -#include "structure/graph_impl.cuh" - -namespace cugraph { - -// SG instantiation - -template class graph_t; -template class graph_t; - -} // namespace cugraph diff --git a/cpp/src/structure/graph_view_mg_v32_e64.cu b/cpp/src/structure/graph_view_mg_v32_e64.cu deleted file mode 100644 index 1c6edc53706..00000000000 --- a/cpp/src/structure/graph_view_mg_v32_e64.cu +++ /dev/null @@ -1,24 +0,0 @@ -/* - * Copyright (c) 2020-2024, NVIDIA CORPORATION. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * 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. - */ -#include "structure/graph_view_impl.cuh" - -namespace cugraph { - -// MG instantiation - -template class graph_view_t; -template class graph_view_t; -} // namespace cugraph diff --git a/cpp/src/structure/graph_view_sg_v32_e64.cu b/cpp/src/structure/graph_view_sg_v32_e64.cu deleted file mode 100644 index 12b140e34a6..00000000000 --- a/cpp/src/structure/graph_view_sg_v32_e64.cu +++ /dev/null @@ -1,24 +0,0 @@ -/* - * Copyright (c) 2020-2024, NVIDIA CORPORATION. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * 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. - */ -#include "structure/graph_view_impl.cuh" - -namespace cugraph { - -// SG instantiation - -template class graph_view_t; -template class graph_view_t; -} // namespace cugraph diff --git a/cpp/src/structure/graph_weight_utils_mg_v32_e64.cu b/cpp/src/structure/graph_weight_utils_mg_v32_e64.cu deleted file mode 100644 index a1fe84b2b85..00000000000 --- a/cpp/src/structure/graph_weight_utils_mg_v32_e64.cu +++ /dev/null @@ -1,124 +0,0 @@ -/* - * Copyright (c) 2020-2024, NVIDIA CORPORATION. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * 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. - */ -#include "structure/graph_weight_utils_impl.cuh" - -namespace cugraph { - -// SG instantiation - -// compute_in_weight_sums - -template rmm::device_uvector compute_in_weight_sums( - raft::handle_t const& handle, - graph_view_t const& graph_view, - edge_property_view_t edge_weight_view); - -template rmm::device_uvector compute_in_weight_sums( - raft::handle_t const& handle, - graph_view_t const& graph_view, - edge_property_view_t edge_weight_view); - -template rmm::device_uvector compute_in_weight_sums( - raft::handle_t const& handle, - graph_view_t const& graph_view, - edge_property_view_t edge_weight_view); - -template rmm::device_uvector compute_in_weight_sums( - raft::handle_t const& handle, - graph_view_t const& graph_view, - edge_property_view_t edge_weight_view); - -template rmm::device_uvector compute_out_weight_sums( - raft::handle_t const& handle, - graph_view_t const& graph_view, - edge_property_view_t edge_weight_view); - -template rmm::device_uvector compute_out_weight_sums( - raft::handle_t const& handle, - graph_view_t const& graph_view, - edge_property_view_t edge_weight_view); - -template rmm::device_uvector compute_out_weight_sums( - raft::handle_t const& handle, - graph_view_t const& graph_view, - edge_property_view_t edge_weight_view); - -template rmm::device_uvector compute_out_weight_sums( - raft::handle_t const& handle, - graph_view_t const& graph_view, - edge_property_view_t edge_weight_view); - -template float compute_max_in_weight_sum( - raft::handle_t const& handle, - graph_view_t const& graph_view, - edge_property_view_t edge_weight_view); - -template float compute_max_in_weight_sum( - raft::handle_t const& handle, - graph_view_t const& graph_view, - edge_property_view_t edge_weight_view); - -template double compute_max_in_weight_sum( - raft::handle_t const& handle, - graph_view_t const& graph_view, - edge_property_view_t edge_weight_view); - -template double compute_max_in_weight_sum( - raft::handle_t const& handle, - graph_view_t const& graph_view, - edge_property_view_t edge_weight_view); - -template float compute_max_out_weight_sum( - raft::handle_t const& handle, - graph_view_t const& graph_view, - edge_property_view_t edge_weight_view); - -template float compute_max_out_weight_sum( - raft::handle_t const& handle, - graph_view_t const& graph_view, - edge_property_view_t edge_weight_view); - -template double compute_max_out_weight_sum( - raft::handle_t const& handle, - graph_view_t const& graph_view, - edge_property_view_t edge_weight_view); - -template double compute_max_out_weight_sum( - raft::handle_t const& handle, - graph_view_t const& graph_view, - edge_property_view_t edge_weight_view); - -template float compute_total_edge_weight( - raft::handle_t const& handle, - graph_view_t const& graph_view, - edge_property_view_t edge_weight_view); - -template float compute_total_edge_weight( - raft::handle_t const& handle, - graph_view_t const& graph_view, - edge_property_view_t edge_weight_view); - -template double compute_total_edge_weight( - raft::handle_t const& handle, - graph_view_t const& graph_view, - edge_property_view_t edge_weight_view); - -template double compute_total_edge_weight( - raft::handle_t const& handle, - graph_view_t const& graph_view, - edge_property_view_t edge_weight_view); - -} // namespace cugraph diff --git a/cpp/src/structure/graph_weight_utils_sg_v32_e64.cu b/cpp/src/structure/graph_weight_utils_sg_v32_e64.cu deleted file mode 100644 index 4d4ce7097bd..00000000000 --- a/cpp/src/structure/graph_weight_utils_sg_v32_e64.cu +++ /dev/null @@ -1,125 +0,0 @@ -/* - * Copyright (c) 2020-2024, NVIDIA CORPORATION. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * 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. - */ -#include "structure/graph_weight_utils_impl.cuh" - -namespace cugraph { - -// SG instantiation - -// compute_in_weight_sums - -template rmm::device_uvector compute_in_weight_sums( - raft::handle_t const& handle, - graph_view_t const& graph_view, - edge_property_view_t edge_weight_view); - -template rmm::device_uvector compute_in_weight_sums( - raft::handle_t const& handle, - graph_view_t const& graph_view, - edge_property_view_t edge_weight_view); - -template rmm::device_uvector compute_in_weight_sums( - raft::handle_t const& handle, - graph_view_t const& graph_view, - edge_property_view_t edge_weight_view); - -template rmm::device_uvector compute_in_weight_sums( - raft::handle_t const& handle, - graph_view_t const& graph_view, - edge_property_view_t edge_weight_view); - -template rmm::device_uvector compute_out_weight_sums( - raft::handle_t const& handle, - graph_view_t const& graph_view, - edge_property_view_t edge_weight_view); - -template rmm::device_uvector compute_out_weight_sums( - raft::handle_t const& handle, - graph_view_t const& graph_view, - edge_property_view_t edge_weight_view); - -template rmm::device_uvector -compute_out_weight_sums( - raft::handle_t const& handle, - graph_view_t const& graph_view, - edge_property_view_t edge_weight_view); - -template rmm::device_uvector compute_out_weight_sums( - raft::handle_t const& handle, - graph_view_t const& graph_view, - edge_property_view_t edge_weight_view); - -template float compute_max_in_weight_sum( - raft::handle_t const& handle, - graph_view_t const& graph_view, - edge_property_view_t edge_weight_view); - -template float compute_max_in_weight_sum( - raft::handle_t const& handle, - graph_view_t const& graph_view, - edge_property_view_t edge_weight_view); - -template double compute_max_in_weight_sum( - raft::handle_t const& handle, - graph_view_t const& graph_view, - edge_property_view_t edge_weight_view); - -template double compute_max_in_weight_sum( - raft::handle_t const& handle, - graph_view_t const& graph_view, - edge_property_view_t edge_weight_view); - -template float compute_max_out_weight_sum( - raft::handle_t const& handle, - graph_view_t const& graph_view, - edge_property_view_t edge_weight_view); - -template float compute_max_out_weight_sum( - raft::handle_t const& handle, - graph_view_t const& graph_view, - edge_property_view_t edge_weight_view); - -template double compute_max_out_weight_sum( - raft::handle_t const& handle, - graph_view_t const& graph_view, - edge_property_view_t edge_weight_view); - -template double compute_max_out_weight_sum( - raft::handle_t const& handle, - graph_view_t const& graph_view, - edge_property_view_t edge_weight_view); - -template float compute_total_edge_weight( - raft::handle_t const& handle, - graph_view_t const& graph_view, - edge_property_view_t edge_weight_view); - -template float compute_total_edge_weight( - raft::handle_t const& handle, - graph_view_t const& graph_view, - edge_property_view_t edge_weight_view); - -template double compute_total_edge_weight( - raft::handle_t const& handle, - graph_view_t const& graph_view, - edge_property_view_t edge_weight_view); - -template double compute_total_edge_weight( - raft::handle_t const& handle, - graph_view_t const& graph_view, - edge_property_view_t edge_weight_view); - -} // namespace cugraph diff --git a/cpp/src/structure/induced_subgraph_mg_v32_e64.cu b/cpp/src/structure/induced_subgraph_mg_v32_e64.cu deleted file mode 100644 index e83d101898f..00000000000 --- a/cpp/src/structure/induced_subgraph_mg_v32_e64.cu +++ /dev/null @@ -1,46 +0,0 @@ -/* - * Copyright (c) 2021-2024, NVIDIA CORPORATION. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * 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. - */ -#include "structure/induced_subgraph_impl.cuh" - -namespace cugraph { - -// MG instantiation - -template std::tuple, - rmm::device_uvector, - std::optional>, - rmm::device_uvector> -extract_induced_subgraphs( - raft::handle_t const& handle, - graph_view_t const& graph_view, - std::optional> edge_weight_view, - raft::device_span subgraph_offsets, - raft::device_span subgraph_vertices, - bool do_expensive_check); - -template std::tuple, - rmm::device_uvector, - std::optional>, - rmm::device_uvector> -extract_induced_subgraphs( - raft::handle_t const& handle, - graph_view_t const& graph_view, - std::optional> edge_weight_view, - raft::device_span subgraph_offsets, - raft::device_span subgraph_vertices, - bool do_expensive_check); - -} // namespace cugraph diff --git a/cpp/src/structure/induced_subgraph_sg_v32_e64.cu b/cpp/src/structure/induced_subgraph_sg_v32_e64.cu deleted file mode 100644 index 6a4c08f9682..00000000000 --- a/cpp/src/structure/induced_subgraph_sg_v32_e64.cu +++ /dev/null @@ -1,46 +0,0 @@ -/* - * Copyright (c) 2021-2024, NVIDIA CORPORATION. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * 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. - */ -#include "structure/induced_subgraph_impl.cuh" - -namespace cugraph { - -// SG instantiation - -template std::tuple, - rmm::device_uvector, - std::optional>, - rmm::device_uvector> -extract_induced_subgraphs( - raft::handle_t const& handle, - graph_view_t const& graph_view, - std::optional> edge_weight_view, - raft::device_span subgraph_offsets, - raft::device_span subgraph_vertices, - bool do_expensive_check); - -template std::tuple, - rmm::device_uvector, - std::optional>, - rmm::device_uvector> -extract_induced_subgraphs( - raft::handle_t const& handle, - graph_view_t const& graph_view, - std::optional> edge_weight_view, - raft::device_span subgraph_offsets, - raft::device_span subgraph_vertices, - bool do_expensive_check); - -} // namespace cugraph diff --git a/cpp/src/structure/remove_multi_edges_impl.cuh b/cpp/src/structure/remove_multi_edges_impl.cuh index ce83fdcb66a..7e266ab2caf 100644 --- a/cpp/src/structure/remove_multi_edges_impl.cuh +++ b/cpp/src/structure/remove_multi_edges_impl.cuh @@ -28,6 +28,7 @@ #include +#include #include #include #include @@ -53,8 +54,8 @@ struct hash_src_dst_pair { vertex_t pair[2]; pair[0] = thrust::get<0>(t); pair[1] = thrust::get<1>(t); - cuco::detail::MurmurHash3_32 hash_func{}; - return hash_func.compute_hash(reinterpret_cast(pair), 2 * sizeof(vertex_t)) % + cuco::murmurhash3_32 hash_func{}; + return hash_func.compute_hash(reinterpret_cast(pair), 2 * sizeof(vertex_t)) % num_groups; } }; diff --git a/cpp/src/structure/remove_multi_edges_sg_v32_e64.cu b/cpp/src/structure/remove_multi_edges_sg_v32_e64.cu deleted file mode 100644 index 03b5a634158..00000000000 --- a/cpp/src/structure/remove_multi_edges_sg_v32_e64.cu +++ /dev/null @@ -1,46 +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. - */ -#include "structure/remove_multi_edges_impl.cuh" - -namespace cugraph { - -template std::tuple, - rmm::device_uvector, - std::optional>, - std::optional>, - std::optional>> -remove_multi_edges(raft::handle_t const& handle, - rmm::device_uvector&& edgelist_srcs, - rmm::device_uvector&& edgelist_dsts, - std::optional>&& edgelist_weights, - std::optional>&& edgelist_edge_ids, - std::optional>&& edgelist_edge_types, - bool keep_min_value_edge); - -template std::tuple, - rmm::device_uvector, - std::optional>, - std::optional>, - std::optional>> -remove_multi_edges(raft::handle_t const& handle, - rmm::device_uvector&& edgelist_srcs, - rmm::device_uvector&& edgelist_dsts, - std::optional>&& edgelist_weights, - std::optional>&& edgelist_edge_ids, - std::optional>&& edgelist_edge_types, - bool keep_min_value_edge); - -} // namespace cugraph diff --git a/cpp/src/structure/remove_self_loops_sg_v32_e64.cu b/cpp/src/structure/remove_self_loops_sg_v32_e64.cu deleted file mode 100644 index 0244e75353d..00000000000 --- a/cpp/src/structure/remove_self_loops_sg_v32_e64.cu +++ /dev/null @@ -1,44 +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. - */ -#include "structure/remove_self_loops_impl.cuh" - -namespace cugraph { - -template std::tuple, - rmm::device_uvector, - std::optional>, - std::optional>, - std::optional>> -remove_self_loops(raft::handle_t const& handle, - rmm::device_uvector&& edgelist_srcs, - rmm::device_uvector&& edgelist_dsts, - std::optional>&& edgelist_weights, - std::optional>&& edgelist_edge_ids, - std::optional>&& edgelist_edge_types); - -template std::tuple, - rmm::device_uvector, - std::optional>, - std::optional>, - std::optional>> -remove_self_loops(raft::handle_t const& handle, - rmm::device_uvector&& edgelist_srcs, - rmm::device_uvector&& edgelist_dsts, - std::optional>&& edgelist_weights, - std::optional>&& edgelist_edge_ids, - std::optional>&& edgelist_edge_types); - -} // namespace cugraph diff --git a/cpp/src/structure/renumber_edgelist_mg_v32_e64.cu b/cpp/src/structure/renumber_edgelist_mg_v32_e64.cu deleted file mode 100644 index 6d1414f918c..00000000000 --- a/cpp/src/structure/renumber_edgelist_mg_v32_e64.cu +++ /dev/null @@ -1,33 +0,0 @@ -/* - * Copyright (c) 2021-2024, NVIDIA CORPORATION. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * 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. - */ -#include "structure/renumber_edgelist_impl.cuh" - -namespace cugraph { - -// MG instantiation - -template std::tuple, renumber_meta_t> -renumber_edgelist( - raft::handle_t const& handle, - std::optional>&& local_vertices, - std::vector const& edgelist_srcs /* [INOUT] */, - std::vector const& edgelist_dsts /* [INOUT] */, - std::vector const& edgelist_edge_counts, - std::optional>> const& edgelist_intra_partition_segment_offsets, - bool store_transposed, - bool do_expensive_check); - -} // namespace cugraph diff --git a/cpp/src/structure/renumber_edgelist_sg_v32_e64.cu b/cpp/src/structure/renumber_edgelist_sg_v32_e64.cu deleted file mode 100644 index 5214ec15f3e..00000000000 --- a/cpp/src/structure/renumber_edgelist_sg_v32_e64.cu +++ /dev/null @@ -1,31 +0,0 @@ -/* - * Copyright (c) 2021-2024, NVIDIA CORPORATION. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * 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. - */ -#include "structure/renumber_edgelist_impl.cuh" - -namespace cugraph { - -// SG instantiation - -template std::tuple, renumber_meta_t> -renumber_edgelist(raft::handle_t const& handle, - std::optional>&& vertices, - int32_t* edgelist_srcs /* [INOUT] */, - int32_t* edgelist_dsts /* [INOUT] */, - int64_t num_edgelist_edges, - bool store_transposed, - bool do_expensive_check); - -} // namespace cugraph diff --git a/cpp/src/structure/select_random_vertices_mg_v32_e64.cu b/cpp/src/structure/select_random_vertices_mg_v32_e64.cu deleted file mode 100644 index 16b5243bcd4..00000000000 --- a/cpp/src/structure/select_random_vertices_mg_v32_e64.cu +++ /dev/null @@ -1,41 +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. - */ - -#include "structure/select_random_vertices_impl.hpp" - -namespace cugraph { - -template rmm::device_uvector select_random_vertices( - raft::handle_t const& handle, - graph_view_t const& graph_view, - std::optional> given_set, - raft::random::RngState& rng_state, - size_t select_count, - bool with_replacement, - bool sort_vertices, - bool do_expensive_check); - -template rmm::device_uvector select_random_vertices( - raft::handle_t const& handle, - graph_view_t const& graph_view, - std::optional> given_set, - raft::random::RngState& rng_state, - size_t select_count, - bool with_replacement, - bool sort_vertices, - bool do_expensive_check); - -} // namespace cugraph diff --git a/cpp/src/structure/select_random_vertices_sg_v32_e64.cu b/cpp/src/structure/select_random_vertices_sg_v32_e64.cu deleted file mode 100644 index 21842ba76f8..00000000000 --- a/cpp/src/structure/select_random_vertices_sg_v32_e64.cu +++ /dev/null @@ -1,41 +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. - */ - -#include "structure/select_random_vertices_impl.hpp" - -namespace cugraph { - -template rmm::device_uvector select_random_vertices( - raft::handle_t const& handle, - graph_view_t const& graph_view, - std::optional> given_set, - raft::random::RngState& rng_state, - size_t select_count, - bool with_replacement, - bool sort_vertices, - bool do_expensive_check); - -template rmm::device_uvector select_random_vertices( - raft::handle_t const& handle, - graph_view_t const& graph_view, - std::optional> given_set, - raft::random::RngState& rng_state, - size_t select_count, - bool with_replacement, - bool sort_vertices, - bool do_expensive_check); - -} // namespace cugraph diff --git a/cpp/src/structure/symmetrize_graph_mg_v32_e64.cu b/cpp/src/structure/symmetrize_graph_mg_v32_e64.cu deleted file mode 100644 index db077e676bd..00000000000 --- a/cpp/src/structure/symmetrize_graph_mg_v32_e64.cu +++ /dev/null @@ -1,71 +0,0 @@ -/* - * Copyright (c) 2021-2024, NVIDIA CORPORATION. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * 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. - */ -#include "structure/symmetrize_graph_impl.cuh" - -namespace cugraph { - -// MG instantiation - -template std::tuple< - graph_t, - std::optional, float>>, - std::optional>> -symmetrize_graph( - raft::handle_t const& handle, - graph_t&& graph, - std::optional, float>>&& edge_weights, - std::optional>&& renumber_map, - bool reciprocal, - bool do_expensive_check); - -template std::tuple< - graph_t, - std::optional, float>>, - std::optional>> -symmetrize_graph( - raft::handle_t const& handle, - graph_t&& graph, - std::optional, float>>&& edge_weights, - std::optional>&& renumber_map, - bool reciprocal, - bool do_expensive_check); - -template std::tuple< - graph_t, - std::optional, double>>, - std::optional>> -symmetrize_graph( - raft::handle_t const& handle, - graph_t&& graph, - std::optional, double>>&& edge_weights, - std::optional>&& renumber_map, - bool reciprocal, - bool do_expensive_check); - -template std::tuple< - graph_t, - std::optional, double>>, - std::optional>> -symmetrize_graph( - raft::handle_t const& handle, - graph_t&& graph, - std::optional, double>>&& - edge_weights, - std::optional>&& renumber_map, - bool reciprocal, - bool do_expensive_check); - -} // namespace cugraph diff --git a/cpp/src/structure/symmetrize_graph_sg_v32_e64.cu b/cpp/src/structure/symmetrize_graph_sg_v32_e64.cu deleted file mode 100644 index a819207874d..00000000000 --- a/cpp/src/structure/symmetrize_graph_sg_v32_e64.cu +++ /dev/null @@ -1,73 +0,0 @@ -/* - * Copyright (c) 2021-2024, NVIDIA CORPORATION. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * 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. - */ -#include "structure/symmetrize_graph_impl.cuh" - -namespace cugraph { - -// SG instantiation - -template std::tuple< - graph_t, - std::optional, float>>, - std::optional>> -symmetrize_graph( - raft::handle_t const& handle, - graph_t&& graph, - std::optional, float>>&& edge_weights, - std::optional>&& renumber_map, - bool reciprocal, - bool do_expensive_check); - -template std::tuple< - graph_t, - std::optional, float>>, - std::optional>> -symmetrize_graph( - raft::handle_t const& handle, - graph_t&& graph, - std::optional, float>>&& - edge_weights, - std::optional>&& renumber_map, - bool reciprocal, - bool do_expensive_check); - -template std::tuple< - graph_t, - std::optional, double>>, - std::optional>> -symmetrize_graph( - raft::handle_t const& handle, - graph_t&& graph, - std::optional, double>>&& - edge_weights, - std::optional>&& renumber_map, - bool reciprocal, - bool do_expensive_check); - -template std::tuple< - graph_t, - std::optional, double>>, - std::optional>> -symmetrize_graph( - raft::handle_t const& handle, - graph_t&& graph, - std::optional, double>>&& - edge_weights, - std::optional>&& renumber_map, - bool reciprocal, - bool do_expensive_check); - -} // namespace cugraph diff --git a/cpp/src/structure/transpose_graph_mg_v32_e64.cu b/cpp/src/structure/transpose_graph_mg_v32_e64.cu deleted file mode 100644 index 6bf9b9e4011..00000000000 --- a/cpp/src/structure/transpose_graph_mg_v32_e64.cu +++ /dev/null @@ -1,67 +0,0 @@ -/* - * Copyright (c) 2021-2024, NVIDIA CORPORATION. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * 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. - */ -#include "structure/transpose_graph_impl.cuh" - -namespace cugraph { - -// MG instantiation - -template std::tuple< - graph_t, - std::optional, float>>, - std::optional>> -transpose_graph( - raft::handle_t const& handle, - graph_t&& graph, - std::optional, float>>&& edge_weights, - std::optional>&& renumber_map, - bool do_expensive_check); - -template std::tuple< - graph_t, - std::optional, float>>, - std::optional>> -transpose_graph( - raft::handle_t const& handle, - graph_t&& graph, - std::optional, float>>&& edge_weights, - std::optional>&& renumber_map, - bool do_expensive_check); - -template std::tuple< - graph_t, - std::optional, double>>, - std::optional>> -transpose_graph( - raft::handle_t const& handle, - graph_t&& graph, - std::optional, double>>&& edge_weights, - std::optional>&& renumber_map, - bool do_expensive_check); - -template std::tuple< - graph_t, - std::optional, double>>, - std::optional>> -transpose_graph( - raft::handle_t const& handle, - graph_t&& graph, - std::optional, double>>&& - edge_weights, - std::optional>&& renumber_map, - bool do_expensive_check); - -} // namespace cugraph diff --git a/cpp/src/structure/transpose_graph_sg_v32_e64.cu b/cpp/src/structure/transpose_graph_sg_v32_e64.cu deleted file mode 100644 index af64aa7b20b..00000000000 --- a/cpp/src/structure/transpose_graph_sg_v32_e64.cu +++ /dev/null @@ -1,69 +0,0 @@ -/* - * Copyright (c) 2021-2024, NVIDIA CORPORATION. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * 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. - */ -#include "structure/transpose_graph_impl.cuh" - -namespace cugraph { - -// SG instantiation - -template std::tuple< - graph_t, - std::optional, float>>, - std::optional>> -transpose_graph( - raft::handle_t const& handle, - graph_t&& graph, - std::optional, float>>&& edge_weights, - std::optional>&& renumber_map, - bool do_expensive_check); - -template std::tuple< - graph_t, - std::optional, float>>, - std::optional>> -transpose_graph( - raft::handle_t const& handle, - graph_t&& graph, - std::optional, float>>&& - edge_weights, - std::optional>&& renumber_map, - bool do_expensive_check); - -template std::tuple< - graph_t, - std::optional, double>>, - std::optional>> -transpose_graph( - raft::handle_t const& handle, - graph_t&& graph, - std::optional, double>>&& - edge_weights, - std::optional>&& renumber_map, - bool do_expensive_check); - -template std::tuple< - graph_t, - std::optional, double>>, - std::optional>> -transpose_graph( - raft::handle_t const& handle, - graph_t&& graph, - std::optional, double>>&& - edge_weights, - std::optional>&& renumber_map, - bool do_expensive_check); - -} // namespace cugraph diff --git a/cpp/src/structure/transpose_graph_storage_mg_v32_e64.cu b/cpp/src/structure/transpose_graph_storage_mg_v32_e64.cu deleted file mode 100644 index 15488e2ba17..00000000000 --- a/cpp/src/structure/transpose_graph_storage_mg_v32_e64.cu +++ /dev/null @@ -1,67 +0,0 @@ -/* - * Copyright (c) 2021-2024, NVIDIA CORPORATION. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * 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. - */ -#include "structure/transpose_graph_storage_impl.cuh" - -namespace cugraph { - -// MG instantiation - -template std::tuple< - graph_t, - std::optional, float>>, - std::optional>> -transpose_graph_storage( - raft::handle_t const& handle, - graph_t&& graph, - std::optional, float>>&& edge_weights, - std::optional>&& renumber_map, - bool do_expensive_check); - -template std::tuple< - graph_t, - std::optional, float>>, - std::optional>> -transpose_graph_storage( - raft::handle_t const& handle, - graph_t&& graph, - std::optional, float>>&& edge_weights, - std::optional>&& renumber_map, - bool do_expensive_check); - -template std::tuple< - graph_t, - std::optional, double>>, - std::optional>> -transpose_graph_storage( - raft::handle_t const& handle, - graph_t&& graph, - std::optional, double>>&& edge_weights, - std::optional>&& renumber_map, - bool do_expensive_check); - -template std::tuple< - graph_t, - std::optional, double>>, - std::optional>> -transpose_graph_storage( - raft::handle_t const& handle, - graph_t&& graph, - std::optional, double>>&& - edge_weights, - std::optional>&& renumber_map, - bool do_expensive_check); - -} // namespace cugraph diff --git a/cpp/src/structure/transpose_graph_storage_sg_v32_e64.cu b/cpp/src/structure/transpose_graph_storage_sg_v32_e64.cu deleted file mode 100644 index ac8787582dd..00000000000 --- a/cpp/src/structure/transpose_graph_storage_sg_v32_e64.cu +++ /dev/null @@ -1,69 +0,0 @@ -/* - * Copyright (c) 2021-2024, NVIDIA CORPORATION. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * 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. - */ -#include "structure/transpose_graph_storage_impl.cuh" - -namespace cugraph { - -// SG instantiation - -template std::tuple< - graph_t, - std::optional, float>>, - std::optional>> -transpose_graph_storage( - raft::handle_t const& handle, - graph_t&& graph, - std::optional, float>>&& edge_weights, - std::optional>&& renumber_map, - bool do_expensive_check); - -template std::tuple< - graph_t, - std::optional, float>>, - std::optional>> -transpose_graph_storage( - raft::handle_t const& handle, - graph_t&& graph, - std::optional, float>>&& - edge_weights, - std::optional>&& renumber_map, - bool do_expensive_check); - -template std::tuple< - graph_t, - std::optional, double>>, - std::optional>> -transpose_graph_storage( - raft::handle_t const& handle, - graph_t&& graph, - std::optional, double>>&& - edge_weights, - std::optional>&& renumber_map, - bool do_expensive_check); - -template std::tuple< - graph_t, - std::optional, double>>, - std::optional>> -transpose_graph_storage( - raft::handle_t const& handle, - graph_t&& graph, - std::optional, double>>&& - edge_weights, - std::optional>&& renumber_map, - bool do_expensive_check); - -} // namespace cugraph diff --git a/cpp/src/traversal/bfs_mg_v32_e64.cu b/cpp/src/traversal/bfs_mg_v32_e64.cu deleted file mode 100644 index 5fde01e0fcc..00000000000 --- a/cpp/src/traversal/bfs_mg_v32_e64.cu +++ /dev/null @@ -1,33 +0,0 @@ -/* - * Copyright (c) 2021-2024, NVIDIA CORPORATION. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * 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. - */ - -#include "traversal/bfs_impl.cuh" - -namespace cugraph { - -// MG instantiation - -template void bfs(raft::handle_t const& handle, - graph_view_t const& graph_view, - int32_t* distances, - int32_t* predecessors, - int32_t const* sources, - size_t n_sources, - bool direction_optimizing, - int32_t depth_limit, - bool do_expensive_check); - -} // namespace cugraph diff --git a/cpp/src/traversal/bfs_sg_v32_e64.cu b/cpp/src/traversal/bfs_sg_v32_e64.cu deleted file mode 100644 index 3a6a7ef01de..00000000000 --- a/cpp/src/traversal/bfs_sg_v32_e64.cu +++ /dev/null @@ -1,33 +0,0 @@ -/* - * Copyright (c) 2021-2024, NVIDIA CORPORATION. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * 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. - */ - -#include "traversal/bfs_impl.cuh" - -namespace cugraph { - -// SG instantiation - -template void bfs(raft::handle_t const& handle, - graph_view_t const& graph_view, - int32_t* distances, - int32_t* predecessors, - int32_t const* sources, - size_t n_sources, - bool direction_optimizing, - int32_t depth_limit, - bool do_expensive_check); - -} // namespace cugraph diff --git a/cpp/src/traversal/extract_bfs_paths_mg_v32_e64.cu b/cpp/src/traversal/extract_bfs_paths_mg_v32_e64.cu deleted file mode 100644 index 00aacc50c47..00000000000 --- a/cpp/src/traversal/extract_bfs_paths_mg_v32_e64.cu +++ /dev/null @@ -1,31 +0,0 @@ -/* - * Copyright (c) 2021-2024, NVIDIA CORPORATION. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * 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. - */ - -#include "traversal/extract_bfs_paths_impl.cuh" - -namespace cugraph { - -// MG instantiation - -template std::tuple, int32_t> extract_bfs_paths( - raft::handle_t const& handle, - graph_view_t const& graph_view, - int32_t const* distances, - int32_t const* predecessors, - int32_t const* destinations, - size_t n_destinations); - -} // namespace cugraph diff --git a/cpp/src/traversal/extract_bfs_paths_sg_v32_e64.cu b/cpp/src/traversal/extract_bfs_paths_sg_v32_e64.cu deleted file mode 100644 index 369ae9efa1a..00000000000 --- a/cpp/src/traversal/extract_bfs_paths_sg_v32_e64.cu +++ /dev/null @@ -1,31 +0,0 @@ -/* - * Copyright (c) 2021-2024, NVIDIA CORPORATION. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * 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. - */ - -#include "traversal/extract_bfs_paths_impl.cuh" - -namespace cugraph { - -// SG instantiation - -template std::tuple, int32_t> extract_bfs_paths( - raft::handle_t const& handle, - graph_view_t const& graph_view, - int32_t const* distances, - int32_t const* predecessors, - int32_t const* destinations, - size_t n_destinations); - -} // namespace cugraph diff --git a/cpp/src/traversal/k_hop_nbrs_mg_v32_e64.cu b/cpp/src/traversal/k_hop_nbrs_mg_v32_e64.cu deleted file mode 100644 index 31049883166..00000000000 --- a/cpp/src/traversal/k_hop_nbrs_mg_v32_e64.cu +++ /dev/null @@ -1,29 +0,0 @@ -/* - * 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. - * 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. - */ -#include "traversal/k_hop_nbrs_impl.cuh" - -namespace cugraph { - -// MG instantiation - -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); - -} // namespace cugraph diff --git a/cpp/src/traversal/k_hop_nbrs_sg_v32_e64.cu b/cpp/src/traversal/k_hop_nbrs_sg_v32_e64.cu deleted file mode 100644 index cd47f81361f..00000000000 --- a/cpp/src/traversal/k_hop_nbrs_sg_v32_e64.cu +++ /dev/null @@ -1,29 +0,0 @@ -/* - * 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. - * 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. - */ -#include "traversal/k_hop_nbrs_impl.cuh" - -namespace cugraph { - -// MG instantiation - -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); - -} // namespace cugraph diff --git a/cpp/src/traversal/od_shortest_distances_sg_v32_e64.cu b/cpp/src/traversal/od_shortest_distances_sg_v32_e64.cu deleted file mode 100644 index 880bc775589..00000000000 --- a/cpp/src/traversal/od_shortest_distances_sg_v32_e64.cu +++ /dev/null @@ -1,40 +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. - */ -#include "traversal/od_shortest_distances_impl.cuh" - -namespace cugraph { - -// SG instantiation - -template rmm::device_uvector od_shortest_distances( - raft::handle_t const& handle, - graph_view_t const& graph_view, - edge_property_view_t edge_weight_view, - raft::device_span origins, - raft::device_span destinations, - float cutoff, - bool do_expensive_check); - -template rmm::device_uvector od_shortest_distances( - raft::handle_t const& handle, - graph_view_t const& graph_view, - edge_property_view_t edge_weight_view, - raft::device_span origins, - raft::device_span destinations, - double cutoff, - bool do_expensive_check); - -} // namespace cugraph diff --git a/cpp/src/traversal/sssp_mg_v32_e64.cu b/cpp/src/traversal/sssp_mg_v32_e64.cu deleted file mode 100644 index 382b31cebf9..00000000000 --- a/cpp/src/traversal/sssp_mg_v32_e64.cu +++ /dev/null @@ -1,40 +0,0 @@ -/* - * Copyright (c) 2021-2024, NVIDIA CORPORATION. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * 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. - */ -#include "traversal/sssp_impl.cuh" - -namespace cugraph { - -// MG instantiation - -template void sssp(raft::handle_t const& handle, - graph_view_t const& graph_view, - edge_property_view_t edge_weight_view, - float* distances, - int32_t* predecessors, - int32_t source_vertex, - float cutoff, - bool do_expensive_check); - -template void sssp(raft::handle_t const& handle, - graph_view_t const& graph_view, - edge_property_view_t edge_weight_view, - double* distances, - int32_t* predecessors, - int32_t source_vertex, - double cutoff, - bool do_expensive_check); - -} // namespace cugraph diff --git a/cpp/src/traversal/sssp_sg_v32_e64.cu b/cpp/src/traversal/sssp_sg_v32_e64.cu deleted file mode 100644 index b02d43cfaf2..00000000000 --- a/cpp/src/traversal/sssp_sg_v32_e64.cu +++ /dev/null @@ -1,40 +0,0 @@ -/* - * Copyright (c) 2021-2024, NVIDIA CORPORATION. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * 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. - */ -#include "traversal/sssp_impl.cuh" - -namespace cugraph { - -// SG instantiation - -template void sssp(raft::handle_t const& handle, - graph_view_t const& graph_view, - edge_property_view_t edge_weight_view, - float* distances, - int32_t* predecessors, - int32_t source_vertex, - float cutoff, - bool do_expensive_check); - -template void sssp(raft::handle_t const& handle, - graph_view_t const& graph_view, - edge_property_view_t edge_weight_view, - double* distances, - int32_t* predecessors, - int32_t source_vertex, - double cutoff, - bool do_expensive_check); - -} // namespace cugraph diff --git a/cpp/src/utilities/shuffle_vertex_pairs_mg_v32_e64.cu b/cpp/src/utilities/shuffle_vertex_pairs_mg_v32_e64.cu deleted file mode 100644 index d79b2379224..00000000000 --- a/cpp/src/utilities/shuffle_vertex_pairs_mg_v32_e64.cu +++ /dev/null @@ -1,120 +0,0 @@ -/* - * Copyright (c) 2021-2024, NVIDIA CORPORATION. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * 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. - */ - -#include "detail/graph_partition_utils.cuh" -#include "shuffle_vertex_pairs.cuh" - -#include -#include -#include -#include -#include - -#include -#include - -#include - -namespace cugraph { - -namespace detail { -template std::tuple, - rmm::device_uvector, - std::optional>, - std::optional>, - std::optional>, - std::vector> -shuffle_ext_vertex_pairs_with_values_to_local_gpu_by_edge_partitioning( - raft::handle_t const& handle, - rmm::device_uvector&& majors, - rmm::device_uvector&& minors, - std::optional>&& weights, - std::optional>&& edge_ids, - std::optional>&& edge_types); - -template std::tuple, - rmm::device_uvector, - std::optional>, - std::optional>, - std::optional>, - std::vector> -shuffle_ext_vertex_pairs_with_values_to_local_gpu_by_edge_partitioning( - raft::handle_t const& handle, - rmm::device_uvector&& majors, - rmm::device_uvector&& minors, - std::optional>&& weights, - std::optional>&& edge_ids, - std::optional>&& edge_types); - -template std::tuple, - rmm::device_uvector, - std::optional>, - std::optional>, - std::optional>, - std::vector> -shuffle_int_vertex_pairs_with_values_to_local_gpu_by_edge_partitioning( - raft::handle_t const& handle, - rmm::device_uvector&& majors, - rmm::device_uvector&& minors, - std::optional>&& weights, - std::optional>&& edge_ids, - std::optional>&& edge_types, - std::vector const& vertex_partition_range_lasts); - -template std::tuple, - rmm::device_uvector, - std::optional>, - std::optional>, - std::optional>, - std::vector> -shuffle_int_vertex_pairs_with_values_to_local_gpu_by_edge_partitioning( - raft::handle_t const& handle, - rmm::device_uvector&& majors, - rmm::device_uvector&& minors, - std::optional>&& weights, - std::optional>&& edge_ids, - std::optional>&& edge_types, - std::vector const& vertex_partition_range_lasts); - -} // namespace detail - -template std::tuple, - rmm::device_uvector, - std::optional>, - std::optional>, - std::optional>, - std::vector> -shuffle_external_edges(raft::handle_t const& handle, - rmm::device_uvector&& majors, - rmm::device_uvector&& minors, - std::optional>&& weights, - std::optional>&& edge_ids, - std::optional>&& edge_types); - -template std::tuple, - rmm::device_uvector, - std::optional>, - std::optional>, - std::optional>, - std::vector> -shuffle_external_edges(raft::handle_t const& handle, - rmm::device_uvector&& majors, - rmm::device_uvector&& minors, - std::optional>&& weights, - std::optional>&& edge_ids, - std::optional>&& edge_types); - -} // namespace cugraph diff --git a/cpp/tests/CMakeLists.txt b/cpp/tests/CMakeLists.txt index 3145a2ea1be..04bd3552190 100644 --- a/cpp/tests/CMakeLists.txt +++ b/cpp/tests/CMakeLists.txt @@ -220,6 +220,7 @@ function(ConfigureTestMG CMAKE_TEST_NAME) GPUS ${GPU_COUNT} PERCENT 100 INSTALL_COMPONENT_SET testing_mg + INSTALL_TARGET ${CMAKE_TEST_NAME} ) set_tests_properties(${CMAKE_TEST_NAME} PROPERTIES LABELS "CUGRAPH_MG") @@ -302,6 +303,7 @@ function(ConfigureCTestMG CMAKE_TEST_NAME) GPUS ${GPU_COUNT} PERCENT 100 INSTALL_COMPONENT_SET testing_mg + INSTALL_TARGET ${CMAKE_TEST_NAME} ) set_tests_properties(${CMAKE_TEST_NAME} PROPERTIES LABELS "CUGRAPH_C_MG") diff --git a/cpp/tests/c_api/betweenness_centrality_test.c b/cpp/tests/c_api/betweenness_centrality_test.c index cc37a10798e..7fec78eaffd 100644 --- a/cpp/tests/c_api/betweenness_centrality_test.c +++ b/cpp/tests/c_api/betweenness_centrality_test.c @@ -122,7 +122,7 @@ int generic_betweenness_centrality_test(vertex_t* h_src, cugraph_type_erased_device_array_view_free(seeds_view); cugraph_type_erased_device_array_free(seeds); - cugraph_sg_graph_free(p_graph); + cugraph_graph_free(p_graph); cugraph_free_resource_handle(handle); cugraph_error_free(ret_error); diff --git a/cpp/tests/c_api/bfs_test.c b/cpp/tests/c_api/bfs_test.c index 8feb426a853..b61051d8f90 100644 --- a/cpp/tests/c_api/bfs_test.c +++ b/cpp/tests/c_api/bfs_test.c @@ -109,7 +109,7 @@ int generic_bfs_test(vertex_t* h_src, cugraph_type_erased_device_array_free(p_sources); cugraph_paths_result_free(p_result); - cugraph_sg_graph_free(p_graph); + cugraph_graph_free(p_graph); cugraph_free_resource_handle(p_handle); cugraph_error_free(ret_error); diff --git a/cpp/tests/c_api/biased_neighbor_sample_test.c b/cpp/tests/c_api/biased_neighbor_sample_test.c index fe80514c825..0ccb236f7fc 100644 --- a/cpp/tests/c_api/biased_neighbor_sample_test.c +++ b/cpp/tests/c_api/biased_neighbor_sample_test.c @@ -461,7 +461,7 @@ int generic_biased_neighbor_sample_test(const cugraph_resource_handle_t* handle, cugraph_sample_result_free(result); #endif - cugraph_sg_graph_free(graph); + cugraph_graph_free(graph); cugraph_error_free(ret_error); return test_ret_value; } @@ -680,7 +680,7 @@ int test_biased_neighbor_sample_with_labels(const cugraph_resource_handle_t* han cugraph_sampling_options_free(sampling_options); #endif - cugraph_sg_graph_free(graph); + cugraph_graph_free(graph); cugraph_error_free(ret_error); } diff --git a/cpp/tests/c_api/core_number_test.c b/cpp/tests/c_api/core_number_test.c index ca0bbf7134f..c9c85694db5 100644 --- a/cpp/tests/c_api/core_number_test.c +++ b/cpp/tests/c_api/core_number_test.c @@ -81,7 +81,7 @@ int generic_core_number_test(vertex_t* h_src, } cugraph_core_result_free(p_result); - cugraph_sg_graph_free(p_graph); + cugraph_graph_free(p_graph); cugraph_free_resource_handle(p_handle); cugraph_error_free(ret_error); diff --git a/cpp/tests/c_api/create_graph_test.c b/cpp/tests/c_api/create_graph_test.c index 41b8691e79c..a07f31fce57 100644 --- a/cpp/tests/c_api/create_graph_test.c +++ b/cpp/tests/c_api/create_graph_test.c @@ -104,6 +104,7 @@ int test_create_sg_graph_simple() FALSE, FALSE, FALSE, + FALSE, &graph, &ret_error); TEST_ASSERT(test_ret_value, ret_code == CUGRAPH_SUCCESS, "graph creation failed."); @@ -203,7 +204,7 @@ int test_create_sg_graph_csr() handle, wgt_view, (byte_t*)h_wgt, &ret_error); TEST_ASSERT(test_ret_value, ret_code == CUGRAPH_SUCCESS, "wgt copy_from_host failed."); - ret_code = cugraph_sg_graph_create_from_csr(handle, + ret_code = cugraph_graph_create_sg_from_csr(handle, &properties, offsets_view, indices_view, @@ -213,6 +214,7 @@ int test_create_sg_graph_csr() FALSE, FALSE, FALSE, + FALSE, &graph, &ret_error); TEST_ASSERT(test_ret_value, ret_code == CUGRAPH_SUCCESS, "graph creation failed."); @@ -408,6 +410,7 @@ int test_create_sg_graph_symmetric_error() FALSE, FALSE, FALSE, + FALSE, TRUE, &graph, &ret_error); @@ -526,6 +529,7 @@ int test_create_sg_graph_with_isolated_vertices() FALSE, FALSE, FALSE, + FALSE, &graph, &ret_error); TEST_ASSERT(test_ret_value, ret_code == CUGRAPH_SUCCESS, "graph creation failed."); @@ -665,7 +669,7 @@ int test_create_sg_graph_csr_with_isolated() handle, wgt_view, (byte_t*)h_wgt, &ret_error); TEST_ASSERT(test_ret_value, ret_code == CUGRAPH_SUCCESS, "wgt copy_from_host failed."); - ret_code = cugraph_sg_graph_create_from_csr(handle, + ret_code = cugraph_graph_create_sg_from_csr(handle, &properties, offsets_view, indices_view, @@ -675,6 +679,7 @@ int test_create_sg_graph_csr_with_isolated() FALSE, FALSE, FALSE, + FALSE, &graph, &ret_error); TEST_ASSERT(test_ret_value, ret_code == CUGRAPH_SUCCESS, "graph creation failed."); @@ -840,6 +845,7 @@ int test_create_sg_graph_with_isolated_vertices_multi_input() TRUE, TRUE, FALSE, + FALSE, &graph, &ret_error); TEST_ASSERT(test_ret_value, ret_code == CUGRAPH_SUCCESS, "graph creation failed."); diff --git a/cpp/tests/c_api/ecg_test.c b/cpp/tests/c_api/ecg_test.c index 4d4dd64572f..4f4c29b97b9 100644 --- a/cpp/tests/c_api/ecg_test.c +++ b/cpp/tests/c_api/ecg_test.c @@ -121,7 +121,7 @@ int generic_ecg_test(vertex_t* h_src, cugraph_hierarchical_clustering_result_free(result); } - cugraph_sg_graph_free(graph); + cugraph_graph_free(graph); cugraph_free_resource_handle(handle); cugraph_error_free(ret_error); diff --git a/cpp/tests/c_api/edge_betweenness_centrality_test.c b/cpp/tests/c_api/edge_betweenness_centrality_test.c index 95b875b21af..8b9167778d9 100644 --- a/cpp/tests/c_api/edge_betweenness_centrality_test.c +++ b/cpp/tests/c_api/edge_betweenness_centrality_test.c @@ -128,7 +128,7 @@ int generic_edge_betweenness_centrality_test(vertex_t* h_src, } cugraph_edge_centrality_result_free(result); - cugraph_sg_graph_free(graph); + cugraph_graph_free(graph); cugraph_free_resource_handle(handle); cugraph_error_free(ret_error); diff --git a/cpp/tests/c_api/egonet_test.c b/cpp/tests/c_api/egonet_test.c index b4d27935ce1..1bde50afbad 100644 --- a/cpp/tests/c_api/egonet_test.c +++ b/cpp/tests/c_api/egonet_test.c @@ -165,7 +165,7 @@ int generic_egonet_test(vertex_t* h_src, cugraph_induced_subgraph_result_free(result); } - cugraph_sg_graph_free(graph); + cugraph_graph_free(graph); cugraph_free_resource_handle(resource_handle); cugraph_error_free(ret_error); diff --git a/cpp/tests/c_api/eigenvector_centrality_test.c b/cpp/tests/c_api/eigenvector_centrality_test.c index ded505aeedc..d42745917d2 100644 --- a/cpp/tests/c_api/eigenvector_centrality_test.c +++ b/cpp/tests/c_api/eigenvector_centrality_test.c @@ -83,7 +83,7 @@ int generic_eigenvector_centrality_test(vertex_t* h_src, } cugraph_centrality_result_free(p_result); - cugraph_sg_graph_free(p_graph); + cugraph_graph_free(p_graph); cugraph_free_resource_handle(p_handle); cugraph_error_free(ret_error); diff --git a/cpp/tests/c_api/extract_paths_test.c b/cpp/tests/c_api/extract_paths_test.c index 5b87c3151c7..46e23112742 100644 --- a/cpp/tests/c_api/extract_paths_test.c +++ b/cpp/tests/c_api/extract_paths_test.c @@ -124,7 +124,7 @@ int generic_bfs_test_with_extract_paths(vertex_t* h_src, cugraph_type_erased_device_array_free(p_destinations); cugraph_extract_paths_result_free(p_extract_paths_result); cugraph_paths_result_free(p_paths_result); - cugraph_sg_graph_free(p_graph); + cugraph_graph_free(p_graph); cugraph_free_resource_handle(p_handle); cugraph_error_free(ret_error); diff --git a/cpp/tests/c_api/hits_test.c b/cpp/tests/c_api/hits_test.c index a9dbbb4f224..db63b0366b5 100644 --- a/cpp/tests/c_api/hits_test.c +++ b/cpp/tests/c_api/hits_test.c @@ -153,7 +153,7 @@ int generic_hits_test(vertex_t* h_src, } cugraph_hits_result_free(p_result); - cugraph_sg_graph_free(p_graph); + cugraph_graph_free(p_graph); cugraph_free_resource_handle(p_handle); cugraph_error_free(ret_error); diff --git a/cpp/tests/c_api/k_core_test.c b/cpp/tests/c_api/k_core_test.c index 81c1973d051..c60001fc8e7 100644 --- a/cpp/tests/c_api/k_core_test.c +++ b/cpp/tests/c_api/k_core_test.c @@ -142,7 +142,7 @@ int generic_k_core_test(vertex_t* h_src, cugraph_k_core_result_free(k_core_result); cugraph_core_result_free(core_result); - cugraph_sg_graph_free(graph); + cugraph_graph_free(graph); cugraph_free_resource_handle(resource_handle); cugraph_error_free(ret_error); diff --git a/cpp/tests/c_api/k_truss_test.c b/cpp/tests/c_api/k_truss_test.c index 9aa90f66480..1ebacfead9f 100644 --- a/cpp/tests/c_api/k_truss_test.c +++ b/cpp/tests/c_api/k_truss_test.c @@ -150,7 +150,7 @@ int generic_k_truss_test(vertex_t* h_src, cugraph_induced_subgraph_result_free(result); } - cugraph_sg_graph_free(graph); + cugraph_graph_free(graph); cugraph_free_resource_handle(resource_handle); cugraph_error_free(ret_error); diff --git a/cpp/tests/c_api/katz_test.c b/cpp/tests/c_api/katz_test.c index 4ee61b2b806..33bb6a5a9af 100644 --- a/cpp/tests/c_api/katz_test.c +++ b/cpp/tests/c_api/katz_test.c @@ -93,7 +93,7 @@ int generic_katz_test(vertex_t* h_src, } cugraph_centrality_result_free(p_result); - cugraph_sg_graph_free(p_graph); + cugraph_graph_free(p_graph); cugraph_free_resource_handle(p_handle); cugraph_error_free(ret_error); diff --git a/cpp/tests/c_api/legacy_spectral_test.c b/cpp/tests/c_api/legacy_spectral_test.c index ecb61e47ae6..ad695dd0883 100644 --- a/cpp/tests/c_api/legacy_spectral_test.c +++ b/cpp/tests/c_api/legacy_spectral_test.c @@ -141,7 +141,7 @@ int generic_spectral_test(vertex_t* h_src, cugraph_clustering_result_free(result); } - cugraph_sg_graph_free(graph); + cugraph_graph_free(graph); cugraph_free_resource_handle(handle); cugraph_error_free(ret_error); @@ -272,7 +272,7 @@ int generic_balanced_cut_test(vertex_t* h_src, cugraph_clustering_result_free(result); } - cugraph_sg_graph_free(graph); + cugraph_graph_free(graph); cugraph_free_resource_handle(handle); cugraph_error_free(ret_error); diff --git a/cpp/tests/c_api/leiden_test.c b/cpp/tests/c_api/leiden_test.c index df206ebd1ed..57e6e921cce 100644 --- a/cpp/tests/c_api/leiden_test.c +++ b/cpp/tests/c_api/leiden_test.c @@ -114,7 +114,7 @@ int generic_leiden_test(vertex_t* h_src, cugraph_hierarchical_clustering_result_free(p_result); } - cugraph_sg_graph_free(p_graph); + cugraph_graph_free(p_graph); cugraph_free_resource_handle(p_handle); cugraph_error_free(ret_error); diff --git a/cpp/tests/c_api/louvain_test.c b/cpp/tests/c_api/louvain_test.c index 41d777545b2..c083dbaa676 100644 --- a/cpp/tests/c_api/louvain_test.c +++ b/cpp/tests/c_api/louvain_test.c @@ -114,7 +114,7 @@ int generic_louvain_test(vertex_t* h_src, cugraph_hierarchical_clustering_result_free(p_result); } - cugraph_sg_graph_free(p_graph); + cugraph_graph_free(p_graph); cugraph_free_resource_handle(p_handle); cugraph_error_free(ret_error); diff --git a/cpp/tests/c_api/mg_betweenness_centrality_test.c b/cpp/tests/c_api/mg_betweenness_centrality_test.c index 6a3cb69dd57..6f45792200e 100644 --- a/cpp/tests/c_api/mg_betweenness_centrality_test.c +++ b/cpp/tests/c_api/mg_betweenness_centrality_test.c @@ -118,7 +118,7 @@ int generic_betweenness_centrality_test(const cugraph_resource_handle_t* handle, cugraph_type_erased_device_array_view_free(seeds_view); cugraph_type_erased_device_array_free(seeds); - cugraph_mg_graph_free(p_graph); + cugraph_graph_free(p_graph); cugraph_error_free(ret_error); return test_ret_value; diff --git a/cpp/tests/c_api/mg_bfs_test.c b/cpp/tests/c_api/mg_bfs_test.c index 026d8f0796c..db24a180774 100644 --- a/cpp/tests/c_api/mg_bfs_test.c +++ b/cpp/tests/c_api/mg_bfs_test.c @@ -106,7 +106,7 @@ int generic_bfs_test(const cugraph_resource_handle_t* p_handle, } cugraph_paths_result_free(paths_result); - cugraph_mg_graph_free(p_graph); + cugraph_graph_free(p_graph); cugraph_error_free(ret_error); return test_ret_value; diff --git a/cpp/tests/c_api/mg_biased_neighbor_sample_test.c b/cpp/tests/c_api/mg_biased_neighbor_sample_test.c index ce96fc6f5f7..ead86f22ad3 100644 --- a/cpp/tests/c_api/mg_biased_neighbor_sample_test.c +++ b/cpp/tests/c_api/mg_biased_neighbor_sample_test.c @@ -432,7 +432,7 @@ int generic_biased_neighbor_sample_test(const cugraph_resource_handle_t* handle, cugraph_sample_result_free(result); #endif - cugraph_mg_graph_free(graph); + cugraph_graph_free(graph); cugraph_error_free(ret_error); return test_ret_value; } @@ -678,7 +678,7 @@ int test_biased_neighbor_from_alex(const cugraph_resource_handle_t* handle) cugraph_sample_result_free(result); cugraph_type_erased_host_array_view_free(h_fan_out_view); - cugraph_mg_graph_free(graph); + cugraph_graph_free(graph); cugraph_error_free(ret_error); cugraph_sampling_options_free(sampling_options); @@ -941,7 +941,7 @@ int test_biased_neighbor_sample_alex_bug(const cugraph_resource_handle_t* handle cugraph_sample_result_free(result); #endif - cugraph_sg_graph_free(graph); + cugraph_graph_free(graph); cugraph_error_free(ret_error); } @@ -1221,7 +1221,7 @@ int test_biased_neighbor_sample_sort_by_hop(const cugraph_resource_handle_t* han cugraph_sample_result_free(result); #endif - cugraph_sg_graph_free(graph); + cugraph_graph_free(graph); cugraph_error_free(ret_error); } diff --git a/cpp/tests/c_api/mg_core_number_test.c b/cpp/tests/c_api/mg_core_number_test.c index 68c69a83c4f..a588c1997b1 100644 --- a/cpp/tests/c_api/mg_core_number_test.c +++ b/cpp/tests/c_api/mg_core_number_test.c @@ -79,7 +79,7 @@ int generic_core_number_test(const cugraph_resource_handle_t* p_handle, } cugraph_core_result_free(p_result); - cugraph_sg_graph_free(p_graph); + cugraph_graph_free(p_graph); cugraph_error_free(ret_error); return test_ret_value; diff --git a/cpp/tests/c_api/mg_create_graph_test.c b/cpp/tests/c_api/mg_create_graph_test.c index dd817881325..12579f26d06 100644 --- a/cpp/tests/c_api/mg_create_graph_test.c +++ b/cpp/tests/c_api/mg_create_graph_test.c @@ -109,6 +109,7 @@ int test_create_mg_graph_simple(const cugraph_resource_handle_t* handle) 1, FALSE, FALSE, + FALSE, TRUE, &graph, &ret_error); @@ -251,6 +252,7 @@ int test_create_mg_graph_multiple_edge_lists(const cugraph_resource_handle_t* ha num_local_arrays, FALSE, FALSE, + FALSE, TRUE, &graph, &ret_error); @@ -446,6 +448,7 @@ int test_create_mg_graph_multiple_edge_lists_multi_edge(const cugraph_resource_h num_local_arrays, TRUE, TRUE, + FALSE, TRUE, &graph, &ret_error); diff --git a/cpp/tests/c_api/mg_ecg_test.c b/cpp/tests/c_api/mg_ecg_test.c index b14ebda2959..626cb6025f5 100644 --- a/cpp/tests/c_api/mg_ecg_test.c +++ b/cpp/tests/c_api/mg_ecg_test.c @@ -100,7 +100,7 @@ int generic_ecg_test(const cugraph_resource_handle_t* handle, cugraph_hierarchical_clustering_result_free(result); } - cugraph_mg_graph_free(graph); + cugraph_graph_free(graph); cugraph_error_free(ret_error); return test_ret_value; diff --git a/cpp/tests/c_api/mg_edge_betweenness_centrality_test.c b/cpp/tests/c_api/mg_edge_betweenness_centrality_test.c index 319d4fb789b..cc3cc4c94c5 100644 --- a/cpp/tests/c_api/mg_edge_betweenness_centrality_test.c +++ b/cpp/tests/c_api/mg_edge_betweenness_centrality_test.c @@ -130,7 +130,7 @@ int generic_edge_betweenness_centrality_test(const cugraph_resource_handle_t* ha } cugraph_edge_centrality_result_free(result); - cugraph_mg_graph_free(graph); + cugraph_graph_free(graph); cugraph_error_free(ret_error); return test_ret_value; diff --git a/cpp/tests/c_api/mg_egonet_test.c b/cpp/tests/c_api/mg_egonet_test.c index 6a308102ebe..41328f1f908 100644 --- a/cpp/tests/c_api/mg_egonet_test.c +++ b/cpp/tests/c_api/mg_egonet_test.c @@ -161,7 +161,7 @@ int generic_egonet_test(const cugraph_resource_handle_t* resource_handle, cugraph_induced_subgraph_result_free(result); } - cugraph_sg_graph_free(graph); + cugraph_graph_free(graph); cugraph_error_free(ret_error); return test_ret_value; diff --git a/cpp/tests/c_api/mg_eigenvector_centrality_test.c b/cpp/tests/c_api/mg_eigenvector_centrality_test.c index 37bf2afca3c..cdf2387fdb3 100644 --- a/cpp/tests/c_api/mg_eigenvector_centrality_test.c +++ b/cpp/tests/c_api/mg_eigenvector_centrality_test.c @@ -84,7 +84,7 @@ int generic_eigenvector_centrality_test(const cugraph_resource_handle_t* handle, } cugraph_centrality_result_free(p_result); - cugraph_mg_graph_free(p_graph); + cugraph_graph_free(p_graph); cugraph_error_free(ret_error); return test_ret_value; diff --git a/cpp/tests/c_api/mg_hits_test.c b/cpp/tests/c_api/mg_hits_test.c index 3e10bfc05d6..201718417a7 100644 --- a/cpp/tests/c_api/mg_hits_test.c +++ b/cpp/tests/c_api/mg_hits_test.c @@ -154,7 +154,7 @@ int generic_hits_test(const cugraph_resource_handle_t* p_handle, } cugraph_hits_result_free(p_result); - cugraph_mg_graph_free(p_graph); + cugraph_graph_free(p_graph); cugraph_error_free(ret_error); return test_ret_value; diff --git a/cpp/tests/c_api/mg_induced_subgraph_test.c b/cpp/tests/c_api/mg_induced_subgraph_test.c index 018b308688e..39eefb9258c 100644 --- a/cpp/tests/c_api/mg_induced_subgraph_test.c +++ b/cpp/tests/c_api/mg_induced_subgraph_test.c @@ -153,7 +153,7 @@ int generic_induced_subgraph_test(const cugraph_resource_handle_t* handle, cugraph_type_erased_device_array_free(subgraph_offsets); cugraph_type_erased_device_array_free(subgraph_vertices); cugraph_induced_subgraph_result_free(result); - cugraph_mg_graph_free(graph); + cugraph_graph_free(graph); cugraph_error_free(ret_error); return test_ret_value; } diff --git a/cpp/tests/c_api/mg_k_core_test.c b/cpp/tests/c_api/mg_k_core_test.c index 1218475481b..45aa1283679 100644 --- a/cpp/tests/c_api/mg_k_core_test.c +++ b/cpp/tests/c_api/mg_k_core_test.c @@ -110,7 +110,7 @@ int generic_k_core_test(const cugraph_resource_handle_t* resource_handle, cugraph_k_core_result_free(k_core_result); cugraph_core_result_free(core_result); - cugraph_mg_graph_free(graph); + cugraph_graph_free(graph); cugraph_error_free(ret_error); return test_ret_value; diff --git a/cpp/tests/c_api/mg_k_truss_test.c b/cpp/tests/c_api/mg_k_truss_test.c index e406eb330a7..ed385c6ca76 100644 --- a/cpp/tests/c_api/mg_k_truss_test.c +++ b/cpp/tests/c_api/mg_k_truss_test.c @@ -16,6 +16,7 @@ #include "mg_test_utils.h" /* RUN_TEST */ +#include #include #include @@ -99,7 +100,7 @@ int generic_k_truss_test(const cugraph_resource_handle_t* handle, } cugraph_induced_subgraph_result_free(result); - cugraph_mg_graph_free(graph); + cugraph_graph_free(graph); cugraph_error_free(ret_error); return test_ret_value; } diff --git a/cpp/tests/c_api/mg_katz_test.c b/cpp/tests/c_api/mg_katz_test.c index 2efb5d50539..6d000c335da 100644 --- a/cpp/tests/c_api/mg_katz_test.c +++ b/cpp/tests/c_api/mg_katz_test.c @@ -94,7 +94,7 @@ int generic_katz_test(const cugraph_resource_handle_t* handle, } cugraph_centrality_result_free(p_result); - cugraph_mg_graph_free(p_graph); + cugraph_graph_free(p_graph); cugraph_error_free(ret_error); return test_ret_value; diff --git a/cpp/tests/c_api/mg_leiden_test.c b/cpp/tests/c_api/mg_leiden_test.c index 72719b4d515..231c021c467 100644 --- a/cpp/tests/c_api/mg_leiden_test.c +++ b/cpp/tests/c_api/mg_leiden_test.c @@ -105,7 +105,7 @@ int generic_leiden_test(const cugraph_resource_handle_t* p_handle, cugraph_hierarchical_clustering_result_free(p_result); } - cugraph_mg_graph_free(p_graph); + cugraph_graph_free(p_graph); cugraph_error_free(ret_error); return test_ret_value; diff --git a/cpp/tests/c_api/mg_lookup_src_dst_test.c b/cpp/tests/c_api/mg_lookup_src_dst_test.c index 0cffffeb425..8c85d245acc 100644 --- a/cpp/tests/c_api/mg_lookup_src_dst_test.c +++ b/cpp/tests/c_api/mg_lookup_src_dst_test.c @@ -206,7 +206,7 @@ int generic_lookup_src_dst_test(const cugraph_resource_handle_t* handle, cugraph_lookup_result_free(result); - cugraph_mg_graph_free(graph); + cugraph_graph_free(graph); cugraph_error_free(ret_error); return test_ret_value; diff --git a/cpp/tests/c_api/mg_louvain_test.c b/cpp/tests/c_api/mg_louvain_test.c index 858783614e5..54331fd8c66 100644 --- a/cpp/tests/c_api/mg_louvain_test.c +++ b/cpp/tests/c_api/mg_louvain_test.c @@ -96,7 +96,7 @@ int generic_louvain_test(const cugraph_resource_handle_t* p_handle, cugraph_hierarchical_clustering_result_free(p_result); } - cugraph_mg_graph_free(p_graph); + cugraph_graph_free(p_graph); cugraph_error_free(ret_error); return test_ret_value; diff --git a/cpp/tests/c_api/mg_negative_sampling_test.c b/cpp/tests/c_api/mg_negative_sampling_test.c index 3289206d8db..274bad35dfb 100644 --- a/cpp/tests/c_api/mg_negative_sampling_test.c +++ b/cpp/tests/c_api/mg_negative_sampling_test.c @@ -203,7 +203,7 @@ int generic_negative_sampling_test(const cugraph_resource_handle_t* handle, cugraph_type_erased_device_array_free(d_src_bias); cugraph_type_erased_device_array_free(d_dst_bias); cugraph_coo_free(result); - cugraph_mg_graph_free(graph); + cugraph_graph_free(graph); cugraph_error_free(ret_error); return test_ret_value; } diff --git a/cpp/tests/c_api/mg_pagerank_test.c b/cpp/tests/c_api/mg_pagerank_test.c index 8bd02e70181..4616db3f704 100644 --- a/cpp/tests/c_api/mg_pagerank_test.c +++ b/cpp/tests/c_api/mg_pagerank_test.c @@ -94,7 +94,7 @@ int generic_pagerank_test(const cugraph_resource_handle_t* handle, } cugraph_centrality_result_free(p_result); - cugraph_mg_graph_free(p_graph); + cugraph_graph_free(p_graph); cugraph_error_free(ret_error); return test_ret_value; @@ -169,7 +169,7 @@ int generic_pagerank_nonconverging_test(const cugraph_resource_handle_t* handle, } cugraph_centrality_result_free(p_result); - cugraph_mg_graph_free(p_graph); + cugraph_graph_free(p_graph); cugraph_error_free(ret_error); return test_ret_value; @@ -278,7 +278,7 @@ int generic_personalized_pagerank_test(const cugraph_resource_handle_t* handle, } cugraph_centrality_result_free(p_result); - cugraph_mg_graph_free(p_graph); + cugraph_graph_free(p_graph); cugraph_error_free(ret_error); return test_ret_value; @@ -387,7 +387,7 @@ int generic_personalized_pagerank_nonconverging_test(const cugraph_resource_hand } cugraph_centrality_result_free(p_result); - cugraph_mg_graph_free(p_graph); + cugraph_graph_free(p_graph); cugraph_error_free(ret_error); return test_ret_value; diff --git a/cpp/tests/c_api/mg_random_walks_test.c b/cpp/tests/c_api/mg_random_walks_test.c index 1c3e4ac0d38..13252e0f1dc 100644 --- a/cpp/tests/c_api/mg_random_walks_test.c +++ b/cpp/tests/c_api/mg_random_walks_test.c @@ -130,7 +130,7 @@ int generic_uniform_random_walks_test(const cugraph_resource_handle_t* handle, } cugraph_random_walk_result_free(result); - cugraph_mg_graph_free(graph); + cugraph_graph_free(graph); cugraph_error_free(ret_error); return test_ret_value; @@ -232,7 +232,7 @@ int generic_biased_random_walks_test(const cugraph_resource_handle_t* handle, cugraph_random_walk_result_free(result); #endif - cugraph_mg_graph_free(graph); + cugraph_graph_free(graph); cugraph_error_free(ret_error); return test_ret_value; @@ -338,7 +338,7 @@ int generic_node2vec_random_walks_test(const cugraph_resource_handle_t* handle, cugraph_random_walk_result_free(result); #endif - cugraph_mg_graph_free(graph); + cugraph_graph_free(graph); cugraph_error_free(ret_error); return test_ret_value; diff --git a/cpp/tests/c_api/mg_similarity_test.c b/cpp/tests/c_api/mg_similarity_test.c index 486ca34aaca..637f66e40ed 100644 --- a/cpp/tests/c_api/mg_similarity_test.c +++ b/cpp/tests/c_api/mg_similarity_test.c @@ -189,7 +189,7 @@ int generic_similarity_test(const cugraph_resource_handle_t* handle, if (result != NULL) cugraph_similarity_result_free(result); if (vertex_pairs != NULL) cugraph_vertex_pairs_free(vertex_pairs); - cugraph_mg_graph_free(graph); + cugraph_graph_free(graph); cugraph_error_free(ret_error); return test_ret_value; diff --git a/cpp/tests/c_api/mg_sssp_test.c b/cpp/tests/c_api/mg_sssp_test.c index 1158885aed2..3103b7331f4 100644 --- a/cpp/tests/c_api/mg_sssp_test.c +++ b/cpp/tests/c_api/mg_sssp_test.c @@ -94,7 +94,7 @@ int generic_sssp_test(const cugraph_resource_handle_t* p_handle, cugraph_type_erased_device_array_view_free(distances); cugraph_type_erased_device_array_view_free(predecessors); cugraph_paths_result_free(p_result); - cugraph_sg_graph_free(p_graph); + cugraph_graph_free(p_graph); cugraph_error_free(ret_error); return test_ret_value; @@ -167,7 +167,7 @@ int generic_sssp_test_double(const cugraph_resource_handle_t* p_handle, cugraph_type_erased_device_array_view_free(distances); cugraph_type_erased_device_array_view_free(predecessors); cugraph_paths_result_free(p_result); - cugraph_sg_graph_free(p_graph); + cugraph_graph_free(p_graph); cugraph_error_free(ret_error); return test_ret_value; diff --git a/cpp/tests/c_api/mg_strongly_connected_components_test.c b/cpp/tests/c_api/mg_strongly_connected_components_test.c index 38b2691c784..95777cc86fe 100644 --- a/cpp/tests/c_api/mg_strongly_connected_components_test.c +++ b/cpp/tests/c_api/mg_strongly_connected_components_test.c @@ -100,7 +100,7 @@ int generic_scc_test(const cugraph_resource_handle_t* handle, cugraph_labeling_result_free(p_result); #endif - cugraph_mg_graph_free(p_graph); + cugraph_graph_free(p_graph); cugraph_error_free(ret_error); return test_ret_value; diff --git a/cpp/tests/c_api/mg_test_utils.cpp b/cpp/tests/c_api/mg_test_utils.cpp index 58c5e59c16f..98b64014726 100644 --- a/cpp/tests/c_api/mg_test_utils.cpp +++ b/cpp/tests/c_api/mg_test_utils.cpp @@ -191,16 +191,20 @@ extern "C" int create_mg_test_graph(const cugraph_resource_handle_t* handle, handle, wgt_view, (byte_t*)h_wgt, ret_error); TEST_ASSERT(test_ret_value, ret_code == CUGRAPH_SUCCESS, "wgt copy_from_host failed."); - ret_code = cugraph_mg_graph_create(handle, + ret_code = cugraph_graph_create_mg(handle, &properties, - src_view, - dst_view, - wgt_view, + NULL, + &src_view, + &dst_view, + &wgt_view, NULL, NULL, store_transposed, original_num_edges, // UNUSED FALSE, + FALSE, + FALSE, + FALSE, p_graph, ret_error); TEST_ASSERT(test_ret_value, ret_code == CUGRAPH_SUCCESS, "graph creation failed."); @@ -285,16 +289,20 @@ extern "C" int create_mg_test_graph_double(const cugraph_resource_handle_t* hand handle, wgt_view, (byte_t*)h_wgt, ret_error); TEST_ASSERT(test_ret_value, ret_code == CUGRAPH_SUCCESS, "wgt copy_from_host failed."); - ret_code = cugraph_mg_graph_create(handle, + ret_code = cugraph_graph_create_mg(handle, &properties, - src_view, - dst_view, - wgt_view, + NULL, + &src_view, + &dst_view, + &wgt_view, NULL, NULL, store_transposed, original_num_edges, // UNUSED FALSE, + FALSE, + FALSE, + FALSE, p_graph, ret_error); TEST_ASSERT(test_ret_value, ret_code == CUGRAPH_SUCCESS, "graph creation failed."); @@ -373,16 +381,20 @@ extern "C" int create_mg_test_graph_with_edge_ids(const cugraph_resource_handle_ handle, idx_view, (byte_t*)h_idx, ret_error); TEST_ASSERT(test_ret_value, ret_code == CUGRAPH_SUCCESS, "wgt copy_from_host failed."); - ret_code = cugraph_mg_graph_create(handle, + ret_code = cugraph_graph_create_mg(handle, &properties, - src_view, - dst_view, NULL, - idx_view, + &src_view, + &dst_view, + NULL, + &idx_view, NULL, store_transposed, original_num_edges, // UNUSED FALSE, + FALSE, + FALSE, + FALSE, p_graph, ret_error); TEST_ASSERT(test_ret_value, ret_code == CUGRAPH_SUCCESS, "graph creation failed."); @@ -496,16 +508,20 @@ extern "C" int create_mg_test_graph_with_properties(const cugraph_resource_handl TEST_ASSERT(test_ret_value, ret_code == CUGRAPH_SUCCESS, "wgt copy_from_host failed."); } - ret_code = cugraph_mg_graph_create(handle, + ret_code = cugraph_graph_create_mg(handle, &properties, - src_view, - dst_view, - wgt_view, - idx_view, - type_view, + NULL, + &src_view, + &dst_view, + &wgt_view, + &idx_view, + &type_view, store_transposed, original_num_edges, // UNUSED FALSE, + FALSE, + FALSE, + FALSE, p_graph, ret_error); TEST_ASSERT(test_ret_value, ret_code == CUGRAPH_SUCCESS, "graph creation failed."); @@ -625,16 +641,20 @@ int create_mg_test_graph_new(const cugraph_resource_handle_t* handle, TEST_ASSERT(test_ret_value, ret_code == CUGRAPH_SUCCESS, "edge_id copy_from_host failed."); } - ret_code = cugraph_mg_graph_create(handle, + ret_code = cugraph_graph_create_mg(handle, &properties, - src_view, - dst_view, - wgt_view, - edge_id_view, - edge_type_view, + NULL, + &src_view, + &dst_view, + &wgt_view, + &edge_id_view, + &edge_type_view, store_transposed, original_num_edges, // UNUSED FALSE, + FALSE, + FALSE, + FALSE, graph, ret_error); TEST_ASSERT(test_ret_value, ret_code == CUGRAPH_SUCCESS, "graph creation failed."); diff --git a/cpp/tests/c_api/mg_triangle_count_test.c b/cpp/tests/c_api/mg_triangle_count_test.c index d6eec6aad25..149c42046f5 100644 --- a/cpp/tests/c_api/mg_triangle_count_test.c +++ b/cpp/tests/c_api/mg_triangle_count_test.c @@ -105,7 +105,7 @@ int generic_triangle_count_test(const cugraph_resource_handle_t* handle, cugraph_triangle_count_result_free(p_result); } - cugraph_mg_graph_free(p_graph); + cugraph_graph_free(p_graph); cugraph_error_free(ret_error); return test_ret_value; diff --git a/cpp/tests/c_api/mg_two_hop_neighbors_test.c b/cpp/tests/c_api/mg_two_hop_neighbors_test.c index 056da2bcc45..31d5d535c8d 100644 --- a/cpp/tests/c_api/mg_two_hop_neighbors_test.c +++ b/cpp/tests/c_api/mg_two_hop_neighbors_test.c @@ -110,7 +110,7 @@ int generic_two_hop_nbr_test(const cugraph_resource_handle_t* resource_handle, cugraph_vertex_pairs_free(result); cugraph_type_erased_device_array_view_free(start_vertices_view); cugraph_type_erased_device_array_free(start_vertices); - cugraph_mg_graph_free(graph); + cugraph_graph_free(graph); cugraph_error_free(ret_error); return test_ret_value; diff --git a/cpp/tests/c_api/mg_uniform_neighbor_sample_test.c b/cpp/tests/c_api/mg_uniform_neighbor_sample_test.c index 3d8fb02ed46..b046b453c1c 100644 --- a/cpp/tests/c_api/mg_uniform_neighbor_sample_test.c +++ b/cpp/tests/c_api/mg_uniform_neighbor_sample_test.c @@ -431,7 +431,7 @@ int generic_uniform_neighbor_sample_test(const cugraph_resource_handle_t* handle cugraph_sample_result_free(result); #endif - cugraph_mg_graph_free(graph); + cugraph_graph_free(graph); cugraph_error_free(ret_error); return test_ret_value; } @@ -676,7 +676,7 @@ int test_uniform_neighbor_from_alex(const cugraph_resource_handle_t* handle) cugraph_sample_result_free(result); cugraph_type_erased_host_array_view_free(h_fan_out_view); - cugraph_mg_graph_free(graph); + cugraph_graph_free(graph); cugraph_error_free(ret_error); cugraph_sampling_options_free(sampling_options); @@ -938,7 +938,7 @@ int test_uniform_neighbor_sample_alex_bug(const cugraph_resource_handle_t* handl cugraph_sample_result_free(result); #endif - cugraph_sg_graph_free(graph); + cugraph_graph_free(graph); cugraph_error_free(ret_error); } @@ -1217,7 +1217,7 @@ int test_uniform_neighbor_sample_sort_by_hop(const cugraph_resource_handle_t* ha cugraph_sample_result_free(result); #endif - cugraph_sg_graph_free(graph); + cugraph_graph_free(graph); cugraph_error_free(ret_error); } diff --git a/cpp/tests/c_api/mg_weakly_connected_components_test.c b/cpp/tests/c_api/mg_weakly_connected_components_test.c index 3410c6dfd69..9b9dcfd6d5a 100644 --- a/cpp/tests/c_api/mg_weakly_connected_components_test.c +++ b/cpp/tests/c_api/mg_weakly_connected_components_test.c @@ -93,7 +93,7 @@ int generic_wcc_test(const cugraph_resource_handle_t* handle, cugraph_type_erased_device_array_view_free(components); cugraph_type_erased_device_array_view_free(vertices); cugraph_labeling_result_free(p_result); - cugraph_mg_graph_free(p_graph); + cugraph_graph_free(p_graph); cugraph_error_free(ret_error); return test_ret_value; diff --git a/cpp/tests/c_api/negative_sampling_test.c b/cpp/tests/c_api/negative_sampling_test.c index 5e8d3f7e765..52360d622dd 100644 --- a/cpp/tests/c_api/negative_sampling_test.c +++ b/cpp/tests/c_api/negative_sampling_test.c @@ -194,7 +194,7 @@ int generic_negative_sampling_test(const cugraph_resource_handle_t* handle, cugraph_type_erased_device_array_free(d_vertices); cugraph_type_erased_device_array_free(d_src_bias); cugraph_coo_free(result); - cugraph_sg_graph_free(graph); + cugraph_graph_free(graph); cugraph_error_free(ret_error); return test_ret_value; } diff --git a/cpp/tests/c_api/pagerank_test.c b/cpp/tests/c_api/pagerank_test.c index 0d55852dbb2..b0caef58eee 100644 --- a/cpp/tests/c_api/pagerank_test.c +++ b/cpp/tests/c_api/pagerank_test.c @@ -93,7 +93,7 @@ int generic_pagerank_test(vertex_t* h_src, } cugraph_centrality_result_free(p_result); - cugraph_sg_graph_free(p_graph); + cugraph_graph_free(p_graph); cugraph_free_resource_handle(p_handle); cugraph_error_free(ret_error); @@ -168,7 +168,7 @@ int generic_pagerank_nonconverging_test(vertex_t* h_src, } cugraph_centrality_result_free(p_result); - cugraph_sg_graph_free(p_graph); + cugraph_graph_free(p_graph); cugraph_free_resource_handle(p_handle); cugraph_error_free(ret_error); @@ -277,7 +277,7 @@ int generic_personalized_pagerank_test(vertex_t* h_src, } cugraph_centrality_result_free(p_result); - cugraph_sg_graph_free(p_graph); + cugraph_graph_free(p_graph); cugraph_free_resource_handle(p_handle); cugraph_error_free(ret_error); @@ -386,7 +386,7 @@ int generic_personalized_pagerank_nonconverging_test(vertex_t* h_src, } cugraph_centrality_result_free(p_result); - cugraph_sg_graph_free(p_graph); + cugraph_graph_free(p_graph); cugraph_free_resource_handle(p_handle); cugraph_error_free(ret_error); diff --git a/cpp/tests/c_api/sg_random_walks_test.c b/cpp/tests/c_api/sg_random_walks_test.c index 14108d91c04..05d77a0b3b2 100644 --- a/cpp/tests/c_api/sg_random_walks_test.c +++ b/cpp/tests/c_api/sg_random_walks_test.c @@ -141,7 +141,7 @@ int generic_uniform_random_walks_test(vertex_t* h_src, } cugraph_random_walk_result_free(result); - cugraph_sg_graph_free(graph); + cugraph_graph_free(graph); cugraph_free_resource_handle(handle); cugraph_error_free(ret_error); @@ -192,9 +192,6 @@ int generic_biased_random_walks_test(vertex_t* h_src, ret_code = cugraph_biased_random_walks(handle, graph, d_start_view, max_depth, &result, &ret_error); -#if 1 - TEST_ASSERT(test_ret_value, ret_code != CUGRAPH_SUCCESS, "biased_random_walks should have failed") -#else TEST_ASSERT(test_ret_value, ret_code == CUGRAPH_SUCCESS, cugraph_error_message(ret_error)); TEST_ASSERT(test_ret_value, ret_code == CUGRAPH_SUCCESS, "biased_random_walks failed."); @@ -208,10 +205,10 @@ int generic_biased_random_walks_test(vertex_t* h_src, size_t wgts_size = cugraph_type_erased_device_array_view_size(wgts); vertex_t h_result_verts[verts_size]; - vertex_t h_result_wgts[wgts_size]; + weight_t h_result_wgts[wgts_size]; - ret_code = - cugraph_type_erased_device_array_view_copy_to_host(handle, (byte_t*)h_verts, verts, &ret_error); + ret_code = cugraph_type_erased_device_array_view_copy_to_host( + handle, (byte_t*)h_result_verts, verts, &ret_error); TEST_ASSERT(test_ret_value, ret_code == CUGRAPH_SUCCESS, "copy_to_host failed."); ret_code = cugraph_type_erased_device_array_view_copy_to_host( @@ -231,25 +228,37 @@ int generic_biased_random_walks_test(vertex_t* h_src, M[h_src[i]][h_dst[i]] = h_wgt[i]; TEST_ASSERT(test_ret_value, - cugraph_random_walk_result_get_max_path_length() == max_depth, + cugraph_random_walk_result_get_max_path_length(result) == max_depth, "path length does not match"); for (int i = 0; (i < num_starts) && (test_ret_value == 0); ++i) { - TEST_ASSERT(test_ret_value, - M[h_start[i]][h_result_verts[i * (max_depth + 1)]] == h_result_wgts[i * max_depth], - "biased_random_walks got edge that doesn't exist"); - for (size_t j = 1; j < cugraph_random_walk_result_get_max_path_length(); ++j) - TEST_ASSERT( - test_ret_value, - M[h_start[i * (max_depth + 1) + j - 1]][h_result_verts[i * (max_depth + 1) + j]] == - h_result_wgts[i * max_depth + j - 1], - "biased_random_walks got edge that doesn't exist"); + TEST_ASSERT( + test_ret_value, h_start[i] == h_result_verts[i * (max_depth + 1)], "start of path not found"); + for (size_t j = 0; j < max_depth; ++j) { + int src_index = i * (max_depth + 1) + j; + int dst_index = src_index + 1; + if (h_result_verts[dst_index] < 0) { + if (h_result_verts[src_index] >= 0) { + int departing_count = 0; + for (int k = 0; k < num_vertices; ++k) { + if (M[h_result_verts[src_index]][k] >= 0) departing_count++; + } + TEST_ASSERT(test_ret_value, + departing_count == 0, + "biased_random_walks found no edge when an edge exists"); + } + } else { + TEST_ASSERT(test_ret_value, + M[h_result_verts[src_index]][h_result_verts[dst_index]] == + h_result_wgts[i * max_depth + j], + "biased_random_walks got edge that doesn't exist"); + } + } } cugraph_random_walk_result_free(result); -#endif - cugraph_sg_graph_free(graph); + cugraph_graph_free(graph); cugraph_free_resource_handle(handle); cugraph_error_free(ret_error); @@ -302,10 +311,6 @@ int generic_node2vec_random_walks_test(vertex_t* h_src, ret_code = cugraph_node2vec_random_walks( handle, graph, d_start_view, max_depth, p, q, &result, &ret_error); -#if 1 - TEST_ASSERT( - test_ret_value, ret_code != CUGRAPH_SUCCESS, "node2vec_random_walks should have failed") -#else TEST_ASSERT(test_ret_value, ret_code == CUGRAPH_SUCCESS, cugraph_error_message(ret_error)); TEST_ASSERT(test_ret_value, ret_code == CUGRAPH_SUCCESS, "node2vec_random_walks failed."); @@ -319,10 +324,10 @@ int generic_node2vec_random_walks_test(vertex_t* h_src, size_t wgts_size = cugraph_type_erased_device_array_view_size(wgts); vertex_t h_result_verts[verts_size]; - vertex_t h_result_wgts[wgts_size]; + weight_t h_result_wgts[wgts_size]; - ret_code = - cugraph_type_erased_device_array_view_copy_to_host(handle, (byte_t*)h_verts, verts, &ret_error); + ret_code = cugraph_type_erased_device_array_view_copy_to_host( + handle, (byte_t*)h_result_verts, verts, &ret_error); TEST_ASSERT(test_ret_value, ret_code == CUGRAPH_SUCCESS, "copy_to_host failed."); ret_code = cugraph_type_erased_device_array_view_copy_to_host( @@ -342,25 +347,37 @@ int generic_node2vec_random_walks_test(vertex_t* h_src, M[h_src[i]][h_dst[i]] = h_wgt[i]; TEST_ASSERT(test_ret_value, - cugraph_random_walk_result_get_max_path_length() == max_depth, + cugraph_random_walk_result_get_max_path_length(result) == max_depth, "path length does not match"); for (int i = 0; (i < num_starts) && (test_ret_value == 0); ++i) { - TEST_ASSERT(test_ret_value, - M[h_start[i]][h_result_verts[i * (max_depth + 1)]] == h_result_wgts[i * max_depth], - "node2vec_random_walks got edge that doesn't exist"); - for (size_t j = 1; j < max_depth; ++j) - TEST_ASSERT( - test_ret_value, - M[h_start[i * (max_depth + 1) + j - 1]][h_result_verts[i * (max_depth + 1) + j]] == - h_result_wgts[i * max_depth + j - 1], - "node2vec_random_walks got edge that doesn't exist"); + TEST_ASSERT( + test_ret_value, h_start[i] == h_result_verts[i * (max_depth + 1)], "start of path not found"); + for (size_t j = 0; j < max_depth; ++j) { + int src_index = i * (max_depth + 1) + j; + int dst_index = src_index + 1; + if (h_result_verts[dst_index] < 0) { + if (h_result_verts[src_index] >= 0) { + int departing_count = 0; + for (int k = 0; k < num_vertices; ++k) { + if (M[h_result_verts[src_index]][k] >= 0) departing_count++; + } + TEST_ASSERT(test_ret_value, + departing_count == 0, + "node2vec_random_walks found no edge when an edge exists"); + } + } else { + TEST_ASSERT(test_ret_value, + M[h_result_verts[src_index]][h_result_verts[dst_index]] == + h_result_wgts[i * max_depth + j], + "node2vec_random_walks got edge that doesn't exist"); + } + } } cugraph_random_walk_result_free(result); -#endif - cugraph_sg_graph_free(graph); + cugraph_graph_free(graph); cugraph_free_resource_handle(handle); cugraph_error_free(ret_error); @@ -390,7 +407,7 @@ int test_biased_random_walks() vertex_t src[] = {0, 1, 1, 2, 2, 2, 3, 4}; vertex_t dst[] = {1, 3, 4, 0, 1, 3, 5, 5}; - weight_t wgt[] = {0, 1, 2, 3, 4, 5, 6, 7}; + weight_t wgt[] = {1, 2, 3, 4, 5, 6, 7, 8}; vertex_t start[] = {2, 2}; return generic_biased_random_walks_test( diff --git a/cpp/tests/c_api/similarity_test.c b/cpp/tests/c_api/similarity_test.c index 70e0cb6fb95..ac4dff850fa 100644 --- a/cpp/tests/c_api/similarity_test.c +++ b/cpp/tests/c_api/similarity_test.c @@ -128,7 +128,7 @@ int generic_similarity_test(vertex_t* h_src, if (result != NULL) cugraph_similarity_result_free(result); if (vertex_pairs != NULL) cugraph_vertex_pairs_free(vertex_pairs); - cugraph_sg_graph_free(graph); + cugraph_graph_free(graph); cugraph_free_resource_handle(handle); cugraph_error_free(ret_error); @@ -238,7 +238,7 @@ int generic_all_pairs_similarity_test(vertex_t* h_src, } if (result != NULL) cugraph_similarity_result_free(result); - cugraph_sg_graph_free(graph); + cugraph_graph_free(graph); cugraph_free_resource_handle(handle); cugraph_error_free(ret_error); diff --git a/cpp/tests/c_api/sssp_test.c b/cpp/tests/c_api/sssp_test.c index 48039fcb43c..290542b1f9d 100644 --- a/cpp/tests/c_api/sssp_test.c +++ b/cpp/tests/c_api/sssp_test.c @@ -94,7 +94,7 @@ int generic_sssp_test(vertex_t* h_src, cugraph_type_erased_device_array_view_free(distances); cugraph_type_erased_device_array_view_free(predecessors); cugraph_paths_result_free(p_result); - cugraph_sg_graph_free(p_graph); + cugraph_graph_free(p_graph); cugraph_free_resource_handle(p_handle); cugraph_error_free(ret_error); @@ -168,7 +168,7 @@ int generic_sssp_test_double(vertex_t* h_src, cugraph_type_erased_device_array_view_free(distances); cugraph_type_erased_device_array_view_free(predecessors); cugraph_paths_result_free(p_result); - cugraph_sg_graph_free(p_graph); + cugraph_graph_free(p_graph); cugraph_free_resource_handle(p_handle); cugraph_error_free(ret_error); diff --git a/cpp/tests/c_api/strongly_connected_components_test.c b/cpp/tests/c_api/strongly_connected_components_test.c index 24dd24c3fcd..0706c33a0bb 100644 --- a/cpp/tests/c_api/strongly_connected_components_test.c +++ b/cpp/tests/c_api/strongly_connected_components_test.c @@ -95,7 +95,7 @@ int generic_scc_test(vertex_t* h_src, cugraph_type_erased_device_array_view_free(vertices); cugraph_labeling_result_free(p_result); - cugraph_sg_graph_free(p_graph); + cugraph_graph_free(p_graph); cugraph_free_resource_handle(p_handle); cugraph_error_free(ret_error); diff --git a/cpp/tests/c_api/test_utils.cpp b/cpp/tests/c_api/test_utils.cpp index 193251917a4..2df62345784 100644 --- a/cpp/tests/c_api/test_utils.cpp +++ b/cpp/tests/c_api/test_utils.cpp @@ -98,8 +98,9 @@ extern "C" int create_test_graph(const cugraph_resource_handle_t* p_handle, p_handle, wgt_view, (byte_t*)h_wgt, ret_error); TEST_ASSERT(test_ret_value, ret_code == CUGRAPH_SUCCESS, "wgt copy_from_host failed."); - ret_code = cugraph_sg_graph_create(p_handle, + ret_code = cugraph_graph_create_sg(p_handle, &properties, + nullptr, src_view, dst_view, wgt_view, @@ -108,6 +109,9 @@ extern "C" int create_test_graph(const cugraph_resource_handle_t* p_handle, store_transposed, renumber, FALSE, + FALSE, + FALSE, + FALSE, p_graph, ret_error); TEST_ASSERT(test_ret_value, ret_code == CUGRAPH_SUCCESS, "graph creation failed."); @@ -180,8 +184,9 @@ extern "C" int create_test_graph_double(const cugraph_resource_handle_t* p_handl p_handle, wgt_view, (byte_t*)h_wgt, ret_error); TEST_ASSERT(test_ret_value, ret_code == CUGRAPH_SUCCESS, "wgt copy_from_host failed."); - ret_code = cugraph_sg_graph_create(p_handle, + ret_code = cugraph_graph_create_sg(p_handle, &properties, + nullptr, src_view, dst_view, wgt_view, @@ -190,6 +195,9 @@ extern "C" int create_test_graph_double(const cugraph_resource_handle_t* p_handl store_transposed, renumber, FALSE, + FALSE, + FALSE, + FALSE, p_graph, ret_error); TEST_ASSERT(test_ret_value, ret_code == CUGRAPH_SUCCESS, "graph creation failed."); @@ -355,8 +363,9 @@ int create_sg_test_graph(const cugraph_resource_handle_t* handle, TEST_ASSERT(test_ret_value, ret_code == CUGRAPH_SUCCESS, "edge_id copy_from_host failed."); } - ret_code = cugraph_sg_graph_create(handle, + ret_code = cugraph_graph_create_sg(handle, &properties, + nullptr, src_view, dst_view, wgt_view, @@ -365,6 +374,9 @@ int create_sg_test_graph(const cugraph_resource_handle_t* handle, store_transposed, renumber, FALSE, + FALSE, + FALSE, + FALSE, graph, ret_error); TEST_ASSERT(test_ret_value, ret_code == CUGRAPH_SUCCESS, "graph creation failed."); diff --git a/cpp/tests/c_api/triangle_count_test.c b/cpp/tests/c_api/triangle_count_test.c index 5929e3d6560..383cc335941 100644 --- a/cpp/tests/c_api/triangle_count_test.c +++ b/cpp/tests/c_api/triangle_count_test.c @@ -102,7 +102,7 @@ int generic_triangle_count_test(vertex_t* h_src, cugraph_triangle_count_result_free(p_result); } - cugraph_sg_graph_free(p_graph); + cugraph_graph_free(p_graph); cugraph_free_resource_handle(p_handle); cugraph_error_free(ret_error); diff --git a/cpp/tests/c_api/two_hop_neighbors_test.c b/cpp/tests/c_api/two_hop_neighbors_test.c index bc95db3932b..44ccfd11622 100644 --- a/cpp/tests/c_api/two_hop_neighbors_test.c +++ b/cpp/tests/c_api/two_hop_neighbors_test.c @@ -117,7 +117,7 @@ int generic_two_hop_nbr_test(vertex_t* h_src, cugraph_vertex_pairs_free(result); cugraph_type_erased_device_array_view_free(start_vertices_view); cugraph_type_erased_device_array_free(start_vertices); - cugraph_sg_graph_free(graph); + cugraph_graph_free(graph); cugraph_free_resource_handle(resource_handle); cugraph_error_free(ret_error); diff --git a/cpp/tests/c_api/uniform_neighbor_sample_test.c b/cpp/tests/c_api/uniform_neighbor_sample_test.c index 451dbca51a7..404e38627ae 100644 --- a/cpp/tests/c_api/uniform_neighbor_sample_test.c +++ b/cpp/tests/c_api/uniform_neighbor_sample_test.c @@ -460,7 +460,7 @@ int generic_uniform_neighbor_sample_test(const cugraph_resource_handle_t* handle cugraph_sample_result_free(result); #endif - cugraph_sg_graph_free(graph); + cugraph_graph_free(graph); cugraph_error_free(ret_error); return test_ret_value; } @@ -528,8 +528,9 @@ int create_test_graph_with_edge_ids(const cugraph_resource_handle_t* p_handle, ret_code = cugraph_type_erased_device_array_view_as_type(ids, weight_tid, &wgt_view, ret_error); TEST_ASSERT(test_ret_value, ret_code == CUGRAPH_SUCCESS, "wgt cast from ids failed."); - ret_code = cugraph_sg_graph_create(p_handle, + ret_code = cugraph_graph_create_sg(p_handle, &properties, + NULL, src_view, dst_view, wgt_view, @@ -538,6 +539,9 @@ int create_test_graph_with_edge_ids(const cugraph_resource_handle_t* p_handle, store_transposed, renumber, FALSE, + FALSE, + FALSE, + FALSE, p_graph, ret_error); TEST_ASSERT(test_ret_value, ret_code == CUGRAPH_SUCCESS, "graph creation failed."); @@ -766,7 +770,7 @@ int test_uniform_neighbor_sample_with_labels(const cugraph_resource_handle_t* ha cugraph_sampling_options_free(sampling_options); #endif - cugraph_sg_graph_free(graph); + cugraph_graph_free(graph); cugraph_error_free(ret_error); } diff --git a/cpp/tests/c_api/weakly_connected_components_test.c b/cpp/tests/c_api/weakly_connected_components_test.c index ee1a6b9066b..04fdcbc8930 100644 --- a/cpp/tests/c_api/weakly_connected_components_test.c +++ b/cpp/tests/c_api/weakly_connected_components_test.c @@ -93,7 +93,7 @@ int generic_wcc_test(vertex_t* h_src, cugraph_type_erased_device_array_view_free(components); cugraph_type_erased_device_array_view_free(vertices); cugraph_labeling_result_free(p_result); - cugraph_sg_graph_free(p_graph); + cugraph_graph_free(p_graph); cugraph_free_resource_handle(p_handle); cugraph_error_free(ret_error); diff --git a/cpp/tests/centrality/betweenness_centrality_test.cpp b/cpp/tests/centrality/betweenness_centrality_test.cpp index 671e70bd40c..42f619efa2b 100644 --- a/cpp/tests/centrality/betweenness_centrality_test.cpp +++ b/cpp/tests/centrality/betweenness_centrality_test.cpp @@ -182,12 +182,6 @@ TEST_P(Tests_BetweennessCentrality_Rmat, CheckInt32Int32FloatFloat) override_Rmat_Usecase_with_cmd_line_arguments(GetParam())); } -TEST_P(Tests_BetweennessCentrality_Rmat, CheckInt32Int64FloatFloat) -{ - run_current_test( - override_Rmat_Usecase_with_cmd_line_arguments(GetParam())); -} - TEST_P(Tests_BetweennessCentrality_Rmat, CheckInt64Int64FloatFloat) { run_current_test( diff --git a/cpp/tests/centrality/edge_betweenness_centrality_test.cpp b/cpp/tests/centrality/edge_betweenness_centrality_test.cpp index 4f9cdbe6458..9ba840bde90 100644 --- a/cpp/tests/centrality/edge_betweenness_centrality_test.cpp +++ b/cpp/tests/centrality/edge_betweenness_centrality_test.cpp @@ -205,12 +205,6 @@ TEST_P(Tests_EdgeBetweennessCentrality_Rmat, CheckInt32Int32FloatFloat) override_Rmat_Usecase_with_cmd_line_arguments(GetParam())); } -TEST_P(Tests_EdgeBetweennessCentrality_Rmat, CheckInt32Int64FloatFloat) -{ - run_current_test( - override_Rmat_Usecase_with_cmd_line_arguments(GetParam())); -} - TEST_P(Tests_EdgeBetweennessCentrality_Rmat, CheckInt64Int64FloatFloat) { run_current_test( diff --git a/cpp/tests/centrality/eigenvector_centrality_test.cpp b/cpp/tests/centrality/eigenvector_centrality_test.cpp index 9e232888e77..f9bccd6256b 100644 --- a/cpp/tests/centrality/eigenvector_centrality_test.cpp +++ b/cpp/tests/centrality/eigenvector_centrality_test.cpp @@ -254,13 +254,6 @@ TEST_P(Tests_EigenvectorCentrality_Rmat, CheckInt32Int32FloatFloat) std::get<0>(param), override_Rmat_Usecase_with_cmd_line_arguments(std::get<1>(param))); } -TEST_P(Tests_EigenvectorCentrality_Rmat, CheckInt32Int64FloatFloat) -{ - auto param = GetParam(); - run_current_test( - std::get<0>(param), override_Rmat_Usecase_with_cmd_line_arguments(std::get<1>(param))); -} - TEST_P(Tests_EigenvectorCentrality_Rmat, CheckInt64Int64FloatFloat) { auto param = GetParam(); diff --git a/cpp/tests/centrality/katz_centrality_test.cpp b/cpp/tests/centrality/katz_centrality_test.cpp index fc5aead5d90..a6365a37c70 100644 --- a/cpp/tests/centrality/katz_centrality_test.cpp +++ b/cpp/tests/centrality/katz_centrality_test.cpp @@ -258,13 +258,6 @@ TEST_P(Tests_KatzCentrality_Rmat, CheckInt32Int32FloatFloat) std::get<0>(param), override_Rmat_Usecase_with_cmd_line_arguments(std::get<1>(param))); } -TEST_P(Tests_KatzCentrality_Rmat, CheckInt32Int64FloatFloat) -{ - auto param = GetParam(); - run_current_test( - std::get<0>(param), override_Rmat_Usecase_with_cmd_line_arguments(std::get<1>(param))); -} - TEST_P(Tests_KatzCentrality_Rmat, CheckInt64Int64FloatFloat) { auto param = GetParam(); diff --git a/cpp/tests/centrality/mg_betweenness_centrality_test.cpp b/cpp/tests/centrality/mg_betweenness_centrality_test.cpp index 65a1098033b..35f6a5157ff 100644 --- a/cpp/tests/centrality/mg_betweenness_centrality_test.cpp +++ b/cpp/tests/centrality/mg_betweenness_centrality_test.cpp @@ -205,12 +205,6 @@ TEST_P(Tests_MGBetweennessCentrality_Rmat, CheckInt32Int32FloatFloat) override_Rmat_Usecase_with_cmd_line_arguments(GetParam())); } -TEST_P(Tests_MGBetweennessCentrality_Rmat, CheckInt32Int64FloatFloat) -{ - run_current_test( - override_Rmat_Usecase_with_cmd_line_arguments(GetParam())); -} - TEST_P(Tests_MGBetweennessCentrality_Rmat, CheckInt64Int64FloatFloat) { run_current_test( diff --git a/cpp/tests/centrality/mg_edge_betweenness_centrality_test.cpp b/cpp/tests/centrality/mg_edge_betweenness_centrality_test.cpp index 8dbeb076c00..ff100a33e40 100644 --- a/cpp/tests/centrality/mg_edge_betweenness_centrality_test.cpp +++ b/cpp/tests/centrality/mg_edge_betweenness_centrality_test.cpp @@ -209,12 +209,6 @@ TEST_P(Tests_MGEdgeBetweennessCentrality_Rmat, CheckInt32Int32FloatFloat) override_Rmat_Usecase_with_cmd_line_arguments(GetParam())); } -TEST_P(Tests_MGEdgeBetweennessCentrality_Rmat, CheckInt32Int64FloatFloat) -{ - run_current_test( - override_Rmat_Usecase_with_cmd_line_arguments(GetParam())); -} - TEST_P(Tests_MGEdgeBetweennessCentrality_Rmat, CheckInt64Int64FloatFloat) { run_current_test( diff --git a/cpp/tests/centrality/mg_eigenvector_centrality_test.cpp b/cpp/tests/centrality/mg_eigenvector_centrality_test.cpp index 39406e05d6c..0e2a0e37c1b 100644 --- a/cpp/tests/centrality/mg_eigenvector_centrality_test.cpp +++ b/cpp/tests/centrality/mg_eigenvector_centrality_test.cpp @@ -238,13 +238,6 @@ TEST_P(Tests_MGEigenvectorCentrality_Rmat, CheckInt32Int32FloatFloat) std::get<0>(param), override_Rmat_Usecase_with_cmd_line_arguments(std::get<1>(param))); } -TEST_P(Tests_MGEigenvectorCentrality_Rmat, CheckInt32Int64FloatFloat) -{ - auto param = GetParam(); - run_current_test( - std::get<0>(param), override_Rmat_Usecase_with_cmd_line_arguments(std::get<1>(param))); -} - TEST_P(Tests_MGEigenvectorCentrality_Rmat, CheckInt64Int64FloatFloat) { auto param = GetParam(); diff --git a/cpp/tests/centrality/mg_katz_centrality_test.cpp b/cpp/tests/centrality/mg_katz_centrality_test.cpp index 15a4089fa1b..5ccade18c18 100644 --- a/cpp/tests/centrality/mg_katz_centrality_test.cpp +++ b/cpp/tests/centrality/mg_katz_centrality_test.cpp @@ -229,13 +229,6 @@ TEST_P(Tests_MGKatzCentrality_Rmat, CheckInt32Int32FloatFloat) std::get<0>(param), override_Rmat_Usecase_with_cmd_line_arguments(std::get<1>(param))); } -TEST_P(Tests_MGKatzCentrality_Rmat, CheckInt32Int64FloatFloat) -{ - auto param = GetParam(); - run_current_test( - std::get<0>(param), override_Rmat_Usecase_with_cmd_line_arguments(std::get<1>(param))); -} - TEST_P(Tests_MGKatzCentrality_Rmat, CheckInt64Int64FloatFloat) { auto param = GetParam(); diff --git a/cpp/tests/community/mg_ecg_test.cpp b/cpp/tests/community/mg_ecg_test.cpp index c99f83fa2e8..14d1697744e 100644 --- a/cpp/tests/community/mg_ecg_test.cpp +++ b/cpp/tests/community/mg_ecg_test.cpp @@ -182,12 +182,6 @@ TEST_P(Tests_MGEcg_Rmat, CheckInt32Int32Float) override_Rmat_Usecase_with_cmd_line_arguments(GetParam())); } -TEST_P(Tests_MGEcg_Rmat, CheckInt32Int64Float) -{ - run_current_test( - override_Rmat_Usecase_with_cmd_line_arguments(GetParam())); -} - TEST_P(Tests_MGEcg_Rmat, CheckInt64Int64Float) { run_current_test( diff --git a/cpp/tests/community/mg_edge_triangle_count_test.cpp b/cpp/tests/community/mg_edge_triangle_count_test.cpp index 89bdf870ccd..5f00d4bbc5c 100644 --- a/cpp/tests/community/mg_edge_triangle_count_test.cpp +++ b/cpp/tests/community/mg_edge_triangle_count_test.cpp @@ -206,13 +206,6 @@ TEST_P(Tests_MGEdgeTriangleCount_Rmat, CheckInt32Int32) std::get<0>(param), override_Rmat_Usecase_with_cmd_line_arguments(std::get<1>(param))); } -TEST_P(Tests_MGEdgeTriangleCount_Rmat, CheckInt32Int64) -{ - auto param = GetParam(); - run_current_test( - std::get<0>(param), override_Rmat_Usecase_with_cmd_line_arguments(std::get<1>(param))); -} - TEST_P(Tests_MGEdgeTriangleCount_Rmat, CheckInt64Int64) { auto param = GetParam(); diff --git a/cpp/tests/community/mg_egonet_test.cu b/cpp/tests/community/mg_egonet_test.cu index ac363df3ec5..130e01e8df9 100644 --- a/cpp/tests/community/mg_egonet_test.cu +++ b/cpp/tests/community/mg_egonet_test.cu @@ -268,12 +268,6 @@ TEST_P(Tests_MGEgonet_Rmat, CheckInt32Int32Float) override_Rmat_Usecase_with_cmd_line_arguments(GetParam())); } -TEST_P(Tests_MGEgonet_Rmat, CheckInt32Int64Float) -{ - run_current_test( - override_Rmat_Usecase_with_cmd_line_arguments(GetParam())); -} - TEST_P(Tests_MGEgonet_Rmat, CheckInt64Int64Float) { run_current_test( diff --git a/cpp/tests/community/mg_k_truss_test.cpp b/cpp/tests/community/mg_k_truss_test.cpp index a1624949007..d3463e73a6f 100644 --- a/cpp/tests/community/mg_k_truss_test.cpp +++ b/cpp/tests/community/mg_k_truss_test.cpp @@ -241,13 +241,6 @@ TEST_P(Tests_MGKTruss_Rmat, CheckInt32Int32) std::get<0>(param), override_Rmat_Usecase_with_cmd_line_arguments(std::get<1>(param))); } -TEST_P(Tests_MGKTruss_Rmat, CheckInt32Int64) -{ - auto param = GetParam(); - run_current_test( - std::get<0>(param), override_Rmat_Usecase_with_cmd_line_arguments(std::get<1>(param))); -} - TEST_P(Tests_MGKTruss_Rmat, CheckInt64Int64) { auto param = GetParam(); diff --git a/cpp/tests/community/mg_leiden_test.cpp b/cpp/tests/community/mg_leiden_test.cpp index 65f4827ba06..6949ac8d170 100644 --- a/cpp/tests/community/mg_leiden_test.cpp +++ b/cpp/tests/community/mg_leiden_test.cpp @@ -214,12 +214,6 @@ TEST_P(Tests_MGLeiden_Rmat, CheckInt32Int32Float) override_Rmat_Usecase_with_cmd_line_arguments(GetParam())); } -TEST_P(Tests_MGLeiden_Rmat, CheckInt32Int64Float) -{ - run_current_test( - override_Rmat_Usecase_with_cmd_line_arguments(GetParam())); -} - TEST_P(Tests_MGLeiden_Rmat, CheckInt64Int64Float) { run_current_test( diff --git a/cpp/tests/community/mg_louvain_test.cpp b/cpp/tests/community/mg_louvain_test.cpp index 106ad2562f7..4aebd26c256 100644 --- a/cpp/tests/community/mg_louvain_test.cpp +++ b/cpp/tests/community/mg_louvain_test.cpp @@ -252,12 +252,6 @@ TEST_P(Tests_MGLouvain_Rmat, CheckInt32Int32Float) override_Rmat_Usecase_with_cmd_line_arguments(GetParam())); } -TEST_P(Tests_MGLouvain_Rmat, CheckInt32Int64Float) -{ - run_current_test( - override_Rmat_Usecase_with_cmd_line_arguments(GetParam())); -} - TEST_P(Tests_MGLouvain_Rmat, CheckInt64Int64Float) { run_current_test( diff --git a/cpp/tests/community/mg_triangle_count_test.cpp b/cpp/tests/community/mg_triangle_count_test.cpp index 932ff5050f1..b541933ca4d 100644 --- a/cpp/tests/community/mg_triangle_count_test.cpp +++ b/cpp/tests/community/mg_triangle_count_test.cpp @@ -246,13 +246,6 @@ TEST_P(Tests_MGTriangleCount_Rmat, CheckInt32Int32) std::get<0>(param), override_Rmat_Usecase_with_cmd_line_arguments(std::get<1>(param))); } -TEST_P(Tests_MGTriangleCount_Rmat, CheckInt32Int64) -{ - auto param = GetParam(); - run_current_test( - std::get<0>(param), override_Rmat_Usecase_with_cmd_line_arguments(std::get<1>(param))); -} - TEST_P(Tests_MGTriangleCount_Rmat, CheckInt64Int64) { auto param = GetParam(); diff --git a/cpp/tests/community/mg_weighted_matching_test.cpp b/cpp/tests/community/mg_weighted_matching_test.cpp index 5a150bbc1f7..4e57450ace7 100644 --- a/cpp/tests/community/mg_weighted_matching_test.cpp +++ b/cpp/tests/community/mg_weighted_matching_test.cpp @@ -188,12 +188,6 @@ TEST_P(Tests_MGWeightedMatching_File, CheckInt32Int32FloatFloat) override_File_Usecase_with_cmd_line_arguments(GetParam())); } -TEST_P(Tests_MGWeightedMatching_File, CheckInt32Int64FloatFloat) -{ - run_current_test( - override_File_Usecase_with_cmd_line_arguments(GetParam())); -} - TEST_P(Tests_MGWeightedMatching_File, CheckInt64Int64FloatFloat) { run_current_test( @@ -206,12 +200,6 @@ TEST_P(Tests_MGWeightedMatching_Rmat, CheckInt32Int32FloatFloat) override_Rmat_Usecase_with_cmd_line_arguments(GetParam())); } -TEST_P(Tests_MGWeightedMatching_Rmat, CheckInt32Int64FloatFloat) -{ - run_current_test( - override_Rmat_Usecase_with_cmd_line_arguments(GetParam())); -} - TEST_P(Tests_MGWeightedMatching_Rmat, CheckInt64Int64FloatFloat) { run_current_test( diff --git a/cpp/tests/community/triangle_count_test.cpp b/cpp/tests/community/triangle_count_test.cpp index b4f4b87943a..c35ab4e6f4d 100644 --- a/cpp/tests/community/triangle_count_test.cpp +++ b/cpp/tests/community/triangle_count_test.cpp @@ -263,11 +263,6 @@ TEST_P(Tests_TriangleCount_Rmat, CheckInt32Int32) run_current_test(override_Rmat_Usecase_with_cmd_line_arguments(GetParam())); } -TEST_P(Tests_TriangleCount_File, CheckInt32Int64) -{ - run_current_test(override_File_Usecase_with_cmd_line_arguments(GetParam())); -} - TEST_P(Tests_TriangleCount_Rmat, CheckInt64Int64) { run_current_test(override_Rmat_Usecase_with_cmd_line_arguments(GetParam())); diff --git a/cpp/tests/community/weighted_matching_test.cpp b/cpp/tests/community/weighted_matching_test.cpp index 436273c3be3..ddaa85a14db 100644 --- a/cpp/tests/community/weighted_matching_test.cpp +++ b/cpp/tests/community/weighted_matching_test.cpp @@ -123,12 +123,6 @@ TEST_P(Tests_SGWeightedMatching_File, CheckInt32Int32FloatFloat) override_File_Usecase_with_cmd_line_arguments(GetParam())); } -TEST_P(Tests_SGWeightedMatching_File, CheckInt32Int64FloatFloat) -{ - run_current_test( - override_File_Usecase_with_cmd_line_arguments(GetParam())); -} - TEST_P(Tests_SGWeightedMatching_File, CheckInt64Int64FloatFloat) { run_current_test( @@ -141,12 +135,6 @@ TEST_P(Tests_SGWeightedMatching_Rmat, CheckInt32Int32FloatFloat) override_Rmat_Usecase_with_cmd_line_arguments(GetParam())); } -TEST_P(Tests_SGWeightedMatching_Rmat, CheckInt32Int64FloatFloat) -{ - run_current_test( - override_Rmat_Usecase_with_cmd_line_arguments(GetParam())); -} - TEST_P(Tests_SGWeightedMatching_Rmat, CheckInt64Int64FloatFloat) { run_current_test( diff --git a/cpp/tests/components/mg_mis_test.cu b/cpp/tests/components/mg_mis_test.cu index 9c50be3fa28..0696a6a1db1 100644 --- a/cpp/tests/components/mg_mis_test.cu +++ b/cpp/tests/components/mg_mis_test.cu @@ -213,12 +213,6 @@ TEST_P(Tests_MGMaximalIndependentSet_File, CheckInt32Int32FloatFloat) override_File_Usecase_with_cmd_line_arguments(GetParam())); } -TEST_P(Tests_MGMaximalIndependentSet_File, CheckInt32Int64FloatFloat) -{ - run_current_test( - override_File_Usecase_with_cmd_line_arguments(GetParam())); -} - TEST_P(Tests_MGMaximalIndependentSet_File, CheckInt64Int64FloatFloat) { run_current_test( @@ -231,12 +225,6 @@ TEST_P(Tests_MGMaximalIndependentSet_Rmat, CheckInt32Int32FloatFloat) override_Rmat_Usecase_with_cmd_line_arguments(GetParam())); } -TEST_P(Tests_MGMaximalIndependentSet_Rmat, CheckInt32Int64FloatFloat) -{ - run_current_test( - override_Rmat_Usecase_with_cmd_line_arguments(GetParam())); -} - TEST_P(Tests_MGMaximalIndependentSet_Rmat, CheckInt64Int64FloatFloat) { run_current_test( diff --git a/cpp/tests/components/mg_vertex_coloring_test.cu b/cpp/tests/components/mg_vertex_coloring_test.cu index 14e15df502f..17327e35c97 100644 --- a/cpp/tests/components/mg_vertex_coloring_test.cu +++ b/cpp/tests/components/mg_vertex_coloring_test.cu @@ -214,12 +214,6 @@ TEST_P(Tests_MGGraphColoring_File, CheckInt32Int32FloatFloat) override_File_Usecase_with_cmd_line_arguments(GetParam())); } -TEST_P(Tests_MGGraphColoring_File, CheckInt32Int64FloatFloat) -{ - run_current_test( - override_File_Usecase_with_cmd_line_arguments(GetParam())); -} - TEST_P(Tests_MGGraphColoring_File, CheckInt64Int64FloatFloat) { run_current_test( @@ -232,12 +226,6 @@ TEST_P(Tests_MGGraphColoring_Rmat, CheckInt32Int32FloatFloat) override_Rmat_Usecase_with_cmd_line_arguments(GetParam())); } -TEST_P(Tests_MGGraphColoring_Rmat, CheckInt32Int64FloatFloat) -{ - run_current_test( - override_Rmat_Usecase_with_cmd_line_arguments(GetParam())); -} - TEST_P(Tests_MGGraphColoring_Rmat, CheckInt64Int64FloatFloat) { run_current_test( diff --git a/cpp/tests/components/mg_weakly_connected_components_test.cpp b/cpp/tests/components/mg_weakly_connected_components_test.cpp index 368fea68877..bb3bc826a71 100644 --- a/cpp/tests/components/mg_weakly_connected_components_test.cpp +++ b/cpp/tests/components/mg_weakly_connected_components_test.cpp @@ -195,13 +195,6 @@ TEST_P(Tests_MGWeaklyConnectedComponents_Rmat, CheckInt32Int32) std::get<0>(param), override_Rmat_Usecase_with_cmd_line_arguments(std::get<1>(param))); } -TEST_P(Tests_MGWeaklyConnectedComponents_Rmat, CheckInt32Int64) -{ - auto param = GetParam(); - run_current_test( - std::get<0>(param), override_Rmat_Usecase_with_cmd_line_arguments(std::get<1>(param))); -} - TEST_P(Tests_MGWeaklyConnectedComponents_Rmat, CheckInt64Int64) { auto param = GetParam(); diff --git a/cpp/tests/components/mis_test.cu b/cpp/tests/components/mis_test.cu index f98aa1fe0c7..d7871f32082 100644 --- a/cpp/tests/components/mis_test.cu +++ b/cpp/tests/components/mis_test.cu @@ -179,12 +179,6 @@ TEST_P(Tests_SGMaximalIndependentSet_File, CheckInt32Int32FloatFloat) override_File_Usecase_with_cmd_line_arguments(GetParam())); } -TEST_P(Tests_SGMaximalIndependentSet_File, CheckInt32Int64FloatFloat) -{ - run_current_test( - override_File_Usecase_with_cmd_line_arguments(GetParam())); -} - TEST_P(Tests_SGMaximalIndependentSet_File, CheckInt64Int64FloatFloat) { run_current_test( @@ -197,12 +191,6 @@ TEST_P(Tests_SGMaximalIndependentSet_Rmat, CheckInt32Int32FloatFloat) override_Rmat_Usecase_with_cmd_line_arguments(GetParam())); } -TEST_P(Tests_SGMaximalIndependentSet_Rmat, CheckInt32Int64FloatFloat) -{ - run_current_test( - override_Rmat_Usecase_with_cmd_line_arguments(GetParam())); -} - TEST_P(Tests_SGMaximalIndependentSet_Rmat, CheckInt64Int64FloatFloat) { run_current_test( diff --git a/cpp/tests/components/vertex_coloring_test.cu b/cpp/tests/components/vertex_coloring_test.cu index c7c37c6ad56..fed64f272d7 100644 --- a/cpp/tests/components/vertex_coloring_test.cu +++ b/cpp/tests/components/vertex_coloring_test.cu @@ -182,12 +182,6 @@ TEST_P(Tests_SGGraphColoring_File, CheckInt32Int32FloatFloat) override_File_Usecase_with_cmd_line_arguments(GetParam())); } -TEST_P(Tests_SGGraphColoring_File, CheckInt32Int64FloatFloat) -{ - run_current_test( - override_File_Usecase_with_cmd_line_arguments(GetParam())); -} - TEST_P(Tests_SGGraphColoring_File, CheckInt64Int64FloatFloat) { run_current_test( @@ -200,12 +194,6 @@ TEST_P(Tests_SGGraphColoring_Rmat, CheckInt32Int32FloatFloat) override_Rmat_Usecase_with_cmd_line_arguments(GetParam())); } -TEST_P(Tests_SGGraphColoring_Rmat, CheckInt32Int64FloatFloat) -{ - run_current_test( - override_Rmat_Usecase_with_cmd_line_arguments(GetParam())); -} - TEST_P(Tests_SGGraphColoring_Rmat, CheckInt64Int64FloatFloat) { run_current_test( diff --git a/cpp/tests/components/weakly_connected_components_test.cpp b/cpp/tests/components/weakly_connected_components_test.cpp index 7b909c6f594..db8eeefe511 100644 --- a/cpp/tests/components/weakly_connected_components_test.cpp +++ b/cpp/tests/components/weakly_connected_components_test.cpp @@ -213,13 +213,6 @@ TEST_P(Tests_WeaklyConnectedComponents_Rmat, CheckInt32Int32) std::get<0>(param), override_Rmat_Usecase_with_cmd_line_arguments(std::get<1>(param))); } -TEST_P(Tests_WeaklyConnectedComponents_Rmat, CheckInt32Int64) -{ - auto param = GetParam(); - run_current_test( - std::get<0>(param), override_Rmat_Usecase_with_cmd_line_arguments(std::get<1>(param))); -} - TEST_P(Tests_WeaklyConnectedComponents_Rmat, CheckInt64Int64) { auto param = GetParam(); diff --git a/cpp/tests/cores/core_number_test.cpp b/cpp/tests/cores/core_number_test.cpp index ca0174202c2..937bdb95241 100644 --- a/cpp/tests/cores/core_number_test.cpp +++ b/cpp/tests/cores/core_number_test.cpp @@ -331,13 +331,6 @@ TEST_P(Tests_CoreNumber_Rmat, CheckInt32Int32) std::get<0>(param), override_Rmat_Usecase_with_cmd_line_arguments(std::get<1>(param))); } -TEST_P(Tests_CoreNumber_Rmat, CheckInt32Int64) -{ - auto param = GetParam(); - run_current_test( - std::get<0>(param), override_Rmat_Usecase_with_cmd_line_arguments(std::get<1>(param))); -} - TEST_P(Tests_CoreNumber_Rmat, CheckInt64Int64) { auto param = GetParam(); diff --git a/cpp/tests/cores/k_core_test.cpp b/cpp/tests/cores/k_core_test.cpp index 064b7862842..5dbafe206dc 100644 --- a/cpp/tests/cores/k_core_test.cpp +++ b/cpp/tests/cores/k_core_test.cpp @@ -134,11 +134,6 @@ TEST_P(Tests_KCore_Rmat, CheckInt32Int32) run_current_test(override_Rmat_Usecase_with_cmd_line_arguments(GetParam())); } -TEST_P(Tests_KCore_Rmat, CheckInt32Int64) -{ - run_current_test(override_Rmat_Usecase_with_cmd_line_arguments(GetParam())); -} - TEST_P(Tests_KCore_Rmat, CheckInt64Int64) { run_current_test(override_Rmat_Usecase_with_cmd_line_arguments(GetParam())); diff --git a/cpp/tests/cores/k_core_validate.cu b/cpp/tests/cores/k_core_validate.cu index 53c97dd466b..4645af95a91 100644 --- a/cpp/tests/cores/k_core_validate.cu +++ b/cpp/tests/cores/k_core_validate.cu @@ -99,16 +99,6 @@ template void check_correctness( std::optional>> const& subgraph, size_t k); -template void check_correctness( - raft::handle_t const& handle, - graph_view_t const& graph_view, - std::optional> edge_weight_view, - rmm::device_uvector const& core_numbers, - std::tuple, - rmm::device_uvector, - std::optional>> const& subgraph, - size_t k); - template void check_correctness( raft::handle_t const& handle, graph_view_t const& graph_view, diff --git a/cpp/tests/cores/mg_core_number_test.cpp b/cpp/tests/cores/mg_core_number_test.cpp index f8294d81fdf..f6b73be7b09 100644 --- a/cpp/tests/cores/mg_core_number_test.cpp +++ b/cpp/tests/cores/mg_core_number_test.cpp @@ -205,13 +205,6 @@ TEST_P(Tests_MGCoreNumber_Rmat, CheckInt32Int32FloatFloat) std::get<0>(param), override_Rmat_Usecase_with_cmd_line_arguments(std::get<1>(param))); } -TEST_P(Tests_MGCoreNumber_Rmat, CheckInt32Int64FloatFloat) -{ - auto param = GetParam(); - run_current_test( - std::get<0>(param), override_Rmat_Usecase_with_cmd_line_arguments(std::get<1>(param))); -} - TEST_P(Tests_MGCoreNumber_Rmat, CheckInt64Int64FloatFloat) { auto param = GetParam(); diff --git a/cpp/tests/cores/mg_k_core_test.cpp b/cpp/tests/cores/mg_k_core_test.cpp index 28bc445bda8..8ebbff6f5a4 100644 --- a/cpp/tests/cores/mg_k_core_test.cpp +++ b/cpp/tests/cores/mg_k_core_test.cpp @@ -208,11 +208,6 @@ TEST_P(Tests_MGKCore_Rmat, CheckInt32Int32) run_current_test(override_Rmat_Usecase_with_cmd_line_arguments(GetParam())); } -TEST_P(Tests_MGKCore_Rmat, CheckInt32Int64) -{ - run_current_test(override_Rmat_Usecase_with_cmd_line_arguments(GetParam())); -} - TEST_P(Tests_MGKCore_Rmat, CheckInt64Int64) { run_current_test(override_Rmat_Usecase_with_cmd_line_arguments(GetParam())); diff --git a/cpp/tests/link_analysis/hits_test.cpp b/cpp/tests/link_analysis/hits_test.cpp index 89bc0ca34c5..0017f4652ba 100644 --- a/cpp/tests/link_analysis/hits_test.cpp +++ b/cpp/tests/link_analysis/hits_test.cpp @@ -316,12 +316,6 @@ TEST_P(Tests_Hits_Rmat, CheckInt32Int32Float) override_Rmat_Usecase_with_cmd_line_arguments(GetParam())); } -TEST_P(Tests_Hits_Rmat, CheckInt32Int64Float) -{ - run_current_test( - override_Rmat_Usecase_with_cmd_line_arguments(GetParam())); -} - TEST_P(Tests_Hits_Rmat, CheckInt64Int64Float) { run_current_test( diff --git a/cpp/tests/link_analysis/mg_hits_test.cpp b/cpp/tests/link_analysis/mg_hits_test.cpp index 8a13204a5aa..eb2a9bcd721 100644 --- a/cpp/tests/link_analysis/mg_hits_test.cpp +++ b/cpp/tests/link_analysis/mg_hits_test.cpp @@ -266,13 +266,6 @@ TEST_P(Tests_MGHits_Rmat, CheckInt32Int32FloatFloat) std::get<0>(param), override_Rmat_Usecase_with_cmd_line_arguments(std::get<1>(param))); } -TEST_P(Tests_MGHits_Rmat, CheckInt32Int64FloatFloat) -{ - auto param = GetParam(); - run_current_test( - std::get<0>(param), override_Rmat_Usecase_with_cmd_line_arguments(std::get<1>(param))); -} - TEST_P(Tests_MGHits_Rmat, CheckInt64Int64FloatFloat) { auto param = GetParam(); diff --git a/cpp/tests/link_analysis/mg_pagerank_test.cpp b/cpp/tests/link_analysis/mg_pagerank_test.cpp index a9e3a10b2ae..f6ca6b03192 100644 --- a/cpp/tests/link_analysis/mg_pagerank_test.cpp +++ b/cpp/tests/link_analysis/mg_pagerank_test.cpp @@ -283,13 +283,6 @@ TEST_P(Tests_MGPageRank_Rmat, CheckInt32Int32FloatFloat) std::get<0>(param), override_Rmat_Usecase_with_cmd_line_arguments(std::get<1>(param))); } -TEST_P(Tests_MGPageRank_Rmat, CheckInt32Int64FloatFloat) -{ - auto param = GetParam(); - run_current_test( - std::get<0>(param), override_Rmat_Usecase_with_cmd_line_arguments(std::get<1>(param))); -} - TEST_P(Tests_MGPageRank_Rmat, CheckInt64Int64FloatFloat) { auto param = GetParam(); diff --git a/cpp/tests/link_analysis/pagerank_test.cpp b/cpp/tests/link_analysis/pagerank_test.cpp index 196476d6756..b2bc501218a 100644 --- a/cpp/tests/link_analysis/pagerank_test.cpp +++ b/cpp/tests/link_analysis/pagerank_test.cpp @@ -369,12 +369,6 @@ TEST_P(Tests_PageRank_Rmat, CheckInt32Int32FloatFloat) override_Rmat_Usecase_with_cmd_line_arguments(GetParam())); } -TEST_P(Tests_PageRank_File, CheckInt32Int64FloatFloat) -{ - run_current_test( - override_File_Usecase_with_cmd_line_arguments(GetParam())); -} - TEST_P(Tests_PageRank_Rmat, CheckInt64Int64FloatFloat) { run_current_test( diff --git a/cpp/tests/link_prediction/mg_similarity_test.cpp b/cpp/tests/link_prediction/mg_similarity_test.cpp index 3bcabb6b6df..302248fe516 100644 --- a/cpp/tests/link_prediction/mg_similarity_test.cpp +++ b/cpp/tests/link_prediction/mg_similarity_test.cpp @@ -190,13 +190,6 @@ TEST_P(Tests_MGSimilarity_Rmat, CheckInt32Int32FloatFloatJaccard) override_Rmat_Usecase_with_cmd_line_arguments(GetParam()), cugraph::test::test_jaccard_t{}); } -TEST_P(Tests_MGSimilarity_Rmat, CheckInt32Int64FloatFloatJaccard) -{ - auto param = GetParam(); - run_current_test( - override_Rmat_Usecase_with_cmd_line_arguments(GetParam()), cugraph::test::test_jaccard_t{}); -} - TEST_P(Tests_MGSimilarity_Rmat, CheckInt64Int64FloatFloatJaccard) { auto param = GetParam(); @@ -216,12 +209,6 @@ TEST_P(Tests_MGSimilarity_Rmat, CheckInt32Int32FloatSorensen) override_Rmat_Usecase_with_cmd_line_arguments(GetParam()), cugraph::test::test_sorensen_t{}); } -TEST_P(Tests_MGSimilarity_Rmat, CheckInt32Int64FloatSorensen) -{ - run_current_test( - override_Rmat_Usecase_with_cmd_line_arguments(GetParam()), cugraph::test::test_sorensen_t{}); -} - TEST_P(Tests_MGSimilarity_Rmat, CheckInt64Int64FloatSorensen) { run_current_test( @@ -240,12 +227,6 @@ TEST_P(Tests_MGSimilarity_Rmat, CheckInt32Int32FloatOverlap) override_Rmat_Usecase_with_cmd_line_arguments(GetParam()), cugraph::test::test_overlap_t{}); } -TEST_P(Tests_MGSimilarity_Rmat, CheckInt32Int64FloatOverlap) -{ - run_current_test( - override_Rmat_Usecase_with_cmd_line_arguments(GetParam()), cugraph::test::test_overlap_t{}); -} - TEST_P(Tests_MGSimilarity_Rmat, CheckInt64Int64FloatOverlap) { run_current_test( @@ -266,13 +247,6 @@ TEST_P(Tests_MGSimilarity_Rmat, CheckInt32Int32FloatFloatCosine) override_Rmat_Usecase_with_cmd_line_arguments(GetParam()), cugraph::test::test_cosine_t{}); } -TEST_P(Tests_MGSimilarity_Rmat, CheckInt32Int64FloatFloatCosine) -{ - auto param = GetParam(); - run_current_test( - override_Rmat_Usecase_with_cmd_line_arguments(GetParam()), cugraph::test::test_cosine_t{}); -} - TEST_P(Tests_MGSimilarity_Rmat, CheckInt64Int64FloatFloatCosine) { auto param = GetParam(); diff --git a/cpp/tests/link_prediction/mg_weighted_similarity_test.cpp b/cpp/tests/link_prediction/mg_weighted_similarity_test.cpp index 730a3ac8f08..2076d4ff79e 100644 --- a/cpp/tests/link_prediction/mg_weighted_similarity_test.cpp +++ b/cpp/tests/link_prediction/mg_weighted_similarity_test.cpp @@ -200,13 +200,6 @@ TEST_P(Tests_MGWeightedSimilarity_Rmat, CheckInt32Int32FloatFloatJaccard) override_Rmat_Usecase_with_cmd_line_arguments(GetParam()), cugraph::test::test_jaccard_t{}); } -TEST_P(Tests_MGWeightedSimilarity_Rmat, CheckInt32Int64FloatFloatJaccard) -{ - auto param = GetParam(); - run_current_test( - override_Rmat_Usecase_with_cmd_line_arguments(GetParam()), cugraph::test::test_jaccard_t{}); -} - TEST_P(Tests_MGWeightedSimilarity_Rmat, CheckInt64Int64FloatFloatJaccard) { auto param = GetParam(); @@ -226,12 +219,6 @@ TEST_P(Tests_MGWeightedSimilarity_Rmat, CheckInt32Int32FloatSorensen) override_Rmat_Usecase_with_cmd_line_arguments(GetParam()), cugraph::test::test_sorensen_t{}); } -TEST_P(Tests_MGWeightedSimilarity_Rmat, CheckInt32Int64FloatSorensen) -{ - run_current_test( - override_Rmat_Usecase_with_cmd_line_arguments(GetParam()), cugraph::test::test_sorensen_t{}); -} - TEST_P(Tests_MGWeightedSimilarity_Rmat, CheckInt64Int64FloatSorensen) { run_current_test( @@ -250,12 +237,6 @@ TEST_P(Tests_MGWeightedSimilarity_Rmat, CheckInt32Int32FloatOverlap) override_Rmat_Usecase_with_cmd_line_arguments(GetParam()), cugraph::test::test_overlap_t{}); } -TEST_P(Tests_MGWeightedSimilarity_Rmat, CheckInt32Int64FloatOverlap) -{ - run_current_test( - override_Rmat_Usecase_with_cmd_line_arguments(GetParam()), cugraph::test::test_overlap_t{}); -} - TEST_P(Tests_MGWeightedSimilarity_Rmat, CheckInt64Int64FloatOverlap) { run_current_test( @@ -276,13 +257,6 @@ TEST_P(Tests_MGWeightedSimilarity_Rmat, CheckInt32Int32FloatFloatCosine) override_Rmat_Usecase_with_cmd_line_arguments(GetParam()), cugraph::test::test_cosine_t{}); } -TEST_P(Tests_MGWeightedSimilarity_Rmat, CheckInt32Int64FloatFloatCosine) -{ - auto param = GetParam(); - run_current_test( - override_Rmat_Usecase_with_cmd_line_arguments(GetParam()), cugraph::test::test_cosine_t{}); -} - TEST_P(Tests_MGWeightedSimilarity_Rmat, CheckInt64Int64FloatFloatCosine) { auto param = GetParam(); diff --git a/cpp/tests/link_prediction/similarity_test.cu b/cpp/tests/link_prediction/similarity_test.cu index 5547c4bd0c0..ec6db102830 100644 --- a/cpp/tests/link_prediction/similarity_test.cu +++ b/cpp/tests/link_prediction/similarity_test.cu @@ -223,12 +223,6 @@ TEST_P(Tests_Similarity_Rmat, CheckInt32Int32FloatJaccard) override_Rmat_Usecase_with_cmd_line_arguments(GetParam()), cugraph::test::test_jaccard_t{}); } -TEST_P(Tests_Similarity_Rmat, CheckInt32Int64FloatJaccard) -{ - run_current_test( - override_Rmat_Usecase_with_cmd_line_arguments(GetParam()), cugraph::test::test_jaccard_t{}); -} - TEST_P(Tests_Similarity_Rmat, CheckInt64Int64FloatJaccard) { run_current_test( @@ -247,12 +241,6 @@ TEST_P(Tests_Similarity_Rmat, CheckInt32Int32FloatSorensen) override_Rmat_Usecase_with_cmd_line_arguments(GetParam()), cugraph::test::test_sorensen_t{}); } -TEST_P(Tests_Similarity_Rmat, CheckInt32Int64FloatSorensen) -{ - run_current_test( - override_Rmat_Usecase_with_cmd_line_arguments(GetParam()), cugraph::test::test_sorensen_t{}); -} - TEST_P(Tests_Similarity_Rmat, CheckInt64Int64FloatSorensen) { run_current_test( @@ -271,12 +259,6 @@ TEST_P(Tests_Similarity_Rmat, CheckInt32Int32FloatOverlap) override_Rmat_Usecase_with_cmd_line_arguments(GetParam()), cugraph::test::test_overlap_t{}); } -TEST_P(Tests_Similarity_Rmat, CheckInt32Int64FloatOverlap) -{ - run_current_test( - override_Rmat_Usecase_with_cmd_line_arguments(GetParam()), cugraph::test::test_overlap_t{}); -} - TEST_P(Tests_Similarity_Rmat, CheckInt64Int64FloatOverlap) { run_current_test( @@ -295,12 +277,6 @@ TEST_P(Tests_Similarity_Rmat, CheckInt32Int32FloatCosine) override_Rmat_Usecase_with_cmd_line_arguments(GetParam()), cugraph::test::test_cosine_t{}); } -TEST_P(Tests_Similarity_Rmat, CheckInt32Int64FloatCosine) -{ - run_current_test( - override_Rmat_Usecase_with_cmd_line_arguments(GetParam()), cugraph::test::test_cosine_t{}); -} - TEST_P(Tests_Similarity_Rmat, CheckInt64Int64FloatCosine) { run_current_test( diff --git a/cpp/tests/link_prediction/weighted_similarity_test.cpp b/cpp/tests/link_prediction/weighted_similarity_test.cpp index 2450e7d6376..cfd1171eedb 100644 --- a/cpp/tests/link_prediction/weighted_similarity_test.cpp +++ b/cpp/tests/link_prediction/weighted_similarity_test.cpp @@ -233,12 +233,6 @@ TEST_P(Tests_Similarity_Rmat, CheckInt32Int32FloatJaccard) override_Rmat_Usecase_with_cmd_line_arguments(GetParam()), cugraph::test::test_jaccard_t{}); } -TEST_P(Tests_Similarity_Rmat, CheckInt32Int64FloatJaccard) -{ - run_current_test( - override_Rmat_Usecase_with_cmd_line_arguments(GetParam()), cugraph::test::test_jaccard_t{}); -} - TEST_P(Tests_Similarity_Rmat, CheckInt64Int64FloatJaccard) { run_current_test( @@ -257,12 +251,6 @@ TEST_P(Tests_Similarity_Rmat, CheckInt32Int32FloatSorensen) override_Rmat_Usecase_with_cmd_line_arguments(GetParam()), cugraph::test::test_sorensen_t{}); } -TEST_P(Tests_Similarity_Rmat, CheckInt32Int64FloatSorensen) -{ - run_current_test( - override_Rmat_Usecase_with_cmd_line_arguments(GetParam()), cugraph::test::test_sorensen_t{}); -} - TEST_P(Tests_Similarity_Rmat, CheckInt64Int64FloatSorensen) { run_current_test( @@ -281,12 +269,6 @@ TEST_P(Tests_Similarity_Rmat, CheckInt32Int32FloatOverlap) override_Rmat_Usecase_with_cmd_line_arguments(GetParam()), cugraph::test::test_overlap_t{}); } -TEST_P(Tests_Similarity_Rmat, CheckInt32Int64FloatOverlap) -{ - run_current_test( - override_Rmat_Usecase_with_cmd_line_arguments(GetParam()), cugraph::test::test_overlap_t{}); -} - TEST_P(Tests_Similarity_Rmat, CheckInt64Int64FloatOverlap) { run_current_test( @@ -305,12 +287,6 @@ TEST_P(Tests_Similarity_Rmat, CheckInt32Int32FloatCosine) override_Rmat_Usecase_with_cmd_line_arguments(GetParam()), cugraph::test::test_cosine_t{}); } -TEST_P(Tests_Similarity_Rmat, CheckInt32Int64FloatCosine) -{ - run_current_test( - override_Rmat_Usecase_with_cmd_line_arguments(GetParam()), cugraph::test::test_cosine_t{}); -} - TEST_P(Tests_Similarity_Rmat, CheckInt64Int64FloatCosine) { run_current_test( diff --git a/cpp/tests/lookup/lookup_src_dst_test.cpp b/cpp/tests/lookup/lookup_src_dst_test.cpp index 87f4958f740..5f23af6dfa3 100644 --- a/cpp/tests/lookup/lookup_src_dst_test.cpp +++ b/cpp/tests/lookup/lookup_src_dst_test.cpp @@ -250,12 +250,6 @@ TEST_P(Tests_SGLookupEdgeSrcDst_File, CheckInt32Int32FloatFloat) override_File_Usecase_with_cmd_line_arguments(GetParam())); } -TEST_P(Tests_SGLookupEdgeSrcDst_File, CheckInt32Int64FloatFloat) -{ - run_current_test( - override_File_Usecase_with_cmd_line_arguments(GetParam())); -} - TEST_P(Tests_SGLookupEdgeSrcDst_File, CheckInt64Int64FloatFloat) { run_current_test( @@ -268,12 +262,6 @@ TEST_P(Tests_SGLookupEdgeSrcDst_Rmat, CheckInt32Int32FloatFloat) override_Rmat_Usecase_with_cmd_line_arguments(GetParam())); } -TEST_P(Tests_SGLookupEdgeSrcDst_Rmat, CheckInt32Int64FloatFloat) -{ - run_current_test( - override_Rmat_Usecase_with_cmd_line_arguments(GetParam())); -} - TEST_P(Tests_SGLookupEdgeSrcDst_Rmat, CheckInt64Int64FloatFloat) { run_current_test( diff --git a/cpp/tests/lookup/mg_lookup_src_dst_test.cpp b/cpp/tests/lookup/mg_lookup_src_dst_test.cpp index 8d31b0ca157..7136f620919 100644 --- a/cpp/tests/lookup/mg_lookup_src_dst_test.cpp +++ b/cpp/tests/lookup/mg_lookup_src_dst_test.cpp @@ -293,12 +293,6 @@ TEST_P(Tests_MGLookupEdgeSrcDst_File, CheckInt32Int32FloatFloat) override_File_Usecase_with_cmd_line_arguments(GetParam())); } -TEST_P(Tests_MGLookupEdgeSrcDst_File, CheckInt32Int64FloatFloat) -{ - run_current_test( - override_File_Usecase_with_cmd_line_arguments(GetParam())); -} - TEST_P(Tests_MGLookupEdgeSrcDst_File, CheckInt64Int64FloatFloat) { run_current_test( @@ -311,12 +305,6 @@ TEST_P(Tests_MGLookupEdgeSrcDst_Rmat, CheckInt32Int32FloatFloat) override_Rmat_Usecase_with_cmd_line_arguments(GetParam())); } -TEST_P(Tests_MGLookupEdgeSrcDst_Rmat, CheckInt32Int64FloatFloat) -{ - run_current_test( - override_Rmat_Usecase_with_cmd_line_arguments(GetParam())); -} - TEST_P(Tests_MGLookupEdgeSrcDst_Rmat, CheckInt64Int64FloatFloat) { run_current_test( diff --git a/cpp/tests/mtmg/multi_node_threaded_test.cu b/cpp/tests/mtmg/multi_node_threaded_test.cu index 06ccd4a7fa1..374c432aac5 100644 --- a/cpp/tests/mtmg/multi_node_threaded_test.cu +++ b/cpp/tests/mtmg/multi_node_threaded_test.cu @@ -39,6 +39,7 @@ #include #include +#include #include #include diff --git a/cpp/tests/prims/mg_count_if_e.cu b/cpp/tests/prims/mg_count_if_e.cu index 88494132ac7..63a785fb182 100644 --- a/cpp/tests/prims/mg_count_if_e.cu +++ b/cpp/tests/prims/mg_count_if_e.cu @@ -212,14 +212,6 @@ TEST_P(Tests_MGCountIfE_Rmat, CheckInt32Int32FloatTupleIntFloatTransposeFalse) cugraph::test::override_Rmat_Usecase_with_cmd_line_arguments(std::get<1>(param))); } -TEST_P(Tests_MGCountIfE_Rmat, CheckInt32Int64FloatTupleIntFloatTransposeFalse) -{ - auto param = GetParam(); - run_current_test, false>( - std::get<0>(param), - cugraph::test::override_Rmat_Usecase_with_cmd_line_arguments(std::get<1>(param))); -} - TEST_P(Tests_MGCountIfE_Rmat, CheckInt64Int64FloatTupleIntFloatTransposeFalse) { auto param = GetParam(); @@ -243,14 +235,6 @@ TEST_P(Tests_MGCountIfE_Rmat, CheckInt32Int32FloatTupleIntFloatTransposeTrue) cugraph::test::override_Rmat_Usecase_with_cmd_line_arguments(std::get<1>(param))); } -TEST_P(Tests_MGCountIfE_Rmat, CheckInt32Int64FloatTupleIntFloatTransposeTrue) -{ - auto param = GetParam(); - run_current_test, true>( - std::get<0>(param), - cugraph::test::override_Rmat_Usecase_with_cmd_line_arguments(std::get<1>(param))); -} - TEST_P(Tests_MGCountIfE_Rmat, CheckInt64Int64FloatTupleIntFloatTransposeTrue) { auto param = GetParam(); @@ -273,14 +257,6 @@ TEST_P(Tests_MGCountIfE_Rmat, CheckInt32Int32FloatTransposeFalse) cugraph::test::override_Rmat_Usecase_with_cmd_line_arguments(std::get<1>(param))); } -TEST_P(Tests_MGCountIfE_Rmat, CheckInt32Int64FloatTransposeFalse) -{ - auto param = GetParam(); - run_current_test( - std::get<0>(param), - cugraph::test::override_Rmat_Usecase_with_cmd_line_arguments(std::get<1>(param))); -} - TEST_P(Tests_MGCountIfE_Rmat, CheckInt64Int64FloatTransposeFalse) { auto param = GetParam(); @@ -303,14 +279,6 @@ TEST_P(Tests_MGCountIfE_Rmat, CheckInt32Int32FloatTransposeTrue) cugraph::test::override_Rmat_Usecase_with_cmd_line_arguments(std::get<1>(param))); } -TEST_P(Tests_MGCountIfE_Rmat, CheckInt32Int64FloatTransposeTrue) -{ - auto param = GetParam(); - run_current_test( - std::get<0>(param), - cugraph::test::override_Rmat_Usecase_with_cmd_line_arguments(std::get<1>(param))); -} - TEST_P(Tests_MGCountIfE_Rmat, CheckInt64Int64FloatTransposeTrue) { auto param = GetParam(); diff --git a/cpp/tests/prims/mg_count_if_v.cu b/cpp/tests/prims/mg_count_if_v.cu index 56550027936..0d399f52acd 100644 --- a/cpp/tests/prims/mg_count_if_v.cu +++ b/cpp/tests/prims/mg_count_if_v.cu @@ -48,7 +48,7 @@ struct test_predicate { test_predicate(int mod_count) : mod(mod_count) {} __device__ bool operator()(vertex_t, const vertex_t& val) { - cuco::detail::MurmurHash3_32 hash_func{}; + cuco::murmurhash3_32 hash_func{}; return (0 == (hash_func(val) % mod)); } }; @@ -168,13 +168,6 @@ TEST_P(Tests_MGCountIfV_Rmat, CheckInt32Int32FloatTransposeFalse) std::get<0>(param), override_Rmat_Usecase_with_cmd_line_arguments(std::get<1>(param))); } -TEST_P(Tests_MGCountIfV_Rmat, CheckInt32Int64FloatTransposeFalse) -{ - auto param = GetParam(); - run_current_test( - std::get<0>(param), override_Rmat_Usecase_with_cmd_line_arguments(std::get<1>(param))); -} - TEST_P(Tests_MGCountIfV_Rmat, CheckInt64Int64FloatTransposeFalse) { auto param = GetParam(); @@ -195,13 +188,6 @@ TEST_P(Tests_MGCountIfV_Rmat, CheckInt32Int32FloatTransposeTrue) std::get<0>(param), override_Rmat_Usecase_with_cmd_line_arguments(std::get<1>(param))); } -TEST_P(Tests_MGCountIfV_Rmat, CheckInt32Int64FloatTransposeTrue) -{ - auto param = GetParam(); - run_current_test( - std::get<0>(param), override_Rmat_Usecase_with_cmd_line_arguments(std::get<1>(param))); -} - TEST_P(Tests_MGCountIfV_Rmat, CheckInt64Int64FloatTransposeTrue) { auto param = GetParam(); diff --git a/cpp/tests/prims/mg_extract_transform_e.cu b/cpp/tests/prims/mg_extract_transform_e.cu index e45f10c3175..d3d6524cbdb 100644 --- a/cpp/tests/prims/mg_extract_transform_e.cu +++ b/cpp/tests/prims/mg_extract_transform_e.cu @@ -334,20 +334,6 @@ TEST_P(Tests_MGExtractTransformE_Rmat, CheckInt32Int32FloatInt32TupleFloatInt32) cugraph::test::override_Rmat_Usecase_with_cmd_line_arguments(std::get<1>(param))); } -TEST_P(Tests_MGExtractTransformE_File, CheckInt32Int64FloatInt32Int32) -{ - auto param = GetParam(); - run_current_test(std::get<0>(param), std::get<1>(param)); -} - -TEST_P(Tests_MGExtractTransformE_Rmat, CheckInt32Int64FloatInt32Int32) -{ - auto param = GetParam(); - run_current_test( - std::get<0>(param), - cugraph::test::override_Rmat_Usecase_with_cmd_line_arguments(std::get<1>(param))); -} - TEST_P(Tests_MGExtractTransformE_File, CheckInt64Int64FloatInt32Int32) { auto param = GetParam(); diff --git a/cpp/tests/prims/mg_extract_transform_v_frontier_outgoing_e.cu b/cpp/tests/prims/mg_extract_transform_v_frontier_outgoing_e.cu index 03f64e422c9..a8393d84e43 100644 --- a/cpp/tests/prims/mg_extract_transform_v_frontier_outgoing_e.cu +++ b/cpp/tests/prims/mg_extract_transform_v_frontier_outgoing_e.cu @@ -435,21 +435,6 @@ TEST_P(Tests_MGExtractTransformVFrontierOutgoingE_Rmat, CheckInt32Int32FloatInt3 cugraph::test::override_Rmat_Usecase_with_cmd_line_arguments(std::get<1>(param))); } -TEST_P(Tests_MGExtractTransformVFrontierOutgoingE_File, CheckInt32Int64FloatInt32Int32) -{ - auto param = GetParam(); - run_current_test(std::get<0>(param), - std::get<1>(param)); -} - -TEST_P(Tests_MGExtractTransformVFrontierOutgoingE_Rmat, CheckInt32Int64FloatInt32Int32) -{ - auto param = GetParam(); - run_current_test( - std::get<0>(param), - cugraph::test::override_Rmat_Usecase_with_cmd_line_arguments(std::get<1>(param))); -} - TEST_P(Tests_MGExtractTransformVFrontierOutgoingE_File, CheckInt64Int64FloatInt32Int32) { auto param = GetParam(); diff --git a/cpp/tests/prims/mg_per_v_pair_transform_dst_nbr_intersection.cu b/cpp/tests/prims/mg_per_v_pair_transform_dst_nbr_intersection.cu index fc6369ec721..48c308746f1 100644 --- a/cpp/tests/prims/mg_per_v_pair_transform_dst_nbr_intersection.cu +++ b/cpp/tests/prims/mg_per_v_pair_transform_dst_nbr_intersection.cu @@ -137,7 +137,7 @@ class Tests_MGPerVPairTransformDstNbrIntersection cugraph::get_dataframe_buffer_begin(mg_vertex_pair_buffer), cugraph::get_dataframe_buffer_end(mg_vertex_pair_buffer), [comm_rank, num_vertices = mg_graph_view.number_of_vertices()] __device__(size_t i) { - cuco::detail::MurmurHash3_32 + cuco::murmurhash3_32 hash_func{}; // use hash_func to generate arbitrary vertex pairs auto v0 = static_cast(hash_func(i + comm_rank) % num_vertices); auto v1 = static_cast(hash_func(i + num_vertices + comm_rank) % num_vertices); @@ -291,14 +291,6 @@ TEST_P(Tests_MGPerVPairTransformDstNbrIntersection_Rmat, CheckInt32Int32Float) cugraph::test::override_Rmat_Usecase_with_cmd_line_arguments(std::get<1>(param))); } -TEST_P(Tests_MGPerVPairTransformDstNbrIntersection_Rmat, CheckInt32Int64Float) -{ - auto param = GetParam(); - run_current_test( - std::get<0>(param), - cugraph::test::override_Rmat_Usecase_with_cmd_line_arguments(std::get<1>(param))); -} - TEST_P(Tests_MGPerVPairTransformDstNbrIntersection_Rmat, CheckInt64Int64Float) { auto param = GetParam(); diff --git a/cpp/tests/prims/mg_per_v_pair_transform_dst_nbr_weighted_intersection.cu b/cpp/tests/prims/mg_per_v_pair_transform_dst_nbr_weighted_intersection.cu index 06a23880d81..4e12cf608cb 100644 --- a/cpp/tests/prims/mg_per_v_pair_transform_dst_nbr_weighted_intersection.cu +++ b/cpp/tests/prims/mg_per_v_pair_transform_dst_nbr_weighted_intersection.cu @@ -163,7 +163,7 @@ class Tests_MGPerVPairTransformDstNbrIntersection cugraph::get_dataframe_buffer_begin(mg_vertex_pair_buffer), cugraph::get_dataframe_buffer_end(mg_vertex_pair_buffer), [comm_rank, num_vertices = mg_graph_view.number_of_vertices()] __device__(size_t i) { - cuco::detail::MurmurHash3_32 + cuco::murmurhash3_32 hash_func{}; // use hash_func to generate arbitrary vertex pairs auto v0 = static_cast(hash_func(i + comm_rank) % num_vertices); auto v1 = static_cast(hash_func(i + num_vertices + comm_rank) % num_vertices); @@ -337,14 +337,6 @@ TEST_P(Tests_MGPerVPairTransformDstNbrIntersection_Rmat, CheckInt32Int32Float) cugraph::test::override_Rmat_Usecase_with_cmd_line_arguments(std::get<1>(param))); } -TEST_P(Tests_MGPerVPairTransformDstNbrIntersection_Rmat, CheckInt32Int64Float) -{ - auto param = GetParam(); - run_current_test( - std::get<0>(param), - cugraph::test::override_Rmat_Usecase_with_cmd_line_arguments(std::get<1>(param))); -} - TEST_P(Tests_MGPerVPairTransformDstNbrIntersection_Rmat, CheckInt64Int64Float) { auto param = GetParam(); diff --git a/cpp/tests/prims/mg_per_v_random_select_transform_outgoing_e.cu b/cpp/tests/prims/mg_per_v_random_select_transform_outgoing_e.cu index f698701eb08..386fce24a87 100644 --- a/cpp/tests/prims/mg_per_v_random_select_transform_outgoing_e.cu +++ b/cpp/tests/prims/mg_per_v_random_select_transform_outgoing_e.cu @@ -565,14 +565,6 @@ TEST_P(Tests_MGPerVRandomSelectTransformOutgoingE_Rmat, CheckInt32Int32FloatTupl cugraph::test::override_Rmat_Usecase_with_cmd_line_arguments(std::get<1>(param))); } -TEST_P(Tests_MGPerVRandomSelectTransformOutgoingE_Rmat, CheckInt32Int64FloatTupleIntFloat) -{ - auto param = GetParam(); - run_current_test>( - std::get<0>(param), - cugraph::test::override_Rmat_Usecase_with_cmd_line_arguments(std::get<1>(param))); -} - TEST_P(Tests_MGPerVRandomSelectTransformOutgoingE_Rmat, CheckInt64Int64FloatTupleIntFloat) { auto param = GetParam(); @@ -595,14 +587,6 @@ TEST_P(Tests_MGPerVRandomSelectTransformOutgoingE_Rmat, CheckInt32Int32Float) cugraph::test::override_Rmat_Usecase_with_cmd_line_arguments(std::get<1>(param))); } -TEST_P(Tests_MGPerVRandomSelectTransformOutgoingE_Rmat, CheckInt32Int64Float) -{ - auto param = GetParam(); - run_current_test( - std::get<0>(param), - cugraph::test::override_Rmat_Usecase_with_cmd_line_arguments(std::get<1>(param))); -} - TEST_P(Tests_MGPerVRandomSelectTransformOutgoingE_Rmat, CheckInt64Int64Float) { auto param = GetParam(); diff --git a/cpp/tests/prims/mg_per_v_transform_reduce_dst_key_aggregated_outgoing_e.cu b/cpp/tests/prims/mg_per_v_transform_reduce_dst_key_aggregated_outgoing_e.cu index e08baa610e5..3dd256544b4 100644 --- a/cpp/tests/prims/mg_per_v_transform_reduce_dst_key_aggregated_outgoing_e.cu +++ b/cpp/tests/prims/mg_per_v_transform_reduce_dst_key_aggregated_outgoing_e.cu @@ -513,15 +513,6 @@ TEST_P(Tests_MGPerVTransformReduceDstKeyAggregatedOutgoingE_Rmat, cugraph::test::override_Rmat_Usecase_with_cmd_line_arguments(std::get<1>(param))); } -TEST_P(Tests_MGPerVTransformReduceDstKeyAggregatedOutgoingE_Rmat, - CheckInt32Int64FloatTupleIntFloatTransposeFalse) -{ - auto param = GetParam(); - run_current_test>( - std::get<0>(param), - cugraph::test::override_Rmat_Usecase_with_cmd_line_arguments(std::get<1>(param))); -} - TEST_P(Tests_MGPerVTransformReduceDstKeyAggregatedOutgoingE_Rmat, CheckInt64Int64FloatTupleIntFloatTransposeFalse) { @@ -547,15 +538,6 @@ TEST_P(Tests_MGPerVTransformReduceDstKeyAggregatedOutgoingE_Rmat, cugraph::test::override_Rmat_Usecase_with_cmd_line_arguments(std::get<1>(param))); } -TEST_P(Tests_MGPerVTransformReduceDstKeyAggregatedOutgoingE_Rmat, - CheckInt32Int64FloatTransposeFalse) -{ - auto param = GetParam(); - run_current_test( - std::get<0>(param), - cugraph::test::override_Rmat_Usecase_with_cmd_line_arguments(std::get<1>(param))); -} - TEST_P(Tests_MGPerVTransformReduceDstKeyAggregatedOutgoingE_Rmat, CheckInt64Int64FloatTransposeFalse) { diff --git a/cpp/tests/prims/mg_per_v_transform_reduce_incoming_outgoing_e.cu b/cpp/tests/prims/mg_per_v_transform_reduce_incoming_outgoing_e.cu index eb350ddb435..41830b3017c 100644 --- a/cpp/tests/prims/mg_per_v_transform_reduce_incoming_outgoing_e.cu +++ b/cpp/tests/prims/mg_per_v_transform_reduce_incoming_outgoing_e.cu @@ -494,15 +494,6 @@ TEST_P(Tests_MGPerVTransformReduceIncomingOutgoingE_Rmat, cugraph::test::override_Rmat_Usecase_with_cmd_line_arguments(std::get<1>(param))); } -TEST_P(Tests_MGPerVTransformReduceIncomingOutgoingE_Rmat, - CheckInt32Int64FloatTupleIntFloatTransposeFalse) -{ - auto param = GetParam(); - run_current_test, false>( - std::get<0>(param), - cugraph::test::override_Rmat_Usecase_with_cmd_line_arguments(std::get<1>(param))); -} - TEST_P(Tests_MGPerVTransformReduceIncomingOutgoingE_Rmat, CheckInt64Int64FloatTupleIntFloatTransposeFalse) { @@ -529,15 +520,6 @@ TEST_P(Tests_MGPerVTransformReduceIncomingOutgoingE_Rmat, cugraph::test::override_Rmat_Usecase_with_cmd_line_arguments(std::get<1>(param))); } -TEST_P(Tests_MGPerVTransformReduceIncomingOutgoingE_Rmat, - CheckInt32Int64FloatTupleIntFloatTransposeTrue) -{ - auto param = GetParam(); - run_current_test, true>( - std::get<0>(param), - cugraph::test::override_Rmat_Usecase_with_cmd_line_arguments(std::get<1>(param))); -} - TEST_P(Tests_MGPerVTransformReduceIncomingOutgoingE_Rmat, CheckInt64Int64FloatTupleIntFloatTransposeTrue) { @@ -561,14 +543,6 @@ TEST_P(Tests_MGPerVTransformReduceIncomingOutgoingE_Rmat, CheckInt32Int32FloatTr cugraph::test::override_Rmat_Usecase_with_cmd_line_arguments(std::get<1>(param))); } -TEST_P(Tests_MGPerVTransformReduceIncomingOutgoingE_Rmat, CheckInt32Int64FloatTransposeFalse) -{ - auto param = GetParam(); - run_current_test( - std::get<0>(param), - cugraph::test::override_Rmat_Usecase_with_cmd_line_arguments(std::get<1>(param))); -} - TEST_P(Tests_MGPerVTransformReduceIncomingOutgoingE_Rmat, CheckInt64Int64FloatTransposeFalse) { auto param = GetParam(); @@ -591,14 +565,6 @@ TEST_P(Tests_MGPerVTransformReduceIncomingOutgoingE_Rmat, CheckInt32Int32FloatTr cugraph::test::override_Rmat_Usecase_with_cmd_line_arguments(std::get<1>(param))); } -TEST_P(Tests_MGPerVTransformReduceIncomingOutgoingE_Rmat, CheckInt32Int64FloatTransposeTrue) -{ - auto param = GetParam(); - run_current_test( - std::get<0>(param), - cugraph::test::override_Rmat_Usecase_with_cmd_line_arguments(std::get<1>(param))); -} - TEST_P(Tests_MGPerVTransformReduceIncomingOutgoingE_Rmat, CheckInt64Int64FloatTransposeTrue) { auto param = GetParam(); diff --git a/cpp/tests/prims/mg_reduce_v.cu b/cpp/tests/prims/mg_reduce_v.cu index 0f53adcc71c..ebd557da004 100644 --- a/cpp/tests/prims/mg_reduce_v.cu +++ b/cpp/tests/prims/mg_reduce_v.cu @@ -270,13 +270,6 @@ TEST_P(Tests_MGReduceV_Rmat, CheckInt32Int32FloatTransposeFalse) std::get<0>(param), override_Rmat_Usecase_with_cmd_line_arguments(std::get<1>(param))); } -TEST_P(Tests_MGReduceV_Rmat, CheckInt32Int64FloatTransposeFalse) -{ - auto param = GetParam(); - run_current_test( - std::get<0>(param), override_Rmat_Usecase_with_cmd_line_arguments(std::get<1>(param))); -} - TEST_P(Tests_MGReduceV_Rmat, CheckInt64Int64FloatTransposeFalse) { auto param = GetParam(); @@ -297,13 +290,6 @@ TEST_P(Tests_MGReduceV_Rmat, CheckInt32Int32FloatTransposeTrue) std::get<0>(param), override_Rmat_Usecase_with_cmd_line_arguments(std::get<1>(param))); } -TEST_P(Tests_MGReduceV_Rmat, CheckInt32Int64FloatTransposeTrue) -{ - auto param = GetParam(); - run_current_test( - std::get<0>(param), override_Rmat_Usecase_with_cmd_line_arguments(std::get<1>(param))); -} - TEST_P(Tests_MGReduceV_Rmat, CheckInt64Int64FloatTransposeTrue) { auto param = GetParam(); diff --git a/cpp/tests/prims/mg_transform_e.cu b/cpp/tests/prims/mg_transform_e.cu index 2f131b4d54f..3984c7cd86b 100644 --- a/cpp/tests/prims/mg_transform_e.cu +++ b/cpp/tests/prims/mg_transform_e.cu @@ -278,14 +278,6 @@ TEST_P(Tests_MGTransformE_Rmat, CheckInt32Int32FloatTupleIntFloatTransposeFalse) cugraph::test::override_Rmat_Usecase_with_cmd_line_arguments(std::get<1>(param))); } -TEST_P(Tests_MGTransformE_Rmat, CheckInt32Int64FloatTupleIntFloatTransposeFalse) -{ - auto param = GetParam(); - run_current_test, false>( - std::get<0>(param), - cugraph::test::override_Rmat_Usecase_with_cmd_line_arguments(std::get<1>(param))); -} - TEST_P(Tests_MGTransformE_Rmat, CheckInt64Int64FloatTupleIntFloatTransposeFalse) { auto param = GetParam(); @@ -309,14 +301,6 @@ TEST_P(Tests_MGTransformE_Rmat, CheckInt32Int32FloatTupleIntFloatTransposeTrue) cugraph::test::override_Rmat_Usecase_with_cmd_line_arguments(std::get<1>(param))); } -TEST_P(Tests_MGTransformE_Rmat, CheckInt32Int64FloatTupleIntFloatTransposeTrue) -{ - auto param = GetParam(); - run_current_test, true>( - std::get<0>(param), - cugraph::test::override_Rmat_Usecase_with_cmd_line_arguments(std::get<1>(param))); -} - TEST_P(Tests_MGTransformE_Rmat, CheckInt64Int64FloatTupleIntFloatTransposeTrue) { auto param = GetParam(); @@ -339,14 +323,6 @@ TEST_P(Tests_MGTransformE_Rmat, CheckInt32Int32FloatIntTransposeFalse) cugraph::test::override_Rmat_Usecase_with_cmd_line_arguments(std::get<1>(param))); } -TEST_P(Tests_MGTransformE_Rmat, CheckInt32Int64FloatIntTransposeFalse) -{ - auto param = GetParam(); - run_current_test( - std::get<0>(param), - cugraph::test::override_Rmat_Usecase_with_cmd_line_arguments(std::get<1>(param))); -} - TEST_P(Tests_MGTransformE_Rmat, CheckInt64Int64FloatIntTransposeFalse) { auto param = GetParam(); @@ -369,14 +345,6 @@ TEST_P(Tests_MGTransformE_Rmat, CheckInt32Int32FloatIntTransposeTrue) cugraph::test::override_Rmat_Usecase_with_cmd_line_arguments(std::get<1>(param))); } -TEST_P(Tests_MGTransformE_Rmat, CheckInt32Int64FloatIntTransposeTrue) -{ - auto param = GetParam(); - run_current_test( - std::get<0>(param), - cugraph::test::override_Rmat_Usecase_with_cmd_line_arguments(std::get<1>(param))); -} - TEST_P(Tests_MGTransformE_Rmat, CheckInt64Int64FloatIntTransposeTrue) { auto param = GetParam(); @@ -399,14 +367,6 @@ TEST_P(Tests_MGTransformE_Rmat, CheckInt32Int32FloatBoolTransposeFalse) cugraph::test::override_Rmat_Usecase_with_cmd_line_arguments(std::get<1>(param))); } -TEST_P(Tests_MGTransformE_Rmat, CheckInt32Int64FloatBoolTransposeFalse) -{ - auto param = GetParam(); - run_current_test( - std::get<0>(param), - cugraph::test::override_Rmat_Usecase_with_cmd_line_arguments(std::get<1>(param))); -} - TEST_P(Tests_MGTransformE_Rmat, CheckInt64Int64FloatBoolTransposeFalse) { auto param = GetParam(); @@ -429,14 +389,6 @@ TEST_P(Tests_MGTransformE_Rmat, CheckInt32Int32FloatBoolTransposeTrue) cugraph::test::override_Rmat_Usecase_with_cmd_line_arguments(std::get<1>(param))); } -TEST_P(Tests_MGTransformE_Rmat, CheckInt32Int64FloatBoolTransposeTrue) -{ - auto param = GetParam(); - run_current_test( - std::get<0>(param), - cugraph::test::override_Rmat_Usecase_with_cmd_line_arguments(std::get<1>(param))); -} - TEST_P(Tests_MGTransformE_Rmat, CheckInt64Int64FloatBoolTransposeTrue) { auto param = GetParam(); diff --git a/cpp/tests/prims/mg_transform_reduce_dst_nbr_intersection_of_e_endpoints_by_v.cu b/cpp/tests/prims/mg_transform_reduce_dst_nbr_intersection_of_e_endpoints_by_v.cu index 8eee3d5a6d5..cb86a96d78b 100644 --- a/cpp/tests/prims/mg_transform_reduce_dst_nbr_intersection_of_e_endpoints_by_v.cu +++ b/cpp/tests/prims/mg_transform_reduce_dst_nbr_intersection_of_e_endpoints_by_v.cu @@ -246,14 +246,6 @@ TEST_P(Tests_MGTransformReduceDstNbrIntersectionOfEEndpointsByV_Rmat, CheckInt32 cugraph::test::override_Rmat_Usecase_with_cmd_line_arguments(std::get<1>(param))); } -TEST_P(Tests_MGTransformReduceDstNbrIntersectionOfEEndpointsByV_Rmat, CheckInt32Int64Float) -{ - auto param = GetParam(); - run_current_test( - std::get<0>(param), - cugraph::test::override_Rmat_Usecase_with_cmd_line_arguments(std::get<1>(param))); -} - TEST_P(Tests_MGTransformReduceDstNbrIntersectionOfEEndpointsByV_Rmat, CheckInt64Int64Float) { auto param = GetParam(); diff --git a/cpp/tests/prims/mg_transform_reduce_e.cu b/cpp/tests/prims/mg_transform_reduce_e.cu index ff8bd42f1ad..e290f05e9e4 100644 --- a/cpp/tests/prims/mg_transform_reduce_e.cu +++ b/cpp/tests/prims/mg_transform_reduce_e.cu @@ -228,14 +228,6 @@ TEST_P(Tests_MGTransformReduceE_Rmat, CheckInt32Int32FloatTupleIntFloatTranspose cugraph::test::override_Rmat_Usecase_with_cmd_line_arguments(std::get<1>(param))); } -TEST_P(Tests_MGTransformReduceE_Rmat, CheckInt32Int64FloatTupleIntFloatTransposeFalse) -{ - auto param = GetParam(); - run_current_test, false>( - std::get<0>(param), - cugraph::test::override_Rmat_Usecase_with_cmd_line_arguments(std::get<1>(param))); -} - TEST_P(Tests_MGTransformReduceE_Rmat, CheckInt64Int64FloatTupleIntFloatTransposeFalse) { auto param = GetParam(); @@ -259,14 +251,6 @@ TEST_P(Tests_MGTransformReduceE_Rmat, CheckInt32Int32FloatTupleIntFloatTranspose cugraph::test::override_Rmat_Usecase_with_cmd_line_arguments(std::get<1>(param))); } -TEST_P(Tests_MGTransformReduceE_Rmat, CheckInt32Int64FloatTupleIntFloatTransposeTrue) -{ - auto param = GetParam(); - run_current_test, true>( - std::get<0>(param), - cugraph::test::override_Rmat_Usecase_with_cmd_line_arguments(std::get<1>(param))); -} - TEST_P(Tests_MGTransformReduceE_Rmat, CheckInt64Int64FloatTupleIntFloatTransposeTrue) { auto param = GetParam(); @@ -289,14 +273,6 @@ TEST_P(Tests_MGTransformReduceE_Rmat, CheckInt32Int32FloatTransposeFalse) cugraph::test::override_Rmat_Usecase_with_cmd_line_arguments(std::get<1>(param))); } -TEST_P(Tests_MGTransformReduceE_Rmat, CheckInt32Int64FloatTransposeFalse) -{ - auto param = GetParam(); - run_current_test( - std::get<0>(param), - cugraph::test::override_Rmat_Usecase_with_cmd_line_arguments(std::get<1>(param))); -} - TEST_P(Tests_MGTransformReduceE_Rmat, CheckInt64Int64FloatTransposeFalse) { auto param = GetParam(); @@ -319,14 +295,6 @@ TEST_P(Tests_MGTransformReduceE_Rmat, CheckInt32Int32FloatTransposeTrue) cugraph::test::override_Rmat_Usecase_with_cmd_line_arguments(std::get<1>(param))); } -TEST_P(Tests_MGTransformReduceE_Rmat, CheckInt32Int64FloatTransposeTrue) -{ - auto param = GetParam(); - run_current_test( - std::get<0>(param), - cugraph::test::override_Rmat_Usecase_with_cmd_line_arguments(std::get<1>(param))); -} - TEST_P(Tests_MGTransformReduceE_Rmat, CheckInt64Int64FloatTransposeTrue) { auto param = GetParam(); diff --git a/cpp/tests/prims/mg_transform_reduce_e_by_src_dst_key.cu b/cpp/tests/prims/mg_transform_reduce_e_by_src_dst_key.cu index c7bb51e3635..b050e314a15 100644 --- a/cpp/tests/prims/mg_transform_reduce_e_by_src_dst_key.cu +++ b/cpp/tests/prims/mg_transform_reduce_e_by_src_dst_key.cu @@ -354,14 +354,6 @@ TEST_P(Tests_MGTransformReduceEBySrcDstKey_Rmat, CheckInt32Int32FloatTupleIntFlo cugraph::test::override_Rmat_Usecase_with_cmd_line_arguments(std::get<1>(param))); } -TEST_P(Tests_MGTransformReduceEBySrcDstKey_Rmat, CheckInt32Int64FloatTupleIntFloatTransposeFalse) -{ - auto param = GetParam(); - run_current_test, false>( - std::get<0>(param), - cugraph::test::override_Rmat_Usecase_with_cmd_line_arguments(std::get<1>(param))); -} - TEST_P(Tests_MGTransformReduceEBySrcDstKey_Rmat, CheckInt64Int64FloatTupleIntFloatTransposeFalse) { auto param = GetParam(); @@ -385,14 +377,6 @@ TEST_P(Tests_MGTransformReduceEBySrcDstKey_Rmat, CheckInt32Int32FloatTupleIntFlo cugraph::test::override_Rmat_Usecase_with_cmd_line_arguments(std::get<1>(param))); } -TEST_P(Tests_MGTransformReduceEBySrcDstKey_Rmat, CheckInt32Int64FloatTupleIntFloatTransposeTrue) -{ - auto param = GetParam(); - run_current_test, true>( - std::get<0>(param), - cugraph::test::override_Rmat_Usecase_with_cmd_line_arguments(std::get<1>(param))); -} - TEST_P(Tests_MGTransformReduceEBySrcDstKey_Rmat, CheckInt64Int64FloatTupleIntFloatTransposeTrue) { auto param = GetParam(); @@ -415,14 +399,6 @@ TEST_P(Tests_MGTransformReduceEBySrcDstKey_Rmat, CheckInt32Int32FloatTransposeFa cugraph::test::override_Rmat_Usecase_with_cmd_line_arguments(std::get<1>(param))); } -TEST_P(Tests_MGTransformReduceEBySrcDstKey_Rmat, CheckInt32Int64FloatTransposeFalse) -{ - auto param = GetParam(); - run_current_test( - std::get<0>(param), - cugraph::test::override_Rmat_Usecase_with_cmd_line_arguments(std::get<1>(param))); -} - TEST_P(Tests_MGTransformReduceEBySrcDstKey_Rmat, CheckInt64Int64FloatTransposeFalse) { auto param = GetParam(); @@ -445,14 +421,6 @@ TEST_P(Tests_MGTransformReduceEBySrcDstKey_Rmat, CheckInt32Int32FloatTransposeTr cugraph::test::override_Rmat_Usecase_with_cmd_line_arguments(std::get<1>(param))); } -TEST_P(Tests_MGTransformReduceEBySrcDstKey_Rmat, CheckInt32Int64FloatTransposeTrue) -{ - auto param = GetParam(); - run_current_test( - std::get<0>(param), - cugraph::test::override_Rmat_Usecase_with_cmd_line_arguments(std::get<1>(param))); -} - TEST_P(Tests_MGTransformReduceEBySrcDstKey_Rmat, CheckInt64Int64FloatTransposeTrue) { auto param = GetParam(); diff --git a/cpp/tests/prims/mg_transform_reduce_v.cu b/cpp/tests/prims/mg_transform_reduce_v.cu index 0e6d71094bd..1e5cb7207b1 100644 --- a/cpp/tests/prims/mg_transform_reduce_v.cu +++ b/cpp/tests/prims/mg_transform_reduce_v.cu @@ -53,7 +53,7 @@ struct v_op_t { __device__ auto operator()(vertex_t, vertex_t val) const { - cuco::detail::MurmurHash3_32 hash_func{}; + cuco::murmurhash3_32 hash_func{}; return cugraph::test::detail::make_property_value(hash_func(val) % mod); } }; @@ -246,14 +246,6 @@ TEST_P(Tests_MGTransformReduceV_Rmat, CheckInt32Int32FloatTupleIntFloatTranspose cugraph::test::override_Rmat_Usecase_with_cmd_line_arguments(std::get<1>(param))); } -TEST_P(Tests_MGTransformReduceV_Rmat, CheckInt32Int64FloatTupleIntFloatTransposeFalse) -{ - auto param = GetParam(); - run_current_test, false>( - std::get<0>(param), - cugraph::test::override_Rmat_Usecase_with_cmd_line_arguments(std::get<1>(param))); -} - TEST_P(Tests_MGTransformReduceV_Rmat, CheckInt64Int64FloatTupleIntFloatTransposeFalse) { auto param = GetParam(); @@ -277,14 +269,6 @@ TEST_P(Tests_MGTransformReduceV_Rmat, CheckInt32Int32FloatTupleIntFloatTranspose cugraph::test::override_Rmat_Usecase_with_cmd_line_arguments(std::get<1>(param))); } -TEST_P(Tests_MGTransformReduceV_Rmat, CheckInt32Int64FloatTupleIntFloatTransposeTrue) -{ - auto param = GetParam(); - run_current_test, true>( - std::get<0>(param), - cugraph::test::override_Rmat_Usecase_with_cmd_line_arguments(std::get<1>(param))); -} - TEST_P(Tests_MGTransformReduceV_Rmat, CheckInt64Int64FloatTupleIntFloatTransposeTrue) { auto param = GetParam(); @@ -307,14 +291,6 @@ TEST_P(Tests_MGTransformReduceV_Rmat, CheckInt32Int32FloatTransposeFalse) cugraph::test::override_Rmat_Usecase_with_cmd_line_arguments(std::get<1>(param))); } -TEST_P(Tests_MGTransformReduceV_Rmat, CheckInt32Int64FloatTransposeFalse) -{ - auto param = GetParam(); - run_current_test( - std::get<0>(param), - cugraph::test::override_Rmat_Usecase_with_cmd_line_arguments(std::get<1>(param))); -} - TEST_P(Tests_MGTransformReduceV_Rmat, CheckInt64Int64FloatTransposeFalse) { auto param = GetParam(); @@ -337,14 +313,6 @@ TEST_P(Tests_MGTransformReduceV_Rmat, CheckInt32Int32FloatTransposeTrue) cugraph::test::override_Rmat_Usecase_with_cmd_line_arguments(std::get<1>(param))); } -TEST_P(Tests_MGTransformReduceV_Rmat, CheckInt32Int64FloatTransposeTrue) -{ - auto param = GetParam(); - run_current_test( - std::get<0>(param), - cugraph::test::override_Rmat_Usecase_with_cmd_line_arguments(std::get<1>(param))); -} - TEST_P(Tests_MGTransformReduceV_Rmat, CheckInt64Int64FloatTransposeTrue) { auto param = GetParam(); diff --git a/cpp/tests/prims/mg_transform_reduce_v_frontier_outgoing_e_by_src_dst.cu b/cpp/tests/prims/mg_transform_reduce_v_frontier_outgoing_e_by_src_dst.cu index 5947dd9a560..9b7e24856fe 100644 --- a/cpp/tests/prims/mg_transform_reduce_v_frontier_outgoing_e_by_src_dst.cu +++ b/cpp/tests/prims/mg_transform_reduce_v_frontier_outgoing_e_by_src_dst.cu @@ -688,21 +688,6 @@ TEST_P(Tests_MGTransformReduceVFrontierOutgoingEBySrcDst_Rmat, cugraph::test::override_Rmat_Usecase_with_cmd_line_arguments(std::get<1>(param))); } -TEST_P(Tests_MGTransformReduceVFrontierOutgoingEBySrcDst_File, CheckInt32Int64FloatInt32Int32) -{ - auto param = GetParam(); - run_current_test(std::get<0>(param), - std::get<1>(param)); -} - -TEST_P(Tests_MGTransformReduceVFrontierOutgoingEBySrcDst_Rmat, CheckInt32Int64FloatInt32Int32) -{ - auto param = GetParam(); - run_current_test( - std::get<0>(param), - cugraph::test::override_Rmat_Usecase_with_cmd_line_arguments(std::get<1>(param))); -} - TEST_P(Tests_MGTransformReduceVFrontierOutgoingEBySrcDst_File, CheckInt64Int64FloatInt32Int32) { auto param = GetParam(); diff --git a/cpp/tests/sampling/biased_neighbor_sampling.cpp b/cpp/tests/sampling/biased_neighbor_sampling.cpp index 0b7307bef7d..6e63d18383e 100644 --- a/cpp/tests/sampling/biased_neighbor_sampling.cpp +++ b/cpp/tests/sampling/biased_neighbor_sampling.cpp @@ -223,13 +223,6 @@ TEST_P(Tests_Biased_Neighbor_Sampling_File, CheckInt32Int32Float) override_File_Usecase_with_cmd_line_arguments(GetParam())); } -TEST_P(Tests_Biased_Neighbor_Sampling_File, CheckInt32Int64Float) -{ - auto param = GetParam(); - run_current_test( - override_File_Usecase_with_cmd_line_arguments(GetParam())); -} - TEST_P(Tests_Biased_Neighbor_Sampling_File, CheckInt64Int64Float) { auto param = GetParam(); @@ -243,12 +236,6 @@ TEST_P(Tests_Biased_Neighbor_Sampling_Rmat, CheckInt32Int32Float) override_Rmat_Usecase_with_cmd_line_arguments(GetParam())); } -TEST_P(Tests_Biased_Neighbor_Sampling_Rmat, CheckInt32Int64Float) -{ - run_current_test( - override_Rmat_Usecase_with_cmd_line_arguments(GetParam())); -} - TEST_P(Tests_Biased_Neighbor_Sampling_Rmat, CheckInt64Int64Float) { run_current_test( diff --git a/cpp/tests/sampling/mg_biased_neighbor_sampling.cpp b/cpp/tests/sampling/mg_biased_neighbor_sampling.cpp index 8f08320aac8..d39e1725b63 100644 --- a/cpp/tests/sampling/mg_biased_neighbor_sampling.cpp +++ b/cpp/tests/sampling/mg_biased_neighbor_sampling.cpp @@ -298,12 +298,6 @@ TEST_P(Tests_MGBiased_Neighbor_Sampling_Rmat, CheckInt32Int32Float) override_Rmat_Usecase_with_cmd_line_arguments(GetParam())); } -TEST_P(Tests_MGBiased_Neighbor_Sampling_Rmat, CheckInt32Int64Float) -{ - run_current_test( - override_Rmat_Usecase_with_cmd_line_arguments(GetParam())); -} - TEST_P(Tests_MGBiased_Neighbor_Sampling_Rmat, CheckInt64Int64Float) { run_current_test( diff --git a/cpp/tests/sampling/mg_random_walks_test.cpp b/cpp/tests/sampling/mg_random_walks_test.cpp index c2ad5c37e9e..e2415c08e60 100644 --- a/cpp/tests/sampling/mg_random_walks_test.cpp +++ b/cpp/tests/sampling/mg_random_walks_test.cpp @@ -44,8 +44,10 @@ struct UniformRandomWalks_Usecase { raft::device_span start_vertices, size_t max_depth) { + raft::random::RngState rng_state(static_cast(handle.get_comms().get_rank())); + return cugraph::uniform_random_walks( - handle, graph_view, edge_weight_view, start_vertices, max_depth, seed); + handle, rng_state, graph_view, edge_weight_view, start_vertices, max_depth); } bool expect_throw() { return false; } @@ -66,12 +68,13 @@ struct BiasedRandomWalks_Usecase { { CUGRAPH_EXPECTS(edge_weight_view.has_value(), "Biased random walk requires edge weights."); + raft::random::RngState rng_state(static_cast(handle.get_comms().get_rank())); + return cugraph::biased_random_walks( - handle, graph_view, *edge_weight_view, start_vertices, max_depth, seed); + handle, rng_state, graph_view, *edge_weight_view, start_vertices, max_depth); } - // FIXME: Not currently implemented - bool expect_throw() { return true; } + bool expect_throw() { return !test_weighted; } }; struct Node2VecRandomWalks_Usecase { @@ -89,18 +92,19 @@ struct Node2VecRandomWalks_Usecase { raft::device_span start_vertices, size_t max_depth) { + raft::random::RngState rng_state(static_cast(handle.get_comms().get_rank())); + return cugraph::node2vec_random_walks(handle, + rng_state, graph_view, edge_weight_view, start_vertices, max_depth, static_cast(p), - static_cast(q), - seed); + static_cast(q)); } - // FIXME: Not currently implemented - bool expect_throw() { return true; } + bool expect_throw() { return false; } }; template diff --git a/cpp/tests/sampling/mg_uniform_neighbor_sampling.cpp b/cpp/tests/sampling/mg_uniform_neighbor_sampling.cpp index 23f1da40cf4..0dd63e4fb06 100644 --- a/cpp/tests/sampling/mg_uniform_neighbor_sampling.cpp +++ b/cpp/tests/sampling/mg_uniform_neighbor_sampling.cpp @@ -320,12 +320,6 @@ TEST_P(Tests_MGUniform_Neighbor_Sampling_Rmat, CheckInt32Int32Float) override_Rmat_Usecase_with_cmd_line_arguments(GetParam())); } -TEST_P(Tests_MGUniform_Neighbor_Sampling_Rmat, CheckInt32Int64Float) -{ - run_current_test( - override_Rmat_Usecase_with_cmd_line_arguments(GetParam())); -} - TEST_P(Tests_MGUniform_Neighbor_Sampling_Rmat, CheckInt64Int64Float) { run_current_test( diff --git a/cpp/tests/sampling/negative_sampling.cpp b/cpp/tests/sampling/negative_sampling.cpp index ba929c63e9b..8906d011376 100644 --- a/cpp/tests/sampling/negative_sampling.cpp +++ b/cpp/tests/sampling/negative_sampling.cpp @@ -213,18 +213,12 @@ class Tests_Negative_Sampling : public ::testing::TestWithParam using Tests_Negative_Sampling_File_i32_i32_float = Tests_Negative_Sampling; -using Tests_Negative_Sampling_File_i32_i64_float = - Tests_Negative_Sampling; - using Tests_Negative_Sampling_File_i64_i64_float = Tests_Negative_Sampling; using Tests_Negative_Sampling_Rmat_i32_i32_float = Tests_Negative_Sampling; -using Tests_Negative_Sampling_Rmat_i32_i64_float = - Tests_Negative_Sampling; - using Tests_Negative_Sampling_Rmat_i64_i64_float = Tests_Negative_Sampling; @@ -255,12 +249,6 @@ TEST_P(Tests_Negative_Sampling_File_i32_i32_float, CheckInt32Int32Float) run_all_tests(this); } -TEST_P(Tests_Negative_Sampling_File_i32_i64_float, CheckInt32Int64Float) -{ - load_graph(override_File_Usecase_with_cmd_line_arguments(GetParam())); - run_all_tests(this); -} - TEST_P(Tests_Negative_Sampling_File_i64_i64_float, CheckInt64Int64Float) { load_graph(override_File_Usecase_with_cmd_line_arguments(GetParam())); @@ -273,12 +261,6 @@ TEST_P(Tests_Negative_Sampling_Rmat_i32_i32_float, CheckInt32Int32Float) run_all_tests(this); } -TEST_P(Tests_Negative_Sampling_Rmat_i32_i64_float, CheckInt32Int64Float) -{ - load_graph(override_Rmat_Usecase_with_cmd_line_arguments(GetParam())); - run_all_tests(this); -} - TEST_P(Tests_Negative_Sampling_Rmat_i64_i64_float, CheckInt64Int64Float) { load_graph(override_Rmat_Usecase_with_cmd_line_arguments(GetParam())); @@ -297,18 +279,6 @@ INSTANTIATE_TEST_SUITE_P( cugraph::test::File_Usecase("test/datasets/ljournal-2008.mtx"), cugraph::test::File_Usecase("test/datasets/webbase-1M.mtx"))); -INSTANTIATE_TEST_SUITE_P( - file_test, - Tests_Negative_Sampling_File_i32_i64_float, - ::testing::Values(cugraph::test::File_Usecase("test/datasets/karate.mtx"))); - -INSTANTIATE_TEST_SUITE_P( - file_large_test, - Tests_Negative_Sampling_File_i32_i64_float, - ::testing::Values(cugraph::test::File_Usecase("test/datasets/web-Google.mtx"), - cugraph::test::File_Usecase("test/datasets/ljournal-2008.mtx"), - cugraph::test::File_Usecase("test/datasets/webbase-1M.mtx"))); - INSTANTIATE_TEST_SUITE_P( file_test, Tests_Negative_Sampling_File_i64_i64_float, @@ -326,11 +296,6 @@ INSTANTIATE_TEST_SUITE_P( Tests_Negative_Sampling_Rmat_i32_i32_float, ::testing::Values(cugraph::test::Rmat_Usecase(10, 16, 0.57, 0.19, 0.19, 0, false, false, 0))); -INSTANTIATE_TEST_SUITE_P( - rmat_small_test, - Tests_Negative_Sampling_Rmat_i32_i64_float, - ::testing::Values(cugraph::test::Rmat_Usecase(10, 16, 0.57, 0.19, 0.19, 0, false, false, 0))); - INSTANTIATE_TEST_SUITE_P( rmat_small_test, Tests_Negative_Sampling_Rmat_i64_i64_float, diff --git a/cpp/tests/sampling/random_walks_check.cuh b/cpp/tests/sampling/random_walks_check.cuh index 0fd73b5bba7..380b97a5b84 100644 --- a/cpp/tests/sampling/random_walks_check.cuh +++ b/cpp/tests/sampling/random_walks_check.cuh @@ -108,7 +108,7 @@ void random_walks_validate( (int)d, (float)w); } else { - printf("edge (%d,%d) NOT FOUND\n", (int)s, (int)d); + printf("edge (%d,%d), weight %g NOT FOUND\n", (int)s, (int)d, (float)w); } return 1; diff --git a/cpp/tests/sampling/sampling_heterogeneous_post_processing_test.cpp b/cpp/tests/sampling/sampling_heterogeneous_post_processing_test.cpp index 2b2049dc8db..4d58bfc31e6 100644 --- a/cpp/tests/sampling/sampling_heterogeneous_post_processing_test.cpp +++ b/cpp/tests/sampling/sampling_heterogeneous_post_processing_test.cpp @@ -578,11 +578,6 @@ TEST_P(Tests_SamplingHeterogeneousPostProcessing_Rmat, CheckInt32Int32) run_current_test(override_Rmat_Usecase_with_cmd_line_arguments(GetParam())); } -TEST_P(Tests_SamplingHeterogeneousPostProcessing_Rmat, CheckInt32Int64) -{ - run_current_test(override_Rmat_Usecase_with_cmd_line_arguments(GetParam())); -} - TEST_P(Tests_SamplingHeterogeneousPostProcessing_Rmat, CheckInt64Int64) { run_current_test(override_Rmat_Usecase_with_cmd_line_arguments(GetParam())); diff --git a/cpp/tests/sampling/sampling_post_processing_test.cpp b/cpp/tests/sampling/sampling_post_processing_test.cpp index b262794d26d..c1b99b99b0a 100644 --- a/cpp/tests/sampling/sampling_post_processing_test.cpp +++ b/cpp/tests/sampling/sampling_post_processing_test.cpp @@ -896,11 +896,6 @@ TEST_P(Tests_SamplingPostProcessing_Rmat, CheckInt32Int32) run_current_test(override_Rmat_Usecase_with_cmd_line_arguments(GetParam())); } -TEST_P(Tests_SamplingPostProcessing_Rmat, CheckInt32Int64) -{ - run_current_test(override_Rmat_Usecase_with_cmd_line_arguments(GetParam())); -} - TEST_P(Tests_SamplingPostProcessing_Rmat, CheckInt64Int64) { run_current_test(override_Rmat_Usecase_with_cmd_line_arguments(GetParam())); diff --git a/cpp/tests/sampling/sg_random_walks_test.cpp b/cpp/tests/sampling/sg_random_walks_test.cpp index 7409c2ab758..4bcfebc6d51 100644 --- a/cpp/tests/sampling/sg_random_walks_test.cpp +++ b/cpp/tests/sampling/sg_random_walks_test.cpp @@ -40,8 +40,10 @@ struct UniformRandomWalks_Usecase { raft::device_span start_vertices, size_t num_paths) { + raft::random::RngState rng_state(0); + return cugraph::uniform_random_walks( - handle, graph_view, edge_weight_view, start_vertices, num_paths, seed); + handle, rng_state, graph_view, edge_weight_view, start_vertices, num_paths); } bool expect_throw() { return false; } @@ -62,12 +64,13 @@ struct BiasedRandomWalks_Usecase { { CUGRAPH_EXPECTS(edge_weight_view.has_value(), "Biased random walk requires edge weights."); + raft::random::RngState rng_state(0); + return cugraph::biased_random_walks( - handle, graph_view, *edge_weight_view, start_vertices, num_paths, seed); + handle, rng_state, graph_view, *edge_weight_view, start_vertices, num_paths); } - // FIXME: Not currently implemented - bool expect_throw() { return true; } + bool expect_throw() { return !test_weighted; } }; struct Node2VecRandomWalks_Usecase { @@ -85,18 +88,19 @@ struct Node2VecRandomWalks_Usecase { raft::device_span start_vertices, size_t num_paths) { + raft::random::RngState rng_state(0); + return cugraph::node2vec_random_walks(handle, + rng_state, graph_view, edge_weight_view, start_vertices, num_paths, static_cast(p), - static_cast(q), - seed); + static_cast(q)); } - // FIXME: Not currently implemented - bool expect_throw() { return true; } + bool expect_throw() { return false; } }; template @@ -197,9 +201,6 @@ using Tests_Node2VecRandomWalks_File = using Tests_Node2VecRandomWalks_Rmat = Tests_RandomWalks>; -#if 0 -// FIXME: We should use these tests, gtest-1.11.0 makes it a runtime error -// to define and not instantiate these. TEST_P(Tests_UniformRandomWalks_File, Initialize_i32_i32_f) { run_current_test( @@ -211,7 +212,6 @@ TEST_P(Tests_UniformRandomWalks_Rmat, Initialize_i32_i32_f) run_current_test( override_Rmat_Usecase_with_cmd_line_arguments(GetParam())); } -#endif TEST_P(Tests_BiasedRandomWalks_File, Initialize_i32_i32_f) { @@ -237,19 +237,12 @@ TEST_P(Tests_Node2VecRandomWalks_Rmat, Initialize_i32_i32_f) override_Rmat_Usecase_with_cmd_line_arguments(GetParam())); } -#if 0 -// FIXME: Not sure why these are failing, but we're refactoring anyway. INSTANTIATE_TEST_SUITE_P( simple_test, Tests_UniformRandomWalks_File, - ::testing::Combine( - ::testing::Values(UniformRandomWalks_Usecase{false, 0, true}, - UniformRandomWalks_Usecase{true, 0, true}), - ::testing::Values(cugraph::test::File_Usecase("test/datasets/karate.mtx"), - cugraph::test::File_Usecase("test/datasets/web-Google.mtx"), - cugraph::test::File_Usecase("test/datasets/ljournal-2008.mtx"), - cugraph::test::File_Usecase("test/datasets/webbase-1M.mtx")))); -#endif + ::testing::Combine(::testing::Values(UniformRandomWalks_Usecase{false, 0, true}, + UniformRandomWalks_Usecase{true, 0, true}), + ::testing::Values(cugraph::test::File_Usecase("test/datasets/karate.mtx")))); INSTANTIATE_TEST_SUITE_P( file_test, @@ -265,6 +258,16 @@ INSTANTIATE_TEST_SUITE_P( Node2VecRandomWalks_Usecase{4, 8, true, 0, true}), ::testing::Values(cugraph::test::File_Usecase("test/datasets/karate.mtx")))); +INSTANTIATE_TEST_SUITE_P( + file_large_test, + Tests_UniformRandomWalks_File, + ::testing::Combine( + ::testing::Values(UniformRandomWalks_Usecase{false, 0, true}, + UniformRandomWalks_Usecase{true, 0, true}), + ::testing::Values(cugraph::test::File_Usecase("test/datasets/web-Google.mtx"), + cugraph::test::File_Usecase("test/datasets/ljournal-2008.mtx"), + cugraph::test::File_Usecase("test/datasets/webbase-1M.mtx")))); + INSTANTIATE_TEST_SUITE_P( file_large_test, Tests_BiasedRandomWalks_File, @@ -285,23 +288,20 @@ INSTANTIATE_TEST_SUITE_P( cugraph::test::File_Usecase("test/datasets/ljournal-2008.mtx"), cugraph::test::File_Usecase("test/datasets/webbase-1M.mtx")))); -#if 0 -// FIXME: Not sure why these are failing, but we're refactoring anyway. INSTANTIATE_TEST_SUITE_P( rmat_small_test, Tests_UniformRandomWalks_Rmat, - ::testing::Combine(::testing::Values(UniformRandomWalks_Usecase{false, 0, true}, - UniformRandomWalks_Usecase{true, 0, true}), - ::testing::Values(cugraph::test::Rmat_Usecase( - 10, 16, 0.57, 0.19, 0.19, 0, false, false)))); + ::testing::Combine( + ::testing::Values(UniformRandomWalks_Usecase{false, 0, true}, + UniformRandomWalks_Usecase{true, 0, true}), + ::testing::Values(cugraph::test::Rmat_Usecase(10, 16, 0.57, 0.19, 0.19, 0, false, false)))); INSTANTIATE_TEST_SUITE_P( rmat_benchmark_test, Tests_UniformRandomWalks_Rmat, - ::testing::Combine(::testing::Values(UniformRandomWalks_Usecase{true, 0, false}), - ::testing::Values(cugraph::test::Rmat_Usecase( - 20, 32, 0.57, 0.19, 0.19, 0, false, false)))); -#endif + ::testing::Combine( + ::testing::Values(UniformRandomWalks_Usecase{true, 0, false}), + ::testing::Values(cugraph::test::Rmat_Usecase(20, 32, 0.57, 0.19, 0.19, 0, false, false)))); INSTANTIATE_TEST_SUITE_P( rmat_small_test, diff --git a/cpp/tests/sampling/uniform_neighbor_sampling.cpp b/cpp/tests/sampling/uniform_neighbor_sampling.cpp index e348780e14b..87524b03acf 100644 --- a/cpp/tests/sampling/uniform_neighbor_sampling.cpp +++ b/cpp/tests/sampling/uniform_neighbor_sampling.cpp @@ -240,12 +240,6 @@ TEST_P(Tests_Uniform_Neighbor_Sampling_File, CheckInt32Int32Float) override_File_Usecase_with_cmd_line_arguments(GetParam())); } -TEST_P(Tests_Uniform_Neighbor_Sampling_File, CheckInt32Int64Float) -{ - run_current_test( - override_File_Usecase_with_cmd_line_arguments(GetParam())); -} - TEST_P(Tests_Uniform_Neighbor_Sampling_File, CheckInt64Int64Float) { run_current_test( @@ -258,12 +252,6 @@ TEST_P(Tests_Uniform_Neighbor_Sampling_Rmat, CheckInt32Int32Float) override_Rmat_Usecase_with_cmd_line_arguments(GetParam())); } -TEST_P(Tests_Uniform_Neighbor_Sampling_Rmat, CheckInt32Int64Float) -{ - run_current_test( - override_Rmat_Usecase_with_cmd_line_arguments(GetParam())); -} - TEST_P(Tests_Uniform_Neighbor_Sampling_Rmat, CheckInt64Int64Float) { run_current_test( diff --git a/cpp/tests/structure/coarsen_graph_test.cpp b/cpp/tests/structure/coarsen_graph_test.cpp index 9225156f7f3..417dd4f3e05 100644 --- a/cpp/tests/structure/coarsen_graph_test.cpp +++ b/cpp/tests/structure/coarsen_graph_test.cpp @@ -366,18 +366,6 @@ TEST_P(Tests_CoarsenGraph_Rmat, CheckInt32Int32FloatTransposeTrue) override_Rmat_Usecase_with_cmd_line_arguments(GetParam())); } -TEST_P(Tests_CoarsenGraph_Rmat, CheckInt32Int64FloatTransposeFalse) -{ - run_current_test( - override_Rmat_Usecase_with_cmd_line_arguments(GetParam())); -} - -TEST_P(Tests_CoarsenGraph_Rmat, CheckInt32Int64FloatTransposeTrue) -{ - run_current_test( - override_Rmat_Usecase_with_cmd_line_arguments(GetParam())); -} - TEST_P(Tests_CoarsenGraph_Rmat, CheckInt64Int64FloatTransposeFalse) { run_current_test( diff --git a/cpp/tests/structure/count_self_loops_and_multi_edges_test.cpp b/cpp/tests/structure/count_self_loops_and_multi_edges_test.cpp index 0055ee1315e..178909037b1 100644 --- a/cpp/tests/structure/count_self_loops_and_multi_edges_test.cpp +++ b/cpp/tests/structure/count_self_loops_and_multi_edges_test.cpp @@ -177,13 +177,6 @@ TEST_P(Tests_CountSelfLoopsAndMultiEdges_Rmat, CheckInt32Int32FloatTransposeFals std::get<0>(param), override_Rmat_Usecase_with_cmd_line_arguments(std::get<1>(param))); } -TEST_P(Tests_CountSelfLoopsAndMultiEdges_Rmat, CheckInt32Int64FloatTransposeFalse) -{ - auto param = GetParam(); - run_current_test( - std::get<0>(param), override_Rmat_Usecase_with_cmd_line_arguments(std::get<1>(param))); -} - TEST_P(Tests_CountSelfLoopsAndMultiEdges_Rmat, CheckInt64Int64FloatTransposeFalse) { auto param = GetParam(); diff --git a/cpp/tests/structure/has_edge_and_compute_multiplicity_test.cpp b/cpp/tests/structure/has_edge_and_compute_multiplicity_test.cpp index 322d7915504..9c2576cfe6c 100644 --- a/cpp/tests/structure/has_edge_and_compute_multiplicity_test.cpp +++ b/cpp/tests/structure/has_edge_and_compute_multiplicity_test.cpp @@ -223,13 +223,6 @@ TEST_P(Tests_HasEdgeAndComputeMultiplicity_Rmat, CheckInt32Int32FloatTransposeFa std::get<0>(param), override_Rmat_Usecase_with_cmd_line_arguments(std::get<1>(param))); } -TEST_P(Tests_HasEdgeAndComputeMultiplicity_Rmat, CheckInt32Int64FloatTransposeFalse) -{ - auto param = GetParam(); - run_current_test( - std::get<0>(param), override_Rmat_Usecase_with_cmd_line_arguments(std::get<1>(param))); -} - TEST_P(Tests_HasEdgeAndComputeMultiplicity_Rmat, CheckInt64Int64FloatTransposeFalse) { auto param = GetParam(); diff --git a/cpp/tests/structure/mg_coarsen_graph_test.cpp b/cpp/tests/structure/mg_coarsen_graph_test.cpp index 471773d71bd..deb4c287183 100644 --- a/cpp/tests/structure/mg_coarsen_graph_test.cpp +++ b/cpp/tests/structure/mg_coarsen_graph_test.cpp @@ -436,20 +436,6 @@ TEST_P(Tests_MGCoarsenGraph_Rmat, CheckInt32Int32FloatTransposeFalse) std::get<0>(param), override_Rmat_Usecase_with_cmd_line_arguments(std::get<1>(param))); } -TEST_P(Tests_MGCoarsenGraph_Rmat, CheckInt32Int64FloatTransposeFalse) -{ - auto param = GetParam(); - run_current_test( - std::get<0>(param), override_Rmat_Usecase_with_cmd_line_arguments(std::get<1>(param))); -} - -TEST_P(Tests_MGCoarsenGraph_Rmat, CheckInt64Int64FloatTransposeFalse) -{ - auto param = GetParam(); - run_current_test( - std::get<0>(param), override_Rmat_Usecase_with_cmd_line_arguments(std::get<1>(param))); -} - TEST_P(Tests_MGCoarsenGraph_File, CheckInt32Int32FloatTransposeTrue) { auto param = GetParam(); diff --git a/cpp/tests/structure/mg_count_self_loops_and_multi_edges_test.cpp b/cpp/tests/structure/mg_count_self_loops_and_multi_edges_test.cpp index 61f40049e31..8b78e16c404 100644 --- a/cpp/tests/structure/mg_count_self_loops_and_multi_edges_test.cpp +++ b/cpp/tests/structure/mg_count_self_loops_and_multi_edges_test.cpp @@ -180,13 +180,6 @@ TEST_P(Tests_MGCountSelfLoopsAndMultiEdges_Rmat, CheckInt32Int32FloatTransposeFa std::get<0>(param), override_Rmat_Usecase_with_cmd_line_arguments(std::get<1>(param))); } -TEST_P(Tests_MGCountSelfLoopsAndMultiEdges_Rmat, CheckInt32Int64FloatTransposeFalse) -{ - auto param = GetParam(); - run_current_test( - std::get<0>(param), override_Rmat_Usecase_with_cmd_line_arguments(std::get<1>(param))); -} - TEST_P(Tests_MGCountSelfLoopsAndMultiEdges_Rmat, CheckInt64Int64FloatTransposeFalse) { auto param = GetParam(); diff --git a/cpp/tests/structure/mg_has_edge_and_compute_multiplicity_test.cpp b/cpp/tests/structure/mg_has_edge_and_compute_multiplicity_test.cpp index b8ad06dd18b..9da8dfeb595 100644 --- a/cpp/tests/structure/mg_has_edge_and_compute_multiplicity_test.cpp +++ b/cpp/tests/structure/mg_has_edge_and_compute_multiplicity_test.cpp @@ -278,13 +278,6 @@ TEST_P(Tests_MGHasEdgeAndComputeMultiplicity_Rmat, CheckInt32Int32FloatTranspose std::get<0>(param), override_Rmat_Usecase_with_cmd_line_arguments(std::get<1>(param))); } -TEST_P(Tests_MGHasEdgeAndComputeMultiplicity_Rmat, CheckInt32Int64FloatTransposeFalse) -{ - auto param = GetParam(); - run_current_test( - std::get<0>(param), override_Rmat_Usecase_with_cmd_line_arguments(std::get<1>(param))); -} - TEST_P(Tests_MGHasEdgeAndComputeMultiplicity_Rmat, CheckInt64Int64FloatTransposeFalse) { auto param = GetParam(); diff --git a/cpp/tests/structure/mg_induced_subgraph_test.cu b/cpp/tests/structure/mg_induced_subgraph_test.cu index fd636e8c4c9..2958686c945 100644 --- a/cpp/tests/structure/mg_induced_subgraph_test.cu +++ b/cpp/tests/structure/mg_induced_subgraph_test.cu @@ -288,12 +288,6 @@ TEST_P(Tests_MGInducedSubgraph_Rmat, CheckInt32Int32) override_Rmat_Usecase_with_cmd_line_arguments(GetParam())); } -TEST_P(Tests_MGInducedSubgraph_Rmat, CheckInt32Int64) -{ - run_current_test( - override_Rmat_Usecase_with_cmd_line_arguments(GetParam())); -} - TEST_P(Tests_MGInducedSubgraph_Rmat, CheckInt64Int64) { run_current_test( diff --git a/cpp/tests/structure/mg_select_random_vertices_test.cpp b/cpp/tests/structure/mg_select_random_vertices_test.cpp index a33e2ca1813..d59bb8e0f63 100644 --- a/cpp/tests/structure/mg_select_random_vertices_test.cpp +++ b/cpp/tests/structure/mg_select_random_vertices_test.cpp @@ -225,12 +225,6 @@ TEST_P(Tests_MGSelectRandomVertices_Rmat, CheckInt32Int32FloatFloat) override_Rmat_Usecase_with_cmd_line_arguments(GetParam())); } -TEST_P(Tests_MGSelectRandomVertices_Rmat, CheckInt32Int64FloatFloat) -{ - run_current_test( - override_Rmat_Usecase_with_cmd_line_arguments(GetParam())); -} - TEST_P(Tests_MGSelectRandomVertices_Rmat, CheckInt64Int64FloatFloat) { run_current_test( diff --git a/cpp/tests/structure/mg_symmetrize_test.cpp b/cpp/tests/structure/mg_symmetrize_test.cpp index 7d83b482ccf..ebdec278db1 100644 --- a/cpp/tests/structure/mg_symmetrize_test.cpp +++ b/cpp/tests/structure/mg_symmetrize_test.cpp @@ -262,20 +262,6 @@ TEST_P(Tests_MGSymmetrize_Rmat, CheckInt32Int32FloatTransposedTrue) std::get<0>(param), override_Rmat_Usecase_with_cmd_line_arguments(std::get<1>(param))); } -TEST_P(Tests_MGSymmetrize_Rmat, CheckInt32Int64FloatTransposedFalse) -{ - auto param = GetParam(); - run_current_test( - std::get<0>(param), override_Rmat_Usecase_with_cmd_line_arguments(std::get<1>(param))); -} - -TEST_P(Tests_MGSymmetrize_Rmat, CheckInt32Int64FloatTransposedTrue) -{ - auto param = GetParam(); - run_current_test( - std::get<0>(param), override_Rmat_Usecase_with_cmd_line_arguments(std::get<1>(param))); -} - TEST_P(Tests_MGSymmetrize_Rmat, CheckInt64Int64FloatTransposedFalse) { auto param = GetParam(); diff --git a/cpp/tests/structure/mg_transpose_storage_test.cpp b/cpp/tests/structure/mg_transpose_storage_test.cpp index c43561a4251..41c50b396fb 100644 --- a/cpp/tests/structure/mg_transpose_storage_test.cpp +++ b/cpp/tests/structure/mg_transpose_storage_test.cpp @@ -261,20 +261,6 @@ TEST_P(Tests_MGTransposeStorage_Rmat, CheckInt32Int32FloatTransposeStoragedTrue) std::get<0>(param), override_Rmat_Usecase_with_cmd_line_arguments(std::get<1>(param))); } -TEST_P(Tests_MGTransposeStorage_Rmat, CheckInt32Int64FloatTransposeStoragedFalse) -{ - auto param = GetParam(); - run_current_test( - std::get<0>(param), override_Rmat_Usecase_with_cmd_line_arguments(std::get<1>(param))); -} - -TEST_P(Tests_MGTransposeStorage_Rmat, CheckInt32Int64FloatTransposeStoragedTrue) -{ - auto param = GetParam(); - run_current_test( - std::get<0>(param), override_Rmat_Usecase_with_cmd_line_arguments(std::get<1>(param))); -} - TEST_P(Tests_MGTransposeStorage_Rmat, CheckInt64Int64FloatTransposeStoragedFalse) { auto param = GetParam(); diff --git a/cpp/tests/structure/mg_transpose_test.cpp b/cpp/tests/structure/mg_transpose_test.cpp index a1a816e6f4b..28f5c000d3d 100644 --- a/cpp/tests/structure/mg_transpose_test.cpp +++ b/cpp/tests/structure/mg_transpose_test.cpp @@ -257,20 +257,6 @@ TEST_P(Tests_MGTranspose_Rmat, CheckInt32Int32FloatTransposedTrue) std::get<0>(param), override_Rmat_Usecase_with_cmd_line_arguments(std::get<1>(param))); } -TEST_P(Tests_MGTranspose_Rmat, CheckInt32Int64FloatTransposedFalse) -{ - auto param = GetParam(); - run_current_test( - std::get<0>(param), override_Rmat_Usecase_with_cmd_line_arguments(std::get<1>(param))); -} - -TEST_P(Tests_MGTranspose_Rmat, CheckInt32Int64FloatTransposedTrue) -{ - auto param = GetParam(); - run_current_test( - std::get<0>(param), override_Rmat_Usecase_with_cmd_line_arguments(std::get<1>(param))); -} - TEST_P(Tests_MGTranspose_Rmat, CheckInt64Int64FloatTransposedFalse) { auto param = GetParam(); diff --git a/cpp/tests/structure/symmetrize_test.cpp b/cpp/tests/structure/symmetrize_test.cpp index bf5e28e472f..5c9d76df117 100644 --- a/cpp/tests/structure/symmetrize_test.cpp +++ b/cpp/tests/structure/symmetrize_test.cpp @@ -434,20 +434,6 @@ TEST_P(Tests_Symmetrize_Rmat, CheckInt32Int32FloatTransposeTrue) std::get<0>(param), override_Rmat_Usecase_with_cmd_line_arguments(std::get<1>(param))); } -TEST_P(Tests_Symmetrize_Rmat, CheckInt32Int64FloatTransposeFalse) -{ - auto param = GetParam(); - run_current_test( - std::get<0>(param), override_Rmat_Usecase_with_cmd_line_arguments(std::get<1>(param))); -} - -TEST_P(Tests_Symmetrize_Rmat, CheckInt32Int64FloatTransposeTrue) -{ - auto param = GetParam(); - run_current_test( - std::get<0>(param), override_Rmat_Usecase_with_cmd_line_arguments(std::get<1>(param))); -} - TEST_P(Tests_Symmetrize_Rmat, CheckInt64Int64FloatTransposeFalse) { auto param = GetParam(); diff --git a/cpp/tests/structure/transpose_storage_test.cpp b/cpp/tests/structure/transpose_storage_test.cpp index d14f975b382..86c58fbe6b8 100644 --- a/cpp/tests/structure/transpose_storage_test.cpp +++ b/cpp/tests/structure/transpose_storage_test.cpp @@ -214,20 +214,6 @@ TEST_P(Tests_TransposeStorage_Rmat, CheckInt32Int32FloatTransposeTrue) std::get<0>(param), override_Rmat_Usecase_with_cmd_line_arguments(std::get<1>(param))); } -TEST_P(Tests_TransposeStorage_Rmat, CheckInt32Int64FloatTransposeFalse) -{ - auto param = GetParam(); - run_current_test( - std::get<0>(param), override_Rmat_Usecase_with_cmd_line_arguments(std::get<1>(param))); -} - -TEST_P(Tests_TransposeStorage_Rmat, CheckInt32Int64FloatTransposeTrue) -{ - auto param = GetParam(); - run_current_test( - std::get<0>(param), override_Rmat_Usecase_with_cmd_line_arguments(std::get<1>(param))); -} - TEST_P(Tests_TransposeStorage_Rmat, CheckInt64Int64FloatTransposeFalse) { auto param = GetParam(); diff --git a/cpp/tests/structure/transpose_test.cpp b/cpp/tests/structure/transpose_test.cpp index 4b666d72814..e8c3b31f932 100644 --- a/cpp/tests/structure/transpose_test.cpp +++ b/cpp/tests/structure/transpose_test.cpp @@ -198,20 +198,6 @@ TEST_P(Tests_Transpose_Rmat, CheckInt32Int32FloatTransposeTrue) std::get<0>(param), override_Rmat_Usecase_with_cmd_line_arguments(std::get<1>(param))); } -TEST_P(Tests_Transpose_Rmat, CheckInt32Int64FloatTransposeFalse) -{ - auto param = GetParam(); - run_current_test( - std::get<0>(param), override_Rmat_Usecase_with_cmd_line_arguments(std::get<1>(param))); -} - -TEST_P(Tests_Transpose_Rmat, CheckInt32Int64FloatTransposeTrue) -{ - auto param = GetParam(); - run_current_test( - std::get<0>(param), override_Rmat_Usecase_with_cmd_line_arguments(std::get<1>(param))); -} - TEST_P(Tests_Transpose_Rmat, CheckInt64Int64FloatTransposeFalse) { auto param = GetParam(); diff --git a/cpp/tests/structure/weight_sum_test.cpp b/cpp/tests/structure/weight_sum_test.cpp index 6f600e69431..5affd93073b 100644 --- a/cpp/tests/structure/weight_sum_test.cpp +++ b/cpp/tests/structure/weight_sum_test.cpp @@ -217,18 +217,6 @@ TEST_P(Tests_WeightSum_Rmat, CheckInt32Int32FloatTransposeTrue) run_current_test(std::get<0>(param), std::get<1>(param)); } -TEST_P(Tests_WeightSum_Rmat, CheckInt32Int64FloatTransposeFalse) -{ - auto param = override_Rmat_Usecase_with_cmd_line_arguments(GetParam()); - run_current_test(std::get<0>(param), std::get<1>(param)); -} - -TEST_P(Tests_WeightSum_Rmat, CheckInt32Int64FloatTransposeTrue) -{ - auto param = override_Rmat_Usecase_with_cmd_line_arguments(GetParam()); - run_current_test(std::get<0>(param), std::get<1>(param)); -} - TEST_P(Tests_WeightSum_Rmat, CheckInt64Int64FloatTransposeFalse) { auto param = override_Rmat_Usecase_with_cmd_line_arguments(GetParam()); diff --git a/cpp/tests/traversal/bfs_test.cpp b/cpp/tests/traversal/bfs_test.cpp index c5041378d78..b17b9aee66b 100644 --- a/cpp/tests/traversal/bfs_test.cpp +++ b/cpp/tests/traversal/bfs_test.cpp @@ -275,13 +275,6 @@ TEST_P(Tests_BFS_Rmat, CheckInt32Int32) std::get<0>(param), override_Rmat_Usecase_with_cmd_line_arguments(std::get<1>(param))); } -TEST_P(Tests_BFS_Rmat, CheckInt32Int64) -{ - auto param = GetParam(); - run_current_test( - std::get<0>(param), override_Rmat_Usecase_with_cmd_line_arguments(std::get<1>(param))); -} - TEST_P(Tests_BFS_Rmat, CheckInt64Int64) { auto param = GetParam(); diff --git a/cpp/tests/traversal/extract_bfs_paths_test.cu b/cpp/tests/traversal/extract_bfs_paths_test.cu index 89f87503494..62b654df233 100644 --- a/cpp/tests/traversal/extract_bfs_paths_test.cu +++ b/cpp/tests/traversal/extract_bfs_paths_test.cu @@ -215,13 +215,6 @@ TEST_P(Tests_ExtractBfsPaths_Rmat, CheckInt32Int32) std::get<0>(param), override_Rmat_Usecase_with_cmd_line_arguments(std::get<1>(param))); } -TEST_P(Tests_ExtractBfsPaths_Rmat, CheckInt32Int64) -{ - auto param = GetParam(); - run_current_test( - std::get<0>(param), override_Rmat_Usecase_with_cmd_line_arguments(std::get<1>(param))); -} - TEST_P(Tests_ExtractBfsPaths_Rmat, CheckInt64Int64) { auto param = GetParam(); diff --git a/cpp/tests/traversal/k_hop_nbrs_test.cpp b/cpp/tests/traversal/k_hop_nbrs_test.cpp index e385f05b0c7..326921552db 100644 --- a/cpp/tests/traversal/k_hop_nbrs_test.cpp +++ b/cpp/tests/traversal/k_hop_nbrs_test.cpp @@ -256,13 +256,6 @@ TEST_P(Tests_KHopNbrs_Rmat, CheckInt32Int32) std::get<0>(param), override_Rmat_Usecase_with_cmd_line_arguments(std::get<1>(param))); } -TEST_P(Tests_KHopNbrs_Rmat, CheckInt32Int64) -{ - auto param = GetParam(); - run_current_test( - std::get<0>(param), override_Rmat_Usecase_with_cmd_line_arguments(std::get<1>(param))); -} - TEST_P(Tests_KHopNbrs_Rmat, CheckInt64Int64) { auto param = GetParam(); diff --git a/cpp/tests/traversal/mg_bfs_test.cpp b/cpp/tests/traversal/mg_bfs_test.cpp index c294c6d0091..4d4b83e275b 100644 --- a/cpp/tests/traversal/mg_bfs_test.cpp +++ b/cpp/tests/traversal/mg_bfs_test.cpp @@ -294,13 +294,6 @@ TEST_P(Tests_MGBFS_Rmat, CheckInt32Int32) std::get<0>(param), override_Rmat_Usecase_with_cmd_line_arguments(std::get<1>(param))); } -TEST_P(Tests_MGBFS_Rmat, CheckInt32Int64) -{ - auto param = GetParam(); - run_current_test( - std::get<0>(param), override_Rmat_Usecase_with_cmd_line_arguments(std::get<1>(param))); -} - TEST_P(Tests_MGBFS_Rmat, CheckInt64Int64) { auto param = GetParam(); diff --git a/cpp/tests/traversal/mg_extract_bfs_paths_test.cu b/cpp/tests/traversal/mg_extract_bfs_paths_test.cu index 476a6ffab8f..1ef5c282c1c 100644 --- a/cpp/tests/traversal/mg_extract_bfs_paths_test.cu +++ b/cpp/tests/traversal/mg_extract_bfs_paths_test.cu @@ -298,13 +298,6 @@ TEST_P(Tests_MGExtractBFSPaths_Rmat, CheckInt32Int32) std::get<0>(param), override_Rmat_Usecase_with_cmd_line_arguments(std::get<1>(param))); } -TEST_P(Tests_MGExtractBFSPaths_Rmat, CheckInt32Int64) -{ - auto param = GetParam(); - run_current_test( - std::get<0>(param), override_Rmat_Usecase_with_cmd_line_arguments(std::get<1>(param))); -} - TEST_P(Tests_MGExtractBFSPaths_Rmat, CheckInt64Int64) { auto param = GetParam(); diff --git a/cpp/tests/traversal/mg_k_hop_nbrs_test.cpp b/cpp/tests/traversal/mg_k_hop_nbrs_test.cpp index 311d1f55b9c..4e4b7d38ccd 100644 --- a/cpp/tests/traversal/mg_k_hop_nbrs_test.cpp +++ b/cpp/tests/traversal/mg_k_hop_nbrs_test.cpp @@ -254,13 +254,6 @@ TEST_P(Tests_MGKHopNbrs_Rmat, CheckInt32Int32) std::get<0>(param), override_Rmat_Usecase_with_cmd_line_arguments(std::get<1>(param))); } -TEST_P(Tests_MGKHopNbrs_Rmat, CheckInt32Int64) -{ - auto param = GetParam(); - run_current_test( - std::get<0>(param), override_Rmat_Usecase_with_cmd_line_arguments(std::get<1>(param))); -} - TEST_P(Tests_MGKHopNbrs_Rmat, CheckInt64Int64) { auto param = GetParam(); diff --git a/cpp/tests/traversal/mg_sssp_test.cpp b/cpp/tests/traversal/mg_sssp_test.cpp index 9ad16d1c947..bc3f5870f6c 100644 --- a/cpp/tests/traversal/mg_sssp_test.cpp +++ b/cpp/tests/traversal/mg_sssp_test.cpp @@ -285,13 +285,6 @@ TEST_P(Tests_MGSSSP_Rmat, CheckInt32Int32Float) std::get<0>(param), override_Rmat_Usecase_with_cmd_line_arguments(std::get<1>(param))); } -TEST_P(Tests_MGSSSP_Rmat, CheckInt32Int64Float) -{ - auto param = GetParam(); - run_current_test( - std::get<0>(param), override_Rmat_Usecase_with_cmd_line_arguments(std::get<1>(param))); -} - TEST_P(Tests_MGSSSP_Rmat, CheckInt64Int64Float) { auto param = GetParam(); diff --git a/cpp/tests/traversal/od_shortest_distances_test.cpp b/cpp/tests/traversal/od_shortest_distances_test.cpp index fe9fe99e784..aba85e2b425 100644 --- a/cpp/tests/traversal/od_shortest_distances_test.cpp +++ b/cpp/tests/traversal/od_shortest_distances_test.cpp @@ -235,13 +235,6 @@ TEST_P(Tests_ODShortestDistances_Rmat, CheckInt32Int32Float) std::get<0>(param), override_Rmat_Usecase_with_cmd_line_arguments(std::get<1>(param))); } -TEST_P(Tests_ODShortestDistances_Rmat, CheckInt32Int64Float) -{ - auto param = GetParam(); - run_current_test( - std::get<0>(param), override_Rmat_Usecase_with_cmd_line_arguments(std::get<1>(param))); -} - TEST_P(Tests_ODShortestDistances_Rmat, CheckInt64Int64Float) { auto param = GetParam(); diff --git a/cpp/tests/traversal/sssp_test.cpp b/cpp/tests/traversal/sssp_test.cpp index 3eff1a8e106..9180ec94da5 100644 --- a/cpp/tests/traversal/sssp_test.cpp +++ b/cpp/tests/traversal/sssp_test.cpp @@ -271,13 +271,6 @@ TEST_P(Tests_SSSP_Rmat, CheckInt32Int32Float) std::get<0>(param), override_Rmat_Usecase_with_cmd_line_arguments(std::get<1>(param))); } -TEST_P(Tests_SSSP_Rmat, CheckInt32Int64Float) -{ - auto param = GetParam(); - run_current_test( - std::get<0>(param), override_Rmat_Usecase_with_cmd_line_arguments(std::get<1>(param))); -} - TEST_P(Tests_SSSP_Rmat, CheckInt64Int64Float) { auto param = GetParam(); diff --git a/cpp/tests/utilities/conversion_utilities_mg.cu b/cpp/tests/utilities/conversion_utilities_mg.cu index cb4703ec89b..6c5db5b6c57 100644 --- a/cpp/tests/utilities/conversion_utilities_mg.cu +++ b/cpp/tests/utilities/conversion_utilities_mg.cu @@ -25,13 +25,6 @@ graph_to_host_coo( std::optional> edge_weight_view, std::optional> renumber_map); -template std::tuple, std::vector, std::optional>> -graph_to_host_coo( - raft::handle_t const& handle, - cugraph::graph_view_t const& graph_view, - std::optional> edge_weight_view, - std::optional> renumber_map); - template std::tuple, std::vector, std::optional>> graph_to_host_coo( raft::handle_t const& handle, @@ -46,13 +39,6 @@ graph_to_host_coo( std::optional> edge_weight_view, std::optional> renumber_map); -template std::tuple, std::vector, std::optional>> -graph_to_host_coo( - raft::handle_t const& handle, - cugraph::graph_view_t const& graph_view, - std::optional> edge_weight_view, - std::optional> renumber_map); - template std::tuple, std::vector, std::optional>> graph_to_host_coo( raft::handle_t const& handle, @@ -67,13 +53,6 @@ graph_to_host_coo( std::optional> edge_weight_view, std::optional> renumber_map); -template std::tuple, std::vector, std::optional>> -graph_to_host_coo( - raft::handle_t const& handle, - cugraph::graph_view_t const& graph_view, - std::optional> edge_weight_view, - std::optional> renumber_map); - template std::tuple, std::vector, std::optional>> graph_to_host_coo( raft::handle_t const& handle, @@ -88,13 +67,6 @@ graph_to_host_coo( std::optional> edge_weight_view, std::optional> renumber_map); -template std::tuple, std::vector, std::optional>> -graph_to_host_coo( - raft::handle_t const& handle, - cugraph::graph_view_t const& graph_view, - std::optional> edge_weight_view, - std::optional> renumber_map); - template std::tuple, std::vector, std::optional>> graph_to_host_coo( raft::handle_t const& handle, @@ -111,15 +83,6 @@ graph_to_device_coo( std::optional> edge_weight_view, std::optional> renumber_map); -template std::tuple, - rmm::device_uvector, - std::optional>> -graph_to_device_coo( - raft::handle_t const& handle, - cugraph::graph_view_t const& graph_view, - std::optional> edge_weight_view, - std::optional> renumber_map); - template std::tuple, rmm::device_uvector, std::optional>> @@ -138,15 +101,6 @@ graph_to_device_coo( std::optional> edge_weight_view, std::optional> renumber_map); -template std::tuple, - rmm::device_uvector, - std::optional>> -graph_to_device_coo( - raft::handle_t const& handle, - cugraph::graph_view_t const& graph_view, - std::optional> edge_weight_view, - std::optional> renumber_map); - template std::tuple, rmm::device_uvector, std::optional>> @@ -165,15 +119,6 @@ graph_to_device_coo( std::optional> edge_weight_view, std::optional> renumber_map); -template std::tuple, - rmm::device_uvector, - std::optional>> -graph_to_device_coo( - raft::handle_t const& handle, - cugraph::graph_view_t const& graph_view, - std::optional> edge_weight_view, - std::optional> renumber_map); - template std::tuple, rmm::device_uvector, std::optional>> @@ -192,15 +137,6 @@ graph_to_device_coo( std::optional> edge_weight_view, std::optional> renumber_map); -template std::tuple, - rmm::device_uvector, - std::optional>> -graph_to_device_coo( - raft::handle_t const& handle, - cugraph::graph_view_t const& graph_view, - std::optional> edge_weight_view, - std::optional> renumber_map); - template std::tuple, rmm::device_uvector, std::optional>> @@ -217,13 +153,6 @@ graph_to_host_csr( std::optional> edge_weight_view, std::optional> renumber_map); -template std::tuple, std::vector, std::optional>> -graph_to_host_csr( - raft::handle_t const& handle, - cugraph::graph_view_t const& graph_view, - std::optional> edge_weight_view, - std::optional> renumber_map); - template std::tuple, std::vector, std::optional>> graph_to_host_csr( raft::handle_t const& handle, @@ -238,13 +167,6 @@ graph_to_host_csr( std::optional> edge_weight_view, std::optional> renumber_map); -template std::tuple, std::vector, std::optional>> -graph_to_host_csr( - raft::handle_t const& handle, - cugraph::graph_view_t const& graph_view, - std::optional> edge_weight_view, - std::optional> renumber_map); - template std::tuple, std::vector, std::optional>> graph_to_host_csr( raft::handle_t const& handle, @@ -259,13 +181,6 @@ graph_to_host_csr( std::optional> edge_weight_view, std::optional> renumber_map); -template std::tuple, std::vector, std::optional>> -graph_to_host_csr( - raft::handle_t const& handle, - cugraph::graph_view_t const& graph_view, - std::optional> edge_weight_view, - std::optional> renumber_map); - template std::tuple, std::vector, std::optional>> graph_to_host_csr( raft::handle_t const& handle, @@ -280,13 +195,6 @@ graph_to_host_csr( std::optional> edge_weight_view, std::optional> renumber_map); -template std::tuple, std::vector, std::optional>> -graph_to_host_csr( - raft::handle_t const& handle, - cugraph::graph_view_t const& graph_view, - std::optional> edge_weight_view, - std::optional> renumber_map); - template std::tuple, std::vector, std::optional>> graph_to_host_csr( raft::handle_t const& handle, @@ -301,13 +209,6 @@ graph_to_host_csc( std::optional> edge_weight_view, std::optional> renumber_map); -template std::tuple, std::vector, std::optional>> -graph_to_host_csc( - raft::handle_t const& handle, - cugraph::graph_view_t const& graph_view, - std::optional> edge_weight_view, - std::optional> renumber_map); - template std::tuple, std::vector, std::optional>> graph_to_host_csc( raft::handle_t const& handle, @@ -322,13 +223,6 @@ graph_to_host_csc( std::optional> edge_weight_view, std::optional> renumber_map); -template std::tuple, std::vector, std::optional>> -graph_to_host_csc( - raft::handle_t const& handle, - cugraph::graph_view_t const& graph_view, - std::optional> edge_weight_view, - std::optional> renumber_map); - template std::tuple, std::vector, std::optional>> graph_to_host_csc( raft::handle_t const& handle, @@ -343,13 +237,6 @@ graph_to_host_csc( std::optional> edge_weight_view, std::optional> renumber_map); -template std::tuple, std::vector, std::optional>> -graph_to_host_csc( - raft::handle_t const& handle, - cugraph::graph_view_t const& graph_view, - std::optional> edge_weight_view, - std::optional> renumber_map); - template std::tuple, std::vector, std::optional>> graph_to_host_csc( raft::handle_t const& handle, @@ -364,13 +251,6 @@ graph_to_host_csc( std::optional> edge_weight_view, std::optional> renumber_map); -template std::tuple, std::vector, std::optional>> -graph_to_host_csc( - raft::handle_t const& handle, - cugraph::graph_view_t const& graph_view, - std::optional> edge_weight_view, - std::optional> renumber_map); - template std::tuple, std::vector, std::optional>> graph_to_host_csc( raft::handle_t const& handle, @@ -391,19 +271,6 @@ mg_graph_to_sg_graph( std::optional> renumber_map, bool renumber); -template std::tuple< - cugraph::graph_t, - std::optional, float>>, - std::optional, int64_t>>, - std::optional>> -mg_graph_to_sg_graph( - raft::handle_t const& handle, - cugraph::graph_view_t const& graph_view, - std::optional> edge_weight_view, - std::optional> edge_id_view, - std::optional> renumber_map, - bool renumber); - template std::tuple< cugraph::graph_t, std::optional, float>>, @@ -430,19 +297,6 @@ mg_graph_to_sg_graph( std::optional> renumber_map, bool renumber); -template std::tuple< - cugraph::graph_t, - std::optional, double>>, - std::optional, int64_t>>, - std::optional>> -mg_graph_to_sg_graph( - raft::handle_t const& handle, - cugraph::graph_view_t const& graph_view, - std::optional> edge_weight_view, - std::optional> edge_id_view, - std::optional> renumber_map, - bool renumber); - template std::tuple< cugraph::graph_t, std::optional, double>>, @@ -469,19 +323,6 @@ mg_graph_to_sg_graph( std::optional> renumber_map, bool renumber); -template std::tuple< - cugraph::graph_t, - std::optional, float>>, - std::optional, int64_t>>, - std::optional>> -mg_graph_to_sg_graph( - raft::handle_t const& handle, - cugraph::graph_view_t const& graph_view, - std::optional> edge_weight_view, - std::optional> edge_id_view, - std::optional> renumber_map, - bool renumber); - template std::tuple< cugraph::graph_t, std::optional, float>>, @@ -508,19 +349,6 @@ mg_graph_to_sg_graph( std::optional> renumber_map, bool renumber); -template std::tuple< - cugraph::graph_t, - std::optional, double>>, - std::optional, int64_t>>, - std::optional>> -mg_graph_to_sg_graph( - raft::handle_t const& handle, - cugraph::graph_view_t const& graph_view, - std::optional> edge_weight_view, - std::optional> edge_id_view, - std::optional> renumber_map, - bool renumber); - template std::tuple< cugraph::graph_t, std::optional, double>>, diff --git a/cpp/tests/utilities/conversion_utilities_sg.cu b/cpp/tests/utilities/conversion_utilities_sg.cu index 450594807d1..c97881b895a 100644 --- a/cpp/tests/utilities/conversion_utilities_sg.cu +++ b/cpp/tests/utilities/conversion_utilities_sg.cu @@ -25,13 +25,6 @@ graph_to_host_coo( std::optional> edge_weight_view, std::optional> renumber_map); -template std::tuple, std::vector, std::optional>> -graph_to_host_coo( - raft::handle_t const& handle, - cugraph::graph_view_t const& graph_view, - std::optional> edge_weight_view, - std::optional> renumber_map); - template std::tuple, std::vector, std::optional>> graph_to_host_coo( raft::handle_t const& handle, @@ -46,13 +39,6 @@ graph_to_host_coo( std::optional> edge_weight_view, std::optional> renumber_map); -template std::tuple, std::vector, std::optional>> -graph_to_host_coo( - raft::handle_t const& handle, - cugraph::graph_view_t const& graph_view, - std::optional> edge_weight_view, - std::optional> renumber_map); - template std::tuple, std::vector, std::optional>> graph_to_host_coo( raft::handle_t const& handle, @@ -67,13 +53,6 @@ graph_to_host_coo( std::optional> edge_weight_view, std::optional> renumber_map); -template std::tuple, std::vector, std::optional>> -graph_to_host_coo( - raft::handle_t const& handle, - cugraph::graph_view_t const& graph_view, - std::optional> edge_weight_view, - std::optional> renumber_map); - template std::tuple, std::vector, std::optional>> graph_to_host_coo( raft::handle_t const& handle, @@ -88,13 +67,6 @@ graph_to_host_coo( std::optional> edge_weight_view, std::optional> renumber_map); -template std::tuple, std::vector, std::optional>> -graph_to_host_coo( - raft::handle_t const& handle, - cugraph::graph_view_t const& graph_view, - std::optional> edge_weight_view, - std::optional> renumber_map); - template std::tuple, std::vector, std::optional>> graph_to_host_coo( raft::handle_t const& handle, @@ -111,15 +83,6 @@ graph_to_device_coo( std::optional> edge_weight_view, std::optional> renumber_map); -template std::tuple, - rmm::device_uvector, - std::optional>> -graph_to_device_coo( - raft::handle_t const& handle, - cugraph::graph_view_t const& graph_view, - std::optional> edge_weight_view, - std::optional> renumber_map); - template std::tuple, rmm::device_uvector, std::optional>> @@ -138,15 +101,6 @@ graph_to_device_coo( std::optional> edge_weight_view, std::optional> renumber_map); -template std::tuple, - rmm::device_uvector, - std::optional>> -graph_to_device_coo( - raft::handle_t const& handle, - cugraph::graph_view_t const& graph_view, - std::optional> edge_weight_view, - std::optional> renumber_map); - template std::tuple, rmm::device_uvector, std::optional>> @@ -165,15 +119,6 @@ graph_to_device_coo( std::optional> edge_weight_view, std::optional> renumber_map); -template std::tuple, - rmm::device_uvector, - std::optional>> -graph_to_device_coo( - raft::handle_t const& handle, - cugraph::graph_view_t const& graph_view, - std::optional> edge_weight_view, - std::optional> renumber_map); - template std::tuple, rmm::device_uvector, std::optional>> @@ -192,15 +137,6 @@ graph_to_device_coo( std::optional> edge_weight_view, std::optional> renumber_map); -template std::tuple, - rmm::device_uvector, - std::optional>> -graph_to_device_coo( - raft::handle_t const& handle, - cugraph::graph_view_t const& graph_view, - std::optional> edge_weight_view, - std::optional> renumber_map); - template std::tuple, rmm::device_uvector, std::optional>> @@ -217,13 +153,6 @@ graph_to_host_csr( std::optional> edge_weight_view, std::optional> renumber_map); -template std::tuple, std::vector, std::optional>> -graph_to_host_csr( - raft::handle_t const& handle, - cugraph::graph_view_t const& graph_view, - std::optional> edge_weight_view, - std::optional> renumber_map); - template std::tuple, std::vector, std::optional>> graph_to_host_csr( raft::handle_t const& handle, @@ -238,13 +167,6 @@ graph_to_host_csr( std::optional> edge_weight_view, std::optional> renumber_map); -template std::tuple, std::vector, std::optional>> -graph_to_host_csr( - raft::handle_t const& handle, - cugraph::graph_view_t const& graph_view, - std::optional> edge_weight_view, - std::optional> renumber_map); - template std::tuple, std::vector, std::optional>> graph_to_host_csr( raft::handle_t const& handle, @@ -259,13 +181,6 @@ graph_to_host_csr( std::optional> edge_weight_view, std::optional> renumber_map); -template std::tuple, std::vector, std::optional>> -graph_to_host_csr( - raft::handle_t const& handle, - cugraph::graph_view_t const& graph_view, - std::optional> edge_weight_view, - std::optional> renumber_map); - template std::tuple, std::vector, std::optional>> graph_to_host_csr( raft::handle_t const& handle, @@ -280,13 +195,6 @@ graph_to_host_csr( std::optional> edge_weight_view, std::optional> renumber_map); -template std::tuple, std::vector, std::optional>> -graph_to_host_csr( - raft::handle_t const& handle, - cugraph::graph_view_t const& graph_view, - std::optional> edge_weight_view, - std::optional> renumber_map); - template std::tuple, std::vector, std::optional>> graph_to_host_csr( raft::handle_t const& handle, @@ -301,13 +209,6 @@ graph_to_host_csc( std::optional> edge_weight_view, std::optional> renumber_map); -template std::tuple, std::vector, std::optional>> -graph_to_host_csc( - raft::handle_t const& handle, - cugraph::graph_view_t const& graph_view, - std::optional> edge_weight_view, - std::optional> renumber_map); - template std::tuple, std::vector, std::optional>> graph_to_host_csc( raft::handle_t const& handle, @@ -322,13 +223,6 @@ graph_to_host_csc( std::optional> edge_weight_view, std::optional> renumber_map); -template std::tuple, std::vector, std::optional>> -graph_to_host_csc( - raft::handle_t const& handle, - cugraph::graph_view_t const& graph_view, - std::optional> edge_weight_view, - std::optional> renumber_map); - template std::tuple, std::vector, std::optional>> graph_to_host_csc( raft::handle_t const& handle, @@ -343,13 +237,6 @@ graph_to_host_csc( std::optional> edge_weight_view, std::optional> renumber_map); -template std::tuple, std::vector, std::optional>> -graph_to_host_csc( - raft::handle_t const& handle, - cugraph::graph_view_t const& graph_view, - std::optional> edge_weight_view, - std::optional> renumber_map); - template std::tuple, std::vector, std::optional>> graph_to_host_csc( raft::handle_t const& handle, @@ -364,13 +251,6 @@ graph_to_host_csc( std::optional> edge_weight_view, std::optional> renumber_map); -template std::tuple, std::vector, std::optional>> -graph_to_host_csc( - raft::handle_t const& handle, - cugraph::graph_view_t const& graph_view, - std::optional> edge_weight_view, - std::optional> renumber_map); - template std::tuple, std::vector, std::optional>> graph_to_host_csc( raft::handle_t const& handle, diff --git a/cpp/tests/utilities/csv_file_utilities.cu b/cpp/tests/utilities/csv_file_utilities.cu index 08b1e37af8a..e7be9ff3133 100644 --- a/cpp/tests/utilities/csv_file_utilities.cu +++ b/cpp/tests/utilities/csv_file_utilities.cu @@ -406,86 +406,6 @@ read_graph_from_csv_file( bool test_weighted, bool renumber); -template std::tuple< - cugraph::graph_t, - std::optional, float>>, - std::optional>> -read_graph_from_csv_file( - raft::handle_t const& handle, - std::string const& graph_file_full_path, - bool test_weighted, - bool renumber); - -template std::tuple< - cugraph::graph_t, - std::optional, float>>, - std::optional>> -read_graph_from_csv_file( - raft::handle_t const& handle, - std::string const& graph_file_full_path, - bool test_weighted, - bool renumber); - -template std::tuple< - cugraph::graph_t, - std::optional, float>>, - std::optional>> -read_graph_from_csv_file( - raft::handle_t const& handle, - std::string const& graph_file_full_path, - bool test_weighted, - bool renumber); - -template std::tuple< - cugraph::graph_t, - std::optional, float>>, - std::optional>> -read_graph_from_csv_file( - raft::handle_t const& handle, - std::string const& graph_file_full_path, - bool test_weighted, - bool renumber); - -template std::tuple< - cugraph::graph_t, - std::optional, double>>, - std::optional>> -read_graph_from_csv_file( - raft::handle_t const& handle, - std::string const& graph_file_full_path, - bool test_weighted, - bool renumber); - -template std::tuple< - cugraph::graph_t, - std::optional, double>>, - std::optional>> -read_graph_from_csv_file( - raft::handle_t const& handle, - std::string const& graph_file_full_path, - bool test_weighted, - bool renumber); - -template std::tuple< - cugraph::graph_t, - std::optional, double>>, - std::optional>> -read_graph_from_csv_file( - raft::handle_t const& handle, - std::string const& graph_file_full_path, - bool test_weighted, - bool renumber); - -template std::tuple< - cugraph::graph_t, - std::optional, double>>, - std::optional>> -read_graph_from_csv_file( - raft::handle_t const& handle, - std::string const& graph_file_full_path, - bool test_weighted, - bool renumber); - template std::tuple< cugraph::graph_t, std::optional, float>>, diff --git a/cpp/tests/utilities/debug_utilities_mg.cpp b/cpp/tests/utilities/debug_utilities_mg.cpp index 3423189a8ad..e160976d648 100644 --- a/cpp/tests/utilities/debug_utilities_mg.cpp +++ b/cpp/tests/utilities/debug_utilities_mg.cpp @@ -30,18 +30,6 @@ template void print_edges( std::optional> edge_weight_view, std::optional> renumber_map); -template void print_edges( - raft::handle_t const& handle, - cugraph::graph_view_t const& graph_view, - std::optional> edge_weight_view, - std::optional> renumber_map); - -template void print_edges( - raft::handle_t const& handle, - cugraph::graph_view_t const& graph_view, - std::optional> edge_weight_view, - std::optional> renumber_map); - template void print_edges( raft::handle_t const& handle, cugraph::graph_view_t const& graph_view, diff --git a/cpp/tests/utilities/debug_utilities_sg.cpp b/cpp/tests/utilities/debug_utilities_sg.cpp index 622943b3c08..a5984c92397 100644 --- a/cpp/tests/utilities/debug_utilities_sg.cpp +++ b/cpp/tests/utilities/debug_utilities_sg.cpp @@ -30,18 +30,6 @@ template void print_edges( std::optional> edge_weight_view, std::optional> renumber_map); -template void print_edges( - raft::handle_t const& handle, - cugraph::graph_view_t const& graph_view, - std::optional> edge_weight_view, - std::optional> renumber_map); - -template void print_edges( - raft::handle_t const& handle, - cugraph::graph_view_t const& graph_view, - std::optional> edge_weight_view, - std::optional> renumber_map); - template void print_edges( raft::handle_t const& handle, cugraph::graph_view_t const& graph_view, diff --git a/cpp/tests/utilities/matrix_market_file_utilities.cu b/cpp/tests/utilities/matrix_market_file_utilities.cu index 302533113ee..1ca31a1ee6b 100644 --- a/cpp/tests/utilities/matrix_market_file_utilities.cu +++ b/cpp/tests/utilities/matrix_market_file_utilities.cu @@ -567,86 +567,6 @@ read_graph_from_matrix_market_file( bool test_weighted, bool renumber); -template std::tuple< - cugraph::graph_t, - std::optional, float>>, - std::optional>> -read_graph_from_matrix_market_file( - raft::handle_t const& handle, - std::string const& graph_file_full_path, - bool test_weighted, - bool renumber); - -template std::tuple< - cugraph::graph_t, - std::optional, float>>, - std::optional>> -read_graph_from_matrix_market_file( - raft::handle_t const& handle, - std::string const& graph_file_full_path, - bool test_weighted, - bool renumber); - -template std::tuple< - cugraph::graph_t, - std::optional, float>>, - std::optional>> -read_graph_from_matrix_market_file( - raft::handle_t const& handle, - std::string const& graph_file_full_path, - bool test_weighted, - bool renumber); - -template std::tuple< - cugraph::graph_t, - std::optional, float>>, - std::optional>> -read_graph_from_matrix_market_file( - raft::handle_t const& handle, - std::string const& graph_file_full_path, - bool test_weighted, - bool renumber); - -template std::tuple< - cugraph::graph_t, - std::optional, double>>, - std::optional>> -read_graph_from_matrix_market_file( - raft::handle_t const& handle, - std::string const& graph_file_full_path, - bool test_weighted, - bool renumber); - -template std::tuple< - cugraph::graph_t, - std::optional, double>>, - std::optional>> -read_graph_from_matrix_market_file( - raft::handle_t const& handle, - std::string const& graph_file_full_path, - bool test_weighted, - bool renumber); - -template std::tuple< - cugraph::graph_t, - std::optional, double>>, - std::optional>> -read_graph_from_matrix_market_file( - raft::handle_t const& handle, - std::string const& graph_file_full_path, - bool test_weighted, - bool renumber); - -template std::tuple< - cugraph::graph_t, - std::optional, double>>, - std::optional>> -read_graph_from_matrix_market_file( - raft::handle_t const& handle, - std::string const& graph_file_full_path, - bool test_weighted, - bool renumber); - template std::tuple< cugraph::graph_t, std::optional, float>>, diff --git a/cpp/tests/utilities/property_generator_kernels.cuh b/cpp/tests/utilities/property_generator_kernels.cuh index d8d5cc420fd..78b22e0dac2 100644 --- a/cpp/tests/utilities/property_generator_kernels.cuh +++ b/cpp/tests/utilities/property_generator_kernels.cuh @@ -60,7 +60,7 @@ struct vertex_property_transform { { static_assert(cugraph::is_thrust_tuple_of_arithmetic::value || std::is_arithmetic_v); - cuco::detail::MurmurHash3_32 hash_func{}; + cuco::murmurhash3_32 hash_func{}; return make_property_value(hash_func(v) % mod); } }; @@ -74,7 +74,7 @@ struct edge_property_transform { { static_assert(cugraph::is_thrust_tuple_of_arithmetic::value || std::is_arithmetic_v); - cuco::detail::MurmurHash3_32 hash_func{}; + cuco::murmurhash3_32 hash_func{}; return make_property_value(hash_func(src + dst) % mod); } }; diff --git a/cpp/tests/utilities/property_generator_utilities_mg.cu b/cpp/tests/utilities/property_generator_utilities_mg.cu index f283050dca8..cd208684bec 100644 --- a/cpp/tests/utilities/property_generator_utilities_mg.cu +++ b/cpp/tests/utilities/property_generator_utilities_mg.cu @@ -30,18 +30,6 @@ template struct generate, in template struct generate, thrust::tuple>; -template struct generate, bool>; -template struct generate, int32_t>; -template struct generate, int64_t>; -template struct generate, - thrust::tuple>; - -template struct generate, bool>; -template struct generate, int32_t>; -template struct generate, int64_t>; -template struct generate, - thrust::tuple>; - template struct generate, bool>; template struct generate, int32_t>; template struct generate, int64_t>; diff --git a/cpp/tests/utilities/property_generator_utilities_sg.cu b/cpp/tests/utilities/property_generator_utilities_sg.cu index dd1907a9f1d..e824dc2b5d2 100644 --- a/cpp/tests/utilities/property_generator_utilities_sg.cu +++ b/cpp/tests/utilities/property_generator_utilities_sg.cu @@ -30,18 +30,6 @@ template struct generate, i template struct generate, thrust::tuple>; -template struct generate, bool>; -template struct generate, int32_t>; -template struct generate, int64_t>; -template struct generate, - thrust::tuple>; - -template struct generate, bool>; -template struct generate, int32_t>; -template struct generate, int64_t>; -template struct generate, - thrust::tuple>; - template struct generate, bool>; template struct generate, int32_t>; template struct generate, int64_t>; diff --git a/dependencies.yaml b/dependencies.yaml index 2c8335868ba..a4143ff90c9 100644 --- a/dependencies.yaml +++ b/dependencies.yaml @@ -323,8 +323,7 @@ channels: - rapidsai - rapidsai-nightly - dask/label/dev - - pyg - - dglteam/label/cu118 + - dglteam/label/th23_cu118 - conda-forge - nvidia dependencies: @@ -426,12 +425,12 @@ dependencies: packages: - c-compiler - cxx-compiler - - libcudf==24.10.*,>=0.0.0a0 + - libcudf==24.12.*,>=0.0.0a0 # Deprecate libcugraphops - - libcugraphops==24.10.*,>=0.0.0a0 - - libraft-headers==24.10.*,>=0.0.0a0 - - libraft==24.10.*,>=0.0.0a0 - - librmm==24.10.*,>=0.0.0a0 + - libcugraphops==24.12.*,>=0.0.0a0 + - libraft-headers==24.12.*,>=0.0.0a0 + - libraft==24.12.*,>=0.0.0a0 + - librmm==24.12.*,>=0.0.0a0 - openmpi # Required for building cpp-mgtests (multi-GPU tests) specific: - output_types: [conda] @@ -521,18 +520,18 @@ dependencies: common: - output_types: [conda, pyproject] packages: - - &dask rapids-dask-dependency==24.10.*,>=0.0.0a0 - - &dask_cuda dask-cuda==24.10.*,>=0.0.0a0 + - &dask rapids-dask-dependency==24.12.*,>=0.0.0a0 + - &dask_cuda dask-cuda==24.12.*,>=0.0.0a0 - &numba numba>=0.57 - - &numpy numpy>=1.23,<2.0a0 + - &numpy numpy>=1.23,<3.0a0 - output_types: conda packages: - aiohttp - fsspec>=0.6.0 - requests - - nccl>=2.9.9 + - nccl>=2.19 - ucx-proc=*=gpu - - &ucx_py_unsuffixed ucx-py==0.40.*,>=0.0.0a0 + - &ucx_py_unsuffixed ucx-py==0.41.*,>=0.0.0a0 - output_types: pyproject packages: # cudf uses fsspec but is protocol independent. cugraph @@ -545,12 +544,12 @@ dependencies: cuda: "11.*" cuda_suffixed: "true" packages: - - &ucx_py_cu11 ucx-py-cu11==0.40.*,>=0.0.0a0 + - &ucx_py_cu11 ucx-py-cu11==0.41.*,>=0.0.0a0 - matrix: cuda: "12.*" cuda_suffixed: "true" packages: - - &ucx_py_cu12 ucx-py-cu12==0.40.*,>=0.0.0a0 + - &ucx_py_cu12 ucx-py-cu12==0.41.*,>=0.0.0a0 - matrix: packages: - *ucx_py_unsuffixed @@ -573,15 +572,15 @@ dependencies: cuda: "11.*" cuda_suffixed: "true" packages: - - &cugraph_cu11 cugraph-cu11==24.10.*,>=0.0.0a0 + - &cugraph_cu11 cugraph-cu11==24.12.*,>=0.0.0a0 - matrix: cuda: "12.*" cuda_suffixed: "true" packages: - - &cugraph_cu12 cugraph-cu12==24.10.*,>=0.0.0a0 + - &cugraph_cu12 cugraph-cu12==24.12.*,>=0.0.0a0 - matrix: packages: - - &cugraph_unsuffixed cugraph==24.10.*,>=0.0.0a0 + - &cugraph_unsuffixed cugraph==24.12.*,>=0.0.0a0 python_run_cugraph_pyg: common: - output_types: [conda, pyproject] @@ -629,19 +628,19 @@ dependencies: cuda_suffixed: "true" packages: - *cugraph_cu11 - - cugraph-service-client-cu11==24.10.*,>=0.0.0a0 + - cugraph-service-client-cu11==24.12.*,>=0.0.0a0 - *ucx_py_cu11 - matrix: cuda: "12.*" cuda_suffixed: "true" packages: - *cugraph_cu12 - - cugraph-service-client-cu12==24.10.*,>=0.0.0a0 + - cugraph-service-client-cu12==24.12.*,>=0.0.0a0 - *ucx_py_cu12 - matrix: packages: - *cugraph_unsuffixed - - cugraph-service-client==24.10.*,>=0.0.0a0 + - cugraph-service-client==24.12.*,>=0.0.0a0 - *ucx_py_unsuffixed test_cpp: common: @@ -677,7 +676,7 @@ dependencies: - scikit-learn>=0.23.1 - output_types: [conda] packages: - - &pylibwholegraph_unsuffixed pylibwholegraph==24.10.*,>=0.0.0a0 + - &pylibwholegraph_unsuffixed pylibwholegraph==24.12.*,>=0.0.0a0 - *thrift test_python_pylibcugraph: common: @@ -688,7 +687,6 @@ dependencies: common: - output_types: [conda, pyproject] packages: - - packaging>=21 # not needed by nx-cugraph tests, but is required for running networkx tests - pytest-mpl cugraph_dgl_dev: @@ -696,25 +694,27 @@ dependencies: - output_types: [conda] packages: - *cugraph_unsuffixed - - pytorch>=2.0 + # ceiling could be removed when this is fixed: + # https://github.com/conda-forge/pytorch-cpu-feedstock/issues/254 + - &pytorch_conda pytorch>=2.3,<2.4.0a0 - pytorch-cuda==11.8 - &tensordict tensordict>=0.1.2 - - dgl>=1.1.0.cu* + - dgl>=2.4.0.cu* cugraph_pyg_dev: common: - output_types: [conda] packages: - *cugraph_unsuffixed - - pytorch>=2.0 + - *pytorch_conda - pytorch-cuda==11.8 - *tensordict - - pyg>=2.5,<2.6 + - pytorch_geometric>=2.5,<2.6 depends_on_pytorch: common: - output_types: [conda] packages: - - &pytorch_unsuffixed pytorch>=2.0,<2.2.0a0 + - *pytorch_conda - torchdata - pydantic - ogb @@ -734,7 +734,7 @@ dependencies: matrices: - matrix: {cuda: "12.*"} packages: - - &pytorch_pip torch>=2.0,<2.2.0a0 + - &pytorch_pip torch>=2.3,<2.4.0a0 - *tensordict - matrix: {cuda: "11.*"} packages: @@ -759,19 +759,19 @@ dependencies: cuda: "12.*" cuda_suffixed: "true" packages: - - pylibwholegraph-cu12==24.10.*,>=0.0.0a0 + - pylibwholegraph-cu12==24.12.*,>=0.0.0a0 - matrix: cuda: "11.*" cuda_suffixed: "true" packages: - - pylibwholegraph-cu11==24.10.*,>=0.0.0a0 + - pylibwholegraph-cu11==24.12.*,>=0.0.0a0 - {matrix: null, packages: [*pylibwholegraph_unsuffixed]} depends_on_rmm: common: - output_types: conda packages: - - &rmm_unsuffixed rmm==24.10.*,>=0.0.0a0 + - &rmm_unsuffixed rmm==24.12.*,>=0.0.0a0 - output_types: requirements packages: # pip recognizes the index as a global option for the requirements.txt file @@ -784,19 +784,19 @@ dependencies: cuda: "12.*" cuda_suffixed: "true" packages: - - rmm-cu12==24.10.*,>=0.0.0a0 + - rmm-cu12==24.12.*,>=0.0.0a0 - matrix: cuda: "11.*" cuda_suffixed: "true" packages: - - rmm-cu11==24.10.*,>=0.0.0a0 + - rmm-cu11==24.12.*,>=0.0.0a0 - {matrix: null, packages: [*rmm_unsuffixed]} depends_on_cudf: common: - output_types: conda packages: - - &cudf_unsuffixed cudf==24.10.*,>=0.0.0a0 + - &cudf_unsuffixed cudf==24.12.*,>=0.0.0a0 - output_types: requirements packages: # pip recognizes the index as a global option for the requirements.txt file @@ -809,19 +809,19 @@ dependencies: cuda: "12.*" cuda_suffixed: "true" packages: - - cudf-cu12==24.10.*,>=0.0.0a0 + - cudf-cu12==24.12.*,>=0.0.0a0 - matrix: cuda: "11.*" cuda_suffixed: "true" packages: - - cudf-cu11==24.10.*,>=0.0.0a0 + - cudf-cu11==24.12.*,>=0.0.0a0 - {matrix: null, packages: [*cudf_unsuffixed]} depends_on_dask_cudf: common: - output_types: conda packages: - - &dask_cudf_unsuffixed dask-cudf==24.10.*,>=0.0.0a0 + - &dask_cudf_unsuffixed dask-cudf==24.12.*,>=0.0.0a0 - output_types: requirements packages: # pip recognizes the index as a global option for the requirements.txt file @@ -834,19 +834,19 @@ dependencies: cuda: "12.*" cuda_suffixed: "true" packages: - - dask-cudf-cu12==24.10.*,>=0.0.0a0 + - dask-cudf-cu12==24.12.*,>=0.0.0a0 - matrix: cuda: "11.*" cuda_suffixed: "true" packages: - - dask-cudf-cu11==24.10.*,>=0.0.0a0 + - dask-cudf-cu11==24.12.*,>=0.0.0a0 - {matrix: null, packages: [*dask_cudf_unsuffixed]} depends_on_pylibraft: common: - output_types: conda packages: - - &pylibraft_unsuffixed pylibraft==24.10.*,>=0.0.0a0 + - &pylibraft_unsuffixed pylibraft==24.12.*,>=0.0.0a0 - output_types: requirements packages: # pip recognizes the index as a global option for the requirements.txt file @@ -859,19 +859,19 @@ dependencies: cuda: "12.*" cuda_suffixed: "true" packages: - - pylibraft-cu12==24.10.*,>=0.0.0a0 + - pylibraft-cu12==24.12.*,>=0.0.0a0 - matrix: cuda: "11.*" cuda_suffixed: "true" packages: - - pylibraft-cu11==24.10.*,>=0.0.0a0 + - pylibraft-cu11==24.12.*,>=0.0.0a0 - {matrix: null, packages: [*pylibraft_unsuffixed]} depends_on_raft_dask: common: - output_types: conda packages: - - &raft_dask_unsuffixed raft-dask==24.10.*,>=0.0.0a0 + - &raft_dask_unsuffixed raft-dask==24.12.*,>=0.0.0a0 - output_types: requirements packages: # pip recognizes the index as a global option for the requirements.txt file @@ -884,19 +884,19 @@ dependencies: cuda: "12.*" cuda_suffixed: "true" packages: - - raft-dask-cu12==24.10.*,>=0.0.0a0 + - raft-dask-cu12==24.12.*,>=0.0.0a0 - matrix: cuda: "11.*" cuda_suffixed: "true" packages: - - raft-dask-cu11==24.10.*,>=0.0.0a0 + - raft-dask-cu11==24.12.*,>=0.0.0a0 - {matrix: null, packages: [*raft_dask_unsuffixed]} depends_on_pylibcugraph: common: - output_types: conda packages: - - &pylibcugraph_unsuffixed pylibcugraph==24.10.*,>=0.0.0a0 + - &pylibcugraph_unsuffixed pylibcugraph==24.12.*,>=0.0.0a0 - output_types: requirements packages: # pip recognizes the index as a global option for the requirements.txt file @@ -909,12 +909,12 @@ dependencies: cuda: "12.*" cuda_suffixed: "true" packages: - - pylibcugraph-cu12==24.10.*,>=0.0.0a0 + - pylibcugraph-cu12==24.12.*,>=0.0.0a0 - matrix: cuda: "11.*" cuda_suffixed: "true" packages: - - pylibcugraph-cu11==24.10.*,>=0.0.0a0 + - pylibcugraph-cu11==24.12.*,>=0.0.0a0 - {matrix: null, packages: [*pylibcugraph_unsuffixed]} # deprecate pylibcugraphops @@ -922,7 +922,7 @@ dependencies: common: - output_types: conda packages: - - &pylibcugraphops_unsuffixed pylibcugraphops==24.10.*,>=0.0.0a0 + - &pylibcugraphops_unsuffixed pylibcugraphops==24.12.*,>=0.0.0a0 - output_types: requirements packages: # pip recognizes the index as a global option for the requirements.txt file @@ -935,12 +935,12 @@ dependencies: cuda: "12.*" cuda_suffixed: "true" packages: - - pylibcugraphops-cu12==24.10.*,>=0.0.0a0 + - pylibcugraphops-cu12==24.12.*,>=0.0.0a0 - matrix: cuda: "11.*" cuda_suffixed: "true" packages: - - pylibcugraphops-cu11==24.10.*,>=0.0.0a0 + - pylibcugraphops-cu11==24.12.*,>=0.0.0a0 - {matrix: null, packages: [*pylibcugraphops_unsuffixed]} depends_on_cupy: diff --git a/docs/cugraph/source/_static/bc_benchmark.png b/docs/cugraph/source/_static/bc_benchmark.png new file mode 100644 index 00000000000..9e385c97e99 Binary files /dev/null and b/docs/cugraph/source/_static/bc_benchmark.png differ diff --git a/docs/cugraph/source/_static/colab.png b/docs/cugraph/source/_static/colab.png new file mode 100644 index 00000000000..c4c3f5b46e1 Binary files /dev/null and b/docs/cugraph/source/_static/colab.png differ diff --git a/docs/cugraph/source/_static/nxcg-execution-diagram.jpg b/docs/cugraph/source/_static/nxcg-execution-diagram.jpg new file mode 100644 index 00000000000..48136289af9 Binary files /dev/null and b/docs/cugraph/source/_static/nxcg-execution-diagram.jpg differ diff --git a/docs/cugraph/source/basics/cugraph_cascading.md b/docs/cugraph/source/basics/cugraph_cascading.md deleted file mode 100644 index bad3d7fa6a8..00000000000 --- a/docs/cugraph/source/basics/cugraph_cascading.md +++ /dev/null @@ -1,53 +0,0 @@ - -# Method Cascading and cuGraph - -BLUF: cuGraph does not support method cascading - -[Method Cascading](https://en.wikipedia.org/wiki/Method_cascading) is a popular, and useful, functional programming concept and is a great way to make code more readable. Python supports method cascading ... _for the most part_. There are a number of Python built-in classes that do not support cascading. - -An example, from cuDF, is a sequence of method calls for loading data and then finding the largest values from a subset of the data (yes there are other ways this could be done): - -``` -gdf = cudf.from_pandas(df).query(‘val > 200’).nlargest(‘va’3) -``` - -cuGraph does not support method cascading for two main reasons: (1) the object-oriented nature of the Graph data object leverages in-place methods, and (2) the fact that algorithms operate on graphs rather than graphs running algorithms. - -## Graph Data Objects -cuGraph follows an object-oriented design for the Graph objects. Users create a Graph and can then add data to object, but every add method call returns `None`. - -_Why Inplace methods?_
-cuGraph focuses on the big graph problems where there are 10s of millions to trillions of edges (Giga bytes to Terabytes of data). At that scale, creating a copy of the data becomes memory inefficient. - -_Why not return `self` rather than `None`?_
-It would be simple to modify the methods to return `self` rather than `None`, however it opens the methods to misinterpretation. Consider the following code: - -``` -# cascade flow - makes sense -G = cugraph.Graph().from_cudf_edgelist(df) - -# non-cascaded code can be confusing -G = cugraph.Graph() -G2 = G.from_cudf_edgelist(df) -G3 = G.from_cudf_edgelist(df2) -``` -The confusion with the non-cascade code is that G, G1, and G3 are all the same object with the same data. Users could be confused since it is not obvious that changing G3 would also change both G2 and G. To prevent confusion, cuGraph has opted to not return `self`. - -_Why not add a flag "return_self" to the methods?_
-``` -# cascade flow - makes sense -G = cugraph.Graph().from_cudf_edgelist(df, return_self=True) -``` -The fact that a developer would explicitly add a "return_self" flag to the method indicates that the developer is aware that the method returns None. It is just as easy for the developer to use a non-cascading workflow. - -### Algorithms -Algorithms operate on graph objects. -``` -cugraph.pagerank(G) and not G.pagerank() -``` -This pattern allows cuGraph to maintain a particular object-oriented model, where Graph objects simply maintain graph data, and algorithm functions operate independently on Graph objects. While this model has benefits that simplify the overall design and its usability in the majority of use cases, it does mean that the developer cannot cascade graph creation into an algorithm call. - -``` -# will not work -G = cugraph.Graph().from_cudf_edgelist(df).pagerank() -``` diff --git a/docs/cugraph/source/basics/cugraph_intro.md b/docs/cugraph/source/basics/index.md similarity index 99% rename from docs/cugraph/source/basics/cugraph_intro.md rename to docs/cugraph/source/basics/index.md index 7ad2825604a..36aad5166bc 100644 --- a/docs/cugraph/source/basics/cugraph_intro.md +++ b/docs/cugraph/source/basics/index.md @@ -1,5 +1,5 @@ - # cuGraph Introduction + The Data Scientist has a collection of techniques within their proverbial toolbox. Data engineering, statistical analysis, and machine learning are among the most commonly known. However, there @@ -20,8 +20,8 @@ into the RAPIDS data science ecosystem and allows the data scientist to easily call graph algorithms using data stored in a GPU DataFrame, NetworkX Graphs, or even CuPy or SciPy sparse Matrix. - ## Vision + The vision of RAPIDS cuGraph is to ___make graph analysis ubiquitous to the point that users just think in terms of analysis and not technologies or frameworks___. This is a goal that many of us on the cuGraph team have been @@ -48,7 +48,6 @@ high-speed ETL, statistics, and machine learning. To make things even better, RAPIDS and DASK allows cuGraph to scale to multiple GPUs to support multi-billion edge graphs. - ## Terminology cuGraph is a collection of GPU accelerated graph algorithms and graph utility diff --git a/docs/cugraph/source/basics/index.rst b/docs/cugraph/source/basics/index.rst deleted file mode 100644 index 7bba301b657..00000000000 --- a/docs/cugraph/source/basics/index.rst +++ /dev/null @@ -1,11 +0,0 @@ -====== -Basics -====== - - -.. toctree:: - :maxdepth: 2 - - cugraph_intro - nx_transition - cugraph_cascading diff --git a/docs/cugraph/source/basics/nx_transition.rst b/docs/cugraph/source/basics/nx_transition.rst deleted file mode 100644 index 9da2fe9b49e..00000000000 --- a/docs/cugraph/source/basics/nx_transition.rst +++ /dev/null @@ -1,181 +0,0 @@ -************************************** -NetworkX by calling cuGraph Algorithms -************************************** - - -*Note: this is a work in progress and will be updatred and changed as we better flesh out -compatibility issues* - -Latest Update -############# - -Last Update: March 7th, 2024 -Release: 24.04 - -**CuGraph is now a registered backend for networkX. This is described in the following blog: -`Accelerating NetworkX on NVIDIA GPUs for High Performance Graph Analytics -`_ - - -Easy Path – Use NetworkX Graph Objects, Accelerated Algorithms -############################################################## - -Rather than updating all of your existing code, simply update the calls to -graph algorithms by replacing the module name. This allows all the complicated -ETL code to be unchanged while still seeing significate performance -improvements. Again this will be deprecated since networkX dispatching to nx_cugraph -has many advantages. - - -.. image:: ../images/Nx_Cg_1.png - :width: 600 - -It is that easy. All algorithms in cuGraph support a NetworkX graph object as -input and match the NetworkX API list of arguments. - -Currently, cuGraph accepts both NetworkX Graph and DiGraph objects. We will be -adding support for Bipartite graph and Multigraph over the next few releases. - -Differences in Algorithms -########################## - -Since cuGraph currently does not support attribute rich graphs, those -algorithms that return simple scores (centrality, clustering, etc.) best match -the NetworkX process. Algorithms that return a subgraph will do so without -any additional attributes on the nodes or edges. - -Algorithms that exactly match -***************************** - -+-------------------------------+------------------------+ -| Algorithm | Differences | -+===============================+========================+ -| Core Number | None | -+-------------------------------+------------------------+ -| HITS | None | -+-------------------------------+------------------------+ -| PageRank | None | -+-------------------------------+------------------------+ -| Personal PageRank | None | -+-------------------------------+------------------------+ -| Strongly Connected Components | None | -+-------------------------------+------------------------+ -| Weakly Connected Components | None | -+-------------------------------+------------------------+ - -| - - - -Algorithms that do not copy over additional attributes -************************************************************************ - -+-------------------------------+-------------------------------------+ -| Algorithm | Differences | -+===============================+=====================================+ -| K-Truss | Does not copy over attributes | -+-------------------------------+-------------------------------------+ -| K-Core | Does not copy over attributes | -+-------------------------------+-------------------------------------+ -| Subgraph Extraction | Does not copy over attributes | -+-------------------------------+-------------------------------------+ - -| - - -Algorithms not in NetworkX -************************** - -+--------------------------------------+----------------------------+ -| Algorithm | Differences | -+======================================+============================+ -| Ensemble Clustering for Graphs (ECG) | Currently not in NetworkX | -+--------------------------------------+----------------------------+ -| Force Atlas 2 | Currently not in NetworkX | -+--------------------------------------+----------------------------+ -| Leiden | Currently not in NetworkX | -+--------------------------------------+----------------------------+ -| Louvain | Currently not in NetworkX | -+--------------------------------------+----------------------------+ -| Overlap coefficient | Currently not in NetworkX | -+--------------------------------------+----------------------------+ -| Spectral Clustering | Currently not in NetworkX | -+--------------------------------------+----------------------------+ - -| - - -Algorithm where not all arguments are supported -*********************************************** - -+----------------------------+-------------------------------------------------+ -| Algorithm | Differences | -+============================+=================================================+ -|Betweenness Centrality | weight is currently not supported – ignored | -| | endpoints is currently not supported – ignored | -+----------------------------+-------------------------------------------------+ -|Edge Betweenness Centrality | weight is currently not supported – ignored | -+----------------------------+-------------------------------------------------+ -| Katz Centrality | beta is currently not supported – ignored | -| | max_iter defaults to 100 versus 1000 | -+----------------------------+-------------------------------------------------+ - -| - -Algorithms where the results are different -****************************************** - - -For example, the NetworkX traversal algorithms typically return a generator -rather than a dictionary. - - -+----------------------------+-------------------------------------------------+ -| Algorithm | Differences | -+============================+=================================================+ -| Triangle Counting | this algorithm simply returns the total number | -| | of triangle and not the number per vertex | -| | (on roadmap to update) | -+----------------------------+-------------------------------------------------+ -| Jaccard coefficient | Currently we only do a 1-hop computation rather | -| | than an all-pairs. Fix is on roadmap | -+----------------------------+-------------------------------------------------+ -| Breadth First Search (BFS) | Returns a Pandas DataFrame with: | -| | [vertex][distance][predecessor] | -+----------------------------+-------------------------------------------------+ -| Single Source | Returns a Pandas DataFrame with: | -| Shortest Path (SSSP) | [vertex][distance][predecessor] | -+----------------------------+-------------------------------------------------+ - -| - -Graph Building -############## - -The biggest difference between NetworkX and cuGraph is with how Graph objects -are built. NetworkX, for the most part, stores graph data in a dictionary. -That structure allows easy insertion of new records. Consider the following -code for building a NetworkX Graph:: - - # Read the node data - df = pd.read_csv( data_file) - - # Construct graph from edge list. - G = nx.DiGraph() - - for row in df.iterrows(): - G.add_edge( - row[1]["1"], row[1]["2"], count=row[1]["3"] - ) - - -The code block is perfectly fine for NetworkX. However, the process of iterating over the dataframe and adding one node at a time is problematic for GPUs and something that we try and avoid. cuGraph stores data in columns (i.e. arrays). Resizing an array requires allocating a new array one element larger, copying the data, and adding the new value. That is not very efficient. - -If your code follows the above model of inserting one element at a time, the we suggest either rewriting that code or using it as is within NetworkX and just accelerating the algorithms with cuGraph. - -Now, if your code bulk loads the data from Pandas, then RAPIDS can accelerate that process by orders of magnitude. - -.. image:: ../images/Nx_Cg_2.png - :width: 600 - -The above cuGraph code will create cuGraph.Graph object and not a NetworkX.Graph object. diff --git a/docs/cugraph/source/graph_support/DGL_support.md b/docs/cugraph/source/graph_support/DGL_support.md index ba9a28e3170..7d32a9efe37 100644 --- a/docs/cugraph/source/graph_support/DGL_support.md +++ b/docs/cugraph/source/graph_support/DGL_support.md @@ -8,9 +8,12 @@ Install and update cugraph-dgl and the required dependencies using the command: -``` -conda install mamba -n base -c conda-forge -mamba install cugraph-dgl -c rapidsai-nightly -c rapidsai -c pytorch -c conda-forge -c nvidia -c dglteam +```shell +# CUDA 11 +conda install -c rapidsai -c pytorch -c conda-forge -c nvidia -c dglteam/label/th23_cu118 cugraph-dgl + +# CUDA 12 +conda install -c rapidsai -c pytorch -c conda-forge -c nvidia -c dglteam/label/th23_cu121 cugraph-dgl ``` ## Build from Source diff --git a/docs/cugraph/source/index.rst b/docs/cugraph/source/index.rst index 9ea9e4d65cf..0db1860b2b9 100644 --- a/docs/cugraph/source/index.rst +++ b/docs/cugraph/source/index.rst @@ -1,49 +1,87 @@ RAPIDS Graph documentation ========================== + .. image:: images/cugraph_logo_2.png :width: 600 -*Making graph analytics fast and easy regardless of scale* - - -.. list-table:: RAPIDS Graph covers a range of graph libraries and packages, that includes: - :widths: 25 25 25 - :header-rows: 1 - - * - Core - - GNN - - Extension - * - :abbr:`cugraph (Python wrapper with lots of convenience functions)` - - :abbr:`cugraph-ops (GNN aggregators and operators)` - - :abbr:`cugraph-service (Graph-as-a-service provides both Client and Server packages)` - * - :abbr:`pylibcugraph (light-weight Python wrapper with no guard rails)` - - :abbr:`cugraph-dgl (Accelerated extensions for use with the DGL framework)` - - - * - :abbr:`libcugraph (C++ API)` - - :abbr:`cugraph-pyg (Accelerated extensions for use with the PyG framework)` - - - * - :abbr:`libcugraph_etl (C++ renumbering function for strings)` - - :abbr:`wholegraph (Shared memory-based GPU-accelerated GNN training)` - - -.. -| ~~~~~~~~~~~~ Introduction ~~~~~~~~~~~~ cuGraph is a library of graph algorithms that seamlessly integrates into the RAPIDS data science ecosystem and allows the data scientist to easily call -graph algorithms using data stored in GPU DataFrames, NetworkX Graphs, or -even CuPy or SciPy sparse Matrices. +graph algorithms using data stored in cuDF/Pandas DataFrames or CuPy/SciPy +sparse matrices. + +--------------------------- +cuGraph Using NetworkX Code +--------------------------- + +cuGraph is now available as a NetworkX backend using `nx-cugraph `_. +Our major integration effort with NetworkX offers NetworkX users a **zero code change** option to accelerate +their existing NetworkX code using an NVIDIA GPU and cuGraph. + +Check out `zero code change accelerated NetworkX `_. If you would like to continue using standard cuGraph, then continue down below. + +---------------------------- +Getting started with cuGraph +---------------------------- + +Required hardware/software for cuGraph and `RAPIDS `_ + * NVIDIA GPU, Volta architecture or later, with `compute capability 7.0+ `_ + * CUDA 11.2-11.8, 12.0-12.5 + * Python version 3.10, 3.11, or 3.12 + +++++++++++++ +Installation +++++++++++++ + +Please see the latest `RAPIDS System Requirements documentation `_. + +This includes several ways to set up cuGraph + +* From Unix + + * `Conda `_ + * `Docker `_ + * `pip `_ + + +**Note: Windows use of RAPIDS depends on prior installation of** `WSL2 `_. + +* From Windows + + * `Conda `_ + * `Docker `_ + * `pip `_ + + Cugraph API Example + + .. code-block:: python + + import cugraph + import cudf + + # Create an instance of the popular Zachary Karate Club graph + from cugraph.datasets import karate + G = karate.get_graph() + + # Call cugraph.degree_centrality + vertex_bc = cugraph.degree_centrality(G) + + There are several resources containing cuGraph examples, the cuGraph `notebook repository `_ has many examples of loading graph data and running algorithms in Jupyter notebooks. + The cuGraph `test code `_ contains script examples of setting up and calling cuGraph algorithms. + + A simple example of `testing the degree centrality algorithm `_ is a good place to start. There are also `multi-GPU examples `_ with larger data sets as well. -Note: We are redoing all of our documents, please be patient as we update -the docs and links +---- -| +~~~~~~~~~~~~~~~~~ +Table of Contents +~~~~~~~~~~~~~~~~~ .. toctree:: :maxdepth: 2 - :caption: Contents: basics/index nx_cugraph/index @@ -54,8 +92,9 @@ the docs and links references/index api_docs/index +~~~~~~~~~~~~~~~~~~ Indices and tables -================== +~~~~~~~~~~~~~~~~~~ * :ref:`genindex` * :ref:`search` diff --git a/docs/cugraph/source/installation/getting_cugraph.md b/docs/cugraph/source/installation/getting_cugraph.md index 41ec9a67e1f..01bc9e379c9 100644 --- a/docs/cugraph/source/installation/getting_cugraph.md +++ b/docs/cugraph/source/installation/getting_cugraph.md @@ -21,7 +21,7 @@ The RAPIDS Docker containers contain all RAPIDS packages, including all from cuG ## Conda -It is easy to install cuGraph using conda. You can get a minimal conda installation with [Miniconda](https://conda.io/miniconda.html) or get the full installation with [Anaconda](https://www.anaconda.com/download). +It is easy to install cuGraph using conda. You can get a minimal conda installation with [miniforge](https://github.com/conda-forge/miniforge). cuGraph Conda packages * cugraph - this will also import: diff --git a/docs/cugraph/source/nx_cugraph/benchmarks.md b/docs/cugraph/source/nx_cugraph/benchmarks.md new file mode 100644 index 00000000000..45085c133a9 --- /dev/null +++ b/docs/cugraph/source/nx_cugraph/benchmarks.md @@ -0,0 +1,26 @@ +# Benchmarks + +## NetworkX vs. nx-cugraph +We ran several commonly used graph algorithms on both `networkx` and `nx-cugraph`. Here are the results + + +
+ +![bench-image](../_static/bc_benchmark.png) + +
Results from running this Benchmark
+
+ +## Reproducing Benchmarks + +Below are the steps to reproduce the results on your own. + +1. Clone the latest + +2. Follow the instructions to build and activate an environment + +4. Install the latest `nx-cugraph` by following the [Installation Guide](installation.md) + +5. Follow the instructions written in the README [here](https://github.com/rapidsai/cugraph/blob/HEAD/benchmarks/nx-cugraph/pytest-based) diff --git a/docs/cugraph/source/nx_cugraph/how-it-works.md b/docs/cugraph/source/nx_cugraph/how-it-works.md new file mode 100644 index 00000000000..5696688d1b5 --- /dev/null +++ b/docs/cugraph/source/nx_cugraph/how-it-works.md @@ -0,0 +1,113 @@ +# How it Works + +NetworkX has the ability to **dispatch function calls to separately-installed third-party backends**. + +NetworkX backends let users experience improved performance and/or additional functionality without changing their NetworkX Python code. Examples include backends that provide algorithm acceleration using GPUs, parallel processing, graph database integration, and more. + +While NetworkX is a pure-Python implementation, backends may be written to use other libraries and even specialized hardware. `nx-cugraph` is a NetworkX backend that uses RAPIDS cuGraph and NVIDIA GPUs to significantly improve NetworkX performance. + +![nxcg-execution-flow](../_static/nxcg-execution-diagram.jpg) + +## Enabling nx-cugraph + +It is recommended to use `networkx>=3.4` for optimal zero code change performance, but `nx-cugraph` will also work with `networkx 3.0+`. + +NetworkX will use `nx-cugraph` as the backend if any of the following are used: + +### `NX_CUGRAPH_AUTOCONFIG` environment variable. + +The `NX_CUGRAPH_AUTOCONFIG` environment variable can be used to configure NetworkX for full zero code change acceleration using `nx-cugraph`. If a NetworkX function is called that `nx-cugraph` supports, NetworkX will redirect the function call to `nx-cugraph` automatically, or fall back to either another backend if enabled or the default NetworkX implementation. See the [NetworkX documentation on backends](https://networkx.org/documentation/stable/reference/backends.html) for configuring NetworkX manually. + +``` +bash> NX_CUGRAPH_AUTOCONFIG=True python my_networkx_script.py +``` + +### `backend=` keyword argument + +To explicitly specify a particular backend for an API, use the `backend=` +keyword argument. This argument takes precedence over the +`NX_CUGRAPH_AUTOCONFIG` environment variable. This requires anyone +running code that uses the `backend=` keyword argument to have the specified +backend installed. + +Example: +```python +nx.betweenness_centrality(cit_patents_graph, k=k, backend="cugraph") +``` + +### Type-based dispatching + +NetworkX also supports automatically dispatching to backends associated with +specific graph types. Like the `backend=` keyword argument example above, this +requires the user to write code for a specific backend, and therefore requires +the backend to be installed, but has the advantage of ensuring a particular +behavior without the potential for runtime conversions. + +To use type-based dispatching with `nx-cugraph`, the user must import the backend +directly in their code to access the utilities provided to create a Graph +instance specifically for the `nx-cugraph` backend. + +Example: +```python +import networkx as nx +import nx_cugraph as nxcg + +G = nx.Graph() + +# populate the graph +# ... + +nxcg_G = nxcg.from_networkx(G) # conversion happens once here +nx.betweenness_centrality(nxcg_G, k=1000) # nxcg Graph type causes cugraph backend + # to be used, no conversion necessary +``` + +## Command Line Example + +--- + +Create `bc_demo.ipy` and paste the code below. + +```python +import pandas as pd +import networkx as nx + +url = "https://data.rapids.ai/cugraph/datasets/cit-Patents.csv" +df = pd.read_csv(url, sep=" ", names=["src", "dst"], dtype="int32") +G = nx.from_pandas_edgelist(df, source="src", target="dst") + +%time result = nx.betweenness_centrality(G, k=10) +``` +Run the command: +``` +user@machine:/# ipython bc_demo.ipy + +CPU times: user 7min 36s, sys: 5.22 s, total: 7min 41s +Wall time: 7min 41s +``` + +You will observe a run time of approximately 7 minutes...more or less depending on your CPU. + +Run the command again, this time specifying cugraph as the NetworkX backend. +```bash +user@machine:/# NX_CUGRAPH_AUTOCONFIG=True ipython bc_demo.ipy + +CPU times: user 4.14 s, sys: 1.13 s, total: 5.27 s +Wall time: 5.32 s +``` +This run will be much faster, typically around 5 seconds depending on your GPU. + +
+ +*Note, the examples above were run using the following specs*: + +    *NetworkX 3.4*
+    *nx-cugraph 24.10*
+    *CPU: Intel(R) Xeon(R) Gold 6128 CPU @ 3.40GHz 45GB RAM*
+    *GPU: NVIDIA Quadro RTX 8000 80GB RAM*
+ +
+ +--- + +The latest list of algorithms supported by `nx-cugraph` can be found in [GitHub](https://github.com/rapidsai/cugraph/blob/HEAD/python/nx-cugraph/README.md#algorithms), or in the [Supported Algorithms Section](supported-algorithms.md). diff --git a/docs/cugraph/source/nx_cugraph/index.rst b/docs/cugraph/source/nx_cugraph/index.rst index ef6f51601ab..730958a5b73 100644 --- a/docs/cugraph/source/nx_cugraph/index.rst +++ b/docs/cugraph/source/nx_cugraph/index.rst @@ -1,9 +1,66 @@ -=============================== -nxCugraph as a NetworkX Backend -=============================== +nx-cugraph +----------- +``nx-cugraph`` is a NetworkX backend that provides **GPU acceleration** to many popular NetworkX algorithms. + +By simply `installing and enabling nx-cugraph `_, users can see significant speedup on workflows where performance is hindered by the default NetworkX implementation. + +Users can have GPU-based, large-scale performance **without** changing their familiar and easy-to-use NetworkX code. + +.. centered:: Timed result from running the following code snippet (called ``demo.ipy``, showing NetworkX with vs. without ``nx-cugraph``) + +.. code-block:: python + + import pandas as pd + import networkx as nx + + url = "https://data.rapids.ai/cugraph/datasets/cit-Patents.csv" + df = pd.read_csv(url, sep=" ", names=["src", "dst"], dtype="int32") + G = nx.from_pandas_edgelist(df, source="src", target="dst") + + %time result = nx.betweenness_centrality(G, k=10) + + +:: + + user@machine:/# ipython demo.ipy + CPU times: user 7min 36s, sys: 5.22 s, total: 7min 41s + Wall time: 7min 41s + + +:: + + user@machine:/# NX_CUGRAPH_AUTOCONFIG=True ipython demo.ipy + CPU times: user 4.14 s, sys: 1.13 s, total: 5.27 s + Wall time: 5.32 s + + +.. figure:: ../_static/colab.png + :width: 200px + :target: https://nvda.ws/4drM4re + + Try it on Google Colab! + + ++--------------------------------------------------------------------------------------------------------+ +| **Zero Code Change Acceleration** | +| | +| Just set the environment variable ``NX_CUGRAPH_AUTOCONFIG=True`` to enable ``nx-cugraph`` in NetworkX. | ++--------------------------------------------------------------------------------------------------------+ +| **Run the same code on CPU or GPU** | +| | +| Nothing changes, not even your `import` statements, when going from CPU to GPU. | ++--------------------------------------------------------------------------------------------------------+ + + +``nx-cugraph`` is now Generally Available (GA) as part of the ``RAPIDS`` package. See `RAPIDS +Quick Start `_ to get up-and-running with ``nx-cugraph``. .. toctree:: - :maxdepth: 2 + :maxdepth: 1 + :caption: Contents: - nx_cugraph.md + how-it-works + installation + supported-algorithms + benchmarks diff --git a/docs/cugraph/source/nx_cugraph/installation.md b/docs/cugraph/source/nx_cugraph/installation.md new file mode 100644 index 00000000000..a816801d001 --- /dev/null +++ b/docs/cugraph/source/nx_cugraph/installation.md @@ -0,0 +1,50 @@ +# Installing nx-cugraph + +This guide describes how to install ``nx-cugraph`` and use it in your workflows. + + +## System Requirements + +`nx-cugraph` requires the following: + + - **Volta architecture or later NVIDIA GPU, with [compute capability](https://developer.nvidia.com/cuda-gpus) 7.0+** + - **[CUDA](https://docs.nvidia.com/cuda/index.html) 11.2, 11.4, 11.5, 11.8, 12.0, 12.2, or 12.5** + - **Python >= 3.10** + - **[NetworkX](https://networkx.org/documentation/stable/install.html#) >= 3.0 (version 3.4 or higher recommended)** + +More details about system requirements can be found in the [RAPIDS System Requirements Documentation](https://docs.rapids.ai/install#system-req). + +## Installing Packages + +Read the [RAPIDS Quick Start Guide](https://docs.rapids.ai/install) to learn more about installing all RAPIDS libraries. + +`nx-cugraph` can be installed using conda or pip. It is included in the RAPIDS metapackage, or can be installed separately. + +### Conda +**Nightly version** +```bash +conda install -c rapidsai-nightly -c conda-forge -c nvidia nx-cugraph +``` + +**Stable version** +```bash +conda install -c rapidsai -c conda-forge -c nvidia nx-cugraph +``` + +### pip +**Nightly version** +```bash +pip install nx-cugraph-cu11 --extra-index-url https://pypi.anaconda.org/rapidsai-wheels-nightly/simple +``` + +**Stable version** +```bash +pip install nx-cugraph-cu11 --extra-index-url https://pypi.nvidia.com +``` + +
+ +**Note:** + - The `pip install` examples above are for CUDA 11. To install for CUDA 12, replace `-cu11` with `-cu12` + +
diff --git a/docs/cugraph/source/nx_cugraph/nx_cugraph.md b/docs/cugraph/source/nx_cugraph/nx_cugraph.md index 75a30b0be5c..900362a6e2b 100644 --- a/docs/cugraph/source/nx_cugraph/nx_cugraph.md +++ b/docs/cugraph/source/nx_cugraph/nx_cugraph.md @@ -1,18 +1,10 @@ ### nx_cugraph -nx-cugraph is a [NetworkX -backend]() that provides GPU acceleration to many popular NetworkX algorithms. - -By simply [installing and enabling nx-cugraph](), users can see significant speedup on workflows where performance is hindered by the default NetworkX implementation. With nx-cugraph, users can have GPU-based, large-scale performance without changing their familiar and easy-to-use NetworkX code. - -Let's look at some examples of algorithm speedups comparing NetworkX with and without GPU acceleration using nx-cugraph. - -Each chart has three measurements. -* NX - default NetworkX, no GPU acceleration -* nx-cugraph - GPU-accelerated NetworkX using nx-cugraph. This involves an internal conversion/transfer of graph data from CPU to GPU memory -* nx-cugraph (preconvert) - GPU-accelerated NetworkX using nx-cugraph with the graph data pre-converted/transferred to GPU +`nx-cugraph` is a [networkX backend]() that accelerates many popular NetworkX functions using cuGraph and NVIDIA GPUs. +Users simply [install and enable nx-cugraph](installation.md) to experience GPU speedups. +Lets look at some examples of algorithm speedups comparing CPU based NetworkX to dispatched versions run on GPU with nx_cugraph. ![Ancestors](../images/ancestors.png) ![BFS Tree](../images/bfs_tree.png) @@ -22,46 +14,3 @@ Each chart has three measurements. ![Pagerank](../images/pagerank.png) ![Single Source Shortest Path](../images/sssp.png) ![Weakly Connected Components](../images/wcc.png) - -### Command line example -Open bc_demo.ipy and paste the code below. - -``` -import pandas as pd -import networkx as nx - -url = "https://data.rapids.ai/cugraph/datasets/cit-Patents.csv" -df = pd.read_csv(url, sep=" ", names=["src", "dst"], dtype="int32") -G = nx.from_pandas_edgelist(df, source="src", target="dst") - -%time result = nx.betweenness_centrality(G, k=10) -``` -Run the command: -``` -user@machine:/# ipython bc_demo.ipy -``` - -You will observe a run time of approximately 7 minutes...more or less depending on your cpu. - -Run the command again, this time specifying cugraph as the NetworkX backend. -``` -user@machine:/# NETWORKX_BACKEND_PRIORITY=cugraph ipython bc_demo.ipy -``` -This run will be much faster, typically around 20 seconds depending on your GPU. -``` -user@machine:/# NETWORKX_BACKEND_PRIORITY=cugraph ipython bc_demo.ipy -``` -There is also an option to cache the graph conversion to GPU. This can dramatically improve performance when running multiple algorithms on the same graph. -``` -NETWORKX_BACKEND_PRIORITY=cugraph NETWORKX_CACHE_CONVERTED_GRAPHS=True ipython bc_demo.ipy -``` - -When running Python interactively, the cugraph backend can be specified as an argument in the algorithm call. - -For example: -``` -nx.betweenness_centrality(cit_patents_graph, k=k, backend="cugraph") -``` - - -The latest list of algorithms supported by nx-cugraph can be found [here](https://github.com/rapidsai/cugraph/blob/main/python/nx-cugraph/README.md#algorithms). diff --git a/docs/cugraph/source/nx_cugraph/supported-algorithms.rst b/docs/cugraph/source/nx_cugraph/supported-algorithms.rst new file mode 100644 index 00000000000..8f57c02b240 --- /dev/null +++ b/docs/cugraph/source/nx_cugraph/supported-algorithms.rst @@ -0,0 +1,355 @@ +Supported Algorithms +===================== + +The nx-cugraph backend to NetworkX connects +`pylibcugraph `_ (cuGraph's low-level Python +interface to its CUDA-based graph analytics library) and +`CuPy `_ (a GPU-accelerated array library) to NetworkX's +familiar and easy-to-use API. + +Below is the list of algorithms that are currently supported in nx-cugraph. + + +Algorithms +---------- + ++-----------------------------+ +| **Centrality** | ++=============================+ +| betweenness_centrality | ++-----------------------------+ +| edge_betweenness_centrality | ++-----------------------------+ +| degree_centrality | ++-----------------------------+ +| in_degree_centrality | ++-----------------------------+ +| out_degree_centrality | ++-----------------------------+ +| eigenvector_centrality | ++-----------------------------+ +| katz_centrality | ++-----------------------------+ + ++---------------------+ +| **Cluster** | ++=====================+ +| average_clustering | ++---------------------+ +| clustering | ++---------------------+ +| transitivity | ++---------------------+ +| triangles | ++---------------------+ + ++--------------------------+ +| **Community** | ++==========================+ +| louvain_communities | ++--------------------------+ + ++--------------------------+ +| **Bipartite** | ++==========================+ +| complete_bipartite_graph | ++--------------------------+ + ++------------------------------------+ +| **Components** | ++====================================+ +| connected_components | ++------------------------------------+ +| is_connected | ++------------------------------------+ +| node_connected_component | ++------------------------------------+ +| number_connected_components | ++------------------------------------+ +| weakly_connected | ++------------------------------------+ +| is_weakly_connected | ++------------------------------------+ +| number_weakly_connected_components | ++------------------------------------+ +| weakly_connected_components | ++------------------------------------+ + ++-------------+ +| **Core** | ++=============+ +| core_number | ++-------------+ +| k_truss | ++-------------+ + ++-------------+ +| **DAG** | ++=============+ +| ancestors | ++-------------+ +| descendants | ++-------------+ + ++--------------------+ +| **Isolate** | ++====================+ +| is_isolate | ++--------------------+ +| isolates | ++--------------------+ +| number_of_isolates | ++--------------------+ + ++-------------------+ +| **Link analysis** | ++===================+ +| hits | ++-------------------+ +| pagerank | ++-------------------+ + ++----------------+ +| **Operators** | ++================+ +| complement | ++----------------+ +| reverse | ++----------------+ + ++----------------------+ +| **Reciprocity** | ++======================+ +| overall_reciprocity | ++----------------------+ +| reciprocity | ++----------------------+ + ++---------------------------------------+ +| **Shortest Paths** | ++=======================================+ +| has_path | ++---------------------------------------+ +| shortest_path | ++---------------------------------------+ +| shortest_path_length | ++---------------------------------------+ +| all_pairs_shortest_path | ++---------------------------------------+ +| all_pairs_shortest_path_length | ++---------------------------------------+ +| bidirectional_shortest_path | ++---------------------------------------+ +| single_source_shortest_path | ++---------------------------------------+ +| single_source_shortest_path_length | ++---------------------------------------+ +| single_target_shortest_path | ++---------------------------------------+ +| single_target_shortest_path_length | ++---------------------------------------+ +| all_pairs_bellman_ford_path | ++---------------------------------------+ +| all_pairs_bellman_ford_path_length | ++---------------------------------------+ +| all_pairs_dijkstra | ++---------------------------------------+ +| all_pairs_dijkstra_path | ++---------------------------------------+ +| all_pairs_dijkstra_path_length | ++---------------------------------------+ +| bellman_ford_path | ++---------------------------------------+ +| bellman_ford_path_length | ++---------------------------------------+ +| dijkstra_path | ++---------------------------------------+ +| dijkstra_path_length | ++---------------------------------------+ +| single_source_bellman_ford | ++---------------------------------------+ +| single_source_bellman_ford_path | ++---------------------------------------+ +| single_source_bellman_ford_path_length| ++---------------------------------------+ +| single_source_dijkstra | ++---------------------------------------+ +| single_source_dijkstra_path | ++---------------------------------------+ +| single_source_dijkstra_path_length | ++---------------------------------------+ + ++---------------------------+ +| **Traversal** | ++===========================+ +| bfs_edges | ++---------------------------+ +| bfs_layers | ++---------------------------+ +| bfs_predecessors | ++---------------------------+ +| bfs_successors | ++---------------------------+ +| bfs_tree | ++---------------------------+ +| descendants_at_distance | ++---------------------------+ +| generic_bfs_edges | ++---------------------------+ + ++---------------------+ +| **Tree** | ++=====================+ +| is_arborescence | ++---------------------+ +| is_branching | ++---------------------+ +| is_forest | ++---------------------+ +| is_tree | ++---------------------+ + + +Utilities +------- + ++-------------------------+ +| **Classes** | ++=========================+ +| is_negatively_weighted | ++-------------------------+ + ++----------------------+ +| **Convert** | ++======================+ +| from_dict_of_lists | ++----------------------+ +| to_dict_of_lists | ++----------------------+ + ++--------------------------+ +| **Convert Matrix** | ++==========================+ +| from_pandas_edgelist | ++--------------------------+ +| from_scipy_sparse_array | ++--------------------------+ + ++-----------------------------------+ +| **Relabel** | ++===================================+ +| convert_node_labels_to_integers | ++-----------------------------------+ +| relabel_nodes | ++-----------------------------------+ + +Generators +------------ + ++-------------------------------+ +| **Classic** | ++===============================+ +| barbell_graph | ++-------------------------------+ +| circular_ladder_graph | ++-------------------------------+ +| complete_graph | ++-------------------------------+ +| complete_multipartite_graph | ++-------------------------------+ +| cycle_graph | ++-------------------------------+ +| empty_graph | ++-------------------------------+ +| ladder_graph | ++-------------------------------+ +| lollipop_graph | ++-------------------------------+ +| null_graph | ++-------------------------------+ +| path_graph | ++-------------------------------+ +| star_graph | ++-------------------------------+ +| tadpole_graph | ++-------------------------------+ +| trivial_graph | ++-------------------------------+ +| turan_graph | ++-------------------------------+ +| wheel_graph | ++-------------------------------+ + ++-----------------+ +| **Classic** | ++=================+ +| caveman_graph | ++-----------------+ + ++------------+ +| **Ego** | ++============+ +| ego_graph | ++------------+ + ++------------------------------+ +| **small** | ++==============================+ +| bull_graph | ++------------------------------+ +| chvatal_graph | ++------------------------------+ +| cubical_graph | ++------------------------------+ +| desargues_graph | ++------------------------------+ +| diamond_graph | ++------------------------------+ +| dodecahedral_graph | ++------------------------------+ +| frucht_graph | ++------------------------------+ +| heawood_graph | ++------------------------------+ +| house_graph | ++------------------------------+ +| house_x_graph | ++------------------------------+ +| icosahedral_graph | ++------------------------------+ +| krackhardt_kite_graph | ++------------------------------+ +| moebius_kantor_graph | ++------------------------------+ +| octahedral_graph | ++------------------------------+ +| pappus_graph | ++------------------------------+ +| petersen_graph | ++------------------------------+ +| sedgewick_maze_graph | ++------------------------------+ +| tetrahedral_graph | ++------------------------------+ +| truncated_cube_graph | ++------------------------------+ +| truncated_tetrahedron_graph | ++------------------------------+ +| tutte_graph | ++------------------------------+ + ++-------------------------------+ +| **Social** | ++===============================+ +| davis_southern_women_graph | ++-------------------------------+ +| florentine_families_graph | ++-------------------------------+ +| karate_club_graph | ++-------------------------------+ +| les_miserables_graph | ++-------------------------------+ + + +To request nx-cugraph backend support for a NetworkX API that is not listed +above, visit the `cuGraph GitHub repo `_. diff --git a/docs/cugraph/source/wholegraph/installation/container.md b/docs/cugraph/source/wholegraph/installation/container.md index 3a2c627c56a..6aac53cf88f 100644 --- a/docs/cugraph/source/wholegraph/installation/container.md +++ b/docs/cugraph/source/wholegraph/installation/container.md @@ -24,6 +24,7 @@ RUN pip3 install Cython setuputils3 scikit-build nanobind pytest-forked pytest To run GNN applications, you may also need cuGraphOps, DGL and/or PyG libraries to run the GNN layers. You may refer to [DGL](https://www.dgl.ai/pages/start.html) or [PyG](https://pytorch-geometric.readthedocs.io/en/latest/notes/installation.html) For example, to install DGL, you may need to add: + ```dockerfile -RUN pip3 install dgl -f https://data.dgl.ai/wheels/cu118/repo.html +RUN pip3 install dgl -f https://data.dgl.ai/wheels/torch-2.3/cu118/repo.html ``` diff --git a/docs/cugraph/source/wholegraph/installation/getting_wholegraph.md b/docs/cugraph/source/wholegraph/installation/getting_wholegraph.md index 57314dcd426..80c666d6593 100644 --- a/docs/cugraph/source/wholegraph/installation/getting_wholegraph.md +++ b/docs/cugraph/source/wholegraph/installation/getting_wholegraph.md @@ -21,7 +21,7 @@ The RAPIDS Docker containers (as of Release 23.10) contain all RAPIDS packages, ## Conda -It is easy to install WholeGraph using conda. You can get a minimal conda installation with [Miniconda](https://conda.io/miniconda.html) or get the full installation with [Anaconda](https://www.anaconda.com/download). +It is easy to install WholeGraph using conda. You can get a minimal conda installation with [miniforge](https://github.com/conda-forge/miniforge). WholeGraph conda packages * libwholegraph diff --git a/notebooks/README.md b/notebooks/README.md index a8f094c340b..f0d0a25b9dd 100644 --- a/notebooks/README.md +++ b/notebooks/README.md @@ -66,13 +66,13 @@ The easiest way to run the notebooks is to get the latest [rapidsai/notebooks](h For example, get the latest (as of writing the document) nightly image (`a` after the version number indicates that an image is nightly) with cuda 12.0 using ```sh -docker pull rapidsai/notebooks:24.10a-cuda12.0-py3.10 +docker pull rapidsai/notebooks:24.12a-cuda12.0-py3.10 ``` And, then run a container based on the image using ```sh -docker run --rm -it --pull always --gpus all --shm-size=1g --ulimit memlock=-1 --ulimit stack=67108864 -p 8888:8888 rapidsai/notebooks:24.10a-cuda12.0-py3.10 +docker run --rm -it --pull always --gpus all --shm-size=1g --ulimit memlock=-1 --ulimit stack=67108864 -p 8888:8888 rapidsai/notebooks:24.12a-cuda12.0-py3.10 ``` You are all set. Run and edit cugraph notebooks from a browser at url http://127.0.0.1:8888/lab/tree/cugraph/cugraph_benchmarks @@ -88,8 +88,8 @@ ssh -L 127.0.0.1:8888:127.0.0.1:8888 [USER_NAME@][REMOTE_HOST_NAME or REMOTE_HO and then run the container in your remote machine. ```sh -docker pull rapidsai/notebooks:24.10a-cuda12.0-py3.10 -docker run --rm -it --pull always --gpus all --shm-size=1g --ulimit memlock=-1 --ulimit stack=67108864 -p 8888:8888 rapidsai/notebooks:24.10a-cuda12.0-py3.10 +docker pull rapidsai/notebooks:24.12a-cuda12.0-py3.10 +docker run --rm -it --pull always --gpus all --shm-size=1g --ulimit memlock=-1 --ulimit stack=67108864 -p 8888:8888 rapidsai/notebooks:24.12a-cuda12.0-py3.10 ``` You can run and edit cugraph notebooks at url http://127.0.0.1:8888/lab/tree/cugraph/cugraph_benchmarks as if they are running locally. diff --git a/notebooks/demo/accelerating_networkx.ipynb b/notebooks/demo/accelerating_networkx.ipynb new file mode 100644 index 00000000000..1a6c6cfb3f6 --- /dev/null +++ b/notebooks/demo/accelerating_networkx.ipynb @@ -0,0 +1,614 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": { + "id": "R2cpVp2WdOsp" + }, + "source": [ + "# NetworkX - Easy Graph Analytics\n", + "\n", + "NetworkX is the most popular library for graph analytics available in Python, or quite possibly any language. To illustrate this, NetworkX was downloaded more than 71 million times in September of 2024 alone, which is roughly 71 times more than the next most popular graph analytics library! [*](https://en.wikipedia.org/wiki/NetworkX) NetworkX has earned this popularity from its very easy-to-use API, the wealth of documentation and examples available, the large (and friendly) community behind it, and its easy installation which requires nothing more than Python.\n", + "\n", + "However, NetworkX users are familiar with the tradeoff that comes with those benefits. The pure-Python implementation often results in poor performance when graph data starts to reach larger scales, limiting the usefulness of the library for many real-world problems.\n", + "\n", + "# Accelerated NetworkX - Easy (and fast!) Graph Analytics\n", + "\n", + "To address the performance problem, NetworkX 3.0 introduced a mechanism to dispatch algorithm calls to alternate implementations. The NetworkX Python API remains the same but NetworkX will use more capable algorithm implementations provided by one or more backends. This approach means users don't have to give up NetworkX -or even change their code- in order to take advantage of GPU performance." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "xkg10FrNThrK" + }, + "source": [ + "# Let's Get the Environment Setup\n", + "This notebook will demonstrate NetworkX both with and without GPU acceleration provided by the `nx-cugraph` backend.\n", + "\n", + "`nx-cugraph` is available as a package installable using `pip`, `conda`, and [from source](https://github.com/rapidsai/nx-cugraph). Before importing `networkx`, lets install `nx-cugraph` so it can be registered as an available backend by NetworkX when needed. We'll use `pip` to install.\n", + "\n", + "NOTES:\n", + "* `nx-cugraph` requires a compatible NVIDIA GPU, NVIDIA CUDA and associated drivers, and a supported OS. Details about these and other installation prerequisites can be seen [here](https://docs.rapids.ai/install#system-req).\n", + "* The `nx-cugraph` package is currently hosted by NVIDIA and therefore the `--extra-index-url` option must be used.\n", + "* `nx-cugraph` is supported on specific 11.x and 12.x CUDA versions, and the major version number must be known in order to install the correct build (this is determined automatically when using `conda`).\n", + "\n", + "To find the CUDA major version on your system, run the following command:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "id": "NMFwzc1I95BS" + }, + "outputs": [], + "source": [ + "!nvcc --version" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "i91Yj-yZ-nGS" + }, + "source": [ + "From the above output we can see we're using CUDA 12.x so we'll be installing `nx-cugraph-cu12`. If we were using CUDA 11.x, the package name would be `nx-cugraph-cu11`. We'll also be adding `https://pypi.nvidia.com` as an `--extra-index-url`:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "id": "mYYN9EpnWphu" + }, + "outputs": [], + "source": [ + "!pip install nx-cugraph-cu12 --extra-index-url=https://pypi.nvidia.com" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "0h1K-7tI_AZH" + }, + "source": [ + "Of course, we'll also be using `networkx`, which is already provided in the Colab environment. This notebook will be using features added in version 3.3, so we'll import it here to verify we have a compatible version." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "id": "YTV0ZTME2tV6" + }, + "outputs": [], + "source": [ + "import networkx as nx\n", + "nx.__version__" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "UiZKOa3WC7be" + }, + "source": [ + "# Let's Start with Something Simple\n", + "\n", + "To begin, we'll compare NetworkX results without a backend to results of the same algorithm using the `nx-cugraph` backend on a small graph. `nx.karate_club_graph()` returns an instance of the famous example graph consisting of 34 nodes and 78 edges from Zachary's paper, described [here](https://en.wikipedia.org/wiki/Zachary%27s_karate_club)." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "3atL3tI0frYm" + }, + "source": [ + "## Betweenness Centrality\n", + "[Betweenness Centrality](https://en.wikipedia.org/wiki/Betweenness_centrality) is a graph algorithm that computes a centrality score for each node (`v`) based on how many of the shortest paths between pairs of nodes in the graph pass through `v`. A higher centrality score represents a node that \"connects\" other nodes in a network more than that of a node with a lower score.\n", + "\n", + "First, let's create a NetworkX Graph instance of the the Karate Club graph and inspect it." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "id": "JSw7EZ46-kRu" + }, + "outputs": [], + "source": [ + "G = nx.karate_club_graph()\n", + "G.number_of_nodes(), G.number_of_edges()" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "_-E17u2gKgbC" + }, + "source": [ + "Next, let's run betweenness centrality and save the results. Because the Karate Club graph is so small, this should not take long." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "id": "qjxXXKJhKQ4s" + }, + "outputs": [], + "source": [ + "%%time\n", + "nx_bc_results = nx.betweenness_centrality(G)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "ClrR3z9XMfLr" + }, + "source": [ + "Now, let's run the same algorithm on the same data using the `nx-cugraph` backend.\n", + "\n", + "There are several ways to instruct NetworkX to use a particular backend instead of the default implementation. Here, we will use the `config` API, which was added in NetworkX version 3.3.\n", + "\n", + "The following two lines set the backend to \"cugraph\" and enable graph conversion caching.\n", + "\n", + "Some notes:\n", + "* The standard convention for NetworkX backends is to name the package with a `nx-` prefix to denote that these are packages intended to be used with NetworkX, but the `nx-` prefix is not included when referring to them in NetworkX API calls. Here, `nx-cugraph` is the name of the backend package, and `\"cugraph\"` is the name NetworkX will use to refer to it.\n", + "* NetworkX can use multiple backends! `nx.config.backend_priority` is a list that can contain several backends, ordered based on priority. If a backend in the list cannot run a particular algorithm (either because it isn't supported in the backend, the algorithm doesn't support a particular option, or some other reason), NetworkX will try the next backend in the list. If no specified backend is able to run the algorithm, NetworkX will fall back to the default implementation.\n", + "* Many backends have their own data structures for representing an input graph, often optimized for that backend's implementation. Prior to running a backend algorithm, NetworkX will have the backend convert the standard NetworkX Graph instance to the backend-specific type. This conversion can be expensive, and rather than repeat it as part of each algorithm call, NetworkX can cache the conversion so it can be skipped on future calls if the graph doesn't change. This caching can save significant time and improve overall performance." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "id": "oFHwNqqsNsqS" + }, + "outputs": [], + "source": [ + "nx.config.backend_priority=[\"cugraph\"] # NETWORKX_BACKEND_PRIORITY=cugraph\n", + "nx.config.cache_converted_graphs=True # NETWORKX_CACHE_CONVERTED_GRAPHS=True" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "id": "HrUeWRRQRzFP" + }, + "outputs": [], + "source": [ + "%%time\n", + "nxcg_bc_results = nx.betweenness_centrality(G)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "z1hxut3GTj5A" + }, + "source": [ + "You may have noticed that using the `nx-cugraph` backend resulted in a slightly slower execution time. This is not surprising when working with a graph this small, since the overhead of converting the graph for the first time and launching the algorithm kernel on the GPU is actually significantly more than the computation time itself. We'll see later that this overhead is negligible when compared to the time saved when running on a GPU for larger graphs.\n", + "\n", + "Since we've enabled graph conversion caching, we can see that if we re-run the same call the execution time is noticeably shorter." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "id": "7a0XvpUOr9Ju" + }, + "outputs": [], + "source": [ + "%%time\n", + "nxcg_bc_results = nx.betweenness_centrality(G)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "ppjE5J5RscOe" + }, + "source": [ + "Notice the warning above about using the cache. This will only be raised **once** per graph instance (it can also be easily disabled), but its purpose is to point out that the cache should not be used if the Graph object will have its attribute dictionary modified directly. In this case and many others, we won't be modifying the dictionaries directly. Instead, we will use APIs such as `nx.set_node_attributes` which properly clear the cache, so it's safe for us to use the cache. Because of that, we'll disable the warning so we don't see it on other graphs in this session." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "id": "Namb5JLvwS-q" + }, + "outputs": [], + "source": [ + "import warnings\n", + "warnings.filterwarnings(\"ignore\", message=\"Using cached graph for 'cugraph' backend\")" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "BzGAphcILFsT" + }, + "source": [ + "Smaller graphs are also easy to visualize with NetworkX's plotting utilities. The flexibility of NetworkX's `Graph` instances make it trivial to add the betweenness centrality scores back to the graph object as node attributes. This will allow us to use those values for the visualization.\n", + "\n", + "In this case, we'll create new attributes for each node called \"nx_bc\" for the default NetworkX results, and \"nxcg_bc\" for the nx-cugraph results. We'll use those values to assign the color for each node and plot two graphs side-by-side. This will make it easy to visually validate that the nodes with the higher centrality scores for both implementations match and do indeed appear to be more \"central\" to other nodes." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "id": "1coV6ZfcUoqI" + }, + "outputs": [], + "source": [ + "nx.set_node_attributes(G, nx_bc_results, \"nx_bc\")\n", + "nx.set_node_attributes(G, nxcg_bc_results, \"nxcg_bc\")" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "id": "Sba2iYJgLoN2" + }, + "outputs": [], + "source": [ + "# Configure plot size and layout/position for each node\n", + "import matplotlib.pyplot as plt\n", + "plt.rcParams['figure.figsize'] = [12, 8]\n", + "pos = nx.spring_layout(G)\n", + "\n", + "# Assign colors for each set of betweenness centrality results\n", + "nx_colors = [G.nodes[n][\"nx_bc\"] for n in G.nodes()]\n", + "nxcg_colors = [G.nodes[n][\"nxcg_bc\"] for n in G.nodes()]\n", + "\n", + "# Plot the graph and color each node corresponding to NetworkX betweenness centrality values\n", + "plt.subplot(1, 2, 1)\n", + "nx.draw(G, pos=pos, with_labels=True, node_color=nx_colors)\n", + "\n", + "# Plot the graph and color each node corresponding to nx-cugraph betweenness centrality values\n", + "plt.subplot(1, 2, 2)\n", + "nx.draw(G, pos=pos, with_labels=True, node_color=nxcg_colors)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "dJXH4Zn5VNSg" + }, + "source": [ + "As we can see, the same two nodes (`0` and `33`) are the two most central in both graphs, followed by `2`, `31`, and `32`.\n", + "\n", + "## PageRank\n", + "Another popular algorithm is [PageRank](https://en.wikipedia.org/wiki/PageRank). PageRank also assigns scores to each node, but these scores are based on analyzing links to each node to determine relative \"importance\" within the graph.\n", + "\n", + "Let's update the config to use the default NetworkX implementation and run `nx.pagerank`." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "id": "9CdYNk62E1v_" + }, + "outputs": [], + "source": [ + "nx.config.backend_priority=[]" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "id": "Jo39YxVmYolq" + }, + "outputs": [], + "source": [ + "%%time\n", + "nx_pr_results = nx.pagerank(G)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "sV6dM8ToZDiC" + }, + "source": [ + "We could set `nx.config.backend_priority` again to list `\"cugraph\"` as the backend, but let's instead show how the `backend` kwarg can be used to override the priority list and force a specific backend to be used." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "id": "oMSvQVGKY0rn" + }, + "outputs": [], + "source": [ + "%%time\n", + "nxcg_pr_results = nx.pagerank(G, backend=\"cugraph\")" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "ZGux_8xFZneI" + }, + "source": [ + "In this example, instead of plotting the graph to show that the results are identical, we can compare them directly using the saved values from both runs." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "id": "RcmtdFy4Zw7p" + }, + "outputs": [], + "source": [ + "sorted(nx_pr_results) == sorted(nxcg_pr_results)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "mefjUEAnZ4pq" + }, + "source": [ + "# Working with Bigger Data" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "yLY-yl6PuNYo" + }, + "source": [ + "Now we'll look at a larger dataset from https://snap.stanford.edu/data/cit-Patents.html which contains citations across different U.S. patents granted from January 1, 1963 to December 30, 1999. The dataset represents 16.5M citations (edges) between 3.77M patents (nodes).\n", + "\n", + "This will demonstrate that data of this size starts to push the limits of the default pure-Python NetworkX implementation." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "id": "lyYF0LbtFwjh" + }, + "outputs": [], + "source": [ + "# The locale encoding may have been modified from the plots above, reset here to run shell commands\n", + "import locale\n", + "locale.getpreferredencoding = lambda: \"UTF-8\"\n", + "!wget https://data.rapids.ai/cugraph/datasets/cit-Patents.csv # Skip if cit-Patents.csv already exists.\n", + "# !wget https://snap.stanford.edu/data/cit-Patents.txt.gz # Skip if cit-Patents.txt.gz already exists." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "id": "kjGINYphQSQ2" + }, + "outputs": [], + "source": [ + "%load_ext cudf.pandas\n", + "import pandas as pd" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "id": "iV4DieGZOalc" + }, + "outputs": [], + "source": [ + "%%time\n", + "df = pd.read_csv(\"cit-Patents.csv\",\n", + " sep=\" \",\n", + " names=[\"src\", \"dst\"],\n", + " dtype=\"int32\",\n", + ")\n", + "# df = pd.read_csv(\"cit-Patents.txt.gz\",\n", + "# compression=\"gzip\",\n", + "# skiprows=4,\n", + "# sep=\"\\t\",\n", + "# names=[\"src\", \"dst\"],\n", + "# dtype=\"int32\",\n", + "# )" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "id": "PREA67u4eKat" + }, + "outputs": [], + "source": [ + "%%time\n", + "G = nx.from_pandas_edgelist(df, source=\"src\", target=\"dst\")\n", + "G.number_of_nodes(), G.number_of_edges()" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "NcsUxBqpu4zY" + }, + "source": [ + "By default, `nx.betweenness_centrality` will perform an all-pairs shortest path analysis when determining the centrality scores for each node. However, due to the much larger size of this graph, determining the shortest path for all pairs of nodes in the graph is not feasible. Instead, we'll use the parameter `k` to limit the number of shortest path computations used for determining the centrality scores, at the expense of accuracy. As we'll see when using a dataset this size with `nx.betweenness_centrality`, we have to limit `k` to `1` which is not practical but is sufficient here for demonstration purposes (since anything larger than `1` will result in many minutes of execution time)." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "id": "gNDWbj3kAk3j" + }, + "outputs": [], + "source": [ + "%%time\n", + "bc_results = nx.betweenness_centrality(G, k=1)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "NB8xmxMd1PlX" + }, + "source": [ + "Now we'll configure NetworkX to use the `nx-cugraph` backend (again, using the name convention that drops the package name's `nx-` prefix) and run the same call. Because this is a Graph that `nx-cugraph` hasn't seen before, the runtime will include the time to convert and cache a GPU-based graph." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "id": "xUYNG1xhvbWc" + }, + "outputs": [], + "source": [ + "nx.config.backend_priority = [\"cugraph\"]" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "id": "cmK8ZuQGvfPo" + }, + "outputs": [], + "source": [ + "%%time\n", + "bc_results = nx.betweenness_centrality(G, k=1)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "vdHb1YXP15TZ" + }, + "source": [ + "Let's run betweenness centrality again, now with a more useful number of samples by setting `k=100`." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "id": "fKjIrzL-vrGS" + }, + "outputs": [], + "source": [ + "%%time\n", + "bc_results = nx.betweenness_centrality(G, k=100)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "QeMcrAX2HZSM" + }, + "source": [ + "Let's also run pagerank on the same dataset to compare." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "id": "gR8ID6ekHgHt" + }, + "outputs": [], + "source": [ + "nx.config.backend_priority = []" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "id": "rTFuvX5wb_c1" + }, + "outputs": [], + "source": [ + "%%time\n", + "nx_pr_results = nx.pagerank(G)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "id": "8sJx9aeJV9hv" + }, + "outputs": [], + "source": [ + "%%time\n", + "nxcg_pr_results = nx.pagerank(G, backend=\"cugraph\")" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "id": "wGOVQ6ZyY4Ih" + }, + "outputs": [], + "source": [ + "sorted(nx_pr_results) == sorted(nxcg_pr_results)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "k2DfAaZaDIBj" + }, + "source": [ + "---\n", + "\n", + "Information on the U.S. Patent Citation Network dataset used in this notebook is as follows:\n", + "
Authors: Jure Leskovec and Andrej Krevl\n", + "
Title: SNAP Datasets, Stanford Large Network Dataset Collection\n", + "
URL: http://snap.stanford.edu/data\n", + "
Date: June 2014\n", + "
\n" + ] + } + ], + "metadata": { + "accelerator": "GPU", + "colab": { + "gpuType": "T4", + "provenance": [] + }, + "kernelspec": { + "display_name": "Python 3", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.12.4" + } + }, + "nbformat": 4, + "nbformat_minor": 0 +} diff --git a/notebooks/demo/mg_pagerank.ipynb b/notebooks/demo/mg_pagerank.ipynb index bb333048450..e3314f80b3c 100644 --- a/notebooks/demo/mg_pagerank.ipynb +++ b/notebooks/demo/mg_pagerank.ipynb @@ -219,250 +219,250 @@ "text": [ "2023-05-12 09:25:01,974 - distributed.sizeof - WARNING - Sizeof calculation failed. Defaulting to 0.95 MiB\n", "Traceback (most recent call last):\n", - " File \"/home/dacosta/miniconda3/envs/cugraph_0411/lib/python3.10/site-packages/distributed/sizeof.py\", line 17, in safe_sizeof\n", + " File \"/home/dacosta/miniforge/envs/cugraph_0411/lib/python3.10/site-packages/distributed/sizeof.py\", line 17, in safe_sizeof\n", " return sizeof(obj)\n", - " File \"/home/dacosta/miniconda3/envs/cugraph_0411/lib/python3.10/site-packages/dask/utils.py\", line 642, in __call__\n", + " File \"/home/dacosta/miniforge/envs/cugraph_0411/lib/python3.10/site-packages/dask/utils.py\", line 642, in __call__\n", " return meth(arg, *args, **kwargs)\n", - " File \"/home/dacosta/miniconda3/envs/cugraph_0411/lib/python3.10/contextlib.py\", line 79, in inner\n", + " File \"/home/dacosta/miniforge/envs/cugraph_0411/lib/python3.10/contextlib.py\", line 79, in inner\n", " return func(*args, **kwds)\n", - " File \"/home/dacosta/miniconda3/envs/cugraph_0411/lib/python3.10/site-packages/dask_cudf/backends.py\", line 430, in sizeof_cudf_dataframe\n", + " File \"/home/dacosta/miniforge/envs/cugraph_0411/lib/python3.10/site-packages/dask_cudf/backends.py\", line 430, in sizeof_cudf_dataframe\n", " + df._index.memory_usage()\n", - " File \"/home/dacosta/miniconda3/envs/cugraph_0411/lib/python3.10/contextlib.py\", line 79, in inner\n", + " File \"/home/dacosta/miniforge/envs/cugraph_0411/lib/python3.10/contextlib.py\", line 79, in inner\n", " return func(*args, **kwds)\n", - " File \"/home/dacosta/miniconda3/envs/cugraph_0411/lib/python3.10/site-packages/cudf/core/multiindex.py\", line 1594, in memory_usage\n", + " File \"/home/dacosta/miniforge/envs/cugraph_0411/lib/python3.10/site-packages/cudf/core/multiindex.py\", line 1594, in memory_usage\n", " if self.levels:\n", - " File \"/home/dacosta/miniconda3/envs/cugraph_0411/lib/python3.10/contextlib.py\", line 79, in inner\n", + " File \"/home/dacosta/miniforge/envs/cugraph_0411/lib/python3.10/contextlib.py\", line 79, in inner\n", " return func(*args, **kwds)\n", - " File \"/home/dacosta/miniconda3/envs/cugraph_0411/lib/python3.10/site-packages/cudf/core/multiindex.py\", line 605, in levels\n", + " File \"/home/dacosta/miniforge/envs/cugraph_0411/lib/python3.10/site-packages/cudf/core/multiindex.py\", line 605, in levels\n", " self._compute_levels_and_codes()\n", - " File \"/home/dacosta/miniconda3/envs/cugraph_0411/lib/python3.10/contextlib.py\", line 79, in inner\n", + " File \"/home/dacosta/miniforge/envs/cugraph_0411/lib/python3.10/contextlib.py\", line 79, in inner\n", " return func(*args, **kwds)\n", - " File \"/home/dacosta/miniconda3/envs/cugraph_0411/lib/python3.10/site-packages/cudf/core/multiindex.py\", line 748, in _compute_levels_and_codes\n", + " File \"/home/dacosta/miniforge/envs/cugraph_0411/lib/python3.10/site-packages/cudf/core/multiindex.py\", line 748, in _compute_levels_and_codes\n", " code, cats = cudf.Series._from_data({None: col}).factorize()\n", - " File \"/home/dacosta/miniconda3/envs/cugraph_0411/lib/python3.10/contextlib.py\", line 79, in inner\n", + " File \"/home/dacosta/miniforge/envs/cugraph_0411/lib/python3.10/contextlib.py\", line 79, in inner\n", " return func(*args, **kwds)\n", - " File \"/home/dacosta/miniconda3/envs/cugraph_0411/lib/python3.10/site-packages/cudf/core/single_column_frame.py\", line 311, in factorize\n", + " File \"/home/dacosta/miniforge/envs/cugraph_0411/lib/python3.10/site-packages/cudf/core/single_column_frame.py\", line 311, in factorize\n", " return cudf.core.algorithms.factorize(\n", - " File \"/home/dacosta/miniconda3/envs/cugraph_0411/lib/python3.10/site-packages/cudf/core/algorithms.py\", line 138, in factorize\n", + " File \"/home/dacosta/miniforge/envs/cugraph_0411/lib/python3.10/site-packages/cudf/core/algorithms.py\", line 138, in factorize\n", " labels = values._column._label_encoding(\n", - " File \"/home/dacosta/miniconda3/envs/cugraph_0411/lib/python3.10/site-packages/cudf/core/column/column.py\", line 1385, in _label_encoding\n", + " File \"/home/dacosta/miniforge/envs/cugraph_0411/lib/python3.10/site-packages/cudf/core/column/column.py\", line 1385, in _label_encoding\n", " order = order.take(left_gather_map, check_bounds=False).argsort()\n", - " File \"/home/dacosta/miniconda3/envs/cugraph_0411/lib/python3.10/site-packages/cudf/core/column/column.py\", line 1101, in argsort\n", + " File \"/home/dacosta/miniforge/envs/cugraph_0411/lib/python3.10/site-packages/cudf/core/column/column.py\", line 1101, in argsort\n", " return self.as_frame()._get_sorted_inds(\n", - " File \"/home/dacosta/miniconda3/envs/cugraph_0411/lib/python3.10/site-packages/cudf/core/frame.py\", line 1572, in _get_sorted_inds\n", + " File \"/home/dacosta/miniforge/envs/cugraph_0411/lib/python3.10/site-packages/cudf/core/frame.py\", line 1572, in _get_sorted_inds\n", " return libcudf.sort.order_by(to_sort, ascending, na_position)\n", - " File \"/home/dacosta/miniconda3/envs/cugraph_0411/lib/python3.10/contextlib.py\", line 79, in inner\n", + " File \"/home/dacosta/miniforge/envs/cugraph_0411/lib/python3.10/contextlib.py\", line 79, in inner\n", " return func(*args, **kwds)\n", " File \"sort.pyx\", line 141, in cudf._lib.sort.order_by\n", - "MemoryError: std::bad_alloc: out_of_memory: CUDA error at: /home/dacosta/miniconda3/envs/cugraph_0411/include/rmm/mr/device/cuda_memory_resource.hpp\n", + "MemoryError: std::bad_alloc: out_of_memory: CUDA error at: /home/dacosta/miniforge/envs/cugraph_0411/include/rmm/mr/device/cuda_memory_resource.hpp\n", "2023-05-12 09:25:01,976 - distributed.sizeof - WARNING - Sizeof calculation failed. Defaulting to 0.95 MiB\n", "Traceback (most recent call last):\n", - " File \"/home/dacosta/miniconda3/envs/cugraph_0411/lib/python3.10/site-packages/distributed/sizeof.py\", line 17, in safe_sizeof\n", + " File \"/home/dacosta/miniforge/envs/cugraph_0411/lib/python3.10/site-packages/distributed/sizeof.py\", line 17, in safe_sizeof\n", " return sizeof(obj)\n", - " File \"/home/dacosta/miniconda3/envs/cugraph_0411/lib/python3.10/site-packages/dask/utils.py\", line 642, in __call__\n", + " File \"/home/dacosta/miniforge/envs/cugraph_0411/lib/python3.10/site-packages/dask/utils.py\", line 642, in __call__\n", " return meth(arg, *args, **kwargs)\n", - " File \"/home/dacosta/miniconda3/envs/cugraph_0411/lib/python3.10/contextlib.py\", line 79, in inner\n", + " File \"/home/dacosta/miniforge/envs/cugraph_0411/lib/python3.10/contextlib.py\", line 79, in inner\n", " return func(*args, **kwds)\n", - " File \"/home/dacosta/miniconda3/envs/cugraph_0411/lib/python3.10/site-packages/dask_cudf/backends.py\", line 430, in sizeof_cudf_dataframe\n", + " File \"/home/dacosta/miniforge/envs/cugraph_0411/lib/python3.10/site-packages/dask_cudf/backends.py\", line 430, in sizeof_cudf_dataframe\n", " + df._index.memory_usage()\n", - " File \"/home/dacosta/miniconda3/envs/cugraph_0411/lib/python3.10/contextlib.py\", line 79, in inner\n", + " File \"/home/dacosta/miniforge/envs/cugraph_0411/lib/python3.10/contextlib.py\", line 79, in inner\n", " return func(*args, **kwds)\n", - " File \"/home/dacosta/miniconda3/envs/cugraph_0411/lib/python3.10/site-packages/cudf/core/multiindex.py\", line 1594, in memory_usage\n", + " File \"/home/dacosta/miniforge/envs/cugraph_0411/lib/python3.10/site-packages/cudf/core/multiindex.py\", line 1594, in memory_usage\n", " if self.levels:\n", - " File \"/home/dacosta/miniconda3/envs/cugraph_0411/lib/python3.10/contextlib.py\", line 79, in inner\n", + " File \"/home/dacosta/miniforge/envs/cugraph_0411/lib/python3.10/contextlib.py\", line 79, in inner\n", " return func(*args, **kwds)\n", - " File \"/home/dacosta/miniconda3/envs/cugraph_0411/lib/python3.10/site-packages/cudf/core/multiindex.py\", line 605, in levels\n", + " File \"/home/dacosta/miniforge/envs/cugraph_0411/lib/python3.10/site-packages/cudf/core/multiindex.py\", line 605, in levels\n", " self._compute_levels_and_codes()\n", - " File \"/home/dacosta/miniconda3/envs/cugraph_0411/lib/python3.10/contextlib.py\", line 79, in inner\n", + " File \"/home/dacosta/miniforge/envs/cugraph_0411/lib/python3.10/contextlib.py\", line 79, in inner\n", " return func(*args, **kwds)\n", - " File \"/home/dacosta/miniconda3/envs/cugraph_0411/lib/python3.10/site-packages/cudf/core/multiindex.py\", line 748, in _compute_levels_and_codes\n", + " File \"/home/dacosta/miniforge/envs/cugraph_0411/lib/python3.10/site-packages/cudf/core/multiindex.py\", line 748, in _compute_levels_and_codes\n", " code, cats = cudf.Series._from_data({None: col}).factorize()\n", - " File \"/home/dacosta/miniconda3/envs/cugraph_0411/lib/python3.10/contextlib.py\", line 79, in inner\n", + " File \"/home/dacosta/miniforge/envs/cugraph_0411/lib/python3.10/contextlib.py\", line 79, in inner\n", " return func(*args, **kwds)\n", - " File \"/home/dacosta/miniconda3/envs/cugraph_0411/lib/python3.10/site-packages/cudf/core/single_column_frame.py\", line 311, in factorize\n", + " File \"/home/dacosta/miniforge/envs/cugraph_0411/lib/python3.10/site-packages/cudf/core/single_column_frame.py\", line 311, in factorize\n", " return cudf.core.algorithms.factorize(\n", - " File \"/home/dacosta/miniconda3/envs/cugraph_0411/lib/python3.10/site-packages/cudf/core/algorithms.py\", line 138, in factorize\n", + " File \"/home/dacosta/miniforge/envs/cugraph_0411/lib/python3.10/site-packages/cudf/core/algorithms.py\", line 138, in factorize\n", " labels = values._column._label_encoding(\n", - " File \"/home/dacosta/miniconda3/envs/cugraph_0411/lib/python3.10/site-packages/cudf/core/column/column.py\", line 1385, in _label_encoding\n", + " File \"/home/dacosta/miniforge/envs/cugraph_0411/lib/python3.10/site-packages/cudf/core/column/column.py\", line 1385, in _label_encoding\n", " order = order.take(left_gather_map, check_bounds=False).argsort()\n", - " File \"/home/dacosta/miniconda3/envs/cugraph_0411/lib/python3.10/site-packages/cudf/core/column/column.py\", line 1101, in argsort\n", + " File \"/home/dacosta/miniforge/envs/cugraph_0411/lib/python3.10/site-packages/cudf/core/column/column.py\", line 1101, in argsort\n", " return self.as_frame()._get_sorted_inds(\n", - " File \"/home/dacosta/miniconda3/envs/cugraph_0411/lib/python3.10/site-packages/cudf/core/frame.py\", line 1572, in _get_sorted_inds\n", + " File \"/home/dacosta/miniforge/envs/cugraph_0411/lib/python3.10/site-packages/cudf/core/frame.py\", line 1572, in _get_sorted_inds\n", " return libcudf.sort.order_by(to_sort, ascending, na_position)\n", - " File \"/home/dacosta/miniconda3/envs/cugraph_0411/lib/python3.10/contextlib.py\", line 79, in inner\n", + " File \"/home/dacosta/miniforge/envs/cugraph_0411/lib/python3.10/contextlib.py\", line 79, in inner\n", " return func(*args, **kwds)\n", " File \"sort.pyx\", line 141, in cudf._lib.sort.order_by\n", - "MemoryError: std::bad_alloc: out_of_memory: CUDA error at: /home/dacosta/miniconda3/envs/cugraph_0411/include/rmm/mr/device/cuda_memory_resource.hpp\n", + "MemoryError: std::bad_alloc: out_of_memory: CUDA error at: /home/dacosta/miniforge/envs/cugraph_0411/include/rmm/mr/device/cuda_memory_resource.hpp\n", "2023-05-12 09:25:03,767 - distributed.sizeof - WARNING - Sizeof calculation failed. Defaulting to 0.95 MiB\n", "Traceback (most recent call last):\n", - " File \"/home/dacosta/miniconda3/envs/cugraph_0411/lib/python3.10/site-packages/distributed/sizeof.py\", line 17, in safe_sizeof\n", + " File \"/home/dacosta/miniforge/envs/cugraph_0411/lib/python3.10/site-packages/distributed/sizeof.py\", line 17, in safe_sizeof\n", " return sizeof(obj)\n", - " File \"/home/dacosta/miniconda3/envs/cugraph_0411/lib/python3.10/site-packages/dask/utils.py\", line 642, in __call__\n", + " File \"/home/dacosta/miniforge/envs/cugraph_0411/lib/python3.10/site-packages/dask/utils.py\", line 642, in __call__\n", " return meth(arg, *args, **kwargs)\n", - " File \"/home/dacosta/miniconda3/envs/cugraph_0411/lib/python3.10/contextlib.py\", line 79, in inner\n", + " File \"/home/dacosta/miniforge/envs/cugraph_0411/lib/python3.10/contextlib.py\", line 79, in inner\n", " return func(*args, **kwds)\n", - " File \"/home/dacosta/miniconda3/envs/cugraph_0411/lib/python3.10/site-packages/dask_cudf/backends.py\", line 430, in sizeof_cudf_dataframe\n", + " File \"/home/dacosta/miniforge/envs/cugraph_0411/lib/python3.10/site-packages/dask_cudf/backends.py\", line 430, in sizeof_cudf_dataframe\n", " + df._index.memory_usage()\n", - " File \"/home/dacosta/miniconda3/envs/cugraph_0411/lib/python3.10/contextlib.py\", line 79, in inner\n", + " File \"/home/dacosta/miniforge/envs/cugraph_0411/lib/python3.10/contextlib.py\", line 79, in inner\n", " return func(*args, **kwds)\n", - " File \"/home/dacosta/miniconda3/envs/cugraph_0411/lib/python3.10/site-packages/cudf/core/multiindex.py\", line 1594, in memory_usage\n", + " File \"/home/dacosta/miniforge/envs/cugraph_0411/lib/python3.10/site-packages/cudf/core/multiindex.py\", line 1594, in memory_usage\n", " if self.levels:\n", - " File \"/home/dacosta/miniconda3/envs/cugraph_0411/lib/python3.10/contextlib.py\", line 79, in inner\n", + " File \"/home/dacosta/miniforge/envs/cugraph_0411/lib/python3.10/contextlib.py\", line 79, in inner\n", " return func(*args, **kwds)\n", - " File \"/home/dacosta/miniconda3/envs/cugraph_0411/lib/python3.10/site-packages/cudf/core/multiindex.py\", line 605, in levels\n", + " File \"/home/dacosta/miniforge/envs/cugraph_0411/lib/python3.10/site-packages/cudf/core/multiindex.py\", line 605, in levels\n", " self._compute_levels_and_codes()\n", - " File \"/home/dacosta/miniconda3/envs/cugraph_0411/lib/python3.10/contextlib.py\", line 79, in inner\n", + " File \"/home/dacosta/miniforge/envs/cugraph_0411/lib/python3.10/contextlib.py\", line 79, in inner\n", " return func(*args, **kwds)\n", - " File \"/home/dacosta/miniconda3/envs/cugraph_0411/lib/python3.10/site-packages/cudf/core/multiindex.py\", line 748, in _compute_levels_and_codes\n", + " File \"/home/dacosta/miniforge/envs/cugraph_0411/lib/python3.10/site-packages/cudf/core/multiindex.py\", line 748, in _compute_levels_and_codes\n", " code, cats = cudf.Series._from_data({None: col}).factorize()\n", - " File \"/home/dacosta/miniconda3/envs/cugraph_0411/lib/python3.10/contextlib.py\", line 79, in inner\n", + " File \"/home/dacosta/miniforge/envs/cugraph_0411/lib/python3.10/contextlib.py\", line 79, in inner\n", " return func(*args, **kwds)\n", - " File \"/home/dacosta/miniconda3/envs/cugraph_0411/lib/python3.10/site-packages/cudf/core/single_column_frame.py\", line 311, in factorize\n", + " File \"/home/dacosta/miniforge/envs/cugraph_0411/lib/python3.10/site-packages/cudf/core/single_column_frame.py\", line 311, in factorize\n", " return cudf.core.algorithms.factorize(\n", - " File \"/home/dacosta/miniconda3/envs/cugraph_0411/lib/python3.10/site-packages/cudf/core/algorithms.py\", line 138, in factorize\n", + " File \"/home/dacosta/miniforge/envs/cugraph_0411/lib/python3.10/site-packages/cudf/core/algorithms.py\", line 138, in factorize\n", " labels = values._column._label_encoding(\n", - " File \"/home/dacosta/miniconda3/envs/cugraph_0411/lib/python3.10/site-packages/cudf/core/column/column.py\", line 1385, in _label_encoding\n", + " File \"/home/dacosta/miniforge/envs/cugraph_0411/lib/python3.10/site-packages/cudf/core/column/column.py\", line 1385, in _label_encoding\n", " order = order.take(left_gather_map, check_bounds=False).argsort()\n", - " File \"/home/dacosta/miniconda3/envs/cugraph_0411/lib/python3.10/site-packages/cudf/core/column/column.py\", line 1101, in argsort\n", + " File \"/home/dacosta/miniforge/envs/cugraph_0411/lib/python3.10/site-packages/cudf/core/column/column.py\", line 1101, in argsort\n", " return self.as_frame()._get_sorted_inds(\n", - " File \"/home/dacosta/miniconda3/envs/cugraph_0411/lib/python3.10/site-packages/cudf/core/frame.py\", line 1572, in _get_sorted_inds\n", + " File \"/home/dacosta/miniforge/envs/cugraph_0411/lib/python3.10/site-packages/cudf/core/frame.py\", line 1572, in _get_sorted_inds\n", " return libcudf.sort.order_by(to_sort, ascending, na_position)\n", - " File \"/home/dacosta/miniconda3/envs/cugraph_0411/lib/python3.10/contextlib.py\", line 79, in inner\n", + " File \"/home/dacosta/miniforge/envs/cugraph_0411/lib/python3.10/contextlib.py\", line 79, in inner\n", " return func(*args, **kwds)\n", " File \"sort.pyx\", line 141, in cudf._lib.sort.order_by\n", - "MemoryError: std::bad_alloc: out_of_memory: CUDA error at: /home/dacosta/miniconda3/envs/cugraph_0411/include/rmm/mr/device/cuda_memory_resource.hpp\n", + "MemoryError: std::bad_alloc: out_of_memory: CUDA error at: /home/dacosta/miniforge/envs/cugraph_0411/include/rmm/mr/device/cuda_memory_resource.hpp\n", "2023-05-12 09:25:03,768 - distributed.sizeof - WARNING - Sizeof calculation failed. Defaulting to 0.95 MiB\n", "Traceback (most recent call last):\n", - " File \"/home/dacosta/miniconda3/envs/cugraph_0411/lib/python3.10/site-packages/distributed/sizeof.py\", line 17, in safe_sizeof\n", + " File \"/home/dacosta/miniforge/envs/cugraph_0411/lib/python3.10/site-packages/distributed/sizeof.py\", line 17, in safe_sizeof\n", " return sizeof(obj)\n", - " File \"/home/dacosta/miniconda3/envs/cugraph_0411/lib/python3.10/site-packages/dask/utils.py\", line 642, in __call__\n", + " File \"/home/dacosta/miniforge/envs/cugraph_0411/lib/python3.10/site-packages/dask/utils.py\", line 642, in __call__\n", " return meth(arg, *args, **kwargs)\n", - " File \"/home/dacosta/miniconda3/envs/cugraph_0411/lib/python3.10/contextlib.py\", line 79, in inner\n", + " File \"/home/dacosta/miniforge/envs/cugraph_0411/lib/python3.10/contextlib.py\", line 79, in inner\n", " return func(*args, **kwds)\n", - " File \"/home/dacosta/miniconda3/envs/cugraph_0411/lib/python3.10/site-packages/dask_cudf/backends.py\", line 430, in sizeof_cudf_dataframe\n", + " File \"/home/dacosta/miniforge/envs/cugraph_0411/lib/python3.10/site-packages/dask_cudf/backends.py\", line 430, in sizeof_cudf_dataframe\n", " + df._index.memory_usage()\n", - " File \"/home/dacosta/miniconda3/envs/cugraph_0411/lib/python3.10/contextlib.py\", line 79, in inner\n", + " File \"/home/dacosta/miniforge/envs/cugraph_0411/lib/python3.10/contextlib.py\", line 79, in inner\n", " return func(*args, **kwds)\n", - " File \"/home/dacosta/miniconda3/envs/cugraph_0411/lib/python3.10/site-packages/cudf/core/multiindex.py\", line 1594, in memory_usage\n", + " File \"/home/dacosta/miniforge/envs/cugraph_0411/lib/python3.10/site-packages/cudf/core/multiindex.py\", line 1594, in memory_usage\n", " if self.levels:\n", - " File \"/home/dacosta/miniconda3/envs/cugraph_0411/lib/python3.10/contextlib.py\", line 79, in inner\n", + " File \"/home/dacosta/miniforge/envs/cugraph_0411/lib/python3.10/contextlib.py\", line 79, in inner\n", " return func(*args, **kwds)\n", - " File \"/home/dacosta/miniconda3/envs/cugraph_0411/lib/python3.10/site-packages/cudf/core/multiindex.py\", line 605, in levels\n", + " File \"/home/dacosta/miniforge/envs/cugraph_0411/lib/python3.10/site-packages/cudf/core/multiindex.py\", line 605, in levels\n", " self._compute_levels_and_codes()\n", - " File \"/home/dacosta/miniconda3/envs/cugraph_0411/lib/python3.10/contextlib.py\", line 79, in inner\n", + " File \"/home/dacosta/miniforge/envs/cugraph_0411/lib/python3.10/contextlib.py\", line 79, in inner\n", " return func(*args, **kwds)\n", - " File \"/home/dacosta/miniconda3/envs/cugraph_0411/lib/python3.10/site-packages/cudf/core/multiindex.py\", line 748, in _compute_levels_and_codes\n", + " File \"/home/dacosta/miniforge/envs/cugraph_0411/lib/python3.10/site-packages/cudf/core/multiindex.py\", line 748, in _compute_levels_and_codes\n", " code, cats = cudf.Series._from_data({None: col}).factorize()\n", - " File \"/home/dacosta/miniconda3/envs/cugraph_0411/lib/python3.10/contextlib.py\", line 79, in inner\n", + " File \"/home/dacosta/miniforge/envs/cugraph_0411/lib/python3.10/contextlib.py\", line 79, in inner\n", " return func(*args, **kwds)\n", - " File \"/home/dacosta/miniconda3/envs/cugraph_0411/lib/python3.10/site-packages/cudf/core/single_column_frame.py\", line 311, in factorize\n", + " File \"/home/dacosta/miniforge/envs/cugraph_0411/lib/python3.10/site-packages/cudf/core/single_column_frame.py\", line 311, in factorize\n", " return cudf.core.algorithms.factorize(\n", - " File \"/home/dacosta/miniconda3/envs/cugraph_0411/lib/python3.10/site-packages/cudf/core/algorithms.py\", line 138, in factorize\n", + " File \"/home/dacosta/miniforge/envs/cugraph_0411/lib/python3.10/site-packages/cudf/core/algorithms.py\", line 138, in factorize\n", " labels = values._column._label_encoding(\n", - " File \"/home/dacosta/miniconda3/envs/cugraph_0411/lib/python3.10/site-packages/cudf/core/column/column.py\", line 1385, in _label_encoding\n", + " File \"/home/dacosta/miniforge/envs/cugraph_0411/lib/python3.10/site-packages/cudf/core/column/column.py\", line 1385, in _label_encoding\n", " order = order.take(left_gather_map, check_bounds=False).argsort()\n", - " File \"/home/dacosta/miniconda3/envs/cugraph_0411/lib/python3.10/site-packages/cudf/core/column/column.py\", line 1101, in argsort\n", + " File \"/home/dacosta/miniforge/envs/cugraph_0411/lib/python3.10/site-packages/cudf/core/column/column.py\", line 1101, in argsort\n", " return self.as_frame()._get_sorted_inds(\n", - " File \"/home/dacosta/miniconda3/envs/cugraph_0411/lib/python3.10/site-packages/cudf/core/frame.py\", line 1572, in _get_sorted_inds\n", + " File \"/home/dacosta/miniforge/envs/cugraph_0411/lib/python3.10/site-packages/cudf/core/frame.py\", line 1572, in _get_sorted_inds\n", " return libcudf.sort.order_by(to_sort, ascending, na_position)\n", - " File \"/home/dacosta/miniconda3/envs/cugraph_0411/lib/python3.10/contextlib.py\", line 79, in inner\n", + " File \"/home/dacosta/miniforge/envs/cugraph_0411/lib/python3.10/contextlib.py\", line 79, in inner\n", " return func(*args, **kwds)\n", " File \"sort.pyx\", line 141, in cudf._lib.sort.order_by\n", - "MemoryError: std::bad_alloc: out_of_memory: CUDA error at: /home/dacosta/miniconda3/envs/cugraph_0411/include/rmm/mr/device/cuda_memory_resource.hpp\n", + "MemoryError: std::bad_alloc: out_of_memory: CUDA error at: /home/dacosta/miniforge/envs/cugraph_0411/include/rmm/mr/device/cuda_memory_resource.hpp\n", "2023-05-12 09:25:03,820 - distributed.worker - ERROR - Could not deserialize task ('len-chunk-319fe46af5510615b2fae86c6e732896-841a12bf4568ebb80eb2030cc4d9651d', 1)\n", "Traceback (most recent call last):\n", - " File \"/home/dacosta/miniconda3/envs/cugraph_0411/lib/python3.10/site-packages/distributed/worker.py\", line 2923, in loads_function\n", + " File \"/home/dacosta/miniforge/envs/cugraph_0411/lib/python3.10/site-packages/distributed/worker.py\", line 2923, in loads_function\n", " result = cache_loads[bytes_object]\n", - " File \"/home/dacosta/miniconda3/envs/cugraph_0411/lib/python3.10/site-packages/distributed/collections.py\", line 24, in __getitem__\n", + " File \"/home/dacosta/miniforge/envs/cugraph_0411/lib/python3.10/site-packages/distributed/collections.py\", line 24, in __getitem__\n", " value = super().__getitem__(key)\n", - " File \"/home/dacosta/miniconda3/envs/cugraph_0411/lib/python3.10/collections/__init__.py\", line 1106, in __getitem__\n", + " File \"/home/dacosta/miniforge/envs/cugraph_0411/lib/python3.10/collections/__init__.py\", line 1106, in __getitem__\n", " raise KeyError(key)\n", "KeyError: b'\\x80\\x05\\x95>\\x0b\\x00\\x00\\x00\\x00\\x00\\x00\\x8c\\x11dask.optimization\\x94\\x8c\\x10SubgraphCallable\\x94\\x93\\x94(}\\x94(\\x8cKlen-chunk-319fe46af5510615b2fae86c6e732896-841a12bf4568ebb80eb2030cc4d9651d\\x94\\x8cZassign-getitem-len-chunk-319fe46af5510615b2fae86c6e732896-841a12bf4568ebb80eb2030cc4d9651d\\x94\\x8c*rename-01db283bd79fee66f232920c8dc6b55e_.0\\x94\\x8c;getitem-to_frame-rename-01db283bd79fee66f232920c8dc6b55e_.0\\x94\\x8c+getitem-3499fd71ac25ebbc1a06991edea6067c_.0\\x94\\x8c\\t_operator\\x94\\x8c\\x07getitem\\x94\\x93\\x94\\x8c/reset_index-f4c18304ca92859ccd09f44cf89b4b43_.0\\x94\\x8c\\x13__dask_blockwise__1\\x94\\x87\\x94h\\x0c(\\x8c\\ndask.utils\\x94\\x8c\\x05apply\\x94\\x93\\x94h\\x0f\\x8c\\x0cmethodcaller\\x94\\x93\\x94\\x8c\\x0breset_index\\x94\\x85\\x94R\\x94]\\x94\\x8c\\x13__dask_blockwise__5\\x94a\\x8c\\x08builtins\\x94\\x8c\\x04dict\\x94\\x93\\x94]\\x94]\\x94(\\x8c\\x04drop\\x94\\x89ea\\x86\\x94t\\x94h\\x07(h\\x11\\x8c\\x13dask.dataframe.core\\x94\\x8c\\x11apply_and_enforce\\x94\\x93\\x94]\\x94((h\\x11h#]\\x94h\\x0bh\\x0c\\x8c\\x13__dask_blockwise__0\\x94\\x87\\x94ah\\x1b]\\x94(]\\x94(\\x8c\\x05_func\\x94h\\x13\\x8c\\x08to_frame\\x94\\x85\\x94R\\x94e]\\x94(\\x8c\\x05_meta\\x94\\x8c\\x08builtins\\x94\\x8c\\x07getattr\\x94\\x93\\x94\\x8c\\x13cudf.core.dataframe\\x94\\x8c\\tDataFrame\\x94\\x93\\x94\\x8c\\x10host_deserialize\\x94\\x86\\x94R\\x94}\\x94(\\x8c\\x0ftype-serialized\\x94C0\\x80\\x04\\x95%\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x8c\\x13cudf.core.dataframe\\x94\\x8c\\tDataFrame\\x94\\x93\\x94.\\x94\\x8c\\x0ccolumn_names\\x94C\\x14\\x80\\x04\\x95\\t\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x8c\\x03src\\x94\\x85\\x94.\\x94\\x8c\\x07columns\\x94}\\x94(\\x8c\\x0ftype-serialized\\x94C=\\x80\\x04\\x952\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x8c\\x1acudf.core.column.numerical\\x94\\x8c\\x0fNumericalColumn\\x94\\x93\\x94.\\x94\\x8c\\x05dtype\\x94CB\\x80\\x04\\x957\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x8c\\x05numpy\\x94\\x8c\\x05dtype\\x94\\x93\\x94\\x8c\\x02i4\\x94\\x89\\x88\\x87\\x94R\\x94(K\\x03\\x8c\\x01<\\x94NNNJ\\xff\\xff\\xff\\xffJ\\xff\\xff\\xff\\xffK\\x00t\\x94b.\\x94\\x8c\\x18dtype-is-cudf-serialized\\x94\\x89\\x8c\\x04data\\x94}\\x94(\\x8c\\x0ftype-serialized\\x94CI\\x80\\x04\\x95>\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x8c!cudf.core.buffer.spillable_buffer\\x94\\x8c\\x14SpillableBufferSlice\\x94\\x93\\x94.\\x94\\x8c\\x0bframe_count\\x94K\\x01u\\x8c\\x04mask\\x94}\\x94(hGCD\\x80\\x04\\x959\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x8c!cudf.core.buffer.spillable_buffer\\x94\\x8c\\x0fSpillableBuffer\\x94\\x93\\x94.\\x94hIK\\x01u\\x8c\\x04size\\x94K\\x00hIK\\x02u\\x85\\x94\\x8c\\x05index\\x94}\\x94(\\x8c\\x0cindex_column\\x94}\\x94(\\x8c\\x05start\\x94K\\x00\\x8c\\x04stop\\x94K\\x00\\x8c\\x04step\\x94K\\x01u\\x8c\\x04name\\x94C\\x04\\x80\\x04N.\\x94hBCB\\x80\\x04\\x957\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x8c\\x05numpy\\x94\\x8c\\x05dtype\\x94\\x93\\x94\\x8c\\x02i8\\x94\\x89\\x88\\x87\\x94R\\x94(K\\x03\\x8c\\x01<\\x94NNNJ\\xff\\xff\\xff\\xffJ\\xff\\xff\\xff\\xffK\\x00t\\x94b.\\x94\\x8c\\x0ftype-serialized\\x94C-\\x80\\x04\\x95\"\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x8c\\x0fcudf.core.index\\x94\\x8c\\nRangeIndex\\x94\\x93\\x94.\\x94hIK\\x00u\\x8c\\x11index_frame_count\\x94K\\x00\\x8c\\x07is-cuda\\x94]\\x94(\\x88\\x88e\\x8c\\x07lengths\\x94]\\x94(K\\x00K\\x00e\\x8c\\twriteable\\x94NN\\x86\\x94u]\\x94(\\x8c\\x12numpy.core.numeric\\x94\\x8c\\x0b_frombuffer\\x94\\x93\\x94(C\\x00\\x94\\x8c\\x05numpy\\x94hB\\x93\\x94\\x8c\\x02u1\\x94\\x89\\x88\\x87\\x94R\\x94(K\\x03\\x8c\\x01|\\x94NNNJ\\xff\\xff\\xff\\xffJ\\xff\\xff\\xff\\xffK\\x00t\\x94bK\\x00\\x85\\x94\\x8c\\x01C\\x94t\\x94R\\x94he(C\\x00\\x94hkK\\x00\\x85\\x94hot\\x94R\\x94e\\x86\\x94R\\x94ee\\x86\\x94t\\x94\\x8c\\x13__dask_blockwise__2\\x94eh\\x1b]\\x94(]\\x94(h*h\\x13\\x8c\\x06rename\\x94\\x85\\x94R\\x94e]\\x94(h/h2h5h6\\x86\\x94R\\x94}\\x94(h:C0\\x80\\x04\\x95%\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x8c\\x13cudf.core.dataframe\\x94\\x8c\\tDataFrame\\x94\\x93\\x94.\\x94h}\\x94(h@C=\\x80\\x04\\x952\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x8c\\x1acudf.core.column.numerical\\x94\\x8c\\x0fNumericalColumn\\x94\\x93\\x94.\\x94hBCB\\x80\\x04\\x957\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x8c\\x05numpy\\x94\\x8c\\x05dtype\\x94\\x93\\x94\\x8c\\x02i4\\x94\\x89\\x88\\x87\\x94R\\x94(K\\x03\\x8c\\x01<\\x94NNNJ\\xff\\xff\\xff\\xffJ\\xff\\xff\\xff\\xffK\\x00t\\x94b.\\x94hD\\x89hE}\\x94(hGCI\\x80\\x04\\x95>\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x8c!cudf.core.buffer.spillable_buffer\\x94\\x8c\\x14SpillableBufferSlice\\x94\\x93\\x94.\\x94hIK\\x01uhMK\\x00hIK\\x01u\\x85\\x94hO}\\x94(hQ}\\x94(hSK\\x00hTK\\x00hUK\\x01uhVC\\x04\\x80\\x04N.\\x94hBCB\\x80\\x04\\x957\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x8c\\x05numpy\\x94\\x8c\\x05dtype\\x94\\x93\\x94\\x8c\\x02i8\\x94\\x89\\x88\\x87\\x94R\\x94(K\\x03\\x8c\\x01<\\x94NNNJ\\xff\\xff\\xff\\xffJ\\xff\\xff\\xff\\xffK\\x00t\\x94b.\\x94hYC-\\x80\\x04\\x95\"\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x8c\\x0fcudf.core.index\\x94\\x8c\\nRangeIndex\\x94\\x93\\x94.\\x94hIK\\x00uh[K\\x00h\\\\]\\x94\\x88ah^]\\x94K\\x00ah`N\\x85\\x94u]\\x94he(C\\x00\\x94hkK\\x00\\x85\\x94hot\\x94R\\x94a\\x86\\x94R\\x94e]\\x94(h>h\\x1b]\\x94]\\x94(\\x8c\\x03src\\x94h\\x9eea\\x86\\x94ee\\x86\\x94t\\x94h\\x05(h\\x11h!\\x8c\\x10_reduction_chunk\\x94\\x93\\x94]\\x94h\\x0b(\\x8c\\x16dask.dataframe.methods\\x94\\x8c\\x06assign\\x94\\x93\\x94h\\x06h\\rh\\x08t\\x94h&\\x87\\x94ah\\x1b]\\x94]\\x94(\\x8c\\taca_chunk\\x94h0\\x8c\\x03len\\x94\\x93\\x94ea\\x86\\x94t\\x94\\x8c\\x13__dask_blockwise__0\\x94h\\x9e\\x8c\\x13__dask_blockwise__1\\x94\\x8c\\x03dst\\x94\\x8c\\x13__dask_blockwise__2\\x94N\\x8c\\x13__dask_blockwise__3\\x94\\x8c)to_frame-804980ae30b71d28f0a6bd3d5b7610f9\\x94\\x8c\\x13__dask_blockwise__4\\x94\\x8c(getitem-15414b72be12e28054238b44933937ab\\x94\\x8c\\x13__dask_blockwise__6\\x94\\x8c3cudf-aggregate-agg-c50c2d97de169ca4f41e43a92a042630\\x94uh\\x04\\x8c\\x13__dask_blockwise__5\\x94\\x85\\x94\\x8c6subgraph_callable-b4ca530e-8895-432e-b553-40a7b5892ab2\\x94t\\x94R\\x94.'\n", "\n", "During handling of the above exception, another exception occurred:\n", "\n", "Traceback (most recent call last):\n", - " File \"/home/dacosta/miniconda3/envs/cugraph_0411/lib/python3.10/site-packages/distributed/worker.py\", line 2244, in execute\n", + " File \"/home/dacosta/miniforge/envs/cugraph_0411/lib/python3.10/site-packages/distributed/worker.py\", line 2244, in execute\n", " function, args, kwargs = await self._maybe_deserialize_task(ts)\n", - " File \"/home/dacosta/miniconda3/envs/cugraph_0411/lib/python3.10/site-packages/distributed/worker.py\", line 2216, in _maybe_deserialize_task\n", + " File \"/home/dacosta/miniforge/envs/cugraph_0411/lib/python3.10/site-packages/distributed/worker.py\", line 2216, in _maybe_deserialize_task\n", " function, args, kwargs = _deserialize(*ts.run_spec)\n", - " File \"/home/dacosta/miniconda3/envs/cugraph_0411/lib/python3.10/contextlib.py\", line 79, in inner\n", + " File \"/home/dacosta/miniforge/envs/cugraph_0411/lib/python3.10/contextlib.py\", line 79, in inner\n", " return func(*args, **kwds)\n", - " File \"/home/dacosta/miniconda3/envs/cugraph_0411/lib/python3.10/site-packages/distributed/worker.py\", line 2937, in _deserialize\n", + " File \"/home/dacosta/miniforge/envs/cugraph_0411/lib/python3.10/site-packages/distributed/worker.py\", line 2937, in _deserialize\n", " function = loads_function(function)\n", - " File \"/home/dacosta/miniconda3/envs/cugraph_0411/lib/python3.10/site-packages/distributed/worker.py\", line 2925, in loads_function\n", + " File \"/home/dacosta/miniforge/envs/cugraph_0411/lib/python3.10/site-packages/distributed/worker.py\", line 2925, in loads_function\n", " result = pickle.loads(bytes_object)\n", - " File \"/home/dacosta/miniconda3/envs/cugraph_0411/lib/python3.10/site-packages/distributed/protocol/pickle.py\", line 96, in loads\n", + " File \"/home/dacosta/miniforge/envs/cugraph_0411/lib/python3.10/site-packages/distributed/protocol/pickle.py\", line 96, in loads\n", " return pickle.loads(x)\n", - " File \"/home/dacosta/miniconda3/envs/cugraph_0411/lib/python3.10/site-packages/cudf/core/abc.py\", line 176, in host_deserialize\n", + " File \"/home/dacosta/miniforge/envs/cugraph_0411/lib/python3.10/site-packages/cudf/core/abc.py\", line 176, in host_deserialize\n", " obj = cls.device_deserialize(header, frames)\n", - " File \"/home/dacosta/miniconda3/envs/cugraph_0411/lib/python3.10/site-packages/cudf/core/abc.py\", line 130, in device_deserialize\n", + " File \"/home/dacosta/miniforge/envs/cugraph_0411/lib/python3.10/site-packages/cudf/core/abc.py\", line 130, in device_deserialize\n", " return typ.deserialize(header, frames)\n", - " File \"/home/dacosta/miniconda3/envs/cugraph_0411/lib/python3.10/site-packages/cudf/core/dataframe.py\", line 1019, in deserialize\n", + " File \"/home/dacosta/miniforge/envs/cugraph_0411/lib/python3.10/site-packages/cudf/core/dataframe.py\", line 1019, in deserialize\n", " obj = super().deserialize(\n", - " File \"/home/dacosta/miniconda3/envs/cugraph_0411/lib/python3.10/site-packages/cudf/core/frame.py\", line 106, in deserialize\n", + " File \"/home/dacosta/miniforge/envs/cugraph_0411/lib/python3.10/site-packages/cudf/core/frame.py\", line 106, in deserialize\n", " columns = deserialize_columns(header[\"columns\"], frames)\n", - " File \"/home/dacosta/miniconda3/envs/cugraph_0411/lib/python3.10/site-packages/cudf/core/column/column.py\", line 2450, in deserialize_columns\n", + " File \"/home/dacosta/miniforge/envs/cugraph_0411/lib/python3.10/site-packages/cudf/core/column/column.py\", line 2450, in deserialize_columns\n", " colobj = col_typ.deserialize(meta, frames[:col_frame_count])\n", - " File \"/home/dacosta/miniconda3/envs/cugraph_0411/lib/python3.10/site-packages/cudf/core/column/column.py\", line 1216, in deserialize\n", + " File \"/home/dacosta/miniforge/envs/cugraph_0411/lib/python3.10/site-packages/cudf/core/column/column.py\", line 1216, in deserialize\n", " data, frames = unpack(header[\"data\"], frames)\n", - " File \"/home/dacosta/miniconda3/envs/cugraph_0411/lib/python3.10/site-packages/cudf/core/column/column.py\", line 1204, in unpack\n", + " File \"/home/dacosta/miniforge/envs/cugraph_0411/lib/python3.10/site-packages/cudf/core/column/column.py\", line 1204, in unpack\n", " obj = klass.deserialize(header, frames[:count])\n", - " File \"/home/dacosta/miniconda3/envs/cugraph_0411/lib/python3.10/site-packages/cudf/core/buffer/spillable_buffer.py\", line 574, in deserialize\n", + " File \"/home/dacosta/miniforge/envs/cugraph_0411/lib/python3.10/site-packages/cudf/core/buffer/spillable_buffer.py\", line 574, in deserialize\n", " return SpillableBuffer.deserialize(header, frames)\n", - " File \"/home/dacosta/miniconda3/envs/cugraph_0411/lib/python3.10/site-packages/cudf/core/buffer/buffer.py\", line 335, in deserialize\n", + " File \"/home/dacosta/miniforge/envs/cugraph_0411/lib/python3.10/site-packages/cudf/core/buffer/buffer.py\", line 335, in deserialize\n", " return cls._from_device_memory(frame)\n", - " File \"/home/dacosta/miniconda3/envs/cugraph_0411/lib/python3.10/site-packages/cudf/core/buffer/spillable_buffer.py\", line 235, in _from_device_memory\n", + " File \"/home/dacosta/miniforge/envs/cugraph_0411/lib/python3.10/site-packages/cudf/core/buffer/spillable_buffer.py\", line 235, in _from_device_memory\n", " ret._finalize_init(ptr_desc={\"type\": \"gpu\"}, exposed=exposed)\n", - " File \"/home/dacosta/miniconda3/envs/cugraph_0411/lib/python3.10/site-packages/cudf/core/buffer/spillable_buffer.py\", line 206, in _finalize_init\n", + " File \"/home/dacosta/miniforge/envs/cugraph_0411/lib/python3.10/site-packages/cudf/core/buffer/spillable_buffer.py\", line 206, in _finalize_init\n", " raise ValueError(\n", "ValueError: cannot create without a global spill manager\n", "2023-05-12 09:25:03,817 - distributed.worker - ERROR - Could not deserialize task ('len-chunk-319fe46af5510615b2fae86c6e732896-841a12bf4568ebb80eb2030cc4d9651d', 0)\n", "Traceback (most recent call last):\n", - " File \"/home/dacosta/miniconda3/envs/cugraph_0411/lib/python3.10/site-packages/distributed/worker.py\", line 2923, in loads_function\n", + " File \"/home/dacosta/miniforge/envs/cugraph_0411/lib/python3.10/site-packages/distributed/worker.py\", line 2923, in loads_function\n", " result = cache_loads[bytes_object]\n", - " File \"/home/dacosta/miniconda3/envs/cugraph_0411/lib/python3.10/site-packages/distributed/collections.py\", line 24, in __getitem__\n", + " File \"/home/dacosta/miniforge/envs/cugraph_0411/lib/python3.10/site-packages/distributed/collections.py\", line 24, in __getitem__\n", " value = super().__getitem__(key)\n", - " File \"/home/dacosta/miniconda3/envs/cugraph_0411/lib/python3.10/collections/__init__.py\", line 1106, in __getitem__\n", + " File \"/home/dacosta/miniforge/envs/cugraph_0411/lib/python3.10/collections/__init__.py\", line 1106, in __getitem__\n", " raise KeyError(key)\n", "KeyError: b'\\x80\\x05\\x95>\\x0b\\x00\\x00\\x00\\x00\\x00\\x00\\x8c\\x11dask.optimization\\x94\\x8c\\x10SubgraphCallable\\x94\\x93\\x94(}\\x94(\\x8cKlen-chunk-319fe46af5510615b2fae86c6e732896-841a12bf4568ebb80eb2030cc4d9651d\\x94\\x8cZassign-getitem-len-chunk-319fe46af5510615b2fae86c6e732896-841a12bf4568ebb80eb2030cc4d9651d\\x94\\x8c*rename-01db283bd79fee66f232920c8dc6b55e_.0\\x94\\x8c;getitem-to_frame-rename-01db283bd79fee66f232920c8dc6b55e_.0\\x94\\x8c+getitem-3499fd71ac25ebbc1a06991edea6067c_.0\\x94\\x8c\\t_operator\\x94\\x8c\\x07getitem\\x94\\x93\\x94\\x8c/reset_index-f4c18304ca92859ccd09f44cf89b4b43_.0\\x94\\x8c\\x13__dask_blockwise__1\\x94\\x87\\x94h\\x0c(\\x8c\\ndask.utils\\x94\\x8c\\x05apply\\x94\\x93\\x94h\\x0f\\x8c\\x0cmethodcaller\\x94\\x93\\x94\\x8c\\x0breset_index\\x94\\x85\\x94R\\x94]\\x94\\x8c\\x13__dask_blockwise__5\\x94a\\x8c\\x08builtins\\x94\\x8c\\x04dict\\x94\\x93\\x94]\\x94]\\x94(\\x8c\\x04drop\\x94\\x89ea\\x86\\x94t\\x94h\\x07(h\\x11\\x8c\\x13dask.dataframe.core\\x94\\x8c\\x11apply_and_enforce\\x94\\x93\\x94]\\x94((h\\x11h#]\\x94h\\x0bh\\x0c\\x8c\\x13__dask_blockwise__0\\x94\\x87\\x94ah\\x1b]\\x94(]\\x94(\\x8c\\x05_func\\x94h\\x13\\x8c\\x08to_frame\\x94\\x85\\x94R\\x94e]\\x94(\\x8c\\x05_meta\\x94\\x8c\\x08builtins\\x94\\x8c\\x07getattr\\x94\\x93\\x94\\x8c\\x13cudf.core.dataframe\\x94\\x8c\\tDataFrame\\x94\\x93\\x94\\x8c\\x10host_deserialize\\x94\\x86\\x94R\\x94}\\x94(\\x8c\\x0ftype-serialized\\x94C0\\x80\\x04\\x95%\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x8c\\x13cudf.core.dataframe\\x94\\x8c\\tDataFrame\\x94\\x93\\x94.\\x94\\x8c\\x0ccolumn_names\\x94C\\x14\\x80\\x04\\x95\\t\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x8c\\x03src\\x94\\x85\\x94.\\x94\\x8c\\x07columns\\x94}\\x94(\\x8c\\x0ftype-serialized\\x94C=\\x80\\x04\\x952\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x8c\\x1acudf.core.column.numerical\\x94\\x8c\\x0fNumericalColumn\\x94\\x93\\x94.\\x94\\x8c\\x05dtype\\x94CB\\x80\\x04\\x957\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x8c\\x05numpy\\x94\\x8c\\x05dtype\\x94\\x93\\x94\\x8c\\x02i4\\x94\\x89\\x88\\x87\\x94R\\x94(K\\x03\\x8c\\x01<\\x94NNNJ\\xff\\xff\\xff\\xffJ\\xff\\xff\\xff\\xffK\\x00t\\x94b.\\x94\\x8c\\x18dtype-is-cudf-serialized\\x94\\x89\\x8c\\x04data\\x94}\\x94(\\x8c\\x0ftype-serialized\\x94CI\\x80\\x04\\x95>\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x8c!cudf.core.buffer.spillable_buffer\\x94\\x8c\\x14SpillableBufferSlice\\x94\\x93\\x94.\\x94\\x8c\\x0bframe_count\\x94K\\x01u\\x8c\\x04mask\\x94}\\x94(hGCD\\x80\\x04\\x959\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x8c!cudf.core.buffer.spillable_buffer\\x94\\x8c\\x0fSpillableBuffer\\x94\\x93\\x94.\\x94hIK\\x01u\\x8c\\x04size\\x94K\\x00hIK\\x02u\\x85\\x94\\x8c\\x05index\\x94}\\x94(\\x8c\\x0cindex_column\\x94}\\x94(\\x8c\\x05start\\x94K\\x00\\x8c\\x04stop\\x94K\\x00\\x8c\\x04step\\x94K\\x01u\\x8c\\x04name\\x94C\\x04\\x80\\x04N.\\x94hBCB\\x80\\x04\\x957\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x8c\\x05numpy\\x94\\x8c\\x05dtype\\x94\\x93\\x94\\x8c\\x02i8\\x94\\x89\\x88\\x87\\x94R\\x94(K\\x03\\x8c\\x01<\\x94NNNJ\\xff\\xff\\xff\\xffJ\\xff\\xff\\xff\\xffK\\x00t\\x94b.\\x94\\x8c\\x0ftype-serialized\\x94C-\\x80\\x04\\x95\"\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x8c\\x0fcudf.core.index\\x94\\x8c\\nRangeIndex\\x94\\x93\\x94.\\x94hIK\\x00u\\x8c\\x11index_frame_count\\x94K\\x00\\x8c\\x07is-cuda\\x94]\\x94(\\x88\\x88e\\x8c\\x07lengths\\x94]\\x94(K\\x00K\\x00e\\x8c\\twriteable\\x94NN\\x86\\x94u]\\x94(\\x8c\\x12numpy.core.numeric\\x94\\x8c\\x0b_frombuffer\\x94\\x93\\x94(C\\x00\\x94\\x8c\\x05numpy\\x94hB\\x93\\x94\\x8c\\x02u1\\x94\\x89\\x88\\x87\\x94R\\x94(K\\x03\\x8c\\x01|\\x94NNNJ\\xff\\xff\\xff\\xffJ\\xff\\xff\\xff\\xffK\\x00t\\x94bK\\x00\\x85\\x94\\x8c\\x01C\\x94t\\x94R\\x94he(C\\x00\\x94hkK\\x00\\x85\\x94hot\\x94R\\x94e\\x86\\x94R\\x94ee\\x86\\x94t\\x94\\x8c\\x13__dask_blockwise__2\\x94eh\\x1b]\\x94(]\\x94(h*h\\x13\\x8c\\x06rename\\x94\\x85\\x94R\\x94e]\\x94(h/h2h5h6\\x86\\x94R\\x94}\\x94(h:C0\\x80\\x04\\x95%\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x8c\\x13cudf.core.dataframe\\x94\\x8c\\tDataFrame\\x94\\x93\\x94.\\x94h}\\x94(h@C=\\x80\\x04\\x952\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x8c\\x1acudf.core.column.numerical\\x94\\x8c\\x0fNumericalColumn\\x94\\x93\\x94.\\x94hBCB\\x80\\x04\\x957\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x8c\\x05numpy\\x94\\x8c\\x05dtype\\x94\\x93\\x94\\x8c\\x02i4\\x94\\x89\\x88\\x87\\x94R\\x94(K\\x03\\x8c\\x01<\\x94NNNJ\\xff\\xff\\xff\\xffJ\\xff\\xff\\xff\\xffK\\x00t\\x94b.\\x94hD\\x89hE}\\x94(hGCI\\x80\\x04\\x95>\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x8c!cudf.core.buffer.spillable_buffer\\x94\\x8c\\x14SpillableBufferSlice\\x94\\x93\\x94.\\x94hIK\\x01uhMK\\x00hIK\\x01u\\x85\\x94hO}\\x94(hQ}\\x94(hSK\\x00hTK\\x00hUK\\x01uhVC\\x04\\x80\\x04N.\\x94hBCB\\x80\\x04\\x957\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x8c\\x05numpy\\x94\\x8c\\x05dtype\\x94\\x93\\x94\\x8c\\x02i8\\x94\\x89\\x88\\x87\\x94R\\x94(K\\x03\\x8c\\x01<\\x94NNNJ\\xff\\xff\\xff\\xffJ\\xff\\xff\\xff\\xffK\\x00t\\x94b.\\x94hYC-\\x80\\x04\\x95\"\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x8c\\x0fcudf.core.index\\x94\\x8c\\nRangeIndex\\x94\\x93\\x94.\\x94hIK\\x00uh[K\\x00h\\\\]\\x94\\x88ah^]\\x94K\\x00ah`N\\x85\\x94u]\\x94he(C\\x00\\x94hkK\\x00\\x85\\x94hot\\x94R\\x94a\\x86\\x94R\\x94e]\\x94(h>h\\x1b]\\x94]\\x94(\\x8c\\x03src\\x94h\\x9eea\\x86\\x94ee\\x86\\x94t\\x94h\\x05(h\\x11h!\\x8c\\x10_reduction_chunk\\x94\\x93\\x94]\\x94h\\x0b(\\x8c\\x16dask.dataframe.methods\\x94\\x8c\\x06assign\\x94\\x93\\x94h\\x06h\\rh\\x08t\\x94h&\\x87\\x94ah\\x1b]\\x94]\\x94(\\x8c\\taca_chunk\\x94h0\\x8c\\x03len\\x94\\x93\\x94ea\\x86\\x94t\\x94\\x8c\\x13__dask_blockwise__0\\x94h\\x9e\\x8c\\x13__dask_blockwise__1\\x94\\x8c\\x03dst\\x94\\x8c\\x13__dask_blockwise__2\\x94N\\x8c\\x13__dask_blockwise__3\\x94\\x8c)to_frame-804980ae30b71d28f0a6bd3d5b7610f9\\x94\\x8c\\x13__dask_blockwise__4\\x94\\x8c(getitem-15414b72be12e28054238b44933937ab\\x94\\x8c\\x13__dask_blockwise__6\\x94\\x8c3cudf-aggregate-agg-c50c2d97de169ca4f41e43a92a042630\\x94uh\\x04\\x8c\\x13__dask_blockwise__5\\x94\\x85\\x94\\x8c6subgraph_callable-b4ca530e-8895-432e-b553-40a7b5892ab2\\x94t\\x94R\\x94.'\n", "\n", "During handling of the above exception, another exception occurred:\n", "\n", "Traceback (most recent call last):\n", - " File \"/home/dacosta/miniconda3/envs/cugraph_0411/lib/python3.10/site-packages/distributed/worker.py\", line 2244, in execute\n", + " File \"/home/dacosta/miniforge/envs/cugraph_0411/lib/python3.10/site-packages/distributed/worker.py\", line 2244, in execute\n", " function, args, kwargs = await self._maybe_deserialize_task(ts)\n", - " File \"/home/dacosta/miniconda3/envs/cugraph_0411/lib/python3.10/site-packages/distributed/worker.py\", line 2216, in _maybe_deserialize_task\n", + " File \"/home/dacosta/miniforge/envs/cugraph_0411/lib/python3.10/site-packages/distributed/worker.py\", line 2216, in _maybe_deserialize_task\n", " function, args, kwargs = _deserialize(*ts.run_spec)\n", - " File \"/home/dacosta/miniconda3/envs/cugraph_0411/lib/python3.10/contextlib.py\", line 79, in inner\n", + " File \"/home/dacosta/miniforge/envs/cugraph_0411/lib/python3.10/contextlib.py\", line 79, in inner\n", " return func(*args, **kwds)\n", - " File \"/home/dacosta/miniconda3/envs/cugraph_0411/lib/python3.10/site-packages/distributed/worker.py\", line 2937, in _deserialize\n", + " File \"/home/dacosta/miniforge/envs/cugraph_0411/lib/python3.10/site-packages/distributed/worker.py\", line 2937, in _deserialize\n", " function = loads_function(function)\n", - " File \"/home/dacosta/miniconda3/envs/cugraph_0411/lib/python3.10/site-packages/distributed/worker.py\", line 2925, in loads_function\n", + " File \"/home/dacosta/miniforge/envs/cugraph_0411/lib/python3.10/site-packages/distributed/worker.py\", line 2925, in loads_function\n", " result = pickle.loads(bytes_object)\n", - " File \"/home/dacosta/miniconda3/envs/cugraph_0411/lib/python3.10/site-packages/distributed/protocol/pickle.py\", line 96, in loads\n", + " File \"/home/dacosta/miniforge/envs/cugraph_0411/lib/python3.10/site-packages/distributed/protocol/pickle.py\", line 96, in loads\n", " return pickle.loads(x)\n", - " File \"/home/dacosta/miniconda3/envs/cugraph_0411/lib/python3.10/site-packages/cudf/core/abc.py\", line 176, in host_deserialize\n", + " File \"/home/dacosta/miniforge/envs/cugraph_0411/lib/python3.10/site-packages/cudf/core/abc.py\", line 176, in host_deserialize\n", " obj = cls.device_deserialize(header, frames)\n", - " File \"/home/dacosta/miniconda3/envs/cugraph_0411/lib/python3.10/site-packages/cudf/core/abc.py\", line 130, in device_deserialize\n", + " File \"/home/dacosta/miniforge/envs/cugraph_0411/lib/python3.10/site-packages/cudf/core/abc.py\", line 130, in device_deserialize\n", " return typ.deserialize(header, frames)\n", - " File \"/home/dacosta/miniconda3/envs/cugraph_0411/lib/python3.10/site-packages/cudf/core/dataframe.py\", line 1019, in deserialize\n", + " File \"/home/dacosta/miniforge/envs/cugraph_0411/lib/python3.10/site-packages/cudf/core/dataframe.py\", line 1019, in deserialize\n", " obj = super().deserialize(\n", - " File \"/home/dacosta/miniconda3/envs/cugraph_0411/lib/python3.10/site-packages/cudf/core/frame.py\", line 106, in deserialize\n", + " File \"/home/dacosta/miniforge/envs/cugraph_0411/lib/python3.10/site-packages/cudf/core/frame.py\", line 106, in deserialize\n", " columns = deserialize_columns(header[\"columns\"], frames)\n", - " File \"/home/dacosta/miniconda3/envs/cugraph_0411/lib/python3.10/site-packages/cudf/core/column/column.py\", line 2450, in deserialize_columns\n", + " File \"/home/dacosta/miniforge/envs/cugraph_0411/lib/python3.10/site-packages/cudf/core/column/column.py\", line 2450, in deserialize_columns\n", " colobj = col_typ.deserialize(meta, frames[:col_frame_count])\n", - " File \"/home/dacosta/miniconda3/envs/cugraph_0411/lib/python3.10/site-packages/cudf/core/column/column.py\", line 1216, in deserialize\n", + " File \"/home/dacosta/miniforge/envs/cugraph_0411/lib/python3.10/site-packages/cudf/core/column/column.py\", line 1216, in deserialize\n", " data, frames = unpack(header[\"data\"], frames)\n", - " File \"/home/dacosta/miniconda3/envs/cugraph_0411/lib/python3.10/site-packages/cudf/core/column/column.py\", line 1204, in unpack\n", + " File \"/home/dacosta/miniforge/envs/cugraph_0411/lib/python3.10/site-packages/cudf/core/column/column.py\", line 1204, in unpack\n", " obj = klass.deserialize(header, frames[:count])\n", - " File \"/home/dacosta/miniconda3/envs/cugraph_0411/lib/python3.10/site-packages/cudf/core/buffer/spillable_buffer.py\", line 574, in deserialize\n", + " File \"/home/dacosta/miniforge/envs/cugraph_0411/lib/python3.10/site-packages/cudf/core/buffer/spillable_buffer.py\", line 574, in deserialize\n", " return SpillableBuffer.deserialize(header, frames)\n", - " File \"/home/dacosta/miniconda3/envs/cugraph_0411/lib/python3.10/site-packages/cudf/core/buffer/buffer.py\", line 335, in deserialize\n", + " File \"/home/dacosta/miniforge/envs/cugraph_0411/lib/python3.10/site-packages/cudf/core/buffer/buffer.py\", line 335, in deserialize\n", " return cls._from_device_memory(frame)\n", - " File \"/home/dacosta/miniconda3/envs/cugraph_0411/lib/python3.10/site-packages/cudf/core/buffer/spillable_buffer.py\", line 235, in _from_device_memory\n", + " File \"/home/dacosta/miniforge/envs/cugraph_0411/lib/python3.10/site-packages/cudf/core/buffer/spillable_buffer.py\", line 235, in _from_device_memory\n", " ret._finalize_init(ptr_desc={\"type\": \"gpu\"}, exposed=exposed)\n", - " File \"/home/dacosta/miniconda3/envs/cugraph_0411/lib/python3.10/site-packages/cudf/core/buffer/spillable_buffer.py\", line 206, in _finalize_init\n", + " File \"/home/dacosta/miniforge/envs/cugraph_0411/lib/python3.10/site-packages/cudf/core/buffer/spillable_buffer.py\", line 206, in _finalize_init\n", " raise ValueError(\n", "ValueError: cannot create without a global spill manager\n" ] @@ -475,34 +475,34 @@ "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", "\u001b[0;31mValueError\u001b[0m Traceback (most recent call last)", "Cell \u001b[0;32mIn[6], line 3\u001b[0m\n\u001b[1;32m 1\u001b[0m \u001b[39m# Create a directed graph using the source (src) and destination (dst) vertex pairs from the Dataframe \u001b[39;00m\n\u001b[1;32m 2\u001b[0m G \u001b[39m=\u001b[39m cugraph\u001b[39m.\u001b[39mGraph(directed\u001b[39m=\u001b[39m\u001b[39mTrue\u001b[39;00m)\n\u001b[0;32m----> 3\u001b[0m G\u001b[39m.\u001b[39;49mfrom_dask_cudf_edgelist(e_list, source\u001b[39m=\u001b[39;49m\u001b[39m'\u001b[39;49m\u001b[39msrc\u001b[39;49m\u001b[39m'\u001b[39;49m, destination\u001b[39m=\u001b[39;49m\u001b[39m'\u001b[39;49m\u001b[39mdst\u001b[39;49m\u001b[39m'\u001b[39;49m)\n\u001b[1;32m 5\u001b[0m \u001b[39m# Print time\u001b[39;00m\n\u001b[1;32m 6\u001b[0m \u001b[39mprint\u001b[39m(\u001b[39m\"\u001b[39m\u001b[39mRead, load and renumber: \u001b[39m\u001b[39m\"\u001b[39m, time\u001b[39m.\u001b[39mtime()\u001b[39m-\u001b[39mt_start, \u001b[39m\"\u001b[39m\u001b[39ms\u001b[39m\u001b[39m\"\u001b[39m)\n", - "File \u001b[0;32m~/miniconda3/envs/cugraph_0411/lib/python3.10/site-packages/cugraph/structure/graph_classes.py:309\u001b[0m, in \u001b[0;36mGraph.from_dask_cudf_edgelist\u001b[0;34m(self, input_ddf, source, destination, edge_attr, renumber, store_transposed, legacy_renum_only)\u001b[0m\n\u001b[1;32m 307\u001b[0m \u001b[39melif\u001b[39;00m \u001b[39mself\u001b[39m\u001b[39m.\u001b[39m_Impl\u001b[39m.\u001b[39medgelist \u001b[39mis\u001b[39;00m \u001b[39mnot\u001b[39;00m \u001b[39mNone\u001b[39;00m:\n\u001b[1;32m 308\u001b[0m \u001b[39mraise\u001b[39;00m \u001b[39mRuntimeError\u001b[39;00m(\u001b[39m\"\u001b[39m\u001b[39mGraph already has values\u001b[39m\u001b[39m\"\u001b[39m)\n\u001b[0;32m--> 309\u001b[0m \u001b[39mself\u001b[39;49m\u001b[39m.\u001b[39;49m_Impl\u001b[39m.\u001b[39;49m_simpleDistributedGraphImpl__from_edgelist(\n\u001b[1;32m 310\u001b[0m input_ddf,\n\u001b[1;32m 311\u001b[0m source,\n\u001b[1;32m 312\u001b[0m destination,\n\u001b[1;32m 313\u001b[0m edge_attr,\n\u001b[1;32m 314\u001b[0m renumber,\n\u001b[1;32m 315\u001b[0m store_transposed,\n\u001b[1;32m 316\u001b[0m legacy_renum_only,\n\u001b[1;32m 317\u001b[0m )\n", - "File \u001b[0;32m~/miniconda3/envs/cugraph_0411/lib/python3.10/site-packages/cugraph/structure/graph_implementation/simpleDistributedGraph.py:272\u001b[0m, in \u001b[0;36msimpleDistributedGraphImpl.__from_edgelist\u001b[0;34m(self, input_ddf, source, destination, edge_attr, renumber, store_transposed, legacy_renum_only)\u001b[0m\n\u001b[1;32m 268\u001b[0m dst_col_name \u001b[39m=\u001b[39m \u001b[39mself\u001b[39m\u001b[39m.\u001b[39mrenumber_map\u001b[39m.\u001b[39mrenumbered_dst_col_name\n\u001b[1;32m 270\u001b[0m ddf \u001b[39m=\u001b[39m \u001b[39mself\u001b[39m\u001b[39m.\u001b[39medgelist\u001b[39m.\u001b[39medgelist_df\n\u001b[0;32m--> 272\u001b[0m num_edges \u001b[39m=\u001b[39m \u001b[39mlen\u001b[39;49m(ddf)\n\u001b[1;32m 273\u001b[0m edge_data \u001b[39m=\u001b[39m get_distributed_data(ddf)\n\u001b[1;32m 275\u001b[0m graph_props \u001b[39m=\u001b[39m GraphProperties(\n\u001b[1;32m 276\u001b[0m is_multigraph\u001b[39m=\u001b[39m\u001b[39mself\u001b[39m\u001b[39m.\u001b[39mproperties\u001b[39m.\u001b[39mmulti_edge,\n\u001b[1;32m 277\u001b[0m is_symmetric\u001b[39m=\u001b[39m\u001b[39mnot\u001b[39;00m \u001b[39mself\u001b[39m\u001b[39m.\u001b[39mproperties\u001b[39m.\u001b[39mdirected,\n\u001b[1;32m 278\u001b[0m )\n", - "File \u001b[0;32m~/miniconda3/envs/cugraph_0411/lib/python3.10/site-packages/dask/dataframe/core.py:4775\u001b[0m, in \u001b[0;36mDataFrame.__len__\u001b[0;34m(self)\u001b[0m\n\u001b[1;32m 4773\u001b[0m \u001b[39mreturn\u001b[39;00m \u001b[39msuper\u001b[39m()\u001b[39m.\u001b[39m\u001b[39m__len__\u001b[39m()\n\u001b[1;32m 4774\u001b[0m \u001b[39melse\u001b[39;00m:\n\u001b[0;32m-> 4775\u001b[0m \u001b[39mreturn\u001b[39;00m \u001b[39mlen\u001b[39;49m(s)\n", - "File \u001b[0;32m~/miniconda3/envs/cugraph_0411/lib/python3.10/site-packages/dask/dataframe/core.py:843\u001b[0m, in \u001b[0;36m_Frame.__len__\u001b[0;34m(self)\u001b[0m\n\u001b[1;32m 840\u001b[0m \u001b[39mdef\u001b[39;00m \u001b[39m__len__\u001b[39m(\u001b[39mself\u001b[39m):\n\u001b[1;32m 841\u001b[0m \u001b[39mreturn\u001b[39;00m \u001b[39mself\u001b[39;49m\u001b[39m.\u001b[39;49mreduction(\n\u001b[1;32m 842\u001b[0m \u001b[39mlen\u001b[39;49m, np\u001b[39m.\u001b[39;49msum, token\u001b[39m=\u001b[39;49m\u001b[39m\"\u001b[39;49m\u001b[39mlen\u001b[39;49m\u001b[39m\"\u001b[39;49m, meta\u001b[39m=\u001b[39;49m\u001b[39mint\u001b[39;49m, split_every\u001b[39m=\u001b[39;49m\u001b[39mFalse\u001b[39;49;00m\n\u001b[0;32m--> 843\u001b[0m )\u001b[39m.\u001b[39;49mcompute()\n", - "File \u001b[0;32m~/miniconda3/envs/cugraph_0411/lib/python3.10/site-packages/dask/base.py:314\u001b[0m, in \u001b[0;36mDaskMethodsMixin.compute\u001b[0;34m(self, **kwargs)\u001b[0m\n\u001b[1;32m 290\u001b[0m \u001b[39mdef\u001b[39;00m \u001b[39mcompute\u001b[39m(\u001b[39mself\u001b[39m, \u001b[39m*\u001b[39m\u001b[39m*\u001b[39mkwargs):\n\u001b[1;32m 291\u001b[0m \u001b[39m \u001b[39m\u001b[39m\"\"\"Compute this dask collection\u001b[39;00m\n\u001b[1;32m 292\u001b[0m \n\u001b[1;32m 293\u001b[0m \u001b[39m This turns a lazy Dask collection into its in-memory equivalent.\u001b[39;00m\n\u001b[0;32m (...)\u001b[0m\n\u001b[1;32m 312\u001b[0m \u001b[39m dask.base.compute\u001b[39;00m\n\u001b[1;32m 313\u001b[0m \u001b[39m \"\"\"\u001b[39;00m\n\u001b[0;32m--> 314\u001b[0m (result,) \u001b[39m=\u001b[39m compute(\u001b[39mself\u001b[39;49m, traverse\u001b[39m=\u001b[39;49m\u001b[39mFalse\u001b[39;49;00m, \u001b[39m*\u001b[39;49m\u001b[39m*\u001b[39;49mkwargs)\n\u001b[1;32m 315\u001b[0m \u001b[39mreturn\u001b[39;00m result\n", - "File \u001b[0;32m~/miniconda3/envs/cugraph_0411/lib/python3.10/site-packages/dask/base.py:599\u001b[0m, in \u001b[0;36mcompute\u001b[0;34m(traverse, optimize_graph, scheduler, get, *args, **kwargs)\u001b[0m\n\u001b[1;32m 596\u001b[0m keys\u001b[39m.\u001b[39mappend(x\u001b[39m.\u001b[39m__dask_keys__())\n\u001b[1;32m 597\u001b[0m postcomputes\u001b[39m.\u001b[39mappend(x\u001b[39m.\u001b[39m__dask_postcompute__())\n\u001b[0;32m--> 599\u001b[0m results \u001b[39m=\u001b[39m schedule(dsk, keys, \u001b[39m*\u001b[39;49m\u001b[39m*\u001b[39;49mkwargs)\n\u001b[1;32m 600\u001b[0m \u001b[39mreturn\u001b[39;00m repack([f(r, \u001b[39m*\u001b[39ma) \u001b[39mfor\u001b[39;00m r, (f, a) \u001b[39min\u001b[39;00m \u001b[39mzip\u001b[39m(results, postcomputes)])\n", - "File \u001b[0;32m~/miniconda3/envs/cugraph_0411/lib/python3.10/site-packages/distributed/client.py:3186\u001b[0m, in \u001b[0;36mClient.get\u001b[0;34m(self, dsk, keys, workers, allow_other_workers, resources, sync, asynchronous, direct, retries, priority, fifo_timeout, actors, **kwargs)\u001b[0m\n\u001b[1;32m 3184\u001b[0m should_rejoin \u001b[39m=\u001b[39m \u001b[39mFalse\u001b[39;00m\n\u001b[1;32m 3185\u001b[0m \u001b[39mtry\u001b[39;00m:\n\u001b[0;32m-> 3186\u001b[0m results \u001b[39m=\u001b[39m \u001b[39mself\u001b[39;49m\u001b[39m.\u001b[39;49mgather(packed, asynchronous\u001b[39m=\u001b[39;49masynchronous, direct\u001b[39m=\u001b[39;49mdirect)\n\u001b[1;32m 3187\u001b[0m \u001b[39mfinally\u001b[39;00m:\n\u001b[1;32m 3188\u001b[0m \u001b[39mfor\u001b[39;00m f \u001b[39min\u001b[39;00m futures\u001b[39m.\u001b[39mvalues():\n", - "File \u001b[0;32m~/miniconda3/envs/cugraph_0411/lib/python3.10/site-packages/distributed/client.py:2345\u001b[0m, in \u001b[0;36mClient.gather\u001b[0;34m(self, futures, errors, direct, asynchronous)\u001b[0m\n\u001b[1;32m 2343\u001b[0m \u001b[39melse\u001b[39;00m:\n\u001b[1;32m 2344\u001b[0m local_worker \u001b[39m=\u001b[39m \u001b[39mNone\u001b[39;00m\n\u001b[0;32m-> 2345\u001b[0m \u001b[39mreturn\u001b[39;00m \u001b[39mself\u001b[39;49m\u001b[39m.\u001b[39;49msync(\n\u001b[1;32m 2346\u001b[0m \u001b[39mself\u001b[39;49m\u001b[39m.\u001b[39;49m_gather,\n\u001b[1;32m 2347\u001b[0m futures,\n\u001b[1;32m 2348\u001b[0m errors\u001b[39m=\u001b[39;49merrors,\n\u001b[1;32m 2349\u001b[0m direct\u001b[39m=\u001b[39;49mdirect,\n\u001b[1;32m 2350\u001b[0m local_worker\u001b[39m=\u001b[39;49mlocal_worker,\n\u001b[1;32m 2351\u001b[0m asynchronous\u001b[39m=\u001b[39;49masynchronous,\n\u001b[1;32m 2352\u001b[0m )\n", - "File \u001b[0;32m~/miniconda3/envs/cugraph_0411/lib/python3.10/site-packages/distributed/utils.py:349\u001b[0m, in \u001b[0;36mSyncMethodMixin.sync\u001b[0;34m(self, func, asynchronous, callback_timeout, *args, **kwargs)\u001b[0m\n\u001b[1;32m 347\u001b[0m \u001b[39mreturn\u001b[39;00m future\n\u001b[1;32m 348\u001b[0m \u001b[39melse\u001b[39;00m:\n\u001b[0;32m--> 349\u001b[0m \u001b[39mreturn\u001b[39;00m sync(\n\u001b[1;32m 350\u001b[0m \u001b[39mself\u001b[39;49m\u001b[39m.\u001b[39;49mloop, func, \u001b[39m*\u001b[39;49margs, callback_timeout\u001b[39m=\u001b[39;49mcallback_timeout, \u001b[39m*\u001b[39;49m\u001b[39m*\u001b[39;49mkwargs\n\u001b[1;32m 351\u001b[0m )\n", - "File \u001b[0;32m~/miniconda3/envs/cugraph_0411/lib/python3.10/site-packages/distributed/utils.py:416\u001b[0m, in \u001b[0;36msync\u001b[0;34m(loop, func, callback_timeout, *args, **kwargs)\u001b[0m\n\u001b[1;32m 414\u001b[0m \u001b[39mif\u001b[39;00m error:\n\u001b[1;32m 415\u001b[0m typ, exc, tb \u001b[39m=\u001b[39m error\n\u001b[0;32m--> 416\u001b[0m \u001b[39mraise\u001b[39;00m exc\u001b[39m.\u001b[39mwith_traceback(tb)\n\u001b[1;32m 417\u001b[0m \u001b[39melse\u001b[39;00m:\n\u001b[1;32m 418\u001b[0m \u001b[39mreturn\u001b[39;00m result\n", - "File \u001b[0;32m~/miniconda3/envs/cugraph_0411/lib/python3.10/site-packages/distributed/utils.py:389\u001b[0m, in \u001b[0;36msync..f\u001b[0;34m()\u001b[0m\n\u001b[1;32m 387\u001b[0m future \u001b[39m=\u001b[39m wait_for(future, callback_timeout)\n\u001b[1;32m 388\u001b[0m future \u001b[39m=\u001b[39m asyncio\u001b[39m.\u001b[39mensure_future(future)\n\u001b[0;32m--> 389\u001b[0m result \u001b[39m=\u001b[39m \u001b[39myield\u001b[39;00m future\n\u001b[1;32m 390\u001b[0m \u001b[39mexcept\u001b[39;00m \u001b[39mException\u001b[39;00m:\n\u001b[1;32m 391\u001b[0m error \u001b[39m=\u001b[39m sys\u001b[39m.\u001b[39mexc_info()\n", - "File \u001b[0;32m~/miniconda3/envs/cugraph_0411/lib/python3.10/site-packages/tornado/gen.py:769\u001b[0m, in \u001b[0;36mRunner.run\u001b[0;34m(self)\u001b[0m\n\u001b[1;32m 766\u001b[0m exc_info \u001b[39m=\u001b[39m \u001b[39mNone\u001b[39;00m\n\u001b[1;32m 768\u001b[0m \u001b[39mtry\u001b[39;00m:\n\u001b[0;32m--> 769\u001b[0m value \u001b[39m=\u001b[39m future\u001b[39m.\u001b[39;49mresult()\n\u001b[1;32m 770\u001b[0m \u001b[39mexcept\u001b[39;00m \u001b[39mException\u001b[39;00m:\n\u001b[1;32m 771\u001b[0m exc_info \u001b[39m=\u001b[39m sys\u001b[39m.\u001b[39mexc_info()\n", - "File \u001b[0;32m~/miniconda3/envs/cugraph_0411/lib/python3.10/site-packages/distributed/client.py:2208\u001b[0m, in \u001b[0;36mClient._gather\u001b[0;34m(self, futures, errors, direct, local_worker)\u001b[0m\n\u001b[1;32m 2206\u001b[0m exc \u001b[39m=\u001b[39m CancelledError(key)\n\u001b[1;32m 2207\u001b[0m \u001b[39melse\u001b[39;00m:\n\u001b[0;32m-> 2208\u001b[0m \u001b[39mraise\u001b[39;00m exception\u001b[39m.\u001b[39mwith_traceback(traceback)\n\u001b[1;32m 2209\u001b[0m \u001b[39mraise\u001b[39;00m exc\n\u001b[1;32m 2210\u001b[0m \u001b[39mif\u001b[39;00m errors \u001b[39m==\u001b[39m \u001b[39m\"\u001b[39m\u001b[39mskip\u001b[39m\u001b[39m\"\u001b[39m:\n", - "File \u001b[0;32m~/miniconda3/envs/cugraph_0411/lib/python3.10/contextlib.py:79\u001b[0m, in \u001b[0;36minner\u001b[0;34m()\u001b[0m\n\u001b[1;32m 76\u001b[0m \u001b[39m@wraps\u001b[39m(func)\n\u001b[1;32m 77\u001b[0m \u001b[39mdef\u001b[39;00m \u001b[39minner\u001b[39m(\u001b[39m*\u001b[39margs, \u001b[39m*\u001b[39m\u001b[39m*\u001b[39mkwds):\n\u001b[1;32m 78\u001b[0m \u001b[39mwith\u001b[39;00m \u001b[39mself\u001b[39m\u001b[39m.\u001b[39m_recreate_cm():\n\u001b[0;32m---> 79\u001b[0m \u001b[39mreturn\u001b[39;00m func(\u001b[39m*\u001b[39margs, \u001b[39m*\u001b[39m\u001b[39m*\u001b[39mkwds)\n", - "File \u001b[0;32m~/miniconda3/envs/cugraph_0411/lib/python3.10/site-packages/distributed/worker.py:2937\u001b[0m, in \u001b[0;36m_deserialize\u001b[0;34m()\u001b[0m\n\u001b[1;32m 2934\u001b[0m \u001b[39m# Some objects require threadlocal state during deserialization, e.g. to\u001b[39;00m\n\u001b[1;32m 2935\u001b[0m \u001b[39m# detect the current worker\u001b[39;00m\n\u001b[1;32m 2936\u001b[0m \u001b[39mif\u001b[39;00m function \u001b[39mis\u001b[39;00m \u001b[39mnot\u001b[39;00m \u001b[39mNone\u001b[39;00m:\n\u001b[0;32m-> 2937\u001b[0m function \u001b[39m=\u001b[39m loads_function(function)\n\u001b[1;32m 2938\u001b[0m \u001b[39mif\u001b[39;00m args \u001b[39mand\u001b[39;00m \u001b[39misinstance\u001b[39m(args, \u001b[39mbytes\u001b[39m):\n\u001b[1;32m 2939\u001b[0m args \u001b[39m=\u001b[39m pickle\u001b[39m.\u001b[39mloads(args)\n", - "File \u001b[0;32m~/miniconda3/envs/cugraph_0411/lib/python3.10/site-packages/distributed/worker.py:2925\u001b[0m, in \u001b[0;36mloads_function\u001b[0;34m()\u001b[0m\n\u001b[1;32m 2923\u001b[0m result \u001b[39m=\u001b[39m cache_loads[bytes_object]\n\u001b[1;32m 2924\u001b[0m \u001b[39mexcept\u001b[39;00m \u001b[39mKeyError\u001b[39;00m:\n\u001b[0;32m-> 2925\u001b[0m result \u001b[39m=\u001b[39m pickle\u001b[39m.\u001b[39mloads(bytes_object)\n\u001b[1;32m 2926\u001b[0m cache_loads[bytes_object] \u001b[39m=\u001b[39m result\n\u001b[1;32m 2927\u001b[0m \u001b[39mreturn\u001b[39;00m result\n", - "File \u001b[0;32m~/miniconda3/envs/cugraph_0411/lib/python3.10/site-packages/distributed/protocol/pickle.py:96\u001b[0m, in \u001b[0;36mloads\u001b[0;34m()\u001b[0m\n\u001b[1;32m 94\u001b[0m \u001b[39mreturn\u001b[39;00m pickle\u001b[39m.\u001b[39mloads(x, buffers\u001b[39m=\u001b[39mbuffers)\n\u001b[1;32m 95\u001b[0m \u001b[39melse\u001b[39;00m:\n\u001b[0;32m---> 96\u001b[0m \u001b[39mreturn\u001b[39;00m pickle\u001b[39m.\u001b[39mloads(x)\n\u001b[1;32m 97\u001b[0m \u001b[39mexcept\u001b[39;00m \u001b[39mException\u001b[39;00m:\n\u001b[1;32m 98\u001b[0m logger\u001b[39m.\u001b[39minfo(\u001b[39m\"\u001b[39m\u001b[39mFailed to deserialize \u001b[39m\u001b[39m%s\u001b[39;00m\u001b[39m\"\u001b[39m, x[:\u001b[39m10000\u001b[39m], exc_info\u001b[39m=\u001b[39m\u001b[39mTrue\u001b[39;00m)\n", - "File \u001b[0;32m~/miniconda3/envs/cugraph_0411/lib/python3.10/site-packages/cudf/core/abc.py:176\u001b[0m, in \u001b[0;36mhost_deserialize\u001b[0;34m()\u001b[0m\n\u001b[1;32m 154\u001b[0m \u001b[39m\u001b[39m\u001b[39m\"\"\"Perform device-side deserialization tasks.\u001b[39;00m\n\u001b[1;32m 155\u001b[0m \n\u001b[1;32m 156\u001b[0m \u001b[39mParameters\u001b[39;00m\n\u001b[0;32m (...)\u001b[0m\n\u001b[1;32m 170\u001b[0m \u001b[39m:meta private:\u001b[39;00m\n\u001b[1;32m 171\u001b[0m \u001b[39m\"\"\"\u001b[39;00m\n\u001b[1;32m 172\u001b[0m frames \u001b[39m=\u001b[39m [\n\u001b[1;32m 173\u001b[0m cudf\u001b[39m.\u001b[39mcore\u001b[39m.\u001b[39mbuffer\u001b[39m.\u001b[39mas_buffer(f) \u001b[39mif\u001b[39;00m c \u001b[39melse\u001b[39;00m f\n\u001b[1;32m 174\u001b[0m \u001b[39mfor\u001b[39;00m c, f \u001b[39min\u001b[39;00m \u001b[39mzip\u001b[39m(header[\u001b[39m\"\u001b[39m\u001b[39mis-cuda\u001b[39m\u001b[39m\"\u001b[39m], \u001b[39mmap\u001b[39m(\u001b[39mmemoryview\u001b[39m, frames))\n\u001b[1;32m 175\u001b[0m ]\n\u001b[0;32m--> 176\u001b[0m obj \u001b[39m=\u001b[39m \u001b[39mcls\u001b[39m\u001b[39m.\u001b[39mdevice_deserialize(header, frames)\n\u001b[1;32m 177\u001b[0m \u001b[39mreturn\u001b[39;00m obj\n", - "File \u001b[0;32m~/miniconda3/envs/cugraph_0411/lib/python3.10/site-packages/cudf/core/abc.py:130\u001b[0m, in \u001b[0;36mdevice_deserialize\u001b[0;34m()\u001b[0m\n\u001b[1;32m 125\u001b[0m typ \u001b[39m=\u001b[39m pickle\u001b[39m.\u001b[39mloads(header[\u001b[39m\"\u001b[39m\u001b[39mtype-serialized\u001b[39m\u001b[39m\"\u001b[39m])\n\u001b[1;32m 126\u001b[0m frames \u001b[39m=\u001b[39m [\n\u001b[1;32m 127\u001b[0m cudf\u001b[39m.\u001b[39mcore\u001b[39m.\u001b[39mbuffer\u001b[39m.\u001b[39mas_buffer(f) \u001b[39mif\u001b[39;00m c \u001b[39melse\u001b[39;00m \u001b[39mmemoryview\u001b[39m(f)\n\u001b[1;32m 128\u001b[0m \u001b[39mfor\u001b[39;00m c, f \u001b[39min\u001b[39;00m \u001b[39mzip\u001b[39m(header[\u001b[39m\"\u001b[39m\u001b[39mis-cuda\u001b[39m\u001b[39m\"\u001b[39m], frames)\n\u001b[1;32m 129\u001b[0m ]\n\u001b[0;32m--> 130\u001b[0m \u001b[39mreturn\u001b[39;00m typ\u001b[39m.\u001b[39mdeserialize(header, frames)\n", - "File \u001b[0;32m~/miniconda3/envs/cugraph_0411/lib/python3.10/site-packages/cudf/core/dataframe.py:1019\u001b[0m, in \u001b[0;36mdeserialize\u001b[0;34m()\u001b[0m\n\u001b[1;32m 1016\u001b[0m \u001b[39m@classmethod\u001b[39m\n\u001b[1;32m 1017\u001b[0m \u001b[39mdef\u001b[39;00m \u001b[39mdeserialize\u001b[39m(\u001b[39mcls\u001b[39m, header, frames):\n\u001b[1;32m 1018\u001b[0m index_nframes \u001b[39m=\u001b[39m header[\u001b[39m\"\u001b[39m\u001b[39mindex_frame_count\u001b[39m\u001b[39m\"\u001b[39m]\n\u001b[0;32m-> 1019\u001b[0m obj \u001b[39m=\u001b[39m \u001b[39msuper\u001b[39m()\u001b[39m.\u001b[39mdeserialize(\n\u001b[1;32m 1020\u001b[0m header, frames[header[\u001b[39m\"\u001b[39m\u001b[39mindex_frame_count\u001b[39m\u001b[39m\"\u001b[39m] :]\n\u001b[1;32m 1021\u001b[0m )\n\u001b[1;32m 1023\u001b[0m idx_typ \u001b[39m=\u001b[39m pickle\u001b[39m.\u001b[39mloads(header[\u001b[39m\"\u001b[39m\u001b[39mindex\u001b[39m\u001b[39m\"\u001b[39m][\u001b[39m\"\u001b[39m\u001b[39mtype-serialized\u001b[39m\u001b[39m\"\u001b[39m])\n\u001b[1;32m 1024\u001b[0m index \u001b[39m=\u001b[39m idx_typ\u001b[39m.\u001b[39mdeserialize(header[\u001b[39m\"\u001b[39m\u001b[39mindex\u001b[39m\u001b[39m\"\u001b[39m], frames[:index_nframes])\n", - "File \u001b[0;32m~/miniconda3/envs/cugraph_0411/lib/python3.10/site-packages/cudf/core/frame.py:106\u001b[0m, in \u001b[0;36mdeserialize\u001b[0;34m()\u001b[0m\n\u001b[1;32m 104\u001b[0m cls_deserialize \u001b[39m=\u001b[39m pickle\u001b[39m.\u001b[39mloads(header[\u001b[39m\"\u001b[39m\u001b[39mtype-serialized\u001b[39m\u001b[39m\"\u001b[39m])\n\u001b[1;32m 105\u001b[0m column_names \u001b[39m=\u001b[39m pickle\u001b[39m.\u001b[39mloads(header[\u001b[39m\"\u001b[39m\u001b[39mcolumn_names\u001b[39m\u001b[39m\"\u001b[39m])\n\u001b[0;32m--> 106\u001b[0m columns \u001b[39m=\u001b[39m deserialize_columns(header[\u001b[39m\"\u001b[39m\u001b[39mcolumns\u001b[39m\u001b[39m\"\u001b[39m], frames)\n\u001b[1;32m 107\u001b[0m \u001b[39mreturn\u001b[39;00m cls_deserialize\u001b[39m.\u001b[39m_from_data(\u001b[39mdict\u001b[39m(\u001b[39mzip\u001b[39m(column_names, columns)))\n", - "File \u001b[0;32m~/miniconda3/envs/cugraph_0411/lib/python3.10/site-packages/cudf/core/column/column.py:2450\u001b[0m, in \u001b[0;36mdeserialize_columns\u001b[0;34m()\u001b[0m\n\u001b[1;32m 2448\u001b[0m col_frame_count \u001b[39m=\u001b[39m meta[\u001b[39m\"\u001b[39m\u001b[39mframe_count\u001b[39m\u001b[39m\"\u001b[39m]\n\u001b[1;32m 2449\u001b[0m col_typ \u001b[39m=\u001b[39m pickle\u001b[39m.\u001b[39mloads(meta[\u001b[39m\"\u001b[39m\u001b[39mtype-serialized\u001b[39m\u001b[39m\"\u001b[39m])\n\u001b[0;32m-> 2450\u001b[0m colobj \u001b[39m=\u001b[39m col_typ\u001b[39m.\u001b[39mdeserialize(meta, frames[:col_frame_count])\n\u001b[1;32m 2451\u001b[0m columns\u001b[39m.\u001b[39mappend(colobj)\n\u001b[1;32m 2452\u001b[0m \u001b[39m# Advance frames\u001b[39;00m\n", - "File \u001b[0;32m~/miniconda3/envs/cugraph_0411/lib/python3.10/site-packages/cudf/core/column/column.py:1216\u001b[0m, in \u001b[0;36mdeserialize\u001b[0;34m()\u001b[0m\n\u001b[1;32m 1214\u001b[0m dtype \u001b[39m=\u001b[39m pickle\u001b[39m.\u001b[39mloads(header[\u001b[39m\"\u001b[39m\u001b[39mdtype\u001b[39m\u001b[39m\"\u001b[39m])\n\u001b[1;32m 1215\u001b[0m \u001b[39mif\u001b[39;00m \u001b[39m\"\u001b[39m\u001b[39mdata\u001b[39m\u001b[39m\"\u001b[39m \u001b[39min\u001b[39;00m header:\n\u001b[0;32m-> 1216\u001b[0m data, frames \u001b[39m=\u001b[39m unpack(header[\u001b[39m\"\u001b[39m\u001b[39mdata\u001b[39m\u001b[39m\"\u001b[39m], frames)\n\u001b[1;32m 1217\u001b[0m \u001b[39melse\u001b[39;00m:\n\u001b[1;32m 1218\u001b[0m data \u001b[39m=\u001b[39m \u001b[39mNone\u001b[39;00m\n", - "File \u001b[0;32m~/miniconda3/envs/cugraph_0411/lib/python3.10/site-packages/cudf/core/column/column.py:1204\u001b[0m, in \u001b[0;36munpack\u001b[0;34m()\u001b[0m\n\u001b[1;32m 1202\u001b[0m count \u001b[39m=\u001b[39m header[\u001b[39m\"\u001b[39m\u001b[39mframe_count\u001b[39m\u001b[39m\"\u001b[39m]\n\u001b[1;32m 1203\u001b[0m klass \u001b[39m=\u001b[39m pickle\u001b[39m.\u001b[39mloads(header[\u001b[39m\"\u001b[39m\u001b[39mtype-serialized\u001b[39m\u001b[39m\"\u001b[39m])\n\u001b[0;32m-> 1204\u001b[0m obj \u001b[39m=\u001b[39m klass\u001b[39m.\u001b[39mdeserialize(header, frames[:count])\n\u001b[1;32m 1205\u001b[0m \u001b[39mreturn\u001b[39;00m obj, frames[count:]\n", - "File \u001b[0;32m~/miniconda3/envs/cugraph_0411/lib/python3.10/site-packages/cudf/core/buffer/spillable_buffer.py:574\u001b[0m, in \u001b[0;36mdeserialize\u001b[0;34m()\u001b[0m\n\u001b[1;32m 567\u001b[0m \u001b[39m@classmethod\u001b[39m\n\u001b[1;32m 568\u001b[0m \u001b[39mdef\u001b[39;00m \u001b[39mdeserialize\u001b[39m(\u001b[39mcls\u001b[39m, header: \u001b[39mdict\u001b[39m, frames: \u001b[39mlist\u001b[39m):\n\u001b[1;32m 569\u001b[0m \u001b[39m# TODO: because of the hack in `SpillableBuffer.serialize()` where\u001b[39;00m\n\u001b[0;32m (...)\u001b[0m\n\u001b[1;32m 572\u001b[0m \u001b[39m# deserialize into `SpillableBufferSlice` when the frames hasn't been\u001b[39;00m\n\u001b[1;32m 573\u001b[0m \u001b[39m# copied.\u001b[39;00m\n\u001b[0;32m--> 574\u001b[0m \u001b[39mreturn\u001b[39;00m SpillableBuffer\u001b[39m.\u001b[39mdeserialize(header, frames)\n", - "File \u001b[0;32m~/miniconda3/envs/cugraph_0411/lib/python3.10/site-packages/cudf/core/buffer/buffer.py:335\u001b[0m, in \u001b[0;36mdeserialize\u001b[0;34m()\u001b[0m\n\u001b[1;32m 332\u001b[0m \u001b[39mreturn\u001b[39;00m frame \u001b[39m# The frame is already deserialized\u001b[39;00m\n\u001b[1;32m 334\u001b[0m \u001b[39mif\u001b[39;00m \u001b[39mhasattr\u001b[39m(frame, \u001b[39m\"\u001b[39m\u001b[39m__cuda_array_interface__\u001b[39m\u001b[39m\"\u001b[39m):\n\u001b[0;32m--> 335\u001b[0m \u001b[39mreturn\u001b[39;00m \u001b[39mcls\u001b[39m\u001b[39m.\u001b[39m_from_device_memory(frame)\n\u001b[1;32m 336\u001b[0m \u001b[39mreturn\u001b[39;00m \u001b[39mcls\u001b[39m\u001b[39m.\u001b[39m_from_host_memory(frame)\n", - "File \u001b[0;32m~/miniconda3/envs/cugraph_0411/lib/python3.10/site-packages/cudf/core/buffer/spillable_buffer.py:235\u001b[0m, in \u001b[0;36m_from_device_memory\u001b[0;34m()\u001b[0m\n\u001b[1;32m 218\u001b[0m \u001b[39m\u001b[39m\u001b[39m\"\"\"Create a spillabe buffer from device memory.\u001b[39;00m\n\u001b[1;32m 219\u001b[0m \n\u001b[1;32m 220\u001b[0m \u001b[39mNo data is being copied.\u001b[39;00m\n\u001b[0;32m (...)\u001b[0m\n\u001b[1;32m 232\u001b[0m \u001b[39m Buffer representing the same device memory as `data`\u001b[39;00m\n\u001b[1;32m 233\u001b[0m \u001b[39m\"\"\"\u001b[39;00m\n\u001b[1;32m 234\u001b[0m ret \u001b[39m=\u001b[39m \u001b[39msuper\u001b[39m()\u001b[39m.\u001b[39m_from_device_memory(data)\n\u001b[0;32m--> 235\u001b[0m ret\u001b[39m.\u001b[39m_finalize_init(ptr_desc\u001b[39m=\u001b[39m{\u001b[39m\"\u001b[39m\u001b[39mtype\u001b[39m\u001b[39m\"\u001b[39m: \u001b[39m\"\u001b[39m\u001b[39mgpu\u001b[39m\u001b[39m\"\u001b[39m}, exposed\u001b[39m=\u001b[39mexposed)\n\u001b[1;32m 236\u001b[0m \u001b[39mreturn\u001b[39;00m ret\n", - "File \u001b[0;32m~/miniconda3/envs/cugraph_0411/lib/python3.10/site-packages/cudf/core/buffer/spillable_buffer.py:206\u001b[0m, in \u001b[0;36m_finalize_init\u001b[0;34m()\u001b[0m\n\u001b[1;32m 204\u001b[0m manager \u001b[39m=\u001b[39m get_global_manager()\n\u001b[1;32m 205\u001b[0m \u001b[39mif\u001b[39;00m manager \u001b[39mis\u001b[39;00m \u001b[39mNone\u001b[39;00m:\n\u001b[0;32m--> 206\u001b[0m \u001b[39mraise\u001b[39;00m \u001b[39mValueError\u001b[39;00m(\n\u001b[1;32m 207\u001b[0m \u001b[39mf\u001b[39m\u001b[39m\"\u001b[39m\u001b[39mcannot create \u001b[39m\u001b[39m{\u001b[39;00m\u001b[39mself\u001b[39m\u001b[39m.\u001b[39m\u001b[39m__class__\u001b[39m\u001b[39m}\u001b[39;00m\u001b[39m without \u001b[39m\u001b[39m\"\u001b[39m\n\u001b[1;32m 208\u001b[0m \u001b[39m\"\u001b[39m\u001b[39ma global spill manager\u001b[39m\u001b[39m\"\u001b[39m\n\u001b[1;32m 209\u001b[0m )\n\u001b[1;32m 211\u001b[0m \u001b[39mself\u001b[39m\u001b[39m.\u001b[39m_manager \u001b[39m=\u001b[39m manager\n\u001b[1;32m 212\u001b[0m \u001b[39mself\u001b[39m\u001b[39m.\u001b[39m_manager\u001b[39m.\u001b[39madd(\u001b[39mself\u001b[39m)\n", + "File \u001b[0;32m~/miniforge/envs/cugraph_0411/lib/python3.10/site-packages/cugraph/structure/graph_classes.py:309\u001b[0m, in \u001b[0;36mGraph.from_dask_cudf_edgelist\u001b[0;34m(self, input_ddf, source, destination, edge_attr, renumber, store_transposed, legacy_renum_only)\u001b[0m\n\u001b[1;32m 307\u001b[0m \u001b[39melif\u001b[39;00m \u001b[39mself\u001b[39m\u001b[39m.\u001b[39m_Impl\u001b[39m.\u001b[39medgelist \u001b[39mis\u001b[39;00m \u001b[39mnot\u001b[39;00m \u001b[39mNone\u001b[39;00m:\n\u001b[1;32m 308\u001b[0m \u001b[39mraise\u001b[39;00m \u001b[39mRuntimeError\u001b[39;00m(\u001b[39m\"\u001b[39m\u001b[39mGraph already has values\u001b[39m\u001b[39m\"\u001b[39m)\n\u001b[0;32m--> 309\u001b[0m \u001b[39mself\u001b[39;49m\u001b[39m.\u001b[39;49m_Impl\u001b[39m.\u001b[39;49m_simpleDistributedGraphImpl__from_edgelist(\n\u001b[1;32m 310\u001b[0m input_ddf,\n\u001b[1;32m 311\u001b[0m source,\n\u001b[1;32m 312\u001b[0m destination,\n\u001b[1;32m 313\u001b[0m edge_attr,\n\u001b[1;32m 314\u001b[0m renumber,\n\u001b[1;32m 315\u001b[0m store_transposed,\n\u001b[1;32m 316\u001b[0m legacy_renum_only,\n\u001b[1;32m 317\u001b[0m )\n", + "File \u001b[0;32m~/miniforge/envs/cugraph_0411/lib/python3.10/site-packages/cugraph/structure/graph_implementation/simpleDistributedGraph.py:272\u001b[0m, in \u001b[0;36msimpleDistributedGraphImpl.__from_edgelist\u001b[0;34m(self, input_ddf, source, destination, edge_attr, renumber, store_transposed, legacy_renum_only)\u001b[0m\n\u001b[1;32m 268\u001b[0m dst_col_name \u001b[39m=\u001b[39m \u001b[39mself\u001b[39m\u001b[39m.\u001b[39mrenumber_map\u001b[39m.\u001b[39mrenumbered_dst_col_name\n\u001b[1;32m 270\u001b[0m ddf \u001b[39m=\u001b[39m \u001b[39mself\u001b[39m\u001b[39m.\u001b[39medgelist\u001b[39m.\u001b[39medgelist_df\n\u001b[0;32m--> 272\u001b[0m num_edges \u001b[39m=\u001b[39m \u001b[39mlen\u001b[39;49m(ddf)\n\u001b[1;32m 273\u001b[0m edge_data \u001b[39m=\u001b[39m get_distributed_data(ddf)\n\u001b[1;32m 275\u001b[0m graph_props \u001b[39m=\u001b[39m GraphProperties(\n\u001b[1;32m 276\u001b[0m is_multigraph\u001b[39m=\u001b[39m\u001b[39mself\u001b[39m\u001b[39m.\u001b[39mproperties\u001b[39m.\u001b[39mmulti_edge,\n\u001b[1;32m 277\u001b[0m is_symmetric\u001b[39m=\u001b[39m\u001b[39mnot\u001b[39;00m \u001b[39mself\u001b[39m\u001b[39m.\u001b[39mproperties\u001b[39m.\u001b[39mdirected,\n\u001b[1;32m 278\u001b[0m )\n", + "File \u001b[0;32m~/miniforge/envs/cugraph_0411/lib/python3.10/site-packages/dask/dataframe/core.py:4775\u001b[0m, in \u001b[0;36mDataFrame.__len__\u001b[0;34m(self)\u001b[0m\n\u001b[1;32m 4773\u001b[0m \u001b[39mreturn\u001b[39;00m \u001b[39msuper\u001b[39m()\u001b[39m.\u001b[39m\u001b[39m__len__\u001b[39m()\n\u001b[1;32m 4774\u001b[0m \u001b[39melse\u001b[39;00m:\n\u001b[0;32m-> 4775\u001b[0m \u001b[39mreturn\u001b[39;00m \u001b[39mlen\u001b[39;49m(s)\n", + "File \u001b[0;32m~/miniforge/envs/cugraph_0411/lib/python3.10/site-packages/dask/dataframe/core.py:843\u001b[0m, in \u001b[0;36m_Frame.__len__\u001b[0;34m(self)\u001b[0m\n\u001b[1;32m 840\u001b[0m \u001b[39mdef\u001b[39;00m \u001b[39m__len__\u001b[39m(\u001b[39mself\u001b[39m):\n\u001b[1;32m 841\u001b[0m \u001b[39mreturn\u001b[39;00m \u001b[39mself\u001b[39;49m\u001b[39m.\u001b[39;49mreduction(\n\u001b[1;32m 842\u001b[0m \u001b[39mlen\u001b[39;49m, np\u001b[39m.\u001b[39;49msum, token\u001b[39m=\u001b[39;49m\u001b[39m\"\u001b[39;49m\u001b[39mlen\u001b[39;49m\u001b[39m\"\u001b[39;49m, meta\u001b[39m=\u001b[39;49m\u001b[39mint\u001b[39;49m, split_every\u001b[39m=\u001b[39;49m\u001b[39mFalse\u001b[39;49;00m\n\u001b[0;32m--> 843\u001b[0m )\u001b[39m.\u001b[39;49mcompute()\n", + "File \u001b[0;32m~/miniforge/envs/cugraph_0411/lib/python3.10/site-packages/dask/base.py:314\u001b[0m, in \u001b[0;36mDaskMethodsMixin.compute\u001b[0;34m(self, **kwargs)\u001b[0m\n\u001b[1;32m 290\u001b[0m \u001b[39mdef\u001b[39;00m \u001b[39mcompute\u001b[39m(\u001b[39mself\u001b[39m, \u001b[39m*\u001b[39m\u001b[39m*\u001b[39mkwargs):\n\u001b[1;32m 291\u001b[0m \u001b[39m \u001b[39m\u001b[39m\"\"\"Compute this dask collection\u001b[39;00m\n\u001b[1;32m 292\u001b[0m \n\u001b[1;32m 293\u001b[0m \u001b[39m This turns a lazy Dask collection into its in-memory equivalent.\u001b[39;00m\n\u001b[0;32m (...)\u001b[0m\n\u001b[1;32m 312\u001b[0m \u001b[39m dask.base.compute\u001b[39;00m\n\u001b[1;32m 313\u001b[0m \u001b[39m \"\"\"\u001b[39;00m\n\u001b[0;32m--> 314\u001b[0m (result,) \u001b[39m=\u001b[39m compute(\u001b[39mself\u001b[39;49m, traverse\u001b[39m=\u001b[39;49m\u001b[39mFalse\u001b[39;49;00m, \u001b[39m*\u001b[39;49m\u001b[39m*\u001b[39;49mkwargs)\n\u001b[1;32m 315\u001b[0m \u001b[39mreturn\u001b[39;00m result\n", + "File \u001b[0;32m~/miniforge/envs/cugraph_0411/lib/python3.10/site-packages/dask/base.py:599\u001b[0m, in \u001b[0;36mcompute\u001b[0;34m(traverse, optimize_graph, scheduler, get, *args, **kwargs)\u001b[0m\n\u001b[1;32m 596\u001b[0m keys\u001b[39m.\u001b[39mappend(x\u001b[39m.\u001b[39m__dask_keys__())\n\u001b[1;32m 597\u001b[0m postcomputes\u001b[39m.\u001b[39mappend(x\u001b[39m.\u001b[39m__dask_postcompute__())\n\u001b[0;32m--> 599\u001b[0m results \u001b[39m=\u001b[39m schedule(dsk, keys, \u001b[39m*\u001b[39;49m\u001b[39m*\u001b[39;49mkwargs)\n\u001b[1;32m 600\u001b[0m \u001b[39mreturn\u001b[39;00m repack([f(r, \u001b[39m*\u001b[39ma) \u001b[39mfor\u001b[39;00m r, (f, a) \u001b[39min\u001b[39;00m \u001b[39mzip\u001b[39m(results, postcomputes)])\n", + "File \u001b[0;32m~/miniforge/envs/cugraph_0411/lib/python3.10/site-packages/distributed/client.py:3186\u001b[0m, in \u001b[0;36mClient.get\u001b[0;34m(self, dsk, keys, workers, allow_other_workers, resources, sync, asynchronous, direct, retries, priority, fifo_timeout, actors, **kwargs)\u001b[0m\n\u001b[1;32m 3184\u001b[0m should_rejoin \u001b[39m=\u001b[39m \u001b[39mFalse\u001b[39;00m\n\u001b[1;32m 3185\u001b[0m \u001b[39mtry\u001b[39;00m:\n\u001b[0;32m-> 3186\u001b[0m results \u001b[39m=\u001b[39m \u001b[39mself\u001b[39;49m\u001b[39m.\u001b[39;49mgather(packed, asynchronous\u001b[39m=\u001b[39;49masynchronous, direct\u001b[39m=\u001b[39;49mdirect)\n\u001b[1;32m 3187\u001b[0m \u001b[39mfinally\u001b[39;00m:\n\u001b[1;32m 3188\u001b[0m \u001b[39mfor\u001b[39;00m f \u001b[39min\u001b[39;00m futures\u001b[39m.\u001b[39mvalues():\n", + "File \u001b[0;32m~/miniforge/envs/cugraph_0411/lib/python3.10/site-packages/distributed/client.py:2345\u001b[0m, in \u001b[0;36mClient.gather\u001b[0;34m(self, futures, errors, direct, asynchronous)\u001b[0m\n\u001b[1;32m 2343\u001b[0m \u001b[39melse\u001b[39;00m:\n\u001b[1;32m 2344\u001b[0m local_worker \u001b[39m=\u001b[39m \u001b[39mNone\u001b[39;00m\n\u001b[0;32m-> 2345\u001b[0m \u001b[39mreturn\u001b[39;00m \u001b[39mself\u001b[39;49m\u001b[39m.\u001b[39;49msync(\n\u001b[1;32m 2346\u001b[0m \u001b[39mself\u001b[39;49m\u001b[39m.\u001b[39;49m_gather,\n\u001b[1;32m 2347\u001b[0m futures,\n\u001b[1;32m 2348\u001b[0m errors\u001b[39m=\u001b[39;49merrors,\n\u001b[1;32m 2349\u001b[0m direct\u001b[39m=\u001b[39;49mdirect,\n\u001b[1;32m 2350\u001b[0m local_worker\u001b[39m=\u001b[39;49mlocal_worker,\n\u001b[1;32m 2351\u001b[0m asynchronous\u001b[39m=\u001b[39;49masynchronous,\n\u001b[1;32m 2352\u001b[0m )\n", + "File \u001b[0;32m~/miniforge/envs/cugraph_0411/lib/python3.10/site-packages/distributed/utils.py:349\u001b[0m, in \u001b[0;36mSyncMethodMixin.sync\u001b[0;34m(self, func, asynchronous, callback_timeout, *args, **kwargs)\u001b[0m\n\u001b[1;32m 347\u001b[0m \u001b[39mreturn\u001b[39;00m future\n\u001b[1;32m 348\u001b[0m \u001b[39melse\u001b[39;00m:\n\u001b[0;32m--> 349\u001b[0m \u001b[39mreturn\u001b[39;00m sync(\n\u001b[1;32m 350\u001b[0m \u001b[39mself\u001b[39;49m\u001b[39m.\u001b[39;49mloop, func, \u001b[39m*\u001b[39;49margs, callback_timeout\u001b[39m=\u001b[39;49mcallback_timeout, \u001b[39m*\u001b[39;49m\u001b[39m*\u001b[39;49mkwargs\n\u001b[1;32m 351\u001b[0m )\n", + "File \u001b[0;32m~/miniforge/envs/cugraph_0411/lib/python3.10/site-packages/distributed/utils.py:416\u001b[0m, in \u001b[0;36msync\u001b[0;34m(loop, func, callback_timeout, *args, **kwargs)\u001b[0m\n\u001b[1;32m 414\u001b[0m \u001b[39mif\u001b[39;00m error:\n\u001b[1;32m 415\u001b[0m typ, exc, tb \u001b[39m=\u001b[39m error\n\u001b[0;32m--> 416\u001b[0m \u001b[39mraise\u001b[39;00m exc\u001b[39m.\u001b[39mwith_traceback(tb)\n\u001b[1;32m 417\u001b[0m \u001b[39melse\u001b[39;00m:\n\u001b[1;32m 418\u001b[0m \u001b[39mreturn\u001b[39;00m result\n", + "File \u001b[0;32m~/miniforge/envs/cugraph_0411/lib/python3.10/site-packages/distributed/utils.py:389\u001b[0m, in \u001b[0;36msync..f\u001b[0;34m()\u001b[0m\n\u001b[1;32m 387\u001b[0m future \u001b[39m=\u001b[39m wait_for(future, callback_timeout)\n\u001b[1;32m 388\u001b[0m future \u001b[39m=\u001b[39m asyncio\u001b[39m.\u001b[39mensure_future(future)\n\u001b[0;32m--> 389\u001b[0m result \u001b[39m=\u001b[39m \u001b[39myield\u001b[39;00m future\n\u001b[1;32m 390\u001b[0m \u001b[39mexcept\u001b[39;00m \u001b[39mException\u001b[39;00m:\n\u001b[1;32m 391\u001b[0m error \u001b[39m=\u001b[39m sys\u001b[39m.\u001b[39mexc_info()\n", + "File \u001b[0;32m~/miniforge/envs/cugraph_0411/lib/python3.10/site-packages/tornado/gen.py:769\u001b[0m, in \u001b[0;36mRunner.run\u001b[0;34m(self)\u001b[0m\n\u001b[1;32m 766\u001b[0m exc_info \u001b[39m=\u001b[39m \u001b[39mNone\u001b[39;00m\n\u001b[1;32m 768\u001b[0m \u001b[39mtry\u001b[39;00m:\n\u001b[0;32m--> 769\u001b[0m value \u001b[39m=\u001b[39m future\u001b[39m.\u001b[39;49mresult()\n\u001b[1;32m 770\u001b[0m \u001b[39mexcept\u001b[39;00m \u001b[39mException\u001b[39;00m:\n\u001b[1;32m 771\u001b[0m exc_info \u001b[39m=\u001b[39m sys\u001b[39m.\u001b[39mexc_info()\n", + "File \u001b[0;32m~/miniforge/envs/cugraph_0411/lib/python3.10/site-packages/distributed/client.py:2208\u001b[0m, in \u001b[0;36mClient._gather\u001b[0;34m(self, futures, errors, direct, local_worker)\u001b[0m\n\u001b[1;32m 2206\u001b[0m exc \u001b[39m=\u001b[39m CancelledError(key)\n\u001b[1;32m 2207\u001b[0m \u001b[39melse\u001b[39;00m:\n\u001b[0;32m-> 2208\u001b[0m \u001b[39mraise\u001b[39;00m exception\u001b[39m.\u001b[39mwith_traceback(traceback)\n\u001b[1;32m 2209\u001b[0m \u001b[39mraise\u001b[39;00m exc\n\u001b[1;32m 2210\u001b[0m \u001b[39mif\u001b[39;00m errors \u001b[39m==\u001b[39m \u001b[39m\"\u001b[39m\u001b[39mskip\u001b[39m\u001b[39m\"\u001b[39m:\n", + "File \u001b[0;32m~/miniforge/envs/cugraph_0411/lib/python3.10/contextlib.py:79\u001b[0m, in \u001b[0;36minner\u001b[0;34m()\u001b[0m\n\u001b[1;32m 76\u001b[0m \u001b[39m@wraps\u001b[39m(func)\n\u001b[1;32m 77\u001b[0m \u001b[39mdef\u001b[39;00m \u001b[39minner\u001b[39m(\u001b[39m*\u001b[39margs, \u001b[39m*\u001b[39m\u001b[39m*\u001b[39mkwds):\n\u001b[1;32m 78\u001b[0m \u001b[39mwith\u001b[39;00m \u001b[39mself\u001b[39m\u001b[39m.\u001b[39m_recreate_cm():\n\u001b[0;32m---> 79\u001b[0m \u001b[39mreturn\u001b[39;00m func(\u001b[39m*\u001b[39margs, \u001b[39m*\u001b[39m\u001b[39m*\u001b[39mkwds)\n", + "File \u001b[0;32m~/miniforge/envs/cugraph_0411/lib/python3.10/site-packages/distributed/worker.py:2937\u001b[0m, in \u001b[0;36m_deserialize\u001b[0;34m()\u001b[0m\n\u001b[1;32m 2934\u001b[0m \u001b[39m# Some objects require threadlocal state during deserialization, e.g. to\u001b[39;00m\n\u001b[1;32m 2935\u001b[0m \u001b[39m# detect the current worker\u001b[39;00m\n\u001b[1;32m 2936\u001b[0m \u001b[39mif\u001b[39;00m function \u001b[39mis\u001b[39;00m \u001b[39mnot\u001b[39;00m \u001b[39mNone\u001b[39;00m:\n\u001b[0;32m-> 2937\u001b[0m function \u001b[39m=\u001b[39m loads_function(function)\n\u001b[1;32m 2938\u001b[0m \u001b[39mif\u001b[39;00m args \u001b[39mand\u001b[39;00m \u001b[39misinstance\u001b[39m(args, \u001b[39mbytes\u001b[39m):\n\u001b[1;32m 2939\u001b[0m args \u001b[39m=\u001b[39m pickle\u001b[39m.\u001b[39mloads(args)\n", + "File \u001b[0;32m~/miniforge/envs/cugraph_0411/lib/python3.10/site-packages/distributed/worker.py:2925\u001b[0m, in \u001b[0;36mloads_function\u001b[0;34m()\u001b[0m\n\u001b[1;32m 2923\u001b[0m result \u001b[39m=\u001b[39m cache_loads[bytes_object]\n\u001b[1;32m 2924\u001b[0m \u001b[39mexcept\u001b[39;00m \u001b[39mKeyError\u001b[39;00m:\n\u001b[0;32m-> 2925\u001b[0m result \u001b[39m=\u001b[39m pickle\u001b[39m.\u001b[39mloads(bytes_object)\n\u001b[1;32m 2926\u001b[0m cache_loads[bytes_object] \u001b[39m=\u001b[39m result\n\u001b[1;32m 2927\u001b[0m \u001b[39mreturn\u001b[39;00m result\n", + "File \u001b[0;32m~/miniforge/envs/cugraph_0411/lib/python3.10/site-packages/distributed/protocol/pickle.py:96\u001b[0m, in \u001b[0;36mloads\u001b[0;34m()\u001b[0m\n\u001b[1;32m 94\u001b[0m \u001b[39mreturn\u001b[39;00m pickle\u001b[39m.\u001b[39mloads(x, buffers\u001b[39m=\u001b[39mbuffers)\n\u001b[1;32m 95\u001b[0m \u001b[39melse\u001b[39;00m:\n\u001b[0;32m---> 96\u001b[0m \u001b[39mreturn\u001b[39;00m pickle\u001b[39m.\u001b[39mloads(x)\n\u001b[1;32m 97\u001b[0m \u001b[39mexcept\u001b[39;00m \u001b[39mException\u001b[39;00m:\n\u001b[1;32m 98\u001b[0m logger\u001b[39m.\u001b[39minfo(\u001b[39m\"\u001b[39m\u001b[39mFailed to deserialize \u001b[39m\u001b[39m%s\u001b[39;00m\u001b[39m\"\u001b[39m, x[:\u001b[39m10000\u001b[39m], exc_info\u001b[39m=\u001b[39m\u001b[39mTrue\u001b[39;00m)\n", + "File \u001b[0;32m~/miniforge/envs/cugraph_0411/lib/python3.10/site-packages/cudf/core/abc.py:176\u001b[0m, in \u001b[0;36mhost_deserialize\u001b[0;34m()\u001b[0m\n\u001b[1;32m 154\u001b[0m \u001b[39m\u001b[39m\u001b[39m\"\"\"Perform device-side deserialization tasks.\u001b[39;00m\n\u001b[1;32m 155\u001b[0m \n\u001b[1;32m 156\u001b[0m \u001b[39mParameters\u001b[39;00m\n\u001b[0;32m (...)\u001b[0m\n\u001b[1;32m 170\u001b[0m \u001b[39m:meta private:\u001b[39;00m\n\u001b[1;32m 171\u001b[0m \u001b[39m\"\"\"\u001b[39;00m\n\u001b[1;32m 172\u001b[0m frames \u001b[39m=\u001b[39m [\n\u001b[1;32m 173\u001b[0m cudf\u001b[39m.\u001b[39mcore\u001b[39m.\u001b[39mbuffer\u001b[39m.\u001b[39mas_buffer(f) \u001b[39mif\u001b[39;00m c \u001b[39melse\u001b[39;00m f\n\u001b[1;32m 174\u001b[0m \u001b[39mfor\u001b[39;00m c, f \u001b[39min\u001b[39;00m \u001b[39mzip\u001b[39m(header[\u001b[39m\"\u001b[39m\u001b[39mis-cuda\u001b[39m\u001b[39m\"\u001b[39m], \u001b[39mmap\u001b[39m(\u001b[39mmemoryview\u001b[39m, frames))\n\u001b[1;32m 175\u001b[0m ]\n\u001b[0;32m--> 176\u001b[0m obj \u001b[39m=\u001b[39m \u001b[39mcls\u001b[39m\u001b[39m.\u001b[39mdevice_deserialize(header, frames)\n\u001b[1;32m 177\u001b[0m \u001b[39mreturn\u001b[39;00m obj\n", + "File \u001b[0;32m~/miniforge/envs/cugraph_0411/lib/python3.10/site-packages/cudf/core/abc.py:130\u001b[0m, in \u001b[0;36mdevice_deserialize\u001b[0;34m()\u001b[0m\n\u001b[1;32m 125\u001b[0m typ \u001b[39m=\u001b[39m pickle\u001b[39m.\u001b[39mloads(header[\u001b[39m\"\u001b[39m\u001b[39mtype-serialized\u001b[39m\u001b[39m\"\u001b[39m])\n\u001b[1;32m 126\u001b[0m frames \u001b[39m=\u001b[39m [\n\u001b[1;32m 127\u001b[0m cudf\u001b[39m.\u001b[39mcore\u001b[39m.\u001b[39mbuffer\u001b[39m.\u001b[39mas_buffer(f) \u001b[39mif\u001b[39;00m c \u001b[39melse\u001b[39;00m \u001b[39mmemoryview\u001b[39m(f)\n\u001b[1;32m 128\u001b[0m \u001b[39mfor\u001b[39;00m c, f \u001b[39min\u001b[39;00m \u001b[39mzip\u001b[39m(header[\u001b[39m\"\u001b[39m\u001b[39mis-cuda\u001b[39m\u001b[39m\"\u001b[39m], frames)\n\u001b[1;32m 129\u001b[0m ]\n\u001b[0;32m--> 130\u001b[0m \u001b[39mreturn\u001b[39;00m typ\u001b[39m.\u001b[39mdeserialize(header, frames)\n", + "File \u001b[0;32m~/miniforge/envs/cugraph_0411/lib/python3.10/site-packages/cudf/core/dataframe.py:1019\u001b[0m, in \u001b[0;36mdeserialize\u001b[0;34m()\u001b[0m\n\u001b[1;32m 1016\u001b[0m \u001b[39m@classmethod\u001b[39m\n\u001b[1;32m 1017\u001b[0m \u001b[39mdef\u001b[39;00m \u001b[39mdeserialize\u001b[39m(\u001b[39mcls\u001b[39m, header, frames):\n\u001b[1;32m 1018\u001b[0m index_nframes \u001b[39m=\u001b[39m header[\u001b[39m\"\u001b[39m\u001b[39mindex_frame_count\u001b[39m\u001b[39m\"\u001b[39m]\n\u001b[0;32m-> 1019\u001b[0m obj \u001b[39m=\u001b[39m \u001b[39msuper\u001b[39m()\u001b[39m.\u001b[39mdeserialize(\n\u001b[1;32m 1020\u001b[0m header, frames[header[\u001b[39m\"\u001b[39m\u001b[39mindex_frame_count\u001b[39m\u001b[39m\"\u001b[39m] :]\n\u001b[1;32m 1021\u001b[0m )\n\u001b[1;32m 1023\u001b[0m idx_typ \u001b[39m=\u001b[39m pickle\u001b[39m.\u001b[39mloads(header[\u001b[39m\"\u001b[39m\u001b[39mindex\u001b[39m\u001b[39m\"\u001b[39m][\u001b[39m\"\u001b[39m\u001b[39mtype-serialized\u001b[39m\u001b[39m\"\u001b[39m])\n\u001b[1;32m 1024\u001b[0m index \u001b[39m=\u001b[39m idx_typ\u001b[39m.\u001b[39mdeserialize(header[\u001b[39m\"\u001b[39m\u001b[39mindex\u001b[39m\u001b[39m\"\u001b[39m], frames[:index_nframes])\n", + "File \u001b[0;32m~/miniforge/envs/cugraph_0411/lib/python3.10/site-packages/cudf/core/frame.py:106\u001b[0m, in \u001b[0;36mdeserialize\u001b[0;34m()\u001b[0m\n\u001b[1;32m 104\u001b[0m cls_deserialize \u001b[39m=\u001b[39m pickle\u001b[39m.\u001b[39mloads(header[\u001b[39m\"\u001b[39m\u001b[39mtype-serialized\u001b[39m\u001b[39m\"\u001b[39m])\n\u001b[1;32m 105\u001b[0m column_names \u001b[39m=\u001b[39m pickle\u001b[39m.\u001b[39mloads(header[\u001b[39m\"\u001b[39m\u001b[39mcolumn_names\u001b[39m\u001b[39m\"\u001b[39m])\n\u001b[0;32m--> 106\u001b[0m columns \u001b[39m=\u001b[39m deserialize_columns(header[\u001b[39m\"\u001b[39m\u001b[39mcolumns\u001b[39m\u001b[39m\"\u001b[39m], frames)\n\u001b[1;32m 107\u001b[0m \u001b[39mreturn\u001b[39;00m cls_deserialize\u001b[39m.\u001b[39m_from_data(\u001b[39mdict\u001b[39m(\u001b[39mzip\u001b[39m(column_names, columns)))\n", + "File \u001b[0;32m~/miniforge/envs/cugraph_0411/lib/python3.10/site-packages/cudf/core/column/column.py:2450\u001b[0m, in \u001b[0;36mdeserialize_columns\u001b[0;34m()\u001b[0m\n\u001b[1;32m 2448\u001b[0m col_frame_count \u001b[39m=\u001b[39m meta[\u001b[39m\"\u001b[39m\u001b[39mframe_count\u001b[39m\u001b[39m\"\u001b[39m]\n\u001b[1;32m 2449\u001b[0m col_typ \u001b[39m=\u001b[39m pickle\u001b[39m.\u001b[39mloads(meta[\u001b[39m\"\u001b[39m\u001b[39mtype-serialized\u001b[39m\u001b[39m\"\u001b[39m])\n\u001b[0;32m-> 2450\u001b[0m colobj \u001b[39m=\u001b[39m col_typ\u001b[39m.\u001b[39mdeserialize(meta, frames[:col_frame_count])\n\u001b[1;32m 2451\u001b[0m columns\u001b[39m.\u001b[39mappend(colobj)\n\u001b[1;32m 2452\u001b[0m \u001b[39m# Advance frames\u001b[39;00m\n", + "File \u001b[0;32m~/miniforge/envs/cugraph_0411/lib/python3.10/site-packages/cudf/core/column/column.py:1216\u001b[0m, in \u001b[0;36mdeserialize\u001b[0;34m()\u001b[0m\n\u001b[1;32m 1214\u001b[0m dtype \u001b[39m=\u001b[39m pickle\u001b[39m.\u001b[39mloads(header[\u001b[39m\"\u001b[39m\u001b[39mdtype\u001b[39m\u001b[39m\"\u001b[39m])\n\u001b[1;32m 1215\u001b[0m \u001b[39mif\u001b[39;00m \u001b[39m\"\u001b[39m\u001b[39mdata\u001b[39m\u001b[39m\"\u001b[39m \u001b[39min\u001b[39;00m header:\n\u001b[0;32m-> 1216\u001b[0m data, frames \u001b[39m=\u001b[39m unpack(header[\u001b[39m\"\u001b[39m\u001b[39mdata\u001b[39m\u001b[39m\"\u001b[39m], frames)\n\u001b[1;32m 1217\u001b[0m \u001b[39melse\u001b[39;00m:\n\u001b[1;32m 1218\u001b[0m data \u001b[39m=\u001b[39m \u001b[39mNone\u001b[39;00m\n", + "File \u001b[0;32m~/miniforge/envs/cugraph_0411/lib/python3.10/site-packages/cudf/core/column/column.py:1204\u001b[0m, in \u001b[0;36munpack\u001b[0;34m()\u001b[0m\n\u001b[1;32m 1202\u001b[0m count \u001b[39m=\u001b[39m header[\u001b[39m\"\u001b[39m\u001b[39mframe_count\u001b[39m\u001b[39m\"\u001b[39m]\n\u001b[1;32m 1203\u001b[0m klass \u001b[39m=\u001b[39m pickle\u001b[39m.\u001b[39mloads(header[\u001b[39m\"\u001b[39m\u001b[39mtype-serialized\u001b[39m\u001b[39m\"\u001b[39m])\n\u001b[0;32m-> 1204\u001b[0m obj \u001b[39m=\u001b[39m klass\u001b[39m.\u001b[39mdeserialize(header, frames[:count])\n\u001b[1;32m 1205\u001b[0m \u001b[39mreturn\u001b[39;00m obj, frames[count:]\n", + "File \u001b[0;32m~/miniforge/envs/cugraph_0411/lib/python3.10/site-packages/cudf/core/buffer/spillable_buffer.py:574\u001b[0m, in \u001b[0;36mdeserialize\u001b[0;34m()\u001b[0m\n\u001b[1;32m 567\u001b[0m \u001b[39m@classmethod\u001b[39m\n\u001b[1;32m 568\u001b[0m \u001b[39mdef\u001b[39;00m \u001b[39mdeserialize\u001b[39m(\u001b[39mcls\u001b[39m, header: \u001b[39mdict\u001b[39m, frames: \u001b[39mlist\u001b[39m):\n\u001b[1;32m 569\u001b[0m \u001b[39m# TODO: because of the hack in `SpillableBuffer.serialize()` where\u001b[39;00m\n\u001b[0;32m (...)\u001b[0m\n\u001b[1;32m 572\u001b[0m \u001b[39m# deserialize into `SpillableBufferSlice` when the frames hasn't been\u001b[39;00m\n\u001b[1;32m 573\u001b[0m \u001b[39m# copied.\u001b[39;00m\n\u001b[0;32m--> 574\u001b[0m \u001b[39mreturn\u001b[39;00m SpillableBuffer\u001b[39m.\u001b[39mdeserialize(header, frames)\n", + "File \u001b[0;32m~/miniforge/envs/cugraph_0411/lib/python3.10/site-packages/cudf/core/buffer/buffer.py:335\u001b[0m, in \u001b[0;36mdeserialize\u001b[0;34m()\u001b[0m\n\u001b[1;32m 332\u001b[0m \u001b[39mreturn\u001b[39;00m frame \u001b[39m# The frame is already deserialized\u001b[39;00m\n\u001b[1;32m 334\u001b[0m \u001b[39mif\u001b[39;00m \u001b[39mhasattr\u001b[39m(frame, \u001b[39m\"\u001b[39m\u001b[39m__cuda_array_interface__\u001b[39m\u001b[39m\"\u001b[39m):\n\u001b[0;32m--> 335\u001b[0m \u001b[39mreturn\u001b[39;00m \u001b[39mcls\u001b[39m\u001b[39m.\u001b[39m_from_device_memory(frame)\n\u001b[1;32m 336\u001b[0m \u001b[39mreturn\u001b[39;00m \u001b[39mcls\u001b[39m\u001b[39m.\u001b[39m_from_host_memory(frame)\n", + "File \u001b[0;32m~/miniforge/envs/cugraph_0411/lib/python3.10/site-packages/cudf/core/buffer/spillable_buffer.py:235\u001b[0m, in \u001b[0;36m_from_device_memory\u001b[0;34m()\u001b[0m\n\u001b[1;32m 218\u001b[0m \u001b[39m\u001b[39m\u001b[39m\"\"\"Create a spillabe buffer from device memory.\u001b[39;00m\n\u001b[1;32m 219\u001b[0m \n\u001b[1;32m 220\u001b[0m \u001b[39mNo data is being copied.\u001b[39;00m\n\u001b[0;32m (...)\u001b[0m\n\u001b[1;32m 232\u001b[0m \u001b[39m Buffer representing the same device memory as `data`\u001b[39;00m\n\u001b[1;32m 233\u001b[0m \u001b[39m\"\"\"\u001b[39;00m\n\u001b[1;32m 234\u001b[0m ret \u001b[39m=\u001b[39m \u001b[39msuper\u001b[39m()\u001b[39m.\u001b[39m_from_device_memory(data)\n\u001b[0;32m--> 235\u001b[0m ret\u001b[39m.\u001b[39m_finalize_init(ptr_desc\u001b[39m=\u001b[39m{\u001b[39m\"\u001b[39m\u001b[39mtype\u001b[39m\u001b[39m\"\u001b[39m: \u001b[39m\"\u001b[39m\u001b[39mgpu\u001b[39m\u001b[39m\"\u001b[39m}, exposed\u001b[39m=\u001b[39mexposed)\n\u001b[1;32m 236\u001b[0m \u001b[39mreturn\u001b[39;00m ret\n", + "File \u001b[0;32m~/miniforge/envs/cugraph_0411/lib/python3.10/site-packages/cudf/core/buffer/spillable_buffer.py:206\u001b[0m, in \u001b[0;36m_finalize_init\u001b[0;34m()\u001b[0m\n\u001b[1;32m 204\u001b[0m manager \u001b[39m=\u001b[39m get_global_manager()\n\u001b[1;32m 205\u001b[0m \u001b[39mif\u001b[39;00m manager \u001b[39mis\u001b[39;00m \u001b[39mNone\u001b[39;00m:\n\u001b[0;32m--> 206\u001b[0m \u001b[39mraise\u001b[39;00m \u001b[39mValueError\u001b[39;00m(\n\u001b[1;32m 207\u001b[0m \u001b[39mf\u001b[39m\u001b[39m\"\u001b[39m\u001b[39mcannot create \u001b[39m\u001b[39m{\u001b[39;00m\u001b[39mself\u001b[39m\u001b[39m.\u001b[39m\u001b[39m__class__\u001b[39m\u001b[39m}\u001b[39;00m\u001b[39m without \u001b[39m\u001b[39m\"\u001b[39m\n\u001b[1;32m 208\u001b[0m \u001b[39m\"\u001b[39m\u001b[39ma global spill manager\u001b[39m\u001b[39m\"\u001b[39m\n\u001b[1;32m 209\u001b[0m )\n\u001b[1;32m 211\u001b[0m \u001b[39mself\u001b[39m\u001b[39m.\u001b[39m_manager \u001b[39m=\u001b[39m manager\n\u001b[1;32m 212\u001b[0m \u001b[39mself\u001b[39m\u001b[39m.\u001b[39m_manager\u001b[39m.\u001b[39madd(\u001b[39mself\u001b[39m)\n", "\u001b[0;31mValueError\u001b[0m: cannot create without a global spill manager" ] } diff --git a/python/cugraph-dgl/README.md b/python/cugraph-dgl/README.md index ac4cb2f6253..013d4fe5e2e 100644 --- a/python/cugraph-dgl/README.md +++ b/python/cugraph-dgl/README.md @@ -8,9 +8,12 @@ Install and update cugraph-dgl and the required dependencies using the command: -``` -conda install mamba -n base -c conda-forge -mamba install cugraph-dgl -c rapidsai-nightly -c rapidsai -c pytorch -c conda-forge -c nvidia -c dglteam +```shell +# CUDA 11 +conda install -c rapidsai -c pytorch -c conda-forge -c nvidia -c dglteam/label/th23_cu118 cugraph-dgl + +# CUDA 12 +conda install -c rapidsai -c pytorch -c conda-forge -c nvidia -c dglteam/label/th23_cu121 cugraph-dgl ``` ## Build from Source diff --git a/python/cugraph-dgl/conda/cugraph_dgl_dev_cuda-118.yaml b/python/cugraph-dgl/conda/cugraph_dgl_dev_cuda-118.yaml index ea30b652286..174012b8f8c 100644 --- a/python/cugraph-dgl/conda/cugraph_dgl_dev_cuda-118.yaml +++ b/python/cugraph-dgl/conda/cugraph_dgl_dev_cuda-118.yaml @@ -4,22 +4,21 @@ channels: - rapidsai - rapidsai-nightly - dask/label/dev -- pyg -- dglteam/label/cu118 +- dglteam/label/th23_cu118 - conda-forge - nvidia dependencies: -- cugraph==24.10.*,>=0.0.0a0 -- dgl>=1.1.0.cu* +- cugraph==24.12.*,>=0.0.0a0 +- dgl>=2.4.0.cu* - pandas - pre-commit -- pylibcugraphops==24.10.*,>=0.0.0a0 +- pylibcugraphops==24.12.*,>=0.0.0a0 - pytest - pytest-benchmark - pytest-cov - pytest-xdist - pytorch-cuda==11.8 -- pytorch>=2.0 +- pytorch>=2.3,<2.4.0a0 - scipy - tensordict>=0.1.2 name: cugraph_dgl_dev_cuda-118 diff --git a/python/cugraph-dgl/cugraph_dgl/dataloading/neighbor_sampler.py b/python/cugraph-dgl/cugraph_dgl/dataloading/neighbor_sampler.py index 87d111adcba..ecc51006995 100644 --- a/python/cugraph-dgl/cugraph_dgl/dataloading/neighbor_sampler.py +++ b/python/cugraph-dgl/cugraph_dgl/dataloading/neighbor_sampler.py @@ -18,7 +18,7 @@ from typing import Sequence, Optional, Union, List, Tuple, Iterator -from cugraph.gnn import UniformNeighborSampler, DistSampleWriter +from cugraph.gnn import UniformNeighborSampler, BiasedNeighborSampler, DistSampleWriter from cugraph.utilities.utils import import_optional import cugraph_dgl @@ -93,7 +93,6 @@ def __init__( If provided, the probability of each neighbor being sampled is proportional to the edge feature with the given name. Mutually exclusive with mask. - Currently unsupported. mask: str Optional. If proivided, only neighbors where the edge mask @@ -133,10 +132,6 @@ def __init__( raise NotImplementedError( "Edge masking is currently unsupported by cuGraph-DGL" ) - if prob: - raise NotImplementedError( - "Edge masking is currently unsupported by cuGraph-DGL" - ) if prefetch_edge_feats: warnings.warn("'prefetch_edge_feats' is ignored by cuGraph-DGL") if prefetch_node_feats: @@ -146,6 +141,8 @@ def __init__( if fused: warnings.warn("'fused' is ignored by cuGraph-DGL") + self.__prob_attr = prob + self.fanouts = fanouts_per_layer reverse_fanouts = fanouts_per_layer.copy() reverse_fanouts.reverse() @@ -180,8 +177,14 @@ def sample( format=kwargs.pop("format", "parquet"), ) - ds = UniformNeighborSampler( - g._graph(self.edge_dir), + sampling_clx = ( + UniformNeighborSampler + if self.__prob_attr is None + else BiasedNeighborSampler + ) + + ds = sampling_clx( + g._graph(self.edge_dir, prob_attr=self.__prob_attr), writer, compression="CSR", fanout=self._reversed_fanout_vals, @@ -194,10 +197,8 @@ def sample( if g.is_homogeneous: indices = torch.concat(list(indices)) - ds.sample_from_nodes(indices.long(), batch_size=batch_size) - return HomogeneousSampleReader( - ds.get_reader(), self.output_format, self.edge_dir - ) + reader = ds.sample_from_nodes(indices.long(), batch_size=batch_size) + return HomogeneousSampleReader(reader, self.output_format, self.edge_dir) raise ValueError( "Sampling heterogeneous graphs is currently" diff --git a/python/cugraph-dgl/cugraph_dgl/dataloading/sampler.py b/python/cugraph-dgl/cugraph_dgl/dataloading/sampler.py index 731ec1b8d6f..7ea608e7e53 100644 --- a/python/cugraph-dgl/cugraph_dgl/dataloading/sampler.py +++ b/python/cugraph-dgl/cugraph_dgl/dataloading/sampler.py @@ -20,7 +20,6 @@ create_homogeneous_sampled_graphs_from_tensors_csc, ) -from cugraph.gnn import DistSampleReader from cugraph.utilities.utils import import_optional @@ -33,14 +32,18 @@ class SampleReader: Iterator that processes results from the cuGraph distributed sampler. """ - def __init__(self, base_reader: DistSampleReader, output_format: str = "dgl.Block"): + def __init__( + self, + base_reader: Iterator[Tuple[Dict[str, "torch.Tensor"], int, int]], + output_format: str = "dgl.Block", + ): """ Constructs a new SampleReader. Parameters ---------- - base_reader: DistSampleReader - The reader responsible for loading saved samples produced by + base_reader: Iterator[Tuple[Dict[str, "torch.Tensor"], int, int]] + The iterator responsible for loading saved samples produced by the cuGraph distributed sampler. """ self.__output_format = output_format @@ -83,7 +86,7 @@ class HomogeneousSampleReader(SampleReader): def __init__( self, - base_reader: DistSampleReader, + base_reader: Iterator[Tuple[Dict[str, "torch.Tensor"], int, int]], output_format: str = "dgl.Block", edge_dir="in", ): @@ -92,7 +95,7 @@ def __init__( Parameters ---------- - base_reader: DistSampleReader + base_reader: Iterator[Tuple[Dict[str, "torch.Tensor"], int, int]] The reader responsible for loading saved samples produced by the cuGraph distributed sampler. output_format: str diff --git a/python/cugraph-dgl/cugraph_dgl/graph.py b/python/cugraph-dgl/cugraph_dgl/graph.py index 011ab736d00..88b93656fa8 100644 --- a/python/cugraph-dgl/cugraph_dgl/graph.py +++ b/python/cugraph-dgl/cugraph_dgl/graph.py @@ -312,7 +312,7 @@ def add_edges( self.__graph = None self.__vertex_offsets = None - def num_nodes(self, ntype: str = None) -> int: + def num_nodes(self, ntype: Optional[str] = None) -> int: """ Returns the number of nodes of ntype, or if ntype is not provided, the total number of nodes in the graph. @@ -322,7 +322,7 @@ def num_nodes(self, ntype: str = None) -> int: return self.__num_nodes_dict[ntype] - def number_of_nodes(self, ntype: str = None) -> int: + def number_of_nodes(self, ntype: Optional[str] = None) -> int: """ Alias for num_nodes. """ @@ -381,7 +381,7 @@ def _vertex_offsets(self) -> Dict[str, int]: return dict(self.__vertex_offsets) - def __get_edgelist(self) -> Dict[str, "torch.Tensor"]: + def __get_edgelist(self, prob_attr=None) -> Dict[str, "torch.Tensor"]: """ This function always returns src/dst labels with respect to the out direction. @@ -431,63 +431,71 @@ def __get_edgelist(self) -> Dict[str, "torch.Tensor"]: ) ) + num_edges_t = torch.tensor( + [self.__edge_indices[et].shape[1] for et in sorted_keys], device="cuda" + ) + if self.is_multi_gpu: rank = torch.distributed.get_rank() world_size = torch.distributed.get_world_size() - num_edges_t = torch.tensor( - [self.__edge_indices[et].shape[1] for et in sorted_keys], device="cuda" - ) num_edges_all_t = torch.empty( world_size, num_edges_t.numel(), dtype=torch.int64, device="cuda" ) torch.distributed.all_gather_into_tensor(num_edges_all_t, num_edges_t) - if rank > 0: - start_offsets = num_edges_all_t[:rank].T.sum(axis=1) - edge_id_array = torch.concat( + start_offsets = num_edges_all_t[:rank].T.sum(axis=1) + + else: + rank = 0 + start_offsets = torch.zeros( + (len(sorted_keys),), dtype=torch.int64, device="cuda" + ) + num_edges_all_t = num_edges_t.reshape((1, num_edges_t.numel())) + + # Use pinned memory here for fast access to CPU/WG storage + edge_id_array_per_type = [ + torch.arange( + start_offsets[i], + start_offsets[i] + num_edges_all_t[rank][i], + dtype=torch.int64, + device="cpu", + ).pin_memory() + for i in range(len(sorted_keys)) + ] + + # Retrieve the weights from the appropriate feature(s) + # DGL implicitly requires all edge types use the same + # feature name. + if prob_attr is None: + weights = None + else: + if len(sorted_keys) > 1: + weights = torch.concat( [ - torch.arange( - start_offsets[i], - start_offsets[i] + num_edges_all_t[rank][i], - dtype=torch.int64, - device="cuda", - ) - for i in range(len(sorted_keys)) + self.edata[prob_attr][sorted_keys[i]][ix] + for i, ix in enumerate(edge_id_array_per_type) ] ) else: - edge_id_array = torch.concat( - [ - torch.arange( - self.__edge_indices[et].shape[1], - dtype=torch.int64, - device="cuda", - ) - for et in sorted_keys - ] - ) + weights = self.edata[prob_attr][edge_id_array_per_type[0]] - else: - # single GPU - edge_id_array = torch.concat( - [ - torch.arange( - self.__edge_indices[et].shape[1], - dtype=torch.int64, - device="cuda", - ) - for et in sorted_keys - ] - ) + # Safe to move this to cuda because the consumer will always + # move it to cuda if it isn't already there. + edge_id_array = torch.concat(edge_id_array_per_type).cuda() - return { + edgelist_dict = { "src": edge_index[0], "dst": edge_index[1], "etp": edge_type_array, "eid": edge_id_array, } + if weights is not None: + edgelist_dict["wgt"] = weights + + return edgelist_dict + @property def is_homogeneous(self): return len(self.__num_edges_dict) <= 1 and len(self.__num_nodes_dict) <= 1 @@ -508,7 +516,9 @@ def _resource_handle(self): return self.__handle def _graph( - self, direction: str + self, + direction: str, + prob_attr: Optional[str] = None, ) -> Union[pylibcugraph.SGGraph, pylibcugraph.MGGraph]: """ Gets the pylibcugraph Graph object with edges pointing in the given direction @@ -522,12 +532,16 @@ def _graph( is_multigraph=True, is_symmetric=False ) - if self.__graph is not None and self.__graph[1] != direction: - self.__graph = None + if self.__graph is not None: + if ( + self.__graph["direction"] != direction + or self.__graph["prob_attr"] != prob_attr + ): + self.__graph = None if self.__graph is None: src_col, dst_col = ("src", "dst") if direction == "out" else ("dst", "src") - edgelist_dict = self.__get_edgelist() + edgelist_dict = self.__get_edgelist(prob_attr=prob_attr) if self.is_multi_gpu: rank = torch.distributed.get_rank() @@ -536,33 +550,35 @@ def _graph( vertices_array = cupy.arange(self.num_nodes(), dtype="int64") vertices_array = cupy.array_split(vertices_array, world_size)[rank] - self.__graph = ( - pylibcugraph.MGGraph( - self._resource_handle, - graph_properties, - [cupy.asarray(edgelist_dict[src_col]).astype("int64")], - [cupy.asarray(edgelist_dict[dst_col]).astype("int64")], - vertices_array=[vertices_array], - edge_id_array=[cupy.asarray(edgelist_dict["eid"])], - edge_type_array=[cupy.asarray(edgelist_dict["etp"])], - ), - direction, + graph = pylibcugraph.MGGraph( + self._resource_handle, + graph_properties, + [cupy.asarray(edgelist_dict[src_col]).astype("int64")], + [cupy.asarray(edgelist_dict[dst_col]).astype("int64")], + vertices_array=[vertices_array], + edge_id_array=[cupy.asarray(edgelist_dict["eid"])], + edge_type_array=[cupy.asarray(edgelist_dict["etp"])], + weight_array=[cupy.asarray(edgelist_dict["wgt"])] + if "wgt" in edgelist_dict + else None, ) else: - self.__graph = ( - pylibcugraph.SGGraph( - self._resource_handle, - graph_properties, - cupy.asarray(edgelist_dict[src_col]).astype("int64"), - cupy.asarray(edgelist_dict[dst_col]).astype("int64"), - vertices_array=cupy.arange(self.num_nodes(), dtype="int64"), - edge_id_array=cupy.asarray(edgelist_dict["eid"]), - edge_type_array=cupy.asarray(edgelist_dict["etp"]), - ), - direction, + graph = pylibcugraph.SGGraph( + self._resource_handle, + graph_properties, + cupy.asarray(edgelist_dict[src_col]).astype("int64"), + cupy.asarray(edgelist_dict[dst_col]).astype("int64"), + vertices_array=cupy.arange(self.num_nodes(), dtype="int64"), + edge_id_array=cupy.asarray(edgelist_dict["eid"]), + edge_type_array=cupy.asarray(edgelist_dict["etp"]), + weight_array=cupy.asarray(edgelist_dict["wgt"]) + if "wgt" in edgelist_dict + else None, ) - return self.__graph[0] + self.__graph = {"graph": graph, "direction": direction, "prob_attr": prob_attr} + + return self.__graph["graph"] def _has_n_emb(self, ntype: str, emb_name: str) -> bool: return (ntype, emb_name) in self.__ndata_storage @@ -604,9 +620,6 @@ def _get_n_emb( ) try: - print( - u, - ) return self.__ndata_storage[ntype, emb_name].fetch( _cast_to_torch_tensor(u), "cuda" ) diff --git a/python/cugraph-dgl/cugraph_dgl/nn/conv/base.py b/python/cugraph-dgl/cugraph_dgl/nn/conv/base.py index d2460f814c9..fcd5a26aee6 100644 --- a/python/cugraph-dgl/cugraph_dgl/nn/conv/base.py +++ b/python/cugraph-dgl/cugraph_dgl/nn/conv/base.py @@ -129,7 +129,7 @@ def __init__( if csrc_ids is not None: if csrc_ids.numel() != self._num_src_nodes + 1: raise RuntimeError( - f"Size mismatch for 'csrc_ids': expected ({size[0]+1},), " + f"Size mismatch for 'csrc_ids': expected ({size[0] + 1},), " f"but got {tuple(csrc_ids.size())}" ) csrc_ids = csrc_ids.contiguous() @@ -137,7 +137,7 @@ def __init__( if cdst_ids is not None: if cdst_ids.numel() != self._num_dst_nodes + 1: raise RuntimeError( - f"Size mismatch for 'cdst_ids': expected ({size[1]+1},), " + f"Size mismatch for 'cdst_ids': expected ({size[1] + 1},), " f"but got {tuple(cdst_ids.size())}" ) cdst_ids = cdst_ids.contiguous() diff --git a/python/cugraph-dgl/cugraph_dgl/tests/dataloading/test_dataloader.py b/python/cugraph-dgl/cugraph_dgl/tests/dataloading/test_dataloader.py index ef47875463d..419ec7790a9 100644 --- a/python/cugraph-dgl/cugraph_dgl/tests/dataloading/test_dataloader.py +++ b/python/cugraph-dgl/cugraph_dgl/tests/dataloading/test_dataloader.py @@ -11,6 +11,7 @@ # See the License for the specific language governing permissions and # limitations under the License. + import cugraph_dgl.dataloading import pytest @@ -48,9 +49,12 @@ def test_dataloader_basic_homogeneous(): assert len(out_t) <= 2 -def sample_dgl_graphs(g, train_nid, fanouts, batch_size=1): +def sample_dgl_graphs(g, train_nid, fanouts, batch_size=1, prob_attr=None): # Single fanout to match cugraph - sampler = dgl.dataloading.NeighborSampler(fanouts) + sampler = dgl.dataloading.NeighborSampler( + fanouts, + prob=prob_attr, + ) dataloader = dgl.dataloading.DataLoader( g, train_nid, @@ -71,8 +75,13 @@ def sample_dgl_graphs(g, train_nid, fanouts, batch_size=1): return dgl_output -def sample_cugraph_dgl_graphs(cugraph_g, train_nid, fanouts, batch_size=1): - sampler = cugraph_dgl.dataloading.NeighborSampler(fanouts) +def sample_cugraph_dgl_graphs( + cugraph_g, train_nid, fanouts, batch_size=1, prob_attr=None +): + sampler = cugraph_dgl.dataloading.NeighborSampler( + fanouts, + prob=prob_attr, + ) dataloader = cugraph_dgl.dataloading.FutureDataLoader( cugraph_g, @@ -126,3 +135,41 @@ def test_same_homogeneousgraph_results(ix, batch_size): dgl_output[0]["blocks"][0].num_edges() == cugraph_output[0]["blocks"][0].num_edges() ) + + +@pytest.mark.skipif(isinstance(torch, MissingModule), reason="torch not available") +@pytest.mark.skipif(isinstance(dgl, MissingModule), reason="dgl not available") +def test_dataloader_biased_homogeneous(): + src = torch.tensor([1, 2, 3, 4, 5, 6, 7, 8]) + dst = torch.tensor([0, 0, 0, 0, 1, 1, 1, 1]) + wgt = torch.tensor([1, 1, 2, 0, 0, 0, 2, 1], dtype=torch.float32) + + train_nid = torch.tensor([0, 1]) + # Create a heterograph with 3 node types and 3 edges types. + dgl_g = dgl.graph((src, dst)) + dgl_g.edata["wgt"] = wgt + + cugraph_g = cugraph_dgl.Graph(is_multi_gpu=False) + cugraph_g.add_nodes(9) + cugraph_g.add_edges(u=src, v=dst, data={"wgt": wgt}) + + dgl_output = sample_dgl_graphs(dgl_g, train_nid, [4], batch_size=2, prob_attr="wgt") + cugraph_output = sample_cugraph_dgl_graphs( + cugraph_g, train_nid, [4], batch_size=2, prob_attr="wgt" + ) + + cugraph_output_nodes = cugraph_output[0]["output_nodes"].cpu().numpy() + dgl_output_nodes = dgl_output[0]["output_nodes"].cpu().numpy() + + np.testing.assert_array_equal( + np.sort(cugraph_output_nodes), np.sort(dgl_output_nodes) + ) + assert ( + dgl_output[0]["blocks"][0].num_dst_nodes() + == cugraph_output[0]["blocks"][0].num_dst_nodes() + ) + assert ( + dgl_output[0]["blocks"][0].num_edges() + == cugraph_output[0]["blocks"][0].num_edges() + ) + assert 5 == cugraph_output[0]["blocks"][0].num_edges() diff --git a/python/cugraph-dgl/cugraph_dgl/tests/dataloading/test_dataloader_mg.py b/python/cugraph-dgl/cugraph_dgl/tests/dataloading/test_dataloader_mg.py index b32233f16a6..061f4fa2077 100644 --- a/python/cugraph-dgl/cugraph_dgl/tests/dataloading/test_dataloader_mg.py +++ b/python/cugraph-dgl/cugraph_dgl/tests/dataloading/test_dataloader_mg.py @@ -82,9 +82,18 @@ def test_dataloader_basic_homogeneous(): ) -def sample_dgl_graphs(g, train_nid, fanouts, batch_size=1): +def sample_dgl_graphs( + g, + train_nid, + fanouts, + batch_size=1, + prob_attr=None, +): # Single fanout to match cugraph - sampler = dgl.dataloading.NeighborSampler(fanouts) + sampler = dgl.dataloading.NeighborSampler( + fanouts, + prob=prob_attr, + ) dataloader = dgl.dataloading.DataLoader( g, train_nid, @@ -105,8 +114,17 @@ def sample_dgl_graphs(g, train_nid, fanouts, batch_size=1): return dgl_output -def sample_cugraph_dgl_graphs(cugraph_g, train_nid, fanouts, batch_size=1): - sampler = cugraph_dgl.dataloading.NeighborSampler(fanouts) +def sample_cugraph_dgl_graphs( + cugraph_g, + train_nid, + fanouts, + batch_size=1, + prob_attr=None, +): + sampler = cugraph_dgl.dataloading.NeighborSampler( + fanouts, + prob=prob_attr, + ) dataloader = cugraph_dgl.dataloading.FutureDataLoader( cugraph_g, @@ -179,3 +197,58 @@ def test_same_homogeneousgraph_results_mg(ix, batch_size): args=(world_size, uid, ix, batch_size), nprocs=world_size, ) + + +def run_test_dataloader_biased_homogeneous(rank, world_size, uid): + init_pytorch_worker(rank, world_size, uid, True) + + src = torch.tensor([1, 2, 3, 4, 5, 6, 7, 8]) + (rank * 9) + dst = torch.tensor([0, 0, 0, 0, 1, 1, 1, 1]) + (rank * 9) + wgt = torch.tensor( + [0.1, 0.1, 0.2, 0, 0, 0, 0.2, 0.1] * world_size, dtype=torch.float32 + ) + + train_nid = torch.tensor([0, 1]) + (rank * 9) + # Create a heterograph with 3 node types and 3 edge types. + dgl_g = dgl.graph((src, dst)) + dgl_g.edata["wgt"] = wgt[:8] + + cugraph_g = cugraph_dgl.Graph(is_multi_gpu=True) + cugraph_g.add_nodes(9 * world_size) + cugraph_g.add_edges(u=src, v=dst, data={"wgt": wgt}) + + dgl_output = sample_dgl_graphs(dgl_g, train_nid, [4], batch_size=2, prob_attr="wgt") + cugraph_output = sample_cugraph_dgl_graphs( + cugraph_g, train_nid, [4], batch_size=2, prob_attr="wgt" + ) + + cugraph_output_nodes = cugraph_output[0]["output_nodes"].cpu().numpy() + dgl_output_nodes = dgl_output[0]["output_nodes"].cpu().numpy() + + np.testing.assert_array_equal( + np.sort(cugraph_output_nodes), np.sort(dgl_output_nodes) + ) + assert ( + dgl_output[0]["blocks"][0].num_dst_nodes() + == cugraph_output[0]["blocks"][0].num_dst_nodes() + ) + assert ( + dgl_output[0]["blocks"][0].num_edges() + == cugraph_output[0]["blocks"][0].num_edges() + ) + + assert 5 == cugraph_output[0]["blocks"][0].num_edges() + + +@pytest.mark.skipif(isinstance(torch, MissingModule), reason="torch not available") +@pytest.mark.skipif(isinstance(dgl, MissingModule), reason="dgl not available") +def test_dataloader_biased_homogeneous_mg(): + uid = cugraph_comms_create_unique_id() + # Limit the number of GPUs this test is run with + world_size = torch.cuda.device_count() + + torch.multiprocessing.spawn( + run_test_dataloader_biased_homogeneous, + args=(world_size, uid), + nprocs=world_size, + ) diff --git a/python/cugraph-dgl/examples/graphsage/node-classification-dask.py b/python/cugraph-dgl/examples/graphsage/node-classification-dask.py index 992669e4284..0481f9566bc 100644 --- a/python/cugraph-dgl/examples/graphsage/node-classification-dask.py +++ b/python/cugraph-dgl/examples/graphsage/node-classification-dask.py @@ -205,7 +205,9 @@ def train(args, device, g, dataset, model): et = time.time() - print(f"Time taken for epoch {epoch} with batch_size {batch_size} = {et-st} s") + print( + f"Time taken for epoch {epoch} with batch_size {batch_size} = {et - st} s" + ) acc = evaluate(model, g, val_dataloader) print( "Epoch {:05d} | Loss {:.4f} | Accuracy {:.4f} ".format( diff --git a/python/cugraph-dgl/examples/graphsage/node-classification.py b/python/cugraph-dgl/examples/graphsage/node-classification.py index 2b8b687efab..56ac41c09b4 100644 --- a/python/cugraph-dgl/examples/graphsage/node-classification.py +++ b/python/cugraph-dgl/examples/graphsage/node-classification.py @@ -215,7 +215,9 @@ def train(args, device, g, dataset, model, directory): et = time.time() - print(f"Time taken for epoch {epoch} with batch_size {batch_size} = {et-st} s") + print( + f"Time taken for epoch {epoch} with batch_size {batch_size} = {et - st} s" + ) acc = evaluate(model, g, val_dataloader) print( "Epoch {:05d} | Loss {:.4f} | Accuracy {:.4f} ".format( diff --git a/python/cugraph-dgl/examples/multi_trainer_MG_example/model.py b/python/cugraph-dgl/examples/multi_trainer_MG_example/model.py index d3aad2ab309..3e0c0454905 100644 --- a/python/cugraph-dgl/examples/multi_trainer_MG_example/model.py +++ b/python/cugraph-dgl/examples/multi_trainer_MG_example/model.py @@ -134,7 +134,7 @@ def train_model(model, g, opt, train_dataloader, num_epochs, rank, val_nid): et = time.time() print( f"Total time taken for num_epochs {num_epochs} " - f"with batch_size {train_dataloader._batch_size} = {et-st} s on rank ={rank}" + f"with batch_size {train_dataloader._batch_size} = {et - st} s on rank ={rank}" ) if rank == 0: val_acc = layerwise_infer(g, val_nid, model, 1024 * 5, "cuda") diff --git a/python/cugraph-dgl/examples/multi_trainer_MG_example/workflow_mnmg.py b/python/cugraph-dgl/examples/multi_trainer_MG_example/workflow_mnmg.py index b1878b37d4e..11afe466014 100644 --- a/python/cugraph-dgl/examples/multi_trainer_MG_example/workflow_mnmg.py +++ b/python/cugraph-dgl/examples/multi_trainer_MG_example/workflow_mnmg.py @@ -234,7 +234,7 @@ def run_workflow( torch.distributed.barrier() total_et = time.time() print( - f"Total time taken on n_epochs {n_epochs} = {total_et-total_st} s", + f"Total time taken on n_epochs {n_epochs} = {total_et - total_st} s", f"measured by worker = {global_rank}", ) diff --git a/python/cugraph-dgl/examples/multi_trainer_MG_example/workflow_snmg.py b/python/cugraph-dgl/examples/multi_trainer_MG_example/workflow_snmg.py index da5c2b4d64e..001d7fb82dc 100644 --- a/python/cugraph-dgl/examples/multi_trainer_MG_example/workflow_snmg.py +++ b/python/cugraph-dgl/examples/multi_trainer_MG_example/workflow_snmg.py @@ -207,7 +207,7 @@ def run_workflow(rank, world_size, cugraph_id, dataset, temp_dir): torch.distributed.barrier() total_et = time.time() print( - f"Total time taken on n_epochs {n_epochs} = {total_et-total_st} s", + f"Total time taken on n_epochs {n_epochs} = {total_et - total_st} s", f"measured by worker = {rank}", ) diff --git a/python/cugraph-dgl/pyproject.toml b/python/cugraph-dgl/pyproject.toml index 0cfeb10822a..e3e12216ac7 100644 --- a/python/cugraph-dgl/pyproject.toml +++ b/python/cugraph-dgl/pyproject.toml @@ -24,23 +24,23 @@ classifiers = [ "Programming Language :: Python", ] dependencies = [ - "cugraph==24.10.*,>=0.0.0a0", + "cugraph==24.12.*,>=0.0.0a0", "numba>=0.57", - "numpy>=1.23,<2.0a0", - "pylibcugraphops==24.10.*,>=0.0.0a0", + "numpy>=1.23,<3.0a0", + "pylibcugraphops==24.12.*,>=0.0.0a0", ] # This list was generated by `rapids-dependency-file-generator`. To make changes, edit ../../dependencies.yaml and run `rapids-dependency-file-generator`. [project.optional-dependencies] test = [ "pandas", - "pylibwholegraph==24.10.*,>=0.0.0a0", + "pylibwholegraph==24.12.*,>=0.0.0a0", "pytest", "pytest-benchmark", "pytest-cov", "pytest-xdist", "scipy", "tensordict>=0.1.2", - "torch>=2.0,<2.2.0a0", + "torch>=2.3,<2.4.0a0", ] # This list was generated by `rapids-dependency-file-generator`. To make changes, edit ../../dependencies.yaml and run `rapids-dependency-file-generator`. [project.urls] diff --git a/python/cugraph-equivariant/cugraph_equivariant/tests/pytest.ini b/python/cugraph-equivariant/cugraph_equivariant/tests/pytest.ini new file mode 100644 index 00000000000..7b0a9f29fb1 --- /dev/null +++ b/python/cugraph-equivariant/cugraph_equivariant/tests/pytest.ini @@ -0,0 +1,4 @@ +# Copyright (c) 2024, NVIDIA CORPORATION. + +[pytest] +addopts = --tb=native diff --git a/python/cugraph-equivariant/pyproject.toml b/python/cugraph-equivariant/pyproject.toml index 2cc25885b84..7713e89ac20 100644 --- a/python/cugraph-equivariant/pyproject.toml +++ b/python/cugraph-equivariant/pyproject.toml @@ -37,7 +37,7 @@ classifiers = [ "Programming Language :: Python :: 3.12", ] dependencies = [ - "pylibcugraphops==24.10.*,>=0.0.0a0", + "pylibcugraphops==24.12.*,>=0.0.0a0", ] # This list was generated by `rapids-dependency-file-generator`. To make changes, edit ../../dependencies.yaml and run `rapids-dependency-file-generator`. [project.urls] diff --git a/python/cugraph-pyg/conda/cugraph_pyg_dev_cuda-118.yaml b/python/cugraph-pyg/conda/cugraph_pyg_dev_cuda-118.yaml index bd1ca33af70..4778ff0eaf6 100644 --- a/python/cugraph-pyg/conda/cugraph_pyg_dev_cuda-118.yaml +++ b/python/cugraph-pyg/conda/cugraph_pyg_dev_cuda-118.yaml @@ -4,22 +4,21 @@ channels: - rapidsai - rapidsai-nightly - dask/label/dev -- pyg -- dglteam/label/cu118 +- dglteam/label/th23_cu118 - conda-forge - nvidia dependencies: -- cugraph==24.10.*,>=0.0.0a0 +- cugraph==24.12.*,>=0.0.0a0 - pandas - pre-commit -- pyg>=2.5,<2.6 -- pylibcugraphops==24.10.*,>=0.0.0a0 +- pylibcugraphops==24.12.*,>=0.0.0a0 - pytest - pytest-benchmark - pytest-cov - pytest-xdist - pytorch-cuda==11.8 -- pytorch>=2.0 +- pytorch>=2.3,<2.4.0a0 +- pytorch_geometric>=2.5,<2.6 - scipy - tensordict>=0.1.2 name: cugraph_pyg_dev_cuda-118 diff --git a/python/cugraph-pyg/cugraph_pyg/__init__.py b/python/cugraph-pyg/cugraph_pyg/__init__.py index 719751c966a..e566e6e9fdd 100644 --- a/python/cugraph-pyg/cugraph_pyg/__init__.py +++ b/python/cugraph-pyg/cugraph_pyg/__init__.py @@ -1,4 +1,4 @@ -# Copyright (c) 2019-2023, NVIDIA CORPORATION. +# Copyright (c) 2019-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 @@ -12,3 +12,8 @@ # limitations under the License. from cugraph_pyg._version import __git_commit__, __version__ + +import cugraph_pyg.data +import cugraph_pyg.loader +import cugraph_pyg.sampler +import cugraph_pyg.nn diff --git a/python/cugraph-pyg/cugraph_pyg/data/dask_graph_store.py b/python/cugraph-pyg/cugraph_pyg/data/dask_graph_store.py index c805cd496c8..6195f3118a4 100644 --- a/python/cugraph-pyg/cugraph_pyg/data/dask_graph_store.py +++ b/python/cugraph-pyg/cugraph_pyg/data/dask_graph_store.py @@ -150,7 +150,7 @@ def is_set(self, key): if key not in self.__dataclass_fields__: raise KeyError(key) attr = getattr(self, key) - return type(attr) != _field_status or attr != _field_status.UNSET + return type(attr) is not _field_status or attr != _field_status.UNSET def is_fully_specified(self): """ diff --git a/python/cugraph-pyg/cugraph_pyg/data/graph_store.py b/python/cugraph-pyg/cugraph_pyg/data/graph_store.py index 93ea5700c50..c47dda5eaa5 100644 --- a/python/cugraph-pyg/cugraph_pyg/data/graph_store.py +++ b/python/cugraph-pyg/cugraph_pyg/data/graph_store.py @@ -205,13 +205,18 @@ def _num_vertices(self) -> Dict[str, int]: else edge_attr.size[1] ) else: - if edge_attr.edge_type[0] not in num_vertices: + if edge_attr.edge_type[0] != edge_attr.edge_type[2]: + if edge_attr.edge_type[0] not in num_vertices: + num_vertices[edge_attr.edge_type[0]] = int( + self.__edge_indices[edge_attr.edge_type][0].max() + 1 + ) + if edge_attr.edge_type[2] not in num_vertices: + num_vertices[edge_attr.edge_type[1]] = int( + self.__edge_indices[edge_attr.edge_type][1].max() + 1 + ) + elif edge_attr.edge_type[0] not in num_vertices: num_vertices[edge_attr.edge_type[0]] = int( - self.__edge_indices[edge_attr.edge_type][0].max() + 1 - ) - if edge_attr.edge_type[2] not in num_vertices: - num_vertices[edge_attr.edge_type[1]] = int( - self.__edge_indices[edge_attr.edge_type][1].max() + 1 + self.__edge_indices[edge_attr.edge_type].max() + 1 ) if self.is_multi_gpu: diff --git a/python/cugraph-pyg/cugraph_pyg/examples/gcn_dist_mnmg.py b/python/cugraph-pyg/cugraph_pyg/examples/gcn_dist_mnmg.py index 7002d7ebded..127ca809d91 100644 --- a/python/cugraph-pyg/cugraph_pyg/examples/gcn_dist_mnmg.py +++ b/python/cugraph-pyg/cugraph_pyg/examples/gcn_dist_mnmg.py @@ -185,6 +185,8 @@ def run_train( wall_clock_start, tempdir=None, num_layers=3, + in_memory=False, + seeds_per_call=-1, ): optimizer = torch.optim.Adam(model.parameters(), lr=0.01, weight_decay=0.0005) @@ -196,20 +198,23 @@ def run_train( from cugraph_pyg.loader import NeighborLoader ix_train = split_idx["train"].cuda() - train_path = os.path.join(tempdir, f"train_{global_rank}") - os.mkdir(train_path) + train_path = None if in_memory else os.path.join(tempdir, f"train_{global_rank}") + if train_path: + os.mkdir(train_path) train_loader = NeighborLoader( data, input_nodes=ix_train, directory=train_path, shuffle=True, drop_last=True, + local_seeds_per_call=seeds_per_call if seeds_per_call > 0 else None, **kwargs, ) ix_test = split_idx["test"].cuda() - test_path = os.path.join(tempdir, f"test_{global_rank}") - os.mkdir(test_path) + test_path = None if in_memory else os.path.join(tempdir, f"test_{global_rank}") + if test_path: + os.mkdir(test_path) test_loader = NeighborLoader( data, input_nodes=ix_test, @@ -221,14 +226,16 @@ def run_train( ) ix_valid = split_idx["valid"].cuda() - valid_path = os.path.join(tempdir, f"valid_{global_rank}") - os.mkdir(valid_path) + valid_path = None if in_memory else os.path.join(tempdir, f"valid_{global_rank}") + if valid_path: + os.mkdir(valid_path) valid_loader = NeighborLoader( data, input_nodes=ix_valid, directory=valid_path, shuffle=True, drop_last=True, + local_seeds_per_call=seeds_per_call if seeds_per_call > 0 else None, **kwargs, ) @@ -347,6 +354,9 @@ def parse_args(): parser.add_argument("--skip_partition", action="store_true") parser.add_argument("--wg_mem_type", type=str, default="distributed") + parser.add_argument("--in_memory", action="store_true", default=False) + parser.add_argument("--seeds_per_call", type=int, default=-1) + return parser.parse_args() @@ -429,6 +439,8 @@ def parse_args(): wall_clock_start, tempdir, args.num_layers, + args.in_memory, + args.seeds_per_call, ) else: warnings.warn("This script should be run with 'torchrun`. Exiting.") diff --git a/python/cugraph-pyg/cugraph_pyg/examples/gcn_dist_sg.py b/python/cugraph-pyg/cugraph_pyg/examples/gcn_dist_sg.py index b299fc2a1a1..0f9c39bf04d 100644 --- a/python/cugraph-pyg/cugraph_pyg/examples/gcn_dist_sg.py +++ b/python/cugraph-pyg/cugraph_pyg/examples/gcn_dist_sg.py @@ -66,7 +66,7 @@ def train(epoch: int): torch.cuda.synchronize() print( f"Average Training Iteration Time (s/iter): \ - {(time.perf_counter() - start_avg_time)/(i-warmup_steps):.6f}" + {(time.perf_counter() - start_avg_time) / (i - warmup_steps):.6f}" ) @@ -91,10 +91,20 @@ def test(loader: NeighborLoader, val_steps: Optional[int] = None): def create_loader( - data, num_neighbors, input_nodes, replace, batch_size, samples_dir, stage_name + data, + num_neighbors, + input_nodes, + replace, + batch_size, + samples_dir, + stage_name, + local_seeds_per_call, ): - directory = os.path.join(samples_dir, stage_name) - os.mkdir(directory) + if samples_dir is not None: + directory = os.path.join(samples_dir, stage_name) + os.mkdir(directory) + else: + directory = None return NeighborLoader( data, num_neighbors=num_neighbors, @@ -102,6 +112,7 @@ def create_loader( replace=replace, batch_size=batch_size, directory=directory, + local_seeds_per_call=local_seeds_per_call, ) @@ -147,6 +158,8 @@ def parse_args(): parser.add_argument("--tempdir_root", type=str, default=None) parser.add_argument("--dataset_root", type=str, default="dataset") parser.add_argument("--dataset", type=str, default="ogbn-products") + parser.add_argument("--in_memory", action="store_true", default=False) + parser.add_argument("--seeds_per_call", type=int, default=-1) return parser.parse_args() @@ -170,7 +183,10 @@ def parse_args(): "num_neighbors": [args.fan_out] * args.num_layers, "replace": False, "batch_size": args.batch_size, - "samples_dir": samples_dir, + "samples_dir": None if args.in_memory else samples_dir, + "local_seeds_per_call": None + if args.seeds_per_call <= 0 + else args.seeds_per_call, } train_loader = create_loader( diff --git a/python/cugraph-pyg/cugraph_pyg/examples/gcn_dist_snmg.py b/python/cugraph-pyg/cugraph_pyg/examples/gcn_dist_snmg.py index b1bb0240e71..73efbc92a24 100644 --- a/python/cugraph-pyg/cugraph_pyg/examples/gcn_dist_snmg.py +++ b/python/cugraph-pyg/cugraph_pyg/examples/gcn_dist_snmg.py @@ -86,6 +86,8 @@ def run_train( wall_clock_start, tempdir=None, num_layers=3, + in_memory=False, + seeds_per_call=-1, ): init_pytorch_worker( @@ -119,20 +121,23 @@ def run_train( dist.barrier() ix_train = torch.tensor_split(split_idx["train"], world_size)[rank].cuda() - train_path = os.path.join(tempdir, f"train_{rank}") - os.mkdir(train_path) + train_path = None if in_memory else os.path.join(tempdir, f"train_{rank}") + if train_path: + os.mkdir(train_path) train_loader = NeighborLoader( (feature_store, graph_store), input_nodes=ix_train, directory=train_path, shuffle=True, drop_last=True, + local_seeds_per_call=seeds_per_call if seeds_per_call > 0 else None, **kwargs, ) ix_test = torch.tensor_split(split_idx["test"], world_size)[rank].cuda() - test_path = os.path.join(tempdir, f"test_{rank}") - os.mkdir(test_path) + test_path = None if in_memory else os.path.join(tempdir, f"test_{rank}") + if test_path: + os.mkdir(test_path) test_loader = NeighborLoader( (feature_store, graph_store), input_nodes=ix_test, @@ -144,14 +149,16 @@ def run_train( ) ix_valid = torch.tensor_split(split_idx["valid"], world_size)[rank].cuda() - valid_path = os.path.join(tempdir, f"valid_{rank}") - os.mkdir(valid_path) + valid_path = None if in_memory else os.path.join(tempdir, f"valid_{rank}") + if valid_path: + os.mkdir(valid_path) valid_loader = NeighborLoader( (feature_store, graph_store), input_nodes=ix_valid, directory=valid_path, shuffle=True, drop_last=True, + local_seeds_per_call=seeds_per_call if seeds_per_call > 0 else None, **kwargs, ) @@ -269,6 +276,8 @@ def run_train( parser.add_argument("--tempdir_root", type=str, default=None) parser.add_argument("--dataset_root", type=str, default="dataset") parser.add_argument("--dataset", type=str, default="ogbn-products") + parser.add_argument("--in_memory", action="store_true", default=False) + parser.add_argument("--seeds_per_call", type=int, default=-1) parser.add_argument( "--n_devices", @@ -322,6 +331,8 @@ def run_train( wall_clock_start, tempdir, args.num_layers, + args.in_memory, + args.seeds_per_call, ), nprocs=world_size, join=True, diff --git a/python/cugraph-pyg/cugraph_pyg/examples/rgcn_link_class_mnmg.py b/python/cugraph-pyg/cugraph_pyg/examples/rgcn_link_class_mnmg.py new file mode 100644 index 00000000000..5c75e01e6f5 --- /dev/null +++ b/python/cugraph-pyg/cugraph_pyg/examples/rgcn_link_class_mnmg.py @@ -0,0 +1,418 @@ +# 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. + +# This example illustrates link classification using the ogbl-wikikg2 dataset. + +import os +import json +import argparse +import warnings + +import torch + +import torch.nn.functional as F +from torch.nn import Parameter +from torch_geometric.nn import FastRGCNConv, GAE +from torch.nn.parallel import DistributedDataParallel + +from ogb.linkproppred import PygLinkPropPredDataset + +import cugraph_pyg + +from cugraph.gnn import ( + cugraph_comms_init, + cugraph_comms_create_unique_id, + cugraph_comms_shutdown, +) + +from pylibwholegraph.torch.initialize import ( + init as wm_init, + finalize as wm_finalize, +) + + +# Enable cudf spilling to save gpu memory +from cugraph.testing.mg_utils import enable_spilling + +# Ensures that a CUDA context is not created on import of rapids. +# Allows pytorch to create the context instead +os.environ["RAPIDS_NO_INITIALIZE"] = "1" + + +def init_pytorch_worker(global_rank, local_rank, world_size, uid): + import rmm + + rmm.reinitialize(devices=[local_rank], pool_allocator=True, managed_memory=True) + + import cupy + from rmm.allocators.cupy import rmm_cupy_allocator + + cupy.cuda.set_allocator(rmm_cupy_allocator) + + cugraph_comms_init( + global_rank, + world_size, + uid, + local_rank, + ) + + wm_init(global_rank, world_size, local_rank, torch.cuda.device_count()) + + enable_spilling() + + +class RGCNEncoder(torch.nn.Module): + def __init__(self, num_nodes, hidden_channels, num_relations, num_bases=30): + super().__init__() + self.node_emb = Parameter(torch.empty(num_nodes, hidden_channels)) + self.conv1 = FastRGCNConv( + hidden_channels, hidden_channels, num_relations, num_bases=num_bases + ) + self.conv2 = FastRGCNConv( + hidden_channels, hidden_channels, num_relations, num_bases=num_bases + ) + self.reset_parameters() + + def reset_parameters(self): + torch.nn.init.xavier_uniform_(self.node_emb) + self.conv1.reset_parameters() + self.conv2.reset_parameters() + + def forward(self, edge_index, edge_type): + x = self.node_emb + x = self.conv1(x, edge_index, edge_type).relu_() + x = F.dropout(x, p=0.2, training=self.training) + x = self.conv2(x, edge_index, edge_type) + return x + + +def train(epoch, model, optimizer, train_loader, edge_feature_store, num_steps=None): + model.train() + optimizer.zero_grad() + + for i, batch in enumerate(train_loader): + r = edge_feature_store[("n", "e", "n"), "rel"][batch.e_id].flatten().cuda() + z = model.encode(batch.edge_index, r) + + loss = model.recon_loss(z, batch.edge_index) + loss.backward() + optimizer.step() + + if i % 10 == 0: + print( + f"Epoch: {epoch:02d}, Iteration: {i:02d}, Loss: {loss:.4f}", flush=True + ) + if num_steps and i == num_steps: + break + + +def test(stage, epoch, model, loader, num_steps=None): + # TODO support ROC-AUC metric + # Predict probabilities of future edges + model.eval() + + rr = 0.0 + for i, (h, h_neg, t, t_neg, r) in enumerate(loader): + if num_steps and i >= num_steps: + break + + ei = torch.concatenate( + [ + torch.stack([h, t]).cuda(), + torch.stack([h_neg.flatten(), t_neg.flatten()]).cuda(), + ], + dim=-1, + ) + + r = torch.concatenate([r, torch.repeat_interleave(r, h_neg.shape[-1])]).cuda() + + z = model.encode(ei, r) + q = model.decode(z, ei) + + _, ix = torch.sort(q, descending=True) + rr += 1.0 / (1.0 + ix[0]) + + print(f"epoch {epoch:02d} {stage} mrr:", rr / i, flush=True) + + +def parse_args(): + parser = argparse.ArgumentParser() + parser.add_argument("--hidden_channels", type=int, default=128) + parser.add_argument("--num_layers", type=int, default=1) + parser.add_argument("--lr", type=float, default=0.001) + parser.add_argument("--epochs", type=int, default=4) + parser.add_argument("--batch_size", type=int, default=16384) + parser.add_argument("--num_neg", type=int, default=500) + parser.add_argument("--num_pos", type=int, default=-1) + parser.add_argument("--fan_out", type=int, default=10) + parser.add_argument("--dataset", type=str, default="ogbl-wikikg2") + parser.add_argument("--dataset_root", type=str, default="dataset") + parser.add_argument("--seeds_per_call", type=int, default=-1) + parser.add_argument("--n_devices", type=int, default=-1) + parser.add_argument("--skip_partition", action="store_true") + + return parser.parse_args() + + +def run_train(rank, world_size, model, data, edge_feature_store, meta, splits, args): + model = model.to(rank) + model = GAE(DistributedDataParallel(model, device_ids=[rank])) + optimizer = torch.optim.Adam(model.parameters(), lr=args.lr) + + eli = torch.stack([splits["train"]["head"], splits["train"]["tail"]]) + + train_loader = cugraph_pyg.loader.LinkNeighborLoader( + data, + [args.fan_out] * args.num_layers, + edge_label_index=eli, + local_seeds_per_call=args.seeds_per_call if args.seeds_per_call > 0 else None, + batch_size=args.batch_size, + shuffle=True, + drop_last=True, + ) + + def get_eval_loader(stage: str): + head = splits[stage]["head"] + tail = splits[stage]["tail"] + + head_neg = splits[stage]["head_neg"][:, : args.num_neg] + tail_neg = splits[stage]["tail_neg"][:, : args.num_neg] + + rel = splits[stage]["relation"] + + return torch.utils.data.DataLoader( + torch.utils.data.TensorDataset( + head.pin_memory(), + head_neg.pin_memory(), + tail.pin_memory(), + tail_neg.pin_memory(), + rel.pin_memory(), + ), + batch_size=1, + shuffle=False, + drop_last=True, + ) + + test_loader = get_eval_loader("test") + valid_loader = get_eval_loader("valid") + + num_train_steps = (args.num_pos // args.batch_size) if args.num_pos > 0 else 100 + + for epoch in range(1, 1 + args.epochs): + train( + epoch, + model, + optimizer, + train_loader, + edge_feature_store, + num_steps=num_train_steps, + ) + test("validation", epoch, model, valid_loader, num_steps=1024) + + test("test", epoch, model, test_loader, num_steps=1024) + + wm_finalize() + cugraph_comms_shutdown() + + +def partition_data( + data, splits, meta, edge_path, rel_path, pos_path, neg_path, meta_path +): + # Split and save edge index + os.makedirs( + edge_path, + exist_ok=True, + ) + for (r, e) in enumerate(torch.tensor_split(data.edge_index, world_size, dim=1)): + rank_path = os.path.join(edge_path, f"rank={r}.pt") + torch.save( + e.clone(), + rank_path, + ) + + # Split and save edge reltypes + os.makedirs( + rel_path, + exist_ok=True, + ) + for (r, f) in enumerate(torch.tensor_split(data.edge_reltype, world_size)): + rank_path = os.path.join(rel_path, f"rank={r}.pt") + torch.save( + f.clone(), + rank_path, + ) + + # Split and save positive edges + os.makedirs( + pos_path, + exist_ok=True, + ) + for stage in ["train", "test", "valid"]: + for (r, n) in enumerate( + torch.tensor_split( + torch.stack([splits[stage]["head"], splits[stage]["tail"]]), + world_size, + dim=-1, + ) + ): + rank_path = os.path.join(pos_path, f"rank={r}_{stage}.pt") + torch.save( + n.clone(), + rank_path, + ) + + # Split and save negative edges + os.makedirs( + neg_path, + exist_ok=True, + ) + for stage in ["test", "valid"]: + for (r, n) in enumerate( + torch.tensor_split( + torch.stack([splits[stage]["head_neg"], splits[stage]["tail_neg"]]), + world_size, + dim=1, + ) + ): + rank_path = os.path.join(neg_path, f"rank={r}_{stage}.pt") + torch.save(n.clone(), rank_path) + for (r, n) in enumerate( + torch.tensor_split(splits[stage]["relation"], world_size, dim=-1) + ): + print(n) + rank_path = os.path.join(neg_path, f"rank={r}_{stage}_relation.pt") + torch.save(n.clone(), rank_path) + + with open(meta_path, "w") as f: + json.dump(meta, f) + + +def load_partitioned_data(rank, edge_path, rel_path, pos_path, neg_path, meta_path): + from cugraph_pyg.data import GraphStore, WholeFeatureStore, TensorDictFeatureStore + + graph_store = GraphStore() + feature_store = TensorDictFeatureStore() + edge_feature_store = WholeFeatureStore() + + # Load edge index + graph_store[("n", "e", "n"), "coo"] = torch.load( + os.path.join(edge_path, f"rank={rank}.pt") + ) + + # Load edge rel type + edge_feature_store[("n", "e", "n"), "rel"] = torch.load( + os.path.join(rel_path, f"rank={rank}.pt") + ) + + splits = {} + + # Load positive edges + for stage in ["train", "test", "valid"]: + head, tail = torch.load(os.path.join(pos_path, f"rank={rank}_{stage}.pt")) + splits[stage] = { + "head": head, + "tail": tail, + } + + # Load negative edges + for stage in ["test", "valid"]: + head_neg, tail_neg = torch.load( + os.path.join(neg_path, f"rank={rank}_{stage}.pt") + ) + relation = torch.load( + os.path.join(neg_path, f"rank={rank}_{stage}_relation.pt") + ) + splits[stage]["head_neg"] = head_neg + splits[stage]["tail_neg"] = tail_neg + splits[stage]["relation"] = relation + + with open(meta_path, "r") as f: + meta = json.load(f) + + return (feature_store, graph_store), edge_feature_store, splits, meta + + +if __name__ == "__main__": + args = parse_args() + + if "LOCAL_RANK" in os.environ: + torch.distributed.init_process_group("nccl") + world_size = torch.distributed.get_world_size() + global_rank = torch.distributed.get_rank() + local_rank = int(os.environ["LOCAL_RANK"]) + device = torch.device(local_rank) + + # Create the uid needed for cuGraph comms + if global_rank == 0: + cugraph_id = [cugraph_comms_create_unique_id()] + else: + cugraph_id = [None] + torch.distributed.broadcast_object_list(cugraph_id, src=0, device=device) + cugraph_id = cugraph_id[0] + + init_pytorch_worker(global_rank, local_rank, world_size, cugraph_id) + + # Split the data + edge_path = os.path.join(args.dataset_root, args.dataset + "_eix_part") + rel_path = os.path.join(args.dataset_root, args.dataset + "_rel_part") + pos_path = os.path.join(args.dataset_root, args.dataset + "_e_pos_part") + neg_path = os.path.join(args.dataset_root, args.dataset + "_e_neg_part") + meta_path = os.path.join(args.dataset_root, args.dataset + "_meta.json") + + if not args.skip_partition and global_rank == 0: + data = PygLinkPropPredDataset(args.dataset, root=args.dataset_root) + dataset = data[0] + + splits = data.get_edge_split() + + meta = {} + meta["num_nodes"] = int(dataset.num_nodes) + meta["num_rels"] = int(dataset.edge_reltype.max()) + 1 + + partition_data( + dataset, + splits, + meta, + edge_path=edge_path, + rel_path=rel_path, + pos_path=pos_path, + neg_path=neg_path, + meta_path=meta_path, + ) + del data + del dataset + del splits + torch.distributed.barrier() + + # Load partitions + data, edge_feature_store, splits, meta = load_partitioned_data( + rank=global_rank, + edge_path=edge_path, + rel_path=rel_path, + pos_path=pos_path, + neg_path=neg_path, + meta_path=meta_path, + ) + torch.distributed.barrier() + + model = RGCNEncoder( + meta["num_nodes"], + hidden_channels=args.hidden_channels, + num_relations=meta["num_rels"], + ) + + run_train( + global_rank, world_size, model, data, edge_feature_store, meta, splits, args + ) + else: + warnings.warn("This script should be run with 'torchrun`. Exiting.") diff --git a/python/cugraph-pyg/cugraph_pyg/examples/rgcn_link_class_sg.py b/python/cugraph-pyg/cugraph_pyg/examples/rgcn_link_class_sg.py new file mode 100644 index 00000000000..67d7eecc7c2 --- /dev/null +++ b/python/cugraph-pyg/cugraph_pyg/examples/rgcn_link_class_sg.py @@ -0,0 +1,219 @@ +# 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. + +# This example illustrates link classification using the ogbl-wikikg2 dataset. + +import argparse + +from typing import Tuple, Dict, Any + +import torch +import cupy + +import rmm +from rmm.allocators.cupy import rmm_cupy_allocator +from rmm.allocators.torch import rmm_torch_allocator + +# Must change allocators immediately upon import +# or else other imports will cause memory to be +# allocated and prevent changing the allocator +rmm.reinitialize(devices=[0], pool_allocator=True, managed_memory=True) +cupy.cuda.set_allocator(rmm_cupy_allocator) +torch.cuda.memory.change_current_allocator(rmm_torch_allocator) + +import torch.nn.functional as F # noqa: E402 +from torch.nn import Parameter # noqa: E402 +from torch_geometric.nn import FastRGCNConv, GAE # noqa: E402 +import torch_geometric # noqa: E402 +import cugraph_pyg # noqa: E402 + +# Enable cudf spilling to save gpu memory +from cugraph.testing.mg_utils import enable_spilling # noqa: E402 + +enable_spilling() + + +class RGCNEncoder(torch.nn.Module): + def __init__(self, num_nodes, hidden_channels, num_relations, num_bases=30): + super().__init__() + self.node_emb = Parameter(torch.empty(num_nodes, hidden_channels)) + self.conv1 = FastRGCNConv( + hidden_channels, hidden_channels, num_relations, num_bases=num_bases + ) + self.conv2 = FastRGCNConv( + hidden_channels, hidden_channels, num_relations, num_bases=num_bases + ) + self.reset_parameters() + + def reset_parameters(self): + torch.nn.init.xavier_uniform_(self.node_emb) + self.conv1.reset_parameters() + self.conv2.reset_parameters() + + def forward(self, edge_index, edge_type): + x = self.node_emb + x = self.conv1(x, edge_index, edge_type).relu_() + x = F.dropout(x, p=0.2, training=self.training) + x = self.conv2(x, edge_index, edge_type) + return x + + +def load_data( + dataset_str, dataset_root: str +) -> Tuple[ + Tuple["torch_geometric.data.FeatureStore", "torch_geometric.data.GraphStore"], + "torch_geometric.data.FeatureStore", + Dict[str, Dict[str, "torch.Tensor"]], + Dict[str, Any], +]: + from ogb.linkproppred import PygLinkPropPredDataset + + data = PygLinkPropPredDataset(dataset_str, root=dataset_root) + dataset = data[0] + + splits = data.get_edge_split() + + from cugraph_pyg.data import GraphStore, TensorDictFeatureStore + + graph_store = GraphStore() + feature_store = TensorDictFeatureStore() + edge_feature_store = TensorDictFeatureStore() + meta = {} + + graph_store[("n", "e", "n"), "coo"] = dataset.edge_index + edge_feature_store[("n", "e", "n"), "rel"] = dataset.edge_reltype.pin_memory() + meta["num_nodes"] = dataset.num_nodes + meta["num_rels"] = dataset.edge_reltype.max() + 1 + + return (feature_store, graph_store), edge_feature_store, splits, meta + + +def train(epoch, model, optimizer, train_loader, edge_feature_store): + model.train() + optimizer.zero_grad() + + for i, batch in enumerate(train_loader): + r = edge_feature_store[("n", "e", "n"), "rel"][batch.e_id].flatten().cuda() + z = model.encode(batch.edge_index, r) + + loss = model.recon_loss(z, batch.edge_index) + loss.backward() + optimizer.step() + + if i % 10 == 0: + print(f"Epoch: {epoch:02d}, Iteration: {i:02d}, Loss: {loss:.4f}") + if i == 100: + break + + +def test(stage, epoch, model, loader, num_steps=None): + # TODO support ROC-AUC metric + # Predict probabilities of future edges + model.eval() + + rr = 0.0 + for i, (h, h_neg, t, t_neg, r) in enumerate(loader): + if num_steps and i >= num_steps: + break + + ei = torch.concatenate( + [ + torch.stack([h, t]).cuda(), + torch.stack([h_neg.flatten(), t_neg.flatten()]).cuda(), + ], + dim=-1, + ) + + r = torch.concatenate([r, torch.repeat_interleave(r, h_neg.shape[-1])]).cuda() + + z = model.encode(ei, r) + q = model.decode(z, ei) + + _, ix = torch.sort(q, descending=True) + rr += 1.0 / (1.0 + ix[0]) + + print(f"epoch {epoch:02d} {stage} mrr:", rr / i) + + +def parse_args(): + parser = argparse.ArgumentParser() + parser.add_argument("--hidden_channels", type=int, default=128) + parser.add_argument("--num_layers", type=int, default=1) + parser.add_argument("--lr", type=float, default=0.001) + parser.add_argument("--epochs", type=int, default=4) + parser.add_argument("--batch_size", type=int, default=16384) + parser.add_argument("--num_neg", type=int, default=500) + parser.add_argument("--fan_out", type=int, default=10) + parser.add_argument("--dataset", type=str, default="ogbl-wikikg2") + parser.add_argument("--dataset_root", type=str, default="dataset") + parser.add_argument("--seeds_per_call", type=int, default=-1) + + return parser.parse_args() + + +if __name__ == "__main__": + args = parse_args() + + data, edge_feature_store, splits, meta = load_data(args.dataset, args.dataset_root) + + model = GAE( + RGCNEncoder( + meta["num_nodes"], + hidden_channels=args.hidden_channels, + num_relations=meta["num_rels"], + ) + ).cuda() + optimizer = torch.optim.Adam(model.parameters(), lr=args.lr) + + train_loader = cugraph_pyg.loader.LinkNeighborLoader( + data, + [args.fan_out] * args.num_layers, + edge_label_index=torch.stack( + [splits["train"]["head"], splits["train"]["tail"]] + ), + local_seeds_per_call=args.seeds_per_call if args.seeds_per_call > 0 else None, + batch_size=args.batch_size, + shuffle=True, + drop_last=True, + ) + + def get_eval_loader(stage: str): + head = splits[stage]["head"] + tail = splits[stage]["tail"] + + head_neg = splits[stage]["head_neg"][:, : args.num_neg] + tail_neg = splits[stage]["tail_neg"][:, : args.num_neg] + + rel = splits[stage]["relation"] + + return torch.utils.data.DataLoader( + torch.utils.data.TensorDataset( + head.pin_memory(), + head_neg.pin_memory(), + tail.pin_memory(), + tail_neg.pin_memory(), + rel.pin_memory(), + ), + batch_size=1, + shuffle=False, + drop_last=True, + ) + + test_loader = get_eval_loader("test") + valid_loader = get_eval_loader("valid") + + for epoch in range(1, 1 + args.epochs): + train(epoch, model, optimizer, train_loader, edge_feature_store) + test("validation", epoch, model, valid_loader, num_steps=1024) + + test("test", epoch, model, test_loader, num_steps=1024) diff --git a/python/cugraph-pyg/cugraph_pyg/examples/rgcn_link_class_snmg.py b/python/cugraph-pyg/cugraph_pyg/examples/rgcn_link_class_snmg.py new file mode 100644 index 00000000000..2c0ae53a08e --- /dev/null +++ b/python/cugraph-pyg/cugraph_pyg/examples/rgcn_link_class_snmg.py @@ -0,0 +1,320 @@ +# 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. + +# This example illustrates link classification using the ogbl-wikikg2 dataset. + +import os +import argparse +import warnings + +from typing import Tuple, Any + +import torch + +import torch.nn.functional as F +from torch.nn import Parameter +from torch_geometric.nn import FastRGCNConv, GAE +from torch.nn.parallel import DistributedDataParallel + +import torch_geometric +import cugraph_pyg + +from cugraph.gnn import ( + cugraph_comms_init, + cugraph_comms_create_unique_id, + cugraph_comms_shutdown, +) + +from pylibwholegraph.torch.initialize import ( + init as wm_init, + finalize as wm_finalize, +) + + +# Enable cudf spilling to save gpu memory +from cugraph.testing.mg_utils import enable_spilling + +# Ensures that a CUDA context is not created on import of rapids. +# Allows pytorch to create the context instead +os.environ["RAPIDS_NO_INITIALIZE"] = "1" + + +def init_pytorch_worker(rank, world_size, uid): + import rmm + + rmm.reinitialize(devices=[rank], pool_allocator=True, managed_memory=True) + + import cupy + from rmm.allocators.cupy import rmm_cupy_allocator + + cupy.cuda.set_allocator(rmm_cupy_allocator) + + cugraph_comms_init( + rank, + world_size, + uid, + rank, + ) + + wm_init(rank, world_size, rank, world_size) + + os.environ["MASTER_ADDR"] = "localhost" + os.environ["MASTER_PORT"] = "12355" + torch.distributed.init_process_group( + "nccl", + rank=rank, + world_size=world_size, + ) + + enable_spilling() + + +class RGCNEncoder(torch.nn.Module): + def __init__(self, num_nodes, hidden_channels, num_relations, num_bases=30): + super().__init__() + self.node_emb = Parameter(torch.empty(num_nodes, hidden_channels)) + self.conv1 = FastRGCNConv( + hidden_channels, hidden_channels, num_relations, num_bases=num_bases + ) + self.conv2 = FastRGCNConv( + hidden_channels, hidden_channels, num_relations, num_bases=num_bases + ) + self.reset_parameters() + + def reset_parameters(self): + torch.nn.init.xavier_uniform_(self.node_emb) + self.conv1.reset_parameters() + self.conv2.reset_parameters() + + def forward(self, edge_index, edge_type): + x = self.node_emb + x = self.conv1(x, edge_index, edge_type).relu_() + x = F.dropout(x, p=0.2, training=self.training) + x = self.conv2(x, edge_index, edge_type) + return x + + +def load_data( + rank: int, + world_size: int, + data: Any, +) -> Tuple[ + Tuple["torch_geometric.data.FeatureStore", "torch_geometric.data.GraphStore"], + "torch_geometric.data.FeatureStore", +]: + from cugraph_pyg.data import GraphStore, WholeFeatureStore, TensorDictFeatureStore + + graph_store = GraphStore() + feature_store = TensorDictFeatureStore() # empty fs required by PyG + edge_feature_store = WholeFeatureStore() + + graph_store[("n", "e", "n"), "coo"] = torch.tensor_split( + data.edge_index.cuda(), world_size, dim=1 + )[rank] + + edge_feature_store[("n", "e", "n"), "rel"] = torch.tensor_split( + data.edge_reltype.cuda(), + world_size, + )[rank] + + return (feature_store, graph_store), edge_feature_store + + +def train(epoch, model, optimizer, train_loader, edge_feature_store, num_steps=None): + model.train() + optimizer.zero_grad() + + for i, batch in enumerate(train_loader): + r = edge_feature_store[("n", "e", "n"), "rel"][batch.e_id].flatten().cuda() + z = model.encode(batch.edge_index, r) + + loss = model.recon_loss(z, batch.edge_index) + loss.backward() + optimizer.step() + + if i % 10 == 0: + print( + f"Epoch: {epoch:02d}, Iteration: {i:02d}, Loss: {loss:.4f}", flush=True + ) + if num_steps and i == num_steps: + break + + +def test(stage, epoch, model, loader, num_steps=None): + # TODO support ROC-AUC metric + # Predict probabilities of future edges + model.eval() + + rr = 0.0 + for i, (h, h_neg, t, t_neg, r) in enumerate(loader): + if num_steps and i >= num_steps: + break + + ei = torch.concatenate( + [ + torch.stack([h, t]).cuda(), + torch.stack([h_neg.flatten(), t_neg.flatten()]).cuda(), + ], + dim=-1, + ) + + r = torch.concatenate([r, torch.repeat_interleave(r, h_neg.shape[-1])]).cuda() + + z = model.encode(ei, r) + q = model.decode(z, ei) + + _, ix = torch.sort(q, descending=True) + rr += 1.0 / (1.0 + ix[0]) + + print(f"epoch {epoch:02d} {stage} mrr:", rr / i, flush=True) + + +def parse_args(): + parser = argparse.ArgumentParser() + parser.add_argument("--hidden_channels", type=int, default=128) + parser.add_argument("--num_layers", type=int, default=1) + parser.add_argument("--lr", type=float, default=0.001) + parser.add_argument("--epochs", type=int, default=4) + parser.add_argument("--batch_size", type=int, default=16384) + parser.add_argument("--num_neg", type=int, default=500) + parser.add_argument("--num_pos", type=int, default=-1) + parser.add_argument("--fan_out", type=int, default=10) + parser.add_argument("--dataset", type=str, default="ogbl-wikikg2") + parser.add_argument("--dataset_root", type=str, default="dataset") + parser.add_argument("--seeds_per_call", type=int, default=-1) + parser.add_argument("--n_devices", type=int, default=-1) + + return parser.parse_args() + + +def run_train(rank, world_size, uid, model, data, meta, splits, args): + init_pytorch_worker( + rank, + world_size, + uid, + ) + + model = model.to(rank) + model = GAE(DistributedDataParallel(model, device_ids=[rank])) + optimizer = torch.optim.Adam(model.parameters(), lr=args.lr) + + data, edge_feature_store = load_data(rank, world_size, data) + + eli = torch.stack( + [ + torch.tensor_split(splits["train"]["head"], world_size)[rank], + torch.tensor_split(splits["train"]["tail"], world_size)[rank], + ] + ) + + train_loader = cugraph_pyg.loader.LinkNeighborLoader( + data, + [args.fan_out] * args.num_layers, + edge_label_index=eli, + local_seeds_per_call=args.seeds_per_call if args.seeds_per_call > 0 else None, + batch_size=args.batch_size, + shuffle=True, + drop_last=True, + ) + + def get_eval_loader(stage: str): + head = torch.tensor_split(splits[stage]["head"], world_size)[rank] + tail = torch.tensor_split(splits[stage]["tail"], world_size)[rank] + + head_neg = torch.tensor_split( + splits[stage]["head_neg"][:, : args.num_neg], world_size + )[rank] + tail_neg = torch.tensor_split( + splits[stage]["tail_neg"][:, : args.num_neg], world_size + )[rank] + + rel = torch.tensor_split(splits[stage]["relation"], world_size)[rank] + + return torch.utils.data.DataLoader( + torch.utils.data.TensorDataset( + head.pin_memory(), + head_neg.pin_memory(), + tail.pin_memory(), + tail_neg.pin_memory(), + rel.pin_memory(), + ), + batch_size=1, + shuffle=False, + drop_last=True, + ) + + test_loader = get_eval_loader("test") + valid_loader = get_eval_loader("valid") + + num_train_steps = (args.num_pos // args.batch_size) if args.num_pos > 0 else 100 + + for epoch in range(1, 1 + args.epochs): + train( + epoch, + model, + optimizer, + train_loader, + edge_feature_store, + num_steps=num_train_steps, + ) + test("validation", epoch, model, valid_loader, num_steps=1024) + + test("test", epoch, model, test_loader, num_steps=1024) + + wm_finalize() + cugraph_comms_shutdown() + + +if __name__ == "__main__": + if "CI_RUN" in os.environ and os.environ["CI_RUN"] == "1": + warnings.warn("Skipping SMNG example in CI due to memory limit") + else: + args = parse_args() + + # change the allocator before any allocations are made + from rmm.allocators.torch import rmm_torch_allocator + + torch.cuda.memory.change_current_allocator(rmm_torch_allocator) + + # import ogb here to stop it from creating a context and breaking pytorch/rmm + from ogb.linkproppred import PygLinkPropPredDataset + + data = PygLinkPropPredDataset(args.dataset, root=args.dataset_root) + dataset = data[0] + + splits = data.get_edge_split() + + meta = {} + meta["num_nodes"] = dataset.num_nodes + meta["num_rels"] = dataset.edge_reltype.max() + 1 + + model = RGCNEncoder( + meta["num_nodes"], + hidden_channels=args.hidden_channels, + num_relations=meta["num_rels"], + ) + + print("Data =", data) + if args.n_devices == -1: + world_size = torch.cuda.device_count() + else: + world_size = args.n_devices + print("Using", world_size, "GPUs...") + + uid = cugraph_comms_create_unique_id() + torch.multiprocessing.spawn( + run_train, + (world_size, uid, model, data, meta, splits, args), + nprocs=world_size, + join=True, + ) diff --git a/python/cugraph-pyg/cugraph_pyg/loader/__init__.py b/python/cugraph-pyg/cugraph_pyg/loader/__init__.py index cad66aaa183..c804b3d1f97 100644 --- a/python/cugraph-pyg/cugraph_pyg/loader/__init__.py +++ b/python/cugraph-pyg/cugraph_pyg/loader/__init__.py @@ -16,6 +16,9 @@ from cugraph_pyg.loader.node_loader import NodeLoader from cugraph_pyg.loader.neighbor_loader import NeighborLoader +from cugraph_pyg.loader.link_loader import LinkLoader +from cugraph_pyg.loader.link_neighbor_loader import LinkNeighborLoader + from cugraph_pyg.loader.dask_node_loader import DaskNeighborLoader from cugraph_pyg.loader.dask_node_loader import BulkSampleLoader diff --git a/python/cugraph-pyg/cugraph_pyg/loader/link_loader.py b/python/cugraph-pyg/cugraph_pyg/loader/link_loader.py new file mode 100644 index 00000000000..77e2ac4f99d --- /dev/null +++ b/python/cugraph-pyg/cugraph_pyg/loader/link_loader.py @@ -0,0 +1,205 @@ +# 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 warnings + +import cugraph_pyg +from typing import Union, Tuple, Callable, Optional + +from cugraph.utilities.utils import import_optional + +torch_geometric = import_optional("torch_geometric") +torch = import_optional("torch") + + +class LinkLoader: + """ + Duck-typed version of torch_geometric.loader.LinkLoader. + Loads samples from batches of input nodes using a + `~cugraph_pyg.sampler.BaseSampler.sample_from_edges` + function. + """ + + def __init__( + self, + data: Union[ + "torch_geometric.data.Data", + "torch_geometric.data.HeteroData", + Tuple[ + "torch_geometric.data.FeatureStore", "torch_geometric.data.GraphStore" + ], + ], + link_sampler: "cugraph_pyg.sampler.BaseSampler", + edge_label_index: "torch_geometric.typing.InputEdges" = None, + edge_label: "torch_geometric.typing.OptTensor" = None, + edge_label_time: "torch_geometric.typing.OptTensor" = None, + neg_sampling: Optional["torch_geometric.sampler.NegativeSampling"] = None, + neg_sampling_ratio: Optional[Union[int, float]] = None, + transform: Optional[Callable] = None, + transform_sampler_output: Optional[Callable] = None, + filter_per_worker: Optional[bool] = None, + custom_cls: Optional["torch_geometric.data.HeteroData"] = None, + input_id: "torch_geometric.typing.OptTensor" = None, + batch_size: int = 1, # refers to number of edges in batch + shuffle: bool = False, + drop_last: bool = False, + **kwargs, + ): + """ + Parameters + ---------- + data: Data, HeteroData, or Tuple[FeatureStore, GraphStore] + See torch_geometric.loader.NodeLoader. + link_sampler: BaseSampler + See torch_geometric.loader.LinkLoader. + edge_label_index: InputEdges + See torch_geometric.loader.LinkLoader. + edge_label: OptTensor + See torch_geometric.loader.LinkLoader. + edge_label_time: OptTensor + See torch_geometric.loader.LinkLoader. + neg_sampling: Optional[NegativeSampling] + Type of negative sampling to perform, if desired. + See torch_geometric.loader.LinkLoader. + neg_sampling_ratio: Optional[Union[int, float]] + Negative sampling ratio. Affects how many negative + samples are generated. + See torch_geometric.loader.LinkLoader. + transform: Callable (optional, default=None) + This argument currently has no effect. + transform_sampler_output: Callable (optional, default=None) + This argument currently has no effect. + filter_per_worker: bool (optional, default=False) + This argument currently has no effect. + custom_cls: HeteroData + This argument currently has no effect. This loader will + always return a Data or HeteroData object. + input_id: OptTensor + See torch_geometric.loader.LinkLoader. + + """ + if not isinstance(data, (list, tuple)) or not isinstance( + data[1], cugraph_pyg.data.GraphStore + ): + # Will eventually automatically convert these objects to cuGraph objects. + raise NotImplementedError("Currently can't accept non-cugraph graphs") + + if not isinstance(link_sampler, cugraph_pyg.sampler.BaseSampler): + raise NotImplementedError("Must provide a cuGraph sampler") + + if edge_label_time is not None: + raise ValueError("Temporal sampling is currently unsupported") + + if filter_per_worker: + warnings.warn("filter_per_worker is currently ignored") + + if custom_cls is not None: + warnings.warn("custom_cls is currently ignored") + + if transform is not None: + warnings.warn("transform is currently ignored.") + + if transform_sampler_output is not None: + warnings.warn("transform_sampler_output is currently ignored.") + + if neg_sampling_ratio is not None: + warnings.warn( + "The 'neg_sampling_ratio' argument is deprecated in PyG" + " and is not supported in cuGraph-PyG." + ) + + neg_sampling = torch_geometric.sampler.NegativeSampling.cast(neg_sampling) + + ( + input_type, + edge_label_index, + ) = torch_geometric.loader.utils.get_edge_label_index( + data, + (None, edge_label_index), + ) + + self.__input_data = torch_geometric.sampler.EdgeSamplerInput( + input_id=torch.arange( + edge_label_index[0].numel(), dtype=torch.int64, device="cuda" + ) + if input_id is None + else input_id, + row=edge_label_index[0], + col=edge_label_index[1], + label=edge_label, + time=edge_label_time, + input_type=input_type, + ) + + # Edge label check from torch_geometric.loader.LinkLoader + if ( + neg_sampling is not None + and neg_sampling.is_binary() + and edge_label is not None + and edge_label.min() == 0 + ): + edge_label = edge_label + 1 + + if ( + neg_sampling is not None + and neg_sampling.is_triplet() + and edge_label is not None + ): + raise ValueError( + "'edge_label' needs to be undefined for " + "'triplet'-based negative sampling. Please use " + "`src_index`, `dst_pos_index` and " + "`neg_pos_index` of the returned mini-batch " + "instead to differentiate between positive and " + "negative samples." + ) + + self.__data = data + + self.__link_sampler = link_sampler + self.__neg_sampling = neg_sampling + + self.__batch_size = batch_size + self.__shuffle = shuffle + self.__drop_last = drop_last + + def __iter__(self): + if self.__shuffle: + perm = torch.randperm(self.__input_data.row.numel()) + else: + perm = torch.arange(self.__input_data.row.numel()) + + if self.__drop_last: + d = perm.numel() % self.__batch_size + perm = perm[:-d] + + input_data = torch_geometric.sampler.EdgeSamplerInput( + input_id=self.__input_data.input_id[perm], + row=self.__input_data.row[perm], + col=self.__input_data.col[perm], + label=None + if self.__input_data.label is None + else self.__input_data.label[perm], + time=None + if self.__input_data.time is None + else self.__input_data.time[perm], + input_type=self.__input_data.input_type, + ) + + return cugraph_pyg.sampler.SampleIterator( + self.__data, + self.__link_sampler.sample_from_edges( + input_data, + neg_sampling=self.__neg_sampling, + ), + ) diff --git a/python/cugraph-pyg/cugraph_pyg/loader/link_neighbor_loader.py b/python/cugraph-pyg/cugraph_pyg/loader/link_neighbor_loader.py new file mode 100644 index 00000000000..080565368c4 --- /dev/null +++ b/python/cugraph-pyg/cugraph_pyg/loader/link_neighbor_loader.py @@ -0,0 +1,243 @@ +# 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 warnings + +from typing import Union, Tuple, Optional, Callable, List, Dict + +import cugraph_pyg +from cugraph_pyg.loader import LinkLoader +from cugraph_pyg.sampler import BaseSampler + +from cugraph.gnn import NeighborSampler, DistSampleWriter +from cugraph.utilities.utils import import_optional + +torch_geometric = import_optional("torch_geometric") + + +class LinkNeighborLoader(LinkLoader): + """ + Duck-typed version of torch_geometric.loader.LinkNeighborLoader + + Link loader that implements the neighbor sampling + algorithm used in GraphSAGE. + """ + + def __init__( + self, + data: Union[ + "torch_geometric.data.Data", + "torch_geometric.data.HeteroData", + Tuple[ + "torch_geometric.data.FeatureStore", "torch_geometric.data.GraphStore" + ], + ], + num_neighbors: Union[ + List[int], Dict["torch_geometric.typing.EdgeType", List[int]] + ], + edge_label_index: "torch_geometric.typing.InputEdges" = None, + edge_label: "torch_geometric.typing.OptTensor" = None, + edge_label_time: "torch_geometric.typing.OptTensor" = None, + replace: bool = False, + subgraph_type: Union[ + "torch_geometric.typing.SubgraphType", str + ] = "directional", + disjoint: bool = False, + temporal_strategy: str = "uniform", + neg_sampling: Optional["torch_geometric.sampler.NegativeSampling"] = None, + neg_sampling_ratio: Optional[Union[int, float]] = None, + time_attr: Optional[str] = None, + weight_attr: Optional[str] = None, + transform: Optional[Callable] = None, + transform_sampler_output: Optional[Callable] = None, + is_sorted: bool = False, + filter_per_worker: Optional[bool] = None, + neighbor_sampler: Optional["torch_geometric.sampler.NeighborSampler"] = None, + directed: bool = True, # Deprecated. + batch_size: int = 16, # Refers to number of edges per batch. + directory: Optional[str] = None, + batches_per_partition=256, + format: str = "parquet", + compression: Optional[str] = None, + local_seeds_per_call: Optional[int] = None, + **kwargs, + ): + """ + data: Data, HeteroData, or Tuple[FeatureStore, GraphStore] + See torch_geometric.loader.LinkNeighborLoader. + num_neighbors: List[int] or Dict[EdgeType, List[int]] + Fanout values. + See torch_geometric.loader.LinkNeighborLoader. + edge_label_index: InputEdges + Input edges for sampling. + See torch_geometric.loader.LinkNeighborLoader. + edge_label: OptTensor + Labels for input edges. + See torch_geometric.loader.LinkNeighborLoader. + edge_label_time: OptTensor + Time attribute for input edges. + See torch_geometric.loader.LinkNeighborLoader. + replace: bool (optional, default=False) + Whether to sample with replacement. + See torch_geometric.loader.LinkNeighborLoader. + subgraph_type: Union[SubgraphType, str] (optional, default='directional') + The type of subgraph to return. + Currently only 'directional' is supported. + See torch_geometric.loader.LinkNeighborLoader. + disjoint: bool (optional, default=False) + Whether to perform disjoint sampling. + Currently unsupported. + See torch_geometric.loader.LinkNeighborLoader. + temporal_strategy: str (optional, default='uniform') + Currently only 'uniform' is suppported. + See torch_geometric.loader.LinkNeighborLoader. + time_attr: str (optional, default=None) + Used for temporal sampling. + See torch_geometric.loader.LinkNeighborLoader. + weight_attr: str (optional, default=None) + Used for biased sampling. + See torch_geometric.loader.LinkNeighborLoader. + transform: Callable (optional, default=None) + See torch_geometric.loader.LinkNeighborLoader. + transform_sampler_output: Callable (optional, default=None) + See torch_geometric.loader.LinkNeighborLoader. + is_sorted: bool (optional, default=False) + Ignored by cuGraph. + See torch_geometric.loader.LinkNeighborLoader. + filter_per_worker: bool (optional, default=False) + Currently ignored by cuGraph, but this may + change once in-memory sampling is implemented. + See torch_geometric.loader.LinkNeighborLoader. + neighbor_sampler: torch_geometric.sampler.NeighborSampler + (optional, default=None) + Not supported by cuGraph. + See torch_geometric.loader.LinkNeighborLoader. + directed: bool (optional, default=True) + Deprecated. + See torch_geometric.loader.LinkNeighborLoader. + batch_size: int (optional, default=16) + The number of input nodes per output minibatch. + See torch.utils.dataloader. + directory: str (optional, default=None) + The directory where samples will be temporarily stored, + if spilling samples to disk. If None, this loader + will perform buffered in-memory sampling. + If writing to disk, setting this argument + to a tempfile.TemporaryDirectory with a context + manager is a good option but depending on the filesystem, + you may want to choose an alternative location with fast I/O + intead. + See cugraph.gnn.DistSampleWriter. + batches_per_partition: int (optional, default=256) + The number of batches per partition if writing samples to + disk. Manually tuning this parameter is not recommended + but reducing it may help conserve GPU memory. + See cugraph.gnn.DistSampleWriter. + format: str (optional, default='parquet') + If writing samples to disk, they will be written in this + file format. + See cugraph.gnn.DistSampleWriter. + compression: str (optional, default=None) + The compression type to use if writing samples to disk. + If not provided, it is automatically chosen. + local_seeds_per_call: int (optional, default=None) + The number of seeds to process within a single sampling call. + Manually tuning this parameter is not recommended but reducing + it may conserve GPU memory. The total number of seeds processed + per sampling call is equal to the sum of this parameter across + all workers. If not provided, it will be automatically + calculated. + See cugraph.gnn.DistSampler. + **kwargs + Other keyword arguments passed to the superclass. + """ + + subgraph_type = torch_geometric.sampler.base.SubgraphType(subgraph_type) + + if not directed: + subgraph_type = torch_geometric.sampler.base.SubgraphType.induced + warnings.warn( + "The 'directed' argument is deprecated. " + "Use subgraph_type='induced' instead." + ) + if subgraph_type != torch_geometric.sampler.base.SubgraphType.directional: + raise ValueError("Only directional subgraphs are currently supported") + if disjoint: + raise ValueError("Disjoint sampling is currently unsupported") + if temporal_strategy != "uniform": + warnings.warn("Only the uniform temporal strategy is currently supported") + if neighbor_sampler is not None: + raise ValueError("Passing a neighbor sampler is currently unsupported") + if time_attr is not None: + raise ValueError("Temporal sampling is currently unsupported") + if is_sorted: + warnings.warn("The 'is_sorted' argument is ignored by cuGraph.") + if not isinstance(data, (list, tuple)) or not isinstance( + data[1], cugraph_pyg.data.GraphStore + ): + # Will eventually automatically convert these objects to cuGraph objects. + raise NotImplementedError("Currently can't accept non-cugraph graphs") + + if compression is None: + compression = "CSR" + elif compression not in ["CSR", "COO"]: + raise ValueError("Invalid value for compression (expected 'CSR' or 'COO')") + + writer = ( + None + if directory is None + else DistSampleWriter( + directory=directory, + batches_per_partition=batches_per_partition, + format=format, + ) + ) + + feature_store, graph_store = data + + if weight_attr is not None: + graph_store._set_weight_attr((feature_store, weight_attr)) + + sampler = BaseSampler( + NeighborSampler( + graph_store._graph, + writer, + retain_original_seeds=True, + fanout=num_neighbors, + prior_sources_behavior="exclude", + deduplicate_sources=True, + compression=compression, + compress_per_hop=False, + with_replacement=replace, + local_seeds_per_call=local_seeds_per_call, + biased=(weight_attr is not None), + ), + (feature_store, graph_store), + batch_size=batch_size, + ) + # TODO add heterogeneous support and pass graph_store._vertex_offsets + + super().__init__( + (feature_store, graph_store), + sampler, + edge_label_index=edge_label_index, + edge_label=edge_label, + edge_label_time=edge_label_time, + neg_sampling=neg_sampling, + neg_sampling_ratio=neg_sampling_ratio, + transform=transform, + transform_sampler_output=transform_sampler_output, + filter_per_worker=filter_per_worker, + batch_size=batch_size, + **kwargs, + ) diff --git a/python/cugraph-pyg/cugraph_pyg/loader/neighbor_loader.py b/python/cugraph-pyg/cugraph_pyg/loader/neighbor_loader.py index 7f12bbb3fe6..1da2c6dc381 100644 --- a/python/cugraph-pyg/cugraph_pyg/loader/neighbor_loader.py +++ b/python/cugraph-pyg/cugraph_pyg/loader/neighbor_loader.py @@ -12,7 +12,6 @@ # limitations under the License. import warnings -import tempfile from typing import Union, Tuple, Optional, Callable, List, Dict @@ -123,14 +122,14 @@ def __init__( The number of input nodes per output minibatch. See torch.utils.dataloader. directory: str (optional, default=None) - The directory where samples will be temporarily stored. - It is recommend that this be set by the user, usually - setting it to a tempfile.TemporaryDirectory with a context + The directory where samples will be temporarily stored, + if spilling samples to disk. If None, this loader + will perform buffered in-memory sampling. + If writing to disk, setting this argument + to a tempfile.TemporaryDirectory with a context manager is a good option but depending on the filesystem, you may want to choose an alternative location with fast I/O intead. - If not set, this will create a TemporaryDirectory that will - persist until this object is garbage collected. See cugraph.gnn.DistSampleWriter. batches_per_partition: int (optional, default=256) The number of batches per partition if writing samples to @@ -182,20 +181,19 @@ def __init__( # Will eventually automatically convert these objects to cuGraph objects. raise NotImplementedError("Currently can't accept non-cugraph graphs") - if directory is None: - warnings.warn("Setting a directory to store samples is recommended.") - self._tempdir = tempfile.TemporaryDirectory() - directory = self._tempdir.name - if compression is None: compression = "CSR" elif compression not in ["CSR", "COO"]: raise ValueError("Invalid value for compression (expected 'CSR' or 'COO')") - writer = DistSampleWriter( - directory=directory, - batches_per_partition=batches_per_partition, - format=format, + writer = ( + None + if directory is None + else DistSampleWriter( + directory=directory, + batches_per_partition=batches_per_partition, + format=format, + ) ) feature_store, graph_store = data diff --git a/python/cugraph-pyg/cugraph_pyg/loader/node_loader.py b/python/cugraph-pyg/cugraph_pyg/loader/node_loader.py index 49923783d6b..4b236f75885 100644 --- a/python/cugraph-pyg/cugraph_pyg/loader/node_loader.py +++ b/python/cugraph-pyg/cugraph_pyg/loader/node_loader.py @@ -110,8 +110,10 @@ def __init__( input_id, ) - self.__input_data = torch_geometric.loader.node_loader.NodeSamplerInput( - input_id=input_id, + self.__input_data = torch_geometric.sampler.NodeSamplerInput( + input_id=torch.arange(len(input_nodes), dtype=torch.int64, device="cuda") + if input_id is None + else input_id, node=input_nodes, time=None, input_type=input_type, @@ -135,10 +137,8 @@ def __iter__(self): d = perm.numel() % self.__batch_size perm = perm[:-d] - input_data = torch_geometric.loader.node_loader.NodeSamplerInput( - input_id=None - if self.__input_data.input_id is None - else self.__input_data.input_id[perm], + input_data = torch_geometric.sampler.NodeSamplerInput( + input_id=self.__input_data.input_id[perm], node=self.__input_data.node[perm], time=None if self.__input_data.time is None diff --git a/python/cugraph-pyg/cugraph_pyg/sampler/sampler.py b/python/cugraph-pyg/cugraph_pyg/sampler/sampler.py index 268e9ffebbd..bc3d4fd8d3c 100644 --- a/python/cugraph-pyg/cugraph_pyg/sampler/sampler.py +++ b/python/cugraph-pyg/cugraph_pyg/sampler/sampler.py @@ -14,9 +14,9 @@ from typing import Optional, Iterator, Union, Dict, Tuple from cugraph.utilities.utils import import_optional -from cugraph.gnn import DistSampler, DistSampleReader +from cugraph.gnn import DistSampler -from .sampler_utils import filter_cugraph_pyg_store +from .sampler_utils import filter_cugraph_pyg_store, neg_sample, neg_cat torch = import_optional("torch") torch_geometric = import_optional("torch_geometric") @@ -60,7 +60,12 @@ def __next__(self): next_sample = next(self.__output_iter) if isinstance(next_sample, torch_geometric.sampler.SamplerOutput): sz = next_sample.edge.numel() - if sz == next_sample.col.numel(): + if sz == next_sample.col.numel() and ( + next_sample.node.numel() > next_sample.col[-1] + ): + # This will only trigger on very small batches and will have minimal + # performance impact. If COO output is removed, then this condition + # can be avoided. col = next_sample.col else: col = torch_geometric.edge_index.ptr2index( @@ -101,10 +106,20 @@ def __next__(self): data.num_sampled_nodes = next_sample.num_sampled_nodes data.num_sampled_edges = next_sample.num_sampled_edges - data.input_id = data.batch - data.seed_time = None + data.input_id = next_sample.metadata[0] data.batch_size = data.input_id.size(0) + if len(next_sample.metadata) == 2: + data.seed_time = next_sample.metadata[1] + elif len(next_sample.metadata) == 4: + ( + data.edge_label_index, + data.edge_label, + data.seed_time, + ) = next_sample.metadata[1:] + else: + raise ValueError("Invalid metadata") + elif isinstance(next_sample, torch_geometric.sampler.HeteroSamplerOutput): col = {} for edge_type, col_idx in next_sample.col: @@ -152,13 +167,15 @@ class SampleReader: Iterator that processes results from the cuGraph distributed sampler. """ - def __init__(self, base_reader: DistSampleReader): + def __init__( + self, base_reader: Iterator[Tuple[Dict[str, "torch.Tensor"], int, int]] + ): """ Constructs a new SampleReader. Parameters ---------- - base_reader: DistSampleReader + base_reader: Iterator[Tuple[Dict[str, "torch.Tensor"], int, int]] The reader responsible for loading saved samples produced by the cuGraph distributed sampler. """ @@ -173,6 +190,9 @@ def __next__(self): self.__base_reader ) + self.__raw_sample_data["input_offsets"] -= self.__raw_sample_data[ + "input_offsets" + ][0].clone() self.__raw_sample_data["label_hop_offsets"] -= self.__raw_sample_data[ "label_hop_offsets" ][0].clone() @@ -202,14 +222,16 @@ class HomogeneousSampleReader(SampleReader): produced by the cuGraph distributed sampler. """ - def __init__(self, base_reader: DistSampleReader): + def __init__( + self, base_reader: Iterator[Tuple[Dict[str, "torch.Tensor"], int, int]] + ): """ Constructs a new HomogeneousSampleReader Parameters ---------- - base_reader: DistSampleReader - The reader responsible for loading saved samples produced by + base_reader: Iterator[Tuple[Dict[str, "torch.Tensor"], int, int]] + The iterator responsible for loading saved samples produced by the cuGraph distributed sampler. """ super().__init__(base_reader) @@ -262,6 +284,52 @@ def __decode_csc(self, raw_sample_data: Dict[str, "torch.Tensor"], index: int): [num_seeds, num_sampled_nodes_hops.diff(prepend=num_seeds)] ) + input_index = raw_sample_data["input_index"][ + raw_sample_data["input_offsets"][index] : raw_sample_data["input_offsets"][ + index + 1 + ] + ] + + num_seeds = input_index.numel() + input_index = input_index[input_index >= 0] + + num_pos = input_index.numel() + num_neg = num_seeds - num_pos + if num_neg > 0: + edge_label = torch.concat( + [ + torch.full((num_pos,), 1.0), + torch.full((num_neg,), 0.0), + ] + ) + else: + edge_label = None + + edge_inverse = ( + ( + raw_sample_data["edge_inverse"][ + (raw_sample_data["input_offsets"][index] * 2) : ( + raw_sample_data["input_offsets"][index + 1] * 2 + ) + ] + ) + if "edge_inverse" in raw_sample_data + else None + ) + + if edge_inverse is None: + metadata = ( + input_index, + None, # TODO this will eventually include time + ) + else: + metadata = ( + input_index, + edge_inverse.view(2, -1), + edge_label, + None, # TODO this will eventually include time + ) + return torch_geometric.sampler.SamplerOutput( node=renumber_map.cpu(), row=minors, @@ -270,6 +338,7 @@ def __decode_csc(self, raw_sample_data: Dict[str, "torch.Tensor"], index: int): batch=renumber_map[:num_seeds], num_sampled_nodes=num_sampled_nodes.cpu(), num_sampled_edges=num_sampled_edges.cpu(), + metadata=metadata, ) def __decode_coo(self, raw_sample_data: Dict[str, "torch.Tensor"], index: int): @@ -315,6 +384,37 @@ def __decode_coo(self, raw_sample_data: Dict[str, "torch.Tensor"], index: int): [num_seeds, num_sampled_nodes_hops.diff(prepend=num_seeds)] ) + input_index = raw_sample_data["input_index"][ + raw_sample_data["input_offsets"][index] : raw_sample_data["input_offsets"][ + index + 1 + ] + ] + + edge_inverse = ( + ( + raw_sample_data["edge_inverse"][ + (raw_sample_data["input_offsets"][index] * 2) : ( + raw_sample_data["input_offsets"][index + 1] * 2 + ) + ] + ) + if "edge_inverse" in raw_sample_data + else None + ) + + if edge_inverse is None: + metadata = ( + input_index, + None, # TODO this will eventually include time + ) + else: + metadata = ( + input_index, + edge_inverse.view(2, -1), + None, + None, # TODO this will eventually include time + ) + return torch_geometric.sampler.SamplerOutput( node=renumber_map.cpu(), row=minors, @@ -323,6 +423,7 @@ def __decode_coo(self, raw_sample_data: Dict[str, "torch.Tensor"], index: int): batch=renumber_map[:num_seeds], num_sampled_nodes=num_sampled_nodes, num_sampled_edges=num_sampled_edges, + metadata=metadata, ) def _decode(self, raw_sample_data: Dict[str, "torch.Tensor"], index: int): @@ -353,8 +454,8 @@ def sample_from_nodes( "torch_geometric.sampler.SamplerOutput", ] ]: - self.__sampler.sample_from_nodes( - index.node, batch_size=self.__batch_size, **kwargs + reader = self.__sampler.sample_from_nodes( + index.node, batch_size=self.__batch_size, input_id=index.input_id, **kwargs ) edge_attrs = self.__graph_store.get_all_edge_attrs() @@ -362,7 +463,7 @@ def sample_from_nodes( len(edge_attrs) == 1 and edge_attrs[0].edge_type[0] == edge_attrs[0].edge_type[2] ): - return HomogeneousSampleReader(self.__sampler.get_reader()) + return HomogeneousSampleReader(reader) else: # TODO implement heterogeneous sampling raise NotImplementedError( @@ -381,4 +482,59 @@ def sample_from_edges( "torch_geometric.sampler.SamplerOutput", ] ]: - raise NotImplementedError("Edge sampling is currently unimplemented.") + src = index.row + dst = index.col + input_id = index.input_id + neg_batch_size = 0 + if neg_sampling: + # Sample every negative subset at once. + # TODO handle temporal sampling (node_time) + src_neg, dst_neg = neg_sample( + self.__graph_store, + index.row, + index.col, + self.__batch_size, + neg_sampling, + None, # src_time, + None, # src_node_time, + ) + if neg_sampling.is_binary(): + src, _ = neg_cat(src.cuda(), src_neg, self.__batch_size) + else: + # triplet, cat dst to src so length is the same; will + # result in the same set of unique vertices + src, _ = neg_cat(src.cuda(), dst_neg, self.__batch_size) + dst, neg_batch_size = neg_cat(dst.cuda(), dst_neg, self.__batch_size) + + # Concatenate -1s so the input id tensor lines up and can + # be processed by the dist sampler. + # When loading the output batch, '-1' will be dropped. + input_id, _ = neg_cat( + input_id, + torch.full( + (dst_neg.numel(),), -1, dtype=torch.int64, device=input_id.device + ), + self.__batch_size, + ) + + # TODO for temporal sampling, node times have to be + # adjusted here. + reader = self.__sampler.sample_from_edges( + torch.stack([src, dst]), # reverse of usual convention + input_id=input_id, + batch_size=self.__batch_size + neg_batch_size, + **kwargs, + ) + + edge_attrs = self.__graph_store.get_all_edge_attrs() + if ( + len(edge_attrs) == 1 + and edge_attrs[0].edge_type[0] == edge_attrs[0].edge_type[2] + ): + return HomogeneousSampleReader(reader) + else: + # TODO implement heterogeneous sampling + raise NotImplementedError( + "Sampling heterogeneous graphs is currently" + " unsupported in the non-dask API" + ) diff --git a/python/cugraph-pyg/cugraph_pyg/sampler/sampler_utils.py b/python/cugraph-pyg/cugraph_pyg/sampler/sampler_utils.py index dba7c146b01..b3d56ef9992 100644 --- a/python/cugraph-pyg/cugraph_pyg/sampler/sampler_utils.py +++ b/python/cugraph-pyg/cugraph_pyg/sampler/sampler_utils.py @@ -14,10 +14,14 @@ from typing import Sequence, Dict, Tuple -from cugraph_pyg.data import DaskGraphStore +from math import ceil + +from cugraph_pyg.data import GraphStore, DaskGraphStore from cugraph.utilities.utils import import_optional import cudf +import cupy +import pylibcugraph dask_cudf = import_optional("dask_cudf") torch_geometric = import_optional("torch_geometric") @@ -429,3 +433,99 @@ def filter_cugraph_pyg_store( data[attr.attr_name] = tensors[i] return data + + +def neg_sample( + graph_store: GraphStore, + seed_src: "torch.Tensor", + seed_dst: "torch.Tensor", + batch_size: int, + neg_sampling: "torch_geometric.sampler.NegativeSampling", + time: "torch.Tensor", + node_time: "torch.Tensor", +) -> Tuple["torch.Tensor", "torch.Tensor"]: + try: + # Compatibility for PyG 2.5 + src_weight = neg_sampling.src_weight + dst_weight = neg_sampling.dst_weight + except AttributeError: + src_weight = neg_sampling.weight + dst_weight = neg_sampling.weight + unweighted = src_weight is None and dst_weight is None + + # Require at least one negative edge per batch + num_neg = max( + int(ceil(neg_sampling.amount * seed_src.numel())), + int(ceil(seed_src.numel() / batch_size)), + ) + + if graph_store.is_multi_gpu: + num_neg_global = torch.tensor([num_neg], device="cuda") + torch.distributed.all_reduce(num_neg_global, op=torch.distributed.ReduceOp.SUM) + num_neg = int(num_neg_global) + else: + num_neg_global = num_neg + + if node_time is None: + result_dict = pylibcugraph.negative_sampling( + graph_store._resource_handle, + graph_store._graph, + num_neg_global, + vertices=None + if unweighted + else cupy.arange(src_weight.numel(), dtype="int64"), + src_bias=None if src_weight is None else cupy.asarray(src_weight), + dst_bias=None if dst_weight is None else cupy.asarray(dst_weight), + remove_duplicates=False, + remove_false_negatives=False, + exact_number_of_samples=True, + do_expensive_check=False, + ) + + src_neg = torch.as_tensor(result_dict["sources"], device="cuda")[:num_neg] + dst_neg = torch.as_tensor(result_dict["destinations"], device="cuda")[:num_neg] + + # TODO modifiy the C API so this condition is impossible + if src_neg.numel() < num_neg: + num_gen = num_neg - src_neg.numel() + src_neg = torch.concat( + [ + src_neg, + torch.randint( + 0, src_neg.max(), (num_gen,), device="cuda", dtype=torch.int64 + ), + ] + ) + dst_neg = torch.concat( + [ + dst_neg, + torch.randint( + 0, dst_neg.max(), (num_gen,), device="cuda", dtype=torch.int64 + ), + ] + ) + return src_neg, dst_neg + raise NotImplementedError( + "Temporal negative sampling is currently unimplemented in cuGraph-PyG" + ) + + +def neg_cat( + seed_pos: "torch.Tensor", seed_neg: "torch.Tensor", pos_batch_size: int +) -> Tuple["torch.Tensor", int]: + num_seeds = seed_pos.numel() + num_batches = int(ceil(num_seeds / pos_batch_size)) + neg_batch_size = int(ceil(seed_neg.numel() / num_batches)) + + batch_pos_offsets = torch.full((num_batches,), pos_batch_size).cumsum(-1)[:-1] + seed_pos_splits = torch.tensor_split(seed_pos, batch_pos_offsets) + + batch_neg_offsets = torch.full((num_batches,), neg_batch_size).cumsum(-1)[:-1] + seed_neg_splits = torch.tensor_split(seed_neg, batch_neg_offsets) + + return ( + torch.concatenate( + [torch.concatenate(s) for s in zip(seed_pos_splits, seed_neg_splits)] + ), + neg_batch_size, + ) diff --git a/python/cugraph-pyg/cugraph_pyg/tests/loader/test_neighbor_loader.py b/python/cugraph-pyg/cugraph_pyg/tests/loader/test_neighbor_loader.py index c4ad941de7a..8ee18a826f7 100644 --- a/python/cugraph-pyg/cugraph_pyg/tests/loader/test_neighbor_loader.py +++ b/python/cugraph-pyg/cugraph_pyg/tests/loader/test_neighbor_loader.py @@ -16,6 +16,7 @@ from cugraph.datasets import karate from cugraph.utilities.utils import import_optional, MissingModule +import cugraph_pyg from cugraph_pyg.data import TensorDictFeatureStore, GraphStore from cugraph_pyg.loader import NeighborLoader @@ -86,3 +87,110 @@ def test_neighbor_loader_biased(): assert out.edge_index.shape[1] == 2 assert (out.edge_index.cpu() == torch.tensor([[3, 4], [1, 2]])).all() + + +@pytest.mark.skipif(isinstance(torch, MissingModule), reason="torch not available") +@pytest.mark.sg +@pytest.mark.parametrize("num_nodes", [10, 25]) +@pytest.mark.parametrize("num_edges", [64, 128]) +@pytest.mark.parametrize("batch_size", [2, 4]) +@pytest.mark.parametrize("select_edges", [16, 32]) +@pytest.mark.parametrize("depth", [1, 3]) +@pytest.mark.parametrize("num_neighbors", [1, 4]) +def test_link_neighbor_loader_basic( + num_nodes, num_edges, batch_size, select_edges, num_neighbors, depth +): + graph_store = GraphStore() + feature_store = TensorDictFeatureStore() + + eix = torch.randperm(num_edges)[:select_edges] + graph_store[("n", "e", "n"), "coo"] = torch.stack( + [ + torch.randint(0, num_nodes, (num_edges,)), + torch.randint(0, num_nodes, (num_edges,)), + ] + ) + + elx = graph_store[("n", "e", "n"), "coo"][:, eix] + loader = cugraph_pyg.loader.LinkNeighborLoader( + (feature_store, graph_store), + num_neighbors=[num_neighbors] * depth, + edge_label_index=elx, + batch_size=batch_size, + shuffle=False, + ) + + elx = torch.tensor_split(elx, eix.numel() // batch_size, dim=1) + for i, batch in enumerate(loader): + assert ( + batch.input_id.cpu() == torch.arange(i * batch_size, (i + 1) * batch_size) + ).all() + assert (elx[i] == batch.n_id[batch.edge_label_index.cpu()]).all() + + +@pytest.mark.skipif(isinstance(torch, MissingModule), reason="torch not available") +@pytest.mark.sg +@pytest.mark.parametrize("batch_size", [1, 2]) +def test_link_neighbor_loader_negative_sampling_basic(batch_size): + num_edges = 62 + num_nodes = 19 + select_edges = 17 + + graph_store = GraphStore() + feature_store = TensorDictFeatureStore() + + eix = torch.randperm(num_edges)[:select_edges] + graph_store[("n", "e", "n"), "coo"] = torch.stack( + [ + torch.randint(0, num_nodes, (num_edges,)), + torch.randint(0, num_nodes, (num_edges,)), + ] + ) + + elx = graph_store[("n", "e", "n"), "coo"][:, eix] + loader = cugraph_pyg.loader.LinkNeighborLoader( + (feature_store, graph_store), + num_neighbors=[3, 3, 3], + edge_label_index=elx, + batch_size=batch_size, + neg_sampling="binary", + shuffle=False, + ) + + elx = torch.tensor_split(elx, eix.numel() // batch_size, dim=1) + for i, batch in enumerate(loader): + assert batch.edge_label[0] == 1.0 + + +@pytest.mark.skipif(isinstance(torch, MissingModule), reason="torch not available") +@pytest.mark.sg +@pytest.mark.parametrize("batch_size", [1, 2]) +def test_link_neighbor_loader_negative_sampling_uneven(batch_size): + num_edges = 62 + num_nodes = 19 + select_edges = 17 + + graph_store = GraphStore() + feature_store = TensorDictFeatureStore() + + eix = torch.randperm(num_edges)[:select_edges] + graph_store[("n", "e", "n"), "coo"] = torch.stack( + [ + torch.randint(0, num_nodes, (num_edges,)), + torch.randint(0, num_nodes, (num_edges,)), + ] + ) + + elx = graph_store[("n", "e", "n"), "coo"][:, eix] + loader = cugraph_pyg.loader.LinkNeighborLoader( + (feature_store, graph_store), + num_neighbors=[3, 3, 3], + edge_label_index=elx, + batch_size=batch_size, + neg_sampling=torch_geometric.sampler.NegativeSampling("binary", amount=0.1), + shuffle=False, + ) + + elx = torch.tensor_split(elx, eix.numel() // batch_size, dim=1) + for i, batch in enumerate(loader): + assert batch.edge_label[0] == 1.0 diff --git a/python/cugraph-pyg/cugraph_pyg/tests/loader/test_neighbor_loader_mg.py b/python/cugraph-pyg/cugraph_pyg/tests/loader/test_neighbor_loader_mg.py index b8089bb901d..d1dee01a508 100644 --- a/python/cugraph-pyg/cugraph_pyg/tests/loader/test_neighbor_loader_mg.py +++ b/python/cugraph-pyg/cugraph_pyg/tests/loader/test_neighbor_loader_mg.py @@ -19,7 +19,7 @@ from cugraph.utilities.utils import import_optional, MissingModule from cugraph_pyg.data import TensorDictFeatureStore, GraphStore -from cugraph_pyg.loader import NeighborLoader +from cugraph_pyg.loader import NeighborLoader, LinkNeighborLoader from cugraph.gnn import ( cugraph_comms_init, @@ -96,6 +96,7 @@ def run_test_neighbor_loader_mg(rank, uid, world_size, specify_size): cugraph_comms_shutdown() +@pytest.mark.skip(reason="deleteme") @pytest.mark.parametrize("specify_size", [True, False]) @pytest.mark.skipif(isinstance(torch, MissingModule), reason="torch not available") @pytest.mark.mg @@ -165,6 +166,7 @@ def run_test_neighbor_loader_biased_mg(rank, uid, world_size): cugraph_comms_shutdown() +@pytest.mark.skip(reason="deleteme") @pytest.mark.skipif(isinstance(torch, MissingModule), reason="torch not available") @pytest.mark.mg def test_neighbor_loader_biased_mg(): @@ -179,3 +181,184 @@ def test_neighbor_loader_biased_mg(): ), nprocs=world_size, ) + + +def run_test_link_neighbor_loader_basic_mg( + rank, + uid, + world_size, + num_nodes: int, + num_edges: int, + select_edges: int, + batch_size: int, + num_neighbors: int, + depth: int, +): + init_pytorch_worker(rank, world_size, uid) + + graph_store = GraphStore(is_multi_gpu=True) + feature_store = TensorDictFeatureStore() + + eix = torch.randperm(num_edges)[:select_edges] + graph_store[("n", "e", "n"), "coo"] = torch.stack( + [ + torch.randint(0, num_nodes, (num_edges,)), + torch.randint(0, num_nodes, (num_edges,)), + ] + ) + + elx = graph_store[("n", "e", "n"), "coo"][:, eix] + loader = LinkNeighborLoader( + (feature_store, graph_store), + num_neighbors=[num_neighbors] * depth, + edge_label_index=elx, + batch_size=batch_size, + shuffle=False, + ) + + elx = torch.tensor_split(elx, eix.numel() // batch_size, dim=1) + for i, batch in enumerate(loader): + assert ( + batch.input_id.cpu() == torch.arange(i * batch_size, (i + 1) * batch_size) + ).all() + assert (elx[i] == batch.n_id[batch.edge_label_index.cpu()]).all() + + cugraph_comms_shutdown() + + +@pytest.mark.skip(reason="deleteme") +@pytest.mark.skipif(isinstance(torch, MissingModule), reason="torch not available") +@pytest.mark.mg +@pytest.mark.parametrize("select_edges", [64, 128]) +@pytest.mark.parametrize("batch_size", [2, 4]) +@pytest.mark.parametrize("depth", [1, 3]) +def test_link_neighbor_loader_basic_mg(select_edges, batch_size, depth): + num_nodes = 25 + num_edges = 128 + num_neighbors = 2 + + uid = cugraph_comms_create_unique_id() + world_size = torch.cuda.device_count() + + torch.multiprocessing.spawn( + run_test_link_neighbor_loader_basic_mg, + args=( + uid, + world_size, + num_nodes, + num_edges, + select_edges, + batch_size, + num_neighbors, + depth, + ), + nprocs=world_size, + ) + + +def run_test_link_neighbor_loader_uneven_mg(rank, uid, world_size, edge_index): + init_pytorch_worker(rank, world_size, uid) + + graph_store = GraphStore(is_multi_gpu=True) + feature_store = TensorDictFeatureStore() + + batch_size = 1 + graph_store[("n", "e", "n"), "coo"] = torch.tensor_split( + edge_index, world_size, dim=-1 + )[rank] + + elx = graph_store[("n", "e", "n"), "coo"] # select all edges on each worker + loader = LinkNeighborLoader( + (feature_store, graph_store), + num_neighbors=[2, 2, 2], + edge_label_index=elx, + batch_size=batch_size, + shuffle=False, + ) + + for i, batch in enumerate(loader): + assert ( + batch.input_id.cpu() == torch.arange(i * batch_size, (i + 1) * batch_size) + ).all() + + assert (elx[:, [i]] == batch.n_id[batch.edge_label_index.cpu()]).all() + + cugraph_comms_shutdown() + + +@pytest.mark.skip(reason="deleteme") +@pytest.mark.skipif(isinstance(torch, MissingModule), reason="torch not available") +@pytest.mark.mg +def test_link_neighbor_loader_uneven_mg(): + edge_index = torch.tensor( + [ + [0, 1, 3, 4, 7], + [1, 0, 8, 9, 12], + ] + ) + + uid = cugraph_comms_create_unique_id() + world_size = torch.cuda.device_count() + + torch.multiprocessing.spawn( + run_test_link_neighbor_loader_uneven_mg, + args=( + uid, + world_size, + edge_index, + ), + nprocs=world_size, + ) + + +def run_test_link_neighbor_loader_negative_sampling_basic_mg( + rank, world_size, uid, batch_size +): + num_edges = 62 * world_size + num_nodes = 19 * world_size + select_edges = 17 + + init_pytorch_worker(rank, world_size, uid) + + graph_store = GraphStore(is_multi_gpu=True) + feature_store = TensorDictFeatureStore() + + eix = torch.randperm(num_edges)[:select_edges] + graph_store[("n", "e", "n"), "coo"] = torch.stack( + [ + torch.randint(0, num_nodes, (num_edges,)), + torch.randint(0, num_nodes, (num_edges,)), + ] + ) + + elx = graph_store[("n", "e", "n"), "coo"][:, eix] + loader = LinkNeighborLoader( + (feature_store, graph_store), + num_neighbors=[3, 3, 3], + edge_label_index=elx, + batch_size=batch_size, + neg_sampling="binary", + shuffle=False, + ) + + elx = torch.tensor_split(elx, eix.numel() // batch_size, dim=1) + for i, batch in enumerate(loader): + assert batch.edge_label[0] == 1.0 + + +@pytest.mark.skipif(isinstance(torch, MissingModule), reason="torch not available") +@pytest.mark.mg +@pytest.mark.parametrize("batch_size", [1, 2]) +def test_link_neighbor_loader_negative_sampling_basic_mg(batch_size): + uid = cugraph_comms_create_unique_id() + world_size = torch.cuda.device_count() + + torch.multiprocessing.spawn( + run_test_link_neighbor_loader_negative_sampling_basic_mg, + args=( + world_size, + uid, + batch_size, + ), + nprocs=world_size, + ) diff --git a/python/cugraph-pyg/cugraph_pyg/tests/pytest.ini b/python/cugraph-pyg/cugraph_pyg/tests/pytest.ini new file mode 100644 index 00000000000..7b0a9f29fb1 --- /dev/null +++ b/python/cugraph-pyg/cugraph_pyg/tests/pytest.ini @@ -0,0 +1,4 @@ +# Copyright (c) 2024, NVIDIA CORPORATION. + +[pytest] +addopts = --tb=native diff --git a/python/cugraph-pyg/pyproject.toml b/python/cugraph-pyg/pyproject.toml index d206d6001cc..e157f36f8f6 100644 --- a/python/cugraph-pyg/pyproject.toml +++ b/python/cugraph-pyg/pyproject.toml @@ -29,10 +29,10 @@ classifiers = [ "Programming Language :: Python :: 3.12", ] dependencies = [ - "cugraph==24.10.*,>=0.0.0a0", + "cugraph==24.12.*,>=0.0.0a0", "numba>=0.57", - "numpy>=1.23,<2.0a0", - "pylibcugraphops==24.10.*,>=0.0.0a0", + "numpy>=1.23,<3.0a0", + "pylibcugraphops==24.12.*,>=0.0.0a0", ] # This list was generated by `rapids-dependency-file-generator`. To make changes, edit ../../dependencies.yaml and run `rapids-dependency-file-generator`. [project.urls] @@ -42,14 +42,14 @@ Documentation = "https://docs.rapids.ai/api/cugraph/stable/" [project.optional-dependencies] test = [ "pandas", - "pylibwholegraph==24.10.*,>=0.0.0a0", + "pylibwholegraph==24.12.*,>=0.0.0a0", "pytest", "pytest-benchmark", "pytest-cov", "pytest-xdist", "scipy", "tensordict>=0.1.2", - "torch>=2.0,<2.2.0a0", + "torch>=2.3,<2.4.0a0", ] # This list was generated by `rapids-dependency-file-generator`. To make changes, edit ../../dependencies.yaml and run `rapids-dependency-file-generator`. [tool.setuptools] diff --git a/python/cugraph-pyg/pytest.ini b/python/cugraph-pyg/pytest.ini index db99a54ae49..07c4ffa0958 100644 --- a/python/cugraph-pyg/pytest.ini +++ b/python/cugraph-pyg/pytest.ini @@ -17,6 +17,7 @@ addopts = --benchmark-max-time=0 --benchmark-min-rounds=1 --benchmark-columns="mean, rounds" + --tb=native ## do not run slow tests/benchmarks by default -m "not slow" diff --git a/python/cugraph-service/pytest.ini b/python/cugraph-service/pytest.ini index 6a0dd36ecec..f2ba9175f82 100644 --- a/python/cugraph-service/pytest.ini +++ b/python/cugraph-service/pytest.ini @@ -16,6 +16,7 @@ addopts = --benchmark-warmup=off --benchmark-max-time=0 --benchmark-min-rounds=1 --benchmark-columns="min, max, mean, rounds" + --tb=native ## for use with rapids-pytest-benchmark plugin #--benchmark-gpu-disable ## for use with pytest-cov plugin diff --git a/python/cugraph-service/server/pyproject.toml b/python/cugraph-service/server/pyproject.toml index b9789c201d2..f388fd4c126 100644 --- a/python/cugraph-service/server/pyproject.toml +++ b/python/cugraph-service/server/pyproject.toml @@ -20,18 +20,18 @@ authors = [ license = { text = "Apache 2.0" } requires-python = ">=3.10" dependencies = [ - "cudf==24.10.*,>=0.0.0a0", - "cugraph-service-client==24.10.*,>=0.0.0a0", - "cugraph==24.10.*,>=0.0.0a0", + "cudf==24.12.*,>=0.0.0a0", + "cugraph-service-client==24.12.*,>=0.0.0a0", + "cugraph==24.12.*,>=0.0.0a0", "cupy-cuda11x>=12.0.0", - "dask-cuda==24.10.*,>=0.0.0a0", - "dask-cudf==24.10.*,>=0.0.0a0", + "dask-cuda==24.12.*,>=0.0.0a0", + "dask-cudf==24.12.*,>=0.0.0a0", "numba>=0.57", - "numpy>=1.23,<2.0a0", - "rapids-dask-dependency==24.10.*,>=0.0.0a0", - "rmm==24.10.*,>=0.0.0a0", + "numpy>=1.23,<3.0a0", + "rapids-dask-dependency==24.12.*,>=0.0.0a0", + "rmm==24.12.*,>=0.0.0a0", "thriftpy2!=0.5.0,!=0.5.1", - "ucx-py==0.40.*,>=0.0.0a0", + "ucx-py==0.41.*,>=0.0.0a0", ] # This list was generated by `rapids-dependency-file-generator`. To make changes, edit ../../../dependencies.yaml and run `rapids-dependency-file-generator`. classifiers = [ "Intended Audience :: Developers", @@ -47,7 +47,7 @@ cugraph-service-server = "cugraph_service_server.__main__:main" [project.optional-dependencies] test = [ "networkx>=2.5.1", - "numpy>=1.23,<2.0a0", + "numpy>=1.23,<3.0a0", "pandas", "pytest", "pytest-benchmark", diff --git a/python/cugraph-service/tests/pytest.ini b/python/cugraph-service/tests/pytest.ini new file mode 100644 index 00000000000..7b0a9f29fb1 --- /dev/null +++ b/python/cugraph-service/tests/pytest.ini @@ -0,0 +1,4 @@ +# Copyright (c) 2024, NVIDIA CORPORATION. + +[pytest] +addopts = --tb=native diff --git a/python/cugraph-service/tests/test_e2e.py b/python/cugraph-service/tests/test_e2e.py index c9b3d24f20e..3079a2423c7 100644 --- a/python/cugraph-service/tests/test_e2e.py +++ b/python/cugraph-service/tests/test_e2e.py @@ -1,4 +1,4 @@ -# 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. @@ -307,8 +307,8 @@ def test_load_call_unload_extension(client, extension1): assert len(results) == 2 assert len(results[0]) == 33 assert len(results[1]) == 21 - assert type(results[0][0]) == int - assert type(results[1][0]) == float + assert type(results[0][0]) is int + assert type(results[1][0]) is float assert results[0][0] == 9 assert results[1][0] == 9.0 diff --git a/python/cugraph-service/tests/test_mg_e2e.py b/python/cugraph-service/tests/test_mg_e2e.py index 39c1195151d..5526593aee0 100644 --- a/python/cugraph-service/tests/test_mg_e2e.py +++ b/python/cugraph-service/tests/test_mg_e2e.py @@ -1,4 +1,4 @@ -# 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. @@ -413,8 +413,8 @@ def test_call_extension_result_on_device( assert len(results) == 2 assert len(results[0]) == array1_len assert len(results[1]) == array2_len - assert type(results[0][0]) == int - assert type(results[1][0]) == float + assert type(results[0][0]) is int + assert type(results[1][0]) is float assert results[0][0] == 9 assert results[1][0] == 9.0 else: diff --git a/python/cugraph/cugraph/gnn/data_loading/__init__.py b/python/cugraph/cugraph/gnn/data_loading/__init__.py index 9e2c81ec749..25f58be88aa 100644 --- a/python/cugraph/cugraph/gnn/data_loading/__init__.py +++ b/python/cugraph/cugraph/gnn/data_loading/__init__.py @@ -14,9 +14,12 @@ from cugraph.gnn.data_loading.bulk_sampler import BulkSampler from cugraph.gnn.data_loading.dist_sampler import ( DistSampler, + NeighborSampler, +) +from cugraph.gnn.data_loading.dist_io import ( DistSampleWriter, DistSampleReader, - NeighborSampler, + BufferedSampleReader, ) diff --git a/python/cugraph/cugraph/gnn/data_loading/bulk_sampler_io.py b/python/cugraph/cugraph/gnn/data_loading/bulk_sampler_io.py index 6abbd82647b..222fb49a836 100644 --- a/python/cugraph/cugraph/gnn/data_loading/bulk_sampler_io.py +++ b/python/cugraph/cugraph/gnn/data_loading/bulk_sampler_io.py @@ -33,10 +33,12 @@ def create_df_from_disjoint_series(series_list: List[cudf.Series]): def create_df_from_disjoint_arrays(array_dict: Dict[str, cupy.array]): + series_dict = {} for k in list(array_dict.keys()): - array_dict[k] = cudf.Series(array_dict[k], name=k) + if array_dict[k] is not None: + series_dict[k] = cudf.Series(array_dict[k], name=k) - return create_df_from_disjoint_series(list(array_dict.values())) + return create_df_from_disjoint_series(list(series_dict.values())) def _write_samples_to_parquet_csr( diff --git a/python/cugraph/cugraph/gnn/data_loading/dist_io/__init__.py b/python/cugraph/cugraph/gnn/data_loading/dist_io/__init__.py new file mode 100644 index 00000000000..29bb5489be2 --- /dev/null +++ b/python/cugraph/cugraph/gnn/data_loading/dist_io/__init__.py @@ -0,0 +1,16 @@ +# 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. + + +from .reader import BufferedSampleReader, DistSampleReader +from .writer import DistSampleWriter diff --git a/python/cugraph/cugraph/gnn/data_loading/dist_io/reader.py b/python/cugraph/cugraph/gnn/data_loading/dist_io/reader.py new file mode 100644 index 00000000000..69f909e7a8d --- /dev/null +++ b/python/cugraph/cugraph/gnn/data_loading/dist_io/reader.py @@ -0,0 +1,144 @@ +# 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 os +import re + +import cudf + +from typing import Callable, Iterator, Tuple, Dict, Optional + +from cugraph.utilities.utils import import_optional, MissingModule + +# Prevent PyTorch from being imported and causing an OOM error +torch = MissingModule("torch") + + +class DistSampleReader: + def __init__( + self, + directory: str, + *, + format: str = "parquet", + rank: Optional[int] = None, + filelist=None, + ): + torch = import_optional("torch") + + self.__format = format + self.__directory = directory + + if format != "parquet": + raise ValueError("Invalid format (currently supported: 'parquet')") + + if filelist is None: + files = os.listdir(directory) + ex = re.compile(r"batch\=([0-9]+)\.([0-9]+)\-([0-9]+)\.([0-9]+)\.parquet") + filematch = [ex.match(f) for f in files] + filematch = [f for f in filematch if f] + + if rank is not None: + filematch = [f for f in filematch if int(f[1]) == rank] + + batch_count = sum([int(f[4]) - int(f[2]) + 1 for f in filematch]) + filematch = sorted(filematch, key=lambda f: int(f[2]), reverse=True) + + self.__files = filematch + else: + self.__files = list(filelist) + + if rank is None: + self.__batch_count = batch_count + else: + # TODO maybe remove this in favor of warning users that they are + # probably going to cause a hang, instead of attempting to resolve + # the hang for them by dropping batches. + batch_count = torch.tensor([batch_count], device="cuda") + torch.distributed.all_reduce(batch_count, torch.distributed.ReduceOp.MIN) + self.__batch_count = int(batch_count) + + def __iter__(self): + return self + + def __next__(self) -> Tuple[Dict[str, "torch.Tensor"], int, int]: + torch = import_optional("torch") + + if len(self.__files) > 0: + f = self.__files.pop() + fname = f[0] + start_inclusive = int(f[2]) + end_inclusive = int(f[4]) + + if (end_inclusive - start_inclusive + 1) > self.__batch_count: + end_inclusive = start_inclusive + self.__batch_count - 1 + self.__batch_count = 0 + else: + self.__batch_count -= end_inclusive - start_inclusive + 1 + + df = cudf.read_parquet(os.path.join(self.__directory, fname)) + tensors = {} + for col in list(df.columns): + s = df[col].dropna() + if len(s) > 0: + tensors[col] = torch.as_tensor(s, device="cuda") + df.drop(col, axis=1, inplace=True) + + return tensors, start_inclusive, end_inclusive + + raise StopIteration + + +class BufferedSampleReader: + def __init__( + self, + nodes_call_groups: list["torch.Tensor"], + sample_fn: Callable[..., Iterator[Tuple[Dict[str, "torch.Tensor"], int, int]]], + *args, + **kwargs, + ): + self.__sample_args = args + self.__sample_kwargs = kwargs + + self.__nodes_call_groups = iter(nodes_call_groups) + self.__sample_fn = sample_fn + self.__current_call_id = 0 + self.__current_reader = None + + def __next__(self) -> Tuple[Dict[str, "torch.Tensor"], int, int]: + new_reader = False + + if self.__current_reader is None: + new_reader = True + else: + try: + out = next(self.__current_reader) + except StopIteration: + new_reader = True + + if new_reader: + # Will trigger StopIteration if there are no more call groups + self.__current_reader = self.__sample_fn( + self.__current_call_id, + next(self.__nodes_call_groups), + *self.__sample_args, + **self.__sample_kwargs, + ) + + self.__current_call_id += 1 + out = next(self.__current_reader) + + return out + + def __iter__(self) -> Iterator[Tuple[Dict[str, "torch.Tensor"], int, int]]: + return self diff --git a/python/cugraph/cugraph/gnn/data_loading/dist_io/writer.py b/python/cugraph/cugraph/gnn/data_loading/dist_io/writer.py new file mode 100644 index 00000000000..f8ad4719a76 --- /dev/null +++ b/python/cugraph/cugraph/gnn/data_loading/dist_io/writer.py @@ -0,0 +1,321 @@ +# 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 os + +from math import ceil + + +import cupy + +from cugraph.utilities.utils import MissingModule +from cugraph.gnn.data_loading.dist_io import DistSampleReader + +from cugraph.gnn.data_loading.bulk_sampler_io import create_df_from_disjoint_arrays + +from typing import Iterator, Tuple, Dict + +torch = MissingModule("torch") + + +class DistSampleWriter: + def __init__( + self, + directory: str, + *, + batches_per_partition: int = 256, + format: str = "parquet", + ): + """ + Parameters + ---------- + directory: str (required) + The directory where samples will be written. This + writer can only write to disk. + batches_per_partition: int (optional, default=256) + The number of batches to write in a single file. + format: str (optional, default='parquet') + The file format of the output files containing the + sampled minibatches. Currently, only parquet format + is supported. + """ + if format != "parquet": + raise ValueError("Invalid format (currently supported: 'parquet')") + + self.__format = format + self.__directory = directory + self.__batches_per_partition = batches_per_partition + + @property + def _format(self): + return self.__format + + @property + def _directory(self): + return self.__directory + + @property + def _batches_per_partition(self): + return self.__batches_per_partition + + def get_reader( + self, rank: int + ) -> Iterator[Tuple[Dict[str, "torch.Tensor"], int, int]]: + """ + Returns an iterator over sampled data. + """ + + # currently only disk reading is supported + return DistSampleReader(self._directory, format=self._format, rank=rank) + + def __write_minibatches_coo(self, minibatch_dict): + has_edge_ids = minibatch_dict["edge_id"] is not None + has_edge_types = minibatch_dict["edge_type"] is not None + has_weights = minibatch_dict["weight"] is not None + + if minibatch_dict["renumber_map"] is None: + raise ValueError( + "Distributed sampling without renumbering is not supported" + ) + + # Quit if there are no batches to write. + if len(minibatch_dict["batch_id"]) == 0: + return + + fanout_length = (len(minibatch_dict["label_hop_offsets"]) - 1) // len( + minibatch_dict["batch_id"] + ) + + for p in range( + 0, int(ceil(len(minibatch_dict["batch_id"]) / self.__batches_per_partition)) + ): + partition_start = p * (self.__batches_per_partition) + partition_end = (p + 1) * (self.__batches_per_partition) + + label_hop_offsets_array_p = minibatch_dict["label_hop_offsets"][ + partition_start * fanout_length : partition_end * fanout_length + 1 + ] + + batch_id_array_p = minibatch_dict["batch_id"][partition_start:partition_end] + start_batch_id = batch_id_array_p[0] + + input_offsets_p = minibatch_dict["input_offsets"][ + partition_start : (partition_end + 1) + ] + input_index_p = minibatch_dict["input_index"][ + input_offsets_p[0] : input_offsets_p[-1] + ] + edge_inverse_p = ( + minibatch_dict["edge_inverse"][ + (input_offsets_p[0] * 2) : (input_offsets_p[-1] * 2) + ] + if "edge_inverse" in minibatch_dict + else None + ) + + start_ix, end_ix = label_hop_offsets_array_p[[0, -1]] + majors_array_p = minibatch_dict["majors"][start_ix:end_ix] + minors_array_p = minibatch_dict["minors"][start_ix:end_ix] + edge_id_array_p = ( + minibatch_dict["edge_id"][start_ix:end_ix] + if has_edge_ids + else cupy.array([], dtype="int64") + ) + edge_type_array_p = ( + minibatch_dict["edge_type"][start_ix:end_ix] + if has_edge_types + else cupy.array([], dtype="int32") + ) + weight_array_p = ( + minibatch_dict["weight"][start_ix:end_ix] + if has_weights + else cupy.array([], dtype="float32") + ) + + # create the renumber map offsets + renumber_map_offsets_array_p = minibatch_dict["renumber_map_offsets"][ + partition_start : partition_end + 1 + ] + + renumber_map_start_ix, renumber_map_end_ix = renumber_map_offsets_array_p[ + [0, -1] + ] + + renumber_map_array_p = minibatch_dict["renumber_map"][ + renumber_map_start_ix:renumber_map_end_ix + ] + + results_dataframe_p = create_df_from_disjoint_arrays( + { + "majors": majors_array_p, + "minors": minors_array_p, + "map": renumber_map_array_p, + "label_hop_offsets": label_hop_offsets_array_p, + "weight": weight_array_p, + "edge_id": edge_id_array_p, + "edge_type": edge_type_array_p, + "renumber_map_offsets": renumber_map_offsets_array_p, + "input_index": input_index_p, + "input_offsets": input_offsets_p, + "edge_inverse": edge_inverse_p, + } + ) + + end_batch_id = start_batch_id + len(batch_id_array_p) - 1 + rank = minibatch_dict["rank"] if "rank" in minibatch_dict else 0 + + full_output_path = os.path.join( + self.__directory, + f"batch={rank:05d}.{start_batch_id:08d}-" + f"{rank:05d}.{end_batch_id:08d}.parquet", + ) + + results_dataframe_p.to_parquet( + full_output_path, + compression=None, + index=False, + force_nullable_schema=True, + ) + + def __write_minibatches_csr(self, minibatch_dict): + has_edge_ids = minibatch_dict["edge_id"] is not None + has_edge_types = minibatch_dict["edge_type"] is not None + has_weights = minibatch_dict["weight"] is not None + + if minibatch_dict["renumber_map"] is None: + raise ValueError( + "Distributed sampling without renumbering is not supported" + ) + + # Quit if there are no batches to write. + if len(minibatch_dict["batch_id"]) == 0: + return + + fanout_length = (len(minibatch_dict["label_hop_offsets"]) - 1) // len( + minibatch_dict["batch_id"] + ) + + for p in range( + 0, int(ceil(len(minibatch_dict["batch_id"]) / self.__batches_per_partition)) + ): + partition_start = p * (self.__batches_per_partition) + partition_end = (p + 1) * (self.__batches_per_partition) + + label_hop_offsets_array_p = minibatch_dict["label_hop_offsets"][ + partition_start * fanout_length : partition_end * fanout_length + 1 + ] + + batch_id_array_p = minibatch_dict["batch_id"][partition_start:partition_end] + start_batch_id = batch_id_array_p[0] + + input_offsets_p = minibatch_dict["input_offsets"][ + partition_start : (partition_end + 1) + ] + input_index_p = minibatch_dict["input_index"][ + input_offsets_p[0] : input_offsets_p[-1] + ] + edge_inverse_p = ( + minibatch_dict["edge_inverse"][ + (input_offsets_p[0] * 2) : (input_offsets_p[-1] * 2) + ] + if "edge_inverse" in minibatch_dict + else None + ) + + # major offsets and minors + ( + major_offsets_start_incl, + major_offsets_end_incl, + ) = label_hop_offsets_array_p[[0, -1]] + + start_ix, end_ix = minibatch_dict["major_offsets"][ + [major_offsets_start_incl, major_offsets_end_incl] + ] + + major_offsets_array_p = minibatch_dict["major_offsets"][ + major_offsets_start_incl : major_offsets_end_incl + 1 + ] + + minors_array_p = minibatch_dict["minors"][start_ix:end_ix] + edge_id_array_p = ( + minibatch_dict["edge_id"][start_ix:end_ix] + if has_edge_ids + else cupy.array([], dtype="int64") + ) + edge_type_array_p = ( + minibatch_dict["edge_type"][start_ix:end_ix] + if has_edge_types + else cupy.array([], dtype="int32") + ) + weight_array_p = ( + minibatch_dict["weight"][start_ix:end_ix] + if has_weights + else cupy.array([], dtype="float32") + ) + + # create the renumber map offsets + renumber_map_offsets_array_p = minibatch_dict["renumber_map_offsets"][ + partition_start : partition_end + 1 + ] + + renumber_map_start_ix, renumber_map_end_ix = renumber_map_offsets_array_p[ + [0, -1] + ] + + renumber_map_array_p = minibatch_dict["renumber_map"][ + renumber_map_start_ix:renumber_map_end_ix + ] + + results_dataframe_p = create_df_from_disjoint_arrays( + { + "major_offsets": major_offsets_array_p, + "minors": minors_array_p, + "map": renumber_map_array_p, + "label_hop_offsets": label_hop_offsets_array_p, + "weight": weight_array_p, + "edge_id": edge_id_array_p, + "edge_type": edge_type_array_p, + "renumber_map_offsets": renumber_map_offsets_array_p, + "input_index": input_index_p, + "input_offsets": input_offsets_p, + "edge_inverse": edge_inverse_p, + } + ) + + end_batch_id = start_batch_id + len(batch_id_array_p) - 1 + rank = minibatch_dict["rank"] if "rank" in minibatch_dict else 0 + + full_output_path = os.path.join( + self.__directory, + f"batch={rank:05d}.{start_batch_id:08d}-" + f"{rank:05d}.{end_batch_id:08d}.parquet", + ) + + results_dataframe_p.to_parquet( + full_output_path, + compression=None, + index=False, + force_nullable_schema=True, + ) + + def write_minibatches(self, minibatch_dict): + if (minibatch_dict["majors"] is not None) and ( + minibatch_dict["minors"] is not None + ): + self.__write_minibatches_coo(minibatch_dict) + elif (minibatch_dict["major_offsets"] is not None) and ( + minibatch_dict["minors"] is not None + ): + self.__write_minibatches_csr(minibatch_dict) + else: + raise ValueError("invalid columns") diff --git a/python/cugraph/cugraph/gnn/data_loading/dist_sampler.py b/python/cugraph/cugraph/gnn/data_loading/dist_sampler.py index a49139961fd..0ff38741e1a 100644 --- a/python/cugraph/cugraph/gnn/data_loading/dist_sampler.py +++ b/python/cugraph/cugraph/gnn/data_loading/dist_sampler.py @@ -11,8 +11,6 @@ # See the License for the specific language governing permissions and # limitations under the License. -import os -import re import warnings from math import ceil from functools import reduce @@ -27,348 +25,19 @@ from cugraph.utilities.utils import import_optional, MissingModule from cugraph.gnn.comms import cugraph_comms_get_raft_handle -from cugraph.gnn.data_loading.bulk_sampler_io import create_df_from_disjoint_arrays + +from cugraph.gnn.data_loading.dist_io import BufferedSampleReader +from cugraph.gnn.data_loading.dist_io import DistSampleWriter torch = MissingModule("torch") TensorType = Union["torch.Tensor", cupy.ndarray, cudf.Series] -class DistSampleReader: - def __init__( - self, - directory: str, - *, - format: str = "parquet", - rank: Optional[int] = None, - filelist=None, - ): - torch = import_optional("torch") - - self.__format = format - self.__directory = directory - - if format != "parquet": - raise ValueError("Invalid format (currently supported: 'parquet')") - - if filelist is None: - files = os.listdir(directory) - ex = re.compile(r"batch\=([0-9]+)\.([0-9]+)\-([0-9]+)\.([0-9]+)\.parquet") - filematch = [ex.match(f) for f in files] - filematch = [f for f in filematch if f] - - if rank is not None: - filematch = [f for f in filematch if int(f[1]) == rank] - - batch_count = sum([int(f[4]) - int(f[2]) + 1 for f in filematch]) - filematch = sorted(filematch, key=lambda f: int(f[2]), reverse=True) - - self.__files = filematch - else: - self.__files = list(filelist) - - if rank is None: - self.__batch_count = batch_count - else: - batch_count = torch.tensor([batch_count], device="cuda") - torch.distributed.all_reduce(batch_count, torch.distributed.ReduceOp.MIN) - self.__batch_count = int(batch_count) - - def __iter__(self): - return self - - def __next__(self): - torch = import_optional("torch") - - if len(self.__files) > 0: - f = self.__files.pop() - fname = f[0] - start_inclusive = int(f[2]) - end_inclusive = int(f[4]) - - if (end_inclusive - start_inclusive + 1) > self.__batch_count: - end_inclusive = start_inclusive + self.__batch_count - 1 - self.__batch_count = 0 - else: - self.__batch_count -= end_inclusive - start_inclusive + 1 - - df = cudf.read_parquet(os.path.join(self.__directory, fname)) - tensors = {} - for col in list(df.columns): - s = df[col].dropna() - if len(s) > 0: - tensors[col] = torch.as_tensor(s, device="cuda") - df.drop(col, axis=1, inplace=True) - - return tensors, start_inclusive, end_inclusive - - raise StopIteration - - -class DistSampleWriter: - def __init__( - self, - directory: str, - *, - batches_per_partition: int = 256, - format: str = "parquet", - ): - """ - Parameters - ---------- - directory: str (required) - The directory where samples will be written. This - writer can only write to disk. - batches_per_partition: int (optional, default=256) - The number of batches to write in a single file. - format: str (optional, default='parquet') - The file format of the output files containing the - sampled minibatches. Currently, only parquet format - is supported. - """ - if format != "parquet": - raise ValueError("Invalid format (currently supported: 'parquet')") - - self.__format = format - self.__directory = directory - self.__batches_per_partition = batches_per_partition - - @property - def _format(self): - return self.__format - - @property - def _directory(self): - return self.__directory - - @property - def _batches_per_partition(self): - return self.__batches_per_partition - - def get_reader( - self, rank: int - ) -> Iterator[Tuple[Dict[str, "torch.Tensor"], int, int]]: - """ - Returns an iterator over sampled data. - """ - - # currently only disk reading is supported - return DistSampleReader(self._directory, format=self._format, rank=rank) - - def __write_minibatches_coo(self, minibatch_dict): - has_edge_ids = minibatch_dict["edge_id"] is not None - has_edge_types = minibatch_dict["edge_type"] is not None - has_weights = minibatch_dict["weight"] is not None - - if minibatch_dict["renumber_map"] is None: - raise ValueError( - "Distributed sampling without renumbering is not supported" - ) - - # Quit if there are no batches to write. - if len(minibatch_dict["batch_id"]) == 0: - return - - fanout_length = (len(minibatch_dict["label_hop_offsets"]) - 1) // len( - minibatch_dict["batch_id"] - ) - rank_batch_offset = minibatch_dict["batch_id"][0] - - for p in range( - 0, int(ceil(len(minibatch_dict["batch_id"]) / self.__batches_per_partition)) - ): - partition_start = p * (self.__batches_per_partition) - partition_end = (p + 1) * (self.__batches_per_partition) - - label_hop_offsets_array_p = minibatch_dict["label_hop_offsets"][ - partition_start * fanout_length : partition_end * fanout_length + 1 - ] - - batch_id_array_p = minibatch_dict["batch_id"][partition_start:partition_end] - start_batch_id = batch_id_array_p[0] - rank_batch_offset - - start_ix, end_ix = label_hop_offsets_array_p[[0, -1]] - majors_array_p = minibatch_dict["majors"][start_ix:end_ix] - minors_array_p = minibatch_dict["minors"][start_ix:end_ix] - edge_id_array_p = ( - minibatch_dict["edge_id"][start_ix:end_ix] - if has_edge_ids - else cupy.array([], dtype="int64") - ) - edge_type_array_p = ( - minibatch_dict["edge_type"][start_ix:end_ix] - if has_edge_types - else cupy.array([], dtype="int32") - ) - weight_array_p = ( - minibatch_dict["weight"][start_ix:end_ix] - if has_weights - else cupy.array([], dtype="float32") - ) - - # create the renumber map offsets - renumber_map_offsets_array_p = minibatch_dict["renumber_map_offsets"][ - partition_start : partition_end + 1 - ] - - renumber_map_start_ix, renumber_map_end_ix = renumber_map_offsets_array_p[ - [0, -1] - ] - - renumber_map_array_p = minibatch_dict["renumber_map"][ - renumber_map_start_ix:renumber_map_end_ix - ] - - results_dataframe_p = create_df_from_disjoint_arrays( - { - "majors": majors_array_p, - "minors": minors_array_p, - "map": renumber_map_array_p, - "label_hop_offsets": label_hop_offsets_array_p, - "weight": weight_array_p, - "edge_id": edge_id_array_p, - "edge_type": edge_type_array_p, - "renumber_map_offsets": renumber_map_offsets_array_p, - } - ) - - end_batch_id = start_batch_id + len(batch_id_array_p) - 1 - rank = minibatch_dict["rank"] if "rank" in minibatch_dict else 0 - - full_output_path = os.path.join( - self.__directory, - f"batch={rank:05d}.{start_batch_id:08d}-" - f"{rank:05d}.{end_batch_id:08d}.parquet", - ) - - results_dataframe_p.to_parquet( - full_output_path, - compression=None, - index=False, - force_nullable_schema=True, - ) - - def __write_minibatches_csr(self, minibatch_dict): - has_edge_ids = minibatch_dict["edge_id"] is not None - has_edge_types = minibatch_dict["edge_type"] is not None - has_weights = minibatch_dict["weight"] is not None - - if minibatch_dict["renumber_map"] is None: - raise ValueError( - "Distributed sampling without renumbering is not supported" - ) - - # Quit if there are no batches to write. - if len(minibatch_dict["batch_id"]) == 0: - return - - fanout_length = (len(minibatch_dict["label_hop_offsets"]) - 1) // len( - minibatch_dict["batch_id"] - ) - - for p in range( - 0, int(ceil(len(minibatch_dict["batch_id"]) / self.__batches_per_partition)) - ): - partition_start = p * (self.__batches_per_partition) - partition_end = (p + 1) * (self.__batches_per_partition) - - label_hop_offsets_array_p = minibatch_dict["label_hop_offsets"][ - partition_start * fanout_length : partition_end * fanout_length + 1 - ] - - batch_id_array_p = minibatch_dict["batch_id"][partition_start:partition_end] - start_batch_id = batch_id_array_p[0] - - # major offsets and minors - ( - major_offsets_start_incl, - major_offsets_end_incl, - ) = label_hop_offsets_array_p[[0, -1]] - - start_ix, end_ix = minibatch_dict["major_offsets"][ - [major_offsets_start_incl, major_offsets_end_incl] - ] - - major_offsets_array_p = minibatch_dict["major_offsets"][ - major_offsets_start_incl : major_offsets_end_incl + 1 - ] - - minors_array_p = minibatch_dict["minors"][start_ix:end_ix] - edge_id_array_p = ( - minibatch_dict["edge_id"][start_ix:end_ix] - if has_edge_ids - else cupy.array([], dtype="int64") - ) - edge_type_array_p = ( - minibatch_dict["edge_type"][start_ix:end_ix] - if has_edge_types - else cupy.array([], dtype="int32") - ) - weight_array_p = ( - minibatch_dict["weight"][start_ix:end_ix] - if has_weights - else cupy.array([], dtype="float32") - ) - - # create the renumber map offsets - renumber_map_offsets_array_p = minibatch_dict["renumber_map_offsets"][ - partition_start : partition_end + 1 - ] - - renumber_map_start_ix, renumber_map_end_ix = renumber_map_offsets_array_p[ - [0, -1] - ] - - renumber_map_array_p = minibatch_dict["renumber_map"][ - renumber_map_start_ix:renumber_map_end_ix - ] - - results_dataframe_p = create_df_from_disjoint_arrays( - { - "major_offsets": major_offsets_array_p, - "minors": minors_array_p, - "map": renumber_map_array_p, - "label_hop_offsets": label_hop_offsets_array_p, - "weight": weight_array_p, - "edge_id": edge_id_array_p, - "edge_type": edge_type_array_p, - "renumber_map_offsets": renumber_map_offsets_array_p, - } - ) - - end_batch_id = start_batch_id + len(batch_id_array_p) - 1 - rank = minibatch_dict["rank"] if "rank" in minibatch_dict else 0 - - full_output_path = os.path.join( - self.__directory, - f"batch={rank:05d}.{start_batch_id:08d}-" - f"{rank:05d}.{end_batch_id:08d}.parquet", - ) - - results_dataframe_p.to_parquet( - full_output_path, - compression=None, - index=False, - force_nullable_schema=True, - ) - - def write_minibatches(self, minibatch_dict): - if (minibatch_dict["majors"] is not None) and ( - minibatch_dict["minors"] is not None - ): - self.__write_minibatches_coo(minibatch_dict) - elif (minibatch_dict["major_offsets"] is not None) and ( - minibatch_dict["minors"] is not None - ): - self.__write_minibatches_csr(minibatch_dict) - else: - raise ValueError("invalid columns") - - class DistSampler: def __init__( self, graph: Union[pylibcugraph.SGGraph, pylibcugraph.MGGraph], - writer: DistSampleWriter, + writer: Optional[DistSampleWriter], local_seeds_per_call: int, retain_original_seeds: bool = False, ): @@ -379,7 +48,8 @@ def __init__( The pylibcugraph graph object that will be sampled. writer: DistSampleWriter (required) The writer responsible for writing samples to disk - or, in the future, device or host memory. + or; if None, then samples will be written to memory + instead. local_seeds_per_call: int The number of seeds on this rank this sampler will process in a single sampling call. Batches will @@ -402,14 +72,6 @@ def __init__( self.__handle = None self.__retain_original_seeds = retain_original_seeds - def get_reader(self) -> Iterator[Tuple[Dict[str, "torch.Tensor"], int, int]]: - """ - Returns an iterator over sampled data. - """ - torch = import_optional("torch") - rank = torch.distributed.get_rank() if self.is_multi_gpu else None - return self.__writer.get_reader(rank) - def sample_batches( self, seeds: TensorType, @@ -564,6 +226,108 @@ def get_start_batch_offset( else: return 0, input_size_is_equal + def __sample_from_nodes_func( + self, + call_id: int, + current_seeds_and_ix: Tuple["torch.Tensor", "torch.Tensor"], + batch_id_start: int, + batch_size: int, + batches_per_call: int, + random_state: int, + assume_equal_input_size: bool, + ) -> Union[None, Iterator[Tuple[Dict[str, "torch.Tensor"], int, int]]]: + torch = import_optional("torch") + + current_seeds, current_ix = current_seeds_and_ix + + current_batches = torch.arange( + batch_id_start + call_id * batches_per_call, + batch_id_start + + call_id * batches_per_call + + int(ceil(len(current_seeds))) + + 1, + device="cuda", + dtype=torch.int32, + ) + + current_batches = current_batches.repeat_interleave(batch_size)[ + : len(current_seeds) + ] + + # do qr division to get the number of batch_size batches and the + # size of the last batch + num_full, last_count = divmod(len(current_seeds), batch_size) + input_offsets = torch.concatenate( + [ + torch.tensor([0], device="cuda", dtype=torch.int64), + torch.full((num_full,), batch_size, device="cuda", dtype=torch.int64), + torch.tensor([last_count], device="cuda", dtype=torch.int64) + if last_count > 0 + else torch.tensor([], device="cuda", dtype=torch.int64), + ] + ).cumsum(-1) + + minibatch_dict = self.sample_batches( + seeds=current_seeds, + batch_ids=current_batches, + random_state=random_state, + assume_equal_input_size=assume_equal_input_size, + ) + minibatch_dict["input_index"] = current_ix.cuda() + minibatch_dict["input_offsets"] = input_offsets + + if self.__writer is None: + # rename renumber_map -> map to match unbuffered format + minibatch_dict["map"] = minibatch_dict["renumber_map"] + del minibatch_dict["renumber_map"] + minibatch_dict = { + k: torch.as_tensor(v, device="cuda") + for k, v in minibatch_dict.items() + if v is not None + } + + return iter([(minibatch_dict, current_batches[0], current_batches[-1])]) + else: + self.__writer.write_minibatches(minibatch_dict) + return None + + def __get_call_groups( + self, + seeds: TensorType, + input_id: TensorType, + seeds_per_call: int, + assume_equal_input_size: bool = False, + ): + torch = import_optional("torch") + + # Split the input seeds into call groups. Each call group + # corresponds to one sampling call. A call group contains + # many batches. + seeds_call_groups = torch.split(seeds, seeds_per_call, dim=-1) + index_call_groups = torch.split(input_id, seeds_per_call, dim=-1) + + # Need to add empties to the list of call groups to handle the case + # where not all ranks have the same number of call groups. This + # prevents a hang since we need all ranks to make the same number + # of calls. + if not assume_equal_input_size: + num_call_groups = torch.tensor( + [len(seeds_call_groups)], device="cuda", dtype=torch.int32 + ) + torch.distributed.all_reduce( + num_call_groups, op=torch.distributed.ReduceOp.MAX + ) + seeds_call_groups = list(seeds_call_groups) + ( + [torch.tensor([], dtype=seeds.dtype, device="cuda")] + * (int(num_call_groups) - len(seeds_call_groups)) + ) + index_call_groups = list(index_call_groups) + ( + [torch.tensor([], dtype=torch.int64, device=input_id.device)] + * (int(num_call_groups) - len(index_call_groups)) + ) + + return seeds_call_groups, index_call_groups + def sample_from_nodes( self, nodes: TensorType, @@ -571,7 +335,8 @@ def sample_from_nodes( batch_size: int = 16, random_state: int = 62, assume_equal_input_size: bool = False, - ): + input_id: Optional[TensorType] = None, + ) -> Iterator[Tuple[Dict[str, "torch.Tensor"], int, int]]: """ Performs node-based sampling. Accepts a list of seed nodes, and batch size. Splits the seed list into batches, then divides the batches into call groups @@ -587,64 +352,301 @@ def sample_from_nodes( The size of each batch. random_state: int The random seed to use for sampling. + assume_equal_input_size: bool + Whether the inputs across workers should be assumed to be equal in + dimension. Skips some checks if True. + input_id: Optional[TensorType] + Input ids corresponding to the original batch tensor, if it + was permuted prior to calling this function. If present, + will be saved with the samples. """ torch = import_optional("torch") nodes = torch.as_tensor(nodes, device="cuda") + num_seeds = nodes.numel() batches_per_call = self._local_seeds_per_call // batch_size actual_seeds_per_call = batches_per_call * batch_size - # Split the input seeds into call groups. Each call group - # corresponds to one sampling call. A call group contains - # many batches. - num_seeds = len(nodes) - nodes_call_groups = torch.split(nodes, actual_seeds_per_call) + if input_id is None: + input_id = torch.arange(num_seeds, dtype=torch.int64, device="cpu") local_num_batches = int(ceil(num_seeds / batch_size)) batch_id_start, input_size_is_equal = self.get_start_batch_offset( local_num_batches, assume_equal_input_size=assume_equal_input_size ) - # Need to add empties to the list of call groups to handle the case - # where not all nodes have the same number of call groups. This - # prevents a hang since we need all ranks to make the same number - # of calls. - if not input_size_is_equal: - num_call_groups = torch.tensor( - [len(nodes_call_groups)], device="cuda", dtype=torch.int32 - ) - torch.distributed.all_reduce( - num_call_groups, op=torch.distributed.ReduceOp.MAX + nodes_call_groups, index_call_groups = self.__get_call_groups( + nodes, + input_id, + actual_seeds_per_call, + assume_equal_input_size=input_size_is_equal, + ) + + sample_args = ( + batch_id_start, + batch_size, + batches_per_call, + random_state, + input_size_is_equal, + ) + + if self.__writer is None: + # Buffered sampling + return BufferedSampleReader( + zip(nodes_call_groups, index_call_groups), + self.__sample_from_nodes_func, + *sample_args, ) - nodes_call_groups = list(nodes_call_groups) + ( - [torch.tensor([], dtype=nodes.dtype, device="cuda")] - * (int(num_call_groups) - len(nodes_call_groups)) + else: + # Unbuffered sampling + for i, current_seeds_and_ix in enumerate( + zip(nodes_call_groups, index_call_groups) + ): + self.__sample_from_nodes_func( + i, + current_seeds_and_ix, + *sample_args, + ) + + # Return a reader that points to the stored samples + rank = torch.distributed.get_rank() if self.is_multi_gpu else None + return self.__writer.get_reader(rank) + + def __sample_from_edges_func( + self, + call_id: int, + current_seeds_and_ix: Tuple["torch.Tensor", "torch.Tensor"], + batch_id_start: int, + batch_size: int, + batches_per_call: int, + random_state: int, + assume_equal_input_size: bool, + ) -> Union[None, Iterator[Tuple[Dict[str, "torch.Tensor"], int, int]]]: + torch = import_optional("torch") + + current_seeds, current_ix = current_seeds_and_ix + num_seed_edges = current_ix.numel() + + # The index gets stored as-is regardless of what makes it into + # the final batch and in what order. + # do qr division to get the number of batch_size batches and the + # size of the last batch + num_whole_batches, last_count = divmod(num_seed_edges, batch_size) + input_offsets = torch.concatenate( + [ + torch.tensor([0], device="cuda", dtype=torch.int64), + torch.full( + (num_whole_batches,), batch_size, device="cuda", dtype=torch.int64 + ), + torch.tensor([last_count], device="cuda", dtype=torch.int64) + if last_count > 0 + else torch.tensor([], device="cuda", dtype=torch.int64), + ] + ).cumsum(-1) + + current_seeds, leftover_seeds = ( + current_seeds[:, : (batch_size * num_whole_batches)], + current_seeds[:, (batch_size * num_whole_batches) :], + ) + + # For input edges, we need to translate this into unique vertices + # for each batch. + # We start by reorganizing the seed and index tensors so we can + # determine the unique vertices. This results in the expected + # src-to-dst concatenation for each batch + current_seeds = torch.concat( + [ + current_seeds[0].reshape((-1, batch_size)), + current_seeds[1].reshape((-1, batch_size)), + ], + axis=-1, + ) + + # The returned unique values must be sorted or else the inverse won't line up + # In the future this may be a good target for a C++ function + # Each element is a tuple of (unique, index, inverse) + # The seeds must be presorted with a stable sort prior to calling + # unique_consecutive in order to support negative sampling. This is + # because if we put positive edges after negative ones, then we may + # inadvertently turn a true positive into a false negative. + y = ( + torch.sort( + t, + stable=True, ) + for t in current_seeds + ) + z = ((v, torch.sort(i)[1]) for v, i in y) - # Make a call to sample_batches for each call group - for i, current_seeds in enumerate(nodes_call_groups): - current_batches = torch.arange( - batch_id_start + i * batches_per_call, - batch_id_start - + i * batches_per_call - + int(ceil(len(current_seeds))) - + 1, - device="cuda", - dtype=torch.int32, + u = [ + ( + torch.unique_consecutive( + t, + return_inverse=True, + ), + i, ) + for t, i in z + ] - current_batches = current_batches.repeat_interleave(batch_size)[ - : len(current_seeds) + if len(u) > 0: + current_seeds = torch.concat([a[0] for a, _ in u]) + current_inv = torch.concat([a[1][i] for a, i in u]) + current_batches = torch.concat( + [ + torch.full( + (a[0].numel(),), + i + batch_id_start + (call_id * batches_per_call), + device="cuda", + dtype=torch.int32, + ) + for i, (a, _) in enumerate(u) + ] + ) + else: + current_seeds = torch.tensor([], device="cuda", dtype=torch.int64) + current_inv = torch.tensor([], device="cuda", dtype=torch.int64) + current_batches = torch.tensor([], device="cuda", dtype=torch.int32) + del u + + # Join with the leftovers + leftover_seeds, lyi = torch.sort( + leftover_seeds.flatten(), + stable=True, + ) + lz = torch.sort(lyi)[1] + leftover_seeds, lui = leftover_seeds.unique_consecutive(return_inverse=True) + leftover_inv = lui[lz] + + current_seeds = torch.concat([current_seeds, leftover_seeds]) + current_inv = torch.concat([current_inv, leftover_inv]) + current_batches = torch.concat( + [ + current_batches, + torch.full( + (leftover_seeds.numel(),), + (current_batches[-1] + 1) if current_batches.numel() > 0 else 0, + device="cuda", + dtype=torch.int32, + ), ] + ) + del leftover_seeds + del lz + del lui + + minibatch_dict = self.sample_batches( + seeds=current_seeds, + batch_ids=current_batches, + random_state=random_state, + assume_equal_input_size=assume_equal_input_size, + ) + minibatch_dict["input_index"] = current_ix.cuda() + minibatch_dict["input_offsets"] = input_offsets + minibatch_dict[ + "edge_inverse" + ] = current_inv # (2 * batch_size) entries per batch + + if self.__writer is None: + # rename renumber_map -> map to match unbuffered format + minibatch_dict["map"] = minibatch_dict["renumber_map"] + del minibatch_dict["renumber_map"] + minibatch_dict = { + k: torch.as_tensor(v, device="cuda") + for k, v in minibatch_dict.items() + if v is not None + } + + return iter([(minibatch_dict, current_batches[0], current_batches[-1])]) + else: + self.__writer.write_minibatches(minibatch_dict) + return None - minibatch_dict = self.sample_batches( - seeds=current_seeds, - batch_ids=current_batches, - random_state=random_state, - assume_equal_input_size=input_size_is_equal, + def sample_from_edges( + self, + edges: TensorType, + *, + batch_size: int = 16, + random_state: int = 62, + assume_equal_input_size: bool = False, + input_id: Optional[TensorType] = None, + ) -> Iterator[Tuple[Dict[str, "torch.Tensor"], int, int]]: + """ + Performs sampling starting from seed edges. + + Parameters + ---------- + edges: TensorType + 2 x (# edges) tensor of edges to sample from. + Standard src/dst format. This will be converted + to a list of seed nodes. + batch_size: int + The size of each batch. + random_state: int + The random seed to use for sampling. + assume_equal_input_size: bool + Whether this function should assume that inputs + are equal across ranks. Skips some potentially + slow steps if True. + input_id: Optional[TensorType] + Input ids corresponding to the original batch tensor, if it + was permuted prior to calling this function. If present, + will be saved with the samples. + """ + + torch = import_optional("torch") + + edges = torch.as_tensor(edges, device="cuda") + num_seed_edges = edges.shape[-1] + + batches_per_call = self._local_seeds_per_call // batch_size + actual_seed_edges_per_call = batches_per_call * batch_size + + if input_id is None: + input_id = torch.arange(len(edges), dtype=torch.int64, device="cpu") + + local_num_batches = int(ceil(num_seed_edges / batch_size)) + batch_id_start, input_size_is_equal = self.get_start_batch_offset( + local_num_batches, assume_equal_input_size=assume_equal_input_size + ) + + edges_call_groups, index_call_groups = self.__get_call_groups( + edges, + input_id, + actual_seed_edges_per_call, + assume_equal_input_size=input_size_is_equal, + ) + + sample_args = ( + batch_id_start, + batch_size, + batches_per_call, + random_state, + input_size_is_equal, + ) + + if self.__writer is None: + # Buffered sampling + return BufferedSampleReader( + zip(edges_call_groups, index_call_groups), + self.__sample_from_edges_func, + *sample_args, ) - self.__writer.write_minibatches(minibatch_dict) + else: + # Unbuffered sampling + for i, current_seeds_and_ix in enumerate( + zip(edges_call_groups, index_call_groups) + ): + self.__sample_from_edges_func( + i, + current_seeds_and_ix, + *sample_args, + ) + + # Return a reader that points to the stored samples + rank = torch.distributed.get_rank() if self.is_multi_gpu else None + return self.__writer.get_reader(rank) @property def is_multi_gpu(self): @@ -709,6 +711,8 @@ def __init__( # sampling. So setting the function here is safe. In the future, # if libcugraph allows setting a new attribute, this API might # change. + # TODO allow func to be a call to a future remote sampling API + # if the provided graph is in another process (rapidsai/cugraph#4623). self.__func = ( pylibcugraph.biased_neighbor_sample if biased @@ -776,7 +780,7 @@ def sample_batches( label_to_output_comm_rank=cupy.asarray(label_to_output_comm_rank), h_fan_out=np.array(self.__fanout, dtype="int32"), with_replacement=self.__with_replacement, - do_expensive_check=True, + do_expensive_check=False, with_edge_properties=True, random_state=random_state + rank, prior_sources_behavior=self.__prior_sources_behavior, diff --git a/python/cugraph/cugraph/structure/graph_classes.py b/python/cugraph/cugraph/structure/graph_classes.py index e90c0576f55..84234f7e904 100644 --- a/python/cugraph/cugraph/structure/graph_classes.py +++ b/python/cugraph/cugraph/structure/graph_classes.py @@ -116,6 +116,7 @@ def from_cudf_edgelist( renumber=True, store_transposed=False, legacy_renum_only=False, + symmetrize=None, ): """ Initialize a graph from the edge list. It is an error to call this @@ -174,6 +175,15 @@ def from_cudf_edgelist( This parameter is deprecated and will be removed. + symmetrize: bool, optional (default=None) + If True, symmetrize the edge list for an undirected graph. Setting + this flag to True for a directed graph returns an error. The default + behavior symmetrizes the edges if the graph is undirected. This flag + cannot be set to True if the edgelist contains edge IDs or edge Types. + If the incoming edgelist is intended for an undirected graph and it is + known to be symmetric, this flag can be set to False to skip the + symmetrization step for better performance. + Examples -------- >>> df = cudf.read_csv(datasets_path / 'karate.csv', delimiter=' ', @@ -201,6 +211,7 @@ def from_cudf_edgelist( renumber=renumber, store_transposed=store_transposed, legacy_renum_only=legacy_renum_only, + symmetrize=symmetrize, ) def from_cudf_adjlist( @@ -210,6 +221,7 @@ def from_cudf_adjlist( value_col=None, renumber=True, store_transposed=False, + symmetrize=None, ): """ Initialize a graph from the adjacency list. It is an error to call this @@ -247,6 +259,14 @@ def from_cudf_adjlist( store_transposed : bool, optional (default=False) If True, stores the transpose of the adjacency matrix. Required for certain algorithms. + symmetrize: bool, optional (default=None) + If True, symmetrize the edge list for an undirected graph. Setting + this flag to True for a directed graph returns an error. The default + behavior symmetrizes the edges if the graph is undirected. This flag + cannot be set to True if the edgelist contains edge IDs or edge Types. + If the incoming edgelist is intended for an undirected graph and it is + known to be symmetric, this flag can be set to False to skip the + symmetrization step for better performance. Examples -------- @@ -268,7 +288,12 @@ def from_cudf_adjlist( raise RuntimeError("Graph is already initialized") elif self._Impl.edgelist is not None or self._Impl.adjlist is not None: raise RuntimeError("Graph already has values") - self._Impl._simpleGraphImpl__from_adjlist(offset_col, index_col, value_col) + self._Impl._simpleGraphImpl__from_adjlist( + offset_col=offset_col, + index_col=index_col, + value_col=value_col, + symmetrize=symmetrize, + ) def from_dask_cudf_edgelist( self, diff --git a/python/cugraph/cugraph/structure/graph_implementation/simpleDistributedGraph.py b/python/cugraph/cugraph/structure/graph_implementation/simpleDistributedGraph.py index 7f3f7e83e59..83dad234287 100644 --- a/python/cugraph/cugraph/structure/graph_implementation/simpleDistributedGraph.py +++ b/python/cugraph/cugraph/structure/graph_implementation/simpleDistributedGraph.py @@ -34,7 +34,6 @@ ) from cugraph.structure.number_map import NumberMap -from cugraph.structure.symmetrize import symmetrize from cugraph.dask.common.part_utils import ( persist_dask_df_equal_parts_per_worker, ) @@ -98,6 +97,7 @@ def _make_plc_graph( edge_id_type, edge_type_id, drop_multi_edges, + symmetrize, ): weights = None edge_ids = None @@ -151,6 +151,7 @@ def _make_plc_graph( else ([cudf.Series(dtype=edge_type_id)] if edge_type_id else None), num_arrays=num_arrays, store_transposed=store_transposed, + symmetrize=symmetrize, do_expensive_check=False, drop_multi_edges=drop_multi_edges, ) @@ -172,6 +173,7 @@ def __from_edgelist( renumber=True, store_transposed=False, legacy_renum_only=False, + symmetrize=None, ): if not isinstance(input_ddf, dask_cudf.DataFrame): raise TypeError("input should be a dask_cudf dataFrame") @@ -184,6 +186,35 @@ def __from_edgelist( ].dtype not in [np.int32, np.int64]: raise ValueError("set renumber to True for non integer columns ids") + if self.properties.directed and symmetrize: + raise ValueError( + "The edgelist can only be symmetrized for undirected graphs." + ) + + if self.properties.directed: + if symmetrize: + raise ValueError( + "The edgelist can only be symmetrized for undirected graphs." + ) + else: + if symmetrize or symmetrize is None: + unsupported = False + if edge_id is not None or edge_type is not None: + unsupported = True + if isinstance(edge_attr, list): + if len(edge_attr) > 1: + unsupported = True + if unsupported: + raise ValueError( + "Edge list containing Edge Ids or Types can't be symmetrized. " + "If the edges are already symmetric, set the 'symmetrize' " + "flag to False" + ) + + if symmetrize is None: + # default behavior + symmetrize = not self.properties.directed + s_col = source d_col = destination if not isinstance(s_col, list): @@ -266,27 +297,11 @@ def __from_edgelist( ddf_columns += value_col_names input_ddf = input_ddf[ddf_columns] - if len(value_col_names) == 0: - source_col, dest_col = symmetrize( - input_ddf, - source, - destination, - multi=True, # Deprecated parameter - symmetrize=not self.properties.directed, - ) - value_col = None - else: - source_col, dest_col, value_col = symmetrize( - input_ddf, - source, - destination, - value_col_names, - multi=True, # Deprecated parameter - symmetrize=not self.properties.directed, - ) - # Create a dask_cudf dataframe from the cudf series # or dataframe objects obtained from symmetrization + source_col = input_ddf[source] + dest_col = input_ddf[destination] + value_col = input_ddf[value_col_names] if isinstance(source_col, dask_cudf.Series): frames = [ source_col.to_frame(name=source), @@ -370,6 +385,7 @@ def __from_edgelist( self.edge_id_type, self.edge_type_id_type, not self.properties.multi_edge, + not self.properties.directed, ) for w, edata in persisted_keys_d.items() } diff --git a/python/cugraph/cugraph/structure/graph_implementation/simpleGraph.py b/python/cugraph/cugraph/structure/graph_implementation/simpleGraph.py index bc5cca67c2e..858b114ebdc 100644 --- a/python/cugraph/cugraph/structure/graph_implementation/simpleGraph.py +++ b/python/cugraph/cugraph/structure/graph_implementation/simpleGraph.py @@ -13,7 +13,7 @@ from cugraph.structure import graph_primtypes_wrapper from cugraph.structure.replicate_edgelist import replicate_cudf_dataframe -from cugraph.structure.symmetrize import symmetrize +from cugraph.structure.symmetrize import symmetrize as symmetrize_df from cugraph.structure.number_map import NumberMap import cugraph.dask.common.mg_utils as mg_utils import cudf @@ -134,6 +134,7 @@ def __from_edgelist( renumber=True, legacy_renum_only=False, store_transposed=False, + symmetrize=None, ): if legacy_renum_only: warning_msg = ( @@ -143,6 +144,35 @@ def __from_edgelist( warning_msg, ) + if self.properties.directed and symmetrize: + raise ValueError( + "The edgelist can only be symmetrized for undirected graphs." + ) + + if self.properties.directed: + if symmetrize: + raise ValueError( + "The edgelist can only be symmetrized for undirected graphs." + ) + else: + if symmetrize or symmetrize is None: + unsupported = False + if edge_id is not None or edge_type is not None: + unsupported = True + if isinstance(edge_attr, list): + if len(edge_attr) > 1: + unsupported = True + if unsupported: + raise ValueError( + "Edge list containing Edge Ids or Types can't be symmetrized. " + "If the edges are already symmetric, set the 'symmetrize' " + "flag to False" + ) + + if symmetrize is None: + # default behavior + symmetrize = not self.properties.directed + # Verify column names present in input DataFrame s_col = source d_col = destination @@ -264,45 +294,27 @@ def __from_edgelist( ) raise ValueError("set renumber to True for non integer columns ids") - # The dataframe will be symmetrized iff the graph is undirected - # otherwise the inital dataframe will be returned. Duplicated edges - # will be dropped unless the graph is a MultiGraph(Not Implemented yet) - # TODO: Update Symmetrize to work on Graph and/or DataFrame + # The dataframe will be symmetrized iff the graph is undirected with the + # symmetrize flag set to None or True otherwise, the inital dataframe will + # be returned. If set to False, the API will assume that the edges are already + # symmetric. Duplicated edges will be dropped unless the graph is a + # MultiGraph(Not Implemented yet) + if edge_attr is not None: - source_col, dest_col, value_col = symmetrize( - elist, - source, - destination, - edge_attr, - multi=self.properties.multi_edge, # Deprecated parameter - symmetrize=not self.properties.directed, - ) + value_col = { + self.edgeWeightCol: elist[weight] if weight in edge_attr else None, + self.edgeIdCol: elist[edge_id] if edge_id in edge_attr else None, + self.edgeTypeCol: elist[edge_type] if edge_type in edge_attr else None, + } - if isinstance(value_col, cudf.DataFrame): - value_dict = {} - for i in value_col.columns: - value_dict[i] = value_col[i] - value_col = value_dict else: value_col = None - source_col, dest_col = symmetrize( - elist, - source, - destination, - multi=self.properties.multi_edge, # Deprecated parameter - symmetrize=not self.properties.directed, - ) - - if isinstance(value_col, dict): - value_col = { - self.edgeWeightCol: value_col[weight] if weight in value_col else None, - self.edgeIdCol: value_col[edge_id] if edge_id in value_col else None, - self.edgeTypeCol: value_col[edge_type] - if edge_type in value_col - else None, - } - self.edgelist = simpleGraphImpl.EdgeList(source_col, dest_col, value_col) + # FIXME: if the user calls self.edgelist.edgelist_df after creating a + # symmetric graph, return the symmetric edgelist? + self.edgelist = simpleGraphImpl.EdgeList( + elist[source], elist[destination], value_col + ) if self.batch_enabled: self._replicate_edgelist() @@ -312,6 +324,7 @@ def __from_edgelist( store_transposed=store_transposed, renumber=renumber, drop_multi_edges=not self.properties.multi_edge, + symmetrize=symmetrize, ) def to_pandas_edgelist( @@ -549,13 +562,23 @@ def __from_adjlist( value_col=None, renumber=True, store_transposed=False, + symmetrize=None, ): self.adjlist = simpleGraphImpl.AdjList(offset_col, index_col, value_col) + + if self.properties.directed and symmetrize: + raise ValueError("The edges can only be symmetrized for undirected graphs.") + if value_col is not None: self.properties.weighted = True self._make_plc_graph( - value_col=value_col, store_transposed=store_transposed, renumber=renumber + value_col=value_col, + store_transposed=store_transposed, + renumber=renumber, + symmetrize=not self.properties.directed + if symmetrize is None + else symmetrize, ) if self.batch_enabled: @@ -1146,6 +1169,7 @@ def _make_plc_graph( store_transposed: bool = False, renumber: bool = True, drop_multi_edges: bool = False, + symmetrize: bool = False, ): """ Parameters @@ -1164,6 +1188,8 @@ def _make_plc_graph( int32 or int64 type. drop_multi_edges: bool (default=False) Whether to drop multi edges + symmetrize: bool (default=False) + Whether to symmetrize """ if value_col is None: @@ -1228,6 +1254,7 @@ def _make_plc_graph( do_expensive_check=True, input_array_format=input_array_format, drop_multi_edges=drop_multi_edges, + symmetrize=symmetrize, ) def to_directed(self, DiG, store_transposed=False): @@ -1253,12 +1280,18 @@ def to_directed(self, DiG, store_transposed=False): DiG._make_plc_graph(value_col, store_transposed) def to_undirected(self, G, store_transposed=False): + """ Return an undirected copy of the graph. Note: This will discard any edge ids or edge types but will preserve edge weights if present. """ + # FIXME: Update this function to not call the deprecated + # symmetrize function. + # 1) Import the C++ function that symmetrize a graph + # 2) decompress the edgelist to update 'simpleGraphImpl.EdgeList' + # Doesn't work for edgelists with edge_ids and edge_types. G.properties.renumbered = self.properties.renumbered G.renumber_map = self.renumber_map if self.properties.directed is False: @@ -1268,14 +1301,14 @@ def to_undirected(self, G, store_transposed=False): else: df = self.edgelist.edgelist_df if self.edgelist.weights: - source_col, dest_col, value_col = symmetrize( + source_col, dest_col, value_col = symmetrize_df( df, simpleGraphImpl.srcCol, simpleGraphImpl.dstCol, simpleGraphImpl.edgeWeightCol, ) else: - source_col, dest_col = symmetrize( + source_col, dest_col = symmetrize_df( df, simpleGraphImpl.srcCol, simpleGraphImpl.dstCol ) value_col = None @@ -1310,6 +1343,28 @@ def has_edge(self, u, v): v = tmp["id"][1] df = self.edgelist.edgelist_df + + if self.edgelist.weights: + # FIXME: Update this function to not call the deprecated + # symmetrize function. + source_col, dest_col, value_col = symmetrize_df( + df, + simpleGraphImpl.srcCol, + simpleGraphImpl.dstCol, + simpleGraphImpl.edgeWeightCol, + symmetrize=not self.properties.directed, + ) + else: + source_col, dest_col = symmetrize_df( + df, + simpleGraphImpl.srcCol, + simpleGraphImpl.dstCol, + symmetrize=not self.properties.directed, + ) + value_col = None + + self.edgelist = simpleGraphImpl.EdgeList(source_col, dest_col, value_col) + return ( (df[simpleGraphImpl.srcCol] == u) & (df[simpleGraphImpl.dstCol] == v) ).any() diff --git a/python/cugraph/cugraph/structure/graph_primtypes.pxd b/python/cugraph/cugraph/structure/graph_primtypes.pxd index eaf552195da..f547db5c463 100644 --- a/python/cugraph/cugraph/structure/graph_primtypes.pxd +++ b/python/cugraph/cugraph/structure/graph_primtypes.pxd @@ -1,4 +1,4 @@ -# Copyright (c) 2019-2023, NVIDIA CORPORATION. +# Copyright (c) 2019-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 @@ -21,7 +21,7 @@ from libcpp.memory cimport unique_ptr from libcpp.utility cimport pair from libcpp.vector cimport vector from pylibraft.common.handle cimport * -from rmm._lib.device_buffer cimport device_buffer +from rmm.librmm.device_buffer cimport device_buffer cdef extern from "cugraph/legacy/graph.hpp" namespace "cugraph::legacy": diff --git a/python/cugraph/cugraph/structure/graph_primtypes.pyx b/python/cugraph/cugraph/structure/graph_primtypes.pyx index 10f3871e157..063790a33a4 100644 --- a/python/cugraph/cugraph/structure/graph_primtypes.pyx +++ b/python/cugraph/cugraph/structure/graph_primtypes.pyx @@ -1,4 +1,4 @@ -# Copyright (c) 2020-2023, NVIDIA CORPORATION. +# Copyright (c) 2020-2024, NVIDIA CORPORATION. # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at @@ -20,7 +20,7 @@ import numpy as np from libc.stdint cimport uintptr_t from libcpp.utility cimport move -from rmm._lib.device_buffer cimport DeviceBuffer +from rmm.pylibrmm.device_buffer cimport DeviceBuffer from cudf.core.buffer import as_buffer import cudf diff --git a/python/cugraph/cugraph/structure/graph_utilities.pxd b/python/cugraph/cugraph/structure/graph_utilities.pxd index 39e2cdbbff5..5612990c452 100644 --- a/python/cugraph/cugraph/structure/graph_utilities.pxd +++ b/python/cugraph/cugraph/structure/graph_utilities.pxd @@ -21,7 +21,7 @@ from libcpp.memory cimport unique_ptr from libcpp.utility cimport pair from libcpp.vector cimport vector -from rmm._lib.device_buffer cimport device_buffer +from rmm.librmm.device_buffer cimport device_buffer from pylibraft.common.handle cimport handle_t diff --git a/python/cugraph/cugraph/structure/hypergraph.py b/python/cugraph/cugraph/structure/hypergraph.py index bdc98333da0..55e6bbcca3d 100644 --- a/python/cugraph/cugraph/structure/hypergraph.py +++ b/python/cugraph/cugraph/structure/hypergraph.py @@ -37,6 +37,7 @@ import cudf import numpy as np from cugraph.structure.graph_classes import Graph +from cugraph.structure.symmetrize import symmetrize def hypergraph( @@ -277,6 +278,32 @@ def hypergraph( renumber=True, ) + df = cudf.DataFrame() + + # Need to refactor this code as it uses the + # deprecated symmetrize call. + if "weights" in graph.edgelist.edgelist_df: + source_col, dest_col, value_col = symmetrize( + graph.edgelist.edgelist_df, + "src", + "dst", + "weights", + symmetrize=not graph.is_directed(), + ) + + df["src"] = source_col + df["dst"] = dest_col + df["weights"] = value_col + else: + source_col, dest_col = symmetrize( + graph.edgelist.edgelist_df, "src", "dst", symmetrize=not graph.is_directed() + ) + + df["src"] = source_col + df["dst"] = dest_col + + graph.edgelist.edgelist_df = df + return { "nodes": nodes, "edges": edges, diff --git a/python/cugraph/cugraph/structure/property_graph.py b/python/cugraph/cugraph/structure/property_graph.py index 53c1bf778c7..5f55a15888a 100644 --- a/python/cugraph/cugraph/structure/property_graph.py +++ b/python/cugraph/cugraph/structure/property_graph.py @@ -15,6 +15,7 @@ import numpy as np import cugraph +from cugraph.structure.symmetrize import symmetrize from cugraph.utilities.utils import ( import_optional, MissingModule, @@ -2005,6 +2006,33 @@ def edge_props_to_graph( else: G.from_pandas_edgelist(edge_prop_df.reset_index(), **create_args) + # FIXME: Property_graph does not fully leverage the PLC API yet. + # It still relies on the edges being symmetrized by the deprecated + # symmetrize function. + + # Symmetrize the internal representation of the edgelists + + if edge_attr is not None: + source_col, dest_col, value_col = symmetrize( + G.edgelist.edgelist_df, + "src", + "dst", + "weights", + symmetrize=not G.is_directed(), + ) + else: + source_col, dest_col = symmetrize( + G.edgelist.edgelist_df, "src", "dst", symmetrize=not G.is_directed() + ) + + renumbered_edge_prop_df = cudf.DataFrame() + renumbered_edge_prop_df["src"] = source_col + renumbered_edge_prop_df["dst"] = dest_col + if edge_attr: + renumbered_edge_prop_df["weights"] = value_col + + G.edgelist.edgelist_df = renumbered_edge_prop_df + if add_edge_data: # Set the edge_data on the resulting Graph to a DataFrame # containing the edges and the edge ID for each. Edge IDs are diff --git a/python/cugraph/cugraph/structure/symmetrize.py b/python/cugraph/cugraph/structure/symmetrize.py index 3e46d81b6ff..b59661b1cd4 100644 --- a/python/cugraph/cugraph/structure/symmetrize.py +++ b/python/cugraph/cugraph/structure/symmetrize.py @@ -257,6 +257,11 @@ def symmetrize( >>> df['values'] = cudf.Series(M['2']) >>> src, dst, val = symmetrize(df, 'sources', 'destinations', 'values', multi=True) """ + warnings.warn( + "This method is deprecated and will no longer be supported. The symmetrization " + "of the edges are only supported by setting the 'symmetrize' flag to 'True'", + FutureWarning, + ) # FIXME: Redundant check that should be done at the graph creation if "edge_id" in input_df.columns and symmetrize: diff --git a/python/cugraph/cugraph/tests/data_store/test_property_graph.py b/python/cugraph/cugraph/tests/data_store/test_property_graph.py index da5608e0193..50f08cdf3d0 100644 --- a/python/cugraph/cugraph/tests/data_store/test_property_graph.py +++ b/python/cugraph/cugraph/tests/data_store/test_property_graph.py @@ -2576,9 +2576,10 @@ def bench_extract_subgraph_for_rmat(gpubenchmark, rmat_PropertyGraph): scn = PropertyGraph.src_col_name dcn = PropertyGraph.dst_col_name - verts = [] - for i in range(0, 10000, 10): - verts.append(generated_df["src"].iloc[i]) + # Build a query string to extract a graph with only specific edges based on + # the integer vertex IDs. Other edge and/or vertex properties can be + # included in the query as well. + verts = [int(generated_df["src"].iloc[i]) for i in range(0, 10000, 10)] selected_edges = pG.select_edges(f"{scn}.isin({verts}) | {dcn}.isin({verts})") gpubenchmark( @@ -2618,9 +2619,10 @@ def bench_extract_subgraph_for_rmat_detect_duplicate_edges( scn = PropertyGraph.src_col_name dcn = PropertyGraph.dst_col_name - verts = [] - for i in range(0, 10000, 10): - verts.append(generated_df["src"].iloc[i]) + # Build a query string to extract a graph with only specific edges based on + # the integer vertex IDs. Other edge and/or vertex properties can be + # included in the query as well. + verts = [int(generated_df["src"].iloc[i]) for i in range(0, 10000, 10)] selected_edges = pG.select_edges(f"{scn}.isin({verts}) | {dcn}.isin({verts})") diff --git a/python/cugraph/cugraph/tests/generators/test_rmat.py b/python/cugraph/cugraph/tests/generators/test_rmat.py index 1cee0461686..87cbe636fdc 100644 --- a/python/cugraph/cugraph/tests/generators/test_rmat.py +++ b/python/cugraph/cugraph/tests/generators/test_rmat.py @@ -27,7 +27,9 @@ _scale_values = [2, 4, 16] _scale_test_ids = [f"scale={x}" for x in _scale_values] _graph_types = [cugraph.Graph, None, int] -_graph_test_ids = [f"create_using={getattr(x,'__name__',str(x))}" for x in _graph_types] +_graph_test_ids = [ + f"create_using={getattr(x, '__name__', str(x))}" for x in _graph_types +] _clip_and_flip = [False, True] _clip_and_flip_test_ids = [f"clip_and_flip={x}" for x in _clip_and_flip] _scramble_vertex_ids = [False, True] diff --git a/python/cugraph/cugraph/tests/generators/test_rmat_mg.py b/python/cugraph/cugraph/tests/generators/test_rmat_mg.py index 0e1808d2f80..44a6b3a2fc1 100644 --- a/python/cugraph/cugraph/tests/generators/test_rmat_mg.py +++ b/python/cugraph/cugraph/tests/generators/test_rmat_mg.py @@ -1,4 +1,4 @@ -# Copyright (c) 2021-2023, NVIDIA CORPORATION. +# Copyright (c) 2021-2024, NVIDIA CORPORATION. # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at @@ -34,7 +34,9 @@ _scale_values = [2, 4, 16] _scale_test_ids = [f"scale={x}" for x in _scale_values] _graph_types = [cugraph.Graph, None, int] -_graph_test_ids = [f"create_using={getattr(x,'__name__',str(x))}" for x in _graph_types] +_graph_test_ids = [ + f"create_using={getattr(x, '__name__', str(x))}" for x in _graph_types +] def _call_rmat(scale, num_edges, create_using, mg=True): diff --git a/python/cugraph/cugraph/tests/sampling/test_bulk_sampler.py b/python/cugraph/cugraph/tests/sampling/test_bulk_sampler.py index 65bcce78771..3c5d6428001 100644 --- a/python/cugraph/cugraph/tests/sampling/test_bulk_sampler.py +++ b/python/cugraph/cugraph/tests/sampling/test_bulk_sampler.py @@ -119,7 +119,7 @@ def test_bulk_sampler_remainder(scratch_dir): assert b in recovered_samples["batch_id"].values_host.tolist() for x in range(0, 6, 2): - subdir = f"{x}-{x+1}" + subdir = f"{x}-{x + 1}" df = cudf.read_parquet(os.path.join(samples_path, f"batch={subdir}.parquet")) assert ((df.batch_id == x) | (df.batch_id == (x + 1))).all() diff --git a/python/cugraph/cugraph/tests/sampling/test_dist_sampler.py b/python/cugraph/cugraph/tests/sampling/test_dist_sampler.py index 70b20e7baec..64db0232fb1 100644 --- a/python/cugraph/cugraph/tests/sampling/test_dist_sampler.py +++ b/python/cugraph/cugraph/tests/sampling/test_dist_sampler.py @@ -20,6 +20,7 @@ from cugraph.datasets import karate from cugraph.gnn import UniformNeighborSampler, DistSampleWriter +from cugraph.gnn.data_loading.bulk_sampler_io import create_df_from_disjoint_arrays from pylibcugraph import SGGraph, ResourceHandle, GraphProperties @@ -41,7 +42,7 @@ @pytest.fixture -def karate_graph(): +def karate_graph() -> SGGraph: el = karate.get_edgelist().reset_index().rename(columns={"index": "eid"}) G = SGGraph( ResourceHandle(), @@ -101,3 +102,60 @@ def test_dist_sampler_simple( assert original_el.dst.iloc[edge_id.iloc[i]] == dst.iloc[i] shutil.rmtree(samples_path) + + +@pytest.mark.sg +@pytest.mark.skipif(isinstance(torch, MissingModule), reason="torch not available") +@pytest.mark.parametrize("seeds_per_call", [4, 5, 10]) +@pytest.mark.parametrize("compression", ["COO", "CSR"]) +def test_dist_sampler_buffered_in_memory( + scratch_dir: str, karate_graph: SGGraph, seeds_per_call: int, compression: str +): + G = karate_graph + + samples_path = os.path.join(scratch_dir, "test_bulk_sampler_buffered_in_memory") + create_directory_with_overwrite(samples_path) + + seeds = cupy.arange(10, dtype="int64") + + unbuffered_sampler = UniformNeighborSampler( + G, + writer=DistSampleWriter(samples_path), + local_seeds_per_call=seeds_per_call, + compression=compression, + ) + + buffered_sampler = UniformNeighborSampler( + G, + writer=None, + local_seeds_per_call=seeds_per_call, + compression=compression, + ) + + unbuffered_results = unbuffered_sampler.sample_from_nodes( + seeds, + batch_size=4, + ) + + unbuffered_results = [ + (create_df_from_disjoint_arrays(r[0]), r[1], r[2]) for r in unbuffered_results + ] + + buffered_results = buffered_sampler.sample_from_nodes(seeds, batch_size=4) + buffered_results = [ + (create_df_from_disjoint_arrays(r[0]), r[1], r[2]) for r in buffered_results + ] + + assert len(buffered_results) == len(unbuffered_results) + + for k in range(len(buffered_results)): + br, bs, be = buffered_results[k] + ur, us, ue = unbuffered_results[k] + + assert bs == us + assert be == ue + + for col in ur.columns: + assert (br[col].dropna() == ur[col].dropna()).all() + + shutil.rmtree(samples_path) diff --git a/python/cugraph/cugraph/tests/sampling/test_dist_sampler_mg.py b/python/cugraph/cugraph/tests/sampling/test_dist_sampler_mg.py index a1c32938994..5bb541d6cf3 100644 --- a/python/cugraph/cugraph/tests/sampling/test_dist_sampler_mg.py +++ b/python/cugraph/cugraph/tests/sampling/test_dist_sampler_mg.py @@ -18,6 +18,8 @@ import cupy import cudf +from typing import Any + from cugraph.datasets import karate from cugraph.gnn import ( UniformNeighborSampler, @@ -27,6 +29,7 @@ cugraph_comms_init, cugraph_comms_shutdown, ) +from cugraph.gnn.data_loading.bulk_sampler_io import create_df_from_disjoint_arrays from pylibcugraph import MGGraph, ResourceHandle, GraphProperties from cugraph.utilities.utils import ( @@ -235,3 +238,80 @@ def test_dist_sampler_uneven(scratch_dir, batch_size, fanout, seeds_per_call): assert original_el.dst.iloc[edge_id.iloc[i]] == dst.iloc[i] shutil.rmtree(samples_path) + + +def run_test_dist_sampler_buffered_in_memory( + rank: int, + world_size: int, + uid: Any, + samples_path: str, + seeds_per_call: int, + compression: str, +): + init_pytorch(rank, world_size) + cugraph_comms_init(rank, world_size, uid, device=rank) + + G = karate_mg_graph(rank, world_size) + + num_seeds = 8 + seeds = cupy.random.randint(0, 34, num_seeds, dtype="int64") + + unbuffered_sampler = UniformNeighborSampler( + G, + writer=DistSampleWriter(samples_path), + local_seeds_per_call=seeds_per_call, + compression=compression, + ) + + buffered_sampler = UniformNeighborSampler( + G, + writer=None, + local_seeds_per_call=seeds_per_call, + compression=compression, + ) + + unbuffered_results = unbuffered_sampler.sample_from_nodes( + seeds, + batch_size=4, + ) + + unbuffered_results = [ + (create_df_from_disjoint_arrays(r[0]), r[1], r[2]) for r in unbuffered_results + ] + + buffered_results = buffered_sampler.sample_from_nodes(seeds, batch_size=4) + buffered_results = [ + (create_df_from_disjoint_arrays(r[0]), r[1], r[2]) for r in buffered_results + ] + + assert len(buffered_results) == len(unbuffered_results) + + for k in range(len(buffered_results)): + br, bs, be = buffered_results[k] + ur, us, ue = unbuffered_results[k] + + assert bs == us + assert be == ue + + for col in ur.columns: + assert (br[col].dropna() == ur[col].dropna()).all() + + +@pytest.mark.mg +@pytest.mark.skipif(isinstance(torch, MissingModule), reason="torch not available") +@pytest.mark.parametrize("seeds_per_call", [4, 5, 10]) +@pytest.mark.parametrize("compression", ["COO", "CSR"]) +def test_dist_sampler_buffered_in_memory(scratch_dir, seeds_per_call, compression): + uid = cugraph_comms_create_unique_id() + + samples_path = os.path.join(scratch_dir, "test_bulk_sampler_buffered_in_memory_mg") + create_directory_with_overwrite(samples_path) + + world_size = torch.cuda.device_count() + torch.multiprocessing.spawn( + run_test_dist_sampler_buffered_in_memory, + args=(world_size, uid, samples_path, seeds_per_call, compression), + nprocs=world_size, + ) + + shutil.rmtree(samples_path) diff --git a/python/cugraph/cugraph/tests/sampling/test_random_walks_mg.py b/python/cugraph/cugraph/tests/sampling/test_random_walks_mg.py index 2db3c6f5907..34eeb2902f8 100644 --- a/python/cugraph/cugraph/tests/sampling/test_random_walks_mg.py +++ b/python/cugraph/cugraph/tests/sampling/test_random_walks_mg.py @@ -19,8 +19,10 @@ import cugraph import dask_cudf import cugraph.dask as dcg +import cudf from cugraph.testing import SMALL_DATASETS from cugraph.datasets import karate_asymmetric +from cugraph.structure.symmetrize import symmetrize from pylibcugraph.testing.utils import gen_fixture_params_product @@ -205,4 +207,15 @@ def input_graph(request): def test_dask_mg_random_walks(dask_client, input_graph): path_data, seeds, max_depth = calc_random_walks(input_graph) df_G = input_graph.input_df.compute().reset_index(drop=True) - check_random_walks(input_graph, path_data, seeds, max_depth, df_G) + + # FIXME: leverages the deprecated symmetrize call + source_col, dest_col, value_col = symmetrize( + df_G, "src", "dst", "value", symmetrize=not input_graph.is_directed() + ) + + df = cudf.DataFrame() + df["src"] = source_col + df["dst"] = dest_col + df["value"] = value_col + + check_random_walks(input_graph, path_data, seeds, max_depth, df) diff --git a/python/cugraph/cugraph/tests/sampling/test_uniform_neighbor_sample.py b/python/cugraph/cugraph/tests/sampling/test_uniform_neighbor_sample.py index 304ead6fea9..ad0dbe77f7d 100644 --- a/python/cugraph/cugraph/tests/sampling/test_uniform_neighbor_sample.py +++ b/python/cugraph/cugraph/tests/sampling/test_uniform_neighbor_sample.py @@ -21,6 +21,7 @@ from cugraph import uniform_neighbor_sample from cugraph.testing import UNDIRECTED_DATASETS from cugraph.datasets import email_Eu_core, small_tree +from cugraph.structure.symmetrize import symmetrize from pylibcugraph.testing.utils import gen_fixture_params_product @@ -148,6 +149,15 @@ def test_uniform_neighbor_sample_simple(input_combo): # should be 'None' if the datasets was never renumbered input_df = G.edgelist.edgelist_df + # FIXME: Uses the deprecated implementation of symmetrize. + source_col, dest_col = symmetrize( + input_df, "src", "dst", symmetrize=not G.is_directed() + ) + + input_df = cudf.DataFrame() + input_df["src"] = source_col + input_df["dst"] = dest_col + result_nbr = uniform_neighbor_sample( G, input_combo["start_list"], @@ -235,6 +245,19 @@ def test_uniform_neighbor_sample_tree(directed): G = cugraph.Graph(directed=directed) G.from_cudf_edgelist(df, "src", "dst", "value") + # FIXME: Uses the deprecated implementation of symmetrize. + source_col, dest_col, value_col = symmetrize( + G.edgelist.edgelist_df, "src", "dst", "weights", symmetrize=not G.is_directed() + ) + + # Retrieve the input dataframe. + # input_df != df if 'directed = False' because df will be symmetrized + # internally. + input_df = cudf.DataFrame() + input_df["src"] = source_col + input_df["dst"] = dest_col + input_df["value"] = value_col + # # Make sure the old C++ renumbering was skipped because: # 1) Pylibcugraph already does renumbering @@ -245,11 +268,6 @@ def test_uniform_neighbor_sample_tree(directed): assert G.renumbered is False - # Retrieve the input dataframe. - # input_df != df if 'directed = False' because df will be symmetrized - # internally. - input_df = G.edgelist.edgelist_df - # TODO: Incomplete, include more testing for tree graph as well as # for larger graphs start_list = cudf.Series([0, 0], dtype="int32") diff --git a/python/cugraph/cugraph/tests/sampling/test_uniform_neighbor_sample_mg.py b/python/cugraph/cugraph/tests/sampling/test_uniform_neighbor_sample_mg.py index c65535f98a2..4a85b49a66e 100644 --- a/python/cugraph/cugraph/tests/sampling/test_uniform_neighbor_sample_mg.py +++ b/python/cugraph/cugraph/tests/sampling/test_uniform_neighbor_sample_mg.py @@ -27,6 +27,7 @@ from cugraph.dask import uniform_neighbor_sample from cugraph.dask.common.mg_utils import is_single_gpu from cugraph.structure.symmetrize import _memory_efficient_drop_duplicates +from cugraph.structure.symmetrize import symmetrize_ddf from cugraph.datasets import email_Eu_core, small_tree from pylibcugraph.testing.utils import gen_fixture_params_product @@ -144,6 +145,10 @@ def test_mg_uniform_neighbor_sample_simple(dask_client, input_combo): input_df, vertex_col_name, len(workers) ) + input_df = symmetrize_ddf( + input_df, src_name="src", dst_name="dst", symmetrize=not dg.is_directed() + ) + result_nbr = uniform_neighbor_sample( dg, input_combo["start_list"], @@ -247,6 +252,11 @@ def test_mg_uniform_neighbor_sample_tree(dask_client, directed): # input_df != ddf if 'directed = False' because ddf will be symmetrized # internally. input_df = G.input_df + + input_df = symmetrize_ddf( + input_df, src_name="src", dst_name="dst", symmetrize=not G.is_directed() + ) + join = result_nbr.merge( input_df, left_on=[*result_nbr.columns[:2]], right_on=[*input_df.columns[:2]] ) diff --git a/python/cugraph/cugraph/tests/structure/test_graph.py b/python/cugraph/cugraph/tests/structure/test_graph.py index c0524fcfe77..b3e517100e1 100644 --- a/python/cugraph/cugraph/tests/structure/test_graph.py +++ b/python/cugraph/cugraph/tests/structure/test_graph.py @@ -25,6 +25,8 @@ from cugraph.testing import utils from cudf.testing import assert_series_equal from cudf.testing.testing import assert_frame_equal +from cugraph.structure.symmetrize import symmetrize +from cugraph.datasets import karate_asymmetric # MG import dask_cudf @@ -203,6 +205,37 @@ def test_add_adj_list_to_edge_list(graph_file): compare_series(destinations_cu, destinations_exp) +@pytest.mark.sg +def test_create_undirected_graph_from_asymmetric_adj_list(): + # karate_asymmetric.get_path() + Mnx = utils.read_csv_for_nx(karate_asymmetric.get_path()) + N = max(max(Mnx["0"]), max(Mnx["1"])) + 1 + Mcsr = scipy.sparse.csr_matrix((Mnx.weight, (Mnx["0"], Mnx["1"])), shape=(N, N)) + + offsets = cudf.Series(Mcsr.indptr) + indices = cudf.Series(Mcsr.indices) + + G = cugraph.Graph(directed=False) + + with pytest.raises(Exception): + # Ifan undirected graph is created with 'symmetrize' set to False, the + # edgelist provided by the user must be symmetric. + G.from_cudf_adjlist(offsets, indices, None, symmetrize=False) + + G = cugraph.Graph(directed=False) + G.from_cudf_adjlist(offsets, indices, None, symmetrize=True) + + # FIXME: Since we have no mechanism to access the symmetrized edgelist + # from the graph_view_t, assert that the edgelist size is unchanged. Once + # exposing 'decompress_to_edgelist', ensure that + # G.number_of_edges() == 2 * karate_asymmetric.get_edgelist()? + assert G.number_of_edges() == len(karate_asymmetric.get_edgelist()) + + # FIXME: Once 'decompress_to_edgelist' is exposed to the + # python API, ensure that the derived edgelist is symmetric + # if symmetrize = True. + + # Test @pytest.mark.sg @pytest.mark.parametrize("graph_file", utils.DATASETS) @@ -534,6 +567,18 @@ def test_to_directed(graph_file): # cugraph add_edge_list G = cugraph.Graph() G.from_cudf_edgelist(cu_M, source="0", destination="1") + + # FIXME: Uses the deprecated implementation of symmetrize. + source_col, dest_col = symmetrize( + G.edgelist.edgelist_df, "src", "dst", symmetrize=not G.is_directed() + ) + + input_df = cudf.DataFrame() + input_df["src"] = source_col + input_df["dst"] = dest_col + + G.edgelist.edgelist_df = input_df + Gnx = nx.from_pandas_edgelist(M, source="0", target="1", create_using=nx.Graph()) DiG = G.to_directed() diff --git a/python/cugraph/cugraph/tests/structure/test_graph_mg.py b/python/cugraph/cugraph/tests/structure/test_graph_mg.py index cba61731e9a..f2cc1583f93 100644 --- a/python/cugraph/cugraph/tests/structure/test_graph_mg.py +++ b/python/cugraph/cugraph/tests/structure/test_graph_mg.py @@ -303,7 +303,7 @@ def test_mg_graph_serializable(dask_client, input_combo): G = input_combo["MGGraph"] dask_client.publish_dataset(shared_g=G) shared_g = dask_client.get_dataset("shared_g") - assert type(shared_g) == type(G) + assert type(shared_g) is type(G) assert G.number_of_vertices() == shared_g.number_of_vertices() assert G.number_of_edges() == shared_g.number_of_edges() # cleanup @@ -314,7 +314,7 @@ def test_mg_graph_serializable(dask_client, input_combo): def test_mg_graph_copy(): G = cugraph.MultiGraph(directed=True) G_c = copy.deepcopy(G) - assert type(G) == type(G_c) + assert type(G) is type(G_c) @pytest.mark.mg diff --git a/python/cugraph/cugraph/tests/structure/test_multigraph.py b/python/cugraph/cugraph/tests/structure/test_multigraph.py index a9ea617fdb8..e245894b479 100644 --- a/python/cugraph/cugraph/tests/structure/test_multigraph.py +++ b/python/cugraph/cugraph/tests/structure/test_multigraph.py @@ -1,4 +1,4 @@ -# Copyright (c) 2020-2023, NVIDIA CORPORATION. +# Copyright (c) 2020-2024, NVIDIA CORPORATION. # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at @@ -76,7 +76,7 @@ def test_Graph_from_MultiGraph(graph_file): G = cugraph.Graph(GM) Gnx = nx.Graph(GnxM) - assert Gnx.number_of_edges() == G.number_of_edges() + assert Gnx.number_of_edges() == G.number_of_edges(directed_edges=True) GdM = graph_file.get_graph(create_using=cugraph.MultiGraph(directed=True)) GnxdM = nx.from_pandas_edgelist( nxM, diff --git a/python/cugraph/cugraph/tests/traversal/test_sssp.py b/python/cugraph/cugraph/tests/traversal/test_sssp.py index 58288e022e8..ceb6040275d 100644 --- a/python/cugraph/cugraph/tests/traversal/test_sssp.py +++ b/python/cugraph/cugraph/tests/traversal/test_sssp.py @@ -1,4 +1,4 @@ -# Copyright (c) 2019-2023, NVIDIA CORPORATION. +# Copyright (c) 2019-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 @@ -486,7 +486,7 @@ def test_scipy_api_compat(): distances = cugraph.shortest_path( input_coo_matrix, source=0, return_predecessors=False ) - assert type(distances) != tuple + assert type(distances) is not tuple with pytest.raises(ValueError): cugraph.shortest_path(input_coo_matrix, source=0, unweighted=False) diff --git a/python/cugraph/cugraph/tests/utils/test_dataset.py b/python/cugraph/cugraph/tests/utils/test_dataset.py index a52b99dabfe..3873cd1c3e4 100644 --- a/python/cugraph/cugraph/tests/utils/test_dataset.py +++ b/python/cugraph/cugraph/tests/utils/test_dataset.py @@ -26,6 +26,7 @@ from cugraph.dask.common.mg_utils import is_single_gpu from cugraph.datasets import karate from cugraph.structure import Graph +from cugraph.structure.symmetrize import symmetrize from cugraph.testing import ( RAPIDS_DATASET_ROOT_DIR_PATH, ALL_DATASETS, @@ -379,6 +380,29 @@ def test_node_and_edge_count(dataset): download=True, create_using=Graph(directed=dataset_is_directed) ) + df = cudf.DataFrame() + if "weights" in G.edgelist.edgelist_df: + source_col, dest_col, value_col = symmetrize( + G.edgelist.edgelist_df, + "src", + "dst", + "weights", + symmetrize=not G.is_directed(), + ) + + df["src"] = source_col + df["dst"] = dest_col + df["weights"] = value_col + else: + source_col, dest_col = symmetrize( + G.edgelist.edgelist_df, "src", "dst", symmetrize=not G.is_directed() + ) + + df["src"] = source_col + df["dst"] = dest_col + + G.edgelist.edgelist_df = df + assert G.number_of_nodes() == dataset.metadata["number_of_nodes"] assert G.number_of_edges() == dataset.metadata["number_of_edges"] diff --git a/python/cugraph/cugraph/traversal/sssp.py b/python/cugraph/cugraph/traversal/sssp.py index 5ab97e60390..bb98b5a9a29 100644 --- a/python/cugraph/cugraph/traversal/sssp.py +++ b/python/cugraph/cugraph/traversal/sssp.py @@ -1,4 +1,4 @@ -# Copyright (c) 2019-2023, NVIDIA CORPORATION. +# Copyright (c) 2019-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 @@ -36,7 +36,7 @@ def _ensure_args( # checks common to all input types if (method is not None) and (method != "auto"): raise ValueError("only 'auto' is currently accepted for method") - if (indices is not None) and (type(indices) == list): + if (indices is not None) and (type(indices) is list): raise ValueError("indices currently cannot be a list-like type") if (indices is not None) and (source is not None): raise TypeError("cannot specify both 'source' and 'indices'") @@ -70,9 +70,11 @@ def _ensure_args( # Check for non-Graph-type inputs else: - if (directed is not None) and (type(directed) != bool): + if (directed is not None) and (type(directed) is not bool): raise ValueError("'directed' must be a bool") - if (return_predecessors is not None) and (type(return_predecessors) != bool): + if (return_predecessors is not None) and ( + type(return_predecessors) is not bool + ): raise ValueError("'return_predecessors' must be a bool") if (unweighted is not None) and (unweighted is not True): raise ValueError("'unweighted' currently must be True if " "specified") diff --git a/python/cugraph/cugraph/utilities/nx_factory.py b/python/cugraph/cugraph/utilities/nx_factory.py index d07d17978d7..794fb33a7a1 100644 --- a/python/cugraph/cugraph/utilities/nx_factory.py +++ b/python/cugraph/cugraph/utilities/nx_factory.py @@ -1,4 +1,4 @@ -# Copyright (c) 2020-2023, NVIDIA CORPORATION. +# Copyright (c) 2020-2024, NVIDIA CORPORATION. # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at @@ -24,6 +24,8 @@ from cudf import from_pandas from cudf.api.types import is_integer_dtype +from cugraph.structure.symmetrize import symmetrize + # nx will be a MissingModule instance if NetworkX is not installed (any # attribute access on a MissingModule instance results in a RuntimeError). nx = import_optional("networkx") @@ -129,6 +131,17 @@ def convert_from_nx( if is_weighted is False: _gdf = convert_unweighted_to_gdf(nxG, vertex_type) + # FIXME: The legacy algorithms do not support the PLC graph + # hence, the symmetrization cannot be performed at the graph + # creation. Use the deprecated 'symmetrize' function for now. + source_col, dest_col = symmetrize( + _gdf, "src", "dst", symmetrize=not G.is_directed() + ) + + _gdf = cudf.DataFrame() + + _gdf["src"] = source_col + _gdf["dst"] = dest_col G.from_cudf_edgelist( _gdf, source="src", @@ -140,6 +153,18 @@ def convert_from_nx( else: if weight is None: _gdf = convert_weighted_unnamed_to_gdf(nxG, vertex_type) + # FIXME: The legacy algorithms do not support the PLC graph + # hence, the symmetrization cannot be performed at the graph + # creation. Use the deprecated 'symmetrize' function for now. + source_col, dest_col, value_col = symmetrize( + _gdf, "src", "target", "weight", symmetrize=not G.is_directed() + ) + + _gdf = cudf.DataFrame() + + _gdf["src"] = source_col + _gdf["target"] = dest_col + _gdf["weight"] = value_col G.from_cudf_edgelist( _gdf, source="source", @@ -148,8 +173,22 @@ def convert_from_nx( renumber=do_renumber, store_transposed=store_transposed, ) + else: _gdf = convert_weighted_named_to_gdf(nxG, weight, vertex_type) + # FIXME: The legacy algorithms do not support the PLC graph + # hence, the symmetrization cannot be performed at the graph + # creation. Use the deprecated 'symmetrize' function for now. + source_col, dest_col, value_col = symmetrize( + _gdf, "src", "dst", "weight", symmetrize=not G.is_directed() + ) + + _gdf = cudf.DataFrame() + + _gdf["src"] = source_col + _gdf["dst"] = dest_col + _gdf["weight"] = value_col + G.from_cudf_edgelist( _gdf, source="src", diff --git a/python/cugraph/pyproject.toml b/python/cugraph/pyproject.toml index 31721c8a568..8185a8d915d 100644 --- a/python/cugraph/pyproject.toml +++ b/python/cugraph/pyproject.toml @@ -23,18 +23,18 @@ authors = [ license = { text = "Apache 2.0" } requires-python = ">=3.10" dependencies = [ - "cudf==24.10.*,>=0.0.0a0", + "cudf==24.12.*,>=0.0.0a0", "cupy-cuda11x>=12.0.0", - "dask-cuda==24.10.*,>=0.0.0a0", - "dask-cudf==24.10.*,>=0.0.0a0", + "dask-cuda==24.12.*,>=0.0.0a0", + "dask-cudf==24.12.*,>=0.0.0a0", "fsspec[http]>=0.6.0", "numba>=0.57", - "numpy>=1.23,<2.0a0", - "pylibcugraph==24.10.*,>=0.0.0a0", - "raft-dask==24.10.*,>=0.0.0a0", - "rapids-dask-dependency==24.10.*,>=0.0.0a0", - "rmm==24.10.*,>=0.0.0a0", - "ucx-py==0.40.*,>=0.0.0a0", + "numpy>=1.23,<3.0a0", + "pylibcugraph==24.12.*,>=0.0.0a0", + "raft-dask==24.12.*,>=0.0.0a0", + "rapids-dask-dependency==24.12.*,>=0.0.0a0", + "rmm==24.12.*,>=0.0.0a0", + "ucx-py==0.41.*,>=0.0.0a0", ] # This list was generated by `rapids-dependency-file-generator`. To make changes, edit ../../dependencies.yaml and run `rapids-dependency-file-generator`. classifiers = [ "Intended Audience :: Developers", @@ -47,9 +47,9 @@ classifiers = [ [project.optional-dependencies] test = [ "networkx>=2.5.1", - "numpy>=1.23,<2.0a0", + "numpy>=1.23,<3.0a0", "pandas", - "pylibwholegraph==24.10.*,>=0.0.0a0", + "pylibwholegraph==24.12.*,>=0.0.0a0", "pytest", "pytest-benchmark", "pytest-cov", @@ -82,9 +82,9 @@ build-backend = "scikit_build_core.build" requires = [ "cmake>=3.26.4,!=3.30.0", "ninja", - "pylibcugraph==24.10.*,>=0.0.0a0", - "pylibraft==24.10.*,>=0.0.0a0", - "rmm==24.10.*,>=0.0.0a0", + "pylibcugraph==24.12.*,>=0.0.0a0", + "pylibraft==24.12.*,>=0.0.0a0", + "rmm==24.12.*,>=0.0.0a0", ] # This list was generated by `rapids-dependency-file-generator`. To make changes, edit ../../dependencies.yaml and run `rapids-dependency-file-generator`. dependencies-file = "../../dependencies.yaml" matrix-entry = "cuda_suffixed=true" diff --git a/python/cugraph/pytest.ini b/python/cugraph/pytest.ini index 675a6cf8fde..2f01a0cc51b 100644 --- a/python/cugraph/pytest.ini +++ b/python/cugraph/pytest.ini @@ -17,6 +17,7 @@ addopts = --benchmark-max-time=0 --benchmark-min-rounds=1 --benchmark-columns="mean, rounds" + --tb=native ## do not run the slow tests/benchmarks by default -m "not slow" ## for use with rapids-pytest-benchmark plugin @@ -70,3 +71,4 @@ filterwarnings = ignore:This function is deprecated. Batched support for multiple vertices:DeprecationWarning # Called via dask. Not obviously addressable in cugraph. ignore:The behavior of array concatenation with empty entries is deprecated:FutureWarning + ignore:This method is deprecated and will no longer be supported. The symmetrization:FutureWarning diff --git a/python/nx-cugraph/README.md b/python/nx-cugraph/README.md index c3ca0b880a9..8cc3a5d90df 100644 --- a/python/nx-cugraph/README.md +++ b/python/nx-cugraph/README.md @@ -1,7 +1,7 @@ # nx-cugraph ## Description -[RAPIDS](https://rapids.ai) nx-cugraph is a [backend to NetworkX](https://networkx.org/documentation/stable/reference/utils.html#backends) +[RAPIDS](https://rapids.ai) nx-cugraph is a [backend to NetworkX](https://networkx.org/documentation/stable/backends.html) to run supported algorithms with GPU acceleration. ## System Requirements @@ -10,7 +10,7 @@ nx-cugraph requires the following: * NVIDIA GPU, Volta architecture or later, with [compute capability](https://developer.nvidia.com/cuda-gpus) 7.0+ * CUDA 11.2, 11.4, 11.5, 11.8, 12.0, 12.2, or 12.5 * Python version 3.10, 3.11, or 3.12 - * NetworkX >= version 3.0 (version 3.2 or higher recommended) + * NetworkX >= version 3.0 (version 3.4 or higher recommended) More details about system requirements can be found in the [RAPIDS System Requirements documentation](https://docs.rapids.ai/install#system-req). @@ -45,18 +45,20 @@ Notes: NetworkX will use nx-cugraph as the graph analytics backend if any of the following are used: -### `NETWORKX_AUTOMATIC_BACKENDS` environment variable. -The `NETWORKX_AUTOMATIC_BACKENDS` environment variable can be used to have NetworkX automatically dispatch to specified backends an API is called that the backend supports. -Set `NETWORKX_AUTOMATIC_BACKENDS=cugraph` to use nx-cugraph to GPU accelerate supported APIs with no code changes. +### `NX_CUGRAPH_AUTOCONFIG` environment variable. +By setting `NX_CUGRAPH_AUTOCONFIG=True`, NetworkX will automatically dispatch algorithm calls to nx-cugraph (if the backend is supported). This allows users to GPU accelerate their code with zero code change. + +Read more on [Networkx Backends and How They Work](https://networkx.org/documentation/stable/reference/backends.html). + Example: ``` -bash> NETWORKX_AUTOMATIC_BACKENDS=cugraph python my_networkx_script.py +bash> NX_CUGRAPH_AUTOCONFIG=True python my_networkx_script.py ``` ### `backend=` keyword argument To explicitly specify a particular backend for an API, use the `backend=` keyword argument. This argument takes precedence over the -`NETWORKX_AUTOMATIC_BACKENDS` environment variable. This requires anyone +`NX_CUGRAPH_AUTOCONFIG` environment variable. This requires anyone running code that uses the `backend=` keyword argument to have the specified backend installed. diff --git a/python/nx-cugraph/_nx_cugraph/__init__.py b/python/nx-cugraph/_nx_cugraph/__init__.py index 41c18c27ecf..9feeda568a6 100644 --- a/python/nx-cugraph/_nx_cugraph/__init__.py +++ b/python/nx-cugraph/_nx_cugraph/__init__.py @@ -22,6 +22,7 @@ $ python _nx_cugraph/__init__.py """ +import os from _nx_cugraph._version import __version__ @@ -35,7 +36,7 @@ "backend_name": "cugraph", "project": "nx-cugraph", "package": "nx_cugraph", - "url": f"https://github.com/rapidsai/cugraph/tree/branch-{_version_major:0>2}.{_version_minor:0>2}/python/nx-cugraph", + "url": "https://rapids.ai/nx-cugraph", "short_summary": "GPU-accelerated backend.", # "description": "TODO", "functions": { @@ -179,7 +180,7 @@ "ego_graph": "Weighted ego_graph with negative cycles is not yet supported. `NotImplementedError` will be raised if there are negative `distance` edge weights.", "eigenvector_centrality": "`nstart` parameter is not used, but it is checked for validity.", "from_pandas_edgelist": "cudf.DataFrame inputs also supported; value columns with str is unsuppported.", - "generic_bfs_edges": "`neighbors` and `sort_neighbors` parameters are not yet supported.", + "generic_bfs_edges": "`neighbors` parameter is not yet supported.", "katz_centrality": "`nstart` isn't used (but is checked), and `normalized=False` is not supported.", "louvain_communities": "`seed` parameter is currently ignored, and self-loops are not yet supported.", "pagerank": "`dangling` parameter is not supported, but it is checked for validity.", @@ -293,12 +294,59 @@ def get_info(): for key in info_keys: del d[key] + + d["default_config"] = { + "use_compat_graphs": os.environ.get("NX_CUGRAPH_USE_COMPAT_GRAPHS", "true") + .strip() + .lower() + == "true", + } + + # Enable zero-code change usage with a simple environment variable + # by setting or updating other NETWORKX environment variables. + if os.environ.get("NX_CUGRAPH_AUTOCONFIG", "").strip().lower() == "true": + from itertools import chain + + def update_env_var(varname): + """Add "cugraph" to a list of backend names environment variable.""" + if varname not in os.environ: + os.environ[varname] = "cugraph" + return + string = os.environ[varname] + vals = [ + stripped for x in string.strip().split(",") if (stripped := x.strip()) + ] + if "cugraph" not in vals: + # Should we append or prepend? Let's be first! + os.environ[varname] = ",".join(chain(["cugraph"], vals)) + + # Automatically convert NetworkX Graphs to nx-cugraph for algorithms + if (varname := "NETWORKX_BACKEND_PRIORITY_ALGOS") in os.environ: + # "*_ALGOS" is given priority in NetworkX >=3.4 + update_env_var(varname) + # But update this too to "just work" if users mix env vars and nx versions + os.environ["NETWORKX_BACKEND_PRIORITY"] = os.environ[varname] + else: + update_env_var("NETWORKX_BACKEND_PRIORITY") + # And for older NetworkX versions + update_env_var("NETWORKX_AUTOMATIC_BACKENDS") # For NetworkX 3.2 + update_env_var("NETWORKX_GRAPH_CONVERT") # For NetworkX 3.0 and 3.1 + # Automatically create nx-cugraph Graph from graph generators + update_env_var("NETWORKX_BACKEND_PRIORITY_GENERATORS") + # Run default NetworkX implementation (in >=3.4) if not implemented by nx-cugraph + if (varname := "NETWORKX_FALLBACK_TO_NX") not in os.environ: + os.environ[varname] = "true" + # Cache graph conversions (default is False in NetworkX 3.2 + if (varname := "NETWORKX_CACHE_CONVERTED_GRAPHS") not in os.environ: + os.environ[varname] = "true" + return d -def _check_networkx_version(): - import warnings +def _check_networkx_version() -> tuple[int, int]: + """Check the version of networkx and return ``(major, minor)`` version tuple.""" import re + import warnings import networkx as nx @@ -321,6 +369,10 @@ def _check_networkx_version(): f"{nx.__version__}. Please upgrade (or fix) your Python environment." ) + nxver_major = int(version_major) + nxver_minor = int(re.match(r"^\d+", version_minor).group()) + return (nxver_major, nxver_minor) + if __name__ == "__main__": from pathlib import Path diff --git a/python/nx-cugraph/lint.yaml b/python/nx-cugraph/lint.yaml index b2184a185c4..dab2ea70ef1 100644 --- a/python/nx-cugraph/lint.yaml +++ b/python/nx-cugraph/lint.yaml @@ -26,7 +26,7 @@ repos: - id: mixed-line-ending - id: trailing-whitespace - repo: https://github.com/abravalheri/validate-pyproject - rev: v0.18 + rev: v0.19 hooks: - id: validate-pyproject name: Validate pyproject.toml @@ -40,29 +40,29 @@ repos: hooks: - id: isort - repo: https://github.com/asottile/pyupgrade - rev: v3.16.0 + rev: v3.17.0 hooks: - id: pyupgrade args: [--py310-plus] - repo: https://github.com/psf/black - rev: 24.4.2 + rev: 24.8.0 hooks: - id: black # - id: black-jupyter - repo: https://github.com/astral-sh/ruff-pre-commit - rev: v0.5.4 + rev: v0.6.7 hooks: - id: ruff args: [--fix-only, --show-fixes] # --unsafe-fixes] - repo: https://github.com/PyCQA/flake8 - rev: 7.1.0 + rev: 7.1.1 hooks: - id: flake8 args: ['--per-file-ignores=_nx_cugraph/__init__.py:E501', '--extend-ignore=B020,SIM105'] # Why is this necessary? additional_dependencies: &flake8_dependencies # These versions need updated manually - - flake8==7.1.0 - - flake8-bugbear==24.4.26 + - flake8==7.1.1 + - flake8-bugbear==24.8.19 - flake8-simplify==0.21.0 - repo: https://github.com/asottile/yesqa rev: v1.5.0 @@ -77,7 +77,7 @@ repos: additional_dependencies: [tomli] files: ^(nx_cugraph|docs)/ - repo: https://github.com/astral-sh/ruff-pre-commit - rev: v0.5.4 + rev: v0.6.7 hooks: - id: ruff - repo: https://github.com/pre-commit/pre-commit-hooks diff --git a/python/nx-cugraph/nx_cugraph/__init__.py b/python/nx-cugraph/nx_cugraph/__init__.py index 542256fa781..4404e57f645 100644 --- a/python/nx-cugraph/nx_cugraph/__init__.py +++ b/python/nx-cugraph/nx_cugraph/__init__.py @@ -12,6 +12,11 @@ # limitations under the License. from networkx.exception import * +from _nx_cugraph._version import __git_commit__, __version__ +from _nx_cugraph import _check_networkx_version + +_nxver: tuple[int, int] = _check_networkx_version() + from . import utils from . import classes @@ -32,7 +37,10 @@ from . import algorithms from .algorithms import * -from _nx_cugraph._version import __git_commit__, __version__ -from _nx_cugraph import _check_networkx_version +from .interface import BackendInterface -_check_networkx_version() +BackendInterface.Graph = classes.Graph +BackendInterface.DiGraph = classes.DiGraph +BackendInterface.MultiGraph = classes.MultiGraph +BackendInterface.MultiDiGraph = classes.MultiDiGraph +del BackendInterface diff --git a/python/nx-cugraph/nx_cugraph/algorithms/bipartite/generators.py b/python/nx-cugraph/nx_cugraph/algorithms/bipartite/generators.py index 60276b7d41b..214970235c6 100644 --- a/python/nx-cugraph/nx_cugraph/algorithms/bipartite/generators.py +++ b/python/nx-cugraph/nx_cugraph/algorithms/bipartite/generators.py @@ -16,6 +16,7 @@ import networkx as nx import numpy as np +from nx_cugraph import _nxver from nx_cugraph.generators._utils import _create_using_class, _number_and_nodes from nx_cugraph.utils import index_dtype, networkx_algorithm @@ -48,7 +49,7 @@ def complete_bipartite_graph(n1, n2, create_using=None): nodes.extend(range(n2) if nodes2 is None else nodes2) if len(set(nodes)) != len(nodes): raise nx.NetworkXError("Inputs n1 and n2 must contain distinct nodes") - if nx.__version__[:3] <= "3.3": + if _nxver <= (3, 3): name = f"complete_bipartite_graph({orig_n1}, {orig_n2})" else: name = f"complete_bipartite_graph({n1}, {n2})" diff --git a/python/nx-cugraph/nx_cugraph/algorithms/community/louvain.py b/python/nx-cugraph/nx_cugraph/algorithms/community/louvain.py index ea1318060e0..52c512c454d 100644 --- a/python/nx-cugraph/nx_cugraph/algorithms/community/louvain.py +++ b/python/nx-cugraph/nx_cugraph/algorithms/community/louvain.py @@ -12,9 +12,9 @@ # limitations under the License. import warnings -import networkx as nx import pylibcugraph as plc +from nx_cugraph import _nxver from nx_cugraph.convert import _to_undirected_graph from nx_cugraph.utils import ( _dtype_param, @@ -27,7 +27,7 @@ __all__ = ["louvain_communities"] # max_level argument was added to NetworkX 3.3 -if nx.__version__[:3] <= "3.2": +if _nxver <= (3, 2): _max_level_param = { "max_level : int, optional": ( "Upper limit of the number of macro-iterations (max: 500)." @@ -81,7 +81,7 @@ def _louvain_communities( node_ids, clusters, modularity = plc.louvain( resource_handle=plc.ResourceHandle(), graph=G._get_plc_graph(weight, 1, dtype), - max_level=max_level, # TODO: add this parameter to NetworkX + max_level=max_level, threshold=threshold, resolution=resolution, do_expensive_check=False, diff --git a/python/nx-cugraph/nx_cugraph/algorithms/core.py b/python/nx-cugraph/nx_cugraph/algorithms/core.py index 8eb9a9946e7..e69ee88a17c 100644 --- a/python/nx-cugraph/nx_cugraph/algorithms/core.py +++ b/python/nx-cugraph/nx_cugraph/algorithms/core.py @@ -15,6 +15,7 @@ import pylibcugraph as plc import nx_cugraph as nxcg +from nx_cugraph import _nxver from nx_cugraph.convert import _to_undirected_graph from nx_cugraph.utils import ( _get_int_dtype, @@ -58,9 +59,12 @@ def _(G): @networkx_algorithm(is_incomplete=True, version_added="23.12", _plc="k_truss_subgraph") def k_truss(G, k): if is_nx := isinstance(G, nx.Graph): + is_compat_graph = isinstance(G, nxcg.Graph) G = nxcg.from_networkx(G, preserve_all_attrs=True) + else: + is_compat_graph = False if nxcg.number_of_selfloops(G) > 0: - if nx.__version__[:3] <= "3.2": + if _nxver <= (3, 2): exc_class = nx.NetworkXError else: exc_class = nx.NetworkXNotImplemented @@ -128,6 +132,7 @@ def k_truss(G, k): node_values, node_masks, key_to_id=key_to_id, + use_compat_graph=is_compat_graph, ) new_graph.graph.update(G.graph) return new_graph diff --git a/python/nx-cugraph/nx_cugraph/algorithms/link_analysis/hits_alg.py b/python/nx-cugraph/nx_cugraph/algorithms/link_analysis/hits_alg.py index e529b83ab1a..cc59fd5eb64 100644 --- a/python/nx-cugraph/nx_cugraph/algorithms/link_analysis/hits_alg.py +++ b/python/nx-cugraph/nx_cugraph/algorithms/link_analysis/hits_alg.py @@ -15,6 +15,7 @@ import numpy as np import pylibcugraph as plc +from nx_cugraph import _nxver from nx_cugraph.convert import _to_graph from nx_cugraph.utils import ( _dtype_param, @@ -53,7 +54,7 @@ def hits( if nstart is not None: nstart = G._dict_to_nodearray(nstart, 0, dtype) if max_iter <= 0: - if nx.__version__[:3] <= "3.2": + if _nxver <= (3, 2): raise ValueError("`maxiter` must be a positive integer.") raise nx.PowerIterationFailedConvergence(max_iter) try: diff --git a/python/nx-cugraph/nx_cugraph/algorithms/operators/unary.py b/python/nx-cugraph/nx_cugraph/algorithms/operators/unary.py index f53b3458949..75dc5fbc706 100644 --- a/python/nx-cugraph/nx_cugraph/algorithms/operators/unary.py +++ b/python/nx-cugraph/nx_cugraph/algorithms/operators/unary.py @@ -23,6 +23,7 @@ @networkx_algorithm(version_added="24.02") def complement(G): + is_compat_graph = isinstance(G, nxcg.Graph) G = _to_graph(G) N = G._N # Upcast to int64 so indices don't overflow. @@ -43,6 +44,7 @@ def complement(G): src_indices.astype(index_dtype), dst_indices.astype(index_dtype), key_to_id=G.key_to_id, + use_compat_graph=is_compat_graph, ) @@ -51,10 +53,16 @@ def reverse(G, copy=True): if not G.is_directed(): raise nx.NetworkXError("Cannot reverse an undirected graph.") if isinstance(G, nx.Graph): - if not copy: + is_compat_graph = isinstance(G, nxcg.Graph) + if not copy and not is_compat_graph: raise RuntimeError( "Using `copy=False` is invalid when using a NetworkX graph " "as input to `nx_cugraph.reverse`" ) G = nxcg.from_networkx(G, preserve_all_attrs=True) - return G.reverse(copy=copy) + else: + is_compat_graph = False + rv = G.reverse(copy=copy) + if is_compat_graph: + return rv._to_compat_graph() + return rv diff --git a/python/nx-cugraph/nx_cugraph/algorithms/shortest_paths/generic.py b/python/nx-cugraph/nx_cugraph/algorithms/shortest_paths/generic.py index 7d6d77f34a4..ab3c7214303 100644 --- a/python/nx-cugraph/nx_cugraph/algorithms/shortest_paths/generic.py +++ b/python/nx-cugraph/nx_cugraph/algorithms/shortest_paths/generic.py @@ -14,6 +14,7 @@ import numpy as np import nx_cugraph as nxcg +from nx_cugraph import _nxver from nx_cugraph.convert import _to_graph from nx_cugraph.utils import _dtype_param, _get_float_dtype, networkx_algorithm @@ -57,7 +58,7 @@ def shortest_path( paths = nxcg.all_pairs_dijkstra_path(G, weight=weight, dtype=dtype) else: # method == 'bellman-ford': paths = nxcg.all_pairs_bellman_ford_path(G, weight=weight, dtype=dtype) - if nx.__version__[:3] <= "3.4": + if _nxver <= (3, 4): paths = dict(paths) # To target elif method == "unweighted": @@ -129,7 +130,7 @@ def shortest_path_length( # To target elif method == "unweighted": lengths = nxcg.single_target_shortest_path_length(G, target) - if nx.__version__[:3] <= "3.4": + if _nxver <= (3, 4): lengths = dict(lengths) elif method == "dijkstra": lengths = nxcg.single_source_dijkstra_path_length( diff --git a/python/nx-cugraph/nx_cugraph/algorithms/shortest_paths/unweighted.py b/python/nx-cugraph/nx_cugraph/algorithms/shortest_paths/unweighted.py index 0e98c366e4a..e9c515632ca 100644 --- a/python/nx-cugraph/nx_cugraph/algorithms/shortest_paths/unweighted.py +++ b/python/nx-cugraph/nx_cugraph/algorithms/shortest_paths/unweighted.py @@ -17,6 +17,7 @@ import numpy as np import pylibcugraph as plc +from nx_cugraph import _nxver from nx_cugraph.convert import _to_graph from nx_cugraph.utils import _groupby, index_dtype, networkx_algorithm @@ -43,7 +44,7 @@ def single_source_shortest_path_length(G, source, cutoff=None): def single_target_shortest_path_length(G, target, cutoff=None): G = _to_graph(G) rv = _bfs(G, target, cutoff, "Target", return_type="length") - if nx.__version__[:3] <= "3.4": + if _nxver <= (3, 4): return iter(rv.items()) return rv @@ -61,7 +62,7 @@ def bidirectional_shortest_path(G, source, target): # TODO PERF: do bidirectional traversal in core G = _to_graph(G) if source not in G or target not in G: - if nx.__version__[:3] <= "3.3": + if _nxver <= (3, 3): raise nx.NodeNotFound( f"Either source {source} or target {target} is not in G" ) diff --git a/python/nx-cugraph/nx_cugraph/algorithms/traversal/breadth_first_search.py b/python/nx-cugraph/nx_cugraph/algorithms/traversal/breadth_first_search.py index 5e4466d7d33..72d0079cf0c 100644 --- a/python/nx-cugraph/nx_cugraph/algorithms/traversal/breadth_first_search.py +++ b/python/nx-cugraph/nx_cugraph/algorithms/traversal/breadth_first_search.py @@ -18,6 +18,7 @@ import pylibcugraph as plc import nx_cugraph as nxcg +from nx_cugraph import _nxver from nx_cugraph.convert import _to_graph from nx_cugraph.utils import _groupby, index_dtype, networkx_algorithm @@ -57,7 +58,7 @@ def _bfs(G, source, *, depth_limit=None, reverse=False): return distances[mask], predecessors[mask], node_ids[mask] -if nx.__version__[:3] <= "3.3": +if _nxver <= (3, 3): @networkx_algorithm(is_incomplete=True, version_added="24.02", _plc="bfs") def generic_bfs_edges( @@ -132,13 +133,15 @@ def bfs_tree(G, source, reverse=False, depth_limit=None, sort_neighbors=None): raise NotImplementedError( "sort_neighbors argument in bfs_tree is not currently supported" ) + is_compat_graph = isinstance(G, nxcg.Graph) G = _check_G_and_source(G, source) if depth_limit is not None and depth_limit < 1: - return nxcg.DiGraph.from_coo( + return nxcg.CudaDiGraph.from_coo( 1, cp.array([], dtype=index_dtype), cp.array([], dtype=index_dtype), id_to_key=[source], + use_compat_graph=is_compat_graph, ) distances, predecessors, node_ids = _bfs( @@ -148,11 +151,12 @@ def bfs_tree(G, source, reverse=False, depth_limit=None, sort_neighbors=None): reverse=reverse, ) if predecessors.size == 0: - return nxcg.DiGraph.from_coo( + return nxcg.CudaDiGraph.from_coo( 1, cp.array([], dtype=index_dtype), cp.array([], dtype=index_dtype), id_to_key=[source], + use_compat_graph=is_compat_graph, ) # TODO: create renumbering helper function(s) unique_node_ids = cp.unique(cp.hstack((predecessors, node_ids))) @@ -170,11 +174,12 @@ def bfs_tree(G, source, reverse=False, depth_limit=None, sort_neighbors=None): old_index: new_index for new_index, old_index in enumerate(unique_node_ids.tolist()) } - return nxcg.DiGraph.from_coo( + return nxcg.CudaDiGraph.from_coo( unique_node_ids.size, src_indices, dst_indices, key_to_id=key_to_id, + use_compat_graph=is_compat_graph, ) diff --git a/python/nx-cugraph/nx_cugraph/classes/__init__.py b/python/nx-cugraph/nx_cugraph/classes/__init__.py index 19a5357da55..71168e5364f 100644 --- a/python/nx-cugraph/nx_cugraph/classes/__init__.py +++ b/python/nx-cugraph/nx_cugraph/classes/__init__.py @@ -1,4 +1,4 @@ -# Copyright (c) 2023, NVIDIA CORPORATION. +# 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 @@ -10,9 +10,9 @@ # 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. -from .graph import Graph -from .digraph import DiGraph -from .multigraph import MultiGraph -from .multidigraph import MultiDiGraph +from .graph import CudaGraph, Graph +from .digraph import CudaDiGraph, DiGraph +from .multigraph import CudaMultiGraph, MultiGraph +from .multidigraph import CudaMultiDiGraph, MultiDiGraph from .function import * diff --git a/python/nx-cugraph/nx_cugraph/classes/digraph.py b/python/nx-cugraph/nx_cugraph/classes/digraph.py index e5cfb8f6815..178bf44f16e 100644 --- a/python/nx-cugraph/nx_cugraph/classes/digraph.py +++ b/python/nx-cugraph/nx_cugraph/classes/digraph.py @@ -18,34 +18,108 @@ import cupy as cp import networkx as nx import numpy as np +from networkx.classes.digraph import ( + _CachedPropertyResetterAdjAndSucc, + _CachedPropertyResetterPred, +) import nx_cugraph as nxcg from ..utils import index_dtype -from .graph import Graph +from .graph import CudaGraph, Graph if TYPE_CHECKING: # pragma: no cover from nx_cugraph.typing import AttrKey -__all__ = ["DiGraph"] +__all__ = ["CudaDiGraph", "DiGraph"] networkx_api = nxcg.utils.decorators.networkx_class(nx.DiGraph) -class DiGraph(Graph): - ################# - # Class methods # - ################# +class DiGraph(nx.DiGraph, Graph): + _nx_attrs = ("_node", "_adj", "_succ", "_pred") + + name = Graph.name + _node = Graph._node + + @property + @networkx_api + def _adj(self): + if (adj := self.__dict__["_adj"]) is None: + self._reify_networkx() + adj = self.__dict__["_adj"] + return adj + + @_adj.setter + def _adj(self, val): + self._prepare_setter() + _CachedPropertyResetterAdjAndSucc.__set__(None, self, val) + if cache := getattr(self, "__networkx_cache__", None): + cache.clear() + + @property + @networkx_api + def _succ(self): + if (succ := self.__dict__["_succ"]) is None: + self._reify_networkx() + succ = self.__dict__["_succ"] + return succ + + @_succ.setter + def _succ(self, val): + self._prepare_setter() + _CachedPropertyResetterAdjAndSucc.__set__(None, self, val) + if cache := getattr(self, "__networkx_cache__", None): + cache.clear() + + @property + @networkx_api + def _pred(self): + if (pred := self.__dict__["_pred"]) is None: + self._reify_networkx() + pred = self.__dict__["_pred"] + return pred + + @_pred.setter + def _pred(self, val): + self._prepare_setter() + _CachedPropertyResetterPred.__set__(None, self, val) + if cache := getattr(self, "__networkx_cache__", None): + cache.clear() @classmethod @networkx_api def is_directed(cls) -> bool: return True + @classmethod + @networkx_api + def is_multigraph(cls) -> bool: + return False + + @classmethod + def to_cudagraph_class(cls) -> type[CudaDiGraph]: + return CudaDiGraph + @classmethod def to_networkx_class(cls) -> type[nx.DiGraph]: return nx.DiGraph + +class CudaDiGraph(CudaGraph): + ################# + # Class methods # + ################# + + is_directed = classmethod(DiGraph.is_directed.__func__) + is_multigraph = classmethod(DiGraph.is_multigraph.__func__) + to_cudagraph_class = classmethod(DiGraph.to_cudagraph_class.__func__) + to_networkx_class = classmethod(DiGraph.to_networkx_class.__func__) + + @classmethod + def _to_compat_graph_class(cls) -> type[DiGraph]: + return DiGraph + @networkx_api def size(self, weight: AttrKey | None = None) -> int: if weight is not None: @@ -57,7 +131,7 @@ def size(self, weight: AttrKey | None = None) -> int: ########################## @networkx_api - def reverse(self, copy: bool = True) -> DiGraph: + def reverse(self, copy: bool = True) -> CudaDiGraph: return self._copy(not copy, self.__class__, reverse=True) @networkx_api @@ -162,6 +236,7 @@ def to_undirected(self, reciprocal=False, as_view=False): node_masks, key_to_id=key_to_id, id_to_key=id_to_key, + use_compat_graph=False, ) if as_view: rv.graph = self.graph diff --git a/python/nx-cugraph/nx_cugraph/classes/graph.py b/python/nx-cugraph/nx_cugraph/classes/graph.py index 7425eacb2b4..cfe1e1c87e9 100644 --- a/python/nx-cugraph/nx_cugraph/classes/graph.py +++ b/python/nx-cugraph/nx_cugraph/classes/graph.py @@ -20,8 +20,13 @@ import networkx as nx import numpy as np import pylibcugraph as plc +from networkx.classes.graph import ( + _CachedPropertyResetterAdj, + _CachedPropertyResetterNode, +) import nx_cugraph as nxcg +from nx_cugraph import _nxver from ..utils import index_dtype @@ -40,57 +45,246 @@ any_ndarray, ) -__all__ = ["Graph"] +__all__ = ["CudaGraph", "Graph"] networkx_api = nxcg.utils.decorators.networkx_class(nx.Graph) +# The "everything" cache key is an internal implementation detail of NetworkX +# that may change between releases. +if _nxver < (3, 4): + _CACHE_KEY = ( + True, # Include all edge values + True, # Include all node values + True, # Include `.graph` attributes + ) +else: + _CACHE_KEY = ( + True, # Include all edge values + True, # Include all node values + # `.graph` attributes are always included now + ) + +# Use to indicate when a full conversion to GPU failed so we don't try again. +_CANT_CONVERT_TO_GPU = "_CANT_CONVERT_TO_GPU" + + +# `collections.UserDict` was the preferred way to subclass dict, but now +# subclassing dict directly is much better supported and should work here. +# This class should only be necessary if the user clears the cache manually. +class _GraphCache(dict): + """Cache that ensures Graph will reify into a NetworkX graph when cleared.""" + + _graph: Graph -class Graph: + def __init__(self, graph: Graph): + self._graph = graph + + def clear(self) -> None: + self._graph._reify_networkx() + super().clear() + + +class Graph(nx.Graph): # Tell networkx to dispatch calls with this object to nx-cugraph __networkx_backend__: ClassVar[str] = "cugraph" # nx >=3.2 __networkx_plugin__: ClassVar[str] = "cugraph" # nx <3.2 + # Core attributes of NetowkrX graphs that will be copied and cleared as appropriate. + # These attributes comprise the edge and node data model for NetworkX graphs. + _nx_attrs = ("_node", "_adj") + # Allow networkx dispatch machinery to cache conversions. # This means we should clear the cache if we ever mutate the object! - __networkx_cache__: dict | None + __networkx_cache__: _GraphCache | None # networkx properties graph: dict - graph_attr_dict_factory: ClassVar[type] = dict + # Should we declare type annotations for the rest? + + # Properties that trigger copying to the CPU + def _prepare_setter(self): + """Be careful when setting private attributes which may be used during init.""" + if ( + # If not present, then this must be in init + any(attr not in self.__dict__ for attr in self._nx_attrs) + # Already on the CPU + or not any(self.__dict__[attr] is None for attr in self._nx_attrs) + ): + return + if self._is_on_gpu: + # Copy from GPU to CPU + self._reify_networkx() + return + # Default values + for attr in self._nx_attrs: + if self.__dict__[attr] is None: + if attr == "_succ": + self.__dict__[attr] = self.__dict__["_adj"] + else: + self.__dict__[attr] = {} - # Not networkx properties - # We store edge data in COO format with {src,dst}_indices and edge_values. - src_indices: cp.ndarray[IndexValue] - dst_indices: cp.ndarray[IndexValue] - edge_values: dict[AttrKey, cp.ndarray[EdgeValue]] - edge_masks: dict[AttrKey, cp.ndarray[bool]] - node_values: dict[AttrKey, any_ndarray[NodeValue]] - node_masks: dict[AttrKey, any_ndarray[bool]] - key_to_id: dict[NodeKey, IndexValue] | None - _id_to_key: list[NodeKey] | None - _N: int - _node_ids: cp.ndarray[IndexValue] | None # holds plc.SGGraph.vertices_array data + @property + @networkx_api + def _node(self): + if (node := self.__dict__["_node"]) is None: + self._reify_networkx() + node = self.__dict__["_node"] + return node + + @_node.setter + def _node(self, val): + self._prepare_setter() + _CachedPropertyResetterNode.__set__(None, self, val) + if cache := getattr(self, "__networkx_cache__", None): + cache.clear() - # Used by graph._get_plc_graph - _plc_type_map: ClassVar[dict[np.dtype, np.dtype]] = { - # signed int - np.dtype(np.int8): np.dtype(np.float32), - np.dtype(np.int16): np.dtype(np.float32), - np.dtype(np.int32): np.dtype(np.float64), - np.dtype(np.int64): np.dtype(np.float64), # raise if abs(x) > 2**53 - # unsigned int - np.dtype(np.uint8): np.dtype(np.float32), - np.dtype(np.uint16): np.dtype(np.float32), - np.dtype(np.uint32): np.dtype(np.float64), - np.dtype(np.uint64): np.dtype(np.float64), # raise if x > 2**53 - # other - np.dtype(np.bool_): np.dtype(np.float32), - np.dtype(np.float16): np.dtype(np.float32), - } - _plc_allowed_edge_types: ClassVar[set[np.dtype]] = { - np.dtype(np.float32), - np.dtype(np.float64), - } + @property + @networkx_api + def _adj(self): + if (adj := self.__dict__["_adj"]) is None: + self._reify_networkx() + adj = self.__dict__["_adj"] + return adj + + @_adj.setter + def _adj(self, val): + self._prepare_setter() + _CachedPropertyResetterAdj.__set__(None, self, val) + if cache := getattr(self, "__networkx_cache__", None): + cache.clear() + + @property + def _is_on_gpu(self) -> bool: + """Whether the full graph is on device (in the cache). + + This returns False when only a subset of the graph (such as only + edge indices and edge attribute) is on device. + + The graph may be on host (CPU) and device (GPU) at the same time. + """ + cache = getattr(self, "__networkx_cache__", None) + if not cache: + return False + return _CACHE_KEY in cache.get("backends", {}).get("cugraph", {}) + + @property + def _is_on_cpu(self) -> bool: + """Whether the graph is on host as a NetworkX graph. + + This means the core data structures that comprise a NetworkX graph + (such as ``G._node`` and ``G._adj``) are present. + + The graph may be on host (CPU) and device (GPU) at the same time. + """ + return self.__dict__["_node"] is not None + + @property + def _cudagraph(self): + """Return the full ``CudaGraph`` on device, computing if necessary, or None.""" + nx_cache = getattr(self, "__networkx_cache__", None) + if nx_cache is None: + nx_cache = {} + elif _CANT_CONVERT_TO_GPU in nx_cache: + return None + cache = nx_cache.setdefault("backends", {}).setdefault("cugraph", {}) + if (Gcg := cache.get(_CACHE_KEY)) is not None: + if isinstance(Gcg, Graph): + # This shouldn't happen during normal use, but be extra-careful anyway + return Gcg._cudagraph + return Gcg + if self.__dict__["_node"] is None: + raise RuntimeError( + f"{type(self).__name__} cannot be converted to the GPU, because it is " + "not on the CPU! This is not supposed to be possible. If you believe " + "you have found a bug, please report a minimum reproducible example to " + "https://github.com/rapidsai/cugraph/issues/new/choose" + ) + try: + Gcg = nxcg.from_networkx( + self, preserve_edge_attrs=True, preserve_node_attrs=True + ) + except Exception: + # Should we warn that the full graph can't be on GPU? + nx_cache[_CANT_CONVERT_TO_GPU] = True + return None + Gcg.graph = self.graph + cache[_CACHE_KEY] = Gcg + return Gcg + + @_cudagraph.setter + def _cudagraph(self, val, *, clear_cpu=True): + """Set the full ``CudaGraph`` for this graph, or remove from device if None.""" + if (cache := getattr(self, "__networkx_cache__", None)) is None: + # Should we warn? + return + # TODO: pay close attention to when we should clear the cache, since + # this may or may not be a mutation. + cache = cache.setdefault("backends", {}).setdefault("cugraph", {}) + if val is None: + cache.pop(_CACHE_KEY, None) + else: + self.graph = val.graph + cache[_CACHE_KEY] = val + if clear_cpu: + for key in self._nx_attrs: + self.__dict__[key] = None + + @nx.Graph.name.setter + def name(self, s): + # Don't clear the cache when setting the name, since `.graph` is shared. + # There is a very small risk here for the cache to become (slightly) + # insconsistent if graphs from other backends are cached. + self.graph["name"] = s + + @classmethod + @networkx_api + def is_directed(cls) -> bool: + return False + + @classmethod + @networkx_api + def is_multigraph(cls) -> bool: + return False + + @classmethod + def to_cudagraph_class(cls) -> type[CudaGraph]: + return CudaGraph + + @classmethod + @networkx_api + def to_directed_class(cls) -> type[nxcg.DiGraph]: + return nxcg.DiGraph + + @classmethod + def to_networkx_class(cls) -> type[nx.Graph]: + return nx.Graph + + @classmethod + @networkx_api + def to_undirected_class(cls) -> type[Graph]: + return Graph + + def __init__(self, incoming_graph_data=None, **attr): + super().__init__(incoming_graph_data, **attr) + self.__networkx_cache__ = _GraphCache(self) + + def _reify_networkx(self) -> None: + """Copy graph to host (CPU) if necessary.""" + if self.__dict__["_node"] is None: + # After we make this into an nx graph, we rely on the cache being correct + Gcg = self._cudagraph + G = nxcg.to_networkx(Gcg) + for key in self._nx_attrs: + self.__dict__[key] = G.__dict__[key] + + def _become(self, other: Graph): + if self.__class__ is not other.__class__: + raise TypeError( + "Attempting to update graph inplace with graph of different type!" + ) + # Begin with the simplest implementation; do we need to do more? + self.__dict__.update(other.__dict__) + return self #################### # Creation methods # @@ -109,9 +303,10 @@ def from_coo( *, key_to_id: dict[NodeKey, IndexValue] | None = None, id_to_key: list[NodeKey] | None = None, + use_compat_graph: bool | None = None, **attr, - ) -> Graph: - new_graph = object.__new__(cls) + ) -> Graph | CudaGraph: + new_graph = object.__new__(cls.to_cudagraph_class()) new_graph.__networkx_cache__ = {} new_graph.src_indices = src_indices new_graph.dst_indices = dst_indices @@ -173,7 +368,8 @@ def from_coo( isolates = nxcg.algorithms.isolate._isolates(new_graph) if len(isolates) > 0: new_graph._node_ids = cp.arange(new_graph._N, dtype=index_dtype) - + if use_compat_graph or use_compat_graph is None and issubclass(cls, Graph): + new_graph = new_graph._to_compat_graph() return new_graph @classmethod @@ -188,8 +384,9 @@ def from_csr( *, key_to_id: dict[NodeKey, IndexValue] | None = None, id_to_key: list[NodeKey] | None = None, + use_compat_graph: bool | None = None, **attr, - ) -> Graph: + ) -> Graph | CudaGraph: N = indptr.size - 1 src_indices = cp.array( # cp.repeat is slow to use here, so use numpy instead @@ -205,6 +402,7 @@ def from_csr( node_masks, key_to_id=key_to_id, id_to_key=id_to_key, + use_compat_graph=use_compat_graph, **attr, ) @@ -220,8 +418,9 @@ def from_csc( *, key_to_id: dict[NodeKey, IndexValue] | None = None, id_to_key: list[NodeKey] | None = None, + use_compat_graph: bool | None = None, **attr, - ) -> Graph: + ) -> Graph | CudaGraph: N = indptr.size - 1 dst_indices = cp.array( # cp.repeat is slow to use here, so use numpy instead @@ -237,6 +436,7 @@ def from_csc( node_masks, key_to_id=key_to_id, id_to_key=id_to_key, + use_compat_graph=use_compat_graph, **attr, ) @@ -254,8 +454,9 @@ def from_dcsr( *, key_to_id: dict[NodeKey, IndexValue] | None = None, id_to_key: list[NodeKey] | None = None, + use_compat_graph: bool | None = None, **attr, - ) -> Graph: + ) -> Graph | CudaGraph: src_indices = cp.array( # cp.repeat is slow to use here, so use numpy instead np.repeat(compressed_srcs.get(), cp.diff(indptr).get()) @@ -270,6 +471,7 @@ def from_dcsr( node_masks, key_to_id=key_to_id, id_to_key=id_to_key, + use_compat_graph=use_compat_graph, **attr, ) @@ -287,8 +489,9 @@ def from_dcsc( *, key_to_id: dict[NodeKey, IndexValue] | None = None, id_to_key: list[NodeKey] | None = None, + use_compat_graph: bool | None = None, **attr, - ) -> Graph: + ) -> Graph | CudaGraph: dst_indices = cp.array( # cp.repeat is slow to use here, so use numpy instead np.repeat(compressed_dsts.get(), cp.diff(indptr).get()) @@ -303,13 +506,75 @@ def from_dcsc( node_masks, key_to_id=key_to_id, id_to_key=id_to_key, + use_compat_graph=use_compat_graph, **attr, ) - def __new__(cls, incoming_graph_data=None, **attr) -> Graph: + +class CudaGraph: + # Tell networkx to dispatch calls with this object to nx-cugraph + __networkx_backend__: ClassVar[str] = "cugraph" # nx >=3.2 + __networkx_plugin__: ClassVar[str] = "cugraph" # nx <3.2 + + # Allow networkx dispatch machinery to cache conversions. + # This means we should clear the cache if we ever mutate the object! + __networkx_cache__: dict | None + + # networkx properties + graph: dict + graph_attr_dict_factory: ClassVar[type] = dict + + # Not networkx properties + # We store edge data in COO format with {src,dst}_indices and edge_values. + src_indices: cp.ndarray[IndexValue] + dst_indices: cp.ndarray[IndexValue] + edge_values: dict[AttrKey, cp.ndarray[EdgeValue]] + edge_masks: dict[AttrKey, cp.ndarray[bool]] + node_values: dict[AttrKey, any_ndarray[NodeValue]] + node_masks: dict[AttrKey, any_ndarray[bool]] + key_to_id: dict[NodeKey, IndexValue] | None + _id_to_key: list[NodeKey] | None + _N: int + _node_ids: cp.ndarray[IndexValue] | None # holds plc.SGGraph.vertices_array data + + # Used by graph._get_plc_graph + _plc_type_map: ClassVar[dict[np.dtype, np.dtype]] = { + # signed int + np.dtype(np.int8): np.dtype(np.float32), + np.dtype(np.int16): np.dtype(np.float32), + np.dtype(np.int32): np.dtype(np.float64), + np.dtype(np.int64): np.dtype(np.float64), # raise if abs(x) > 2**53 + # unsigned int + np.dtype(np.uint8): np.dtype(np.float32), + np.dtype(np.uint16): np.dtype(np.float32), + np.dtype(np.uint32): np.dtype(np.float64), + np.dtype(np.uint64): np.dtype(np.float64), # raise if x > 2**53 + # other + np.dtype(np.bool_): np.dtype(np.float32), + np.dtype(np.float16): np.dtype(np.float32), + } + _plc_allowed_edge_types: ClassVar[set[np.dtype]] = { + np.dtype(np.float32), + np.dtype(np.float64), + } + + #################### + # Creation methods # + #################### + + from_coo = classmethod(Graph.from_coo.__func__) + from_csr = classmethod(Graph.from_csr.__func__) + from_csc = classmethod(Graph.from_csc.__func__) + from_dcsr = classmethod(Graph.from_dcsr.__func__) + from_dcsc = classmethod(Graph.from_dcsc.__func__) + + def __new__(cls, incoming_graph_data=None, **attr) -> CudaGraph: if incoming_graph_data is None: new_graph = cls.from_coo( - 0, cp.empty(0, index_dtype), cp.empty(0, index_dtype) + 0, + cp.empty(0, index_dtype), + cp.empty(0, index_dtype), + use_compat_graph=False, ) elif incoming_graph_data.__class__ is cls: new_graph = incoming_graph_data.copy() @@ -318,34 +583,30 @@ def __new__(cls, incoming_graph_data=None, **attr) -> Graph: else: raise NotImplementedError new_graph.graph.update(attr) + # We could return Graph here (if configured), but let's not for now return new_graph ################# # Class methods # ################# - @classmethod - @networkx_api - def is_directed(cls) -> bool: - return False + is_directed = classmethod(Graph.is_directed.__func__) + is_multigraph = classmethod(Graph.is_multigraph.__func__) + to_cudagraph_class = classmethod(Graph.to_cudagraph_class.__func__) + to_networkx_class = classmethod(Graph.to_networkx_class.__func__) @classmethod @networkx_api - def is_multigraph(cls) -> bool: - return False + def to_directed_class(cls) -> type[nxcg.CudaDiGraph]: + return nxcg.CudaDiGraph @classmethod @networkx_api - def to_directed_class(cls) -> type[nxcg.DiGraph]: - return nxcg.DiGraph - - @classmethod - def to_networkx_class(cls) -> type[nx.Graph]: - return nx.Graph + def to_undirected_class(cls) -> type[CudaGraph]: + return CudaGraph @classmethod - @networkx_api - def to_undirected_class(cls) -> type[Graph]: + def _to_compat_graph_class(cls) -> type[Graph]: return Graph ############## @@ -438,7 +699,7 @@ def clear_edges(self) -> None: cache.clear() @networkx_api - def copy(self, as_view: bool = False) -> Graph: + def copy(self, as_view: bool = False) -> CudaGraph: # Does shallow copy in networkx return self._copy(as_view, self.__class__) @@ -534,14 +795,19 @@ def size(self, weight: AttrKey | None = None) -> int: return int(cp.count_nonzero(self.src_indices <= self.dst_indices)) @networkx_api - def to_directed(self, as_view: bool = False) -> nxcg.DiGraph: + def to_directed(self, as_view: bool = False) -> nxcg.CudaDiGraph: return self._copy(as_view, self.to_directed_class()) @networkx_api - def to_undirected(self, as_view: bool = False) -> Graph: + def to_undirected(self, as_view: bool = False) -> CudaGraph: # Does deep copy in networkx return self._copy(as_view, self.to_undirected_class()) + def _to_compat_graph(self) -> Graph: + rv = self._to_compat_graph_class()() + rv._cudagraph = self + return rv + # Not implemented... # adj, adjacency, add_edge, add_edges_from, add_node, # add_nodes_from, add_weighted_edges_from, degree, @@ -552,8 +818,8 @@ def to_undirected(self, as_view: bool = False) -> Graph: # Private methods # ################### - def _copy(self, as_view: bool, cls: type[Graph], reverse: bool = False): - # DRY warning: see also MultiGraph._copy + def _copy(self, as_view: bool, cls: type[CudaGraph], reverse: bool = False): + # DRY warning: see also CudaMultiGraph._copy src_indices = self.src_indices dst_indices = self.dst_indices edge_values = self.edge_values @@ -593,6 +859,7 @@ def _copy(self, as_view: bool, cls: type[Graph], reverse: bool = False): node_masks, key_to_id=key_to_id, id_to_key=id_to_key, + use_compat_graph=False, ) if as_view: rv.graph = self.graph @@ -689,6 +956,14 @@ def _get_plc_graph( src_indices = src_indices.astype(index_dtype) dst_indices = dst_indices.astype(index_dtype) + # This sets drop_multi_edges=True for non-multigraph input, which means + # the data in self.src_indices and self.dst_indices may not be + # identical to that contained in the returned pcl.SGGraph (the returned + # SGGraph may have fewer edges since duplicates are dropped). Ideally + # self.src_indices and self.dst_indices would be updated to have + # duplicate edges removed for non-multigraph instances, but that + # requires additional code which would be redundant and likely not as + # performant as the code in PLC. return plc.SGGraph( resource_handle=plc.ResourceHandle(), graph_properties=plc.GraphProperties( @@ -702,10 +977,11 @@ def _get_plc_graph( renumber=False, do_expensive_check=False, vertices_array=self._node_ids, + drop_multi_edges=not self.is_multigraph(), ) def _sort_edge_indices(self, primary="src"): - # DRY warning: see also MultiGraph._sort_edge_indices + # DRY warning: see also CudaMultiGraph._sort_edge_indices if primary == "src": stacked = cp.vstack((self.dst_indices, self.src_indices)) elif primary == "dst": @@ -727,7 +1003,7 @@ def _sort_edge_indices(self, primary="src"): {key: val[indices] for key, val in self.edge_masks.items()} ) - def _become(self, other: Graph): + def _become(self, other: CudaGraph): if self.__class__ is not other.__class__: raise TypeError( "Attempting to update graph inplace with graph of different type!" diff --git a/python/nx-cugraph/nx_cugraph/classes/multidigraph.py b/python/nx-cugraph/nx_cugraph/classes/multidigraph.py index 2e7a55a9eb1..5a6595567d2 100644 --- a/python/nx-cugraph/nx_cugraph/classes/multidigraph.py +++ b/python/nx-cugraph/nx_cugraph/classes/multidigraph.py @@ -16,24 +16,51 @@ import nx_cugraph as nxcg -from .digraph import DiGraph -from .multigraph import MultiGraph +from .digraph import CudaDiGraph, DiGraph +from .graph import Graph +from .multigraph import CudaMultiGraph, MultiGraph -__all__ = ["MultiDiGraph"] +__all__ = ["CudaMultiDiGraph", "MultiDiGraph"] networkx_api = nxcg.utils.decorators.networkx_class(nx.MultiDiGraph) -class MultiDiGraph(MultiGraph, DiGraph): +class MultiDiGraph(nx.MultiDiGraph, MultiGraph, DiGraph): + name = Graph.name + _node = Graph._node + _adj = DiGraph._adj + _succ = DiGraph._succ + _pred = DiGraph._pred + @classmethod @networkx_api def is_directed(cls) -> bool: return True + @classmethod + @networkx_api + def is_multigraph(cls) -> bool: + return True + + @classmethod + def to_cudagraph_class(cls) -> type[CudaMultiDiGraph]: + return CudaMultiDiGraph + @classmethod def to_networkx_class(cls) -> type[nx.MultiDiGraph]: return nx.MultiDiGraph + +class CudaMultiDiGraph(CudaMultiGraph, CudaDiGraph): + is_directed = classmethod(MultiDiGraph.is_directed.__func__) + is_multigraph = classmethod(MultiDiGraph.is_multigraph.__func__) + to_cudagraph_class = classmethod(MultiDiGraph.to_cudagraph_class.__func__) + to_networkx_class = classmethod(MultiDiGraph.to_networkx_class.__func__) + + @classmethod + def _to_compat_graph_class(cls) -> type[MultiDiGraph]: + return MultiDiGraph + ########################## # NetworkX graph methods # ########################## diff --git a/python/nx-cugraph/nx_cugraph/classes/multigraph.py b/python/nx-cugraph/nx_cugraph/classes/multigraph.py index 23d9faa8734..c8c8f1dfb00 100644 --- a/python/nx-cugraph/nx_cugraph/classes/multigraph.py +++ b/python/nx-cugraph/nx_cugraph/classes/multigraph.py @@ -22,7 +22,7 @@ import nx_cugraph as nxcg from ..utils import index_dtype -from .graph import Graph +from .graph import CudaGraph, Graph, _GraphCache if TYPE_CHECKING: from nx_cugraph.typing import ( @@ -34,32 +34,47 @@ NodeValue, any_ndarray, ) -__all__ = ["MultiGraph"] +__all__ = ["MultiGraph", "CudaMultiGraph"] networkx_api = nxcg.utils.decorators.networkx_class(nx.MultiGraph) -class MultiGraph(Graph): - # networkx properties - edge_key_dict_factory: ClassVar[type] = dict +class MultiGraph(nx.MultiGraph, Graph): + name = Graph.name + _node = Graph._node + _adj = Graph._adj - # Not networkx properties + @classmethod + @networkx_api + def is_directed(cls) -> bool: + return False - # In a MultiGraph, each edge has a unique `(src, dst, key)` key. - # By default, `key` is 0 if possible, else 1, else 2, etc. - # This key can be any hashable Python object in NetworkX. - # We don't use a dict for our data structure here, because - # that would require a `(src, dst, key)` key. - # Instead, we keep `edge_keys` and/or `edge_indices`. - # `edge_keys` is the list of Python objects for each edge. - # `edge_indices` is for the common case of default multiedge keys, - # in which case we can store it as a cupy array. - # `edge_indices` is generally preferred. It is possible to provide - # both where edge_indices is the default and edge_keys is anything. - # It is also possible for them both to be None, which means the - # default edge indices has not yet been calculated. - edge_indices: cp.ndarray[IndexValue] | None - edge_keys: list[EdgeKey] | None + @classmethod + @networkx_api + def is_multigraph(cls) -> bool: + return True + + @classmethod + def to_cudagraph_class(cls) -> type[CudaMultiGraph]: + return CudaMultiGraph + + @classmethod + @networkx_api + def to_directed_class(cls) -> type[nxcg.MultiDiGraph]: + return nxcg.MultiDiGraph + + @classmethod + def to_networkx_class(cls) -> type[nx.MultiGraph]: + return nx.MultiGraph + + @classmethod + @networkx_api + def to_undirected_class(cls) -> type[MultiGraph]: + return MultiGraph + + def __init__(self, incoming_graph_data=None, multigraph_input=None, **attr): + super().__init__(incoming_graph_data, multigraph_input, **attr) + self.__networkx_cache__ = _GraphCache(self) #################### # Creation methods # @@ -80,9 +95,10 @@ def from_coo( key_to_id: dict[NodeKey, IndexValue] | None = None, id_to_key: list[NodeKey] | None = None, edge_keys: list[EdgeKey] | None = None, + use_compat_graph: bool | None = None, **attr, - ) -> MultiGraph: - new_graph = super().from_coo( + ) -> MultiGraph | CudaMultiGraph: + new_graph = super(cls.to_undirected_class(), cls).from_coo( N, src_indices, dst_indices, @@ -92,6 +108,7 @@ def from_coo( node_masks, key_to_id=key_to_id, id_to_key=id_to_key, + use_compat_graph=False, **attr, ) new_graph.edge_indices = edge_indices @@ -102,6 +119,8 @@ def from_coo( and len(new_graph.edge_keys) != src_indices.size ): raise ValueError + if use_compat_graph or use_compat_graph is None and issubclass(cls, Graph): + new_graph = new_graph._to_compat_graph() return new_graph @classmethod @@ -118,8 +137,9 @@ def from_csr( key_to_id: dict[NodeKey, IndexValue] | None = None, id_to_key: list[NodeKey] | None = None, edge_keys: list[EdgeKey] | None = None, + use_compat_graph: bool | None = None, **attr, - ) -> MultiGraph: + ) -> MultiGraph | CudaMultiGraph: N = indptr.size - 1 src_indices = cp.array( # cp.repeat is slow to use here, so use numpy instead @@ -137,6 +157,7 @@ def from_csr( key_to_id=key_to_id, id_to_key=id_to_key, edge_keys=edge_keys, + use_compat_graph=use_compat_graph, **attr, ) @@ -154,8 +175,9 @@ def from_csc( key_to_id: dict[NodeKey, IndexValue] | None = None, id_to_key: list[NodeKey] | None = None, edge_keys: list[EdgeKey] | None = None, + use_compat_graph: bool | None = None, **attr, - ) -> MultiGraph: + ) -> MultiGraph | CudaMultiGraph: N = indptr.size - 1 dst_indices = cp.array( # cp.repeat is slow to use here, so use numpy instead @@ -173,6 +195,7 @@ def from_csc( key_to_id=key_to_id, id_to_key=id_to_key, edge_keys=edge_keys, + use_compat_graph=use_compat_graph, **attr, ) @@ -192,8 +215,9 @@ def from_dcsr( key_to_id: dict[NodeKey, IndexValue] | None = None, id_to_key: list[NodeKey] | None = None, edge_keys: list[EdgeKey] | None = None, + use_compat_graph: bool | None = None, **attr, - ) -> MultiGraph: + ) -> MultiGraph | CudaMultiGraph: src_indices = cp.array( # cp.repeat is slow to use here, so use numpy instead np.repeat(compressed_srcs.get(), cp.diff(indptr).get()) @@ -210,6 +234,7 @@ def from_dcsr( key_to_id=key_to_id, id_to_key=id_to_key, edge_keys=edge_keys, + use_compat_graph=use_compat_graph, **attr, ) @@ -229,8 +254,9 @@ def from_dcsc( key_to_id: dict[NodeKey, IndexValue] | None = None, id_to_key: list[NodeKey] | None = None, edge_keys: list[EdgeKey] | None = None, + use_compat_graph: bool | None = None, **attr, - ) -> Graph: + ) -> MultiGraph | CudaGraph: dst_indices = cp.array( # cp.repeat is slow to use here, so use numpy instead np.repeat(compressed_dsts.get(), cp.diff(indptr).get()) @@ -247,12 +273,46 @@ def from_dcsc( key_to_id=key_to_id, id_to_key=id_to_key, edge_keys=edge_keys, + use_compat_graph=use_compat_graph, **attr, ) + +class CudaMultiGraph(CudaGraph): + # networkx properties + edge_key_dict_factory: ClassVar[type] = dict + + # Not networkx properties + + # In a MultiGraph, each edge has a unique `(src, dst, key)` key. + # By default, `key` is 0 if possible, else 1, else 2, etc. + # This key can be any hashable Python object in NetworkX. + # We don't use a dict for our data structure here, because + # that would require a `(src, dst, key)` key. + # Instead, we keep `edge_keys` and/or `edge_indices`. + # `edge_keys` is the list of Python objects for each edge. + # `edge_indices` is for the common case of default multiedge keys, + # in which case we can store it as a cupy array. + # `edge_indices` is generally preferred. It is possible to provide + # both where edge_indices is the default and edge_keys is anything. + # It is also possible for them both to be None, which means the + # default edge indices has not yet been calculated. + edge_indices: cp.ndarray[IndexValue] | None + edge_keys: list[EdgeKey] | None + + #################### + # Creation methods # + #################### + + from_coo = classmethod(MultiGraph.from_coo.__func__) + from_csr = classmethod(MultiGraph.from_csr.__func__) + from_csc = classmethod(MultiGraph.from_csc.__func__) + from_dcsr = classmethod(MultiGraph.from_dcsr.__func__) + from_dcsc = classmethod(MultiGraph.from_dcsc.__func__) + def __new__( cls, incoming_graph_data=None, multigraph_input=None, **attr - ) -> MultiGraph: + ) -> CudaMultiGraph: if isinstance(incoming_graph_data, dict) and multigraph_input is not False: new_graph = nxcg.from_networkx( nx.MultiGraph(incoming_graph_data, multigraph_input=multigraph_input), @@ -267,28 +327,23 @@ def __new__( # Class methods # ################# - @classmethod - @networkx_api - def is_directed(cls) -> bool: - return False + is_directed = classmethod(MultiGraph.is_directed.__func__) + is_multigraph = classmethod(MultiGraph.is_multigraph.__func__) + to_cudagraph_class = classmethod(MultiGraph.to_cudagraph_class.__func__) + to_networkx_class = classmethod(MultiGraph.to_networkx_class.__func__) @classmethod @networkx_api - def is_multigraph(cls) -> bool: - return True + def to_directed_class(cls) -> type[nxcg.CudaMultiDiGraph]: + return nxcg.CudaMultiDiGraph @classmethod @networkx_api - def to_directed_class(cls) -> type[nxcg.MultiDiGraph]: - return nxcg.MultiDiGraph - - @classmethod - def to_networkx_class(cls) -> type[nx.MultiGraph]: - return nx.MultiGraph + def to_undirected_class(cls) -> type[CudaMultiGraph]: + return CudaMultiGraph @classmethod - @networkx_api - def to_undirected_class(cls) -> type[MultiGraph]: + def _to_compat_graph_class(cls) -> type[MultiGraph]: return MultiGraph ########################## @@ -308,7 +363,7 @@ def clear_edges(self) -> None: self.edge_keys = None @networkx_api - def copy(self, as_view: bool = False) -> MultiGraph: + def copy(self, as_view: bool = False) -> CudaMultiGraph: # Does shallow copy in networkx return self._copy(as_view, self.__class__) @@ -391,11 +446,11 @@ def has_edge(self, u: NodeKey, v: NodeKey, key: EdgeKey | None = None) -> bool: return any(edge_keys[i] == key for i in indices.tolist()) @networkx_api - def to_directed(self, as_view: bool = False) -> nxcg.MultiDiGraph: + def to_directed(self, as_view: bool = False) -> nxcg.CudaMultiDiGraph: return self._copy(as_view, self.to_directed_class()) @networkx_api - def to_undirected(self, as_view: bool = False) -> MultiGraph: + def to_undirected(self, as_view: bool = False) -> CudaMultiGraph: # Does deep copy in networkx return self._copy(as_view, self.to_undirected_class()) @@ -403,8 +458,8 @@ def to_undirected(self, as_view: bool = False) -> MultiGraph: # Private methods # ################### - def _copy(self, as_view: bool, cls: type[Graph], reverse: bool = False): - # DRY warning: see also Graph._copy + def _copy(self, as_view: bool, cls: type[CudaGraph], reverse: bool = False): + # DRY warning: see also CudaGraph._copy src_indices = self.src_indices dst_indices = self.dst_indices edge_indices = self.edge_indices @@ -451,6 +506,7 @@ def _copy(self, as_view: bool, cls: type[Graph], reverse: bool = False): key_to_id=key_to_id, id_to_key=id_to_key, edge_keys=edge_keys, + use_compat_graph=False, ) if as_view: rv.graph = self.graph @@ -460,7 +516,7 @@ def _copy(self, as_view: bool, cls: type[Graph], reverse: bool = False): return rv def _sort_edge_indices(self, primary="src"): - # DRY warning: see also Graph._sort_edge_indices + # DRY warning: see also CudaGraph._sort_edge_indices if self.edge_indices is None and self.edge_keys is None: return super()._sort_edge_indices(primary=primary) if primary == "src": diff --git a/python/nx-cugraph/nx_cugraph/convert.py b/python/nx-cugraph/nx_cugraph/convert.py index 56d16d837d7..a872f13ac70 100644 --- a/python/nx-cugraph/nx_cugraph/convert.py +++ b/python/nx-cugraph/nx_cugraph/convert.py @@ -12,6 +12,7 @@ # limitations under the License. from __future__ import annotations +import functools import itertools import operator as op from collections import Counter, defaultdict @@ -23,9 +24,13 @@ import numpy as np import nx_cugraph as nxcg +from nx_cugraph import _nxver from .utils import index_dtype, networkx_algorithm -from .utils.misc import pairwise +from .utils.misc import _And_NotImplementedError, pairwise + +if _nxver >= (3, 4): + from networkx.utils.backends import _get_cache_key, _get_from_cache, _set_to_cache if TYPE_CHECKING: # pragma: no cover from nx_cugraph.typing import AttrKey, Dtype, EdgeValue, NodeValue, any_ndarray @@ -60,6 +65,27 @@ def _iterate_values(graph, adj, is_dicts, func): return func(it), False +# Consider adding this to `utils` if it is useful elsewhere +def _fallback_decorator(func): + """Catch and convert exceptions to ``NotImplementedError``; use as a decorator. + + ``nx.NetworkXError`` are raised without being converted. This allows + falling back to other backends if, for example, conversion to GPU failed. + """ + + @functools.wraps(func) + def inner(*args, **kwargs): + try: + return func(*args, **kwargs) + except nx.NetworkXError: + raise + except Exception as exc: + raise _And_NotImplementedError(exc) from exc + + return inner + + +@_fallback_decorator def from_networkx( graph: nx.Graph, edge_attrs: AttrKey | dict[AttrKey, EdgeValue | None] | None = None, @@ -74,7 +100,8 @@ def from_networkx( as_directed: bool = False, name: str | None = None, graph_name: str | None = None, -) -> nxcg.Graph: + use_compat_graph: bool | None = False, +) -> nxcg.Graph | nxcg.CudaGraph: """Convert a networkx graph to nx_cugraph graph; can convert all attributes. Parameters @@ -114,10 +141,16 @@ def from_networkx( The name of the algorithm when dispatched from networkx. graph_name : str, optional The name of the graph argument geing converted when dispatched from networkx. + use_compat_graph : bool or None, default False + Indicate whether to return a graph that is compatible with NetworkX graph. + For example, ``nx_cugraph.Graph`` can be used as a NetworkX graph and can + reside in host (CPU) or device (GPU) memory. The default is False, which + will return e.g. ``nx_cugraph.CudaGraph`` that only resides on device (GPU) + and is not fully compatible as a NetworkX graph. Returns ------- - nx_cugraph.Graph + nx_cugraph.Graph or nx_cugraph.CudaGraph Notes ----- @@ -145,6 +178,41 @@ def from_networkx( graph = G else: raise TypeError(f"Expected networkx.Graph; got {type(graph)}") + elif isinstance(graph, nxcg.Graph): + if ( + use_compat_graph + # Use compat graphs by default + or use_compat_graph is None + and (_nxver < (3, 3) or nx.config.backends.cugraph.use_compat_graphs) + ): + return graph + if graph._is_on_gpu: + return graph._cudagraph + if not graph._is_on_cpu: + raise RuntimeError( + f"{type(graph).__name__} cannot be converted to the GPU, because it is " + "not on the CPU! This is not supposed to be possible. If you believe " + "you have found a bug, please report a minimum reproducible example to " + "https://github.com/rapidsai/cugraph/issues/new/choose" + ) + if _nxver >= (3, 4): + cache_key = _get_cache_key( + edge_attrs=edge_attrs, + node_attrs=node_attrs, + preserve_edge_attrs=preserve_edge_attrs, + preserve_node_attrs=preserve_node_attrs, + preserve_graph_attrs=preserve_graph_attrs, + ) + cache = getattr(graph, "__networkx_cache__", None) + if cache is not None: + cache = cache.setdefault("backends", {}).setdefault("cugraph", {}) + compat_key, rv = _get_from_cache(cache, cache_key) + if rv is not None: + if isinstance(rv, nxcg.Graph): + # This shouldn't happen during normal use, but be extra-careful + rv = rv._cudagraph + if rv is not None: + return rv if preserve_all_attrs: preserve_edge_attrs = True @@ -165,7 +233,12 @@ def from_networkx( else: node_attrs = {node_attrs: None} - if graph.__class__ in {nx.Graph, nx.DiGraph, nx.MultiGraph, nx.MultiDiGraph}: + if graph.__class__ in { + nx.Graph, + nx.DiGraph, + nx.MultiGraph, + nx.MultiDiGraph, + } or isinstance(graph, nxcg.Graph): # This is a NetworkX private attribute, but is much faster to use adj = graph._adj else: @@ -455,9 +528,9 @@ def func(it, edge_attr=edge_attr, dtype=dtype): # if vals.ndim > 1: ... if graph.is_multigraph(): if graph.is_directed() or as_directed: - klass = nxcg.MultiDiGraph + klass = nxcg.CudaMultiDiGraph else: - klass = nxcg.MultiGraph + klass = nxcg.CudaMultiGraph rv = klass.from_coo( N, src_indices, @@ -469,12 +542,13 @@ def func(it, edge_attr=edge_attr, dtype=dtype): node_masks, key_to_id=key_to_id, edge_keys=edge_keys, + use_compat_graph=False, ) else: if graph.is_directed() or as_directed: - klass = nxcg.DiGraph + klass = nxcg.CudaDiGraph else: - klass = nxcg.Graph + klass = nxcg.CudaGraph rv = klass.from_coo( N, src_indices, @@ -484,9 +558,22 @@ def func(it, edge_attr=edge_attr, dtype=dtype): node_values, node_masks, key_to_id=key_to_id, + use_compat_graph=False, ) if preserve_graph_attrs: rv.graph.update(graph.graph) # deepcopy? + if _nxver >= (3, 4) and isinstance(graph, nxcg.Graph) and cache is not None: + # Make sure this conversion is added to the cache, and make all of + # our graphs share the same `.graph` attribute for consistency. + rv.graph = graph.graph + _set_to_cache(cache, cache_key, rv) + if ( + use_compat_graph + # Use compat graphs by default + or use_compat_graph is None + and (_nxver < (3, 3) or nx.config.backends.cugraph.use_compat_graphs) + ): + return rv._to_compat_graph() return rv @@ -535,14 +622,16 @@ def _iter_attr_dicts( return full_dicts -def to_networkx(G: nxcg.Graph, *, sort_edges: bool = False) -> nx.Graph: +def to_networkx( + G: nxcg.Graph | nxcg.CudaGraph, *, sort_edges: bool = False +) -> nx.Graph: """Convert a nx_cugraph graph to networkx graph. All edge and node attributes and ``G.graph`` properties are converted. Parameters ---------- - G : nx_cugraph.Graph + G : nx_cugraph.Graph or nx_cugraph.CudaGraph sort_edges : bool, default False Whether to sort the edge data of the input graph by (src, dst) indices before converting. This can be useful to convert to networkx graphs @@ -557,6 +646,9 @@ def to_networkx(G: nxcg.Graph, *, sort_edges: bool = False) -> nx.Graph: -------- from_networkx : The opposite; convert networkx graph to nx_cugraph graph """ + if isinstance(G, nxcg.Graph): + # These graphs are already NetworkX graphs :) + return G rv = G.to_networkx_class()() id_to_key = G.id_to_key if sort_edges: @@ -623,13 +715,13 @@ def _to_graph( edge_attr: AttrKey | None = None, edge_default: EdgeValue | None = 1, edge_dtype: Dtype | None = None, -) -> nxcg.Graph | nxcg.DiGraph: +) -> nxcg.CudaGraph | nxcg.CudaDiGraph: """Ensure that input type is a nx_cugraph graph, and convert if necessary. Directed and undirected graphs are both allowed. This is an internal utility function and may change or be removed. """ - if isinstance(G, nxcg.Graph): + if isinstance(G, nxcg.CudaGraph): return G if isinstance(G, nx.Graph): return from_networkx( @@ -644,15 +736,15 @@ def _to_directed_graph( edge_attr: AttrKey | None = None, edge_default: EdgeValue | None = 1, edge_dtype: Dtype | None = None, -) -> nxcg.DiGraph: - """Ensure that input type is a nx_cugraph DiGraph, and convert if necessary. +) -> nxcg.CudaDiGraph: + """Ensure that input type is a nx_cugraph CudaDiGraph, and convert if necessary. Undirected graphs will be converted to directed. This is an internal utility function and may change or be removed. """ - if isinstance(G, nxcg.DiGraph): + if isinstance(G, nxcg.CudaDiGraph): return G - if isinstance(G, nxcg.Graph): + if isinstance(G, nxcg.CudaGraph): return G.to_directed() if isinstance(G, nx.Graph): return from_networkx( @@ -670,13 +762,13 @@ def _to_undirected_graph( edge_attr: AttrKey | None = None, edge_default: EdgeValue | None = 1, edge_dtype: Dtype | None = None, -) -> nxcg.Graph: - """Ensure that input type is a nx_cugraph Graph, and convert if necessary. +) -> nxcg.CudaGraph: + """Ensure that input type is a nx_cugraph CudaGraph, and convert if necessary. Only undirected graphs are allowed. Directed graphs will raise ValueError. This is an internal utility function and may change or be removed. """ - if isinstance(G, nxcg.Graph): + if isinstance(G, nxcg.CudaGraph): if G.is_directed(): raise ValueError("Only undirected graphs supported; got a directed graph") return G @@ -688,7 +780,7 @@ def _to_undirected_graph( raise TypeError -@networkx_algorithm(version_added="24.08") +@networkx_algorithm(version_added="24.08", fallback=True) def from_dict_of_lists(d, create_using=None): from .generators._utils import _create_using_class diff --git a/python/nx-cugraph/nx_cugraph/convert_matrix.py b/python/nx-cugraph/nx_cugraph/convert_matrix.py index 38139b913cf..54975902861 100644 --- a/python/nx-cugraph/nx_cugraph/convert_matrix.py +++ b/python/nx-cugraph/nx_cugraph/convert_matrix.py @@ -14,6 +14,8 @@ import networkx as nx import numpy as np +from nx_cugraph import _nxver + from .generators._utils import _create_using_class from .utils import _cp_iscopied_asarray, index_dtype, networkx_algorithm @@ -24,7 +26,7 @@ # Value columns with string dtype is not supported -@networkx_algorithm(is_incomplete=True, version_added="23.12") +@networkx_algorithm(is_incomplete=True, version_added="23.12", fallback=True) def from_pandas_edgelist( df, source="source", @@ -138,7 +140,7 @@ def from_pandas_edgelist( and ( # In nx <= 3.3, `edge_key` was ignored if `edge_attr` is None edge_attr is not None - or nx.__version__[:3] > "3.3" + or _nxver > (3, 3) ) ): try: @@ -161,7 +163,7 @@ def from_pandas_edgelist( return G -@networkx_algorithm(version_added="23.12") +@networkx_algorithm(version_added="23.12", fallback=True) def from_scipy_sparse_array( A, parallel_edges=False, create_using=None, edge_attribute="weight" ): diff --git a/python/nx-cugraph/nx_cugraph/generators/_utils.py b/python/nx-cugraph/nx_cugraph/generators/_utils.py index e38ace5b28d..bc9ab84bdad 100644 --- a/python/nx-cugraph/nx_cugraph/generators/_utils.py +++ b/python/nx-cugraph/nx_cugraph/generators/_utils.py @@ -1,4 +1,4 @@ -# Copyright (c) 2023, NVIDIA CORPORATION. +# 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 @@ -16,6 +16,7 @@ import networkx as nx import nx_cugraph as nxcg +from nx_cugraph import _nxver from ..utils import index_dtype @@ -74,7 +75,7 @@ def _common_small_graph(n, nodes, create_using, *, allow_directed=True): return G -def _create_using_class(create_using, *, default=nxcg.Graph): +def _create_using_class(create_using, *, default=nx.Graph): """Handle ``create_using`` argument and return a Graph type from nx_cugraph.""" inplace = False if create_using is None: @@ -85,16 +86,17 @@ def _create_using_class(create_using, *, default=nxcg.Graph): create_using, "is_multigraph" ): raise TypeError("create_using is not a valid graph type or instance") - elif not isinstance(create_using, nxcg.Graph): + elif not isinstance(create_using, (nxcg.Graph, nxcg.CudaGraph)): raise NotImplementedError( f"create_using with object of type {type(create_using)} is not supported " - "by the cugraph backend; only nx_cugraph.Graph objects are allowed." + "by the cugraph backend; only nx_cugraph.Graph or nx_cugraph.CudaGraph " + "objects are allowed." ) else: inplace = True G = create_using G.clear() - if not isinstance(G, nxcg.Graph): + if not isinstance(G, (nxcg.Graph, nxcg.CudaGraph)): if G.is_multigraph(): if G.is_directed(): graph_class = nxcg.MultiDiGraph @@ -104,10 +106,12 @@ def _create_using_class(create_using, *, default=nxcg.Graph): graph_class = nxcg.DiGraph else: graph_class = nxcg.Graph + if _nxver >= (3, 3) and not nx.config.backends.cugraph.use_compat_graphs: + graph_class = graph_class.to_cudagraph_class() if G.__class__ not in {nx.Graph, nx.DiGraph, nx.MultiGraph, nx.MultiDiGraph}: raise NotImplementedError( f"create_using with type {type(G)} is not supported by the cugraph " - "backend; only standard networkx or nx_cugraph Graph objects are " + "backend; only standard networkx or nx_cugraph graph objects are " "allowed (but not customized subclasses derived from them)." ) else: diff --git a/python/nx-cugraph/nx_cugraph/generators/classic.py b/python/nx-cugraph/nx_cugraph/generators/classic.py index a548beea34f..cfcb2a3afec 100644 --- a/python/nx-cugraph/nx_cugraph/generators/classic.py +++ b/python/nx-cugraph/nx_cugraph/generators/classic.py @@ -18,6 +18,7 @@ import numpy as np import nx_cugraph as nxcg +from nx_cugraph import _nxver from ..utils import _get_int_dtype, index_dtype, networkx_algorithm from ._utils import ( @@ -102,7 +103,9 @@ def complete_graph(n, create_using=None): @networkx_algorithm(version_added="23.12") def complete_multipartite_graph(*subset_sizes): if not subset_sizes: - return nxcg.Graph() + if _nxver < (3, 3) or nx.config.backends.cugraph.use_compat_graphs: + return nxcg.Graph() + return nxcg.CudaGraph() try: subset_sizes = [_ensure_int(size) for size in subset_sizes] except TypeError: @@ -139,6 +142,8 @@ def complete_multipartite_graph(*subset_sizes): dst_indices, node_values={"subset": subsets_array}, id_to_key=nodes, + use_compat_graph=_nxver < (3, 3) + or nx.config.backends.cugraph.use_compat_graphs, ) diff --git a/python/nx-cugraph/nx_cugraph/generators/community.py b/python/nx-cugraph/nx_cugraph/generators/community.py index 9b0e0848de9..4e5063cc345 100644 --- a/python/nx-cugraph/nx_cugraph/generators/community.py +++ b/python/nx-cugraph/nx_cugraph/generators/community.py @@ -11,8 +11,10 @@ # See the License for the specific language governing permissions and # limitations under the License. import cupy as cp +import networkx as nx import nx_cugraph as nxcg +from nx_cugraph import _nxver from ..utils import networkx_algorithm from ._utils import ( @@ -42,4 +44,7 @@ def caveman_graph(l, k): # noqa: E741 dst_cliques.extend(dst_clique + i * k for i in range(1, l)) src_indices = cp.hstack(src_cliques) dst_indices = cp.hstack(dst_cliques) - return nxcg.Graph.from_coo(l * k, src_indices, dst_indices) + use_compat_graph = _nxver < (3, 3) or nx.config.backends.cugraph.use_compat_graphs + return nxcg.CudaGraph.from_coo( + l * k, src_indices, dst_indices, use_compat_graph=use_compat_graph + ) diff --git a/python/nx-cugraph/nx_cugraph/generators/ego.py b/python/nx-cugraph/nx_cugraph/generators/ego.py index 66c9c8b95ee..9a91fa0b6c3 100644 --- a/python/nx-cugraph/nx_cugraph/generators/ego.py +++ b/python/nx-cugraph/nx_cugraph/generators/ego.py @@ -32,7 +32,10 @@ def ego_graph( ): """Weighted ego_graph with negative cycles is not yet supported. `NotImplementedError` will be raised if there are negative `distance` edge weights.""" # noqa: E501 if isinstance(G, nx.Graph): + is_compat_graph = isinstance(G, nxcg.Graph) G = nxcg.from_networkx(G, preserve_all_attrs=True) + else: + is_compat_graph = False if n not in G: if distance is None: raise nx.NodeNotFound(f"Source {n} is not in G") @@ -100,7 +103,10 @@ def ego_graph( node_mask &= node_ids != src_index node_ids = node_ids[node_mask] if node_ids.size == G._N: - return G.copy() + rv = G.copy() + if is_compat_graph: + return rv._to_compat_graph() + return rv # TODO: create renumbering helper function(s) node_ids.sort() # TODO: is this ever necessary? Keep for safety node_values = {key: val[node_ids] for key, val in G.node_values.items()} @@ -137,6 +143,7 @@ def ego_graph( "node_values": node_values, "node_masks": node_masks, "key_to_id": key_to_id, + "use_compat_graph": False, } if G.is_multigraph(): if G.edge_keys is not None: @@ -147,6 +154,8 @@ def ego_graph( kwargs["edge_indices"] = G.edge_indices[edge_mask] rv = G.__class__.from_coo(**kwargs) rv.graph.update(G.graph) + if is_compat_graph: + return rv._to_compat_graph() return rv diff --git a/python/nx-cugraph/nx_cugraph/generators/small.py b/python/nx-cugraph/nx_cugraph/generators/small.py index 45487571cda..d0c03cb7dd4 100644 --- a/python/nx-cugraph/nx_cugraph/generators/small.py +++ b/python/nx-cugraph/nx_cugraph/generators/small.py @@ -14,6 +14,7 @@ import networkx as nx import nx_cugraph as nxcg +from nx_cugraph import _nxver from ..utils import index_dtype, networkx_algorithm from ._utils import _IS_NX32_OR_LESS, _create_using_class @@ -449,7 +450,14 @@ def pappus_graph(): index_dtype, ) # fmt: on - return nxcg.Graph.from_coo(18, src_indices, dst_indices, name="Pappus Graph") + use_compat_graph = _nxver < (3, 3) or nx.config.backends.cugraph.use_compat_graphs + return nxcg.CudaGraph.from_coo( + 18, + src_indices, + dst_indices, + name="Pappus Graph", + use_compat_graph=use_compat_graph, + ) @networkx_algorithm(version_added="23.12") diff --git a/python/nx-cugraph/nx_cugraph/generators/social.py b/python/nx-cugraph/nx_cugraph/generators/social.py index 07e82c63fbf..09d405e7561 100644 --- a/python/nx-cugraph/nx_cugraph/generators/social.py +++ b/python/nx-cugraph/nx_cugraph/generators/social.py @@ -11,9 +11,11 @@ # See the License for the specific language governing permissions and # limitations under the License. import cupy as cp +import networkx as nx import numpy as np import nx_cugraph as nxcg +from nx_cugraph import _nxver from ..utils import index_dtype, networkx_algorithm @@ -77,7 +79,8 @@ def davis_southern_women_graph(): "E13", "E14", ] # fmt: on - return nxcg.Graph.from_coo( + use_compat_graph = _nxver < (3, 3) or nx.config.backends.cugraph.use_compat_graphs + return nxcg.CudaGraph.from_coo( 32, src_indices, dst_indices, @@ -85,6 +88,7 @@ def davis_southern_women_graph(): id_to_key=women + events, top=women, bottom=events, + use_compat_graph=use_compat_graph, ) @@ -111,7 +115,14 @@ def florentine_families_graph(): "Salviati", "Strozzi", "Tornabuoni" ] # fmt: on - return nxcg.Graph.from_coo(15, src_indices, dst_indices, id_to_key=nodes) + use_compat_graph = _nxver < (3, 3) or nx.config.backends.cugraph.use_compat_graphs + return nxcg.CudaGraph.from_coo( + 15, + src_indices, + dst_indices, + id_to_key=nodes, + use_compat_graph=use_compat_graph, + ) @networkx_algorithm(version_added="23.12") @@ -165,13 +176,15 @@ def karate_club_graph(): "Officer", "Officer", "Officer", "Officer", "Officer", "Officer", ]) # fmt: on - return nxcg.Graph.from_coo( + use_compat_graph = _nxver < (3, 3) or nx.config.backends.cugraph.use_compat_graphs + return nxcg.CudaGraph.from_coo( 34, src_indices, dst_indices, edge_values={"weight": weights}, node_values={"club": clubs}, name="Zachary's Karate Club", + use_compat_graph=use_compat_graph, ) @@ -289,6 +302,12 @@ def les_miserables_graph(): "Zephine", ] # fmt: on - return nxcg.Graph.from_coo( - 77, src_indices, dst_indices, edge_values={"weight": weights}, id_to_key=nodes + use_compat_graph = _nxver < (3, 3) or nx.config.backends.cugraph.use_compat_graphs + return nxcg.CudaGraph.from_coo( + 77, + src_indices, + dst_indices, + edge_values={"weight": weights}, + id_to_key=nodes, + use_compat_graph=use_compat_graph, ) diff --git a/python/nx-cugraph/nx_cugraph/interface.py b/python/nx-cugraph/nx_cugraph/interface.py index 4007230efa9..1a3d08409a2 100644 --- a/python/nx-cugraph/nx_cugraph/interface.py +++ b/python/nx-cugraph/nx_cugraph/interface.py @@ -18,6 +18,7 @@ import networkx as nx import nx_cugraph as nxcg +from nx_cugraph import _nxver class BackendInterface: @@ -32,11 +33,19 @@ def convert_from_nx(graph, *args, edge_attrs=None, weight=None, **kwargs): "edge_attrs and weight arguments should not both be given" ) edge_attrs = {weight: 1} - return nxcg.from_networkx(graph, *args, edge_attrs=edge_attrs, **kwargs) + return nxcg.from_networkx( + graph, + *args, + edge_attrs=edge_attrs, + use_compat_graph=_nxver < (3, 3) + or nx.config.backends.cugraph.use_compat_graphs, + **kwargs, + ) @staticmethod def convert_to_nx(obj, *, name: str | None = None): - if isinstance(obj, nxcg.Graph): + if isinstance(obj, nxcg.CudaGraph): + # Observe that this does not try to convert Graph! return nxcg.to_networkx(obj) return obj @@ -62,19 +71,32 @@ def key(testpath): return (testname, frozenset({classname, filename})) return (testname, frozenset({filename})) + use_compat_graph = ( + _nxver < (3, 3) or nx.config.backends.cugraph.use_compat_graphs + ) + fallback = use_compat_graph or nx.utils.backends._dispatchable._fallback_to_nx + # Reasons for xfailing + # For nx version <= 3.1 no_weights = "weighted implementation not currently supported" no_multigraph = "multigraphs not currently supported" + # For nx version <= 3.2 + nx_cugraph_in_test_setup = ( + "nx-cugraph Graph is incompatible in test setup in nx versions < 3.3" + ) + # For all versions louvain_different = "Louvain may be different due to RNG" - no_string_dtype = "string edge values not currently supported" sssp_path_different = "sssp may choose a different valid path" + tuple_elements_preferred = "elements are tuples instead of lists" + no_mixed_dtypes_for_nodes = ( + # This one is tricky b/c we don't raise; all dtypes are treated as str + "mixed dtypes (str, int, float) for single node property not supported" + ) + # These shouldn't fail if using Graph or falling back to networkx + no_string_dtype = "string edge values not currently supported" no_object_dtype_for_edges = ( "Edges don't support object dtype (lists, strings, etc.)" ) - tuple_elements_preferred = "elements are tuples instead of lists" - nx_cugraph_in_test_setup = ( - "nx-cugraph Graph is incompatible in test setup in nx versions < 3.3" - ) xfail = { # This is removed while strongly_connected_components() is not @@ -98,38 +120,6 @@ def key(testpath): "test_cycles.py:TestMinimumCycleBasis." "test_gh6787_and_edge_attribute_names" ): sssp_path_different, - key( - "test_graph_hashing.py:test_isomorphic_edge_attr" - ): no_object_dtype_for_edges, - key( - "test_graph_hashing.py:test_isomorphic_edge_attr_and_node_attr" - ): no_object_dtype_for_edges, - key( - "test_graph_hashing.py:test_isomorphic_edge_attr_subgraph_hash" - ): no_object_dtype_for_edges, - key( - "test_graph_hashing.py:" - "test_isomorphic_edge_attr_and_node_attr_subgraph_hash" - ): no_object_dtype_for_edges, - key( - "test_summarization.py:TestSNAPNoEdgeTypes.test_summary_graph" - ): no_object_dtype_for_edges, - key( - "test_summarization.py:TestSNAPUndirected.test_summary_graph" - ): no_object_dtype_for_edges, - key( - "test_summarization.py:TestSNAPDirected.test_summary_graph" - ): no_object_dtype_for_edges, - key("test_gexf.py:TestGEXF.test_relabel"): no_object_dtype_for_edges, - key( - "test_gml.py:TestGraph.test_parse_gml_cytoscape_bug" - ): no_object_dtype_for_edges, - key("test_gml.py:TestGraph.test_parse_gml"): no_object_dtype_for_edges, - key("test_gml.py:TestGraph.test_read_gml"): no_object_dtype_for_edges, - key("test_gml.py:TestGraph.test_data_types"): no_object_dtype_for_edges, - key( - "test_gml.py:TestPropertyLists.test_reading_graph_with_list_property" - ): no_object_dtype_for_edges, key( "test_relabel.py:" "test_relabel_preserve_node_order_partial_mapping_with_copy_false" @@ -138,48 +128,107 @@ def key(testpath): "test_gml.py:" "TestPropertyLists.test_reading_graph_with_single_element_list_property" ): tuple_elements_preferred, - key( - "test_relabel.py:" - "TestRelabel.test_relabel_multidigraph_inout_merge_nodes" - ): no_string_dtype, - key( - "test_relabel.py:TestRelabel.test_relabel_multigraph_merge_inplace" - ): no_string_dtype, - key( - "test_relabel.py:TestRelabel.test_relabel_multidigraph_merge_inplace" - ): no_string_dtype, - key( - "test_relabel.py:TestRelabel.test_relabel_multidigraph_inout_copy" - ): no_string_dtype, - key( - "test_relabel.py:TestRelabel.test_relabel_multigraph_merge_copy" - ): no_string_dtype, - key( - "test_relabel.py:TestRelabel.test_relabel_multidigraph_merge_copy" - ): no_string_dtype, - key( - "test_relabel.py:TestRelabel.test_relabel_multigraph_nonnumeric_key" - ): no_string_dtype, - key("test_contraction.py:test_multigraph_path"): no_object_dtype_for_edges, - key( - "test_contraction.py:test_directed_multigraph_path" - ): no_object_dtype_for_edges, - key( - "test_contraction.py:test_multigraph_blockmodel" - ): no_object_dtype_for_edges, - key( - "test_summarization.py:TestSNAPUndirectedMulti.test_summary_graph" - ): no_string_dtype, - key( - "test_summarization.py:TestSNAPDirectedMulti.test_summary_graph" - ): no_string_dtype, } + if not fallback: + xfail.update( + { + key( + "test_graph_hashing.py:test_isomorphic_edge_attr" + ): no_object_dtype_for_edges, + key( + "test_graph_hashing.py:test_isomorphic_edge_attr_and_node_attr" + ): no_object_dtype_for_edges, + key( + "test_graph_hashing.py:test_isomorphic_edge_attr_subgraph_hash" + ): no_object_dtype_for_edges, + key( + "test_graph_hashing.py:" + "test_isomorphic_edge_attr_and_node_attr_subgraph_hash" + ): no_object_dtype_for_edges, + key( + "test_summarization.py:TestSNAPNoEdgeTypes.test_summary_graph" + ): no_object_dtype_for_edges, + key( + "test_summarization.py:TestSNAPUndirected.test_summary_graph" + ): no_object_dtype_for_edges, + key( + "test_summarization.py:TestSNAPDirected.test_summary_graph" + ): no_object_dtype_for_edges, + key( + "test_gexf.py:TestGEXF.test_relabel" + ): no_object_dtype_for_edges, + key( + "test_gml.py:TestGraph.test_parse_gml_cytoscape_bug" + ): no_object_dtype_for_edges, + key( + "test_gml.py:TestGraph.test_parse_gml" + ): no_object_dtype_for_edges, + key( + "test_gml.py:TestGraph.test_read_gml" + ): no_object_dtype_for_edges, + key( + "test_gml.py:TestGraph.test_data_types" + ): no_object_dtype_for_edges, + key( + "test_gml.py:" + "TestPropertyLists.test_reading_graph_with_list_property" + ): no_object_dtype_for_edges, + key( + "test_relabel.py:" + "TestRelabel.test_relabel_multidigraph_inout_merge_nodes" + ): no_string_dtype, + key( + "test_relabel.py:" + "TestRelabel.test_relabel_multigraph_merge_inplace" + ): no_string_dtype, + key( + "test_relabel.py:" + "TestRelabel.test_relabel_multidigraph_merge_inplace" + ): no_string_dtype, + key( + "test_relabel.py:" + "TestRelabel.test_relabel_multidigraph_inout_copy" + ): no_string_dtype, + key( + "test_relabel.py:TestRelabel.test_relabel_multigraph_merge_copy" + ): no_string_dtype, + key( + "test_relabel.py:" + "TestRelabel.test_relabel_multidigraph_merge_copy" + ): no_string_dtype, + key( + "test_relabel.py:" + "TestRelabel.test_relabel_multigraph_nonnumeric_key" + ): no_string_dtype, + key( + "test_contraction.py:test_multigraph_path" + ): no_object_dtype_for_edges, + key( + "test_contraction.py:test_directed_multigraph_path" + ): no_object_dtype_for_edges, + key( + "test_contraction.py:test_multigraph_blockmodel" + ): no_object_dtype_for_edges, + key( + "test_summarization.py:" + "TestSNAPUndirectedMulti.test_summary_graph" + ): no_string_dtype, + key( + "test_summarization.py:TestSNAPDirectedMulti.test_summary_graph" + ): no_string_dtype, + } + ) + else: + xfail.update( + { + key( + "test_gml.py:" + "TestPropertyLists.test_reading_graph_with_list_property" + ): no_mixed_dtypes_for_nodes, + } + ) - from packaging.version import parse - - nxver = parse(nx.__version__) - - if nxver.major == 3 and nxver.minor <= 2: + if _nxver <= (3, 2): xfail.update( { # NetworkX versions prior to 3.2.1 have tests written to @@ -216,7 +265,7 @@ def key(testpath): } ) - if nxver.major == 3 and nxver.minor <= 1: + if _nxver <= (3, 1): # MAINT: networkx 3.0, 3.1 # NetworkX 3.2 added the ability to "fallback to nx" if backend algorithms # raise NotImplementedError or `can_run` returns False. The tests below @@ -332,24 +381,25 @@ def key(testpath): xfail[key("test_louvain.py:test_threshold")] = ( "Louvain does not support seed parameter" ) - if nxver.major == 3 and nxver.minor >= 2: - xfail.update( - { - key( - "test_convert_pandas.py:TestConvertPandas." - "test_from_edgelist_multi_attr_incl_target" - ): no_string_dtype, - key( - "test_convert_pandas.py:TestConvertPandas." - "test_from_edgelist_multidigraph_and_edge_attr" - ): no_string_dtype, - key( - "test_convert_pandas.py:TestConvertPandas." - "test_from_edgelist_int_attr_name" - ): no_string_dtype, - } - ) - if nxver.minor == 2: + if _nxver >= (3, 2): + if not fallback: + xfail.update( + { + key( + "test_convert_pandas.py:TestConvertPandas." + "test_from_edgelist_multi_attr_incl_target" + ): no_string_dtype, + key( + "test_convert_pandas.py:TestConvertPandas." + "test_from_edgelist_multidigraph_and_edge_attr" + ): no_string_dtype, + key( + "test_convert_pandas.py:TestConvertPandas." + "test_from_edgelist_int_attr_name" + ): no_string_dtype, + } + ) + if _nxver[1] == 2: different_iteration_order = "Different graph data iteration order" xfail.update( { @@ -366,7 +416,7 @@ def key(testpath): ): different_iteration_order, } ) - elif nxver.minor >= 3: + elif _nxver[1] >= 3: xfail.update( { key("test_louvain.py:test_max_level"): louvain_different, diff --git a/python/nx-cugraph/nx_cugraph/relabel.py b/python/nx-cugraph/nx_cugraph/relabel.py index 20d1337a99c..e38e18c779e 100644 --- a/python/nx-cugraph/nx_cugraph/relabel.py +++ b/python/nx-cugraph/nx_cugraph/relabel.py @@ -29,13 +29,18 @@ @networkx_algorithm(version_added="24.08") def relabel_nodes(G, mapping, copy=True): + G_orig = G if isinstance(G, nx.Graph): - if not copy: + is_compat_graph = isinstance(G, nxcg.Graph) + if not copy and not is_compat_graph: raise RuntimeError( "Using `copy=False` is invalid when using a NetworkX graph " "as input to `nx_cugraph.relabel_nodes`" ) G = nxcg.from_networkx(G, preserve_all_attrs=True) + else: + is_compat_graph = False + it = range(G._N) if G.key_to_id is None else G.id_to_key if callable(mapping): previd_to_key = [mapping(node) for node in it] @@ -225,12 +230,13 @@ def relabel_nodes(G, mapping, copy=True): node_masks=node_masks, id_to_key=newid_to_key, key_to_id=key_to_newid, + use_compat_graph=is_compat_graph, **extra_kwargs, ) rv.graph.update(G.graph) if not copy: - G._become(rv) - return G + G_orig._become(rv) + return G_orig return rv @@ -241,7 +247,10 @@ def convert_node_labels_to_integers( if ordering not in {"default", "sorted", "increasing degree", "decreasing degree"}: raise nx.NetworkXError(f"Unknown node ordering: {ordering}") if isinstance(G, nx.Graph): + is_compat_graph = isinstance(G, nxcg.Graph) G = nxcg.from_networkx(G, preserve_all_attrs=True) + else: + is_compat_graph = False G = G.copy() if label_attribute is not None: prev_vals = G.id_to_key @@ -279,4 +288,6 @@ def convert_node_labels_to_integers( key_to_id = G.key_to_id G.key_to_id = {i: key_to_id[n] for i, (d, n) in enumerate(pairs, first_label)} G._id_to_key = id_to_key + if is_compat_graph: + return G._to_compat_graph() return G diff --git a/python/nx-cugraph/nx_cugraph/tests/pytest.ini b/python/nx-cugraph/nx_cugraph/tests/pytest.ini new file mode 100644 index 00000000000..7b0a9f29fb1 --- /dev/null +++ b/python/nx-cugraph/nx_cugraph/tests/pytest.ini @@ -0,0 +1,4 @@ +# Copyright (c) 2024, NVIDIA CORPORATION. + +[pytest] +addopts = --tb=native diff --git a/python/nx-cugraph/nx_cugraph/tests/test_bfs.py b/python/nx-cugraph/nx_cugraph/tests/test_bfs.py index c2b22e98949..ad2c62c1fb9 100644 --- a/python/nx-cugraph/nx_cugraph/tests/test_bfs.py +++ b/python/nx-cugraph/nx_cugraph/tests/test_bfs.py @@ -12,11 +12,10 @@ # limitations under the License. import networkx as nx import pytest -from packaging.version import parse -nxver = parse(nx.__version__) +from nx_cugraph import _nxver -if nxver.major == 3 and nxver.minor < 2: +if _nxver < (3, 2): pytest.skip("Need NetworkX >=3.2 to test clustering", allow_module_level=True) diff --git a/python/nx-cugraph/nx_cugraph/tests/test_classes.py b/python/nx-cugraph/nx_cugraph/tests/test_classes.py new file mode 100644 index 00000000000..0ac238b3558 --- /dev/null +++ b/python/nx-cugraph/nx_cugraph/tests/test_classes.py @@ -0,0 +1,77 @@ +# 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 nx_cugraph as nxcg + + +def test_class_to_class(): + """Basic sanity checks to ensure metadata relating graph classes are accurate.""" + for prefix in ["", "Cuda"]: + for suffix in ["Graph", "DiGraph", "MultiGraph", "MultiDiGraph"]: + cls_name = f"{prefix}{suffix}" + cls = getattr(nxcg, cls_name) + assert cls.__name__ == cls_name + G = cls() + assert cls is G.__class__ + # cudagraph + val = cls.to_cudagraph_class() + val2 = G.to_cudagraph_class() + assert val is val2 + assert val.__name__ == f"Cuda{suffix}" + assert val.__module__.startswith("nx_cugraph") + assert cls.is_directed() == G.is_directed() == val.is_directed() + assert cls.is_multigraph() == G.is_multigraph() == val.is_multigraph() + # networkx + val = cls.to_networkx_class() + val2 = G.to_networkx_class() + assert val is val2 + assert val.__name__ == suffix + assert val.__module__.startswith("networkx") + val = val() + assert cls.is_directed() == G.is_directed() == val.is_directed() + assert cls.is_multigraph() == G.is_multigraph() == val.is_multigraph() + # directed + val = cls.to_directed_class() + val2 = G.to_directed_class() + assert val is val2 + assert val.__module__.startswith("nx_cugraph") + assert val.is_directed() + assert cls.is_multigraph() == G.is_multigraph() == val.is_multigraph() + if "Di" in suffix: + assert val is cls + else: + assert "Di" in val.__name__ + assert prefix in val.__name__ + assert cls.to_undirected_class() is cls + # undirected + val = cls.to_undirected_class() + val2 = G.to_undirected_class() + assert val is val2 + assert val.__module__.startswith("nx_cugraph") + assert not val.is_directed() + assert cls.is_multigraph() == G.is_multigraph() == val.is_multigraph() + if "Di" not in suffix: + assert val is cls + else: + assert "Di" not in val.__name__ + assert prefix in val.__name__ + assert cls.to_directed_class() is cls + # "zero" + if prefix == "Cuda": + val = cls._to_compat_graph_class() + val2 = G._to_compat_graph_class() + assert val is val2 + assert val.__name__ == suffix + assert val.__module__.startswith("nx_cugraph") + assert val.to_cudagraph_class() is cls + assert cls.is_directed() == G.is_directed() == val.is_directed() + assert cls.is_multigraph() == G.is_multigraph() == val.is_multigraph() diff --git a/python/nx-cugraph/nx_cugraph/tests/test_cluster.py b/python/nx-cugraph/nx_cugraph/tests/test_cluster.py index ad4770f1ab8..fd8e1b3cf13 100644 --- a/python/nx-cugraph/nx_cugraph/tests/test_cluster.py +++ b/python/nx-cugraph/nx_cugraph/tests/test_cluster.py @@ -12,11 +12,10 @@ # limitations under the License. import networkx as nx import pytest -from packaging.version import parse -nxver = parse(nx.__version__) +from nx_cugraph import _nxver -if nxver.major == 3 and nxver.minor < 2: +if _nxver < (3, 2): pytest.skip("Need NetworkX >=3.2 to test clustering", allow_module_level=True) diff --git a/python/nx-cugraph/nx_cugraph/tests/test_convert.py b/python/nx-cugraph/nx_cugraph/tests/test_convert.py index 634b28e961c..3d109af8a74 100644 --- a/python/nx-cugraph/nx_cugraph/tests/test_convert.py +++ b/python/nx-cugraph/nx_cugraph/tests/test_convert.py @@ -13,13 +13,10 @@ import cupy as cp import networkx as nx import pytest -from packaging.version import parse import nx_cugraph as nxcg from nx_cugraph import interface -nxver = parse(nx.__version__) - @pytest.mark.parametrize( "graph_class", [nx.Graph, nx.DiGraph, nx.MultiGraph, nx.MultiDiGraph] diff --git a/python/nx-cugraph/nx_cugraph/tests/test_ego_graph.py b/python/nx-cugraph/nx_cugraph/tests/test_ego_graph.py index 5474f9d79e3..f3d0a8d3767 100644 --- a/python/nx-cugraph/nx_cugraph/tests/test_ego_graph.py +++ b/python/nx-cugraph/nx_cugraph/tests/test_ego_graph.py @@ -12,16 +12,13 @@ # limitations under the License. import networkx as nx import pytest -from packaging.version import parse import nx_cugraph as nxcg +from nx_cugraph import _nxver from .testing_utils import assert_graphs_equal -nxver = parse(nx.__version__) - - -if nxver.major == 3 and nxver.minor < 2: +if _nxver < (3, 2): pytest.skip("Need NetworkX >=3.2 to test ego_graph", allow_module_level=True) @@ -49,7 +46,12 @@ def test_ego_graph_cycle_graph( kwargs = {"radius": radius, "center": center, "undirected": undirected} Hnx = nx.ego_graph(Gnx, n, **kwargs) Hcg = nx.ego_graph(Gnx, n, **kwargs, backend="cugraph") + use_compat_graphs = _nxver < (3, 3) or nx.config.backends.cugraph.use_compat_graphs + assert_graphs_equal(Hnx, Hcg._cudagraph if use_compat_graphs else Hcg) + Hcg = nx.ego_graph(Gcg, n, **kwargs) assert_graphs_equal(Hnx, Hcg) + Hcg = nx.ego_graph(Gcg._to_compat_graph(), n, **kwargs) + assert_graphs_equal(Hnx, Hcg._cudagraph) with pytest.raises(nx.NodeNotFound, match="not in G"): nx.ego_graph(Gnx, -1, **kwargs) with pytest.raises(nx.NodeNotFound, match="not in G"): @@ -61,20 +63,35 @@ def test_ego_graph_cycle_graph( kwargs["distance"] = "weight" H2nx = nx.ego_graph(Gnx, n, **kwargs) - is_nx32 = nxver.major == 3 and nxver.minor == 2 + is_nx32 = _nxver[:2] == (3, 2) if undirected and Gnx.is_directed() and Gnx.is_multigraph(): if is_nx32: # `should_run` was added in nx 3.3 match = "Weighted ego_graph with undirected=True not implemented" + elif _nxver >= (3, 4): + match = "not implemented by 'cugraph'" else: match = "not implemented by cugraph" - with pytest.raises(RuntimeError, match=match): + with pytest.raises( + RuntimeError if _nxver < (3, 4) else NotImplementedError, match=match + ): nx.ego_graph(Gnx, n, **kwargs, backend="cugraph") with pytest.raises(NotImplementedError, match="ego_graph"): - nx.ego_graph(Gcg, n, **kwargs) + nx.ego_graph(Gcg, n, **kwargs, backend="cugraph") + if _nxver < (3, 4) or not nx.config.fallback_to_nx: + with pytest.raises(NotImplementedError, match="ego_graph"): + nx.ego_graph(Gcg, n, **kwargs) + else: + # This is an interesting case. `nxcg.ego_graph` is not implemented for + # these arguments, so it falls back to networkx. Hence, as it is currently + # implemented, the input graph is `nxcg.CudaGraph`, but the output graph + # is `nx.Graph`. Should networkx convert back to "cugraph" backend? + H2cg = nx.ego_graph(Gcg, n, **kwargs) + assert type(H2nx) is type(H2cg) + assert_graphs_equal(H2nx, nxcg.from_networkx(H2cg, preserve_all_attrs=True)) else: H2cg = nx.ego_graph(Gnx, n, **kwargs, backend="cugraph") - assert_graphs_equal(H2nx, H2cg) + assert_graphs_equal(H2nx, H2cg._cudagraph if use_compat_graphs else H2cg) with pytest.raises(nx.NodeNotFound, match="not found in graph"): nx.ego_graph(Gnx, -1, **kwargs) with pytest.raises(nx.NodeNotFound, match="not found in graph"): diff --git a/python/nx-cugraph/nx_cugraph/tests/test_generators.py b/python/nx-cugraph/nx_cugraph/tests/test_generators.py index c751b0fe2b3..5c405f1c93b 100644 --- a/python/nx-cugraph/nx_cugraph/tests/test_generators.py +++ b/python/nx-cugraph/nx_cugraph/tests/test_generators.py @@ -13,25 +13,24 @@ import networkx as nx import numpy as np import pytest -from packaging.version import parse import nx_cugraph as nxcg +from nx_cugraph import _nxver from .testing_utils import assert_graphs_equal -nxver = parse(nx.__version__) - - -if nxver.major == 3 and nxver.minor < 2: +if _nxver < (3, 2): pytest.skip("Need NetworkX >=3.2 to test generators", allow_module_level=True) def compare(name, create_using, *args, is_vanilla=False): exc1 = exc2 = None func = getattr(nx, name) - if isinstance(create_using, nxcg.Graph): + if isinstance(create_using, nxcg.CudaGraph): nx_create_using = nxcg.to_networkx(create_using) - elif isinstance(create_using, type) and issubclass(create_using, nxcg.Graph): + elif isinstance(create_using, type) and issubclass( + create_using, (nxcg.Graph, nxcg.CudaGraph) + ): nx_create_using = create_using.to_networkx_class() elif isinstance(create_using, nx.Graph): nx_create_using = create_using.copy() @@ -61,8 +60,27 @@ def compare(name, create_using, *args, is_vanilla=False): exc2 = exc if exc1 is not None or exc2 is not None: assert type(exc1) is type(exc2) + return + if isinstance(Gcg, nxcg.Graph): + # If the graph is empty, it may be on host, otherwise it should be on device + if len(G): + assert Gcg._is_on_gpu + assert not Gcg._is_on_cpu + assert_graphs_equal(G, Gcg._cudagraph) else: assert_graphs_equal(G, Gcg) + # Ensure the output type is correct + if is_vanilla: + if _nxver < (3, 3) or nx.config.backends.cugraph.use_compat_graphs: + assert isinstance(Gcg, nxcg.Graph) + else: + assert isinstance(Gcg, nxcg.CudaGraph) + elif isinstance(create_using, type) and issubclass( + create_using, (nxcg.Graph, nxcg.CudaGraph) + ): + assert type(Gcg) is create_using + elif isinstance(create_using, (nxcg.Graph, nxcg.CudaGraph)): + assert type(Gcg) is type(create_using) N = list(range(-1, 5)) @@ -76,6 +94,10 @@ def compare(name, create_using, *args, is_vanilla=False): nxcg.DiGraph, nxcg.MultiGraph, nxcg.MultiDiGraph, + nxcg.CudaGraph, + nxcg.CudaDiGraph, + nxcg.CudaMultiGraph, + nxcg.CudaMultiDiGraph, # These raise NotImplementedError # nx.Graph(), # nx.DiGraph(), @@ -85,6 +107,10 @@ def compare(name, create_using, *args, is_vanilla=False): nxcg.DiGraph(), nxcg.MultiGraph(), nxcg.MultiDiGraph(), + nxcg.CudaGraph(), + nxcg.CudaDiGraph(), + nxcg.CudaMultiGraph(), + nxcg.CudaMultiDiGraph(), None, object, # Bad input 7, # Bad input @@ -158,7 +184,7 @@ def compare(name, create_using, *args, is_vanilla=False): @pytest.mark.parametrize("create_using", COMPLETE_CREATE_USING) def test_generator_noarg(name, create_using): print(name, create_using, type(create_using)) - if isinstance(create_using, nxcg.Graph) and name in { + if isinstance(create_using, nxcg.CudaGraph) and name in { # fmt: off "bull_graph", "chvatal_graph", "cubical_graph", "diamond_graph", "house_graph", "house_x_graph", "icosahedral_graph", "krackhardt_kite_graph", diff --git a/python/nx-cugraph/nx_cugraph/tests/test_graph_methods.py b/python/nx-cugraph/nx_cugraph/tests/test_graph_methods.py index 3120995a2b2..40a361b1084 100644 --- a/python/nx-cugraph/nx_cugraph/tests/test_graph_methods.py +++ b/python/nx-cugraph/nx_cugraph/tests/test_graph_methods.py @@ -47,7 +47,7 @@ def _create_Gs(): @pytest.mark.parametrize("Gnx", _create_Gs()) @pytest.mark.parametrize("reciprocal", [False, True]) def test_to_undirected_directed(Gnx, reciprocal): - Gcg = nxcg.DiGraph(Gnx) + Gcg = nxcg.CudaDiGraph(Gnx) assert_graphs_equal(Gnx, Gcg) Hnx1 = Gnx.to_undirected(reciprocal=reciprocal) Hcg1 = Gcg.to_undirected(reciprocal=reciprocal) @@ -62,6 +62,6 @@ def test_multidigraph_to_undirected(): Gnx.add_edge(0, 1) Gnx.add_edge(0, 1) Gnx.add_edge(1, 0) - Gcg = nxcg.MultiDiGraph(Gnx) + Gcg = nxcg.CudaMultiDiGraph(Gnx) with pytest.raises(NotImplementedError): Gcg.to_undirected() diff --git a/python/nx-cugraph/nx_cugraph/tests/test_match_api.py b/python/nx-cugraph/nx_cugraph/tests/test_match_api.py index 176b531a6e7..1a61c69b3e7 100644 --- a/python/nx-cugraph/nx_cugraph/tests/test_match_api.py +++ b/python/nx-cugraph/nx_cugraph/tests/test_match_api.py @@ -14,13 +14,10 @@ import inspect import networkx as nx -from packaging.version import parse import nx_cugraph as nxcg from nx_cugraph.utils import networkx_algorithm -nxver = parse(nx.__version__) - def test_match_signature_and_names(): """Simple test to ensure our signatures and basic module layout match networkx.""" diff --git a/python/nx-cugraph/nx_cugraph/tests/test_multigraph.py b/python/nx-cugraph/nx_cugraph/tests/test_multigraph.py index a8f189a4745..9208eea09f2 100644 --- a/python/nx-cugraph/nx_cugraph/tests/test_multigraph.py +++ b/python/nx-cugraph/nx_cugraph/tests/test_multigraph.py @@ -1,4 +1,4 @@ -# Copyright (c) 2023, NVIDIA CORPORATION. +# 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 @@ -26,7 +26,7 @@ def test_get_edge_data(test_nxcugraph): G.add_edge(0, 3) G.add_edge(0, 3) if test_nxcugraph: - G = nxcg.MultiGraph(G) + G = nxcg.CudaMultiGraph(G) default = object() assert G.get_edge_data(0, 0, default=default) is default assert G.get_edge_data("a", "b", default=default) is default @@ -60,7 +60,7 @@ def test_get_edge_data(test_nxcugraph): G = nx.MultiGraph() G.add_edge(0, 1) if test_nxcugraph: - G = nxcg.MultiGraph(G) + G = nxcg.CudaMultiGraph(G) assert G.get_edge_data(0, 1, default=default) == {0: {}} assert G.get_edge_data(0, 1, 0, default=default) == {} assert G.get_edge_data(0, 1, 1, default=default) is default diff --git a/python/nx-cugraph/nx_cugraph/tests/test_pagerank.py b/python/nx-cugraph/nx_cugraph/tests/test_pagerank.py new file mode 100644 index 00000000000..252f9e6bbb8 --- /dev/null +++ b/python/nx-cugraph/nx_cugraph/tests/test_pagerank.py @@ -0,0 +1,40 @@ +# 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 networkx as nx +import pandas as pd +import pytest + + +def test_pagerank_multigraph(): + """ + Ensures correct pagerank for Graphs and MultiGraphs when using from_pandas_edgelist. + + PageRank for MultiGraph should give different result compared to Graph; when using + a Graph, the duplicate edges should be dropped. + """ + df = pd.DataFrame( + {"source": [0, 1, 1, 1, 1, 1, 1, 2], "target": [1, 2, 2, 2, 2, 2, 2, 3]} + ) + expected_pr_for_G = nx.pagerank(nx.from_pandas_edgelist(df)) + expected_pr_for_MultiG = nx.pagerank( + nx.from_pandas_edgelist(df, create_using=nx.MultiGraph) + ) + + G = nx.from_pandas_edgelist(df, backend="cugraph") + actual_pr_for_G = nx.pagerank(G, backend="cugraph") + + MultiG = nx.from_pandas_edgelist(df, create_using=nx.MultiGraph, backend="cugraph") + actual_pr_for_MultiG = nx.pagerank(MultiG, backend="cugraph") + + assert actual_pr_for_G == pytest.approx(expected_pr_for_G) + assert actual_pr_for_MultiG == pytest.approx(expected_pr_for_MultiG) diff --git a/python/nx-cugraph/nx_cugraph/tests/testing_utils.py b/python/nx-cugraph/nx_cugraph/tests/testing_utils.py index 529a96efd81..50836acf55f 100644 --- a/python/nx-cugraph/nx_cugraph/tests/testing_utils.py +++ b/python/nx-cugraph/nx_cugraph/tests/testing_utils.py @@ -17,7 +17,7 @@ def assert_graphs_equal(Gnx, Gcg): assert isinstance(Gnx, nx.Graph) - assert isinstance(Gcg, nxcg.Graph) + assert isinstance(Gcg, nxcg.CudaGraph) assert (a := Gnx.number_of_nodes()) == (b := Gcg.number_of_nodes()), (a, b) assert (a := Gnx.number_of_edges()) == (b := Gcg.number_of_edges()), (a, b) assert (a := Gnx.is_directed()) == (b := Gcg.is_directed()), (a, b) diff --git a/python/nx-cugraph/nx_cugraph/utils/decorators.py b/python/nx-cugraph/nx_cugraph/utils/decorators.py index 3c5de4f2936..16486996ba0 100644 --- a/python/nx-cugraph/nx_cugraph/utils/decorators.py +++ b/python/nx-cugraph/nx_cugraph/utils/decorators.py @@ -16,10 +16,14 @@ from textwrap import dedent import networkx as nx +from networkx import NetworkXError from networkx.utils.decorators import nodes_or_number, not_implemented_for +from nx_cugraph import _nxver from nx_cugraph.interface import BackendInterface +from .misc import _And_NotImplementedError + try: from networkx.utils.backends import _registered_algorithms except ModuleNotFoundError: @@ -44,6 +48,7 @@ class networkx_algorithm: version_added: str is_incomplete: bool is_different: bool + _fallback: bool _plc_names: set[str] | None def __new__( @@ -59,6 +64,7 @@ def __new__( version_added: str, # Required is_incomplete: bool = False, # See self.extra_doc for details if True is_different: bool = False, # See self.extra_doc for details if True + fallback: bool = False, # Change non-nx exceptions to NotImplementedError _plc: str | set[str] | None = None, # Hidden from user, may be removed someday ): if func is None: @@ -70,10 +76,11 @@ def __new__( version_added=version_added, is_incomplete=is_incomplete, is_different=is_different, + fallback=fallback, _plc=_plc, ) instance = object.__new__(cls) - if nodes_or_number is not None and nx.__version__[:3] > "3.2": + if nodes_or_number is not None and _nxver > (3, 2): func = nx.utils.decorators.nodes_or_number(nodes_or_number)(func) # update_wrapper sets __wrapped__, which will be used for the signature update_wrapper(instance, func) @@ -100,6 +107,7 @@ def __new__( instance.version_added = version_added instance.is_incomplete = is_incomplete instance.is_different = is_different + instance.fallback = fallback # The docstring on our function is added to the NetworkX docstring. instance.extra_doc = ( dedent(func.__doc__.lstrip("\n").rstrip()) if func.__doc__ else None @@ -113,7 +121,7 @@ def __new__( # Set methods so they are in __dict__ instance._can_run = instance._can_run instance._should_run = instance._should_run - if nodes_or_number is not None and nx.__version__[:3] <= "3.2": + if nodes_or_number is not None and _nxver <= (3, 2): instance = nx.utils.decorators.nodes_or_number(nodes_or_number)(instance) return instance @@ -136,7 +144,14 @@ def _should_run(self, func): self.should_run = func def __call__(self, /, *args, **kwargs): - return self.__wrapped__(*args, **kwargs) + if not self.fallback: + return self.__wrapped__(*args, **kwargs) + try: + return self.__wrapped__(*args, **kwargs) + except NetworkXError: + raise + except Exception as exc: + raise _And_NotImplementedError(exc) from exc def __reduce__(self): return _restore_networkx_dispatched, (self.name,) diff --git a/python/nx-cugraph/nx_cugraph/utils/misc.py b/python/nx-cugraph/nx_cugraph/utils/misc.py index 8526524f1de..01c25dd5983 100644 --- a/python/nx-cugraph/nx_cugraph/utils/misc.py +++ b/python/nx-cugraph/nx_cugraph/utils/misc.py @@ -194,7 +194,7 @@ def _get_int_dtype( def _get_float_dtype( - dtype: Dtype, *, graph: nxcg.Graph | None = None, weight: EdgeKey | None = None + dtype: Dtype, *, graph: nxcg.CudaGraph | None = None, weight: EdgeKey | None = None ): """Promote dtype to float32 or float64 as appropriate.""" if dtype is None: @@ -238,3 +238,37 @@ def _cp_iscopied_asarray(a, *args, orig_object=None, **kwargs): ): return False, arr return True, arr + + +class _And_NotImplementedError(NotImplementedError): + """Additionally make an exception a ``NotImplementedError``. + + For example: + + >>> try: + ... raise _And_NotImplementedError(KeyError("missing")) + ... except KeyError: + ... pass + + or + + >>> try: + ... raise _And_NotImplementedError(KeyError("missing")) + ... except NotImplementedError: + ... pass + + """ + + def __new__(cls, exc): + exc_type = type(exc) + if issubclass(exc_type, NotImplementedError): + new_type = exc_type + else: + new_type = type( + f"{exc_type.__name__}{cls.__name__}", + (exc_type, NotImplementedError), + {}, + ) + instance = NotImplementedError.__new__(new_type) + instance.__init__(*exc.args) + return instance diff --git a/python/nx-cugraph/pyproject.toml b/python/nx-cugraph/pyproject.toml index e7b4ea44dd8..d145aa549da 100644 --- a/python/nx-cugraph/pyproject.toml +++ b/python/nx-cugraph/pyproject.toml @@ -34,13 +34,12 @@ classifiers = [ dependencies = [ "cupy-cuda11x>=12.0.0", "networkx>=3.0", - "numpy>=1.23,<2.0a0", - "pylibcugraph==24.10.*,>=0.0.0a0", + "numpy>=1.23,<3.0a0", + "pylibcugraph==24.12.*,>=0.0.0a0", ] # This list was generated by `rapids-dependency-file-generator`. To make changes, edit ../../dependencies.yaml and run `rapids-dependency-file-generator`. [project.optional-dependencies] test = [ - "packaging>=21", "pandas", "pytest", "pytest-benchmark", @@ -170,6 +169,7 @@ external = [ ] ignore = [ # Would be nice to fix these + "B905", # `zip()` without an explicit `strict=` parameter (Note: possible since py39 was dropped; we should do this!) "D100", # Missing docstring in public module "D101", # Missing docstring in public class "D102", # Missing docstring in public method @@ -215,6 +215,7 @@ ignore = [ "SIM105", # Use contextlib.suppress(...) instead of try-except-pass (Note: try-except-pass is much faster) "SIM108", # Use ternary operator ... instead of if-else-block (Note: if-else better for coverage and sometimes clearer) "TRY003", # Avoid specifying long messages outside the exception class (Note: why?) + "UP038", # Use `X | Y` in `isinstance` call instead of `(X, Y)` (Note: tuple is faster for now) # Ignored categories "C90", # mccabe (Too strict, but maybe we should make things less complex) @@ -241,6 +242,7 @@ ignore = [ # Allow assert, print, RNG, and no docstring "nx_cugraph/**/tests/*py" = ["S101", "S311", "T201", "D103", "D100"] "_nx_cugraph/__init__.py" = ["E501"] +"nx_cugraph/__init__.py" = ["E402"] # Allow module level import not at top of file "nx_cugraph/algorithms/**/*py" = ["D205", "D401"] # Allow flexible docstrings for algorithms "nx_cugraph/generators/**/*py" = ["D205", "D401"] # Allow flexible docstrings for generators "nx_cugraph/interface.py" = ["D401"] # Flexible docstrings diff --git a/python/nx-cugraph/run_nx_tests.sh b/python/nx-cugraph/run_nx_tests.sh index bceec53b7d5..5fb173cf939 100755 --- a/python/nx-cugraph/run_nx_tests.sh +++ b/python/nx-cugraph/run_nx_tests.sh @@ -18,6 +18,10 @@ # testing takes longer. Without it, tests will xfail when encountering a # function that we don't implement. # +# NX_CUGRAPH_USE_COMPAT_GRAPHS, {"True", "False"}, default is "True" +# Whether to use `nxcg.Graph` as the nx_cugraph backend graph. +# A Graph should be a compatible NetworkX graph, so fewer tests should fail. +# # Coverage of `nx_cugraph.algorithms` is reported and is a good sanity check # that algorithms run. diff --git a/python/pylibcugraph/pylibcugraph/CMakeLists.txt b/python/pylibcugraph/pylibcugraph/CMakeLists.txt index 21446d639fe..fb46030bc56 100644 --- a/python/pylibcugraph/pylibcugraph/CMakeLists.txt +++ b/python/pylibcugraph/pylibcugraph/CMakeLists.txt @@ -54,6 +54,8 @@ set(cython_sources triangle_count.pyx two_hop_neighbors.pyx uniform_neighbor_sample.pyx + biased_neighbor_sample.pyx + negative_sampling.pyx uniform_random_walks.pyx utils.pyx weakly_connected_components.pyx @@ -67,6 +69,7 @@ set(cython_sources heterogeneous_uniform_neighbor_sample.pyx homogeneous_biased_neighbor_sample.pyx homogeneous_uniform_neighbor_sample.pyx + edge_id_lookup_table.pyx ) set(linked_libraries cugraph::cugraph;cugraph::cugraph_c) diff --git a/python/pylibcugraph/pylibcugraph/__init__.py b/python/pylibcugraph/pylibcugraph/__init__.py index 09a584c6da4..ea584569d77 100644 --- a/python/pylibcugraph/pylibcugraph/__init__.py +++ b/python/pylibcugraph/pylibcugraph/__init__.py @@ -21,6 +21,8 @@ from pylibcugraph.graph_properties import GraphProperties +from pylibcugraph.edge_id_lookup_table import EdgeIdLookupTable + from pylibcugraph.eigenvector_centrality import eigenvector_centrality from pylibcugraph.katz_centrality import katz_centrality @@ -48,6 +50,8 @@ #from pylibcugraph.uniform_neighbor_sample import neighbor_sample #from pylibcugraph.biased_neighbor_sample import biased_neighbor_sample +from pylibcugraph.negative_sampling import negative_sampling + from pylibcugraph.core_number import core_number from pylibcugraph.k_core import k_core diff --git a/python/pylibcugraph/pylibcugraph/_cugraph_c/graph.pxd b/python/pylibcugraph/pylibcugraph/_cugraph_c/graph.pxd index 4247bcc1b2a..5bbe5bc4a87 100644 --- a/python/pylibcugraph/pylibcugraph/_cugraph_c/graph.pxd +++ b/python/pylibcugraph/pylibcugraph/_cugraph_c/graph.pxd @@ -37,21 +37,6 @@ cdef extern from "cugraph_c/graph.h": bool_t is_symmetric bool_t is_multigraph - cdef cugraph_error_code_t \ - cugraph_sg_graph_create( - const cugraph_resource_handle_t* handle, - const cugraph_graph_properties_t* properties, - const cugraph_type_erased_device_array_view_t* src, - const cugraph_type_erased_device_array_view_t* dst, - const cugraph_type_erased_device_array_view_t* weights, - const cugraph_type_erased_device_array_view_t* edge_ids, - const cugraph_type_erased_device_array_view_t* edge_types, - bool_t store_transposed, - bool_t renumber, - bool_t check, - cugraph_graph_t** graph, - cugraph_error_t** error) - # Supports isolated vertices cdef cugraph_error_code_t \ cugraph_graph_create_sg( @@ -67,16 +52,11 @@ cdef extern from "cugraph_c/graph.h": bool_t renumber, bool_t drop_self_loops, bool_t drop_multi_edges, + bool_t symmetrize, bool_t check, cugraph_graph_t** graph, cugraph_error_t** error) - # This may get renamed to cugraph_graph_free() - cdef void \ - cugraph_sg_graph_free( - cugraph_graph_t* graph - ) - # FIXME: Might want to delete 'cugraph_sg_graph_free' and replace # 'cugraph_mg_graph_free' by 'cugraph_graph_free' cdef void \ @@ -84,44 +64,6 @@ cdef extern from "cugraph_c/graph.h": cugraph_graph_t* graph ) - cdef cugraph_error_code_t \ - cugraph_mg_graph_create( - const cugraph_resource_handle_t* handle, - const cugraph_graph_properties_t* properties, - const cugraph_type_erased_device_array_view_t* src, - const cugraph_type_erased_device_array_view_t* dst, - const cugraph_type_erased_device_array_view_t* weights, - const cugraph_type_erased_device_array_view_t* edge_ids, - const cugraph_type_erased_device_array_view_t* edge_types, - bool_t store_transposed, - size_t num_edges, - bool_t check, - cugraph_graph_t** graph, - cugraph_error_t** error - ) - - # This may get renamed to or replaced with cugraph_graph_free() - cdef void \ - cugraph_mg_graph_free( - cugraph_graph_t* graph - ) - - cdef cugraph_error_code_t \ - cugraph_sg_graph_create_from_csr( - const cugraph_resource_handle_t* handle, - const cugraph_graph_properties_t* properties, - const cugraph_type_erased_device_array_view_t* offsets, - const cugraph_type_erased_device_array_view_t* indices, - const cugraph_type_erased_device_array_view_t* weights, - const cugraph_type_erased_device_array_view_t* edge_ids, - const cugraph_type_erased_device_array_view_t* edge_type_ids, - bool_t store_transposed, - bool_t renumber, - bool_t check, - cugraph_graph_t** graph, - cugraph_error_t** error - ) - cdef cugraph_error_code_t \ cugraph_graph_create_sg_from_csr( const cugraph_resource_handle_t* handle, @@ -133,27 +75,7 @@ cdef extern from "cugraph_c/graph.h": const cugraph_type_erased_device_array_view_t* edge_type_ids, bool_t store_transposed, bool_t renumber, - bool_t check, - cugraph_graph_t** graph, - cugraph_error_t** error - ) - - cdef void \ - cugraph_sg_graph_free( - cugraph_graph_t* graph - ) - - cdef cugraph_error_code_t \ - cugraph_mg_graph_create( - const cugraph_resource_handle_t* handle, - const cugraph_graph_properties_t* properties, - const cugraph_type_erased_device_array_view_t* src, - const cugraph_type_erased_device_array_view_t* dst, - const cugraph_type_erased_device_array_view_t* weights, - const cugraph_type_erased_device_array_view_t* edge_ids, - const cugraph_type_erased_device_array_view_t* edge_type_ids, - bool_t store_transposed, - size_t num_edges, + bool_t symmetrize, bool_t check, cugraph_graph_t** graph, cugraph_error_t** error @@ -173,11 +95,7 @@ cdef extern from "cugraph_c/graph.h": size_t num_arrays, bool_t drop_self_loops, bool_t drop_multi_edges, + bool_t symmetrize, bool_t do_expensive_check, cugraph_graph_t** graph, cugraph_error_t** error) - - cdef void \ - cugraph_mg_graph_free( - cugraph_graph_t* graph - ) diff --git a/python/pylibcugraph/pylibcugraph/_cugraph_c/lookup_src_dst.pxd b/python/pylibcugraph/pylibcugraph/_cugraph_c/lookup_src_dst.pxd index 710ca7d113b..e8a2bbf47ae 100644 --- a/python/pylibcugraph/pylibcugraph/_cugraph_c/lookup_src_dst.pxd +++ b/python/pylibcugraph/pylibcugraph/_cugraph_c/lookup_src_dst.pxd @@ -70,3 +70,5 @@ cdef extern from "cugraph_c/lookup_src_dst.h": const cugraph_lookup_result_t* result) cdef void cugraph_lookup_result_free(cugraph_lookup_result_t* result) + + cdef void cugraph_lookup_container_free(cugraph_lookup_container_t* container) diff --git a/python/pylibcugraph/pylibcugraph/_cugraph_c/sampling_algorithms.pxd b/python/pylibcugraph/pylibcugraph/_cugraph_c/sampling_algorithms.pxd index 2af8e1d6d7e..f54d34d91d1 100644 --- a/python/pylibcugraph/pylibcugraph/_cugraph_c/sampling_algorithms.pxd +++ b/python/pylibcugraph/pylibcugraph/_cugraph_c/sampling_algorithms.pxd @@ -168,10 +168,10 @@ cdef extern from "cugraph_c/sampling_algorithms.h": const cugraph_resource_handle_t* handle, cugraph_rng_state_t* rng_state, cugraph_graph_t* graph, - size_t num_samples, const cugraph_type_erased_device_array_view_t* vertices, const cugraph_type_erased_device_array_view_t* src_bias, const cugraph_type_erased_device_array_view_t* dst_bias, + size_t num_samples, bool_t remove_duplicates, bool_t remove_false_negatives, bool_t exact_number_of_samples, diff --git a/python/pylibcugraph/pylibcugraph/biased_neighbor_sample.pyx b/python/pylibcugraph/pylibcugraph/biased_neighbor_sample.pyx index 77f1f04c394..2dd138d5d06 100644 --- a/python/pylibcugraph/pylibcugraph/biased_neighbor_sample.pyx +++ b/python/pylibcugraph/pylibcugraph/biased_neighbor_sample.pyx @@ -118,7 +118,7 @@ def biased_neighbor_sample(ResourceHandle resource_handle, Device array containing the list of starting vertices for sampling. h_fan_out: numpy array type - Host array containing the brancing out (fan-out) degrees per + Host array containing the branching out (fan-out) degrees per starting vertex for each hop level. with_replacement: bool diff --git a/python/pylibcugraph/pylibcugraph/edge_id_lookup_table.pxd b/python/pylibcugraph/pylibcugraph/edge_id_lookup_table.pxd new file mode 100644 index 00000000000..9bbd19963a7 --- /dev/null +++ b/python/pylibcugraph/pylibcugraph/edge_id_lookup_table.pxd @@ -0,0 +1,34 @@ +# 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. + +# Have cython use python 3 syntax +# cython: language_level = 3 + +from pylibcugraph._cugraph_c.error cimport ( + cugraph_error_code_t, + cugraph_error_t, +) +from pylibcugraph._cugraph_c.lookup_src_dst cimport ( + cugraph_lookup_container_t, +) +from pylibcugraph.resource_handle cimport ( + ResourceHandle, +) +from pylibcugraph.graphs cimport ( + _GPUGraph, +) + +cdef class EdgeIdLookupTable: + cdef ResourceHandle handle, + cdef _GPUGraph graph, + cdef cugraph_lookup_container_t* lookup_container_c_ptr diff --git a/python/pylibcugraph/pylibcugraph/edge_id_lookup_table.pyx b/python/pylibcugraph/pylibcugraph/edge_id_lookup_table.pyx new file mode 100644 index 00000000000..49ccdbdd168 --- /dev/null +++ b/python/pylibcugraph/pylibcugraph/edge_id_lookup_table.pyx @@ -0,0 +1,114 @@ +# 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. + +# Have cython use python 3 syntax +# cython: language_level = 3 + +from pylibcugraph._cugraph_c.resource_handle cimport ( + cugraph_resource_handle_t, +) +from pylibcugraph._cugraph_c.error cimport ( + cugraph_error_code_t, + cugraph_error_t, +) +from pylibcugraph._cugraph_c.array cimport ( + cugraph_type_erased_device_array_view_t, + cugraph_type_erased_device_array_view_create, + cugraph_type_erased_device_array_view_free, + cugraph_type_erased_host_array_view_t, + cugraph_type_erased_host_array_view_create, + cugraph_type_erased_host_array_view_free, +) +from pylibcugraph._cugraph_c.graph cimport ( + cugraph_graph_t, +) +from pylibcugraph._cugraph_c.lookup_src_dst cimport ( + cugraph_lookup_container_t, + cugraph_build_edge_id_and_type_to_src_dst_lookup_map, + cugraph_lookup_container_free, + cugraph_lookup_endpoints_from_edge_ids_and_single_type, + cugraph_lookup_result_t, +) +from pylibcugraph.utils cimport ( + assert_success, + assert_CAI_type, + assert_AI_type, + get_c_type_from_numpy_type, + create_cugraph_type_erased_device_array_view_from_py_obj +) +from pylibcugraph.resource_handle cimport ( + ResourceHandle, +) +from pylibcugraph.graphs cimport ( + _GPUGraph, +) +from pylibcugraph.internal_types.edge_id_lookup_result cimport ( + EdgeIdLookupResult, +) + +cdef class EdgeIdLookupTable: + def __cinit__(self, ResourceHandle resource_handle, _GPUGraph graph): + self.handle = resource_handle + self.graph = graph + + cdef cugraph_error_code_t error_code + cdef cugraph_error_t* error_ptr + + error_code = cugraph_build_edge_id_and_type_to_src_dst_lookup_map( + self.handle.c_resource_handle_ptr, + self.graph.c_graph_ptr, + &self.lookup_container_c_ptr, + &error_ptr, + ) + + assert_success(error_code, error_ptr, "cugraph_build_edge_id_and_type_to_src_dst_lookup_map") + + def __dealloc__(self): + if self.lookup_container_c_ptr is not NULL: + cugraph_lookup_container_free(self.lookup_container_c_ptr) + + def lookup_vertex_ids( + self, + edge_ids, + int edge_type + ): + """ + For a single edge type, finds the source and destination vertex ids corresponding + to the provided edge ids. + """ + + cdef cugraph_error_code_t error_code + cdef cugraph_error_t* error_ptr + cdef cugraph_lookup_result_t* result_ptr + + cdef cugraph_type_erased_device_array_view_t* edge_ids_c_ptr + edge_ids_c_ptr = create_cugraph_type_erased_device_array_view_from_py_obj(edge_ids) + + error_code = cugraph_lookup_endpoints_from_edge_ids_and_single_type( + self.handle.c_resource_handle_ptr, + self.graph.c_graph_ptr, + self.lookup_container_c_ptr, + edge_ids_c_ptr, + edge_type, + &result_ptr, + &error_ptr, + ) + + assert_success(error_code, error_ptr, "cugraph_lookup_endpoints_from_edge_ids_and_single_type") + + lr = EdgeIdLookupResult() + lr.set_ptr((result_ptr)) + return { + 'sources': lr.get_sources(), + 'destinations': lr.get_destinations(), + } diff --git a/python/pylibcugraph/pylibcugraph/graphs.pyx b/python/pylibcugraph/pylibcugraph/graphs.pyx index def47390ce5..ba32eb5b641 100644 --- a/python/pylibcugraph/pylibcugraph/graphs.pyx +++ b/python/pylibcugraph/pylibcugraph/graphs.pyx @@ -26,12 +26,8 @@ from pylibcugraph._cugraph_c.array cimport ( from pylibcugraph._cugraph_c.graph cimport ( cugraph_graph_create_sg, cugraph_graph_create_mg, - cugraph_sg_graph_create_from_csr, #FIXME: Remove this once - # 'cugraph_graph_create_sg_from_csr' is exposed cugraph_graph_create_sg_from_csr, - cugraph_sg_graph_free, #FIXME: Remove this cugraph_graph_free, - cugraph_mg_graph_free, #FIXME: Remove this ) from pylibcugraph.resource_handle cimport ( ResourceHandle, @@ -123,9 +119,17 @@ cdef class SGGraph(_GPUGraph): drop_self_loops : bool, optional (default='False') If true, drop any self loops that exist in the provided edge list. + Not supported for CSR graph. + drop_multi_edges: bool, optional (default='False') If true, drop any multi edges that exist in the provided edge list + Not supported for CSR graph. + + symmetrize: bool, optional (default='False') + If true, symmetrize the edge list + + Examples --------- >>> import pylibcugraph, cupy, numpy @@ -155,7 +159,8 @@ cdef class SGGraph(_GPUGraph): input_array_format="COO", vertices_array=None, drop_self_loops=False, - drop_multi_edges=False): + drop_multi_edges=False, + symmetrize=False): # FIXME: add tests for these if not(isinstance(store_transposed, (int, bool))): @@ -217,6 +222,7 @@ cdef class SGGraph(_GPUGraph): renumber, drop_self_loops, drop_multi_edges, + symmetrize, do_expensive_check, &(self.c_graph_ptr), &error_ptr) @@ -224,7 +230,7 @@ cdef class SGGraph(_GPUGraph): "cugraph_graph_create_sg()") elif input_array_format == "CSR": - error_code = cugraph_sg_graph_create_from_csr( + error_code = cugraph_graph_create_sg_from_csr( resource_handle.c_resource_handle_ptr, &(graph_properties.c_graph_properties), srcs_or_offsets_view_ptr, @@ -234,6 +240,7 @@ cdef class SGGraph(_GPUGraph): edge_type_view_ptr, store_transposed, renumber, + symmetrize, # drop_self_loops, #FIXME: Not supported yet # drop_multi_edges, #FIXME: Not supported yet do_expensive_check, @@ -259,7 +266,7 @@ cdef class SGGraph(_GPUGraph): def __dealloc__(self): if self.c_graph_ptr is not NULL: - cugraph_sg_graph_free(self.c_graph_ptr) + cugraph_graph_free(self.c_graph_ptr) cdef class MGGraph(_GPUGraph): @@ -325,6 +332,10 @@ cdef class MGGraph(_GPUGraph): drop_multi_edges: bool, optional (default='False') If true, drop any multi edges that exist in the provided edge list + + symmetrize: bool, optional (default='False') + If true, symmetrize the edge list + """ def __cinit__(self, ResourceHandle resource_handle, @@ -339,7 +350,8 @@ cdef class MGGraph(_GPUGraph): vertices_array=None, size_t num_arrays=1, # default value to not break users drop_self_loops=False, - drop_multi_edges=False): + drop_multi_edges=False, + symmetrize=False): if not(isinstance(store_transposed, (int, bool))): raise TypeError("expected int or bool for store_transposed, got " @@ -465,6 +477,7 @@ cdef class MGGraph(_GPUGraph): num_arrays, drop_self_loops, drop_multi_edges, + symmetrize, do_expensive_check, &(self.c_graph_ptr), &error_ptr) @@ -486,4 +499,4 @@ cdef class MGGraph(_GPUGraph): def __dealloc__(self): if self.c_graph_ptr is not NULL: - cugraph_mg_graph_free(self.c_graph_ptr) + cugraph_graph_free(self.c_graph_ptr) diff --git a/python/pylibcugraph/pylibcugraph/internal_types/CMakeLists.txt b/python/pylibcugraph/pylibcugraph/internal_types/CMakeLists.txt index 1ca169c5869..1b0d6ec71a4 100644 --- a/python/pylibcugraph/pylibcugraph/internal_types/CMakeLists.txt +++ b/python/pylibcugraph/pylibcugraph/internal_types/CMakeLists.txt @@ -1,5 +1,5 @@ # ============================================================================= -# Copyright (c) 2022, 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. You may obtain a copy of the License at @@ -14,6 +14,8 @@ set(cython_sources sampling_result.pyx + coo.pyx + edge_id_lookup_result.pyx ) set(linked_libraries cugraph::cugraph;cugraph::cugraph_c) diff --git a/python/pylibcugraph/pylibcugraph/internal_types/coo.pxd b/python/pylibcugraph/pylibcugraph/internal_types/coo.pxd new file mode 100644 index 00000000000..129b0be4dbe --- /dev/null +++ b/python/pylibcugraph/pylibcugraph/internal_types/coo.pxd @@ -0,0 +1,28 @@ +# 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. + +# Have cython use python 3 syntax +# cython: language_level = 3 + + +from pylibcugraph._cugraph_c.coo cimport ( + cugraph_coo_t, +) +from pylibcugraph._cugraph_c.array cimport ( + cugraph_type_erased_device_array_view_t, +) + +cdef class COO: + cdef cugraph_coo_t* c_coo_ptr + cdef set_ptr(self, cugraph_coo_t* ptr) + cdef get_array(self, cugraph_type_erased_device_array_view_t* ptr) diff --git a/python/pylibcugraph/pylibcugraph/internal_types/coo.pyx b/python/pylibcugraph/pylibcugraph/internal_types/coo.pyx new file mode 100644 index 00000000000..64d10c22eaf --- /dev/null +++ b/python/pylibcugraph/pylibcugraph/internal_types/coo.pyx @@ -0,0 +1,96 @@ +# 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. + +# Have cython use python 3 syntax +# cython: language_level = 3 + +from pylibcugraph._cugraph_c.coo cimport ( + cugraph_coo_t, + cugraph_coo_free, + cugraph_coo_get_sources, + cugraph_coo_get_destinations, + cugraph_coo_get_edge_weights, + cugraph_coo_get_edge_id, + cugraph_coo_get_edge_type, +) +from pylibcugraph._cugraph_c.array cimport ( + cugraph_type_erased_device_array_view_t, +) +from pylibcugraph.utils cimport create_cupy_array_view_for_device_ptr + +cdef class COO: + """ + Cython interface to a cugraph_coo_t pointer. Instances of this + call will take ownership of the pointer and free it under standard python + GC rules (ie. when all references to it are no longer present). + + This class provides methods to return non-owning cupy ndarrays for the + corresponding array members. Returning these cupy arrays increments the ref + count on the COO instances from which the cupy arrays are + referencing. + """ + def __cinit__(self): + # This COO instance owns sample_result_ptr now. It will be + # freed when this instance is deleted (see __dealloc__()) + self.c_coo_ptr = NULL + + def __dealloc__(self): + if self.c_coo_ptr is not NULL: + cugraph_coo_free(self.c_coo_ptr) + + cdef set_ptr(self, cugraph_coo_t* ptr): + self.c_coo_ptr = ptr + + cdef get_array(self, cugraph_type_erased_device_array_view_t* ptr): + if ptr is NULL: + return None + + return create_cupy_array_view_for_device_ptr( + ptr, + self, + ) + + def get_sources(self): + if self.c_coo_ptr is NULL: + raise ValueError("pointer not set, must call set_ptr() with a " + "non-NULL value first.") + cdef cugraph_type_erased_device_array_view_t* ptr = cugraph_coo_get_sources(self.c_coo_ptr) + return self.get_array(ptr) + + def get_destinations(self): + if self.c_coo_ptr is NULL: + raise ValueError("pointer not set, must call set_ptr() with a " + "non-NULL value first.") + cdef cugraph_type_erased_device_array_view_t* ptr = cugraph_coo_get_destinations(self.c_coo_ptr) + return self.get_array(ptr) + + def get_edge_ids(self): + if self.c_coo_ptr is NULL: + raise ValueError("pointer not set, must call set_ptr() with a " + "non-NULL value first.") + cdef cugraph_type_erased_device_array_view_t* ptr = cugraph_coo_get_edge_id(self.c_coo_ptr) + return self.get_array(ptr) + + def get_edge_types(self): + if self.c_coo_ptr is NULL: + raise ValueError("pointer not set, must call set_ptr() with a " + "non-NULL value first.") + cdef cugraph_type_erased_device_array_view_t* ptr = cugraph_coo_get_edge_type(self.c_coo_ptr) + return self.get_array(ptr) + + def get_edge_weights(self): + if self.c_coo_ptr is NULL: + raise ValueError("pointer not set, must call set_ptr() with a " + "non-NULL value first.") + cdef cugraph_type_erased_device_array_view_t* ptr = cugraph_coo_get_edge_weights(self.c_coo_ptr) + return self.get_array(ptr) diff --git a/python/pylibcugraph/pylibcugraph/internal_types/edge_id_lookup_result.pxd b/python/pylibcugraph/pylibcugraph/internal_types/edge_id_lookup_result.pxd new file mode 100644 index 00000000000..68dd2362a00 --- /dev/null +++ b/python/pylibcugraph/pylibcugraph/internal_types/edge_id_lookup_result.pxd @@ -0,0 +1,30 @@ +# 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. + +# Have cython use python 3 syntax +# cython: language_level = 3 + + +from pylibcugraph._cugraph_c.lookup_src_dst cimport ( + cugraph_lookup_result_t +) +from pylibcugraph._cugraph_c.array cimport ( + cugraph_type_erased_device_array_view_t, +) + +cdef class EdgeIdLookupResult: + cdef cugraph_lookup_result_t* result_c_ptr + + cdef get_array(self, cugraph_type_erased_device_array_view_t* ptr) + + cdef set_ptr(self, cugraph_lookup_result_t* ptr) diff --git a/python/pylibcugraph/pylibcugraph/internal_types/edge_id_lookup_result.pyx b/python/pylibcugraph/pylibcugraph/internal_types/edge_id_lookup_result.pyx new file mode 100644 index 00000000000..5f7165ce988 --- /dev/null +++ b/python/pylibcugraph/pylibcugraph/internal_types/edge_id_lookup_result.pyx @@ -0,0 +1,63 @@ +# 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. + +# Have cython use python 3 syntax +# cython: language_level = 3 + +from pylibcugraph._cugraph_c.lookup_src_dst cimport ( + cugraph_lookup_result_t, + cugraph_lookup_result_free, + cugraph_lookup_result_get_dsts, + cugraph_lookup_result_get_srcs, +) +from pylibcugraph._cugraph_c.array cimport ( + cugraph_type_erased_device_array_view_t, +) +from pylibcugraph.utils cimport ( + create_cupy_array_view_for_device_ptr, +) + +cdef class EdgeIdLookupResult: + def __cinit__(self): + """ + Sets this object as the owner of the given pointer. + """ + self.result_c_ptr = NULL + + cdef set_ptr(self, cugraph_lookup_result_t* ptr): + self.result_c_ptr = ptr + + def __dealloc__(self): + if self.result_c_ptr is not NULL: + cugraph_lookup_result_free(self.result_c_ptr) + + cdef get_array(self, cugraph_type_erased_device_array_view_t* ptr): + if ptr is NULL: + return None + + return create_cupy_array_view_for_device_ptr( + ptr, + self, + ) + + def get_sources(self): + if self.result_c_ptr is NULL: + return None + cdef cugraph_type_erased_device_array_view_t* ptr = cugraph_lookup_result_get_srcs(self.result_c_ptr) + return self.get_array(ptr) + + def get_destinations(self): + if self.result_c_ptr is NULL: + return None + cdef cugraph_type_erased_device_array_view_t* ptr = cugraph_lookup_result_get_dsts(self.result_c_ptr) + return self.get_array(ptr) diff --git a/python/pylibcugraph/pylibcugraph/negative_sampling.pyx b/python/pylibcugraph/pylibcugraph/negative_sampling.pyx new file mode 100644 index 00000000000..610cfa90ccf --- /dev/null +++ b/python/pylibcugraph/pylibcugraph/negative_sampling.pyx @@ -0,0 +1,184 @@ +# 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. + +# Have cython use python 3 syntax +# cython: language_level = 3 + +from libc.stdint cimport uintptr_t + +from pylibcugraph._cugraph_c.resource_handle cimport ( + cugraph_resource_handle_t, + bool_t, +) +from pylibcugraph._cugraph_c.error cimport ( + cugraph_error_code_t, + cugraph_error_t, +) +from pylibcugraph._cugraph_c.array cimport ( + cugraph_type_erased_device_array_view_t, + cugraph_type_erased_device_array_view_create, + cugraph_type_erased_device_array_view_free, + cugraph_type_erased_host_array_view_t, + cugraph_type_erased_host_array_view_create, + cugraph_type_erased_host_array_view_free, +) +from pylibcugraph.resource_handle cimport ( + ResourceHandle, +) +from pylibcugraph.graphs cimport ( + _GPUGraph, +) +from pylibcugraph._cugraph_c.graph cimport ( + cugraph_graph_t, +) +from pylibcugraph._cugraph_c.sampling_algorithms cimport ( + cugraph_negative_sampling, +) +from pylibcugraph._cugraph_c.coo cimport ( + cugraph_coo_t, +) +from pylibcugraph.internal_types.coo cimport ( + COO, +) +from pylibcugraph.utils cimport ( + assert_success, + assert_CAI_type, + create_cugraph_type_erased_device_array_view_from_py_obj, +) +from pylibcugraph._cugraph_c.random cimport ( + cugraph_rng_state_t +) +from pylibcugraph.random cimport ( + CuGraphRandomState +) + +def negative_sampling(ResourceHandle resource_handle, + _GPUGraph graph, + size_t num_samples, + random_state=None, + vertices=None, + src_bias=None, + dst_bias=None, + remove_duplicates=False, + remove_false_negatives=False, + exact_number_of_samples=False, + do_expensive_check=False): + """ + Performs negative sampling, which is essentially a form of graph generation. + + By setting vertices, src_bias, and dst_bias, this function can perform + biased negative sampling. + + Parameters + ---------- + resource_handle: ResourceHandle + Handle to the underlying device and host resources needed for + referencing data and running algorithms. + input_graph: SGGraph or MGGraph + The stored cuGraph graph to create negative samples for. + num_samples: int + The number of negative edges to generate for each positive edge. + random_state: int (Optional) + Random state to use when generating samples. Optional argument, + defaults to a hash of process id, time, and hostname. + (See pylibcugraph.random.CuGraphRandomState) + vertices: device array type (Optional) + Vertex ids corresponding to the src/dst biases, if provided. + Ignored if src/dst biases are not provided. + src_bias: device array type (Optional) + Probability per edge that a vertex is selected as a source vertex. + Does not have to be normalized. Uses a uniform distribution if + not provided. + dst_bias: device array type (Optional) + Probability per edge that a vertex is selected as a destination vertex. + Does not have to be normalized. Uses a uniform distribution if + not provided. + remove_duplicates: bool (Optional) + Whether to remove duplicate edges from the generated edgelist. + Defaults to False (does not remove duplicates). + remove_false_negatives: bool (Optional) + Whether to remove false negatives from the generated edgelist. + Defaults to False (does not check for and remove false negatives). + exact_number_of_samples: bool (Optional) + Whether to manually regenerate samples until the desired number + as specified by num_samples has been generated. + Defaults to False (does not regenerate if enough samples are not + produced in the initial round). + do_expensive_check: bool (Optional) + Whether to perform an expensive error check at the C++ level. + Defaults to False (no error check). + + Returns + ------- + dict[str, cupy.ndarray] + Generated edges in COO format. + """ + + assert_CAI_type(vertices, "vertices", True) + assert_CAI_type(src_bias, "src_bias", True) + assert_CAI_type(dst_bias, "dst_bias", True) + + cdef cugraph_resource_handle_t* c_resource_handle_ptr = ( + resource_handle.c_resource_handle_ptr + ) + + cdef cugraph_graph_t* c_graph_ptr = graph.c_graph_ptr + + cdef bool_t c_remove_duplicates = remove_duplicates + cdef bool_t c_remove_false_negatives = remove_false_negatives + cdef bool_t c_exact_number_of_samples = exact_number_of_samples + cdef bool_t c_do_expensive_check = do_expensive_check + + cg_rng_state = CuGraphRandomState(resource_handle, random_state) + + cdef cugraph_rng_state_t* rng_state_ptr = \ + cg_rng_state.rng_state_ptr + + cdef cugraph_type_erased_device_array_view_t* vertices_ptr = \ + create_cugraph_type_erased_device_array_view_from_py_obj(vertices) + cdef cugraph_type_erased_device_array_view_t* src_bias_ptr = \ + create_cugraph_type_erased_device_array_view_from_py_obj(src_bias) + cdef cugraph_type_erased_device_array_view_t* dst_bias_ptr = \ + create_cugraph_type_erased_device_array_view_from_py_obj(dst_bias) + + cdef cugraph_coo_t* result_ptr + cdef cugraph_error_t* err_ptr + cdef cugraph_error_code_t error_code + + error_code = cugraph_negative_sampling( + c_resource_handle_ptr, + rng_state_ptr, + c_graph_ptr, + vertices_ptr, + src_bias_ptr, + dst_bias_ptr, + num_samples, + c_remove_duplicates, + c_remove_false_negatives, + c_exact_number_of_samples, + c_do_expensive_check, + &result_ptr, + &err_ptr, + ) + assert_success(error_code, err_ptr, "cugraph_negative_sampling") + + coo = COO() + coo.set_ptr(result_ptr) + + return { + 'sources': coo.get_sources(), + 'destinations': coo.get_destinations(), + 'edge_id': coo.get_edge_ids(), + 'edge_type': coo.get_edge_types(), + 'weight': coo.get_edge_weights(), + } diff --git a/python/pylibcugraph/pylibcugraph/tests/test_lookup_table.py b/python/pylibcugraph/pylibcugraph/tests/test_lookup_table.py new file mode 100644 index 00000000000..2910a5f8d4d --- /dev/null +++ b/python/pylibcugraph/pylibcugraph/tests/test_lookup_table.py @@ -0,0 +1,80 @@ +# 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 cupy + +from pylibcugraph import ( + SGGraph, + ResourceHandle, + GraphProperties, + EdgeIdLookupTable, +) + + +# ============================================================================= +# Pytest fixtures +# ============================================================================= +# fixtures used in this test module are defined in conftest.py + + +# ============================================================================= +# Tests +# ============================================================================= + + +def test_lookup_table(): + # Vertex id array + vtcs = cupy.arange(6, dtype="int64") + + # Edge ids are unique per edge type and start from 0 + # Each edge type has the same src/dst vertex type here, + # just as it would in a GNN application. + srcs = cupy.array([0, 1, 5, 4, 3, 2, 2, 0, 5, 4, 4, 5]) + dsts = cupy.array([1, 5, 0, 3, 2, 1, 3, 3, 2, 3, 1, 4]) + etps = cupy.array([0, 2, 6, 7, 4, 3, 4, 1, 7, 7, 6, 8], dtype="int32") + eids = cupy.array([0, 0, 0, 0, 0, 0, 1, 0, 1, 2, 1, 0]) + + wgts = cupy.ones((len(srcs),), dtype="float32") + + graph = SGGraph( + resource_handle=ResourceHandle(), + graph_properties=GraphProperties(is_symmetric=False, is_multigraph=True), + src_or_offset_array=srcs, + dst_or_index_array=dsts, + vertices_array=vtcs, + weight_array=wgts, + edge_id_array=eids, + edge_type_array=etps, + store_transposed=False, + renumber=False, + do_expensive_check=True, + ) + + table = EdgeIdLookupTable(ResourceHandle(), graph) + + assert table is not None + + found_edges = table.lookup_vertex_ids(cupy.array([0, 1, 2, 3, 4]), 7) + assert (found_edges["sources"] == cupy.array([4, 5, 4, -1, -1])).all() + assert (found_edges["destinations"] == cupy.array([3, 2, 3, -1, -1])).all() + + found_edges = table.lookup_vertex_ids(cupy.array([0]), 5) + assert (found_edges["sources"] == cupy.array([-1])).all() + assert (found_edges["destinations"] == cupy.array([-1])).all() + + found_edges = table.lookup_vertex_ids(cupy.array([3, 1, 0, 5]), 6) + assert (found_edges["sources"] == cupy.array([-1, 4, 5, -1])).all() + assert (found_edges["destinations"] == cupy.array([-1, 1, 0, -1])).all() + + # call __dealloc__() + del table diff --git a/python/pylibcugraph/pylibcugraph/uniform_neighbor_sample.pyx b/python/pylibcugraph/pylibcugraph/uniform_neighbor_sample.pyx index c25c9119985..f3e2336d8f6 100644 --- a/python/pylibcugraph/pylibcugraph/uniform_neighbor_sample.pyx +++ b/python/pylibcugraph/pylibcugraph/uniform_neighbor_sample.pyx @@ -117,7 +117,7 @@ def uniform_neighbor_sample(ResourceHandle resource_handle, Device array containing the list of starting vertices for sampling. h_fan_out: numpy array type - Host array containing the brancing out (fan-out) degrees per + Host array containing the branching out (fan-out) degrees per starting vertex for each hop level. with_replacement: bool diff --git a/python/pylibcugraph/pyproject.toml b/python/pylibcugraph/pyproject.toml index 92c417f0372..c12280473b5 100644 --- a/python/pylibcugraph/pyproject.toml +++ b/python/pylibcugraph/pyproject.toml @@ -27,8 +27,8 @@ dependencies = [ "nvidia-curand", "nvidia-cusolver", "nvidia-cusparse", - "pylibraft==24.10.*,>=0.0.0a0", - "rmm==24.10.*,>=0.0.0a0", + "pylibraft==24.12.*,>=0.0.0a0", + "rmm==24.12.*,>=0.0.0a0", ] # This list was generated by `rapids-dependency-file-generator`. To make changes, edit ../../dependencies.yaml and run `rapids-dependency-file-generator`. classifiers = [ "Intended Audience :: Developers", @@ -40,8 +40,8 @@ classifiers = [ [project.optional-dependencies] test = [ - "cudf==24.10.*,>=0.0.0a0", - "numpy>=1.23,<2.0a0", + "cudf==24.12.*,>=0.0.0a0", + "numpy>=1.23,<3.0a0", "pandas", "pytest", "pytest-benchmark", @@ -74,7 +74,7 @@ dependencies-file = "../../dependencies.yaml" requires = [ "cmake>=3.26.4,!=3.30.0", "ninja", - "pylibraft==24.10.*,>=0.0.0a0", - "rmm==24.10.*,>=0.0.0a0", + "pylibraft==24.12.*,>=0.0.0a0", + "rmm==24.12.*,>=0.0.0a0", ] # This list was generated by `rapids-dependency-file-generator`. To make changes, edit ../../dependencies.yaml and run `rapids-dependency-file-generator`. matrix-entry = "cuda_suffixed=true;use_cuda_wheels=true" diff --git a/python/pylibcugraph/pytest.ini b/python/pylibcugraph/pytest.ini index 573628de680..d5ade9f4836 100644 --- a/python/pylibcugraph/pytest.ini +++ b/python/pylibcugraph/pytest.ini @@ -14,3 +14,5 @@ [pytest] markers = cugraph_ops: Tests requiring cugraph-ops + +addopts = --tb=native diff --git a/readme_pages/pylibcugraph.md b/readme_pages/pylibcugraph.md index 3bb552141e9..fcb5a624931 100644 --- a/readme_pages/pylibcugraph.md +++ b/readme_pages/pylibcugraph.md @@ -4,7 +4,7 @@


-CuGraph pylibcugraph +cuGraph pylibcugraph

Part of [RAPIDS](https://rapids.ai) cuGraph, pylibcugraph is a wrapper around the cuGraph C API. It is aimed more at integrators instead of algorithm writers or end users like Data Scientists. Most of the cuGraph python API uses pylibcugraph to efficiently run algorithms by removing much of the overhead of the python-centric implementation, relying more on cython instead. Pylibcugraph is intended for applications that require a tighter integration with cuGraph at the Python layer with fewer dependencies.