blob: ebd3408b236b3710283c6fc3f3565c6ccd1e2f40 [file] [log] [blame]
Michel Iwaniec00633802017-10-12 14:14:15 +01001/*
Michele Di Giorgioe5bf4c52019-02-14 17:47:33 +00002 * Copyright (c) 2016-2019 ARM Limited.
Michel Iwaniec00633802017-10-12 14:14:15 +01003 *
4 * SPDX-License-Identifier: MIT
5 *
6 * Permission is hereby granted, free of charge, to any person obtaining a copy
7 * of this software and associated documentation files (the "Software"), to
8 * deal in the Software without restriction, including without limitation the
9 * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
10 * sell copies of the Software, and to permit persons to whom the Software is
11 * furnished to do so, subject to the following conditions:
12 *
13 * The above copyright notice and this permission notice shall be included in all
14 * copies or substantial portions of the Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22 * SOFTWARE.
23 */
Manuel Bottini30dbeef2019-06-26 16:23:03 +010024#include "activation_quant_helpers.h"
Michel Iwaniec00633802017-10-12 14:14:15 +010025
Michele Di Giorgiod304e802018-07-06 10:17:33 +010026#define VEC_FLOAT VEC_DATA_TYPE(float, VEC_SIZE)
Michel Iwaniec00633802017-10-12 14:14:15 +010027
Georgios Pinitas4b3fba12019-06-04 17:31:46 +010028#if defined(FLOAT_DOMAIN)
29// Activations performed in the float domain
30
31#include "activation_float_helpers.h"
32
Manuel Bottini30dbeef2019-06-26 16:23:03 +010033/** This performs an activation function on quantized inputs with float transformations.
Georgios Pinitas4b3fba12019-06-04 17:31:46 +010034 *
35 * @note In order to perform the activation function "in-place", the pre-processor -DIN_PLACE must be passed at compile time
36 *
37 * @note Datatype should be given as a preprocessor argument using -DDATA_TYPE=type. e.g. -DDATA_TYPE=short
38 * @note Vector size should be given as a preprocessor argument using -DVEC_SIZE=size. e.g. -DVEC_SIZE=16
39 * @note A, B variables required by some activation functions are set using -DA_VAL= and -DB_VAL= respectively.
40 * @note Quantization scales of the input/output tensors are passed in with -DS1_VAL= and -DS2_VAL= respectively.
Manuel Bottini30dbeef2019-06-26 16:23:03 +010041 * @note Quantization offsets of the input/output tensors are passed in only if asymmetric with -DO1_VAL= and -DO2_VAL= respectively.
Georgios Pinitas4b3fba12019-06-04 17:31:46 +010042 * @note Quantized value of constant zero should be given as a preprocessor argument using -DCONST_0=value. e.g. -DCONST_0=128.
43 *
Manuel Bottini30dbeef2019-06-26 16:23:03 +010044 * @param[in] input_ptr Pointer to the source image. Supported data types: QASYMM8/QSYMM16
Georgios Pinitas4b3fba12019-06-04 17:31:46 +010045 * @param[in] input_stride_x Stride of the source image in X dimension (in bytes)
46 * @param[in] input_step_x input_stride_x * number of elements along X processed per workitem(in bytes)
47 * @param[in] input_stride_y Stride of the source image in Y dimension (in bytes)
48 * @param[in] input_step_y input_stride_y * number of elements along Y processed per workitem(in bytes)
49 * @param[in] input_stride_z Stride of the source tensor in Z dimension (in bytes)
50 * @param[in] input_step_z input_stride_z * number of elements along Z processed per workitem(in bytes)
51 * @param[in] input_offset_first_element_in_bytes The offset of the first element in the source image
52 * @param[out] output_ptr (Optional) Pointer to the destination image. Supported data types: same as @p input_ptr
53 * @param[in] output_stride_x (Optional) Stride of the destination image in X dimension (in bytes)
54 * @param[in] output_step_x (Optional) output_stride_x * number of elements along X processed per workitem(in bytes)
55 * @param[in] output_stride_y (Optional) Stride of the destination image in Y dimension (in bytes)
56 * @param[in] output_step_y (Optional) output_stride_y * number of elements along Y processed per workitem(in bytes)
57 * @param[in] output_stride_z (Optional) Stride of the source tensor in Z dimension (in bytes)
58 * @param[in] output_step_z (Optional) output_stride_z * number of elements along Z processed per workitem(in bytes)
59 * @param[in] output_offset_first_element_in_bytes (Optional) The offset of the first element in the destination image
60 */
Manuel Bottini30dbeef2019-06-26 16:23:03 +010061__kernel void activation_layer_quant_f32(
Georgios Pinitas4b3fba12019-06-04 17:31:46 +010062 TENSOR3D_DECLARATION(input)
63#ifndef IN_PLACE
64 ,
65 TENSOR3D_DECLARATION(output)
66#endif /* not IN_PLACE */
67)
68{
69 // Get pixels pointer
70 Tensor3D input = CONVERT_TO_TENSOR3D_STRUCT(input);
71#ifdef IN_PLACE
72 Tensor3D output = input;
73#else /* IN_PLACE */
74 Tensor3D output = CONVERT_TO_TENSOR3D_STRUCT(output);
75#endif /* IN_PLACE */
76
77 // Load data
78 TYPE data = VLOAD(VEC_SIZE)(0, (__global DATA_TYPE *)input.ptr);
79
80 VEC_FLOAT data_flt = CONVERT(data, VEC_FLOAT);
Manuel Bottini30dbeef2019-06-26 16:23:03 +010081#if defined(O1_VAL)
82 data_flt = round(data_flt - (float)O1_VAL) * ((float)S1_VAL);
83#else // defined(O1_VAL)
84 data_flt = round(data_flt) * ((float)S1_VAL);
85#endif // defined(O1_VAL)
86 data_flt = ACTIVATION(ACT, float, data_flt, A_VAL, B_VAL);
Georgios Pinitas4b3fba12019-06-04 17:31:46 +010087
Manuel Bottini30dbeef2019-06-26 16:23:03 +010088#if defined(O2_VAL)
89 data = CONVERT_SAT(round(data_flt / ((float)S2_VAL)) + (float)O2_VAL, TYPE);
90#else // defined(O2_VAL)
91 data = CONVERT_SAT(round(data_flt / ((float)S2_VAL)), TYPE);
92#endif // defined(O2_VAL)
Georgios Pinitas4b3fba12019-06-04 17:31:46 +010093
94 // Store result
95 VSTORE(VEC_SIZE)
96 (data, 0, (__global DATA_TYPE *)output.ptr);
97}
98
99#else // defined(FLOAT_DOMAIN)
100// Activations performed in the quantized domain
101
Giorgio Arena99ac60b2018-02-16 15:17:23 +0000102#if defined(ACT)
Manuel Bottini30dbeef2019-06-26 16:23:03 +0100103/** This performs an activation function on quantized inputs.
Michel Iwaniec00633802017-10-12 14:14:15 +0100104 *
105 * @note In order to perform the activation function "in-place", the pre-processor -DIN_PLACE must be passed at compile time
106 *
107 * @note Datatype should be given as a preprocessor argument using -DDATA_TYPE=type. e.g. -DDATA_TYPE=short
108 * @note Vector size should be given as a preprocessor argument using -DVEC_SIZE=size. e.g. -DVEC_SIZE=16
109 * @note Activation function should be given as a preprocessor argument using -DACT=name. e.g. -DACT=TANH
110 * @note A, B variables required by some activation functions are set using -DA_VAL= and -DB_VAL= respectively.
111 * @note Quantization scales of the input/output tensors are passed in with -DS1_VAL= and -DS2_VAL= respectively.
112 * @note Quantization offsets of the input/output tensors are passed in with -DO1_VAL= and -DO2_VAL= respectively.
Michele Di Giorgioa1f7e332018-01-22 17:26:36 +0000113 * @note Quantized value of constant zero should be given as a preprocessor argument using -DCONST_0=value. e.g. -DCONST_0=128.
Michel Iwaniec00633802017-10-12 14:14:15 +0100114 *
Manuel Bottini30dbeef2019-06-26 16:23:03 +0100115 * @param[in] input_ptr Pointer to the source image. Supported data types: QASYMM8/QSYMM16
Michel Iwaniec00633802017-10-12 14:14:15 +0100116 * @param[in] input_stride_x Stride of the source image in X dimension (in bytes)
117 * @param[in] input_step_x input_stride_x * number of elements along X processed per workitem(in bytes)
118 * @param[in] input_stride_y Stride of the source image in Y dimension (in bytes)
119 * @param[in] input_step_y input_stride_y * number of elements along Y processed per workitem(in bytes)
120 * @param[in] input_stride_z Stride of the source tensor in Z dimension (in bytes)
121 * @param[in] input_step_z input_stride_z * number of elements along Z processed per workitem(in bytes)
122 * @param[in] input_offset_first_element_in_bytes The offset of the first element in the source image
Michele Di Giorgioe5bf4c52019-02-14 17:47:33 +0000123 * @param[out] output_ptr (Optional) Pointer to the destination image. Supported data types: same as @p input_ptr
124 * @param[in] output_stride_x (Optional) Stride of the destination image in X dimension (in bytes)
125 * @param[in] output_step_x (Optional) output_stride_x * number of elements along X processed per workitem(in bytes)
126 * @param[in] output_stride_y (Optional) Stride of the destination image in Y dimension (in bytes)
127 * @param[in] output_step_y (Optional) output_stride_y * number of elements along Y processed per workitem(in bytes)
128 * @param[in] output_stride_z (Optional) Stride of the source tensor in Z dimension (in bytes)
129 * @param[in] output_step_z (Optional) output_stride_z * number of elements along Z processed per workitem(in bytes)
130 * @param[in] output_offset_first_element_in_bytes (Optional) The offset of the first element in the destination image
Michel Iwaniec00633802017-10-12 14:14:15 +0100131 */
Manuel Bottini30dbeef2019-06-26 16:23:03 +0100132__kernel void activation_layer_quant(
Michel Iwaniec00633802017-10-12 14:14:15 +0100133 TENSOR3D_DECLARATION(input)
134#ifndef IN_PLACE
135 ,
136 TENSOR3D_DECLARATION(output)
137#endif /* not IN_PLACE */
138)
139{
140 // Get pixels pointer
Georgios Pinitas4b3fba12019-06-04 17:31:46 +0100141 Tensor3D input = CONVERT_TO_TENSOR3D_STRUCT(input);
Michel Iwaniec00633802017-10-12 14:14:15 +0100142#ifdef IN_PLACE
143 Tensor3D output = input;
144#else /* IN_PLACE */
145 Tensor3D output = CONVERT_TO_TENSOR3D_STRUCT(output);
146#endif /* IN_PLACE */
147
148 // Load data
149 TYPE data = VLOAD(VEC_SIZE)(0, (__global DATA_TYPE *)input.ptr);
150
Manuel Bottini30dbeef2019-06-26 16:23:03 +0100151 data = PERFORM_ACTIVATION_QUANT(ACT, data);
Michel Iwaniec00633802017-10-12 14:14:15 +0100152
153 // Store result
154 VSTORE(VEC_SIZE)
Giorgio Arenaa0d11832018-01-17 16:13:46 +0000155 (data, 0, (__global DATA_TYPE *)output.ptr);
Michel Iwaniec00633802017-10-12 14:14:15 +0100156}
Georgios Pinitas4b3fba12019-06-04 17:31:46 +0100157#endif // defined(ACT)
158#endif // defined(FLOAT_DOMAIN)