From ffd010767fe401f87a747c0e7f935ddb7da4c63b Mon Sep 17 00:00:00 2001 From: Vincent Rabaud Date: Thu, 4 Nov 2021 22:48:10 +0100 Subject: [PATCH] Only use fma functions when CV_FMA3 is set. In practice, processors offering AVX2/AVX512 also FMA, that is why it got unnoticed. --- .../core/include/opencv2/core/hal/intrin_avx.hpp | 14 +++++++++++++- .../include/opencv2/core/hal/intrin_avx512.hpp | 14 +++++++++++++- 2 files changed, 26 insertions(+), 2 deletions(-) diff --git a/modules/core/include/opencv2/core/hal/intrin_avx.hpp b/modules/core/include/opencv2/core/hal/intrin_avx.hpp index 54e8927192..7fbf6f1314 100644 --- a/modules/core/include/opencv2/core/hal/intrin_avx.hpp +++ b/modules/core/include/opencv2/core/hal/intrin_avx.hpp @@ -1390,11 +1390,21 @@ OPENCV_HAL_IMPL_AVX_CHECK_SHORT(v_int16x16) ////////// Other math ///////// /** Some frequent operations **/ +#if CV_FMA3 #define OPENCV_HAL_IMPL_AVX_MULADD(_Tpvec, suffix) \ inline _Tpvec v_fma(const _Tpvec& a, const _Tpvec& b, const _Tpvec& c) \ { return _Tpvec(_mm256_fmadd_##suffix(a.val, b.val, c.val)); } \ inline _Tpvec v_muladd(const _Tpvec& a, const _Tpvec& b, const _Tpvec& c) \ - { return _Tpvec(_mm256_fmadd_##suffix(a.val, b.val, c.val)); } \ + { return _Tpvec(_mm256_fmadd_##suffix(a.val, b.val, c.val)); } +#else +#define OPENCV_HAL_IMPL_AVX_MULADD(_Tpvec, suffix) \ + inline _Tpvec v_fma(const _Tpvec& a, const _Tpvec& b, const _Tpvec& c) \ + { return _Tpvec(_mm256_add_##suffix(_mm256_mul_##suffix(a.val, b.val), c.val)); } \ + inline _Tpvec v_muladd(const _Tpvec& a, const _Tpvec& b, const _Tpvec& c) \ + { return _Tpvec(_mm256_add_##suffix(_mm256_mul_##suffix(a.val, b.val), c.val)); } +#endif + +#define OPENCV_HAL_IMPL_AVX_MISC(_Tpvec, suffix) \ inline _Tpvec v_sqrt(const _Tpvec& x) \ { return _Tpvec(_mm256_sqrt_##suffix(x.val)); } \ inline _Tpvec v_sqr_magnitude(const _Tpvec& a, const _Tpvec& b) \ @@ -1404,6 +1414,8 @@ OPENCV_HAL_IMPL_AVX_CHECK_SHORT(v_int16x16) OPENCV_HAL_IMPL_AVX_MULADD(v_float32x8, ps) OPENCV_HAL_IMPL_AVX_MULADD(v_float64x4, pd) +OPENCV_HAL_IMPL_AVX_MISC(v_float32x8, ps) +OPENCV_HAL_IMPL_AVX_MISC(v_float64x4, pd) inline v_int32x8 v_fma(const v_int32x8& a, const v_int32x8& b, const v_int32x8& c) { diff --git a/modules/core/include/opencv2/core/hal/intrin_avx512.hpp b/modules/core/include/opencv2/core/hal/intrin_avx512.hpp index 75a3bd4b85..d20d6dd1ff 100644 --- a/modules/core/include/opencv2/core/hal/intrin_avx512.hpp +++ b/modules/core/include/opencv2/core/hal/intrin_avx512.hpp @@ -1385,11 +1385,21 @@ inline v_uint64x8 v_popcount(const v_uint64x8& a) { return v_popcount(v_reinte ////////// Other math ///////// /** Some frequent operations **/ +#if CV_FMA3 #define OPENCV_HAL_IMPL_AVX512_MULADD(_Tpvec, suffix) \ inline _Tpvec v_fma(const _Tpvec& a, const _Tpvec& b, const _Tpvec& c) \ { return _Tpvec(_mm512_fmadd_##suffix(a.val, b.val, c.val)); } \ inline _Tpvec v_muladd(const _Tpvec& a, const _Tpvec& b, const _Tpvec& c) \ - { return _Tpvec(_mm512_fmadd_##suffix(a.val, b.val, c.val)); } \ + { return _Tpvec(_mm512_fmadd_##suffix(a.val, b.val, c.val)); } +#else +#define OPENCV_HAL_IMPL_AVX512_MULADD(_Tpvec, suffix) \ + inline _Tpvec v_fma(const _Tpvec& a, const _Tpvec& b, const _Tpvec& c) \ + { return _Tpvec(_mm512_add_##suffix(_mm512_mul_##suffix(a.val, b.val), c.val)); } \ + inline _Tpvec v_muladd(const _Tpvec& a, const _Tpvec& b, const _Tpvec& c) \ + { return _Tpvec(_mm512_add_##suffix(_mm512_mul_##suffix(a.val, b.val), c.val)); } +#endif + +#define OPENCV_HAL_IMPL_AVX512_MISC(_Tpvec, suffix) \ inline _Tpvec v_sqrt(const _Tpvec& x) \ { return _Tpvec(_mm512_sqrt_##suffix(x.val)); } \ inline _Tpvec v_sqr_magnitude(const _Tpvec& a, const _Tpvec& b) \ @@ -1399,6 +1409,8 @@ inline v_uint64x8 v_popcount(const v_uint64x8& a) { return v_popcount(v_reinte OPENCV_HAL_IMPL_AVX512_MULADD(v_float32x16, ps) OPENCV_HAL_IMPL_AVX512_MULADD(v_float64x8, pd) +OPENCV_HAL_IMPL_AVX512_MISC(v_float32x16, ps) +OPENCV_HAL_IMPL_AVX512_MISC(v_float64x8, pd) inline v_int32x16 v_fma(const v_int32x16& a, const v_int32x16& b, const v_int32x16& c) { return a * b + c; } -- GitLab