From d5513f522b3c1adb0d83c39781cd8bf09950bb64 Mon Sep 17 00:00:00 2001 From: Ilya Lavrenov Date: Tue, 15 Apr 2014 00:11:16 +0400 Subject: [PATCH 1/3] cv::sort --- modules/core/perf/perf_sort.cpp | 32 +++++++++++++++++++++++ modules/core/src/matrix.cpp | 46 ++++++++++++++++++++++++++++----- 2 files changed, 72 insertions(+), 6 deletions(-) create mode 100644 modules/core/perf/perf_sort.cpp diff --git a/modules/core/perf/perf_sort.cpp b/modules/core/perf/perf_sort.cpp new file mode 100644 index 0000000000..fac2b45aad --- /dev/null +++ b/modules/core/perf/perf_sort.cpp @@ -0,0 +1,32 @@ +#include "perf_precomp.hpp" + +using namespace std; +using namespace cv; +using namespace perf; + +using std::tr1::tuple; +using std::tr1::make_tuple; +using std::tr1::get; + +#define TYPICAL_MAT_SIZES_SORT TYPICAL_MAT_SIZES +#define TYPICAL_MAT_TYPES_SORT CV_8SC1, CV_16UC1, CV_32FC1 +#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) ) + +typedef tuple sortParams; +typedef TestBaseWithParam sortFixture; + +PERF_TEST_P(sortFixture, sort, TYPICAL_MATS_SORT) +{ + const sortParams params = GetParam(); + const Size sz = get<0>(params); + const int type = get<1>(params), flags = get<2>(params); + + cv::Mat a(sz, type), b(sz, type); + + declare.in(a, WARMUP_RNG).out(b); + + TEST_CYCLE() cv::sort(a, b, flags); + + SANITY_CHECK(b); +} diff --git a/modules/core/src/matrix.cpp b/modules/core/src/matrix.cpp index d753b97a30..f1dd8a8bce 100644 --- a/modules/core/src/matrix.cpp +++ b/modules/core/src/matrix.cpp @@ -3467,6 +3467,30 @@ void cv::reduce(InputArray _src, OutputArray _dst, int dim, int op, int dtype) namespace cv { +#if IPP_VERSION_X100 > 0 && !defined HAVE_IPP_ICV_ONLY + +typedef IppStatus (CV_STDCALL *IppSortFunc)(void *, int); + +static IppSortFunc getSortFunc(int depth, bool sortDescending) +{ + if (!sortDescending) + return depth == CV_8U ? (IppSortFunc)ippsSortAscend_8u_I : + depth == CV_16U ? (IppSortFunc)ippsSortAscend_16u_I : + depth == CV_16S ? (IppSortFunc)ippsSortAscend_16s_I : + depth == CV_32S ? (IppSortFunc)ippsSortAscend_32s_I : + depth == CV_32F ? (IppSortFunc)ippsSortAscend_32f_I : + depth == CV_64F ? (IppSortFunc)ippsSortAscend_64f_I : 0; + else + return depth == CV_8U ? (IppSortFunc)ippsSortDescend_8u_I : + depth == CV_16U ? (IppSortFunc)ippsSortDescend_16u_I : + depth == CV_16S ? (IppSortFunc)ippsSortDescend_16s_I : + depth == CV_32S ? (IppSortFunc)ippsSortDescend_32s_I : + depth == CV_32F ? (IppSortFunc)ippsSortDescend_32f_I : + depth == CV_64F ? (IppSortFunc)ippsSortDescend_64f_I : 0; +} + +#endif + template static void sort_( const Mat& src, Mat& dst, int flags ) { AutoBuffer buf; @@ -3485,6 +3509,10 @@ template static void sort_( const Mat& src, Mat& dst, int flags ) } bptr = (T*)buf; +#if IPP_VERSION_X100 > 0 && !defined HAVE_IPP_ICV_ONLY + IppSortFunc ippFunc = getSortFunc(src.depth(), sortDescending); +#endif + for( i = 0; i < n; i++ ) { T* ptr = bptr; @@ -3494,8 +3522,7 @@ template static void sort_( const Mat& src, Mat& dst, int flags ) if( !inplace ) { const T* sptr = (const T*)(src.data + src.step*i); - for( j = 0; j < len; j++ ) - dptr[j] = sptr[j]; + memcpy(dptr, sptr, sizeof(T) * len); } ptr = dptr; } @@ -3504,10 +3531,17 @@ template static void sort_( const Mat& src, Mat& dst, int flags ) for( j = 0; j < len; j++ ) ptr[j] = ((const T*)(src.data + src.step*j))[i]; } - std::sort( ptr, ptr + len ); - if( sortDescending ) - for( j = 0; j < len/2; j++ ) - std::swap(ptr[j], ptr[len-1-j]); + +#if IPP_VERSION_X100 > 0 && !defined HAVE_IPP_ICV_ONLY + if (!ippFunc || ippFunc(ptr, len) < 0) +#endif + { + std::sort( ptr, ptr + len ); + if( sortDescending ) + for( j = 0; j < len/2; j++ ) + std::swap(ptr[j], ptr[len-1-j]); + } + if( !sortRows ) for( j = 0; j < len; j++ ) ((T*)(dst.data + dst.step*j))[i] = ptr[j]; From 26e8c6216f648f09886c1a510d0edf4e2cb5ce38 Mon Sep 17 00:00:00 2001 From: Ilya Lavrenov Date: Tue, 15 Apr 2014 14:43:44 +0400 Subject: [PATCH 2/3] cv:;sortIdx --- modules/core/perf/perf_sort.cpp | 20 ++++++++++++++++ modules/core/src/matrix.cpp | 41 +++++++++++++++++++++++++++++---- 2 files changed, 57 insertions(+), 4 deletions(-) diff --git a/modules/core/perf/perf_sort.cpp b/modules/core/perf/perf_sort.cpp index fac2b45aad..d9e12bc118 100644 --- a/modules/core/perf/perf_sort.cpp +++ b/modules/core/perf/perf_sort.cpp @@ -30,3 +30,23 @@ PERF_TEST_P(sortFixture, sort, TYPICAL_MATS_SORT) SANITY_CHECK(b); } + +typedef sortFixture sortIdxFixture; + +#undef SORT_TYPES +#define SORT_TYPES SORT_EVERY_COLUMN | SORT_ASCENDING, SORT_EVERY_COLUMN | SORT_DESCENDING + +PERF_TEST_P(sortIdxFixture, sorIdx, TYPICAL_MATS_SORT) +{ + const sortParams params = GetParam(); + const Size sz = get<0>(params); + const int type = get<1>(params), flags = get<2>(params); + + cv::Mat a(sz, type), b(sz, type); + + declare.in(a, WARMUP_RNG).out(b); + + TEST_CYCLE() cv::sortIdx(a, b, flags); + + SANITY_CHECK(b); +} diff --git a/modules/core/src/matrix.cpp b/modules/core/src/matrix.cpp index f1dd8a8bce..f81252ad22 100644 --- a/modules/core/src/matrix.cpp +++ b/modules/core/src/matrix.cpp @@ -3556,7 +3556,29 @@ public: const _Tp* arr; }; +#if IPP_VERSION_X100 > 0 && !defined HAVE_IPP_ICV_ONLY +typedef IppStatus (CV_STDCALL *IppSortIndexFunc)(void *, int *, int); + +static IppSortIndexFunc getSortIndexFunc(int depth, bool sortDescending) +{ + if (!sortDescending) + return depth == CV_8U ? (IppSortIndexFunc)ippsSortIndexAscend_8u_I : + depth == CV_16U ? (IppSortIndexFunc)ippsSortIndexAscend_16u_I : + depth == CV_16S ? (IppSortIndexFunc)ippsSortIndexAscend_16s_I : + depth == CV_32S ? (IppSortIndexFunc)ippsSortIndexAscend_32s_I : + depth == CV_32F ? (IppSortIndexFunc)ippsSortIndexAscend_32f_I : + depth == CV_64F ? (IppSortIndexFunc)ippsSortIndexAscend_64f_I : 0; + else + return depth == CV_8U ? (IppSortIndexFunc)ippsSortIndexDescend_8u_I : + depth == CV_16U ? (IppSortIndexFunc)ippsSortIndexDescend_16u_I : + depth == CV_16S ? (IppSortIndexFunc)ippsSortIndexDescend_16s_I : + depth == CV_32S ? (IppSortIndexFunc)ippsSortIndexDescend_32s_I : + depth == CV_32F ? (IppSortIndexFunc)ippsSortIndexDescend_32f_I : + depth == CV_64F ? (IppSortIndexFunc)ippsSortIndexDescend_64f_I : 0; +} + +#endif template static void sortIdx_( const Mat& src, Mat& dst, int flags ) { @@ -3581,6 +3603,10 @@ template static void sortIdx_( const Mat& src, Mat& dst, int flags ) bptr = (T*)buf; _iptr = (int*)ibuf; +#if IPP_VERSION_X100 > 0 && !defined HAVE_IPP_ICV_ONLY + IppSortIndexFunc ippFunc = getSortIndexFunc(src.depth(), sortDescending); +#endif + for( i = 0; i < n; i++ ) { T* ptr = bptr; @@ -3598,10 +3624,17 @@ template static void sortIdx_( const Mat& src, Mat& dst, int flags ) } for( j = 0; j < len; j++ ) iptr[j] = j; - std::sort( iptr, iptr + len, LessThanIdx(ptr) ); - if( sortDescending ) - for( j = 0; j < len/2; j++ ) - std::swap(iptr[j], iptr[len-1-j]); + +#if IPP_VERSION_X100 > 0 && !defined HAVE_IPP_ICV_ONLY + if (sortRows || !ippFunc || ippFunc(ptr, iptr, len) < 0) +#endif + { + std::sort( iptr, iptr + len, LessThanIdx(ptr) ); + if( sortDescending ) + for( j = 0; j < len/2; j++ ) + std::swap(iptr[j], iptr[len-1-j]); + } + if( !sortRows ) for( j = 0; j < len; j++ ) ((int*)(dst.data + dst.step*j))[i] = iptr[j]; From 1f6b719776a658333ee2df25a2e94ac264f9ca6b Mon Sep 17 00:00:00 2001 From: Ilya Lavrenov Date: Tue, 15 Apr 2014 14:58:11 +0400 Subject: [PATCH 3/3] added ippisFlip to cv::sort --- modules/core/perf/perf_sort.cpp | 4 +- modules/core/src/matrix.cpp | 68 +++++++++++++++++++++++++++------ 2 files changed, 58 insertions(+), 14 deletions(-) diff --git a/modules/core/perf/perf_sort.cpp b/modules/core/perf/perf_sort.cpp index d9e12bc118..491919e00c 100644 --- a/modules/core/perf/perf_sort.cpp +++ b/modules/core/perf/perf_sort.cpp @@ -9,7 +9,7 @@ using std::tr1::make_tuple; using std::tr1::get; #define TYPICAL_MAT_SIZES_SORT TYPICAL_MAT_SIZES -#define TYPICAL_MAT_TYPES_SORT CV_8SC1, CV_16UC1, CV_32FC1 +#define TYPICAL_MAT_TYPES_SORT CV_8UC1, CV_16UC1, CV_32FC1 #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) ) @@ -48,5 +48,5 @@ PERF_TEST_P(sortIdxFixture, sorIdx, TYPICAL_MATS_SORT) TEST_CYCLE() cv::sortIdx(a, b, flags); - SANITY_CHECK(b); + SANITY_CHECK_NOTHING(); } diff --git a/modules/core/src/matrix.cpp b/modules/core/src/matrix.cpp index f81252ad22..69f5938592 100644 --- a/modules/core/src/matrix.cpp +++ b/modules/core/src/matrix.cpp @@ -3468,8 +3468,10 @@ namespace cv { #if IPP_VERSION_X100 > 0 && !defined HAVE_IPP_ICV_ONLY +#define USE_IPP_SORT typedef IppStatus (CV_STDCALL *IppSortFunc)(void *, int); +typedef IppSortFunc IppFlipFunc; static IppSortFunc getSortFunc(int depth, bool sortDescending) { @@ -3489,6 +3491,18 @@ static IppSortFunc getSortFunc(int depth, bool sortDescending) depth == CV_64F ? (IppSortFunc)ippsSortDescend_64f_I : 0; } +static IppFlipFunc getFlipFunc(int depth) +{ + CV_SUPPRESS_DEPRECATED_START + return + depth == CV_8U || depth == CV_8S ? (IppFlipFunc)ippsFlip_8u_I : + depth == CV_16U || depth == CV_16S ? (IppFlipFunc)ippsFlip_16u_I : + depth == CV_32S || depth == CV_32F ? (IppFlipFunc)ippsFlip_32f_I : + depth == CV_64F ? (IppFlipFunc)ippsFlip_64f_I : 0; + CV_SUPPRESS_DEPRECATED_END +} + + #endif template static void sort_( const Mat& src, Mat& dst, int flags ) @@ -3509,8 +3523,10 @@ template static void sort_( const Mat& src, Mat& dst, int flags ) } bptr = (T*)buf; -#if IPP_VERSION_X100 > 0 && !defined HAVE_IPP_ICV_ONLY - IppSortFunc ippFunc = getSortFunc(src.depth(), sortDescending); +#ifdef USE_IPP_SORT + int depth = src.depth(); + IppSortFunc ippSortFunc = getSortFunc(depth, sortDescending); + IppFlipFunc ippFlipFunc = getFlipFunc(depth); #endif for( i = 0; i < n; i++ ) @@ -3532,14 +3548,27 @@ template static void sort_( const Mat& src, Mat& dst, int flags ) ptr[j] = ((const T*)(src.data + src.step*j))[i]; } -#if IPP_VERSION_X100 > 0 && !defined HAVE_IPP_ICV_ONLY - if (!ippFunc || ippFunc(ptr, len) < 0) +#ifdef USE_IPP_SORT + if (!ippSortFunc || ippSortFunc(ptr, len) < 0) #endif { +#ifdef USE_IPP_SORT + setIppErrorStatus(); +#endif std::sort( ptr, ptr + len ); if( sortDescending ) - for( j = 0; j < len/2; j++ ) - std::swap(ptr[j], ptr[len-1-j]); + { +#ifdef USE_IPP_SORT + if (!ippFlipFunc || ippFlipFunc(ptr, len) < 0) +#endif + { +#ifdef USE_IPP_SORT + setIppErrorStatus(); +#endif + for( j = 0; j < len/2; j++ ) + std::swap(ptr[j], ptr[len-1-j]); + } + } } if( !sortRows ) @@ -3556,7 +3585,7 @@ public: const _Tp* arr; }; -#if IPP_VERSION_X100 > 0 && !defined HAVE_IPP_ICV_ONLY +#ifdef USE_IPP_SORT typedef IppStatus (CV_STDCALL *IppSortIndexFunc)(void *, int *, int); @@ -3603,8 +3632,10 @@ template static void sortIdx_( const Mat& src, Mat& dst, int flags ) bptr = (T*)buf; _iptr = (int*)ibuf; -#if IPP_VERSION_X100 > 0 && !defined HAVE_IPP_ICV_ONLY - IppSortIndexFunc ippFunc = getSortIndexFunc(src.depth(), sortDescending); +#ifdef USE_IPP_SORT + int depth = src.depth(); + IppSortIndexFunc ippFunc = getSortIndexFunc(depth, sortDescending); + IppFlipFunc ippFlipFunc = getFlipFunc(depth); #endif for( i = 0; i < n; i++ ) @@ -3625,14 +3656,27 @@ template static void sortIdx_( const Mat& src, Mat& dst, int flags ) for( j = 0; j < len; j++ ) iptr[j] = j; -#if IPP_VERSION_X100 > 0 && !defined HAVE_IPP_ICV_ONLY +#ifdef USE_IPP_SORT if (sortRows || !ippFunc || ippFunc(ptr, iptr, len) < 0) #endif { +#ifdef USE_IPP_SORT + setIppErrorStatus(); +#endif std::sort( iptr, iptr + len, LessThanIdx(ptr) ); if( sortDescending ) - for( j = 0; j < len/2; j++ ) - std::swap(iptr[j], iptr[len-1-j]); + { +#ifdef USE_IPP_SORT + if (!ippFlipFunc || ippFlipFunc(iptr, len) < 0) +#endif + { +#ifdef USE_IPP_SORT + setIppErrorStatus(); +#endif + for( j = 0; j < len/2; j++ ) + std::swap(iptr[j], iptr[len-1-j]); + } + } } if( !sortRows )