1
0
mirror of https://github.com/opencv/opencv.git synced 2026-07-29 23:33:05 +04:00

Merge remote-tracking branch 'origin/3.4' into merge-3.4

This commit is contained in:
Alexander Smorkalov
2023-04-20 16:44:22 +03:00
26 changed files with 336 additions and 227 deletions
@@ -880,14 +880,10 @@ OPENCV_HAL_IMPL_CMP_OP(<=)
For all types except 64-bit integer values. */
OPENCV_HAL_IMPL_CMP_OP(>=)
/** @brief Equal comparison
For all types except 64-bit integer values. */
/** @brief Equal comparison */
OPENCV_HAL_IMPL_CMP_OP(==)
/** @brief Not equal comparison
For all types except 64-bit integer values. */
/** @brief Not equal comparison */
OPENCV_HAL_IMPL_CMP_OP(!=)
template<int n>
@@ -1036,18 +1036,6 @@ OPENCV_HAL_IMPL_NEON_BIN_FUNC(v_float64x2, v_min, vminq_f64)
OPENCV_HAL_IMPL_NEON_BIN_FUNC(v_float64x2, v_max, vmaxq_f64)
#endif
#if CV_SIMD128_64F
inline int64x2_t vmvnq_s64(int64x2_t a)
{
int64x2_t vx = vreinterpretq_s64_u32(vdupq_n_u32(0xFFFFFFFF));
return veorq_s64(a, vx);
}
inline uint64x2_t vmvnq_u64(uint64x2_t a)
{
uint64x2_t vx = vreinterpretq_u64_u32(vdupq_n_u32(0xFFFFFFFF));
return veorq_u64(a, vx);
}
#endif
#define OPENCV_HAL_IMPL_NEON_INT_CMP_OP(_Tpvec, cast, suffix, not_suffix) \
inline _Tpvec operator == (const _Tpvec& a, const _Tpvec& b) \
{ return _Tpvec(cast(vceqq_##suffix(a.val, b.val))); } \
@@ -1069,9 +1057,47 @@ OPENCV_HAL_IMPL_NEON_INT_CMP_OP(v_int16x8, vreinterpretq_s16_u16, s16, u16)
OPENCV_HAL_IMPL_NEON_INT_CMP_OP(v_uint32x4, OPENCV_HAL_NOP, u32, u32)
OPENCV_HAL_IMPL_NEON_INT_CMP_OP(v_int32x4, vreinterpretq_s32_u32, s32, u32)
OPENCV_HAL_IMPL_NEON_INT_CMP_OP(v_float32x4, vreinterpretq_f32_u32, f32, u32)
#if defined(__aarch64__) || defined(_M_ARM64)
static inline uint64x2_t vmvnq_u64(uint64x2_t a)
{
uint64x2_t vx = vreinterpretq_u64_u32(vdupq_n_u32(0xFFFFFFFF));
return veorq_u64(a, vx);
}
//OPENCV_HAL_IMPL_NEON_INT_CMP_OP(v_uint64x2, OPENCV_HAL_NOP, u64, u64)
//OPENCV_HAL_IMPL_NEON_INT_CMP_OP(v_int64x2, vreinterpretq_s64_u64, s64, u64)
static inline v_uint64x2 operator == (const v_uint64x2& a, const v_uint64x2& b)
{ return v_uint64x2(vceqq_u64(a.val, b.val)); }
static inline v_uint64x2 operator != (const v_uint64x2& a, const v_uint64x2& b)
{ return v_uint64x2(vmvnq_u64(vceqq_u64(a.val, b.val))); }
static inline v_int64x2 operator == (const v_int64x2& a, const v_int64x2& b)
{ return v_int64x2(vreinterpretq_s64_u64(vceqq_s64(a.val, b.val))); }
static inline v_int64x2 operator != (const v_int64x2& a, const v_int64x2& b)
{ return v_int64x2(vreinterpretq_s64_u64(vmvnq_u64(vceqq_s64(a.val, b.val)))); }
#else
static inline v_uint64x2 operator == (const v_uint64x2& a, const v_uint64x2& b)
{
uint32x4_t cmp = vceqq_u32(vreinterpretq_u32_u64(a.val), vreinterpretq_u32_u64(b.val));
uint32x4_t swapped = vrev64q_u32(cmp);
return v_uint64x2(vreinterpretq_u64_u32(vandq_u32(cmp, swapped)));
}
static inline v_uint64x2 operator != (const v_uint64x2& a, const v_uint64x2& b)
{
uint32x4_t cmp = vceqq_u32(vreinterpretq_u32_u64(a.val), vreinterpretq_u32_u64(b.val));
uint32x4_t swapped = vrev64q_u32(cmp);
uint64x2_t v_eq = vreinterpretq_u64_u32(vandq_u32(cmp, swapped));
uint64x2_t vx = vreinterpretq_u64_u32(vdupq_n_u32(0xFFFFFFFF));
return v_uint64x2(veorq_u64(v_eq, vx));
}
static inline v_int64x2 operator == (const v_int64x2& a, const v_int64x2& b)
{
return v_reinterpret_as_s64(v_reinterpret_as_u64(a) == v_reinterpret_as_u64(b));
}
static inline v_int64x2 operator != (const v_int64x2& a, const v_int64x2& b)
{
return v_reinterpret_as_s64(v_reinterpret_as_u64(a) != v_reinterpret_as_u64(b));
}
#endif
#if CV_SIMD128_64F
OPENCV_HAL_IMPL_NEON_INT_CMP_OP(v_uint64x2, OPENCV_HAL_NOP, u64, u64)
OPENCV_HAL_IMPL_NEON_INT_CMP_OP(v_int64x2, vreinterpretq_s64_u64, s64, u64)
OPENCV_HAL_IMPL_NEON_INT_CMP_OP(v_float64x2, vreinterpretq_f64_u64, f64, u64)
#endif
@@ -62,10 +62,6 @@ static bool ipp_countNonZero( Mat &src, int &res )
{
CV_INSTRUMENT_REGION_IPP();
// see https://github.com/opencv/opencv/issues/17453
if (src.dims <= 2 && src.step > 520000 && cv::ipp::getIppTopFeatures() == ippCPUID_SSE42)
return false;
#if IPP_VERSION_X100 < 201801
// Poor performance of SSE42
if(cv::ipp::getIppTopFeatures() == ippCPUID_SSE42)
+2 -2
View File
@@ -531,7 +531,7 @@ inline int hal_ni_dftFree1D(cvhalDFT *context) { return CV_HAL_ERROR_NOT_IMPLEME
/**
@param context double pointer to context storing all necessary data
@param width,height image dimensions
@param depth image type (CV_32F or CV64F)
@param depth image type (CV_32F or CV_64F)
@param src_channels number of channels in input image
@param dst_channels number of channels in output image
@param flags algorithm options (combination of CV_HAL_DFT_INVERSE, ...)
@@ -558,7 +558,7 @@ inline int hal_ni_dftFree2D(cvhalDFT *context) { return CV_HAL_ERROR_NOT_IMPLEME
/**
@param context double pointer to context storing all necessary data
@param width,height image dimensions
@param depth image type (CV_32F or CV64F)
@param depth image type (CV_32F or CV_64F)
@param flags algorithm options (combination of CV_HAL_DFT_INVERSE, ...)
*/
inline int hal_ni_dctInit2D(cvhalDFT **context, int width, int height, int depth, int flags) { return CV_HAL_ERROR_NOT_IMPLEMENTED; }
+1 -22
View File
@@ -7,10 +7,6 @@
#include "mathfuncs_core.simd.hpp"
#include "mathfuncs_core.simd_declarations.hpp" // defines CV_CPU_DISPATCH_MODES_ALL=AVX2,...,BASELINE based on CMakeLists.txt content
#define IPP_DISABLE_MAGNITUDE_32F 1 // accuracy: https://github.com/opencv/opencv/issues/19506
namespace cv { namespace hal {
///////////////////////////////////// ATAN2 ////////////////////////////////////
@@ -48,25 +44,8 @@ void magnitude32f(const float* x, const float* y, float* mag, int len)
CV_INSTRUMENT_REGION();
CALL_HAL(magnitude32f, cv_hal_magnitude32f, x, y, mag, len);
#ifdef HAVE_IPP
bool allowIPP = true;
#ifdef IPP_DISABLE_MAGNITUDE_32F
if (cv::ipp::getIppTopFeatures() & (
#if IPP_VERSION_X100 >= 201700
ippCPUID_AVX512F |
#endif
ippCPUID_AVX2)
)
{
allowIPP = (len & 7) == 0;
}
#endif
// SSE42 performance issues
CV_IPP_RUN((IPP_VERSION_X100 > 201800 || cv::ipp::getIppTopFeatures() != ippCPUID_SSE42) && allowIPP,
CV_INSTRUMENT_FUN_IPP(ippsMagnitude_32f, x, y, mag, len) >= 0);
#endif
CV_IPP_RUN(IPP_VERSION_X100 > 201800 || cv::ipp::getIppTopFeatures() != ippCPUID_SSE42, CV_INSTRUMENT_FUN_IPP(ippsMagnitude_32f, x, y, mag, len) >= 0);
CV_CPU_DISPATCH(magnitude32f, (x, y, mag, len),
CV_CPU_DISPATCH_MODES_ALL);
-10
View File
@@ -995,16 +995,6 @@ static bool ipp_norm(InputArray _src1, InputArray _src2, int normType, InputArra
type == CV_16UC3 ? (ippiMaskNormDiffFuncC3)ippiNormDiff_L2_16u_C3CMR :
type == CV_32FC3 ? (ippiMaskNormDiffFuncC3)ippiNormDiff_L2_32f_C3CMR :
0) : 0;
if (cv::ipp::getIppTopFeatures() & (
#if IPP_VERSION_X100 >= 201700
ippCPUID_AVX512F |
#endif
ippCPUID_AVX2)
) // IPP_DISABLE_NORM_16UC3_mask_small (#11399)
{
if (normType == NORM_L1 && type == CV_16UC3 && sz.width < 16)
return false;
}
if( ippiNormDiff_C3CMR )
{
Ipp64f norm1, norm2, norm3;
+49 -34
View File
@@ -166,7 +166,7 @@ template <typename R> struct Data
{
*this = r;
}
operator R ()
operator R () const
{
return initializer<VTraits<R>::max_nlanes>().init(*this);
}
@@ -1736,11 +1736,39 @@ template<typename R> struct TheTest
}
#endif
#if CV_SIMD_64F
void do_check_cmp64(const Data<R>& dataA, const Data<R>& dataB)
{
R a = dataA;
R b = dataB;
#if CV_SIMD_SCALABLE
Data<R> dataEQ = v_eq(a, b);
Data<R> dataNE = v_ne(a, b);
#else
Data<R> dataEQ = (a == b);
Data<R> dataNE = (a != b);
#endif
for (int i = 0; i < VTraits<R>::vlanes(); ++i)
{
SCOPED_TRACE(cv::format("i=%d", i));
if (cvtest::debugLevel > 0) cout << "i=" << i << " ( " << dataA[i] << " vs " << dataB[i] << " ): eq=" << dataEQ[i] << " ne=" << dataNE[i] << endl;
EXPECT_NE((LaneType)dataEQ[i], (LaneType)dataNE[i]);
if (dataA[i] == dataB[i])
EXPECT_EQ((LaneType)-1, (LaneType)dataEQ[i]);
else
EXPECT_EQ((LaneType)0, (LaneType)dataEQ[i]);
if (dataA[i] != dataB[i])
EXPECT_EQ((LaneType)-1, (LaneType)dataNE[i]);
else
EXPECT_EQ((LaneType)0, (LaneType)dataNE[i]);
}
}
TheTest & test_cmp64()
{
Data<R> dataA, dataB;
R a = dataA, b = dataB;
Data<R> dataA;
Data<R> dataB;
for (int i = 0; i < VTraits<R>::vlanes(); ++i)
{
@@ -1748,37 +1776,25 @@ template<typename R> struct TheTest
}
dataA[0]++;
a = dataA, b = dataB;
do_check_cmp64(dataA, dataB);
do_check_cmp64(dataB, dataA);
Data<R> resC = (a == b);
Data<R> resD = (a != b);
dataA[0] = dataB[0];
dataA[1] += (((LaneType)1) << 32);
do_check_cmp64(dataA, dataB);
do_check_cmp64(dataB, dataA);
for (int i = 0; i < VTraits<R>::vlanes(); ++i)
{
SCOPED_TRACE(cv::format("i=%d", i));
EXPECT_EQ(dataA[i] == dataB[i], resC[i] != 0);
EXPECT_EQ(dataA[i] != dataB[i], resD[i] != 0);
}
dataA[0] = (LaneType)-1;
dataB[0] = (LaneType)-1;
dataA[1] = (LaneType)-1;
dataB[1] = (LaneType)2;
for (int i = 0; i < VTraits<R>::vlanes(); ++i)
{
dataA[i] = dataB[i] = (LaneType)-1;
}
do_check_cmp64(dataA, dataB);
do_check_cmp64(dataB, dataA);
a = dataA, b = dataB;
resC = (a == b);
resD = (a != b);
for (int i = 0; i < VTraits<R>::vlanes(); ++i)
{
SCOPED_TRACE(cv::format("i=%d", i));
EXPECT_EQ(dataA[i] == dataB[i], resC[i] != 0);
EXPECT_EQ(dataA[i] != dataB[i], resD[i] != 0);
}
return *this;
}
#endif
};
#define DUMP_ENTRY(type) printf("SIMD%d: %s\n", 8*VTraits<v_uint8>::vlanes(), CV__TRACE_FUNCTION);
@@ -2023,9 +2039,8 @@ void test_hal_intrin_uint64()
TheTest<v_uint64>()
.test_loadstore()
.test_addsub()
#if CV_SIMD_64F
.test_cmp64()
#endif
//.test_cmp() - not declared as supported
.test_shift<1>().test_shift<8>()
.test_logic()
.test_reverse()
@@ -2043,9 +2058,8 @@ void test_hal_intrin_int64()
TheTest<v_int64>()
.test_loadstore()
.test_addsub()
#if CV_SIMD_64F
.test_cmp64()
#endif
//.test_cmp() - not declared as supported
.test_shift<1>().test_shift<8>()
.test_logic()
.test_reverse()
@@ -2128,7 +2142,8 @@ void test_hal_intrin_float64()
.test_rotate<2>().test_rotate<3>()
#endif
;
#else
std::cout << "SKIP: CV_SIMD_64F is not available" << std::endl;
#endif
}