|
66 | 66 | "```\n", |
67 | 67 | "pip install \\\n", |
68 | 68 | " --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", |
70 | 70 | "```\n", |
71 | 71 | "\n", |
72 | 72 | "\n", |
|
93 | 93 | "# Install a cudf / cugraph build that matches this environment's CUDA and Python.\n", |
94 | 94 | "# The 24.10 pin in the original notebook is far too old (no wheels for recent\n", |
95 | 95 | "# Python); use a current RAPIDS release instead.\n", |
96 | | - "!pip install \\\n", |
| 96 | + "%pip install \\\n", |
97 | 97 | " --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.*\"" |
99 | 101 | ] |
100 | 102 | }, |
101 | 103 | { |
|
209 | 211 | " 'dst': [1, 2, 2, 0]\n", |
210 | 212 | "})\n", |
211 | 213 | "\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", |
214 | 217 | "G.from_cudf_edgelist(edge_list, source='src', destination='dst')" |
215 | 218 | ] |
216 | 219 | }, |
|
310 | 313 | }, |
311 | 314 | "outputs": [], |
312 | 315 | "source": [ |
313 | | - "# Perform PageRank on the weighted graph\n", |
| 316 | + "# Perform PageRank on the graph we built above\n", |
314 | 317 | "pagerank_result = cugraph.pagerank(G)\n", |
315 | 318 | "\n", |
316 | 319 | "# Display the PageRank values\n", |
317 | 320 | "print(pagerank_result)\n", |
318 | 321 | "\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", |
320 | 327 | "\n", |
321 | 328 | "# 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())" |
323 | 331 | ] |
324 | 332 | }, |
325 | 333 | { |
|
329 | 337 | "source": [ |
330 | 338 | "## NetworkX x cuGraph\n", |
331 | 339 | "\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:" |
333 | 341 | ] |
334 | 342 | }, |
335 | 343 | { |
|
343 | 351 | }, |
344 | 352 | "outputs": [], |
345 | 353 | "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')}\")" |
347 | 356 | ] |
348 | 357 | }, |
349 | 358 | { |
|
365 | 374 | }, |
366 | 375 | "outputs": [], |
367 | 376 | "source": [ |
368 | | - "#%env NX_CUGRAPH_AUTOCONFIG=True\n", |
369 | | - "\n", |
370 | 377 | "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__}\")" |
374 | 379 | ] |
375 | 380 | }, |
376 | 381 | { |
|
384 | 389 | }, |
385 | 390 | "outputs": [], |
386 | 391 | "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", |
388 | 394 | "\n", |
389 | | - "import time \n", |
| 395 | + "import time\n", |
390 | 396 | "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\")" |
394 | 400 | ] |
395 | 401 | }, |
396 | 402 | { |
397 | 403 | "cell_type": "markdown", |
398 | 404 | "id": "d3040a65", |
399 | 405 | "metadata": {}, |
400 | 406 | "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:" |
402 | 408 | ] |
403 | 409 | }, |
404 | 410 | { |
|
412 | 418 | }, |
413 | 419 | "outputs": [], |
414 | 420 | "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", |
421 | 425 | "\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", |
422 | 430 | "\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}\")" |
428 | 433 | ] |
429 | 434 | }, |
430 | 435 | { |
431 | 436 | "cell_type": "markdown", |
432 | 437 | "id": "f3d1af59", |
433 | 438 | "metadata": {}, |
434 | 439 | "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" |
436 | 441 | ] |
437 | 442 | }, |
438 | 443 | { |
|
593 | 598 | }, |
594 | 599 | "outputs": [], |
595 | 600 | "source": [ |
596 | | - "pagerank_scores = nx.pagerank(C)\n", |
| 601 | + "pagerank_scores = nx.pagerank(C, backend=\"cugraph\")\n", |
597 | 602 | "pagerank_df = cudf.DataFrame({'node_id': pagerank_scores.keys(), 'score': pagerank_scores.values()})\n", |
598 | 603 | "pagerank_df.tail()" |
599 | 604 | ] |
|
0 commit comments