Skip to main content

ForceAtlas2

UDTF: cugraph_force_atlas2

Official cuGraph reference: C API

Place vertices in two dimensions with a force-directed simulation that attracts connected vertices and repels vertices from one another.

Quickstart​

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

SELECT *
FROM cugraph_force_atlas2(
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
vertex_attributesno
  • vertex: Int32, Int64, Utf8, LargeUtf8, Utf8View
  • radius, mobility, mass (optional): Float32
optional per-vertex ForceAtlas2 attributes; at least one attribute column is required
initial_positionsno
  • vertex: Int32, Int64, Utf8, LargeUtf8, Utf8View
  • x, y: Float32
optional complete ForceAtlas2 initial positions

Vertex columns of vertex_attributes, initial_positions must use the same vertex domain as edges: the integer type of src and dst, or any listed string type when the endpoints are strings. Every edge_id column must have the integer type of src and dst; string-keyed graphs accept no edge IDs.

Named value arguments​

OptionTypeDefaultConstraintsDescription
barnes_hut_optimizebooleanfalseuse the Barnes-Hut ForceAtlas2 approximation
barnes_hut_thetanumber0.5min 0; max 1Barnes-Hut speed and accuracy trade-off
edge_weight_influencenumber1min 0non-negative edge weight influence
gravitynumber1min 0non-negative ForceAtlas2 gravity strength
jitter_tolerancenumber1min 0non-negative ForceAtlas2 jitter tolerance
lin_log_modebooleanfalseuse the ForceAtlas2 lin-log attraction model
max_iterinteger500min 1; max 2147483647ForceAtlas2 iteration limit
outbound_attraction_distributionbooleanfalsedistribute ForceAtlas2 attraction along outbound edges
overlap_scaling_rationumber2> 0positive overlap repulsion scaling ratio
prevent_overlappingbooleanfalseprevent node overlap; requires a radius attribute
scaling_rationumber2> 0positive ForceAtlas2 repulsion scaling ratio
seedinteger0min 0; max 18446744073709552000random initialization seed
strong_gravity_modebooleanfalseuse stronger gravity for distant nodes
verbosebooleanfalsewhether ForceAtlas2 emits convergence information

Graph construction options​

This UDTF requires directed=false (undirected/symmetric graph). All other graph construction options follow the shared defaults documented in Graph Construction Options.

Output​

ColumnTypeNullableDescription
vertexInt64|Utf8noVertex receiving ForceAtlas2 layout coordinates.
xFloat32noX coordinate assigned by ForceAtlas2.
yFloat32noY coordinate assigned by ForceAtlas2.

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

Examples​

Where do brand neighborhoods appear when shared fans determine the map?​

The MerRec map places brands with shared fans nearby. Medical scrubs, golf, cameras, and bridal wear appear as separate regions. A merchandising team can inspect these groups before testing navigation collections.

The query derives distinct shopper-brand likes, scores the 5,000 brands with the most fans using Jaccard similarity, and keeps each brand's five nearest links for the layout. Leiden assigns colors from brand pairs whose Jaccard score reaches 0.02.

WITH fans AS (
SELECT -(e.user_id + 1) AS src, CAST(i.brand_id AS BIGINT) AS dst
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
GROUP BY e.user_id, i.brand_id
), top_brands AS (
SELECT dst AS brand_id, COUNT(*) AS fans FROM fans GROUP BY dst ORDER BY fans DESC, dst LIMIT 5000
), similar AS (
SELECT first, second, similarity
FROM cugraph_jaccard(
edges => (SELECT src, dst FROM fans),
vertex_pairs => (SELECT a.brand_id AS first, b.brand_id AS second
FROM top_brands a JOIN top_brands b ON a.brand_id < b.brand_id),
directed => false)
WHERE similarity >= 0.02
), nearest AS (
SELECT a, b, similarity,
ROW_NUMBER() OVER (PARTITION BY a ORDER BY similarity DESC, b) AS rk
FROM (SELECT first AS a, second AS b, similarity FROM similar
UNION ALL SELECT second AS a, first AS b, similarity FROM similar) d
), worlds AS (
SELECT vertex AS brand_id, community AS world
FROM cugraph_leiden(
edges => (SELECT first AS src, second AS dst, CAST(similarity AS DOUBLE) AS weight FROM similar),
directed => false, resolution => 3, seed => 42)
), layout AS (
SELECT vertex AS brand_id, x, y
FROM cugraph_force_atlas2(
edges => (SELECT a AS src, b AS dst, CAST(similarity AS DOUBLE) AS weight FROM nearest WHERE rk <= 5),
directed => false, max_iter => 2000, barnes_hut_optimize => true,
outbound_attraction_distribution => true, lin_log_mode => true,
scaling_ratio => 5, gravity => 5, seed => 42)
), 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 l.brand_id, b.brand_name, t.fans, w.world, l.x, l.y
FROM layout l
JOIN worlds w ON w.brand_id = l.brand_id
JOIN top_brands t ON t.brand_id = l.brand_id
JOIN brands b ON b.brand_id = l.brand_id
ORDER BY l.brand_id;

Hover or tap a dot for its brand, world and fans.

Shopping worldsSelect to compare
  • Unlabelled worlds2,073
4,853 brands placed by ForceAtlas2 from shared fans. Colors are Leiden shopping worlds. Dot area grows with fans. Gray dots belong to worlds without a label. Select one or more worlds to highlight them and rank their most-liked brands together.

Positions show neighborhoods, without a meaningful distance unit. Each region's label summarizes its leading brands. Layout coordinates can change between executions, so the map supports inspection of regions rather than precise distances between individual dots.

Limits​

  • vertex_attributes and initial_positions must contain exactly one non-null row for every graph vertex
  • duplicate, missing, and extra ForceAtlas2 side-input vertices are rejected at execution
  • radius, mobility, mass, x, and y side-input columns must be Float32
  • prevent_overlapping=true requires a radius binding
  • seed sets only the initial positions; coordinates differ between runs because force accumulation uses floating-point atomics