Optimize openCL version of reduce function

This commit is contained in:
vbystricky
2014-05-21 13:22:44 +04:00
parent ab2749d648
commit 169351b01d
2 changed files with 89 additions and 5 deletions

View File

@@ -3428,11 +3428,60 @@ static bool ocl_reduce(InputArray _src, OutputArray _dst,
const char * const ops[4] = { "OCL_CV_REDUCE_SUM", "OCL_CV_REDUCE_AVG",
"OCL_CV_REDUCE_MAX", "OCL_CV_REDUCE_MIN" };
char cvt[40];
ocl::Kernel k("reduce", ocl::core::reduce2_oclsrc,
format("-D %s -D dim=%d -D cn=%d -D ddepth=%d -D srcT=%s -D dstT=%s -D convertToDT=%s%s",
ops[op], dim, cn, ddepth, ocl::typeToStr(sdepth), ocl::typeToStr(ddepth),
ocl::convertTypeStr(sdepth, ddepth, 1, cvt),
doubleSupport ? " -D DOUBLE_SUPPORT" : ""));
const int min_opt_cols = 128;
if ((1 == dim) && (_src.cols() > min_opt_cols))
{
int buf_cols = 32;
cv::String build_opt_pre = format("-D BUF_COLS=%d -D %s -D dim=1 -D cn=%d -D ddepth=%d -D srcT=%s -D dstT=%s -D convertToDT=%s%s",
buf_cols, ops[op], cn, ddepth, ocl::typeToStr(sdepth), ocl::typeToStr(ddepth),
ocl::convertTypeStr(sdepth, ddepth, 1, cvt),
doubleSupport ? " -D DOUBLE_SUPPORT" : "");
ocl::Kernel kpre("reduce_horz_pre", ocl::core::reduce2_oclsrc, build_opt_pre);
if (kpre.empty())
return false;
cv::String build_opt_main = format("-D %s -D dim=1 -D cn=%d -D ddepth=%d -D srcT=%s -D dstT=%s -D convertToDT=noconvert%s",
ops[op], cn, ddepth, ocl::typeToStr(ddepth), ocl::typeToStr(ddepth),
doubleSupport ? " -D DOUBLE_SUPPORT" : "");
ocl::Kernel kmain("reduce", ocl::core::reduce2_oclsrc, build_opt_main);
if (kmain.empty())
return false;
UMat src = _src.getUMat();
Size dsize(1, src.rows);
_dst.create(dsize, dtype);
UMat dst = _dst.getUMat(), temp = dst;
if (op0 == CV_REDUCE_AVG && sdepth < CV_32S && ddepth0 < CV_32S)
temp.create(dsize, CV_32SC(cn));
UMat buf(src.rows, buf_cols, temp.type());
size_t globalSize[2] = { buf_cols, src.rows };
kpre.args(ocl::KernelArg::ReadOnly(src), ocl::KernelArg::WriteOnlyNoSize(buf));
if (!kpre.run(2, globalSize, NULL, false))
return false;
globalSize[0] = src.rows;
kmain.args(ocl::KernelArg::ReadOnly(buf), ocl::KernelArg::WriteOnlyNoSize(temp));
if (!kmain.run(1, globalSize, NULL, false))
return false;
if (op0 == CV_REDUCE_AVG)
temp.convertTo(dst, ddepth0, 1. / (dim == 0 ? src.rows : src.cols));
return true;
}
cv::String build_opt = format("-D %s -D dim=%d -D cn=%d -D ddepth=%d -D srcT=%s -D dstT=%s -D convertToDT=%s%s",
ops[op], dim, cn, ddepth, ocl::typeToStr(sdepth), ocl::typeToStr(ddepth),
ocl::convertTypeStr(sdepth, ddepth, 1, cvt),
doubleSupport ? " -D DOUBLE_SUPPORT" : "");
ocl::Kernel k("reduce", ocl::core::reduce2_oclsrc, build_opt);
if (k.empty())
return false;