blob: bbfda9ca826d9d1a71e72a68a366f67c9620001f [file] [log] [blame]
Georgios Pinitasd8734b52017-12-22 15:27:52 +00001/*
2 * Copyright (c) 2018 ARM Limited.
3 *
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 */
Georgios Pinitasd9eb2752018-04-03 13:44:29 +010024#ifndef __ARM_COMPUTE_GRAPH_LAYERS_H__
25#define __ARM_COMPUTE_GRAPH_LAYERS_H__
Georgios Pinitasd8734b52017-12-22 15:27:52 +000026
Georgios Pinitasd9eb2752018-04-03 13:44:29 +010027#include "arm_compute/graph/GraphBuilder.h"
28#include "arm_compute/graph/Types.h"
29#include "arm_compute/graph/frontend/ILayer.h"
30#include "arm_compute/graph/frontend/IStream.h"
31#include "arm_compute/graph/frontend/SubStream.h"
Georgios Pinitasd8734b52017-12-22 15:27:52 +000032
33#include "arm_compute/core/utils/misc/Utility.h"
34
35#include <memory>
36#include <string>
37
38namespace arm_compute
39{
Georgios Pinitasd9eb2752018-04-03 13:44:29 +010040namespace graph
Georgios Pinitasd8734b52017-12-22 15:27:52 +000041{
42namespace frontend
43{
44/** Input Layer */
45class InputLayer final : public ILayer
46{
47public:
Alex Gildayc357c472018-03-21 13:54:09 +000048 /** Construct an input layer.
49 *
50 * @param[in] desc Description of input tensor.
51 * @param[in] accessor Accessor to get input tensor data from.
52 */
Georgios Pinitasd8734b52017-12-22 15:27:52 +000053 InputLayer(TensorDescriptor desc, ITensorAccessorUPtr accessor)
54 : _desc(desc), _accessor(std::move(accessor))
55 {
56 }
57
58 NodeID create_layer(IStream &s) override
59 {
Georgios Pinitas5c2fb3f2018-05-01 15:26:20 +010060 NodeParams common_params = { name(), s.hints().target_hint };
Georgios Pinitasd8734b52017-12-22 15:27:52 +000061 return GraphBuilder::add_input_node(s.graph(), common_params, _desc, std::move(_accessor));
62 }
63
64private:
65 TensorDescriptor _desc;
66 ITensorAccessorUPtr _accessor;
67};
68
69/** Output Layer */
70class OutputLayer final : public ILayer
71{
72public:
Alex Gildayc357c472018-03-21 13:54:09 +000073 /** Construct an output layer.
74 *
75 * @param[in] accessor Accessor to give output tensor data to.
76 */
Georgios Pinitasd8734b52017-12-22 15:27:52 +000077 OutputLayer(ITensorAccessorUPtr accessor)
78 : _accessor(std::move(accessor))
79 {
80 }
81
82 NodeID create_layer(IStream &s) override
83 {
Georgios Pinitas5c2fb3f2018-05-01 15:26:20 +010084 NodeParams common_params = { name(), s.hints().target_hint };
Georgios Pinitasd8734b52017-12-22 15:27:52 +000085 NodeIdxPair input = { s.tail_node(), 0 };
86 return GraphBuilder::add_output_node(s.graph(), common_params, input, std::move(_accessor));
87 }
88
89private:
90 ITensorAccessorUPtr _accessor;
91};
92
93/** Activation Layer */
94class ActivationLayer final : public ILayer
95{
96public:
Alex Gildayc357c472018-03-21 13:54:09 +000097 /** Construct an activation layer.
98 *
99 * @param[in] act_info Activation information
100 */
Georgios Pinitasd8734b52017-12-22 15:27:52 +0000101 ActivationLayer(ActivationLayerInfo act_info)
102 : _act_info(act_info)
103 {
104 }
105
106 NodeID create_layer(IStream &s) override
107 {
Georgios Pinitas5c2fb3f2018-05-01 15:26:20 +0100108 NodeParams common_params = { name(), s.hints().target_hint };
Georgios Pinitasd8734b52017-12-22 15:27:52 +0000109 NodeIdxPair input = { s.tail_node(), 0 };
110 return GraphBuilder::add_activation_node(s.graph(), common_params, input, _act_info);
111 }
112
113private:
114 ActivationLayerInfo _act_info;
115};
116
117/** Batchnormalization Layer */
118class BatchNormalizationLayer final : public ILayer
119{
120public:
Alex Gildayc357c472018-03-21 13:54:09 +0000121 /** Construct a batch normalization layer.
122 *
123 * @param[in] mean Accessor to get mean tensor data from.
124 * @param[in] var Accessor to get var tensor data from.
125 * @param[in] gamma (Optional) Accessor to get gamma tensor data from. Default: nullptr.
126 * @param[in] beta (Optional) Accessor to get beta tensor data from. Default: nullptr.
127 * @param[in] epsilon (Optional) Epsilon value. Default: 0.001.
128 */
Georgios Pinitasd8734b52017-12-22 15:27:52 +0000129 BatchNormalizationLayer(ITensorAccessorUPtr mean,
130 ITensorAccessorUPtr var,
131 ITensorAccessorUPtr gamma = nullptr,
132 ITensorAccessorUPtr beta = nullptr,
133 float epsilon = 0.001f)
134 : _mean(std::move(mean)), _var(std::move(var)), _gamma(std::move(gamma)), _beta(std::move(beta)), _epsilon(epsilon)
135 {
136 }
137
138 NodeID create_layer(IStream &s) override
139 {
140 ARM_COMPUTE_ERROR_ON(_mean == nullptr);
141 ARM_COMPUTE_ERROR_ON(_var == nullptr);
142
Georgios Pinitas5c2fb3f2018-05-01 15:26:20 +0100143 NodeParams common_params = { name(), s.hints().target_hint };
Georgios Pinitasd8734b52017-12-22 15:27:52 +0000144 NodeIdxPair input = { s.tail_node(), 0 };
145 return GraphBuilder::add_batch_normalization_node(s.graph(), common_params, input, _epsilon,
146 std::move(_mean), std::move(_var), std::move(_beta), std::move(_gamma));
147 }
148
149private:
150 ITensorAccessorUPtr _mean;
151 ITensorAccessorUPtr _var;
152 ITensorAccessorUPtr _gamma;
153 ITensorAccessorUPtr _beta;
154 float _epsilon;
155};
156
Georgios Pinitas087eaf62018-05-16 15:52:35 +0100157/** Channel Shuffle Layer */
158class ChannelShuffleLayer final : public ILayer
159{
160public:
161 /** Construct a Channel Shuffle layer.
162 *
163 * @param[in] num_groups Number of groups
164 */
165 ChannelShuffleLayer(unsigned int num_groups)
166 : _num_groups(num_groups)
167 {
168 }
169
170 NodeID create_layer(IStream &s) override
171 {
172 NodeParams common_params = { name(), s.hints().target_hint };
173 NodeIdxPair input = { s.tail_node(), 0 };
174 return GraphBuilder::add_channel_shuffle_node(s.graph(), common_params, input, _num_groups);
175 }
176
177private:
178 unsigned int _num_groups;
179};
180
Georgios Pinitas427bbbf2018-08-28 13:32:02 +0100181/** Concat Layer */
182class ConcatLayer final : public ILayer
183{
184public:
185 /** Construct a concatenation layer
186 *
187 * @param[in] sub_stream1 First graph branch
188 * @param[in] sub_stream2 Second graph branch
189 * @param[in] rest_sub_streams Rest sub-graph branches
190 */
191 template <typename... Ts>
192 ConcatLayer(SubStream &&sub_stream1, SubStream &&sub_stream2, Ts &&... rest_sub_streams)
193 : _sub_streams()
194 {
195 _sub_streams.push_back(arm_compute::support::cpp14::make_unique<SubStream>(std::move(sub_stream1)));
196 _sub_streams.push_back(arm_compute::support::cpp14::make_unique<SubStream>(std::move(sub_stream2)));
197
198 utility::for_each([&](SubStream && sub_stream)
199 {
200 _sub_streams.push_back(arm_compute::support::cpp14::make_unique<SubStream>(std::move(sub_stream)));
201 },
202 std::move(rest_sub_streams)...);
203 }
204 /** Construct a concat layer
205 *
206 * @param[in] sub_stream Sub-stream
207 */
208 template <typename... Ts>
209 ConcatLayer(SubStream &&sub_stream)
210 : _sub_streams()
211 {
212 _sub_streams.push_back(arm_compute::support::cpp14::make_unique<SubStream>(std::move(sub_stream)));
213 }
214 NodeID create_layer(IStream &s) override
215 {
216 NodeID nid = EmptyNodeID;
217 NodeParams common_params = { name(), s.hints().target_hint };
218 if(_sub_streams.size() == 1 && _sub_streams.at(0) != nullptr)
219 {
220 nid = _sub_streams[0]->tail_node();
221 }
222 else
223 {
224 // Collect tail nodes and concatenate
225 std::vector<NodeIdxPair> nodes;
226 for(auto &ss : _sub_streams)
227 {
228 if(ss && (ss->tail_node() != EmptyNodeID))
229 {
230 const auto tail_node = s.graph().node(ss->tail_node());
231 if(tail_node != nullptr && tail_node->type() != NodeType::Output)
232 {
233 nodes.push_back({ ss->tail_node(), 0 });
234 }
235 }
236 }
237 nid = GraphBuilder::add_concatenate_node(s.graph(), common_params, nodes, DataLayoutDimension::CHANNEL);
238 }
239 return nid;
240 }
241
242private:
243 std::vector<std::unique_ptr<SubStream>> _sub_streams;
244};
245
Georgios Pinitasd8734b52017-12-22 15:27:52 +0000246/** Convolution Layer */
247class ConvolutionLayer final : public ILayer
248{
249public:
Alex Gildayc357c472018-03-21 13:54:09 +0000250 /** Construct a convolution layer.
251 *
Giorgio Arenabb54e4e2018-04-05 17:20:34 +0100252 * @param[in] conv_width Convolution width.
253 * @param[in] conv_height Convolution height.
254 * @param[in] ofm Output feature map.
255 * @param[in] weights Accessor to get kernel weights from.
256 * @param[in] bias Accessor to get kernel bias from.
257 * @param[in] conv_info Padding and stride information.
258 * @param[in] num_groups (Optional) Number of groups. Default: 1.
259 * @param[in] weights_quant_info (Optional) Weights quantization information
260 * @param[in] out_quant_info (Optional) Output quantization info
Alex Gildayc357c472018-03-21 13:54:09 +0000261 */
Giorgio Arenabb54e4e2018-04-05 17:20:34 +0100262 ConvolutionLayer(unsigned int conv_width,
263 unsigned int conv_height,
264 unsigned int ofm,
265 ITensorAccessorUPtr weights,
266 ITensorAccessorUPtr bias,
267 PadStrideInfo conv_info,
268 unsigned int num_groups = 1,
269 const QuantizationInfo weights_quant_info = QuantizationInfo(),
270 const QuantizationInfo out_quant_info = QuantizationInfo())
Georgios Pinitasd8734b52017-12-22 15:27:52 +0000271 : _conv_width(conv_width),
272 _conv_height(conv_height),
273 _ofm(ofm),
274 _conv_info(std::move(conv_info)),
275 _num_groups(num_groups),
276 _weights(std::move(weights)),
Giorgio Arenabb54e4e2018-04-05 17:20:34 +0100277 _bias(std::move(bias)),
278 _weights_quant_info(std::move(weights_quant_info)),
279 _out_quant_info(std::move(out_quant_info))
Georgios Pinitasd8734b52017-12-22 15:27:52 +0000280 {
281 }
282
283 NodeID create_layer(IStream &s) override
284 {
Georgios Pinitasd8734b52017-12-22 15:27:52 +0000285 NodeIdxPair input = { s.tail_node(), 0 };
Georgios Pinitas5c2fb3f2018-05-01 15:26:20 +0100286 NodeParams common_params = { name(), s.hints().target_hint };
Georgios Pinitasd8734b52017-12-22 15:27:52 +0000287 return GraphBuilder::add_convolution_node(s.graph(), common_params, input,
Georgios Pinitasee33ea52018-03-08 16:01:29 +0000288 Size2D(_conv_width, _conv_height), _ofm, _conv_info, _num_groups,
Giorgio Arena59631a12018-05-02 13:59:04 +0100289 s.hints().convolution_method_hint, s.hints().fast_math_hint,
Giorgio Arenabb54e4e2018-04-05 17:20:34 +0100290 std::move(_weights), std::move(_bias), std::move(_weights_quant_info), std::move(_out_quant_info));
Georgios Pinitasd8734b52017-12-22 15:27:52 +0000291 }
292
293private:
Giorgio Arenabb54e4e2018-04-05 17:20:34 +0100294 unsigned int _conv_width;
295 unsigned int _conv_height;
296 unsigned int _ofm;
297 const PadStrideInfo _conv_info;
298 unsigned int _num_groups;
299 ITensorAccessorUPtr _weights;
300 ITensorAccessorUPtr _bias;
301 const QuantizationInfo _weights_quant_info;
302 const QuantizationInfo _out_quant_info;
Georgios Pinitasd8734b52017-12-22 15:27:52 +0000303};
304
Georgios Pinitas087eaf62018-05-16 15:52:35 +0100305/** Deconvolution Layer */
306class DeconvolutionLayer final : public ILayer
307{
308public:
309 /** Construct a convolution layer.
310 *
311 * @param[in] conv_width Convolution width.
312 * @param[in] conv_height Convolution height.
313 * @param[in] ofm Output feature map.
314 * @param[in] weights Accessor to get kernel weights from.
315 * @param[in] bias Accessor to get kernel bias from.
316 * @param[in] deconv_info Padding and stride information.
317 * @param[in] inner_border Inner border padding (right, top)
318 */
319 DeconvolutionLayer(unsigned int conv_width,
320 unsigned int conv_height,
321 unsigned int ofm,
322 ITensorAccessorUPtr weights,
323 ITensorAccessorUPtr bias,
324 PadStrideInfo deconv_info,
325 Size2D inner_border)
326 : _conv_width(conv_width),
327 _conv_height(conv_height),
328 _ofm(ofm),
329 _deconv_info(std::move(deconv_info)),
330 _inner_border(inner_border),
331 _weights(std::move(weights)),
332 _bias(std::move(bias))
333 {
334 }
335
336 NodeID create_layer(IStream &s) override
337 {
338 NodeIdxPair input = { s.tail_node(), 0 };
339 NodeParams common_params = { name(), s.hints().target_hint };
340 return GraphBuilder::add_deconvolution_node(s.graph(), common_params, input,
341 Size2D(_conv_width, _conv_height), _ofm, _deconv_info, _inner_border,
342 std::move(_weights), std::move(_bias));
343 }
344
345private:
346 unsigned int _conv_width;
347 unsigned int _conv_height;
348 unsigned int _ofm;
349 const PadStrideInfo _deconv_info;
350 Size2D _inner_border;
351 ITensorAccessorUPtr _weights;
352 ITensorAccessorUPtr _bias;
353};
354
Georgios Pinitasd8734b52017-12-22 15:27:52 +0000355/** Depthwise Convolution Layer */
356class DepthwiseConvolutionLayer final : public ILayer
357{
358public:
Alex Gildayc357c472018-03-21 13:54:09 +0000359 /** Construct a depthwise convolution layer.
360 *
361 * @param[in] conv_width Convolution width.
362 * @param[in] conv_height Convolution height.
363 * @param[in] weights Accessor to get kernel weights from.
364 * @param[in] bias Accessor to get kernel bias from.
365 * @param[in] conv_info Padding and stride information.
Giorgio Arenabb54e4e2018-04-05 17:20:34 +0100366 * @param[in] quant_info (Optional) Quantization info used for weights
Alex Gildayc357c472018-03-21 13:54:09 +0000367 */
Giorgio Arenabb54e4e2018-04-05 17:20:34 +0100368 DepthwiseConvolutionLayer(unsigned int conv_width,
369 unsigned int conv_height,
370 ITensorAccessorUPtr weights,
371 ITensorAccessorUPtr bias,
372 PadStrideInfo conv_info,
373 const QuantizationInfo quant_info = QuantizationInfo())
Georgios Pinitasd8734b52017-12-22 15:27:52 +0000374 : _conv_width(conv_width),
375 _conv_height(conv_height),
376 _conv_info(std::move(conv_info)),
377 _weights(std::move(weights)),
Giorgio Arenabb54e4e2018-04-05 17:20:34 +0100378 _bias(std::move(bias)),
379 _quant_info(std::move(quant_info))
Georgios Pinitasd8734b52017-12-22 15:27:52 +0000380 {
381 }
382
383 NodeID create_layer(IStream &s) override
384 {
385 NodeIdxPair input = { s.tail_node(), 0 };
Georgios Pinitas5c2fb3f2018-05-01 15:26:20 +0100386 NodeParams common_params = { name(), s.hints().target_hint };
Georgios Pinitasd8734b52017-12-22 15:27:52 +0000387 return GraphBuilder::add_depthwise_convolution_node(s.graph(), common_params,
388 input, Size2D(_conv_width, _conv_height), _conv_info,
389 s.hints().depthwise_convolution_method_hint,
Giorgio Arenabb54e4e2018-04-05 17:20:34 +0100390 std::move(_weights), std::move(_bias), std::move(_quant_info));
Georgios Pinitasd8734b52017-12-22 15:27:52 +0000391 }
392
393private:
Giorgio Arenabb54e4e2018-04-05 17:20:34 +0100394 unsigned int _conv_width;
395 unsigned int _conv_height;
396 const PadStrideInfo _conv_info;
397 ITensorAccessorUPtr _weights;
398 ITensorAccessorUPtr _bias;
399 const QuantizationInfo _quant_info;
Georgios Pinitasd8734b52017-12-22 15:27:52 +0000400};
401
Georgios Pinitas087eaf62018-05-16 15:52:35 +0100402/** Dummy Layer */
403class DummyLayer final : public ILayer
404{
405public:
406 /** Construct an input layer.
407 *
408 * @param[in] shape Output shape
409 */
410 DummyLayer(TensorShape shape)
411 : _shape(shape)
412 {
413 }
414
415 NodeID create_layer(IStream &s) override
416 {
417 NodeParams common_params = { name(), s.hints().target_hint };
418 NodeIdxPair input = { s.tail_node(), 0 };
419 return GraphBuilder::add_dummy_node(s.graph(), common_params, input, _shape);
420 }
421
422private:
423 TensorShape _shape;
424};
425
Georgios Pinitas427bbbf2018-08-28 13:32:02 +0100426class EltwiseLayer final : public ILayer
427{
428public:
429 /** Construct an element-wise operation layer
430 *
431 * @param[in] sub_stream0 First graph sub-stream
432 * @param[in] sub_stream1 First graph sub-stream
433 * @param[in] op Element-wise operation to perform
434 */
435 EltwiseLayer(SubStream &&sub_stream0, SubStream &&sub_stream1, EltwiseOperation op)
436 : _ss0(std::move(sub_stream0)), _ss1(std::move(sub_stream1)), _op(op)
437 {
438 }
439
440 NodeID create_layer(IStream &s) override
441 {
442 NodeParams common_params = { name(), s.hints().target_hint };
443 NodeIdxPair input0 = { _ss0.tail_node(), 0 };
444 NodeIdxPair input1 = { _ss1.tail_node(), 0 };
445
446 return GraphBuilder::add_elementwise_node(s.graph(), common_params, input0, input1, _op);
447 }
448
449private:
450 SubStream _ss0;
451 SubStream _ss1;
452 EltwiseOperation _op;
453};
Georgios Pinitasd8734b52017-12-22 15:27:52 +0000454/** Flatten Layer */
455class FlattenLayer final : public ILayer
456{
457public:
Alex Gildayc357c472018-03-21 13:54:09 +0000458 /** Construct a flatten layer. */
Georgios Pinitasd8734b52017-12-22 15:27:52 +0000459 FlattenLayer()
460 {
461 }
462
463 NodeID create_layer(IStream &s) override
464 {
Georgios Pinitas5c2fb3f2018-05-01 15:26:20 +0100465 NodeParams common_params = { name(), s.hints().target_hint };
Georgios Pinitasd8734b52017-12-22 15:27:52 +0000466 NodeIdxPair input = { s.tail_node(), 0 };
467 return GraphBuilder::add_flatten_node(s.graph(), common_params, input);
468 }
469};
470
471/** Fully Connected Layer */
472class FullyConnectedLayer final : public ILayer
473{
474public:
Alex Gildayc357c472018-03-21 13:54:09 +0000475 /** Construct a fully connected layer.
476 *
Georgios Pinitas2f1366a2018-07-31 16:33:06 +0100477 * @param[in] num_outputs Number of outputs.
478 * @param[in] weights Accessor to get weights from.
479 * @param[in] bias Accessor to get bias from.
Georgios Pinitasc55cef12018-08-01 15:24:18 +0100480 * @param[in] fc_info (Optional) Fully connected layer metadata
Georgios Pinitas2f1366a2018-07-31 16:33:06 +0100481 * @param[in] weights_quant_info (Optional) Weights quantization information
482 * @param[in] out_quant_info (Optional) Output quantization info
Alex Gildayc357c472018-03-21 13:54:09 +0000483 */
Georgios Pinitasc55cef12018-08-01 15:24:18 +0100484 FullyConnectedLayer(unsigned int num_outputs,
485 ITensorAccessorUPtr weights,
486 ITensorAccessorUPtr bias,
487 const FullyConnectedLayerInfo fc_info = FullyConnectedLayerInfo(),
488 const QuantizationInfo weights_quant_info = QuantizationInfo(),
489 const QuantizationInfo out_quant_info = QuantizationInfo())
Georgios Pinitas2f1366a2018-07-31 16:33:06 +0100490 : _num_outputs(num_outputs),
491 _weights(std::move(weights)),
492 _bias(std::move(bias)),
Georgios Pinitasc55cef12018-08-01 15:24:18 +0100493 _fc_info(fc_info),
Georgios Pinitas2f1366a2018-07-31 16:33:06 +0100494 _weights_quant_info(std::move(weights_quant_info)),
495 _out_quant_info(std::move(out_quant_info))
Georgios Pinitasd8734b52017-12-22 15:27:52 +0000496 {
497 }
498
499 NodeID create_layer(IStream &s) override
500 {
Georgios Pinitas5c2fb3f2018-05-01 15:26:20 +0100501 NodeParams common_params = { name(), s.hints().target_hint };
Georgios Pinitasd8734b52017-12-22 15:27:52 +0000502 NodeIdxPair input = { s.tail_node(), 0 };
503 return GraphBuilder::add_fully_connected_layer(s.graph(), common_params, input, _num_outputs,
Georgios Pinitasc55cef12018-08-01 15:24:18 +0100504 std::move(_weights), std::move(_bias), _fc_info,
Georgios Pinitas2f1366a2018-07-31 16:33:06 +0100505 std::move(_weights_quant_info), std::move(_out_quant_info));
Georgios Pinitasd8734b52017-12-22 15:27:52 +0000506 }
507
508private:
Georgios Pinitasc55cef12018-08-01 15:24:18 +0100509 unsigned int _num_outputs;
510 ITensorAccessorUPtr _weights;
511 ITensorAccessorUPtr _bias;
512 const FullyConnectedLayerInfo _fc_info;
513 const QuantizationInfo _weights_quant_info;
514 const QuantizationInfo _out_quant_info;
Georgios Pinitasd8734b52017-12-22 15:27:52 +0000515};
516
517/** Normalization Layer */
518class NormalizationLayer final : public ILayer
519{
520public:
Alex Gildayc357c472018-03-21 13:54:09 +0000521 /** Construct a normalization layer.
522 *
523 * @param[in] norm_info Normalization information.
524 */
Georgios Pinitasd8734b52017-12-22 15:27:52 +0000525 NormalizationLayer(NormalizationLayerInfo norm_info)
526 : _norm_info(norm_info)
527 {
528 }
529
530 NodeID create_layer(IStream &s) override
531 {
Georgios Pinitas5c2fb3f2018-05-01 15:26:20 +0100532 NodeParams common_params = { name(), s.hints().target_hint };
Georgios Pinitasd8734b52017-12-22 15:27:52 +0000533 NodeIdxPair input = { s.tail_node(), 0 };
534 return GraphBuilder::add_normalization_node(s.graph(), common_params, input, _norm_info);
535 }
536
537private:
538 NormalizationLayerInfo _norm_info;
539};
540
Michele Di Giorgio555d1102018-09-12 13:51:59 +0100541/** Normalize planar YUV Layer */
542class NormalizePlanarYUVLayer final : public ILayer
543{
544public:
545 /** Construct a normalize planar YUV layer.
546 *
547 * @param[in] mean Accessor to get mean tensor data from.
548 * @param[in] std Accessor to get std tensor data from.
549 */
550 NormalizePlanarYUVLayer(ITensorAccessorUPtr mean,
551 ITensorAccessorUPtr std)
552 : _mean(std::move(mean)), _std(std::move(std))
553 {
554 }
555
556 NodeID create_layer(IStream &s) override
557 {
558 ARM_COMPUTE_ERROR_ON(_mean == nullptr);
559 ARM_COMPUTE_ERROR_ON(_std == nullptr);
560
561 NodeParams common_params = { name(), s.hints().target_hint };
562 NodeIdxPair input = { s.tail_node(), 0 };
563 return GraphBuilder::add_normalize_planar_yuv_node(s.graph(), common_params, input,
564 std::move(_mean), std::move(_std));
565 }
566
567private:
568 ITensorAccessorUPtr _mean;
569 ITensorAccessorUPtr _std;
570};
571
Georgios Pinitas57c48242018-08-02 13:41:49 +0100572/** Permute Layer */
573class PermuteLayer final : public ILayer
574{
575public:
576 /** Construct a permute layer.
577 *
578 * @param[in] perm Permutation vector.
579 * @param[in] layout (Optional) Data layout to assign to permuted tensor.
580 * If UNKNOWN then the input's layout will be used.
581 */
582 PermuteLayer(PermutationVector perm, DataLayout layout = DataLayout::UNKNOWN)
583 : _perm(perm), _layout(layout)
584 {
585 }
586
587 NodeID create_layer(IStream &s) override
588 {
589 NodeParams common_params = { name(), s.hints().target_hint };
590 NodeIdxPair input = { s.tail_node(), 0 };
591 return GraphBuilder::add_permute_node(s.graph(), common_params, input, _perm, _layout);
592 }
593
594private:
595 PermutationVector _perm;
596 DataLayout _layout;
597};
598
Georgios Pinitasd8734b52017-12-22 15:27:52 +0000599/** Pooling Layer */
600class PoolingLayer final : public ILayer
601{
602public:
Alex Gildayc357c472018-03-21 13:54:09 +0000603 /** Construct a pooling layer.
604 *
605 * @param[in] pool_info Pooling information.
606 */
Georgios Pinitasd8734b52017-12-22 15:27:52 +0000607 PoolingLayer(PoolingLayerInfo pool_info)
608 : _pool_info(pool_info)
609 {
610 }
611
612 NodeID create_layer(IStream &s) override
613 {
Georgios Pinitas5c2fb3f2018-05-01 15:26:20 +0100614 NodeParams common_params = { name(), s.hints().target_hint };
Georgios Pinitasd8734b52017-12-22 15:27:52 +0000615 NodeIdxPair input = { s.tail_node(), 0 };
616 return GraphBuilder::add_pooling_node(s.graph(), common_params, input, _pool_info);
617 }
618
619private:
620 PoolingLayerInfo _pool_info;
621};
622
Gian Marco Iodice23e24792018-09-07 15:32:14 +0100623/** Reorg Layer */
624class ReorgLayer final : public ILayer
625{
626public:
627 /** Construct a reorg layer.
628 *
629 * @param[in] stride Stride value to use for reorganizing the values in the output tensor.
630 * It defines the spatial distance between 2 consecutive pixels in the x and y direction
631 */
632 ReorgLayer(int stride)
633 : _stride(stride)
634 {
635 }
636
637 NodeID create_layer(IStream &s) override
638 {
639 NodeParams common_params = { name(), s.hints().target_hint };
640 NodeIdxPair input = { s.tail_node(), 0 };
641 return GraphBuilder::add_reorg_node(s.graph(), common_params, input, _stride);
642 }
643
644private:
645 int _stride;
646};
647
Georgios Pinitasd8734b52017-12-22 15:27:52 +0000648/** Reshape Layer */
649class ReshapeLayer final : public ILayer
650{
651public:
Alex Gildayc357c472018-03-21 13:54:09 +0000652 /** Construct a reshape layer.
653 *
654 * @param[in] shape Target shape.
655 */
Georgios Pinitasd8734b52017-12-22 15:27:52 +0000656 ReshapeLayer(TensorShape shape)
657 : _shape(shape)
658 {
659 }
660
661 NodeID create_layer(IStream &s) override
662 {
Georgios Pinitas5c2fb3f2018-05-01 15:26:20 +0100663 NodeParams common_params = { name(), s.hints().target_hint };
Georgios Pinitasd8734b52017-12-22 15:27:52 +0000664 NodeIdxPair input = { s.tail_node(), 0 };
665 return GraphBuilder::add_reshape_node(s.graph(), common_params, input, _shape);
666 }
667
668private:
669 TensorShape _shape;
670};
671
Georgios Pinitas087eaf62018-05-16 15:52:35 +0100672/** Resize Layer */
673class ResizeLayer final : public ILayer
674{
675public:
676 ResizeLayer(InterpolationPolicy policy, float width_scale, float height_scale)
677 : _policy(policy), _width_scale(width_scale), _height_scale(height_scale)
678 {
679 }
680
681 NodeID create_layer(IStream &s) override
682 {
683 NodeParams common_params = { name(), s.hints().target_hint };
684 NodeIdxPair input = { s.tail_node(), 0 };
685 return GraphBuilder::add_resize_node(s.graph(), common_params, input, _policy, _width_scale, _height_scale);
686 }
687
688private:
689 InterpolationPolicy _policy;
690 float _width_scale;
691 float _height_scale;
692};
693
Isabella Gottardi88d5b222018-04-06 12:24:55 +0100694/** Scale Layer */
695class ScaleLayer final : public ILayer
696{
697public:
698 /** Construct a scale layer.
699 *
700 * @param[in] mul_w Accessor to get mul weight from.
701 * @param[in] add_w Accessor to get add weight from.
702 */
703 ScaleLayer(ITensorAccessorUPtr mul_w,
704 ITensorAccessorUPtr add_w)
705 : _mul_w(std::move(mul_w)), _add_w(std::move(add_w))
706 {
707 }
708
709 NodeID create_layer(IStream &s) override
710 {
711 NodeParams common_params = { name(), s.hints().target_hint };
712 NodeIdxPair input = { s.tail_node(), 0 };
713 return GraphBuilder::add_scale_layer(s.graph(), common_params, input, std::move(_mul_w), std::move(_add_w));
714 }
715
716private:
717 ITensorAccessorUPtr _mul_w;
718 ITensorAccessorUPtr _add_w;
719};
720
Georgios Pinitasd8734b52017-12-22 15:27:52 +0000721/** Softmax Layer */
722class SoftmaxLayer final : public ILayer
723{
724public:
Alex Gildayc357c472018-03-21 13:54:09 +0000725 /** Construct a softmax layer.
726 *
727 * @param[in] beta (Optional) Beta value. Default 1.0.
728 */
Georgios Pinitasd8734b52017-12-22 15:27:52 +0000729 SoftmaxLayer(float beta = 1.0f)
730 : _beta(beta)
731 {
732 }
733
734 NodeID create_layer(IStream &s) override
735 {
Georgios Pinitas5c2fb3f2018-05-01 15:26:20 +0100736 NodeParams common_params = { name(), s.hints().target_hint };
Georgios Pinitasd8734b52017-12-22 15:27:52 +0000737 NodeIdxPair input = { s.tail_node(), 0 };
738 return GraphBuilder::add_softmax_node(s.graph(), common_params, input, _beta);
739 }
740
741private:
742 float _beta;
743};
Michalis Spyrou96f67692018-09-13 11:39:28 +0100744
745/** YOLO Layer */
746class YOLOLayer final : public ILayer
747{
748public:
749 /** Construct a YOLO layer.
750 *
751 * @param[in] act_info Activation info
752 * @param[in] num_classes Number of classes to activate
753 */
754 YOLOLayer(ActivationLayerInfo act_info, int32_t num_classes)
755 : _act_info(act_info), _num_classes(num_classes)
756 {
757 }
758
759 NodeID create_layer(IStream &s) override
760 {
761 NodeParams common_params = { name(), s.hints().target_hint };
762 NodeIdxPair input = { s.tail_node(), 0 };
763 return GraphBuilder::add_yolo_node(s.graph(), common_params, input, _act_info, _num_classes);
764 }
765
766private:
767 ActivationLayerInfo _act_info;
768 int32_t _num_classes;
769};
Georgios Pinitasd8734b52017-12-22 15:27:52 +0000770} // namespace frontend
Georgios Pinitasd9eb2752018-04-03 13:44:29 +0100771} // namespace graph
Georgios Pinitasd8734b52017-12-22 15:27:52 +0000772} // namespace arm_compute
Georgios Pinitasd9eb2752018-04-03 13:44:29 +0100773#endif /* __ARM_COMPUTE_GRAPH_LAYERS_H__ */