Skip to content

fix(rpp): Fix normalize HOST to write 3D output and zero-init ND reductions - #12205

Open
sruthi0107 wants to merge 2 commits into
developfrom
users/sruthi0107/fix-normalize-host-3d-zeros
Open

sruthi0107 wants to merge 2 commits into
developfrom
users/sruthi0107/fix-normalize-host-3d-zeros

Conversation

@sruthi0107

Copy link
Copy Markdown

Motivation

Normalize processes a batch of samples, computing or reading a mean and stddev for each, then writing (src - mean) * scale/stddev + shift. Two independent HOST defects made this fail above 2D:

  1. 3D output was all zeros. The F32 3D path computed the statistics but only dispatched a normalize write for NHWC layouts. For a same-layout non-NHWC tensor (e.g. NCHW) no branch matched, so the destination was left at its 0.0 pre-fill and the op returned all zeros while reporting RPP_SUCCESS.

  2. 4D and F16 values were wrong (not zero). The generic-ND path computes mean/stddev with compute_ND_mean / compute_ND_stddev, which accumulate with +=. But the destination buffers were never zeroed first, and the API uses one buffer as both input and scratch — so the reductions were computed on top of the caller-supplied values, inflating the variance (scale / sqrt((suppliedStddev + sumsq)/N)).

HIP is correct for both and is used as the reference.

Issue

JIRA ID : AICV-224

Technical Details

HOST only; both fixes in normalize.cpp.

  1. 3D write: add a same-layout fallback in the 3D dispatch that uses normalize_3D_tensor_nontoggle, which steps outer dims by the descriptor strides and the innermost contiguously and is therefore layout-agnostic for dense tensors.

  2. ND zero-init: zero meanTensor and stdDevTensor over [0, size) before each compute_ND_* call, in both the f32/f32 and generic host entry points, so the accumulating reductions start from zero instead of the caller's supplied values.

Test Plan

Ran the normalize correctness filters from the GoogleTest suite: rpp_tests --gtest_filter='*NormalizeTest*HOST_*cms3*'

Test Result

Test Before After
HOST F32 3D axis7 cms3 2×5×12×16, element (0,0) 0 (expected -2.109473) -2.109473 PASS
HOST F32 4D axis8 cms3 2×2×4×10×12, element (0,0) -1.199973 (expected -1.887847) -1.887847 PASS
HOST F32 3D/4D cms2 & cms3 (all masks) FAIL PASS
HOST F16 2D/3D/4D partial-mask cms2 & cms3 FAIL PASS

The F32 3D path computed mean/stddev but only dispatched a normalize
write for NHWC layouts (avx_axis3 / nontoggle / axis3-toggle). For a
same-layout non-NHWC tensor (e.g. NCHW) none of those branches fired, so
the destination was left at its 0.0 pre-fill and the op returned all
zeros while reporting RPP_SUCCESS.

Add a same-layout fallback that uses normalize_3D_tensor_nontoggle, which
steps outer dims by the descriptor strides and the innermost contiguously
and is therefore layout-agnostic for dense tensors.

Fixes the F32 3D "writes zeros" cases (cms2/cms3 3D go green; cms0/cms1
3D now write real values, their residual failures belong to the separate
per-sample-params and supplied-stddev issues). The 4D / generic-ND
compute-path defect in the same ticket is a distinct root cause and is
not addressed here.
compute_ND_mean and compute_ND_stddev accumulate into meanTensor /
stdDevTensor with +=, but the generic-ND path never zeroed those buffers
first. They still hold the caller-supplied mean/stddev values (the API
takes one buffer that is both input and scratch), so the reductions were
computed on top of that data: the variance in particular was inflated by
the pre-existing stddev, e.g. 1.5 / sqrt((1.0 + sumsq)/N) instead of
1.5 / sqrt(sumsq/N).

The 2D and 3D helpers already zero their accumulators (meanPtr[i] = 0 /
stdDevPtr[i] = 0) and HIP hipMemsetAsync's the tensors; only the ND path
was missing it. Zero meanTensor and stdDevTensor over [0, size) before
each compute_ND_* call, in both the f32/f32 and generic host entry
points.

The contamination shrinks relative to the true sum as more axes are
reduced, which is why the error was largest for single-axis masks and
vanished at full reduction. Fixes the generic-ND compute cases in the
normalize suite (F32 3D/4D and F16 2D/3D/4D partial-mask cms2/cms3),
25 cases in total, with no regressions and HIP unchanged.
@sruthi0107
sruthi0107 requested a review from a team as a code owner September 16, 2026 20:03
@therock-pr-bot

therock-pr-bot Bot commented Sep 16, 2026

Copy link
Copy Markdown

✅ All Checks Passed — Ready for Review

Check Status Details
📝 PR Description ✅ Pass
Forbidden Files ✅ Pass
🧪 Unit Test ⚠️ Warning Error: Source/code files changed without an accompanying unit test.
Expected: add at least one test file named like test_<name>.py / test_<name>.cpp (or <name>_test.*).
Current: code file(s) changed: projects/rpp/src/modules/tensor/cpu/kernel/normalize.cpp; no test file found
🔎 pre-commit ✅ Pass
🚫 Draft PR 🔜 To Be Enabled
🚩 Feature Flag 🔜 To Be Enabled
📊 Code Coverage 🔜 To Be Enabled
🤖 therock-pr-bot ✅ Pass

🎉 All checks passed! This PR is ready for review.

📖 Need help? See the Policy FAQ for details on every check and how to fix failures.

🙋 Wish to Override Policy?

@therock-pr-bot

Copy link
Copy Markdown

🎉 All checks passed! This PR is ready for review.

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.

1 participant