mirror of
https://github.com/opencv/opencv.git
synced 2026-07-21 19:33:03 +04:00
Merge pull request #28375 from arniechangsifive:dev/arniec/fix-fails-on-tail-agnostic-as-1s
hal/riscv-rvv: Fix test failures on hardware that implements tail-agnostic as all 1s #28375 ### 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 ### Summary Fix test failures in `opencv_test_core` and `opencv_test_imgproc` on hardware that implements the tail-agnostic policy by overwriting tail elements with all 1s ### Root Cause According to the [RISC-V Vector Extension Specification v1.0](https://github.com/riscvarchive/riscv-v-spec/blob/master/v-spec.adoc#343-vector-tail-agnostic-and-vector-mask-agnostic-vta-and-vma): > "When a set is marked agnostic, the corresponding set of destination elements in any vector destination operand can either retain the value they previously held, or are overwritten with 1s." Both `dotProd_32f` and `dotProd_32s` functions use accumulator variables(`s`) that persist across loop iterations, but were using vector intrinsics with tail-agnostic policy. The tail elements can be overwritten with 1s, corrupting the accumulator and producing NaN during the final reduction sum. ### Solution Changed both functions to use `tail-undisturbed`(`tu`) policy to ensure tail elements remain unchanged across loop iterations. ### Reproduce Steps The failures can be reproduced using [QEMU](https://gitlab.com/qemu-project/qemu) with `rvv_ma_all_1s=true` and `rvv_ta_all_1s=true` options to emulate hardware implementing tail-agnostic policy as all 1s. #### Reproduce **`opencv_test_core`** failures: ``` qemu-riscv64 -cpu rv64,zba=true,zbb=true,zbc=true,zbs=true,v=true,vlen=512,elen=64,vext_spec=v1.0,rvv_ma_all_1s=true,rvv_ta_all_1s=true -L '/PATH_TO_SYSROOT/sysroot/' ./opencv_test_core --gtest_filter="Core_DotProduct*" ``` Before the patch: ``` [ FAILED ] Core_DotProduct.accuracy (24 ms) ``` After the patch: ``` [ PASSED ] 1 test. ``` #### Reproduce **`opencv_test_imgproc`** failures: ``` qemu-riscv64 -cpu rv64,zba=true,zbb=true,zbc=true,zbs=true,v=true,vlen=512,elen=64,vext_spec=v1.0,rvv_ma_all_1s=true,rvv_ta_all_1s=true -L '/workspace/riscv/sysroot/' ./opencv_test_imgproc --gtest_filter="fitLine_Modes.accuracy/*" ``` Before the patch ``` [ FAILED ] 24 tests, listed below: [ FAILED ] fitLine_Modes.accuracy/0, where GetParam() = (13, 1) [ FAILED ] fitLine_Modes.accuracy/1, where GetParam() = (13, 2) [ FAILED ] fitLine_Modes.accuracy/2, where GetParam() = (13, 4) [ FAILED ] fitLine_Modes.accuracy/3, where GetParam() = (13, 5) [ FAILED ] fitLine_Modes.accuracy/4, where GetParam() = (13, 6) [ FAILED ] fitLine_Modes.accuracy/5, where GetParam() = (13, 7) [ FAILED ] fitLine_Modes.accuracy/6, where GetParam() = (21, 1) [ FAILED ] fitLine_Modes.accuracy/7, where GetParam() = (21, 2) [ FAILED ] fitLine_Modes.accuracy/8, where GetParam() = (21, 4) [ FAILED ] fitLine_Modes.accuracy/9, where GetParam() = (21, 5) [ FAILED ] fitLine_Modes.accuracy/10, where GetParam() = (21, 6) [ FAILED ] fitLine_Modes.accuracy/11, where GetParam() = (21, 7) [ FAILED ] fitLine_Modes.accuracy/12, where GetParam() = (12, 1) [ FAILED ] fitLine_Modes.accuracy/13, where GetParam() = (12, 2) [ FAILED ] fitLine_Modes.accuracy/14, where GetParam() = (12, 4) [ FAILED ] fitLine_Modes.accuracy/15, where GetParam() = (12, 5) [ FAILED ] fitLine_Modes.accuracy/16, where GetParam() = (12, 6) [ FAILED ] fitLine_Modes.accuracy/17, where GetParam() = (12, 7) [ FAILED ] fitLine_Modes.accuracy/18, where GetParam() = (20, 1) [ FAILED ] fitLine_Modes.accuracy/19, where GetParam() = (20, 2) [ FAILED ] fitLine_Modes.accuracy/20, where GetParam() = (20, 4) [ FAILED ] fitLine_Modes.accuracy/21, where GetParam() = (20, 5) [ FAILED ] fitLine_Modes.accuracy/22, where GetParam() = (20, 6) [ FAILED ] fitLine_Modes.accuracy/23, where GetParam() = (20, 7) ``` After the patch `[ PASSED ] 24 tests.`
This commit is contained in:
@@ -137,7 +137,7 @@ static inline double dotProd_32s(const int *a, const int *b, int len) {
|
||||
auto va = __riscv_vle32_v_i32m4(a + j, vl);
|
||||
auto vb = __riscv_vle32_v_i32m4(b + j, vl);
|
||||
|
||||
s = __riscv_vfadd(s, __riscv_vfcvt_f(__riscv_vwmul(va, vb, vl), vl), vl);
|
||||
s = __riscv_vfadd_vv_f64m8_tu(s, s, __riscv_vfcvt_f(__riscv_vwmul(va, vb, vl), vl), vl);
|
||||
}
|
||||
r = __riscv_vfmv_f(__riscv_vfredosum(s, __riscv_vfmv_v_f_f64m1(0.f, __riscv_vsetvlmax_e64m1()), __riscv_vsetvlmax_e64m8()));
|
||||
|
||||
@@ -160,7 +160,7 @@ static inline double dotProd_32f(const float *a, const float *b, int len) {
|
||||
auto va = __riscv_vle32_v_f32m4(a + j, vl);
|
||||
auto vb = __riscv_vle32_v_f32m4(b + j, vl);
|
||||
|
||||
s = __riscv_vfmacc(s, va, vb, vl);
|
||||
s = __riscv_vfmacc_vv_f32m4_tu(s, va, vb, vl);
|
||||
}
|
||||
r += (double)__riscv_vfmv_f(__riscv_vfredusum(s, __riscv_vfmv_v_f_f32m1(0.f, __riscv_vsetvlmax_e32m1()), __riscv_vsetvlmax_e32m4()));
|
||||
|
||||
|
||||
Reference in New Issue
Block a user