ONE - On-device Neural Engine
Loading...
Searching...
No Matches
luci_interpreter::kernels::DepthwiseConv2D Class Reference

#include <DepthwiseConv2D.h>

Collaboration diagram for luci_interpreter::kernels::DepthwiseConv2D:

Public Member Functions

 DepthwiseConv2D (const Tensor *input, const Tensor *filter, const Tensor *bias, Tensor *output, Tensor *scratchpad, const DepthwiseConv2DParams &params)
 
const Tensorinput () const
 
const Tensorfilter () const
 
const Tensorbias () const
 
Tensoroutput () const
 
void configure () override
 
void execute () const override
 
- Public Member Functions inherited from luci_interpreter::KernelWithParams< DepthwiseConv2DParams >
const DepthwiseConv2DParamsparams () const
 
- Public Member Functions inherited from luci_interpreter::Kernel
virtual ~Kernel ()=default
 
const std::vector< const Tensor * > & getInputTensors () const
 
const std::vector< Tensor * > & getOutputTensors () const
 

Additional Inherited Members

- Protected Member Functions inherited from luci_interpreter::KernelWithParams< DepthwiseConv2DParams >
 KernelWithParams (std::vector< const Tensor * > inputs, std::vector< Tensor * > outputs, const DepthwiseConv2DParams &params)
 
- Protected Member Functions inherited from luci_interpreter::Kernel
 Kernel (std::vector< const Tensor * > inputs, std::vector< Tensor * > outputs)
 
- Protected Attributes inherited from luci_interpreter::KernelWithParams< DepthwiseConv2DParams >
const DepthwiseConv2DParams _params
 
- Protected Attributes inherited from luci_interpreter::Kernel
const std::vector< const Tensor * > _inputs
 
const std::vector< Tensor * > _outputs
 

Detailed Description

Definition at line 28 of file DepthwiseConv2D.h.

Constructor & Destructor Documentation

◆ DepthwiseConv2D()

luci_interpreter::kernels::DepthwiseConv2D::DepthwiseConv2D ( const Tensor input,
const Tensor filter,
const Tensor bias,
Tensor output,
Tensor scratchpad,
const DepthwiseConv2DParams params 
)

Definition at line 30 of file DepthwiseConv2D.cpp.

33 : KernelWithParams<DepthwiseConv2DParams>({input, filter, bias}, {output, scratchpad}, params)
34{
35}
const DepthwiseConv2DParams & params() const
Definition Kernel.h:67

References bias(), filter(), and input().

Member Function Documentation

◆ bias()

const Tensor * luci_interpreter::kernels::DepthwiseConv2D::bias ( ) const
inline

Definition at line 36 of file DepthwiseConv2D.h.

36{ return _inputs[2]; }
const std::vector< const Tensor * > _inputs
Definition Kernel.h:52

References luci_interpreter::Kernel::_inputs.

Referenced by configure(), and DepthwiseConv2D().

◆ configure()

void luci_interpreter::kernels::DepthwiseConv2D::configure ( )
overridevirtual

Implements luci_interpreter::Kernel.

Definition at line 37 of file DepthwiseConv2D.cpp.

38{
39 // TensorFlow Lite (as of v2.2.0) supports the following combinations of types:
40 // | input filter bias output |
41 // ----+---------------------------+
42 // (1) | float float float float |
43 // (2) | float int8 float float | hybrid
44 // (3) | uint8 uint8 int32 uint8 | quantized
45 // (4) | int8 int8 int32 int8 | quantized per channel
46 // (5) | int16 int8 int64 int16 | quantized per channel 16x8
47 //
48 // We only support (1), (3) and (4) for now, and additionally the following:
49 // | input filter bias output |
50 // ----+---------------------------+
51 // (5) | int16 int16 int64 int16 |
52 //
53 if (input()->element_type() == DataType::FLOAT32 && filter()->element_type() == DataType::FLOAT32)
54 {
55 LUCI_INTERPRETER_CHECK(bias() == nullptr || bias()->element_type() == DataType::FLOAT32);
56 }
57 else if (input()->element_type() == DataType::U8 && filter()->element_type() == DataType::U8)
58 {
59 LUCI_INTERPRETER_CHECK(bias() == nullptr || bias()->element_type() == DataType::S32);
60 }
61 else if (input()->element_type() == DataType::S8 && filter()->element_type() == DataType::S8)
62 {
63 LUCI_INTERPRETER_CHECK(filter()->shape().num_dims() == 4);
64 LUCI_INTERPRETER_CHECK(static_cast<uint32_t>(filter()->shape().dim(3)) ==
65 filter()->scales().size());
66 for (auto zerop : filter()->zero_points())
67 {
68 LUCI_INTERPRETER_CHECK(zerop == 0);
69 }
70 LUCI_INTERPRETER_CHECK(bias() == nullptr || bias()->element_type() == DataType::S32);
71 }
72 else if (input()->element_type() == DataType::S16 && filter()->element_type() == DataType::S16)
73 {
74 LUCI_INTERPRETER_CHECK(bias() == nullptr || bias()->element_type() == DataType::S64);
75 }
76 else
77 {
78 throw std::runtime_error("luci-intp DepthwiseConv2D(1) Unsupported type.");
79 }
80 LUCI_INTERPRETER_CHECK(output()->element_type() == input()->element_type());
81
82 const Shape &input_shape = input()->shape();
83 const Shape &filter_shape = filter()->shape();
84 LUCI_INTERPRETER_CHECK(input_shape.num_dims() == 4 && filter_shape.num_dims() == 4);
85
86 const int32_t batches = input_shape.dim(0);
87 const int32_t input_height = input_shape.dim(1);
88 const int32_t input_width = input_shape.dim(2);
89 // Filter format: [1, H, W, O].
90 LUCI_INTERPRETER_CHECK(filter_shape.dim(0) == 1);
91 const int32_t filter_height = filter_shape.dim(1);
92 const int32_t filter_width = filter_shape.dim(2);
93 const int32_t channels_out = filter_shape.dim(3);
94
95 LUCI_INTERPRETER_CHECK(bias() == nullptr || (bias()->shape().num_dims() == 1 &&
96 bias()->shape().dim(0) == channels_out));
97
98 const int32_t output_height =
99 computeOutputSize(_params.padding, input_height, filter_height, _params.stride_height,
101 const int32_t output_width =
102 computeOutputSize(_params.padding, input_width, filter_width, _params.stride_width,
104
106 input_height, filter_height, output_height);
107 _padding_width = computePadding(_params.stride_width, _params.dilation_width_factor, input_width,
108 filter_width, output_width);
109
110 output()->resize({batches, output_height, output_width, channels_out});
111
112 tflite::DepthwiseParams params{};
113
116
117 auto scratchpad = getOutputTensors()[1];
118 luci_interpreter_pal::SetupScratchpadTensor(scratchpad, params, input()->element_type(),
121}
const std::vector< Tensor * > & getOutputTensors() const
Definition Kernel.h:40
void resize(const Shape &new_shape)
Definition Tensor.cpp:56
const Shape & shape() const
Definition Tensor.h:107
#define LUCI_INTERPRETER_CHECK(cond)
Definition Utils.h:36
int32_t computePadding(int32_t stride, int32_t dilation_rate, int32_t in_size, int32_t filter_size, int32_t out_size)
Definition Utils.h:41
tflite::RuntimeShape getTensorShape(const Tensor *tensor)
Definition Utils.h:194
int32_t computeOutputSize(Padding padding, int32_t image_size, int32_t filter_size, int32_t stride, int32_t dilation_rate=1)
Definition Utils.h:59
int32_t size[5]
Definition Slice.cpp:35
Definition Shape.h:28

References luci_interpreter::KernelWithParams< DepthwiseConv2DParams >::_params, bias(), luci_interpreter::kernels::computeOutputSize(), luci_interpreter::kernels::computePadding(), luci_interpreter::DepthwiseConv2DParams::dilation_height_factor, luci_interpreter::DepthwiseConv2DParams::dilation_width_factor, luci_interpreter::Shape::dim(), filter(), luci_interpreter::Kernel::getOutputTensors(), luci_interpreter::kernels::getTensorShape(), input(), LUCI_INTERPRETER_CHECK, luci_interpreter::Shape::num_dims(), output(), luci_interpreter::DepthwiseConv2DParams::padding, luci_interpreter::KernelWithParams< DepthwiseConv2DParams >::params(), luci_interpreter::Tensor::resize(), luci_interpreter::Tensor::shape(), size, luci_interpreter::DepthwiseConv2DParams::stride_height, luci_interpreter::DepthwiseConv2DParams::stride_width, and luci_interpreter::Tensor::zero_points().

◆ execute()

void luci_interpreter::kernels::DepthwiseConv2D::execute ( ) const
overridevirtual

Implements luci_interpreter::Kernel.

Definition at line 123 of file DepthwiseConv2D.cpp.

124{
125 switch (input()->element_type())
126 {
127 case DataType::FLOAT32:
128 if (filter()->element_type() == DataType::FLOAT32)
129 {
130 evalFloat();
131 break;
132 }
133 throw std::runtime_error("luci-intp DepthwiseConv2D(2) Unsupported type.");
134 case DataType::U8:
135 if (filter()->scales().size() == 1)
136 {
137 evalQuantized();
138 }
139 else if (filter()->scales().size() > 1)
140 {
141 LUCI_INTERPRETER_CHECK(filter()->shape().num_dims() == 4);
142 LUCI_INTERPRETER_CHECK(filter()->scales().size() ==
143 static_cast<size_t>(filter()->shape().dim(3)));
144 evalQuantizedPerChannel();
145 }
146 break;
147 case DataType::S8:
148 evalQuantizedS8PerChannel();
149 break;
150 case DataType::S16:
151 evalQuantizedS16();
152 break;
153 default:
154 throw std::runtime_error("luci-intp DepthwiseConv2D(3) Unsupported type.");
155 }
156}

References filter(), input(), LUCI_INTERPRETER_CHECK, and size.

◆ filter()

const Tensor * luci_interpreter::kernels::DepthwiseConv2D::filter ( ) const
inline

Definition at line 35 of file DepthwiseConv2D.h.

35{ return _inputs[1]; }

References luci_interpreter::Kernel::_inputs.

Referenced by configure(), DepthwiseConv2D(), and execute().

◆ input()

const Tensor * luci_interpreter::kernels::DepthwiseConv2D::input ( ) const
inline

Definition at line 34 of file DepthwiseConv2D.h.

34{ return _inputs[0]; }

References luci_interpreter::Kernel::_inputs.

Referenced by configure(), DepthwiseConv2D(), and execute().

◆ output()

Tensor * luci_interpreter::kernels::DepthwiseConv2D::output ( ) const
inline

Definition at line 37 of file DepthwiseConv2D.h.

37{ return _outputs[0]; }
const std::vector< Tensor * > _outputs
Definition Kernel.h:53

References luci_interpreter::Kernel::_outputs.

Referenced by configure().


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