ONE - On-device Neural Engine
All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
KernelGenerator.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 "KernelGenerator.h"
18
19#include "ops/ConvolutionLayer.h"
20#include "ops/FullyConnectedLayer.h"
21
22#include <backend/Backend.h>
23#include <backend/IConfig.h>
24#include <memory>
25#include <util/Utils.h>
26#include <util/logging.h>
28
29#include <stdexcept>
30
31namespace onert::backend::ruy
32{
33
34std::unique_ptr<exec::FunctionSequence> KernelGenerator::generate(ir::OperationIndex ind)
35{
36 auto ret = std::make_unique<exec::FunctionSequence>();
37
38 assert(_tensor_builder->dynamicTensorManager());
39 assert(_tensor_reg);
40
41 // Prepare to handle dynamic tensors later
42 auto dyn_ctx = std::make_shared<exec::FunctionSequence::DynamicTensorCtx>();
43 {
44 dyn_ctx->op = &_operations_ctx.at(ind);
45 dyn_ctx->dynamic_shape_inferer = std::make_shared<exec::DynamicShapeInferer>(_tensor_reg);
46 }
47 ret->dynamic_tensor_ctx(dyn_ctx);
48
49 auto &op = _graph.operations().at(ind);
50 op.accept(*this);
51 assert(_return_fn); // _return_fn must have been generated
52 ret->append(std::move(_return_fn));
53
54 for (const auto &ind : (op.getInputs() | ir::Remove::UNDEFINED) + op.getOutputs())
55 {
56 auto tensor = _tensor_reg->getNativeTensor(ind);
57 if (tensor)
58 {
59 tensor->increase_ref();
60 }
61 }
62 return ret;
63}
64
66 const ir::Graph &graph, const std::shared_ptr<TensorBuilder> &tensor_builder,
67 const std::shared_ptr<basic::TensorRegistry> &tensor_reg,
68 const std::shared_ptr<backend::custom::IKernelBuilder> &kernel_builder,
69 const std::shared_ptr<ExternalContext> &external_context)
70 : basic::KernelGeneratorBase{graph}, _ctx(graph.operands()), _operations_ctx{graph.operations()},
71 _tensor_builder(tensor_builder), _tensor_reg{tensor_reg}, _kernel_builder(kernel_builder),
72 _external_context(external_context)
73{
74 // DO NOTHING
75}
76
77void KernelGenerator::visit(const ir::operation::Conv2D &node)
78{
80
81 const auto ofm_index{node.getOutputs().at(0)};
82 const auto ifm_index{node.getInputs().at(Conv2D::Input::INPUT)};
83 const auto ker_index{node.getInputs().at(Conv2D::Input::KERNEL)};
84 const auto bias_index{node.getInputs().at(Conv2D::Input::BIAS)};
85
86 auto ofm_tensor = _tensor_reg->getPortableTensor(ofm_index);
87 auto ifm_tensor = _tensor_reg->getPortableTensor(ifm_index);
88 auto ker_tensor = _tensor_reg->getPortableTensor(ker_index);
89 auto bias_tensor = _tensor_reg->getPortableTensor(bias_index);
90
91 const auto stride = node.param().stride;
92 const auto activation = node.param().activation;
93 const auto &param_padding = node.param().padding;
94 const auto dilation = node.param().dilation;
95 auto fn = std::make_unique<ops::ConvolutionLayer>();
96
97 if (_ctx.at(ifm_index).info().isDynamic() || _ctx.at(ker_index).info().isDynamic())
98 {
99 fn->configure(ifm_tensor, ker_tensor, bias_tensor, param_padding.type, param_padding.param.left,
100 param_padding.param.right, param_padding.param.top, param_padding.param.bottom,
101 stride.horizontal, stride.vertical, dilation.width_factor, dilation.height_factor,
102 activation, ofm_tensor, _external_context);
103
104 _return_fn = std::move(fn);
105 return;
106 }
107 const auto ifm_shape = _ctx.at(ifm_index).shape().asFeature();
108 const auto ofm_shape = _ctx.at(ofm_index).shape().asFeature();
109 // Kernel format is [depth_out, kernel_height, kernel_width, depth_in].
110 const auto &ker_shape = _ctx.at(ker_index).shape();
111 const auto ker_height = ker_shape.dim(1);
112 const auto ker_width = ker_shape.dim(2);
113
114 const auto padding =
115 ir::calculatePadding(param_padding, ifm_shape, ofm_shape, stride, ker_width, ker_height,
116 dilation.width_factor, dilation.height_factor);
117
118 fn->configure(ifm_tensor, ker_tensor, bias_tensor, param_padding.type, padding.left,
119 padding.right, padding.top, padding.bottom, stride.horizontal, stride.vertical,
120 dilation.width_factor, dilation.height_factor, activation, ofm_tensor,
121 _external_context);
122
123 _return_fn = std::move(fn);
124}
125
126void KernelGenerator::visit(const ir::operation::FullyConnected &node)
127{
128 using ir::operation::FullyConnected;
129
130 const auto output_index{node.getOutputs().at(0)};
131 const auto input_index{node.getInputs().at(FullyConnected::Input::INPUT)};
132 const auto weight_index{node.getInputs().at(FullyConnected::Input::WEIGHT)};
133 const auto bias_index{node.getInputs().at(FullyConnected::Input::BIAS)};
134 const auto activation = node.param().activation;
135 const auto weights_format = node.param().weights_format;
136 if (weights_format != ir::FullyConnectedWeightsFormat::Default)
137 throw std::runtime_error("Unsupported FullyConnected Weights Format");
138
139 auto output_tensor = _tensor_reg->getPortableTensor(output_index);
140 auto input_tensor = _tensor_reg->getPortableTensor(input_index);
141 auto weight_tensor = _tensor_reg->getPortableTensor(weight_index);
142 auto bias_tensor = bias_index.undefined() ? nullptr : _tensor_reg->getPortableTensor(bias_index);
143
144 auto fn = std::make_unique<ops::FullyConnectedLayer>();
145
146 fn->configure(input_tensor, weight_tensor, bias_tensor, activation, output_tensor,
147 _external_context);
148
149 _return_fn = std::move(fn);
150}
151
152} // namespace onert::backend::ruy
std::unique_ptr< exec::IFunction > _return_fn
std::unique_ptr< exec::FunctionSequence > generate(ir::OperationIndex ind) override
KernelGenerator(const ir::Graph &graph, const std::shared_ptr< TensorBuilder > &tensor_builder, const std::shared_ptr< basic::TensorRegistry > &tensor_reg, const std::shared_ptr< custom::IKernelBuilder > &kernel_builder, const std::shared_ptr< ExternalContext > &external_context)
const Operations & operations() const override
Definition Graph.h:112
const OperandIndex & at(IOIndex set_index) const
const OperandIndexSequence & getOutputs() const override
Definition Operation.h:53
OperandIndexSequence & getInputs()
Definition Operation.h:51
const Param & param() const
Definition Conv2D.h:56
const Object & at(const Index &index) const
Get the object that is associated with the given index.
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
This file contains utility macro.
CLTensor ker_tensor
CLTensor bias_tensor