An OpenVX 1.3.2 implementation written in Rust. rustVX provides the complete OpenVX Vision Feature Set through a standard C API (libopenvx_ffi), enabling existing OpenVX applications to use a memory-safe, portable backend with no source changes.
Note
rustVX targets the OpenVX 1.3.2 specification. The KHR Streaming extension pipeup APIs were recently added (see PR #54) and are now exercised in CI; the streaming CTS test suite passes and is included in the conformance totals below.
| Item | Status |
|---|---|
| Current version | 1.3.2 (workspace version in Cargo.toml) |
| OpenVX target | 1.3.2 |
| C API stability | Stable — follows the Khronos OpenVX 1.3.2 specification |
| Native Rust API stability | Evolving — the openvx-core / openvx-vision crate APIs are not yet finalized |
| MSRV | Not declared; latest stable Rust toolchain recommended |
| Distribution | Build from source (no crates.io / OS packages yet) |
rustVX passes the full Khronos OpenVX 1.3.2 Conformance Test Suite for all required profiles:
| Profile | Required tests | Passing | Status |
|---|---|---|---|
| OpenVX baseline | 5555 | 5555 / 5555 | ✅ |
| Vision conformance profile | 6192 | 6192 / 6192 | ✅ |
| Enhanced Vision conformance profile | 1503 | 1503 / 1503 | ✅ |
| User Data Object extension | 14 | 14 / 14 | ✅ |
| Pipelining extension | 109 | 109 / 109 | ✅ |
| Streaming extension | 24 | 24 / 24 | ✅ |
| Total | 7058 | 7058 / 7058 | ✅ 100% |
All implemented kernels and KHR extensions are exercised in CI with -DOPENVX_CONFORMANCE_VISION=ON -DOPENVX_USE_ENHANCED_VISION=ON -DOPENVX_USE_USER_DATA_OBJECT=ON -DOPENVX_USE_PIPELINING=ON -DOPENVX_USE_STREAMING=ON.
The following OpenVX 1.3.2 extensions are not implemented in rustVX today:
- Neural Network (NN) extension
- Import/Export extension
- Debug extension
If you need one of these, please open an issue to discuss scope and priority.
Latest CTS run results are published on each push and pull request via the Actions tab.
rustVX/
├── openvx-core/ # Core framework: context, graph, node, types, C API
├── openvx-image/ # Image data object and channel operations
├── openvx-buffer/ # Generic buffer for intermediate data
├── openvx-vision/ # All vision kernels (filters, geometric, features, etc.)
├── openvx-ffi/ # C shared library (cdylib) exporting the full OpenVX API
├── include/VX/ # Standard OpenVX C headers
└── OpenVX-cts/ # Khronos Conformance Test Suite (git submodule)
The workspace compiles into a single shared library (libopenvx_ffi.so / .dylib / .dll) that any OpenVX application can link against.
For a high-level overview of how the crates fit together, see docs/ARCHITECTURE.md.
| Tool | Version |
|---|---|
| Rust | stable (MSRV not declared; latest stable recommended) |
| C compiler | gcc, clang, or MSVC |
| CMake | 3.10+ |
| Make or Ninja | for building the CTS |
| Platform | Tier | Notes |
|---|---|---|
| Linux x86_64 | Primary | CI-tested on Ubuntu 22.04 with AVX2 |
| macOS x86_64 / Apple Silicon | Supported | Build instructions provided; Apple Silicon uses the NEON path |
| Windows MSVC x64 | Supported | Build instructions provided |
| Linux AArch64 | Best-effort | NEON path exists; not continuously tested in CI |
openvx-core and openvx-vision compile on any platform Rust supports. SIMD kernels are selected at runtime from CPU feature flags, not vendor strings.
# Clone with submodules
git clone --recurse-submodules https://github.com/kiritigowda/rustVX.git
cd rustVX
# Build the library
cargo build --releaseThe shared library is produced at:
| Platform | Path |
|---|---|
| Linux | target/release/libopenvx_ffi.so |
| macOS | target/release/libopenvx_ffi.dylib |
| Windows | target/release/openvx_ffi.dll |
The standard OpenVX 1.3 C headers are bundled in include/VX/ and can be passed to your C/C++ build directly.
rustVX is currently distributed as a build-from-source project. After building once, you can use the shared library and headers directly from the build tree, or copy them to a system or project prefix.
# Linux / macOS
export LD_LIBRARY_PATH=/path/to/rustVX/target/release:$LD_LIBRARY_PATH # Linux
export DYLD_LIBRARY_PATH=/path/to/rustVX/target/release:$DYLD_LIBRARY_PATH # macOS
# Compile your C/C++ application
gcc app.c -I /path/to/rustVX/include -L /path/to/rustVX/target/release -lopenvx_ffi -o app
./appOn Windows, add target\release to your PATH and link against openvx_ffi.dll.lib.
To keep rustVX isolated from system directories, copy the library and headers into a local prefix such as /opt/rustVX or $HOME/.local/rustVX:
PREFIX=/opt/rustVX
mkdir -p "$PREFIX/lib" "$PREFIX/include"
cp target/release/libopenvx_ffi.so* "$PREFIX/lib/" # Linux
# cp target/release/libopenvx_ffi.dylib* "$PREFIX/lib/" # macOS
# cp target/release/openvx_ffi.dll "$PREFIX/lib/" # Windows
cp -r include/VX "$PREFIX/include/"
# Optional: create drop-in Khronos library names
ln -sf libopenvx_ffi.so "$PREFIX/lib/libopenvx.so"
ln -sf libopenvx_ffi.so "$PREFIX/lib/libvxu.so"Then build against the prefix:
gcc app.c -I "$PREFIX/include" -L "$PREFIX/lib" -lopenvx_ffi -Wl,-rpath,"$PREFIX/lib" -o appIf you prefer a system-wide installation, install to /usr/local:
sudo cp target/release/libopenvx_ffi.so* /usr/local/lib/
sudo cp -r include/VX /usr/local/include/
sudo ldconfig # Linux onlyNote
rustVX is not yet published on crates.io for cargo install, and no OS packages (.deb, .rpm, Homebrew, etc.) are provided. The shared library produced by cargo build --release -p openvx-ffi is the canonical artifact.
For Rust projects that want the native Rust kernel API, add the workspace crates as path dependencies:
[dependencies]
openvx-core = { path = "/path/to/rustVX/openvx-core" }
openvx-vision = { path = "/path/to/rustVX/openvx-vision" }To enable SIMD kernels on both crates, add matching features (for example, avx2 on x86_64 or neon on AArch64):
[dependencies]
openvx-core = { path = "/path/to/rustVX/openvx-core", features = ["avx2"] }
openvx-vision = { path = "/path/to/rustVX/openvx-vision", features = ["avx2"] }Both openvx-core (host of the C-API kernel callbacks the OpenVX graph executor invokes) and openvx-vision (host of the public Rust API kernels) expose a matching opt-in feature set:
| Feature | Effect |
|---|---|
simd |
Enables the portable SIMD abstraction layer; required by the architecture-specific features below |
sse2 / avx2 |
x86_64 SIMD back-ends (imply simd) |
neon |
AArch64 SIMD back-end (implies simd) |
parallel (openvx-vision only) |
Enables Rayon-based multi-threaded kernels |
Build with the matching pair on each crate so the FFI graph path and the direct Rust API path both pick up the SIMD kernels:
cargo build --release -p openvx-ffi \
--features "openvx-core/sse2 openvx-core/avx2 openvx-vision/sse2 openvx-vision/avx2"Performance work targets AMD Zen (Ryzen / EPYC, Zen 2+) — that's what CI measures and what the Benchmark & compare numbers come from. Intel and ARM aren't penalised; the runtime dispatcher reads CPU flags, not vendor strings, so any host whose flags match the same gate runs the same path:
- AMD Zen 2+ (Ryzen 3000+, Threadripper 3000+, EPYC Rome / Milan / Genoa) → AVX2 kernels +
-C target-cpu=x86-64-v3auto-vec. - Intel Haswell and later → same AVX2 path, parity with Zen.
- Older x86_64 (pre-AVX2) → SSE2 kernels +
-C target-cpu=x86-64-v2. - AArch64 (Apple Silicon, AWS Graviton, etc.) → NEON path.
- Anything else / no features → scalar slice loop (still ~50× faster than the original per-pixel reference loops used during early development).
Dispatch lives in openvx-core::simd_kernels (FFI graph path) and openvx-vision::x86_64_simd (Rust API). CI auto-detects host flags; for a manual Zen-targeted build:
RUSTFLAGS="-C target-cpu=x86-64-v3" \
cargo build --release -p openvx-ffi \
--features "openvx-core/sse2 openvx-core/avx2 \
openvx-vision/sse2 openvx-vision/avx2"libopenvx_ffi exports the full vx* / vxu* symbol set defined by the standard OpenVX headers, so existing OpenVX code links against it with no source changes. A minimal graph-mode example:
#include <VX/vx.h>
int main(void) {
vx_context ctx = vxCreateContext();
vx_graph g = vxCreateGraph(ctx);
/* ... build graph, call vxVerifyGraph / vxProcessGraph ... */
vxReleaseGraph(&g);
vxReleaseContext(&ctx);
return 0;
}You can also use the immediate-mode vxu* helpers without building a graph. For example, to scale an image:
#include <VX/vx.h>
#include <VX/vxu.h>
vx_status scale_image(vx_context ctx,
vx_image src, vx_image dst,
vx_scalar scale_x, vx_scalar scale_y)
{
return vxuScaleImage(ctx, src, dst, VX_INTERPOLATION_BILINEAR);
}# Linux
gcc app.c -I rustVX/include -L rustVX/target/release -lopenvx_ffi -o app
LD_LIBRARY_PATH=rustVX/target/release ./appFor drop-in compatibility with build systems that look for libopenvx / libvxu (e.g. find_library(NAMES openvx vxu)), symlink the rustVX library to those names:
ln -s libopenvx_ffi.so target/release/libopenvx.so
ln -s libopenvx_ffi.so target/release/libvxu.soThe workspace crates also expose a native Rust API. Add openvx-vision (and openvx-core if you need the context directly) to your Cargo.toml:
[dependencies]
openvx-core = { path = "path/to/rustVX/openvx-core" }
openvx-vision = { path = "path/to/rustVX/openvx-vision" }To enable SIMD kernels on both the Rust API path and the FFI graph path, enable the matching feature on both crates:
[dependencies]
openvx-core = { path = "path/to/rustVX/openvx-core", features = ["avx2"] }
openvx-vision = { path = "path/to/rustVX/openvx-vision", features = ["avx2"] }Use sse2 or neon instead of avx2 depending on your target platform. If no SIMD feature is enabled, the scalar fallback is used.
Then register kernels and execute them against a context:
use openvx_core::{Context, VxResult};
use openvx_vision::register_all_kernels;
fn main() -> VxResult<()> {
let context = Context::new()?;
register_all_kernels(&context)?;
// ... create data objects and call kernel.execute() or use the C FFI graph API ...
Ok(())
}For graph-mode vision workloads from Rust, the recommended path is to use the C FFI (openvx-ffi) through the standard vx* / vxu* API, which gives full OpenVX graph optimization, pipelining, and streaming support.
Before running the full Khronos CTS, confirm the workspace builds and passes its own tests:
# Build the shared library
cargo build --release -p openvx-ffi
# Run Rust unit and integration tests
cargo test --workspace --release
# Run the Criterion micro-benchmarks
cargo bench -p openvx-visionIf all three commands succeed, the library is ready for the conformance suite.
The Khronos CTS is included as a git submodule. Initialize it with:
git submodule update --init --recursiveThe upstream CTS uses an older cmake_minimum_required. Add this flag when configuring:
cmake .. -DCMAKE_POLICY_VERSION_MINIMUM=3.5 ...It is harmless on older CMake versions.
The dynamic linker cannot find the rustVX library. Set the library path before running:
# Linux
export LD_LIBRARY_PATH=/path/to/rustVX/target/release:$LD_LIBRARY_PATH
# macOS
export DYLD_LIBRARY_PATH=/path/to/rustVX/target/release:$DYLD_LIBRARY_PATH
# Windows (PowerShell)
$env:PATH = "$PWD\..\..\target\release;$env:PATH"Build the CTS with -fno-strict-aliasing. The upstream CTS intentionally performs type punning between vx_uint8* and vx_char*; GCC -O3 miscompiles those comparisons without the flag. This is a CTS build issue, not a rustVX runtime bug, and does not affect rustVX performance.
Make sure you are using a recent stable Rust toolchain. rustVX uses Rust edition 2021 and does not pin an explicit MSRV.
The Khronos OpenVX Conformance Test Suite is included as a git submodule. Build and run it against the rustVX library:
Note
The -DCMAKE_POLICY_VERSION_MINIMUM=3.5 flag below is needed when configuring with CMake 4.0+, which dropped compatibility with the older cmake_minimum_required versions used by the upstream CTS. It is harmless on older CMake.
# Build the CTS
cd OpenVX-cts
mkdir -p build && cd build
cmake .. \
-DCMAKE_C_FLAGS="-fno-strict-aliasing" \
-DCMAKE_CXX_FLAGS="-fno-strict-aliasing" \
-DCMAKE_BUILD_TYPE=Release \
-DCMAKE_POLICY_VERSION_MINIMUM=3.5 \
-DCMAKE_C_STANDARD_LIBRARIES="-lm" \
-DCMAKE_CXX_STANDARD_LIBRARIES="-lm" \
-DOPENVX_INCLUDES="$(pwd)/../../include;$(pwd)/../include" \
-DOPENVX_LIBRARIES="$(pwd)/../../target/release/libopenvx_ffi.so;m" \
-DOPENVX_CONFORMANCE_VISION=ON \
-DOPENVX_USE_ENHANCED_VISION=ON \
-DOPENVX_USE_USER_DATA_OBJECT=ON \
-DOPENVX_USE_PIPELINING=ON \
-DOPENVX_USE_STREAMING=ON
make -j$(nproc)
# Run all tests
export LD_LIBRARY_PATH=$(pwd)/../../target/release
export VX_TEST_DATA_PATH=$(pwd)/../test_data/
./bin/vx_test_conformance# Build the CTS
cd OpenVX-cts
mkdir -p build && cd build
cmake .. \
-DCMAKE_C_FLAGS="-fno-strict-aliasing" \
-DCMAKE_CXX_FLAGS="-fno-strict-aliasing" \
-DCMAKE_BUILD_TYPE=Release \
-DCMAKE_POLICY_VERSION_MINIMUM=3.5 \
-DOPENVX_INCLUDES="$(pwd)/../../include;$(pwd)/../include" \
-DOPENVX_LIBRARIES="$(pwd)/../../target/release/libopenvx_ffi.dylib" \
-DOPENVX_CONFORMANCE_VISION=ON \
-DOPENVX_USE_ENHANCED_VISION=ON \
-DOPENVX_USE_USER_DATA_OBJECT=ON \
-DOPENVX_USE_PIPELINING=ON \
-DOPENVX_USE_STREAMING=ON
make -j$(sysctl -n hw.ncpu)
# Run all tests
export DYLD_LIBRARY_PATH=$(pwd)/../../target/release
export VX_TEST_DATA_PATH=$(pwd)/../test_data/
./bin/vx_test_conformance# Build the CTS
cd OpenVX-cts
mkdir build; cd build
cmake .. `
-DCMAKE_C_FLAGS="-fno-strict-aliasing" `
-DCMAKE_CXX_FLAGS="-fno-strict-aliasing" `
-DCMAKE_BUILD_TYPE=Release `
-DCMAKE_POLICY_VERSION_MINIMUM=3.5 `
-DOPENVX_INCLUDES="$PWD\..\..\include;$PWD\..\include" `
-DOPENVX_LIBRARIES="$PWD\..\..\target\release\openvx_ffi.dll.lib" `
-DOPENVX_CONFORMANCE_VISION=ON `
-DOPENVX_USE_ENHANCED_VISION=ON `
-DOPENVX_USE_USER_DATA_OBJECT=ON `
-DOPENVX_USE_PIPELINING=ON `
-DOPENVX_USE_STREAMING=ON
cmake --build . --config Release
# Run all tests
$env:PATH = "$PWD\..\..\target\release;$env:PATH"
$env:VX_TEST_DATA_PATH = "$PWD\..\test_data\"
.\bin\Release\vx_test_conformance.exeUse the --filter flag to run a subset of tests:
# Run only filter tests
./bin/vx_test_conformance --filter="Gaussian3x3.*:Median3x3.*:Box3x3.*"
# Run only feature detection tests
./bin/vx_test_conformance --filter="HarrisCorners.*:FastCorners.*:vxCanny.*"
# Run only control flow tests
./bin/vx_test_conformance --filter="ControlFlow.SelectNode*:ControlFlow.ScalarOperationNode*"
# Run only tensor tests
./bin/vx_test_conformance --filter="Tensor.*:TensorOp.*"Note
The -fno-strict-aliasing flag above is needed because the CTS test suite contains intentional (but technically undefined-behavior) type punning between vx_uint8* and vx_char* inside own_verify_data_items(). GCC -O3 optimizes those comparisons incorrectly without the flag, causing 5 pre-existing Array.vxCreateArray failures. The flag is harmless on all compilers and does not affect rustVX runtime performance.
Beyond the Khronos CTS, rustVX has its own Rust-side test and benchmark suites:
# Run all unit and integration tests
cargo test --workspace --release
# Run the Criterion micro-benchmarks for vision kernels
cargo bench -p openvx-visionEnd-to-end performance is also tracked against the Khronos OpenVX sample implementation on every CI run via openvx-mark; see the Benchmark & compare job in the Actions tab for the latest comparison report.
Tip
The Benchmark & compare job renders the rustVX-vs-Khronos comparison table directly into the GitHub Actions job summary for each run — no need to dig into logs. The summary opens with a headline panel showing the geomean speedup of rustVX over the Khronos sample (per-kernel best/worst speedups and a win/loss count) followed by the full per-benchmark detail table. The raw JSON reports are also published as downloadable workflow artifacts (benchmark-results-rustvx, benchmark-results-khronos-sample, and benchmark-comparison) on every push and pull request.
GitHub Actions builds and runs the full CTS on every push and pull request. The workflow splits the suite into parallel jobs for faster feedback:
See the Actions tab for full run history.
Contributions, bug reports, and feature requests are welcome.
- Found a bug or have a question? Open an issue.
- Want to contribute a fix or new kernel? Fork the repo, create a topic branch, and open a pull request against
main. CI must pass — both the Khronos CTS jobs and the rustVX-vs-Khronos benchmark comparison run on every PR. - Please make sure
cargo fmt,cargo clippy --workspace --all-targets, andcargo test --workspacepass locally before submitting.
This project is licensed under the MIT License.
The OpenVX logo is a trademark of The Khronos Group Inc. The vector logo file in docs/openvx-logo.svg is sourced from Wikimedia Commons and is included for identification purposes only.