Skip to content

Commit a245d2d

Browse files
brycelelbachmyli5
andcommitted
Chapter 9 cuGraph: Correct PageRank examples and backend setup.
Install nx-cugraph before NetworkX performs backend discovery, select CPU and GPU implementations explicitly, and make the benchmark reproducible. Correct the directed toy graph and Karate dataset example while preserving a meaningful benchmark size. Co-authored-by: myli5 <cloudmyli5@gmail.com> Signed-off-by: Bryce Adelstein Lelbach <brycelelbach@gmail.com>
1 parent 5f8d349 commit a245d2d

1 file changed

Lines changed: 39 additions & 34 deletions

File tree

Accelerated_Python_User_Guide/notebooks/Chapter_09_Intro_to_cuGraph.ipynb

Lines changed: 39 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@
6666
"```\n",
6767
"pip install \\\n",
6868
" --extra-index-url=https://pypi.nvidia.com \\\n",
69-
" cudf-cu12==24.10.* cugraph-cu12==24.10.* \n",
69+
" cudf-cu12==26.8.* cugraph-cu12==26.8.* nx-cugraph-cu12==26.8.* \n",
7070
"```\n",
7171
"\n",
7272
"\n",
@@ -93,9 +93,11 @@
9393
"# Install a cudf / cugraph build that matches this environment's CUDA and Python.\n",
9494
"# The 24.10 pin in the original notebook is far too old (no wheels for recent\n",
9595
"# Python); use a current RAPIDS release instead.\n",
96-
"!pip install \\\n",
96+
"%pip install \\\n",
9797
" --extra-index-url=https://pypi.nvidia.com \\\n",
98-
" \"cudf-cu12==26.8.*\" \"cugraph-cu12==26.8.*\""
98+
" \"cudf-cu12==26.8.*\" \\\n",
99+
" \"cugraph-cu12==26.8.*\" \\\n",
100+
" \"nx-cugraph-cu12==26.8.*\""
99101
]
100102
},
101103
{
@@ -209,8 +211,9 @@
209211
" 'dst': [1, 2, 2, 0]\n",
210212
"})\n",
211213
"\n",
212-
"# Create the graph\n",
213-
"G = cugraph.Graph()\n",
214+
"# Create the graph. The edge list is directed (note the 2 -> 0 \"connects back\"\n",
215+
"# edge), so build a directed Graph.\n",
216+
"G = cugraph.Graph(directed=True)\n",
214217
"G.from_cudf_edgelist(edge_list, source='src', destination='dst')"
215218
]
216219
},
@@ -310,16 +313,21 @@
310313
},
311314
"outputs": [],
312315
"source": [
313-
"# Perform PageRank on the weighted graph\n",
316+
"# Perform PageRank on the graph we built above\n",
314317
"pagerank_result = cugraph.pagerank(G)\n",
315318
"\n",
316319
"# Display the PageRank values\n",
317320
"print(pagerank_result)\n",
318321
"\n",
319-
"G = karate.get_graph(download=True)\n",
322+
"# Now try it on a larger, real-world graph: Zachary's Karate Club, which ships\n",
323+
"# with cuGraph as a sample dataset.\n",
324+
"from cugraph.datasets import karate\n",
325+
"\n",
326+
"karate_G = karate.get_graph(download=True)\n",
320327
"\n",
321328
"# Call cugraph.pagerank to get the pagerank scores\n",
322-
"gdf_page = cugraph.pagerank(G)\n"
329+
"gdf_page = cugraph.pagerank(karate_G)\n",
330+
"print(gdf_page.sort_values('pagerank', ascending=False).head())"
323331
]
324332
},
325333
{
@@ -329,7 +337,7 @@
329337
"source": [
330338
"## NetworkX x cuGraph\n",
331339
"\n",
332-
"Let's start by installing the zero-code change NetworkX cuGraph package:"
340+
"The prerequisites cell installs the zero-code-change NetworkX cuGraph package before NetworkX is imported. Verify the installed backend version:"
333341
]
334342
},
335343
{
@@ -343,7 +351,8 @@
343351
},
344352
"outputs": [],
345353
"source": [
346-
"!pip install \"nx-cugraph-cu12==26.8.*\" --extra-index-url=https://pypi.nvidia.com"
354+
"from importlib.metadata import version\n",
355+
"print(f\"using nx-cugraph version {version('nx-cugraph-cu12')}\")"
347356
]
348357
},
349358
{
@@ -365,12 +374,8 @@
365374
},
366375
"outputs": [],
367376
"source": [
368-
"#%env NX_CUGRAPH_AUTOCONFIG=True\n",
369-
"\n",
370377
"import networkx as nx\n",
371-
"print(f\"using networkx version {nx.__version__}\")\n",
372-
"\n",
373-
"#nx.config.warnings_to_ignore.add(\"cache\")"
378+
"print(f\"using networkx version {nx.__version__}\")"
374379
]
375380
},
376381
{
@@ -384,21 +389,22 @@
384389
},
385390
"outputs": [],
386391
"source": [
387-
"G = nx.gnm_random_graph(5000, 40000)\n",
392+
"# A reproducible graph large enough for a meaningful backend comparison.\n",
393+
"benchmark_graph = nx.gnm_random_graph(200_000, 2_000_000, seed=42)\n",
388394
"\n",
389-
"import time \n",
395+
"import time\n",
390396
"start_time = time.time()\n",
391-
"pr = nx.pagerank(G)\n",
392-
"elapsed_time = time.time() - start_time\n",
393-
"print(elapsed_time)"
397+
"cpu_pagerank = nx.pagerank(benchmark_graph, backend=\"networkx\")\n",
398+
"cpu_elapsed = time.time() - start_time\n",
399+
"print(f\"NetworkX CPU time: {cpu_elapsed:.3f} seconds\")"
394400
]
395401
},
396402
{
397403
"cell_type": "markdown",
398404
"id": "d3040a65",
399405
"metadata": {},
400406
"source": [
401-
"Then let's try to set the backend to cuGraph by default instead of using the non-accelerated backend: "
407+
"Then run the same calculation explicitly with the cuGraph backend:"
402408
]
403409
},
404410
{
@@ -412,27 +418,26 @@
412418
},
413419
"outputs": [],
414420
"source": [
415-
"%env NX_CUGRAPH_AUTOCONFIG=True\n",
416-
"\n",
417-
"import networkx as nx\n",
418-
"print(f\"using networkx version {nx.__version__}\")\n",
419-
"\n",
420-
"#nx.config.warnings_to_ignore.add(\"cache\")\n",
421+
"import time\n",
422+
"start_time = time.time()\n",
423+
"gpu_pagerank = nx.pagerank(benchmark_graph, backend=\"cugraph\")\n",
424+
"gpu_elapsed = time.time() - start_time\n",
421425
"\n",
426+
"assert len(gpu_pagerank) == len(cpu_pagerank)\n",
427+
"assert abs(sum(cpu_pagerank.values()) - 1.0) < 1e-4\n",
428+
"assert abs(sum(gpu_pagerank.values()) - 1.0) < 1e-4\n",
429+
"max_error = max(abs(gpu_pagerank[node] - score) for node, score in cpu_pagerank.items())\n",
422430
"\n",
423-
"import time \n",
424-
"start_time = time.time()\n",
425-
"pr = nx.pagerank(G)\n",
426-
"elapsed_time = time.time() - start_time\n",
427-
"print(elapsed_time)"
431+
"print(f\"cuGraph GPU time: {gpu_elapsed:.3f} seconds\")\n",
432+
"print(f\"Maximum PageRank difference: {max_error:.3e}\")"
428433
]
429434
},
430435
{
431436
"cell_type": "markdown",
432437
"id": "f3d1af59",
433438
"metadata": {},
434439
"source": [
435-
"Now that we've configured our cuGraph setup with NetworkX, let's start experimenting with its functionalities using a real-world example!\n"
440+
"Now that the cuGraph backend is available through NetworkX, let's start experimenting with a real-world example!\n"
436441
]
437442
},
438443
{
@@ -593,7 +598,7 @@
593598
},
594599
"outputs": [],
595600
"source": [
596-
"pagerank_scores = nx.pagerank(C)\n",
601+
"pagerank_scores = nx.pagerank(C, backend=\"cugraph\")\n",
597602
"pagerank_df = cudf.DataFrame({'node_id': pagerank_scores.keys(), 'score': pagerank_scores.values()})\n",
598603
"pagerank_df.tail()"
599604
]

0 commit comments

Comments
 (0)