ECG
SQL function: cugraph_ecg
Official cuGraph reference: C API
Stabilize community assignments by combining an ensemble of randomized Louvain partitions into a final consensus clustering.
Signature
cugraph_ecg(table_name [, src_col, dst_col [, weight_col [, options_json]]])
Quickstart
The call below expects a registered edge table or view target_edges with endpoint columns src and dst. Substitute your own registered relations.
SELECT * FROM cugraph_ecg('target_edges');
Inputs
table_name must be a registered edge table or view (the edges role); parenthesized subqueries are not accepted, and metadata validation resolves the same registered name.
Endpoint columns accept numeric Int32, Int64 vertex IDs or logical string Utf8, LargeUtf8, Utf8View vertex IDs; string vertex-identity outputs are canonicalized to Utf8 (native mapping Int64) while scores, distances, counts, coordinates, and opaque labels stay numeric. The shared vertex-ID contract is summarized in Vertex ID support; the concrete call-specific schema comes from gpu_validate_call.
Logical string side-input limitations:
- edge ID columns and edge-ID predicate side inputs are not supported for logical string graphs
Arguments and options
Positional scalar arguments
src_col and dst_col name the edge endpoint columns; both are optional and default to src and dst.
| Argument | Type | Required | Default | Notes |
|---|---|---|---|---|
weight_col | Utf8|null | no | accepted as an edge-column binding; native algorithm execution does not consume weights; semantic effect: none for this algorithm |
JSON options
| Option | Type | Default | Constraints | Description |
|---|---|---|---|---|
ensemble_size | UInt32 | 10 | min 1 | Number of truncated Louvain runs on permuted inputs whose partitions vote on the final edge weights. Larger ensembles smooth the weights at proportionally higher cost. |
max_level | UInt32 | 100 | min 1 | Maximum number of hierarchy levels for the final Louvain pass. |
min_weight | Float64 | 0.001 | min 0 | Floor for edge weights in the final Louvain graph: an edge that no ensemble partition placed inside a community keeps this weight instead of zero. |
resolution | Float64 | 1 | > 0 | Resolution parameter (gamma) in the modularity formula. Higher values produce more, smaller communities; lower values produce fewer, larger ones. |
seed | UInt64 | 0 | Seed for the native random-number generator state that permutes the input for each ensemble run. Different seeds produce different ensembles. | |
threshold | Float64 | 1e-7 | min 0 | Minimum modularity gain for each level of the final Louvain pass; a level continues only while the gain exceeds it. |
Graph construction options
This function builds an undirected graph by default (directed=false); all other graph construction options follow the shared defaults documented in Graph Construction Options.
Output
| Column | Type | Nullable | Description |
|---|---|---|---|
vertex | Int64|Utf8 | no | Vertex assigned to an ECG community. |
partition | Int64 | no | Community identifier assigned by ECG. |
These are generic descriptor schemas; validate the call to get the concrete, table-specific output schema.
Examples
This example runs on the citation network demo dataset.
Benchmark the ensemble against single-run algorithms
ECG runs an ensemble of Louvain passes (ensemble_size, default 10), reweights
edges by how often their endpoints co-cluster, and clusters the consensus. Is
that worth it? Because every cugraph_* function returns a plain relation, one
statement can run all three community algorithms on the same subgraph (the
Louvain example's 2010s AI views) and score them against the human-assigned
primary_fos labels — the share of members in a community carrying its
dominant label:
CREATE OR REPLACE VIEW ai_nodes AS
SELECT paper_id FROM papers
WHERE year >= 2010 AND primary_fos IN (
'Deep learning', 'Artificial neural network', 'Convolutional neural network',
'Recurrent neural network', 'Natural language processing',
'Reinforcement learning', 'Image segmentation', 'Feature extraction',
'Object detection', 'Speech recognition');
CREATE OR REPLACE VIEW ai_edges AS
SELECT e.src, e.dst
FROM citation_edges e
JOIN ai_nodes a ON a.paper_id = e.src
JOIN ai_nodes b ON b.paper_id = e.dst;
WITH labeled AS (
SELECT 'louvain' AS algorithm, c."partition" AS community, p.primary_fos
FROM cugraph_louvain('ai_edges', 'src', 'dst') c
JOIN papers p ON p.paper_id = c.vertex
UNION ALL
SELECT 'leiden', c."partition", p.primary_fos
FROM cugraph_leiden('ai_edges', 'src', 'dst') c
JOIN papers p ON p.paper_id = c.vertex
UNION ALL
SELECT 'ecg', c."partition", p.primary_fos
FROM cugraph_ecg('ai_edges', 'src', 'dst') c
JOIN papers p ON p.paper_id = c.vertex),
counts AS (
SELECT algorithm, community, primary_fos, COUNT(*) AS n
FROM labeled GROUP BY 1, 2, 3),
sized AS (
SELECT algorithm, community, SUM(n) AS members, MAX(n) AS top_label
FROM counts GROUP BY 1, 2)
SELECT algorithm,
COUNT(*) AS communities,
COUNT(*) FILTER (WHERE members >= 100) AS ge100,
ROUND(SUM(top_label) FILTER (WHERE members >= 100) * 100.0
/ SUM(members) FILTER (WHERE members >= 100), 1) AS purity_pct
FROM sized
GROUP BY algorithm
ORDER BY purity_pct DESC;
| algorithm | communities | ge100 | purity_pct |
|---|---|---|---|
| leiden | 2,670 | 16 | 44.1 |
| ecg | 5,014 | 41 | 41.7 |
| louvain | 1,960 | 14 | 38.5 |
In this run the three GPU graph builds plus the joins and aggregation returned
together in about one second on the capture host. ECG's
consensus is deliberately conservative: it only keeps vertices together when
most ensemble members agree, so on this subgraph it produced the finest
partition (5,014 communities, 41 of them with 100+ papers) and scored above a
single Louvain run on label purity. Determinism comes from seed (default 0);
ensemble_size trades run time for consensus stability.
Limits
No algorithm-specific limitations.
Validate the call
Dry-run validation checks registered relation metadata, column presence, static dtypes, and options only; it does not scan edge data, construct a graph, or prove source-vertex existence:
SELECT * FROM gpu_validate_call(
'cugraph_ecg',
'{"schema_version":1,"relations":{"edges":{"table":"target_edges"}},"options":{"src_col":"src","dst_col":"dst"}}'
);
See GPU Function Catalog API for the full gpu_validate_call contract.