#endif
#endif
+#if defined OP_NORM_INF_MASK || defined OP_MIN_MAX_LOC || defined OP_MIN_MAX_LOC_MASK
+
+#ifdef DEPTH_0
+#define MIN_VAL 0
+#define MAX_VAL 255
+#elif defined DEPTH_1
+#define MIN_VAL -128
+#define MAX_VAL 127
+#elif defined DEPTH_2
+#define MIN_VAL 0
+#define MAX_VAL 65535
+#elif defined DEPTH_3
+#define MIN_VAL -32768
+#define MAX_VAL 32767
+#elif defined DEPTH_4
+#define MIN_VAL INT_MIN
+#define MAX_VAL INT_MAX
+#elif defined DEPTH_5
+#define MIN_VAL (-FLT_MAX)
+#define MAX_VAL FLT_MAX
+#elif defined DEPTH_6
+#define MIN_VAL (-DBL_MAX)
+#define MAX_VAL DBL_MAX
+#endif
+
+#define dstT srcT
+#define dstT1 srcT1
+
+#endif // min/max stuff
+
#define noconvert
#if cn != 3
#define CALC_RESULT \
storepix(localmem[0], dstptr + dstTSIZE * gid)
-// minMaxLoc stuff
-#elif defined OP_MIN_MAX_LOC || defined OP_MIN_MAX_LOC_MASK
+// norm (NORM_INF) with cn > 1 and mask
+#elif defined OP_NORM_INF_MASK
-#ifdef DEPTH_0
-#define srcT uchar
-#define MIN_VAL 0
-#define MAX_VAL 255
-#elif defined DEPTH_1
-#define srcT char
-#define MIN_VAL -128
-#define MAX_VAL 127
-#elif defined DEPTH_2
-#define srcT ushort
-#define MIN_VAL 0
-#define MAX_VAL 65535
-#elif defined DEPTH_3
-#define srcT short
-#define MIN_VAL -32768
-#define MAX_VAL 32767
-#elif defined DEPTH_4
-#define srcT int
-#define MIN_VAL INT_MIN
-#define MAX_VAL INT_MAX
-#elif defined DEPTH_5
-#define srcT float
-#define MIN_VAL (-FLT_MAX)
-#define MAX_VAL FLT_MAX
-#elif defined DEPTH_6
-#define srcT double
-#define MIN_VAL (-DBL_MAX)
-#define MAX_VAL DBL_MAX
-#endif
+#define DECLARE_LOCAL_MEM \
+ __local srcT localmem_max[WGS2_ALIGNED]
+#define DEFINE_ACCUMULATOR \
+ srcT maxval = MIN_VAL, temp
+#define REDUCE_GLOBAL \
+ int mask_index = mad24(id / cols, mask_step, mask_offset + (id % cols)); \
+ if (mask[mask_index]) \
+ { \
+ temp = loadpix(srcptr + src_index); \
+ maxval = max(maxval, (srcT)(temp >= 0 ? temp : -temp)); \
+ }
+#define SET_LOCAL_1 \
+ localmem_max[lid] = maxval
+#define REDUCE_LOCAL_1 \
+ localmem_max[lid - WGS2_ALIGNED] = max(maxval, localmem_max[lid - WGS2_ALIGNED])
+#define REDUCE_LOCAL_2 \
+ localmem_max[lid] = max(localmem_max[lid], localmem_max[lid2])
+#define CALC_RESULT \
+ storepix(localmem_max[0], dstptr + dstTSIZE * gid)
-#define dstT srcT
+// minMaxLoc stuff
+#elif defined OP_MIN_MAX_LOC || defined OP_MIN_MAX_LOC_MASK
#define DECLARE_LOCAL_MEM \
__local srcT localmem_min[WGS2_ALIGNED]; \
//M*/
#include "precomp.hpp"
-#include "opencl_kernels.hpp"
#include <climits>
#include <limits>
+#include "opencl_kernels.hpp"
+
namespace cv
{
T min = std::numeric_limits<T>::max();
T max = std::numeric_limits<T>::min() > 0 ? -std::numeric_limits<T>::max() : std::numeric_limits<T>::min();
int minloc = INT_MAX, maxloc = INT_MAX;
- for( int i = 0; i < groupnum; i++)
+ for (int i = 0; i < groupnum; i++)
{
T current_min = minv.at<T>(0,i);
T current_max = maxv.at<T>(0,i);
}
}
bool zero_mask = (maxloc == INT_MAX) || (minloc == INT_MAX);
- if(minVal)
+ if (minVal)
*minVal = zero_mask ? 0 : (double)min;
- if(maxVal)
+ if (maxVal)
*maxVal = zero_mask ? 0 : (double)max;
- if(minLoc)
+ if (minLoc)
{
minLoc[0] = zero_mask ? -1 : minloc/cols;
minLoc[1] = zero_mask ? -1 : minloc%cols;
}
- if(maxLoc)
+ if (maxLoc)
{
maxLoc[0] = zero_mask ? -1 : maxloc/cols;
maxLoc[1] = zero_mask ? -1 : maxloc%cols;
wgs2_aligned <<= 1;
wgs2_aligned >>= 1;
- String opts = format("-D DEPTH_%d -D OP_MIN_MAX_LOC%s -D WGS=%d -D WGS2_ALIGNED=%d%s",
- depth, _mask.empty() ? "" : "_MASK", (int)wgs, wgs2_aligned, doubleSupport ? " -D DOUBLE_SUPPORT" : "");
+ String opts = format("-D DEPTH_%d -D srcT=%s -D OP_MIN_MAX_LOC%s -D WGS=%d -D WGS2_ALIGNED=%d%s",
+ depth, ocl::typeToStr(depth), _mask.empty() ? "" : "_MASK", (int)wgs,
+ wgs2_aligned, doubleSupport ? " -D DOUBLE_SUPPORT" : "");
ocl::Kernel k("reduce", ocl::core::reduce_oclsrc, opts);
if (k.empty())
haveMask = _mask.kind() != _InputArray::NONE;
if ( !(normType == NORM_INF || normType == NORM_L1 || normType == NORM_L2 || normType == NORM_L2SQR) ||
- (!doubleSupport && depth == CV_64F) || (normType == NORM_INF && haveMask && cn != 1))
+ (!doubleSupport && depth == CV_64F))
return false;
UMat src = _src.getUMat();
if (normType == NORM_INF)
{
- UMat abssrc;
+ if (cn == 1 || !haveMask)
+ {
+ UMat abssrc;
+
+ if (depth != CV_8U && depth != CV_16U)
+ {
+ int wdepth = std::max(CV_32S, depth);
+ char cvt[50];
+
+ ocl::Kernel kabs("KF", ocl::core::arithm_oclsrc,
+ format("-D UNARY_OP -D OP_ABS_NOSAT -D dstT=%s -D srcT1=%s -D convertToDT=%s%s",
+ ocl::typeToStr(wdepth), ocl::typeToStr(depth),
+ ocl::convertTypeStr(depth, wdepth, 1, cvt),
+ doubleSupport ? " -D DOUBLE_SUPPORT" : ""));
+ if (kabs.empty())
+ return false;
+
+ abssrc.create(src.size(), CV_MAKE_TYPE(wdepth, cn));
+ kabs.args(ocl::KernelArg::ReadOnlyNoSize(src), ocl::KernelArg::WriteOnly(abssrc, cn));
+
+ size_t globalsize[2] = { src.cols * cn, src.rows };
+ if (!kabs.run(2, globalsize, NULL, false))
+ return false;
+ }
+ else
+ abssrc = src;
- if (depth != CV_8U && depth != CV_16U)
+ cv::minMaxIdx(haveMask ? abssrc : abssrc.reshape(1), NULL, &result, NULL, NULL, _mask);
+ }
+ else
{
- int wdepth = std::max(CV_32S, depth);
- char cvt[50];
-
- ocl::Kernel kabs("KF", ocl::core::arithm_oclsrc,
- format("-D UNARY_OP -D OP_ABS_NOSAT -D dstT=%s -D srcT1=%s -D convertToDT=%s%s",
- ocl::typeToStr(wdepth), ocl::typeToStr(depth),
- ocl::convertTypeStr(depth, wdepth, 1, cvt),
- doubleSupport ? " -D DOUBLE_SUPPORT" : ""));
- if (kabs.empty())
+ int dbsize = ocl::Device::getDefault().maxComputeUnits();
+ size_t wgs = ocl::Device::getDefault().maxWorkGroupSize();
+
+ int wgs2_aligned = 1;
+ while (wgs2_aligned < (int)wgs)
+ wgs2_aligned <<= 1;
+ wgs2_aligned >>= 1;
+
+ ocl::Kernel k("reduce", ocl::core::reduce_oclsrc,
+ format("-D OP_NORM_INF_MASK -D HAVE_MASK -D DEPTH_%d"
+ " -D srcT=%s -D srcT1=%s -D WGS=%d -D cn=%d -D WGS2_ALIGNED=%d%s",
+ depth, ocl::typeToStr(type), ocl::typeToStr(depth),
+ wgs, cn, wgs2_aligned, doubleSupport ? " -D DOUBLE_SUPPORT" : ""));
+ if (k.empty())
return false;
- abssrc.create(src.size(), CV_MAKE_TYPE(wdepth, cn));
- kabs.args(ocl::KernelArg::ReadOnlyNoSize(src), ocl::KernelArg::WriteOnly(abssrc, cn));
+ UMat db(1, dbsize, type), mask = _mask.getUMat();
+ k.args(ocl::KernelArg::ReadOnlyNoSize(src), src.cols, (int)src.total(),
+ dbsize, ocl::KernelArg::PtrWriteOnly(db), ocl::KernelArg::ReadOnlyNoSize(mask));
- size_t globalsize[2] = { src.cols * cn, src.rows };
- if (!kabs.run(2, globalsize, NULL, false))
+ size_t globalsize = dbsize * wgs;
+ if (!k.run(1, &globalsize, &wgs, true))
return false;
- }
- else
- abssrc = src;
- cv::minMaxIdx(haveMask ? abssrc : abssrc.reshape(1), NULL, &result, NULL, NULL, _mask);
+ minMaxIdx(db.getMat(ACCESS_READ), NULL, &result, NULL, NULL, noArray());
+ }
}
else if (normType == NORM_L1 || normType == NORM_L2 || normType == NORM_L2SQR)
{