blob: ea6c8d813d8617db886663336c5da43dd9196622 [file] [log] [blame]
Pablo Tello89519332017-11-17 11:52:36 +00001/*
Pablo Tello9ceebbe2018-01-10 16:44:13 +00002 * Copyright (c) 2017-2018 ARM Limited.
Pablo Tello89519332017-11-17 11:52:36 +00003 *
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 */
24#ifndef __ARM_COMPUTE_NEGEMMWINOGRADLAYERKERNEL_H__
25#define __ARM_COMPUTE_NEGEMMWINOGRADLAYERKERNEL_H__
26
27#include "arm_compute/core/NEON/INEKernel.h"
Pablo Tello9ceebbe2018-01-10 16:44:13 +000028#include "arm_compute/core/NEON/kernels/winograd/convolution.hpp"
Pablo Tello3d4968a2017-12-04 15:03:35 +000029#include "arm_compute/core/NEON/kernels/winograd/tensor.hpp"
Pablo Tello89519332017-11-17 11:52:36 +000030
31namespace arm_compute
32{
33class ITensor;
Pablo Tello3d4968a2017-12-04 15:03:35 +000034class NEWinogradLayerKernel;
Pablo Tellod6ca4782018-01-23 09:36:04 +000035class NEWinogradLayerTransformInputKernel;
36class NEWinogradLayerTransformWeightsKernel;
Pablo Tello02541fb2017-12-15 09:48:59 +000037
Pablo Tello4e2c1392018-01-09 10:30:27 +000038class Winograd3x3F32 final
Pablo Tello3d4968a2017-12-04 15:03:35 +000039{
40public:
Pablo Tello6c6e77a2018-01-23 10:03:27 +000041 /** Create a new Winograd convolution layer.
42 *
43 * @param[in] n_batches Number of batches in the input and output tensors.
44 * @param[in] n_input_channels Number of feature maps in a batch of the input tensor.
45 * @param[in] n_input_rows Number of rows in a feature map of the input tensor.
46 * @param[in] n_input_cols Number of columns in a feature map of the input tensor.
47 * @param[in] n_output_channels Number of feature maps in the output tensor.
48 * @param[in] same_padding Use "SAME" padding, otherwise use "VALID".
49 * @param[in] weights Pointer to weight tensor in spatial domain. Must be ordered as "Height x Rows x Input Feature Maps x Output Feature Maps.
50 * @param[out] weights_storage Pointer to storage for weight tensor in the Winograd domain. Must be at least the size returned by `get_weight_storage_size
51 * @param[in] input Pointer to NHWC ordered input tensor, in the spatial domain.
52 * @param[out] winograd_input Pointer to working space for the input tensor in the Winograd domain. Must be at least the size returned by `get_input_storage_size`.
Pablo Tellod6ca4782018-01-23 09:36:04 +000053 * @param[in] biases Pointer to the biases vector.
Pablo Tello6c6e77a2018-01-23 10:03:27 +000054 * @param[out] output Pointer to NHWC ordered output tensor, in the spatial domain.
55 * @param[out] winograd_output Pointer to working space for the output tensor in the Winograd domain. Must be at least the size returned by `get_output_storage_size`.
56 */
Pablo Tello3d4968a2017-12-04 15:03:35 +000057 friend class NEWinogradLayerKernel;
Pablo Tellod6ca4782018-01-23 09:36:04 +000058 friend class NEWinogradLayerTransformInputKernel;
59 friend class NEWinogradLayerTransformOutputKernel;
60 friend class NEWinogradLayerTransformWeightsKernel;
61
Pablo Tello9ceebbe2018-01-10 16:44:13 +000062 Winograd3x3F32(
Pablo Tello6c6e77a2018-01-23 10:03:27 +000063 const int n_batches,
64 const int n_input_channels,
65 const int n_input_rows,
66 const int n_input_cols,
67 const int n_output_channels,
68 const bool same_padding,
69 const float *const weights,
70 float *const weights_storage,
71 const float *const input,
72 float *const winograd_input,
73 float *const output,
74 float *const winograd_output);
Pablo Tello9ceebbe2018-01-10 16:44:13 +000075
Pablo Tello3d4968a2017-12-04 15:03:35 +000076 ~Winograd3x3F32();
Pablo Tello3d4968a2017-12-04 15:03:35 +000077
78private:
79 class Private;
80 std::unique_ptr<Private> _pimpl;
81};
Pablo Tello89519332017-11-17 11:52:36 +000082
Pablo Tellod6ca4782018-01-23 09:36:04 +000083class INEWinogradLayerTransformKernel : public INEKernel
84{
85public:
86 /** Constructor */
87 INEWinogradLayerTransformKernel();
88
89 /** Prevent instances of this class from being copied (As this class contains pointers) */
90 INEWinogradLayerTransformKernel(const INEWinogradLayerTransformKernel &) = delete;
91 /** Prevent instances of this class from being copied (As this class contains pointers) */
92 INEWinogradLayerTransformKernel &operator=(const INEWinogradLayerTransformKernel &) = delete;
93 /** Allow instances of this class to be moved */
94 INEWinogradLayerTransformKernel(INEWinogradLayerTransformKernel &&) = default;
95 /** Allow instances of this class to be moved */
96 INEWinogradLayerTransformKernel &operator=(INEWinogradLayerTransformKernel &&) = default;
97
98 virtual ~INEWinogradLayerTransformKernel() = default;
99
100 /** Initialise the kernel
101 *
102 * @param[in] convolver A pointer to the winograd convolver, this object must have been configured and is ready to execute 16 GEMMS .
103 */
104 virtual void configure(Winograd3x3F32 *convolver);
105
106protected:
107 Winograd3x3F32 *_convolver;
108};
109
110class NEWinogradLayerTransformInputKernel final : public INEWinogradLayerTransformKernel
111{
112public:
113 const char *name() const override
114 {
115 return "NEWinogradLayerTransformInputKernel";
116 }
117 // Inherited methods overridden:
118 void configure(Winograd3x3F32 *convolver) override;
119 void run(const Window &window, const ThreadInfo &info) override;
120 bool is_parallelisable() const override;
121};
122
123class NEWinogradLayerTransformOutputKernel final : public INEKernel
124{
125public:
126 const char *name() const override
127 {
128 return "NEWinogradLayerTransformOutputKernel";
129 }
130 /** Constructor */
131 NEWinogradLayerTransformOutputKernel();
132
133 /** Prevent instances of this class from being copied (As this class contains pointers) */
134 NEWinogradLayerTransformOutputKernel(const NEWinogradLayerTransformOutputKernel &) = delete;
135 /** Prevent instances of this class from being copied (As this class contains pointers) */
136 NEWinogradLayerTransformOutputKernel &operator=(const NEWinogradLayerTransformOutputKernel &) = delete;
137 /** Allow instances of this class to be moved */
138 NEWinogradLayerTransformOutputKernel(NEWinogradLayerTransformOutputKernel &&) = default;
139 /** Allow instances of this class to be moved */
140 NEWinogradLayerTransformOutputKernel &operator=(NEWinogradLayerTransformOutputKernel &&) = default;
141
142 ~NEWinogradLayerTransformOutputKernel() = default;
143
144 /** Configure the output transform kernel.
145 *
146 * @param[in] biases Pointer to the biases tensor.
147 * @param[in] output_workingspace Pointer to working space for the output tensor in the Winograd domain.
148 * @param[in] matrix_stride Output matrix stride, can be computed with winograd::WinogradGEMM<2, 2, 3, 3>::Convolution<float, float>::get_output_matrix_stride()
149 * @param[out] output Pointer to NHWC ordered output tensor, in the spatial domain.
150 * @param[in] n_batches Number of batches in the input tensor.
151 * @param[in] n_rows Number of rows in output tensor.
152 * @param[in] n_cols Number of columns in output tensor.
153 * @param[in] n_channels Number of feature maps in the output tensor.
154 */
155 void configure(
156 const ITensor *biases,
157 const float *const output_workingspace,
158 const int matrix_stride,
159 float *const output,
160 const int n_batches,
161 const int n_rows,
162 const int n_cols,
163 const int n_channels);
164
165 // Inherited methods overridden:
166 void run(const Window &window, const ThreadInfo &info) override;
167 bool is_parallelisable() const override;
168
169private:
170 const ITensor *_biases;
171 const float *_output_workspace;
172 int _matrix_stride;
173 int _matrix_row_stride;
174 float *_output;
175 int _n_batches;
176 int _n_rows;
177 int _n_cols;
178 int _n_channels;
179};
180
181class NEWinogradLayerTransformWeightsKernel final : public INEWinogradLayerTransformKernel
182{
183public:
184 const char *name() const override
185 {
186 return "NEWinogradLayerTransformWeightsKernel";
187 }
188 // Inherited methods overridden:
189 void configure(Winograd3x3F32 *convolver) override;
190 void run(const Window &window, const ThreadInfo &info) override;
191 bool is_parallelisable() const override;
192};
193
194class NEWinogradLayerKernel final : public INEKernel
Pablo Tello89519332017-11-17 11:52:36 +0000195{
196public:
Anthony Barbiere8a49832018-01-18 10:04:05 +0000197 const char *name() const override
198 {
199 return "NEWinogradLayerKernel";
200 }
Pablo Tello89519332017-11-17 11:52:36 +0000201 /** Constructor */
202 NEWinogradLayerKernel();
203
204 /** Prevent instances of this class from being copied (As this class contains pointers) */
205 NEWinogradLayerKernel(const NEWinogradLayerKernel &) = delete;
206 /** Prevent instances of this class from being copied (As this class contains pointers) */
207 NEWinogradLayerKernel &operator=(const NEWinogradLayerKernel &) = delete;
208 /** Allow instances of this class to be moved */
209 NEWinogradLayerKernel(NEWinogradLayerKernel &&) = default;
210 /** Allow instances of this class to be moved */
211 NEWinogradLayerKernel &operator=(NEWinogradLayerKernel &&) = default;
212
Pablo Tellod6ca4782018-01-23 09:36:04 +0000213 ~NEWinogradLayerKernel() = default;
Pablo Tello89519332017-11-17 11:52:36 +0000214
215 /** Initialise the kernel
216 *
Pablo Tello02541fb2017-12-15 09:48:59 +0000217 * @param[in] convolver A pointer to the winograd convolver, this object must have been configured and is ready to execute 16 GEMMS .
Pablo Tello89519332017-11-17 11:52:36 +0000218 */
Pablo Tello02541fb2017-12-15 09:48:59 +0000219 void configure(Winograd3x3F32 *convolver);
Pablo Tello89519332017-11-17 11:52:36 +0000220
221 // Inherited methods overridden:
222 void run(const Window &window, const ThreadInfo &info) override;
223
Pablo Tello6c6e77a2018-01-23 10:03:27 +0000224 /** Determine how much memory (in units of TIn) to allocate for the
225 * transformed weights.
226 *
227 * @param[in] n_output_channels Number of output feature maps.
228 * @param[in] n_input_channels Number of input feature maps.
229 */
230 static unsigned int get_weight_storage_size(
231 const int n_output_channels,
232 const int n_input_channels);
Pablo Tello3d4968a2017-12-04 15:03:35 +0000233
Pablo Tello6c6e77a2018-01-23 10:03:27 +0000234 /** Determine how much memory (in units of TIn) to allocate for the
235 * transformed input.
236 *
237 * @param[in] n_batches Number of batches in the input tensor.
238 * @param[in] n_channels Number of feature maps in the input tensor.
239 * @param[in] n_rows Number of rows in each feature map.
240 * @param[in] n_cols Number of columns in each feature map.
241 * @param[in] same_padding Use "SAME" padding, otherwise use "VALID".
242 */
Pablo Tello9ceebbe2018-01-10 16:44:13 +0000243 static unsigned int get_input_storage_size(
Pablo Tello6c6e77a2018-01-23 10:03:27 +0000244 const int n_batches,
245 const int n_channels,
246 const int n_rows,
247 const int n_cols,
248 const bool same_padding);
Pablo Tello3d4968a2017-12-04 15:03:35 +0000249
Pablo Tello9ceebbe2018-01-10 16:44:13 +0000250 /** Determine how much memory (in units of TOut) to allocate for the
251 * (Winograd domain) output.
Pablo Tello6c6e77a2018-01-23 10:03:27 +0000252 *
253 * @param[in] n_batches Number of batches in the output tensor.
254 * @param[in] n_rows Number of rows in each feature map of the input tensor.
255 * @param[in] n_cols Number of columns in each feature map of the input tensor.
256 * @param[in] n_output_channels Number of feature maps in the output tensor.
257 * @param[in] same_padding Use "SAME" padding, otherwise use "VALID".
Pablo Tello9ceebbe2018-01-10 16:44:13 +0000258 */
259 static unsigned int get_output_storage_size(
Pablo Tello6c6e77a2018-01-23 10:03:27 +0000260 const int n_batches,
261 const int n_rows,
262 const int n_cols,
263 const int n_output_channels,
264 const bool same_padding);
Pablo Tello3d4968a2017-12-04 15:03:35 +0000265
Pablo Tello89519332017-11-17 11:52:36 +0000266protected:
267 Winograd3x3F32 *_convolver;
Pablo Tello89519332017-11-17 11:52:36 +0000268};
269
270} // namespace arm_compute
271#endif /*__ARM_COMPUTE_NEGEMMWINOGRADLAYERKERNEL_H__*/