ovphysx Overview#
ovphysx is a self-contained PhysX runtime exposed as a C API with Python bindings. It consumes application-owned ovstage data, runs simulation, and returns same-device Warp arrays from the Python output-read API on CPU and CUDA. Native C transport and the deprecated tensor-binding surface retain DLTensor interoperability. It currently supports Windows (x86_64) and Linux (x86_64, aarch64) platforms. On x86_64, pre-built binaries require a CPU with AVX (Advanced Vector Extensions); refer to System Requirements.
This library is AI-agent friendly: SKILLS.md and the skills/ directory ship with both the Python wheel and the C SDK package. AGENTS.md is also available in the source repository for quick codebase onboarding.
This page explains how ovphysx fits into the stack, what workflows it supports, and where to find build, tutorial, and API details.
Who This Is For#
If you integrate ovphysx in Python apps or pipelines using the wheel.
If you integrate the SDK in C or C++ native applications.
What You Can Do#
Consume caller-owned ovstage data and drain committed ordinal ranges into the simulation.
Replicate subtrees for large-scale parallel environments with
clone()/ovphysx_clone()(PhysX-side replication in the internal representation only; USD untouched).Write simulation inputs (positions, velocities, controls) through the session write API (
PhysX.write/ovphysx_write) or, when paired withovstage, through attribute writes drained withupdate_from_ovstage().Step the simulation.
Read results (updated simulation state) back into your tensors. ovphysx does not write results back to the attached stage; the application owns writing state back to
ovstage.
To get started, refer to the Quickstart.
Relationship to PhysX SDK and ovstage#
ovphysx packages USD-aware scene ingestion, a streaming execution model, and tensorized data access on top of the PhysX SDK.
Applications own scene population through ovstage. ovphysx consumes that stage through attach_ovstage() / ovphysx_attach_ovstage() and drains committed ordinal ranges with update_from_ovstage() / ovphysx_update_from_ovstage().
Core Concepts#
Stream-ordered execution: calls run in submission order and see prior writes without extra sync.
Session read/write:
PhysX.read/PhysX.write(Covphysx_read/ovphysx_write) move physics data (rigid-body poses, velocities, joint state, and the other columns listed in Readable data), selected by object type. The older path-pattern tensor-binding API is deprecated (refer to Tensor Bindings).Thread safety: instances share the underlying physics runtime; serialize simulation, stage mutation, and binding creation across instances. A single instance is not safe for concurrent calls.
Warp output interoperability:
PhysX.read()returnswarp.array; use Warp’s DLPack support to share memory with NumPy, PyTorch, and other consumers.
End-to-End Usage in Python#
Typical usage of ovphysx:
Create and destroy instances with
PhysX()andphysx.destroy().After population, seal the ordinal with
stage.advance_write_floor(ordinal).wait(), then attach withphysx.attach_ovstage(stage, read_ordinal=ordinal). Apply later committed edits withphysx.update_from_ovstage(from_ordinal, to_ordinal).Write and read simulation state with the session API —
physx.write()/physx.read()— selecting an object type and attribute; each group exposes the mapped buffers as NumPy views (host) orwarp.array(device). (The deprecatedphysx.create_tensor_binding()path still works; refer to Migrating to the Session Read/Write API.)Step the simulation with
physx.step()— it is asynchronous (returns anop_index); usephysx.step_sync()to step and wait in one call, orwait_op()/wait_all()when consuming results outside the ovphysx stream. In-stream tensor reads wait automatically.
Refer to the Python API Reference for the full Python API surface.
C/C++ SDK#
The C API mirrors the Python flow:
Initialize/shutdown the process lifecycle with
ovphysx_initialize()andovphysx_shutdown().Create and destroy instances with
ovphysx_create_instance()andovphysx_destroy_instance().Attach ovstage with
ovphysx_attach_ovstage()and apply committed edits withovphysx_update_from_ovstage(handle, range), whererangeis anovstage_ordinal_range_t.Write and read simulation state with the session API —
ovphysx_write()/ovphysx_read()— selecting an object type and attribute throughovphysx_query(), then filling or reading the mapped groups. (The deprecatedovphysx_create_tensor_binding()path still works.)Step the simulation with
ovphysx_step()— it is asynchronous (returns anop_index); useovphysx_step_sync()to step and wait in one call, orovphysx_wait_op()when consuming results outside the stream.
Refer to the C API Reference for the full C API surface.
Release and Distribution#
Python: install the wheel as the primary distribution (
pip install ovphysx).C/C++: consume the SDK package with headers and shared libraries (refer to the GitHub release page).
Wheel Contents and Environment Notes#
The Python wheel (pip install ovphysx) contains the physics runtime and declares
an exact dependency on the matched ovstage wheel. Together those two wheels
provide the complete runtime; no additional NVIDIA or USD package is required.
What the Wheel Bundles#
ovphysx shared libraries (
libovphysx.so/ovphysx.dll)Carbonite runtime (embedded static framework plus bootstrap plugins)
PhysX runtime (statically linked simulation and tensor implementation)
Codeless PhysX USD schemas (
ovphysx/schemas/physx/, data only; the application registers them)
The exact matched ovstage wheel supplies ovstage together with the USD
resolver and the internal namespaced OpenUSD runtime ovstage uses to ingest USD
scenes. The ovphysx wheel ships no OpenUSD library, USD plugin registry, or
resolver of its own. Python dependencies are
packaging, that exact ovstage wheel, and the bounded warp-lang feature line.
USD Coexistence and Schema Registration#
ovphysx ships no OpenUSD runtime and never loads, links, preloads, or version-checks one. ovstage ingests USD scenes through its own internal namespaced OpenUSD runtime; the application owns whatever USD it authors with, for example stock usd-core from PyPI. ovphysx does not inspect or validate the USD libraries present in the process.
ovphysx ships its PhysX USD schemas (PhysxSchema, OmniUsdPhysicsDeformableSchema)
as codeless USD plugins and never touches the environment. It reports where they
are: ovphysx_get_codeless_schema_root() in C, ovphysx.codeless_schema_root()
and ovphysx.codeless_schema_paths() in Python. The application registers them
with the USD runtime it owns before the first ovstage population call in the
process (ovstage_population_register_usd_schemas() /
ovstage.population.register_usd_schemas()); USD assembles its schema registry
once, and a late registration cannot be repaired. Attaching an ovstage that was
populated without the registration fails with an error naming the missing call,
because such a stage carries none of the asset’s PhysX settings. Refer to
Physics Schemas for the ovstage and stock usd-core
recipes.
Versioning and Compatibility#
ovphysx follows semantic versioning for the SDK surface (C API and Python bindings).
Backward compatibility guarantees that come with semantic versioning apply only to releases at or after v1.0; pre-1.0 releases may include breaking changes between minor and patch versions.
Functions exposed in experimental or internal folders (or prefixes) have no guarantees and may change or be removed without notice.
Version Management#
The project version is defined in VERSION (for example, 0.1.0 or 0.1.4-specialFeature).
CMakeLists.txtreadsVERSIONand generatesinclude/ovphysx/version.hPython wheels convert to PEP 440 (
X.Y.Z-suffix→X.Y.Z.suffix)C++ archives keep the original semver format
API/ABI Policy#
Major: breaking C API or ABI changes, removed symbols, or incompatible data layout changes.
Minor: backwards-compatible API additions, new symbols, or optional features.
Patch: backwards-compatible bug fixes and internal changes only.
For v1.0 and later releases, backward compatibility is expected across patch and minor releases for the published C API and Python API. ABI compatibility is maintained within a major line; SONAME uses the major version on Linux to make ABI expectations explicit.
When a breaking change is required at the C API level, consider adding a versioned entrypoint (for example, ovphysx_create_instance_v2) to preserve compatibility, similar to CUDA-style *_v2 APIs. Deprecated APIs should remain for at least one minor release with clear deprecation notes.
Python bindings validate that the package version and native library version match at runtime (base semver), and will raise a clear error if they diverge. This check can be bypassed for advanced cases with ignore_version_mismatch=True on PhysX.
System Requirements#
In addition to the platform list above:
Python 3.10+ for the wheel; a C++17 toolchain for the SDK. For the tested compiler and CUDA Toolkit matrix, refer to the PhysX SDK Linux platform readme; building the SDK/wheel on a newer-than-baseline glibc (> 2.35) requires
SKIP_GLIBC_CHECK=ON.x86_64 (Linux and Windows): AVX required. Shipped
libovphysx/ovphysx.dllbuilds use AVX instructions unconditionally. There is no runtime CPU-feature dispatch and no non-AVX code path. Hosts without AVX (some older x86-64 CPUs, certain virtual machines or emulators with AVX disabled) are unsupported.ovphysx_initialize()(and PythonPhysX()construction) returns an error with an explicit AVX requirement message before simulation starts.Linux aarch64: AVX does not apply (ARM has its own SIMD); use the aarch64 wheel.
GPU (optional): NVIDIA GPU + CUDA-capable driver recommended for GPU dynamics; CPU-only simulation is supported on supported CPUs.
On Linux x86_64, this command reports whether the host CPU advertises AVX. Run it before you install the wheel or SDK:
grep -qw avx /proc/cpuinfo && echo "AVX present" || echo "AVX missing"
On Windows, confirm AVX in your processor specifications before installing the x86_64 wheel or SDK.
Runtime Warnings#
The native SDK bundles PhysX and Carbonite; the separately downloaded ovstage
package supplies ovstage, OmniClient, its connection library, and its internal
USD runtime. The Python distribution provides
the same runtime through the coordinated ovphysx and exact ovstage wheels. On startup and during
simulation, you may see warnings from these downstream dependencies such as:
[Warning] PhysXFoundation: Unable to create GPU Foundation— appears on machines without an NVIDIA GPU; the SDK falls back to CPU simulation transparently.
These messages do not indicate a problem with your application. They originate from the bundled runtime dependencies.
To suppress most startup noise, set the log level before creating an instance:
C:
ovphysx_set_log_level(OVPHYSX_LOG_ERROR);Python:
ovphysx.set_log_level(ovphysx.LogLevel.ERROR)
PhysX SDK Documentation#
ovphysx uses the PhysX SDK and a statically linked Omni PhysX runtime under the hood. For broader PhysX and Omni PhysX guidance, refer to the respective developer resources:
Conclusion#
You now have a high-level view of ovphysx capabilities, compatibility policy, and distribution options. For build and runtime details, refer to the Developer Guide. For hands-on usage, continue with Hello World.