ONE - On-device Neural Engine
Loading...
Searching...
No Matches
Conv2DLayer.cc
Go to the documentation of this file.
1/*
2 * Copyright (c) 2020 Samsung Electronics Co., Ltd. All Rights Reserved
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#include "Conv2DLayer.h"
18
19#include "../KernelGenerator.h"
20#include "../Tensor.h"
21#include "../Validator.h"
22
23#include "ir/Padding.h"
24
25namespace onert::backend::ruy
26{
27
28void Validator::visit(const ir::operation::Conv2D &) { _supported = true; }
29
30void KernelGenerator::visit(const ir::operation::Conv2D &node)
31{
32 using ir::operation::Conv2D;
33
34 const auto ofm_index{node.getOutputs().at(0)};
35 const auto ifm_index{node.getInputs().at(Conv2D::Input::INPUT)};
36 const auto ker_index{node.getInputs().at(Conv2D::Input::KERNEL)};
37 const auto bias_index{node.getInputs().at(Conv2D::Input::BIAS)};
38
39 auto ofm_tensor = _tensor_reg->getPortableTensor(ofm_index);
40 auto ifm_tensor = _tensor_reg->getPortableTensor(ifm_index);
41 auto ker_tensor = _tensor_reg->getPortableTensor(ker_index);
42 auto bias_tensor = _tensor_reg->getPortableTensor(bias_index);
43
44 const auto stride = node.param().stride;
45 const auto activation = node.param().activation;
46 const auto &param_padding = node.param().padding;
47 const auto dilation = node.param().dilation;
48 auto fn = std::make_unique<ops::ConvolutionLayer>();
49
50 if (_ctx.at(ifm_index).info().isDynamic() || _ctx.at(ker_index).info().isDynamic())
51 {
52 fn->configure(ifm_tensor, ker_tensor, bias_tensor, param_padding.type, param_padding.param.left,
53 param_padding.param.right, param_padding.param.top, param_padding.param.bottom,
54 stride.horizontal, stride.vertical, dilation.width_factor, dilation.height_factor,
55 activation, ofm_tensor, _external_context);
56
57 _return_fn = std::move(fn);
58 return;
59 }
60 const auto ifm_shape = _ctx.at(ifm_index).shape().asFeature();
61 const auto ofm_shape = _ctx.at(ofm_index).shape().asFeature();
62 // Kernel format is [depth_out, kernel_height, kernel_width, depth_in].
63 const auto &ker_shape = _ctx.at(ker_index).shape();
64 const auto ker_height = ker_shape.dim(1);
65 const auto ker_width = ker_shape.dim(2);
66
67 const auto padding =
68 ir::calculatePadding(param_padding, ifm_shape, ofm_shape, stride, ker_width, ker_height,
69 dilation.width_factor, dilation.height_factor);
70
71 fn->configure(ifm_tensor, ker_tensor, bias_tensor, param_padding.type, padding.left,
72 padding.right, padding.top, padding.bottom, stride.horizontal, stride.vertical,
73 dilation.width_factor, dilation.height_factor, activation, ofm_tensor,
74 _external_context);
75
76 _return_fn = std::move(fn);
77}
78
79} // namespace onert::backend::ruy
80
82{
84 : _input(nullptr), _kernel(nullptr), _bias(nullptr), _output(nullptr),
85 _paddingType(ir::PaddingType::EXPLICIT), _paddingLeft(0), _paddingTop(0), _paddingRight(0),
86 _paddingBottom(0), _strideWidth(0), _strideHeight(0), _dilationWidthFactor(1),
87 _dilationHeightFactor(1), _activation(ir::Activation::NONE),
88 _conv_kernel(new nnfw::ruy::Conv()), _prepare(false)
89{
90 // DO NOTHING
91}
92
94
96{
97 float output_activation_min = 0, output_activation_max = 0;
98 CalculateActivationRange(_activation, &output_activation_min, &output_activation_max);
99
100 nnfw::ruy::ConvParams op_params;
101 op_params.padding_type = getPaddingType(_paddingType);
102 op_params.padding_values.width = _paddingLeft;
103 op_params.padding_values.height = _paddingTop;
104 op_params.stride_width = _strideWidth;
105 op_params.stride_height = _strideHeight;
106 op_params.dilation_width_factor = _dilationWidthFactor;
107 op_params.dilation_height_factor = _dilationHeightFactor;
108 op_params.float_activation_min = output_activation_min;
109 op_params.float_activation_max = output_activation_max;
110
111 nnfw::ruy::Conv &kernel = *_conv_kernel;
112 kernel(op_params, getTensorShape(_input), reinterpret_cast<const float *>(_input->buffer()),
113 getTensorShape(_kernel), reinterpret_cast<const float *>(_kernel->buffer()),
114 getTensorShape(_bias), reinterpret_cast<const float *>(_bias->buffer()),
115 getTensorShape(_output), reinterpret_cast<float *>(_output->buffer()),
116 _external_context->ruy_context());
117}
118
120 const IPortableTensor *bias, const ir::PaddingType paddingType,
121 const uint32_t paddingLeft, const uint32_t paddingRight,
122 const uint32_t paddingTop, const uint32_t paddingBottom,
123 const uint32_t strideWidth, const uint32_t strideHeight,
124 const uint32_t dilationWidthFactor,
125 const uint32_t dilationHeightFactor,
126 const ir::Activation activation, IPortableTensor *output,
127 const std::shared_ptr<ExternalContext> &external_context)
128{
129 _input = input;
130 _kernel = kernel;
131 _bias = bias;
132 _paddingType = paddingType;
133 _paddingLeft = paddingLeft;
134 _paddingRight = paddingRight;
135 _paddingTop = paddingTop;
136 _paddingBottom = paddingBottom;
137 _strideWidth = strideWidth;
138 _strideHeight = strideHeight;
139 _dilationWidthFactor = dilationWidthFactor;
140 _dilationHeightFactor = dilationHeightFactor;
141 _activation = activation;
142 _output = output;
143 _external_context = external_context;
144}
145
147{
148 prepare();
149
150 if (_input->is_dynamic() || _kernel->is_dynamic())
151 {
152 const auto ifm_shape = _input->getShape().asFeature();
153 const auto ofm_shape = _output->getShape().asFeature();
154 // Kernel format is [depth_out, kernel_height, kernel_width, depth_in].
155 const auto ker_shape = _kernel->getShape();
156 const auto ker_height = ker_shape.dim(1);
157 const auto ker_width = ker_shape.dim(2);
158
159 ir::Stride stride;
160 stride.vertical = _strideWidth;
161 stride.horizontal = _strideWidth;
162
163 ir::Padding param_padding;
164 param_padding.type = _paddingType;
165 param_padding.param.left = _paddingLeft;
166 param_padding.param.right = _paddingRight;
167 param_padding.param.top = _paddingTop;
168 param_padding.param.bottom = _paddingBottom;
169
170 const auto padding =
171 ir::calculatePadding(param_padding, ifm_shape, ofm_shape, stride, ker_width, ker_height,
172 _dilationWidthFactor, _dilationHeightFactor);
173
174 _paddingLeft = padding.left;
175 _paddingRight = padding.right;
176 _paddingTop = padding.top;
177 _paddingBottom = padding.bottom;
178 }
179 if (_input->data_type() == OperandType::FLOAT32)
180 {
181 convFloat32();
182 }
183 else
184 {
185 throw std::runtime_error{"Conv: unsupported data type"};
186 }
187}
188
190{
191 if (_prepare)
192 return;
193
194 nnfw::ruy::Conv &kernel = *_conv_kernel;
195 if (_input->data_type() == OperandType::FLOAT32 && _kernel->is_constant())
196 {
197 kernel.prepare(getTensorShape(_input), getTensorShape(_kernel), getTensorShape(_output),
198 _strideWidth, _strideHeight, _dilationWidthFactor, _dilationHeightFactor);
199 }
200 _prepare = true;
201}
202
203} // namespace onert::backend::ruy::ops
void Conv(const float *input_data, const Dims< 4 > &input_dims, const float *filter_data, const Dims< 4 > &filter_dims, const float *bias_data, const Dims< 4 > &bias_dims, int stride_width, int stride_height, int pad_width, int pad_height, float *output_data, const Dims< 4 > &output_dims, float *im2col_data, const Dims< 4 > &im2col_dims)
void prepare(const Shape &input_shape, const Shape &kernel_shape, const Shape &output_shape, uint32_t stride_width, uint32_t stride_height, uint32_t dilation_width_factor, uint32_t dilation_height_factor)
Definition Conv.h:41
A tensor class that is portable for other backends.
ir::DataType data_type() const override final
ir::Shape getShape() const override final
Get ir::Shape of tensor.
bool is_dynamic() const override final
Return true if the tensor needs dynamic allocation, meaning that during compile-time the outpus shape...
bool is_constant() const override final
Return true if the tensor is constant.
virtual uint8_t * buffer() const =0
std::unique_ptr< exec::IFunction > _return_fn
void configure(const IPortableTensor *input, const IPortableTensor *kernel, const IPortableTensor *bias, ir::PaddingType _paddingType, const uint32_t paddingLeft, const uint32_t paddingRight, const uint32_t paddingTop, const uint32_t paddingBottom, const uint32_t strideWidth, const uint32_t strideHeight, const uint32_t dilationWidthFactor, const uint32_t dilationHeightFactor, const ir::Activation activation, IPortableTensor *output, const std::shared_ptr< ExternalContext > &external_context)
const Object & at(const Index &index) const
Get the object that is associated with the given index.
Definition topk_v2.h:30
nnfw::ruy::Shape getTensorShape(const IPortableTensor *tensor)
const ExplicitPadding calculatePadding(const Padding &padding, const FeatureShape &ifm_shape, const FeatureShape &ofm_shape, const Stride &stride, uint32_t kw, uint32_t kh, uint32_t dwf=1, uint32_t dhf=1)
Definition Padding.cc:131
void CalculateActivationRange(ir::Activation activation, T *activation_min, T *activation_max)
CLTensor ker_tensor
CLTensor bias_tensor
float float_activation_max
Definition Types.h:77
PaddingType padding_type
Definition Types.h:58
PaddingValues padding_values
Definition Types.h:59
float float_activation_min
Definition Types.h:76
int16_t dilation_height_factor
Definition Types.h:64
int16_t stride_width
Definition Types.h:61
int16_t dilation_width_factor
Definition Types.h:63
int16_t stride_height
Definition Types.h:62
PaddingType type
Definition Padding.h:59
ExplicitPadding param
Definition Padding.h:60