aboutsummaryrefslogtreecommitdiff
path: root/src/core/CL/cl_kernels/normalization_layer.cl
diff options
context:
space:
mode:
authorMichele Di Giorgio <michele.digiorgio@arm.com>2017-06-22 16:55:57 +0100
committerAnthony Barbier <anthony.barbier@arm.com>2018-09-17 14:16:42 +0100
commit6c928343b0fa2bf60ffdfe21aea28b598d742ed4 (patch)
tree0a03b06b8329c734c250239112892ac070233481 /src/core/CL/cl_kernels/normalization_layer.cl
parentd5e65c71261fd42d3e69478507fbfcc8cf36befc (diff)
downloadComputeLibrary-6c928343b0fa2bf60ffdfe21aea28b598d742ed4.tar.gz
COMPMID-413: Add support for QS8 and QS16 CLNormalizationLayer.
Change-Id: I1aaa9fb8d05796bbca9cfae584e084646552bb71 Reviewed-on: http://mpd-gerrit.cambridge.arm.com/80155 Reviewed-by: Anthony Barbier <anthony.barbier@arm.com> Tested-by: Kaizen <jeremy.johnson+kaizengerrit@arm.com>
Diffstat (limited to 'src/core/CL/cl_kernels/normalization_layer.cl')
-rw-r--r--src/core/CL/cl_kernels/normalization_layer.cl104
1 files changed, 71 insertions, 33 deletions
diff --git a/src/core/CL/cl_kernels/normalization_layer.cl b/src/core/CL/cl_kernels/normalization_layer.cl
index 2305ae0d15..598b734c26 100644
--- a/src/core/CL/cl_kernels/normalization_layer.cl
+++ b/src/core/CL/cl_kernels/normalization_layer.cl
@@ -23,11 +23,41 @@
*/
#include "helpers.h"
+#if defined(FIXED_POINT_POSITION)
+
+#include "fixed_point.h"
+#define MUL_OP(x, y) MUL_SAT_OP_EXPAND((x), (y), DATA_TYPE, VEC_SIZE, FIXED_POINT_POSITION)
+#define ADD_OP(x, y) ADD_SAT_OP_EXPAND((x), (y), DATA_TYPE, VEC_SIZE)
+#define DIV_OP(x, y) DIV_SAT_OP_EXPAND((x), (y), DATA_TYPE, VEC_SIZE, FIXED_POINT_POSITION)
+#define EXP_OP(x) EXP_OP_EXPAND((x), DATA_TYPE, VEC_SIZE, FIXED_POINT_POSITION)
+#define LOG_OP(x) LOG_OP_EXPAND((x), DATA_TYPE, VEC_SIZE, FIXED_POINT_POSITION)
+#define POW_OP(x, y) EXP_OP(MUL_OP(LOG_OP((x)), (y)))
+#define SQCVT_SAT(a) SQCVT_SAT_OP_EXPAND((a), DATA_TYPE, FIXED_POINT_POSITION)
+
+#define LOAD_OP(offset, ptr) vload16(offset, ptr)
+#define STORE_OP(data, offset, ptr) vstore16(data, offset, ptr)
+
+#else // FIXED_POINT_POSITION
+
+#define MUL_OP(x, y) ((x) * (y))
+#define ADD_OP(x, y) ((x) + (y))
+#define DIV_OP(x, y) ((x) / (y))
+#define POW_OP(x, y) pow((x), (y))
+#define SQCVT_SAT(a) (a)
+
+#define LOAD_OP(offset, ptr) vload4(offset, ptr)
+#define STORE_OP(data, offset, ptr) vstore4(data, offset, ptr)
+
+#endif // FIXED_POINT_POSITION
+
/** Apply cross map normalization.
*
* @note Datatype should be given as a preprocessor argument using -DDATA_TYPE=type. e.g. -DDATA_TYPE=short
+ * @note Vector size should be given as a preprocessor argument using -DVEC_SIZE=size, e.g. -DVEC_SIZE=16
+ * @note In case of fixed-point operation -DFIXED_POINT_POSITION=fixed_point_position must be provided: e.g. -DFIXED_POINT_POSITION=3
+ * @note Scaling coefficient (= alpha/norm_size), beta and kappa need to be passed at compile time using -DCOEFF, -DALPHA and -DKAPPA
*
- * @param[in] input_ptr Pointer to the first source tensor. Supported data types: F16, F32
+ * @param[in] input_ptr Pointer to the first source tensor. Supported data types: QS8/QS16/F16/F32
* @param[in] input_stride_x Stride of the first source tensor in X dimension (in bytes)
* @param[in] input_step_x input_stride_x * number of elements along X processed per workitem(in bytes)
* @param[in] input_stride_y Stride of the first source tensor in Y dimension (in bytes)
@@ -35,7 +65,7 @@
* @param[in] input_stride_z Stride of the first source tensor in Z dimension (in bytes)
* @param[in] input_step_z input_stride_z * number of elements along Z processed per workitem(in bytes)
* @param[in] input_offset_first_element_in_bytes The offset of the first element in the first source tensor
- * @param[in] squared_input_ptr Pointer to the second source tensor. Supported data types: F16, F32
+ * @param[in] squared_input_ptr Pointer to the second source tensor. Supported data types: same as @p input_ptr
* @param[in] squared_input_stride_x Stride of the second source tensor in X dimension (in bytes)
* @param[in] squared_input_step_x input_stride_x * number of elements along X processed per workitem(in bytes)
* @param[in] squared_input_stride_y Stride of the second source tensor in Y dimension (in bytes)
@@ -43,7 +73,7 @@
* @param[in] squared_input_stride_z Stride of the second source tensor in Z dimension (in bytes)
* @param[in] squared_input_step_z input_stride_z * number of elements along Z processed per workitem(in bytes)
* @param[in] squared_input_offset_first_element_in_bytes The offset of the second element in the second source tensor
- * @param[out] output_ptr Pointer to the destination tensor. Supported data types: F16, F32
+ * @param[out] output_ptr Pointer to the destination tensor. Supported data types: same as @p input_ptr
* @param[in] output_stride_x Stride of the destination tensor in X dimension (in bytes)
* @param[in] output_step_x output_stride_x * number of elements along X processed per workitem(in bytes)
* @param[in] output_stride_y Stride of the destination tensor in Y dimension (in bytes)
@@ -51,24 +81,25 @@
* @param[in] output_stride_z Stride of the destination tensor in Z dimension (in bytes)
* @param[in] output_step_z output_stride_z * number of elements along Z processed per workitem(in bytes)
* @param[in] output_offset_first_element_in_bytes The offset of the first element in the destination tensor
- * @param[in] coeff Alpha parameter / norm_size
- * @param[in] beta Beta parameter in the normalization equation
- * @param[in] kappa Kappa parameter in the normalization equation
* @param[in] radius Number of elements on the right or left side to normalize across
*/
__kernel void normalization_layer_cross_map(TENSOR3D_DECLARATION(input),
TENSOR3D_DECLARATION(squared_input),
TENSOR3D_DECLARATION(output),
- float coeff,
- float beta,
- float kappa,
- uint radius)
+ uint radius)
{
Tensor3D in = CONVERT_TO_TENSOR3D_STRUCT(input);
Tensor3D squared_in = CONVERT_TO_TENSOR3D_STRUCT(squared_input);
Tensor3D out = CONVERT_TO_TENSOR3D_STRUCT(output);
- DATA_TYPE acc = 0;
+ VEC_DATA_TYPE(DATA_TYPE, VEC_SIZE)
+ acc = (VEC_DATA_TYPE(DATA_TYPE, VEC_SIZE))0;
+ const VEC_DATA_TYPE(DATA_TYPE, VEC_SIZE)
+ coeff_v = (VEC_DATA_TYPE(DATA_TYPE, VEC_SIZE))SQCVT_SAT(COEFF);
+ const VEC_DATA_TYPE(DATA_TYPE, VEC_SIZE)
+ beta_v = (VEC_DATA_TYPE(DATA_TYPE, VEC_SIZE))SQCVT_SAT(BETA);
+ const VEC_DATA_TYPE(DATA_TYPE, VEC_SIZE)
+ kappa_v = (VEC_DATA_TYPE(DATA_TYPE, VEC_SIZE))SQCVT_SAT(KAPPA);
const int num_of_slices = get_global_size(2);
const int current_slice = get_global_id(2);
@@ -78,21 +109,26 @@ __kernel void normalization_layer_cross_map(TENSOR3D_DECLARATION(input),
for(int i = left_slice; i <= right_slice; i++)
{
- acc += *(__global DATA_TYPE *)tensor3D_offset(&squared_in, 0, 0, i - current_slice);
+ acc = ADD_OP(acc, LOAD_OP(0, (__global DATA_TYPE *)tensor3D_offset(&squared_in, 0, 0, i - current_slice)));
}
- const float normalized = pow(kappa + coeff * (float)acc, beta);
+ acc = ADD_OP(MUL_OP(acc, coeff_v), kappa_v);
+ const VEC_DATA_TYPE(DATA_TYPE, VEC_SIZE)
+ normalized = POW_OP(acc, beta_v);
+ const VEC_DATA_TYPE(DATA_TYPE, VEC_SIZE)
+ normalized_pixel = DIV_OP(LOAD_OP(0, (__global DATA_TYPE *)in.ptr), normalized);
- const float normalized_pixel = (float) * ((__global DATA_TYPE *)in.ptr) / normalized;
-
- *(__global DATA_TYPE *)out.ptr = CONVERT(normalized_pixel, DATA_TYPE);
+ STORE_OP(normalized_pixel, 0, (__global DATA_TYPE *)out.ptr);
}
/** Apply in map normalization.
*
* @note Datatype should be given as a preprocessor argument using -DDATA_TYPE=type. e.g. -DDATA_TYPE=short
+ * @note Vector size should be given as a preprocessor argument using -DVEC_SIZE=size, e.g. -DVEC_SIZE=16
+ * @note In case of fixed-point operation -DFIXED_POINT_POSITION=fixed_point_position must be provided: e.g. -DFIXED_POINT_POSITION=3
+ * @note Scaling coefficient (= alpha/norm_size), beta and kappa need to be passed at compile time using -DCOEFF, -DALPHA and -DKAPPA
*
- * @param[in] input_ptr Pointer to the first source tensor. Supported data types: F16, F32
+ * @param[in] input_ptr Pointer to the first source tensor. Supported data types: QS8/F16/F32
* @param[in] input_stride_x Stride of the first source tensor in X dimension (in bytes)
* @param[in] input_step_x input_stride_x * number of elements along X processed per workitem(in bytes)
* @param[in] input_stride_y Stride of the first source tensor in Y dimension (in bytes)
@@ -100,7 +136,7 @@ __kernel void normalization_layer_cross_map(TENSOR3D_DECLARATION(input),
* @param[in] input_stride_z Stride of the first source tensor in Z dimension (in bytes)
* @param[in] input_step_z input_stride_z * number of elements along Z processed per workitem(in bytes)
* @param[in] input_offset_first_element_in_bytes The offset of the first element in the first source tensor
- * @param[in] squared_input_ptr Pointer to the second source tensor. Supported data types: F16, F32
+ * @param[in] squared_input_ptr Pointer to the second source tensor. Supported data types: same as @p input_ptr
* @param[in] squared_input_stride_x Stride of the second source tensor in X dimension (in bytes)
* @param[in] squared_input_step_x input_stride_x * number of elements along X processed per workitem(in bytes)
* @param[in] squared_input_stride_y Stride of the second source tensor in Y dimension (in bytes)
@@ -108,7 +144,7 @@ __kernel void normalization_layer_cross_map(TENSOR3D_DECLARATION(input),
* @param[in] squared_input_stride_z Stride of the second source tensor in Z dimension (in bytes)
* @param[in] squared_input_step_z input_stride_z * number of elements along Z processed per workitem(in bytes)
* @param[in] squared_input_offset_first_element_in_bytes The offset of the second element in the second source tensor
- * @param[out] output_ptr Pointer to the destination tensor. Supported data types: F16, F32
+ * @param[out] output_ptr Pointer to the destination tensor. Supported data types: same as @p input_ptr
* @param[in] output_stride_x Stride of the destination tensor in X dimension (in bytes)
* @param[in] output_step_x output_stride_x * number of elements along X processed per workitem(in bytes)
* @param[in] output_stride_y Stride of the first destination tensor in Y dimension (in bytes)
@@ -116,25 +152,25 @@ __kernel void normalization_layer_cross_map(TENSOR3D_DECLARATION(input),
* @param[in] output_stride_z Stride of the first source tensor in Z dimension (in bytes)
* @param[in] output_step_z output_stride_z * number of elements along Z processed per workitem(in bytes)
* @param[in] output_offset_first_element_in_bytes The offset of the first element in the destination tensor
- * @param[in] coeff Alpha parameter / norm_size
- * @param[in] beta Beta parameter in the normalization equation
- * @param[in] kappa Kappa parameter in the normalization equation
* @param[in] radius Number of elements on the right or left side to normalize across
*/
__kernel void normalization_layer_in_map_1D(TENSOR3D_DECLARATION(input),
TENSOR3D_DECLARATION(squared_input),
TENSOR3D_DECLARATION(output),
- float coeff,
- float beta,
- float kappa,
- uint radius)
+ uint radius)
{
Tensor3D in = CONVERT_TO_TENSOR3D_STRUCT(input);
Tensor3D squared_in = CONVERT_TO_TENSOR3D_STRUCT(squared_input);
Tensor3D out = CONVERT_TO_TENSOR3D_STRUCT(output);
- VEC_DATA_TYPE(DATA_TYPE, 4)
- acc_vec = 0;
+ VEC_DATA_TYPE(DATA_TYPE, VEC_SIZE)
+ acc = (VEC_DATA_TYPE(DATA_TYPE, VEC_SIZE))0;
+ const VEC_DATA_TYPE(DATA_TYPE, VEC_SIZE)
+ coeff_v = (VEC_DATA_TYPE(DATA_TYPE, VEC_SIZE))SQCVT_SAT(COEFF);
+ const VEC_DATA_TYPE(DATA_TYPE, VEC_SIZE)
+ beta_v = (VEC_DATA_TYPE(DATA_TYPE, VEC_SIZE))SQCVT_SAT(BETA);
+ const VEC_DATA_TYPE(DATA_TYPE, VEC_SIZE)
+ kappa_v = (VEC_DATA_TYPE(DATA_TYPE, VEC_SIZE))SQCVT_SAT(KAPPA);
const int current_pos = get_global_id(0) << 2;
@@ -143,12 +179,14 @@ __kernel void normalization_layer_in_map_1D(TENSOR3D_DECLARATION(input),
for(int i = left_pos; i <= right_pos; i += 1)
{
- acc_vec += vload4(0, (__global DATA_TYPE *)tensor3D_offset(&squared_in, i - current_pos, 0, 0));
+ acc = ADD_OP(acc, LOAD_OP(0, (__global DATA_TYPE *)tensor3D_offset(&squared_in, i - current_pos, 0, 0)));
}
- const float4 normalized = pow((float4)kappa + coeff * CONVERT(acc_vec, float4), beta);
-
- const float4 normalized_pixel = CONVERT(vload4(0, (__global DATA_TYPE *)in.ptr), float4) / normalized;
+ acc = ADD_OP(MUL_OP(acc, coeff_v), kappa_v);
+ const VEC_DATA_TYPE(DATA_TYPE, VEC_SIZE)
+ normalized = POW_OP(acc, beta_v);
+ const VEC_DATA_TYPE(DATA_TYPE, VEC_SIZE)
+ normalized_pixel = DIV_OP(LOAD_OP(0, (__global DATA_TYPE *)in.ptr), normalized);
- vstore4(CONVERT(normalized_pixel, VEC_DATA_TYPE(DATA_TYPE, 4)), 0, (__global DATA_TYPE *)out.ptr);
+ STORE_OP(normalized_pixel, 0, (__global DATA_TYPE *)out.ptr);
}