Skip to content

Commit

Permalink
Added guards for preventing k-truss execution on CUDA 11.4 systems (#…
Browse files Browse the repository at this point in the history
…1773)

Added guards for preventing k-truss execution on CUDA 11.4 systems and the appropriate user-friendly messaging, along with a new unit test.
Also updated the k-truss notebook with a note about the unsupported CUDA version and a comment to skip automated tests on CUDA 11.4, along with updates to the notebook skip mechanism to also look at CUDA version.

Tested on a CUDA 11.2 system by changing the unsupported version to 11.2 to verify correct behavior.

Behavior on a CUDA 11.4 systems should be to allow cugraph to be imported as always, but if the user calls k_truss or kturss_subgraph, a NotImplementedError exception with "is not currently supported in CUDA 11.4 environments" message is raised. If the user directly imports the module (ie. from cugraph.community.ktruss_subgraph import k_truss), the exception is raised immediately.

Behavior on non-CUDA 11.4 systems should be exactly the same as prior to this change.
  • Loading branch information
rlratzel authored Aug 16, 2021
1 parent f7c22a6 commit 97bfeed
Show file tree
Hide file tree
Showing 5 changed files with 87 additions and 10 deletions.
8 changes: 7 additions & 1 deletion ci/gpu/notebook_list.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,12 +17,12 @@

from numba import cuda

cuda_version_string = ".".join([str(n) for n in cuda.runtime.get_version()])
#
# Not strictly true... however what we mean is
# Pascal or earlier
#
pascal = False

device = cuda.get_current_device()
# check for the attribute using both pre and post numba 0.53 names
cc = getattr(device, 'COMPUTE_CAPABILITY', None) or \
Expand All @@ -45,6 +45,12 @@
print(f'SKIPPING {filename} (does not run on Pascal)', file=sys.stderr)
skip = True
break;
elif re.search('# Does not run on CUDA ', line) and \
(cuda_version_string in line):
print(f'SKIPPING {filename} (does not run on CUDA {cuda_version_string})',
file=sys.stderr)
skip = True
break;

if not skip:
print(filename)
10 changes: 3 additions & 7 deletions notebooks/cores/ktruss.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -5,25 +5,21 @@
"metadata": {},
"source": [
"# K-Truss\n",
"# Does not run on CUDA 11.4\n",
"\n",
"\n",
"In this notebook, we will use cuGraph to identify the K-Truss clusters in a test graph \n",
"\n",
"Notebook Credits\n",
"* Original Authors: Bradley Rees\n",
"* Created: 10/28/2019\n",
"* Last Edit: 08/16/2020\n",
"\n",
"RAPIDS Versions: 0.13\n",
"\n",
"Test Hardware\n",
"* GV100 32G, CUDA 10.2\n",
"\n",
"* Last Edit: 08/13/2021\n",
"\n",
"\n",
"## Introduction\n",
"\n",
"Compute the k-truss of the graph G. A K-Truss is a relaxed cliques where every vertex is supported by at least k-2 triangle.\n",
"NOTE: k-truss is currently not supported on CUDA 11.4 systems.\n",
"\n",
"Ref:\n",
"\n",
Expand Down
35 changes: 33 additions & 2 deletions python/cugraph/community/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,38 @@
)
from cugraph.community.subgraph_extraction import subgraph
from cugraph.community.triangle_count import triangles
from cugraph.community.ktruss_subgraph import ktruss_subgraph
from cugraph.community.ktruss_subgraph import k_truss
from cugraph.community.egonet import ego_graph
from cugraph.community.egonet import batched_ego_graphs

# FIXME: special case for ktruss on CUDA 11.4: an 11.4 bug causes ktruss to
# crash in that environment. Allow ktruss to import on non-11.4 systems, but
# replace ktruss with a __UnsupportedModule instance, which lazily raises an
# exception when referenced.
from numba import cuda
__cuda_version = cuda.runtime.get_version()
__ktruss_unsupported_cuda_version = (11, 4)

class __UnsupportedModule:
def __init__(self, exception):
self.__exception = exception

def __getattr__(self, attr):
raise self.__exception

def __call__(self, *args, **kwargs):
raise self.__exception


if __cuda_version != __ktruss_unsupported_cuda_version:
from cugraph.community.ktruss_subgraph import ktruss_subgraph
from cugraph.community.ktruss_subgraph import k_truss
else:
__kuvs = ".".join([str(n) for n in __ktruss_unsupported_cuda_version])
k_truss = __UnsupportedModule(
NotImplementedError("k_truss is not currently supported in CUDA"
f" {__kuvs} environments.")
)
ktruss_subgraph = __UnsupportedModule(
NotImplementedError("ktruss_subgraph is not currently supported in CUDA"
f" {__kuvs} environments.")
)
15 changes: 15 additions & 0 deletions python/cugraph/community/ktruss_subgraph.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,24 @@
from cugraph.utilities import check_nx_graph
from cugraph.utilities import cugraph_to_nx

# FIXME: special case for ktruss on CUDA 11.4: an 11.4 bug causes ktruss to
# crash in that environment. Allow ktruss to import on non-11.4 systems, but
# raise an exception if ktruss is directly imported on 11.4.
from numba import cuda
__cuda_version = cuda.runtime.get_version()
__ktruss_unsupported_cuda_version = (11, 4)
if __cuda_version == __ktruss_unsupported_cuda_version:
__kuvs = ".".join([str(n) for n in __ktruss_unsupported_cuda_version])
raise NotImplementedError("k_truss is not currently supported in CUDA"
f" {__kuvs} environments.")


def k_truss(G, k):
"""
Returns the K-Truss subgraph of a graph for a specific k.
NOTE: this function is currently not available on CUDA 11.4 systems.
The k-truss of a graph is a subgraph where each edge is part of at least
(k−2) triangles. K-trusses are used for finding tighlty knit groups of
vertices in a graph. A k-truss is a relaxation of a k-clique in the graph
Expand Down Expand Up @@ -60,6 +73,8 @@ def ktruss_subgraph(G, k, use_weights=True):
"""
Returns the K-Truss subgraph of a graph for a specific k.
NOTE: this function is currently not available on CUDA 11.4 systems.
The k-truss of a graph is a subgraph where each edge is part of at least
(k−2) triangles. K-trusses are used for finding tighlty knit groups of
vertices in a graph. A k-truss is a relaxation of a k-clique in the graph
Expand Down
29 changes: 29 additions & 0 deletions python/cugraph/tests/test_k_truss_subgraph.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
from cugraph.tests import utils

import numpy as np
from numba import cuda

# Temporarily suppress warnings till networkX fixes deprecation warnings
# (Using or importing the ABCs from 'collections' instead of from
Expand Down Expand Up @@ -73,6 +74,31 @@ def compare_k_truss(k_truss_cugraph, k, ground_truth_file):
return True


__cuda_version = cuda.runtime.get_version()
__unsupported_cuda_version = (11, 4)


# FIXME: remove when ktruss is supported on CUDA 11.4
def test_unsupported_cuda_version():
"""
Ensures the proper exception is raised when ktruss is called in an
unsupported env, and not when called in a supported env.
"""
k = 5
cu_M = utils.read_csv_file(utils.DATASETS_KTRUSS[0][0])
G = cugraph.Graph()
G.from_cudf_edgelist(cu_M, source="0", destination="1", edge_attr="2")

if __cuda_version == __unsupported_cuda_version:
with pytest.raises(NotImplementedError):
cugraph.k_truss(G, k)
else:
cugraph.k_truss(G, k)


@pytest.mark.skipif((__cuda_version == __unsupported_cuda_version),
reason="skipping on unsupported CUDA "
f"{__unsupported_cuda_version} environment.")
@pytest.mark.parametrize("graph_file, nx_ground_truth", utils.DATASETS_KTRUSS)
def test_ktruss_subgraph_Graph(graph_file, nx_ground_truth):
gc.collect()
Expand All @@ -86,6 +112,9 @@ def test_ktruss_subgraph_Graph(graph_file, nx_ground_truth):
compare_k_truss(k_subgraph, k, nx_ground_truth)


@pytest.mark.skipif((__cuda_version == __unsupported_cuda_version),
reason="skipping on unsupported CUDA "
f"{__unsupported_cuda_version} environment.")
@pytest.mark.parametrize("graph_file, nx_ground_truth", utils.DATASETS_KTRUSS)
def test_ktruss_subgraph_Graph_nx(graph_file, nx_ground_truth):
gc.collect()
Expand Down

0 comments on commit 97bfeed

Please sign in to comment.