ONE - On-device Neural Engine
Loading...
Searching...
No Matches
onert::backend::cpu::ops::DepthwiseConvolutionLayer Class Reference

#include <DepthwiseConv2DLayer.h>

Collaboration diagram for onert::backend::cpu::ops::DepthwiseConvolutionLayer:

Public Member Functions

 DepthwiseConvolutionLayer ()=default
 
void convFloat32 ()
 
void convQ8uPerTensor ()
 
void convQ8uPerChannel ()
 
void convQ8i ()
 
void convQ8iHybridPerChannel ()
 
void configure (const IPortableTensor *input, const IPortableTensor *kernel, const IPortableTensor *bias, const uint32_t paddingLeft, const uint32_t paddingRight, const uint32_t paddingTop, const uint32_t paddingBottom, const uint32_t strideW, const uint32_t strideH, const uint32_t multiplier, const uint32_t dilationWidth, const uint32_t dilationHeight, const ir::Activation activation, IPortableTensor *output, const std::shared_ptr< ExternalContext > &external_context)
 
void run () override
 
- Public Member Functions inherited from onert::exec::IFunction
virtual ~IFunction ()=default
 
virtual void prepare ()
 

Protected Attributes

const IPortableTensor_input {nullptr}
 
const IPortableTensor_kernel {nullptr}
 
const IPortableTensor_bias {nullptr}
 
IPortableTensor_output {nullptr}
 
uint32_t _paddingLeft {0}
 
uint32_t _paddingTop {0}
 
uint32_t _paddingRight {0}
 
uint32_t _paddingBottom {0}
 
uint32_t _strideWidth {0}
 
uint32_t _strideHeight {0}
 
uint32_t _multiplier {0}
 
uint32_t _dilationWidth {1}
 
uint32_t _dilationHeight {1}
 
ir::Activation _activation {ir::Activation::NONE}
 

Detailed Description

Definition at line 29 of file DepthwiseConv2DLayer.h.

Constructor & Destructor Documentation

◆ DepthwiseConvolutionLayer()

onert::backend::cpu::ops::DepthwiseConvolutionLayer::DepthwiseConvolutionLayer ( )
default

Member Function Documentation

◆ configure()

void onert::backend::cpu::ops::DepthwiseConvolutionLayer::configure ( const IPortableTensor input,
const IPortableTensor kernel,
const IPortableTensor bias,
const uint32_t  paddingLeft,
const uint32_t  paddingRight,
const uint32_t  paddingTop,
const uint32_t  paddingBottom,
const uint32_t  strideW,
const uint32_t  strideH,
const uint32_t  multiplier,
const uint32_t  dilationWidth,
const uint32_t  dilationHeight,
const ir::Activation  activation,
IPortableTensor output,
const std::shared_ptr< ExternalContext > &  external_context 
)

Definition at line 291 of file DepthwiseConv2DLayer.cc.

298{
299 _input = input;
300 _kernel = kernel;
301 _bias = bias;
302 _paddingLeft = paddingLeft;
303 _paddingRight = paddingRight;
304 _paddingTop = paddingTop;
305 _paddingBottom = paddingBottom;
306 _strideWidth = strideWidth;
307 _strideHeight = strideHeight;
308 _multiplier = multiplier;
309 _dilationWidth = dilationWidth;
310 _dilationHeight = dilationHeight;
311 _activation = activation;
312 _output = output;
313 _external_context = external_context;
314 _is_hybrid = _input->data_type() == OperandType::FLOAT32 &&
315 _kernel->data_type() == OperandType::QUANT_INT8_SYMM;
316
317 if (_is_hybrid)
318 {
319 ensureQ8iHybridPerChannel();
320 prepareQ8iHybridPerChannel();
321 _prepared = true;
322 }
323 else if (_input->data_type() == OperandType::QUANT_INT8_ASYMM)
324 {
326 {
327 prepareQ8i();
328 _prepared = true;
329 }
330 }
331 else if (_input->data_type() == OperandType::QUANT_UINT8_ASYMM && _kernel->is_constant() &&
333 {
334 const bool per_channel_quantized = _kernel->data_scales().size() > 1;
335 if (per_channel_quantized)
336 {
337 prepareQ8uPerChannel();
338 _prepared = true;
339 }
340 }
341}
const std::vector< float > & data_scales() const override final
ir::DataType data_type() const override final
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.

References _activation, _bias, _dilationHeight, _dilationWidth, _input, _kernel, _multiplier, _output, _paddingBottom, _paddingLeft, _paddingRight, _paddingTop, _strideHeight, _strideWidth, onert::backend::IPortableTensor::data_scales(), onert::backend::IPortableTensor::data_type(), onert::backend::IPortableTensor::is_constant(), and onert::backend::IPortableTensor::is_dynamic().

◆ convFloat32()

void onert::backend::cpu::ops::DepthwiseConvolutionLayer::convFloat32 ( )

Definition at line 72 of file DepthwiseConv2DLayer.cc.

73{
74 float output_activation_min = 0, output_activation_max = 0;
75 CalculateActivationRange(_activation, &output_activation_min, &output_activation_max);
76
78 op_params.stride_width = _strideWidth;
79 op_params.stride_height = _strideHeight;
84 op_params.depth_multiplier = _multiplier;
85 op_params.float_activation_min = output_activation_min;
86 op_params.float_activation_max = output_activation_max;
87
88 // TODO: Use the following call if TensorBuilder manages padded_filter_data
89 // and filter_buffers_data:
90 //
91 // void DepthwiseConvOp(
92 // const DepthwiseConvParams &params,
93 // const Shape &input_shape, const float *input_data,
94 // const Shape &filter_shape, const float *filter_data,
95 // const Shape &bias_shape, const float *bias_data,
96 // float *padded_filter_data, bool pad_filter,
97 // float *filter_buffers_data,
98 // const Shape &output_shape, float *output_data
99 // );
100 //
101 // See https://github.com/Samsung/ONE/pull/13669 for an example of using DepthwiseConvOp
102 nnfw::cker::DepthwiseConv<float, float>(
103 op_params, getShape(_input), getBuffer<float>(_input), getShape(_kernel),
104 getBuffer<float>(_kernel), getShape(_bias), getBuffer<float>(_bias), getShape(_output),
105 getBuffer<float>(_output), _external_context->ruy_context());
106}
nnfw::cker::Shape getShape(const IPortableTensor *tensor)
void CalculateActivationRange(ir::Activation activation, T *activation_min, T *activation_max)
PaddingValues padding_values
Definition Types.h:234

References _activation, _bias, _dilationHeight, _dilationWidth, _input, _kernel, _multiplier, _output, _paddingLeft, _paddingTop, _strideHeight, _strideWidth, onert::util::CalculateActivationRange(), nnfw::cker::DepthwiseConvParams::depth_multiplier, nnfw::cker::DepthwiseConvParams::dilation_height_factor, nnfw::cker::DepthwiseConvParams::dilation_width_factor, nnfw::cker::DepthwiseConvParams::float_activation_max, nnfw::cker::DepthwiseConvParams::float_activation_min, onert::backend::cpu::ops::getShape(), nnfw::cker::PaddingValues::height, nnfw::cker::DepthwiseConvParams::padding_values, nnfw::cker::DepthwiseConvParams::stride_height, nnfw::cker::DepthwiseConvParams::stride_width, and nnfw::cker::PaddingValues::width.

Referenced by run().

◆ convQ8i()

void onert::backend::cpu::ops::DepthwiseConvolutionLayer::convQ8i ( )

Definition at line 171 of file DepthwiseConv2DLayer.cc.

172{
173 if (!_prepared)
174 {
175 prepareQ8i();
176 _prepared = true;
177 }
178
179 int32_t output_activation_min = 0;
180 int32_t output_activation_max = 0;
182 &output_activation_max);
183
188 op_params.depth_multiplier = _multiplier;
189 op_params.stride_width = _strideWidth;
190 op_params.stride_height = _strideHeight;
193 op_params.input_offset = -_input->data_zero_point();
194 op_params.weights_offset = 0;
196 op_params.quantized_activation_min = output_activation_min;
197 op_params.quantized_activation_max = output_activation_max;
198
200 op_params, _per_channel_output_multiplier.data(), _per_channel_output_shift.data(),
201 getShape(_input), getBuffer<int8_t>(_input), getShape(_kernel), getBuffer<int8_t>(_kernel),
202 getShape(_bias), getBuffer<int32_t>(_bias), getShape(_output), getBuffer<int8_t>(_output),
203 _external_context->ruy_context());
204}
int32_t data_zero_point() const override final
void DepthwiseConvPerChannel(const DepthwiseConvParams &params, const int32_t *output_multiplier, const int32_t *output_shift, const Shape &input_shape, const int8_t *input_data, const Shape &filter_shape, const int8_t *filter_data, const Shape &bias_shape, const int32_t *bias_data, const Shape &output_shape, int8_t *output_data, ruy::Context *ruy_context)
void CalculateActivationRangeQuantized(ir::Activation activation, const IPortableTensor *output, int32_t *act_min, int32_t *act_max)

References _activation, _bias, _dilationHeight, _dilationWidth, _input, _kernel, _multiplier, _output, _paddingLeft, _paddingTop, _strideHeight, _strideWidth, onert::backend::cpu::ops::CalculateActivationRangeQuantized(), onert::backend::IPortableTensor::data_zero_point(), nnfw::cker::DepthwiseConvParams::depth_multiplier, nnfw::cker::optimized_integer_ops::DepthwiseConvPerChannel(), nnfw::cker::DepthwiseConvParams::dilation_height_factor, nnfw::cker::DepthwiseConvParams::dilation_width_factor, onert::backend::cpu::ops::getShape(), nnfw::cker::PaddingValues::height, nnfw::cker::DepthwiseConvParams::input_offset, nnfw::cker::kSame, nnfw::cker::DepthwiseConvParams::output_offset, nnfw::cker::DepthwiseConvParams::padding_type, nnfw::cker::DepthwiseConvParams::padding_values, nnfw::cker::DepthwiseConvParams::quantized_activation_max, nnfw::cker::DepthwiseConvParams::quantized_activation_min, nnfw::cker::DepthwiseConvParams::stride_height, nnfw::cker::DepthwiseConvParams::stride_width, nnfw::cker::DepthwiseConvParams::weights_offset, and nnfw::cker::PaddingValues::width.

Referenced by run().

◆ convQ8iHybridPerChannel()

void onert::backend::cpu::ops::DepthwiseConvolutionLayer::convQ8iHybridPerChannel ( )

Definition at line 206 of file DepthwiseConv2DLayer.cc.

207{
208 if (!_prepared)
209 {
210 prepareQ8iHybridPerChannel();
211 _prepared = true;
212 }
213
214 float output_activation_min = 0, output_activation_max = 0;
215 CalculateActivationRange(_activation, &output_activation_min, &output_activation_max);
216
217 auto input_shape = getShape(_input);
218 const int batch_size = input_shape.Dims(0);
219 const int input_size = input_shape.FlatSize() / batch_size;
220
221 auto scaling_factors_ptr = _input_scaling_factors.data();
222 auto input_offsets_ptr = _input_offsets.data();
223
224 for (int b = 0; b < batch_size; ++b)
225 {
226 const int offset = b * input_size;
227 nnfw::cker::PortableAsymmetricQuantizeFloats(getBuffer<float>(_input) + offset, input_size,
228 _input_quantized.data() + offset,
229 &scaling_factors_ptr[b], &input_offsets_ptr[b]);
230 }
231
235 op_params.depth_multiplier = _multiplier;
236 op_params.stride_width = _strideWidth;
237 op_params.stride_height = _strideHeight;
240 op_params.float_activation_min = output_activation_min;
241 op_params.float_activation_max = output_activation_max;
242
244 op_params, _input_scaling_factors.data(), getShape(_input), _input_quantized.data(),
245 getShape(_kernel), getBuffer<int8_t>(_kernel), getShape(_bias), getBuffer<float>(_bias),
246 getShape(_output), getBuffer<float>(_output), _kernel->data_scales().data(),
247 _input_offsets.data());
248}
__global uchar * offset(const Image *img, int x, int y)
Definition helpers.h:540
void DepthwiseConvHybridPerChannel(const DepthwiseConvParams &params, float *scaling_factors_ptr, const Shape &input_shape, const int8_t *input_data, const Shape &filter_shape, const int8_t *filter_data, const Shape &bias_shape, const float *bias_data, const Shape &output_shape, float *output_data, const float *per_channel_scale, int32_t *input_offset)
void PortableAsymmetricQuantizeFloats(const float *values, const int size, int8_t *quantized_values, float *scaling_factor, int32_t *offset)

References _activation, _bias, _dilationHeight, _dilationWidth, _input, _kernel, _multiplier, _output, _paddingLeft, _paddingTop, _strideHeight, _strideWidth, onert::util::CalculateActivationRange(), onert::backend::IPortableTensor::data_scales(), nnfw::cker::DepthwiseConvParams::depth_multiplier, nnfw::cker::reference_integer_ops::DepthwiseConvHybridPerChannel(), nnfw::cker::DepthwiseConvParams::dilation_height_factor, nnfw::cker::DepthwiseConvParams::dilation_width_factor, nnfw::cker::DepthwiseConvParams::float_activation_max, nnfw::cker::DepthwiseConvParams::float_activation_min, onert::backend::cpu::ops::getShape(), nnfw::cker::PaddingValues::height, offset(), nnfw::cker::DepthwiseConvParams::padding_values, nnfw::cker::PortableAsymmetricQuantizeFloats(), nnfw::cker::DepthwiseConvParams::stride_height, nnfw::cker::DepthwiseConvParams::stride_width, and nnfw::cker::PaddingValues::width.

Referenced by run().

◆ convQ8uPerChannel()

void onert::backend::cpu::ops::DepthwiseConvolutionLayer::convQ8uPerChannel ( )

Definition at line 143 of file DepthwiseConv2DLayer.cc.

144{
148 op_params.stride_width = _strideWidth;
149 op_params.stride_height = _strideHeight;
152 op_params.depth_multiplier = _multiplier;
153 op_params.input_offset = -_input->data_zero_point();
155 int32_t output_activation_min = 0;
156 int32_t output_activation_max = 0;
158 &output_activation_max);
159 op_params.quantized_activation_min = output_activation_min;
160 op_params.quantized_activation_max = output_activation_max;
161 // NOTE: The following fields of ConvParams are not used:
162 // padding_type, weights_offset, output_{multiplier,shift}, float_activation_{min,max}
163
165 op_params, _per_channel_output_multiplier.data(), _per_channel_output_shift.data(),
166 getShape(_input), getBuffer<uint8_t>(_input), getShape(_kernel), getBuffer<uint8_t>(_kernel),
167 _kernel->data_zero_points().data(), getShape(_bias), getBuffer<int32_t>(_bias),
168 getShape(_output), getBuffer<uint8_t>(_output));
169}
const std::vector< int32_t > & data_zero_points() const override
void DepthwiseConvPerChannel(const DepthwiseConvParams &params, const int32_t *output_multiplier, const int32_t *output_shift, const Shape &input_shape, const uint8_t *input_data, const Shape &filter_shape, const uint8_t *filter_data, const int32_t *filter_zeropoint, const Shape &bias_shape, const int32_t *bias_data, const Shape &output_shape, uint8_t *output_data)

References _activation, _bias, _dilationHeight, _dilationWidth, _input, _kernel, _multiplier, _output, _paddingLeft, _paddingTop, _strideHeight, _strideWidth, onert::backend::cpu::ops::CalculateActivationRangeQuantized(), onert::backend::IPortableTensor::data_zero_point(), onert::backend::IPortableTensor::data_zero_points(), nnfw::cker::DepthwiseConvParams::depth_multiplier, nnfw::cker::reference_integer_ops::DepthwiseConvPerChannel(), nnfw::cker::DepthwiseConvParams::dilation_height_factor, nnfw::cker::DepthwiseConvParams::dilation_width_factor, onert::backend::cpu::ops::getShape(), nnfw::cker::PaddingValues::height, nnfw::cker::DepthwiseConvParams::input_offset, nnfw::cker::DepthwiseConvParams::output_offset, nnfw::cker::DepthwiseConvParams::padding_values, nnfw::cker::DepthwiseConvParams::quantized_activation_max, nnfw::cker::DepthwiseConvParams::quantized_activation_min, nnfw::cker::DepthwiseConvParams::stride_height, nnfw::cker::DepthwiseConvParams::stride_width, and nnfw::cker::PaddingValues::width.

Referenced by run().

◆ convQ8uPerTensor()

void onert::backend::cpu::ops::DepthwiseConvolutionLayer::convQ8uPerTensor ( )

Definition at line 108 of file DepthwiseConv2DLayer.cc.

109{
110 int32_t output_activation_min = 0;
111 int32_t output_activation_max = 0;
113 &output_activation_max);
114
115 double real_multiplier = 0.0;
116 int32_t output_multiplier = 0;
117 int32_t output_shift = 0;
119 QuantizeMultiplier(real_multiplier, &output_multiplier, &output_shift);
120
122 op_params.stride_width = _strideWidth;
123 op_params.stride_height = _strideHeight;
128 op_params.depth_multiplier = _multiplier;
129 op_params.input_offset = -_input->data_zero_point();
130 op_params.weights_offset = -_kernel->data_zero_point();
132 op_params.output_multiplier = output_multiplier;
133 op_params.output_shift = output_shift;
134 op_params.quantized_activation_min = output_activation_min;
135 op_params.quantized_activation_max = output_activation_max;
136
137 nnfw::cker::DepthwiseConv<uint8_t, int32_t>(
138 op_params, getShape(_input), getBuffer<uint8_t>(_input), getShape(_kernel),
139 getBuffer<uint8_t>(_kernel), getShape(_bias), getBuffer<int32_t>(_bias), getShape(_output),
140 getBuffer<uint8_t>(_output), _external_context->ruy_context());
141}
void QuantizeMultiplier(double double_multiplier, int32_t *quantized_multiplier, int *shift)
void GetQuantizedConvolutionMultiplier(const IPortableTensor *input, const IPortableTensor *filter, const IPortableTensor *bias, const IPortableTensor *output, double *multiplier)

References _activation, _bias, _dilationHeight, _dilationWidth, _input, _kernel, _multiplier, _output, _paddingLeft, _paddingTop, _strideHeight, _strideWidth, onert::backend::cpu::ops::CalculateActivationRangeQuantized(), onert::backend::IPortableTensor::data_zero_point(), nnfw::cker::DepthwiseConvParams::depth_multiplier, nnfw::cker::DepthwiseConvParams::dilation_height_factor, nnfw::cker::DepthwiseConvParams::dilation_width_factor, onert::backend::cpu::ops::GetQuantizedConvolutionMultiplier(), onert::backend::cpu::ops::getShape(), nnfw::cker::PaddingValues::height, nnfw::cker::DepthwiseConvParams::input_offset, nnfw::cker::DepthwiseConvParams::output_multiplier, nnfw::cker::DepthwiseConvParams::output_offset, nnfw::cker::DepthwiseConvParams::output_shift, nnfw::cker::DepthwiseConvParams::padding_values, nnfw::cker::DepthwiseConvParams::quantized_activation_max, nnfw::cker::DepthwiseConvParams::quantized_activation_min, onert::backend::cpu::ops::QuantizeMultiplier(), nnfw::cker::DepthwiseConvParams::stride_height, nnfw::cker::DepthwiseConvParams::stride_width, nnfw::cker::DepthwiseConvParams::weights_offset, and nnfw::cker::PaddingValues::width.

Referenced by run().

◆ run()

void onert::backend::cpu::ops::DepthwiseConvolutionLayer::run ( )
overridevirtual

Implements onert::exec::IFunction.

Definition at line 343 of file DepthwiseConv2DLayer.cc.

344{
345 if (_is_hybrid)
346 {
348 }
349 else if (_input->data_type() == OperandType::FLOAT32)
350 {
351 convFloat32();
352 }
353 else if (_input->data_type() == OperandType::QUANT_UINT8_ASYMM)
354 {
355 const bool per_channel_quantized = _kernel->data_scales().size() > 1;
356 if (per_channel_quantized)
358 else
360 }
361 else if (_input->data_type() == OperandType::QUANT_INT8_ASYMM)
362 {
363 convQ8i();
364 }
365 else
366 {
367 throw std::runtime_error{"DepthwiseConv: unsupported data type"};
368 }
369}

References _input, _kernel, convFloat32(), convQ8i(), convQ8iHybridPerChannel(), convQ8uPerChannel(), convQ8uPerTensor(), onert::backend::IPortableTensor::data_scales(), and onert::backend::IPortableTensor::data_type().

Referenced by onert::backend::train::ops::DepthwiseConvolutionLayer::forward().

Field Documentation

◆ _activation

ir::Activation onert::backend::cpu::ops::DepthwiseConvolutionLayer::_activation {ir::Activation::NONE}
protected

◆ _bias

const IPortableTensor* onert::backend::cpu::ops::DepthwiseConvolutionLayer::_bias {nullptr}
protected

◆ _dilationHeight

uint32_t onert::backend::cpu::ops::DepthwiseConvolutionLayer::_dilationHeight {1}
protected

◆ _dilationWidth

uint32_t onert::backend::cpu::ops::DepthwiseConvolutionLayer::_dilationWidth {1}
protected

◆ _input

const IPortableTensor* onert::backend::cpu::ops::DepthwiseConvolutionLayer::_input {nullptr}
protected

◆ _kernel

const IPortableTensor* onert::backend::cpu::ops::DepthwiseConvolutionLayer::_kernel {nullptr}
protected

◆ _multiplier

uint32_t onert::backend::cpu::ops::DepthwiseConvolutionLayer::_multiplier {0}
protected

◆ _output

IPortableTensor* onert::backend::cpu::ops::DepthwiseConvolutionLayer::_output {nullptr}
protected

◆ _paddingBottom

uint32_t onert::backend::cpu::ops::DepthwiseConvolutionLayer::_paddingBottom {0}
protected

Definition at line 68 of file DepthwiseConv2DLayer.h.

68{0};

Referenced by configure().

◆ _paddingLeft

uint32_t onert::backend::cpu::ops::DepthwiseConvolutionLayer::_paddingLeft {0}
protected

◆ _paddingRight

uint32_t onert::backend::cpu::ops::DepthwiseConvolutionLayer::_paddingRight {0}
protected

Definition at line 67 of file DepthwiseConv2DLayer.h.

67{0};

Referenced by configure().

◆ _paddingTop

uint32_t onert::backend::cpu::ops::DepthwiseConvolutionLayer::_paddingTop {0}
protected

◆ _strideHeight

uint32_t onert::backend::cpu::ops::DepthwiseConvolutionLayer::_strideHeight {0}
protected

◆ _strideWidth

uint32_t onert::backend::cpu::ops::DepthwiseConvolutionLayer::_strideWidth {0}
protected

The documentation for this class was generated from the following files: