Skip to main content

GPU Coverage Validation

algeon_explain_coverage and EXPLAIN GPU report which parts of the query will execute on the GPU and which will stay on the DataFusion CPU path, with a stable reason and remedy for each part that was not selected. Coverage validation generates the physical plan without executing it. Consequently, resource admission waits, memory grant enforcement, runtime exceptions, and cuGraph input checks occur strictly at runtime, providing no execution guarantees. The returned runtime_caveats list them whenever the final plan contains GPU work, with codes in the runtime caveats table. Every column, JSON field and code is defined in the GPU Coverage Report reference.

Check a query​

On a session with the Algeon native optimizer installed, call the metadata UDTF with one query string literal:

SELECT row_kind,
gpu_path,
candidate_shape,
reason_code,
remedy_code,
remedy_kind,
remedy,
blocking,
coverage_json
FROM algeon_explain_coverage('SELECT l_returnflag, sum(l_quantity)
FROM lineitem GROUP BY l_returnflag');

The UDTF returns one summary row followed by one candidate row for each native-planning outcome. The Flight SQL server accepts the same projection without a string-literal escape layer:

EXPLAIN GPU SELECT l_returnflag, sum(l_quantity)
FROM lineitem GROUP BY l_returnflag;

EXPLAIN GPU FORMAT JSON SELECT l_returnflag, sum(l_quantity)
FROM lineitem GROUP BY l_returnflag;

Both forms return the same Arrow schema. VERBOSE is accepted as the complete row mode. FORMAT JSON returns only the summary row, whose coverage_json contains all candidate evidence. Send EXPLAIN GPU as a Flight SQL statement query or as a prepared statement without parameters. A prepared EXPLAIN GPU returns the coverage schema when it is prepared and plans the explained query each time the handle executes; this enables Python ADBC DB-API cursor.execute() to re-plan on each invocation. The update endpoint rejects EXPLAIN GPU.

A recorded Flight SQL session over the MerRec dataset ran EXPLAIN GPU on a query with four cuGraph calls. Its summary and candidate rows, reduced to the columns the capture kept, were:

row_kindgpu_pathgpu_fragmentscpu_boundariescandidate_familyoutcome
summarynative150accepted_replaced
candidatesort_fetch_hash_join_inputselected
candidateprojected_global_hash_join_aggregateselected
candidateother_literal_inputselected
candidateprojected_global_hash_join_aggregateselected
candidateprojected_global_hash_join_aggregateselected
candidateother_literal_inputselected
candidateprojected_global_hash_join_aggregateselected

Step 4 of the session capture holds the full SQL in native_required mode.

Read the result​

The summary row's gpu_path is read from the completed executable plan:

gpu_pathCompleted plan
nativeThe planned path contains no known DataFusion CPU execution.
partial_nativeGPU work and at least one DataFusion CPU boundary share the plan.
cpuThe plan has no selected GPU runtime node.

A statement that produces no executable plan reports the terminal rejected value, described below.

Candidate rows explain selection, and gpu_path describes the completed plan. One report can list a not_supported candidate under a native summary when another selected candidate covers the executable path.

reason_code says which contract a candidate missed. The blocking column names the part of the query that missed it, in one line such as cast from Int64 to Int32 in `CAST(buys AS INT)` , and is null when the producing site could not name it. The structured form is listed under what blocked a candidate.

Each non-selected candidate also carries remedy_code, a readable remedy and one of four remedy_kind values:

remedy_kindSuggested change
user_actionChange the query or its input, for example rewrite_expression.
config_actionChange a session setting, for example set_target_partitions_one.
engine_gapNative lowering lacks the capability. The remedy names the blocking shape.
cpu_preferredA preference rule kept the DataFusion plan.

The remedies for plan shapes table lists when a partition setting removes the blocker and when it does not.

Rejected statements​

A statement that fails parsing, logical planning, physical planning or a final-plan requirement returns one rejected summary row. Its gpu_fragments and cpu_boundaries cells are null. Candidate rows follow only when native planning recorded candidates before it failed:

{"planning_outcome":"rejected","reason_code":"invalid_request","detail":"cuML training relation requires a 'label' column","confidence":"plan_time_only","planning_did_io":false,"runtime_caveat_count":0}

reason_code and detail match the code and status message returned upon executing the statement. Handling Errors defines the correspondence between rejection fields and runtime errors. A few rejections exist only in the validator: empty input, multiple statements, a non-query statement, and a direct or view-indirect recursive call to algeon_explain_coverage. None of these validator rejections has an execution counterpart, and each carries its own stable reason_code and message.

cuGraph input relations​

A cuGraph function plans each input relation in its own nested session. The relation's candidate is reported with the function and the relation it feeds, such as cugraph_pagerank.edges, cugraph_bfs.sources or cugraph_bfs.include_edges. The label wraps the candidate shape in candidate_shape (cugraph_pagerank.edges(ProjectionExec(FilterExec(...)))), and candidate_family describes the shape under the label. When a relation cannot lower, its not_supported row follows the outer candidate and names the blocking subject, and a NativeRequired error names the same subject.

Each entry of coverage_json.cugraph_calls has algorithm, statically_valid, notes and inputs_native. inputs_native is true when every input relation reaches the graph as a native GPU-resident producer. It is false when at least one input runs on DataFusion and is staged through host Arrow. The labelled candidate rows give the reason.

Relationship to gpu_validate_call​

gpu_validate_call validates one installed GPU UDTF call's named relations and provider-owned options. Its result does not inspect the surrounding physical plan. algeon_explain_coverage inspects the whole planned query, including DataFusion boundaries feeding or consuming an explicit GPU island. Use both when composing graph SQL: validate the UDTF call, then check coverage for the query that will execute.