diff --git a/python/cugraph/cugraph/dask/centrality/katz_centrality.py b/python/cugraph/cugraph/dask/centrality/katz_centrality.py index 1fd3602593e..2897450a7ae 100644 --- a/python/cugraph/cugraph/dask/centrality/katz_centrality.py +++ b/python/cugraph/cugraph/dask/centrality/katz_centrality.py @@ -72,7 +72,7 @@ def katz_centrality(input_graph, ---------- input_graph : cuGraph.Graph cuGraph graph descriptor with connectivity information. The graph can - contain either directed (DiGraph) or undirected edges (Graph). + contain either directed or undirected edges. alpha : float, optional (default=None) Attenuation factor. If alpha is not specified then diff --git a/python/cugraph/cugraph/dask/link_analysis/pagerank.py b/python/cugraph/cugraph/dask/link_analysis/pagerank.py index fda70deb2ac..6805d8690ce 100644 --- a/python/cugraph/cugraph/dask/link_analysis/pagerank.py +++ b/python/cugraph/cugraph/dask/link_analysis/pagerank.py @@ -74,7 +74,7 @@ def pagerank(input_graph, input_graph : cugraph.DiGraph cuGraph graph descriptor, should contain the connectivity information as dask cudf edge list dataframe(edge weights are not used for this - algorithm). Undirected Graph not currently supported. + algorithm). alpha : float, optional (default=0.85) The damping factor alpha represents the probability to follow an diff --git a/python/cugraph/cugraph/dask/sampling/neighborhood_sampling.py b/python/cugraph/cugraph/dask/sampling/neighborhood_sampling.py index b7e842c6f31..fb79ada22fd 100644 --- a/python/cugraph/cugraph/dask/sampling/neighborhood_sampling.py +++ b/python/cugraph/cugraph/dask/sampling/neighborhood_sampling.py @@ -95,7 +95,7 @@ def EXPERIMENTAL__uniform_neighborhood(input_graph, Parameters ---------- - input_graph : cugraph.DiGraph + input_graph : cugraph.Graph cuGraph graph, which contains connectivity information as dask cudf edge list dataframe diff --git a/python/cugraph/cugraph/dask/traversal/bfs.py b/python/cugraph/cugraph/dask/traversal/bfs.py index 539d385effd..43883073730 100644 --- a/python/cugraph/cugraph/dask/traversal/bfs.py +++ b/python/cugraph/cugraph/dask/traversal/bfs.py @@ -66,10 +66,10 @@ def bfs(input_graph, Parameters ---------- - input_graph : directed cugraph.Graph + input_graph : cugraph.Graph cuGraph graph instance, should contain the connectivity information as dask cudf edge list dataframe(edge weights are not used for this - algorithm). Undirected Graph not currently supported. + algorithm). start : Integer Specify starting vertex for breadth-first search; this function diff --git a/python/cugraph/cugraph/dask/traversal/sssp.py b/python/cugraph/cugraph/dask/traversal/sssp.py index dddd390fb9e..d174f02dc4a 100644 --- a/python/cugraph/cugraph/dask/traversal/sssp.py +++ b/python/cugraph/cugraph/dask/traversal/sssp.py @@ -63,10 +63,9 @@ def sssp(input_graph, source): Parameters ---------- - input_graph : directed cugraph.Graph + input_graph : cugraph.Graph cuGraph graph descriptor, should contain the connectivity information as dask cudf edge list dataframe. - Undirected Graph not currently supported. source : Integer Specify source vertex diff --git a/python/cugraph/cugraph/link_prediction/jaccard.py b/python/cugraph/cugraph/link_prediction/jaccard.py index 8c9ad6754db..10bfd35f252 100644 --- a/python/cugraph/cugraph/link_prediction/jaccard.py +++ b/python/cugraph/cugraph/link_prediction/jaccard.py @@ -12,7 +12,6 @@ # limitations under the License. import cudf -from cugraph.structure.graph_classes import Graph from cugraph.link_prediction import jaccard_wrapper from cugraph.utilities import (ensure_cugraph_obj_for_nx, df_edge_score_to_dictionary, @@ -108,9 +107,8 @@ def jaccard(input_graph, vertex_pair=None): >>> df = cugraph.jaccard(G) """ - if type(input_graph) is not Graph: - raise TypeError("input graph must a Graph") - + if input_graph.is_directed(): + raise ValueError("Input must be an undirected Graph.") if type(vertex_pair) == cudf.DataFrame: vertex_pair = renumber_vertex_pair(input_graph, vertex_pair) elif vertex_pair is not None: diff --git a/python/cugraph/cugraph/structure/graph_implementation/simpleDistributedGraph.py b/python/cugraph/cugraph/structure/graph_implementation/simpleDistributedGraph.py index 01616e397cf..203efd1bcb7 100644 --- a/python/cugraph/cugraph/structure/graph_implementation/simpleDistributedGraph.py +++ b/python/cugraph/cugraph/structure/graph_implementation/simpleDistributedGraph.py @@ -64,8 +64,6 @@ def __from_edgelist( ): if not isinstance(input_ddf, dask_cudf.DataFrame): raise TypeError("input should be a dask_cudf dataFrame") - if self.properties.directed is False: - raise TypeError("Undirected distributed graph not supported") s_col = source d_col = destination diff --git a/python/cugraph/cugraph/tests/dask/test_mg_bfs.py b/python/cugraph/cugraph/tests/dask/test_mg_bfs.py index 58b18a02cf5..f5aa1a05b98 100644 --- a/python/cugraph/cugraph/tests/dask/test_mg_bfs.py +++ b/python/cugraph/cugraph/tests/dask/test_mg_bfs.py @@ -11,6 +11,7 @@ # See the License for the specific language governing permissions and # limitations under the License. +import pytest import cugraph.dask as dcg import gc # import pytest @@ -20,12 +21,23 @@ # from cugraph.dask.common.mg_utils import is_single_gpu from cugraph.tests.utils import RAPIDS_DATASET_ROOT_DIR_PATH +# ============================================================================= +# Pytest Setup / Teardown - called for each test function +# ============================================================================= + + +def setup_function(): + gc.collect() + + +IS_DIRECTED = [True, False] + # @pytest.mark.skipif( # is_single_gpu(), reason="skipping MG testing on Single GPU system" # ) -def test_dask_bfs(dask_client): - gc.collect() +@pytest.mark.parametrize("directed", IS_DIRECTED) +def test_dask_bfs(dask_client, directed): input_data_path = (RAPIDS_DATASET_ROOT_DIR_PATH / "netscience.csv").as_posix() @@ -60,10 +72,10 @@ def modify_dataset(df): df = modify_dataset(df) - g = cugraph.Graph(directed=True) + g = cugraph.Graph(directed=directed) g.from_cudf_edgelist(df, "src", "dst") - dg = cugraph.Graph(directed=True) + dg = cugraph.Graph(directed=directed) dg.from_dask_cudf_edgelist(ddf, "src", "dst") expected_dist = cugraph.bfs(g, [0, 1000]) @@ -88,7 +100,8 @@ def modify_dataset(df): # @pytest.mark.skipif( # is_single_gpu(), reason="skipping MG testing on Single GPU system" # ) -def test_dask_bfs_multi_column_depthlimit(dask_client): +@pytest.mark.parametrize("directed", IS_DIRECTED) +def test_dask_bfs_multi_column_depthlimit(dask_client, directed): gc.collect() input_data_path = (RAPIDS_DATASET_ROOT_DIR_PATH / @@ -115,10 +128,10 @@ def test_dask_bfs_multi_column_depthlimit(dask_client): df['src_b'] = df['src_a'] + 1000 df['dst_b'] = df['dst_a'] + 1000 - g = cugraph.Graph(directed=True) + g = cugraph.Graph(directed=directed) g.from_cudf_edgelist(df, ["src_a", "src_b"], ["dst_a", "dst_b"]) - dg = cugraph.Graph(directed=True) + dg = cugraph.Graph(directed=directed) dg.from_dask_cudf_edgelist(ddf, ["src_a", "src_b"], ["dst_a", "dst_b"]) start = cudf.DataFrame() diff --git a/python/cugraph/cugraph/tests/dask/test_mg_comms.py b/python/cugraph/cugraph/tests/dask/test_mg_comms.py index 2c02779f199..cb3dfdc3eb7 100644 --- a/python/cugraph/cugraph/tests/dask/test_mg_comms.py +++ b/python/cugraph/cugraph/tests/dask/test_mg_comms.py @@ -11,6 +11,7 @@ # See the License for the specific language governing permissions and # limitations under the License. +import pytest import cugraph.dask as dcg import gc # import pytest @@ -20,12 +21,23 @@ # from cugraph.dask.common.mg_utils import is_single_gpu from cugraph.tests.utils import RAPIDS_DATASET_ROOT_DIR_PATH +# ============================================================================= +# Pytest Setup / Teardown - called for each test function +# ============================================================================= + + +def setup_function(): + gc.collect() + + +IS_DIRECTED = [True, False] + # @pytest.mark.skipif( # is_single_gpu(), reason="skipping MG testing on Single GPU system" # ) -def test_dask_pagerank(dask_client): - gc.collect() +@pytest.mark.parametrize("directed", IS_DIRECTED) +def test_dask_pagerank(dask_client, directed): # Initialize and run pagerank on two distributed graphs # with same communicator @@ -48,7 +60,7 @@ def test_dask_pagerank(dask_client): dtype=["int32", "int32", "float32"], ) - dg1 = cugraph.Graph(directed=True) + dg1 = cugraph.Graph(directed=directed) dg1.from_dask_cudf_edgelist(ddf1, "src", "dst") result_pr1 = dcg.pagerank(dg1).compute() @@ -61,7 +73,7 @@ def test_dask_pagerank(dask_client): dtype=["int32", "int32", "float32"], ) - dg2 = cugraph.Graph(directed=True) + dg2 = cugraph.Graph(directed=directed) dg2.from_dask_cudf_edgelist(ddf2, "src", "dst") result_pr2 = dcg.pagerank(dg2).compute() @@ -74,7 +86,7 @@ def test_dask_pagerank(dask_client): dtype=["int32", "int32", "float32"], ) - g1 = cugraph.Graph(directed=True) + g1 = cugraph.Graph(directed=directed) g1.from_cudf_edgelist(df1, "src", "dst") expected_pr1 = cugraph.pagerank(g1) @@ -85,7 +97,7 @@ def test_dask_pagerank(dask_client): dtype=["int32", "int32", "float32"], ) - g2 = cugraph.Graph(directed=True) + g2 = cugraph.Graph(directed=directed) g2.from_cudf_edgelist(df2, "src", "dst") expected_pr2 = cugraph.pagerank(g2) diff --git a/python/cugraph/cugraph/tests/dask/test_mg_connectivity.py b/python/cugraph/cugraph/tests/dask/test_mg_connectivity.py index 9427b18aa92..fbe04da6348 100644 --- a/python/cugraph/cugraph/tests/dask/test_mg_connectivity.py +++ b/python/cugraph/cugraph/tests/dask/test_mg_connectivity.py @@ -11,6 +11,7 @@ # See the License for the specific language governing permissions and # limitations under the License. +import pytest import cugraph.dask as dcg import gc # import pytest @@ -20,12 +21,23 @@ # from cugraph.dask.common.mg_utils import is_single_gpu from cugraph.tests.utils import RAPIDS_DATASET_ROOT_DIR_PATH +# ============================================================================= +# Pytest Setup / Teardown - called for each test function +# ============================================================================= + + +def setup_function(): + gc.collect() + + +IS_DIRECTED = [True, False] + # @pytest.mark.skipif( # is_single_gpu(), reason="skipping MG testing on Single GPU system" # ) -def test_dask_wcc(dask_client): - gc.collect() +@pytest.mark.parametrize("directed", IS_DIRECTED) +def test_dask_wcc(dask_client, directed): input_data_path = (RAPIDS_DATASET_ROOT_DIR_PATH / "netscience.csv").as_posix() @@ -47,10 +59,10 @@ def test_dask_wcc(dask_client): dtype=["int32", "int32", "float32"], ) - g = cugraph.Graph(directed=True) + g = cugraph.Graph(directed=directed) g.from_cudf_edgelist(df, "src", "dst", renumber=True) - dg = cugraph.Graph(directed=True) + dg = cugraph.Graph(directed=directed) dg.from_dask_cudf_edgelist(ddf, "src", "dst") expected_dist = cugraph.weakly_connected_components(g) diff --git a/python/cugraph/cugraph/tests/dask/test_mg_degree.py b/python/cugraph/cugraph/tests/dask/test_mg_degree.py index b0b46e93d10..ce27c6e6c95 100644 --- a/python/cugraph/cugraph/tests/dask/test_mg_degree.py +++ b/python/cugraph/cugraph/tests/dask/test_mg_degree.py @@ -21,12 +21,23 @@ from cugraph.dask.common.mg_utils import is_single_gpu from cugraph.tests.utils import RAPIDS_DATASET_ROOT_DIR_PATH +# ============================================================================= +# Pytest Setup / Teardown - called for each test function +# ============================================================================= + + +def setup_function(): + gc.collect() + + +IS_DIRECTED = [True, False] + @pytest.mark.skipif( is_single_gpu(), reason="skipping MG testing on Single GPU system" ) -def test_dask_mg_degree(dask_client): - gc.collect() +@pytest.mark.parametrize("directed", IS_DIRECTED) +def test_dask_mg_degree(dask_client, directed): input_data_path = (RAPIDS_DATASET_ROOT_DIR_PATH / "karate-asymmetric.csv").as_posix() @@ -49,10 +60,10 @@ def test_dask_mg_degree(dask_client): dtype=["int32", "int32", "float32"], ) - dg = cugraph.Graph(directed=True) + dg = cugraph.Graph(directed=directed) dg.from_dask_cudf_edgelist(ddf, "src", "dst") - g = cugraph.Graph(directed=True) + g = cugraph.Graph(directed=directed) g.from_cudf_edgelist(df, "src", "dst") merge_df_in = ( diff --git a/python/cugraph/cugraph/tests/dask/test_mg_hits.py b/python/cugraph/cugraph/tests/dask/test_mg_hits.py index 124bc5066cb..dde91690b7a 100644 --- a/python/cugraph/cugraph/tests/dask/test_mg_hits.py +++ b/python/cugraph/cugraph/tests/dask/test_mg_hits.py @@ -19,6 +19,7 @@ # from cugraph.dask.common.mg_utils import is_single_gpu from cugraph.tests import utils + # ============================================================================= # Pytest Setup / Teardown - called for each test function # ============================================================================= @@ -28,6 +29,9 @@ def setup_function(): gc.collect() +IS_DIRECTED = [True, False] + + # ============================================================================= # Pytest fixtures # ============================================================================= @@ -38,6 +42,7 @@ def setup_function(): fixture_params = utils.genFixtureParamsProduct((datasets, "graph_file"), ([50], "max_iter"), ([1.0e-6], "tol"), + (IS_DIRECTED, "directed") ) @@ -47,7 +52,10 @@ def input_combo(request): Simply return the current combination of params as a dictionary for use in tests or other parameterized fixtures. """ - parameters = dict(zip(("graph_file", "max_iter", "tol"), request.param)) + parameters = dict(zip(("graph_file", + "max_iter", + "tol", + "directed"), request.param)) return parameters @@ -60,9 +68,9 @@ def input_expected_output(input_combo): """ input_data_path = input_combo["graph_file"] - + directed = input_combo["directed"] G = utils.generate_cugraph_graph_from_file( - input_data_path) + input_data_path, directed=directed) sg_cugraph_hits = cugraph.hits( G, input_combo["max_iter"], @@ -83,7 +91,7 @@ def input_expected_output(input_combo): dtype=["int32", "int32", "float32"], ) - dg = cugraph.Graph(directed=True) + dg = cugraph.Graph(directed=directed) dg.from_dask_cudf_edgelist( ddf, source='src', destination='dst', edge_attr='value', renumber=True) diff --git a/python/cugraph/cugraph/tests/dask/test_mg_katz_centrality.py b/python/cugraph/cugraph/tests/dask/test_mg_katz_centrality.py index 1b0f89c1fd7..97b5b56fe9a 100644 --- a/python/cugraph/cugraph/tests/dask/test_mg_katz_centrality.py +++ b/python/cugraph/cugraph/tests/dask/test_mg_katz_centrality.py @@ -22,11 +22,23 @@ from cugraph.tests.utils import RAPIDS_DATASET_ROOT_DIR_PATH +# ============================================================================= +# Pytest Setup / Teardown - called for each test function +# ============================================================================= + + +def setup_function(): + gc.collect() + + +IS_DIRECTED = [True, False] + + @pytest.mark.skipif( is_single_gpu(), reason="skipping MG testing on Single GPU system" ) -def test_dask_katz_centrality(dask_client): - gc.collect() +@pytest.mark.parametrize("directed", IS_DIRECTED) +def test_dask_katz_centrality(dask_client, directed): input_data_path = (RAPIDS_DATASET_ROOT_DIR_PATH / "karate.csv").as_posix() @@ -55,9 +67,14 @@ def test_dask_katz_centrality(dask_client): import networkx as nx from cugraph.tests import utils NM = utils.read_csv_for_nx(input_data_path) - Gnx = nx.from_pandas_edgelist( - NM, create_using=nx.DiGraph(), source="0", target="1" - ) + if directed: + Gnx = nx.from_pandas_edgelist( + NM, create_using=nx.DiGraph(), source="0", target="1" + ) + else: + Gnx = nx.from_pandas_edgelist( + NM, create_using=nx.Graph(), source="0", target="1" + ) nk = nx.katz_centrality(Gnx, alpha=katz_alpha) import pandas as pd pdf = pd.DataFrame(nk.items(), columns=['vertex', 'katz_centrality']) diff --git a/python/cugraph/cugraph/tests/dask/test_mg_louvain.py b/python/cugraph/cugraph/tests/dask/test_mg_louvain.py index fbf3dab90e2..43389c0f679 100644 --- a/python/cugraph/cugraph/tests/dask/test_mg_louvain.py +++ b/python/cugraph/cugraph/tests/dask/test_mg_louvain.py @@ -49,6 +49,7 @@ def setFixtureParamNames(*args, **kwargs): def daskGraphFromDataset(request, dask_client): """ Returns a new dask dataframe created from the dataset file param. + This creates un undirected Graph. """ # Since parameterized fixtures do not assign param names to param values, # manually call the helper to do so. @@ -69,15 +70,43 @@ def daskGraphFromDataset(request, dask_client): return dg +@pytest.fixture(scope="module", + params=utils.DATASETS_UNDIRECTED, + ids=[f"dataset={d.as_posix()}" + for d in utils.DATASETS_UNDIRECTED]) +def uddaskGraphFromDataset(request, dask_client): + """ + Returns a new dask dataframe created from the dataset file param. + This creates un undirected Graph. + """ + # Since parameterized fixtures do not assign param names to param + # values, manually call the helper to do so. + setFixtureParamNames(request, ["dataset"]) + dataset = request.param + + chunksize = dcg.get_chunksize(dataset) + ddf = dask_cudf.read_csv( + dataset, + chunksize=chunksize, + delimiter=" ", + names=["src", "dst", "value"], + dtype=["int32", "int32", "float32"], + ) + + dg = cugraph.Graph(directed=False) + dg.from_dask_cudf_edgelist(ddf, "src", "dst") + return dg + + ############################################################################### # Tests # @pytest.mark.skipif( # is_single_gpu(), reason="skipping MG testing on Single GPU system" # ) def test_mg_louvain_with_edgevals(daskGraphFromDataset): - # FIXME: daskGraphFromDataset returns a DiGraph, which Louvain is currently - # accepting. In the future, an MNMG symmeterize will need to be called to - # create a Graph for Louvain. + # FIXME: daskGraphFromDataset returns a Directed graph, which Louvain is + # currently accepting. In the future, an MNMG symmeterize will need to + # be called to create a Graph for Louvain. parts, mod = dcg.louvain(daskGraphFromDataset) # FIXME: either call Nx with the same dataset and compare results, or @@ -86,3 +115,19 @@ def test_mg_louvain_with_edgevals(daskGraphFromDataset): print(parts.compute()) print(mod) print() + + +############################################################################### +# Tests +# @pytest.mark.skipif( +# is_single_gpu(), reason="skipping MG testing on Single GPU system" +# ) +def test_mg_udlouvain_with_edgevals(uddaskGraphFromDataset): + parts, mod = dcg.louvain(uddaskGraphFromDataset) + + # FIXME: either call Nx with the same dataset and compare results, or + # hardcode golden results to compare to. + print() + print(parts.compute()) + print(mod) + print() diff --git a/python/cugraph/cugraph/tests/dask/test_mg_neighborhood_sampling.py b/python/cugraph/cugraph/tests/dask/test_mg_neighborhood_sampling.py index 25838445e11..4dcba8d6ee9 100644 --- a/python/cugraph/cugraph/tests/dask/test_mg_neighborhood_sampling.py +++ b/python/cugraph/cugraph/tests/dask/test_mg_neighborhood_sampling.py @@ -28,6 +28,9 @@ def setup_function(): gc.collect() +IS_DIRECTED = [True, False] + + # datasets = utils.RAPIDS_DATASET_ROOT_DIR_PATH/"karate.csv" datasets = utils.DATASETS_SMALL fixture_params = utils.genFixtureParamsProduct((datasets, "graph_file")) @@ -43,10 +46,12 @@ def _get_param_args(param_name, param_values): [pytest.param(v, id=f"{param_name}={v}") for v in param_values]) -@pytest.mark.skipif( - is_single_gpu(), reason="skipping MG testing on Single GPU system" -) -def test_mg_neighborhood_sampling_simple(dask_client): +# @pytest.mark.skipif( +# is_single_gpu(), reason="skipping MG testing on Single GPU system" +# ) +@pytest.mark.skip(reason="Currently hangs, awaiting fix in algo") +@pytest.mark.parametrize("directed", IS_DIRECTED) +def test_mg_neighborhood_sampling_simple(dask_client, directed): from cugraph.experimental.dask import uniform_neighborhood_sampling @@ -60,7 +65,7 @@ def test_mg_neighborhood_sampling_simple(dask_client): }) ddf = dask_cudf.from_cudf(df, npartitions=2) - G = cugraph.Graph(directed=True) + G = cugraph.Graph(directed=directed) G.from_dask_cudf_edgelist(ddf, "src", "dst", "value") # TODO: Incomplete, include more testing for tree graph as well as @@ -90,7 +95,9 @@ def test_mg_neighborhood_sampling_simple(dask_client): @pytest.mark.skipif( is_single_gpu(), reason="skipping MG testing on Single GPU system" ) -def test_mg_neighborhood_sampling_tree(dask_client): +@pytest.mark.parametrize("directed", IS_DIRECTED) +@pytest.mark.skip(reason="Currently hangs, awaiting fix in algo") +def test_mg_neighborhood_sampling_tree(dask_client, directed): from cugraph.experimental.dask import uniform_neighborhood_sampling @@ -106,7 +113,7 @@ def test_mg_neighborhood_sampling_tree(dask_client): dtype=["int32", "int32", "float32"], ) - G = cugraph.Graph(directed=True) + G = cugraph.Graph(directed=directed) G.from_dask_cudf_edgelist(ddf, "src", "dst", "value") # TODO: Incomplete, include more testing for tree graph as well as diff --git a/python/cugraph/cugraph/tests/dask/test_mg_pagerank.py b/python/cugraph/cugraph/tests/dask/test_mg_pagerank.py index 957e9a7747e..f03a77a46f6 100644 --- a/python/cugraph/cugraph/tests/dask/test_mg_pagerank.py +++ b/python/cugraph/cugraph/tests/dask/test_mg_pagerank.py @@ -48,13 +48,15 @@ def personalize(vertices, personalization_perc): PERSONALIZATION_PERC = [0, 10, 50] +IS_DIRECTED = [True, False] # @pytest.mark.skipif( # is_single_gpu(), reason="skipping MG testing on Single GPU system" # ) @pytest.mark.parametrize("personalization_perc", PERSONALIZATION_PERC) -def test_dask_pagerank(dask_client, personalization_perc): +@pytest.mark.parametrize("directed", IS_DIRECTED) +def test_dask_pagerank(dask_client, personalization_perc, directed): gc.collect() input_data_path = (RAPIDS_DATASET_ROOT_DIR_PATH / @@ -77,10 +79,10 @@ def test_dask_pagerank(dask_client, personalization_perc): dtype=["int32", "int32", "float32"], ) - g = cugraph.Graph(directed=True) + g = cugraph.Graph(directed=directed) g.from_cudf_edgelist(df, "src", "dst") - dg = cugraph.Graph(directed=True) + dg = cugraph.Graph(directed=directed) dg.from_dask_cudf_edgelist(ddf, "src", "dst") personalization = None diff --git a/python/cugraph/cugraph/tests/dask/test_mg_renumber.py b/python/cugraph/cugraph/tests/dask/test_mg_renumber.py index a0e428d1d65..d21b96cf4c5 100644 --- a/python/cugraph/cugraph/tests/dask/test_mg_renumber.py +++ b/python/cugraph/cugraph/tests/dask/test_mg_renumber.py @@ -38,6 +38,9 @@ def setup_function(): gc.collect() +IS_DIRECTED = [True, False] + + @pytest.mark.skipif( is_single_gpu(), reason="skipping MG testing on Single GPU system" ) @@ -130,7 +133,8 @@ def test_mg_renumber_add_internal_vertex_id(graph_file, dask_client): @pytest.mark.skipif( is_single_gpu(), reason="skipping MG testing on Single GPU system" ) -def test_dask_pagerank(dask_client): +@pytest.mark.parametrize("directed", IS_DIRECTED) +def test_dask_pagerank(dask_client, directed): pandas.set_option("display.max_rows", 10000) input_data_path = (RAPIDS_DATASET_ROOT_DIR_PATH / @@ -152,10 +156,10 @@ def test_dask_pagerank(dask_client): dtype=["int32", "int32", "float32"], ) - g = cugraph.Graph(directed=True) + g = cugraph.Graph(directed=directed) g.from_cudf_edgelist(df, "src", "dst") - dg = cugraph.Graph(directed=True) + dg = cugraph.Graph(directed=directed) dg.from_dask_cudf_edgelist(ddf, "src", "dst") expected_pr = cugraph.pagerank(g) @@ -185,7 +189,8 @@ def test_dask_pagerank(dask_client): is_single_gpu(), reason="skipping MG testing on Single GPU system" ) @pytest.mark.parametrize("renumber", [False]) -def test_directed_graph_renumber_false(renumber, dask_client): +@pytest.mark.parametrize("directed", IS_DIRECTED) +def test_graph_renumber_false(renumber, dask_client, directed): input_data_path = (RAPIDS_DATASET_ROOT_DIR_PATH / "karate.csv").as_posix() chunksize = dcg.get_chunksize(input_data_path) @@ -197,7 +202,7 @@ def test_directed_graph_renumber_false(renumber, dask_client): names=["src", "dst", "value"], dtype=["int32", "int32", "float32"], ) - dg = cugraph.Graph(directed=True) + dg = cugraph.Graph(directed=directed) with pytest.raises(ValueError): dg.from_dask_cudf_edgelist(ddf, "src", "dst", renumber=renumber) @@ -207,7 +212,8 @@ def test_directed_graph_renumber_false(renumber, dask_client): is_single_gpu(), reason="skipping MG testing on Single GPU system" ) @pytest.mark.parametrize("renumber", [False]) -def test_multi_directed_graph_renumber_false(renumber, dask_client): +@pytest.mark.parametrize("directed", IS_DIRECTED) +def test_multi_graph_renumber_false(renumber, dask_client, directed): input_data_path = (RAPIDS_DATASET_ROOT_DIR_PATH / "karate_multi_edge.csv").as_posix() chunksize = dcg.get_chunksize(input_data_path) @@ -219,8 +225,10 @@ def test_multi_directed_graph_renumber_false(renumber, dask_client): names=["src", "dst", "value"], dtype=["int32", "int32", "float32"], ) - dg = cugraph.MultiGraph(directed=True) + dg = cugraph.MultiGraph(directed=directed) + # ValueError always thrown since renumber must be True with + # MNMG algorithms with pytest.raises(ValueError): dg.from_dask_cudf_edgelist(ddf, "src", "dst", renumber=renumber) diff --git a/python/cugraph/cugraph/tests/dask/test_mg_sssp.py b/python/cugraph/cugraph/tests/dask/test_mg_sssp.py index 656c91d1754..c8a2361b6ad 100644 --- a/python/cugraph/cugraph/tests/dask/test_mg_sssp.py +++ b/python/cugraph/cugraph/tests/dask/test_mg_sssp.py @@ -11,6 +11,7 @@ # See the License for the specific language governing permissions and # limitations under the License. +import pytest import cugraph.dask as dcg import gc # import pytest @@ -20,12 +21,23 @@ # from cugraph.dask.common.mg_utils import is_single_gpu from cugraph.tests.utils import RAPIDS_DATASET_ROOT_DIR_PATH +# ============================================================================= +# Pytest Setup / Teardown - called for each test function +# ============================================================================= + + +def setup_function(): + gc.collect() + + +IS_DIRECTED = [True, False] + # @pytest.mark.skipif( # is_single_gpu(), reason="skipping MG testing on Single GPU system" # ) -def test_dask_sssp(dask_client): - gc.collect() +@pytest.mark.parametrize("directed", IS_DIRECTED) +def test_dask_sssp(dask_client, directed): input_data_path = (RAPIDS_DATASET_ROOT_DIR_PATH / "netscience.csv").as_posix() @@ -47,10 +59,10 @@ def test_dask_sssp(dask_client): dtype=["int32", "int32", "float32"], ) - g = cugraph.Graph(directed=True) + g = cugraph.Graph(directed=directed) g.from_cudf_edgelist(df, "src", "dst", "value", renumber=True) - dg = cugraph.Graph(directed=True) + dg = cugraph.Graph(directed=directed) dg.from_dask_cudf_edgelist(ddf, "src", "dst", "value") expected_dist = cugraph.sssp(g, 0) diff --git a/python/cugraph/cugraph/tests/dask/test_mg_utility.py b/python/cugraph/cugraph/tests/dask/test_mg_utility.py index 732c785df68..4aec0ba93c1 100644 --- a/python/cugraph/cugraph/tests/dask/test_mg_utility.py +++ b/python/cugraph/cugraph/tests/dask/test_mg_utility.py @@ -35,10 +35,14 @@ def setup_function(): gc.collect() +IS_DIRECTED = [True, False] + + # @pytest.mark.skipif( # is_single_gpu(), reason="skipping MG testing on Single GPU system" # ) -def test_from_edgelist(dask_client): +@pytest.mark.parametrize("directed", IS_DIRECTED) +def test_from_edgelist(dask_client, directed): input_data_path = (RAPIDS_DATASET_ROOT_DIR_PATH / "karate.csv").as_posix() print(f"dataset={input_data_path}") @@ -53,9 +57,9 @@ def test_from_edgelist(dask_client): dg1 = cugraph.from_edgelist( ddf, source="src", destination="dst", edge_attr="value", - create_using=cugraph.Graph(directed=True)) + create_using=cugraph.Graph(directed=directed)) - dg2 = cugraph.Graph(directed=True) + dg2 = cugraph.Graph(directed=directed) dg2.from_dask_cudf_edgelist( ddf, source="src", destination="dst", edge_attr="value" ) diff --git a/python/cugraph/cugraph/tests/test_jaccard.py b/python/cugraph/cugraph/tests/test_jaccard.py index 50bffe71fff..b7ce514d5f9 100644 --- a/python/cugraph/cugraph/tests/test_jaccard.py +++ b/python/cugraph/cugraph/tests/test_jaccard.py @@ -1,4 +1,4 @@ -# Copyright (c) 2020-2021, NVIDIA CORPORATION. +# Copyright (c) 2020-2022, NVIDIA CORPORATION. # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at @@ -155,6 +155,24 @@ def test_jaccard(read_csv, gpubenchmark): assert err == 0 +def test_directed_graph_check(read_csv): + M, _ = read_csv + + cu_M = cudf.DataFrame() + cu_M["src_0"] = cudf.Series(M["0"]) + cu_M["dst_0"] = cudf.Series(M["1"]) + cu_M["src_1"] = cu_M["src_0"] + 1000 + cu_M["dst_1"] = cu_M["dst_0"] + 1000 + G1 = cugraph.Graph(directed=True) + G1.from_cudf_edgelist(cu_M, source=["src_0", "src_1"], + destination=["dst_0", "dst_1"]) + + vertex_pair = cu_M[["src_0", "src_1", "dst_0", "dst_1"]] + vertex_pair = vertex_pair[:5] + with pytest.raises(ValueError): + cugraph.jaccard(G1, vertex_pair) + + def test_nx_jaccard_time(read_csv, gpubenchmark): M, _ = read_csv