Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
213 changes: 213 additions & 0 deletions .github/workflows/conformance.yml
Original file line number Diff line number Diff line change
Expand Up @@ -53,10 +53,49 @@ jobs:
uses: actions/upload-artifact@v4
with:
name: build-artifacts
# `include/` is bundled so the downstream benchmark job can build
# openvx-mark against rustVX without needing to check out the
# rustVX source tree.
path: |
target/release/libopenvx_ffi.so
OpenVX-cts/build/bin/vx_test_conformance
OpenVX-cts/test_data/
include/
retention-days: 1

# Build the Khronos OpenVX sample implementation in its own phase, in
# parallel with the rustVX `build` job, and upload the resulting library
# + headers as a self-contained archive. The benchmark job below pulls
# both archives down onto a single runner so rustVX and the Khronos
# sample are exercised on identical hardware.
build-khronos-sample:
name: Build Khronos OpenVX sample
runs-on: ubuntu-22.04
steps:
- name: Install system dependencies
run: |
sudo apt-get update
sudo apt-get install -y build-essential cmake git python3
- name: Build Khronos OpenVX sample
run: |
git clone --recursive --depth 1 \
https://github.com/KhronosGroup/OpenVX-sample-impl.git khronos-sample
cd khronos-sample
python3 Build.py --os=Linux --arch=64 --conf=Release
- name: Stage Khronos sample archive
run: |
set -euo pipefail
LIB_SRC=$(dirname $(find khronos-sample -name "libopenvx.so" -not -path "*/build/*" | head -1))
echo "Khronos libraries discovered in: $LIB_SRC"
mkdir -p khronos-stage/lib
cp "$LIB_SRC"/libopenvx*.so "$LIB_SRC"/libvxu*.so khronos-stage/lib/
cp -r khronos-sample/api-docs/include khronos-stage/include
ls -R khronos-stage
- name: Upload Khronos sample artifacts
uses: actions/upload-artifact@v4
with:
name: khronos-sample-artifacts
path: khronos-stage/
retention-days: 1

baseline:
Expand Down Expand Up @@ -277,3 +316,177 @@ jobs:
export LD_LIBRARY_PATH=${{ github.workspace }}/target/release
export VX_TEST_DATA_PATH=${{ github.workspace }}/OpenVX-cts/test_data/
timeout 300 ./bin/vx_test_conformance --filter="GaussianPyramid.*:LaplacianPyramid.*:LaplacianReconstruct.*:OptFlowPyrLK.*"

# Performance benchmark using openvx-mark, comparing rustVX against the
# Khronos OpenVX sample implementation on the SAME runner so the two
# numbers come from identical hardware. This job does NOT rebuild either
# implementation — it just downloads the archives produced by the
# `build` and `build-khronos-sample` phases above, builds the openvx-mark
# tool against each, runs the same workload, and compares the JSON
# reports. The CTS jobs above use `continue-on-error: true`, so this
# job effectively gates on `build`, `build-khronos-sample`, and
# `baseline` succeeding (matching the existing CTS gate).
benchmark:
name: Benchmark & compare (rustVX vs Khronos sample)
runs-on: ubuntu-22.04
needs:
- build
- build-khronos-sample
- baseline
- graph
- data-objects
- image-ops
- vision-color
- vision-filters
- vision-arithmetic
- vision-geometric
- vision-features
- vision-statistics
- vision-pyramid
continue-on-error: true
steps:
- name: Install system dependencies
run: |
sudo apt-get update
sudo apt-get install -y build-essential cmake git python3

- name: Download rustVX archive
uses: actions/download-artifact@v4
with:
name: build-artifacts
path: ${{ github.workspace }}/rustvx-pkg

- name: Download Khronos sample archive
uses: actions/download-artifact@v4
with:
name: khronos-sample-artifacts
path: ${{ github.workspace }}/khronos-pkg

- name: Expose rustVX as libopenvx / libvxu
id: rustvx
# openvx-mark uses `find_library(NAMES openvx)` and
# `find_library(NAMES vxu)`. rustVX ships a single
# `libopenvx_ffi.so` that exports the full set of `vx*`/`vxu*`
# symbols, so symlink the two classic Khronos library names to
# it without changing rustVX's own build output.
run: |
set -euo pipefail
LIB_DIR=${{ github.workspace }}/rustvx-pkg/target/release
chmod -R u+rwX "$LIB_DIR"
cd "$LIB_DIR"
ln -sf libopenvx_ffi.so libopenvx.so
ln -sf libopenvx_ffi.so libvxu.so
ls -la libopenvx*.so libvxu*.so
echo "lib_dir=$LIB_DIR" >> "$GITHUB_OUTPUT"
echo "include_dir=${{ github.workspace }}/rustvx-pkg/include" >> "$GITHUB_OUTPUT"

- name: Inspect Khronos sample archive
id: khronos
run: |
set -euo pipefail
LIB_DIR=${{ github.workspace }}/khronos-pkg/lib
INCLUDE_DIR=${{ github.workspace }}/khronos-pkg/include
ls -la "$LIB_DIR"
echo "lib_dir=$LIB_DIR" >> "$GITHUB_OUTPUT"
echo "include_dir=$INCLUDE_DIR" >> "$GITHUB_OUTPUT"

- name: Clone openvx-mark
run: |
git clone --depth 1 https://github.com/kiritigowda/openvx-mark.git \
${{ github.workspace }}/openvx-mark

# ---------------------------------------------------------------------
# rustVX benchmark
# ---------------------------------------------------------------------
- name: Build openvx-mark against rustVX
run: |
mkdir -p ${{ github.workspace }}/openvx-mark/build-rustvx
cd ${{ github.workspace }}/openvx-mark/build-rustvx
cmake \
-DCMAKE_BUILD_TYPE=Release \
-DOPENVX_INCLUDES=${{ steps.rustvx.outputs.include_dir }} \
-DOPENVX_LIB_DIR=${{ steps.rustvx.outputs.lib_dir }} \
..
cmake --build . -j$(nproc)

- name: Run benchmark (rustVX)
run: |
cd ${{ github.workspace }}/openvx-mark/build-rustvx
export LD_LIBRARY_PATH=${{ steps.rustvx.outputs.lib_dir }}:$LD_LIBRARY_PATH
./openvx-mark --resolution VGA --iterations 10 --warmup 3

# ---------------------------------------------------------------------
# Khronos sample benchmark
# ---------------------------------------------------------------------
- name: Build openvx-mark against Khronos sample
run: |
mkdir -p ${{ github.workspace }}/openvx-mark/build-khronos
cd ${{ github.workspace }}/openvx-mark/build-khronos
cmake \
-DCMAKE_BUILD_TYPE=Release \
-DOPENVX_INCLUDES=${{ steps.khronos.outputs.include_dir }} \
-DOPENVX_LIB_DIR=${{ steps.khronos.outputs.lib_dir }} \
..
cmake --build . -j$(nproc)

- name: Run benchmark (Khronos sample)
run: |
cd ${{ github.workspace }}/openvx-mark/build-khronos
export LD_LIBRARY_PATH=${{ steps.khronos.outputs.lib_dir }}:$LD_LIBRARY_PATH
./openvx-mark --resolution VGA --iterations 10 --warmup 3

# ---------------------------------------------------------------------
# Compare results
# ---------------------------------------------------------------------
- name: Compare benchmark results (rustVX vs Khronos)
run: |
RUSTVX=${{ github.workspace }}/openvx-mark/build-rustvx/benchmark_results/benchmark_results.json
KHRONOS=${{ github.workspace }}/openvx-mark/build-khronos/benchmark_results/benchmark_results.json

if [ ! -f "$RUSTVX" ] || [ ! -f "$KHRONOS" ]; then
echo "Skipping comparison — one or both benchmark results missing"
ls -la "$(dirname $RUSTVX)" 2>/dev/null || true
ls -la "$(dirname $KHRONOS)" 2>/dev/null || true
exit 0
fi

# First report is the "candidate" (rustVX); second is the "baseline"
# (Khronos). The Speedup column shows how much faster the candidate
# is than the baseline (>1.0x = rustVX wins).
python3 ${{ github.workspace }}/openvx-mark/scripts/compare_reports.py \
"$RUSTVX" "$KHRONOS" \
--output ${{ github.workspace }}/openvx-mark/comparison

- name: Post comparison to job summary
if: always()
run: |
COMPARISON=${{ github.workspace }}/openvx-mark/comparison.md
if [ -f "$COMPARISON" ]; then
cat "$COMPARISON" >> "$GITHUB_STEP_SUMMARY"
else
echo "_No comparison report was produced._" >> "$GITHUB_STEP_SUMMARY"
fi

- name: Upload rustVX benchmark results
if: always()
uses: actions/upload-artifact@v4
with:
name: benchmark-results-rustvx
path: ${{ github.workspace }}/openvx-mark/build-rustvx/benchmark_results/
if-no-files-found: ignore

- name: Upload Khronos sample benchmark results
if: always()
uses: actions/upload-artifact@v4
with:
name: benchmark-results-khronos-sample
path: ${{ github.workspace }}/openvx-mark/build-khronos/benchmark_results/
if-no-files-found: ignore

- name: Upload comparison report
if: always()
uses: actions/upload-artifact@v4
with:
name: benchmark-comparison
path: ${{ github.workspace }}/openvx-mark/comparison.*
if-no-files-found: ignore
2 changes: 1 addition & 1 deletion LICENSE
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
MIT License

Copyright (c) 2025 Kiriti Nagesh Gowda
Copyright (c) 2026 Kiriti Nagesh Gowda

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
Expand Down
60 changes: 45 additions & 15 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,9 +1,29 @@
<p align="center">
<a href="https://www.khronos.org/openvx/">
<img src="docs/openvx-logo.svg" alt="OpenVX" width="320">
</a>
</p>

# rustVX

[![OpenVX Conformance](https://github.com/kiritigowda/rustVX/actions/workflows/conformance.yml/badge.svg?branch=develop)](https://github.com/kiritigowda/rustVX/actions/workflows/conformance.yml)
[![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg)](LICENSE)
[![Rust](https://img.shields.io/badge/rust-stable-orange.svg)](https://www.rust-lang.org/)

An [OpenVX 1.3.1](https://www.khronos.org/openvx/) 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.

## Conformance Status

rustVX passes the full [Khronos OpenVX 1.3 Conformance Test Suite](https://github.com/KhronosGroup/OpenVX-cts) for both required profiles:

| Profile | Required tests | Passing |
|---------|----------------|---------|
| OpenVX baseline | 863 | **863 / 863** |
| Vision conformance profile | 4957 | **4957 / 4957** |
| **Total enabled** | **5820** | **5820 / 5820** |

Latest CTS run results are published on each push and pull request via the [Actions tab](https://github.com/kiritigowda/rustVX/actions).

## Project Structure

```
Expand Down Expand Up @@ -49,7 +69,10 @@ The shared library is produced at:

## Running Conformance Tests

The [OpenVX Conformance Test Suite](https://github.com/simonCatBot/OpenVX-cts) is included as a git submodule. Build and run it against the rustVX library:
The [Khronos OpenVX Conformance Test Suite](https://github.com/KhronosGroup/OpenVX-cts) 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.

### Linux

Expand All @@ -59,6 +82,7 @@ cd OpenVX-cts
mkdir -p build && cd build
cmake .. \
-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" \
Expand All @@ -80,6 +104,7 @@ cd OpenVX-cts
mkdir -p build && cd build
cmake .. \
-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
Expand All @@ -99,6 +124,7 @@ cd OpenVX-cts
mkdir build; cd build
cmake .. `
-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
Expand All @@ -124,22 +150,26 @@ Use the `--filter` flag to run a subset of tests:

## Continuous Integration

GitHub Actions builds and runs the full CTS on every push and pull request. The workflow splits tests into parallel jobs for faster feedback:
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:

- **baseline** -- Graph, Logging, SmokeTest, Target
- **graph** -- Graph callbacks, delays, ROI, UserNode
- **data-objects** -- Scalar, Array, Matrix, Convolution, Distribution, LUT, Histogram
- **image-ops** -- Image, CopyImagePatch, MapImagePatch, Remap
- **vision-color** -- ColorConvert, ChannelExtract, ChannelCombine, ConvertDepth
- **vision-filters** -- Box, Gaussian, Median, Dilate, Erode, Sobel, Convolve, EqualizeHistogram, NonLinearFilter
- **vision-arithmetic** -- Add, Subtract, Multiply, Bitwise, Not, WeightedAverage, Threshold
- **vision-geometric** -- Scale, WarpAffine, WarpPerspective, Remap, HalfScaleGaussian
- **vision-features** -- HarrisCorners, FastCorners, Canny
- **vision-statistics** -- MeanStdDev, MinMaxLoc, Integral
- **vision-pyramid** -- GaussianPyramid, LaplacianPyramid, LaplacianReconstruct, OptFlowPyrLK
| Job | Test categories | Pipeline status |
|-----|-----------------|-----------------|
| **baseline** | GraphBase, Logging, SmokeTest, Target | [![baseline](https://img.shields.io/github/check-runs/kiritigowda/rustVX/develop?nameFilter=baseline&label=)](https://github.com/kiritigowda/rustVX/actions/workflows/conformance.yml?query=branch%3Adevelop) |
| **graph** | Graph framework (cycles, virtual data, multi-run, replicate node), GraphCallback, GraphDelay, GraphROI, UserNode | [![graph](https://img.shields.io/github/check-runs/kiritigowda/rustVX/develop?nameFilter=graph&label=)](https://github.com/kiritigowda/rustVX/actions/workflows/conformance.yml?query=branch%3Adevelop) |
| **data-objects** | Scalar, Array, ObjectArray, Matrix, Convolution, Distribution, LUT, Histogram | [![data-objects](https://img.shields.io/github/check-runs/kiritigowda/rustVX/develop?nameFilter=data-objects&label=)](https://github.com/kiritigowda/rustVX/actions/workflows/conformance.yml?query=branch%3Adevelop) |
| **image-ops** | Image, CopyImagePatch, MapImagePatch, CreateImageFromChannel, Remap | [![image-ops](https://img.shields.io/github/check-runs/kiritigowda/rustVX/develop?nameFilter=image-ops&label=)](https://github.com/kiritigowda/rustVX/actions/workflows/conformance.yml?query=branch%3Adevelop) |
| **vision-color** | ColorConvert, ChannelExtract, ChannelCombine, ConvertDepth | [![vision-color](https://img.shields.io/github/check-runs/kiritigowda/rustVX/develop?nameFilter=vision-color&label=)](https://github.com/kiritigowda/rustVX/actions/workflows/conformance.yml?query=branch%3Adevelop) |
| **vision-filters** | Box, Gaussian, Median, Dilate, Erode, Sobel, Magnitude, Phase, NonLinearFilter, Convolve, EqualizeHistogram | [![vision-filters](https://img.shields.io/github/check-runs/kiritigowda/rustVX/develop?nameFilter=vision-filters&label=)](https://github.com/kiritigowda/rustVX/actions/workflows/conformance.yml?query=branch%3Adevelop) |
| **vision-arithmetic** | Add, Subtract, Multiply, Bitwise (And/Or/Xor/Not), WeightedAverage, Threshold | [![vision-arithmetic](https://img.shields.io/github/check-runs/kiritigowda/rustVX/develop?nameFilter=vision-arithmetic&label=)](https://github.com/kiritigowda/rustVX/actions/workflows/conformance.yml?query=branch%3Adevelop) |
| **vision-geometric** | Scale, WarpAffine, WarpPerspective, Remap, HalfScaleGaussian | [![vision-geometric](https://img.shields.io/github/check-runs/kiritigowda/rustVX/develop?nameFilter=vision-geometric&label=)](https://github.com/kiritigowda/rustVX/actions/workflows/conformance.yml?query=branch%3Adevelop) |
| **vision-features** | HarrisCorners, FastCorners, Canny | [![vision-features](https://img.shields.io/github/check-runs/kiritigowda/rustVX/develop?nameFilter=vision-features&label=)](https://github.com/kiritigowda/rustVX/actions/workflows/conformance.yml?query=branch%3Adevelop) |
| **vision-statistics** | MeanStdDev, MinMaxLoc, Integral | [![vision-statistics](https://img.shields.io/github/check-runs/kiritigowda/rustVX/develop?nameFilter=vision-statistics&label=)](https://github.com/kiritigowda/rustVX/actions/workflows/conformance.yml?query=branch%3Adevelop) |
| **vision-pyramid** | GaussianPyramid, LaplacianPyramid, LaplacianReconstruct, OptFlowPyrLK | [![vision-pyramid](https://img.shields.io/github/check-runs/kiritigowda/rustVX/develop?nameFilter=vision-pyramid&label=)](https://github.com/kiritigowda/rustVX/actions/workflows/conformance.yml?query=branch%3Adevelop) |

See the [Actions tab](https://github.com/kiritigowda/rustVX/actions) for latest results.
See the [Actions tab](https://github.com/kiritigowda/rustVX/actions) for full run history.

## License

MIT
This project is licensed under the [MIT License](LICENSE).

The OpenVX logo is a trademark of [The Khronos Group Inc.](https://www.khronos.org/legal/trademarks) The vector logo file in `docs/openvx-logo.svg` is sourced from [Wikimedia Commons](https://commons.wikimedia.org/wiki/File:OpenVX_logo.svg) and is included for identification purposes only.
Loading
Loading