1
0
mirror of https://github.com/opencv/opencv.git synced 2026-07-31 08:13:04 +04:00

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

This commit is contained in:
Alexander Alekhin
2018-07-31 21:35:00 +03:00
71 changed files with 2658 additions and 1392 deletions
+3 -7
View File
@@ -2008,11 +2008,9 @@ TEST(Subtract, scalarc4_matc4)
TEST(Compare, empty)
{
cv::Mat temp, dst1, dst2;
cv::compare(temp, temp, dst1, cv::CMP_EQ);
dst2 = temp > 5;
EXPECT_NO_THROW(cv::compare(temp, temp, dst1, cv::CMP_EQ));
EXPECT_TRUE(dst1.empty());
EXPECT_TRUE(dst2.empty());
EXPECT_THROW(dst2 = temp > 5, cv::Exception);
}
TEST(Compare, regression_8999)
@@ -2020,9 +2018,7 @@ TEST(Compare, regression_8999)
Mat_<double> A(4,1); A << 1, 3, 2, 4;
Mat_<double> B(1,1); B << 2;
Mat C;
ASSERT_ANY_THROW({
cv::compare(A, B, C, CMP_LT);
});
EXPECT_THROW(cv::compare(A, B, C, CMP_LT), cv::Exception);
}
+23 -94
View File
@@ -43,106 +43,35 @@
namespace opencv_test { namespace {
class Core_ConcatenationTest : public cvtest::BaseTest
TEST(Core_Concatenation, empty)
{
public:
Core_ConcatenationTest(bool horizontal, bool firstEmpty, bool secondEmpty);
protected:
int prepare_test_case( int );
void run_func();
int validate_test_results( int );
const Mat mat0x5(0,5, CV_8U, Scalar::all(1));
const Mat mat10x5(10,5, CV_8U, Scalar::all(1));
const Mat mat20x5(20,5, CV_8U, Scalar::all(1));
Mat mat0x5;
Mat mat10x5;
Mat mat20x5;
Mat mat5x0;
Mat mat5x10;
Mat mat5x20;
const Mat mat5x0(5,0, CV_8U, Scalar::all(1));
const Mat mat5x10(5,10, CV_8U, Scalar::all(1));
const Mat mat5x20(5,20, CV_8U, Scalar::all(1));
Mat result;
bool horizontal;
bool firstEmpty;
bool secondEmpty;
cv::hconcat(mat5x0, mat5x0, result);
EXPECT_MAT_N_DIFF(result, mat5x0, 0);
cv::hconcat(mat5x0, mat5x10, result);
EXPECT_MAT_N_DIFF(result, mat5x10, 0);
cv::hconcat(mat5x10, mat5x0, result);
EXPECT_MAT_N_DIFF(result, mat5x10, 0);
cv::hconcat(mat5x10, mat5x10, result);
EXPECT_MAT_N_DIFF(result, mat5x20, 0);
private:
static bool areEqual(const Mat& m1, const Mat& m2);
};
Core_ConcatenationTest::Core_ConcatenationTest(bool horizontal_, bool firstEmpty_, bool secondEmpty_)
: horizontal(horizontal_)
, firstEmpty(firstEmpty_)
, secondEmpty(secondEmpty_)
{
test_case_count = 1;
mat0x5 = Mat::ones(0,5, CV_8U);
mat10x5 = Mat::ones(10,5, CV_8U);
mat20x5 = Mat::ones(20,5, CV_8U);
mat5x0 = Mat::ones(5,0, CV_8U);
mat5x10 = Mat::ones(5,10, CV_8U);
mat5x20 = Mat::ones(5,20, CV_8U);
cv::vconcat(mat0x5, mat0x5, result);
EXPECT_MAT_N_DIFF(result, mat0x5, 0);
cv::vconcat(mat0x5, mat10x5, result);
EXPECT_MAT_N_DIFF(result, mat10x5, 0);
cv::vconcat(mat10x5, mat0x5, result);
EXPECT_MAT_N_DIFF(result, mat10x5, 0);
cv::vconcat(mat10x5, mat10x5, result);
EXPECT_MAT_N_DIFF(result, mat20x5, 0);
}
int Core_ConcatenationTest::prepare_test_case( int test_case_idx )
{
cvtest::BaseTest::prepare_test_case( test_case_idx );
return 1;
}
void Core_ConcatenationTest::run_func()
{
if (horizontal)
{
cv::hconcat((firstEmpty ? mat5x0 : mat5x10),
(secondEmpty ? mat5x0 : mat5x10),
result);
} else {
cv::vconcat((firstEmpty ? mat0x5 : mat10x5),
(secondEmpty ? mat0x5 : mat10x5),
result);
}
}
int Core_ConcatenationTest::validate_test_results( int )
{
Mat expected;
if (firstEmpty && secondEmpty)
expected = (horizontal ? mat5x0 : mat0x5);
else if ((firstEmpty && !secondEmpty) || (!firstEmpty && secondEmpty))
expected = (horizontal ? mat5x10 : mat10x5);
else
expected = (horizontal ? mat5x20 : mat20x5);
if (areEqual(expected, result))
{
return cvtest::TS::OK;
} else
{
ts->printf( cvtest::TS::LOG, "Concatenation failed");
ts->set_failed_test_info( cvtest::TS::FAIL_MISMATCH );
}
return cvtest::TS::OK;
}
bool Core_ConcatenationTest::areEqual(const Mat &m1, const Mat &m2)
{
return m1.size() == m2.size()
&& m1.type() == m2.type()
&& countNonZero(m1 != m2) == 0;
}
TEST(Core_Concatenation, hconcat_empty_nonempty) { Core_ConcatenationTest test(true, true, false); test.safe_run(); }
TEST(Core_Concatenation, hconcat_nonempty_empty) { Core_ConcatenationTest test(true, false, true); test.safe_run(); }
TEST(Core_Concatenation, hconcat_empty_empty) { Core_ConcatenationTest test(true, true, true); test.safe_run(); }
TEST(Core_Concatenation, vconcat_empty_nonempty) { Core_ConcatenationTest test(false, true, false); test.safe_run(); }
TEST(Core_Concatenation, vconcat_nonempty_empty) { Core_ConcatenationTest test(false, false, true); test.safe_run(); }
TEST(Core_Concatenation, vconcat_empty_empty) { Core_ConcatenationTest test(false, true, true); test.safe_run(); }
}} // namespace
+5
View File
@@ -0,0 +1,5 @@
// This file is part of OpenCV project.
// It is subject to the license terms in the LICENSE file found in the top-level directory
// of this distribution and at http://opencv.org/license.html.
#include "test_precomp.hpp"
#include "test_intrin.simd.hpp"
+75 -223
View File
@@ -2,249 +2,101 @@
// It is subject to the license terms in the LICENSE file found in the top-level directory
// of this distribution and at http://opencv.org/license.html.
#include "test_precomp.hpp"
#include "test_intrin.simd.hpp"
#include "test_intrin_utils.hpp"
#define CV_CPU_SIMD_FILENAME "test_intrin_utils.hpp"
#define CV_CPU_SIMD_FILENAME "test_intrin.simd.hpp"
#define CV_CPU_DISPATCH_MODE FP16
#include "opencv2/core/private/cv_cpu_include_simd_declarations.hpp"
using namespace cv;
#define CV_CPU_DISPATCH_MODE AVX2
#include "opencv2/core/private/cv_cpu_include_simd_declarations.hpp"
namespace opencv_test { namespace hal {
using namespace CV_CPU_OPTIMIZATION_NAMESPACE;
//============= 8-bit integer =====================================================================
TEST(hal_intrin, uint8x16)
{ test_hal_intrin_uint8(); }
TEST(hal_intrin, uint8x16) {
TheTest<v_uint8x16>()
.test_loadstore()
.test_interleave()
.test_expand()
.test_expand_q()
.test_addsub()
.test_addsub_wrap()
.test_cmp()
.test_logic()
.test_min_max()
.test_absdiff()
.test_mask()
.test_popcount()
.test_pack<1>().test_pack<2>().test_pack<3>().test_pack<8>()
.test_pack_u<1>().test_pack_u<2>().test_pack_u<3>().test_pack_u<8>()
.test_unpack()
.test_extract<0>().test_extract<1>().test_extract<8>().test_extract<15>()
.test_rotate<0>().test_rotate<1>().test_rotate<8>().test_rotate<15>()
;
}
TEST(hal_intrin, int8x16)
{ test_hal_intrin_int8(); }
TEST(hal_intrin, int8x16) {
TheTest<v_int8x16>()
.test_loadstore()
.test_interleave()
.test_expand()
.test_expand_q()
.test_addsub()
.test_addsub_wrap()
.test_cmp()
.test_logic()
.test_min_max()
.test_absdiff()
.test_abs()
.test_mask()
.test_popcount()
.test_pack<1>().test_pack<2>().test_pack<3>().test_pack<8>()
.test_unpack()
.test_extract<0>().test_extract<1>().test_extract<8>().test_extract<15>()
.test_rotate<0>().test_rotate<1>().test_rotate<8>().test_rotate<15>()
;
}
TEST(hal_intrin, uint16x8)
{ test_hal_intrin_uint16(); }
//============= 16-bit integer =====================================================================
TEST(hal_intrin, int16x8)
{ test_hal_intrin_int16(); }
TEST(hal_intrin, uint16x8) {
TheTest<v_uint16x8>()
.test_loadstore()
.test_interleave()
.test_expand()
.test_addsub()
.test_addsub_wrap()
.test_mul()
.test_mul_expand()
.test_cmp()
.test_shift<1>()
.test_shift<8>()
.test_logic()
.test_min_max()
.test_absdiff()
.test_reduce()
.test_mask()
.test_popcount()
.test_pack<1>().test_pack<2>().test_pack<7>().test_pack<16>()
.test_pack_u<1>().test_pack_u<2>().test_pack_u<7>().test_pack_u<16>()
.test_unpack()
.test_extract<0>().test_extract<1>().test_extract<4>().test_extract<7>()
.test_rotate<0>().test_rotate<1>().test_rotate<4>().test_rotate<7>()
;
}
TEST(hal_intrin, int32x4)
{ test_hal_intrin_int32(); }
TEST(hal_intrin, int16x8) {
TheTest<v_int16x8>()
.test_loadstore()
.test_interleave()
.test_expand()
.test_addsub()
.test_addsub_wrap()
.test_mul()
.test_mul_expand()
.test_cmp()
.test_shift<1>()
.test_shift<8>()
.test_dot_prod()
.test_logic()
.test_min_max()
.test_absdiff()
.test_abs()
.test_reduce()
.test_mask()
.test_popcount()
.test_pack<1>().test_pack<2>().test_pack<7>().test_pack<16>()
.test_unpack()
.test_extract<0>().test_extract<1>().test_extract<4>().test_extract<7>()
.test_rotate<0>().test_rotate<1>().test_rotate<4>().test_rotate<7>()
;
}
TEST(hal_intrin, uint32x4)
{ test_hal_intrin_uint32(); }
//============= 32-bit integer =====================================================================
TEST(hal_intrin, uint64x2)
{ test_hal_intrin_uint64(); }
TEST(hal_intrin, uint32x4) {
TheTest<v_uint32x4>()
.test_loadstore()
.test_interleave()
.test_expand()
.test_addsub()
.test_mul()
.test_mul_expand()
.test_cmp()
.test_shift<1>()
.test_shift<8>()
.test_logic()
.test_min_max()
.test_absdiff()
.test_reduce()
.test_mask()
.test_popcount()
.test_pack<1>().test_pack<2>().test_pack<15>().test_pack<32>()
.test_unpack()
.test_extract<0>().test_extract<1>().test_extract<2>().test_extract<3>()
.test_rotate<0>().test_rotate<1>().test_rotate<2>().test_rotate<3>()
.test_transpose()
;
}
TEST(hal_intrin, int64x2)
{ test_hal_intrin_int64(); }
TEST(hal_intrin, int32x4) {
TheTest<v_int32x4>()
.test_loadstore()
.test_interleave()
.test_expand()
.test_addsub()
.test_mul()
.test_abs()
.test_cmp()
.test_popcount()
.test_shift<1>().test_shift<8>()
.test_logic()
.test_min_max()
.test_absdiff()
.test_reduce()
.test_mask()
.test_pack<1>().test_pack<2>().test_pack<15>().test_pack<32>()
.test_unpack()
.test_extract<0>().test_extract<1>().test_extract<2>().test_extract<3>()
.test_rotate<0>().test_rotate<1>().test_rotate<2>().test_rotate<3>()
.test_float_cvt32()
.test_float_cvt64()
.test_transpose()
;
}
TEST(hal_intrin, float32x4)
{ test_hal_intrin_float32(); }
//============= 64-bit integer =====================================================================
TEST(hal_intrin, float64x2)
{ test_hal_intrin_float64(); }
TEST(hal_intrin, uint64x2) {
TheTest<v_uint64x2>()
.test_loadstore()
.test_addsub()
.test_shift<1>().test_shift<8>()
.test_logic()
.test_extract<0>().test_extract<1>()
.test_rotate<0>().test_rotate<1>()
;
}
TEST(hal_intrin, int64x2) {
TheTest<v_int64x2>()
.test_loadstore()
.test_addsub()
.test_shift<1>().test_shift<8>()
.test_logic()
.test_extract<0>().test_extract<1>()
.test_rotate<0>().test_rotate<1>()
;
}
//============= Floating point =====================================================================
TEST(hal_intrin, float32x4) {
TheTest<v_float32x4>()
.test_loadstore()
.test_interleave()
.test_interleave_2channel()
.test_addsub()
.test_mul()
.test_div()
.test_cmp()
.test_sqrt_abs()
.test_min_max()
.test_float_absdiff()
.test_reduce()
.test_mask()
.test_unpack()
.test_float_math()
.test_float_cvt64()
.test_matmul()
.test_transpose()
.test_reduce_sum4()
.test_extract<0>().test_extract<1>().test_extract<2>().test_extract<3>()
.test_rotate<0>().test_rotate<1>().test_rotate<2>().test_rotate<3>()
;
}
#if CV_SIMD128_64F
TEST(hal_intrin, float64x2) {
TheTest<v_float64x2>()
.test_loadstore()
.test_addsub()
.test_mul()
.test_div()
.test_cmp()
.test_sqrt_abs()
.test_min_max()
.test_float_absdiff()
.test_mask()
.test_unpack()
.test_float_math()
.test_float_cvt32()
.test_extract<0>().test_extract<1>()
.test_rotate<0>().test_rotate<1>()
;
}
#endif
TEST(hal_intrin,float16)
TEST(hal_intrin, float16x8)
{
CV_CPU_CALL_FP16_(test_hal_intrin_float16, ());
throw SkipTestException("Unsupported hardware: FP16 is not available");
}
}}
#define DISPATCH_SIMD_MODES AVX2
#define DISPATCH_SIMD_NAME "SIMD256"
#define DISPATCH_SIMD(fun) \
do { \
CV_CPU_DISPATCH(fun, (), DISPATCH_SIMD_MODES); \
throw SkipTestException( \
"Unsupported hardware: " \
DISPATCH_SIMD_NAME \
" is not available" \
); \
} while(0)
TEST(hal_intrin256, uint8x32)
{ DISPATCH_SIMD(test_hal_intrin_uint8); }
TEST(hal_intrin256, int8x32)
{ DISPATCH_SIMD(test_hal_intrin_int8); }
TEST(hal_intrin256, uint16x16)
{ DISPATCH_SIMD(test_hal_intrin_uint16); }
TEST(hal_intrin256, int16x16)
{ DISPATCH_SIMD(test_hal_intrin_int16); }
TEST(hal_intrin256, uint32x8)
{ DISPATCH_SIMD(test_hal_intrin_uint32); }
TEST(hal_intrin256, int32x8)
{ DISPATCH_SIMD(test_hal_intrin_int32); }
TEST(hal_intrin256, uint64x4)
{ DISPATCH_SIMD(test_hal_intrin_uint64); }
TEST(hal_intrin256, int64x4)
{ DISPATCH_SIMD(test_hal_intrin_int64); }
TEST(hal_intrin256, float32x8)
{ DISPATCH_SIMD(test_hal_intrin_float32); }
TEST(hal_intrin256, float64x4)
{ DISPATCH_SIMD(test_hal_intrin_float64); }
TEST(hal_intrin256, float16x16)
{
if (!CV_CPU_HAS_SUPPORT_FP16)
throw SkipTestException("Unsupported hardware: FP16 is not available");
DISPATCH_SIMD(test_hal_intrin_float16);
}
}} // namespace
+1 -1
View File
@@ -9,7 +9,7 @@ CV_CPU_OPTIMIZATION_NAMESPACE_BEGIN
void test_hal_intrin_float16()
{
TheTest<v_float16x8>()
TheTest<v_float16>()
.test_loadstore_fp16()
.test_float_cvt_fp16()
;
+296
View File
@@ -0,0 +1,296 @@
// This file is part of OpenCV project.
// It is subject to the license terms in the LICENSE file found in the top-level directory
// of this distribution and at http://opencv.org/license.html.
#include "test_precomp.hpp"
#include "test_intrin_utils.hpp"
namespace opencv_test { namespace hal {
CV_CPU_OPTIMIZATION_NAMESPACE_BEGIN
void test_hal_intrin_uint8();
void test_hal_intrin_int8();
void test_hal_intrin_uint16();
void test_hal_intrin_int16();
void test_hal_intrin_uint32();
void test_hal_intrin_int32();
void test_hal_intrin_uint64();
void test_hal_intrin_int64();
void test_hal_intrin_float32();
void test_hal_intrin_float64();
#ifndef CV_CPU_OPTIMIZATION_DECLARATIONS_ONLY
//============= 8-bit integer =====================================================================
void test_hal_intrin_uint8()
{
TheTest<v_uint8>()
.test_loadstore()
.test_interleave()
.test_expand()
.test_expand_q()
.test_addsub()
.test_addsub_wrap()
.test_cmp()
.test_logic()
.test_min_max()
.test_absdiff()
.test_mask()
.test_popcount()
.test_pack<1>().test_pack<2>().test_pack<3>().test_pack<8>()
.test_pack_u<1>().test_pack_u<2>().test_pack_u<3>().test_pack_u<8>()
.test_unpack()
.test_extract<0>().test_extract<1>().test_extract<8>().test_extract<15>()
.test_rotate<0>().test_rotate<1>().test_rotate<8>().test_rotate<15>()
;
#if CV_SIMD256
TheTest<v_uint8>()
.test_pack<9>().test_pack<10>().test_pack<13>().test_pack<15>()
.test_pack_u<9>().test_pack_u<10>().test_pack_u<13>().test_pack_u<15>()
.test_extract<16>().test_extract<17>().test_extract<23>().test_extract<31>()
.test_rotate<16>().test_rotate<17>().test_rotate<23>().test_rotate<31>()
;
#endif
}
void test_hal_intrin_int8()
{
TheTest<v_int8>()
.test_loadstore()
.test_interleave()
.test_expand()
.test_expand_q()
.test_addsub()
.test_addsub_wrap()
.test_cmp()
.test_logic()
.test_min_max()
.test_absdiff()
.test_abs()
.test_mask()
.test_popcount()
.test_pack<1>().test_pack<2>().test_pack<3>().test_pack<8>()
.test_unpack()
.test_extract<0>().test_extract<1>().test_extract<8>().test_extract<15>()
.test_rotate<0>().test_rotate<1>().test_rotate<8>().test_rotate<15>()
;
}
//============= 16-bit integer =====================================================================
void test_hal_intrin_uint16()
{
TheTest<v_uint16>()
.test_loadstore()
.test_interleave()
.test_expand()
.test_addsub()
.test_addsub_wrap()
.test_mul()
.test_mul_expand()
.test_cmp()
.test_shift<1>()
.test_shift<8>()
.test_logic()
.test_min_max()
.test_absdiff()
.test_reduce()
.test_mask()
.test_popcount()
.test_pack<1>().test_pack<2>().test_pack<7>().test_pack<16>()
.test_pack_u<1>().test_pack_u<2>().test_pack_u<7>().test_pack_u<16>()
.test_unpack()
.test_extract<0>().test_extract<1>().test_extract<4>().test_extract<7>()
.test_rotate<0>().test_rotate<1>().test_rotate<4>().test_rotate<7>()
;
}
void test_hal_intrin_int16()
{
TheTest<v_int16>()
.test_loadstore()
.test_interleave()
.test_expand()
.test_addsub()
.test_addsub_wrap()
.test_mul()
.test_mul_expand()
.test_cmp()
.test_shift<1>()
.test_shift<8>()
.test_dot_prod()
.test_logic()
.test_min_max()
.test_absdiff()
.test_abs()
.test_reduce()
.test_mask()
.test_popcount()
.test_pack<1>().test_pack<2>().test_pack<7>().test_pack<16>()
.test_unpack()
.test_extract<0>().test_extract<1>().test_extract<4>().test_extract<7>()
.test_rotate<0>().test_rotate<1>().test_rotate<4>().test_rotate<7>()
;
}
//============= 32-bit integer =====================================================================
void test_hal_intrin_uint32()
{
TheTest<v_uint32>()
.test_loadstore()
.test_interleave()
.test_expand()
.test_addsub()
.test_mul()
.test_mul_expand()
.test_cmp()
.test_shift<1>()
.test_shift<8>()
.test_logic()
.test_min_max()
.test_absdiff()
.test_reduce()
.test_mask()
.test_popcount()
.test_pack<1>().test_pack<2>().test_pack<15>().test_pack<32>()
.test_unpack()
.test_extract<0>().test_extract<1>().test_extract<2>().test_extract<3>()
.test_rotate<0>().test_rotate<1>().test_rotate<2>().test_rotate<3>()
.test_transpose()
;
}
void test_hal_intrin_int32()
{
TheTest<v_int32>()
.test_loadstore()
.test_interleave()
.test_expand()
.test_addsub()
.test_mul()
.test_abs()
.test_cmp()
.test_popcount()
.test_shift<1>().test_shift<8>()
.test_logic()
.test_min_max()
.test_absdiff()
.test_reduce()
.test_mask()
.test_pack<1>().test_pack<2>().test_pack<15>().test_pack<32>()
.test_unpack()
.test_extract<0>().test_extract<1>().test_extract<2>().test_extract<3>()
.test_rotate<0>().test_rotate<1>().test_rotate<2>().test_rotate<3>()
.test_float_cvt32()
.test_float_cvt64()
.test_transpose()
;
}
//============= 64-bit integer =====================================================================
void test_hal_intrin_uint64()
{
TheTest<v_uint64>()
.test_loadstore()
.test_addsub()
.test_shift<1>().test_shift<8>()
.test_logic()
.test_extract<0>().test_extract<1>()
.test_rotate<0>().test_rotate<1>()
;
}
void test_hal_intrin_int64()
{
TheTest<v_int64>()
.test_loadstore()
.test_addsub()
.test_shift<1>().test_shift<8>()
.test_logic()
.test_extract<0>().test_extract<1>()
.test_rotate<0>().test_rotate<1>()
;
}
//============= Floating point =====================================================================
void test_hal_intrin_float32()
{
TheTest<v_float32>()
.test_loadstore()
.test_interleave()
.test_interleave_2channel()
.test_addsub()
.test_mul()
.test_div()
.test_cmp()
.test_sqrt_abs()
.test_min_max()
.test_float_absdiff()
.test_reduce()
.test_mask()
.test_unpack()
.test_float_math()
.test_float_cvt64()
.test_matmul()
.test_transpose()
.test_reduce_sum4()
.test_extract<0>().test_extract<1>().test_extract<2>().test_extract<3>()
.test_rotate<0>().test_rotate<1>().test_rotate<2>().test_rotate<3>()
;
#if CV_SIMD256
TheTest<v_float32>()
.test_extract<4>().test_extract<5>().test_extract<6>().test_extract<7>()
.test_rotate<4>().test_rotate<5>().test_rotate<6>().test_rotate<7>()
;
#endif
}
void test_hal_intrin_float64()
{
#if CV_SIMD_64F
TheTest<v_float64>()
.test_loadstore()
.test_addsub()
.test_mul()
.test_div()
.test_cmp()
.test_sqrt_abs()
.test_min_max()
.test_float_absdiff()
.test_mask()
.test_unpack()
.test_float_math()
.test_float_cvt32()
.test_extract<0>().test_extract<1>()
.test_rotate<0>().test_rotate<1>()
;
#if CV_SIMD256
TheTest<v_float64>()
.test_extract<2>().test_extract<3>()
.test_rotate<2>().test_rotate<3>()
;
#endif //CV_SIMD256
#endif
}
#if CV_FP16 && CV_SIMD_WIDTH > 16
void test_hal_intrin_float16()
{
TheTest<v_float16>()
.test_loadstore_fp16()
.test_float_cvt_fp16()
;
}
#endif
#endif //CV_CPU_OPTIMIZATION_DECLARATIONS_ONLY
CV_CPU_OPTIMIZATION_NAMESPACE_END
}} //namespace
+109 -60
View File
@@ -13,6 +13,27 @@ void test_hal_intrin_float16();
template <typename R> struct Data;
template <int N> struct initializer;
template <> struct initializer<64>
{
template <typename R> static R init(const Data<R> & d)
{
return R(d[0], d[1], d[2], d[3], d[4], d[5], d[6], d[7], d[8], d[9], d[10], d[11], d[12], d[13], d[14], d[15],
d[16], d[17], d[18], d[19], d[20], d[21], d[22], d[23], d[24], d[25], d[26], d[27], d[28], d[29], d[30], d[31],
d[32], d[33], d[34], d[35], d[36], d[37], d[38], d[39], d[40], d[41], d[42], d[43], d[44], d[45], d[46], d[47],
d[48], d[49], d[50], d[51], d[52], d[53], d[54], d[55], d[56], d[57], d[58], d[59], d[50], d[51], d[52], d[53],
d[54], d[55], d[56], d[57], d[58], d[59], d[60], d[61], d[62], d[63]);
}
};
template <> struct initializer<32>
{
template <typename R> static R init(const Data<R> & d)
{
return R(d[0], d[1], d[2], d[3], d[4], d[5], d[6], d[7], d[8], d[9], d[10], d[11], d[12], d[13], d[14], d[15],
d[16], d[17], d[18], d[19], d[20], d[21], d[22], d[23], d[24], d[25], d[26], d[27], d[28], d[29], d[30], d[31]);
}
};
template <> struct initializer<16>
{
template <typename R> static R init(const Data<R> & d)
@@ -125,6 +146,17 @@ template <typename R> struct Data
{
return d + R::nlanes / 2;
}
LaneType sum(int s, int c)
{
LaneType res = 0;
for (int i = s; i < s + c; ++i)
res += d[i];
return res;
}
LaneType sum()
{
return sum(0, R::nlanes);
}
bool operator==(const Data<R> & other) const
{
for (int i = 0; i < R::nlanes; ++i)
@@ -147,13 +179,12 @@ template <typename R> struct Data
return false;
return true;
}
LaneType d[R::nlanes];
};
template<typename R> struct AlignedData
{
Data<R> CV_DECL_ALIGNED(16) a; // aligned
Data<R> CV_DECL_ALIGNED(CV_SIMD_WIDTH) a; // aligned
char dummy;
Data<R> u; // unaligned
};
@@ -207,22 +238,22 @@ template<typename R> struct TheTest
AlignedData<R> out;
// check if addresses are aligned and unaligned respectively
EXPECT_EQ((size_t)0, (size_t)&data.a.d % 16);
EXPECT_NE((size_t)0, (size_t)&data.u.d % 16);
EXPECT_EQ((size_t)0, (size_t)&out.a.d % 16);
EXPECT_NE((size_t)0, (size_t)&out.u.d % 16);
EXPECT_EQ((size_t)0, (size_t)&data.a.d % CV_SIMD_WIDTH);
EXPECT_NE((size_t)0, (size_t)&data.u.d % CV_SIMD_WIDTH);
EXPECT_EQ((size_t)0, (size_t)&out.a.d % CV_SIMD_WIDTH);
EXPECT_NE((size_t)0, (size_t)&out.u.d % CV_SIMD_WIDTH);
// check some initialization methods
R r1 = data.a;
R r2 = v_load(data.u.d);
R r3 = v_load_aligned(data.a.d);
R r2 = vx_load(data.u.d);
R r3 = vx_load_aligned(data.a.d);
R r4(r2);
EXPECT_EQ(data.a[0], r1.get0());
EXPECT_EQ(data.u[0], r2.get0());
EXPECT_EQ(data.a[0], r3.get0());
EXPECT_EQ(data.u[0], r4.get0());
R r_low = v_load_low((LaneType*)data.u.d);
R r_low = vx_load_low((LaneType*)data.u.d);
EXPECT_EQ(data.u[0], r_low.get0());
v_store(out.u.d, r_low);
for (int i = 0; i < R::nlanes/2; ++i)
@@ -230,7 +261,7 @@ template<typename R> struct TheTest
EXPECT_EQ((LaneType)data.u[i], (LaneType)out.u[i]);
}
R r_low_align8byte = v_load_low((LaneType*)((char*)data.u.d + 8));
R r_low_align8byte = vx_load_low((LaneType*)((char*)data.u.d + (CV_SIMD_WIDTH / 2)));
EXPECT_EQ(data.u[R::nlanes/2], r_low_align8byte.get0());
v_store(out.u.d, r_low_align8byte);
for (int i = 0; i < R::nlanes/2; ++i)
@@ -255,7 +286,7 @@ template<typename R> struct TheTest
// check halves load correctness
res.clear();
R r6 = v_load_halves(d.d, d.mid());
R r6 = vx_load_halves(d.d, d.mid());
v_store(res.d, r6);
EXPECT_EQ(d, res);
@@ -270,17 +301,17 @@ template<typename R> struct TheTest
}
// reinterpret_as
v_uint8x16 vu8 = v_reinterpret_as_u8(r1); out.a.clear(); v_store((uchar*)out.a.d, vu8); EXPECT_EQ(data.a, out.a);
v_int8x16 vs8 = v_reinterpret_as_s8(r1); out.a.clear(); v_store((schar*)out.a.d, vs8); EXPECT_EQ(data.a, out.a);
v_uint16x8 vu16 = v_reinterpret_as_u16(r1); out.a.clear(); v_store((ushort*)out.a.d, vu16); EXPECT_EQ(data.a, out.a);
v_int16x8 vs16 = v_reinterpret_as_s16(r1); out.a.clear(); v_store((short*)out.a.d, vs16); EXPECT_EQ(data.a, out.a);
v_uint32x4 vu32 = v_reinterpret_as_u32(r1); out.a.clear(); v_store((unsigned*)out.a.d, vu32); EXPECT_EQ(data.a, out.a);
v_int32x4 vs32 = v_reinterpret_as_s32(r1); out.a.clear(); v_store((int*)out.a.d, vs32); EXPECT_EQ(data.a, out.a);
v_uint64x2 vu64 = v_reinterpret_as_u64(r1); out.a.clear(); v_store((uint64*)out.a.d, vu64); EXPECT_EQ(data.a, out.a);
v_int64x2 vs64 = v_reinterpret_as_s64(r1); out.a.clear(); v_store((int64*)out.a.d, vs64); EXPECT_EQ(data.a, out.a);
v_float32x4 vf32 = v_reinterpret_as_f32(r1); out.a.clear(); v_store((float*)out.a.d, vf32); EXPECT_EQ(data.a, out.a);
#if CV_SIMD128_64F
v_float64x2 vf64 = v_reinterpret_as_f64(r1); out.a.clear(); v_store((double*)out.a.d, vf64); EXPECT_EQ(data.a, out.a);
v_uint8 vu8 = v_reinterpret_as_u8(r1); out.a.clear(); v_store((uchar*)out.a.d, vu8); EXPECT_EQ(data.a, out.a);
v_int8 vs8 = v_reinterpret_as_s8(r1); out.a.clear(); v_store((schar*)out.a.d, vs8); EXPECT_EQ(data.a, out.a);
v_uint16 vu16 = v_reinterpret_as_u16(r1); out.a.clear(); v_store((ushort*)out.a.d, vu16); EXPECT_EQ(data.a, out.a);
v_int16 vs16 = v_reinterpret_as_s16(r1); out.a.clear(); v_store((short*)out.a.d, vs16); EXPECT_EQ(data.a, out.a);
v_uint32 vu32 = v_reinterpret_as_u32(r1); out.a.clear(); v_store((unsigned*)out.a.d, vu32); EXPECT_EQ(data.a, out.a);
v_int32 vs32 = v_reinterpret_as_s32(r1); out.a.clear(); v_store((int*)out.a.d, vs32); EXPECT_EQ(data.a, out.a);
v_uint64 vu64 = v_reinterpret_as_u64(r1); out.a.clear(); v_store((uint64*)out.a.d, vu64); EXPECT_EQ(data.a, out.a);
v_int64 vs64 = v_reinterpret_as_s64(r1); out.a.clear(); v_store((int64*)out.a.d, vs64); EXPECT_EQ(data.a, out.a);
v_float32 vf32 = v_reinterpret_as_f32(r1); out.a.clear(); v_store((float*)out.a.d, vf32); EXPECT_EQ(data.a, out.a);
#if CV_SIMD_64F
v_float64 vf64 = v_reinterpret_as_f64(r1); out.a.clear(); v_store((double*)out.a.d, vf64); EXPECT_EQ(data.a, out.a);
#endif
return *this;
@@ -357,7 +388,7 @@ template<typename R> struct TheTest
Data<R> dataA;
R a = dataA;
Data<Rx2> resB = v_load_expand(dataA.d);
Data<Rx2> resB = vx_load_expand(dataA.d);
Rx2 c, d;
v_expand(a, c, d);
@@ -378,7 +409,7 @@ template<typename R> struct TheTest
{
typedef typename V_RegTraits<R>::q_reg Rx4;
Data<R> data;
Data<Rx4> out = v_load_expand_q(data.d);
Data<Rx4> out = vx_load_expand_q(data.d);
const int n = Rx4::nlanes;
for (int i = 0; i < n; ++i)
EXPECT_EQ(data[i], out[i]);
@@ -610,7 +641,13 @@ template<typename R> struct TheTest
TheTest & test_popcount()
{
static unsigned popcountTable[] = {0, 1, 2, 4, 5, 7, 9, 12, 13, 15, 17, 20, 22, 25, 28, 32, 33};
static unsigned popcountTable[] = {
0, 1, 2, 4, 5, 7, 9, 12, 13, 15, 17, 20, 22, 25, 28, 32, 33,
35, 37, 40, 42, 45, 48, 52, 54, 57, 60, 64, 67, 71, 75, 80, 81,
83, 85, 88, 90, 93, 96, 100, 102, 105, 108, 112, 115, 119, 123,
128, 130, 133, 136, 140, 143, 147, 151, 156, 159, 163, 167, 172,
176, 181, 186, 192, 193
};
Data<R> dataA;
R a = dataA;
@@ -918,7 +955,7 @@ template<typename R> struct TheTest
TheTest & test_float_cvt32()
{
typedef v_float32x4 Rt;
typedef v_float32 Rt;
Data<R> dataA;
dataA *= 1.1;
R a = dataA;
@@ -934,8 +971,8 @@ template<typename R> struct TheTest
TheTest & test_float_cvt64()
{
#if CV_SIMD128_64F
typedef v_float64x2 Rt;
#if CV_SIMD_64F
typedef v_float64 Rt;
Data<R> dataA;
dataA *= 1.1;
R a = dataA;
@@ -965,23 +1002,29 @@ template<typename R> struct TheTest
R v = dataV, a = dataA, b = dataB, c = dataC, d = dataD;
Data<R> res = v_matmul(v, a, b, c, d);
for (int i = 0; i < R::nlanes; ++i)
for (int i = 0; i < R::nlanes; i += 4)
{
LaneType val = dataV[0] * dataA[i]
+ dataV[1] * dataB[i]
+ dataV[2] * dataC[i]
+ dataV[3] * dataD[i];
EXPECT_DOUBLE_EQ(val, res[i]);
for (int j = i; j < i + 4; ++j)
{
LaneType val = dataV[i] * dataA[j]
+ dataV[i + 1] * dataB[j]
+ dataV[i + 2] * dataC[j]
+ dataV[i + 3] * dataD[j];
EXPECT_COMPARE_EQ(val, res[j]);
}
}
Data<R> resAdd = v_matmuladd(v, a, b, c, d);
for (int i = 0; i < R::nlanes; ++i)
for (int i = 0; i < R::nlanes; i += 4)
{
LaneType val = dataV[0] * dataA[i]
+ dataV[1] * dataB[i]
+ dataV[2] * dataC[i]
+ dataD[i];
EXPECT_DOUBLE_EQ(val, resAdd[i]);
for (int j = i; j < i + 4; ++j)
{
LaneType val = dataV[i] * dataA[j]
+ dataV[i + 1] * dataB[j]
+ dataV[i + 2] * dataC[j]
+ dataD[j];
EXPECT_COMPARE_EQ(val, resAdd[j]);
}
}
return *this;
}
@@ -998,30 +1041,36 @@ template<typename R> struct TheTest
e, f, g, h);
Data<R> res[4] = {e, f, g, h};
for (int i = 0; i < R::nlanes; ++i)
for (int i = 0; i < R::nlanes; i += 4)
{
EXPECT_EQ(dataA[i], res[i][0]);
EXPECT_EQ(dataB[i], res[i][1]);
EXPECT_EQ(dataC[i], res[i][2]);
EXPECT_EQ(dataD[i], res[i][3]);
for (int j = 0; j < 4; ++j)
{
EXPECT_EQ(dataA[i + j], res[j][i]);
EXPECT_EQ(dataB[i + j], res[j][i + 1]);
EXPECT_EQ(dataC[i + j], res[j][i + 2]);
EXPECT_EQ(dataD[i + j], res[j][i + 3]);
}
}
return *this;
}
TheTest & test_reduce_sum4()
{
R a(0.1f, 0.02f, 0.003f, 0.0004f);
R b(1, 20, 300, 4000);
R c(10, 2, 0.3f, 0.04f);
R d(1, 2, 3, 4);
Data<R> dataA, dataB, dataC, dataD;
dataB *= 0.01f;
dataC *= 0.001f;
dataD *= 0.002f;
R sum = v_reduce_sum4(a, b, c, d);
R a = dataA, b = dataB, c = dataC, d = dataD;
Data<R> res = v_reduce_sum4(a, b, c, d);
Data<R> res = sum;
EXPECT_EQ(0.1234f, res[0]);
EXPECT_EQ(4321.0f, res[1]);
EXPECT_EQ(12.34f, res[2]);
EXPECT_EQ(10.0f, res[3]);
for (int i = 0; i < R::nlanes; i += 4)
{
EXPECT_COMPARE_EQ(dataA.sum(i, 4), res[i]);
EXPECT_COMPARE_EQ(dataB.sum(i, 4), res[i + 1]);
EXPECT_COMPARE_EQ(dataC.sum(i, 4), res[i + 2]);
EXPECT_COMPARE_EQ(dataD.sum(i, 4), res[i + 3]);
}
return *this;
}
@@ -1032,14 +1081,14 @@ template<typename R> struct TheTest
AlignedData<R> out;
// check if addresses are aligned and unaligned respectively
EXPECT_EQ((size_t)0, (size_t)&data.a.d % 16);
EXPECT_NE((size_t)0, (size_t)&data.u.d % 16);
EXPECT_EQ((size_t)0, (size_t)&out.a.d % 16);
EXPECT_NE((size_t)0, (size_t)&out.u.d % 16);
EXPECT_EQ((size_t)0, (size_t)&data.a.d % CV_SIMD_WIDTH);
EXPECT_NE((size_t)0, (size_t)&data.u.d % CV_SIMD_WIDTH);
EXPECT_EQ((size_t)0, (size_t)&out.a.d % CV_SIMD_WIDTH);
EXPECT_NE((size_t)0, (size_t)&out.u.d % CV_SIMD_WIDTH);
// check some initialization methods
R r1 = data.u;
R r2 = v_load_f16(data.a.d);
R r2 = vx_load_f16(data.a.d);
R r3(r2);
EXPECT_EQ(data.u[0], r1.get0());
EXPECT_EQ(data.a[0], r2.get0());
-1
View File
@@ -173,7 +173,6 @@ void Core_RandTest::run( int )
dsz = slice+1 < maxSlice ? (int)(cvtest::randInt(rng) % (SZ - sz) + 1) : SZ - sz;
Mat aslice = arr[k].colRange(sz, sz + dsz);
tested_rng.fill(aslice, dist_type, A, B);
//printf("%d - %d\n", sz, sz + dsz);
}
}