Merge pull request #2622 from ilya-lavrenov:ipp_sort

This commit is contained in:
Andrey Pavlenko 2014-04-18 14:47:05 +04:00 committed by OpenCV Buildbot
commit 82c67abbfa
2 changed files with 173 additions and 10 deletions

View File

@ -0,0 +1,52 @@
#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_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) )
typedef tuple<Size, MatType, int> sortParams;
typedef TestBaseWithParam<sortParams> 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);
}
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_NOTHING();
}

View File

@ -3580,6 +3580,44 @@ 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
#define USE_IPP_SORT
typedef IppStatus (CV_STDCALL *IppSortFunc)(void *, int);
typedef IppSortFunc IppFlipFunc;
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;
}
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<typename T> static void sort_( const Mat& src, Mat& dst, int flags )
{
AutoBuffer<T> buf;
@ -3598,6 +3636,12 @@ template<typename T> static void sort_( const Mat& src, Mat& dst, int flags )
}
bptr = (T*)buf;
#ifdef USE_IPP_SORT
int depth = src.depth();
IppSortFunc ippSortFunc = getSortFunc(depth, sortDescending);
IppFlipFunc ippFlipFunc = getFlipFunc(depth);
#endif
for( i = 0; i < n; i++ )
{
T* ptr = bptr;
@ -3607,8 +3651,7 @@ template<typename T> 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;
}
@ -3617,10 +3660,30 @@ template<typename T> 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]);
#ifdef USE_IPP_SORT
if (!ippSortFunc || ippSortFunc(ptr, len) < 0)
#endif
{
#ifdef USE_IPP_SORT
setIppErrorStatus();
#endif
std::sort( ptr, ptr + len );
if( sortDescending )
{
#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 )
for( j = 0; j < len; j++ )
((T*)(dst.data + dst.step*j))[i] = ptr[j];
@ -3635,7 +3698,29 @@ public:
const _Tp* arr;
};
#ifdef USE_IPP_SORT
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<typename T> static void sortIdx_( const Mat& src, Mat& dst, int flags )
{
@ -3660,6 +3745,12 @@ template<typename T> static void sortIdx_( const Mat& src, Mat& dst, int flags )
bptr = (T*)buf;
_iptr = (int*)ibuf;
#ifdef USE_IPP_SORT
int depth = src.depth();
IppSortIndexFunc ippFunc = getSortIndexFunc(depth, sortDescending);
IppFlipFunc ippFlipFunc = getFlipFunc(depth);
#endif
for( i = 0; i < n; i++ )
{
T* ptr = bptr;
@ -3677,10 +3768,30 @@ template<typename T> 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<T>(ptr) );
if( sortDescending )
for( j = 0; j < len/2; j++ )
std::swap(iptr[j], iptr[len-1-j]);
#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<T>(ptr) );
if( sortDescending )
{
#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 )
for( j = 0; j < len; j++ )
((int*)(dst.data + dst.step*j))[i] = iptr[j];