mirror of
https://github.com/opencv/opencv.git
synced 2026-07-31 00:03:03 +04:00
ICV2017u3 package update;
- Optimizations set change. Now IPP integrations will provide code for SSE42, AVX2 and AVX512 (SKX) CPUs only. For HW below SSE42 IPP code is disabled. - Performance regressions fixes for IPP code paths; - cv::boxFilter integration improvement; - cv::filter2D integration improvement;
This commit is contained in:
@@ -693,8 +693,14 @@ CV_EXPORTS void setIppStatus(int status, const char * const funcname = NULL, c
|
||||
int line = 0);
|
||||
CV_EXPORTS int getIppStatus();
|
||||
CV_EXPORTS String getIppErrorLocation();
|
||||
CV_EXPORTS_W bool useIPP();
|
||||
CV_EXPORTS_W void setUseIPP(bool flag);
|
||||
CV_EXPORTS_W bool useIPP();
|
||||
CV_EXPORTS_W void setUseIPP(bool flag);
|
||||
CV_EXPORTS_W String getIppVersion();
|
||||
|
||||
// IPP Not-Exact mode. This function may force use of IPP then both IPP and OpenCV provide proper results
|
||||
// but have internal accuracy differences which have to much direct or indirect impact on accuracy tests.
|
||||
CV_EXPORTS_W bool useIPP_NE();
|
||||
CV_EXPORTS_W void setUseIPP_NE(bool flag);
|
||||
|
||||
} // ipp
|
||||
|
||||
|
||||
@@ -194,8 +194,6 @@ CV_EXPORTS void scalarToRawData(const cv::Scalar& s, void* buf, int type, int un
|
||||
#define IPP_DISABLE_WARPAFFINE 1 // Different results
|
||||
#define IPP_DISABLE_WARPPERSPECTIVE 1 // Different results
|
||||
#define IPP_DISABLE_REMAP 1 // Different results
|
||||
#define IPP_DISABLE_MORPH_ADV 1 // mask flipping in IPP
|
||||
#define IPP_DISABLE_SORT_IDX 0 // different order in index tables
|
||||
#define IPP_DISABLE_YUV_RGB 1 // accuracy difference
|
||||
#define IPP_DISABLE_RGB_YUV 1 // breaks OCL accuracy tests
|
||||
#define IPP_DISABLE_RGB_HSV 1 // breaks OCL accuracy tests
|
||||
@@ -205,21 +203,12 @@ CV_EXPORTS void scalarToRawData(const cv::Scalar& s, void* buf, int type, int un
|
||||
#define IPP_DISABLE_XYZ_RGB 1 // big accuracy difference
|
||||
#define IPP_DISABLE_HAAR 1 // improper integration/results
|
||||
#define IPP_DISABLE_HOUGH 1 // improper integration/results
|
||||
#define IPP_DISABLE_RESIZE_8U 1 // Incompatible accuracy
|
||||
#define IPP_DISABLE_RESIZE_NEAREST 1 // Accuracy mismatch (max diff 1)
|
||||
#define IPP_DISABLE_RESIZE_AREA 1 // Accuracy mismatch (max diff 1)
|
||||
|
||||
#define IPP_DISABLE_MINMAX_NAN_SSE42 1 // cv::minMaxIdx problem with NaN input
|
||||
|
||||
// Temporary disabled named IPP region. Performance
|
||||
#define IPP_DISABLE_PERF_COPYMAKE 1 // performance variations
|
||||
#define IPP_DISABLE_PERF_LUT 1 // there are no performance benefits (PR #2653)
|
||||
#define IPP_DISABLE_PERF_TRUE_DIST_MT 1 // cv::distanceTransform OpenCV MT performance is better
|
||||
#define IPP_DISABLE_PERF_CANNY_MT 1 // cv::Canny OpenCV MT performance is better
|
||||
#define IPP_DISABLE_PERF_HISTU32F_SSE42 1 // cv::calcHist optimizations problem
|
||||
#define IPP_DISABLE_PERF_MORPH_SSE42 1 // cv::erode, cv::dilate optimizations problem
|
||||
#define IPP_DISABLE_PERF_MAG_SSE42 1 // cv::magnitude optimizations problem
|
||||
#define IPP_DISABLE_PERF_BOX16S_SSE42 1 // cv::boxFilter optimizations problem
|
||||
|
||||
#ifdef HAVE_IPP
|
||||
#include "ippversion.h"
|
||||
@@ -229,7 +218,7 @@ CV_EXPORTS void scalarToRawData(const cv::Scalar& s, void* buf, int type, int un
|
||||
|
||||
#define IPP_VERSION_X100 (IPP_VERSION_MAJOR * 100 + IPP_VERSION_MINOR*10 + IPP_VERSION_UPDATE)
|
||||
|
||||
#ifdef HAVE_IPP_ICV_ONLY
|
||||
#ifdef HAVE_IPP_ICV
|
||||
#define ICV_BASE
|
||||
#if IPP_VERSION_X100 >= 201700
|
||||
#include "ippicv.h"
|
||||
@@ -241,6 +230,7 @@ CV_EXPORTS void scalarToRawData(const cv::Scalar& s, void* buf, int type, int un
|
||||
#endif
|
||||
#ifdef HAVE_IPP_IW
|
||||
#include "iw++/iw.hpp"
|
||||
#include "iw/iw_ll.h"
|
||||
#endif
|
||||
|
||||
#if IPP_VERSION_X100 >= 201700
|
||||
@@ -251,6 +241,17 @@ CV_EXPORTS void scalarToRawData(const cv::Scalar& s, void* buf, int type, int un
|
||||
|
||||
#define setIppErrorStatus() cv::ipp::setIppStatus(-1, CV_Func, __FILE__, __LINE__)
|
||||
|
||||
#define ippCPUID_AVX512_SKX (ippCPUID_AVX512F|ippCPUID_AVX512CD|ippCPUID_AVX512VL|ippCPUID_AVX512BW|ippCPUID_AVX512DQ)
|
||||
#define ippCPUID_AVX512_KNL (ippCPUID_AVX512F|ippCPUID_AVX512CD|ippCPUID_AVX512PF|ippCPUID_AVX512ER)
|
||||
|
||||
namespace cv
|
||||
{
|
||||
namespace ipp
|
||||
{
|
||||
CV_EXPORTS unsigned long long getIppTopFeatures(); // Returns top major enabled IPP feature flag
|
||||
}
|
||||
}
|
||||
|
||||
static inline IppiSize ippiSize(size_t width, size_t height)
|
||||
{
|
||||
IppiSize size = { (int)width, (int)height };
|
||||
@@ -322,7 +323,43 @@ static inline IppDataType ippiGetDataType(int depth)
|
||||
(IppDataType)-1;
|
||||
}
|
||||
|
||||
static inline int ippiSuggestThreadsNum(size_t width, size_t height, size_t elemSize, double multiplier)
|
||||
{
|
||||
int threads = cv::getNumThreads();
|
||||
if(threads > 1 && height >= 64)
|
||||
{
|
||||
size_t opMemory = (int)(width*height*elemSize*multiplier);
|
||||
int l2cache = 0;
|
||||
#if IPP_VERSION_X100 >= 201700
|
||||
ippGetL2CacheSize(&l2cache);
|
||||
#endif
|
||||
if(!l2cache)
|
||||
l2cache = 1 << 18;
|
||||
|
||||
return IPP_MAX(1, (IPP_MIN((int)(opMemory/l2cache), threads)));
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
static inline int ippiSuggestThreadsNum(const cv::Mat &image, double multiplier)
|
||||
{
|
||||
return ippiSuggestThreadsNum(image.cols, image.rows, image.elemSize(), multiplier);
|
||||
}
|
||||
|
||||
#ifdef HAVE_IPP_IW
|
||||
static inline bool ippiCheckAnchor(int x, int y, int kernelWidth, int kernelHeight)
|
||||
{
|
||||
if(x != ((kernelWidth-1)/2) || y != ((kernelHeight-1)/2))
|
||||
return 0;
|
||||
else
|
||||
return 1;
|
||||
}
|
||||
|
||||
static inline ::ipp::IwiSize ippiGetSize(const cv::Size & size)
|
||||
{
|
||||
return ::ipp::IwiSize((IwSize)size.width, (IwSize)size.height);
|
||||
}
|
||||
|
||||
static inline IwiDerivativeType ippiGetDerivType(int dx, int dy, bool nvert)
|
||||
{
|
||||
return (dx == 1 && dy == 0) ? ((nvert)?iwiDerivNVerFirst:iwiDerivVerFirst) :
|
||||
@@ -341,10 +378,10 @@ static inline void ippiGetImage(const cv::Mat &src, ::ipp::IwiImage &dst)
|
||||
cv::Point offset;
|
||||
src.locateROI(origSize, offset);
|
||||
|
||||
inMemBorder.borderLeft = (Ipp32u)offset.x;
|
||||
inMemBorder.borderTop = (Ipp32u)offset.y;
|
||||
inMemBorder.borderRight = (Ipp32u)(origSize.width - src.cols - offset.x);
|
||||
inMemBorder.borderBottom = (Ipp32u)(origSize.height - src.rows - offset.y);
|
||||
inMemBorder.left = (IwSize)offset.x;
|
||||
inMemBorder.top = (IwSize)offset.y;
|
||||
inMemBorder.right = (IwSize)(origSize.width - src.cols - offset.x);
|
||||
inMemBorder.bottom = (IwSize)(origSize.height - src.rows - offset.y);
|
||||
}
|
||||
|
||||
dst.Init(ippiSize(src.size()), ippiGetDataType(src.depth()), src.channels(), inMemBorder, (void*)src.ptr(), src.step);
|
||||
@@ -357,7 +394,7 @@ static inline ::ipp::IwiImage ippiGetImage(const cv::Mat &src)
|
||||
return image;
|
||||
}
|
||||
|
||||
static inline IppiBorderType ippiGetBorder(::ipp::IwiImage &image, int ocvBorderType, IppiBorderSize &borderSize)
|
||||
static inline IppiBorderType ippiGetBorder(::ipp::IwiImage &image, int ocvBorderType, ipp::IwiBorderSize &borderSize)
|
||||
{
|
||||
int inMemFlags = 0;
|
||||
IppiBorderType border = ippiGetBorderType(ocvBorderType & ~cv::BORDER_ISOLATED);
|
||||
@@ -366,91 +403,60 @@ static inline IppiBorderType ippiGetBorder(::ipp::IwiImage &image, int ocvBorder
|
||||
|
||||
if(!(ocvBorderType & cv::BORDER_ISOLATED))
|
||||
{
|
||||
if(image.m_inMemSize.borderLeft)
|
||||
if(image.m_inMemSize.left)
|
||||
{
|
||||
if(image.m_inMemSize.borderLeft >= borderSize.borderLeft)
|
||||
if(image.m_inMemSize.left >= borderSize.left)
|
||||
inMemFlags |= ippBorderInMemLeft;
|
||||
else
|
||||
return (IppiBorderType)0;
|
||||
}
|
||||
else
|
||||
borderSize.borderLeft = 0;
|
||||
if(image.m_inMemSize.borderTop)
|
||||
borderSize.left = 0;
|
||||
if(image.m_inMemSize.top)
|
||||
{
|
||||
if(image.m_inMemSize.borderTop >= borderSize.borderTop)
|
||||
if(image.m_inMemSize.top >= borderSize.top)
|
||||
inMemFlags |= ippBorderInMemTop;
|
||||
else
|
||||
return (IppiBorderType)0;
|
||||
}
|
||||
else
|
||||
borderSize.borderTop = 0;
|
||||
if(image.m_inMemSize.borderRight)
|
||||
borderSize.top = 0;
|
||||
if(image.m_inMemSize.right)
|
||||
{
|
||||
if(image.m_inMemSize.borderRight >= borderSize.borderRight)
|
||||
if(image.m_inMemSize.right >= borderSize.right)
|
||||
inMemFlags |= ippBorderInMemRight;
|
||||
else
|
||||
return (IppiBorderType)0;
|
||||
}
|
||||
else
|
||||
borderSize.borderRight = 0;
|
||||
if(image.m_inMemSize.borderBottom)
|
||||
borderSize.right = 0;
|
||||
if(image.m_inMemSize.bottom)
|
||||
{
|
||||
if(image.m_inMemSize.borderBottom >= borderSize.borderBottom)
|
||||
if(image.m_inMemSize.bottom >= borderSize.bottom)
|
||||
inMemFlags |= ippBorderInMemBottom;
|
||||
else
|
||||
return (IppiBorderType)0;
|
||||
}
|
||||
else
|
||||
borderSize.borderBottom = 0;
|
||||
borderSize.bottom = 0;
|
||||
}
|
||||
else
|
||||
borderSize.borderLeft = borderSize.borderRight = borderSize.borderTop = borderSize.borderBottom = 0;
|
||||
borderSize.left = borderSize.right = borderSize.top = borderSize.bottom = 0;
|
||||
|
||||
return (IppiBorderType)(border|inMemFlags);
|
||||
}
|
||||
|
||||
static inline ::ipp::IwValue ippiGetValue(const cv::Scalar &scalar)
|
||||
static inline ::ipp::IwValueFloat ippiGetValue(const cv::Scalar &scalar)
|
||||
{
|
||||
return ::ipp::IwValue(scalar[0], scalar[1], scalar[2], scalar[3]);
|
||||
return ::ipp::IwValueFloat(scalar[0], scalar[1], scalar[2], scalar[3]);
|
||||
}
|
||||
|
||||
static inline int ippiSuggestThreadsNum(const ::ipp::IwiImage &image, double multiplier)
|
||||
{
|
||||
int threads = cv::getNumThreads();
|
||||
if(image.m_size.height > threads)
|
||||
{
|
||||
size_t opMemory = (int)(image.m_step*image.m_size.height*multiplier);
|
||||
int l2cache = 0;
|
||||
#if IPP_VERSION_X100 >= 201700
|
||||
ippGetL2CacheSize(&l2cache);
|
||||
#endif
|
||||
if(!l2cache)
|
||||
l2cache = 1 << 18;
|
||||
|
||||
return IPP_MAX(1, (IPP_MIN((int)(opMemory/l2cache), threads)));
|
||||
}
|
||||
return 1;
|
||||
return ippiSuggestThreadsNum(image.m_size.width, image.m_size.height, image.m_typeSize*image.m_channels, multiplier);
|
||||
}
|
||||
#endif
|
||||
|
||||
static inline int ippiSuggestThreadsNum(const cv::Mat &image, double multiplier)
|
||||
{
|
||||
int threads = cv::getNumThreads();
|
||||
if(image.rows > threads)
|
||||
{
|
||||
size_t opMemory = (int)(image.total()*multiplier);
|
||||
int l2cache = 0;
|
||||
#if IPP_VERSION_X100 >= 201700
|
||||
ippGetL2CacheSize(&l2cache);
|
||||
#endif
|
||||
if(!l2cache)
|
||||
l2cache = 1 << 18;
|
||||
|
||||
return IPP_MAX(1, (IPP_MIN((int)(opMemory/l2cache), threads)));
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
// IPP temporary buffer helper
|
||||
template<typename T>
|
||||
class IppAutoBuffer
|
||||
|
||||
@@ -86,12 +86,6 @@ static MergeFunc getMergeFunc(int depth)
|
||||
}
|
||||
|
||||
#ifdef HAVE_IPP
|
||||
#ifdef HAVE_IPP_IW
|
||||
extern "C" {
|
||||
IW_DECL(IppStatus) llwiCopySplit(const void *pSrc, int srcStep, void* const pDstOrig[], int dstStep,
|
||||
IppiSize size, int typeSize, int channels);
|
||||
}
|
||||
#endif
|
||||
|
||||
namespace cv {
|
||||
static bool ipp_split(const Mat& src, Mat* mv, int channels)
|
||||
@@ -114,7 +108,7 @@ static bool ipp_split(const Mat& src, Mat* mv, int channels)
|
||||
return false;
|
||||
}
|
||||
|
||||
return CV_INSTRUMENT_FUN_IPP(llwiCopySplit, src.ptr(), (int)src.step, dstPtrs, (int)dstStep, size, (int)src.elemSize1(), channels) >= 0;
|
||||
return CV_INSTRUMENT_FUN_IPP(llwiCopySplit, src.ptr(), (int)src.step, dstPtrs, (int)dstStep, size, (int)src.elemSize1(), channels, 0) >= 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -132,7 +126,7 @@ static bool ipp_split(const Mat& src, Mat* mv, int channels)
|
||||
|
||||
for( size_t i = 0; i < it.nplanes; i++, ++it )
|
||||
{
|
||||
if(CV_INSTRUMENT_FUN_IPP(llwiCopySplit, ptrs[0], 0, (void**)&ptrs[1], 0, size, (int)src.elemSize1(), channels) < 0)
|
||||
if(CV_INSTRUMENT_FUN_IPP(llwiCopySplit, ptrs[0], 0, (void**)&ptrs[1], 0, size, (int)src.elemSize1(), channels, 0) < 0)
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
@@ -273,12 +267,6 @@ void cv::split(InputArray _m, OutputArrayOfArrays _mv)
|
||||
}
|
||||
|
||||
#ifdef HAVE_IPP
|
||||
#ifdef HAVE_IPP_IW
|
||||
extern "C" {
|
||||
IW_DECL(IppStatus) llwiCopyMerge(const void* const pSrc[], int srcStep, void *pDst, int dstStep,
|
||||
IppiSize size, int typeSize, int channels);
|
||||
}
|
||||
#endif
|
||||
|
||||
namespace cv {
|
||||
static bool ipp_merge(const Mat* mv, Mat& dst, int channels)
|
||||
@@ -301,7 +289,7 @@ static bool ipp_merge(const Mat* mv, Mat& dst, int channels)
|
||||
return false;
|
||||
}
|
||||
|
||||
return CV_INSTRUMENT_FUN_IPP(llwiCopyMerge, srcPtrs, (int)srcStep, dst.ptr(), (int)dst.step, size, (int)mv[0].elemSize1(), channels) >= 0;
|
||||
return CV_INSTRUMENT_FUN_IPP(llwiCopyMerge, srcPtrs, (int)srcStep, dst.ptr(), (int)dst.step, size, (int)mv[0].elemSize1(), channels, 0) >= 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -319,7 +307,7 @@ static bool ipp_merge(const Mat* mv, Mat& dst, int channels)
|
||||
|
||||
for( size_t i = 0; i < it.nplanes; i++, ++it )
|
||||
{
|
||||
if(CV_INSTRUMENT_FUN_IPP(llwiCopyMerge, (const void**)&ptrs[1], 0, ptrs[0], 0, size, (int)mv[0].elemSize1(), channels) < 0)
|
||||
if(CV_INSTRUMENT_FUN_IPP(llwiCopyMerge, (const void**)&ptrs[1], 0, ptrs[0], 0, size, (int)mv[0].elemSize1(), channels, 0) < 0)
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
@@ -820,16 +808,10 @@ void cv::mixChannels(InputArrayOfArrays src, InputOutputArrayOfArrays dst,
|
||||
}
|
||||
|
||||
#ifdef HAVE_IPP
|
||||
#ifdef HAVE_IPP_IW
|
||||
extern "C" {
|
||||
IW_DECL(IppStatus) llwiCopyMixed(const void *pSrc, int srcStep, int srcChannels, void *pDst, int dstStep, int dstChannels,
|
||||
IppiSize size, int typeSize, int channelsShift);
|
||||
}
|
||||
#endif
|
||||
|
||||
namespace cv
|
||||
{
|
||||
static bool ipp_extractInsertChannel(const Mat &src, Mat &dst, int channel)
|
||||
static bool ipp_extractChannel(const Mat &src, Mat &dst, int channel)
|
||||
{
|
||||
#ifdef HAVE_IPP_IW
|
||||
CV_INSTRUMENT_REGION_IPP()
|
||||
@@ -840,14 +822,11 @@ static bool ipp_extractInsertChannel(const Mat &src, Mat &dst, int channel)
|
||||
if(src.dims != dst.dims)
|
||||
return false;
|
||||
|
||||
if(srcChannels == dstChannels || (srcChannels != 1 && dstChannels != 1))
|
||||
return false;
|
||||
|
||||
if(src.dims <= 2)
|
||||
{
|
||||
IppiSize size = ippiSize(src.size());
|
||||
|
||||
return CV_INSTRUMENT_FUN_IPP(llwiCopyMixed, src.ptr(), (int)src.step, srcChannels, dst.ptr(), (int)dst.step, dstChannels, size, (int)src.elemSize1(), channel) >= 0;
|
||||
return CV_INSTRUMENT_FUN_IPP(llwiCopyChannel, src.ptr(), (int)src.step, srcChannels, channel, dst.ptr(), (int)dst.step, dstChannels, 0, size, (int)src.elemSize1()) >= 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -859,7 +838,45 @@ static bool ipp_extractInsertChannel(const Mat &src, Mat &dst, int channel)
|
||||
|
||||
for( size_t i = 0; i < it.nplanes; i++, ++it )
|
||||
{
|
||||
if(CV_INSTRUMENT_FUN_IPP(llwiCopyMixed, ptrs[0], 0, srcChannels, ptrs[1], 0, dstChannels, size, (int)src.elemSize1(), channel) < 0)
|
||||
if(CV_INSTRUMENT_FUN_IPP(llwiCopyChannel, ptrs[0], 0, srcChannels, channel, ptrs[1], 0, dstChannels, 0, size, (int)src.elemSize1()) < 0)
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
#else
|
||||
CV_UNUSED(src); CV_UNUSED(dst); CV_UNUSED(channel);
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
|
||||
static bool ipp_insertChannel(const Mat &src, Mat &dst, int channel)
|
||||
{
|
||||
#ifdef HAVE_IPP_IW
|
||||
CV_INSTRUMENT_REGION_IPP()
|
||||
|
||||
int srcChannels = src.channels();
|
||||
int dstChannels = dst.channels();
|
||||
|
||||
if(src.dims != dst.dims)
|
||||
return false;
|
||||
|
||||
if(src.dims <= 2)
|
||||
{
|
||||
IppiSize size = ippiSize(src.size());
|
||||
|
||||
return CV_INSTRUMENT_FUN_IPP(llwiCopyChannel, src.ptr(), (int)src.step, srcChannels, 0, dst.ptr(), (int)dst.step, dstChannels, channel, size, (int)src.elemSize1()) >= 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
const Mat *arrays[] = {&dst, NULL};
|
||||
uchar *ptrs[2] = {NULL};
|
||||
NAryMatIterator it(arrays, ptrs);
|
||||
|
||||
IppiSize size = {(int)it.size, 1};
|
||||
|
||||
for( size_t i = 0; i < it.nplanes; i++, ++it )
|
||||
{
|
||||
if(CV_INSTRUMENT_FUN_IPP(llwiCopyChannel, ptrs[0], 0, srcChannels, 0, ptrs[1], 0, dstChannels, channel, size, (int)src.elemSize1()) < 0)
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
@@ -893,7 +910,7 @@ void cv::extractChannel(InputArray _src, OutputArray _dst, int coi)
|
||||
_dst.create(src.dims, &src.size[0], depth);
|
||||
Mat dst = _dst.getMat();
|
||||
|
||||
CV_IPP_RUN_FAST(ipp_extractInsertChannel(src, dst, coi))
|
||||
CV_IPP_RUN_FAST(ipp_extractChannel(src, dst, coi))
|
||||
|
||||
mixChannels(&src, 1, &dst, 1, ch, 1);
|
||||
}
|
||||
@@ -917,7 +934,7 @@ void cv::insertChannel(InputArray _src, InputOutputArray _dst, int coi)
|
||||
|
||||
Mat src = _src.getMat(), dst = _dst.getMat();
|
||||
|
||||
CV_IPP_RUN_FAST(ipp_extractInsertChannel(src, dst, coi))
|
||||
CV_IPP_RUN_FAST(ipp_insertChannel(src, dst, coi))
|
||||
|
||||
mixChannels(&src, 1, &dst, 1, ch, 1);
|
||||
}
|
||||
@@ -5152,7 +5169,7 @@ static bool ipp_convertTo(Mat &src, Mat &dst, double alpha, double beta)
|
||||
iwSrc.Init(ippiSize(sz), srcDepth, 1, NULL, (void*)src.ptr(), src.step);
|
||||
iwDst.Init(ippiSize(sz), dstDepth, 1, NULL, (void*)dst.ptr(), dst.step);
|
||||
|
||||
CV_INSTRUMENT_FUN_IPP(::ipp::iwiScale, &iwSrc, &iwDst, alpha, beta, mode);
|
||||
CV_INSTRUMENT_FUN_IPP(::ipp::iwiScale, iwSrc, iwDst, alpha, beta, ::ipp::IwiScaleParams(mode));
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -5168,7 +5185,7 @@ static bool ipp_convertTo(Mat &src, Mat &dst, double alpha, double beta)
|
||||
iwSrc.m_ptr = ptrs[0];
|
||||
iwDst.m_ptr = ptrs[1];
|
||||
|
||||
CV_INSTRUMENT_FUN_IPP(::ipp::iwiScale, &iwSrc, &iwDst, alpha, beta, mode);
|
||||
CV_INSTRUMENT_FUN_IPP(::ipp::iwiScale, iwSrc, iwDst, alpha, beta, ::ipp::IwiScaleParams(mode));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+11
-23
@@ -49,18 +49,6 @@
|
||||
#include "precomp.hpp"
|
||||
#include "opencl_kernels_core.hpp"
|
||||
|
||||
#ifdef HAVE_IPP_IW
|
||||
extern "C" {
|
||||
IW_DECL(IppStatus) llwiCopyMask(const void *pSrc, int srcStep, void *pDst, int dstStep,
|
||||
IppiSize size, int typeSize, int channels, const Ipp8u *pMask, int maskStep);
|
||||
IW_DECL(IppStatus) llwiSet(const double *pValue, void *pDst, int dstStep,
|
||||
IppiSize size, IppDataType dataType, int channels);
|
||||
IW_DECL(IppStatus) llwiSetMask(const double *pValue, void *pDst, int dstStep,
|
||||
IppiSize size, IppDataType dataType, int channels, const Ipp8u *pMask, int maskStep);
|
||||
IW_DECL(IppStatus) llwiCopyMakeBorder(const void *pSrc, IppSizeL srcStep, void *pDst, IppSizeL dstStep,
|
||||
IppiSizeL size, IppDataType dataType, int channels, IppiBorderSize *pBorderSize, IppiBorderType border, const Ipp64f *pBorderVal);
|
||||
}
|
||||
#endif
|
||||
|
||||
namespace cv
|
||||
{
|
||||
@@ -480,9 +468,9 @@ static bool ipp_Mat_setTo_Mat(Mat &dst, Mat &_val, Mat &mask)
|
||||
|
||||
if(dst.dims <= 2)
|
||||
{
|
||||
IppiSize size = ippiSize(dst.size());
|
||||
IppDataType dataType = ippiGetDataType(dst.depth());
|
||||
::ipp::IwValue s;
|
||||
IppiSize size = ippiSize(dst.size());
|
||||
IppDataType dataType = ippiGetDataType(dst.depth());
|
||||
::ipp::IwValueFloat s;
|
||||
convertAndUnrollScalar(_val, CV_MAKETYPE(CV_64F, dst.channels()), (uchar*)((Ipp64f*)s), 1);
|
||||
|
||||
return CV_INSTRUMENT_FUN_IPP(llwiSetMask, s, dst.ptr(), (int)dst.step, size, dataType, dst.channels(), mask.ptr(), (int)mask.step) >= 0;
|
||||
@@ -493,9 +481,9 @@ static bool ipp_Mat_setTo_Mat(Mat &dst, Mat &_val, Mat &mask)
|
||||
uchar *ptrs[2] = {NULL};
|
||||
NAryMatIterator it(arrays, ptrs);
|
||||
|
||||
IppiSize size = {(int)it.size, 1};
|
||||
IppDataType dataType = ippiGetDataType(dst.depth());
|
||||
::ipp::IwValue s;
|
||||
IppiSize size = {(int)it.size, 1};
|
||||
IppDataType dataType = ippiGetDataType(dst.depth());
|
||||
::ipp::IwValueFloat s;
|
||||
convertAndUnrollScalar(_val, CV_MAKETYPE(CV_64F, dst.channels()), (uchar*)((Ipp64f*)s), 1);
|
||||
|
||||
for( size_t i = 0; i < it.nplanes; i++, ++it)
|
||||
@@ -717,7 +705,7 @@ static bool ipp_flip(Mat &src, Mat &dst, int flip_mode)
|
||||
::ipp::IwiImage iwSrc = ippiGetImage(src);
|
||||
::ipp::IwiImage iwDst = ippiGetImage(dst);
|
||||
|
||||
CV_INSTRUMENT_FUN_IPP(::ipp::iwiMirror, &iwSrc, &iwDst, ippMode);
|
||||
CV_INSTRUMENT_FUN_IPP(::ipp::iwiMirror, iwSrc, iwDst, ippMode);
|
||||
}
|
||||
catch(::ipp::IwException)
|
||||
{
|
||||
@@ -1155,13 +1143,13 @@ static bool ipp_copyMakeBorder( Mat &_src, Mat &_dst, int top, int bottom,
|
||||
if(_src.dims > 2)
|
||||
return false;
|
||||
|
||||
Rect dstRect(borderSize.borderLeft, borderSize.borderTop,
|
||||
_dst.cols - borderSize.borderRight - borderSize.borderLeft,
|
||||
_dst.rows - borderSize.borderBottom - borderSize.borderTop);
|
||||
Rect dstRect(borderSize.left, borderSize.top,
|
||||
_dst.cols - borderSize.right - borderSize.left,
|
||||
_dst.rows - borderSize.bottom - borderSize.top);
|
||||
Mat subDst = Mat(_dst, dstRect);
|
||||
Mat *pSrc = &_src;
|
||||
|
||||
return CV_INSTRUMENT_FUN_IPP(llwiCopyMakeBorder, pSrc->ptr(), pSrc->step, subDst.ptr(), subDst.step, size, dataType, _src.channels(), &borderSize, borderType, &value[0]) >= 0;
|
||||
return CV_INSTRUMENT_FUN_IPP(llwiCopyMakeBorder, pSrc->ptr(), pSrc->step, subDst.ptr(), subDst.step, size, dataType, _src.channels(), borderSize, borderType, &value[0]) >= 0;
|
||||
#else
|
||||
CV_UNUSED(_src); CV_UNUSED(_dst); CV_UNUSED(top); CV_UNUSED(bottom); CV_UNUSED(left); CV_UNUSED(right);
|
||||
CV_UNUSED(_borderType); CV_UNUSED(value);
|
||||
|
||||
@@ -44,7 +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);
|
||||
CV_IPP_RUN(!IPP_DISABLE_PERF_MAG_SSE42 || (ipp::getIppFeatures()&ippCPUID_AVX), CV_INSTRUMENT_FUN_IPP(ippsMagnitude_32f, x, y, mag, len) >= 0);
|
||||
// SSE42 performance issues
|
||||
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);
|
||||
@@ -55,7 +56,8 @@ void magnitude64f(const double* x, const double* y, double* mag, int len)
|
||||
CV_INSTRUMENT_REGION()
|
||||
|
||||
CALL_HAL(magnitude64f, cv_hal_magnitude64f, x, y, mag, len);
|
||||
CV_IPP_RUN(!IPP_DISABLE_PERF_MAG_SSE42 || (ipp::getIppFeatures()&ippCPUID_AVX), CV_INSTRUMENT_FUN_IPP(ippsMagnitude_64f, x, y, mag, len) >= 0);
|
||||
// SSE42 performance issues
|
||||
CV_IPP_RUN(IPP_VERSION_X100 > 201800 || cv::ipp::getIppTopFeatures() != ippCPUID_SSE42, CV_INSTRUMENT_FUN_IPP(ippsMagnitude_64f, x, y, mag, len) >= 0);
|
||||
|
||||
CV_CPU_DISPATCH(magnitude64f, (x, y, mag, len),
|
||||
CV_CPU_DISPATCH_MODES_ALL);
|
||||
@@ -91,7 +93,6 @@ void sqrt32f(const float* src, float* dst, int len)
|
||||
CV_INSTRUMENT_REGION()
|
||||
|
||||
CALL_HAL(sqrt32f, cv_hal_sqrt32f, src, dst, len);
|
||||
CV_IPP_RUN_FAST(CV_INSTRUMENT_FUN_IPP(ippsSqrt_32f_A21, src, dst, len) >= 0);
|
||||
|
||||
CV_CPU_DISPATCH(sqrt32f, (src, dst, len),
|
||||
CV_CPU_DISPATCH_MODES_ALL);
|
||||
@@ -103,7 +104,6 @@ void sqrt64f(const double* src, double* dst, int len)
|
||||
CV_INSTRUMENT_REGION()
|
||||
|
||||
CALL_HAL(sqrt64f, cv_hal_sqrt64f, src, dst, len);
|
||||
CV_IPP_RUN_FAST(CV_INSTRUMENT_FUN_IPP(ippsSqrt_64f_A50, src, dst, len) >= 0);
|
||||
|
||||
CV_CPU_DISPATCH(sqrt64f, (src, dst, len),
|
||||
CV_CPU_DISPATCH_MODES_ALL);
|
||||
|
||||
@@ -3101,7 +3101,7 @@ static double dotProd_8u(const uchar* src1, const uchar* src2, int len)
|
||||
{
|
||||
double r = 0;
|
||||
#if ARITHM_USE_IPP
|
||||
CV_IPP_RUN_FAST(CV_INSTRUMENT_FUN_IPP(ippiDotProd_8u64f_C1R, src1, len*sizeof(uchar), src2, len*sizeof(uchar), ippiSize(len, 1), &r) >= 0, r);
|
||||
CV_IPP_RUN(IPP_VERSION_X100 > 201800 || cv::ipp::getIppTopFeatures() != ippCPUID_SSE42, CV_INSTRUMENT_FUN_IPP(ippiDotProd_8u64f_C1R, src1, len*sizeof(uchar), src2, len*sizeof(uchar), ippiSize(len, 1), &r) >= 0, r);
|
||||
#endif
|
||||
int i = 0;
|
||||
|
||||
|
||||
@@ -4356,7 +4356,6 @@ template<typename T> static void sortIdx_( const Mat& src, Mat& dst, int flags )
|
||||
}
|
||||
|
||||
#ifdef HAVE_IPP
|
||||
#if !IPP_DISABLE_SORT_IDX
|
||||
typedef IppStatus (CV_STDCALL *IppSortIndexFunc)(const void* pSrc, Ipp32s srcStrideBytes, Ipp32s *pDstIndx, int len, Ipp8u *pBuffer);
|
||||
|
||||
static IppSortIndexFunc getSortIndexFunc(int depth, bool sortDescending)
|
||||
@@ -4435,7 +4434,6 @@ static bool ipp_sortIdx( const Mat& src, Mat& dst, int flags )
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
typedef void (*SortFunc)(const Mat& src, Mat& dst, int flags);
|
||||
}
|
||||
@@ -4472,9 +4470,8 @@ void cv::sortIdx( InputArray _src, OutputArray _dst, int flags )
|
||||
_dst.release();
|
||||
_dst.create( src.size(), CV_32S );
|
||||
dst = _dst.getMat();
|
||||
#if !IPP_DISABLE_SORT_IDX
|
||||
|
||||
CV_IPP_RUN_FAST(ipp_sortIdx(src, dst, flags));
|
||||
#endif
|
||||
|
||||
static SortFunc tab[] =
|
||||
{
|
||||
|
||||
@@ -257,7 +257,8 @@ struct CoreTLSData
|
||||
//#ifdef HAVE_OPENCL
|
||||
device(0), useOpenCL(-1),
|
||||
//#endif
|
||||
useIPP(-1)
|
||||
useIPP(-1),
|
||||
useIPP_NE(-1)
|
||||
#ifdef HAVE_TEGRA_OPTIMIZATION
|
||||
,useTegra(-1)
|
||||
#endif
|
||||
@@ -272,7 +273,8 @@ struct CoreTLSData
|
||||
ocl::Queue oclQueue; // the queue used for running a kernel, see also getQueue, Kernel::run
|
||||
int useOpenCL; // 1 - use, 0 - do not use, -1 - auto/not initialized
|
||||
//#endif
|
||||
int useIPP; // 1 - use, 0 - do not use, -1 - auto/not initialized
|
||||
int useIPP; // 1 - use, 0 - do not use, -1 - auto/not initialized
|
||||
int useIPP_NE; // 1 - use, 0 - do not use, -1 - auto/not initialized
|
||||
#ifdef HAVE_TEGRA_OPTIMIZATION
|
||||
int useTegra; // 1 - use, 0 - do not use, -1 - auto/not initialized
|
||||
#endif
|
||||
|
||||
@@ -1294,6 +1294,12 @@ static bool ipp_countNonZero( Mat &src, int &res )
|
||||
{
|
||||
CV_INSTRUMENT_REGION_IPP()
|
||||
|
||||
#if IPP_VERSION_X100 < 201801
|
||||
// Poor performance of SSE42
|
||||
if(cv::ipp::getIppTopFeatures() == ippCPUID_SSE42)
|
||||
return false;
|
||||
#endif
|
||||
|
||||
Ipp32s count = 0;
|
||||
int depth = src.depth();
|
||||
|
||||
@@ -2531,15 +2537,16 @@ static bool ipp_minMaxIdx(Mat &src, double* _minVal, double* _maxVal, int* _minI
|
||||
#if IPP_VERSION_X100 >= 700
|
||||
CV_INSTRUMENT_REGION_IPP()
|
||||
|
||||
#if IPP_DISABLE_MINMAX_NAN_SSE42
|
||||
#if IPP_VERSION_X100 < 201800
|
||||
// cv::minMaxIdx problem with NaN input
|
||||
// Disable 32F processing only
|
||||
if(src.depth() == CV_32F && !(ipp::getIppFeatures()&ippCPUID_AVX))
|
||||
if(src.depth() == CV_32F && cv::ipp::getIppTopFeatures() == ippCPUID_SSE42)
|
||||
return false;
|
||||
#endif
|
||||
|
||||
#if IPP_VERSION_X100 < 201801
|
||||
// cv::minMaxIdx problem with index positions on AVX
|
||||
#if IPP_VERSION_X100 < 201810
|
||||
if(!mask.empty() && _maxIdx && ipp::getIppFeatures()&ippCPUID_AVX)
|
||||
if(!mask.empty() && _maxIdx && cv::ipp::getIppTopFeatures() != ippCPUID_SSE42)
|
||||
return false;
|
||||
#endif
|
||||
|
||||
@@ -2550,8 +2557,8 @@ static bool ipp_minMaxIdx(Mat &src, double* _minVal, double* _maxVal, int* _minI
|
||||
IppiPoint minIdx = {-1, -1};
|
||||
IppiPoint maxIdx = {-1, -1};
|
||||
|
||||
float *pMinVal = (_minVal)?&minVal:NULL;
|
||||
float *pMaxVal = (_maxVal)?&maxVal:NULL;
|
||||
float *pMinVal = (_minVal || _minIdx)?&minVal:NULL;
|
||||
float *pMaxVal = (_maxVal || _maxIdx)?&maxVal:NULL;
|
||||
IppiPoint *pMinIdx = (_minIdx)?&minIdx:NULL;
|
||||
IppiPoint *pMaxIdx = (_maxIdx)?&maxIdx:NULL;
|
||||
|
||||
@@ -2564,6 +2571,8 @@ static bool ipp_minMaxIdx(Mat &src, double* _minVal, double* _maxVal, int* _minI
|
||||
ippMinMaxFun = ipp_minIdx_wrap;
|
||||
else if(_maxVal && !_maxIdx && _minVal && !_minIdx)
|
||||
ippMinMaxFun = ipp_minMax_wrap;
|
||||
else if(!_maxVal && !_maxIdx && !_minVal && !_minIdx)
|
||||
return false;
|
||||
else
|
||||
ippMinMaxFun = ipp_minMaxIndex_wrap;
|
||||
}
|
||||
@@ -2582,8 +2591,12 @@ static bool ipp_minMaxIdx(Mat &src, double* _minVal, double* _maxVal, int* _minI
|
||||
*_maxVal = maxVal;
|
||||
if(_minIdx)
|
||||
{
|
||||
#if IPP_VERSION_X100 < 201801
|
||||
// Should be just ippStsNoOperation check, but there is a bug in the function so we need additional checks
|
||||
if(status == ippStsNoOperation && !mask.empty() && !pMinIdx->x && !pMinIdx->y)
|
||||
#else
|
||||
if(status == ippStsNoOperation)
|
||||
#endif
|
||||
{
|
||||
_minIdx[0] = -1;
|
||||
_minIdx[1] = -1;
|
||||
@@ -2596,8 +2609,12 @@ static bool ipp_minMaxIdx(Mat &src, double* _minVal, double* _maxVal, int* _minI
|
||||
}
|
||||
if(_maxIdx)
|
||||
{
|
||||
#if IPP_VERSION_X100 < 201801
|
||||
// Should be just ippStsNoOperation check, but there is a bug in the function so we need additional checks
|
||||
if(status == ippStsNoOperation && !mask.empty() && !pMaxIdx->x && !pMaxIdx->y)
|
||||
#else
|
||||
if(status == ippStsNoOperation)
|
||||
#endif
|
||||
{
|
||||
_maxIdx[0] = -1;
|
||||
_maxIdx[1] = -1;
|
||||
|
||||
+164
-24
@@ -1909,55 +1909,146 @@ struct IPPInitSingleton
|
||||
public:
|
||||
IPPInitSingleton()
|
||||
{
|
||||
useIPP = true;
|
||||
ippStatus = 0;
|
||||
funcname = NULL;
|
||||
filename = NULL;
|
||||
linen = 0;
|
||||
ippFeatures = 0;
|
||||
useIPP = true;
|
||||
useIPP_NE = false;
|
||||
ippStatus = 0;
|
||||
funcname = NULL;
|
||||
filename = NULL;
|
||||
linen = 0;
|
||||
cpuFeatures = 0;
|
||||
ippFeatures = 0;
|
||||
ippTopFeatures = 0;
|
||||
pIppLibInfo = NULL;
|
||||
|
||||
ippStatus = ippGetCpuFeatures(&cpuFeatures, NULL);
|
||||
if(ippStatus < 0)
|
||||
{
|
||||
std::cerr << "ERROR: IPP cannot detect CPU features, IPP was disabled " << std::endl;
|
||||
useIPP = false;
|
||||
return;
|
||||
}
|
||||
ippFeatures = cpuFeatures;
|
||||
|
||||
bool unsupported = false;
|
||||
const char* pIppEnv = getenv("OPENCV_IPP");
|
||||
cv::String env = pIppEnv;
|
||||
if(env.size())
|
||||
{
|
||||
env = env.toLowerCase();
|
||||
if(env.substr(0, 2) == "ne")
|
||||
{
|
||||
useIPP_NE = true;
|
||||
env = env.substr(3, env.size());
|
||||
}
|
||||
|
||||
if(env == "disabled")
|
||||
{
|
||||
std::cerr << "WARNING: IPP was disabled by OPENCV_IPP environment variable" << std::endl;
|
||||
useIPP = false;
|
||||
}
|
||||
#if IPP_VERSION_X100 >= 900
|
||||
else if(env == "sse")
|
||||
ippFeatures = ippCPUID_SSE;
|
||||
else if(env == "sse2")
|
||||
ippFeatures = ippCPUID_SSE2;
|
||||
else if(env == "sse3")
|
||||
ippFeatures = ippCPUID_SSE3;
|
||||
else if(env == "ssse3")
|
||||
ippFeatures = ippCPUID_SSSE3;
|
||||
else if(env == "sse41")
|
||||
ippFeatures = ippCPUID_SSE41;
|
||||
else if(env == "sse42")
|
||||
ippFeatures = ippCPUID_SSE42;
|
||||
else if(env == "avx")
|
||||
ippFeatures = ippCPUID_AVX;
|
||||
{
|
||||
if(!(cpuFeatures&ippCPUID_SSE42))
|
||||
unsupported = true;
|
||||
ippFeatures = ippCPUID_MMX|ippCPUID_SSE|ippCPUID_SSE2|ippCPUID_SSE3|ippCPUID_SSSE3|ippCPUID_SSE41|ippCPUID_SSE42;
|
||||
ippFeatures |= (cpuFeatures&ippCPUID_AES);
|
||||
ippFeatures |= (cpuFeatures&ippCPUID_CLMUL);
|
||||
ippFeatures |= (cpuFeatures&ippCPUID_SHA);
|
||||
}
|
||||
else if(env == "avx2")
|
||||
ippFeatures = ippCPUID_AVX2;
|
||||
{
|
||||
if(!(cpuFeatures&ippCPUID_AVX2))
|
||||
unsupported = true;
|
||||
ippFeatures = ippCPUID_MMX|ippCPUID_SSE|ippCPUID_SSE2|ippCPUID_SSE3|ippCPUID_SSSE3|ippCPUID_SSE41|ippCPUID_SSE42|ippCPUID_AVX|ippCPUID_AVX2;
|
||||
ippFeatures |= (cpuFeatures&ippCPUID_AES);
|
||||
ippFeatures |= (cpuFeatures&ippCPUID_CLMUL);
|
||||
ippFeatures |= (cpuFeatures&ippCPUID_F16C);
|
||||
ippFeatures |= (cpuFeatures&ippCPUID_ADCOX);
|
||||
ippFeatures |= (cpuFeatures&ippCPUID_RDSEED);
|
||||
ippFeatures |= (cpuFeatures&ippCPUID_PREFETCHW);
|
||||
ippFeatures |= (cpuFeatures&ippCPUID_MPX);
|
||||
}
|
||||
#if defined (_M_AMD64) || defined (__x86_64__)
|
||||
else if(env == "avx512")
|
||||
{
|
||||
if(!(cpuFeatures&ippCPUID_AVX512F))
|
||||
unsupported = true;
|
||||
|
||||
ippFeatures = ippCPUID_MMX|ippCPUID_SSE|ippCPUID_SSE2|ippCPUID_SSE3|ippCPUID_SSSE3|ippCPUID_SSE41|ippCPUID_SSE42|ippCPUID_AVX|ippCPUID_AVX2|ippCPUID_AVX512F;
|
||||
ippFeatures |= (cpuFeatures&ippCPUID_AES);
|
||||
ippFeatures |= (cpuFeatures&ippCPUID_CLMUL);
|
||||
ippFeatures |= (cpuFeatures&ippCPUID_F16C);
|
||||
ippFeatures |= (cpuFeatures&ippCPUID_ADCOX);
|
||||
ippFeatures |= (cpuFeatures&ippCPUID_RDSEED);
|
||||
ippFeatures |= (cpuFeatures&ippCPUID_PREFETCHW);
|
||||
ippFeatures |= (cpuFeatures&ippCPUID_MPX);
|
||||
ippFeatures |= (cpuFeatures&ippCPUID_AVX512CD);
|
||||
ippFeatures |= (cpuFeatures&ippCPUID_AVX512VL);
|
||||
ippFeatures |= (cpuFeatures&ippCPUID_AVX512BW);
|
||||
ippFeatures |= (cpuFeatures&ippCPUID_AVX512DQ);
|
||||
ippFeatures |= (cpuFeatures&ippCPUID_AVX512ER);
|
||||
ippFeatures |= (cpuFeatures&ippCPUID_AVX512PF);
|
||||
ippFeatures |= (cpuFeatures&ippCPUID_AVX512VBMI);
|
||||
}
|
||||
#endif
|
||||
else
|
||||
std::cerr << "ERROR: Improper value of OPENCV_IPP: " << env.c_str() << std::endl;
|
||||
std::cerr << "ERROR: Improper value of OPENCV_IPP: " << env.c_str() << ". Correct values are: disabled, sse42, avx2, avx512 (Intel64 only)" << std::endl;
|
||||
}
|
||||
|
||||
if(unsupported)
|
||||
{
|
||||
std::cerr << "WARNING: selected IPP features are not supported by CPU. IPP was initialized with default features" << std::endl;
|
||||
ippFeatures = cpuFeatures;
|
||||
}
|
||||
|
||||
// Disable AVX1 since we don't track regressions for it. SSE42 will be used instead
|
||||
if(cpuFeatures&ippCPUID_AVX && !(cpuFeatures&ippCPUID_AVX2))
|
||||
ippFeatures &= ~ippCPUID_AVX;
|
||||
|
||||
// IPP integrations in OpenCV support only SSE4.2, AVX2 and AVX-512 optimizations.
|
||||
if(!(
|
||||
cpuFeatures&ippCPUID_AVX512F ||
|
||||
cpuFeatures&ippCPUID_AVX2 ||
|
||||
cpuFeatures&ippCPUID_SSE42
|
||||
))
|
||||
{
|
||||
useIPP = false;
|
||||
return;
|
||||
}
|
||||
|
||||
IPP_INITIALIZER(ippFeatures)
|
||||
ippFeatures = ippGetEnabledCpuFeatures();
|
||||
|
||||
// Detect top level optimizations to make comparison easier for optimizations dependent conditions
|
||||
if(ippFeatures&ippCPUID_AVX512F)
|
||||
{
|
||||
if((ippFeatures&ippCPUID_AVX512_SKX) == ippCPUID_AVX512_SKX)
|
||||
ippTopFeatures = ippCPUID_AVX512_SKX;
|
||||
else if((ippFeatures&ippCPUID_AVX512_KNL) == ippCPUID_AVX512_KNL)
|
||||
ippTopFeatures = ippCPUID_AVX512_KNL;
|
||||
else
|
||||
ippTopFeatures = ippCPUID_AVX512F; // Unknown AVX512 configuration
|
||||
}
|
||||
else if(ippFeatures&ippCPUID_AVX2)
|
||||
ippTopFeatures = ippCPUID_AVX2;
|
||||
else if(ippFeatures&ippCPUID_SSE42)
|
||||
ippTopFeatures = ippCPUID_SSE42;
|
||||
|
||||
pIppLibInfo = ippiGetLibVersion();
|
||||
}
|
||||
|
||||
bool useIPP;
|
||||
public:
|
||||
bool useIPP;
|
||||
bool useIPP_NE;
|
||||
|
||||
int ippStatus; // 0 - all is ok, -1 - IPP functions failed
|
||||
int ippStatus; // 0 - all is ok, -1 - IPP functions failed
|
||||
const char *funcname;
|
||||
const char *filename;
|
||||
int linen;
|
||||
Ipp64u ippFeatures;
|
||||
Ipp64u cpuFeatures;
|
||||
Ipp64u ippTopFeatures;
|
||||
const IppLibraryVersion *pIppLibInfo;
|
||||
};
|
||||
|
||||
static IPPInitSingleton& getIPPSingleton()
|
||||
@@ -1983,6 +2074,17 @@ int getIppFeatures()
|
||||
#endif
|
||||
}
|
||||
|
||||
unsigned long long getIppTopFeatures();
|
||||
|
||||
unsigned long long getIppTopFeatures()
|
||||
{
|
||||
#ifdef HAVE_IPP
|
||||
return getIPPSingleton().ippTopFeatures;
|
||||
#else
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
void setIppStatus(int status, const char * const _funcname, const char * const _filename, int _line)
|
||||
{
|
||||
#ifdef HAVE_IPP
|
||||
@@ -2013,6 +2115,19 @@ String getIppErrorLocation()
|
||||
#endif
|
||||
}
|
||||
|
||||
String getIppVersion()
|
||||
{
|
||||
#ifdef HAVE_IPP
|
||||
const IppLibraryVersion *pInfo = getIPPSingleton().pIppLibInfo;
|
||||
if(pInfo)
|
||||
return format("%s %s %s", pInfo->Name, pInfo->Version, pInfo->BuildDate);
|
||||
else
|
||||
return String("error");
|
||||
#else
|
||||
return String("disabled");
|
||||
#endif
|
||||
}
|
||||
|
||||
bool useIPP()
|
||||
{
|
||||
#ifdef HAVE_IPP
|
||||
@@ -2038,6 +2153,31 @@ void setUseIPP(bool flag)
|
||||
#endif
|
||||
}
|
||||
|
||||
bool useIPP_NE()
|
||||
{
|
||||
#ifdef HAVE_IPP
|
||||
CoreTLSData* data = getCoreTlsData().get();
|
||||
if(data->useIPP_NE < 0)
|
||||
{
|
||||
data->useIPP_NE = getIPPSingleton().useIPP_NE;
|
||||
}
|
||||
return (data->useIPP_NE > 0);
|
||||
#else
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
|
||||
void setUseIPP_NE(bool flag)
|
||||
{
|
||||
CoreTLSData* data = getCoreTlsData().get();
|
||||
#ifdef HAVE_IPP
|
||||
data->useIPP_NE = (getIPPSingleton().useIPP_NE)?flag:false;
|
||||
#else
|
||||
(void)flag;
|
||||
data->useIPP_NE = false;
|
||||
#endif
|
||||
}
|
||||
|
||||
} // namespace ipp
|
||||
|
||||
} // namespace cv
|
||||
|
||||
Reference in New Issue
Block a user