1
0
mirror of https://github.com/opencv/opencv.git synced 2026-07-29 15:23:05 +04:00
Files
opencv/hal
Teddy-Yangjiale 66263c5952 Merge pull request #29057 from Teddy-Yangjiale:rvv-core-norm
Rvv core norm #29057

Fixes opencv/opencv#29052

### Problem
`Core_Norm/ElemWiseTest.accuracy/0` failed on RISC-V with RVV enabled when computing norm for `CV_16S` data.
The reported failing case was:

```text
src[0] ~ 16sC4 3-dim (1 x 116 x 40)
```
The expected norm result was a large positive `double`, but the RVV path returned an incorrect value:

```text
expected: 3370900308417
actual:   -173296
```

This indicates that the problem was not in the public `cv::norm()` API, but in the RVV HAL implementation used for the `CV_16S` L2/L2SQR accumulation path.

### Root Cause

The RVV HAL has a specialized implementation for `CV_16S` L2 norm:

```cpp
NormL2_RVV<short, double>
```

The implementation widens `int16` values, squares them, converts the widened products to `float64`, accumulates them in an `f64m8` vector, and finally reduces the vector to a scalar `double`:

```cpp
auto s = __riscv_vfmv_v_f_f64m8(0, vlmax);
...
auto v_mul = __riscv_vwmul(v, v, vl);
s = __riscv_vfadd_tu(s, s, __riscv_vfwcvt_f(v_mul, vl), vl);
...
return __riscv_vfmv_f(__riscv_vfredosum(...));
```

The bug was in the scalar initializer passed to `__riscv_vfredosum`.

Before this patch, the code created an `f64m1` scalar vector but used the maximum vector length for `e32m1`:

```cpp
__riscv_vfmv_s_f_f64m1(0, __riscv_vsetvlmax_e32m1())
```

This is inconsistent: the vector type is `f64m1`, so the VL used to initialize it must correspond to `e64m1`, not `e32m1`.
2026-05-19 09:28:52 +03:00
..
2025-12-18 09:51:09 +03:00