GPU Coverage Validation
nexus_explain_coverage answers a plan-time question: what execution domains
does this exact SQL query use after physical planning? It plans the query but
does not execute it or acquire a GPU admission grant.
The answer is not a runtime guarantee. GPU admission, device memory, native
runtime errors, and cuGraph input checks still happen at execution time. Read
the returned runtime_caveats whenever the final plan contains GPU work.
SQL surface
On a session with the Nexus native optimizer installed, call the table function with one query string literal:
SELECT row_kind,
gpu_path,
candidate_shape,
reason_code,
remedy_code,
remedy_kind,
remedy,
coverage_json
FROM nexus_explain_coverage('SELECT l_returnflag, sum(l_quantity)
FROM lineitem GROUP BY l_returnflag');
The table function returns one summary row followed by one candidate row
per 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;
VERBOSE is accepted as the complete row mode. FORMAT JSON uses the same
Arrow schema but returns only the summary row, whose coverage_json contains
all candidate evidence. EXPLAIN GPU is Flight SQL statement-query syntax; it
cannot be prepared or sent to an update endpoint. Both the UDTF and Flight
schema carry datafusion_nexus.explain_gpu.schema_version=1 in Arrow schema
metadata so clients can identify this shared row contract without inspecting
its columns.
| Column | Meaning |
|---|---|
query_id | Flight SQL query identifier; null for an embedded UDTF call with no server query. |
row_kind | summary for final-plan coverage or candidate for one native candidate-selection outcome. |
gpu_path | native, partial_native, cpu, or terminal rejected. |
gpu_fragments, cpu_boundaries | Summary-row counts for GPU fragments and DataFusion CPU boundaries. |
physical_root, post_native_plan_root | Summary-row physical-plan roots. physical_root is the authoritative pre-native root captured by the retained optimizer diagnostics (null when no native optimizer diagnostic exists); post_native_plan_root is the completed executable plan's root. |
candidate_shape, candidate_family, outcome | Candidate-row shape, stable shape family, and selection (selected, not_supported, or not_selected_by_cost). The summary outcome is accepted_replaced, retained_datafusion, or rejected_before_execution. |
reason_code, unsupported_category | Stable candidate or terminal-rejection reason and its triage category. |
remedy_code, remedy_kind, remedy | Stable actionable advice for a non-selected candidate. Kinds include user_action, config_action, engine_gap, cudf_rs_gap, and cpu_preferred. |
detail_json | Summary metadata or candidate detail and cost evidence. |
coverage_json | The complete structured result on the summary row; null on candidate rows. |
Validation accepts exactly one query statement. Empty input, multiple
statements, non-query statements, and direct or view-indirect recursive calls
to nexus_explain_coverage return a structured terminal result.
Final disposition and GPU path
The final disposition is derived by walking the executable final physical plan. It is not inferred from whether an optimizer attempted a native rewrite.
| Final disposition | gpu_path | Meaning |
|---|---|---|
native | native | The planned path contains no known DataFusion CPU execution. GPU fragments and explicit GPU islands are counted together. |
mixed | partial_native | The same executable plan contains GPU runtime work and at least one DataFusion CPU boundary. |
datafusion | cpu | The executable plan has no selected GPU runtime node. |
rejected | rejected | Planning returned no executable plan. |
rejected includes the phase, stable reason_code, retry-advice
availability, and safe detail in coverage_json. Terminal source-resolution
failures, an unsupported required GPU island, and a failed final-plan
requirement are planning errors.
By contrast, an ordinary relational capability miss is not an error: the same
query remains executable on the DataFusion baseline and normally has final
disposition datafusion.
Candidate outcomes are diagnostics, not the final plan
coverage_json.candidate_outcomes retains relational candidate-selection
diagnostics from the native optimizer. Each entry has one of these outcome
values:
| Outcome | Meaning | Evidence |
|---|---|---|
selected | The candidate was selected for native execution. | Candidate shape (detail); reason_code, reason_kind, and category are absent. |
not_supported | The exact relational candidate is outside the native capability contract. | reason_code, reason_kind, candidate shape (detail), and category. |
not_selected_by_cost | The candidate is native-capable, but an enabled preference rule retained the DataFusion plan. | The same fields plus cost_evidence projected from native plan-preference facts. |
Every candidate carries its stable candidate_family; every non-selected
candidate also carries remedy_code, remedy_kind, and human-readable
remedy both in its table row and in coverage_json. These
are independent from final_disposition. A report can contain candidate
diagnostics while the final plan is native because another selected candidate
covers the executable path. Conversely, a not_supported or
not_selected_by_cost outcome normally produces an executable DataFusion plan,
not a rejected result. Candidate outcomes explain selection; final-plan domains
describe the completed executable plan.
Validation uses the caller's real planning contract
Validation clones the caller's SessionState. If that state has a Nexus
native optimizer rule, the clone receives an isolated copy of the exact
optimizer configuration after the cloned DataFusion options are applied. Its
completed-plan requirements are copied too. Validation does not install a
diagnostic policy and does not plan a second time under another configuration.
coverage_json.validated_under records:
| Field | Meaning |
|---|---|
native_optimizer_rule_installed | Whether the copied session had the native rule. |
optimizer_config_source | installed_session_rule or native_rule_absent. |
execution_mode | The copied native pipeline mode, when a native rule is present. |
final_plan_requirements | Requirements checked against the exact completed plan, such as no_datafusion_cpu. |
session_config_fingerprint and optimizer_fingerprint | Stable comparison stamps for the cloned configuration. |
catalog_snapshot | session_state_cloned_at_validation_call; it labels the clone and is not a catalog or table-data fingerprint. |
Revalidate after catalog, view, table, or configuration changes. The fingerprints do not claim that source metadata or table contents are unchanged.
Rust surface
The SQL function and Rust API use the same validation primitive:
use datafusion_nexus::{
gpu_coverage::{validate_query, QueryGpuCoverageOverall},
planner::FinalPlanDisposition,
};
let coverage = validate_query(&ctx, "SELECT count(*) FROM lineitem").await?;
match coverage.final_disposition {
FinalPlanDisposition::Native => {}
FinalPlanDisposition::DataFusion | FinalPlanDisposition::Mixed => {
for outcome in &coverage.candidate_outcomes {
eprintln!(
"{} reason_code={} reason_kind={} category={} detail={}",
outcome.selection.as_str(),
outcome.reason_code.as_deref().unwrap_or("absent"),
outcome.reason_kind.map_or("absent", |kind| kind.as_str()),
outcome.category.as_deref().unwrap_or("absent"),
outcome.detail,
);
if let Some(remedy) = outcome.remedy {
eprintln!("{} {}: {}", remedy.code, remedy.kind.as_str(), remedy.guidance);
}
}
}
FinalPlanDisposition::Rejected => {
if let QueryGpuCoverageOverall::Rejected { phase, reason_code, detail, .. } =
&coverage.overall
{
eprintln!("{} {reason_code}: {detail}", phase.as_str());
}
}
}
println!("{}", coverage.to_json());
The API is async because source planning can perform real I/O. It never
executes the returned plan or performs GPU admission.
Runtime caveats
| Code | Meaning |
|---|---|
runtime_gpu_admission_unknown | Query-service grants are acquired only at execution time and can wait or fail under concurrency; once admitted, each grant is immutable. |
device_memory_runtime_unknown | Allocation, reservation, and retry outcomes depend on data and concurrency. |
native_runtime_failure_has_no_cpu_rescue | Once native GPU execution starts, a native failure is terminal; Nexus does not replay it on CPU. |
host_output_materialization | Query output is materialized back to host Arrow outside the GPU-execution promise. |
cugraph_runtime_validation_unknown | cuGraph seed, personalization, weight, and device-side checks can still fail at runtime. |
execution_mode_plan_time_only | Coverage does not acquire a device grant; capability-first admission and bounded execution happen later for the selected native plan. |
Relationship to gpu_validate_call
gpu_validate_call
validates one installed GPU function call's named relations and provider-owned
options. Its result does not inspect the surrounding physical plan.
nexus_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 function call, then check coverage for the query that
will execute.