Skip to content

GFQL: indexed bindings bypass never engages on engine='polars-gpu' (silent loss of the index path) #1803

Description

@lmeyerov

What

graphistry/compute/gfql/lazy/engine/polars/chain.py::_try_indexed_middle_polars deliberately passes Engine.POLARS_GPU when the GPU execution target is active:

engine = Engine.POLARS_GPU if active_target() == ExecutionTarget.GPU else Engine.POLARS
return try_indexed_connected_bindings_state(g, middle, engine=engine), True

but graphistry/compute/gfql/index/bindings.py:307 — the first gate in try_indexed_connected_bindings_state — admits only three engines:

if (
    engine not in (Engine.PANDAS, Engine.CUDF, Engine.POLARS)
    ...
):
    return None

So on engine='polars-gpu' the indexed fixed-hop bindings bypass always declines, and the query silently runs the canonical scan instead.

Evidence

Measured on the dgx GB10 box, graphistry/test-rapids-official:26.02-gfql-polars, docker run --gpus all, cuDF 26.02 / cudf_polars present. index_trace() for [n({id:1}, name='a'), e_forward(name='r'), n(name='b'), rows()] with index_policy='force' on a gfql_index_all()-ed graph:

{'operation': 'indexed_traversal', 'seam': 'connected_bindings', 'engine': 'polars-gpu',
 'served': False, 'reason': 'unsupported_engine', 'path': 'scan',
 'decision_reason': 'unsupported_engine'}

The same query on engine='polars' is served by the bypass.

Impact

Not a wrong answer — every value/parity case in graphistry/tests/compute/gfql/test_rewrite_param_discard.py passes on polars-gpu (45 passed / 2 xfailed on the GPU run). What is lost is the optimization, with no signal at all: a user who indexes a polars graph and runs it on the GPU target gets the scan path and no indication that the index was skipped. That matters because polars-gpu is one of the two engines the perf work targets.

Why it looks like an oversight rather than a decision

The polars-specific branches inside bindings.py (lines 147, 163, 172, 196, 233, 403, 453) are all spelled engine == Engine.POLARS. A polars-gpu graph carries polars frames, so those branches are the ones it would need — i.e. widening the gate to POLARS_GPU also means widening those == Engine.POLARS tests to in (Engine.POLARS, Engine.POLARS_GPU). That is a small, mechanical change, but it is a change (and needs its own GPU parity run), so it is filed rather than folded into the test PR that found it.

Pinned

test_indexed_bypass_still_serves_a_bare_rows[polars-gpu] carries pytest.mark.xfail(strict=True) referencing this issue, so whoever widens the gate is told to delete the marker rather than leaving a stale "known gap".

Found by

Adding the polars-gpu parameter to test_rewrite_param_discard.py (CB3(b) — the file previously skipped polars-gpu). First GPU run, first finding.

Activity

  1. added a commit that references this issue on Jul 28, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions