dnn: use the full vector width in blocked-layout pointwise kernels - #29836
Four block-layout kernels share one defect: they vectorize *across the channel block*, so they only use the vector unit while it happens to match `C0`. This PR fixes all four behind one shared helper, and along the way fixes an unrelated correctness bug found in the same function.
## 1. FP16 BatchNorm writes no output
`batch_norm2_layer.cpp`, the `CV_16F` arm of the accelerated block-layout path, wraps its whole body in a condition that cannot be true:
```cpp
} else if (type == CV_16F) {
const hfloat* inptr = ...;
if (type == CV_32F) { // false by construction
```
There is no `else`, so every vector loop in that arm is dead and **nothing is written to the output**. A half-precision BatchNorm on a blocked tensor with `C0` equal to 1, 2 or 4 times the vector width returns whatever the destination buffer already held. The `CV_32F` and `CV_16BF` arms are correct; only the redundant wrapper is removed.
Confirmed with a sentinel-prefilled destination: before the fix the sentinel survives the call (`maxerr = 12346`) for all three `C0` values, after it the output is exact.
## 2. The kernels only use min(C0, VEC_SZ) lanes
`C0` is the block-layout channel block, fixed at 8 (`net_impl.hpp`, `DEFAULT_C0`), so these guards decide how much of the register gets used:
| kernel | guard | consequence with C0=8 |
|---|---|---|
| ChannelsPReLU | `C0 == VEC_SZ` | scalar at 4 lanes **and** at 16/32 |
| BatchNorm | `C0 == vlanes*{4,2,1}` | scalar at 16/32 |
| InstanceNorm | `c0 <= validC0 - VEC_SZ` | scalar at 16/32 |
| GroupNorm | `c0 <= c0_hi - VEC_SZ` | scalar at 16/32 |
PReLU is the worst case: an equality can only hold on an 8-lane build, so a default x86 SSE build (4 lanes) runs it scalar too. The other three use chunk loops that work at <= 8 lanes and fail above.
These files are not in the CPU-dispatch list, so `v_float32` is whatever `CPU_BASELINE` gives -- this is not RISC-V-specific.
### Approach
A block-layout plane is contiguous over `(H, W, C0)` and the coefficients repeat with period `C0`, so one register can span `vlanes/C0` pixels: replicate the coefficients across it and walk the plane flat.
All three spanning call sites now go through one helper, `cpu_kernels/blocked_pointwise.hpp::blockedSpanApply()`, parameterised by the per-element operation (`BlockedAffineOp`, `BlockedPReLUOp`). PReLU additionally gains a chunked path for `C0 > VEC_SZ`, which is what restores it on 4-lane targets. BatchNorm keeps its own unrolled loops and gains a whole-vector step plus a remainder loop. Pre-existing paths are untouched, so targets that already vectorized keep the same code.
**GroupNorm also gains a vector reduction.** Its mean/variance pass walked one channel at a time with a stride of `C0`, which no target vectorized at all, so that half speeds up everywhere rather than only on wide vectors. Both new GroupNorm paths are restricted to blocks owned entirely by one group; where a group boundary falls inside a block the old per-channel code still runs, because spanning would cross into channels another `parallel_for_` task is writing.
### Note for reviewers: the helper's `noinline` is load-bearing
`blockedSpanApply()` carries an explicit `noinline`. Inlined, GCC 15.2 on RISC-V speculates its stores into callers whose guard is false, which silently corrupted a neighbouring group's channels in `fastNormGroupBlockF32`. The symptom was exactly half the elements wrong at VLEN=1024 in the cases where a group splits a block; a runtime trace showed the guard evaluating false on every block, and inserting any call before the `if` made it disappear. Please do not remove the attribute.
## Benchmarks
SpacemiT K3, GCC 15.2, `CPU_BASELINE=RVV`, single thread, median of 11, pristine vs patched built back to back in one session. The board exposes two core types with different VLEN, so both columns are the same binary on the same machine.
Speedup, VLEN=256 / VLEN=1024:
| shape (NxC1xHxWxC0) | Ci | InstanceNorm | BatchNorm | GroupNorm |
|---|---|---|---|---|
| 1x32x56x56x8 | 256 | 1.01x / 14.38x | 0.91x / 11.62x | 1.85x / 14.56x |
| 1x16x28x28x8 | 128 | 1.01x / 16.27x | 0.98x / 3.95x | 1.91x / 16.01x |
| 1x8x112x112x8 | 64 | 1.02x / 12.76x | 1.03x / 1.37x | 1.98x / 12.86x |
| 1x16x56x56x4 | 64 | 3.01x / 12.47x | 4.49x / 6.18x | 3.01x / 11.78x |
ChannelsPReLU, measured separately the same way:
| shape | Ci | VLEN=256 | VLEN=1024 |
|---|---|---|---|
| 1x32x56x56x8 | 256 | 1.45x | 8.37x |
| 1x16x28x28x8 | 128 | 1.55x | 4.16x |
| 1x64x14x14x8 | 512 | 1.46x | 4.05x |
| 1x8x112x112x8 | 64 | 1.47x | 3.77x |
| 1x16x56x56x4 | 64 | 2.99x | 8.47x |
| 1x8x56x56x16 | 128 | 1.20x | 2.33x |
The VLEN=256 columns for InstanceNorm and BatchNorm are flat by construction -- `C0 == VEC_SZ` there, so those shapes already vectorized and the code is unchanged; the 0.91-1.03x spread is measurement noise. The rows that move at 256 are `C0=4` (block narrower than the vector), PReLU (broken at every width), and GroupNorm (reduction).
**Caveat on the BatchNorm numbers.** BatchNorm timings on this board are much less reproducible than the other three. The `1x8x112x112x8` case in particular measured anywhere from 1.4x to 6.9x across builds with byte-identical BatchNorm sources, and its pristine baseline moved by 26% between runs. The working set there is 3.06 MB, an exact multiple of 4096, and this hardware is sensitive to how source and destination alias in the cache; the numbers above are one back-to-back pair rather than a stable figure. InstanceNorm, GroupNorm and PReLU reproduced to within ~1% across every build.
## Testing
Verified against a scalar reference over 43 shape / `C0` / `Ci` / group combinations across the four layers, at VLEN 256 and 1024, at 1 and 8 threads, clean under `MALLOC_CHECK_=3`. Cases include partial trailing blocks, odd planes (7x7, 13x11) that exercise the remainder loops, `C0` from 2 to 64, and GroupNorm configurations where a group boundary falls inside a block -- those take the fallback and match bit-exactly, which is what confirms the ownership guard.
`opencv_test_dnn` was **not** run: the build used here is `BUILD_LIST=dnn`, which generates no dnn test target, and the board has no `opencv_extra` checkout. The blocked path's reachability was confirmed by inspection instead -- `ActivationLayer::getLayouts` passes the producer's layout through, and `useBlockLayout()` runs unconditionally in `finalizeGraph`, so these kernels are on the default path in real nets.
## Platform scope
Nothing here is behind a RISC-V `#ifdef`; this is universal-intrinsic code that compiles into every target.
| target (C0=8) | lanes | what changes |
|---|---|---|
| x86 SSE baseline (default) | 4 | PReLU newly vectorized; GroupNorm reduction newly vectorized |
| x86 AVX2 baseline | 8 | GroupNorm reduction; BatchNorm loop rewritten (same iterations) |
| x86 AVX-512 baseline | 16 | + all spanning paths go live |
| ARM64 NEON | 4 | as SSE baseline |
| ARMv7 NEON | 4 | `CV_SIMD_64F`=0, reduction path skipped |
| RVV 256 | 8 | PReLU, GroupNorm reduction |
| RVV >= 512 | 16/32 | everything |
Two changes reach a **default x86 build**: PReLU, which was scalar there because `C0 == VEC_SZ` cannot hold at 4 lanes, and the GroupNorm reduction, which was scalar everywhere. The latter changes GroupNorm's numerical output on those targets, since summation order differs -- measured at ~1e-7 relative here.
Measurements are RISC-V only; no x86 or ARM machine was available. The spanning branches were exercised on RVV at the same `vlanes/C0` ratios an AVX-512-baseline build would hit (2:1 and 4:1), but the x86-reachable changes above have had no x86 validation and are the part most worth checking in CI.
Added Bitcast layer & extended MatMul and DFT layers support - #29594
### Pull Request Readiness Checklist
See details at https://github.com/opencv/opencv/wiki/How_to_contribute#making-a-good-pull-request
- [x] I agree to contribute to the project under Apache 2 License.
- [x] To the best of my knowledge, the proposed patch is not based on a code under GPL or another license that is incompatible with OpenCV
- [x] The PR is proposed to the proper branch
- [x] There is a reference to the original bug report and related work
- [x] There is accuracy test, performance test and test data in opencv_extra repository, if applicable
Patch to opencv_extra has the same branch name.
- [x] The feature is well documented and sample code can be built with the project CMake
Support ONNX Cast/CastLike for FP8/FP4/INT4/UINT4/E8M0 dtypes - #29360
### Pull Request Readiness Checklist
See details at https://github.com/opencv/opencv/wiki/How_to_contribute#making-a-good-pull-request
- [x] I agree to contribute to the project under Apache 2 License.
- [x] To the best of my knowledge, the proposed patch is not based on a code under GPL or another license that is incompatible with OpenCV
- [x] The PR is proposed to the proper branch
- [x] There is a reference to the original bug report and related work
- [x] There is accuracy test, performance test and test data in opencv_extra repository, if applicable
Patch to opencv_extra has the same branch name.
- [x] The feature is well documented and sample code can be built with the project CMake
## dnn: extend engine-new layer dtype coverage (control flow, Range, Hardmax, MaxUnpool, CumSum/CumProd, MaxPool, Resize2, normalization, Gemm, MatMul)
ONNX permits these dtypes on these ops, but the engine-new layers refused them at graph-construction time, so :
- valid models either failed to load outright or
- a layer quietly converted to float32 instead (Resize2)
- ran but silently lost precision above float32's 24-bit mantissa.
Companion PR (test data) : [1406](https://github.com/opencv/opencv_extra/pull/1406)
### Support added, per layer
| Layer | Types added | Gate / kernel |
|---|---|---|
| If | Bool, 16U, 16S, 32U, 32S, 64U | Gate only — the condition-reading switch already handled every depth |
| Loop | Bool, 16U, 16S, 32U, 32S, 64U | Gate only — same as If |
| Scan | Bool, 16U, 16S, 32U, 32S, 64U | Gate only — Scan never inspects element values at all |
| Range | 16S | Kernel only — gate was already an unconditional passthrough |
| Hardmax | 64F | Gate only — the `double` kernel has existed since 2024, just unreachable |
| MaxUnpool | 64F | Gate + a genuine `double` instantiation of the value-scatter routine |
| CumSum | 32U, 64U | Gate + two instantiations of the existing running-sum template (wraparound on overflow) |
| CumProd | 32U, 64U | Gate + two instantiations of the existing running-product template |
| MaxPool | 8S, 8U, 64F | Kernel only (gate was already open) — new scalar kernel for the blocked values-only path **and** the separate values+indices path, which had its own float32-only assert |
| Resize2 | 32S (nearest-neighbor only) | Gate + native `int32` gather; bilinear/cubic now reject 32S explicitly instead of silently converting to `float` |
| RMSNorm | 64F | Kernel — `fast_norm.cpp` templated on `T`, genuine `double` accumulator |
| LayerNorm | 64F | Kernel — same shared `fast_norm.cpp` path |
| LayerNorm2 | 64F | Kernel — same shared `fast_norm.cpp` path |
| InstanceNorm | 64F | Kernel — existing SIMD float32 blocked path left untouched, new scalar `double` path added beside it |
| GroupNorm | 64F | Kernel — same treatment as InstanceNorm |
| Gemm | 64F | Kernel — dedicated `cv::gemm` path, bypassing the float-only fastGemm/MLAS kernels |
| MatMul | 64F, 32S, 64S, 32U, 64U | Gate + two new paths: per-batch `cv::gemm` for 64F, and a direct 64-bit-accumulated loop for the four integer types |
Removed `test_maxpool_2d_uint8` from `opencv_all_denylist` : with 8U now supported, the test passes NORMASSERT on all backend/target combinations .
### Pull Request Readiness Checklist
See details at https://github.com/opencv/opencv/wiki/How_to_contribute#making-a-good-pull-request
- [x] I agree to contribute to the project under Apache 2 License.
- [x] To the best of my knowledge, the proposed patch is not based on a code under GPL or another license that is incompatible with OpenCV
- [x] The PR is proposed to the proper branch
- [x] There is a reference to the original bug report and related work
- [x] There is accuracy test, performance test and test data in opencv_extra repository, if applicable
Patch to opencv_extra has the same branch name.
- [x] The feature is well documented and sample code can be built with the project CMake
This PR is about Introducing cuDNN JIT support for the DNN Module
### Pull Request Readiness Checklist
See details at https://github.com/opencv/opencv/wiki/How_to_contribute#making-a-good-pull-request
- [x] I agree to contribute to the project under Apache 2 License.
- [x] To the best of my knowledge, the proposed patch is not based on a code under GPL or another license that is incompatible with OpenCV
- [x] The PR is proposed to the proper branch
- [ ] There is a reference to the original bug report and related work
- [ ] There is accuracy test, performance test and test data in opencv_extra repository, if applicable
Patch to opencv_extra has the same branch name.
- [ ] The feature is well documented and sample code can be built with the project CMake
Added GridSample BiCubic, Dropout support - #29783
Updated ONNX coverage after this PR: 74.8%
### Pull Request Readiness Checklist
See details at https://github.com/opencv/opencv/wiki/How_to_contribute#making-a-good-pull-request
- [x] I agree to contribute to the project under Apache 2 License.
- [x] To the best of my knowledge, the proposed patch is not based on a code under GPL or another license that is incompatible with OpenCV
- [x] The PR is proposed to the proper branch
- [x] There is a reference to the original bug report and related work
- [x] There is accuracy test, performance test and test data in opencv_extra repository, if applicable
Patch to opencv_extra has the same branch name.
- [x] The feature is well documented and sample code can be built with the project CMake
Extend data type support in elementwise, gather and scatter layers - #29786
### PR Changes:
### Support added, per layer
| Layer | Types added | Gate / kernel |
|---|---|---|
| Abs | 8U, 8S, 16U, 16S, 32U, 32S, 64U, 64S | Gate + new templated integer kernel |
| Sign | 8U, 8S, 16U, 16S, 32U, 32S, 64U, 64S | Gate + same templated kernel |
| Neg | 32S | Gate only. The kernel already had a `CV_32S` branch |
| GatherElements | 64F, 16U, 16S, 32U, 64U | Gate + element-width dispatch |
| Scatter | 64F, 16U, 16S, 32U, 64U | Gate + dispatch arms, all five reductions checked |
| ScatterND | 64F, 16U, 16S, 32U, 64U | Gate + dispatch arms, same as Scatter |
| GatherND | 64F, 16U, 16S, 32U, 64U | Gate + element-width dispatch |
| Slice2 | (fix) | Kernel. Wrong-width copy, see below |
`Abs`/`Sign` use one template over all widths with the signed/unsigned split resolved at compile time;
unsigned `abs` short-circuits to `copyTo` and unsigned `sign` reduces to `x != 0`. `GatherElements` and
`GatherND` only move elements, so their per-dtype arms collapsed to four widths. `GatherND` also unified a
target-conditional gate that split `16F`/`32F` by target in a file with no OpenCL path.
`Slice2` had two duplicated depth chains that both fell through to `run_parallel<float>`, a 4-byte copy, so
`64F`/`64U` truncated and `16U`/`16S` read and wrote past the element. Reachable only when the innermost axis
has `step != 1`, which is why the float32 slice tests passed. Now dispatches on `elemSize()`, matching
`pad2_layer.cpp`.
**Two further fixes:** signed-overflow UB in the int64 `Power`/`Neg` path (`sp[i] * scale` is undefined at
`INT64_MIN`, now multiplied through `uint64_t`), and `CV_OCL_RUN` now skips integer depths, since the OCL
activation kernels are float math and `CV_32S` would have gone through a 24-bit mantissa.
**New accuracy tests in `test_int.cpp`**: `Test_Abs_Int`, `Test_Sign_Int`, `Test_Neg_Int`, `Test_Scatter_Int`,
`Test_GatherND_Int`, with `Test_GatherElements_Int` and `Test_ScatterND_Int` widened to nine depths.
Removed `test_slice_start_out_of_bounds` from the parser denylist.
### Pull Request Readiness Checklist
See details at https://github.com/opencv/opencv/wiki/How_to_contribute#making-a-good-pull-request
- [x] I agree to contribute to the project under Apache 2 License.
- [x] To the best of my knowledge, the proposed patch is not based on a code under GPL or another license that is incompatible with OpenCV
- [x] The PR is proposed to the proper branch
- [x] There is a reference to the original bug report and related work
- [x] There is accuracy test, performance test and test data in opencv_extra repository, if applicable
Patch to opencv_extra has the same branch name.
- [x] The feature is well documented and sample code can be built with the project CMake
Linear and Flex attention layers support - #29624
### Pull Request Readiness Checklist
See details at https://github.com/opencv/opencv/wiki/How_to_contribute#making-a-good-pull-request
- [x] I agree to contribute to the project under Apache 2 License.
- [x] To the best of my knowledge, the proposed patch is not based on a code under GPL or another license that is incompatible with OpenCV
- [x] The PR is proposed to the proper branch
- [x] There is a reference to the original bug report and related work
- [x] There is accuracy test, performance test and test data in opencv_extra repository, if applicable
Patch to opencv_extra has the same branch name.
- [x] The feature is well documented and sample code can be built with the project CMake
Add Image Decoder ONNX Layer - #29785
### Pull Request Readiness Checklist
See details at https://github.com/opencv/opencv/wiki/How_to_contribute#making-a-good-pull-request
- [x] I agree to contribute to the project under Apache 2 License.
- [x] To the best of my knowledge, the proposed patch is not based on a code under GPL or another license that is incompatible with OpenCV
- [x] The PR is proposed to the proper branch
- [x] There is a reference to the original bug report and related work
- [x] There is accuracy test, performance test and test data in opencv_extra repository, if applicable
Patch to opencv_extra has the same branch name.
- [x] The feature is well documented and sample code can be built with the project CMake
dnn: vectorize fast_norm for scalable-vector (RVV) targets - #29598
### Problem
The normalization CPU kernels in `fast_norm.cpp` run **scalar** on RISC-V RVV
scalable-vector builds. Their vector code is gated by `#if CV_SIMD`, and on scalable
targets `intrin.hpp` sets `CV_SIMD 0` / `CV_SIMD_SCALABLE 1`, so the blocks are dropped by
the preprocessor. LayerNorm / RMSNorm / InstanceNorm / GroupNorm / MVN are therefore scalar
there. Independently, the `#if CV_SIMD` blocks only covered the block-layout path — the NCHW
paths these layers actually use had no explicit SIMD, and the compiler does not
auto-vectorize them (the per-element `j/step` channel-index division in the GroupNorm apply
and the float→double widening reduction defeat it).
These kernels are the last scalar piece of the new-engine (`ENGINE_NEW`) transformer norm
path; they are shared by the classic engine as well.
### Changes
- Guards → `#if (CV_SIMD || CV_SIMD_SCALABLE)` (6 sites; f64 →
`#if CV_SIMD_64F || CV_SIMD_SCALABLE_64F`), no fixed-width `::nlanes` — same idiom already
used across `modules/dnn/src`.
- Vectorized the NCHW mean/variance reduction (new `normAccumSumSqSum` /
`normAccumSumSqSum64f`, float/double accumulators matching the scalar reference) and the
affine-apply loops.
- `fastNormGroup` apply hoists the per-channel scale/bias out of the inner loop so the
`j/step` division no longer blocks vectorization.
### Testing — SpacemiT K1 (rv64gcv, VLEN=256, 8×1.6 GHz, governor=performance), 5.x
Built `-DCPU_BASELINE=RVV -DRISCV_RVV_SCALABLE=ON`.
**Correctness — zero new failures.** Default `ENGINE_AUTO`:
| Filter | baseline | patch |
|---|---|---|
| `*LayerNorm*:*InstanceNorm*:*MVN*:*Norm*:*GroupNorm*` | 27/27 pass | 27/27 pass |
| `*Test_ONNX_layers*` | 263 pass / 1 fail (`Tile`, pre-existing) | 263 pass / 1 fail (`Tile`) |
Re-run with `OPENCV_FORCE_DNN_ENGINE=2` : the supported subset
(LayerNorm/InstanceNorm/GroupNorm) passes on both baseline and patch (MVN is not implemented
in the new engine and falls back to classic under AUTO).
**Performance** — `opencv_perf_dnn`, geomean of 3 rounds:
| Test | shape | base ms (1thread / 8threads) | patch ms (1t / 8t) | speedup (1t / 8t) |
|---|---|---|---|---|
| GroupNorm::Layer | {2,64,180,240}, g=16 | 104.6 / 14.36 | 12.93 / 10.75 | **8.1×** / 1.34× |
| InstanceNorm::Layer | {2,64,180,240} | 52.96 / 11.76 | 13.63 / 10.72 | **3.9×** / 1.10× |
| LayerNorm::Layer | {1,50,768} | 0.215 / 0.072 | 0.104 / 0.068 | **2.1×** / ~1.0× |
New engine confirmed directly via `readNetFromONNX(layernorm.onnx, ENGINE_NEW)`: 1×512×768
single-thread 2.74 → 1.62 ms (**1.69×**); a base-vs-patch delta under `ENGINE_NEW` proves the
new engine executes the changed kernel.
### Pull Request Readiness Checklist
See details at https://github.com/opencv/opencv/wiki/How_to_contribute#making-a-good-pull-request
- [x] I agree to contribute to the project under Apache 2 License.
- [x] To the best of my knowledge, the proposed patch is not based on a code under GPL or another license that is incompatible with OpenCV
- [x] The PR is proposed to the proper branch
- [ ] There is a reference to the original bug report and related work
- [x] There is accuracy test, performance test and test data in opencv_extra repository, if applicable
Patch to opencv_extra has the same branch name.
- [ ] The feature is well documented and sample code can be built with the project CMake
Dynamic KV-cache support - #29642
The core idea is: reserveKVCache() API to pre-allocate memory for attention caches upfront, which eliminates allocation overhead during token decoding. For LLM inference, simply call reserveKVCache(prompt_len + max_new_tokens) before the prefill stage so the decode loop runs without page allocations, significantly reducing per-token latency for models like Gemma3 and Qwen.
Speedups after this PR on AMD Ryzen 9 9950X 16-Core Processor device:
Qwen2.5-0.5B-Instruct, fp32, CPU, tok/s:
```
Tokens Before After Speedup
64 12.49 23.72 1.90×
128 10.37 23.14 2.23×
256 7.20 22.40 3.11×
512 4.25 21.03 4.95×
```
Gemma 3 1B-it, fp32, CPU, 512 tokens :
```
Tokens Before After Speedup
64 6.99 11.84 1.69×
128 5.84 11.72 2.01×
256 4.17 11.50 2.76×
512 2.47 11.15 4.51×
```
### Pull Request Readiness Checklist
See details at https://github.com/opencv/opencv/wiki/How_to_contribute#making-a-good-pull-request
- [x] I agree to contribute to the project under Apache 2 License.
- [x] To the best of my knowledge, the proposed patch is not based on a code under GPL or another license that is incompatible with OpenCV
- [x] The PR is proposed to the proper branch
- [x] There is a reference to the original bug report and related work
- [x] There is accuracy test, performance test and test data in opencv_extra repository, if applicable
Patch to opencv_extra has the same branch name.
- [x] The feature is well documented and sample code can be built with the project CMake
Add MatMulNBits layer and extend onnx coverage - #29666
Requires:https://github.com/opencv/opencv_extra/pull/1401
### Pull Request Readiness Checklist
See details at https://github.com/opencv/opencv/wiki/How_to_contribute#making-a-good-pull-request
- [x] I agree to contribute to the project under Apache 2 License.
- [x] To the best of my knowledge, the proposed patch is not based on a code under GPL or another license that is incompatible with OpenCV
- [x] The PR is proposed to the proper branch
- [x] There is a reference to the original bug report and related work
- [x] There is accuracy test, performance test and test data in opencv_extra repository, if applicable
Patch to opencv_extra has the same branch name.
- [x] The feature is well documented and sample code can be built with the project CMake
dnn: add HAL hook for general convolution and an RVV kernel - #29689
### Pull Request Readiness Checklist
See details at https://github.com/opencv/opencv/wiki/How_to_contribute#making-a-good-pull-request
- [x] I agree to contribute to the project under Apache 2 License.
- [x] To the best of my knowledge, the proposed patch is not based on a code under GPL or another license that is incompatible with OpenCV
- [x] The PR is proposed to the proper branch
- [x] There is a reference to the original bug report and related work
- [x] There is accuracy test, performance test and test data in opencv_extra repository, if applicable
Patch to opencv_extra has the same branch name.
- [x] The feature is well documented and sample code can be built with the project CMake
### Summary
Adds cv_hal_dnn_conv32f and a RISC-V RVV implementation.
The hook uses the same flat C ABI as the existing DNN hooks and is behaviour-neutral without a backend. The RVV kernel runs e32m2 at vl = K0 = 8 with 10 output positions in flight, and on wide registers packs P = VLMAX/K0 output channel blocks into one vector. It declines to the built-in when an output channel block is only partially filled: K % 8, K/ngroups % 8, or grouped C/ngroups % 8.
### Verification — K3 board, VLEN 256 and 1024, GCC 15.2 + Clang 22
- Standalone harness, 22 configurations (kernel sizes, strides, dilation, asymmetric pads, 1D/2D/3D, groups, residual, all five activations): pass at both VLENs, bit-identical to a scalar reference
- opencv_test_dnn under OPENCV_FORCE_DNN_ENGINE=2: 960 passed / 29 failed, failure set identical with the hook on and off and at both VLENs; the 29 are pre-existing
- Fault injection flips exactly 19 tests, confirming the hook is on the execution path
### Performance – speedup over the built-in
| Network | 8 threads, VLEN 256 | 1 thread, VLEN 256 | 1 thread, VLEN 1024 |
| :--- | :--- | :--- | :--- |
| **SqueezeNet_v1_1** | 2.91× | 7.8× | 19.4× |
| **Inception_v1** | 2.00× | 7.0× | 13.7× |
| **Squeezenet** | 2.17× | 6.9× | 14.5× |
| **TinyYolov2** | 2.14× | 6.8× | 14.2× |
| **ResNet_50** | 2.56× | 5.7× | 9.7× |
| **LResNet100E_IR** | 1.94× | 5.5× | 11.2× |
Re-enable & triage DISABLED tests for DNN module - #29702
Requires: https://github.com/opencv/opencv_extra/pull/1403
**co-authored by: @varun-jaiswal17**
### PR Changes:
## dnn test cleanup: re-enable stale-disabled tests, fix defect-blind tests, remove redundant coverage
### Removed (dead or unbuildable)
- `test_int8_layers.cpp` (1118 lines, removed entirely): cannot compile — `Net::quantize()`,
`getInputDetails`/`getOutputDetails` are all gone from `dnn.hpp`/`dnn/src`. Disabled in that same PR (#24980)
because on-the-fly quantization was removed — every test in this file called `net.quantize()` to calibrate and
run its own int8 conversion. Its own header comment said restore "when test models are quantized outside
OpenCV". Pre-quantized ONNX/TFLite test models already do that.
### Removed (redundant or assertion-free)
- `Tokenizer_BPE.Tokenizer_GPT2_Model`: line-for-line subset of `Tokenizer_GPT2` — same config, same input,
same roundtrip assertion.
- `Test_TensorFlow.read_inception`: printed `out.dims` and asserted nothing about the result;
`inception_accuracy` loads the same `.pb` and checks it against a reference.
- `Test_Caffe_nets` fixture + `INSTANTIATE`: registered **zero** `TEST_P` cases — dead scaffolding for Faster
R-CNN tests removed earlier.
- `Test_ONNX_nets.Squeezenet`: kernels {1×1, 3×3} and every op type already covered by dedicated layer tests.
- `Test_ONNX_nets.VGG16_bn`: single conv kernel (3×3), fully covered by dedicated layer tests; skipped by
default anyway under `mem_6gb`.
- `Test_ONNX_nets.CaffeNet`: identical op multiset, node count (24) and conv signatures to retained `Alexnet`.
- `Test_ONNX_nets.RCNN_ILSVRC13`: `Alexnet` minus `Softmax` (23 vs 24 nodes), identical conv signatures.
- `Test_ONNX_nets.Inception_v1`: same op set as retained `Googlenet` (+1 `Reshape`) — Inception v1 *is*
GoogLeNet.
### Given real assertions instead of stale expectations
- `Test_ONNX_layers.Elementwise_Sqrt`: moved `testONNXModels("sqrt")` below `#endif` — its only work line sat
inside `INF_ENGINE_VER_MAJOR_LT(2021040000)`, so without OpenVINO the body compiled to nothing and reported `[
OK ]` on all 3 backends.
- `Layer_Test_01D.Clip`: now calls `ClipLayer::create` with `"min"`/`"max"` — it set `lp.type = "Clip"` but
constructed `ReLU6Layer::create`, and `runLayer` never reads `layer->type`, so it just re-ran `ReLU6`.
- `Layer_Arg_Test`: removed the "disabled" comment, corrected the `convertTo` comment — the comment said the
test was disabled while it runs 8 cases, and the second said "convert to float" where the code converts to
`CV_64S`.
### Re-enabled as-is (stale disable reasons)
- `Test_ONNX_layers.LSTM`/`LSTM_bidirectional` (`test_onnx_importer.cpp:1551,1558`): disabled by #21522 (2022)
for poor 1-D-mat handling in the importer of that era; no longer reproduces.
- `Test_ONNX_layers.Split_sizes_0d` (`:1373`): disabled by #22652 for a Mul/0-d-tensor shape ambiguity (A×1 vs
1×A); dnn now supports real 1-D Mats, so the output matches the reference exactly.
- `DNNTestNetwork.YOLOv8n`
### Library fixes found while re-enabling
- `Test_ONNX_layers.LSTM_layout_seq`/`LSTM_layout_batch` (`test_onnx_importer.cpp:1721,1728`): `LSTM2` never
transposed `X` for ONNX `layout=1` (batch-first); fixed via `transposeND` gated on `layout==BATCH_SEQ_HID`
(`recurrent2_layers.cpp:172`). Fixture also had a leaked loop variable that made the reference a copy of the
input; rebuilt by hand since ORT itself refuses to run `layout=1`.
- `Test_Graph_Simplifier.ResizeSubgraph` (`test_graph_simplifier.cpp:61`): disabled by the block-layout PR
#28585; expectations updated for the `TransformLayout` pass that PR introduced. The test now covers 4 subgraphs rather than 6, because `GatherCastSubgraph` and `MulCastSubgraph` were removed by `0e36cafcf4` and `7669897910` (`Gather`/`Mul` -> `Cast` is no longer fused, since folding it away silently dropped the `Cast`'s dtype semantics). The dynamic-scale `Shape`/`Gather`/`Cast`/`Floor`/`Concat`/`Unsqueeze`/`Slice` chain these models use to compute Resize's scale factor therefore no longer collapses, and the `Mul` survives as `NaryEltwise`, which is why the expected layer lists grew
### Deliberately kept
- `ZFNet`: its **7×7** conv appears in no dedicated layer test, and its kernel set {7×7, 5×5, 3×3} differs from
`Alexnet`'s {11×11, 5×5, 3×3}.
### Pull Request Readiness Checklist
See details at https://github.com/opencv/opencv/wiki/How_to_contribute#making-a-good-pull-request
- [x] I agree to contribute to the project under Apache 2 License.
- [x] To the best of my knowledge, the proposed patch is not based on a code under GPL or another license that is incompatible with OpenCV
- [x] The PR is proposed to the proper branch
- [x] There is a reference to the original bug report and related work
- [x] There is accuracy test, performance test and test data in opencv_extra repository, if applicable
Patch to opencv_extra has the same branch name.
- [x] The feature is well documented and sample code can be built with the project CMake