blob: 78ac56418f920ba06f09bc37bacce9e9906bb536 [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 Tello02541fb2017-12-15 09:48:59 +000035
Pablo Tello4e2c1392018-01-09 10:30:27 +000036class Winograd3x3F32 final
Pablo Tello3d4968a2017-12-04 15:03:35 +000037{
38public:
Pablo Tello6c6e77a2018-01-23 10:03:27 +000039 /** Create a new Winograd convolution layer.
40 *
41 * @param[in] n_batches Number of batches in the input and output tensors.
42 * @param[in] n_input_channels Number of feature maps in a batch of the input tensor.
43 * @param[in] n_input_rows Number of rows in a feature map of the input tensor.
44 * @param[in] n_input_cols Number of columns in a feature map of the input tensor.
45 * @param[in] n_output_channels Number of feature maps in the output tensor.
46 * @param[in] same_padding Use "SAME" padding, otherwise use "VALID".
47 * @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.
48 * @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
49 * @param[in] input Pointer to NHWC ordered input tensor, in the spatial domain.
50 * @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`.
51 * @param[out] output Pointer to NHWC ordered output tensor, in the spatial domain.
52 * @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`.
53 */
Pablo Tello3d4968a2017-12-04 15:03:35 +000054 friend class NEWinogradLayerKernel;
Pablo Tello9ceebbe2018-01-10 16:44:13 +000055 Winograd3x3F32(
Pablo Tello6c6e77a2018-01-23 10:03:27 +000056 const int n_batches,
57 const int n_input_channels,
58 const int n_input_rows,
59 const int n_input_cols,
60 const int n_output_channels,
61 const bool same_padding,
62 const float *const weights,
63 float *const weights_storage,
64 const float *const input,
65 float *const winograd_input,
66 float *const output,
67 float *const winograd_output);
Pablo Tello9ceebbe2018-01-10 16:44:13 +000068
Pablo Tello3d4968a2017-12-04 15:03:35 +000069 ~Winograd3x3F32();
Pablo Tello9ceebbe2018-01-10 16:44:13 +000070 void transform_weights();
71 void transform_input();
72 void transform_output();
Pablo Tello3d4968a2017-12-04 15:03:35 +000073
74private:
75 class Private;
76 std::unique_ptr<Private> _pimpl;
77};
Pablo Tello89519332017-11-17 11:52:36 +000078
79class NEWinogradLayerKernel : public INEKernel
80{
81public:
Pablo Tello89519332017-11-17 11:52:36 +000082 /** Constructor */
83 NEWinogradLayerKernel();
84
85 /** Prevent instances of this class from being copied (As this class contains pointers) */
86 NEWinogradLayerKernel(const NEWinogradLayerKernel &) = delete;
87 /** Prevent instances of this class from being copied (As this class contains pointers) */
88 NEWinogradLayerKernel &operator=(const NEWinogradLayerKernel &) = delete;
89 /** Allow instances of this class to be moved */
90 NEWinogradLayerKernel(NEWinogradLayerKernel &&) = default;
91 /** Allow instances of this class to be moved */
92 NEWinogradLayerKernel &operator=(NEWinogradLayerKernel &&) = default;
93
94 virtual ~NEWinogradLayerKernel() = default;
95
96 /** Initialise the kernel
97 *
Pablo Tello02541fb2017-12-15 09:48:59 +000098 * @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 +000099 */
Pablo Tello02541fb2017-12-15 09:48:59 +0000100 void configure(Winograd3x3F32 *convolver);
Pablo Tello89519332017-11-17 11:52:36 +0000101
102 // Inherited methods overridden:
103 void run(const Window &window, const ThreadInfo &info) override;
104
Pablo Tello6c6e77a2018-01-23 10:03:27 +0000105 /** Determine how much memory (in units of TIn) to allocate for the
106 * transformed weights.
107 *
108 * @param[in] n_output_channels Number of output feature maps.
109 * @param[in] n_input_channels Number of input feature maps.
110 */
111 static unsigned int get_weight_storage_size(
112 const int n_output_channels,
113 const int n_input_channels);
Pablo Tello3d4968a2017-12-04 15:03:35 +0000114
Pablo Tello6c6e77a2018-01-23 10:03:27 +0000115 /** Determine how much memory (in units of TIn) to allocate for the
116 * transformed input.
117 *
118 * @param[in] n_batches Number of batches in the input tensor.
119 * @param[in] n_channels Number of feature maps in the input tensor.
120 * @param[in] n_rows Number of rows in each feature map.
121 * @param[in] n_cols Number of columns in each feature map.
122 * @param[in] same_padding Use "SAME" padding, otherwise use "VALID".
123 */
Pablo Tello9ceebbe2018-01-10 16:44:13 +0000124 static unsigned int get_input_storage_size(
Pablo Tello6c6e77a2018-01-23 10:03:27 +0000125 const int n_batches,
126 const int n_channels,
127 const int n_rows,
128 const int n_cols,
129 const bool same_padding);
Pablo Tello3d4968a2017-12-04 15:03:35 +0000130
Pablo Tello9ceebbe2018-01-10 16:44:13 +0000131 /** Determine how much memory (in units of TOut) to allocate for the
132 * (Winograd domain) output.
Pablo Tello6c6e77a2018-01-23 10:03:27 +0000133 *
134 * @param[in] n_batches Number of batches in the output tensor.
135 * @param[in] n_rows Number of rows in each feature map of the input tensor.
136 * @param[in] n_cols Number of columns in each feature map of the input tensor.
137 * @param[in] n_output_channels Number of feature maps in the output tensor.
138 * @param[in] same_padding Use "SAME" padding, otherwise use "VALID".
Pablo Tello9ceebbe2018-01-10 16:44:13 +0000139 */
140 static unsigned int get_output_storage_size(
Pablo Tello6c6e77a2018-01-23 10:03:27 +0000141 const int n_batches,
142 const int n_rows,
143 const int n_cols,
144 const int n_output_channels,
145 const bool same_padding);
Pablo Tello3d4968a2017-12-04 15:03:35 +0000146
Pablo Tello89519332017-11-17 11:52:36 +0000147protected:
148 Winograd3x3F32 *_convolver;
Pablo Tello89519332017-11-17 11:52:36 +0000149};
150
151} // namespace arm_compute
152#endif /*__ARM_COMPUTE_NEGEMMWINOGRADLAYERKERNEL_H__*/