mirror of
https://github.com/opencv/opencv.git
synced 2026-07-29 23:33:05 +04:00
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`.
This commit is contained in:
@@ -2770,6 +2770,14 @@ TEST(Core_Norm, NORM_L2_8UC4)
|
||||
EXPECT_EQ(kNorm, cv::norm(a, b, NORM_L2));
|
||||
}
|
||||
|
||||
TEST(Core_Norm, NORM_L2SQR_16SC4_large)
|
||||
{
|
||||
const int sizes[] = {1, 116, 40};
|
||||
Mat src(3, sizes, CV_16SC4, Scalar::all(16384));
|
||||
const double expected = static_cast<double>(src.total()) * src.channels() * 16384.0 * 16384.0;
|
||||
EXPECT_EQ(expected, cv::norm(src, NORM_L2SQR));
|
||||
}
|
||||
|
||||
TEST(Core_ConvertTo, regression_12121)
|
||||
{
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user