Skip to content

Commit a58da70

Browse files
lmeyerovclaude
andcommitted
docs(gfql): refresh perf docs with 0.58.0 release-tag-verified numbers
Refresh the GFQL performance and engine-selection docs to lead with numbers measured on the 0.58.0 release tag (DGX Spark GB10, warm medians N=30, results verified identical across engines): - Seeded typed-hop Cypher fast path, all four engines (pandas 29.9->2.46ms 12.1x, polars 13.8->2.28ms 6.1x, cuDF 30.1->4.89ms 6.1x, polars-gpu 25.2->2.49ms 10.1x; native chain pandas 21.1->1.65ms 12.8x, cuDF 23.2->3.84ms 6.0x) - Resident-index covered-shape lookups (pandas 1.74 / polars 1.59 / polars-gpu 1.91 / cudf 5.78 ms) with the 0.58.0 caveat that Polars frames need gfql_index_all(engine='polars') explicitly (fix in PR #1767) - Flat seeded-hop scaling on pandas: 0.159-0.164ms from 0.25M to 32M edges (pandas-only; polars hop not yet index-routed) - One-keyword engine='polars' LDBC SNB SF1 seed-lookup: 1,299.6->106.1ms (12.3x, same build) — replaces the stale "up to ~38x" headline in engines/performance/quick/about/overview/index - LDBC SNB interactive SF1 vs Neo4j 5.26, same box, warm: GFQL wins 4 of 5 clean pairs; Neo4j wins recent-replies (reported as-is) - OLAP multi-join vs embedded Kuzu (100k scale, engine='polars'): q8 5.0ms vs 1,004ms (200x), q9 14.2x — with the honest inverse (Kuzu wins single-table aggregates 2-4x, seeded property-projection lookups 2.4-64x) Prior Orkut/LiveJournal bulk-sweep tables are retained but relabeled as prior-release measurements; methodology disclosures kept and extended with the 0.58.0 tag-sweep provenance. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Y6dQEcjdazEnzuvuwf73ZL
1 parent 48e73fc commit a58da70

7 files changed

Lines changed: 258 additions & 48 deletions

File tree

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.htm
1010

1111
### Documentation
1212
- **GFQL pay-as-you-go resident indexing user guide**: New :doc:`Pay-As-You-Go Resident Indexing <gfql/indexing>` page — the lifecycle guide to resident indexes (`gfql_index_all()` / `gfql_index_edges()` / `create_index()` / `show_indexes()` / `drop_index()`): what the node-id + CSR in/out adjacency sidecars are, what engages them on 0.58.0 (seeded typed-hop fast paths incl. property RETURNs and property-seeded lookups per #1768/#1770, direct `g.hop()`; the general polars chain traversal honestly noted as not yet covered), the staleness/validity contract (identity + fingerprint; rebind invalidates; declines are safe — identical results either way), engine notes (polars needs `gfql_index_all(engine='polars')` until #1767), 0.58.0-tag measured numbers, and a runnable end-to-end example. Wired into the GFQL toctree + recommended paths alongside :doc:`Seeded Traversal Indexes <gfql/index_adjacency>`.
13+
- **GFQL performance docs refreshed with 0.58.0 release-tag-verified numbers**: `gfql/performance.rst` and `gfql/engines.rst` now lead with numbers measured on the `0.58.0` release tag (DGX Spark GB10, warm medians N=30, results verified identical across engines): the seeded typed-hop Cypher fast path across all four engines (pandas 29.9→2.46ms 12.1×, polars 13.8→2.28ms 6.1×, cuDF 30.1→4.89ms 6.1×, polars-gpu 25.2→2.49ms 10.1×; native chain pandas 21.1→1.65ms 12.8×), resident-index covered-shape lookups (1.59–5.78ms, with the 0.58.0 `gfql_index_all(engine='polars')` caveat / PR #1767), flat seeded-hop scaling on pandas (0.159–0.164ms from 0.25M to 32M edges), the one-keyword `engine='polars'` LDBC SNB SF1 seed-lookup win (1,299.6→106.1ms, 12.3×), LDBC SNB interactive SF1 vs Neo4j 5.26 same-box pairs (GFQL 4 of 5; Neo4j wins recent-replies — reported as-is), and OLAP multi-join vs embedded Kuzu (q8 200×, q9 14.2×) with the honest inverse (Kuzu wins single-table aggregates 2–4× and seeded property-projection lookups 2.4–64×). Older Orkut/LiveJournal bulk-sweep tables are retained but relabeled as prior-release measurements; the stale "up to ~38×" headline in `engines.rst`, `performance.rst`, `quick.rst`, `about.rst`, `overview.rst`, and `index.rst` is replaced with the tag-verified 12.3× LDBC figure.
1314

1415
## [0.58.0 - 2026-07-22]
1516

docs/source/gfql/about.rst

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -382,7 +382,7 @@ results on every engine — see :doc:`Choosing an Engine <engines>`.
382382

383383
::
384384

385-
g_result = g.gfql([ ... ], engine='polars') # up to ~38x over pandas on real graphs
385+
g_result = g.gfql([ ... ], engine='polars') # e.g. 12.3x over pandas on LDBC SNB SF1 seed-lookup
386386

387387
**Example: Force GFQL to use a GPU engine**
388388

docs/source/gfql/engines.rst

Lines changed: 118 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,13 @@ engine is a one-keyword change — no GPU, same results:
3131
query = "MATCH (a)-[e]->(b) RETURN b" # any GFQL / Cypher query
3232
3333
g.gfql(query) # engine='pandas' (default)
34-
g.gfql(query, engine='polars') # up to ~38x faster on real graphs, no GPU, identical results
34+
g.gfql(query, engine='polars') # e.g. 12.3x on LDBC SNB SF1 seed-lookup, no GPU, identical results
35+
36+
On the 0.58.0 release build (DGX Spark GB10, warm medians N=30, results verified
37+
identical), the LDBC SNB SF1 seed-lookup drops from **1,299.6 ms** on eager pandas to
38+
**106.1 ms** with ``engine='polars'`` — **12.3×** from one keyword on the same build. See
39+
:ref:`gfql-0580-numbers` for the full release-verified sweep (seeded fast paths, resident
40+
index, vs Neo4j, OLAP).
3541

3642
Your existing pandas, Polars, or cuDF graph works as-is: the input frames are accepted and
3743
coerced once; the only change is the keyword. The catch: a few exotic Cypher features still
@@ -96,11 +102,55 @@ The four engines
96102
``engine='auto'`` resolves to ``cudf`` for cuDF input and ``pandas`` otherwise. **AUTO
97103
never selects Polars or Polars-GPU** — they are explicit opt-in (see *Why opt-in?* below).
98104

99-
Motivating comparison (real graphs)
100-
-----------------------------------
105+
Release-verified snapshot (0.58.0): seeded typed hop, four engines
106+
------------------------------------------------------------------
107+
108+
Measured on the **0.58.0 release tag** (DGX Spark GB10, warm medians N=30, results
109+
verified identical across engines): the seeded typed-hop Cypher fast path —
110+
``MATCH (m {id: ...})-[:T]->(p) RETURN p`` on a 50k-node / 200k-edge graph — before →
111+
after on the same tag sweep:
112+
113+
.. list-table::
114+
:header-rows: 1
115+
:widths: 25 20 25 15
116+
117+
* - Engine
118+
- Before
119+
- After (0.58.0 fast path)
120+
- Speedup
121+
* - ``pandas``
122+
- 29.9 ms
123+
- **2.46 ms**
124+
- 12.1×
125+
* - ``polars``
126+
- 13.8 ms
127+
- **2.28 ms**
128+
- 6.1×
129+
* - ``cudf``
130+
- 30.1 ms
131+
- **4.89 ms**
132+
- 6.1×
133+
* - ``polars-gpu``
134+
- 25.2 ms
135+
- **2.49 ms**
136+
- 10.1×
137+
138+
The native chain form is faster still (pandas 21.1 → **1.65 ms**, 12.8×; cuDF 23.2 →
139+
**3.84 ms**, 6.0×), and the opt-in resident index (``g.gfql_index_all()``) brings the
140+
covered-shape lookup to **1.74 ms** pandas / **1.59 ms** polars / **1.91 ms** polars-gpu /
141+
**5.78 ms** cudf. (Polars index caveat on 0.58.0: build with
142+
``g.gfql_index_all(engine='polars')`` explicitly — an AUTO build swaps Polars frames to
143+
pandas; fix tracked in PR #1767.) The full release-verified sweep — flat scaling to 32M
144+
edges, LDBC SNB vs Neo4j, OLAP multi-join — is in :ref:`gfql-0580-numbers`.
145+
146+
Motivating comparison (real graphs — prior sweep)
147+
-------------------------------------------------
101148

102149
Same query, same answers, four engines. Warm-median latency on **Orkut** (3.1M nodes /
103-
**117M edges**, SNAP), measured on a single machine:
150+
**117M edges**, SNAP), measured on a single machine. *These are prior-release
151+
measurements from an earlier bulk sweep (pre-0.58.0), retained as a bulk-workload
152+
example — the release-verified 0.58.0 numbers are in the snapshot above and in*
153+
:ref:`gfql-0580-numbers`:
104154

105155
.. list-table::
106156
:header-rows: 1
@@ -135,10 +185,11 @@ Same query, same answers, four engines. Warm-median latency on **Orkut** (3.1M n
135185
*Warm median, identical result rows across all four engines. Reproducer:*
136186
``benchmarks/gfql/index_bulk_olap_bench.py``. *See Methodology below.*
137187

138-
Reading the table:
188+
Reading the table (prior sweep):
139189

140-
- **Polars-CPU beats pandas up to ~38x** on bulk traversal and ~4x on aggregation — **with no
141-
GPU**. On the 1-hop workload it is ~38x faster than pandas (68 ms vs 2613 ms).
190+
- **Polars-CPU beat pandas up to ~38x** on bulk traversal and ~4x on aggregation in that
191+
sweep — **with no GPU**. On the 1-hop workload it was ~38x faster than pandas (68 ms vs
192+
2613 ms).
142193
- **Polars-CPU also beats cuDF** on these shapes (68 ms vs 1005 ms on 1-hop). cuDF runs
143194
GFQL *eagerly*, op by op (a kernel launch + a materialized intermediate per hop), while
144195
Polars builds **one fused lazy plan and collects once**. The fused plan wins until the
@@ -148,10 +199,10 @@ Reading the table:
148199
- **cuDF wins the one extreme case** — a 2-hop from 100K seeds materializing ~85M output rows
149200
(6.0 s) — where raw GPU throughput on a single massive join overtakes everything and
150201
Polars-GPU comes under memory pressure (footnote F3).
151-
- On a smaller graph (**LiveJournal**, 35M edges) the pattern holds: 1-hop from 10K seeds is
202+
- On a smaller graph (**LiveJournal**, 35M edges) the pattern held: 1-hop from 10K seeds was
152203
pandas 1129 ms → polars **37 ms** (~30x). Filter- and lookup-heavy workloads favor Polars
153-
even more strongly — a separate **LDBC SNB sf1** benchmark shows order-of-magnitude gains
154-
(tens of × over pandas; see ``benchmarks/gfql/`` and the GFQL benchmark notes).
204+
as well — on the 0.58.0 tag, the **LDBC SNB SF1** seed-lookup is pandas 1,299.6 ms →
205+
polars **106.1 ms** (**12.3×**, same build; see :ref:`gfql-0580-numbers`).
155206

156207
.. note::
157208
Route by workload shape and size (next section). **CPU Polars wins the common graph-query
@@ -185,19 +236,31 @@ benchmarked** rather than guess.
185236
- Where it complements / GFQL doesn't claim
186237
* - **Neo4j + GDS**
187238
- Server + GDS library; stand up a DB and ETL your data in.
188-
- **Filter→PageRank→filter pipeline**, dgx-spark GB10, warm median: Twitter 2.4M —
189-
13.83 s Neo4j vs 2.55 s GFQL-CPU / **0.30 s GFQL-GPU (46×)**; GPlus 30M —
190-
**>187 s (did-not-finish)** vs 75.78 s CPU / **3.33 s GPU (>56×)**.
191-
- Neo4j remains the transactional system-of-record; run the read-heavy analytics in
192-
GFQL. See :doc:`benchmark_filter_pagerank`.
239+
- **LDBC SNB interactive SF1** vs Neo4j 5.26 (0.58.0 tag, same box, warm): GFQL wins
240+
**4 of 5** clean pairs — seed-lookup **106.1 vs 143.7 ms**, message-content
241+
**7.1 vs 23.0 ms**, message-creator **6.8 vs 27.7 ms** (flip shipped in 0.58.0 via
242+
property-seeded resident-index gathers, PR #1770), one-hop-expand
243+
**111.9 vs 180.7 ms**. Prior sweep: **filter→PageRank→filter pipeline**, dgx-spark
244+
GB10, warm median: Twitter 2.4M — 13.83 s Neo4j vs 2.55 s GFQL-CPU /
245+
**0.30 s GFQL-GPU (46×)**; GPlus 30M — **>187 s (did-not-finish)** vs 75.78 s CPU /
246+
**3.33 s GPU (>56×)**.
247+
- **Neo4j wins recent-replies** (104.0 vs 209.6 ms) in the same LDBC pairs — reported
248+
as-is. Neo4j remains the transactional system-of-record; run the read-heavy
249+
analytics in GFQL. See :doc:`benchmark_filter_pagerank`.
193250
* - **Kuzu**
194251
- Embedded graph DB; still a separate store to load + index.
195-
- **Seeded index lookup** (0.8M nodes / 6.4M edges): 1-hop **0.123 ms vs 1.15 ms
196-
(9.4×)**, 2-hop **0.150 ms vs 4.25 ms (28×)**; prepared-Kuzu LiveJournal 35M ~ **17×**
197-
typical seed, 6× hub. **Bulk frontier expansion** (LiveJournal 35M, 1-hop, many
198-
seeds): **22× Kuzu**, up to **87× at k=100k**. See :doc:`index_adjacency`.
199-
- **Not claimed:** cyclic / multi-way-join patterns (triangles, cliques) where Kuzu's
200-
worst-case-optimal joins can win. Use Kuzu as the store; GFQL for bulk read analytics.
252+
- **OLAP multi-join** (graph-benchmark, 100k-node scale, 0.58.0 tag,
253+
``engine='polars'``): q8 **5.0 ms vs 1,004 ms embedded Kuzu (200×)**; q9 **14.2×**.
254+
Prior sweep — **seeded index lookup** (0.8M nodes / 6.4M edges): 1-hop
255+
**0.123 ms vs 1.15 ms (9.4×)**, 2-hop **0.150 ms vs 4.25 ms (28×)**; prepared-Kuzu
256+
LiveJournal 35M ~ **17×** typical seed, 6× hub; **bulk frontier expansion**
257+
(LiveJournal 35M, 1-hop, many seeds): **22× Kuzu**, up to **87× at k=100k**.
258+
See :doc:`index_adjacency`.
259+
- **Kuzu wins in the same 0.58.0 sweep:** single-table aggregates (**2–4×**) and
260+
seeded property-projection lookups (**2.4–64×**) — GFQL's strengths are traversals,
261+
multi-join OLAP, and covered seeded shapes. Also **not claimed:** cyclic /
262+
multi-way-join patterns (triangles, cliques) where Kuzu's worst-case-optimal joins
263+
can win. Use Kuzu as the store; GFQL for bulk read analytics.
201264
* - **LadybugDB**
202265
- Actively-maintained **Kuzu fork** (Kuzu is archived); embedded C++, strongly-typed
203266
Cypher, opt-in ART *or* hash indexing, zero-copy Arrow/CSR scans, and **out-of-core
@@ -254,9 +317,13 @@ benchmarked** rather than guess.
254317
GFQL **complements** a graph database more than it replaces one: keep Neo4j or Kuzu as the
255318
system-of-record, and do the read-heavy search + analytics in GFQL so ETL, traversal, and
256319
scoring stay in one in-process dataframe pipeline. Route by shape — **selective** seeded
257-
lookups favor the GFQL index (up to 28× Kuzu, 16.9× Neo4j on 2-hop), **bulk** frontier
258-
expansion and full pipelines favor Polars / GPU (22–87× Kuzu; **46–56× Neo4j** on the
259-
filter→PageRank→filter pipeline). Against the **distributed** engines the axis is different:
320+
lookups favor the GFQL index (up to 28× Kuzu, 16.9× Neo4j on 2-hop in prior sweeps;
321+
covered-shape lookups at 1.6–1.9 ms on the 0.58.0 tag), **multi-join OLAP** favors Polars
322+
(q8 **200× Kuzu** on the 0.58.0 tag), and **bulk** frontier expansion and full pipelines
323+
favor Polars / GPU (22–87× Kuzu; **46–56× Neo4j** on the filter→PageRank→filter pipeline,
324+
prior sweeps). The inverse holds too: embedded Kuzu wins single-table aggregates (2–4×)
325+
and seeded property-projection lookups (2.4–64×) in the same 0.58.0 sweep.
326+
Against the **distributed** engines the axis is different:
260327
GFQL trades horizontal scale-out for zero cluster/warehouse setup and interactive latency —
261328
choose it below the single-machine ceiling (100M+ edges fit in-process; a cluster is only
262329
needed once the graph genuinely exceeds one node's memory), and complement PuppyGraph's
@@ -285,7 +352,7 @@ Decision matrix
285352
- > ~10K
286353
- CPU
287354
- ``polars``
288-
- wins from ~10K (2.7x); up to ~38x pandas, ~15x cuDF at 100M [F1]
355+
- wins from ~10K (2.7x); up to ~38x pandas, ~15x cuDF at 100M (prior sweep) [F1]
289356
* - Heavy multi-hop (2-hop+)
290357
- large
291358
- GPU
@@ -332,12 +399,14 @@ result as a GPU run (see *Honesty* below).
332399
**[F5] Selective traversal is an indexing problem, not an engine choice.** A seeded ``hop``
333400
from a few nodes is fastest with the opt-in **CSR adjacency index** (``g.gfql_index_all()`` /
334401
``g.create_index(...)``, ``index_policy=``), which turns the O(E) scan into an O(degree)
335-
gather — flat in graph size, and 9–28× faster than Kuzu / Neo4j on selective lookups. It works
336-
on all four engines, but seeded work is so small that **CPU wins**: on LiveJournal 35M a
337-
typical-seed 1-hop is ~0.13 ms on pandas and ~0.16 ms on Polars (numpy ``searchsorted``) vs
338-
~3 ms on cuDF (GPU kernel-launch floor) — the clean inverse of bulk, where the GPU pulls
339-
ahead. So pick the index for selective traversal and a CPU engine to drive it. See
340-
:doc:`index_adjacency` for the full guide.
402+
gather — flat in graph size: on the 0.58.0 tag, a native seeded 1-hop ``g.hop()`` on pandas
403+
holds **0.159–0.164 ms from 0.25M to 32M edges** (constant avg degree 4; pandas-only —
404+
the Polars hop path is not yet index-routed). It works on all four engines, but seeded
405+
work is so small that **CPU wins**: in a prior LiveJournal 35M sweep a typical-seed 1-hop
406+
was ~0.13 ms on pandas and ~0.16 ms on Polars (numpy ``searchsorted``) vs ~3 ms on cuDF
407+
(GPU kernel-launch floor) — the clean inverse of bulk, where the GPU pulls ahead. So pick
408+
the index for selective traversal and a CPU engine to drive it. See :doc:`index_adjacency`
409+
for the full guide.
341410

342411
Switching engines
343412
-----------------
@@ -386,7 +455,10 @@ never selects Polars or Polars-GPU**, so those two are always an explicit opt-in
386455
.. tip::
387456
For selective, seeded traversal, build the CSR adjacency index once with
388457
``g.gfql_index_all()`` (or ``index_policy=``) — it works on all four engines
389-
and turns the O(E) scan into an O(degree) gather. See :doc:`index_adjacency`.
458+
and turns the O(E) scan into an O(degree) gather. **On 0.58.0, Polars frames need
459+
the engine passed explicitly** — ``g.gfql_index_all(engine='polars')`` — because an
460+
AUTO build swaps Polars frames to pandas (fix tracked in PR #1767).
461+
See :doc:`index_adjacency`.
390462

391463
.. _gfql-offengine-calls:
392464

@@ -549,11 +621,14 @@ Honesty matters more than a bigger number:
549621
misreport pandas performance as Polars (see *Honesty*).
550622
- **One extreme materialization (80M+ output rows):** prefer ``cudf`` over ``polars-gpu``
551623
(footnote F3).
552-
- **vs graph databases:** GFQL-Polars beats embedded kuzu on frontier expansion (up to ~87x
553-
on LiveJournal 1-hop in our runs — reproducer ``benchmarks/gfql/index_vs_kuzu_prepared.py``),
554-
and separately beats Neo4j+GDS end-to-end (:doc:`benchmark_filter_pagerank`). The honest
555-
boundary: kuzu's worst-case-optimal joins target **cyclic / multi-way join** patterns
556-
(triangles, cliques) that we have **not** yet benchmarked, and kuzu may lead there.
624+
- **vs graph databases:** GFQL-Polars beats embedded kuzu on multi-join OLAP (q8 **200×**,
625+
q9 **14.2×** on the 0.58.0 tag) and, in prior sweeps, on frontier expansion (up to ~87x
626+
on LiveJournal 1-hop — reproducer ``benchmarks/gfql/index_vs_kuzu_prepared.py``); it
627+
separately beats Neo4j+GDS end-to-end (:doc:`benchmark_filter_pagerank`). The honest
628+
boundary: in the same 0.58.0 sweep, embedded kuzu **wins single-table aggregates (2–4×)
629+
and seeded property-projection lookups (2.4–64×)**, and its worst-case-optimal joins
630+
target **cyclic / multi-way join** patterns (triangles, cliques) that we have **not**
631+
yet benchmarked, and kuzu may lead there.
557632

558633
Parity and honesty
559634
------------------
@@ -580,6 +655,12 @@ Parity and honesty
580655
Methodology
581656
-----------
582657

658+
- **0.58.0 release-tag sweep** (the seeded typed-hop snapshot, resident-index and
659+
flat-scaling numbers, LDBC SNB SF1 / Neo4j 5.26 pairs, and OLAP q8/q9 above): measured
660+
on the ``0.58.0`` release tag on an NVIDIA DGX Spark (GB10), **warm medians over
661+
N=30 runs**, result rows asserted identical across engines before any timing was kept;
662+
the Neo4j pairs ran on the same box, warm.
663+
- Prior bulk sweep (the Orkut / LiveJournal tables and their derived ratios), pre-0.58.0:
583664
- Host: NVIDIA DGX Spark (GB10 Grace-Blackwell, unified memory — the F3 memory-pressure
584665
boundary is partly a property of this box), RAPIDS container
585666
``graphistry/test-rapids-official:26.02-gfql-polars``.

docs/source/gfql/index.rst

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ Recommended paths:
3636

3737
- New to GFQL: :doc:`overview` -> :doc:`quick` -> :doc:`where` -> :doc:`return`
3838
- Running Cypher syntax in GFQL: :doc:`cypher` -> :doc:`quick` -> :doc:`return` -> :doc:`spec/cypher_mapping`
39-
- Faster on CPU (no GPU): :doc:`engines` -> :doc:`performance` (one keyword, ``engine='polars'``, up to ~38x over pandas)
39+
- Faster on CPU (no GPU): :doc:`engines` -> :doc:`performance` (one keyword, ``engine='polars'``, e.g. 12.3x over pandas on LDBC SNB SF1 seed-lookup)
4040
- Performance path (intro -> engine choice -> GPU -> remote GPU): :doc:`about` -> :doc:`engines` -> :doc:`performance` -> :doc:`remote`
4141
- Fast seeded lookups (start from known nodes, like a DB index): :doc:`indexing` (build once with ``gfql_index_all()``, reused automatically) -> :doc:`index_adjacency` (O(degree), flat in graph size, 9-28x vs Kuzu/Neo4j)
4242
- Translating existing Cypher to native GFQL: :doc:`spec/cypher_mapping`

docs/source/gfql/overview.rst

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -316,7 +316,7 @@ Key advantages of GFQL Let:
316316
Leveraging GPU Acceleration
317317
~~~~~~~~~~~~~~~~~~~~~~~~~~~~
318318

319-
GFQL runs the same query on four interchangeable engines, all returning identical results: ``pandas`` (CPU, default), ``polars`` (CPU columnar — up to ~38x over pandas, **no GPU**), ``cudf`` (NVIDIA GPU), and ``polars-gpu`` (NVIDIA GPU). ``engine='auto'`` resolves to ``cudf`` for cuDF input and ``pandas`` otherwise; ``polars`` / ``polars-gpu`` are explicit opt-in (``auto`` never selects them — **so a Polars-frame graph run with the default is coerced to pandas; pass** ``engine='polars'`` **to stay native**). Neither silently bridges: ``polars-gpu`` is GPU-or-error, and unsupported Polars/Cypher shapes are declined during validation, compilation, or planning before execution rather than falling back to pandas. See :doc:`Choosing an Engine <engines>` for the decision matrix and benchmarks.
319+
GFQL runs the same query on four interchangeable engines, all returning identical results: ``pandas`` (CPU, default), ``polars`` (CPU columnar — e.g. 12.3x over pandas on the LDBC SNB SF1 seed-lookup, **no GPU**), ``cudf`` (NVIDIA GPU), and ``polars-gpu`` (NVIDIA GPU). ``engine='auto'`` resolves to ``cudf`` for cuDF input and ``pandas`` otherwise; ``polars`` / ``polars-gpu`` are explicit opt-in (``auto`` never selects them — **so a Polars-frame graph run with the default is coerced to pandas; pass** ``engine='polars'`` **to stay native**). Neither silently bridges: ``polars-gpu`` is GPU-or-error, and unsupported Polars/Cypher shapes are declined during validation, compilation, or planning before execution rather than falling back to pandas. See :doc:`Choosing an Engine <engines>` for the decision matrix and benchmarks.
320320

321321
When you use cuDF (GPU) dataframes with ``engine='auto'``, GFQL executes queries on the GPU for massive speedups.
322322

0 commit comments

Comments
 (0)