vibespatial.geometry.owned¶
Attributes¶
Classes¶
Enum where members are also (and must be) strings |
|
Enum where members are also (and must be) strings |
|
Device-resident copies of the three routing metadata arrays. |
|
Columnar geometry storage with optional device-resident metadata. |
Functions¶
|
Extract unique (left_tag, right_tag) pairs without Python-level iteration. |
|
|
|
|
|
|
|
|
|
Scatter replacement rows into base at indices, returning a new array. |
|
Construct an OwnedGeometryArray from device buffers without touching host. |
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.
- 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¶
- class vibespatial.geometry.owned.DeviceMetadataState¶
Device-resident copies of the three routing metadata arrays.
When
residency=DEVICE, these arrays live on GPU and the corresponding host numpy arrays inOwnedGeometryArraymay beNone. Accessing the host properties triggers a lazy D->H transfer.- validity: vibespatial.cuda._runtime.DeviceArray¶
- tags: vibespatial.cuda._runtime.DeviceArray¶
- family_row_offsets: vibespatial.cuda._runtime.DeviceArray¶
- 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, device_metadata: DeviceMetadataState | 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¶
- 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.
Stays host-resident and avoids any Shapely materialization. All input arrays are ensured to have host state before concatenation. Device state is not carried over; the caller can move the result to device if needed.
- 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.
- 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.
- 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.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 host-resident the result is host-resident; when both are device-resident, use
device_concat_owned_scatter()instead (future work).
- vibespatial.geometry.owned.build_device_resident_owned(*, device_families: dict[vibespatial.geometry.buffers.GeometryFamily, DeviceFamilyGeometryBuffer], row_count: int, tags: numpy.ndarray, validity: numpy.ndarray, family_row_offsets: numpy.ndarray) 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.