Set Up a Python Project#
The ovstage Python package binds the ovstage C data plane through ctypes. Its
shared loader must be discoverable when the first native operation runs. Programs use Stage and
PathDictionary (both context managers) plus numpy for tensor attribute
I/O.
Note
ovstage is pre-release. The examples consume ovstage as a published wheel
using uv; if the pinned wheel cannot be
resolved, the public wheel is not published yet.
Requirements#
Python 3.10–3.13 (
requires-python = ">=3.10,<3.14"). Recreate the environment with a supported interpreter rather than editing the constraint.NumPy, for tensor I/O (
write_attribute(tensors=...),group.array(...)):pip install numpy
Making ovstage Importable#
Depend on the published ovstage wheel — for example a uv project that pins
it in pyproject.toml (the pattern the examples/python projects use), then
run with uv run. Alternatively, put the ovstage package on PYTHONPATH
directly.
Configuring Transform Updates#
Pass a StageConfig when creating the stage to select the
hierarchy computation model used for automatic transform updates:
import ovstage
config = ovstage.StageConfig(
runtime_default_hierarchy_computation_model=(
ovstage.HierarchyComputationModel.CPU_INCREMENTAL
)
)
with ovstage.Stage("simulation", config=config) as stage:
# A manual computation can select the same configured model.
stage.compute_hierarchy(
input_ordinal=1,
output_ordinal=1,
model=ovstage.HierarchyComputationModel.RUNTIME_DEFAULT,
)
The setting is process-scoped. Configured stages may coexist when their
concrete settings match; creating a stage with a conflicting setting while
another stage remains live raises OvstageError.
RUNTIME_DEFAULT is meaningful as a manual selector. As a configured value,
it does not override the active process default; a fresh process defaults to
CPU incremental.
stage.config returns a detached copy of the process configuration captured
by that stage. It contains the explicit entries from the initialization that
established the active process state; it does not materialize omitted defaults.
Configuring Ordinal Admission#
Use OrdinalAdmissionPolicy to choose how mutations are
checked against retained value and prim-lifecycle changes:
import ovstage
config = ovstage.StageConfig(
runtime_default_ordinal_admission_policy=ovstage.OrdinalAdmissionPolicy.NONDECREASING
)
with ovstage.Stage("simulation", config=config) as stage:
assert (
stage.config.runtime_default_ordinal_admission_policy
== ovstage.OrdinalAdmissionPolicy.NONDECREASING
)
The default is NONDECREASING, which permits repeated writes
at the same unsealed ordinal, while FLOOR_ONLY skips retained-history
conflicts. See Ordinal Admission Policies for the comparison rules.
This setting shares the process lifetime of the hierarchy configuration.
Omission, None and DEFAULT inherit the active policy; they select the
nondecreasing policy only when starting a fresh lifetime. Matching concrete
configurations may coexist. A conflicting policy raises
OvstageError without acquiring an initialization reference
or changing either setting. Close all stages and release any other initialization
references and retained instance owners before selecting another policy.
stage.config reports the original explicit entries, so an omitted policy
remains None and an explicit DEFAULT remains DEFAULT.
Minimal Program#
# Write one value per prim, then advance the watermark before reading.
# wait() reports asynchronous failures; the context manager and finally
# block release the read and its result even if consuming the data fails.
stage.write_attribute(
query, attr, ordinal=1, tensors=np.array([1.0, 2.0, 3.0], np.float32), is_array=False
).wait()
stage.advance_write_floor(ordinal=1).wait()
with stage.read_attributes(query, [attr], OrdinalRange.latest(1)) as read:
read.wait()
group = read.fetch_next()
if group is None:
raise SystemExit("read returned no group at ordinal 1")
try:
# group.array(i) is a zero-copy numpy view of tensor i (CPU).
print("read back ordinal", group.ordinal, group.array(0)) # -> [1. 2. 3.]
finally:
stage.release_group(group)
Where to Go Next#
Getting Started in Python — run the minimal example.
Python API Reference — the full Python API reference.
Application Flow — the end-to-end lifecycle.