vibespatial.geometry.owned¶
Attributes¶
Classes¶
Enum where members are also (and must be) strings |
|
Enum where members are also (and must be) strings |
|
Columnar geometry storage with optional device-resident metadata. |
Functions¶
|
Extract unique (left_tag, right_tag) pairs without Python-level iteration. |
|
Seed the per-row validity cache with an all-valid mask. |
Rebuild a device family buffer after a span-preserving coordinate rewrite. |
|
|
Rebuild a host family buffer after a span-preserving coordinate rewrite. |
|
|
|
|
|
Build an all-null OwnedGeometryArray without materializing Shapely. |
|
|
|
|
|
Scatter replacement rows into base at indices, returning a new array. |
|
Concatenate owned geometry arrays without materializing geometry objects. |
|
Scatter replacement rows into base without leaving the device. |
|
Construct an OwnedGeometryArray from device buffers without touching host. |
Forward metadata for a device result without forcing host copies. |
|
|
Create an N-row owned array from a 1-row owned array. |
|
Physically replicate coordinate buffers in a tiled owned array. |
Module Contents¶
- vibespatial.geometry.owned.cp = None¶
- vibespatial.geometry.owned.NULL_TAG = -1¶
- vibespatial.geometry.owned.FAMILY_TAGS: dict[vibespatial.geometry.buffers.GeometryFamily, int]¶
- vibespatial.geometry.owned.TAG_FAMILIES¶
- vibespatial.geometry.owned.unique_tag_pairs(left_tags: numpy.ndarray, right_tags: numpy.ndarray) list[tuple[int, int]]¶
Extract unique (left_tag, right_tag) pairs without Python-level iteration.
Works with both numpy and CuPy arrays. Packs two int8 tags into one int16 and calls the array library’s
unique, then unpacks the small result (at most 36 pairs for 6 geometry families) on the host.This replaces the
set(zip(left.tolist(), right.tolist()))anti-pattern which forces a full-array D->H transfer and O(n) Python iteration.Precondition: tag values must be non-negative and fit in int8 (0..127). Callers must filter null rows (NULL_TAG = -1) before calling.
- vibespatial.geometry.owned.seed_all_validity_cache(owned: OwnedGeometryArray | None) None¶
Seed the per-row validity cache with an all-valid mask.
Exact overlay/clip results and successful post-repair outputs are already normalized geometry buffers. Marking them valid avoids re-running full OGC validity scans when those public results feed immediately into another polygon operation.
- class vibespatial.geometry.owned.DiagnosticKind¶
Enum where members are also (and must be) strings
- CREATED = 'created'¶
- TRANSFER = 'transfer'¶
- MATERIALIZATION = 'materialization'¶
- RUNTIME = 'runtime'¶
- CACHE = 'cache'¶
- class vibespatial.geometry.owned.BufferSharingMode¶
Enum where members are also (and must be) strings
- COPY = 'copy'¶
- SHARE = 'share'¶
- AUTO = 'auto'¶
- class vibespatial.geometry.owned.DiagnosticEvent¶
- kind: DiagnosticKind¶
- detail: str¶
- residency: vibespatial.runtime.residency.Residency¶
- visible_to_user: bool = False¶
- elapsed_seconds: float = 0.0¶
- bytes_transferred: int = 0¶
- class vibespatial.geometry.owned.FamilyGeometryBuffer¶
-
- row_count: int¶
- x: numpy.ndarray¶
- y: numpy.ndarray¶
- geometry_offsets: numpy.ndarray¶
- empty_mask: numpy.ndarray¶
- part_offsets: numpy.ndarray | None = None¶
- ring_offsets: numpy.ndarray | None = None¶
- bounds: numpy.ndarray | None = None¶
- host_materialized: bool = True¶
- class vibespatial.geometry.owned.GeoArrowBufferView¶
-
- x: numpy.ndarray¶
- y: numpy.ndarray¶
- geometry_offsets: numpy.ndarray¶
- empty_mask: numpy.ndarray¶
- part_offsets: numpy.ndarray | None = None¶
- ring_offsets: numpy.ndarray | None = None¶
- bounds: numpy.ndarray | None = None¶
- class vibespatial.geometry.owned.MixedGeoArrowView¶
- validity: numpy.ndarray¶
- tags: numpy.ndarray¶
- family_row_offsets: numpy.ndarray¶
- families: dict[vibespatial.geometry.buffers.GeometryFamily, GeoArrowBufferView]¶
- class vibespatial.geometry.owned.DeviceFamilyGeometryBuffer¶
-
- x: vibespatial.cuda._runtime.DeviceArray¶
- y: vibespatial.cuda._runtime.DeviceArray¶
- geometry_offsets: vibespatial.cuda._runtime.DeviceArray¶
- empty_mask: vibespatial.cuda._runtime.DeviceArray¶
- part_offsets: vibespatial.cuda._runtime.DeviceArray | None = None¶
- ring_offsets: vibespatial.cuda._runtime.DeviceArray | None = None¶
- bounds: vibespatial.cuda._runtime.DeviceArray | None = None¶
- dense_single_ring_width: int | None = None¶
- vibespatial.geometry.owned.build_updated_device_family_buffer(family: vibespatial.geometry.buffers.GeometryFamily, device_buf: DeviceFamilyGeometryBuffer, d_x_out: vibespatial.cuda._runtime.DeviceArray, d_y_out: vibespatial.cuda._runtime.DeviceArray, d_new_offsets: vibespatial.cuda._runtime.DeviceArray) DeviceFamilyGeometryBuffer¶
Rebuild a device family buffer after a span-preserving coordinate rewrite.
- vibespatial.geometry.owned.build_updated_host_family_buffer(family: vibespatial.geometry.buffers.GeometryFamily, host_buf: FamilyGeometryBuffer, x_out: numpy.ndarray, y_out: numpy.ndarray, new_offsets: numpy.ndarray) FamilyGeometryBuffer¶
Rebuild a host family buffer after a span-preserving coordinate rewrite.
- class vibespatial.geometry.owned.OwnedGeometryDeviceState¶
- validity: vibespatial.cuda._runtime.DeviceArray¶
- tags: vibespatial.cuda._runtime.DeviceArray¶
- family_row_offsets: vibespatial.cuda._runtime.DeviceArray¶
- families: dict[vibespatial.geometry.buffers.GeometryFamily, DeviceFamilyGeometryBuffer]¶
- row_bounds: vibespatial.cuda._runtime.DeviceArray | None = None¶
- class vibespatial.geometry.owned.OwnedGeometryArray(validity: numpy.ndarray | None, tags: numpy.ndarray | None, family_row_offsets: numpy.ndarray | None, families: dict[vibespatial.geometry.buffers.GeometryFamily, FamilyGeometryBuffer], residency: vibespatial.runtime.residency.Residency = Residency.HOST, diagnostics: list[DiagnosticEvent] | None = None, runtime_history: list[vibespatial.runtime.RuntimeSelection] | None = None, geoarrow_backed: bool = False, shares_geoarrow_memory: bool = False, device_adopted: bool = False, device_state: OwnedGeometryDeviceState | None = None, _row_count: int | None = None)¶
Columnar geometry storage with optional device-resident metadata.
The three routing metadata arrays –
validity,tags, andfamily_row_offsets– are exposed as properties. When the array is device-resident, the host numpy copies may beNoneinternally; accessing any property lazily transfers from GPU to CPU, preserving full backward compatibility for host consumers while allowing GPU-only pipelines to avoid the D->H transfer entirely.- families¶
- residency¶
- diagnostics: list[DiagnosticEvent] = None¶
- runtime_history: list[vibespatial.runtime.RuntimeSelection] = None¶
- geoarrow_backed = False¶
- device_adopted = False¶
- device_state = None¶
- property validity: numpy.ndarray¶
- property tags: numpy.ndarray¶
- property family_row_offsets: numpy.ndarray¶
- property row_count: int¶
- property is_indexed_view: bool¶
True when this array is a virtual indexed view over a compact base.
- family_has_rows(family: vibespatial.geometry.buffers.GeometryFamily) bool¶
Check whether family has at least one geometry row to process.
Reads from whichever side is authoritative:
device_statewhen populated, hostFamilyGeometryBufferotherwise. This avoids the bug where host stubs withhost_materialized=Falsereport empty offsets even when device buffers have real data.
- move_to(target: vibespatial.runtime.residency.Residency | str, *, trigger: vibespatial.runtime.residency.TransferTrigger | str, reason: str | None = None) OwnedGeometryArray¶
- record_runtime_selection(selection: vibespatial.runtime.RuntimeSelection) None¶
- cache_bounds(bounds: numpy.ndarray) None¶
- cache_device_bounds(family: vibespatial.geometry.buffers.GeometryFamily, bounds: vibespatial.cuda._runtime.DeviceArray) None¶
- classmethod concat(arrays: list[OwnedGeometryArray]) OwnedGeometryArray¶
Concatenate multiple OwnedGeometryArrays at the buffer level.
When ALL inputs are device-resident (
residency == DEVICE) and have device state populated, concatenation is performed entirely on GPU using CuPy – no D->H transfer occurs. The result is a device-resident OGA with lazy host stubs.When ANY input is host-resident (or lacks device state), falls back to the existing host-side concatenation path.
- diagnostics_report() dict[str, Any]¶
- take(indices: numpy.ndarray) OwnedGeometryArray¶
Return a new OwnedGeometryArray containing only the rows at indices.
Operates entirely at the buffer level – no Shapely round-trip. When the array is DEVICE-resident or indices are already on device (CuPy /
__cuda_array_interface__), dispatches todevice_take()to keep all gathering on GPU. Otherwise returns a HOST-resident array.When the indices have high repetition (many output rows mapping to few unique source rows), returns a virtual indexed view that stores only the unique rows and an index map, avoiding the physical coordinate copy. This is transparent to consumers: kernel dispatch triggers
_resolve(), andto_shapely()expands via cheap Python object references.Memory pressure is handled by the ADR-0040 tiered allocator: Tier B (default) retries with gc.collect on OOM; Tier C (opt-in) uses CUDA managed memory for datasets exceeding VRAM.
- device_take(indices) OwnedGeometryArray¶
Device-side take — all gathering stays on GPU.
Accepts numpy or CuPy indices/mask. Returns a DEVICE-resident OwnedGeometryArray with host buffers marked
host_materialized=False. The host side is lazily populated by_ensure_host_state()on demand.When indices have high repetition, returns a virtual indexed view instead of performing a full device gather. See
take()for the design rationale.
- to_shapely() list[object | None]¶
- to_wkb(*, hex: bool = False) list[bytes | str | None]¶
- to_geoarrow(*, sharing: BufferSharingMode | str = BufferSharingMode.COPY) MixedGeoArrowView¶
- vibespatial.geometry.owned.normalize_buffer_sharing_mode(mode: BufferSharingMode | str) BufferSharingMode¶
- vibespatial.geometry.owned.from_shapely_geometries(geometries: list[object | None] | tuple[object | None, Ellipsis], *, residency: vibespatial.runtime.residency.Residency = Residency.HOST) OwnedGeometryArray¶
- vibespatial.geometry.owned.build_null_owned_array(row_count: int, *, residency: vibespatial.runtime.residency.Residency = Residency.HOST) OwnedGeometryArray¶
Build an all-null OwnedGeometryArray without materializing Shapely.
- vibespatial.geometry.owned.from_wkb(values: list[bytes | str | None] | tuple[bytes | str | None, Ellipsis], *, on_invalid: str = 'raise', residency: vibespatial.runtime.residency.Residency = Residency.HOST) OwnedGeometryArray¶
- vibespatial.geometry.owned.from_geoarrow(view: MixedGeoArrowView, *, residency: vibespatial.runtime.residency.Residency = Residency.HOST, sharing: BufferSharingMode | str = BufferSharingMode.COPY) OwnedGeometryArray¶
- vibespatial.geometry.owned.concat_owned_scatter(base: OwnedGeometryArray, replacement: OwnedGeometryArray, indices: numpy.ndarray) OwnedGeometryArray¶
Scatter replacement rows into base at indices, returning a new array.
Returns a new OwnedGeometryArray with the same row count as base where: - rows at indices come from replacement (in order) - all other rows come from base
len(indices)must equalreplacement.row_count.Operates entirely at the buffer level — no Shapely materialisation. When both inputs are device-resident, dispatches to
device_concat_owned_scatter()so the result stays on GPU.
- vibespatial.geometry.owned.concatenate_owned_arrays(arrays: list[OwnedGeometryArray]) OwnedGeometryArray¶
Concatenate owned geometry arrays without materializing geometry objects.
- vibespatial.geometry.owned.device_concat_owned_scatter(base: OwnedGeometryArray, replacement: OwnedGeometryArray, indices: numpy.ndarray | vibespatial.cuda._runtime.DeviceArray) OwnedGeometryArray¶
Scatter replacement rows into base without leaving the device.
- vibespatial.geometry.owned.build_device_resident_owned(*, device_families: dict[vibespatial.geometry.buffers.GeometryFamily, DeviceFamilyGeometryBuffer], row_count: int, tags: numpy.ndarray | vibespatial.cuda._runtime.DeviceArray, validity: numpy.ndarray | vibespatial.cuda._runtime.DeviceArray, family_row_offsets: numpy.ndarray | vibespatial.cuda._runtime.DeviceArray, execution_mode: str | None = None) OwnedGeometryArray¶
Construct an OwnedGeometryArray from device buffers without touching host.
This is the canonical factory for producing device-resident results from GPU kernels. Host-side FamilyGeometryBuffers are created with empty coordinate stubs (
host_materialized=False); actual data lives only in thedevice_state. Lazy_ensure_host_statewill copy on demand if the caller ever needs Shapely objects.Parameters¶
- device_families
Per-family device buffers produced by a GPU kernel.
- row_count
Total number of rows (geometries) in the output.
- tags
int8 array of family tags, length
row_count.- validity
bool array, length
row_count.- family_row_offsets
int32 array mapping global row index to family-local row index.
- execution_mode
Optional execution mode marker. When set to
"gpu", host numpy metadata arrays are rejected so GPU-path callers cannot silently re-upload metadata through this factory.
- vibespatial.geometry.owned.forward_result_metadata(owned: OwnedGeometryArray) tuple[numpy.ndarray | vibespatial.cuda._runtime.DeviceArray, numpy.ndarray | vibespatial.cuda._runtime.DeviceArray, numpy.ndarray | vibespatial.cuda._runtime.DeviceArray]¶
Forward metadata for a device result without forcing host copies.
When the source already has device metadata, reuse those arrays directly so downstream device-resident builders do not pay a D->H->D round-trip. Otherwise, preserve the historical host-copy behavior for host-only inputs.
- vibespatial.geometry.owned.tile_single_row(owned: OwnedGeometryArray, n: int) OwnedGeometryArray¶
Create an N-row owned array from a 1-row owned array.
The coordinate buffers (x, y) and offset arrays inside each
FamilyGeometryBufferare shared with the original – only the three routing metadata arrays (validity,tags,family_row_offsets) are replicated. This makes the operation O(N) in tiny int8/int32/bool metadata, not O(N * vertex_count) in fp64 coordinates, eliminating the host-side materialization bottleneck for scalar broadcast (nsf.3/nsf.4).Parameters¶
- owned
Must have
row_count == 1.- n
Desired number of output rows.
Returns¶
- OwnedGeometryArray
An n-row array where every row references the same geometry as the single input row. The family buffers have
row_count == 1and every row’sfamily_row_offsetsentry is0.
- vibespatial.geometry.owned.materialize_broadcast(tiled: OwnedGeometryArray) OwnedGeometryArray¶
Physically replicate coordinate buffers in a tiled owned array.
tile_single_row()creates an N-row metadata facade that shares the 1-row coordinate buffers. GPU kernels that index into family buffers by global row index requirefamily_buf.row_count == n. This function converts the metadata-only tile into a fully- materialized array where each family buffer hasnphysical rows with replicated coordinate data.The operation is O(N * vertices_per_geometry) in coordinate copies but avoids per-element Python loops and the Shapely round-trip that would otherwise be required. It is only called for the GPU path of broadcast-right constructive operations.
Parameters¶
- tiled
An
OwnedGeometryArrayproduced bytile_single_row()(N-row metadata, 1-row family buffers with allfamily_row_offsets == 0).
Returns¶
- OwnedGeometryArray
Same metadata but with physically replicated family buffers where
family_buf.row_count == tiled.row_count.