f1dc1103a8e89b6b7e54e83193871f343b899f90
[platform/core/ml/nnfw.git] / runtime / onert / backend / cpu / ops / DepthwiseConvolutionLayer.cc
1 /*
2  * Copyright (c) 2019 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 "DepthwiseConvolutionLayer.h"
18
19 #include <cker/operation/DepthwiseConv.h>
20
21 namespace onert
22 {
23 namespace backend
24 {
25 namespace cpu
26 {
27 namespace ops
28 {
29
30 void DepthwiseConvolutionLayer::convFloat32()
31 {
32   float output_activation_min = 0, output_activation_max = 0;
33   CalculateActivationRange(_activation, &output_activation_min, &output_activation_max);
34
35   nnfw::cker::DepthwiseConvParams op_params;
36   op_params.stride_width = _strideWidth;
37   op_params.stride_height = _strideHeight;
38   op_params.dilation_width_factor = _dilationWidth;
39   op_params.dilation_height_factor = _dilationHeight;
40   op_params.padding_values.width = _paddingLeft;
41   op_params.padding_values.height = _paddingTop;
42   op_params.depth_multiplier = _multiplier;
43   op_params.float_activation_min = output_activation_min;
44   op_params.float_activation_max = output_activation_max;
45
46   nnfw::cker::DepthwiseConv(
47       op_params, getTensorShape(_input), reinterpret_cast<const float *>(_input->buffer()),
48       getTensorShape(_kernel), reinterpret_cast<const float *>(_kernel->buffer()),
49       getTensorShape(_bias), reinterpret_cast<const float *>(_bias->buffer()),
50       getTensorShape(_output), reinterpret_cast<float *>(_output->buffer()));
51 }
52
53 void DepthwiseConvolutionLayer::convQuant8()
54 {
55   int32_t output_activation_min = 0;
56   int32_t output_activation_max = 0;
57   CalculateActivationRangeUint8(_activation, _output, &output_activation_min,
58                                 &output_activation_max);
59
60   double real_multiplier = 0.0;
61   int32_t output_multiplier = 0;
62   int32_t output_shift = 0;
63   GetQuantizedConvolutionMultiplier(_input, _kernel, _bias, _output, &real_multiplier);
64   QuantizeMultiplier(real_multiplier, &output_multiplier, &output_shift);
65
66   nnfw::cker::DepthwiseConvParams op_params;
67   op_params.stride_width = _strideWidth;
68   op_params.stride_height = _strideHeight;
69   op_params.dilation_width_factor = _dilationWidth;
70   op_params.dilation_height_factor = _dilationHeight;
71   op_params.padding_values.width = _paddingLeft;
72   op_params.padding_values.height = _paddingTop;
73   op_params.depth_multiplier = _multiplier;
74   op_params.input_offset = -_input->data_offset();
75   op_params.weights_offset = -_kernel->data_offset();
76   op_params.output_offset = _output->data_offset();
77   op_params.output_multiplier = output_multiplier;
78   op_params.output_shift = output_shift;
79   op_params.quantized_activation_min = output_activation_min;
80   op_params.quantized_activation_max = output_activation_max;
81
82   nnfw::cker::DepthwiseConv(
83       op_params, getTensorShape(_input), reinterpret_cast<const uint8_t *>(_input->buffer()),
84       getTensorShape(_kernel), reinterpret_cast<const uint8_t *>(_kernel->buffer()),
85       getTensorShape(_bias), reinterpret_cast<const int32_t *>(_bias->buffer()),
86       getTensorShape(_output), reinterpret_cast<uint8_t *>(_output->buffer()));
87 }
88
89 void DepthwiseConvolutionLayer::configure(
90     const IPortableTensor *input, const IPortableTensor *kernel, const IPortableTensor *bias,
91     const uint32_t paddingLeft, const uint32_t paddingRight, const uint32_t paddingTop,
92     const uint32_t paddingBottom, const uint32_t strideWidth, const uint32_t strideHeight,
93     const uint32_t multiplier, const uint32_t dilationWidth, const uint32_t dilationHeight,
94     const ir::Activation activation, IPortableTensor *output)
95 {
96   _input = input;
97   _kernel = kernel;
98   _bias = bias;
99   _paddingLeft = paddingLeft;
100   _paddingRight = paddingRight;
101   _paddingTop = paddingTop;
102   _paddingBottom = paddingBottom;
103   _strideWidth = strideWidth;
104   _strideHeight = strideHeight;
105   _multiplier = multiplier;
106   _dilationWidth = dilationWidth;
107   _dilationHeight = dilationHeight;
108   _activation = activation;
109   _output = output;
110 }
111
112 void DepthwiseConvolutionLayer::run()
113 {
114   if (_input->data_type() == OperandType::FLOAT32)
115   {
116     convFloat32();
117   }
118   else if (_input->data_type() == OperandType::QUANT_UINT8_ASYMM)
119   {
120     convQuant8();
121   }
122   else
123   {
124     throw std::runtime_error{"DepthwiseConv: unsupported data type"};
125   }
126 }
127
128 } // namespace ops
129 } // namespace cpu
130 } // namespace backend
131 } // namespace onert