Skip to content

feat(rpp): Add a GoogleTest correctness suite for RPP tensor operations - #11802

Merged
zacharyvincze merged 149 commits into
developfrom
users/zacharyvincze/rpp-test-suite-revamp
Oct 20, 2026
Merged

zacharyvincze merged 149 commits into
developfrom
users/zacharyvincze/rpp-test-suite-revamp

Conversation

@zacharyvincze

@zacharyvincze zacharyvincze commented Sep 8, 2026 •

Copy link
Copy Markdown
Contributor

Summary

Resolves #11894.

Adds projects/rpp/utilities/test/ — a new, self-contained GoogleTest suite that validates RPP tensor ops against independent host-computed reference models. This is purely additive: the existing utilities/test_suite/ is untouched.

The existing test suite compares RPP output against golden image dumps for a fixed set of inputs. That catches regressions but not defects, and only along whichever axis the goldens happened to be captured on. This suite computes the expected result from the operator's documented definition instead, and sweeps every op over the same set of configuration axes, so a bug in one dtype / layout / ROI combination cannot hide behind a passing default.

Scope: ~97 operators, 24,664 test cases, 200 new files.

What's in it

src/
  main.cpp      entry point; installs the suite's console reporter
  framework/    shared harness: config grid, backend memory, comparators, skip list
  reference/    83 independent golden models
  tests/        94 test files — core/, image/, misc/, voxel/

Each op gets one reference/<op>_ref.hpp golden model plus a short TEST_P that builds descriptors, runs the op on both backends, and compares within tolerance over the ROI.

Test grid

Every case is instantiated over the cross product of:

Axis Values
Backend HOST, HIP
DType U8, F16, F32, I8 (+ I16 on the ND grid)
Layout PKD3, PLN3, PLN1, plus fused layout conversions (e.g. PKD3toPLN1)
ROI Full, Partial
Size default, odd-width tail, sub-vector-width, and per-op edge shapes

The shape presets are chosen to land the width at different remainders against SIMD and HIP block widths, so vectorized main loops and scalar tails are both exercised.

Structured, greppable names

{Domain}_{Category}/{Op}Test.{Intent}/{Backend}_{DType}_{Layout}_{Roi}_{Size}[_{OpParams}]

Image_Color/BrightnessTest.Correctness/HIP_U8toU8_PKD3_FullRoi_2x36x48_a1p75_b50

Every axis is independently selectable with --gtest_filter, so "all F32 PKD3 cases" or "HIP only" is a one-liner.

Known-defect skip list

framework/skip_list.hpp holds ~61 filter globs for cases that fail against a real kernel defect (or, in a few cases, a non-reproducible result). Test bodies assert correct behaviour unconditionally — the list is the single place recording which assertions don't hold today, so fixing a kernel means deleting its entry in the same change. RPP_TEST_NO_SKIP_LIST=1 runs them anyway to find entries that have become obsolete.

The suite has already surfaced several genuine defects this way, including a non-deterministic spatter result and layout-specific failures in flip_voxel.

Reporting

A custom console reporter prints one line per suite plus full detail for each failure, which keeps a 24k-case run readable. It replaces GTest's console printer only — --gtest_list_tests and --gtest_output=xml|json are unaffected, so CI and IDE integrations work as with any GTest binary. RPP_TEST_PLAIN_OUTPUT=1 restores stock GTest output.

Building and running

mkdir build && cd build && cmake .. && cmake --build . --parallel
./rpp_tests                     # everything
./rpp_tests --gtest_filter='Image_Color/*'
ctest                           # one process per case; slower, but isolates GPU crashes

Configures standalone against an installed RPP (found under ROCM_PATH) or in-tree as a subdirectory of an RPP build. GoogleTest is fetched at configure time, pinned by tag; -DRPP_TEST_USE_SYSTEM_GTEST=ON uses an installed copy for network-isolated builds. HIP cases are compiled only when the RPP being built against has the HIP backend. The suite's own sources build with -Wall -Wextra -Werror.

Notes for reviewers

  • No RPP library code changes — this PR adds tests only.
  • The bulk of the line count is the 83 reference models and the per-op test instantiations, which
    are repetitive by design. The parts worth close review are src/framework/ (the grid, memory
    handling, and comparators that every test depends on) and the skip list's coverage.
  • Ops not yet covered, and the mixed-precision (U8->F32) dtype axis, are follow-up work; the
    framework already has the seams for both.

@zacharyvincze

Copy link
Copy Markdown
Contributor Author

Addressed documentation issues.

@rrawther rrawther left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Approving so we can migrate and fix the remaining tests

@zacharyvincze
zacharyvincze enabled auto-merge (squash) October 19, 2026 20:30
@spolifroni-amd

Copy link
Copy Markdown
Contributor

Wondering if this needs a line in the changelog.

@zacharyvincze
zacharyvincze merged commit 4c5c20a into develop Oct 20, 2026
90 checks passed
@zacharyvincze
zacharyvincze deleted the users/zacharyvincze/rpp-test-suite-revamp branch October 20, 2026 01:35
isabellagoodwin970 pushed a commit to isabellagoodwin970/rocm-libraries that referenced this pull request Oct 21, 2026
Reference model and Correctness/Negative tests for the new
rppt_bilateral_filter op, in the ROCm#11802 suite layout.

- Golden reuses filter_common.hpp's window: square KxK, REPLICATE
  clamped to the ROI, per-channel range distance, per-image stdDevs,
  stdDevRangeTensor in the dtype's stored units.
- Correctness: 704 cases per backend (gaussian_filter's grid) with
  identity (sr0p1) and gaussian-limit (sr10000) parameter corners.
- Negative: even/out-of-range kernelSize, zero/negative stdDevs and a
  non-REPLICATE border must not return RPP_SUCCESS.

Requires an RPP that declares rppt_bilateral_filter.
@assistant-librarian

Copy link
Copy Markdown
Contributor

TheRock Submodule Bump Activity

Newest first

isabellagoodwin970 pushed a commit to isabellagoodwin970/rocm-libraries that referenced this pull request Oct 23, 2026
Reference model and Correctness/Negative tests for the new
rppt_bilateral_filter op, in the ROCm#11802 suite layout.

- Golden reuses filter_common.hpp's window: square KxK, REPLICATE
  clamped to the ROI, per-channel range distance, per-image stdDevs,
  stdDevRangeTensor in the dtype's stored units.
- Correctness: 704 cases per backend (gaussian_filter's grid) with
  identity (sr0p1) and gaussian-limit (sr10000) parameter corners.
- Negative: even/out-of-range kernelSize, zero/negative stdDevs and a
  non-REPLICATE border must not return RPP_SUCCESS.

Requires an RPP that declares rppt_bilateral_filter.
LakshmiKumar23 pushed a commit that referenced this pull request Oct 27, 2026
…rame (#13941)

## Motivation

When fisheye ran on the CPU with an ROI that does not start at the image
origin, a large part of the output came back black. On a 24x18 ROI at
offset (12, 9), 1408 of 2592 output values were wrong. The GPU path and
full-image ROIs were correct; only CPU partial ROIs were affected.

## Issue
JIRA ID: AICV-260

## Technical Details

The CPU kernel computes the source coordinate relative to the ROI and
reads from a pointer already moved to the ROI origin, which is
consistent. But it checked that coordinate against the ROI's absolute
bounds (x0..x0+w-1, y0..y0+h-1). Every coordinate left of x0 or above y0
was rejected and written as black, and coordinates up to x0+w-1 were
accepted even though the ROI ends at w-1 in that frame.

Validate against the ROI in the same frame the coordinate is in: (0, 0,
w-1, h-1). A new `compute_fisheye_roi_ltrb_local` replaces
`compute_ltrb_from_xywh_host` in the U8, F16, F32 and I8 kernels. The
shared nearest-neighbor helpers are unchanged; warp_affine and
warp_perspective use them with absolute coordinates and are correct.

## Test Plan

Ran the fisheye correctness tests from the GoogleTest suite (#11802)
with the skip list disabled, against `develop` and against this branch:

`RPP_TEST_NO_SKIP_LIST=1 rpp_tests --gtest_filter='*FisheyeTest*'`

Compared CPU against GPU output for all four data types (the suite does
not cover I8), three layouts and four ROI placements. Ran the full
suite, both normal and with the skip list disabled, to check for
regressions.

## Test Result

| Test | Before | After |
|------|--------|-------|
| U8 PKD3 partial ROI, row 1 col 7, golden `96` | `0` (blacked) | `96`
**PASS** |
| CPU fisheye partial-ROI tests | 0/30 | 30/30 **PASS** |
| CPU vs GPU, U8/I8/F16/F32, partial ROIs (differing elements) | 23106 |
0 **PASS** |
| Full suite, normal mode | 15889 OK, 0 FAILED | 15889 OK, 0 FAILED |
| Full suite, skip list disabled | 8601 failing | 8570 failing, 0 new
failures |
sruthi0107 added a commit that referenced this pull request Oct 29, 2026
## Motivation

Implements the HOST (CPU) kernel for `rppt_bilateral_filter`. The API,
entry point and executor declaration came in as scaffolding on
`users/sruthi0107/rpp-bilateral-filter`, where the CPU kernel was a stub
that returned `RPP_ERROR_NOT_IMPLEMENTED`. This PR replaces that stub
with a working scalar implementation that matches the golden model in
`bilateral_filter_ref.hpp`.

## Technical Details

Only `src/modules/tensor/cpu/kernel/bilateral_filter.cpp` changes. The
header, entry point, executor declaration and tests are untouched.

**Algorithm.** For each image, channel and output pixel in the ROI, the
kernel computes the weighted mean over a square K×K window (K ∈ {3, 5,
7, 9}):

    w = exp(-(dy² + dx²) / 2σs²) · exp(-(v - v0)² / 2σr²)
    dst = Σ w·v / Σ w

- **Spatial weights** are precomputed once per image into the host
scratch buffer (`create_bilateral_spatial_kernel_host`).
- **Range weights** depend on the data type:
- **U8 / I8:** a 256-entry lookup table indexed by `|v - v0|`.
Differences are always whole numbers in [0, 255], so the lookup is
exact.
- **F16 / F32:** `exp(-(v - v0)² · rangeMulFactor)` is computed
directly, with `rangeMulFactor = 1 / (2σr²)` precomputed per image.
Float differences aren't whole numbers, so a table can't be indexed by
them.
- **Pixels are accumulated in `Rpp32f`** for every data type.
- **Store:** U8/I8 round to nearest (`nearbyintf`) and then saturate.
F16/F32 are not rounded and are clamped to [0, 1]. I8 adds +128 before
`saturate_pixel` to offset that helper's −128 shift. σr is used in
stored units, with no rescaling.
- **Per-image parameters:** σs and σr are read as `[batchCount]`.
- **Border:** REPLICATE, clamped to the ROI, so no pixels outside the
ROI are read.
- **Layouts:** PLN1, PLN3, PKD3, PKD3→PLN3 and PLN3→PKD3, each addressed
through its own src/dst strides.
- **Parallelism:** one image per OpenMP thread, following
`gaussian_filter_host_tensor`.

**Not in this PR:**
- AVX2 vectorization. This is the plain scalar version; optimization
(for example `fast_exp_avx` for the range term) is planned as a
follow-up, with these tests as the safety net.
- The HIP backend, which still returns `RPP_ERROR_NOT_IMPLEMENTED` from
the scaffold.

## Test Plan

- Built the library with `make rpp` (`-DBACKEND=HIP
-DCMAKE_BUILD_TYPE=Release -DGPU_TARGETS=gfx1100`) and installed it to a
local prefix.
- Copied the tests from `users/sruthi0107/rpp-bilateral-filter-tests`
(golden model and gtest cases, on top of the gtest suite in #11802) into
the working tree without committing them. Built `rpp_tests` against the
local install and confirmed with `ldd` that it loads the new
`librpp.so`.
- Ran `./rpp_tests --gtest_filter='*BilateralFilter*/HOST_*'`.

The test grid covers:
- **Data types:** U8, I8, F16, F32
- **Layouts:** PLN1, PLN3, PKD3, and both mixed layouts
- **ROI:** full and partial
- **Sizes:** 2x36x48, 2x36x55 (odd tail width) and 1x45x13 (narrower
than one AVX2 vector)
- **Parameters:** K = 3/5/7/9; σs = 0.25/1/5; and the two limiting
cases, σr = 0.1 (identity) and σr = 10000 (reduces to a Gaussian)
- **Tolerances:** 1 LSB for U8/I8, 1e-3 for F32, 1e-2 for F16

## Test Result

All 711 HOST tests pass:
- `BilateralFilterTest.Correctness`: 704/704
- `BilateralFilterNegativeTest.Negative`: 7/7

HIP cases were not run; that backend is not implemented yet.

## Submission Checklist

- [x] Look over the contributing guidelines at
https://github.com/ROCm/TheRock/blob/main/GOVERNANCE.md#pull-requests.

---------

Co-authored-by: Sruthi Srinivasan <srutsrin@amd.com>
Co-authored-by: Lakshmi Kumar <lakshmi.kumar@amd.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Feature]: RPP - Create a reference model based test suite with minimal dependencies

9 participants