Explicit Fallback Surfaces¶
Request Signals¶
fallback
cpu fallback
unsupported predicate
unsupported geometry mix
diagnostics
runtime visibility
Open First¶
docs/architecture/fallbacks.md
docs/architecture/runtime.md
src/vibespatial/runtime/fallbacks.py
src/vibespatial/predicates/binary.py
src/vibespatial/spatial/query.py
Verify¶
uv run pytest tests/test_geopandas_fallbacks.pyuv run pytest tests/test_clip_public_api.py tests/test_index_array_boundary.py tests/test_io_arrow.py tests/test_spatial_query.py -quv run pytest tests/upstream/geopandas/tests/test_sindex.py -quv run pytest tests/upstream/geopandas/tests/test_array.py -k "contains or within or intersects"uv run python scripts/check_docs.py --check
Risks¶
Silent host execution makes it impossible to tell whether a GPU path exists.
Warning-based fallback can pollute upstream behavior if used as the only visibility channel.
Fallback logs are not useful if they omit the surface and the reason.
Intent¶
Make host-only execution observable without changing GeoPandas-compatible behavior, and require explicit fallback or compatibility events before any post-selection host materialization.
Decision¶
Use a lightweight fallback-event log instead of warnings as the primary observability channel.
Current policy:
fallback surfaces record
surface,requested,selected,reason, anddetailthe GeoPandas shim exposes
get_fallback_events()andclear_fallback_events()explicit
gpurequests in repo-owned kernels still fail loudlyauto/ GeoPandas-facing host paths record fallback events whenever they stay on CPU because the GPU path is unavailable or unsupportedstrict-native tests assert that fallback recording happens before host semantic cleanup or Shapely materialization
Current Surfaces¶
Fallback events are currently recorded for:
GeoPandas-facing binary predicates routed through
array.GeometryArray._binary_methodGeometryArray.sindexand other owned-backed public adapters that must materialize a host-side spatial indexsindex.querysindex.query_anywhen the indexed tree or query geometries cannot use the owned input-sized reduction pathsindex.query_aggregatewhen geometry or numeric inputs cannot use the native relation/grouped-reduction pathsindex.query_pair_aggregatewhen aligned owned geometry or paired native relation consumption is unavailablesindex.nearestdistance_owned– element-wise distance GPU-to-CPU fallbackgeometry_array_dwithin– dwithin GPU-to-CPU fallbackcliphost semantic cleanup and native clip export when the public result cannot stay in the owned/native boundaryoverlay
keep_geom_typesemantic probes and exact remainder paths that must leave the owned boundaryDeviceGeometryArray Shapely bridges for unsupported predicate, measurement, and constructive operations
GeoArrow / WKB / GeoParquet compatibility bridges and staged GPU decode or device-writer misses
An explicit storage_options, non-local filesystem, or to_pandas_kwargs
request selects the host GeoParquet compatibility transport by contract. That
choice is recorded as a CPU dispatch, not as an automatic GPU fallback, and is
therefore permitted in strict-native mode. An automatic host selection for an
otherwise GPU-eligible read remains an observable fallback.
Observability Contract¶
Fallback visibility must be:
machine-readable in code
narrow enough for repo-local tests
quiet enough to avoid changing upstream warning behavior
recorded before host semantic probes, object-array conversion, or Shapely materialization begin
That is why the event log is preferred over unconditional warnings.
Consequences¶
unsupported GPU paths are now observable in code without changing result semantics
repo-local tests can assert fallback behavior directly
strict-native mode can reject hidden mid-pipeline host exits instead of only warning after the fact
later GPU rollouts can shrink fallback-event volume surface by surface instead of relying on manual inspection