From 96ec0c97dfe8d77ce3cc041cf1f763acf96366c3 Mon Sep 17 00:00:00 2001 From: Andrei Fedorov Date: Tue, 15 Sep 2026 07:47:00 +0200 Subject: [PATCH] Merge pull request #29922 from andreyfe1:extend_perf_core MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Extend core performance tests - #29922 Added more cases for performance tests. It's a part of a bigger PR https://github.com/opencv/opencv/pull/29631 execution time increased by <18% per my measurements. Duplication of https://github.com/opencv/opencv/pull/29900, but from a different fork. `opencv_extra` PR is https://github.com/opencv/opencv_extra/pull/1410 Following was added: | File | Test | Added | |------|------|-------| | `perf_arithm.cpp` | `BinaryOpTest.*` (add/subtract/multiply/absdiff/min/max/transpose2d) | types `CV_16UC1`, `CV_64FC1` | | `perf_compare.cpp` | `compareScalar` | types `CV_16UC1`, `CV_16SC1` | | `perf_dot.cpp` | `dot` | type `CV_64FC1` | | `perf_flip.cpp` | `flip` (`FLIP_TYPES`) | types `CV_32FC3`, `CV_32FC4` | | `perf_mat.cpp` | `Mat_CopyToWithMask` | types `CV_32FC3` | | `perf_mat.cpp` | `Mat_SetToWithMask` | types `CV_8UC3, CV_8UC4, CV_16UC3, CV_16UC4, CV_32FC3, CV_32FC4` | | `perf_norm.cpp` | `norm` | norm type `NORM_L2SQR` | | `perf_norm.cpp` | `norm_mask` | types `CV_8UC3`, `CV_16UC3`, `CV_32FC3`; norm type `NORM_L2SQR` | | `perf_norm.cpp` | `norm2` | norm types `NORM_L2SQR`, `NORM_RELATIVE+NORM_L2SQR` | | `perf_norm.cpp` | `norm2_mask` | types `CV_8UC3`, `CV_16UC3`, `CV_32FC3`; norm types `NORM_L2SQR`, `NORM_RELATIVE\|NORM_L2SQR` | | `perf_sort.cpp` | `sort`, `sorIdx` (`TYPICAL_MAT_TYPES_SORT`) | types `CV_16SC1`, `CV_32SC1`, `CV_64FC1` | | `perf_stat.cpp` | `sum`, `mean` | types widened `{8UC1,8UC4,32FC1}` → `8U/16U/16S/32F × C1/C3/C4` | | `perf_stat.cpp` | `mean_mask`, `meanStdDev`, `meanStdDev_mask` | types widened `{8UC1,8UC4,32FC1}` → `8U/16U/32F × C1/C3/C4` | ### 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 - [x] There is a reference to the original bug report and related work - [x] 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 --- hal/ipp/include/ipp_hal_core.hpp | 8 ++++++++ hal/ipp/src/norm_ipp.cpp | 4 ++++ modules/core/perf/perf_arithm.cpp | 2 +- modules/core/perf/perf_compare.cpp | 2 +- modules/core/perf/perf_dot.cpp | 2 +- modules/core/perf/perf_flip.cpp | 2 +- modules/core/perf/perf_mat.cpp | 4 ++-- modules/core/perf/perf_norm.cpp | 12 ++++++------ modules/core/perf/perf_sort.cpp | 2 +- modules/core/perf/perf_stat.cpp | 20 +++++++++++++++----- 10 files changed, 40 insertions(+), 18 deletions(-) diff --git a/hal/ipp/include/ipp_hal_core.hpp b/hal/ipp/include/ipp_hal_core.hpp index 359764a7bf..ae0bb729a0 100644 --- a/hal/ipp/include/ipp_hal_core.hpp +++ b/hal/ipp/include/ipp_hal_core.hpp @@ -35,6 +35,14 @@ int ipp_hal_minMaxIdxMaskStep(const uchar* src_data, size_t src_step, int width, # define IPP_DISABLE_NORM_INF_16U_C1MR 0 #endif +// segmentation fault in ippiNorm[Diff]_Inf_32f_C3CMR with the macOS ippicv (2021.9.1); +// the newer Linux/Windows ippicv (2026.0.0) is not affected +#if defined(__APPLE__) +# define IPP_DISABLE_NORM_INF_32F_C3CMR 1 +# else +# define IPP_DISABLE_NORM_INF_32F_C3CMR 0 +#endif + int ipp_hal_norm(const uchar* src, size_t src_step, const uchar* mask, size_t mask_step, int width, int height, int type, int norm_type, double* result); diff --git a/hal/ipp/src/norm_ipp.cpp b/hal/ipp/src/norm_ipp.cpp index de555a973e..7ce8a7bcae 100644 --- a/hal/ipp/src/norm_ipp.cpp +++ b/hal/ipp/src/norm_ipp.cpp @@ -50,7 +50,9 @@ int ipp_hal_norm(const uchar* src, size_t src_step, const uchar* mask, size_t ma norm_type == cv::NORM_INF ? (type == CV_8UC3 ? (ippiMaskNormFuncC3)ippiNorm_Inf_8u_C3CMR : type == CV_16UC3 ? (ippiMaskNormFuncC3)ippiNorm_Inf_16u_C3CMR : + #if (!IPP_DISABLE_NORM_INF_32F_C3CMR) type == CV_32FC3 ? (ippiMaskNormFuncC3)ippiNorm_Inf_32f_C3CMR : + #endif 0) : norm_type == cv::NORM_L1 ? (type == CV_8UC3 ? (ippiMaskNormFuncC3)ippiNorm_L1_8u_C3CMR : @@ -265,7 +267,9 @@ int ipp_hal_normDiff(const uchar* src1, size_t src1_step, const uchar* src2, siz norm_type == cv::NORM_INF ? (type == CV_8UC3 ? (ippiMaskNormDiffFuncC3)ippiNormDiff_Inf_8u_C3CMR : type == CV_16UC3 ? (ippiMaskNormDiffFuncC3)ippiNormDiff_Inf_16u_C3CMR : + #if (!IPP_DISABLE_NORM_INF_32F_C3CMR) type == CV_32FC3 ? (ippiMaskNormDiffFuncC3)ippiNormDiff_Inf_32f_C3CMR : + #endif 0) : norm_type == cv::NORM_L1 ? (type == CV_8UC3 ? (ippiMaskNormDiffFuncC3)ippiNormDiff_L1_8u_C3CMR : diff --git a/modules/core/perf/perf_arithm.cpp b/modules/core/perf/perf_arithm.cpp index d8b65e1a08..8877f792a5 100644 --- a/modules/core/perf/perf_arithm.cpp +++ b/modules/core/perf/perf_arithm.cpp @@ -526,7 +526,7 @@ PERF_TEST_P_(BinaryOpTest, transposeND_generic_move_tail_order) INSTANTIATE_TEST_CASE_P(/*nothing*/ , BinaryOpTest, testing::Combine( testing::Values(szVGA, sz720p, sz1080p), - testing::Values(CV_8UC1, CV_8UC3, CV_8UC4, CV_8SC1, CV_16SC1, CV_16SC2, CV_16SC3, CV_16SC4, CV_32SC1, CV_32FC1) + testing::Values(CV_8UC1, CV_8UC3, CV_8UC4, CV_8SC1, CV_16UC1, CV_16SC1, CV_16SC2, CV_16SC3, CV_16SC4, CV_32SC1, CV_32FC1, CV_64FC1) ) ); diff --git a/modules/core/perf/perf_compare.cpp b/modules/core/perf/perf_compare.cpp index be706e1a83..2b595a79da 100644 --- a/modules/core/perf/perf_compare.cpp +++ b/modules/core/perf/perf_compare.cpp @@ -35,7 +35,7 @@ PERF_TEST_P( Size_MatType_CmpType, compare, PERF_TEST_P( Size_MatType_CmpType, compareScalar, testing::Combine( testing::Values(TYPICAL_MAT_SIZES), - testing::Values(TYPICAL_MAT_TYPES), + testing::Values(CV_8UC1, CV_8UC4, CV_16UC1, CV_16SC1, CV_32FC1), CmpType::all() ) ) diff --git a/modules/core/perf/perf_dot.cpp b/modules/core/perf/perf_dot.cpp index 1230220a4c..441ab652bf 100644 --- a/modules/core/perf/perf_dot.cpp +++ b/modules/core/perf/perf_dot.cpp @@ -9,7 +9,7 @@ typedef TestBaseWithParam MatType_Length; PERF_TEST_P( MatType_Length, dot, testing::Combine( - testing::Values( CV_8UC1, CV_8SC1, CV_16SC1, CV_16UC1, CV_32SC1, CV_32FC1 ), + testing::Values( CV_8UC1, CV_8SC1, CV_16SC1, CV_16UC1, CV_32SC1, CV_32FC1, CV_64FC1 ), testing::Values( 32, 64, 128, 256, 512, 1024 ) )) { diff --git a/modules/core/perf/perf_flip.cpp b/modules/core/perf/perf_flip.cpp index 6e89cd6e9a..2229bc2311 100644 --- a/modules/core/perf/perf_flip.cpp +++ b/modules/core/perf/perf_flip.cpp @@ -15,7 +15,7 @@ enum }; #define FLIP_SIZES szQVGA, szVGA, sz1080p -#define FLIP_TYPES CV_8UC1, CV_8UC2, CV_8UC3, CV_8UC4, CV_8SC1, CV_16SC1, CV_16SC2, CV_16SC3, CV_16SC4, CV_32SC1, CV_32FC1 +#define FLIP_TYPES CV_8UC1, CV_8UC2, CV_8UC3, CV_8UC4, CV_8SC1, CV_16SC1, CV_16SC2, CV_16SC3, CV_16SC4, CV_32SC1, CV_32FC1, CV_32FC3, CV_32FC4 #define FLIP_CODES FLIP_X, FLIP_Y, FLIP_XY CV_FLAGS(FlipCode, FLIP_X, FLIP_Y, FLIP_XY); diff --git a/modules/core/perf/perf_mat.cpp b/modules/core/perf/perf_mat.cpp index 277eb92c21..a10e6cb382 100644 --- a/modules/core/perf/perf_mat.cpp +++ b/modules/core/perf/perf_mat.cpp @@ -99,7 +99,7 @@ PERF_TEST_P(Size_MatType, Mat_Clone_Roi, PERF_TEST_P(Size_MatType, Mat_CopyToWithMask, testing::Combine(testing::Values(::perf::sz1080p, ::perf::szODD), - testing::Values(CV_8UC1, CV_8UC2, CV_8UC3, CV_16UC1, CV_16UC3, CV_32SC1, CV_32SC2, CV_32FC4)) + testing::Values(CV_8UC1, CV_8UC2, CV_8UC3, CV_16UC1, CV_16UC3, CV_32SC1, CV_32SC2, CV_32FC3, CV_32FC4)) ) { const Size_MatType_t params = GetParam(); @@ -119,7 +119,7 @@ PERF_TEST_P(Size_MatType, Mat_CopyToWithMask, PERF_TEST_P(Size_MatType, Mat_SetToWithMask, testing::Combine(testing::Values(TYPICAL_MAT_SIZES), - testing::Values(CV_8UC1, CV_8UC2)) + testing::Values(CV_8UC1, CV_8UC2, CV_8UC3, CV_8UC4, CV_16UC3, CV_16UC4, CV_32FC3, CV_32FC4)) ) { const Size_MatType_t params = GetParam(); diff --git a/modules/core/perf/perf_norm.cpp b/modules/core/perf/perf_norm.cpp index c47398f8fc..ab3f98fa50 100644 --- a/modules/core/perf/perf_norm.cpp +++ b/modules/core/perf/perf_norm.cpp @@ -15,7 +15,7 @@ PERF_TEST_P(Size_MatType_NormType, norm, testing::Combine( testing::Values(TYPICAL_MAT_SIZES), testing::Values(CV_8UC1, CV_8UC4, CV_8SC1, CV_16UC1, CV_16SC1, CV_32SC1, CV_32FC1, CV_64FC1), - testing::Values((int)NORM_INF, (int)NORM_L1, (int)NORM_L2) + testing::Values((int)NORM_INF, (int)NORM_L1, (int)NORM_L2, (int)NORM_L2SQR) ) ) { @@ -36,8 +36,8 @@ PERF_TEST_P(Size_MatType_NormType, norm, PERF_TEST_P(Size_MatType_NormType, norm_mask, testing::Combine( testing::Values(TYPICAL_MAT_SIZES), - testing::Values(CV_8UC1, CV_8UC4, CV_8SC1, CV_16UC1, CV_16SC1, CV_32SC1, CV_32FC1, CV_64FC1), - testing::Values((int)NORM_INF, (int)NORM_L1, (int)NORM_L2) + testing::Values(CV_8UC1, CV_8UC3, CV_8UC4, CV_8SC1, CV_16UC1, CV_16UC3, CV_16SC1, CV_32SC1, CV_32FC1, CV_32FC3, CV_64FC1), + testing::Values((int)NORM_INF, (int)NORM_L1, (int)NORM_L2, (int)NORM_L2SQR) ) ) { @@ -60,7 +60,7 @@ PERF_TEST_P(Size_MatType_NormType, norm2, testing::Combine( testing::Values(TYPICAL_MAT_SIZES), testing::Values(CV_8UC1, CV_8UC4, CV_8SC1, CV_16UC1, CV_16SC1, CV_32SC1, CV_32FC1, CV_64FC1), - testing::Values((int)NORM_INF, (int)NORM_L1, (int)NORM_L2, (int)(NORM_RELATIVE+NORM_INF), (int)(NORM_RELATIVE+NORM_L1), (int)(NORM_RELATIVE+NORM_L2)) + testing::Values((int)NORM_INF, (int)NORM_L1, (int)NORM_L2, (int)NORM_L2SQR, (int)(NORM_RELATIVE+NORM_INF), (int)(NORM_RELATIVE+NORM_L1), (int)(NORM_RELATIVE+NORM_L2), (int)(NORM_RELATIVE+NORM_L2SQR)) ) ) { @@ -82,8 +82,8 @@ PERF_TEST_P(Size_MatType_NormType, norm2, PERF_TEST_P(Size_MatType_NormType, norm2_mask, testing::Combine( testing::Values(TYPICAL_MAT_SIZES), - testing::Values(CV_8UC1, CV_8UC4, CV_8SC1, CV_16UC1, CV_16SC1, CV_32SC1, CV_32FC1, CV_64FC1), - testing::Values((int)NORM_INF, (int)NORM_L1, (int)NORM_L2, (int)(NORM_RELATIVE|NORM_INF), (int)(NORM_RELATIVE|NORM_L1), (int)(NORM_RELATIVE|NORM_L2)) + testing::Values(CV_8UC1, CV_8UC3, CV_8UC4, CV_8SC1, CV_16UC1, CV_16UC3, CV_16SC1, CV_32SC1, CV_32FC1, CV_32FC3, CV_64FC1), + testing::Values((int)NORM_INF, (int)NORM_L1, (int)NORM_L2, (int)NORM_L2SQR, (int)(NORM_RELATIVE|NORM_INF), (int)(NORM_RELATIVE|NORM_L1), (int)(NORM_RELATIVE|NORM_L2), (int)(NORM_RELATIVE|NORM_L2SQR)) ) ) { diff --git a/modules/core/perf/perf_sort.cpp b/modules/core/perf/perf_sort.cpp index 98056901ae..90e99a48e5 100644 --- a/modules/core/perf/perf_sort.cpp +++ b/modules/core/perf/perf_sort.cpp @@ -5,7 +5,7 @@ namespace opencv_test using namespace perf; #define TYPICAL_MAT_SIZES_SORT TYPICAL_MAT_SIZES -#define TYPICAL_MAT_TYPES_SORT CV_8UC1, CV_16UC1, CV_32FC1 +#define TYPICAL_MAT_TYPES_SORT CV_8UC1, CV_16UC1, CV_16SC1, CV_32SC1, CV_32FC1, CV_64FC1 #define SORT_TYPES SORT_EVERY_ROW | SORT_ASCENDING, SORT_EVERY_ROW | SORT_DESCENDING #define TYPICAL_MATS_SORT testing::Combine( testing::Values(TYPICAL_MAT_SIZES_SORT), testing::Values(TYPICAL_MAT_TYPES_SORT), testing::Values(SORT_TYPES) ) diff --git a/modules/core/perf/perf_stat.cpp b/modules/core/perf/perf_stat.cpp index 8846475844..3f33f7f7db 100644 --- a/modules/core/perf/perf_stat.cpp +++ b/modules/core/perf/perf_stat.cpp @@ -4,7 +4,13 @@ namespace opencv_test { using namespace perf; -PERF_TEST_P(Size_MatType, sum, TYPICAL_MATS) +// Masked variants: 8U/16U/32F x C1/C3/C4. +#define TYPICAL_MAT_TYPES_STAT_MASK CV_8UC1, CV_8UC3, CV_8UC4, CV_16UC1, CV_16UC3, CV_16UC4, CV_32FC1, CV_32FC3, CV_32FC4 +// sum/mean/meanStdDev additionally cover 16S. +#define TYPICAL_MAT_TYPES_STAT TYPICAL_MAT_TYPES_STAT_MASK, CV_16SC1, CV_16SC3, CV_16SC4 + +PERF_TEST_P(Size_MatType, sum, testing::Combine( testing::Values( TYPICAL_MAT_SIZES ), + testing::Values( TYPICAL_MAT_TYPES_STAT ) )) { Size sz = get<0>(GetParam()); int type = get<1>(GetParam()); @@ -19,7 +25,8 @@ PERF_TEST_P(Size_MatType, sum, TYPICAL_MATS) SANITY_CHECK(s, 1e-6, ERROR_RELATIVE); } -PERF_TEST_P(Size_MatType, mean, TYPICAL_MATS) +PERF_TEST_P(Size_MatType, mean, testing::Combine( testing::Values( TYPICAL_MAT_SIZES ), + testing::Values( TYPICAL_MAT_TYPES_STAT ) )) { Size sz = get<0>(GetParam()); int type = get<1>(GetParam()); @@ -34,7 +41,8 @@ PERF_TEST_P(Size_MatType, mean, TYPICAL_MATS) SANITY_CHECK(s, 1e-5); } -PERF_TEST_P(Size_MatType, mean_mask, TYPICAL_MATS) +PERF_TEST_P(Size_MatType, mean_mask, testing::Combine( testing::Values( TYPICAL_MAT_SIZES ), + testing::Values( TYPICAL_MAT_TYPES_STAT_MASK ) )) { Size sz = get<0>(GetParam()); int type = get<1>(GetParam()); @@ -50,7 +58,8 @@ PERF_TEST_P(Size_MatType, mean_mask, TYPICAL_MATS) SANITY_CHECK(s, 5e-5); } -PERF_TEST_P(Size_MatType, meanStdDev, TYPICAL_MATS) +PERF_TEST_P(Size_MatType, meanStdDev, testing::Combine( testing::Values( TYPICAL_MAT_SIZES ), + testing::Values( TYPICAL_MAT_TYPES_STAT_MASK ) )) { Size sz = get<0>(GetParam()); int matType = get<1>(GetParam()); @@ -67,7 +76,8 @@ PERF_TEST_P(Size_MatType, meanStdDev, TYPICAL_MATS) SANITY_CHECK(dev, 1e-5, ERROR_RELATIVE); } -PERF_TEST_P(Size_MatType, meanStdDev_mask, TYPICAL_MATS) +PERF_TEST_P(Size_MatType, meanStdDev_mask, testing::Combine( testing::Values( TYPICAL_MAT_SIZES ), + testing::Values( TYPICAL_MAT_TYPES_STAT_MASK ) )) { Size sz = get<0>(GetParam()); int matType = get<1>(GetParam());