Skip to content

fix(camera): blur CLI/self-verify calls undefined edge_detect -> NameError on NPU - #2

Open
Vyacheslav-Tomashevskiy wants to merge 2 commits into
Scottcjn:mainfrom
Vyacheslav-Tomashevskiy:fix/blur-cli-edge-detect-nameerror
Open

fix(camera): blur CLI/self-verify calls undefined edge_detect -> NameError on NPU#2
Vyacheslav-Tomashevskiy wants to merge 2 commits into
Scottcjn:mainfrom
Vyacheslav-Tomashevskiy:fix/blur-cli-edge-detect-nameerror

Conversation

@Vyacheslav-Tomashevskiy

Copy link
Copy Markdown

Problem

camera/blur_pipeline.py defines its NPU design as blur (def blur(...), and both camera/npu_camera_daemon.py and camera/test_blur.py do from blur_pipeline import blur). But the module's own runtime paths were still calling edge_detect — a leftover name from AMD's edge_detect IRON example this file was adapted from. edge_detect is never defined or imported anywhere in blur_pipeline.py:

  • _run_and_verify()edge_detect(in_t, b_t, out_t, **_compile_kwargs(opts))
  • main()run_design_cli(edge_detect, ...)

Why CI stays green but real hardware crashes

blur_pipeline.py imports aie.iron at the top, so on a host without the NPU toolchain the module fails at that import first — which is exactly the boundary ci.yml's import loop expects, so CI is green. On a real NPU box the import succeeds, python camera/blur_pipeline.py reaches main(), and it dies with:

NameError: name 'edge_detect' is not defined

before running the blur design or its self-verify. The module's CLI/self-verify is unusable on the one platform it's meant for.

Fix

Rename the two runtime references from edge_detect to blur (the function that actually exists and that the daemon/test already import). Two-line change; no behavior change on the happy path.

Regression test

Added camera/test_blur_pipeline_cli_symbol.py — a pure-AST test (no aie/numpy, runs anywhere) asserting the design symbol the CLI hands to the NPU is one the module actually defines. Mutation-guarded: it fails on the pre-fix code (AssertionError: ... references undefined edge_detect ...) and passes after the fix. python -m compileall -q camera stays clean.


Verified bug — claimed under the RustChain verified-bug channel (rustchain-bounties#71).
RTC: RTCd1554f0f35576faf01d386a6be1c947f560dd0b7

…Error on NPU

blur_pipeline.py defines the design function , but _run_and_verify()
and main() still referenced  (a leftover from the AMD example
this was adapted from), which is never defined or imported in the module.

The module imports aie.iron at the top, so a host without the NPU toolchain
fails at that import first and CI's import-boundary check stays green. But on
a real NPU box, `python camera/blur_pipeline.py` reaches main() and crashes
with `NameError: name 'edge_detect' is not defined` instead of running the
blur design or its self-verify.

Rename the two runtime references to `blur` (the function the daemon and
test_blur.py already import). Add a pure-AST regression test (no aie/numpy
needed, runs anywhere) asserting the design symbol the CLI hands to the NPU
is one the module actually defines.
…edge-detect

Scottcjn#2 fixed the CLI/self-verify NameError (edge_detect -> blur) but left the
golden reference itself wrong: _run_and_verify() still built its expected
output with _edge_detect_ref() -- a Laplacian edge-detect + threshold +
highlight pipeline that shares no math with the Gaussian blur the design
actually computes. On real NPU hardware --verify would go from 'crashes'
to 'runs and reports a correct blur as wrong', since a blur output never
matches an edge map.

Add _blur_ref(), a numpy reference mirroring blur()'s actual pipeline:
rgba2gray -> 3x3 Gaussian blur (the unity-gain [[1,2,1],[2,4,2],[1,2,1]]/16
kernel filter_kernel_buff actually holds, per the module's own 'GAIN FIX'
docstring, not the Laplacian used for edge-detect) -> gray2rgba, combined
via add_weighted with alpha=1 (register 16384 = Q14 unity) and beta=0
(register 0 -- unlike edge_detect's highlighted-edges-over-original
composite, the original RGBA is not blended back in). Route
_run_and_verify() through it instead of _edge_detect_ref().

Tests (camera/test_blur_pipeline_golden_ref.py, no aie/NPU toolchain
needed -- minimal import-time stand-ins only, real design/verify code
never executed):
  - AST guard that _run_and_verify calls _blur_ref, not _edge_detect_ref
  - impulse-response test pinning the exact kernel weights + normalization
  - flat-field test covering BORDER_REPLICATE at the corners
  - checkerboard smoothing test mirroring test_blur.py's real-hardware
    smoke assertion, entirely in numpy, which also catches a beta!=0
    regression (blending the original color back in would fail it)
  - sanity check that _blur_ref and _edge_detect_ref actually differ

Mutation-checked: reverting the _run_and_verify call fails the AST guard;
corrupting the kernel weights fails the impulse-response test. Existing
camera/*.py CI convention preserved -- blur_pipeline.py still fails only
at the aie import boundary, both new/existing camera test files run to
completion.
@Vyacheslav-Tomashevskiy

Copy link
Copy Markdown
Author

Good catch, thank you -- pushed a revision. Added _blur_ref(), a numpy reference that actually mirrors what blur() computes: rgba2gray -> 3x3 Gaussian blur (the unity-gain [[1,2,1],[2,4,2],[1,2,1]]/16 kernel filter_kernel_buff holds, per the module's own "GAIN FIX" docstring) -> gray2rgba, combined via add_weighted with alpha=1/beta=0 (register values 16384/0 -- the original RGBA is not blended back in, unlike edge_detect's highlighted-edges-over-original composite). _run_and_verify() now calls _blur_ref instead of _edge_detect_ref.

Added camera/test_blur_pipeline_golden_ref.py: an AST guard on the _run_and_verify call target, an impulse-response test pinning the exact kernel weights and normalization shift, a flat-field test for BORDER_REPLICATE at the corners, and a checkerboard-smoothing test mirroring test_blur.py's real-hardware smoke assertion (which also catches a beta!=0 regression). No aie/NPU toolchain needed -- minimal import-time stand-ins only, the real design/verify code is never executed, and blur_pipeline.py still fails only at the aie import boundary per this repo's CI convention. Mutation-checked: reverting the _run_and_verify call target fails the AST guard, corrupting the kernel weights fails the impulse-response test.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant