Commit bad149d7 authored by Alexander Alekhin's avatar Alexander Alekhin

Merge pull request #8828 from woodychow:multithreaded_gaussian

parents f935a16e f743603b
...@@ -2241,6 +2241,54 @@ static bool openvx_gaussianBlur(InputArray _src, OutputArray _dst, Size ksize, ...@@ -2241,6 +2241,54 @@ static bool openvx_gaussianBlur(InputArray _src, OutputArray _dst, Size ksize,
#endif #endif
#ifdef HAVE_IPP #ifdef HAVE_IPP
#define IPP_DISABLE_FILTERING_INMEM_PARTIAL 1 // IW 2017u2 has bug which doesn't allow use of partial inMem with tiling
#define IPP_GAUSSIANBLUR_PARALLEL 1
#ifdef HAVE_IPP_IW
class ipp_gaussianBlurParallel: public ParallelLoopBody
{
public:
ipp_gaussianBlurParallel(::ipp::IwiImage &src, ::ipp::IwiImage &dst, int kernelSize, float sigma, ::ipp::IwiBorderType &border, bool *pOk):
m_src(src), m_dst(dst), m_kernelSize(kernelSize), m_sigma(sigma), m_border(border), m_pOk(pOk) {
*m_pOk = true;
}
~ipp_gaussianBlurParallel()
{
}
virtual void operator() (const Range& range) const
{
CV_INSTRUMENT_REGION_IPP()
if(!*m_pOk)
return;
try
{
::ipp::IwiRoi roi = ::ipp::IwiRect(0, range.start, m_dst.m_size.width, range.end - range.start);
CV_INSTRUMENT_FUN_IPP(::ipp::iwiFilterGaussian, &m_src, &m_dst, m_kernelSize, m_sigma, m_border, &roi);
}
catch(::ipp::IwException e)
{
*m_pOk = false;
return;
}
}
private:
::ipp::IwiImage &m_src;
::ipp::IwiImage &m_dst;
int m_kernelSize;
float m_sigma;
::ipp::IwiBorderType &m_border;
volatile bool *m_pOk;
const ipp_gaussianBlurParallel& operator= (const ipp_gaussianBlurParallel&);
};
#endif
static bool ipp_GaussianBlur(InputArray _src, OutputArray _dst, Size ksize, static bool ipp_GaussianBlur(InputArray _src, OutputArray _dst, Size ksize,
double sigma1, double sigma2, int borderType ) double sigma1, double sigma2, int borderType )
{ {
...@@ -2272,7 +2320,23 @@ static bool ipp_GaussianBlur(InputArray _src, OutputArray _dst, Size ksize, ...@@ -2272,7 +2320,23 @@ static bool ipp_GaussianBlur(InputArray _src, OutputArray _dst, Size ksize,
if(!ippBorder.m_borderType) if(!ippBorder.m_borderType)
return false; return false;
CV_INSTRUMENT_FUN_IPP(::ipp::iwiFilterGaussian, &iwSrc, &iwDst, ksize.width, (float)sigma1, ippBorder); const bool disableThreading = IPP_DISABLE_FILTERING_INMEM_PARTIAL &&
((ippBorder.m_borderFlags)&ippBorderInMem) && ((ippBorder.m_borderFlags)&ippBorderInMem) != ippBorderInMem;
const int threads = ippiSuggestThreadsNum(iwDst, 2);
if(!disableThreading && IPP_GAUSSIANBLUR_PARALLEL && threads > 1) {
bool ok;
ipp_gaussianBlurParallel invoker(iwSrc, iwDst, ksize.width, (float) sigma1, ippBorder, &ok);
if(!ok)
return false;
const Range range(0, (int) iwDst.m_size.height);
parallel_for_(range, invoker, threads*4);
if(!ok)
return false;
} else {
CV_INSTRUMENT_FUN_IPP(::ipp::iwiFilterGaussian, &iwSrc, &iwDst, ksize.width, (float) sigma1, ippBorder);
}
} }
catch (::ipp::IwException ex) catch (::ipp::IwException ex)
{ {
...@@ -4255,24 +4319,23 @@ static bool ipp_bilateralFilter(Mat &src, Mat &dst, int d, double sigmaColor, do ...@@ -4255,24 +4319,23 @@ static bool ipp_bilateralFilter(Mat &src, Mat &dst, int d, double sigmaColor, do
if(!ippBorder.m_borderType) if(!ippBorder.m_borderType)
return false; return false;
// IW 2017u2 has bug which doesn't allow use of partial inMem with tiling const bool disableThreading = IPP_DISABLE_FILTERING_INMEM_PARTIAL &&
if((((ippBorder.m_borderFlags)&ippBorderInMem) && ((ippBorder.m_borderFlags)&ippBorderInMem) != ippBorderInMem)) ((ippBorder.m_borderFlags)&ippBorderInMem) && ((ippBorder.m_borderFlags)&ippBorderInMem) != ippBorderInMem;
return false; const int threads = ippiSuggestThreadsNum(iwDst, 2);
if(!disableThreading && IPP_BILATERAL_PARALLEL && threads > 1) {
bool ok = true; bool ok = true;
int threads = ippiSuggestThreadsNum(iwDst, 2); Range range(0, (int)iwDst.m_size.height);
Range range(0, (int)iwDst.m_size.height); ipp_bilateralFilterParallel invoker(iwSrc, iwDst, radius, valSquareSigma, posSquareSigma, ippBorder, &ok);
ipp_bilateralFilterParallel invoker(iwSrc, iwDst, radius, valSquareSigma, posSquareSigma, ippBorder, &ok); if(!ok)
if(!ok) return false;
return false;
if(IPP_BILATERAL_PARALLEL && threads > 1)
parallel_for_(range, invoker, threads*4); parallel_for_(range, invoker, threads*4);
else
invoker(range);
if(!ok) if(!ok)
return false; return false;
} else {
CV_INSTRUMENT_FUN_IPP(::ipp::iwiFilterBilateral, &iwSrc, &iwDst, radius, valSquareSigma, posSquareSigma, ippiFilterBilateralGauss, ippDistNormL1, ippBorder);
}
} }
catch (::ipp::IwException) catch (::ipp::IwException)
{ {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment