Merge pull request #26023 from WanliZhong:vfunc_hfloat

Fix hfloat, float16_t, float collision in 5.x about v_exp and v_log #26023

This PR try to fix https://github.com/opencv/opencv/issues/25922
Because the `hfloat` is defined as explicit conversion, the test code should be modified as it. The `vx_setall_f16` problem has already been fixed.

### 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
- [ ] 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
This commit is contained in:
Wanli 2024-09-02 18:37:57 +09:00 committed by GitHub
parent 0f8bbf4677
commit a735660cc3
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

View File

@ -1881,18 +1881,18 @@ template<typename R> struct TheTest
// Test overflow and underflow values with step
const LaneType step = (LaneType) 0.01;
for (LaneType i = dataMax + 1; i <= dataMax + 11;) {
for (LaneType i = (LaneType) (dataMax + 1); i <= dataMax + 11;) {
Data<R> dataUpperBound, dataLowerBound, resOverflow, resUnderflow;
for (int j = 0; j < n; ++j) {
dataUpperBound[j] = i;
dataLowerBound[j] = -i;
i += step;
dataUpperBound[j] = (LaneType) i;
dataLowerBound[j] = (LaneType) -i;
i = (LaneType) (i + step);
}
R upperBound = dataUpperBound, lowerBound = dataLowerBound;
resOverflow = v_exp(upperBound);
resUnderflow = v_exp(lowerBound);
for (int j = 0; j < n; ++j) {
SCOPED_TRACE(cv::format("Overflow/Underflow test value: %f", i));
SCOPED_TRACE(cv::format("Overflow/Underflow test value: %lf", (double) i));
EXPECT_TRUE(resOverflow[j] > 0 && std::isinf(resOverflow[j]));
EXPECT_GE(resUnderflow[j], 0);
EXPECT_LT(resUnderflow[j], flt_min);
@ -1900,7 +1900,7 @@ template<typename R> struct TheTest
}
// Test random values combined with special values
std::vector<LaneType> specialValues = {0, 1, INFINITY, -INFINITY, NAN, dataMax};
std::vector<LaneType> specialValues = {(LaneType) 0, (LaneType) 1, (LaneType) INFINITY, (LaneType) -INFINITY, (LaneType) NAN, (LaneType) dataMax};
const int testRandNum = 10000;
const double specialValueProbability = 0.1; // 10% chance to insert a special value
cv::RNG_MT19937 rng;
@ -1921,8 +1921,8 @@ template<typename R> struct TheTest
R x = dataRand;
resRand = v_exp(x);
for (int j = 0; j < n; ++j) {
SCOPED_TRACE(cv::format("Random test value: %f", dataRand[j]));
LaneType std_exp = std::exp(dataRand[j]);
SCOPED_TRACE(cv::format("Random test value: %lf", (double) dataRand[j]));
LaneType std_exp = (LaneType) std::exp(dataRand[j]);
if (dataRand[j] == 0) {
// input 0 -> output 1
EXPECT_EQ(resRand[j], 1);
@ -1953,12 +1953,11 @@ template<typename R> struct TheTest
}
TheTest &test_exp_fp16() {
// issue after 4.x merge: float16_t and hfloat conflict: https://github.com/opencv/opencv/issues/25922
#if CV_SIMD_FP16 & 0
float16_t flt16_min;
#if CV_SIMD_FP16
hfloat flt16_min;
uint16_t flt16_min_hex = 0x0400;
std::memcpy(&flt16_min, &flt16_min_hex, sizeof(float16_t));
__test_exp((float16_t) 10, (float16_t) 1e-2, (float16_t) 1e2, flt16_min);
std::memcpy(&flt16_min, &flt16_min_hex, sizeof(hfloat));
__test_exp((hfloat) 10, (hfloat) 1e-2, (hfloat) 1e2, flt16_min);
#endif
return *this;
}
@ -1978,7 +1977,7 @@ template<typename R> struct TheTest
void __test_log(LaneType expBound, LaneType diff_thr, LaneType flt_min) {
int n = VTraits<R>::vlanes();
// Test special values
std::vector<LaneType> specialValues = {0, 1, (LaneType) M_E, INFINITY, -INFINITY, NAN};
std::vector<LaneType> specialValues = {(LaneType) 0, (LaneType) 1, (LaneType) M_E, (LaneType) INFINITY, (LaneType) -INFINITY, (LaneType) NAN};
const int testRandNum = 10000;
const double specialValueProbability = 0.1; // 10% chance to insert a special value
cv::RNG_MT19937 rng;
@ -2000,8 +1999,8 @@ template<typename R> struct TheTest
R x = dataRand;
resRand = v_log(x);
for (int j = 0; j < n; ++j) {
SCOPED_TRACE(cv::format("Random test value: %f", dataRand[j]));
LaneType std_log = std::log(dataRand[j]);
SCOPED_TRACE(cv::format("Random test value: %lf", (double) dataRand[j]));
LaneType std_log = (LaneType) std::log(dataRand[j]);
if (dataRand[j] == 0) {
// input 0 -> output -INF
EXPECT_TRUE(std::isinf(resRand[j]) && resRand[j] < 0);
@ -2023,12 +2022,11 @@ template<typename R> struct TheTest
}
TheTest &test_log_fp16() {
// issue after 4.x merge: float16_t and hfloat conflict: https://github.com/opencv/opencv/issues/25922
#if CV_SIMD_FP16 & 0
float16_t flt16_min;
#if CV_SIMD_FP16
hfloat flt16_min;
uint16_t flt16_min_hex = 0x0400;
std::memcpy(&flt16_min, &flt16_min_hex, sizeof(float16_t));
__test_log((float16_t) 9, (float16_t) 1e-3, flt16_min);
std::memcpy(&flt16_min, &flt16_min_hex, sizeof(hfloat));
__test_log((hfloat) 9, (hfloat) 1e-3, flt16_min);
#endif
return *this;
}
@ -2068,7 +2066,7 @@ template<typename R> struct TheTest
Data<R> outputs = v_erf(R(inputs));
for (int j = 0; j < n; j++) {
SCOPED_TRACE(cv::format("Random test value: %f", inputs[j]));
SCOPED_TRACE(cv::format("Random test value: %lf", inputs[j]));
if (std::isinf(inputs[j])) {
if (inputs[j] < 0) {
EXPECT_EQ(-1, outputs[j]);