Skip to main content

PageRank

UDTF: cugraph_pagerank

Official cuGraph reference: C API

Rank vertices by the stationary probability of a damped random walk that follows outgoing edges.

Quickstart​

The call below supplies edges from registered relation target_edges with canonical src and dst columns and may include weight.

SELECT *
FROM cugraph_pagerank(
edges => (SELECT src, dst FROM target_edges)
);

Inputs​

Every relation is a named parenthesized SELECT subquery. The required edges role uses canonical src and dst columns. Every role, its canonical columns, and their accepted Arrow types are listed under Relation arguments. Metadata validation resolves registered tables named in its JSON request.

The vertex-ID types this UDTF accepts, the numeric types a per-call codebook maps to native ids, and its string-key limits are listed in Vertex ID support; the concrete call-specific schema comes from gpu_validate_call.

Arguments and options​

Relation arguments​

ArgumentRequiredColumnsDescription
edgesyes
  • src, dst: Int32, Int64, Utf8, LargeUtf8, Utf8View
  • weight (optional): Float32, Float64
  • edge_id (optional): Int32, Int64
edge relation with canonical src and dst columns, plus optional weight and edge_id columns

Every edge_id column must have the integer type of src and dst; string-keyed graphs accept no edge IDs.

Named value arguments​

OptionTypeDefaultConstraintsDescription
alphanumber0.85min 0; max 1PageRank damping factor in [0, 1]
epsilonnumber0.00001> 0positive convergence tolerance
max_iterationsinteger100min 1; max 4294967295maximum iteration count, at least 1

Graph construction options​

Graph construction follows the shared defaults (directed=true, renumbering, python_cugraph policy) documented in Graph Construction Options.

Output​

ColumnTypeNullableDescription
vertexInt64|Utf8noVertex receiving the PageRank score.
valueFloat64noPageRank score for the vertex.

These are generic descriptor schemas. Run gpu_validate_call to get the concrete, table-specific output schema.

Examples​

Which brands grew closer to Barbie's audience?​

The query compares each brand's affinity to Barbie's audience from May through June against July through August 2023 and ranks the relative change. A later check of product names tests whether the change coincides with Barbie-related listings.

Each period has a graph of distinct user-brand likes. The after_release flag is true for July to August likes. The split at 1 July falls 20 days before the Barbie film opened on 21 July. User vertices are -(user_id + 1) and brand vertices are brand_id values. Both columns are non-negative in this data, so users occupy negative IDs and la.vertex > 0 keeps only brands (brand 0 is excluded).

Personalized PageRank starts from Barbie; ordinary PageRank supplies each brand's global graph score. Their ratio, lift, describes relative graph affinity: 1 means the two scores are equal. All four calls use the default options (alpha 0.85, epsilon 1e-5, max_iterations 100), and each converged before the iteration limit. Lifts from the two periods were therefore computed to one tolerance. The query ranks the change in that ratio and requires at least 1,000 fans (distinct users) per brand in both periods.

WITH likes AS (
SELECT DISTINCT -(e.user_id + 1) AS src, CAST(i.brand_id AS BIGINT) AS dst,
e.event_time >= TIMESTAMP '2023-07-01 00:00:00' AS after_release
FROM merrec_events e JOIN merrec_items i ON i.item_id = e.item_id
WHERE e.event_type = 'item_like' AND i.brand_id <> 0
AND e.event_time >= TIMESTAMP '2023-05-01 00:00:00'
AND e.event_time < TIMESTAMP '2023-09-01 00:00:00'
), lift_before AS (
SELECT p.vertex, p.value / r.value AS lift
FROM cugraph_personalized_pagerank(
edges => (SELECT src, dst FROM likes WHERE NOT after_release),
personalization => (SELECT 2595 AS vertex, 1.0 AS value),
directed => false) p
JOIN cugraph_pagerank(
edges => (SELECT src, dst FROM likes WHERE NOT after_release), directed => false) r
ON r.vertex = p.vertex
), lift_after AS (
SELECT p.vertex, p.value / r.value AS lift
FROM cugraph_personalized_pagerank(
edges => (SELECT src, dst FROM likes WHERE after_release),
personalization => (SELECT 2595 AS vertex, 1.0 AS value),
directed => false) p
JOIN cugraph_pagerank(
edges => (SELECT src, dst FROM likes WHERE after_release), directed => false) r
ON r.vertex = p.vertex
), fans AS (
SELECT dst AS brand_id,
SUM(CASE WHEN after_release THEN 0 ELSE 1 END) AS fans_before,
SUM(CASE WHEN after_release THEN 1 ELSE 0 END) AS fans_after
FROM likes GROUP BY dst
), brands AS (
SELECT CAST(brand_id AS BIGINT) AS brand_id, MIN(brand_name) AS brand_name
FROM merrec_items WHERE brand_id <> 0 GROUP BY brand_id
)
SELECT b.brand_name, f.fans_before, f.fans_after,
lb.lift AS lift_before, la.lift AS lift_after, la.lift / lb.lift AS lift_change
FROM lift_after la
JOIN lift_before lb ON lb.vertex = la.vertex
JOIN fans f ON f.brand_id = la.vertex
JOIN brands b ON b.brand_id = la.vertex
WHERE la.vertex > 0 AND la.vertex <> 2595
AND f.fans_before >= 1000 AND f.fans_after >= 1000
ORDER BY lift_change DESC, b.brand_name
LIMIT 25;

The first four rows are the largest increases. Taylor Swift is included as a comparison for the product-name check below.

BrandMay-June affinityJuly-August affinityChange
NYX0.972.072.13×
Amc0.971.821.87×
Primark1.102.041.85×
ALDO0.851.501.76×
Taylor Swift0.650.961.48×

The time filters, four graph calls and brand joins ran natively in one plan. Over Flight SQL, the first run on a fresh server took 3.72 s and runs 2 to 4 a median of 3.05 s. On the same host, with the files in the page cache, an equivalent CPU pipeline combining 32-thread DuckDB with igraph took a median of 23.3 s (2.3 s SQL extraction, 13.0 s renumbering and graph construction, 7.7 s for four PageRank calls, 0.3 s final join) with identical top-25 rankings. Device execution avoids transferring and renumbering the 23 million edge pairs across host memory.

Follow-up: check product names. The graph query did not search names. This separate SQL counts like events on listings whose names contain "Barbie", using the same periods. Each of the five brand names checked here maps to one brand_id, matching the brands in the graph result.

WITH selected_items AS (
SELECT item_id, brand_name,
LOWER(COALESCE(name, '')) LIKE '%barbie%' AS is_barbie
FROM merrec_items
WHERE brand_name IN ('NYX', 'Amc', 'Primark', 'ALDO', 'Taylor Swift', 'Stanley', 'OPI', 'ZARA')
), likes AS (
SELECT i.brand_name, i.is_barbie,
e.event_time < TIMESTAMP '2023-07-01 00:00:00' AS may_june
FROM merrec_events e JOIN selected_items i ON i.item_id = e.item_id
WHERE e.event_type = 'item_like'
AND e.event_time >= TIMESTAMP '2023-05-01 00:00:00'
AND e.event_time < TIMESTAMP '2023-09-01 00:00:00'
)
SELECT brand_name,
SUM(CASE WHEN may_june THEN 1 ELSE 0 END) AS total_likes_may_june,
SUM(CASE WHEN NOT may_june THEN 1 ELSE 0 END) AS total_likes_july_august,
SUM(CASE WHEN may_june AND is_barbie THEN 1 ELSE 0 END) AS barbie_likes_may_june,
SUM(CASE WHEN NOT may_june AND is_barbie THEN 1 ELSE 0 END) AS barbie_likes_july_august
FROM likes
GROUP BY brand_name
ORDER BY brand_name;
BrandMatching likes, May-JuneMatching likes, July-August
NYX1.83%30.62%
Primark1.63%24.08%
ALDO0.42%19.04%
Amc0.00%9.25%
Taylor Swift0.03%0.08%

NYX's records include "LIMITED EDITION NYX Barbie Flip Phone Mirror". Taylor Swift's graph score also increased, but only 135 of 164,499 later likes were on matching listings. Its change remains unexplained by this check. Name matches can include seller descriptions and color names.

Follow-up: change the seed. A rise in graph affinity could reflect a broad summer trend rather than Barbie. Rerunning the query with another seed brand tests that. Hot Wheels is a Mattel brand whose collector audience overlaps Barbie's; Nike is a large brand with no July event. Each control replaces Barbie's brand_id (2595) with the seed's (9877 for Hot Wheels, 15987 for Nike) in the personalization vertex and the la.vertex <> exclusion. The rest of the SQL is unchanged.

BrandBarbie seedHot Wheels seedNike seed
NYX2.13×1.53×absent from the top 25
Amc1.87×absent from the top 25absent from the top 25
Primark1.85×1.29×absent from the top 25
ALDO1.76×1.30×absent from the top 25

With Nike as the seed, none of the four brands appears among the 25 largest changes. With Hot Wheels, NYX, ALDO and Primark appear with smaller changes and Amc is absent, consistent with the Mattel collector audience sharing part of the Barbie movement. Item attributes are the latest retained values.

The graph capture contains all 25 brands, query IDs and timings. The listing capture and control captures contain the follow-up SQL and full results.

Limits​

  • calls without an edge weight column repeat between runs; with one, scores can differ in the last digits because out-weight sums accumulate with floating-point atomics