aboutsummaryrefslogtreecommitdiff
path: root/src/core/CL/cl_kernels/minmaxloc.cl
diff options
context:
space:
mode:
authorMichele Di Giorgio <michele.digiorgio@arm.com>2017-07-04 17:19:43 +0100
committerAnthony Barbier <anthony.barbier@arm.com>2018-09-17 14:16:42 +0100
commitef4b4ae784f7533ed6d9e7b51827a894c32ed48e (patch)
tree6f4268044be18c003f5136b8ef7c7c07e219f2bd /src/core/CL/cl_kernels/minmaxloc.cl
parentf87cc7f6fef95f9b022725304118796a6a764a7c (diff)
downloadComputeLibrary-ef4b4ae784f7533ed6d9e7b51827a894c32ed48e.tar.gz
COMPMID-438: Add support for floating point Min-Max Location layer.
Change-Id: I84ae564a40fc7320a6f94a84d53906ba51404f51 Reviewed-on: http://mpd-gerrit.cambridge.arm.com/79797 Reviewed-by: Anthony Barbier <anthony.barbier@arm.com> Tested-by: Kaizen <jeremy.johnson+kaizengerrit@arm.com>
Diffstat (limited to 'src/core/CL/cl_kernels/minmaxloc.cl')
-rw-r--r--src/core/CL/cl_kernels/minmaxloc.cl35
1 files changed, 32 insertions, 3 deletions
diff --git a/src/core/CL/cl_kernels/minmaxloc.cl b/src/core/CL/cl_kernels/minmaxloc.cl
index e628e9bd5b..05fc78dcb5 100644
--- a/src/core/CL/cl_kernels/minmaxloc.cl
+++ b/src/core/CL/cl_kernels/minmaxloc.cl
@@ -32,6 +32,17 @@
#define DATA_TYPE_MAX 0xFF
#endif /* DATA_TYPE_MAX */
+inline int FloatFlip(float val)
+{
+ union
+ {
+ int int_val;
+ float flt_val;
+ } u_val;
+ u_val.flt_val = val;
+ return (u_val.int_val >= 0) ? u_val.int_val : u_val.int_val ^ 0x7FFFFFFF;
+}
+
__constant VEC_DATA_TYPE(DATA_TYPE, 16) type_min = (VEC_DATA_TYPE(DATA_TYPE, 16))(DATA_TYPE_MIN);
__constant VEC_DATA_TYPE(DATA_TYPE, 16) type_max = (VEC_DATA_TYPE(DATA_TYPE, 16))(DATA_TYPE_MAX);
__constant uint16 idx16 = (uint16)(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15);
@@ -78,8 +89,12 @@ __kernel void minmax(
// Handle non multiple of 16
VEC_DATA_TYPE(DATA_TYPE, 16)
data = vload16(0, (__global DATA_TYPE *)offset(&src, width4 << 4, 0));
+#ifdef IS_DATA_TYPE_FLOAT
+ int16 widx = convert_int16(((uint16)(width4 << 4) + idx16) < width);
+#else /* IS_DATA_TYPE_FLOAT */
VEC_DATA_TYPE(DATA_TYPE, 16)
- widx = CONVERT(((uint16)(width4 << 4) + idx16) < width, VEC_DATA_TYPE(DATA_TYPE, 16));
+ widx = CONVERT(((uint16)(width4 << 4) + idx16) < width, VEC_DATA_TYPE(DATA_TYPE, 16));
+#endif /* IS_DATA_TYPE_FLOAT */
local_max = max(local_max, select(type_min, data, widx));
local_min = min(local_min, select(type_max, data, widx));
#endif /* NON_MULTIPLE_OF_16 */
@@ -98,8 +113,13 @@ __kernel void minmax(
local_max.s0 = max(local_max.s0, local_max.s1);
// Update global min/max
+#ifdef IS_DATA_TYPE_FLOAT
+ atomic_min(&min_max[0], FloatFlip(local_min.s0));
+ atomic_max(&min_max[1], FloatFlip(local_max.s0));
+#else /* IS_DATA_TYPE_FLOAT */
atomic_min(&min_max[0], local_min.s0);
atomic_max(&min_max[1], local_max.s0);
+#endif /* IS_DATA_TYPE_FLOAT */
}
/** This function counts the min and max occurrences in an image and tags their position.
@@ -136,9 +156,18 @@ __kernel void minmaxloc(
{
Image src = CONVERT_TO_IMAGE_STRUCT(src);
+#ifdef IS_DATA_TYPE_FLOAT
+ __global float *min_max_ptr = (__global float *)min_max;
+ float min_value = min_max_ptr[0];
+ float max_value = min_max_ptr[1];
+#else /* IS_DATA_TYPE_FLOAT */
+ int min_value = min_max[0];
+ int max_value = min_max[1];
+#endif /* IS_DATA_TYPE_FLOAT */
+
DATA_TYPE value = *((__global DATA_TYPE *)src.ptr);
#ifdef COUNT_MIN_MAX
- if(value == min_max[0])
+ if(value == min_value)
{
uint idx = atomic_inc(&min_max_count[0]);
#ifdef LOCATE_MIN
@@ -149,7 +178,7 @@ __kernel void minmaxloc(
}
#endif /* LOCATE_MIN */
}
- if(value == min_max[1])
+ if(value == max_value)
{
uint idx = atomic_inc(&min_max_count[1]);
#ifdef LOCATE_MAX